commit 24d4df97ff057db4a9afdd9feb4b015fb52e0e8a Author: HYH <2229388563@qq.com> Date: Thu May 7 11:52:40 2020 +0800 初始化 diff --git a/ReadMe.MD b/ReadMe.MD new file mode 100644 index 0000000..aaf691d --- /dev/null +++ b/ReadMe.MD @@ -0,0 +1,35 @@ +# 说明 +本工程主要是迁移[https://github.com/majbthrd/stm32ecm](https://github.com/majbthrd/stm32ecm)到STM32CubeIDE。 + +## 迁移说明 + +* 利用STM32CubeIDE生成工程文件时,需要启用USB并且Device FS应当选择CDC ACM。代码生成后,设置好src文件夹中的源代码,然后取消对工程文件的USB_DEVICE和Middlewares\ST\STM32_USB_Device_Library的编译(也可以直接删除其子文件夹)。 + +* 根据src/src/ecm_main.h的内容将ecm_main.h中的初始化函数和处理函数放在main.c的合适位置。 + + +# 测试结果 + +* 单片机: STM32F072C8T6 + +## 测试的OS + +* Linux(lubuntu 19.04) + +## 测试结果 + +* 网卡的枚举和识别正常 + +![](doc/ecm_eth.png) + +* DHCP测试不正常,因此需要手动设置IP为192.168.7.2。 + +* Ping 192.168.7.1正常(已启用lwip对ICMP协议的支持) + +![](doc/ecm_ping.png) + +* DNS测试正常。能正常解析run.stm和www.run.stm为192.168.7.1。 + +![](doc/ecm_dns.png) + +* HTTP由于存储空间不足无法编译测试。 diff --git a/doc/ecm_dns.png b/doc/ecm_dns.png new file mode 100644 index 0000000..1266bb0 Binary files /dev/null and b/doc/ecm_dns.png differ diff --git a/doc/ecm_eth.png b/doc/ecm_eth.png new file mode 100644 index 0000000..7bcc3c7 Binary files /dev/null and b/doc/ecm_eth.png differ diff --git a/doc/ecm_ping.png b/doc/ecm_ping.png new file mode 100644 index 0000000..0b5b785 Binary files /dev/null and b/doc/ecm_ping.png differ diff --git a/src/ReadMe.md b/src/ReadMe.md new file mode 100644 index 0000000..b1ce2aa --- /dev/null +++ b/src/ReadMe.md @@ -0,0 +1,58 @@ +# 源代码说明 +将此源代码添加到其它工程时,需要进行的工程设置。 +## 头文件目录(相对于当前目录) +* src/ +* lwip-1.4.1/src/include +* lwip-1.4.1/src/include/ipv4 +* dhcp-server +* dns-server +* lwip-1.4.1/apps/httpserver_raw(由于存储空间不足未启用) + +## 源代码文件(相对于当前目录) + +* src/ecm_main.c +* src/time.c +* src/usb_device.c +* src/usbd_conf.c +* src/usbd_core.c +* src/usbd_ctlreq.c +* src/usbd_desc.c +* src/usbd_ecm.c +* src/usbd_ioreq.c + + +* lwip-1.4.1/src/core/def.c +* lwip-1.4.1/src/core/dhcp.c +* lwip-1.4.1/src/core/dns.c +* lwip-1.4.1/src/core/init.c +* lwip-1.4.1/src/core/mem.c +* lwip-1.4.1/src/core/memp.c +* lwip-1.4.1/src/core/netif.c +* lwip-1.4.1/src/core/pbuf.c +* lwip-1.4.1/src/core/raw.c +* lwip-1.4.1/src/core/stats.c +* lwip-1.4.1/src/core/sys.c +* lwip-1.4.1/src/core/tcp.c +* lwip-1.4.1/src/core/tcp_in.c +* lwip-1.4.1/src/core/tcp_out.c +* lwip-1.4.1/src/core/timers.c +* lwip-1.4.1/src/core/udp.c +* lwip-1.4.1/src/core/ipv4/autoip.c +* lwip-1.4.1/src/core/ipv4/icmp.c +* lwip-1.4.1/src/core/ipv4/igmp.c +* lwip-1.4.1/src/core/ipv4/inet.c +* lwip-1.4.1/src/core/ipv4/inet_chksum.c +* lwip-1.4.1/src/core/ipv4/ip.c +* lwip-1.4.1/src/core/ipv4/ip_addr.c +* lwip-1.4.1/src/core/ipv4/ip_frag.c +* lwip-1.4.1/src/netif/etharp.c +* lwip-1.4.1/src/netif/ethernetif.c +* lwip-1.4.1/src/netif/slipif.c + +* dhcp-server/dhserver.c + +* dns-server/dnserver.c + +* lwip-1.4.1/apps/httpserver_raw/fs.c(由于存储空间不足未启用) +* lwip-1.4.1/apps/httpserver_raw/httpd.c(由于存储空间不足未启用) +* lwip-1.4.1/apps/httpserver_raw/fsdata.c(由于存储空间不足未启用) diff --git a/src/dhcp-server/dhserver.c b/src/dhcp-server/dhserver.c new file mode 100644 index 0000000..8b1fe6b --- /dev/null +++ b/src/dhcp-server/dhserver.c @@ -0,0 +1,344 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015 by Sergey Fetisov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "dhserver.h" + +/* DHCP message type */ +#define DHCP_DISCOVER 1 +#define DHCP_OFFER 2 +#define DHCP_REQUEST 3 +#define DHCP_DECLINE 4 +#define DHCP_ACK 5 +#define DHCP_NAK 6 +#define DHCP_RELEASE 7 +#define DHCP_INFORM 8 + +/* DHCP options */ +enum DHCP_OPTIONS +{ + DHCP_PAD = 0, + DHCP_SUBNETMASK = 1, + DHCP_ROUTER = 3, + DHCP_DNSSERVER = 6, + DHCP_HOSTNAME = 12, + DHCP_DNSDOMAIN = 15, + DHCP_MTU = 26, + DHCP_BROADCAST = 28, + DHCP_PERFORMROUTERDISC = 31, + DHCP_STATICROUTE = 33, + DHCP_NISDOMAIN = 40, + DHCP_NISSERVER = 41, + DHCP_NTPSERVER = 42, + DHCP_VENDOR = 43, + DHCP_IPADDRESS = 50, + DHCP_LEASETIME = 51, + DHCP_OPTIONSOVERLOADED = 52, + DHCP_MESSAGETYPE = 53, + DHCP_SERVERID = 54, + DHCP_PARAMETERREQUESTLIST = 55, + DHCP_MESSAGE = 56, + DHCP_MAXMESSAGESIZE = 57, + DHCP_RENEWALTIME = 58, + DHCP_REBINDTIME = 59, + DHCP_CLASSID = 60, + DHCP_CLIENTID = 61, + DHCP_USERCLASS = 77, /* RFC 3004 */ + DHCP_FQDN = 81, + DHCP_DNSSEARCH = 119, /* RFC 3397 */ + DHCP_CSR = 121, /* RFC 3442 */ + DHCP_MSCSR = 249, /* MS code for RFC 3442 */ + DHCP_END = 255 +}; + +typedef struct +{ + uint8_t dp_op; /* packet opcode type */ + uint8_t dp_htype; /* hardware addr type */ + uint8_t dp_hlen; /* hardware addr length */ + uint8_t dp_hops; /* gateway hops */ + uint32_t dp_xid; /* transaction ID */ + uint16_t dp_secs; /* seconds since boot began */ + uint16_t dp_flags; + uint8_t dp_ciaddr[4]; /* client IP address */ + uint8_t dp_yiaddr[4]; /* 'your' IP address */ + uint8_t dp_siaddr[4]; /* server IP address */ + uint8_t dp_giaddr[4]; /* gateway IP address */ + uint8_t dp_chaddr[16]; /* client hardware address */ + uint8_t dp_legacy[192]; + uint8_t dp_magic[4]; + uint8_t dp_options[275]; /* options area */ +} DHCP_TYPE; + +DHCP_TYPE dhcp_data; +static struct udp_pcb *pcb = NULL; +static dhcp_config_t *config = NULL; + +char magic_cookie[] = {0x63,0x82,0x53,0x63}; + +static uint32_t get_ip(const uint8_t *pnt) +{ + uint32_t result; + memcpy(&result, pnt, sizeof(result)); + return result; +} + +static void set_ip(uint8_t *pnt, uint32_t value) +{ + memcpy(pnt, &value, sizeof(value)); +} + +static dhcp_entry_t *entry_by_ip(uint32_t ip) +{ + int i; + for (i = 0; i < config->num_entry; i++) + if (get_ip(config->entries[i].addr) == ip) + return &config->entries[i]; + return NULL; +} + +static dhcp_entry_t *entry_by_mac(uint8_t *mac) +{ + int i; + for (i = 0; i < config->num_entry; i++) + if (memcmp(config->entries[i].mac, mac, 6) == 0) + return &config->entries[i]; + return NULL; +} + +static __inline bool is_vacant(dhcp_entry_t *entry) +{ + return memcmp("\0\0\0\0\0", entry->mac, 6) == 0; +} + +static dhcp_entry_t *vacant_address() +{ + int i; + for (i = 0; i < config->num_entry; i++) + if (is_vacant(config->entries + i)) + return config->entries + i; + return NULL; +} + +static __inline void free_entry(dhcp_entry_t *entry) +{ + memset(entry->mac, 0, 6); +} + +uint8_t *find_dhcp_option(uint8_t *attrs, int size, uint8_t attr) +{ + int i = 0; + while ((i + 1) < size) + { + int next = i + attrs[i + 1] + 2; + if (next > size) return NULL; + if (attrs[i] == attr) + return attrs + i; + i = next; + } + return NULL; +} + +int fill_options(void *dest, + uint8_t msg_type, + const char *domain, + uint32_t dns, + int lease_time, + uint32_t serverid, + uint32_t router, + uint32_t subnet) +{ + uint8_t *ptr = (uint8_t *)dest; + /* ACK message type */ + *ptr++ = 53; + *ptr++ = 1; + *ptr++ = msg_type; + + /* dhcp server identifier */ + *ptr++ = DHCP_SERVERID; + *ptr++ = 4; + set_ip(ptr, serverid); + ptr += 4; + + /* lease time */ + *ptr++ = DHCP_LEASETIME; + *ptr++ = 4; + *ptr++ = (lease_time >> 24) & 0xFF; + *ptr++ = (lease_time >> 16) & 0xFF; + *ptr++ = (lease_time >> 8) & 0xFF; + *ptr++ = (lease_time >> 0) & 0xFF; + + /* subnet mask */ + *ptr++ = DHCP_SUBNETMASK; + *ptr++ = 4; + set_ip(ptr, subnet); + ptr += 4; + + /* router */ + if (router != 0) + { + *ptr++ = DHCP_ROUTER; + *ptr++ = 4; + set_ip(ptr, router); + ptr += 4; + } + + /* domain name */ + if (domain != NULL) + { + int len = strlen(domain); + *ptr++ = DHCP_DNSDOMAIN; + *ptr++ = len; + memcpy(ptr, domain, len); + ptr += len; + } + + /* domain name server (DNS) */ + if (dns != 0) + { + *ptr++ = DHCP_DNSSERVER; + *ptr++ = 4; + set_ip(ptr, dns); + ptr += 4; + } + + /* end */ + *ptr++ = DHCP_END; + return ptr - (uint8_t *)dest; +} + +static void udp_recv_proc(void *arg, struct udp_pcb *upcb, struct pbuf *p, struct ip_addr *addr, u16_t port) +{ + uint8_t *ptr; + dhcp_entry_t *entry; + struct pbuf *pp; + + int n = p->len; + if (n > sizeof(dhcp_data)) n = sizeof(dhcp_data); + memcpy(&dhcp_data, p->payload, n); + switch (dhcp_data.dp_options[2]) + { + case DHCP_DISCOVER: + entry = entry_by_mac(dhcp_data.dp_chaddr); + if (entry == NULL) entry = vacant_address(); + if (entry == NULL) break; + + dhcp_data.dp_op = 2; /* reply */ + dhcp_data.dp_secs = 0; + dhcp_data.dp_flags = 0; + set_ip(dhcp_data.dp_yiaddr, get_ip(entry->addr)); + memcpy(dhcp_data.dp_magic, magic_cookie, 4); + + memset(dhcp_data.dp_options, 0, sizeof(dhcp_data.dp_options)); + + fill_options(dhcp_data.dp_options, + DHCP_OFFER, + config->domain, + get_ip(config->dns), + entry->lease, + get_ip(config->addr), + get_ip(config->addr), + get_ip(entry->subnet)); + + pp = pbuf_alloc(PBUF_TRANSPORT, sizeof(dhcp_data), PBUF_POOL); + if (pp == NULL) break; + memcpy(pp->payload, &dhcp_data, sizeof(dhcp_data)); + udp_sendto(upcb, pp, IP_ADDR_BROADCAST, port); + pbuf_free(pp); + break; + + case DHCP_REQUEST: + /* 1. find requested ipaddr in option list */ + ptr = find_dhcp_option(dhcp_data.dp_options, sizeof(dhcp_data.dp_options), DHCP_IPADDRESS); + if (ptr == NULL) break; + if (ptr[1] != 4) break; + ptr += 2; + + /* 2. does hw-address registered? */ + entry = entry_by_mac(dhcp_data.dp_chaddr); + if (entry != NULL) free_entry(entry); + + /* 3. find requested ipaddr */ + entry = entry_by_ip(get_ip(ptr)); + if (entry == NULL) break; + if (!is_vacant(entry)) break; + + /* 4. fill struct fields */ + memcpy(dhcp_data.dp_yiaddr, ptr, 4); + dhcp_data.dp_op = 2; /* reply */ + dhcp_data.dp_secs = 0; + dhcp_data.dp_flags = 0; + memcpy(dhcp_data.dp_magic, magic_cookie, 4); + + /* 5. fill options */ + memset(dhcp_data.dp_options, 0, sizeof(dhcp_data.dp_options)); + + fill_options(dhcp_data.dp_options, + DHCP_ACK, + config->domain, + get_ip(config->dns), + entry->lease, + get_ip(config->addr), + get_ip(config->addr), + get_ip(entry->subnet)); + + /* 6. send ACK */ + pp = pbuf_alloc(PBUF_TRANSPORT, sizeof(dhcp_data), PBUF_POOL); + if (pp == NULL) break; + memcpy(entry->mac, dhcp_data.dp_chaddr, 6); + memcpy(pp->payload, &dhcp_data, sizeof(dhcp_data)); + udp_sendto(upcb, pp, IP_ADDR_BROADCAST, port); + pbuf_free(pp); + break; + + default: + break; + } + pbuf_free(p); +} + +err_t dhserv_init(dhcp_config_t *c) +{ + err_t err; + udp_init(); + dhserv_free(); + pcb = udp_new(); + if (pcb == NULL) + return ERR_MEM; + err = udp_bind(pcb, IP_ADDR_ANY, c->port); + if (err != ERR_OK) + { + dhserv_free(); + return err; + } + udp_recv(pcb, udp_recv_proc, NULL); + config = c; + return ERR_OK; +} + +void dhserv_free(void) +{ + if (pcb == NULL) return; + udp_remove(pcb); + pcb = NULL; +} diff --git a/src/dhcp-server/dhserver.h b/src/dhcp-server/dhserver.h new file mode 100644 index 0000000..8aff57c --- /dev/null +++ b/src/dhcp-server/dhserver.h @@ -0,0 +1,63 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015 by Sergey Fetisov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/* + * version: 1.0 demo (7.02.2015) + * brief: tiny dhcp ipv4 server using lwip (pcb) + * ref: https://lists.gnu.org/archive/html/lwip-users/2012-12/msg00016.html + */ + +#ifndef DHSERVER_H +#define DHSERVER_H + +#include +#include +#include +#include +#include "lwip/err.h" +#include "lwip/udp.h" +#include "netif/etharp.h" + +typedef struct dhcp_entry +{ + uint8_t mac[6]; + uint8_t addr[4]; + uint8_t subnet[4]; + uint32_t lease; +} dhcp_entry_t; + +typedef struct dhcp_config +{ + uint8_t addr[4]; + uint16_t port; + uint8_t dns[4]; + const char *domain; + int num_entry; + dhcp_entry_t *entries; +} dhcp_config_t; + +err_t dhserv_init(dhcp_config_t *config); +void dhserv_free(void); + +#endif /* DHSERVER_H */ diff --git a/src/dns-server/dnserver.c b/src/dns-server/dnserver.c new file mode 100644 index 0000000..aaa7ebf --- /dev/null +++ b/src/dns-server/dnserver.c @@ -0,0 +1,198 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015 by Sergey Fetisov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/* + * version: 1.0 demo (7.02.2015) + * brief: tiny dns ipv4 server using lwip (pcb) + */ + +#include "dnserver.h" + +#define DNS_MAX_HOST_NAME_LEN 128 + +static struct udp_pcb *pcb = NULL; +dns_query_proc_t query_proc = NULL; + +#pragma pack(push, 1) +typedef struct +{ +#if BYTE_ORDER == LITTLE_ENDIAN + uint8_t rd: 1, /* Recursion Desired */ + tc: 1, /* Truncation Flag */ + aa: 1, /* Authoritative Answer Flag */ + opcode: 4, /* Operation code */ + qr: 1; /* Query/Response Flag */ + uint8_t rcode: 4, /* Response Code */ + z: 3, /* Zero */ + ra: 1; /* Recursion Available */ +#else + uint8_t qr: 1, /* Query/Response Flag */ + opcode: 4, /* Operation code */ + aa: 1, /* Authoritative Answer Flag */ + tc: 1, /* Truncation Flag */ + rd: 1; /* Recursion Desired */ + uint8_t ra: 1, /* Recursion Available */ + z: 3, /* Zero */ + rcode: 4; /* Response Code */ +#endif +} dns_header_flags_t; + +typedef struct +{ + uint16_t id; + dns_header_flags_t flags; + uint16_t n_record[4]; +} dns_header_t; + +typedef struct dns_answer +{ + uint16_t name; + uint16_t type; + uint16_t Class; + uint32_t ttl; + uint16_t len; + uint32_t addr; +} dns_answer_t; +#pragma pack(pop) + +typedef struct dns_query +{ + char name[DNS_MAX_HOST_NAME_LEN]; + uint16_t type; + uint16_t Class; +} dns_query_t; + +static uint16_t get_uint16(const uint8_t *pnt) +{ + uint16_t result; + memcpy(&result, pnt, sizeof(result)); + return result; +} + +static int parse_next_query(void *data, int size, dns_query_t *query) +{ + int len; + int lables; + uint8_t *ptr; + + len = 0; + lables = 0; + ptr = (uint8_t *)data; + + while (true) + { + uint8_t lable_len; + if (size <= 0) return -1; + lable_len = *ptr++; + size--; + if (lable_len == 0) break; + if (lables > 0) + { + if (len == DNS_MAX_HOST_NAME_LEN) return -2; + query->name[len++] = '.'; + } + if (lable_len > size) return -1; + if (len + lable_len >= DNS_MAX_HOST_NAME_LEN) return -2; + memcpy(&query->name[len], ptr, lable_len); + len += lable_len; + ptr += lable_len; + size -= lable_len; + lables++; + } + + if (size < 4) return -1; + query->name[len] = 0; + query->type = get_uint16(ptr); + ptr += 2; + query->Class = get_uint16(ptr); + ptr += 2; + return ptr - (uint8_t *)data; +} + +static void udp_recv_proc(void *arg, struct udp_pcb *upcb, struct pbuf *p, struct ip_addr *addr, u16_t port) +{ + int len; + dns_header_t *header; + static dns_query_t query; + struct pbuf *out; + ip_addr_t host_addr; + dns_answer_t *answer; + + if (p->len <= sizeof(dns_header_t)) goto error; + header = (dns_header_t *)p->payload; + if (header->flags.qr != 0) goto error; + if (ntohs(header->n_record[0]) != 1) goto error; + + len = parse_next_query(header + 1, p->len - sizeof(dns_header_t), &query); + if (len < 0) goto error; + if (!query_proc(query.name, &host_addr)) goto error; + + len += sizeof(dns_header_t); + out = pbuf_alloc(PBUF_TRANSPORT, len + 16, PBUF_POOL); + if (out == NULL) goto error; + + memcpy(out->payload, p->payload, len); + header = (dns_header_t *)out->payload; + header->flags.qr = 1; + header->n_record[1] = htons(1); + answer = (struct dns_answer *)((uint8_t *)out->payload + len); + answer->name = htons(0xC00C); + answer->type = htons(1); + answer->Class = htons(1); + answer->ttl = htonl(32); + answer->len = htons(4); + answer->addr = host_addr.addr; + + udp_sendto(upcb, out, addr, port); + pbuf_free(out); + +error: + pbuf_free(p); +} + +err_t dnserv_init(ip_addr_t *bind, uint16_t port, dns_query_proc_t qp) +{ + err_t err; + udp_init(); + dnserv_free(); + pcb = udp_new(); + if (pcb == NULL) + return ERR_MEM; + err = udp_bind(pcb, bind, port); + if (err != ERR_OK) + { + dnserv_free(); + return err; + } + udp_recv(pcb, udp_recv_proc, NULL); + query_proc = qp; + return ERR_OK; +} + +void dnserv_free() +{ + if (pcb == NULL) return; + udp_remove(pcb); + pcb = NULL; +} diff --git a/src/dns-server/dnserver.h b/src/dns-server/dnserver.h new file mode 100644 index 0000000..0bb1e60 --- /dev/null +++ b/src/dns-server/dnserver.h @@ -0,0 +1,47 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015 by Sergey Fetisov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/* + * version: 1.0 demo (7.02.2015) + * brief: tiny dns ipv4 server using lwip (pcb) + */ + +#ifndef DNSERVER +#define DNSERVER + +#include +#include +#include +#include +#include "lwip/def.h" +#include "lwip/err.h" +#include "lwip/udp.h" +#include "netif/etharp.h" + +typedef bool (*dns_query_proc_t)(const char *name, ip_addr_t *addr); + +err_t dnserv_init(ip_addr_t *bind, uint16_t port, dns_query_proc_t query_proc); +void dnserv_free(void); + +#endif diff --git a/src/lwip-1.4.1/CHANGELOG b/src/lwip-1.4.1/CHANGELOG new file mode 100644 index 0000000..af68299 --- /dev/null +++ b/src/lwip-1.4.1/CHANGELOG @@ -0,0 +1,3349 @@ +HISTORY + +(CVS HEAD) + + * [Enter new changes just after this line - do not remove this line] + + ++ New features: + + + ++ Bugfixes: + + + + +(STABLE-1.4.1) + + ++ New features: + + 2012-03-25: Simon Goldschmidt (idea by Mason) + * posix/*: added posix-compatibility include files posix/netdb.h and posix/sys/socket.h + which are a simple wrapper to the correct lwIP include files. + + 2012-01-16: Simon Goldschmidt + * opt.h, icmp.c: Added option CHECKSUM_GEN_ICMP + + 2011-12-17: Simon Goldschmidt + * ip.h: implemented API functions to access so_options of IP pcbs (UDP, TCP, RAW) + (fixes bug #35061) + + 2011-09-27: Simon Goldschmidt + * opt.h, tcp.c, tcp_in.c: Implemented limiting data on ooseq queue (task #9989) + (define TCP_OOSEQ_MAX_BYTES / TCP_OOSEQ_MAX_PBUFS in lwipopts.h) + + 2011-09-21: Simon Goldschmidt + * opt.h, api.h, api_lib.c, api_msg.h/.c, sockets.c: Implemented timeout on + send (TCP only, bug #33820) + + 2011-09-21: Simon Goldschmidt + * init.c: Converted runtime-sanity-checks into compile-time checks that can + be disabled (since runtime checks can often not be seen on embedded targets) + + 2011-09-11: Simon Goldschmidt + * ppp.h, ppp_impl.h: splitted ppp.h to an internal and external header file + to get a clear separation of which functions an application or port may use + (task #11281) + + 2011-09-11: Simon Goldschmidt + * opt.h, tcp_impl.h, tcp.c, udp.h/.c: Added a config option to randomize + initial local TCP/UDP ports (so that different port ranges are used after + a reboot; bug #33818; this one added tcp_init/udp_init functions again) + + 2011-09-03: Simon Goldschmidt + * dhcp.c: DHCP uses LWIP_RAND() for xid's (bug #30302) + + 2011-08-24: Simon Goldschmidt + * opt.h, netif.h/.c: added netif remove callback (bug #32397) + + 2011-07-26: Simon Goldschmidt + * etharp.c: ETHARP_SUPPORT_VLAN: add support for an external VLAN filter + function instead of only checking for one VLAN (define ETHARP_VLAN_CHECK_FN) + + 2011-07-21: Simon Goldschmidt (patch by hanhui) + * ip4.c, etharp.c, pbuf.h: bug #33634 ip_forward() have a faulty behaviour: + Added pbuf flags to mark incoming packets as link-layer broadcast/multicast. + Also added code to allow ip_forward() to forward non-broadcast packets to + the input netif (set IP_FORWARD_ALLOW_TX_ON_RX_NETIF==1). + + 2011-06-26: Simon Goldschmidt (patch by Cameron Gutman) + * tcp.c, tcp_out.c: bug #33604: added some more asserts to check that + pcb->state != LISTEN + + 2011-05-14: Simon Goldschmidt (patch by Stphane Lesage) + * tcpip.c/.h: patch #7449 allow tcpip callback from interrupt with static + memory message + + + ++ Bugfixes: + + 2012-09-26: Simon Goldschmidt + * api_msg.c: fixed bug #37405 'err_tcp()' uses already freed 'netconn' object + + 2012-09-26: patch by Henrik Persson + * dhcp.c: patch #7843 Fix corner case with dhcp timeouts + + 2012-09-26: patch by Henrik Persson + * dhcp.c: patch #7840 Segfault in dhcp_parse_reply if no end marker in dhcp packet + + 2012-08-22: Simon Goldschmidt + * memp.c: fixed bug #37166: memp_sanity check loops itself + + 2012-05-08: Simon Goldschmidt + * tcp_out.c: fixed bug: #36380 unsent_oversize mismatch in 1.4.1RC1 (this was + a debug-check issue only) + + 2012-03-27: Simon Goldschmidt + * vj.c: fixed bug #35756 header length calculation problem in ppp/vj.c + + 2012-03-27: Simon Goldschmidt (patch by Mason) + * tcp_out.c: fixed bug #35945: SYN packet should provide the recv MSS not the + send MSS + + 2012-03-22: Simon Goldschmidt + * ip4.c: fixed bug #35927: missing refragmentaion in ip_forward + + 2012-03-20: Simon Goldschmidt (patch by Mason) + * netdb.c: fixed bug #35907: lwip_gethostbyname_r returns an invalid h_addr_list + + 2012-03-12: Simon Goldschmidt (patch by Bostjan Meglic) + * ppp.c: fixed bug #35809: PPP GetMask(): Compiler warning on big endian, + possible bug on little endian system + + 2012-02-23: Simon Goldschmidt + * etharp.c: fixed bug #35595: Impossible to send broadcast without a gateway + (introduced when fixing bug# 33551) + + 2012-02-16: Simon Goldschmidt + * ppp.c: fixed pbuf leak when PPP session is aborted through pppSigHUP() + (bug #35541: PPP Memory Leak) + + 2012-02-16: Simon Goldschmidt + * etharp.c: fixed bug #35531: Impossible to send multicast without a gateway + (introduced when fixing bug# 33551) + + 2012-02-16: Simon Goldschmidt (patch by Stphane Lesage) + * msg_in.c, msg_out.c: fixed bug #35536 SNMP: error too big response is malformed + + 2012-02-15: Simon Goldschmidt + * init.c: fixed bug #35537: MEMP_NUM_* sanity checks should be disabled with + MEMP_MEM_MALLOC==1 + + 2012-02-12: Simon Goldschmidt + * tcp.h, tcp_in.c, tcp_out.c: partly fixed bug #25882: TCP hangs on + MSS > pcb->snd_wnd (by not creating segments bigger than half the window) + + 2012-02-11: Simon Goldschmidt + * tcp.c: fixed bug #35435: No pcb state check before adding it to time-wait + queue while closing + + 2012-01-22: Simon Goldschmidt + * tcp.c, tcp_in.c: fixed bug #35305: pcb may be freed too early on shutdown(WR) + + 2012-01-21: Simon Goldschmidt + * tcp.c: fixed bug #34636: FIN_WAIT_2 - Incorrect shutdown of TCP pcb + + 2012-01-20: Simon Goldschmidt + * dhcp.c: fixed bug #35151: DHCP asserts on incoming option lengths + + 2012-01-20: Simon Goldschmidt + * pbuf.c: fixed bug #35291: NULL pointer in pbuf_copy + + 2011-11-25: Simon Goldschmidt + * tcp.h/.c, tcp_impl.h, tcp_in.c: fixed bug #31177: tcp timers can corrupt + tcp_active_pcbs in some cases + + 2011-11-23: Simon Goldschmidt + * sys.c: fixed bug #34884: sys_msleep() body needs to be surrounded with + '#ifndef sys_msleep' + + 2011-11-22: Simon Goldschmidt + * netif.c, etharp.h/.c: fixed bug #34684: Clear the arp table cache when + netif is brought down + + 2011-10-28: Simon Goldschmidt + * tcp_in.c: fixed bug #34638: Dead code in tcp_receive - pcb->dupacks + + 2011-10-23: Simon Goldschmidt + * mem.c: fixed bug #34429: possible memory corruption with + LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT set to 1 + + 2011-10-18: Simon Goldschmidt + * arch.h, netdb.c: fixed bug #34592: lwip_gethostbyname_r uses nonstandard + error value + + 2011-10-18: Simon Goldschmidt + * opt.h: fixed default values of TCP_SNDLOWAT and TCP_SNDQUEUELOWAT for small + windows (bug #34176 select after non-blocking send times out) + + 2011-10-18: Simon Goldschmidt + * tcp_impl.h, tcp_out.c: fixed bug #34587: TCP_BUILD_MSS_OPTION doesn't + consider netif->mtu, causes slow network + + 2011-10-18: Simon Goldschmidt + * sockets.c: fixed bug #34581 missing parentheses in udplite sockets code + + 2011-10-18: Simon Goldschmidt + * sockets.h: fixed bug #34580 fcntl() is missing in LWIP_COMPAT_SOCKETS + + 2011-10-17: Simon Goldschmidt + * api_msg.c: fixed bug #34569: shutdown(SHUT_WR) crashes netconn/socket api + + 2011-10-13: Simon Goldschmidt + * tcp_in.c, tcp_out.c: fixed bug #34517 (persist timer is started although no + zero window is received) by starting the persist timer when a zero window is + received, not when we have more data queued for sending than fits into the + window + + 2011-10-13: Simon Goldschmidt + * def.h, timers.c: fixed bug #34541: LWIP_U32_DIFF is unnecessarily complex + + 2011-10-13: Simon Goldschmidt + * sockets.c, api_lib.c: fixed bug #34540: compiler error when CORE_LOCKING is + used and not all protocols are enabled + + 2011-10-12: Simon Goldschmidt + * pbuf.c: fixed bug #34534: Error in sending fragmented IP if MEM_ALIGNMENT > 4 + + 2011-10-09: Simon Goldschmidt + * tcp_out.c: fixed bug #34426: tcp_zero_window_probe() transmits incorrect + byte value when pcb->unacked != NULL + + 2011-10-09: Simon Goldschmidt + * ip4.c: fixed bug #34447 LWIP_IP_ACCEPT_UDP_PORT(dst_port) wrong + + 2011-09-27: Simon Goldschmidt + * tcp_in.c, tcp_out.c: Reset pcb->unsent_oversize in 2 more places... + + 2011-09-27: Simon Goldschmidt + * tcp_in.c: fixed bug #28288: Data after FIN in oos queue + + 2011-09-27: Simon Goldschmidt + * dhcp.c: fixed bug #34406 dhcp_option_hostname() can overflow the pbuf + + 2011-09-24: Simon Goldschmidt + * mem.h: fixed bug #34377 MEM_SIZE_F is not defined if MEM_LIBC_MALLOC==1 + + 2011-09-23: Simon Goldschmidt + * pbuf.h, tcp.c, tcp_in.c: fixed bug #33871: rejecting TCP_EVENT_RECV() for + the last packet including FIN can lose data + + 2011-09-22: Simon Goldschmidt + * tcp_impl.h: fixed bug #34355: nagle does not take snd_buf/snd_queuelen into + account + + 2011-09-21: Simon Goldschmidt + * opt.h: fixed default value of TCP_SND_BUF to not violate the sanity checks + in init.c + + 2011-09-20: Simon Goldschmidt + * timers.c: fixed bug #34337 (possible NULL pointer in sys_check_timeouts) + + 2011-09-11: Simon Goldschmidt + * tcp_out.c: use pcb->mss instead of TCP_MSS for preallocate mss-sized pbufs + (bug #34019) + + 2011-09-09: Simon Goldschmidt + * udp.c: fixed bug #34072: UDP broadcast is received from wrong UDP pcb if + udp port matches + + 2011-09-03: Simon Goldschmidt + * tcp_in.c: fixed bug #33952 PUSH flag in incoming packet is lost when packet + is aggregated and sent to application + + 2011-09-01: Simon Goldschmidt + * opt.h: fixed bug #31809 LWIP_EVENT_API in opts.h is inconsistent compared + to other options + + 2011-09-01: Simon Goldschmidt + * tcp_in.c: fixed bug #34111 RST for ACK to listening pcb has wrong seqno + + 2011-08-24: Simon Goldschmidt + * api_msg.c, sockets.c: fixed bug #33956 Wrong error returned when calling + accept() on UDP connections + + 2011-08-24: Simon Goldschmidt + * sockets.h: fixed bug #34057 socklen_t should be a typedef + + 2011-08-24: Simon Goldschmidt + * pbuf.c: fixed bug #34112 Odd check in pbuf_alloced_custom (typo) + + 2011-08-24: Simon Goldschmidt + * dhcp.c: fixed bug #34122 dhcp: hostname can overflow + + 2011-08-24: Simon Goldschmidt + * netif.c: fixed bug #34121 netif_add/netif_set_ipaddr fail on NULL ipaddr + + 2011-08-22: Simon Goldschmidt + * tcp_out.c: fixed bug #33962 TF_FIN not always set after FIN is sent. (This + merely prevents nagle from not transmitting fast after closing.) + + 2011-07-22: Simon Goldschmidt + * api_lib.c, api_msg.c, sockets.c, api.h: fixed bug #31084 (socket API returns + always EMSGSIZE on non-blocking sockets if data size > send buffers) -> now + lwip_send() sends as much as possible for non-blocking sockets + + 2011-07-22: Simon Goldschmidt + * pbuf.c/.h, timers.c: freeing ooseq pbufs when the pbuf pool is empty implemented + for NO_SYS==1: when not using sys_check_timeouts(), call PBUF_CHECK_FREE_OOSEQ() + at regular intervals from main level. + + 2011-07-21: Simon Goldschmidt + * etharp.c: fixed bug #33551 (ARP entries may time out although in use) by + sending an ARP request when an ARP entry is used in the last minute before + it would time out. + + 2011-07-04: Simon Goldschmidt + * sys_arch.txt: Fixed documentation after changing sys arch prototypes for 1.4.0. + + 2011-06-26: Simon Goldschmidt + * tcp.c: fixed bug #31723 (tcp_kill_prio() kills pcbs with the same prio) by + updating its documentation only. + + 2011-06-26: Simon Goldschmidt + * mem.c: fixed bug #33545: With MEM_USE_POOLS==1, mem_malloc can return an + unaligned pointer. + + 2011-06-26: Simon Goldschmidt + * mem.c: fixed bug #33544 "warning in mem.c in lwip 1.4.0 with NO_SYS=1" + + 2011-05-25: Simon Goldschmidt + * tcp.c: fixed bug #33398 (pointless conversion when checking TCP port range) + + + +(STABLE-1.4.0) + + ++ New features: + + 2011-03-27: Simon Goldschmidt + * tcp_impl.h, tcp_in.c, tcp_out.c: Removed 'dataptr' from 'struct tcp_seg' and + calculate it in tcp_zero_window_probe (the only place where it was used). + + 2010-11-21: Simon Goldschmidt + * dhcp.c/.h: Added a function to deallocate the struct dhcp from a netif + (fixes bug #31525). + + 2010-07-12: Simon Goldschmidt (patch by Stephane Lesage) + * ip.c, udp.c/.h, pbuf.h, sockets.c: task #10495: Added support for + IP_MULTICAST_LOOP at socket- and raw-API level. + + 2010-06-16: Simon Goldschmidt + * ip.c: Added an optional define (LWIP_IP_ACCEPT_UDP_PORT) that can allow + link-layer-addressed UDP traffic to be received while a netif is down (just + like DHCP during configuration) + + 2010-05-22: Simon Goldschmidt + * many many files: bug #27352: removed packing from ip_addr_t, the packed + version is now only used in protocol headers. Added global storage for + current src/dest IP address while in input functions. + + 2010-05-16: Simon Goldschmidt + * def.h: task #10391: Add preprocessor-macros for compile-time htonl + calculation (and use them throughout the stack where applicable) + + 2010-05-16: Simon Goldschmidt + * opt.h, memp_std.h, memp.c, ppp_oe.h/.c: PPPoE now uses its own MEMP pool + instead of the heap (moved struct pppoe_softc from ppp_oe.c to ppp_oe.h) + + 2010-05-16: Simon Goldschmidt + * opt.h, memp_std.h, dns.h/.c: DNS_LOCAL_HOSTLIST_IS_DYNAMIC uses its own + MEMP pool instead of the heap + + 2010-05-13: Simon Goldschmidt + * tcp.c, udp.c: task #6995: Implement SO_REUSEADDR (correctly), added + new option SO_REUSE_RXTOALL to pass received UDP broadcast/multicast + packets to more than one pcb. + + 2010-05-02: Simon Goldschmidt + * netbuf.h/.c, sockets.c, api_msg.c: use checksum-on-copy for sending + UDP data for LWIP_NETIF_TX_SINGLE_PBUF==1 + + 2010-04-30: Simon Goldschmidt + * udp.h/.c, pbuf.h/.c: task #6849: added udp_send(_to/_if) functions that + take a precalculated checksum, added pbuf_fill_chksum() to copy data + into a pbuf and at the same time calculating the checksum for that data + + 2010-04-29: Simon Goldschmidt + * ip_addr.h, etharp.h/.c, autoip.c: Create overridable macros for copying + 2-byte-aligned IP addresses and MAC addresses + + 2010-04-28: Patch by Bill Auerbach + * ip.c: Inline generating IP checksum to save a function call + + 2010-04-14: Simon Goldschmidt + * tcpip.h/.c, timers.c: Added an overridable define to get informed when the + tcpip_thread processes messages or timeouts to implement a watchdog. + + 2010-03-28: Simon Goldschmidt + * ip_frag.c: create a new (contiguous) PBUF_RAM for every outgoing + fragment if LWIP_NETIF_TX_SINGLE_PBUF==1 + + 2010-03-27: Simon Goldschmidt + * etharp.c: Speedup TX by moving code from find_entry to etharp_output/ + etharp_query to prevent unnecessary function calls (inspired by + patch #7135). + + 2010-03-20: Simon Goldschmidt + * opt.h, tcpip.c/.h: Added an option to disable tcpip_(un)timeout code + since the linker cannot do this automatically to save space. + + 2010-03-20: Simon Goldschmidt + * opt.h, etharp.c/.h: Added support for static ARP table entries + + 2010-03-14: Simon Goldschmidt + * tcp_impl.h, tcp_out.c, inet_chksum.h/.c: task #6849: Calculate checksum + when creating TCP segments, not when (re-)transmitting them. + + 2010-03-07: Simon Goldschmidt + * sockets.c: bug #28775 (select/event_callback: only check select_cb_list + on change) plus use SYS_LIGHTWEIGHT_PROT to protect the select code. + This should speed up receiving data on sockets as the select code in + event_callback is only executed when select is waiting. + + 2010-03-06: Simon Goldschmidt + * tcp_out.c: task #7013 (Create option to have all packets delivered to + netif->output in one piece): Always copy to try to create single pbufs + in tcp_write. + + 2010-03-06: Simon Goldschmidt + * api.h, api_lib.c, sockets.c: task #10167 (sockets: speed up TCP recv + by not allocating a netbuf): added function netconn_recv_tcp_pbuf() + for tcp netconns to receive pbufs, not netbufs; use that function + for tcp sockets. + + 2010-03-05: Jakob Ole Stoklundsen / Simon Goldschmidt + * opt.h, tcp.h, tcp_impl.h, tcp.c, tcp_in.c, tcp_out.c: task #7040: + Work on tcp_enqueue: Don't waste memory when chaining segments, + added option TCP_OVERSIZE to prevent creating many small pbufs when + calling tcp_write with many small blocks of data. Instead, pbufs are + allocated larger than needed and the space is used for later calls to + tcp_write. + + 2010-02-21: Simon Goldschmidt + * stats.c/.h: Added const char* name to mem- and memp-stats for easier + debugging. + + 2010-02-21: Simon Goldschmidt + * tcp.h (and usages), added tcp_impl.h: Splitted API and internal + implementation of tcp to make API usage cleare to application programmers + + 2010-02-14: Simon Goldschmidt/Stephane Lesage + * ip_addr.h: Improved some defines working on ip addresses, added faster + macro to copy addresses that cannot be NULL + + 2010-02-13: Simon Goldschmidt + * api.h, api_lib.c, api_msg.c, sockets.c: task #7865 (implement non- + blocking send operation) + + 2010-02-12: Simon Goldschmidt + * sockets.c/.h: Added a minimal version of posix fctl() to have a + standardised way to set O_NONBLOCK for nonblocking sockets. + + 2010-02-12: Simon Goldschmidt + * dhcp.c/.h, autoip.c/.h: task #10139 (Prefer statically allocated + memory): added autoip_set_struct() and dhcp_set_struct() to let autoip + and dhcp work with user-allocated structs instead of callin mem_malloc + + 2010-02-12: Simon Goldschmidt/Jeff Barber + * tcp.c/h: patch #6865 (SO_REUSEADDR for TCP): if pcb.so_options has + SOF_REUSEADDR set, allow binding to endpoint in TIME_WAIT + + 2010-02-12: Simon Goldschmidt + * sys layer: task #10139 (Prefer statically allocated memory): converted + mbox and semaphore functions to take pointers to sys_mbox_t/sys_sem_t; + converted sys_mbox_new/sys_sem_new to take pointers and return err_t; + task #7212: Add Mutex concept in sys_arch (define LWIP_COMPAT_MUTEX + to let sys.h use binary semaphores instead of mutexes - as before) + + 2010-02-09: Simon Goldschmidt (Simon Kallweit) + * timers.c/.h: Added function sys_restart_timeouts() from patch #7085 + (Restart system timeout handling) + + 2010-02-09: Simon Goldschmidt + * netif.c/.h, removed loopif.c/.h: task #10153 (Integrate loopif into + netif.c) - loopif does not have to be created by the port any more, + just define LWIP_HAVE_LOOPIF to 1. + + 2010-02-08: Simon Goldschmidt + * inet.h, ip_addr.c/.h: Added reentrant versions of inet_ntoa/ipaddr_ntoa + inet_ntoa_r/ipaddr_ntoa_r + + 2010-02-08: Simon Goldschmidt + * netif.h: Added netif_s/get_igmp_mac_filter() macros + + 2010-02-05: Simon Goldschmidt + * netif.h: Added function-like macros to get/set the hostname on a netif + + 2010-02-04: Simon Goldschmidt + * nearly every file: Replaced struct ip_addr by typedef ip_addr_t to + make changing the actual implementation behind the typedef easier. + + 2010-02-01: Simon Goldschmidt + * opt.h, memp_std.h, dns.h, netdb.c, memp.c: Let netdb use a memp pool + for allocating memory when getaddrinfo() is called. + + 2010-01-31: Simon Goldschmidt + * dhcp.h, dhcp.c: Reworked the code that parses DHCP options: parse + them once instead of parsing for every option. This also removes + the need for mem_malloc from dhcp_recv and makes it possible to + correctly retrieve the BOOTP file. + + 2010-01-30: simon Goldschmidt + * sockets.c: Use SYS_LIGHTWEIGHT_PROT instead of a semaphore to protect + the sockets array. + + 2010-01-29: Simon Goldschmidt (patch by Laura Garrett) + * api.h, api_msg.c, sockets.c: Added except set support in select + (patch #6860) + + 2010-01-29: Simon Goldschmidt (patch by Laura Garrett) + * api.h, sockets.h, err.h, api_lib.c, api_msg.c, sockets.c, err.c: + Add non-blocking support for connect (partly from patch #6860), + plus many cleanups in socket & netconn API. + + 2010-01-27: Simon Goldschmidt + * opt.h, tcp.h, init.c, api_msg.c: Added TCP_SNDQUEUELOWAT corresponding + to TCP_SNDLOWAT and added tcp_sndqueuelen() - this fixes bug #28605 + + 2010-01-26: Simon Goldschmidt + * snmp: Use memp pools for snmp instead of the heap; added 4 new pools. + + 2010-01-14: Simon Goldschmidt + * ppp.c/.h: Fixed bug #27856: PPP: Set netif link- and status-callback + by adding ppp_set_netif_statuscallback()/ppp_set_netif_linkcallback() + + 2010-01-13: Simon Goldschmidt + * mem.c: The heap now may be moved to user-defined memory by defining + LWIP_RAM_HEAP_POINTER as a void pointer to that memory's address + (patch #6966 and bug #26133) + + 2010-01-10: Simon Goldschmidt (Bill Auerbach) + * opt.h, memp.c: patch #6822 (Add option to place memory pools in + separate arrays) + + 2010-01-10: Simon Goldschmidt + * init.c, igmp.c: patch #6463 (IGMP - Adding Random Delay): added define + LWIP_RAND() for lwip-wide randomization (to be defined in cc.h) + + 2009-12-31: Simon Goldschmidt + * tcpip.c, init.c, memp.c, sys.c, memp_std.h, sys.h, tcpip.h + added timers.c/.h: Separated timer implementation from semaphore/mbox + implementation, moved timer implementation to timers.c/.h, timers are + now only called from tcpip_thread or by explicitly checking them. + (TASK#7235) + + 2009-12-27: Simon Goldschmidt + * opt.h, etharp.h/.c, init.c, tcpip.c: Added an additional option + LWIP_ETHERNET to support ethernet without ARP (necessary for pure PPPoE) + + + ++ Bugfixes: + + 2011-04-20: Simon Goldschmidt + * sys_arch.txt: sys_arch_timeouts() is not needed any more. + + 2011-04-13: Simon Goldschmidt + * tcp.c, udp.c: Fixed bug #33048 (Bad range for IP source port numbers) by + using ports in the IANA private/dynamic range (49152 through 65535). + + 2011-03-29: Simon Goldschmidt, patch by Emil Lhungdahl: + * etharp.h/.c: Fixed broken VLAN support. + + 2011-03-27: Simon Goldschmidt + * tcp.c: Fixed bug #32926 (TCP_RMV(&tcp_bound_pcbs) is called on unbound tcp + pcbs) by checking if the pcb was bound (local_port != 0). + + 2011-03-27: Simon Goldschmidt + * ppp.c: Fixed bug #32280 (ppp: a pbuf is freed twice) + + 2011-03-27: Simon Goldschmidt + * sockets.c: Fixed bug #32906: lwip_connect+lwip_send did not work for udp and + raw pcbs with LWIP_TCPIP_CORE_LOCKING==1. + + 2011-03-27: Simon Goldschmidt + * tcp_out.c: Fixed bug #32820 (Outgoing TCP connections created before route + is present never times out) by starting retransmission timer before checking + route. + + 2011-03-22: Simon Goldschmidt + * ppp.c: Fixed bug #32648 (PPP code crashes when terminating a link) by only + calling sio_read_abort() if the file descriptor is valid. + + 2011-03-14: Simon Goldschmidt + * err.h/.c, sockets.c, api_msg.c: fixed bug #31748 (Calling non-blocking connect + more than once can render a socket useless) since it mainly involves changing + "FATAL" classification of error codes: ERR_USE and ERR_ISCONN just aren't fatal. + + 2011-03-13: Simon Goldschmidt + * sockets.c: fixed bug #32769 (ESHUTDOWN is linux-specific) by fixing + err_to_errno_table (ERR_CLSD: ENOTCONN instead of ESHUTDOWN), ERR_ISCONN: + use EALRADY instead of -1 + + 2011-03-13: Simon Goldschmidt + * api_lib.c: netconn_accept: return ERR_ABRT instead of ERR_CLSD if the + connection has been aborted by err_tcp (since this is not a normal closing + procedure). + + 2011-03-13: Simon Goldschmidt + * tcp.c: tcp_bind: return ERR_VAL instead of ERR_ISCONN when trying to bind + with pcb->state != CLOSED + + 2011-02-17: Simon Goldschmidt + * rawapi.txt: Fixed bug #32561 tcp_poll argument definition out-of-order in + documentation + + 2011-02-17: Simon Goldschmidt + * many files: Added missing U/UL modifiers to fix 16-bit-arch portability. + + 2011-01-24: Simon Goldschmidt + * sockets.c: Fixed bug #31741: lwip_select seems to have threading problems + + 2010-12-02: Simon Goldschmidt + * err.h: Fixed ERR_IS_FATAL so that ERR_WOULDBLOCK is not fatal. + + 2010-11-23: Simon Goldschmidt + * api.h, api_lib.c, api_msg.c, sockets.c: netconn.recv_avail is only used for + LWIP_SO_RCVBUF and ioctl/FIONREAD. + + 2010-11-23: Simon Goldschmidt + * etharp.c: Fixed bug #31720: ARP-queueing: RFC 1122 recommends to queue at + least 1 packet -> ARP_QUEUEING==0 now queues the most recent packet. + + 2010-11-23: Simon Goldschmidt + * tcp_in.c: Fixed bug #30577: tcp_input: don't discard ACK-only packets after + refusing 'refused_data' again. + + 2010-11-22: Simon Goldschmidt + * sockets.c: Fixed bug #31590: getsockopt(... SO_ERROR ...) gives EINPROGRESS + after a successful nonblocking connection. + + 2010-11-22: Simon Goldschmidt + * etharp.c: Fixed bug #31722: IP packets sent with an AutoIP source addr + must be sent link-local + + 2010-11-22: Simon Goldschmidt + * timers.c: patch #7329: tcp_timer_needed prototype was ifdef'ed out for + LWIP_TIMERS==0 + + 2010-11-20: Simon Goldschmidt + * sockets.c: Fixed bug #31170: lwip_setsockopt() does not set socket number + + 2010-11-20: Simon Goldschmidt + * sockets.h: Fixed bug #31304: Changed SHUT_RD, SHUT_WR and SHUT_RDWR to + resemble other stacks. + + 2010-11-20: Simon Goldschmidt + * dns.c: Fixed bug #31535: TCP_SND_QUEUELEN must be at least 2 or else + no-copy TCP writes will never succeed. + + 2010-11-20: Simon Goldschmidt + * dns.c: Fixed bug #31701: Error return value from dns_gethostbyname() does + not match documentation: return ERR_ARG instead of ERR_VAL if not + initialized or wrong argument. + + 2010-10-20: Simon Goldschmidt + * sockets.h: Fixed bug #31385: sizeof(struct sockaddr) is 30 but should be 16 + + 2010-10-05: Simon Goldschmidt + * dhcp.c: Once again fixed #30038: DHCP/AutoIP cooperation failed when + replugging the network cable after an AutoIP address was assigned. + + 2010-08-10: Simon Goldschmidt + * tcp.c: Fixed bug #30728: tcp_new_port() did not check listen pcbs + + 2010-08-03: Simon Goldschmidt + * udp.c, raw.c: Don't chain empty pbufs when sending them (fixes bug #30625) + + 2010-08-01: Simon Goldschmidt (patch by Greg Renda) + * ppp.c: Applied patch #7264 (PPP protocols are rejected incorrectly on big + endian architectures) + + 2010-07-28: Simon Goldschmidt + * api_lib.c, api_msg.c, sockets.c, mib2.c: Fixed compilation with TCP or UDP + disabled. + + 2010-07-27: Simon Goldschmidt + * tcp.c: Fixed bug #30565 (tcp_connect() check bound list): that check did no + harm but never did anything + + 2010-07-21: Simon Goldschmidt + * ip.c: Fixed invalid fix for bug #30402 (CHECKSUM_GEN_IP_INLINE does not + add IP options) + + 2010-07-16: Kieran Mansley + * msg_in.c: Fixed SNMP ASN constant defines to not use ! operator + + 2010-07-10: Simon Goldschmidt + * ip.c: Fixed bug #30402: CHECKSUM_GEN_IP_INLINE does not add IP options + + 2010-06-30: Simon Goldschmidt + * api_msg.c: fixed bug #30300 (shutdown parameter was not initialized in + netconn_delete) + + 2010-06-28: Kieran Mansley + * timers.c remove unportable printing of C function pointers + + 2010-06-24: Simon Goldschmidt + * init.c, timers.c/.h, opt.h, memp_std.h: From patch #7221: added flag + NO_SYS_NO_TIMERS to drop timer support for NO_SYS==1 for easier upgrading + + 2010-06-24: Simon Goldschmidt + * api(_lib).c/.h, api_msg.c/.h, sockets.c/.h: Fixed bug #10088: Correctly + implemented shutdown at socket level. + + 2010-06-21: Simon Goldschmidt + * pbuf.c/.h, ip_frag.c/.h, opt.h, memp_std.h: Fixed bug #29361 (ip_frag has + problems with zero-copy DMA MACs) by adding custom pbufs and implementing + custom pbufs that reference other (original) pbufs. Additionally set + IP_FRAG_USES_STATIC_BUF=0 as default to be on the safe side. + + 2010-06-15: Simon Goldschmidt + * dhcp.c: Fixed bug #29970: DHCP endian issue parsing option responses + + 2010-06-14: Simon Goldschmidt + * autoip.c: Fixed bug #30039: AutoIP does not reuse previous addresses + + 2010-06-12: Simon Goldschmidt + * dhcp.c: Fixed bug #30038: dhcp_network_changed doesn't reset AUTOIP coop + state + + 2010-05-17: Simon Goldschmidt + * netdb.c: Correctly NULL-terminate h_addr_list + + 2010-05-16: Simon Goldschmidt + * def.h/.c: changed the semantics of LWIP_PREFIX_BYTEORDER_FUNCS to prevent + "symbol already defined" i.e. when linking to winsock + + 2010-05-05: Simon Goldschmidt + * def.h, timers.c: Fixed bug #29769 (sys_check_timeouts: sys_now() may + overflow) + + 2010-04-21: Simon Goldschmidt + * api_msg.c: Fixed bug #29617 (sometime cause stall on delete listening + connection) + + 2010-03-28: Luca Ceresoli + * ip_addr.c/.h: patch #7143: Add a few missing const qualifiers + + 2010-03-27: Luca Ceresoli + * mib2.c: patch #7130: remove meaningless const qualifiers + + 2010-03-26: Simon Goldschmidt + * tcp_out.c: Make LWIP_NETIF_TX_SINGLE_PBUF work for TCP, too + + 2010-03-26: Simon Goldschmidt + * various files: Fixed compiling with different options disabled (TCP/UDP), + triggered by bug #29345; don't allocate acceptmbox if LWIP_TCP is disabled + + 2010-03-25: Simon Goldschmidt + * sockets.c: Fixed bug #29332: lwip_select() processes readset incorrectly + + 2010-03-25: Simon Goldschmidt + * tcp_in.c, test_tcp_oos.c: Fixed bug #29080: Correctly handle remote side + overrunning our rcv_wnd in ooseq case. + + 2010-03-22: Simon Goldschmidt + * tcp.c: tcp_listen() did not copy the pcb's prio. + + 2010-03-19: Simon Goldschmidt + * snmp_msg.c: Fixed bug #29256: SNMP Trap address was not correctly set + + 2010-03-14: Simon Goldschmidt + * opt.h, etharp.h: Fixed bug #29148 (Incorrect PBUF_POOL_BUFSIZE for ports + where ETH_PAD_SIZE > 0) by moving definition of ETH_PAD_SIZE to opt.h + and basing PBUF_LINK_HLEN on it. + + 2010-03-08: Simon Goldschmidt + * netif.c, ipv4/ip.c: task #10241 (AutoIP: don't break existing connections + when assiging routable address): when checking incoming packets and + aborting existing connection on address change, filter out link-local + addresses. + + 2010-03-06: Simon Goldschmidt + * sockets.c: Fixed LWIP_NETIF_TX_SINGLE_PBUF for LWIP_TCPIP_CORE_LOCKING + + 2010-03-06: Simon Goldschmidt + * ipv4/ip.c: Don't try to forward link-local addresses + + 2010-03-06: Simon Goldschmidt + * etharp.c: Fixed bug #29087: etharp: don't send packets for LinkLocal- + addresses to gw + + 2010-03-05: Simon Goldschmidt + * dhcp.c: Fixed bug #29072: Correctly set ciaddr based on message-type + and state. + + 2010-03-05: Simon Goldschmidt + * api_msg.c: Correctly set TCP_WRITE_FLAG_MORE when netconn_write is split + into multiple calls to tcp_write. + + 2010-02-21: Simon Goldschmidt + * opt.h, mem.h, dns.c: task #10140: Remove DNS_USES_STATIC_BUF (keep + the implementation of DNS_USES_STATIC_BUF==1) + + 2010-02-20: Simon Goldschmidt + * tcp.h, tcp.c, tcp_in.c, tcp_out.c: Task #10088: Correctly implement + close() vs. shutdown(). Now the application does not get any more + recv callbacks after calling tcp_close(). Added tcp_shutdown(). + + 2010-02-19: Simon Goldschmidt + * mem.c/.h, pbuf.c: Renamed mem_realloc() to mem_trim() to prevent + confusion with realloc() + + 2010-02-15: Simon Goldschmidt/Stephane Lesage + * netif.c/.h: Link status does not depend on LWIP_NETIF_LINK_CALLBACK + (fixes bug #28899) + + 2010-02-14: Simon Goldschmidt + * netif.c: Fixed bug #28877 (Duplicate ARP gratuitous packet with + LWIP_NETIF_LINK_CALLBACK set on) by only sending if both link- and + admin-status of a netif are up + + 2010-02-14: Simon Goldschmidt + * opt.h: Disable ETHARP_TRUST_IP_MAC by default since it slows down packet + reception and is not really necessary + + 2010-02-14: Simon Goldschmidt + * etharp.c/.h: Fixed ARP input processing: only add a new entry if a + request was directed as us (RFC 826, Packet Reception), otherwise + only update existing entries; internalized some functions + + 2010-02-14: Simon Goldschmidt + * netif.h, etharp.c, tcpip.c: Fixed bug #28183 (ARP and TCP/IP cannot be + disabled on netif used for PPPoE) by adding a new netif flag + (NETIF_FLAG_ETHERNET) that tells the stack the device is an ethernet + device but prevents usage of ARP (so that ethernet_input can be used + for PPPoE). + + 2010-02-12: Simon Goldschmidt + * netif.c: netif_set_link_up/down: only do something if the link state + actually changes + + 2010-02-12: Simon Goldschmidt/Stephane Lesage + * api_msg.c: Fixed bug #28865 (Cannot close socket/netconn in non-blocking + connect) + + 2010-02-12: Simon Goldschmidt + * mem.h: Fixed bug #28866 (mem_realloc function defined in mem.h) + + 2010-02-09: Simon Goldschmidt + * api_lib.c, api_msg.c, sockets.c, api.h, api_msg.h: Fixed bug #22110 + (recv() makes receive window update for data that wasn't received by + application) + + 2010-02-09: Simon Goldschmidt/Stephane Lesage + * sockets.c: Fixed bug #28853 (lwip_recvfrom() returns 0 on receive time-out + or any netconn_recv() error) + + 2010-02-09: Simon Goldschmidt + * ppp.c: task #10154 (PPP: Update snmp in/out counters for tx/rx packets) + + 2010-02-09: Simon Goldschmidt + * netif.c: For loopback packets, adjust the stats- and snmp-counters + for the loopback netif. + + 2010-02-08: Simon Goldschmidt + * igmp.c/.h, ip.h: Moved most defines from igmp.h to igmp.c for clarity + since they are not used anywhere else. + + 2010-02-08: Simon Goldschmidt (Stphane Lesage) + * igmp.c, igmp.h, stats.c, stats.h: Improved IGMP stats + (patch from bug #28798) + + 2010-02-08: Simon Goldschmidt (Stphane Lesage) + * igmp.c: Fixed bug #28798 (Error in "Max Response Time" processing) and + another bug when LWIP_RAND() returns zero. + + 2010-02-04: Simon Goldschmidt + * nearly every file: Use macros defined in ip_addr.h (some of them new) + to work with IP addresses (preparation for bug #27352 - Change ip_addr + from struct to typedef (u32_t) - and better code). + + 2010-01-31: Simon Goldschmidt + * netif.c: Don't call the link-callback from netif_set_up/down() since + this invalidly retriggers DHCP. + + 2010-01-29: Simon Goldschmidt + * ip_addr.h, inet.h, def.h, inet.c, def.c, more: Cleanly separate the + portability file inet.h and its contents from the stack: moved htonX- + functions to def.h (and the new def.c - they are not ipv4 dependent), + let inet.h depend on ip_addr.h and not the other way round. + This fixes bug #28732. + + 2010-01-28: Kieran Mansley + * tcp.c: Ensure ssthresh >= 2*MSS + + 2010-01-27: Simon Goldschmidt + * tcp.h, tcp.c, tcp_in.c: Fixed bug #27871: Calling tcp_abort() in recv + callback can lead to accessing unallocated memory. As a consequence, + ERR_ABRT means the application has called tcp_abort()! + + 2010-01-25: Simon Goldschmidt + * snmp_structs.h, msg_in.c: Partly fixed bug #22070 (MIB_OBJECT_WRITE_ONLY + not implemented in SNMP): write-only or not-accessible are still + returned by getnext (though not by get) + + 2010-01-24: Simon Goldschmidt + * snmp: Renamed the private mib node from 'private' to 'mib_private' to + not use reserved C/C++ keywords + + 2010-01-23: Simon Goldschmidt + * sockets.c: Fixed bug #28716: select() returns 0 after waiting for less + than 1 ms + + 2010-01-21: Simon Goldschmidt + * tcp.c, api_msg.c: Fixed bug #28651 (tcp_connect: no callbacks called + if tcp_enqueue fails) both in raw- and netconn-API + + 2010-01-19: Simon Goldschmidt + * api_msg.c: Fixed bug #27316: netconn: Possible deadlock in err_tcp + + 2010-01-18: Iordan Neshev/Simon Goldschmidt + * src/netif/ppp: reorganised PPP sourcecode to 2.3.11 including some + bugfix backports from 2.4.x. + + 2010-01-18: Simon Goldschmidt + * mem.c: Fixed bug #28679: mem_realloc calculates mem_stats wrong + + 2010-01-17: Simon Goldschmidt + * api_lib.c, api_msg.c, (api_msg.h, api.h, sockets.c, tcpip.c): + task #10102: "netconn: clean up conn->err threading issues" by adding + error return value to struct api_msg_msg + + 2010-01-17: Simon Goldschmidt + * api.h, api_lib.c, sockets.c: Changed netconn_recv() and netconn_accept() + to return err_t (bugs #27709 and #28087) + + 2010-01-14: Simon Goldschmidt + * ...: Use typedef for function prototypes throughout the stack. + + 2010-01-13: Simon Goldschmidt + * api_msg.h/.c, api_lib.c: Fixed bug #26672 (close connection when receive + window = 0) by correctly draining recvmbox/acceptmbox + + 2010-01-11: Simon Goldschmidt + * pap.c: Fixed bug #13315 (PPP PAP authentication can result in + erroneous callbacks) by copying the code from recent pppd + + 2010-01-10: Simon Goldschmidt + * raw.c: Fixed bug #28506 (raw_bind should filter received packets) + + 2010-01-10: Simon Goldschmidt + * tcp.h/.c: bug #28127 (remove call to tcp_output() from tcp_ack(_now)()) + + 2010-01-08: Simon Goldschmidt + * sockets.c: Fixed bug #28519 (lwip_recvfrom bug with len > 65535) + + 2010-01-08: Simon Goldschmidt + * dns.c: Copy hostname for DNS_LOCAL_HOSTLIST_IS_DYNAMIC==1 since string + passed to dns_local_addhost() might be volatile + + 2010-01-07: Simon Goldschmidt + * timers.c, tcp.h: Call tcp_timer_needed() with NO_SYS==1, too + + 2010-01-06: Simon Goldschmidt + * netdb.h: Fixed bug #28496: missing include guards in netdb.h + + 2009-12-31: Simon Goldschmidt + * many ppp files: Reorganised PPP source code from ucip structure to pppd + structure to easily compare our code against the pppd code (around v2.3.1) + + 2009-12-27: Simon Goldschmidt + * tcp_in.c: Another fix for bug #28241 (ooseq processing) and adapted + unit test + + +(STABLE-1.3.2) + + ++ New features: + + 2009-10-27 Simon Goldschmidt/Stephan Lesage + * netifapi.c/.h: Added netifapi_netif_set_addr() + + 2009-10-07 Simon Goldschmidt/Fabian Koch + * api_msg.c, netbuf.c/.h, opt.h: patch #6888: Patch for UDP Netbufs to + support dest-addr and dest-port (optional: LWIP_NETBUF_RECVINFO) + + 2009-08-26 Simon Goldschmidt/Simon Kallweit + * slipif.c/.h: bug #26397: SLIP polling support + + 2009-08-25 Simon Goldschmidt + * opt.h, etharp.h/.c: task #9033: Support IEEE 802.1q tagged frame (VLAN), + New configuration options ETHARP_SUPPORT_VLAN and ETHARP_VLAN_CHECK. + + 2009-08-25 Simon Goldschmidt + * ip_addr.h, netdb.c: patch #6900: added define ip_ntoa(struct ip_addr*) + + 2009-08-24 Jakob Stoklund Olesen + * autoip.c, dhcp.c, netif.c: patch #6725: Teach AutoIP and DHCP to respond + to netif_set_link_up(). + + 2009-08-23 Simon Goldschmidt + * tcp.h/.c: Added function tcp_debug_state_str() to convert a tcp state + to a human-readable string. + + ++ Bugfixes: + + 2009-12-24: Kieran Mansley + * tcp_in.c Apply patches from Oleg Tyshev to improve OOS processing + (BUG#28241) + + 2009-12-06: Simon Goldschmidt + * ppp.h/.c: Fixed bug #27079 (Yet another leak in PPP): outpacket_buf can + be statically allocated (like in ucip) + + 2009-12-04: Simon Goldschmidt (patch by Ioardan Neshev) + * pap.c: patch #6969: PPP: missing PAP authentication UNTIMEOUT + + 2009-12-03: Simon Goldschmidt + * tcp.h, tcp_in.c, tcp_out.c: Fixed bug #28106: dup ack for fast retransmit + could have non-zero length + + 2009-12-02: Simon Goldschmidt + * tcp_in.c: Fixed bug #27904: TCP sends too many ACKs: delay resetting + tcp_input_pcb until after calling the pcb's callbacks + + 2009-11-29: Simon Goldschmidt + * tcp_in.c: Fixed bug #28054: Two segments with FIN flag on the out-of- + sequence queue, also fixed PBUF_POOL leak in the out-of-sequence code + + 2009-11-29: Simon Goldschmidt + * pbuf.c: Fixed bug #28064: pbuf_alloc(PBUF_POOL) is not thread-safe by + queueing a call into tcpip_thread to free ooseq-bufs if the pool is empty + + 2009-11-26: Simon Goldschmidt + * tcp.h: Fixed bug #28098: Nagle can prevent fast retransmit from sending + segment + + 2009-11-26: Simon Goldschmidt + * tcp.h, sockets.c: Fixed bug #28099: API required to disable Nagle + algorithm at PCB level + + 2009-11-22: Simon Goldschmidt + * tcp_out.c: Fixed bug #27905: FIN isn't combined with data on unsent + + 2009-11-22: Simon Goldschmidt (suggested by Bill Auerbach) + * tcp.c: tcp_alloc: prevent increasing stats.err for MEMP_TCP_PCB when + reusing time-wait pcb + + 2009-11-20: Simon Goldschmidt (patch by Albert Bartel) + * sockets.c: Fixed bug #28062: Data received directly after accepting + does not wake up select + + 2009-11-11: Simon Goldschmidt + * netdb.h: Fixed bug #27994: incorrect define for freeaddrinfo(addrinfo) + + 2009-10-30: Simon Goldschmidt + * opt.h: Increased default value for TCP_MSS to 536, updated default + value for TCP_WND to 4*TCP_MSS to keep delayed ACK working. + + 2009-10-28: Kieran Mansley + * tcp_in.c, tcp_out.c, tcp.h: re-work the fast retransmission code + to follow algorithm from TCP/IP Illustrated + + 2009-10-27: Kieran Mansley + * tcp_in.c: fix BUG#27445: grow cwnd with every duplicate ACK + + 2009-10-25: Simon Goldschmidt + * tcp.h: bug-fix in the TCP_EVENT_RECV macro (has to call tcp_recved if + pcb->recv is NULL to keep rcv_wnd correct) + + 2009-10-25: Simon Goldschmidt + * tcp_in.c: Fixed bug #26251: RST process in TIME_WAIT TCP state + + 2009-10-23: Simon Goldschmidt (David Empson) + * tcp.c: Fixed bug #27783: Silly window avoidance for small window sizes + + 2009-10-21: Simon Goldschmidt + * tcp_in.c: Fixed bug #27215: TCP sent() callback gives leading and + trailing 1 byte len (SYN/FIN) + + 2009-10-21: Simon Goldschmidt + * tcp_out.c: Fixed bug #27315: zero window probe and FIN + + 2009-10-19: Simon Goldschmidt + * dhcp.c/.h: Minor code simplification (don't store received pbuf, change + conditional code to assert where applicable), check pbuf length before + testing for valid reply + + 2009-10-19: Simon Goldschmidt + * dhcp.c: Removed most calls to udp_connect since they aren't necessary + when using udp_sendto_if() - always stay connected to IP_ADDR_ANY. + + 2009-10-16: Simon Goldschmidt + * ip.c: Fixed bug #27390: Source IP check in ip_input() causes it to drop + valid DHCP packets -> allow 0.0.0.0 as source address when LWIP_DHCP is + enabled + + 2009-10-15: Simon Goldschmidt (Oleg Tyshev) + * tcp_in.c: Fixed bug #27329: dupacks by unidirectional data transmit + + 2009-10-15: Simon Goldschmidt + * api_lib.c: Fixed bug #27709: conn->err race condition on netconn_recv() + timeout + + 2009-10-15: Simon Goldschmidt + * autoip.c: Fixed bug #27704: autoip starts with wrong address + LWIP_AUTOIP_CREATE_SEED_ADDR() returned address in host byte order instead + of network byte order + + 2009-10-11 Simon Goldschmidt (Jrg Kesten) + * tcp_out.c: Fixed bug #27504: tcp_enqueue wrongly concatenates segments + which are not consecutive when retransmitting unacked segments + + 2009-10-09 Simon Goldschmidt + * opt.h: Fixed default values of some stats to only be enabled if used + Fixes bug #27338: sys_stats is defined when NO_SYS = 1 + + 2009-08-30 Simon Goldschmidt + * ip.c: Fixed bug bug #27345: "ip_frag() does not use the LWIP_NETIF_LOOPBACK + function" by checking for loopback before calling ip_frag + + 2009-08-25 Simon Goldschmidt + * dhcp.c: fixed invalid dependency to etharp_query if DHCP_DOES_ARP_CHECK==0 + + 2009-08-23 Simon Goldschmidt + * ppp.c: bug #27078: Possible memory leak in pppInit() + + 2009-08-23 Simon Goldschmidt + * netdb.c, dns.c: bug #26657: DNS, if host name is "localhost", result + is error. + + 2009-08-23 Simon Goldschmidt + * opt.h, init.c: bug #26649: TCP fails when TCP_MSS > TCP_SND_BUF + Fixed wrong parenthesis, added check in init.c + + 2009-08-23 Simon Goldschmidt + * ppp.c: bug #27266: wait-state debug message in pppMain occurs every ms + + 2009-08-23 Simon Goldschmidt + * many ppp files: bug #27267: Added include to string.h where needed + + 2009-08-23 Simon Goldschmidt + * tcp.h: patch #6843: tcp.h macro optimization patch (for little endian) + + +(STABLE-1.3.1) + + ++ New features: + + 2009-05-10 Simon Goldschmidt + * opt.h, sockets.c, pbuf.c, netbuf.h, pbuf.h: task #7013: Added option + LWIP_NETIF_TX_SINGLE_PBUF to try to create transmit packets from only + one pbuf to help MACs that don't support scatter-gather DMA. + + 2009-05-09 Simon Goldschmidt + * icmp.h, icmp.c: Shrinked ICMP code, added option to NOT check icoming + ECHO pbuf for size (just use it): LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN + + 2009-05-05 Simon Goldschmidt, Jakob Stoklund Olesen + * ip.h, ip.c: Added ip_current_netif() & ip_current_header() to receive + extended info about the currently received packet. + + 2009-04-27 Simon Goldschmidt + * sys.h: Made SYS_LIGHTWEIGHT_PROT and sys_now() work with NO_SYS=1 + + 2009-04-25 Simon Goldschmidt + * mem.c, opt.h: Added option MEM_USE_POOLS_TRY_BIGGER_POOL to try the next + bigger malloc pool if one is empty (only usable with MEM_USE_POOLS). + + 2009-04-21 Simon Goldschmidt + * dns.c, init.c, dns.h, opt.h: task #7507, patch #6786: DNS supports static + hosts table. New configuration options DNS_LOCAL_HOSTLIST and + DNS_LOCAL_HOSTLIST_IS_DYNAMIC. Also, DNS_LOOKUP_LOCAL_EXTERN() can be defined + as an external function for lookup. + + 2009-04-15 Simon Goldschmidt + * dhcp.c: patch #6763: Global DHCP XID can be redefined to something more unique + + 2009-03-31 Kieran Mansley + * tcp.c, tcp_out.c, tcp_in.c, sys.h, tcp.h, opts.h: add support for + TCP timestamp options, off by default. Rework tcp_enqueue() to + take option flags rather than specified option data + + 2009-02-18 Simon Goldschmidt + * cc.h: Added printf formatter for size_t: SZT_F + + 2009-02-16 Simon Goldschmidt (patch by Rishi Khan) + * icmp.c, opt.h: patch #6539: (configurable) response to broadcast- and multicast + pings + + 2009-02-12 Simon Goldschmidt + * init.h: Added LWIP_VERSION to get the current version of the stack + + 2009-02-11 Simon Goldschmidt (suggested by Gottfried Spitaler) + * opt.h, memp.h/.c: added MEMP_MEM_MALLOC to use mem_malloc/mem_free instead + of the pool allocator (can save code size with MEM_LIBC_MALLOC if libc-malloc + is otherwise used) + + 2009-01-28 Jonathan Larmour (suggested by Bill Bauerbach) + * ipv4/inet_chksum.c, ipv4/lwip/inet_chksum.h: inet_chksum_pseudo_partial() + is only used by UDPLITE at present, so conditionalise it. + + 2008-12-03 Simon Goldschmidt (base on patch from Luca Ceresoli) + * autoip.c: checked in (slightly modified) patch #6683: Customizable AUTOIP + "seed" address. This should reduce AUTOIP conflicts if + LWIP_AUTOIP_CREATE_SEED_ADDR is overridden. + + 2008-10-02 Jonathan Larmour and Rishi Khan + * sockets.c (lwip_accept): Return EWOULDBLOCK if would block on non-blocking + socket. + + 2008-06-30 Simon Goldschmidt + * mem.c, opt.h, stats.h: fixed bug #21433: Calling mem_free/pbuf_free from + interrupt context isn't safe: LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT allows + mem_free to run between mem_malloc iterations. Added illegal counter for + mem stats. + + 2008-06-27 Simon Goldschmidt + * stats.h/.c, some other files: patch #6483: stats module improvement: + Added defines to display each module's statistic individually, added stats + defines for MEM, MEMP and SYS modules, removed (unused) rexmit counter. + + 2008-06-17 Simon Goldschmidt + * err.h: patch #6459: Made err_t overridable to use a more efficient type + (define LWIP_ERR_T in cc.h) + + 2008-06-17 Simon Goldschmidt + * slipif.c: patch #6480: Added a configuration option for slipif for symmetry + to loopif + + 2008-06-17 Simon Goldschmidt (patch by Luca Ceresoli) + * netif.c, loopif.c, ip.c, netif.h, loopif.h, opt.h: Checked in slightly + modified version of patch # 6370: Moved loopif code to netif.c so that + loopback traffic is supported on all netifs (all local IPs). + Added option to limit loopback packets for each netifs. + + + ++ Bugfixes: + 2009-08-12 Kieran Mansley + * tcp_in.c, tcp.c: Fix bug #27209: handle trimming of segments when + out of window or out of order properly + + 2009-08-12 Kieran Mansley + * tcp_in.c: Fix bug #27199: use snd_wl2 instead of snd_wl1 + + 2009-07-28 Simon Goldschmidt + * mem.h: Fixed bug #27105: "realloc() cannot replace mem_realloc()"s + + 2009-07-27 Kieran Mansley + * api.h api_msg.h netdb.h sockets.h: add missing #include directives + + 2009-07-09 Kieran Mansley + * api_msg.c, sockets.c, api.h: BUG23240 use signed counters for + recv_avail and don't increment counters until message successfully + sent to mbox + + 2009-06-25 Kieran Mansley + * api_msg.c api.h: BUG26722: initialise netconn write variables + in netconn_alloc + + 2009-06-25 Kieran Mansley + * tcp.h: BUG26879: set ret value in TCP_EVENT macros when function is not set + + 2009-06-25 Kieran Mansley + * tcp.c, tcp_in.c, tcp_out.c, tcp.h: BUG26301 and BUG26267: correct + simultaneous close behaviour, and make snd_nxt have the same meaning + as in the RFCs. + + 2009-05-12 Simon Goldschmidt + * etharp.h, etharp.c, netif.c: fixed bug #26507: "Gratuitous ARP depends on + arp_table / uses etharp_query" by adding etharp_gratuitous() + + 2009-05-12 Simon Goldschmidt + * ip.h, ip.c, igmp.c: bug #26487: Added ip_output_if_opt that can add IP options + to the IP header (used by igmp_ip_output_if) + + 2009-05-06 Simon Goldschmidt + * inet_chksum.c: On little endian architectures, use LWIP_PLATFORM_HTONS (if + defined) for SWAP_BYTES_IN_WORD to speed up checksumming. + + 2009-05-05 Simon Goldschmidt + * sockets.c: bug #26405: Prematurely released semaphore causes lwip_select() + to crash + + 2009-05-04 Simon Goldschmidt + * init.c: snmp was not initialized in lwip_init() + + 2009-05-04 Frdric Bernon + * dhcp.c, netbios.c: Changes if IP_SOF_BROADCAST is enabled. + + 2009-05-03 Simon Goldschmidt + * tcp.h: bug #26349: Nagle algorithm doesn't send although segment is full + (and unsent->next == NULL) + + 2009-05-02 Simon Goldschmidt + * tcpip.h, tcpip.c: fixed tcpip_untimeout (does not need the time, broken after + 1.3.0 in CVS only) - fixes compilation of ppp_oe.c + + 2009-05-02 Simon Goldschmidt + * msg_in.c: fixed bug #25636: SNMPSET value is ignored for integer fields + + 2009-05-01 Simon Goldschmidt + * pap.c: bug #21680: PPP upap_rauthnak() drops legal NAK packets + + 2009-05-01 Simon Goldschmidt + * ppp.c: bug #24228: Memory corruption with PPP and DHCP + + 2009-04-29 Frdric Bernon + * raw.c, udp.c, init.c, opt.h, ip.h, sockets.h: bug #26309: Implement the + SO(F)_BROADCAST filter for all API layers. Avoid the unindented reception + of broadcast packets even when this option wasn't set. Port maintainers + which want to enable this filter have to set IP_SOF_BROADCAST=1 in opt.h. + If you want this option also filter broadcast on recv operations, you also + have to set IP_SOF_BROADCAST_RECV=1 in opt.h. + + 2009-04-28 Simon Goldschmidt, Jakob Stoklund Olesen + * dhcp.c: patch #6721, bugs #25575, #25576: Some small fixes to DHCP and + DHCP/AUTOIP cooperation + + 2009-04-25 Simon Goldschmidt, Oleg Tyshev + * tcp_out.c: bug #24212: Deadlocked tcp_retransmit due to exceeded pcb->cwnd + Fixed by sorting the unsent and unacked queues (segments are inserted at the + right place in tcp_output and tcp_rexmit). + + 2009-04-25 Simon Goldschmidt + * memp.c, mem.c, memp.h, mem_std.h: bug #26213 "Problem with memory allocation + when debugging": memp_sizes contained the wrong sizes (including sanity + regions); memp pools for MEM_USE_POOLS were too small + + 2009-04-24 Simon Goldschmidt, Frdric Bernon + * inet.c: patch #6765: Fix a small problem with the last changes (incorrect + behavior, with with ip address string not ended by a '\0', a space or a + end of line) + + 2009-04-19 Simon Goldschmidt + * rawapi.txt: Fixed bug #26069: Corrected documentation: if tcp_connect fails, + pcb->err is called, not pcb->connected (with an error code). + + 2009-04-19 Simon Goldschmidt + * tcp_out.c: Fixed bug #26236: "TCP options (timestamp) don't work with + no-copy-tcpwrite": deallocate option data, only concat segments with same flags + + 2009-04-19 Simon Goldschmidt + * tcp_out.c: Fixed bug #25094: "Zero-length pbuf" (options are now allocated + in the header pbuf, not the data pbuf) + + 2009-04-18 Simon Goldschmidt + * api_msg.c: fixed bug #25695: Segmentation fault in do_writemore() + + 2009-04-15 Simon Goldschmidt + * sockets.c: tried to fix bug #23559: lwip_recvfrom problem with tcp + + 2009-04-15 Simon Goldschmidt + * dhcp.c: task #9192: mem_free of dhcp->options_in and dhcp->msg_in + + 2009-04-15 Simon Goldschmidt + * ip.c, ip6.c, tcp_out.c, ip.h: patch #6808: Add a utility function + ip_hinted_output() (for smaller code mainly) + + 2009-04-15 Simon Goldschmidt + * inet.c: patch #6765: Supporting new line characters in inet_aton() + + 2009-04-15 Simon Goldschmidt + * dhcp.c: patch #6764: DHCP rebind and renew did not send hostnam option; + Converted constant OPTION_MAX_MSG_SIZE to netif->mtu, check if netif->mtu + is big enough in dhcp_start + + 2009-04-15 Simon Goldschmidt + * netbuf.c: bug #26027: netbuf_chain resulted in pbuf memory leak + + 2009-04-15 Simon Goldschmidt + * sockets.c, ppp.c: bug #25763: corrected 4 occurrences of SMEMCPY to MEMCPY + + 2009-04-15 Simon Goldschmidt + * sockets.c: bug #26121: set_errno can be overridden + + 2009-04-09 Kieran Mansley (patch from Luca Ceresoli ) + * init.c, opt.h: Patch#6774 TCP_QUEUE_OOSEQ breaks compilation when + LWIP_TCP==0 + + 2009-04-09 Kieran Mansley (patch from Roy Lee ) + * tcp.h: Patch#6802 Add do-while-clauses to those function like + macros in tcp.h + + 2009-03-31 Kieran Mansley + * tcp.c, tcp_in.c, tcp_out.c, tcp.h, opt.h: Rework the way window + updates are calculated and sent (BUG20515) + + * tcp_in.c: cope with SYN packets received during established states, + and retransmission of initial SYN. + + * tcp_out.c: set push bit correctly when tcp segments are merged + + 2009-03-27 Kieran Mansley + * tcp_out.c set window correctly on probes (correcting change made + yesterday) + + 2009-03-26 Kieran Mansley + * tcp.c, tcp_in.c, tcp.h: add tcp_abandon() to cope with dropping + connections where no reset required (bug #25622) + + * tcp_out.c: set TCP_ACK flag on keepalive and zero window probes + (bug #20779) + + 2009-02-18 Simon Goldschmidt (Jonathan Larmour and Bill Auerbach) + * ip_frag.c: patch #6528: the buffer used for IP_FRAG_USES_STATIC_BUF could be + too small depending on MEM_ALIGNMENT + + 2009-02-16 Simon Goldschmidt + * sockets.h/.c, api_*.h/.c: fixed arguments of socket functions to match the standard; + converted size argument of netconn_write to 'size_t' + + 2009-02-16 Simon Goldschmidt + * tcp.h, tcp.c: fixed bug #24440: TCP connection close problem on 64-bit host + by moving accept callback function pointer to TCP_PCB_COMMON + + 2009-02-12 Simon Goldschmidt + * dhcp.c: fixed bug #25345 (DHCPDECLINE is sent with "Maximum message size" + option) + + 2009-02-11 Simon Goldschmidt + * dhcp.c: fixed bug #24480 (releasing old udp_pdb and pbuf in dhcp_start) + + 2009-02-11 Simon Goldschmidt + * opt.h, api_msg.c: added configurable default valud for netconn->recv_bufsize: + RECV_BUFSIZE_DEFAULT (fixes bug #23726: pbuf pool exhaustion on slow recv()) + + 2009-02-10 Simon Goldschmidt + * tcp.c: fixed bug #25467: Listen backlog is not reset on timeout in SYN_RCVD: + Accepts_pending is decrease on a corresponding listen pcb when a connection + in state SYN_RCVD is close. + + 2009-01-28 Jonathan Larmour + * pbuf.c: reclaim pbufs from TCP out-of-sequence segments if we run + out of pool pbufs. + + 2008-12-19 Simon Goldschmidt + * many files: patch #6699: fixed some warnings on platform where sizeof(int) == 2 + + 2008-12-10 Tamas Somogyi, Frdric Bernon + * sockets.c: fixed bug #25051: lwip_recvfrom problem with udp: fromaddr and + port uses deleted netbuf. + + 2008-10-18 Simon Goldschmidt + * tcp_in.c: fixed bug ##24596: Vulnerability on faulty TCP options length + in tcp_parseopt + + 2008-10-15 Simon Goldschmidt + * ip_frag.c: fixed bug #24517: IP reassembly crashes on unaligned IP headers + by packing the struct ip_reass_helper. + + 2008-10-03 David Woodhouse, Jonathan Larmour + * etharp.c (etharp_arp_input): Fix type aliasing problem copying ip address. + + 2008-10-02 Jonathan Larmour + * dns.c: Hard-code structure sizes, to avoid issues on some compilers where + padding is included. + + 2008-09-30 Jonathan Larmour + * sockets.c (lwip_accept): check addr isn't NULL. If it's valid, do an + assertion check that addrlen isn't NULL. + + 2008-09-30 Jonathan Larmour + * tcp.c: Fix bug #24227, wrong error message in tcp_bind. + + 2008-08-26 Simon Goldschmidt + * inet.h, ip_addr.h: fixed bug #24132: Cross-dependency between ip_addr.h and + inet.h -> moved declaration of struct in_addr from ip_addr.h to inet.h + + 2008-08-14 Simon Goldschmidt + * api_msg.c: fixed bug #23847: do_close_internal references freed memory (when + tcp_close returns != ERR_OK) + + 2008-07-08 Frdric Bernon + * stats.h: Fix some build bugs introduced with patch #6483 (missing some parameters + in macros, mainly if MEM_STATS=0 and MEMP_STATS=0). + + 2008-06-24 Jonathan Larmour + * tcp_in.c: Fix for bug #23693 as suggested by Art R. Ensure cseg is unused + if tcp_seg_copy fails. + + 2008-06-17 Simon Goldschmidt + * inet_chksum.c: Checked in some ideas of patch #6460 (loop optimizations) + and created defines for swapping bytes and folding u32 to u16. + + 2008-05-30 Kieran Mansley + * tcp_in.c Remove redundant "if" statement, and use real rcv_wnd + rather than rcv_ann_wnd when deciding if packets are in-window. + Contributed by + + 2008-05-30 Kieran Mansley + * mem.h: Fix BUG#23254. Change macro definition of mem_* to allow + passing as function pointers when MEM_LIBC_MALLOC is defined. + + 2008-05-09 Jonathan Larmour + * err.h, err.c, sockets.c: Fix bug #23119: Reorder timeout error code to + stop it being treated as a fatal error. + + 2008-04-15 Simon Goldschmidt + * dhcp.c: fixed bug #22804: dhcp_stop doesn't clear NETIF_FLAG_DHCP + (flag now cleared) + + 2008-03-27 Simon Goldschmidt + * mem.c, tcpip.c, tcpip.h, opt.h: fixed bug #21433 (Calling mem_free/pbuf_free + from interrupt context isn't safe): set LWIP_USE_HEAP_FROM_INTERRUPT to 1 + in lwipopts.h or use pbuf_free_callback(p)/mem_free_callback(m) to free pbufs + or heap memory from interrupt context + + 2008-03-26 Simon Goldschmidt + * tcp_in.c, tcp.c: fixed bug #22249: division by zero could occur if a remote + host sent a zero mss as TCP option. + + +(STABLE-1.3.0) + + ++ New features: + + 2008-03-10 Jonathan Larmour + * inet_chksum.c: Allow choice of one of the sample algorithms to be + made from lwipopts.h. Fix comment on how to override LWIP_CHKSUM. + + 2008-01-22 Frdric Bernon + * tcp.c, tcp_in.c, tcp.h, opt.h: Rename LWIP_CALCULATE_EFF_SEND_MSS in + TCP_CALCULATE_EFF_SEND_MSS to have coherent TCP options names. + + 2008-01-14 Frdric Bernon + * rawapi.txt, api_msg.c, tcp.c, tcp_in.c, tcp.h: changes for task #7675 "Enable + to refuse data on a TCP_EVENT_RECV call". Important, behavior changes for the + tcp_recv callback (see rawapi.txt). + + 2008-01-14 Frdric Bernon, Marc Chaland + * ip.c: Integrate patch #6369" ip_input : checking before realloc". + + 2008-01-12 Frdric Bernon + * tcpip.h, tcpip.c, api.h, api_lib.c, api_msg.c, sockets.c: replace the field + netconn::sem per netconn::op_completed like suggested for the task #7490 + "Add return value to sys_mbox_post". + + 2008-01-12 Frdric Bernon + * api_msg.c, opt.h: replace DEFAULT_RECVMBOX_SIZE per DEFAULT_TCP_RECVMBOX_SIZE, + DEFAULT_UDP_RECVMBOX_SIZE and DEFAULT_RAW_RECVMBOX_SIZE (to optimize queues + sizes), like suggested for the task #7490 "Add return value to sys_mbox_post". + + 2008-01-10 Frdric Bernon + * tcpip.h, tcpip.c: add tcpip_callback_with_block function for the task #7490 + "Add return value to sys_mbox_post". tcpip_callback is always defined as + "blocking" ("block" parameter = 1). + + 2008-01-10 Frdric Bernon + * tcpip.h, tcpip.c, api.h, api_lib.c, api_msg.c, sockets.c: replace the field + netconn::mbox (sys_mbox_t) per netconn::sem (sys_sem_t) for the task #7490 + "Add return value to sys_mbox_post". + + 2008-01-05 Frdric Bernon + * sys_arch.txt, api.h, api_lib.c, api_msg.h, api_msg.c, tcpip.c, sys.h, opt.h: + Introduce changes for task #7490 "Add return value to sys_mbox_post" with some + modifications in the sys_mbox api: sys_mbox_new take a "size" parameters which + indicate the number of pointers query by the mailbox. There is three defines + in opt.h to indicate sizes for tcpip::mbox, netconn::recvmbox, and for the + netconn::acceptmbox. Port maintainers, you can decide to just add this new + parameter in your implementation, but to ignore it to keep the previous behavior. + The new sys_mbox_trypost function return a value to know if the mailbox is + full or if the message is posted. Take a look to sys_arch.txt for more details. + This new function is used in tcpip_input (so, can be called in an interrupt + context since the function is not blocking), and in recv_udp and recv_raw. + + 2008-01-04 Frdric Bernon, Simon Goldschmidt, Jonathan Larmour + * rawapi.txt, api.h, api_lib.c, api_msg.h, api_msg.c, sockets.c, tcp.h, tcp.c, + tcp_in.c, init.c, opt.h: rename backlog options with TCP_ prefix, limit the + "backlog" parameter in an u8_t, 0 is interpreted as "smallest queue", add + documentation in the rawapi.txt file. + + 2007-12-31 Kieran Mansley (based on patch from Per-Henrik Lundbolm) + * tcp.c, tcp_in.c, tcp_out.c, tcp.h: Add TCP persist timer + + 2007-12-31 Frdric Bernon, Luca Ceresoli + * autoip.c, etharp.c: ip_addr.h: Integrate patch #6348: "Broadcast ARP packets + in autoip". The change in etharp_raw could be removed, since all calls to + etharp_raw use ethbroadcast for the "ethdst_addr" parameter. But it could be + wrong in the future. + + 2007-12-30 Frdric Bernon, Tom Evans + * ip.c: Fix bug #21846 "LwIP doesn't appear to perform any IP Source Address + Filtering" reported by Tom Evans. + + 2007-12-21 Frdric Bernon, Simon Goldschmidt, Jonathan Larmour + * tcp.h, opt.h, api.h, api_msg.h, tcp.c, tcp_in.c, api_lib.c, api_msg.c, + sockets.c, init.c: task #7252: Implement TCP listen backlog: Warning: raw API + applications have to call 'tcp_accepted(pcb)' in their accept callback to + keep accepting new connections. + + 2007-12-13 Frdric Bernon + * api_msg.c, err.h, err.c, sockets.c, dns.c, dns.h: replace "enum dns_result" + by err_t type. Add a new err_t code "ERR_INPROGRESS". + + 2007-12-12 Frdric Bernon + * dns.h, dns.c, opt.h: move DNS options to the "right" place. Most visibles + are the one which have ram usage. + + 2007-12-05 Frdric Bernon + * netdb.c: add a LWIP_DNS_API_HOSTENT_STORAGE option to decide to use a static + set of variables (=0) or a local one (=1). In this last case, your port should + provide a function "struct hostent* sys_thread_hostent( struct hostent* h)" + which have to do a copy of "h" and return a pointer ont the "per-thread" copy. + + 2007-12-03 Simon Goldschmidt + * ip.c: ip_input: check if a packet is for inp first before checking all other + netifs on netif_list (speeds up packet receiving in most cases) + + 2007-11-30 Simon Goldschmidt + * udp.c, raw.c: task #7497: Sort lists (pcb, netif, ...) for faster access + UDP: move a (connected) pcb selected for input to the front of the list of + pcbs so that it is found faster next time. Same for RAW pcbs that have eaten + a packet. + + 2007-11-28 Simon Goldschmidt + * etharp.c, stats.c, stats.h, opt.h: Introduced ETHARP_STATS + + 2007-11-25 Simon Goldschmidt + * dhcp.c: dhcp_unfold_reply() uses pbuf_copy_partial instead of its own copy + algorithm. + + 2007-11-24 Simon Goldschmidt + * netdb.h, netdb.c, sockets.h/.c: Moved lwip_gethostbyname from sockets.c + to the new file netdb.c; included lwip_getaddrinfo. + + 2007-11-21 Simon Goldschmidt + * tcp.h, opt.h, tcp.c, tcp_in.c: implemented calculating the effective send-mss + based on the MTU of the netif used to send. Enabled by default. Disable by + setting LWIP_CALCULATE_EFF_SEND_MSS to 0. This fixes bug #21492. + + 2007-11-19 Frdric Bernon + * api_msg.c, dns.h, dns.c: Implement DNS_DOES_NAME_CHECK option (check if name + received match the name query), implement DNS_USES_STATIC_BUF (the place where + copy dns payload to parse the response), return an error if there is no place + for a new query, and fix some minor problems. + + 2007-11-16 Simon Goldschmidt + * new files: ipv4/inet.c, ipv4/inet_chksum.c, ipv6/inet6.c + removed files: core/inet.c, core/inet6.c + Moved inet files into ipv4/ipv6 directory; splitted inet.c/inet.h into + inet and chksum part; changed includes in all lwIP files as appropriate + + 2007-11-16 Simon Goldschmidt + * api.h, api_msg.h, api_lib.c, api_msg.c, socket.h, socket.c: Added sequential + dns resolver function for netconn api (netconn_gethostbyname) and socket api + (gethostbyname/gethostbyname_r). + + 2007-11-15 Jim Pettinato, Frdric Bernon + * opt.h, init.c, tcpip.c, dhcp.c, dns.h, dns.c: add DNS client for simple name + requests with RAW api interface. Initialization is done in lwip_init() with + build time options. DNS timer is added in tcpip_thread context. DHCP can set + DNS server ip addresses when options are received. You need to set LWIP_DNS=1 + in your lwipopts.h file (LWIP_DNS=0 in opt.h). DNS_DEBUG can be set to get + some traces with LWIP_DEBUGF. Sanity check have been added. There is a "todo" + list with points to improve. + + 2007-11-06 Simon Goldschmidt + * opt.h, mib2.c: Patch #6215: added ifAdminStatus write support (if explicitly + enabled by defining SNMP_SAFE_REQUESTS to 0); added code to check link status + for ifOperStatus if LWIP_NETIF_LINK_CALLBACK is defined. + + 2007-11-06 Simon Goldschmidt + * api.h, api_msg.h and dependent files: Task #7410: Removed the need to include + core header files in api.h (ip/tcp/udp/raw.h) to hide the internal + implementation from netconn api applications. + + 2007-11-03 Frdric Bernon + * api.h, api_lib.c, api_msg.c, sockets.c, opt.h: add SO_RCVBUF option for UDP & + RAW netconn. You need to set LWIP_SO_RCVBUF=1 in your lwipopts.h (it's disabled + by default). Netconn API users can use the netconn_recv_bufsize macro to access + it. This is a first release which have to be improve for TCP. Note it used the + netconn::recv_avail which need to be more "thread-safe" (note there is already + the problem for FIONREAD with lwip_ioctl/ioctlsocket). + + 2007-11-01 Frdric Bernon, Marc Chaland + * sockets.h, sockets.c, api.h, api_lib.c, api_msg.h, api_msg.c, tcp.h, tcp_out.c: + Integrate "patch #6250 : MSG_MORE flag for send". MSG_MORE is used at socket api + layer, NETCONN_MORE at netconn api layer, and TCP_WRITE_FLAG_MORE at raw api + layer. This option enable to delayed TCP PUSH flag on multiple "write" calls. + Note that previous "copy" parameter for "write" APIs is now called "apiflags". + + 2007-10-24 Frdric Bernon + * api.h, api_lib.c, api_msg.c: Add macro API_EVENT in the same spirit than + TCP_EVENT_xxx macros to get a code more readable. It could also help to remove + some code (like we have talk in "patch #5919 : Create compile switch to remove + select code"), but it could be done later. + + 2007-10-08 Simon Goldschmidt + * many files: Changed initialization: many init functions are not needed any + more since we now rely on the compiler initializing global and static + variables to zero! + + 2007-10-06 Simon Goldschmidt + * ip_frag.c, memp.c, mib2.c, ip_frag.h, memp_std.h, opt.h: Changed IP_REASSEMBLY + to enqueue the received pbufs so that multiple packets can be reassembled + simultaneously and no static reassembly buffer is needed. + + 2007-10-05 Simon Goldschmidt + * tcpip.c, etharp.h, etharp.c: moved ethernet_input from tcpip.c to etharp.c so + all netifs (or ports) can use it. + + 2007-10-05 Frdric Bernon + * netifapi.h, netifapi.c: add function netifapi_netif_set_default. Change the + common function to reduce a little bit the footprint (for all functions using + only the "netif" parameter). + + 2007-10-03 Frdric Bernon + * netifapi.h, netifapi.c: add functions netifapi_netif_set_up, netifapi_netif_set_down, + netifapi_autoip_start and netifapi_autoip_stop. Use a common function to reduce + a little bit the footprint (for all functions using only the "netif" parameter). + + 2007-09-15 Frdric Bernon + * udp.h, udp.c, sockets.c: Changes for "#20503 IGMP Improvement". Add IP_MULTICAST_IF + option in socket API, and a new field "multicast_ip" in "struct udp_pcb" (for + netconn and raw API users), only if LWIP_IGMP=1. Add getsockopt processing for + IP_MULTICAST_TTL and IP_MULTICAST_IF. + + 2007-09-10 Frdric Bernon + * snmp.h, mib2.c: enable to remove SNMP timer (which consumne several cycles + even when it's not necessary). snmp_agent.txt tell to call snmp_inc_sysuptime() + each 10ms (but, it's intrusive if you use sys_timeout feature). Now, you can + decide to call snmp_add_sysuptime(100) each 1000ms (which is bigger "step", but + call to a lower frequency). Or, you can decide to not call snmp_inc_sysuptime() + or snmp_add_sysuptime(), and to define the SNMP_GET_SYSUPTIME(sysuptime) macro. + This one is undefined by default in mib2.c. SNMP_GET_SYSUPTIME is called inside + snmp_get_sysuptime(u32_t *value), and enable to change "sysuptime" value only + when it's queried (any direct call to "sysuptime" is changed by a call to + snmp_get_sysuptime). + + 2007-09-09 Frdric Bernon, Bill Florac + * igmp.h, igmp.c, netif.h, netif.c, ip.c: To enable to have interfaces with IGMP, + and others without it, there is a new NETIF_FLAG_IGMP flag to set in netif->flags + if you want IGMP on an interface. igmp_stop() is now called inside netif_remove(). + igmp_report_groups() is now called inside netif_set_link_up() (need to have + LWIP_NETIF_LINK_CALLBACK=1) to resend reports once the link is up (avoid to wait + the next query message to receive the matching multicast streams). + + 2007-09-08 Frdric Bernon + * sockets.c, ip.h, api.h, tcp.h: declare a "struct ip_pcb" which only contains + IP_PCB. Add in the netconn's "pcb" union a "struct ip_pcb *ip;" (no size change). + Use this new field to access to common pcb fields (ttl, tos, so_options, etc...). + Enable to access to these fields with LWIP_TCP=0. + + 2007-09-05 Frdric Bernon + * udp.c, ipv4/icmp.c, ipv4/ip.c, ipv6/icmp.c, ipv6/ip6.c, ipv4/icmp.h, + ipv6/icmp.h, opt.h: Integrate "task #7272 : LWIP_ICMP option". The new option + LWIP_ICMP enable/disable ICMP module inside the IP stack (enable per default). + Be careful, disabling ICMP make your product non-compliant to RFC1122, but + help to reduce footprint, and to reduce "visibility" on the Internet. + + 2007-09-05 Frdric Bernon, Bill Florac + * opt.h, sys.h, tcpip.c, slipif.c, ppp.c, sys_arch.txt: Change parameters list + for sys_thread_new (see "task #7252 : Create sys_thread_new_ex()"). Two new + parameters have to be provided: a task name, and a task stack size. For this + one, since it's platform dependant, you could define the best one for you in + your lwipopts.h. For port maintainers, you can just add these new parameters + in your sys_arch.c file, and but it's not mandatory, use them in your OS + specific functions. + + 2007-09-05 Frdric Bernon + * inet.c, autoip.c, msg_in.c, msg_out.c, init.c: Move some build time checkings + inside init.c for task #7142 "Sanity check user-configurable values". + + 2007-09-04 Frdric Bernon, Bill Florac + * igmp.h, igmp.c, memp_std.h, memp.c, init.c, opt.h: Replace mem_malloc call by + memp_malloc, and use a new MEMP_NUM_IGMP_GROUP option (see opt.h to define the + value). It will avoid potential fragmentation problems, use a counter to know + how many times a group is used on an netif, and free it when all applications + leave it. MEMP_NUM_IGMP_GROUP got 8 as default value (and init.c got a sanity + check if LWIP_IGMP!=0). + + 2007-09-03 Frdric Bernon + * igmp.h, igmp.c, sockets.c, api_msg.c: Changes for "#20503 IGMP Improvement". + Initialize igmp_mac_filter to NULL in netif_add (this field should be set in + the netif's "init" function). Use the "imr_interface" field (for socket layer) + and/or the "interface" field (for netconn layer), for join/leave operations. + The igmp_join/leavegroup first parameter change from a netif to an ipaddr. + This field could be a netif's ipaddr, or "any" (same meaning than ip_addr_isany). + + 2007-08-30 Frdric Bernon + * Add netbuf.h, netbuf.c, Change api.h, api_lib.c: #7249 "Split netbuf functions + from api/api_lib". Now netbuf API is independant of netconn, and can be used + with other API (application based on raw API, or future "socket2" API). Ports + maintainers just have to add src/api/netbuf.c in their makefile/projects. + + 2007-08-30 Frdric Bernon, Jonathan Larmour + * init.c: Add first version of lwip_sanity_check for task #7142 "Sanity check + user-configurable values". + + 2007-08-29 Frdric Bernon + * igmp.h, igmp.c, tcpip.c, init.c, netif.c: change igmp_init and add igmp_start. + igmp_start is call inside netif_add. Now, igmp initialization is in the same + spirit than the others modules. Modify some IGMP debug traces. + + 2007-08-29 Frdric Bernon + * Add init.h, init.c, Change opt.h, tcpip.c: Task #7213 "Add a lwip_init function" + Add lwip_init function to regroup all modules initializations, and to provide + a place to add code for task #7142 "Sanity check user-configurable values". + Ports maintainers should remove direct initializations calls from their code, + and add init.c in their makefiles. Note that lwip_init() function is called + inside tcpip_init, but can also be used by raw api users since all calls are + disabled when matching options are disabled. Also note that their is new options + in opt.h, you should configure in your lwipopts.h (they are enabled per default). + + 2007-08-26 Marc Boucher + * api_msg.c: do_close_internal(): Reset the callbacks and arg (conn) to NULL + since they can under certain circumstances be called with an invalid conn + pointer after the connection has been closed (and conn has been freed). + + 2007-08-25 Frdric Bernon (Artem Migaev's Patch) + * netif.h, netif.c: Integrate "patch #6163 : Function to check if link layer is up". + Add a netif_is_link_up() function if LWIP_NETIF_LINK_CALLBACK option is set. + + 2007-08-22 Frdric Bernon + * netif.h, netif.c, opt.h: Rename LWIP_NETIF_CALLBACK in LWIP_NETIF_STATUS_CALLBACK + to be coherent with new LWIP_NETIF_LINK_CALLBACK option before next release. + + 2007-08-22 Frdric Bernon + * tcpip.h, tcpip.c, ethernetif.c, opt.h: remove options ETHARP_TCPIP_INPUT & + ETHARP_TCPIP_ETHINPUT, now, only "ethinput" code is supported, even if the + name is tcpip_input (we keep the name of 1.2.0 function). + + 2007-08-17 Jared Grubb + * memp_std.h, memp.h, memp.c, mem.c, stats.c: (Task #7136) Centralize mempool + settings into new memp_std.h and optional user file lwippools.h. This adds + more dynamic mempools, and allows the user to create an arbitrary number of + mempools for mem_malloc. + + 2007-08-16 Marc Boucher + * api_msg.c: Initialize newconn->state to NETCONN_NONE in accept_function; + otherwise it was left to NETCONN_CLOSE and sent_tcp() could prematurely + close the connection. + + 2007-08-16 Marc Boucher + * sockets.c: lwip_accept(): check netconn_peer() error return. + + 2007-08-16 Marc Boucher + * mem.c, mem.h: Added mem_calloc(). + + 2007-08-16 Marc Boucher + * tcpip.c, tcpip.h memp.c, memp.h: Added distinct memp (MEMP_TCPIP_MSG_INPKT) + for input packets to prevent floods from consuming all of MEMP_TCPIP_MSG + and starving other message types. + Renamed MEMP_TCPIP_MSG to MEMP_TCPIP_MSG_API + + 2007-08-16 Marc Boucher + * pbuf.c, pbuf.h, etharp.c, tcp_in.c, sockets.c: Split pbuf flags in pbuf + type and flgs (later renamed to flags). + Use enum pbuf_flag as pbuf_type. Renumber PBUF_FLAG_*. + Improved lwip_recvfrom(). TCP push now propagated. + + 2007-08-16 Marc Boucher + * ethernetif.c, contrib/ports/various: ethbroadcast now a shared global + provided by etharp. + + 2007-08-16 Marc Boucher + * ppp_oe.c ppp_oe.h, auth.c chap.c fsm.c lcp.c ppp.c ppp.h, + etharp.c ethernetif.c, etharp.h, opt.h tcpip.h, tcpip.c: + Added PPPoE support and various PPP improvements. + + 2007-07-25 Simon Goldschmidt + * api_lib.c, ip_frag.c, pbuf.c, api.h, pbuf.h: Introduced pbuf_copy_partial, + making netbuf_copy_partial use this function. + + 2007-07-25 Simon Goldschmidt + * tcp_in.c: Fix bug #20506: Slow start / initial congestion window starts with + 2 * mss (instead of 1 * mss previously) to comply with some newer RFCs and + other stacks. + + 2007-07-13 Jared Grubb (integrated by Frdric Bernon) + * opt.h, netif.h, netif.c, ethernetif.c: Add new configuration option to add + a link callback in the netif struct, and functions to handle it. Be carefull + for port maintainers to add the NETIF_FLAG_LINK_UP flag (like in ethernetif.c) + if you want to be sure to be compatible with future changes... + + 2007-06-30 Frdric Bernon + * sockets.h, sockets.c: Implement MSG_PEEK flag for recv/recvfrom functions. + + 2007-06-21 Simon Goldschmidt + * etharp.h, etharp.c: Combined etharp_request with etharp_raw for both + LWIP_AUTOIP =0 and =1 to remove redundant code. + + 2007-06-21 Simon Goldschmidt + * mem.c, memp.c, mem.h, memp.h, opt.h: task #6863: Introduced the option + MEM_USE_POOLS to use 4 pools with different sized elements instead of a + heap. This both prevents memory fragmentation and gives a higher speed + at the cost of more memory consumption. Turned off by default. + + 2007-06-21 Simon Goldschmidt + * api_lib.c, api_msg.c, api.h, api_msg.h: Converted the length argument of + netconn_write (and therefore also api_msg_msg.msg.w.len) from u16_t into + int to be able to send a bigger buffer than 64K with one time (mainly + used from lwip_send). + + 2007-06-21 Simon Goldschmidt + * tcp.h, api_msg.c: Moved the nagle algorithm from netconn_write/do_write + into a define (tcp_output_nagle) in tcp.h to provide it to raw api users, too. + + 2007-06-21 Simon Goldschmidt + * api.h, api_lib.c, api_msg.c: Fixed bug #20021: Moved sendbuf-processing in + netconn_write from api_lib.c to api_msg.c to also prevent multiple context- + changes on low memory or empty send-buffer. + + 2007-06-18 Simon Goldschmidt + * etharp.c, etharp.h: Changed etharp to use a defined hardware address length + of 6 to avoid loading netif->hwaddr_len every time (since this file is only + used for ethernet and struct eth_addr already had a defined length of 6). + + 2007-06-17 Simon Goldschmidt + * sockets.c, sockets.h: Implemented socket options SO_NO_CHECK for UDP sockets + to disable UDP checksum generation on transmit. + + 2007-06-13 Frdric Bernon, Simon Goldschmidt + * debug.h, api_msg.c: change LWIP_ERROR to use it to check errors like invalid + pointers or parameters, and let the possibility to redefined it in cc.h. Use + this macro to check "conn" parameter in api_msg.c functions. + + 2007-06-11 Simon Goldschmidt + * sockets.c, sockets.h: Added UDP lite support for sockets + + 2007-06-10 Simon Goldschmidt + * udp.h, opt.h, api_msg.c, ip.c, udp.c: Included switch LWIP_UDPLITE (enabled + by default) to switch off UDP-Lite support if not needed (reduces udp.c code + size) + + 2007-06-09 Dominik Spies (integrated by Frdric Bernon) + * autoip.h, autoip.c, dhcp.h, dhcp.c, netif.h, netif.c, etharp.h, etharp.c, opt.h: + AutoIP implementation available for IPv4, with new options LWIP_AUTOIP and + LWIP_DHCP_AUTOIP_COOP if you want to cooperate with DHCP. Some tips to adapt + (see TODO mark in the source code). + + 2007-06-09 Simon Goldschmidt + * etharp.h, etharp.c, ethernetif.c: Modified order of parameters for + etharp_output() to match netif->output so etharp_output() can be used + directly as netif->output to save one function call. + + 2007-06-08 Simon Goldschmidt + * netif.h, ethernetif.c, slipif.c, loopif.c: Added define + NETIF_INIT_SNMP(netif, type, speed) to initialize per-netif snmp variables, + added initialization of those to ethernetif, slipif and loopif. + + 2007-05-18 Simon Goldschmidt + * opt.h, ip_frag.c, ip_frag.h, ip.c: Added option IP_FRAG_USES_STATIC_BUF + (defaulting to off for now) that can be set to 0 to send fragmented + packets by passing PBUF_REFs down the stack. + + 2007-05-23 Frdric Bernon + * api_lib.c: Implement SO_RCVTIMEO for accept and recv on TCP + connections, such present in patch #5959. + + 2007-05-23 Frdric Bernon + * api.h, api_lib.c, api_msg.c, sockets.c: group the different NETCONN_UDPxxx + code in only one part... + + 2007-05-18 Simon Goldschmidt + * opt.h, memp.h, memp.c: Added option MEMP_OVERFLOW_CHECK to check for memp + elements to overflow. This is achieved by adding some bytes before and after + each pool element (increasing their size, of course), filling them with a + prominent value and checking them on freeing the element. + Set it to 2 to also check every element in every pool each time memp_malloc() + or memp_free() is called (slower but more helpful). + + 2007-05-10 Simon Goldschmidt + * opt.h, memp.h, memp.c, pbuf.c (see task #6831): use a new memp pool for + PBUF_POOL pbufs instead of the old pool implementation in pbuf.c to reduce + code size. + + 2007-05-11 Frdric Bernon + * sockets.c, api_lib.c, api_msg.h, api_msg.c, netifapi.h, netifapi.c, tcpip.c: + Include a function pointer instead of a table index in the message to reduce + footprint. Disable some part of lwip_send and lwip_sendto if some options are + not set (LWIP_TCP, LWIP_UDP, LWIP_RAW). + + 2007-05-10 Simon Goldschmidt + * *.h (except netif/ppp/*.h): Included patch #5448: include '#ifdef __cplusplus + \ extern "C" {' in all header files. Now you can write your application using + the lwIP stack in C++ and simply #include the core files. Note I have left + out the netif/ppp/*h header files for now, since I don't know which files are + included by applications and which are for internal use only. + + 2007-05-09 Simon Goldschmidt + * opt.h, *.c/*.h: Included patch #5920: Create define to override C-library + memcpy. 2 Defines are created: MEMCPY() for normal memcpy, SMEMCPY() for + situations where some compilers might inline the copy and save a function + call. Also replaced all calls to memcpy() with calls to (S)MEMCPY(). + + 2007-05-08 Simon Goldschmidt + * mem.h: If MEM_LIBC_MALLOC==1, allow the defines (e.g. mem_malloc() -> malloc()) + to be overriden in case the C-library malloc implementation is not protected + against concurrent access. + + 2007-05-04 Simon Goldschmidt (Atte Kojo) + * etharp.c: Introduced fast one-entry-cache to speed up ARP lookup when sending + multiple packets to the same host. + + 2007-05-04 Frdric Bernon, Jonathan Larmour + * sockets.c, api.h, api_lib.c, api_msg.h, api_msg.c: Fix bug #19162 "lwip_sento: a possible + to corrupt remote addr/port connection state". Reduce problems "not enought memory" with + netbuf (if we receive lot of datagrams). Improve lwip_sendto (only one exchange between + sockets api and api_msg which run in tcpip_thread context). Add netconn_sento function. + Warning, if you directly access to "fromaddr" & "fromport" field from netbuf struct, + these fields are now renamed "addr" & "port". + + 2007-04-11 Jonathan Larmour + * sys.h, api_lib.c: Provide new sys_mbox_tryfetch function. Require ports to provide new + sys_arch_mbox_tryfetch function to get a message if one is there, otherwise return + with SYS_MBOX_EMPTY. sys_arch_mbox_tryfetch can be implemented as a function-like macro + by the port in sys_arch.h if desired. + + 2007-04-06 Frdric Bernon, Simon Goldschmidt + * opt.h, tcpip.h, tcpip.c, netifapi.h, netifapi.c: New configuration option LWIP_NETIF_API + allow to use thread-safe functions to add/remove netif in list, and to start/stop dhcp + clients, using new functions from netifapi.h. Disable as default (no port change to do). + + 2007-04-05 Frdric Bernon + * sockets.c: remplace ENOBUFS errors on alloc_socket by ENFILE to be more BSD compliant. + + 2007-04-04 Simon Goldschmidt + * arch.h, api_msg.c, dhcp.c, msg_in.c, sockets.c: Introduced #define LWIP_UNUSED_ARG(x) + use this for and architecture-independent form to tell the compiler you intentionally + are not using this variable. Can be overriden in cc.h. + + 2007-03-28 Frdric Bernon + * opt.h, netif.h, dhcp.h, dhcp.c: New configuration option LWIP_NETIF_HOSTNAME allow to + define a hostname in netif struct (this is just a pointer, so, you can use a hardcoded + string, point on one of your's ethernetif field, or alloc a string you will free yourself). + It will be used by DHCP to register a client hostname, but can also be use when you call + snmp_set_sysname. + + 2007-03-28 Frdric Bernon + * netif.h, netif.c: A new NETIF_FLAG_ETHARP flag is defined in netif.h, to allow to + initialize a network interface's flag with. It tell this interface is an ethernet + device, and we can use ARP with it to do a "gratuitous ARP" (RFC 3220 "IP Mobility + Support for IPv4" section 4.6) when interface is "up" with netif_set_up(). + + 2007-03-26 Frdric Bernon, Jonathan Larmour + * opt.h, tcpip.c: New configuration option LWIP_ARP allow to disable ARP init at build + time if you only use PPP or SLIP. The default is enable. Note we don't have to call + etharp_init in your port's initilization sequence if you use tcpip.c, because this call + is done in tcpip_init function. + + 2007-03-22 Frdric Bernon + * stats.h, stats.c, msg_in.c: Stats counters can be change to u32_t if necessary with the + new option LWIP_STATS_LARGE. If you need this option, define LWIP_STATS_LARGE to 1 in + your lwipopts.h. More, unused counters are not defined in the stats structs, and not + display by stats_display(). Note that some options (SYS_STATS and RAW_STATS) are defined + but never used. Fix msg_in.c with the correct #if test for a stat display. + + 2007-03-21 Kieran Mansley + * netif.c, netif.h: Apply patch#4197 with some changes (originator: rireland@hmgsl.com). + Provides callback on netif up/down state change. + + 2007-03-11 Frdric Bernon, Mace Gael, Steve Reynolds + * sockets.h, sockets.c, api.h, api_lib.c, api_msg.h, api_msg.c, igmp.h, igmp.c, + ip.c, netif.h, tcpip.c, opt.h: + New configuration option LWIP_IGMP to enable IGMP processing. Based on only one + filter per all network interfaces. Declare a new function in netif to enable to + control the MAC filter (to reduce lwIP traffic processing). + + 2007-03-11 Frdric Bernon + * tcp.h, tcp.c, sockets.c, tcp_out.c, tcp_in.c, opt.h: Keepalive values can + be configured at run time with LWIP_TCP_KEEPALIVE, but don't change this + unless you know what you're doing (default are RFC1122 compliant). Note + that TCP_KEEPIDLE and TCP_KEEPINTVL have to be set in seconds. + + 2007-03-08 Frdric Bernon + * tcp.h: Keepalive values can be configured at compile time, but don't change + this unless you know what you're doing (default are RFC1122 compliant). + + 2007-03-08 Frdric Bernon + * sockets.c, api.h, api_lib.c, tcpip.c, sys.h, sys.c, err.c, opt.h: + Implement LWIP_SO_RCVTIMEO configuration option to enable/disable SO_RCVTIMEO + on UDP sockets/netconn. + + 2007-03-08 Simon Goldschmidt + * snmp_msg.h, msg_in.c: SNMP UDP ports can be configured at compile time. + + 2007-03-06 Frdric Bernon + * api.h, api_lib.c, sockets.h, sockets.c, tcpip.c, sys.h, sys.c, err.h: + Implement SO_RCVTIMEO on UDP sockets/netconn. + + 2007-02-28 Kieran Mansley (based on patch from Simon Goldschmidt) + * api_lib.c, tcpip.c, memp.c, memp.h: make API msg structs allocated + on the stack and remove the API msg type from memp + + 2007-02-26 Jonathan Larmour (based on patch from Simon Goldschmidt) + * sockets.h, sockets.c: Move socket initialization to new + lwip_socket_init() function. + NOTE: this changes the API with ports. Ports will have to be + updated to call lwip_socket_init() now. + + 2007-02-26 Jonathan Larmour (based on patch from Simon Goldschmidt) + * api_lib.c: Use memcpy in netbuf_copy_partial. + + + ++ Bug fixes: + + 2008-03-17 Frdric Bernon, Ed Kerekes + * igmp.h, igmp.c: Fix bug #22613 "IGMP iphdr problem" (could have + some problems to fill the IP header on some targets, use now the + ip.h macros to do it). + + 2008-03-13 Frdric Bernon + * sockets.c: Fix bug #22435 "lwip_recvfrom with TCP break;". Using + (lwip_)recvfrom with valid "from" and "fromlen" parameters, on a + TCP connection caused a crash. Note that using (lwip_)recvfrom + like this is a bit slow and that using (lwip)getpeername is the + good lwip way to do it (so, using recv is faster on tcp sockets). + + 2008-03-12 Frdric Bernon, Jonathan Larmour + * api_msg.c, contrib/apps/ping.c: Fix bug #22530 "api_msg.c's + recv_raw() does not consume data", and the ping sample (with + LWIP_SOCKET=1, the code did the wrong supposition that lwip_recvfrom + returned the IP payload, without the IP header). + + 2008-03-04 Jonathan Larmour + * mem.c, stats.c, mem.h: apply patch #6414 to avoid compiler errors + and/or warnings on some systems where mem_size_t and size_t differ. + * pbuf.c, ppp.c: Fix warnings on some systems with mem_malloc. + + 2008-03-04 Kieran Mansley (contributions by others) + * Numerous small compiler error/warning fixes from contributions to + mailing list after 1.3.0 release candidate made. + + 2008-01-25 Cui hengbin (integrated by Frdric Bernon) + * dns.c: Fix bug #22108 "DNS problem" caused by unaligned structures. + + 2008-01-15 Kieran Mansley + * tcp_out.c: BUG20511. Modify persist timer to start when we are + prevented from sending by a small send window, not just a zero + send window. + + 2008-01-09 Jonathan Larmour + * opt.h, ip.c: Rename IP_OPTIONS define to IP_OPTIONS_ALLOWED to avoid + conflict with Linux system headers. + + 2008-01-06 Jonathan Larmour + * dhcp.c: fix bug #19927: "DHCP NACK problem" by clearing any existing set IP + address entirely on receiving a DHCPNAK, and restarting discovery. + + 2007-12-21 Simon Goldschmidt + * sys.h, api_lib.c, api_msg.c, sockets.c: fix bug #21698: "netconn->recv_avail + is not protected" by using new macros for interlocked access to modify/test + netconn->recv_avail. + + 2007-12-20 Kieran Mansley (based on patch from Oleg Tyshev) + * tcp_in.c: fix bug# 21535 (nrtx not reset correctly in SYN_SENT state) + + 2007-12-20 Kieran Mansley (based on patch from Per-Henrik Lundbolm) + * tcp.c, tcp_in.c, tcp_out.c, tcp.h: fix bug #20199 (better handling + of silly window avoidance and prevent lwIP from shrinking the window) + + 2007-12-04 Simon Goldschmidt + * tcp.c, tcp_in.c: fix bug #21699 (segment leak in ooseq processing when last + data packet was lost): add assert that all segment lists are empty in + tcp_pcb_remove before setting pcb to CLOSED state; don't directly set CLOSED + state from LAST_ACK in tcp_process + + 2007-12-02 Simon Goldschmidt + * sockets.h: fix bug #21654: exclude definition of struct timeval from #ifndef FD_SET + If including for system-struct timeval, LWIP_TIMEVAL_PRIVATE now + has to be set to 0 in lwipopts.h + + 2007-12-02 Simon Goldschmidt + * api_msg.c, api_lib.c: fix bug #21656 (recvmbox problem in netconn API): always + allocate a recvmbox in netconn_new_with_proto_and_callback. For a tcp-listen + netconn, this recvmbox is later freed and a new mbox is allocated for acceptmbox. + This is a fix for thread-safety and allocates all items needed for a netconn + when the netconn is created. + + 2007-11-30 Simon Goldschmidt + * udp.c: first attempt to fix bug #21655 (DHCP doesn't work reliably with multiple + netifs): if LWIP_DHCP is enabled, UDP packets to DHCP_CLIENT_PORT are passed + to netif->dhcp->pcb only (if that exists) and not to any other pcb for the same + port (only solution to let UDP pcbs 'bind' to a netif instead of an IP address) + + 2007-11-27 Simon Goldschmidt + * ip.c: fixed bug #21643 (udp_send/raw_send don't fail if netif is down) by + letting ip_route only use netifs that are up. + + 2007-11-27 Simon Goldschmidt + * err.h, api_lib.c, api_msg.c, sockets.c: Changed error handling: ERR_MEM, ERR_BUF + and ERR_RTE are seen as non-fatal, all other errors are fatal. netconns and + sockets block most operations once they have seen a fatal error. + + 2007-11-27 Simon Goldschmidt + * udp.h, udp.c, dhcp.c: Implemented new function udp_sendto_if which takes the + netif to send as an argument (to be able to send on netifs that are down). + + 2007-11-26 Simon Goldschmidt + * tcp_in.c: Fixed bug #21582: pcb->acked accounting can be wrong when ACKs + arrive out-of-order + + 2007-11-21 Simon Goldschmidt + * tcp.h, tcp_out.c, api_msg.c: Fixed bug #20287: tcp_output_nagle sends too early + Fixed the nagle algorithm; nagle now also works for all raw API applications + and has to be explicitly disabled with 'tcp_pcb->flags |= TF_NODELAY' + + 2007-11-12 Frdric Bernon + * sockets.c, api.h, api_lib.c, api_msg.h, api_msg.c: Fixed bug #20900. Now, most + of the netconn_peer and netconn_addr processing is done inside tcpip_thread + context in do_getaddr. + + 2007-11-10 Simon Goldschmidt + * etharp.c: Fixed bug: assert fired when MEMP_ARP_QUEUE was empty (which can + happen any time). Now the packet simply isn't enqueued when out of memory. + + 2007-11-01 Simon Goldschmidt + * tcp.c, tcp_in.c: Fixed bug #21494: The send mss (pcb->mss) is set to 536 (or + TCP_MSS if that is smaller) as long as no MSS option is received from the + remote host. + + 2007-11-01 Simon Goldschmidt + * tcp.h, tcp.c, tcp_in.c: Fixed bug #21491: The MSS option sent (with SYN) + is now based on TCP_MSS instead of pcb->mss (on passive open now effectively + sending our configured TCP_MSS instead of the one received). + + 2007-11-01 Simon Goldschmidt + * tcp_in.c: Fixed bug #21181: On active open, the initial congestion window was + calculated based on the configured TCP_MSS, not on the MSS option received + with SYN+ACK. + + 2007-10-09 Simon Goldschmidt + * udp.c, inet.c, inet.h: Fixed UDPLite: send: Checksum was always generated too + short and also was generated wrong if checksum coverage != tot_len; + receive: checksum was calculated wrong if checksum coverage != tot_len + + 2007-10-08 Simon Goldschmidt + * mem.c: lfree was not updated in mem_realloc! + + 2007-10-07 Frdric Bernon + * sockets.c, api.h, api_lib.c: First step to fix "bug #20900 : Potential + crash error problem with netconn_peer & netconn_addr". VERY IMPORTANT: + this change cause an API breakage for netconn_addr, since a parameter + type change. Any compiler should cause an error without any changes in + yours netconn_peer calls (so, it can't be a "silent change"). It also + reduce a little bit the footprint for socket layer (lwip_getpeername & + lwip_getsockname use now a common lwip_getaddrname function since + netconn_peer & netconn_addr have the same parameters). + + 2007-09-20 Simon Goldschmidt + * tcp.c: Fixed bug #21080 (tcp_bind without check pcbs in TIME_WAIT state) + by checking tcp_tw_pcbs also + + 2007-09-19 Simon Goldschmidt + * icmp.c: Fixed bug #21107 (didn't reset IP TTL in ICMP echo replies) + + 2007-09-15 Mike Kleshov + * mem.c: Fixed bug #21077 (inaccuracy in calculation of lwip_stat.mem.used) + + 2007-09-06 Frdric Bernon + * several-files: replace some #include "arch/cc.h" by "lwip/arch.h", or simply remove + it as long as "lwip/opt.h" is included before (this one include "lwip/debug.h" which + already include "lwip/arch.h"). Like that, default defines are provided by "lwip/arch.h" + if they are not defined in cc.h, in the same spirit than "lwip/opt.h" for lwipopts.h. + + 2007-08-30 Frdric Bernon + * igmp.h, igmp.c: Some changes to remove some redundant code, add some traces, + and fix some coding style. + + 2007-08-28 Frdric Bernon + * tcpip.c: Fix TCPIP_MSG_INPKT processing: now, tcpip_input can be used for any + kind of packets. These packets are considered like Ethernet packets (payload + pointing to ethhdr) if the netif got the NETIF_FLAG_ETHARP flag. Else, packets + are considered like IP packets (payload pointing to iphdr). + + 2007-08-27 Frdric Bernon + * api.h, api_lib.c, api_msg.c: First fix for "bug #20900 : Potential crash error + problem with netconn_peer & netconn_addr". Introduce NETCONN_LISTEN netconn_state + and remove obsolete ones (NETCONN_RECV & NETCONN_ACCEPT). + + 2007-08-24 Kieran Mansley + * inet.c Modify (acc >> 16) test to ((acc >> 16) != 0) to help buggy + compiler (Paradigm C++) + + 2007-08-09 Frdric Bernon, Bill Florac + * stats.h, stats.c, igmp.h, igmp.c, opt.h: Fix for bug #20503 : IGMP Improvement. + Introduce IGMP_STATS to centralize statistics management. + + 2007-08-09 Frdric Bernon, Bill Florac + * udp.c: Fix for bug #20503 : IGMP Improvement. Enable to receive a multicast + packet on a udp pcb binded on an netif's IP address, and not on "any". + + 2007-08-09 Frdric Bernon, Bill Florac + * igmp.h, igmp.c, ip.c: Fix minor changes from bug #20503 : IGMP Improvement. + This is mainly on using lookup/lookfor, and some coding styles... + + 2007-07-26 Frdric Bernon (and "thedoctor") + * igmp.c: Fix bug #20595 to accept IGMPv3 "Query" messages. + + 2007-07-25 Simon Goldschmidt + * api_msg.c, tcp.c: Another fix for bug #20021: by not returning an error if + tcp_output fails in tcp_close, the code in do_close_internal gets simpler + (tcp_output is called again later from tcp timers). + + 2007-07-25 Simon Goldschmidt + * ip_frag.c: Fixed bug #20429: use the new pbuf_copy_partial instead of the old + copy_from_pbuf, which illegally modified the given pbuf. + + 2007-07-25 Simon Goldschmidt + * tcp_out.c: tcp_enqueue: pcb->snd_queuelen didn't work for chaine PBUF_RAMs: + changed snd_queuelen++ to snd_queuelen += pbuf_clen(p). + + 2007-07-24 Simon Goldschmidt + * api_msg.c, tcp.c: Fix bug #20480: Check the pcb passed to tcp_listen() for the + correct state (must be CLOSED). + + 2007-07-13 Thomas Taranowski (commited by Jared Grubb) + * memp.c: Fix bug #20478: memp_malloc returned NULL+MEMP_SIZE on failed + allocation. It now returns NULL. + + 2007-07-13 Frdric Bernon + * api_msg.c: Fix bug #20318: api_msg "recv" callbacks don't call pbuf_free in + all error cases. + + 2007-07-13 Frdric Bernon + * api_msg.c: Fix bug #20315: possible memory leak problem if tcp_listen failed, + because current code doesn't follow rawapi.txt documentation. + + 2007-07-13 Kieran Mansley + * src/core/tcp_in.c Apply patch#5741 from Oleg Tyshev to fix bug in + out of sequence processing of received packets + + 2007-07-03 Simon Goldschmidt + * nearly-all-files: Added assertions where PBUF_RAM pbufs are used and an + assumption is made that this pbuf is in one piece (i.e. not chained). These + assumptions clash with the possibility of converting to fully pool-based + pbuf implementations, where PBUF_RAM pbufs might be chained. + + 2007-07-03 Simon Goldschmidt + * api.h, api_lib.c, api_msg.c: Final fix for bug #20021 and some other problems + when closing tcp netconns: removed conn->sem, less context switches when + closing, both netconn_close and netconn_delete should safely close tcp + connections. + + 2007-07-02 Simon Goldschmidt + * ipv4/ip.h, ipv6/ip.h, opt.h, netif.h, etharp.h, ipv4/ip.c, netif.c, raw.c, + tcp_out.c, udp.c, etharp.c: Added option LWIP_NETIF_HWADDRHINT (default=off) + to cache ARP table indices with each pcb instead of single-entry cache for + the complete stack. + + 2007-07-02 Simon Goldschmidt + * tcp.h, tcp.c, tcp_in.c, tcp_out.c: Added some ASSERTS and casts to prevent + warnings when assigning to smaller types. + + 2007-06-28 Simon Goldschmidt + * tcp_out.c: Added check to prevent tcp_pcb->snd_queuelen from overflowing. + + 2007-06-28 Simon Goldschmidt + * tcp.h: Fixed bug #20287: Fixed nagle algorithm (sending was done too early if + a segment contained chained pbufs) + + 2007-06-28 Frdric Bernon + * autoip.c: replace most of rand() calls by a macro LWIP_AUTOIP_RAND which compute + a "pseudo-random" value based on netif's MAC and some autoip fields. It's always + possible to define this macro in your own lwipopts.h to always use C library's + rand(). Note that autoip_create_rand_addr doesn't use this macro. + + 2007-06-28 Frdric Bernon + * netifapi.h, netifapi.c, tcpip.h, tcpip.c: Update code to handle the option + LWIP_TCPIP_CORE_LOCKING, and do some changes to be coherent with last modifications + in api_lib/api_msg (use pointers and not type with table, etc...) + + 2007-06-26 Simon Goldschmidt + * udp.h: Fixed bug #20259: struct udp_hdr was lacking the packin defines. + + 2007-06-25 Simon Goldschmidt + * udp.c: Fixed bug #20253: icmp_dest_unreach was called with a wrong p->payload + for udp packets with no matching pcb. + + 2007-06-25 Simon Goldschmidt + * udp.c: Fixed bug #20220: UDP PCB search in udp_input(): a non-local match + could get udp input packets if the remote side matched. + + 2007-06-13 Simon Goldschmidt + * netif.c: Fixed bug #20180 (TCP pcbs listening on IP_ADDR_ANY could get + changed in netif_set_ipaddr if previous netif->ip_addr.addr was 0. + + 2007-06-13 Simon Goldschmidt + * api_msg.c: pcb_new sets conn->err if protocol is not implemented + -> netconn_new_..() does not allocate a new connection for unsupported + protocols. + + 2007-06-13 Frdric Bernon, Simon Goldschmidt + * api_lib.c: change return expression in netconn_addr and netconn_peer, because + conn->err was reset to ERR_OK without any reasons (and error was lost)... + + 2007-06-13 Frdric Bernon, Matthias Weisser + * opt.h, mem.h, mem.c, memp.c, pbuf.c, ip_frag.c, vj.c: Fix bug #20162. Rename + MEM_ALIGN in LWIP_MEM_ALIGN and MEM_ALIGN_SIZE in LWIP_MEM_ALIGN_SIZE to avoid + some macro names collision with some OS macros. + + 2007-06-11 Simon Goldschmidt + * udp.c: UDP Lite: corrected the use of chksum_len (based on RFC3828: if it's 0, + create checksum over the complete packet. On RX, if it's < 8 (and not 0), + discard the packet. Also removed the duplicate 'udphdr->chksum = 0' for both + UDP & UDP Lite. + + 2007-06-11 Srinivas Gollakota & Oleg Tyshev + * tcp_out.c: Fix for bug #20075 : "A problem with keep-alive timer and TCP flags" + where TCP flags wasn't initialized in tcp_keepalive. + + 2007-06-03 Simon Goldschmidt + * udp.c: udp_input(): Input pbuf was not freed if pcb had no recv function + registered, p->payload was modified without modifying p->len if sending + icmp_dest_unreach() (had no negative effect but was definitively wrong). + + 2007-06-03 Simon Goldschmidt + * icmp.c: Corrected bug #19937: For responding to an icmp echo request, icmp + re-used the input pbuf even if that didn't have enough space to include the + link headers. Now the space is tested and a new pbuf is allocated for the + echo response packet if the echo request pbuf isn't big enough. + + 2007-06-01 Simon Goldschmidt + * sockets.c: Checked in patch #5914: Moved sockopt processing into tcpip_thread. + + 2007-05-23 Frdric Bernon + * api_lib.c, sockets.c: Fixed bug #5958 for netconn_listen (acceptmbox only + allocated by do_listen if success) and netconn_accept errors handling. In + most of api_lib functions, we replace some errors checkings like "if (conn==NULL)" + by ASSERT, except for netconn_delete. + + 2007-05-23 Frdric Bernon + * api_lib.c: Fixed bug #5957 "Safe-thread problem inside netconn_recv" to return + an error code if it's impossible to fetch a pbuf on a TCP connection (and not + directly close the recvmbox). + + 2007-05-22 Simon Goldschmidt + * tcp.c: Fixed bug #1895 (tcp_bind not correct) by introducing a list of + bound but unconnected (and non-listening) tcp_pcbs. + + 2007-05-22 Frdric Bernon + * sys.h, sys.c, api_lib.c, tcpip.c: remove sys_mbox_fetch_timeout() (was only + used for LWIP_SO_RCVTIMEO option) and use sys_arch_mbox_fetch() instead of + sys_mbox_fetch() in api files. Now, users SHOULD NOT use internal lwIP features + like "sys_timeout" in their application threads. + + 2007-05-22 Frdric Bernon + * api.h, api_lib.c, api_msg.h, api_msg.c: change the struct api_msg_msg to see + which parameters are used by which do_xxx function, and to avoid "misusing" + parameters (patch #5938). + + 2007-05-22 Simon Goldschmidt + * api_lib.c, api_msg.c, raw.c, api.h, api_msg.h, raw.h: Included patch #5938: + changed raw_pcb.protocol from u16_t to u8_t since for IPv4 and IPv6, proto + is only 8 bits wide. This affects the api, as there, the protocol was + u16_t, too. + + 2007-05-18 Simon Goldschmidt + * memp.c: addition to patch #5913: smaller pointer was returned but + memp_memory was the same size -> did not save memory. + + 2007-05-16 Simon Goldschmidt + * loopif.c, slipif.c: Fix bug #19729: free pbuf if netif->input() returns + != ERR_OK. + + 2007-05-16 Simon Goldschmidt + * api_msg.c, udp.c: If a udp_pcb has a local_ip set, check if it is the same + as the one of the netif used for sending to prevent sending from old + addresses after a netif address gets changed (partly fixes bug #3168). + + 2007-05-16 Frdric Bernon + * tcpip.c, igmp.h, igmp.c: Fixed bug "#19800 : IGMP: igmp_tick() will not work + with NO_SYS=1". Note that igmp_init is always in tcpip_thread (and not in + tcpip_init) because we have to be sure that network interfaces are already + added (mac filter is updated only in igmp_init for the moment). + + 2007-05-16 Simon Goldschmidt + * mem.c, memp.c: Removed semaphores from memp, changed sys_sem_wait calls + into sys_arch_sem_wait calls to prevent timers from running while waiting + for the heap. This fixes bug #19167. + + 2007-05-13 Simon Goldschmidt + * tcp.h, sockets.h, sockets.c: Fixed bug from patch #5865 by moving the defines + for socket options (lwip_set/-getsockopt) used with level IPPROTO_TCP from + tcp.h to sockets.h. + + 2007-05-07 Simon Goldschmidt + * mem.c: Another attempt to fix bug #17922. + + 2007-05-04 Simon Goldschmidt + * pbuf.c, pbuf.h, etharp.c: Further update to ARP queueing: Changed pbuf_copy() + implementation so that it can be reused (don't allocate the target + pbuf inside pbuf_copy()). + + 2007-05-04 Simon Goldschmidt + * memp.c: checked in patch #5913: in memp_malloc() we can return memp as mem + to save a little RAM (next pointer of memp is not used while not in pool). + + 2007-05-03 "maq" + * sockets.c: Fix ioctl FIONREAD when some data remains from last recv. + (patch #3574). + + 2007-04-23 Simon Goldschmidt + * loopif.c, loopif.h, opt.h, src/netif/FILES: fix bug #2595: "loopif results + in NULL reference for incoming TCP packets". Loopif has to be configured + (using LWIP_LOOPIF_MULTITHREADING) to directly call netif->input() + (multithreading environments, e.g. netif->input() = tcpip_input()) or + putting packets on a list that is fed to the stack by calling loopif_poll() + (single-thread / NO_SYS / polling environment where e.g. + netif->input() = ip_input). + + 2007-04-17 Jonathan Larmour + * pbuf.c: Use s32_t in pbuf_realloc(), as an s16_t can't reliably hold + the difference between two u16_t's. + * sockets.h: FD_SETSIZE needs to match number of sockets, which is + MEMP_NUM_NETCONN in sockets.c right now. + + 2007-04-12 Jonathan Larmour + * icmp.c: Reset IP header TTL in ICMP ECHO responses (bug #19580). + + 2007-04-12 Kieran Mansley + * tcp.c, tcp_in.c, tcp_out.c, tcp.h: Modify way the retransmission + timer is reset to fix bug#19434, with help from Oleg Tyshev. + + 2007-04-11 Simon Goldschmidt + * etharp.c, pbuf.c, pbuf.h: 3rd fix for bug #11400 (arp-queuing): More pbufs than + previously thought need to be copied (everything but PBUF_ROM!). Cleaned up + pbuf.c: removed functions no needed any more (by etharp). + + 2007-04-11 Kieran Mansley + * inet.c, ip_addr.h, sockets.h, sys.h, tcp.h: Apply patch #5745: Fix + "Constant is long" warnings with 16bit compilers. Contributed by + avatar@mmlab.cse.yzu.edu.tw + + 2007-04-05 Frdric Bernon, Jonathan Larmour + * api_msg.c: Fix bug #16830: "err_tcp() posts to connection mailbox when no pend on + the mailbox is active". Now, the post is only done during a connect, and do_send, + do_write and do_join_leave_group don't do anything if a previous error was signaled. + + 2007-04-03 Frdric Bernon + * ip.c: Don't set the IP_DF ("Don't fragment") flag in the IP header in IP output + packets. See patch #5834. + + 2007-03-30 Frdric Bernon + * api_msg.c: add a "pcb_new" helper function to avoid redundant code, and to add + missing pcb allocations checking (in do_bind, and for each raw_new). Fix style. + + 2007-03-30 Frdric Bernon + * most of files: prefix all debug.h define with "LWIP_" to avoid any conflict with + others environment defines (these were too "generic"). + + 2007-03-28 Frdric Bernon + * api.h, api_lib.c, sockets.c: netbuf_ref doesn't check its internal pbuf_alloc call + result and can cause a crash. lwip_send now check netbuf_ref result. + + 2007-03-28 Simon Goldschmidt + * sockets.c Remove "#include " from sockets.c to avoid multiple + definition of macros (in errno.h and lwip/arch.h) if LWIP_PROVIDE_ERRNO is + defined. This is the way it should have been already (looking at + doc/sys_arch.txt) + + 2007-03-28 Kieran Mansley + * opt.h Change default PBUF_POOL_BUFSIZE (again) to accomodate default MSS + + IP and TCP headers *and* physical link headers + + 2007-03-26 Frdric Bernon (based on patch from Dmitry Potapov) + * api_lib.c: patch for netconn_write(), fixes a possible race condition which cause + to send some garbage. It is not a definitive solution, but the patch does solve + the problem for most cases. + + 2007-03-22 Frdric Bernon + * api_msg.h, api_msg.c: Remove obsolete API_MSG_ACCEPT and do_accept (never used). + + 2007-03-22 Frdric Bernon + * api_lib.c: somes resources couldn't be freed if there was errors during + netconn_new_with_proto_and_callback. + + 2007-03-22 Frdric Bernon + * ethernetif.c: update netif->input calls to check return value. In older ports, + it's a good idea to upgrade them, even if before, there could be another problem + (access to an uninitialized mailbox). + + 2007-03-21 Simon Goldschmidt + * sockets.c: fixed bug #5067 (essentialy a signed/unsigned warning fixed + by casting to unsigned). + + 2007-03-21 Frdric Bernon + * api_lib.c, api_msg.c, tcpip.c: integrate sys_mbox_fetch(conn->mbox, NULL) calls from + api_lib.c to tcpip.c's tcpip_apimsg(). Now, use a local variable and not a + dynamic one from memp to send tcpip_msg to tcpip_thread in a synchrone call. + Free tcpip_msg from tcpip_apimsg is not done in tcpip_thread. This give a + faster and more reliable communication between api_lib and tcpip. + + 2007-03-21 Frdric Bernon + * opt.h: Add LWIP_NETIF_CALLBACK (to avoid compiler warning) and set it to 0. + + 2007-03-21 Frdric Bernon + * api_msg.c, igmp.c, igmp.h: Fix C++ style comments + + 2007-03-21 Kieran Mansley + * opt.h Change default PBUF_POOL_BUFSIZE to accomodate default MSS + + IP and TCP headers + + 2007-03-21 Kieran Mansley + * Fix all uses of pbuf_header to check the return value. In some + cases just assert if it fails as I'm not sure how to fix them, but + this is no worse than before when they would carry on regardless + of the failure. + + 2007-03-21 Kieran Mansley + * sockets.c, igmp.c, igmp.h, memp.h: Fix C++ style comments and + comment out missing header include in icmp.c + + 2007-03-20 Frdric Bernon + * memp.h, stats.c: Fix stats_display function where memp_names table wasn't + synchronized with memp.h. + + 2007-03-20 Frdric Bernon + * tcpip.c: Initialize tcpip's mbox, and verify if initialized in tcpip_input, + tcpip_ethinput, tcpip_callback, tcpip_apimsg, to fix a init problem with + network interfaces. Also fix a compiler warning. + + 2007-03-20 Kieran Mansley + * udp.c: Only try and use pbuf_header() to make space for headers if + not a ROM or REF pbuf. + + 2007-03-19 Frdric Bernon + * api_msg.h, api_msg.c, tcpip.h, tcpip.c: Add return types to tcpip_apimsg() + and api_msg_post(). + + 2007-03-19 Frdric Bernon + * Remove unimplemented "memp_realloc" function from memp.h. + + 2007-03-11 Simon Goldschmidt + * pbuf.c: checked in patch #5796: pbuf_alloc: len field claculation caused + memory corruption. + + 2007-03-11 Simon Goldschmidt (based on patch from Dmitry Potapov) + * api_lib.c, sockets.c, api.h, api_msg.h, sockets.h: Fixed bug #19251 + (missing `const' qualifier in socket functions), to get more compatible to + standard POSIX sockets. + + 2007-03-11 Frdric Bernon (based on patch from Dmitry Potapov) + * sockets.c: Add asserts inside bind, connect and sendto to check input + parameters. Remove excessive set_errno() calls after get_socket(), because + errno is set inside of get_socket(). Move last sock_set_errno() inside + lwip_close. + + 2007-03-09 Simon Goldschmidt + * memp.c: Fixed bug #11400: New etharp queueing introduced bug: memp_memory + was allocated too small. + + 2007-03-06 Simon Goldschmidt + * tcpip.c: Initialize dhcp timers in tcpip_thread (if LWIP_DHCP) to protect + the stack from concurrent access. + + 2007-03-06 Frdric Bernon, Dmitry Potapov + * tcpip.c, ip_frag.c, ethernetif.c: Fix some build problems, and a redundancy + call to "lwip_stats.link.recv++;" in low_level_input() & ethernetif_input(). + + 2007-03-06 Simon Goldschmidt + * ip_frag.c, ip_frag.h: Reduce code size: don't include code in those files + if IP_FRAG == 0 and IP_REASSEMBLY == 0 + + 2007-03-06 Frdric Bernon, Simon Goldschmidt + * opt.h, ip_frag.h, tcpip.h, tcpip.c, ethernetif.c: add new configuration + option named ETHARP_TCPIP_ETHINPUT, which enable the new tcpip_ethinput. + Allow to do ARP processing for incoming packets inside tcpip_thread + (protecting ARP layer against concurrent access). You can also disable + old code using tcp_input with new define ETHARP_TCPIP_INPUT set to 0. + Older ports have to use tcpip_ethinput. + + 2007-03-06 Simon Goldschmidt (based on patch from Dmitry Potapov) + * err.h, err.c: fixed compiler warning "initialization dircards qualifiers + from pointer target type" + + 2007-03-05 Frdric Bernon + * opt.h, sockets.h: add new configuration options (LWIP_POSIX_SOCKETS_IO_NAMES, + ETHARP_TRUST_IP_MAC, review SO_REUSE) + + 2007-03-04 Frdric Bernon + * api_msg.c: Remove some compiler warnings : parameter "pcb" was never + referenced. + + 2007-03-04 Frdric Bernon + * api_lib.c: Fix "[patch #5764] api_lib.c cleanup: after patch #5687" (from + Dmitry Potapov). + The api_msg struct stay on the stack (not moved to netconn struct). + + 2007-03-04 Simon Goldschmidt (based on patch from Dmitry Potapov) + * pbuf.c: Fix BUG#19168 - pbuf_free can cause deadlock (if + SYS_LIGHTWEIGHT_PROT=1 & freeing PBUF_RAM when mem_sem is not available) + Also fixed cast warning in pbuf_alloc() + + 2007-03-04 Simon Goldschmidt + * etharp.c, etharp.h, memp.c, memp.h, opt.h: Fix BUG#11400 - don't corrupt + existing pbuf chain when enqueuing multiple pbufs to a pending ARP request + + 2007-03-03 Frdric Bernon + * udp.c: remove obsolete line "static struct udp_pcb *pcb_cache = NULL;" + It is static, and never used in udp.c except udp_init(). + + 2007-03-02 Simon Goldschmidt + * tcpip.c: Moved call to ip_init(), udp_init() and tcp_init() from + tcpip_thread() to tcpip_init(). This way, raw API connections can be + initialized before tcpip_thread is running (e.g. before OS is started) + + 2007-03-02 Frdric Bernon + * rawapi.txt: Fix documentation mismatch with etharp.h about etharp_tmr's call + interval. + + 2007-02-28 Kieran Mansley + * pbuf.c: Fix BUG#17645 - ensure pbuf payload pointer is not moved + outside the region of the pbuf by pbuf_header() + + 2007-02-28 Kieran Mansley + * sockets.c: Fix BUG#19161 - ensure milliseconds timeout is non-zero + when supplied timeout is also non-zero + +(STABLE-1.2.0) + + 2006-12-05 Leon Woestenberg + * CHANGELOG: Mention STABLE-1.2.0 release. + + ++ New features: + + 2006-12-01 Christiaan Simons + * mem.h, opt.h: Added MEM_LIBC_MALLOC option. + Note this is a workaround. Currently I have no other options left. + + 2006-10-26 Christiaan Simons (accepted patch by Jonathan Larmour) + * ipv4/ip_frag.c: rename MAX_MTU to IP_FRAG_MAX_MTU and move define + to include/lwip/opt.h. + * ipv4/lwip/ip_frag.h: Remove unused IP_REASS_INTERVAL. + Move IP_REASS_MAXAGE and IP_REASS_BUFSIZE to include/lwip/opt.h. + * opt.h: Add above new options. + + 2006-08-18 Christiaan Simons + * tcp_{in,out}.c: added SNMP counters. + * ipv4/ip.c: added SNMP counters. + * ipv4/ip_frag.c: added SNMP counters. + + 2006-08-08 Christiaan Simons + * etharp.{c,h}: added etharp_find_addr() to read + (stable) ethernet/IP address pair from ARP table + + 2006-07-14 Christiaan Simons + * mib_structs.c: added + * include/lwip/snmp_structs.h: added + * netif.{c,h}, netif/ethernetif.c: added SNMP statistics to netif struct + + 2006-07-06 Christiaan Simons + * snmp/asn1_{enc,dec}.c added + * snmp/mib2.c added + * snmp/msg_{in,out}.c added + * include/lwip/snmp_asn1.h added + * include/lwip/snmp_msg.h added + * doc/snmp_agent.txt added + + 2006-03-29 Christiaan Simons + * inet.c, inet.h: Added platform byteswap support. + Added LWIP_PLATFORM_BYTESWAP define (defaults to 0) and + optional LWIP_PLATFORM_HTONS(), LWIP_PLATFORM_HTONL() macros. + + ++ Bug fixes: + + 2006-11-30 Christiaan Simons + * dhcp.c: Fixed false triggers of request_timeout. + + 2006-11-28 Christiaan Simons + * netif.c: In netif_add() fixed missing clear of ip_addr, netmask, gw and flags. + + 2006-10-11 Christiaan Simons + * api_lib.c etharp.c, ip.c, memp.c, stats.c, sys.{c,h} tcp.h: + Partially accepted patch #5449 for ANSI C compatibility / build fixes. + * ipv4/lwip/ip.h ipv6/lwip/ip.h: Corrected UDP-Lite protocol + identifier from 170 to 136 (bug #17574). + + 2006-10-10 Christiaan Simons + * api_msg.c: Fixed Nagle algorithm as reported by Bob Grice. + + 2006-08-17 Christiaan Simons + * udp.c: Fixed bug #17200, added check for broadcast + destinations for PCBs bound to a unicast address. + + 2006-08-07 Christiaan Simons + * api_msg.c: Flushing TCP output in do_close() (bug #15926). + + 2006-06-27 Christiaan Simons + * api_msg.c: Applied patch for cold case (bug #11135). + In accept_function() ensure newconn->callback is always initialized. + + 2006-06-15 Christiaan Simons + * mem.h: added MEM_SIZE_F alias to fix an ancient cold case (bug #1748), + facilitate printing of mem_size_t and u16_t statistics. + + 2006-06-14 Christiaan Simons + * api_msg.c: Applied patch #5146 to handle allocation failures + in accept() by Kevin Lawson. + + 2006-05-26 Christiaan Simons + * api_lib.c: Removed conn->sem creation and destruction + from netconn_write() and added sys_sem_new to netconn_new_*. + +(STABLE-1_1_1) + + 2006-03-03 Christiaan Simons + * ipv4/ip_frag.c: Added bound-checking assertions on ip_reassbitmap + access and added pbuf_alloc() return value checks. + + 2006-01-01 Leon Woestenberg + * tcp_{in,out}.c, tcp_out.c: Removed 'even sndbuf' fix in TCP, which is + now handled by the checksum routine properly. + + 2006-02-27 Leon Woestenberg + * pbuf.c: Fix alignment; pbuf_init() would not work unless + pbuf_pool_memory[] was properly aligned. (Patch by Curt McDowell.) + + 2005-12-20 Leon Woestenberg + * tcp.c: Remove PCBs which stay in LAST_ACK state too long. Patch + submitted by Mitrani Hiroshi. + + 2005-12-15 Christiaan Simons + * inet.c: Disabled the added summing routine to preserve code space. + + 2005-12-14 Leon Woestenberg + * tcp_in.c: Duplicate FIN ACK race condition fix by Kelvin Lawson. + Added Curt McDowell's optimized checksumming routine for future + inclusion. Need to create test case for unaliged, aligned, odd, + even length combination of cases on various endianess machines. + + 2005-12-09 Christiaan Simons + * inet.c: Rewrote standard checksum routine in proper portable C. + + 2005-11-25 Christiaan Simons + * udp.c tcp.c: Removed SO_REUSE hack. Should reside in socket code only. + * *.c: introduced cc.h LWIP_DEBUG formatters matching the u16_t, s16_t, + u32_t, s32_t typedefs. This solves most debug word-length assumes. + + 2005-07-17 Leon Woestenberg + * inet.c: Fixed unaligned 16-bit access in the standard checksum + routine by Peter Jolasson. + * slipif.c: Fixed implementation assumption of single-pbuf datagrams. + + 2005-02-04 Leon Woestenberg + * tcp_out.c: Fixed uninitialized 'queue' referenced in memerr branch. + * tcp_{out|in}.c: Applied patch fixing unaligned access. + + 2005-01-04 Leon Woestenberg + * pbuf.c: Fixed missing semicolon after LWIP_DEBUG statement. + + 2005-01-03 Leon Woestenberg + * udp.c: UDP pcb->recv() was called even when it was NULL. + +(STABLE-1_1_0) + + 2004-12-28 Leon Woestenberg + * etharp.*: Disabled multiple packets on the ARP queue. + This clashes with TCP queueing. + + 2004-11-28 Leon Woestenberg + * etharp.*: Fixed race condition from ARP request to ARP timeout. + Halved the ARP period, doubled the period counts. + ETHARP_MAX_PENDING now should be at least 2. This prevents + the counter from reaching 0 right away (which would allow + too little time for ARP responses to be received). + + 2004-11-25 Leon Woestenberg + * dhcp.c: Decline messages were not multicast but unicast. + * etharp.c: ETHARP_CREATE is renamed to ETHARP_TRY_HARD. + Do not try hard to insert arbitrary packet's source address, + etharp_ip_input() now calls etharp_update() without ETHARP_TRY_HARD. + etharp_query() now always DOES call ETHARP_TRY_HARD so that users + querying an address will see it appear in the cache (DHCP could + suffer from this when a server invalidly gave an in-use address.) + * ipv4/ip_addr.h: Renamed ip_addr_maskcmp() to _netcmp() as we are + comparing network addresses (identifiers), not the network masks + themselves. + * ipv4/ip_addr.c: ip_addr_isbroadcast() now checks that the given + IP address actually belongs to the network of the given interface. + + 2004-11-24 Kieran Mansley + * tcp.c: Increment pcb->snd_buf when ACK is received in SYN_SENT state. + +(STABLE-1_1_0-RC1) + + 2004-10-16 Kieran Mansley + * tcp.c: Add code to tcp_recved() to send an ACK (window update) immediately, + even if one is already pending, if the rcv_wnd is above a threshold + (currently TCP_WND/2). This avoids waiting for a timer to expire to send a + delayed ACK in order to open the window if the stack is only receiving data. + + 2004-09-12 Kieran Mansley + * tcp*.*: Retransmit time-out handling improvement by Sam Jansen. + + 2004-08-20 Tony Mountifield + * etharp.c: Make sure the first pbuf queued on an ARP entry + is properly ref counted. + + 2004-07-27 Tony Mountifield + * debug.h: Added (int) cast in LWIP_DEBUGF() to avoid compiler + warnings about comparison. + * pbuf.c: Stopped compiler complaining of empty if statement + when LWIP_DEBUGF() empty. Closed an unclosed comment. + * tcp.c: Stopped compiler complaining of empty if statement + when LWIP_DEBUGF() empty. + * ip.h Corrected IPH_TOS() macro: returns a byte, so doesn't need htons(). + * inet.c: Added a couple of casts to quiet the compiler. + No need to test isascii(c) before isdigit(c) or isxdigit(c). + + 2004-07-22 Tony Mountifield + * inet.c: Made data types consistent in inet_ntoa(). + Added casts for return values of checksum routines, to pacify compiler. + * ip_frag.c, tcp_out.c, sockets.c, pbuf.c + Small corrections to some debugging statements, to pacify compiler. + + 2004-07-21 Tony Mountifield + * etharp.c: Removed spurious semicolon and added missing end-of-comment. + * ethernetif.c Updated low_level_output() to match prototype for + netif->linkoutput and changed low_level_input() similarly for consistency. + * api_msg.c: Changed recv_raw() from int to u8_t, to match prototype + of raw_recv() in raw.h and so avoid compiler error. + * sockets.c: Added trivial (int) cast to keep compiler happier. + * ip.c, netif.c Changed debug statements to use the tidier ip4_addrN() macros. + +(STABLE-1_0_0) + + ++ Changes: + + 2004-07-05 Leon Woestenberg + * sockets.*: Restructured LWIP_PRIVATE_TIMEVAL. Make sure + your cc.h file defines this either 1 or 0. If non-defined, + defaults to 1. + * .c: Added and includes where used. + * etharp.c: Made some array indices unsigned. + + 2004-06-27 Leon Woestenberg + * netif.*: Added netif_set_up()/down(). + * dhcp.c: Changes to restart program flow. + + 2004-05-07 Leon Woestenberg + * etharp.c: In find_entry(), instead of a list traversal per candidate, do a + single-pass lookup for different candidates. Should exploit locality. + + 2004-04-29 Leon Woestenberg + * tcp*.c: Cleaned up source comment documentation for Doxygen processing. + * opt.h: ETHARP_ALWAYS_INSERT option removed to comply with ARP RFC. + * etharp.c: update_arp_entry() only adds new ARP entries when adviced to by + the caller. This deprecates the ETHARP_ALWAYS_INSERT overrule option. + + ++ Bug fixes: + + 2004-04-27 Leon Woestenberg + * etharp.c: Applied patch of bug #8708 by Toni Mountifield with a solution + suggested by Timmy Brolin. Fix for 32-bit processors that cannot access + non-aligned 32-bit words, such as soms 32-bit TCP/IP header fields. Fix + is to prefix the 14-bit Ethernet headers with two padding bytes. + + 2004-04-23 Leon Woestenberg + * ip_addr.c: Fix in the ip_addr_isbroadcast() check. + * etharp.c: Fixed the case where the packet that initiates the ARP request + is not queued, and gets lost. Fixed the case where the packets destination + address is already known; we now always queue the packet and perform an ARP + request. + +(STABLE-0_7_0) + + ++ Bug fixes: + + * Fixed TCP bug for SYN_SENT to ESTABLISHED state transition. + * Fixed TCP bug in dequeueing of FIN from out of order segment queue. + * Fixed two possible NULL references in rare cases. + +(STABLE-0_6_6) + + ++ Bug fixes: + + * Fixed DHCP which did not include the IP address in DECLINE messages. + + ++ Changes: + + * etharp.c has been hauled over a bit. + +(STABLE-0_6_5) + + ++ Bug fixes: + + * Fixed TCP bug induced by bad window resizing with unidirectional TCP traffic. + * Packets sent from ARP queue had invalid source hardware address. + + ++ Changes: + + * Pass-by ARP requests do now update the cache. + + ++ New features: + + * No longer dependent on ctype.h. + * New socket options. + * Raw IP pcb support. + +(STABLE-0_6_4) + + ++ Bug fixes: + + * Some debug formatters and casts fixed. + * Numereous fixes in PPP. + + ++ Changes: + + * DEBUGF now is LWIP_DEBUGF + * pbuf_dechain() has been re-enabled. + * Mentioned the changed use of CVS branches in README. + +(STABLE-0_6_3) + + ++ Bug fixes: + + * Fixed pool pbuf memory leak in pbuf_alloc(). + Occured if not enough PBUF_POOL pbufs for a packet pbuf chain. + Reported by Savin Zlobec. + + * PBUF_POOL chains had their tot_len field not set for non-first + pbufs. Fixed in pbuf_alloc(). + + ++ New features: + + * Added PPP stack contributed by Marc Boucher + + ++ Changes: + + * Now drops short packets for ICMP/UDP/TCP protocols. More robust. + + * ARP queueuing now queues the latest packet instead of the first. + This is the RFC recommended behaviour, but can be overridden in + lwipopts.h. + +(0.6.2) + + ++ Bugfixes: + + * TCP has been fixed to deal with the new use of the pbuf->ref + counter. + + * DHCP dhcp_inform() crash bug fixed. + + ++ Changes: + + * Removed pbuf_pool_free_cache and pbuf_pool_alloc_cache. Also removed + pbuf_refresh(). This has sped up pbuf pool operations considerably. + Implemented by David Haas. + +(0.6.1) + + ++ New features: + + * The packet buffer implementation has been enhanced to support + zero-copy and copy-on-demand for packet buffers which have their + payloads in application-managed memory. + Implemented by David Haas. + + Use PBUF_REF to make a pbuf refer to RAM. lwIP will use zero-copy + if an outgoing packet can be directly sent on the link, or perform + a copy-on-demand when necessary. + + The application can safely assume the packet is sent, and the RAM + is available to the application directly after calling udp_send() + or similar function. + + ++ Bugfixes: + + * ARP_QUEUEING should now correctly work for all cases, including + PBUF_REF. + Implemented by Leon Woestenberg. + + ++ Changes: + + * IP_ADDR_ANY is no longer a NULL pointer. Instead, it is a pointer + to a '0.0.0.0' IP address. + + * The packet buffer implementation is changed. The pbuf->ref counter + meaning has changed, and several pbuf functions have been + adapted accordingly. + + * netif drivers have to be changed to set the hardware address length field + that must be initialized correctly by the driver (hint: 6 for Ethernet MAC). + See the contrib/ports/c16x cs8900 driver as a driver example. + + * netif's have a dhcp field that must be initialized to NULL by the driver. + See the contrib/ports/c16x cs8900 driver as a driver example. + +(0.5.x) This file has been unmaintained up to 0.6.1. All changes are + logged in CVS but have not been explained here. + +(0.5.3) Changes since version 0.5.2 + + ++ Bugfixes: + + * memp_malloc(MEMP_API_MSG) could fail with multiple application + threads because it wasn't protected by semaphores. + + ++ Other changes: + + * struct ip_addr now packed. + + * The name of the time variable in arp.c has been changed to ctime + to avoid conflicts with the time() function. + +(0.5.2) Changes since version 0.5.1 + + ++ New features: + + * A new TCP function, tcp_tmr(), now handles both TCP timers. + + ++ Bugfixes: + + * A bug in tcp_parseopt() could cause the stack to hang because of a + malformed TCP option. + + * The address of new connections in the accept() function in the BSD + socket library was not handled correctly. + + * pbuf_dechain() did not update the ->tot_len field of the tail. + + * Aborted TCP connections were not handled correctly in all + situations. + + ++ Other changes: + + * All protocol header structs are now packed. + + * The ->len field in the tcp_seg structure now counts the actual + amount of data, and does not add one for SYN and FIN segments. + +(0.5.1) Changes since version 0.5.0 + + ++ New features: + + * Possible to run as a user process under Linux. + + * Preliminary support for cross platform packed structs. + + * ARP timer now implemented. + + ++ Bugfixes: + + * TCP output queue length was badly initialized when opening + connections. + + * TCP delayed ACKs were not sent correctly. + + * Explicit initialization of BSS segment variables. + + * read() in BSD socket library could drop data. + + * Problems with memory alignment. + + * Situations when all TCP buffers were used could lead to + starvation. + + * TCP MSS option wasn't parsed correctly. + + * Problems with UDP checksum calculation. + + * IP multicast address tests had endianess problems. + + * ARP requests had wrong destination hardware address. + + ++ Other changes: + + * struct eth_addr changed from u16_t[3] array to u8_t[6]. + + * A ->linkoutput() member was added to struct netif. + + * TCP and UDP ->dest_* struct members where changed to ->remote_*. + + * ntoh* macros are now null definitions for big endian CPUs. + +(0.5.0) Changes since version 0.4.2 + + ++ New features: + + * Redesigned operating system emulation layer to make porting easier. + + * Better control over TCP output buffers. + + * Documenation added. + + ++ Bugfixes: + + * Locking issues in buffer management. + + * Bugfixes in the sequential API. + + * IP forwarding could cause memory leakage. This has been fixed. + + ++ Other changes: + + * Directory structure somewhat changed; the core/ tree has been + collapsed. + +(0.4.2) Changes since version 0.4.1 + + ++ New features: + + * Experimental ARP implementation added. + + * Skeleton Ethernet driver added. + + * Experimental BSD socket API library added. + + ++ Bugfixes: + + * In very intense situations, memory leakage could occur. This has + been fixed. + + ++ Other changes: + + * Variables named "data" and "code" have been renamed in order to + avoid name conflicts in certain compilers. + + * Variable++ have in appliciable cases been translated to ++variable + since some compilers generate better code in the latter case. + +(0.4.1) Changes since version 0.4 + + ++ New features: + + * TCP: Connection attempts time out earlier than data + transmissions. Nagle algorithm implemented. Push flag set on the + last segment in a burst. + + * UDP: experimental support for UDP-Lite extensions. + + ++ Bugfixes: + + * TCP: out of order segments were in some cases handled incorrectly, + and this has now been fixed. Delayed acknowledgements was broken + in 0.4, has now been fixed. Binding to an address that is in use + now results in an error. Reset connections sometimes hung an + application; this has been fixed. + + * Checksum calculation sometimes failed for chained pbufs with odd + lengths. This has been fixed. + + * API: a lot of bug fixes in the API. The UDP API has been improved + and tested. Error reporting and handling has been + improved. Logical flaws and race conditions for incoming TCP + connections has been found and removed. + + * Memory manager: alignment issues. Reallocating memory sometimes + failed, this has been fixed. + + * Generic library: bcopy was flawed and has been fixed. + + ++ Other changes: + + * API: all datatypes has been changed from generic ones such as + ints, to specified ones such as u16_t. Functions that return + errors now have the correct type (err_t). + + * General: A lot of code cleaned up and debugging code removed. Many + portability issues have been fixed. + + * The license was changed; the advertising clause was removed. + + * C64 port added. + + * Thanks: Huge thanks go to Dagan Galarneau, Horst Garnetzke, Petri + Kosunen, Mikael Caleres, and Frits Wilmink for reporting and + fixing bugs! + +(0.4) Changes since version 0.3.1 + + * Memory management has been radically changed; instead of + allocating memory from a shared heap, memory for objects that are + rapidly allocated and deallocated is now kept in pools. Allocation + and deallocation from those memory pools is very fast. The shared + heap is still present but is used less frequently. + + * The memory, memory pool, and packet buffer subsystems now support + 4-, 2-, or 1-byte alignment. + + * "Out of memory" situations are handled in a more robust way. + + * Stack usage has been reduced. + + * Easier configuration of lwIP parameters such as memory usage, + TTLs, statistics gathering, etc. All configuration parameters are + now kept in a single header file "lwipopts.h". + + * The directory structure has been changed slightly so that all + architecture specific files are kept under the src/arch + hierarchy. + + * Error propagation has been improved, both in the protocol modules + and in the API. + + * The code for the RTXC architecture has been implemented, tested + and put to use. + + * Bugs have been found and corrected in the TCP, UDP, IP, API, and + the Internet checksum modules. + + * Bugs related to porting between a 32-bit and a 16-bit architecture + have been found and corrected. + + * The license has been changed slightly to conform more with the + original BSD license, including the advertisement clause. + +(0.3.1) Changes since version 0.3 + + * Fix of a fatal bug in the buffer management. Pbufs with allocated + RAM never returned the RAM when the pbuf was deallocated. + + * TCP congestion control, window updates and retransmissions did not + work correctly. This has now been fixed. + + * Bugfixes in the API. + +(0.3) Changes since version 0.2 + + * New and improved directory structure. All include files are now + kept in a dedicated include/ directory. + + * The API now has proper error handling. A new function, + netconn_err(), now returns an error code for the connection in + case of errors. + + * Improvements in the memory management subsystem. The system now + keeps a pointer to the lowest free memory block. A new function, + mem_malloc2() tries to allocate memory once, and if it fails tries + to free some memory and retry the allocation. + + * Much testing has been done with limited memory + configurations. lwIP now does a better job when overloaded. + + * Some bugfixes and improvements to the buffer (pbuf) subsystem. + + * Many bugfixes in the TCP code: + + - Fixed a bug in tcp_close(). + + - The TCP receive window was incorrectly closed when out of + sequence segments was received. This has been fixed. + + - Connections are now timed-out of the FIN-WAIT-2 state. + + - The initial congestion window could in some cases be too + large. This has been fixed. + + - The retransmission queue could in some cases be screwed up. This + has been fixed. + + - TCP RST flag now handled correctly. + + - Out of sequence data was in some cases never delivered to the + application. This has been fixed. + + - Retransmitted segments now contain the correct acknowledgment + number and advertised window. + + - TCP retransmission timeout backoffs are not correctly computed + (ala BSD). After a number of retransmissions, TCP now gives up + the connection. + + * TCP connections now are kept on three lists, one for active + connections, one for listening connections, and one for + connections that are in TIME-WAIT. This greatly speeds up the fast + timeout processing for sending delayed ACKs. + + * TCP now provides proper feedback to the application when a + connection has been successfully set up. + + * More comments have been added to the code. The code has also been + somewhat cleaned up. + +(0.2) Initial public release. diff --git a/src/lwip-1.4.1/COPYING b/src/lwip-1.4.1/COPYING new file mode 100644 index 0000000..e23898b --- /dev/null +++ b/src/lwip-1.4.1/COPYING @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2001, 2002 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + + diff --git a/src/lwip-1.4.1/FILES b/src/lwip-1.4.1/FILES new file mode 100644 index 0000000..6625319 --- /dev/null +++ b/src/lwip-1.4.1/FILES @@ -0,0 +1,4 @@ +src/ - The source code for the lwIP TCP/IP stack. +doc/ - The documentation for lwIP. + +See also the FILES file in each subdirectory. diff --git a/src/lwip-1.4.1/README b/src/lwip-1.4.1/README new file mode 100644 index 0000000..a62cc4f --- /dev/null +++ b/src/lwip-1.4.1/README @@ -0,0 +1,89 @@ +INTRODUCTION + +lwIP is a small independent implementation of the TCP/IP protocol +suite that has been developed by Adam Dunkels at the Computer and +Networks Architectures (CNA) lab at the Swedish Institute of Computer +Science (SICS). + +The focus of the lwIP TCP/IP implementation is to reduce the RAM usage +while still having a full scale TCP. This making lwIP suitable for use +in embedded systems with tens of kilobytes of free RAM and room for +around 40 kilobytes of code ROM. + +FEATURES + + * IP (Internet Protocol) including packet forwarding over multiple network + interfaces + * ICMP (Internet Control Message Protocol) for network maintenance and debugging + * IGMP (Internet Group Management Protocol) for multicast traffic management + * UDP (User Datagram Protocol) including experimental UDP-lite extensions + * TCP (Transmission Control Protocol) with congestion control, RTT estimation + and fast recovery/fast retransmit + * Specialized raw/native API for enhanced performance + * Optional Berkeley-like socket API + * DNS (Domain names resolver) + * SNMP (Simple Network Management Protocol) + * DHCP (Dynamic Host Configuration Protocol) + * AUTOIP (for IPv4, conform with RFC 3927) + * PPP (Point-to-Point Protocol) + * ARP (Address Resolution Protocol) for Ethernet + +LICENSE + +lwIP is freely available under a BSD license. + +DEVELOPMENT + +lwIP has grown into an excellent TCP/IP stack for embedded devices, +and developers using the stack often submit bug fixes, improvements, +and additions to the stack to further increase its usefulness. + +Development of lwIP is hosted on Savannah, a central point for +software development, maintenance and distribution. Everyone can +help improve lwIP by use of Savannah's interface, CVS and the +mailing list. A core team of developers will commit changes to the +CVS source tree. + +The lwIP TCP/IP stack is maintained in the 'lwip' CVS module and +contributions (such as platform ports) are in the 'contrib' module. + +See doc/savannah.txt for details on CVS server access for users and +developers. + +Last night's CVS tar ball can be downloaded from: + http://savannah.gnu.org/cvs.backups/lwip.tar.gz [CHANGED - NEEDS FIXING] + +The current CVS trees are web-browsable: + http://savannah.nongnu.org/cgi-bin/viewcvs/lwip/lwip/ + http://savannah.nongnu.org/cgi-bin/viewcvs/lwip/contrib/ + +Submit patches and bugs via the lwIP project page: + http://savannah.nongnu.org/projects/lwip/ + + +DOCUMENTATION + +The original out-dated homepage of lwIP and Adam Dunkels' papers on +lwIP are at the official lwIP home page: + http://www.sics.se/~adam/lwip/ + +Self documentation of the source code is regularly extracted from the +current CVS sources and is available from this web page: + http://www.nongnu.org/lwip/ + +There is now a constantly growin wiki about lwIP at + http://lwip.wikia.com/wiki/LwIP_Wiki + +Also, there are mailing lists you can subscribe at + http://savannah.nongnu.org/mail/?group=lwip +plus searchable archives: + http://lists.nongnu.org/archive/html/lwip-users/ + http://lists.nongnu.org/archive/html/lwip-devel/ + +Reading Adam's papers, the files in docs/, browsing the source code +documentation and browsing the mailing list archives is a good way to +become familiar with the design of lwIP. + +Adam Dunkels +Leon Woestenberg + diff --git a/src/lwip-1.4.1/UPGRADING b/src/lwip-1.4.1/UPGRADING new file mode 100644 index 0000000..6501107 --- /dev/null +++ b/src/lwip-1.4.1/UPGRADING @@ -0,0 +1,144 @@ +This file lists major changes between release versions that require +ports or applications to be changed. Use it to update a port or an +application written for an older version of lwIP to correctly work +with newer versions. + + +(CVS HEAD) + + * [Enter new changes just after this line - do not remove this line] + + ++ Application changes: + + * Replaced struct ip_addr by typedef ip_addr_t (struct ip_addr is kept for + compatibility to old applications, but will be removed in the future). + + * Renamed mem_realloc() to mem_trim() to prevent confusion with realloc() + + +++ Raw API: + * Changed the semantics of tcp_close() (since it was rather a + shutdown before): Now the application does *NOT* get any calls to the recv + callback (aside from NULL/closed) after calling tcp_close() + + * When calling tcp_abort() from a raw API TCP callback function, + make sure you return ERR_ABRT to prevent accessing unallocated memory. + (ERR_ABRT now means the applicaiton has called tcp_abort!) + + +++ Netconn API: + * Changed netconn_receive() and netconn_accept() to return + err_t, not a pointer to new data/netconn. + + +++ Socket API: + * LWIP_SO_RCVTIMEO: when accept() or recv() time out, they + now set errno to EWOULDBLOCK/EAGAIN, not ETIMEDOUT. + + * Added a minimal version of posix fctl() to have a + standardised way to set O_NONBLOCK for nonblocking sockets. + + +++ all APIs: + * correctly implemented SO(F)_REUSEADDR + + ++ Port changes + + +++ new files: + + * Added 4 new files: def.c, timers.c, timers.h, tcp_impl.h: + + * Moved stack-internal parts of tcp.h to tcp_impl.h, tcp.h now only contains + the actual application programmer's API + + * Separated timer implementation from sys.h/.c, moved to timers.h/.c; + Added timer implementation for NO_SYS==1, set NO_SYS_NO_TIMERS==1 if you + still want to use your own timer implementation for NO_SYS==0 (as before). + + +++ sys layer: + + * Converted mbox- and semaphore-functions to take pointers to sys_mbox_t/ + sys_sem_t; + + * Converted sys_mbox_new/sys_sem_new to take pointers and return err_t; + + * Added Mutex concept in sys_arch (define LWIP_COMPAT_MUTEX to let sys.h use + binary semaphores instead of mutexes - as before) + + +++ new options: + + * Don't waste memory when chaining segments, added option TCP_OVERSIZE to + prevent creating many small pbufs when calling tcp_write with many small + blocks of data. Instead, pbufs are allocated larger than needed and the + space is used for later calls to tcp_write. + + * Added LWIP_NETIF_TX_SINGLE_PBUF to always copy to try to create single pbufs + in tcp_write/udp_send. + + * Added an additional option LWIP_ETHERNET to support ethernet without ARP + (necessary for pure PPPoE) + + * Add MEMP_SEPARATE_POOLS to place memory pools in separate arrays. This may + be used to place these pools into user-defined memory by using external + declaration. + + * Added TCP_SNDQUEUELOWAT corresponding to TCP_SNDLOWAT + + +++ new pools: + + * Netdb uses a memp pool for allocating memory when getaddrinfo() is called, + so MEMP_NUM_NETDB has to be set accordingly. + + * DNS_LOCAL_HOSTLIST_IS_DYNAMIC uses a memp pool instead of the heap, so + MEMP_NUM_LOCALHOSTLIST has to be set accordingly. + + * Snmp-agent uses a memp pools instead of the heap, so MEMP_NUM_SNMP_* have + to be set accordingly. + + * PPPoE uses a MEMP pool instead of the heap, so MEMP_NUM_PPPOE_INTERFACES + has to be set accordingly + + * Integrated loopif into netif.c - loopif does not have to be created by the + port any more, just define LWIP_HAVE_LOOPIF to 1. + + * Added define LWIP_RAND() for lwip-wide randomization (needs to be defined + in cc.h, e.g. used by igmp) + + * Added printf-formatter X8_F to printf u8_t as hex + + * The heap now may be moved to user-defined memory by defining + LWIP_RAM_HEAP_POINTER as a void pointer to that memory's address + + * added autoip_set_struct() and dhcp_set_struct() to let autoip and dhcp work + with user-allocated structs instead of calling mem_malloc + + * Added const char* name to mem- and memp-stats for easier debugging. + + * Calculate the TCP/UDP checksum while copying to only fetch data once: + Define LWIP_CHKSUM_COPY to a memcpy-like function that returns the checksum + + * Added SO_REUSE_RXTOALL to pass received UDP broadcast/multicast packets to + more than one pcb. + + * Changed the semantics of ARP_QUEUEING==0: ARP_QUEUEING now cannot be turned + off any more, if this is set to 0, only one packet (the most recent one) is + queued (like demanded by RFC 1122). + + + ++ Major bugfixes/improvements + + * Implemented tcp_shutdown() to only shut down one end of a connection + * Implemented shutdown() at socket- and netconn-level + * Added errorset support to select() + improved select speed overhead + * Merged pppd to v2.3.11 (including some backported bugfixes from 2.4.x) + * Added timer implementation for NO_SYS==1 (may be disabled with NO_SYS_NO_TIMERS==1 + * Use macros defined in ip_addr.h to work with IP addresses + * Implemented many nonblocking socket/netconn functions + * Fixed ARP input processing: only add a new entry if a request was directed as us + * mem_realloc() to mem_trim() to prevent confusion with realloc() + * Some improvements for AutoIP (don't route/forward link-local addresses, don't break + existing connections when assigning a routable address) + * Correctly handle remote side overrunning our rcv_wnd in ooseq case + * Removed packing from ip_addr_t, the packed version is now only used in protocol headers + * Corrected PBUF_POOL_BUFSIZE for ports where ETH_PAD_SIZE > 0 + * Added support for static ARP table entries + +(STABLE-1.3.2) + + * initial version of this file diff --git a/src/lwip-1.4.1/apps/chargen/README b/src/lwip-1.4.1/apps/chargen/README new file mode 100644 index 0000000..7dc2ee5 --- /dev/null +++ b/src/lwip-1.4.1/apps/chargen/README @@ -0,0 +1,52 @@ + + CHARGEN + +This file implements a nice example of handling multiple tcp sockets in a +server environment. Just call chargen_init() from your application after +you have initialized lwip and added your network interfaces. Change the +MAX_SERV option to increase or decrease the number of sessions supported. + +chargen will jam as much data as possible into the output socket, so it +will take up a lot of CPU time. Therefore it will be a good idea to run it +as the lowest possible priority (just ahead of any idle task). + +This is also a good example of how to support multiple sessions in an +embedded system where you might not have fork(). The multiple sessions are +all handled by the same thread and select() is used for demultiplexing. + +No makefile is provided, just add chargen to the makefile for your +application. It is OS and HW independent. + +Once the chargen server is running in your application, go to another system +and open a telnet session to your lwip platform at port 19. You should see an +ASCII pattern start to stream on you screen. + +As an example, lets say that your system running lwip is at IP address +192.168.10.244 and you have a linux system connected to it at IP address +192.168.10.59. Issue the following command at a terminal prompt on the linux system: + +telnet 192.168.10.244 19 + +You will see a pattern similar to the following on streaming by on your +screen: + +ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{ +BCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{| +CDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|} +DEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ +EFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~! +FGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~!" +GHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~!"# +HIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~!"#$ +IJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~!"#$% +JKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~!"#$%& +KLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~!"#$%&' +LMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~!"#$%&'( + +It even works from windows: At a dos prompt you can also issue the same +telnet command and you will get a similar (but much slower, at least on W98) +data stream. + +David Haas + + diff --git a/src/lwip-1.4.1/apps/chargen/chargen.c b/src/lwip-1.4.1/apps/chargen/chargen.c new file mode 100644 index 0000000..c6ea83e --- /dev/null +++ b/src/lwip-1.4.1/apps/chargen/chargen.c @@ -0,0 +1,269 @@ +/** @file + * + * chargen server for lwip + */ +/* + * Copyright (c) 2003 NBS Card Technology, Paramus, NJ. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: David Haas + * + * Purpose: chargen server for testing and demonstration purposes + * + * This file implements a nice example of handling multiple tcp sockets in a + * server environment. Just call chargen_init() from your application after + * you have initialized lwip and added your network interfaces. Change the + * MAX_SERV option to increase or decrease the number of sessions supported. + * + * chargen will jam as much data as possible into the output socket, so it + * will take up a lot of CPU time. Therefore it will be a good idea to run it + * as the lowest possible priority (just ahead of any idle task). + * + * This is also a good example of how to support multiple sessions in an + * embedded system where you might not have fork(). + */ + +#include "lwip/opt.h" +#include "lwip/sys.h" +#include "lwip/sockets.h" +#include "lwip/mem.h" + +#include + +#include "chargen.h" + +#if LWIP_SOCKET + +#define MAX_SERV 5 /* Maximum number of chargen services. Don't need too many */ +#define CHARGEN_THREAD_NAME "chargen" +#define CHARGEN_PRIORITY 254 /* Really low priority */ +#define CHARGEN_THREAD_STACKSIZE 0 +#define SEND_SIZE TCP_SNDLOWAT /* If we only send this much, then when select + says we can send, we know we won't block */ +struct charcb +{ + struct charcb *next; + int socket; + struct sockaddr_in cliaddr; + socklen_t clilen; + char nextchar; +}; + +static struct charcb *charcb_list = 0; +static int do_read(struct charcb *p_charcb); +static void close_chargen(struct charcb *p_charcb); + +/************************************************************** + * void chargen_thread(void *arg) + * + * chargen task. This server will wait for connections on well + * known TCP port number: 19. For every connection, the server will + * write as much data as possible to the tcp port. + **************************************************************/ +static void chargen_thread(void *arg) +{ + int listenfd; + struct sockaddr_in chargen_saddr; + fd_set readset; + fd_set writeset; + int i, maxfdp1; + struct charcb *p_charcb; + LWIP_UNUSED_ARG(arg); + + /* First acquire our socket for listening for connections */ + listenfd = socket(AF_INET, SOCK_STREAM, 0); + + LWIP_ASSERT("chargen_thread(): Socket create failed.", listenfd >= 0); + memset(&chargen_saddr, 0, sizeof(chargen_saddr)); + chargen_saddr.sin_family = AF_INET; + chargen_saddr.sin_addr.s_addr = PP_HTONL(INADDR_ANY); + chargen_saddr.sin_port = htons(19); /* Chargen server port */ + + if (bind(listenfd, (struct sockaddr *) &chargen_saddr, sizeof(chargen_saddr)) == -1) + LWIP_ASSERT("chargen_thread(): Socket bind failed.", 0); + + /* Put socket into listening mode */ + if (listen(listenfd, MAX_SERV) == -1) + LWIP_ASSERT("chargen_thread(): Listen failed.", 0); + + + /* Wait forever for network input: This could be connections or data */ + for (;;) + { + maxfdp1 = listenfd+1; + + /* Determine what sockets need to be in readset */ + FD_ZERO(&readset); + FD_ZERO(&writeset); + FD_SET(listenfd, &readset); + for (p_charcb = charcb_list; p_charcb; p_charcb = p_charcb->next) + { + if (maxfdp1 < p_charcb->socket + 1) + maxfdp1 = p_charcb->socket + 1; + FD_SET(p_charcb->socket, &readset); + FD_SET(p_charcb->socket, &writeset); + } + + /* Wait for data or a new connection */ + i = select(maxfdp1, &readset, &writeset, 0, 0); + + if (i == 0) + continue; + /* At least one descriptor is ready */ + if (FD_ISSET(listenfd, &readset)) + { + /* We have a new connection request!!! */ + /* Lets create a new control block */ + p_charcb = (struct charcb *)mem_malloc(sizeof(struct charcb)); + if (p_charcb) + { + p_charcb->socket = accept(listenfd, + (struct sockaddr *) &p_charcb->cliaddr, + &p_charcb->clilen); + if (p_charcb->socket < 0) + mem_free(p_charcb); + else + { + /* Keep this tecb in our list */ + p_charcb->next = charcb_list; + charcb_list = p_charcb; + p_charcb->nextchar = 0x21; + } + } else { + /* No memory to accept connection. Just accept and then close */ + int sock; + struct sockaddr cliaddr; + socklen_t clilen; + + sock = accept(listenfd, &cliaddr, &clilen); + if (sock >= 0) + close(sock); + } + } + /* Go through list of connected clients and process data */ + for (p_charcb = charcb_list; p_charcb; p_charcb = p_charcb->next) + { + if (FD_ISSET(p_charcb->socket, &readset)) + { + /* This socket is ready for reading. This could be because someone typed + * some characters or it could be because the socket is now closed. Try reading + * some data to see. */ + if (do_read(p_charcb) < 0) + break; + } + if (FD_ISSET(p_charcb->socket, &writeset)) + { + char line[80]; + char setchar = p_charcb->nextchar; + + for( i = 0; i < 59; i++) + { + line[i] = setchar; + if (++setchar == 0x7f) + setchar = 0x21; + } + line[i] = 0; + strcat(line, "\n\r"); + if (write(p_charcb->socket, line, strlen(line)) < 0) + { + close_chargen(p_charcb); + break; + } + if (++p_charcb->nextchar == 0x7f) + p_charcb->nextchar = 0x21; + } + + } + } + + +} + +/************************************************************** + * void close_chargen(struct charcb *p_charcb) + * + * Close the socket and remove this charcb from the list. + **************************************************************/ +static void close_chargen(struct charcb *p_charcb) +{ + struct charcb *p_search_charcb; + + /* Either an error or tcp connection closed on other + * end. Close here */ + close(p_charcb->socket); + /* Free charcb */ + if (charcb_list == p_charcb) + charcb_list = p_charcb->next; + else + for (p_search_charcb = charcb_list; p_search_charcb; p_search_charcb = p_search_charcb->next) + { + if (p_search_charcb->next == p_charcb) + { + p_search_charcb->next = p_charcb->next; + break; + } + } + mem_free(p_charcb); +} + + +/************************************************************** + * void do_read(struct charcb *p_charcb) + * + * Socket definitely is ready for reading. Read a buffer from the socket and + * discard the data. If no data is read, then the socket is closed and the + * charcb is removed from the list and freed. + **************************************************************/ +static int do_read(struct charcb *p_charcb) +{ + char buffer[80]; + int readcount; + + /* Read some data */ + readcount = read(p_charcb->socket, &buffer, 80); + if (readcount <= 0) + { + close_chargen(p_charcb); + return -1; + } + return 0; +} + + +/************************************************************** + * void chargen_init(void) + * + * This function initializes the chargen service. This function + * may only be called either before or after tasking has started. + **************************************************************/ +void chargen_init(void) +{ + sys_thread_new( CHARGEN_THREAD_NAME, chargen_thread, 0, CHARGEN_THREAD_STACKSIZE, CHARGEN_PRIORITY); + +} + +#endif /* LWIP_SOCKET */ diff --git a/src/lwip-1.4.1/apps/chargen/chargen.h b/src/lwip-1.4.1/apps/chargen/chargen.h new file mode 100644 index 0000000..8036041 --- /dev/null +++ b/src/lwip-1.4.1/apps/chargen/chargen.h @@ -0,0 +1,13 @@ +#ifndef __CHARGEN_H__ +#define __CHARGEN_H__ + +#include "lwip/opt.h" + +#if LWIP_SOCKET + +void chargen_init(void); + +#endif /* LWIP_SOCKET */ + + +#endif /* __CHARGEN_H__ */ diff --git a/src/lwip-1.4.1/apps/httpserver/README b/src/lwip-1.4.1/apps/httpserver/README new file mode 100644 index 0000000..1f18bb8 --- /dev/null +++ b/src/lwip-1.4.1/apps/httpserver/README @@ -0,0 +1,12 @@ +HTTPSERVER + +This is a demonstration of how to make the most basic kind +of server using lWIP. + +* httpserver-raw.c - uses raw TCP calls (coming soon!) + +* httpserver-netconn.c - uses netconn and netbuf API + +This code updates the examples in Adam Dunkel's original +lwIP documentation to match changes in the code since that +PDF release. diff --git a/src/lwip-1.4.1/apps/httpserver/httpserver-netconn.c b/src/lwip-1.4.1/apps/httpserver/httpserver-netconn.c new file mode 100644 index 0000000..6ffcc5c --- /dev/null +++ b/src/lwip-1.4.1/apps/httpserver/httpserver-netconn.c @@ -0,0 +1,99 @@ + +#include "lwip/opt.h" +#include "lwip/arch.h" +#include "lwip/api.h" + +#include "httpserver-netconn.h" + +#if LWIP_NETCONN + +#ifndef HTTPD_DEBUG +#define HTTPD_DEBUG LWIP_DBG_OFF +#endif + +const static char http_html_hdr[] = "HTTP/1.1 200 OK\r\nContent-type: text/html\r\n\r\n"; +const static char http_index_html[] = "Congrats!

Welcome to our lwIP HTTP server!

This is a small test page, served by httpserver-netconn."; + +/** Serve one HTTP connection accepted in the http thread */ +static void +http_server_netconn_serve(struct netconn *conn) +{ + struct netbuf *inbuf; + char *buf; + u16_t buflen; + err_t err; + + /* Read the data from the port, blocking if nothing yet there. + We assume the request (the part we care about) is in one netbuf */ + err = netconn_recv(conn, &inbuf); + + if (err == ERR_OK) { + netbuf_data(inbuf, (void**)&buf, &buflen); + + /* Is this an HTTP GET command? (only check the first 5 chars, since + there are other formats for GET, and we're keeping it very simple )*/ + if (buflen>=5 && + buf[0]=='G' && + buf[1]=='E' && + buf[2]=='T' && + buf[3]==' ' && + buf[4]=='/' ) { + + /* Send the HTML header + * subtract 1 from the size, since we dont send the \0 in the string + * NETCONN_NOCOPY: our data is const static, so no need to copy it + */ + netconn_write(conn, http_html_hdr, sizeof(http_html_hdr)-1, NETCONN_NOCOPY); + + /* Send our HTML page */ + netconn_write(conn, http_index_html, sizeof(http_index_html)-1, NETCONN_NOCOPY); + } + } + /* Close the connection (server closes in HTTP) */ + netconn_close(conn); + + /* Delete the buffer (netconn_recv gives us ownership, + so we have to make sure to deallocate the buffer) */ + netbuf_delete(inbuf); +} + +/** The main function, never returns! */ +static void +http_server_netconn_thread(void *arg) +{ + struct netconn *conn, *newconn; + err_t err; + LWIP_UNUSED_ARG(arg); + + /* Create a new TCP connection handle */ + conn = netconn_new(NETCONN_TCP); + LWIP_ERROR("http_server: invalid conn", (conn != NULL), return;); + + /* Bind to port 80 (HTTP) with default IP address */ + netconn_bind(conn, NULL, 80); + + /* Put the connection into LISTEN state */ + netconn_listen(conn); + + do { + err = netconn_accept(conn, &newconn); + if (err == ERR_OK) { + http_server_netconn_serve(newconn); + netconn_delete(newconn); + } + } while(err == ERR_OK); + LWIP_DEBUGF(HTTPD_DEBUG, + ("http_server_netconn_thread: netconn_accept received error %d, shutting down", + err)); + netconn_close(conn); + netconn_delete(conn); +} + +/** Initialize the HTTP server (start its thread) */ +void +http_server_netconn_init() +{ + sys_thread_new("http_server_netconn", http_server_netconn_thread, NULL, DEFAULT_THREAD_STACKSIZE, DEFAULT_THREAD_PRIO); +} + +#endif /* LWIP_NETCONN*/ diff --git a/src/lwip-1.4.1/apps/httpserver/httpserver-netconn.h b/src/lwip-1.4.1/apps/httpserver/httpserver-netconn.h new file mode 100644 index 0000000..7b84715 --- /dev/null +++ b/src/lwip-1.4.1/apps/httpserver/httpserver-netconn.h @@ -0,0 +1,6 @@ +#ifndef __HTTPSERVER_NETCONN_H__ +#define __HTTPSERVER_NETCONN_H__ + +void http_server_netconn_init(); + +#endif /* __HTTPSERVER_NETCONN_H__ */ diff --git a/src/lwip-1.4.1/apps/httpserver_raw/fs.c b/src/lwip-1.4.1/apps/httpserver_raw/fs.c new file mode 100644 index 0000000..2cb7575 --- /dev/null +++ b/src/lwip-1.4.1/apps/httpserver_raw/fs.c @@ -0,0 +1,180 @@ +/* + * Copyright (c) 2001-2003 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#include "lwip/opt.h" +#include "lwip/def.h" +#include "fs.h" +#include "fsdata.h" +#include + +/** Set this to 1 to include "fsdata_custom.c" instead of "fsdata.c" for the + * file system (to prevent changing the file included in CVS) */ +#ifndef HTTPD_USE_CUSTOM_FSDATA +#define HTTPD_USE_CUSTOM_FSDATA 0 +#endif + +#if HTTPD_USE_CUSTOM_FSDATA +#include "fsdata_custom.c" +#else /* HTTPD_USE_CUSTOM_FSDATA */ +#include "fsdata.c" +#endif /* HTTPD_USE_CUSTOM_FSDATA */ + +/*-----------------------------------------------------------------------------------*/ + +#if LWIP_HTTPD_CUSTOM_FILES +int fs_open_custom(struct fs_file *file, const char *name); +void fs_close_custom(struct fs_file *file); +#if LWIP_HTTPD_FS_ASYNC_READ +u8_t fs_canread_custom(struct fs_file *file); +u8_t fs_wait_read_custom(struct fs_file *file, fs_wait_cb callback_fn, void *callback_arg); +#endif /* LWIP_HTTPD_FS_ASYNC_READ */ +#endif /* LWIP_HTTPD_CUSTOM_FILES */ + +/*-----------------------------------------------------------------------------------*/ +err_t +fs_open(struct fs_file *file, const char *name) +{ + const struct fsdata_file *f; + + if ((file == NULL) || (name == NULL)) { + return ERR_ARG; + } + +#if LWIP_HTTPD_CUSTOM_FILES + if (fs_open_custom(file, name)) { + file->is_custom_file = 1; + return ERR_OK; + } + file->is_custom_file = 0; +#endif /* LWIP_HTTPD_CUSTOM_FILES */ + + for (f = FS_ROOT; f != NULL; f = f->next) { + if (!strcmp(name, (char *)f->name)) { + file->data = (const char *)f->data; + file->len = f->len; + file->index = f->len; + file->pextension = NULL; + file->http_header_included = f->http_header_included; +#if HTTPD_PRECALCULATED_CHECKSUM + file->chksum_count = f->chksum_count; + file->chksum = f->chksum; +#endif /* HTTPD_PRECALCULATED_CHECKSUM */ +#if LWIP_HTTPD_FILE_STATE + file->state = fs_state_init(file, name); +#endif /* #if LWIP_HTTPD_FILE_STATE */ + return ERR_OK; + } + } + /* file not found */ + return ERR_VAL; +} + +/*-----------------------------------------------------------------------------------*/ +void +fs_close(struct fs_file *file) +{ +#if LWIP_HTTPD_CUSTOM_FILES + if (file->is_custom_file) { + fs_close_custom(file); + } +#endif /* LWIP_HTTPD_CUSTOM_FILES */ +#if LWIP_HTTPD_FILE_STATE + fs_state_free(file, file->state); +#endif /* #if LWIP_HTTPD_FILE_STATE */ + LWIP_UNUSED_ARG(file); +} +/*-----------------------------------------------------------------------------------*/ +#if LWIP_HTTPD_DYNAMIC_FILE_READ +#if LWIP_HTTPD_FS_ASYNC_READ +int +fs_read_async(struct fs_file *file, char *buffer, int count, fs_wait_cb callback_fn, void *callback_arg) +#else /* LWIP_HTTPD_FS_ASYNC_READ */ +int +fs_read(struct fs_file *file, char *buffer, int count) +#endif /* LWIP_HTTPD_FS_ASYNC_READ */ +{ + int read; + + if(file->index == file->len) { + return FS_READ_EOF; + } +#if LWIP_HTTPD_FS_ASYNC_READ +#if LWIP_HTTPD_CUSTOM_FILES + if (!fs_canread_custom(file)) { + if (fs_wait_read_custom(file, callback_fn, callback_arg)) { + return FS_READ_DELAYED; + } + } +#else /* LWIP_HTTPD_CUSTOM_FILES */ + LWIP_UNUSED_ARG(callback_fn); + LWIP_UNUSED_ARG(callback_arg); +#endif /* LWIP_HTTPD_CUSTOM_FILES */ +#endif /* LWIP_HTTPD_FS_ASYNC_READ */ + + read = file->len - file->index; + if(read > count) { + read = count; + } + + MEMCPY(buffer, (file->data + file->index), read); + file->index += read; + + return(read); +} +#endif /* LWIP_HTTPD_DYNAMIC_FILE_READ */ +/*-----------------------------------------------------------------------------------*/ +#if LWIP_HTTPD_FS_ASYNC_READ +int +fs_is_file_ready(struct fs_file *file, fs_wait_cb callback_fn, void *callback_arg) +{ + if (file != NULL) { +#if LWIP_HTTPD_FS_ASYNC_READ +#if LWIP_HTTPD_CUSTOM_FILES + if (!fs_canread_custom(file)) { + if (fs_wait_read_custom(file, callback_fn, callback_arg)) { + return 0; + } + } +#else /* LWIP_HTTPD_CUSTOM_FILES */ + LWIP_UNUSED_ARG(callback_fn); + LWIP_UNUSED_ARG(callback_arg); +#endif /* LWIP_HTTPD_CUSTOM_FILES */ +#endif /* LWIP_HTTPD_FS_ASYNC_READ */ + } + return 1; +} +#endif /* LWIP_HTTPD_FS_ASYNC_READ */ +/*-----------------------------------------------------------------------------------*/ +int +fs_bytes_left(struct fs_file *file) +{ + return file->len - file->index; +} diff --git a/src/lwip-1.4.1/apps/httpserver_raw/fs.h b/src/lwip-1.4.1/apps/httpserver_raw/fs.h new file mode 100644 index 0000000..c021e2f --- /dev/null +++ b/src/lwip-1.4.1/apps/httpserver_raw/fs.h @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2001-2003 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __FS_H__ +#define __FS_H__ + +#include "lwip/opt.h" +#include "lwip/err.h" + +/** Set this to 1 and provide the functions: + * - "int fs_open_custom(struct fs_file *file, const char *name)" + * Called first for every opened file to allow opening files + * that are not included in fsdata(_custom).c + * - "void fs_close_custom(struct fs_file *file)" + * Called to free resources allocated by fs_open_custom(). + */ +#ifndef LWIP_HTTPD_CUSTOM_FILES +#define LWIP_HTTPD_CUSTOM_FILES 0 +#endif + +/** Set this to 1 to support fs_read() to dynamically read file data. + * Without this (default=off), only one-block files are supported, + * and the contents must be ready after fs_open(). + */ +#ifndef LWIP_HTTPD_DYNAMIC_FILE_READ +#define LWIP_HTTPD_DYNAMIC_FILE_READ 0 +#endif + +/** Set this to 1 to include an application state argument per file + * that is opened. This allows to keep a state per connection/file. + */ +#ifndef LWIP_HTTPD_FILE_STATE +#define LWIP_HTTPD_FILE_STATE 0 +#endif + +/** HTTPD_PRECALCULATED_CHECKSUM==1: include precompiled checksums for + * predefined (MSS-sized) chunks of the files to prevent having to calculate + * the checksums at runtime. */ +#ifndef HTTPD_PRECALCULATED_CHECKSUM +#define HTTPD_PRECALCULATED_CHECKSUM 0 +#endif + +/** LWIP_HTTPD_FS_ASYNC_READ==1: support asynchronous read operations + * (fs_read_async returns FS_READ_DELAYED and calls a callback when finished). + */ +#ifndef LWIP_HTTPD_FS_ASYNC_READ +#define LWIP_HTTPD_FS_ASYNC_READ 0 +#endif + +#define FS_READ_EOF -1 +#define FS_READ_DELAYED -2 + +#if HTTPD_PRECALCULATED_CHECKSUM +struct fsdata_chksum { + u32_t offset; + u16_t chksum; + u16_t len; +}; +#endif /* HTTPD_PRECALCULATED_CHECKSUM */ + +struct fs_file { + const char *data; + int len; + int index; + void *pextension; +#if HTTPD_PRECALCULATED_CHECKSUM + const struct fsdata_chksum *chksum; + u16_t chksum_count; +#endif /* HTTPD_PRECALCULATED_CHECKSUM */ + u8_t http_header_included; +#if LWIP_HTTPD_CUSTOM_FILES + u8_t is_custom_file; +#endif /* LWIP_HTTPD_CUSTOM_FILES */ +#if LWIP_HTTPD_FILE_STATE + void *state; +#endif /* LWIP_HTTPD_FILE_STATE */ +}; + +#if LWIP_HTTPD_FS_ASYNC_READ +typedef void (*fs_wait_cb)(void *arg); +#endif /* LWIP_HTTPD_FS_ASYNC_READ */ + +err_t fs_open(struct fs_file *file, const char *name); +void fs_close(struct fs_file *file); +#if LWIP_HTTPD_DYNAMIC_FILE_READ +#if LWIP_HTTPD_FS_ASYNC_READ +int fs_read_async(struct fs_file *file, char *buffer, int count, fs_wait_cb callback_fn, void *callback_arg); +#else /* LWIP_HTTPD_FS_ASYNC_READ */ +int fs_read(struct fs_file *file, char *buffer, int count); +#endif /* LWIP_HTTPD_FS_ASYNC_READ */ +#endif /* LWIP_HTTPD_DYNAMIC_FILE_READ */ +#if LWIP_HTTPD_FS_ASYNC_READ +int fs_is_file_ready(struct fs_file *file, fs_wait_cb callback_fn, void *callback_arg); +#endif /* LWIP_HTTPD_FS_ASYNC_READ */ +int fs_bytes_left(struct fs_file *file); + +#if LWIP_HTTPD_FILE_STATE +/** This user-defined function is called when a file is opened. */ +void *fs_state_init(struct fs_file *file, const char *name); +/** This user-defined function is called when a file is closed. */ +void fs_state_free(struct fs_file *file, void *state); +#endif /* #if LWIP_HTTPD_FILE_STATE */ + +#endif /* __FS_H__ */ diff --git a/src/lwip-1.4.1/apps/httpserver_raw/fs/404.html b/src/lwip-1.4.1/apps/httpserver_raw/fs/404.html new file mode 100644 index 0000000..40b343a --- /dev/null +++ b/src/lwip-1.4.1/apps/httpserver_raw/fs/404.html @@ -0,0 +1,21 @@ + +lwIP - A Lightweight TCP/IP Stack + + + + +
+ SICS logo + +

lwIP - A Lightweight TCP/IP Stack

+

404 - Page not found

+

+ Sorry, the page you are requesting was not found on this + server. +

+
+   +
+ + diff --git a/src/lwip-1.4.1/apps/httpserver_raw/fs/img/sics.gif b/src/lwip-1.4.1/apps/httpserver_raw/fs/img/sics.gif new file mode 100644 index 0000000..0a4fc7b Binary files /dev/null and b/src/lwip-1.4.1/apps/httpserver_raw/fs/img/sics.gif differ diff --git a/src/lwip-1.4.1/apps/httpserver_raw/fs/index.html b/src/lwip-1.4.1/apps/httpserver_raw/fs/index.html new file mode 100644 index 0000000..ab575ef --- /dev/null +++ b/src/lwip-1.4.1/apps/httpserver_raw/fs/index.html @@ -0,0 +1,47 @@ + +lwIP - A Lightweight TCP/IP Stack + + + + +
+ SICS logo + +

lwIP - A Lightweight TCP/IP Stack

+

+ The web page you are watching was served by a simple web + server running on top of the lightweight TCP/IP stack lwIP. +

+

+ lwIP is an open source implementation of the TCP/IP + protocol suite that was originally written by Adam Dunkels + of the Swedish Institute of Computer Science but now is + being actively developed by a team of developers + distributed world-wide. Since it's release, lwIP has + spurred a lot of interest and has been ported to several + platforms and operating systems. lwIP can be used either + with or without an underlying OS. +

+

+ The focus of the lwIP TCP/IP implementation is to reduce + the RAM usage while still having a full scale TCP. This + makes lwIP suitable for use in embedded systems with tens + of kilobytes of free RAM and room for around 40 kilobytes + of code ROM. +

+

+ More information about lwIP can be found at the lwIP + homepage at http://savannah.nongnu.org/projects/lwip/ + or at the lwIP wiki at http://lwip.wikia.com/. +

+
+   +
+ + + diff --git a/src/lwip-1.4.1/apps/httpserver_raw/fsdata.c b/src/lwip-1.4.1/apps/httpserver_raw/fsdata.c new file mode 100644 index 0000000..fe28e31 --- /dev/null +++ b/src/lwip-1.4.1/apps/httpserver_raw/fsdata.c @@ -0,0 +1,2668 @@ +#include "fs.h" +#include "lwip/def.h" +#include "fsdata.h" + + +#define file_NULL (struct fsdata_file *) NULL + + +static const unsigned int dummy_align__img_toaster_svg = 0; +static const unsigned char data__img_toaster_svg[] = { +/* /img/toaster.svg (17 chars) */ +0x2f,0x69,0x6d,0x67,0x2f,0x74,0x6f,0x61,0x73,0x74,0x65,0x72,0x2e,0x73,0x76,0x67, +0x00,0x00,0x00,0x00, + +/* HTTP header */ +/* "HTTP/1.0 200 OK +" (17 bytes) */ +0x48,0x54,0x54,0x50,0x2f,0x31,0x2e,0x30,0x20,0x32,0x30,0x30,0x20,0x4f,0x4b,0x0d, +0x0a, +/* "Server: lwIP/1.3.1 (http://savannah.nongnu.org/projects/lwip) +" (63 bytes) */ +0x53,0x65,0x72,0x76,0x65,0x72,0x3a,0x20,0x6c,0x77,0x49,0x50,0x2f,0x31,0x2e,0x33, +0x2e,0x31,0x20,0x28,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x73,0x61,0x76,0x61,0x6e, +0x6e,0x61,0x68,0x2e,0x6e,0x6f,0x6e,0x67,0x6e,0x75,0x2e,0x6f,0x72,0x67,0x2f,0x70, +0x72,0x6f,0x6a,0x65,0x63,0x74,0x73,0x2f,0x6c,0x77,0x69,0x70,0x29,0x0d,0x0a, +/* "Content-type: image/svg+xml + +" (31 bytes) */ +0x43,0x6f,0x6e,0x74,0x65,0x6e,0x74,0x2d,0x74,0x79,0x70,0x65,0x3a,0x20,0x69,0x6d, +0x61,0x67,0x65,0x2f,0x73,0x76,0x67,0x2b,0x78,0x6d,0x6c,0x0d,0x0a,0x0d,0x0a, +/* raw file data (12174 bytes) */ +0x3c,0x3f,0x78,0x6d,0x6c,0x20,0x76,0x65,0x72,0x73,0x69,0x6f,0x6e,0x3d,0x22,0x31, +0x2e,0x30,0x22,0x20,0x65,0x6e,0x63,0x6f,0x64,0x69,0x6e,0x67,0x3d,0x22,0x55,0x54, +0x46,0x2d,0x38,0x22,0x20,0x73,0x74,0x61,0x6e,0x64,0x61,0x6c,0x6f,0x6e,0x65,0x3d, +0x22,0x6e,0x6f,0x22,0x3f,0x3e,0x0d,0x0a,0x3c,0x73,0x76,0x67,0x0d,0x0a,0x20,0x20, +0x20,0x20,0x78,0x6d,0x6c,0x6e,0x73,0x3a,0x69,0x6e,0x6b,0x73,0x63,0x61,0x70,0x65, +0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x69,0x6e,0x6b, +0x73,0x63,0x61,0x70,0x65,0x2e,0x6f,0x72,0x67,0x2f,0x6e,0x61,0x6d,0x65,0x73,0x70, +0x61,0x63,0x65,0x73,0x2f,0x69,0x6e,0x6b,0x73,0x63,0x61,0x70,0x65,0x22,0x0d,0x0a, +0x20,0x20,0x20,0x20,0x78,0x6d,0x6c,0x6e,0x73,0x3a,0x72,0x64,0x66,0x3d,0x22,0x68, +0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67, +0x2f,0x31,0x39,0x39,0x39,0x2f,0x30,0x32,0x2f,0x32,0x32,0x2d,0x72,0x64,0x66,0x2d, +0x73,0x79,0x6e,0x74,0x61,0x78,0x2d,0x6e,0x73,0x23,0x22,0x0d,0x0a,0x20,0x20,0x20, +0x20,0x78,0x6d,0x6c,0x6e,0x73,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77, +0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67,0x2f,0x32,0x30,0x30,0x30,0x2f,0x73, +0x76,0x67,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x78,0x6d,0x6c,0x6e,0x73,0x3a,0x73, +0x6f,0x64,0x69,0x70,0x6f,0x64,0x69,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f, +0x73,0x6f,0x64,0x69,0x70,0x6f,0x64,0x69,0x2e,0x73,0x6f,0x75,0x72,0x63,0x65,0x66, +0x6f,0x72,0x67,0x65,0x2e,0x6e,0x65,0x74,0x2f,0x44,0x54,0x44,0x2f,0x73,0x6f,0x64, +0x69,0x70,0x6f,0x64,0x69,0x2d,0x30,0x2e,0x64,0x74,0x64,0x22,0x0d,0x0a,0x20,0x20, +0x20,0x20,0x78,0x6d,0x6c,0x6e,0x73,0x3a,0x63,0x63,0x3d,0x22,0x68,0x74,0x74,0x70, +0x3a,0x2f,0x2f,0x63,0x72,0x65,0x61,0x74,0x69,0x76,0x65,0x63,0x6f,0x6d,0x6d,0x6f, +0x6e,0x73,0x2e,0x6f,0x72,0x67,0x2f,0x6e,0x73,0x23,0x22,0x0d,0x0a,0x20,0x20,0x20, +0x20,0x78,0x6d,0x6c,0x6e,0x73,0x3a,0x78,0x6c,0x69,0x6e,0x6b,0x3d,0x22,0x68,0x74, +0x74,0x70,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67,0x2f, +0x31,0x39,0x39,0x39,0x2f,0x78,0x6c,0x69,0x6e,0x6b,0x22,0x0d,0x0a,0x20,0x20,0x20, +0x20,0x78,0x6d,0x6c,0x6e,0x73,0x3a,0x64,0x63,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a, +0x2f,0x2f,0x70,0x75,0x72,0x6c,0x2e,0x6f,0x72,0x67,0x2f,0x64,0x63,0x2f,0x65,0x6c, +0x65,0x6d,0x65,0x6e,0x74,0x73,0x2f,0x31,0x2e,0x31,0x2f,0x22,0x0d,0x0a,0x20,0x20, +0x20,0x20,0x78,0x6d,0x6c,0x6e,0x73,0x3a,0x73,0x76,0x67,0x3d,0x22,0x68,0x74,0x74, +0x70,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67,0x2f,0x32, +0x30,0x30,0x30,0x2f,0x73,0x76,0x67,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x78,0x6d, +0x6c,0x6e,0x73,0x3a,0x6e,0x73,0x31,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f, +0x73,0x6f,0x7a,0x69,0x2e,0x62,0x61,0x69,0x65,0x72,0x6f,0x75,0x67,0x65,0x2e,0x66, +0x72,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x69,0x64,0x3d,0x22,0x73,0x76,0x67,0x32, +0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x76,0x69,0x65,0x77,0x42,0x6f,0x78,0x3d,0x22, +0x30,0x20,0x30,0x20,0x33,0x36,0x36,0x2e,0x37,0x36,0x20,0x33,0x38,0x33,0x2e,0x39, +0x34,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x76,0x65,0x72,0x73,0x69,0x6f,0x6e,0x3d, +0x22,0x31,0x2e,0x30,0x22,0x0d,0x0a,0x20,0x20,0x3e,0x0d,0x0a,0x20,0x20,0x3c,0x64, +0x65,0x66,0x73,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x64,0x3d,0x22,0x64, +0x65,0x66,0x73,0x34,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x3e,0x0d,0x0a,0x20,0x20, +0x20,0x20,0x3c,0x6c,0x69,0x6e,0x65,0x61,0x72,0x47,0x72,0x61,0x64,0x69,0x65,0x6e, +0x74,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x64,0x3d,0x22,0x6c, +0x69,0x6e,0x65,0x61,0x72,0x47,0x72,0x61,0x64,0x69,0x65,0x6e,0x74,0x33,0x34,0x32, +0x31,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x6b,0x73, +0x63,0x61,0x70,0x65,0x3a,0x63,0x6f,0x6c,0x6c,0x65,0x63,0x74,0x3d,0x22,0x61,0x6c, +0x77,0x61,0x79,0x73,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x3e,0x0d,0x0a, +0x20,0x20,0x20,0x20,0x20,0x20,0x3c,0x73,0x74,0x6f,0x70,0x0d,0x0a,0x20,0x20,0x20, +0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x64,0x3d,0x22,0x73,0x74,0x6f,0x70,0x33, +0x34,0x32,0x33,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, +0x73,0x74,0x79,0x6c,0x65,0x3d,0x22,0x73,0x74,0x6f,0x70,0x2d,0x63,0x6f,0x6c,0x6f, +0x72,0x3a,0x23,0x35,0x35,0x35,0x37,0x35,0x33,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20, +0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x3d,0x22,0x30,0x22, +0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x2f,0x3e,0x0d,0x0a,0x20,0x20,0x20,0x20, +0x20,0x20,0x3c,0x73,0x74,0x6f,0x70,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20, +0x20,0x20,0x20,0x69,0x64,0x3d,0x22,0x73,0x74,0x6f,0x70,0x33,0x34,0x32,0x35,0x22, +0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x74,0x79,0x6c, +0x65,0x3d,0x22,0x73,0x74,0x6f,0x70,0x2d,0x63,0x6f,0x6c,0x6f,0x72,0x3a,0x23,0x35, +0x35,0x35,0x37,0x35,0x33,0x3b,0x73,0x74,0x6f,0x70,0x2d,0x6f,0x70,0x61,0x63,0x69, +0x74,0x79,0x3a,0x30,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, +0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x3d,0x22,0x31,0x22,0x0d,0x0a,0x20,0x20,0x20, +0x20,0x20,0x20,0x2f,0x3e,0x0d,0x0a,0x20,0x20,0x20,0x20,0x3c,0x2f,0x6c,0x69,0x6e, +0x65,0x61,0x72,0x47,0x72,0x61,0x64,0x69,0x65,0x6e,0x74,0x0d,0x0a,0x20,0x20,0x20, +0x20,0x3e,0x0d,0x0a,0x20,0x20,0x20,0x20,0x3c,0x6c,0x69,0x6e,0x65,0x61,0x72,0x47, +0x72,0x61,0x64,0x69,0x65,0x6e,0x74,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20, +0x20,0x69,0x64,0x3d,0x22,0x6c,0x69,0x6e,0x65,0x61,0x72,0x47,0x72,0x61,0x64,0x69, +0x65,0x6e,0x74,0x33,0x33,0x33,0x37,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20, +0x20,0x20,0x69,0x6e,0x6b,0x73,0x63,0x61,0x70,0x65,0x3a,0x63,0x6f,0x6c,0x6c,0x65, +0x63,0x74,0x3d,0x22,0x61,0x6c,0x77,0x61,0x79,0x73,0x22,0x0d,0x0a,0x20,0x20,0x20, +0x20,0x20,0x20,0x3e,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x3c,0x73,0x74,0x6f, +0x70,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x64,0x3d, +0x22,0x73,0x74,0x6f,0x70,0x33,0x33,0x33,0x39,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20, +0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x74,0x79,0x6c,0x65,0x3d,0x22,0x73,0x74,0x6f, +0x70,0x2d,0x63,0x6f,0x6c,0x6f,0x72,0x3a,0x23,0x65,0x65,0x65,0x65,0x65,0x63,0x22, +0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x66,0x66,0x73, +0x65,0x74,0x3d,0x22,0x30,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x2f,0x3e, +0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x3c,0x73,0x74,0x6f,0x70,0x0d,0x0a,0x20, +0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x64,0x3d,0x22,0x73,0x74,0x6f, +0x70,0x33,0x33,0x34,0x31,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, +0x20,0x20,0x73,0x74,0x79,0x6c,0x65,0x3d,0x22,0x73,0x74,0x6f,0x70,0x2d,0x63,0x6f, +0x6c,0x6f,0x72,0x3a,0x23,0x65,0x65,0x65,0x65,0x65,0x63,0x3b,0x73,0x74,0x6f,0x70, +0x2d,0x6f,0x70,0x61,0x63,0x69,0x74,0x79,0x3a,0x30,0x22,0x0d,0x0a,0x20,0x20,0x20, +0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x3d,0x22,0x31, +0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x2f,0x3e,0x0d,0x0a,0x20,0x20,0x20, +0x20,0x3c,0x2f,0x6c,0x69,0x6e,0x65,0x61,0x72,0x47,0x72,0x61,0x64,0x69,0x65,0x6e, +0x74,0x0d,0x0a,0x20,0x20,0x20,0x20,0x3e,0x0d,0x0a,0x20,0x20,0x20,0x20,0x3c,0x6c, +0x69,0x6e,0x65,0x61,0x72,0x47,0x72,0x61,0x64,0x69,0x65,0x6e,0x74,0x0d,0x0a,0x20, +0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x64,0x3d,0x22,0x6c,0x69,0x6e,0x65,0x61, +0x72,0x47,0x72,0x61,0x64,0x69,0x65,0x6e,0x74,0x33,0x35,0x37,0x30,0x22,0x0d,0x0a, +0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x6b,0x73,0x63,0x61,0x70,0x65, +0x3a,0x63,0x6f,0x6c,0x6c,0x65,0x63,0x74,0x3d,0x22,0x61,0x6c,0x77,0x61,0x79,0x73, +0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x3e,0x0d,0x0a,0x20,0x20,0x20,0x20, +0x20,0x20,0x3c,0x73,0x74,0x6f,0x70,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20, +0x20,0x20,0x20,0x69,0x64,0x3d,0x22,0x73,0x74,0x6f,0x70,0x33,0x35,0x37,0x32,0x22, +0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x74,0x79,0x6c, +0x65,0x3d,0x22,0x73,0x74,0x6f,0x70,0x2d,0x63,0x6f,0x6c,0x6f,0x72,0x3a,0x23,0x65, +0x65,0x65,0x65,0x65,0x63,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, +0x20,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x3d,0x22,0x30,0x22,0x0d,0x0a,0x20,0x20, +0x20,0x20,0x20,0x20,0x2f,0x3e,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x3c,0x73, +0x74,0x6f,0x70,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69, +0x64,0x3d,0x22,0x73,0x74,0x6f,0x70,0x33,0x35,0x37,0x34,0x22,0x0d,0x0a,0x20,0x20, +0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x74,0x79,0x6c,0x65,0x3d,0x22,0x73, +0x74,0x6f,0x70,0x2d,0x63,0x6f,0x6c,0x6f,0x72,0x3a,0x23,0x35,0x35,0x35,0x37,0x35, +0x33,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x66, +0x66,0x73,0x65,0x74,0x3d,0x22,0x31,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20, +0x2f,0x3e,0x0d,0x0a,0x20,0x20,0x20,0x20,0x3c,0x2f,0x6c,0x69,0x6e,0x65,0x61,0x72, +0x47,0x72,0x61,0x64,0x69,0x65,0x6e,0x74,0x0d,0x0a,0x20,0x20,0x20,0x20,0x3e,0x0d, +0x0a,0x20,0x20,0x20,0x20,0x3c,0x6c,0x69,0x6e,0x65,0x61,0x72,0x47,0x72,0x61,0x64, +0x69,0x65,0x6e,0x74,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x64, +0x3d,0x22,0x6c,0x69,0x6e,0x65,0x61,0x72,0x47,0x72,0x61,0x64,0x69,0x65,0x6e,0x74, +0x33,0x35,0x36,0x32,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69, +0x6e,0x6b,0x73,0x63,0x61,0x70,0x65,0x3a,0x63,0x6f,0x6c,0x6c,0x65,0x63,0x74,0x3d, +0x22,0x61,0x6c,0x77,0x61,0x79,0x73,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20, +0x3e,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x3c,0x73,0x74,0x6f,0x70,0x0d,0x0a, +0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x64,0x3d,0x22,0x73,0x74, +0x6f,0x70,0x33,0x35,0x36,0x34,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20, +0x20,0x20,0x20,0x73,0x74,0x79,0x6c,0x65,0x3d,0x22,0x73,0x74,0x6f,0x70,0x2d,0x63, +0x6f,0x6c,0x6f,0x72,0x3a,0x23,0x32,0x65,0x33,0x34,0x33,0x36,0x22,0x0d,0x0a,0x20, +0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x3d, +0x22,0x30,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x2f,0x3e,0x0d,0x0a,0x20, +0x20,0x20,0x20,0x20,0x20,0x3c,0x73,0x74,0x6f,0x70,0x0d,0x0a,0x20,0x20,0x20,0x20, +0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x64,0x3d,0x22,0x73,0x74,0x6f,0x70,0x33,0x35, +0x36,0x36,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73, +0x74,0x79,0x6c,0x65,0x3d,0x22,0x73,0x74,0x6f,0x70,0x2d,0x63,0x6f,0x6c,0x6f,0x72, +0x3a,0x23,0x35,0x35,0x35,0x37,0x35,0x33,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20, +0x20,0x20,0x20,0x20,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x3d,0x22,0x31,0x22,0x0d, +0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x2f,0x3e,0x0d,0x0a,0x20,0x20,0x20,0x20,0x3c, +0x2f,0x6c,0x69,0x6e,0x65,0x61,0x72,0x47,0x72,0x61,0x64,0x69,0x65,0x6e,0x74,0x0d, +0x0a,0x20,0x20,0x20,0x20,0x3e,0x0d,0x0a,0x20,0x20,0x20,0x20,0x3c,0x6c,0x69,0x6e, +0x65,0x61,0x72,0x47,0x72,0x61,0x64,0x69,0x65,0x6e,0x74,0x0d,0x0a,0x20,0x20,0x20, +0x20,0x20,0x20,0x20,0x20,0x69,0x64,0x3d,0x22,0x6c,0x69,0x6e,0x65,0x61,0x72,0x47, +0x72,0x61,0x64,0x69,0x65,0x6e,0x74,0x33,0x32,0x37,0x34,0x22,0x0d,0x0a,0x20,0x20, +0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x6b,0x73,0x63,0x61,0x70,0x65,0x3a,0x63, +0x6f,0x6c,0x6c,0x65,0x63,0x74,0x3d,0x22,0x61,0x6c,0x77,0x61,0x79,0x73,0x22,0x0d, +0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x3e,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20, +0x3c,0x73,0x74,0x6f,0x70,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, +0x20,0x69,0x64,0x3d,0x22,0x73,0x74,0x6f,0x70,0x33,0x32,0x37,0x36,0x22,0x0d,0x0a, +0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x74,0x79,0x6c,0x65,0x3d, +0x22,0x73,0x74,0x6f,0x70,0x2d,0x63,0x6f,0x6c,0x6f,0x72,0x3a,0x23,0x62,0x61,0x62, +0x64,0x62,0x36,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, +0x6f,0x66,0x66,0x73,0x65,0x74,0x3d,0x22,0x30,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20, +0x20,0x20,0x2f,0x3e,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x3c,0x73,0x74,0x6f, +0x70,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x64,0x3d, +0x22,0x73,0x74,0x6f,0x70,0x33,0x32,0x37,0x38,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20, +0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x74,0x79,0x6c,0x65,0x3d,0x22,0x73,0x74,0x6f, +0x70,0x2d,0x63,0x6f,0x6c,0x6f,0x72,0x3a,0x23,0x38,0x38,0x38,0x61,0x38,0x35,0x22, +0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x66,0x66,0x73, +0x65,0x74,0x3d,0x22,0x31,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x2f,0x3e, +0x0d,0x0a,0x20,0x20,0x20,0x20,0x3c,0x2f,0x6c,0x69,0x6e,0x65,0x61,0x72,0x47,0x72, +0x61,0x64,0x69,0x65,0x6e,0x74,0x0d,0x0a,0x20,0x20,0x20,0x20,0x3e,0x0d,0x0a,0x20, +0x20,0x20,0x20,0x3c,0x6c,0x69,0x6e,0x65,0x61,0x72,0x47,0x72,0x61,0x64,0x69,0x65, +0x6e,0x74,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x64,0x3d,0x22, +0x6c,0x69,0x6e,0x65,0x61,0x72,0x47,0x72,0x61,0x64,0x69,0x65,0x6e,0x74,0x33,0x35, +0x37,0x38,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x79,0x32,0x3d, +0x22,0x31,0x31,0x31,0x2e,0x36,0x38,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20, +0x20,0x20,0x78,0x6c,0x69,0x6e,0x6b,0x3a,0x68,0x72,0x65,0x66,0x3d,0x22,0x23,0x6c, +0x69,0x6e,0x65,0x61,0x72,0x47,0x72,0x61,0x64,0x69,0x65,0x6e,0x74,0x33,0x35,0x36, +0x32,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x67,0x72,0x61,0x64, +0x69,0x65,0x6e,0x74,0x55,0x6e,0x69,0x74,0x73,0x3d,0x22,0x75,0x73,0x65,0x72,0x53, +0x70,0x61,0x63,0x65,0x4f,0x6e,0x55,0x73,0x65,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20, +0x20,0x20,0x20,0x20,0x78,0x32,0x3d,0x22,0x32,0x36,0x38,0x2e,0x39,0x34,0x22,0x0d, +0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x67,0x72,0x61,0x64,0x69,0x65,0x6e, +0x74,0x54,0x72,0x61,0x6e,0x73,0x66,0x6f,0x72,0x6d,0x3d,0x22,0x6d,0x61,0x74,0x72, +0x69,0x78,0x28,0x2e,0x37,0x38,0x38,0x31,0x37,0x20,0x30,0x20,0x30,0x20,0x31,0x2e, +0x35,0x37,0x39,0x31,0x20,0x2d,0x35,0x34,0x35,0x2e,0x33,0x32,0x20,0x2d,0x31,0x37, +0x34,0x2e,0x38,0x39,0x29,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, +0x79,0x31,0x3d,0x22,0x31,0x36,0x33,0x2e,0x31,0x38,0x22,0x0d,0x0a,0x20,0x20,0x20, +0x20,0x20,0x20,0x20,0x20,0x78,0x31,0x3d,0x22,0x32,0x38,0x30,0x2e,0x34,0x34,0x22, +0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x6b,0x73,0x63,0x61, +0x70,0x65,0x3a,0x63,0x6f,0x6c,0x6c,0x65,0x63,0x74,0x3d,0x22,0x61,0x6c,0x77,0x61, +0x79,0x73,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x2f,0x3e,0x0d,0x0a,0x20,0x20,0x20, +0x20,0x3c,0x6c,0x69,0x6e,0x65,0x61,0x72,0x47,0x72,0x61,0x64,0x69,0x65,0x6e,0x74, +0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x64,0x3d,0x22,0x6c,0x69, +0x6e,0x65,0x61,0x72,0x47,0x72,0x61,0x64,0x69,0x65,0x6e,0x74,0x33,0x35,0x38,0x30, +0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x79,0x32,0x3d,0x22,0x31, +0x31,0x31,0x2e,0x36,0x38,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, +0x78,0x6c,0x69,0x6e,0x6b,0x3a,0x68,0x72,0x65,0x66,0x3d,0x22,0x23,0x6c,0x69,0x6e, +0x65,0x61,0x72,0x47,0x72,0x61,0x64,0x69,0x65,0x6e,0x74,0x33,0x35,0x37,0x30,0x22, +0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x67,0x72,0x61,0x64,0x69,0x65, +0x6e,0x74,0x55,0x6e,0x69,0x74,0x73,0x3d,0x22,0x75,0x73,0x65,0x72,0x53,0x70,0x61, +0x63,0x65,0x4f,0x6e,0x55,0x73,0x65,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20, +0x20,0x20,0x78,0x32,0x3d,0x22,0x32,0x36,0x38,0x2e,0x39,0x34,0x22,0x0d,0x0a,0x20, +0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x67,0x72,0x61,0x64,0x69,0x65,0x6e,0x74,0x54, +0x72,0x61,0x6e,0x73,0x66,0x6f,0x72,0x6d,0x3d,0x22,0x6d,0x61,0x74,0x72,0x69,0x78, +0x28,0x2e,0x37,0x38,0x38,0x31,0x37,0x20,0x30,0x20,0x30,0x20,0x31,0x2e,0x35,0x37, +0x39,0x31,0x20,0x2d,0x35,0x34,0x35,0x2e,0x33,0x32,0x20,0x2d,0x31,0x37,0x34,0x2e, +0x38,0x39,0x29,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x79,0x31, +0x3d,0x22,0x31,0x35,0x36,0x2e,0x36,0x38,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20, +0x20,0x20,0x20,0x78,0x31,0x3d,0x22,0x32,0x36,0x38,0x2e,0x39,0x34,0x22,0x0d,0x0a, +0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x6b,0x73,0x63,0x61,0x70,0x65, +0x3a,0x63,0x6f,0x6c,0x6c,0x65,0x63,0x74,0x3d,0x22,0x61,0x6c,0x77,0x61,0x79,0x73, +0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x2f,0x3e,0x0d,0x0a,0x20,0x20,0x20,0x20,0x3c, +0x6c,0x69,0x6e,0x65,0x61,0x72,0x47,0x72,0x61,0x64,0x69,0x65,0x6e,0x74,0x0d,0x0a, +0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x64,0x3d,0x22,0x6c,0x69,0x6e,0x65, +0x61,0x72,0x47,0x72,0x61,0x64,0x69,0x65,0x6e,0x74,0x33,0x37,0x30,0x33,0x22,0x0d, +0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x79,0x32,0x3d,0x22,0x35,0x39,0x36, +0x2e,0x33,0x36,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x78,0x6c, +0x69,0x6e,0x6b,0x3a,0x68,0x72,0x65,0x66,0x3d,0x22,0x23,0x6c,0x69,0x6e,0x65,0x61, +0x72,0x47,0x72,0x61,0x64,0x69,0x65,0x6e,0x74,0x33,0x32,0x37,0x34,0x22,0x0d,0x0a, +0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x70,0x72,0x65,0x61,0x64,0x4d,0x65, +0x74,0x68,0x6f,0x64,0x3d,0x22,0x72,0x65,0x66,0x6c,0x65,0x63,0x74,0x22,0x0d,0x0a, +0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x67,0x72,0x61,0x64,0x69,0x65,0x6e,0x74, +0x55,0x6e,0x69,0x74,0x73,0x3d,0x22,0x75,0x73,0x65,0x72,0x53,0x70,0x61,0x63,0x65, +0x4f,0x6e,0x55,0x73,0x65,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, +0x78,0x32,0x3d,0x22,0x31,0x32,0x32,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20, +0x20,0x20,0x67,0x72,0x61,0x64,0x69,0x65,0x6e,0x74,0x54,0x72,0x61,0x6e,0x73,0x66, +0x6f,0x72,0x6d,0x3d,0x22,0x6d,0x61,0x74,0x72,0x69,0x78,0x28,0x2d,0x2e,0x37,0x31, +0x20,0x2d,0x2e,0x33,0x35,0x34,0x39,0x32,0x20,0x30,0x20,0x31,0x20,0x32,0x31,0x35, +0x2e,0x32,0x32,0x20,0x2d,0x32,0x32,0x37,0x2e,0x30,0x35,0x29,0x22,0x0d,0x0a,0x20, +0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x79,0x31,0x3d,0x22,0x34,0x34,0x36,0x2e,0x33, +0x36,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x78,0x31,0x3d,0x22, +0x2d,0x31,0x32,0x36,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69, +0x6e,0x6b,0x73,0x63,0x61,0x70,0x65,0x3a,0x63,0x6f,0x6c,0x6c,0x65,0x63,0x74,0x3d, +0x22,0x61,0x6c,0x77,0x61,0x79,0x73,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x2f,0x3e, +0x0d,0x0a,0x20,0x20,0x20,0x20,0x3c,0x6c,0x69,0x6e,0x65,0x61,0x72,0x47,0x72,0x61, +0x64,0x69,0x65,0x6e,0x74,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69, +0x64,0x3d,0x22,0x6c,0x69,0x6e,0x65,0x61,0x72,0x47,0x72,0x61,0x64,0x69,0x65,0x6e, +0x74,0x33,0x37,0x31,0x33,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, +0x79,0x32,0x3d,0x22,0x36,0x32,0x39,0x2e,0x34,0x36,0x22,0x0d,0x0a,0x20,0x20,0x20, +0x20,0x20,0x20,0x20,0x20,0x67,0x72,0x61,0x64,0x69,0x65,0x6e,0x74,0x55,0x6e,0x69, +0x74,0x73,0x3d,0x22,0x75,0x73,0x65,0x72,0x53,0x70,0x61,0x63,0x65,0x4f,0x6e,0x55, +0x73,0x65,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x78,0x32,0x3d, +0x22,0x31,0x34,0x32,0x2e,0x38,0x38,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20, +0x20,0x20,0x67,0x72,0x61,0x64,0x69,0x65,0x6e,0x74,0x54,0x72,0x61,0x6e,0x73,0x66, +0x6f,0x72,0x6d,0x3d,0x22,0x74,0x72,0x61,0x6e,0x73,0x6c,0x61,0x74,0x65,0x28,0x32, +0x36,0x34,0x2c,0x2d,0x33,0x35,0x38,0x29,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20, +0x20,0x20,0x20,0x79,0x31,0x3d,0x22,0x35,0x34,0x38,0x2e,0x34,0x36,0x22,0x0d,0x0a, +0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x78,0x31,0x3d,0x22,0x31,0x30,0x31,0x2e, +0x39,0x36,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x6b, +0x73,0x63,0x61,0x70,0x65,0x3a,0x63,0x6f,0x6c,0x6c,0x65,0x63,0x74,0x3d,0x22,0x61, +0x6c,0x77,0x61,0x79,0x73,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x3e,0x0d, +0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x3c,0x73,0x74,0x6f,0x70,0x0d,0x0a,0x20,0x20, +0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x64,0x3d,0x22,0x73,0x74,0x6f,0x70, +0x33,0x37,0x30,0x39,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, +0x20,0x73,0x74,0x79,0x6c,0x65,0x3d,0x22,0x73,0x74,0x6f,0x70,0x2d,0x63,0x6f,0x6c, +0x6f,0x72,0x3a,0x23,0x64,0x33,0x64,0x37,0x63,0x66,0x22,0x0d,0x0a,0x20,0x20,0x20, +0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x3d,0x22,0x30, +0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x2f,0x3e,0x0d,0x0a,0x20,0x20,0x20, +0x20,0x20,0x20,0x3c,0x73,0x74,0x6f,0x70,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20, +0x20,0x20,0x20,0x20,0x69,0x64,0x3d,0x22,0x73,0x74,0x6f,0x70,0x33,0x37,0x31,0x31, +0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x74,0x79, +0x6c,0x65,0x3d,0x22,0x73,0x74,0x6f,0x70,0x2d,0x63,0x6f,0x6c,0x6f,0x72,0x3a,0x23, +0x38,0x38,0x38,0x61,0x38,0x35,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20, +0x20,0x20,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x3d,0x22,0x31,0x22,0x0d,0x0a,0x20, +0x20,0x20,0x20,0x20,0x20,0x2f,0x3e,0x0d,0x0a,0x20,0x20,0x20,0x20,0x3c,0x2f,0x6c, +0x69,0x6e,0x65,0x61,0x72,0x47,0x72,0x61,0x64,0x69,0x65,0x6e,0x74,0x0d,0x0a,0x20, +0x20,0x20,0x20,0x3e,0x0d,0x0a,0x20,0x20,0x20,0x20,0x3c,0x6c,0x69,0x6e,0x65,0x61, +0x72,0x47,0x72,0x61,0x64,0x69,0x65,0x6e,0x74,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20, +0x20,0x20,0x20,0x69,0x64,0x3d,0x22,0x6c,0x69,0x6e,0x65,0x61,0x72,0x47,0x72,0x61, +0x64,0x69,0x65,0x6e,0x74,0x32,0x34,0x36,0x31,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20, +0x20,0x20,0x20,0x20,0x79,0x32,0x3d,0x22,0x31,0x31,0x31,0x2e,0x36,0x38,0x22,0x0d, +0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x78,0x6c,0x69,0x6e,0x6b,0x3a,0x68, +0x72,0x65,0x66,0x3d,0x22,0x23,0x6c,0x69,0x6e,0x65,0x61,0x72,0x47,0x72,0x61,0x64, +0x69,0x65,0x6e,0x74,0x33,0x35,0x36,0x32,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20, +0x20,0x20,0x20,0x67,0x72,0x61,0x64,0x69,0x65,0x6e,0x74,0x55,0x6e,0x69,0x74,0x73, +0x3d,0x22,0x75,0x73,0x65,0x72,0x53,0x70,0x61,0x63,0x65,0x4f,0x6e,0x55,0x73,0x65, +0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x78,0x32,0x3d,0x22,0x32, +0x36,0x38,0x2e,0x39,0x34,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, +0x67,0x72,0x61,0x64,0x69,0x65,0x6e,0x74,0x54,0x72,0x61,0x6e,0x73,0x66,0x6f,0x72, +0x6d,0x3d,0x22,0x6d,0x61,0x74,0x72,0x69,0x78,0x28,0x2e,0x37,0x38,0x38,0x31,0x37, +0x20,0x30,0x20,0x30,0x20,0x31,0x2e,0x35,0x37,0x39,0x31,0x20,0x2d,0x35,0x34,0x36, +0x2e,0x34,0x33,0x20,0x2d,0x32,0x32,0x32,0x2e,0x39,0x36,0x29,0x22,0x0d,0x0a,0x20, +0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x79,0x31,0x3d,0x22,0x31,0x36,0x33,0x2e,0x31, +0x38,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x78,0x31,0x3d,0x22, +0x32,0x38,0x30,0x2e,0x34,0x34,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20, +0x20,0x69,0x6e,0x6b,0x73,0x63,0x61,0x70,0x65,0x3a,0x63,0x6f,0x6c,0x6c,0x65,0x63, +0x74,0x3d,0x22,0x61,0x6c,0x77,0x61,0x79,0x73,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20, +0x2f,0x3e,0x0d,0x0a,0x20,0x20,0x20,0x20,0x3c,0x6c,0x69,0x6e,0x65,0x61,0x72,0x47, +0x72,0x61,0x64,0x69,0x65,0x6e,0x74,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20, +0x20,0x69,0x64,0x3d,0x22,0x6c,0x69,0x6e,0x65,0x61,0x72,0x47,0x72,0x61,0x64,0x69, +0x65,0x6e,0x74,0x32,0x34,0x36,0x33,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20, +0x20,0x20,0x79,0x32,0x3d,0x22,0x31,0x31,0x31,0x2e,0x36,0x38,0x22,0x0d,0x0a,0x20, +0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x78,0x6c,0x69,0x6e,0x6b,0x3a,0x68,0x72,0x65, +0x66,0x3d,0x22,0x23,0x6c,0x69,0x6e,0x65,0x61,0x72,0x47,0x72,0x61,0x64,0x69,0x65, +0x6e,0x74,0x33,0x35,0x37,0x30,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20, +0x20,0x67,0x72,0x61,0x64,0x69,0x65,0x6e,0x74,0x55,0x6e,0x69,0x74,0x73,0x3d,0x22, +0x75,0x73,0x65,0x72,0x53,0x70,0x61,0x63,0x65,0x4f,0x6e,0x55,0x73,0x65,0x22,0x0d, +0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x78,0x32,0x3d,0x22,0x32,0x36,0x38, +0x2e,0x39,0x34,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x67,0x72, +0x61,0x64,0x69,0x65,0x6e,0x74,0x54,0x72,0x61,0x6e,0x73,0x66,0x6f,0x72,0x6d,0x3d, +0x22,0x6d,0x61,0x74,0x72,0x69,0x78,0x28,0x2e,0x37,0x38,0x38,0x31,0x37,0x20,0x30, +0x20,0x30,0x20,0x31,0x2e,0x35,0x37,0x39,0x31,0x20,0x2d,0x35,0x34,0x36,0x2e,0x34, +0x33,0x20,0x2d,0x32,0x32,0x32,0x2e,0x39,0x36,0x29,0x22,0x0d,0x0a,0x20,0x20,0x20, +0x20,0x20,0x20,0x20,0x20,0x79,0x31,0x3d,0x22,0x31,0x35,0x36,0x2e,0x36,0x38,0x22, +0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x78,0x31,0x3d,0x22,0x32,0x36, +0x38,0x2e,0x39,0x34,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69, +0x6e,0x6b,0x73,0x63,0x61,0x70,0x65,0x3a,0x63,0x6f,0x6c,0x6c,0x65,0x63,0x74,0x3d, +0x22,0x61,0x6c,0x77,0x61,0x79,0x73,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x2f,0x3e, +0x0d,0x0a,0x20,0x20,0x20,0x20,0x3c,0x66,0x69,0x6c,0x74,0x65,0x72,0x0d,0x0a,0x20, +0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x64,0x3d,0x22,0x66,0x69,0x6c,0x74,0x65, +0x72,0x33,0x32,0x38,0x34,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, +0x69,0x6e,0x6b,0x73,0x63,0x61,0x70,0x65,0x3a,0x63,0x6f,0x6c,0x6c,0x65,0x63,0x74, +0x3d,0x22,0x61,0x6c,0x77,0x61,0x79,0x73,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20, +0x20,0x3e,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x3c,0x66,0x65,0x47,0x61,0x75, +0x73,0x73,0x69,0x61,0x6e,0x42,0x6c,0x75,0x72,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20, +0x20,0x20,0x20,0x20,0x20,0x69,0x64,0x3d,0x22,0x66,0x65,0x47,0x61,0x75,0x73,0x73, +0x69,0x61,0x6e,0x42,0x6c,0x75,0x72,0x33,0x32,0x38,0x36,0x22,0x0d,0x0a,0x20,0x20, +0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x74,0x64,0x44,0x65,0x76,0x69,0x61, +0x74,0x69,0x6f,0x6e,0x3d,0x22,0x34,0x2e,0x30,0x39,0x34,0x30,0x30,0x31,0x37,0x22, +0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x6b,0x73, +0x63,0x61,0x70,0x65,0x3a,0x63,0x6f,0x6c,0x6c,0x65,0x63,0x74,0x3d,0x22,0x61,0x6c, +0x77,0x61,0x79,0x73,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x2f,0x3e,0x0d, +0x0a,0x20,0x20,0x20,0x20,0x3c,0x2f,0x66,0x69,0x6c,0x74,0x65,0x72,0x0d,0x0a,0x20, +0x20,0x20,0x20,0x3e,0x0d,0x0a,0x20,0x20,0x20,0x20,0x3c,0x6c,0x69,0x6e,0x65,0x61, +0x72,0x47,0x72,0x61,0x64,0x69,0x65,0x6e,0x74,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20, +0x20,0x20,0x20,0x69,0x64,0x3d,0x22,0x6c,0x69,0x6e,0x65,0x61,0x72,0x47,0x72,0x61, +0x64,0x69,0x65,0x6e,0x74,0x33,0x33,0x34,0x33,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20, +0x20,0x20,0x20,0x20,0x79,0x32,0x3d,0x22,0x37,0x30,0x39,0x2e,0x30,0x37,0x22,0x0d, +0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x78,0x6c,0x69,0x6e,0x6b,0x3a,0x68, +0x72,0x65,0x66,0x3d,0x22,0x23,0x6c,0x69,0x6e,0x65,0x61,0x72,0x47,0x72,0x61,0x64, +0x69,0x65,0x6e,0x74,0x33,0x33,0x33,0x37,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20, +0x20,0x20,0x20,0x67,0x72,0x61,0x64,0x69,0x65,0x6e,0x74,0x55,0x6e,0x69,0x74,0x73, +0x3d,0x22,0x75,0x73,0x65,0x72,0x53,0x70,0x61,0x63,0x65,0x4f,0x6e,0x55,0x73,0x65, +0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x78,0x32,0x3d,0x22,0x31, +0x31,0x32,0x2e,0x39,0x37,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, +0x67,0x72,0x61,0x64,0x69,0x65,0x6e,0x74,0x54,0x72,0x61,0x6e,0x73,0x66,0x6f,0x72, +0x6d,0x3d,0x22,0x74,0x72,0x61,0x6e,0x73,0x6c,0x61,0x74,0x65,0x28,0x32,0x37,0x39, +0x2e,0x35,0x36,0x20,0x2d,0x33,0x36,0x35,0x2e,0x37,0x38,0x29,0x22,0x0d,0x0a,0x20, +0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x79,0x31,0x3d,0x22,0x37,0x30,0x39,0x2e,0x30, +0x37,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x78,0x31,0x3d,0x22, +0x31,0x32,0x39,0x2e,0x39,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, +0x69,0x6e,0x6b,0x73,0x63,0x61,0x70,0x65,0x3a,0x63,0x6f,0x6c,0x6c,0x65,0x63,0x74, +0x3d,0x22,0x61,0x6c,0x77,0x61,0x79,0x73,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x2f, +0x3e,0x0d,0x0a,0x20,0x20,0x20,0x20,0x3c,0x6c,0x69,0x6e,0x65,0x61,0x72,0x47,0x72, +0x61,0x64,0x69,0x65,0x6e,0x74,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, +0x69,0x64,0x3d,0x22,0x6c,0x69,0x6e,0x65,0x61,0x72,0x47,0x72,0x61,0x64,0x69,0x65, +0x6e,0x74,0x33,0x33,0x34,0x37,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20, +0x20,0x79,0x32,0x3d,0x22,0x37,0x30,0x39,0x2e,0x30,0x37,0x22,0x0d,0x0a,0x20,0x20, +0x20,0x20,0x20,0x20,0x20,0x20,0x78,0x6c,0x69,0x6e,0x6b,0x3a,0x68,0x72,0x65,0x66, +0x3d,0x22,0x23,0x6c,0x69,0x6e,0x65,0x61,0x72,0x47,0x72,0x61,0x64,0x69,0x65,0x6e, +0x74,0x33,0x33,0x33,0x37,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, +0x67,0x72,0x61,0x64,0x69,0x65,0x6e,0x74,0x55,0x6e,0x69,0x74,0x73,0x3d,0x22,0x75, +0x73,0x65,0x72,0x53,0x70,0x61,0x63,0x65,0x4f,0x6e,0x55,0x73,0x65,0x22,0x0d,0x0a, +0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x78,0x32,0x3d,0x22,0x31,0x31,0x32,0x2e, +0x39,0x37,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x67,0x72,0x61, +0x64,0x69,0x65,0x6e,0x74,0x54,0x72,0x61,0x6e,0x73,0x66,0x6f,0x72,0x6d,0x3d,0x22, +0x74,0x72,0x61,0x6e,0x73,0x6c,0x61,0x74,0x65,0x28,0x33,0x30,0x36,0x2e,0x38,0x34, +0x20,0x2d,0x33,0x37,0x38,0x2e,0x31,0x37,0x29,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20, +0x20,0x20,0x20,0x20,0x79,0x31,0x3d,0x22,0x37,0x30,0x39,0x2e,0x30,0x37,0x22,0x0d, +0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x78,0x31,0x3d,0x22,0x31,0x32,0x39, +0x2e,0x39,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x6b, +0x73,0x63,0x61,0x70,0x65,0x3a,0x63,0x6f,0x6c,0x6c,0x65,0x63,0x74,0x3d,0x22,0x61, +0x6c,0x77,0x61,0x79,0x73,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x2f,0x3e,0x0d,0x0a, +0x20,0x20,0x20,0x20,0x3c,0x66,0x69,0x6c,0x74,0x65,0x72,0x0d,0x0a,0x20,0x20,0x20, +0x20,0x20,0x20,0x20,0x20,0x69,0x64,0x3d,0x22,0x66,0x69,0x6c,0x74,0x65,0x72,0x33, +0x34,0x30,0x37,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e, +0x6b,0x73,0x63,0x61,0x70,0x65,0x3a,0x63,0x6f,0x6c,0x6c,0x65,0x63,0x74,0x3d,0x22, +0x61,0x6c,0x77,0x61,0x79,0x73,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x3e, +0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x3c,0x66,0x65,0x47,0x61,0x75,0x73,0x73, +0x69,0x61,0x6e,0x42,0x6c,0x75,0x72,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20, +0x20,0x20,0x20,0x69,0x64,0x3d,0x22,0x66,0x65,0x47,0x61,0x75,0x73,0x73,0x69,0x61, +0x6e,0x42,0x6c,0x75,0x72,0x33,0x34,0x30,0x39,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20, +0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x74,0x64,0x44,0x65,0x76,0x69,0x61,0x74,0x69, +0x6f,0x6e,0x3d,0x22,0x30,0x2e,0x34,0x33,0x32,0x36,0x39,0x33,0x32,0x32,0x22,0x0d, +0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x6b,0x73,0x63, +0x61,0x70,0x65,0x3a,0x63,0x6f,0x6c,0x6c,0x65,0x63,0x74,0x3d,0x22,0x61,0x6c,0x77, +0x61,0x79,0x73,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x2f,0x3e,0x0d,0x0a, +0x20,0x20,0x20,0x20,0x3c,0x2f,0x66,0x69,0x6c,0x74,0x65,0x72,0x0d,0x0a,0x20,0x20, +0x20,0x20,0x3e,0x0d,0x0a,0x20,0x20,0x20,0x20,0x3c,0x6c,0x69,0x6e,0x65,0x61,0x72, +0x47,0x72,0x61,0x64,0x69,0x65,0x6e,0x74,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20, +0x20,0x20,0x69,0x64,0x3d,0x22,0x6c,0x69,0x6e,0x65,0x61,0x72,0x47,0x72,0x61,0x64, +0x69,0x65,0x6e,0x74,0x33,0x34,0x32,0x37,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20, +0x20,0x20,0x20,0x79,0x32,0x3d,0x22,0x34,0x39,0x36,0x2e,0x32,0x39,0x22,0x0d,0x0a, +0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x78,0x6c,0x69,0x6e,0x6b,0x3a,0x68,0x72, +0x65,0x66,0x3d,0x22,0x23,0x6c,0x69,0x6e,0x65,0x61,0x72,0x47,0x72,0x61,0x64,0x69, +0x65,0x6e,0x74,0x33,0x34,0x32,0x31,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20, +0x20,0x20,0x67,0x72,0x61,0x64,0x69,0x65,0x6e,0x74,0x55,0x6e,0x69,0x74,0x73,0x3d, +0x22,0x75,0x73,0x65,0x72,0x53,0x70,0x61,0x63,0x65,0x4f,0x6e,0x55,0x73,0x65,0x22, +0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x78,0x32,0x3d,0x22,0x31,0x38, +0x2e,0x34,0x39,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x67,0x72, +0x61,0x64,0x69,0x65,0x6e,0x74,0x54,0x72,0x61,0x6e,0x73,0x66,0x6f,0x72,0x6d,0x3d, +0x22,0x74,0x72,0x61,0x6e,0x73,0x6c,0x61,0x74,0x65,0x28,0x32,0x36,0x34,0x2c,0x2d, +0x33,0x35,0x38,0x29,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x79, +0x31,0x3d,0x22,0x34,0x35,0x39,0x2e,0x30,0x34,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20, +0x20,0x20,0x20,0x20,0x78,0x31,0x3d,0x22,0x2d,0x33,0x30,0x2e,0x39,0x38,0x39,0x22, +0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x6b,0x73,0x63,0x61, +0x70,0x65,0x3a,0x63,0x6f,0x6c,0x6c,0x65,0x63,0x74,0x3d,0x22,0x61,0x6c,0x77,0x61, +0x79,0x73,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x2f,0x3e,0x0d,0x0a,0x20,0x20,0x20, +0x20,0x3c,0x6c,0x69,0x6e,0x65,0x61,0x72,0x47,0x72,0x61,0x64,0x69,0x65,0x6e,0x74, +0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x64,0x3d,0x22,0x6c,0x69, +0x6e,0x65,0x61,0x72,0x47,0x72,0x61,0x64,0x69,0x65,0x6e,0x74,0x33,0x34,0x33,0x31, +0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x79,0x32,0x3d,0x22,0x34, +0x39,0x36,0x2e,0x32,0x39,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, +0x78,0x6c,0x69,0x6e,0x6b,0x3a,0x68,0x72,0x65,0x66,0x3d,0x22,0x23,0x6c,0x69,0x6e, +0x65,0x61,0x72,0x47,0x72,0x61,0x64,0x69,0x65,0x6e,0x74,0x33,0x34,0x32,0x31,0x22, +0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x67,0x72,0x61,0x64,0x69,0x65, +0x6e,0x74,0x55,0x6e,0x69,0x74,0x73,0x3d,0x22,0x75,0x73,0x65,0x72,0x53,0x70,0x61, +0x63,0x65,0x4f,0x6e,0x55,0x73,0x65,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20, +0x20,0x20,0x78,0x32,0x3d,0x22,0x31,0x38,0x2e,0x34,0x39,0x22,0x0d,0x0a,0x20,0x20, +0x20,0x20,0x20,0x20,0x20,0x20,0x67,0x72,0x61,0x64,0x69,0x65,0x6e,0x74,0x54,0x72, +0x61,0x6e,0x73,0x66,0x6f,0x72,0x6d,0x3d,0x22,0x74,0x72,0x61,0x6e,0x73,0x6c,0x61, +0x74,0x65,0x28,0x32,0x32,0x32,0x2e,0x32,0x38,0x20,0x2d,0x33,0x33,0x36,0x2e,0x37, +0x39,0x29,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x79,0x31,0x3d, +0x22,0x34,0x35,0x39,0x2e,0x30,0x34,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20, +0x20,0x20,0x78,0x31,0x3d,0x22,0x2d,0x33,0x30,0x2e,0x39,0x38,0x39,0x22,0x0d,0x0a, +0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x6b,0x73,0x63,0x61,0x70,0x65, +0x3a,0x63,0x6f,0x6c,0x6c,0x65,0x63,0x74,0x3d,0x22,0x61,0x6c,0x77,0x61,0x79,0x73, +0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x2f,0x3e,0x0d,0x0a,0x20,0x20,0x20,0x20,0x3c, +0x6c,0x69,0x6e,0x65,0x61,0x72,0x47,0x72,0x61,0x64,0x69,0x65,0x6e,0x74,0x0d,0x0a, +0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x64,0x3d,0x22,0x6c,0x69,0x6e,0x65, +0x61,0x72,0x47,0x72,0x61,0x64,0x69,0x65,0x6e,0x74,0x33,0x34,0x36,0x36,0x22,0x0d, +0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x79,0x32,0x3d,0x22,0x36,0x39,0x38, +0x2e,0x37,0x34,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x67,0x72, +0x61,0x64,0x69,0x65,0x6e,0x74,0x55,0x6e,0x69,0x74,0x73,0x3d,0x22,0x75,0x73,0x65, +0x72,0x53,0x70,0x61,0x63,0x65,0x4f,0x6e,0x55,0x73,0x65,0x22,0x0d,0x0a,0x20,0x20, +0x20,0x20,0x20,0x20,0x20,0x20,0x78,0x32,0x3d,0x22,0x2d,0x31,0x30,0x2e,0x36,0x35, +0x37,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x67,0x72,0x61,0x64, +0x69,0x65,0x6e,0x74,0x54,0x72,0x61,0x6e,0x73,0x66,0x6f,0x72,0x6d,0x3d,0x22,0x74, +0x72,0x61,0x6e,0x73,0x6c,0x61,0x74,0x65,0x28,0x33,0x35,0x30,0x2e,0x30,0x36,0x20, +0x2d,0x32,0x35,0x34,0x2e,0x31,0x32,0x29,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20, +0x20,0x20,0x20,0x79,0x31,0x3d,0x22,0x37,0x31,0x31,0x2e,0x32,0x39,0x22,0x0d,0x0a, +0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x78,0x31,0x3d,0x22,0x2d,0x35,0x2e,0x36, +0x35,0x36,0x39,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e, +0x6b,0x73,0x63,0x61,0x70,0x65,0x3a,0x63,0x6f,0x6c,0x6c,0x65,0x63,0x74,0x3d,0x22, +0x61,0x6c,0x77,0x61,0x79,0x73,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x3e, +0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x3c,0x73,0x74,0x6f,0x70,0x0d,0x0a,0x20, +0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x64,0x3d,0x22,0x73,0x74,0x6f, +0x70,0x33,0x34,0x36,0x32,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, +0x20,0x20,0x73,0x74,0x79,0x6c,0x65,0x3d,0x22,0x73,0x74,0x6f,0x70,0x2d,0x63,0x6f, +0x6c,0x6f,0x72,0x3a,0x23,0x38,0x38,0x38,0x61,0x38,0x35,0x22,0x0d,0x0a,0x20,0x20, +0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x3d,0x22, +0x30,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x2f,0x3e,0x0d,0x0a,0x20,0x20, +0x20,0x20,0x20,0x20,0x3c,0x73,0x74,0x6f,0x70,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20, +0x20,0x20,0x20,0x20,0x20,0x69,0x64,0x3d,0x22,0x73,0x74,0x6f,0x70,0x33,0x34,0x36, +0x34,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x74, +0x79,0x6c,0x65,0x3d,0x22,0x73,0x74,0x6f,0x70,0x2d,0x63,0x6f,0x6c,0x6f,0x72,0x3a, +0x23,0x38,0x38,0x38,0x61,0x38,0x35,0x3b,0x73,0x74,0x6f,0x70,0x2d,0x6f,0x70,0x61, +0x63,0x69,0x74,0x79,0x3a,0x30,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20, +0x20,0x20,0x20,0x6f,0x66,0x66,0x73,0x65,0x74,0x3d,0x22,0x31,0x22,0x0d,0x0a,0x20, +0x20,0x20,0x20,0x20,0x20,0x2f,0x3e,0x0d,0x0a,0x20,0x20,0x20,0x20,0x3c,0x2f,0x6c, +0x69,0x6e,0x65,0x61,0x72,0x47,0x72,0x61,0x64,0x69,0x65,0x6e,0x74,0x0d,0x0a,0x20, +0x20,0x20,0x20,0x3e,0x0d,0x0a,0x20,0x20,0x3c,0x2f,0x64,0x65,0x66,0x73,0x0d,0x0a, +0x20,0x20,0x3e,0x0d,0x0a,0x20,0x20,0x3c,0x73,0x6f,0x64,0x69,0x70,0x6f,0x64,0x69, +0x3a,0x6e,0x61,0x6d,0x65,0x64,0x76,0x69,0x65,0x77,0x0d,0x0a,0x20,0x20,0x20,0x20, +0x20,0x20,0x69,0x64,0x3d,0x22,0x62,0x61,0x73,0x65,0x22,0x0d,0x0a,0x20,0x20,0x20, +0x20,0x20,0x20,0x62,0x6f,0x72,0x64,0x65,0x72,0x63,0x6f,0x6c,0x6f,0x72,0x3d,0x22, +0x23,0x36,0x36,0x36,0x36,0x36,0x36,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20, +0x69,0x6e,0x6b,0x73,0x63,0x61,0x70,0x65,0x3a,0x70,0x61,0x67,0x65,0x73,0x68,0x61, +0x64,0x6f,0x77,0x3d,0x22,0x32,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x69, +0x6e,0x6b,0x73,0x63,0x61,0x70,0x65,0x3a,0x67,0x75,0x69,0x64,0x65,0x2d,0x62,0x62, +0x6f,0x78,0x3d,0x22,0x74,0x72,0x75,0x65,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20, +0x20,0x67,0x75,0x69,0x64,0x65,0x74,0x6f,0x6c,0x65,0x72,0x61,0x6e,0x63,0x65,0x3d, +0x22,0x37,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x70,0x61,0x67,0x65,0x63, +0x6f,0x6c,0x6f,0x72,0x3d,0x22,0x23,0x66,0x66,0x66,0x66,0x66,0x66,0x22,0x0d,0x0a, +0x20,0x20,0x20,0x20,0x20,0x20,0x67,0x72,0x69,0x64,0x74,0x6f,0x6c,0x65,0x72,0x61, +0x6e,0x63,0x65,0x3d,0x22,0x35,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x69, +0x6e,0x6b,0x73,0x63,0x61,0x70,0x65,0x3a,0x77,0x69,0x6e,0x64,0x6f,0x77,0x2d,0x68, +0x65,0x69,0x67,0x68,0x74,0x3d,0x22,0x39,0x31,0x35,0x22,0x0d,0x0a,0x20,0x20,0x20, +0x20,0x20,0x20,0x69,0x6e,0x6b,0x73,0x63,0x61,0x70,0x65,0x3a,0x7a,0x6f,0x6f,0x6d, +0x3d,0x22,0x30,0x2e,0x35,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e, +0x6b,0x73,0x63,0x61,0x70,0x65,0x3a,0x77,0x69,0x6e,0x64,0x6f,0x77,0x2d,0x78,0x3d, +0x22,0x30,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x68,0x6f,0x77,0x67, +0x72,0x69,0x64,0x3d,0x22,0x66,0x61,0x6c,0x73,0x65,0x22,0x0d,0x0a,0x20,0x20,0x20, +0x20,0x20,0x20,0x62,0x6f,0x72,0x64,0x65,0x72,0x6f,0x70,0x61,0x63,0x69,0x74,0x79, +0x3d,0x22,0x31,0x2e,0x30,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e, +0x6b,0x73,0x63,0x61,0x70,0x65,0x3a,0x63,0x75,0x72,0x72,0x65,0x6e,0x74,0x2d,0x6c, +0x61,0x79,0x65,0x72,0x3d,0x22,0x6c,0x61,0x79,0x65,0x72,0x31,0x22,0x0d,0x0a,0x20, +0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x6b,0x73,0x63,0x61,0x70,0x65,0x3a,0x63,0x78, +0x3d,0x22,0x2d,0x31,0x37,0x34,0x2e,0x35,0x38,0x38,0x32,0x35,0x22,0x0d,0x0a,0x20, +0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x6b,0x73,0x63,0x61,0x70,0x65,0x3a,0x63,0x79, +0x3d,0x22,0x2d,0x32,0x32,0x33,0x2e,0x34,0x37,0x36,0x36,0x34,0x22,0x0d,0x0a,0x20, +0x20,0x20,0x20,0x20,0x20,0x73,0x68,0x6f,0x77,0x67,0x75,0x69,0x64,0x65,0x73,0x3d, +0x22,0x74,0x72,0x75,0x65,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e, +0x6b,0x73,0x63,0x61,0x70,0x65,0x3a,0x77,0x69,0x6e,0x64,0x6f,0x77,0x2d,0x79,0x3d, +0x22,0x33,0x38,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x6b,0x73, +0x63,0x61,0x70,0x65,0x3a,0x77,0x69,0x6e,0x64,0x6f,0x77,0x2d,0x77,0x69,0x64,0x74, +0x68,0x3d,0x22,0x31,0x32,0x37,0x32,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20, +0x69,0x6e,0x6b,0x73,0x63,0x61,0x70,0x65,0x3a,0x70,0x61,0x67,0x65,0x6f,0x70,0x61, +0x63,0x69,0x74,0x79,0x3d,0x22,0x30,0x2e,0x30,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20, +0x20,0x20,0x69,0x6e,0x6b,0x73,0x63,0x61,0x70,0x65,0x3a,0x64,0x6f,0x63,0x75,0x6d, +0x65,0x6e,0x74,0x2d,0x75,0x6e,0x69,0x74,0x73,0x3d,0x22,0x70,0x78,0x22,0x0d,0x0a, +0x20,0x20,0x20,0x20,0x3e,0x0d,0x0a,0x20,0x20,0x20,0x20,0x3c,0x69,0x6e,0x6b,0x73, +0x63,0x61,0x70,0x65,0x3a,0x67,0x72,0x69,0x64,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20, +0x20,0x20,0x20,0x69,0x64,0x3d,0x22,0x67,0x72,0x69,0x64,0x33,0x37,0x30,0x31,0x22, +0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x67,0x72,0x69,0x64,0x61,0x6e, +0x67,0x6c,0x65,0x78,0x3d,0x22,0x32,0x36,0x2e,0x35,0x36,0x22,0x0d,0x0a,0x20,0x20, +0x20,0x20,0x20,0x20,0x20,0x20,0x67,0x72,0x69,0x64,0x61,0x6e,0x67,0x6c,0x65,0x7a, +0x3d,0x22,0x32,0x36,0x2e,0x35,0x36,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20, +0x20,0x20,0x65,0x6e,0x61,0x62,0x6c,0x65,0x64,0x3d,0x22,0x74,0x72,0x75,0x65,0x22, +0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x70,0x61,0x63,0x69,0x6e, +0x67,0x79,0x3d,0x22,0x32,0x6d,0x6d,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20, +0x20,0x20,0x76,0x69,0x73,0x69,0x62,0x6c,0x65,0x3d,0x22,0x74,0x72,0x75,0x65,0x22, +0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x75,0x6e,0x69,0x74,0x73,0x3d, +0x22,0x6d,0x6d,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x74,0x79, +0x70,0x65,0x3d,0x22,0x61,0x78,0x6f,0x6e,0x6f,0x6d,0x67,0x72,0x69,0x64,0x22,0x0d, +0x0a,0x20,0x20,0x20,0x20,0x2f,0x3e,0x0d,0x0a,0x20,0x20,0x3c,0x2f,0x73,0x6f,0x64, +0x69,0x70,0x6f,0x64,0x69,0x3a,0x6e,0x61,0x6d,0x65,0x64,0x76,0x69,0x65,0x77,0x0d, +0x0a,0x20,0x20,0x3e,0x0d,0x0a,0x20,0x20,0x3c,0x67,0x0d,0x0a,0x20,0x20,0x20,0x20, +0x20,0x20,0x69,0x64,0x3d,0x22,0x6c,0x61,0x79,0x65,0x72,0x31,0x22,0x0d,0x0a,0x20, +0x20,0x20,0x20,0x20,0x20,0x69,0x6e,0x6b,0x73,0x63,0x61,0x70,0x65,0x3a,0x6c,0x61, +0x62,0x65,0x6c,0x3d,0x22,0x43,0x61,0x70,0x61,0x20,0x31,0x22,0x0d,0x0a,0x20,0x20, +0x20,0x20,0x20,0x20,0x69,0x6e,0x6b,0x73,0x63,0x61,0x70,0x65,0x3a,0x67,0x72,0x6f, +0x75,0x70,0x6d,0x6f,0x64,0x65,0x3d,0x22,0x6c,0x61,0x79,0x65,0x72,0x22,0x0d,0x0a, +0x20,0x20,0x20,0x20,0x20,0x20,0x74,0x72,0x61,0x6e,0x73,0x66,0x6f,0x72,0x6d,0x3d, +0x22,0x74,0x72,0x61,0x6e,0x73,0x6c,0x61,0x74,0x65,0x28,0x2d,0x39,0x31,0x2e,0x31, +0x32,0x35,0x20,0x2d,0x37,0x39,0x2e,0x34,0x38,0x34,0x29,0x22,0x0d,0x0a,0x20,0x20, +0x20,0x20,0x3e,0x0d,0x0a,0x20,0x20,0x20,0x20,0x3c,0x70,0x61,0x74,0x68,0x0d,0x0a, +0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x64,0x3d,0x22,0x70,0x61,0x74,0x68, +0x33,0x32,0x39,0x30,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73, +0x74,0x79,0x6c,0x65,0x3d,0x22,0x66,0x69,0x6c,0x6c,0x3a,0x23,0x32,0x65,0x33,0x34, +0x33,0x36,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x64,0x3d,0x22, +0x6d,0x31,0x31,0x35,0x2e,0x31,0x33,0x20,0x33,0x32,0x36,0x2e,0x33,0x36,0x76,0x34, +0x30,0x2e,0x32,0x6c,0x32,0x35,0x2e,0x39,0x35,0x20,0x31,0x32,0x2e,0x31,0x38,0x20, +0x38,0x37,0x2e,0x33,0x35,0x2d,0x34,0x33,0x2e,0x32,0x35,0x20,0x31,0x2e,0x30,0x39, +0x2d,0x36,0x35,0x2e,0x34,0x31,0x2d,0x31,0x31,0x34,0x2e,0x33,0x39,0x20,0x35,0x36, +0x2e,0x32,0x38,0x7a,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x2f,0x3e,0x0d,0x0a,0x20, +0x20,0x20,0x20,0x3c,0x70,0x61,0x74,0x68,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20, +0x20,0x20,0x69,0x64,0x3d,0x22,0x70,0x61,0x74,0x68,0x33,0x32,0x38,0x38,0x22,0x0d, +0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x74,0x79,0x6c,0x65,0x3d,0x22, +0x66,0x69,0x6c,0x6c,0x3a,0x23,0x32,0x65,0x33,0x34,0x33,0x36,0x22,0x0d,0x0a,0x20, +0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x64,0x3d,0x22,0x6d,0x32,0x37,0x37,0x2e,0x35, +0x20,0x34,0x30,0x39,0x2e,0x37,0x39,0x76,0x34,0x30,0x2e,0x32,0x6c,0x32,0x35,0x2e, +0x39,0x34,0x20,0x31,0x32,0x2e,0x31,0x38,0x20,0x38,0x37,0x2e,0x33,0x35,0x2d,0x34, +0x33,0x2e,0x32,0x34,0x20,0x31,0x2e,0x31,0x2d,0x36,0x35,0x2e,0x34,0x32,0x2d,0x31, +0x31,0x34,0x2e,0x33,0x39,0x20,0x35,0x36,0x2e,0x32,0x38,0x7a,0x22,0x0d,0x0a,0x20, +0x20,0x20,0x20,0x2f,0x3e,0x0d,0x0a,0x20,0x20,0x20,0x20,0x3c,0x70,0x61,0x74,0x68, +0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x64,0x3d,0x22,0x70,0x61, +0x74,0x68,0x33,0x36,0x39,0x35,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20, +0x20,0x73,0x6f,0x64,0x69,0x70,0x6f,0x64,0x69,0x3a,0x6e,0x6f,0x64,0x65,0x74,0x79, +0x70,0x65,0x73,0x3d,0x22,0x63,0x63,0x63,0x63,0x63,0x63,0x63,0x63,0x22,0x0d,0x0a, +0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x74,0x79,0x6c,0x65,0x3d,0x22,0x66, +0x69,0x6c,0x6c,0x3a,0x75,0x72,0x6c,0x28,0x23,0x6c,0x69,0x6e,0x65,0x61,0x72,0x47, +0x72,0x61,0x64,0x69,0x65,0x6e,0x74,0x33,0x37,0x31,0x33,0x29,0x22,0x0d,0x0a,0x20, +0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x64,0x3d,0x22,0x6d,0x34,0x32,0x31,0x2e,0x31, +0x36,0x20,0x31,0x37,0x32,0x2e,0x32,0x31,0x63,0x32,0x30,0x2e,0x33,0x34,0x20,0x31, +0x30,0x2e,0x31,0x36,0x20,0x33,0x36,0x2e,0x37,0x32,0x20,0x34,0x31,0x2e,0x34,0x20, +0x33,0x36,0x2e,0x37,0x32,0x20,0x37,0x30,0x2e,0x30,0x34,0x76,0x31,0x36,0x37,0x2e, +0x35,0x6c,0x2d,0x31,0x30,0x36,0x2e,0x37,0x35,0x20,0x35,0x33,0x2e,0x36,0x38,0x2d, +0x31,0x35,0x32,0x2e,0x31,0x37,0x2d,0x31,0x38,0x33,0x2e,0x31,0x31,0x2d,0x39,0x32, +0x2d,0x31,0x34,0x39,0x2e,0x37,0x36,0x20,0x31,0x32,0x38,0x2e,0x37,0x32,0x2d,0x35, +0x31,0x2e,0x30,0x37,0x36,0x20,0x31,0x38,0x35,0x2e,0x34,0x38,0x20,0x39,0x32,0x2e, +0x37,0x32,0x36,0x7a,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x2f,0x3e,0x0d,0x0a,0x20, +0x20,0x20,0x20,0x3c,0x70,0x61,0x74,0x68,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20, +0x20,0x20,0x69,0x64,0x3d,0x22,0x70,0x61,0x74,0x68,0x33,0x36,0x38,0x35,0x22,0x0d, +0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x74,0x79,0x6c,0x65,0x3d,0x22, +0x66,0x69,0x6c,0x6c,0x3a,0x75,0x72,0x6c,0x28,0x23,0x6c,0x69,0x6e,0x65,0x61,0x72, +0x47,0x72,0x61,0x64,0x69,0x65,0x6e,0x74,0x33,0x37,0x30,0x33,0x29,0x22,0x0d,0x0a, +0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x64,0x3d,0x22,0x6d,0x33,0x31,0x33,0x2e, +0x33,0x34,0x20,0x32,0x32,0x35,0x2e,0x38,0x35,0x63,0x32,0x30,0x2e,0x33,0x34,0x20, +0x31,0x30,0x2e,0x31,0x37,0x20,0x33,0x36,0x2e,0x37,0x32,0x20,0x34,0x31,0x2e,0x34, +0x20,0x33,0x36,0x2e,0x37,0x32,0x20,0x37,0x30,0x2e,0x30,0x34,0x76,0x31,0x36,0x37, +0x2e,0x35,0x6c,0x2d,0x32,0x35,0x38,0x2e,0x39,0x33,0x2d,0x31,0x32,0x39,0x2e,0x34, +0x33,0x20,0x30,0x2e,0x30,0x30,0x34,0x2d,0x31,0x36,0x37,0x2e,0x35,0x63,0x30,0x2d, +0x32,0x38,0x2e,0x36,0x34,0x20,0x31,0x36,0x2e,0x33,0x38,0x36,0x2d,0x34,0x33,0x2e, +0x35,0x20,0x33,0x36,0x2e,0x37,0x31,0x36,0x2d,0x33,0x33,0x2e,0x33,0x33,0x6c,0x31, +0x38,0x35,0x2e,0x34,0x39,0x20,0x39,0x32,0x2e,0x37,0x32,0x7a,0x22,0x0d,0x0a,0x20, +0x20,0x20,0x20,0x2f,0x3e,0x0d,0x0a,0x20,0x20,0x20,0x20,0x3c,0x70,0x61,0x74,0x68, +0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x64,0x3d,0x22,0x70,0x61, +0x74,0x68,0x33,0x37,0x30,0x35,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20, +0x20,0x73,0x74,0x79,0x6c,0x65,0x3d,0x22,0x66,0x69,0x6c,0x6c,0x3a,0x75,0x72,0x6c, +0x28,0x23,0x6c,0x69,0x6e,0x65,0x61,0x72,0x47,0x72,0x61,0x64,0x69,0x65,0x6e,0x74, +0x33,0x37,0x30,0x33,0x29,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, +0x64,0x3d,0x22,0x6d,0x33,0x31,0x33,0x2e,0x33,0x34,0x20,0x32,0x32,0x35,0x2e,0x38, +0x35,0x63,0x32,0x30,0x2e,0x33,0x34,0x20,0x31,0x30,0x2e,0x31,0x37,0x20,0x33,0x36, +0x2e,0x37,0x32,0x20,0x34,0x31,0x2e,0x34,0x20,0x33,0x36,0x2e,0x37,0x32,0x20,0x37, +0x30,0x2e,0x30,0x34,0x76,0x31,0x36,0x37,0x2e,0x35,0x6c,0x2d,0x32,0x35,0x38,0x2e, +0x39,0x33,0x2d,0x31,0x32,0x39,0x2e,0x34,0x33,0x20,0x30,0x2e,0x30,0x30,0x34,0x2d, +0x31,0x36,0x37,0x2e,0x35,0x63,0x30,0x2d,0x32,0x38,0x2e,0x36,0x34,0x20,0x31,0x36, +0x2e,0x33,0x38,0x36,0x2d,0x34,0x33,0x2e,0x35,0x20,0x33,0x36,0x2e,0x37,0x31,0x36, +0x2d,0x33,0x33,0x2e,0x33,0x33,0x6c,0x31,0x38,0x35,0x2e,0x34,0x39,0x20,0x39,0x32, +0x2e,0x37,0x32,0x7a,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x2f,0x3e,0x0d,0x0a,0x20, +0x20,0x20,0x20,0x3c,0x72,0x65,0x63,0x74,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20, +0x20,0x20,0x69,0x64,0x3d,0x22,0x72,0x65,0x63,0x74,0x33,0x35,0x37,0x36,0x22,0x0d, +0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x74,0x79,0x6c,0x65,0x3d,0x22, +0x73,0x74,0x72,0x6f,0x6b,0x65,0x2d,0x6c,0x69,0x6e,0x65,0x6a,0x6f,0x69,0x6e,0x3a, +0x62,0x65,0x76,0x65,0x6c,0x3b,0x73,0x74,0x72,0x6f,0x6b,0x65,0x3a,0x75,0x72,0x6c, +0x28,0x23,0x6c,0x69,0x6e,0x65,0x61,0x72,0x47,0x72,0x61,0x64,0x69,0x65,0x6e,0x74, +0x33,0x35,0x38,0x30,0x29,0x3b,0x73,0x74,0x72,0x6f,0x6b,0x65,0x2d,0x6c,0x69,0x6e, +0x65,0x63,0x61,0x70,0x3a,0x72,0x6f,0x75,0x6e,0x64,0x3b,0x73,0x74,0x72,0x6f,0x6b, +0x65,0x2d,0x77,0x69,0x64,0x74,0x68,0x3a,0x32,0x2e,0x32,0x33,0x31,0x32,0x3b,0x66, +0x69,0x6c,0x6c,0x3a,0x75,0x72,0x6c,0x28,0x23,0x6c,0x69,0x6e,0x65,0x61,0x72,0x47, +0x72,0x61,0x64,0x69,0x65,0x6e,0x74,0x33,0x35,0x37,0x38,0x29,0x22,0x0d,0x0a,0x20, +0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x74,0x72,0x61,0x6e,0x73,0x66,0x6f,0x72,0x6d, +0x3d,0x22,0x6d,0x61,0x74,0x72,0x69,0x78,0x28,0x2d,0x2e,0x38,0x39,0x34,0x34,0x33, +0x20,0x2d,0x2e,0x34,0x34,0x37,0x32,0x31,0x20,0x2d,0x2e,0x38,0x39,0x34,0x34,0x33, +0x20,0x2e,0x34,0x34,0x37,0x32,0x31,0x20,0x30,0x20,0x30,0x29,0x22,0x0d,0x0a,0x20, +0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x79,0x3d,0x22,0x31,0x30,0x2e,0x37,0x31, +0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x68,0x65,0x69,0x67,0x68, +0x74,0x3d,0x22,0x33,0x30,0x2e,0x33,0x36,0x32,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20, +0x20,0x20,0x20,0x20,0x77,0x69,0x64,0x74,0x68,0x3d,0x22,0x32,0x31,0x33,0x2e,0x33, +0x39,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x79,0x3d,0x22,0x32, +0x34,0x2e,0x31,0x39,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x78, +0x3d,0x22,0x2d,0x34,0x34,0x30,0x2e,0x30,0x34,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20, +0x2f,0x3e,0x0d,0x0a,0x20,0x20,0x20,0x20,0x3c,0x72,0x65,0x63,0x74,0x0d,0x0a,0x20, +0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x64,0x3d,0x22,0x72,0x65,0x63,0x74,0x32, +0x34,0x35,0x39,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x79, +0x3d,0x22,0x31,0x30,0x2e,0x37,0x31,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20, +0x20,0x20,0x73,0x74,0x79,0x6c,0x65,0x3d,0x22,0x73,0x74,0x72,0x6f,0x6b,0x65,0x2d, +0x6c,0x69,0x6e,0x65,0x6a,0x6f,0x69,0x6e,0x3a,0x62,0x65,0x76,0x65,0x6c,0x3b,0x73, +0x74,0x72,0x6f,0x6b,0x65,0x3a,0x75,0x72,0x6c,0x28,0x23,0x6c,0x69,0x6e,0x65,0x61, +0x72,0x47,0x72,0x61,0x64,0x69,0x65,0x6e,0x74,0x32,0x34,0x36,0x33,0x29,0x3b,0x73, +0x74,0x72,0x6f,0x6b,0x65,0x2d,0x6c,0x69,0x6e,0x65,0x63,0x61,0x70,0x3a,0x72,0x6f, +0x75,0x6e,0x64,0x3b,0x73,0x74,0x72,0x6f,0x6b,0x65,0x2d,0x77,0x69,0x64,0x74,0x68, +0x3a,0x32,0x2e,0x32,0x33,0x31,0x32,0x3b,0x66,0x69,0x6c,0x6c,0x3a,0x75,0x72,0x6c, +0x28,0x23,0x6c,0x69,0x6e,0x65,0x61,0x72,0x47,0x72,0x61,0x64,0x69,0x65,0x6e,0x74, +0x32,0x34,0x36,0x31,0x29,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, +0x74,0x72,0x61,0x6e,0x73,0x66,0x6f,0x72,0x6d,0x3d,0x22,0x6d,0x61,0x74,0x72,0x69, +0x78,0x28,0x2d,0x2e,0x38,0x39,0x34,0x34,0x33,0x20,0x2d,0x2e,0x34,0x34,0x37,0x32, +0x31,0x20,0x2d,0x2e,0x38,0x39,0x34,0x34,0x33,0x20,0x2e,0x34,0x34,0x37,0x32,0x31, +0x20,0x30,0x20,0x30,0x29,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, +0x68,0x65,0x69,0x67,0x68,0x74,0x3d,0x22,0x33,0x30,0x2e,0x33,0x36,0x32,0x22,0x0d, +0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x77,0x69,0x64,0x74,0x68,0x3d,0x22, +0x32,0x31,0x33,0x2e,0x33,0x39,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20, +0x20,0x79,0x3d,0x22,0x2d,0x32,0x33,0x2e,0x38,0x38,0x35,0x22,0x0d,0x0a,0x20,0x20, +0x20,0x20,0x20,0x20,0x20,0x20,0x78,0x3d,0x22,0x2d,0x34,0x34,0x31,0x2e,0x31,0x36, +0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x2f,0x3e,0x0d,0x0a,0x20,0x20,0x20,0x20,0x3c, +0x70,0x61,0x74,0x68,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x64, +0x3d,0x22,0x70,0x61,0x74,0x68,0x32,0x34,0x36,0x35,0x22,0x0d,0x0a,0x20,0x20,0x20, +0x20,0x20,0x20,0x20,0x20,0x73,0x74,0x79,0x6c,0x65,0x3d,0x22,0x66,0x69,0x6c,0x74, +0x65,0x72,0x3a,0x75,0x72,0x6c,0x28,0x23,0x66,0x69,0x6c,0x74,0x65,0x72,0x33,0x32, +0x38,0x34,0x29,0x3b,0x66,0x69,0x6c,0x6c,0x3a,0x23,0x65,0x65,0x65,0x65,0x65,0x63, +0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x64,0x3d,0x22,0x6d,0x31, +0x31,0x35,0x2e,0x32,0x32,0x20,0x31,0x32,0x33,0x2e,0x39,0x34,0x63,0x2d,0x31,0x34, +0x2e,0x30,0x37,0x20,0x30,0x2e,0x31,0x39,0x2d,0x32,0x34,0x2e,0x30,0x39,0x35,0x20, +0x31,0x34,0x2e,0x31,0x33,0x2d,0x32,0x34,0x2e,0x30,0x39,0x35,0x20,0x33,0x36,0x2e, +0x35,0x76,0x31,0x34,0x63,0x30,0x2d,0x32,0x38,0x2e,0x36,0x34,0x20,0x31,0x36,0x2e, +0x33,0x38,0x35,0x2d,0x34,0x33,0x2e,0x34,0x37,0x20,0x33,0x36,0x2e,0x37,0x31,0x35, +0x2d,0x33,0x33,0x2e,0x33,0x31,0x6c,0x31,0x38,0x35,0x2e,0x35,0x20,0x39,0x32,0x2e, +0x37,0x32,0x63,0x32,0x30,0x2e,0x33,0x34,0x20,0x31,0x30,0x2e,0x31,0x37,0x20,0x33, +0x36,0x2e,0x37,0x32,0x20,0x34,0x31,0x2e,0x33,0x39,0x20,0x33,0x36,0x2e,0x37,0x32, +0x20,0x37,0x30,0x2e,0x30,0x33,0x76,0x2d,0x31,0x34,0x63,0x30,0x2d,0x32,0x38,0x2e, +0x36,0x34,0x2d,0x31,0x36,0x2e,0x33,0x38,0x2d,0x35,0x39,0x2e,0x38,0x36,0x2d,0x33, +0x36,0x2e,0x37,0x32,0x2d,0x37,0x30,0x2e,0x30,0x33,0x6c,0x2d,0x31,0x38,0x35,0x2e, +0x35,0x2d,0x39,0x32,0x2e,0x37,0x32,0x63,0x2d,0x34,0x2e,0x34,0x34,0x2d,0x32,0x2e, +0x32,0x32,0x2d,0x38,0x2e,0x36,0x38,0x2d,0x33,0x2e,0x32,0x34,0x2d,0x31,0x32,0x2e, +0x36,0x32,0x2d,0x33,0x2e,0x31,0x39,0x7a,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x2f, +0x3e,0x0d,0x0a,0x20,0x20,0x20,0x20,0x3c,0x70,0x61,0x74,0x68,0x0d,0x0a,0x20,0x20, +0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x64,0x3d,0x22,0x70,0x61,0x74,0x68,0x33,0x33, +0x31,0x37,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x74,0x79, +0x6c,0x65,0x3d,0x22,0x73,0x74,0x72,0x6f,0x6b,0x65,0x2d,0x6c,0x69,0x6e,0x65,0x6a, +0x6f,0x69,0x6e,0x3a,0x62,0x65,0x76,0x65,0x6c,0x3b,0x73,0x74,0x72,0x6f,0x6b,0x65, +0x3a,0x75,0x72,0x6c,0x28,0x23,0x6c,0x69,0x6e,0x65,0x61,0x72,0x47,0x72,0x61,0x64, +0x69,0x65,0x6e,0x74,0x33,0x33,0x34,0x33,0x29,0x3b,0x73,0x74,0x72,0x6f,0x6b,0x65, +0x2d,0x6c,0x69,0x6e,0x65,0x63,0x61,0x70,0x3a,0x72,0x6f,0x75,0x6e,0x64,0x3b,0x73, +0x74,0x72,0x6f,0x6b,0x65,0x2d,0x77,0x69,0x64,0x74,0x68,0x3a,0x32,0x2e,0x31,0x32, +0x39,0x34,0x3b,0x66,0x69,0x6c,0x6c,0x3a,0x23,0x34,0x39,0x34,0x63,0x34,0x61,0x22, +0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x64,0x3d,0x22,0x6d,0x33,0x39, +0x36,0x2e,0x35,0x33,0x20,0x32,0x36,0x31,0x2e,0x36,0x37,0x6c,0x2d,0x38,0x20,0x34, +0x76,0x31,0x35,0x39,0x2e,0x32,0x35,0x6c,0x38,0x2d,0x34,0x76,0x2d,0x31,0x35,0x39, +0x2e,0x32,0x35,0x7a,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x2f,0x3e,0x0d,0x0a,0x20, +0x20,0x20,0x20,0x3c,0x70,0x61,0x74,0x68,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20, +0x20,0x20,0x69,0x64,0x3d,0x22,0x70,0x61,0x74,0x68,0x33,0x33,0x34,0x35,0x22,0x0d, +0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x74,0x79,0x6c,0x65,0x3d,0x22, +0x73,0x74,0x72,0x6f,0x6b,0x65,0x2d,0x6c,0x69,0x6e,0x65,0x6a,0x6f,0x69,0x6e,0x3a, +0x62,0x65,0x76,0x65,0x6c,0x3b,0x73,0x74,0x72,0x6f,0x6b,0x65,0x3a,0x75,0x72,0x6c, +0x28,0x23,0x6c,0x69,0x6e,0x65,0x61,0x72,0x47,0x72,0x61,0x64,0x69,0x65,0x6e,0x74, +0x33,0x33,0x34,0x37,0x29,0x3b,0x73,0x74,0x72,0x6f,0x6b,0x65,0x2d,0x6c,0x69,0x6e, +0x65,0x63,0x61,0x70,0x3a,0x72,0x6f,0x75,0x6e,0x64,0x3b,0x73,0x74,0x72,0x6f,0x6b, +0x65,0x2d,0x77,0x69,0x64,0x74,0x68,0x3a,0x32,0x2e,0x31,0x32,0x39,0x34,0x3b,0x66, +0x69,0x6c,0x6c,0x3a,0x23,0x34,0x39,0x34,0x63,0x34,0x61,0x22,0x0d,0x0a,0x20,0x20, +0x20,0x20,0x20,0x20,0x20,0x20,0x64,0x3d,0x22,0x6d,0x34,0x32,0x33,0x2e,0x38,0x31, +0x20,0x32,0x34,0x39,0x2e,0x32,0x37,0x6c,0x2d,0x38,0x20,0x34,0x76,0x31,0x35,0x39, +0x2e,0x32,0x35,0x6c,0x38,0x2d,0x34,0x76,0x2d,0x31,0x35,0x39,0x2e,0x32,0x35,0x7a, +0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x2f,0x3e,0x0d,0x0a,0x20,0x20,0x20,0x20,0x3c, +0x67,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x64,0x3d,0x22,0x67, +0x33,0x33,0x35,0x39,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x74, +0x72,0x61,0x6e,0x73,0x66,0x6f,0x72,0x6d,0x3d,0x22,0x6d,0x61,0x74,0x72,0x69,0x78, +0x28,0x2e,0x36,0x39,0x35,0x33,0x32,0x20,0x30,0x20,0x30,0x20,0x2e,0x36,0x39,0x35, +0x33,0x32,0x20,0x32,0x39,0x36,0x2e,0x37,0x20,0x2d,0x31,0x35,0x38,0x2e,0x39,0x38, +0x29,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x3e,0x0d,0x0a,0x20,0x20,0x20, +0x20,0x20,0x20,0x3c,0x70,0x61,0x74,0x68,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20, +0x20,0x20,0x20,0x20,0x69,0x64,0x3d,0x22,0x70,0x61,0x74,0x68,0x33,0x33,0x34,0x39, +0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x64,0x3d,0x22, +0x6d,0x33,0x35,0x2e,0x34,0x34,0x31,0x20,0x37,0x33,0x34,0x2e,0x37,0x33,0x6c,0x33, +0x35,0x2e,0x34,0x34,0x31,0x20,0x31,0x37,0x2e,0x37,0x32,0x20,0x37,0x30,0x2e,0x38, +0x37,0x38,0x2d,0x33,0x35,0x2e,0x34,0x34,0x2d,0x33,0x35,0x2e,0x34,0x34,0x2d,0x31, +0x37,0x2e,0x37,0x31,0x2d,0x37,0x30,0x2e,0x38,0x37,0x39,0x20,0x33,0x35,0x2e,0x34, +0x33,0x7a,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73, +0x6f,0x64,0x69,0x70,0x6f,0x64,0x69,0x3a,0x6e,0x6f,0x64,0x65,0x74,0x79,0x70,0x65, +0x73,0x3d,0x22,0x63,0x63,0x63,0x63,0x63,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20, +0x20,0x20,0x20,0x20,0x20,0x73,0x74,0x79,0x6c,0x65,0x3d,0x22,0x66,0x69,0x6c,0x6c, +0x3a,0x23,0x34,0x62,0x34,0x65,0x34,0x63,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20, +0x20,0x20,0x20,0x20,0x20,0x74,0x72,0x61,0x6e,0x73,0x66,0x6f,0x72,0x6d,0x3d,0x22, +0x74,0x72,0x61,0x6e,0x73,0x6c,0x61,0x74,0x65,0x28,0x38,0x36,0x2e,0x30,0x36,0x32, +0x20,0x31,0x30,0x33,0x2e,0x38,0x38,0x29,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20, +0x20,0x2f,0x3e,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x3c,0x70,0x61,0x74,0x68, +0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x64,0x3d,0x22, +0x70,0x61,0x74,0x68,0x33,0x33,0x35,0x33,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20, +0x20,0x20,0x20,0x20,0x20,0x73,0x6f,0x64,0x69,0x70,0x6f,0x64,0x69,0x3a,0x6e,0x6f, +0x64,0x65,0x74,0x79,0x70,0x65,0x73,0x3d,0x22,0x63,0x63,0x63,0x63,0x63,0x22,0x0d, +0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x74,0x79,0x6c,0x65, +0x3d,0x22,0x66,0x69,0x6c,0x6c,0x3a,0x23,0x32,0x65,0x33,0x34,0x33,0x36,0x22,0x0d, +0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x64,0x3d,0x22,0x6d,0x31, +0x35,0x36,0x2e,0x39,0x34,0x20,0x38,0x34,0x36,0x2e,0x33,0x39,0x76,0x39,0x2e,0x39, +0x34,0x6c,0x37,0x30,0x2e,0x38,0x39,0x2d,0x33,0x35,0x2e,0x34,0x34,0x76,0x2d,0x39, +0x2e,0x39,0x34,0x6c,0x2d,0x37,0x30,0x2e,0x38,0x39,0x20,0x33,0x35,0x2e,0x34,0x34, +0x7a,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x2f,0x3e,0x0d,0x0a,0x20,0x20, +0x20,0x20,0x20,0x20,0x3c,0x70,0x61,0x74,0x68,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20, +0x20,0x20,0x20,0x20,0x20,0x69,0x64,0x3d,0x22,0x70,0x61,0x74,0x68,0x33,0x33,0x35, +0x35,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x6f, +0x64,0x69,0x70,0x6f,0x64,0x69,0x3a,0x6e,0x6f,0x64,0x65,0x74,0x79,0x70,0x65,0x73, +0x3d,0x22,0x63,0x63,0x63,0x63,0x63,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20, +0x20,0x20,0x20,0x20,0x73,0x74,0x79,0x6c,0x65,0x3d,0x22,0x66,0x69,0x6c,0x6c,0x3a, +0x23,0x34,0x62,0x34,0x65,0x34,0x63,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20, +0x20,0x20,0x20,0x20,0x64,0x3d,0x22,0x6d,0x31,0x32,0x31,0x2e,0x35,0x20,0x38,0x31, +0x35,0x2e,0x38,0x36,0x6c,0x33,0x35,0x2e,0x34,0x34,0x20,0x33,0x30,0x2e,0x37,0x32, +0x20,0x37,0x30,0x2e,0x38,0x39,0x2d,0x33,0x35,0x2e,0x34,0x34,0x2d,0x33,0x35,0x2e, +0x34,0x34,0x2d,0x33,0x30,0x2e,0x37,0x31,0x2d,0x37,0x30,0x2e,0x38,0x39,0x20,0x33, +0x35,0x2e,0x34,0x33,0x7a,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x2f,0x3e, +0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x3c,0x70,0x61,0x74,0x68,0x0d,0x0a,0x20, +0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x64,0x3d,0x22,0x70,0x61,0x74, +0x68,0x33,0x33,0x35,0x37,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, +0x20,0x20,0x64,0x3d,0x22,0x6d,0x33,0x35,0x2e,0x34,0x34,0x31,0x20,0x37,0x31,0x30, +0x2e,0x39,0x33,0x76,0x32,0x33,0x2e,0x38,0x6c,0x33,0x35,0x2e,0x34,0x34,0x31,0x20, +0x31,0x37,0x2e,0x37,0x32,0x76,0x2d,0x39,0x2e,0x35,0x32,0x6c,0x2d,0x33,0x35,0x2e, +0x34,0x34,0x31,0x2d,0x33,0x32,0x7a,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20, +0x20,0x20,0x20,0x20,0x73,0x6f,0x64,0x69,0x70,0x6f,0x64,0x69,0x3a,0x6e,0x6f,0x64, +0x65,0x74,0x79,0x70,0x65,0x73,0x3d,0x22,0x63,0x63,0x63,0x63,0x63,0x22,0x0d,0x0a, +0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x74,0x79,0x6c,0x65,0x3d, +0x22,0x66,0x69,0x6c,0x6c,0x3a,0x23,0x35,0x35,0x35,0x37,0x35,0x33,0x22,0x0d,0x0a, +0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x74,0x72,0x61,0x6e,0x73,0x66, +0x6f,0x72,0x6d,0x3d,0x22,0x74,0x72,0x61,0x6e,0x73,0x6c,0x61,0x74,0x65,0x28,0x38, +0x36,0x2e,0x30,0x36,0x32,0x20,0x31,0x30,0x33,0x2e,0x38,0x38,0x29,0x22,0x0d,0x0a, +0x20,0x20,0x20,0x20,0x20,0x20,0x2f,0x3e,0x0d,0x0a,0x20,0x20,0x20,0x20,0x3c,0x2f, +0x67,0x0d,0x0a,0x20,0x20,0x20,0x20,0x3e,0x0d,0x0a,0x20,0x20,0x20,0x20,0x3c,0x70, +0x61,0x74,0x68,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x64,0x3d, +0x22,0x70,0x61,0x74,0x68,0x33,0x33,0x36,0x35,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20, +0x20,0x20,0x20,0x20,0x73,0x74,0x79,0x6c,0x65,0x3d,0x22,0x6f,0x70,0x61,0x63,0x69, +0x74,0x79,0x3a,0x2e,0x36,0x3b,0x66,0x69,0x6c,0x74,0x65,0x72,0x3a,0x75,0x72,0x6c, +0x28,0x23,0x66,0x69,0x6c,0x74,0x65,0x72,0x33,0x34,0x30,0x37,0x29,0x3b,0x66,0x69, +0x6c,0x6c,0x3a,0x23,0x35,0x35,0x35,0x37,0x35,0x33,0x22,0x0d,0x0a,0x20,0x20,0x20, +0x20,0x20,0x20,0x20,0x20,0x64,0x3d,0x22,0x6d,0x33,0x38,0x32,0x2e,0x33,0x34,0x20, +0x34,0x32,0x34,0x2e,0x31,0x34,0x6c,0x32,0x34,0x2e,0x30,0x34,0x20,0x31,0x32,0x2e, +0x30,0x33,0x2d,0x31,0x35,0x2e,0x30,0x36,0x20,0x36,0x2e,0x31,0x2d,0x38,0x2e,0x39, +0x38,0x2d,0x31,0x38,0x2e,0x31,0x33,0x7a,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x2f, +0x3e,0x0d,0x0a,0x20,0x20,0x20,0x20,0x3c,0x70,0x61,0x74,0x68,0x0d,0x0a,0x20,0x20, +0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x64,0x3d,0x22,0x70,0x61,0x74,0x68,0x33,0x34, +0x31,0x31,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x6f,0x64, +0x69,0x70,0x6f,0x64,0x69,0x3a,0x6e,0x6f,0x64,0x65,0x74,0x79,0x70,0x65,0x73,0x3d, +0x22,0x63,0x63,0x63,0x63,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, +0x73,0x74,0x79,0x6c,0x65,0x3d,0x22,0x6f,0x70,0x61,0x63,0x69,0x74,0x79,0x3a,0x2e, +0x39,0x3b,0x66,0x69,0x6c,0x6c,0x3a,0x75,0x72,0x6c,0x28,0x23,0x6c,0x69,0x6e,0x65, +0x61,0x72,0x47,0x72,0x61,0x64,0x69,0x65,0x6e,0x74,0x33,0x34,0x32,0x37,0x29,0x22, +0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x64,0x3d,0x22,0x6d,0x32,0x33, +0x30,0x2e,0x30,0x36,0x20,0x39,0x35,0x2e,0x33,0x31,0x33,0x6c,0x2d,0x30,0x2e,0x30, +0x35,0x20,0x32,0x32,0x2e,0x31,0x30,0x37,0x20,0x39,0x33,0x2e,0x34,0x38,0x20,0x32, +0x34,0x2e,0x33,0x35,0x2d,0x39,0x33,0x2e,0x34,0x33,0x2d,0x34,0x36,0x2e,0x34,0x35, +0x37,0x7a,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x2f,0x3e,0x0d,0x0a,0x20,0x20,0x20, +0x20,0x3c,0x70,0x61,0x74,0x68,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, +0x69,0x64,0x3d,0x22,0x70,0x61,0x74,0x68,0x33,0x34,0x32,0x39,0x22,0x0d,0x0a,0x20, +0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x6f,0x64,0x69,0x70,0x6f,0x64,0x69,0x3a, +0x6e,0x6f,0x64,0x65,0x74,0x79,0x70,0x65,0x73,0x3d,0x22,0x63,0x63,0x63,0x63,0x22, +0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x74,0x79,0x6c,0x65,0x3d, +0x22,0x6f,0x70,0x61,0x63,0x69,0x74,0x79,0x3a,0x2e,0x39,0x3b,0x66,0x69,0x6c,0x6c, +0x3a,0x75,0x72,0x6c,0x28,0x23,0x6c,0x69,0x6e,0x65,0x61,0x72,0x47,0x72,0x61,0x64, +0x69,0x65,0x6e,0x74,0x33,0x34,0x33,0x31,0x29,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20, +0x20,0x20,0x20,0x20,0x64,0x3d,0x22,0x6d,0x31,0x38,0x38,0x2e,0x33,0x34,0x20,0x31, +0x31,0x36,0x2e,0x35,0x33,0x6c,0x2d,0x30,0x2e,0x30,0x35,0x20,0x32,0x32,0x2e,0x31, +0x20,0x39,0x33,0x2e,0x34,0x38,0x20,0x32,0x34,0x2e,0x33,0x35,0x2d,0x39,0x33,0x2e, +0x34,0x33,0x2d,0x34,0x36,0x2e,0x34,0x35,0x7a,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20, +0x2f,0x3e,0x0d,0x0a,0x20,0x20,0x20,0x20,0x3c,0x70,0x61,0x74,0x68,0x0d,0x0a,0x20, +0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x69,0x64,0x3d,0x22,0x70,0x61,0x74,0x68,0x33, +0x34,0x34,0x32,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x73,0x74, +0x79,0x6c,0x65,0x3d,0x22,0x6f,0x70,0x61,0x63,0x69,0x74,0x79,0x3a,0x2e,0x39,0x3b, +0x66,0x69,0x6c,0x6c,0x3a,0x75,0x72,0x6c,0x28,0x23,0x6c,0x69,0x6e,0x65,0x61,0x72, +0x47,0x72,0x61,0x64,0x69,0x65,0x6e,0x74,0x33,0x34,0x36,0x36,0x29,0x22,0x0d,0x0a, +0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x64,0x3d,0x22,0x6d,0x33,0x32,0x36,0x2e, +0x30,0x32,0x20,0x34,0x34,0x35,0x2e,0x38,0x35,0x6c,0x31,0x38,0x2e,0x33,0x39,0x20, +0x31,0x31,0x2e,0x33,0x32,0x76,0x2d,0x31,0x39,0x2e,0x31,0x6c,0x2d,0x31,0x38,0x2e, +0x33,0x39,0x20,0x37,0x2e,0x37,0x38,0x7a,0x22,0x0d,0x0a,0x20,0x20,0x20,0x20,0x2f, +0x3e,0x0d,0x0a,0x20,0x20,0x3c,0x2f,0x67,0x0d,0x0a,0x20,0x20,0x3e,0x0d,0x0a,0x20, +0x20,0x3e,0x0d,0x0a,0x3c,0x2f,0x73,0x76,0x67,0x0d,0x0a,0x3e,0x0d,0x0a,}; + +static const unsigned int dummy_align__404_html = 1; +static const unsigned char data__404_html[] = { +/* /404.html (10 chars) */ +0x2f,0x34,0x30,0x34,0x2e,0x68,0x74,0x6d,0x6c,0x00,0x00,0x00, + +/* HTTP header */ +/* "HTTP/1.0 404 File not found +" (29 bytes) */ +0x48,0x54,0x54,0x50,0x2f,0x31,0x2e,0x30,0x20,0x34,0x30,0x34,0x20,0x46,0x69,0x6c, +0x65,0x20,0x6e,0x6f,0x74,0x20,0x66,0x6f,0x75,0x6e,0x64,0x0d,0x0a, +/* "Server: lwIP/1.3.1 (http://savannah.nongnu.org/projects/lwip) +" (63 bytes) */ +0x53,0x65,0x72,0x76,0x65,0x72,0x3a,0x20,0x6c,0x77,0x49,0x50,0x2f,0x31,0x2e,0x33, +0x2e,0x31,0x20,0x28,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x73,0x61,0x76,0x61,0x6e, +0x6e,0x61,0x68,0x2e,0x6e,0x6f,0x6e,0x67,0x6e,0x75,0x2e,0x6f,0x72,0x67,0x2f,0x70, +0x72,0x6f,0x6a,0x65,0x63,0x74,0x73,0x2f,0x6c,0x77,0x69,0x70,0x29,0x0d,0x0a, +/* "Content-type: text/html + +" (27 bytes) */ +0x43,0x6f,0x6e,0x74,0x65,0x6e,0x74,0x2d,0x74,0x79,0x70,0x65,0x3a,0x20,0x74,0x65, +0x78,0x74,0x2f,0x68,0x74,0x6d,0x6c,0x0d,0x0a,0x0d,0x0a, +/* raw file data (119 bytes) */ +0x3c,0x68,0x74,0x6d,0x6c,0x3e,0x0a,0x3c,0x68,0x65,0x61,0x64,0x3e,0x3c,0x74,0x69, +0x74,0x6c,0x65,0x3e,0x45,0x78,0x61,0x6d,0x70,0x6c,0x65,0x3c,0x2f,0x74,0x69,0x74, +0x6c,0x65,0x3e,0x3c,0x2f,0x68,0x65,0x61,0x64,0x3e,0x0a,0x3c,0x62,0x6f,0x64,0x79, +0x20,0x62,0x67,0x63,0x6f,0x6c,0x6f,0x72,0x3d,0x22,0x77,0x68,0x69,0x74,0x65,0x22, +0x20,0x74,0x65,0x78,0x74,0x3d,0x22,0x62,0x6c,0x61,0x63,0x6b,0x22,0x3e,0x0a,0x3c, +0x48,0x31,0x3e,0x50,0x41,0x47,0x45,0x20,0x4e,0x4f,0x54,0x20,0x46,0x4f,0x55,0x4e, +0x44,0x3c,0x2f,0x48,0x31,0x3e,0x0a,0x3c,0x2f,0x62,0x6f,0x64,0x79,0x3e,0x0a,0x3c, +0x2f,0x68,0x74,0x6d,0x6c,0x3e,0x0a,}; + +static const unsigned int dummy_align__index_html = 2; +static const unsigned char data__index_html[] = { +/* /index.html (12 chars) */ +0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x68,0x74,0x6d,0x6c,0x00, + +/* HTTP header */ +/* "HTTP/1.0 200 OK +" (17 bytes) */ +0x48,0x54,0x54,0x50,0x2f,0x31,0x2e,0x30,0x20,0x32,0x30,0x30,0x20,0x4f,0x4b,0x0d, +0x0a, +/* "Server: lwIP/1.3.1 (http://savannah.nongnu.org/projects/lwip) +" (63 bytes) */ +0x53,0x65,0x72,0x76,0x65,0x72,0x3a,0x20,0x6c,0x77,0x49,0x50,0x2f,0x31,0x2e,0x33, +0x2e,0x31,0x20,0x28,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x73,0x61,0x76,0x61,0x6e, +0x6e,0x61,0x68,0x2e,0x6e,0x6f,0x6e,0x67,0x6e,0x75,0x2e,0x6f,0x72,0x67,0x2f,0x70, +0x72,0x6f,0x6a,0x65,0x63,0x74,0x73,0x2f,0x6c,0x77,0x69,0x70,0x29,0x0d,0x0a, +/* "Content-type: text/html + +" (27 bytes) */ +0x43,0x6f,0x6e,0x74,0x65,0x6e,0x74,0x2d,0x74,0x79,0x70,0x65,0x3a,0x20,0x74,0x65, +0x78,0x74,0x2f,0x68,0x74,0x6d,0x6c,0x0d,0x0a,0x0d,0x0a, +/* raw file data (2302 bytes) */ +0x3c,0x68,0x74,0x6d,0x6c,0x3e,0x0d,0x0a,0x3c,0x68,0x65,0x61,0x64,0x3e,0x3c,0x74, +0x69,0x74,0x6c,0x65,0x3e,0x54,0x6f,0x61,0x73,0x74,0x65,0x72,0x20,0x45,0x78,0x61, +0x6d,0x70,0x6c,0x65,0x3c,0x2f,0x74,0x69,0x74,0x6c,0x65,0x3e,0x0d,0x0a,0x0d,0x0a, +0x3c,0x73,0x74,0x79,0x6c,0x65,0x3e,0x0d,0x0a,0x2e,0x72,0x64,0x69,0x76,0x20,0x7b, +0x0d,0x0a,0x09,0x68,0x65,0x69,0x67,0x68,0x74,0x3a,0x20,0x32,0x34,0x30,0x70,0x78, +0x3b,0x0d,0x0a,0x09,0x77,0x69,0x64,0x74,0x68,0x3a,0x20,0x31,0x35,0x30,0x70,0x78, +0x3b,0x0d,0x0a,0x09,0x62,0x6f,0x72,0x64,0x65,0x72,0x2d,0x72,0x61,0x64,0x69,0x75, +0x73,0x3a,0x20,0x35,0x70,0x78,0x3b,0x0d,0x0a,0x20,0x20,0x20,0x20,0x2d,0x6d,0x6f, +0x7a,0x2d,0x62,0x6f,0x72,0x64,0x65,0x72,0x2d,0x72,0x61,0x64,0x69,0x75,0x73,0x3a, +0x20,0x35,0x70,0x78,0x20,0x35,0x70,0x78,0x20,0x35,0x70,0x78,0x20,0x35,0x70,0x78, +0x3b,0x0d,0x0a,0x20,0x20,0x20,0x20,0x2d,0x77,0x65,0x62,0x6b,0x69,0x74,0x2d,0x62, +0x6f,0x72,0x64,0x65,0x72,0x2d,0x72,0x61,0x64,0x69,0x75,0x73,0x3a,0x20,0x35,0x70, +0x78,0x20,0x35,0x70,0x78,0x20,0x35,0x70,0x78,0x20,0x35,0x70,0x78,0x3b,0x0d,0x0a, +0x09,0x62,0x6f,0x72,0x64,0x65,0x72,0x3a,0x20,0x31,0x70,0x78,0x20,0x73,0x6f,0x6c, +0x69,0x64,0x3b,0x0d,0x0a,0x09,0x64,0x69,0x73,0x70,0x6c,0x61,0x79,0x3a,0x20,0x74, +0x61,0x62,0x6c,0x65,0x2d,0x63,0x65,0x6c,0x6c,0x3b,0x0d,0x0a,0x09,0x76,0x65,0x72, +0x74,0x69,0x63,0x61,0x6c,0x2d,0x61,0x6c,0x69,0x67,0x6e,0x3a,0x20,0x6d,0x69,0x64, +0x64,0x6c,0x65,0x3b,0x0d,0x0a,0x09,0x70,0x61,0x64,0x64,0x69,0x6e,0x67,0x3a,0x20, +0x35,0x70,0x78,0x3b,0x0d,0x0a,0x09,0x74,0x65,0x78,0x74,0x2d,0x61,0x6c,0x69,0x67, +0x6e,0x3a,0x20,0x63,0x65,0x6e,0x74,0x65,0x72,0x3b,0x0d,0x0a,0x7d,0x0d,0x0a,0x3c, +0x2f,0x73,0x74,0x79,0x6c,0x65,0x3e,0x0d,0x0a,0x0d,0x0a,0x3c,0x73,0x63,0x72,0x69, +0x70,0x74,0x20,0x73,0x72,0x63,0x3d,0x22,0x2f,0x7a,0x65,0x70,0x74,0x6f,0x2e,0x6d, +0x69,0x6e,0x2e,0x6a,0x73,0x22,0x3e,0x3c,0x2f,0x73,0x63,0x72,0x69,0x70,0x74,0x3e, +0x0d,0x0a,0x0d,0x0a,0x3c,0x73,0x63,0x72,0x69,0x70,0x74,0x3e,0x0d,0x0a,0x0d,0x0a, +0x76,0x61,0x72,0x20,0x70,0x6f,0x6c,0x6c,0x69,0x6e,0x67,0x45,0x72,0x72,0x6f,0x72, +0x20,0x3d,0x20,0x66,0x61,0x6c,0x73,0x65,0x3b,0x0d,0x0a,0x0d,0x0a,0x66,0x75,0x6e, +0x63,0x74,0x69,0x6f,0x6e,0x20,0x64,0x6f,0x55,0x70,0x64,0x61,0x74,0x65,0x28,0x73, +0x74,0x61,0x74,0x65,0x29,0x0d,0x0a,0x7b,0x0d,0x0a,0x09,0x64,0x6f,0x63,0x75,0x6d, +0x65,0x6e,0x74,0x2e,0x67,0x65,0x74,0x45,0x6c,0x65,0x6d,0x65,0x6e,0x74,0x42,0x79, +0x49,0x64,0x28,0x22,0x64,0x65,0x76,0x73,0x74,0x61,0x74,0x65,0x22,0x29,0x2e,0x69, +0x6e,0x6e,0x65,0x72,0x48,0x54,0x4d,0x4c,0x20,0x3d,0x20,0x27,0x27,0x20,0x2b,0x20, +0x28,0x70,0x6f,0x6c,0x6c,0x69,0x6e,0x67,0x45,0x72,0x72,0x6f,0x72,0x20,0x3f,0x20, +0x27,0x3c,0x66,0x6f,0x6e,0x74,0x20,0x63,0x6f,0x6c,0x6f,0x72,0x3d,0x22,0x72,0x65, +0x64,0x22,0x3e,0x4c,0x69,0x6e,0x6b,0x20,0x65,0x72,0x72,0x6f,0x72,0x3c,0x2f,0x66, +0x6f,0x6e,0x74,0x3e,0x27,0x20,0x3a,0x20,0x27,0x43,0x6f,0x6e,0x6e,0x65,0x63,0x74, +0x65,0x64,0x27,0x29,0x3b,0x0d,0x0a,0x09,0x69,0x66,0x20,0x28,0x70,0x6f,0x6c,0x6c, +0x69,0x6e,0x67,0x45,0x72,0x72,0x6f,0x72,0x29,0x20,0x72,0x65,0x74,0x75,0x72,0x6e, +0x3b,0x0d,0x0a,0x0d,0x0a,0x09,0x64,0x6f,0x63,0x75,0x6d,0x65,0x6e,0x74,0x2e,0x67, +0x65,0x74,0x45,0x6c,0x65,0x6d,0x65,0x6e,0x74,0x42,0x79,0x49,0x64,0x28,0x22,0x73, +0x79,0x73,0x74,0x69,0x63,0x6b,0x22,0x29,0x2e,0x69,0x6e,0x6e,0x65,0x72,0x48,0x54, +0x4d,0x4c,0x20,0x3d,0x20,0x27,0x27,0x20,0x2b,0x20,0x28,0x73,0x74,0x61,0x74,0x65, +0x2e,0x73,0x79,0x73,0x74,0x69,0x63,0x6b,0x20,0x2f,0x20,0x31,0x30,0x30,0x30,0x29, +0x20,0x2b,0x20,0x27,0x20,0x73,0x65,0x63,0x6f,0x6e,0x64,0x73,0x27,0x3b,0x0d,0x0a, +0x09,0x64,0x6f,0x63,0x75,0x6d,0x65,0x6e,0x74,0x2e,0x67,0x65,0x74,0x45,0x6c,0x65, +0x6d,0x65,0x6e,0x74,0x42,0x79,0x49,0x64,0x28,0x22,0x61,0x6c,0x70,0x68,0x61,0x22, +0x29,0x2e,0x63,0x68,0x65,0x63,0x6b,0x65,0x64,0x20,0x3d,0x20,0x73,0x74,0x61,0x74, +0x65,0x2e,0x75,0x73,0x65,0x72,0x2e,0x61,0x20,0x3d,0x3d,0x20,0x31,0x3b,0x0d,0x0a, +0x09,0x64,0x6f,0x63,0x75,0x6d,0x65,0x6e,0x74,0x2e,0x67,0x65,0x74,0x45,0x6c,0x65, +0x6d,0x65,0x6e,0x74,0x42,0x79,0x49,0x64,0x28,0x22,0x62,0x72,0x61,0x76,0x6f,0x22, +0x29,0x2e,0x63,0x68,0x65,0x63,0x6b,0x65,0x64,0x20,0x3d,0x20,0x73,0x74,0x61,0x74, +0x65,0x2e,0x75,0x73,0x65,0x72,0x2e,0x62,0x20,0x3d,0x3d,0x20,0x31,0x3b,0x0d,0x0a, +0x09,0x64,0x6f,0x63,0x75,0x6d,0x65,0x6e,0x74,0x2e,0x67,0x65,0x74,0x45,0x6c,0x65, +0x6d,0x65,0x6e,0x74,0x42,0x79,0x49,0x64,0x28,0x22,0x63,0x68,0x61,0x72,0x6c,0x69, +0x65,0x22,0x29,0x2e,0x63,0x68,0x65,0x63,0x6b,0x65,0x64,0x20,0x3d,0x20,0x73,0x74, +0x61,0x74,0x65,0x2e,0x75,0x73,0x65,0x72,0x2e,0x63,0x20,0x3d,0x3d,0x20,0x31,0x3b, +0x0d,0x0a,0x7d,0x0d,0x0a,0x0d,0x0a,0x76,0x61,0x72,0x20,0x73,0x65,0x6e,0x64,0x53, +0x74,0x61,0x74,0x65,0x52,0x65,0x71,0x75,0x65,0x73,0x74,0x20,0x3d,0x20,0x66,0x75, +0x6e,0x63,0x74,0x69,0x6f,0x6e,0x20,0x28,0x29,0x0d,0x0a,0x7b,0x0d,0x0a,0x09,0x24, +0x2e,0x61,0x6a,0x61,0x78,0x28,0x7b,0x0d,0x0a,0x09,0x09,0x75,0x72,0x6c,0x3a,0x20, +0x22,0x2f,0x73,0x74,0x61,0x74,0x65,0x2e,0x63,0x67,0x69,0x22,0x2c,0x0d,0x0a,0x09, +0x09,0x74,0x69,0x6d,0x65,0x6f,0x75,0x74,0x3a,0x20,0x32,0x30,0x30,0x30,0x2c,0x0d, +0x0a,0x09,0x09,0x73,0x75,0x63,0x63,0x65,0x73,0x73,0x3a,0x20,0x66,0x75,0x6e,0x63, +0x74,0x69,0x6f,0x6e,0x28,0x64,0x61,0x74,0x61,0x29,0x0d,0x0a,0x09,0x09,0x7b,0x0d, +0x0a,0x09,0x09,0x09,0x73,0x65,0x74,0x54,0x69,0x6d,0x65,0x6f,0x75,0x74,0x28,0x73, +0x65,0x6e,0x64,0x53,0x74,0x61,0x74,0x65,0x52,0x65,0x71,0x75,0x65,0x73,0x74,0x2c, +0x20,0x32,0x30,0x30,0x29,0x3b,0x0d,0x0a,0x09,0x09,0x09,0x70,0x6f,0x6c,0x6c,0x69, +0x6e,0x67,0x45,0x72,0x72,0x6f,0x72,0x20,0x3d,0x20,0x66,0x61,0x6c,0x73,0x65,0x3b, +0x0d,0x0a,0x09,0x09,0x09,0x64,0x6f,0x55,0x70,0x64,0x61,0x74,0x65,0x28,0x64,0x61, +0x74,0x61,0x29,0x3b,0x0d,0x0a,0x09,0x09,0x7d,0x2c,0x0d,0x0a,0x09,0x09,0x65,0x72, +0x72,0x6f,0x72,0x3a,0x20,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x64,0x61, +0x74,0x61,0x29,0x0d,0x0a,0x09,0x09,0x7b,0x0d,0x0a,0x09,0x09,0x09,0x73,0x65,0x74, +0x54,0x69,0x6d,0x65,0x6f,0x75,0x74,0x28,0x73,0x65,0x6e,0x64,0x53,0x74,0x61,0x74, +0x65,0x52,0x65,0x71,0x75,0x65,0x73,0x74,0x2c,0x20,0x31,0x30,0x30,0x30,0x29,0x3b, +0x0d,0x0a,0x09,0x09,0x09,0x70,0x6f,0x6c,0x6c,0x69,0x6e,0x67,0x45,0x72,0x72,0x6f, +0x72,0x20,0x3d,0x20,0x74,0x72,0x75,0x65,0x3b,0x0d,0x0a,0x09,0x09,0x09,0x64,0x6f, +0x55,0x70,0x64,0x61,0x74,0x65,0x28,0x64,0x61,0x74,0x61,0x29,0x3b,0x0d,0x0a,0x09, +0x09,0x7d,0x2c,0x0d,0x0a,0x09,0x09,0x64,0x61,0x74,0x61,0x54,0x79,0x70,0x65,0x3a, +0x20,0x22,0x6a,0x73,0x6f,0x6e,0x22,0x0d,0x0a,0x09,0x7d,0x29,0x3b,0x0d,0x0a,0x7d, +0x0d,0x0a,0x0d,0x0a,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x20,0x63,0x74,0x6c, +0x28,0x64,0x61,0x74,0x61,0x6f,0x62,0x6a,0x29,0x0d,0x0a,0x7b,0x0d,0x0a,0x09,0x24, +0x2e,0x61,0x6a,0x61,0x78,0x28,0x7b,0x0d,0x0a,0x09,0x09,0x75,0x72,0x6c,0x3a,0x20, +0x22,0x2f,0x63,0x74,0x6c,0x2e,0x63,0x67,0x69,0x22,0x2c,0x0d,0x0a,0x09,0x09,0x64, +0x61,0x74,0x61,0x3a,0x20,0x64,0x61,0x74,0x61,0x6f,0x62,0x6a,0x2c,0x0d,0x0a,0x09, +0x09,0x73,0x75,0x63,0x63,0x65,0x73,0x73,0x3a,0x20,0x66,0x75,0x6e,0x63,0x74,0x69, +0x6f,0x6e,0x28,0x64,0x61,0x74,0x61,0x29,0x20,0x7b,0x20,0x64,0x6f,0x55,0x70,0x64, +0x61,0x74,0x65,0x28,0x64,0x61,0x74,0x61,0x29,0x3b,0x20,0x7d,0x2c,0x0d,0x0a,0x09, +0x09,0x64,0x61,0x74,0x61,0x54,0x79,0x70,0x65,0x3a,0x20,0x22,0x6a,0x73,0x6f,0x6e, +0x22,0x0d,0x0a,0x09,0x7d,0x29,0x3b,0x0d,0x0a,0x7d,0x0d,0x0a,0x0d,0x0a,0x66,0x75, +0x6e,0x63,0x74,0x69,0x6f,0x6e,0x20,0x64,0x6f,0x63,0x52,0x65,0x61,0x64,0x79,0x28, +0x29,0x0d,0x0a,0x7b,0x0d,0x0a,0x09,0x73,0x65,0x6e,0x64,0x53,0x74,0x61,0x74,0x65, +0x52,0x65,0x71,0x75,0x65,0x73,0x74,0x28,0x29,0x3b,0x0d,0x0a,0x7d,0x0d,0x0a,0x0d, +0x0a,0x24,0x28,0x64,0x6f,0x63,0x75,0x6d,0x65,0x6e,0x74,0x29,0x2e,0x72,0x65,0x61, +0x64,0x79,0x28,0x64,0x6f,0x63,0x52,0x65,0x61,0x64,0x79,0x28,0x29,0x29,0x3b,0x0d, +0x0a,0x0d,0x0a,0x3c,0x2f,0x73,0x63,0x72,0x69,0x70,0x74,0x3e,0x20,0x0d,0x0a,0x0d, +0x0a,0x3c,0x2f,0x68,0x65,0x61,0x64,0x3e,0x0d,0x0a,0x3c,0x62,0x6f,0x64,0x79,0x20, +0x62,0x67,0x63,0x6f,0x6c,0x6f,0x72,0x3d,0x22,0x77,0x68,0x69,0x74,0x65,0x22,0x20, +0x74,0x65,0x78,0x74,0x3d,0x22,0x62,0x6c,0x61,0x63,0x6b,0x22,0x3e,0x0d,0x0a,0x3c, +0x63,0x65,0x6e,0x74,0x65,0x72,0x3e,0x3c,0x74,0x61,0x62,0x6c,0x65,0x20,0x63,0x65, +0x6c,0x6c,0x73,0x70,0x61,0x63,0x69,0x6e,0x67,0x3d,0x22,0x33,0x32,0x22,0x3e,0x0d, +0x0a,0x3c,0x74,0x72,0x3e,0x0d,0x0a,0x09,0x3c,0x74,0x64,0x3e,0x0d,0x0a,0x3c,0x21, +0x2d,0x2d,0x5b,0x69,0x66,0x20,0x6c,0x74,0x65,0x20,0x49,0x45,0x20,0x39,0x20,0x5d, +0x3e,0x0d,0x0a,0x09,0x53,0x6f,0x72,0x72,0x79,0x2c,0x20,0x49,0x45,0x3c,0x39,0x20, +0x62,0x72,0x6f,0x77,0x73,0x65,0x72,0x3c,0x62,0x72,0x3e,0x0d,0x0a,0x09,0x64,0x6f, +0x65,0x73,0x20,0x6e,0x6f,0x74,0x20,0x73,0x75,0x70,0x70,0x6f,0x72,0x74,0x20,0x53, +0x56,0x47,0x0d,0x0a,0x3c,0x21,0x5b,0x65,0x6e,0x64,0x69,0x66,0x5d,0x2d,0x2d,0x3e, +0x0d,0x0a,0x3c,0x21,0x2d,0x2d,0x5b,0x69,0x66,0x20,0x21,0x6c,0x74,0x65,0x20,0x49, +0x45,0x20,0x39,0x5d,0x3e,0x20,0x2d,0x2d,0x3e,0x0d,0x0a,0x09,0x3c,0x69,0x6d,0x67, +0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x3d,0x22,0x34,0x30,0x30,0x22,0x20,0x73,0x72, +0x63,0x3d,0x22,0x2e,0x2f,0x69,0x6d,0x67,0x2f,0x74,0x6f,0x61,0x73,0x74,0x65,0x72, +0x2e,0x73,0x76,0x67,0x22,0x3e,0x0d,0x0a,0x3c,0x21,0x2d,0x2d,0x20,0x3c,0x21,0x5b, +0x65,0x6e,0x64,0x69,0x66,0x5d,0x2d,0x2d,0x3e,0x0d,0x0a,0x0d,0x0a,0x09,0x3c,0x2f, +0x74,0x64,0x3e,0x0d,0x0a,0x09,0x3c,0x74,0x64,0x3e,0x0d,0x0a,0x09,0x09,0x3c,0x64, +0x69,0x76,0x20,0x63,0x6c,0x61,0x73,0x73,0x3d,0x22,0x72,0x64,0x69,0x76,0x22,0x3e, +0x0d,0x0a,0x09,0x09,0x09,0x3c,0x62,0x3e,0x44,0x65,0x76,0x69,0x63,0x65,0x20,0x73, +0x74,0x61,0x74,0x65,0x3c,0x2f,0x62,0x3e,0x3c,0x62,0x72,0x3e,0x0d,0x0a,0x09,0x09, +0x09,0x3c,0x64,0x69,0x76,0x20,0x69,0x64,0x3d,0x22,0x64,0x65,0x76,0x73,0x74,0x61, +0x74,0x65,0x22,0x3e,0x3c,0x2f,0x64,0x69,0x76,0x3e,0x3c,0x62,0x72,0x3e,0x0d,0x0a, +0x09,0x09,0x09,0x3c,0x62,0x3e,0x44,0x65,0x76,0x69,0x63,0x65,0x20,0x74,0x69,0x6d, +0x65,0x3c,0x2f,0x62,0x3e,0x3c,0x62,0x72,0x3e,0x0d,0x0a,0x09,0x09,0x09,0x3c,0x64, +0x69,0x76,0x20,0x69,0x64,0x3d,0x22,0x73,0x79,0x73,0x74,0x69,0x63,0x6b,0x22,0x3e, +0x3c,0x2f,0x64,0x69,0x76,0x3e,0x3c,0x62,0x72,0x3e,0x0d,0x0a,0x09,0x09,0x09,0x3c, +0x62,0x3e,0x55,0x73,0x65,0x72,0x20,0x43,0x6f,0x6e,0x74,0x72,0x6f,0x6c,0x73,0x3c, +0x2f,0x62,0x3e,0x3c,0x62,0x72,0x3e,0x0d,0x0a,0x09,0x09,0x09,0x3c,0x69,0x6e,0x70, +0x75,0x74,0x20,0x69,0x64,0x3d,0x22,0x61,0x6c,0x70,0x68,0x61,0x22,0x20,0x74,0x79, +0x70,0x65,0x3d,0x22,0x63,0x68,0x65,0x63,0x6b,0x62,0x6f,0x78,0x22,0x20,0x6f,0x6e, +0x63,0x6c,0x69,0x63,0x6b,0x3d,0x22,0x63,0x74,0x6c,0x28,0x7b,0x61,0x3a,0x20,0x28, +0x74,0x68,0x69,0x73,0x2e,0x63,0x68,0x65,0x63,0x6b,0x65,0x64,0x20,0x3f,0x20,0x31, +0x20,0x3a,0x20,0x30,0x29,0x7d,0x29,0x22,0x3e,0x61,0x6c,0x70,0x68,0x61,0x3c,0x62, +0x72,0x3e,0x0d,0x0a,0x09,0x09,0x09,0x3c,0x69,0x6e,0x70,0x75,0x74,0x20,0x69,0x64, +0x3d,0x22,0x62,0x72,0x61,0x76,0x6f,0x22,0x20,0x74,0x79,0x70,0x65,0x3d,0x22,0x63, +0x68,0x65,0x63,0x6b,0x62,0x6f,0x78,0x22,0x20,0x6f,0x6e,0x63,0x6c,0x69,0x63,0x6b, +0x3d,0x22,0x63,0x74,0x6c,0x28,0x7b,0x62,0x3a,0x20,0x28,0x74,0x68,0x69,0x73,0x2e, +0x63,0x68,0x65,0x63,0x6b,0x65,0x64,0x20,0x3f,0x20,0x31,0x20,0x3a,0x20,0x30,0x29, +0x7d,0x29,0x22,0x3e,0x62,0x72,0x61,0x76,0x6f,0x3c,0x62,0x72,0x3e,0x0d,0x0a,0x09, +0x09,0x09,0x3c,0x69,0x6e,0x70,0x75,0x74,0x20,0x69,0x64,0x3d,0x22,0x63,0x68,0x61, +0x72,0x6c,0x69,0x65,0x22,0x20,0x74,0x79,0x70,0x65,0x3d,0x22,0x63,0x68,0x65,0x63, +0x6b,0x62,0x6f,0x78,0x22,0x20,0x6f,0x6e,0x63,0x6c,0x69,0x63,0x6b,0x3d,0x22,0x63, +0x74,0x6c,0x28,0x7b,0x63,0x3a,0x20,0x28,0x74,0x68,0x69,0x73,0x2e,0x63,0x68,0x65, +0x63,0x6b,0x65,0x64,0x20,0x3f,0x20,0x31,0x20,0x3a,0x20,0x30,0x29,0x7d,0x29,0x22, +0x3e,0x63,0x68,0x61,0x72,0x6c,0x69,0x65,0x3c,0x62,0x72,0x3e,0x0d,0x0a,0x09,0x09, +0x3c,0x2f,0x64,0x69,0x76,0x3e,0x0d,0x0a,0x09,0x3c,0x2f,0x74,0x64,0x3e,0x0d,0x0a, +0x3c,0x2f,0x74,0x72,0x3e,0x0d,0x0a,0x3c,0x2f,0x74,0x61,0x62,0x6c,0x65,0x3e,0x0d, +0x0a,0x3c,0x2f,0x63,0x65,0x6e,0x74,0x65,0x72,0x3e,0x0d,0x0a,0x3c,0x2f,0x62,0x6f, +0x64,0x79,0x3e,0x0d,0x0a,0x3c,0x2f,0x68,0x74,0x6d,0x6c,0x3e,0x0d,0x0a,}; + +static const unsigned int dummy_align__state_shtml = 3; +static const unsigned char data__state_shtml[] = { +/* /state.shtml (13 chars) */ +0x2f,0x73,0x74,0x61,0x74,0x65,0x2e,0x73,0x68,0x74,0x6d,0x6c,0x00,0x00,0x00,0x00, + +/* HTTP header */ +/* "HTTP/1.0 200 OK +" (17 bytes) */ +0x48,0x54,0x54,0x50,0x2f,0x31,0x2e,0x30,0x20,0x32,0x30,0x30,0x20,0x4f,0x4b,0x0d, +0x0a, +/* "Server: lwIP/1.3.1 (http://savannah.nongnu.org/projects/lwip) +" (63 bytes) */ +0x53,0x65,0x72,0x76,0x65,0x72,0x3a,0x20,0x6c,0x77,0x49,0x50,0x2f,0x31,0x2e,0x33, +0x2e,0x31,0x20,0x28,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x73,0x61,0x76,0x61,0x6e, +0x6e,0x61,0x68,0x2e,0x6e,0x6f,0x6e,0x67,0x6e,0x75,0x2e,0x6f,0x72,0x67,0x2f,0x70, +0x72,0x6f,0x6a,0x65,0x63,0x74,0x73,0x2f,0x6c,0x77,0x69,0x70,0x29,0x0d,0x0a, +/* "Content-type: text/html +Expires: Fri, 10 Apr 2008 14:00:00 GMT +Pragma: no-cache + +" (85 bytes) */ +0x43,0x6f,0x6e,0x74,0x65,0x6e,0x74,0x2d,0x74,0x79,0x70,0x65,0x3a,0x20,0x74,0x65, +0x78,0x74,0x2f,0x68,0x74,0x6d,0x6c,0x0d,0x0a,0x45,0x78,0x70,0x69,0x72,0x65,0x73, +0x3a,0x20,0x46,0x72,0x69,0x2c,0x20,0x31,0x30,0x20,0x41,0x70,0x72,0x20,0x32,0x30, +0x30,0x38,0x20,0x31,0x34,0x3a,0x30,0x30,0x3a,0x30,0x30,0x20,0x47,0x4d,0x54,0x0d, +0x0a,0x50,0x72,0x61,0x67,0x6d,0x61,0x3a,0x20,0x6e,0x6f,0x2d,0x63,0x61,0x63,0x68, +0x65,0x0d,0x0a,0x0d,0x0a, +/* raw file data (111 bytes) */ +0x7b,0x0d,0x0a,0x09,0x22,0x73,0x79,0x73,0x74,0x69,0x63,0x6b,0x22,0x3a,0x20,0x3c, +0x21,0x2d,0x2d,0x23,0x73,0x79,0x73,0x74,0x69,0x63,0x6b,0x2d,0x2d,0x3e,0x2c,0x0d, +0x0a,0x09,0x22,0x75,0x73,0x65,0x72,0x22,0x3a,0x20,0x7b,0x20,0x22,0x61,0x22,0x3a, +0x20,0x3c,0x21,0x2d,0x2d,0x23,0x61,0x6c,0x70,0x68,0x61,0x2d,0x2d,0x3e,0x2c,0x20, +0x22,0x62,0x22,0x3a,0x20,0x3c,0x21,0x2d,0x2d,0x23,0x62,0x72,0x61,0x76,0x6f,0x2d, +0x2d,0x3e,0x2c,0x20,0x22,0x63,0x22,0x3a,0x20,0x3c,0x21,0x2d,0x2d,0x23,0x63,0x68, +0x61,0x72,0x6c,0x69,0x65,0x2d,0x2d,0x3e,0x20,0x7d,0x0d,0x0a,0x7d,0x0d,0x0a,}; + +static unsigned const int dummy_align__zepto_min_js = 4; +static unsigned const char data__zepto_min_js[] = { +/* /zepto.min.js (14 chars) */ +0x2f,0x7a,0x65,0x70,0x74,0x6f,0x2e,0x6d,0x69,0x6e,0x2e,0x6a,0x73,0x00,0x00,0x00, + +/* HTTP header */ +/* "HTTP/1.0 200 OK +" (17 bytes) */ +0x48,0x54,0x54,0x50,0x2f,0x31,0x2e,0x30,0x20,0x32,0x30,0x30,0x20,0x4f,0x4b,0x0d, +0x0a, +/* "Server: lwIP/1.3.1 (http://savannah.nongnu.org/projects/lwip) +" (63 bytes) */ +0x53,0x65,0x72,0x76,0x65,0x72,0x3a,0x20,0x6c,0x77,0x49,0x50,0x2f,0x31,0x2e,0x33, +0x2e,0x31,0x20,0x28,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x73,0x61,0x76,0x61,0x6e, +0x6e,0x61,0x68,0x2e,0x6e,0x6f,0x6e,0x67,0x6e,0x75,0x2e,0x6f,0x72,0x67,0x2f,0x70, +0x72,0x6f,0x6a,0x65,0x63,0x74,0x73,0x2f,0x6c,0x77,0x69,0x70,0x29,0x0d,0x0a, +/* "Content-type: application/x-javascript + +" (42 bytes) */ +0x43,0x6f,0x6e,0x74,0x65,0x6e,0x74,0x2d,0x74,0x79,0x70,0x65,0x3a,0x20,0x61,0x70, +0x70,0x6c,0x69,0x63,0x61,0x74,0x69,0x6f,0x6e,0x2f,0x78,0x2d,0x6a,0x61,0x76,0x61, +0x73,0x63,0x72,0x69,0x70,0x74,0x0d,0x0a,0x0d,0x0a, +/* raw file data (25138 bytes) */ +0x2f,0x2a,0x20,0x5a,0x65,0x70,0x74,0x6f,0x20,0x76,0x31,0x2e,0x31,0x2e,0x36,0x20, +0x2d,0x20,0x7a,0x65,0x70,0x74,0x6f,0x20,0x65,0x76,0x65,0x6e,0x74,0x20,0x61,0x6a, +0x61,0x78,0x20,0x66,0x6f,0x72,0x6d,0x20,0x69,0x65,0x20,0x2d,0x20,0x7a,0x65,0x70, +0x74,0x6f,0x6a,0x73,0x2e,0x63,0x6f,0x6d,0x2f,0x6c,0x69,0x63,0x65,0x6e,0x73,0x65, +0x20,0x2a,0x2f,0x0a,0x76,0x61,0x72,0x20,0x5a,0x65,0x70,0x74,0x6f,0x3d,0x66,0x75, +0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x29,0x7b,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f, +0x6e,0x20,0x4c,0x28,0x74,0x29,0x7b,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x6e,0x75, +0x6c,0x6c,0x3d,0x3d,0x74,0x3f,0x53,0x74,0x72,0x69,0x6e,0x67,0x28,0x74,0x29,0x3a, +0x6a,0x5b,0x53,0x2e,0x63,0x61,0x6c,0x6c,0x28,0x74,0x29,0x5d,0x7c,0x7c,0x22,0x6f, +0x62,0x6a,0x65,0x63,0x74,0x22,0x7d,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x20, +0x5a,0x28,0x74,0x29,0x7b,0x72,0x65,0x74,0x75,0x72,0x6e,0x22,0x66,0x75,0x6e,0x63, +0x74,0x69,0x6f,0x6e,0x22,0x3d,0x3d,0x4c,0x28,0x74,0x29,0x7d,0x66,0x75,0x6e,0x63, +0x74,0x69,0x6f,0x6e,0x20,0x5f,0x28,0x74,0x29,0x7b,0x72,0x65,0x74,0x75,0x72,0x6e, +0x20,0x6e,0x75,0x6c,0x6c,0x21,0x3d,0x74,0x26,0x26,0x74,0x3d,0x3d,0x74,0x2e,0x77, +0x69,0x6e,0x64,0x6f,0x77,0x7d,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x20,0x24, +0x28,0x74,0x29,0x7b,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x6e,0x75,0x6c,0x6c,0x21, +0x3d,0x74,0x26,0x26,0x74,0x2e,0x6e,0x6f,0x64,0x65,0x54,0x79,0x70,0x65,0x3d,0x3d, +0x74,0x2e,0x44,0x4f,0x43,0x55,0x4d,0x45,0x4e,0x54,0x5f,0x4e,0x4f,0x44,0x45,0x7d, +0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x20,0x44,0x28,0x74,0x29,0x7b,0x72,0x65, +0x74,0x75,0x72,0x6e,0x22,0x6f,0x62,0x6a,0x65,0x63,0x74,0x22,0x3d,0x3d,0x4c,0x28, +0x74,0x29,0x7d,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x20,0x4d,0x28,0x74,0x29, +0x7b,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x44,0x28,0x74,0x29,0x26,0x26,0x21,0x5f, +0x28,0x74,0x29,0x26,0x26,0x4f,0x62,0x6a,0x65,0x63,0x74,0x2e,0x67,0x65,0x74,0x50, +0x72,0x6f,0x74,0x6f,0x74,0x79,0x70,0x65,0x4f,0x66,0x28,0x74,0x29,0x3d,0x3d,0x4f, +0x62,0x6a,0x65,0x63,0x74,0x2e,0x70,0x72,0x6f,0x74,0x6f,0x74,0x79,0x70,0x65,0x7d, +0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x20,0x52,0x28,0x74,0x29,0x7b,0x72,0x65, +0x74,0x75,0x72,0x6e,0x22,0x6e,0x75,0x6d,0x62,0x65,0x72,0x22,0x3d,0x3d,0x74,0x79, +0x70,0x65,0x6f,0x66,0x20,0x74,0x2e,0x6c,0x65,0x6e,0x67,0x74,0x68,0x7d,0x66,0x75, +0x6e,0x63,0x74,0x69,0x6f,0x6e,0x20,0x6b,0x28,0x74,0x29,0x7b,0x72,0x65,0x74,0x75, +0x72,0x6e,0x20,0x73,0x2e,0x63,0x61,0x6c,0x6c,0x28,0x74,0x2c,0x66,0x75,0x6e,0x63, +0x74,0x69,0x6f,0x6e,0x28,0x74,0x29,0x7b,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x6e, +0x75,0x6c,0x6c,0x21,0x3d,0x74,0x7d,0x29,0x7d,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f, +0x6e,0x20,0x7a,0x28,0x74,0x29,0x7b,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x74,0x2e, +0x6c,0x65,0x6e,0x67,0x74,0x68,0x3e,0x30,0x3f,0x6e,0x2e,0x66,0x6e,0x2e,0x63,0x6f, +0x6e,0x63,0x61,0x74,0x2e,0x61,0x70,0x70,0x6c,0x79,0x28,0x5b,0x5d,0x2c,0x74,0x29, +0x3a,0x74,0x7d,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x20,0x46,0x28,0x74,0x29, +0x7b,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x74,0x2e,0x72,0x65,0x70,0x6c,0x61,0x63, +0x65,0x28,0x2f,0x3a,0x3a,0x2f,0x67,0x2c,0x22,0x2f,0x22,0x29,0x2e,0x72,0x65,0x70, +0x6c,0x61,0x63,0x65,0x28,0x2f,0x28,0x5b,0x41,0x2d,0x5a,0x5d,0x2b,0x29,0x28,0x5b, +0x41,0x2d,0x5a,0x5d,0x5b,0x61,0x2d,0x7a,0x5d,0x29,0x2f,0x67,0x2c,0x22,0x24,0x31, +0x5f,0x24,0x32,0x22,0x29,0x2e,0x72,0x65,0x70,0x6c,0x61,0x63,0x65,0x28,0x2f,0x28, +0x5b,0x61,0x2d,0x7a,0x5c,0x64,0x5d,0x29,0x28,0x5b,0x41,0x2d,0x5a,0x5d,0x29,0x2f, +0x67,0x2c,0x22,0x24,0x31,0x5f,0x24,0x32,0x22,0x29,0x2e,0x72,0x65,0x70,0x6c,0x61, +0x63,0x65,0x28,0x2f,0x5f,0x2f,0x67,0x2c,0x22,0x2d,0x22,0x29,0x2e,0x74,0x6f,0x4c, +0x6f,0x77,0x65,0x72,0x43,0x61,0x73,0x65,0x28,0x29,0x7d,0x66,0x75,0x6e,0x63,0x74, +0x69,0x6f,0x6e,0x20,0x71,0x28,0x74,0x29,0x7b,0x72,0x65,0x74,0x75,0x72,0x6e,0x20, +0x74,0x20,0x69,0x6e,0x20,0x66,0x3f,0x66,0x5b,0x74,0x5d,0x3a,0x66,0x5b,0x74,0x5d, +0x3d,0x6e,0x65,0x77,0x20,0x52,0x65,0x67,0x45,0x78,0x70,0x28,0x22,0x28,0x5e,0x7c, +0x5c,0x5c,0x73,0x29,0x22,0x2b,0x74,0x2b,0x22,0x28,0x5c,0x5c,0x73,0x7c,0x24,0x29, +0x22,0x29,0x7d,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x20,0x48,0x28,0x74,0x2c, +0x65,0x29,0x7b,0x72,0x65,0x74,0x75,0x72,0x6e,0x22,0x6e,0x75,0x6d,0x62,0x65,0x72, +0x22,0x21,0x3d,0x74,0x79,0x70,0x65,0x6f,0x66,0x20,0x65,0x7c,0x7c,0x63,0x5b,0x46, +0x28,0x74,0x29,0x5d,0x3f,0x65,0x3a,0x65,0x2b,0x22,0x70,0x78,0x22,0x7d,0x66,0x75, +0x6e,0x63,0x74,0x69,0x6f,0x6e,0x20,0x49,0x28,0x74,0x29,0x7b,0x76,0x61,0x72,0x20, +0x65,0x2c,0x6e,0x3b,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x75,0x5b,0x74,0x5d,0x7c, +0x7c,0x28,0x65,0x3d,0x61,0x2e,0x63,0x72,0x65,0x61,0x74,0x65,0x45,0x6c,0x65,0x6d, +0x65,0x6e,0x74,0x28,0x74,0x29,0x2c,0x61,0x2e,0x62,0x6f,0x64,0x79,0x2e,0x61,0x70, +0x70,0x65,0x6e,0x64,0x43,0x68,0x69,0x6c,0x64,0x28,0x65,0x29,0x2c,0x6e,0x3d,0x67, +0x65,0x74,0x43,0x6f,0x6d,0x70,0x75,0x74,0x65,0x64,0x53,0x74,0x79,0x6c,0x65,0x28, +0x65,0x2c,0x22,0x22,0x29,0x2e,0x67,0x65,0x74,0x50,0x72,0x6f,0x70,0x65,0x72,0x74, +0x79,0x56,0x61,0x6c,0x75,0x65,0x28,0x22,0x64,0x69,0x73,0x70,0x6c,0x61,0x79,0x22, +0x29,0x2c,0x65,0x2e,0x70,0x61,0x72,0x65,0x6e,0x74,0x4e,0x6f,0x64,0x65,0x2e,0x72, +0x65,0x6d,0x6f,0x76,0x65,0x43,0x68,0x69,0x6c,0x64,0x28,0x65,0x29,0x2c,0x22,0x6e, +0x6f,0x6e,0x65,0x22,0x3d,0x3d,0x6e,0x26,0x26,0x28,0x6e,0x3d,0x22,0x62,0x6c,0x6f, +0x63,0x6b,0x22,0x29,0x2c,0x75,0x5b,0x74,0x5d,0x3d,0x6e,0x29,0x2c,0x75,0x5b,0x74, +0x5d,0x7d,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x20,0x56,0x28,0x74,0x29,0x7b, +0x72,0x65,0x74,0x75,0x72,0x6e,0x22,0x63,0x68,0x69,0x6c,0x64,0x72,0x65,0x6e,0x22, +0x69,0x6e,0x20,0x74,0x3f,0x6f,0x2e,0x63,0x61,0x6c,0x6c,0x28,0x74,0x2e,0x63,0x68, +0x69,0x6c,0x64,0x72,0x65,0x6e,0x29,0x3a,0x6e,0x2e,0x6d,0x61,0x70,0x28,0x74,0x2e, +0x63,0x68,0x69,0x6c,0x64,0x4e,0x6f,0x64,0x65,0x73,0x2c,0x66,0x75,0x6e,0x63,0x74, +0x69,0x6f,0x6e,0x28,0x74,0x29,0x7b,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x31,0x3d, +0x3d,0x74,0x2e,0x6e,0x6f,0x64,0x65,0x54,0x79,0x70,0x65,0x3f,0x74,0x3a,0x76,0x6f, +0x69,0x64,0x20,0x30,0x7d,0x29,0x7d,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x20, +0x42,0x28,0x6e,0x2c,0x69,0x2c,0x72,0x29,0x7b,0x66,0x6f,0x72,0x28,0x65,0x20,0x69, +0x6e,0x20,0x69,0x29,0x72,0x26,0x26,0x28,0x4d,0x28,0x69,0x5b,0x65,0x5d,0x29,0x7c, +0x7c,0x41,0x28,0x69,0x5b,0x65,0x5d,0x29,0x29,0x3f,0x28,0x4d,0x28,0x69,0x5b,0x65, +0x5d,0x29,0x26,0x26,0x21,0x4d,0x28,0x6e,0x5b,0x65,0x5d,0x29,0x26,0x26,0x28,0x6e, +0x5b,0x65,0x5d,0x3d,0x7b,0x7d,0x29,0x2c,0x41,0x28,0x69,0x5b,0x65,0x5d,0x29,0x26, +0x26,0x21,0x41,0x28,0x6e,0x5b,0x65,0x5d,0x29,0x26,0x26,0x28,0x6e,0x5b,0x65,0x5d, +0x3d,0x5b,0x5d,0x29,0x2c,0x42,0x28,0x6e,0x5b,0x65,0x5d,0x2c,0x69,0x5b,0x65,0x5d, +0x2c,0x72,0x29,0x29,0x3a,0x69,0x5b,0x65,0x5d,0x21,0x3d,0x3d,0x74,0x26,0x26,0x28, +0x6e,0x5b,0x65,0x5d,0x3d,0x69,0x5b,0x65,0x5d,0x29,0x7d,0x66,0x75,0x6e,0x63,0x74, +0x69,0x6f,0x6e,0x20,0x55,0x28,0x74,0x2c,0x65,0x29,0x7b,0x72,0x65,0x74,0x75,0x72, +0x6e,0x20,0x6e,0x75,0x6c,0x6c,0x3d,0x3d,0x65,0x3f,0x6e,0x28,0x74,0x29,0x3a,0x6e, +0x28,0x74,0x29,0x2e,0x66,0x69,0x6c,0x74,0x65,0x72,0x28,0x65,0x29,0x7d,0x66,0x75, +0x6e,0x63,0x74,0x69,0x6f,0x6e,0x20,0x4a,0x28,0x74,0x2c,0x65,0x2c,0x6e,0x2c,0x69, +0x29,0x7b,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x5a,0x28,0x65,0x29,0x3f,0x65,0x2e, +0x63,0x61,0x6c,0x6c,0x28,0x74,0x2c,0x6e,0x2c,0x69,0x29,0x3a,0x65,0x7d,0x66,0x75, +0x6e,0x63,0x74,0x69,0x6f,0x6e,0x20,0x58,0x28,0x74,0x2c,0x65,0x2c,0x6e,0x29,0x7b, +0x6e,0x75,0x6c,0x6c,0x3d,0x3d,0x6e,0x3f,0x74,0x2e,0x72,0x65,0x6d,0x6f,0x76,0x65, +0x41,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x28,0x65,0x29,0x3a,0x74,0x2e,0x73, +0x65,0x74,0x41,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x28,0x65,0x2c,0x6e,0x29, +0x7d,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x20,0x57,0x28,0x65,0x2c,0x6e,0x29, +0x7b,0x76,0x61,0x72,0x20,0x69,0x3d,0x65,0x2e,0x63,0x6c,0x61,0x73,0x73,0x4e,0x61, +0x6d,0x65,0x7c,0x7c,0x22,0x22,0x2c,0x72,0x3d,0x69,0x26,0x26,0x69,0x2e,0x62,0x61, +0x73,0x65,0x56,0x61,0x6c,0x21,0x3d,0x3d,0x74,0x3b,0x72,0x65,0x74,0x75,0x72,0x6e, +0x20,0x6e,0x3d,0x3d,0x3d,0x74,0x3f,0x72,0x3f,0x69,0x2e,0x62,0x61,0x73,0x65,0x56, +0x61,0x6c,0x3a,0x69,0x3a,0x76,0x6f,0x69,0x64,0x28,0x72,0x3f,0x69,0x2e,0x62,0x61, +0x73,0x65,0x56,0x61,0x6c,0x3d,0x6e,0x3a,0x65,0x2e,0x63,0x6c,0x61,0x73,0x73,0x4e, +0x61,0x6d,0x65,0x3d,0x6e,0x29,0x7d,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x20, +0x59,0x28,0x74,0x29,0x7b,0x74,0x72,0x79,0x7b,0x72,0x65,0x74,0x75,0x72,0x6e,0x20, +0x74,0x3f,0x22,0x74,0x72,0x75,0x65,0x22,0x3d,0x3d,0x74,0x7c,0x7c,0x28,0x22,0x66, +0x61,0x6c,0x73,0x65,0x22,0x3d,0x3d,0x74,0x3f,0x21,0x31,0x3a,0x22,0x6e,0x75,0x6c, +0x6c,0x22,0x3d,0x3d,0x74,0x3f,0x6e,0x75,0x6c,0x6c,0x3a,0x2b,0x74,0x2b,0x22,0x22, +0x3d,0x3d,0x74,0x3f,0x2b,0x74,0x3a,0x2f,0x5e,0x5b,0x5c,0x5b,0x5c,0x7b,0x5d,0x2f, +0x2e,0x74,0x65,0x73,0x74,0x28,0x74,0x29,0x3f,0x6e,0x2e,0x70,0x61,0x72,0x73,0x65, +0x4a,0x53,0x4f,0x4e,0x28,0x74,0x29,0x3a,0x74,0x29,0x3a,0x74,0x7d,0x63,0x61,0x74, +0x63,0x68,0x28,0x65,0x29,0x7b,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x74,0x7d,0x7d, +0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x20,0x47,0x28,0x74,0x2c,0x65,0x29,0x7b, +0x65,0x28,0x74,0x29,0x3b,0x66,0x6f,0x72,0x28,0x76,0x61,0x72,0x20,0x6e,0x3d,0x30, +0x2c,0x69,0x3d,0x74,0x2e,0x63,0x68,0x69,0x6c,0x64,0x4e,0x6f,0x64,0x65,0x73,0x2e, +0x6c,0x65,0x6e,0x67,0x74,0x68,0x3b,0x69,0x3e,0x6e,0x3b,0x6e,0x2b,0x2b,0x29,0x47, +0x28,0x74,0x2e,0x63,0x68,0x69,0x6c,0x64,0x4e,0x6f,0x64,0x65,0x73,0x5b,0x6e,0x5d, +0x2c,0x65,0x29,0x7d,0x76,0x61,0x72,0x20,0x74,0x2c,0x65,0x2c,0x6e,0x2c,0x69,0x2c, +0x43,0x2c,0x4e,0x2c,0x72,0x3d,0x5b,0x5d,0x2c,0x6f,0x3d,0x72,0x2e,0x73,0x6c,0x69, +0x63,0x65,0x2c,0x73,0x3d,0x72,0x2e,0x66,0x69,0x6c,0x74,0x65,0x72,0x2c,0x61,0x3d, +0x77,0x69,0x6e,0x64,0x6f,0x77,0x2e,0x64,0x6f,0x63,0x75,0x6d,0x65,0x6e,0x74,0x2c, +0x75,0x3d,0x7b,0x7d,0x2c,0x66,0x3d,0x7b,0x7d,0x2c,0x63,0x3d,0x7b,0x22,0x63,0x6f, +0x6c,0x75,0x6d,0x6e,0x2d,0x63,0x6f,0x75,0x6e,0x74,0x22,0x3a,0x31,0x2c,0x63,0x6f, +0x6c,0x75,0x6d,0x6e,0x73,0x3a,0x31,0x2c,0x22,0x66,0x6f,0x6e,0x74,0x2d,0x77,0x65, +0x69,0x67,0x68,0x74,0x22,0x3a,0x31,0x2c,0x22,0x6c,0x69,0x6e,0x65,0x2d,0x68,0x65, +0x69,0x67,0x68,0x74,0x22,0x3a,0x31,0x2c,0x6f,0x70,0x61,0x63,0x69,0x74,0x79,0x3a, +0x31,0x2c,0x22,0x7a,0x2d,0x69,0x6e,0x64,0x65,0x78,0x22,0x3a,0x31,0x2c,0x7a,0x6f, +0x6f,0x6d,0x3a,0x31,0x7d,0x2c,0x6c,0x3d,0x2f,0x5e,0x5c,0x73,0x2a,0x3c,0x28,0x5c, +0x77,0x2b,0x7c,0x21,0x29,0x5b,0x5e,0x3e,0x5d,0x2a,0x3e,0x2f,0x2c,0x68,0x3d,0x2f, +0x5e,0x3c,0x28,0x5c,0x77,0x2b,0x29,0x5c,0x73,0x2a,0x5c,0x2f,0x3f,0x3e,0x28,0x3f, +0x3a,0x3c,0x5c,0x2f,0x5c,0x31,0x3e,0x7c,0x29,0x24,0x2f,0x2c,0x70,0x3d,0x2f,0x3c, +0x28,0x3f,0x21,0x61,0x72,0x65,0x61,0x7c,0x62,0x72,0x7c,0x63,0x6f,0x6c,0x7c,0x65, +0x6d,0x62,0x65,0x64,0x7c,0x68,0x72,0x7c,0x69,0x6d,0x67,0x7c,0x69,0x6e,0x70,0x75, +0x74,0x7c,0x6c,0x69,0x6e,0x6b,0x7c,0x6d,0x65,0x74,0x61,0x7c,0x70,0x61,0x72,0x61, +0x6d,0x29,0x28,0x28,0x5b,0x5c,0x77,0x3a,0x5d,0x2b,0x29,0x5b,0x5e,0x3e,0x5d,0x2a, +0x29,0x5c,0x2f,0x3e,0x2f,0x67,0x69,0x2c,0x64,0x3d,0x2f,0x5e,0x28,0x3f,0x3a,0x62, +0x6f,0x64,0x79,0x7c,0x68,0x74,0x6d,0x6c,0x29,0x24,0x2f,0x69,0x2c,0x6d,0x3d,0x2f, +0x28,0x5b,0x41,0x2d,0x5a,0x5d,0x29,0x2f,0x67,0x2c,0x67,0x3d,0x5b,0x22,0x76,0x61, +0x6c,0x22,0x2c,0x22,0x63,0x73,0x73,0x22,0x2c,0x22,0x68,0x74,0x6d,0x6c,0x22,0x2c, +0x22,0x74,0x65,0x78,0x74,0x22,0x2c,0x22,0x64,0x61,0x74,0x61,0x22,0x2c,0x22,0x77, +0x69,0x64,0x74,0x68,0x22,0x2c,0x22,0x68,0x65,0x69,0x67,0x68,0x74,0x22,0x2c,0x22, +0x6f,0x66,0x66,0x73,0x65,0x74,0x22,0x5d,0x2c,0x76,0x3d,0x5b,0x22,0x61,0x66,0x74, +0x65,0x72,0x22,0x2c,0x22,0x70,0x72,0x65,0x70,0x65,0x6e,0x64,0x22,0x2c,0x22,0x62, +0x65,0x66,0x6f,0x72,0x65,0x22,0x2c,0x22,0x61,0x70,0x70,0x65,0x6e,0x64,0x22,0x5d, +0x2c,0x79,0x3d,0x61,0x2e,0x63,0x72,0x65,0x61,0x74,0x65,0x45,0x6c,0x65,0x6d,0x65, +0x6e,0x74,0x28,0x22,0x74,0x61,0x62,0x6c,0x65,0x22,0x29,0x2c,0x78,0x3d,0x61,0x2e, +0x63,0x72,0x65,0x61,0x74,0x65,0x45,0x6c,0x65,0x6d,0x65,0x6e,0x74,0x28,0x22,0x74, +0x72,0x22,0x29,0x2c,0x62,0x3d,0x7b,0x74,0x72,0x3a,0x61,0x2e,0x63,0x72,0x65,0x61, +0x74,0x65,0x45,0x6c,0x65,0x6d,0x65,0x6e,0x74,0x28,0x22,0x74,0x62,0x6f,0x64,0x79, +0x22,0x29,0x2c,0x74,0x62,0x6f,0x64,0x79,0x3a,0x79,0x2c,0x74,0x68,0x65,0x61,0x64, +0x3a,0x79,0x2c,0x74,0x66,0x6f,0x6f,0x74,0x3a,0x79,0x2c,0x74,0x64,0x3a,0x78,0x2c, +0x74,0x68,0x3a,0x78,0x2c,0x22,0x2a,0x22,0x3a,0x61,0x2e,0x63,0x72,0x65,0x61,0x74, +0x65,0x45,0x6c,0x65,0x6d,0x65,0x6e,0x74,0x28,0x22,0x64,0x69,0x76,0x22,0x29,0x7d, +0x2c,0x77,0x3d,0x2f,0x63,0x6f,0x6d,0x70,0x6c,0x65,0x74,0x65,0x7c,0x6c,0x6f,0x61, +0x64,0x65,0x64,0x7c,0x69,0x6e,0x74,0x65,0x72,0x61,0x63,0x74,0x69,0x76,0x65,0x2f, +0x2c,0x45,0x3d,0x2f,0x5e,0x5b,0x5c,0x77,0x2d,0x5d,0x2a,0x24,0x2f,0x2c,0x6a,0x3d, +0x7b,0x7d,0x2c,0x53,0x3d,0x6a,0x2e,0x74,0x6f,0x53,0x74,0x72,0x69,0x6e,0x67,0x2c, +0x54,0x3d,0x7b,0x7d,0x2c,0x4f,0x3d,0x61,0x2e,0x63,0x72,0x65,0x61,0x74,0x65,0x45, +0x6c,0x65,0x6d,0x65,0x6e,0x74,0x28,0x22,0x64,0x69,0x76,0x22,0x29,0x2c,0x50,0x3d, +0x7b,0x74,0x61,0x62,0x69,0x6e,0x64,0x65,0x78,0x3a,0x22,0x74,0x61,0x62,0x49,0x6e, +0x64,0x65,0x78,0x22,0x2c,0x72,0x65,0x61,0x64,0x6f,0x6e,0x6c,0x79,0x3a,0x22,0x72, +0x65,0x61,0x64,0x4f,0x6e,0x6c,0x79,0x22,0x2c,0x22,0x66,0x6f,0x72,0x22,0x3a,0x22, +0x68,0x74,0x6d,0x6c,0x46,0x6f,0x72,0x22,0x2c,0x22,0x63,0x6c,0x61,0x73,0x73,0x22, +0x3a,0x22,0x63,0x6c,0x61,0x73,0x73,0x4e,0x61,0x6d,0x65,0x22,0x2c,0x6d,0x61,0x78, +0x6c,0x65,0x6e,0x67,0x74,0x68,0x3a,0x22,0x6d,0x61,0x78,0x4c,0x65,0x6e,0x67,0x74, +0x68,0x22,0x2c,0x63,0x65,0x6c,0x6c,0x73,0x70,0x61,0x63,0x69,0x6e,0x67,0x3a,0x22, +0x63,0x65,0x6c,0x6c,0x53,0x70,0x61,0x63,0x69,0x6e,0x67,0x22,0x2c,0x63,0x65,0x6c, +0x6c,0x70,0x61,0x64,0x64,0x69,0x6e,0x67,0x3a,0x22,0x63,0x65,0x6c,0x6c,0x50,0x61, +0x64,0x64,0x69,0x6e,0x67,0x22,0x2c,0x72,0x6f,0x77,0x73,0x70,0x61,0x6e,0x3a,0x22, +0x72,0x6f,0x77,0x53,0x70,0x61,0x6e,0x22,0x2c,0x63,0x6f,0x6c,0x73,0x70,0x61,0x6e, +0x3a,0x22,0x63,0x6f,0x6c,0x53,0x70,0x61,0x6e,0x22,0x2c,0x75,0x73,0x65,0x6d,0x61, +0x70,0x3a,0x22,0x75,0x73,0x65,0x4d,0x61,0x70,0x22,0x2c,0x66,0x72,0x61,0x6d,0x65, +0x62,0x6f,0x72,0x64,0x65,0x72,0x3a,0x22,0x66,0x72,0x61,0x6d,0x65,0x42,0x6f,0x72, +0x64,0x65,0x72,0x22,0x2c,0x63,0x6f,0x6e,0x74,0x65,0x6e,0x74,0x65,0x64,0x69,0x74, +0x61,0x62,0x6c,0x65,0x3a,0x22,0x63,0x6f,0x6e,0x74,0x65,0x6e,0x74,0x45,0x64,0x69, +0x74,0x61,0x62,0x6c,0x65,0x22,0x7d,0x2c,0x41,0x3d,0x41,0x72,0x72,0x61,0x79,0x2e, +0x69,0x73,0x41,0x72,0x72,0x61,0x79,0x7c,0x7c,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f, +0x6e,0x28,0x74,0x29,0x7b,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x74,0x20,0x69,0x6e, +0x73,0x74,0x61,0x6e,0x63,0x65,0x6f,0x66,0x20,0x41,0x72,0x72,0x61,0x79,0x7d,0x3b, +0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x54,0x2e,0x6d,0x61,0x74,0x63,0x68,0x65,0x73, +0x3d,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x74,0x2c,0x65,0x29,0x7b,0x69, +0x66,0x28,0x21,0x65,0x7c,0x7c,0x21,0x74,0x7c,0x7c,0x31,0x21,0x3d,0x3d,0x74,0x2e, +0x6e,0x6f,0x64,0x65,0x54,0x79,0x70,0x65,0x29,0x72,0x65,0x74,0x75,0x72,0x6e,0x21, +0x31,0x3b,0x76,0x61,0x72,0x20,0x6e,0x3d,0x74,0x2e,0x77,0x65,0x62,0x6b,0x69,0x74, +0x4d,0x61,0x74,0x63,0x68,0x65,0x73,0x53,0x65,0x6c,0x65,0x63,0x74,0x6f,0x72,0x7c, +0x7c,0x74,0x2e,0x6d,0x6f,0x7a,0x4d,0x61,0x74,0x63,0x68,0x65,0x73,0x53,0x65,0x6c, +0x65,0x63,0x74,0x6f,0x72,0x7c,0x7c,0x74,0x2e,0x6f,0x4d,0x61,0x74,0x63,0x68,0x65, +0x73,0x53,0x65,0x6c,0x65,0x63,0x74,0x6f,0x72,0x7c,0x7c,0x74,0x2e,0x6d,0x61,0x74, +0x63,0x68,0x65,0x73,0x53,0x65,0x6c,0x65,0x63,0x74,0x6f,0x72,0x3b,0x69,0x66,0x28, +0x6e,0x29,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x6e,0x2e,0x63,0x61,0x6c,0x6c,0x28, +0x74,0x2c,0x65,0x29,0x3b,0x76,0x61,0x72,0x20,0x69,0x2c,0x72,0x3d,0x74,0x2e,0x70, +0x61,0x72,0x65,0x6e,0x74,0x4e,0x6f,0x64,0x65,0x2c,0x6f,0x3d,0x21,0x72,0x3b,0x72, +0x65,0x74,0x75,0x72,0x6e,0x20,0x6f,0x26,0x26,0x28,0x72,0x3d,0x4f,0x29,0x2e,0x61, +0x70,0x70,0x65,0x6e,0x64,0x43,0x68,0x69,0x6c,0x64,0x28,0x74,0x29,0x2c,0x69,0x3d, +0x7e,0x54,0x2e,0x71,0x73,0x61,0x28,0x72,0x2c,0x65,0x29,0x2e,0x69,0x6e,0x64,0x65, +0x78,0x4f,0x66,0x28,0x74,0x29,0x2c,0x6f,0x26,0x26,0x4f,0x2e,0x72,0x65,0x6d,0x6f, +0x76,0x65,0x43,0x68,0x69,0x6c,0x64,0x28,0x74,0x29,0x2c,0x69,0x7d,0x2c,0x43,0x3d, +0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x74,0x29,0x7b,0x72,0x65,0x74,0x75, +0x72,0x6e,0x20,0x74,0x2e,0x72,0x65,0x70,0x6c,0x61,0x63,0x65,0x28,0x2f,0x2d,0x2b, +0x28,0x2e,0x29,0x3f,0x2f,0x67,0x2c,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28, +0x74,0x2c,0x65,0x29,0x7b,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x65,0x3f,0x65,0x2e, +0x74,0x6f,0x55,0x70,0x70,0x65,0x72,0x43,0x61,0x73,0x65,0x28,0x29,0x3a,0x22,0x22, +0x7d,0x29,0x7d,0x2c,0x4e,0x3d,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x74, +0x29,0x7b,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x73,0x2e,0x63,0x61,0x6c,0x6c,0x28, +0x74,0x2c,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x65,0x2c,0x6e,0x29,0x7b, +0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x74,0x2e,0x69,0x6e,0x64,0x65,0x78,0x4f,0x66, +0x28,0x65,0x29,0x3d,0x3d,0x6e,0x7d,0x29,0x7d,0x2c,0x54,0x2e,0x66,0x72,0x61,0x67, +0x6d,0x65,0x6e,0x74,0x3d,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x65,0x2c, +0x69,0x2c,0x72,0x29,0x7b,0x76,0x61,0x72,0x20,0x73,0x2c,0x75,0x2c,0x66,0x3b,0x72, +0x65,0x74,0x75,0x72,0x6e,0x20,0x68,0x2e,0x74,0x65,0x73,0x74,0x28,0x65,0x29,0x26, +0x26,0x28,0x73,0x3d,0x6e,0x28,0x61,0x2e,0x63,0x72,0x65,0x61,0x74,0x65,0x45,0x6c, +0x65,0x6d,0x65,0x6e,0x74,0x28,0x52,0x65,0x67,0x45,0x78,0x70,0x2e,0x24,0x31,0x29, +0x29,0x29,0x2c,0x73,0x7c,0x7c,0x28,0x65,0x2e,0x72,0x65,0x70,0x6c,0x61,0x63,0x65, +0x26,0x26,0x28,0x65,0x3d,0x65,0x2e,0x72,0x65,0x70,0x6c,0x61,0x63,0x65,0x28,0x70, +0x2c,0x22,0x3c,0x24,0x31,0x3e,0x3c,0x2f,0x24,0x32,0x3e,0x22,0x29,0x29,0x2c,0x69, +0x3d,0x3d,0x3d,0x74,0x26,0x26,0x28,0x69,0x3d,0x6c,0x2e,0x74,0x65,0x73,0x74,0x28, +0x65,0x29,0x26,0x26,0x52,0x65,0x67,0x45,0x78,0x70,0x2e,0x24,0x31,0x29,0x2c,0x69, +0x20,0x69,0x6e,0x20,0x62,0x7c,0x7c,0x28,0x69,0x3d,0x22,0x2a,0x22,0x29,0x2c,0x66, +0x3d,0x62,0x5b,0x69,0x5d,0x2c,0x66,0x2e,0x69,0x6e,0x6e,0x65,0x72,0x48,0x54,0x4d, +0x4c,0x3d,0x22,0x22,0x2b,0x65,0x2c,0x73,0x3d,0x6e,0x2e,0x65,0x61,0x63,0x68,0x28, +0x6f,0x2e,0x63,0x61,0x6c,0x6c,0x28,0x66,0x2e,0x63,0x68,0x69,0x6c,0x64,0x4e,0x6f, +0x64,0x65,0x73,0x29,0x2c,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x29,0x7b, +0x66,0x2e,0x72,0x65,0x6d,0x6f,0x76,0x65,0x43,0x68,0x69,0x6c,0x64,0x28,0x74,0x68, +0x69,0x73,0x29,0x7d,0x29,0x29,0x2c,0x4d,0x28,0x72,0x29,0x26,0x26,0x28,0x75,0x3d, +0x6e,0x28,0x73,0x29,0x2c,0x6e,0x2e,0x65,0x61,0x63,0x68,0x28,0x72,0x2c,0x66,0x75, +0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x74,0x2c,0x65,0x29,0x7b,0x67,0x2e,0x69,0x6e, +0x64,0x65,0x78,0x4f,0x66,0x28,0x74,0x29,0x3e,0x2d,0x31,0x3f,0x75,0x5b,0x74,0x5d, +0x28,0x65,0x29,0x3a,0x75,0x2e,0x61,0x74,0x74,0x72,0x28,0x74,0x2c,0x65,0x29,0x7d, +0x29,0x29,0x2c,0x73,0x7d,0x2c,0x54,0x2e,0x5a,0x3d,0x66,0x75,0x6e,0x63,0x74,0x69, +0x6f,0x6e,0x28,0x74,0x2c,0x65,0x29,0x7b,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x74, +0x3d,0x74,0x7c,0x7c,0x5b,0x5d,0x2c,0x74,0x2e,0x5f,0x5f,0x70,0x72,0x6f,0x74,0x6f, +0x5f,0x5f,0x3d,0x6e,0x2e,0x66,0x6e,0x2c,0x74,0x2e,0x73,0x65,0x6c,0x65,0x63,0x74, +0x6f,0x72,0x3d,0x65,0x7c,0x7c,0x22,0x22,0x2c,0x74,0x7d,0x2c,0x54,0x2e,0x69,0x73, +0x5a,0x3d,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x74,0x29,0x7b,0x72,0x65, +0x74,0x75,0x72,0x6e,0x20,0x74,0x20,0x69,0x6e,0x73,0x74,0x61,0x6e,0x63,0x65,0x6f, +0x66,0x20,0x54,0x2e,0x5a,0x7d,0x2c,0x54,0x2e,0x69,0x6e,0x69,0x74,0x3d,0x66,0x75, +0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x65,0x2c,0x69,0x29,0x7b,0x76,0x61,0x72,0x20, +0x72,0x3b,0x69,0x66,0x28,0x21,0x65,0x29,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x54, +0x2e,0x5a,0x28,0x29,0x3b,0x69,0x66,0x28,0x22,0x73,0x74,0x72,0x69,0x6e,0x67,0x22, +0x3d,0x3d,0x74,0x79,0x70,0x65,0x6f,0x66,0x20,0x65,0x29,0x69,0x66,0x28,0x65,0x3d, +0x65,0x2e,0x74,0x72,0x69,0x6d,0x28,0x29,0x2c,0x22,0x3c,0x22,0x3d,0x3d,0x65,0x5b, +0x30,0x5d,0x26,0x26,0x6c,0x2e,0x74,0x65,0x73,0x74,0x28,0x65,0x29,0x29,0x72,0x3d, +0x54,0x2e,0x66,0x72,0x61,0x67,0x6d,0x65,0x6e,0x74,0x28,0x65,0x2c,0x52,0x65,0x67, +0x45,0x78,0x70,0x2e,0x24,0x31,0x2c,0x69,0x29,0x2c,0x65,0x3d,0x6e,0x75,0x6c,0x6c, +0x3b,0x65,0x6c,0x73,0x65,0x7b,0x69,0x66,0x28,0x69,0x21,0x3d,0x3d,0x74,0x29,0x72, +0x65,0x74,0x75,0x72,0x6e,0x20,0x6e,0x28,0x69,0x29,0x2e,0x66,0x69,0x6e,0x64,0x28, +0x65,0x29,0x3b,0x72,0x3d,0x54,0x2e,0x71,0x73,0x61,0x28,0x61,0x2c,0x65,0x29,0x7d, +0x65,0x6c,0x73,0x65,0x7b,0x69,0x66,0x28,0x5a,0x28,0x65,0x29,0x29,0x72,0x65,0x74, +0x75,0x72,0x6e,0x20,0x6e,0x28,0x61,0x29,0x2e,0x72,0x65,0x61,0x64,0x79,0x28,0x65, +0x29,0x3b,0x69,0x66,0x28,0x54,0x2e,0x69,0x73,0x5a,0x28,0x65,0x29,0x29,0x72,0x65, +0x74,0x75,0x72,0x6e,0x20,0x65,0x3b,0x69,0x66,0x28,0x41,0x28,0x65,0x29,0x29,0x72, +0x3d,0x6b,0x28,0x65,0x29,0x3b,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x28,0x44,0x28, +0x65,0x29,0x29,0x72,0x3d,0x5b,0x65,0x5d,0x2c,0x65,0x3d,0x6e,0x75,0x6c,0x6c,0x3b, +0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x28,0x6c,0x2e,0x74,0x65,0x73,0x74,0x28,0x65, +0x29,0x29,0x72,0x3d,0x54,0x2e,0x66,0x72,0x61,0x67,0x6d,0x65,0x6e,0x74,0x28,0x65, +0x2e,0x74,0x72,0x69,0x6d,0x28,0x29,0x2c,0x52,0x65,0x67,0x45,0x78,0x70,0x2e,0x24, +0x31,0x2c,0x69,0x29,0x2c,0x65,0x3d,0x6e,0x75,0x6c,0x6c,0x3b,0x65,0x6c,0x73,0x65, +0x7b,0x69,0x66,0x28,0x69,0x21,0x3d,0x3d,0x74,0x29,0x72,0x65,0x74,0x75,0x72,0x6e, +0x20,0x6e,0x28,0x69,0x29,0x2e,0x66,0x69,0x6e,0x64,0x28,0x65,0x29,0x3b,0x72,0x3d, +0x54,0x2e,0x71,0x73,0x61,0x28,0x61,0x2c,0x65,0x29,0x7d,0x7d,0x72,0x65,0x74,0x75, +0x72,0x6e,0x20,0x54,0x2e,0x5a,0x28,0x72,0x2c,0x65,0x29,0x7d,0x2c,0x6e,0x3d,0x66, +0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x74,0x2c,0x65,0x29,0x7b,0x72,0x65,0x74, +0x75,0x72,0x6e,0x20,0x54,0x2e,0x69,0x6e,0x69,0x74,0x28,0x74,0x2c,0x65,0x29,0x7d, +0x2c,0x6e,0x2e,0x65,0x78,0x74,0x65,0x6e,0x64,0x3d,0x66,0x75,0x6e,0x63,0x74,0x69, +0x6f,0x6e,0x28,0x74,0x29,0x7b,0x76,0x61,0x72,0x20,0x65,0x2c,0x6e,0x3d,0x6f,0x2e, +0x63,0x61,0x6c,0x6c,0x28,0x61,0x72,0x67,0x75,0x6d,0x65,0x6e,0x74,0x73,0x2c,0x31, +0x29,0x3b,0x72,0x65,0x74,0x75,0x72,0x6e,0x22,0x62,0x6f,0x6f,0x6c,0x65,0x61,0x6e, +0x22,0x3d,0x3d,0x74,0x79,0x70,0x65,0x6f,0x66,0x20,0x74,0x26,0x26,0x28,0x65,0x3d, +0x74,0x2c,0x74,0x3d,0x6e,0x2e,0x73,0x68,0x69,0x66,0x74,0x28,0x29,0x29,0x2c,0x6e, +0x2e,0x66,0x6f,0x72,0x45,0x61,0x63,0x68,0x28,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f, +0x6e,0x28,0x6e,0x29,0x7b,0x42,0x28,0x74,0x2c,0x6e,0x2c,0x65,0x29,0x7d,0x29,0x2c, +0x74,0x7d,0x2c,0x54,0x2e,0x71,0x73,0x61,0x3d,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f, +0x6e,0x28,0x74,0x2c,0x65,0x29,0x7b,0x76,0x61,0x72,0x20,0x6e,0x2c,0x69,0x3d,0x22, +0x23,0x22,0x3d,0x3d,0x65,0x5b,0x30,0x5d,0x2c,0x72,0x3d,0x21,0x69,0x26,0x26,0x22, +0x2e,0x22,0x3d,0x3d,0x65,0x5b,0x30,0x5d,0x2c,0x73,0x3d,0x69,0x7c,0x7c,0x72,0x3f, +0x65,0x2e,0x73,0x6c,0x69,0x63,0x65,0x28,0x31,0x29,0x3a,0x65,0x2c,0x61,0x3d,0x45, +0x2e,0x74,0x65,0x73,0x74,0x28,0x73,0x29,0x3b,0x72,0x65,0x74,0x75,0x72,0x6e,0x20, +0x24,0x28,0x74,0x29,0x26,0x26,0x61,0x26,0x26,0x69,0x3f,0x28,0x6e,0x3d,0x74,0x2e, +0x67,0x65,0x74,0x45,0x6c,0x65,0x6d,0x65,0x6e,0x74,0x42,0x79,0x49,0x64,0x28,0x73, +0x29,0x29,0x3f,0x5b,0x6e,0x5d,0x3a,0x5b,0x5d,0x3a,0x31,0x21,0x3d,0x3d,0x74,0x2e, +0x6e,0x6f,0x64,0x65,0x54,0x79,0x70,0x65,0x26,0x26,0x39,0x21,0x3d,0x3d,0x74,0x2e, +0x6e,0x6f,0x64,0x65,0x54,0x79,0x70,0x65,0x3f,0x5b,0x5d,0x3a,0x6f,0x2e,0x63,0x61, +0x6c,0x6c,0x28,0x61,0x26,0x26,0x21,0x69,0x3f,0x72,0x3f,0x74,0x2e,0x67,0x65,0x74, +0x45,0x6c,0x65,0x6d,0x65,0x6e,0x74,0x73,0x42,0x79,0x43,0x6c,0x61,0x73,0x73,0x4e, +0x61,0x6d,0x65,0x28,0x73,0x29,0x3a,0x74,0x2e,0x67,0x65,0x74,0x45,0x6c,0x65,0x6d, +0x65,0x6e,0x74,0x73,0x42,0x79,0x54,0x61,0x67,0x4e,0x61,0x6d,0x65,0x28,0x65,0x29, +0x3a,0x74,0x2e,0x71,0x75,0x65,0x72,0x79,0x53,0x65,0x6c,0x65,0x63,0x74,0x6f,0x72, +0x41,0x6c,0x6c,0x28,0x65,0x29,0x29,0x7d,0x2c,0x6e,0x2e,0x63,0x6f,0x6e,0x74,0x61, +0x69,0x6e,0x73,0x3d,0x61,0x2e,0x64,0x6f,0x63,0x75,0x6d,0x65,0x6e,0x74,0x45,0x6c, +0x65,0x6d,0x65,0x6e,0x74,0x2e,0x63,0x6f,0x6e,0x74,0x61,0x69,0x6e,0x73,0x3f,0x66, +0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x74,0x2c,0x65,0x29,0x7b,0x72,0x65,0x74, +0x75,0x72,0x6e,0x20,0x74,0x21,0x3d,0x3d,0x65,0x26,0x26,0x74,0x2e,0x63,0x6f,0x6e, +0x74,0x61,0x69,0x6e,0x73,0x28,0x65,0x29,0x7d,0x3a,0x66,0x75,0x6e,0x63,0x74,0x69, +0x6f,0x6e,0x28,0x74,0x2c,0x65,0x29,0x7b,0x66,0x6f,0x72,0x28,0x3b,0x65,0x26,0x26, +0x28,0x65,0x3d,0x65,0x2e,0x70,0x61,0x72,0x65,0x6e,0x74,0x4e,0x6f,0x64,0x65,0x29, +0x3b,0x29,0x69,0x66,0x28,0x65,0x3d,0x3d,0x3d,0x74,0x29,0x72,0x65,0x74,0x75,0x72, +0x6e,0x21,0x30,0x3b,0x72,0x65,0x74,0x75,0x72,0x6e,0x21,0x31,0x7d,0x2c,0x6e,0x2e, +0x74,0x79,0x70,0x65,0x3d,0x4c,0x2c,0x6e,0x2e,0x69,0x73,0x46,0x75,0x6e,0x63,0x74, +0x69,0x6f,0x6e,0x3d,0x5a,0x2c,0x6e,0x2e,0x69,0x73,0x57,0x69,0x6e,0x64,0x6f,0x77, +0x3d,0x5f,0x2c,0x6e,0x2e,0x69,0x73,0x41,0x72,0x72,0x61,0x79,0x3d,0x41,0x2c,0x6e, +0x2e,0x69,0x73,0x50,0x6c,0x61,0x69,0x6e,0x4f,0x62,0x6a,0x65,0x63,0x74,0x3d,0x4d, +0x2c,0x6e,0x2e,0x69,0x73,0x45,0x6d,0x70,0x74,0x79,0x4f,0x62,0x6a,0x65,0x63,0x74, +0x3d,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x74,0x29,0x7b,0x76,0x61,0x72, +0x20,0x65,0x3b,0x66,0x6f,0x72,0x28,0x65,0x20,0x69,0x6e,0x20,0x74,0x29,0x72,0x65, +0x74,0x75,0x72,0x6e,0x21,0x31,0x3b,0x72,0x65,0x74,0x75,0x72,0x6e,0x21,0x30,0x7d, +0x2c,0x6e,0x2e,0x69,0x6e,0x41,0x72,0x72,0x61,0x79,0x3d,0x66,0x75,0x6e,0x63,0x74, +0x69,0x6f,0x6e,0x28,0x74,0x2c,0x65,0x2c,0x6e,0x29,0x7b,0x72,0x65,0x74,0x75,0x72, +0x6e,0x20,0x72,0x2e,0x69,0x6e,0x64,0x65,0x78,0x4f,0x66,0x2e,0x63,0x61,0x6c,0x6c, +0x28,0x65,0x2c,0x74,0x2c,0x6e,0x29,0x7d,0x2c,0x6e,0x2e,0x63,0x61,0x6d,0x65,0x6c, +0x43,0x61,0x73,0x65,0x3d,0x43,0x2c,0x6e,0x2e,0x74,0x72,0x69,0x6d,0x3d,0x66,0x75, +0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x74,0x29,0x7b,0x72,0x65,0x74,0x75,0x72,0x6e, +0x20,0x6e,0x75,0x6c,0x6c,0x3d,0x3d,0x74,0x3f,0x22,0x22,0x3a,0x53,0x74,0x72,0x69, +0x6e,0x67,0x2e,0x70,0x72,0x6f,0x74,0x6f,0x74,0x79,0x70,0x65,0x2e,0x74,0x72,0x69, +0x6d,0x2e,0x63,0x61,0x6c,0x6c,0x28,0x74,0x29,0x7d,0x2c,0x6e,0x2e,0x75,0x75,0x69, +0x64,0x3d,0x30,0x2c,0x6e,0x2e,0x73,0x75,0x70,0x70,0x6f,0x72,0x74,0x3d,0x7b,0x7d, +0x2c,0x6e,0x2e,0x65,0x78,0x70,0x72,0x3d,0x7b,0x7d,0x2c,0x6e,0x2e,0x6d,0x61,0x70, +0x3d,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x74,0x2c,0x65,0x29,0x7b,0x76, +0x61,0x72,0x20,0x6e,0x2c,0x72,0x2c,0x6f,0x2c,0x69,0x3d,0x5b,0x5d,0x3b,0x69,0x66, +0x28,0x52,0x28,0x74,0x29,0x29,0x66,0x6f,0x72,0x28,0x72,0x3d,0x30,0x3b,0x72,0x3c, +0x74,0x2e,0x6c,0x65,0x6e,0x67,0x74,0x68,0x3b,0x72,0x2b,0x2b,0x29,0x6e,0x3d,0x65, +0x28,0x74,0x5b,0x72,0x5d,0x2c,0x72,0x29,0x2c,0x6e,0x75,0x6c,0x6c,0x21,0x3d,0x6e, +0x26,0x26,0x69,0x2e,0x70,0x75,0x73,0x68,0x28,0x6e,0x29,0x3b,0x65,0x6c,0x73,0x65, +0x20,0x66,0x6f,0x72,0x28,0x6f,0x20,0x69,0x6e,0x20,0x74,0x29,0x6e,0x3d,0x65,0x28, +0x74,0x5b,0x6f,0x5d,0x2c,0x6f,0x29,0x2c,0x6e,0x75,0x6c,0x6c,0x21,0x3d,0x6e,0x26, +0x26,0x69,0x2e,0x70,0x75,0x73,0x68,0x28,0x6e,0x29,0x3b,0x72,0x65,0x74,0x75,0x72, +0x6e,0x20,0x7a,0x28,0x69,0x29,0x7d,0x2c,0x6e,0x2e,0x65,0x61,0x63,0x68,0x3d,0x66, +0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x74,0x2c,0x65,0x29,0x7b,0x76,0x61,0x72, +0x20,0x6e,0x2c,0x69,0x3b,0x69,0x66,0x28,0x52,0x28,0x74,0x29,0x29,0x7b,0x66,0x6f, +0x72,0x28,0x6e,0x3d,0x30,0x3b,0x6e,0x3c,0x74,0x2e,0x6c,0x65,0x6e,0x67,0x74,0x68, +0x3b,0x6e,0x2b,0x2b,0x29,0x69,0x66,0x28,0x65,0x2e,0x63,0x61,0x6c,0x6c,0x28,0x74, +0x5b,0x6e,0x5d,0x2c,0x6e,0x2c,0x74,0x5b,0x6e,0x5d,0x29,0x3d,0x3d,0x3d,0x21,0x31, +0x29,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x74,0x7d,0x65,0x6c,0x73,0x65,0x20,0x66, +0x6f,0x72,0x28,0x69,0x20,0x69,0x6e,0x20,0x74,0x29,0x69,0x66,0x28,0x65,0x2e,0x63, +0x61,0x6c,0x6c,0x28,0x74,0x5b,0x69,0x5d,0x2c,0x69,0x2c,0x74,0x5b,0x69,0x5d,0x29, +0x3d,0x3d,0x3d,0x21,0x31,0x29,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x74,0x3b,0x72, +0x65,0x74,0x75,0x72,0x6e,0x20,0x74,0x7d,0x2c,0x6e,0x2e,0x67,0x72,0x65,0x70,0x3d, +0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x74,0x2c,0x65,0x29,0x7b,0x72,0x65, +0x74,0x75,0x72,0x6e,0x20,0x73,0x2e,0x63,0x61,0x6c,0x6c,0x28,0x74,0x2c,0x65,0x29, +0x7d,0x2c,0x77,0x69,0x6e,0x64,0x6f,0x77,0x2e,0x4a,0x53,0x4f,0x4e,0x26,0x26,0x28, +0x6e,0x2e,0x70,0x61,0x72,0x73,0x65,0x4a,0x53,0x4f,0x4e,0x3d,0x4a,0x53,0x4f,0x4e, +0x2e,0x70,0x61,0x72,0x73,0x65,0x29,0x2c,0x6e,0x2e,0x65,0x61,0x63,0x68,0x28,0x22, +0x42,0x6f,0x6f,0x6c,0x65,0x61,0x6e,0x20,0x4e,0x75,0x6d,0x62,0x65,0x72,0x20,0x53, +0x74,0x72,0x69,0x6e,0x67,0x20,0x46,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x20,0x41, +0x72,0x72,0x61,0x79,0x20,0x44,0x61,0x74,0x65,0x20,0x52,0x65,0x67,0x45,0x78,0x70, +0x20,0x4f,0x62,0x6a,0x65,0x63,0x74,0x20,0x45,0x72,0x72,0x6f,0x72,0x22,0x2e,0x73, +0x70,0x6c,0x69,0x74,0x28,0x22,0x20,0x22,0x29,0x2c,0x66,0x75,0x6e,0x63,0x74,0x69, +0x6f,0x6e,0x28,0x74,0x2c,0x65,0x29,0x7b,0x6a,0x5b,0x22,0x5b,0x6f,0x62,0x6a,0x65, +0x63,0x74,0x20,0x22,0x2b,0x65,0x2b,0x22,0x5d,0x22,0x5d,0x3d,0x65,0x2e,0x74,0x6f, +0x4c,0x6f,0x77,0x65,0x72,0x43,0x61,0x73,0x65,0x28,0x29,0x7d,0x29,0x2c,0x6e,0x2e, +0x66,0x6e,0x3d,0x7b,0x66,0x6f,0x72,0x45,0x61,0x63,0x68,0x3a,0x72,0x2e,0x66,0x6f, +0x72,0x45,0x61,0x63,0x68,0x2c,0x72,0x65,0x64,0x75,0x63,0x65,0x3a,0x72,0x2e,0x72, +0x65,0x64,0x75,0x63,0x65,0x2c,0x70,0x75,0x73,0x68,0x3a,0x72,0x2e,0x70,0x75,0x73, +0x68,0x2c,0x73,0x6f,0x72,0x74,0x3a,0x72,0x2e,0x73,0x6f,0x72,0x74,0x2c,0x69,0x6e, +0x64,0x65,0x78,0x4f,0x66,0x3a,0x72,0x2e,0x69,0x6e,0x64,0x65,0x78,0x4f,0x66,0x2c, +0x63,0x6f,0x6e,0x63,0x61,0x74,0x3a,0x72,0x2e,0x63,0x6f,0x6e,0x63,0x61,0x74,0x2c, +0x6d,0x61,0x70,0x3a,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x74,0x29,0x7b, +0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x6e,0x28,0x6e,0x2e,0x6d,0x61,0x70,0x28,0x74, +0x68,0x69,0x73,0x2c,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x65,0x2c,0x6e, +0x29,0x7b,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x74,0x2e,0x63,0x61,0x6c,0x6c,0x28, +0x65,0x2c,0x6e,0x2c,0x65,0x29,0x7d,0x29,0x29,0x7d,0x2c,0x73,0x6c,0x69,0x63,0x65, +0x3a,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x29,0x7b,0x72,0x65,0x74,0x75, +0x72,0x6e,0x20,0x6e,0x28,0x6f,0x2e,0x61,0x70,0x70,0x6c,0x79,0x28,0x74,0x68,0x69, +0x73,0x2c,0x61,0x72,0x67,0x75,0x6d,0x65,0x6e,0x74,0x73,0x29,0x29,0x7d,0x2c,0x72, +0x65,0x61,0x64,0x79,0x3a,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x74,0x29, +0x7b,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x77,0x2e,0x74,0x65,0x73,0x74,0x28,0x61, +0x2e,0x72,0x65,0x61,0x64,0x79,0x53,0x74,0x61,0x74,0x65,0x29,0x26,0x26,0x61,0x2e, +0x62,0x6f,0x64,0x79,0x3f,0x74,0x28,0x6e,0x29,0x3a,0x61,0x2e,0x61,0x64,0x64,0x45, +0x76,0x65,0x6e,0x74,0x4c,0x69,0x73,0x74,0x65,0x6e,0x65,0x72,0x28,0x22,0x44,0x4f, +0x4d,0x43,0x6f,0x6e,0x74,0x65,0x6e,0x74,0x4c,0x6f,0x61,0x64,0x65,0x64,0x22,0x2c, +0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x29,0x7b,0x74,0x28,0x6e,0x29,0x7d, +0x2c,0x21,0x31,0x29,0x2c,0x74,0x68,0x69,0x73,0x7d,0x2c,0x67,0x65,0x74,0x3a,0x66, +0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x65,0x29,0x7b,0x72,0x65,0x74,0x75,0x72, +0x6e,0x20,0x65,0x3d,0x3d,0x3d,0x74,0x3f,0x6f,0x2e,0x63,0x61,0x6c,0x6c,0x28,0x74, +0x68,0x69,0x73,0x29,0x3a,0x74,0x68,0x69,0x73,0x5b,0x65,0x3e,0x3d,0x30,0x3f,0x65, +0x3a,0x65,0x2b,0x74,0x68,0x69,0x73,0x2e,0x6c,0x65,0x6e,0x67,0x74,0x68,0x5d,0x7d, +0x2c,0x74,0x6f,0x41,0x72,0x72,0x61,0x79,0x3a,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f, +0x6e,0x28,0x29,0x7b,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x74,0x68,0x69,0x73,0x2e, +0x67,0x65,0x74,0x28,0x29,0x7d,0x2c,0x73,0x69,0x7a,0x65,0x3a,0x66,0x75,0x6e,0x63, +0x74,0x69,0x6f,0x6e,0x28,0x29,0x7b,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x74,0x68, +0x69,0x73,0x2e,0x6c,0x65,0x6e,0x67,0x74,0x68,0x7d,0x2c,0x72,0x65,0x6d,0x6f,0x76, +0x65,0x3a,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x29,0x7b,0x72,0x65,0x74, +0x75,0x72,0x6e,0x20,0x74,0x68,0x69,0x73,0x2e,0x65,0x61,0x63,0x68,0x28,0x66,0x75, +0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x29,0x7b,0x6e,0x75,0x6c,0x6c,0x21,0x3d,0x74, +0x68,0x69,0x73,0x2e,0x70,0x61,0x72,0x65,0x6e,0x74,0x4e,0x6f,0x64,0x65,0x26,0x26, +0x74,0x68,0x69,0x73,0x2e,0x70,0x61,0x72,0x65,0x6e,0x74,0x4e,0x6f,0x64,0x65,0x2e, +0x72,0x65,0x6d,0x6f,0x76,0x65,0x43,0x68,0x69,0x6c,0x64,0x28,0x74,0x68,0x69,0x73, +0x29,0x7d,0x29,0x7d,0x2c,0x65,0x61,0x63,0x68,0x3a,0x66,0x75,0x6e,0x63,0x74,0x69, +0x6f,0x6e,0x28,0x74,0x29,0x7b,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x72,0x2e,0x65, +0x76,0x65,0x72,0x79,0x2e,0x63,0x61,0x6c,0x6c,0x28,0x74,0x68,0x69,0x73,0x2c,0x66, +0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x65,0x2c,0x6e,0x29,0x7b,0x72,0x65,0x74, +0x75,0x72,0x6e,0x20,0x74,0x2e,0x63,0x61,0x6c,0x6c,0x28,0x65,0x2c,0x6e,0x2c,0x65, +0x29,0x21,0x3d,0x3d,0x21,0x31,0x7d,0x29,0x2c,0x74,0x68,0x69,0x73,0x7d,0x2c,0x66, +0x69,0x6c,0x74,0x65,0x72,0x3a,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x74, +0x29,0x7b,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x5a,0x28,0x74,0x29,0x3f,0x74,0x68, +0x69,0x73,0x2e,0x6e,0x6f,0x74,0x28,0x74,0x68,0x69,0x73,0x2e,0x6e,0x6f,0x74,0x28, +0x74,0x29,0x29,0x3a,0x6e,0x28,0x73,0x2e,0x63,0x61,0x6c,0x6c,0x28,0x74,0x68,0x69, +0x73,0x2c,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x65,0x29,0x7b,0x72,0x65, +0x74,0x75,0x72,0x6e,0x20,0x54,0x2e,0x6d,0x61,0x74,0x63,0x68,0x65,0x73,0x28,0x65, +0x2c,0x74,0x29,0x7d,0x29,0x29,0x7d,0x2c,0x61,0x64,0x64,0x3a,0x66,0x75,0x6e,0x63, +0x74,0x69,0x6f,0x6e,0x28,0x74,0x2c,0x65,0x29,0x7b,0x72,0x65,0x74,0x75,0x72,0x6e, +0x20,0x6e,0x28,0x4e,0x28,0x74,0x68,0x69,0x73,0x2e,0x63,0x6f,0x6e,0x63,0x61,0x74, +0x28,0x6e,0x28,0x74,0x2c,0x65,0x29,0x29,0x29,0x29,0x7d,0x2c,0x69,0x73,0x3a,0x66, +0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x74,0x29,0x7b,0x72,0x65,0x74,0x75,0x72, +0x6e,0x20,0x74,0x68,0x69,0x73,0x2e,0x6c,0x65,0x6e,0x67,0x74,0x68,0x3e,0x30,0x26, +0x26,0x54,0x2e,0x6d,0x61,0x74,0x63,0x68,0x65,0x73,0x28,0x74,0x68,0x69,0x73,0x5b, +0x30,0x5d,0x2c,0x74,0x29,0x7d,0x2c,0x6e,0x6f,0x74,0x3a,0x66,0x75,0x6e,0x63,0x74, +0x69,0x6f,0x6e,0x28,0x65,0x29,0x7b,0x76,0x61,0x72,0x20,0x69,0x3d,0x5b,0x5d,0x3b, +0x69,0x66,0x28,0x5a,0x28,0x65,0x29,0x26,0x26,0x65,0x2e,0x63,0x61,0x6c,0x6c,0x21, +0x3d,0x3d,0x74,0x29,0x74,0x68,0x69,0x73,0x2e,0x65,0x61,0x63,0x68,0x28,0x66,0x75, +0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x74,0x29,0x7b,0x65,0x2e,0x63,0x61,0x6c,0x6c, +0x28,0x74,0x68,0x69,0x73,0x2c,0x74,0x29,0x7c,0x7c,0x69,0x2e,0x70,0x75,0x73,0x68, +0x28,0x74,0x68,0x69,0x73,0x29,0x7d,0x29,0x3b,0x65,0x6c,0x73,0x65,0x7b,0x76,0x61, +0x72,0x20,0x72,0x3d,0x22,0x73,0x74,0x72,0x69,0x6e,0x67,0x22,0x3d,0x3d,0x74,0x79, +0x70,0x65,0x6f,0x66,0x20,0x65,0x3f,0x74,0x68,0x69,0x73,0x2e,0x66,0x69,0x6c,0x74, +0x65,0x72,0x28,0x65,0x29,0x3a,0x52,0x28,0x65,0x29,0x26,0x26,0x5a,0x28,0x65,0x2e, +0x69,0x74,0x65,0x6d,0x29,0x3f,0x6f,0x2e,0x63,0x61,0x6c,0x6c,0x28,0x65,0x29,0x3a, +0x6e,0x28,0x65,0x29,0x3b,0x74,0x68,0x69,0x73,0x2e,0x66,0x6f,0x72,0x45,0x61,0x63, +0x68,0x28,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x74,0x29,0x7b,0x72,0x2e, +0x69,0x6e,0x64,0x65,0x78,0x4f,0x66,0x28,0x74,0x29,0x3c,0x30,0x26,0x26,0x69,0x2e, +0x70,0x75,0x73,0x68,0x28,0x74,0x29,0x7d,0x29,0x7d,0x72,0x65,0x74,0x75,0x72,0x6e, +0x20,0x6e,0x28,0x69,0x29,0x7d,0x2c,0x68,0x61,0x73,0x3a,0x66,0x75,0x6e,0x63,0x74, +0x69,0x6f,0x6e,0x28,0x74,0x29,0x7b,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x74,0x68, +0x69,0x73,0x2e,0x66,0x69,0x6c,0x74,0x65,0x72,0x28,0x66,0x75,0x6e,0x63,0x74,0x69, +0x6f,0x6e,0x28,0x29,0x7b,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x44,0x28,0x74,0x29, +0x3f,0x6e,0x2e,0x63,0x6f,0x6e,0x74,0x61,0x69,0x6e,0x73,0x28,0x74,0x68,0x69,0x73, +0x2c,0x74,0x29,0x3a,0x6e,0x28,0x74,0x68,0x69,0x73,0x29,0x2e,0x66,0x69,0x6e,0x64, +0x28,0x74,0x29,0x2e,0x73,0x69,0x7a,0x65,0x28,0x29,0x7d,0x29,0x7d,0x2c,0x65,0x71, +0x3a,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x74,0x29,0x7b,0x72,0x65,0x74, +0x75,0x72,0x6e,0x2d,0x31,0x3d,0x3d,0x3d,0x74,0x3f,0x74,0x68,0x69,0x73,0x2e,0x73, +0x6c,0x69,0x63,0x65,0x28,0x74,0x29,0x3a,0x74,0x68,0x69,0x73,0x2e,0x73,0x6c,0x69, +0x63,0x65,0x28,0x74,0x2c,0x2b,0x74,0x2b,0x31,0x29,0x7d,0x2c,0x66,0x69,0x72,0x73, +0x74,0x3a,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x29,0x7b,0x76,0x61,0x72, +0x20,0x74,0x3d,0x74,0x68,0x69,0x73,0x5b,0x30,0x5d,0x3b,0x72,0x65,0x74,0x75,0x72, +0x6e,0x20,0x74,0x26,0x26,0x21,0x44,0x28,0x74,0x29,0x3f,0x74,0x3a,0x6e,0x28,0x74, +0x29,0x7d,0x2c,0x6c,0x61,0x73,0x74,0x3a,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e, +0x28,0x29,0x7b,0x76,0x61,0x72,0x20,0x74,0x3d,0x74,0x68,0x69,0x73,0x5b,0x74,0x68, +0x69,0x73,0x2e,0x6c,0x65,0x6e,0x67,0x74,0x68,0x2d,0x31,0x5d,0x3b,0x72,0x65,0x74, +0x75,0x72,0x6e,0x20,0x74,0x26,0x26,0x21,0x44,0x28,0x74,0x29,0x3f,0x74,0x3a,0x6e, +0x28,0x74,0x29,0x7d,0x2c,0x66,0x69,0x6e,0x64,0x3a,0x66,0x75,0x6e,0x63,0x74,0x69, +0x6f,0x6e,0x28,0x74,0x29,0x7b,0x76,0x61,0x72,0x20,0x65,0x2c,0x69,0x3d,0x74,0x68, +0x69,0x73,0x3b,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x65,0x3d,0x74,0x3f,0x22,0x6f, +0x62,0x6a,0x65,0x63,0x74,0x22,0x3d,0x3d,0x74,0x79,0x70,0x65,0x6f,0x66,0x20,0x74, +0x3f,0x6e,0x28,0x74,0x29,0x2e,0x66,0x69,0x6c,0x74,0x65,0x72,0x28,0x66,0x75,0x6e, +0x63,0x74,0x69,0x6f,0x6e,0x28,0x29,0x7b,0x76,0x61,0x72,0x20,0x74,0x3d,0x74,0x68, +0x69,0x73,0x3b,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x72,0x2e,0x73,0x6f,0x6d,0x65, +0x2e,0x63,0x61,0x6c,0x6c,0x28,0x69,0x2c,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e, +0x28,0x65,0x29,0x7b,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x6e,0x2e,0x63,0x6f,0x6e, +0x74,0x61,0x69,0x6e,0x73,0x28,0x65,0x2c,0x74,0x29,0x7d,0x29,0x7d,0x29,0x3a,0x31, +0x3d,0x3d,0x74,0x68,0x69,0x73,0x2e,0x6c,0x65,0x6e,0x67,0x74,0x68,0x3f,0x6e,0x28, +0x54,0x2e,0x71,0x73,0x61,0x28,0x74,0x68,0x69,0x73,0x5b,0x30,0x5d,0x2c,0x74,0x29, +0x29,0x3a,0x74,0x68,0x69,0x73,0x2e,0x6d,0x61,0x70,0x28,0x66,0x75,0x6e,0x63,0x74, +0x69,0x6f,0x6e,0x28,0x29,0x7b,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x54,0x2e,0x71, +0x73,0x61,0x28,0x74,0x68,0x69,0x73,0x2c,0x74,0x29,0x7d,0x29,0x3a,0x6e,0x28,0x29, +0x7d,0x2c,0x63,0x6c,0x6f,0x73,0x65,0x73,0x74,0x3a,0x66,0x75,0x6e,0x63,0x74,0x69, +0x6f,0x6e,0x28,0x74,0x2c,0x65,0x29,0x7b,0x76,0x61,0x72,0x20,0x69,0x3d,0x74,0x68, +0x69,0x73,0x5b,0x30,0x5d,0x2c,0x72,0x3d,0x21,0x31,0x3b,0x66,0x6f,0x72,0x28,0x22, +0x6f,0x62,0x6a,0x65,0x63,0x74,0x22,0x3d,0x3d,0x74,0x79,0x70,0x65,0x6f,0x66,0x20, +0x74,0x26,0x26,0x28,0x72,0x3d,0x6e,0x28,0x74,0x29,0x29,0x3b,0x69,0x26,0x26,0x21, +0x28,0x72,0x3f,0x72,0x2e,0x69,0x6e,0x64,0x65,0x78,0x4f,0x66,0x28,0x69,0x29,0x3e, +0x3d,0x30,0x3a,0x54,0x2e,0x6d,0x61,0x74,0x63,0x68,0x65,0x73,0x28,0x69,0x2c,0x74, +0x29,0x29,0x3b,0x29,0x69,0x3d,0x69,0x21,0x3d,0x3d,0x65,0x26,0x26,0x21,0x24,0x28, +0x69,0x29,0x26,0x26,0x69,0x2e,0x70,0x61,0x72,0x65,0x6e,0x74,0x4e,0x6f,0x64,0x65, +0x3b,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x6e,0x28,0x69,0x29,0x7d,0x2c,0x70,0x61, +0x72,0x65,0x6e,0x74,0x73,0x3a,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x74, +0x29,0x7b,0x66,0x6f,0x72,0x28,0x76,0x61,0x72,0x20,0x65,0x3d,0x5b,0x5d,0x2c,0x69, +0x3d,0x74,0x68,0x69,0x73,0x3b,0x69,0x2e,0x6c,0x65,0x6e,0x67,0x74,0x68,0x3e,0x30, +0x3b,0x29,0x69,0x3d,0x6e,0x2e,0x6d,0x61,0x70,0x28,0x69,0x2c,0x66,0x75,0x6e,0x63, +0x74,0x69,0x6f,0x6e,0x28,0x74,0x29,0x7b,0x72,0x65,0x74,0x75,0x72,0x6e,0x28,0x74, +0x3d,0x74,0x2e,0x70,0x61,0x72,0x65,0x6e,0x74,0x4e,0x6f,0x64,0x65,0x29,0x26,0x26, +0x21,0x24,0x28,0x74,0x29,0x26,0x26,0x65,0x2e,0x69,0x6e,0x64,0x65,0x78,0x4f,0x66, +0x28,0x74,0x29,0x3c,0x30,0x3f,0x28,0x65,0x2e,0x70,0x75,0x73,0x68,0x28,0x74,0x29, +0x2c,0x74,0x29,0x3a,0x76,0x6f,0x69,0x64,0x20,0x30,0x7d,0x29,0x3b,0x72,0x65,0x74, +0x75,0x72,0x6e,0x20,0x55,0x28,0x65,0x2c,0x74,0x29,0x7d,0x2c,0x70,0x61,0x72,0x65, +0x6e,0x74,0x3a,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x74,0x29,0x7b,0x72, +0x65,0x74,0x75,0x72,0x6e,0x20,0x55,0x28,0x4e,0x28,0x74,0x68,0x69,0x73,0x2e,0x70, +0x6c,0x75,0x63,0x6b,0x28,0x22,0x70,0x61,0x72,0x65,0x6e,0x74,0x4e,0x6f,0x64,0x65, +0x22,0x29,0x29,0x2c,0x74,0x29,0x7d,0x2c,0x63,0x68,0x69,0x6c,0x64,0x72,0x65,0x6e, +0x3a,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x74,0x29,0x7b,0x72,0x65,0x74, +0x75,0x72,0x6e,0x20,0x55,0x28,0x74,0x68,0x69,0x73,0x2e,0x6d,0x61,0x70,0x28,0x66, +0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x29,0x7b,0x72,0x65,0x74,0x75,0x72,0x6e, +0x20,0x56,0x28,0x74,0x68,0x69,0x73,0x29,0x7d,0x29,0x2c,0x74,0x29,0x7d,0x2c,0x63, +0x6f,0x6e,0x74,0x65,0x6e,0x74,0x73,0x3a,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e, +0x28,0x29,0x7b,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x74,0x68,0x69,0x73,0x2e,0x6d, +0x61,0x70,0x28,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x29,0x7b,0x72,0x65, +0x74,0x75,0x72,0x6e,0x20,0x6f,0x2e,0x63,0x61,0x6c,0x6c,0x28,0x74,0x68,0x69,0x73, +0x2e,0x63,0x68,0x69,0x6c,0x64,0x4e,0x6f,0x64,0x65,0x73,0x29,0x7d,0x29,0x7d,0x2c, +0x73,0x69,0x62,0x6c,0x69,0x6e,0x67,0x73,0x3a,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f, +0x6e,0x28,0x74,0x29,0x7b,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x55,0x28,0x74,0x68, +0x69,0x73,0x2e,0x6d,0x61,0x70,0x28,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28, +0x74,0x2c,0x65,0x29,0x7b,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x73,0x2e,0x63,0x61, +0x6c,0x6c,0x28,0x56,0x28,0x65,0x2e,0x70,0x61,0x72,0x65,0x6e,0x74,0x4e,0x6f,0x64, +0x65,0x29,0x2c,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x74,0x29,0x7b,0x72, +0x65,0x74,0x75,0x72,0x6e,0x20,0x74,0x21,0x3d,0x3d,0x65,0x7d,0x29,0x7d,0x29,0x2c, +0x74,0x29,0x7d,0x2c,0x65,0x6d,0x70,0x74,0x79,0x3a,0x66,0x75,0x6e,0x63,0x74,0x69, +0x6f,0x6e,0x28,0x29,0x7b,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x74,0x68,0x69,0x73, +0x2e,0x65,0x61,0x63,0x68,0x28,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x29, +0x7b,0x74,0x68,0x69,0x73,0x2e,0x69,0x6e,0x6e,0x65,0x72,0x48,0x54,0x4d,0x4c,0x3d, +0x22,0x22,0x7d,0x29,0x7d,0x2c,0x70,0x6c,0x75,0x63,0x6b,0x3a,0x66,0x75,0x6e,0x63, +0x74,0x69,0x6f,0x6e,0x28,0x74,0x29,0x7b,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x6e, +0x2e,0x6d,0x61,0x70,0x28,0x74,0x68,0x69,0x73,0x2c,0x66,0x75,0x6e,0x63,0x74,0x69, +0x6f,0x6e,0x28,0x65,0x29,0x7b,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x65,0x5b,0x74, +0x5d,0x7d,0x29,0x7d,0x2c,0x73,0x68,0x6f,0x77,0x3a,0x66,0x75,0x6e,0x63,0x74,0x69, +0x6f,0x6e,0x28,0x29,0x7b,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x74,0x68,0x69,0x73, +0x2e,0x65,0x61,0x63,0x68,0x28,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x29, +0x7b,0x22,0x6e,0x6f,0x6e,0x65,0x22,0x3d,0x3d,0x74,0x68,0x69,0x73,0x2e,0x73,0x74, +0x79,0x6c,0x65,0x2e,0x64,0x69,0x73,0x70,0x6c,0x61,0x79,0x26,0x26,0x28,0x74,0x68, +0x69,0x73,0x2e,0x73,0x74,0x79,0x6c,0x65,0x2e,0x64,0x69,0x73,0x70,0x6c,0x61,0x79, +0x3d,0x22,0x22,0x29,0x2c,0x22,0x6e,0x6f,0x6e,0x65,0x22,0x3d,0x3d,0x67,0x65,0x74, +0x43,0x6f,0x6d,0x70,0x75,0x74,0x65,0x64,0x53,0x74,0x79,0x6c,0x65,0x28,0x74,0x68, +0x69,0x73,0x2c,0x22,0x22,0x29,0x2e,0x67,0x65,0x74,0x50,0x72,0x6f,0x70,0x65,0x72, +0x74,0x79,0x56,0x61,0x6c,0x75,0x65,0x28,0x22,0x64,0x69,0x73,0x70,0x6c,0x61,0x79, +0x22,0x29,0x26,0x26,0x28,0x74,0x68,0x69,0x73,0x2e,0x73,0x74,0x79,0x6c,0x65,0x2e, +0x64,0x69,0x73,0x70,0x6c,0x61,0x79,0x3d,0x49,0x28,0x74,0x68,0x69,0x73,0x2e,0x6e, +0x6f,0x64,0x65,0x4e,0x61,0x6d,0x65,0x29,0x29,0x7d,0x29,0x7d,0x2c,0x72,0x65,0x70, +0x6c,0x61,0x63,0x65,0x57,0x69,0x74,0x68,0x3a,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f, +0x6e,0x28,0x74,0x29,0x7b,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x74,0x68,0x69,0x73, +0x2e,0x62,0x65,0x66,0x6f,0x72,0x65,0x28,0x74,0x29,0x2e,0x72,0x65,0x6d,0x6f,0x76, +0x65,0x28,0x29,0x7d,0x2c,0x77,0x72,0x61,0x70,0x3a,0x66,0x75,0x6e,0x63,0x74,0x69, +0x6f,0x6e,0x28,0x74,0x29,0x7b,0x76,0x61,0x72,0x20,0x65,0x3d,0x5a,0x28,0x74,0x29, +0x3b,0x69,0x66,0x28,0x74,0x68,0x69,0x73,0x5b,0x30,0x5d,0x26,0x26,0x21,0x65,0x29, +0x76,0x61,0x72,0x20,0x69,0x3d,0x6e,0x28,0x74,0x29,0x2e,0x67,0x65,0x74,0x28,0x30, +0x29,0x2c,0x72,0x3d,0x69,0x2e,0x70,0x61,0x72,0x65,0x6e,0x74,0x4e,0x6f,0x64,0x65, +0x7c,0x7c,0x74,0x68,0x69,0x73,0x2e,0x6c,0x65,0x6e,0x67,0x74,0x68,0x3e,0x31,0x3b, +0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x74,0x68,0x69,0x73,0x2e,0x65,0x61,0x63,0x68, +0x28,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x6f,0x29,0x7b,0x6e,0x28,0x74, +0x68,0x69,0x73,0x29,0x2e,0x77,0x72,0x61,0x70,0x41,0x6c,0x6c,0x28,0x65,0x3f,0x74, +0x2e,0x63,0x61,0x6c,0x6c,0x28,0x74,0x68,0x69,0x73,0x2c,0x6f,0x29,0x3a,0x72,0x3f, +0x69,0x2e,0x63,0x6c,0x6f,0x6e,0x65,0x4e,0x6f,0x64,0x65,0x28,0x21,0x30,0x29,0x3a, +0x69,0x29,0x7d,0x29,0x7d,0x2c,0x77,0x72,0x61,0x70,0x41,0x6c,0x6c,0x3a,0x66,0x75, +0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x74,0x29,0x7b,0x69,0x66,0x28,0x74,0x68,0x69, +0x73,0x5b,0x30,0x5d,0x29,0x7b,0x6e,0x28,0x74,0x68,0x69,0x73,0x5b,0x30,0x5d,0x29, +0x2e,0x62,0x65,0x66,0x6f,0x72,0x65,0x28,0x74,0x3d,0x6e,0x28,0x74,0x29,0x29,0x3b, +0x66,0x6f,0x72,0x28,0x76,0x61,0x72,0x20,0x65,0x3b,0x28,0x65,0x3d,0x74,0x2e,0x63, +0x68,0x69,0x6c,0x64,0x72,0x65,0x6e,0x28,0x29,0x29,0x2e,0x6c,0x65,0x6e,0x67,0x74, +0x68,0x3b,0x29,0x74,0x3d,0x65,0x2e,0x66,0x69,0x72,0x73,0x74,0x28,0x29,0x3b,0x6e, +0x28,0x74,0x29,0x2e,0x61,0x70,0x70,0x65,0x6e,0x64,0x28,0x74,0x68,0x69,0x73,0x29, +0x7d,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x74,0x68,0x69,0x73,0x7d,0x2c,0x77,0x72, +0x61,0x70,0x49,0x6e,0x6e,0x65,0x72,0x3a,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e, +0x28,0x74,0x29,0x7b,0x76,0x61,0x72,0x20,0x65,0x3d,0x5a,0x28,0x74,0x29,0x3b,0x72, +0x65,0x74,0x75,0x72,0x6e,0x20,0x74,0x68,0x69,0x73,0x2e,0x65,0x61,0x63,0x68,0x28, +0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x69,0x29,0x7b,0x76,0x61,0x72,0x20, +0x72,0x3d,0x6e,0x28,0x74,0x68,0x69,0x73,0x29,0x2c,0x6f,0x3d,0x72,0x2e,0x63,0x6f, +0x6e,0x74,0x65,0x6e,0x74,0x73,0x28,0x29,0x2c,0x73,0x3d,0x65,0x3f,0x74,0x2e,0x63, +0x61,0x6c,0x6c,0x28,0x74,0x68,0x69,0x73,0x2c,0x69,0x29,0x3a,0x74,0x3b,0x6f,0x2e, +0x6c,0x65,0x6e,0x67,0x74,0x68,0x3f,0x6f,0x2e,0x77,0x72,0x61,0x70,0x41,0x6c,0x6c, +0x28,0x73,0x29,0x3a,0x72,0x2e,0x61,0x70,0x70,0x65,0x6e,0x64,0x28,0x73,0x29,0x7d, +0x29,0x7d,0x2c,0x75,0x6e,0x77,0x72,0x61,0x70,0x3a,0x66,0x75,0x6e,0x63,0x74,0x69, +0x6f,0x6e,0x28,0x29,0x7b,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x74,0x68,0x69,0x73, +0x2e,0x70,0x61,0x72,0x65,0x6e,0x74,0x28,0x29,0x2e,0x65,0x61,0x63,0x68,0x28,0x66, +0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x29,0x7b,0x6e,0x28,0x74,0x68,0x69,0x73, +0x29,0x2e,0x72,0x65,0x70,0x6c,0x61,0x63,0x65,0x57,0x69,0x74,0x68,0x28,0x6e,0x28, +0x74,0x68,0x69,0x73,0x29,0x2e,0x63,0x68,0x69,0x6c,0x64,0x72,0x65,0x6e,0x28,0x29, +0x29,0x7d,0x29,0x2c,0x74,0x68,0x69,0x73,0x7d,0x2c,0x63,0x6c,0x6f,0x6e,0x65,0x3a, +0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x29,0x7b,0x72,0x65,0x74,0x75,0x72, +0x6e,0x20,0x74,0x68,0x69,0x73,0x2e,0x6d,0x61,0x70,0x28,0x66,0x75,0x6e,0x63,0x74, +0x69,0x6f,0x6e,0x28,0x29,0x7b,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x74,0x68,0x69, +0x73,0x2e,0x63,0x6c,0x6f,0x6e,0x65,0x4e,0x6f,0x64,0x65,0x28,0x21,0x30,0x29,0x7d, +0x29,0x7d,0x2c,0x68,0x69,0x64,0x65,0x3a,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e, +0x28,0x29,0x7b,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x74,0x68,0x69,0x73,0x2e,0x63, +0x73,0x73,0x28,0x22,0x64,0x69,0x73,0x70,0x6c,0x61,0x79,0x22,0x2c,0x22,0x6e,0x6f, +0x6e,0x65,0x22,0x29,0x7d,0x2c,0x74,0x6f,0x67,0x67,0x6c,0x65,0x3a,0x66,0x75,0x6e, +0x63,0x74,0x69,0x6f,0x6e,0x28,0x65,0x29,0x7b,0x72,0x65,0x74,0x75,0x72,0x6e,0x20, +0x74,0x68,0x69,0x73,0x2e,0x65,0x61,0x63,0x68,0x28,0x66,0x75,0x6e,0x63,0x74,0x69, +0x6f,0x6e,0x28,0x29,0x7b,0x76,0x61,0x72,0x20,0x69,0x3d,0x6e,0x28,0x74,0x68,0x69, +0x73,0x29,0x3b,0x28,0x65,0x3d,0x3d,0x3d,0x74,0x3f,0x22,0x6e,0x6f,0x6e,0x65,0x22, +0x3d,0x3d,0x69,0x2e,0x63,0x73,0x73,0x28,0x22,0x64,0x69,0x73,0x70,0x6c,0x61,0x79, +0x22,0x29,0x3a,0x65,0x29,0x3f,0x69,0x2e,0x73,0x68,0x6f,0x77,0x28,0x29,0x3a,0x69, +0x2e,0x68,0x69,0x64,0x65,0x28,0x29,0x7d,0x29,0x7d,0x2c,0x70,0x72,0x65,0x76,0x3a, +0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x74,0x29,0x7b,0x72,0x65,0x74,0x75, +0x72,0x6e,0x20,0x6e,0x28,0x74,0x68,0x69,0x73,0x2e,0x70,0x6c,0x75,0x63,0x6b,0x28, +0x22,0x70,0x72,0x65,0x76,0x69,0x6f,0x75,0x73,0x45,0x6c,0x65,0x6d,0x65,0x6e,0x74, +0x53,0x69,0x62,0x6c,0x69,0x6e,0x67,0x22,0x29,0x29,0x2e,0x66,0x69,0x6c,0x74,0x65, +0x72,0x28,0x74,0x7c,0x7c,0x22,0x2a,0x22,0x29,0x7d,0x2c,0x6e,0x65,0x78,0x74,0x3a, +0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x74,0x29,0x7b,0x72,0x65,0x74,0x75, +0x72,0x6e,0x20,0x6e,0x28,0x74,0x68,0x69,0x73,0x2e,0x70,0x6c,0x75,0x63,0x6b,0x28, +0x22,0x6e,0x65,0x78,0x74,0x45,0x6c,0x65,0x6d,0x65,0x6e,0x74,0x53,0x69,0x62,0x6c, +0x69,0x6e,0x67,0x22,0x29,0x29,0x2e,0x66,0x69,0x6c,0x74,0x65,0x72,0x28,0x74,0x7c, +0x7c,0x22,0x2a,0x22,0x29,0x7d,0x2c,0x68,0x74,0x6d,0x6c,0x3a,0x66,0x75,0x6e,0x63, +0x74,0x69,0x6f,0x6e,0x28,0x74,0x29,0x7b,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x30, +0x20,0x69,0x6e,0x20,0x61,0x72,0x67,0x75,0x6d,0x65,0x6e,0x74,0x73,0x3f,0x74,0x68, +0x69,0x73,0x2e,0x65,0x61,0x63,0x68,0x28,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e, +0x28,0x65,0x29,0x7b,0x76,0x61,0x72,0x20,0x69,0x3d,0x74,0x68,0x69,0x73,0x2e,0x69, +0x6e,0x6e,0x65,0x72,0x48,0x54,0x4d,0x4c,0x3b,0x6e,0x28,0x74,0x68,0x69,0x73,0x29, +0x2e,0x65,0x6d,0x70,0x74,0x79,0x28,0x29,0x2e,0x61,0x70,0x70,0x65,0x6e,0x64,0x28, +0x4a,0x28,0x74,0x68,0x69,0x73,0x2c,0x74,0x2c,0x65,0x2c,0x69,0x29,0x29,0x7d,0x29, +0x3a,0x30,0x20,0x69,0x6e,0x20,0x74,0x68,0x69,0x73,0x3f,0x74,0x68,0x69,0x73,0x5b, +0x30,0x5d,0x2e,0x69,0x6e,0x6e,0x65,0x72,0x48,0x54,0x4d,0x4c,0x3a,0x6e,0x75,0x6c, +0x6c,0x7d,0x2c,0x74,0x65,0x78,0x74,0x3a,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e, +0x28,0x74,0x29,0x7b,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x30,0x20,0x69,0x6e,0x20, +0x61,0x72,0x67,0x75,0x6d,0x65,0x6e,0x74,0x73,0x3f,0x74,0x68,0x69,0x73,0x2e,0x65, +0x61,0x63,0x68,0x28,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x65,0x29,0x7b, +0x76,0x61,0x72,0x20,0x6e,0x3d,0x4a,0x28,0x74,0x68,0x69,0x73,0x2c,0x74,0x2c,0x65, +0x2c,0x74,0x68,0x69,0x73,0x2e,0x74,0x65,0x78,0x74,0x43,0x6f,0x6e,0x74,0x65,0x6e, +0x74,0x29,0x3b,0x74,0x68,0x69,0x73,0x2e,0x74,0x65,0x78,0x74,0x43,0x6f,0x6e,0x74, +0x65,0x6e,0x74,0x3d,0x6e,0x75,0x6c,0x6c,0x3d,0x3d,0x6e,0x3f,0x22,0x22,0x3a,0x22, +0x22,0x2b,0x6e,0x7d,0x29,0x3a,0x30,0x20,0x69,0x6e,0x20,0x74,0x68,0x69,0x73,0x3f, +0x74,0x68,0x69,0x73,0x5b,0x30,0x5d,0x2e,0x74,0x65,0x78,0x74,0x43,0x6f,0x6e,0x74, +0x65,0x6e,0x74,0x3a,0x6e,0x75,0x6c,0x6c,0x7d,0x2c,0x61,0x74,0x74,0x72,0x3a,0x66, +0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x6e,0x2c,0x69,0x29,0x7b,0x76,0x61,0x72, +0x20,0x72,0x3b,0x72,0x65,0x74,0x75,0x72,0x6e,0x22,0x73,0x74,0x72,0x69,0x6e,0x67, +0x22,0x21,0x3d,0x74,0x79,0x70,0x65,0x6f,0x66,0x20,0x6e,0x7c,0x7c,0x31,0x20,0x69, +0x6e,0x20,0x61,0x72,0x67,0x75,0x6d,0x65,0x6e,0x74,0x73,0x3f,0x74,0x68,0x69,0x73, +0x2e,0x65,0x61,0x63,0x68,0x28,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x74, +0x29,0x7b,0x69,0x66,0x28,0x31,0x3d,0x3d,0x3d,0x74,0x68,0x69,0x73,0x2e,0x6e,0x6f, +0x64,0x65,0x54,0x79,0x70,0x65,0x29,0x69,0x66,0x28,0x44,0x28,0x6e,0x29,0x29,0x66, +0x6f,0x72,0x28,0x65,0x20,0x69,0x6e,0x20,0x6e,0x29,0x58,0x28,0x74,0x68,0x69,0x73, +0x2c,0x65,0x2c,0x6e,0x5b,0x65,0x5d,0x29,0x3b,0x65,0x6c,0x73,0x65,0x20,0x58,0x28, +0x74,0x68,0x69,0x73,0x2c,0x6e,0x2c,0x4a,0x28,0x74,0x68,0x69,0x73,0x2c,0x69,0x2c, +0x74,0x2c,0x74,0x68,0x69,0x73,0x2e,0x67,0x65,0x74,0x41,0x74,0x74,0x72,0x69,0x62, +0x75,0x74,0x65,0x28,0x6e,0x29,0x29,0x29,0x7d,0x29,0x3a,0x74,0x68,0x69,0x73,0x2e, +0x6c,0x65,0x6e,0x67,0x74,0x68,0x26,0x26,0x31,0x3d,0x3d,0x3d,0x74,0x68,0x69,0x73, +0x5b,0x30,0x5d,0x2e,0x6e,0x6f,0x64,0x65,0x54,0x79,0x70,0x65,0x3f,0x21,0x28,0x72, +0x3d,0x74,0x68,0x69,0x73,0x5b,0x30,0x5d,0x2e,0x67,0x65,0x74,0x41,0x74,0x74,0x72, +0x69,0x62,0x75,0x74,0x65,0x28,0x6e,0x29,0x29,0x26,0x26,0x6e,0x20,0x69,0x6e,0x20, +0x74,0x68,0x69,0x73,0x5b,0x30,0x5d,0x3f,0x74,0x68,0x69,0x73,0x5b,0x30,0x5d,0x5b, +0x6e,0x5d,0x3a,0x72,0x3a,0x74,0x7d,0x2c,0x72,0x65,0x6d,0x6f,0x76,0x65,0x41,0x74, +0x74,0x72,0x3a,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x74,0x29,0x7b,0x72, +0x65,0x74,0x75,0x72,0x6e,0x20,0x74,0x68,0x69,0x73,0x2e,0x65,0x61,0x63,0x68,0x28, +0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x29,0x7b,0x31,0x3d,0x3d,0x3d,0x74, +0x68,0x69,0x73,0x2e,0x6e,0x6f,0x64,0x65,0x54,0x79,0x70,0x65,0x26,0x26,0x74,0x2e, +0x73,0x70,0x6c,0x69,0x74,0x28,0x22,0x20,0x22,0x29,0x2e,0x66,0x6f,0x72,0x45,0x61, +0x63,0x68,0x28,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x74,0x29,0x7b,0x58, +0x28,0x74,0x68,0x69,0x73,0x2c,0x74,0x29,0x7d,0x2c,0x74,0x68,0x69,0x73,0x29,0x7d, +0x29,0x7d,0x2c,0x70,0x72,0x6f,0x70,0x3a,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e, +0x28,0x74,0x2c,0x65,0x29,0x7b,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x74,0x3d,0x50, +0x5b,0x74,0x5d,0x7c,0x7c,0x74,0x2c,0x31,0x20,0x69,0x6e,0x20,0x61,0x72,0x67,0x75, +0x6d,0x65,0x6e,0x74,0x73,0x3f,0x74,0x68,0x69,0x73,0x2e,0x65,0x61,0x63,0x68,0x28, +0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x6e,0x29,0x7b,0x74,0x68,0x69,0x73, +0x5b,0x74,0x5d,0x3d,0x4a,0x28,0x74,0x68,0x69,0x73,0x2c,0x65,0x2c,0x6e,0x2c,0x74, +0x68,0x69,0x73,0x5b,0x74,0x5d,0x29,0x7d,0x29,0x3a,0x74,0x68,0x69,0x73,0x5b,0x30, +0x5d,0x26,0x26,0x74,0x68,0x69,0x73,0x5b,0x30,0x5d,0x5b,0x74,0x5d,0x7d,0x2c,0x64, +0x61,0x74,0x61,0x3a,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x65,0x2c,0x6e, +0x29,0x7b,0x76,0x61,0x72,0x20,0x69,0x3d,0x22,0x64,0x61,0x74,0x61,0x2d,0x22,0x2b, +0x65,0x2e,0x72,0x65,0x70,0x6c,0x61,0x63,0x65,0x28,0x6d,0x2c,0x22,0x2d,0x24,0x31, +0x22,0x29,0x2e,0x74,0x6f,0x4c,0x6f,0x77,0x65,0x72,0x43,0x61,0x73,0x65,0x28,0x29, +0x2c,0x72,0x3d,0x31,0x20,0x69,0x6e,0x20,0x61,0x72,0x67,0x75,0x6d,0x65,0x6e,0x74, +0x73,0x3f,0x74,0x68,0x69,0x73,0x2e,0x61,0x74,0x74,0x72,0x28,0x69,0x2c,0x6e,0x29, +0x3a,0x74,0x68,0x69,0x73,0x2e,0x61,0x74,0x74,0x72,0x28,0x69,0x29,0x3b,0x72,0x65, +0x74,0x75,0x72,0x6e,0x20,0x6e,0x75,0x6c,0x6c,0x21,0x3d,0x3d,0x72,0x3f,0x59,0x28, +0x72,0x29,0x3a,0x74,0x7d,0x2c,0x76,0x61,0x6c,0x3a,0x66,0x75,0x6e,0x63,0x74,0x69, +0x6f,0x6e,0x28,0x74,0x29,0x7b,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x30,0x20,0x69, +0x6e,0x20,0x61,0x72,0x67,0x75,0x6d,0x65,0x6e,0x74,0x73,0x3f,0x74,0x68,0x69,0x73, +0x2e,0x65,0x61,0x63,0x68,0x28,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x65, +0x29,0x7b,0x74,0x68,0x69,0x73,0x2e,0x76,0x61,0x6c,0x75,0x65,0x3d,0x4a,0x28,0x74, +0x68,0x69,0x73,0x2c,0x74,0x2c,0x65,0x2c,0x74,0x68,0x69,0x73,0x2e,0x76,0x61,0x6c, +0x75,0x65,0x29,0x7d,0x29,0x3a,0x74,0x68,0x69,0x73,0x5b,0x30,0x5d,0x26,0x26,0x28, +0x74,0x68,0x69,0x73,0x5b,0x30,0x5d,0x2e,0x6d,0x75,0x6c,0x74,0x69,0x70,0x6c,0x65, +0x3f,0x6e,0x28,0x74,0x68,0x69,0x73,0x5b,0x30,0x5d,0x29,0x2e,0x66,0x69,0x6e,0x64, +0x28,0x22,0x6f,0x70,0x74,0x69,0x6f,0x6e,0x22,0x29,0x2e,0x66,0x69,0x6c,0x74,0x65, +0x72,0x28,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x29,0x7b,0x72,0x65,0x74, +0x75,0x72,0x6e,0x20,0x74,0x68,0x69,0x73,0x2e,0x73,0x65,0x6c,0x65,0x63,0x74,0x65, +0x64,0x7d,0x29,0x2e,0x70,0x6c,0x75,0x63,0x6b,0x28,0x22,0x76,0x61,0x6c,0x75,0x65, +0x22,0x29,0x3a,0x74,0x68,0x69,0x73,0x5b,0x30,0x5d,0x2e,0x76,0x61,0x6c,0x75,0x65, +0x29,0x7d,0x2c,0x6f,0x66,0x66,0x73,0x65,0x74,0x3a,0x66,0x75,0x6e,0x63,0x74,0x69, +0x6f,0x6e,0x28,0x74,0x29,0x7b,0x69,0x66,0x28,0x74,0x29,0x72,0x65,0x74,0x75,0x72, +0x6e,0x20,0x74,0x68,0x69,0x73,0x2e,0x65,0x61,0x63,0x68,0x28,0x66,0x75,0x6e,0x63, +0x74,0x69,0x6f,0x6e,0x28,0x65,0x29,0x7b,0x76,0x61,0x72,0x20,0x69,0x3d,0x6e,0x28, +0x74,0x68,0x69,0x73,0x29,0x2c,0x72,0x3d,0x4a,0x28,0x74,0x68,0x69,0x73,0x2c,0x74, +0x2c,0x65,0x2c,0x69,0x2e,0x6f,0x66,0x66,0x73,0x65,0x74,0x28,0x29,0x29,0x2c,0x6f, +0x3d,0x69,0x2e,0x6f,0x66,0x66,0x73,0x65,0x74,0x50,0x61,0x72,0x65,0x6e,0x74,0x28, +0x29,0x2e,0x6f,0x66,0x66,0x73,0x65,0x74,0x28,0x29,0x2c,0x73,0x3d,0x7b,0x74,0x6f, +0x70,0x3a,0x72,0x2e,0x74,0x6f,0x70,0x2d,0x6f,0x2e,0x74,0x6f,0x70,0x2c,0x6c,0x65, +0x66,0x74,0x3a,0x72,0x2e,0x6c,0x65,0x66,0x74,0x2d,0x6f,0x2e,0x6c,0x65,0x66,0x74, +0x7d,0x3b,0x22,0x73,0x74,0x61,0x74,0x69,0x63,0x22,0x3d,0x3d,0x69,0x2e,0x63,0x73, +0x73,0x28,0x22,0x70,0x6f,0x73,0x69,0x74,0x69,0x6f,0x6e,0x22,0x29,0x26,0x26,0x28, +0x73,0x2e,0x70,0x6f,0x73,0x69,0x74,0x69,0x6f,0x6e,0x3d,0x22,0x72,0x65,0x6c,0x61, +0x74,0x69,0x76,0x65,0x22,0x29,0x2c,0x69,0x2e,0x63,0x73,0x73,0x28,0x73,0x29,0x7d, +0x29,0x3b,0x69,0x66,0x28,0x21,0x74,0x68,0x69,0x73,0x2e,0x6c,0x65,0x6e,0x67,0x74, +0x68,0x29,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x6e,0x75,0x6c,0x6c,0x3b,0x76,0x61, +0x72,0x20,0x65,0x3d,0x74,0x68,0x69,0x73,0x5b,0x30,0x5d,0x2e,0x67,0x65,0x74,0x42, +0x6f,0x75,0x6e,0x64,0x69,0x6e,0x67,0x43,0x6c,0x69,0x65,0x6e,0x74,0x52,0x65,0x63, +0x74,0x28,0x29,0x3b,0x72,0x65,0x74,0x75,0x72,0x6e,0x7b,0x6c,0x65,0x66,0x74,0x3a, +0x65,0x2e,0x6c,0x65,0x66,0x74,0x2b,0x77,0x69,0x6e,0x64,0x6f,0x77,0x2e,0x70,0x61, +0x67,0x65,0x58,0x4f,0x66,0x66,0x73,0x65,0x74,0x2c,0x74,0x6f,0x70,0x3a,0x65,0x2e, +0x74,0x6f,0x70,0x2b,0x77,0x69,0x6e,0x64,0x6f,0x77,0x2e,0x70,0x61,0x67,0x65,0x59, +0x4f,0x66,0x66,0x73,0x65,0x74,0x2c,0x77,0x69,0x64,0x74,0x68,0x3a,0x4d,0x61,0x74, +0x68,0x2e,0x72,0x6f,0x75,0x6e,0x64,0x28,0x65,0x2e,0x77,0x69,0x64,0x74,0x68,0x29, +0x2c,0x68,0x65,0x69,0x67,0x68,0x74,0x3a,0x4d,0x61,0x74,0x68,0x2e,0x72,0x6f,0x75, +0x6e,0x64,0x28,0x65,0x2e,0x68,0x65,0x69,0x67,0x68,0x74,0x29,0x7d,0x7d,0x2c,0x63, +0x73,0x73,0x3a,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x74,0x2c,0x69,0x29, +0x7b,0x69,0x66,0x28,0x61,0x72,0x67,0x75,0x6d,0x65,0x6e,0x74,0x73,0x2e,0x6c,0x65, +0x6e,0x67,0x74,0x68,0x3c,0x32,0x29,0x7b,0x76,0x61,0x72,0x20,0x72,0x2c,0x6f,0x3d, +0x74,0x68,0x69,0x73,0x5b,0x30,0x5d,0x3b,0x69,0x66,0x28,0x21,0x6f,0x29,0x72,0x65, +0x74,0x75,0x72,0x6e,0x3b,0x69,0x66,0x28,0x72,0x3d,0x67,0x65,0x74,0x43,0x6f,0x6d, +0x70,0x75,0x74,0x65,0x64,0x53,0x74,0x79,0x6c,0x65,0x28,0x6f,0x2c,0x22,0x22,0x29, +0x2c,0x22,0x73,0x74,0x72,0x69,0x6e,0x67,0x22,0x3d,0x3d,0x74,0x79,0x70,0x65,0x6f, +0x66,0x20,0x74,0x29,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x6f,0x2e,0x73,0x74,0x79, +0x6c,0x65,0x5b,0x43,0x28,0x74,0x29,0x5d,0x7c,0x7c,0x72,0x2e,0x67,0x65,0x74,0x50, +0x72,0x6f,0x70,0x65,0x72,0x74,0x79,0x56,0x61,0x6c,0x75,0x65,0x28,0x74,0x29,0x3b, +0x69,0x66,0x28,0x41,0x28,0x74,0x29,0x29,0x7b,0x76,0x61,0x72,0x20,0x73,0x3d,0x7b, +0x7d,0x3b,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x6e,0x2e,0x65,0x61,0x63,0x68,0x28, +0x74,0x2c,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x74,0x2c,0x65,0x29,0x7b, +0x73,0x5b,0x65,0x5d,0x3d,0x6f,0x2e,0x73,0x74,0x79,0x6c,0x65,0x5b,0x43,0x28,0x65, +0x29,0x5d,0x7c,0x7c,0x72,0x2e,0x67,0x65,0x74,0x50,0x72,0x6f,0x70,0x65,0x72,0x74, +0x79,0x56,0x61,0x6c,0x75,0x65,0x28,0x65,0x29,0x7d,0x29,0x2c,0x73,0x7d,0x7d,0x76, +0x61,0x72,0x20,0x61,0x3d,0x22,0x22,0x3b,0x69,0x66,0x28,0x22,0x73,0x74,0x72,0x69, +0x6e,0x67,0x22,0x3d,0x3d,0x4c,0x28,0x74,0x29,0x29,0x69,0x7c,0x7c,0x30,0x3d,0x3d, +0x3d,0x69,0x3f,0x61,0x3d,0x46,0x28,0x74,0x29,0x2b,0x22,0x3a,0x22,0x2b,0x48,0x28, +0x74,0x2c,0x69,0x29,0x3a,0x74,0x68,0x69,0x73,0x2e,0x65,0x61,0x63,0x68,0x28,0x66, +0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x29,0x7b,0x74,0x68,0x69,0x73,0x2e,0x73, +0x74,0x79,0x6c,0x65,0x2e,0x72,0x65,0x6d,0x6f,0x76,0x65,0x50,0x72,0x6f,0x70,0x65, +0x72,0x74,0x79,0x28,0x46,0x28,0x74,0x29,0x29,0x7d,0x29,0x3b,0x65,0x6c,0x73,0x65, +0x20,0x66,0x6f,0x72,0x28,0x65,0x20,0x69,0x6e,0x20,0x74,0x29,0x74,0x5b,0x65,0x5d, +0x7c,0x7c,0x30,0x3d,0x3d,0x3d,0x74,0x5b,0x65,0x5d,0x3f,0x61,0x2b,0x3d,0x46,0x28, +0x65,0x29,0x2b,0x22,0x3a,0x22,0x2b,0x48,0x28,0x65,0x2c,0x74,0x5b,0x65,0x5d,0x29, +0x2b,0x22,0x3b,0x22,0x3a,0x74,0x68,0x69,0x73,0x2e,0x65,0x61,0x63,0x68,0x28,0x66, +0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x29,0x7b,0x74,0x68,0x69,0x73,0x2e,0x73, +0x74,0x79,0x6c,0x65,0x2e,0x72,0x65,0x6d,0x6f,0x76,0x65,0x50,0x72,0x6f,0x70,0x65, +0x72,0x74,0x79,0x28,0x46,0x28,0x65,0x29,0x29,0x7d,0x29,0x3b,0x72,0x65,0x74,0x75, +0x72,0x6e,0x20,0x74,0x68,0x69,0x73,0x2e,0x65,0x61,0x63,0x68,0x28,0x66,0x75,0x6e, +0x63,0x74,0x69,0x6f,0x6e,0x28,0x29,0x7b,0x74,0x68,0x69,0x73,0x2e,0x73,0x74,0x79, +0x6c,0x65,0x2e,0x63,0x73,0x73,0x54,0x65,0x78,0x74,0x2b,0x3d,0x22,0x3b,0x22,0x2b, +0x61,0x7d,0x29,0x7d,0x2c,0x69,0x6e,0x64,0x65,0x78,0x3a,0x66,0x75,0x6e,0x63,0x74, +0x69,0x6f,0x6e,0x28,0x74,0x29,0x7b,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x74,0x3f, +0x74,0x68,0x69,0x73,0x2e,0x69,0x6e,0x64,0x65,0x78,0x4f,0x66,0x28,0x6e,0x28,0x74, +0x29,0x5b,0x30,0x5d,0x29,0x3a,0x74,0x68,0x69,0x73,0x2e,0x70,0x61,0x72,0x65,0x6e, +0x74,0x28,0x29,0x2e,0x63,0x68,0x69,0x6c,0x64,0x72,0x65,0x6e,0x28,0x29,0x2e,0x69, +0x6e,0x64,0x65,0x78,0x4f,0x66,0x28,0x74,0x68,0x69,0x73,0x5b,0x30,0x5d,0x29,0x7d, +0x2c,0x68,0x61,0x73,0x43,0x6c,0x61,0x73,0x73,0x3a,0x66,0x75,0x6e,0x63,0x74,0x69, +0x6f,0x6e,0x28,0x74,0x29,0x7b,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x74,0x3f,0x72, +0x2e,0x73,0x6f,0x6d,0x65,0x2e,0x63,0x61,0x6c,0x6c,0x28,0x74,0x68,0x69,0x73,0x2c, +0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x74,0x29,0x7b,0x72,0x65,0x74,0x75, +0x72,0x6e,0x20,0x74,0x68,0x69,0x73,0x2e,0x74,0x65,0x73,0x74,0x28,0x57,0x28,0x74, +0x29,0x29,0x7d,0x2c,0x71,0x28,0x74,0x29,0x29,0x3a,0x21,0x31,0x7d,0x2c,0x61,0x64, +0x64,0x43,0x6c,0x61,0x73,0x73,0x3a,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28, +0x74,0x29,0x7b,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x74,0x3f,0x74,0x68,0x69,0x73, +0x2e,0x65,0x61,0x63,0x68,0x28,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x65, +0x29,0x7b,0x69,0x66,0x28,0x22,0x63,0x6c,0x61,0x73,0x73,0x4e,0x61,0x6d,0x65,0x22, +0x69,0x6e,0x20,0x74,0x68,0x69,0x73,0x29,0x7b,0x69,0x3d,0x5b,0x5d,0x3b,0x76,0x61, +0x72,0x20,0x72,0x3d,0x57,0x28,0x74,0x68,0x69,0x73,0x29,0x2c,0x6f,0x3d,0x4a,0x28, +0x74,0x68,0x69,0x73,0x2c,0x74,0x2c,0x65,0x2c,0x72,0x29,0x3b,0x6f,0x2e,0x73,0x70, +0x6c,0x69,0x74,0x28,0x2f,0x5c,0x73,0x2b,0x2f,0x67,0x29,0x2e,0x66,0x6f,0x72,0x45, +0x61,0x63,0x68,0x28,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x74,0x29,0x7b, +0x6e,0x28,0x74,0x68,0x69,0x73,0x29,0x2e,0x68,0x61,0x73,0x43,0x6c,0x61,0x73,0x73, +0x28,0x74,0x29,0x7c,0x7c,0x69,0x2e,0x70,0x75,0x73,0x68,0x28,0x74,0x29,0x7d,0x2c, +0x74,0x68,0x69,0x73,0x29,0x2c,0x69,0x2e,0x6c,0x65,0x6e,0x67,0x74,0x68,0x26,0x26, +0x57,0x28,0x74,0x68,0x69,0x73,0x2c,0x72,0x2b,0x28,0x72,0x3f,0x22,0x20,0x22,0x3a, +0x22,0x22,0x29,0x2b,0x69,0x2e,0x6a,0x6f,0x69,0x6e,0x28,0x22,0x20,0x22,0x29,0x29, +0x7d,0x7d,0x29,0x3a,0x74,0x68,0x69,0x73,0x7d,0x2c,0x72,0x65,0x6d,0x6f,0x76,0x65, +0x43,0x6c,0x61,0x73,0x73,0x3a,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x65, +0x29,0x7b,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x74,0x68,0x69,0x73,0x2e,0x65,0x61, +0x63,0x68,0x28,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x6e,0x29,0x7b,0x69, +0x66,0x28,0x22,0x63,0x6c,0x61,0x73,0x73,0x4e,0x61,0x6d,0x65,0x22,0x69,0x6e,0x20, +0x74,0x68,0x69,0x73,0x29,0x7b,0x69,0x66,0x28,0x65,0x3d,0x3d,0x3d,0x74,0x29,0x72, +0x65,0x74,0x75,0x72,0x6e,0x20,0x57,0x28,0x74,0x68,0x69,0x73,0x2c,0x22,0x22,0x29, +0x3b,0x69,0x3d,0x57,0x28,0x74,0x68,0x69,0x73,0x29,0x2c,0x4a,0x28,0x74,0x68,0x69, +0x73,0x2c,0x65,0x2c,0x6e,0x2c,0x69,0x29,0x2e,0x73,0x70,0x6c,0x69,0x74,0x28,0x2f, +0x5c,0x73,0x2b,0x2f,0x67,0x29,0x2e,0x66,0x6f,0x72,0x45,0x61,0x63,0x68,0x28,0x66, +0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x74,0x29,0x7b,0x69,0x3d,0x69,0x2e,0x72, +0x65,0x70,0x6c,0x61,0x63,0x65,0x28,0x71,0x28,0x74,0x29,0x2c,0x22,0x20,0x22,0x29, +0x7d,0x29,0x2c,0x57,0x28,0x74,0x68,0x69,0x73,0x2c,0x69,0x2e,0x74,0x72,0x69,0x6d, +0x28,0x29,0x29,0x7d,0x7d,0x29,0x7d,0x2c,0x74,0x6f,0x67,0x67,0x6c,0x65,0x43,0x6c, +0x61,0x73,0x73,0x3a,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x65,0x2c,0x69, +0x29,0x7b,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x65,0x3f,0x74,0x68,0x69,0x73,0x2e, +0x65,0x61,0x63,0x68,0x28,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x72,0x29, +0x7b,0x76,0x61,0x72,0x20,0x6f,0x3d,0x6e,0x28,0x74,0x68,0x69,0x73,0x29,0x2c,0x73, +0x3d,0x4a,0x28,0x74,0x68,0x69,0x73,0x2c,0x65,0x2c,0x72,0x2c,0x57,0x28,0x74,0x68, +0x69,0x73,0x29,0x29,0x3b,0x73,0x2e,0x73,0x70,0x6c,0x69,0x74,0x28,0x2f,0x5c,0x73, +0x2b,0x2f,0x67,0x29,0x2e,0x66,0x6f,0x72,0x45,0x61,0x63,0x68,0x28,0x66,0x75,0x6e, +0x63,0x74,0x69,0x6f,0x6e,0x28,0x65,0x29,0x7b,0x28,0x69,0x3d,0x3d,0x3d,0x74,0x3f, +0x21,0x6f,0x2e,0x68,0x61,0x73,0x43,0x6c,0x61,0x73,0x73,0x28,0x65,0x29,0x3a,0x69, +0x29,0x3f,0x6f,0x2e,0x61,0x64,0x64,0x43,0x6c,0x61,0x73,0x73,0x28,0x65,0x29,0x3a, +0x6f,0x2e,0x72,0x65,0x6d,0x6f,0x76,0x65,0x43,0x6c,0x61,0x73,0x73,0x28,0x65,0x29, +0x7d,0x29,0x7d,0x29,0x3a,0x74,0x68,0x69,0x73,0x7d,0x2c,0x73,0x63,0x72,0x6f,0x6c, +0x6c,0x54,0x6f,0x70,0x3a,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x65,0x29, +0x7b,0x69,0x66,0x28,0x74,0x68,0x69,0x73,0x2e,0x6c,0x65,0x6e,0x67,0x74,0x68,0x29, +0x7b,0x76,0x61,0x72,0x20,0x6e,0x3d,0x22,0x73,0x63,0x72,0x6f,0x6c,0x6c,0x54,0x6f, +0x70,0x22,0x69,0x6e,0x20,0x74,0x68,0x69,0x73,0x5b,0x30,0x5d,0x3b,0x72,0x65,0x74, +0x75,0x72,0x6e,0x20,0x65,0x3d,0x3d,0x3d,0x74,0x3f,0x6e,0x3f,0x74,0x68,0x69,0x73, +0x5b,0x30,0x5d,0x2e,0x73,0x63,0x72,0x6f,0x6c,0x6c,0x54,0x6f,0x70,0x3a,0x74,0x68, +0x69,0x73,0x5b,0x30,0x5d,0x2e,0x70,0x61,0x67,0x65,0x59,0x4f,0x66,0x66,0x73,0x65, +0x74,0x3a,0x74,0x68,0x69,0x73,0x2e,0x65,0x61,0x63,0x68,0x28,0x6e,0x3f,0x66,0x75, +0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x29,0x7b,0x74,0x68,0x69,0x73,0x2e,0x73,0x63, +0x72,0x6f,0x6c,0x6c,0x54,0x6f,0x70,0x3d,0x65,0x7d,0x3a,0x66,0x75,0x6e,0x63,0x74, +0x69,0x6f,0x6e,0x28,0x29,0x7b,0x74,0x68,0x69,0x73,0x2e,0x73,0x63,0x72,0x6f,0x6c, +0x6c,0x54,0x6f,0x28,0x74,0x68,0x69,0x73,0x2e,0x73,0x63,0x72,0x6f,0x6c,0x6c,0x58, +0x2c,0x65,0x29,0x7d,0x29,0x7d,0x7d,0x2c,0x73,0x63,0x72,0x6f,0x6c,0x6c,0x4c,0x65, +0x66,0x74,0x3a,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x65,0x29,0x7b,0x69, +0x66,0x28,0x74,0x68,0x69,0x73,0x2e,0x6c,0x65,0x6e,0x67,0x74,0x68,0x29,0x7b,0x76, +0x61,0x72,0x20,0x6e,0x3d,0x22,0x73,0x63,0x72,0x6f,0x6c,0x6c,0x4c,0x65,0x66,0x74, +0x22,0x69,0x6e,0x20,0x74,0x68,0x69,0x73,0x5b,0x30,0x5d,0x3b,0x72,0x65,0x74,0x75, +0x72,0x6e,0x20,0x65,0x3d,0x3d,0x3d,0x74,0x3f,0x6e,0x3f,0x74,0x68,0x69,0x73,0x5b, +0x30,0x5d,0x2e,0x73,0x63,0x72,0x6f,0x6c,0x6c,0x4c,0x65,0x66,0x74,0x3a,0x74,0x68, +0x69,0x73,0x5b,0x30,0x5d,0x2e,0x70,0x61,0x67,0x65,0x58,0x4f,0x66,0x66,0x73,0x65, +0x74,0x3a,0x74,0x68,0x69,0x73,0x2e,0x65,0x61,0x63,0x68,0x28,0x6e,0x3f,0x66,0x75, +0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x29,0x7b,0x74,0x68,0x69,0x73,0x2e,0x73,0x63, +0x72,0x6f,0x6c,0x6c,0x4c,0x65,0x66,0x74,0x3d,0x65,0x7d,0x3a,0x66,0x75,0x6e,0x63, +0x74,0x69,0x6f,0x6e,0x28,0x29,0x7b,0x74,0x68,0x69,0x73,0x2e,0x73,0x63,0x72,0x6f, +0x6c,0x6c,0x54,0x6f,0x28,0x65,0x2c,0x74,0x68,0x69,0x73,0x2e,0x73,0x63,0x72,0x6f, +0x6c,0x6c,0x59,0x29,0x7d,0x29,0x7d,0x7d,0x2c,0x70,0x6f,0x73,0x69,0x74,0x69,0x6f, +0x6e,0x3a,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x29,0x7b,0x69,0x66,0x28, +0x74,0x68,0x69,0x73,0x2e,0x6c,0x65,0x6e,0x67,0x74,0x68,0x29,0x7b,0x76,0x61,0x72, +0x20,0x74,0x3d,0x74,0x68,0x69,0x73,0x5b,0x30,0x5d,0x2c,0x65,0x3d,0x74,0x68,0x69, +0x73,0x2e,0x6f,0x66,0x66,0x73,0x65,0x74,0x50,0x61,0x72,0x65,0x6e,0x74,0x28,0x29, +0x2c,0x69,0x3d,0x74,0x68,0x69,0x73,0x2e,0x6f,0x66,0x66,0x73,0x65,0x74,0x28,0x29, +0x2c,0x72,0x3d,0x64,0x2e,0x74,0x65,0x73,0x74,0x28,0x65,0x5b,0x30,0x5d,0x2e,0x6e, +0x6f,0x64,0x65,0x4e,0x61,0x6d,0x65,0x29,0x3f,0x7b,0x74,0x6f,0x70,0x3a,0x30,0x2c, +0x6c,0x65,0x66,0x74,0x3a,0x30,0x7d,0x3a,0x65,0x2e,0x6f,0x66,0x66,0x73,0x65,0x74, +0x28,0x29,0x3b,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x69,0x2e,0x74,0x6f,0x70,0x2d, +0x3d,0x70,0x61,0x72,0x73,0x65,0x46,0x6c,0x6f,0x61,0x74,0x28,0x6e,0x28,0x74,0x29, +0x2e,0x63,0x73,0x73,0x28,0x22,0x6d,0x61,0x72,0x67,0x69,0x6e,0x2d,0x74,0x6f,0x70, +0x22,0x29,0x29,0x7c,0x7c,0x30,0x2c,0x69,0x2e,0x6c,0x65,0x66,0x74,0x2d,0x3d,0x70, +0x61,0x72,0x73,0x65,0x46,0x6c,0x6f,0x61,0x74,0x28,0x6e,0x28,0x74,0x29,0x2e,0x63, +0x73,0x73,0x28,0x22,0x6d,0x61,0x72,0x67,0x69,0x6e,0x2d,0x6c,0x65,0x66,0x74,0x22, +0x29,0x29,0x7c,0x7c,0x30,0x2c,0x72,0x2e,0x74,0x6f,0x70,0x2b,0x3d,0x70,0x61,0x72, +0x73,0x65,0x46,0x6c,0x6f,0x61,0x74,0x28,0x6e,0x28,0x65,0x5b,0x30,0x5d,0x29,0x2e, +0x63,0x73,0x73,0x28,0x22,0x62,0x6f,0x72,0x64,0x65,0x72,0x2d,0x74,0x6f,0x70,0x2d, +0x77,0x69,0x64,0x74,0x68,0x22,0x29,0x29,0x7c,0x7c,0x30,0x2c,0x72,0x2e,0x6c,0x65, +0x66,0x74,0x2b,0x3d,0x70,0x61,0x72,0x73,0x65,0x46,0x6c,0x6f,0x61,0x74,0x28,0x6e, +0x28,0x65,0x5b,0x30,0x5d,0x29,0x2e,0x63,0x73,0x73,0x28,0x22,0x62,0x6f,0x72,0x64, +0x65,0x72,0x2d,0x6c,0x65,0x66,0x74,0x2d,0x77,0x69,0x64,0x74,0x68,0x22,0x29,0x29, +0x7c,0x7c,0x30,0x2c,0x7b,0x74,0x6f,0x70,0x3a,0x69,0x2e,0x74,0x6f,0x70,0x2d,0x72, +0x2e,0x74,0x6f,0x70,0x2c,0x6c,0x65,0x66,0x74,0x3a,0x69,0x2e,0x6c,0x65,0x66,0x74, +0x2d,0x72,0x2e,0x6c,0x65,0x66,0x74,0x7d,0x7d,0x7d,0x2c,0x6f,0x66,0x66,0x73,0x65, +0x74,0x50,0x61,0x72,0x65,0x6e,0x74,0x3a,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e, +0x28,0x29,0x7b,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x74,0x68,0x69,0x73,0x2e,0x6d, +0x61,0x70,0x28,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x29,0x7b,0x66,0x6f, +0x72,0x28,0x76,0x61,0x72,0x20,0x74,0x3d,0x74,0x68,0x69,0x73,0x2e,0x6f,0x66,0x66, +0x73,0x65,0x74,0x50,0x61,0x72,0x65,0x6e,0x74,0x7c,0x7c,0x61,0x2e,0x62,0x6f,0x64, +0x79,0x3b,0x74,0x26,0x26,0x21,0x64,0x2e,0x74,0x65,0x73,0x74,0x28,0x74,0x2e,0x6e, +0x6f,0x64,0x65,0x4e,0x61,0x6d,0x65,0x29,0x26,0x26,0x22,0x73,0x74,0x61,0x74,0x69, +0x63,0x22,0x3d,0x3d,0x6e,0x28,0x74,0x29,0x2e,0x63,0x73,0x73,0x28,0x22,0x70,0x6f, +0x73,0x69,0x74,0x69,0x6f,0x6e,0x22,0x29,0x3b,0x29,0x74,0x3d,0x74,0x2e,0x6f,0x66, +0x66,0x73,0x65,0x74,0x50,0x61,0x72,0x65,0x6e,0x74,0x3b,0x72,0x65,0x74,0x75,0x72, +0x6e,0x20,0x74,0x7d,0x29,0x7d,0x7d,0x2c,0x6e,0x2e,0x66,0x6e,0x2e,0x64,0x65,0x74, +0x61,0x63,0x68,0x3d,0x6e,0x2e,0x66,0x6e,0x2e,0x72,0x65,0x6d,0x6f,0x76,0x65,0x2c, +0x5b,0x22,0x77,0x69,0x64,0x74,0x68,0x22,0x2c,0x22,0x68,0x65,0x69,0x67,0x68,0x74, +0x22,0x5d,0x2e,0x66,0x6f,0x72,0x45,0x61,0x63,0x68,0x28,0x66,0x75,0x6e,0x63,0x74, +0x69,0x6f,0x6e,0x28,0x65,0x29,0x7b,0x76,0x61,0x72,0x20,0x69,0x3d,0x65,0x2e,0x72, +0x65,0x70,0x6c,0x61,0x63,0x65,0x28,0x2f,0x2e,0x2f,0x2c,0x66,0x75,0x6e,0x63,0x74, +0x69,0x6f,0x6e,0x28,0x74,0x29,0x7b,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x74,0x5b, +0x30,0x5d,0x2e,0x74,0x6f,0x55,0x70,0x70,0x65,0x72,0x43,0x61,0x73,0x65,0x28,0x29, +0x7d,0x29,0x3b,0x6e,0x2e,0x66,0x6e,0x5b,0x65,0x5d,0x3d,0x66,0x75,0x6e,0x63,0x74, +0x69,0x6f,0x6e,0x28,0x72,0x29,0x7b,0x76,0x61,0x72,0x20,0x6f,0x2c,0x73,0x3d,0x74, +0x68,0x69,0x73,0x5b,0x30,0x5d,0x3b,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x72,0x3d, +0x3d,0x3d,0x74,0x3f,0x5f,0x28,0x73,0x29,0x3f,0x73,0x5b,0x22,0x69,0x6e,0x6e,0x65, +0x72,0x22,0x2b,0x69,0x5d,0x3a,0x24,0x28,0x73,0x29,0x3f,0x73,0x2e,0x64,0x6f,0x63, +0x75,0x6d,0x65,0x6e,0x74,0x45,0x6c,0x65,0x6d,0x65,0x6e,0x74,0x5b,0x22,0x73,0x63, +0x72,0x6f,0x6c,0x6c,0x22,0x2b,0x69,0x5d,0x3a,0x28,0x6f,0x3d,0x74,0x68,0x69,0x73, +0x2e,0x6f,0x66,0x66,0x73,0x65,0x74,0x28,0x29,0x29,0x26,0x26,0x6f,0x5b,0x65,0x5d, +0x3a,0x74,0x68,0x69,0x73,0x2e,0x65,0x61,0x63,0x68,0x28,0x66,0x75,0x6e,0x63,0x74, +0x69,0x6f,0x6e,0x28,0x74,0x29,0x7b,0x73,0x3d,0x6e,0x28,0x74,0x68,0x69,0x73,0x29, +0x2c,0x73,0x2e,0x63,0x73,0x73,0x28,0x65,0x2c,0x4a,0x28,0x74,0x68,0x69,0x73,0x2c, +0x72,0x2c,0x74,0x2c,0x73,0x5b,0x65,0x5d,0x28,0x29,0x29,0x29,0x7d,0x29,0x7d,0x7d, +0x29,0x2c,0x76,0x2e,0x66,0x6f,0x72,0x45,0x61,0x63,0x68,0x28,0x66,0x75,0x6e,0x63, +0x74,0x69,0x6f,0x6e,0x28,0x74,0x2c,0x65,0x29,0x7b,0x76,0x61,0x72,0x20,0x69,0x3d, +0x65,0x25,0x32,0x3b,0x6e,0x2e,0x66,0x6e,0x5b,0x74,0x5d,0x3d,0x66,0x75,0x6e,0x63, +0x74,0x69,0x6f,0x6e,0x28,0x29,0x7b,0x76,0x61,0x72,0x20,0x74,0x2c,0x6f,0x2c,0x72, +0x3d,0x6e,0x2e,0x6d,0x61,0x70,0x28,0x61,0x72,0x67,0x75,0x6d,0x65,0x6e,0x74,0x73, +0x2c,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x65,0x29,0x7b,0x72,0x65,0x74, +0x75,0x72,0x6e,0x20,0x74,0x3d,0x4c,0x28,0x65,0x29,0x2c,0x22,0x6f,0x62,0x6a,0x65, +0x63,0x74,0x22,0x3d,0x3d,0x74,0x7c,0x7c,0x22,0x61,0x72,0x72,0x61,0x79,0x22,0x3d, +0x3d,0x74,0x7c,0x7c,0x6e,0x75,0x6c,0x6c,0x3d,0x3d,0x65,0x3f,0x65,0x3a,0x54,0x2e, +0x66,0x72,0x61,0x67,0x6d,0x65,0x6e,0x74,0x28,0x65,0x29,0x7d,0x29,0x2c,0x73,0x3d, +0x74,0x68,0x69,0x73,0x2e,0x6c,0x65,0x6e,0x67,0x74,0x68,0x3e,0x31,0x3b,0x72,0x65, +0x74,0x75,0x72,0x6e,0x20,0x72,0x2e,0x6c,0x65,0x6e,0x67,0x74,0x68,0x3c,0x31,0x3f, +0x74,0x68,0x69,0x73,0x3a,0x74,0x68,0x69,0x73,0x2e,0x65,0x61,0x63,0x68,0x28,0x66, +0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x74,0x2c,0x75,0x29,0x7b,0x6f,0x3d,0x69, +0x3f,0x75,0x3a,0x75,0x2e,0x70,0x61,0x72,0x65,0x6e,0x74,0x4e,0x6f,0x64,0x65,0x2c, +0x75,0x3d,0x30,0x3d,0x3d,0x65,0x3f,0x75,0x2e,0x6e,0x65,0x78,0x74,0x53,0x69,0x62, +0x6c,0x69,0x6e,0x67,0x3a,0x31,0x3d,0x3d,0x65,0x3f,0x75,0x2e,0x66,0x69,0x72,0x73, +0x74,0x43,0x68,0x69,0x6c,0x64,0x3a,0x32,0x3d,0x3d,0x65,0x3f,0x75,0x3a,0x6e,0x75, +0x6c,0x6c,0x3b,0x76,0x61,0x72,0x20,0x66,0x3d,0x6e,0x2e,0x63,0x6f,0x6e,0x74,0x61, +0x69,0x6e,0x73,0x28,0x61,0x2e,0x64,0x6f,0x63,0x75,0x6d,0x65,0x6e,0x74,0x45,0x6c, +0x65,0x6d,0x65,0x6e,0x74,0x2c,0x6f,0x29,0x3b,0x72,0x2e,0x66,0x6f,0x72,0x45,0x61, +0x63,0x68,0x28,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x74,0x29,0x7b,0x69, +0x66,0x28,0x73,0x29,0x74,0x3d,0x74,0x2e,0x63,0x6c,0x6f,0x6e,0x65,0x4e,0x6f,0x64, +0x65,0x28,0x21,0x30,0x29,0x3b,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x28,0x21,0x6f, +0x29,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x6e,0x28,0x74,0x29,0x2e,0x72,0x65,0x6d, +0x6f,0x76,0x65,0x28,0x29,0x3b,0x6f,0x2e,0x69,0x6e,0x73,0x65,0x72,0x74,0x42,0x65, +0x66,0x6f,0x72,0x65,0x28,0x74,0x2c,0x75,0x29,0x2c,0x66,0x26,0x26,0x47,0x28,0x74, +0x2c,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x74,0x29,0x7b,0x6e,0x75,0x6c, +0x6c,0x3d,0x3d,0x74,0x2e,0x6e,0x6f,0x64,0x65,0x4e,0x61,0x6d,0x65,0x7c,0x7c,0x22, +0x53,0x43,0x52,0x49,0x50,0x54,0x22,0x21,0x3d,0x3d,0x74,0x2e,0x6e,0x6f,0x64,0x65, +0x4e,0x61,0x6d,0x65,0x2e,0x74,0x6f,0x55,0x70,0x70,0x65,0x72,0x43,0x61,0x73,0x65, +0x28,0x29,0x7c,0x7c,0x74,0x2e,0x74,0x79,0x70,0x65,0x26,0x26,0x22,0x74,0x65,0x78, +0x74,0x2f,0x6a,0x61,0x76,0x61,0x73,0x63,0x72,0x69,0x70,0x74,0x22,0x21,0x3d,0x3d, +0x74,0x2e,0x74,0x79,0x70,0x65,0x7c,0x7c,0x74,0x2e,0x73,0x72,0x63,0x7c,0x7c,0x77, +0x69,0x6e,0x64,0x6f,0x77,0x2e,0x65,0x76,0x61,0x6c,0x2e,0x63,0x61,0x6c,0x6c,0x28, +0x77,0x69,0x6e,0x64,0x6f,0x77,0x2c,0x74,0x2e,0x69,0x6e,0x6e,0x65,0x72,0x48,0x54, +0x4d,0x4c,0x29,0x7d,0x29,0x7d,0x29,0x7d,0x29,0x7d,0x2c,0x6e,0x2e,0x66,0x6e,0x5b, +0x69,0x3f,0x74,0x2b,0x22,0x54,0x6f,0x22,0x3a,0x22,0x69,0x6e,0x73,0x65,0x72,0x74, +0x22,0x2b,0x28,0x65,0x3f,0x22,0x42,0x65,0x66,0x6f,0x72,0x65,0x22,0x3a,0x22,0x41, +0x66,0x74,0x65,0x72,0x22,0x29,0x5d,0x3d,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e, +0x28,0x65,0x29,0x7b,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x6e,0x28,0x65,0x29,0x5b, +0x74,0x5d,0x28,0x74,0x68,0x69,0x73,0x29,0x2c,0x74,0x68,0x69,0x73,0x7d,0x7d,0x29, +0x2c,0x54,0x2e,0x5a,0x2e,0x70,0x72,0x6f,0x74,0x6f,0x74,0x79,0x70,0x65,0x3d,0x6e, +0x2e,0x66,0x6e,0x2c,0x54,0x2e,0x75,0x6e,0x69,0x71,0x3d,0x4e,0x2c,0x54,0x2e,0x64, +0x65,0x73,0x65,0x72,0x69,0x61,0x6c,0x69,0x7a,0x65,0x56,0x61,0x6c,0x75,0x65,0x3d, +0x59,0x2c,0x6e,0x2e,0x7a,0x65,0x70,0x74,0x6f,0x3d,0x54,0x2c,0x6e,0x7d,0x28,0x29, +0x3b,0x77,0x69,0x6e,0x64,0x6f,0x77,0x2e,0x5a,0x65,0x70,0x74,0x6f,0x3d,0x5a,0x65, +0x70,0x74,0x6f,0x2c,0x76,0x6f,0x69,0x64,0x20,0x30,0x3d,0x3d,0x3d,0x77,0x69,0x6e, +0x64,0x6f,0x77,0x2e,0x24,0x26,0x26,0x28,0x77,0x69,0x6e,0x64,0x6f,0x77,0x2e,0x24, +0x3d,0x5a,0x65,0x70,0x74,0x6f,0x29,0x2c,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e, +0x28,0x74,0x29,0x7b,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x20,0x6c,0x28,0x74, +0x29,0x7b,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x74,0x2e,0x5f,0x7a,0x69,0x64,0x7c, +0x7c,0x28,0x74,0x2e,0x5f,0x7a,0x69,0x64,0x3d,0x65,0x2b,0x2b,0x29,0x7d,0x66,0x75, +0x6e,0x63,0x74,0x69,0x6f,0x6e,0x20,0x68,0x28,0x74,0x2c,0x65,0x2c,0x6e,0x2c,0x69, +0x29,0x7b,0x69,0x66,0x28,0x65,0x3d,0x70,0x28,0x65,0x29,0x2c,0x65,0x2e,0x6e,0x73, +0x29,0x76,0x61,0x72,0x20,0x72,0x3d,0x64,0x28,0x65,0x2e,0x6e,0x73,0x29,0x3b,0x72, +0x65,0x74,0x75,0x72,0x6e,0x28,0x73,0x5b,0x6c,0x28,0x74,0x29,0x5d,0x7c,0x7c,0x5b, +0x5d,0x29,0x2e,0x66,0x69,0x6c,0x74,0x65,0x72,0x28,0x66,0x75,0x6e,0x63,0x74,0x69, +0x6f,0x6e,0x28,0x74,0x29,0x7b,0x72,0x65,0x74,0x75,0x72,0x6e,0x21,0x28,0x21,0x74, +0x7c,0x7c,0x65,0x2e,0x65,0x26,0x26,0x74,0x2e,0x65,0x21,0x3d,0x65,0x2e,0x65,0x7c, +0x7c,0x65,0x2e,0x6e,0x73,0x26,0x26,0x21,0x72,0x2e,0x74,0x65,0x73,0x74,0x28,0x74, +0x2e,0x6e,0x73,0x29,0x7c,0x7c,0x6e,0x26,0x26,0x6c,0x28,0x74,0x2e,0x66,0x6e,0x29, +0x21,0x3d,0x3d,0x6c,0x28,0x6e,0x29,0x7c,0x7c,0x69,0x26,0x26,0x74,0x2e,0x73,0x65, +0x6c,0x21,0x3d,0x69,0x29,0x7d,0x29,0x7d,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e, +0x20,0x70,0x28,0x74,0x29,0x7b,0x76,0x61,0x72,0x20,0x65,0x3d,0x28,0x22,0x22,0x2b, +0x74,0x29,0x2e,0x73,0x70,0x6c,0x69,0x74,0x28,0x22,0x2e,0x22,0x29,0x3b,0x72,0x65, +0x74,0x75,0x72,0x6e,0x7b,0x65,0x3a,0x65,0x5b,0x30,0x5d,0x2c,0x6e,0x73,0x3a,0x65, +0x2e,0x73,0x6c,0x69,0x63,0x65,0x28,0x31,0x29,0x2e,0x73,0x6f,0x72,0x74,0x28,0x29, +0x2e,0x6a,0x6f,0x69,0x6e,0x28,0x22,0x20,0x22,0x29,0x7d,0x7d,0x66,0x75,0x6e,0x63, +0x74,0x69,0x6f,0x6e,0x20,0x64,0x28,0x74,0x29,0x7b,0x72,0x65,0x74,0x75,0x72,0x6e, +0x20,0x6e,0x65,0x77,0x20,0x52,0x65,0x67,0x45,0x78,0x70,0x28,0x22,0x28,0x3f,0x3a, +0x5e,0x7c,0x20,0x29,0x22,0x2b,0x74,0x2e,0x72,0x65,0x70,0x6c,0x61,0x63,0x65,0x28, +0x22,0x20,0x22,0x2c,0x22,0x20,0x2e,0x2a,0x20,0x3f,0x22,0x29,0x2b,0x22,0x28,0x3f, +0x3a,0x20,0x7c,0x24,0x29,0x22,0x29,0x7d,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e, +0x20,0x6d,0x28,0x74,0x2c,0x65,0x29,0x7b,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x74, +0x2e,0x64,0x65,0x6c,0x26,0x26,0x21,0x75,0x26,0x26,0x74,0x2e,0x65,0x20,0x69,0x6e, +0x20,0x66,0x7c,0x7c,0x21,0x21,0x65,0x7d,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e, +0x20,0x67,0x28,0x74,0x29,0x7b,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x63,0x5b,0x74, +0x5d,0x7c,0x7c,0x75,0x26,0x26,0x66,0x5b,0x74,0x5d,0x7c,0x7c,0x74,0x7d,0x66,0x75, +0x6e,0x63,0x74,0x69,0x6f,0x6e,0x20,0x76,0x28,0x65,0x2c,0x69,0x2c,0x72,0x2c,0x6f, +0x2c,0x61,0x2c,0x75,0x2c,0x66,0x29,0x7b,0x76,0x61,0x72,0x20,0x68,0x3d,0x6c,0x28, +0x65,0x29,0x2c,0x64,0x3d,0x73,0x5b,0x68,0x5d,0x7c,0x7c,0x28,0x73,0x5b,0x68,0x5d, +0x3d,0x5b,0x5d,0x29,0x3b,0x69,0x2e,0x73,0x70,0x6c,0x69,0x74,0x28,0x2f,0x5c,0x73, +0x2f,0x29,0x2e,0x66,0x6f,0x72,0x45,0x61,0x63,0x68,0x28,0x66,0x75,0x6e,0x63,0x74, +0x69,0x6f,0x6e,0x28,0x69,0x29,0x7b,0x69,0x66,0x28,0x22,0x72,0x65,0x61,0x64,0x79, +0x22,0x3d,0x3d,0x69,0x29,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x74,0x28,0x64,0x6f, +0x63,0x75,0x6d,0x65,0x6e,0x74,0x29,0x2e,0x72,0x65,0x61,0x64,0x79,0x28,0x72,0x29, +0x3b,0x76,0x61,0x72,0x20,0x73,0x3d,0x70,0x28,0x69,0x29,0x3b,0x73,0x2e,0x66,0x6e, +0x3d,0x72,0x2c,0x73,0x2e,0x73,0x65,0x6c,0x3d,0x61,0x2c,0x73,0x2e,0x65,0x20,0x69, +0x6e,0x20,0x63,0x26,0x26,0x28,0x72,0x3d,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e, +0x28,0x65,0x29,0x7b,0x76,0x61,0x72,0x20,0x6e,0x3d,0x65,0x2e,0x72,0x65,0x6c,0x61, +0x74,0x65,0x64,0x54,0x61,0x72,0x67,0x65,0x74,0x3b,0x72,0x65,0x74,0x75,0x72,0x6e, +0x21,0x6e,0x7c,0x7c,0x6e,0x21,0x3d,0x3d,0x74,0x68,0x69,0x73,0x26,0x26,0x21,0x74, +0x2e,0x63,0x6f,0x6e,0x74,0x61,0x69,0x6e,0x73,0x28,0x74,0x68,0x69,0x73,0x2c,0x6e, +0x29,0x3f,0x73,0x2e,0x66,0x6e,0x2e,0x61,0x70,0x70,0x6c,0x79,0x28,0x74,0x68,0x69, +0x73,0x2c,0x61,0x72,0x67,0x75,0x6d,0x65,0x6e,0x74,0x73,0x29,0x3a,0x76,0x6f,0x69, +0x64,0x20,0x30,0x7d,0x29,0x2c,0x73,0x2e,0x64,0x65,0x6c,0x3d,0x75,0x3b,0x76,0x61, +0x72,0x20,0x6c,0x3d,0x75,0x7c,0x7c,0x72,0x3b,0x73,0x2e,0x70,0x72,0x6f,0x78,0x79, +0x3d,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x74,0x29,0x7b,0x69,0x66,0x28, +0x74,0x3d,0x6a,0x28,0x74,0x29,0x2c,0x21,0x74,0x2e,0x69,0x73,0x49,0x6d,0x6d,0x65, +0x64,0x69,0x61,0x74,0x65,0x50,0x72,0x6f,0x70,0x61,0x67,0x61,0x74,0x69,0x6f,0x6e, +0x53,0x74,0x6f,0x70,0x70,0x65,0x64,0x28,0x29,0x29,0x7b,0x74,0x2e,0x64,0x61,0x74, +0x61,0x3d,0x6f,0x3b,0x76,0x61,0x72,0x20,0x69,0x3d,0x6c,0x2e,0x61,0x70,0x70,0x6c, +0x79,0x28,0x65,0x2c,0x74,0x2e,0x5f,0x61,0x72,0x67,0x73,0x3d,0x3d,0x6e,0x3f,0x5b, +0x74,0x5d,0x3a,0x5b,0x74,0x5d,0x2e,0x63,0x6f,0x6e,0x63,0x61,0x74,0x28,0x74,0x2e, +0x5f,0x61,0x72,0x67,0x73,0x29,0x29,0x3b,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x69, +0x3d,0x3d,0x3d,0x21,0x31,0x26,0x26,0x28,0x74,0x2e,0x70,0x72,0x65,0x76,0x65,0x6e, +0x74,0x44,0x65,0x66,0x61,0x75,0x6c,0x74,0x28,0x29,0x2c,0x74,0x2e,0x73,0x74,0x6f, +0x70,0x50,0x72,0x6f,0x70,0x61,0x67,0x61,0x74,0x69,0x6f,0x6e,0x28,0x29,0x29,0x2c, +0x69,0x7d,0x7d,0x2c,0x73,0x2e,0x69,0x3d,0x64,0x2e,0x6c,0x65,0x6e,0x67,0x74,0x68, +0x2c,0x64,0x2e,0x70,0x75,0x73,0x68,0x28,0x73,0x29,0x2c,0x22,0x61,0x64,0x64,0x45, +0x76,0x65,0x6e,0x74,0x4c,0x69,0x73,0x74,0x65,0x6e,0x65,0x72,0x22,0x69,0x6e,0x20, +0x65,0x26,0x26,0x65,0x2e,0x61,0x64,0x64,0x45,0x76,0x65,0x6e,0x74,0x4c,0x69,0x73, +0x74,0x65,0x6e,0x65,0x72,0x28,0x67,0x28,0x73,0x2e,0x65,0x29,0x2c,0x73,0x2e,0x70, +0x72,0x6f,0x78,0x79,0x2c,0x6d,0x28,0x73,0x2c,0x66,0x29,0x29,0x7d,0x29,0x7d,0x66, +0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x20,0x79,0x28,0x74,0x2c,0x65,0x2c,0x6e,0x2c, +0x69,0x2c,0x72,0x29,0x7b,0x76,0x61,0x72,0x20,0x6f,0x3d,0x6c,0x28,0x74,0x29,0x3b, +0x28,0x65,0x7c,0x7c,0x22,0x22,0x29,0x2e,0x73,0x70,0x6c,0x69,0x74,0x28,0x2f,0x5c, +0x73,0x2f,0x29,0x2e,0x66,0x6f,0x72,0x45,0x61,0x63,0x68,0x28,0x66,0x75,0x6e,0x63, +0x74,0x69,0x6f,0x6e,0x28,0x65,0x29,0x7b,0x68,0x28,0x74,0x2c,0x65,0x2c,0x6e,0x2c, +0x69,0x29,0x2e,0x66,0x6f,0x72,0x45,0x61,0x63,0x68,0x28,0x66,0x75,0x6e,0x63,0x74, +0x69,0x6f,0x6e,0x28,0x65,0x29,0x7b,0x64,0x65,0x6c,0x65,0x74,0x65,0x20,0x73,0x5b, +0x6f,0x5d,0x5b,0x65,0x2e,0x69,0x5d,0x2c,0x22,0x72,0x65,0x6d,0x6f,0x76,0x65,0x45, +0x76,0x65,0x6e,0x74,0x4c,0x69,0x73,0x74,0x65,0x6e,0x65,0x72,0x22,0x69,0x6e,0x20, +0x74,0x26,0x26,0x74,0x2e,0x72,0x65,0x6d,0x6f,0x76,0x65,0x45,0x76,0x65,0x6e,0x74, +0x4c,0x69,0x73,0x74,0x65,0x6e,0x65,0x72,0x28,0x67,0x28,0x65,0x2e,0x65,0x29,0x2c, +0x65,0x2e,0x70,0x72,0x6f,0x78,0x79,0x2c,0x6d,0x28,0x65,0x2c,0x72,0x29,0x29,0x7d, +0x29,0x7d,0x29,0x7d,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x20,0x6a,0x28,0x65, +0x2c,0x69,0x29,0x7b,0x72,0x65,0x74,0x75,0x72,0x6e,0x28,0x69,0x7c,0x7c,0x21,0x65, +0x2e,0x69,0x73,0x44,0x65,0x66,0x61,0x75,0x6c,0x74,0x50,0x72,0x65,0x76,0x65,0x6e, +0x74,0x65,0x64,0x29,0x26,0x26,0x28,0x69,0x7c,0x7c,0x28,0x69,0x3d,0x65,0x29,0x2c, +0x74,0x2e,0x65,0x61,0x63,0x68,0x28,0x45,0x2c,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f, +0x6e,0x28,0x74,0x2c,0x6e,0x29,0x7b,0x76,0x61,0x72,0x20,0x72,0x3d,0x69,0x5b,0x74, +0x5d,0x3b,0x65,0x5b,0x74,0x5d,0x3d,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28, +0x29,0x7b,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x74,0x68,0x69,0x73,0x5b,0x6e,0x5d, +0x3d,0x78,0x2c,0x72,0x26,0x26,0x72,0x2e,0x61,0x70,0x70,0x6c,0x79,0x28,0x69,0x2c, +0x61,0x72,0x67,0x75,0x6d,0x65,0x6e,0x74,0x73,0x29,0x7d,0x2c,0x65,0x5b,0x6e,0x5d, +0x3d,0x62,0x7d,0x29,0x2c,0x28,0x69,0x2e,0x64,0x65,0x66,0x61,0x75,0x6c,0x74,0x50, +0x72,0x65,0x76,0x65,0x6e,0x74,0x65,0x64,0x21,0x3d,0x3d,0x6e,0x3f,0x69,0x2e,0x64, +0x65,0x66,0x61,0x75,0x6c,0x74,0x50,0x72,0x65,0x76,0x65,0x6e,0x74,0x65,0x64,0x3a, +0x22,0x72,0x65,0x74,0x75,0x72,0x6e,0x56,0x61,0x6c,0x75,0x65,0x22,0x69,0x6e,0x20, +0x69,0x3f,0x69,0x2e,0x72,0x65,0x74,0x75,0x72,0x6e,0x56,0x61,0x6c,0x75,0x65,0x3d, +0x3d,0x3d,0x21,0x31,0x3a,0x69,0x2e,0x67,0x65,0x74,0x50,0x72,0x65,0x76,0x65,0x6e, +0x74,0x44,0x65,0x66,0x61,0x75,0x6c,0x74,0x26,0x26,0x69,0x2e,0x67,0x65,0x74,0x50, +0x72,0x65,0x76,0x65,0x6e,0x74,0x44,0x65,0x66,0x61,0x75,0x6c,0x74,0x28,0x29,0x29, +0x26,0x26,0x28,0x65,0x2e,0x69,0x73,0x44,0x65,0x66,0x61,0x75,0x6c,0x74,0x50,0x72, +0x65,0x76,0x65,0x6e,0x74,0x65,0x64,0x3d,0x78,0x29,0x29,0x2c,0x65,0x7d,0x66,0x75, +0x6e,0x63,0x74,0x69,0x6f,0x6e,0x20,0x53,0x28,0x74,0x29,0x7b,0x76,0x61,0x72,0x20, +0x65,0x2c,0x69,0x3d,0x7b,0x6f,0x72,0x69,0x67,0x69,0x6e,0x61,0x6c,0x45,0x76,0x65, +0x6e,0x74,0x3a,0x74,0x7d,0x3b,0x66,0x6f,0x72,0x28,0x65,0x20,0x69,0x6e,0x20,0x74, +0x29,0x77,0x2e,0x74,0x65,0x73,0x74,0x28,0x65,0x29,0x7c,0x7c,0x74,0x5b,0x65,0x5d, +0x3d,0x3d,0x3d,0x6e,0x7c,0x7c,0x28,0x69,0x5b,0x65,0x5d,0x3d,0x74,0x5b,0x65,0x5d, +0x29,0x3b,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x6a,0x28,0x69,0x2c,0x74,0x29,0x7d, +0x76,0x61,0x72,0x20,0x6e,0x2c,0x65,0x3d,0x31,0x2c,0x69,0x3d,0x41,0x72,0x72,0x61, +0x79,0x2e,0x70,0x72,0x6f,0x74,0x6f,0x74,0x79,0x70,0x65,0x2e,0x73,0x6c,0x69,0x63, +0x65,0x2c,0x72,0x3d,0x74,0x2e,0x69,0x73,0x46,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e, +0x2c,0x6f,0x3d,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x74,0x29,0x7b,0x72, +0x65,0x74,0x75,0x72,0x6e,0x22,0x73,0x74,0x72,0x69,0x6e,0x67,0x22,0x3d,0x3d,0x74, +0x79,0x70,0x65,0x6f,0x66,0x20,0x74,0x7d,0x2c,0x73,0x3d,0x7b,0x7d,0x2c,0x61,0x3d, +0x7b,0x7d,0x2c,0x75,0x3d,0x22,0x6f,0x6e,0x66,0x6f,0x63,0x75,0x73,0x69,0x6e,0x22, +0x69,0x6e,0x20,0x77,0x69,0x6e,0x64,0x6f,0x77,0x2c,0x66,0x3d,0x7b,0x66,0x6f,0x63, +0x75,0x73,0x3a,0x22,0x66,0x6f,0x63,0x75,0x73,0x69,0x6e,0x22,0x2c,0x62,0x6c,0x75, +0x72,0x3a,0x22,0x66,0x6f,0x63,0x75,0x73,0x6f,0x75,0x74,0x22,0x7d,0x2c,0x63,0x3d, +0x7b,0x6d,0x6f,0x75,0x73,0x65,0x65,0x6e,0x74,0x65,0x72,0x3a,0x22,0x6d,0x6f,0x75, +0x73,0x65,0x6f,0x76,0x65,0x72,0x22,0x2c,0x6d,0x6f,0x75,0x73,0x65,0x6c,0x65,0x61, +0x76,0x65,0x3a,0x22,0x6d,0x6f,0x75,0x73,0x65,0x6f,0x75,0x74,0x22,0x7d,0x3b,0x61, +0x2e,0x63,0x6c,0x69,0x63,0x6b,0x3d,0x61,0x2e,0x6d,0x6f,0x75,0x73,0x65,0x64,0x6f, +0x77,0x6e,0x3d,0x61,0x2e,0x6d,0x6f,0x75,0x73,0x65,0x75,0x70,0x3d,0x61,0x2e,0x6d, +0x6f,0x75,0x73,0x65,0x6d,0x6f,0x76,0x65,0x3d,0x22,0x4d,0x6f,0x75,0x73,0x65,0x45, +0x76,0x65,0x6e,0x74,0x73,0x22,0x2c,0x74,0x2e,0x65,0x76,0x65,0x6e,0x74,0x3d,0x7b, +0x61,0x64,0x64,0x3a,0x76,0x2c,0x72,0x65,0x6d,0x6f,0x76,0x65,0x3a,0x79,0x7d,0x2c, +0x74,0x2e,0x70,0x72,0x6f,0x78,0x79,0x3d,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e, +0x28,0x65,0x2c,0x6e,0x29,0x7b,0x76,0x61,0x72,0x20,0x73,0x3d,0x32,0x20,0x69,0x6e, +0x20,0x61,0x72,0x67,0x75,0x6d,0x65,0x6e,0x74,0x73,0x26,0x26,0x69,0x2e,0x63,0x61, +0x6c,0x6c,0x28,0x61,0x72,0x67,0x75,0x6d,0x65,0x6e,0x74,0x73,0x2c,0x32,0x29,0x3b, +0x69,0x66,0x28,0x72,0x28,0x65,0x29,0x29,0x7b,0x76,0x61,0x72,0x20,0x61,0x3d,0x66, +0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x29,0x7b,0x72,0x65,0x74,0x75,0x72,0x6e, +0x20,0x65,0x2e,0x61,0x70,0x70,0x6c,0x79,0x28,0x6e,0x2c,0x73,0x3f,0x73,0x2e,0x63, +0x6f,0x6e,0x63,0x61,0x74,0x28,0x69,0x2e,0x63,0x61,0x6c,0x6c,0x28,0x61,0x72,0x67, +0x75,0x6d,0x65,0x6e,0x74,0x73,0x29,0x29,0x3a,0x61,0x72,0x67,0x75,0x6d,0x65,0x6e, +0x74,0x73,0x29,0x7d,0x3b,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x61,0x2e,0x5f,0x7a, +0x69,0x64,0x3d,0x6c,0x28,0x65,0x29,0x2c,0x61,0x7d,0x69,0x66,0x28,0x6f,0x28,0x6e, +0x29,0x29,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x73,0x3f,0x28,0x73,0x2e,0x75,0x6e, +0x73,0x68,0x69,0x66,0x74,0x28,0x65,0x5b,0x6e,0x5d,0x2c,0x65,0x29,0x2c,0x74,0x2e, +0x70,0x72,0x6f,0x78,0x79,0x2e,0x61,0x70,0x70,0x6c,0x79,0x28,0x6e,0x75,0x6c,0x6c, +0x2c,0x73,0x29,0x29,0x3a,0x74,0x2e,0x70,0x72,0x6f,0x78,0x79,0x28,0x65,0x5b,0x6e, +0x5d,0x2c,0x65,0x29,0x3b,0x74,0x68,0x72,0x6f,0x77,0x20,0x6e,0x65,0x77,0x20,0x54, +0x79,0x70,0x65,0x45,0x72,0x72,0x6f,0x72,0x28,0x22,0x65,0x78,0x70,0x65,0x63,0x74, +0x65,0x64,0x20,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x22,0x29,0x7d,0x2c,0x74, +0x2e,0x66,0x6e,0x2e,0x62,0x69,0x6e,0x64,0x3d,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f, +0x6e,0x28,0x74,0x2c,0x65,0x2c,0x6e,0x29,0x7b,0x72,0x65,0x74,0x75,0x72,0x6e,0x20, +0x74,0x68,0x69,0x73,0x2e,0x6f,0x6e,0x28,0x74,0x2c,0x65,0x2c,0x6e,0x29,0x7d,0x2c, +0x74,0x2e,0x66,0x6e,0x2e,0x75,0x6e,0x62,0x69,0x6e,0x64,0x3d,0x66,0x75,0x6e,0x63, +0x74,0x69,0x6f,0x6e,0x28,0x74,0x2c,0x65,0x29,0x7b,0x72,0x65,0x74,0x75,0x72,0x6e, +0x20,0x74,0x68,0x69,0x73,0x2e,0x6f,0x66,0x66,0x28,0x74,0x2c,0x65,0x29,0x7d,0x2c, +0x74,0x2e,0x66,0x6e,0x2e,0x6f,0x6e,0x65,0x3d,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f, +0x6e,0x28,0x74,0x2c,0x65,0x2c,0x6e,0x2c,0x69,0x29,0x7b,0x72,0x65,0x74,0x75,0x72, +0x6e,0x20,0x74,0x68,0x69,0x73,0x2e,0x6f,0x6e,0x28,0x74,0x2c,0x65,0x2c,0x6e,0x2c, +0x69,0x2c,0x31,0x29,0x7d,0x3b,0x76,0x61,0x72,0x20,0x78,0x3d,0x66,0x75,0x6e,0x63, +0x74,0x69,0x6f,0x6e,0x28,0x29,0x7b,0x72,0x65,0x74,0x75,0x72,0x6e,0x21,0x30,0x7d, +0x2c,0x62,0x3d,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x29,0x7b,0x72,0x65, +0x74,0x75,0x72,0x6e,0x21,0x31,0x7d,0x2c,0x77,0x3d,0x2f,0x5e,0x28,0x5b,0x41,0x2d, +0x5a,0x5d,0x7c,0x72,0x65,0x74,0x75,0x72,0x6e,0x56,0x61,0x6c,0x75,0x65,0x24,0x7c, +0x6c,0x61,0x79,0x65,0x72,0x5b,0x58,0x59,0x5d,0x24,0x29,0x2f,0x2c,0x45,0x3d,0x7b, +0x70,0x72,0x65,0x76,0x65,0x6e,0x74,0x44,0x65,0x66,0x61,0x75,0x6c,0x74,0x3a,0x22, +0x69,0x73,0x44,0x65,0x66,0x61,0x75,0x6c,0x74,0x50,0x72,0x65,0x76,0x65,0x6e,0x74, +0x65,0x64,0x22,0x2c,0x73,0x74,0x6f,0x70,0x49,0x6d,0x6d,0x65,0x64,0x69,0x61,0x74, +0x65,0x50,0x72,0x6f,0x70,0x61,0x67,0x61,0x74,0x69,0x6f,0x6e,0x3a,0x22,0x69,0x73, +0x49,0x6d,0x6d,0x65,0x64,0x69,0x61,0x74,0x65,0x50,0x72,0x6f,0x70,0x61,0x67,0x61, +0x74,0x69,0x6f,0x6e,0x53,0x74,0x6f,0x70,0x70,0x65,0x64,0x22,0x2c,0x73,0x74,0x6f, +0x70,0x50,0x72,0x6f,0x70,0x61,0x67,0x61,0x74,0x69,0x6f,0x6e,0x3a,0x22,0x69,0x73, +0x50,0x72,0x6f,0x70,0x61,0x67,0x61,0x74,0x69,0x6f,0x6e,0x53,0x74,0x6f,0x70,0x70, +0x65,0x64,0x22,0x7d,0x3b,0x74,0x2e,0x66,0x6e,0x2e,0x64,0x65,0x6c,0x65,0x67,0x61, +0x74,0x65,0x3d,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x74,0x2c,0x65,0x2c, +0x6e,0x29,0x7b,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x74,0x68,0x69,0x73,0x2e,0x6f, +0x6e,0x28,0x65,0x2c,0x74,0x2c,0x6e,0x29,0x7d,0x2c,0x74,0x2e,0x66,0x6e,0x2e,0x75, +0x6e,0x64,0x65,0x6c,0x65,0x67,0x61,0x74,0x65,0x3d,0x66,0x75,0x6e,0x63,0x74,0x69, +0x6f,0x6e,0x28,0x74,0x2c,0x65,0x2c,0x6e,0x29,0x7b,0x72,0x65,0x74,0x75,0x72,0x6e, +0x20,0x74,0x68,0x69,0x73,0x2e,0x6f,0x66,0x66,0x28,0x65,0x2c,0x74,0x2c,0x6e,0x29, +0x7d,0x2c,0x74,0x2e,0x66,0x6e,0x2e,0x6c,0x69,0x76,0x65,0x3d,0x66,0x75,0x6e,0x63, +0x74,0x69,0x6f,0x6e,0x28,0x65,0x2c,0x6e,0x29,0x7b,0x72,0x65,0x74,0x75,0x72,0x6e, +0x20,0x74,0x28,0x64,0x6f,0x63,0x75,0x6d,0x65,0x6e,0x74,0x2e,0x62,0x6f,0x64,0x79, +0x29,0x2e,0x64,0x65,0x6c,0x65,0x67,0x61,0x74,0x65,0x28,0x74,0x68,0x69,0x73,0x2e, +0x73,0x65,0x6c,0x65,0x63,0x74,0x6f,0x72,0x2c,0x65,0x2c,0x6e,0x29,0x2c,0x74,0x68, +0x69,0x73,0x7d,0x2c,0x74,0x2e,0x66,0x6e,0x2e,0x64,0x69,0x65,0x3d,0x66,0x75,0x6e, +0x63,0x74,0x69,0x6f,0x6e,0x28,0x65,0x2c,0x6e,0x29,0x7b,0x72,0x65,0x74,0x75,0x72, +0x6e,0x20,0x74,0x28,0x64,0x6f,0x63,0x75,0x6d,0x65,0x6e,0x74,0x2e,0x62,0x6f,0x64, +0x79,0x29,0x2e,0x75,0x6e,0x64,0x65,0x6c,0x65,0x67,0x61,0x74,0x65,0x28,0x74,0x68, +0x69,0x73,0x2e,0x73,0x65,0x6c,0x65,0x63,0x74,0x6f,0x72,0x2c,0x65,0x2c,0x6e,0x29, +0x2c,0x74,0x68,0x69,0x73,0x7d,0x2c,0x74,0x2e,0x66,0x6e,0x2e,0x6f,0x6e,0x3d,0x66, +0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x65,0x2c,0x73,0x2c,0x61,0x2c,0x75,0x2c, +0x66,0x29,0x7b,0x76,0x61,0x72,0x20,0x63,0x2c,0x6c,0x2c,0x68,0x3d,0x74,0x68,0x69, +0x73,0x3b,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x65,0x26,0x26,0x21,0x6f,0x28,0x65, +0x29,0x3f,0x28,0x74,0x2e,0x65,0x61,0x63,0x68,0x28,0x65,0x2c,0x66,0x75,0x6e,0x63, +0x74,0x69,0x6f,0x6e,0x28,0x74,0x2c,0x65,0x29,0x7b,0x68,0x2e,0x6f,0x6e,0x28,0x74, +0x2c,0x73,0x2c,0x61,0x2c,0x65,0x2c,0x66,0x29,0x7d,0x29,0x2c,0x68,0x29,0x3a,0x28, +0x6f,0x28,0x73,0x29,0x7c,0x7c,0x72,0x28,0x75,0x29,0x7c,0x7c,0x75,0x3d,0x3d,0x3d, +0x21,0x31,0x7c,0x7c,0x28,0x75,0x3d,0x61,0x2c,0x61,0x3d,0x73,0x2c,0x73,0x3d,0x6e, +0x29,0x2c,0x28,0x72,0x28,0x61,0x29,0x7c,0x7c,0x61,0x3d,0x3d,0x3d,0x21,0x31,0x29, +0x26,0x26,0x28,0x75,0x3d,0x61,0x2c,0x61,0x3d,0x6e,0x29,0x2c,0x75,0x3d,0x3d,0x3d, +0x21,0x31,0x26,0x26,0x28,0x75,0x3d,0x62,0x29,0x2c,0x68,0x2e,0x65,0x61,0x63,0x68, +0x28,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x6e,0x2c,0x72,0x29,0x7b,0x66, +0x26,0x26,0x28,0x63,0x3d,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x74,0x29, +0x7b,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x79,0x28,0x72,0x2c,0x74,0x2e,0x74,0x79, +0x70,0x65,0x2c,0x75,0x29,0x2c,0x75,0x2e,0x61,0x70,0x70,0x6c,0x79,0x28,0x74,0x68, +0x69,0x73,0x2c,0x61,0x72,0x67,0x75,0x6d,0x65,0x6e,0x74,0x73,0x29,0x7d,0x29,0x2c, +0x73,0x26,0x26,0x28,0x6c,0x3d,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x65, +0x29,0x7b,0x76,0x61,0x72,0x20,0x6e,0x2c,0x6f,0x3d,0x74,0x28,0x65,0x2e,0x74,0x61, +0x72,0x67,0x65,0x74,0x29,0x2e,0x63,0x6c,0x6f,0x73,0x65,0x73,0x74,0x28,0x73,0x2c, +0x72,0x29,0x2e,0x67,0x65,0x74,0x28,0x30,0x29,0x3b,0x72,0x65,0x74,0x75,0x72,0x6e, +0x20,0x6f,0x26,0x26,0x6f,0x21,0x3d,0x3d,0x72,0x3f,0x28,0x6e,0x3d,0x74,0x2e,0x65, +0x78,0x74,0x65,0x6e,0x64,0x28,0x53,0x28,0x65,0x29,0x2c,0x7b,0x63,0x75,0x72,0x72, +0x65,0x6e,0x74,0x54,0x61,0x72,0x67,0x65,0x74,0x3a,0x6f,0x2c,0x6c,0x69,0x76,0x65, +0x46,0x69,0x72,0x65,0x64,0x3a,0x72,0x7d,0x29,0x2c,0x28,0x63,0x7c,0x7c,0x75,0x29, +0x2e,0x61,0x70,0x70,0x6c,0x79,0x28,0x6f,0x2c,0x5b,0x6e,0x5d,0x2e,0x63,0x6f,0x6e, +0x63,0x61,0x74,0x28,0x69,0x2e,0x63,0x61,0x6c,0x6c,0x28,0x61,0x72,0x67,0x75,0x6d, +0x65,0x6e,0x74,0x73,0x2c,0x31,0x29,0x29,0x29,0x29,0x3a,0x76,0x6f,0x69,0x64,0x20, +0x30,0x7d,0x29,0x2c,0x76,0x28,0x72,0x2c,0x65,0x2c,0x75,0x2c,0x61,0x2c,0x73,0x2c, +0x6c,0x7c,0x7c,0x63,0x29,0x7d,0x29,0x29,0x7d,0x2c,0x74,0x2e,0x66,0x6e,0x2e,0x6f, +0x66,0x66,0x3d,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x65,0x2c,0x69,0x2c, +0x73,0x29,0x7b,0x76,0x61,0x72,0x20,0x61,0x3d,0x74,0x68,0x69,0x73,0x3b,0x72,0x65, +0x74,0x75,0x72,0x6e,0x20,0x65,0x26,0x26,0x21,0x6f,0x28,0x65,0x29,0x3f,0x28,0x74, +0x2e,0x65,0x61,0x63,0x68,0x28,0x65,0x2c,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e, +0x28,0x74,0x2c,0x65,0x29,0x7b,0x61,0x2e,0x6f,0x66,0x66,0x28,0x74,0x2c,0x69,0x2c, +0x65,0x29,0x7d,0x29,0x2c,0x61,0x29,0x3a,0x28,0x6f,0x28,0x69,0x29,0x7c,0x7c,0x72, +0x28,0x73,0x29,0x7c,0x7c,0x73,0x3d,0x3d,0x3d,0x21,0x31,0x7c,0x7c,0x28,0x73,0x3d, +0x69,0x2c,0x69,0x3d,0x6e,0x29,0x2c,0x73,0x3d,0x3d,0x3d,0x21,0x31,0x26,0x26,0x28, +0x73,0x3d,0x62,0x29,0x2c,0x61,0x2e,0x65,0x61,0x63,0x68,0x28,0x66,0x75,0x6e,0x63, +0x74,0x69,0x6f,0x6e,0x28,0x29,0x7b,0x79,0x28,0x74,0x68,0x69,0x73,0x2c,0x65,0x2c, +0x73,0x2c,0x69,0x29,0x7d,0x29,0x29,0x7d,0x2c,0x74,0x2e,0x66,0x6e,0x2e,0x74,0x72, +0x69,0x67,0x67,0x65,0x72,0x3d,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x65, +0x2c,0x6e,0x29,0x7b,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x65,0x3d,0x6f,0x28,0x65, +0x29,0x7c,0x7c,0x74,0x2e,0x69,0x73,0x50,0x6c,0x61,0x69,0x6e,0x4f,0x62,0x6a,0x65, +0x63,0x74,0x28,0x65,0x29,0x3f,0x74,0x2e,0x45,0x76,0x65,0x6e,0x74,0x28,0x65,0x29, +0x3a,0x6a,0x28,0x65,0x29,0x2c,0x65,0x2e,0x5f,0x61,0x72,0x67,0x73,0x3d,0x6e,0x2c, +0x74,0x68,0x69,0x73,0x2e,0x65,0x61,0x63,0x68,0x28,0x66,0x75,0x6e,0x63,0x74,0x69, +0x6f,0x6e,0x28,0x29,0x7b,0x65,0x2e,0x74,0x79,0x70,0x65,0x20,0x69,0x6e,0x20,0x66, +0x26,0x26,0x22,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x22,0x3d,0x3d,0x74,0x79, +0x70,0x65,0x6f,0x66,0x20,0x74,0x68,0x69,0x73,0x5b,0x65,0x2e,0x74,0x79,0x70,0x65, +0x5d,0x3f,0x74,0x68,0x69,0x73,0x5b,0x65,0x2e,0x74,0x79,0x70,0x65,0x5d,0x28,0x29, +0x3a,0x22,0x64,0x69,0x73,0x70,0x61,0x74,0x63,0x68,0x45,0x76,0x65,0x6e,0x74,0x22, +0x69,0x6e,0x20,0x74,0x68,0x69,0x73,0x3f,0x74,0x68,0x69,0x73,0x2e,0x64,0x69,0x73, +0x70,0x61,0x74,0x63,0x68,0x45,0x76,0x65,0x6e,0x74,0x28,0x65,0x29,0x3a,0x74,0x28, +0x74,0x68,0x69,0x73,0x29,0x2e,0x74,0x72,0x69,0x67,0x67,0x65,0x72,0x48,0x61,0x6e, +0x64,0x6c,0x65,0x72,0x28,0x65,0x2c,0x6e,0x29,0x7d,0x29,0x7d,0x2c,0x74,0x2e,0x66, +0x6e,0x2e,0x74,0x72,0x69,0x67,0x67,0x65,0x72,0x48,0x61,0x6e,0x64,0x6c,0x65,0x72, +0x3d,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x65,0x2c,0x6e,0x29,0x7b,0x76, +0x61,0x72,0x20,0x69,0x2c,0x72,0x3b,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x74,0x68, +0x69,0x73,0x2e,0x65,0x61,0x63,0x68,0x28,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e, +0x28,0x73,0x2c,0x61,0x29,0x7b,0x69,0x3d,0x53,0x28,0x6f,0x28,0x65,0x29,0x3f,0x74, +0x2e,0x45,0x76,0x65,0x6e,0x74,0x28,0x65,0x29,0x3a,0x65,0x29,0x2c,0x69,0x2e,0x5f, +0x61,0x72,0x67,0x73,0x3d,0x6e,0x2c,0x69,0x2e,0x74,0x61,0x72,0x67,0x65,0x74,0x3d, +0x61,0x2c,0x74,0x2e,0x65,0x61,0x63,0x68,0x28,0x68,0x28,0x61,0x2c,0x65,0x2e,0x74, +0x79,0x70,0x65,0x7c,0x7c,0x65,0x29,0x2c,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e, +0x28,0x74,0x2c,0x65,0x29,0x7b,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x72,0x3d,0x65, +0x2e,0x70,0x72,0x6f,0x78,0x79,0x28,0x69,0x29,0x2c,0x69,0x2e,0x69,0x73,0x49,0x6d, +0x6d,0x65,0x64,0x69,0x61,0x74,0x65,0x50,0x72,0x6f,0x70,0x61,0x67,0x61,0x74,0x69, +0x6f,0x6e,0x53,0x74,0x6f,0x70,0x70,0x65,0x64,0x28,0x29,0x3f,0x21,0x31,0x3a,0x76, +0x6f,0x69,0x64,0x20,0x30,0x7d,0x29,0x7d,0x29,0x2c,0x72,0x7d,0x2c,0x22,0x66,0x6f, +0x63,0x75,0x73,0x69,0x6e,0x20,0x66,0x6f,0x63,0x75,0x73,0x6f,0x75,0x74,0x20,0x66, +0x6f,0x63,0x75,0x73,0x20,0x62,0x6c,0x75,0x72,0x20,0x6c,0x6f,0x61,0x64,0x20,0x72, +0x65,0x73,0x69,0x7a,0x65,0x20,0x73,0x63,0x72,0x6f,0x6c,0x6c,0x20,0x75,0x6e,0x6c, +0x6f,0x61,0x64,0x20,0x63,0x6c,0x69,0x63,0x6b,0x20,0x64,0x62,0x6c,0x63,0x6c,0x69, +0x63,0x6b,0x20,0x6d,0x6f,0x75,0x73,0x65,0x64,0x6f,0x77,0x6e,0x20,0x6d,0x6f,0x75, +0x73,0x65,0x75,0x70,0x20,0x6d,0x6f,0x75,0x73,0x65,0x6d,0x6f,0x76,0x65,0x20,0x6d, +0x6f,0x75,0x73,0x65,0x6f,0x76,0x65,0x72,0x20,0x6d,0x6f,0x75,0x73,0x65,0x6f,0x75, +0x74,0x20,0x6d,0x6f,0x75,0x73,0x65,0x65,0x6e,0x74,0x65,0x72,0x20,0x6d,0x6f,0x75, +0x73,0x65,0x6c,0x65,0x61,0x76,0x65,0x20,0x63,0x68,0x61,0x6e,0x67,0x65,0x20,0x73, +0x65,0x6c,0x65,0x63,0x74,0x20,0x6b,0x65,0x79,0x64,0x6f,0x77,0x6e,0x20,0x6b,0x65, +0x79,0x70,0x72,0x65,0x73,0x73,0x20,0x6b,0x65,0x79,0x75,0x70,0x20,0x65,0x72,0x72, +0x6f,0x72,0x22,0x2e,0x73,0x70,0x6c,0x69,0x74,0x28,0x22,0x20,0x22,0x29,0x2e,0x66, +0x6f,0x72,0x45,0x61,0x63,0x68,0x28,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28, +0x65,0x29,0x7b,0x74,0x2e,0x66,0x6e,0x5b,0x65,0x5d,0x3d,0x66,0x75,0x6e,0x63,0x74, +0x69,0x6f,0x6e,0x28,0x74,0x29,0x7b,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x30,0x20, +0x69,0x6e,0x20,0x61,0x72,0x67,0x75,0x6d,0x65,0x6e,0x74,0x73,0x3f,0x74,0x68,0x69, +0x73,0x2e,0x62,0x69,0x6e,0x64,0x28,0x65,0x2c,0x74,0x29,0x3a,0x74,0x68,0x69,0x73, +0x2e,0x74,0x72,0x69,0x67,0x67,0x65,0x72,0x28,0x65,0x29,0x7d,0x7d,0x29,0x2c,0x74, +0x2e,0x45,0x76,0x65,0x6e,0x74,0x3d,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28, +0x74,0x2c,0x65,0x29,0x7b,0x6f,0x28,0x74,0x29,0x7c,0x7c,0x28,0x65,0x3d,0x74,0x2c, +0x74,0x3d,0x65,0x2e,0x74,0x79,0x70,0x65,0x29,0x3b,0x76,0x61,0x72,0x20,0x6e,0x3d, +0x64,0x6f,0x63,0x75,0x6d,0x65,0x6e,0x74,0x2e,0x63,0x72,0x65,0x61,0x74,0x65,0x45, +0x76,0x65,0x6e,0x74,0x28,0x61,0x5b,0x74,0x5d,0x7c,0x7c,0x22,0x45,0x76,0x65,0x6e, +0x74,0x73,0x22,0x29,0x2c,0x69,0x3d,0x21,0x30,0x3b,0x69,0x66,0x28,0x65,0x29,0x66, +0x6f,0x72,0x28,0x76,0x61,0x72,0x20,0x72,0x20,0x69,0x6e,0x20,0x65,0x29,0x22,0x62, +0x75,0x62,0x62,0x6c,0x65,0x73,0x22,0x3d,0x3d,0x72,0x3f,0x69,0x3d,0x21,0x21,0x65, +0x5b,0x72,0x5d,0x3a,0x6e,0x5b,0x72,0x5d,0x3d,0x65,0x5b,0x72,0x5d,0x3b,0x72,0x65, +0x74,0x75,0x72,0x6e,0x20,0x6e,0x2e,0x69,0x6e,0x69,0x74,0x45,0x76,0x65,0x6e,0x74, +0x28,0x74,0x2c,0x69,0x2c,0x21,0x30,0x29,0x2c,0x6a,0x28,0x6e,0x29,0x7d,0x7d,0x28, +0x5a,0x65,0x70,0x74,0x6f,0x29,0x2c,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28, +0x74,0x29,0x7b,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x20,0x68,0x28,0x65,0x2c, +0x6e,0x2c,0x69,0x29,0x7b,0x76,0x61,0x72,0x20,0x72,0x3d,0x74,0x2e,0x45,0x76,0x65, +0x6e,0x74,0x28,0x6e,0x29,0x3b,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x74,0x28,0x65, +0x29,0x2e,0x74,0x72,0x69,0x67,0x67,0x65,0x72,0x28,0x72,0x2c,0x69,0x29,0x2c,0x21, +0x72,0x2e,0x69,0x73,0x44,0x65,0x66,0x61,0x75,0x6c,0x74,0x50,0x72,0x65,0x76,0x65, +0x6e,0x74,0x65,0x64,0x28,0x29,0x7d,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x20, +0x70,0x28,0x74,0x2c,0x65,0x2c,0x69,0x2c,0x72,0x29,0x7b,0x72,0x65,0x74,0x75,0x72, +0x6e,0x20,0x74,0x2e,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x3f,0x68,0x28,0x65,0x7c,0x7c, +0x6e,0x2c,0x69,0x2c,0x72,0x29,0x3a,0x76,0x6f,0x69,0x64,0x20,0x30,0x7d,0x66,0x75, +0x6e,0x63,0x74,0x69,0x6f,0x6e,0x20,0x64,0x28,0x65,0x29,0x7b,0x65,0x2e,0x67,0x6c, +0x6f,0x62,0x61,0x6c,0x26,0x26,0x30,0x3d,0x3d,0x3d,0x74,0x2e,0x61,0x63,0x74,0x69, +0x76,0x65,0x2b,0x2b,0x26,0x26,0x70,0x28,0x65,0x2c,0x6e,0x75,0x6c,0x6c,0x2c,0x22, +0x61,0x6a,0x61,0x78,0x53,0x74,0x61,0x72,0x74,0x22,0x29,0x7d,0x66,0x75,0x6e,0x63, +0x74,0x69,0x6f,0x6e,0x20,0x6d,0x28,0x65,0x29,0x7b,0x65,0x2e,0x67,0x6c,0x6f,0x62, +0x61,0x6c,0x26,0x26,0x21,0x2d,0x2d,0x74,0x2e,0x61,0x63,0x74,0x69,0x76,0x65,0x26, +0x26,0x70,0x28,0x65,0x2c,0x6e,0x75,0x6c,0x6c,0x2c,0x22,0x61,0x6a,0x61,0x78,0x53, +0x74,0x6f,0x70,0x22,0x29,0x7d,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x20,0x67, +0x28,0x74,0x2c,0x65,0x29,0x7b,0x76,0x61,0x72,0x20,0x6e,0x3d,0x65,0x2e,0x63,0x6f, +0x6e,0x74,0x65,0x78,0x74,0x3b,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x65,0x2e,0x62, +0x65,0x66,0x6f,0x72,0x65,0x53,0x65,0x6e,0x64,0x2e,0x63,0x61,0x6c,0x6c,0x28,0x6e, +0x2c,0x74,0x2c,0x65,0x29,0x3d,0x3d,0x3d,0x21,0x31,0x7c,0x7c,0x70,0x28,0x65,0x2c, +0x6e,0x2c,0x22,0x61,0x6a,0x61,0x78,0x42,0x65,0x66,0x6f,0x72,0x65,0x53,0x65,0x6e, +0x64,0x22,0x2c,0x5b,0x74,0x2c,0x65,0x5d,0x29,0x3d,0x3d,0x3d,0x21,0x31,0x3f,0x21, +0x31,0x3a,0x76,0x6f,0x69,0x64,0x20,0x70,0x28,0x65,0x2c,0x6e,0x2c,0x22,0x61,0x6a, +0x61,0x78,0x53,0x65,0x6e,0x64,0x22,0x2c,0x5b,0x74,0x2c,0x65,0x5d,0x29,0x7d,0x66, +0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x20,0x76,0x28,0x74,0x2c,0x65,0x2c,0x6e,0x2c, +0x69,0x29,0x7b,0x76,0x61,0x72,0x20,0x72,0x3d,0x6e,0x2e,0x63,0x6f,0x6e,0x74,0x65, +0x78,0x74,0x2c,0x6f,0x3d,0x22,0x73,0x75,0x63,0x63,0x65,0x73,0x73,0x22,0x3b,0x6e, +0x2e,0x73,0x75,0x63,0x63,0x65,0x73,0x73,0x2e,0x63,0x61,0x6c,0x6c,0x28,0x72,0x2c, +0x74,0x2c,0x6f,0x2c,0x65,0x29,0x2c,0x69,0x26,0x26,0x69,0x2e,0x72,0x65,0x73,0x6f, +0x6c,0x76,0x65,0x57,0x69,0x74,0x68,0x28,0x72,0x2c,0x5b,0x74,0x2c,0x6f,0x2c,0x65, +0x5d,0x29,0x2c,0x70,0x28,0x6e,0x2c,0x72,0x2c,0x22,0x61,0x6a,0x61,0x78,0x53,0x75, +0x63,0x63,0x65,0x73,0x73,0x22,0x2c,0x5b,0x65,0x2c,0x6e,0x2c,0x74,0x5d,0x29,0x2c, +0x78,0x28,0x6f,0x2c,0x65,0x2c,0x6e,0x29,0x7d,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f, +0x6e,0x20,0x79,0x28,0x74,0x2c,0x65,0x2c,0x6e,0x2c,0x69,0x2c,0x72,0x29,0x7b,0x76, +0x61,0x72,0x20,0x6f,0x3d,0x69,0x2e,0x63,0x6f,0x6e,0x74,0x65,0x78,0x74,0x3b,0x69, +0x2e,0x65,0x72,0x72,0x6f,0x72,0x2e,0x63,0x61,0x6c,0x6c,0x28,0x6f,0x2c,0x6e,0x2c, +0x65,0x2c,0x74,0x29,0x2c,0x72,0x26,0x26,0x72,0x2e,0x72,0x65,0x6a,0x65,0x63,0x74, +0x57,0x69,0x74,0x68,0x28,0x6f,0x2c,0x5b,0x6e,0x2c,0x65,0x2c,0x74,0x5d,0x29,0x2c, +0x70,0x28,0x69,0x2c,0x6f,0x2c,0x22,0x61,0x6a,0x61,0x78,0x45,0x72,0x72,0x6f,0x72, +0x22,0x2c,0x5b,0x6e,0x2c,0x69,0x2c,0x74,0x7c,0x7c,0x65,0x5d,0x29,0x2c,0x78,0x28, +0x65,0x2c,0x6e,0x2c,0x69,0x29,0x7d,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x20, +0x78,0x28,0x74,0x2c,0x65,0x2c,0x6e,0x29,0x7b,0x76,0x61,0x72,0x20,0x69,0x3d,0x6e, +0x2e,0x63,0x6f,0x6e,0x74,0x65,0x78,0x74,0x3b,0x6e,0x2e,0x63,0x6f,0x6d,0x70,0x6c, +0x65,0x74,0x65,0x2e,0x63,0x61,0x6c,0x6c,0x28,0x69,0x2c,0x65,0x2c,0x74,0x29,0x2c, +0x70,0x28,0x6e,0x2c,0x69,0x2c,0x22,0x61,0x6a,0x61,0x78,0x43,0x6f,0x6d,0x70,0x6c, +0x65,0x74,0x65,0x22,0x2c,0x5b,0x65,0x2c,0x6e,0x5d,0x29,0x2c,0x6d,0x28,0x6e,0x29, +0x7d,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x20,0x62,0x28,0x29,0x7b,0x7d,0x66, +0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x20,0x77,0x28,0x74,0x29,0x7b,0x72,0x65,0x74, +0x75,0x72,0x6e,0x20,0x74,0x26,0x26,0x28,0x74,0x3d,0x74,0x2e,0x73,0x70,0x6c,0x69, +0x74,0x28,0x22,0x3b,0x22,0x2c,0x32,0x29,0x5b,0x30,0x5d,0x29,0x2c,0x74,0x26,0x26, +0x28,0x74,0x3d,0x3d,0x66,0x3f,0x22,0x68,0x74,0x6d,0x6c,0x22,0x3a,0x74,0x3d,0x3d, +0x75,0x3f,0x22,0x6a,0x73,0x6f,0x6e,0x22,0x3a,0x73,0x2e,0x74,0x65,0x73,0x74,0x28, +0x74,0x29,0x3f,0x22,0x73,0x63,0x72,0x69,0x70,0x74,0x22,0x3a,0x61,0x2e,0x74,0x65, +0x73,0x74,0x28,0x74,0x29,0x26,0x26,0x22,0x78,0x6d,0x6c,0x22,0x29,0x7c,0x7c,0x22, +0x74,0x65,0x78,0x74,0x22,0x7d,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x20,0x45, +0x28,0x74,0x2c,0x65,0x29,0x7b,0x72,0x65,0x74,0x75,0x72,0x6e,0x22,0x22,0x3d,0x3d, +0x65,0x3f,0x74,0x3a,0x28,0x74,0x2b,0x22,0x26,0x22,0x2b,0x65,0x29,0x2e,0x72,0x65, +0x70,0x6c,0x61,0x63,0x65,0x28,0x2f,0x5b,0x26,0x3f,0x5d,0x7b,0x31,0x2c,0x32,0x7d, +0x2f,0x2c,0x22,0x3f,0x22,0x29,0x7d,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x20, +0x6a,0x28,0x65,0x29,0x7b,0x65,0x2e,0x70,0x72,0x6f,0x63,0x65,0x73,0x73,0x44,0x61, +0x74,0x61,0x26,0x26,0x65,0x2e,0x64,0x61,0x74,0x61,0x26,0x26,0x22,0x73,0x74,0x72, +0x69,0x6e,0x67,0x22,0x21,0x3d,0x74,0x2e,0x74,0x79,0x70,0x65,0x28,0x65,0x2e,0x64, +0x61,0x74,0x61,0x29,0x26,0x26,0x28,0x65,0x2e,0x64,0x61,0x74,0x61,0x3d,0x74,0x2e, +0x70,0x61,0x72,0x61,0x6d,0x28,0x65,0x2e,0x64,0x61,0x74,0x61,0x2c,0x65,0x2e,0x74, +0x72,0x61,0x64,0x69,0x74,0x69,0x6f,0x6e,0x61,0x6c,0x29,0x29,0x2c,0x21,0x65,0x2e, +0x64,0x61,0x74,0x61,0x7c,0x7c,0x65,0x2e,0x74,0x79,0x70,0x65,0x26,0x26,0x22,0x47, +0x45,0x54,0x22,0x21,0x3d,0x65,0x2e,0x74,0x79,0x70,0x65,0x2e,0x74,0x6f,0x55,0x70, +0x70,0x65,0x72,0x43,0x61,0x73,0x65,0x28,0x29,0x7c,0x7c,0x28,0x65,0x2e,0x75,0x72, +0x6c,0x3d,0x45,0x28,0x65,0x2e,0x75,0x72,0x6c,0x2c,0x65,0x2e,0x64,0x61,0x74,0x61, +0x29,0x2c,0x65,0x2e,0x64,0x61,0x74,0x61,0x3d,0x76,0x6f,0x69,0x64,0x20,0x30,0x29, +0x7d,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x20,0x53,0x28,0x65,0x2c,0x6e,0x2c, +0x69,0x2c,0x72,0x29,0x7b,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x74,0x2e,0x69,0x73, +0x46,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x6e,0x29,0x26,0x26,0x28,0x72,0x3d, +0x69,0x2c,0x69,0x3d,0x6e,0x2c,0x6e,0x3d,0x76,0x6f,0x69,0x64,0x20,0x30,0x29,0x2c, +0x74,0x2e,0x69,0x73,0x46,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x69,0x29,0x7c, +0x7c,0x28,0x72,0x3d,0x69,0x2c,0x69,0x3d,0x76,0x6f,0x69,0x64,0x20,0x30,0x29,0x2c, +0x7b,0x75,0x72,0x6c,0x3a,0x65,0x2c,0x64,0x61,0x74,0x61,0x3a,0x6e,0x2c,0x73,0x75, +0x63,0x63,0x65,0x73,0x73,0x3a,0x69,0x2c,0x64,0x61,0x74,0x61,0x54,0x79,0x70,0x65, +0x3a,0x72,0x7d,0x7d,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x20,0x43,0x28,0x65, +0x2c,0x6e,0x2c,0x69,0x2c,0x72,0x29,0x7b,0x76,0x61,0x72,0x20,0x6f,0x2c,0x73,0x3d, +0x74,0x2e,0x69,0x73,0x41,0x72,0x72,0x61,0x79,0x28,0x6e,0x29,0x2c,0x61,0x3d,0x74, +0x2e,0x69,0x73,0x50,0x6c,0x61,0x69,0x6e,0x4f,0x62,0x6a,0x65,0x63,0x74,0x28,0x6e, +0x29,0x3b,0x74,0x2e,0x65,0x61,0x63,0x68,0x28,0x6e,0x2c,0x66,0x75,0x6e,0x63,0x74, +0x69,0x6f,0x6e,0x28,0x6e,0x2c,0x75,0x29,0x7b,0x6f,0x3d,0x74,0x2e,0x74,0x79,0x70, +0x65,0x28,0x75,0x29,0x2c,0x72,0x26,0x26,0x28,0x6e,0x3d,0x69,0x3f,0x72,0x3a,0x72, +0x2b,0x22,0x5b,0x22,0x2b,0x28,0x61,0x7c,0x7c,0x22,0x6f,0x62,0x6a,0x65,0x63,0x74, +0x22,0x3d,0x3d,0x6f,0x7c,0x7c,0x22,0x61,0x72,0x72,0x61,0x79,0x22,0x3d,0x3d,0x6f, +0x3f,0x6e,0x3a,0x22,0x22,0x29,0x2b,0x22,0x5d,0x22,0x29,0x2c,0x21,0x72,0x26,0x26, +0x73,0x3f,0x65,0x2e,0x61,0x64,0x64,0x28,0x75,0x2e,0x6e,0x61,0x6d,0x65,0x2c,0x75, +0x2e,0x76,0x61,0x6c,0x75,0x65,0x29,0x3a,0x22,0x61,0x72,0x72,0x61,0x79,0x22,0x3d, +0x3d,0x6f,0x7c,0x7c,0x21,0x69,0x26,0x26,0x22,0x6f,0x62,0x6a,0x65,0x63,0x74,0x22, +0x3d,0x3d,0x6f,0x3f,0x43,0x28,0x65,0x2c,0x75,0x2c,0x69,0x2c,0x6e,0x29,0x3a,0x65, +0x2e,0x61,0x64,0x64,0x28,0x6e,0x2c,0x75,0x29,0x7d,0x29,0x7d,0x76,0x61,0x72,0x20, +0x69,0x2c,0x72,0x2c,0x65,0x3d,0x30,0x2c,0x6e,0x3d,0x77,0x69,0x6e,0x64,0x6f,0x77, +0x2e,0x64,0x6f,0x63,0x75,0x6d,0x65,0x6e,0x74,0x2c,0x6f,0x3d,0x2f,0x3c,0x73,0x63, +0x72,0x69,0x70,0x74,0x5c,0x62,0x5b,0x5e,0x3c,0x5d,0x2a,0x28,0x3f,0x3a,0x28,0x3f, +0x21,0x3c,0x5c,0x2f,0x73,0x63,0x72,0x69,0x70,0x74,0x3e,0x29,0x3c,0x5b,0x5e,0x3c, +0x5d,0x2a,0x29,0x2a,0x3c,0x5c,0x2f,0x73,0x63,0x72,0x69,0x70,0x74,0x3e,0x2f,0x67, +0x69,0x2c,0x73,0x3d,0x2f,0x5e,0x28,0x3f,0x3a,0x74,0x65,0x78,0x74,0x7c,0x61,0x70, +0x70,0x6c,0x69,0x63,0x61,0x74,0x69,0x6f,0x6e,0x29,0x5c,0x2f,0x6a,0x61,0x76,0x61, +0x73,0x63,0x72,0x69,0x70,0x74,0x2f,0x69,0x2c,0x61,0x3d,0x2f,0x5e,0x28,0x3f,0x3a, +0x74,0x65,0x78,0x74,0x7c,0x61,0x70,0x70,0x6c,0x69,0x63,0x61,0x74,0x69,0x6f,0x6e, +0x29,0x5c,0x2f,0x78,0x6d,0x6c,0x2f,0x69,0x2c,0x75,0x3d,0x22,0x61,0x70,0x70,0x6c, +0x69,0x63,0x61,0x74,0x69,0x6f,0x6e,0x2f,0x6a,0x73,0x6f,0x6e,0x22,0x2c,0x66,0x3d, +0x22,0x74,0x65,0x78,0x74,0x2f,0x68,0x74,0x6d,0x6c,0x22,0x2c,0x63,0x3d,0x2f,0x5e, +0x5c,0x73,0x2a,0x24,0x2f,0x2c,0x6c,0x3d,0x6e,0x2e,0x63,0x72,0x65,0x61,0x74,0x65, +0x45,0x6c,0x65,0x6d,0x65,0x6e,0x74,0x28,0x22,0x61,0x22,0x29,0x3b,0x6c,0x2e,0x68, +0x72,0x65,0x66,0x3d,0x77,0x69,0x6e,0x64,0x6f,0x77,0x2e,0x6c,0x6f,0x63,0x61,0x74, +0x69,0x6f,0x6e,0x2e,0x68,0x72,0x65,0x66,0x2c,0x74,0x2e,0x61,0x63,0x74,0x69,0x76, +0x65,0x3d,0x30,0x2c,0x74,0x2e,0x61,0x6a,0x61,0x78,0x4a,0x53,0x4f,0x4e,0x50,0x3d, +0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x69,0x2c,0x72,0x29,0x7b,0x69,0x66, +0x28,0x21,0x28,0x22,0x74,0x79,0x70,0x65,0x22,0x69,0x6e,0x20,0x69,0x29,0x29,0x72, +0x65,0x74,0x75,0x72,0x6e,0x20,0x74,0x2e,0x61,0x6a,0x61,0x78,0x28,0x69,0x29,0x3b, +0x76,0x61,0x72,0x20,0x66,0x2c,0x68,0x2c,0x6f,0x3d,0x69,0x2e,0x6a,0x73,0x6f,0x6e, +0x70,0x43,0x61,0x6c,0x6c,0x62,0x61,0x63,0x6b,0x2c,0x73,0x3d,0x28,0x74,0x2e,0x69, +0x73,0x46,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x6f,0x29,0x3f,0x6f,0x28,0x29, +0x3a,0x6f,0x29,0x7c,0x7c,0x22,0x6a,0x73,0x6f,0x6e,0x70,0x22,0x2b,0x20,0x2b,0x2b, +0x65,0x2c,0x61,0x3d,0x6e,0x2e,0x63,0x72,0x65,0x61,0x74,0x65,0x45,0x6c,0x65,0x6d, +0x65,0x6e,0x74,0x28,0x22,0x73,0x63,0x72,0x69,0x70,0x74,0x22,0x29,0x2c,0x75,0x3d, +0x77,0x69,0x6e,0x64,0x6f,0x77,0x5b,0x73,0x5d,0x2c,0x63,0x3d,0x66,0x75,0x6e,0x63, +0x74,0x69,0x6f,0x6e,0x28,0x65,0x29,0x7b,0x74,0x28,0x61,0x29,0x2e,0x74,0x72,0x69, +0x67,0x67,0x65,0x72,0x48,0x61,0x6e,0x64,0x6c,0x65,0x72,0x28,0x22,0x65,0x72,0x72, +0x6f,0x72,0x22,0x2c,0x65,0x7c,0x7c,0x22,0x61,0x62,0x6f,0x72,0x74,0x22,0x29,0x7d, +0x2c,0x6c,0x3d,0x7b,0x61,0x62,0x6f,0x72,0x74,0x3a,0x63,0x7d,0x3b,0x72,0x65,0x74, +0x75,0x72,0x6e,0x20,0x72,0x26,0x26,0x72,0x2e,0x70,0x72,0x6f,0x6d,0x69,0x73,0x65, +0x28,0x6c,0x29,0x2c,0x74,0x28,0x61,0x29,0x2e,0x6f,0x6e,0x28,0x22,0x6c,0x6f,0x61, +0x64,0x20,0x65,0x72,0x72,0x6f,0x72,0x22,0x2c,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f, +0x6e,0x28,0x65,0x2c,0x6e,0x29,0x7b,0x63,0x6c,0x65,0x61,0x72,0x54,0x69,0x6d,0x65, +0x6f,0x75,0x74,0x28,0x68,0x29,0x2c,0x74,0x28,0x61,0x29,0x2e,0x6f,0x66,0x66,0x28, +0x29,0x2e,0x72,0x65,0x6d,0x6f,0x76,0x65,0x28,0x29,0x2c,0x22,0x65,0x72,0x72,0x6f, +0x72,0x22,0x21,0x3d,0x65,0x2e,0x74,0x79,0x70,0x65,0x26,0x26,0x66,0x3f,0x76,0x28, +0x66,0x5b,0x30,0x5d,0x2c,0x6c,0x2c,0x69,0x2c,0x72,0x29,0x3a,0x79,0x28,0x6e,0x75, +0x6c,0x6c,0x2c,0x6e,0x7c,0x7c,0x22,0x65,0x72,0x72,0x6f,0x72,0x22,0x2c,0x6c,0x2c, +0x69,0x2c,0x72,0x29,0x2c,0x77,0x69,0x6e,0x64,0x6f,0x77,0x5b,0x73,0x5d,0x3d,0x75, +0x2c,0x66,0x26,0x26,0x74,0x2e,0x69,0x73,0x46,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e, +0x28,0x75,0x29,0x26,0x26,0x75,0x28,0x66,0x5b,0x30,0x5d,0x29,0x2c,0x75,0x3d,0x66, +0x3d,0x76,0x6f,0x69,0x64,0x20,0x30,0x7d,0x29,0x2c,0x67,0x28,0x6c,0x2c,0x69,0x29, +0x3d,0x3d,0x3d,0x21,0x31,0x3f,0x28,0x63,0x28,0x22,0x61,0x62,0x6f,0x72,0x74,0x22, +0x29,0x2c,0x6c,0x29,0x3a,0x28,0x77,0x69,0x6e,0x64,0x6f,0x77,0x5b,0x73,0x5d,0x3d, +0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x29,0x7b,0x66,0x3d,0x61,0x72,0x67, +0x75,0x6d,0x65,0x6e,0x74,0x73,0x7d,0x2c,0x61,0x2e,0x73,0x72,0x63,0x3d,0x69,0x2e, +0x75,0x72,0x6c,0x2e,0x72,0x65,0x70,0x6c,0x61,0x63,0x65,0x28,0x2f,0x5c,0x3f,0x28, +0x2e,0x2b,0x29,0x3d,0x5c,0x3f,0x2f,0x2c,0x22,0x3f,0x24,0x31,0x3d,0x22,0x2b,0x73, +0x29,0x2c,0x6e,0x2e,0x68,0x65,0x61,0x64,0x2e,0x61,0x70,0x70,0x65,0x6e,0x64,0x43, +0x68,0x69,0x6c,0x64,0x28,0x61,0x29,0x2c,0x69,0x2e,0x74,0x69,0x6d,0x65,0x6f,0x75, +0x74,0x3e,0x30,0x26,0x26,0x28,0x68,0x3d,0x73,0x65,0x74,0x54,0x69,0x6d,0x65,0x6f, +0x75,0x74,0x28,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x29,0x7b,0x63,0x28, +0x22,0x74,0x69,0x6d,0x65,0x6f,0x75,0x74,0x22,0x29,0x7d,0x2c,0x69,0x2e,0x74,0x69, +0x6d,0x65,0x6f,0x75,0x74,0x29,0x29,0x2c,0x6c,0x29,0x7d,0x2c,0x74,0x2e,0x61,0x6a, +0x61,0x78,0x53,0x65,0x74,0x74,0x69,0x6e,0x67,0x73,0x3d,0x7b,0x74,0x79,0x70,0x65, +0x3a,0x22,0x47,0x45,0x54,0x22,0x2c,0x62,0x65,0x66,0x6f,0x72,0x65,0x53,0x65,0x6e, +0x64,0x3a,0x62,0x2c,0x73,0x75,0x63,0x63,0x65,0x73,0x73,0x3a,0x62,0x2c,0x65,0x72, +0x72,0x6f,0x72,0x3a,0x62,0x2c,0x63,0x6f,0x6d,0x70,0x6c,0x65,0x74,0x65,0x3a,0x62, +0x2c,0x63,0x6f,0x6e,0x74,0x65,0x78,0x74,0x3a,0x6e,0x75,0x6c,0x6c,0x2c,0x67,0x6c, +0x6f,0x62,0x61,0x6c,0x3a,0x21,0x30,0x2c,0x78,0x68,0x72,0x3a,0x66,0x75,0x6e,0x63, +0x74,0x69,0x6f,0x6e,0x28,0x29,0x7b,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x6e,0x65, +0x77,0x20,0x77,0x69,0x6e,0x64,0x6f,0x77,0x2e,0x58,0x4d,0x4c,0x48,0x74,0x74,0x70, +0x52,0x65,0x71,0x75,0x65,0x73,0x74,0x7d,0x2c,0x61,0x63,0x63,0x65,0x70,0x74,0x73, +0x3a,0x7b,0x73,0x63,0x72,0x69,0x70,0x74,0x3a,0x22,0x74,0x65,0x78,0x74,0x2f,0x6a, +0x61,0x76,0x61,0x73,0x63,0x72,0x69,0x70,0x74,0x2c,0x20,0x61,0x70,0x70,0x6c,0x69, +0x63,0x61,0x74,0x69,0x6f,0x6e,0x2f,0x6a,0x61,0x76,0x61,0x73,0x63,0x72,0x69,0x70, +0x74,0x2c,0x20,0x61,0x70,0x70,0x6c,0x69,0x63,0x61,0x74,0x69,0x6f,0x6e,0x2f,0x78, +0x2d,0x6a,0x61,0x76,0x61,0x73,0x63,0x72,0x69,0x70,0x74,0x22,0x2c,0x6a,0x73,0x6f, +0x6e,0x3a,0x75,0x2c,0x78,0x6d,0x6c,0x3a,0x22,0x61,0x70,0x70,0x6c,0x69,0x63,0x61, +0x74,0x69,0x6f,0x6e,0x2f,0x78,0x6d,0x6c,0x2c,0x20,0x74,0x65,0x78,0x74,0x2f,0x78, +0x6d,0x6c,0x22,0x2c,0x68,0x74,0x6d,0x6c,0x3a,0x66,0x2c,0x74,0x65,0x78,0x74,0x3a, +0x22,0x74,0x65,0x78,0x74,0x2f,0x70,0x6c,0x61,0x69,0x6e,0x22,0x7d,0x2c,0x63,0x72, +0x6f,0x73,0x73,0x44,0x6f,0x6d,0x61,0x69,0x6e,0x3a,0x21,0x31,0x2c,0x74,0x69,0x6d, +0x65,0x6f,0x75,0x74,0x3a,0x30,0x2c,0x70,0x72,0x6f,0x63,0x65,0x73,0x73,0x44,0x61, +0x74,0x61,0x3a,0x21,0x30,0x2c,0x63,0x61,0x63,0x68,0x65,0x3a,0x21,0x30,0x7d,0x2c, +0x74,0x2e,0x61,0x6a,0x61,0x78,0x3d,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28, +0x65,0x29,0x7b,0x76,0x61,0x72,0x20,0x61,0x2c,0x6f,0x3d,0x74,0x2e,0x65,0x78,0x74, +0x65,0x6e,0x64,0x28,0x7b,0x7d,0x2c,0x65,0x7c,0x7c,0x7b,0x7d,0x29,0x2c,0x73,0x3d, +0x74,0x2e,0x44,0x65,0x66,0x65,0x72,0x72,0x65,0x64,0x26,0x26,0x74,0x2e,0x44,0x65, +0x66,0x65,0x72,0x72,0x65,0x64,0x28,0x29,0x3b,0x66,0x6f,0x72,0x28,0x69,0x20,0x69, +0x6e,0x20,0x74,0x2e,0x61,0x6a,0x61,0x78,0x53,0x65,0x74,0x74,0x69,0x6e,0x67,0x73, +0x29,0x76,0x6f,0x69,0x64,0x20,0x30,0x3d,0x3d,0x3d,0x6f,0x5b,0x69,0x5d,0x26,0x26, +0x28,0x6f,0x5b,0x69,0x5d,0x3d,0x74,0x2e,0x61,0x6a,0x61,0x78,0x53,0x65,0x74,0x74, +0x69,0x6e,0x67,0x73,0x5b,0x69,0x5d,0x29,0x3b,0x64,0x28,0x6f,0x29,0x2c,0x6f,0x2e, +0x63,0x72,0x6f,0x73,0x73,0x44,0x6f,0x6d,0x61,0x69,0x6e,0x7c,0x7c,0x28,0x61,0x3d, +0x6e,0x2e,0x63,0x72,0x65,0x61,0x74,0x65,0x45,0x6c,0x65,0x6d,0x65,0x6e,0x74,0x28, +0x22,0x61,0x22,0x29,0x2c,0x61,0x2e,0x68,0x72,0x65,0x66,0x3d,0x6f,0x2e,0x75,0x72, +0x6c,0x2c,0x61,0x2e,0x68,0x72,0x65,0x66,0x3d,0x61,0x2e,0x68,0x72,0x65,0x66,0x2c, +0x6f,0x2e,0x63,0x72,0x6f,0x73,0x73,0x44,0x6f,0x6d,0x61,0x69,0x6e,0x3d,0x6c,0x2e, +0x70,0x72,0x6f,0x74,0x6f,0x63,0x6f,0x6c,0x2b,0x22,0x2f,0x2f,0x22,0x2b,0x6c,0x2e, +0x68,0x6f,0x73,0x74,0x21,0x3d,0x61,0x2e,0x70,0x72,0x6f,0x74,0x6f,0x63,0x6f,0x6c, +0x2b,0x22,0x2f,0x2f,0x22,0x2b,0x61,0x2e,0x68,0x6f,0x73,0x74,0x29,0x2c,0x6f,0x2e, +0x75,0x72,0x6c,0x7c,0x7c,0x28,0x6f,0x2e,0x75,0x72,0x6c,0x3d,0x77,0x69,0x6e,0x64, +0x6f,0x77,0x2e,0x6c,0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e,0x2e,0x74,0x6f,0x53,0x74, +0x72,0x69,0x6e,0x67,0x28,0x29,0x29,0x2c,0x6a,0x28,0x6f,0x29,0x3b,0x76,0x61,0x72, +0x20,0x75,0x3d,0x6f,0x2e,0x64,0x61,0x74,0x61,0x54,0x79,0x70,0x65,0x2c,0x66,0x3d, +0x2f,0x5c,0x3f,0x2e,0x2b,0x3d,0x5c,0x3f,0x2f,0x2e,0x74,0x65,0x73,0x74,0x28,0x6f, +0x2e,0x75,0x72,0x6c,0x29,0x3b,0x69,0x66,0x28,0x66,0x26,0x26,0x28,0x75,0x3d,0x22, +0x6a,0x73,0x6f,0x6e,0x70,0x22,0x29,0x2c,0x6f,0x2e,0x63,0x61,0x63,0x68,0x65,0x21, +0x3d,0x3d,0x21,0x31,0x26,0x26,0x28,0x65,0x26,0x26,0x65,0x2e,0x63,0x61,0x63,0x68, +0x65,0x3d,0x3d,0x3d,0x21,0x30,0x7c,0x7c,0x22,0x73,0x63,0x72,0x69,0x70,0x74,0x22, +0x21,0x3d,0x75,0x26,0x26,0x22,0x6a,0x73,0x6f,0x6e,0x70,0x22,0x21,0x3d,0x75,0x29, +0x7c,0x7c,0x28,0x6f,0x2e,0x75,0x72,0x6c,0x3d,0x45,0x28,0x6f,0x2e,0x75,0x72,0x6c, +0x2c,0x22,0x5f,0x3d,0x22,0x2b,0x44,0x61,0x74,0x65,0x2e,0x6e,0x6f,0x77,0x28,0x29, +0x29,0x29,0x2c,0x22,0x6a,0x73,0x6f,0x6e,0x70,0x22,0x3d,0x3d,0x75,0x29,0x72,0x65, +0x74,0x75,0x72,0x6e,0x20,0x66,0x7c,0x7c,0x28,0x6f,0x2e,0x75,0x72,0x6c,0x3d,0x45, +0x28,0x6f,0x2e,0x75,0x72,0x6c,0x2c,0x6f,0x2e,0x6a,0x73,0x6f,0x6e,0x70,0x3f,0x6f, +0x2e,0x6a,0x73,0x6f,0x6e,0x70,0x2b,0x22,0x3d,0x3f,0x22,0x3a,0x6f,0x2e,0x6a,0x73, +0x6f,0x6e,0x70,0x3d,0x3d,0x3d,0x21,0x31,0x3f,0x22,0x22,0x3a,0x22,0x63,0x61,0x6c, +0x6c,0x62,0x61,0x63,0x6b,0x3d,0x3f,0x22,0x29,0x29,0x2c,0x74,0x2e,0x61,0x6a,0x61, +0x78,0x4a,0x53,0x4f,0x4e,0x50,0x28,0x6f,0x2c,0x73,0x29,0x3b,0x76,0x61,0x72,0x20, +0x43,0x2c,0x68,0x3d,0x6f,0x2e,0x61,0x63,0x63,0x65,0x70,0x74,0x73,0x5b,0x75,0x5d, +0x2c,0x70,0x3d,0x7b,0x7d,0x2c,0x6d,0x3d,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e, +0x28,0x74,0x2c,0x65,0x29,0x7b,0x70,0x5b,0x74,0x2e,0x74,0x6f,0x4c,0x6f,0x77,0x65, +0x72,0x43,0x61,0x73,0x65,0x28,0x29,0x5d,0x3d,0x5b,0x74,0x2c,0x65,0x5d,0x7d,0x2c, +0x78,0x3d,0x2f,0x5e,0x28,0x5b,0x5c,0x77,0x2d,0x5d,0x2b,0x3a,0x29,0x5c,0x2f,0x5c, +0x2f,0x2f,0x2e,0x74,0x65,0x73,0x74,0x28,0x6f,0x2e,0x75,0x72,0x6c,0x29,0x3f,0x52, +0x65,0x67,0x45,0x78,0x70,0x2e,0x24,0x31,0x3a,0x77,0x69,0x6e,0x64,0x6f,0x77,0x2e, +0x6c,0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e,0x2e,0x70,0x72,0x6f,0x74,0x6f,0x63,0x6f, +0x6c,0x2c,0x53,0x3d,0x6f,0x2e,0x78,0x68,0x72,0x28,0x29,0x2c,0x54,0x3d,0x53,0x2e, +0x73,0x65,0x74,0x52,0x65,0x71,0x75,0x65,0x73,0x74,0x48,0x65,0x61,0x64,0x65,0x72, +0x3b,0x69,0x66,0x28,0x73,0x26,0x26,0x73,0x2e,0x70,0x72,0x6f,0x6d,0x69,0x73,0x65, +0x28,0x53,0x29,0x2c,0x6f,0x2e,0x63,0x72,0x6f,0x73,0x73,0x44,0x6f,0x6d,0x61,0x69, +0x6e,0x7c,0x7c,0x6d,0x28,0x22,0x58,0x2d,0x52,0x65,0x71,0x75,0x65,0x73,0x74,0x65, +0x64,0x2d,0x57,0x69,0x74,0x68,0x22,0x2c,0x22,0x58,0x4d,0x4c,0x48,0x74,0x74,0x70, +0x52,0x65,0x71,0x75,0x65,0x73,0x74,0x22,0x29,0x2c,0x6d,0x28,0x22,0x41,0x63,0x63, +0x65,0x70,0x74,0x22,0x2c,0x68,0x7c,0x7c,0x22,0x2a,0x2f,0x2a,0x22,0x29,0x2c,0x28, +0x68,0x3d,0x6f,0x2e,0x6d,0x69,0x6d,0x65,0x54,0x79,0x70,0x65,0x7c,0x7c,0x68,0x29, +0x26,0x26,0x28,0x68,0x2e,0x69,0x6e,0x64,0x65,0x78,0x4f,0x66,0x28,0x22,0x2c,0x22, +0x29,0x3e,0x2d,0x31,0x26,0x26,0x28,0x68,0x3d,0x68,0x2e,0x73,0x70,0x6c,0x69,0x74, +0x28,0x22,0x2c,0x22,0x2c,0x32,0x29,0x5b,0x30,0x5d,0x29,0x2c,0x53,0x2e,0x6f,0x76, +0x65,0x72,0x72,0x69,0x64,0x65,0x4d,0x69,0x6d,0x65,0x54,0x79,0x70,0x65,0x26,0x26, +0x53,0x2e,0x6f,0x76,0x65,0x72,0x72,0x69,0x64,0x65,0x4d,0x69,0x6d,0x65,0x54,0x79, +0x70,0x65,0x28,0x68,0x29,0x29,0x2c,0x28,0x6f,0x2e,0x63,0x6f,0x6e,0x74,0x65,0x6e, +0x74,0x54,0x79,0x70,0x65,0x7c,0x7c,0x6f,0x2e,0x63,0x6f,0x6e,0x74,0x65,0x6e,0x74, +0x54,0x79,0x70,0x65,0x21,0x3d,0x3d,0x21,0x31,0x26,0x26,0x6f,0x2e,0x64,0x61,0x74, +0x61,0x26,0x26,0x22,0x47,0x45,0x54,0x22,0x21,0x3d,0x6f,0x2e,0x74,0x79,0x70,0x65, +0x2e,0x74,0x6f,0x55,0x70,0x70,0x65,0x72,0x43,0x61,0x73,0x65,0x28,0x29,0x29,0x26, +0x26,0x6d,0x28,0x22,0x43,0x6f,0x6e,0x74,0x65,0x6e,0x74,0x2d,0x54,0x79,0x70,0x65, +0x22,0x2c,0x6f,0x2e,0x63,0x6f,0x6e,0x74,0x65,0x6e,0x74,0x54,0x79,0x70,0x65,0x7c, +0x7c,0x22,0x61,0x70,0x70,0x6c,0x69,0x63,0x61,0x74,0x69,0x6f,0x6e,0x2f,0x78,0x2d, +0x77,0x77,0x77,0x2d,0x66,0x6f,0x72,0x6d,0x2d,0x75,0x72,0x6c,0x65,0x6e,0x63,0x6f, +0x64,0x65,0x64,0x22,0x29,0x2c,0x6f,0x2e,0x68,0x65,0x61,0x64,0x65,0x72,0x73,0x29, +0x66,0x6f,0x72,0x28,0x72,0x20,0x69,0x6e,0x20,0x6f,0x2e,0x68,0x65,0x61,0x64,0x65, +0x72,0x73,0x29,0x6d,0x28,0x72,0x2c,0x6f,0x2e,0x68,0x65,0x61,0x64,0x65,0x72,0x73, +0x5b,0x72,0x5d,0x29,0x3b,0x69,0x66,0x28,0x53,0x2e,0x73,0x65,0x74,0x52,0x65,0x71, +0x75,0x65,0x73,0x74,0x48,0x65,0x61,0x64,0x65,0x72,0x3d,0x6d,0x2c,0x53,0x2e,0x6f, +0x6e,0x72,0x65,0x61,0x64,0x79,0x73,0x74,0x61,0x74,0x65,0x63,0x68,0x61,0x6e,0x67, +0x65,0x3d,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x29,0x7b,0x69,0x66,0x28, +0x34,0x3d,0x3d,0x53,0x2e,0x72,0x65,0x61,0x64,0x79,0x53,0x74,0x61,0x74,0x65,0x29, +0x7b,0x53,0x2e,0x6f,0x6e,0x72,0x65,0x61,0x64,0x79,0x73,0x74,0x61,0x74,0x65,0x63, +0x68,0x61,0x6e,0x67,0x65,0x3d,0x62,0x2c,0x63,0x6c,0x65,0x61,0x72,0x54,0x69,0x6d, +0x65,0x6f,0x75,0x74,0x28,0x43,0x29,0x3b,0x76,0x61,0x72,0x20,0x65,0x2c,0x6e,0x3d, +0x21,0x31,0x3b,0x69,0x66,0x28,0x53,0x2e,0x73,0x74,0x61,0x74,0x75,0x73,0x3e,0x3d, +0x32,0x30,0x30,0x26,0x26,0x53,0x2e,0x73,0x74,0x61,0x74,0x75,0x73,0x3c,0x33,0x30, +0x30,0x7c,0x7c,0x33,0x30,0x34,0x3d,0x3d,0x53,0x2e,0x73,0x74,0x61,0x74,0x75,0x73, +0x7c,0x7c,0x30,0x3d,0x3d,0x53,0x2e,0x73,0x74,0x61,0x74,0x75,0x73,0x26,0x26,0x22, +0x66,0x69,0x6c,0x65,0x3a,0x22,0x3d,0x3d,0x78,0x29,0x7b,0x75,0x3d,0x75,0x7c,0x7c, +0x77,0x28,0x6f,0x2e,0x6d,0x69,0x6d,0x65,0x54,0x79,0x70,0x65,0x7c,0x7c,0x53,0x2e, +0x67,0x65,0x74,0x52,0x65,0x73,0x70,0x6f,0x6e,0x73,0x65,0x48,0x65,0x61,0x64,0x65, +0x72,0x28,0x22,0x63,0x6f,0x6e,0x74,0x65,0x6e,0x74,0x2d,0x74,0x79,0x70,0x65,0x22, +0x29,0x29,0x2c,0x65,0x3d,0x53,0x2e,0x72,0x65,0x73,0x70,0x6f,0x6e,0x73,0x65,0x54, +0x65,0x78,0x74,0x3b,0x74,0x72,0x79,0x7b,0x22,0x73,0x63,0x72,0x69,0x70,0x74,0x22, +0x3d,0x3d,0x75,0x3f,0x28,0x31,0x2c,0x65,0x76,0x61,0x6c,0x29,0x28,0x65,0x29,0x3a, +0x22,0x78,0x6d,0x6c,0x22,0x3d,0x3d,0x75,0x3f,0x65,0x3d,0x53,0x2e,0x72,0x65,0x73, +0x70,0x6f,0x6e,0x73,0x65,0x58,0x4d,0x4c,0x3a,0x22,0x6a,0x73,0x6f,0x6e,0x22,0x3d, +0x3d,0x75,0x26,0x26,0x28,0x65,0x3d,0x63,0x2e,0x74,0x65,0x73,0x74,0x28,0x65,0x29, +0x3f,0x6e,0x75,0x6c,0x6c,0x3a,0x74,0x2e,0x70,0x61,0x72,0x73,0x65,0x4a,0x53,0x4f, +0x4e,0x28,0x65,0x29,0x29,0x7d,0x63,0x61,0x74,0x63,0x68,0x28,0x69,0x29,0x7b,0x6e, +0x3d,0x69,0x7d,0x6e,0x3f,0x79,0x28,0x6e,0x2c,0x22,0x70,0x61,0x72,0x73,0x65,0x72, +0x65,0x72,0x72,0x6f,0x72,0x22,0x2c,0x53,0x2c,0x6f,0x2c,0x73,0x29,0x3a,0x76,0x28, +0x65,0x2c,0x53,0x2c,0x6f,0x2c,0x73,0x29,0x7d,0x65,0x6c,0x73,0x65,0x20,0x79,0x28, +0x53,0x2e,0x73,0x74,0x61,0x74,0x75,0x73,0x54,0x65,0x78,0x74,0x7c,0x7c,0x6e,0x75, +0x6c,0x6c,0x2c,0x53,0x2e,0x73,0x74,0x61,0x74,0x75,0x73,0x3f,0x22,0x65,0x72,0x72, +0x6f,0x72,0x22,0x3a,0x22,0x61,0x62,0x6f,0x72,0x74,0x22,0x2c,0x53,0x2c,0x6f,0x2c, +0x73,0x29,0x7d,0x7d,0x2c,0x67,0x28,0x53,0x2c,0x6f,0x29,0x3d,0x3d,0x3d,0x21,0x31, +0x29,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x53,0x2e,0x61,0x62,0x6f,0x72,0x74,0x28, +0x29,0x2c,0x79,0x28,0x6e,0x75,0x6c,0x6c,0x2c,0x22,0x61,0x62,0x6f,0x72,0x74,0x22, +0x2c,0x53,0x2c,0x6f,0x2c,0x73,0x29,0x2c,0x53,0x3b,0x69,0x66,0x28,0x6f,0x2e,0x78, +0x68,0x72,0x46,0x69,0x65,0x6c,0x64,0x73,0x29,0x66,0x6f,0x72,0x28,0x72,0x20,0x69, +0x6e,0x20,0x6f,0x2e,0x78,0x68,0x72,0x46,0x69,0x65,0x6c,0x64,0x73,0x29,0x53,0x5b, +0x72,0x5d,0x3d,0x6f,0x2e,0x78,0x68,0x72,0x46,0x69,0x65,0x6c,0x64,0x73,0x5b,0x72, +0x5d,0x3b,0x76,0x61,0x72,0x20,0x4e,0x3d,0x22,0x61,0x73,0x79,0x6e,0x63,0x22,0x69, +0x6e,0x20,0x6f,0x3f,0x6f,0x2e,0x61,0x73,0x79,0x6e,0x63,0x3a,0x21,0x30,0x3b,0x53, +0x2e,0x6f,0x70,0x65,0x6e,0x28,0x6f,0x2e,0x74,0x79,0x70,0x65,0x2c,0x6f,0x2e,0x75, +0x72,0x6c,0x2c,0x4e,0x2c,0x6f,0x2e,0x75,0x73,0x65,0x72,0x6e,0x61,0x6d,0x65,0x2c, +0x6f,0x2e,0x70,0x61,0x73,0x73,0x77,0x6f,0x72,0x64,0x29,0x3b,0x66,0x6f,0x72,0x28, +0x72,0x20,0x69,0x6e,0x20,0x70,0x29,0x54,0x2e,0x61,0x70,0x70,0x6c,0x79,0x28,0x53, +0x2c,0x70,0x5b,0x72,0x5d,0x29,0x3b,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x6f,0x2e, +0x74,0x69,0x6d,0x65,0x6f,0x75,0x74,0x3e,0x30,0x26,0x26,0x28,0x43,0x3d,0x73,0x65, +0x74,0x54,0x69,0x6d,0x65,0x6f,0x75,0x74,0x28,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f, +0x6e,0x28,0x29,0x7b,0x53,0x2e,0x6f,0x6e,0x72,0x65,0x61,0x64,0x79,0x73,0x74,0x61, +0x74,0x65,0x63,0x68,0x61,0x6e,0x67,0x65,0x3d,0x62,0x2c,0x53,0x2e,0x61,0x62,0x6f, +0x72,0x74,0x28,0x29,0x2c,0x79,0x28,0x6e,0x75,0x6c,0x6c,0x2c,0x22,0x74,0x69,0x6d, +0x65,0x6f,0x75,0x74,0x22,0x2c,0x53,0x2c,0x6f,0x2c,0x73,0x29,0x7d,0x2c,0x6f,0x2e, +0x74,0x69,0x6d,0x65,0x6f,0x75,0x74,0x29,0x29,0x2c,0x53,0x2e,0x73,0x65,0x6e,0x64, +0x28,0x6f,0x2e,0x64,0x61,0x74,0x61,0x3f,0x6f,0x2e,0x64,0x61,0x74,0x61,0x3a,0x6e, +0x75,0x6c,0x6c,0x29,0x2c,0x53,0x7d,0x2c,0x74,0x2e,0x67,0x65,0x74,0x3d,0x66,0x75, +0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x29,0x7b,0x72,0x65,0x74,0x75,0x72,0x6e,0x20, +0x74,0x2e,0x61,0x6a,0x61,0x78,0x28,0x53,0x2e,0x61,0x70,0x70,0x6c,0x79,0x28,0x6e, +0x75,0x6c,0x6c,0x2c,0x61,0x72,0x67,0x75,0x6d,0x65,0x6e,0x74,0x73,0x29,0x29,0x7d, +0x2c,0x74,0x2e,0x70,0x6f,0x73,0x74,0x3d,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e, +0x28,0x29,0x7b,0x76,0x61,0x72,0x20,0x65,0x3d,0x53,0x2e,0x61,0x70,0x70,0x6c,0x79, +0x28,0x6e,0x75,0x6c,0x6c,0x2c,0x61,0x72,0x67,0x75,0x6d,0x65,0x6e,0x74,0x73,0x29, +0x3b,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x65,0x2e,0x74,0x79,0x70,0x65,0x3d,0x22, +0x50,0x4f,0x53,0x54,0x22,0x2c,0x74,0x2e,0x61,0x6a,0x61,0x78,0x28,0x65,0x29,0x7d, +0x2c,0x74,0x2e,0x67,0x65,0x74,0x4a,0x53,0x4f,0x4e,0x3d,0x66,0x75,0x6e,0x63,0x74, +0x69,0x6f,0x6e,0x28,0x29,0x7b,0x76,0x61,0x72,0x20,0x65,0x3d,0x53,0x2e,0x61,0x70, +0x70,0x6c,0x79,0x28,0x6e,0x75,0x6c,0x6c,0x2c,0x61,0x72,0x67,0x75,0x6d,0x65,0x6e, +0x74,0x73,0x29,0x3b,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x65,0x2e,0x64,0x61,0x74, +0x61,0x54,0x79,0x70,0x65,0x3d,0x22,0x6a,0x73,0x6f,0x6e,0x22,0x2c,0x74,0x2e,0x61, +0x6a,0x61,0x78,0x28,0x65,0x29,0x7d,0x2c,0x74,0x2e,0x66,0x6e,0x2e,0x6c,0x6f,0x61, +0x64,0x3d,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x65,0x2c,0x6e,0x2c,0x69, +0x29,0x7b,0x69,0x66,0x28,0x21,0x74,0x68,0x69,0x73,0x2e,0x6c,0x65,0x6e,0x67,0x74, +0x68,0x29,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x74,0x68,0x69,0x73,0x3b,0x76,0x61, +0x72,0x20,0x61,0x2c,0x72,0x3d,0x74,0x68,0x69,0x73,0x2c,0x73,0x3d,0x65,0x2e,0x73, +0x70,0x6c,0x69,0x74,0x28,0x2f,0x5c,0x73,0x2f,0x29,0x2c,0x75,0x3d,0x53,0x28,0x65, +0x2c,0x6e,0x2c,0x69,0x29,0x2c,0x66,0x3d,0x75,0x2e,0x73,0x75,0x63,0x63,0x65,0x73, +0x73,0x3b,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x73,0x2e,0x6c,0x65,0x6e,0x67,0x74, +0x68,0x3e,0x31,0x26,0x26,0x28,0x75,0x2e,0x75,0x72,0x6c,0x3d,0x73,0x5b,0x30,0x5d, +0x2c,0x61,0x3d,0x73,0x5b,0x31,0x5d,0x29,0x2c,0x75,0x2e,0x73,0x75,0x63,0x63,0x65, +0x73,0x73,0x3d,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x65,0x29,0x7b,0x72, +0x2e,0x68,0x74,0x6d,0x6c,0x28,0x61,0x3f,0x74,0x28,0x22,0x3c,0x64,0x69,0x76,0x3e, +0x22,0x29,0x2e,0x68,0x74,0x6d,0x6c,0x28,0x65,0x2e,0x72,0x65,0x70,0x6c,0x61,0x63, +0x65,0x28,0x6f,0x2c,0x22,0x22,0x29,0x29,0x2e,0x66,0x69,0x6e,0x64,0x28,0x61,0x29, +0x3a,0x65,0x29,0x2c,0x66,0x26,0x26,0x66,0x2e,0x61,0x70,0x70,0x6c,0x79,0x28,0x72, +0x2c,0x61,0x72,0x67,0x75,0x6d,0x65,0x6e,0x74,0x73,0x29,0x7d,0x2c,0x74,0x2e,0x61, +0x6a,0x61,0x78,0x28,0x75,0x29,0x2c,0x74,0x68,0x69,0x73,0x7d,0x3b,0x76,0x61,0x72, +0x20,0x54,0x3d,0x65,0x6e,0x63,0x6f,0x64,0x65,0x55,0x52,0x49,0x43,0x6f,0x6d,0x70, +0x6f,0x6e,0x65,0x6e,0x74,0x3b,0x74,0x2e,0x70,0x61,0x72,0x61,0x6d,0x3d,0x66,0x75, +0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x65,0x2c,0x6e,0x29,0x7b,0x76,0x61,0x72,0x20, +0x69,0x3d,0x5b,0x5d,0x3b,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x69,0x2e,0x61,0x64, +0x64,0x3d,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x65,0x2c,0x6e,0x29,0x7b, +0x74,0x2e,0x69,0x73,0x46,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x6e,0x29,0x26, +0x26,0x28,0x6e,0x3d,0x6e,0x28,0x29,0x29,0x2c,0x6e,0x75,0x6c,0x6c,0x3d,0x3d,0x6e, +0x26,0x26,0x28,0x6e,0x3d,0x22,0x22,0x29,0x2c,0x74,0x68,0x69,0x73,0x2e,0x70,0x75, +0x73,0x68,0x28,0x54,0x28,0x65,0x29,0x2b,0x22,0x3d,0x22,0x2b,0x54,0x28,0x6e,0x29, +0x29,0x7d,0x2c,0x43,0x28,0x69,0x2c,0x65,0x2c,0x6e,0x29,0x2c,0x69,0x2e,0x6a,0x6f, +0x69,0x6e,0x28,0x22,0x26,0x22,0x29,0x2e,0x72,0x65,0x70,0x6c,0x61,0x63,0x65,0x28, +0x2f,0x25,0x32,0x30,0x2f,0x67,0x2c,0x22,0x2b,0x22,0x29,0x7d,0x7d,0x28,0x5a,0x65, +0x70,0x74,0x6f,0x29,0x2c,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x74,0x29, +0x7b,0x74,0x2e,0x66,0x6e,0x2e,0x73,0x65,0x72,0x69,0x61,0x6c,0x69,0x7a,0x65,0x41, +0x72,0x72,0x61,0x79,0x3d,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x29,0x7b, +0x76,0x61,0x72,0x20,0x65,0x2c,0x6e,0x2c,0x69,0x3d,0x5b,0x5d,0x2c,0x72,0x3d,0x66, +0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x74,0x29,0x7b,0x72,0x65,0x74,0x75,0x72, +0x6e,0x20,0x74,0x2e,0x66,0x6f,0x72,0x45,0x61,0x63,0x68,0x3f,0x74,0x2e,0x66,0x6f, +0x72,0x45,0x61,0x63,0x68,0x28,0x72,0x29,0x3a,0x76,0x6f,0x69,0x64,0x20,0x69,0x2e, +0x70,0x75,0x73,0x68,0x28,0x7b,0x6e,0x61,0x6d,0x65,0x3a,0x65,0x2c,0x76,0x61,0x6c, +0x75,0x65,0x3a,0x74,0x7d,0x29,0x7d,0x3b,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x74, +0x68,0x69,0x73,0x5b,0x30,0x5d,0x26,0x26,0x74,0x2e,0x65,0x61,0x63,0x68,0x28,0x74, +0x68,0x69,0x73,0x5b,0x30,0x5d,0x2e,0x65,0x6c,0x65,0x6d,0x65,0x6e,0x74,0x73,0x2c, +0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x69,0x2c,0x6f,0x29,0x7b,0x6e,0x3d, +0x6f,0x2e,0x74,0x79,0x70,0x65,0x2c,0x65,0x3d,0x6f,0x2e,0x6e,0x61,0x6d,0x65,0x2c, +0x65,0x26,0x26,0x22,0x66,0x69,0x65,0x6c,0x64,0x73,0x65,0x74,0x22,0x21,0x3d,0x6f, +0x2e,0x6e,0x6f,0x64,0x65,0x4e,0x61,0x6d,0x65,0x2e,0x74,0x6f,0x4c,0x6f,0x77,0x65, +0x72,0x43,0x61,0x73,0x65,0x28,0x29,0x26,0x26,0x21,0x6f,0x2e,0x64,0x69,0x73,0x61, +0x62,0x6c,0x65,0x64,0x26,0x26,0x22,0x73,0x75,0x62,0x6d,0x69,0x74,0x22,0x21,0x3d, +0x6e,0x26,0x26,0x22,0x72,0x65,0x73,0x65,0x74,0x22,0x21,0x3d,0x6e,0x26,0x26,0x22, +0x62,0x75,0x74,0x74,0x6f,0x6e,0x22,0x21,0x3d,0x6e,0x26,0x26,0x22,0x66,0x69,0x6c, +0x65,0x22,0x21,0x3d,0x6e,0x26,0x26,0x28,0x22,0x72,0x61,0x64,0x69,0x6f,0x22,0x21, +0x3d,0x6e,0x26,0x26,0x22,0x63,0x68,0x65,0x63,0x6b,0x62,0x6f,0x78,0x22,0x21,0x3d, +0x6e,0x7c,0x7c,0x6f,0x2e,0x63,0x68,0x65,0x63,0x6b,0x65,0x64,0x29,0x26,0x26,0x72, +0x28,0x74,0x28,0x6f,0x29,0x2e,0x76,0x61,0x6c,0x28,0x29,0x29,0x7d,0x29,0x2c,0x69, +0x7d,0x2c,0x74,0x2e,0x66,0x6e,0x2e,0x73,0x65,0x72,0x69,0x61,0x6c,0x69,0x7a,0x65, +0x3d,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x29,0x7b,0x76,0x61,0x72,0x20, +0x74,0x3d,0x5b,0x5d,0x3b,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x74,0x68,0x69,0x73, +0x2e,0x73,0x65,0x72,0x69,0x61,0x6c,0x69,0x7a,0x65,0x41,0x72,0x72,0x61,0x79,0x28, +0x29,0x2e,0x66,0x6f,0x72,0x45,0x61,0x63,0x68,0x28,0x66,0x75,0x6e,0x63,0x74,0x69, +0x6f,0x6e,0x28,0x65,0x29,0x7b,0x74,0x2e,0x70,0x75,0x73,0x68,0x28,0x65,0x6e,0x63, +0x6f,0x64,0x65,0x55,0x52,0x49,0x43,0x6f,0x6d,0x70,0x6f,0x6e,0x65,0x6e,0x74,0x28, +0x65,0x2e,0x6e,0x61,0x6d,0x65,0x29,0x2b,0x22,0x3d,0x22,0x2b,0x65,0x6e,0x63,0x6f, +0x64,0x65,0x55,0x52,0x49,0x43,0x6f,0x6d,0x70,0x6f,0x6e,0x65,0x6e,0x74,0x28,0x65, +0x2e,0x76,0x61,0x6c,0x75,0x65,0x29,0x29,0x7d,0x29,0x2c,0x74,0x2e,0x6a,0x6f,0x69, +0x6e,0x28,0x22,0x26,0x22,0x29,0x7d,0x2c,0x74,0x2e,0x66,0x6e,0x2e,0x73,0x75,0x62, +0x6d,0x69,0x74,0x3d,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x65,0x29,0x7b, +0x69,0x66,0x28,0x30,0x20,0x69,0x6e,0x20,0x61,0x72,0x67,0x75,0x6d,0x65,0x6e,0x74, +0x73,0x29,0x74,0x68,0x69,0x73,0x2e,0x62,0x69,0x6e,0x64,0x28,0x22,0x73,0x75,0x62, +0x6d,0x69,0x74,0x22,0x2c,0x65,0x29,0x3b,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x28, +0x74,0x68,0x69,0x73,0x2e,0x6c,0x65,0x6e,0x67,0x74,0x68,0x29,0x7b,0x76,0x61,0x72, +0x20,0x6e,0x3d,0x74,0x2e,0x45,0x76,0x65,0x6e,0x74,0x28,0x22,0x73,0x75,0x62,0x6d, +0x69,0x74,0x22,0x29,0x3b,0x74,0x68,0x69,0x73,0x2e,0x65,0x71,0x28,0x30,0x29,0x2e, +0x74,0x72,0x69,0x67,0x67,0x65,0x72,0x28,0x6e,0x29,0x2c,0x6e,0x2e,0x69,0x73,0x44, +0x65,0x66,0x61,0x75,0x6c,0x74,0x50,0x72,0x65,0x76,0x65,0x6e,0x74,0x65,0x64,0x28, +0x29,0x7c,0x7c,0x74,0x68,0x69,0x73,0x2e,0x67,0x65,0x74,0x28,0x30,0x29,0x2e,0x73, +0x75,0x62,0x6d,0x69,0x74,0x28,0x29,0x7d,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x74, +0x68,0x69,0x73,0x7d,0x7d,0x28,0x5a,0x65,0x70,0x74,0x6f,0x29,0x2c,0x66,0x75,0x6e, +0x63,0x74,0x69,0x6f,0x6e,0x28,0x74,0x29,0x7b,0x22,0x5f,0x5f,0x70,0x72,0x6f,0x74, +0x6f,0x5f,0x5f,0x22,0x69,0x6e,0x7b,0x7d,0x7c,0x7c,0x74,0x2e,0x65,0x78,0x74,0x65, +0x6e,0x64,0x28,0x74,0x2e,0x7a,0x65,0x70,0x74,0x6f,0x2c,0x7b,0x5a,0x3a,0x66,0x75, +0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x65,0x2c,0x6e,0x29,0x7b,0x72,0x65,0x74,0x75, +0x72,0x6e,0x20,0x65,0x3d,0x65,0x7c,0x7c,0x5b,0x5d,0x2c,0x74,0x2e,0x65,0x78,0x74, +0x65,0x6e,0x64,0x28,0x65,0x2c,0x74,0x2e,0x66,0x6e,0x29,0x2c,0x65,0x2e,0x73,0x65, +0x6c,0x65,0x63,0x74,0x6f,0x72,0x3d,0x6e,0x7c,0x7c,0x22,0x22,0x2c,0x65,0x2e,0x5f, +0x5f,0x5a,0x3d,0x21,0x30,0x2c,0x65,0x7d,0x2c,0x69,0x73,0x5a,0x3a,0x66,0x75,0x6e, +0x63,0x74,0x69,0x6f,0x6e,0x28,0x65,0x29,0x7b,0x72,0x65,0x74,0x75,0x72,0x6e,0x22, +0x61,0x72,0x72,0x61,0x79,0x22,0x3d,0x3d,0x3d,0x74,0x2e,0x74,0x79,0x70,0x65,0x28, +0x65,0x29,0x26,0x26,0x22,0x5f,0x5f,0x5a,0x22,0x69,0x6e,0x20,0x65,0x7d,0x7d,0x29, +0x3b,0x74,0x72,0x79,0x7b,0x67,0x65,0x74,0x43,0x6f,0x6d,0x70,0x75,0x74,0x65,0x64, +0x53,0x74,0x79,0x6c,0x65,0x28,0x76,0x6f,0x69,0x64,0x20,0x30,0x29,0x7d,0x63,0x61, +0x74,0x63,0x68,0x28,0x65,0x29,0x7b,0x76,0x61,0x72,0x20,0x6e,0x3d,0x67,0x65,0x74, +0x43,0x6f,0x6d,0x70,0x75,0x74,0x65,0x64,0x53,0x74,0x79,0x6c,0x65,0x3b,0x77,0x69, +0x6e,0x64,0x6f,0x77,0x2e,0x67,0x65,0x74,0x43,0x6f,0x6d,0x70,0x75,0x74,0x65,0x64, +0x53,0x74,0x79,0x6c,0x65,0x3d,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x74, +0x29,0x7b,0x74,0x72,0x79,0x7b,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x6e,0x28,0x74, +0x29,0x7d,0x63,0x61,0x74,0x63,0x68,0x28,0x65,0x29,0x7b,0x72,0x65,0x74,0x75,0x72, +0x6e,0x20,0x6e,0x75,0x6c,0x6c,0x7d,0x7d,0x7d,0x7d,0x28,0x5a,0x65,0x70,0x74,0x6f, +0x29,0x3b,}; + + + +const struct fsdata_file file__img_toaster_svg[] = { { +file_NULL, +data__img_toaster_svg, +data__img_toaster_svg + 20, +sizeof(data__img_toaster_svg) - 20, +1, +}}; + +const struct fsdata_file file__404_html[] = { { +file__img_toaster_svg, +data__404_html, +data__404_html + 12, +sizeof(data__404_html) - 12, +1, +}}; + +const struct fsdata_file file__index_html[] = { { +file__404_html, +data__index_html, +data__index_html + 12, +sizeof(data__index_html) - 12, +1, +}}; + +const struct fsdata_file file__state_shtml[] = { { +file__index_html, +data__state_shtml, +data__state_shtml + 16, +sizeof(data__state_shtml) - 16, +1, +}}; + +const struct fsdata_file file__zepto_min_js[] = { { +file__state_shtml, +data__zepto_min_js, +data__zepto_min_js + 16, +sizeof(data__zepto_min_js) - 16, +1, +}}; + +#define FS_ROOT file__zepto_min_js +#define FS_NUMFILES 5 + diff --git a/src/lwip-1.4.1/apps/httpserver_raw/fsdata.h b/src/lwip-1.4.1/apps/httpserver_raw/fsdata.h new file mode 100644 index 0000000..6f6c557 --- /dev/null +++ b/src/lwip-1.4.1/apps/httpserver_raw/fsdata.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2001-2003 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __FSDATA_H__ +#define __FSDATA_H__ + +#include "lwip/opt.h" +#include "fs.h" + +struct fsdata_file { + const struct fsdata_file *next; + const unsigned char *name; + const unsigned char *data; + int len; + u8_t http_header_included; +#if HTTPD_PRECALCULATED_CHECKSUM + u16_t chksum_count; + const struct fsdata_chksum *chksum; +#endif /* HTTPD_PRECALCULATED_CHECKSUM */ +}; + +#endif /* __FSDATA_H__ */ diff --git a/src/lwip-1.4.1/apps/httpserver_raw/httpd.c b/src/lwip-1.4.1/apps/httpserver_raw/httpd.c new file mode 100644 index 0000000..241a376 --- /dev/null +++ b/src/lwip-1.4.1/apps/httpserver_raw/httpd.c @@ -0,0 +1,2506 @@ +/* + * Copyright (c) 2001-2003 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * Simon Goldschmidt + * + */ + +/* This httpd supports for a + * rudimentary server-side-include facility which will replace tags of the form + * in any file whose extension is .shtml, .shtm or .ssi with + * strings provided by an include handler whose pointer is provided to the + * module via function http_set_ssi_handler(). + * Additionally, a simple common + * gateway interface (CGI) handling mechanism has been added to allow clients + * to hook functions to particular request URIs. + * + * To enable SSI support, define label LWIP_HTTPD_SSI in lwipopts.h. + * To enable CGI support, define label LWIP_HTTPD_CGI in lwipopts.h. + * + * By default, the server assumes that HTTP headers are already present in + * each file stored in the file system. By defining LWIP_HTTPD_DYNAMIC_HEADERS in + * lwipopts.h, this behavior can be changed such that the server inserts the + * headers automatically based on the extension of the file being served. If + * this mode is used, be careful to ensure that the file system image used + * does not already contain the header information. + * + * File system images without headers can be created using the makefsfile + * tool with the -h command line option. + * + * + * Notes about valid SSI tags + * -------------------------- + * + * The following assumptions are made about tags used in SSI markers: + * + * 1. No tag may contain '-' or whitespace characters within the tag name. + * 2. Whitespace is allowed between the tag leadin "". + * 3. The maximum tag name length is LWIP_HTTPD_MAX_TAG_NAME_LEN, currently 8 characters. + * + * Notes on CGI usage + * ------------------ + * + * The simple CGI support offered here works with GET method requests only + * and can handle up to 16 parameters encoded into the URI. The handler + * function may not write directly to the HTTP output but must return a + * filename that the HTTP server will send to the browser as a response to + * the incoming CGI request. + * + * + * + * The list of supported file types is quite short, so if makefsdata complains + * about an unknown extension, make sure to add it (and its doctype) to + * the 'g_psHTTPHeaders' list. + */ +#include "httpd.h" +#include "lwip/debug.h" +#include "lwip/stats.h" +#include "httpd_structs.h" +#include "lwip/tcp.h" +#include "fs.h" + +#include +#include + +#if LWIP_TCP + +#ifndef HTTPD_DEBUG +#define HTTPD_DEBUG LWIP_DBG_OFF +#endif + +/** Set this to 1 and add the next line to lwippools.h to use a memp pool + * for allocating struct http_state instead of the heap: + * + * LWIP_MEMPOOL(HTTPD_STATE, 20, 100, "HTTPD_STATE") + */ +#ifndef HTTPD_USE_MEM_POOL +#define HTTPD_USE_MEM_POOL 0 +#endif + +/** The server port for HTTPD to use */ +#ifndef HTTPD_SERVER_PORT +#define HTTPD_SERVER_PORT 80 +#endif + +/** Maximum retries before the connection is aborted/closed. + * - number of times pcb->poll is called -> default is 4*500ms = 2s; + * - reset when pcb->sent is called + */ +#ifndef HTTPD_MAX_RETRIES +#define HTTPD_MAX_RETRIES 4 +#endif + +/** The poll delay is X*500ms */ +#ifndef HTTPD_POLL_INTERVAL +#define HTTPD_POLL_INTERVAL 4 +#endif + +/** Priority for tcp pcbs created by HTTPD (very low by default). + * Lower priorities get killed first when running out of memroy. + */ +#ifndef HTTPD_TCP_PRIO +#define HTTPD_TCP_PRIO TCP_PRIO_MIN +#endif + +/** Set this to 1 to enabled timing each file sent */ +#ifndef LWIP_HTTPD_TIMING +#define LWIP_HTTPD_TIMING 0 +#endif +#ifndef HTTPD_DEBUG_TIMING +#define HTTPD_DEBUG_TIMING LWIP_DBG_OFF +#endif + +/** Set this to 1 on platforms where strnstr is not available */ +#ifndef LWIP_HTTPD_STRNSTR_PRIVATE +#define LWIP_HTTPD_STRNSTR_PRIVATE 1 +#endif + +/** Set this to one to show error pages when parsing a request fails instead + of simply closing the connection. */ +#ifndef LWIP_HTTPD_SUPPORT_EXTSTATUS +#define LWIP_HTTPD_SUPPORT_EXTSTATUS 0 +#endif + +/** Set this to 0 to drop support for HTTP/0.9 clients (to save some bytes) */ +#ifndef LWIP_HTTPD_SUPPORT_V09 +#define LWIP_HTTPD_SUPPORT_V09 1 +#endif + +/** Set this to 1 to enable HTTP/1.1 persistent connections. + * ATTENTION: If the generated file system includes HTTP headers, these must + * include the "Connection: keep-alive" header (pass argument "-11" to makefsdata). + */ +#ifndef LWIP_HTTPD_SUPPORT_11_KEEPALIVE +#define LWIP_HTTPD_SUPPORT_11_KEEPALIVE 0 +#endif + +/** Set this to 1 to support HTTP request coming in in multiple packets/pbufs */ +#ifndef LWIP_HTTPD_SUPPORT_REQUESTLIST +#define LWIP_HTTPD_SUPPORT_REQUESTLIST 1 +#endif + +#if LWIP_HTTPD_SUPPORT_REQUESTLIST +/** Number of rx pbufs to enqueue to parse an incoming request (up to the first + newline) */ +#ifndef LWIP_HTTPD_REQ_QUEUELEN +#define LWIP_HTTPD_REQ_QUEUELEN 5 +#endif + +/** Number of (TCP payload-) bytes (in pbufs) to enqueue to parse and incoming + request (up to the first double-newline) */ +#ifndef LWIP_HTTPD_REQ_BUFSIZE +#define LWIP_HTTPD_REQ_BUFSIZE LWIP_HTTPD_MAX_REQ_LENGTH +#endif + +/** Defines the maximum length of a HTTP request line (up to the first CRLF, + copied from pbuf into this a global buffer when pbuf- or packet-queues + are received - otherwise the input pbuf is used directly) */ +#ifndef LWIP_HTTPD_MAX_REQ_LENGTH +#define LWIP_HTTPD_MAX_REQ_LENGTH LWIP_MIN(1023, (LWIP_HTTPD_REQ_QUEUELEN * PBUF_POOL_BUFSIZE)) +#endif +#endif /* LWIP_HTTPD_SUPPORT_REQUESTLIST */ + +/** Maximum length of the filename to send as response to a POST request, + * filled in by the application when a POST is finished. + */ +#ifndef LWIP_HTTPD_POST_MAX_RESPONSE_URI_LEN +#define LWIP_HTTPD_POST_MAX_RESPONSE_URI_LEN 63 +#endif + +/** Set this to 0 to not send the SSI tag (default is on, so the tag will + * be sent in the HTML page */ +#ifndef LWIP_HTTPD_SSI_INCLUDE_TAG +#define LWIP_HTTPD_SSI_INCLUDE_TAG 1 +#endif + +/** Set this to 1 to call tcp_abort when tcp_close fails with memory error. + * This can be used to prevent consuming all memory in situations where the + * HTTP server has low priority compared to other communication. */ +#ifndef LWIP_HTTPD_ABORT_ON_CLOSE_MEM_ERROR +#define LWIP_HTTPD_ABORT_ON_CLOSE_MEM_ERROR 0 +#endif + +/** Set this to 1 to kill the oldest connection when running out of + * memory for 'struct http_state' or 'struct http_ssi_state'. + * ATTENTION: This puts all connections on a linked list, so may be kind of slow. + */ +#ifndef LWIP_HTTPD_KILL_OLD_ON_CONNECTIONS_EXCEEDED +#define LWIP_HTTPD_KILL_OLD_ON_CONNECTIONS_EXCEEDED 0 +#endif + +/** Minimum length for a valid HTTP/0.9 request: "GET /\r\n" -> 7 bytes */ +#define MIN_REQ_LEN 7 + +#define CRLF "\r\n" +#define HTTP11_CONNECTIONKEEPALIVE "Connection: keep-alive" + +#if LWIP_HTTPD_SSI +#define LWIP_HTTPD_IS_SSI(hs) ((hs)->ssi) +#else /* LWIP_HTTPD_SSI */ +#define LWIP_HTTPD_IS_SSI(hs) 0 +#endif /* LWIP_HTTPD_SSI */ + +/** These defines check whether tcp_write has to copy data or not */ + +/** This was TI's check whether to let TCP copy data or not +#define HTTP_IS_DATA_VOLATILE(hs) ((hs->file < (char *)0x20000000) ? 0 : TCP_WRITE_FLAG_COPY)*/ +#ifndef HTTP_IS_DATA_VOLATILE +#if LWIP_HTTPD_SSI +/* Copy for SSI files, no copy for non-SSI files */ +#define HTTP_IS_DATA_VOLATILE(hs) ((hs)->ssi ? TCP_WRITE_FLAG_COPY : 0) +#else /* LWIP_HTTPD_SSI */ +/** Default: don't copy if the data is sent from file-system directly */ +#define HTTP_IS_DATA_VOLATILE(hs) (((hs->file != NULL) && (hs->handle != NULL) && (hs->file == \ + (char*)hs->handle->data + hs->handle->len - hs->left)) \ + ? 0 : TCP_WRITE_FLAG_COPY) +#endif /* LWIP_HTTPD_SSI */ +#endif + +/** Default: headers are sent from ROM */ +#ifndef HTTP_IS_HDR_VOLATILE +#define HTTP_IS_HDR_VOLATILE(hs, ptr) 0 +#endif + +#if LWIP_HTTPD_SSI +/** Default: Tags are sent from struct http_state and are therefore volatile */ +#ifndef HTTP_IS_TAG_VOLATILE +#define HTTP_IS_TAG_VOLATILE(ptr) TCP_WRITE_FLAG_COPY +#endif +#endif /* LWIP_HTTPD_SSI */ + +/* Return values for http_send_*() */ +#define HTTP_DATA_TO_SEND_BREAK 2 +#define HTTP_DATA_TO_SEND_CONTINUE 1 +#define HTTP_NO_DATA_TO_SEND 0 + +#if HTTPD_USE_MEM_POOL +#define HTTP_ALLOC_SSI_STATE() (struct http_ssi_state *)memp_malloc(MEMP_HTTPD_SSI_STATE) +#define HTTP_ALLOC_HTTP_STATE() (struct http_state *)memp_malloc(MEMP_HTTPD_STATE) +#else /* HTTPD_USE_MEM_POOL */ +#define HTTP_ALLOC_SSI_STATE() (struct http_ssi_state *)mem_malloc(sizeof(struct http_ssi_state)) +#define HTTP_ALLOC_HTTP_STATE() (struct http_state *)mem_malloc(sizeof(struct http_state)) +#endif /* HTTPD_USE_MEM_POOL */ + +typedef struct +{ + const char *name; + u8_t shtml; +} default_filename; + +const default_filename g_psDefaultFilenames[] = { + {"/index.shtml", 1 }, + {"/index.ssi", 1 }, + {"/index.shtm", 1 }, + {"/index.html", 0 }, + {"/index.htm", 0 } +}; + +#define NUM_DEFAULT_FILENAMES (sizeof(g_psDefaultFilenames) / \ + sizeof(default_filename)) + +#if LWIP_HTTPD_SUPPORT_REQUESTLIST +/** HTTP request is copied here from pbufs for simple parsing */ +static char httpd_req_buf[LWIP_HTTPD_MAX_REQ_LENGTH+1]; +#endif /* LWIP_HTTPD_SUPPORT_REQUESTLIST */ + +#if LWIP_HTTPD_SUPPORT_POST +/** Filename for response file to send when POST is finished */ +static char http_post_response_filename[LWIP_HTTPD_POST_MAX_RESPONSE_URI_LEN+1]; +#endif /* LWIP_HTTPD_SUPPORT_POST */ + +#if LWIP_HTTPD_DYNAMIC_HEADERS +/* The number of individual strings that comprise the headers sent before each + * requested file. + */ +#define NUM_FILE_HDR_STRINGS 3 +#endif /* LWIP_HTTPD_DYNAMIC_HEADERS */ + +#if LWIP_HTTPD_SSI + +#define HTTPD_LAST_TAG_PART 0xFFFF + +enum tag_check_state { + TAG_NONE, /* Not processing an SSI tag */ + TAG_LEADIN, /* Tag lead in "" being processed */ + TAG_SENDING /* Sending tag replacement string */ +}; + +struct http_ssi_state { + const char *parsed; /* Pointer to the first unparsed byte in buf. */ +#if !LWIP_HTTPD_SSI_INCLUDE_TAG + const char *tag_started;/* Pointer to the first opening '<' of the tag. */ +#endif /* !LWIP_HTTPD_SSI_INCLUDE_TAG */ + const char *tag_end; /* Pointer to char after the closing '>' of the tag. */ + u32_t parse_left; /* Number of unparsed bytes in buf. */ + u16_t tag_index; /* Counter used by tag parsing state machine */ + u16_t tag_insert_len; /* Length of insert in string tag_insert */ +#if LWIP_HTTPD_SSI_MULTIPART + u16_t tag_part; /* Counter passed to and changed by tag insertion function to insert multiple times */ +#endif /* LWIP_HTTPD_SSI_MULTIPART */ + u8_t tag_name_len; /* Length of the tag name in string tag_name */ + char tag_name[LWIP_HTTPD_MAX_TAG_NAME_LEN + 1]; /* Last tag name extracted */ + char tag_insert[LWIP_HTTPD_MAX_TAG_INSERT_LEN + 1]; /* Insert string for tag_name */ + enum tag_check_state tag_state; /* State of the tag processor */ +}; +#endif /* LWIP_HTTPD_SSI */ + +struct http_state { +#if LWIP_HTTPD_KILL_OLD_ON_CONNECTIONS_EXCEEDED + struct http_state *next; +#endif /* LWIP_HTTPD_KILL_OLD_ON_CONNECTIONS_EXCEEDED */ + struct fs_file file_handle; + struct fs_file *handle; + char *file; /* Pointer to first unsent byte in buf. */ + + struct tcp_pcb *pcb; +#if LWIP_HTTPD_SUPPORT_REQUESTLIST + struct pbuf *req; +#endif /* LWIP_HTTPD_SUPPORT_REQUESTLIST */ + +#if LWIP_HTTPD_DYNAMIC_FILE_READ + char *buf; /* File read buffer. */ + int buf_len; /* Size of file read buffer, buf. */ +#endif /* LWIP_HTTPD_DYNAMIC_FILE_READ */ + u32_t left; /* Number of unsent bytes in buf. */ + u8_t retries; +#if LWIP_HTTPD_SUPPORT_11_KEEPALIVE + u8_t keepalive; +#endif /* LWIP_HTTPD_SUPPORT_11_KEEPALIVE */ +#if LWIP_HTTPD_SSI + struct http_ssi_state *ssi; +#endif /* LWIP_HTTPD_SSI */ +#if LWIP_HTTPD_CGI + char *params[LWIP_HTTPD_MAX_CGI_PARAMETERS]; /* Params extracted from the request URI */ + char *param_vals[LWIP_HTTPD_MAX_CGI_PARAMETERS]; /* Values for each extracted param */ +#endif /* LWIP_HTTPD_CGI */ +#if LWIP_HTTPD_DYNAMIC_HEADERS + const char *hdrs[NUM_FILE_HDR_STRINGS]; /* HTTP headers to be sent. */ + u16_t hdr_pos; /* The position of the first unsent header byte in the + current string */ + u16_t hdr_index; /* The index of the hdr string currently being sent. */ +#endif /* LWIP_HTTPD_DYNAMIC_HEADERS */ +#if LWIP_HTTPD_TIMING + u32_t time_started; +#endif /* LWIP_HTTPD_TIMING */ +#if LWIP_HTTPD_SUPPORT_POST + u32_t post_content_len_left; +#if LWIP_HTTPD_POST_MANUAL_WND + u32_t unrecved_bytes; + u8_t no_auto_wnd; + u8_t post_finished; +#endif /* LWIP_HTTPD_POST_MANUAL_WND */ +#endif /* LWIP_HTTPD_SUPPORT_POST*/ +}; + +static err_t http_close_conn(struct tcp_pcb *pcb, struct http_state *hs); +static err_t http_close_or_abort_conn(struct tcp_pcb *pcb, struct http_state *hs, u8_t abort_conn); +static err_t http_find_file(struct http_state *hs, const char *uri, int is_09); +static err_t http_init_file(struct http_state *hs, struct fs_file *file, int is_09, const char *uri, u8_t tag_check); +static err_t http_poll(void *arg, struct tcp_pcb *pcb); +#if LWIP_HTTPD_FS_ASYNC_READ +static void http_continue(void *connection); +#endif /* LWIP_HTTPD_FS_ASYNC_READ */ + +#if LWIP_HTTPD_SSI +/* SSI insert handler function pointer. */ +tSSIHandler g_pfnSSIHandler = NULL; +int g_iNumTags = 0; +const char **g_ppcTags = NULL; + +#define LEN_TAG_LEAD_IN 5 +const char * const g_pcTagLeadIn = ""; +#endif /* LWIP_HTTPD_SSI */ + +#if LWIP_HTTPD_CGI +/* CGI handler information */ +const tCGI *g_pCGIs; +int g_iNumCGIs; +#endif /* LWIP_HTTPD_CGI */ + +#if LWIP_HTTPD_KILL_OLD_ON_CONNECTIONS_EXCEEDED +/** global list of active HTTP connections, use to kill the oldest when + running out of memory */ +static struct http_state *http_connections; +#endif /* LWIP_HTTPD_KILL_OLD_ON_CONNECTIONS_EXCEEDED */ + +#if LWIP_HTTPD_STRNSTR_PRIVATE +/** Like strstr but does not need 'buffer' to be NULL-terminated */ +char* +strnstr(const char* buffer, const char* token, size_t n) +{ + const char* p; + int tokenlen = (int)strlen(token); + if (tokenlen == 0) { + return (char *)buffer; + } + for (p = buffer; *p && (p + tokenlen <= buffer + n); p++) { + if ((*p == *token) && (strncmp(p, token, tokenlen) == 0)) { + return (char *)p; + } + } + return NULL; +} +#endif /* LWIP_HTTPD_STRNSTR_PRIVATE */ + +#if LWIP_HTTPD_KILL_OLD_ON_CONNECTIONS_EXCEEDED +static void +http_kill_oldest_connection(u8_t ssi_required) +{ + struct http_state *hs = http_connections; + struct http_state *hs_free_next = NULL; + while(hs && hs->next) { + if (ssi_required) { + if (hs->next->ssi != NULL) { + hs_free_next = hs; + } + } else { + hs_free_next = hs; + } + hs = hs->next; + } + if (hs_free_next != NULL) { + LWIP_ASSERT("hs_free_next->next != NULL", hs_free_next->next != NULL); + LWIP_ASSERT("hs_free_next->next->pcb != NULL", hs_free_next->next->pcb != NULL); + /* send RST when killing a connection because of memory shortage */ + http_close_or_abort_conn(hs_free_next->next->pcb, hs_free_next->next, 1); /* this also unlinks the http_state from the list */ + } +} +#endif /* LWIP_HTTPD_KILL_OLD_ON_CONNECTIONS_EXCEEDED */ + +#if LWIP_HTTPD_SSI +/** Allocate as struct http_ssi_state. */ +static struct http_ssi_state* +http_ssi_state_alloc(void) +{ + struct http_ssi_state *ret = HTTP_ALLOC_SSI_STATE(); +#if LWIP_HTTPD_KILL_OLD_ON_CONNECTIONS_EXCEEDED + if (ret == NULL) { + http_kill_oldest_connection(1); + ret = HTTP_ALLOC_SSI_STATE(); + } +#endif /* LWIP_HTTPD_KILL_OLD_ON_CONNECTIONS_EXCEEDED */ + if (ret != NULL) { + memset(ret, 0, sizeof(struct http_ssi_state)); + } + return ret; +} + +/** Free a struct http_ssi_state. */ +static void +http_ssi_state_free(struct http_ssi_state *ssi) +{ + if (ssi != NULL) { +#if HTTPD_USE_MEM_POOL + memp_free(MEMP_HTTPD_SSI_STATE, ssi); +#else /* HTTPD_USE_MEM_POOL */ + mem_free(ssi); +#endif /* HTTPD_USE_MEM_POOL */ + } +} +#endif /* LWIP_HTTPD_SSI */ + +/** Initialize a struct http_state. + */ +static void +http_state_init(struct http_state* hs) +{ + /* Initialize the structure. */ + memset(hs, 0, sizeof(struct http_state)); +#if LWIP_HTTPD_DYNAMIC_HEADERS + /* Indicate that the headers are not yet valid */ + hs->hdr_index = NUM_FILE_HDR_STRINGS; +#endif /* LWIP_HTTPD_DYNAMIC_HEADERS */ +} + +/** Allocate a struct http_state. */ +static struct http_state* +http_state_alloc(void) +{ + struct http_state *ret = HTTP_ALLOC_HTTP_STATE(); +#if LWIP_HTTPD_KILL_OLD_ON_CONNECTIONS_EXCEEDED + if (ret == NULL) { + http_kill_oldest_connection(0); + ret = HTTP_ALLOC_HTTP_STATE(); + } +#endif /* LWIP_HTTPD_KILL_OLD_ON_CONNECTIONS_EXCEEDED */ + if (ret != NULL) { + http_state_init(ret); +#if LWIP_HTTPD_KILL_OLD_ON_CONNECTIONS_EXCEEDED + /* add the connection to the list */ + if (http_connections == NULL) { + http_connections = ret; + } else { + struct http_state *last; + for(last = http_connections; last->next != NULL; last = last->next); + LWIP_ASSERT("last != NULL", last != NULL); + last->next = ret; + } +#endif /* LWIP_HTTPD_KILL_OLD_ON_CONNECTIONS_EXCEEDED */ + } + return ret; +} + +/** Free a struct http_state. + * Also frees the file data if dynamic. + */ +static void +http_state_eof(struct http_state *hs) +{ + if(hs->handle) { +#if LWIP_HTTPD_TIMING + u32_t ms_needed = sys_now() - hs->time_started; + u32_t needed = LWIP_MAX(1, (ms_needed/100)); + LWIP_DEBUGF(HTTPD_DEBUG_TIMING, ("httpd: needed %"U32_F" ms to send file of %d bytes -> %"U32_F" bytes/sec\n", + ms_needed, hs->handle->len, ((((u32_t)hs->handle->len) * 10) / needed))); +#endif /* LWIP_HTTPD_TIMING */ + fs_close(hs->handle); + hs->handle = NULL; + } +#if LWIP_HTTPD_DYNAMIC_FILE_READ + if (hs->buf != NULL) { + mem_free(hs->buf); + hs->buf = NULL; + } +#endif /* LWIP_HTTPD_DYNAMIC_FILE_READ */ +#if LWIP_HTTPD_SSI + if (hs->ssi) { + http_ssi_state_free(hs->ssi); + hs->ssi = NULL; + } +#endif /* LWIP_HTTPD_SSI */ +} + +/** Free a struct http_state. + * Also frees the file data if dynamic. + */ +static void +http_state_free(struct http_state *hs) +{ + if (hs != NULL) { + http_state_eof(hs); +#if LWIP_HTTPD_KILL_OLD_ON_CONNECTIONS_EXCEEDED + /* take the connection off the list */ + if (http_connections) { + if (http_connections == hs) { + http_connections = hs->next; + } else { + struct http_state *last; + for(last = http_connections; last->next != NULL; last = last->next) { + if (last->next == hs) { + last->next = hs->next; + break; + } + } + } + } +#endif /* LWIP_HTTPD_KILL_OLD_ON_CONNECTIONS_EXCEEDED */ +#if HTTPD_USE_MEM_POOL + memp_free(MEMP_HTTPD_STATE, hs); +#else /* HTTPD_USE_MEM_POOL */ + mem_free(hs); +#endif /* HTTPD_USE_MEM_POOL */ + } +} + +/** Call tcp_write() in a loop trying smaller and smaller length + * + * @param pcb tcp_pcb to send + * @param ptr Data to send + * @param length Length of data to send (in/out: on return, contains the + * amount of data sent) + * @param apiflags directly passed to tcp_write + * @return the return value of tcp_write + */ +static err_t +http_write(struct tcp_pcb *pcb, const void* ptr, u16_t *length, u8_t apiflags) +{ + u16_t len; + err_t err; + LWIP_ASSERT("length != NULL", length != NULL); + len = *length; + if (len == 0) { + return ERR_OK; + } + do { + LWIP_DEBUGF(HTTPD_DEBUG | LWIP_DBG_TRACE, ("Trying go send %d bytes\n", len)); + err = tcp_write(pcb, ptr, len, apiflags); + if (err == ERR_MEM) { + if ((tcp_sndbuf(pcb) == 0) || + (tcp_sndqueuelen(pcb) >= TCP_SND_QUEUELEN)) { + /* no need to try smaller sizes */ + len = 1; + } else { + len /= 2; + } + LWIP_DEBUGF(HTTPD_DEBUG | LWIP_DBG_TRACE, + ("Send failed, trying less (%d bytes)\n", len)); + } + } while ((err == ERR_MEM) && (len > 1)); + + if (err == ERR_OK) { + LWIP_DEBUGF(HTTPD_DEBUG | LWIP_DBG_TRACE, ("Sent %d bytes\n", len)); + } else { + LWIP_DEBUGF(HTTPD_DEBUG | LWIP_DBG_TRACE, ("Send failed with err %d (\"%s\")\n", err, lwip_strerr(err))); + } + + *length = len; + return err; +} + +/** + * The connection shall be actively closed (using RST to close from fault states). + * Reset the sent- and recv-callbacks. + * + * @param pcb the tcp pcb to reset callbacks + * @param hs connection state to free + */ +static err_t +http_close_or_abort_conn(struct tcp_pcb *pcb, struct http_state *hs, u8_t abort_conn) +{ + err_t err; + LWIP_DEBUGF(HTTPD_DEBUG, ("Closing connection %p\n", (void*)pcb)); + +#if LWIP_HTTPD_SUPPORT_POST + if (hs != NULL) { + if ((hs->post_content_len_left != 0) +#if LWIP_HTTPD_POST_MANUAL_WND + || ((hs->no_auto_wnd != 0) && (hs->unrecved_bytes != 0)) +#endif /* LWIP_HTTPD_POST_MANUAL_WND */ + ) { + /* make sure the post code knows that the connection is closed */ + http_post_response_filename[0] = 0; + httpd_post_finished(hs, http_post_response_filename, LWIP_HTTPD_POST_MAX_RESPONSE_URI_LEN); + } + } +#endif /* LWIP_HTTPD_SUPPORT_POST*/ + + + tcp_arg(pcb, NULL); + tcp_recv(pcb, NULL); + tcp_err(pcb, NULL); + tcp_poll(pcb, NULL, 0); + tcp_sent(pcb, NULL); + if (hs != NULL) { + http_state_free(hs); + } + + if (abort_conn) { + tcp_abort(pcb); + return ERR_OK; + } + err = tcp_close(pcb); + if (err != ERR_OK) { + LWIP_DEBUGF(HTTPD_DEBUG, ("Error %d closing %p\n", err, (void*)pcb)); + /* error closing, try again later in poll */ + tcp_poll(pcb, http_poll, HTTPD_POLL_INTERVAL); + } + return err; +} + +/** + * The connection shall be actively closed. + * Reset the sent- and recv-callbacks. + * + * @param pcb the tcp pcb to reset callbacks + * @param hs connection state to free + */ +static err_t +http_close_conn(struct tcp_pcb *pcb, struct http_state *hs) +{ + return http_close_or_abort_conn(pcb, hs, 0); +} + +/** End of file: either close the connection (Connection: close) or + * close the file (Connection: keep-alive) + */ +static void +http_eof(struct tcp_pcb *pcb, struct http_state *hs) +{ + /* HTTP/1.1 persistent connection? (Not supported for SSI) */ +#if LWIP_HTTPD_SUPPORT_11_KEEPALIVE + if (hs->keepalive && !LWIP_HTTPD_IS_SSI(hs)) { + http_state_eof(hs); + http_state_init(hs); + hs->keepalive = 1; + } else +#endif /* LWIP_HTTPD_SUPPORT_11_KEEPALIVE */ + { + http_close_conn(pcb, hs); + } +} + +#if LWIP_HTTPD_CGI +/** + * Extract URI parameters from the parameter-part of an URI in the form + * "test.cgi?x=y" @todo: better explanation! + * Pointers to the parameters are stored in hs->param_vals. + * + * @param hs http connection state + * @param params pointer to the NULL-terminated parameter string from the URI + * @return number of parameters extracted + */ +static int +extract_uri_parameters(struct http_state *hs, char *params) +{ + char *pair; + char *equals; + int loop; + + /* If we have no parameters at all, return immediately. */ + if(!params || (params[0] == '\0')) { + return(0); + } + + /* Get a pointer to our first parameter */ + pair = params; + + /* Parse up to LWIP_HTTPD_MAX_CGI_PARAMETERS from the passed string and ignore the + * remainder (if any) */ + for(loop = 0; (loop < LWIP_HTTPD_MAX_CGI_PARAMETERS) && pair; loop++) { + + /* Save the name of the parameter */ + hs->params[loop] = pair; + + /* Remember the start of this name=value pair */ + equals = pair; + + /* Find the start of the next name=value pair and replace the delimiter + * with a 0 to terminate the previous pair string. */ + pair = strchr(pair, '&'); + if(pair) { + *pair = '\0'; + pair++; + } else { + /* We didn't find a new parameter so find the end of the URI and + * replace the space with a '\0' */ + pair = strchr(equals, ' '); + if(pair) { + *pair = '\0'; + } + + /* Revert to NULL so that we exit the loop as expected. */ + pair = NULL; + } + + /* Now find the '=' in the previous pair, replace it with '\0' and save + * the parameter value string. */ + equals = strchr(equals, '='); + if(equals) { + *equals = '\0'; + hs->param_vals[loop] = equals + 1; + } else { + hs->param_vals[loop] = NULL; + } + } + + return loop; +} +#endif /* LWIP_HTTPD_CGI */ + +#if LWIP_HTTPD_SSI +/** + * Insert a tag (found in an shtml in the form of "" into the file. + * The tag's name is stored in ssi->tag_name (NULL-terminated), the replacement + * should be written to hs->tag_insert (up to a length of LWIP_HTTPD_MAX_TAG_INSERT_LEN). + * The amount of data written is stored to ssi->tag_insert_len. + * + * @todo: return tag_insert_len - maybe it can be removed from struct http_state? + * + * @param hs http connection state + */ +static void +get_tag_insert(struct http_state *hs) +{ + int loop; + size_t len; + struct http_ssi_state *ssi; + LWIP_ASSERT("hs != NULL", hs != NULL); + ssi = hs->ssi; + LWIP_ASSERT("ssi != NULL", ssi != NULL); +#if LWIP_HTTPD_SSI_MULTIPART + u16_t current_tag_part = ssi->tag_part; + ssi->tag_part = HTTPD_LAST_TAG_PART; +#endif /* LWIP_HTTPD_SSI_MULTIPART */ + + if(g_pfnSSIHandler && g_ppcTags && g_iNumTags) { + + /* Find this tag in the list we have been provided. */ + for(loop = 0; loop < g_iNumTags; loop++) { + if(strcmp(ssi->tag_name, g_ppcTags[loop]) == 0) { + ssi->tag_insert_len = g_pfnSSIHandler(loop, ssi->tag_insert, + LWIP_HTTPD_MAX_TAG_INSERT_LEN +#if LWIP_HTTPD_SSI_MULTIPART + , current_tag_part, &ssi->tag_part +#endif /* LWIP_HTTPD_SSI_MULTIPART */ +#if LWIP_HTTPD_FILE_STATE + , hs->handle->state +#endif /* LWIP_HTTPD_FILE_STATE */ + ); + return; + } + } + } + + /* If we drop out, we were asked to serve a page which contains tags that + * we don't have a handler for. Merely echo back the tags with an error + * marker. */ +#define UNKNOWN_TAG1_TEXT "***UNKNOWN TAG " +#define UNKNOWN_TAG1_LEN 18 +#define UNKNOWN_TAG2_TEXT "***" +#define UNKNOWN_TAG2_LEN 7 + len = LWIP_MIN(strlen(ssi->tag_name), + LWIP_HTTPD_MAX_TAG_INSERT_LEN - (UNKNOWN_TAG1_LEN + UNKNOWN_TAG2_LEN)); + MEMCPY(ssi->tag_insert, UNKNOWN_TAG1_TEXT, UNKNOWN_TAG1_LEN); + MEMCPY(&ssi->tag_insert[UNKNOWN_TAG1_LEN], ssi->tag_name, len); + MEMCPY(&ssi->tag_insert[UNKNOWN_TAG1_LEN + len], UNKNOWN_TAG2_TEXT, UNKNOWN_TAG2_LEN); + ssi->tag_insert[UNKNOWN_TAG1_LEN + len + UNKNOWN_TAG2_LEN] = 0; + + len = strlen(ssi->tag_insert); + LWIP_ASSERT("len <= 0xffff", len <= 0xffff); + ssi->tag_insert_len = (u16_t)len; +} +#endif /* LWIP_HTTPD_SSI */ + +#if LWIP_HTTPD_DYNAMIC_HEADERS +/** + * Generate the relevant HTTP headers for the given filename and write + * them into the supplied buffer. + */ +static void +get_http_headers(struct http_state *pState, char *pszURI) +{ + unsigned int iLoop; + char *pszWork; + char *pszExt; + char *pszVars; + + /* Ensure that we initialize the loop counter. */ + iLoop = 0; + + /* In all cases, the second header we send is the server identification + so set it here. */ + pState->hdrs[1] = g_psHTTPHeaderStrings[HTTP_HDR_SERVER]; + + /* Is this a normal file or the special case we use to send back the + default "404: Page not found" response? */ + if (pszURI == NULL) { + pState->hdrs[0] = g_psHTTPHeaderStrings[HTTP_HDR_NOT_FOUND]; + pState->hdrs[2] = g_psHTTPHeaderStrings[DEFAULT_404_HTML]; + + /* Set up to send the first header string. */ + pState->hdr_index = 0; + pState->hdr_pos = 0; + return; + } else { + /* We are dealing with a particular filename. Look for one other + special case. We assume that any filename with "404" in it must be + indicative of a 404 server error whereas all other files require + the 200 OK header. */ + if (strstr(pszURI, "404")) { + pState->hdrs[0] = g_psHTTPHeaderStrings[HTTP_HDR_NOT_FOUND]; + } else if (strstr(pszURI, "400")) { + pState->hdrs[0] = g_psHTTPHeaderStrings[HTTP_HDR_BAD_REQUEST]; + } else if (strstr(pszURI, "501")) { + pState->hdrs[0] = g_psHTTPHeaderStrings[HTTP_HDR_NOT_IMPL]; + } else { + pState->hdrs[0] = g_psHTTPHeaderStrings[HTTP_HDR_OK]; + } + + /* Determine if the URI has any variables and, if so, temporarily remove + them. */ + pszVars = strchr(pszURI, '?'); + if(pszVars) { + *pszVars = '\0'; + } + + /* Get a pointer to the file extension. We find this by looking for the + last occurrence of "." in the filename passed. */ + pszExt = NULL; + pszWork = strchr(pszURI, '.'); + while(pszWork) { + pszExt = pszWork + 1; + pszWork = strchr(pszExt, '.'); + } + + /* Now determine the content type and add the relevant header for that. */ + for(iLoop = 0; (iLoop < NUM_HTTP_HEADERS) && pszExt; iLoop++) { + /* Have we found a matching extension? */ + if(!strcmp(g_psHTTPHeaders[iLoop].extension, pszExt)) { + pState->hdrs[2] = + g_psHTTPHeaderStrings[g_psHTTPHeaders[iLoop].headerIndex]; + break; + } + } + + /* Reinstate the parameter marker if there was one in the original URI. */ + if(pszVars) { + *pszVars = '?'; + } + } + + /* Does the URL passed have any file extension? If not, we assume it + is a special-case URL used for control state notification and we do + not send any HTTP headers with the response. */ + if(!pszExt) { + /* Force the header index to a value indicating that all headers + have already been sent. */ + pState->hdr_index = NUM_FILE_HDR_STRINGS; + } else { + /* Did we find a matching extension? */ + if(iLoop == NUM_HTTP_HEADERS) { + /* No - use the default, plain text file type. */ + pState->hdrs[2] = g_psHTTPHeaderStrings[HTTP_HDR_DEFAULT_TYPE]; + } + + /* Set up to send the first header string. */ + pState->hdr_index = 0; + pState->hdr_pos = 0; + } +} + +/** Sub-function of http_send(): send dynamic headers + * + * @returns: - HTTP_NO_DATA_TO_SEND: no new data has been enqueued + * - HTTP_DATA_TO_SEND_CONTINUE: continue with sending HTTP body + * - HTTP_DATA_TO_SEND_BREAK: data has been enqueued, headers pending, + * so don't send HTTP body yet + */ +static u8_t +http_send_headers(struct tcp_pcb *pcb, struct http_state *hs) +{ + err_t err; + u16_t len; + u8_t data_to_send = HTTP_NO_DATA_TO_SEND; + u16_t hdrlen, sendlen; + + /* How much data can we send? */ + len = tcp_sndbuf(pcb); + sendlen = len; + + while(len && (hs->hdr_index < NUM_FILE_HDR_STRINGS) && sendlen) { + const void *ptr; + u16_t old_sendlen; + /* How much do we have to send from the current header? */ + hdrlen = (u16_t)strlen(hs->hdrs[hs->hdr_index]); + + /* How much of this can we send? */ + sendlen = (len < (hdrlen - hs->hdr_pos)) ? len : (hdrlen - hs->hdr_pos); + + /* Send this amount of data or as much as we can given memory + * constraints. */ + ptr = (const void *)(hs->hdrs[hs->hdr_index] + hs->hdr_pos); + old_sendlen = sendlen; + err = http_write(pcb, ptr, &sendlen, HTTP_IS_HDR_VOLATILE(hs, ptr)); + if ((err == ERR_OK) && (old_sendlen != sendlen)) { + /* Remember that we added some more data to be transmitted. */ + data_to_send = HTTP_DATA_TO_SEND_CONTINUE; + } else if (err != ERR_OK) { + /* special case: http_write does not try to send 1 byte */ + sendlen = 0; + } + + /* Fix up the header position for the next time round. */ + hs->hdr_pos += sendlen; + len -= sendlen; + + /* Have we finished sending this string? */ + if(hs->hdr_pos == hdrlen) { + /* Yes - move on to the next one */ + hs->hdr_index++; + hs->hdr_pos = 0; + } + } + /* If we get here and there are still header bytes to send, we send + * the header information we just wrote immediately. If there are no + * more headers to send, but we do have file data to send, drop through + * to try to send some file data too. */ + if((hs->hdr_index < NUM_FILE_HDR_STRINGS) || !hs->file) { + LWIP_DEBUGF(HTTPD_DEBUG, ("tcp_output\n")); + return HTTP_DATA_TO_SEND_BREAK; + } + return data_to_send; +} +#endif /* LWIP_HTTPD_DYNAMIC_HEADERS */ + +/** Sub-function of http_send(): end-of-file (or block) is reached, + * either close the file or read the next block (if supported). + * + * @returns: 0 if the file is finished or no data has been read + * 1 if the file is not finished and data has been read + */ +static u8_t +http_check_eof(struct tcp_pcb *pcb, struct http_state *hs) +{ +#if LWIP_HTTPD_DYNAMIC_FILE_READ + int count; +#endif /* LWIP_HTTPD_DYNAMIC_FILE_READ */ + + /* Do we have a valid file handle? */ + if (hs->handle == NULL) { + /* No - close the connection. */ + http_eof(pcb, hs); + return 0; + } + if (fs_bytes_left(hs->handle) <= 0) { + /* We reached the end of the file so this request is done. */ + LWIP_DEBUGF(HTTPD_DEBUG, ("End of file.\n")); + http_eof(pcb, hs); + return 0; + } +#if LWIP_HTTPD_DYNAMIC_FILE_READ + /* Do we already have a send buffer allocated? */ + if(hs->buf) { + /* Yes - get the length of the buffer */ + count = hs->buf_len; + } else { + /* We don't have a send buffer so allocate one up to 2mss bytes long. */ + count = 2 * tcp_mss(pcb); + do { + hs->buf = (char*)mem_malloc((mem_size_t)count); + if (hs->buf != NULL) { + hs->buf_len = count; + break; + } + count = count / 2; + } while (count > 100); + + /* Did we get a send buffer? If not, return immediately. */ + if (hs->buf == NULL) { + LWIP_DEBUGF(HTTPD_DEBUG, ("No buff\n")); + return 0; + } + } + + /* Read a block of data from the file. */ + LWIP_DEBUGF(HTTPD_DEBUG, ("Trying to read %d bytes.\n", count)); + +#if LWIP_HTTPD_FS_ASYNC_READ + count = fs_read_async(hs->handle, hs->buf, count, http_continue, hs); +#else /* LWIP_HTTPD_FS_ASYNC_READ */ + count = fs_read(hs->handle, hs->buf, count); +#endif /* LWIP_HTTPD_FS_ASYNC_READ */ + if (count < 0) { + if (count == FS_READ_DELAYED) { + /* Delayed read, wait for FS to unblock us */ + return 0; + } + /* We reached the end of the file so this request is done. + * @todo: don't close here for HTTP/1.1? */ + LWIP_DEBUGF(HTTPD_DEBUG, ("End of file.\n")); + http_eof(pcb, hs); + return 0; + } + + /* Set up to send the block of data we just read */ + LWIP_DEBUGF(HTTPD_DEBUG, ("Read %d bytes.\n", count)); + hs->left = count; + hs->file = hs->buf; +#if LWIP_HTTPD_SSI + if (hs->ssi) { + hs->ssi->parse_left = count; + hs->ssi->parsed = hs->buf; + } +#endif /* LWIP_HTTPD_SSI */ +#else /* LWIP_HTTPD_DYNAMIC_FILE_READ */ + LWIP_ASSERT("SSI and DYNAMIC_HEADERS turned off but eof not reached", 0); +#endif /* LWIP_HTTPD_SSI || LWIP_HTTPD_DYNAMIC_HEADERS */ + return 1; +} + +/** Sub-function of http_send(): This is the normal send-routine for non-ssi files + * + * @returns: - 1: data has been written (so call tcp_ouput) + * - 0: no data has been written (no need to call tcp_output) + */ +static u8_t +http_send_data_nonssi(struct tcp_pcb *pcb, struct http_state *hs) +{ + err_t err; + u16_t len; + u16_t mss; + u8_t data_to_send = 0; + + /* We are not processing an SHTML file so no tag checking is necessary. + * Just send the data as we received it from the file. */ + + /* We cannot send more data than space available in the send + buffer. */ + if (tcp_sndbuf(pcb) < hs->left) { + len = tcp_sndbuf(pcb); + } else { + len = (u16_t)hs->left; + LWIP_ASSERT("hs->left did not fit into u16_t!", (len == hs->left)); + } + mss = tcp_mss(pcb); + if (len > (2 * mss)) { + len = 2 * mss; + } + + err = http_write(pcb, hs->file, &len, HTTP_IS_DATA_VOLATILE(hs)); + if (err == ERR_OK) { + data_to_send = 1; + hs->file += len; + hs->left -= len; + } + + return data_to_send; +} + +#if LWIP_HTTPD_SSI +/** Sub-function of http_send(): This is the send-routine for ssi files + * + * @returns: - 1: data has been written (so call tcp_ouput) + * - 0: no data has been written (no need to call tcp_output) + */ +static u8_t +http_send_data_ssi(struct tcp_pcb *pcb, struct http_state *hs) +{ + err_t err = ERR_OK; + u16_t len; + u16_t mss; + u8_t data_to_send = 0; + + struct http_ssi_state *ssi = hs->ssi; + LWIP_ASSERT("ssi != NULL", ssi != NULL); + /* We are processing an SHTML file so need to scan for tags and replace + * them with insert strings. We need to be careful here since a tag may + * straddle the boundary of two blocks read from the file and we may also + * have to split the insert string between two tcp_write operations. */ + + /* How much data could we send? */ + len = tcp_sndbuf(pcb); + + /* Do we have remaining data to send before parsing more? */ + if(ssi->parsed > hs->file) { + /* We cannot send more data than space available in the send + buffer. */ + if (tcp_sndbuf(pcb) < (ssi->parsed - hs->file)) { + len = tcp_sndbuf(pcb); + } else { + LWIP_ASSERT("Data size does not fit into u16_t!", + (ssi->parsed - hs->file) <= 0xffff); + len = (u16_t)(ssi->parsed - hs->file); + } + mss = tcp_mss(pcb); + if(len > (2 * mss)) { + len = 2 * mss; + } + + err = http_write(pcb, hs->file, &len, HTTP_IS_DATA_VOLATILE(hs)); + if (err == ERR_OK) { + data_to_send = 1; + hs->file += len; + hs->left -= len; + } + + /* If the send buffer is full, return now. */ + if(tcp_sndbuf(pcb) == 0) { + return data_to_send; + } + } + + LWIP_DEBUGF(HTTPD_DEBUG, ("State %d, %d left\n", ssi->tag_state, (int)ssi->parse_left)); + + /* We have sent all the data that was already parsed so continue parsing + * the buffer contents looking for SSI tags. */ + while((ssi->parse_left) && (err == ERR_OK)) { + /* @todo: somewhere in this loop, 'len' should grow again... */ + if (len == 0) { + return data_to_send; + } + switch(ssi->tag_state) { + case TAG_NONE: + /* We are not currently processing an SSI tag so scan for the + * start of the lead-in marker. */ + if(*ssi->parsed == g_pcTagLeadIn[0]) { + /* We found what could be the lead-in for a new tag so change + * state appropriately. */ + ssi->tag_state = TAG_LEADIN; + ssi->tag_index = 1; +#if !LWIP_HTTPD_SSI_INCLUDE_TAG + ssi->tag_started = ssi->parsed; +#endif /* !LWIP_HTTPD_SSI_INCLUDE_TAG */ + } + + /* Move on to the next character in the buffer */ + ssi->parse_left--; + ssi->parsed++; + break; + + case TAG_LEADIN: + /* We are processing the lead-in marker, looking for the start of + * the tag name. */ + + /* Have we reached the end of the leadin? */ + if(ssi->tag_index == LEN_TAG_LEAD_IN) { + ssi->tag_index = 0; + ssi->tag_state = TAG_FOUND; + } else { + /* Have we found the next character we expect for the tag leadin? */ + if(*ssi->parsed == g_pcTagLeadIn[ssi->tag_index]) { + /* Yes - move to the next one unless we have found the complete + * leadin, in which case we start looking for the tag itself */ + ssi->tag_index++; + } else { + /* We found an unexpected character so this is not a tag. Move + * back to idle state. */ + ssi->tag_state = TAG_NONE; + } + + /* Move on to the next character in the buffer */ + ssi->parse_left--; + ssi->parsed++; + } + break; + + case TAG_FOUND: + /* We are reading the tag name, looking for the start of the + * lead-out marker and removing any whitespace found. */ + + /* Remove leading whitespace between the tag leading and the first + * tag name character. */ + if((ssi->tag_index == 0) && ((*ssi->parsed == ' ') || + (*ssi->parsed == '\t') || (*ssi->parsed == '\n') || + (*ssi->parsed == '\r'))) { + /* Move on to the next character in the buffer */ + ssi->parse_left--; + ssi->parsed++; + break; + } + + /* Have we found the end of the tag name? This is signalled by + * us finding the first leadout character or whitespace */ + if((*ssi->parsed == g_pcTagLeadOut[0]) || + (*ssi->parsed == ' ') || (*ssi->parsed == '\t') || + (*ssi->parsed == '\n') || (*ssi->parsed == '\r')) { + + if(ssi->tag_index == 0) { + /* We read a zero length tag so ignore it. */ + ssi->tag_state = TAG_NONE; + } else { + /* We read a non-empty tag so go ahead and look for the + * leadout string. */ + ssi->tag_state = TAG_LEADOUT; + LWIP_ASSERT("ssi->tag_index <= 0xff", ssi->tag_index <= 0xff); + ssi->tag_name_len = (u8_t)ssi->tag_index; + ssi->tag_name[ssi->tag_index] = '\0'; + if(*ssi->parsed == g_pcTagLeadOut[0]) { + ssi->tag_index = 1; + } else { + ssi->tag_index = 0; + } + } + } else { + /* This character is part of the tag name so save it */ + if(ssi->tag_index < LWIP_HTTPD_MAX_TAG_NAME_LEN) { + ssi->tag_name[ssi->tag_index++] = *ssi->parsed; + } else { + /* The tag was too long so ignore it. */ + ssi->tag_state = TAG_NONE; + } + } + + /* Move on to the next character in the buffer */ + ssi->parse_left--; + ssi->parsed++; + + break; + + /* We are looking for the end of the lead-out marker. */ + case TAG_LEADOUT: + /* Remove leading whitespace between the tag leading and the first + * tag leadout character. */ + if((ssi->tag_index == 0) && ((*ssi->parsed == ' ') || + (*ssi->parsed == '\t') || (*ssi->parsed == '\n') || + (*ssi->parsed == '\r'))) { + /* Move on to the next character in the buffer */ + ssi->parse_left--; + ssi->parsed++; + break; + } + + /* Have we found the next character we expect for the tag leadout? */ + if(*ssi->parsed == g_pcTagLeadOut[ssi->tag_index]) { + /* Yes - move to the next one unless we have found the complete + * leadout, in which case we need to call the client to process + * the tag. */ + + /* Move on to the next character in the buffer */ + ssi->parse_left--; + ssi->parsed++; + + if(ssi->tag_index == (LEN_TAG_LEAD_OUT - 1)) { + /* Call the client to ask for the insert string for the + * tag we just found. */ +#if LWIP_HTTPD_SSI_MULTIPART + ssi->tag_part = 0; /* start with tag part 0 */ +#endif /* LWIP_HTTPD_SSI_MULTIPART */ + get_tag_insert(hs); + + /* Next time through, we are going to be sending data + * immediately, either the end of the block we start + * sending here or the insert string. */ + ssi->tag_index = 0; + ssi->tag_state = TAG_SENDING; + ssi->tag_end = ssi->parsed; +#if !LWIP_HTTPD_SSI_INCLUDE_TAG + ssi->parsed = ssi->tag_started; +#endif /* !LWIP_HTTPD_SSI_INCLUDE_TAG*/ + + /* If there is any unsent data in the buffer prior to the + * tag, we need to send it now. */ + if (ssi->tag_end > hs->file) { + /* How much of the data can we send? */ +#if LWIP_HTTPD_SSI_INCLUDE_TAG + if(len > ssi->tag_end - hs->file) { + len = (u16_t)(ssi->tag_end - hs->file); + } +#else /* LWIP_HTTPD_SSI_INCLUDE_TAG*/ + if(len > ssi->tag_started - hs->file) { + /* we would include the tag in sending */ + len = (u16_t)(ssi->tag_started - hs->file); + } +#endif /* LWIP_HTTPD_SSI_INCLUDE_TAG*/ + + err = http_write(pcb, hs->file, &len, HTTP_IS_DATA_VOLATILE(hs)); + if (err == ERR_OK) { + data_to_send = 1; +#if !LWIP_HTTPD_SSI_INCLUDE_TAG + if(ssi->tag_started <= hs->file) { + /* pretend to have sent the tag, too */ + len += ssi->tag_end - ssi->tag_started; + } +#endif /* !LWIP_HTTPD_SSI_INCLUDE_TAG*/ + hs->file += len; + hs->left -= len; + } + } + } else { + ssi->tag_index++; + } + } else { + /* We found an unexpected character so this is not a tag. Move + * back to idle state. */ + ssi->parse_left--; + ssi->parsed++; + ssi->tag_state = TAG_NONE; + } + break; + + /* + * We have found a valid tag and are in the process of sending + * data as a result of that discovery. We send either remaining data + * from the file prior to the insert point or the insert string itself. + */ + case TAG_SENDING: + /* Do we have any remaining file data to send from the buffer prior + * to the tag? */ + if(ssi->tag_end > hs->file) { + /* How much of the data can we send? */ +#if LWIP_HTTPD_SSI_INCLUDE_TAG + if(len > ssi->tag_end - hs->file) { + len = (u16_t)(ssi->tag_end - hs->file); + } +#else /* LWIP_HTTPD_SSI_INCLUDE_TAG*/ + LWIP_ASSERT("hs->started >= hs->file", ssi->tag_started >= hs->file); + if (len > ssi->tag_started - hs->file) { + /* we would include the tag in sending */ + len = (u16_t)(ssi->tag_started - hs->file); + } +#endif /* LWIP_HTTPD_SSI_INCLUDE_TAG*/ + if (len != 0) { + err = http_write(pcb, hs->file, &len, HTTP_IS_DATA_VOLATILE(hs)); + } else { + err = ERR_OK; + } + if (err == ERR_OK) { + data_to_send = 1; +#if !LWIP_HTTPD_SSI_INCLUDE_TAG + if(ssi->tag_started <= hs->file) { + /* pretend to have sent the tag, too */ + len += ssi->tag_end - ssi->tag_started; + } +#endif /* !LWIP_HTTPD_SSI_INCLUDE_TAG*/ + hs->file += len; + hs->left -= len; + } + } else { +#if LWIP_HTTPD_SSI_MULTIPART + if(ssi->tag_index >= ssi->tag_insert_len) { + /* Did the last SSIHandler have more to send? */ + if (ssi->tag_part != HTTPD_LAST_TAG_PART) { + /* If so, call it again */ + ssi->tag_index = 0; + get_tag_insert(hs); + } + } +#endif /* LWIP_HTTPD_SSI_MULTIPART */ + + /* Do we still have insert data left to send? */ + if(ssi->tag_index < ssi->tag_insert_len) { + /* We are sending the insert string itself. How much of the + * insert can we send? */ + if(len > (ssi->tag_insert_len - ssi->tag_index)) { + len = (ssi->tag_insert_len - ssi->tag_index); + } + + /* Note that we set the copy flag here since we only have a + * single tag insert buffer per connection. If we don't do + * this, insert corruption can occur if more than one insert + * is processed before we call tcp_output. */ + err = http_write(pcb, &(ssi->tag_insert[ssi->tag_index]), &len, + HTTP_IS_TAG_VOLATILE(hs)); + if (err == ERR_OK) { + data_to_send = 1; + ssi->tag_index += len; + /* Don't return here: keep on sending data */ + } + } else { +#if LWIP_HTTPD_SSI_MULTIPART + if (ssi->tag_part == HTTPD_LAST_TAG_PART) +#endif /* LWIP_HTTPD_SSI_MULTIPART */ + { + /* We have sent all the insert data so go back to looking for + * a new tag. */ + LWIP_DEBUGF(HTTPD_DEBUG, ("Everything sent.\n")); + ssi->tag_index = 0; + ssi->tag_state = TAG_NONE; +#if !LWIP_HTTPD_SSI_INCLUDE_TAG + ssi->parsed = ssi->tag_end; +#endif /* !LWIP_HTTPD_SSI_INCLUDE_TAG*/ + } + } + break; + } + } + } + + /* If we drop out of the end of the for loop, this implies we must have + * file data to send so send it now. In TAG_SENDING state, we've already + * handled this so skip the send if that's the case. */ + if((ssi->tag_state != TAG_SENDING) && (ssi->parsed > hs->file)) { + /* We cannot send more data than space available in the send + buffer. */ + if (tcp_sndbuf(pcb) < (ssi->parsed - hs->file)) { + len = tcp_sndbuf(pcb); + } else { + LWIP_ASSERT("Data size does not fit into u16_t!", + (ssi->parsed - hs->file) <= 0xffff); + len = (u16_t)(ssi->parsed - hs->file); + } + if(len > (2 * tcp_mss(pcb))) { + len = 2 * tcp_mss(pcb); + } + + err = http_write(pcb, hs->file, &len, HTTP_IS_DATA_VOLATILE(hs)); + if (err == ERR_OK) { + data_to_send = 1; + hs->file += len; + hs->left -= len; + } + } + return data_to_send; +} +#endif /* LWIP_HTTPD_SSI */ + +/** + * Try to send more data on this pcb. + * + * @param pcb the pcb to send data + * @param hs connection state + */ +static u8_t +http_send(struct tcp_pcb *pcb, struct http_state *hs) +{ + u8_t data_to_send = HTTP_NO_DATA_TO_SEND; + + LWIP_DEBUGF(HTTPD_DEBUG | LWIP_DBG_TRACE, ("http_send: pcb=%p hs=%p left=%d\n", (void*)pcb, + (void*)hs, hs != NULL ? (int)hs->left : 0)); + +#if LWIP_HTTPD_SUPPORT_POST && LWIP_HTTPD_POST_MANUAL_WND + if (hs->unrecved_bytes != 0) { + return 0; + } +#endif /* LWIP_HTTPD_SUPPORT_POST && LWIP_HTTPD_POST_MANUAL_WND */ + + /* If we were passed a NULL state structure pointer, ignore the call. */ + if (hs == NULL) { + return 0; + } + +#if LWIP_HTTPD_FS_ASYNC_READ + /* Check if we are allowed to read from this file. + (e.g. SSI might want to delay sending until data is available) */ + if (!fs_is_file_ready(hs->handle, http_continue, hs)) { + return 0; + } +#endif /* LWIP_HTTPD_FS_ASYNC_READ */ + +#if LWIP_HTTPD_DYNAMIC_HEADERS + /* Do we have any more header data to send for this file? */ + if(hs->hdr_index < NUM_FILE_HDR_STRINGS) { + data_to_send = http_send_headers(pcb, hs); + if (data_to_send != HTTP_DATA_TO_SEND_CONTINUE) { + return data_to_send; + } + } +#endif /* LWIP_HTTPD_DYNAMIC_HEADERS */ + + /* Have we run out of file data to send? If so, we need to read the next + * block from the file. */ + if (hs->left == 0) { + if (!http_check_eof(pcb, hs)) { + return 0; + } + } + +#if LWIP_HTTPD_SSI + if(hs->ssi) { + data_to_send = http_send_data_ssi(pcb, hs); + } else +#endif /* LWIP_HTTPD_SSI */ + { + data_to_send = http_send_data_nonssi(pcb, hs); + } + + if((hs->left == 0) && (fs_bytes_left(hs->handle) <= 0)) { + /* We reached the end of the file so this request is done. + * This adds the FIN flag right into the last data segment. */ + LWIP_DEBUGF(HTTPD_DEBUG, ("End of file.\n")); + http_eof(pcb, hs); + return 0; + } + LWIP_DEBUGF(HTTPD_DEBUG | LWIP_DBG_TRACE, ("send_data end.\n")); + return data_to_send; +} + +#if LWIP_HTTPD_SUPPORT_EXTSTATUS +/** Initialize a http connection with a file to send for an error message + * + * @param hs http connection state + * @param error_nr HTTP error number + * @return ERR_OK if file was found and hs has been initialized correctly + * another err_t otherwise + */ +static err_t +http_find_error_file(struct http_state *hs, u16_t error_nr) +{ + const char *uri1, *uri2, *uri3; + err_t err; + + if (error_nr == 501) { + uri1 = "/501.html"; + uri2 = "/501.htm"; + uri3 = "/501.shtml"; + } else { + /* 400 (bad request is the default) */ + uri1 = "/400.html"; + uri2 = "/400.htm"; + uri3 = "/400.shtml"; + } + err = fs_open(&hs->file_handle, uri1); + if (err != ERR_OK) { + err = fs_open(&hs->file_handle, uri2); + if (err != ERR_OK) { + err = fs_open(&hs->file_handle, uri3); + if (err != ERR_OK) { + LWIP_DEBUGF(HTTPD_DEBUG, ("Error page for error %"U16_F" not found\n", + error_nr)); + return ERR_ARG; + } + } + } + return http_init_file(hs, &hs->file_handle, 0, NULL, 0); +} +#else /* LWIP_HTTPD_SUPPORT_EXTSTATUS */ +#define http_find_error_file(hs, error_nr) ERR_ARG +#endif /* LWIP_HTTPD_SUPPORT_EXTSTATUS */ + +/** + * Get the file struct for a 404 error page. + * Tries some file names and returns NULL if none found. + * + * @param uri pointer that receives the actual file name URI + * @return file struct for the error page or NULL no matching file was found + */ +static struct fs_file * +http_get_404_file(struct http_state *hs, const char **uri) +{ + err_t err; + + *uri = "/404.html"; + err = fs_open(&hs->file_handle, *uri); + if (err != ERR_OK) { + /* 404.html doesn't exist. Try 404.htm instead. */ + *uri = "/404.htm"; + err = fs_open(&hs->file_handle, *uri); + if (err != ERR_OK) { + /* 404.htm doesn't exist either. Try 404.shtml instead. */ + *uri = "/404.shtml"; + err = fs_open(&hs->file_handle, *uri); + if (err != ERR_OK) { + /* 404.htm doesn't exist either. Indicate to the caller that it should + * send back a default 404 page. + */ + *uri = NULL; + return NULL; + } + } + } + + return &hs->file_handle; +} + +#if LWIP_HTTPD_SUPPORT_POST +static err_t +http_handle_post_finished(struct http_state *hs) +{ +#if LWIP_HTTPD_POST_MANUAL_WND + /* Prevent multiple calls to httpd_post_finished, since it might have already + been called before from httpd_post_data_recved(). */ + if (hs->post_finished) { + return ERR_OK; + } + hs->post_finished = 1; +#endif /* LWIP_HTTPD_POST_MANUAL_WND */ + /* application error or POST finished */ + /* NULL-terminate the buffer */ + http_post_response_filename[0] = 0; + httpd_post_finished(hs, http_post_response_filename, LWIP_HTTPD_POST_MAX_RESPONSE_URI_LEN); + return http_find_file(hs, http_post_response_filename, 0); +} + +/** Pass received POST body data to the application and correctly handle + * returning a response document or closing the connection. + * ATTENTION: The application is responsible for the pbuf now, so don't free it! + * + * @param hs http connection state + * @param p pbuf to pass to the application + * @return ERR_OK if passed successfully, another err_t if the response file + * hasn't been found (after POST finished) + */ +static err_t +http_post_rxpbuf(struct http_state *hs, struct pbuf *p) +{ + err_t err; + + /* adjust remaining Content-Length */ + if (hs->post_content_len_left < p->tot_len) { + hs->post_content_len_left = 0; + } else { + hs->post_content_len_left -= p->tot_len; + } + err = httpd_post_receive_data(hs, p); + if ((err != ERR_OK) || (hs->post_content_len_left == 0)) { +#if LWIP_HTTPD_SUPPORT_POST && LWIP_HTTPD_POST_MANUAL_WND + if (hs->unrecved_bytes != 0) { + return ERR_OK; + } +#endif /* LWIP_HTTPD_SUPPORT_POST && LWIP_HTTPD_POST_MANUAL_WND */ + /* application error or POST finished */ + return http_handle_post_finished(hs); + } + + return ERR_OK; +} + +/** Handle a post request. Called from http_parse_request when method 'POST' + * is found. + * + * @param p The input pbuf (containing the POST header and body). + * @param hs The http connection state. + * @param data HTTP request (header and part of body) from input pbuf(s). + * @param data_len Size of 'data'. + * @param uri The HTTP URI parsed from input pbuf(s). + * @param uri_end Pointer to the end of 'uri' (here, the rest of the HTTP + * header starts). + * @return ERR_OK: POST correctly parsed and accepted by the application. + * ERR_INPROGRESS: POST not completely parsed (no error yet) + * another err_t: Error parsing POST or denied by the application + */ +static err_t +http_post_request(struct pbuf **inp, struct http_state *hs, + char *data, u16_t data_len, char *uri, char *uri_end) +{ + err_t err; + /* search for end-of-header (first double-CRLF) */ + char* crlfcrlf = strnstr(uri_end + 1, CRLF CRLF, data_len - (uri_end + 1 - data)); + + if (crlfcrlf != NULL) { + /* search for "Content-Length: " */ +#define HTTP_HDR_CONTENT_LEN "Content-Length: " +#define HTTP_HDR_CONTENT_LEN_LEN 16 +#define HTTP_HDR_CONTENT_LEN_DIGIT_MAX_LEN 10 + char *scontent_len = strnstr(uri_end + 1, HTTP_HDR_CONTENT_LEN, crlfcrlf - (uri_end + 1)); + if (scontent_len != NULL) { + char *scontent_len_end = strnstr(scontent_len + HTTP_HDR_CONTENT_LEN_LEN, CRLF, HTTP_HDR_CONTENT_LEN_DIGIT_MAX_LEN); + if (scontent_len_end != NULL) { + int content_len; + char *conten_len_num = scontent_len + HTTP_HDR_CONTENT_LEN_LEN; + *scontent_len_end = 0; + content_len = atoi(conten_len_num); + if (content_len > 0) { + /* adjust length of HTTP header passed to application */ + const char *hdr_start_after_uri = uri_end + 1; + u16_t hdr_len = LWIP_MIN(data_len, crlfcrlf + 4 - data); + u16_t hdr_data_len = LWIP_MIN(data_len, crlfcrlf + 4 - hdr_start_after_uri); + u8_t post_auto_wnd = 1; + http_post_response_filename[0] = 0; + err = httpd_post_begin(hs, uri, hdr_start_after_uri, hdr_data_len, content_len, + http_post_response_filename, LWIP_HTTPD_POST_MAX_RESPONSE_URI_LEN, &post_auto_wnd); + if (err == ERR_OK) { + /* try to pass in data of the first pbuf(s) */ + struct pbuf *q = *inp; + u16_t start_offset = hdr_len; +#if LWIP_HTTPD_POST_MANUAL_WND + hs->no_auto_wnd = !post_auto_wnd; +#endif /* LWIP_HTTPD_POST_MANUAL_WND */ + /* set the Content-Length to be received for this POST */ + hs->post_content_len_left = (u32_t)content_len; + + /* get to the pbuf where the body starts */ + while((q != NULL) && (q->len <= start_offset)) { + struct pbuf *head = q; + start_offset -= q->len; + q = q->next; + /* free the head pbuf */ + head->next = NULL; + pbuf_free(head); + } + *inp = NULL; + if (q != NULL) { + /* hide the remaining HTTP header */ + pbuf_header(q, -(s16_t)start_offset); +#if LWIP_HTTPD_POST_MANUAL_WND + if (!post_auto_wnd) { + /* already tcp_recved() this data... */ + hs->unrecved_bytes = q->tot_len; + } +#endif /* LWIP_HTTPD_POST_MANUAL_WND */ + return http_post_rxpbuf(hs, q); + } else { + return ERR_OK; + } + } else { + /* return file passed from application */ + return http_find_file(hs, http_post_response_filename, 0); + } + } else { + LWIP_DEBUGF(HTTPD_DEBUG, ("POST received invalid Content-Length: %s\n", + conten_len_num)); + return ERR_ARG; + } + } + } + } + /* if we come here, the POST is incomplete */ +#if LWIP_HTTPD_SUPPORT_REQUESTLIST + return ERR_INPROGRESS; +#else /* LWIP_HTTPD_SUPPORT_REQUESTLIST */ + return ERR_ARG; +#endif /* LWIP_HTTPD_SUPPORT_REQUESTLIST */ +} + +#if LWIP_HTTPD_POST_MANUAL_WND +/** A POST implementation can call this function to update the TCP window. + * This can be used to throttle data reception (e.g. when received data is + * programmed to flash and data is received faster than programmed). + * + * @param connection A connection handle passed to httpd_post_begin for which + * httpd_post_finished has *NOT* been called yet! + * @param recved_len Length of data received (for window update) + */ +void httpd_post_data_recved(void *connection, u16_t recved_len) +{ + struct http_state *hs = (struct http_state*)connection; + if (hs != NULL) { + if (hs->no_auto_wnd) { + u16_t len = recved_len; + if (hs->unrecved_bytes >= recved_len) { + hs->unrecved_bytes -= recved_len; + } else { + LWIP_DEBUGF(HTTPD_DEBUG | LWIP_DBG_LEVEL_WARNING, ("httpd_post_data_recved: recved_len too big\n")); + len = (u16_t)hs->unrecved_bytes; + hs->unrecved_bytes = 0; + } + if (hs->pcb != NULL) { + if (len != 0) { + tcp_recved(hs->pcb, len); + } + if ((hs->post_content_len_left == 0) && (hs->unrecved_bytes == 0)) { + /* finished handling POST */ + http_handle_post_finished(hs); + http_send(hs->pcb, hs); + } + } + } + } +} +#endif /* LWIP_HTTPD_POST_MANUAL_WND */ + +#endif /* LWIP_HTTPD_SUPPORT_POST */ + +#if LWIP_HTTPD_FS_ASYNC_READ +/** Try to send more data if file has been blocked before + * This is a callback function passed to fs_read_async(). + */ +static void +http_continue(void *connection) +{ + struct http_state *hs = (struct http_state*)connection; + if (hs && (hs->pcb) && (hs->handle)) { + LWIP_ASSERT("hs->pcb != NULL", hs->pcb != NULL); + LWIP_DEBUGF(HTTPD_DEBUG | LWIP_DBG_TRACE, ("httpd_continue: try to send more data\n")); + if (http_send(hs->pcb, hs)) { + /* If we wrote anything to be sent, go ahead and send it now. */ + LWIP_DEBUGF(HTTPD_DEBUG | LWIP_DBG_TRACE, ("tcp_output\n")); + tcp_output(hs->pcb); + } + } +} +#endif /* LWIP_HTTPD_FS_ASYNC_READ */ + +/** + * When data has been received in the correct state, try to parse it + * as a HTTP request. + * + * @param p the received pbuf + * @param hs the connection state + * @param pcb the tcp_pcb which received this packet + * @return ERR_OK if request was OK and hs has been initialized correctly + * ERR_INPROGRESS if request was OK so far but not fully received + * another err_t otherwise + */ +static err_t +http_parse_request(struct pbuf **inp, struct http_state *hs, struct tcp_pcb *pcb) +{ + char *data; + char *crlf; + u16_t data_len; + struct pbuf *p = *inp; +#if LWIP_HTTPD_SUPPORT_REQUESTLIST + u16_t clen; +#endif /* LWIP_HTTPD_SUPPORT_REQUESTLIST */ +#if LWIP_HTTPD_SUPPORT_POST + err_t err; +#endif /* LWIP_HTTPD_SUPPORT_POST */ + + LWIP_UNUSED_ARG(pcb); /* only used for post */ + LWIP_ASSERT("p != NULL", p != NULL); + LWIP_ASSERT("hs != NULL", hs != NULL); + + if ((hs->handle != NULL) || (hs->file != NULL)) { + LWIP_DEBUGF(HTTPD_DEBUG, ("Received data while sending a file\n")); + /* already sending a file */ + /* @todo: abort? */ + return ERR_USE; + } + +#if LWIP_HTTPD_SUPPORT_REQUESTLIST + + LWIP_DEBUGF(HTTPD_DEBUG, ("Received %"U16_F" bytes\n", p->tot_len)); + + /* first check allowed characters in this pbuf? */ + + /* enqueue the pbuf */ + if (hs->req == NULL) { + LWIP_DEBUGF(HTTPD_DEBUG, ("First pbuf\n")); + hs->req = p; + } else { + LWIP_DEBUGF(HTTPD_DEBUG, ("pbuf enqueued\n")); + pbuf_cat(hs->req, p); + } + + if (hs->req->next != NULL) { + data_len = LWIP_MIN(hs->req->tot_len, LWIP_HTTPD_MAX_REQ_LENGTH); + pbuf_copy_partial(hs->req, httpd_req_buf, data_len, 0); + data = httpd_req_buf; + } else +#endif /* LWIP_HTTPD_SUPPORT_REQUESTLIST */ + { + data = (char *)p->payload; + data_len = p->len; + if (p->len != p->tot_len) { + LWIP_DEBUGF(HTTPD_DEBUG, ("Warning: incomplete header due to chained pbufs\n")); + } + } + + /* received enough data for minimal request? */ + if (data_len >= MIN_REQ_LEN) { + /* wait for CRLF before parsing anything */ + crlf = strnstr(data, CRLF, data_len); + if (crlf != NULL) { +#if LWIP_HTTPD_SUPPORT_POST + int is_post = 0; +#endif /* LWIP_HTTPD_SUPPORT_POST */ + int is_09 = 0; + char *sp1, *sp2; + u16_t left_len, uri_len; + LWIP_DEBUGF(HTTPD_DEBUG | LWIP_DBG_TRACE, ("CRLF received, parsing request\n")); + /* parse method */ + if (!strncmp(data, "GET ", 4)) { + sp1 = data + 3; + /* received GET request */ + LWIP_DEBUGF(HTTPD_DEBUG | LWIP_DBG_TRACE, ("Received GET request\"\n")); +#if LWIP_HTTPD_SUPPORT_POST + } else if (!strncmp(data, "POST ", 5)) { + /* store request type */ + is_post = 1; + sp1 = data + 4; + /* received GET request */ + LWIP_DEBUGF(HTTPD_DEBUG | LWIP_DBG_TRACE, ("Received POST request\n")); +#endif /* LWIP_HTTPD_SUPPORT_POST */ + } else { + /* null-terminate the METHOD (pbuf is freed anyway wen returning) */ + data[4] = 0; + /* unsupported method! */ + LWIP_DEBUGF(HTTPD_DEBUG, ("Unsupported request method (not implemented): \"%s\"\n", + data)); + return http_find_error_file(hs, 501); + } + /* if we come here, method is OK, parse URI */ + left_len = data_len - ((sp1 +1) - data); + sp2 = strnstr(sp1 + 1, " ", left_len); +#if LWIP_HTTPD_SUPPORT_V09 + if (sp2 == NULL) { + /* HTTP 0.9: respond with correct protocol version */ + sp2 = strnstr(sp1 + 1, CRLF, left_len); + is_09 = 1; +#if LWIP_HTTPD_SUPPORT_POST + if (is_post) { + /* HTTP/0.9 does not support POST */ + goto badrequest; + } +#endif /* LWIP_HTTPD_SUPPORT_POST */ + } +#endif /* LWIP_HTTPD_SUPPORT_V09 */ + uri_len = sp2 - (sp1 + 1); + if ((sp2 != 0) && (sp2 > sp1)) { + /* wait for CRLFCRLF (indicating end of HTTP headers) before parsing anything */ + if (strnstr(data, CRLF CRLF, data_len) != NULL) { + char *uri = sp1 + 1; +#if LWIP_HTTPD_SUPPORT_11_KEEPALIVE + if (!is_09 && strnstr(data, HTTP11_CONNECTIONKEEPALIVE, data_len)) { + hs->keepalive = 1; + } +#endif /* LWIP_HTTPD_SUPPORT_11_KEEPALIVE */ + /* null-terminate the METHOD (pbuf is freed anyway wen returning) */ + *sp1 = 0; + uri[uri_len] = 0; + LWIP_DEBUGF(HTTPD_DEBUG, ("Received \"%s\" request for URI: \"%s\"\n", + data, uri)); +#if LWIP_HTTPD_SUPPORT_POST + if (is_post) { +#if LWIP_HTTPD_SUPPORT_REQUESTLIST + struct pbuf **q = &hs->req; +#else /* LWIP_HTTPD_SUPPORT_REQUESTLIST */ + struct pbuf **q = inp; +#endif /* LWIP_HTTPD_SUPPORT_REQUESTLIST */ + err = http_post_request(q, hs, data, data_len, uri, sp2); + if (err != ERR_OK) { + /* restore header for next try */ + *sp1 = ' '; + *sp2 = ' '; + uri[uri_len] = ' '; + } + if (err == ERR_ARG) { + goto badrequest; + } + return err; + } else +#endif /* LWIP_HTTPD_SUPPORT_POST */ + { + return http_find_file(hs, uri, is_09); + } + } + } else { + LWIP_DEBUGF(HTTPD_DEBUG, ("invalid URI\n")); + } + } + } + +#if LWIP_HTTPD_SUPPORT_REQUESTLIST + clen = pbuf_clen(hs->req); + if ((hs->req->tot_len <= LWIP_HTTPD_REQ_BUFSIZE) && + (clen <= LWIP_HTTPD_REQ_QUEUELEN)) { + /* request not fully received (too short or CRLF is missing) */ + return ERR_INPROGRESS; + } else +#endif /* LWIP_HTTPD_SUPPORT_REQUESTLIST */ + { +#if LWIP_HTTPD_SUPPORT_POST +badrequest: +#endif /* LWIP_HTTPD_SUPPORT_POST */ + LWIP_DEBUGF(HTTPD_DEBUG, ("bad request\n")); + /* could not parse request */ + return http_find_error_file(hs, 400); + } +} + +/** Try to find the file specified by uri and, if found, initialize hs + * accordingly. + * + * @param hs the connection state + * @param uri the HTTP header URI + * @param is_09 1 if the request is HTTP/0.9 (no HTTP headers in response) + * @return ERR_OK if file was found and hs has been initialized correctly + * another err_t otherwise + */ +static err_t +http_find_file(struct http_state *hs, const char *uri, int is_09) +{ + size_t loop; + struct fs_file *file = NULL; + char *params; + err_t err; +#if LWIP_HTTPD_CGI + int i; + int count; +#endif /* LWIP_HTTPD_CGI */ +#if !LWIP_HTTPD_SSI + const +#endif /* !LWIP_HTTPD_SSI */ + /* By default, assume we will not be processing server-side-includes tags */ + u8_t tag_check = 0; + + /* Have we been asked for the default root file? */ + if((uri[0] == '/') && (uri[1] == 0)) { + /* Try each of the configured default filenames until we find one + that exists. */ + for (loop = 0; loop < NUM_DEFAULT_FILENAMES; loop++) { + LWIP_DEBUGF(HTTPD_DEBUG | LWIP_DBG_TRACE, ("Looking for %s...\n", g_psDefaultFilenames[loop].name)); + err = fs_open(&hs->file_handle, (char *)g_psDefaultFilenames[loop].name); + uri = (char *)g_psDefaultFilenames[loop].name; + if(err == ERR_OK) { + file = &hs->file_handle; + LWIP_DEBUGF(HTTPD_DEBUG | LWIP_DBG_TRACE, ("Opened.\n")); +#if LWIP_HTTPD_SSI + tag_check = g_psDefaultFilenames[loop].shtml; +#endif /* LWIP_HTTPD_SSI */ + break; + } + } + if (file == NULL) { + /* None of the default filenames exist so send back a 404 page */ + file = http_get_404_file(hs, &uri); +#if LWIP_HTTPD_SSI + tag_check = 0; +#endif /* LWIP_HTTPD_SSI */ + } + } else { + /* No - we've been asked for a specific file. */ + /* First, isolate the base URI (without any parameters) */ + params = (char *)strchr(uri, '?'); + if (params != NULL) { + /* URI contains parameters. NULL-terminate the base URI */ + *params = '\0'; + params++; + } + +#if LWIP_HTTPD_CGI + /* Does the base URI we have isolated correspond to a CGI handler? */ + if (g_iNumCGIs && g_pCGIs) { + for (i = 0; i < g_iNumCGIs; i++) { + if (strcmp(uri, g_pCGIs[i].pcCGIName) == 0) { + /* + * We found a CGI that handles this URI so extract the + * parameters and call the handler. + */ + count = extract_uri_parameters(hs, params); + uri = g_pCGIs[i].pfnCGIHandler(i, count, hs->params, + hs->param_vals); + break; + } + } + } +#endif /* LWIP_HTTPD_CGI */ + + LWIP_DEBUGF(HTTPD_DEBUG | LWIP_DBG_TRACE, ("Opening %s\n", uri)); + + err = fs_open(&hs->file_handle, uri); + if (err == ERR_OK) { + file = &hs->file_handle; + } else { + file = http_get_404_file(hs, &uri); + } +#if LWIP_HTTPD_SSI + if (file != NULL) { + /* See if we have been asked for an shtml file and, if so, + enable tag checking. */ + tag_check = 0; + for (loop = 0; loop < NUM_SHTML_EXTENSIONS; loop++) { + if (strstr(uri, g_pcSSIExtensions[loop])) { + tag_check = 1; + break; + } + } + } +#endif /* LWIP_HTTPD_SSI */ + } + return http_init_file(hs, file, is_09, uri, tag_check); +} + +/** Initialize a http connection with a file to send (if found). + * Called by http_find_file and http_find_error_file. + * + * @param hs http connection state + * @param file file structure to send (or NULL if not found) + * @param is_09 1 if the request is HTTP/0.9 (no HTTP headers in response) + * @param uri the HTTP header URI + * @param tag_check enable SSI tag checking + * @return ERR_OK if file was found and hs has been initialized correctly + * another err_t otherwise + */ +static err_t +http_init_file(struct http_state *hs, struct fs_file *file, int is_09, const char *uri, u8_t tag_check) +{ + if (file != NULL) { + /* file opened, initialise struct http_state */ +#if LWIP_HTTPD_SSI + if (tag_check) { + struct http_ssi_state *ssi = http_ssi_state_alloc(); + if (ssi != NULL) { + ssi->tag_index = 0; + ssi->tag_state = TAG_NONE; + ssi->parsed = file->data; + ssi->parse_left = file->len; + ssi->tag_end = file->data; + hs->ssi = ssi; + } + } +#else /* LWIP_HTTPD_SSI */ + LWIP_UNUSED_ARG(tag_check); +#endif /* LWIP_HTTPD_SSI */ + hs->handle = file; + hs->file = (char*)file->data; + LWIP_ASSERT("File length must be positive!", (file->len >= 0)); + hs->left = file->len; + hs->retries = 0; +#if LWIP_HTTPD_TIMING + hs->time_started = sys_now(); +#endif /* LWIP_HTTPD_TIMING */ +#if !LWIP_HTTPD_DYNAMIC_HEADERS + LWIP_ASSERT("HTTP headers not included in file system", hs->handle->http_header_included); +#endif /* !LWIP_HTTPD_DYNAMIC_HEADERS */ +#if LWIP_HTTPD_SUPPORT_V09 + if (hs->handle->http_header_included && is_09) { + /* HTTP/0.9 responses are sent without HTTP header, + search for the end of the header. */ + char *file_start = strnstr(hs->file, CRLF CRLF, hs->left); + if (file_start != NULL) { + size_t diff = file_start + 4 - hs->file; + hs->file += diff; + hs->left -= (u32_t)diff; + } + } +#endif /* LWIP_HTTPD_SUPPORT_V09*/ + } else { + hs->handle = NULL; + hs->file = NULL; + hs->left = 0; + hs->retries = 0; + } +#if LWIP_HTTPD_DYNAMIC_HEADERS + /* Determine the HTTP headers to send based on the file extension of + * the requested URI. */ + if ((hs->handle == NULL) || !hs->handle->http_header_included) { + get_http_headers(hs, (char*)uri); + } +#else /* LWIP_HTTPD_DYNAMIC_HEADERS */ + LWIP_UNUSED_ARG(uri); +#endif /* LWIP_HTTPD_DYNAMIC_HEADERS */ + return ERR_OK; +} + +/** + * The pcb had an error and is already deallocated. + * The argument might still be valid (if != NULL). + */ +static void +http_err(void *arg, err_t err) +{ + struct http_state *hs = (struct http_state *)arg; + LWIP_UNUSED_ARG(err); + + LWIP_DEBUGF(HTTPD_DEBUG, ("http_err: %s", lwip_strerr(err))); + + if (hs != NULL) { + http_state_free(hs); + } +} + +/** + * Data has been sent and acknowledged by the remote host. + * This means that more data can be sent. + */ +static err_t +http_sent(void *arg, struct tcp_pcb *pcb, u16_t len) +{ + struct http_state *hs = (struct http_state *)arg; + + LWIP_DEBUGF(HTTPD_DEBUG | LWIP_DBG_TRACE, ("http_sent %p\n", (void*)pcb)); + + LWIP_UNUSED_ARG(len); + + if (hs == NULL) { + return ERR_OK; + } + + hs->retries = 0; + + http_send(pcb, hs); + + return ERR_OK; +} + +/** + * The poll function is called every 2nd second. + * If there has been no data sent (which resets the retries) in 8 seconds, close. + * If the last portion of a file has not been sent in 2 seconds, close. + * + * This could be increased, but we don't want to waste resources for bad connections. + */ +static err_t +http_poll(void *arg, struct tcp_pcb *pcb) +{ + struct http_state *hs = (struct http_state *)arg; + LWIP_DEBUGF(HTTPD_DEBUG | LWIP_DBG_TRACE, ("http_poll: pcb=%p hs=%p pcb_state=%s\n", + (void*)pcb, (void*)hs, tcp_debug_state_str(pcb->state))); + + if (hs == NULL) { + err_t closed; + /* arg is null, close. */ + LWIP_DEBUGF(HTTPD_DEBUG, ("http_poll: arg is NULL, close\n")); + closed = http_close_conn(pcb, NULL); + LWIP_UNUSED_ARG(closed); +#if LWIP_HTTPD_ABORT_ON_CLOSE_MEM_ERROR + if (closed == ERR_MEM) { + tcp_abort(pcb); + return ERR_ABRT; + } +#endif /* LWIP_HTTPD_ABORT_ON_CLOSE_MEM_ERROR */ + return ERR_OK; + } else { + hs->retries++; + if (hs->retries == HTTPD_MAX_RETRIES) { + LWIP_DEBUGF(HTTPD_DEBUG, ("http_poll: too many retries, close\n")); + http_close_conn(pcb, hs); + return ERR_OK; + } + + /* If this connection has a file open, try to send some more data. If + * it has not yet received a GET request, don't do this since it will + * cause the connection to close immediately. */ + if(hs && (hs->handle)) { + LWIP_DEBUGF(HTTPD_DEBUG | LWIP_DBG_TRACE, ("http_poll: try to send more data\n")); + if(http_send(pcb, hs)) { + /* If we wrote anything to be sent, go ahead and send it now. */ + LWIP_DEBUGF(HTTPD_DEBUG | LWIP_DBG_TRACE, ("tcp_output\n")); + tcp_output(pcb); + } + } + } + + return ERR_OK; +} + +/** + * Data has been received on this pcb. + * For HTTP 1.0, this should normally only happen once (if the request fits in one packet). + */ +static err_t +http_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err) +{ + err_t parsed = ERR_ABRT; + struct http_state *hs = (struct http_state *)arg; + LWIP_DEBUGF(HTTPD_DEBUG | LWIP_DBG_TRACE, ("http_recv: pcb=%p pbuf=%p err=%s\n", (void*)pcb, + (void*)p, lwip_strerr(err))); + + if ((err != ERR_OK) || (p == NULL) || (hs == NULL)) { + /* error or closed by other side? */ + if (p != NULL) { + /* Inform TCP that we have taken the data. */ + tcp_recved(pcb, p->tot_len); + pbuf_free(p); + } + if (hs == NULL) { + /* this should not happen, only to be robust */ + LWIP_DEBUGF(HTTPD_DEBUG, ("Error, http_recv: hs is NULL, close\n")); + } + http_close_conn(pcb, hs); + return ERR_OK; + } + +#if LWIP_HTTPD_SUPPORT_POST && LWIP_HTTPD_POST_MANUAL_WND + if (hs->no_auto_wnd) { + hs->unrecved_bytes += p->tot_len; + } else +#endif /* LWIP_HTTPD_SUPPORT_POST && LWIP_HTTPD_POST_MANUAL_WND */ + { + /* Inform TCP that we have taken the data. */ + tcp_recved(pcb, p->tot_len); + } + +#if LWIP_HTTPD_SUPPORT_POST + if (hs->post_content_len_left > 0) { + /* reset idle counter when POST data is received */ + hs->retries = 0; + /* this is data for a POST, pass the complete pbuf to the application */ + http_post_rxpbuf(hs, p); + /* pbuf is passed to the application, don't free it! */ + if (hs->post_content_len_left == 0) { + /* all data received, send response or close connection */ + http_send(pcb, hs); + } + return ERR_OK; + } else +#endif /* LWIP_HTTPD_SUPPORT_POST */ + { + if (hs->handle == NULL) { + parsed = http_parse_request(&p, hs, pcb); + LWIP_ASSERT("http_parse_request: unexpected return value", parsed == ERR_OK + || parsed == ERR_INPROGRESS ||parsed == ERR_ARG || parsed == ERR_USE); + } else { + LWIP_DEBUGF(HTTPD_DEBUG, ("http_recv: already sending data\n")); + } +#if LWIP_HTTPD_SUPPORT_REQUESTLIST + if (parsed != ERR_INPROGRESS) { + /* request fully parsed or error */ + if (hs->req != NULL) { + pbuf_free(hs->req); + hs->req = NULL; + } + } +#else /* LWIP_HTTPD_SUPPORT_REQUESTLIST */ + if (p != NULL) { + /* pbuf not passed to application, free it now */ + pbuf_free(p); + } +#endif /* LWIP_HTTPD_SUPPORT_REQUESTLIST */ + if (parsed == ERR_OK) { +#if LWIP_HTTPD_SUPPORT_POST + if (hs->post_content_len_left == 0) +#endif /* LWIP_HTTPD_SUPPORT_POST */ + { + LWIP_DEBUGF(HTTPD_DEBUG | LWIP_DBG_TRACE, ("http_recv: data %p len %"S32_F"\n", hs->file, hs->left)); + http_send(pcb, hs); + } + } else if (parsed == ERR_ARG) { + /* @todo: close on ERR_USE? */ + http_close_conn(pcb, hs); + } + } + return ERR_OK; +} + +/** + * A new incoming connection has been accepted. + */ +static err_t +http_accept(void *arg, struct tcp_pcb *pcb, err_t err) +{ + struct http_state *hs; + struct tcp_pcb_listen *lpcb = (struct tcp_pcb_listen*)arg; + LWIP_UNUSED_ARG(err); + LWIP_DEBUGF(HTTPD_DEBUG, ("http_accept %p / %p\n", (void*)pcb, arg)); + + /* Decrease the listen backlog counter */ + tcp_accepted(lpcb); + /* Set priority */ + tcp_setprio(pcb, HTTPD_TCP_PRIO); + + /* Allocate memory for the structure that holds the state of the + connection - initialized by that function. */ + hs = http_state_alloc(); + if (hs == NULL) { + LWIP_DEBUGF(HTTPD_DEBUG, ("http_accept: Out of memory, RST\n")); + return ERR_MEM; + } + hs->pcb = pcb; + + /* Tell TCP that this is the structure we wish to be passed for our + callbacks. */ + tcp_arg(pcb, hs); + + /* Set up the various callback functions */ + tcp_recv(pcb, http_recv); + tcp_err(pcb, http_err); + tcp_poll(pcb, http_poll, HTTPD_POLL_INTERVAL); + tcp_sent(pcb, http_sent); + + return ERR_OK; +} + +/** + * Initialize the httpd with the specified local address. + */ +static void +httpd_init_addr(ip_addr_t *local_addr) +{ + struct tcp_pcb *pcb; + err_t err; + + pcb = tcp_new(); + LWIP_ASSERT("httpd_init: tcp_new failed", pcb != NULL); + tcp_setprio(pcb, HTTPD_TCP_PRIO); + /* set SOF_REUSEADDR here to explicitly bind httpd to multiple interfaces */ + err = tcp_bind(pcb, local_addr, HTTPD_SERVER_PORT); + LWIP_ASSERT("httpd_init: tcp_bind failed", err == ERR_OK); + pcb = tcp_listen(pcb); + LWIP_ASSERT("httpd_init: tcp_listen failed", pcb != NULL); + /* initialize callback arg and accept callback */ + tcp_arg(pcb, pcb); + tcp_accept(pcb, http_accept); +} + +/** + * Initialize the httpd: set up a listening PCB and bind it to the defined port + */ +void +httpd_init(void) +{ +#if HTTPD_USE_MEM_POOL + LWIP_ASSERT("memp_sizes[MEMP_HTTPD_STATE] >= sizeof(http_state)", + memp_sizes[MEMP_HTTPD_STATE] >= sizeof(http_state)); + LWIP_ASSERT("memp_sizes[MEMP_HTTPD_SSI_STATE] >= sizeof(http_ssi_state)", + memp_sizes[MEMP_HTTPD_SSI_STATE] >= sizeof(http_ssi_state)); +#endif + LWIP_DEBUGF(HTTPD_DEBUG, ("httpd_init\n")); + + httpd_init_addr(IP_ADDR_ANY); +} + +#if LWIP_HTTPD_SSI +/** + * Set the SSI handler function. + * + * @param ssi_handler the SSI handler function + * @param tags an array of SSI tag strings to search for in SSI-enabled files + * @param num_tags number of tags in the 'tags' array + */ +void +http_set_ssi_handler(tSSIHandler ssi_handler, const char **tags, int num_tags) +{ + LWIP_DEBUGF(HTTPD_DEBUG, ("http_set_ssi_handler\n")); + + LWIP_ASSERT("no ssi_handler given", ssi_handler != NULL); + LWIP_ASSERT("no tags given", tags != NULL); + LWIP_ASSERT("invalid number of tags", num_tags > 0); + + g_pfnSSIHandler = ssi_handler; + g_ppcTags = tags; + g_iNumTags = num_tags; +} +#endif /* LWIP_HTTPD_SSI */ + +#if LWIP_HTTPD_CGI +/** + * Set an array of CGI filenames/handler functions + * + * @param cgis an array of CGI filenames/handler functions + * @param num_handlers number of elements in the 'cgis' array + */ +void +http_set_cgi_handlers(const tCGI *cgis, int num_handlers) +{ + LWIP_ASSERT("no cgis given", cgis != NULL); + LWIP_ASSERT("invalid number of handlers", num_handlers > 0); + + g_pCGIs = cgis; + g_iNumCGIs = num_handlers; +} +#endif /* LWIP_HTTPD_CGI */ + +#endif /* LWIP_TCP */ diff --git a/src/lwip-1.4.1/apps/httpserver_raw/httpd.h b/src/lwip-1.4.1/apps/httpserver_raw/httpd.h new file mode 100644 index 0000000..88cefce --- /dev/null +++ b/src/lwip-1.4.1/apps/httpserver_raw/httpd.h @@ -0,0 +1,236 @@ +/* + * Copyright (c) 2001-2003 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + * This version of the file has been modified by Texas Instruments to offer + * simple server-side-include (SSI) and Common Gateway Interface (CGI) + * capability. + */ + +#ifndef __HTTPD_H__ +#define __HTTPD_H__ + +#include "lwip/opt.h" +#include "lwip/err.h" +#include "lwip/pbuf.h" + + +/** Set this to 1 to support CGI */ +#ifndef LWIP_HTTPD_CGI +#define LWIP_HTTPD_CGI 0 +#endif + +/** Set this to 1 to support SSI (Server-Side-Includes) */ +#ifndef LWIP_HTTPD_SSI +#define LWIP_HTTPD_SSI 0 +#endif + +/** Set this to 1 to support HTTP POST */ +#ifndef LWIP_HTTPD_SUPPORT_POST +#define LWIP_HTTPD_SUPPORT_POST 0 +#endif + + +#if LWIP_HTTPD_CGI + +/* + * Function pointer for a CGI script handler. + * + * This function is called each time the HTTPD server is asked for a file + * whose name was previously registered as a CGI function using a call to + * http_set_cgi_handler. The iIndex parameter provides the index of the + * CGI within the ppcURLs array passed to http_set_cgi_handler. Parameters + * pcParam and pcValue provide access to the parameters provided along with + * the URI. iNumParams provides a count of the entries in the pcParam and + * pcValue arrays. Each entry in the pcParam array contains the name of a + * parameter with the corresponding entry in the pcValue array containing the + * value for that parameter. Note that pcParam may contain multiple elements + * with the same name if, for example, a multi-selection list control is used + * in the form generating the data. + * + * The function should return a pointer to a character string which is the + * path and filename of the response that is to be sent to the connected + * browser, for example "/thanks.htm" or "/response/error.ssi". + * + * The maximum number of parameters that will be passed to this function via + * iNumParams is defined by LWIP_HTTPD_MAX_CGI_PARAMETERS. Any parameters in the incoming + * HTTP request above this number will be discarded. + * + * Requests intended for use by this CGI mechanism must be sent using the GET + * method (which encodes all parameters within the URI rather than in a block + * later in the request). Attempts to use the POST method will result in the + * request being ignored. + * + */ +typedef const char *(*tCGIHandler)(int iIndex, int iNumParams, char *pcParam[], + char *pcValue[]); + +/* + * Structure defining the base filename (URL) of a CGI and the associated + * function which is to be called when that URL is requested. + */ +typedef struct +{ + const char *pcCGIName; + tCGIHandler pfnCGIHandler; +} tCGI; + +void http_set_cgi_handlers(const tCGI *pCGIs, int iNumHandlers); + + +/* The maximum number of parameters that the CGI handler can be sent. */ +#ifndef LWIP_HTTPD_MAX_CGI_PARAMETERS +#define LWIP_HTTPD_MAX_CGI_PARAMETERS 16 +#endif + +#endif /* LWIP_HTTPD_CGI */ + +#if LWIP_HTTPD_SSI + +/** LWIP_HTTPD_SSI_MULTIPART==1: SSI handler function is called with 2 more + * arguments indicating a counter for insert string that are too long to be + * inserted at once: the SSI handler function must then set 'next_tag_part' + * which will be passed back to it in the next call. */ +#ifndef LWIP_HTTPD_SSI_MULTIPART +#define LWIP_HTTPD_SSI_MULTIPART 0 +#endif + +/* + * Function pointer for the SSI tag handler callback. + * + * This function will be called each time the HTTPD server detects a tag of the + * form in a .shtml, .ssi or .shtm file where "name" appears as + * one of the tags supplied to http_set_ssi_handler in the ppcTags array. The + * returned insert string, which will be appended after the the string + * "" in file sent back to the client,should be written to pointer + * pcInsert. iInsertLen contains the size of the buffer pointed to by + * pcInsert. The iIndex parameter provides the zero-based index of the tag as + * found in the ppcTags array and identifies the tag that is to be processed. + * + * The handler returns the number of characters written to pcInsert excluding + * any terminating NULL or a negative number to indicate a failure (tag not + * recognized, for example). + * + * Note that the behavior of this SSI mechanism is somewhat different from the + * "normal" SSI processing as found in, for example, the Apache web server. In + * this case, the inserted text is appended following the SSI tag rather than + * replacing the tag entirely. This allows for an implementation that does not + * require significant additional buffering of output data yet which will still + * offer usable SSI functionality. One downside to this approach is when + * attempting to use SSI within JavaScript. The SSI tag is structured to + * resemble an HTML comment but this syntax does not constitute a comment + * within JavaScript and, hence, leaving the tag in place will result in + * problems in these cases. To work around this, any SSI tag which needs to + * output JavaScript code must do so in an encapsulated way, sending the whole + * HTML section as a single include. + */ +typedef u16_t (*tSSIHandler)(int iIndex, char *pcInsert, int iInsertLen +#if LWIP_HTTPD_SSI_MULTIPART + , u16_t current_tag_part, u16_t *next_tag_part +#endif /* LWIP_HTTPD_SSI_MULTIPART */ +#if LWIP_HTTPD_FILE_STATE + , void *connection_state +#endif /* LWIP_HTTPD_FILE_STATE */ + ); + +void http_set_ssi_handler(tSSIHandler pfnSSIHandler, + const char **ppcTags, int iNumTags); + +/* The maximum length of the string comprising the tag name */ +#ifndef LWIP_HTTPD_MAX_TAG_NAME_LEN +#define LWIP_HTTPD_MAX_TAG_NAME_LEN 8 +#endif + +/* The maximum length of string that can be returned to replace any given tag */ +#ifndef LWIP_HTTPD_MAX_TAG_INSERT_LEN +#define LWIP_HTTPD_MAX_TAG_INSERT_LEN 192 +#endif + +#endif /* LWIP_HTTPD_SSI */ + +#if LWIP_HTTPD_SUPPORT_POST + +/* These functions must be implemented by the application */ + +/** Called when a POST request has been received. The application can decide + * whether to accept it or not. + * + * @param connection Unique connection identifier, valid until httpd_post_end + * is called. + * @param uri The HTTP header URI receiving the POST request. + * @param http_request The raw HTTP request (the first packet, normally). + * @param http_request_len Size of 'http_request'. + * @param content_len Content-Length from HTTP header. + * @param response_uri Filename of response file, to be filled when denying the + * request + * @param response_uri_len Size of the 'response_uri' buffer. + * @param post_auto_wnd Set this to 0 to let the callback code handle window + * updates by calling 'httpd_post_data_recved' (to throttle rx speed) + * default is 1 (httpd handles window updates automatically) + * @return ERR_OK: Accept the POST request, data may be passed in + * another err_t: Deny the POST request, send back 'bad request'. + */ +err_t httpd_post_begin(void *connection, const char *uri, const char *http_request, + u16_t http_request_len, int content_len, char *response_uri, + u16_t response_uri_len, u8_t *post_auto_wnd); + +/** Called for each pbuf of data that has been received for a POST. + * ATTENTION: The application is responsible for freeing the pbufs passed in! + * + * @param connection Unique connection identifier. + * @param p Received data. + * @return ERR_OK: Data accepted. + * another err_t: Data denied, http_post_get_response_uri will be called. + */ +err_t httpd_post_receive_data(void *connection, struct pbuf *p); + +/** Called when all data is received or when the connection is closed. + * The application must return the filename/URI of a file to send in response + * to this POST request. If the response_uri buffer is untouched, a 404 + * response is returned. + * + * @param connection Unique connection identifier. + * @param response_uri Filename of response file, to be filled when denying the request + * @param response_uri_len Size of the 'response_uri' buffer. + */ +void httpd_post_finished(void *connection, char *response_uri, u16_t response_uri_len); + +#ifndef LWIP_HTTPD_POST_MANUAL_WND +#define LWIP_HTTPD_POST_MANUAL_WND 0 +#endif + +#if LWIP_HTTPD_POST_MANUAL_WND +void httpd_post_data_recved(void *connection, u16_t recved_len); +#endif /* LWIP_HTTPD_POST_MANUAL_WND */ + +#endif /* LWIP_HTTPD_SUPPORT_POST */ + +void httpd_init(void); + +#endif /* __HTTPD_H__ */ diff --git a/src/lwip-1.4.1/apps/httpserver_raw/httpd_structs.h b/src/lwip-1.4.1/apps/httpserver_raw/httpd_structs.h new file mode 100644 index 0000000..78ef2ff --- /dev/null +++ b/src/lwip-1.4.1/apps/httpserver_raw/httpd_structs.h @@ -0,0 +1,132 @@ +#ifndef __HTTPD_STRUCTS_H__ +#define __HTTPD_STRUCTS_H__ + +#include "httpd.h" + +/** This string is passed in the HTTP header as "Server: " */ +#ifndef HTTPD_SERVER_AGENT +#define HTTPD_SERVER_AGENT "lwIP/1.3.1 (http://savannah.nongnu.org/projects/lwip)" +#endif + +/** Set this to 1 if you want to include code that creates HTTP headers + * at runtime. Default is off: HTTP headers are then created statically + * by the makefsdata tool. Static headers mean smaller code size, but + * the (readonly) fsdata will grow a bit as every file includes the HTTP + * header. */ +#ifndef LWIP_HTTPD_DYNAMIC_HEADERS +#define LWIP_HTTPD_DYNAMIC_HEADERS 0 +#endif + + +#if LWIP_HTTPD_DYNAMIC_HEADERS +/** This struct is used for a list of HTTP header strings for various + * filename extensions. */ +typedef struct +{ + const char *extension; + int headerIndex; +} tHTTPHeader; + +/** A list of strings used in HTTP headers */ +static const char * const g_psHTTPHeaderStrings[] = +{ + "Content-type: text/html\r\n\r\n", + "Content-type: text/html\r\nExpires: Fri, 10 Apr 2008 14:00:00 GMT\r\nPragma: no-cache\r\n\r\n", + "Content-type: image/gif\r\n\r\n", + "Content-type: image/png\r\n\r\n", + "Content-type: image/jpeg\r\n\r\n", + "Content-type: image/bmp\r\n\r\n", + "Content-type: image/x-icon\r\n\r\n", + "Content-type: application/octet-stream\r\n\r\n", + "Content-type: application/x-javascript\r\n\r\n", + "Content-type: application/x-javascript\r\n\r\n", + "Content-type: text/css\r\n\r\n", + "Content-type: application/x-shockwave-flash\r\n\r\n", + "Content-type: text/xml\r\n\r\n", + "Content-type: text/plain\r\n\r\n", + "HTTP/1.0 200 OK\r\n", + "HTTP/1.0 404 File not found\r\n", + "HTTP/1.0 400 Bad Request\r\n", + "HTTP/1.0 501 Not Implemented\r\n", + "HTTP/1.1 200 OK\r\n", + "HTTP/1.1 404 File not found\r\n", + "HTTP/1.1 400 Bad Request\r\n", + "HTTP/1.1 501 Not Implemented\r\n", + "Content-Length: ", + "Connection: Close\r\n", + "Connection: keep-alive\r\n", + "Server: "HTTPD_SERVER_AGENT"\r\n", + "\r\n

404: The requested file cannot be found.

\r\n", + + "Content-type: image/svg+xml\r\n\r\n" +}; + +/* Indexes into the g_psHTTPHeaderStrings array */ +#define HTTP_HDR_HTML 0 /* text/html */ +#define HTTP_HDR_SSI 1 /* text/html Expires... */ +#define HTTP_HDR_GIF 2 /* image/gif */ +#define HTTP_HDR_PNG 3 /* image/png */ +#define HTTP_HDR_JPG 4 /* image/jpeg */ +#define HTTP_HDR_BMP 5 /* image/bmp */ +#define HTTP_HDR_ICO 6 /* image/x-icon */ +#define HTTP_HDR_APP 7 /* application/octet-stream */ +#define HTTP_HDR_JS 8 /* application/x-javascript */ +#define HTTP_HDR_RA 9 /* application/x-javascript */ +#define HTTP_HDR_CSS 10 /* text/css */ +#define HTTP_HDR_SWF 11 /* application/x-shockwave-flash */ +#define HTTP_HDR_XML 12 /* text/xml */ +#define HTTP_HDR_DEFAULT_TYPE 13 /* text/plain */ +#define HTTP_HDR_OK 14 /* 200 OK */ +#define HTTP_HDR_NOT_FOUND 15 /* 404 File not found */ +#define HTTP_HDR_BAD_REQUEST 16 /* 400 Bad request */ +#define HTTP_HDR_NOT_IMPL 17 /* 501 Not Implemented */ +#define HTTP_HDR_OK_11 18 /* 200 OK */ +#define HTTP_HDR_NOT_FOUND_11 19 /* 404 File not found */ +#define HTTP_HDR_BAD_REQUEST_11 20 /* 400 Bad request */ +#define HTTP_HDR_NOT_IMPL_11 21 /* 501 Not Implemented */ +#define HTTP_HDR_CONTENT_LENGTH 22 /* Content-Length: (HTTP 1.1)*/ +#define HTTP_HDR_CONN_CLOSE 23 /* Connection: Close (HTTP 1.1) */ +#define HTTP_HDR_CONN_KEEPALIVE 24 /* Connection: keep-alive (HTTP 1.1) */ +#define HTTP_HDR_SERVER 25 /* Server: HTTPD_SERVER_AGENT */ +#define DEFAULT_404_HTML 26 /* default 404 body */ + +/* added by FSE: */ +#define HTTP_HDR_SVG 27 /* image/svg+xml */ + + +/** A list of extension-to-HTTP header strings */ +const static tHTTPHeader g_psHTTPHeaders[] = +{ + { "html", HTTP_HDR_HTML}, + { "htm", HTTP_HDR_HTML}, + { "shtml",HTTP_HDR_SSI}, + { "shtm", HTTP_HDR_SSI}, + { "ssi", HTTP_HDR_SSI}, + { "gif", HTTP_HDR_GIF}, + { "png", HTTP_HDR_PNG}, + { "jpg", HTTP_HDR_JPG}, + { "bmp", HTTP_HDR_BMP}, + { "ico", HTTP_HDR_ICO}, + { "class",HTTP_HDR_APP}, + { "cls", HTTP_HDR_APP}, + { "js", HTTP_HDR_JS}, + { "ram", HTTP_HDR_RA}, + { "css", HTTP_HDR_CSS}, + { "swf", HTTP_HDR_SWF}, + { "xml", HTTP_HDR_XML}, + { "xsl", HTTP_HDR_XML}, + { "svg", HTTP_HDR_SVG} +}; + +#define NUM_HTTP_HEADERS (sizeof(g_psHTTPHeaders) / sizeof(tHTTPHeader)) + +#endif /* LWIP_HTTPD_DYNAMIC_HEADERS */ + +#if LWIP_HTTPD_SSI +static const char * const g_pcSSIExtensions[] = { + ".shtml", ".shtm", ".ssi", ".xml" +}; +#define NUM_SHTML_EXTENSIONS (sizeof(g_pcSSIExtensions) / sizeof(const char *)) +#endif /* LWIP_HTTPD_SSI */ + +#endif /* __HTTPD_STRUCTS_H__ */ diff --git a/src/lwip-1.4.1/apps/httpserver_raw/makefsdata/makefsdata b/src/lwip-1.4.1/apps/httpserver_raw/makefsdata/makefsdata new file mode 100644 index 0000000..37b4203 --- /dev/null +++ b/src/lwip-1.4.1/apps/httpserver_raw/makefsdata/makefsdata @@ -0,0 +1,97 @@ +#!/usr/bin/perl + +open(OUTPUT, "> fsdata.c"); + +chdir("fs"); +open(FILES, "find . -type f |"); + +while($file = ) { + + # Do not include files in CVS directories nor backup files. + if($file =~ /(CVS|~)/) { + next; + } + + chop($file); + + open(HEADER, "> /tmp/header") || die $!; + if($file =~ /404/) { + print(HEADER "HTTP/1.0 404 File not found\r\n"); + } else { + print(HEADER "HTTP/1.0 200 OK\r\n"); + } + print(HEADER "Server: lwIP/pre-0.6 (http://www.sics.se/~adam/lwip/)\r\n"); + if($file =~ /\.html$/) { + print(HEADER "Content-type: text/html\r\n"); + } elsif($file =~ /\.gif$/) { + print(HEADER "Content-type: image/gif\r\n"); + } elsif($file =~ /\.png$/) { + print(HEADER "Content-type: image/png\r\n"); + } elsif($file =~ /\.jpg$/) { + print(HEADER "Content-type: image/jpeg\r\n"); + } elsif($file =~ /\.class$/) { + print(HEADER "Content-type: application/octet-stream\r\n"); + } elsif($file =~ /\.ram$/) { + print(HEADER "Content-type: audio/x-pn-realaudio\r\n"); + } else { + print(HEADER "Content-type: text/plain\r\n"); + } + print(HEADER "\r\n"); + close(HEADER); + + unless($file =~ /\.plain$/ || $file =~ /cgi/) { + system("cat /tmp/header $file > /tmp/file"); + } else { + system("cp $file /tmp/file"); + } + + open(FILE, "/tmp/file"); + unlink("/tmp/file"); + unlink("/tmp/header"); + + $file =~ s/\.//; + $fvar = $file; + $fvar =~ s-/-_-g; + $fvar =~ s-\.-_-g; + print(OUTPUT "static const unsigned char data".$fvar."[] = {\n"); + print(OUTPUT "\t/* $file */\n\t"); + for($j = 0; $j < length($file); $j++) { + printf(OUTPUT "%#02x, ", unpack("C", substr($file, $j, 1))); + } + printf(OUTPUT "0,\n"); + + + $i = 0; + while(read(FILE, $data, 1)) { + if($i == 0) { + print(OUTPUT "\t"); + } + printf(OUTPUT "%#02x, ", unpack("C", $data)); + $i++; + if($i == 10) { + print(OUTPUT "\n"); + $i = 0; + } + } + print(OUTPUT "};\n\n"); + close(FILE); + push(@fvars, $fvar); + push(@files, $file); +} + +for($i = 0; $i < @fvars; $i++) { + $file = $files[$i]; + $fvar = $fvars[$i]; + + if($i == 0) { + $prevfile = "NULL"; + } else { + $prevfile = "file" . $fvars[$i - 1]; + } + print(OUTPUT "const struct fsdata_file file".$fvar."[] = {{$prevfile, data$fvar, "); + print(OUTPUT "data$fvar + ". (length($file) + 1) .", "); + print(OUTPUT "sizeof(data$fvar) - ". (length($file) + 1) ."}};\n\n"); +} + +print(OUTPUT "#define FS_ROOT file$fvars[$i - 1]\n\n"); +print(OUTPUT "#define FS_NUMFILES $i\n"); diff --git a/src/lwip-1.4.1/apps/httpserver_raw/makefsdata/makefsdata.c b/src/lwip-1.4.1/apps/httpserver_raw/makefsdata/makefsdata.c new file mode 100644 index 0000000..6c1f4bf --- /dev/null +++ b/src/lwip-1.4.1/apps/httpserver_raw/makefsdata/makefsdata.c @@ -0,0 +1,636 @@ +/** + * makefsdata: Converts a directory structure for use with the lwIP httpd. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Jim Pettinato + * Simon Goldschmidt + * + * @todo: + * - take TCP_MSS, LWIP_TCP_TIMESTAMPS and + * PAYLOAD_ALIGN_TYPE/PAYLOAD_ALIGNMENT as arguments + */ + +#include +#include +#ifdef WIN32 +#define WIN32_LEAN_AND_MEAN +#include "windows.h" +#else +#include +#endif +#include +#include + +/* Compatibility defines Win32 vs. DOS */ +#ifdef WIN32 + +#define FIND_T WIN32_FIND_DATAA +#define FIND_T_FILENAME(fInfo) (fInfo.cFileName) +#define FIND_T_IS_DIR(fInfo) ((fInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0) +#define FIND_T_IS_FILE(fInfo) ((fInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0) +#define FIND_RET_T HANDLE +#define FINDFIRST_FILE(path, result) FindFirstFileA(path, result) +#define FINDFIRST_DIR(path, result) FindFirstFileA(path, result) +#define FINDNEXT(ff_res, result) FindNextFileA(ff_res, result) +#define FINDFIRST_SUCCEEDED(ret) (ret != INVALID_HANDLE_VALUE) +#define FINDNEXT_SUCCEEDED(ret) (ret == TRUE) + +#define GETCWD(path, len) GetCurrentDirectoryA(len, path) +#define CHDIR(path) SetCurrentDirectoryA(path) + +#define NEWLINE "\r\n" +#define NEWLINE_LEN 2 + +#else + +#define FIND_T struct ffblk +#define FIND_T_FILENAME(fInfo) (fInfo.ff_name) +#define FIND_T_IS_DIR(fInfo) ((fInfo.ff_attrib & FA_DIREC) == FA_DIREC) +#define FIND_T_IS_FILE(fInfo) (1) +#define FIND_RET_T int +#define FINDFIRST_FILE(path, result) findfirst(path, result, FA_ARCH) +#define FINDFIRST_DIR(path, result) findfirst(path, result, FA_DIREC) +#define FINDNEXT(ff_res, result) FindNextFileA(ff_res, result) +#define FINDFIRST_SUCCEEDED(ret) (ret == 0) +#define FINDNEXT_SUCCEEDED(ret) (ret == 0) + +#define GETCWD(path, len) getcwd(path, len) +#define CHDIR(path) chdir(path) + +#endif + +/* define this to get the header variables we use to build HTTP headers */ +#define LWIP_HTTPD_DYNAMIC_HEADERS 1 +#define LWIP_HTTPD_SSI 1 +#include "../httpd_structs.h" + +#include "../../../../lwip/src/core/ipv4/inet_chksum.c" +#include "../../../../lwip/src/core/def.c" + +/** (Your server name here) */ +const char *serverID = "Server: "HTTPD_SERVER_AGENT"\r\n"; + +/* change this to suit your MEM_ALIGNMENT */ +#define PAYLOAD_ALIGNMENT 4 +/* set this to 0 to prevent aligning payload */ +#define ALIGN_PAYLOAD 1 +/* define this to a type that has the required alignment */ +#define PAYLOAD_ALIGN_TYPE "unsigned int" +static int payload_alingment_dummy_counter = 0; + +#define HEX_BYTES_PER_LINE 16 + +#define MAX_PATH_LEN 256 + +#define COPY_BUFSIZE 10240 + +int process_sub(FILE *data_file, FILE *struct_file); +int process_file(FILE *data_file, FILE *struct_file, const char *filename); +int file_write_http_header(FILE *data_file, const char *filename, int file_size, + u16_t *http_hdr_len, u16_t *http_hdr_chksum); +int file_put_ascii(FILE *file, const char *ascii_string, int len, int *i); +int s_put_ascii(char *buf, const char *ascii_string, int len, int *i); +void concat_files(const char *file1, const char *file2, const char *targetfile); + +static unsigned char file_buffer_raw[COPY_BUFSIZE]; +/* 5 bytes per char + 3 bytes per line */ +static char file_buffer_c[COPY_BUFSIZE * 5 + ((COPY_BUFSIZE / HEX_BYTES_PER_LINE) * 3)]; + +char curSubdir[MAX_PATH_LEN]; +char lastFileVar[MAX_PATH_LEN]; +char hdr_buf[4096]; + +unsigned char processSubs = 1; +unsigned char includeHttpHeader = 1; +unsigned char useHttp11 = 0; +unsigned char supportSsi = 1; +unsigned char precalcChksum = 0; + +int main(int argc, char *argv[]) +{ + FIND_T fInfo; + FIND_RET_T fret; + char path[MAX_PATH_LEN]; + char appPath[MAX_PATH_LEN]; + FILE *data_file; + FILE *struct_file; + int filesProcessed; + int i; + char targetfile[MAX_PATH_LEN]; + strcpy(targetfile, "fsdata.c"); + + memset(path, 0, sizeof(path)); + memset(appPath, 0, sizeof(appPath)); + + printf(NEWLINE " makefsdata - HTML to C source converter" NEWLINE); + printf(" by Jim Pettinato - circa 2003 " NEWLINE); + printf(" extended by Simon Goldschmidt - 2009 " NEWLINE NEWLINE); + + strcpy(path, "fs"); + for(i = 1; i < argc; i++) { + if (argv[i][0] == '-') { + if (strstr(argv[i], "-s")) { + processSubs = 0; + } else if (strstr(argv[i], "-e")) { + includeHttpHeader = 0; + } else if (strstr(argv[i], "-11")) { + useHttp11 = 1; + } else if (strstr(argv[i], "-nossi")) { + supportSsi = 0; + } else if (strstr(argv[i], "-c")) { + precalcChksum = 1; + } else if((argv[i][1] == 'f') && (argv[i][2] == ':')) { + strcpy(targetfile, &argv[i][3]); + printf("Writing to file \"%s\"\n", targetfile); + } + } else { + strcpy(path, argv[i]); + } + } + + /* if command line param or subdir named 'fs' not found spout usage verbiage */ + fret = FINDFIRST_DIR(path, &fInfo); + if (!FINDFIRST_SUCCEEDED(fret)) { + /* if no subdir named 'fs' (or the one which was given) exists, spout usage verbiage */ + printf(" Failed to open directory \"%s\"." NEWLINE NEWLINE, path); + printf(" Usage: htmlgen [targetdir] [-s] [-i] [-f:]" NEWLINE NEWLINE); + printf(" targetdir: relative or absolute path to files to convert" NEWLINE); + printf(" switch -s: toggle processing of subdirectories (default is on)" NEWLINE); + printf(" switch -e: exclude HTTP header from file (header is created at runtime, default is off)" NEWLINE); + printf(" switch -11: include HTTP 1.1 header (1.0 is default)" NEWLINE); + printf(" switch -nossi: no support for SSI (cannot calculate Content-Length for SSI)" NEWLINE); + printf(" switch -c: precalculate checksums for all pages (default is off)" NEWLINE); + printf(" switch -f: target filename (default is \"fsdata.c\")" NEWLINE); + printf(" if targetdir not specified, htmlgen will attempt to" NEWLINE); + printf(" process files in subdirectory 'fs'" NEWLINE); + exit(-1); + } + + printf("HTTP %sheader will %s statically included." NEWLINE, + (includeHttpHeader ? (useHttp11 ? "1.1 " : "1.0 ") : ""), + (includeHttpHeader ? "be" : "not be")); + + sprintf(curSubdir, ""); /* start off in web page's root directory - relative paths */ + printf(" Processing all files in directory %s", path); + if (processSubs) { + printf(" and subdirectories..." NEWLINE NEWLINE); + } else { + printf("..." NEWLINE NEWLINE); + } + + GETCWD(appPath, MAX_PATH_LEN); + data_file = fopen("fsdata.tmp", "wb"); + if (data_file == NULL) { + printf("Failed to create file \"fsdata.tmp\"\n"); + exit(-1); + } + struct_file = fopen("fshdr.tmp", "wb"); + if (struct_file == NULL) { + printf("Failed to create file \"fshdr.tmp\"\n"); + exit(-1); + } + + CHDIR(path); + + fprintf(data_file, "#include \"fs.h\"" NEWLINE); + fprintf(data_file, "#include \"lwip/def.h\"" NEWLINE); + fprintf(data_file, "#include \"fsdata.h\"" NEWLINE NEWLINE NEWLINE); + + fprintf(data_file, "#define file_NULL (struct fsdata_file *) NULL" NEWLINE NEWLINE NEWLINE); + + sprintf(lastFileVar, "NULL"); + + filesProcessed = process_sub(data_file, struct_file); + + /* data_file now contains all of the raw data.. now append linked list of + * file header structs to allow embedded app to search for a file name */ + fprintf(data_file, NEWLINE NEWLINE); + fprintf(struct_file, "#define FS_ROOT file_%s" NEWLINE, lastFileVar); + fprintf(struct_file, "#define FS_NUMFILES %d" NEWLINE NEWLINE, filesProcessed); + + fclose(data_file); + fclose(struct_file); + + CHDIR(appPath); + /* append struct_file to data_file */ + printf(NEWLINE "Creating target file..." NEWLINE NEWLINE); + concat_files("fsdata.tmp", "fshdr.tmp", targetfile); + + /* if succeeded, delete the temporary files */ + remove("fsdata.tmp"); + remove("fshdr.tmp"); + + printf(NEWLINE "Processed %d files - done." NEWLINE NEWLINE, filesProcessed); + + return 0; +} + +static void copy_file(const char *filename_in, FILE *fout) +{ + FILE *fin; + size_t len; + fin = fopen(filename_in, "rb"); + if (fin == NULL) { + printf("Failed to open file \"%s\"\n", filename_in); + exit(-1); + } + + while((len = fread(file_buffer_raw, 1, COPY_BUFSIZE, fin)) > 0) + { + fwrite(file_buffer_raw, 1, len, fout); + } + fclose(fin); +} + +void concat_files(const char *file1, const char *file2, const char *targetfile) +{ + FILE *fout; + fout = fopen(targetfile, "wb"); + if (fout == NULL) { + printf("Failed to open file \"%s\"\n", targetfile); + exit(-1); + } + copy_file(file1, fout); + copy_file(file2, fout); + fclose(fout); +} + +int process_sub(FILE *data_file, FILE *struct_file) +{ + FIND_T fInfo; + FIND_RET_T fret; + int filesProcessed = 0; + char oldSubdir[MAX_PATH_LEN]; + + if (processSubs) { + /* process subs recursively */ + strcpy(oldSubdir, curSubdir); + fret = FINDFIRST_DIR("*", &fInfo); + if (FINDFIRST_SUCCEEDED(fret)) { + do { + const char *curName = FIND_T_FILENAME(fInfo); + if (curName == NULL) continue; + if (curName[0] == '.') continue; + if (strcmp(curName, "CVS") == 0) continue; + if (!FIND_T_IS_DIR(fInfo)) continue; + CHDIR(curName); + strcat(curSubdir, "/"); + strcat(curSubdir, curName); + printf(NEWLINE "processing subdirectory %s/..." NEWLINE, curSubdir); + filesProcessed += process_sub(data_file, struct_file); + CHDIR(".."); + strcpy(curSubdir, oldSubdir); + } while (FINDNEXT_SUCCEEDED(FINDNEXT(fret, &fInfo))); + } + } + + fret = FINDFIRST_FILE("*.*", &fInfo); + if (FINDFIRST_SUCCEEDED(fret)) { + /* at least one file in directory */ + do { + if (FIND_T_IS_FILE(fInfo)) { + const char *curName = FIND_T_FILENAME(fInfo); + printf("processing %s/%s..." NEWLINE, curSubdir, curName); + if (process_file(data_file, struct_file, curName) < 0) { + printf(NEWLINE "Error... aborting" NEWLINE); + return -1; + } + filesProcessed++; + } + } while (FINDNEXT_SUCCEEDED(FINDNEXT(fret, &fInfo))); + } + return filesProcessed; +} + +int get_file_size(const char* filename) +{ + FILE *inFile; + int file_size = -1; + inFile = fopen(filename, "rb"); + if (inFile == NULL) { + printf("Failed to open file \"%s\"\n", filename); + exit(-1); + } + fseek(inFile, 0, SEEK_END); + file_size = ftell(inFile); + fclose(inFile); + return file_size; +} + +void process_file_data(const char *filename, FILE *data_file) +{ + FILE *source_file; + size_t len, written, i, src_off=0; + + source_file = fopen(filename, "rb"); + + do { + size_t off = 0; + len = fread(file_buffer_raw, 1, COPY_BUFSIZE, source_file); + if (len > 0) { + for (i = 0; i < len; i++) { + sprintf(&file_buffer_c[off], "0x%02.2x,", file_buffer_raw[i]); + off += 5; + if ((++src_off % HEX_BYTES_PER_LINE) == 0) { + memcpy(&file_buffer_c[off], NEWLINE, NEWLINE_LEN); + off += NEWLINE_LEN; + } + } + written = fwrite(file_buffer_c, 1, off, data_file); + } + } while(len > 0); + fclose(source_file); +} + +int write_checksums(FILE *struct_file, const char *filename, const char *varname, + u16_t hdr_len, u16_t hdr_chksum) +{ + int chunk_size = TCP_MSS; + int offset; + size_t len; + int i = 0; + FILE *f; +#if LWIP_TCP_TIMESTAMPS + /* when timestamps are used, usable space is 12 bytes less per segment */ + chunk_size -= 12; +#endif + + fprintf(struct_file, "#if HTTPD_PRECALCULATED_CHECKSUM" NEWLINE); + fprintf(struct_file, "const struct fsdata_chksum chksums_%s[] = {" NEWLINE, varname); + + memset(file_buffer_raw, 0xab, sizeof(file_buffer_raw)); + f = fopen(filename, "rb"); + if (f == INVALID_HANDLE_VALUE) { + printf("Failed to open file \"%s\"\n", filename); + exit(-1); + } + if (hdr_len > 0) { + /* add checksum for HTTP header */ + fprintf(struct_file, "{%d, 0x%04x, %d}," NEWLINE, 0, hdr_chksum, hdr_len); + i++; + } + for (offset = hdr_len; ; offset += len) { + unsigned short chksum; + len = fread(file_buffer_raw, 1, chunk_size, f); + if (len == 0) { + break; + } + chksum = ~inet_chksum(file_buffer_raw, (u16_t)len); + /* add checksum for data */ + fprintf(struct_file, "{%d, 0x%04x, %d}," NEWLINE, offset, chksum, len); + i++; + } + fclose(f); + fprintf(struct_file, "};" NEWLINE); + fprintf(struct_file, "#endif /* HTTPD_PRECALCULATED_CHECKSUM */" NEWLINE); + return i; +} + +int process_file(FILE *data_file, FILE *struct_file, const char *filename) +{ + char *pch; + char varname[MAX_PATH_LEN]; + int i = 0; + char qualifiedName[MAX_PATH_LEN]; + int file_size; + u16_t http_hdr_chksum = 0; + u16_t http_hdr_len = 0; + int chksum_count = 0; + + /* create qualified name (TODO: prepend slash or not?) */ + sprintf(qualifiedName,"%s/%s", curSubdir, filename); + /* create C variable name */ + strcpy(varname, qualifiedName); + /* convert slashes & dots to underscores */ + while ((pch = strpbrk(varname, "./\\")) != NULL) { + *pch = '_'; + } +#if ALIGN_PAYLOAD + /* to force even alignment of array */ + fprintf(data_file, "static const " PAYLOAD_ALIGN_TYPE " dummy_align_%s = %d;" NEWLINE, varname, payload_alingment_dummy_counter++); +#endif /* ALIGN_PAYLOAD */ + fprintf(data_file, "static const unsigned char data_%s[] = {" NEWLINE, varname); + /* encode source file name (used by file system, not returned to browser) */ + fprintf(data_file, "/* %s (%d chars) */" NEWLINE, qualifiedName, strlen(qualifiedName)+1); + file_put_ascii(data_file, qualifiedName, strlen(qualifiedName)+1, &i); +#if ALIGN_PAYLOAD + /* pad to even number of bytes to assure payload is on aligned boundary */ + while(i % PAYLOAD_ALIGNMENT != 0) { + fprintf(data_file, "0x%02.2x,", 0); + i++; + } +#endif /* ALIGN_PAYLOAD */ + fprintf(data_file, NEWLINE); + + file_size = get_file_size(filename); + if (includeHttpHeader) { + file_write_http_header(data_file, filename, file_size, &http_hdr_len, &http_hdr_chksum); + } + if (precalcChksum) { + chksum_count = write_checksums(struct_file, filename, varname, http_hdr_len, http_hdr_chksum); + } + + /* build declaration of struct fsdata_file in temp file */ + fprintf(struct_file, "const struct fsdata_file file_%s[] = { {" NEWLINE, varname); + fprintf(struct_file, "file_%s," NEWLINE, lastFileVar); + fprintf(struct_file, "data_%s," NEWLINE, varname); + fprintf(struct_file, "data_%s + %d," NEWLINE, varname, i); + fprintf(struct_file, "sizeof(data_%s) - %d," NEWLINE, varname, i); + fprintf(struct_file, "%d," NEWLINE, includeHttpHeader); + if (precalcChksum) { + fprintf(struct_file, "#if HTTPD_PRECALCULATED_CHECKSUM" NEWLINE); + fprintf(struct_file, "%d, chksums_%s," NEWLINE, chksum_count, varname); + fprintf(struct_file, "#endif /* HTTPD_PRECALCULATED_CHECKSUM */" NEWLINE); + } + fprintf(struct_file, "}};" NEWLINE NEWLINE); + strcpy(lastFileVar, varname); + + /* write actual file contents */ + i = 0; + fprintf(data_file, NEWLINE "/* raw file data (%d bytes) */" NEWLINE, file_size); + process_file_data(filename, data_file); + fprintf(data_file, "};" NEWLINE NEWLINE); + + return 0; +} + +int file_write_http_header(FILE *data_file, const char *filename, int file_size, + u16_t *http_hdr_len, u16_t *http_hdr_chksum) +{ + int i = 0; + int response_type = HTTP_HDR_OK; + int file_type = HTTP_HDR_DEFAULT_TYPE; + const char *cur_string; + size_t cur_len; + int written = 0; + size_t hdr_len = 0; + u16_t acc; + const char *file_ext; + int j; + u8_t keepalive = useHttp11; + + if (keepalive) { + size_t loop; + for (loop = 0; loop < NUM_SHTML_EXTENSIONS; loop++) { + if (strstr(filename, g_pcSSIExtensions[loop])) { + /* no keepalive connection for SSI files */ + keepalive = 0; + } + } + } + + memset(hdr_buf, 0, sizeof(hdr_buf)); + + if (useHttp11) { + response_type = HTTP_HDR_OK_11; + } + + fprintf(data_file, NEWLINE "/* HTTP header */"); + if (strstr(filename, "404") == filename) { + response_type = HTTP_HDR_NOT_FOUND; + if (useHttp11) { + response_type = HTTP_HDR_NOT_FOUND_11; + } + } else if (strstr(filename, "400") == filename) { + response_type = HTTP_HDR_BAD_REQUEST; + if (useHttp11) { + response_type = HTTP_HDR_BAD_REQUEST_11; + } + } else if (strstr(filename, "501") == filename) { + response_type = HTTP_HDR_NOT_IMPL; + if (useHttp11) { + response_type = HTTP_HDR_NOT_IMPL_11; + } + } + cur_string = g_psHTTPHeaderStrings[response_type]; + cur_len = strlen(cur_string); + fprintf(data_file, NEWLINE "/* \"%s\" (%d bytes) */" NEWLINE, cur_string, cur_len); + written += file_put_ascii(data_file, cur_string, cur_len, &i); + i = 0; + if (precalcChksum) { + memcpy(&hdr_buf[hdr_len], cur_string, cur_len); + hdr_len += cur_len; + } + + cur_string = serverID; + cur_len = strlen(cur_string); + fprintf(data_file, NEWLINE "/* \"%s\" (%d bytes) */" NEWLINE, cur_string, cur_len); + written += file_put_ascii(data_file, cur_string, cur_len, &i); + i = 0; + if (precalcChksum) { + memcpy(&hdr_buf[hdr_len], cur_string, cur_len); + hdr_len += cur_len; + } + + file_ext = filename; + while(strstr(file_ext, ".") != NULL) { + file_ext = strstr(file_ext, "."); + file_ext++; + } + if((file_ext == NULL) || (*file_ext == 0)) { + printf("failed to get extension for file \"%s\", using default.\n", filename); + } else { + for(j = 0; j < NUM_HTTP_HEADERS; j++) { + if(!strcmp(file_ext, g_psHTTPHeaders[j].extension)) { + file_type = g_psHTTPHeaders[j].headerIndex; + break; + } + } + if (j >= NUM_HTTP_HEADERS) { + printf("failed to get file type for extension \"%s\", using default.\n", file_ext); + file_type = HTTP_HDR_DEFAULT_TYPE; + } + } + + if (useHttp11) { + char intbuf[MAX_PATH_LEN]; + int content_len = file_size; + memset(intbuf, 0, sizeof(intbuf)); + + if (!keepalive) { + content_len *= 2; + } + { + cur_string = g_psHTTPHeaderStrings[HTTP_HDR_CONTENT_LENGTH]; + cur_len = strlen(cur_string); + fprintf(data_file, NEWLINE "/* \"%s%d\r\n\" (%d+ bytes) */" NEWLINE, cur_string, content_len, cur_len+2); + written += file_put_ascii(data_file, cur_string, cur_len, &i); + if (precalcChksum) { + memcpy(&hdr_buf[hdr_len], cur_string, cur_len); + hdr_len += cur_len; + } + + _itoa(content_len, intbuf, 10); + strcat(intbuf, "\r\n"); + cur_len = strlen(intbuf); + written += file_put_ascii(data_file, intbuf, cur_len, &i); + i = 0; + if (precalcChksum) { + memcpy(&hdr_buf[hdr_len], intbuf, cur_len); + hdr_len += cur_len; + } + } + + if (keepalive) { + cur_string = g_psHTTPHeaderStrings[HTTP_HDR_CONN_KEEPALIVE]; + } else { + cur_string = g_psHTTPHeaderStrings[HTTP_HDR_CONN_CLOSE]; + } + cur_len = strlen(cur_string); + fprintf(data_file, NEWLINE "/* \"%s\" (%d bytes) */" NEWLINE, cur_string, cur_len); + written += file_put_ascii(data_file, cur_string, cur_len, &i); + i = 0; + if (precalcChksum) { + memcpy(&hdr_buf[hdr_len], cur_string, cur_len); + hdr_len += cur_len; + } + } + + cur_string = g_psHTTPHeaderStrings[file_type]; + cur_len = strlen(cur_string); + fprintf(data_file, NEWLINE "/* \"%s\" (%d bytes) */" NEWLINE, cur_string, cur_len); + written += file_put_ascii(data_file, cur_string, cur_len, &i); + i = 0; + if (precalcChksum) { + memcpy(&hdr_buf[hdr_len], cur_string, cur_len); + hdr_len += cur_len; + + LWIP_ASSERT("hdr_len <= 0xffff", hdr_len <= 0xffff); + LWIP_ASSERT("strlen(hdr_buf) == hdr_len", strlen(hdr_buf) == hdr_len); + acc = ~inet_chksum(hdr_buf, (u16_t)hdr_len); + *http_hdr_len = (u16_t)hdr_len; + *http_hdr_chksum = acc; + } + + return written; +} + +int file_put_ascii(FILE *file, const char* ascii_string, int len, int *i) +{ + int x; + for(x = 0; x < len; x++) { + unsigned char cur = ascii_string[x]; + fprintf(file, "0x%02.2x,", cur); + if ((++(*i) % HEX_BYTES_PER_LINE) == 0) { + fprintf(file, NEWLINE); + } + } + return len; +} + +int s_put_ascii(char *buf, const char *ascii_string, int len, int *i) +{ + int x; + int idx = 0; + for(x = 0; x < len; x++) { + unsigned char cur = ascii_string[x]; + sprintf(&buf[idx], "0x%02.2x,", cur); + idx += 5; + if ((++(*i) % HEX_BYTES_PER_LINE) == 0) { + sprintf(&buf[idx], NEWLINE); + idx += NEWLINE_LEN; + } + } + return len; +} diff --git a/src/lwip-1.4.1/apps/httpserver_raw/makefsdata/readme.txt b/src/lwip-1.4.1/apps/httpserver_raw/makefsdata/readme.txt new file mode 100644 index 0000000..3768585 --- /dev/null +++ b/src/lwip-1.4.1/apps/httpserver_raw/makefsdata/readme.txt @@ -0,0 +1,13 @@ +This directory contains a script ('makefsdata') to create C code suitable for +httpd for given html pages (or other files) in a directory. + +There is also a plain C console application doing the same and extended a bit. + +Usage: htmlgen [targetdir] [-s] [-i]s + targetdir: relative or absolute path to files to convert + switch -s: toggle processing of subdirectories (default is on) + switch -e: exclude HTTP header from file (header is created at runtime, default is on) + switch -11: include HTTP 1.1 header (1.0 is default) + + if targetdir not specified, makefsdata will attempt to + process files in subdirectory 'fs'. diff --git a/src/lwip-1.4.1/apps/netbios/netbios.c b/src/lwip-1.4.1/apps/netbios/netbios.c new file mode 100644 index 0000000..54547b5 --- /dev/null +++ b/src/lwip-1.4.1/apps/netbios/netbios.c @@ -0,0 +1,337 @@ +/** + * @file + * NetBIOS name service sample + * + */ + +/* + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * This file is part of the lwIP TCP/IP stack. + * + */ + +#include "lwip/opt.h" + +#if LWIP_UDP /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/udp.h" +#include "lwip/netif.h" + +#include + +/** This is an example implementation of a NetBIOS name server. + * It responds to name queries for a configurable name. + * Name resolving is not supported. + * + * Note that the device doesn't broadcast it's own name so can't + * detect duplicate names! + */ + +/** NetBIOS name of LWIP device + * This must be uppercase until NETBIOS_STRCMP() is defined to a string + * comparision function that is case insensitive. + * If you want to use the netif's hostname, use this (with LWIP_NETIF_HOSTNAME): + * (ip_current_netif() != NULL ? ip_current_netif()->hostname != NULL ? ip_current_netif()->hostname : "" : "") + */ +#ifndef NETBIOS_LWIP_NAME +#define NETBIOS_LWIP_NAME "NETBIOSLWIPDEV" +#endif + +/** Since there's no standard function for case-insensitive string comparision, + * we need another define here: + * define this to stricmp() for windows or strcasecmp() for linux. + * If not defined, comparision is case sensitive and NETBIOS_LWIP_NAME must be + * uppercase + */ +#ifndef NETBIOS_STRCMP +#define NETBIOS_STRCMP(str1, str2) strcmp(str1, str2) +#endif + +/** default port number for "NetBIOS Name service */ +#define NETBIOS_PORT 137 + +/** size of a NetBIOS name */ +#define NETBIOS_NAME_LEN 16 + +/** The Time-To-Live for NetBIOS name responds (in seconds) + * Default is 300000 seconds (3 days, 11 hours, 20 minutes) */ +#define NETBIOS_NAME_TTL 300000 + +/** NetBIOS header flags */ +#define NETB_HFLAG_RESPONSE 0x8000U +#define NETB_HFLAG_OPCODE 0x7800U +#define NETB_HFLAG_OPCODE_NAME_QUERY 0x0000U +#define NETB_HFLAG_AUTHORATIVE 0x0400U +#define NETB_HFLAG_TRUNCATED 0x0200U +#define NETB_HFLAG_RECURS_DESIRED 0x0100U +#define NETB_HFLAG_RECURS_AVAILABLE 0x0080U +#define NETB_HFLAG_BROADCAST 0x0010U +#define NETB_HFLAG_REPLYCODE 0x0008U +#define NETB_HFLAG_REPLYCODE_NOERROR 0x0000U + +/** NetBIOS name flags */ +#define NETB_NFLAG_UNIQUE 0x8000U +#define NETB_NFLAG_NODETYPE 0x6000U +#define NETB_NFLAG_NODETYPE_HNODE 0x6000U +#define NETB_NFLAG_NODETYPE_MNODE 0x4000U +#define NETB_NFLAG_NODETYPE_PNODE 0x2000U +#define NETB_NFLAG_NODETYPE_BNODE 0x0000U + +/** NetBIOS message header */ +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct netbios_hdr { + PACK_STRUCT_FIELD(u16_t trans_id); + PACK_STRUCT_FIELD(u16_t flags); + PACK_STRUCT_FIELD(u16_t questions); + PACK_STRUCT_FIELD(u16_t answerRRs); + PACK_STRUCT_FIELD(u16_t authorityRRs); + PACK_STRUCT_FIELD(u16_t additionalRRs); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +/** NetBIOS message name part */ +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct netbios_name_hdr { + PACK_STRUCT_FIELD(u8_t nametype); + PACK_STRUCT_FIELD(u8_t encname[(NETBIOS_NAME_LEN*2)+1]); + PACK_STRUCT_FIELD(u16_t type); + PACK_STRUCT_FIELD(u16_t cls); + PACK_STRUCT_FIELD(u32_t ttl); + PACK_STRUCT_FIELD(u16_t datalen); + PACK_STRUCT_FIELD(u16_t flags); + PACK_STRUCT_FIELD(ip_addr_p_t addr); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +/** NetBIOS message */ +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct netbios_resp +{ + struct netbios_hdr resp_hdr; + struct netbios_name_hdr resp_name; +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +/** NetBIOS decoding name */ +static int +netbios_name_decoding( char *name_enc, char *name_dec, int name_dec_len) +{ + char *pname; + char cname; + char cnbname; + int index = 0; + + LWIP_UNUSED_ARG(name_dec_len); + + /* Start decoding netbios name. */ + pname = name_enc; + for (;;) { + /* Every two characters of the first level-encoded name + * turn into one character in the decoded name. */ + cname = *pname; + if (cname == '\0') + break; /* no more characters */ + if (cname == '.') + break; /* scope ID follows */ + if (cname < 'A' || cname > 'Z') { + /* Not legal. */ + return -1; + } + cname -= 'A'; + cnbname = cname << 4; + pname++; + + cname = *pname; + if (cname == '\0' || cname == '.') { + /* No more characters in the name - but we're in + * the middle of a pair. Not legal. */ + return -1; + } + if (cname < 'A' || cname > 'Z') { + /* Not legal. */ + return -1; + } + cname -= 'A'; + cnbname |= cname; + pname++; + + /* Do we have room to store the character? */ + if (index < NETBIOS_NAME_LEN) { + /* Yes - store the character. */ + name_dec[index++] = (cnbname!=' '?cnbname:'\0'); + } + } + + return 0; +} + +#if 0 /* function currently unused */ +/** NetBIOS encoding name */ +static int +netbios_name_encoding(char *name_enc, char *name_dec, int name_dec_len) +{ + char *pname; + char cname; + unsigned char ucname; + int index = 0; + + /* Start encoding netbios name. */ + pname = name_enc; + + for (;;) { + /* Every two characters of the first level-encoded name + * turn into one character in the decoded name. */ + cname = *pname; + if (cname == '\0') + break; /* no more characters */ + if (cname == '.') + break; /* scope ID follows */ + if ((cname < 'A' || cname > 'Z') && (cname < '0' || cname > '9')) { + /* Not legal. */ + return -1; + } + + /* Do we have room to store the character? */ + if (index >= name_dec_len) { + return -1; + } + + /* Yes - store the character. */ + ucname = cname; + name_dec[index++] = ('A'+((ucname>>4) & 0x0F)); + name_dec[index++] = ('A'+( ucname & 0x0F)); + pname++; + } + + /* Fill with "space" coding */ + for (;indexpayload; + struct netbios_name_hdr* netbios_name_hdr = (struct netbios_name_hdr*)(netbios_hdr+1); + + /* we only answer if we got a default interface */ + if (netif_default != NULL) { + /* @todo: do we need to check answerRRs/authorityRRs/additionalRRs? */ + /* if the packet is a NetBIOS name query question */ + if (((netbios_hdr->flags & PP_NTOHS(NETB_HFLAG_OPCODE)) == PP_NTOHS(NETB_HFLAG_OPCODE_NAME_QUERY)) && + ((netbios_hdr->flags & PP_NTOHS(NETB_HFLAG_RESPONSE)) == 0) && + (netbios_hdr->questions == PP_NTOHS(1))) { + /* decode the NetBIOS name */ + netbios_name_decoding( (char*)(netbios_name_hdr->encname), netbios_name, sizeof(netbios_name)); + /* if the packet is for us */ + if (NETBIOS_STRCMP(netbios_name, NETBIOS_LWIP_NAME) == 0) { + struct pbuf *q; + struct netbios_resp *resp; + + q = pbuf_alloc(PBUF_TRANSPORT, sizeof(struct netbios_resp), PBUF_RAM); + if (q != NULL) { + resp = (struct netbios_resp*)q->payload; + + /* prepare NetBIOS header response */ + resp->resp_hdr.trans_id = netbios_hdr->trans_id; + resp->resp_hdr.flags = PP_HTONS(NETB_HFLAG_RESPONSE | + NETB_HFLAG_OPCODE_NAME_QUERY | + NETB_HFLAG_AUTHORATIVE | + NETB_HFLAG_RECURS_DESIRED); + resp->resp_hdr.questions = 0; + resp->resp_hdr.answerRRs = PP_HTONS(1); + resp->resp_hdr.authorityRRs = 0; + resp->resp_hdr.additionalRRs = 0; + + /* prepare NetBIOS header datas */ + MEMCPY( resp->resp_name.encname, netbios_name_hdr->encname, sizeof(netbios_name_hdr->encname)); + resp->resp_name.nametype = netbios_name_hdr->nametype; + resp->resp_name.type = netbios_name_hdr->type; + resp->resp_name.cls = netbios_name_hdr->cls; + resp->resp_name.ttl = PP_HTONL(NETBIOS_NAME_TTL); + resp->resp_name.datalen = PP_HTONS(sizeof(resp->resp_name.flags)+sizeof(resp->resp_name.addr)); + resp->resp_name.flags = PP_HTONS(NETB_NFLAG_NODETYPE_BNODE); + ip_addr_copy(resp->resp_name.addr, netif_default->ip_addr); + + /* send the NetBIOS response */ + udp_sendto(upcb, q, addr, port); + + /* free the "reference" pbuf */ + pbuf_free(q); + } + } + } + } + /* free the pbuf */ + pbuf_free(p); + } +} + +void netbios_init(void) +{ + struct udp_pcb *pcb; + + LWIP_ASSERT("NetBIOS name is too long!", strlen(NETBIOS_LWIP_NAME) < NETBIOS_NAME_LEN); + + pcb = udp_new(); + if (pcb != NULL) { + /* we have to be allowed to send broadcast packets! */ + pcb->so_options |= SOF_BROADCAST; + udp_bind(pcb, IP_ADDR_ANY, NETBIOS_PORT); + udp_recv(pcb, netbios_recv, pcb); + } +} +#endif /* LWIP_UDP */ diff --git a/src/lwip-1.4.1/apps/netbios/netbios.h b/src/lwip-1.4.1/apps/netbios/netbios.h new file mode 100644 index 0000000..2c73f78 --- /dev/null +++ b/src/lwip-1.4.1/apps/netbios/netbios.h @@ -0,0 +1,6 @@ +#ifndef __NETBIOS_H__ +#define __NETBIOS_H__ + +void netbios_init(void); + +#endif /* __NETBIOS_H__ */ diff --git a/src/lwip-1.4.1/apps/netio/netio.c b/src/lwip-1.4.1/apps/netio/netio.c new file mode 100644 index 0000000..3879e40 --- /dev/null +++ b/src/lwip-1.4.1/apps/netio/netio.c @@ -0,0 +1,51 @@ +#include "netio.h" + +#include "lwip/opt.h" +#include "lwip/tcp.h" + +/* See http://www.nwlab.net/art/netio/netio.html to get the netio tool */ + +#if LWIP_TCP +static err_t netio_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err) +{ + + LWIP_UNUSED_ARG(arg); + + if (err == ERR_OK && p != NULL) { + tcp_recved(pcb, p->tot_len); + pbuf_free(p); + } else { + pbuf_free(p); + } + + if (err == ERR_OK && p == NULL) { + tcp_arg(pcb, NULL); + tcp_sent(pcb, NULL); + tcp_recv(pcb, NULL); + tcp_close(pcb); + } + + return ERR_OK; +} + +static err_t netio_accept(void *arg, struct tcp_pcb *pcb, err_t err) +{ + LWIP_UNUSED_ARG(arg); + LWIP_UNUSED_ARG(err); + + tcp_arg(pcb, NULL); + tcp_sent(pcb, NULL); + tcp_recv(pcb, netio_recv); + return ERR_OK; +} + +void netio_init(void) +{ + struct tcp_pcb *pcb; + + pcb = tcp_new(); + tcp_bind(pcb, IP_ADDR_ANY, 18767); + pcb = tcp_listen(pcb); + tcp_accept(pcb, netio_accept); +} +#endif /* LWIP_TCP */ diff --git a/src/lwip-1.4.1/apps/netio/netio.h b/src/lwip-1.4.1/apps/netio/netio.h new file mode 100644 index 0000000..d80b117 --- /dev/null +++ b/src/lwip-1.4.1/apps/netio/netio.h @@ -0,0 +1,6 @@ +#ifndef __NETIO_H__ +#define __NETIO_H__ + +void netio_init(void); + +#endif /* __NETIO_H__ */ diff --git a/src/lwip-1.4.1/apps/ping/ping.c b/src/lwip-1.4.1/apps/ping/ping.c new file mode 100644 index 0000000..595c2a1 --- /dev/null +++ b/src/lwip-1.4.1/apps/ping/ping.c @@ -0,0 +1,329 @@ +/** + * @file + * Ping sender module + * + */ + +/* + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * This file is part of the lwIP TCP/IP stack. + * + */ + +/** + * This is an example of a "ping" sender (with raw API and socket API). + * It can be used as a start point to maintain opened a network connection, or + * like a network "watchdog" for your device. + * + */ + +#include "lwip/opt.h" + +#if LWIP_RAW /* don't build if not configured for use in lwipopts.h */ + +#include "ping.h" + +#include "lwip/mem.h" +#include "lwip/raw.h" +#include "lwip/icmp.h" +#include "lwip/netif.h" +#include "lwip/sys.h" +#include "lwip/timers.h" +#include "lwip/inet_chksum.h" + +#if PING_USE_SOCKETS +#include "lwip/sockets.h" +#include "lwip/inet.h" +#endif /* PING_USE_SOCKETS */ + + +/** + * PING_DEBUG: Enable debugging for PING. + */ +#ifndef PING_DEBUG +#define PING_DEBUG LWIP_DBG_ON +#endif + +/** ping target - should be a "ip_addr_t" */ +#ifndef PING_TARGET +#define PING_TARGET (netif_default?netif_default->gw:ip_addr_any) +#endif + +/** ping receive timeout - in milliseconds */ +#ifndef PING_RCV_TIMEO +#define PING_RCV_TIMEO 1000 +#endif + +/** ping delay - in milliseconds */ +#ifndef PING_DELAY +#define PING_DELAY 1000 +#endif + +/** ping identifier - must fit on a u16_t */ +#ifndef PING_ID +#define PING_ID 0xAFAF +#endif + +/** ping additional data size to include in the packet */ +#ifndef PING_DATA_SIZE +#define PING_DATA_SIZE 32 +#endif + +/** ping result action - no default action */ +#ifndef PING_RESULT +#define PING_RESULT(ping_ok) +#endif + +/* ping variables */ +static u16_t ping_seq_num; +static u32_t ping_time; +#if !PING_USE_SOCKETS +static struct raw_pcb *ping_pcb; +#endif /* PING_USE_SOCKETS */ + +/** Prepare a echo ICMP request */ +static void +ping_prepare_echo( struct icmp_echo_hdr *iecho, u16_t len) +{ + size_t i; + size_t data_len = len - sizeof(struct icmp_echo_hdr); + + ICMPH_TYPE_SET(iecho, ICMP_ECHO); + ICMPH_CODE_SET(iecho, 0); + iecho->chksum = 0; + iecho->id = PING_ID; + iecho->seqno = htons(++ping_seq_num); + + /* fill the additional data buffer with some data */ + for(i = 0; i < data_len; i++) { + ((char*)iecho)[sizeof(struct icmp_echo_hdr) + i] = (char)i; + } + + iecho->chksum = inet_chksum(iecho, len); +} + +#if PING_USE_SOCKETS + +/* Ping using the socket ip */ +static err_t +ping_send(int s, ip_addr_t *addr) +{ + int err; + struct icmp_echo_hdr *iecho; + struct sockaddr_in to; + size_t ping_size = sizeof(struct icmp_echo_hdr) + PING_DATA_SIZE; + LWIP_ASSERT("ping_size is too big", ping_size <= 0xffff); + + iecho = (struct icmp_echo_hdr *)mem_malloc((mem_size_t)ping_size); + if (!iecho) { + return ERR_MEM; + } + + ping_prepare_echo(iecho, (u16_t)ping_size); + + to.sin_len = sizeof(to); + to.sin_family = AF_INET; + inet_addr_from_ipaddr(&to.sin_addr, addr); + + err = lwip_sendto(s, iecho, ping_size, 0, (struct sockaddr*)&to, sizeof(to)); + + mem_free(iecho); + + return (err ? ERR_OK : ERR_VAL); +} + +static void +ping_recv(int s) +{ + char buf[64]; + int fromlen, len; + struct sockaddr_in from; + struct ip_hdr *iphdr; + struct icmp_echo_hdr *iecho; + + while((len = lwip_recvfrom(s, buf, sizeof(buf), 0, (struct sockaddr*)&from, (socklen_t*)&fromlen)) > 0) { + if (len >= (int)(sizeof(struct ip_hdr)+sizeof(struct icmp_echo_hdr))) { + ip_addr_t fromaddr; + inet_addr_to_ipaddr(&fromaddr, &from.sin_addr); + LWIP_DEBUGF( PING_DEBUG, ("ping: recv ")); + ip_addr_debug_print(PING_DEBUG, &fromaddr); + LWIP_DEBUGF( PING_DEBUG, (" %"U32_F" ms\n", (sys_now() - ping_time))); + + iphdr = (struct ip_hdr *)buf; + iecho = (struct icmp_echo_hdr *)(buf + (IPH_HL(iphdr) * 4)); + if ((iecho->id == PING_ID) && (iecho->seqno == htons(ping_seq_num))) { + /* do some ping result processing */ + PING_RESULT((ICMPH_TYPE(iecho) == ICMP_ER)); + return; + } else { + LWIP_DEBUGF( PING_DEBUG, ("ping: drop\n")); + } + } + } + + if (len == 0) { + LWIP_DEBUGF( PING_DEBUG, ("ping: recv - %"U32_F" ms - timeout\n", (sys_now()-ping_time))); + } + + /* do some ping result processing */ + PING_RESULT(0); +} + +static void +ping_thread(void *arg) +{ + int s; + int timeout = PING_RCV_TIMEO; + ip_addr_t ping_target; + + LWIP_UNUSED_ARG(arg); + + if ((s = lwip_socket(AF_INET, SOCK_RAW, IP_PROTO_ICMP)) < 0) { + return; + } + + lwip_setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)); + + while (1) { + ping_target = PING_TARGET; + + if (ping_send(s, &ping_target) == ERR_OK) { + LWIP_DEBUGF( PING_DEBUG, ("ping: send ")); + ip_addr_debug_print(PING_DEBUG, &ping_target); + LWIP_DEBUGF( PING_DEBUG, ("\n")); + + ping_time = sys_now(); + ping_recv(s); + } else { + LWIP_DEBUGF( PING_DEBUG, ("ping: send ")); + ip_addr_debug_print(PING_DEBUG, &ping_target); + LWIP_DEBUGF( PING_DEBUG, (" - error\n")); + } + sys_msleep(PING_DELAY); + } +} + +#else /* PING_USE_SOCKETS */ + +/* Ping using the raw ip */ +static u8_t +ping_recv(void *arg, struct raw_pcb *pcb, struct pbuf *p, ip_addr_t *addr) +{ + struct icmp_echo_hdr *iecho; + LWIP_UNUSED_ARG(arg); + LWIP_UNUSED_ARG(pcb); + LWIP_UNUSED_ARG(addr); + LWIP_ASSERT("p != NULL", p != NULL); + + if ((p->tot_len >= (PBUF_IP_HLEN + sizeof(struct icmp_echo_hdr))) && + pbuf_header( p, -PBUF_IP_HLEN) == 0) { + iecho = (struct icmp_echo_hdr *)p->payload; + + if ((iecho->id == PING_ID) && (iecho->seqno == htons(ping_seq_num))) { + LWIP_DEBUGF( PING_DEBUG, ("ping: recv ")); + ip_addr_debug_print(PING_DEBUG, addr); + LWIP_DEBUGF( PING_DEBUG, (" %"U32_F" ms\n", (sys_now()-ping_time))); + + /* do some ping result processing */ + PING_RESULT(1); + pbuf_free(p); + return 1; /* eat the packet */ + } + } + + return 0; /* don't eat the packet */ +} + +static void +ping_send(struct raw_pcb *raw, ip_addr_t *addr) +{ + struct pbuf *p; + struct icmp_echo_hdr *iecho; + size_t ping_size = sizeof(struct icmp_echo_hdr) + PING_DATA_SIZE; + + LWIP_DEBUGF( PING_DEBUG, ("ping: send ")); + ip_addr_debug_print(PING_DEBUG, addr); + LWIP_DEBUGF( PING_DEBUG, ("\n")); + LWIP_ASSERT("ping_size <= 0xffff", ping_size <= 0xffff); + + p = pbuf_alloc(PBUF_IP, (u16_t)ping_size, PBUF_RAM); + if (!p) { + return; + } + if ((p->len == p->tot_len) && (p->next == NULL)) { + iecho = (struct icmp_echo_hdr *)p->payload; + + ping_prepare_echo(iecho, (u16_t)ping_size); + + raw_sendto(raw, p, addr); + ping_time = sys_now(); + } + pbuf_free(p); +} + +static void +ping_timeout(void *arg) +{ + struct raw_pcb *pcb = (struct raw_pcb*)arg; + ip_addr_t ping_target = PING_TARGET; + + LWIP_ASSERT("ping_timeout: no pcb given!", pcb != NULL); + + ping_send(pcb, &ping_target); + + sys_timeout(PING_DELAY, ping_timeout, pcb); +} + +static void +ping_raw_init(void) +{ + ping_pcb = raw_new(IP_PROTO_ICMP); + LWIP_ASSERT("ping_pcb != NULL", ping_pcb != NULL); + + raw_recv(ping_pcb, ping_recv, NULL); + raw_bind(ping_pcb, IP_ADDR_ANY); + sys_timeout(PING_DELAY, ping_timeout, ping_pcb); +} + +void +ping_send_now() +{ + ip_addr_t ping_target = PING_TARGET; + LWIP_ASSERT("ping_pcb != NULL", ping_pcb != NULL); + ping_send(ping_pcb, &ping_target); +} + +#endif /* PING_USE_SOCKETS */ + +void +ping_init(void) +{ +#if PING_USE_SOCKETS + sys_thread_new("ping_thread", ping_thread, NULL, DEFAULT_THREAD_STACKSIZE, DEFAULT_THREAD_PRIO); +#else /* PING_USE_SOCKETS */ + ping_raw_init(); +#endif /* PING_USE_SOCKETS */ +} + +#endif /* LWIP_RAW */ diff --git a/src/lwip-1.4.1/apps/ping/ping.h b/src/lwip-1.4.1/apps/ping/ping.h new file mode 100644 index 0000000..81f7264 --- /dev/null +++ b/src/lwip-1.4.1/apps/ping/ping.h @@ -0,0 +1,18 @@ +#ifndef __PING_H__ +#define __PING_H__ + +/** + * PING_USE_SOCKETS: Set to 1 to use sockets, otherwise the raw api is used + */ +#ifndef PING_USE_SOCKETS +#define PING_USE_SOCKETS LWIP_SOCKET +#endif + + +void ping_init(void); + +#if !PING_USE_SOCKETS +void ping_send_now(void); +#endif /* !PING_USE_SOCKETS */ + +#endif /* __PING_H__ */ diff --git a/src/lwip-1.4.1/apps/rtp/rtp.c b/src/lwip-1.4.1/apps/rtp/rtp.c new file mode 100644 index 0000000..3f44e8e --- /dev/null +++ b/src/lwip-1.4.1/apps/rtp/rtp.c @@ -0,0 +1,294 @@ +/** + * @file + * RTP client/server module + * + */ + +/* + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * This file is part of the lwIP TCP/IP stack. + * + */ + +#include "lwip/opt.h" + +#if LWIP_SOCKET && LWIP_IGMP /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/sys.h" +#include "lwip/sockets.h" + +#include "rtpdata.h" + +#include + +/** This is an example of a "RTP" client/server based on a MPEG4 bitstream (with socket API). + */ + +/** + * RTP_DEBUG: Enable debugging for RTP. + */ +#ifndef RTP_DEBUG +#define RTP_DEBUG LWIP_DBG_ON +#endif + +/** RTP stream port */ +#ifndef RTP_STREAM_PORT +#define RTP_STREAM_PORT 4000 +#endif + +/** RTP stream multicast address as IPv4 address in "u32_t" format */ +#ifndef RTP_STREAM_ADDRESS +#define RTP_STREAM_ADDRESS inet_addr("232.0.0.0") +#endif + +/** RTP send delay - in milliseconds */ +#ifndef RTP_SEND_DELAY +#define RTP_SEND_DELAY 40 +#endif + +/** RTP receive timeout - in milliseconds */ +#ifndef RTP_RECV_TIMEOUT +#define RTP_RECV_TIMEOUT 2000 +#endif + +/** RTP stats display period - in received packets */ +#ifndef RTP_RECV_STATS +#define RTP_RECV_STATS 50 +#endif + +/** RTP macro to let the application process the data */ +#ifndef RTP_RECV_PROCESSING +#define RTP_RECV_PROCESSING(p,s) +#endif + +/** RTP packet/payload size */ +#define RTP_PACKET_SIZE 1500 +#define RTP_PAYLOAD_SIZE 1024 + +/** RTP header constants */ +#define RTP_VERSION 0x80 +#define RTP_TIMESTAMP_INCREMENT 3600 +#define RTP_SSRC 0 +#define RTP_PAYLOADTYPE 96 +#define RTP_MARKER_MASK 0x80 + +/** RTP message header */ +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct rtp_hdr { + PACK_STRUCT_FIELD(u8_t version); + PACK_STRUCT_FIELD(u8_t payloadtype); + PACK_STRUCT_FIELD(u16_t seqNum); + PACK_STRUCT_FIELD(u32_t timestamp); + PACK_STRUCT_FIELD(u32_t ssrc); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +/** RTP packets */ +static u8_t rtp_send_packet[RTP_PACKET_SIZE]; +static u8_t rtp_recv_packet[RTP_PACKET_SIZE]; + +/** + * RTP send packets + */ +static void +rtp_send_packets( int sock, struct sockaddr_in* to) +{ + struct rtp_hdr* rtphdr; + u8_t* rtp_payload; + int rtp_payload_size; + int rtp_data_index; + + /* prepare RTP packet */ + rtphdr = (struct rtp_hdr*)rtp_send_packet; + rtphdr->version = RTP_VERSION; + rtphdr->payloadtype = 0; + rtphdr->ssrc = PP_HTONL(RTP_SSRC); + rtphdr->timestamp = htonl(ntohl(rtphdr->timestamp) + RTP_TIMESTAMP_INCREMENT); + + /* send RTP stream packets */ + rtp_data_index = 0; + do { + rtp_payload = rtp_send_packet+sizeof(struct rtp_hdr); + rtp_payload_size = min(RTP_PAYLOAD_SIZE, (sizeof(rtp_data) - rtp_data_index)); + + memcpy(rtp_payload, rtp_data + rtp_data_index, rtp_payload_size); + + /* set MARKER bit in RTP header on the last packet of an image */ + rtphdr->payloadtype = RTP_PAYLOADTYPE | (((rtp_data_index + rtp_payload_size) + >= sizeof(rtp_data)) ? RTP_MARKER_MASK : 0); + + /* send RTP stream packet */ + if (sendto(sock, rtp_send_packet, sizeof(struct rtp_hdr) + rtp_payload_size, + 0, (struct sockaddr *)to, sizeof(struct sockaddr)) >= 0) { + rtphdr->seqNum = htons(ntohs(rtphdr->seqNum) + 1); + rtp_data_index += rtp_payload_size; + } else { + LWIP_DEBUGF(RTP_DEBUG, ("rtp_sender: not sendto==%i\n", errno)); + } + }while (rtp_data_index < sizeof(rtp_data)); +} + +/** + * RTP send thread + */ +static void +rtp_send_thread(void *arg) +{ + int sock; + struct sockaddr_in local; + struct sockaddr_in to; + u32_t rtp_stream_address; + + LWIP_UNUSED_ARG(arg); + + /* initialize RTP stream address */ + rtp_stream_address = RTP_STREAM_ADDRESS; + + /* if we got a valid RTP stream address... */ + if (rtp_stream_address != 0) { + /* create new socket */ + sock = socket(AF_INET, SOCK_DGRAM, 0); + if (sock >= 0) { + /* prepare local address */ + memset(&local, 0, sizeof(local)); + local.sin_family = AF_INET; + local.sin_port = PP_HTONS(INADDR_ANY); + local.sin_addr.s_addr = PP_HTONL(INADDR_ANY); + + /* bind to local address */ + if (bind(sock, (struct sockaddr *)&local, sizeof(local)) == 0) { + /* prepare RTP stream address */ + memset(&to, 0, sizeof(to)); + to.sin_family = AF_INET; + to.sin_port = PP_HTONS(RTP_STREAM_PORT); + to.sin_addr.s_addr = rtp_stream_address; + + /* send RTP packets */ + memset(rtp_send_packet, 0, sizeof(rtp_send_packet)); + while (1) { + rtp_send_packets( sock, &to); + sys_msleep(RTP_SEND_DELAY); + } + } + + /* close the socket */ + closesocket(sock); + } + } +} + +/** + * RTP recv thread + */ +static void +rtp_recv_thread(void *arg) +{ + int sock; + struct sockaddr_in local; + struct sockaddr_in from; + int fromlen; + struct ip_mreq ipmreq; + struct rtp_hdr* rtphdr; + u32_t rtp_stream_address; + int timeout; + int result; + int recvrtppackets = 0; + int lostrtppackets = 0; + u16_t lastrtpseq = 0; + + LWIP_UNUSED_ARG(arg); + + /* initialize RTP stream address */ + rtp_stream_address = RTP_STREAM_ADDRESS; + + /* if we got a valid RTP stream address... */ + if (rtp_stream_address != 0) { + /* create new socket */ + sock = socket(AF_INET, SOCK_DGRAM, 0); + if (sock >= 0) { + /* prepare local address */ + memset(&local, 0, sizeof(local)); + local.sin_family = AF_INET; + local.sin_port = PP_HTONS(RTP_STREAM_PORT); + local.sin_addr.s_addr = PP_HTONL(INADDR_ANY); + + /* bind to local address */ + if (bind(sock, (struct sockaddr *)&local, sizeof(local)) == 0) { + /* set recv timeout */ + timeout = RTP_RECV_TIMEOUT; + setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(timeout)); + + /* prepare multicast "ip_mreq" struct */ + ipmreq.imr_multiaddr.s_addr = rtp_stream_address; + ipmreq.imr_interface.s_addr = PP_HTONL(INADDR_ANY); + + /* join multicast group */ + if (setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, &ipmreq, sizeof(ipmreq)) == 0) { + /* receive RTP packets */ + while(1) { + fromlen = sizeof(from); + result = recvfrom(sock, rtp_recv_packet, sizeof(rtp_recv_packet), 0, + (struct sockaddr *)&from, (socklen_t *)&fromlen); + if (result >= sizeof(struct rtp_hdr)) { + rtphdr = (struct rtp_hdr *)rtp_recv_packet; + recvrtppackets++; + if ((lastrtpseq == 0) || ((lastrtpseq + 1) == ntohs(rtphdr->seqNum))) { + RTP_RECV_PROCESSING((rtp_recv_packet + sizeof(rtp_hdr)),(result-sizeof(rtp_hdr))); + } else { + lostrtppackets++; + } + lastrtpseq = ntohs(rtphdr->seqNum); + if ((recvrtppackets % RTP_RECV_STATS) == 0) { + LWIP_DEBUGF(RTP_DEBUG, ("rtp_recv_thread: recv %6i packet(s) / lost %4i packet(s) (%.4f%%)...\n", recvrtppackets, lostrtppackets, (lostrtppackets*100.0)/recvrtppackets)); + } + } else { + LWIP_DEBUGF(RTP_DEBUG, ("rtp_recv_thread: recv timeout...\n")); + } + } + + /* leave multicast group */ + setsockopt(sock, IPPROTO_IP, IP_DROP_MEMBERSHIP, &ipmreq, sizeof(ipmreq)); + } + } + + /* close the socket */ + closesocket(sock); + } + } +} + +void +rtp_init(void) +{ + sys_thread_new("rtp_send_thread", rtp_send_thread, NULL, DEFAULT_THREAD_STACKSIZE, DEFAULT_THREAD_PRIO); + sys_thread_new("rtp_recv_thread", rtp_recv_thread, NULL, DEFAULT_THREAD_STACKSIZE, DEFAULT_THREAD_PRIO); +} + +#endif /* LWIP_SOCKET && LWIP_IGMP */ diff --git a/src/lwip-1.4.1/apps/rtp/rtp.h b/src/lwip-1.4.1/apps/rtp/rtp.h new file mode 100644 index 0000000..5c5b443 --- /dev/null +++ b/src/lwip-1.4.1/apps/rtp/rtp.h @@ -0,0 +1,8 @@ +#ifndef __RTP_H__ +#define __RTP_H__ + +#if LWIP_SOCKET && LWIP_IGMP +void rtp_init(void); +#endif /* LWIP_SOCKET && LWIP_IGMP */ + +#endif /* __RTP_H__ */ diff --git a/src/lwip-1.4.1/apps/rtp/rtpdata.h b/src/lwip-1.4.1/apps/rtp/rtpdata.h new file mode 100644 index 0000000..655a1fe --- /dev/null +++ b/src/lwip-1.4.1/apps/rtp/rtpdata.h @@ -0,0 +1,2040 @@ +const char rtp_data[] = { + 0x00, 0x00, 0x01, 0xb0, 0xf5, 0x00, 0x00, 0x01, + 0xb5, 0x09, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x01, 0x20, 0x00, 0x86, 0x84, 0x00, 0x67, 0x0c, + 0x2c, 0x10, 0x90, 0x51, 0x8f, 0x00, 0x00, 0x01, + 0xb2, 0x44, 0x69, 0x76, 0x58, 0x35, 0x30, 0x33, + 0x62, 0x31, 0x33, 0x39, 0x33, 0x70, 0x00, 0x00, + 0x01, 0xb2, 0x58, 0x76, 0x69, 0x44, 0x30, 0x30, + 0x33, 0x39, 0x00, 0x00, 0x01, 0xb6, 0x18, 0x60, + 0xab, 0x94, 0x03, 0xc0, 0xca, 0xc0, 0x3e, 0xd0, + 0x78, 0x4f, 0xf9, 0x44, 0x91, 0xe9, 0xfa, 0xc9, + 0xfe, 0xa1, 0xa4, 0xc1, 0x66, 0x03, 0x2e, 0x39, + 0x0c, 0x7e, 0x0e, 0xaa, 0x02, 0x92, 0xf8, 0xd5, + 0xec, 0xe2, 0x35, 0xb9, 0x35, 0x0c, 0xb3, 0x82, + 0xa6, 0xad, 0xd0, 0xd1, 0xca, 0xb8, 0xe8, 0x10, + 0x55, 0x78, 0x03, 0xc0, 0x38, 0x15, 0xba, 0xce, + 0xe2, 0xea, 0x00, 0xc3, 0x60, 0xb1, 0x70, 0xf4, + 0x14, 0x6c, 0x35, 0x4d, 0xe8, 0x5a, 0x1e, 0x58, + 0xdf, 0x03, 0x01, 0xfd, 0x2a, 0x45, 0x54, 0xca, + 0x0f, 0x05, 0x00, 0xbd, 0xd0, 0xcc, 0xb4, 0x90, + 0x4c, 0x24, 0x6b, 0x20, 0x30, 0x95, 0xf1, 0x2f, + 0xb4, 0xa7, 0x83, 0xdc, 0xce, 0x03, 0x05, 0x02, + 0x1a, 0x5d, 0x1a, 0x2c, 0xbf, 0x51, 0x28, 0x8b, + 0xd7, 0x6b, 0xdd, 0xf9, 0x44, 0xbb, 0x0e, 0x91, + 0x64, 0xb9, 0xa6, 0x33, 0xd3, 0x6e, 0x34, 0xa4, + 0xac, 0xac, 0x53, 0x0d, 0x79, 0xbe, 0xae, 0x5b, + 0x47, 0x2e, 0xde, 0x62, 0xa1, 0x53, 0xcd, 0x7d, + 0xfe, 0x66, 0xa1, 0x2b, 0x9c, 0xe1, 0xca, 0xbc, + 0xea, 0x84, 0x1c, 0x68, 0xff, 0xbb, 0x28, 0xa1, + 0x26, 0x18, 0x99, 0xb1, 0x4f, 0x68, 0x80, 0x28, + 0x0e, 0x20, 0xc3, 0xbf, 0x0f, 0x80, 0xf8, 0x90, + 0x3b, 0x1f, 0x16, 0xe4, 0xb0, 0x6f, 0x44, 0x16, + 0x38, 0xb8, 0xc3, 0x81, 0x22, 0xfa, 0xe3, 0x09, + 0xf6, 0x61, 0x6d, 0xef, 0x67, 0x56, 0x3b, 0x57, + 0xb5, 0x23, 0x03, 0x1f, 0x6d, 0x0d, 0xb9, 0x08, + 0xc6, 0x43, 0xba, 0xd1, 0x40, 0x5a, 0xe8, 0xca, + 0x9e, 0x17, 0x1f, 0x6d, 0x5d, 0x16, 0x98, 0xab, + 0xe6, 0x99, 0xf6, 0x37, 0xc6, 0x1b, 0xdc, 0xb9, + 0xb3, 0xfe, 0x9a, 0x4b, 0x1e, 0xec, 0xf9, 0x5f, + 0xb8, 0xc7, 0xfc, 0xbe, 0x6c, 0xd5, 0xf3, 0x9b, + 0x17, 0x8b, 0x89, 0x82, 0xff, 0x30, 0x19, 0x20, + 0x30, 0xe6, 0x29, 0x96, 0x75, 0x75, 0xeb, 0x00, + 0x3f, 0xa1, 0x20, 0x5b, 0x06, 0x11, 0x98, 0x1f, + 0xb2, 0xad, 0x3a, 0x59, 0xe6, 0x7d, 0x38, 0xa4, + 0xb1, 0x4f, 0xfe, 0xdf, 0x3a, 0x4b, 0xdb, 0x69, + 0xc3, 0x93, 0xcc, 0xdf, 0x5e, 0xf7, 0x2a, 0x38, + 0x2a, 0x89, 0x84, 0x80, 0x6c, 0x12, 0x44, 0x95, + 0x78, 0xd8, 0x7e, 0x3f, 0x4e, 0xcf, 0x3f, 0x39, + 0xba, 0x9f, 0xfa, 0x8f, 0x2f, 0x62, 0xfa, 0xf0, + 0xb6, 0x20, 0xa7, 0x06, 0x02, 0x3f, 0x28, 0x96, + 0x80, 0xf0, 0x99, 0x8e, 0x82, 0x15, 0x11, 0x87, + 0x35, 0xa4, 0xfd, 0x53, 0xcb, 0xcd, 0x68, 0x38, + 0xe8, 0xdb, 0x8d, 0xc2, 0x71, 0xbc, 0x65, 0x3e, + 0xac, 0x5b, 0x0d, 0xae, 0xc0, 0x3c, 0x77, 0xfe, + 0xe8, 0xde, 0x3c, 0xbd, 0xdb, 0xb3, 0x39, 0x09, + 0x56, 0x0a, 0xa2, 0xfe, 0x40, 0xd7, 0x6f, 0x56, + 0x07, 0x02, 0xec, 0xd6, 0xed, 0x06, 0x5e, 0x2f, + 0xb6, 0xce, 0xf1, 0x4f, 0x16, 0x88, 0x04, 0x41, + 0x79, 0x0e, 0x98, 0xbe, 0x54, 0x75, 0x1a, 0xd6, + 0x50, 0xcf, 0x82, 0x6a, 0xf7, 0xaf, 0x7f, 0xfb, + 0x6d, 0x88, 0x97, 0x24, 0x40, 0x68, 0xa0, 0x57, + 0x79, 0x57, 0xe9, 0x6b, 0xaa, 0xe5, 0xe4, 0x2b, + 0xaa, 0x14, 0x64, 0x90, 0x6c, 0x50, 0x4a, 0xe3, + 0x97, 0x43, 0xf6, 0x81, 0x90, 0xa9, 0xa6, 0xba, + 0xb1, 0x21, 0x12, 0x5f, 0xe0, 0xdf, 0x88, 0x86, + 0x03, 0x30, 0x94, 0xb2, 0x6d, 0xd2, 0xdc, 0x45, + 0x14, 0x54, 0x1d, 0xe8, 0x38, 0x8d, 0xbe, 0x8a, + 0xaf, 0x20, 0xa2, 0x3e, 0xa2, 0x5c, 0xc6, 0xae, + 0xe6, 0xc4, 0x48, 0xec, 0xea, 0xc7, 0x4e, 0x17, + 0xb2, 0x91, 0x52, 0xb4, 0xe9, 0x8b, 0x15, 0xfb, + 0x99, 0x7c, 0xda, 0xb8, 0xad, 0x57, 0x31, 0x5b, + 0x5b, 0x67, 0xaa, 0x1e, 0x93, 0x76, 0xa5, 0x25, + 0xd9, 0x0d, 0x70, 0xd8, 0xb9, 0x11, 0x34, 0xfd, + 0xaf, 0x0e, 0x0d, 0x42, 0x57, 0x97, 0x26, 0x06, + 0xdf, 0x29, 0x7e, 0x79, 0x72, 0x22, 0x36, 0xa5, + 0x9f, 0x6a, 0x16, 0x24, 0x6f, 0x10, 0x56, 0xec, + 0x5b, 0x46, 0x50, 0x94, 0x88, 0xc4, 0xfa, 0x9e, + 0xd8, 0x5b, 0xb7, 0x50, 0x72, 0x62, 0x25, 0xaa, + 0x39, 0x84, 0x69, 0xaa, 0xfc, 0xbf, 0x9b, 0x45, + 0xf7, 0xc5, 0x41, 0x97, 0x41, 0xc7, 0xac, 0x7f, + 0x68, 0x92, 0xab, 0x64, 0xaa, 0x46, 0x32, 0x84, + 0x77, 0x1b, 0xfc, 0xbc, 0x5a, 0x42, 0x28, 0xfa, + 0x3e, 0x55, 0xf4, 0xe9, 0x44, 0xac, 0xc5, 0x4a, + 0x6c, 0x93, 0xde, 0x03, 0x6d, 0xdc, 0xb8, 0x5b, + 0xb7, 0x83, 0x7e, 0xc2, 0xaa, 0x33, 0x70, 0x34, + 0x41, 0x46, 0x25, 0xa5, 0x6f, 0xdb, 0x96, 0x0f, + 0xd3, 0xab, 0xd4, 0x17, 0x65, 0x96, 0x0c, 0x1e, + 0x39, 0x4c, 0x9d, 0x90, 0x3f, 0x5b, 0x8d, 0xaa, + 0xce, 0xac, 0xa6, 0x50, 0xf0, 0x66, 0xb2, 0x30, + 0xce, 0x42, 0x61, 0xaa, 0xb6, 0x7e, 0xca, 0xbf, + 0xfd, 0xbf, 0xef, 0x51, 0xed, 0xdf, 0x95, 0x0b, + 0xa7, 0x34, 0x24, 0x13, 0x62, 0x44, 0x81, 0xdf, + 0x3a, 0x8e, 0x95, 0x91, 0x67, 0xd7, 0x57, 0x54, + 0x92, 0x1d, 0x79, 0xa3, 0x2a, 0xf3, 0x0c, 0x7a, + 0x12, 0xa8, 0x33, 0xf9, 0x05, 0x02, 0x7b, 0xef, + 0x12, 0x18, 0xab, 0x8b, 0x40, 0x38, 0x7e, 0x0c, + 0x1f, 0x04, 0x30, 0x62, 0xa8, 0xd5, 0xd9, 0x78, + 0xdd, 0x1c, 0xb4, 0x57, 0xc1, 0x83, 0xc4, 0x41, + 0x08, 0x72, 0x5c, 0xc2, 0xb6, 0xd3, 0xd4, 0x85, + 0x4a, 0x7e, 0x58, 0xc3, 0x19, 0xfa, 0xdd, 0x51, + 0x03, 0x85, 0x1d, 0xe9, 0x10, 0x5e, 0x8c, 0x8f, + 0x41, 0x03, 0xe9, 0xbc, 0xa8, 0xba, 0xeb, 0x73, + 0x7d, 0x85, 0x69, 0xc7, 0x3b, 0xd9, 0x49, 0x0b, + 0x39, 0x03, 0x12, 0x11, 0x8b, 0x72, 0x97, 0x62, + 0x5f, 0xfe, 0x59, 0x4d, 0xc0, 0x3a, 0xdf, 0xcb, + 0x3e, 0x80, 0x39, 0xd5, 0x7a, 0xb1, 0x45, 0x86, + 0x06, 0xf6, 0xb6, 0xda, 0x98, 0xa1, 0x41, 0xae, + 0x12, 0xd3, 0xd1, 0x71, 0x5a, 0xa5, 0x40, 0xc0, + 0x8a, 0x3f, 0x4e, 0xac, 0x78, 0x93, 0x55, 0x31, + 0xfc, 0xcf, 0x67, 0x93, 0x52, 0xc4, 0x53, 0x0d, + 0xdf, 0x49, 0xd7, 0x83, 0x00, 0x18, 0x4b, 0xcd, + 0x65, 0xaf, 0xb5, 0xd5, 0x6c, 0xc4, 0x14, 0xb7, + 0xdb, 0x9d, 0x06, 0x17, 0xca, 0xe1, 0x60, 0x07, + 0x6d, 0x57, 0xd0, 0xfb, 0x1a, 0xf5, 0xb2, 0x56, + 0xca, 0xea, 0x21, 0x77, 0x41, 0xc0, 0x46, 0xc8, + 0x85, 0xe3, 0x15, 0x6a, 0xdb, 0x80, 0x47, 0x6d, + 0x05, 0x44, 0x06, 0x04, 0xf6, 0x92, 0x24, 0xdb, + 0x9b, 0x6f, 0xfa, 0x8d, 0x72, 0x2d, 0x75, 0x7e, + 0x33, 0x9c, 0xe7, 0x06, 0xbb, 0x3d, 0xa4, 0xb7, + 0xee, 0x31, 0x46, 0x4b, 0x91, 0xe2, 0xb0, 0x54, + 0x5c, 0x78, 0x9e, 0x45, 0x90, 0xe4, 0x76, 0xbe, + 0xe1, 0x4c, 0xae, 0x89, 0x20, 0x6e, 0x77, 0x76, + 0x94, 0x63, 0x93, 0xaa, 0x62, 0x0e, 0x28, 0x7b, + 0xec, 0xc9, 0xc5, 0x25, 0x64, 0x5a, 0xe9, 0xcc, + 0x91, 0x1a, 0x9c, 0xcf, 0x91, 0x47, 0x32, 0x12, + 0x9f, 0x8b, 0x36, 0x07, 0x33, 0x4c, 0x45, 0x06, + 0x19, 0xdb, 0x61, 0xc5, 0x68, 0xb7, 0xab, 0x2e, + 0x7b, 0x5c, 0xa6, 0x4c, 0x6e, 0x08, 0x5f, 0xc1, + 0xc4, 0x99, 0x64, 0xef, 0xd8, 0x05, 0x5c, 0x0f, + 0x76, 0xdd, 0xab, 0x4f, 0x8e, 0x29, 0x54, 0x59, + 0x1d, 0x30, 0x33, 0xfb, 0x3b, 0x43, 0x96, 0xf4, + 0x52, 0x47, 0x2c, 0x66, 0x81, 0xca, 0xa6, 0x73, + 0x51, 0xc1, 0xc0, 0x32, 0x98, 0xa3, 0x41, 0x1c, + 0x40, 0x5e, 0x22, 0x05, 0xa0, 0xdb, 0xb0, 0x88, + 0xdf, 0xee, 0x2f, 0x3a, 0xbb, 0xe2, 0xef, 0x79, + 0x09, 0xa6, 0x0c, 0x0f, 0x4c, 0xdc, 0x81, 0xcc, + 0x3d, 0x36, 0x52, 0x4e, 0xbd, 0x44, 0x0d, 0x0d, + 0x84, 0xf5, 0x74, 0x33, 0x14, 0x1a, 0x87, 0xcb, + 0xcc, 0x93, 0xa3, 0x69, 0x21, 0x20, 0x26, 0x23, + 0xd9, 0x95, 0x0c, 0x22, 0x2b, 0x2f, 0x0d, 0xf4, + 0x34, 0x74, 0x53, 0x16, 0x5d, 0x60, 0x96, 0x3e, + 0x53, 0xd3, 0xcc, 0xc5, 0x72, 0x49, 0xc2, 0x4d, + 0xea, 0x02, 0x21, 0x7f, 0xbd, 0x80, 0x1d, 0xf0, + 0x87, 0xe6, 0xdb, 0xcc, 0x92, 0xdd, 0xfe, 0x78, + 0x4a, 0xd2, 0xf9, 0x77, 0x24, 0xed, 0x5a, 0x31, + 0x6c, 0xec, 0x71, 0x5d, 0x85, 0xad, 0xb3, 0xb9, + 0x6f, 0x11, 0x2d, 0xfa, 0x42, 0x2b, 0xcb, 0x01, + 0x08, 0x18, 0x11, 0x56, 0xcb, 0x01, 0xe1, 0xe0, + 0x1f, 0x06, 0xe8, 0x3c, 0x6c, 0x01, 0xaa, 0x49, + 0x86, 0xbf, 0x63, 0x79, 0x03, 0xbe, 0xd8, 0x47, + 0x4f, 0x26, 0x0d, 0x11, 0xe3, 0x76, 0x27, 0x0e, + 0xf1, 0x79, 0x44, 0x46, 0xc3, 0x3b, 0x4f, 0x05, + 0x20, 0x40, 0xff, 0x59, 0x6f, 0xaa, 0x17, 0xf4, + 0x40, 0xa1, 0x15, 0x0a, 0x4c, 0x0f, 0x94, 0x81, + 0xb8, 0x0c, 0x8e, 0x8d, 0xc3, 0x80, 0xc1, 0xeb, + 0x02, 0x16, 0xf4, 0xbe, 0xca, 0xa4, 0x3a, 0xa8, + 0xec, 0x0c, 0x89, 0xc4, 0x59, 0xe4, 0x8b, 0x9a, + 0x40, 0x7e, 0xae, 0xea, 0xa0, 0xeb, 0x6a, 0x99, + 0x95, 0x73, 0x79, 0x62, 0x18, 0xb8, 0x38, 0x64, + 0x73, 0x97, 0xb7, 0x58, 0xd1, 0x2d, 0x8d, 0xbe, + 0xf3, 0x13, 0x2f, 0x7c, 0xc0, 0x1d, 0x61, 0x4e, + 0x4c, 0xe6, 0x95, 0xce, 0x97, 0xf9, 0xbc, 0xf4, + 0x5a, 0xce, 0xa1, 0x3b, 0x39, 0xef, 0xc5, 0x39, + 0x4b, 0x72, 0x1b, 0xa5, 0x41, 0x92, 0x27, 0xda, + 0x72, 0xc2, 0xbb, 0xd4, 0x8d, 0x34, 0x97, 0x9d, + 0xb7, 0xde, 0xe7, 0xb0, 0x64, 0x8a, 0x0a, 0x0c, + 0x0e, 0x60, 0x30, 0x62, 0xb8, 0xbb, 0x9f, 0x96, + 0x05, 0x31, 0x33, 0xfa, 0x3c, 0x1f, 0xf4, 0x3d, + 0x04, 0x3c, 0x5c, 0x1e, 0x1b, 0xfe, 0xf1, 0xfe, + 0xa1, 0xb1, 0x03, 0x54, 0x99, 0x50, 0x61, 0xc5, + 0xbc, 0x2d, 0x00, 0xfe, 0xaf, 0x01, 0xe1, 0x7f, + 0xeb, 0xd4, 0x77, 0x0d, 0xb4, 0x0a, 0x9c, 0x18, + 0x92, 0x3d, 0x5a, 0xbf, 0xc0, 0x98, 0x66, 0xcc, + 0x06, 0x09, 0x6a, 0x50, 0xe9, 0x18, 0x32, 0x00, + 0x78, 0xc8, 0x06, 0x68, 0xac, 0x8b, 0x3f, 0x38, + 0xbf, 0x4a, 0x33, 0x30, 0x1c, 0x4f, 0xae, 0x16, + 0x44, 0x98, 0x24, 0x08, 0xc9, 0x07, 0xed, 0x62, + 0xbb, 0x89, 0x15, 0xca, 0x0f, 0x09, 0x00, 0x7a, + 0x51, 0xc5, 0x93, 0x54, 0x45, 0xfb, 0x73, 0xdf, + 0xe9, 0x42, 0x07, 0x90, 0x10, 0xcb, 0xdb, 0x2b, + 0x47, 0x20, 0x2b, 0xaa, 0xf4, 0x5c, 0xa4, 0x28, + 0x38, 0x9d, 0x5a, 0x44, 0x22, 0x0d, 0x54, 0x81, + 0x1d, 0x07, 0x0a, 0x37, 0xee, 0x49, 0x8b, 0xfb, + 0x3a, 0x8d, 0x7e, 0x83, 0x84, 0xfd, 0xf7, 0x98, + 0xad, 0xac, 0xa7, 0x46, 0x07, 0x62, 0x72, 0x56, + 0x1c, 0x03, 0x05, 0x4d, 0x70, 0xd8, 0x60, 0x62, + 0x8a, 0x8d, 0xe8, 0x23, 0x03, 0x04, 0x6d, 0x60, + 0xdc, 0x2a, 0x27, 0x92, 0x08, 0x8f, 0x65, 0xed, + 0xbd, 0xca, 0xa5, 0x1d, 0x80, 0x8d, 0x11, 0x03, + 0x83, 0xc7, 0x05, 0x04, 0x85, 0xcd, 0x2f, 0x3a, + 0xd4, 0x83, 0x02, 0x91, 0x91, 0xc5, 0x76, 0xb5, + 0x79, 0xcb, 0xfb, 0x29, 0x22, 0x90, 0x1e, 0x09, + 0x9f, 0x2c, 0x07, 0x77, 0xa0, 0x38, 0xf8, 0x63, + 0xf5, 0x2a, 0xd4, 0xc5, 0x0f, 0xd7, 0x43, 0x38, + 0xb5, 0xe8, 0x38, 0x94, 0x29, 0x71, 0x68, 0xb4, + 0x99, 0x0a, 0x4d, 0xf6, 0x94, 0x9d, 0x8e, 0x96, + 0x58, 0x88, 0x63, 0x46, 0x02, 0x9d, 0x64, 0x83, + 0x70, 0x72, 0x32, 0x6f, 0x90, 0x1d, 0x0e, 0xd5, + 0xf5, 0xd9, 0x0d, 0xe8, 0x0f, 0xa3, 0x20, 0x5f, + 0x26, 0x59, 0xc3, 0x50, 0x33, 0x04, 0xc9, 0x0c, + 0xc8, 0xa2, 0xce, 0x12, 0x43, 0x44, 0xa3, 0x55, + 0xe5, 0x07, 0x05, 0x1a, 0x69, 0xa8, 0xc4, 0x39, + 0x92, 0xa2, 0x44, 0x0e, 0x08, 0xe0, 0xa2, 0x4a, + 0x28, 0xd7, 0x80, 0xe1, 0x37, 0x96, 0x0c, 0x49, + 0x28, 0x0f, 0x3c, 0xc8, 0xe2, 0xc1, 0x5d, 0x4f, + 0xd4, 0x48, 0xa2, 0x21, 0x59, 0xf1, 0x0d, 0x9f, + 0xaa, 0xc6, 0x77, 0xc8, 0xe5, 0xce, 0x0d, 0xca, + 0x02, 0x87, 0x4a, 0x49, 0x01, 0xc8, 0x48, 0xc8, + 0xf3, 0x1b, 0x2f, 0xdf, 0x6c, 0xcb, 0x88, 0x66, + 0xf1, 0x40, 0xbd, 0x6a, 0x34, 0xfc, 0xb0, 0x89, + 0xde, 0x11, 0xc5, 0xc6, 0xa2, 0x44, 0xc6, 0xdb, + 0x67, 0xff, 0xd1, 0x79, 0x01, 0xa4, 0x9e, 0xf0, + 0x1f, 0x10, 0x57, 0x2b, 0x24, 0xc5, 0x1c, 0x09, + 0x45, 0x7e, 0xcc, 0x55, 0xe5, 0x0d, 0x64, 0xe2, + 0x2c, 0xe4, 0xea, 0xe4, 0x81, 0x31, 0xfd, 0x61, + 0x38, 0x8f, 0xba, 0x1f, 0xb4, 0xd9, 0x6c, 0xa8, + 0xac, 0xe4, 0xe8, 0xca, 0x9e, 0xee, 0xa9, 0x51, + 0xd7, 0xe9, 0x9d, 0xcc, 0xb0, 0x7c, 0x24, 0xc5, + 0x13, 0xa0, 0x89, 0x78, 0x0b, 0x15, 0xd1, 0x09, + 0xe4, 0xbf, 0x34, 0x6f, 0xcf, 0x0b, 0x82, 0x51, + 0xb3, 0x70, 0x7d, 0x83, 0xe1, 0x24, 0x0d, 0x33, + 0xad, 0xda, 0x5d, 0xfe, 0xe7, 0x38, 0x54, 0x52, + 0x0e, 0x3d, 0xd5, 0xec, 0xef, 0x0b, 0x05, 0xe1, + 0x16, 0xa9, 0x45, 0xec, 0x5f, 0x81, 0xb9, 0xc8, + 0xff, 0x36, 0x0e, 0x0e, 0x01, 0x81, 0x31, 0xae, + 0x4b, 0x35, 0xd8, 0x18, 0x17, 0x8c, 0x33, 0x7a, + 0xa2, 0xee, 0x06, 0x5b, 0xd8, 0x0b, 0x07, 0xb0, + 0x52, 0xbe, 0xf6, 0xf4, 0x38, 0xec, 0x35, 0x6e, + 0x45, 0xc1, 0x5e, 0x51, 0xd3, 0x67, 0x93, 0x6d, + 0xaf, 0xd0, 0xe0, 0x2a, 0xea, 0x6a, 0x1e, 0x03, + 0x0c, 0x38, 0xa4, 0x38, 0xea, 0x34, 0x41, 0x99, + 0xcb, 0xe0, 0xcd, 0xda, 0xf2, 0xee, 0x86, 0x28, + 0x83, 0x38, 0x0b, 0x13, 0xd1, 0x73, 0x1e, 0x4f, + 0xb5, 0x18, 0x7d, 0xef, 0xed, 0x09, 0xdf, 0xf7, + 0x4a, 0x91, 0xdb, 0x41, 0x84, 0xf7, 0x07, 0x14, + 0x15, 0x3b, 0x01, 0xc5, 0x28, 0x41, 0x78, 0x9f, + 0xf6, 0x92, 0xce, 0x06, 0xe0, 0xb9, 0x9d, 0xa0, + 0xee, 0xf0, 0x25, 0xa9, 0xd4, 0xe0, 0x71, 0xb4, + 0x66, 0x0c, 0x11, 0x47, 0x01, 0x89, 0x34, 0x62, + 0x11, 0x60, 0x27, 0xa0, 0xfb, 0x1f, 0xfe, 0xd1, + 0x50, 0x6e, 0x0e, 0x23, 0xc3, 0xd8, 0x0e, 0xe8, + 0x53, 0xa7, 0x94, 0x03, 0x12, 0x41, 0x9a, 0x90, + 0x97, 0xce, 0x87, 0x0d, 0x42, 0x9d, 0x07, 0xce, + 0xff, 0xef, 0x4e, 0x07, 0x1a, 0x31, 0x08, 0x92, + 0x98, 0x0c, 0x49, 0x46, 0x74, 0x22, 0x2a, 0xf1, + 0x01, 0x51, 0x48, 0x26, 0xe9, 0xf5, 0xcd, 0xb0, + 0x0c, 0x2e, 0xa1, 0x3d, 0x29, 0x05, 0x4f, 0xa0, + 0x12, 0x06, 0x08, 0x9c, 0x94, 0x08, 0x60, 0xce, + 0xd0, 0x96, 0x81, 0x81, 0x18, 0x62, 0x03, 0xcc, + 0xba, 0x15, 0xd6, 0x91, 0x11, 0x14, 0x7e, 0xb2, + 0x7e, 0xd4, 0x56, 0x74, 0x37, 0xdc, 0x82, 0xfb, + 0x21, 0xa1, 0x93, 0x91, 0x60, 0x3d, 0xcb, 0x28, + 0x4b, 0x52, 0xe9, 0x26, 0x4a, 0x0c, 0x32, 0xca, + 0x31, 0xab, 0x10, 0x19, 0x6e, 0x76, 0x50, 0x1e, + 0x7c, 0x89, 0x2f, 0x42, 0x4a, 0x46, 0xf8, 0xb1, + 0x5e, 0xdc, 0xbe, 0x81, 0x4a, 0x0c, 0x4e, 0x6a, + 0x31, 0x70, 0xd4, 0x17, 0x62, 0x30, 0xf8, 0xbb, + 0xaa, 0xba, 0x06, 0x98, 0xf4, 0x05, 0x40, 0x7c, + 0x8e, 0x81, 0x22, 0xc7, 0x8b, 0xf2, 0x67, 0x49, + 0x64, 0x58, 0x1c, 0xb8, 0xa0, 0x6d, 0xb9, 0xea, + 0x5b, 0x11, 0x47, 0x18, 0xe7, 0xd0, 0xbc, 0xce, + 0xf3, 0x9d, 0x19, 0x10, 0x92, 0x95, 0x45, 0x47, + 0x78, 0x87, 0x81, 0x32, 0x6b, 0xc0, 0xe5, 0x7a, + 0x79, 0x25, 0x37, 0x0d, 0x05, 0x06, 0x73, 0x39, + 0x50, 0x9f, 0x8f, 0x5d, 0x09, 0x24, 0x34, 0x32, + 0x18, 0x04, 0x62, 0x9c, 0xe8, 0x1e, 0x06, 0x52, + 0x88, 0x1e, 0x26, 0x01, 0x30, 0x36, 0x81, 0x60, + 0x63, 0x41, 0x6a, 0x77, 0xa8, 0x42, 0xd4, 0xba, + 0x1f, 0x0e, 0x79, 0x06, 0x2d, 0x16, 0x83, 0x00, + 0xe3, 0xe6, 0xcb, 0xba, 0x82, 0x4a, 0x27, 0xd7, + 0x5e, 0xdc, 0x58, 0x44, 0x19, 0x28, 0x0c, 0xc7, + 0x2f, 0x57, 0xb2, 0x83, 0x83, 0x40, 0xcc, 0x1c, + 0xb8, 0x99, 0x41, 0xb9, 0xb0, 0xc8, 0x1f, 0x36, + 0x00, 0x75, 0x14, 0xa9, 0x25, 0x34, 0x87, 0x83, + 0x05, 0x13, 0x16, 0x7d, 0x91, 0x40, 0x3b, 0x9c, + 0xe8, 0x38, 0x57, 0x17, 0xd2, 0x03, 0xc0, 0xff, + 0x4e, 0x0c, 0x1f, 0x16, 0x96, 0xc0, 0xe3, 0x8d, + 0x62, 0x75, 0xb8, 0x04, 0xae, 0x03, 0x80, 0x88, + 0xa1, 0x56, 0x31, 0x57, 0x66, 0x2d, 0x8a, 0xef, + 0x11, 0x6f, 0xca, 0xe9, 0x47, 0x79, 0xd0, 0x9d, + 0x0c, 0xb0, 0x18, 0x47, 0x06, 0x03, 0x57, 0x2c, + 0xda, 0x8f, 0x4a, 0x80, 0xd9, 0xa0, 0x62, 0x80, + 0x60, 0x4d, 0x95, 0x18, 0x8c, 0x18, 0x45, 0xcb, + 0x17, 0xad, 0x34, 0xa3, 0xd2, 0xa1, 0xb5, 0xd3, + 0x32, 0xd9, 0xdb, 0xd1, 0x82, 0x98, 0x18, 0x83, + 0xa9, 0xcd, 0xb5, 0x20, 0x77, 0x03, 0x5c, 0x5f, + 0xa6, 0xdb, 0x48, 0x12, 0xd7, 0x46, 0xc8, 0xd1, + 0x78, 0x1c, 0x1d, 0x17, 0x04, 0x91, 0xe8, 0xbc, + 0x2a, 0xa0, 0x53, 0x83, 0x11, 0x29, 0xff, 0x18, + 0xfe, 0x8d, 0x98, 0x6e, 0xad, 0x11, 0x65, 0xa0, + 0xc8, 0x3c, 0x48, 0x48, 0x13, 0x55, 0x28, 0xf5, + 0x61, 0x9d, 0xe0, 0x38, 0x5e, 0x12, 0xc0, 0x70, + 0x44, 0xbf, 0x6f, 0x25, 0x9d, 0x2b, 0xcf, 0xb6, + 0x79, 0x3d, 0xcf, 0x45, 0x32, 0xa8, 0x19, 0x67, + 0x3a, 0x14, 0x43, 0x6d, 0x7d, 0xa1, 0x04, 0xb7, + 0x3e, 0xd3, 0x75, 0x45, 0x2a, 0x6a, 0x6d, 0xb2, + 0x12, 0x87, 0x90, 0xa0, 0x6b, 0xbf, 0x1a, 0x5b, + 0xb7, 0x14, 0xd0, 0x26, 0x88, 0x5e, 0xb8, 0x4d, + 0x70, 0x19, 0x65, 0x36, 0xdd, 0x9c, 0x40, 0x7a, + 0xbf, 0x21, 0xc8, 0x38, 0x38, 0x01, 0xca, 0x1e, + 0xc5, 0xee, 0xb3, 0x40, 0xc0, 0x9a, 0xd6, 0x24, + 0xa7, 0xb4, 0x6b, 0x06, 0x18, 0xfc, 0x1c, 0x11, + 0xaf, 0x6d, 0xcc, 0xbd, 0x5e, 0xc8, 0x8e, 0x07, + 0xbc, 0xe0, 0x52, 0x8f, 0x9a, 0xb1, 0x74, 0x40, + 0xe4, 0x63, 0x20, 0x99, 0x4f, 0xa8, 0xbc, 0x0e, + 0xf2, 0x86, 0x80, 0xea, 0x09, 0x8a, 0xec, 0xdd, + 0xe7, 0x39, 0x49, 0x6e, 0xc4, 0x5c, 0x5d, 0x0d, + 0x45, 0xd1, 0x7b, 0x8b, 0xd5, 0xaf, 0x43, 0x17, + 0xe9, 0x49, 0xac, 0x6d, 0x10, 0xa6, 0x4e, 0x5e, + 0xa8, 0xc8, 0x20, 0xca, 0x54, 0x8e, 0xa1, 0x15, + 0xb5, 0x0d, 0xa0, 0x66, 0x70, 0x93, 0x6f, 0x01, + 0xc4, 0x2b, 0xc1, 0x46, 0xbd, 0x74, 0x96, 0x05, + 0x75, 0x50, 0xc0, 0xc3, 0x8b, 0x22, 0x25, 0x07, + 0x1d, 0xf6, 0x70, 0x92, 0x2d, 0x17, 0x09, 0xcb, + 0xef, 0xbd, 0x88, 0xd6, 0x46, 0x7b, 0xbd, 0xa0, + 0xe7, 0xe9, 0xc7, 0x09, 0x01, 0xc0, 0xb1, 0x29, + 0x3a, 0xc1, 0xdd, 0x05, 0xd2, 0x6a, 0x60, 0x73, + 0x06, 0x54, 0x26, 0x84, 0x0b, 0x22, 0x42, 0x7e, + 0x0d, 0x62, 0xfe, 0xc5, 0xb8, 0x30, 0x3a, 0xa2, + 0x5f, 0x5b, 0xee, 0x6c, 0xc2, 0x50, 0x7a, 0x18, + 0x00, 0xdf, 0x86, 0x41, 0x97, 0x16, 0x3d, 0xd9, + 0xcb, 0x09, 0x46, 0x40, 0xb0, 0x04, 0xe5, 0xa0, + 0xbb, 0xa9, 0x8d, 0x84, 0xa6, 0xd4, 0xb7, 0x53, + 0xb2, 0xdf, 0x33, 0x16, 0x41, 0x38, 0x2f, 0x3c, + 0xa8, 0x21, 0xef, 0x3e, 0xd6, 0xcd, 0x8b, 0xf9, + 0x1f, 0x03, 0x7a, 0x29, 0x18, 0x84, 0x26, 0x7f, + 0xe1, 0xdf, 0x98, 0x1c, 0x36, 0x58, 0xdc, 0x51, + 0xde, 0x2d, 0x35, 0x1f, 0x69, 0xa7, 0x0a, 0x82, + 0x08, 0xe9, 0x59, 0x7f, 0x2b, 0x4a, 0x39, 0x25, + 0x96, 0x5f, 0xf1, 0x08, 0xa6, 0x5b, 0x4b, 0x67, + 0x51, 0x12, 0xf0, 0xf2, 0xae, 0x68, 0xbb, 0x72, + 0xef, 0x0a, 0xb6, 0x02, 0xbd, 0x14, 0x42, 0x37, + 0x1b, 0x80, 0xe2, 0x3a, 0xb7, 0xb4, 0x1c, 0x0a, + 0x9b, 0xa0, 0xea, 0x11, 0x21, 0x4b, 0x07, 0xc9, + 0x93, 0xb7, 0x7b, 0xd1, 0x13, 0x8d, 0x62, 0xfd, + 0x28, 0xbd, 0x44, 0x0e, 0x0f, 0x4e, 0x49, 0xb4, + 0x43, 0x11, 0xc0, 0x38, 0x38, 0x08, 0xd2, 0xd9, + 0x2e, 0x2c, 0x03, 0x9f, 0xa7, 0xd6, 0x37, 0x46, + 0x01, 0x1f, 0x58, 0x56, 0xc0, 0x9c, 0x07, 0x0c, + 0x9d, 0xba, 0x0a, 0x9a, 0x15, 0xd4, 0x63, 0x6a, + 0x13, 0x69, 0xe0, 0x6f, 0x4c, 0xd0, 0x53, 0xc0, + 0xf6, 0x6f, 0x3c, 0xb7, 0x7d, 0xcb, 0x3b, 0x40, + 0x8e, 0xfa, 0x04, 0x48, 0x16, 0x35, 0x8b, 0x7d, + 0xbc, 0x81, 0xaa, 0xb2, 0xe8, 0xbf, 0x7a, 0x0c, + 0x1c, 0xfe, 0x86, 0x26, 0x8e, 0x86, 0x25, 0x83, + 0x9d, 0x07, 0x11, 0xcf, 0xb8, 0x5b, 0x88, 0xe9, + 0x5e, 0x12, 0x21, 0x13, 0xed, 0xb1, 0xfa, 0x0c, + 0x87, 0xf0, 0xa3, 0x96, 0x05, 0x75, 0x33, 0x7a, + 0x3d, 0x1f, 0x09, 0x49, 0x58, 0x56, 0x9d, 0x95, + 0x5e, 0x52, 0x9b, 0x30, 0x3d, 0x64, 0x3d, 0xe4, + 0xde, 0xcb, 0x3c, 0x59, 0x56, 0x0d, 0xd4, 0x94, + 0x43, 0xf6, 0x24, 0xb7, 0x19, 0x1f, 0xa5, 0x6f, + 0xd7, 0xc5, 0x9f, 0x56, 0xde, 0xe7, 0x38, 0x8a, + 0xed, 0x3c, 0x15, 0xc1, 0x9b, 0x6b, 0x55, 0xab, + 0x11, 0xa4, 0xce, 0xef, 0xd2, 0x4c, 0x88, 0x00, + 0xad, 0x15, 0x18, 0xff, 0xb5, 0xad, 0xdf, 0x6f, + 0xa4, 0xdc, 0xbc, 0xab, 0x84, 0x65, 0x30, 0xab, + 0x09, 0x6b, 0xf4, 0xff, 0x43, 0x78, 0x30, 0x08, + 0xa7, 0xa0, 0xa9, 0xa2, 0xf0, 0x8b, 0x72, 0x82, + 0xa0, 0x5c, 0x12, 0xb0, 0x27, 0xe1, 0x84, 0x09, + 0x27, 0x6e, 0x2d, 0x62, 0xc6, 0xd1, 0x85, 0x1a, + 0x72, 0xb1, 0xbf, 0x83, 0xcc, 0x7f, 0xfa, 0x13, + 0x54, 0xe0, 0x71, 0xfa, 0x0e, 0x23, 0x7d, 0x06, + 0x25, 0x18, 0x4a, 0x11, 0x69, 0x43, 0x76, 0xe8, + 0xc8, 0x18, 0x23, 0x96, 0x15, 0x2c, 0x7f, 0x4e, + 0x8b, 0x01, 0x83, 0x6d, 0x18, 0x83, 0x04, 0x5b, + 0x80, 0xa8, 0xc1, 0x9d, 0x01, 0xfa, 0xe2, 0xa3, + 0x8d, 0x4f, 0xe9, 0x63, 0x0d, 0xfe, 0xe7, 0x7b, + 0xcc, 0x5e, 0x86, 0xf5, 0x1b, 0xae, 0x0e, 0x93, + 0xa0, 0x1f, 0x36, 0x33, 0xe8, 0x0e, 0x74, 0xcf, + 0xa0, 0x43, 0x11, 0x82, 0x6d, 0x5a, 0xa8, 0xa6, + 0x1a, 0xcb, 0xa1, 0xb4, 0x99, 0x6a, 0x08, 0x8f, + 0x68, 0x30, 0x2c, 0x5f, 0x51, 0xfd, 0x10, 0x1a, + 0xff, 0xd6, 0xec, 0xe7, 0x7a, 0xc7, 0xaf, 0x49, + 0x16, 0xbb, 0x51, 0x50, 0xad, 0xbf, 0x8b, 0x76, + 0x86, 0x20, 0x9b, 0x11, 0x81, 0xc5, 0x1b, 0x6f, + 0x06, 0xdf, 0xfc, 0x28, 0xda, 0xe9, 0x03, 0x6a, + 0xc1, 0x83, 0x96, 0xc1, 0x86, 0x3a, 0x12, 0xd2, + 0x8a, 0x8c, 0x83, 0x85, 0xd0, 0xa0, 0xf3, 0x2e, + 0x86, 0xee, 0xe1, 0xb7, 0xa1, 0x6d, 0x16, 0x2e, + 0xf4, 0x46, 0xc1, 0x45, 0x99, 0xd2, 0x6d, 0x72, + 0xd2, 0xe6, 0x52, 0x84, 0x07, 0x84, 0xf3, 0xc0, + 0xe0, 0x0e, 0xa2, 0x1f, 0x6c, 0xce, 0xf6, 0x83, + 0xc1, 0xc0, 0x3f, 0x47, 0xb9, 0x68, 0xc8, 0x11, + 0x04, 0x14, 0x40, 0xc3, 0x43, 0x13, 0xa0, 0xf3, + 0xff, 0xff, 0xbe, 0xfe, 0x58, 0xd4, 0x51, 0x7b, + 0x0a, 0x01, 0x62, 0x48, 0xe1, 0x9b, 0x6b, 0x65, + 0x8b, 0x54, 0x41, 0xc8, 0x9d, 0x57, 0x57, 0x64, + 0xf7, 0x51, 0x83, 0x0c, 0x47, 0x25, 0x01, 0xc8, + 0xad, 0x4a, 0x58, 0x4b, 0x05, 0xe0, 0xc0, 0x3d, + 0x10, 0x4e, 0xb5, 0x85, 0xb8, 0xbc, 0xb0, 0x1e, + 0x2a, 0x00, 0xb0, 0x58, 0xbd, 0x5e, 0xca, 0x4a, + 0x0c, 0x2e, 0x19, 0x82, 0xe5, 0x3e, 0x8b, 0xa0, + 0xe0, 0xc8, 0x8a, 0xae, 0xe7, 0xbe, 0x55, 0xbc, + 0x45, 0x4a, 0x60, 0x60, 0x09, 0xcb, 0x89, 0x4c, + 0x32, 0x08, 0x6d, 0x09, 0x0d, 0xb4, 0xd2, 0x54, + 0xf8, 0xa8, 0xab, 0xca, 0x6f, 0xc4, 0xbf, 0x00, + 0xe6, 0xb6, 0x8c, 0x4f, 0xc6, 0x16, 0xf7, 0x67, + 0x1a, 0x9b, 0x2a, 0x1c, 0xe0, 0x0e, 0x44, 0x80, + 0x80, 0x34, 0xb2, 0x9d, 0x59, 0x58, 0x17, 0xd1, + 0x87, 0x81, 0x60, 0x2c, 0xf8, 0x0a, 0xad, 0x69, + 0x49, 0x5d, 0x40, 0x43, 0x1b, 0x4e, 0x83, 0x7c, + 0x48, 0x88, 0x92, 0x09, 0x3f, 0x05, 0x78, 0xf6, + 0xc0, 0x60, 0xc9, 0xea, 0xd0, 0x66, 0xd3, 0x20, + 0x08, 0x5b, 0xa0, 0xaf, 0x1d, 0xb3, 0xa1, 0x35, + 0x2e, 0x1c, 0xc8, 0x33, 0x09, 0x1a, 0x34, 0x6d, + 0x83, 0x06, 0x61, 0x21, 0x5a, 0x99, 0x57, 0xd1, + 0xcc, 0xa2, 0x96, 0xed, 0x05, 0xc3, 0x61, 0x84, + 0x1e, 0x07, 0xfc, 0x3e, 0x55, 0x2d, 0x01, 0xe4, + 0x92, 0xc4, 0x56, 0xd6, 0xff, 0xc0, 0xa0, 0x6a, + 0x23, 0x89, 0x29, 0xc4, 0x76, 0x43, 0xf6, 0x7c, + 0xd6, 0x55, 0x0a, 0x0a, 0xb1, 0x00, 0x13, 0xaf, + 0xa2, 0xa0, 0xe4, 0x5c, 0x11, 0xb2, 0xa2, 0x51, + 0x80, 0x46, 0x98, 0xc3, 0x1e, 0x1b, 0x35, 0xc2, + 0x5c, 0xb5, 0xf4, 0xfb, 0xf2, 0x1c, 0x83, 0x83, + 0x80, 0x7c, 0xf8, 0x01, 0xfd, 0x9a, 0x85, 0x49, + 0x69, 0xc7, 0xd8, 0x1a, 0xc3, 0x0f, 0xa3, 0x27, + 0xb5, 0xa6, 0xc5, 0xdb, 0x3a, 0x15, 0x6e, 0x5e, + 0xdb, 0x93, 0x60, 0x8b, 0x28, 0x31, 0x48, 0xc0, + 0x35, 0x09, 0x3b, 0x5f, 0x28, 0x18, 0x54, 0x01, + 0x80, 0x66, 0x8c, 0x8e, 0x7e, 0xd6, 0xaa, 0x8d, + 0xa9, 0x9c, 0xa6, 0xe3, 0x10, 0xb6, 0x8c, 0x16, + 0xd0, 0x97, 0x4f, 0x78, 0x15, 0x21, 0x88, 0xb8, + 0x85, 0xb9, 0x01, 0xd1, 0x67, 0x69, 0xfd, 0xbe, + 0xe4, 0x52, 0xd6, 0xc4, 0x6a, 0x24, 0x07, 0x54, + 0x28, 0x08, 0xa6, 0x6f, 0x94, 0x03, 0x22, 0xf8, + 0x67, 0x46, 0x20, 0x9a, 0x4c, 0x93, 0x90, 0x1c, + 0x09, 0x90, 0x32, 0x46, 0x32, 0x0a, 0x2d, 0xe8, + 0x27, 0xc5, 0xdc, 0xf6, 0xc9, 0xde, 0x4e, 0x1a, + 0x45, 0x02, 0x5b, 0xab, 0xeb, 0x4a, 0x2f, 0x4d, + 0x95, 0x29, 0xe8, 0x0f, 0x04, 0xcc, 0xb8, 0xbc, + 0x6b, 0x32, 0x06, 0x08, 0x0d, 0xc0, 0x5f, 0xdb, + 0x24, 0x46, 0xb1, 0xbe, 0x85, 0x5a, 0xeb, 0x4a, + 0xa0, 0x40, 0x42, 0x48, 0x59, 0x37, 0xbd, 0x18, + 0x82, 0x72, 0x63, 0xfd, 0xa5, 0x12, 0x83, 0x90, + 0x85, 0x1e, 0xd5, 0x83, 0x35, 0xe0, 0xb9, 0x02, + 0xc7, 0xcd, 0x88, 0x23, 0x86, 0xe7, 0xc7, 0x12, + 0x4b, 0xcd, 0x1c, 0x59, 0x51, 0x29, 0x0c, 0x3b, + 0xc9, 0xd0, 0x4d, 0xf9, 0x6a, 0x33, 0xba, 0xef, + 0x2e, 0xe5, 0xd8, 0x69, 0x1a, 0x14, 0x44, 0x29, + 0xe6, 0xcb, 0xee, 0x7f, 0xd6, 0x9b, 0x25, 0x0c, + 0x51, 0x05, 0x48, 0xe4, 0xf9, 0x6a, 0xfd, 0xc9, + 0x9d, 0x8b, 0xd9, 0xd1, 0x3a, 0x14, 0x7d, 0xa9, + 0x38, 0x5a, 0x55, 0xd4, 0x57, 0x7f, 0xfb, 0x62, + 0x11, 0x80, 0x30, 0x61, 0x1d, 0x6a, 0x00, 0x92, + 0x2e, 0x9a, 0x7b, 0x82, 0x4a, 0x75, 0x77, 0x3b, + 0x61, 0xb6, 0xbe, 0x36, 0xa1, 0x87, 0x67, 0x46, + 0x0f, 0x30, 0xaf, 0x70, 0xbd, 0x8d, 0xc8, 0x31, + 0x53, 0x37, 0xc0, 0xc1, 0x8c, 0x15, 0x1d, 0x4d, + 0x38, 0xb5, 0x5c, 0x1c, 0x0b, 0xc1, 0x53, 0x17, + 0xe0, 0x75, 0xb6, 0x68, 0x19, 0x9d, 0x2b, 0xf4, + 0xe2, 0x09, 0x41, 0x30, 0xbe, 0xd0, 0xf7, 0xb2, + 0x2c, 0x69, 0xd1, 0x33, 0x83, 0xa6, 0x59, 0x66, + 0x17, 0xcb, 0x59, 0x6c, 0x18, 0x0c, 0x27, 0x1b, + 0xfe, 0xd4, 0x72, 0xac, 0x75, 0x25, 0x65, 0xca, + 0xfa, 0x0c, 0x05, 0xac, 0x29, 0x06, 0x04, 0xe1, + 0x78, 0xe8, 0x79, 0x4a, 0xf2, 0xa9, 0xe6, 0xfb, + 0xf1, 0x0e, 0x7e, 0xcd, 0x95, 0x6c, 0xed, 0x5a, + 0x9a, 0xa6, 0xc5, 0x01, 0x4d, 0x38, 0x36, 0x24, + 0x6b, 0xac, 0xe8, 0xf0, 0x77, 0xb9, 0xe9, 0x6f, + 0x55, 0x8f, 0x52, 0x48, 0xb2, 0xeb, 0xe6, 0x29, + 0xb7, 0xa6, 0xa5, 0x71, 0xbe, 0x57, 0x9e, 0xd0, + 0xda, 0xa1, 0xe5, 0x08, 0xaa, 0x65, 0xc1, 0x13, + 0xe8, 0x43, 0xef, 0x06, 0xac, 0xf8, 0x1f, 0x37, + 0xff, 0xb7, 0x53, 0x7e, 0x65, 0xd9, 0xf4, 0xdf, + 0x99, 0xc5, 0x25, 0x9b, 0x9b, 0x5c, 0x71, 0x90, + 0x6c, 0x49, 0xbe, 0x55, 0xff, 0x69, 0x70, 0xfa, + 0xff, 0xca, 0x7f, 0xe4, 0xe2, 0x4c, 0x42, 0x84, + 0x3a, 0x7d, 0xb0, 0x07, 0x07, 0x8c, 0x29, 0x80, + 0xc5, 0xa3, 0xc6, 0xee, 0xe1, 0x66, 0xe3, 0x1f, + 0xdf, 0xd5, 0x15, 0x08, 0x89, 0x16, 0x3c, 0x30, + 0x39, 0xcf, 0xaf, 0x35, 0x10, 0x2a, 0x38, 0x19, + 0xbe, 0x26, 0xb8, 0x13, 0x83, 0x00, 0x1c, 0xe4, + 0xda, 0xc5, 0x2b, 0xcf, 0xd2, 0xad, 0xc2, 0xa9, + 0x37, 0xb7, 0xb5, 0x01, 0x41, 0x0d, 0x40, 0x38, + 0x01, 0x9d, 0xe5, 0x12, 0x7f, 0xb4, 0x38, 0x54, + 0x5c, 0xdb, 0x7c, 0x02, 0x73, 0x7e, 0x2c, 0x17, + 0x2a, 0x1e, 0x09, 0x0a, 0xb3, 0x7c, 0x5d, 0x07, + 0xbb, 0xf5, 0xfb, 0xff, 0xa6, 0x9e, 0xef, 0x29, + 0xb5, 0x0b, 0x70, 0x6a, 0xa0, 0x6d, 0x01, 0x67, + 0xe9, 0x2d, 0x98, 0x72, 0xa6, 0x44, 0x47, 0x12, + 0xa2, 0x58, 0x25, 0x2b, 0xdc, 0x67, 0x71, 0xa5, + 0x57, 0x0b, 0x15, 0x65, 0xba, 0xa6, 0x07, 0xb3, + 0xb6, 0x22, 0x35, 0xde, 0x13, 0x09, 0xda, 0x08, + 0x0d, 0xb3, 0xad, 0x83, 0xc1, 0x40, 0x42, 0x3b, + 0xb7, 0x22, 0x90, 0xf5, 0xbe, 0x5d, 0xea, 0xcb, + 0x01, 0x88, 0xa5, 0x72, 0x60, 0xbe, 0x23, 0x64, + 0x6d, 0x57, 0xbb, 0x10, 0x7f, 0x94, 0x41, 0xac, + 0x73, 0x84, 0xb1, 0x75, 0xc1, 0x38, 0xeb, 0x25, + 0xbe, 0x6e, 0xf4, 0xb9, 0x8f, 0xa9, 0xd5, 0x84, + 0x14, 0xad, 0xfe, 0xc3, 0x48, 0x11, 0x52, 0x99, + 0x3a, 0x4e, 0x70, 0xe7, 0x65, 0x5a, 0x29, 0x85, + 0x2a, 0x02, 0x68, 0x99, 0xaf, 0xaa, 0xfa, 0xad, + 0x2c, 0xd1, 0x09, 0x46, 0xc4, 0x0d, 0xfd, 0xba, + 0x0c, 0x18, 0x98, 0x6d, 0x97, 0x5a, 0xd3, 0x0d, + 0xf9, 0x57, 0xbd, 0x75, 0x4e, 0x7f, 0x3b, 0xd5, + 0xf2, 0xa3, 0x9d, 0xde, 0xaf, 0x10, 0x13, 0x97, + 0xd5, 0x1c, 0xdb, 0xa3, 0xa2, 0xe9, 0x50, 0x7d, + 0x44, 0xdd, 0xe4, 0x0d, 0xea, 0x08, 0x27, 0x33, + 0x41, 0xba, 0xd5, 0xda, 0xc4, 0x2c, 0xec, 0xe7, + 0x66, 0x35, 0xc9, 0x3b, 0xd9, 0x27, 0x73, 0x83, + 0x17, 0x0d, 0x08, 0x3d, 0x35, 0x34, 0xa6, 0x9e, + 0xd7, 0xea, 0x84, 0xb2, 0xcf, 0x87, 0x95, 0x94, + 0xd5, 0x8b, 0x2e, 0x11, 0x89, 0x02, 0x06, 0x25, + 0x6a, 0x46, 0xd5, 0xe5, 0xa5, 0xb9, 0x54, 0x67, + 0x22, 0x9d, 0x2b, 0x92, 0xa0, 0x3c, 0x5e, 0xc5, + 0x78, 0x38, 0xac, 0xc2, 0xff, 0xe1, 0x57, 0xbc, + 0xb2, 0xd5, 0x48, 0xc7, 0x85, 0x10, 0x81, 0x54, + 0x89, 0x3d, 0xbb, 0xdc, 0xb8, 0xd8, 0xf5, 0x9c, + 0x8c, 0xa7, 0xe9, 0x46, 0x45, 0xd7, 0x40, 0x88, + 0x8c, 0xdc, 0x56, 0xdc, 0x46, 0xa3, 0x06, 0xfc, + 0xce, 0x91, 0x69, 0x8a, 0x55, 0x02, 0x8b, 0x72, + 0xe7, 0xdb, 0x1f, 0xa5, 0x2b, 0x06, 0x40, 0x55, + 0x31, 0x45, 0x9d, 0x40, 0xdd, 0x90, 0x54, 0x9a, + 0x70, 0x64, 0x89, 0x15, 0xc9, 0xbe, 0x4f, 0xb3, + 0x6d, 0xe5, 0x1c, 0xab, 0xc2, 0xc8, 0x30, 0x94, + 0xea, 0x5e, 0x54, 0xab, 0x14, 0x7b, 0xfe, 0xce, + 0x9b, 0xe6, 0xae, 0x50, 0xa6, 0xe9, 0x18, 0xb6, + 0xb1, 0x95, 0x44, 0x53, 0xcf, 0x7b, 0x96, 0x7b, + 0x98, 0x59, 0x43, 0x8e, 0x95, 0x0c, 0x21, 0x3b, + 0x95, 0xc2, 0xb5, 0xe1, 0x42, 0x80, 0xc0, 0xf6, + 0x99, 0xa4, 0xe0, 0x19, 0x83, 0xe1, 0x29, 0x28, + 0xf3, 0xd4, 0x72, 0xdb, 0x77, 0xd4, 0x3c, 0xaa, + 0x70, 0x3c, 0x45, 0xbd, 0x1b, 0x76, 0xf4, 0x80, + 0x30, 0x60, 0x34, 0x12, 0x6f, 0xe2, 0x84, 0x96, + 0xaf, 0x36, 0x29, 0xfb, 0x52, 0x73, 0xa8, 0xff, + 0x2d, 0xe9, 0xe3, 0x3f, 0xf4, 0xa8, 0xb2, 0xf7, + 0x4d, 0x15, 0x45, 0x83, 0x9b, 0x38, 0x33, 0x8b, + 0x8a, 0xf0, 0x80, 0xd4, 0x5e, 0x79, 0x7e, 0xf2, + 0xd1, 0xb8, 0xbe, 0x2f, 0xb2, 0x94, 0x9e, 0x24, + 0x73, 0xfe, 0x02, 0x63, 0x26, 0x79, 0xa4, 0xdd, + 0x4a, 0xda, 0x4a, 0xb5, 0xbb, 0x7c, 0x55, 0xdb, + 0xee, 0xca, 0x1b, 0x4b, 0xd9, 0xd8, 0x02, 0x0e, + 0xfd, 0xaa, 0xd7, 0xee, 0x6c, 0xb3, 0x86, 0xfb, + 0x28, 0x56, 0x0c, 0x1a, 0xab, 0xf8, 0x24, 0xb3, + 0xf5, 0x51, 0x46, 0xc6, 0x5b, 0xbd, 0x5a, 0xc9, + 0x26, 0xd9, 0xb5, 0x75, 0xb9, 0xc3, 0x7c, 0x3c, + 0x48, 0x43, 0x08, 0x5a, 0x3f, 0x6f, 0x4b, 0xfb, + 0x41, 0x86, 0xc5, 0xad, 0xf1, 0x78, 0xa7, 0x24, + 0xce, 0x45, 0xe8, 0xa4, 0x5e, 0x33, 0xcb, 0x3b, + 0x39, 0xd4, 0x67, 0x55, 0x72, 0x63, 0xc2, 0xd6, + 0x1b, 0x45, 0x29, 0xbb, 0xd8, 0x81, 0x00, 0xcc, + 0x63, 0xd3, 0xc5, 0x12, 0x73, 0xfe, 0xf6, 0xde, + 0x6e, 0x41, 0x89, 0x5f, 0xaf, 0x65, 0x5a, 0x9b, + 0x21, 0x59, 0x5c, 0xc1, 0x0b, 0xc5, 0x7a, 0xbe, + 0x28, 0xdf, 0x40, 0xf6, 0x2c, 0x8a, 0xc2, 0xa5, + 0x2b, 0x74, 0xf9, 0x3d, 0x63, 0x13, 0xd8, 0x98, + 0x71, 0x6f, 0x73, 0xb6, 0x88, 0x0d, 0xb3, 0x66, + 0x5a, 0x56, 0x22, 0x77, 0x9b, 0x88, 0x08, 0x64, + 0x2d, 0xff, 0x50, 0x42, 0x0d, 0x35, 0x47, 0x1b, + 0x93, 0x2d, 0x42, 0x88, 0x50, 0x2f, 0x06, 0xcf, + 0x29, 0x4a, 0x3e, 0xa5, 0x5d, 0xc4, 0xea, 0xbb, + 0x03, 0xde, 0xf0, 0x73, 0x2f, 0x51, 0xa8, 0x13, + 0x11, 0x64, 0x03, 0x14, 0xfb, 0xb3, 0xe1, 0xe2, + 0x65, 0x18, 0xcd, 0xd9, 0x51, 0x72, 0xf3, 0x72, + 0xd1, 0x12, 0xa3, 0x42, 0x8c, 0x4d, 0x00, 0x79, + 0x9f, 0x36, 0x24, 0x8e, 0x95, 0x2a, 0xcc, 0x06, + 0x02, 0xea, 0xad, 0x2b, 0xaa, 0x43, 0xcf, 0xe5, + 0xd3, 0x4b, 0x2c, 0x4a, 0x34, 0x76, 0xdb, 0x9b, + 0x97, 0x80, 0xe1, 0x56, 0xba, 0x6d, 0xe5, 0xf7, + 0x40, 0x70, 0x3a, 0x05, 0x91, 0xca, 0x8f, 0x9b, + 0xc1, 0x88, 0x2c, 0x0f, 0x0b, 0xb2, 0x50, 0x42, + 0x06, 0x2d, 0xbb, 0x98, 0x4b, 0xc6, 0x22, 0x90, + 0x78, 0xcf, 0xfd, 0xe6, 0x50, 0x60, 0x9d, 0x16, + 0xda, 0xd1, 0xd2, 0x6f, 0xb3, 0xf9, 0x21, 0xab, + 0x38, 0xc2, 0x30, 0xd4, 0xb7, 0xea, 0x1d, 0xfa, + 0xf6, 0xe7, 0x01, 0xc1, 0xde, 0xc0, 0xb3, 0x4f, + 0x03, 0x0f, 0xe7, 0x40, 0x39, 0x3a, 0x3a, 0xbb, + 0x08, 0x81, 0x5f, 0x10, 0x10, 0x94, 0x4c, 0x5d, + 0x3f, 0x9f, 0xd0, 0x34, 0x9d, 0x3e, 0xad, 0x31, + 0x8f, 0x66, 0xf6, 0xf4, 0x45, 0x2a, 0x9b, 0x78, + 0xe2, 0x02, 0x3f, 0xbc, 0x3f, 0x2e, 0xfb, 0x01, + 0xf8, 0x1a, 0x9b, 0xc0, 0xf6, 0xe5, 0xb5, 0x65, + 0xf8, 0xa2, 0xce, 0x3c, 0x23, 0xb4, 0x25, 0x17, + 0x2a, 0xb5, 0xa0, 0x60, 0xfd, 0x5f, 0x2f, 0xa5, + 0x0f, 0xd5, 0x28, 0x6b, 0xf6, 0xf4, 0x3a, 0xe4, + 0xf2, 0x28, 0x8c, 0xd8, 0xac, 0xe4, 0xdf, 0x51, + 0x0b, 0x14, 0x6a, 0x32, 0x5e, 0x0b, 0x9d, 0x5f, + 0xf8, 0x9d, 0x27, 0xfd, 0x36, 0xfb, 0xfa, 0x59, + 0xe0, 0x33, 0xce, 0xf1, 0x63, 0xb6, 0xd9, 0x6f, + 0x41, 0xe1, 0x20, 0x15, 0xba, 0x5e, 0x42, 0x57, + 0xed, 0x09, 0x1a, 0x59, 0xed, 0x1e, 0x8f, 0x4b, + 0xea, 0x56, 0x94, 0x6f, 0x33, 0xba, 0x2f, 0x14, + 0x74, 0x9e, 0x08, 0x51, 0x08, 0x8d, 0xbf, 0xf3, + 0x7d, 0x57, 0x2a, 0xf1, 0x01, 0xf2, 0x59, 0xd2, + 0xd9, 0xce, 0xe4, 0x97, 0xa4, 0xf8, 0x3f, 0x9c, + 0x00, 0x6b, 0xa3, 0x1a, 0xfe, 0x82, 0x26, 0xd6, + 0x26, 0x67, 0xb6, 0xf2, 0xab, 0xad, 0x7c, 0x3d, + 0x9c, 0x06, 0x34, 0xa3, 0x61, 0x55, 0x29, 0x42, + 0xe3, 0xac, 0xea, 0x52, 0x4a, 0xc6, 0x1c, 0x32, + 0x21, 0xa5, 0x69, 0xbf, 0x7f, 0x1a, 0xc6, 0x04, + 0xaa, 0x92, 0x0e, 0x54, 0x79, 0xac, 0xa5, 0xbb, + 0xe4, 0x32, 0xc5, 0x2a, 0x38, 0x69, 0x67, 0x91, + 0x57, 0xf1, 0xfa, 0xa0, 0xe9, 0xa5, 0x43, 0xea, + 0x9e, 0x6c, 0xe4, 0x1b, 0x72, 0xef, 0x1c, 0x5a, + 0xac, 0xcc, 0xf7, 0xae, 0x41, 0xcc, 0xa6, 0xcf, + 0xaa, 0xe5, 0xd5, 0x77, 0xc1, 0xdc, 0x6e, 0x7f, + 0xb9, 0xad, 0x62, 0xe5, 0x56, 0xf0, 0xd3, 0xca, + 0x35, 0x1a, 0x55, 0x3f, 0xa0, 0xc1, 0xef, 0x9b, + 0x6a, 0x59, 0xba, 0x59, 0x35, 0x6f, 0x72, 0xd3, + 0x48, 0x86, 0xa5, 0x41, 0x4e, 0x25, 0xa3, 0x06, + 0x0f, 0x55, 0xa6, 0x9b, 0xb3, 0x26, 0x03, 0x8e, + 0x2d, 0xe6, 0x75, 0x3b, 0x38, 0xd4, 0xe7, 0xfe, + 0xa3, 0xdd, 0xe5, 0xd9, 0x2a, 0x20, 0x71, 0x29, + 0x39, 0xec, 0xab, 0xdc, 0xda, 0xa5, 0x47, 0xae, + 0x59, 0x05, 0xb5, 0x71, 0x2b, 0x0a, 0x84, 0x25, + 0x51, 0x9f, 0xa9, 0x6d, 0x2f, 0x9b, 0x8a, 0x1b, + 0x4f, 0xc9, 0xfd, 0xe6, 0x4e, 0x74, 0x3b, 0x5c, + 0x8b, 0xf3, 0x6e, 0x4a, 0x18, 0xc0, 0x74, 0x3f, + 0x72, 0xee, 0x48, 0xa7, 0x75, 0xb6, 0x7f, 0x6a, + 0x2e, 0x49, 0x6a, 0xd3, 0xa1, 0x40, 0xd4, 0x47, + 0xd8, 0xce, 0x59, 0x2c, 0x43, 0xc5, 0xe5, 0x5d, + 0xfa, 0x66, 0x3f, 0xfa, 0x86, 0xf5, 0x7c, 0x3d, + 0x17, 0x32, 0xa2, 0x0f, 0xf1, 0xa5, 0x3d, 0xb4, + 0x11, 0xf8, 0x6c, 0x96, 0x22, 0x18, 0xb9, 0xe9, + 0x56, 0xee, 0x15, 0x28, 0x44, 0x84, 0x91, 0x11, + 0x09, 0xab, 0x75, 0xb6, 0x3d, 0xd9, 0x38, 0xb9, + 0x6a, 0x10, 0x1c, 0x35, 0x19, 0xb3, 0x89, 0xd9, + 0x95, 0x16, 0xfa, 0x92, 0x2f, 0x45, 0xdc, 0x3f, + 0x25, 0x2c, 0xd0, 0x74, 0xd0, 0xc8, 0xf6, 0x9a, + 0x31, 0x3f, 0xb8, 0x5a, 0x80, 0xd2, 0xc8, 0x39, + 0x10, 0x04, 0xb1, 0x12, 0xf9, 0x19, 0x5a, 0xe6, + 0xa0, 0xd1, 0x7d, 0x00, 0xdd, 0xed, 0x2b, 0x49, + 0xa0, 0x48, 0x07, 0x3c, 0x69, 0x00, 0x34, 0x43, + 0x5e, 0xc6, 0xf1, 0xa4, 0x12, 0x73, 0x06, 0xc8, + 0x0e, 0x97, 0x18, 0xdb, 0xd5, 0x82, 0xbd, 0x78, + 0xf2, 0x3f, 0x5e, 0xa1, 0x5f, 0x88, 0x88, 0x92, + 0xfe, 0x5f, 0x5b, 0xe9, 0xda, 0x04, 0xe5, 0x04, + 0xc2, 0x23, 0xf6, 0x95, 0x49, 0x92, 0x40, 0xfd, + 0x58, 0x31, 0xbd, 0xc8, 0x83, 0xd2, 0xd4, 0x76, + 0x21, 0x0a, 0x82, 0x40, 0xf0, 0x21, 0x26, 0x69, + 0x40, 0x19, 0x12, 0xcb, 0x95, 0x37, 0xd1, 0xc6, + 0x82, 0xbb, 0x56, 0xab, 0x8d, 0x86, 0xcf, 0xb2, + 0x83, 0xba, 0x43, 0x53, 0xa6, 0x95, 0x7e, 0x52, + 0xb6, 0x6e, 0xac, 0x8a, 0xa1, 0x29, 0x38, 0x58, + 0x77, 0xbe, 0xf2, 0x46, 0x77, 0x65, 0x2c, 0xc8, + 0xa6, 0xac, 0xba, 0x88, 0x8e, 0xc3, 0x74, 0x5c, + 0x41, 0x70, 0x20, 0x8f, 0xf6, 0x16, 0x87, 0xc3, + 0xa4, 0xc6, 0xe1, 0x78, 0x97, 0xef, 0x51, 0x87, + 0x17, 0xea, 0xc8, 0xe9, 0xc5, 0x04, 0x31, 0xe9, + 0x68, 0x84, 0xde, 0x26, 0x56, 0x3a, 0xf8, 0xfc, + 0xb3, 0x8a, 0x12, 0x33, 0xe6, 0x57, 0x43, 0x32, + 0x6f, 0xd1, 0x0d, 0x6a, 0x8d, 0x83, 0x7e, 0x70, + 0x1c, 0x7a, 0x26, 0xbe, 0x02, 0x94, 0x03, 0x98, + 0x6e, 0x6b, 0x0c, 0x0e, 0xdb, 0xdc, 0x44, 0x55, + 0x80, 0xc0, 0x3c, 0x26, 0x33, 0xf0, 0x41, 0xd6, + 0xdb, 0x97, 0xc3, 0xa5, 0x77, 0xd7, 0x26, 0xf7, + 0x6e, 0x79, 0x47, 0x67, 0x78, 0xbe, 0x55, 0xc5, + 0x41, 0x9d, 0x5a, 0xb0, 0x65, 0x6a, 0x0a, 0xd2, + 0x0f, 0xfd, 0xe0, 0xe7, 0xc3, 0xa5, 0x00, 0xf1, + 0x5f, 0xfb, 0xb4, 0xc0, 0x30, 0x4e, 0x3d, 0x6d, + 0x94, 0xb6, 0x83, 0x2f, 0xf6, 0xed, 0x06, 0x25, + 0xbb, 0xd0, 0x60, 0xaf, 0xea, 0x64, 0x2b, 0x86, + 0x9b, 0x68, 0x66, 0x79, 0x91, 0x8f, 0x7c, 0x10, + 0xd5, 0x8e, 0x73, 0xaa, 0x8b, 0x95, 0x67, 0x54, + 0x52, 0xd1, 0xeb, 0x5d, 0x9e, 0x42, 0x22, 0xf9, + 0x73, 0xd0, 0x3d, 0x11, 0xc1, 0x09, 0xa1, 0x15, + 0x33, 0x7f, 0x99, 0x54, 0x28, 0xdf, 0xb7, 0xcb, + 0x50, 0x8d, 0xff, 0x0f, 0xad, 0xd7, 0xf3, 0x37, + 0xed, 0x20, 0xf6, 0x82, 0x3a, 0x80, 0xc8, 0xfe, + 0x91, 0x1a, 0x0d, 0xa0, 0xa0, 0xc9, 0x20, 0x2a, + 0xa3, 0x76, 0x64, 0x9d, 0x04, 0x4f, 0x5e, 0x83, + 0x0c, 0x78, 0xf1, 0x82, 0x70, 0x66, 0x47, 0xd6, + 0x71, 0x50, 0x8d, 0x06, 0x31, 0x89, 0xd4, 0x05, + 0x4d, 0x4b, 0xde, 0x03, 0x0a, 0x59, 0x46, 0x04, + 0x81, 0x2d, 0x38, 0x30, 0xd8, 0x74, 0x3f, 0x64, + 0x18, 0xa1, 0x33, 0x3f, 0x83, 0x1c, 0xc7, 0x8f, + 0xd6, 0xf8, 0x49, 0x09, 0x7f, 0xfa, 0x19, 0x99, + 0xd7, 0x30, 0xd8, 0x41, 0x4a, 0xc2, 0x6e, 0x35, + 0x3d, 0xac, 0xfe, 0xd2, 0xa6, 0xa1, 0xbb, 0x33, + 0x3c, 0xe3, 0x7c, 0xc0, 0x60, 0x3f, 0x3c, 0xdc, + 0x5a, 0x02, 0xa5, 0x26, 0x37, 0x94, 0x11, 0xbb, + 0xf6, 0xb4, 0x91, 0x1c, 0xc8, 0xe1, 0x60, 0x28, + 0x04, 0x36, 0x15, 0x2b, 0x0f, 0x23, 0x05, 0xe5, + 0xcc, 0xe3, 0x6c, 0x36, 0x15, 0x98, 0xbf, 0x07, + 0x81, 0x81, 0xcd, 0xb0, 0x51, 0xe8, 0x3c, 0x6c, + 0x01, 0x63, 0xcf, 0xc1, 0x88, 0x7f, 0x75, 0xa1, + 0x70, 0xe3, 0xe6, 0x4c, 0xb1, 0x4d, 0xaa, 0x4b, + 0x1a, 0x6b, 0x39, 0x02, 0x9d, 0x31, 0xe8, 0x8c, + 0x08, 0x21, 0x09, 0x9c, 0xf7, 0x9b, 0x1e, 0xb4, + 0xab, 0x85, 0xb7, 0xf1, 0x9c, 0xe7, 0x50, 0xe4, + 0xee, 0xf2, 0x0c, 0x00, 0x58, 0xb9, 0xa4, 0xf1, + 0xbf, 0xcd, 0x62, 0x2a, 0xf8, 0xe6, 0x8e, 0x65, + 0x94, 0xb5, 0x4e, 0xcb, 0xcc, 0x2c, 0x34, 0x6c, + 0x44, 0x88, 0x09, 0xd4, 0x68, 0x1e, 0x02, 0x08, + 0x32, 0xfe, 0x75, 0x58, 0x43, 0x63, 0xc4, 0x9e, + 0x4d, 0xbf, 0x17, 0xeb, 0x6c, 0x0c, 0x78, 0x78, + 0xd2, 0x40, 0x60, 0x0e, 0x2e, 0x4d, 0xfb, 0xa0, + 0xc1, 0xf8, 0xee, 0x56, 0x8a, 0xee, 0xaa, 0x6f, + 0xc9, 0x29, 0x4e, 0x07, 0x8d, 0xac, 0x1b, 0x96, + 0x9c, 0x2b, 0x13, 0xe7, 0x78, 0xba, 0xe8, 0x79, + 0xb6, 0x40, 0x71, 0xdd, 0x34, 0x1b, 0x4c, 0x9e, + 0x5e, 0xa9, 0x53, 0xba, 0xba, 0xc1, 0xd4, 0x81, + 0xc0, 0x15, 0x51, 0x50, 0xed, 0xbc, 0xef, 0x24, + 0x3c, 0x2b, 0xba, 0x39, 0x2a, 0xef, 0x27, 0xa7, + 0x2f, 0x27, 0x7b, 0x62, 0x3a, 0x6d, 0x70, 0xdf, + 0x86, 0xcf, 0x16, 0xf0, 0x18, 0x63, 0xf8, 0xd6, + 0x37, 0xb6, 0x4b, 0x23, 0x6a, 0xdb, 0x6d, 0xbb, + 0x7f, 0x9c, 0x5b, 0x79, 0x24, 0xe5, 0xe9, 0xae, + 0x22, 0xa7, 0x6c, 0x3e, 0x4b, 0x36, 0x58, 0xa3, + 0xd8, 0xcb, 0x15, 0x49, 0x6e, 0xef, 0x3b, 0x11, + 0xac, 0xb4, 0xd5, 0x8d, 0xd0, 0xa5, 0x56, 0x0e, + 0x65, 0x07, 0x13, 0x54, 0xff, 0xb3, 0x7f, 0x3e, + 0xa2, 0xee, 0xf0, 0xac, 0xd0, 0xc9, 0x79, 0x87, + 0xd5, 0x52, 0xa5, 0x49, 0x65, 0x44, 0x55, 0xaa, + 0x2c, 0x96, 0x1b, 0xe9, 0x36, 0x1f, 0x5c, 0x54, + 0xdb, 0x7e, 0x6e, 0x8e, 0x7f, 0x99, 0xd9, 0x24, + 0x51, 0x67, 0xaf, 0x64, 0x2a, 0xbc, 0xbc, 0xff, + 0x16, 0xe4, 0x40, 0x42, 0x4f, 0x5a, 0x92, 0x29, + 0x69, 0x15, 0x6f, 0xbb, 0x16, 0xe1, 0xbb, 0xd5, + 0x39, 0x38, 0xa0, 0x97, 0xa2, 0x65, 0x15, 0xe9, + 0xa6, 0x59, 0xec, 0x92, 0xed, 0xd5, 0x1b, 0x79, + 0x2d, 0x51, 0x2f, 0x56, 0x37, 0xbd, 0x24, 0x36, + 0x52, 0x43, 0x76, 0x28, 0xeb, 0x6a, 0x24, 0x6f, + 0x79, 0xd0, 0xe4, 0xaa, 0xf3, 0x27, 0x6a, 0xc8, + 0x91, 0xa2, 0xa6, 0x8e, 0xab, 0x92, 0xb3, 0xed, + 0xd0, 0xef, 0x11, 0xb4, 0xa0, 0xab, 0x60, 0xcb, + 0x3a, 0x52, 0xbd, 0x1a, 0xae, 0xc8, 0xe7, 0x56, + 0x9c, 0x53, 0x85, 0x8a, 0x77, 0x57, 0xcd, 0xa2, + 0xe5, 0xe1, 0xb3, 0x67, 0xa0, 0x9f, 0x4c, 0xbc, + 0xda, 0x39, 0xc2, 0xb9, 0x27, 0x11, 0xc3, 0x7a, + 0xb7, 0x17, 0xec, 0x1a, 0xc7, 0xf7, 0x3c, 0xd4, + 0xdf, 0xe6, 0x95, 0xf3, 0x25, 0x37, 0xb5, 0x04, + 0x50, 0xb7, 0x45, 0xc2, 0x72, 0x49, 0xb9, 0xbe, + 0xb3, 0xeb, 0x6e, 0x64, 0x8a, 0x6d, 0x80, 0xc1, + 0x9d, 0xe0, 0xc5, 0xf4, 0xad, 0x86, 0xdb, 0x51, + 0x2d, 0xbf, 0x68, 0xa9, 0x78, 0x83, 0x22, 0x1b, + 0xab, 0x9b, 0x28, 0x26, 0x36, 0xac, 0x84, 0xe6, + 0x98, 0x56, 0xf8, 0x84, 0x05, 0xdb, 0x94, 0x71, + 0x9d, 0xba, 0xdc, 0x5f, 0xcb, 0x2f, 0xbc, 0xd8, + 0x8e, 0xed, 0x24, 0x51, 0xd5, 0xfa, 0x4e, 0x2f, + 0x08, 0x5a, 0xc8, 0x96, 0x5c, 0xad, 0x86, 0x36, + 0xcd, 0x80, 0x60, 0xb7, 0x67, 0x3f, 0xc5, 0x25, + 0x45, 0x9d, 0x11, 0x26, 0x20, 0xed, 0xe7, 0x7a, + 0x7c, 0x4e, 0x3d, 0x51, 0x07, 0x29, 0x33, 0xfd, + 0xad, 0xa3, 0xc5, 0x02, 0x09, 0x62, 0xd9, 0x3a, + 0x55, 0x66, 0xd9, 0x16, 0x5e, 0x45, 0xad, 0x5d, + 0xe6, 0xc7, 0x43, 0xcd, 0x1e, 0x36, 0xdf, 0xcb, + 0x51, 0x4c, 0xf6, 0x60, 0x7b, 0x3b, 0x14, 0xa3, + 0x8b, 0xf1, 0x4a, 0x0b, 0x3a, 0x54, 0x46, 0x38, + 0xa7, 0x14, 0x1a, 0xe1, 0x3a, 0xa6, 0xa4, 0x08, + 0x5f, 0xf3, 0x3d, 0x6b, 0xf6, 0x5c, 0xc2, 0xc5, + 0x16, 0xdb, 0x69, 0xb5, 0x30, 0xac, 0x0b, 0xaf, + 0x56, 0xe1, 0x24, 0x3c, 0x2f, 0x69, 0x33, 0x3b, + 0xbd, 0xd6, 0x14, 0x28, 0x5b, 0x24, 0x9d, 0x46, + 0xb5, 0x5e, 0xa0, 0xb2, 0x73, 0x51, 0x0d, 0x04, + 0x6c, 0x0f, 0x38, 0x97, 0xed, 0xcd, 0xaa, 0x55, + 0xa3, 0xb5, 0x7e, 0x96, 0x22, 0xc1, 0x16, 0x2d, + 0xd4, 0x7c, 0xe9, 0xd4, 0xd9, 0xf3, 0x63, 0x86, + 0xfc, 0xd2, 0x82, 0xdd, 0x44, 0x86, 0xf5, 0x05, + 0xe5, 0x5f, 0x82, 0xe2, 0x47, 0xb9, 0x69, 0xb5, + 0x03, 0x4d, 0x31, 0xc0, 0x43, 0xa3, 0xb0, 0xfa, + 0xcb, 0x6b, 0x09, 0x23, 0x3f, 0x6b, 0x72, 0x28, + 0x97, 0xf2, 0xaf, 0x9c, 0x9c, 0x1b, 0x48, 0xb4, + 0x8b, 0x1f, 0x3a, 0x0d, 0x15, 0x2b, 0x82, 0x18, + 0xf9, 0x96, 0x0a, 0xfc, 0x06, 0xf3, 0x3e, 0x89, + 0x4c, 0x8a, 0x64, 0xaa, 0x43, 0x84, 0x7d, 0x82, + 0xe3, 0xa2, 0xc5, 0x62, 0x32, 0x51, 0xda, 0xa1, + 0xc0, 0xe0, 0xac, 0x73, 0x91, 0x9b, 0xfe, 0x49, + 0x9a, 0xc7, 0x43, 0xd9, 0x32, 0xd0, 0x2f, 0x2a, + 0x25, 0xa8, 0x99, 0x22, 0xe5, 0x4d, 0x08, 0xcc, + 0xa4, 0xf4, 0x6a, 0x34, 0x1f, 0x8f, 0xd8, 0x5f, + 0x8a, 0x57, 0xad, 0xc8, 0x8d, 0x4f, 0x27, 0x50, + 0x05, 0x12, 0xb6, 0x83, 0x83, 0x35, 0x82, 0x2d, + 0x30, 0x89, 0x78, 0x68, 0x5c, 0x09, 0x95, 0xd1, + 0x90, 0x38, 0x17, 0xb6, 0x88, 0xa0, 0x1c, 0x30, + 0x0a, 0x6c, 0x94, 0x16, 0x20, 0xb0, 0x0a, 0x8f, + 0x0c, 0xc9, 0xaa, 0xe6, 0x84, 0x82, 0xff, 0x6a, + 0x25, 0xc1, 0x1c, 0x1c, 0xbc, 0x05, 0xc1, 0x61, + 0xeb, 0x63, 0xce, 0x2b, 0x1e, 0x2a, 0x4b, 0x04, + 0x7c, 0x61, 0x9f, 0x8e, 0x99, 0xfd, 0x49, 0xa0, + 0x78, 0x43, 0xff, 0xb2, 0xe1, 0x5f, 0x3d, 0xec, + 0x06, 0xe8, 0x94, 0xbf, 0x67, 0x43, 0xdb, 0xfc, + 0xf3, 0x7c, 0xed, 0xc3, 0xf8, 0xa5, 0x11, 0xa0, + 0x58, 0x04, 0x5e, 0xab, 0x54, 0x99, 0x29, 0x53, + 0x0a, 0x87, 0xf1, 0x20, 0x78, 0xac, 0x18, 0x3d, + 0x2e, 0x12, 0xc4, 0x86, 0xd1, 0x28, 0xfc, 0x03, + 0x71, 0x38, 0xf8, 0x15, 0xb1, 0xad, 0x47, 0x03, + 0xa6, 0xcc, 0x7d, 0x53, 0x16, 0x94, 0x1d, 0x17, + 0x22, 0xdf, 0xe3, 0xef, 0x89, 0x77, 0xa3, 0xd6, + 0x87, 0x98, 0x9b, 0xf7, 0x1a, 0x1f, 0xb3, 0xad, + 0xb0, 0x5c, 0x23, 0x24, 0x4e, 0xca, 0x46, 0x13, + 0xeb, 0x71, 0xaa, 0x23, 0x46, 0x5a, 0xf8, 0x93, + 0xf6, 0x37, 0xf7, 0x26, 0x82, 0xb5, 0x3b, 0x7d, + 0xf4, 0xf5, 0xc9, 0x98, 0x01, 0x65, 0xb5, 0x50, + 0xf5, 0x4d, 0xcf, 0x36, 0xad, 0xb1, 0xd4, 0xff, + 0x9b, 0x4c, 0xc7, 0xef, 0x80, 0xcb, 0x0a, 0xd3, + 0x2b, 0xf3, 0x6c, 0x7f, 0x22, 0xd7, 0x2e, 0x01, + 0x5f, 0x59, 0xb9, 0x2c, 0xbf, 0xf6, 0xc8, 0xf3, + 0xd1, 0x85, 0x40, 0x7d, 0x30, 0x06, 0x08, 0x0c, + 0xb5, 0x78, 0xc0, 0x2a, 0xc4, 0xb4, 0xad, 0x80, + 0x69, 0x7a, 0x95, 0x69, 0xc7, 0xa9, 0xd4, 0x33, + 0x57, 0xf1, 0x74, 0x12, 0xfc, 0xd3, 0x4d, 0x62, + 0x96, 0x94, 0xef, 0x44, 0x81, 0xbd, 0x1b, 0x78, + 0xc0, 0xb9, 0x20, 0xf8, 0x79, 0x07, 0x89, 0xc4, + 0x06, 0x87, 0xc9, 0x32, 0xf1, 0xa6, 0x1b, 0xd4, + 0x81, 0x01, 0x5c, 0x54, 0xad, 0x9f, 0xd0, 0x61, + 0x04, 0x77, 0xf9, 0x32, 0xcd, 0x69, 0xb4, 0xac, + 0x78, 0x72, 0x94, 0x40, 0x4d, 0xee, 0xa9, 0xb3, + 0xc9, 0x98, 0xda, 0xd9, 0x91, 0x8f, 0x2e, 0xa4, + 0x18, 0x07, 0xd9, 0xc8, 0x03, 0xc9, 0x45, 0x38, + 0x38, 0x89, 0xff, 0xb3, 0x57, 0x69, 0x46, 0x37, + 0x37, 0xcd, 0xb5, 0xf5, 0x4c, 0xf7, 0x92, 0xa7, + 0x48, 0xad, 0xa9, 0x57, 0x93, 0x7b, 0xef, 0xae, + 0x59, 0xf6, 0xb6, 0x15, 0xca, 0x22, 0x3e, 0x58, + 0x65, 0x26, 0x4a, 0x39, 0xf0, 0xf4, 0x4a, 0x4a, + 0xd4, 0xff, 0x8a, 0x94, 0x75, 0x9f, 0x29, 0xf5, + 0xdf, 0x36, 0xa3, 0x6e, 0x07, 0xbe, 0xec, 0x2d, + 0xcf, 0xc9, 0xb7, 0xb1, 0x6e, 0xf5, 0xc1, 0x88, + 0x43, 0xf1, 0x7f, 0x81, 0xc0, 0xa4, 0x04, 0x50, + 0x6e, 0x16, 0x7c, 0x3f, 0x05, 0x58, 0x30, 0xe4, + 0x7a, 0x0e, 0x05, 0x58, 0x30, 0x29, 0xc1, 0x8b, + 0x4b, 0x01, 0x4c, 0x0c, 0xa4, 0x18, 0x41, 0x10, + 0x41, 0x10, 0x18, 0x6c, 0xa4, 0x3f, 0x02, 0xe0, + 0xaa, 0x06, 0x0e, 0x41, 0xf0, 0x7f, 0xed, 0x0b, + 0x69, 0x44, 0xb4, 0xe5, 0xcd, 0x5c, 0x1f, 0xb4, + 0x3f, 0xd5, 0x7c, 0x6d, 0xa2, 0xf6, 0x8b, 0xc4, + 0x88, 0x24, 0x2b, 0x4f, 0xac, 0xec, 0xff, 0xc7, + 0x20, 0x64, 0x78, 0xa9, 0x20, 0x32, 0x96, 0x1b, + 0x8a, 0xfc, 0xac, 0xaf, 0xf5, 0xac, 0x6f, 0x14, + 0xe5, 0x6d, 0xa6, 0xcc, 0x45, 0x19, 0x2a, 0xe8, + 0xd0, 0x12, 0x9f, 0xc1, 0xe9, 0xa0, 0x03, 0xe0, + 0x52, 0x9a, 0x82, 0x27, 0xb7, 0x7e, 0x3e, 0xbd, + 0x60, 0xb5, 0xb5, 0x65, 0xcc, 0xf4, 0x42, 0xec, + 0xbb, 0x3f, 0xf4, 0x89, 0x55, 0xef, 0x41, 0x55, + 0x14, 0x03, 0x23, 0x65, 0xb5, 0xae, 0x33, 0xdd, + 0xe1, 0x87, 0x9b, 0xe6, 0xfa, 0x20, 0x27, 0x1f, + 0x27, 0x98, 0xa2, 0x6d, 0x2e, 0x2f, 0x48, 0x3f, + 0x51, 0xde, 0xdc, 0x8d, 0xd4, 0xcd, 0xb6, 0x58, + 0xa5, 0x46, 0xdc, 0x2d, 0xe1, 0x69, 0x67, 0xf8, + 0x36, 0xa7, 0x87, 0x23, 0xf9, 0x41, 0xe0, 0x60, + 0x43, 0x05, 0x14, 0x03, 0x05, 0x9d, 0x08, 0x00, + 0x8a, 0x08, 0xb5, 0x38, 0x2a, 0x80, 0xd6, 0xab, + 0x10, 0xe8, 0x3c, 0x17, 0xfd, 0x34, 0xb8, 0x15, + 0xa0, 0xaa, 0x8a, 0xc0, 0xd4, 0x6d, 0x42, 0xea, + 0x47, 0x0a, 0x03, 0xd0, 0xb1, 0x29, 0xed, 0x06, + 0xe9, 0x7b, 0x6a, 0x9b, 0x06, 0x62, 0x27, 0xf0, + 0x28, 0x84, 0x3c, 0x10, 0x01, 0x84, 0xa0, 0x62, + 0xd5, 0x0d, 0xeb, 0x2c, 0x37, 0x07, 0x9f, 0x57, + 0x73, 0xc0, 0xc2, 0x00, 0x7e, 0xc0, 0xec, 0x71, + 0x55, 0x4c, 0x67, 0xc3, 0xfa, 0xcd, 0x4c, 0x38, + 0xf3, 0x3f, 0x85, 0xd0, 0xc5, 0xba, 0x80, 0xf4, + 0x4d, 0x3f, 0x56, 0x9b, 0x64, 0x40, 0xc2, 0xf1, + 0xd6, 0xab, 0xed, 0xca, 0x93, 0x04, 0xb1, 0xf6, + 0x97, 0xf7, 0x03, 0xbf, 0x52, 0xec, 0x57, 0x53, + 0xcd, 0xf2, 0x8a, 0x5b, 0xea, 0xd2, 0x9c, 0x51, + 0xaa, 0x64, 0xe3, 0xd4, 0x08, 0x25, 0xe5, 0xc2, + 0x56, 0x84, 0x2c, 0x6f, 0xe5, 0xdd, 0x56, 0x24, + 0x97, 0x24, 0x6f, 0x13, 0xa7, 0x9e, 0xd6, 0x07, + 0xca, 0xc3, 0xf1, 0xc8, 0xef, 0x32, 0x2b, 0xf5, + 0x98, 0xab, 0x5a, 0xcc, 0x0f, 0xd9, 0x9f, 0x1f, + 0x78, 0xae, 0x7f, 0x2e, 0xf0, 0x2c, 0x61, 0x08, + 0x1e, 0x06, 0x04, 0x10, 0x53, 0x01, 0xe0, 0xfc, + 0x18, 0xb0, 0x6c, 0x5c, 0xa0, 0x3e, 0x1c, 0xd0, + 0x3b, 0x40, 0xf9, 0x65, 0x53, 0xd0, 0x61, 0x00, + 0x1e, 0x0b, 0xfc, 0xf9, 0x41, 0x56, 0x20, 0x88, + 0x0a, 0x41, 0x80, 0xc7, 0x40, 0xd0, 0xe0, 0x3c, + 0x07, 0xc1, 0x80, 0x54, 0x46, 0x0c, 0xad, 0x30, + 0xf0, 0x1e, 0x0a, 0x02, 0xf4, 0xe3, 0xf6, 0x87, + 0xdc, 0x07, 0x81, 0xff, 0x1c, 0x48, 0x61, 0x5a, + 0xb4, 0xbe, 0x63, 0x80, 0xaa, 0x50, 0x3f, 0xfb, + 0x2d, 0x7d, 0x96, 0x67, 0x01, 0x55, 0xd0, 0xf7, + 0xed, 0x6e, 0x87, 0xd6, 0x95, 0xeb, 0x9e, 0xda, + 0xb2, 0x0e, 0x1a, 0x0c, 0x6c, 0xa7, 0xaa, 0xe1, + 0x79, 0x84, 0xd9, 0x98, 0x23, 0x09, 0x6d, 0xf2, + 0x08, 0xbd, 0x68, 0x70, 0x3c, 0x1f, 0xb2, 0x1e, + 0x71, 0x48, 0x18, 0xef, 0x95, 0x32, 0xc8, 0x79, + 0xc5, 0x25, 0x43, 0x72, 0xa4, 0x6f, 0x7a, 0x3a, + 0xb9, 0x55, 0x27, 0xca, 0x5d, 0x55, 0x5b, 0x2c, + 0x2f, 0x2e, 0xdf, 0x5c, 0xff, 0x92, 0x25, 0x63, + 0x7f, 0x35, 0x4e, 0x76, 0x8d, 0xf2, 0x9b, 0x99, + 0xff, 0x7e, 0xf4, 0xb3, 0xe6, 0x03, 0x10, 0x32, + 0x70, 0x86, 0x0d, 0x85, 0x6a, 0x3a, 0x24, 0xb0, + 0x99, 0x6a, 0x06, 0xb8, 0x21, 0x02, 0x18, 0x32, + 0xe9, 0x18, 0xd0, 0x78, 0x48, 0x0a, 0xd2, 0x83, + 0x15, 0xb0, 0xba, 0x49, 0x67, 0x0b, 0x19, 0x06, + 0x41, 0xa1, 0x70, 0xe9, 0x57, 0x52, 0xe8, 0x85, + 0xf6, 0x1b, 0x55, 0x8a, 0xda, 0x10, 0x68, 0x33, + 0x09, 0x81, 0xe0, 0x7f, 0xb5, 0x04, 0x49, 0xff, + 0x08, 0x40, 0xaa, 0x6f, 0xa3, 0xcf, 0xb6, 0xac, + 0x21, 0x2a, 0x1d, 0xab, 0xf9, 0x6d, 0x2c, 0x6f, + 0xcd, 0xb4, 0x3e, 0xd4, 0x93, 0xfe, 0xf7, 0xd4, + 0xb2, 0x20, 0x99, 0xbb, 0xd3, 0x4a, 0x78, 0x88, + 0x1c, 0x41, 0xa6, 0x83, 0x65, 0xc0, 0x7b, 0xc3, + 0x81, 0xca, 0x41, 0x21, 0x50, 0x82, 0xde, 0x2a, + 0x68, 0xb7, 0xc9, 0xbc, 0x1f, 0xab, 0xfa, 0xde, + 0x55, 0xe2, 0xde, 0x0e, 0x59, 0xff, 0x2a, 0x86, + 0xb3, 0xbf, 0xd5, 0x15, 0x44, 0x59, 0xe6, 0x6d, + 0x06, 0x60, 0xab, 0x07, 0x20, 0xa0, 0x95, 0xb0, + 0x2d, 0x04, 0x11, 0x28, 0xb5, 0x92, 0xbd, 0x68, + 0x0c, 0x42, 0xde, 0xb6, 0x06, 0x73, 0x5a, 0x2a, + 0x5c, 0x73, 0x9b, 0xe0, 0xee, 0x58, 0xe0, 0xb8, + 0x07, 0x40, 0xf8, 0x42, 0x1d, 0xb2, 0x0c, 0x5c, + 0xc0, 0xf8, 0x7a, 0x98, 0xbd, 0xbf, 0x83, 0x2b, + 0x03, 0xc5, 0xf1, 0xa5, 0x5f, 0x9f, 0xdc, 0x63, + 0x2f, 0xfb, 0xac, 0xe6, 0x2e, 0x9b, 0x65, 0x4e, + 0xd0, 0x18, 0x4e, 0x58, 0xdd, 0xa5, 0xb2, 0x67, + 0x5a, 0x6c, 0x05, 0x1e, 0x06, 0x60, 0x1b, 0x00, + 0xf0, 0xec, 0x14, 0x1f, 0x4e, 0x9d, 0x24, 0x56, + 0xc8, 0x43, 0x64, 0x7e, 0x5a, 0xaf, 0x66, 0x6b, + 0x6a, 0xb1, 0x84, 0xec, 0xb1, 0xe0, 0x55, 0x6d, + 0xf5, 0x03, 0x56, 0x70, 0x73, 0x77, 0x3b, 0x7f, + 0xf5, 0x9b, 0x2d, 0x62, 0x40, 0x18, 0x6a, 0xf5, + 0x1f, 0xc5, 0xf7, 0xa3, 0x2e, 0x3f, 0x5c, 0x98, + 0x42, 0x08, 0x21, 0x09, 0x60, 0x78, 0x3f, 0xf8, + 0x47, 0x43, 0xf6, 0xa9, 0x27, 0x0a, 0x1e, 0x33, + 0x03, 0xea, 0xfc, 0x08, 0x61, 0x08, 0x7d, 0xa5, + 0xc9, 0xe6, 0xcd, 0xce, 0x7d, 0x81, 0xfb, 0x43, + 0xd1, 0xf8, 0x90, 0x3c, 0xaa, 0xaf, 0x53, 0x96, + 0x42, 0xfa, 0x98, 0xbc, 0x3c, 0x8c, 0x2f, 0xd2, + 0xc8, 0xa5, 0xaf, 0xa9, 0x93, 0xf9, 0x6b, 0x82, + 0x58, 0x28, 0xc0, 0xf8, 0xfd, 0x85, 0x4a, 0x95, + 0x0e, 0x59, 0xfe, 0xee, 0x16, 0xab, 0x6e, 0x30, + 0xc3, 0x4c, 0x4f, 0xb3, 0xfe, 0x37, 0xfe, 0x4d, + 0xcf, 0x66, 0x4d, 0x6f, 0x79, 0xfb, 0xc9, 0xc8, + 0xbf, 0x21, 0xc3, 0x03, 0xdf, 0x84, 0x0a, 0xc0, + 0xe5, 0x28, 0xf8, 0x0e, 0x8e, 0x83, 0xff, 0xcf, + 0x27, 0x2f, 0x54, 0xb8, 0xe5, 0x52, 0xae, 0xf9, + 0xb9, 0x37, 0x1b, 0x97, 0x62, 0x8f, 0x29, 0x96, + 0xe6, 0xac, 0x6e, 0x1c, 0xb6, 0xde, 0x21, 0xe4, + 0x34, 0xed, 0x71, 0x9b, 0x69, 0xfe, 0xac, 0x4a, + 0x4a, 0x07, 0x55, 0x2b, 0x08, 0x42, 0x1a, 0x46, + 0xe2, 0x51, 0x08, 0x7a, 0x21, 0x7c, 0x0e, 0x68, + 0x34, 0x11, 0x92, 0xd5, 0x6c, 0xf9, 0xa5, 0x4a, + 0x75, 0x52, 0x56, 0x04, 0x11, 0xfb, 0x55, 0x16, + 0xa8, 0xd5, 0x7e, 0xb8, 0x38, 0x93, 0x7f, 0xbb, + 0xa0, 0xb2, 0x28, 0xd0, 0x33, 0x62, 0x58, 0x94, + 0x9c, 0x78, 0x3f, 0x48, 0xa8, 0x4a, 0xa2, 0x1a, + 0x96, 0xb0, 0xb1, 0x52, 0x42, 0xf5, 0x49, 0xfd, + 0x36, 0x66, 0xea, 0xfe, 0x9e, 0x6f, 0xdb, 0x93, + 0x79, 0x6a, 0x25, 0xd7, 0xe3, 0xec, 0x03, 0x5b, + 0x1f, 0x0f, 0x47, 0x63, 0xe1, 0xf4, 0x1d, 0x0f, + 0x00, 0xe8, 0xf9, 0xaf, 0x26, 0x4e, 0xca, 0x7a, + 0x94, 0x7a, 0xc1, 0x77, 0xd5, 0x07, 0xdf, 0xd2, + 0xdf, 0x56, 0x9b, 0xfa, 0x5c, 0x61, 0x99, 0x65, + 0x6b, 0xc0, 0x65, 0x82, 0xbf, 0xa9, 0xa3, 0x89, + 0x02, 0xd4, 0xc2, 0x06, 0x0e, 0x80, 0x31, 0xa0, + 0x78, 0x2f, 0xf9, 0x44, 0x06, 0x18, 0x9b, 0x7e, + 0xac, 0x1e, 0x0b, 0xfd, 0x9f, 0x82, 0x85, 0x91, + 0x28, 0x18, 0x38, 0xf7, 0x04, 0x28, 0x23, 0xe8, + 0x30, 0x18, 0x10, 0x18, 0x51, 0xec, 0xe0, 0x2b, + 0x27, 0xc5, 0x7d, 0x51, 0xde, 0x75, 0x74, 0x27, + 0xb5, 0xc1, 0x66, 0xc0, 0x8e, 0x10, 0xcb, 0xd2, + 0x83, 0x32, 0x21, 0x26, 0x12, 0x07, 0xf1, 0x37, + 0xbe, 0xaf, 0x52, 0x44, 0xcd, 0x40, 0x6c, 0x12, + 0xfb, 0xcc, 0xef, 0x03, 0xfb, 0x90, 0x21, 0xa4, + 0xef, 0x74, 0x18, 0xd2, 0x9b, 0x3c, 0x22, 0x1f, + 0x14, 0x01, 0xe0, 0x51, 0x62, 0x66, 0x52, 0x40, + 0x3b, 0xa2, 0x4e, 0x09, 0x5e, 0x05, 0x3f, 0xc7, + 0xc0, 0xa7, 0xcb, 0x47, 0x20, 0xaa, 0x8c, 0x8e, + 0x14, 0xf0, 0xb7, 0xa3, 0x80, 0x23, 0xc2, 0xc0, + 0xe7, 0x87, 0xcd, 0x24, 0x6c, 0x49, 0x03, 0x82, + 0x18, 0x31, 0x5e, 0x17, 0xc6, 0x9a, 0xbc, 0x60, + 0x1e, 0x0b, 0xfd, 0xb1, 0x28, 0x10, 0xc2, 0x13, + 0x5f, 0xa3, 0x75, 0x05, 0x8d, 0x89, 0x25, 0xc5, + 0x5b, 0xf5, 0x0a, 0x78, 0x05, 0xbe, 0xf2, 0x1a, + 0xca, 0x86, 0x80, 0xc7, 0x9a, 0x55, 0xe9, 0x33, + 0xde, 0x2b, 0xfe, 0xff, 0x74, 0x45, 0xdb, 0x77, + 0x76, 0x95, 0xdf, 0xff, 0x6d, 0xaf, 0x35, 0x8f, + 0x79, 0x01, 0x64, 0x91, 0x10, 0xcc, 0x55, 0xae, + 0x68, 0x14, 0x00, 0xcd, 0x0f, 0x19, 0x56, 0x56, + 0x39, 0xc6, 0x2e, 0x79, 0xa6, 0xb5, 0x70, 0xe6, + 0x90, 0x6a, 0x0c, 0xb2, 0xa9, 0x3d, 0xde, 0x16, + 0xb6, 0xdf, 0xf5, 0x44, 0x59, 0x4d, 0xdb, 0xd7, + 0xc7, 0xd4, 0x06, 0xd0, 0x07, 0x03, 0x97, 0x3f, + 0xa1, 0xa4, 0x48, 0x81, 0xc7, 0x5a, 0x1b, 0x0f, + 0x6d, 0x33, 0xa6, 0x2d, 0xf0, 0xe8, 0xb9, 0x8e, + 0x0e, 0x13, 0x30, 0xd4, 0x35, 0xe6, 0xbd, 0x81, + 0x91, 0x84, 0x0b, 0x32, 0x2c, 0x2f, 0x09, 0x9d, + 0x9d, 0x3f, 0xe5, 0x34, 0x11, 0xce, 0x62, 0x19, + 0xd2, 0x9e, 0x3f, 0x4e, 0x78, 0x0e, 0x25, 0x19, + 0x11, 0xf5, 0x00, 0x3c, 0x94, 0x23, 0xdc, 0x07, + 0x23, 0x39, 0x91, 0xa3, 0xe1, 0xe5, 0x02, 0x43, + 0x4d, 0x3f, 0x51, 0x82, 0xc4, 0x1c, 0x2e, 0xeb, + 0xcf, 0xc1, 0xf3, 0x0d, 0x27, 0xb9, 0x93, 0x74, + 0x73, 0x37, 0x6d, 0xd0, 0x33, 0x9e, 0xea, 0x39, + 0x14, 0xa2, 0xea, 0x22, 0xce, 0x73, 0x88, 0x88, + 0x54, 0xa8, 0xc4, 0xc2, 0xd5, 0x0b, 0x2c, 0x37, + 0xe2, 0xdd, 0x88, 0x44, 0xc6, 0xc1, 0x5d, 0x5c, + 0xae, 0xec, 0xa8, 0xd4, 0x44, 0x1c, 0xaa, 0x3b, + 0xd5, 0x90, 0x20, 0x9d, 0x43, 0xc3, 0x83, 0x71, + 0xea, 0x82, 0xf6, 0xc4, 0x0b, 0x1a, 0xff, 0x40, + 0x87, 0xd8, 0x0f, 0x66, 0xf3, 0xf2, 0x72, 0x6a, + 0xd6, 0x11, 0xad, 0xef, 0xd9, 0xa0, 0xc1, 0xef, + 0xe1, 0x59, 0x56, 0x77, 0x95, 0x44, 0x88, 0x44, + 0x5e, 0xf2, 0x22, 0xea, 0xce, 0x15, 0x26, 0xf6, + 0x24, 0x9b, 0xb9, 0xb7, 0xa8, 0x54, 0xd6, 0x65, + 0xbc, 0xe2, 0xd1, 0x6f, 0x4e, 0x45, 0x90, 0x8c, + 0xce, 0xf6, 0x23, 0x8b, 0xc3, 0x43, 0x5a, 0x9a, + 0xde, 0xe2, 0x82, 0xd0, 0xfb, 0xed, 0xb2, 0x1e, + 0x41, 0xc2, 0x05, 0x08, 0x06, 0xd7, 0x54, 0xf1, + 0x1c, 0x95, 0x71, 0x41, 0x4a, 0xd3, 0x72, 0xc5, + 0xb9, 0x93, 0x6d, 0xd6, 0xb3, 0xa8, 0xaa, 0xc8, + 0xed, 0x8b, 0xc5, 0xd6, 0x97, 0x49, 0xd7, 0x9d, + 0x89, 0xe4, 0x91, 0x69, 0x2c, 0xda, 0xba, 0xd6, + 0x0d, 0x83, 0xde, 0xc5, 0xc6, 0x26, 0xfa, 0x81, + 0xe9, 0x56, 0xea, 0x9b, 0x27, 0x36, 0xa3, 0xe7, + 0x2a, 0xcb, 0x2c, 0x8b, 0xa3, 0x71, 0x99, 0xe5, + 0x9b, 0xc4, 0x10, 0x33, 0xa1, 0x5c, 0x4d, 0x45, + 0x62, 0x02, 0xab, 0x93, 0x9f, 0x51, 0x20, 0x77, + 0xe5, 0x37, 0x72, 0xa0, 0x95, 0x74, 0x5c, 0x5e, + 0xa9, 0x58, 0x6a, 0x33, 0xfa, 0xbf, 0x0f, 0xf9, + 0xa9, 0x8b, 0x75, 0xaf, 0x58, 0x5b, 0xcc, 0xfb, + 0x17, 0x43, 0xd2, 0xae, 0xf9, 0x47, 0xb6, 0x1b, + 0xde, 0xc5, 0xd1, 0xae, 0x8d, 0xeb, 0x37, 0xe5, + 0xf3, 0x3e, 0xc2, 0x9f, 0x69, 0x6e, 0xb7, 0xf0, + 0x21, 0x22, 0x2e, 0x76, 0x49, 0x57, 0x45, 0x56, + 0x40, 0x8d, 0xe2, 0x54, 0x8a, 0x8b, 0x4b, 0x6c, + 0x68, 0x70, 0xc2, 0x2f, 0x7b, 0x99, 0x16, 0xef, + 0x54, 0xc8, 0xa3, 0xa1, 0xea, 0x3e, 0xda, 0xb8, + 0x56, 0xa5, 0xbc, 0x20, 0xab, 0xa2, 0xaf, 0x27, + 0xa2, 0xeb, 0xa1, 0x9b, 0x32, 0x4d, 0xa6, 0xf8, + 0x1c, 0x68, 0x61, 0x45, 0x7a, 0xb3, 0x6b, 0x4d, + 0x0e, 0x3f, 0xfb, 0xb8, 0x8e, 0x7e, 0xf7, 0x85, + 0x8b, 0x55, 0x1c, 0xe6, 0x4e, 0x73, 0xbc, 0x8b, + 0x09, 0x88, 0xfe, 0x37, 0xa5, 0x9d, 0xb6, 0x5b, + 0x67, 0x38, 0x80, 0xd7, 0x7b, 0xc2, 0x53, 0xae, + 0x58, 0xb2, 0xd9, 0xb6, 0xae, 0x4b, 0x0d, 0xaf, + 0x4d, 0x94, 0x3b, 0x5c, 0xfe, 0x9a, 0xb8, 0x90, + 0x15, 0xbf, 0x56, 0xb6, 0xb7, 0x72, 0x2d, 0x7d, + 0x65, 0x96, 0x08, 0x90, 0xab, 0xba, 0xa4, 0xd1, + 0x11, 0x5a, 0x3c, 0xcd, 0x62, 0x59, 0x3e, 0xc4, + 0xe6, 0xf6, 0xac, 0xa4, 0xae, 0x59, 0xb3, 0xba, + 0xa7, 0x88, 0xfb, 0x28, 0xde, 0x72, 0x11, 0xd8, + 0xe3, 0xb2, 0x23, 0x95, 0x05, 0x5a, 0x8c, 0x16, + 0xea, 0xf0, 0xdc, 0x59, 0x01, 0x3c, 0xff, 0x54, + 0xe1, 0x65, 0xf5, 0xe5, 0x0f, 0x2d, 0x58, 0x63, + 0x7b, 0x9c, 0xe3, 0xd9, 0x7a, 0xb1, 0x2f, 0x7b, + 0x28, 0x4b, 0x13, 0x4d, 0x33, 0x03, 0x86, 0x2f, + 0xbc, 0x1e, 0xdc, 0x91, 0x1f, 0x7b, 0x79, 0x00, + 0xae, 0xad, 0xde, 0xf1, 0x18, 0x50, 0x4d, 0x80, + 0x33, 0x9d, 0xb9, 0xca, 0x50, 0x8f, 0x84, 0xab, + 0xf0, 0x99, 0x55, 0x73, 0x73, 0xdc, 0x6b, 0x2e, + 0x7f, 0x9c, 0x9f, 0x11, 0x20, 0x2b, 0xe2, 0x95, + 0xc9, 0xa1, 0xab, 0x24, 0x93, 0xb0, 0xd1, 0x51, + 0x52, 0x05, 0xd6, 0x0c, 0x5f, 0x78, 0x4b, 0x4f, + 0xd4, 0xc4, 0x6a, 0x92, 0xfa, 0x6b, 0x6a, 0x76, + 0xf4, 0x73, 0x62, 0x8e, 0x6a, 0xca, 0x16, 0x43, + 0x06, 0xd3, 0xa8, 0xc2, 0x9b, 0xb0, 0x72, 0xca, + 0xa9, 0xf8, 0xb4, 0x1f, 0xb0, 0xdf, 0xba, 0x49, + 0xb3, 0x96, 0x0d, 0xd1, 0x2e, 0x68, 0x4e, 0x83, + 0x10, 0x41, 0xad, 0xb7, 0x36, 0xde, 0xb7, 0xce, + 0xf0, 0xb7, 0x16, 0x5a, 0xe2, 0xd7, 0x96, 0x0a, + 0xcb, 0xe2, 0xac, 0xeb, 0x05, 0x57, 0x91, 0x99, + 0x78, 0x8f, 0x8b, 0xf7, 0x16, 0x5f, 0x90, 0x28, + 0x5b, 0x6b, 0xa2, 0xee, 0xf7, 0xa0, 0xf5, 0x30, + 0x01, 0x84, 0xbd, 0x05, 0xe0, 0x3a, 0x1b, 0x04, + 0xd5, 0x56, 0xd3, 0x61, 0x8c, 0xa0, 0xe0, 0x1e, + 0x72, 0xa9, 0xf9, 0x10, 0x1f, 0xd3, 0xa3, 0x68, + 0xca, 0x11, 0x1d, 0x2c, 0xa6, 0x9a, 0x88, 0xae, + 0x29, 0xe7, 0xaf, 0xfd, 0x3f, 0xc1, 0xce, 0x7b, + 0xfc, 0x53, 0xec, 0x6f, 0x90, 0x41, 0xcc, 0xb3, + 0x19, 0xe6, 0x0e, 0x66, 0xa8, 0x73, 0x52, 0xb1, + 0xa4, 0x20, 0xe4, 0x47, 0x0c, 0xb4, 0xad, 0x9b, + 0xf6, 0x73, 0xe9, 0xae, 0x7b, 0x2c, 0x2c, 0xf9, + 0x6c, 0x05, 0x6c, 0x0e, 0x54, 0x41, 0xb5, 0xe8, + 0xc5, 0x18, 0xa9, 0x4a, 0x81, 0xc2, 0x8a, 0x98, + 0xaa, 0xf2, 0xce, 0x7f, 0xde, 0xff, 0xaa, 0x36, + 0x99, 0xf7, 0x99, 0x6b, 0x79, 0x7a, 0x56, 0xc3, + 0x33, 0x5a, 0xde, 0x6c, 0x9b, 0x14, 0xe5, 0xe6, + 0xe6, 0x68, 0xdf, 0x23, 0xde, 0xef, 0x57, 0xed, + 0xb6, 0xdb, 0xd4, 0x3d, 0xb4, 0x96, 0xa1, 0xb4, + 0x8d, 0x05, 0x24, 0x80, 0xe2, 0x51, 0xaf, 0xe8, + 0x3f, 0x7c, 0x00, 0x72, 0x13, 0xc6, 0xc2, 0xd0, + 0x2b, 0x26, 0x8e, 0x74, 0x7c, 0x3c, 0xd6, 0x62, + 0x8b, 0x15, 0xfc, 0x74, 0x3c, 0xfa, 0x59, 0x73, + 0x85, 0x97, 0x13, 0xfd, 0x35, 0x57, 0x2b, 0x53, + 0x24, 0x6a, 0x96, 0xf5, 0xa5, 0x12, 0x7a, 0xe2, + 0x88, 0x79, 0x54, 0xe9, 0x07, 0x83, 0xf5, 0x10, + 0x7e, 0x93, 0xc9, 0x7d, 0x2a, 0x9e, 0x37, 0xaa, + 0xfd, 0x4b, 0x78, 0x37, 0x2d, 0x61, 0xb6, 0x1b, + 0x29, 0x0f, 0x54, 0x7d, 0x6b, 0xf9, 0xa5, 0x98, + 0x7a, 0xaf, 0x41, 0x63, 0xd0, 0xc0, 0xeb, 0x19, + 0x83, 0x81, 0x3a, 0xd9, 0x06, 0x24, 0xaf, 0xa3, + 0x44, 0xc4, 0x9b, 0xca, 0x37, 0xcc, 0x2c, 0x51, + 0x22, 0x8a, 0xd6, 0x56, 0x0b, 0x24, 0x92, 0x35, + 0x58, 0xb0, 0x70, 0x20, 0x4c, 0xc9, 0xe8, 0xc1, + 0x60, 0xe0, 0xb2, 0x4f, 0x28, 0x51, 0x0f, 0x29, + 0x31, 0xa9, 0xd8, 0xa9, 0xa4, 0xc9, 0xa6, 0xf3, + 0xb8, 0x3e, 0x1e, 0x24, 0x2e, 0x9b, 0x73, 0xaa, + 0x2b, 0x70, 0xb9, 0x86, 0x87, 0x3b, 0x93, 0x7f, + 0x30, 0xb5, 0x4a, 0x82, 0xdf, 0xa8, 0xe2, 0x9a, + 0x7c, 0xcf, 0x4f, 0x7e, 0x9b, 0x2b, 0x19, 0x05, + 0x5a, 0x8c, 0x24, 0x07, 0x12, 0x91, 0xe9, 0x8b, + 0x44, 0x84, 0x93, 0x47, 0x29, 0xd8, 0x1f, 0x09, + 0x54, 0x77, 0x36, 0x96, 0x27, 0x06, 0x50, 0x3e, + 0xf2, 0x59, 0xff, 0x87, 0x6c, 0xfd, 0x2e, 0x35, + 0x89, 0xef, 0xea, 0x9d, 0x2d, 0xbb, 0xf5, 0x2d, + 0xaf, 0x2d, 0xbd, 0x78, 0x95, 0x38, 0xe1, 0xb4, + 0xda, 0xc7, 0xd3, 0x34, 0x3f, 0x53, 0x24, 0xaa, + 0x93, 0xe3, 0x4c, 0xb1, 0xbf, 0xc1, 0xb5, 0xfb, + 0x5a, 0xa7, 0x0a, 0xbf, 0x26, 0xaf, 0x2f, 0x2a, + 0x24, 0x4e, 0x44, 0x4a, 0x49, 0x93, 0x1a, 0xf9, + 0x6b, 0x79, 0xac, 0xaf, 0xc5, 0x3c, 0xcb, 0xca, + 0x6e, 0x50, 0x60, 0xa5, 0x3d, 0xf3, 0x78, 0xb3, + 0x5c, 0x44, 0xa6, 0xfc, 0xd6, 0x8c, 0xba, 0x8c, + 0x1d, 0x48, 0x06, 0x10, 0x9a, 0x88, 0x10, 0x1e, + 0xd7, 0xb2, 0xe6, 0xf5, 0xa4, 0xe9, 0x15, 0x09, + 0x25, 0xed, 0x35, 0x93, 0x75, 0xb6, 0x5a, 0x92, + 0x22, 0x54, 0xd6, 0x78, 0x93, 0x39, 0xef, 0x01, + 0x49, 0x92, 0x39, 0x3d, 0x4d, 0xe6, 0x8b, 0xa7, + 0x8b, 0x92, 0x5b, 0xb3, 0x1a, 0x48, 0x93, 0xcd, + 0x5e, 0xed, 0xad, 0x7b, 0x22, 0x3d, 0xde, 0xcc, + 0xdb, 0xb7, 0x7b, 0x6f, 0x24, 0x99, 0x88, 0x0f, + 0x6f, 0xe1, 0x66, 0x45, 0x3d, 0x02, 0x74, 0xd2, + 0xc4, 0xa1, 0x57, 0x50, 0x8c, 0x95, 0x11, 0x40, + 0x2c, 0x45, 0x3c, 0x52, 0x85, 0xfa, 0x6a, 0xb4, + 0x21, 0x09, 0x0d, 0x72, 0xaa, 0x10, 0x84, 0x85, + 0x56, 0x7f, 0xcc, 0xe0, 0x80, 0x3a, 0x2e, 0x6a, + 0xc6, 0x58, 0xe8, 0xe1, 0x9c, 0xbe, 0x6b, 0x38, + 0xdb, 0x4a, 0x74, 0x70, 0xdc, 0x0f, 0x5a, 0x2d, + 0xd5, 0x16, 0x29, 0xd3, 0xe5, 0xfc, 0xc3, 0x49, + 0xb2, 0x34, 0xc3, 0x4d, 0x30, 0xd6, 0x5b, 0x71, + 0x86, 0x3d, 0x15, 0x7a, 0x5d, 0xbd, 0xfd, 0x9e, + 0xc9, 0x99, 0x3b, 0x7b, 0xbb, 0x79, 0xdb, 0xb6, + 0xed, 0x5e, 0x9f, 0x2a, 0x63, 0x5a, 0x2f, 0x25, + 0x42, 0x14, 0x42, 0x4a, 0x45, 0x13, 0x74, 0xa3, + 0x87, 0xc4, 0x7b, 0x99, 0xfc, 0xdf, 0x6f, 0xa3, + 0x7e, 0xfc, 0xb1, 0xbf, 0x7f, 0x33, 0xfe, 0xdf, + 0x55, 0xae, 0x7f, 0xdf, 0x53, 0x9b, 0x95, 0x0e, + 0x6f, 0x65, 0x21, 0xba, 0x88, 0x1d, 0xc0, 0x58, + 0x03, 0x9f, 0x81, 0xcb, 0xd4, 0x60, 0xe2, 0x17, + 0x18, 0xbe, 0xa6, 0xa2, 0x41, 0x28, 0x74, 0xd1, + 0x6b, 0x4d, 0x09, 0x43, 0xc5, 0x5e, 0x67, 0x2e, + 0x2b, 0xf2, 0xa1, 0xe2, 0x65, 0x58, 0xaf, 0x39, + 0xb1, 0x43, 0x38, 0xc3, 0x59, 0x8c, 0xe7, 0x3f, + 0xfc, 0xe7, 0xe6, 0xad, 0xfd, 0x82, 0x2b, 0xc5, + 0xad, 0x7b, 0xde, 0x6a, 0x34, 0xd7, 0xa3, 0x5e, + 0xcc, 0x99, 0xef, 0x35, 0x26, 0x67, 0xbd, 0x88, + 0xb3, 0x3d, 0xee, 0x66, 0x64, 0x85, 0x53, 0x24, + 0xe6, 0x49, 0xc8, 0x79, 0x0f, 0x55, 0xc6, 0x43, + 0x20, 0x1f, 0x0a, 0x02, 0xad, 0x88, 0x90, 0x84, + 0x56, 0x94, 0x85, 0x55, 0x1b, 0xe3, 0x0c, 0x7a, + 0xb7, 0xbe, 0x6b, 0x33, 0x59, 0xd2, 0xd6, 0x77, + 0xd9, 0x26, 0xb3, 0xfe, 0x70, 0xb5, 0xbb, 0xc9, + 0x5b, 0xff, 0x39, 0x85, 0xbb, 0xdd, 0x51, 0xc9, + 0xde, 0x3a, 0x38, 0xb0, 0xcc, 0x1d, 0xc0, 0x4e, + 0x4c, 0xe3, 0x5b, 0x62, 0x11, 0xae, 0xbe, 0xa8, + 0x86, 0x2f, 0xce, 0xdd, 0x19, 0x02, 0xc5, 0xee, + 0xc2, 0x9a, 0x0b, 0x96, 0x95, 0x63, 0x9a, 0xfa, + 0x83, 0x88, 0x74, 0x07, 0x1f, 0xd1, 0x02, 0x22, + 0x2a, 0x0c, 0x45, 0xcb, 0x42, 0x64, 0x42, 0x41, + 0xa7, 0x45, 0x21, 0x44, 0x83, 0x86, 0x03, 0x56, + 0x80, 0x31, 0x21, 0x7d, 0x59, 0x10, 0x64, 0x19, + 0x39, 0xd6, 0xe9, 0x1e, 0x9c, 0x5c, 0x44, 0xb1, + 0x28, 0x39, 0x71, 0x5a, 0x62, 0x78, 0x91, 0x60, + 0x7f, 0x2f, 0xff, 0xf0, 0x3d, 0x1c, 0x00, 0x60, + 0xe7, 0x67, 0x74, 0xcb, 0x8c, 0x21, 0x40, 0x2c, + 0x51, 0x0d, 0x75, 0x88, 0x40, 0x70, 0x38, 0x82, + 0x01, 0xc6, 0xba, 0x0e, 0x26, 0x68, 0x56, 0x44, + 0x0e, 0x34, 0xe6, 0x2b, 0x13, 0x69, 0x9a, 0x65, + 0x85, 0x28, 0x79, 0x10, 0xf0, 0x31, 0x91, 0x61, + 0x88, 0x54, 0xa2, 0xaf, 0x41, 0xcf, 0xef, 0x7b, + 0xcb, 0xcb, 0xd9, 0x54, 0xca, 0x22, 0x21, 0x40, + 0xe2, 0xfa, 0x8a, 0xf2, 0x03, 0x81, 0x72, 0x70, + 0x41, 0x9a, 0xd5, 0xdc, 0x8d, 0xf2, 0x76, 0x2e, + 0x55, 0xfb, 0xa8, 0x38, 0x6d, 0x70, 0x74, 0x7a, + 0x10, 0x54, 0xc5, 0xaa, 0x26, 0xa3, 0x44, 0x0b, + 0x00, 0x5f, 0x2c, 0xdc, 0xe0, 0x75, 0x11, 0xde, + 0x44, 0x7c, 0xec, 0x44, 0x75, 0x75, 0x43, 0x9a, + 0xc5, 0x0f, 0xed, 0xde, 0xed, 0x24, 0xd9, 0x10, + 0x62, 0xc8, 0xf8, 0x04, 0x56, 0xec, 0x46, 0x42, + 0x96, 0x15, 0xcb, 0x17, 0x5a, 0xc4, 0x38, 0xb1, + 0x22, 0xe8, 0xa1, 0x48, 0xc8, 0xe1, 0x92, 0xae, + 0x09, 0xd1, 0x34, 0xf3, 0x03, 0x9b, 0xd1, 0xb7, + 0x22, 0x05, 0x89, 0x29, 0x0e, 0xb9, 0x11, 0xf1, + 0x12, 0x14, 0x01, 0x8c, 0x0c, 0xa9, 0x3c, 0xcc, + 0x5e, 0x23, 0xec, 0x28, 0x0a, 0x67, 0x57, 0x36, + 0x0e, 0x28, 0x39, 0x22, 0x11, 0x71, 0xda, 0xbf, + 0x91, 0x7d, 0xd2, 0x85, 0xd7, 0x0c, 0xc6, 0x01, + 0x3d, 0x2b, 0xda, 0xcb, 0x52, 0x23, 0x88, 0x56, + 0xec, 0xe8, 0xc6, 0x20, 0x44, 0x4f, 0x8a, 0x14, + 0x12, 0x50, 0xc5, 0x12, 0xe4, 0x4c, 0xa4, 0xe7, + 0x46, 0x9a, 0x66, 0x72, 0x36, 0xde, 0x8e, 0x7e, + 0xc9, 0x50, 0x14, 0xf4, 0x5a, 0x12, 0x55, 0xa1, + 0x5d, 0x24, 0x22, 0x82, 0xc9, 0x51, 0xcb, 0xde, + 0x02, 0xc0, 0xa7, 0xa2, 0x92, 0x35, 0x44, 0x46, + 0x85, 0x11, 0x28, 0x30, 0x51, 0xa4, 0x43, 0x41, + 0x85, 0xe0, 0xe0, 0xae, 0xf5, 0x09, 0x06, 0x99, + 0x2f, 0x31, 0x99, 0x16, 0xc2, 0xc9, 0xc0, 0xd3, + 0xa3, 0x28, 0x43, 0xda, 0xbf, 0x9b, 0xe8, 0x1d, + 0xdb, 0xf5, 0xd0, 0x16, 0x60, 0x67, 0x49, 0x10, + 0xde, 0x9d, 0x9e, 0x14, 0x8c, 0x51, 0x82, 0xc0, + 0xd0, 0xa9, 0x55, 0x18, 0x5a, 0xd5, 0xb2, 0xd2, + 0xb9, 0xcd, 0x59, 0x65, 0xcd, 0xd4, 0x08, 0x14, + 0x41, 0x83, 0x9c, 0xdd, 0x5d, 0xfa, 0x6b, 0x29, + 0x05, 0xcb, 0x52, 0x32, 0x07, 0x06, 0x24, 0xe6, + 0xaf, 0xe9, 0x48, 0xa5, 0x45, 0x3a, 0x48, 0x0e, + 0x20, 0x5e, 0x70, 0x17, 0xba, 0x75, 0x69, 0x48, + 0x47, 0x1d, 0x36, 0x0e, 0x17, 0x11, 0x6e, 0xea, + 0x34, 0x63, 0x35, 0x86, 0x92, 0x5b, 0xa6, 0xa9, + 0x2c, 0xe8, 0x38, 0x16, 0x02, 0xa5, 0x59, 0xd1, + 0x75, 0x7b, 0xde, 0x70, 0x1f, 0xbe, 0x00, 0x3f, + 0xfa, 0xfa, 0xce, 0x9a, 0x90, 0x51, 0xe4, 0xea, + 0x0c, 0x22, 0x99, 0x57, 0x34, 0x4d, 0x57, 0xa3, + 0x8f, 0x86, 0xca, 0x0f, 0xdb, 0x6d, 0x37, 0x50, + 0x4a, 0xe5, 0x5b, 0x6a, 0xd8, 0xbf, 0x65, 0xec, + 0xd7, 0x2b, 0xb5, 0xff, 0x61, 0xc7, 0xe9, 0x7b, + 0xd3, 0x96, 0xcc, 0x9c, 0x5a, 0xb7, 0xed, 0x41, + 0x38, 0x73, 0x46, 0x53, 0x75, 0x6b, 0xfd, 0x30, + 0xd7, 0x84, 0xaf, 0xd3, 0x32, 0x07, 0x95, 0xfc, + 0x73, 0x5a, 0x1b, 0xf9, 0x42, 0x99, 0x03, 0x8e, + 0x10, 0xcc, 0xa0, 0xe1, 0xa0, 0xc4, 0x10, 0x8b, + 0xf7, 0xe3, 0xdc, 0xf0, 0x7d, 0x71, 0x4e, 0x7e, + 0x5d, 0xb4, 0x36, 0x14, 0x28, 0x83, 0x03, 0x00, + 0x58, 0x82, 0xc0, 0xfa, 0x7f, 0x39, 0x51, 0x9e, + 0x89, 0xbb, 0x20, 0xcd, 0x12, 0x01, 0x3d, 0xaf, + 0x50, 0x83, 0x85, 0xe8, 0x8a, 0x05, 0x29, 0xaf, + 0x4e, 0xe8, 0x84, 0x31, 0x08, 0x8c, 0x3f, 0xa7, + 0x22, 0xf5, 0x88, 0xea, 0x83, 0xba, 0x18, 0x0a, + 0xf4, 0x92, 0xa1, 0x44, 0x0e, 0x44, 0x12, 0x6a, + 0x0e, 0x90, 0x1c, 0x7a, 0xa0, 0x21, 0xa9, 0xb5, + 0xd1, 0x83, 0xba, 0x6d, 0x08, 0x4d, 0xdf, 0x97, + 0x35, 0x22, 0x30, 0x72, 0x03, 0xbf, 0x88, 0xc0, + 0x72, 0xe0, 0x38, 0x29, 0x9d, 0x34, 0xbd, 0x0a, + 0x34, 0xdf, 0x91, 0xf0, 0xa4, 0x53, 0x39, 0x09, + 0x2a, 0x30, 0x73, 0xdf, 0x91, 0xc4, 0x00, 0xe5, + 0xa7, 0x01, 0x39, 0xf9, 0x11, 0xa0, 0x8a, 0xbe, + 0x2f, 0xaa, 0x31, 0x90, 0xcc, 0x31, 0x27, 0xfd, + 0x34, 0xb1, 0xcf, 0x01, 0xfd, 0x7f, 0xff, 0xd2, + 0x74, 0xa0, 0x1d, 0x4a, 0x4e, 0x59, 0x0e, 0xe9, + 0xb4, 0x05, 0x00, 0xe3, 0x44, 0xf8, 0x31, 0x05, + 0xd3, 0x8b, 0x21, 0x7e, 0x5c, 0x1c, 0x03, 0xc1, + 0x3d, 0x51, 0x14, 0x0a, 0xea, 0x78, 0xa0, 0x31, + 0x09, 0x64, 0x1c, 0x12, 0xbe, 0x1b, 0x80, 0xe2, + 0x0c, 0x8b, 0x84, 0x85, 0x20, 0xb0, 0x09, 0x18, + 0x28, 0xd3, 0xe0, 0xe4, 0x20, 0xe0, 0x4d, 0xf6, + 0x9a, 0x07, 0x06, 0x4f, 0x60, 0xe4, 0x46, 0xdf, + 0xc6, 0x22, 0xe0, 0xc0, 0x28, 0xe2, 0x32, 0x0d, + 0x3f, 0xde, 0x00, 0xe0, 0x92, 0x01, 0x79, 0x54, + 0x6e, 0xec, 0xba, 0x02, 0x1a, 0x6c, 0xfc, 0x5f, + 0x8b, 0xc0, 0x77, 0x4f, 0x4a, 0x03, 0x61, 0x1b, + 0x50, 0x83, 0x84, 0x5f, 0xa3, 0x31, 0x45, 0xc5, + 0x81, 0xd4, 0xee, 0x9c, 0xda, 0x48, 0x31, 0xe2, + 0x32, 0x8a, 0xe2, 0xd2, 0x5b, 0xb7, 0x68, 0xcb, + 0x0d, 0x12, 0xa2, 0x42, 0x14, 0x65, 0xcd, 0x03, + 0x83, 0x20, 0x9d, 0x0e, 0x0b, 0x82, 0x96, 0xb4, + 0x64, 0xed, 0x34, 0xf9, 0xb5, 0x0d, 0x80, 0xfd, + 0xb0, 0x01, 0xd6, 0x62, 0x8d, 0x5d, 0x1d, 0x29, + 0xa1, 0x80, 0x66, 0x32, 0x7f, 0xe9, 0xb1, 0x33, + 0x17, 0x1a, 0x87, 0x59, 0x72, 0x0a, 0xba, 0x7a, + 0x88, 0x92, 0xf1, 0xf8, 0x31, 0x07, 0x40, 0x8f, + 0x12, 0xa0, 0x45, 0x3a, 0x88, 0x1c, 0x11, 0x30, + 0x72, 0xe4, 0x5a, 0x83, 0x61, 0x3c, 0x4e, 0xaa, + 0x00, 0xc9, 0x19, 0xf6, 0xb0, 0x38, 0x07, 0x04, + 0x93, 0x46, 0x62, 0x66, 0xb0, 0x2c, 0x08, 0xea, + 0x95, 0xc1, 0x3f, 0x48, 0x99, 0x3a, 0x8e, 0xf4, + 0xd2, 0xc0, 0xe0, 0xc4, 0x69, 0x34, 0x1e, 0x82, + 0x00, 0x30, 0x71, 0x4b, 0xdb, 0x0c, 0x45, 0x29, + 0xda, 0x4d, 0xa7, 0xf9, 0xde, 0x74, 0x5c, 0x0b, + 0xa4, 0xfc, 0xa6, 0xfc, 0x3d, 0x51, 0xc9, 0xf0, + 0xf3, 0x88, 0xcd, 0x4e, 0xd3, 0x60, 0xbb, 0xf3, + 0xaa, 0x17, 0xe4, 0xa2, 0xe0, 0x71, 0xf8, 0x8b, + 0x5c, 0x86, 0xa8, 0x3b, 0xa7, 0x64, 0x1a, 0x69, + 0x8e, 0x01, 0x14, 0x49, 0x41, 0x3c, 0x08, 0xd0, + 0x18, 0x07, 0xb9, 0x1c, 0x4e, 0x25, 0xd4, 0x71, + 0x80, 0x7d, 0x8f, 0xff, 0x52, 0xdd, 0x36, 0x14, + 0xd7, 0x4d, 0x38, 0xba, 0x36, 0x5a, 0x18, 0xa9, + 0xd2, 0x91, 0xda, 0x1f, 0xb5, 0x90, 0xa1, 0x71, + 0x7f, 0x48, 0x28, 0x19, 0x7a, 0x8c, 0xbc, 0x61, + 0xc8, 0x12, 0x7e, 0xae, 0x15, 0x60, 0xc8, 0x4d, + 0xe6, 0xea, 0x20, 0xc0, 0x13, 0x75, 0xe9, 0x52, + 0xaf, 0x74, 0x3d, 0xd6, 0x6d, 0xa2, 0xba, 0x69, + 0x32, 0xa4, 0x77, 0x65, 0x3d, 0x2b, 0x50, 0x75, + 0x05, 0xd5, 0xee, 0x1f, 0x55, 0xca, 0xd1, 0xbf, + 0x5e, 0x59, 0xbe, 0x06, 0x24, 0xc3, 0xe9, 0xff, + 0xeb, 0x20, 0x39, 0x41, 0xda, 0x80, 0x75, 0x07, + 0x0d, 0x56, 0x02, 0xe7, 0xaf, 0xa0, 0xcc, 0x8b, + 0x4e, 0x65, 0x91, 0x12, 0xc3, 0x49, 0x52, 0xe7, + 0x59, 0xa5, 0x01, 0x47, 0x2d, 0x06, 0x14, 0x4e, + 0x6a, 0x3a, 0x76, 0x2e, 0xbf, 0xfe, 0xd7, 0xc1, + 0x8d, 0xfa, 0xd4, 0x44, 0x27, 0x3e, 0x5a, 0x25, + 0xb0, 0xc5, 0x51, 0xd3, 0x54, 0xb2, 0xab, 0xf0, + 0x3c, 0x64, 0x01, 0xad, 0xb7, 0x8b, 0x85, 0x63, + 0x16, 0x67, 0x95, 0xc0, 0x64, 0x3e, 0xd9, 0x62, + 0x14, 0x41, 0x29, 0x6f, 0x5b, 0xc5, 0xba, 0x84, + 0xd0, 0xc4, 0x2b, 0x4d, 0x8a, 0x01, 0xd2, 0xe0, + 0x0f, 0x76, 0x9a, 0x02, 0x40, 0xed, 0xa1, 0x2e, + 0x37, 0x7d, 0x8c, 0xe4, 0xf5, 0x90, 0x15, 0xad, + 0x6b, 0x48, 0x10, 0x29, 0x40, 0xb1, 0x01, 0x1d, + 0xc3, 0x5c, 0x07, 0x1f, 0x24, 0xab, 0x4a, 0x90, + 0x14, 0x82, 0xc0, 0x27, 0x8d, 0x44, 0x18, 0x12, + 0x05, 0x1a, 0x24, 0x1c, 0x34, 0xbf, 0x42, 0xbd, + 0x3b, 0x15, 0x6d, 0x07, 0x12, 0x0b, 0x9e, 0xac, + 0x0c, 0x81, 0xcf, 0xf6, 0x03, 0xd0, 0x40, 0x06, + 0x30, 0x20, 0x61, 0x4e, 0x9d, 0x8c, 0xf8, 0x26, + 0x84, 0x43, 0x33, 0x74, 0x1c, 0x0b, 0xec, 0xb9, + 0x36, 0x41, 0x45, 0x5a, 0x28, 0xb9, 0xcd, 0x3f, + 0x9d, 0x2d, 0x80, 0xe9, 0x01, 0xc2, 0xfa, 0x34, + 0xde, 0x07, 0x1b, 0x73, 0xc1, 0xb8, 0xcf, 0xa5, + 0x23, 0x56, 0xd7, 0x41, 0xc8, 0xf8, 0x14, 0xe7, + 0x2a, 0xf0, 0x52, 0x0e, 0x0a, 0x3c, 0x43, 0x7a, + 0x8c, 0x4f, 0x89, 0x41, 0xd4, 0x13, 0x7d, 0xa0, + 0xe0, 0xc8, 0x89, 0xaa, 0x03, 0xd1, 0x3f, 0x3b, + 0xd2, 0x40, 0x71, 0xd6, 0x37, 0x01, 0xfc, 0x05, + 0xd3, 0x84, 0x39, 0x09, 0x03, 0x23, 0xa1, 0x1e, + 0x9e, 0x19, 0x83, 0x06, 0x41, 0x57, 0x07, 0x0c, + 0x09, 0x4f, 0x63, 0xfc, 0x66, 0xb8, 0x38, 0xf2, + 0xf0, 0x17, 0x71, 0x3c, 0x32, 0x0a, 0xba, 0x28, + 0x81, 0x72, 0x40, 0x5c, 0x35, 0xa9, 0x0b, 0x07, + 0x02, 0x6a, 0x12, 0x11, 0xe9, 0xea, 0x0e, 0x01, + 0xe0, 0xb8, 0xe8, 0x81, 0xc2, 0x8d, 0x46, 0x42, + 0x9c, 0x0f, 0x43, 0xff, 0xff, 0x02, 0x76, 0x22, + 0xa9, 0xcd, 0x07, 0x52, 0x3e, 0x0e, 0x04, 0xea, + 0xa0, 0xf3, 0xd0, 0x01, 0x83, 0x88, 0x9a, 0xe8, + 0xd1, 0x92, 0x03, 0x81, 0x3e, 0xf6, 0x54, 0x5d, + 0x58, 0x4d, 0x17, 0x66, 0xc3, 0x10, 0x5c, 0xf0, + 0xcc, 0x1c, 0x12, 0x3a, 0xe9, 0x05, 0x80, 0x54, + 0xc8, 0xc1, 0xd7, 0xa7, 0xaa, 0xf5, 0xd8, 0x6d, + 0x68, 0x8a, 0xba, 0x39, 0xc4, 0x08, 0xc8, 0x2c, + 0x07, 0x83, 0x84, 0xf5, 0x79, 0xa8, 0x45, 0xcb, + 0x82, 0xc3, 0x83, 0x17, 0xa6, 0x48, 0x48, 0x27, + 0xd3, 0xc2, 0xe1, 0x3f, 0x07, 0x04, 0xcc, 0x65, + 0xd0, 0xc8, 0x28, 0xc0, 0xe2, 0x40, 0x5c, 0x5b, + 0x38, 0x0b, 0xba, 0xbf, 0xa5, 0x72, 0x72, 0xca, + 0x8d, 0x1a, 0x21, 0x75, 0x8b, 0x13, 0xf2, 0x99, + 0x67, 0x10, 0x51, 0x81, 0x07, 0x15, 0x60, 0x75, + 0x58, 0x2a, 0xb6, 0x9e, 0xd3, 0xca, 0x54, 0xc5, + 0x8a, 0x41, 0xce, 0x65, 0x24, 0x4d, 0x15, 0x45, + 0xd0, 0xc0, 0x5c, 0x0b, 0xcc, 0xb1, 0xb1, 0x8f, + 0x20, 0x60, 0x13, 0x34, 0xee, 0x14, 0xbf, 0x5e, + 0x77, 0x4d, 0x03, 0xa0, 0x2c, 0x42, 0x6d, 0x2d, + 0xa7, 0x97, 0x2f, 0x98, 0xdb, 0x5c, 0x2d, 0xd5, + 0xd1, 0x77, 0xa8, 0x2e, 0x5e, 0x73, 0x81, 0x2d, + 0xef, 0xb1, 0xa5, 0x38, 0x38, 0xb9, 0x56, 0xec, + 0xd6, 0xb7, 0x64, 0x24, 0x41, 0x6a, 0x2a, 0x71, + 0x3d, 0x04, 0x5a, 0x28, 0xa9, 0x99, 0xd6, 0x49, + 0x01, 0xc4, 0x16, 0x20, 0xe8, 0xa0, 0xe5, 0x63, + 0xe8, 0x53, 0xe9, 0x2f, 0x14, 0x03, 0xb8, 0x35, + 0xa0, 0x44, 0x82, 0x2f, 0xdb, 0xd8, 0x1b, 0xeb, + 0xd0, 0x3c, 0x58, 0x3d, 0x19, 0x16, 0x1d, 0xd7, + 0xb5, 0x1b, 0x60, 0x54, 0xaf, 0xfd, 0xb4, 0x38, + 0xd7, 0x7a, 0xc2, 0xa0, 0x62, 0x49, 0x2a, 0xf5, + 0x61, 0x33, 0xfa, 0x25, 0xa7, 0xbc, 0x16, 0x27, + 0x7d, 0xd4, 0x3f, 0x76, 0xba, 0xbf, 0xcc, 0xb3, + 0x9d, 0xdc, 0xd9, 0xc3, 0xd5, 0x3e, 0xd2, 0x0b, + 0xfc, 0xb6, 0x58, 0xe8, 0x80, 0x52, 0x06, 0x07, + 0xb5, 0xfd, 0x15, 0xb1, 0x6e, 0x5e, 0xf4, 0xb3, + 0x76, 0x0a, 0xb5, 0xea, 0xfe, 0x4f, 0xd9, 0xe1, + 0xc2, 0x76, 0xbb, 0x02, 0xd9, 0x1e, 0x0f, 0x77, + 0xab, 0x4f, 0x79, 0xb5, 0x8c, 0xd2, 0xdc, 0x42, + 0x27, 0xef, 0xf5, 0x4e, 0x60, 0x31, 0xa9, 0x4d, + 0x54, 0x47, 0xf5, 0xdb, 0x4d, 0x25, 0xec, 0xee, + 0x7d, 0x56, 0x5b, 0x78, 0x2b, 0xd1, 0x25, 0xc4, + 0x75, 0x96, 0xf9, 0xc8, 0x08, 0xce, 0xfb, 0x9f, + 0xe2, 0xf3, 0x1f, 0x6d, 0xb5, 0xb6, 0x21, 0x95, + 0x01, 0xf4, 0xca, 0x8a, 0x87, 0xbb, 0x20, 0x49, + 0x53, 0x2e, 0x5c, 0xa9, 0xa8, 0x5e, 0xc3, 0x74, + 0xb4, 0xa9, 0x96, 0xb4, 0x3b, 0xf8, 0x73, 0x05, + 0x6b, 0x37, 0x79, 0x4a, 0x78, 0x2f, 0x82, 0x75, + 0xd3, 0x2b, 0x03, 0x6a, 0xda, 0x54, 0xc4, 0xfd, + 0xd6, 0xff, 0xef, 0x65, 0xe7, 0x17, 0xba, 0xb5, + 0x5c, 0xc9, 0xa8, 0x9a, 0x8f, 0x9a, 0x61, 0x8a, + 0xce, 0xa7, 0xdc, 0xc0, 0x2f, 0xf4, 0x21, 0x9a, + 0xc6, 0x85, 0x43, 0x2c, 0xe0, 0xca, 0x93, 0x69, + 0xae, 0x5d, 0x7b, 0xe3, 0x6b, 0x82, 0x71, 0x4a, + 0x8a, 0x91, 0xf1, 0x28, 0x3a, 0xbd, 0x05, 0xac, + 0x15, 0x22, 0xea, 0x04, 0x0e, 0xc8, 0xa2, 0xee, + 0xf4, 0x1c, 0x52, 0x0e, 0x40, 0x15, 0x4d, 0x8b, + 0x03, 0xa0, 0x0f, 0xe9, 0x1a, 0x0b, 0x43, 0x61, + 0x85, 0x39, 0xa6, 0x41, 0x78, 0x4b, 0x78, 0x88, + 0xf6, 0x9c, 0xf5, 0x70, 0x77, 0x02, 0x2c, 0x0f, + 0x4f, 0x00, 0x18, 0xd2, 0xc7, 0x08, 0x41, 0xc1, + 0x88, 0x4d, 0x40, 0xc7, 0x99, 0x19, 0x1e, 0x9e, + 0xf2, 0xd6, 0x02, 0xc7, 0x80, 0xe1, 0x93, 0xf7, + 0x91, 0x8c, 0x85, 0x73, 0x1a, 0x5c, 0xfc, 0x22, + 0x74, 0xa7, 0xb4, 0xd8, 0x39, 0x18, 0x4b, 0x97, + 0x01, 0xe8, 0xc1, 0x3f, 0xa2, 0x07, 0xf5, 0x80, + 0x0f, 0xf4, 0x13, 0x35, 0x02, 0xad, 0x7d, 0x20, + 0xc0, 0x1c, 0x14, 0xfa, 0x32, 0xef, 0x41, 0xc3, + 0x56, 0x19, 0x23, 0x21, 0x62, 0xe7, 0xf2, 0x02, + 0xeb, 0x4d, 0x83, 0x8a, 0x41, 0xc3, 0x07, 0x30, + 0x73, 0xf4, 0xea, 0x23, 0x40, 0xe0, 0x9d, 0xae, + 0x4a, 0x32, 0x05, 0xc4, 0xe9, 0x2f, 0x5d, 0xae, + 0xc1, 0xc5, 0x34, 0x51, 0x22, 0xad, 0xc0, 0x75, + 0xbc, 0x07, 0x1e, 0xb3, 0x47, 0xb7, 0x54, 0xf8, + 0x39, 0xcd, 0x08, 0x3a, 0x80, 0xea, 0x13, 0xb5, + 0xc1, 0xcb, 0x84, 0xac, 0x9b, 0x29, 0x0a, 0x34, + 0xfa, 0xe4, 0x83, 0x1a, 0x0e, 0x26, 0x90, 0x72, + 0xeb, 0x03, 0xa0, 0xd7, 0x23, 0xa1, 0x92, 0xc0, + 0xb1, 0x39, 0xd1, 0x03, 0x83, 0x32, 0x78, 0x09, + 0xf5, 0x7f, 0x17, 0x37, 0xd5, 0xa2, 0x31, 0xad, + 0xa2, 0xe8, 0x48, 0xa3, 0x3e, 0x6f, 0xec, 0x75, + 0xb6, 0xb3, 0xf2, 0xcb, 0x9a, 0x0e, 0xe0, 0x48, + 0x36, 0x08, 0x23, 0xe4, 0xa9, 0xd8, 0x5b, 0x6b, + 0x1b, 0x38, 0xdf, 0xbb, 0xc4, 0x7d, 0x86, 0x53, + 0x14, 0x44, 0x47, 0xf5, 0xf5, 0xca, 0x32, 0x17, + 0x86, 0x63, 0x43, 0x09, 0xeb, 0x06, 0x93, 0xfa, + 0xde, 0x08, 0xb1, 0x0c, 0x5a, 0xf4, 0x26, 0x1b, + 0xab, 0x12, 0xd5, 0x6e, 0xd2, 0xcc, 0x56, 0xc3, + 0x1f, 0xa6, 0xcd, 0x10, 0x18, 0x1e, 0x25, 0x65, + 0xb6, 0xf7, 0x7d, 0x1a, 0x56, 0x95, 0x8b, 0x22, + 0xdd, 0x18, 0x74, 0xe1, 0x53, 0xb0, 0x6f, 0xc1, + 0x5e, 0xb9, 0xe1, 0x1e, 0x17, 0x37, 0xe5, 0xbe, + 0x9f, 0x06, 0xf8, 0xb9, 0x49, 0x09, 0x94, 0xf7, + 0xfa, 0x88, 0x40, 0xde, 0x0d, 0xe5, 0xa4, 0xab, + 0x82, 0x4f, 0x48, 0x97, 0x8b, 0x45, 0x17, 0x31, + 0x4c, 0xd2, 0x81, 0x5a, 0x7b, 0x7d, 0x3a, 0xbb, + 0x02, 0x07, 0xfa, 0xf3, 0x1b, 0xcb, 0x56, 0xc5, + 0x0a, 0x62, 0x37, 0x6b, 0xab, 0xff, 0xde, 0x61, + 0x68, 0x1a, 0x6e, 0xf6, 0xc2, 0xb5, 0x91, 0x20, + 0x07, 0x05, 0x6a, 0x6e, 0x6e, 0xd8, 0xa3, 0x9c, + 0x80, 0x3c, 0x4e, 0x8c, 0xc6, 0x96, 0xef, 0x73, + 0x35, 0x08, 0x26, 0x2a, 0xdb, 0x0c, 0x2f, 0xdb, + 0x3d, 0xb3, 0x94, 0xf9, 0x72, 0xe4, 0x25, 0xca, + 0x41, 0xa6, 0x66, 0x83, 0x51, 0xfe, 0xf0, 0xb3, + 0xd7, 0x0a, 0x40, 0x77, 0x02, 0x7a, 0xa2, 0x18, + 0x43, 0x66, 0x22, 0xcb, 0x3a, 0x1c, 0x40, 0x70, + 0x26, 0xa7, 0x02, 0x09, 0x7d, 0x46, 0xd2, 0xab, + 0x41, 0x83, 0x41, 0x79, 0x1a, 0x30, 0x0f, 0xab, + 0x06, 0x0e, 0x18, 0xa0, 0xc0, 0x48, 0x23, 0xf2, + 0x06, 0xd0, 0x64, 0xfd, 0xfe, 0x5c, 0xd7, 0xed, + 0x2b, 0x53, 0xbb, 0x79, 0x0c, 0x49, 0x71, 0x70, + 0x37, 0x34, 0x7b, 0x77, 0xab, 0xa3, 0x80, 0xa6, + 0x89, 0xd7, 0x07, 0x8a, 0x80, 0x24, 0x2d, 0x4f, + 0x3c, 0xba, 0xe7, 0x4a, 0x35, 0x22, 0x4d, 0x4f, + 0x8b, 0xef, 0x10, 0x87, 0xda, 0xdc, 0xe2, 0x00, + 0x21, 0x5f, 0xdb, 0xb4, 0xdc, 0x19, 0xba, 0x11, + 0x26, 0x9d, 0x53, 0x50, 0x41, 0xad, 0x73, 0x50, + 0x85, 0x2f, 0x77, 0x50, 0x65, 0xa3, 0x20, 0x71, + 0x35, 0x71, 0x2e, 0xad, 0x8d, 0x6c, 0x17, 0x06, + 0x67, 0xaa, 0xdc, 0x5d, 0x6a, 0x6d, 0x49, 0xdd, + 0x7f, 0x32, 0xae, 0x8e, 0x04, 0x95, 0xb2, 0x71, + 0x7e, 0x2d, 0x0e, 0xc1, 0x70, 0x7f, 0x35, 0x7f, + 0x60, 0x73, 0x06, 0x11, 0xf0, 0xa8, 0x7d, 0xb2, + 0x87, 0xbf, 0x6d, 0x07, 0xa4, 0x0d, 0x0f, 0x99, + 0xc5, 0x3c, 0xe0, 0x66, 0x0e, 0x9d, 0x3f, 0xa6, + 0xae, 0xa7, 0x6b, 0x16, 0x47, 0x43, 0x87, 0x3e, + 0x17, 0xb6, 0x36, 0x68, 0x71, 0x00, 0x8b, 0x37, + 0x83, 0x08, 0x8c, 0x29, 0x2c, 0xd2, 0x46, 0x98, + 0x1b, 0x2a, 0xe1, 0x2c, 0x46, 0x31, 0xe0, 0x5b, + 0x1c, 0x86, 0xb0, 0x67, 0xd1, 0x7b, 0xe5, 0xe1, + 0xa0, 0xa3, 0x5d, 0x04, 0xc3, 0xe1, 0xeb, 0x50, + 0x15, 0xbf, 0xfc, 0x8b, 0x66, 0x4a, 0x85, 0x47, + 0x69, 0x16, 0x62, 0x2a, 0xff, 0xff, 0x7c, 0xa1, + 0x49, 0x5d, 0xde, 0x44, 0x60, 0xe2, 0x0b, 0xba, + 0x1a, 0xf2, 0x11, 0x56, 0x36, 0x85, 0x03, 0xe2, + 0x9f, 0xe4, 0x24, 0x14, 0xeb, 0xdd, 0xd6, 0x2b, + 0x5c, 0x9b, 0x9c, 0x85, 0x72, 0xae, 0x86, 0x74, + 0x89, 0x74, 0xfb, 0x6a, 0x0b, 0xee, 0xa3, 0x18, + 0xae, 0x47, 0x1c, 0xb0, 0xa6, 0x93, 0x44, 0xcb, + 0xd2, 0x51, 0x33, 0xf5, 0x4a, 0x90, 0x58, 0xba, + 0xa6, 0x50, 0x48, 0x60, 0xb1, 0x95, 0x4a, 0xc7, + 0x3c, 0xd6, 0x99, 0x9f, 0x51, 0xec, 0x61, 0x42, + 0xc8, 0x3b, 0xf6, 0xda, 0xc4, 0x4b, 0x53, 0x4b, + 0x1c, 0x44, 0x3f, 0x69, 0x2e, 0x79, 0xb6, 0xb6, + 0x55, 0xa7, 0x62, 0x9c, 0xd5, 0x14, 0xd5, 0xad, + 0x7f, 0x72, 0x89, 0xa0, 0x0c, 0xa2, 0xea, 0xc2, + 0x80, 0xd8, 0x3e, 0x11, 0xc4, 0x94, 0x9e, 0x1c, + 0x31, 0x18, 0x51, 0xde, 0xf0, 0x70, 0x7e, 0xee, + 0x16, 0x95, 0xa9, 0x2b, 0x0a, 0xa2, 0xeb, 0x25, + 0xa5, 0x55, 0x11, 0xb1, 0x49, 0xa6, 0xba, 0x4a, + 0x48, 0x1c, 0x00, 0xf0, 0xa0, 0x88, 0xf5, 0xbc, + 0xc9, 0x6f, 0x70, 0x3d, 0x93, 0xa7, 0x91, 0xd6, + 0x3d, 0x03, 0x8f, 0xfe, 0x8b, 0xd6, 0x05, 0xc1, + 0x76, 0x96, 0x6e, 0x83, 0xce, 0xff, 0xfb, 0xc3, + 0xda, 0xf0, 0xa1, 0x65, 0x97, 0xa2, 0x8b, 0xbf, + 0xa5, 0x10, 0x89, 0x02, 0xce, 0x23, 0x2d, 0xb2, + 0x55, 0x0e, 0x4f, 0x53, 0x78, 0xdf, 0xf7, 0x3d, + 0xab, 0x14, 0xbf, 0xc8, 0x0a, 0xe8, 0xfd, 0x79, + 0xb0, 0xa4, 0xa4, 0x1c, 0x41, 0x13, 0x64, 0x46, + 0x28, 0x4c, 0xb3, 0x24, 0x02, 0xba, 0x58, 0x50, + 0x14, 0xa7, 0x67, 0x35, 0x7e, 0xf2, 0xa2, 0x7b, + 0xb6, 0x0c, 0x33, 0xa8, 0x4e, 0xeb, 0xee, 0x74, + 0xb6, 0x03, 0xb8, 0x0b, 0x01, 0x71, 0x0d, 0x65, + 0x91, 0x7a, 0x0e, 0x05, 0x8f, 0x68, 0x48, 0x96, + 0x31, 0xb0, 0x39, 0xcc, 0xd4, 0x41, 0x4c, 0xec, + 0xfa, 0x22, 0xbc, 0xb5, 0x09, 0x07, 0x36, 0x77, + 0x8b, 0xe0, 0xaf, 0x5f, 0x58, 0xb1, 0xb9, 0x49, + 0x4d, 0x3b, 0xca, 0x87, 0xb6, 0x70, 0x92, 0x82, + 0xf1, 0xe5, 0xe8, 0xdb, 0x7b, 0x65, 0x2c, 0xd8, + 0xf1, 0x84, 0x08, 0x7f, 0x67, 0xf0, 0x40, 0x69, + 0x24, 0xd4, 0x6b, 0x53, 0x7c, 0x74, 0x9d, 0xe8, + 0x88, 0x2b, 0xab, 0xba, 0x49, 0xc4, 0x34, 0x55, + 0x81, 0x60, 0x0b, 0xb3, 0xc2, 0x30, 0x22, 0xa9, + 0xee, 0x82, 0x2b, 0x3a, 0x0b, 0x00, 0x5c, 0x6c, + 0x95, 0x04, 0xe5, 0xef, 0x46, 0x22, 0x74, 0x98, + 0x52, 0x2a, 0xd7, 0x6f, 0x68, 0x11, 0x85, 0x29, + 0xfd, 0xbd, 0x28, 0xc8, 0x4f, 0xb6, 0xde, 0x41, + 0x13, 0x17, 0x46, 0x46, 0xca, 0x3e, 0x69, 0xd5, + 0x3f, 0xde, 0x02, 0x69, 0x86, 0x47, 0xe3, 0xe6, + 0x03, 0xb6, 0x7d, 0x00, 0x9f, 0x68, 0xc1, 0x1b, + 0xd4, 0xd2, 0xf5, 0x7b, 0x2d, 0x6d, 0xb6, 0x74, + 0x09, 0xff, 0x46, 0x5c, 0x87, 0x15, 0x53, 0xd4, + 0x1a, 0x30, 0xe0, 0x60, 0x31, 0x0a, 0xf5, 0x03, + 0x38, 0x49, 0x0e, 0x6b, 0x9d, 0x12, 0x62, 0xaf, + 0xe1, 0x57, 0xd2, 0xb0, 0xb5, 0x86, 0x0f, 0x36, + 0x3b, 0x4c, 0xda, 0xcd, 0x46, 0x1b, 0xef, 0x0b, + 0x46, 0x07, 0xf6, 0x23, 0x41, 0x42, 0x69, 0xcb, + 0x91, 0x07, 0xaf, 0x78, 0xb9, 0x21, 0x20, 0x9c, + 0xb5, 0x00, 0x4c, 0x13, 0x35, 0xcf, 0x17, 0x08, + 0x62, 0x5e, 0xb6, 0x05, 0xb3, 0xd9, 0x28, 0x78, + 0x0c, 0x2f, 0x21, 0x32, 0x21, 0x30, 0xad, 0x4c, + 0xb6, 0xa5, 0x56, 0xda, 0xdc, 0x46, 0x4d, 0x3a, + 0xa6, 0x2d, 0xcb, 0x94, 0x16, 0x26, 0xc1, 0x75, + 0x0b, 0x8a, 0x6f, 0xf4, 0xaa, 0x0d, 0x9d, 0xae, + 0xb8, 0xf8, 0x78, 0x3c, 0x5d, 0x4f, 0xd5, 0x35, + 0x3a, 0x57, 0xd2, 0x97, 0xce, 0x79, 0x80, 0x24, + 0x0e, 0xed, 0x3e, 0x58, 0x39, 0x90, 0x16, 0x00, + 0x9d, 0x45, 0x74, 0x65, 0xc0, 0x1c, 0x48, 0x43, + 0xc4, 0x7d, 0xe6, 0xf4, 0x9b, 0x5e, 0x61, 0x6a, + 0xeb, 0x74, 0xd2, 0xc0, 0x9a, 0x9b, 0x3b, 0xb3, + 0x0d, 0x5b, 0xc0, 0x5d, 0x65, 0xba, 0x4a, 0x32, + 0x19, 0x02, 0xea, 0x7b, 0x21, 0xbb, 0x1f, 0x8c, + 0xce, 0x77, 0x0a, 0x25, 0x8b, 0x83, 0x81, 0x73, + 0x41, 0xf7, 0xa1, 0xb1, 0x9b, 0xfe, 0x4f, 0xc1, + 0x17, 0x51, 0x9b, 0xe1, 0x28, 0x2d, 0xa2, 0x4a, + 0x4b, 0x4d, 0xbc, 0xad, 0x33, 0x4a, 0x27, 0x10, + 0xd2, 0x50, 0x1c, 0xb1, 0x36, 0x50, 0x48, 0x65, + 0x35, 0xf8, 0x88, 0x28, 0x6b, 0x82, 0xc0, 0x1c, + 0x80, 0xa0, 0xfd, 0x5d, 0x17, 0x78, 0x13, 0xeb, + 0xcb, 0x5d, 0x85, 0x08, 0x51, 0x92, 0xf4, 0x1c, + 0xf4, 0xa4, 0xe2, 0x35, 0x9f, 0x08, 0xa9, 0xa4, + 0x08, 0x05, 0x32, 0x6d, 0x16, 0xf1, 0x7b, 0xc1, + 0x92, 0xc7, 0xd7, 0x8b, 0x2c, 0x27, 0xdf, 0x4e, + 0x9a, 0xe6, 0x54, 0x40, 0xe4, 0x21, 0x5a, 0xf9, + 0xc6, 0x24, 0xef, 0x65, 0x07, 0x2e, 0x2b, 0x4d, + 0x4f, 0x2a, 0x09, 0x6c, 0xe8, 0xc7, 0x88, 0x05, + 0xc7, 0x50, 0xb2, 0xde, 0xa2, 0xa1, 0x80, 0x64, + 0x0b, 0xb3, 0x36, 0xcd, 0x26, 0xde, 0x98, 0x8a, + 0xe4, 0x84, 0x17, 0x54, 0x2c, 0x54, 0x0e, 0x18, + 0x38, 0xa6, 0xb5, 0x0a, 0x46, 0x41, 0x2f, 0x1c, + 0x74, 0x80, 0xee, 0xf1, 0x7e, 0x74, 0x29, 0x8b, + 0xd4, 0xdd, 0xb5, 0x64, 0x74, 0x17, 0xcf, 0xcf, + 0xd8, 0x32, 0x34, 0xf9, 0xfc, 0x58, 0x64, 0xb5, + 0x44, 0x0e, 0x34, 0x41, 0x17, 0x15, 0xeb, 0xe0, + 0xa3, 0x49, 0x08, 0x3f, 0xe8, 0xc8, 0x8d, 0x5e, + 0xde, 0xa2, 0xb5, 0x00, 0x3a, 0x05, 0x78, 0xca, + 0x0a, 0xf5, 0xe5, 0x09, 0xb0, 0x5f, 0xea, 0x33, + 0x73, 0xce, 0x12, 0xde, 0x89, 0xa2, 0x49, 0x17, + 0x5a, 0x70, 0x07, 0xc1, 0x3b, 0xf5, 0x4c, 0x58, + 0xf6, 0xbe, 0x51, 0x49, 0x0f, 0xee, 0x8c, 0x11, + 0x03, 0x85, 0x5a, 0x29, 0x35, 0xd3, 0x44, 0x4c, + 0x63, 0x24, 0x0c, 0xc5, 0x2b, 0x2d, 0x9c, 0x46, + 0x50, 0x28, 0xd3, 0x88, 0xc4, 0x34, 0xbb, 0xb0, + 0x81, 0x41, 0x3d, 0xcf, 0x22, 0x58, 0x63, 0x43, + 0x13, 0xd3, 0x70, 0x64, 0x28, 0xc6, 0xcb, 0x90, + 0x6b, 0x9d, 0xd8, 0x38, 0x74, 0xfe, 0xf8, 0xa5, + 0x18, 0x0f, 0x08, 0xa3, 0x76, 0x8c, 0xa0, 0xbc, + 0x85, 0xc8, 0x2f, 0x0a, 0x16, 0x41, 0xc8, 0x3a, + 0x02, 0xe7, 0x5e, 0x03, 0xd2, 0x49, 0xde, 0x53, + 0x5c, 0x5c, 0x85, 0xf0, 0xa5, 0x69, 0x10, 0xf4, + 0x28, 0x65, 0x48, 0x38, 0x52, 0x11, 0x7b, 0x78, + 0x8b, 0x9d, 0x07, 0x04, 0x53, 0x3b, 0xd4, 0x75, + 0x41, 0xdd, 0x7c, 0xb1, 0xb4, 0x43, 0x21, 0x33, + 0xa0, 0xfd, 0xf0, 0x01, 0xee, 0x5e, 0x23, 0xd0, + 0x1e, 0x4c, 0xef, 0x05, 0xe2, 0xe1, 0x47, 0x8b, + 0x21, 0x84, 0x1a, 0x7b, 0xa8, 0x14, 0x03, 0x8e, + 0xb1, 0x5c, 0xf4, 0x92, 0x42, 0x55, 0x86, 0x92, + 0x69, 0x69, 0x42, 0x5b, 0x6a, 0xf1, 0x01, 0x20, + 0x4b, 0xa7, 0x0b, 0x03, 0x82, 0x36, 0x8b, 0xa8, + 0x0d, 0x10, 0xe1, 0x88, 0x38, 0x62, 0x2e, 0x13, + 0xe0, 0x7a, 0x48, 0x00, 0xc6, 0xb3, 0xbd, 0xe8, + 0x49, 0xaf, 0xb8, 0xed, 0x3b, 0x10, 0xa2, 0x15, + 0x4a, 0xd4, 0x30, 0x7e, 0x9c, 0xe9, 0xb0, 0x58, + 0x92, 0x04, 0x8d, 0x2a, 0xc8, 0xcf, 0xe9, 0xcc, + 0x8b, 0xa3, 0x0c, 0x89, 0xf5, 0x9c, 0xe5, 0xc5, + 0x08, 0xca, 0xd4, 0x95, 0x15, 0x21, 0xe2, 0xc8, + 0xc6, 0x93, 0xc2, 0x40, 0x70, 0x62, 0xf7, 0x20, + 0x39, 0x60, 0xaa, 0x5a, 0x48, 0x2e, 0x22, 0xd3, + 0x47, 0x26, 0x2c, 0xb8, 0xc8, 0x88, 0xaf, 0x11, + 0xf0, 0x32, 0x07, 0x02, 0x6c, 0xf1, 0x0f, 0x38, + 0x84, 0x1d, 0x5d, 0x96, 0x07, 0x70, 0x1c, 0x2b, + 0xb9, 0xc2, 0x50, 0x9b, 0x4e, 0x45, 0xe3, 0x25, + 0x8f, 0xee, 0x14, 0x72, 0x2c, 0x68, 0x29, 0x80, + 0x46, 0x58, 0xa1, 0x11, 0x20, 0x38, 0x9b, 0x70, + 0x90, 0x1c, 0x2e, 0x0c, 0x84, 0xcc, 0x7e, 0x27, + 0x2a, 0x16, 0x07, 0x0a, 0x1a, 0x88, 0x0f, 0x41, + 0xff, 0xf8, 0x61, 0x44, 0xd8, 0x60, 0x18, 0x85, + 0x53, 0x03, 0x20, 0x73, 0xa2, 0x07, 0x6b, 0xee, + 0x92, 0xc7, 0x4f, 0x0d, 0xf6, 0xf0, 0x17, 0x1a, + 0x59, 0xde, 0x9b, 0x28, 0x07, 0x04, 0xda, 0xca, + 0x2b, 0x6a, 0x37, 0x58, 0x6b, 0xaf, 0x83, 0x13, + 0x60, 0xe7, 0x6e, 0xc4, 0x48, 0x21, 0x0e, 0x58, + 0x92, 0x83, 0x82, 0x78, 0x8b, 0x23, 0x58, 0xd9, + 0x0d, 0x24, 0x7d, 0xb9, 0x2c, 0x07, 0x2c, 0x0e, + 0x42, 0x09, 0x98, 0xb0, 0xd8, 0x4d, 0x23, 0x10, + 0x70, 0xa7, 0x73, 0x86, 0xc6, 0x0b, 0x04, 0x9f, + 0xfb, 0x56, 0x29, 0x07, 0x23, 0x8f, 0x98, 0x0e, + 0x8f, 0x63, 0x0a, 0x50, 0x76, 0x29, 0x28, 0x26, + 0x3c, 0x5f, 0x02, 0xfb, 0x51, 0x9b, 0xb0, 0x61, + 0xc0, 0x70, 0xbc, 0x17, 0x29, 0xc0, 0xcc, 0x1d, + 0x08, 0x62, 0xca, 0x72, 0xf0, 0xa4, 0xfd, 0x5d, + 0x2c, 0x58, 0xd5, 0x5c, 0x1c, 0x2a, 0x4e, 0xf7, + 0x0a, 0x01, 0xfa, 0xff, 0xff, 0xd5, 0x09, 0xa8, + 0x8c, 0x1c, 0x30, 0x25, 0x09, 0xd3, 0xd9, 0x30, + 0xd3, 0xdb, 0x94, 0x13, 0x74, 0xc8, 0x71, 0x1a, + 0x21, 0x87, 0x43, 0x10, 0x89, 0x5a, 0x6b, 0x91, + 0xd5, 0x66, 0xa0, 0xb0, 0x1c, 0x30, 0x58, 0x64, + 0x15, 0xfe, 0x36, 0x04, 0x7b, 0x4d, 0x23, 0x07, + 0x3a, 0xf1, 0x0a, 0xc2, 0x7d, 0x3b, 0xa1, 0x91, + 0xa4, 0x62, 0x96, 0xb1, 0xae, 0x83, 0xf6, 0xc0, + 0x07, 0xae, 0x6c, 0x11, 0x45, 0xf4, 0x1c, 0x35, + 0x6a, 0x28, 0x39, 0x60, 0x71, 0x1b, 0xf4, 0x39, + 0x44, 0x41, 0xae, 0xf1, 0x07, 0x01, 0xd4, 0x89, + 0xf6, 0x94, 0x1f, 0x7d, 0xab, 0x1b, 0x20, 0xdb, + 0x22, 0x1e, 0xa2, 0x07, 0x09, 0x8b, 0xe3, 0xf4, + 0xda, 0x82, 0x8c, 0x25, 0x01, 0xc0, 0xe2, 0x36, + 0x59, 0xa0, 0xe2, 0x42, 0x82, 0x64, 0x78, 0xb0, + 0x66, 0x0e, 0x59, 0xdd, 0x63, 0x65, 0x0b, 0x02, + 0x6a, 0x8c, 0xc2, 0xad, 0x7a, 0x90, 0xa3, 0xa0, + 0xbd, 0xda, 0x53, 0xd9, 0xd5, 0x82, 0x4f, 0x2c, + 0x37, 0xd8, 0x50, 0x8c, 0xa0, 0x2a, 0x70, 0x5e, + 0x47, 0x4a, 0xa9, 0x28, 0xaf, 0x4f, 0x58, 0x88, + 0x31, 0x29, 0x19, 0x76, 0x8c, 0xc8, 0xbf, 0x0d, + 0xc1, 0x56, 0xe7, 0x0a, 0x05, 0xe5, 0x20, 0xe8, + 0xe6, 0xb0, 0x3b, 0xb7, 0xa0, 0xe1, 0x80, 0xaa, + 0xa0, 0x23, 0xd7, 0x74, 0xd5, 0x01, 0xfc, 0x19, + 0x85, 0x13, 0x01, 0xc1, 0x91, 0x1b, 0xec, 0x28, + 0x80, 0xb1, 0xe2, 0xc7, 0x6a, 0x74, 0x07, 0x2c, + 0x31, 0x15, 0xd8, 0xbd, 0xb7, 0x82, 0xe2, 0x1d, + 0x3c, 0xa2, 0x83, 0x97, 0x09, 0x3a, 0xc0, 0xb1, + 0x34, 0x50, 0x0b, 0x87, 0x6c, 0xc8, 0xa7, 0x6e, + 0x64, 0x37, 0xb7, 0x91, 0x1f, 0x09, 0x0a, 0x38, + 0x34, 0x8c, 0x97, 0x80, 0xe5, 0x8d, 0x94, 0x0a, + 0xd6, 0xe9, 0x24, 0x18, 0xae, 0x34, 0xd7, 0xd2, + 0x94, 0x20, 0x36, 0x34, 0x7c, 0x29, 0xe9, 0xb0, + 0x71, 0x3e, 0xe2, 0x08, 0x69, 0xde, 0x14, 0x8b, + 0xca, 0x01, 0x32, 0x67, 0x64, 0x43, 0x85, 0x07, + 0xf4, 0xdf, 0x04, 0xdb, 0x88, 0x38, 0xb0, 0xbc, + 0x32, 0x44, 0x14, 0x4f, 0x10, 0xa8, 0x34, 0x89, + 0x10, 0x38, 0x28, 0x7c, 0xe2, 0x0a, 0x0e, 0x17, + 0x04, 0xae, 0xfd, 0x78, 0x5d, 0x12, 0xdc, 0xde, + 0x73, 0x9c, 0x17, 0x85, 0x2f, 0x79, 0xc5, 0xbb, + 0x2c, 0x21, 0x6b, 0x92, 0x14, 0x92, 0x9f, 0x9e, + 0x0c, 0xd6, 0x20, 0x99, 0x28, 0xae, 0x27, 0x22, + 0x6d, 0xd9, 0xc4, 0x41, 0x99, 0xfd, 0x71, 0x42, + 0x25, 0x8a, 0x41, 0xd2, 0x1c, 0x60, 0xe3, 0xfa, + 0x14, 0x70, 0xa4, 0x8a, 0xaf, 0xa5, 0xd1, 0x90, + 0x26, 0x42, 0x2e, 0x53, 0x42, 0xe8, 0x0e, 0x0a, + 0x37, 0x27, 0x69, 0x29, 0x21, 0x41, 0x3c, 0xf6, + 0xf2, 0x21, 0xe5, 0x07, 0x48, 0x7a, 0x49, 0xd0, + 0x5c, 0xe9, 0xc9, 0x25, 0x0c, 0xa7, 0x02, 0xa9, + 0x9d, 0x17, 0x8c, 0x85, 0xdd, 0x05, 0xf6, 0x83, + 0x31, 0x8f, 0x41, 0xc2, 0xa8, 0x46, 0x0e, 0xa0, + 0xe0, 0x5f, 0x3c, 0x19, 0xd1, 0x4e, 0x9e, 0x40, + 0x89, 0x60, 0x5e, 0xcf, 0x60, 0x38, 0x07, 0xd4, + 0x20, 0xba, 0x7c, 0x28, 0xe8, 0x38, 0x62, 0xe9, + 0x25, 0xe1, 0xa1, 0x90, 0x38, 0x9a, 0xac, 0x45, + 0xaf, 0xa5, 0x8b, 0x21, 0xea, 0x23, 0x60, 0xe7, + 0x68, 0x8c, 0xa3, 0x81, 0x4c, 0xc3, 0x74, 0xd7, + 0x03, 0x22, 0x3e, 0xb8, 0xb8, 0x26, 0x64, 0x24, + 0xa4, 0xa7, 0xb4, 0xe6, 0x14, 0x12, 0x05, 0x52, + 0x0f, 0x45, 0x00, 0x19, 0xfc, 0x0e, 0x0a, 0x34, + 0x19, 0x03, 0x81, 0x7f, 0x8d, 0x34, 0xf7, 0x02, + 0x39, 0x8b, 0x8b, 0x90, 0x04, 0x52, 0x14, 0xb8, + 0xb8, 0x2c, 0x42, 0x58, 0x0b, 0x98, 0x9e, 0x51, + 0xc0, 0xc5, 0x68, 0x11, 0xe8, 0x03, 0x81, 0xc0, + 0xbf, 0x66, 0x81, 0xd5, 0xd2, 0xb9, 0x41, 0x27, + 0x02, 0x63, 0x11, 0xa3, 0x3f, 0x57, 0x9e, 0x73, + 0xbc, 0xb1, 0x09, 0x4f, 0x08, 0x37, 0x30, 0x94, + 0xe6, 0x93, 0x8b, 0xa3, 0x36, 0x6e, 0x00, 0xe1, + 0xae, 0xa8, 0x91, 0x83, 0x8d, 0x12, 0x85, 0x4a, + 0x8a, 0x1b, 0x27, 0xd3, 0xd3, 0x88, 0xc3, 0x07, + 0xcc, 0x80, 0xe0, 0x5c, 0xcc, 0xea, 0xc1, 0x90, + 0x2c, 0x5d, 0x3c, 0xa0, 0xe0, 0x9e, 0xad, 0x62, + 0x37, 0xc5, 0xe2, 0xa1, 0x40, 0x84, 0x2b, 0x82, + 0xb0, 0x5d, 0x3e, 0x73, 0xbd, 0x07, 0x0b, 0xc2, + 0x77, 0x16, 0x25, 0x17, 0x70, 0xd8, 0x38, 0x69, + 0x08, 0xb4, 0xcb, 0x0e, 0x05, 0x14, 0x38, 0x27, + 0x48, 0xaa, 0xa1, 0x85, 0x10, 0x07, 0xa3, 0x3d, + 0x54, 0x66, 0x18, 0x03, 0x8f, 0x1b, 0x3a, 0x4a, + 0x27, 0xd7, 0xbb, 0x01, 0xd0, 0xfe, 0xea, 0xf3, + 0xa6, 0xf8, 0x43, 0x86, 0x10, 0x1c, 0x76, 0x86, + 0x34, 0x62, 0x4a, 0x0b, 0xc4, 0xb9, 0xd3, 0x4e, + 0xd7, 0xf9, 0xa0, 0xb1, 0x24, 0x14, 0x50, 0xcf, + 0x86, 0x81, 0x3d, 0xe5, 0x42, 0xb7, 0x68, 0x2e, + 0xf4, 0x92, 0x14, 0x44, 0x63, 0x2e, 0x1d, 0x7e, + 0xaf, 0x42, 0x6d, 0x7f, 0x64, 0x29, 0x0a, 0xb5, + 0xec, 0x40, 0x0e, 0x04, 0xef, 0xbd, 0xe7, 0x56, + 0x40, 0x0b, 0x0a, 0x79, 0x8c, 0x7b, 0xc0, 0xa7, + 0x3d, 0xaf, 0x94, 0xde, 0x21, 0x45, 0xc0, 0xc0, + 0x17, 0x33, 0x31, 0x0a, 0xcb, 0x92, 0x03, 0x8f, + 0xb5, 0xd0, 0xf7, 0x9d, 0x3b, 0x56, 0x61, 0x21, + 0x25, 0x19, 0x82, 0xee, 0xf3, 0x92, 0xa3, 0x76, + 0xbd, 0xe7, 0xf6, 0x76, 0xf6, 0xe4, 0xc0, 0x29, + 0x81, 0xb5, 0xd0, 0x70, 0xad, 0xff, 0x3c, 0xba, + 0xd3, 0x6d, 0x96, 0xf5, 0x10, 0x2f, 0xe3, 0xb3, + 0x05, 0xc4, 0x53, 0xdb, 0x61, 0x20, 0x3a, 0x9f, + 0x9d, 0x35, 0xca, 0x4f, 0xa6, 0xe2, 0x90, 0x72, + 0xdd, 0x09, 0x21, 0x70, 0x7e, 0xe8, 0x00, 0xf2, + 0xe0, 0x3d, 0x60, 0x1d, 0x42, 0x5d, 0x20, 0x6d, + 0x82, 0xb6, 0xea, 0xe8, 0x04, 0xda, 0xfa, 0x48, + 0x8b, 0xb0, 0x96, 0xa0, 0x07, 0x2c, 0x4f, 0xed, + 0xbc, 0x5b, 0xa0, 0xe9, 0x05, 0x0f, 0x3a, 0x4a, + 0x82, 0x0a, 0xfe, 0x62, 0x13, 0xb1, 0x79, 0xde, + 0x8b, 0x88, 0x34, 0xe5, 0x1a, 0x01, 0x70, 0x57, + 0x2b, 0x82, 0xc3, 0x91, 0x72, 0x1a, 0xad, 0x62, + 0x0e, 0x83, 0x89, 0x57, 0x81, 0x27, 0x50, 0x2f, + 0x07, 0x3f, 0x07, 0x23, 0x3f, 0x17, 0xfc, 0xc4, + 0x1d, 0xda, 0x18, 0x11, 0x3b, 0x6f, 0x50, 0x62, + 0xc2, 0xf4, 0x40, 0x9d, 0xbc, 0x52, 0x88, 0x5c, + 0x2b, 0x77, 0x28, 0x6e, 0xb9, 0x20, 0x2e, 0xad, + 0x42, 0x68, 0x9f, 0x5e, 0x64, 0xbd, 0x36, 0x53, + 0x0a, 0x4a, 0x46, 0x8d, 0x64, 0x2b, 0x22, 0x3b, + 0xa6, 0xf5, 0x06, 0x76, 0x12, 0x89, 0xba, 0xc3, + 0x24, 0x23, 0x10, 0xc0, 0x87, 0x92, 0xf0, 0xe6, + 0xbe, 0x2b, 0x88, 0x6d, 0x34, 0x18, 0x1f, 0x95, + 0x89, 0x01, 0x7b, 0xed, 0x07, 0x20, 0x0c, 0x44, + 0xdb, 0x69, 0xae, 0x12, 0x20, 0x20, 0x8b, 0x40, + 0x9e, 0x2c, 0x4f, 0x10, 0x9b, 0x5c, 0x24, 0x79, + 0x78, 0x85, 0x12, 0x31, 0x98, 0x56, 0xf6, 0xde, + 0xa2, 0xb4, 0x66, 0x43, 0x54, 0xa9, 0x76, 0xbc, + 0xf0, 0x1c, 0x45, 0xba, 0x1a, 0x21, 0x28, 0x07, + 0x3f, 0x81, 0x1e, 0x83, 0x06, 0x5d, 0x0c, 0x89, + 0xa7, 0x94, 0x93, 0x80, 0xbd, 0xe9, 0xa0, 0xc3, + 0xa0, 0x3c, 0xee, 0x9c, 0xf2, 0x12, 0x03, 0x85, + 0x4f, 0x80, 0xea, 0x7a, 0xa2, 0xc8, 0x10, 0xae, + 0x8c, 0x82, 0x46, 0x28, 0xc1, 0xc2, 0xf0, 0x77, + 0x48, 0x69, 0xae, 0x48, 0x2b, 0xab, 0xe4, 0x0b, + 0x5e, 0xa3, 0x91, 0x61, 0x5e, 0x5c, 0xda, 0x34, + 0x44, 0xbd, 0xa4, 0x0d, 0x7e, 0x50, 0x73, 0xba, + 0xf4, 0x1f, 0xbf, 0xff, 0xff, 0x6a, 0x20, 0xa6, + 0x27, 0xf9, 0xc0, 0x7a, 0x0f, 0xff, 0xcf, 0xf5, + 0xd1, 0xae, 0x15, 0x65, 0x28, 0x90, 0x84, 0xd3, + 0x0a, 0x2f, 0x06, 0x00, 0xe2, 0x3f, 0x83, 0x4d, + 0x3f, 0x10, 0xac, 0x52, 0x0e, 0x3b, 0x81, 0xd1, + 0x7e, 0x06, 0x01, 0x14, 0x82, 0x3a, 0x04, 0x02, + 0xe4, 0x76, 0x1e, 0xe0, 0xe0, 0x5d, 0x52, 0x95, + 0xdd, 0xa7, 0xb8, 0x0b, 0x14, 0x00, 0xe0, 0xc8, + 0xeb, 0x58, 0xd8, 0xc4, 0x30, 0x21, 0xe0, 0xf4, + 0x30, 0x01, 0x84, 0xf4, 0x31, 0x18, 0x02, 0x7a, + 0x94, 0x2c, 0x15, 0xc4, 0xda, 0xc4, 0x78, 0x62, + 0x32, 0x8b, 0x42, 0x45, 0x81, 0xc5, 0x24, 0x71, + 0x01, 0x74, 0xe0, 0xc8, 0x90, 0x1c, 0x6c, 0x94, + 0x4d, 0x48, 0xb4, 0xf4, 0x37, 0x0d, 0x03, 0x89, + 0x0f, 0x38, 0x67, 0x60, 0x3f, 0xbc, 0x00, 0x6c, + 0x5e, 0x0e, 0x41, 0x4d, 0x85, 0x76, 0x02, 0xef, + 0x5e, 0x41, 0xcb, 0xd0, 0x70, 0x64, 0x85, 0x62, + 0x79, 0xd1, 0x80, 0xb8, 0x1c, 0x27, 0x70, 0x1f, + 0xdf, 0xff, 0xf7, 0x20, 0xa3, 0x25, 0x22, 0xd3, + 0x8b, 0x9e, 0x02, 0x1e, 0x5c, 0x1c, 0x11, 0xae, + 0xa3, 0x3a, 0xb7, 0xb2, 0x8b, 0xab, 0xe0, 0xb1, + 0x12, 0xf0, 0x1c, 0x2e, 0x0a, 0x12, 0xbc, 0x95, + 0x0f, 0x6a, 0x09, 0x2f, 0x45, 0xeb, 0x40, 0x1c, + 0x43, 0xcd, 0x59, 0x0b, 0xe2, 0x6a, 0x5f, 0x43, + 0x4a, 0x09, 0x54, 0xd3, 0x62, 0x9f, 0x65, 0x88, + 0x94, 0x8c, 0xaa, 0xc2, 0xfa, 0xfe, 0x55, 0x2c, + 0xe7, 0x82, 0xad, 0x6d, 0x41, 0xcc, 0x19, 0x22, + 0xe0, 0xa7, 0x31, 0x53, 0x91, 0x03, 0xf5, 0x17, + 0xfe, 0x2e, 0x29, 0x26, 0x4c, 0xb1, 0xb9, 0x2f, + 0x5b, 0x80, 0x8c, 0xb8, 0x61, 0x41, 0x77, 0x41, + 0xef, 0x11, 0xd4, 0x06, 0x86, 0x24, 0x5e, 0x44, + 0x2b, 0x8c, 0xd1, 0x14, 0x93, 0x32, 0xfc, 0x5b, + 0x51, 0x0a, 0xb4, 0xe5, 0x64, 0x3c, 0xb4, 0xd8, + 0x39, 0x18, 0x51, 0x48, 0x41, 0xcb, 0x70, 0x9f, + 0x70, 0x32, 0x40, 0x15, 0x4a, 0x88, 0x0e, 0x46, + 0x19, 0x84, 0x70, 0xd2, 0xe7, 0xf5, 0xe7, 0x81, + 0xaa, 0xe7, 0xdf, 0xe8, 0x69, 0x25, 0x36, 0x48, + 0x0e, 0x42, 0x14, 0x4d, 0xa6, 0xf2, 0x92, 0xac, + 0x49, 0xd2, 0x66, 0x85, 0x01, 0x28, 0xb8, 0x13, + 0x19, 0x6b, 0x78, 0x2e, 0x7e, 0xbf, 0xf8, 0x13, + 0xee, 0x50, 0x71, 0xcf, 0x20, 0x7f, 0x20, 0x30, + 0x2c, 0x34, 0x13, 0x5b, 0xb2, 0x31, 0x8a, 0xe2, + 0xf7, 0x34, 0x83, 0x31, 0xa6, 0xbe, 0x99, 0x56, + 0x1b, 0x6b, 0xb4, 0xa8, 0xf9, 0xca, 0x31, 0x1a, + 0x39, 0x50, 0x2c, 0x0e, 0x90, 0x1c, 0x73, 0xdc, + 0x9d, 0x5d, 0x6e, 0x22, 0xa6, 0x90, 0x9e, 0x5a, + 0xb2, 0x0e, 0x13, 0x45, 0xe7, 0xb3, 0xa0, 0xc4, + 0xcf, 0xbd, 0x43, 0x4d, 0x83, 0x06, 0x50, 0xe5, + 0x81, 0x6e, 0x00, 0xee, 0x00, 0xe8, 0xe9, 0xb8, + 0x52, 0x41, 0xec, 0x1b, 0x51, 0x75, 0x80, 0x99, + 0x57, 0xd1, 0x75, 0xd0, 0x94, 0x12, 0x0b, 0x89, + 0xfc, 0x17, 0x44, 0x25, 0x20, 0xb9, 0x53, 0x79, + 0x67, 0x3b, 0xf5, 0x22, 0x26, 0x69, 0x25, 0x42, + 0xe5, 0x71, 0x9c, 0xa1, 0xd0, 0x31, 0x5f, 0x6c, + 0x9b, 0x56, 0x35, 0x41, 0x71, 0x0b, 0x64, 0xe0, + 0x8a, 0x2b, 0xd3, 0xd7, 0x41, 0x63, 0x00, 0x79, + 0xdd, 0xd9, 0x2a, 0xe8, 0x51, 0x10, 0x40, 0x22, + 0x7d, 0x0b, 0x3b, 0xe2, 0x45, 0xe8, 0xbf, 0x54, + 0xf4, 0x60, 0xb0, 0xa5, 0x29, 0xe5, 0x11, 0x0d, + 0x29, 0xab, 0xde, 0xa2, 0x45, 0x20, 0x2f, 0xea, + 0xc8, 0xfa, 0x2e, 0x7e, 0x9c, 0x95, 0x12, 0x84, + 0xae, 0x23, 0x07, 0x09, 0x93, 0x24, 0x09, 0x38, + 0x3b, 0x86, 0x81, 0x35, 0x84, 0xda, 0xfb, 0x92, + 0x2f, 0x10, 0x83, 0x82, 0x2e, 0xba, 0x10, 0xc8, + 0xa4, 0x22, 0xdd, 0x07, 0x0d, 0x1f, 0x0d, 0xd9, + 0xd0, 0x4d, 0xd7, 0x21, 0xd7, 0x98, 0x03, 0x81, + 0x60, 0x7d, 0xd5, 0xe7, 0x21, 0x42, 0xe7, 0xe6, + 0xa0, 0xab, 0x83, 0x82, 0x7d, 0xc8, 0x32, 0xe5, + 0x07, 0x3e, 0x14, 0x9d, 0xd3, 0xf3, 0xa4, 0xa3, + 0x10, 0xca, 0x83, 0x8e, 0xa6, 0xb1, 0x4a, 0xc4, + 0xed, 0x74, 0x7d, 0x07, 0x02, 0xeb, 0xc3, 0x17, + 0x9c, 0xa8, 0xc2, 0x4a, 0x9f, 0x5c, 0x5c, 0x69, + 0x01, 0x36, 0x9d, 0xa4, 0xa0, 0xf3, 0xff, 0xff, + 0xa0, 0x39, 0x32, 0x52, 0x45, 0x91, 0x2f, 0xc0, + 0x9f, 0x06, 0x60, 0xe2, 0x5a, 0x77, 0x0a, 0x3f, + 0x89, 0x24, 0x28, 0x5c, 0x22, 0xac, 0xc5, 0xf8, + 0xb7, 0x6c, 0x40, 0x33, 0x7d, 0x58, 0x89, 0x72, + 0x69, 0xea, 0xc0, 0xe1, 0x91, 0x1f, 0x57, 0xd9, + 0x99, 0x27, 0x17, 0x47, 0x7a, 0x88, 0x26, 0xdb, + 0xa6, 0xe5, 0xe4, 0x01, 0xe2, 0xa9, 0x0c, 0x05, + 0x3b, 0x90, 0xda, 0x3e, 0x2c, 0x2b, 0x7e, 0x77, + 0xa4, 0x7a, 0x73, 0xc8, 0x1c, 0x59, 0x0a, 0x41, + 0x3f, 0x16, 0x61, 0x47, 0x01, 0xc4, 0xb3, 0x80, + 0xba, 0xd3, 0x4d, 0x86, 0x21, 0x80, 0x52, 0xfa, + 0x48, 0x8d, 0x10, 0xc4, 0x17, 0xd2, 0xf5, 0x14, + 0x0a, 0xe2, 0x7d, 0x46, 0x54, 0x4b, 0x0c, 0x0d, + 0x05, 0x58, 0xb0, 0x95, 0x4f, 0x50, 0x83, 0x91, + 0x05, 0x39, 0x10, 0x39, 0x10, 0x38, 0x8f, 0x1b, + 0xbc, 0x85, 0x01, 0x88, 0xd3, 0xb4, 0x13, 0xb5, + 0xe5, 0x74, 0x4b, 0x03, 0x91, 0x10, 0x31, 0x8c, + 0x0a, 0x25, 0x72, 0x5b, 0x06, 0x70, 0x9e, 0x51, + 0x53, 0x55, 0x19, 0x28, 0x38, 0xa0, 0x8f, 0x83, + 0x64, 0x21, 0x5e, 0xbb, 0x19, 0xcd, 0x18, 0x06, + 0x20, 0xe3, 0xf3, 0x16, 0xe8, 0x38, 0x22, 0xd0, + 0x12, 0x62, 0xac, 0x6c, 0x1d, 0x11, 0x9d, 0xbd, + 0x28, 0x84, 0xfa, 0xfa, 0x95, 0x77, 0xa0, 0x3a, + 0x86, 0x48, 0xa9, 0xa0, 0x8e, 0x2c, 0x50, 0x8f, + 0xbc, 0x01, 0xc0, 0xb0, 0x05, 0xcc, 0xd5, 0x90, + 0x41, 0x70, 0x4e, 0x9a, 0xeb, 0x22, 0x07, 0x14, + 0x82, 0xeb, 0xe0, 0x9f, 0x4e, 0x2c, 0x07, 0xea, + 0x80, 0x0d, 0x12, 0xc2, 0x81, 0x98, 0x38, 0x56, + 0x99, 0x60, 0x38, 0x27, 0xa5, 0x00, 0xf3, 0xff, + 0xff, 0x91, 0x99, 0x54, 0x8c, 0x4d, 0x9f, 0xab, + 0xdd, 0x51, 0x57, 0x5c, 0x90, 0x60, 0xb1, 0xef, + 0xca, 0x2b, 0xc0, 0xe2, 0x2a, 0x58, 0x94, 0xf1, + 0x4a, 0x22, 0xc8, 0x5d, 0xdf, 0x50, 0x49, 0x46, + 0x68, 0xc6, 0x51, 0xd1, 0x7b, 0x03, 0x00, 0x4d, + 0xa5, 0x14, 0x1d, 0x51, 0x05, 0x4f, 0x8b, 0x76, + 0x86, 0x6b, 0x03, 0x81, 0x3b, 0xd3, 0xb5, 0x1a, + 0xa7, 0xb6, 0xce, 0x20, 0x9c, 0x5e, 0x2c, 0x6c, + 0x86, 0x79, 0xc3, 0x64, 0x9d, 0x3f, 0xb8, 0x6c, + 0x1c, 0x42, 0xd6, 0x5a, 0x76, 0x0a, 0x2a, 0x32, + 0x3d, 0x77, 0x79, 0xc4, 0x16, 0x12, 0xd0, 0xa7, + 0x41, 0x80, 0xaf, 0x76, 0x20, 0xec, 0x07, 0x05, + 0x1f, 0x11, 0x85, 0x1c, 0xa8, 0x02, 0x8d, 0x7c, + 0x0e, 0x21, 0x75, 0x4f, 0x60, 0x3a, 0xa2, 0x27, + 0x9d, 0x06, 0x0c, 0x8d, 0x0a, 0xd9, 0x22, 0xf5, + 0x4d, 0x07, 0x50, 0x4c, 0xed, 0xe2, 0x30, 0xcc, + 0x07, 0xbb, 0x4f, 0x0c, 0xd1, 0x14, 0x83, 0x83, + 0x3e, 0x0d, 0x67, 0x94, 0x62, 0x0e, 0x17, 0xf5, + 0x00, 0xd1, 0xf0, 0x1c, 0xfd, 0x62, 0x04, 0x24, + 0x18, 0x51, 0x53, 0xfc, 0x28, 0x07, 0x0d, 0x77, + 0x03, 0x31, 0x5e, 0x51, 0xc8, 0x0e, 0x0a, 0xda, + 0xd5, 0x0f, 0x16, 0x58, 0x1d, 0xc0, 0x71, 0xc6, + 0x8b, 0x22, 0xc4, 0x66, 0xc2, 0x3d, 0x77, 0x6c, + 0xd2, 0x47, 0x65, 0x15, 0x0f, 0x41, 0xc3, 0x31, + 0x3f, 0xec, 0x36, 0x0b, 0xc7, 0x3b, 0x57, 0x44, + 0x52, 0x6e, 0x8a, 0xa7, 0x37, 0x95, 0x6a, 0x09, + 0x95, 0x37, 0xc4, 0x3c, 0x81, 0x98, 0x3a, 0x04, + 0x9f, 0x8b, 0x1a, 0x19, 0x83, 0x83, 0x11, 0x35, + 0x03, 0x90, 0x50, 0x72, 0x12, 0x39, 0xb0, 0xdf, + 0x41, 0xc4, 0x71, 0x4a, 0x12, 0x6d, 0x3e, 0x58, + 0xb8, 0xc9, 0x08, 0x2c, 0x20, 0x38, 0xf7, 0x58, + 0xd7, 0x41, 0xc1, 0x3d, 0x70, 0x33, 0x05, 0xd4, + 0xa8, 0x58, 0x1c, 0x18, 0xc8, 0x14, 0x77, 0xa2, + 0xa8, 0xbf, 0xcb, 0x51, 0x83, 0x8e, 0xc5, 0x29, + 0x5c, 0x17, 0x9e, 0xa0, 0x25, 0x44, 0x28, 0x9a, + 0x2f, 0xa8, 0x43, 0x0a, 0x7a, 0xd8, 0x8f, 0xb6, + 0x82, 0x66, 0x9f, 0x5e, 0x0c, 0x0d, 0x03, 0x97, + 0x42, 0x8c, 0xf4, 0xf0, 0xda, 0x21, 0x3e, 0x47, + 0xc3, 0x64, 0xcc, 0x66, 0x0e, 0x1a, 0x51, 0x5d, + 0x5d, 0x3b, 0x8a, 0x0a, 0x0a, 0x62, 0x3e, 0x72, + 0x3d, 0xdf, 0x83, 0x90, 0xa0, 0x05, 0xf7, 0xde, + 0x45, 0xb8, 0x33, 0xe2, 0xc0, 0xb0, 0x19, 0x91, + 0x3c, 0xef, 0x43, 0x75, 0xa2, 0x33, 0x6b, 0xf0, + 0x33, 0x7e, 0x56, 0x28, 0xd3, 0xab, 0xd4, 0x52, + 0x90, 0xfe, 0x21, 0x40, 0x52, 0xe8, 0x9e, 0xe7, + 0x22, 0x00, 0xd5, 0x4d, 0x06, 0x09, 0xe7, 0x90, + 0x16, 0x3c, 0xe1, 0x42, 0x10, 0xc0, 0x69, 0x10, + 0x71, 0xd1, 0x3d, 0x27, 0x79, 0x08, 0xda, 0x81, + 0x9a, 0x30, 0x72, 0x30, 0x4d, 0x72, 0x2e, 0x83, + 0x9c, 0x07, 0x06, 0x42, 0xbd, 0xcb, 0xd2, 0x2e, + 0x74, 0x51, 0xa7, 0xd4, 0x53, 0x70, 0x63, 0xc0, + 0x70, 0x49, 0xb9, 0x06, 0x66, 0xd0, 0x02, 0xc4, + 0x17, 0x9b, 0x84, 0x88, 0xc3, 0x30, 0x70, 0x55, + 0xb8, 0x0e, 0x5c, 0x1c, 0x32, 0x09, 0x90, 0xe5, + 0x5e, 0x6d, 0x01, 0xc4, 0x7d, 0x0a, 0xfd, 0x46, + 0x48, 0x48, 0xb3, 0xb7, 0x06, 0x4b, 0x8c, 0x10, + 0x03, 0x9f, 0xba, 0x2e, 0x46, 0x19, 0xbe, 0xf5, + 0x1a, 0xc7, 0xb4, 0xe0, 0x65, 0x02, 0x7c, 0x30, + 0x0c, 0x4d, 0x8a, 0x5f, 0x0d, 0x45, 0xca, 0x28, + 0x4b, 0x2b, 0x03, 0xa0, 0x30, 0x2c, 0x42, 0x5c, + 0xe6, 0x9e, 0x28, 0x82, 0xe0, 0x5c, 0xbe, 0xa3, + 0x96, 0x06, 0x61, 0x2c, 0x40, 0x1d, 0xd2, 0x17, + 0xc5, 0xc1, 0xc3, 0x5e, 0xce, 0x1a, 0xe0, 0xaf, + 0x4f, 0x0c, 0xba, 0x19, 0x06, 0x40, 0x3c, 0x6b, + 0xe7, 0x57, 0x58, 0xd4, 0x07, 0x1b, 0x14, 0x27, + 0xce, 0x92, 0xc2, 0x94, 0x60, 0xbe, 0x60, 0xe0, + 0x9f, 0x44, 0x85, 0xfa, 0xf8, 0xd8, 0x64, 0xa3, + 0x80, 0x39, 0x10, 0x55, 0xed, 0x18, 0x9b, 0x0b, + 0x32, 0x20, 0x58, 0x02, 0xe7, 0x1b, 0x21, 0xbd, + 0x9d, 0xe9, 0x50, 0x26, 0xe9, 0xba, 0x1f, 0xa2, + 0xee, 0x14, 0x2e, 0x03, 0xc8, 0xdd, 0x10, 0x4d, + 0x66, 0x8c, 0xe9, 0x48, 0x2e, 0x51, 0xe0, 0x26, + 0xa9, 0xc6, 0x43, 0x9c, 0x92, 0x20, 0x04, 0xd2, + 0xd7, 0x43, 0x27, 0x01, 0x7d, 0xa7, 0x65, 0x7c, + 0x0e, 0xb0, 0x11, 0xc2, 0x5b, 0xbf, 0x51, 0x57, + 0xc0, 0x46, 0xb1, 0x71, 0x97, 0x5d, 0x62, 0x06, + 0x68, 0xdf, 0xba, 0x6c, 0xad, 0x18, 0xc8, 0xe4, + 0x28, 0xcc, 0x1b, 0x7b, 0x85, 0x10, 0x31, 0x3f, + 0x41, 0xc8, 0x88, 0xb4, 0xde, 0x7f, 0x7e, 0x0c, + 0x05, 0x3e, 0xb9, 0xb5, 0x10, 0x6b, 0x2a, 0x1b, + 0xe7, 0x54, 0xe6, 0x12, 0x8d, 0xe8, 0x38, 0x62, + 0x7b, 0xd2, 0x45, 0xe8, 0x51, 0xf8, 0x8d, 0x71, + 0x78, 0x38, 0x62, 0x13, 0xb2, 0xfd, 0x09, 0x62, + 0x6c, 0x0d, 0x60, 0x32, 0x1f, 0xb7, 0xfa, 0x53, + 0xc8, 0x50, 0xb7, 0x06, 0x92, 0xa3, 0x32, 0xad, + 0x38, 0x0e, 0x28, 0x3d, 0x27, 0x9f, 0x20, 0x63, + 0xd7, 0xcb, 0xd4, 0x72, 0xf0, 0x90, 0x83, 0x5f, + 0x5d, 0x18, 0x92, 0xa3, 0x0d, 0xd7, 0x3d, 0xaa, + 0x91, 0x95, 0xe9, 0x48, 0xd1, 0xf4, 0x1f, 0xc2, + 0x00, 0x3f, 0x6c, 0x44, 0xba, 0x00, 0x70, 0x72, + 0x7e, 0x70, 0x57, 0x53, 0x64, 0x92, 0x0c, 0xcd, + 0x92, 0x02, 0xeb, 0xae, 0x50, 0x2a, 0xca, 0x0a, + 0x45, 0xc0, 0x3c, 0x1c, 0xee, 0x18, 0x03, 0x90, + 0x84, 0x54, 0x35, 0xe8, 0x49, 0xa7, 0x35, 0x12, + 0x00, 0x1c, 0x2e, 0x07, 0x3b, 0x49, 0x01, 0xdd, + 0x19, 0x83, 0x90, 0x89, 0xa7, 0x85, 0x05, 0x01, + 0x1b, 0x17, 0x14, 0x03, 0xb8, 0x0b, 0xe6, 0xc2, + 0x9e, 0x94, 0x9c, 0xd3, 0xa0, 0x70, 0x66, 0x43, + 0x3c, 0x07, 0x05, 0x49, 0x74, 0xd5, 0xe0, 0xc0, + 0x07, 0xae, 0xea, 0x5f, 0xa6, 0xc1, 0xc3, 0x05, + 0x85, 0xc2, 0xb8, 0xa4, 0x90, 0x2b, 0x89, 0xb8, + 0x0e, 0x42, 0x12, 0x34, 0x46, 0x81, 0xc4, 0xa2, + 0x96, 0xb8, 0x64, 0x6e, 0x02, 0xe7, 0xa3, 0x40, + 0x32, 0x07, 0x40, 0x5c, 0x3d, 0xed, 0x5f, 0xa1, + 0x55, 0x4b, 0xf9, 0x60, 0x70, 0xa2, 0x11, 0xf4, + 0x32, 0x73, 0xe5, 0x29, 0x0c, 0x01, 0xc5, 0x03, + 0x5b, 0x57, 0x20, 0x89, 0xd8, 0x39, 0x00, 0x39, + 0x71, 0x80, 0xd1, 0x8c, 0x49, 0x3a, 0x09, 0xf0, + 0xa2, 0x23, 0x07, 0x02, 0xfa, 0x54, 0x78, 0x94, + 0x31, 0x13, 0xac, 0x2a, 0x15, 0xd5, 0xe1, 0x17, + 0x51, 0x03, 0xa5, 0x3b, 0xa1, 0x2a, 0x37, 0xed, + 0xd2, 0xa2, 0x52, 0x42, 0x8a, 0xb1, 0xa2, 0x83, + 0xb2, 0xa4, 0xa2, 0x4a, 0x50, 0x8f, 0xa1, 0x80, + 0x55, 0x29, 0xd8, 0x9e, 0x50, 0x87, 0xa7, 0x31, + 0x50, 0x3b, 0x92, 0x0c, 0x0f, 0xf1, 0x99, 0x48, + 0x38, 0x07, 0x22, 0x24, 0x3f, 0xc1, 0xcb, 0x83, + 0x81, 0x60, 0x35, 0xc1, 0x75, 0x13, 0xf1, 0x74, + 0x43, 0x12, 0x51, 0x98, 0x47, 0x84, 0x52, 0x81, + 0x82, 0xc0, 0xe1, 0xac, 0x74, 0x16, 0x04, 0xa1, + 0x81, 0xe6, 0x04, 0x83, 0x20, 0x89, 0xd6, 0x42, + 0x7f, 0x4d, 0xd1, 0x81, 0x48, 0xa1, 0x46, 0x3f, + 0x8c, 0xc5, 0x33, 0x9b, 0xe4, 0x1b, 0x9d, 0x5c, + 0x63, 0x90, 0x1c, 0x83, 0xae, 0xc8, 0x51, 0x06, + 0x50, 0x32, 0xa0, 0xbf, 0x2d, 0xc0, 0x71, 0x20, + 0x38, 0x5c, 0x4a, 0xef, 0xa7, 0xb4, 0xd0, 0xb8, + 0x4b, 0x45, 0xc2, 0xf0, 0x4e, 0x65, 0x21, 0x3f, + 0x34, 0x8c, 0x1c, 0x4a, 0x0e, 0xeb, 0xe4, 0xa0, + 0x1d, 0x46, 0x01, 0x5c, 0xe8, 0x9f, 0x5f, 0x14, + 0xa2, 0x37, 0x49, 0x44, 0xcf, 0x9c, 0x18, 0x92, + 0xa3, 0x07, 0x09, 0xe6, 0x1b, 0x09, 0x2b, 0x83, + 0x10, 0x4c, 0xe2, 0x35, 0x9d, 0x13, 0x92, 0x80, + 0x70, 0x66, 0x35, 0x6b, 0x77, 0x84, 0x6c, 0x64, + 0xb9, 0xa5, 0x96, 0x13, 0xee, 0x0c, 0x41, 0xc8, + 0xfa, 0x13, 0xb5, 0x9d, 0x25, 0x0a, 0x75, 0xde, + 0x50, 0x70, 0x2f, 0xa7, 0x56, 0x37, 0x61, 0xb2, + 0x42, 0x40, 0xae, 0x68, 0xcc, 0xa5, 0x07, 0x42, + 0x4d, 0x0d, 0xad, 0xca, 0x0b, 0xd5, 0xa3, 0x21, + 0x36, 0x9e, 0x8a, 0x22, 0xfd, 0x05, 0x88, 0x38, + 0x82, 0x4a, 0x28, 0xc1, 0x6e, 0x92, 0xad, 0x43, + 0x17, 0x4a, 0x34, 0x60, 0xfe, 0x10, 0x01, 0xe3, + 0x75, 0x6e, 0x03, 0x82, 0x4b, 0xdc, 0xa2, 0xbd, + 0x77, 0x28, 0x3b, 0xab, 0x77, 0x85, 0x21, 0x3c, + 0xc1, 0x9b, 0x9c, 0xb6, 0x76, 0xdb, 0x67, 0x78, + 0xb6, 0x5e, 0x21, 0x92, 0xde, 0x11, 0x4a, 0x20, + 0x74, 0x08, 0xa4, 0xa1, 0xb8, 0xd3, 0x5e, 0x68, + 0xd6, 0x57, 0x85, 0x01, 0x89, 0x0c, 0x5e, 0xa0, + 0x07, 0x1a, 0x07, 0x09, 0xf7, 0x11, 0x02, 0xeb, + 0x07, 0x1e, 0xd3, 0x46, 0xad, 0x11, 0x94, 0x74, + 0x1d, 0xd7, 0x29, 0xc3, 0x62, 0xf7, 0x24, 0x1f, + 0x7c, 0x18, 0x38, 0xf8, 0x30, 0xc2, 0x86, 0x12, + 0x03, 0x9f, 0xea, 0x66, 0xc1, 0x83, 0x86, 0xc6, + 0x5e, 0xa0, 0x39, 0xce, 0x51, 0x44, 0xda, 0xf8, + 0x5f, 0x01, 0xc3, 0x4f, 0x61, 0xb5, 0xe8, 0x62, + 0x8c, 0xa0, 0x17, 0x57, 0x75, 0x0f, 0x36, 0xf1, + 0x65, 0xc8, 0x1c, 0x02, 0x53, 0xab, 0xd0, 0x58, + 0xba, 0xf6, 0x44, 0x00, 0x9d, 0xaf, 0x48, 0x22, + 0x38, 0x85, 0x09, 0x48, 0x45, 0xe5, 0x28, 0x1a, + 0xfb, 0x20, 0x6f, 0x38, 0x32, 0x14, 0x54, 0xb4, + 0x63, 0xd0, 0x70, 0xd6, 0x82, 0xef, 0x5d, 0xd1, + 0x9f, 0x56, 0x3d, 0xc6, 0x1c, 0xe2, 0x11, 0x5b, + 0x46, 0x6a, 0xfd, 0x6e, 0x04, 0xad, 0x62, 0x8c, + 0x07, 0x00, 0xe2, 0x32, 0xf8, 0x1c, 0xf0, 0x51, + 0x57, 0xc0, 0xe0, 0x1c, 0x2a, 0xf1, 0x07, 0x09, + 0xb0, 0xbe, 0x03, 0xb8, 0x09, 0xfd, 0x62, 0x8b, + 0x45, 0xe1, 0x5d, 0x07, 0x2c, 0xb0, 0x4f, 0x17, + 0xf4, 0x95, 0x00, 0x26, 0xc9, 0x4a, 0x18, 0x13, + 0xe2, 0xb4, 0x6b, 0xd0, 0xb1, 0xd4, 0x11, 0x69, + 0x69, 0xc2, 0xc8, 0x75, 0xf2, 0xc0, 0xe4, 0x64, + 0x1d, 0x71, 0x80, 0xb8, 0x4c, 0xc6, 0x36, 0x3b, + 0x64, 0x90, 0x38, 0xb3, 0x56, 0x18, 0x65, 0x08, + 0x8c, 0x46, 0xb9, 0xfa, 0xbf, 0x0c, 0xaa, 0xc1, + 0x26, 0x90, 0x1e, 0x8f, 0xff, 0xf2, 0x36, 0xba, + 0x34, 0x56, 0x54, 0x2b, 0x03, 0x90, 0x9e, 0x9a, + 0x31, 0x44, 0x18, 0x11, 0xfb, 0xc8, 0x13, 0x6b, + 0xe9, 0x61, 0x24, 0xc4, 0x68, 0x85, 0x33, 0x25, + 0x29, 0xa1, 0x15, 0x5d, 0xa4, 0xb2, 0xda, 0x15, + 0x7e, 0x62, 0x35, 0x96, 0x20, 0xf3, 0xa4, 0x51, + 0x79, 0xb0, 0xa5, 0x1f, 0x20, 0xc7, 0x80, 0x9b, + 0xed, 0x24, 0xe2, 0x11, 0xab, 0xe8, 0xcb, 0xa1, + 0x54, 0xcc, 0x44, 0x8b, 0x66, 0x76, 0x3a, 0x62, + 0x20, 0x4f, 0xd7, 0xe2, 0x29, 0xbe, 0x92, 0x93, + 0xb5, 0x90, 0x03, 0xba, 0x27, 0x7d, 0xb0, 0x39, + 0x2b, 0xea, 0x31, 0x9f, 0x02, 0x7f, 0x78, 0x50, + 0x80, 0x30, 0x3f, 0x68, 0x38, 0x90, 0x5e, 0x73, + 0x5f, 0x4e, 0xc5, 0x83, 0x80, 0x58, 0x53, 0x64, + 0x0e, 0xf5, 0x75, 0xea, 0xfd, 0x28, 0x01, 0xc2, + 0x7d, 0x25, 0x24, 0x18, 0x21, 0x26, 0x63, 0x2e, + 0x14, 0x03, 0x89, 0xb0, 0x4b, 0xd7, 0xcb, 0x40, + 0x1c, 0x0e, 0x27, 0xf1, 0x0a, 0x25, 0x08, 0xf8, + 0x0b, 0x00, 0x96, 0x57, 0x24, 0xb4, 0x1c, 0xbb, + 0xf2, 0xc8, 0x90, 0x13, 0xdb, 0xc5, 0xf8, 0x0b, + 0x8d, 0x77, 0x68, 0xc5, 0x12, 0x15, 0xd6, 0x58, + 0x1c, 0x41, 0x0a, 0x24, 0x17, 0x74, 0x99, 0x86, + 0x6e, 0x7b, 0x56, 0x5b, 0x8a, 0x1e, 0xb3, 0xa8, + 0xcf, 0x6b, 0xb5, 0x34, 0x66, 0x18, 0x0c, 0x90, + 0x0c, 0x0f, 0x6e, 0x12, 0x2e, 0x50, 0x30, 0x15, + 0xb8, 0xa5, 0x61, 0xbd, 0xe7, 0x21, 0x0b, 0x51, + 0x94, 0xd4, 0xe7, 0x03, 0x00, 0x75, 0x0a, 0xfb, + 0xce, 0x9c, 0xab, 0xb2, 0x94, 0x48, 0x17, 0x0c, + 0x02, 0x67, 0xc1, 0x91, 0x45, 0xa6, 0xc1, 0x3e, + 0x49, 0x62, 0x34, 0x41, 0x33, 0xb4, 0x67, 0xd1, + 0x5c, 0x9d, 0xe2, 0xe7, 0x62, 0xee, 0x55, 0x08, + 0x81, 0xdc, 0x42, 0x0e, 0x21, 0x85, 0xe4, 0xef, + 0x00, 0x78, 0x39, 0x18, 0x55, 0x2b, 0x92, 0xde, + 0xf4, 0xd1, 0x48, 0x2e, 0x7c, 0x90, 0x91, 0x6e, + 0x83, 0x84, 0xee, 0x4b, 0x16, 0x14, 0x55, 0xf5, + 0x45, 0x10, 0x03, 0x9c, 0xe7, 0x0d, 0xf4, 0x90, + 0x64, 0x0b, 0x17, 0xcd, 0x84, 0x96, 0x4a, 0xbc, + 0x09, 0x37, 0x4a, 0x3a, 0x0f, 0x3d, 0x00, 0x19, + 0x34, 0x74, 0x5f, 0x59, 0x41, 0x18, 0x17, 0x33, + 0x95, 0x75, 0xe7, 0x14, 0x80, 0xee, 0x84, 0xcc, + 0xae, 0x12, 0x80, 0xf2, 0x0d, 0xa4, 0x9d, 0xc9, + 0x00, 0x79, 0x03, 0x3b, 0x5f, 0x5b, 0xc4, 0x3d, + 0x82, 0xf0, 0x71, 0xf9, 0xb3, 0x88, 0xfb, 0xd0, + 0x72, 0x09, 0xd1, 0xa4, 0xe2, 0xc8, 0x33, 0x7a, + 0x8d, 0x00, 0x39, 0x08, 0x2e, 0xb5, 0xc0, 0xd4, + 0xd7, 0x68, 0x38, 0x17, 0x5a, 0x33, 0xfa, 0xf3, + 0x38, 0x83, 0x8b, 0x12, 0x21, 0x39, 0x2b, 0x94, + 0xf5, 0x18, 0x38, 0x33, 0x21, 0x9b, 0x41, 0xf1, + 0xe0, 0x07, 0xd2, 0x52, 0x59, 0x11, 0x92, 0x92, + 0x2f, 0x41, 0xc4, 0x3d, 0x5e, 0x1e, 0xd3, 0x95, + 0xc0, 0x71, 0x0c, 0x7a, 0xc5, 0x38, 0x8c, 0x6e, + 0xed, 0x31, 0xb0, 0xe2, 0x82, 0x35, 0x09, 0x27, + 0x3d, 0xaa, 0x72, 0xdc, 0x43, 0x04, 0x47, 0xc5, + 0xa9, 0xb0, 0x9b, 0x7f +}; diff --git a/src/lwip-1.4.1/apps/shell/shell.c b/src/lwip-1.4.1/apps/shell/shell.c new file mode 100644 index 0000000..d028905 --- /dev/null +++ b/src/lwip-1.4.1/apps/shell/shell.c @@ -0,0 +1,1183 @@ +/* + * Copyright (c) 2001-2003 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#include "shell.h" + +#include "lwip/opt.h" + +#if LWIP_NETCONN + +#include +#include + +#include "lwip/mem.h" +#include "lwip/debug.h" +#include "lwip/def.h" +#include "lwip/api.h" +#include "lwip/stats.h" + +#ifdef WIN32 +#define NEWLINE "\r\n" +#else /* WIN32 */ +#define NEWLINE "\n" +#endif /* WIN32 */ + +/** Define this to 1 if you want to echo back all received characters + * (e.g. so they are displayed on a remote telnet) + */ +#ifndef SHELL_ECHO +#define SHELL_ECHO 0 +#endif + +#define BUFSIZE 1024 +static unsigned char buffer[BUFSIZE]; + +struct command { + struct netconn *conn; + s8_t (* exec)(struct command *); + u8_t nargs; + char *args[10]; +}; + +#undef IP_HDRINCL + +#include +#include +#include + +#define ESUCCESS 0 +#define ESYNTAX -1 +#define ETOOFEW -2 +#define ETOOMANY -3 +#define ECLOSED -4 + +#define NCONNS 10 +static struct netconn *conns[NCONNS]; + +/* help_msg is split into 2 strings to prevent exceeding the C89 maximum length of 509 per string */ +static char help_msg1[] = "Available commands:"NEWLINE"\ +open [IP address] [TCP port]: opens a TCP connection to the specified address."NEWLINE"\ +lstn [TCP port]: sets up a server on the specified port."NEWLINE"\ +acpt [connection #]: waits for an incoming connection request."NEWLINE"\ +send [connection #] [message]: sends a message on a TCP connection."NEWLINE"\ +udpc [local UDP port] [IP address] [remote port]: opens a UDP \"connection\"."NEWLINE"\ +udpl [local UDP port] [IP address] [remote port]: opens a UDP-Lite \"connection\"."NEWLINE""; +static char help_msg2[] = "udpn [local UDP port] [IP address] [remote port]: opens a UDP \"connection\" without checksums."NEWLINE"\ +udpb [local port] [remote port]: opens a UDP broadcast \"connection\"."NEWLINE"\ +usnd [connection #] [message]: sends a message on a UDP connection."NEWLINE"\ +recv [connection #]: recieves data on a TCP or UDP connection."NEWLINE"\ +clos [connection #]: closes a TCP or UDP connection."NEWLINE"\ +stat: prints out lwIP statistics."NEWLINE"\ +quit: quits."NEWLINE""; + +#if LWIP_STATS +static char padding_10spaces[] = " "; + +#define PROTOCOL_STATS (LINK_STATS && ETHARP_STATS && IPFRAG_STATS && IP_STATS && ICMP_STATS && UDP_STATS && TCP_STATS) + +#if PROTOCOL_STATS +static const char* shell_stat_proto_names[] = { +#if LINK_STATS + "LINK ", +#endif +#if ETHARP_STATS + "ETHARP ", +#endif +#if IPFRAG_STATS + "IP_FRAG ", +#endif +#if IP_STATS + "IP ", +#endif +#if ICMP_STATS + "ICMP ", +#endif +#if UDP_STATS + "UDP ", +#endif +#if TCP_STATS + "TCP ", +#endif + "last" +}; + +static struct stats_proto* shell_stat_proto_stats[] = { +#if LINK_STATS + &lwip_stats.link, +#endif +#if ETHARP_STATS + &lwip_stats.etharp, +#endif +#if IPFRAG_STATS + &lwip_stats.ip_frag, +#endif +#if IP_STATS + &lwip_stats.ip, +#endif +#if ICMP_STATS + &lwip_stats.icmp, +#endif +#if UDP_STATS + &lwip_stats.udp, +#endif +#if TCP_STATS + &lwip_stats.tcp, +#endif +}; +const size_t num_protostats = sizeof(shell_stat_proto_stats)/sizeof(struct stats_proto*); + +static const char *stat_msgs_proto[] = { + " * transmitted ", + " * received ", + " forwarded ", + " * dropped ", + " * checksum errors ", + " * length errors ", + " * memory errors ", + " routing errors ", + " protocol errors ", + " option errors ", + " * misc errors ", + " cache hits " +}; +#endif /* PROTOCOL_STATS */ +#endif /* LWIP_STATS */ + +/*-----------------------------------------------------------------------------------*/ +static void +sendstr(const char *str, struct netconn *conn) +{ + netconn_write(conn, (void *)str, strlen(str), NETCONN_NOCOPY); +} +/*-----------------------------------------------------------------------------------*/ +static s8_t +com_open(struct command *com) +{ + ip_addr_t ipaddr; + u16_t port; + int i; + err_t err; + long tmp; + + if (ipaddr_aton(com->args[0], &ipaddr) == -1) { + sendstr(strerror(errno), com->conn); + return ESYNTAX; + } + tmp = strtol(com->args[1], NULL, 10); + if((tmp < 0) || (tmp > 0xffff)) { + sendstr("Invalid port number."NEWLINE, com->conn); + return ESUCCESS; + } + port = (u16_t)tmp; + + /* Find the first unused connection in conns. */ + for(i = 0; i < NCONNS && conns[i] != NULL; i++); + + if (i == NCONNS) { + sendstr("No more connections available, sorry."NEWLINE, com->conn); + return ESUCCESS; + } + + sendstr("Opening connection to ", com->conn); + netconn_write(com->conn, com->args[0], strlen(com->args[0]), NETCONN_COPY); + sendstr(":", com->conn); + netconn_write(com->conn, com->args[1], strlen(com->args[1]), NETCONN_COPY); + sendstr(NEWLINE, com->conn); + + conns[i] = netconn_new(NETCONN_TCP); + if (conns[i] == NULL) { + sendstr("Could not create connection identifier (out of memory)."NEWLINE, com->conn); + return ESUCCESS; + } + err = netconn_connect(conns[i], &ipaddr, port); + if (err != ERR_OK) { + fprintf(stderr, "error %s"NEWLINE, lwip_strerr(err)); + sendstr("Could not connect to remote host: ", com->conn); +#ifdef LWIP_DEBUG + sendstr(lwip_strerr(err), com->conn); +#else + sendstr("(debugging must be turned on for error message to appear)", com->conn); +#endif /* LWIP_DEBUG */ + sendstr(NEWLINE, com->conn); + netconn_delete(conns[i]); + conns[i] = NULL; + return ESUCCESS; + } + + sendstr("Opened connection, connection identifier is ", com->conn); + snprintf((char *)buffer, sizeof(buffer), "%d"NEWLINE, i); + netconn_write(com->conn, buffer, strlen((const char *)buffer), NETCONN_COPY); + + return ESUCCESS; +} +/*-----------------------------------------------------------------------------------*/ +static s8_t +com_lstn(struct command *com) +{ + u16_t port; + int i; + err_t err; + long tmp; + + tmp = strtol(com->args[0], NULL, 10); + if((tmp < 0) || (tmp > 0xffff)) { + sendstr("Invalid port number."NEWLINE, com->conn); + return ESUCCESS; + } + port = (u16_t)tmp; + + /* Find the first unused connection in conns. */ + for(i = 0; i < NCONNS && conns[i] != NULL; i++); + + if (i == NCONNS) { + sendstr("No more connections available, sorry."NEWLINE, com->conn); + return ESUCCESS; + } + + sendstr("Opening a listening connection on port ", com->conn); + netconn_write(com->conn, com->args[0], strlen(com->args[0]), NETCONN_COPY); + sendstr(NEWLINE, com->conn); + + conns[i] = netconn_new(NETCONN_TCP); + if (conns[i] == NULL) { + sendstr("Could not create connection identifier (out of memory)."NEWLINE, com->conn); + return ESUCCESS; + } + + err = netconn_bind(conns[i], IP_ADDR_ANY, port); + if (err != ERR_OK) { + netconn_delete(conns[i]); + conns[i] = NULL; + sendstr("Could not bind: ", com->conn); +#ifdef LWIP_DEBUG + sendstr(lwip_strerr(err), com->conn); +#else + sendstr("(debugging must be turned on for error message to appear)", com->conn); +#endif /* LWIP_DEBUG */ + sendstr(NEWLINE, com->conn); + return ESUCCESS; + } + + err = netconn_listen(conns[i]); + if (err != ERR_OK) { + netconn_delete(conns[i]); + conns[i] = NULL; + sendstr("Could not listen: ", com->conn); +#ifdef LWIP_DEBUG + sendstr(lwip_strerr(err), com->conn); +#else + sendstr("(debugging must be turned on for error message to appear)", com->conn); +#endif /* LWIP_DEBUG */ + sendstr(NEWLINE, com->conn); + return ESUCCESS; + } + + sendstr("Opened connection, connection identifier is ", com->conn); + snprintf((char *)buffer, sizeof(buffer), "%d"NEWLINE, i); + netconn_write(com->conn, buffer, strlen((const char *)buffer), NETCONN_COPY); + + return ESUCCESS; +} +/*-----------------------------------------------------------------------------------*/ +/*-----------------------------------------------------------------------------------*/ +static s8_t +com_clos(struct command *com) +{ + int i; + err_t err; + + i = strtol(com->args[0], NULL, 10); + + if (i > NCONNS) { + sendstr("Connection identifier too high."NEWLINE, com->conn); + return ESUCCESS; + } + if (conns[i] == NULL) { + sendstr("Connection identifier not in use."NEWLINE, com->conn); + return ESUCCESS; + } + + err = netconn_close(conns[i]); + if (err != ERR_OK) { + sendstr("Could not close connection: ", com->conn); +#ifdef LWIP_DEBUG + sendstr(lwip_strerr(err), com->conn); +#else + sendstr("(debugging must be turned on for error message to appear)", com->conn); +#endif /* LWIP_DEBUG */ + sendstr(NEWLINE, com->conn); + return ESUCCESS; + } + + sendstr("Connection closed."NEWLINE, com->conn); + netconn_delete(conns[i]); + conns[i] = NULL; + return ESUCCESS; +} +/*-----------------------------------------------------------------------------------*/ +static s8_t +com_acpt(struct command *com) +{ + int i, j; + err_t err; + + /* Find the first unused connection in conns. */ + for(j = 0; j < NCONNS && conns[j] != NULL; j++); + + if (j == NCONNS) { + sendstr("No more connections available, sorry."NEWLINE, com->conn); + return ESUCCESS; + } + + i = strtol(com->args[0], NULL, 10); + + if (i > NCONNS) { + sendstr("Connection identifier too high."NEWLINE, com->conn); + return ESUCCESS; + } + if (conns[i] == NULL) { + sendstr("Connection identifier not in use."NEWLINE, com->conn); + return ESUCCESS; + } + + err = netconn_accept(conns[i], &conns[j]); + + if (err != ERR_OK) { + sendstr("Could not accept connection: ", com->conn); +#ifdef LWIP_DEBUG + sendstr(lwip_strerr(err), com->conn); +#else + sendstr("(debugging must be turned on for error message to appear)", com->conn); +#endif /* LWIP_DEBUG */ + sendstr(NEWLINE, com->conn); + return ESUCCESS; + } + + sendstr("Accepted connection, connection identifier for new connection is ", com->conn); + snprintf((char *)buffer, sizeof(buffer), "%d"NEWLINE, j); + netconn_write(com->conn, buffer, strlen((const char *)buffer), NETCONN_COPY); + + return ESUCCESS; +} +/*-----------------------------------------------------------------------------------*/ +#if LWIP_STATS +static void +com_stat_write_mem(struct netconn *conn, struct stats_mem *elem, int i) +{ + u16_t len; + char buf[100]; + size_t slen; + +#ifdef LWIP_DEBUG + LWIP_UNUSED_ARG(i); + slen = strlen(elem->name); + netconn_write(conn, elem->name, slen, NETCONN_COPY); +#else /* LWIP_DEBUG */ + len = (u16_t)sprintf(buf, "%d", i); + slen = strlen(buf); + netconn_write(conn, buf, slen, NETCONN_COPY); +#endif /* LWIP_DEBUG */ + if(slen < 10) { + netconn_write(conn, padding_10spaces, 10-slen, NETCONN_COPY); + } + + len = (u16_t)sprintf(buf, " * available %"MEM_SIZE_F NEWLINE, elem->avail); + netconn_write(conn, buf, len, NETCONN_COPY); + len = (u16_t)sprintf(buf, " * used %"MEM_SIZE_F NEWLINE, elem->used); + netconn_write(conn, buf, len, NETCONN_COPY); + len = (u16_t)sprintf(buf, " * high water mark %"MEM_SIZE_F NEWLINE, elem->max); + netconn_write(conn, buf, len, NETCONN_COPY); + len = (u16_t)sprintf(buf, " * errors %"STAT_COUNTER_F NEWLINE, elem->err); + netconn_write(conn, buf, len, NETCONN_COPY); + len = (u16_t)sprintf(buf, " * illegal %"STAT_COUNTER_F NEWLINE, elem->illegal); + netconn_write(conn, buf, len, NETCONN_COPY); +} +static void +com_stat_write_sys(struct netconn *conn, struct stats_syselem *elem, const char *name) +{ + u16_t len; + char buf[100]; + size_t slen = strlen(name); + + netconn_write(conn, name, slen, NETCONN_COPY); + if(slen < 10) { + netconn_write(conn, padding_10spaces, 10-slen, NETCONN_COPY); + } + + len = (u16_t)sprintf(buf, " * used %"STAT_COUNTER_F NEWLINE, elem->used); + netconn_write(conn, buf, len, NETCONN_COPY); + len = (u16_t)sprintf(buf, " * high water mark %"STAT_COUNTER_F NEWLINE, elem->max); + netconn_write(conn, buf, len, NETCONN_COPY); + len = (u16_t)sprintf(buf, " * errors %"STAT_COUNTER_F NEWLINE, elem->err); + netconn_write(conn, buf, len, NETCONN_COPY); +} +static s8_t +com_stat(struct command *com) +{ +#if PROTOCOL_STATS || MEMP_STATS + size_t i; +#endif /* PROTOCOL_STATS || MEMP_STATS */ +#if PROTOCOL_STATS + size_t k; + char buf[100]; + u16_t len; + + /* protocol stats, @todo: add IGMP */ + for(i = 0; i < num_protostats; i++) { + size_t s = sizeof(struct stats_proto)/sizeof(STAT_COUNTER); + STAT_COUNTER *c = &shell_stat_proto_stats[i]->xmit; + LWIP_ASSERT("stats not in sync", s == sizeof(stat_msgs_proto)/sizeof(char*)); + netconn_write(com->conn, shell_stat_proto_names[i], strlen(shell_stat_proto_names[i]), NETCONN_COPY); + for(k = 0; k < s; k++) { + len = (u16_t)sprintf(buf, "%s%"STAT_COUNTER_F NEWLINE, stat_msgs_proto[k], c[k]); + netconn_write(com->conn, buf, len, NETCONN_COPY); + } + } +#endif /* PROTOCOL_STATS */ +#if MEM_STATS + com_stat_write_mem(com->conn, &lwip_stats.mem, -1); +#endif /* MEM_STATS */ +#if MEMP_STATS + for(i = 0; i < MEMP_MAX; i++) { + com_stat_write_mem(com->conn, &lwip_stats.memp[i], -1); + } +#endif /* MEMP_STATS */ +#if SYS_STATS + com_stat_write_sys(com->conn, &lwip_stats.sys.sem, "SEM "); + com_stat_write_sys(com->conn, &lwip_stats.sys.mutex, "MUTEX "); + com_stat_write_sys(com->conn, &lwip_stats.sys.sem, "MBOX "); +#endif /* SYS_STATS */ + + return ESUCCESS; +} +#endif +/*-----------------------------------------------------------------------------------*/ +static s8_t +com_send(struct command *com) +{ + int i; + err_t err; + size_t len; + + i = strtol(com->args[0], NULL, 10); + + if (i > NCONNS) { + sendstr("Connection identifier too high."NEWLINE, com->conn); + return ESUCCESS; + } + + if (conns[i] == NULL) { + sendstr("Connection identifier not in use."NEWLINE, com->conn); + return ESUCCESS; + } + + len = strlen(com->args[1]); + com->args[1][len] = '\r'; + com->args[1][len + 1] = '\n'; + com->args[1][len + 2] = 0; + + err = netconn_write(conns[i], com->args[1], len + 3, NETCONN_COPY); + if (err != ERR_OK) { + sendstr("Could not send data: ", com->conn); +#ifdef LWIP_DEBUG + sendstr(lwip_strerr(err), com->conn); +#else + sendstr("(debugging must be turned on for error message to appear)", com->conn); +#endif /* LWIP_DEBUG */ + sendstr(NEWLINE, com->conn); + return ESUCCESS; + } + + sendstr("Data enqueued for sending."NEWLINE, com->conn); + return ESUCCESS; +} +/*-----------------------------------------------------------------------------------*/ +static s8_t +com_recv(struct command *com) +{ + int i; + err_t err; + struct netbuf *buf; + u16_t len; + + i = strtol(com->args[0], NULL, 10); + + if (i > NCONNS) { + sendstr("Connection identifier too high."NEWLINE, com->conn); + return ESUCCESS; + } + + if (conns[i] == NULL) { + sendstr("Connection identifier not in use."NEWLINE, com->conn); + return ESUCCESS; + } + + err = netconn_recv(conns[i], &buf); + if (err == ERR_OK) { + + netbuf_copy(buf, buffer, BUFSIZE); + len = netbuf_len(buf); + sendstr("Reading from connection:"NEWLINE, com->conn); + netconn_write(com->conn, buffer, len, NETCONN_COPY); + netbuf_delete(buf); + } else { + sendstr("EOF."NEWLINE, com->conn); + } + err = netconn_err(conns[i]); + if (err != ERR_OK) { + sendstr("Could not receive data: ", com->conn); +#ifdef LWIP_DEBUG + sendstr(lwip_strerr(err), com->conn); +#else + sendstr("(debugging must be turned on for error message to appear)", com->conn); +#endif /* LWIP_DEBUG */ + sendstr(NEWLINE, com->conn); + return ESUCCESS; + } + return ESUCCESS; +} +/*-----------------------------------------------------------------------------------*/ +static s8_t +com_udpc(struct command *com) +{ + ip_addr_t ipaddr; + u16_t lport, rport; + int i; + err_t err; + long tmp; + + tmp = strtol(com->args[0], NULL, 10); + if((tmp < 0) || (tmp > 0xffff)) { + sendstr("Invalid port number."NEWLINE, com->conn); + return ESUCCESS; + } + lport = (u16_t)tmp; + if (ipaddr_aton(com->args[1], &ipaddr) == -1) { + sendstr(strerror(errno), com->conn); + return ESYNTAX; + } + tmp = strtol(com->args[2], NULL, 10); + if((tmp < 0) || (tmp > 0xffff)) { + sendstr("Invalid port number."NEWLINE, com->conn); + return ESUCCESS; + } + rport = (u16_t)tmp; + + /* Find the first unused connection in conns. */ + for(i = 0; i < NCONNS && conns[i] != NULL; i++); + + if (i == NCONNS) { + sendstr("No more connections available, sorry."NEWLINE, com->conn); + return ESUCCESS; + } + + sendstr("Setting up UDP connection from port ", com->conn); + netconn_write(com->conn, com->args[0], strlen(com->args[0]), NETCONN_COPY); + sendstr(" to ", com->conn); + netconn_write(com->conn, com->args[1], strlen(com->args[1]), NETCONN_COPY); + sendstr(":", com->conn); + netconn_write(com->conn, com->args[2], strlen(com->args[2]), NETCONN_COPY); + sendstr(NEWLINE, com->conn); + + conns[i] = netconn_new(NETCONN_UDP); + if (conns[i] == NULL) { + sendstr("Could not create connection identifier (out of memory)."NEWLINE, com->conn); + return ESUCCESS; + } + + err = netconn_connect(conns[i], &ipaddr, rport); + if (err != ERR_OK) { + netconn_delete(conns[i]); + conns[i] = NULL; + sendstr("Could not connect to remote host: ", com->conn); +#ifdef LWIP_DEBUG + sendstr(lwip_strerr(err), com->conn); +#else + sendstr("(debugging must be turned on for error message to appear)", com->conn); +#endif /* LWIP_DEBUG */ + sendstr(NEWLINE, com->conn); + return ESUCCESS; + } + + err = netconn_bind(conns[i], IP_ADDR_ANY, lport); + if (err != ERR_OK) { + netconn_delete(conns[i]); + conns[i] = NULL; + sendstr("Could not bind: ", com->conn); +#ifdef LWIP_DEBUG + sendstr(lwip_strerr(err), com->conn); +#else + sendstr("(debugging must be turned on for error message to appear)", com->conn); +#endif /* LWIP_DEBUG */ + sendstr(NEWLINE, com->conn); + return ESUCCESS; + } + + sendstr("Connection set up, connection identifier is ", com->conn); + snprintf((char *)buffer, sizeof(buffer), "%d"NEWLINE, i); + netconn_write(com->conn, buffer, strlen((const char *)buffer), NETCONN_COPY); + + return ESUCCESS; +} +/*-----------------------------------------------------------------------------------*/ +static s8_t +com_udpl(struct command *com) +{ + ip_addr_t ipaddr; + u16_t lport, rport; + int i; + err_t err; + long tmp; + + tmp = strtol(com->args[0], NULL, 10); + if((tmp < 0) || (tmp > 0xffff)) { + sendstr("Invalid port number."NEWLINE, com->conn); + return ESUCCESS; + } + lport = (u16_t)tmp; + if (ipaddr_aton(com->args[1], &ipaddr) == -1) { + sendstr(strerror(errno), com->conn); + return ESYNTAX; + } + tmp = strtol(com->args[2], NULL, 10); + if((tmp < 0) || (tmp > 0xffff)) { + sendstr("Invalid port number."NEWLINE, com->conn); + return ESUCCESS; + } + rport = (u16_t)tmp; + + /* Find the first unused connection in conns. */ + for(i = 0; i < NCONNS && conns[i] != NULL; i++); + + if (i == NCONNS) { + sendstr("No more connections available, sorry."NEWLINE, com->conn); + return ESUCCESS; + } + + sendstr("Setting up UDP-Lite connection from port ", com->conn); + netconn_write(com->conn, com->args[0], strlen(com->args[0]), NETCONN_COPY); + sendstr(" to ", com->conn); + netconn_write(com->conn, com->args[1], strlen(com->args[1]), NETCONN_COPY); + sendstr(":", com->conn); + netconn_write(com->conn, com->args[2], strlen(com->args[2]), NETCONN_COPY); + sendstr(NEWLINE, com->conn); + + conns[i] = netconn_new(NETCONN_UDPLITE); + if (conns[i] == NULL) { + sendstr("Could not create connection identifier (out of memory)."NEWLINE, com->conn); + return ESUCCESS; + } + + err = netconn_connect(conns[i], &ipaddr, rport); + if (err != ERR_OK) { + netconn_delete(conns[i]); + conns[i] = NULL; + sendstr("Could not connect to remote host: ", com->conn); +#ifdef LWIP_DEBUG + sendstr(lwip_strerr(err), com->conn); +#else + sendstr("(debugging must be turned on for error message to appear)", com->conn); +#endif /* LWIP_DEBUG */ + sendstr(NEWLINE, com->conn); + return ESUCCESS; + } + + err = netconn_bind(conns[i], IP_ADDR_ANY, lport); + if (err != ERR_OK) { + netconn_delete(conns[i]); + conns[i] = NULL; + sendstr("Could not bind: ", com->conn); +#ifdef LWIP_DEBUG + sendstr(lwip_strerr(err), com->conn); +#else + sendstr("(debugging must be turned on for error message to appear)", com->conn); +#endif /* LWIP_DEBUG */ + sendstr(NEWLINE, com->conn); + return ESUCCESS; + } + + sendstr("Connection set up, connection identifier is ", com->conn); + snprintf((char *)buffer, sizeof(buffer), "%d"NEWLINE, i); + netconn_write(com->conn, buffer, strlen((const char *)buffer), NETCONN_COPY); + + return ESUCCESS; +} +/*-----------------------------------------------------------------------------------*/ +static s8_t +com_udpn(struct command *com) +{ + ip_addr_t ipaddr; + u16_t lport, rport; + int i; + err_t err; + long tmp; + + tmp = strtol(com->args[0], NULL, 10); + if((tmp < 0) || (tmp > 0xffff)) { + sendstr("Invalid port number."NEWLINE, com->conn); + return ESUCCESS; + } + lport = (u16_t)tmp; + if (ipaddr_aton(com->args[1], &ipaddr) == -1) { + sendstr(strerror(errno), com->conn); + return ESYNTAX; + } + tmp = strtol(com->args[2], NULL, 10); + if((tmp < 0) || (tmp > 0xffff)) { + sendstr("Invalid port number."NEWLINE, com->conn); + return ESUCCESS; + } + rport = (u16_t)tmp; + + /* Find the first unused connection in conns. */ + for(i = 0; i < NCONNS && conns[i] != NULL; i++); + + if (i == NCONNS) { + sendstr("No more connections available, sorry."NEWLINE, com->conn); + return ESUCCESS; + } + + sendstr("Setting up UDP connection without checksums from port ", com->conn); + netconn_write(com->conn, com->args[0], strlen(com->args[0]), NETCONN_COPY); + sendstr(" to ", com->conn); + netconn_write(com->conn, com->args[1], strlen(com->args[1]), NETCONN_COPY); + sendstr(":", com->conn); + netconn_write(com->conn, com->args[2], strlen(com->args[2]), NETCONN_COPY); + sendstr(NEWLINE, com->conn); + + conns[i] = netconn_new(NETCONN_UDPNOCHKSUM); + if (conns[i] == NULL) { + sendstr("Could not create connection identifier (out of memory)."NEWLINE, com->conn); + return ESUCCESS; + } + + err = netconn_connect(conns[i], &ipaddr, rport); + if (err != ERR_OK) { + netconn_delete(conns[i]); + conns[i] = NULL; + sendstr("Could not connect to remote host: ", com->conn); +#ifdef LWIP_DEBUG + sendstr(lwip_strerr(err), com->conn); +#else + sendstr("(debugging must be turned on for error message to appear)", com->conn); +#endif /* LWIP_DEBUG */ + sendstr(NEWLINE, com->conn); + return ESUCCESS; + } + + err = netconn_bind(conns[i], IP_ADDR_ANY, lport); + if (err != ERR_OK) { + netconn_delete(conns[i]); + conns[i] = NULL; + sendstr("Could not bind: ", com->conn); +#ifdef LWIP_DEBUG + sendstr(lwip_strerr(err), com->conn); +#else + sendstr("(debugging must be turned on for error message to appear)", com->conn); +#endif /* LWIP_DEBUG */ + sendstr(NEWLINE, com->conn); + return ESUCCESS; + } + + sendstr("Connection set up, connection identifier is ", com->conn); + snprintf((char *)buffer, sizeof(buffer), "%d"NEWLINE, i); + netconn_write(com->conn, buffer, strlen((const char *)buffer), NETCONN_COPY); + + return ESUCCESS; +} +/*-----------------------------------------------------------------------------------*/ +static s8_t +com_udpb(struct command *com) +{ + ip_addr_t ipaddr; + u16_t lport, rport; + int i; + err_t err; + ip_addr_t bcaddr; + long tmp; + + tmp = strtol(com->args[0], NULL, 10); + if((tmp < 0) || (tmp > 0xffff)) { + sendstr("Invalid port number."NEWLINE, com->conn); + return ESUCCESS; + } + lport = (u16_t)tmp; + if (ipaddr_aton(com->args[1], &ipaddr) == -1) { + sendstr(strerror(errno), com->conn); + return ESYNTAX; + } + tmp = strtol(com->args[2], NULL, 10); + if((tmp < 0) || (tmp > 0xffff)) { + sendstr("Invalid port number."NEWLINE, com->conn); + return ESUCCESS; + } + rport = (u16_t)tmp; + + /* Find the first unused connection in conns. */ + for(i = 0; i < NCONNS && conns[i] != NULL; i++); + + if (i == NCONNS) { + sendstr("No more connections available, sorry."NEWLINE, com->conn); + return ESUCCESS; + } + + sendstr("Setting up UDP broadcast connection from port ", com->conn); + netconn_write(com->conn, com->args[0], strlen(com->args[0]), NETCONN_COPY); + sendstr(" to ", com->conn); + netconn_write(com->conn, com->args[1], strlen(com->args[1]), NETCONN_COPY); + sendstr(NEWLINE, com->conn); + + conns[i] = netconn_new(NETCONN_UDP); + if (conns[i] == NULL) { + sendstr("Could not create connection identifier (out of memory)."NEWLINE, com->conn); + return ESUCCESS; + } + + err = netconn_connect(conns[i], &ipaddr, rport); + if (err != ERR_OK) { + netconn_delete(conns[i]); + conns[i] = NULL; + sendstr("Could not connect to remote host: ", com->conn); +#ifdef LWIP_DEBUG + sendstr(lwip_strerr(err), com->conn); +#else + sendstr("(debugging must be turned on for error message to appear)", com->conn); +#endif /* LWIP_DEBUG */ + sendstr(NEWLINE, com->conn); + return ESUCCESS; + } + + IP4_ADDR(&bcaddr, 255,255,255,255); + err = netconn_bind(conns[i], &bcaddr, lport); + if (err != ERR_OK) { + netconn_delete(conns[i]); + conns[i] = NULL; + sendstr("Could not bind: ", com->conn); +#ifdef LWIP_DEBUG + sendstr(lwip_strerr(err), com->conn); +#else + sendstr("(debugging must be turned on for error message to appear)", com->conn); +#endif /* LWIP_DEBUG */ + sendstr(NEWLINE, com->conn); + return ESUCCESS; + } + + sendstr("Connection set up, connection identifier is ", com->conn); + snprintf((char *)buffer, sizeof(buffer), "%d"NEWLINE, i); + netconn_write(com->conn, buffer, strlen((const char *)buffer), NETCONN_COPY); + + return ESUCCESS; +} +/*-----------------------------------------------------------------------------------*/ +static s8_t +com_usnd(struct command *com) +{ + long i; + err_t err; + struct netbuf *buf; + char *mem; + u16_t len; + size_t tmp; + + i = strtol(com->args[0], NULL, 10); + + if (i > NCONNS) { + sendstr("Connection identifier too high."NEWLINE, com->conn); + return ESUCCESS; + } + + if (conns[i] == NULL) { + sendstr("Connection identifier not in use."NEWLINE, com->conn); + return ESUCCESS; + } + tmp = strlen(com->args[1]) + 1; + if (tmp > 0xffff) { + sendstr("Invalid length."NEWLINE, com->conn); + return ESUCCESS; + } + len = (u16_t)tmp; + + buf = netbuf_new(); + mem = (char *)netbuf_alloc(buf, len); + if (mem == NULL) { + sendstr("Could not allocate memory for sending."NEWLINE, com->conn); + return ESUCCESS; + } + strncpy(mem, com->args[1], len); + err = netconn_send(conns[i], buf); + netbuf_delete(buf); + if (err != ERR_OK) { + sendstr("Could not send data: ", com->conn); +#ifdef LWIP_DEBUG + sendstr(lwip_strerr(err), com->conn); +#else + sendstr("(debugging must be turned on for error message to appear)", com->conn); +#endif /* LWIP_DEBUG */ + sendstr(NEWLINE, com->conn); + return ESUCCESS; + } + + sendstr("Data sent."NEWLINE, com->conn); + return ESUCCESS; +} +/*-----------------------------------------------------------------------------------*/ +static s8_t +com_help(struct command *com) +{ + sendstr(help_msg1, com->conn); + sendstr(help_msg2, com->conn); + return ESUCCESS; +} +/*-----------------------------------------------------------------------------------*/ +static s8_t +parse_command(struct command *com, u32_t len) +{ + u16_t i; + u16_t bufp; + + if (strncmp((const char *)buffer, "open", 4) == 0) { + com->exec = com_open; + com->nargs = 2; + } else if (strncmp((const char *)buffer, "lstn", 4) == 0) { + com->exec = com_lstn; + com->nargs = 1; + } else if (strncmp((const char *)buffer, "acpt", 4) == 0) { + com->exec = com_acpt; + com->nargs = 1; + } else if (strncmp((const char *)buffer, "clos", 4) == 0) { + com->exec = com_clos; + com->nargs = 1; +#if LWIP_STATS + } else if (strncmp((const char *)buffer, "stat", 4) == 0) { + com->exec = com_stat; + com->nargs = 0; +#endif + } else if (strncmp((const char *)buffer, "send", 4) == 0) { + com->exec = com_send; + com->nargs = 2; + } else if (strncmp((const char *)buffer, "recv", 4) == 0) { + com->exec = com_recv; + com->nargs = 1; + } else if (strncmp((const char *)buffer, "udpc", 4) == 0) { + com->exec = com_udpc; + com->nargs = 3; + } else if (strncmp((const char *)buffer, "udpb", 4) == 0) { + com->exec = com_udpb; + com->nargs = 2; + } else if (strncmp((const char *)buffer, "udpl", 4) == 0) { + com->exec = com_udpl; + com->nargs = 3; + } else if (strncmp((const char *)buffer, "udpn", 4) == 0) { + com->exec = com_udpn; + com->nargs = 3; + } else if (strncmp((const char *)buffer, "usnd", 4) == 0) { + com->exec = com_usnd; + com->nargs = 2; + } else if (strncmp((const char *)buffer, "help", 4) == 0) { + com->exec = com_help; + com->nargs = 0; + } else if (strncmp((const char *)buffer, "quit", 4) == 0) { + printf("quit"NEWLINE); + return ECLOSED; + } else { + return ESYNTAX; + } + + if (com->nargs == 0) { + return ESUCCESS; + } + bufp = 0; + for(; bufp < len && buffer[bufp] != ' '; bufp++); + for(i = 0; i < 10; i++) { + for(; bufp < len && buffer[bufp] == ' '; bufp++); + if (buffer[bufp] == '\r' || + buffer[bufp] == '\n') { + buffer[bufp] = 0; + if (i < com->nargs - 1) { + return ETOOFEW; + } + if (i > com->nargs - 1) { + return ETOOMANY; + } + break; + } + if (bufp > len) { + return ETOOFEW; + } + com->args[i] = (char *)&buffer[bufp]; + for(; bufp < len && buffer[bufp] != ' ' && buffer[bufp] != '\r' && + buffer[bufp] != '\n'; bufp++) { + if (buffer[bufp] == '\\') { + buffer[bufp] = ' '; + } + } + if (bufp > len) { + return ESYNTAX; + } + buffer[bufp] = 0; + bufp++; + if (i == com->nargs - 1) { + break; + } + + } + + return ESUCCESS; +} +/*-----------------------------------------------------------------------------------*/ +static void +shell_error(s8_t err, struct netconn *conn) +{ + switch (err) { + case ESYNTAX: + sendstr("## Syntax error"NEWLINE, conn); + break; + case ETOOFEW: + sendstr("## Too few arguments to command given"NEWLINE, conn); + break; + case ETOOMANY: + sendstr("## Too many arguments to command given"NEWLINE, conn); + break; + case ECLOSED: + sendstr("## Connection closed"NEWLINE, conn); + break; + default: + /* unknown error, don't assert here */ + break; + } +} +/*-----------------------------------------------------------------------------------*/ +static void +prompt(struct netconn *conn) +{ + sendstr("> ", conn); +} +/*-----------------------------------------------------------------------------------*/ +static void +shell_main(struct netconn *conn) +{ + struct pbuf *p; + u16_t len = 0, cur_len; + struct command com; + s8_t err; + int i; + err_t ret; +#if SHELL_ECHO + void *echomem; +#endif /* SHELL_ECHO */ + + do { + ret = netconn_recv_tcp_pbuf(conn, &p); + if (ret == ERR_OK) { + pbuf_copy_partial(p, &buffer[len], BUFSIZE - len, 0); + cur_len = p->tot_len; + len += cur_len; +#if SHELL_ECHO + echomem = mem_malloc(cur_len); + if (echomem != NULL) { + pbuf_copy_partial(p, echomem, cur_len, 0); + netconn_write(conn, echomem, cur_len, NETCONN_COPY); + mem_free(echomem); + } +#endif /* SHELL_ECHO */ + pbuf_free(p); + if (((len > 0) && ((buffer[len-1] == '\r') || (buffer[len-1] == '\n'))) || + (len >= BUFSIZE)) { + if (buffer[0] != 0xff && + buffer[1] != 0xfe) { + err = parse_command(&com, len); + if (err == ESUCCESS) { + com.conn = conn; + err = com.exec(&com); + } + if (err == ECLOSED) { + printf("Closed"NEWLINE); + shell_error(err, conn); + goto close; + } + if (err != ESUCCESS) { + shell_error(err, conn); + } + } else { + sendstr(NEWLINE NEWLINE + "lwIP simple interactive shell."NEWLINE + "(c) Copyright 2001, Swedish Institute of Computer Science."NEWLINE + "Written by Adam Dunkels."NEWLINE + "For help, try the \"help\" command."NEWLINE, conn); + } + if (ret == ERR_OK) { + prompt(conn); + } + len = 0; + } + } + } while (ret == ERR_OK); + printf("err %s"NEWLINE, lwip_strerr(ret)); + +close: + netconn_close(conn); + + for(i = 0; i < NCONNS; i++) { + if (conns[i] != NULL) { + netconn_delete(conns[i]); + } + conns[i] = NULL; + } +} +/*-----------------------------------------------------------------------------------*/ +static void +shell_thread(void *arg) +{ + struct netconn *conn, *newconn; + err_t err; + LWIP_UNUSED_ARG(arg); + + conn = netconn_new(NETCONN_TCP); + netconn_bind(conn, NULL, 23); + netconn_listen(conn); + + while (1) { + err = netconn_accept(conn, &newconn); + if (err == ERR_OK) { + shell_main(newconn); + netconn_delete(newconn); + } + } +} +/*-----------------------------------------------------------------------------------*/ +void +shell_init(void) +{ + sys_thread_new("shell_thread", shell_thread, NULL, DEFAULT_THREAD_STACKSIZE, DEFAULT_THREAD_PRIO); +} + +#endif /* LWIP_NETCONN */ diff --git a/src/lwip-1.4.1/apps/shell/shell.h b/src/lwip-1.4.1/apps/shell/shell.h new file mode 100644 index 0000000..874a753 --- /dev/null +++ b/src/lwip-1.4.1/apps/shell/shell.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2001-2003 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __SHELL_H__ +#define __SHELL_H__ + +void shell_init(void); + +#endif /* __SHELL_H__ */ diff --git a/src/lwip-1.4.1/apps/smtp/smtp.c b/src/lwip-1.4.1/apps/smtp/smtp.c new file mode 100644 index 0000000..612785a --- /dev/null +++ b/src/lwip-1.4.1/apps/smtp/smtp.c @@ -0,0 +1,1310 @@ +/** + * @file + * SMTP client module + * + * Author: Simon Goldschmidt + * + * Example usage: + * + * void my_smtp_result_fn(void *arg, u8_t smtp_result, u16_t srv_err, err_t err) + * { + * printf("mail (%p) sent with results: 0x%02x, 0x%04x, 0x%08x\n", arg, + * smtp_result, srv_err, err); + * } + * static void my_smtp_test(void) + * { + * smtp_set_server_addr("mymailserver.org"); + * smtp_set_auth("username", "password"); + * smtp_send_mail("recipient", "sender", "subject", "body", my_smtp_result_fn, + * some_argument); + * } + * + * When using from any other thread than the tcpip_thread (for NO_SYS==0), use + * smtp_send_mail_int()! + */ + +#include "lwip/opt.h" + +#include "smtp.h" + +#if LWIP_TCP +#include "lwip/sys.h" +#include "lwip/sockets.h" +#include "lwip/tcp.h" +#include "lwip/dns.h" + +#include + +/** This is simple SMTP client for raw API. + * It is a minimal implementation of SMTP as specified in RFC 5321. + * + * @todo: + * - attachments (the main difficulty here is streaming base64-encoding to + * prevent having to allocate a buffer for the whole encoded file at once) + * - test with more mail servers... + */ + +/** + * SMTP_DEBUG: Enable debugging for SNTP. + */ +#ifndef SMTP_DEBUG +#define SMTP_DEBUG LWIP_DBG_OFF +#endif + +/** Maximum length reserved for server name */ +#ifndef SMTP_MAX_SERVERNAME_LEN +#define SMTP_MAX_SERVERNAME_LEN 256 +#endif + +/** Maximum length reserved for username */ +#ifndef SMTP_MAX_USERNAME_LEN +#define SMTP_MAX_USERNAME_LEN 32 +#endif + +/** Maximum length reserved for password */ +#ifndef SMTP_MAX_PASS_LEN +#define SMTP_MAX_PASS_LEN 32 +#endif + +/** Set this to 0 if you know the authentication data will not change + * during the smtp session, which saves some heap space. */ +#ifndef SMTP_COPY_AUTHDATA +#define SMTP_COPY_AUTHDATA 1 +#endif + +/** Set this to 0 to save some code space if you know for sure that all data + * passed to this module conforms to the requirements in the SMTP RFC. + * WARNING: use this with care! + */ +#ifndef SMTP_CHECK_DATA +#define SMTP_CHECK_DATA 1 +#endif + +/** Set this to 1 to enable AUTH PLAIN support */ +#ifndef SMTP_SUPPORT_AUTH_PLAIN +#define SMTP_SUPPORT_AUTH_PLAIN 1 +#endif + +/** Set this to 1 to enable AUTH LOGIN support */ +#ifndef SMTP_SUPPORT_AUTH_LOGIN +#define SMTP_SUPPORT_AUTH_LOGIN 1 +#endif + +/** TCP poll interval. Unit is 0.5 sec. */ +#define SMTP_POLL_INTERVAL 4 +/** TCP poll timeout while sending message body, reset after every + * successful write. 3 minutes */ +#define SMTP_TIMEOUT_DATABLOCK ( 3 * 60 * SMTP_POLL_INTERVAL / 2) +/** TCP poll timeout while waiting for confirmation after sending the body. + * 10 minutes */ +#define SMTP_TIMEOUT_DATATERM (10 * 60 * SMTP_POLL_INTERVAL / 2) +/** TCP poll timeout while not sending the body. + * This is somewhat lower than the RFC states (5 minutes for initial, MAIL + * and RCPT) but still OK for us here. + * 2 minutes */ +#define SMTP_TIMEOUT ( 2 * 60 * SMTP_POLL_INTERVAL / 2) + +/* the various debug levels for this file */ +#define SMTP_DEBUG_TRACE (SMTP_DEBUG | LWIP_DBG_TRACE) +#define SMTP_DEBUG_STATE (SMTP_DEBUG | LWIP_DBG_STATE) +#define SMTP_DEBUG_WARN (SMTP_DEBUG | LWIP_DBG_LEVEL_WARNING) +#define SMTP_DEBUG_WARN_STATE (SMTP_DEBUG | LWIP_DBG_LEVEL_WARNING | LWIP_DBG_STATE) +#define SMTP_DEBUG_SERIOUS (SMTP_DEBUG | LWIP_DBG_LEVEL_SERIOUS) + + +#define SMTP_RX_BUF_LEN 255 +#define SMTP_TX_BUF_LEN 255 +#define SMTP_CRLF "\r\n" +#define SMTP_CRLF_LEN 2 + +#define SMTP_RESP_220 "220" +#define SMTP_RESP_235 "235" +#define SMTP_RESP_250 "250" +#define SMTP_RESP_334 "334" +#define SMTP_RESP_354 "354" +#define SMTP_RESP_LOGIN_UNAME "VXNlcm5hbWU6" +#define SMTP_RESP_LOGIN_PASS "UGFzc3dvcmQ6" + +#define SMTP_KEYWORD_AUTH_SP "AUTH " +#define SMTP_KEYWORD_AUTH_EQ "AUTH=" +#define SMTP_KEYWORD_AUTH_LEN 5 +#define SMTP_AUTH_PARAM_PLAIN "PLAIN" +#define SMTP_AUTH_PARAM_LOGIN "LOGIN" + +#define SMTP_CMD_EHLO_1 "EHLO [" +#define SMTP_CMD_EHLO_1_LEN 6 +#define SMTP_CMD_EHLO_2 "]\r\n" +#define SMTP_CMD_EHLO_2_LEN 3 +#define SMTP_CMD_AUTHPLAIN_1 "AUTH PLAIN " +#define SMTP_CMD_AUTHPLAIN_1_LEN 11 +#define SMTP_CMD_AUTHPLAIN_2 "\r\n" +#define SMTP_CMD_AUTHPLAIN_2_LEN 2 +#define SMTP_CMD_AUTHLOGIN "AUTH LOGIN\r\n" +#define SMTP_CMD_AUTHLOGIN_LEN 12 +#define SMTP_CMD_MAIL_1 "MAIL FROM: <" +#define SMTP_CMD_MAIL_1_LEN 12 +#define SMTP_CMD_MAIL_2 ">\r\n" +#define SMTP_CMD_MAIL_2_LEN 3 +#define SMTP_CMD_RCPT_1 "RCPT TO: <" +#define SMTP_CMD_RCPT_1_LEN 10 +#define SMTP_CMD_RCPT_2 ">\r\n" +#define SMTP_CMD_RCPT_2_LEN 3 +#define SMTP_CMD_DATA "DATA\r\n" +#define SMTP_CMD_DATA_LEN 6 +#define SMTP_CMD_HEADER_1 "From: <" +#define SMTP_CMD_HEADER_1_LEN 7 +#define SMTP_CMD_HEADER_2 ">\r\nTo: <" +#define SMTP_CMD_HEADER_2_LEN 8 +#define SMTP_CMD_HEADER_3 ">\r\nSubject: " +#define SMTP_CMD_HEADER_3_LEN 12 +#define SMTP_CMD_HEADER_4 "\r\n\r\n" +#define SMTP_CMD_HEADER_4_LEN 4 +#define SMTP_CMD_BODY_FINISHED "\r\n.\r\n" +#define SMTP_CMD_BODY_FINISHED_LEN 5 +#define SMTP_CMD_QUIT "QUIT\r\n" +#define SMTP_CMD_QUIT_LEN 6 + +#if SMTP_STAT_TX_BUF_MAX +#define SMTP_TX_BUF_MAX(len) LWIP_MACRO(if((len) > smtp_tx_buf_len_max) smtp_tx_buf_len_max = (len);) +#else /* SMTP_STAT_TX_BUF_MAX */ +#define SMTP_TX_BUF_MAX(len) +#endif /* SMTP_STAT_TX_BUF_MAX */ + +#if SMTP_COPY_AUTHDATA +#define SMTP_USERNAME(session) (session)->username +#define SMTP_PASS(session) (session)->pass +#define SMTP_AUTH_PLAIN_DATA(session) (session)->auth_plain +#define SMTP_AUTH_PLAIN_LEN(session) (session)->auth_plain_len +#else /* SMTP_COPY_AUTHDATA */ +#define SMTP_USERNAME(session) smtp_username +#define SMTP_PASS(session) smtp_pass +#define SMTP_AUTH_PLAIN_DATA(session) smtp_auth_plain +#define SMTP_AUTH_PLAIN_LEN(session) smtp_auth_plain_len +#endif /* SMTP_COPY_AUTHDATA */ + + +/** State for SMTP client state machine */ +enum smtp_session_state { + SMTP_NULL, + SMTP_HELO, + SMTP_AUTH_PLAIN, + SMTP_AUTH_LOGIN_UNAME, + SMTP_AUTH_LOGIN_PASS, + SMTP_AUTH_LOGIN, + SMTP_MAIL, + SMTP_RCPT, + SMTP_DATA, + SMTP_BODY, + SMTP_QUIT, + SMTP_CLOSED +}; + +#if LWIP_DEBUG +/** State-to-string table for debugging */ +const char *smtp_state_str[] = { + "SMTP_NULL", + "SMTP_HELO", + "SMTP_AUTH_PLAIN", + "SMTP_AUTH_LOGIN_UNAME", + "SMTP_AUTH_LOGIN_PASS", + "SMTP_AUTH_LOGIN", + "SMTP_MAIL", + "SMTP_RCPT", + "SMTP_DATA", + "SMTP_BODY", + "SMTP_QUIT", + "SMTP_CLOSED", +}; + +const char *smtp_result_strs[] = { + "SMTP_RESULT_OK", + "SMTP_RESULT_ERR_UNKNOWN", + "SMTP_RESULT_ERR_CONNECT", + "SMTP_RESULT_ERR_HOSTNAME", + "SMTP_RESULT_ERR_CLOSED", + "SMTP_RESULT_ERR_TIMEOUT", + "SMTP_RESULT_ERR_SVR_RESP", +}; +#endif /* LWIP_DEBUG */ + +/** struct keeping the body and state of an smtp session */ +struct smtp_session { + /** keeping the state of the smtp session */ + enum smtp_session_state state; + /** timeout handling, if this reaches 0, the connection is closed */ + u16_t timer; + /** helper buffer for transmit, not used for sending body */ + char tx_buf[SMTP_TX_BUF_LEN + 1]; + struct pbuf* p; + /** source email address */ + const char* from; + /** size of the sourceemail address */ + u16_t from_len; + /** target email address */ + const char* to; + /** size of the target email address */ + u16_t to_len; + /** subject of the email */ + const char *subject; + /** length of the subject string */ + u16_t subject_len; + /** this is the body of the mail to be sent */ + const char* body; + /** this is the length of the body to be sent */ + u16_t body_len; + /** amount of data from body already sent */ + u16_t body_sent; + /** callback function to call when closed */ + smtp_result_fn callback_fn; + /** argument for callback function */ + void *callback_arg; +#if SMTP_COPY_AUTHDATA + /** Username to use for this request */ + char *username; + /** Password to use for this request */ + char *pass; + /** Username and password combined as necessary for PLAIN authentication */ + char auth_plain[SMTP_MAX_USERNAME_LEN + SMTP_MAX_PASS_LEN + 3]; + /** Length of smtp_auth_plain string (cannot use strlen since it includes \0) */ + size_t auth_plain_len; +#endif /* SMTP_COPY_AUTHDATA */ +}; + +/** IP address or DNS name of the server to use for next SMTP request */ +static char smtp_server[SMTP_MAX_SERVERNAME_LEN + 1]; +/** TCP port of the server to use for next SMTP request */ +static u16_t smtp_server_port = SMTP_DEFAULT_PORT; +/** Username to use for the next SMTP request */ +static char *smtp_username; +/** Password to use for the next SMTP request */ +static char *smtp_pass; +/** Username and password combined as necessary for PLAIN authentication */ +static char smtp_auth_plain[SMTP_MAX_USERNAME_LEN + SMTP_MAX_PASS_LEN + 3]; +/** Length of smtp_auth_plain string (cannot use strlen since it includes \0) */ +static size_t smtp_auth_plain_len; + +static size_t max_tx_buf_len; +static size_t max_rx_buf_len; + +static err_t smtp_verify(const char *data, size_t data_len, u8_t linebreaks_allowed); +static err_t smtp_tcp_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err); +static void smtp_tcp_err(void *arg, err_t err); +static err_t smtp_tcp_poll(void *arg, struct tcp_pcb *pcb); +static err_t smtp_tcp_sent(void *arg, struct tcp_pcb *pcb, u16_t len); +static err_t smtp_tcp_connected(void *arg, struct tcp_pcb *pcb, err_t err); +static void smtp_dns_found(const char* hostname, ip_addr_t *ipaddr, void *arg); +static size_t smtp_base64_encode(char* target, size_t target_len, const char* source, size_t source_len); +static enum smtp_session_state smtp_prepare_mail(struct smtp_session *s, u16_t *tx_buf_len); +static void smtp_send_body(struct smtp_session *s, struct tcp_pcb *pcb); +static void smtp_process(void *arg, struct tcp_pcb *pcb, struct pbuf *p); + + +#if LWIP_DEBUG +/** Convert an smtp result to a string */ +const char* +smtp_result_str(u8_t smtp_result) +{ + if (smtp_result > SMTP_RESULT_ERR_SVR_RESP) { + return "UNKNOWN"; + } + return smtp_result_strs[smtp_result]; +} + +/** Null-terminates the payload of p for printing out messages. + * WARNING: use this only if p is not needed any more as the last byte of + * payload is deleted! + */ +static char* +smtp_pbuf_str(struct pbuf* p) +{ + if ((p == NULL) || (p->len == 0)) { + return ""; + } + ((char*)p->payload)[p->len] = 0; + return p->payload; +} +#endif /* LWIP_DEBUG */ + +/** Set IP address or DNS name for next SMTP connection + * + * @param server IP address (in ASCII representation) or DNS name of the server + */ +void +smtp_set_server_addr(const char* server) +{ + size_t len = 0; + if (server != NULL) { + len = strlen(server); + } + if (len > SMTP_MAX_SERVERNAME_LEN) { + len = SMTP_MAX_SERVERNAME_LEN; + } + memcpy(smtp_server, server, len); +} + +/** Set TCP port for next SMTP connection + * + * @param port TCP port + */ +void +smtp_set_server_port(u16_t port) +{ + smtp_server_port = port; +} + +/** Set authentication parameters for next SMTP connection + * + * @param username login name as passed to the server + * @param pass password passed to the server together with username + */ +err_t +smtp_set_auth(const char* username, const char* pass) +{ + size_t uname_len = 0; + size_t pass_len = 0; + + memset(smtp_auth_plain, 0xfa, 64); + if (username != NULL) { + uname_len = strlen(username); + if (uname_len > SMTP_MAX_USERNAME_LEN) { + LWIP_DEBUGF(SMTP_DEBUG_SERIOUS, ("Username is too long, %d instead of %d\n", + (int)uname_len, SMTP_MAX_USERNAME_LEN)); + return ERR_ARG; + } + } + if (pass != NULL) { +#if SMTP_SUPPORT_AUTH_LOGIN || SMTP_SUPPORT_AUTH_PLAIN + pass_len = strlen(pass); + if (pass_len > SMTP_MAX_PASS_LEN) { + LWIP_DEBUGF(SMTP_DEBUG_SERIOUS, ("Password is too long, %d instead of %d\n", + (int)uname_len, SMTP_MAX_USERNAME_LEN)); + return ERR_ARG; + } +#else /* SMTP_SUPPORT_AUTH_LOGIN || SMTP_SUPPORT_AUTH_PLAIN */ + LWIP_DEBUGF(SMTP_DEBUG_WARN, ("Password not supported as no authentication methods are activated\n")); +#endif /* SMTP_SUPPORT_AUTH_LOGIN || SMTP_SUPPORT_AUTH_PLAIN */ + } + *smtp_auth_plain = 0; + smtp_username = smtp_auth_plain + 1; + strcpy(smtp_username, username); + smtp_pass = smtp_auth_plain + uname_len + 2; + strcpy(smtp_pass, pass); + smtp_auth_plain_len = uname_len + pass_len + 2; + + return ERR_OK; +} + +/** The actual mail-sending function, called by smtp_send_mail and + * smtp_send_mail_static after setting up the struct smtp_session. + */ +static err_t +smtp_send_mail_alloced(struct smtp_session *s) +{ + err_t err; + struct tcp_pcb* pcb; + ip_addr_t addr; + + LWIP_ASSERT("no smtp_session supplied", s != NULL); + +#if SMTP_CHECK_DATA + /* check that body conforms to RFC: + * - convert all single-CR or -LF in body to CRLF + * - only 7-bit ASCII is allowed + */ + if (smtp_verify(s->to, s->to_len, 0) != ERR_OK) { + return ERR_ARG; + } + if (smtp_verify(s->from, s->from_len, 0) != ERR_OK) { + return ERR_ARG; + } + if (smtp_verify(s->subject, s->subject_len, 0) != ERR_OK) { + return ERR_ARG; + } + if (smtp_verify(s->body, s->body_len, 0) != ERR_OK) { + return ERR_ARG; + } +#endif /* SMTP_CHECK_DATA */ + + pcb = tcp_new(); + if (pcb == NULL) { + err = ERR_MEM; + goto leave; + } + +#if SMTP_COPY_AUTHDATA + /* copy auth data, ensuring the first byte is always zero */ + memcpy(s->auth_plain + 1, smtp_auth_plain + 1, smtp_auth_plain_len - 1); + s->auth_plain_len = smtp_auth_plain_len; + /* default username and pass is empty string */ + s->username = s->auth_plain; + s->pass = s->auth_plain; + if (smtp_username != NULL) { + s->username += smtp_username - smtp_auth_plain; + } + if (smtp_pass != NULL) { + s->pass += smtp_pass - smtp_auth_plain; + } +#endif /* SMTP_COPY_AUTHDATA */ + + s->state = SMTP_NULL; + s->timer = SMTP_TIMEOUT; + + tcp_arg(pcb, s); + tcp_recv(pcb, smtp_tcp_recv); + tcp_err(pcb, smtp_tcp_err); + tcp_poll(pcb, smtp_tcp_poll, SMTP_POLL_INTERVAL); + tcp_sent(pcb, smtp_tcp_sent); + +#if LWIP_DNS + err = dns_gethostbyname(smtp_server, &addr, smtp_dns_found, pcb); +#else /* LWIP_DNS */ + addr.addr = ipaddr_addr(smtp_server); + err = addr.addr == IPADDR_NONE ? ERR_ARG : ERR_OK; +#endif /* LWIP_DNS */ + if (err == ERR_OK) { + err = tcp_connect(pcb, &addr, smtp_server_port, smtp_tcp_connected); + if (err != ERR_OK) { + LWIP_DEBUGF(SMTP_DEBUG_WARN_STATE, ("tcp_connect failed: %d\n", (int)err)); + goto deallocate_and_leave; + } + } else if (err != ERR_INPROGRESS) { + LWIP_DEBUGF(SMTP_DEBUG_WARN_STATE, ("dns_gethostbyname failed: %d\n", (int)err)); + goto deallocate_and_leave; + } + return ERR_OK; + +deallocate_and_leave: + if (pcb != NULL) { + tcp_arg(pcb, NULL); + tcp_close(pcb); + } +leave: + mem_free(s); + /* no need to call the callback here since we return != ERR_OK */ + return err; +} + +/** Send an email via the currently selected server, username and password. + * + * @param from source email address (must be NULL-terminated) + * @param to target email address (must be NULL-terminated) + * @param subject email subject (must be NULL-terminated) + * @param body email body (must be NULL-terminated) + * @param + * @returns - ERR_OK if structures were allocated and no error occured starting the connection + * (this does not mean the email has been successfully sent!) + * - another err_t on error. + */ +err_t +smtp_send_mail(const char* from, const char* to, const char* subject, const char* body, + smtp_result_fn callback_fn, void* callback_arg) +{ + struct smtp_session* s; + size_t from_len = strlen(from); + size_t to_len = strlen(to); + size_t subject_len = strlen(subject); + size_t body_len = strlen(body); + size_t mem_len = sizeof(struct smtp_session); + + mem_len += from_len + to_len + subject_len + body_len + 4; + if (mem_len > 0xffff) { + /* too long! */ + return ERR_MEM; + } + + /* Allocate memory to keep this email's session state */ + s = (struct smtp_session *)mem_malloc((mem_size_t)mem_len); + if (s == NULL) { + return ERR_MEM; + } + /* initialize the structure */ + memset(s, 0, mem_len); + s->from = (char*)s + sizeof(struct smtp_session); + s->from_len = (u16_t)from_len; + s->to = s->from + from_len + 1; + s->to_len = (u16_t)to_len; + s->subject = s->to + to_len + 1; + s->subject_len = (u16_t)subject_len; + s->body = s->subject + subject_len + 1; + s->body_len = (u16_t)body_len; + /* copy source and target email address */ + memcpy((char*)s->from, from, from_len + 1); + memcpy((char*)s->to, to, to_len + 1); + memcpy((char*)s->subject, subject, subject_len + 1); + memcpy((char*)s->body, body, body_len + 1); + + s->callback_fn = callback_fn; + s->callback_arg = callback_arg; + + /* call the actual implementation of this function */ + return smtp_send_mail_alloced(s); +} + +/** Same as smtp_send_mail, but doesn't copy from, to, subject and body into + * an internal buffer to save memory. + * WARNING: the above data must stay untouched until the callback function is + * called (unless the function returns != ERR_OK) + */ +err_t +smtp_send_mail_static(const char *from, const char* to, const char* subject, + const char* body, smtp_result_fn callback_fn, void* callback_arg) +{ + struct smtp_session* s; + size_t len; + + s = mem_malloc(sizeof(struct smtp_session)); + if (s == NULL) { + return ERR_MEM; + } + memset(s, 0, sizeof(struct smtp_session)); + /* initialize the structure */ + s->from = from; + len = strlen(from); + LWIP_ASSERT("string is too long", len <= 0xffff); + s->from_len = (u16_t)len; + s->to = to; + len = strlen(to); + LWIP_ASSERT("string is too long", len <= 0xffff); + s->to_len = (u16_t)len; + s->subject = subject; + len = strlen(subject); + LWIP_ASSERT("string is too long", len <= 0xffff); + s->subject_len = (u16_t)len; + s->body = body; + len = strlen(body); + LWIP_ASSERT("string is too long", len <= 0xffff); + s->body_len = (u16_t)len; + s->callback_fn = callback_fn; + s->callback_arg = callback_arg; + /* call the actual implementation of this function */ + return smtp_send_mail_alloced(s); +} + + +/** Same as smpt_send_mail but takes a struct smtp_send_request as single + * parameter which contains all the other parameters. + * To be used with tcpip_callback to send mail from interrupt context or from + * another thread. + * + * WARNING: server and authentication must stay untouched until this function has run! + * + * Usage example: + * - allocate a struct smtp_send_request (in a way that is allowed in interrupt context) + * - fill the members of the struct as if calling smtp_send_mail + * - specify a callback_function + * - set callback_arg to the structure itself + * - call this function + * - wait for the callback function to be called + * - in the callback function, deallocate the structure (passed as arg) + */ +void +smtp_send_mail_int(void *arg) +{ + struct smtp_send_request *req = arg; + err_t err; + + LWIP_ASSERT("smtp_send_mail_int: no argument given", arg != NULL); + + if (req->static_data) { + err = smtp_send_mail_static(req->from, req->to, req->subject, req->body, + req->callback_fn, req->callback_arg); + } else { + err = smtp_send_mail(req->from, req->to, req->subject, req->body, + req->callback_fn, req->callback_arg); + } + if ((err != ERR_OK) && (req->callback_fn != NULL)) { + req->callback_fn(req->callback_arg, SMTP_RESULT_ERR_UNKNOWN, 0, err); + } +} + +#if SMTP_CHECK_DATA +/** Verify that a given string conforms to the SMTP rules + * (7-bit only, no single CR or LF, + * @todo: no line consisting of a single dot only) + */ +static err_t +smtp_verify(const char *data, size_t data_len, u8_t linebreaks_allowed) +{ + size_t i; + u8_t last_was_cr = 0; + for (i = 0; i < data_len; i++) { + char current = data[i]; + if ((current & 0x80) != 0) { + LWIP_DEBUGF(SMTP_DEBUG_WARN, ("smtp_verify: no 8-bit data supported: %s\n", data)); + return ERR_ARG; + } + if (current == '\r') { + if (!linebreaks_allowed) { + LWIP_DEBUGF(SMTP_DEBUG_WARN, ("smtp_verify: found CR where no linebreaks allowed: %s\n", data)); + return ERR_ARG; + } + if (last_was_cr) { + LWIP_DEBUGF(SMTP_DEBUG_WARN, ("smtp_verify: found double CR: %s\n", data)); + return ERR_ARG; + } + last_was_cr = 1; + } else { + if (current == '\n') { + if (!last_was_cr) { + LWIP_DEBUGF(SMTP_DEBUG_WARN, ("smtp_verify: found LF without CR before: %s\n", data)); + return ERR_ARG; + } + } + last_was_cr = 0; + } + } + return ERR_OK; +} +#endif /* SMTP_CHECK_DATA */ + +/** Frees the smpt_session and calls the callback function */ +static void +smtp_free(struct smtp_session *s, u8_t result, u16_t srv_err, err_t err) +{ + smtp_result_fn fn = s->callback_fn; + void *arg = s->callback_arg; + if (s->p != NULL) { + pbuf_free(s->p); + } + mem_free(s); + if (fn != NULL) { + fn(arg, result, srv_err, err); + } +} + +/** Try to close a pcb and free the arg if successful */ +static void +smtp_close(struct smtp_session *s, struct tcp_pcb *pcb, u8_t result, + u16_t srv_err, err_t err) +{ + tcp_arg(pcb, NULL); + if (tcp_close(pcb) == ERR_OK) { + if (s != NULL) { + smtp_free(s, result, srv_err, err); + } + } else { + /* close failed, set back arg */ + tcp_arg(pcb, s); + } +} + +/** Raw API TCP err callback: pcb is already deallocated */ +static void +smtp_tcp_err(void *arg, err_t err) +{ + LWIP_UNUSED_ARG(err); + if (arg != NULL) { + LWIP_DEBUGF(SMTP_DEBUG_WARN_STATE, ("smtp_tcp_err: connection reset by remote host\n")); + smtp_free(arg, SMTP_RESULT_ERR_CLOSED, 0, err); + } +} + +/** Raw API TCP poll callback */ +static err_t +smtp_tcp_poll(void *arg, struct tcp_pcb *pcb) +{ + if (arg != NULL) { + struct smtp_session *s = arg; + if (s->timer != 0) { + s->timer--; + } + } + smtp_process(arg, pcb, NULL); + return ERR_OK; +} + +/** Raw API TCP sent callback */ +static err_t +smtp_tcp_sent(void *arg, struct tcp_pcb *pcb, u16_t len) +{ + LWIP_UNUSED_ARG(len); + + smtp_process(arg, pcb, NULL); + + return ERR_OK; +} + +/** Raw API TCP recv callback */ +static err_t +smtp_tcp_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err) +{ + LWIP_UNUSED_ARG(err); + if (p != NULL) { + tcp_recved(pcb, p->tot_len); + smtp_process(arg, pcb, p); + } else { + LWIP_DEBUGF(SMTP_DEBUG_WARN_STATE, ("smtp_tcp_recv: connection closed by remote host\n")); + smtp_close(arg, pcb, SMTP_RESULT_ERR_CLOSED, 0, err); + } + return ERR_OK; +} + +static err_t +smtp_tcp_connected(void *arg, struct tcp_pcb *pcb, err_t err) +{ + LWIP_UNUSED_ARG(arg); + + if (err == ERR_OK) { + LWIP_DEBUGF(SMTP_DEBUG_STATE, ("smtp_connected: Waiting for 220\n")); + } else { + LWIP_DEBUGF(SMTP_DEBUG_WARN, ("smtp_connected: %d\n", (int)err)); + smtp_close(arg, pcb, SMTP_RESULT_ERR_CONNECT, 0, err); + } + return ERR_OK; +} + +/** DNS callback + * If ipaddr is non-NULL, resolving succeeded, otherwise it failed. + */ +static void +smtp_dns_found(const char* hostname, ip_addr_t *ipaddr, void *arg) +{ + struct tcp_pcb *pcb = arg; + err_t err; + u8_t result; + + LWIP_UNUSED_ARG(hostname); + + if (ipaddr != NULL) { + LWIP_DEBUGF(SMTP_DEBUG_STATE, ("smtp_dns_found: hostname resolved, connecting\n")); + err = tcp_connect(pcb, ipaddr, smtp_server_port, smtp_tcp_connected); + if (err == ERR_OK) { + return; + } + LWIP_DEBUGF(SMTP_DEBUG_WARN_STATE, ("tcp_connect failed: %d\n", (int)err)); + result = SMTP_RESULT_ERR_CONNECT; + } else { + LWIP_DEBUGF(SMTP_DEBUG_WARN_STATE, ("smtp_dns_found: failed to resolve hostname: %s\n", + hostname)); + result = SMTP_RESULT_ERR_HOSTNAME; + err = ERR_ARG; + } + smtp_close(pcb->callback_arg, pcb, result, 0, err); +} + +#if SMTP_SUPPORT_AUTH_AUTH || SMTP_SUPPORT_AUTH_LOGIN + +/** Table 6-bit-index-to-ASCII used for base64-encoding */ +const u8_t base64_table[] = { + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', + 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', + 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', + 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', + 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', + 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + '+', '/' +}; + +/** Base64 encoding */ +static size_t +smtp_base64_encode(char* target, size_t target_len, const char* source, size_t source_len) +{ + size_t i; + s8_t j; + size_t target_idx = 0; + size_t longer = 3 - (source_len % 3); + size_t source_len_b64 = source_len + longer; + size_t len = (((source_len_b64) * 4) / 3); + u8_t x = 5; + u8_t current = 0; + LWIP_UNUSED_ARG(target_len); + + LWIP_ASSERT("target_len is too short", target_len >= len); + + for (i = 0; i < source_len_b64; i++) { + u8_t b = (i < source_len ? source[i] : 0); + for (j = 7; j >= 0; j--, x--) { + u8_t shift = ((b & (1 << j)) != 0) ? 1 : 0; + current |= shift << x; + if (x == 0) { + target[target_idx++] = base64_table[current]; + x = 6; + current = 0; + } + } + } + for (i = len - longer; i < len; i++) { + target[i] = '='; + } + return len; +} +#endif /* SMTP_SUPPORT_AUTH_AUTH || SMTP_SUPPORT_AUTH_LOGIN */ + +/** Parse pbuf to see if it contains the beginning of an answer. + * If so, it returns the contained response code as number between 1 and 999. + * If not, zero is returned. + * + * @param s smtp session struct + */ +static u16_t +smtp_is_response(struct smtp_session *s) +{ + char digits[4]; + long num; + + if (s->p == NULL) { + return 0; + } + /* copy three digits and convert them to int */ + if (pbuf_copy_partial(s->p, digits, 3, 0) != 3) { + /* pbuf was too short */ + return 0; + } + digits[3] = 0; + num = strtol(digits, NULL, 10); + if ((num <= 0) || (num >= 1000)) { + /* failed to find response code at start of line */ + return 0; + } + return (u16_t)num; +} + +/** Parse pbuf to see if it contains a fully received answer. + * If one is found, ERR_OK is returned. + * If none is found, ERR_VAL is returned. + * + * A fully received answer is a 3-digit number followed by a space, + * some string and a CRLF as line ending. + * + * @param s smtp session struct + */ +static err_t +smtp_is_response_finished(struct smtp_session *s) +{ + u8_t sp; + u16_t crlf; + u16_t offset; + + if (s->p == NULL) { + return ERR_VAL; + } + offset = 0; +again: + /* We could check the response number here, but we trust the + * protocol definition which says the client can rely on it being + * the same on every line. */ + + /* find CRLF */ + crlf = pbuf_memfind(s->p, SMTP_CRLF, SMTP_CRLF_LEN, offset + 4); + if (crlf == 0xFFFF) { + /* no CRLF found */ + return ERR_VAL; + } + sp = pbuf_get_at(s->p, offset + 3); + if (sp == '-') { + /* no space after response code -> try next line */ + offset = crlf + 2; + goto again; + } else if (sp == ' ') { + /* CRLF found after response code + space -> valid response */ + return ERR_OK; + } + /* sp contains invalid character */ + return ERR_VAL; +} + +/** Prepare HELO/EHLO message */ +static enum smtp_session_state +smtp_prepare_helo(struct smtp_session *s, u16_t *tx_buf_len, struct tcp_pcb *pcb) +{ + size_t ipa_len; + char *ipa = ip_ntoa(&pcb->local_ip); + LWIP_ASSERT("ip_ntoa returned NULL", ipa != NULL); + ipa_len = strlen(ipa); + LWIP_ASSERT("string too long", ipa_len <= 0xffff); + + *tx_buf_len = SMTP_CMD_EHLO_1_LEN + (u16_t)ipa_len + SMTP_CMD_EHLO_2_LEN; + LWIP_ASSERT("tx_buf overflow detected", *tx_buf_len <= SMTP_TX_BUF_LEN); + + SMEMCPY(s->tx_buf, SMTP_CMD_EHLO_1, SMTP_CMD_EHLO_1_LEN); + MEMCPY(&s->tx_buf[SMTP_CMD_EHLO_1_LEN], ipa, ipa_len); + SMEMCPY(&s->tx_buf[SMTP_CMD_EHLO_1_LEN + ipa_len], SMTP_CMD_EHLO_2, SMTP_CMD_EHLO_2_LEN); + return SMTP_HELO; +} + +#if SMTP_SUPPORT_AUTH_AUTH || SMTP_SUPPORT_AUTH_LOGIN +/** Parse last server response (in rx_buf) for supported authentication method, + * create data to send out (to tx_buf), set tx_data_len correctly + * and return the next state. + */ +static enum smtp_session_state +smtp_prepare_auth_or_mail(struct smtp_session *s, u16_t *tx_buf_len) +{ + /* check response for supported authentication method */ + u16_t auth = pbuf_strstr(s->p, SMTP_KEYWORD_AUTH_SP); + if (auth == 0xFFFF) { + auth = pbuf_strstr(s->p, SMTP_KEYWORD_AUTH_EQ); + } + if (auth != 0xFFFF) { + u16_t crlf = pbuf_memfind(s->p, SMTP_CRLF, SMTP_CRLF_LEN, auth); + if ((crlf != 0xFFFF) && (crlf > auth)) { + /* use tx_buf temporarily */ + u16_t copied = pbuf_copy_partial(s->p, s->tx_buf, crlf - auth, auth); + if (copied != 0) { + char *sep = s->tx_buf + SMTP_KEYWORD_AUTH_LEN; + s->tx_buf[copied] = 0; +#if SMTP_SUPPORT_AUTH_PLAIN + /* favour PLAIN over LOGIN since it involves less requests */ + if (strstr(sep, SMTP_AUTH_PARAM_PLAIN) != NULL) { + size_t auth_len; + /* server supports AUTH PLAIN */ + SMEMCPY(s->tx_buf, SMTP_CMD_AUTHPLAIN_1, SMTP_CMD_AUTHPLAIN_1_LEN); + + /* add base64-encoded string "\0username\0password" */ + auth_len = smtp_base64_encode(&s->tx_buf[SMTP_CMD_AUTHPLAIN_1_LEN], + SMTP_TX_BUF_LEN - SMTP_CMD_AUTHPLAIN_1_LEN, SMTP_AUTH_PLAIN_DATA(s), + SMTP_AUTH_PLAIN_LEN(s)); + LWIP_ASSERT("string too long", auth_len <= 0xffff); + *tx_buf_len = SMTP_CMD_AUTHPLAIN_1_LEN + SMTP_CMD_AUTHPLAIN_2_LEN + (u16_t)auth_len; + LWIP_ASSERT("tx_buf overflow detected", *tx_buf_len <= SMTP_TX_BUF_LEN); + SMEMCPY(&s->tx_buf[SMTP_CMD_AUTHPLAIN_1_LEN + auth_len], SMTP_CMD_AUTHPLAIN_2, + SMTP_CMD_AUTHPLAIN_2_LEN); + return SMTP_AUTH_PLAIN; + } else +#endif /* SMTP_SUPPORT_AUTH_PLAIN */ + { +#if SMTP_SUPPORT_AUTH_LOGIN + if (strstr(sep, SMTP_AUTH_PARAM_LOGIN) != NULL) { + /* server supports AUTH LOGIN */ + *tx_buf_len = SMTP_CMD_AUTHLOGIN_LEN; + SMEMCPY(s->tx_buf, SMTP_CMD_AUTHLOGIN, SMTP_CMD_AUTHLOGIN_LEN); + return SMTP_AUTH_LOGIN_UNAME; + } +#endif /* SMTP_SUPPORT_AUTH_LOGIN */ + } + } + } + } + /* server didnt's send correct keywords for AUTH, try sending directly */ + return smtp_prepare_mail(s, tx_buf_len); +} +#endif /* SMTP_SUPPORT_AUTH_AUTH || SMTP_SUPPORT_AUTH_LOGIN */ + +#if SMTP_SUPPORT_AUTH_LOGIN +/** Send base64-encoded username */ +static enum smtp_session_state +smtp_prepare_auth_login_uname(struct smtp_session *s, u16_t *tx_buf_len) +{ + size_t base64_len = smtp_base64_encode(s->tx_buf, SMTP_TX_BUF_LEN, + SMTP_USERNAME(s), strlen(SMTP_USERNAME(s))); + /* @todo: support base64-encoded longer than 64k */ + LWIP_ASSERT("string too long", base64_len <= 0xffff); + LWIP_ASSERT("tx_buf overflow detected", base64_len + SMTP_CRLF_LEN <= SMTP_TX_BUF_LEN); + *tx_buf_len = (u16_t)base64_len + SMTP_CRLF_LEN; + + SMEMCPY(&s->tx_buf[base64_len], SMTP_CRLF, SMTP_CRLF_LEN); + s->tx_buf[*tx_buf_len] = 0; + return SMTP_AUTH_LOGIN_PASS; +} + +/** Send base64-encoded password */ +static enum smtp_session_state +smtp_prepare_auth_login_pass(struct smtp_session *s, u16_t *tx_buf_len) +{ + size_t base64_len = smtp_base64_encode(s->tx_buf, SMTP_TX_BUF_LEN, + SMTP_PASS(s), strlen(SMTP_PASS(s))); + /* @todo: support base64-encoded longer than 64k */ + LWIP_ASSERT("string too long", base64_len <= 0xffff); + LWIP_ASSERT("tx_buf overflow detected", base64_len + SMTP_CRLF_LEN <= SMTP_TX_BUF_LEN); + *tx_buf_len = (u16_t)base64_len + SMTP_CRLF_LEN; + + SMEMCPY(&s->tx_buf[base64_len], SMTP_CRLF, SMTP_CRLF_LEN); + s->tx_buf[*tx_buf_len] = 0; + return SMTP_AUTH_LOGIN; +} +#endif /* SMTP_SUPPORT_AUTH_LOGIN */ + +/** Prepare MAIL message */ +static enum smtp_session_state +smtp_prepare_mail(struct smtp_session *s, u16_t *tx_buf_len) +{ + char *target = s->tx_buf; + *tx_buf_len = SMTP_CMD_MAIL_1_LEN + SMTP_CMD_MAIL_2_LEN + s->from_len; + LWIP_ASSERT("tx_buf overflow detected", *tx_buf_len <= SMTP_TX_BUF_LEN); + target[*tx_buf_len] = 0; + + SMEMCPY(target, SMTP_CMD_MAIL_1, SMTP_CMD_MAIL_1_LEN); + target += SMTP_CMD_MAIL_1_LEN; + memcpy(target, s->from, s->from_len); + target += s->from_len; + SMEMCPY(target, SMTP_CMD_MAIL_2, SMTP_CMD_MAIL_2_LEN); + return SMTP_MAIL; +} + +/** Prepare RCPT message */ +static enum smtp_session_state +smtp_prepare_rcpt(struct smtp_session *s, u16_t *tx_buf_len) +{ + char *target = s->tx_buf; + *tx_buf_len = SMTP_CMD_RCPT_1_LEN + SMTP_CMD_RCPT_2_LEN + s->to_len; + LWIP_ASSERT("tx_buf overflow detected", *tx_buf_len <= SMTP_TX_BUF_LEN); + target[*tx_buf_len] = 0; + + SMEMCPY(target, SMTP_CMD_RCPT_1, SMTP_CMD_RCPT_1_LEN); + target += SMTP_CMD_RCPT_1_LEN; + memcpy(target, s->to, s->to_len); + target += s->to_len; + SMEMCPY(target, SMTP_CMD_RCPT_2, SMTP_CMD_RCPT_2_LEN); + return SMTP_RCPT; +} + +/** Prepare header of body */ +static enum smtp_session_state +smtp_prepare_header(struct smtp_session *s, u16_t *tx_buf_len) +{ + char *target = s->tx_buf; + *tx_buf_len = SMTP_CMD_HEADER_1_LEN + SMTP_CMD_HEADER_2_LEN + + SMTP_CMD_HEADER_3_LEN + SMTP_CMD_HEADER_4_LEN + s->from_len + s->to_len + + s->subject_len; + LWIP_ASSERT("tx_buf overflow detected", *tx_buf_len <= SMTP_TX_BUF_LEN); + target[*tx_buf_len] = 0; + + SMEMCPY(target, SMTP_CMD_HEADER_1, SMTP_CMD_HEADER_1_LEN); + target += SMTP_CMD_HEADER_1_LEN; + memcpy(target, s->from, s->from_len); + target += s->from_len; + SMEMCPY(target, SMTP_CMD_HEADER_2, SMTP_CMD_HEADER_2_LEN); + target += SMTP_CMD_HEADER_2_LEN; + memcpy(target, s->to, s->to_len); + target += s->to_len; + SMEMCPY(target, SMTP_CMD_HEADER_3, SMTP_CMD_HEADER_3_LEN); + target += SMTP_CMD_HEADER_3_LEN; + memcpy(target, s->subject, s->subject_len); + target += s->subject_len; + SMEMCPY(target, SMTP_CMD_HEADER_4, SMTP_CMD_HEADER_4_LEN); + + return SMTP_BODY; +} + +/** Prepare QUIT message */ +static enum smtp_session_state +smtp_prepare_quit(struct smtp_session *s, u16_t *tx_buf_len) +{ + *tx_buf_len = SMTP_CMD_QUIT_LEN; + s->tx_buf[*tx_buf_len] = 0; + SMEMCPY(s->tx_buf, SMTP_CMD_QUIT, SMTP_CMD_QUIT_LEN); + LWIP_ASSERT("tx_buf overflow detected", *tx_buf_len <= SMTP_TX_BUF_LEN); + return SMTP_CLOSED; +} + +/** If in state SMTP_BODY, try to send more body data */ +static void +smtp_send_body(struct smtp_session *s, struct tcp_pcb *pcb) +{ + err_t err; + + if (s->state == SMTP_BODY) { + u16_t send_len = s->body_len - s->body_sent; + if (send_len > 0) { + u16_t snd_buf = tcp_sndbuf(pcb); + if (send_len > snd_buf) { + send_len = snd_buf; + } + if (send_len > 0) { + /* try to send something out */ + err = tcp_write(pcb, &s->body[s->body_sent], (u16_t)send_len, TCP_WRITE_FLAG_COPY); + if (err == ERR_OK) { + s->timer = SMTP_TIMEOUT_DATABLOCK; + s->body_sent += send_len; + if (s->body_sent < s->body_len) { + LWIP_DEBUGF(SMTP_DEBUG_STATE, ("smtp_send_body: %d of %d bytes written\n", + s->body_sent, s->body_len)); + } + } + } + } + if (s->body_sent == s->body_len) { + /* the whole body has been written, write last line */ + LWIP_DEBUGF(SMTP_DEBUG_STATE, ("smtp_send_body: body completely written (%d bytes), appending end-of-body\n", + s->body_len)); + err = tcp_write(pcb, SMTP_CMD_BODY_FINISHED, SMTP_CMD_BODY_FINISHED_LEN, 0); + if (err == ERR_OK) { + s->timer = SMTP_TIMEOUT_DATATERM; + LWIP_DEBUGF(SMTP_DEBUG_STATE, ("smtp_send_body: end-of-body written, changing state to %s\n", + smtp_state_str[SMTP_QUIT])); + /* last line written, change state, wait for confirmation */ + s->state = SMTP_QUIT; + } + } + } +} + +/** State machine-like implementation of an SMTP client. + */ +static void +smtp_process(void *arg, struct tcp_pcb *pcb, struct pbuf *p) +{ + struct smtp_session* s = arg; + u16_t response_code = 0; + u16_t tx_buf_len = 0; + enum smtp_session_state next_state; + + if (arg == NULL) { + /* already closed SMTP connection */ + if (p != NULL) { + LWIP_DEBUGF(SMTP_DEBUG_TRACE, ("Received %d bytes after closing: %s\n", + p->tot_len, smtp_pbuf_str(p))); + pbuf_free(p); + } + return; + } + + next_state = s->state; + + if (p != NULL) { + /* received data */ + if (s->p == NULL) { + s->p = p; + } else { + pbuf_cat(s->p, p); + } + } else { + /* idle timer, close connection if timed out */ + if (s->timer == 0) { + LWIP_DEBUGF(SMTP_DEBUG_WARN_STATE, ("smtp_process: connection timed out, closing\n")); + smtp_close(s, pcb, SMTP_RESULT_ERR_TIMEOUT, 0, ERR_TIMEOUT); + return; + } + if (s->state == SMTP_BODY) { + smtp_send_body(s, pcb); + return; + } + } + response_code = smtp_is_response(s); + if (response_code) { + LWIP_DEBUGF(SMTP_DEBUG_TRACE, ("smtp_process: received response code: %d\n", response_code)); + if (smtp_is_response_finished(s) != ERR_OK) { + LWIP_DEBUGF(SMTP_DEBUG_TRACE, ("smtp_process: partly received response code: %d\n", response_code)); + /* wait for next packet to complete the respone */ + return; + } + } else { + if (s->p != NULL) { + LWIP_DEBUGF(SMTP_DEBUG_WARN, ("smtp_process: unknown data received (%s)\n", + smtp_pbuf_str(s->p))); + pbuf_free(s->p); + s->p = NULL; + } + return; + } + + switch(s->state) + { + case(SMTP_NULL): + /* wait for 220 */ + if (response_code == 220) { + /* then send EHLO */ + next_state = smtp_prepare_helo(s, &tx_buf_len, pcb); + } + break; + case(SMTP_HELO): + /* wait for 250 */ + if (response_code == 250) { +#if SMTP_SUPPORT_AUTH_AUTH || SMTP_SUPPORT_AUTH_LOGIN + /* then send AUTH or MAIL */ + next_state = smtp_prepare_auth_or_mail(s, &tx_buf_len); + } + break; + case(SMTP_AUTH_LOGIN): + case(SMTP_AUTH_PLAIN): + /* wait for 235 */ + if (response_code == 235) { +#endif /* SMTP_SUPPORT_AUTH_AUTH || SMTP_SUPPORT_AUTH_LOGIN */ + /* send MAIL */ + next_state = smtp_prepare_mail(s, &tx_buf_len); + } + break; +#if SMTP_SUPPORT_AUTH_LOGIN + case(SMTP_AUTH_LOGIN_UNAME): + /* wait for 334 Username */ + if (response_code == 334) { + if (pbuf_strstr(s->p, SMTP_RESP_LOGIN_UNAME) != 0xFFFF) { + /* send username */ + next_state = smtp_prepare_auth_login_uname(s, &tx_buf_len); + } + } + break; + case(SMTP_AUTH_LOGIN_PASS): + /* wait for 334 Password */ + if (response_code == 334) { + if (pbuf_strstr(s->p, SMTP_RESP_LOGIN_PASS) != 0xFFFF) { + /* send username */ + next_state = smtp_prepare_auth_login_pass(s, &tx_buf_len); + } + } + break; +#endif /* SMTP_SUPPORT_AUTH_LOGIN */ + case(SMTP_MAIL): + /* wait for 250 */ + if (response_code == 250) { + /* send RCPT */ + next_state = smtp_prepare_rcpt(s, &tx_buf_len); + } + break; + case(SMTP_RCPT): + /* wait for 250 */ + if (response_code == 250) { + /* send DATA */ + SMEMCPY(s->tx_buf, SMTP_CMD_DATA, SMTP_CMD_DATA_LEN); + tx_buf_len = SMTP_CMD_DATA_LEN; + next_state = SMTP_DATA; + } + break; + case(SMTP_DATA): + /* wait for 354 */ + if (response_code == 354) { + /* send email header */ + next_state = smtp_prepare_header(s, &tx_buf_len); + } + break; + case(SMTP_BODY): + /* nothing to be done here, handled somewhere else */ + break; + case(SMTP_QUIT): + /* wait for 250 */ + if (response_code == 250) { + /* send QUIT */ + next_state = smtp_prepare_quit(s, &tx_buf_len); + } + break; + case(SMTP_CLOSED): + /* nothing to do, wait for connection closed from server */ + return; + default: + LWIP_DEBUGF(SMTP_DEBUG_SERIOUS, ("Invalid state: %d/%s\n", (int)s->state, + smtp_state_str[s->state])); + break; + } + if (s->state == next_state) { + LWIP_DEBUGF(SMTP_DEBUG_WARN_STATE, ("smtp_process[%s]: unexpected response_code, closing: %d (%s)\n", + smtp_state_str[s->state], response_code, smtp_pbuf_str(s->p))); + /* close connection */ + smtp_close(s, pcb, SMTP_RESULT_ERR_SVR_RESP, response_code, ERR_OK); + return; + } + if (tx_buf_len > 0) { + SMTP_TX_BUF_MAX(tx_buf_len); + if (tcp_write(pcb, s->tx_buf, tx_buf_len, TCP_WRITE_FLAG_COPY) == ERR_OK) { + LWIP_DEBUGF(SMTP_DEBUG_TRACE, ("smtp_process[%s]: received command %d (%s)\n", + smtp_state_str[s->state], response_code, smtp_pbuf_str(s->p))); + LWIP_DEBUGF(SMTP_DEBUG_TRACE, ("smtp_process[%s]: sent %"U16_F" bytes: \"%s\"\n", + smtp_state_str[s->state], tx_buf_len, s->tx_buf)); + s->timer = SMTP_TIMEOUT; + pbuf_free(s->p); + s->p = NULL; + LWIP_DEBUGF(SMTP_DEBUG_STATE, ("smtp_process: changing state from %s to %s\n", + smtp_state_str[s->state], smtp_state_str[next_state])); + s->state = next_state; + if (next_state == SMTP_BODY) { + /* try to stream-send body data right now */ + smtp_send_body(s, pcb); + } else if (next_state == SMTP_CLOSED) { + /* sent out all data, delete structure */ + tcp_arg(pcb, NULL); + smtp_free(s, SMTP_RESULT_OK, 0, ERR_OK); + } + } + } +} +#endif /* LWIP_TCP */ diff --git a/src/lwip-1.4.1/apps/smtp/smtp.h b/src/lwip-1.4.1/apps/smtp/smtp.h new file mode 100644 index 0000000..d6c2ced --- /dev/null +++ b/src/lwip-1.4.1/apps/smtp/smtp.h @@ -0,0 +1,67 @@ +#ifndef __SMTP_H__ +#define __SMTP_H__ + +#include "lwip/err.h" + +/** The default TCP port used for SMTP */ +#define SMTP_DEFAULT_PORT 25 + +/** Email successfully sent */ +#define SMTP_RESULT_OK 0 +/** Unknown error */ +#define SMTP_RESULT_ERR_UNKNOWN 1 +/** Connection to server failed */ +#define SMTP_RESULT_ERR_CONNECT 2 +/** Failed to resolve server hostname */ +#define SMTP_RESULT_ERR_HOSTNAME 3 +/** Connection unexpectedly closed by remote server */ +#define SMTP_RESULT_ERR_CLOSED 4 +/** Connection timed out (server didn't respond in time) */ +#define SMTP_RESULT_ERR_TIMEOUT 5 +/** Server responded with an unknown response code */ +#define SMTP_RESULT_ERR_SVR_RESP 6 + +/** Prototype of an smtp callback function + * + * @param arg argument specified when initiating the email + * @param smtp_result result of the mail transfer (see defines SMTP_RESULT_*) + * @param srv_err if aborted by the server, this contains the error code received + * @param err an error returned by internal lwip functions, can help to specify + * the source of the error but must not necessarily be != ERR_OK + */ +typedef void (*smtp_result_fn)(void *arg, u8_t smtp_result, u16_t srv_err, err_t err); + +/** This structure is used as argument for smtp_send_mail_int(), + * which in turn can be used with tcpip_callback() to send mail + * from interrupt context. + * For member description, see parameter description of smtp_send_mail(). + * When using with tcpip_callback, this structure has to stay allocated + * (e.g. using mem_malloc/mem_free) until its 'callback_fn' is called. + */ +struct smtp_send_request { + const char *from; + const char* to; + const char* subject; + const char* body; + smtp_result_fn callback_fn; + void* callback_arg; + /** If this is != 0, data is *not* copied into an extra buffer + * but used from the pointers supplied in this struct. + * This means less memory usage, but data must stay untouched until + * the callback function is called. */ + u8_t static_data; +}; + +void smtp_set_server_addr(const char* server); +void smtp_set_server_port(u16_t port); +err_t smtp_set_auth(const char* username, const char* pass); +err_t smtp_send_mail(const char *from, const char* to, const char* subject, const char* body, + smtp_result_fn callback_fn, void* callback_arg); +err_t smtp_send_mail_static(const char *from, const char* to, const char* subject, const char* body, + smtp_result_fn callback_fn, void* callback_arg); +void smtp_send_mail_int(void *arg); +#if LWIP_DEBUG +const char* smtp_result_str(u8_t smtp_result); +#endif + +#endif /* __SMTP_H__ */ diff --git a/src/lwip-1.4.1/apps/snmp_private_mib/lwip_prvmib.c b/src/lwip-1.4.1/apps/snmp_private_mib/lwip_prvmib.c new file mode 100644 index 0000000..3541b9d --- /dev/null +++ b/src/lwip-1.4.1/apps/snmp_private_mib/lwip_prvmib.c @@ -0,0 +1,604 @@ +/** + * @file + * lwip Private MIB + * + * @todo create MIB file for this example + * @note the lwip enterprise tree root (26381) is owned by the lwIP project. + * It is NOT allowed to allocate new objects under this ID (26381) without our, + * the lwip developers, permission! + * + * Please apply for your own ID with IANA: http://www.iana.org/numbers.html + * + * lwip OBJECT IDENTIFIER ::= { enterprises 26381 } + * example OBJECT IDENTIFIER ::= { lwip 1 } + */ + +/* + * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * Author: Christiaan Simons + */ + +#include "private_mib.h" + +#if LWIP_SNMP + +/** Directory where the sensor files are */ +#define SENSORS_DIR "w:\\sensors" +/** Set to 1 to read sensor values from files (in directory defined by SENSORS_DIR) */ +#define SENSORS_USE_FILES 0 +/** Set to 1 to search sensor files at startup (in directory defined by SENSORS_DIR) */ +#define SENSORS_SEARCH_FILES 0 + +#if SENSORS_SEARCH_FILES +#include +#include +#include +#include +#include +#include +#endif /* SENSORS_SEARCH_FILES */ + +#include +#include + +#include "lwip/snmp_msg.h" +#include "lwip/snmp_asn1.h" + +#if !SENSORS_USE_FILES || !SENSORS_SEARCH_FILES +/** When not using & searching files, defines the number of sensors */ +#define SENSOR_COUNT 2 +#endif /* !SENSORS_USE_FILES || !SENSORS_SEARCH_FILES */ +#if !SENSORS_USE_FILES +/** When not using files, contains the values of the sensors */ +s32_t sensor_values[SENSOR_COUNT]; +#endif /* !SENSORS_USE_FILES */ + +/* + This example presents a table for a few (at most 10) sensors. + Sensor detection takes place at initialization (once only). + Sensors may and can not be added or removed after agent + has started. Note this is only a limitation of this crude example, + the agent does support dynamic object insertions and removals. + + You'll need to manually create a directory called "sensors" and + a few single line text files with an integer temperature value. + The files must be called [0..9].txt. + + ./sensors/0.txt [content: 20] + ./sensors/3.txt [content: 75] + + The sensor values may be changed in runtime by editing the + text files in the "sensors" directory. +*/ + + +#define SENSOR_MAX 10 +#define SENSOR_NAME_LEN 20 + +struct sensor_inf +{ + char sensor_files[SENSOR_MAX][SENSOR_NAME_LEN + 1]; + /* (Sparse) list of sensors (table index), + the actual "hot insertion" is done in lwip_privmib_init() */ + struct mib_list_rootnode sensor_list_rn; +}; + +struct sensor_inf sensor_addr_inf = +{ + {{0}}, + { + NULL, + NULL, + NULL, + NULL, + MIB_NODE_LR, + 0, + NULL, + NULL, + 0 + } +}; + + +static u16_t sensorentry_length(void* addr_inf, u8_t level); +static s32_t sensorentry_idcmp(void* addr_inf, u8_t level, u16_t idx, s32_t sub_id); +static void sensorentry_get_subid(void* addr_inf, u8_t level, u16_t idx, s32_t *sub_id); + +static void sensorentry_get_object_def_q(void* addr_inf, u8_t rid, u8_t ident_len, s32_t *ident); +static void sensorentry_get_object_def_a(u8_t rid, u8_t ident_len, s32_t *ident, struct obj_def *od); +static void sensorentry_get_object_def_pc(u8_t rid, u8_t ident_len, s32_t *ident); +static void sensorentry_get_value_q(u8_t rid, struct obj_def *od); +static void sensorentry_get_value_a(u8_t rid, struct obj_def *od, u16_t len, void *value); +static void sensorentry_get_value_pc(u8_t rid, struct obj_def *od); +static void sensorentry_set_test_q(u8_t rid, struct obj_def *od); +static u8_t sensorentry_set_test_a(u8_t rid, struct obj_def *od, u16_t len, void *value); +static void sensorentry_set_test_pc(u8_t rid, struct obj_def *od); +static void sensorentry_set_value_q(u8_t rid, struct obj_def *od, u16_t len, void *value); +static void sensorentry_set_value_a(u8_t rid, struct obj_def *od, u16_t len, void *value); +static void sensorentry_set_value_pc(u8_t rid, struct obj_def *od); + +/* sensorentry .1.3.6.1.4.1.26381.1.1.1 (.level0.level1) + where level 0 is the object identifier (temperature) and level 1 the index */ +static struct mib_external_node sensorentry = { + &noleafs_get_object_def, + &noleafs_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_EX, + 0, + &sensor_addr_inf, + /* 0 tree_levels (empty table) at power-up, + 2 when one or more sensors are detected */ + 0, + &sensorentry_length, + &sensorentry_idcmp, + &sensorentry_get_subid, + + &sensorentry_get_object_def_q, + &sensorentry_get_value_q, + &sensorentry_set_test_q, + &sensorentry_set_value_q, + + &sensorentry_get_object_def_a, + &sensorentry_get_value_a, + &sensorentry_set_test_a, + &sensorentry_set_value_a, + + &sensorentry_get_object_def_pc, + &sensorentry_get_value_pc, + &sensorentry_set_test_pc, + &sensorentry_set_value_pc +}; + +/* sensortable .1.3.6.1.4.1.26381.1.1 */ +static const s32_t sensortable_ids[1] = { 1 }; +static struct mib_node* const sensortable_nodes[1] = { + (struct mib_node* const)&sensorentry +}; +static const struct mib_array_node sensortable = { + &noleafs_get_object_def, + &noleafs_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_AR, + 1, + sensortable_ids, + sensortable_nodes +}; + +/* example .1.3.6.1.4.1.26381.1 */ +static const s32_t example_ids[1] = { 1 }; +static struct mib_node* const example_nodes[1] = { + (struct mib_node* const)&sensortable +}; +static const struct mib_array_node example = { + &noleafs_get_object_def, + &noleafs_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_AR, + 1, + example_ids, + example_nodes +}; + +/* lwip .1.3.6.1.4.1.26381 */ +static const s32_t lwip_ids[1] = { 1 }; +static struct mib_node* const lwip_nodes[1] = { (struct mib_node* const)&example }; +static const struct mib_array_node lwip = { + &noleafs_get_object_def, + &noleafs_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_AR, + 1, + lwip_ids, + lwip_nodes +}; + +/* enterprises .1.3.6.1.4.1 */ +static const s32_t enterprises_ids[1] = { 26381 }; +static struct mib_node* const enterprises_nodes[1] = { (struct mib_node* const)&lwip }; +static const struct mib_array_node enterprises = { + &noleafs_get_object_def, + &noleafs_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_AR, + 1, + enterprises_ids, + enterprises_nodes +}; + +/* private .1.3.6.1.4 */ +static const s32_t private_ids[1] = { 1 }; +static struct mib_node* const private_nodes[1] = { (struct mib_node* const)&enterprises }; +const struct mib_array_node mib_private = { + &noleafs_get_object_def, + &noleafs_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_AR, + 1, + private_ids, + private_nodes +}; + + +/** + * Initialises this private MIB before use. + * @see main.c + */ +void +lwip_privmib_init(void) +{ +#if SENSORS_USE_FILES && SENSORS_SEARCH_FILES + char *buf, *ebuf, *cp; + size_t bufsize; + int nbytes; + struct stat sb; + struct dirent *dp; + int fd; +#else /* SENSORS_USE_FILES && SENSORS_SEARCH_FILES */ + int i; +#endif /* SENSORS_USE_FILES && SENSORS_SEARCH_FILES */ + + printf("SNMP private MIB start, detecting sensors.\n"); + +#if SENSORS_USE_FILES && SENSORS_SEARCH_FILES + /* look for sensors in sensors directory */ + fd = open(SENSORS_DIR, O_RDONLY); + if (fd > -1) + { + fstat(fd, &sb); + bufsize = sb.st_size; + if (bufsize < sb.st_blksize) + { + bufsize = sb.st_blksize; + } + buf = malloc(bufsize); + if (buf != NULL) + { + do + { + long base; + + nbytes = getdirentries(fd, buf, bufsize, &base); + if (nbytes > 0) + { + ebuf = buf + nbytes; + cp = buf; + while (cp < ebuf) + { + dp = (struct dirent *)cp; + if (isdigit(dp->d_name[0])) + { + struct mib_list_node *dummy; + unsigned char index; + + index = dp->d_name[0] - '0'; + snmp_mib_node_insert(&sensor_addr_inf.sensor_list_rn,index,&dummy); + + strncpy(&sensor_addr_inf.sensor_files[index][0],dp->d_name,SENSOR_NAME_LEN); + printf("%s\n", sensor_addr_inf.sensor_files[index]); + } + cp += dp->d_reclen; + } + } + } + while (nbytes > 0); + + free(buf); + } + close(fd); + } +#else /* SENSORS_USE_FILES && SENSORS_SEARCH_FILES */ + for (i = 0; i < SENSOR_COUNT; i++) { + struct mib_list_node *dummy; + s32_t index = i; + char name[256]; + sprintf(name, "%d.txt", i); + + snmp_mib_node_insert(&sensor_addr_inf.sensor_list_rn, index, &dummy); + + strncpy(&sensor_addr_inf.sensor_files[index][0], name, SENSOR_NAME_LEN); + printf("%s\n", sensor_addr_inf.sensor_files[index]); +#if !SENSORS_USE_FILES + /* initialize sensor value to != zero */ + sensor_values[i] = 11 * (i+1); +#endif /* !SENSORS_USE_FILES */ + } +#endif /* SENSORS_USE_FILE && SENSORS_SEARCH_FILES */ + if (sensor_addr_inf.sensor_list_rn.count != 0) + { + /* enable sensor table, 2 tree_levels under this node + one for the registers and one for the index */ + sensorentry.tree_levels = 2; + } +} + + +static u16_t +sensorentry_length(void* addr_inf, u8_t level) +{ + struct sensor_inf *sensors = (struct sensor_inf *)addr_inf; + + if (level == 0) + { + /* one object (temperature) */ + return 1; + } + else if (level == 1) + { + /* number of sensor indexes */ + return sensors->sensor_list_rn.count; + } + else + { + return 0; + } +} + +static s32_t +sensorentry_idcmp(void* addr_inf, u8_t level, u16_t idx, s32_t sub_id) +{ + struct sensor_inf *sensors = (struct sensor_inf *)addr_inf; + + if (level == 0) + { + return ((s32_t)(idx + 1) - sub_id); + } + else if (level == 1) + { + struct mib_list_node *ln; + u16_t i; + + i = 0; + ln = sensors->sensor_list_rn.head; + while (i < idx) + { + i++; + ln = ln->next; + } + LWIP_ASSERT("ln != NULL", ln != NULL); + return (ln->objid - sub_id); + } + else + { + return -1; + } +} + +static void +sensorentry_get_subid(void* addr_inf, u8_t level, u16_t idx, s32_t *sub_id) +{ + struct sensor_inf *sensors = (struct sensor_inf *)addr_inf; + + if (level == 0) + { + *sub_id = idx + 1; + } + else if (level == 1) + { + struct mib_list_node *ln; + u16_t i; + + i = 0; + ln = sensors->sensor_list_rn.head; + while (i < idx) + { + i++; + ln = ln->next; + } + LWIP_ASSERT("ln != NULL", ln != NULL); + *sub_id = ln->objid; + } +} + +/** + * Async question for object definition + */ +static void +sensorentry_get_object_def_q(void* addr_inf, u8_t rid, u8_t ident_len, s32_t *ident) +{ + s32_t sensor_register, sensor_address; + + LWIP_UNUSED_ARG(addr_inf); + LWIP_UNUSED_ARG(rid); + + ident_len += 1; + ident -= 1; + + /* send request */ + sensor_register = ident[0]; + sensor_address = ident[1]; + LWIP_DEBUGF(SNMP_MIB_DEBUG,("sensor_request reg=%"S32_F" addr=%"S32_F"\n", + sensor_register, sensor_address)); + /* fake async quesion/answer */ + snmp_msg_event(rid); +} + +static void +sensorentry_get_object_def_a(u8_t rid, u8_t ident_len, s32_t *ident, struct obj_def *od) +{ + LWIP_UNUSED_ARG(rid); + + /* return to object name, adding index depth (1) */ + ident_len += 1; + ident -= 1; + if (ident_len == 2) + { + od->id_inst_len = ident_len; + od->id_inst_ptr = ident; + + od->instance = MIB_OBJECT_TAB; + od->access = MIB_OBJECT_READ_WRITE; + od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG); + od->v_len = sizeof(s32_t); + } + else + { + LWIP_DEBUGF(SNMP_MIB_DEBUG,("sensorentry_get_object_def_a: no scalar\n")); + od->instance = MIB_OBJECT_NONE; + } +} + +static void +sensorentry_get_object_def_pc(u8_t rid, u8_t ident_len, s32_t *ident) +{ + LWIP_UNUSED_ARG(rid); + LWIP_UNUSED_ARG(ident_len); + LWIP_UNUSED_ARG(ident); + /* nop */ +} + +static void +sensorentry_get_value_q(u8_t rid, struct obj_def *od) +{ + LWIP_UNUSED_ARG(od); + + /* fake async quesion/answer */ + snmp_msg_event(rid); +} + +static void +sensorentry_get_value_a(u8_t rid, struct obj_def *od, u16_t len, void *value) +{ + s32_t i; + s32_t *temperature = (s32_t *)value; +#if SENSORS_USE_FILES + FILE* sensf; + char senspath[sizeof(SENSORS_DIR)+1+SENSOR_NAME_LEN+1] = SENSORS_DIR"/"; +#endif /* SENSORS_USE_FILES */ + + LWIP_UNUSED_ARG(rid); + LWIP_UNUSED_ARG(len); + + i = od->id_inst_ptr[1]; +#if SENSORS_USE_FILES + strncpy(&senspath[sizeof(SENSORS_DIR)], + sensor_addr_inf.sensor_files[i], + SENSOR_NAME_LEN); + sensf = fopen(senspath,"r"); + if (sensf != NULL) + { + fscanf(sensf,"%"S32_F,temperature); + fclose(sensf); + } +#else /* SENSORS_USE_FILES */ + if (i <= SENSOR_COUNT) { + *temperature = sensor_values[i]; + } +#endif /* SENSORS_USE_FILES */ +} + +static void +sensorentry_get_value_pc(u8_t rid, struct obj_def *od) +{ + LWIP_UNUSED_ARG(rid); + LWIP_UNUSED_ARG(od); + /* nop */ +} + +static void +sensorentry_set_test_q(u8_t rid, struct obj_def *od) +{ + LWIP_UNUSED_ARG(od); + /* fake async quesion/answer */ + snmp_msg_event(rid); +} + +static u8_t +sensorentry_set_test_a(u8_t rid, struct obj_def *od, u16_t len, void *value) +{ + LWIP_UNUSED_ARG(rid); + LWIP_UNUSED_ARG(od); + LWIP_UNUSED_ARG(len); + LWIP_UNUSED_ARG(value); + /* sensors are read-only */ + return 1; /* 0 -> read only, != 0 -> read/write */ +} + +static void +sensorentry_set_test_pc(u8_t rid, struct obj_def *od) +{ + LWIP_UNUSED_ARG(rid); + LWIP_UNUSED_ARG(od); + /* nop */ +} + +static void +sensorentry_set_value_q(u8_t rid, struct obj_def *od, u16_t len, void *value) +{ + LWIP_UNUSED_ARG(rid); + LWIP_UNUSED_ARG(od); + LWIP_UNUSED_ARG(len); + LWIP_UNUSED_ARG(value); + /* fake async quesion/answer */ + snmp_msg_event(rid); +} + +static void +sensorentry_set_value_a(u8_t rid, struct obj_def *od, u16_t len, void *value) +{ + s32_t i; + s32_t *temperature = (s32_t *)value; +#if SENSORS_USE_FILES + FILE* sensf; + char senspath[sizeof(SENSORS_DIR)+1+SENSOR_NAME_LEN+1] = SENSORS_DIR"/"; +#endif /* SENSORS_USE_FILES */ + + LWIP_UNUSED_ARG(rid); + LWIP_UNUSED_ARG(len); + + i = od->id_inst_ptr[1]; +#if SENSORS_USE_FILES + strncpy(&senspath[sizeof(SENSORS_DIR)], + sensor_addr_inf.sensor_files[i], + SENSOR_NAME_LEN); + sensf = fopen(senspath, "w"); + if (sensf != NULL) + { + fprintf(sensf, "%"S32_F, temperature); + fclose(sensf); + } +#else /* SENSORS_USE_FILES */ + if (i <= SENSOR_COUNT) { + sensor_values[i] = *temperature; + } +#endif /* SENSORS_USE_FILES */ +} + +static void +sensorentry_set_value_pc(u8_t rid, struct obj_def *od) +{ + LWIP_UNUSED_ARG(rid); + LWIP_UNUSED_ARG(od); + /* nop */ +} + +#endif /* LWIP_SNMP */ diff --git a/src/lwip-1.4.1/apps/snmp_private_mib/private_mib.h b/src/lwip-1.4.1/apps/snmp_private_mib/private_mib.h new file mode 100644 index 0000000..b9a4852 --- /dev/null +++ b/src/lwip-1.4.1/apps/snmp_private_mib/private_mib.h @@ -0,0 +1,28 @@ +/** + * @file + * Exports Private lwIP MIB + */ + +#ifndef __LWIP_PRIVATE_MIB_H__ +#define __LWIP_PRIVATE_MIB_H__ + +#include "arch/cc.h" +#include "lwip/opt.h" + +#if LWIP_SNMP +#include "lwip/snmp_structs.h" +extern const struct mib_array_node mib_private; + +/** @todo remove this?? */ +struct private_msg +{ + u8_t dummy; +}; + +void lwip_privmib_init(void); + +#define SNMP_PRIVATE_MIB_INIT() lwip_privmib_init() + +#endif + +#endif diff --git a/src/lwip-1.4.1/apps/sntp/sntp.c b/src/lwip-1.4.1/apps/sntp/sntp.c new file mode 100644 index 0000000..9ce0ff8 --- /dev/null +++ b/src/lwip-1.4.1/apps/sntp/sntp.c @@ -0,0 +1,606 @@ +/** + * @file + * SNTP client module + * + * This is simple "SNTP" client for the lwIP raw API. + * It is a minimal implementation of SNTPv4 as specified in RFC 4330. + * + * For a list of some public NTP servers, see this link : + * http://support.ntp.org/bin/view/Servers/NTPPoolServers + * + * @todo: + * - set/change servers at runtime + * - complete SNTP_CHECK_RESPONSE checks 3 and 4 + * - support broadcast/multicast mode? + */ + +/* + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Simon Goldschmidt (lwIP raw API part) + */ + +#include "lwip/opt.h" + +#include "sntp.h" + +#include "lwip/timers.h" +#include "lwip/udp.h" +#include "lwip/dns.h" +#include "lwip/ip_addr.h" +#include "lwip/pbuf.h" + +#include +#include + +#if LWIP_UDP + +/** + * SNTP_DEBUG: Enable debugging for SNTP. + */ +#ifndef SNTP_DEBUG +#define SNTP_DEBUG LWIP_DBG_OFF +#endif + +/** SNTP server port */ +#ifndef SNTP_PORT +#define SNTP_PORT 123 +#endif + +/** Set this to 1 to allow SNTP_SERVER_ADDRESS to be a DNS name */ +#ifndef SNTP_SERVER_DNS +#define SNTP_SERVER_DNS 0 +#endif + +/** Set this to 1 to support more than one server */ +#ifndef SNTP_SUPPORT_MULTIPLE_SERVERS +#define SNTP_SUPPORT_MULTIPLE_SERVERS 0 +#endif + +/** \def SNTP_SERVER_ADDRESS + * \brief SNTP server address: + * - as IPv4 address in "u32_t" format + * - as a DNS name if SNTP_SERVER_DNS is set to 1 + * May contain multiple server names (e.g. "pool.ntp.org","second.time.server") + */ +#ifndef SNTP_SERVER_ADDRESS +#if SNTP_SERVER_DNS +#define SNTP_SERVER_ADDRESS "pool.ntp.org" +#else +#define SNTP_SERVER_ADDRESS "213.161.194.93" /* pool.ntp.org */ +#endif +#endif + +/** Sanity check: + * Define this to + * - 0 to turn off sanity checks (default; smaller code) + * - >= 1 to check address and port of the response packet to ensure the + * response comes from the server we sent the request to. + * - >= 2 to check returned Originate Timestamp against Transmit Timestamp + * sent to the server (to ensure response to older request). + * - >= 3 @todo: discard reply if any of the LI, Stratum, or Transmit Timestamp + * fields is 0 or the Mode field is not 4 (unicast) or 5 (broadcast). + * - >= 4 @todo: to check that the Root Delay and Root Dispersion fields are each + * greater than or equal to 0 and less than infinity, where infinity is + * currently a cozy number like one second. This check avoids using a + * server whose synchronization source has expired for a very long time. + */ +#ifndef SNTP_CHECK_RESPONSE +#define SNTP_CHECK_RESPONSE 0 +#endif + +/** According to the RFC, this shall be a random delay + * between 1 and 5 minutes (in milliseconds) to prevent load peaks. + * This can be defined to a random generation function, + * which must return the delay in milliseconds as u32_t. + * Turned off by default. + */ +#ifndef SNTP_STARTUP_DELAY +#define SNTP_STARTUP_DELAY 0 +#endif + +/** SNTP receive timeout - in milliseconds + * Also used as retry timeout - this shouldn't be too low. + * Default is 3 seconds. + */ +#ifndef SNTP_RECV_TIMEOUT +#define SNTP_RECV_TIMEOUT 3000 +#endif + +/** SNTP update delay - in milliseconds + * Default is 1 hour. + */ +#ifndef SNTP_UPDATE_DELAY +#define SNTP_UPDATE_DELAY 3600000 +#endif +#if (SNTP_UPDATE_DELAY < 15000) && !SNTP_SUPPRESS_DELAY_CHECK +#error "SNTPv4 RFC 4330 enforces a minimum update time of 15 seconds!" +#endif + +/** SNTP macro to change system time and/or the update the RTC clock */ +#ifndef SNTP_SET_SYSTEM_TIME +#define SNTP_SET_SYSTEM_TIME(sec) ((void)sec) +#endif + +/** SNTP macro to change system time including microseconds */ +#ifdef SNTP_SET_SYSTEM_TIME_US +#define SNTP_CALC_TIME_US 1 +#define SNTP_RECEIVE_TIME_SIZE 2 +#else +#define SNTP_SET_SYSTEM_TIME_US(sec, us) +#define SNTP_CALC_TIME_US 0 +#define SNTP_RECEIVE_TIME_SIZE 1 +#endif + +/** SNTP macro to get system time, used with SNTP_CHECK_RESPONSE >= 2 + * to send in request and compare in response. + */ +#ifndef SNTP_GET_SYSTEM_TIME +#define SNTP_GET_SYSTEM_TIME(sec, us) do { (sec) = 0; (us) = 0; } while(0) +#endif + +/** Default retry timeout (in milliseconds) if the response + * received is invalid. + * This is doubled with each retry until SNTP_RETRY_TIMEOUT_MAX is reached. + */ +#ifndef SNTP_RETRY_TIMEOUT +#define SNTP_RETRY_TIMEOUT SNTP_RECV_TIMEOUT +#endif + +/** Maximum retry timeout (in milliseconds). */ +#ifndef SNTP_RETRY_TIMEOUT_MAX +#define SNTP_RETRY_TIMEOUT_MAX (SNTP_RETRY_TIMEOUT * 10) +#endif + +/** Increase retry timeout with every retry sent + * Default is on to conform to RFC. + */ +#ifndef SNTP_RETRY_TIMEOUT_EXP +#define SNTP_RETRY_TIMEOUT_EXP 1 +#endif + +/* the various debug levels for this file */ +#define SNTP_DEBUG_TRACE (SNTP_DEBUG | LWIP_DBG_TRACE) +#define SNTP_DEBUG_STATE (SNTP_DEBUG | LWIP_DBG_STATE) +#define SNTP_DEBUG_WARN (SNTP_DEBUG | LWIP_DBG_LEVEL_WARNING) +#define SNTP_DEBUG_WARN_STATE (SNTP_DEBUG | LWIP_DBG_LEVEL_WARNING | LWIP_DBG_STATE) +#define SNTP_DEBUG_SERIOUS (SNTP_DEBUG | LWIP_DBG_LEVEL_SERIOUS) + +#define SNTP_ERR_KOD 1 + +/* SNTP protocol defines */ +#define SNTP_MSG_LEN 48 + +#define SNTP_OFFSET_LI_VN_MODE 0 +#define SNTP_LI_MASK 0xC0 +#define SNTP_LI_NO_WARNING 0x00 +#define SNTP_LI_LAST_MINUTE_61_SEC 0x01 +#define SNTP_LI_LAST_MINUTE_59_SEC 0x02 +#define SNTP_LI_ALARM_CONDITION 0x03 /* (clock not synchronized) */ + +#define SNTP_VERSION_MASK 0x38 +#define SNTP_VERSION (4/* NTP Version 4*/<<3) + +#define SNTP_MODE_MASK 0x07 +#define SNTP_MODE_CLIENT 0x03 +#define SNTP_MODE_SERVER 0x04 +#define SNTP_MODE_BROADCAST 0x05 + +#define SNTP_OFFSET_STRATUM 1 +#define SNTP_STRATUM_KOD 0x00 + +#define SNTP_OFFSET_ORIGINATE_TIME 24 +#define SNTP_OFFSET_RECEIVE_TIME 32 +#define SNTP_OFFSET_TRANSMIT_TIME 40 + +/* number of seconds between 1900 and 1970 */ +#define DIFF_SEC_1900_1970 (2208988800UL) + +/** + * SNTP packet format (without optional fields) + * Timestamps are coded as 64 bits: + * - 32 bits seconds since Jan 01, 1970, 00:00 + * - 32 bits seconds fraction (0-padded) + * For future use, if the MSB in the seconds part is set, seconds are based + * on Feb 07, 2036, 06:28:16. + */ +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct sntp_msg { + PACK_STRUCT_FIELD(u8_t li_vn_mode); + PACK_STRUCT_FIELD(u8_t stratum); + PACK_STRUCT_FIELD(u8_t poll); + PACK_STRUCT_FIELD(u8_t precision); + PACK_STRUCT_FIELD(u32_t root_delay); + PACK_STRUCT_FIELD(u32_t root_dispersion); + PACK_STRUCT_FIELD(u32_t reference_identifier); + PACK_STRUCT_FIELD(u32_t reference_timestamp[2]); + PACK_STRUCT_FIELD(u32_t originate_timestamp[2]); + PACK_STRUCT_FIELD(u32_t receive_timestamp[2]); + PACK_STRUCT_FIELD(u32_t transmit_timestamp[2]); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +/* function prototypes */ +static void sntp_request(void *arg); + +/** The UDP pcb used by the SNTP client */ +static struct udp_pcb* sntp_pcb; +/** Addresses of servers */ +static char* sntp_server_addresses[] = {SNTP_SERVER_ADDRESS}; +#if SNTP_SUPPORT_MULTIPLE_SERVERS +/** The currently used server (initialized to 0) */ +static u8_t sntp_current_server; +static u8_t sntp_num_servers = sizeof(sntp_server_addresses)/sizeof(char*); +#else /* SNTP_SUPPORT_MULTIPLE_SERVERS */ +#define sntp_current_server 0 +#endif /* SNTP_SUPPORT_MULTIPLE_SERVERS */ + +#if SNTP_RETRY_TIMEOUT_EXP +#define SNTP_RESET_RETRY_TIMEOUT() sntp_retry_timeout = SNTP_RETRY_TIMEOUT +/** Retry time, initialized with SNTP_RETRY_TIMEOUT and doubled with each retry. */ +static u32_t sntp_retry_timeout; +#else /* SNTP_RETRY_TIMEOUT_EXP */ +#define SNTP_RESET_RETRY_TIMEOUT() +#define sntp_retry_timeout SNTP_RETRY_TIMEOUT +#endif /* SNTP_RETRY_TIMEOUT_EXP */ + +#if SNTP_CHECK_RESPONSE >= 1 +/** Saves the last server address to compare with response */ +static ip_addr_t sntp_last_server_address; +#endif /* SNTP_CHECK_RESPONSE >= 1 */ + +#if SNTP_CHECK_RESPONSE >= 2 +/** Saves the last timestamp sent (which is sent back by the server) + * to compare against in response */ +static u32_t sntp_last_timestamp_sent[2]; +#endif /* SNTP_CHECK_RESPONSE >= 2 */ + +/** + * SNTP processing of received timestamp + */ +static void +sntp_process(u32_t *receive_timestamp) +{ + /* convert SNTP time (1900-based) to unix GMT time (1970-based) + * @todo: if MSB is 1, SNTP time is 2036-based! + */ + time_t t = (ntohl(receive_timestamp[0]) - DIFF_SEC_1900_1970); + +#if SNTP_CALC_TIME_US + u32_t us = ntohl(receive_timestamp[1]) / 4295; + SNTP_SET_SYSTEM_TIME_US(t, us); + /* display local time from GMT time */ + LWIP_DEBUGF(SNTP_DEBUG_TRACE, ("sntp_process: %s, %"U32_F" us", ctime(&t), us)); + +#else /* SNTP_CALC_TIME_US */ + + /* change system time and/or the update the RTC clock */ + SNTP_SET_SYSTEM_TIME(t); + /* display local time from GMT time */ + LWIP_DEBUGF(SNTP_DEBUG_TRACE, ("sntp_process: %s", ctime(&t))); +#endif /* SNTP_CALC_TIME_US */ +} + +/** + * Initialize request struct to be sent to server. + */ +static void +sntp_initialize_request(struct sntp_msg *req) +{ + memset(req, 0, SNTP_MSG_LEN); + req->li_vn_mode = SNTP_LI_NO_WARNING | SNTP_VERSION | SNTP_MODE_CLIENT; + +#if SNTP_CHECK_RESPONSE >= 2 + { + u32_t sntp_time_sec, sntp_time_us; + /* fill in transmit timestamp and save it in 'sntp_last_timestamp_sent' */ + SNTP_GET_SYSTEM_TIME(sntp_time_sec, sntp_time_us); + sntp_last_timestamp_sent[0] = htonl(sntp_time_sec + DIFF_SEC_1900_1970); + req->transmit_timestamp[0] = sntp_last_timestamp_sent[0]; + /* we send/save us instead of fraction to be faster... */ + sntp_last_timestamp_sent[1] = htonl(sntp_time_us); + req->transmit_timestamp[1] = sntp_last_timestamp_sent[1]; + } +#endif /* SNTP_CHECK_RESPONSE >= 2 */ +} + +/** + * Retry: send a new request (and increase retry timeout). + * + * @param arg is unused (only necessary to conform to sys_timeout) + */ +static void +sntp_retry(void* arg) +{ + LWIP_UNUSED_ARG(arg); + + LWIP_DEBUGF(SNTP_DEBUG_STATE, ("sntp_retry: Next request will be sent in %"U32_F" ms\n", + sntp_retry_timeout)); + + /* set up a timer to send a retry and increase the retry delay */ + sys_timeout(sntp_retry_timeout, sntp_request, NULL); + +#if SNTP_RETRY_TIMEOUT_EXP + { + u32_t new_retry_timeout; + /* increase the timeout for next retry */ + new_retry_timeout = sntp_retry_timeout << 1; + /* limit to maximum timeout and prevent overflow */ + if ((new_retry_timeout <= SNTP_RETRY_TIMEOUT_MAX) && + (new_retry_timeout > sntp_retry_timeout)) { + sntp_retry_timeout = new_retry_timeout; + } + } +#endif /* SNTP_RETRY_TIMEOUT_EXP */ +} + +#if SNTP_SUPPORT_MULTIPLE_SERVERS +/** + * If Kiss-of-Death is received (or another packet parsing error), + * try the next server or retry the current server and increase the retry + * timeout if only one server is available. + * + * @param arg is unused (only necessary to conform to sys_timeout) + */ +static void +sntp_try_next_server(void* arg) +{ + LWIP_UNUSED_ARG(arg); + + if (sntp_num_servers > 1) { + /* new server: reset retry timeout */ + SNTP_RESET_RETRY_TIMEOUT(); + sntp_current_server++; + if (sntp_current_server >= sntp_num_servers) { + sntp_current_server = 0; + } + LWIP_DEBUGF(SNTP_DEBUG_STATE, ("sntp_try_next_server: Sending request to server %"U16_F"\n", + (u16_t)sntp_current_server)); + /* instantly send a request to the next server */ + sntp_request(NULL); + } else { + sntp_retry(NULL); + } +} +#else /* SNTP_SUPPORT_MULTIPLE_SERVERS */ +/* Always retry on error if only one server is supported */ +#define sntp_try_next_server sntp_retry +#endif /* SNTP_SUPPORT_MULTIPLE_SERVERS */ + +/** UDP recv callback for the sntp pcb */ +static void +sntp_recv(void *arg, struct udp_pcb* pcb, struct pbuf *p, ip_addr_t *addr, u16_t port) +{ + u8_t mode; + u8_t stratum; + u32_t receive_timestamp[SNTP_RECEIVE_TIME_SIZE]; + err_t err; + + LWIP_UNUSED_ARG(arg); + LWIP_UNUSED_ARG(pcb); + + /* packet received: stop retry timeout */ + sys_untimeout(sntp_try_next_server, NULL); + sys_untimeout(sntp_request, NULL); + + err = ERR_ARG; +#if SNTP_CHECK_RESPONSE >= 1 + /* check server address and port */ + if (ip_addr_cmp(addr, &sntp_last_server_address) && + (port == SNTP_PORT)) +#else /* SNTP_CHECK_RESPONSE >= 1 */ + LWIP_UNUSED_ARG(addr); + LWIP_UNUSED_ARG(port); +#endif /* SNTP_CHECK_RESPONSE >= 1 */ + { + /* process the response */ + if (p->tot_len == SNTP_MSG_LEN) { + pbuf_copy_partial(p, &mode, 1, SNTP_OFFSET_LI_VN_MODE); + mode &= SNTP_MODE_MASK; + /* if this is a SNTP response... */ + if ((mode == SNTP_MODE_SERVER) || + (mode == SNTP_MODE_BROADCAST)) { + pbuf_copy_partial(p, &stratum, 1, SNTP_OFFSET_STRATUM); + if (stratum == SNTP_STRATUM_KOD) { + /* Kiss-of-death packet. Use another server or increase UPDATE_DELAY. */ + err = SNTP_ERR_KOD; + LWIP_DEBUGF(SNTP_DEBUG_STATE, ("sntp_recv: Received Kiss-of-Death\n")); + } else { +#if SNTP_CHECK_RESPONSE >= 2 + /* check originate_timetamp against sntp_last_timestamp_sent */ + u32_t originate_timestamp[2]; + pbuf_copy_partial(p, &originate_timestamp, 8, SNTP_OFFSET_ORIGINATE_TIME); + if ((originate_timestamp[0] != sntp_last_timestamp_sent[0]) || + (originate_timestamp[1] != sntp_last_timestamp_sent[1])) + { + LWIP_DEBUGF(SNTP_DEBUG_WARN, ("sntp_recv: Invalid originate timestamp in response\n")); + } else +#endif /* SNTP_CHECK_RESPONSE >= 2 */ + /* @todo: add code for SNTP_CHECK_RESPONSE >= 3 and >= 4 here */ + { + /* correct answer */ + err = ERR_OK; + pbuf_copy_partial(p, &receive_timestamp, SNTP_RECEIVE_TIME_SIZE * 4, SNTP_OFFSET_RECEIVE_TIME); + } + } + } else { + LWIP_DEBUGF(SNTP_DEBUG_WARN, ("sntp_recv: Invalid mode in response: %"U16_F"\n", (u16_t)mode)); + } + } else { + LWIP_DEBUGF(SNTP_DEBUG_WARN, ("sntp_recv: Invalid packet length: %"U16_F"\n", p->tot_len)); + } + } + pbuf_free(p); + if (err == ERR_OK) { + /* Correct response, reset retry timeout */ + SNTP_RESET_RETRY_TIMEOUT(); + + sntp_process(receive_timestamp); + + /* Set up timeout for next request */ + sys_timeout((u32_t)SNTP_UPDATE_DELAY, sntp_request, NULL); + LWIP_DEBUGF(SNTP_DEBUG_STATE, ("sntp_recv: Scheduled next time request: %"U32_F" ms\n", + (u32_t)SNTP_UPDATE_DELAY)); + } else if (err == SNTP_ERR_KOD) { + /* Kiss-of-death packet. Use another server or increase UPDATE_DELAY. */ + sntp_try_next_server(NULL); + } else { + /* another error, try the same server again */ + sntp_retry(NULL); + } +} + +/** Actually send an sntp request to a server. + * + * @param server_addr resolved IP address of the SNTP server + */ +static void +sntp_send_request(ip_addr_t *server_addr) +{ + struct pbuf* p; + p = pbuf_alloc(PBUF_TRANSPORT, SNTP_MSG_LEN, PBUF_RAM); + if (p != NULL) { + struct sntp_msg *sntpmsg = (struct sntp_msg *)p->payload; + LWIP_DEBUGF(SNTP_DEBUG_STATE, ("sntp_send_request: Sending request to server\n")); + /* initialize request message */ + sntp_initialize_request(sntpmsg); + /* send request */ + udp_sendto(sntp_pcb, p, server_addr, SNTP_PORT); + /* free the pbuf after sending it */ + pbuf_free(p); + /* set up receive timeout: try next server or retry on timeout */ + sys_timeout((u32_t)SNTP_RECV_TIMEOUT, sntp_try_next_server, NULL); +#if SNTP_CHECK_RESPONSE >= 1 + /* save server address to verify it in sntp_recv */ + ip_addr_set(&sntp_last_server_address, server_addr); +#endif /* SNTP_CHECK_RESPONSE >= 1 */ + } else { + LWIP_DEBUGF(SNTP_DEBUG_SERIOUS, ("sntp_send_request: Out of memory, trying again in %"U32_F" ms\n", + (u32_t)SNTP_RETRY_TIMEOUT)); + /* out of memory: set up a timer to send a retry */ + sys_timeout((u32_t)SNTP_RETRY_TIMEOUT, sntp_request, NULL); + } +} + +#if SNTP_SERVER_DNS +/** + * DNS found callback when using DNS names as server address. + */ +static void +sntp_dns_found(const char* hostname, ip_addr_t *ipaddr, void *arg) +{ + LWIP_UNUSED_ARG(hostname); + LWIP_UNUSED_ARG(arg); + + if (ipaddr != NULL) { + /* Address resolved, send request */ + LWIP_DEBUGF(SNTP_DEBUG_STATE, ("sntp_dns_found: Server address resolved, sending request\n")); + sntp_send_request(ipaddr); + } else { + /* DNS resolving failed -> try another server */ + LWIP_DEBUGF(SNTP_DEBUG_WARN_STATE, ("sntp_dns_found: Failed to resolve server address resolved, trying next server\n")); + sntp_try_next_server(NULL); + } +} +#endif /* SNTP_SERVER_DNS */ + +/** + * Send out an sntp request. + * + * @param arg is unused (only necessary to conform to sys_timeout) + */ +static void +sntp_request(void *arg) +{ + ip_addr_t sntp_server_address; + err_t err; + + LWIP_UNUSED_ARG(arg); + + /* initialize SNTP server address */ +#if SNTP_SERVER_DNS + err = dns_gethostbyname(sntp_server_addresses[sntp_current_server], &sntp_server_address, + sntp_dns_found, NULL); + if (err == ERR_INPROGRESS) { + /* DNS request sent, wait for sntp_dns_found being called */ + LWIP_DEBUGF(SNTP_DEBUG_STATE, ("sntp_request: Waiting for server address to be resolved.\n")); + return; + } +#else /* SNTP_SERVER_DNS */ + err = ipaddr_aton(sntp_server_addresses[sntp_current_server], &sntp_server_address) + ? ERR_OK : ERR_ARG; + +#endif /* SNTP_SERVER_DNS */ + + if (err == ERR_OK) { + sntp_send_request(&sntp_server_address); + } else { + /* address conversion failed, try another server */ + LWIP_DEBUGF(SNTP_DEBUG_WARN_STATE, ("sntp_request: Invalid server address, trying next server.\n")); + sys_timeout((u32_t)SNTP_RETRY_TIMEOUT, sntp_try_next_server, NULL); + } +} + +/** + * Initialize this module. + * Send out request instantly or after SNTP_STARTUP_DELAY. + */ +void +sntp_init(void) +{ + if (sntp_pcb == NULL) { + SNTP_RESET_RETRY_TIMEOUT(); + sntp_pcb = udp_new(); + LWIP_ASSERT("Failed to allocate udp pcb for sntp client", sntp_pcb != NULL); + if (sntp_pcb != NULL) { + udp_recv(sntp_pcb, sntp_recv, NULL); +#if SNTP_STARTUP_DELAY + sys_timeout((u32_t)SNTP_STARTUP_DELAY, sntp_request, NULL); +#else + sntp_request(NULL); +#endif + } + } +} + +/** + * Stop this module. + */ +void +sntp_stop(void) +{ + if (sntp_pcb != NULL) { + sys_untimeout(sntp_request, NULL); + udp_remove(sntp_pcb); + sntp_pcb = NULL; + } +} +#endif /* LWIP_UDP */ diff --git a/src/lwip-1.4.1/apps/sntp/sntp.h b/src/lwip-1.4.1/apps/sntp/sntp.h new file mode 100644 index 0000000..5331145 --- /dev/null +++ b/src/lwip-1.4.1/apps/sntp/sntp.h @@ -0,0 +1,15 @@ +#ifndef __SNTP_H__ +#define __SNTP_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +void sntp_init(void); +void sntp_stop(void); + +#ifdef __cplusplus +} +#endif + +#endif /* __SNTP_H__ */ diff --git a/src/lwip-1.4.1/apps/socket_examples/socket_examples.c b/src/lwip-1.4.1/apps/socket_examples/socket_examples.c new file mode 100644 index 0000000..d915da1 --- /dev/null +++ b/src/lwip-1.4.1/apps/socket_examples/socket_examples.c @@ -0,0 +1,480 @@ + +#include "socket_examples.h" + +#include "lwip/opt.h" + +#if LWIP_SOCKET + +#include "lwip/sockets.h" +#include "lwip/sys.h" + +#include +#include + +#ifndef SOCK_TARGET_HOST +#define SOCK_TARGET_HOST "192.168.1.1" +#endif + +#ifndef SOCK_TARGET_PORT +#define SOCK_TARGET_PORT 80 +#endif + +/** This is an example function that tests + blocking- and nonblocking connect. */ +static void +sockex_nonblocking_connect(void *arg) +{ + int s; + int ret; + u32_t opt; + struct sockaddr_in addr; + fd_set readset; + fd_set writeset; + fd_set errset; + struct timeval tv; + u32_t ticks_a, ticks_b; + int err; + + LWIP_UNUSED_ARG(arg); + /* set up address to connect to */ + memset(&addr, 0, sizeof(addr)); + addr.sin_len = sizeof(addr); + addr.sin_family = AF_INET; + addr.sin_port = PP_HTONS(SOCK_TARGET_PORT); + addr.sin_addr.s_addr = inet_addr(SOCK_TARGET_HOST); + + /* first try blocking: */ + + /* create the socket */ + s = lwip_socket(AF_INET, SOCK_STREAM, 0); + LWIP_ASSERT("s >= 0", s >= 0); + + /* connect */ + ret = lwip_connect(s, (struct sockaddr*)&addr, sizeof(addr)); + /* should succeed */ + LWIP_ASSERT("ret == 0", ret == 0); + + /* write something */ + ret = lwip_write(s, "test", 4); + LWIP_ASSERT("ret == 4", ret == 4); + + /* close */ + ret = lwip_close(s); + LWIP_ASSERT("ret == 0", ret == 0); + + /* now try nonblocking and close before being connected */ + + /* create the socket */ + s = lwip_socket(AF_INET, SOCK_STREAM, 0); + LWIP_ASSERT("s >= 0", s >= 0); + /* nonblocking */ + opt = lwip_fcntl(s, F_GETFL, 0); + LWIP_ASSERT("ret != -1", ret != -1); + opt |= O_NONBLOCK; + ret = lwip_fcntl(s, F_SETFL, opt); + LWIP_ASSERT("ret != -1", ret != -1); + /* connect */ + ret = lwip_connect(s, (struct sockaddr*)&addr, sizeof(addr)); + /* should have an error: "inprogress" */ + LWIP_ASSERT("ret == -1", ret == -1); + err = errno; + LWIP_ASSERT("errno == EINPROGRESS", err == EINPROGRESS); + /* close */ + ret = lwip_close(s); + LWIP_ASSERT("ret == 0", ret == 0); + /* try to close again, should fail with EBADF */ + ret = lwip_close(s); + LWIP_ASSERT("ret == -1", ret == -1); + err = errno; + LWIP_ASSERT("errno == EBADF", err == EBADF); + printf("closing socket in nonblocking connect succeeded\n"); + + /* now try nonblocking, connect should succeed: + this test only works if it is fast enough, i.e. no breakpoints, please! */ + + /* create the socket */ + s = lwip_socket(AF_INET, SOCK_STREAM, 0); + LWIP_ASSERT("s >= 0", s >= 0); + + /* nonblocking */ + opt = 1; + ret = lwip_ioctl(s, FIONBIO, &opt); + LWIP_ASSERT("ret == 0", ret == 0); + + /* connect */ + ret = lwip_connect(s, (struct sockaddr*)&addr, sizeof(addr)); + /* should have an error: "inprogress" */ + LWIP_ASSERT("ret == -1", ret == -1); + err = errno; + LWIP_ASSERT("errno == EINPROGRESS", err == EINPROGRESS); + + /* write should fail, too */ + ret = lwip_write(s, "test", 4); + LWIP_ASSERT("ret == -1", ret == -1); + err = errno; + LWIP_ASSERT("errno == EINPROGRESS", err == EINPROGRESS); + + FD_ZERO(&readset); + FD_SET(s, &readset); + FD_ZERO(&writeset); + FD_SET(s, &writeset); + FD_ZERO(&errset); + FD_SET(s, &errset); + tv.tv_sec = 0; + tv.tv_usec = 0; + /* select without waiting should fail */ + ret = lwip_select(s + 1, &readset, &writeset, &errset, &tv); + LWIP_ASSERT("ret == 0", ret == 0); + LWIP_ASSERT("!FD_ISSET(s, &writeset)", !FD_ISSET(s, &writeset)); + LWIP_ASSERT("!FD_ISSET(s, &readset)", !FD_ISSET(s, &readset)); + LWIP_ASSERT("!FD_ISSET(s, &errset)", !FD_ISSET(s, &errset)); + + FD_ZERO(&readset); + FD_SET(s, &readset); + FD_ZERO(&writeset); + FD_SET(s, &writeset); + FD_ZERO(&errset); + FD_SET(s, &errset); + ticks_a = sys_now(); + /* select with waiting should succeed */ + ret = lwip_select(s + 1, &readset, &writeset, &errset, NULL); + ticks_b = sys_now(); + LWIP_ASSERT("ret == 1", ret == 1); + LWIP_ASSERT("FD_ISSET(s, &writeset)", FD_ISSET(s, &writeset)); + LWIP_ASSERT("!FD_ISSET(s, &readset)", !FD_ISSET(s, &readset)); + LWIP_ASSERT("!FD_ISSET(s, &errset)", !FD_ISSET(s, &errset)); + + /* now write should succeed */ + ret = lwip_write(s, "test", 4); + LWIP_ASSERT("ret == 4", ret == 4); + + /* close */ + ret = lwip_close(s); + LWIP_ASSERT("ret == 0", ret == 0); + + printf("select() needed %d ticks to return writable\n", ticks_b - ticks_a); + + + /* now try nonblocking to invalid address: + this test only works if it is fast enough, i.e. no breakpoints, please! */ + + /* create the socket */ + s = lwip_socket(AF_INET, SOCK_STREAM, 0); + LWIP_ASSERT("s >= 0", s >= 0); + + /* nonblocking */ + opt = 1; + ret = lwip_ioctl(s, FIONBIO, &opt); + LWIP_ASSERT("ret == 0", ret == 0); + + addr.sin_addr.s_addr++; + + /* connect */ + ret = lwip_connect(s, (struct sockaddr*)&addr, sizeof(addr)); + /* should have an error: "inprogress" */ + LWIP_ASSERT("ret == -1", ret == -1); + err = errno; + LWIP_ASSERT("errno == EINPROGRESS", err == EINPROGRESS); + + /* write should fail, too */ + ret = lwip_write(s, "test", 4); + LWIP_ASSERT("ret == -1", ret == -1); + err = errno; + LWIP_ASSERT("errno == EINPROGRESS", err == EINPROGRESS); + + FD_ZERO(&readset); + FD_SET(s, &readset); + FD_ZERO(&writeset); + FD_SET(s, &writeset); + FD_ZERO(&errset); + FD_SET(s, &errset); + tv.tv_sec = 0; + tv.tv_usec = 0; + /* select without waiting should fail */ + ret = lwip_select(s + 1, &readset, &writeset, &errset, &tv); + LWIP_ASSERT("ret == 0", ret == 0); + + FD_ZERO(&readset); + FD_SET(s, &readset); + FD_ZERO(&writeset); + FD_SET(s, &writeset); + FD_ZERO(&errset); + FD_SET(s, &errset); + ticks_a = sys_now(); + /* select with waiting should eventually succeed and return errset! */ + ret = lwip_select(s + 1, &readset, &writeset, &errset, NULL); + ticks_b = sys_now(); + LWIP_ASSERT("ret > 0", ret > 0); + LWIP_ASSERT("FD_ISSET(s, &errset)", FD_ISSET(s, &errset)); + LWIP_ASSERT("!FD_ISSET(s, &readset)", !FD_ISSET(s, &readset)); + LWIP_ASSERT("!FD_ISSET(s, &writeset)", !FD_ISSET(s, &writeset)); + + /* close */ + ret = lwip_close(s); + LWIP_ASSERT("ret == 0", ret == 0); + + printf("select() needed %d ticks to return error\n", ticks_b - ticks_a); + printf("all tests done, thread ending\n"); +} + +/** This is an example function that tests + the recv function (timeout etc.). */ +static void +sockex_testrecv(void *arg) +{ + int s; + int ret; + int err; + int opt; + struct sockaddr_in addr; + size_t len; + char rxbuf[1024]; + fd_set readset; + fd_set errset; + struct timeval tv; + + LWIP_UNUSED_ARG(arg); + /* set up address to connect to */ + memset(&addr, 0, sizeof(addr)); + addr.sin_len = sizeof(addr); + addr.sin_family = AF_INET; + addr.sin_port = PP_HTONS(SOCK_TARGET_PORT); + addr.sin_addr.s_addr = inet_addr(SOCK_TARGET_HOST); + + /* first try blocking: */ + + /* create the socket */ + s = lwip_socket(AF_INET, SOCK_STREAM, 0); + LWIP_ASSERT("s >= 0", s >= 0); + + /* connect */ + ret = lwip_connect(s, (struct sockaddr*)&addr, sizeof(addr)); + /* should succeed */ + LWIP_ASSERT("ret == 0", ret == 0); + + /* set recv timeout (100 ms) */ + opt = 100; + ret = lwip_setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &opt, sizeof(int)); + LWIP_ASSERT("ret == 0", ret == 0); + + /* write the start of a GET request */ +#define SNDSTR1 "G" + len = strlen(SNDSTR1); + ret = lwip_write(s, SNDSTR1, len); + LWIP_ASSERT("ret == len", ret == (int)len); + + /* should time out if the other side is a good HTTP server */ + ret = lwip_read(s, rxbuf, 1); + LWIP_ASSERT("ret == -1", ret == -1); + err = errno; + LWIP_ASSERT("errno == EAGAIN", err == EAGAIN); + + /* write the rest of a GET request */ +#define SNDSTR2 "ET / HTTP_1.1\r\n\r\n" + len = strlen(SNDSTR2); + ret = lwip_write(s, SNDSTR2, len); + LWIP_ASSERT("ret == len", ret == (int)len); + + /* wait a while: should be enough for the server to send a response */ + sys_msleep(1000); + + /* should not time out but receive a response */ + ret = lwip_read(s, rxbuf, 1024); + LWIP_ASSERT("ret > 0", ret > 0); + + /* now select should directly return because the socket is readable */ + FD_ZERO(&readset); + FD_ZERO(&errset); + FD_SET(s, &readset); + FD_SET(s, &errset); + tv.tv_sec = 10; + tv.tv_usec = 0; + ret = lwip_select(s + 1, &readset, NULL, &errset, &tv); + LWIP_ASSERT("ret == 1", ret == 1); + LWIP_ASSERT("!FD_ISSET(s, &errset)", !FD_ISSET(s, &errset)); + LWIP_ASSERT("FD_ISSET(s, &readset)", FD_ISSET(s, &readset)); + + /* should not time out but receive a response */ + ret = lwip_read(s, rxbuf, 1024); + /* might receive a second packet for HTTP/1.1 servers */ + if (ret > 0) { + /* should return 0: closed */ + ret = lwip_read(s, rxbuf, 1024); + LWIP_ASSERT("ret == 0", ret == 0); + } + + /* close */ + ret = lwip_close(s); + LWIP_ASSERT("ret == 0", ret == 0); + + printf("sockex_testrecv finished successfully\n"); +} + +/** helper struct for the 2 functions below (multithreaded: thread-argument) */ +struct sockex_select_helper { + int socket; + int wait_read; + int expect_read; + int wait_write; + int expect_write; + int wait_err; + int expect_err; + int wait_ms; + sys_sem_t sem; +}; + +/** helper thread to wait for socket events using select */ +static void +sockex_select_waiter(void *arg) +{ + struct sockex_select_helper *helper = (struct sockex_select_helper *)arg; + int ret; + fd_set readset; + fd_set writeset; + fd_set errset; + struct timeval tv; + + LWIP_ASSERT("helper != NULL", helper != NULL); + + FD_ZERO(&readset); + FD_ZERO(&writeset); + FD_ZERO(&errset); + if (helper->wait_read) { + FD_SET(helper->socket, &readset); + } + if (helper->wait_write) { + FD_SET(helper->socket, &writeset); + } + if (helper->wait_err) { + FD_SET(helper->socket, &errset); + } + + tv.tv_sec = helper->wait_ms / 1000; + tv.tv_usec = (helper->wait_ms % 1000) * 1000; + + ret = lwip_select(helper->socket, &readset, &writeset, &errset, &tv); + if (helper->expect_read || helper->expect_write || helper->expect_err) { + LWIP_ASSERT("ret > 0", ret > 0); + } else { + LWIP_ASSERT("ret == 0", ret == 0); + } + if (helper->expect_read) { + LWIP_ASSERT("FD_ISSET(helper->socket, &readset)", FD_ISSET(helper->socket, &readset)); + } else { + LWIP_ASSERT("!FD_ISSET(helper->socket, &readset)", !FD_ISSET(helper->socket, &readset)); + } + if (helper->expect_write) { + LWIP_ASSERT("FD_ISSET(helper->socket, &writeset)", FD_ISSET(helper->socket, &writeset)); + } else { + LWIP_ASSERT("!FD_ISSET(helper->socket, &writeset)", !FD_ISSET(helper->socket, &writeset)); + } + if (helper->expect_err) { + LWIP_ASSERT("FD_ISSET(helper->socket, &errset)", FD_ISSET(helper->socket, &errset)); + } else { + LWIP_ASSERT("!FD_ISSET(helper->socket, &errset)", !FD_ISSET(helper->socket, &errset)); + } + sys_sem_signal(&helper->sem); +} + +/** This is an example function that tests + more than one thread being active in select. */ +static void +sockex_testtwoselects(void *arg) +{ + int s1; + int s2; + int ret; + struct sockaddr_in addr; + size_t len; + err_t lwiperr; + struct sockex_select_helper h1, h2, h3, h4; + + LWIP_UNUSED_ARG(arg); + /* set up address to connect to */ + memset(&addr, 0, sizeof(addr)); + addr.sin_len = sizeof(addr); + addr.sin_family = AF_INET; + addr.sin_port = PP_HTONS(SOCK_TARGET_PORT); + addr.sin_addr.s_addr = inet_addr(SOCK_TARGET_HOST); + + /* create the sockets */ + s1 = lwip_socket(AF_INET, SOCK_STREAM, 0); + LWIP_ASSERT("s1 >= 0", s1 >= 0); + s2 = lwip_socket(AF_INET, SOCK_STREAM, 0); + LWIP_ASSERT("s2 >= 0", s2 >= 0); + + /* connect, should succeed */ + ret = lwip_connect(s1, (struct sockaddr*)&addr, sizeof(addr)); + LWIP_ASSERT("ret == 0", ret == 0); + ret = lwip_connect(s2, (struct sockaddr*)&addr, sizeof(addr)); + LWIP_ASSERT("ret == 0", ret == 0); + + /* write the start of a GET request */ +#define SNDSTR1 "G" + len = strlen(SNDSTR1); + ret = lwip_write(s1, SNDSTR1, len); + LWIP_ASSERT("ret == len", ret == (int)len); + ret = lwip_write(s2, SNDSTR1, len); + LWIP_ASSERT("ret == len", ret == (int)len); + + h1.wait_read = 1; + h1.wait_write = 1; + h1.wait_err = 1; + h1.expect_read = 0; + h1.expect_write = 0; + h1.expect_err = 0; + lwiperr = sys_sem_new(&h1.sem, 0); + LWIP_ASSERT("lwiperr == ERR_OK", lwiperr == ERR_OK); + h1.socket = s1; + h1.wait_ms = 500; + + h2 = h1; + lwiperr = sys_sem_new(&h2.sem, 0); + LWIP_ASSERT("lwiperr == ERR_OK", lwiperr == ERR_OK); + h2.socket = s2; + h2.wait_ms = 1000; + + h3 = h1; + lwiperr = sys_sem_new(&h3.sem, 0); + LWIP_ASSERT("lwiperr == ERR_OK", lwiperr == ERR_OK); + h3.socket = s2; + h3.wait_ms = 1500; + + h4 = h1; + lwiperr = sys_sem_new(&h4.sem, 0); + LWIP_ASSERT("lwiperr == ERR_OK", lwiperr == ERR_OK); + h4.socket = s2; + h4.wait_ms = 2000; + + /* select: all sockets should time out if the other side is a good HTTP server */ + + sys_thread_new("sockex_select_waiter1", sockex_select_waiter, &h2, 0, 0); + sys_msleep(100); + sys_thread_new("sockex_select_waiter2", sockex_select_waiter, &h1, 0, 0); + sys_msleep(100); + sys_thread_new("sockex_select_waiter2", sockex_select_waiter, &h4, 0, 0); + sys_msleep(100); + sys_thread_new("sockex_select_waiter2", sockex_select_waiter, &h3, 0, 0); + + sys_sem_wait(&h1.sem); + sys_sem_wait(&h2.sem); + sys_sem_wait(&h3.sem); + sys_sem_wait(&h4.sem); + + /* close */ + ret = lwip_close(s1); + LWIP_ASSERT("ret == 0", ret == 0); + ret = lwip_close(s2); + LWIP_ASSERT("ret == 0", ret == 0); + + printf("sockex_testtwoselects finished successfully\n"); +} + +void socket_examples_init(void) +{ + sys_thread_new("sockex_nonblocking_connect", sockex_nonblocking_connect, NULL, 0, 0); + sys_thread_new("sockex_testrecv", sockex_testrecv, NULL, 0, 0); + /*sys_thread_new("sockex_testtwoselects", sockex_testtwoselects, NULL, 0, 0);*/ +} + +#endif /* LWIP_SOCKETS */ diff --git a/src/lwip-1.4.1/apps/socket_examples/socket_examples.h b/src/lwip-1.4.1/apps/socket_examples/socket_examples.h new file mode 100644 index 0000000..ae8a3ec --- /dev/null +++ b/src/lwip-1.4.1/apps/socket_examples/socket_examples.h @@ -0,0 +1,6 @@ +#ifndef __SOCKET_EXAMPLES_H__ +#define __SOCKET_EXAMPLES_H__ + +void socket_examples_init(void); + +#endif /* __SOCKET_EXAMPLES_H__ */ diff --git a/src/lwip-1.4.1/apps/tcpecho/tcpecho.c b/src/lwip-1.4.1/apps/tcpecho/tcpecho.c new file mode 100644 index 0000000..19cc666 --- /dev/null +++ b/src/lwip-1.4.1/apps/tcpecho/tcpecho.c @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2001-2003 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#include "tcpecho.h" + +#include "lwip/opt.h" + +#if LWIP_NETCONN + +#include "lwip/sys.h" +#include "lwip/api.h" +/*-----------------------------------------------------------------------------------*/ +static void +tcpecho_thread(void *arg) +{ + struct netconn *conn, *newconn; + err_t err; + LWIP_UNUSED_ARG(arg); + + /* Create a new connection identifier. */ + conn = netconn_new(NETCONN_TCP); + + /* Bind connection to well known port number 7. */ + netconn_bind(conn, NULL, 7); + + /* Tell connection to go into listening mode. */ + netconn_listen(conn); + + while (1) { + + /* Grab new connection. */ + err = netconn_accept(conn, &newconn); + /*printf("accepted new connection %p\n", newconn);*/ + /* Process the new connection. */ + if (err == ERR_OK) { + struct netbuf *buf; + void *data; + u16_t len; + + while ((err = netconn_recv(newconn, &buf)) == ERR_OK) { + /*printf("Recved\n");*/ + do { + netbuf_data(buf, &data, &len); + err = netconn_write(newconn, data, len, NETCONN_COPY); +#if 0 + if (err != ERR_OK) { + printf("tcpecho: netconn_write: error \"%s\"\n", lwip_strerr(err)); + } +#endif + } while (netbuf_next(buf) >= 0); + netbuf_delete(buf); + } + /*printf("Got EOF, looping\n");*/ + /* Close connection and discard connection identifier. */ + netconn_close(newconn); + netconn_delete(newconn); + } + } +} +/*-----------------------------------------------------------------------------------*/ +void +tcpecho_init(void) +{ + sys_thread_new("tcpecho_thread", tcpecho_thread, NULL, DEFAULT_THREAD_STACKSIZE, DEFAULT_THREAD_PRIO); +} +/*-----------------------------------------------------------------------------------*/ + +#endif /* LWIP_NETCONN */ diff --git a/src/lwip-1.4.1/apps/tcpecho/tcpecho.h b/src/lwip-1.4.1/apps/tcpecho/tcpecho.h new file mode 100644 index 0000000..8a78c67 --- /dev/null +++ b/src/lwip-1.4.1/apps/tcpecho/tcpecho.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2001-2003 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#ifndef __TCPECHO_H__ +#define __TCPECHO_H__ + +void tcpecho_init(void); + +#endif /* __TCPECHO_H__ */ diff --git a/src/lwip-1.4.1/apps/tcpecho_raw/echo.c b/src/lwip-1.4.1/apps/tcpecho_raw/echo.c new file mode 100644 index 0000000..4e14ca7 --- /dev/null +++ b/src/lwip-1.4.1/apps/tcpecho_raw/echo.c @@ -0,0 +1,363 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * This file is part of and a contribution to the lwIP TCP/IP stack. + * + * Credits go to Adam Dunkels (and the current maintainers) of this software. + * + * Christiaan Simons rewrote this file to get a more stable echo example. + */ + +/** + * @file + * TCP echo server example using raw API. + * + * Echos all bytes sent by connecting client, + * and passively closes when client is done. + * + */ + + +#include "lwip/opt.h" +#include "lwip/debug.h" +#include "lwip/stats.h" +#include "lwip/tcp.h" + +#if LWIP_TCP + +static struct tcp_pcb *echo_pcb; + +enum echo_states +{ + ES_NONE = 0, + ES_ACCEPTED, + ES_RECEIVED, + ES_CLOSING +}; + +struct echo_state +{ + u8_t state; + u8_t retries; + struct tcp_pcb *pcb; + /* pbuf (chain) to recycle */ + struct pbuf *p; +}; + +err_t echo_accept(void *arg, struct tcp_pcb *newpcb, err_t err); +err_t echo_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err); +void echo_error(void *arg, err_t err); +err_t echo_poll(void *arg, struct tcp_pcb *tpcb); +err_t echo_sent(void *arg, struct tcp_pcb *tpcb, u16_t len); +void echo_send(struct tcp_pcb *tpcb, struct echo_state *es); +void echo_close(struct tcp_pcb *tpcb, struct echo_state *es); + +void +echo_init(void) +{ + echo_pcb = tcp_new(); + if (echo_pcb != NULL) + { + err_t err; + + err = tcp_bind(echo_pcb, IP_ADDR_ANY, 7); + if (err == ERR_OK) + { + echo_pcb = tcp_listen(echo_pcb); + tcp_accept(echo_pcb, echo_accept); + } + else + { + /* abort? output diagnostic? */ + } + } + else + { + /* abort? output diagnostic? */ + } +} + + +err_t +echo_accept(void *arg, struct tcp_pcb *newpcb, err_t err) +{ + err_t ret_err; + struct echo_state *es; + + LWIP_UNUSED_ARG(arg); + LWIP_UNUSED_ARG(err); + + /* Unless this pcb should have NORMAL priority, set its priority now. + When running out of pcbs, low priority pcbs can be aborted to create + new pcbs of higher priority. */ + tcp_setprio(newpcb, TCP_PRIO_MIN); + + es = (struct echo_state *)mem_malloc(sizeof(struct echo_state)); + if (es != NULL) + { + es->state = ES_ACCEPTED; + es->pcb = newpcb; + es->retries = 0; + es->p = NULL; + /* pass newly allocated es to our callbacks */ + tcp_arg(newpcb, es); + tcp_recv(newpcb, echo_recv); + tcp_err(newpcb, echo_error); + tcp_poll(newpcb, echo_poll, 0); + ret_err = ERR_OK; + } + else + { + ret_err = ERR_MEM; + } + return ret_err; +} + +err_t +echo_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err) +{ + struct echo_state *es; + err_t ret_err; + + LWIP_ASSERT("arg != NULL",arg != NULL); + es = (struct echo_state *)arg; + if (p == NULL) + { + /* remote host closed connection */ + es->state = ES_CLOSING; + if(es->p == NULL) + { + /* we're done sending, close it */ + echo_close(tpcb, es); + } + else + { + /* we're not done yet */ + tcp_sent(tpcb, echo_sent); + echo_send(tpcb, es); + } + ret_err = ERR_OK; + } + else if(err != ERR_OK) + { + /* cleanup, for unkown reason */ + if (p != NULL) + { + es->p = NULL; + pbuf_free(p); + } + ret_err = err; + } + else if(es->state == ES_ACCEPTED) + { + /* first data chunk in p->payload */ + es->state = ES_RECEIVED; + /* store reference to incoming pbuf (chain) */ + es->p = p; + /* install send completion notifier */ + tcp_sent(tpcb, echo_sent); + echo_send(tpcb, es); + ret_err = ERR_OK; + } + else if (es->state == ES_RECEIVED) + { + /* read some more data */ + if(es->p == NULL) + { + es->p = p; + tcp_sent(tpcb, echo_sent); + echo_send(tpcb, es); + } + else + { + struct pbuf *ptr; + + /* chain pbufs to the end of what we recv'ed previously */ + ptr = es->p; + pbuf_chain(ptr,p); + } + ret_err = ERR_OK; + } + else if(es->state == ES_CLOSING) + { + /* odd case, remote side closing twice, trash data */ + tcp_recved(tpcb, p->tot_len); + es->p = NULL; + pbuf_free(p); + ret_err = ERR_OK; + } + else + { + /* unkown es->state, trash data */ + tcp_recved(tpcb, p->tot_len); + es->p = NULL; + pbuf_free(p); + ret_err = ERR_OK; + } + return ret_err; +} + +void +echo_error(void *arg, err_t err) +{ + struct echo_state *es; + + LWIP_UNUSED_ARG(err); + + es = (struct echo_state *)arg; + if (es != NULL) + { + mem_free(es); + } +} + +err_t +echo_poll(void *arg, struct tcp_pcb *tpcb) +{ + err_t ret_err; + struct echo_state *es; + + es = (struct echo_state *)arg; + if (es != NULL) + { + if (es->p != NULL) + { + /* there is a remaining pbuf (chain) */ + tcp_sent(tpcb, echo_sent); + echo_send(tpcb, es); + } + else + { + /* no remaining pbuf (chain) */ + if(es->state == ES_CLOSING) + { + echo_close(tpcb, es); + } + } + ret_err = ERR_OK; + } + else + { + /* nothing to be done */ + tcp_abort(tpcb); + ret_err = ERR_ABRT; + } + return ret_err; +} + +err_t +echo_sent(void *arg, struct tcp_pcb *tpcb, u16_t len) +{ + struct echo_state *es; + + LWIP_UNUSED_ARG(len); + + es = (struct echo_state *)arg; + es->retries = 0; + + if(es->p != NULL) + { + /* still got pbufs to send */ + tcp_sent(tpcb, echo_sent); + echo_send(tpcb, es); + } + else + { + /* no more pbufs to send */ + if(es->state == ES_CLOSING) + { + echo_close(tpcb, es); + } + } + return ERR_OK; +} + +void +echo_send(struct tcp_pcb *tpcb, struct echo_state *es) +{ + struct pbuf *ptr; + err_t wr_err = ERR_OK; + + while ((wr_err == ERR_OK) && + (es->p != NULL) && + (es->p->len <= tcp_sndbuf(tpcb))) + { + ptr = es->p; + + /* enqueue data for transmission */ + wr_err = tcp_write(tpcb, ptr->payload, ptr->len, 1); + if (wr_err == ERR_OK) + { + u16_t plen; + u8_t freed; + + plen = ptr->len; + /* continue with next pbuf in chain (if any) */ + es->p = ptr->next; + if(es->p != NULL) + { + /* new reference! */ + pbuf_ref(es->p); + } + /* chop first pbuf from chain */ + do + { + /* try hard to free pbuf */ + freed = pbuf_free(ptr); + } + while(freed == 0); + /* we can read more data now */ + tcp_recved(tpcb, plen); + } + else if(wr_err == ERR_MEM) + { + /* we are low on memory, try later / harder, defer to poll */ + es->p = ptr; + } + else + { + /* other problem ?? */ + } + } +} + +void +echo_close(struct tcp_pcb *tpcb, struct echo_state *es) +{ + tcp_arg(tpcb, NULL); + tcp_sent(tpcb, NULL); + tcp_recv(tpcb, NULL); + tcp_err(tpcb, NULL); + tcp_poll(tpcb, NULL, 0); + + if (es != NULL) + { + mem_free(es); + } + tcp_close(tpcb); +} + +#endif /* LWIP_TCP */ diff --git a/src/lwip-1.4.1/apps/tcpecho_raw/echo.h b/src/lwip-1.4.1/apps/tcpecho_raw/echo.h new file mode 100644 index 0000000..fd3217c --- /dev/null +++ b/src/lwip-1.4.1/apps/tcpecho_raw/echo.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * This file is part of the lwIP TCP/IP stack. + * + */ +#ifndef __ECHO_H__ +#define __ECHO_H__ + +void echo_init(void); + +#endif /* __MINIMAL_ECHO_H */ diff --git a/src/lwip-1.4.1/apps/udpecho/udpecho.c b/src/lwip-1.4.1/apps/udpecho/udpecho.c new file mode 100644 index 0000000..f2842d7 --- /dev/null +++ b/src/lwip-1.4.1/apps/udpecho/udpecho.c @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2001-2003 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#include "udpecho.h" + +#include "lwip/opt.h" + +#if LWIP_NETCONN + +#include "lwip/api.h" +#include "lwip/sys.h" + +/*-----------------------------------------------------------------------------------*/ +static void +udpecho_thread(void *arg) +{ + static struct netconn *conn; + static struct netbuf *buf; + static ip_addr_t *addr; + static unsigned short port; + char buffer[4096]; + err_t err; + LWIP_UNUSED_ARG(arg); + + conn = netconn_new(NETCONN_UDP); + LWIP_ASSERT("con != NULL", conn != NULL); + netconn_bind(conn, NULL, 7); + + while (1) { + err = netconn_recv(conn, &buf); + if (err == ERR_OK) { + addr = netbuf_fromaddr(buf); + port = netbuf_fromport(buf); + /* no need netconn_connect here, since the netbuf contains the address */ + if(netbuf_copy(buf, buffer, buf->p->tot_len) != buf->p->tot_len) { + LWIP_DEBUGF(LWIP_DBG_ON, ("netbuf_copy failed\n")); + } else { + buffer[buf->p->tot_len] = '\0'; + err = netconn_send(conn, buf); + if(err != ERR_OK) { + LWIP_DEBUGF(LWIP_DBG_ON, ("netconn_send failed: %d\n", (int)err)); + } else { + LWIP_DEBUGF(LWIP_DBG_ON, ("got %s\n", buffer)); + } + } + netbuf_delete(buf); + } + } +} +/*-----------------------------------------------------------------------------------*/ +void +udpecho_init(void) +{ + sys_thread_new("udpecho_thread", udpecho_thread, NULL, DEFAULT_THREAD_STACKSIZE, DEFAULT_THREAD_PRIO); +} + +#endif /* LWIP_NETCONN */ diff --git a/src/lwip-1.4.1/apps/udpecho/udpecho.h b/src/lwip-1.4.1/apps/udpecho/udpecho.h new file mode 100644 index 0000000..6c50058 --- /dev/null +++ b/src/lwip-1.4.1/apps/udpecho/udpecho.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2001-2003 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __UDPECHO_H__ +#define __UDPECHO_H__ + +void udpecho_init(void); + +#endif /* __UDPECHO_H__ */ diff --git a/src/lwip-1.4.1/doc/FILES b/src/lwip-1.4.1/doc/FILES new file mode 100644 index 0000000..05d356f --- /dev/null +++ b/src/lwip-1.4.1/doc/FILES @@ -0,0 +1,6 @@ +savannah.txt - How to obtain the current development source code. +contrib.txt - How to contribute to lwIP as a developer. +rawapi.txt - The documentation for the core API of lwIP. + Also provides an overview about the other APIs and multithreading. +snmp_agent.txt - The documentation for the lwIP SNMP agent. +sys_arch.txt - The documentation for a system abstraction layer of lwIP. diff --git a/src/lwip-1.4.1/doc/contrib.txt b/src/lwip-1.4.1/doc/contrib.txt new file mode 100644 index 0000000..39596fc --- /dev/null +++ b/src/lwip-1.4.1/doc/contrib.txt @@ -0,0 +1,63 @@ +1 Introduction + +This document describes some guidelines for people participating +in lwIP development. + +2 How to contribute to lwIP + +Here is a short list of suggestions to anybody working with lwIP and +trying to contribute bug reports, fixes, enhancements, platform ports etc. +First of all as you may already know lwIP is a volunteer project so feedback +to fixes or questions might often come late. Hopefully the bug and patch tracking +features of Savannah help us not lose users' input. + +2.1 Source code style: + +1. do not use tabs. +2. indentation is two spaces per level (i.e. per tab). +3. end debug messages with a trailing newline (\n). +4. one space between keyword and opening bracket. +5. no space between function and opening bracket. +6. one space and no newline before opening curly braces of a block. +7. closing curly brace on a single line. +8. spaces surrounding assignment and comparisons. +9. don't initialize static and/or global variables to zero, the compiler takes care of that. +10. use current source code style as further reference. + +2.2 Source code documentation style: + +1. JavaDoc compliant and Doxygen compatible. +2. Function documentation above functions in .c files, not .h files. + (This forces you to synchronize documentation and implementation.) +3. Use current documentation style as further reference. + +2.3 Bug reports and patches: + +1. Make sure you are reporting bugs or send patches against the latest + sources. (From the latest release and/or the current CVS sources.) +2. If you think you found a bug make sure it's not already filed in the + bugtracker at Savannah. +3. If you have a fix put the patch on Savannah. If it is a patch that affects + both core and arch specific stuff please separate them so that the core can + be applied separately while leaving the other patch 'open'. The prefered way + is to NOT touch archs you can't test and let maintainers take care of them. + This is a good way to see if they are used at all - the same goes for unix + netifs except tapif. +4. Do not file a bug and post a fix to it to the patch area. Either a bug report + or a patch will be enough. + If you correct an existing bug then attach the patch to the bug rather than creating a new entry in the patch area. +5. Trivial patches (compiler warning, indentation and spelling fixes or anything obvious which takes a line or two) + can go to the lwip-users list. This is still the fastest way of interaction and the list is not so crowded + as to allow for loss of fixes. Putting bugs on Savannah and subsequently closing them is too much an overhead + for reporting a compiler warning fix. +6. Patches should be specific to a single change or to related changes.Do not mix bugfixes with spelling and other + trivial fixes unless the bugfix is trivial too.Do not reorganize code and rename identifiers in the same patch you + change behaviour if not necessary.A patch is easier to read and understand if it's to the point and short than + if it's not to the point and long :) so the chances for it to be applied are greater. + +2.4 Platform porters: + +1. If you have ported lwIP to a platform (an OS, a uC/processor or a combination of these) and + you think it could benefit others[1] you might want discuss this on the mailing list. You + can also ask for CVS access to submit and maintain your port in the contrib CVS module. + \ No newline at end of file diff --git a/src/lwip-1.4.1/doc/rawapi.txt b/src/lwip-1.4.1/doc/rawapi.txt new file mode 100644 index 0000000..8c19030 --- /dev/null +++ b/src/lwip-1.4.1/doc/rawapi.txt @@ -0,0 +1,511 @@ +Raw TCP/IP interface for lwIP + +Authors: Adam Dunkels, Leon Woestenberg, Christiaan Simons + +lwIP provides three Application Program's Interfaces (APIs) for programs +to use for communication with the TCP/IP code: +* low-level "core" / "callback" or "raw" API. +* higher-level "sequential" API. +* BSD-style socket API. + +The sequential API provides a way for ordinary, sequential, programs +to use the lwIP stack. It is quite similar to the BSD socket API. The +model of execution is based on the blocking open-read-write-close +paradigm. Since the TCP/IP stack is event based by nature, the TCP/IP +code and the application program must reside in different execution +contexts (threads). + +The socket API is a compatibility API for existing applications, +currently it is built on top of the sequential API. It is meant to +provide all functions needed to run socket API applications running +on other platforms (e.g. unix / windows etc.). However, due to limitations +in the specification of this API, there might be incompatibilities +that require small modifications of existing programs. + +** Threading + +lwIP started targeting single-threaded environments. When adding multi- +threading support, instead of making the core thread-safe, another +approach was chosen: there is one main thread running the lwIP core +(also known as the "tcpip_thread"). The raw API may only be used from +this thread! Application threads using the sequential- or socket API +communicate with this main thread through message passing. + + As such, the list of functions that may be called from + other threads or an ISR is very limited! Only functions + from these API header files are thread-safe: + - api.h + - netbuf.h + - netdb.h + - netifapi.h + - sockets.h + - sys.h + + Additionaly, memory (de-)allocation functions may be + called from multiple threads (not ISR!) with NO_SYS=0 + since they are protected by SYS_LIGHTWEIGHT_PROT and/or + semaphores. + + Only since 1.3.0, if SYS_LIGHTWEIGHT_PROT is set to 1 + and LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT is set to 1, + pbuf_free() may also be called from another thread or + an ISR (since only then, mem_free - for PBUF_RAM - may + be called from an ISR: otherwise, the HEAP is only + protected by semaphores). + + +** The remainder of this document discusses the "raw" API. ** + +The raw TCP/IP interface allows the application program to integrate +better with the TCP/IP code. Program execution is event based by +having callback functions being called from within the TCP/IP +code. The TCP/IP code and the application program both run in the same +thread. The sequential API has a much higher overhead and is not very +well suited for small systems since it forces a multithreaded paradigm +on the application. + +The raw TCP/IP interface is not only faster in terms of code execution +time but is also less memory intensive. The drawback is that program +development is somewhat harder and application programs written for +the raw TCP/IP interface are more difficult to understand. Still, this +is the preferred way of writing applications that should be small in +code size and memory usage. + +Both APIs can be used simultaneously by different application +programs. In fact, the sequential API is implemented as an application +program using the raw TCP/IP interface. + +--- Callbacks + +Program execution is driven by callbacks. Each callback is an ordinary +C function that is called from within the TCP/IP code. Every callback +function is passed the current TCP or UDP connection state as an +argument. Also, in order to be able to keep program specific state, +the callback functions are called with a program specified argument +that is independent of the TCP/IP state. + +The function for setting the application connection state is: + +- void tcp_arg(struct tcp_pcb *pcb, void *arg) + + Specifies the program specific state that should be passed to all + other callback functions. The "pcb" argument is the current TCP + connection control block, and the "arg" argument is the argument + that will be passed to the callbacks. + + +--- TCP connection setup + +The functions used for setting up connections is similar to that of +the sequential API and of the BSD socket API. A new TCP connection +identifier (i.e., a protocol control block - PCB) is created with the +tcp_new() function. This PCB can then be either set to listen for new +incoming connections or be explicitly connected to another host. + +- struct tcp_pcb *tcp_new(void) + + Creates a new connection identifier (PCB). If memory is not + available for creating the new pcb, NULL is returned. + +- err_t tcp_bind(struct tcp_pcb *pcb, ip_addr_t *ipaddr, + u16_t port) + + Binds the pcb to a local IP address and port number. The IP address + can be specified as IP_ADDR_ANY in order to bind the connection to + all local IP addresses. + + If another connection is bound to the same port, the function will + return ERR_USE, otherwise ERR_OK is returned. + +- struct tcp_pcb *tcp_listen(struct tcp_pcb *pcb) + + Commands a pcb to start listening for incoming connections. When an + incoming connection is accepted, the function specified with the + tcp_accept() function will be called. The pcb will have to be bound + to a local port with the tcp_bind() function. + + The tcp_listen() function returns a new connection identifier, and + the one passed as an argument to the function will be + deallocated. The reason for this behavior is that less memory is + needed for a connection that is listening, so tcp_listen() will + reclaim the memory needed for the original connection and allocate a + new smaller memory block for the listening connection. + + tcp_listen() may return NULL if no memory was available for the + listening connection. If so, the memory associated with the pcb + passed as an argument to tcp_listen() will not be deallocated. + +- struct tcp_pcb *tcp_listen_with_backlog(struct tcp_pcb *pcb, u8_t backlog) + + Same as tcp_listen, but limits the number of outstanding connections + in the listen queue to the value specified by the backlog argument. + To use it, your need to set TCP_LISTEN_BACKLOG=1 in your lwipopts.h. + +- void tcp_accepted(struct tcp_pcb *pcb) + + Inform lwIP that an incoming connection has been accepted. This would + usually be called from the accept callback. This allows lwIP to perform + housekeeping tasks, such as allowing further incoming connections to be + queued in the listen backlog. + ATTENTION: the PCB passed in must be the listening pcb, not the pcb passed + into the accept callback! + +- void tcp_accept(struct tcp_pcb *pcb, + err_t (* accept)(void *arg, struct tcp_pcb *newpcb, + err_t err)) + + Specified the callback function that should be called when a new + connection arrives on a listening connection. + +- err_t tcp_connect(struct tcp_pcb *pcb, ip_addr_t *ipaddr, + u16_t port, err_t (* connected)(void *arg, + struct tcp_pcb *tpcb, + err_t err)); + + Sets up the pcb to connect to the remote host and sends the + initial SYN segment which opens the connection. + + The tcp_connect() function returns immediately; it does not wait for + the connection to be properly setup. Instead, it will call the + function specified as the fourth argument (the "connected" argument) + when the connection is established. If the connection could not be + properly established, either because the other host refused the + connection or because the other host didn't answer, the "err" + callback function of this pcb (registered with tcp_err, see below) + will be called. + + The tcp_connect() function can return ERR_MEM if no memory is + available for enqueueing the SYN segment. If the SYN indeed was + enqueued successfully, the tcp_connect() function returns ERR_OK. + + +--- Sending TCP data + +TCP data is sent by enqueueing the data with a call to +tcp_write(). When the data is successfully transmitted to the remote +host, the application will be notified with a call to a specified +callback function. + +- err_t tcp_write(struct tcp_pcb *pcb, const void *dataptr, u16_t len, + u8_t apiflags) + + Enqueues the data pointed to by the argument dataptr. The length of + the data is passed as the len parameter. The apiflags can be one or more of: + - TCP_WRITE_FLAG_COPY: indicates whether the new memory should be allocated + for the data to be copied into. If this flag is not given, no new memory + should be allocated and the data should only be referenced by pointer. This + also means that the memory behind dataptr must not change until the data is + ACKed by the remote host + - TCP_WRITE_FLAG_MORE: indicates that more data follows. If this is given, + the PSH flag is set in the last segment created by this call to tcp_write. + If this flag is given, the PSH flag is not set. + + The tcp_write() function will fail and return ERR_MEM if the length + of the data exceeds the current send buffer size or if the length of + the queue of outgoing segment is larger than the upper limit defined + in lwipopts.h. The number of bytes available in the output queue can + be retrieved with the tcp_sndbuf() function. + + The proper way to use this function is to call the function with at + most tcp_sndbuf() bytes of data. If the function returns ERR_MEM, + the application should wait until some of the currently enqueued + data has been successfully received by the other host and try again. + +- void tcp_sent(struct tcp_pcb *pcb, + err_t (* sent)(void *arg, struct tcp_pcb *tpcb, + u16_t len)) + + Specifies the callback function that should be called when data has + successfully been received (i.e., acknowledged) by the remote + host. The len argument passed to the callback function gives the + amount bytes that was acknowledged by the last acknowledgment. + + +--- Receiving TCP data + +TCP data reception is callback based - an application specified +callback function is called when new data arrives. When the +application has taken the data, it has to call the tcp_recved() +function to indicate that TCP can advertise increase the receive +window. + +- void tcp_recv(struct tcp_pcb *pcb, + err_t (* recv)(void *arg, struct tcp_pcb *tpcb, + struct pbuf *p, err_t err)) + + Sets the callback function that will be called when new data + arrives. The callback function will be passed a NULL pbuf to + indicate that the remote host has closed the connection. If + there are no errors and the callback function is to return + ERR_OK, then it must free the pbuf. Otherwise, it must not + free the pbuf so that lwIP core code can store it. + +- void tcp_recved(struct tcp_pcb *pcb, u16_t len) + + Must be called when the application has received the data. The len + argument indicates the length of the received data. + + +--- Application polling + +When a connection is idle (i.e., no data is either transmitted or +received), lwIP will repeatedly poll the application by calling a +specified callback function. This can be used either as a watchdog +timer for killing connections that have stayed idle for too long, or +as a method of waiting for memory to become available. For instance, +if a call to tcp_write() has failed because memory wasn't available, +the application may use the polling functionality to call tcp_write() +again when the connection has been idle for a while. + +- void tcp_poll(struct tcp_pcb *pcb, + err_t (* poll)(void *arg, struct tcp_pcb *tpcb), + u8_t interval) + + Specifies the polling interval and the callback function that should + be called to poll the application. The interval is specified in + number of TCP coarse grained timer shots, which typically occurs + twice a second. An interval of 10 means that the application would + be polled every 5 seconds. + + +--- Closing and aborting connections + +- err_t tcp_close(struct tcp_pcb *pcb) + + Closes the connection. The function may return ERR_MEM if no memory + was available for closing the connection. If so, the application + should wait and try again either by using the acknowledgment + callback or the polling functionality. If the close succeeds, the + function returns ERR_OK. + + The pcb is deallocated by the TCP code after a call to tcp_close(). + +- void tcp_abort(struct tcp_pcb *pcb) + + Aborts the connection by sending a RST (reset) segment to the remote + host. The pcb is deallocated. This function never fails. + + ATTENTION: When calling this from one of the TCP callbacks, make + sure you always return ERR_ABRT (and never return ERR_ABRT otherwise + or you will risk accessing deallocated memory or memory leaks! + + +If a connection is aborted because of an error, the application is +alerted of this event by the err callback. Errors that might abort a +connection are when there is a shortage of memory. The callback +function to be called is set using the tcp_err() function. + +- void tcp_err(struct tcp_pcb *pcb, void (* err)(void *arg, + err_t err)) + + The error callback function does not get the pcb passed to it as a + parameter since the pcb may already have been deallocated. + + +--- Lower layer TCP interface + +TCP provides a simple interface to the lower layers of the +system. During system initialization, the function tcp_init() has +to be called before any other TCP function is called. When the system +is running, the two timer functions tcp_fasttmr() and tcp_slowtmr() +must be called with regular intervals. The tcp_fasttmr() should be +called every TCP_FAST_INTERVAL milliseconds (defined in tcp.h) and +tcp_slowtmr() should be called every TCP_SLOW_INTERVAL milliseconds. + + +--- UDP interface + +The UDP interface is similar to that of TCP, but due to the lower +level of complexity of UDP, the interface is significantly simpler. + +- struct udp_pcb *udp_new(void) + + Creates a new UDP pcb which can be used for UDP communication. The + pcb is not active until it has either been bound to a local address + or connected to a remote address. + +- void udp_remove(struct udp_pcb *pcb) + + Removes and deallocates the pcb. + +- err_t udp_bind(struct udp_pcb *pcb, ip_addr_t *ipaddr, + u16_t port) + + Binds the pcb to a local address. The IP-address argument "ipaddr" + can be IP_ADDR_ANY to indicate that it should listen to any local IP + address. The function currently always return ERR_OK. + +- err_t udp_connect(struct udp_pcb *pcb, ip_addr_t *ipaddr, + u16_t port) + + Sets the remote end of the pcb. This function does not generate any + network traffic, but only set the remote address of the pcb. + +- err_t udp_disconnect(struct udp_pcb *pcb) + + Remove the remote end of the pcb. This function does not generate + any network traffic, but only removes the remote address of the pcb. + +- err_t udp_send(struct udp_pcb *pcb, struct pbuf *p) + + Sends the pbuf p. The pbuf is not deallocated. + +- void udp_recv(struct udp_pcb *pcb, + void (* recv)(void *arg, struct udp_pcb *upcb, + struct pbuf *p, + ip_addr_t *addr, + u16_t port), + void *recv_arg) + + Specifies a callback function that should be called when a UDP + datagram is received. + + +--- System initalization + +A truly complete and generic sequence for initializing the lwip stack +cannot be given because it depends on the build configuration (lwipopts.h) +and additional initializations for your runtime environment (e.g. timers). + +We can give you some idea on how to proceed when using the raw API. +We assume a configuration using a single Ethernet netif and the +UDP and TCP transport layers, IPv4 and the DHCP client. + +Call these functions in the order of appearance: + +- stats_init() + + Clears the structure where runtime statistics are gathered. + +- sys_init() + + Not of much use since we set the NO_SYS 1 option in lwipopts.h, + to be called for easy configuration changes. + +- mem_init() + + Initializes the dynamic memory heap defined by MEM_SIZE. + +- memp_init() + + Initializes the memory pools defined by MEMP_NUM_x. + +- pbuf_init() + + Initializes the pbuf memory pool defined by PBUF_POOL_SIZE. + +- etharp_init() + + Initializes the ARP table and queue. + Note: you must call etharp_tmr at a ARP_TMR_INTERVAL (5 seconds) regular interval + after this initialization. + +- ip_init() + + Doesn't do much, it should be called to handle future changes. + +- udp_init() + + Clears the UDP PCB list. + +- tcp_init() + + Clears the TCP PCB list and clears some internal TCP timers. + Note: you must call tcp_fasttmr() and tcp_slowtmr() at the + predefined regular intervals after this initialization. + +- netif_add(struct netif *netif, ip_addr_t *ipaddr, + ip_addr_t *netmask, ip_addr_t *gw, + void *state, err_t (* init)(struct netif *netif), + err_t (* input)(struct pbuf *p, struct netif *netif)) + + Adds your network interface to the netif_list. Allocate a struct + netif and pass a pointer to this structure as the first argument. + Give pointers to cleared ip_addr structures when using DHCP, + or fill them with sane numbers otherwise. The state pointer may be NULL. + + The init function pointer must point to a initialization function for + your ethernet netif interface. The following code illustrates it's use. + + err_t netif_if_init(struct netif *netif) + { + u8_t i; + + for(i = 0; i < ETHARP_HWADDR_LEN; i++) netif->hwaddr[i] = some_eth_addr[i]; + init_my_eth_device(); + return ERR_OK; + } + + For ethernet drivers, the input function pointer must point to the lwip + function ethernet_input() declared in "netif/etharp.h". Other drivers + must use ip_input() declared in "lwip/ip.h". + +- netif_set_default(struct netif *netif) + + Registers the default network interface. + +- netif_set_up(struct netif *netif) + + When the netif is fully configured this function must be called. + +- dhcp_start(struct netif *netif) + + Creates a new DHCP client for this interface on the first call. + Note: you must call dhcp_fine_tmr() and dhcp_coarse_tmr() at + the predefined regular intervals after starting the client. + + You can peek in the netif->dhcp struct for the actual DHCP status. + + +--- Optimalization hints + +The first thing you want to optimize is the lwip_standard_checksum() +routine from src/core/inet.c. You can override this standard +function with the #define LWIP_CHKSUM . + +There are C examples given in inet.c or you might want to +craft an assembly function for this. RFC1071 is a good +introduction to this subject. + +Other significant improvements can be made by supplying +assembly or inline replacements for htons() and htonl() +if you're using a little-endian architecture. +#define LWIP_PLATFORM_BYTESWAP 1 +#define LWIP_PLATFORM_HTONS(x) +#define LWIP_PLATFORM_HTONL(x) + +Check your network interface driver if it reads at +a higher speed than the maximum wire-speed. If the +hardware isn't serviced frequently and fast enough +buffer overflows are likely to occur. + +E.g. when using the cs8900 driver, call cs8900if_service(ethif) +as frequently as possible. When using an RTOS let the cs8900 interrupt +wake a high priority task that services your driver using a binary +semaphore or event flag. Some drivers might allow additional tuning +to match your application and network. + +For a production release it is recommended to set LWIP_STATS to 0. +Note that speed performance isn't influenced much by simply setting +high values to the memory options. + +For more optimization hints take a look at the lwIP wiki. + +--- Zero-copy MACs + +To achieve zero-copy on transmit, the data passed to the raw API must +remain unchanged until sent. Because the send- (or write-)functions return +when the packets have been enqueued for sending, data must be kept stable +after that, too. + +This implies that PBUF_RAM/PBUF_POOL pbufs passed to raw-API send functions +must *not* be reused by the application unless their ref-count is 1. + +For no-copy pbufs (PBUF_ROM/PBUF_REF), data must be kept unchanged, too, +but the stack/driver will/must copy PBUF_REF'ed data when enqueueing, while +PBUF_ROM-pbufs are just enqueued (as ROM-data is expected to never change). + +Also, data passed to tcp_write without the copy-flag must not be changed! + +Therefore, be careful which type of PBUF you use and if you copy TCP data +or not! diff --git a/src/lwip-1.4.1/doc/savannah.txt b/src/lwip-1.4.1/doc/savannah.txt new file mode 100644 index 0000000..409905b --- /dev/null +++ b/src/lwip-1.4.1/doc/savannah.txt @@ -0,0 +1,135 @@ +Daily Use Guide for using Savannah for lwIP + +Table of Contents: + +1 - Obtaining lwIP from the CVS repository +2 - Committers/developers CVS access using SSH (to be written) +3 - Merging from DEVEL branch to main trunk (stable branch) +4 - How to release lwIP + + + +1 Obtaining lwIP from the CVS repository +---------------------------------------- + +To perform an anonymous CVS checkout of the main trunk (this is where +bug fixes and incremental enhancements occur), do this: + +cvs -z3 -d:pserver:anonymous@cvs.sv.gnu.org:/sources/lwip checkout lwip + +Or, obtain a stable branch (updated with bug fixes only) as follows: +cvs -z3 -d:pserver:anonymous@cvs.sv.gnu.org:/sources/lwip checkout \ + -r STABLE-0_7 -d lwip-0.7 lwip + +Or, obtain a specific (fixed) release as follows: +cvs -z3 -d:pserver:anonymous@cvs.sv.gnu.org:/sources/lwip checkout \ + -r STABLE-0_7_0 -d lwip-0.7.0 lwip + +3 Committers/developers CVS access using SSH +-------------------------------------------- + +The Savannah server uses SSH (Secure Shell) protocol 2 authentication and encryption. +As such, CVS commits to the server occur through a SSH tunnel for project members. +To create a SSH2 key pair in UNIX-like environments, do this: + +ssh-keygen -t dsa + +Under Windows, a recommended SSH client is "PuTTY", freely available with good +documentation and a graphic user interface. Use its key generator. + +Now paste the id_dsa.pub contents into your Savannah account public key list. Wait +a while so that Savannah can update its configuration (This can take minutes). + +Try to login using SSH: + +ssh -v your_login@cvs.sv.gnu.org + +If it tells you: + +Authenticating with public key "your_key_name"... +Server refused to allocate pty + +then you could login; Savannah refuses to give you a shell - which is OK, as we +are allowed to use SSH for CVS only. Now, you should be able to do this: + +export CVS_RSH=ssh +cvs -z3 -d:ext:your_login@cvs.sv.gnu.org:/sources/lwip co lwip + +after which you can edit your local files with bug fixes or new features and +commit them. Make sure you know what you are doing when using CVS to make +changes on the repository. If in doubt, ask on the lwip-members mailing list. + +(If SSH asks about authenticity of the host, you can check the key + fingerprint against http://savannah.nongnu.org/cvs/?group=lwip) + + +3 Merging from DEVEL branch to main trunk (stable) +-------------------------------------------------- + +Merging is a delicate process in CVS and requires the +following disciplined steps in order to prevent conflicts +in the future. Conflicts can be hard to solve! + +Merging from branch A to branch B requires that the A branch +has a tag indicating the previous merger. This tag is called +'merged_from_A_to_B'. After merging, the tag is moved in the +A branch to remember this merger for future merge actions. + +IMPORTANT: AFTER COMMITTING A SUCCESFUL MERGE IN THE +REPOSITORY, THE TAG MUST BE SET ON THE SOURCE BRANCH OF THE +MERGE ACTION (REPLACING EXISTING TAGS WITH THE SAME NAME). + +Merge all changes in DEVEL since our last merge to main: + +In the working copy of the main trunk: +cvs update -P -jmerged_from_DEVEL_to_main -jDEVEL + +(This will apply the changes between 'merged_from_DEVEL_to_main' +and 'DEVEL' to your work set of files) + +We can now commit the merge result. +cvs commit -R -m "Merged from DEVEL to main." + +If this worked out OK, we now move the tag in the DEVEL branch +to this merge point, so we can use this point for future merges: + +cvs rtag -F -r DEVEL merged_from_DEVEL_to_main lwip + +4 How to release lwIP +--------------------- + +First, checkout a clean copy of the branch to be released. Tag this set with +tag name "STABLE-0_6_3". (I use release number 0.6.3 throughout this example). + +Login CVS using pserver authentication, then export a clean copy of the +tagged tree. Export is similar to a checkout, except that the CVS metadata +is not created locally. + +export CVS_RSH=ssh +cvs -z3 -d:pserver:anonymous@cvs.sv.gnu.org:/sources/lwip checkout \ + -r STABLE-0_6_3 -d lwip-0.6.3 lwip + +Archive this directory using tar, gzip'd, bzip2'd and zip'd. + +tar czvf lwip-0.6.3.tar.gz lwip-0.6.3 +tar cjvf lwip-0.6.3.tar.bz2 lwip-0.6.3 +zip -r lwip-0.6.3.zip lwip-0.6.3 + +Now, sign the archives with a detached GPG binary signature as follows: + +gpg -b lwip-0.6.3.tar.gz +gpg -b lwip-0.6.3.tar.bz2 +gpg -b lwip-0.6.3.zip + +Upload these files using anonymous FTP: +ncftp ftp://savannah.gnu.org/incoming/savannah/lwip + +ncftp>mput *0.6.3.* + +Additionally, you may post a news item on Savannah, like this: + +A new 0.6.3 release is now available here: +http://savannah.nongnu.org/files/?group=lwip&highlight=0.6.3 + +You will have to submit this via the user News interface, then approve +this via the Administrator News interface. \ No newline at end of file diff --git a/src/lwip-1.4.1/doc/snmp_agent.txt b/src/lwip-1.4.1/doc/snmp_agent.txt new file mode 100644 index 0000000..2653230 --- /dev/null +++ b/src/lwip-1.4.1/doc/snmp_agent.txt @@ -0,0 +1,181 @@ +SNMPv1 agent for lwIP + +Author: Christiaan Simons + +This is a brief introduction how to use and configure the SNMP agent. +Note the agent uses the raw-API UDP interface so you may also want to +read rawapi.txt to gain a better understanding of the SNMP message handling. + +0 Agent Capabilities +==================== + +SNMPv1 per RFC1157 + This is an old(er) standard but is still widely supported. + For SNMPv2c and v3 have a greater complexity and need many + more lines of code. IMHO this breaks the idea of "lightweight IP". + + Note the S in SNMP stands for "Simple". Note that "Simple" is + relative. SNMP is simple compared to the complex ISO network + management protocols CMIP (Common Management Information Protocol) + and CMOT (CMip Over Tcp). + +MIB II per RFC1213 + The standard lwIP stack management information base. + This is a required MIB, so this is always enabled. + When builing lwIP without TCP, the mib-2.tcp group is omitted. + The groups EGP, CMOT and transmission are disabled by default. + + Most mib-2 objects are not writable except: + sysName, sysLocation, sysContact, snmpEnableAuthenTraps. + Writing to or changing the ARP and IP address and route + tables is not possible. + + Note lwIP has a very limited notion of IP routing. It currently + doen't have a route table and doesn't have a notion of the U,G,H flags. + Instead lwIP uses the interface list with only one default interface + acting as a single gateway interface (G) for the default route. + + The agent returns a "virtual table" with the default route 0.0.0.0 + for the default interface and network routes (no H) for each + network interface in the netif_list. + All routes are considered to be up (U). + +Loading additional MIBs + MIBs can only be added in compile-time, not in run-time. + There is no MIB compiler thus additional MIBs must be hand coded. + +Large SNMP message support + The packet decoding and encoding routines are designed + to use pbuf-chains. Larger payloads than the minimum + SNMP requirement of 484 octets are supported if the + PBUF_POOL_SIZE and IP_REASS_BUFSIZE are set to match your + local requirement. + +1 Building the Agent +==================== + +First of all you'll need to add the following define +to your local lwipopts.h: + +#define LWIP_SNMP 1 + +and add the source files in lwip/src/core/snmp +and some snmp headers in lwip/src/include/lwip to your makefile. + +Note you'll might need to adapt you network driver to update +the mib2 variables for your interface. + +2 Running the Agent +=================== + +The following function calls must be made in your program to +actually get the SNMP agent running. + +Before starting the agent you should supply pointers +to non-volatile memory for sysContact, sysLocation, +and snmpEnableAuthenTraps. You can do this by calling + +snmp_set_syscontact() +snmp_set_syslocation() +snmp_set_snmpenableauthentraps() + +Additionally you may want to set + +snmp_set_sysdescr() +snmp_set_sysobjid() (if you have a private MIB) +snmp_set_sysname() + +Also before starting the agent you need to setup +one or more trap destinations using these calls: + +snmp_trap_dst_enable(); +snmp_trap_dst_ip_set(); + +In the lwIP initialisation sequence call snmp_init() just after +the call to udp_init(). + +Exactly every 10 msec the SNMP uptime timestamp must be updated with +snmp_inc_sysuptime(). You should call this from a timer interrupt +or a timer signal handler depending on your runtime environment. + +An alternative way to update the SNMP uptime timestamp is to do a call like +snmp_add_sysuptime(100) each 1000ms (which is bigger "step", but call to +a lower frequency). Another one is to not call snmp_inc_sysuptime() or +snmp_add_sysuptime(), and to define the SNMP_GET_SYSUPTIME(sysuptime) macro. +This one is undefined by default in mib2.c. SNMP_GET_SYSUPTIME is called inside +snmp_get_sysuptime(u32_t *value), and enable to change "sysuptime" value only +when it's queried (any function which need "sysuptime" have to call +snmp_get_sysuptime). + + +3 Private MIBs +============== + +If want to extend the agent with your own private MIB you'll need to +add the following define to your local lwipopts.h: + +#define SNMP_PRIVATE_MIB 1 + +You must provide the private_mib.h and associated files yourself. +Note we don't have a "MIB compiler" that generates C source from a MIB, +so you're required to do some serious coding if you enable this! + +Note the lwIP enterprise ID (26381) is assigned to the lwIP project, +ALL OBJECT IDENTIFIERS LIVING UNDER THIS ID ARE ASSIGNED BY THE lwIP +MAINTAINERS! + +If you need to create your own private MIB you'll need +to apply for your own enterprise ID with IANA: http://www.iana.org/numbers.html + +You can set it by passing a struct snmp_obj_id to the agent +using snmp_set_sysobjid(&my_object_id), just before snmp_init(). + +Note the object identifiers for thes MIB-2 and your private MIB +tree must be kept in sorted ascending (lexicographical) order. +This to ensure correct getnext operation. + +An example for a private MIB is part of the "minimal Unix" project: +contrib/ports/unix/proj/minimal/lwip_prvmib.c + +The next chapter gives a more detailed description of the +MIB-2 tree and the optional private MIB. + +4 The Gory Details +================== + +4.0 Object identifiers and the MIB tree. + +We have three distinct parts for all object identifiers: + +The prefix + .iso.org.dod.internet + +the middle part + .mgmt.mib-2.ip.ipNetToMediaTable.ipNetToMediaEntry.ipNetToMediaPhysAddress + +and the index part + .1.192.168.0.1 + +Objects located above the .internet hierarchy aren't supported. +Currently only the .mgmt sub-tree is available and +when the SNMP_PRIVATE_MIB is enabled the .private tree +becomes available too. + +Object identifiers from incoming requests are checked +for a matching prefix, middle part and index part +or are expanded(*) for GetNext requests with short +or inexisting names in the request. +(* we call this "expansion" but this also +resembles the "auto-completion" operation) + +The middle part is usually located in ROM (const) +to preserve precious RAM on small microcontrollers. +However RAM location is possible for a dynamically +changing private tree. + +The index part is handled by functions which in +turn use dynamically allocated index trees from RAM. +These trees are updated by e.g. the etharp code +when new entries are made or removed form the ARP cache. + +/** @todo more gory details */ diff --git a/src/lwip-1.4.1/doc/sys_arch.txt b/src/lwip-1.4.1/doc/sys_arch.txt new file mode 100644 index 0000000..847cd77 --- /dev/null +++ b/src/lwip-1.4.1/doc/sys_arch.txt @@ -0,0 +1,267 @@ +sys_arch interface for lwIP 0.6++ + +Author: Adam Dunkels + +The operating system emulation layer provides a common interface +between the lwIP code and the underlying operating system kernel. The +general idea is that porting lwIP to new architectures requires only +small changes to a few header files and a new sys_arch +implementation. It is also possible to do a sys_arch implementation +that does not rely on any underlying operating system. + +The sys_arch provides semaphores and mailboxes to lwIP. For the full +lwIP functionality, multiple threads support can be implemented in the +sys_arch, but this is not required for the basic lwIP +functionality. Previous versions of lwIP required the sys_arch to +implement timer scheduling as well but as of lwIP 0.5 this is +implemented in a higher layer. + +In addition to the source file providing the functionality of sys_arch, +the OS emulation layer must provide several header files defining +macros used throughout lwip. The files required and the macros they +must define are listed below the sys_arch description. + +Semaphores can be either counting or binary - lwIP works with both +kinds. Mailboxes are used for message passing and can be implemented +either as a queue which allows multiple messages to be posted to a +mailbox, or as a rendez-vous point where only one message can be +posted at a time. lwIP works with both kinds, but the former type will +be more efficient. A message in a mailbox is just a pointer, nothing +more. + +Semaphores are represented by the type "sys_sem_t" which is typedef'd +in the sys_arch.h file. Mailboxes are equivalently represented by the +type "sys_mbox_t". lwIP does not place any restrictions on how +sys_sem_t or sys_mbox_t are represented internally. + +Since lwIP 1.4.0, semaphore and mailbox functions are prototyped in a way that +allows both using pointers or actual OS structures to be used. This way, memory +required for such types can be either allocated in place (globally or on the +stack) or on the heap (allocated internally in the "*_new()" functions). + +The following functions must be implemented by the sys_arch: + +- void sys_init(void) + + Is called to initialize the sys_arch layer. + +- err_t sys_sem_new(sys_sem_t *sem, u8_t count) + + Creates a new semaphore. The semaphore is allocated to the memory that 'sem' + points to (which can be both a pointer or the actual OS structure). + The "count" argument specifies the initial state of the semaphore (which is + either 0 or 1). + If the semaphore has been created, ERR_OK should be returned. Returning any + other error will provide a hint what went wrong, but except for assertions, + no real error handling is implemented. + +- void sys_sem_free(sys_sem_t *sem) + + Deallocates a semaphore. + +- void sys_sem_signal(sys_sem_t *sem) + + Signals a semaphore. + +- u32_t sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout) + + Blocks the thread while waiting for the semaphore to be + signaled. If the "timeout" argument is non-zero, the thread should + only be blocked for the specified time (measured in + milliseconds). If the "timeout" argument is zero, the thread should be + blocked until the semaphore is signalled. + + If the timeout argument is non-zero, the return value is the number of + milliseconds spent waiting for the semaphore to be signaled. If the + semaphore wasn't signaled within the specified time, the return value is + SYS_ARCH_TIMEOUT. If the thread didn't have to wait for the semaphore + (i.e., it was already signaled), the function may return zero. + + Notice that lwIP implements a function with a similar name, + sys_sem_wait(), that uses the sys_arch_sem_wait() function. + +- int sys_sem_valid(sys_sem_t *sem) + + Returns 1 if the semaphore is valid, 0 if it is not valid. + When using pointers, a simple way is to check the pointer for != NULL. + When directly using OS structures, implementing this may be more complex. + This may also be a define, in which case the function is not prototyped. + +- void sys_sem_set_invalid(sys_sem_t *sem) + + Invalidate a semaphore so that sys_sem_valid() returns 0. + ATTENTION: This does NOT mean that the semaphore shall be deallocated: + sys_sem_free() is always called before calling this function! + This may also be a define, in which case the function is not prototyped. + +- err_t sys_mbox_new(sys_mbox_t *mbox, int size) + + Creates an empty mailbox for maximum "size" elements. Elements stored + in mailboxes are pointers. You have to define macros "_MBOX_SIZE" + in your lwipopts.h, or ignore this parameter in your implementation + and use a default size. + If the mailbox has been created, ERR_OK should be returned. Returning any + other error will provide a hint what went wrong, but except for assertions, + no real error handling is implemented. + +- void sys_mbox_free(sys_mbox_t *mbox) + + Deallocates a mailbox. If there are messages still present in the + mailbox when the mailbox is deallocated, it is an indication of a + programming error in lwIP and the developer should be notified. + +- void sys_mbox_post(sys_mbox_t *mbox, void *msg) + + Posts the "msg" to the mailbox. This function have to block until + the "msg" is really posted. + +- err_t sys_mbox_trypost(sys_mbox_t *mbox, void *msg) + + Try to post the "msg" to the mailbox. Returns ERR_MEM if this one + is full, else, ERR_OK if the "msg" is posted. + +- u32_t sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout) + + Blocks the thread until a message arrives in the mailbox, but does + not block the thread longer than "timeout" milliseconds (similar to + the sys_arch_sem_wait() function). If "timeout" is 0, the thread should + be blocked until a message arrives. The "msg" argument is a result + parameter that is set by the function (i.e., by doing "*msg = + ptr"). The "msg" parameter maybe NULL to indicate that the message + should be dropped. + + The return values are the same as for the sys_arch_sem_wait() function: + Number of milliseconds spent waiting or SYS_ARCH_TIMEOUT if there was a + timeout. + + Note that a function with a similar name, sys_mbox_fetch(), is + implemented by lwIP. + +- u32_t sys_arch_mbox_tryfetch(sys_mbox_t *mbox, void **msg) + + This is similar to sys_arch_mbox_fetch, however if a message is not + present in the mailbox, it immediately returns with the code + SYS_MBOX_EMPTY. On success 0 is returned. + + To allow for efficient implementations, this can be defined as a + function-like macro in sys_arch.h instead of a normal function. For + example, a naive implementation could be: + #define sys_arch_mbox_tryfetch(mbox,msg) \ + sys_arch_mbox_fetch(mbox,msg,1) + although this would introduce unnecessary delays. + +- int sys_mbox_valid(sys_mbox_t *mbox) + + Returns 1 if the mailbox is valid, 0 if it is not valid. + When using pointers, a simple way is to check the pointer for != NULL. + When directly using OS structures, implementing this may be more complex. + This may also be a define, in which case the function is not prototyped. + +- void sys_mbox_set_invalid(sys_mbox_t *mbox) + + Invalidate a mailbox so that sys_mbox_valid() returns 0. + ATTENTION: This does NOT mean that the mailbox shall be deallocated: + sys_mbox_free() is always called before calling this function! + This may also be a define, in which case the function is not prototyped. + +If threads are supported by the underlying operating system and if +such functionality is needed in lwIP, the following function will have +to be implemented as well: + +- sys_thread_t sys_thread_new(char *name, void (* thread)(void *arg), void *arg, int stacksize, int prio) + + Starts a new thread named "name" with priority "prio" that will begin its + execution in the function "thread()". The "arg" argument will be passed as an + argument to the thread() function. The stack size to used for this thread is + the "stacksize" parameter. The id of the new thread is returned. Both the id + and the priority are system dependent. + +- sys_prot_t sys_arch_protect(void) + + This optional function does a "fast" critical region protection and returns + the previous protection level. This function is only called during very short + critical regions. An embedded system which supports ISR-based drivers might + want to implement this function by disabling interrupts. Task-based systems + might want to implement this by using a mutex or disabling tasking. This + function should support recursive calls from the same task or interrupt. In + other words, sys_arch_protect() could be called while already protected. In + that case the return value indicates that it is already protected. + + sys_arch_protect() is only required if your port is supporting an operating + system. + +- void sys_arch_unprotect(sys_prot_t pval) + + This optional function does a "fast" set of critical region protection to the + value specified by pval. See the documentation for sys_arch_protect() for + more information. This function is only required if your port is supporting + an operating system. + +For some configurations, you also need: + +- u32_t sys_now(void) + + This optional function returns the current time in milliseconds (don't care + for wraparound, this is only used for time diffs). + Not implementing this function means you cannot use some modules (e.g. TCP + timestamps, internal timeouts for NO_SYS==1). + + +Note: + +Be carefull with using mem_malloc() in sys_arch. When malloc() refers to +mem_malloc() you can run into a circular function call problem. In mem.c +mem_init() tries to allcate a semaphore using mem_malloc, which of course +can't be performed when sys_arch uses mem_malloc. + +------------------------------------------------------------------------------- +Additional files required for the "OS support" emulation layer: +------------------------------------------------------------------------------- + +cc.h - Architecture environment, some compiler specific, some + environment specific (probably should move env stuff + to sys_arch.h.) + + Typedefs for the types used by lwip - + u8_t, s8_t, u16_t, s16_t, u32_t, s32_t, mem_ptr_t + + Compiler hints for packing lwip's structures - + PACK_STRUCT_FIELD(x) + PACK_STRUCT_STRUCT + PACK_STRUCT_BEGIN + PACK_STRUCT_END + + Platform specific diagnostic output - + LWIP_PLATFORM_DIAG(x) - non-fatal, print a message. + LWIP_PLATFORM_ASSERT(x) - fatal, print message and abandon execution. + Portability defines for printf formatters: + U16_F, S16_F, X16_F, U32_F, S32_F, X32_F, SZT_F + + "lightweight" synchronization mechanisms - + SYS_ARCH_DECL_PROTECT(x) - declare a protection state variable. + SYS_ARCH_PROTECT(x) - enter protection mode. + SYS_ARCH_UNPROTECT(x) - leave protection mode. + + If the compiler does not provide memset() this file must include a + definition of it, or include a file which defines it. + + This file must either include a system-local which defines + the standard *nix error codes, or it should #define LWIP_PROVIDE_ERRNO + to make lwip/arch.h define the codes which are used throughout. + + +perf.h - Architecture specific performance measurement. + Measurement calls made throughout lwip, these can be defined to nothing. + PERF_START - start measuring something. + PERF_STOP(x) - stop measuring something, and record the result. + +sys_arch.h - Tied to sys_arch.c + + Arch dependent types for the following objects: + sys_sem_t, sys_mbox_t, sys_thread_t, + And, optionally: + sys_prot_t + + Defines to set vars of sys_mbox_t and sys_sem_t to NULL. + SYS_MBOX_NULL NULL + SYS_SEM_NULL NULL diff --git a/src/lwip-1.4.1/src/FILES b/src/lwip-1.4.1/src/FILES new file mode 100644 index 0000000..952aeab --- /dev/null +++ b/src/lwip-1.4.1/src/FILES @@ -0,0 +1,13 @@ +api/ - The code for the high-level wrapper API. Not needed if + you use the lowel-level call-back/raw API. + +core/ - The core of the TPC/IP stack; protocol implementations, + memory and buffer management, and the low-level raw API. + +include/ - lwIP include files. + +netif/ - Generic network interface device drivers are kept here, + as well as the ARP module. + +For more information on the various subdirectories, check the FILES +file in each directory. diff --git a/src/lwip-1.4.1/src/api/api_lib.c b/src/lwip-1.4.1/src/api/api_lib.c new file mode 100644 index 0000000..4bdf08e --- /dev/null +++ b/src/lwip-1.4.1/src/api/api_lib.c @@ -0,0 +1,780 @@ +/** + * @file + * Sequential API External module + * + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +/* This is the part of the API that is linked with + the application */ + +#include "lwip/opt.h" + +#if LWIP_NETCONN /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/api.h" +#include "lwip/tcpip.h" +#include "lwip/memp.h" + +#include "lwip/ip.h" +#include "lwip/raw.h" +#include "lwip/udp.h" +#include "lwip/tcp.h" + +#include + +/** + * Create a new netconn (of a specific type) that has a callback function. + * The corresponding pcb is also created. + * + * @param t the type of 'connection' to create (@see enum netconn_type) + * @param proto the IP protocol for RAW IP pcbs + * @param callback a function to call on status changes (RX available, TX'ed) + * @return a newly allocated struct netconn or + * NULL on memory error + */ +struct netconn* +netconn_new_with_proto_and_callback(enum netconn_type t, u8_t proto, netconn_callback callback) +{ + struct netconn *conn; + struct api_msg msg; + + conn = netconn_alloc(t, callback); + if (conn != NULL) { + msg.function = do_newconn; + msg.msg.msg.n.proto = proto; + msg.msg.conn = conn; + if (TCPIP_APIMSG(&msg) != ERR_OK) { + LWIP_ASSERT("freeing conn without freeing pcb", conn->pcb.tcp == NULL); + LWIP_ASSERT("conn has no op_completed", sys_sem_valid(&conn->op_completed)); + LWIP_ASSERT("conn has no recvmbox", sys_mbox_valid(&conn->recvmbox)); +#if LWIP_TCP + LWIP_ASSERT("conn->acceptmbox shouldn't exist", !sys_mbox_valid(&conn->acceptmbox)); +#endif /* LWIP_TCP */ + sys_sem_free(&conn->op_completed); + sys_mbox_free(&conn->recvmbox); + memp_free(MEMP_NETCONN, conn); + return NULL; + } + } + return conn; +} + +/** + * Close a netconn 'connection' and free its resources. + * UDP and RAW connection are completely closed, TCP pcbs might still be in a waitstate + * after this returns. + * + * @param conn the netconn to delete + * @return ERR_OK if the connection was deleted + */ +err_t +netconn_delete(struct netconn *conn) +{ + struct api_msg msg; + + /* No ASSERT here because possible to get a (conn == NULL) if we got an accept error */ + if (conn == NULL) { + return ERR_OK; + } + + msg.function = do_delconn; + msg.msg.conn = conn; + tcpip_apimsg(&msg); + + netconn_free(conn); + + /* don't care for return value of do_delconn since it only calls void functions */ + + return ERR_OK; +} + +/** + * Get the local or remote IP address and port of a netconn. + * For RAW netconns, this returns the protocol instead of a port! + * + * @param conn the netconn to query + * @param addr a pointer to which to save the IP address + * @param port a pointer to which to save the port (or protocol for RAW) + * @param local 1 to get the local IP address, 0 to get the remote one + * @return ERR_CONN for invalid connections + * ERR_OK if the information was retrieved + */ +err_t +netconn_getaddr(struct netconn *conn, ip_addr_t *addr, u16_t *port, u8_t local) +{ + struct api_msg msg; + err_t err; + + LWIP_ERROR("netconn_getaddr: invalid conn", (conn != NULL), return ERR_ARG;); + LWIP_ERROR("netconn_getaddr: invalid addr", (addr != NULL), return ERR_ARG;); + LWIP_ERROR("netconn_getaddr: invalid port", (port != NULL), return ERR_ARG;); + + msg.function = do_getaddr; + msg.msg.conn = conn; + msg.msg.msg.ad.ipaddr = addr; + msg.msg.msg.ad.port = port; + msg.msg.msg.ad.local = local; + err = TCPIP_APIMSG(&msg); + + NETCONN_SET_SAFE_ERR(conn, err); + return err; +} + +/** + * Bind a netconn to a specific local IP address and port. + * Binding one netconn twice might not always be checked correctly! + * + * @param conn the netconn to bind + * @param addr the local IP address to bind the netconn to (use IP_ADDR_ANY + * to bind to all addresses) + * @param port the local port to bind the netconn to (not used for RAW) + * @return ERR_OK if bound, any other err_t on failure + */ +err_t +netconn_bind(struct netconn *conn, ip_addr_t *addr, u16_t port) +{ + struct api_msg msg; + err_t err; + + LWIP_ERROR("netconn_bind: invalid conn", (conn != NULL), return ERR_ARG;); + + msg.function = do_bind; + msg.msg.conn = conn; + msg.msg.msg.bc.ipaddr = addr; + msg.msg.msg.bc.port = port; + err = TCPIP_APIMSG(&msg); + + NETCONN_SET_SAFE_ERR(conn, err); + return err; +} + +/** + * Connect a netconn to a specific remote IP address and port. + * + * @param conn the netconn to connect + * @param addr the remote IP address to connect to + * @param port the remote port to connect to (no used for RAW) + * @return ERR_OK if connected, return value of tcp_/udp_/raw_connect otherwise + */ +err_t +netconn_connect(struct netconn *conn, ip_addr_t *addr, u16_t port) +{ + struct api_msg msg; + err_t err; + + LWIP_ERROR("netconn_connect: invalid conn", (conn != NULL), return ERR_ARG;); + + msg.function = do_connect; + msg.msg.conn = conn; + msg.msg.msg.bc.ipaddr = addr; + msg.msg.msg.bc.port = port; + /* This is the only function which need to not block tcpip_thread */ + err = tcpip_apimsg(&msg); + + NETCONN_SET_SAFE_ERR(conn, err); + return err; +} + +/** + * Disconnect a netconn from its current peer (only valid for UDP netconns). + * + * @param conn the netconn to disconnect + * @return TODO: return value is not set here... + */ +err_t +netconn_disconnect(struct netconn *conn) +{ + struct api_msg msg; + err_t err; + + LWIP_ERROR("netconn_disconnect: invalid conn", (conn != NULL), return ERR_ARG;); + + msg.function = do_disconnect; + msg.msg.conn = conn; + err = TCPIP_APIMSG(&msg); + + NETCONN_SET_SAFE_ERR(conn, err); + return err; +} + +/** + * Set a TCP netconn into listen mode + * + * @param conn the tcp netconn to set to listen mode + * @param backlog the listen backlog, only used if TCP_LISTEN_BACKLOG==1 + * @return ERR_OK if the netconn was set to listen (UDP and RAW netconns + * don't return any error (yet?)) + */ +err_t +netconn_listen_with_backlog(struct netconn *conn, u8_t backlog) +{ +#if LWIP_TCP + struct api_msg msg; + err_t err; + + /* This does no harm. If TCP_LISTEN_BACKLOG is off, backlog is unused. */ + LWIP_UNUSED_ARG(backlog); + + LWIP_ERROR("netconn_listen: invalid conn", (conn != NULL), return ERR_ARG;); + + msg.function = do_listen; + msg.msg.conn = conn; +#if TCP_LISTEN_BACKLOG + msg.msg.msg.lb.backlog = backlog; +#endif /* TCP_LISTEN_BACKLOG */ + err = TCPIP_APIMSG(&msg); + + NETCONN_SET_SAFE_ERR(conn, err); + return err; +#else /* LWIP_TCP */ + LWIP_UNUSED_ARG(conn); + LWIP_UNUSED_ARG(backlog); + return ERR_ARG; +#endif /* LWIP_TCP */ +} + +/** + * Accept a new connection on a TCP listening netconn. + * + * @param conn the TCP listen netconn + * @param new_conn pointer where the new connection is stored + * @return ERR_OK if a new connection has been received or an error + * code otherwise + */ +err_t +netconn_accept(struct netconn *conn, struct netconn **new_conn) +{ +#if LWIP_TCP + struct netconn *newconn; + err_t err; +#if TCP_LISTEN_BACKLOG + struct api_msg msg; +#endif /* TCP_LISTEN_BACKLOG */ + + LWIP_ERROR("netconn_accept: invalid pointer", (new_conn != NULL), return ERR_ARG;); + *new_conn = NULL; + LWIP_ERROR("netconn_accept: invalid conn", (conn != NULL), return ERR_ARG;); + LWIP_ERROR("netconn_accept: invalid acceptmbox", sys_mbox_valid(&conn->acceptmbox), return ERR_ARG;); + + err = conn->last_err; + if (ERR_IS_FATAL(err)) { + /* don't recv on fatal errors: this might block the application task + waiting on acceptmbox forever! */ + return err; + } + +#if LWIP_SO_RCVTIMEO + if (sys_arch_mbox_fetch(&conn->acceptmbox, (void **)&newconn, conn->recv_timeout) == SYS_ARCH_TIMEOUT) { + NETCONN_SET_SAFE_ERR(conn, ERR_TIMEOUT); + return ERR_TIMEOUT; + } +#else + sys_arch_mbox_fetch(&conn->acceptmbox, (void **)&newconn, 0); +#endif /* LWIP_SO_RCVTIMEO*/ + /* Register event with callback */ + API_EVENT(conn, NETCONN_EVT_RCVMINUS, 0); + + if (newconn == NULL) { + /* connection has been aborted */ + NETCONN_SET_SAFE_ERR(conn, ERR_ABRT); + return ERR_ABRT; + } +#if TCP_LISTEN_BACKLOG + /* Let the stack know that we have accepted the connection. */ + msg.function = do_recv; + msg.msg.conn = conn; + /* don't care for the return value of do_recv */ + TCPIP_APIMSG(&msg); +#endif /* TCP_LISTEN_BACKLOG */ + + *new_conn = newconn; + /* don't set conn->last_err: it's only ERR_OK, anyway */ + return ERR_OK; +#else /* LWIP_TCP */ + LWIP_UNUSED_ARG(conn); + LWIP_UNUSED_ARG(new_conn); + return ERR_ARG; +#endif /* LWIP_TCP */ +} + +/** + * Receive data: actual implementation that doesn't care whether pbuf or netbuf + * is received + * + * @param conn the netconn from which to receive data + * @param new_buf pointer where a new pbuf/netbuf is stored when received data + * @return ERR_OK if data has been received, an error code otherwise (timeout, + * memory error or another error) + */ +static err_t +netconn_recv_data(struct netconn *conn, void **new_buf) +{ + void *buf = NULL; + u16_t len; + err_t err; +#if LWIP_TCP + struct api_msg msg; +#endif /* LWIP_TCP */ + + LWIP_ERROR("netconn_recv: invalid pointer", (new_buf != NULL), return ERR_ARG;); + *new_buf = NULL; + LWIP_ERROR("netconn_recv: invalid conn", (conn != NULL), return ERR_ARG;); + LWIP_ERROR("netconn_accept: invalid recvmbox", sys_mbox_valid(&conn->recvmbox), return ERR_CONN;); + + err = conn->last_err; + if (ERR_IS_FATAL(err)) { + /* don't recv on fatal errors: this might block the application task + waiting on recvmbox forever! */ + /* @todo: this does not allow us to fetch data that has been put into recvmbox + before the fatal error occurred - is that a problem? */ + return err; + } + +#if LWIP_SO_RCVTIMEO + if (sys_arch_mbox_fetch(&conn->recvmbox, &buf, conn->recv_timeout) == SYS_ARCH_TIMEOUT) { + NETCONN_SET_SAFE_ERR(conn, ERR_TIMEOUT); + return ERR_TIMEOUT; + } +#else + sys_arch_mbox_fetch(&conn->recvmbox, &buf, 0); +#endif /* LWIP_SO_RCVTIMEO*/ + +#if LWIP_TCP +#if (LWIP_UDP || LWIP_RAW) + if (conn->type == NETCONN_TCP) +#endif /* (LWIP_UDP || LWIP_RAW) */ + { + if (!netconn_get_noautorecved(conn) || (buf == NULL)) { + /* Let the stack know that we have taken the data. */ + /* TODO: Speedup: Don't block and wait for the answer here + (to prevent multiple thread-switches). */ + msg.function = do_recv; + msg.msg.conn = conn; + if (buf != NULL) { + msg.msg.msg.r.len = ((struct pbuf *)buf)->tot_len; + } else { + msg.msg.msg.r.len = 1; + } + /* don't care for the return value of do_recv */ + TCPIP_APIMSG(&msg); + } + + /* If we are closed, we indicate that we no longer wish to use the socket */ + if (buf == NULL) { + API_EVENT(conn, NETCONN_EVT_RCVMINUS, 0); + /* Avoid to lose any previous error code */ + NETCONN_SET_SAFE_ERR(conn, ERR_CLSD); + return ERR_CLSD; + } + len = ((struct pbuf *)buf)->tot_len; + } +#endif /* LWIP_TCP */ +#if LWIP_TCP && (LWIP_UDP || LWIP_RAW) + else +#endif /* LWIP_TCP && (LWIP_UDP || LWIP_RAW) */ +#if (LWIP_UDP || LWIP_RAW) + { + LWIP_ASSERT("buf != NULL", buf != NULL); + len = netbuf_len((struct netbuf *)buf); + } +#endif /* (LWIP_UDP || LWIP_RAW) */ + +#if LWIP_SO_RCVBUF + SYS_ARCH_DEC(conn->recv_avail, len); +#endif /* LWIP_SO_RCVBUF */ + /* Register event with callback */ + API_EVENT(conn, NETCONN_EVT_RCVMINUS, len); + + LWIP_DEBUGF(API_LIB_DEBUG, ("netconn_recv_data: received %p, len=%"U16_F"\n", buf, len)); + + *new_buf = buf; + /* don't set conn->last_err: it's only ERR_OK, anyway */ + return ERR_OK; +} + +/** + * Receive data (in form of a pbuf) from a TCP netconn + * + * @param conn the netconn from which to receive data + * @param new_buf pointer where a new pbuf is stored when received data + * @return ERR_OK if data has been received, an error code otherwise (timeout, + * memory error or another error) + * ERR_ARG if conn is not a TCP netconn + */ +err_t +netconn_recv_tcp_pbuf(struct netconn *conn, struct pbuf **new_buf) +{ + LWIP_ERROR("netconn_recv: invalid conn", (conn != NULL) && + netconn_type(conn) == NETCONN_TCP, return ERR_ARG;); + + return netconn_recv_data(conn, (void **)new_buf); +} + +/** + * Receive data (in form of a netbuf containing a packet buffer) from a netconn + * + * @param conn the netconn from which to receive data + * @param new_buf pointer where a new netbuf is stored when received data + * @return ERR_OK if data has been received, an error code otherwise (timeout, + * memory error or another error) + */ +err_t +netconn_recv(struct netconn *conn, struct netbuf **new_buf) +{ +#if LWIP_TCP + struct netbuf *buf = NULL; + err_t err; +#endif /* LWIP_TCP */ + + LWIP_ERROR("netconn_recv: invalid pointer", (new_buf != NULL), return ERR_ARG;); + *new_buf = NULL; + LWIP_ERROR("netconn_recv: invalid conn", (conn != NULL), return ERR_ARG;); + LWIP_ERROR("netconn_accept: invalid recvmbox", sys_mbox_valid(&conn->recvmbox), return ERR_CONN;); + +#if LWIP_TCP +#if (LWIP_UDP || LWIP_RAW) + if (conn->type == NETCONN_TCP) +#endif /* (LWIP_UDP || LWIP_RAW) */ + { + struct pbuf *p = NULL; + /* This is not a listening netconn, since recvmbox is set */ + + buf = (struct netbuf *)memp_malloc(MEMP_NETBUF); + if (buf == NULL) { + NETCONN_SET_SAFE_ERR(conn, ERR_MEM); + return ERR_MEM; + } + + err = netconn_recv_data(conn, (void **)&p); + if (err != ERR_OK) { + memp_free(MEMP_NETBUF, buf); + return err; + } + LWIP_ASSERT("p != NULL", p != NULL); + + buf->p = p; + buf->ptr = p; + buf->port = 0; + ip_addr_set_any(&buf->addr); + *new_buf = buf; + /* don't set conn->last_err: it's only ERR_OK, anyway */ + return ERR_OK; + } +#endif /* LWIP_TCP */ +#if LWIP_TCP && (LWIP_UDP || LWIP_RAW) + else +#endif /* LWIP_TCP && (LWIP_UDP || LWIP_RAW) */ + { +#if (LWIP_UDP || LWIP_RAW) + return netconn_recv_data(conn, (void **)new_buf); +#endif /* (LWIP_UDP || LWIP_RAW) */ + } +} + +/** + * TCP: update the receive window: by calling this, the application + * tells the stack that it has processed data and is able to accept + * new data. + * ATTENTION: use with care, this is mainly used for sockets! + * Can only be used when calling netconn_set_noautorecved(conn, 1) before. + * + * @param conn the netconn for which to update the receive window + * @param length amount of data processed (ATTENTION: this must be accurate!) + */ +void +netconn_recved(struct netconn *conn, u32_t length) +{ +#if LWIP_TCP + if ((conn != NULL) && (conn->type == NETCONN_TCP) && + (netconn_get_noautorecved(conn))) { + struct api_msg msg; + /* Let the stack know that we have taken the data. */ + /* TODO: Speedup: Don't block and wait for the answer here + (to prevent multiple thread-switches). */ + msg.function = do_recv; + msg.msg.conn = conn; + msg.msg.msg.r.len = length; + /* don't care for the return value of do_recv */ + TCPIP_APIMSG(&msg); + } +#else /* LWIP_TCP */ + LWIP_UNUSED_ARG(conn); + LWIP_UNUSED_ARG(length); +#endif /* LWIP_TCP */ +} + +/** + * Send data (in form of a netbuf) to a specific remote IP address and port. + * Only to be used for UDP and RAW netconns (not TCP). + * + * @param conn the netconn over which to send data + * @param buf a netbuf containing the data to send + * @param addr the remote IP address to which to send the data + * @param port the remote port to which to send the data + * @return ERR_OK if data was sent, any other err_t on error + */ +err_t +netconn_sendto(struct netconn *conn, struct netbuf *buf, ip_addr_t *addr, u16_t port) +{ + if (buf != NULL) { + ip_addr_set(&buf->addr, addr); + buf->port = port; + return netconn_send(conn, buf); + } + return ERR_VAL; +} + +/** + * Send data over a UDP or RAW netconn (that is already connected). + * + * @param conn the UDP or RAW netconn over which to send data + * @param buf a netbuf containing the data to send + * @return ERR_OK if data was sent, any other err_t on error + */ +err_t +netconn_send(struct netconn *conn, struct netbuf *buf) +{ + struct api_msg msg; + err_t err; + + LWIP_ERROR("netconn_send: invalid conn", (conn != NULL), return ERR_ARG;); + + LWIP_DEBUGF(API_LIB_DEBUG, ("netconn_send: sending %"U16_F" bytes\n", buf->p->tot_len)); + msg.function = do_send; + msg.msg.conn = conn; + msg.msg.msg.b = buf; + err = TCPIP_APIMSG(&msg); + + NETCONN_SET_SAFE_ERR(conn, err); + return err; +} + +/** + * Send data over a TCP netconn. + * + * @param conn the TCP netconn over which to send data + * @param dataptr pointer to the application buffer that contains the data to send + * @param size size of the application data to send + * @param apiflags combination of following flags : + * - NETCONN_COPY: data will be copied into memory belonging to the stack + * - NETCONN_MORE: for TCP connection, PSH flag will be set on last segment sent + * - NETCONN_DONTBLOCK: only write the data if all dat can be written at once + * @param bytes_written pointer to a location that receives the number of written bytes + * @return ERR_OK if data was sent, any other err_t on error + */ +err_t +netconn_write_partly(struct netconn *conn, const void *dataptr, size_t size, + u8_t apiflags, size_t *bytes_written) +{ + struct api_msg msg; + err_t err; + u8_t dontblock; + + LWIP_ERROR("netconn_write: invalid conn", (conn != NULL), return ERR_ARG;); + LWIP_ERROR("netconn_write: invalid conn->type", (conn->type == NETCONN_TCP), return ERR_VAL;); + if (size == 0) { + return ERR_OK; + } + dontblock = netconn_is_nonblocking(conn) || (apiflags & NETCONN_DONTBLOCK); + if (dontblock && !bytes_written) { + /* This implies netconn_write() cannot be used for non-blocking send, since + it has no way to return the number of bytes written. */ + return ERR_VAL; + } + + /* non-blocking write sends as much */ + msg.function = do_write; + msg.msg.conn = conn; + msg.msg.msg.w.dataptr = dataptr; + msg.msg.msg.w.apiflags = apiflags; + msg.msg.msg.w.len = size; +#if LWIP_SO_SNDTIMEO + if (conn->send_timeout != 0) { + /* get the time we started, which is later compared to + sys_now() + conn->send_timeout */ + msg.msg.msg.w.time_started = sys_now(); + } else { + msg.msg.msg.w.time_started = 0; + } +#endif /* LWIP_SO_SNDTIMEO */ + + /* For locking the core: this _can_ be delayed on low memory/low send buffer, + but if it is, this is done inside api_msg.c:do_write(), so we can use the + non-blocking version here. */ + err = TCPIP_APIMSG(&msg); + if ((err == ERR_OK) && (bytes_written != NULL)) { + if (dontblock +#if LWIP_SO_SNDTIMEO + || (conn->send_timeout != 0) +#endif /* LWIP_SO_SNDTIMEO */ + ) { + /* nonblocking write: maybe the data has been sent partly */ + *bytes_written = msg.msg.msg.w.len; + } else { + /* blocking call succeeded: all data has been sent if it */ + *bytes_written = size; + } + } + + NETCONN_SET_SAFE_ERR(conn, err); + return err; +} + +/** + * Close ot shutdown a TCP netconn (doesn't delete it). + * + * @param conn the TCP netconn to close or shutdown + * @param how fully close or only shutdown one side? + * @return ERR_OK if the netconn was closed, any other err_t on error + */ +static err_t +netconn_close_shutdown(struct netconn *conn, u8_t how) +{ + struct api_msg msg; + err_t err; + + LWIP_ERROR("netconn_close: invalid conn", (conn != NULL), return ERR_ARG;); + + msg.function = do_close; + msg.msg.conn = conn; + /* shutting down both ends is the same as closing */ + msg.msg.msg.sd.shut = how; + /* because of the LWIP_TCPIP_CORE_LOCKING implementation of do_close, + don't use TCPIP_APIMSG here */ + err = tcpip_apimsg(&msg); + + NETCONN_SET_SAFE_ERR(conn, err); + return err; +} + +/** + * Close a TCP netconn (doesn't delete it). + * + * @param conn the TCP netconn to close + * @return ERR_OK if the netconn was closed, any other err_t on error + */ +err_t +netconn_close(struct netconn *conn) +{ + /* shutting down both ends is the same as closing */ + return netconn_close_shutdown(conn, NETCONN_SHUT_RDWR); +} + +/** + * Shut down one or both sides of a TCP netconn (doesn't delete it). + * + * @param conn the TCP netconn to shut down + * @return ERR_OK if the netconn was closed, any other err_t on error + */ +err_t +netconn_shutdown(struct netconn *conn, u8_t shut_rx, u8_t shut_tx) +{ + return netconn_close_shutdown(conn, (shut_rx ? NETCONN_SHUT_RD : 0) | (shut_tx ? NETCONN_SHUT_WR : 0)); +} + +#if LWIP_IGMP +/** + * Join multicast groups for UDP netconns. + * + * @param conn the UDP netconn for which to change multicast addresses + * @param multiaddr IP address of the multicast group to join or leave + * @param netif_addr the IP address of the network interface on which to send + * the igmp message + * @param join_or_leave flag whether to send a join- or leave-message + * @return ERR_OK if the action was taken, any err_t on error + */ +err_t +netconn_join_leave_group(struct netconn *conn, + ip_addr_t *multiaddr, + ip_addr_t *netif_addr, + enum netconn_igmp join_or_leave) +{ + struct api_msg msg; + err_t err; + + LWIP_ERROR("netconn_join_leave_group: invalid conn", (conn != NULL), return ERR_ARG;); + + msg.function = do_join_leave_group; + msg.msg.conn = conn; + msg.msg.msg.jl.multiaddr = multiaddr; + msg.msg.msg.jl.netif_addr = netif_addr; + msg.msg.msg.jl.join_or_leave = join_or_leave; + err = TCPIP_APIMSG(&msg); + + NETCONN_SET_SAFE_ERR(conn, err); + return err; +} +#endif /* LWIP_IGMP */ + +#if LWIP_DNS +/** + * Execute a DNS query, only one IP address is returned + * + * @param name a string representation of the DNS host name to query + * @param addr a preallocated ip_addr_t where to store the resolved IP address + * @return ERR_OK: resolving succeeded + * ERR_MEM: memory error, try again later + * ERR_ARG: dns client not initialized or invalid hostname + * ERR_VAL: dns server response was invalid + */ +err_t +netconn_gethostbyname(const char *name, ip_addr_t *addr) +{ + struct dns_api_msg msg; + err_t err; + sys_sem_t sem; + + LWIP_ERROR("netconn_gethostbyname: invalid name", (name != NULL), return ERR_ARG;); + LWIP_ERROR("netconn_gethostbyname: invalid addr", (addr != NULL), return ERR_ARG;); + + err = sys_sem_new(&sem, 0); + if (err != ERR_OK) { + return err; + } + + msg.name = name; + msg.addr = addr; + msg.err = &err; + msg.sem = &sem; + + tcpip_callback(do_gethostbyname, &msg); + sys_sem_wait(&sem); + sys_sem_free(&sem); + + return err; +} +#endif /* LWIP_DNS*/ + +#endif /* LWIP_NETCONN */ diff --git a/src/lwip-1.4.1/src/api/api_msg.c b/src/lwip-1.4.1/src/api/api_msg.c new file mode 100644 index 0000000..d4e44b9 --- /dev/null +++ b/src/lwip-1.4.1/src/api/api_msg.c @@ -0,0 +1,1565 @@ +/** + * @file + * Sequential API Internal module + * + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#include "lwip/opt.h" + +#if LWIP_NETCONN /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/api_msg.h" + +#include "lwip/ip.h" +#include "lwip/udp.h" +#include "lwip/tcp.h" +#include "lwip/raw.h" + +#include "lwip/memp.h" +#include "lwip/tcpip.h" +#include "lwip/igmp.h" +#include "lwip/dns.h" + +#include + +#define SET_NONBLOCKING_CONNECT(conn, val) do { if(val) { \ + (conn)->flags |= NETCONN_FLAG_IN_NONBLOCKING_CONNECT; \ +} else { \ + (conn)->flags &= ~ NETCONN_FLAG_IN_NONBLOCKING_CONNECT; }} while(0) +#define IN_NONBLOCKING_CONNECT(conn) (((conn)->flags & NETCONN_FLAG_IN_NONBLOCKING_CONNECT) != 0) + +/* forward declarations */ +#if LWIP_TCP +static err_t do_writemore(struct netconn *conn); +static void do_close_internal(struct netconn *conn); +#endif + +#if LWIP_RAW +/** + * Receive callback function for RAW netconns. + * Doesn't 'eat' the packet, only references it and sends it to + * conn->recvmbox + * + * @see raw.h (struct raw_pcb.recv) for parameters and return value + */ +static u8_t +recv_raw(void *arg, struct raw_pcb *pcb, struct pbuf *p, + ip_addr_t *addr) +{ + struct pbuf *q; + struct netbuf *buf; + struct netconn *conn; + + LWIP_UNUSED_ARG(addr); + conn = (struct netconn *)arg; + + if ((conn != NULL) && sys_mbox_valid(&conn->recvmbox)) { +#if LWIP_SO_RCVBUF + int recv_avail; + SYS_ARCH_GET(conn->recv_avail, recv_avail); + if ((recv_avail + (int)(p->tot_len)) > conn->recv_bufsize) { + return 0; + } +#endif /* LWIP_SO_RCVBUF */ + /* copy the whole packet into new pbufs */ + q = pbuf_alloc(PBUF_RAW, p->tot_len, PBUF_RAM); + if(q != NULL) { + if (pbuf_copy(q, p) != ERR_OK) { + pbuf_free(q); + q = NULL; + } + } + + if (q != NULL) { + u16_t len; + buf = (struct netbuf *)memp_malloc(MEMP_NETBUF); + if (buf == NULL) { + pbuf_free(q); + return 0; + } + + buf->p = q; + buf->ptr = q; + ip_addr_copy(buf->addr, *ip_current_src_addr()); + buf->port = pcb->protocol; + + len = q->tot_len; + if (sys_mbox_trypost(&conn->recvmbox, buf) != ERR_OK) { + netbuf_delete(buf); + return 0; + } else { +#if LWIP_SO_RCVBUF + SYS_ARCH_INC(conn->recv_avail, len); +#endif /* LWIP_SO_RCVBUF */ + /* Register event with callback */ + API_EVENT(conn, NETCONN_EVT_RCVPLUS, len); + } + } + } + + return 0; /* do not eat the packet */ +} +#endif /* LWIP_RAW*/ + +#if LWIP_UDP +/** + * Receive callback function for UDP netconns. + * Posts the packet to conn->recvmbox or deletes it on memory error. + * + * @see udp.h (struct udp_pcb.recv) for parameters + */ +static void +recv_udp(void *arg, struct udp_pcb *pcb, struct pbuf *p, + ip_addr_t *addr, u16_t port) +{ + struct netbuf *buf; + struct netconn *conn; + u16_t len; +#if LWIP_SO_RCVBUF + int recv_avail; +#endif /* LWIP_SO_RCVBUF */ + + LWIP_UNUSED_ARG(pcb); /* only used for asserts... */ + LWIP_ASSERT("recv_udp must have a pcb argument", pcb != NULL); + LWIP_ASSERT("recv_udp must have an argument", arg != NULL); + conn = (struct netconn *)arg; + LWIP_ASSERT("recv_udp: recv for wrong pcb!", conn->pcb.udp == pcb); + +#if LWIP_SO_RCVBUF + SYS_ARCH_GET(conn->recv_avail, recv_avail); + if ((conn == NULL) || !sys_mbox_valid(&conn->recvmbox) || + ((recv_avail + (int)(p->tot_len)) > conn->recv_bufsize)) { +#else /* LWIP_SO_RCVBUF */ + if ((conn == NULL) || !sys_mbox_valid(&conn->recvmbox)) { +#endif /* LWIP_SO_RCVBUF */ + pbuf_free(p); + return; + } + + buf = (struct netbuf *)memp_malloc(MEMP_NETBUF); + if (buf == NULL) { + pbuf_free(p); + return; + } else { + buf->p = p; + buf->ptr = p; + ip_addr_set(&buf->addr, addr); + buf->port = port; +#if LWIP_NETBUF_RECVINFO + { + const struct ip_hdr* iphdr = ip_current_header(); + /* get the UDP header - always in the first pbuf, ensured by udp_input */ + const struct udp_hdr* udphdr = (void*)(((char*)iphdr) + IPH_LEN(iphdr)); +#if LWIP_CHECKSUM_ON_COPY + buf->flags = NETBUF_FLAG_DESTADDR; +#endif /* LWIP_CHECKSUM_ON_COPY */ + ip_addr_set(&buf->toaddr, ip_current_dest_addr()); + buf->toport_chksum = udphdr->dest; + } +#endif /* LWIP_NETBUF_RECVINFO */ + } + + len = p->tot_len; + if (sys_mbox_trypost(&conn->recvmbox, buf) != ERR_OK) { + netbuf_delete(buf); + return; + } else { +#if LWIP_SO_RCVBUF + SYS_ARCH_INC(conn->recv_avail, len); +#endif /* LWIP_SO_RCVBUF */ + /* Register event with callback */ + API_EVENT(conn, NETCONN_EVT_RCVPLUS, len); + } +} +#endif /* LWIP_UDP */ + +#if LWIP_TCP +/** + * Receive callback function for TCP netconns. + * Posts the packet to conn->recvmbox, but doesn't delete it on errors. + * + * @see tcp.h (struct tcp_pcb.recv) for parameters and return value + */ +static err_t +recv_tcp(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err) +{ + struct netconn *conn; + u16_t len; + + LWIP_UNUSED_ARG(pcb); + LWIP_ASSERT("recv_tcp must have a pcb argument", pcb != NULL); + LWIP_ASSERT("recv_tcp must have an argument", arg != NULL); + conn = (struct netconn *)arg; + LWIP_ASSERT("recv_tcp: recv for wrong pcb!", conn->pcb.tcp == pcb); + + if (conn == NULL) { + return ERR_VAL; + } + if (!sys_mbox_valid(&conn->recvmbox)) { + /* recvmbox already deleted */ + if (p != NULL) { + tcp_recved(pcb, p->tot_len); + pbuf_free(p); + } + return ERR_OK; + } + /* Unlike for UDP or RAW pcbs, don't check for available space + using recv_avail since that could break the connection + (data is already ACKed) */ + + /* don't overwrite fatal errors! */ + NETCONN_SET_SAFE_ERR(conn, err); + + if (p != NULL) { + len = p->tot_len; + } else { + len = 0; + } + + if (sys_mbox_trypost(&conn->recvmbox, p) != ERR_OK) { + /* don't deallocate p: it is presented to us later again from tcp_fasttmr! */ + return ERR_MEM; + } else { +#if LWIP_SO_RCVBUF + SYS_ARCH_INC(conn->recv_avail, len); +#endif /* LWIP_SO_RCVBUF */ + /* Register event with callback */ + API_EVENT(conn, NETCONN_EVT_RCVPLUS, len); + } + + return ERR_OK; +} + +/** + * Poll callback function for TCP netconns. + * Wakes up an application thread that waits for a connection to close + * or data to be sent. The application thread then takes the + * appropriate action to go on. + * + * Signals the conn->sem. + * netconn_close waits for conn->sem if closing failed. + * + * @see tcp.h (struct tcp_pcb.poll) for parameters and return value + */ +static err_t +poll_tcp(void *arg, struct tcp_pcb *pcb) +{ + struct netconn *conn = (struct netconn *)arg; + + LWIP_UNUSED_ARG(pcb); + LWIP_ASSERT("conn != NULL", (conn != NULL)); + + if (conn->state == NETCONN_WRITE) { + do_writemore(conn); + } else if (conn->state == NETCONN_CLOSE) { + do_close_internal(conn); + } + /* @todo: implement connect timeout here? */ + + /* Did a nonblocking write fail before? Then check available write-space. */ + if (conn->flags & NETCONN_FLAG_CHECK_WRITESPACE) { + /* If the queued byte- or pbuf-count drops below the configured low-water limit, + let select mark this pcb as writable again. */ + if ((conn->pcb.tcp != NULL) && (tcp_sndbuf(conn->pcb.tcp) > TCP_SNDLOWAT) && + (tcp_sndqueuelen(conn->pcb.tcp) < TCP_SNDQUEUELOWAT)) { + conn->flags &= ~NETCONN_FLAG_CHECK_WRITESPACE; + API_EVENT(conn, NETCONN_EVT_SENDPLUS, 0); + } + } + + return ERR_OK; +} + +/** + * Sent callback function for TCP netconns. + * Signals the conn->sem and calls API_EVENT. + * netconn_write waits for conn->sem if send buffer is low. + * + * @see tcp.h (struct tcp_pcb.sent) for parameters and return value + */ +static err_t +sent_tcp(void *arg, struct tcp_pcb *pcb, u16_t len) +{ + struct netconn *conn = (struct netconn *)arg; + + LWIP_UNUSED_ARG(pcb); + LWIP_ASSERT("conn != NULL", (conn != NULL)); + + if (conn->state == NETCONN_WRITE) { + do_writemore(conn); + } else if (conn->state == NETCONN_CLOSE) { + do_close_internal(conn); + } + + if (conn) { + /* If the queued byte- or pbuf-count drops below the configured low-water limit, + let select mark this pcb as writable again. */ + if ((conn->pcb.tcp != NULL) && (tcp_sndbuf(conn->pcb.tcp) > TCP_SNDLOWAT) && + (tcp_sndqueuelen(conn->pcb.tcp) < TCP_SNDQUEUELOWAT)) { + conn->flags &= ~NETCONN_FLAG_CHECK_WRITESPACE; + API_EVENT(conn, NETCONN_EVT_SENDPLUS, len); + } + } + + return ERR_OK; +} + +/** + * Error callback function for TCP netconns. + * Signals conn->sem, posts to all conn mboxes and calls API_EVENT. + * The application thread has then to decide what to do. + * + * @see tcp.h (struct tcp_pcb.err) for parameters + */ +static void +err_tcp(void *arg, err_t err) +{ + struct netconn *conn; + enum netconn_state old_state; + SYS_ARCH_DECL_PROTECT(lev); + + conn = (struct netconn *)arg; + LWIP_ASSERT("conn != NULL", (conn != NULL)); + + conn->pcb.tcp = NULL; + + /* no check since this is always fatal! */ + SYS_ARCH_PROTECT(lev); + conn->last_err = err; + SYS_ARCH_UNPROTECT(lev); + + /* reset conn->state now before waking up other threads */ + old_state = conn->state; + conn->state = NETCONN_NONE; + + /* Notify the user layer about a connection error. Used to signal + select. */ + API_EVENT(conn, NETCONN_EVT_ERROR, 0); + /* Try to release selects pending on 'read' or 'write', too. + They will get an error if they actually try to read or write. */ + API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0); + API_EVENT(conn, NETCONN_EVT_SENDPLUS, 0); + + /* pass NULL-message to recvmbox to wake up pending recv */ + if (sys_mbox_valid(&conn->recvmbox)) { + /* use trypost to prevent deadlock */ + sys_mbox_trypost(&conn->recvmbox, NULL); + } + /* pass NULL-message to acceptmbox to wake up pending accept */ + if (sys_mbox_valid(&conn->acceptmbox)) { + /* use trypost to preven deadlock */ + sys_mbox_trypost(&conn->acceptmbox, NULL); + } + + if ((old_state == NETCONN_WRITE) || (old_state == NETCONN_CLOSE) || + (old_state == NETCONN_CONNECT)) { + /* calling do_writemore/do_close_internal is not necessary + since the pcb has already been deleted! */ + int was_nonblocking_connect = IN_NONBLOCKING_CONNECT(conn); + SET_NONBLOCKING_CONNECT(conn, 0); + + if (!was_nonblocking_connect) { + /* set error return code */ + LWIP_ASSERT("conn->current_msg != NULL", conn->current_msg != NULL); + conn->current_msg->err = err; + conn->current_msg = NULL; + /* wake up the waiting task */ + sys_sem_signal(&conn->op_completed); + } + } else { + LWIP_ASSERT("conn->current_msg == NULL", conn->current_msg == NULL); + } +} + +/** + * Setup a tcp_pcb with the correct callback function pointers + * and their arguments. + * + * @param conn the TCP netconn to setup + */ +static void +setup_tcp(struct netconn *conn) +{ + struct tcp_pcb *pcb; + + pcb = conn->pcb.tcp; + tcp_arg(pcb, conn); + tcp_recv(pcb, recv_tcp); + tcp_sent(pcb, sent_tcp); + tcp_poll(pcb, poll_tcp, 4); + tcp_err(pcb, err_tcp); +} + +/** + * Accept callback function for TCP netconns. + * Allocates a new netconn and posts that to conn->acceptmbox. + * + * @see tcp.h (struct tcp_pcb_listen.accept) for parameters and return value + */ +static err_t +accept_function(void *arg, struct tcp_pcb *newpcb, err_t err) +{ + struct netconn *newconn; + struct netconn *conn = (struct netconn *)arg; + + LWIP_DEBUGF(API_MSG_DEBUG, ("accept_function: newpcb->tate: %s\n", tcp_debug_state_str(newpcb->state))); + + if (!sys_mbox_valid(&conn->acceptmbox)) { + LWIP_DEBUGF(API_MSG_DEBUG, ("accept_function: acceptmbox already deleted\n")); + return ERR_VAL; + } + + /* We have to set the callback here even though + * the new socket is unknown. conn->socket is marked as -1. */ + newconn = netconn_alloc(conn->type, conn->callback); + if (newconn == NULL) { + return ERR_MEM; + } + newconn->pcb.tcp = newpcb; + setup_tcp(newconn); + /* no protection: when creating the pcb, the netconn is not yet known + to the application thread */ + newconn->last_err = err; + + if (sys_mbox_trypost(&conn->acceptmbox, newconn) != ERR_OK) { + /* When returning != ERR_OK, the pcb is aborted in tcp_process(), + so do nothing here! */ + /* remove all references to this netconn from the pcb */ + struct tcp_pcb* pcb = newconn->pcb.tcp; + tcp_arg(pcb, NULL); + tcp_recv(pcb, NULL); + tcp_sent(pcb, NULL); + tcp_poll(pcb, NULL, 4); + tcp_err(pcb, NULL); + /* remove reference from to the pcb from this netconn */ + newconn->pcb.tcp = NULL; + /* no need to drain since we know the recvmbox is empty. */ + sys_mbox_free(&newconn->recvmbox); + sys_mbox_set_invalid(&newconn->recvmbox); + netconn_free(newconn); + return ERR_MEM; + } else { + /* Register event with callback */ + API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0); + } + + return ERR_OK; +} +#endif /* LWIP_TCP */ + +/** + * Create a new pcb of a specific type. + * Called from do_newconn(). + * + * @param msg the api_msg_msg describing the connection type + * @return msg->conn->err, but the return value is currently ignored + */ +static void +pcb_new(struct api_msg_msg *msg) +{ + LWIP_ASSERT("pcb_new: pcb already allocated", msg->conn->pcb.tcp == NULL); + + /* Allocate a PCB for this connection */ + switch(NETCONNTYPE_GROUP(msg->conn->type)) { +#if LWIP_RAW + case NETCONN_RAW: + msg->conn->pcb.raw = raw_new(msg->msg.n.proto); + if(msg->conn->pcb.raw == NULL) { + msg->err = ERR_MEM; + break; + } + raw_recv(msg->conn->pcb.raw, recv_raw, msg->conn); + break; +#endif /* LWIP_RAW */ +#if LWIP_UDP + case NETCONN_UDP: + msg->conn->pcb.udp = udp_new(); + if(msg->conn->pcb.udp == NULL) { + msg->err = ERR_MEM; + break; + } +#if LWIP_UDPLITE + if (msg->conn->type==NETCONN_UDPLITE) { + udp_setflags(msg->conn->pcb.udp, UDP_FLAGS_UDPLITE); + } +#endif /* LWIP_UDPLITE */ + if (msg->conn->type==NETCONN_UDPNOCHKSUM) { + udp_setflags(msg->conn->pcb.udp, UDP_FLAGS_NOCHKSUM); + } + udp_recv(msg->conn->pcb.udp, recv_udp, msg->conn); + break; +#endif /* LWIP_UDP */ +#if LWIP_TCP + case NETCONN_TCP: + msg->conn->pcb.tcp = tcp_new(); + if(msg->conn->pcb.tcp == NULL) { + msg->err = ERR_MEM; + break; + } + setup_tcp(msg->conn); + break; +#endif /* LWIP_TCP */ + default: + /* Unsupported netconn type, e.g. protocol disabled */ + msg->err = ERR_VAL; + break; + } +} + +/** + * Create a new pcb of a specific type inside a netconn. + * Called from netconn_new_with_proto_and_callback. + * + * @param msg the api_msg_msg describing the connection type + */ +void +do_newconn(struct api_msg_msg *msg) +{ + msg->err = ERR_OK; + if(msg->conn->pcb.tcp == NULL) { + pcb_new(msg); + } + /* Else? This "new" connection already has a PCB allocated. */ + /* Is this an error condition? Should it be deleted? */ + /* We currently just are happy and return. */ + + TCPIP_APIMSG_ACK(msg); +} + +/** + * Create a new netconn (of a specific type) that has a callback function. + * The corresponding pcb is NOT created! + * + * @param t the type of 'connection' to create (@see enum netconn_type) + * @param proto the IP protocol for RAW IP pcbs + * @param callback a function to call on status changes (RX available, TX'ed) + * @return a newly allocated struct netconn or + * NULL on memory error + */ +struct netconn* +netconn_alloc(enum netconn_type t, netconn_callback callback) +{ + struct netconn *conn; + int size; + + conn = (struct netconn *)memp_malloc(MEMP_NETCONN); + if (conn == NULL) { + return NULL; + } + + conn->last_err = ERR_OK; + conn->type = t; + conn->pcb.tcp = NULL; + +#if (DEFAULT_RAW_RECVMBOX_SIZE == DEFAULT_UDP_RECVMBOX_SIZE) && \ + (DEFAULT_RAW_RECVMBOX_SIZE == DEFAULT_TCP_RECVMBOX_SIZE) + size = DEFAULT_RAW_RECVMBOX_SIZE; +#else + switch(NETCONNTYPE_GROUP(t)) { +#if LWIP_RAW + case NETCONN_RAW: + size = DEFAULT_RAW_RECVMBOX_SIZE; + break; +#endif /* LWIP_RAW */ +#if LWIP_UDP + case NETCONN_UDP: + size = DEFAULT_UDP_RECVMBOX_SIZE; + break; +#endif /* LWIP_UDP */ +#if LWIP_TCP + case NETCONN_TCP: + size = DEFAULT_TCP_RECVMBOX_SIZE; + break; +#endif /* LWIP_TCP */ + default: + LWIP_ASSERT("netconn_alloc: undefined netconn_type", 0); + goto free_and_return; + } +#endif + + if (sys_sem_new(&conn->op_completed, 0) != ERR_OK) { + goto free_and_return; + } + if (sys_mbox_new(&conn->recvmbox, size) != ERR_OK) { + sys_sem_free(&conn->op_completed); + goto free_and_return; + } + +#if LWIP_TCP + sys_mbox_set_invalid(&conn->acceptmbox); +#endif + conn->state = NETCONN_NONE; +#if LWIP_SOCKET + /* initialize socket to -1 since 0 is a valid socket */ + conn->socket = -1; +#endif /* LWIP_SOCKET */ + conn->callback = callback; +#if LWIP_TCP + conn->current_msg = NULL; + conn->write_offset = 0; +#endif /* LWIP_TCP */ +#if LWIP_SO_SNDTIMEO + conn->send_timeout = 0; +#endif /* LWIP_SO_SNDTIMEO */ +#if LWIP_SO_RCVTIMEO + conn->recv_timeout = 0; +#endif /* LWIP_SO_RCVTIMEO */ +#if LWIP_SO_RCVBUF + conn->recv_bufsize = RECV_BUFSIZE_DEFAULT; + conn->recv_avail = 0; +#endif /* LWIP_SO_RCVBUF */ + conn->flags = 0; + return conn; +free_and_return: + memp_free(MEMP_NETCONN, conn); + return NULL; +} + +/** + * Delete a netconn and all its resources. + * The pcb is NOT freed (since we might not be in the right thread context do this). + * + * @param conn the netconn to free + */ +void +netconn_free(struct netconn *conn) +{ + LWIP_ASSERT("PCB must be deallocated outside this function", conn->pcb.tcp == NULL); + LWIP_ASSERT("recvmbox must be deallocated before calling this function", + !sys_mbox_valid(&conn->recvmbox)); +#if LWIP_TCP + LWIP_ASSERT("acceptmbox must be deallocated before calling this function", + !sys_mbox_valid(&conn->acceptmbox)); +#endif /* LWIP_TCP */ + + sys_sem_free(&conn->op_completed); + sys_sem_set_invalid(&conn->op_completed); + + memp_free(MEMP_NETCONN, conn); +} + +/** + * Delete rcvmbox and acceptmbox of a netconn and free the left-over data in + * these mboxes + * + * @param conn the netconn to free + * @bytes_drained bytes drained from recvmbox + * @accepts_drained pending connections drained from acceptmbox + */ +static void +netconn_drain(struct netconn *conn) +{ + void *mem; +#if LWIP_TCP + struct pbuf *p; +#endif /* LWIP_TCP */ + + /* This runs in tcpip_thread, so we don't need to lock against rx packets */ + + /* Delete and drain the recvmbox. */ + if (sys_mbox_valid(&conn->recvmbox)) { + while (sys_mbox_tryfetch(&conn->recvmbox, &mem) != SYS_MBOX_EMPTY) { +#if LWIP_TCP + if (conn->type == NETCONN_TCP) { + if(mem != NULL) { + p = (struct pbuf*)mem; + /* pcb might be set to NULL already by err_tcp() */ + if (conn->pcb.tcp != NULL) { + tcp_recved(conn->pcb.tcp, p->tot_len); + } + pbuf_free(p); + } + } else +#endif /* LWIP_TCP */ + { + netbuf_delete((struct netbuf *)mem); + } + } + sys_mbox_free(&conn->recvmbox); + sys_mbox_set_invalid(&conn->recvmbox); + } + + /* Delete and drain the acceptmbox. */ +#if LWIP_TCP + if (sys_mbox_valid(&conn->acceptmbox)) { + while (sys_mbox_tryfetch(&conn->acceptmbox, &mem) != SYS_MBOX_EMPTY) { + struct netconn *newconn = (struct netconn *)mem; + /* Only tcp pcbs have an acceptmbox, so no need to check conn->type */ + /* pcb might be set to NULL already by err_tcp() */ + if (conn->pcb.tcp != NULL) { + tcp_accepted(conn->pcb.tcp); + } + /* drain recvmbox */ + netconn_drain(newconn); + if (newconn->pcb.tcp != NULL) { + tcp_abort(newconn->pcb.tcp); + newconn->pcb.tcp = NULL; + } + netconn_free(newconn); + } + sys_mbox_free(&conn->acceptmbox); + sys_mbox_set_invalid(&conn->acceptmbox); + } +#endif /* LWIP_TCP */ +} + +#if LWIP_TCP +/** + * Internal helper function to close a TCP netconn: since this sometimes + * doesn't work at the first attempt, this function is called from multiple + * places. + * + * @param conn the TCP netconn to close + */ +static void +do_close_internal(struct netconn *conn) +{ + err_t err; + u8_t shut, shut_rx, shut_tx, close; + + LWIP_ASSERT("invalid conn", (conn != NULL)); + LWIP_ASSERT("this is for tcp netconns only", (conn->type == NETCONN_TCP)); + LWIP_ASSERT("conn must be in state NETCONN_CLOSE", (conn->state == NETCONN_CLOSE)); + LWIP_ASSERT("pcb already closed", (conn->pcb.tcp != NULL)); + LWIP_ASSERT("conn->current_msg != NULL", conn->current_msg != NULL); + + shut = conn->current_msg->msg.sd.shut; + shut_rx = shut & NETCONN_SHUT_RD; + shut_tx = shut & NETCONN_SHUT_WR; + /* shutting down both ends is the same as closing */ + close = shut == NETCONN_SHUT_RDWR; + + /* Set back some callback pointers */ + if (close) { + tcp_arg(conn->pcb.tcp, NULL); + } + if (conn->pcb.tcp->state == LISTEN) { + tcp_accept(conn->pcb.tcp, NULL); + } else { + /* some callbacks have to be reset if tcp_close is not successful */ + if (shut_rx) { + tcp_recv(conn->pcb.tcp, NULL); + tcp_accept(conn->pcb.tcp, NULL); + } + if (shut_tx) { + tcp_sent(conn->pcb.tcp, NULL); + } + if (close) { + tcp_poll(conn->pcb.tcp, NULL, 4); + tcp_err(conn->pcb.tcp, NULL); + } + } + /* Try to close the connection */ + if (close) { + err = tcp_close(conn->pcb.tcp); + } else { + err = tcp_shutdown(conn->pcb.tcp, shut_rx, shut_tx); + } + if (err == ERR_OK) { + /* Closing succeeded */ + conn->current_msg->err = ERR_OK; + conn->current_msg = NULL; + conn->state = NETCONN_NONE; + if (close) { + /* Set back some callback pointers as conn is going away */ + conn->pcb.tcp = NULL; + /* Trigger select() in socket layer. Make sure everybody notices activity + on the connection, error first! */ + API_EVENT(conn, NETCONN_EVT_ERROR, 0); + } + if (shut_rx) { + API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0); + } + if (shut_tx) { + API_EVENT(conn, NETCONN_EVT_SENDPLUS, 0); + } + /* wake up the application task */ + sys_sem_signal(&conn->op_completed); + } else { + /* Closing failed, restore some of the callbacks */ + /* Closing of listen pcb will never fail! */ + LWIP_ASSERT("Closing a listen pcb may not fail!", (conn->pcb.tcp->state != LISTEN)); + tcp_sent(conn->pcb.tcp, sent_tcp); + tcp_poll(conn->pcb.tcp, poll_tcp, 4); + tcp_err(conn->pcb.tcp, err_tcp); + tcp_arg(conn->pcb.tcp, conn); + /* don't restore recv callback: we don't want to receive any more data */ + } + /* If closing didn't succeed, we get called again either + from poll_tcp or from sent_tcp */ +} +#endif /* LWIP_TCP */ + +/** + * Delete the pcb inside a netconn. + * Called from netconn_delete. + * + * @param msg the api_msg_msg pointing to the connection + */ +void +do_delconn(struct api_msg_msg *msg) +{ + /* @todo TCP: abort running write/connect? */ + if ((msg->conn->state != NETCONN_NONE) && + (msg->conn->state != NETCONN_LISTEN) && + (msg->conn->state != NETCONN_CONNECT)) { + /* this only happens for TCP netconns */ + LWIP_ASSERT("msg->conn->type == NETCONN_TCP", msg->conn->type == NETCONN_TCP); + msg->err = ERR_INPROGRESS; + } else { + LWIP_ASSERT("blocking connect in progress", + (msg->conn->state != NETCONN_CONNECT) || IN_NONBLOCKING_CONNECT(msg->conn)); + /* Drain and delete mboxes */ + netconn_drain(msg->conn); + + if (msg->conn->pcb.tcp != NULL) { + + switch (NETCONNTYPE_GROUP(msg->conn->type)) { +#if LWIP_RAW + case NETCONN_RAW: + raw_remove(msg->conn->pcb.raw); + break; +#endif /* LWIP_RAW */ +#if LWIP_UDP + case NETCONN_UDP: + msg->conn->pcb.udp->recv_arg = NULL; + udp_remove(msg->conn->pcb.udp); + break; +#endif /* LWIP_UDP */ +#if LWIP_TCP + case NETCONN_TCP: + LWIP_ASSERT("already writing or closing", msg->conn->current_msg == NULL && + msg->conn->write_offset == 0); + msg->conn->state = NETCONN_CLOSE; + msg->msg.sd.shut = NETCONN_SHUT_RDWR; + msg->conn->current_msg = msg; + do_close_internal(msg->conn); + /* API_EVENT is called inside do_close_internal, before releasing + the application thread, so we can return at this point! */ + return; +#endif /* LWIP_TCP */ + default: + break; + } + msg->conn->pcb.tcp = NULL; + } + /* tcp netconns don't come here! */ + + /* @todo: this lets select make the socket readable and writable, + which is wrong! errfd instead? */ + API_EVENT(msg->conn, NETCONN_EVT_RCVPLUS, 0); + API_EVENT(msg->conn, NETCONN_EVT_SENDPLUS, 0); + } + if (sys_sem_valid(&msg->conn->op_completed)) { + sys_sem_signal(&msg->conn->op_completed); + } +} + +/** + * Bind a pcb contained in a netconn + * Called from netconn_bind. + * + * @param msg the api_msg_msg pointing to the connection and containing + * the IP address and port to bind to + */ +void +do_bind(struct api_msg_msg *msg) +{ + if (ERR_IS_FATAL(msg->conn->last_err)) { + msg->err = msg->conn->last_err; + } else { + msg->err = ERR_VAL; + if (msg->conn->pcb.tcp != NULL) { + switch (NETCONNTYPE_GROUP(msg->conn->type)) { +#if LWIP_RAW + case NETCONN_RAW: + msg->err = raw_bind(msg->conn->pcb.raw, msg->msg.bc.ipaddr); + break; +#endif /* LWIP_RAW */ +#if LWIP_UDP + case NETCONN_UDP: + msg->err = udp_bind(msg->conn->pcb.udp, msg->msg.bc.ipaddr, msg->msg.bc.port); + break; +#endif /* LWIP_UDP */ +#if LWIP_TCP + case NETCONN_TCP: + msg->err = tcp_bind(msg->conn->pcb.tcp, msg->msg.bc.ipaddr, msg->msg.bc.port); + break; +#endif /* LWIP_TCP */ + default: + break; + } + } + } + TCPIP_APIMSG_ACK(msg); +} + +#if LWIP_TCP +/** + * TCP callback function if a connection (opened by tcp_connect/do_connect) has + * been established (or reset by the remote host). + * + * @see tcp.h (struct tcp_pcb.connected) for parameters and return values + */ +static err_t +do_connected(void *arg, struct tcp_pcb *pcb, err_t err) +{ + struct netconn *conn; + int was_blocking; + + LWIP_UNUSED_ARG(pcb); + + conn = (struct netconn *)arg; + + if (conn == NULL) { + return ERR_VAL; + } + + LWIP_ASSERT("conn->state == NETCONN_CONNECT", conn->state == NETCONN_CONNECT); + LWIP_ASSERT("(conn->current_msg != NULL) || conn->in_non_blocking_connect", + (conn->current_msg != NULL) || IN_NONBLOCKING_CONNECT(conn)); + + if (conn->current_msg != NULL) { + conn->current_msg->err = err; + } + if ((conn->type == NETCONN_TCP) && (err == ERR_OK)) { + setup_tcp(conn); + } + was_blocking = !IN_NONBLOCKING_CONNECT(conn); + SET_NONBLOCKING_CONNECT(conn, 0); + conn->current_msg = NULL; + conn->state = NETCONN_NONE; + if (!was_blocking) { + NETCONN_SET_SAFE_ERR(conn, ERR_OK); + } + API_EVENT(conn, NETCONN_EVT_SENDPLUS, 0); + + if (was_blocking) { + sys_sem_signal(&conn->op_completed); + } + return ERR_OK; +} +#endif /* LWIP_TCP */ + +/** + * Connect a pcb contained inside a netconn + * Called from netconn_connect. + * + * @param msg the api_msg_msg pointing to the connection and containing + * the IP address and port to connect to + */ +void +do_connect(struct api_msg_msg *msg) +{ + if (msg->conn->pcb.tcp == NULL) { + /* This may happen when calling netconn_connect() a second time */ + msg->err = ERR_CLSD; + } else { + switch (NETCONNTYPE_GROUP(msg->conn->type)) { +#if LWIP_RAW + case NETCONN_RAW: + msg->err = raw_connect(msg->conn->pcb.raw, msg->msg.bc.ipaddr); + break; +#endif /* LWIP_RAW */ +#if LWIP_UDP + case NETCONN_UDP: + msg->err = udp_connect(msg->conn->pcb.udp, msg->msg.bc.ipaddr, msg->msg.bc.port); + break; +#endif /* LWIP_UDP */ +#if LWIP_TCP + case NETCONN_TCP: + /* Prevent connect while doing any other action. */ + if (msg->conn->state != NETCONN_NONE) { + msg->err = ERR_ISCONN; + } else { + setup_tcp(msg->conn); + msg->err = tcp_connect(msg->conn->pcb.tcp, msg->msg.bc.ipaddr, + msg->msg.bc.port, do_connected); + if (msg->err == ERR_OK) { + u8_t non_blocking = netconn_is_nonblocking(msg->conn); + msg->conn->state = NETCONN_CONNECT; + SET_NONBLOCKING_CONNECT(msg->conn, non_blocking); + if (non_blocking) { + msg->err = ERR_INPROGRESS; + } else { + msg->conn->current_msg = msg; + /* sys_sem_signal() is called from do_connected (or err_tcp()), + * when the connection is established! */ + return; + } + } + } + break; +#endif /* LWIP_TCP */ + default: + LWIP_ERROR("Invalid netconn type", 0, do{ msg->err = ERR_VAL; }while(0)); + break; + } + } + sys_sem_signal(&msg->conn->op_completed); +} + +/** + * Connect a pcb contained inside a netconn + * Only used for UDP netconns. + * Called from netconn_disconnect. + * + * @param msg the api_msg_msg pointing to the connection to disconnect + */ +void +do_disconnect(struct api_msg_msg *msg) +{ +#if LWIP_UDP + if (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_UDP) { + udp_disconnect(msg->conn->pcb.udp); + msg->err = ERR_OK; + } else +#endif /* LWIP_UDP */ + { + msg->err = ERR_VAL; + } + TCPIP_APIMSG_ACK(msg); +} + +#if LWIP_TCP +/** + * Set a TCP pcb contained in a netconn into listen mode + * Called from netconn_listen. + * + * @param msg the api_msg_msg pointing to the connection + */ +void +do_listen(struct api_msg_msg *msg) +{ + if (ERR_IS_FATAL(msg->conn->last_err)) { + msg->err = msg->conn->last_err; + } else { + msg->err = ERR_CONN; + if (msg->conn->pcb.tcp != NULL) { + if (msg->conn->type == NETCONN_TCP) { + if (msg->conn->state == NETCONN_NONE) { +#if TCP_LISTEN_BACKLOG + struct tcp_pcb* lpcb = tcp_listen_with_backlog(msg->conn->pcb.tcp, msg->msg.lb.backlog); +#else /* TCP_LISTEN_BACKLOG */ + struct tcp_pcb* lpcb = tcp_listen(msg->conn->pcb.tcp); +#endif /* TCP_LISTEN_BACKLOG */ + if (lpcb == NULL) { + /* in this case, the old pcb is still allocated */ + msg->err = ERR_MEM; + } else { + /* delete the recvmbox and allocate the acceptmbox */ + if (sys_mbox_valid(&msg->conn->recvmbox)) { + /** @todo: should we drain the recvmbox here? */ + sys_mbox_free(&msg->conn->recvmbox); + sys_mbox_set_invalid(&msg->conn->recvmbox); + } + msg->err = ERR_OK; + if (!sys_mbox_valid(&msg->conn->acceptmbox)) { + msg->err = sys_mbox_new(&msg->conn->acceptmbox, DEFAULT_ACCEPTMBOX_SIZE); + } + if (msg->err == ERR_OK) { + msg->conn->state = NETCONN_LISTEN; + msg->conn->pcb.tcp = lpcb; + tcp_arg(msg->conn->pcb.tcp, msg->conn); + tcp_accept(msg->conn->pcb.tcp, accept_function); + } else { + /* since the old pcb is already deallocated, free lpcb now */ + tcp_close(lpcb); + msg->conn->pcb.tcp = NULL; + } + } + } + } else { + msg->err = ERR_ARG; + } + } + } + TCPIP_APIMSG_ACK(msg); +} +#endif /* LWIP_TCP */ + +/** + * Send some data on a RAW or UDP pcb contained in a netconn + * Called from netconn_send + * + * @param msg the api_msg_msg pointing to the connection + */ +void +do_send(struct api_msg_msg *msg) +{ + if (ERR_IS_FATAL(msg->conn->last_err)) { + msg->err = msg->conn->last_err; + } else { + msg->err = ERR_CONN; + if (msg->conn->pcb.tcp != NULL) { + switch (NETCONNTYPE_GROUP(msg->conn->type)) { +#if LWIP_RAW + case NETCONN_RAW: + if (ip_addr_isany(&msg->msg.b->addr)) { + msg->err = raw_send(msg->conn->pcb.raw, msg->msg.b->p); + } else { + msg->err = raw_sendto(msg->conn->pcb.raw, msg->msg.b->p, &msg->msg.b->addr); + } + break; +#endif +#if LWIP_UDP + case NETCONN_UDP: +#if LWIP_CHECKSUM_ON_COPY + if (ip_addr_isany(&msg->msg.b->addr)) { + msg->err = udp_send_chksum(msg->conn->pcb.udp, msg->msg.b->p, + msg->msg.b->flags & NETBUF_FLAG_CHKSUM, msg->msg.b->toport_chksum); + } else { + msg->err = udp_sendto_chksum(msg->conn->pcb.udp, msg->msg.b->p, + &msg->msg.b->addr, msg->msg.b->port, + msg->msg.b->flags & NETBUF_FLAG_CHKSUM, msg->msg.b->toport_chksum); + } +#else /* LWIP_CHECKSUM_ON_COPY */ + if (ip_addr_isany(&msg->msg.b->addr)) { + msg->err = udp_send(msg->conn->pcb.udp, msg->msg.b->p); + } else { + msg->err = udp_sendto(msg->conn->pcb.udp, msg->msg.b->p, &msg->msg.b->addr, msg->msg.b->port); + } +#endif /* LWIP_CHECKSUM_ON_COPY */ + break; +#endif /* LWIP_UDP */ + default: + break; + } + } + } + TCPIP_APIMSG_ACK(msg); +} + +#if LWIP_TCP +/** + * Indicate data has been received from a TCP pcb contained in a netconn + * Called from netconn_recv + * + * @param msg the api_msg_msg pointing to the connection + */ +void +do_recv(struct api_msg_msg *msg) +{ + msg->err = ERR_OK; + if (msg->conn->pcb.tcp != NULL) { + if (msg->conn->type == NETCONN_TCP) { +#if TCP_LISTEN_BACKLOG + if (msg->conn->pcb.tcp->state == LISTEN) { + tcp_accepted(msg->conn->pcb.tcp); + } else +#endif /* TCP_LISTEN_BACKLOG */ + { + u32_t remaining = msg->msg.r.len; + do { + u16_t recved = (remaining > 0xffff) ? 0xffff : (u16_t)remaining; + tcp_recved(msg->conn->pcb.tcp, recved); + remaining -= recved; + }while(remaining != 0); + } + } + } + TCPIP_APIMSG_ACK(msg); +} + +/** + * See if more data needs to be written from a previous call to netconn_write. + * Called initially from do_write. If the first call can't send all data + * (because of low memory or empty send-buffer), this function is called again + * from sent_tcp() or poll_tcp() to send more data. If all data is sent, the + * blocking application thread (waiting in netconn_write) is released. + * + * @param conn netconn (that is currently in state NETCONN_WRITE) to process + * @return ERR_OK + * ERR_MEM if LWIP_TCPIP_CORE_LOCKING=1 and sending hasn't yet finished + */ +static err_t +do_writemore(struct netconn *conn) +{ + err_t err; + void *dataptr; + u16_t len, available; + u8_t write_finished = 0; + size_t diff; + u8_t dontblock = netconn_is_nonblocking(conn) || + (conn->current_msg->msg.w.apiflags & NETCONN_DONTBLOCK); + u8_t apiflags = conn->current_msg->msg.w.apiflags; + + LWIP_ASSERT("conn != NULL", conn != NULL); + LWIP_ASSERT("conn->state == NETCONN_WRITE", (conn->state == NETCONN_WRITE)); + LWIP_ASSERT("conn->current_msg != NULL", conn->current_msg != NULL); + LWIP_ASSERT("conn->pcb.tcp != NULL", conn->pcb.tcp != NULL); + LWIP_ASSERT("conn->write_offset < conn->current_msg->msg.w.len", + conn->write_offset < conn->current_msg->msg.w.len); + +#if LWIP_SO_SNDTIMEO + if ((conn->send_timeout != 0) && + ((s32_t)(sys_now() - conn->current_msg->msg.w.time_started) >= conn->send_timeout)) { + write_finished = 1; + if (conn->write_offset == 0) { + /* nothing has been written */ + err = ERR_WOULDBLOCK; + conn->current_msg->msg.w.len = 0; + } else { + /* partial write */ + err = ERR_OK; + conn->current_msg->msg.w.len = conn->write_offset; + } + } else +#endif /* LWIP_SO_SNDTIMEO */ + { + dataptr = (u8_t*)conn->current_msg->msg.w.dataptr + conn->write_offset; + diff = conn->current_msg->msg.w.len - conn->write_offset; + if (diff > 0xffffUL) { /* max_u16_t */ + len = 0xffff; +#if LWIP_TCPIP_CORE_LOCKING + conn->flags |= NETCONN_FLAG_WRITE_DELAYED; +#endif + apiflags |= TCP_WRITE_FLAG_MORE; + } else { + len = (u16_t)diff; + } + available = tcp_sndbuf(conn->pcb.tcp); + if (available < len) { + /* don't try to write more than sendbuf */ + len = available; + if (dontblock){ + if (!len) { + err = ERR_WOULDBLOCK; + goto err_mem; + } + } else { +#if LWIP_TCPIP_CORE_LOCKING + conn->flags |= NETCONN_FLAG_WRITE_DELAYED; +#endif + apiflags |= TCP_WRITE_FLAG_MORE; + } + } + LWIP_ASSERT("do_writemore: invalid length!", ((conn->write_offset + len) <= conn->current_msg->msg.w.len)); + err = tcp_write(conn->pcb.tcp, dataptr, len, apiflags); + /* if OK or memory error, check available space */ + if ((err == ERR_OK) || (err == ERR_MEM)) { +err_mem: + if (dontblock && (len < conn->current_msg->msg.w.len)) { + /* non-blocking write did not write everything: mark the pcb non-writable + and let poll_tcp check writable space to mark the pcb writable again */ + API_EVENT(conn, NETCONN_EVT_SENDMINUS, len); + conn->flags |= NETCONN_FLAG_CHECK_WRITESPACE; + } else if ((tcp_sndbuf(conn->pcb.tcp) <= TCP_SNDLOWAT) || + (tcp_sndqueuelen(conn->pcb.tcp) >= TCP_SNDQUEUELOWAT)) { + /* The queued byte- or pbuf-count exceeds the configured low-water limit, + let select mark this pcb as non-writable. */ + API_EVENT(conn, NETCONN_EVT_SENDMINUS, len); + } + } + + if (err == ERR_OK) { + conn->write_offset += len; + if ((conn->write_offset == conn->current_msg->msg.w.len) || dontblock) { + /* return sent length */ + conn->current_msg->msg.w.len = conn->write_offset; + /* everything was written */ + write_finished = 1; + conn->write_offset = 0; + } + tcp_output(conn->pcb.tcp); + } else if ((err == ERR_MEM) && !dontblock) { + /* If ERR_MEM, we wait for sent_tcp or poll_tcp to be called + we do NOT return to the application thread, since ERR_MEM is + only a temporary error! */ + + /* tcp_write returned ERR_MEM, try tcp_output anyway */ + tcp_output(conn->pcb.tcp); + +#if LWIP_TCPIP_CORE_LOCKING + conn->flags |= NETCONN_FLAG_WRITE_DELAYED; +#endif + } else { + /* On errors != ERR_MEM, we don't try writing any more but return + the error to the application thread. */ + write_finished = 1; + conn->current_msg->msg.w.len = 0; + } + } + if (write_finished) { + /* everything was written: set back connection state + and back to application task */ + conn->current_msg->err = err; + conn->current_msg = NULL; + conn->state = NETCONN_NONE; +#if LWIP_TCPIP_CORE_LOCKING + if ((conn->flags & NETCONN_FLAG_WRITE_DELAYED) != 0) +#endif + { + sys_sem_signal(&conn->op_completed); + } + } +#if LWIP_TCPIP_CORE_LOCKING + else + return ERR_MEM; +#endif + return ERR_OK; +} +#endif /* LWIP_TCP */ + +/** + * Send some data on a TCP pcb contained in a netconn + * Called from netconn_write + * + * @param msg the api_msg_msg pointing to the connection + */ +void +do_write(struct api_msg_msg *msg) +{ + if (ERR_IS_FATAL(msg->conn->last_err)) { + msg->err = msg->conn->last_err; + } else { + if (msg->conn->type == NETCONN_TCP) { +#if LWIP_TCP + if (msg->conn->state != NETCONN_NONE) { + /* netconn is connecting, closing or in blocking write */ + msg->err = ERR_INPROGRESS; + } else if (msg->conn->pcb.tcp != NULL) { + msg->conn->state = NETCONN_WRITE; + /* set all the variables used by do_writemore */ + LWIP_ASSERT("already writing or closing", msg->conn->current_msg == NULL && + msg->conn->write_offset == 0); + LWIP_ASSERT("msg->msg.w.len != 0", msg->msg.w.len != 0); + msg->conn->current_msg = msg; + msg->conn->write_offset = 0; +#if LWIP_TCPIP_CORE_LOCKING + msg->conn->flags &= ~NETCONN_FLAG_WRITE_DELAYED; + if (do_writemore(msg->conn) != ERR_OK) { + LWIP_ASSERT("state!", msg->conn->state == NETCONN_WRITE); + UNLOCK_TCPIP_CORE(); + sys_arch_sem_wait(&msg->conn->op_completed, 0); + LOCK_TCPIP_CORE(); + LWIP_ASSERT("state!", msg->conn->state == NETCONN_NONE); + } +#else /* LWIP_TCPIP_CORE_LOCKING */ + do_writemore(msg->conn); +#endif /* LWIP_TCPIP_CORE_LOCKING */ + /* for both cases: if do_writemore was called, don't ACK the APIMSG + since do_writemore ACKs it! */ + return; + } else { + msg->err = ERR_CONN; + } +#else /* LWIP_TCP */ + msg->err = ERR_VAL; +#endif /* LWIP_TCP */ +#if (LWIP_UDP || LWIP_RAW) + } else { + msg->err = ERR_VAL; +#endif /* (LWIP_UDP || LWIP_RAW) */ + } + } + TCPIP_APIMSG_ACK(msg); +} + +/** + * Return a connection's local or remote address + * Called from netconn_getaddr + * + * @param msg the api_msg_msg pointing to the connection + */ +void +do_getaddr(struct api_msg_msg *msg) +{ + if (msg->conn->pcb.ip != NULL) { + *(msg->msg.ad.ipaddr) = (msg->msg.ad.local ? msg->conn->pcb.ip->local_ip : + msg->conn->pcb.ip->remote_ip); + + msg->err = ERR_OK; + switch (NETCONNTYPE_GROUP(msg->conn->type)) { +#if LWIP_RAW + case NETCONN_RAW: + if (msg->msg.ad.local) { + *(msg->msg.ad.port) = msg->conn->pcb.raw->protocol; + } else { + /* return an error as connecting is only a helper for upper layers */ + msg->err = ERR_CONN; + } + break; +#endif /* LWIP_RAW */ +#if LWIP_UDP + case NETCONN_UDP: + if (msg->msg.ad.local) { + *(msg->msg.ad.port) = msg->conn->pcb.udp->local_port; + } else { + if ((msg->conn->pcb.udp->flags & UDP_FLAGS_CONNECTED) == 0) { + msg->err = ERR_CONN; + } else { + *(msg->msg.ad.port) = msg->conn->pcb.udp->remote_port; + } + } + break; +#endif /* LWIP_UDP */ +#if LWIP_TCP + case NETCONN_TCP: + *(msg->msg.ad.port) = (msg->msg.ad.local?msg->conn->pcb.tcp->local_port:msg->conn->pcb.tcp->remote_port); + break; +#endif /* LWIP_TCP */ + default: + LWIP_ASSERT("invalid netconn_type", 0); + break; + } + } else { + msg->err = ERR_CONN; + } + TCPIP_APIMSG_ACK(msg); +} + +/** + * Close a TCP pcb contained in a netconn + * Called from netconn_close + * + * @param msg the api_msg_msg pointing to the connection + */ +void +do_close(struct api_msg_msg *msg) +{ +#if LWIP_TCP + /* @todo: abort running write/connect? */ + if ((msg->conn->state != NETCONN_NONE) && (msg->conn->state != NETCONN_LISTEN)) { + /* this only happens for TCP netconns */ + LWIP_ASSERT("msg->conn->type == NETCONN_TCP", msg->conn->type == NETCONN_TCP); + msg->err = ERR_INPROGRESS; + } else if ((msg->conn->pcb.tcp != NULL) && (msg->conn->type == NETCONN_TCP)) { + if ((msg->msg.sd.shut != NETCONN_SHUT_RDWR) && (msg->conn->state == NETCONN_LISTEN)) { + /* LISTEN doesn't support half shutdown */ + msg->err = ERR_CONN; + } else { + if (msg->msg.sd.shut & NETCONN_SHUT_RD) { + /* Drain and delete mboxes */ + netconn_drain(msg->conn); + } + LWIP_ASSERT("already writing or closing", msg->conn->current_msg == NULL && + msg->conn->write_offset == 0); + msg->conn->state = NETCONN_CLOSE; + msg->conn->current_msg = msg; + do_close_internal(msg->conn); + /* for tcp netconns, do_close_internal ACKs the message */ + return; + } + } else +#endif /* LWIP_TCP */ + { + msg->err = ERR_VAL; + } + sys_sem_signal(&msg->conn->op_completed); +} + +#if LWIP_IGMP +/** + * Join multicast groups for UDP netconns. + * Called from netconn_join_leave_group + * + * @param msg the api_msg_msg pointing to the connection + */ +void +do_join_leave_group(struct api_msg_msg *msg) +{ + if (ERR_IS_FATAL(msg->conn->last_err)) { + msg->err = msg->conn->last_err; + } else { + if (msg->conn->pcb.tcp != NULL) { + if (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_UDP) { +#if LWIP_UDP + if (msg->msg.jl.join_or_leave == NETCONN_JOIN) { + msg->err = igmp_joingroup(msg->msg.jl.netif_addr, msg->msg.jl.multiaddr); + } else { + msg->err = igmp_leavegroup(msg->msg.jl.netif_addr, msg->msg.jl.multiaddr); + } +#endif /* LWIP_UDP */ +#if (LWIP_TCP || LWIP_RAW) + } else { + msg->err = ERR_VAL; +#endif /* (LWIP_TCP || LWIP_RAW) */ + } + } else { + msg->err = ERR_CONN; + } + } + TCPIP_APIMSG_ACK(msg); +} +#endif /* LWIP_IGMP */ + +#if LWIP_DNS +/** + * Callback function that is called when DNS name is resolved + * (or on timeout). A waiting application thread is waked up by + * signaling the semaphore. + */ +static void +do_dns_found(const char *name, ip_addr_t *ipaddr, void *arg) +{ + struct dns_api_msg *msg = (struct dns_api_msg*)arg; + + LWIP_ASSERT("DNS response for wrong host name", strcmp(msg->name, name) == 0); + LWIP_UNUSED_ARG(name); + + if (ipaddr == NULL) { + /* timeout or memory error */ + *msg->err = ERR_VAL; + } else { + /* address was resolved */ + *msg->err = ERR_OK; + *msg->addr = *ipaddr; + } + /* wake up the application task waiting in netconn_gethostbyname */ + sys_sem_signal(msg->sem); +} + +/** + * Execute a DNS query + * Called from netconn_gethostbyname + * + * @param arg the dns_api_msg pointing to the query + */ +void +do_gethostbyname(void *arg) +{ + struct dns_api_msg *msg = (struct dns_api_msg*)arg; + + *msg->err = dns_gethostbyname(msg->name, msg->addr, do_dns_found, msg); + if (*msg->err != ERR_INPROGRESS) { + /* on error or immediate success, wake up the application + * task waiting in netconn_gethostbyname */ + sys_sem_signal(msg->sem); + } +} +#endif /* LWIP_DNS */ + +#endif /* LWIP_NETCONN */ diff --git a/src/lwip-1.4.1/src/api/err.c b/src/lwip-1.4.1/src/api/err.c new file mode 100644 index 0000000..92fa8b7 --- /dev/null +++ b/src/lwip-1.4.1/src/api/err.c @@ -0,0 +1,75 @@ +/** + * @file + * Error Management module + * + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#include "lwip/err.h" + +#ifdef LWIP_DEBUG + +static const char *err_strerr[] = { + "Ok.", /* ERR_OK 0 */ + "Out of memory error.", /* ERR_MEM -1 */ + "Buffer error.", /* ERR_BUF -2 */ + "Timeout.", /* ERR_TIMEOUT -3 */ + "Routing problem.", /* ERR_RTE -4 */ + "Operation in progress.", /* ERR_INPROGRESS -5 */ + "Illegal value.", /* ERR_VAL -6 */ + "Operation would block.", /* ERR_WOULDBLOCK -7 */ + "Address in use.", /* ERR_USE -8 */ + "Already connected.", /* ERR_ISCONN -9 */ + "Connection aborted.", /* ERR_ABRT -10 */ + "Connection reset.", /* ERR_RST -11 */ + "Connection closed.", /* ERR_CLSD -12 */ + "Not connected.", /* ERR_CONN -13 */ + "Illegal argument.", /* ERR_ARG -14 */ + "Low-level netif error.", /* ERR_IF -15 */ +}; + +/** + * Convert an lwip internal error to a string representation. + * + * @param err an lwip internal err_t + * @return a string representation for err + */ +const char * +lwip_strerr(err_t err) +{ + return err_strerr[-err]; + +} + +#endif /* LWIP_DEBUG */ diff --git a/src/lwip-1.4.1/src/api/netbuf.c b/src/lwip-1.4.1/src/api/netbuf.c new file mode 100644 index 0000000..9390c9e --- /dev/null +++ b/src/lwip-1.4.1/src/api/netbuf.c @@ -0,0 +1,245 @@ +/** + * @file + * Network buffer management + * + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#include "lwip/opt.h" + +#if LWIP_NETCONN /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/netbuf.h" +#include "lwip/memp.h" + +#include + +/** + * Create (allocate) and initialize a new netbuf. + * The netbuf doesn't yet contain a packet buffer! + * + * @return a pointer to a new netbuf + * NULL on lack of memory + */ +struct +netbuf *netbuf_new(void) +{ + struct netbuf *buf; + + buf = (struct netbuf *)memp_malloc(MEMP_NETBUF); + if (buf != NULL) { + buf->p = NULL; + buf->ptr = NULL; + ip_addr_set_any(&buf->addr); + buf->port = 0; +#if LWIP_NETBUF_RECVINFO || LWIP_CHECKSUM_ON_COPY +#if LWIP_CHECKSUM_ON_COPY + buf->flags = 0; +#endif /* LWIP_CHECKSUM_ON_COPY */ + buf->toport_chksum = 0; +#if LWIP_NETBUF_RECVINFO + ip_addr_set_any(&buf->toaddr); +#endif /* LWIP_NETBUF_RECVINFO */ +#endif /* LWIP_NETBUF_RECVINFO || LWIP_CHECKSUM_ON_COPY */ + return buf; + } else { + return NULL; + } +} + +/** + * Deallocate a netbuf allocated by netbuf_new(). + * + * @param buf pointer to a netbuf allocated by netbuf_new() + */ +void +netbuf_delete(struct netbuf *buf) +{ + if (buf != NULL) { + if (buf->p != NULL) { + pbuf_free(buf->p); + buf->p = buf->ptr = NULL; + } + memp_free(MEMP_NETBUF, buf); + } +} + +/** + * Allocate memory for a packet buffer for a given netbuf. + * + * @param buf the netbuf for which to allocate a packet buffer + * @param size the size of the packet buffer to allocate + * @return pointer to the allocated memory + * NULL if no memory could be allocated + */ +void * +netbuf_alloc(struct netbuf *buf, u16_t size) +{ + LWIP_ERROR("netbuf_alloc: invalid buf", (buf != NULL), return NULL;); + + /* Deallocate any previously allocated memory. */ + if (buf->p != NULL) { + pbuf_free(buf->p); + } + buf->p = pbuf_alloc(PBUF_TRANSPORT, size, PBUF_RAM); + if (buf->p == NULL) { + return NULL; + } + LWIP_ASSERT("check that first pbuf can hold size", + (buf->p->len >= size)); + buf->ptr = buf->p; + return buf->p->payload; +} + +/** + * Free the packet buffer included in a netbuf + * + * @param buf pointer to the netbuf which contains the packet buffer to free + */ +void +netbuf_free(struct netbuf *buf) +{ + LWIP_ERROR("netbuf_free: invalid buf", (buf != NULL), return;); + if (buf->p != NULL) { + pbuf_free(buf->p); + } + buf->p = buf->ptr = NULL; +} + +/** + * Let a netbuf reference existing (non-volatile) data. + * + * @param buf netbuf which should reference the data + * @param dataptr pointer to the data to reference + * @param size size of the data + * @return ERR_OK if data is referenced + * ERR_MEM if data couldn't be referenced due to lack of memory + */ +err_t +netbuf_ref(struct netbuf *buf, const void *dataptr, u16_t size) +{ + LWIP_ERROR("netbuf_ref: invalid buf", (buf != NULL), return ERR_ARG;); + if (buf->p != NULL) { + pbuf_free(buf->p); + } + buf->p = pbuf_alloc(PBUF_TRANSPORT, 0, PBUF_REF); + if (buf->p == NULL) { + buf->ptr = NULL; + return ERR_MEM; + } + buf->p->payload = (void*)dataptr; + buf->p->len = buf->p->tot_len = size; + buf->ptr = buf->p; + return ERR_OK; +} + +/** + * Chain one netbuf to another (@see pbuf_chain) + * + * @param head the first netbuf + * @param tail netbuf to chain after head, freed by this function, may not be reference after returning + */ +void +netbuf_chain(struct netbuf *head, struct netbuf *tail) +{ + LWIP_ERROR("netbuf_ref: invalid head", (head != NULL), return;); + LWIP_ERROR("netbuf_chain: invalid tail", (tail != NULL), return;); + pbuf_cat(head->p, tail->p); + head->ptr = head->p; + memp_free(MEMP_NETBUF, tail); +} + +/** + * Get the data pointer and length of the data inside a netbuf. + * + * @param buf netbuf to get the data from + * @param dataptr pointer to a void pointer where to store the data pointer + * @param len pointer to an u16_t where the length of the data is stored + * @return ERR_OK if the information was retreived, + * ERR_BUF on error. + */ +err_t +netbuf_data(struct netbuf *buf, void **dataptr, u16_t *len) +{ + LWIP_ERROR("netbuf_data: invalid buf", (buf != NULL), return ERR_ARG;); + LWIP_ERROR("netbuf_data: invalid dataptr", (dataptr != NULL), return ERR_ARG;); + LWIP_ERROR("netbuf_data: invalid len", (len != NULL), return ERR_ARG;); + + if (buf->ptr == NULL) { + return ERR_BUF; + } + *dataptr = buf->ptr->payload; + *len = buf->ptr->len; + return ERR_OK; +} + +/** + * Move the current data pointer of a packet buffer contained in a netbuf + * to the next part. + * The packet buffer itself is not modified. + * + * @param buf the netbuf to modify + * @return -1 if there is no next part + * 1 if moved to the next part but now there is no next part + * 0 if moved to the next part and there are still more parts + */ +s8_t +netbuf_next(struct netbuf *buf) +{ + LWIP_ERROR("netbuf_free: invalid buf", (buf != NULL), return -1;); + if (buf->ptr->next == NULL) { + return -1; + } + buf->ptr = buf->ptr->next; + if (buf->ptr->next == NULL) { + return 1; + } + return 0; +} + +/** + * Move the current data pointer of a packet buffer contained in a netbuf + * to the beginning of the packet. + * The packet buffer itself is not modified. + * + * @param buf the netbuf to modify + */ +void +netbuf_first(struct netbuf *buf) +{ + LWIP_ERROR("netbuf_free: invalid buf", (buf != NULL), return;); + buf->ptr = buf->p; +} + +#endif /* LWIP_NETCONN */ diff --git a/src/lwip-1.4.1/src/api/netdb.c b/src/lwip-1.4.1/src/api/netdb.c new file mode 100644 index 0000000..6a4bac5 --- /dev/null +++ b/src/lwip-1.4.1/src/api/netdb.c @@ -0,0 +1,353 @@ +/** + * @file + * API functions for name resolving + * + */ + +/* + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Simon Goldschmidt + * + */ + +#include "lwip/netdb.h" + +#if LWIP_DNS && LWIP_SOCKET + +#include "lwip/err.h" +#include "lwip/mem.h" +#include "lwip/memp.h" +#include "lwip/ip_addr.h" +#include "lwip/api.h" +#include "lwip/dns.h" + +#include +#include + +/** helper struct for gethostbyname_r to access the char* buffer */ +struct gethostbyname_r_helper { + ip_addr_t *addr_list[2]; + ip_addr_t addr; + char *aliases; +}; + +/** h_errno is exported in netdb.h for access by applications. */ +#if LWIP_DNS_API_DECLARE_H_ERRNO +int h_errno; +#endif /* LWIP_DNS_API_DECLARE_H_ERRNO */ + +/** define "hostent" variables storage: 0 if we use a static (but unprotected) + * set of variables for lwip_gethostbyname, 1 if we use a local storage */ +#ifndef LWIP_DNS_API_HOSTENT_STORAGE +#define LWIP_DNS_API_HOSTENT_STORAGE 0 +#endif + +/** define "hostent" variables storage */ +#if LWIP_DNS_API_HOSTENT_STORAGE +#define HOSTENT_STORAGE +#else +#define HOSTENT_STORAGE static +#endif /* LWIP_DNS_API_STATIC_HOSTENT */ + +/** + * Returns an entry containing addresses of address family AF_INET + * for the host with name name. + * Due to dns_gethostbyname limitations, only one address is returned. + * + * @param name the hostname to resolve + * @return an entry containing addresses of address family AF_INET + * for the host with name name + */ +struct hostent* +lwip_gethostbyname(const char *name) +{ + err_t err; + ip_addr_t addr; + + /* buffer variables for lwip_gethostbyname() */ + HOSTENT_STORAGE struct hostent s_hostent; + HOSTENT_STORAGE char *s_aliases; + HOSTENT_STORAGE ip_addr_t s_hostent_addr; + HOSTENT_STORAGE ip_addr_t *s_phostent_addr[2]; + + /* query host IP address */ + err = netconn_gethostbyname(name, &addr); + if (err != ERR_OK) { + LWIP_DEBUGF(DNS_DEBUG, ("lwip_gethostbyname(%s) failed, err=%d\n", name, err)); + h_errno = HOST_NOT_FOUND; + return NULL; + } + + /* fill hostent */ + s_hostent_addr = addr; + s_phostent_addr[0] = &s_hostent_addr; + s_phostent_addr[1] = NULL; + s_hostent.h_name = (char*)name; + s_hostent.h_aliases = &s_aliases; + s_hostent.h_addrtype = AF_INET; + s_hostent.h_length = sizeof(ip_addr_t); + s_hostent.h_addr_list = (char**)&s_phostent_addr; + +#if DNS_DEBUG + /* dump hostent */ + LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_name == %s\n", s_hostent.h_name)); + LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_aliases == %p\n", s_hostent.h_aliases)); + if (s_hostent.h_aliases != NULL) { + u8_t idx; + for ( idx=0; s_hostent.h_aliases[idx]; idx++) { + LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_aliases[%i]-> == %p\n", idx, s_hostent.h_aliases[idx])); + LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_aliases[%i]-> == %s\n", idx, s_hostent.h_aliases[idx])); + } + } + LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_addrtype == %d\n", s_hostent.h_addrtype)); + LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_length == %d\n", s_hostent.h_length)); + LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_addr_list == %p\n", s_hostent.h_addr_list)); + if (s_hostent.h_addr_list != NULL) { + u8_t idx; + for ( idx=0; s_hostent.h_addr_list[idx]; idx++) { + LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_addr_list[%i] == %p\n", idx, s_hostent.h_addr_list[idx])); + LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_addr_list[%i]-> == %s\n", idx, ip_ntoa((ip_addr_t*)s_hostent.h_addr_list[idx]))); + } + } +#endif /* DNS_DEBUG */ + +#if LWIP_DNS_API_HOSTENT_STORAGE + /* this function should return the "per-thread" hostent after copy from s_hostent */ + return sys_thread_hostent(&s_hostent); +#else + return &s_hostent; +#endif /* LWIP_DNS_API_HOSTENT_STORAGE */ +} + +/** + * Thread-safe variant of lwip_gethostbyname: instead of using a static + * buffer, this function takes buffer and errno pointers as arguments + * and uses these for the result. + * + * @param name the hostname to resolve + * @param ret pre-allocated struct where to store the result + * @param buf pre-allocated buffer where to store additional data + * @param buflen the size of buf + * @param result pointer to a hostent pointer that is set to ret on success + * and set to zero on error + * @param h_errnop pointer to an int where to store errors (instead of modifying + * the global h_errno) + * @return 0 on success, non-zero on error, additional error information + * is stored in *h_errnop instead of h_errno to be thread-safe + */ +int +lwip_gethostbyname_r(const char *name, struct hostent *ret, char *buf, + size_t buflen, struct hostent **result, int *h_errnop) +{ + err_t err; + struct gethostbyname_r_helper *h; + char *hostname; + size_t namelen; + int lh_errno; + + if (h_errnop == NULL) { + /* ensure h_errnop is never NULL */ + h_errnop = &lh_errno; + } + + if (result == NULL) { + /* not all arguments given */ + *h_errnop = EINVAL; + return -1; + } + /* first thing to do: set *result to nothing */ + *result = NULL; + if ((name == NULL) || (ret == NULL) || (buf == NULL)) { + /* not all arguments given */ + *h_errnop = EINVAL; + return -1; + } + + namelen = strlen(name); + if (buflen < (sizeof(struct gethostbyname_r_helper) + namelen + 1 + (MEM_ALIGNMENT - 1))) { + /* buf can't hold the data needed + a copy of name */ + *h_errnop = ERANGE; + return -1; + } + + h = (struct gethostbyname_r_helper*)LWIP_MEM_ALIGN(buf); + hostname = ((char*)h) + sizeof(struct gethostbyname_r_helper); + + /* query host IP address */ + err = netconn_gethostbyname(name, &h->addr); + if (err != ERR_OK) { + LWIP_DEBUGF(DNS_DEBUG, ("lwip_gethostbyname(%s) failed, err=%d\n", name, err)); + *h_errnop = HOST_NOT_FOUND; + return -1; + } + + /* copy the hostname into buf */ + MEMCPY(hostname, name, namelen); + hostname[namelen] = 0; + + /* fill hostent */ + h->addr_list[0] = &h->addr; + h->addr_list[1] = NULL; + h->aliases = NULL; + ret->h_name = hostname; + ret->h_aliases = &h->aliases; + ret->h_addrtype = AF_INET; + ret->h_length = sizeof(ip_addr_t); + ret->h_addr_list = (char**)&h->addr_list; + + /* set result != NULL */ + *result = ret; + + /* return success */ + return 0; +} + +/** + * Frees one or more addrinfo structures returned by getaddrinfo(), along with + * any additional storage associated with those structures. If the ai_next field + * of the structure is not null, the entire list of structures is freed. + * + * @param ai struct addrinfo to free + */ +void +lwip_freeaddrinfo(struct addrinfo *ai) +{ + struct addrinfo *next; + + while (ai != NULL) { + next = ai->ai_next; + memp_free(MEMP_NETDB, ai); + ai = next; + } +} + +/** + * Translates the name of a service location (for example, a host name) and/or + * a service name and returns a set of socket addresses and associated + * information to be used in creating a socket with which to address the + * specified service. + * Memory for the result is allocated internally and must be freed by calling + * lwip_freeaddrinfo()! + * + * Due to a limitation in dns_gethostbyname, only the first address of a + * host is returned. + * Also, service names are not supported (only port numbers)! + * + * @param nodename descriptive name or address string of the host + * (may be NULL -> local address) + * @param servname port number as string of NULL + * @param hints structure containing input values that set socktype and protocol + * @param res pointer to a pointer where to store the result (set to NULL on failure) + * @return 0 on success, non-zero on failure + */ +int +lwip_getaddrinfo(const char *nodename, const char *servname, + const struct addrinfo *hints, struct addrinfo **res) +{ + err_t err; + ip_addr_t addr; + struct addrinfo *ai; + struct sockaddr_in *sa = NULL; + int port_nr = 0; + size_t total_size; + size_t namelen = 0; + + if (res == NULL) { + return EAI_FAIL; + } + *res = NULL; + if ((nodename == NULL) && (servname == NULL)) { + return EAI_NONAME; + } + + if (servname != NULL) { + /* service name specified: convert to port number + * @todo?: currently, only ASCII integers (port numbers) are supported! */ + port_nr = atoi(servname); + if ((port_nr <= 0) || (port_nr > 0xffff)) { + return EAI_SERVICE; + } + } + + if (nodename != NULL) { + /* service location specified, try to resolve */ + err = netconn_gethostbyname(nodename, &addr); + if (err != ERR_OK) { + return EAI_FAIL; + } + } else { + /* service location specified, use loopback address */ + ip_addr_set_loopback(&addr); + } + + total_size = sizeof(struct addrinfo) + sizeof(struct sockaddr_in); + if (nodename != NULL) { + namelen = strlen(nodename); + LWIP_ASSERT("namelen is too long", (namelen + 1) <= (mem_size_t)-1); + total_size += namelen + 1; + } + /* If this fails, please report to lwip-devel! :-) */ + LWIP_ASSERT("total_size <= NETDB_ELEM_SIZE: please report this!", + total_size <= NETDB_ELEM_SIZE); + ai = (struct addrinfo *)memp_malloc(MEMP_NETDB); + if (ai == NULL) { + goto memerr; + } + memset(ai, 0, total_size); + sa = (struct sockaddr_in*)((u8_t*)ai + sizeof(struct addrinfo)); + /* set up sockaddr */ + inet_addr_from_ipaddr(&sa->sin_addr, &addr); + sa->sin_family = AF_INET; + sa->sin_len = sizeof(struct sockaddr_in); + sa->sin_port = htons((u16_t)port_nr); + + /* set up addrinfo */ + ai->ai_family = AF_INET; + if (hints != NULL) { + /* copy socktype & protocol from hints if specified */ + ai->ai_socktype = hints->ai_socktype; + ai->ai_protocol = hints->ai_protocol; + } + if (nodename != NULL) { + /* copy nodename to canonname if specified */ + ai->ai_canonname = ((char*)ai + sizeof(struct addrinfo) + sizeof(struct sockaddr_in)); + MEMCPY(ai->ai_canonname, nodename, namelen); + ai->ai_canonname[namelen] = 0; + } + ai->ai_addrlen = sizeof(struct sockaddr_in); + ai->ai_addr = (struct sockaddr*)sa; + + *res = ai; + + return 0; +memerr: + if (ai != NULL) { + memp_free(MEMP_NETDB, ai); + } + return EAI_MEMORY; +} + +#endif /* LWIP_DNS && LWIP_SOCKET */ diff --git a/src/lwip-1.4.1/src/api/netifapi.c b/src/lwip-1.4.1/src/api/netifapi.c new file mode 100644 index 0000000..43e4720 --- /dev/null +++ b/src/lwip-1.4.1/src/api/netifapi.c @@ -0,0 +1,160 @@ +/** + * @file + * Network Interface Sequential API module + * + */ + +/* + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * This file is part of the lwIP TCP/IP stack. + * + */ + +#include "lwip/opt.h" + +#if LWIP_NETIF_API /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/netifapi.h" +#include "lwip/tcpip.h" + +/** + * Call netif_add() inside the tcpip_thread context. + */ +void +do_netifapi_netif_add(struct netifapi_msg_msg *msg) +{ + if (!netif_add( msg->netif, + msg->msg.add.ipaddr, + msg->msg.add.netmask, + msg->msg.add.gw, + msg->msg.add.state, + msg->msg.add.init, + msg->msg.add.input)) { + msg->err = ERR_IF; + } else { + msg->err = ERR_OK; + } + TCPIP_NETIFAPI_ACK(msg); +} + +/** + * Call netif_set_addr() inside the tcpip_thread context. + */ +void +do_netifapi_netif_set_addr(struct netifapi_msg_msg *msg) +{ + netif_set_addr( msg->netif, + msg->msg.add.ipaddr, + msg->msg.add.netmask, + msg->msg.add.gw); + msg->err = ERR_OK; + TCPIP_NETIFAPI_ACK(msg); +} + +/** + * Call the "errtfunc" (or the "voidfunc" if "errtfunc" is NULL) inside the + * tcpip_thread context. + */ +void +do_netifapi_netif_common(struct netifapi_msg_msg *msg) +{ + if (msg->msg.common.errtfunc != NULL) { + msg->err = msg->msg.common.errtfunc(msg->netif); + } else { + msg->err = ERR_OK; + msg->msg.common.voidfunc(msg->netif); + } + TCPIP_NETIFAPI_ACK(msg); +} + +/** + * Call netif_add() in a thread-safe way by running that function inside the + * tcpip_thread context. + * + * @note for params @see netif_add() + */ +err_t +netifapi_netif_add(struct netif *netif, + ip_addr_t *ipaddr, + ip_addr_t *netmask, + ip_addr_t *gw, + void *state, + netif_init_fn init, + netif_input_fn input) +{ + struct netifapi_msg msg; + msg.function = do_netifapi_netif_add; + msg.msg.netif = netif; + msg.msg.msg.add.ipaddr = ipaddr; + msg.msg.msg.add.netmask = netmask; + msg.msg.msg.add.gw = gw; + msg.msg.msg.add.state = state; + msg.msg.msg.add.init = init; + msg.msg.msg.add.input = input; + TCPIP_NETIFAPI(&msg); + return msg.msg.err; +} + +/** + * Call netif_set_addr() in a thread-safe way by running that function inside the + * tcpip_thread context. + * + * @note for params @see netif_set_addr() + */ +err_t +netifapi_netif_set_addr(struct netif *netif, + ip_addr_t *ipaddr, + ip_addr_t *netmask, + ip_addr_t *gw) +{ + struct netifapi_msg msg; + msg.function = do_netifapi_netif_set_addr; + msg.msg.netif = netif; + msg.msg.msg.add.ipaddr = ipaddr; + msg.msg.msg.add.netmask = netmask; + msg.msg.msg.add.gw = gw; + TCPIP_NETIFAPI(&msg); + return msg.msg.err; +} + +/** + * call the "errtfunc" (or the "voidfunc" if "errtfunc" is NULL) in a thread-safe + * way by running that function inside the tcpip_thread context. + * + * @note use only for functions where there is only "netif" parameter. + */ +err_t +netifapi_netif_common(struct netif *netif, netifapi_void_fn voidfunc, + netifapi_errt_fn errtfunc) +{ + struct netifapi_msg msg; + msg.function = do_netifapi_netif_common; + msg.msg.netif = netif; + msg.msg.msg.common.voidfunc = voidfunc; + msg.msg.msg.common.errtfunc = errtfunc; + TCPIP_NETIFAPI(&msg); + return msg.msg.err; +} + +#endif /* LWIP_NETIF_API */ diff --git a/src/lwip-1.4.1/src/api/sockets.c b/src/lwip-1.4.1/src/api/sockets.c new file mode 100644 index 0000000..359919e --- /dev/null +++ b/src/lwip-1.4.1/src/api/sockets.c @@ -0,0 +1,2374 @@ +/** + * @file + * Sockets BSD-Like API module + * + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + * Improved by Marc Boucher and David Haas + * + */ + +#include "lwip/opt.h" + +#if LWIP_SOCKET /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/sockets.h" +#include "lwip/api.h" +#include "lwip/sys.h" +#include "lwip/igmp.h" +#include "lwip/inet.h" +#include "lwip/tcp.h" +#include "lwip/raw.h" +#include "lwip/udp.h" +#include "lwip/tcpip.h" +#include "lwip/pbuf.h" +#if LWIP_CHECKSUM_ON_COPY +#include "lwip/inet_chksum.h" +#endif + +#include + +#define NUM_SOCKETS MEMP_NUM_NETCONN + +/** Contains all internal pointers and states used for a socket */ +struct lwip_sock { + /** sockets currently are built on netconns, each socket has one netconn */ + struct netconn *conn; + /** data that was left from the previous read */ + void *lastdata; + /** offset in the data that was left from the previous read */ + u16_t lastoffset; + /** number of times data was received, set by event_callback(), + tested by the receive and select functions */ + s16_t rcvevent; + /** number of times data was ACKed (free send buffer), set by event_callback(), + tested by select */ + u16_t sendevent; + /** error happened for this socket, set by event_callback(), tested by select */ + u16_t errevent; + /** last error that occurred on this socket */ + int err; + /** counter of how many threads are waiting for this socket using select */ + int select_waiting; +}; + +/** Description for a task waiting in select */ +struct lwip_select_cb { + /** Pointer to the next waiting task */ + struct lwip_select_cb *next; + /** Pointer to the previous waiting task */ + struct lwip_select_cb *prev; + /** readset passed to select */ + fd_set *readset; + /** writeset passed to select */ + fd_set *writeset; + /** unimplemented: exceptset passed to select */ + fd_set *exceptset; + /** don't signal the same semaphore twice: set to 1 when signalled */ + int sem_signalled; + /** semaphore to wake up a task waiting for select */ + sys_sem_t sem; +}; + +/** This struct is used to pass data to the set/getsockopt_internal + * functions running in tcpip_thread context (only a void* is allowed) */ +struct lwip_setgetsockopt_data { + /** socket struct for which to change options */ + struct lwip_sock *sock; +#ifdef LWIP_DEBUG + /** socket index for which to change options */ + int s; +#endif /* LWIP_DEBUG */ + /** level of the option to process */ + int level; + /** name of the option to process */ + int optname; + /** set: value to set the option to + * get: value of the option is stored here */ + void *optval; + /** size of *optval */ + socklen_t *optlen; + /** if an error occures, it is temporarily stored here */ + err_t err; +}; + +/** The global array of available sockets */ +static struct lwip_sock sockets[NUM_SOCKETS]; +/** The global list of tasks waiting for select */ +static struct lwip_select_cb *select_cb_list; +/** This counter is increased from lwip_select when the list is chagned + and checked in event_callback to see if it has changed. */ +static volatile int select_cb_ctr; + +/** Table to quickly map an lwIP error (err_t) to a socket error + * by using -err as an index */ +static const int err_to_errno_table[] = { + 0, /* ERR_OK 0 No error, everything OK. */ + ENOMEM, /* ERR_MEM -1 Out of memory error. */ + ENOBUFS, /* ERR_BUF -2 Buffer error. */ + EWOULDBLOCK, /* ERR_TIMEOUT -3 Timeout */ + EHOSTUNREACH, /* ERR_RTE -4 Routing problem. */ + EINPROGRESS, /* ERR_INPROGRESS -5 Operation in progress */ + EINVAL, /* ERR_VAL -6 Illegal value. */ + EWOULDBLOCK, /* ERR_WOULDBLOCK -7 Operation would block. */ + EADDRINUSE, /* ERR_USE -8 Address in use. */ + EALREADY, /* ERR_ISCONN -9 Already connected. */ + ECONNABORTED, /* ERR_ABRT -10 Connection aborted. */ + ECONNRESET, /* ERR_RST -11 Connection reset. */ + ENOTCONN, /* ERR_CLSD -12 Connection closed. */ + ENOTCONN, /* ERR_CONN -13 Not connected. */ + EIO, /* ERR_ARG -14 Illegal argument. */ + -1, /* ERR_IF -15 Low-level netif error */ +}; + +#define ERR_TO_ERRNO_TABLE_SIZE \ + (sizeof(err_to_errno_table)/sizeof(err_to_errno_table[0])) + +#define err_to_errno(err) \ + ((unsigned)(-(err)) < ERR_TO_ERRNO_TABLE_SIZE ? \ + err_to_errno_table[-(err)] : EIO) + +#ifdef ERRNO +#ifndef set_errno +#define set_errno(err) errno = (err) +#endif +#else /* ERRNO */ +#define set_errno(err) +#endif /* ERRNO */ + +#define sock_set_errno(sk, e) do { \ + sk->err = (e); \ + set_errno(sk->err); \ +} while (0) + +/* Forward delcaration of some functions */ +static void event_callback(struct netconn *conn, enum netconn_evt evt, u16_t len); +static void lwip_getsockopt_internal(void *arg); +static void lwip_setsockopt_internal(void *arg); + +/** + * Initialize this module. This function has to be called before any other + * functions in this module! + */ +void +lwip_socket_init(void) +{ +} + +/** + * Map a externally used socket index to the internal socket representation. + * + * @param s externally used socket index + * @return struct lwip_sock for the socket or NULL if not found + */ +static struct lwip_sock * +get_socket(int s) +{ + struct lwip_sock *sock; + + if ((s < 0) || (s >= NUM_SOCKETS)) { + LWIP_DEBUGF(SOCKETS_DEBUG, ("get_socket(%d): invalid\n", s)); + set_errno(EBADF); + return NULL; + } + + sock = &sockets[s]; + + if (!sock->conn) { + LWIP_DEBUGF(SOCKETS_DEBUG, ("get_socket(%d): not active\n", s)); + set_errno(EBADF); + return NULL; + } + + return sock; +} + +/** + * Same as get_socket but doesn't set errno + * + * @param s externally used socket index + * @return struct lwip_sock for the socket or NULL if not found + */ +static struct lwip_sock * +tryget_socket(int s) +{ + if ((s < 0) || (s >= NUM_SOCKETS)) { + return NULL; + } + if (!sockets[s].conn) { + return NULL; + } + return &sockets[s]; +} + +/** + * Allocate a new socket for a given netconn. + * + * @param newconn the netconn for which to allocate a socket + * @param accepted 1 if socket has been created by accept(), + * 0 if socket has been created by socket() + * @return the index of the new socket; -1 on error + */ +static int +alloc_socket(struct netconn *newconn, int accepted) +{ + int i; + SYS_ARCH_DECL_PROTECT(lev); + + /* allocate a new socket identifier */ + for (i = 0; i < NUM_SOCKETS; ++i) { + /* Protect socket array */ + SYS_ARCH_PROTECT(lev); + if (!sockets[i].conn) { + sockets[i].conn = newconn; + /* The socket is not yet known to anyone, so no need to protect + after having marked it as used. */ + SYS_ARCH_UNPROTECT(lev); + sockets[i].lastdata = NULL; + sockets[i].lastoffset = 0; + sockets[i].rcvevent = 0; + /* TCP sendbuf is empty, but the socket is not yet writable until connected + * (unless it has been created by accept()). */ + sockets[i].sendevent = (newconn->type == NETCONN_TCP ? (accepted != 0) : 1); + sockets[i].errevent = 0; + sockets[i].err = 0; + sockets[i].select_waiting = 0; + return i; + } + SYS_ARCH_UNPROTECT(lev); + } + return -1; +} + +/** Free a socket. The socket's netconn must have been + * delete before! + * + * @param sock the socket to free + * @param is_tcp != 0 for TCP sockets, used to free lastdata + */ +static void +free_socket(struct lwip_sock *sock, int is_tcp) +{ + void *lastdata; + SYS_ARCH_DECL_PROTECT(lev); + + lastdata = sock->lastdata; + sock->lastdata = NULL; + sock->lastoffset = 0; + sock->err = 0; + + /* Protect socket array */ + SYS_ARCH_PROTECT(lev); + sock->conn = NULL; + SYS_ARCH_UNPROTECT(lev); + /* don't use 'sock' after this line, as another task might have allocated it */ + + if (lastdata != NULL) { + if (is_tcp) { + pbuf_free((struct pbuf *)lastdata); + } else { + netbuf_delete((struct netbuf *)lastdata); + } + } +} + +/* Below this, the well-known socket functions are implemented. + * Use google.com or opengroup.org to get a good description :-) + * + * Exceptions are documented! + */ + +int +lwip_accept(int s, struct sockaddr *addr, socklen_t *addrlen) +{ + struct lwip_sock *sock, *nsock; + struct netconn *newconn; + ip_addr_t naddr; + u16_t port; + int newsock; + struct sockaddr_in sin; + err_t err; + SYS_ARCH_DECL_PROTECT(lev); + + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d)...\n", s)); + sock = get_socket(s); + if (!sock) { + return -1; + } + + if (netconn_is_nonblocking(sock->conn) && (sock->rcvevent <= 0)) { + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d): returning EWOULDBLOCK\n", s)); + sock_set_errno(sock, EWOULDBLOCK); + return -1; + } + + /* wait for a new connection */ + err = netconn_accept(sock->conn, &newconn); + if (err != ERR_OK) { + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d): netconn_acept failed, err=%d\n", s, err)); + if (netconn_type(sock->conn) != NETCONN_TCP) { + sock_set_errno(sock, EOPNOTSUPP); + return EOPNOTSUPP; + } + sock_set_errno(sock, err_to_errno(err)); + return -1; + } + LWIP_ASSERT("newconn != NULL", newconn != NULL); + /* Prevent automatic window updates, we do this on our own! */ + netconn_set_noautorecved(newconn, 1); + + /* get the IP address and port of the remote host */ + err = netconn_peer(newconn, &naddr, &port); + if (err != ERR_OK) { + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d): netconn_peer failed, err=%d\n", s, err)); + netconn_delete(newconn); + sock_set_errno(sock, err_to_errno(err)); + return -1; + } + + /* Note that POSIX only requires us to check addr is non-NULL. addrlen must + * not be NULL if addr is valid. + */ + if (NULL != addr) { + LWIP_ASSERT("addr valid but addrlen NULL", addrlen != NULL); + memset(&sin, 0, sizeof(sin)); + sin.sin_len = sizeof(sin); + sin.sin_family = AF_INET; + sin.sin_port = htons(port); + inet_addr_from_ipaddr(&sin.sin_addr, &naddr); + + if (*addrlen > sizeof(sin)) + *addrlen = sizeof(sin); + + MEMCPY(addr, &sin, *addrlen); + } + + newsock = alloc_socket(newconn, 1); + if (newsock == -1) { + netconn_delete(newconn); + sock_set_errno(sock, ENFILE); + return -1; + } + LWIP_ASSERT("invalid socket index", (newsock >= 0) && (newsock < NUM_SOCKETS)); + LWIP_ASSERT("newconn->callback == event_callback", newconn->callback == event_callback); + nsock = &sockets[newsock]; + + /* See event_callback: If data comes in right away after an accept, even + * though the server task might not have created a new socket yet. + * In that case, newconn->socket is counted down (newconn->socket--), + * so nsock->rcvevent is >= 1 here! + */ + SYS_ARCH_PROTECT(lev); + nsock->rcvevent += (s16_t)(-1 - newconn->socket); + newconn->socket = newsock; + SYS_ARCH_UNPROTECT(lev); + + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d) returning new sock=%d addr=", s, newsock)); + ip_addr_debug_print(SOCKETS_DEBUG, &naddr); + LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F"\n", port)); + + sock_set_errno(sock, 0); + return newsock; +} + +int +lwip_bind(int s, const struct sockaddr *name, socklen_t namelen) +{ + struct lwip_sock *sock; + ip_addr_t local_addr; + u16_t local_port; + err_t err; + const struct sockaddr_in *name_in; + + sock = get_socket(s); + if (!sock) { + return -1; + } + + /* check size, familiy and alignment of 'name' */ + LWIP_ERROR("lwip_bind: invalid address", ((namelen == sizeof(struct sockaddr_in)) && + ((name->sa_family) == AF_INET) && ((((mem_ptr_t)name) % 4) == 0)), + sock_set_errno(sock, err_to_errno(ERR_ARG)); return -1;); + name_in = (const struct sockaddr_in *)(void*)name; + + inet_addr_to_ipaddr(&local_addr, &name_in->sin_addr); + local_port = name_in->sin_port; + + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_bind(%d, addr=", s)); + ip_addr_debug_print(SOCKETS_DEBUG, &local_addr); + LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F")\n", ntohs(local_port))); + + err = netconn_bind(sock->conn, &local_addr, ntohs(local_port)); + + if (err != ERR_OK) { + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_bind(%d) failed, err=%d\n", s, err)); + sock_set_errno(sock, err_to_errno(err)); + return -1; + } + + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_bind(%d) succeeded\n", s)); + sock_set_errno(sock, 0); + return 0; +} + +int +lwip_close(int s) +{ + struct lwip_sock *sock; + int is_tcp = 0; + + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_close(%d)\n", s)); + + sock = get_socket(s); + if (!sock) { + return -1; + } + + if(sock->conn != NULL) { + is_tcp = netconn_type(sock->conn) == NETCONN_TCP; + } else { + LWIP_ASSERT("sock->lastdata == NULL", sock->lastdata == NULL); + } + + netconn_delete(sock->conn); + + free_socket(sock, is_tcp); + set_errno(0); + return 0; +} + +int +lwip_connect(int s, const struct sockaddr *name, socklen_t namelen) +{ + struct lwip_sock *sock; + err_t err; + const struct sockaddr_in *name_in; + + sock = get_socket(s); + if (!sock) { + return -1; + } + + /* check size, familiy and alignment of 'name' */ + LWIP_ERROR("lwip_connect: invalid address", ((namelen == sizeof(struct sockaddr_in)) && + ((name->sa_family) == AF_INET) && ((((mem_ptr_t)name) % 4) == 0)), + sock_set_errno(sock, err_to_errno(ERR_ARG)); return -1;); + name_in = (const struct sockaddr_in *)(void*)name; + + if (name_in->sin_family == AF_UNSPEC) { + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d, AF_UNSPEC)\n", s)); + err = netconn_disconnect(sock->conn); + } else { + ip_addr_t remote_addr; + u16_t remote_port; + + inet_addr_to_ipaddr(&remote_addr, &name_in->sin_addr); + remote_port = name_in->sin_port; + + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d, addr=", s)); + ip_addr_debug_print(SOCKETS_DEBUG, &remote_addr); + LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F")\n", ntohs(remote_port))); + + err = netconn_connect(sock->conn, &remote_addr, ntohs(remote_port)); + } + + if (err != ERR_OK) { + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d) failed, err=%d\n", s, err)); + sock_set_errno(sock, err_to_errno(err)); + return -1; + } + + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d) succeeded\n", s)); + sock_set_errno(sock, 0); + return 0; +} + +/** + * Set a socket into listen mode. + * The socket may not have been used for another connection previously. + * + * @param s the socket to set to listening mode + * @param backlog (ATTENTION: needs TCP_LISTEN_BACKLOG=1) + * @return 0 on success, non-zero on failure + */ +int +lwip_listen(int s, int backlog) +{ + struct lwip_sock *sock; + err_t err; + + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_listen(%d, backlog=%d)\n", s, backlog)); + + sock = get_socket(s); + if (!sock) { + return -1; + } + + /* limit the "backlog" parameter to fit in an u8_t */ + backlog = LWIP_MIN(LWIP_MAX(backlog, 0), 0xff); + + err = netconn_listen_with_backlog(sock->conn, (u8_t)backlog); + + if (err != ERR_OK) { + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_listen(%d) failed, err=%d\n", s, err)); + if (netconn_type(sock->conn) != NETCONN_TCP) { + sock_set_errno(sock, EOPNOTSUPP); + return EOPNOTSUPP; + } + sock_set_errno(sock, err_to_errno(err)); + return -1; + } + + sock_set_errno(sock, 0); + return 0; +} + +int +lwip_recvfrom(int s, void *mem, size_t len, int flags, + struct sockaddr *from, socklen_t *fromlen) +{ + struct lwip_sock *sock; + void *buf = NULL; + struct pbuf *p; + u16_t buflen, copylen; + int off = 0; + ip_addr_t *addr; + u16_t port; + u8_t done = 0; + err_t err; + + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d, %p, %"SZT_F", 0x%x, ..)\n", s, mem, len, flags)); + sock = get_socket(s); + if (!sock) { + return -1; + } + + do { + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom: top while sock->lastdata=%p\n", sock->lastdata)); + /* Check if there is data left from the last recv operation. */ + if (sock->lastdata) { + buf = sock->lastdata; + } else { + /* If this is non-blocking call, then check first */ + if (((flags & MSG_DONTWAIT) || netconn_is_nonblocking(sock->conn)) && + (sock->rcvevent <= 0)) { + if (off > 0) { + /* update receive window */ + netconn_recved(sock->conn, (u32_t)off); + /* already received data, return that */ + sock_set_errno(sock, 0); + return off; + } + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d): returning EWOULDBLOCK\n", s)); + sock_set_errno(sock, EWOULDBLOCK); + return -1; + } + + /* No data was left from the previous operation, so we try to get + some from the network. */ + if (netconn_type(sock->conn) == NETCONN_TCP) { + err = netconn_recv_tcp_pbuf(sock->conn, (struct pbuf **)&buf); + } else { + err = netconn_recv(sock->conn, (struct netbuf **)&buf); + } + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom: netconn_recv err=%d, netbuf=%p\n", + err, buf)); + + if (err != ERR_OK) { + if (off > 0) { + /* update receive window */ + netconn_recved(sock->conn, (u32_t)off); + /* already received data, return that */ + sock_set_errno(sock, 0); + return off; + } + /* We should really do some error checking here. */ + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d): buf == NULL, error is \"%s\"!\n", + s, lwip_strerr(err))); + sock_set_errno(sock, err_to_errno(err)); + if (err == ERR_CLSD) { + return 0; + } else { + return -1; + } + } + LWIP_ASSERT("buf != NULL", buf != NULL); + sock->lastdata = buf; + } + + if (netconn_type(sock->conn) == NETCONN_TCP) { + p = (struct pbuf *)buf; + } else { + p = ((struct netbuf *)buf)->p; + } + buflen = p->tot_len; + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom: buflen=%"U16_F" len=%"SZT_F" off=%d sock->lastoffset=%"U16_F"\n", + buflen, len, off, sock->lastoffset)); + + buflen -= sock->lastoffset; + + if (len > buflen) { + copylen = buflen; + } else { + copylen = (u16_t)len; + } + + /* copy the contents of the received buffer into + the supplied memory pointer mem */ + pbuf_copy_partial(p, (u8_t*)mem + off, copylen, sock->lastoffset); + + off += copylen; + + if (netconn_type(sock->conn) == NETCONN_TCP) { + LWIP_ASSERT("invalid copylen, len would underflow", len >= copylen); + len -= copylen; + if ( (len <= 0) || + (p->flags & PBUF_FLAG_PUSH) || + (sock->rcvevent <= 0) || + ((flags & MSG_PEEK)!=0)) { + done = 1; + } + } else { + done = 1; + } + + /* Check to see from where the data was.*/ + if (done) { + ip_addr_t fromaddr; + if (from && fromlen) { + struct sockaddr_in sin; + + if (netconn_type(sock->conn) == NETCONN_TCP) { + addr = &fromaddr; + netconn_getaddr(sock->conn, addr, &port, 0); + } else { + addr = netbuf_fromaddr((struct netbuf *)buf); + port = netbuf_fromport((struct netbuf *)buf); + } + + memset(&sin, 0, sizeof(sin)); + sin.sin_len = sizeof(sin); + sin.sin_family = AF_INET; + sin.sin_port = htons(port); + inet_addr_from_ipaddr(&sin.sin_addr, addr); + + if (*fromlen > sizeof(sin)) { + *fromlen = sizeof(sin); + } + + MEMCPY(from, &sin, *fromlen); + + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d): addr=", s)); + ip_addr_debug_print(SOCKETS_DEBUG, addr); + LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F" len=%d\n", port, off)); + } else { +#if SOCKETS_DEBUG + if (netconn_type(sock->conn) == NETCONN_TCP) { + addr = &fromaddr; + netconn_getaddr(sock->conn, addr, &port, 0); + } else { + addr = netbuf_fromaddr((struct netbuf *)buf); + port = netbuf_fromport((struct netbuf *)buf); + } + + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d): addr=", s)); + ip_addr_debug_print(SOCKETS_DEBUG, addr); + LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F" len=%d\n", port, off)); +#endif /* SOCKETS_DEBUG */ + } + } + + /* If we don't peek the incoming message... */ + if ((flags & MSG_PEEK) == 0) { + /* If this is a TCP socket, check if there is data left in the + buffer. If so, it should be saved in the sock structure for next + time around. */ + if ((netconn_type(sock->conn) == NETCONN_TCP) && (buflen - copylen > 0)) { + sock->lastdata = buf; + sock->lastoffset += copylen; + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom: lastdata now netbuf=%p\n", buf)); + } else { + sock->lastdata = NULL; + sock->lastoffset = 0; + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom: deleting netbuf=%p\n", buf)); + if (netconn_type(sock->conn) == NETCONN_TCP) { + pbuf_free((struct pbuf *)buf); + } else { + netbuf_delete((struct netbuf *)buf); + } + } + } + } while (!done); + + if (off > 0) { + /* update receive window */ + netconn_recved(sock->conn, (u32_t)off); + } + sock_set_errno(sock, 0); + return off; +} + +int +lwip_read(int s, void *mem, size_t len) +{ + return lwip_recvfrom(s, mem, len, 0, NULL, NULL); +} + +int +lwip_recv(int s, void *mem, size_t len, int flags) +{ + return lwip_recvfrom(s, mem, len, flags, NULL, NULL); +} + +int +lwip_send(int s, const void *data, size_t size, int flags) +{ + struct lwip_sock *sock; + err_t err; + u8_t write_flags; + size_t written; + + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_send(%d, data=%p, size=%"SZT_F", flags=0x%x)\n", + s, data, size, flags)); + + sock = get_socket(s); + if (!sock) { + return -1; + } + + if (sock->conn->type != NETCONN_TCP) { +#if (LWIP_UDP || LWIP_RAW) + return lwip_sendto(s, data, size, flags, NULL, 0); +#else /* (LWIP_UDP || LWIP_RAW) */ + sock_set_errno(sock, err_to_errno(ERR_ARG)); + return -1; +#endif /* (LWIP_UDP || LWIP_RAW) */ + } + + write_flags = NETCONN_COPY | + ((flags & MSG_MORE) ? NETCONN_MORE : 0) | + ((flags & MSG_DONTWAIT) ? NETCONN_DONTBLOCK : 0); + written = 0; + err = netconn_write_partly(sock->conn, data, size, write_flags, &written); + + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_send(%d) err=%d written=%"SZT_F"\n", s, err, written)); + sock_set_errno(sock, err_to_errno(err)); + return (err == ERR_OK ? (int)written : -1); +} + +int +lwip_sendto(int s, const void *data, size_t size, int flags, + const struct sockaddr *to, socklen_t tolen) +{ + struct lwip_sock *sock; + err_t err; + u16_t short_size; + const struct sockaddr_in *to_in; + u16_t remote_port; +#if !LWIP_TCPIP_CORE_LOCKING + struct netbuf buf; +#endif + + sock = get_socket(s); + if (!sock) { + return -1; + } + + if (sock->conn->type == NETCONN_TCP) { +#if LWIP_TCP + return lwip_send(s, data, size, flags); +#else /* LWIP_TCP */ + LWIP_UNUSED_ARG(flags); + sock_set_errno(sock, err_to_errno(ERR_ARG)); + return -1; +#endif /* LWIP_TCP */ + } + + /* @todo: split into multiple sendto's? */ + LWIP_ASSERT("lwip_sendto: size must fit in u16_t", size <= 0xffff); + short_size = (u16_t)size; + LWIP_ERROR("lwip_sendto: invalid address", (((to == NULL) && (tolen == 0)) || + ((tolen == sizeof(struct sockaddr_in)) && + ((to->sa_family) == AF_INET) && ((((mem_ptr_t)to) % 4) == 0))), + sock_set_errno(sock, err_to_errno(ERR_ARG)); return -1;); + to_in = (const struct sockaddr_in *)(void*)to; + +#if LWIP_TCPIP_CORE_LOCKING + /* Should only be consider like a sample or a simple way to experiment this option (no check of "to" field...) */ + { + struct pbuf* p; + ip_addr_t *remote_addr; + +#if LWIP_NETIF_TX_SINGLE_PBUF + p = pbuf_alloc(PBUF_TRANSPORT, short_size, PBUF_RAM); + if (p != NULL) { +#if LWIP_CHECKSUM_ON_COPY + u16_t chksum = 0; + if (sock->conn->type != NETCONN_RAW) { + chksum = LWIP_CHKSUM_COPY(p->payload, data, short_size); + } else +#endif /* LWIP_CHECKSUM_ON_COPY */ + MEMCPY(p->payload, data, size); +#else /* LWIP_NETIF_TX_SINGLE_PBUF */ + p = pbuf_alloc(PBUF_TRANSPORT, short_size, PBUF_REF); + if (p != NULL) { + p->payload = (void*)data; +#endif /* LWIP_NETIF_TX_SINGLE_PBUF */ + + if (to_in != NULL) { + inet_addr_to_ipaddr_p(remote_addr, &to_in->sin_addr); + remote_port = ntohs(to_in->sin_port); + } else { + remote_addr = &sock->conn->pcb.ip->remote_ip; +#if LWIP_UDP + if (NETCONNTYPE_GROUP(sock->conn->type) == NETCONN_UDP) { + remote_port = sock->conn->pcb.udp->remote_port; + } else +#endif /* LWIP_UDP */ + { + remote_port = 0; + } + } + + LOCK_TCPIP_CORE(); + if (netconn_type(sock->conn) == NETCONN_RAW) { +#if LWIP_RAW + err = sock->conn->last_err = raw_sendto(sock->conn->pcb.raw, p, remote_addr); +#else /* LWIP_RAW */ + err = ERR_ARG; +#endif /* LWIP_RAW */ + } +#if LWIP_UDP && LWIP_RAW + else +#endif /* LWIP_UDP && LWIP_RAW */ + { +#if LWIP_UDP +#if LWIP_CHECKSUM_ON_COPY && LWIP_NETIF_TX_SINGLE_PBUF + err = sock->conn->last_err = udp_sendto_chksum(sock->conn->pcb.udp, p, + remote_addr, remote_port, 1, chksum); +#else /* LWIP_CHECKSUM_ON_COPY && LWIP_NETIF_TX_SINGLE_PBUF */ + err = sock->conn->last_err = udp_sendto(sock->conn->pcb.udp, p, + remote_addr, remote_port); +#endif /* LWIP_CHECKSUM_ON_COPY && LWIP_NETIF_TX_SINGLE_PBUF */ +#else /* LWIP_UDP */ + err = ERR_ARG; +#endif /* LWIP_UDP */ + } + UNLOCK_TCPIP_CORE(); + + pbuf_free(p); + } else { + err = ERR_MEM; + } + } +#else /* LWIP_TCPIP_CORE_LOCKING */ + /* initialize a buffer */ + buf.p = buf.ptr = NULL; +#if LWIP_CHECKSUM_ON_COPY + buf.flags = 0; +#endif /* LWIP_CHECKSUM_ON_COPY */ + if (to) { + inet_addr_to_ipaddr(&buf.addr, &to_in->sin_addr); + remote_port = ntohs(to_in->sin_port); + netbuf_fromport(&buf) = remote_port; + } else { + remote_port = 0; + ip_addr_set_any(&buf.addr); + netbuf_fromport(&buf) = 0; + } + + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_sendto(%d, data=%p, short_size=%"U16_F", flags=0x%x to=", + s, data, short_size, flags)); + ip_addr_debug_print(SOCKETS_DEBUG, &buf.addr); + LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F"\n", remote_port)); + + /* make the buffer point to the data that should be sent */ +#if LWIP_NETIF_TX_SINGLE_PBUF + /* Allocate a new netbuf and copy the data into it. */ + if (netbuf_alloc(&buf, short_size) == NULL) { + err = ERR_MEM; + } else { +#if LWIP_CHECKSUM_ON_COPY + if (sock->conn->type != NETCONN_RAW) { + u16_t chksum = LWIP_CHKSUM_COPY(buf.p->payload, data, short_size); + netbuf_set_chksum(&buf, chksum); + err = ERR_OK; + } else +#endif /* LWIP_CHECKSUM_ON_COPY */ + { + err = netbuf_take(&buf, data, short_size); + } + } +#else /* LWIP_NETIF_TX_SINGLE_PBUF */ + err = netbuf_ref(&buf, data, short_size); +#endif /* LWIP_NETIF_TX_SINGLE_PBUF */ + if (err == ERR_OK) { + /* send the data */ + err = netconn_send(sock->conn, &buf); + } + + /* deallocated the buffer */ + netbuf_free(&buf); +#endif /* LWIP_TCPIP_CORE_LOCKING */ + sock_set_errno(sock, err_to_errno(err)); + return (err == ERR_OK ? short_size : -1); +} + +int +lwip_socket(int domain, int type, int protocol) +{ + struct netconn *conn; + int i; + + LWIP_UNUSED_ARG(domain); + + /* create a netconn */ + switch (type) { + case SOCK_RAW: + conn = netconn_new_with_proto_and_callback(NETCONN_RAW, (u8_t)protocol, event_callback); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_socket(%s, SOCK_RAW, %d) = ", + domain == PF_INET ? "PF_INET" : "UNKNOWN", protocol)); + break; + case SOCK_DGRAM: + conn = netconn_new_with_callback( (protocol == IPPROTO_UDPLITE) ? + NETCONN_UDPLITE : NETCONN_UDP, event_callback); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_socket(%s, SOCK_DGRAM, %d) = ", + domain == PF_INET ? "PF_INET" : "UNKNOWN", protocol)); + break; + case SOCK_STREAM: + conn = netconn_new_with_callback(NETCONN_TCP, event_callback); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_socket(%s, SOCK_STREAM, %d) = ", + domain == PF_INET ? "PF_INET" : "UNKNOWN", protocol)); + if (conn != NULL) { + /* Prevent automatic window updates, we do this on our own! */ + netconn_set_noautorecved(conn, 1); + } + break; + default: + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_socket(%d, %d/UNKNOWN, %d) = -1\n", + domain, type, protocol)); + set_errno(EINVAL); + return -1; + } + + if (!conn) { + LWIP_DEBUGF(SOCKETS_DEBUG, ("-1 / ENOBUFS (could not create netconn)\n")); + set_errno(ENOBUFS); + return -1; + } + + i = alloc_socket(conn, 0); + + if (i == -1) { + netconn_delete(conn); + set_errno(ENFILE); + return -1; + } + conn->socket = i; + LWIP_DEBUGF(SOCKETS_DEBUG, ("%d\n", i)); + set_errno(0); + return i; +} + +int +lwip_write(int s, const void *data, size_t size) +{ + return lwip_send(s, data, size, 0); +} + +/** + * Go through the readset and writeset lists and see which socket of the sockets + * set in the sets has events. On return, readset, writeset and exceptset have + * the sockets enabled that had events. + * + * exceptset is not used for now!!! + * + * @param maxfdp1 the highest socket index in the sets + * @param readset_in: set of sockets to check for read events + * @param writeset_in: set of sockets to check for write events + * @param exceptset_in: set of sockets to check for error events + * @param readset_out: set of sockets that had read events + * @param writeset_out: set of sockets that had write events + * @param exceptset_out: set os sockets that had error events + * @return number of sockets that had events (read/write/exception) (>= 0) + */ +static int +lwip_selscan(int maxfdp1, fd_set *readset_in, fd_set *writeset_in, fd_set *exceptset_in, + fd_set *readset_out, fd_set *writeset_out, fd_set *exceptset_out) +{ + int i, nready = 0; + fd_set lreadset, lwriteset, lexceptset; + struct lwip_sock *sock; + SYS_ARCH_DECL_PROTECT(lev); + + FD_ZERO(&lreadset); + FD_ZERO(&lwriteset); + FD_ZERO(&lexceptset); + + /* Go through each socket in each list to count number of sockets which + currently match */ + for(i = 0; i < maxfdp1; i++) { + void* lastdata = NULL; + s16_t rcvevent = 0; + u16_t sendevent = 0; + u16_t errevent = 0; + /* First get the socket's status (protected)... */ + SYS_ARCH_PROTECT(lev); + sock = tryget_socket(i); + if (sock != NULL) { + lastdata = sock->lastdata; + rcvevent = sock->rcvevent; + sendevent = sock->sendevent; + errevent = sock->errevent; + } + SYS_ARCH_UNPROTECT(lev); + /* ... then examine it: */ + /* See if netconn of this socket is ready for read */ + if (readset_in && FD_ISSET(i, readset_in) && ((lastdata != NULL) || (rcvevent > 0))) { + FD_SET(i, &lreadset); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_selscan: fd=%d ready for reading\n", i)); + nready++; + } + /* See if netconn of this socket is ready for write */ + if (writeset_in && FD_ISSET(i, writeset_in) && (sendevent != 0)) { + FD_SET(i, &lwriteset); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_selscan: fd=%d ready for writing\n", i)); + nready++; + } + /* See if netconn of this socket had an error */ + if (exceptset_in && FD_ISSET(i, exceptset_in) && (errevent != 0)) { + FD_SET(i, &lexceptset); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_selscan: fd=%d ready for exception\n", i)); + nready++; + } + } + /* copy local sets to the ones provided as arguments */ + *readset_out = lreadset; + *writeset_out = lwriteset; + *exceptset_out = lexceptset; + + LWIP_ASSERT("nready >= 0", nready >= 0); + return nready; +} + +/** + * Processing exceptset is not yet implemented. + */ +int +lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset, + struct timeval *timeout) +{ + u32_t waitres = 0; + int nready; + fd_set lreadset, lwriteset, lexceptset; + u32_t msectimeout; + struct lwip_select_cb select_cb; + err_t err; + int i; + SYS_ARCH_DECL_PROTECT(lev); + + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select(%d, %p, %p, %p, tvsec=%"S32_F" tvusec=%"S32_F")\n", + maxfdp1, (void *)readset, (void *) writeset, (void *) exceptset, + timeout ? (s32_t)timeout->tv_sec : (s32_t)-1, + timeout ? (s32_t)timeout->tv_usec : (s32_t)-1)); + + /* Go through each socket in each list to count number of sockets which + currently match */ + nready = lwip_selscan(maxfdp1, readset, writeset, exceptset, &lreadset, &lwriteset, &lexceptset); + + /* If we don't have any current events, then suspend if we are supposed to */ + if (!nready) { + if (timeout && timeout->tv_sec == 0 && timeout->tv_usec == 0) { + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select: no timeout, returning 0\n")); + /* This is OK as the local fdsets are empty and nready is zero, + or we would have returned earlier. */ + goto return_copy_fdsets; + } + + /* None ready: add our semaphore to list: + We don't actually need any dynamic memory. Our entry on the + list is only valid while we are in this function, so it's ok + to use local variables. */ + + select_cb.next = NULL; + select_cb.prev = NULL; + select_cb.readset = readset; + select_cb.writeset = writeset; + select_cb.exceptset = exceptset; + select_cb.sem_signalled = 0; + err = sys_sem_new(&select_cb.sem, 0); + if (err != ERR_OK) { + /* failed to create semaphore */ + set_errno(ENOMEM); + return -1; + } + + /* Protect the select_cb_list */ + SYS_ARCH_PROTECT(lev); + + /* Put this select_cb on top of list */ + select_cb.next = select_cb_list; + if (select_cb_list != NULL) { + select_cb_list->prev = &select_cb; + } + select_cb_list = &select_cb; + /* Increasing this counter tells even_callback that the list has changed. */ + select_cb_ctr++; + + /* Now we can safely unprotect */ + SYS_ARCH_UNPROTECT(lev); + + /* Increase select_waiting for each socket we are interested in */ + for(i = 0; i < maxfdp1; i++) { + if ((readset && FD_ISSET(i, readset)) || + (writeset && FD_ISSET(i, writeset)) || + (exceptset && FD_ISSET(i, exceptset))) { + struct lwip_sock *sock = tryget_socket(i); + LWIP_ASSERT("sock != NULL", sock != NULL); + SYS_ARCH_PROTECT(lev); + sock->select_waiting++; + LWIP_ASSERT("sock->select_waiting > 0", sock->select_waiting > 0); + SYS_ARCH_UNPROTECT(lev); + } + } + + /* Call lwip_selscan again: there could have been events between + the last scan (whithout us on the list) and putting us on the list! */ + nready = lwip_selscan(maxfdp1, readset, writeset, exceptset, &lreadset, &lwriteset, &lexceptset); + if (!nready) { + /* Still none ready, just wait to be woken */ + if (timeout == 0) { + /* Wait forever */ + msectimeout = 0; + } else { + msectimeout = ((timeout->tv_sec * 1000) + ((timeout->tv_usec + 500)/1000)); + if (msectimeout == 0) { + /* Wait 1ms at least (0 means wait forever) */ + msectimeout = 1; + } + } + + waitres = sys_arch_sem_wait(&select_cb.sem, msectimeout); + } + /* Increase select_waiting for each socket we are interested in */ + for(i = 0; i < maxfdp1; i++) { + if ((readset && FD_ISSET(i, readset)) || + (writeset && FD_ISSET(i, writeset)) || + (exceptset && FD_ISSET(i, exceptset))) { + struct lwip_sock *sock = tryget_socket(i); + LWIP_ASSERT("sock != NULL", sock != NULL); + SYS_ARCH_PROTECT(lev); + sock->select_waiting--; + LWIP_ASSERT("sock->select_waiting >= 0", sock->select_waiting >= 0); + SYS_ARCH_UNPROTECT(lev); + } + } + /* Take us off the list */ + SYS_ARCH_PROTECT(lev); + if (select_cb.next != NULL) { + select_cb.next->prev = select_cb.prev; + } + if (select_cb_list == &select_cb) { + LWIP_ASSERT("select_cb.prev == NULL", select_cb.prev == NULL); + select_cb_list = select_cb.next; + } else { + LWIP_ASSERT("select_cb.prev != NULL", select_cb.prev != NULL); + select_cb.prev->next = select_cb.next; + } + /* Increasing this counter tells even_callback that the list has changed. */ + select_cb_ctr++; + SYS_ARCH_UNPROTECT(lev); + + sys_sem_free(&select_cb.sem); + if (waitres == SYS_ARCH_TIMEOUT) { + /* Timeout */ + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select: timeout expired\n")); + /* This is OK as the local fdsets are empty and nready is zero, + or we would have returned earlier. */ + goto return_copy_fdsets; + } + + /* See what's set */ + nready = lwip_selscan(maxfdp1, readset, writeset, exceptset, &lreadset, &lwriteset, &lexceptset); + } + + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select: nready=%d\n", nready)); +return_copy_fdsets: + set_errno(0); + if (readset) { + *readset = lreadset; + } + if (writeset) { + *writeset = lwriteset; + } + if (exceptset) { + *exceptset = lexceptset; + } + + + return nready; +} + +/** + * Callback registered in the netconn layer for each socket-netconn. + * Processes recvevent (data available) and wakes up tasks waiting for select. + */ +static void +event_callback(struct netconn *conn, enum netconn_evt evt, u16_t len) +{ + int s; + struct lwip_sock *sock; + struct lwip_select_cb *scb; + int last_select_cb_ctr; + SYS_ARCH_DECL_PROTECT(lev); + + LWIP_UNUSED_ARG(len); + + /* Get socket */ + if (conn) { + s = conn->socket; + if (s < 0) { + /* Data comes in right away after an accept, even though + * the server task might not have created a new socket yet. + * Just count down (or up) if that's the case and we + * will use the data later. Note that only receive events + * can happen before the new socket is set up. */ + SYS_ARCH_PROTECT(lev); + if (conn->socket < 0) { + if (evt == NETCONN_EVT_RCVPLUS) { + conn->socket--; + } + SYS_ARCH_UNPROTECT(lev); + return; + } + s = conn->socket; + SYS_ARCH_UNPROTECT(lev); + } + + sock = get_socket(s); + if (!sock) { + return; + } + } else { + return; + } + + SYS_ARCH_PROTECT(lev); + /* Set event as required */ + switch (evt) { + case NETCONN_EVT_RCVPLUS: + sock->rcvevent++; + break; + case NETCONN_EVT_RCVMINUS: + sock->rcvevent--; + break; + case NETCONN_EVT_SENDPLUS: + sock->sendevent = 1; + break; + case NETCONN_EVT_SENDMINUS: + sock->sendevent = 0; + break; + case NETCONN_EVT_ERROR: + sock->errevent = 1; + break; + default: + LWIP_ASSERT("unknown event", 0); + break; + } + + if (sock->select_waiting == 0) { + /* noone is waiting for this socket, no need to check select_cb_list */ + SYS_ARCH_UNPROTECT(lev); + return; + } + + /* Now decide if anyone is waiting for this socket */ + /* NOTE: This code goes through the select_cb_list list multiple times + ONLY IF a select was actually waiting. We go through the list the number + of waiting select calls + 1. This list is expected to be small. */ + + /* At this point, SYS_ARCH is still protected! */ +again: + for (scb = select_cb_list; scb != NULL; scb = scb->next) { + if (scb->sem_signalled == 0) { + /* semaphore not signalled yet */ + int do_signal = 0; + /* Test this select call for our socket */ + if (sock->rcvevent > 0) { + if (scb->readset && FD_ISSET(s, scb->readset)) { + do_signal = 1; + } + } + if (sock->sendevent != 0) { + if (!do_signal && scb->writeset && FD_ISSET(s, scb->writeset)) { + do_signal = 1; + } + } + if (sock->errevent != 0) { + if (!do_signal && scb->exceptset && FD_ISSET(s, scb->exceptset)) { + do_signal = 1; + } + } + if (do_signal) { + scb->sem_signalled = 1; + /* Don't call SYS_ARCH_UNPROTECT() before signaling the semaphore, as this might + lead to the select thread taking itself off the list, invalidagin the semaphore. */ + sys_sem_signal(&scb->sem); + } + } + /* unlock interrupts with each step */ + last_select_cb_ctr = select_cb_ctr; + SYS_ARCH_UNPROTECT(lev); + /* this makes sure interrupt protection time is short */ + SYS_ARCH_PROTECT(lev); + if (last_select_cb_ctr != select_cb_ctr) { + /* someone has changed select_cb_list, restart at the beginning */ + goto again; + } + } + SYS_ARCH_UNPROTECT(lev); +} + +/** + * Unimplemented: Close one end of a full-duplex connection. + * Currently, the full connection is closed. + */ +int +lwip_shutdown(int s, int how) +{ + struct lwip_sock *sock; + err_t err; + u8_t shut_rx = 0, shut_tx = 0; + + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_shutdown(%d, how=%d)\n", s, how)); + + sock = get_socket(s); + if (!sock) { + return -1; + } + + if (sock->conn != NULL) { + if (netconn_type(sock->conn) != NETCONN_TCP) { + sock_set_errno(sock, EOPNOTSUPP); + return EOPNOTSUPP; + } + } else { + sock_set_errno(sock, ENOTCONN); + return ENOTCONN; + } + + if (how == SHUT_RD) { + shut_rx = 1; + } else if (how == SHUT_WR) { + shut_tx = 1; + } else if(how == SHUT_RDWR) { + shut_rx = 1; + shut_tx = 1; + } else { + sock_set_errno(sock, EINVAL); + return EINVAL; + } + err = netconn_shutdown(sock->conn, shut_rx, shut_tx); + + sock_set_errno(sock, err_to_errno(err)); + return (err == ERR_OK ? 0 : -1); +} + +static int +lwip_getaddrname(int s, struct sockaddr *name, socklen_t *namelen, u8_t local) +{ + struct lwip_sock *sock; + struct sockaddr_in sin; + ip_addr_t naddr; + + sock = get_socket(s); + if (!sock) { + return -1; + } + + memset(&sin, 0, sizeof(sin)); + sin.sin_len = sizeof(sin); + sin.sin_family = AF_INET; + + /* get the IP address and port */ + netconn_getaddr(sock->conn, &naddr, &sin.sin_port, local); + + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getaddrname(%d, addr=", s)); + ip_addr_debug_print(SOCKETS_DEBUG, &naddr); + LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F")\n", sin.sin_port)); + + sin.sin_port = htons(sin.sin_port); + inet_addr_from_ipaddr(&sin.sin_addr, &naddr); + + if (*namelen > sizeof(sin)) { + *namelen = sizeof(sin); + } + + MEMCPY(name, &sin, *namelen); + sock_set_errno(sock, 0); + return 0; +} + +int +lwip_getpeername(int s, struct sockaddr *name, socklen_t *namelen) +{ + return lwip_getaddrname(s, name, namelen, 0); +} + +int +lwip_getsockname(int s, struct sockaddr *name, socklen_t *namelen) +{ + return lwip_getaddrname(s, name, namelen, 1); +} + +int +lwip_getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen) +{ + err_t err = ERR_OK; + struct lwip_sock *sock = get_socket(s); + struct lwip_setgetsockopt_data data; + + if (!sock) { + return -1; + } + + if ((NULL == optval) || (NULL == optlen)) { + sock_set_errno(sock, EFAULT); + return -1; + } + + /* Do length and type checks for the various options first, to keep it readable. */ + switch (level) { + +/* Level: SOL_SOCKET */ + case SOL_SOCKET: + switch (optname) { + + case SO_ACCEPTCONN: + case SO_BROADCAST: + /* UNIMPL case SO_DEBUG: */ + /* UNIMPL case SO_DONTROUTE: */ + case SO_ERROR: + case SO_KEEPALIVE: + /* UNIMPL case SO_CONTIMEO: */ +#if LWIP_SO_SNDTIMEO + case SO_SNDTIMEO: +#endif /* LWIP_SO_SNDTIMEO */ +#if LWIP_SO_RCVTIMEO + case SO_RCVTIMEO: +#endif /* LWIP_SO_RCVTIMEO */ +#if LWIP_SO_RCVBUF + case SO_RCVBUF: +#endif /* LWIP_SO_RCVBUF */ + /* UNIMPL case SO_OOBINLINE: */ + /* UNIMPL case SO_SNDBUF: */ + /* UNIMPL case SO_RCVLOWAT: */ + /* UNIMPL case SO_SNDLOWAT: */ +#if SO_REUSE + case SO_REUSEADDR: + case SO_REUSEPORT: +#endif /* SO_REUSE */ + case SO_TYPE: + /* UNIMPL case SO_USELOOPBACK: */ + if (*optlen < sizeof(int)) { + err = EINVAL; + } + break; + + case SO_NO_CHECK: + if (*optlen < sizeof(int)) { + err = EINVAL; + } +#if LWIP_UDP + if ((sock->conn->type != NETCONN_UDP) || + ((udp_flags(sock->conn->pcb.udp) & UDP_FLAGS_UDPLITE) != 0)) { + /* this flag is only available for UDP, not for UDP lite */ + err = EAFNOSUPPORT; + } +#endif /* LWIP_UDP */ + break; + + default: + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, SOL_SOCKET, UNIMPL: optname=0x%x, ..)\n", + s, optname)); + err = ENOPROTOOPT; + } /* switch (optname) */ + break; + +/* Level: IPPROTO_IP */ + case IPPROTO_IP: + switch (optname) { + /* UNIMPL case IP_HDRINCL: */ + /* UNIMPL case IP_RCVDSTADDR: */ + /* UNIMPL case IP_RCVIF: */ + case IP_TTL: + case IP_TOS: + if (*optlen < sizeof(int)) { + err = EINVAL; + } + break; +#if LWIP_IGMP + case IP_MULTICAST_TTL: + if (*optlen < sizeof(u8_t)) { + err = EINVAL; + } + break; + case IP_MULTICAST_IF: + if (*optlen < sizeof(struct in_addr)) { + err = EINVAL; + } + break; + case IP_MULTICAST_LOOP: + if (*optlen < sizeof(u8_t)) { + err = EINVAL; + } + if (NETCONNTYPE_GROUP(sock->conn->type) != NETCONN_UDP) { + err = EAFNOSUPPORT; + } + break; +#endif /* LWIP_IGMP */ + + default: + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, UNIMPL: optname=0x%x, ..)\n", + s, optname)); + err = ENOPROTOOPT; + } /* switch (optname) */ + break; + +#if LWIP_TCP +/* Level: IPPROTO_TCP */ + case IPPROTO_TCP: + if (*optlen < sizeof(int)) { + err = EINVAL; + break; + } + + /* If this is no TCP socket, ignore any options. */ + if (sock->conn->type != NETCONN_TCP) + return 0; + + switch (optname) { + case TCP_NODELAY: + case TCP_KEEPALIVE: +#if LWIP_TCP_KEEPALIVE + case TCP_KEEPIDLE: + case TCP_KEEPINTVL: + case TCP_KEEPCNT: +#endif /* LWIP_TCP_KEEPALIVE */ + break; + + default: + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_TCP, UNIMPL: optname=0x%x, ..)\n", + s, optname)); + err = ENOPROTOOPT; + } /* switch (optname) */ + break; +#endif /* LWIP_TCP */ +#if LWIP_UDP && LWIP_UDPLITE +/* Level: IPPROTO_UDPLITE */ + case IPPROTO_UDPLITE: + if (*optlen < sizeof(int)) { + err = EINVAL; + break; + } + + /* If this is no UDP lite socket, ignore any options. */ + if (sock->conn->type != NETCONN_UDPLITE) { + return 0; + } + + switch (optname) { + case UDPLITE_SEND_CSCOV: + case UDPLITE_RECV_CSCOV: + break; + + default: + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_UDPLITE, UNIMPL: optname=0x%x, ..)\n", + s, optname)); + err = ENOPROTOOPT; + } /* switch (optname) */ + break; +#endif /* LWIP_UDP && LWIP_UDPLITE*/ +/* UNDEFINED LEVEL */ + default: + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, level=0x%x, UNIMPL: optname=0x%x, ..)\n", + s, level, optname)); + err = ENOPROTOOPT; + } /* switch */ + + + if (err != ERR_OK) { + sock_set_errno(sock, err); + return -1; + } + + /* Now do the actual option processing */ + data.sock = sock; +#ifdef LWIP_DEBUG + data.s = s; +#endif /* LWIP_DEBUG */ + data.level = level; + data.optname = optname; + data.optval = optval; + data.optlen = optlen; + data.err = err; + tcpip_callback(lwip_getsockopt_internal, &data); + sys_arch_sem_wait(&sock->conn->op_completed, 0); + /* maybe lwip_getsockopt_internal has changed err */ + err = data.err; + + sock_set_errno(sock, err); + return err ? -1 : 0; +} + +static void +lwip_getsockopt_internal(void *arg) +{ + struct lwip_sock *sock; +#ifdef LWIP_DEBUG + int s; +#endif /* LWIP_DEBUG */ + int level, optname; + void *optval; + struct lwip_setgetsockopt_data *data; + + LWIP_ASSERT("arg != NULL", arg != NULL); + + data = (struct lwip_setgetsockopt_data*)arg; + sock = data->sock; +#ifdef LWIP_DEBUG + s = data->s; +#endif /* LWIP_DEBUG */ + level = data->level; + optname = data->optname; + optval = data->optval; + + switch (level) { + +/* Level: SOL_SOCKET */ + case SOL_SOCKET: + switch (optname) { + + /* The option flags */ + case SO_ACCEPTCONN: + case SO_BROADCAST: + /* UNIMPL case SO_DEBUG: */ + /* UNIMPL case SO_DONTROUTE: */ + case SO_KEEPALIVE: + /* UNIMPL case SO_OOBINCLUDE: */ +#if SO_REUSE + case SO_REUSEADDR: + case SO_REUSEPORT: +#endif /* SO_REUSE */ + /*case SO_USELOOPBACK: UNIMPL */ + *(int*)optval = ip_get_option(sock->conn->pcb.ip, optname); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, SOL_SOCKET, optname=0x%x, ..) = %s\n", + s, optname, (*(int*)optval?"on":"off"))); + break; + + case SO_TYPE: + switch (NETCONNTYPE_GROUP(sock->conn->type)) { + case NETCONN_RAW: + *(int*)optval = SOCK_RAW; + break; + case NETCONN_TCP: + *(int*)optval = SOCK_STREAM; + break; + case NETCONN_UDP: + *(int*)optval = SOCK_DGRAM; + break; + default: /* unrecognized socket type */ + *(int*)optval = sock->conn->type; + LWIP_DEBUGF(SOCKETS_DEBUG, + ("lwip_getsockopt(%d, SOL_SOCKET, SO_TYPE): unrecognized socket type %d\n", + s, *(int *)optval)); + } /* switch (sock->conn->type) */ + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, SOL_SOCKET, SO_TYPE) = %d\n", + s, *(int *)optval)); + break; + + case SO_ERROR: + /* only overwrite ERR_OK or tempoary errors */ + if ((sock->err == 0) || (sock->err == EINPROGRESS)) { + sock_set_errno(sock, err_to_errno(sock->conn->last_err)); + } + *(int *)optval = sock->err; + sock->err = 0; + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, SOL_SOCKET, SO_ERROR) = %d\n", + s, *(int *)optval)); + break; + +#if LWIP_SO_SNDTIMEO + case SO_SNDTIMEO: + *(int *)optval = netconn_get_sendtimeout(sock->conn); + break; +#endif /* LWIP_SO_SNDTIMEO */ +#if LWIP_SO_RCVTIMEO + case SO_RCVTIMEO: + *(int *)optval = netconn_get_recvtimeout(sock->conn); + break; +#endif /* LWIP_SO_RCVTIMEO */ +#if LWIP_SO_RCVBUF + case SO_RCVBUF: + *(int *)optval = netconn_get_recvbufsize(sock->conn); + break; +#endif /* LWIP_SO_RCVBUF */ +#if LWIP_UDP + case SO_NO_CHECK: + *(int*)optval = (udp_flags(sock->conn->pcb.udp) & UDP_FLAGS_NOCHKSUM) ? 1 : 0; + break; +#endif /* LWIP_UDP*/ + default: + LWIP_ASSERT("unhandled optname", 0); + break; + } /* switch (optname) */ + break; + +/* Level: IPPROTO_IP */ + case IPPROTO_IP: + switch (optname) { + case IP_TTL: + *(int*)optval = sock->conn->pcb.ip->ttl; + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, IP_TTL) = %d\n", + s, *(int *)optval)); + break; + case IP_TOS: + *(int*)optval = sock->conn->pcb.ip->tos; + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, IP_TOS) = %d\n", + s, *(int *)optval)); + break; +#if LWIP_IGMP + case IP_MULTICAST_TTL: + *(u8_t*)optval = sock->conn->pcb.ip->ttl; + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, IP_MULTICAST_TTL) = %d\n", + s, *(int *)optval)); + break; + case IP_MULTICAST_IF: + inet_addr_from_ipaddr((struct in_addr*)optval, &sock->conn->pcb.udp->multicast_ip); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, IP_MULTICAST_IF) = 0x%"X32_F"\n", + s, *(u32_t *)optval)); + break; + case IP_MULTICAST_LOOP: + if ((sock->conn->pcb.udp->flags & UDP_FLAGS_MULTICAST_LOOP) != 0) { + *(u8_t*)optval = 1; + } else { + *(u8_t*)optval = 0; + } + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, IP_MULTICAST_LOOP) = %d\n", + s, *(int *)optval)); + break; +#endif /* LWIP_IGMP */ + default: + LWIP_ASSERT("unhandled optname", 0); + break; + } /* switch (optname) */ + break; + +#if LWIP_TCP +/* Level: IPPROTO_TCP */ + case IPPROTO_TCP: + switch (optname) { + case TCP_NODELAY: + *(int*)optval = tcp_nagle_disabled(sock->conn->pcb.tcp); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_TCP, TCP_NODELAY) = %s\n", + s, (*(int*)optval)?"on":"off") ); + break; + case TCP_KEEPALIVE: + *(int*)optval = (int)sock->conn->pcb.tcp->keep_idle; + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, TCP_KEEPALIVE) = %d\n", + s, *(int *)optval)); + break; + +#if LWIP_TCP_KEEPALIVE + case TCP_KEEPIDLE: + *(int*)optval = (int)(sock->conn->pcb.tcp->keep_idle/1000); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, TCP_KEEPIDLE) = %d\n", + s, *(int *)optval)); + break; + case TCP_KEEPINTVL: + *(int*)optval = (int)(sock->conn->pcb.tcp->keep_intvl/1000); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, TCP_KEEPINTVL) = %d\n", + s, *(int *)optval)); + break; + case TCP_KEEPCNT: + *(int*)optval = (int)sock->conn->pcb.tcp->keep_cnt; + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, TCP_KEEPCNT) = %d\n", + s, *(int *)optval)); + break; +#endif /* LWIP_TCP_KEEPALIVE */ + default: + LWIP_ASSERT("unhandled optname", 0); + break; + } /* switch (optname) */ + break; +#endif /* LWIP_TCP */ +#if LWIP_UDP && LWIP_UDPLITE + /* Level: IPPROTO_UDPLITE */ + case IPPROTO_UDPLITE: + switch (optname) { + case UDPLITE_SEND_CSCOV: + *(int*)optval = sock->conn->pcb.udp->chksum_len_tx; + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_UDPLITE, UDPLITE_SEND_CSCOV) = %d\n", + s, (*(int*)optval)) ); + break; + case UDPLITE_RECV_CSCOV: + *(int*)optval = sock->conn->pcb.udp->chksum_len_rx; + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_UDPLITE, UDPLITE_RECV_CSCOV) = %d\n", + s, (*(int*)optval)) ); + break; + default: + LWIP_ASSERT("unhandled optname", 0); + break; + } /* switch (optname) */ + break; +#endif /* LWIP_UDP */ + default: + LWIP_ASSERT("unhandled level", 0); + break; + } /* switch (level) */ + sys_sem_signal(&sock->conn->op_completed); +} + +int +lwip_setsockopt(int s, int level, int optname, const void *optval, socklen_t optlen) +{ + struct lwip_sock *sock = get_socket(s); + err_t err = ERR_OK; + struct lwip_setgetsockopt_data data; + + if (!sock) { + return -1; + } + + if (NULL == optval) { + sock_set_errno(sock, EFAULT); + return -1; + } + + /* Do length and type checks for the various options first, to keep it readable. */ + switch (level) { + +/* Level: SOL_SOCKET */ + case SOL_SOCKET: + switch (optname) { + + case SO_BROADCAST: + /* UNIMPL case SO_DEBUG: */ + /* UNIMPL case SO_DONTROUTE: */ + case SO_KEEPALIVE: + /* UNIMPL case case SO_CONTIMEO: */ +#if LWIP_SO_SNDTIMEO + case SO_SNDTIMEO: +#endif /* LWIP_SO_SNDTIMEO */ +#if LWIP_SO_RCVTIMEO + case SO_RCVTIMEO: +#endif /* LWIP_SO_RCVTIMEO */ +#if LWIP_SO_RCVBUF + case SO_RCVBUF: +#endif /* LWIP_SO_RCVBUF */ + /* UNIMPL case SO_OOBINLINE: */ + /* UNIMPL case SO_SNDBUF: */ + /* UNIMPL case SO_RCVLOWAT: */ + /* UNIMPL case SO_SNDLOWAT: */ +#if SO_REUSE + case SO_REUSEADDR: + case SO_REUSEPORT: +#endif /* SO_REUSE */ + /* UNIMPL case SO_USELOOPBACK: */ + if (optlen < sizeof(int)) { + err = EINVAL; + } + break; + case SO_NO_CHECK: + if (optlen < sizeof(int)) { + err = EINVAL; + } +#if LWIP_UDP + if ((sock->conn->type != NETCONN_UDP) || + ((udp_flags(sock->conn->pcb.udp) & UDP_FLAGS_UDPLITE) != 0)) { + /* this flag is only available for UDP, not for UDP lite */ + err = EAFNOSUPPORT; + } +#endif /* LWIP_UDP */ + break; + default: + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, SOL_SOCKET, UNIMPL: optname=0x%x, ..)\n", + s, optname)); + err = ENOPROTOOPT; + } /* switch (optname) */ + break; + +/* Level: IPPROTO_IP */ + case IPPROTO_IP: + switch (optname) { + /* UNIMPL case IP_HDRINCL: */ + /* UNIMPL case IP_RCVDSTADDR: */ + /* UNIMPL case IP_RCVIF: */ + case IP_TTL: + case IP_TOS: + if (optlen < sizeof(int)) { + err = EINVAL; + } + break; +#if LWIP_IGMP + case IP_MULTICAST_TTL: + if (optlen < sizeof(u8_t)) { + err = EINVAL; + } + if (NETCONNTYPE_GROUP(sock->conn->type) != NETCONN_UDP) { + err = EAFNOSUPPORT; + } + break; + case IP_MULTICAST_IF: + if (optlen < sizeof(struct in_addr)) { + err = EINVAL; + } + if (NETCONNTYPE_GROUP(sock->conn->type) != NETCONN_UDP) { + err = EAFNOSUPPORT; + } + break; + case IP_MULTICAST_LOOP: + if (optlen < sizeof(u8_t)) { + err = EINVAL; + } + if (NETCONNTYPE_GROUP(sock->conn->type) != NETCONN_UDP) { + err = EAFNOSUPPORT; + } + break; + case IP_ADD_MEMBERSHIP: + case IP_DROP_MEMBERSHIP: + if (optlen < sizeof(struct ip_mreq)) { + err = EINVAL; + } + if (NETCONNTYPE_GROUP(sock->conn->type) != NETCONN_UDP) { + err = EAFNOSUPPORT; + } + break; +#endif /* LWIP_IGMP */ + default: + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_IP, UNIMPL: optname=0x%x, ..)\n", + s, optname)); + err = ENOPROTOOPT; + } /* switch (optname) */ + break; + +#if LWIP_TCP +/* Level: IPPROTO_TCP */ + case IPPROTO_TCP: + if (optlen < sizeof(int)) { + err = EINVAL; + break; + } + + /* If this is no TCP socket, ignore any options. */ + if (sock->conn->type != NETCONN_TCP) + return 0; + + switch (optname) { + case TCP_NODELAY: + case TCP_KEEPALIVE: +#if LWIP_TCP_KEEPALIVE + case TCP_KEEPIDLE: + case TCP_KEEPINTVL: + case TCP_KEEPCNT: +#endif /* LWIP_TCP_KEEPALIVE */ + break; + + default: + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, UNIMPL: optname=0x%x, ..)\n", + s, optname)); + err = ENOPROTOOPT; + } /* switch (optname) */ + break; +#endif /* LWIP_TCP */ +#if LWIP_UDP && LWIP_UDPLITE +/* Level: IPPROTO_UDPLITE */ + case IPPROTO_UDPLITE: + if (optlen < sizeof(int)) { + err = EINVAL; + break; + } + + /* If this is no UDP lite socket, ignore any options. */ + if (sock->conn->type != NETCONN_UDPLITE) + return 0; + + switch (optname) { + case UDPLITE_SEND_CSCOV: + case UDPLITE_RECV_CSCOV: + break; + + default: + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_UDPLITE, UNIMPL: optname=0x%x, ..)\n", + s, optname)); + err = ENOPROTOOPT; + } /* switch (optname) */ + break; +#endif /* LWIP_UDP && LWIP_UDPLITE */ +/* UNDEFINED LEVEL */ + default: + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, level=0x%x, UNIMPL: optname=0x%x, ..)\n", + s, level, optname)); + err = ENOPROTOOPT; + } /* switch (level) */ + + + if (err != ERR_OK) { + sock_set_errno(sock, err); + return -1; + } + + + /* Now do the actual option processing */ + data.sock = sock; +#ifdef LWIP_DEBUG + data.s = s; +#endif /* LWIP_DEBUG */ + data.level = level; + data.optname = optname; + data.optval = (void*)optval; + data.optlen = &optlen; + data.err = err; + tcpip_callback(lwip_setsockopt_internal, &data); + sys_arch_sem_wait(&sock->conn->op_completed, 0); + /* maybe lwip_setsockopt_internal has changed err */ + err = data.err; + + sock_set_errno(sock, err); + return err ? -1 : 0; +} + +static void +lwip_setsockopt_internal(void *arg) +{ + struct lwip_sock *sock; +#ifdef LWIP_DEBUG + int s; +#endif /* LWIP_DEBUG */ + int level, optname; + const void *optval; + struct lwip_setgetsockopt_data *data; + + LWIP_ASSERT("arg != NULL", arg != NULL); + + data = (struct lwip_setgetsockopt_data*)arg; + sock = data->sock; +#ifdef LWIP_DEBUG + s = data->s; +#endif /* LWIP_DEBUG */ + level = data->level; + optname = data->optname; + optval = data->optval; + + switch (level) { + +/* Level: SOL_SOCKET */ + case SOL_SOCKET: + switch (optname) { + + /* The option flags */ + case SO_BROADCAST: + /* UNIMPL case SO_DEBUG: */ + /* UNIMPL case SO_DONTROUTE: */ + case SO_KEEPALIVE: + /* UNIMPL case SO_OOBINCLUDE: */ +#if SO_REUSE + case SO_REUSEADDR: + case SO_REUSEPORT: +#endif /* SO_REUSE */ + /* UNIMPL case SO_USELOOPBACK: */ + if (*(int*)optval) { + ip_set_option(sock->conn->pcb.ip, optname); + } else { + ip_reset_option(sock->conn->pcb.ip, optname); + } + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, SOL_SOCKET, optname=0x%x, ..) -> %s\n", + s, optname, (*(int*)optval?"on":"off"))); + break; +#if LWIP_SO_SNDTIMEO + case SO_SNDTIMEO: + netconn_set_sendtimeout(sock->conn, (s32_t)*(int*)optval); + break; +#endif /* LWIP_SO_SNDTIMEO */ +#if LWIP_SO_RCVTIMEO + case SO_RCVTIMEO: + netconn_set_recvtimeout(sock->conn, *(int*)optval); + break; +#endif /* LWIP_SO_RCVTIMEO */ +#if LWIP_SO_RCVBUF + case SO_RCVBUF: + netconn_set_recvbufsize(sock->conn, *(int*)optval); + break; +#endif /* LWIP_SO_RCVBUF */ +#if LWIP_UDP + case SO_NO_CHECK: + if (*(int*)optval) { + udp_setflags(sock->conn->pcb.udp, udp_flags(sock->conn->pcb.udp) | UDP_FLAGS_NOCHKSUM); + } else { + udp_setflags(sock->conn->pcb.udp, udp_flags(sock->conn->pcb.udp) & ~UDP_FLAGS_NOCHKSUM); + } + break; +#endif /* LWIP_UDP */ + default: + LWIP_ASSERT("unhandled optname", 0); + break; + } /* switch (optname) */ + break; + +/* Level: IPPROTO_IP */ + case IPPROTO_IP: + switch (optname) { + case IP_TTL: + sock->conn->pcb.ip->ttl = (u8_t)(*(int*)optval); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_IP, IP_TTL, ..) -> %d\n", + s, sock->conn->pcb.ip->ttl)); + break; + case IP_TOS: + sock->conn->pcb.ip->tos = (u8_t)(*(int*)optval); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_IP, IP_TOS, ..)-> %d\n", + s, sock->conn->pcb.ip->tos)); + break; +#if LWIP_IGMP + case IP_MULTICAST_TTL: + sock->conn->pcb.udp->ttl = (u8_t)(*(u8_t*)optval); + break; + case IP_MULTICAST_IF: + inet_addr_to_ipaddr(&sock->conn->pcb.udp->multicast_ip, (struct in_addr*)optval); + break; + case IP_MULTICAST_LOOP: + if (*(u8_t*)optval) { + udp_setflags(sock->conn->pcb.udp, udp_flags(sock->conn->pcb.udp) | UDP_FLAGS_MULTICAST_LOOP); + } else { + udp_setflags(sock->conn->pcb.udp, udp_flags(sock->conn->pcb.udp) & ~UDP_FLAGS_MULTICAST_LOOP); + } + break; + case IP_ADD_MEMBERSHIP: + case IP_DROP_MEMBERSHIP: + { + /* If this is a TCP or a RAW socket, ignore these options. */ + struct ip_mreq *imr = (struct ip_mreq *)optval; + ip_addr_t if_addr; + ip_addr_t multi_addr; + inet_addr_to_ipaddr(&if_addr, &imr->imr_interface); + inet_addr_to_ipaddr(&multi_addr, &imr->imr_multiaddr); + if(optname == IP_ADD_MEMBERSHIP){ + data->err = igmp_joingroup(&if_addr, &multi_addr); + } else { + data->err = igmp_leavegroup(&if_addr, &multi_addr); + } + if(data->err != ERR_OK) { + data->err = EADDRNOTAVAIL; + } + } + break; +#endif /* LWIP_IGMP */ + default: + LWIP_ASSERT("unhandled optname", 0); + break; + } /* switch (optname) */ + break; + +#if LWIP_TCP +/* Level: IPPROTO_TCP */ + case IPPROTO_TCP: + switch (optname) { + case TCP_NODELAY: + if (*(int*)optval) { + tcp_nagle_disable(sock->conn->pcb.tcp); + } else { + tcp_nagle_enable(sock->conn->pcb.tcp); + } + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, TCP_NODELAY) -> %s\n", + s, (*(int *)optval)?"on":"off") ); + break; + case TCP_KEEPALIVE: + sock->conn->pcb.tcp->keep_idle = (u32_t)(*(int*)optval); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, TCP_KEEPALIVE) -> %"U32_F"\n", + s, sock->conn->pcb.tcp->keep_idle)); + break; + +#if LWIP_TCP_KEEPALIVE + case TCP_KEEPIDLE: + sock->conn->pcb.tcp->keep_idle = 1000*(u32_t)(*(int*)optval); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, TCP_KEEPIDLE) -> %"U32_F"\n", + s, sock->conn->pcb.tcp->keep_idle)); + break; + case TCP_KEEPINTVL: + sock->conn->pcb.tcp->keep_intvl = 1000*(u32_t)(*(int*)optval); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, TCP_KEEPINTVL) -> %"U32_F"\n", + s, sock->conn->pcb.tcp->keep_intvl)); + break; + case TCP_KEEPCNT: + sock->conn->pcb.tcp->keep_cnt = (u32_t)(*(int*)optval); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, TCP_KEEPCNT) -> %"U32_F"\n", + s, sock->conn->pcb.tcp->keep_cnt)); + break; +#endif /* LWIP_TCP_KEEPALIVE */ + default: + LWIP_ASSERT("unhandled optname", 0); + break; + } /* switch (optname) */ + break; +#endif /* LWIP_TCP*/ +#if LWIP_UDP && LWIP_UDPLITE + /* Level: IPPROTO_UDPLITE */ + case IPPROTO_UDPLITE: + switch (optname) { + case UDPLITE_SEND_CSCOV: + if ((*(int*)optval != 0) && ((*(int*)optval < 8) || (*(int*)optval > 0xffff))) { + /* don't allow illegal values! */ + sock->conn->pcb.udp->chksum_len_tx = 8; + } else { + sock->conn->pcb.udp->chksum_len_tx = (u16_t)*(int*)optval; + } + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_UDPLITE, UDPLITE_SEND_CSCOV) -> %d\n", + s, (*(int*)optval)) ); + break; + case UDPLITE_RECV_CSCOV: + if ((*(int*)optval != 0) && ((*(int*)optval < 8) || (*(int*)optval > 0xffff))) { + /* don't allow illegal values! */ + sock->conn->pcb.udp->chksum_len_rx = 8; + } else { + sock->conn->pcb.udp->chksum_len_rx = (u16_t)*(int*)optval; + } + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_UDPLITE, UDPLITE_RECV_CSCOV) -> %d\n", + s, (*(int*)optval)) ); + break; + default: + LWIP_ASSERT("unhandled optname", 0); + break; + } /* switch (optname) */ + break; +#endif /* LWIP_UDP */ + default: + LWIP_ASSERT("unhandled level", 0); + break; + } /* switch (level) */ + sys_sem_signal(&sock->conn->op_completed); +} + +int +lwip_ioctl(int s, long cmd, void *argp) +{ + struct lwip_sock *sock = get_socket(s); + u8_t val; +#if LWIP_SO_RCVBUF + u16_t buflen = 0; + s16_t recv_avail; +#endif /* LWIP_SO_RCVBUF */ + + if (!sock) { + return -1; + } + + switch (cmd) { +#if LWIP_SO_RCVBUF + case FIONREAD: + if (!argp) { + sock_set_errno(sock, EINVAL); + return -1; + } + + SYS_ARCH_GET(sock->conn->recv_avail, recv_avail); + if (recv_avail < 0) { + recv_avail = 0; + } + *((u16_t*)argp) = (u16_t)recv_avail; + + /* Check if there is data left from the last recv operation. /maq 041215 */ + if (sock->lastdata) { + struct pbuf *p = (struct pbuf *)sock->lastdata; + if (netconn_type(sock->conn) != NETCONN_TCP) { + p = ((struct netbuf *)p)->p; + } + buflen = p->tot_len; + buflen -= sock->lastoffset; + + *((u16_t*)argp) += buflen; + } + + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_ioctl(%d, FIONREAD, %p) = %"U16_F"\n", s, argp, *((u16_t*)argp))); + sock_set_errno(sock, 0); + return 0; +#endif /* LWIP_SO_RCVBUF */ + + case FIONBIO: + val = 0; + if (argp && *(u32_t*)argp) { + val = 1; + } + netconn_set_nonblocking(sock->conn, val); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_ioctl(%d, FIONBIO, %d)\n", s, val)); + sock_set_errno(sock, 0); + return 0; + + default: + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_ioctl(%d, UNIMPL: 0x%lx, %p)\n", s, cmd, argp)); + sock_set_errno(sock, ENOSYS); /* not yet implemented */ + return -1; + } /* switch (cmd) */ +} + +/** A minimal implementation of fcntl. + * Currently only the commands F_GETFL and F_SETFL are implemented. + * Only the flag O_NONBLOCK is implemented. + */ +int +lwip_fcntl(int s, int cmd, int val) +{ + struct lwip_sock *sock = get_socket(s); + int ret = -1; + + if (!sock || !sock->conn) { + return -1; + } + + switch (cmd) { + case F_GETFL: + ret = netconn_is_nonblocking(sock->conn) ? O_NONBLOCK : 0; + break; + case F_SETFL: + if ((val & ~O_NONBLOCK) == 0) { + /* only O_NONBLOCK, all other bits are zero */ + netconn_set_nonblocking(sock->conn, val & O_NONBLOCK); + ret = 0; + } + break; + default: + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_fcntl(%d, UNIMPL: %d, %d)\n", s, cmd, val)); + break; + } + return ret; +} + +#endif /* LWIP_SOCKET */ diff --git a/src/lwip-1.4.1/src/api/tcpip.c b/src/lwip-1.4.1/src/api/tcpip.c new file mode 100644 index 0000000..18d5f67 --- /dev/null +++ b/src/lwip-1.4.1/src/api/tcpip.c @@ -0,0 +1,511 @@ +/** + * @file + * Sequential API Main thread module + * + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#include "lwip/opt.h" + +#if !NO_SYS /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/sys.h" +#include "lwip/memp.h" +#include "lwip/mem.h" +#include "lwip/pbuf.h" +#include "lwip/tcpip.h" +#include "lwip/init.h" +#include "netif/etharp.h" +#include "netif/ppp_oe.h" + +/* global variables */ +static tcpip_init_done_fn tcpip_init_done; +static void *tcpip_init_done_arg; +static sys_mbox_t mbox; + +#if LWIP_TCPIP_CORE_LOCKING +/** The global semaphore to lock the stack. */ +sys_mutex_t lock_tcpip_core; +#endif /* LWIP_TCPIP_CORE_LOCKING */ + + +/** + * The main lwIP thread. This thread has exclusive access to lwIP core functions + * (unless access to them is not locked). Other threads communicate with this + * thread using message boxes. + * + * It also starts all the timers to make sure they are running in the right + * thread context. + * + * @param arg unused argument + */ +static void +tcpip_thread(void *arg) +{ + struct tcpip_msg *msg; + LWIP_UNUSED_ARG(arg); + + if (tcpip_init_done != NULL) { + tcpip_init_done(tcpip_init_done_arg); + } + + LOCK_TCPIP_CORE(); + while (1) { /* MAIN Loop */ + UNLOCK_TCPIP_CORE(); + LWIP_TCPIP_THREAD_ALIVE(); + /* wait for a message, timeouts are processed while waiting */ + sys_timeouts_mbox_fetch(&mbox, (void **)&msg); + LOCK_TCPIP_CORE(); + switch (msg->type) { +#if LWIP_NETCONN + case TCPIP_MSG_API: + LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: API message %p\n", (void *)msg)); + msg->msg.apimsg->function(&(msg->msg.apimsg->msg)); + break; +#endif /* LWIP_NETCONN */ + +#if !LWIP_TCPIP_CORE_LOCKING_INPUT + case TCPIP_MSG_INPKT: + LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: PACKET %p\n", (void *)msg)); +#if LWIP_ETHERNET + if (msg->msg.inp.netif->flags & (NETIF_FLAG_ETHARP | NETIF_FLAG_ETHERNET)) { + ethernet_input(msg->msg.inp.p, msg->msg.inp.netif); + } else +#endif /* LWIP_ETHERNET */ + { + ip_input(msg->msg.inp.p, msg->msg.inp.netif); + } + memp_free(MEMP_TCPIP_MSG_INPKT, msg); + break; +#endif /* LWIP_TCPIP_CORE_LOCKING_INPUT */ + +#if LWIP_NETIF_API + case TCPIP_MSG_NETIFAPI: + LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: Netif API message %p\n", (void *)msg)); + msg->msg.netifapimsg->function(&(msg->msg.netifapimsg->msg)); + break; +#endif /* LWIP_NETIF_API */ + +#if LWIP_TCPIP_TIMEOUT + case TCPIP_MSG_TIMEOUT: + LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: TIMEOUT %p\n", (void *)msg)); + sys_timeout(msg->msg.tmo.msecs, msg->msg.tmo.h, msg->msg.tmo.arg); + memp_free(MEMP_TCPIP_MSG_API, msg); + break; + case TCPIP_MSG_UNTIMEOUT: + LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: UNTIMEOUT %p\n", (void *)msg)); + sys_untimeout(msg->msg.tmo.h, msg->msg.tmo.arg); + memp_free(MEMP_TCPIP_MSG_API, msg); + break; +#endif /* LWIP_TCPIP_TIMEOUT */ + + case TCPIP_MSG_CALLBACK: + LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: CALLBACK %p\n", (void *)msg)); + msg->msg.cb.function(msg->msg.cb.ctx); + memp_free(MEMP_TCPIP_MSG_API, msg); + break; + + case TCPIP_MSG_CALLBACK_STATIC: + LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: CALLBACK_STATIC %p\n", (void *)msg)); + msg->msg.cb.function(msg->msg.cb.ctx); + break; + + default: + LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: invalid message: %d\n", msg->type)); + LWIP_ASSERT("tcpip_thread: invalid message", 0); + break; + } + } +} + +/** + * Pass a received packet to tcpip_thread for input processing + * + * @param p the received packet, p->payload pointing to the Ethernet header or + * to an IP header (if inp doesn't have NETIF_FLAG_ETHARP or + * NETIF_FLAG_ETHERNET flags) + * @param inp the network interface on which the packet was received + */ +err_t +tcpip_input(struct pbuf *p, struct netif *inp) +{ +#if LWIP_TCPIP_CORE_LOCKING_INPUT + err_t ret; + LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_input: PACKET %p/%p\n", (void *)p, (void *)inp)); + LOCK_TCPIP_CORE(); +#if LWIP_ETHERNET + if (inp->flags & (NETIF_FLAG_ETHARP | NETIF_FLAG_ETHERNET)) { + ret = ethernet_input(p, inp); + } else +#endif /* LWIP_ETHERNET */ + { + ret = ip_input(p, inp); + } + UNLOCK_TCPIP_CORE(); + return ret; +#else /* LWIP_TCPIP_CORE_LOCKING_INPUT */ + struct tcpip_msg *msg; + + if (!sys_mbox_valid(&mbox)) { + return ERR_VAL; + } + msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_INPKT); + if (msg == NULL) { + return ERR_MEM; + } + + msg->type = TCPIP_MSG_INPKT; + msg->msg.inp.p = p; + msg->msg.inp.netif = inp; + if (sys_mbox_trypost(&mbox, msg) != ERR_OK) { + memp_free(MEMP_TCPIP_MSG_INPKT, msg); + return ERR_MEM; + } + return ERR_OK; +#endif /* LWIP_TCPIP_CORE_LOCKING_INPUT */ +} + +/** + * Call a specific function in the thread context of + * tcpip_thread for easy access synchronization. + * A function called in that way may access lwIP core code + * without fearing concurrent access. + * + * @param f the function to call + * @param ctx parameter passed to f + * @param block 1 to block until the request is posted, 0 to non-blocking mode + * @return ERR_OK if the function was called, another err_t if not + */ +err_t +tcpip_callback_with_block(tcpip_callback_fn function, void *ctx, u8_t block) +{ + struct tcpip_msg *msg; + + if (sys_mbox_valid(&mbox)) { + msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_API); + if (msg == NULL) { + return ERR_MEM; + } + + msg->type = TCPIP_MSG_CALLBACK; + msg->msg.cb.function = function; + msg->msg.cb.ctx = ctx; + if (block) { + sys_mbox_post(&mbox, msg); + } else { + if (sys_mbox_trypost(&mbox, msg) != ERR_OK) { + memp_free(MEMP_TCPIP_MSG_API, msg); + return ERR_MEM; + } + } + return ERR_OK; + } + return ERR_VAL; +} + +#if LWIP_TCPIP_TIMEOUT +/** + * call sys_timeout in tcpip_thread + * + * @param msec time in milliseconds for timeout + * @param h function to be called on timeout + * @param arg argument to pass to timeout function h + * @return ERR_MEM on memory error, ERR_OK otherwise + */ +err_t +tcpip_timeout(u32_t msecs, sys_timeout_handler h, void *arg) +{ + struct tcpip_msg *msg; + + if (sys_mbox_valid(&mbox)) { + msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_API); + if (msg == NULL) { + return ERR_MEM; + } + + msg->type = TCPIP_MSG_TIMEOUT; + msg->msg.tmo.msecs = msecs; + msg->msg.tmo.h = h; + msg->msg.tmo.arg = arg; + sys_mbox_post(&mbox, msg); + return ERR_OK; + } + return ERR_VAL; +} + +/** + * call sys_untimeout in tcpip_thread + * + * @param msec time in milliseconds for timeout + * @param h function to be called on timeout + * @param arg argument to pass to timeout function h + * @return ERR_MEM on memory error, ERR_OK otherwise + */ +err_t +tcpip_untimeout(sys_timeout_handler h, void *arg) +{ + struct tcpip_msg *msg; + + if (sys_mbox_valid(&mbox)) { + msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_API); + if (msg == NULL) { + return ERR_MEM; + } + + msg->type = TCPIP_MSG_UNTIMEOUT; + msg->msg.tmo.h = h; + msg->msg.tmo.arg = arg; + sys_mbox_post(&mbox, msg); + return ERR_OK; + } + return ERR_VAL; +} +#endif /* LWIP_TCPIP_TIMEOUT */ + +#if LWIP_NETCONN +/** + * Call the lower part of a netconn_* function + * This function is then running in the thread context + * of tcpip_thread and has exclusive access to lwIP core code. + * + * @param apimsg a struct containing the function to call and its parameters + * @return ERR_OK if the function was called, another err_t if not + */ +err_t +tcpip_apimsg(struct api_msg *apimsg) +{ + struct tcpip_msg msg; +#ifdef LWIP_DEBUG + /* catch functions that don't set err */ + apimsg->msg.err = ERR_VAL; +#endif + + if (sys_mbox_valid(&mbox)) { + msg.type = TCPIP_MSG_API; + msg.msg.apimsg = apimsg; + sys_mbox_post(&mbox, &msg); + sys_arch_sem_wait(&apimsg->msg.conn->op_completed, 0); + return apimsg->msg.err; + } + return ERR_VAL; +} + +#if LWIP_TCPIP_CORE_LOCKING +/** + * Call the lower part of a netconn_* function + * This function has exclusive access to lwIP core code by locking it + * before the function is called. + * + * @param apimsg a struct containing the function to call and its parameters + * @return ERR_OK (only for compatibility fo tcpip_apimsg()) + */ +err_t +tcpip_apimsg_lock(struct api_msg *apimsg) +{ +#ifdef LWIP_DEBUG + /* catch functions that don't set err */ + apimsg->msg.err = ERR_VAL; +#endif + + LOCK_TCPIP_CORE(); + apimsg->function(&(apimsg->msg)); + UNLOCK_TCPIP_CORE(); + return apimsg->msg.err; + +} +#endif /* LWIP_TCPIP_CORE_LOCKING */ +#endif /* LWIP_NETCONN */ + +#if LWIP_NETIF_API +#if !LWIP_TCPIP_CORE_LOCKING +/** + * Much like tcpip_apimsg, but calls the lower part of a netifapi_* + * function. + * + * @param netifapimsg a struct containing the function to call and its parameters + * @return error code given back by the function that was called + */ +err_t +tcpip_netifapi(struct netifapi_msg* netifapimsg) +{ + struct tcpip_msg msg; + + if (sys_mbox_valid(&mbox)) { + err_t err = sys_sem_new(&netifapimsg->msg.sem, 0); + if (err != ERR_OK) { + netifapimsg->msg.err = err; + return err; + } + + msg.type = TCPIP_MSG_NETIFAPI; + msg.msg.netifapimsg = netifapimsg; + sys_mbox_post(&mbox, &msg); + sys_sem_wait(&netifapimsg->msg.sem); + sys_sem_free(&netifapimsg->msg.sem); + return netifapimsg->msg.err; + } + return ERR_VAL; +} +#else /* !LWIP_TCPIP_CORE_LOCKING */ +/** + * Call the lower part of a netifapi_* function + * This function has exclusive access to lwIP core code by locking it + * before the function is called. + * + * @param netifapimsg a struct containing the function to call and its parameters + * @return ERR_OK (only for compatibility fo tcpip_netifapi()) + */ +err_t +tcpip_netifapi_lock(struct netifapi_msg* netifapimsg) +{ + LOCK_TCPIP_CORE(); + netifapimsg->function(&(netifapimsg->msg)); + UNLOCK_TCPIP_CORE(); + return netifapimsg->msg.err; +} +#endif /* !LWIP_TCPIP_CORE_LOCKING */ +#endif /* LWIP_NETIF_API */ + +/** + * Allocate a structure for a static callback message and initialize it. + * This is intended to be used to send "static" messages from interrupt context. + * + * @param function the function to call + * @param ctx parameter passed to function + * @return a struct pointer to pass to tcpip_trycallback(). + */ +struct tcpip_callback_msg* tcpip_callbackmsg_new(tcpip_callback_fn function, void *ctx) +{ + struct tcpip_msg *msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_API); + if (msg == NULL) { + return NULL; + } + msg->type = TCPIP_MSG_CALLBACK_STATIC; + msg->msg.cb.function = function; + msg->msg.cb.ctx = ctx; + return (struct tcpip_callback_msg*)msg; +} + +/** + * Free a callback message allocated by tcpip_callbackmsg_new(). + * + * @param msg the message to free + */ +void tcpip_callbackmsg_delete(struct tcpip_callback_msg* msg) +{ + memp_free(MEMP_TCPIP_MSG_API, msg); +} + +/** + * Try to post a callback-message to the tcpip_thread mbox + * This is intended to be used to send "static" messages from interrupt context. + * + * @param msg pointer to the message to post + * @return sys_mbox_trypost() return code + */ +err_t +tcpip_trycallback(struct tcpip_callback_msg* msg) +{ + if (!sys_mbox_valid(&mbox)) { + return ERR_VAL; + } + return sys_mbox_trypost(&mbox, msg); +} + +/** + * Initialize this module: + * - initialize all sub modules + * - start the tcpip_thread + * + * @param initfunc a function to call when tcpip_thread is running and finished initializing + * @param arg argument to pass to initfunc + */ +void +tcpip_init(tcpip_init_done_fn initfunc, void *arg) +{ + lwip_init(); + + tcpip_init_done = initfunc; + tcpip_init_done_arg = arg; + if(sys_mbox_new(&mbox, TCPIP_MBOX_SIZE) != ERR_OK) { + LWIP_ASSERT("failed to create tcpip_thread mbox", 0); + } +#if LWIP_TCPIP_CORE_LOCKING + if(sys_mutex_new(&lock_tcpip_core) != ERR_OK) { + LWIP_ASSERT("failed to create lock_tcpip_core", 0); + } +#endif /* LWIP_TCPIP_CORE_LOCKING */ + + sys_thread_new(TCPIP_THREAD_NAME, tcpip_thread, NULL, TCPIP_THREAD_STACKSIZE, TCPIP_THREAD_PRIO); +} + +/** + * Simple callback function used with tcpip_callback to free a pbuf + * (pbuf_free has a wrong signature for tcpip_callback) + * + * @param p The pbuf (chain) to be dereferenced. + */ +static void +pbuf_free_int(void *p) +{ + struct pbuf *q = (struct pbuf *)p; + pbuf_free(q); +} + +/** + * A simple wrapper function that allows you to free a pbuf from interrupt context. + * + * @param p The pbuf (chain) to be dereferenced. + * @return ERR_OK if callback could be enqueued, an err_t if not + */ +err_t +pbuf_free_callback(struct pbuf *p) +{ + return tcpip_callback_with_block(pbuf_free_int, p, 0); +} + +/** + * A simple wrapper function that allows you to free heap memory from + * interrupt context. + * + * @param m the heap memory to free + * @return ERR_OK if callback could be enqueued, an err_t if not + */ +err_t +mem_free_callback(void *m) +{ + return tcpip_callback_with_block(mem_free, m, 0); +} + +#endif /* !NO_SYS */ diff --git a/src/lwip-1.4.1/src/core/def.c b/src/lwip-1.4.1/src/core/def.c new file mode 100644 index 0000000..352b552 --- /dev/null +++ b/src/lwip-1.4.1/src/core/def.c @@ -0,0 +1,108 @@ +/** + * @file + * Common functions used throughout the stack. + * + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Simon Goldschmidt + * + */ + +#include "lwip/opt.h" +#include "lwip/def.h" + +/** + * These are reference implementations of the byte swapping functions. + * Again with the aim of being simple, correct and fully portable. + * Byte swapping is the second thing you would want to optimize. You will + * need to port it to your architecture and in your cc.h: + * + * #define LWIP_PLATFORM_BYTESWAP 1 + * #define LWIP_PLATFORM_HTONS(x) + * #define LWIP_PLATFORM_HTONL(x) + * + * Note ntohs() and ntohl() are merely references to the htonx counterparts. + */ + +#if (LWIP_PLATFORM_BYTESWAP == 0) && (BYTE_ORDER == LITTLE_ENDIAN) + +/** + * Convert an u16_t from host- to network byte order. + * + * @param n u16_t in host byte order + * @return n in network byte order + */ +u16_t +lwip_htons(u16_t n) +{ + return ((n & 0xff) << 8) | ((n & 0xff00) >> 8); +} + +/** + * Convert an u16_t from network- to host byte order. + * + * @param n u16_t in network byte order + * @return n in host byte order + */ +u16_t +lwip_ntohs(u16_t n) +{ + return lwip_htons(n); +} + +/** + * Convert an u32_t from host- to network byte order. + * + * @param n u32_t in host byte order + * @return n in network byte order + */ +u32_t +lwip_htonl(u32_t n) +{ + return ((n & 0xff) << 24) | + ((n & 0xff00) << 8) | + ((n & 0xff0000UL) >> 8) | + ((n & 0xff000000UL) >> 24); +} + +/** + * Convert an u32_t from network- to host byte order. + * + * @param n u32_t in network byte order + * @return n in host byte order + */ +u32_t +lwip_ntohl(u32_t n) +{ + return lwip_htonl(n); +} + +#endif /* (LWIP_PLATFORM_BYTESWAP == 0) && (BYTE_ORDER == LITTLE_ENDIAN) */ diff --git a/src/lwip-1.4.1/src/core/dhcp.c b/src/lwip-1.4.1/src/core/dhcp.c new file mode 100644 index 0000000..cf864a8 --- /dev/null +++ b/src/lwip-1.4.1/src/core/dhcp.c @@ -0,0 +1,1770 @@ +/** + * @file + * Dynamic Host Configuration Protocol client + * + */ + +/* + * + * Copyright (c) 2001-2004 Leon Woestenberg + * Copyright (c) 2001-2004 Axon Digital Design B.V., The Netherlands. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * This file is a contribution to the lwIP TCP/IP stack. + * The Swedish Institute of Computer Science and Adam Dunkels + * are specifically granted permission to redistribute this + * source code. + * + * Author: Leon Woestenberg + * + * This is a DHCP client for the lwIP TCP/IP stack. It aims to conform + * with RFC 2131 and RFC 2132. + * + * TODO: + * - Support for interfaces other than Ethernet (SLIP, PPP, ...) + * + * Please coordinate changes and requests with Leon Woestenberg + * + * + * Integration with your code: + * + * In lwip/dhcp.h + * #define DHCP_COARSE_TIMER_SECS (recommended 60 which is a minute) + * #define DHCP_FINE_TIMER_MSECS (recommended 500 which equals TCP coarse timer) + * + * Then have your application call dhcp_coarse_tmr() and + * dhcp_fine_tmr() on the defined intervals. + * + * dhcp_start(struct netif *netif); + * starts a DHCP client instance which configures the interface by + * obtaining an IP address lease and maintaining it. + * + * Use dhcp_release(netif) to end the lease and use dhcp_stop(netif) + * to remove the DHCP client. + * + */ + +#include "lwip/opt.h" + +#if LWIP_DHCP /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/stats.h" +#include "lwip/mem.h" +#include "lwip/udp.h" +#include "lwip/ip_addr.h" +#include "lwip/netif.h" +#include "lwip/def.h" +#include "lwip/dhcp.h" +#include "lwip/autoip.h" +#include "lwip/dns.h" +#include "netif/etharp.h" + +#include + +/** DHCP_CREATE_RAND_XID: if this is set to 1, the xid is created using + * LWIP_RAND() (this overrides DHCP_GLOBAL_XID) + */ +#ifndef DHCP_CREATE_RAND_XID +#define DHCP_CREATE_RAND_XID 1 +#endif + +/** Default for DHCP_GLOBAL_XID is 0xABCD0000 + * This can be changed by defining DHCP_GLOBAL_XID and DHCP_GLOBAL_XID_HEADER, e.g. + * #define DHCP_GLOBAL_XID_HEADER "stdlib.h" + * #define DHCP_GLOBAL_XID rand() + */ +#ifdef DHCP_GLOBAL_XID_HEADER +#include DHCP_GLOBAL_XID_HEADER /* include optional starting XID generation prototypes */ +#endif + +/** DHCP_OPTION_MAX_MSG_SIZE is set to the MTU + * MTU is checked to be big enough in dhcp_start */ +#define DHCP_MAX_MSG_LEN(netif) (netif->mtu) +#define DHCP_MAX_MSG_LEN_MIN_REQUIRED 576 +/** Minimum length for reply before packet is parsed */ +#define DHCP_MIN_REPLY_LEN 44 + +#define REBOOT_TRIES 2 + +/** Option handling: options are parsed in dhcp_parse_reply + * and saved in an array where other functions can load them from. + * This might be moved into the struct dhcp (not necessarily since + * lwIP is single-threaded and the array is only used while in recv + * callback). */ +#define DHCP_OPTION_IDX_OVERLOAD 0 +#define DHCP_OPTION_IDX_MSG_TYPE 1 +#define DHCP_OPTION_IDX_SERVER_ID 2 +#define DHCP_OPTION_IDX_LEASE_TIME 3 +#define DHCP_OPTION_IDX_T1 4 +#define DHCP_OPTION_IDX_T2 5 +#define DHCP_OPTION_IDX_SUBNET_MASK 6 +#define DHCP_OPTION_IDX_ROUTER 7 +#define DHCP_OPTION_IDX_DNS_SERVER 8 +#define DHCP_OPTION_IDX_MAX (DHCP_OPTION_IDX_DNS_SERVER + DNS_MAX_SERVERS) + +/** Holds the decoded option values, only valid while in dhcp_recv. + @todo: move this into struct dhcp? */ +u32_t dhcp_rx_options_val[DHCP_OPTION_IDX_MAX]; +/** Holds a flag which option was received and is contained in dhcp_rx_options_val, + only valid while in dhcp_recv. + @todo: move this into struct dhcp? */ +u8_t dhcp_rx_options_given[DHCP_OPTION_IDX_MAX]; + +#ifdef DHCP_GLOBAL_XID +static u32_t xid; +static u8_t xid_initialised; +#endif /* DHCP_GLOBAL_XID */ + +#define dhcp_option_given(dhcp, idx) (dhcp_rx_options_given[idx] != 0) +#define dhcp_got_option(dhcp, idx) (dhcp_rx_options_given[idx] = 1) +#define dhcp_clear_option(dhcp, idx) (dhcp_rx_options_given[idx] = 0) +#define dhcp_clear_all_options(dhcp) (memset(dhcp_rx_options_given, 0, sizeof(dhcp_rx_options_given))) +#define dhcp_get_option_value(dhcp, idx) (dhcp_rx_options_val[idx]) +#define dhcp_set_option_value(dhcp, idx, val) (dhcp_rx_options_val[idx] = (val)) + + +/* DHCP client state machine functions */ +static err_t dhcp_discover(struct netif *netif); +static err_t dhcp_select(struct netif *netif); +static void dhcp_bind(struct netif *netif); +#if DHCP_DOES_ARP_CHECK +static err_t dhcp_decline(struct netif *netif); +#endif /* DHCP_DOES_ARP_CHECK */ +static err_t dhcp_rebind(struct netif *netif); +static err_t dhcp_reboot(struct netif *netif); +static void dhcp_set_state(struct dhcp *dhcp, u8_t new_state); + +/* receive, unfold, parse and free incoming messages */ +static void dhcp_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, ip_addr_t *addr, u16_t port); + +/* set the DHCP timers */ +static void dhcp_timeout(struct netif *netif); +static void dhcp_t1_timeout(struct netif *netif); +static void dhcp_t2_timeout(struct netif *netif); + +/* build outgoing messages */ +/* create a DHCP message, fill in common headers */ +static err_t dhcp_create_msg(struct netif *netif, struct dhcp *dhcp, u8_t message_type); +/* free a DHCP request */ +static void dhcp_delete_msg(struct dhcp *dhcp); +/* add a DHCP option (type, then length in bytes) */ +static void dhcp_option(struct dhcp *dhcp, u8_t option_type, u8_t option_len); +/* add option values */ +static void dhcp_option_byte(struct dhcp *dhcp, u8_t value); +static void dhcp_option_short(struct dhcp *dhcp, u16_t value); +static void dhcp_option_long(struct dhcp *dhcp, u32_t value); +#if LWIP_NETIF_HOSTNAME +static void dhcp_option_hostname(struct dhcp *dhcp, struct netif *netif); +#endif /* LWIP_NETIF_HOSTNAME */ +/* always add the DHCP options trailer to end and pad */ +static void dhcp_option_trailer(struct dhcp *dhcp); + +/** + * Back-off the DHCP client (because of a received NAK response). + * + * Back-off the DHCP client because of a received NAK. Receiving a + * NAK means the client asked for something non-sensible, for + * example when it tries to renew a lease obtained on another network. + * + * We clear any existing set IP address and restart DHCP negotiation + * afresh (as per RFC2131 3.2.3). + * + * @param netif the netif under DHCP control + */ +static void +dhcp_handle_nak(struct netif *netif) +{ + struct dhcp *dhcp = netif->dhcp; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_handle_nak(netif=%p) %c%c%"U16_F"\n", + (void*)netif, netif->name[0], netif->name[1], (u16_t)netif->num)); + /* Set the interface down since the address must no longer be used, as per RFC2131 */ + netif_set_down(netif); + /* remove IP address from interface */ + netif_set_ipaddr(netif, IP_ADDR_ANY); + netif_set_gw(netif, IP_ADDR_ANY); + netif_set_netmask(netif, IP_ADDR_ANY); + /* Change to a defined state */ + dhcp_set_state(dhcp, DHCP_BACKING_OFF); + /* We can immediately restart discovery */ + dhcp_discover(netif); +} + +#if DHCP_DOES_ARP_CHECK +/** + * Checks if the offered IP address is already in use. + * + * It does so by sending an ARP request for the offered address and + * entering CHECKING state. If no ARP reply is received within a small + * interval, the address is assumed to be free for use by us. + * + * @param netif the netif under DHCP control + */ +static void +dhcp_check(struct netif *netif) +{ + struct dhcp *dhcp = netif->dhcp; + err_t result; + u16_t msecs; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_check(netif=%p) %c%c\n", (void *)netif, (s16_t)netif->name[0], + (s16_t)netif->name[1])); + dhcp_set_state(dhcp, DHCP_CHECKING); + /* create an ARP query for the offered IP address, expecting that no host + responds, as the IP address should not be in use. */ + result = etharp_query(netif, &dhcp->offered_ip_addr, NULL); + if (result != ERR_OK) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, ("dhcp_check: could not perform ARP query\n")); + } + dhcp->tries++; + msecs = 500; + dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_check(): set request timeout %"U16_F" msecs\n", msecs)); +} +#endif /* DHCP_DOES_ARP_CHECK */ + +/** + * Remember the configuration offered by a DHCP server. + * + * @param netif the netif under DHCP control + */ +static void +dhcp_handle_offer(struct netif *netif) +{ + struct dhcp *dhcp = netif->dhcp; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_handle_offer(netif=%p) %c%c%"U16_F"\n", + (void*)netif, netif->name[0], netif->name[1], (u16_t)netif->num)); + /* obtain the server address */ + if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_SERVER_ID)) { + ip4_addr_set_u32(&dhcp->server_ip_addr, htonl(dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_SERVER_ID))); + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_STATE, ("dhcp_handle_offer(): server 0x%08"X32_F"\n", + ip4_addr_get_u32(&dhcp->server_ip_addr))); + /* remember offered address */ + ip_addr_copy(dhcp->offered_ip_addr, dhcp->msg_in->yiaddr); + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_STATE, ("dhcp_handle_offer(): offer for 0x%08"X32_F"\n", + ip4_addr_get_u32(&dhcp->offered_ip_addr))); + + dhcp_select(netif); + } else { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, + ("dhcp_handle_offer(netif=%p) did not get server ID!\n", (void*)netif)); + } +} + +/** + * Select a DHCP server offer out of all offers. + * + * Simply select the first offer received. + * + * @param netif the netif under DHCP control + * @return lwIP specific error (see error.h) + */ +static err_t +dhcp_select(struct netif *netif) +{ + struct dhcp *dhcp = netif->dhcp; + err_t result; + u16_t msecs; + + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_select(netif=%p) %c%c%"U16_F"\n", (void*)netif, netif->name[0], netif->name[1], (u16_t)netif->num)); + dhcp_set_state(dhcp, DHCP_REQUESTING); + + /* create and initialize the DHCP message header */ + result = dhcp_create_msg(netif, dhcp, DHCP_REQUEST); + if (result == ERR_OK) { + dhcp_option(dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN); + dhcp_option_short(dhcp, DHCP_MAX_MSG_LEN(netif)); + + /* MUST request the offered IP address */ + dhcp_option(dhcp, DHCP_OPTION_REQUESTED_IP, 4); + dhcp_option_long(dhcp, ntohl(ip4_addr_get_u32(&dhcp->offered_ip_addr))); + + dhcp_option(dhcp, DHCP_OPTION_SERVER_ID, 4); + dhcp_option_long(dhcp, ntohl(ip4_addr_get_u32(&dhcp->server_ip_addr))); + + dhcp_option(dhcp, DHCP_OPTION_PARAMETER_REQUEST_LIST, 4/*num options*/); + dhcp_option_byte(dhcp, DHCP_OPTION_SUBNET_MASK); + dhcp_option_byte(dhcp, DHCP_OPTION_ROUTER); + dhcp_option_byte(dhcp, DHCP_OPTION_BROADCAST); + dhcp_option_byte(dhcp, DHCP_OPTION_DNS_SERVER); + +#if LWIP_NETIF_HOSTNAME + dhcp_option_hostname(dhcp, netif); +#endif /* LWIP_NETIF_HOSTNAME */ + + dhcp_option_trailer(dhcp); + /* shrink the pbuf to the actual content length */ + pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len); + + /* send broadcast to any DHCP server */ + udp_sendto_if(dhcp->pcb, dhcp->p_out, IP_ADDR_BROADCAST, DHCP_SERVER_PORT, netif); + dhcp_delete_msg(dhcp); + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_select: REQUESTING\n")); + } else { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, ("dhcp_select: could not allocate DHCP request\n")); + } + dhcp->tries++; + msecs = (dhcp->tries < 6 ? 1 << dhcp->tries : 60) * 1000; + dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_STATE, ("dhcp_select(): set request timeout %"U16_F" msecs\n", msecs)); + return result; +} + +/** + * The DHCP timer that checks for lease renewal/rebind timeouts. + */ +void +dhcp_coarse_tmr() +{ + struct netif *netif = netif_list; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_coarse_tmr()\n")); + /* iterate through all network interfaces */ + while (netif != NULL) { + /* only act on DHCP configured interfaces */ + if (netif->dhcp != NULL) { + /* timer is active (non zero), and triggers (zeroes) now? */ + if (netif->dhcp->t2_timeout-- == 1) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_coarse_tmr(): t2 timeout\n")); + /* this clients' rebind timeout triggered */ + dhcp_t2_timeout(netif); + /* timer is active (non zero), and triggers (zeroes) now */ + } else if (netif->dhcp->t1_timeout-- == 1) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_coarse_tmr(): t1 timeout\n")); + /* this clients' renewal timeout triggered */ + dhcp_t1_timeout(netif); + } + } + /* proceed to next netif */ + netif = netif->next; + } +} + +/** + * DHCP transaction timeout handling + * + * A DHCP server is expected to respond within a short period of time. + * This timer checks whether an outstanding DHCP request is timed out. + */ +void +dhcp_fine_tmr() +{ + struct netif *netif = netif_list; + /* loop through netif's */ + while (netif != NULL) { + /* only act on DHCP configured interfaces */ + if (netif->dhcp != NULL) { + /* timer is active (non zero), and is about to trigger now */ + if (netif->dhcp->request_timeout > 1) { + netif->dhcp->request_timeout--; + } + else if (netif->dhcp->request_timeout == 1) { + netif->dhcp->request_timeout--; + /* { netif->dhcp->request_timeout == 0 } */ + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_fine_tmr(): request timeout\n")); + /* this client's request timeout triggered */ + dhcp_timeout(netif); + } + } + /* proceed to next network interface */ + netif = netif->next; + } +} + +/** + * A DHCP negotiation transaction, or ARP request, has timed out. + * + * The timer that was started with the DHCP or ARP request has + * timed out, indicating no response was received in time. + * + * @param netif the netif under DHCP control + */ +static void +dhcp_timeout(struct netif *netif) +{ + struct dhcp *dhcp = netif->dhcp; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_timeout()\n")); + /* back-off period has passed, or server selection timed out */ + if ((dhcp->state == DHCP_BACKING_OFF) || (dhcp->state == DHCP_SELECTING)) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_timeout(): restarting discovery\n")); + dhcp_discover(netif); + /* receiving the requested lease timed out */ + } else if (dhcp->state == DHCP_REQUESTING) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_timeout(): REQUESTING, DHCP request timed out\n")); + if (dhcp->tries <= 5) { + dhcp_select(netif); + } else { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_timeout(): REQUESTING, releasing, restarting\n")); + dhcp_release(netif); + dhcp_discover(netif); + } +#if DHCP_DOES_ARP_CHECK + /* received no ARP reply for the offered address (which is good) */ + } else if (dhcp->state == DHCP_CHECKING) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_timeout(): CHECKING, ARP request timed out\n")); + if (dhcp->tries <= 1) { + dhcp_check(netif); + /* no ARP replies on the offered address, + looks like the IP address is indeed free */ + } else { + /* bind the interface to the offered address */ + dhcp_bind(netif); + } +#endif /* DHCP_DOES_ARP_CHECK */ + } + /* did not get response to renew request? */ + else if (dhcp->state == DHCP_RENEWING) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_timeout(): RENEWING, DHCP request timed out\n")); + /* just retry renewal */ + /* note that the rebind timer will eventually time-out if renew does not work */ + dhcp_renew(netif); + /* did not get response to rebind request? */ + } else if (dhcp->state == DHCP_REBINDING) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_timeout(): REBINDING, DHCP request timed out\n")); + if (dhcp->tries <= 8) { + dhcp_rebind(netif); + } else { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_timeout(): RELEASING, DISCOVERING\n")); + dhcp_release(netif); + dhcp_discover(netif); + } + } else if (dhcp->state == DHCP_REBOOTING) { + if (dhcp->tries < REBOOT_TRIES) { + dhcp_reboot(netif); + } else { + dhcp_discover(netif); + } + } +} + +/** + * The renewal period has timed out. + * + * @param netif the netif under DHCP control + */ +static void +dhcp_t1_timeout(struct netif *netif) +{ + struct dhcp *dhcp = netif->dhcp; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_STATE, ("dhcp_t1_timeout()\n")); + if ((dhcp->state == DHCP_REQUESTING) || (dhcp->state == DHCP_BOUND) || + (dhcp->state == DHCP_RENEWING)) { + /* just retry to renew - note that the rebind timer (t2) will + * eventually time-out if renew tries fail. */ + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, + ("dhcp_t1_timeout(): must renew\n")); + /* This slightly different to RFC2131: DHCPREQUEST will be sent from state + DHCP_RENEWING, not DHCP_BOUND */ + dhcp_renew(netif); + } +} + +/** + * The rebind period has timed out. + * + * @param netif the netif under DHCP control + */ +static void +dhcp_t2_timeout(struct netif *netif) +{ + struct dhcp *dhcp = netif->dhcp; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_t2_timeout()\n")); + if ((dhcp->state == DHCP_REQUESTING) || (dhcp->state == DHCP_BOUND) || + (dhcp->state == DHCP_RENEWING)) { + /* just retry to rebind */ + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, + ("dhcp_t2_timeout(): must rebind\n")); + /* This slightly different to RFC2131: DHCPREQUEST will be sent from state + DHCP_REBINDING, not DHCP_BOUND */ + dhcp_rebind(netif); + } +} + +/** + * Handle a DHCP ACK packet + * + * @param netif the netif under DHCP control + */ +static void +dhcp_handle_ack(struct netif *netif) +{ + struct dhcp *dhcp = netif->dhcp; +#if LWIP_DNS + u8_t n; +#endif /* LWIP_DNS */ + + /* clear options we might not get from the ACK */ + ip_addr_set_zero(&dhcp->offered_sn_mask); + ip_addr_set_zero(&dhcp->offered_gw_addr); +#if LWIP_DHCP_BOOTP_FILE + ip_addr_set_zero(&dhcp->offered_si_addr); +#endif /* LWIP_DHCP_BOOTP_FILE */ + + /* lease time given? */ + if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_LEASE_TIME)) { + /* remember offered lease time */ + dhcp->offered_t0_lease = dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_LEASE_TIME); + } + /* renewal period given? */ + if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_T1)) { + /* remember given renewal period */ + dhcp->offered_t1_renew = dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_T1); + } else { + /* calculate safe periods for renewal */ + dhcp->offered_t1_renew = dhcp->offered_t0_lease / 2; + } + + /* renewal period given? */ + if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_T2)) { + /* remember given rebind period */ + dhcp->offered_t2_rebind = dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_T2); + } else { + /* calculate safe periods for rebinding */ + dhcp->offered_t2_rebind = dhcp->offered_t0_lease; + } + + /* (y)our internet address */ + ip_addr_copy(dhcp->offered_ip_addr, dhcp->msg_in->yiaddr); + +#if LWIP_DHCP_BOOTP_FILE + /* copy boot server address, + boot file name copied in dhcp_parse_reply if not overloaded */ + ip_addr_copy(dhcp->offered_si_addr, dhcp->msg_in->siaddr); +#endif /* LWIP_DHCP_BOOTP_FILE */ + + /* subnet mask given? */ + if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_SUBNET_MASK)) { + /* remember given subnet mask */ + ip4_addr_set_u32(&dhcp->offered_sn_mask, htonl(dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_SUBNET_MASK))); + dhcp->subnet_mask_given = 1; + } else { + dhcp->subnet_mask_given = 0; + } + + /* gateway router */ + if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_ROUTER)) { + ip4_addr_set_u32(&dhcp->offered_gw_addr, htonl(dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_ROUTER))); + } + +#if LWIP_DNS + /* DNS servers */ + n = 0; + while(dhcp_option_given(dhcp, DHCP_OPTION_IDX_DNS_SERVER + n) && (n < DNS_MAX_SERVERS)) { + ip_addr_t dns_addr; + ip4_addr_set_u32(&dns_addr, htonl(dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_DNS_SERVER + n))); + dns_setserver(n, &dns_addr); + n++; + } +#endif /* LWIP_DNS */ +} + +/** Set a statically allocated struct dhcp to work with. + * Using this prevents dhcp_start to allocate it using mem_malloc. + * + * @param netif the netif for which to set the struct dhcp + * @param dhcp (uninitialised) dhcp struct allocated by the application + */ +void +dhcp_set_struct(struct netif *netif, struct dhcp *dhcp) +{ + LWIP_ASSERT("netif != NULL", netif != NULL); + LWIP_ASSERT("dhcp != NULL", dhcp != NULL); + LWIP_ASSERT("netif already has a struct dhcp set", netif->dhcp == NULL); + + /* clear data structure */ + memset(dhcp, 0, sizeof(struct dhcp)); + /* dhcp_set_state(&dhcp, DHCP_OFF); */ + netif->dhcp = dhcp; +} + +/** Removes a struct dhcp from a netif. + * + * ATTENTION: Only use this when not using dhcp_set_struct() to allocate the + * struct dhcp since the memory is passed back to the heap. + * + * @param netif the netif from which to remove the struct dhcp + */ +void dhcp_cleanup(struct netif *netif) +{ + LWIP_ASSERT("netif != NULL", netif != NULL); + + if (netif->dhcp != NULL) { + mem_free(netif->dhcp); + netif->dhcp = NULL; + } +} + +/** + * Start DHCP negotiation for a network interface. + * + * If no DHCP client instance was attached to this interface, + * a new client is created first. If a DHCP client instance + * was already present, it restarts negotiation. + * + * @param netif The lwIP network interface + * @return lwIP error code + * - ERR_OK - No error + * - ERR_MEM - Out of memory + */ +err_t +dhcp_start(struct netif *netif) +{ + struct dhcp *dhcp; + err_t result = ERR_OK; + + LWIP_ERROR("netif != NULL", (netif != NULL), return ERR_ARG;); + dhcp = netif->dhcp; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_start(netif=%p) %c%c%"U16_F"\n", (void*)netif, netif->name[0], netif->name[1], (u16_t)netif->num)); + /* Remove the flag that says this netif is handled by DHCP, + it is set when we succeeded starting. */ + netif->flags &= ~NETIF_FLAG_DHCP; + + /* check hwtype of the netif */ + if ((netif->flags & NETIF_FLAG_ETHARP) == 0) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_start(): No ETHARP netif\n")); + return ERR_ARG; + } + + /* check MTU of the netif */ + if (netif->mtu < DHCP_MAX_MSG_LEN_MIN_REQUIRED) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_start(): Cannot use this netif with DHCP: MTU is too small\n")); + return ERR_MEM; + } + + /* no DHCP client attached yet? */ + if (dhcp == NULL) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_start(): starting new DHCP client\n")); + dhcp = (struct dhcp *)mem_malloc(sizeof(struct dhcp)); + if (dhcp == NULL) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_start(): could not allocate dhcp\n")); + return ERR_MEM; + } + /* store this dhcp client in the netif */ + netif->dhcp = dhcp; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_start(): allocated dhcp")); + /* already has DHCP client attached */ + } else { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_start(): restarting DHCP configuration\n")); + if (dhcp->pcb != NULL) { + udp_remove(dhcp->pcb); + } + LWIP_ASSERT("pbuf p_out wasn't freed", dhcp->p_out == NULL); + LWIP_ASSERT("reply wasn't freed", dhcp->msg_in == NULL ); + } + + /* clear data structure */ + memset(dhcp, 0, sizeof(struct dhcp)); + /* dhcp_set_state(&dhcp, DHCP_OFF); */ + /* allocate UDP PCB */ + dhcp->pcb = udp_new(); + if (dhcp->pcb == NULL) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_start(): could not obtain pcb\n")); + return ERR_MEM; + } + ip_set_option(dhcp->pcb, SOF_BROADCAST); + /* set up local and remote port for the pcb */ + udp_bind(dhcp->pcb, IP_ADDR_ANY, DHCP_CLIENT_PORT); + udp_connect(dhcp->pcb, IP_ADDR_ANY, DHCP_SERVER_PORT); + /* set up the recv callback and argument */ + udp_recv(dhcp->pcb, dhcp_recv, netif); + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_start(): starting DHCP configuration\n")); + /* (re)start the DHCP negotiation */ + result = dhcp_discover(netif); + if (result != ERR_OK) { + /* free resources allocated above */ + dhcp_stop(netif); + return ERR_MEM; + } + /* Set the flag that says this netif is handled by DHCP. */ + netif->flags |= NETIF_FLAG_DHCP; + return result; +} + +/** + * Inform a DHCP server of our manual configuration. + * + * This informs DHCP servers of our fixed IP address configuration + * by sending an INFORM message. It does not involve DHCP address + * configuration, it is just here to be nice to the network. + * + * @param netif The lwIP network interface + */ +void +dhcp_inform(struct netif *netif) +{ + struct dhcp dhcp; + err_t result = ERR_OK; + struct udp_pcb *pcb; + + LWIP_ERROR("netif != NULL", (netif != NULL), return;); + + memset(&dhcp, 0, sizeof(struct dhcp)); + dhcp_set_state(&dhcp, DHCP_INFORM); + + if ((netif->dhcp != NULL) && (netif->dhcp->pcb != NULL)) { + /* re-use existing pcb */ + pcb = netif->dhcp->pcb; + } else { + pcb = udp_new(); + if (pcb == NULL) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("dhcp_inform(): could not obtain pcb")); + return; + } + dhcp.pcb = pcb; + ip_set_option(dhcp.pcb, SOF_BROADCAST); + udp_bind(dhcp.pcb, IP_ADDR_ANY, DHCP_CLIENT_PORT); + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_inform(): created new udp pcb\n")); + } + /* create and initialize the DHCP message header */ + result = dhcp_create_msg(netif, &dhcp, DHCP_INFORM); + if (result == ERR_OK) { + dhcp_option(&dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN); + dhcp_option_short(&dhcp, DHCP_MAX_MSG_LEN(netif)); + + dhcp_option_trailer(&dhcp); + + pbuf_realloc(dhcp.p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp.options_out_len); + + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_inform: INFORMING\n")); + udp_sendto_if(pcb, dhcp.p_out, IP_ADDR_BROADCAST, DHCP_SERVER_PORT, netif); + dhcp_delete_msg(&dhcp); + } else { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("dhcp_inform: could not allocate DHCP request\n")); + } + + if (dhcp.pcb != NULL) { + /* otherwise, the existing pcb was used */ + udp_remove(dhcp.pcb); + } +} + +/** Handle a possible change in the network configuration. + * + * This enters the REBOOTING state to verify that the currently bound + * address is still valid. + */ +void +dhcp_network_changed(struct netif *netif) +{ + struct dhcp *dhcp = netif->dhcp; + if (!dhcp) + return; + switch (dhcp->state) { + case DHCP_REBINDING: + case DHCP_RENEWING: + case DHCP_BOUND: + case DHCP_REBOOTING: + netif_set_down(netif); + dhcp->tries = 0; + dhcp_reboot(netif); + break; + case DHCP_OFF: + /* stay off */ + break; + default: + dhcp->tries = 0; +#if LWIP_DHCP_AUTOIP_COOP + if(dhcp->autoip_coop_state == DHCP_AUTOIP_COOP_STATE_ON) { + autoip_stop(netif); + dhcp->autoip_coop_state = DHCP_AUTOIP_COOP_STATE_OFF; + } +#endif /* LWIP_DHCP_AUTOIP_COOP */ + dhcp_discover(netif); + break; + } +} + +#if DHCP_DOES_ARP_CHECK +/** + * Match an ARP reply with the offered IP address. + * + * @param netif the network interface on which the reply was received + * @param addr The IP address we received a reply from + */ +void dhcp_arp_reply(struct netif *netif, ip_addr_t *addr) +{ + LWIP_ERROR("netif != NULL", (netif != NULL), return;); + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_arp_reply()\n")); + /* is a DHCP client doing an ARP check? */ + if ((netif->dhcp != NULL) && (netif->dhcp->state == DHCP_CHECKING)) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_arp_reply(): CHECKING, arp reply for 0x%08"X32_F"\n", + ip4_addr_get_u32(addr))); + /* did a host respond with the address we + were offered by the DHCP server? */ + if (ip_addr_cmp(addr, &netif->dhcp->offered_ip_addr)) { + /* we will not accept the offered address */ + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE | LWIP_DBG_LEVEL_WARNING, + ("dhcp_arp_reply(): arp reply matched with offered address, declining\n")); + dhcp_decline(netif); + } + } +} + +/** + * Decline an offered lease. + * + * Tell the DHCP server we do not accept the offered address. + * One reason to decline the lease is when we find out the address + * is already in use by another host (through ARP). + * + * @param netif the netif under DHCP control + */ +static err_t +dhcp_decline(struct netif *netif) +{ + struct dhcp *dhcp = netif->dhcp; + err_t result = ERR_OK; + u16_t msecs; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_decline()\n")); + dhcp_set_state(dhcp, DHCP_BACKING_OFF); + /* create and initialize the DHCP message header */ + result = dhcp_create_msg(netif, dhcp, DHCP_DECLINE); + if (result == ERR_OK) { + dhcp_option(dhcp, DHCP_OPTION_REQUESTED_IP, 4); + dhcp_option_long(dhcp, ntohl(ip4_addr_get_u32(&dhcp->offered_ip_addr))); + + dhcp_option_trailer(dhcp); + /* resize pbuf to reflect true size of options */ + pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len); + + /* per section 4.4.4, broadcast DECLINE messages */ + udp_sendto_if(dhcp->pcb, dhcp->p_out, IP_ADDR_BROADCAST, DHCP_SERVER_PORT, netif); + dhcp_delete_msg(dhcp); + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_decline: BACKING OFF\n")); + } else { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, + ("dhcp_decline: could not allocate DHCP request\n")); + } + dhcp->tries++; + msecs = 10*1000; + dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_decline(): set request timeout %"U16_F" msecs\n", msecs)); + return result; +} +#endif /* DHCP_DOES_ARP_CHECK */ + + +/** + * Start the DHCP process, discover a DHCP server. + * + * @param netif the netif under DHCP control + */ +static err_t +dhcp_discover(struct netif *netif) +{ + struct dhcp *dhcp = netif->dhcp; + err_t result = ERR_OK; + u16_t msecs; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_discover()\n")); + ip_addr_set_any(&dhcp->offered_ip_addr); + dhcp_set_state(dhcp, DHCP_SELECTING); + /* create and initialize the DHCP message header */ + result = dhcp_create_msg(netif, dhcp, DHCP_DISCOVER); + if (result == ERR_OK) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_discover: making request\n")); + + dhcp_option(dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN); + dhcp_option_short(dhcp, DHCP_MAX_MSG_LEN(netif)); + + dhcp_option(dhcp, DHCP_OPTION_PARAMETER_REQUEST_LIST, 4/*num options*/); + dhcp_option_byte(dhcp, DHCP_OPTION_SUBNET_MASK); + dhcp_option_byte(dhcp, DHCP_OPTION_ROUTER); + dhcp_option_byte(dhcp, DHCP_OPTION_BROADCAST); + dhcp_option_byte(dhcp, DHCP_OPTION_DNS_SERVER); + + dhcp_option_trailer(dhcp); + + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_discover: realloc()ing\n")); + pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len); + + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_discover: sendto(DISCOVER, IP_ADDR_BROADCAST, DHCP_SERVER_PORT)\n")); + udp_sendto_if(dhcp->pcb, dhcp->p_out, IP_ADDR_BROADCAST, DHCP_SERVER_PORT, netif); + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_discover: deleting()ing\n")); + dhcp_delete_msg(dhcp); + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_discover: SELECTING\n")); + } else { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("dhcp_discover: could not allocate DHCP request\n")); + } + dhcp->tries++; +#if LWIP_DHCP_AUTOIP_COOP + if(dhcp->tries >= LWIP_DHCP_AUTOIP_COOP_TRIES && dhcp->autoip_coop_state == DHCP_AUTOIP_COOP_STATE_OFF) { + dhcp->autoip_coop_state = DHCP_AUTOIP_COOP_STATE_ON; + autoip_start(netif); + } +#endif /* LWIP_DHCP_AUTOIP_COOP */ + msecs = (dhcp->tries < 6 ? 1 << dhcp->tries : 60) * 1000; + dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_discover(): set request timeout %"U16_F" msecs\n", msecs)); + return result; +} + + +/** + * Bind the interface to the offered IP address. + * + * @param netif network interface to bind to the offered address + */ +static void +dhcp_bind(struct netif *netif) +{ + u32_t timeout; + struct dhcp *dhcp; + ip_addr_t sn_mask, gw_addr; + LWIP_ERROR("dhcp_bind: netif != NULL", (netif != NULL), return;); + dhcp = netif->dhcp; + LWIP_ERROR("dhcp_bind: dhcp != NULL", (dhcp != NULL), return;); + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_bind(netif=%p) %c%c%"U16_F"\n", (void*)netif, netif->name[0], netif->name[1], (u16_t)netif->num)); + + /* temporary DHCP lease? */ + if (dhcp->offered_t1_renew != 0xffffffffUL) { + /* set renewal period timer */ + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_bind(): t1 renewal timer %"U32_F" secs\n", dhcp->offered_t1_renew)); + timeout = (dhcp->offered_t1_renew + DHCP_COARSE_TIMER_SECS / 2) / DHCP_COARSE_TIMER_SECS; + if(timeout > 0xffff) { + timeout = 0xffff; + } + dhcp->t1_timeout = (u16_t)timeout; + if (dhcp->t1_timeout == 0) { + dhcp->t1_timeout = 1; + } + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_bind(): set request timeout %"U32_F" msecs\n", dhcp->offered_t1_renew*1000)); + } + /* set renewal period timer */ + if (dhcp->offered_t2_rebind != 0xffffffffUL) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_bind(): t2 rebind timer %"U32_F" secs\n", dhcp->offered_t2_rebind)); + timeout = (dhcp->offered_t2_rebind + DHCP_COARSE_TIMER_SECS / 2) / DHCP_COARSE_TIMER_SECS; + if(timeout > 0xffff) { + timeout = 0xffff; + } + dhcp->t2_timeout = (u16_t)timeout; + if (dhcp->t2_timeout == 0) { + dhcp->t2_timeout = 1; + } + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_bind(): set request timeout %"U32_F" msecs\n", dhcp->offered_t2_rebind*1000)); + } + + /* If we have sub 1 minute lease, t2 and t1 will kick in at the same time. */ + if ((dhcp->t1_timeout >= dhcp->t2_timeout) && (dhcp->t2_timeout > 0)) { + dhcp->t1_timeout = 0; + } + + if (dhcp->subnet_mask_given) { + /* copy offered network mask */ + ip_addr_copy(sn_mask, dhcp->offered_sn_mask); + } else { + /* subnet mask not given, choose a safe subnet mask given the network class */ + u8_t first_octet = ip4_addr1(&dhcp->offered_ip_addr); + if (first_octet <= 127) { + ip4_addr_set_u32(&sn_mask, PP_HTONL(0xff000000UL)); + } else if (first_octet >= 192) { + ip4_addr_set_u32(&sn_mask, PP_HTONL(0xffffff00UL)); + } else { + ip4_addr_set_u32(&sn_mask, PP_HTONL(0xffff0000UL)); + } + } + + ip_addr_copy(gw_addr, dhcp->offered_gw_addr); + /* gateway address not given? */ + if (ip_addr_isany(&gw_addr)) { + /* copy network address */ + ip_addr_get_network(&gw_addr, &dhcp->offered_ip_addr, &sn_mask); + /* use first host address on network as gateway */ + ip4_addr_set_u32(&gw_addr, ip4_addr_get_u32(&gw_addr) | PP_HTONL(0x00000001UL)); + } + +#if LWIP_DHCP_AUTOIP_COOP + if(dhcp->autoip_coop_state == DHCP_AUTOIP_COOP_STATE_ON) { + autoip_stop(netif); + dhcp->autoip_coop_state = DHCP_AUTOIP_COOP_STATE_OFF; + } +#endif /* LWIP_DHCP_AUTOIP_COOP */ + + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_STATE, ("dhcp_bind(): IP: 0x%08"X32_F"\n", + ip4_addr_get_u32(&dhcp->offered_ip_addr))); + netif_set_ipaddr(netif, &dhcp->offered_ip_addr); + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_STATE, ("dhcp_bind(): SN: 0x%08"X32_F"\n", + ip4_addr_get_u32(&sn_mask))); + netif_set_netmask(netif, &sn_mask); + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_STATE, ("dhcp_bind(): GW: 0x%08"X32_F"\n", + ip4_addr_get_u32(&gw_addr))); + netif_set_gw(netif, &gw_addr); + /* bring the interface up */ + netif_set_up(netif); + /* netif is now bound to DHCP leased address */ + dhcp_set_state(dhcp, DHCP_BOUND); +} + +/** + * Renew an existing DHCP lease at the involved DHCP server. + * + * @param netif network interface which must renew its lease + */ +err_t +dhcp_renew(struct netif *netif) +{ + struct dhcp *dhcp = netif->dhcp; + err_t result; + u16_t msecs; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_renew()\n")); + dhcp_set_state(dhcp, DHCP_RENEWING); + + /* create and initialize the DHCP message header */ + result = dhcp_create_msg(netif, dhcp, DHCP_REQUEST); + if (result == ERR_OK) { + dhcp_option(dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN); + dhcp_option_short(dhcp, DHCP_MAX_MSG_LEN(netif)); + +#if 0 + dhcp_option(dhcp, DHCP_OPTION_REQUESTED_IP, 4); + dhcp_option_long(dhcp, ntohl(dhcp->offered_ip_addr.addr)); +#endif + +#if 0 + dhcp_option(dhcp, DHCP_OPTION_SERVER_ID, 4); + dhcp_option_long(dhcp, ntohl(dhcp->server_ip_addr.addr)); +#endif + +#if LWIP_NETIF_HOSTNAME + dhcp_option_hostname(dhcp, netif); +#endif /* LWIP_NETIF_HOSTNAME */ + + /* append DHCP message trailer */ + dhcp_option_trailer(dhcp); + + pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len); + + udp_sendto_if(dhcp->pcb, dhcp->p_out, &dhcp->server_ip_addr, DHCP_SERVER_PORT, netif); + dhcp_delete_msg(dhcp); + + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_renew: RENEWING\n")); + } else { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("dhcp_renew: could not allocate DHCP request\n")); + } + dhcp->tries++; + /* back-off on retries, but to a maximum of 20 seconds */ + msecs = dhcp->tries < 10 ? dhcp->tries * 2000 : 20 * 1000; + dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_renew(): set request timeout %"U16_F" msecs\n", msecs)); + return result; +} + +/** + * Rebind with a DHCP server for an existing DHCP lease. + * + * @param netif network interface which must rebind with a DHCP server + */ +static err_t +dhcp_rebind(struct netif *netif) +{ + struct dhcp *dhcp = netif->dhcp; + err_t result; + u16_t msecs; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_rebind()\n")); + dhcp_set_state(dhcp, DHCP_REBINDING); + + /* create and initialize the DHCP message header */ + result = dhcp_create_msg(netif, dhcp, DHCP_REQUEST); + if (result == ERR_OK) { + dhcp_option(dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN); + dhcp_option_short(dhcp, DHCP_MAX_MSG_LEN(netif)); + +#if LWIP_NETIF_HOSTNAME + dhcp_option_hostname(dhcp, netif); +#endif /* LWIP_NETIF_HOSTNAME */ + +#if 0 + dhcp_option(dhcp, DHCP_OPTION_REQUESTED_IP, 4); + dhcp_option_long(dhcp, ntohl(dhcp->offered_ip_addr.addr)); + + dhcp_option(dhcp, DHCP_OPTION_SERVER_ID, 4); + dhcp_option_long(dhcp, ntohl(dhcp->server_ip_addr.addr)); +#endif + + dhcp_option_trailer(dhcp); + + pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len); + + /* broadcast to server */ + udp_sendto_if(dhcp->pcb, dhcp->p_out, IP_ADDR_BROADCAST, DHCP_SERVER_PORT, netif); + dhcp_delete_msg(dhcp); + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_rebind: REBINDING\n")); + } else { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("dhcp_rebind: could not allocate DHCP request\n")); + } + dhcp->tries++; + msecs = dhcp->tries < 10 ? dhcp->tries * 1000 : 10 * 1000; + dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_rebind(): set request timeout %"U16_F" msecs\n", msecs)); + return result; +} + +/** + * Enter REBOOTING state to verify an existing lease + * + * @param netif network interface which must reboot + */ +static err_t +dhcp_reboot(struct netif *netif) +{ + struct dhcp *dhcp = netif->dhcp; + err_t result; + u16_t msecs; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_reboot()\n")); + dhcp_set_state(dhcp, DHCP_REBOOTING); + + /* create and initialize the DHCP message header */ + result = dhcp_create_msg(netif, dhcp, DHCP_REQUEST); + if (result == ERR_OK) { + dhcp_option(dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN); + dhcp_option_short(dhcp, 576); + + dhcp_option(dhcp, DHCP_OPTION_REQUESTED_IP, 4); + dhcp_option_long(dhcp, ntohl(ip4_addr_get_u32(&dhcp->offered_ip_addr))); + + dhcp_option_trailer(dhcp); + + pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len); + + /* broadcast to server */ + udp_sendto_if(dhcp->pcb, dhcp->p_out, IP_ADDR_BROADCAST, DHCP_SERVER_PORT, netif); + dhcp_delete_msg(dhcp); + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_reboot: REBOOTING\n")); + } else { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("dhcp_reboot: could not allocate DHCP request\n")); + } + dhcp->tries++; + msecs = dhcp->tries < 10 ? dhcp->tries * 1000 : 10 * 1000; + dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_reboot(): set request timeout %"U16_F" msecs\n", msecs)); + return result; +} + + +/** + * Release a DHCP lease. + * + * @param netif network interface which must release its lease + */ +err_t +dhcp_release(struct netif *netif) +{ + struct dhcp *dhcp = netif->dhcp; + err_t result; + u16_t msecs; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_release()\n")); + + /* idle DHCP client */ + dhcp_set_state(dhcp, DHCP_OFF); + /* clean old DHCP offer */ + ip_addr_set_zero(&dhcp->server_ip_addr); + ip_addr_set_zero(&dhcp->offered_ip_addr); + ip_addr_set_zero(&dhcp->offered_sn_mask); + ip_addr_set_zero(&dhcp->offered_gw_addr); +#if LWIP_DHCP_BOOTP_FILE + ip_addr_set_zero(&dhcp->offered_si_addr); +#endif /* LWIP_DHCP_BOOTP_FILE */ + dhcp->offered_t0_lease = dhcp->offered_t1_renew = dhcp->offered_t2_rebind = 0; + + /* create and initialize the DHCP message header */ + result = dhcp_create_msg(netif, dhcp, DHCP_RELEASE); + if (result == ERR_OK) { + dhcp_option_trailer(dhcp); + + pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len); + + udp_sendto_if(dhcp->pcb, dhcp->p_out, &dhcp->server_ip_addr, DHCP_SERVER_PORT, netif); + dhcp_delete_msg(dhcp); + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_release: RELEASED, DHCP_OFF\n")); + } else { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("dhcp_release: could not allocate DHCP request\n")); + } + dhcp->tries++; + msecs = dhcp->tries < 10 ? dhcp->tries * 1000 : 10 * 1000; + dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_release(): set request timeout %"U16_F" msecs\n", msecs)); + /* bring the interface down */ + netif_set_down(netif); + /* remove IP address from interface */ + netif_set_ipaddr(netif, IP_ADDR_ANY); + netif_set_gw(netif, IP_ADDR_ANY); + netif_set_netmask(netif, IP_ADDR_ANY); + + return result; +} + +/** + * Remove the DHCP client from the interface. + * + * @param netif The network interface to stop DHCP on + */ +void +dhcp_stop(struct netif *netif) +{ + struct dhcp *dhcp; + LWIP_ERROR("dhcp_stop: netif != NULL", (netif != NULL), return;); + dhcp = netif->dhcp; + /* Remove the flag that says this netif is handled by DHCP. */ + netif->flags &= ~NETIF_FLAG_DHCP; + + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_stop()\n")); + /* netif is DHCP configured? */ + if (dhcp != NULL) { +#if LWIP_DHCP_AUTOIP_COOP + if(dhcp->autoip_coop_state == DHCP_AUTOIP_COOP_STATE_ON) { + autoip_stop(netif); + dhcp->autoip_coop_state = DHCP_AUTOIP_COOP_STATE_OFF; + } +#endif /* LWIP_DHCP_AUTOIP_COOP */ + + if (dhcp->pcb != NULL) { + udp_remove(dhcp->pcb); + dhcp->pcb = NULL; + } + LWIP_ASSERT("reply wasn't freed", dhcp->msg_in == NULL); + dhcp_set_state(dhcp, DHCP_OFF); + } +} + +/* + * Set the DHCP state of a DHCP client. + * + * If the state changed, reset the number of tries. + */ +static void +dhcp_set_state(struct dhcp *dhcp, u8_t new_state) +{ + if (new_state != dhcp->state) { + dhcp->state = new_state; + dhcp->tries = 0; + dhcp->request_timeout = 0; + } +} + +/* + * Concatenate an option type and length field to the outgoing + * DHCP message. + * + */ +static void +dhcp_option(struct dhcp *dhcp, u8_t option_type, u8_t option_len) +{ + LWIP_ASSERT("dhcp_option: dhcp->options_out_len + 2 + option_len <= DHCP_OPTIONS_LEN", dhcp->options_out_len + 2U + option_len <= DHCP_OPTIONS_LEN); + dhcp->msg_out->options[dhcp->options_out_len++] = option_type; + dhcp->msg_out->options[dhcp->options_out_len++] = option_len; +} +/* + * Concatenate a single byte to the outgoing DHCP message. + * + */ +static void +dhcp_option_byte(struct dhcp *dhcp, u8_t value) +{ + LWIP_ASSERT("dhcp_option_byte: dhcp->options_out_len < DHCP_OPTIONS_LEN", dhcp->options_out_len < DHCP_OPTIONS_LEN); + dhcp->msg_out->options[dhcp->options_out_len++] = value; +} + +static void +dhcp_option_short(struct dhcp *dhcp, u16_t value) +{ + LWIP_ASSERT("dhcp_option_short: dhcp->options_out_len + 2 <= DHCP_OPTIONS_LEN", dhcp->options_out_len + 2U <= DHCP_OPTIONS_LEN); + dhcp->msg_out->options[dhcp->options_out_len++] = (u8_t)((value & 0xff00U) >> 8); + dhcp->msg_out->options[dhcp->options_out_len++] = (u8_t) (value & 0x00ffU); +} + +static void +dhcp_option_long(struct dhcp *dhcp, u32_t value) +{ + LWIP_ASSERT("dhcp_option_long: dhcp->options_out_len + 4 <= DHCP_OPTIONS_LEN", dhcp->options_out_len + 4U <= DHCP_OPTIONS_LEN); + dhcp->msg_out->options[dhcp->options_out_len++] = (u8_t)((value & 0xff000000UL) >> 24); + dhcp->msg_out->options[dhcp->options_out_len++] = (u8_t)((value & 0x00ff0000UL) >> 16); + dhcp->msg_out->options[dhcp->options_out_len++] = (u8_t)((value & 0x0000ff00UL) >> 8); + dhcp->msg_out->options[dhcp->options_out_len++] = (u8_t)((value & 0x000000ffUL)); +} + +#if LWIP_NETIF_HOSTNAME +static void +dhcp_option_hostname(struct dhcp *dhcp, struct netif *netif) +{ + if (netif->hostname != NULL) { + size_t namelen = strlen(netif->hostname); + if (namelen > 0) { + u8_t len; + const char *p = netif->hostname; + /* Shrink len to available bytes (need 2 bytes for OPTION_HOSTNAME + and 1 byte for trailer) */ + size_t available = DHCP_OPTIONS_LEN - dhcp->options_out_len - 3; + LWIP_ASSERT("DHCP: hostname is too long!", namelen <= available); + len = LWIP_MIN(namelen, available); + dhcp_option(dhcp, DHCP_OPTION_HOSTNAME, len); + while (len--) { + dhcp_option_byte(dhcp, *p++); + } + } + } +} +#endif /* LWIP_NETIF_HOSTNAME */ + +/** + * Extract the DHCP message and the DHCP options. + * + * Extract the DHCP message and the DHCP options, each into a contiguous + * piece of memory. As a DHCP message is variable sized by its options, + * and also allows overriding some fields for options, the easy approach + * is to first unfold the options into a conitguous piece of memory, and + * use that further on. + * + */ +static err_t +dhcp_parse_reply(struct dhcp *dhcp, struct pbuf *p) +{ + u8_t *options; + u16_t offset; + u16_t offset_max; + u16_t options_idx; + u16_t options_idx_max; + struct pbuf *q; + int parse_file_as_options = 0; + int parse_sname_as_options = 0; + + /* clear received options */ + dhcp_clear_all_options(dhcp); + /* check that beginning of dhcp_msg (up to and including chaddr) is in first pbuf */ + if (p->len < DHCP_SNAME_OFS) { + return ERR_BUF; + } + dhcp->msg_in = (struct dhcp_msg *)p->payload; +#if LWIP_DHCP_BOOTP_FILE + /* clear boot file name */ + dhcp->boot_file_name[0] = 0; +#endif /* LWIP_DHCP_BOOTP_FILE */ + + /* parse options */ + + /* start with options field */ + options_idx = DHCP_OPTIONS_OFS; + /* parse options to the end of the received packet */ + options_idx_max = p->tot_len; +again: + q = p; + while((q != NULL) && (options_idx >= q->len)) { + options_idx -= q->len; + options_idx_max -= q->len; + q = q->next; + } + if (q == NULL) { + return ERR_BUF; + } + offset = options_idx; + offset_max = options_idx_max; + options = (u8_t*)q->payload; + /* at least 1 byte to read and no end marker, then at least 3 bytes to read? */ + while((q != NULL) && (options[offset] != DHCP_OPTION_END) && (offset < offset_max)) { + u8_t op = options[offset]; + u8_t len; + u8_t decode_len = 0; + int decode_idx = -1; + u16_t val_offset = offset + 2; + /* len byte might be in the next pbuf */ + if (offset + 1 < q->len) { + len = options[offset + 1]; + } else { + len = (q->next != NULL ? ((u8_t*)q->next->payload)[0] : 0); + } + /* LWIP_DEBUGF(DHCP_DEBUG, ("msg_offset=%"U16_F", q->len=%"U16_F, msg_offset, q->len)); */ + decode_len = len; + switch(op) { + /* case(DHCP_OPTION_END): handled above */ + case(DHCP_OPTION_PAD): + /* special option: no len encoded */ + decode_len = len = 0; + /* will be increased below */ + offset--; + break; + case(DHCP_OPTION_SUBNET_MASK): + LWIP_ERROR("len == 4", len == 4, return ERR_VAL;); + decode_idx = DHCP_OPTION_IDX_SUBNET_MASK; + break; + case(DHCP_OPTION_ROUTER): + decode_len = 4; /* only copy the first given router */ + LWIP_ERROR("len >= decode_len", len >= decode_len, return ERR_VAL;); + decode_idx = DHCP_OPTION_IDX_ROUTER; + break; + case(DHCP_OPTION_DNS_SERVER): + /* special case: there might be more than one server */ + LWIP_ERROR("len % 4 == 0", len % 4 == 0, return ERR_VAL;); + /* limit number of DNS servers */ + decode_len = LWIP_MIN(len, 4 * DNS_MAX_SERVERS); + LWIP_ERROR("len >= decode_len", len >= decode_len, return ERR_VAL;); + decode_idx = DHCP_OPTION_IDX_DNS_SERVER; + break; + case(DHCP_OPTION_LEASE_TIME): + LWIP_ERROR("len == 4", len == 4, return ERR_VAL;); + decode_idx = DHCP_OPTION_IDX_LEASE_TIME; + break; + case(DHCP_OPTION_OVERLOAD): + LWIP_ERROR("len == 1", len == 1, return ERR_VAL;); + decode_idx = DHCP_OPTION_IDX_OVERLOAD; + break; + case(DHCP_OPTION_MESSAGE_TYPE): + LWIP_ERROR("len == 1", len == 1, return ERR_VAL;); + decode_idx = DHCP_OPTION_IDX_MSG_TYPE; + break; + case(DHCP_OPTION_SERVER_ID): + LWIP_ERROR("len == 4", len == 4, return ERR_VAL;); + decode_idx = DHCP_OPTION_IDX_SERVER_ID; + break; + case(DHCP_OPTION_T1): + LWIP_ERROR("len == 4", len == 4, return ERR_VAL;); + decode_idx = DHCP_OPTION_IDX_T1; + break; + case(DHCP_OPTION_T2): + LWIP_ERROR("len == 4", len == 4, return ERR_VAL;); + decode_idx = DHCP_OPTION_IDX_T2; + break; + default: + decode_len = 0; + LWIP_DEBUGF(DHCP_DEBUG, ("skipping option %"U16_F" in options\n", op)); + break; + } + offset += len + 2; + if (decode_len > 0) { + u32_t value = 0; + u16_t copy_len; +decode_next: + LWIP_ASSERT("check decode_idx", decode_idx >= 0 && decode_idx < DHCP_OPTION_IDX_MAX); + if (!dhcp_option_given(dhcp, decode_idx)) { + copy_len = LWIP_MIN(decode_len, 4); + pbuf_copy_partial(q, &value, copy_len, val_offset); + if (decode_len > 4) { + /* decode more than one u32_t */ + LWIP_ERROR("decode_len % 4 == 0", decode_len % 4 == 0, return ERR_VAL;); + dhcp_got_option(dhcp, decode_idx); + dhcp_set_option_value(dhcp, decode_idx, htonl(value)); + decode_len -= 4; + val_offset += 4; + decode_idx++; + goto decode_next; + } else if (decode_len == 4) { + value = ntohl(value); + } else { + LWIP_ERROR("invalid decode_len", decode_len == 1, return ERR_VAL;); + value = ((u8_t*)&value)[0]; + } + dhcp_got_option(dhcp, decode_idx); + dhcp_set_option_value(dhcp, decode_idx, value); + } + } + if (offset >= q->len) { + offset -= q->len; + offset_max -= q->len; + if ((offset < offset_max) && offset_max) { + q = q->next; + LWIP_ASSERT("next pbuf was null", q); + options = (u8_t*)q->payload; + } else { + /* We've run out of bytes, probably no end marker. Don't proceed. */ + break; + } + } + } + /* is this an overloaded message? */ + if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_OVERLOAD)) { + u32_t overload = dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_OVERLOAD); + dhcp_clear_option(dhcp, DHCP_OPTION_IDX_OVERLOAD); + if (overload == DHCP_OVERLOAD_FILE) { + parse_file_as_options = 1; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("overloaded file field\n")); + } else if (overload == DHCP_OVERLOAD_SNAME) { + parse_sname_as_options = 1; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("overloaded sname field\n")); + } else if (overload == DHCP_OVERLOAD_SNAME_FILE) { + parse_sname_as_options = 1; + parse_file_as_options = 1; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("overloaded sname and file field\n")); + } else { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("invalid overload option: %d\n", (int)overload)); + } +#if LWIP_DHCP_BOOTP_FILE + if (!parse_file_as_options) { + /* only do this for ACK messages */ + if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_MSG_TYPE) && + (dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_MSG_TYPE) == DHCP_ACK)) + /* copy bootp file name, don't care for sname (server hostname) */ + pbuf_copy_partial(p, dhcp->boot_file_name, DHCP_FILE_LEN-1, DHCP_FILE_OFS); + /* make sure the string is really NULL-terminated */ + dhcp->boot_file_name[DHCP_FILE_LEN-1] = 0; + } +#endif /* LWIP_DHCP_BOOTP_FILE */ + } + if (parse_file_as_options) { + /* if both are overloaded, parse file first and then sname (RFC 2131 ch. 4.1) */ + parse_file_as_options = 0; + options_idx = DHCP_FILE_OFS; + options_idx_max = DHCP_FILE_OFS + DHCP_FILE_LEN; + goto again; + } else if (parse_sname_as_options) { + parse_sname_as_options = 0; + options_idx = DHCP_SNAME_OFS; + options_idx_max = DHCP_SNAME_OFS + DHCP_SNAME_LEN; + goto again; + } + return ERR_OK; +} + +/** + * If an incoming DHCP message is in response to us, then trigger the state machine + */ +static void +dhcp_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, ip_addr_t *addr, u16_t port) +{ + struct netif *netif = (struct netif *)arg; + struct dhcp *dhcp = netif->dhcp; + struct dhcp_msg *reply_msg = (struct dhcp_msg *)p->payload; + u8_t msg_type; + u8_t i; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_recv(pbuf = %p) from DHCP server %"U16_F".%"U16_F".%"U16_F".%"U16_F" port %"U16_F"\n", (void*)p, + ip4_addr1_16(addr), ip4_addr2_16(addr), ip4_addr3_16(addr), ip4_addr4_16(addr), port)); + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("pbuf->len = %"U16_F"\n", p->len)); + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("pbuf->tot_len = %"U16_F"\n", p->tot_len)); + /* prevent warnings about unused arguments */ + LWIP_UNUSED_ARG(pcb); + LWIP_UNUSED_ARG(addr); + LWIP_UNUSED_ARG(port); + + LWIP_ASSERT("reply wasn't freed", dhcp->msg_in == NULL); + + if (p->len < DHCP_MIN_REPLY_LEN) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, ("DHCP reply message or pbuf too short\n")); + goto free_pbuf_and_return; + } + + if (reply_msg->op != DHCP_BOOTREPLY) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, ("not a DHCP reply message, but type %"U16_F"\n", (u16_t)reply_msg->op)); + goto free_pbuf_and_return; + } + /* iterate through hardware address and match against DHCP message */ + for (i = 0; i < netif->hwaddr_len; i++) { + if (netif->hwaddr[i] != reply_msg->chaddr[i]) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, + ("netif->hwaddr[%"U16_F"]==%02"X16_F" != reply_msg->chaddr[%"U16_F"]==%02"X16_F"\n", + (u16_t)i, (u16_t)netif->hwaddr[i], (u16_t)i, (u16_t)reply_msg->chaddr[i])); + goto free_pbuf_and_return; + } + } + /* match transaction ID against what we expected */ + if (ntohl(reply_msg->xid) != dhcp->xid) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, + ("transaction id mismatch reply_msg->xid(%"X32_F")!=dhcp->xid(%"X32_F")\n",ntohl(reply_msg->xid),dhcp->xid)); + goto free_pbuf_and_return; + } + /* option fields could be unfold? */ + if (dhcp_parse_reply(dhcp, p) != ERR_OK) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, + ("problem unfolding DHCP message - too short on memory?\n")); + goto free_pbuf_and_return; + } + + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("searching DHCP_OPTION_MESSAGE_TYPE\n")); + /* obtain pointer to DHCP message type */ + if (!dhcp_option_given(dhcp, DHCP_OPTION_IDX_MSG_TYPE)) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, ("DHCP_OPTION_MESSAGE_TYPE option not found\n")); + goto free_pbuf_and_return; + } + + /* read DHCP message type */ + msg_type = (u8_t)dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_MSG_TYPE); + /* message type is DHCP ACK? */ + if (msg_type == DHCP_ACK) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("DHCP_ACK received\n")); + /* in requesting state? */ + if (dhcp->state == DHCP_REQUESTING) { + dhcp_handle_ack(netif); +#if DHCP_DOES_ARP_CHECK + /* check if the acknowledged lease address is already in use */ + dhcp_check(netif); +#else + /* bind interface to the acknowledged lease address */ + dhcp_bind(netif); +#endif + } + /* already bound to the given lease address? */ + else if ((dhcp->state == DHCP_REBOOTING) || (dhcp->state == DHCP_REBINDING) || (dhcp->state == DHCP_RENEWING)) { + dhcp_bind(netif); + } + } + /* received a DHCP_NAK in appropriate state? */ + else if ((msg_type == DHCP_NAK) && + ((dhcp->state == DHCP_REBOOTING) || (dhcp->state == DHCP_REQUESTING) || + (dhcp->state == DHCP_REBINDING) || (dhcp->state == DHCP_RENEWING ))) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("DHCP_NAK received\n")); + dhcp_handle_nak(netif); + } + /* received a DHCP_OFFER in DHCP_SELECTING state? */ + else if ((msg_type == DHCP_OFFER) && (dhcp->state == DHCP_SELECTING)) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("DHCP_OFFER received in DHCP_SELECTING state\n")); + dhcp->request_timeout = 0; + /* remember offered lease */ + dhcp_handle_offer(netif); + } +free_pbuf_and_return: + dhcp->msg_in = NULL; + pbuf_free(p); +} + +/** + * Create a DHCP request, fill in common headers + * + * @param netif the netif under DHCP control + * @param dhcp dhcp control struct + * @param message_type message type of the request + */ +static err_t +dhcp_create_msg(struct netif *netif, struct dhcp *dhcp, u8_t message_type) +{ + u16_t i; +#ifndef DHCP_GLOBAL_XID + /** default global transaction identifier starting value (easy to match + * with a packet analyser). We simply increment for each new request. + * Predefine DHCP_GLOBAL_XID to a better value or a function call to generate one + * at runtime, any supporting function prototypes can be defined in DHCP_GLOBAL_XID_HEADER */ +#if DHCP_CREATE_RAND_XID && defined(LWIP_RAND) + static u32_t xid; +#else /* DHCP_CREATE_RAND_XID && defined(LWIP_RAND) */ + static u32_t xid = 0xABCD0000; +#endif /* DHCP_CREATE_RAND_XID && defined(LWIP_RAND) */ +#else + if (!xid_initialised) { + xid = DHCP_GLOBAL_XID; + xid_initialised = !xid_initialised; + } +#endif + LWIP_ERROR("dhcp_create_msg: netif != NULL", (netif != NULL), return ERR_ARG;); + LWIP_ERROR("dhcp_create_msg: dhcp != NULL", (dhcp != NULL), return ERR_VAL;); + LWIP_ASSERT("dhcp_create_msg: dhcp->p_out == NULL", dhcp->p_out == NULL); + LWIP_ASSERT("dhcp_create_msg: dhcp->msg_out == NULL", dhcp->msg_out == NULL); + dhcp->p_out = pbuf_alloc(PBUF_TRANSPORT, sizeof(struct dhcp_msg), PBUF_RAM); + if (dhcp->p_out == NULL) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, + ("dhcp_create_msg(): could not allocate pbuf\n")); + return ERR_MEM; + } + LWIP_ASSERT("dhcp_create_msg: check that first pbuf can hold struct dhcp_msg", + (dhcp->p_out->len >= sizeof(struct dhcp_msg))); + + /* reuse transaction identifier in retransmissions */ + if (dhcp->tries == 0) { +#if DHCP_CREATE_RAND_XID && defined(LWIP_RAND) + xid = LWIP_RAND(); +#else /* DHCP_CREATE_RAND_XID && defined(LWIP_RAND) */ + xid++; +#endif /* DHCP_CREATE_RAND_XID && defined(LWIP_RAND) */ + } + dhcp->xid = xid; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, + ("transaction id xid(%"X32_F")\n", xid)); + + dhcp->msg_out = (struct dhcp_msg *)dhcp->p_out->payload; + + dhcp->msg_out->op = DHCP_BOOTREQUEST; + /* TODO: make link layer independent */ + dhcp->msg_out->htype = DHCP_HTYPE_ETH; + dhcp->msg_out->hlen = netif->hwaddr_len; + dhcp->msg_out->hops = 0; + dhcp->msg_out->xid = htonl(dhcp->xid); + dhcp->msg_out->secs = 0; + /* we don't need the broadcast flag since we can receive unicast traffic + before being fully configured! */ + dhcp->msg_out->flags = 0; + ip_addr_set_zero(&dhcp->msg_out->ciaddr); + /* set ciaddr to netif->ip_addr based on message_type and state */ + if ((message_type == DHCP_INFORM) || (message_type == DHCP_DECLINE) || + ((message_type == DHCP_REQUEST) && /* DHCP_BOUND not used for sending! */ + ((dhcp->state==DHCP_RENEWING) || dhcp->state==DHCP_REBINDING))) { + ip_addr_copy(dhcp->msg_out->ciaddr, netif->ip_addr); + } + ip_addr_set_zero(&dhcp->msg_out->yiaddr); + ip_addr_set_zero(&dhcp->msg_out->siaddr); + ip_addr_set_zero(&dhcp->msg_out->giaddr); + for (i = 0; i < DHCP_CHADDR_LEN; i++) { + /* copy netif hardware address, pad with zeroes */ + dhcp->msg_out->chaddr[i] = (i < netif->hwaddr_len) ? netif->hwaddr[i] : 0/* pad byte*/; + } + for (i = 0; i < DHCP_SNAME_LEN; i++) { + dhcp->msg_out->sname[i] = 0; + } + for (i = 0; i < DHCP_FILE_LEN; i++) { + dhcp->msg_out->file[i] = 0; + } + dhcp->msg_out->cookie = PP_HTONL(DHCP_MAGIC_COOKIE); + dhcp->options_out_len = 0; + /* fill options field with an incrementing array (for debugging purposes) */ + for (i = 0; i < DHCP_OPTIONS_LEN; i++) { + dhcp->msg_out->options[i] = (u8_t)i; /* for debugging only, no matter if truncated */ + } + /* Add option MESSAGE_TYPE */ + dhcp_option(dhcp, DHCP_OPTION_MESSAGE_TYPE, DHCP_OPTION_MESSAGE_TYPE_LEN); + dhcp_option_byte(dhcp, message_type); + return ERR_OK; +} + +/** + * Free previously allocated memory used to send a DHCP request. + * + * @param dhcp the dhcp struct to free the request from + */ +static void +dhcp_delete_msg(struct dhcp *dhcp) +{ + LWIP_ERROR("dhcp_delete_msg: dhcp != NULL", (dhcp != NULL), return;); + LWIP_ASSERT("dhcp_delete_msg: dhcp->p_out != NULL", dhcp->p_out != NULL); + LWIP_ASSERT("dhcp_delete_msg: dhcp->msg_out != NULL", dhcp->msg_out != NULL); + if (dhcp->p_out != NULL) { + pbuf_free(dhcp->p_out); + } + dhcp->p_out = NULL; + dhcp->msg_out = NULL; +} + +/** + * Add a DHCP message trailer + * + * Adds the END option to the DHCP message, and if + * necessary, up to three padding bytes. + * + * @param dhcp DHCP state structure + */ +static void +dhcp_option_trailer(struct dhcp *dhcp) +{ + LWIP_ERROR("dhcp_option_trailer: dhcp != NULL", (dhcp != NULL), return;); + LWIP_ASSERT("dhcp_option_trailer: dhcp->msg_out != NULL\n", dhcp->msg_out != NULL); + LWIP_ASSERT("dhcp_option_trailer: dhcp->options_out_len < DHCP_OPTIONS_LEN\n", dhcp->options_out_len < DHCP_OPTIONS_LEN); + dhcp->msg_out->options[dhcp->options_out_len++] = DHCP_OPTION_END; + /* packet is too small, or not 4 byte aligned? */ + while (((dhcp->options_out_len < DHCP_MIN_OPTIONS_LEN) || (dhcp->options_out_len & 3)) && + (dhcp->options_out_len < DHCP_OPTIONS_LEN)) { + /* add a fill/padding byte */ + dhcp->msg_out->options[dhcp->options_out_len++] = 0; + } +} + +#endif /* LWIP_DHCP */ diff --git a/src/lwip-1.4.1/src/core/dns.c b/src/lwip-1.4.1/src/core/dns.c new file mode 100644 index 0000000..d633612 --- /dev/null +++ b/src/lwip-1.4.1/src/core/dns.c @@ -0,0 +1,970 @@ +/** + * @file + * DNS - host name to IP address resolver. + * + */ + +/** + + * This file implements a DNS host name to IP address resolver. + + * Port to lwIP from uIP + * by Jim Pettinato April 2007 + + * uIP version Copyright (c) 2002-2003, Adam Dunkels. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * + * DNS.C + * + * The lwIP DNS resolver functions are used to lookup a host name and + * map it to a numerical IP address. It maintains a list of resolved + * hostnames that can be queried with the dns_lookup() function. + * New hostnames can be resolved using the dns_query() function. + * + * The lwIP version of the resolver also adds a non-blocking version of + * gethostbyname() that will work with a raw API application. This function + * checks for an IP address string first and converts it if it is valid. + * gethostbyname() then does a dns_lookup() to see if the name is + * already in the table. If so, the IP is returned. If not, a query is + * issued and the function returns with a ERR_INPROGRESS status. The app + * using the dns client must then go into a waiting state. + * + * Once a hostname has been resolved (or found to be non-existent), + * the resolver code calls a specified callback function (which + * must be implemented by the module that uses the resolver). + */ + +/*----------------------------------------------------------------------------- + * RFC 1035 - Domain names - implementation and specification + * RFC 2181 - Clarifications to the DNS Specification + *----------------------------------------------------------------------------*/ + +/** @todo: define good default values (rfc compliance) */ +/** @todo: improve answer parsing, more checkings... */ +/** @todo: check RFC1035 - 7.3. Processing responses */ + +/*----------------------------------------------------------------------------- + * Includes + *----------------------------------------------------------------------------*/ + +#include "lwip/opt.h" + +#if LWIP_DNS /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/udp.h" +#include "lwip/mem.h" +#include "lwip/memp.h" +#include "lwip/dns.h" + +#include + +/** DNS server IP address */ +#ifndef DNS_SERVER_ADDRESS +#define DNS_SERVER_ADDRESS(ipaddr) (ip4_addr_set_u32(ipaddr, ipaddr_addr("208.67.222.222"))) /* resolver1.opendns.com */ +#endif + +/** DNS server port address */ +#ifndef DNS_SERVER_PORT +#define DNS_SERVER_PORT 53 +#endif + +/** DNS maximum number of retries when asking for a name, before "timeout". */ +#ifndef DNS_MAX_RETRIES +#define DNS_MAX_RETRIES 4 +#endif + +/** DNS resource record max. TTL (one week as default) */ +#ifndef DNS_MAX_TTL +#define DNS_MAX_TTL 604800 +#endif + +/* DNS protocol flags */ +#define DNS_FLAG1_RESPONSE 0x80 +#define DNS_FLAG1_OPCODE_STATUS 0x10 +#define DNS_FLAG1_OPCODE_INVERSE 0x08 +#define DNS_FLAG1_OPCODE_STANDARD 0x00 +#define DNS_FLAG1_AUTHORATIVE 0x04 +#define DNS_FLAG1_TRUNC 0x02 +#define DNS_FLAG1_RD 0x01 +#define DNS_FLAG2_RA 0x80 +#define DNS_FLAG2_ERR_MASK 0x0f +#define DNS_FLAG2_ERR_NONE 0x00 +#define DNS_FLAG2_ERR_NAME 0x03 + +/* DNS protocol states */ +#define DNS_STATE_UNUSED 0 +#define DNS_STATE_NEW 1 +#define DNS_STATE_ASKING 2 +#define DNS_STATE_DONE 3 + +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +/** DNS message header */ +struct dns_hdr { + PACK_STRUCT_FIELD(u16_t id); + PACK_STRUCT_FIELD(u8_t flags1); + PACK_STRUCT_FIELD(u8_t flags2); + PACK_STRUCT_FIELD(u16_t numquestions); + PACK_STRUCT_FIELD(u16_t numanswers); + PACK_STRUCT_FIELD(u16_t numauthrr); + PACK_STRUCT_FIELD(u16_t numextrarr); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif +#define SIZEOF_DNS_HDR 12 + +/** DNS query message structure. + No packing needed: only used locally on the stack. */ +struct dns_query { + /* DNS query record starts with either a domain name or a pointer + to a name already present somewhere in the packet. */ + u16_t type; + u16_t cls; +}; +#define SIZEOF_DNS_QUERY 4 + +/** DNS answer message structure. + No packing needed: only used locally on the stack. */ +struct dns_answer { + /* DNS answer record starts with either a domain name or a pointer + to a name already present somewhere in the packet. */ + u16_t type; + u16_t cls; + u32_t ttl; + u16_t len; +}; +#define SIZEOF_DNS_ANSWER 10 + +/** DNS table entry */ +struct dns_table_entry { + u8_t state; + u8_t numdns; + u8_t tmr; + u8_t retries; + u8_t seqno; + u8_t err; + u32_t ttl; + char name[DNS_MAX_NAME_LENGTH]; + ip_addr_t ipaddr; + /* pointer to callback on DNS query done */ + dns_found_callback found; + void *arg; +}; + +#if DNS_LOCAL_HOSTLIST + +#if DNS_LOCAL_HOSTLIST_IS_DYNAMIC +/** Local host-list. For hostnames in this list, no + * external name resolution is performed */ +static struct local_hostlist_entry *local_hostlist_dynamic; +#else /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC */ + +/** Defining this allows the local_hostlist_static to be placed in a different + * linker section (e.g. FLASH) */ +#ifndef DNS_LOCAL_HOSTLIST_STORAGE_PRE +#define DNS_LOCAL_HOSTLIST_STORAGE_PRE static +#endif /* DNS_LOCAL_HOSTLIST_STORAGE_PRE */ +/** Defining this allows the local_hostlist_static to be placed in a different + * linker section (e.g. FLASH) */ +#ifndef DNS_LOCAL_HOSTLIST_STORAGE_POST +#define DNS_LOCAL_HOSTLIST_STORAGE_POST +#endif /* DNS_LOCAL_HOSTLIST_STORAGE_POST */ +DNS_LOCAL_HOSTLIST_STORAGE_PRE struct local_hostlist_entry local_hostlist_static[] + DNS_LOCAL_HOSTLIST_STORAGE_POST = DNS_LOCAL_HOSTLIST_INIT; + +#endif /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC */ + +static void dns_init_local(); +#endif /* DNS_LOCAL_HOSTLIST */ + + +/* forward declarations */ +static void dns_recv(void *s, struct udp_pcb *pcb, struct pbuf *p, ip_addr_t *addr, u16_t port); +static void dns_check_entries(void); + +/*----------------------------------------------------------------------------- + * Globales + *----------------------------------------------------------------------------*/ + +/* DNS variables */ +static struct udp_pcb *dns_pcb; +static u8_t dns_seqno; +static struct dns_table_entry dns_table[DNS_TABLE_SIZE]; +static ip_addr_t dns_servers[DNS_MAX_SERVERS]; +/** Contiguous buffer for processing responses */ +static u8_t dns_payload_buffer[LWIP_MEM_ALIGN_BUFFER(DNS_MSG_SIZE)]; +static u8_t* dns_payload; + +/** + * Initialize the resolver: set up the UDP pcb and configure the default server + * (DNS_SERVER_ADDRESS). + */ +void +dns_init() +{ + ip_addr_t dnsserver; + + dns_payload = (u8_t *)LWIP_MEM_ALIGN(dns_payload_buffer); + + /* initialize default DNS server address */ + DNS_SERVER_ADDRESS(&dnsserver); + + LWIP_DEBUGF(DNS_DEBUG, ("dns_init: initializing\n")); + + /* if dns client not yet initialized... */ + if (dns_pcb == NULL) { + dns_pcb = udp_new(); + + if (dns_pcb != NULL) { + /* initialize DNS table not needed (initialized to zero since it is a + * global variable) */ + LWIP_ASSERT("For implicit initialization to work, DNS_STATE_UNUSED needs to be 0", + DNS_STATE_UNUSED == 0); + + /* initialize DNS client */ + udp_bind(dns_pcb, IP_ADDR_ANY, 0); + udp_recv(dns_pcb, dns_recv, NULL); + + /* initialize default DNS primary server */ + dns_setserver(0, &dnsserver); + } + } +#if DNS_LOCAL_HOSTLIST + dns_init_local(); +#endif +} + +/** + * Initialize one of the DNS servers. + * + * @param numdns the index of the DNS server to set must be < DNS_MAX_SERVERS + * @param dnsserver IP address of the DNS server to set + */ +void +dns_setserver(u8_t numdns, ip_addr_t *dnsserver) +{ + if ((numdns < DNS_MAX_SERVERS) && (dns_pcb != NULL) && + (dnsserver != NULL) && !ip_addr_isany(dnsserver)) { + dns_servers[numdns] = (*dnsserver); + } +} + +/** + * Obtain one of the currently configured DNS server. + * + * @param numdns the index of the DNS server + * @return IP address of the indexed DNS server or "ip_addr_any" if the DNS + * server has not been configured. + */ +ip_addr_t +dns_getserver(u8_t numdns) +{ + if (numdns < DNS_MAX_SERVERS) { + return dns_servers[numdns]; + } else { + return *IP_ADDR_ANY; + } +} + +/** + * The DNS resolver client timer - handle retries and timeouts and should + * be called every DNS_TMR_INTERVAL milliseconds (every second by default). + */ +void +dns_tmr(void) +{ + if (dns_pcb != NULL) { + LWIP_DEBUGF(DNS_DEBUG, ("dns_tmr: dns_check_entries\n")); + dns_check_entries(); + } +} + +#if DNS_LOCAL_HOSTLIST +static void +dns_init_local() +{ +#if DNS_LOCAL_HOSTLIST_IS_DYNAMIC && defined(DNS_LOCAL_HOSTLIST_INIT) + int i; + struct local_hostlist_entry *entry; + /* Dynamic: copy entries from DNS_LOCAL_HOSTLIST_INIT to list */ + struct local_hostlist_entry local_hostlist_init[] = DNS_LOCAL_HOSTLIST_INIT; + size_t namelen; + for (i = 0; i < sizeof(local_hostlist_init) / sizeof(struct local_hostlist_entry); i++) { + struct local_hostlist_entry *init_entry = &local_hostlist_init[i]; + LWIP_ASSERT("invalid host name (NULL)", init_entry->name != NULL); + namelen = strlen(init_entry->name); + LWIP_ASSERT("namelen <= DNS_LOCAL_HOSTLIST_MAX_NAMELEN", namelen <= DNS_LOCAL_HOSTLIST_MAX_NAMELEN); + entry = (struct local_hostlist_entry *)memp_malloc(MEMP_LOCALHOSTLIST); + LWIP_ASSERT("mem-error in dns_init_local", entry != NULL); + if (entry != NULL) { + entry->name = (char*)entry + sizeof(struct local_hostlist_entry); + MEMCPY((char*)entry->name, init_entry->name, namelen); + ((char*)entry->name)[namelen] = 0; + entry->addr = init_entry->addr; + entry->next = local_hostlist_dynamic; + local_hostlist_dynamic = entry; + } + } +#endif /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC && defined(DNS_LOCAL_HOSTLIST_INIT) */ +} + +/** + * Scans the local host-list for a hostname. + * + * @param hostname Hostname to look for in the local host-list + * @return The first IP address for the hostname in the local host-list or + * IPADDR_NONE if not found. + */ +static u32_t +dns_lookup_local(const char *hostname) +{ +#if DNS_LOCAL_HOSTLIST_IS_DYNAMIC + struct local_hostlist_entry *entry = local_hostlist_dynamic; + while(entry != NULL) { + if(strcmp(entry->name, hostname) == 0) { + return ip4_addr_get_u32(&entry->addr); + } + entry = entry->next; + } +#else /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC */ + int i; + for (i = 0; i < sizeof(local_hostlist_static) / sizeof(struct local_hostlist_entry); i++) { + if(strcmp(local_hostlist_static[i].name, hostname) == 0) { + return ip4_addr_get_u32(&local_hostlist_static[i].addr); + } + } +#endif /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC */ + return IPADDR_NONE; +} + +#if DNS_LOCAL_HOSTLIST_IS_DYNAMIC +/** Remove all entries from the local host-list for a specific hostname + * and/or IP addess + * + * @param hostname hostname for which entries shall be removed from the local + * host-list + * @param addr address for which entries shall be removed from the local host-list + * @return the number of removed entries + */ +int +dns_local_removehost(const char *hostname, const ip_addr_t *addr) +{ + int removed = 0; + struct local_hostlist_entry *entry = local_hostlist_dynamic; + struct local_hostlist_entry *last_entry = NULL; + while (entry != NULL) { + if (((hostname == NULL) || !strcmp(entry->name, hostname)) && + ((addr == NULL) || ip_addr_cmp(&entry->addr, addr))) { + struct local_hostlist_entry *free_entry; + if (last_entry != NULL) { + last_entry->next = entry->next; + } else { + local_hostlist_dynamic = entry->next; + } + free_entry = entry; + entry = entry->next; + memp_free(MEMP_LOCALHOSTLIST, free_entry); + removed++; + } else { + last_entry = entry; + entry = entry->next; + } + } + return removed; +} + +/** + * Add a hostname/IP address pair to the local host-list. + * Duplicates are not checked. + * + * @param hostname hostname of the new entry + * @param addr IP address of the new entry + * @return ERR_OK if succeeded or ERR_MEM on memory error + */ +err_t +dns_local_addhost(const char *hostname, const ip_addr_t *addr) +{ + struct local_hostlist_entry *entry; + size_t namelen; + LWIP_ASSERT("invalid host name (NULL)", hostname != NULL); + namelen = strlen(hostname); + LWIP_ASSERT("namelen <= DNS_LOCAL_HOSTLIST_MAX_NAMELEN", namelen <= DNS_LOCAL_HOSTLIST_MAX_NAMELEN); + entry = (struct local_hostlist_entry *)memp_malloc(MEMP_LOCALHOSTLIST); + if (entry == NULL) { + return ERR_MEM; + } + entry->name = (char*)entry + sizeof(struct local_hostlist_entry); + MEMCPY((char*)entry->name, hostname, namelen); + ((char*)entry->name)[namelen] = 0; + ip_addr_copy(entry->addr, *addr); + entry->next = local_hostlist_dynamic; + local_hostlist_dynamic = entry; + return ERR_OK; +} +#endif /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC*/ +#endif /* DNS_LOCAL_HOSTLIST */ + +/** + * Look up a hostname in the array of known hostnames. + * + * @note This function only looks in the internal array of known + * hostnames, it does not send out a query for the hostname if none + * was found. The function dns_enqueue() can be used to send a query + * for a hostname. + * + * @param name the hostname to look up + * @return the hostname's IP address, as u32_t (instead of ip_addr_t to + * better check for failure: != IPADDR_NONE) or IPADDR_NONE if the hostname + * was not found in the cached dns_table. + */ +static u32_t +dns_lookup(const char *name) +{ + u8_t i; +#if DNS_LOCAL_HOSTLIST || defined(DNS_LOOKUP_LOCAL_EXTERN) + u32_t addr; +#endif /* DNS_LOCAL_HOSTLIST || defined(DNS_LOOKUP_LOCAL_EXTERN) */ +#if DNS_LOCAL_HOSTLIST + if ((addr = dns_lookup_local(name)) != IPADDR_NONE) { + return addr; + } +#endif /* DNS_LOCAL_HOSTLIST */ +#ifdef DNS_LOOKUP_LOCAL_EXTERN + if((addr = DNS_LOOKUP_LOCAL_EXTERN(name)) != IPADDR_NONE) { + return addr; + } +#endif /* DNS_LOOKUP_LOCAL_EXTERN */ + + /* Walk through name list, return entry if found. If not, return NULL. */ + for (i = 0; i < DNS_TABLE_SIZE; ++i) { + if ((dns_table[i].state == DNS_STATE_DONE) && + (strcmp(name, dns_table[i].name) == 0)) { + LWIP_DEBUGF(DNS_DEBUG, ("dns_lookup: \"%s\": found = ", name)); + ip_addr_debug_print(DNS_DEBUG, &(dns_table[i].ipaddr)); + LWIP_DEBUGF(DNS_DEBUG, ("\n")); + return ip4_addr_get_u32(&dns_table[i].ipaddr); + } + } + + return IPADDR_NONE; +} + +#if DNS_DOES_NAME_CHECK +/** + * Compare the "dotted" name "query" with the encoded name "response" + * to make sure an answer from the DNS server matches the current dns_table + * entry (otherwise, answers might arrive late for hostname not on the list + * any more). + * + * @param query hostname (not encoded) from the dns_table + * @param response encoded hostname in the DNS response + * @return 0: names equal; 1: names differ + */ +static u8_t +dns_compare_name(unsigned char *query, unsigned char *response) +{ + unsigned char n; + + do { + n = *response++; + /** @see RFC 1035 - 4.1.4. Message compression */ + if ((n & 0xc0) == 0xc0) { + /* Compressed name */ + break; + } else { + /* Not compressed name */ + while (n > 0) { + if ((*query) != (*response)) { + return 1; + } + ++response; + ++query; + --n; + }; + ++query; + } + } while (*response != 0); + + return 0; +} +#endif /* DNS_DOES_NAME_CHECK */ + +/** + * Walk through a compact encoded DNS name and return the end of the name. + * + * @param query encoded DNS name in the DNS server response + * @return end of the name + */ +static unsigned char * +dns_parse_name(unsigned char *query) +{ + unsigned char n; + + do { + n = *query++; + /** @see RFC 1035 - 4.1.4. Message compression */ + if ((n & 0xc0) == 0xc0) { + /* Compressed name */ + break; + } else { + /* Not compressed name */ + while (n > 0) { + ++query; + --n; + }; + } + } while (*query != 0); + + return query + 1; +} + +/** + * Send a DNS query packet. + * + * @param numdns index of the DNS server in the dns_servers table + * @param name hostname to query + * @param id index of the hostname in dns_table, used as transaction ID in the + * DNS query packet + * @return ERR_OK if packet is sent; an err_t indicating the problem otherwise + */ +static err_t +dns_send(u8_t numdns, const char* name, u8_t id) +{ + err_t err; + struct dns_hdr *hdr; + struct dns_query qry; + struct pbuf *p; + char *query, *nptr; + const char *pHostname; + u8_t n; + + LWIP_DEBUGF(DNS_DEBUG, ("dns_send: dns_servers[%"U16_F"] \"%s\": request\n", + (u16_t)(numdns), name)); + LWIP_ASSERT("dns server out of array", numdns < DNS_MAX_SERVERS); + LWIP_ASSERT("dns server has no IP address set", !ip_addr_isany(&dns_servers[numdns])); + + /* if here, we have either a new query or a retry on a previous query to process */ + p = pbuf_alloc(PBUF_TRANSPORT, SIZEOF_DNS_HDR + DNS_MAX_NAME_LENGTH + + SIZEOF_DNS_QUERY, PBUF_RAM); + if (p != NULL) { + LWIP_ASSERT("pbuf must be in one piece", p->next == NULL); + /* fill dns header */ + hdr = (struct dns_hdr*)p->payload; + memset(hdr, 0, SIZEOF_DNS_HDR); + hdr->id = htons(id); + hdr->flags1 = DNS_FLAG1_RD; + hdr->numquestions = PP_HTONS(1); + query = (char*)hdr + SIZEOF_DNS_HDR; + pHostname = name; + --pHostname; + + /* convert hostname into suitable query format. */ + do { + ++pHostname; + nptr = query; + ++query; + for(n = 0; *pHostname != '.' && *pHostname != 0; ++pHostname) { + *query = *pHostname; + ++query; + ++n; + } + *nptr = n; + } while(*pHostname != 0); + *query++='\0'; + + /* fill dns query */ + qry.type = PP_HTONS(DNS_RRTYPE_A); + qry.cls = PP_HTONS(DNS_RRCLASS_IN); + SMEMCPY(query, &qry, SIZEOF_DNS_QUERY); + + /* resize pbuf to the exact dns query */ + pbuf_realloc(p, (u16_t)((query + SIZEOF_DNS_QUERY) - ((char*)(p->payload)))); + + /* connect to the server for faster receiving */ + udp_connect(dns_pcb, &dns_servers[numdns], DNS_SERVER_PORT); + /* send dns packet */ + err = udp_sendto(dns_pcb, p, &dns_servers[numdns], DNS_SERVER_PORT); + + /* free pbuf */ + pbuf_free(p); + } else { + err = ERR_MEM; + } + + return err; +} + +/** + * dns_check_entry() - see if pEntry has not yet been queried and, if so, sends out a query. + * Check an entry in the dns_table: + * - send out query for new entries + * - retry old pending entries on timeout (also with different servers) + * - remove completed entries from the table if their TTL has expired + * + * @param i index of the dns_table entry to check + */ +static void +dns_check_entry(u8_t i) +{ + err_t err; + struct dns_table_entry *pEntry = &dns_table[i]; + + LWIP_ASSERT("array index out of bounds", i < DNS_TABLE_SIZE); + + switch(pEntry->state) { + + case DNS_STATE_NEW: { + /* initialize new entry */ + pEntry->state = DNS_STATE_ASKING; + pEntry->numdns = 0; + pEntry->tmr = 1; + pEntry->retries = 0; + + /* send DNS packet for this entry */ + err = dns_send(pEntry->numdns, pEntry->name, i); + if (err != ERR_OK) { + LWIP_DEBUGF(DNS_DEBUG | LWIP_DBG_LEVEL_WARNING, + ("dns_send returned error: %s\n", lwip_strerr(err))); + } + break; + } + + case DNS_STATE_ASKING: { + if (--pEntry->tmr == 0) { + if (++pEntry->retries == DNS_MAX_RETRIES) { + if ((pEntry->numdns+1numdns+1])) { + /* change of server */ + pEntry->numdns++; + pEntry->tmr = 1; + pEntry->retries = 0; + break; + } else { + LWIP_DEBUGF(DNS_DEBUG, ("dns_check_entry: \"%s\": timeout\n", pEntry->name)); + /* call specified callback function if provided */ + if (pEntry->found) + (*pEntry->found)(pEntry->name, NULL, pEntry->arg); + /* flush this entry */ + pEntry->state = DNS_STATE_UNUSED; + pEntry->found = NULL; + break; + } + } + + /* wait longer for the next retry */ + pEntry->tmr = pEntry->retries; + + /* send DNS packet for this entry */ + err = dns_send(pEntry->numdns, pEntry->name, i); + if (err != ERR_OK) { + LWIP_DEBUGF(DNS_DEBUG | LWIP_DBG_LEVEL_WARNING, + ("dns_send returned error: %s\n", lwip_strerr(err))); + } + } + break; + } + + case DNS_STATE_DONE: { + /* if the time to live is nul */ + if (--pEntry->ttl == 0) { + LWIP_DEBUGF(DNS_DEBUG, ("dns_check_entry: \"%s\": flush\n", pEntry->name)); + /* flush this entry */ + pEntry->state = DNS_STATE_UNUSED; + pEntry->found = NULL; + } + break; + } + case DNS_STATE_UNUSED: + /* nothing to do */ + break; + default: + LWIP_ASSERT("unknown dns_table entry state:", 0); + break; + } +} + +/** + * Call dns_check_entry for each entry in dns_table - check all entries. + */ +static void +dns_check_entries(void) +{ + u8_t i; + + for (i = 0; i < DNS_TABLE_SIZE; ++i) { + dns_check_entry(i); + } +} + +/** + * Receive input function for DNS response packets arriving for the dns UDP pcb. + * + * @params see udp.h + */ +static void +dns_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, ip_addr_t *addr, u16_t port) +{ + u16_t i; + char *pHostname; + struct dns_hdr *hdr; + struct dns_answer ans; + struct dns_table_entry *pEntry; + u16_t nquestions, nanswers; + + LWIP_UNUSED_ARG(arg); + LWIP_UNUSED_ARG(pcb); + LWIP_UNUSED_ARG(addr); + LWIP_UNUSED_ARG(port); + + /* is the dns message too big ? */ + if (p->tot_len > DNS_MSG_SIZE) { + LWIP_DEBUGF(DNS_DEBUG, ("dns_recv: pbuf too big\n")); + /* free pbuf and return */ + goto memerr; + } + + /* is the dns message big enough ? */ + if (p->tot_len < (SIZEOF_DNS_HDR + SIZEOF_DNS_QUERY + SIZEOF_DNS_ANSWER)) { + LWIP_DEBUGF(DNS_DEBUG, ("dns_recv: pbuf too small\n")); + /* free pbuf and return */ + goto memerr; + } + + /* copy dns payload inside static buffer for processing */ + if (pbuf_copy_partial(p, dns_payload, p->tot_len, 0) == p->tot_len) { + /* The ID in the DNS header should be our entry into the name table. */ + hdr = (struct dns_hdr*)dns_payload; + i = htons(hdr->id); + if (i < DNS_TABLE_SIZE) { + pEntry = &dns_table[i]; + if(pEntry->state == DNS_STATE_ASKING) { + /* This entry is now completed. */ + pEntry->state = DNS_STATE_DONE; + pEntry->err = hdr->flags2 & DNS_FLAG2_ERR_MASK; + + /* We only care about the question(s) and the answers. The authrr + and the extrarr are simply discarded. */ + nquestions = htons(hdr->numquestions); + nanswers = htons(hdr->numanswers); + + /* Check for error. If so, call callback to inform. */ + if (((hdr->flags1 & DNS_FLAG1_RESPONSE) == 0) || (pEntry->err != 0) || (nquestions != 1)) { + LWIP_DEBUGF(DNS_DEBUG, ("dns_recv: \"%s\": error in flags\n", pEntry->name)); + /* call callback to indicate error, clean up memory and return */ + goto responseerr; + } + +#if DNS_DOES_NAME_CHECK + /* Check if the name in the "question" part match with the name in the entry. */ + if (dns_compare_name((unsigned char *)(pEntry->name), (unsigned char *)dns_payload + SIZEOF_DNS_HDR) != 0) { + LWIP_DEBUGF(DNS_DEBUG, ("dns_recv: \"%s\": response not match to query\n", pEntry->name)); + /* call callback to indicate error, clean up memory and return */ + goto responseerr; + } +#endif /* DNS_DOES_NAME_CHECK */ + + /* Skip the name in the "question" part */ + pHostname = (char *) dns_parse_name((unsigned char *)dns_payload + SIZEOF_DNS_HDR) + SIZEOF_DNS_QUERY; + + while (nanswers > 0) { + /* skip answer resource record's host name */ + pHostname = (char *) dns_parse_name((unsigned char *)pHostname); + + /* Check for IP address type and Internet class. Others are discarded. */ + SMEMCPY(&ans, pHostname, SIZEOF_DNS_ANSWER); + if((ans.type == PP_HTONS(DNS_RRTYPE_A)) && (ans.cls == PP_HTONS(DNS_RRCLASS_IN)) && + (ans.len == PP_HTONS(sizeof(ip_addr_t))) ) { + /* read the answer resource record's TTL, and maximize it if needed */ + pEntry->ttl = ntohl(ans.ttl); + if (pEntry->ttl > DNS_MAX_TTL) { + pEntry->ttl = DNS_MAX_TTL; + } + /* read the IP address after answer resource record's header */ + SMEMCPY(&(pEntry->ipaddr), (pHostname+SIZEOF_DNS_ANSWER), sizeof(ip_addr_t)); + LWIP_DEBUGF(DNS_DEBUG, ("dns_recv: \"%s\": response = ", pEntry->name)); + ip_addr_debug_print(DNS_DEBUG, (&(pEntry->ipaddr))); + LWIP_DEBUGF(DNS_DEBUG, ("\n")); + /* call specified callback function if provided */ + if (pEntry->found) { + (*pEntry->found)(pEntry->name, &pEntry->ipaddr, pEntry->arg); + } + /* deallocate memory and return */ + goto memerr; + } else { + pHostname = pHostname + SIZEOF_DNS_ANSWER + htons(ans.len); + } + --nanswers; + } + LWIP_DEBUGF(DNS_DEBUG, ("dns_recv: \"%s\": error in response\n", pEntry->name)); + /* call callback to indicate error, clean up memory and return */ + goto responseerr; + } + } + } + + /* deallocate memory and return */ + goto memerr; + +responseerr: + /* ERROR: call specified callback function with NULL as name to indicate an error */ + if (pEntry->found) { + (*pEntry->found)(pEntry->name, NULL, pEntry->arg); + } + /* flush this entry */ + pEntry->state = DNS_STATE_UNUSED; + pEntry->found = NULL; + +memerr: + /* free pbuf */ + pbuf_free(p); + return; +} + +/** + * Queues a new hostname to resolve and sends out a DNS query for that hostname + * + * @param name the hostname that is to be queried + * @param found a callback founction to be called on success, failure or timeout + * @param callback_arg argument to pass to the callback function + * @return @return a err_t return code. + */ +static err_t +dns_enqueue(const char *name, dns_found_callback found, void *callback_arg) +{ + u8_t i; + u8_t lseq, lseqi; + struct dns_table_entry *pEntry = NULL; + size_t namelen; + + /* search an unused entry, or the oldest one */ + lseq = lseqi = 0; + for (i = 0; i < DNS_TABLE_SIZE; ++i) { + pEntry = &dns_table[i]; + /* is it an unused entry ? */ + if (pEntry->state == DNS_STATE_UNUSED) + break; + + /* check if this is the oldest completed entry */ + if (pEntry->state == DNS_STATE_DONE) { + if ((dns_seqno - pEntry->seqno) > lseq) { + lseq = dns_seqno - pEntry->seqno; + lseqi = i; + } + } + } + + /* if we don't have found an unused entry, use the oldest completed one */ + if (i == DNS_TABLE_SIZE) { + if ((lseqi >= DNS_TABLE_SIZE) || (dns_table[lseqi].state != DNS_STATE_DONE)) { + /* no entry can't be used now, table is full */ + LWIP_DEBUGF(DNS_DEBUG, ("dns_enqueue: \"%s\": DNS entries table is full\n", name)); + return ERR_MEM; + } else { + /* use the oldest completed one */ + i = lseqi; + pEntry = &dns_table[i]; + } + } + + /* use this entry */ + LWIP_DEBUGF(DNS_DEBUG, ("dns_enqueue: \"%s\": use DNS entry %"U16_F"\n", name, (u16_t)(i))); + + /* fill the entry */ + pEntry->state = DNS_STATE_NEW; + pEntry->seqno = dns_seqno++; + pEntry->found = found; + pEntry->arg = callback_arg; + namelen = LWIP_MIN(strlen(name), DNS_MAX_NAME_LENGTH-1); + MEMCPY(pEntry->name, name, namelen); + pEntry->name[namelen] = 0; + + /* force to send query without waiting timer */ + dns_check_entry(i); + + /* dns query is enqueued */ + return ERR_INPROGRESS; +} + +/** + * Resolve a hostname (string) into an IP address. + * NON-BLOCKING callback version for use with raw API!!! + * + * Returns immediately with one of err_t return codes: + * - ERR_OK if hostname is a valid IP address string or the host + * name is already in the local names table. + * - ERR_INPROGRESS enqueue a request to be sent to the DNS server + * for resolution if no errors are present. + * - ERR_ARG: dns client not initialized or invalid hostname + * + * @param hostname the hostname that is to be queried + * @param addr pointer to a ip_addr_t where to store the address if it is already + * cached in the dns_table (only valid if ERR_OK is returned!) + * @param found a callback function to be called on success, failure or timeout (only if + * ERR_INPROGRESS is returned!) + * @param callback_arg argument to pass to the callback function + * @return a err_t return code. + */ +err_t +dns_gethostbyname(const char *hostname, ip_addr_t *addr, dns_found_callback found, + void *callback_arg) +{ + u32_t ipaddr; + /* not initialized or no valid server yet, or invalid addr pointer + * or invalid hostname or invalid hostname length */ + if ((dns_pcb == NULL) || (addr == NULL) || + (!hostname) || (!hostname[0]) || + (strlen(hostname) >= DNS_MAX_NAME_LENGTH)) { + return ERR_ARG; + } + +#if LWIP_HAVE_LOOPIF + if (strcmp(hostname, "localhost")==0) { + ip_addr_set_loopback(addr); + return ERR_OK; + } +#endif /* LWIP_HAVE_LOOPIF */ + + /* host name already in octet notation? set ip addr and return ERR_OK */ + ipaddr = ipaddr_addr(hostname); + if (ipaddr == IPADDR_NONE) { + /* already have this address cached? */ + ipaddr = dns_lookup(hostname); + } + if (ipaddr != IPADDR_NONE) { + ip4_addr_set_u32(addr, ipaddr); + return ERR_OK; + } + + /* queue query with specified callback */ + return dns_enqueue(hostname, found, callback_arg); +} + +#endif /* LWIP_DNS */ diff --git a/src/lwip-1.4.1/src/core/init.c b/src/lwip-1.4.1/src/core/init.c new file mode 100644 index 0000000..a7b15a7 --- /dev/null +++ b/src/lwip-1.4.1/src/core/init.c @@ -0,0 +1,332 @@ +/** + * @file + * Modules initialization + * + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#include "lwip/opt.h" + +#include "lwip/init.h" +#include "lwip/stats.h" +#include "lwip/sys.h" +#include "lwip/mem.h" +#include "lwip/memp.h" +#include "lwip/pbuf.h" +#include "lwip/netif.h" +#include "lwip/sockets.h" +#include "lwip/ip.h" +#include "lwip/raw.h" +#include "lwip/udp.h" +#include "lwip/tcp_impl.h" +#include "lwip/snmp_msg.h" +#include "lwip/autoip.h" +#include "lwip/igmp.h" +#include "lwip/dns.h" +#include "lwip/timers.h" +#include "netif/etharp.h" +#include "lwip/api.h" + +/* Compile-time sanity checks for configuration errors. + * These can be done independently of LWIP_DEBUG, without penalty. + */ +#ifndef BYTE_ORDER + #error "BYTE_ORDER is not defined, you have to define it in your cc.h" +#endif +#if (!IP_SOF_BROADCAST && IP_SOF_BROADCAST_RECV) + #error "If you want to use broadcast filter per pcb on recv operations, you have to define IP_SOF_BROADCAST=1 in your lwipopts.h" +#endif +#if (!LWIP_UDP && LWIP_UDPLITE) + #error "If you want to use UDP Lite, you have to define LWIP_UDP=1 in your lwipopts.h" +#endif +#if (!LWIP_UDP && LWIP_SNMP) + #error "If you want to use SNMP, you have to define LWIP_UDP=1 in your lwipopts.h" +#endif +#if (!LWIP_UDP && LWIP_DHCP) + #error "If you want to use DHCP, you have to define LWIP_UDP=1 in your lwipopts.h" +#endif +#if (!LWIP_UDP && LWIP_IGMP) + #error "If you want to use IGMP, you have to define LWIP_UDP=1 in your lwipopts.h" +#endif +#if (!LWIP_UDP && LWIP_SNMP) + #error "If you want to use SNMP, you have to define LWIP_UDP=1 in your lwipopts.h" +#endif +#if (!LWIP_UDP && LWIP_DNS) + #error "If you want to use DNS, you have to define LWIP_UDP=1 in your lwipopts.h" +#endif +#if !MEMP_MEM_MALLOC /* MEMP_NUM_* checks are disabled when not using the pool allocator */ +#if (LWIP_ARP && ARP_QUEUEING && (MEMP_NUM_ARP_QUEUE<=0)) + #error "If you want to use ARP Queueing, you have to define MEMP_NUM_ARP_QUEUE>=1 in your lwipopts.h" +#endif +#if (LWIP_RAW && (MEMP_NUM_RAW_PCB<=0)) + #error "If you want to use RAW, you have to define MEMP_NUM_RAW_PCB>=1 in your lwipopts.h" +#endif +#if (LWIP_UDP && (MEMP_NUM_UDP_PCB<=0)) + #error "If you want to use UDP, you have to define MEMP_NUM_UDP_PCB>=1 in your lwipopts.h" +#endif +#if (LWIP_TCP && (MEMP_NUM_TCP_PCB<=0)) + #error "If you want to use TCP, you have to define MEMP_NUM_TCP_PCB>=1 in your lwipopts.h" +#endif +#if (LWIP_IGMP && (MEMP_NUM_IGMP_GROUP<=1)) + #error "If you want to use IGMP, you have to define MEMP_NUM_IGMP_GROUP>1 in your lwipopts.h" +#endif +#if ((LWIP_NETCONN || LWIP_SOCKET) && (MEMP_NUM_TCPIP_MSG_API<=0)) + #error "If you want to use Sequential API, you have to define MEMP_NUM_TCPIP_MSG_API>=1 in your lwipopts.h" +#endif +/* There must be sufficient timeouts, taking into account requirements of the subsystems. */ +#if LWIP_TIMERS && (MEMP_NUM_SYS_TIMEOUT < (LWIP_TCP + IP_REASSEMBLY + LWIP_ARP + (2*LWIP_DHCP) + LWIP_AUTOIP + LWIP_IGMP + LWIP_DNS + PPP_SUPPORT)) + #error "MEMP_NUM_SYS_TIMEOUT is too low to accomodate all required timeouts" +#endif +#if (IP_REASSEMBLY && (MEMP_NUM_REASSDATA > IP_REASS_MAX_PBUFS)) + #error "MEMP_NUM_REASSDATA > IP_REASS_MAX_PBUFS doesn't make sense since each struct ip_reassdata must hold 2 pbufs at least!" +#endif +#endif /* !MEMP_MEM_MALLOC */ +#if (LWIP_TCP && (TCP_WND > 0xffff)) + #error "If you want to use TCP, TCP_WND must fit in an u16_t, so, you have to reduce it in your lwipopts.h" +#endif +#if (LWIP_TCP && (TCP_SND_QUEUELEN > 0xffff)) + #error "If you want to use TCP, TCP_SND_QUEUELEN must fit in an u16_t, so, you have to reduce it in your lwipopts.h" +#endif +#if (LWIP_TCP && (TCP_SND_QUEUELEN < 2)) + #error "TCP_SND_QUEUELEN must be at least 2 for no-copy TCP writes to work" +#endif +#if (LWIP_TCP && ((TCP_MAXRTX > 12) || (TCP_SYNMAXRTX > 12))) + #error "If you want to use TCP, TCP_MAXRTX and TCP_SYNMAXRTX must less or equal to 12 (due to tcp_backoff table), so, you have to reduce them in your lwipopts.h" +#endif +#if (LWIP_TCP && TCP_LISTEN_BACKLOG && (TCP_DEFAULT_LISTEN_BACKLOG < 0) || (TCP_DEFAULT_LISTEN_BACKLOG > 0xff)) + #error "If you want to use TCP backlog, TCP_DEFAULT_LISTEN_BACKLOG must fit into an u8_t" +#endif +#if (LWIP_NETIF_API && (NO_SYS==1)) + #error "If you want to use NETIF API, you have to define NO_SYS=0 in your lwipopts.h" +#endif +#if ((LWIP_SOCKET || LWIP_NETCONN) && (NO_SYS==1)) + #error "If you want to use Sequential API, you have to define NO_SYS=0 in your lwipopts.h" +#endif +#if (!LWIP_NETCONN && LWIP_SOCKET) + #error "If you want to use Socket API, you have to define LWIP_NETCONN=1 in your lwipopts.h" +#endif +#if (((!LWIP_DHCP) || (!LWIP_AUTOIP)) && LWIP_DHCP_AUTOIP_COOP) + #error "If you want to use DHCP/AUTOIP cooperation mode, you have to define LWIP_DHCP=1 and LWIP_AUTOIP=1 in your lwipopts.h" +#endif +#if (((!LWIP_DHCP) || (!LWIP_ARP)) && DHCP_DOES_ARP_CHECK) + #error "If you want to use DHCP ARP checking, you have to define LWIP_DHCP=1 and LWIP_ARP=1 in your lwipopts.h" +#endif +#if (!LWIP_ARP && LWIP_AUTOIP) + #error "If you want to use AUTOIP, you have to define LWIP_ARP=1 in your lwipopts.h" +#endif +#if (LWIP_SNMP && (SNMP_CONCURRENT_REQUESTS<=0)) + #error "If you want to use SNMP, you have to define SNMP_CONCURRENT_REQUESTS>=1 in your lwipopts.h" +#endif +#if (LWIP_SNMP && (SNMP_TRAP_DESTINATIONS<=0)) + #error "If you want to use SNMP, you have to define SNMP_TRAP_DESTINATIONS>=1 in your lwipopts.h" +#endif +#if (LWIP_TCP && ((LWIP_EVENT_API && LWIP_CALLBACK_API) || (!LWIP_EVENT_API && !LWIP_CALLBACK_API))) + #error "One and exactly one of LWIP_EVENT_API and LWIP_CALLBACK_API has to be enabled in your lwipopts.h" +#endif +#if (MEM_LIBC_MALLOC && MEM_USE_POOLS) + #error "MEM_LIBC_MALLOC and MEM_USE_POOLS may not both be simultaneously enabled in your lwipopts.h" +#endif +#if (MEM_USE_POOLS && !MEMP_USE_CUSTOM_POOLS) + #error "MEM_USE_POOLS requires custom pools (MEMP_USE_CUSTOM_POOLS) to be enabled in your lwipopts.h" +#endif +#if (PBUF_POOL_BUFSIZE <= MEM_ALIGNMENT) + #error "PBUF_POOL_BUFSIZE must be greater than MEM_ALIGNMENT or the offset may take the full first pbuf" +#endif +#if (DNS_LOCAL_HOSTLIST && !DNS_LOCAL_HOSTLIST_IS_DYNAMIC && !(defined(DNS_LOCAL_HOSTLIST_INIT))) + #error "you have to define define DNS_LOCAL_HOSTLIST_INIT {{'host1', 0x123}, {'host2', 0x234}} to initialize DNS_LOCAL_HOSTLIST" +#endif +#if PPP_SUPPORT && !PPPOS_SUPPORT & !PPPOE_SUPPORT + #error "PPP_SUPPORT needs either PPPOS_SUPPORT or PPPOE_SUPPORT turned on" +#endif +#if !LWIP_ETHERNET && (LWIP_ARP || PPPOE_SUPPORT) + #error "LWIP_ETHERNET needs to be turned on for LWIP_ARP or PPPOE_SUPPORT" +#endif +#if LWIP_IGMP && !defined(LWIP_RAND) + #error "When using IGMP, LWIP_RAND() needs to be defined to a random-function returning an u32_t random value" +#endif +#if LWIP_TCPIP_CORE_LOCKING_INPUT && !LWIP_TCPIP_CORE_LOCKING + #error "When using LWIP_TCPIP_CORE_LOCKING_INPUT, LWIP_TCPIP_CORE_LOCKING must be enabled, too" +#endif +#if LWIP_TCP && LWIP_NETIF_TX_SINGLE_PBUF && !TCP_OVERSIZE + #error "LWIP_NETIF_TX_SINGLE_PBUF needs TCP_OVERSIZE enabled to create single-pbuf TCP packets" +#endif +#if IP_FRAG && IP_FRAG_USES_STATIC_BUF && LWIP_NETIF_TX_SINGLE_PBUF + #error "LWIP_NETIF_TX_SINGLE_PBUF does not work with IP_FRAG_USES_STATIC_BUF==1 as that creates pbuf queues" +#endif +#if LWIP_NETCONN && LWIP_TCP +#if NETCONN_COPY != TCP_WRITE_FLAG_COPY + #error "NETCONN_COPY != TCP_WRITE_FLAG_COPY" +#endif +#if NETCONN_MORE != TCP_WRITE_FLAG_MORE + #error "NETCONN_MORE != TCP_WRITE_FLAG_MORE" +#endif +#endif /* LWIP_NETCONN && LWIP_TCP */ +#if LWIP_SOCKET +/* Check that the SO_* socket options and SOF_* lwIP-internal flags match */ +#if SO_ACCEPTCONN != SOF_ACCEPTCONN + #error "SO_ACCEPTCONN != SOF_ACCEPTCONN" +#endif +#if SO_REUSEADDR != SOF_REUSEADDR + #error "WARNING: SO_REUSEADDR != SOF_REUSEADDR" +#endif +#if SO_KEEPALIVE != SOF_KEEPALIVE + #error "WARNING: SO_KEEPALIVE != SOF_KEEPALIVE" +#endif +#if SO_BROADCAST != SOF_BROADCAST + #error "WARNING: SO_BROADCAST != SOF_BROADCAST" +#endif +#if SO_LINGER != SOF_LINGER + #error "WARNING: SO_LINGER != SOF_LINGER" +#endif +#endif /* LWIP_SOCKET */ + + +/* Compile-time checks for deprecated options. + */ +#ifdef MEMP_NUM_TCPIP_MSG + #error "MEMP_NUM_TCPIP_MSG option is deprecated. Remove it from your lwipopts.h." +#endif +#ifdef MEMP_NUM_API_MSG + #error "MEMP_NUM_API_MSG option is deprecated. Remove it from your lwipopts.h." +#endif +#ifdef TCP_REXMIT_DEBUG + #error "TCP_REXMIT_DEBUG option is deprecated. Remove it from your lwipopts.h." +#endif +#ifdef RAW_STATS + #error "RAW_STATS option is deprecated. Remove it from your lwipopts.h." +#endif +#ifdef ETHARP_QUEUE_FIRST + #error "ETHARP_QUEUE_FIRST option is deprecated. Remove it from your lwipopts.h." +#endif +#ifdef ETHARP_ALWAYS_INSERT + #error "ETHARP_ALWAYS_INSERT option is deprecated. Remove it from your lwipopts.h." +#endif + +#ifndef LWIP_DISABLE_TCP_SANITY_CHECKS +#define LWIP_DISABLE_TCP_SANITY_CHECKS 0 +#endif +#ifndef LWIP_DISABLE_MEMP_SANITY_CHECKS +#define LWIP_DISABLE_MEMP_SANITY_CHECKS 0 +#endif + +/* MEMP sanity checks */ +#if !LWIP_DISABLE_MEMP_SANITY_CHECKS +#if LWIP_NETCONN +#if MEMP_MEM_MALLOC +#if !MEMP_NUM_NETCONN && LWIP_SOCKET +#error "lwip_sanity_check: WARNING: MEMP_NUM_NETCONN cannot be 0 when using sockets!" +#endif +#else /* MEMP_MEM_MALLOC */ +#if MEMP_NUM_NETCONN > (MEMP_NUM_TCP_PCB+MEMP_NUM_TCP_PCB_LISTEN+MEMP_NUM_UDP_PCB+MEMP_NUM_RAW_PCB) +#error "lwip_sanity_check: WARNING: MEMP_NUM_NETCONN should be less than the sum of MEMP_NUM_{TCP,RAW,UDP}_PCB+MEMP_NUM_TCP_PCB_LISTEN. If you know what you are doing, define LWIP_DISABLE_MEMP_SANITY_CHECKS to 1 to disable this error." +#endif +#endif /* MEMP_MEM_MALLOC */ +#endif /* LWIP_NETCONN */ +#endif /* !LWIP_DISABLE_MEMP_SANITY_CHECKS */ + +/* TCP sanity checks */ +#if !LWIP_DISABLE_TCP_SANITY_CHECKS +#if LWIP_TCP +#if !MEMP_MEM_MALLOC && (MEMP_NUM_TCP_SEG < TCP_SND_QUEUELEN) + #error "lwip_sanity_check: WARNING: MEMP_NUM_TCP_SEG should be at least as big as TCP_SND_QUEUELEN. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error." +#endif +#if TCP_SND_BUF < (2 * TCP_MSS) + #error "lwip_sanity_check: WARNING: TCP_SND_BUF must be at least as much as (2 * TCP_MSS) for things to work smoothly. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error." +#endif +#if TCP_SND_QUEUELEN < (2 * (TCP_SND_BUF / TCP_MSS)) + #error "lwip_sanity_check: WARNING: TCP_SND_QUEUELEN must be at least as much as (2 * TCP_SND_BUF/TCP_MSS) for things to work. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error." +#endif +#if TCP_SNDLOWAT >= TCP_SND_BUF + #error "lwip_sanity_check: WARNING: TCP_SNDLOWAT must be less than TCP_SND_BUF. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error." +#endif +#if TCP_SNDQUEUELOWAT >= TCP_SND_QUEUELEN + #error "lwip_sanity_check: WARNING: TCP_SNDQUEUELOWAT must be less than TCP_SND_QUEUELEN. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error." +#endif +#if !MEMP_MEM_MALLOC && (TCP_WND > (PBUF_POOL_SIZE * (PBUF_POOL_BUFSIZE - (PBUF_LINK_HLEN + PBUF_IP_HLEN + PBUF_TRANSPORT_HLEN)))) + #error "lwip_sanity_check: WARNING: TCP_WND is larger than space provided by PBUF_POOL_SIZE * (PBUF_POOL_BUFSIZE - protocol headers). If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error." +#endif +#if TCP_WND < TCP_MSS + #error "lwip_sanity_check: WARNING: TCP_WND is smaller than MSS. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error." +#endif +#endif /* LWIP_TCP */ +#endif /* !LWIP_DISABLE_TCP_SANITY_CHECKS */ + +/** + * Perform Sanity check of user-configurable values, and initialize all modules. + */ +void +lwip_init(void) +{ + /* Modules initialization */ + stats_init(); +#if !NO_SYS + sys_init(); +#endif /* !NO_SYS */ + mem_init(); + memp_init(); + pbuf_init(); + netif_init(); +#if LWIP_SOCKET + lwip_socket_init(); +#endif /* LWIP_SOCKET */ + ip_init(); +#if LWIP_ARP + etharp_init(); +#endif /* LWIP_ARP */ +#if LWIP_RAW + raw_init(); +#endif /* LWIP_RAW */ +#if LWIP_UDP + udp_init(); +#endif /* LWIP_UDP */ +#if LWIP_TCP + tcp_init(); +#endif /* LWIP_TCP */ +#if LWIP_SNMP + snmp_init(); +#endif /* LWIP_SNMP */ +#if LWIP_AUTOIP + autoip_init(); +#endif /* LWIP_AUTOIP */ +#if LWIP_IGMP + igmp_init(); +#endif /* LWIP_IGMP */ +#if LWIP_DNS + dns_init(); +#endif /* LWIP_DNS */ + +#if LWIP_TIMERS + sys_timeouts_init(); +#endif /* LWIP_TIMERS */ +} diff --git a/src/lwip-1.4.1/src/core/ipv4/autoip.c b/src/lwip-1.4.1/src/core/ipv4/autoip.c new file mode 100644 index 0000000..b122da2 --- /dev/null +++ b/src/lwip-1.4.1/src/core/ipv4/autoip.c @@ -0,0 +1,528 @@ +/** + * @file + * AutoIP Automatic LinkLocal IP Configuration + * + */ + +/* + * + * Copyright (c) 2007 Dominik Spies + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * Author: Dominik Spies + * + * This is a AutoIP implementation for the lwIP TCP/IP stack. It aims to conform + * with RFC 3927. + * + * + * Please coordinate changes and requests with Dominik Spies + * + */ + +/******************************************************************************* + * USAGE: + * + * define LWIP_AUTOIP 1 in your lwipopts.h + * + * If you don't use tcpip.c (so, don't call, you don't call tcpip_init): + * - First, call autoip_init(). + * - call autoip_tmr() all AUTOIP_TMR_INTERVAL msces, + * that should be defined in autoip.h. + * I recommend a value of 100. The value must divide 1000 with a remainder almost 0. + * Possible values are 1000, 500, 333, 250, 200, 166, 142, 125, 111, 100 .... + * + * Without DHCP: + * - Call autoip_start() after netif_add(). + * + * With DHCP: + * - define LWIP_DHCP_AUTOIP_COOP 1 in your lwipopts.h. + * - Configure your DHCP Client. + * + */ + +#include "lwip/opt.h" + +#if LWIP_AUTOIP /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/mem.h" +#include "lwip/udp.h" +#include "lwip/ip_addr.h" +#include "lwip/netif.h" +#include "lwip/autoip.h" +#include "netif/etharp.h" + +#include +#include + +/* 169.254.0.0 */ +#define AUTOIP_NET 0xA9FE0000 +/* 169.254.1.0 */ +#define AUTOIP_RANGE_START (AUTOIP_NET | 0x0100) +/* 169.254.254.255 */ +#define AUTOIP_RANGE_END (AUTOIP_NET | 0xFEFF) + + +/** Pseudo random macro based on netif informations. + * You could use "rand()" from the C Library if you define LWIP_AUTOIP_RAND in lwipopts.h */ +#ifndef LWIP_AUTOIP_RAND +#define LWIP_AUTOIP_RAND(netif) ( (((u32_t)((netif->hwaddr[5]) & 0xff) << 24) | \ + ((u32_t)((netif->hwaddr[3]) & 0xff) << 16) | \ + ((u32_t)((netif->hwaddr[2]) & 0xff) << 8) | \ + ((u32_t)((netif->hwaddr[4]) & 0xff))) + \ + (netif->autoip?netif->autoip->tried_llipaddr:0)) +#endif /* LWIP_AUTOIP_RAND */ + +/** + * Macro that generates the initial IP address to be tried by AUTOIP. + * If you want to override this, define it to something else in lwipopts.h. + */ +#ifndef LWIP_AUTOIP_CREATE_SEED_ADDR +#define LWIP_AUTOIP_CREATE_SEED_ADDR(netif) \ + htonl(AUTOIP_RANGE_START + ((u32_t)(((u8_t)(netif->hwaddr[4])) | \ + ((u32_t)((u8_t)(netif->hwaddr[5]))) << 8))) +#endif /* LWIP_AUTOIP_CREATE_SEED_ADDR */ + +/* static functions */ +static void autoip_handle_arp_conflict(struct netif *netif); + +/* creates a pseudo random LL IP-Address for a network interface */ +static void autoip_create_addr(struct netif *netif, ip_addr_t *ipaddr); + +/* sends an ARP probe */ +static err_t autoip_arp_probe(struct netif *netif); + +/* sends an ARP announce */ +static err_t autoip_arp_announce(struct netif *netif); + +/* configure interface for use with current LL IP-Address */ +static err_t autoip_bind(struct netif *netif); + +/* start sending probes for llipaddr */ +static void autoip_start_probing(struct netif *netif); + + +/** Set a statically allocated struct autoip to work with. + * Using this prevents autoip_start to allocate it using mem_malloc. + * + * @param netif the netif for which to set the struct autoip + * @param dhcp (uninitialised) dhcp struct allocated by the application + */ +void +autoip_set_struct(struct netif *netif, struct autoip *autoip) +{ + LWIP_ASSERT("netif != NULL", netif != NULL); + LWIP_ASSERT("autoip != NULL", autoip != NULL); + LWIP_ASSERT("netif already has a struct autoip set", netif->autoip == NULL); + + /* clear data structure */ + memset(autoip, 0, sizeof(struct autoip)); + /* autoip->state = AUTOIP_STATE_OFF; */ + netif->autoip = autoip; +} + +/** Restart AutoIP client and check the next address (conflict detected) + * + * @param netif The netif under AutoIP control + */ +static void +autoip_restart(struct netif *netif) +{ + netif->autoip->tried_llipaddr++; + autoip_start(netif); +} + +/** + * Handle a IP address conflict after an ARP conflict detection + */ +static void +autoip_handle_arp_conflict(struct netif *netif) +{ + /* Somehow detect if we are defending or retreating */ + unsigned char defend = 1; /* tbd */ + + if (defend) { + if (netif->autoip->lastconflict > 0) { + /* retreat, there was a conflicting ARP in the last + * DEFEND_INTERVAL seconds + */ + LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, + ("autoip_handle_arp_conflict(): we are defending, but in DEFEND_INTERVAL, retreating\n")); + + /* TODO: close all TCP sessions */ + autoip_restart(netif); + } else { + LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, + ("autoip_handle_arp_conflict(): we are defend, send ARP Announce\n")); + autoip_arp_announce(netif); + netif->autoip->lastconflict = DEFEND_INTERVAL * AUTOIP_TICKS_PER_SECOND; + } + } else { + LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, + ("autoip_handle_arp_conflict(): we do not defend, retreating\n")); + /* TODO: close all TCP sessions */ + autoip_restart(netif); + } +} + +/** + * Create an IP-Address out of range 169.254.1.0 to 169.254.254.255 + * + * @param netif network interface on which create the IP-Address + * @param ipaddr ip address to initialize + */ +static void +autoip_create_addr(struct netif *netif, ip_addr_t *ipaddr) +{ + /* Here we create an IP-Address out of range 169.254.1.0 to 169.254.254.255 + * compliant to RFC 3927 Section 2.1 + * We have 254 * 256 possibilities */ + + u32_t addr = ntohl(LWIP_AUTOIP_CREATE_SEED_ADDR(netif)); + addr += netif->autoip->tried_llipaddr; + addr = AUTOIP_NET | (addr & 0xffff); + /* Now, 169.254.0.0 <= addr <= 169.254.255.255 */ + + if (addr < AUTOIP_RANGE_START) { + addr += AUTOIP_RANGE_END - AUTOIP_RANGE_START + 1; + } + if (addr > AUTOIP_RANGE_END) { + addr -= AUTOIP_RANGE_END - AUTOIP_RANGE_START + 1; + } + LWIP_ASSERT("AUTOIP address not in range", (addr >= AUTOIP_RANGE_START) && + (addr <= AUTOIP_RANGE_END)); + ip4_addr_set_u32(ipaddr, htonl(addr)); + + LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, + ("autoip_create_addr(): tried_llipaddr=%"U16_F", %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", + (u16_t)(netif->autoip->tried_llipaddr), ip4_addr1_16(ipaddr), ip4_addr2_16(ipaddr), + ip4_addr3_16(ipaddr), ip4_addr4_16(ipaddr))); +} + +/** + * Sends an ARP probe from a network interface + * + * @param netif network interface used to send the probe + */ +static err_t +autoip_arp_probe(struct netif *netif) +{ + return etharp_raw(netif, (struct eth_addr *)netif->hwaddr, ðbroadcast, + (struct eth_addr *)netif->hwaddr, IP_ADDR_ANY, ðzero, + &netif->autoip->llipaddr, ARP_REQUEST); +} + +/** + * Sends an ARP announce from a network interface + * + * @param netif network interface used to send the announce + */ +static err_t +autoip_arp_announce(struct netif *netif) +{ + return etharp_raw(netif, (struct eth_addr *)netif->hwaddr, ðbroadcast, + (struct eth_addr *)netif->hwaddr, &netif->autoip->llipaddr, ðzero, + &netif->autoip->llipaddr, ARP_REQUEST); +} + +/** + * Configure interface for use with current LL IP-Address + * + * @param netif network interface to configure with current LL IP-Address + */ +static err_t +autoip_bind(struct netif *netif) +{ + struct autoip *autoip = netif->autoip; + ip_addr_t sn_mask, gw_addr; + + LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, + ("autoip_bind(netif=%p) %c%c%"U16_F" %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", + (void*)netif, netif->name[0], netif->name[1], (u16_t)netif->num, + ip4_addr1_16(&autoip->llipaddr), ip4_addr2_16(&autoip->llipaddr), + ip4_addr3_16(&autoip->llipaddr), ip4_addr4_16(&autoip->llipaddr))); + + IP4_ADDR(&sn_mask, 255, 255, 0, 0); + IP4_ADDR(&gw_addr, 0, 0, 0, 0); + + netif_set_ipaddr(netif, &autoip->llipaddr); + netif_set_netmask(netif, &sn_mask); + netif_set_gw(netif, &gw_addr); + + /* bring the interface up */ + netif_set_up(netif); + + return ERR_OK; +} + +/** + * Start AutoIP client + * + * @param netif network interface on which start the AutoIP client + */ +err_t +autoip_start(struct netif *netif) +{ + struct autoip *autoip = netif->autoip; + err_t result = ERR_OK; + + if (netif_is_up(netif)) { + netif_set_down(netif); + } + + /* Set IP-Address, Netmask and Gateway to 0 to make sure that + * ARP Packets are formed correctly + */ + ip_addr_set_zero(&netif->ip_addr); + ip_addr_set_zero(&netif->netmask); + ip_addr_set_zero(&netif->gw); + + LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, + ("autoip_start(netif=%p) %c%c%"U16_F"\n", (void*)netif, netif->name[0], + netif->name[1], (u16_t)netif->num)); + if (autoip == NULL) { + /* no AutoIP client attached yet? */ + LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, + ("autoip_start(): starting new AUTOIP client\n")); + autoip = (struct autoip *)mem_malloc(sizeof(struct autoip)); + if (autoip == NULL) { + LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, + ("autoip_start(): could not allocate autoip\n")); + return ERR_MEM; + } + memset(autoip, 0, sizeof(struct autoip)); + /* store this AutoIP client in the netif */ + netif->autoip = autoip; + LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, ("autoip_start(): allocated autoip")); + } else { + autoip->state = AUTOIP_STATE_OFF; + autoip->ttw = 0; + autoip->sent_num = 0; + ip_addr_set_zero(&autoip->llipaddr); + autoip->lastconflict = 0; + } + + autoip_create_addr(netif, &(autoip->llipaddr)); + autoip_start_probing(netif); + + return result; +} + +static void +autoip_start_probing(struct netif *netif) +{ + struct autoip *autoip = netif->autoip; + + autoip->state = AUTOIP_STATE_PROBING; + autoip->sent_num = 0; + LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, + ("autoip_start_probing(): changing state to PROBING: %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", + ip4_addr1_16(&netif->autoip->llipaddr), ip4_addr2_16(&netif->autoip->llipaddr), + ip4_addr3_16(&netif->autoip->llipaddr), ip4_addr4_16(&netif->autoip->llipaddr))); + + /* time to wait to first probe, this is randomly + * choosen out of 0 to PROBE_WAIT seconds. + * compliant to RFC 3927 Section 2.2.1 + */ + autoip->ttw = (u16_t)(LWIP_AUTOIP_RAND(netif) % (PROBE_WAIT * AUTOIP_TICKS_PER_SECOND)); + + /* + * if we tried more then MAX_CONFLICTS we must limit our rate for + * accquiring and probing address + * compliant to RFC 3927 Section 2.2.1 + */ + if (autoip->tried_llipaddr > MAX_CONFLICTS) { + autoip->ttw = RATE_LIMIT_INTERVAL * AUTOIP_TICKS_PER_SECOND; + } +} + +/** + * Handle a possible change in the network configuration. + * + * If there is an AutoIP address configured, take the interface down + * and begin probing with the same address. + */ +void +autoip_network_changed(struct netif *netif) +{ + if (netif->autoip && netif->autoip->state != AUTOIP_STATE_OFF) { + netif_set_down(netif); + autoip_start_probing(netif); + } +} + +/** + * Stop AutoIP client + * + * @param netif network interface on which stop the AutoIP client + */ +err_t +autoip_stop(struct netif *netif) +{ + netif->autoip->state = AUTOIP_STATE_OFF; + netif_set_down(netif); + return ERR_OK; +} + +/** + * Has to be called in loop every AUTOIP_TMR_INTERVAL milliseconds + */ +void +autoip_tmr() +{ + struct netif *netif = netif_list; + /* loop through netif's */ + while (netif != NULL) { + /* only act on AutoIP configured interfaces */ + if (netif->autoip != NULL) { + if (netif->autoip->lastconflict > 0) { + netif->autoip->lastconflict--; + } + + LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, + ("autoip_tmr() AutoIP-State: %"U16_F", ttw=%"U16_F"\n", + (u16_t)(netif->autoip->state), netif->autoip->ttw)); + + switch(netif->autoip->state) { + case AUTOIP_STATE_PROBING: + if (netif->autoip->ttw > 0) { + netif->autoip->ttw--; + } else { + if (netif->autoip->sent_num >= PROBE_NUM) { + netif->autoip->state = AUTOIP_STATE_ANNOUNCING; + netif->autoip->sent_num = 0; + netif->autoip->ttw = ANNOUNCE_WAIT * AUTOIP_TICKS_PER_SECOND; + LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, + ("autoip_tmr(): changing state to ANNOUNCING: %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", + ip4_addr1_16(&netif->autoip->llipaddr), ip4_addr2_16(&netif->autoip->llipaddr), + ip4_addr3_16(&netif->autoip->llipaddr), ip4_addr4_16(&netif->autoip->llipaddr))); + } else { + autoip_arp_probe(netif); + LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, + ("autoip_tmr() PROBING Sent Probe\n")); + netif->autoip->sent_num++; + /* calculate time to wait to next probe */ + netif->autoip->ttw = (u16_t)((LWIP_AUTOIP_RAND(netif) % + ((PROBE_MAX - PROBE_MIN) * AUTOIP_TICKS_PER_SECOND) ) + + PROBE_MIN * AUTOIP_TICKS_PER_SECOND); + } + } + break; + + case AUTOIP_STATE_ANNOUNCING: + if (netif->autoip->ttw > 0) { + netif->autoip->ttw--; + } else { + if (netif->autoip->sent_num == 0) { + /* We are here the first time, so we waited ANNOUNCE_WAIT seconds + * Now we can bind to an IP address and use it. + * + * autoip_bind calls netif_set_up. This triggers a gratuitous ARP + * which counts as an announcement. + */ + autoip_bind(netif); + } else { + autoip_arp_announce(netif); + LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, + ("autoip_tmr() ANNOUNCING Sent Announce\n")); + } + netif->autoip->ttw = ANNOUNCE_INTERVAL * AUTOIP_TICKS_PER_SECOND; + netif->autoip->sent_num++; + + if (netif->autoip->sent_num >= ANNOUNCE_NUM) { + netif->autoip->state = AUTOIP_STATE_BOUND; + netif->autoip->sent_num = 0; + netif->autoip->ttw = 0; + LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, + ("autoip_tmr(): changing state to BOUND: %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", + ip4_addr1_16(&netif->autoip->llipaddr), ip4_addr2_16(&netif->autoip->llipaddr), + ip4_addr3_16(&netif->autoip->llipaddr), ip4_addr4_16(&netif->autoip->llipaddr))); + } + } + break; + } + } + /* proceed to next network interface */ + netif = netif->next; + } +} + +/** + * Handles every incoming ARP Packet, called by etharp_arp_input. + * + * @param netif network interface to use for autoip processing + * @param hdr Incoming ARP packet + */ +void +autoip_arp_reply(struct netif *netif, struct etharp_hdr *hdr) +{ + LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, ("autoip_arp_reply()\n")); + if ((netif->autoip != NULL) && (netif->autoip->state != AUTOIP_STATE_OFF)) { + /* when ip.src == llipaddr && hw.src != netif->hwaddr + * + * when probing ip.dst == llipaddr && hw.src != netif->hwaddr + * we have a conflict and must solve it + */ + ip_addr_t sipaddr, dipaddr; + struct eth_addr netifaddr; + ETHADDR16_COPY(netifaddr.addr, netif->hwaddr); + + /* Copy struct ip_addr2 to aligned ip_addr, to support compilers without + * structure packing (not using structure copy which breaks strict-aliasing rules). + */ + IPADDR2_COPY(&sipaddr, &hdr->sipaddr); + IPADDR2_COPY(&dipaddr, &hdr->dipaddr); + + if ((netif->autoip->state == AUTOIP_STATE_PROBING) || + ((netif->autoip->state == AUTOIP_STATE_ANNOUNCING) && + (netif->autoip->sent_num == 0))) { + /* RFC 3927 Section 2.2.1: + * from beginning to after ANNOUNCE_WAIT + * seconds we have a conflict if + * ip.src == llipaddr OR + * ip.dst == llipaddr && hw.src != own hwaddr + */ + if ((ip_addr_cmp(&sipaddr, &netif->autoip->llipaddr)) || + (ip_addr_cmp(&dipaddr, &netif->autoip->llipaddr) && + !eth_addr_cmp(&netifaddr, &hdr->shwaddr))) { + LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE | LWIP_DBG_LEVEL_WARNING, + ("autoip_arp_reply(): Probe Conflict detected\n")); + autoip_restart(netif); + } + } else { + /* RFC 3927 Section 2.5: + * in any state we have a conflict if + * ip.src == llipaddr && hw.src != own hwaddr + */ + if (ip_addr_cmp(&sipaddr, &netif->autoip->llipaddr) && + !eth_addr_cmp(&netifaddr, &hdr->shwaddr)) { + LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE | LWIP_DBG_LEVEL_WARNING, + ("autoip_arp_reply(): Conflicting ARP-Packet detected\n")); + autoip_handle_arp_conflict(netif); + } + } + } +} + +#endif /* LWIP_AUTOIP */ diff --git a/src/lwip-1.4.1/src/core/ipv4/icmp.c b/src/lwip-1.4.1/src/core/ipv4/icmp.c new file mode 100644 index 0000000..47ba857 --- /dev/null +++ b/src/lwip-1.4.1/src/core/ipv4/icmp.c @@ -0,0 +1,339 @@ +/** + * @file + * ICMP - Internet Control Message Protocol + * + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +/* Some ICMP messages should be passed to the transport protocols. This + is not implemented. */ + +#include "lwip/opt.h" + +#if LWIP_ICMP /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/icmp.h" +#include "lwip/inet_chksum.h" +#include "lwip/ip.h" +#include "lwip/def.h" +#include "lwip/stats.h" +#include "lwip/snmp.h" + +#include + +/** Small optimization: set to 0 if incoming PBUF_POOL pbuf always can be + * used to modify and send a response packet (and to 1 if this is not the case, + * e.g. when link header is stripped of when receiving) */ +#ifndef LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN +#define LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN 1 +#endif /* LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN */ + +/* The amount of data from the original packet to return in a dest-unreachable */ +#define ICMP_DEST_UNREACH_DATASIZE 8 + +static void icmp_send_response(struct pbuf *p, u8_t type, u8_t code); + +/** + * Processes ICMP input packets, called from ip_input(). + * + * Currently only processes icmp echo requests and sends + * out the echo response. + * + * @param p the icmp echo request packet, p->payload pointing to the ip header + * @param inp the netif on which this packet was received + */ +void +icmp_input(struct pbuf *p, struct netif *inp) +{ + u8_t type; +#ifdef LWIP_DEBUG + u8_t code; +#endif /* LWIP_DEBUG */ + struct icmp_echo_hdr *iecho; + struct ip_hdr *iphdr; + s16_t hlen; + + ICMP_STATS_INC(icmp.recv); + snmp_inc_icmpinmsgs(); + + + iphdr = (struct ip_hdr *)p->payload; + hlen = IPH_HL(iphdr) * 4; + if (pbuf_header(p, -hlen) || (p->tot_len < sizeof(u16_t)*2)) { + LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: short ICMP (%"U16_F" bytes) received\n", p->tot_len)); + goto lenerr; + } + + type = *((u8_t *)p->payload); +#ifdef LWIP_DEBUG + code = *(((u8_t *)p->payload)+1); +#endif /* LWIP_DEBUG */ + switch (type) { + case ICMP_ER: + /* This is OK, echo reply might have been parsed by a raw PCB + (as obviously, an echo request has been sent, too). */ + break; + case ICMP_ECHO: +#if !LWIP_MULTICAST_PING || !LWIP_BROADCAST_PING + { + int accepted = 1; +#if !LWIP_MULTICAST_PING + /* multicast destination address? */ + if (ip_addr_ismulticast(¤t_iphdr_dest)) { + accepted = 0; + } +#endif /* LWIP_MULTICAST_PING */ +#if !LWIP_BROADCAST_PING + /* broadcast destination address? */ + if (ip_addr_isbroadcast(¤t_iphdr_dest, inp)) { + accepted = 0; + } +#endif /* LWIP_BROADCAST_PING */ + /* broadcast or multicast destination address not acceptd? */ + if (!accepted) { + LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: Not echoing to multicast or broadcast pings\n")); + ICMP_STATS_INC(icmp.err); + pbuf_free(p); + return; + } + } +#endif /* !LWIP_MULTICAST_PING || !LWIP_BROADCAST_PING */ + LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: ping\n")); + if (p->tot_len < sizeof(struct icmp_echo_hdr)) { + LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: bad ICMP echo received\n")); + goto lenerr; + } + if (inet_chksum_pbuf(p) != 0) { + LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: checksum failed for received ICMP echo\n")); + pbuf_free(p); + ICMP_STATS_INC(icmp.chkerr); + snmp_inc_icmpinerrors(); + return; + } +#if LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN + if (pbuf_header(p, (PBUF_IP_HLEN + PBUF_LINK_HLEN))) { + /* p is not big enough to contain link headers + * allocate a new one and copy p into it + */ + struct pbuf *r; + /* switch p->payload to ip header */ + if (pbuf_header(p, hlen)) { + LWIP_ASSERT("icmp_input: moving p->payload to ip header failed\n", 0); + goto memerr; + } + /* allocate new packet buffer with space for link headers */ + r = pbuf_alloc(PBUF_LINK, p->tot_len, PBUF_RAM); + if (r == NULL) { + LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: allocating new pbuf failed\n")); + goto memerr; + } + LWIP_ASSERT("check that first pbuf can hold struct the ICMP header", + (r->len >= hlen + sizeof(struct icmp_echo_hdr))); + /* copy the whole packet including ip header */ + if (pbuf_copy(r, p) != ERR_OK) { + LWIP_ASSERT("icmp_input: copying to new pbuf failed\n", 0); + goto memerr; + } + iphdr = (struct ip_hdr *)r->payload; + /* switch r->payload back to icmp header */ + if (pbuf_header(r, -hlen)) { + LWIP_ASSERT("icmp_input: restoring original p->payload failed\n", 0); + goto memerr; + } + /* free the original p */ + pbuf_free(p); + /* we now have an identical copy of p that has room for link headers */ + p = r; + } else { + /* restore p->payload to point to icmp header */ + if (pbuf_header(p, -(s16_t)(PBUF_IP_HLEN + PBUF_LINK_HLEN))) { + LWIP_ASSERT("icmp_input: restoring original p->payload failed\n", 0); + goto memerr; + } + } +#endif /* LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN */ + /* At this point, all checks are OK. */ + /* We generate an answer by switching the dest and src ip addresses, + * setting the icmp type to ECHO_RESPONSE and updating the checksum. */ + iecho = (struct icmp_echo_hdr *)p->payload; + ip_addr_copy(iphdr->src, *ip_current_dest_addr()); + ip_addr_copy(iphdr->dest, *ip_current_src_addr()); + ICMPH_TYPE_SET(iecho, ICMP_ER); +#if CHECKSUM_GEN_ICMP + /* adjust the checksum */ + if (iecho->chksum >= PP_HTONS(0xffffU - (ICMP_ECHO << 8))) { + iecho->chksum += PP_HTONS(ICMP_ECHO << 8) + 1; + } else { + iecho->chksum += PP_HTONS(ICMP_ECHO << 8); + } +#else /* CHECKSUM_GEN_ICMP */ + iecho->chksum = 0; +#endif /* CHECKSUM_GEN_ICMP */ + + /* Set the correct TTL and recalculate the header checksum. */ + IPH_TTL_SET(iphdr, ICMP_TTL); + IPH_CHKSUM_SET(iphdr, 0); +#if CHECKSUM_GEN_IP + IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, IP_HLEN)); +#endif /* CHECKSUM_GEN_IP */ + + ICMP_STATS_INC(icmp.xmit); + /* increase number of messages attempted to send */ + snmp_inc_icmpoutmsgs(); + /* increase number of echo replies attempted to send */ + snmp_inc_icmpoutechoreps(); + + if(pbuf_header(p, hlen)) { + LWIP_ASSERT("Can't move over header in packet", 0); + } else { + err_t ret; + /* send an ICMP packet, src addr is the dest addr of the curren packet */ + ret = ip_output_if(p, ip_current_dest_addr(), IP_HDRINCL, + ICMP_TTL, 0, IP_PROTO_ICMP, inp); + if (ret != ERR_OK) { + LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: ip_output_if returned an error: %c.\n", ret)); + } + } + break; + default: + LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: ICMP type %"S16_F" code %"S16_F" not supported.\n", + (s16_t)type, (s16_t)code)); + ICMP_STATS_INC(icmp.proterr); + ICMP_STATS_INC(icmp.drop); + } + pbuf_free(p); + return; +lenerr: + pbuf_free(p); + ICMP_STATS_INC(icmp.lenerr); + snmp_inc_icmpinerrors(); + return; +#if LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN +memerr: + pbuf_free(p); + ICMP_STATS_INC(icmp.err); + snmp_inc_icmpinerrors(); + return; +#endif /* LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN */ +} + +/** + * Send an icmp 'destination unreachable' packet, called from ip_input() if + * the transport layer protocol is unknown and from udp_input() if the local + * port is not bound. + * + * @param p the input packet for which the 'unreachable' should be sent, + * p->payload pointing to the IP header + * @param t type of the 'unreachable' packet + */ +void +icmp_dest_unreach(struct pbuf *p, enum icmp_dur_type t) +{ + icmp_send_response(p, ICMP_DUR, t); +} + +#if IP_FORWARD || IP_REASSEMBLY +/** + * Send a 'time exceeded' packet, called from ip_forward() if TTL is 0. + * + * @param p the input packet for which the 'time exceeded' should be sent, + * p->payload pointing to the IP header + * @param t type of the 'time exceeded' packet + */ +void +icmp_time_exceeded(struct pbuf *p, enum icmp_te_type t) +{ + icmp_send_response(p, ICMP_TE, t); +} + +#endif /* IP_FORWARD || IP_REASSEMBLY */ + +/** + * Send an icmp packet in response to an incoming packet. + * + * @param p the input packet for which the 'unreachable' should be sent, + * p->payload pointing to the IP header + * @param type Type of the ICMP header + * @param code Code of the ICMP header + */ +static void +icmp_send_response(struct pbuf *p, u8_t type, u8_t code) +{ + struct pbuf *q; + struct ip_hdr *iphdr; + /* we can use the echo header here */ + struct icmp_echo_hdr *icmphdr; + ip_addr_t iphdr_src; + + /* ICMP header + IP header + 8 bytes of data */ + q = pbuf_alloc(PBUF_IP, sizeof(struct icmp_echo_hdr) + IP_HLEN + ICMP_DEST_UNREACH_DATASIZE, + PBUF_RAM); + if (q == NULL) { + LWIP_DEBUGF(ICMP_DEBUG, ("icmp_time_exceeded: failed to allocate pbuf for ICMP packet.\n")); + return; + } + LWIP_ASSERT("check that first pbuf can hold icmp message", + (q->len >= (sizeof(struct icmp_echo_hdr) + IP_HLEN + ICMP_DEST_UNREACH_DATASIZE))); + + iphdr = (struct ip_hdr *)p->payload; + LWIP_DEBUGF(ICMP_DEBUG, ("icmp_time_exceeded from ")); + ip_addr_debug_print(ICMP_DEBUG, &(iphdr->src)); + LWIP_DEBUGF(ICMP_DEBUG, (" to ")); + ip_addr_debug_print(ICMP_DEBUG, &(iphdr->dest)); + LWIP_DEBUGF(ICMP_DEBUG, ("\n")); + + icmphdr = (struct icmp_echo_hdr *)q->payload; + icmphdr->type = type; + icmphdr->code = code; + icmphdr->id = 0; + icmphdr->seqno = 0; + + /* copy fields from original packet */ + SMEMCPY((u8_t *)q->payload + sizeof(struct icmp_echo_hdr), (u8_t *)p->payload, + IP_HLEN + ICMP_DEST_UNREACH_DATASIZE); + + /* calculate checksum */ + icmphdr->chksum = 0; + icmphdr->chksum = inet_chksum(icmphdr, q->len); + ICMP_STATS_INC(icmp.xmit); + /* increase number of messages attempted to send */ + snmp_inc_icmpoutmsgs(); + /* increase number of destination unreachable messages attempted to send */ + snmp_inc_icmpouttimeexcds(); + ip_addr_copy(iphdr_src, iphdr->src); + ip_output(q, NULL, &iphdr_src, ICMP_TTL, 0, IP_PROTO_ICMP); + pbuf_free(q); +} + +#endif /* LWIP_ICMP */ diff --git a/src/lwip-1.4.1/src/core/ipv4/igmp.c b/src/lwip-1.4.1/src/core/ipv4/igmp.c new file mode 100644 index 0000000..45bb5d9 --- /dev/null +++ b/src/lwip-1.4.1/src/core/ipv4/igmp.c @@ -0,0 +1,805 @@ +/** + * @file + * IGMP - Internet Group Management Protocol + * + */ + +/* + * Copyright (c) 2002 CITEL Technologies Ltd. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of CITEL Technologies Ltd nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY CITEL TECHNOLOGIES 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 CITEL TECHNOLOGIES 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. + * + * This file is a contribution to the lwIP TCP/IP stack. + * The Swedish Institute of Computer Science and Adam Dunkels + * are specifically granted permission to redistribute this + * source code. +*/ + +/*------------------------------------------------------------- +Note 1) +Although the rfc requires V1 AND V2 capability +we will only support v2 since now V1 is very old (August 1989) +V1 can be added if required + +a debug print and statistic have been implemented to +show this up. +------------------------------------------------------------- +------------------------------------------------------------- +Note 2) +A query for a specific group address (as opposed to ALLHOSTS) +has now been implemented as I am unsure if it is required + +a debug print and statistic have been implemented to +show this up. +------------------------------------------------------------- +------------------------------------------------------------- +Note 3) +The router alert rfc 2113 is implemented in outgoing packets +but not checked rigorously incoming +------------------------------------------------------------- +Steve Reynolds +------------------------------------------------------------*/ + +/*----------------------------------------------------------------------------- + * RFC 988 - Host extensions for IP multicasting - V0 + * RFC 1054 - Host extensions for IP multicasting - + * RFC 1112 - Host extensions for IP multicasting - V1 + * RFC 2236 - Internet Group Management Protocol, Version 2 - V2 <- this code is based on this RFC (it's the "de facto" standard) + * RFC 3376 - Internet Group Management Protocol, Version 3 - V3 + * RFC 4604 - Using Internet Group Management Protocol Version 3... - V3+ + * RFC 2113 - IP Router Alert Option - + *----------------------------------------------------------------------------*/ + +/*----------------------------------------------------------------------------- + * Includes + *----------------------------------------------------------------------------*/ + +#include "lwip/opt.h" + +#if LWIP_IGMP /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/igmp.h" +#include "lwip/debug.h" +#include "lwip/def.h" +#include "lwip/mem.h" +#include "lwip/ip.h" +#include "lwip/inet_chksum.h" +#include "lwip/netif.h" +#include "lwip/icmp.h" +#include "lwip/udp.h" +#include "lwip/tcp.h" +#include "lwip/stats.h" + +#include "string.h" + +/* + * IGMP constants + */ +#define IGMP_TTL 1 +#define IGMP_MINLEN 8 +#define ROUTER_ALERT 0x9404U +#define ROUTER_ALERTLEN 4 + +/* + * IGMP message types, including version number. + */ +#define IGMP_MEMB_QUERY 0x11 /* Membership query */ +#define IGMP_V1_MEMB_REPORT 0x12 /* Ver. 1 membership report */ +#define IGMP_V2_MEMB_REPORT 0x16 /* Ver. 2 membership report */ +#define IGMP_LEAVE_GROUP 0x17 /* Leave-group message */ + +/* Group membership states */ +#define IGMP_GROUP_NON_MEMBER 0 +#define IGMP_GROUP_DELAYING_MEMBER 1 +#define IGMP_GROUP_IDLE_MEMBER 2 + +/** + * IGMP packet format. + */ +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct igmp_msg { + PACK_STRUCT_FIELD(u8_t igmp_msgtype); + PACK_STRUCT_FIELD(u8_t igmp_maxresp); + PACK_STRUCT_FIELD(u16_t igmp_checksum); + PACK_STRUCT_FIELD(ip_addr_p_t igmp_group_address); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + + +static struct igmp_group *igmp_lookup_group(struct netif *ifp, ip_addr_t *addr); +static err_t igmp_remove_group(struct igmp_group *group); +static void igmp_timeout( struct igmp_group *group); +static void igmp_start_timer(struct igmp_group *group, u8_t max_time); +static void igmp_delaying_member(struct igmp_group *group, u8_t maxresp); +static err_t igmp_ip_output_if(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest, struct netif *netif); +static void igmp_send(struct igmp_group *group, u8_t type); + + +static struct igmp_group* igmp_group_list; +static ip_addr_t allsystems; +static ip_addr_t allrouters; + + +/** + * Initialize the IGMP module + */ +void +igmp_init(void) +{ + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_init: initializing\n")); + + IP4_ADDR(&allsystems, 224, 0, 0, 1); + IP4_ADDR(&allrouters, 224, 0, 0, 2); +} + +#ifdef LWIP_DEBUG +/** + * Dump global IGMP groups list + */ +void +igmp_dump_group_list() +{ + struct igmp_group *group = igmp_group_list; + + while (group != NULL) { + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_dump_group_list: [%"U32_F"] ", (u32_t)(group->group_state))); + ip_addr_debug_print(IGMP_DEBUG, &group->group_address); + LWIP_DEBUGF(IGMP_DEBUG, (" on if %p\n", group->netif)); + group = group->next; + } + LWIP_DEBUGF(IGMP_DEBUG, ("\n")); +} +#else +#define igmp_dump_group_list() +#endif /* LWIP_DEBUG */ + +/** + * Start IGMP processing on interface + * + * @param netif network interface on which start IGMP processing + */ +err_t +igmp_start(struct netif *netif) +{ + struct igmp_group* group; + + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_start: starting IGMP processing on if %p\n", netif)); + + group = igmp_lookup_group(netif, &allsystems); + + if (group != NULL) { + group->group_state = IGMP_GROUP_IDLE_MEMBER; + group->use++; + + /* Allow the igmp messages at the MAC level */ + if (netif->igmp_mac_filter != NULL) { + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_start: igmp_mac_filter(ADD ")); + ip_addr_debug_print(IGMP_DEBUG, &allsystems); + LWIP_DEBUGF(IGMP_DEBUG, (") on if %p\n", netif)); + netif->igmp_mac_filter(netif, &allsystems, IGMP_ADD_MAC_FILTER); + } + + return ERR_OK; + } + + return ERR_MEM; +} + +/** + * Stop IGMP processing on interface + * + * @param netif network interface on which stop IGMP processing + */ +err_t +igmp_stop(struct netif *netif) +{ + struct igmp_group *group = igmp_group_list; + struct igmp_group *prev = NULL; + struct igmp_group *next; + + /* look for groups joined on this interface further down the list */ + while (group != NULL) { + next = group->next; + /* is it a group joined on this interface? */ + if (group->netif == netif) { + /* is it the first group of the list? */ + if (group == igmp_group_list) { + igmp_group_list = next; + } + /* is there a "previous" group defined? */ + if (prev != NULL) { + prev->next = next; + } + /* disable the group at the MAC level */ + if (netif->igmp_mac_filter != NULL) { + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_stop: igmp_mac_filter(DEL ")); + ip_addr_debug_print(IGMP_DEBUG, &group->group_address); + LWIP_DEBUGF(IGMP_DEBUG, (") on if %p\n", netif)); + netif->igmp_mac_filter(netif, &(group->group_address), IGMP_DEL_MAC_FILTER); + } + /* free group */ + memp_free(MEMP_IGMP_GROUP, group); + } else { + /* change the "previous" */ + prev = group; + } + /* move to "next" */ + group = next; + } + return ERR_OK; +} + +/** + * Report IGMP memberships for this interface + * + * @param netif network interface on which report IGMP memberships + */ +void +igmp_report_groups(struct netif *netif) +{ + struct igmp_group *group = igmp_group_list; + + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_report_groups: sending IGMP reports on if %p\n", netif)); + + while (group != NULL) { + if (group->netif == netif) { + igmp_delaying_member(group, IGMP_JOIN_DELAYING_MEMBER_TMR); + } + group = group->next; + } +} + +/** + * Search for a group in the global igmp_group_list + * + * @param ifp the network interface for which to look + * @param addr the group ip address to search for + * @return a struct igmp_group* if the group has been found, + * NULL if the group wasn't found. + */ +struct igmp_group * +igmp_lookfor_group(struct netif *ifp, ip_addr_t *addr) +{ + struct igmp_group *group = igmp_group_list; + + while (group != NULL) { + if ((group->netif == ifp) && (ip_addr_cmp(&(group->group_address), addr))) { + return group; + } + group = group->next; + } + + /* to be clearer, we return NULL here instead of + * 'group' (which is also NULL at this point). + */ + return NULL; +} + +/** + * Search for a specific igmp group and create a new one if not found- + * + * @param ifp the network interface for which to look + * @param addr the group ip address to search + * @return a struct igmp_group*, + * NULL on memory error. + */ +struct igmp_group * +igmp_lookup_group(struct netif *ifp, ip_addr_t *addr) +{ + struct igmp_group *group = igmp_group_list; + + /* Search if the group already exists */ + group = igmp_lookfor_group(ifp, addr); + if (group != NULL) { + /* Group already exists. */ + return group; + } + + /* Group doesn't exist yet, create a new one */ + group = (struct igmp_group *)memp_malloc(MEMP_IGMP_GROUP); + if (group != NULL) { + group->netif = ifp; + ip_addr_set(&(group->group_address), addr); + group->timer = 0; /* Not running */ + group->group_state = IGMP_GROUP_NON_MEMBER; + group->last_reporter_flag = 0; + group->use = 0; + group->next = igmp_group_list; + + igmp_group_list = group; + } + + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_lookup_group: %sallocated a new group with address ", (group?"":"impossible to "))); + ip_addr_debug_print(IGMP_DEBUG, addr); + LWIP_DEBUGF(IGMP_DEBUG, (" on if %p\n", ifp)); + + return group; +} + +/** + * Remove a group in the global igmp_group_list + * + * @param group the group to remove from the global igmp_group_list + * @return ERR_OK if group was removed from the list, an err_t otherwise + */ +static err_t +igmp_remove_group(struct igmp_group *group) +{ + err_t err = ERR_OK; + + /* Is it the first group? */ + if (igmp_group_list == group) { + igmp_group_list = group->next; + } else { + /* look for group further down the list */ + struct igmp_group *tmpGroup; + for (tmpGroup = igmp_group_list; tmpGroup != NULL; tmpGroup = tmpGroup->next) { + if (tmpGroup->next == group) { + tmpGroup->next = group->next; + break; + } + } + /* Group not found in the global igmp_group_list */ + if (tmpGroup == NULL) + err = ERR_ARG; + } + /* free group */ + memp_free(MEMP_IGMP_GROUP, group); + + return err; +} + +/** + * Called from ip_input() if a new IGMP packet is received. + * + * @param p received igmp packet, p->payload pointing to the ip header + * @param inp network interface on which the packet was received + * @param dest destination ip address of the igmp packet + */ +void +igmp_input(struct pbuf *p, struct netif *inp, ip_addr_t *dest) +{ + struct ip_hdr * iphdr; + struct igmp_msg* igmp; + struct igmp_group* group; + struct igmp_group* groupref; + + IGMP_STATS_INC(igmp.recv); + + /* Note that the length CAN be greater than 8 but only 8 are used - All are included in the checksum */ + iphdr = (struct ip_hdr *)p->payload; + if (pbuf_header(p, -(s16_t)(IPH_HL(iphdr) * 4)) || (p->len < IGMP_MINLEN)) { + pbuf_free(p); + IGMP_STATS_INC(igmp.lenerr); + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: length error\n")); + return; + } + + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: message from ")); + ip_addr_debug_print(IGMP_DEBUG, &(iphdr->src)); + LWIP_DEBUGF(IGMP_DEBUG, (" to address ")); + ip_addr_debug_print(IGMP_DEBUG, &(iphdr->dest)); + LWIP_DEBUGF(IGMP_DEBUG, (" on if %p\n", inp)); + + /* Now calculate and check the checksum */ + igmp = (struct igmp_msg *)p->payload; + if (inet_chksum(igmp, p->len)) { + pbuf_free(p); + IGMP_STATS_INC(igmp.chkerr); + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: checksum error\n")); + return; + } + + /* Packet is ok so find an existing group */ + group = igmp_lookfor_group(inp, dest); /* use the destination IP address of incoming packet */ + + /* If group can be found or create... */ + if (!group) { + pbuf_free(p); + IGMP_STATS_INC(igmp.drop); + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: IGMP frame not for us\n")); + return; + } + + /* NOW ACT ON THE INCOMING MESSAGE TYPE... */ + switch (igmp->igmp_msgtype) { + case IGMP_MEMB_QUERY: { + /* IGMP_MEMB_QUERY to the "all systems" address ? */ + if ((ip_addr_cmp(dest, &allsystems)) && ip_addr_isany(&igmp->igmp_group_address)) { + /* THIS IS THE GENERAL QUERY */ + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: General IGMP_MEMB_QUERY on \"ALL SYSTEMS\" address (224.0.0.1) [igmp_maxresp=%i]\n", (int)(igmp->igmp_maxresp))); + + if (igmp->igmp_maxresp == 0) { + IGMP_STATS_INC(igmp.rx_v1); + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: got an all hosts query with time== 0 - this is V1 and not implemented - treat as v2\n")); + igmp->igmp_maxresp = IGMP_V1_DELAYING_MEMBER_TMR; + } else { + IGMP_STATS_INC(igmp.rx_general); + } + + groupref = igmp_group_list; + while (groupref) { + /* Do not send messages on the all systems group address! */ + if ((groupref->netif == inp) && (!(ip_addr_cmp(&(groupref->group_address), &allsystems)))) { + igmp_delaying_member(groupref, igmp->igmp_maxresp); + } + groupref = groupref->next; + } + } else { + /* IGMP_MEMB_QUERY to a specific group ? */ + if (!ip_addr_isany(&igmp->igmp_group_address)) { + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: IGMP_MEMB_QUERY to a specific group ")); + ip_addr_debug_print(IGMP_DEBUG, &igmp->igmp_group_address); + if (ip_addr_cmp(dest, &allsystems)) { + ip_addr_t groupaddr; + LWIP_DEBUGF(IGMP_DEBUG, (" using \"ALL SYSTEMS\" address (224.0.0.1) [igmp_maxresp=%i]\n", (int)(igmp->igmp_maxresp))); + /* we first need to re-look for the group since we used dest last time */ + ip_addr_copy(groupaddr, igmp->igmp_group_address); + group = igmp_lookfor_group(inp, &groupaddr); + } else { + LWIP_DEBUGF(IGMP_DEBUG, (" with the group address as destination [igmp_maxresp=%i]\n", (int)(igmp->igmp_maxresp))); + } + + if (group != NULL) { + IGMP_STATS_INC(igmp.rx_group); + igmp_delaying_member(group, igmp->igmp_maxresp); + } else { + IGMP_STATS_INC(igmp.drop); + } + } else { + IGMP_STATS_INC(igmp.proterr); + } + } + break; + } + case IGMP_V2_MEMB_REPORT: { + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: IGMP_V2_MEMB_REPORT\n")); + IGMP_STATS_INC(igmp.rx_report); + if (group->group_state == IGMP_GROUP_DELAYING_MEMBER) { + /* This is on a specific group we have already looked up */ + group->timer = 0; /* stopped */ + group->group_state = IGMP_GROUP_IDLE_MEMBER; + group->last_reporter_flag = 0; + } + break; + } + default: { + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: unexpected msg %d in state %d on group %p on if %p\n", + igmp->igmp_msgtype, group->group_state, &group, group->netif)); + IGMP_STATS_INC(igmp.proterr); + break; + } + } + + pbuf_free(p); + return; +} + +/** + * Join a group on one network interface. + * + * @param ifaddr ip address of the network interface which should join a new group + * @param groupaddr the ip address of the group which to join + * @return ERR_OK if group was joined on the netif(s), an err_t otherwise + */ +err_t +igmp_joingroup(ip_addr_t *ifaddr, ip_addr_t *groupaddr) +{ + err_t err = ERR_VAL; /* no matching interface */ + struct igmp_group *group; + struct netif *netif; + + /* make sure it is multicast address */ + LWIP_ERROR("igmp_joingroup: attempt to join non-multicast address", ip_addr_ismulticast(groupaddr), return ERR_VAL;); + LWIP_ERROR("igmp_joingroup: attempt to join allsystems address", (!ip_addr_cmp(groupaddr, &allsystems)), return ERR_VAL;); + + /* loop through netif's */ + netif = netif_list; + while (netif != NULL) { + /* Should we join this interface ? */ + if ((netif->flags & NETIF_FLAG_IGMP) && ((ip_addr_isany(ifaddr) || ip_addr_cmp(&(netif->ip_addr), ifaddr)))) { + /* find group or create a new one if not found */ + group = igmp_lookup_group(netif, groupaddr); + + if (group != NULL) { + /* This should create a new group, check the state to make sure */ + if (group->group_state != IGMP_GROUP_NON_MEMBER) { + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_joingroup: join to group not in state IGMP_GROUP_NON_MEMBER\n")); + } else { + /* OK - it was new group */ + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_joingroup: join to new group: ")); + ip_addr_debug_print(IGMP_DEBUG, groupaddr); + LWIP_DEBUGF(IGMP_DEBUG, ("\n")); + + /* If first use of the group, allow the group at the MAC level */ + if ((group->use==0) && (netif->igmp_mac_filter != NULL)) { + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_joingroup: igmp_mac_filter(ADD ")); + ip_addr_debug_print(IGMP_DEBUG, groupaddr); + LWIP_DEBUGF(IGMP_DEBUG, (") on if %p\n", netif)); + netif->igmp_mac_filter(netif, groupaddr, IGMP_ADD_MAC_FILTER); + } + + IGMP_STATS_INC(igmp.tx_join); + igmp_send(group, IGMP_V2_MEMB_REPORT); + + igmp_start_timer(group, IGMP_JOIN_DELAYING_MEMBER_TMR); + + /* Need to work out where this timer comes from */ + group->group_state = IGMP_GROUP_DELAYING_MEMBER; + } + /* Increment group use */ + group->use++; + /* Join on this interface */ + err = ERR_OK; + } else { + /* Return an error even if some network interfaces are joined */ + /** @todo undo any other netif already joined */ + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_joingroup: Not enought memory to join to group\n")); + return ERR_MEM; + } + } + /* proceed to next network interface */ + netif = netif->next; + } + + return err; +} + +/** + * Leave a group on one network interface. + * + * @param ifaddr ip address of the network interface which should leave a group + * @param groupaddr the ip address of the group which to leave + * @return ERR_OK if group was left on the netif(s), an err_t otherwise + */ +err_t +igmp_leavegroup(ip_addr_t *ifaddr, ip_addr_t *groupaddr) +{ + err_t err = ERR_VAL; /* no matching interface */ + struct igmp_group *group; + struct netif *netif; + + /* make sure it is multicast address */ + LWIP_ERROR("igmp_leavegroup: attempt to leave non-multicast address", ip_addr_ismulticast(groupaddr), return ERR_VAL;); + LWIP_ERROR("igmp_leavegroup: attempt to leave allsystems address", (!ip_addr_cmp(groupaddr, &allsystems)), return ERR_VAL;); + + /* loop through netif's */ + netif = netif_list; + while (netif != NULL) { + /* Should we leave this interface ? */ + if ((netif->flags & NETIF_FLAG_IGMP) && ((ip_addr_isany(ifaddr) || ip_addr_cmp(&(netif->ip_addr), ifaddr)))) { + /* find group */ + group = igmp_lookfor_group(netif, groupaddr); + + if (group != NULL) { + /* Only send a leave if the flag is set according to the state diagram */ + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_leavegroup: Leaving group: ")); + ip_addr_debug_print(IGMP_DEBUG, groupaddr); + LWIP_DEBUGF(IGMP_DEBUG, ("\n")); + + /* If there is no other use of the group */ + if (group->use <= 1) { + /* If we are the last reporter for this group */ + if (group->last_reporter_flag) { + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_leavegroup: sending leaving group\n")); + IGMP_STATS_INC(igmp.tx_leave); + igmp_send(group, IGMP_LEAVE_GROUP); + } + + /* Disable the group at the MAC level */ + if (netif->igmp_mac_filter != NULL) { + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_leavegroup: igmp_mac_filter(DEL ")); + ip_addr_debug_print(IGMP_DEBUG, groupaddr); + LWIP_DEBUGF(IGMP_DEBUG, (") on if %p\n", netif)); + netif->igmp_mac_filter(netif, groupaddr, IGMP_DEL_MAC_FILTER); + } + + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_leavegroup: remove group: ")); + ip_addr_debug_print(IGMP_DEBUG, groupaddr); + LWIP_DEBUGF(IGMP_DEBUG, ("\n")); + + /* Free the group */ + igmp_remove_group(group); + } else { + /* Decrement group use */ + group->use--; + } + /* Leave on this interface */ + err = ERR_OK; + } else { + /* It's not a fatal error on "leavegroup" */ + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_leavegroup: not member of group\n")); + } + } + /* proceed to next network interface */ + netif = netif->next; + } + + return err; +} + +/** + * The igmp timer function (both for NO_SYS=1 and =0) + * Should be called every IGMP_TMR_INTERVAL milliseconds (100 ms is default). + */ +void +igmp_tmr(void) +{ + struct igmp_group *group = igmp_group_list; + + while (group != NULL) { + if (group->timer > 0) { + group->timer--; + if (group->timer == 0) { + igmp_timeout(group); + } + } + group = group->next; + } +} + +/** + * Called if a timeout for one group is reached. + * Sends a report for this group. + * + * @param group an igmp_group for which a timeout is reached + */ +static void +igmp_timeout(struct igmp_group *group) +{ + /* If the state is IGMP_GROUP_DELAYING_MEMBER then we send a report for this group */ + if (group->group_state == IGMP_GROUP_DELAYING_MEMBER) { + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_timeout: report membership for group with address ")); + ip_addr_debug_print(IGMP_DEBUG, &(group->group_address)); + LWIP_DEBUGF(IGMP_DEBUG, (" on if %p\n", group->netif)); + + IGMP_STATS_INC(igmp.tx_report); + igmp_send(group, IGMP_V2_MEMB_REPORT); + } +} + +/** + * Start a timer for an igmp group + * + * @param group the igmp_group for which to start a timer + * @param max_time the time in multiples of IGMP_TMR_INTERVAL (decrease with + * every call to igmp_tmr()) + */ +static void +igmp_start_timer(struct igmp_group *group, u8_t max_time) +{ + /* ensure the input value is > 0 */ + if (max_time == 0) { + max_time = 1; + } + /* ensure the random value is > 0 */ + group->timer = (LWIP_RAND() % (max_time - 1)) + 1; +} + +/** + * Delaying membership report for a group if necessary + * + * @param group the igmp_group for which "delaying" membership report + * @param maxresp query delay + */ +static void +igmp_delaying_member(struct igmp_group *group, u8_t maxresp) +{ + if ((group->group_state == IGMP_GROUP_IDLE_MEMBER) || + ((group->group_state == IGMP_GROUP_DELAYING_MEMBER) && + ((group->timer == 0) || (maxresp < group->timer)))) { + igmp_start_timer(group, maxresp); + group->group_state = IGMP_GROUP_DELAYING_MEMBER; + } +} + + +/** + * Sends an IP packet on a network interface. This function constructs the IP header + * and calculates the IP header checksum. If the source IP address is NULL, + * the IP address of the outgoing network interface is filled in as source address. + * + * @param p the packet to send (p->payload points to the data, e.g. next + protocol header; if dest == IP_HDRINCL, p already includes an IP + header and p->payload points to that IP header) + * @param src the source IP address to send from (if src == IP_ADDR_ANY, the + * IP address of the netif used to send is used as source address) + * @param dest the destination IP address to send the packet to + * @param ttl the TTL value to be set in the IP header + * @param proto the PROTOCOL to be set in the IP header + * @param netif the netif on which to send this packet + * @return ERR_OK if the packet was sent OK + * ERR_BUF if p doesn't have enough space for IP/LINK headers + * returns errors returned by netif->output + */ +static err_t +igmp_ip_output_if(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest, struct netif *netif) +{ + /* This is the "router alert" option */ + u16_t ra[2]; + ra[0] = PP_HTONS(ROUTER_ALERT); + ra[1] = 0x0000; /* Router shall examine packet */ + IGMP_STATS_INC(igmp.xmit); + return ip_output_if_opt(p, src, dest, IGMP_TTL, 0, IP_PROTO_IGMP, netif, ra, ROUTER_ALERTLEN); +} + +/** + * Send an igmp packet to a specific group. + * + * @param group the group to which to send the packet + * @param type the type of igmp packet to send + */ +static void +igmp_send(struct igmp_group *group, u8_t type) +{ + struct pbuf* p = NULL; + struct igmp_msg* igmp = NULL; + ip_addr_t src = *IP_ADDR_ANY; + ip_addr_t* dest = NULL; + + /* IP header + "router alert" option + IGMP header */ + p = pbuf_alloc(PBUF_TRANSPORT, IGMP_MINLEN, PBUF_RAM); + + if (p) { + igmp = (struct igmp_msg *)p->payload; + LWIP_ASSERT("igmp_send: check that first pbuf can hold struct igmp_msg", + (p->len >= sizeof(struct igmp_msg))); + ip_addr_copy(src, group->netif->ip_addr); + + if (type == IGMP_V2_MEMB_REPORT) { + dest = &(group->group_address); + ip_addr_copy(igmp->igmp_group_address, group->group_address); + group->last_reporter_flag = 1; /* Remember we were the last to report */ + } else { + if (type == IGMP_LEAVE_GROUP) { + dest = &allrouters; + ip_addr_copy(igmp->igmp_group_address, group->group_address); + } + } + + if ((type == IGMP_V2_MEMB_REPORT) || (type == IGMP_LEAVE_GROUP)) { + igmp->igmp_msgtype = type; + igmp->igmp_maxresp = 0; + igmp->igmp_checksum = 0; + igmp->igmp_checksum = inet_chksum(igmp, IGMP_MINLEN); + + igmp_ip_output_if(p, &src, dest, group->netif); + } + + pbuf_free(p); + } else { + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_send: not enough memory for igmp_send\n")); + IGMP_STATS_INC(igmp.memerr); + } +} + +#endif /* LWIP_IGMP */ diff --git a/src/lwip-1.4.1/src/core/ipv4/inet.c b/src/lwip-1.4.1/src/core/ipv4/inet.c new file mode 100644 index 0000000..e283a57 --- /dev/null +++ b/src/lwip-1.4.1/src/core/ipv4/inet.c @@ -0,0 +1,42 @@ +/** + * @file + * Functions common to all TCP/IPv4 modules, such as the byte order functions. + * + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#include "lwip/opt.h" + +#include "lwip/inet.h" + diff --git a/src/lwip-1.4.1/src/core/ipv4/inet_chksum.c b/src/lwip-1.4.1/src/core/ipv4/inet_chksum.c new file mode 100644 index 0000000..960252f --- /dev/null +++ b/src/lwip-1.4.1/src/core/ipv4/inet_chksum.c @@ -0,0 +1,450 @@ +/** + * @file + * Incluse internet checksum functions. + * + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#include "lwip/opt.h" + +#include "lwip/inet_chksum.h" +#include "lwip/def.h" + +#include +#include + +/* These are some reference implementations of the checksum algorithm, with the + * aim of being simple, correct and fully portable. Checksumming is the + * first thing you would want to optimize for your platform. If you create + * your own version, link it in and in your cc.h put: + * + * #define LWIP_CHKSUM + * + * Or you can select from the implementations below by defining + * LWIP_CHKSUM_ALGORITHM to 1, 2 or 3. + */ + +#ifndef LWIP_CHKSUM +# define LWIP_CHKSUM lwip_standard_chksum +# ifndef LWIP_CHKSUM_ALGORITHM +# define LWIP_CHKSUM_ALGORITHM 2 +# endif +#endif +/* If none set: */ +#ifndef LWIP_CHKSUM_ALGORITHM +# define LWIP_CHKSUM_ALGORITHM 0 +#endif + +#if (LWIP_CHKSUM_ALGORITHM == 1) /* Version #1 */ +/** + * lwip checksum + * + * @param dataptr points to start of data to be summed at any boundary + * @param len length of data to be summed + * @return host order (!) lwip checksum (non-inverted Internet sum) + * + * @note accumulator size limits summable length to 64k + * @note host endianess is irrelevant (p3 RFC1071) + */ +static u16_t +lwip_standard_chksum(void *dataptr, u16_t len) +{ + u32_t acc; + u16_t src; + u8_t *octetptr; + + acc = 0; + /* dataptr may be at odd or even addresses */ + octetptr = (u8_t*)dataptr; + while (len > 1) { + /* declare first octet as most significant + thus assume network order, ignoring host order */ + src = (*octetptr) << 8; + octetptr++; + /* declare second octet as least significant */ + src |= (*octetptr); + octetptr++; + acc += src; + len -= 2; + } + if (len > 0) { + /* accumulate remaining octet */ + src = (*octetptr) << 8; + acc += src; + } + /* add deferred carry bits */ + acc = (acc >> 16) + (acc & 0x0000ffffUL); + if ((acc & 0xffff0000UL) != 0) { + acc = (acc >> 16) + (acc & 0x0000ffffUL); + } + /* This maybe a little confusing: reorder sum using htons() + instead of ntohs() since it has a little less call overhead. + The caller must invert bits for Internet sum ! */ + return htons((u16_t)acc); +} +#endif + +#if (LWIP_CHKSUM_ALGORITHM == 2) /* Alternative version #2 */ +/* + * Curt McDowell + * Broadcom Corp. + * csm@broadcom.com + * + * IP checksum two bytes at a time with support for + * unaligned buffer. + * Works for len up to and including 0x20000. + * by Curt McDowell, Broadcom Corp. 12/08/2005 + * + * @param dataptr points to start of data to be summed at any boundary + * @param len length of data to be summed + * @return host order (!) lwip checksum (non-inverted Internet sum) + */ + +static u16_t +lwip_standard_chksum(void *dataptr, int len) +{ + u8_t *pb = (u8_t *)dataptr; + u16_t *ps, t = 0; + u32_t sum = 0; + int odd = ((mem_ptr_t)pb & 1); + + /* Get aligned to u16_t */ + if (odd && len > 0) { + ((u8_t *)&t)[1] = *pb++; + len--; + } + + /* Add the bulk of the data */ + ps = (u16_t *)(void *)pb; + while (len > 1) { + sum += *ps++; + len -= 2; + } + + /* Consume left-over byte, if any */ + if (len > 0) { + ((u8_t *)&t)[0] = *(u8_t *)ps; + } + + /* Add end bytes */ + sum += t; + + /* Fold 32-bit sum to 16 bits + calling this twice is propably faster than if statements... */ + sum = FOLD_U32T(sum); + sum = FOLD_U32T(sum); + + /* Swap if alignment was odd */ + if (odd) { + sum = SWAP_BYTES_IN_WORD(sum); + } + + return (u16_t)sum; +} +#endif + +#if (LWIP_CHKSUM_ALGORITHM == 3) /* Alternative version #3 */ +/** + * An optimized checksum routine. Basically, it uses loop-unrolling on + * the checksum loop, treating the head and tail bytes specially, whereas + * the inner loop acts on 8 bytes at a time. + * + * @arg start of buffer to be checksummed. May be an odd byte address. + * @len number of bytes in the buffer to be checksummed. + * @return host order (!) lwip checksum (non-inverted Internet sum) + * + * by Curt McDowell, Broadcom Corp. December 8th, 2005 + */ + +static u16_t +lwip_standard_chksum(void *dataptr, int len) +{ + u8_t *pb = (u8_t *)dataptr; + u16_t *ps, t = 0; + u32_t *pl; + u32_t sum = 0, tmp; + /* starts at odd byte address? */ + int odd = ((mem_ptr_t)pb & 1); + + if (odd && len > 0) { + ((u8_t *)&t)[1] = *pb++; + len--; + } + + ps = (u16_t *)pb; + + if (((mem_ptr_t)ps & 3) && len > 1) { + sum += *ps++; + len -= 2; + } + + pl = (u32_t *)ps; + + while (len > 7) { + tmp = sum + *pl++; /* ping */ + if (tmp < sum) { + tmp++; /* add back carry */ + } + + sum = tmp + *pl++; /* pong */ + if (sum < tmp) { + sum++; /* add back carry */ + } + + len -= 8; + } + + /* make room in upper bits */ + sum = FOLD_U32T(sum); + + ps = (u16_t *)pl; + + /* 16-bit aligned word remaining? */ + while (len > 1) { + sum += *ps++; + len -= 2; + } + + /* dangling tail byte remaining? */ + if (len > 0) { /* include odd byte */ + ((u8_t *)&t)[0] = *(u8_t *)ps; + } + + sum += t; /* add end bytes */ + + /* Fold 32-bit sum to 16 bits + calling this twice is propably faster than if statements... */ + sum = FOLD_U32T(sum); + sum = FOLD_U32T(sum); + + if (odd) { + sum = SWAP_BYTES_IN_WORD(sum); + } + + return (u16_t)sum; +} +#endif + +/* inet_chksum_pseudo: + * + * Calculates the pseudo Internet checksum used by TCP and UDP for a pbuf chain. + * IP addresses are expected to be in network byte order. + * + * @param p chain of pbufs over that a checksum should be calculated (ip data part) + * @param src source ip address (used for checksum of pseudo header) + * @param dst destination ip address (used for checksum of pseudo header) + * @param proto ip protocol (used for checksum of pseudo header) + * @param proto_len length of the ip data part (used for checksum of pseudo header) + * @return checksum (as u16_t) to be saved directly in the protocol header + */ +u16_t +inet_chksum_pseudo(struct pbuf *p, + ip_addr_t *src, ip_addr_t *dest, + u8_t proto, u16_t proto_len) +{ + u32_t acc; + u32_t addr; + struct pbuf *q; + u8_t swapped; + + acc = 0; + swapped = 0; + /* iterate through all pbuf in chain */ + for(q = p; q != NULL; q = q->next) { + LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): checksumming pbuf %p (has next %p) \n", + (void *)q, (void *)q->next)); + acc += LWIP_CHKSUM(q->payload, q->len); + /*LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): unwrapped lwip_chksum()=%"X32_F" \n", acc));*/ + /* just executing this next line is probably faster that the if statement needed + to check whether we really need to execute it, and does no harm */ + acc = FOLD_U32T(acc); + if (q->len % 2 != 0) { + swapped = 1 - swapped; + acc = SWAP_BYTES_IN_WORD(acc); + } + /*LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): wrapped lwip_chksum()=%"X32_F" \n", acc));*/ + } + + if (swapped) { + acc = SWAP_BYTES_IN_WORD(acc); + } + addr = ip4_addr_get_u32(src); + acc += (addr & 0xffffUL); + acc += ((addr >> 16) & 0xffffUL); + addr = ip4_addr_get_u32(dest); + acc += (addr & 0xffffUL); + acc += ((addr >> 16) & 0xffffUL); + acc += (u32_t)htons((u16_t)proto); + acc += (u32_t)htons(proto_len); + + /* Fold 32-bit sum to 16 bits + calling this twice is propably faster than if statements... */ + acc = FOLD_U32T(acc); + acc = FOLD_U32T(acc); + LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): pbuf chain lwip_chksum()=%"X32_F"\n", acc)); + return (u16_t)~(acc & 0xffffUL); +} + +/* inet_chksum_pseudo: + * + * Calculates the pseudo Internet checksum used by TCP and UDP for a pbuf chain. + * IP addresses are expected to be in network byte order. + * + * @param p chain of pbufs over that a checksum should be calculated (ip data part) + * @param src source ip address (used for checksum of pseudo header) + * @param dst destination ip address (used for checksum of pseudo header) + * @param proto ip protocol (used for checksum of pseudo header) + * @param proto_len length of the ip data part (used for checksum of pseudo header) + * @return checksum (as u16_t) to be saved directly in the protocol header + */ +u16_t +inet_chksum_pseudo_partial(struct pbuf *p, + ip_addr_t *src, ip_addr_t *dest, + u8_t proto, u16_t proto_len, u16_t chksum_len) +{ + u32_t acc; + u32_t addr; + struct pbuf *q; + u8_t swapped; + u16_t chklen; + + acc = 0; + swapped = 0; + /* iterate through all pbuf in chain */ + for(q = p; (q != NULL) && (chksum_len > 0); q = q->next) { + LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): checksumming pbuf %p (has next %p) \n", + (void *)q, (void *)q->next)); + chklen = q->len; + if (chklen > chksum_len) { + chklen = chksum_len; + } + acc += LWIP_CHKSUM(q->payload, chklen); + chksum_len -= chklen; + LWIP_ASSERT("delete me", chksum_len < 0x7fff); + /*LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): unwrapped lwip_chksum()=%"X32_F" \n", acc));*/ + /* fold the upper bit down */ + acc = FOLD_U32T(acc); + if (q->len % 2 != 0) { + swapped = 1 - swapped; + acc = SWAP_BYTES_IN_WORD(acc); + } + /*LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): wrapped lwip_chksum()=%"X32_F" \n", acc));*/ + } + + if (swapped) { + acc = SWAP_BYTES_IN_WORD(acc); + } + addr = ip4_addr_get_u32(src); + acc += (addr & 0xffffUL); + acc += ((addr >> 16) & 0xffffUL); + addr = ip4_addr_get_u32(dest); + acc += (addr & 0xffffUL); + acc += ((addr >> 16) & 0xffffUL); + acc += (u32_t)htons((u16_t)proto); + acc += (u32_t)htons(proto_len); + + /* Fold 32-bit sum to 16 bits + calling this twice is propably faster than if statements... */ + acc = FOLD_U32T(acc); + acc = FOLD_U32T(acc); + LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): pbuf chain lwip_chksum()=%"X32_F"\n", acc)); + return (u16_t)~(acc & 0xffffUL); +} + +/* inet_chksum: + * + * Calculates the Internet checksum over a portion of memory. Used primarily for IP + * and ICMP. + * + * @param dataptr start of the buffer to calculate the checksum (no alignment needed) + * @param len length of the buffer to calculate the checksum + * @return checksum (as u16_t) to be saved directly in the protocol header + */ + +u16_t +inet_chksum(void *dataptr, u16_t len) +{ + return ~LWIP_CHKSUM(dataptr, len); +} + +/** + * Calculate a checksum over a chain of pbufs (without pseudo-header, much like + * inet_chksum only pbufs are used). + * + * @param p pbuf chain over that the checksum should be calculated + * @return checksum (as u16_t) to be saved directly in the protocol header + */ +u16_t +inet_chksum_pbuf(struct pbuf *p) +{ + u32_t acc; + struct pbuf *q; + u8_t swapped; + + acc = 0; + swapped = 0; + for(q = p; q != NULL; q = q->next) { + acc += LWIP_CHKSUM(q->payload, q->len); + acc = FOLD_U32T(acc); + if (q->len % 2 != 0) { + swapped = 1 - swapped; + acc = SWAP_BYTES_IN_WORD(acc); + } + } + + if (swapped) { + acc = SWAP_BYTES_IN_WORD(acc); + } + return (u16_t)~(acc & 0xffffUL); +} + +/* These are some implementations for LWIP_CHKSUM_COPY, which copies data + * like MEMCPY but generates a checksum at the same time. Since this is a + * performance-sensitive function, you might want to create your own version + * in assembly targeted at your hardware by defining it in lwipopts.h: + * #define LWIP_CHKSUM_COPY(dst, src, len) your_chksum_copy(dst, src, len) + */ + +#if (LWIP_CHKSUM_COPY_ALGORITHM == 1) /* Version #1 */ +/** Safe but slow: first call MEMCPY, then call LWIP_CHKSUM. + * For architectures with big caches, data might still be in cache when + * generating the checksum after copying. + */ +u16_t +lwip_chksum_copy(void *dst, const void *src, u16_t len) +{ + MEMCPY(dst, src, len); + return LWIP_CHKSUM(dst, len); +} +#endif /* (LWIP_CHKSUM_COPY_ALGORITHM == 1) */ diff --git a/src/lwip-1.4.1/src/core/ipv4/ip.c b/src/lwip-1.4.1/src/core/ipv4/ip.c new file mode 100644 index 0000000..95d2db4 --- /dev/null +++ b/src/lwip-1.4.1/src/core/ipv4/ip.c @@ -0,0 +1,924 @@ +/** + * @file + * This is the IPv4 layer implementation for incoming and outgoing IP traffic. + * + * @see ip_frag.c + * + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#include "lwip/opt.h" +#include "lwip/ip.h" +#include "lwip/def.h" +#include "lwip/mem.h" +#include "lwip/ip_frag.h" +#include "lwip/inet_chksum.h" +#include "lwip/netif.h" +#include "lwip/icmp.h" +#include "lwip/igmp.h" +#include "lwip/raw.h" +#include "lwip/udp.h" +#include "lwip/tcp_impl.h" +#include "lwip/snmp.h" +#include "lwip/dhcp.h" +#include "lwip/autoip.h" +#include "lwip/stats.h" +#include "arch/perf.h" + +#include + +/** Set this to 0 in the rare case of wanting to call an extra function to + * generate the IP checksum (in contrast to calculating it on-the-fly). */ +#ifndef LWIP_INLINE_IP_CHKSUM +#define LWIP_INLINE_IP_CHKSUM 1 +#endif +#if LWIP_INLINE_IP_CHKSUM && CHECKSUM_GEN_IP +#define CHECKSUM_GEN_IP_INLINE 1 +#else +#define CHECKSUM_GEN_IP_INLINE 0 +#endif + +#if LWIP_DHCP || defined(LWIP_IP_ACCEPT_UDP_PORT) +#define IP_ACCEPT_LINK_LAYER_ADDRESSING 1 + +/** Some defines for DHCP to let link-layer-addressed packets through while the + * netif is down. + * To use this in your own application/protocol, define LWIP_IP_ACCEPT_UDP_PORT + * to return 1 if the port is accepted and 0 if the port is not accepted. + */ +#if LWIP_DHCP && defined(LWIP_IP_ACCEPT_UDP_PORT) +/* accept DHCP client port and custom port */ +#define IP_ACCEPT_LINK_LAYER_ADDRESSED_PORT(port) (((port) == PP_NTOHS(DHCP_CLIENT_PORT)) \ + || (LWIP_IP_ACCEPT_UDP_PORT(port))) +#elif defined(LWIP_IP_ACCEPT_UDP_PORT) /* LWIP_DHCP && defined(LWIP_IP_ACCEPT_UDP_PORT) */ +/* accept custom port only */ +#define IP_ACCEPT_LINK_LAYER_ADDRESSED_PORT(port) (LWIP_IP_ACCEPT_UDP_PORT(port)) +#else /* LWIP_DHCP && defined(LWIP_IP_ACCEPT_UDP_PORT) */ +/* accept DHCP client port only */ +#define IP_ACCEPT_LINK_LAYER_ADDRESSED_PORT(port) ((port) == PP_NTOHS(DHCP_CLIENT_PORT)) +#endif /* LWIP_DHCP && defined(LWIP_IP_ACCEPT_UDP_PORT) */ + +#else /* LWIP_DHCP */ +#define IP_ACCEPT_LINK_LAYER_ADDRESSING 0 +#endif /* LWIP_DHCP */ + +/** + * The interface that provided the packet for the current callback + * invocation. + */ +struct netif *current_netif; + +/** + * Header of the input packet currently being processed. + */ +const struct ip_hdr *current_header; +/** Source IP address of current_header */ +ip_addr_t current_iphdr_src; +/** Destination IP address of current_header */ +ip_addr_t current_iphdr_dest; + +/** The IP header ID of the next outgoing IP packet */ +static u16_t ip_id; + +/** + * Finds the appropriate network interface for a given IP address. It + * searches the list of network interfaces linearly. A match is found + * if the masked IP address of the network interface equals the masked + * IP address given to the function. + * + * @param dest the destination IP address for which to find the route + * @return the netif on which to send to reach dest + */ +struct netif * +ip_route(ip_addr_t *dest) +{ + struct netif *netif; + +#ifdef LWIP_HOOK_IP4_ROUTE + netif = LWIP_HOOK_IP4_ROUTE(dest); + if (netif != NULL) { + return netif; + } +#endif + + /* iterate through netifs */ + for (netif = netif_list; netif != NULL; netif = netif->next) { + /* network mask matches? */ + if (netif_is_up(netif)) { + if (ip_addr_netcmp(dest, &(netif->ip_addr), &(netif->netmask))) { + /* return netif on which to forward IP packet */ + return netif; + } + } + } + if ((netif_default == NULL) || (!netif_is_up(netif_default))) { + LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip_route: No route to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", + ip4_addr1_16(dest), ip4_addr2_16(dest), ip4_addr3_16(dest), ip4_addr4_16(dest))); + IP_STATS_INC(ip.rterr); + snmp_inc_ipoutnoroutes(); + return NULL; + } + /* no matching netif found, use default netif */ + return netif_default; +} + +#if IP_FORWARD +/** + * Determine whether an IP address is in a reserved set of addresses + * that may not be forwarded, or whether datagrams to that destination + * may be forwarded. + * @param p the packet to forward + * @param dest the destination IP address + * @return 1: can forward 0: discard + */ +static int +ip_canforward(struct pbuf *p) +{ + u32_t addr = ip4_addr_get_u32(ip_current_dest_addr()); + + if (p->flags & PBUF_FLAG_LLBCAST) { + /* don't route link-layer broadcasts */ + return 0; + } + if ((p->flags & PBUF_FLAG_LLMCAST) && !IP_MULTICAST(addr)) { + /* don't route link-layer multicasts unless the destination address is an IP + multicast address */ + return 0; + } + if (IP_EXPERIMENTAL(addr)) { + return 0; + } + if (IP_CLASSA(addr)) { + u32_t net = addr & IP_CLASSA_NET; + if ((net == 0) || (net == (IP_LOOPBACKNET << IP_CLASSA_NSHIFT))) { + /* don't route loopback packets */ + return 0; + } + } + return 1; +} + +/** + * Forwards an IP packet. It finds an appropriate route for the + * packet, decrements the TTL value of the packet, adjusts the + * checksum and outputs the packet on the appropriate interface. + * + * @param p the packet to forward (p->payload points to IP header) + * @param iphdr the IP header of the input packet + * @param inp the netif on which this packet was received + */ +static void +ip_forward(struct pbuf *p, struct ip_hdr *iphdr, struct netif *inp) +{ + struct netif *netif; + + PERF_START; + + if (!ip_canforward(p)) { + goto return_noroute; + } + + /* RFC3927 2.7: do not forward link-local addresses */ + if (ip_addr_islinklocal(¤t_iphdr_dest)) { + LWIP_DEBUGF(IP_DEBUG, ("ip_forward: not forwarding LLA %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", + ip4_addr1_16(¤t_iphdr_dest), ip4_addr2_16(¤t_iphdr_dest), + ip4_addr3_16(¤t_iphdr_dest), ip4_addr4_16(¤t_iphdr_dest))); + goto return_noroute; + } + + /* Find network interface where to forward this IP packet to. */ + netif = ip_route(¤t_iphdr_dest); + if (netif == NULL) { + LWIP_DEBUGF(IP_DEBUG, ("ip_forward: no forwarding route for %"U16_F".%"U16_F".%"U16_F".%"U16_F" found\n", + ip4_addr1_16(¤t_iphdr_dest), ip4_addr2_16(¤t_iphdr_dest), + ip4_addr3_16(¤t_iphdr_dest), ip4_addr4_16(¤t_iphdr_dest))); + /* @todo: send ICMP_DUR_NET? */ + goto return_noroute; + } +#if !IP_FORWARD_ALLOW_TX_ON_RX_NETIF + /* Do not forward packets onto the same network interface on which + * they arrived. */ + if (netif == inp) { + LWIP_DEBUGF(IP_DEBUG, ("ip_forward: not bouncing packets back on incoming interface.\n")); + goto return_noroute; + } +#endif /* IP_FORWARD_ALLOW_TX_ON_RX_NETIF */ + + /* decrement TTL */ + IPH_TTL_SET(iphdr, IPH_TTL(iphdr) - 1); + /* send ICMP if TTL == 0 */ + if (IPH_TTL(iphdr) == 0) { + snmp_inc_ipinhdrerrors(); +#if LWIP_ICMP + /* Don't send ICMP messages in response to ICMP messages */ + if (IPH_PROTO(iphdr) != IP_PROTO_ICMP) { + icmp_time_exceeded(p, ICMP_TE_TTL); + } +#endif /* LWIP_ICMP */ + return; + } + + /* Incrementally update the IP checksum. */ + if (IPH_CHKSUM(iphdr) >= PP_HTONS(0xffffU - 0x100)) { + IPH_CHKSUM_SET(iphdr, IPH_CHKSUM(iphdr) + PP_HTONS(0x100) + 1); + } else { + IPH_CHKSUM_SET(iphdr, IPH_CHKSUM(iphdr) + PP_HTONS(0x100)); + } + + LWIP_DEBUGF(IP_DEBUG, ("ip_forward: forwarding packet to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", + ip4_addr1_16(¤t_iphdr_dest), ip4_addr2_16(¤t_iphdr_dest), + ip4_addr3_16(¤t_iphdr_dest), ip4_addr4_16(¤t_iphdr_dest))); + + IP_STATS_INC(ip.fw); + IP_STATS_INC(ip.xmit); + snmp_inc_ipforwdatagrams(); + + PERF_STOP("ip_forward"); + /* don't fragment if interface has mtu set to 0 [loopif] */ + if (netif->mtu && (p->tot_len > netif->mtu)) { + if ((IPH_OFFSET(iphdr) & PP_NTOHS(IP_DF)) == 0) { +#if IP_FRAG + ip_frag(p, netif, ip_current_dest_addr()); +#else /* IP_FRAG */ + /* @todo: send ICMP Destination Unreacheable code 13 "Communication administratively prohibited"? */ +#endif /* IP_FRAG */ + } else { + /* send ICMP Destination Unreacheable code 4: "Fragmentation Needed and DF Set" */ + icmp_dest_unreach(p, ICMP_DUR_FRAG); + } + return; + } + /* transmit pbuf on chosen interface */ + netif->output(netif, p, ¤t_iphdr_dest); + return; +return_noroute: + snmp_inc_ipoutnoroutes(); +} +#endif /* IP_FORWARD */ + +/** + * This function is called by the network interface device driver when + * an IP packet is received. The function does the basic checks of the + * IP header such as packet size being at least larger than the header + * size etc. If the packet was not destined for us, the packet is + * forwarded (using ip_forward). The IP checksum is always checked. + * + * Finally, the packet is sent to the upper layer protocol input function. + * + * @param p the received IP packet (p->payload points to IP header) + * @param inp the netif on which this packet was received + * @return ERR_OK if the packet was processed (could return ERR_* if it wasn't + * processed, but currently always returns ERR_OK) + */ +err_t +ip_input(struct pbuf *p, struct netif *inp) +{ + struct ip_hdr *iphdr; + struct netif *netif; + u16_t iphdr_hlen; + u16_t iphdr_len; +#if IP_ACCEPT_LINK_LAYER_ADDRESSING + int check_ip_src=1; +#endif /* IP_ACCEPT_LINK_LAYER_ADDRESSING */ + + IP_STATS_INC(ip.recv); + snmp_inc_ipinreceives(); + + /* identify the IP header */ + iphdr = (struct ip_hdr *)p->payload; + if (IPH_V(iphdr) != 4) { + LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_WARNING, ("IP packet dropped due to bad version number %"U16_F"\n", IPH_V(iphdr))); + ip_debug_print(p); + pbuf_free(p); + IP_STATS_INC(ip.err); + IP_STATS_INC(ip.drop); + snmp_inc_ipinhdrerrors(); + return ERR_OK; + } + +#ifdef LWIP_HOOK_IP4_INPUT + if (LWIP_HOOK_IP4_INPUT(p, inp)) { + /* the packet has been eaten */ + return ERR_OK; + } +#endif + + /* obtain IP header length in number of 32-bit words */ + iphdr_hlen = IPH_HL(iphdr); + /* calculate IP header length in bytes */ + iphdr_hlen *= 4; + /* obtain ip length in bytes */ + iphdr_len = ntohs(IPH_LEN(iphdr)); + + /* header length exceeds first pbuf length, or ip length exceeds total pbuf length? */ + if ((iphdr_hlen > p->len) || (iphdr_len > p->tot_len)) { + if (iphdr_hlen > p->len) { + LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, + ("IP header (len %"U16_F") does not fit in first pbuf (len %"U16_F"), IP packet dropped.\n", + iphdr_hlen, p->len)); + } + if (iphdr_len > p->tot_len) { + LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, + ("IP (len %"U16_F") is longer than pbuf (len %"U16_F"), IP packet dropped.\n", + iphdr_len, p->tot_len)); + } + /* free (drop) packet pbufs */ + pbuf_free(p); + IP_STATS_INC(ip.lenerr); + IP_STATS_INC(ip.drop); + snmp_inc_ipindiscards(); + return ERR_OK; + } + + /* verify checksum */ +#if CHECKSUM_CHECK_IP + if (inet_chksum(iphdr, iphdr_hlen) != 0) { + + LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, + ("Checksum (0x%"X16_F") failed, IP packet dropped.\n", inet_chksum(iphdr, iphdr_hlen))); + ip_debug_print(p); + pbuf_free(p); + IP_STATS_INC(ip.chkerr); + IP_STATS_INC(ip.drop); + snmp_inc_ipinhdrerrors(); + return ERR_OK; + } +#endif + + /* Trim pbuf. This should have been done at the netif layer, + * but we'll do it anyway just to be sure that its done. */ + pbuf_realloc(p, iphdr_len); + + /* copy IP addresses to aligned ip_addr_t */ + ip_addr_copy(current_iphdr_dest, iphdr->dest); + ip_addr_copy(current_iphdr_src, iphdr->src); + + /* match packet against an interface, i.e. is this packet for us? */ +#if LWIP_IGMP + if (ip_addr_ismulticast(¤t_iphdr_dest)) { + if ((inp->flags & NETIF_FLAG_IGMP) && (igmp_lookfor_group(inp, ¤t_iphdr_dest))) { + netif = inp; + } else { + netif = NULL; + } + } else +#endif /* LWIP_IGMP */ + { + /* start trying with inp. if that's not acceptable, start walking the + list of configured netifs. + 'first' is used as a boolean to mark whether we started walking the list */ + int first = 1; + netif = inp; + do { + LWIP_DEBUGF(IP_DEBUG, ("ip_input: iphdr->dest 0x%"X32_F" netif->ip_addr 0x%"X32_F" (0x%"X32_F", 0x%"X32_F", 0x%"X32_F")\n", + ip4_addr_get_u32(&iphdr->dest), ip4_addr_get_u32(&netif->ip_addr), + ip4_addr_get_u32(&iphdr->dest) & ip4_addr_get_u32(&netif->netmask), + ip4_addr_get_u32(&netif->ip_addr) & ip4_addr_get_u32(&netif->netmask), + ip4_addr_get_u32(&iphdr->dest) & ~ip4_addr_get_u32(&netif->netmask))); + + /* interface is up and configured? */ + if ((netif_is_up(netif)) && (!ip_addr_isany(&(netif->ip_addr)))) { + /* unicast to this interface address? */ + if (ip_addr_cmp(¤t_iphdr_dest, &(netif->ip_addr)) || + /* or broadcast on this interface network address? */ + ip_addr_isbroadcast(¤t_iphdr_dest, netif)) { + LWIP_DEBUGF(IP_DEBUG, ("ip_input: packet accepted on interface %c%c\n", + netif->name[0], netif->name[1])); + /* break out of for loop */ + break; + } +#if LWIP_AUTOIP + /* connections to link-local addresses must persist after changing + the netif's address (RFC3927 ch. 1.9) */ + if ((netif->autoip != NULL) && + ip_addr_cmp(¤t_iphdr_dest, &(netif->autoip->llipaddr))) { + LWIP_DEBUGF(IP_DEBUG, ("ip_input: LLA packet accepted on interface %c%c\n", + netif->name[0], netif->name[1])); + /* break out of for loop */ + break; + } +#endif /* LWIP_AUTOIP */ + } + if (first) { + first = 0; + netif = netif_list; + } else { + netif = netif->next; + } + if (netif == inp) { + netif = netif->next; + } + } while(netif != NULL); + } + +#if IP_ACCEPT_LINK_LAYER_ADDRESSING + /* Pass DHCP messages regardless of destination address. DHCP traffic is addressed + * using link layer addressing (such as Ethernet MAC) so we must not filter on IP. + * According to RFC 1542 section 3.1.1, referred by RFC 2131). + * + * If you want to accept private broadcast communication while a netif is down, + * define LWIP_IP_ACCEPT_UDP_PORT(dst_port), e.g.: + * + * #define LWIP_IP_ACCEPT_UDP_PORT(dst_port) ((dst_port) == PP_NTOHS(12345)) + */ + if (netif == NULL) { + /* remote port is DHCP server? */ + if (IPH_PROTO(iphdr) == IP_PROTO_UDP) { + struct udp_hdr *udphdr = (struct udp_hdr *)((u8_t *)iphdr + iphdr_hlen); + LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE, ("ip_input: UDP packet to DHCP client port %"U16_F"\n", + ntohs(udphdr->dest))); + if (IP_ACCEPT_LINK_LAYER_ADDRESSED_PORT(udphdr->dest)) { + LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE, ("ip_input: DHCP packet accepted.\n")); + netif = inp; + check_ip_src = 0; + } + } + } +#endif /* IP_ACCEPT_LINK_LAYER_ADDRESSING */ + + /* broadcast or multicast packet source address? Compliant with RFC 1122: 3.2.1.3 */ +#if IP_ACCEPT_LINK_LAYER_ADDRESSING + /* DHCP servers need 0.0.0.0 to be allowed as source address (RFC 1.1.2.2: 3.2.1.3/a) */ + if (check_ip_src && !ip_addr_isany(¤t_iphdr_src)) +#endif /* IP_ACCEPT_LINK_LAYER_ADDRESSING */ + { if ((ip_addr_isbroadcast(¤t_iphdr_src, inp)) || + (ip_addr_ismulticast(¤t_iphdr_src))) { + /* packet source is not valid */ + LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, ("ip_input: packet source is not valid.\n")); + /* free (drop) packet pbufs */ + pbuf_free(p); + IP_STATS_INC(ip.drop); + snmp_inc_ipinaddrerrors(); + snmp_inc_ipindiscards(); + return ERR_OK; + } + } + + /* packet not for us? */ + if (netif == NULL) { + /* packet not for us, route or discard */ + LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE, ("ip_input: packet not for us.\n")); +#if IP_FORWARD + /* non-broadcast packet? */ + if (!ip_addr_isbroadcast(¤t_iphdr_dest, inp)) { + /* try to forward IP packet on (other) interfaces */ + ip_forward(p, iphdr, inp); + } else +#endif /* IP_FORWARD */ + { + snmp_inc_ipinaddrerrors(); + snmp_inc_ipindiscards(); + } + pbuf_free(p); + return ERR_OK; + } + /* packet consists of multiple fragments? */ + if ((IPH_OFFSET(iphdr) & PP_HTONS(IP_OFFMASK | IP_MF)) != 0) { +#if IP_REASSEMBLY /* packet fragment reassembly code present? */ + LWIP_DEBUGF(IP_DEBUG, ("IP packet is a fragment (id=0x%04"X16_F" tot_len=%"U16_F" len=%"U16_F" MF=%"U16_F" offset=%"U16_F"), calling ip_reass()\n", + ntohs(IPH_ID(iphdr)), p->tot_len, ntohs(IPH_LEN(iphdr)), !!(IPH_OFFSET(iphdr) & PP_HTONS(IP_MF)), (ntohs(IPH_OFFSET(iphdr)) & IP_OFFMASK)*8)); + /* reassemble the packet*/ + p = ip_reass(p); + /* packet not fully reassembled yet? */ + if (p == NULL) { + return ERR_OK; + } + iphdr = (struct ip_hdr *)p->payload; +#else /* IP_REASSEMBLY == 0, no packet fragment reassembly code present */ + pbuf_free(p); + LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("IP packet dropped since it was fragmented (0x%"X16_F") (while IP_REASSEMBLY == 0).\n", + ntohs(IPH_OFFSET(iphdr)))); + IP_STATS_INC(ip.opterr); + IP_STATS_INC(ip.drop); + /* unsupported protocol feature */ + snmp_inc_ipinunknownprotos(); + return ERR_OK; +#endif /* IP_REASSEMBLY */ + } + +#if IP_OPTIONS_ALLOWED == 0 /* no support for IP options in the IP header? */ + +#if LWIP_IGMP + /* there is an extra "router alert" option in IGMP messages which we allow for but do not police */ + if((iphdr_hlen > IP_HLEN) && (IPH_PROTO(iphdr) != IP_PROTO_IGMP)) { +#else + if (iphdr_hlen > IP_HLEN) { +#endif /* LWIP_IGMP */ + LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("IP packet dropped since there were IP options (while IP_OPTIONS_ALLOWED == 0).\n")); + pbuf_free(p); + IP_STATS_INC(ip.opterr); + IP_STATS_INC(ip.drop); + /* unsupported protocol feature */ + snmp_inc_ipinunknownprotos(); + return ERR_OK; + } +#endif /* IP_OPTIONS_ALLOWED == 0 */ + + /* send to upper layers */ + LWIP_DEBUGF(IP_DEBUG, ("ip_input: \n")); + ip_debug_print(p); + LWIP_DEBUGF(IP_DEBUG, ("ip_input: p->len %"U16_F" p->tot_len %"U16_F"\n", p->len, p->tot_len)); + + current_netif = inp; + current_header = iphdr; + +#if LWIP_RAW + /* raw input did not eat the packet? */ + if (raw_input(p, inp) == 0) +#endif /* LWIP_RAW */ + { + switch (IPH_PROTO(iphdr)) { +#if LWIP_UDP + case IP_PROTO_UDP: +#if LWIP_UDPLITE + case IP_PROTO_UDPLITE: +#endif /* LWIP_UDPLITE */ + snmp_inc_ipindelivers(); + udp_input(p, inp); + break; +#endif /* LWIP_UDP */ +#if LWIP_TCP + case IP_PROTO_TCP: + snmp_inc_ipindelivers(); + tcp_input(p, inp); + break; +#endif /* LWIP_TCP */ +#if LWIP_ICMP + case IP_PROTO_ICMP: + snmp_inc_ipindelivers(); + icmp_input(p, inp); + break; +#endif /* LWIP_ICMP */ +#if LWIP_IGMP + case IP_PROTO_IGMP: + igmp_input(p, inp, ¤t_iphdr_dest); + break; +#endif /* LWIP_IGMP */ + default: +#if LWIP_ICMP + /* send ICMP destination protocol unreachable unless is was a broadcast */ + if (!ip_addr_isbroadcast(¤t_iphdr_dest, inp) && + !ip_addr_ismulticast(¤t_iphdr_dest)) { + p->payload = iphdr; + icmp_dest_unreach(p, ICMP_DUR_PROTO); + } +#endif /* LWIP_ICMP */ + pbuf_free(p); + + LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("Unsupported transport protocol %"U16_F"\n", IPH_PROTO(iphdr))); + + IP_STATS_INC(ip.proterr); + IP_STATS_INC(ip.drop); + snmp_inc_ipinunknownprotos(); + } + } + + current_netif = NULL; + current_header = NULL; + ip_addr_set_any(¤t_iphdr_src); + ip_addr_set_any(¤t_iphdr_dest); + + return ERR_OK; +} + +/** + * Sends an IP packet on a network interface. This function constructs + * the IP header and calculates the IP header checksum. If the source + * IP address is NULL, the IP address of the outgoing network + * interface is filled in as source address. + * If the destination IP address is IP_HDRINCL, p is assumed to already + * include an IP header and p->payload points to it instead of the data. + * + * @param p the packet to send (p->payload points to the data, e.g. next + protocol header; if dest == IP_HDRINCL, p already includes an IP + header and p->payload points to that IP header) + * @param src the source IP address to send from (if src == IP_ADDR_ANY, the + * IP address of the netif used to send is used as source address) + * @param dest the destination IP address to send the packet to + * @param ttl the TTL value to be set in the IP header + * @param tos the TOS value to be set in the IP header + * @param proto the PROTOCOL to be set in the IP header + * @param netif the netif on which to send this packet + * @return ERR_OK if the packet was sent OK + * ERR_BUF if p doesn't have enough space for IP/LINK headers + * returns errors returned by netif->output + * + * @note ip_id: RFC791 "some host may be able to simply use + * unique identifiers independent of destination" + */ +err_t +ip_output_if(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest, + u8_t ttl, u8_t tos, + u8_t proto, struct netif *netif) +{ +#if IP_OPTIONS_SEND + return ip_output_if_opt(p, src, dest, ttl, tos, proto, netif, NULL, 0); +} + +/** + * Same as ip_output_if() but with the possibility to include IP options: + * + * @ param ip_options pointer to the IP options, copied into the IP header + * @ param optlen length of ip_options + */ +err_t ip_output_if_opt(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest, + u8_t ttl, u8_t tos, u8_t proto, struct netif *netif, void *ip_options, + u16_t optlen) +{ +#endif /* IP_OPTIONS_SEND */ + struct ip_hdr *iphdr; + ip_addr_t dest_addr; +#if CHECKSUM_GEN_IP_INLINE + u32_t chk_sum = 0; +#endif /* CHECKSUM_GEN_IP_INLINE */ + + /* pbufs passed to IP must have a ref-count of 1 as their payload pointer + gets altered as the packet is passed down the stack */ + LWIP_ASSERT("p->ref == 1", p->ref == 1); + + snmp_inc_ipoutrequests(); + + /* Should the IP header be generated or is it already included in p? */ + if (dest != IP_HDRINCL) { + u16_t ip_hlen = IP_HLEN; +#if IP_OPTIONS_SEND + u16_t optlen_aligned = 0; + if (optlen != 0) { +#if CHECKSUM_GEN_IP_INLINE + int i; +#endif /* CHECKSUM_GEN_IP_INLINE */ + /* round up to a multiple of 4 */ + optlen_aligned = ((optlen + 3) & ~3); + ip_hlen += optlen_aligned; + /* First write in the IP options */ + if (pbuf_header(p, optlen_aligned)) { + LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip_output_if_opt: not enough room for IP options in pbuf\n")); + IP_STATS_INC(ip.err); + snmp_inc_ipoutdiscards(); + return ERR_BUF; + } + MEMCPY(p->payload, ip_options, optlen); + if (optlen < optlen_aligned) { + /* zero the remaining bytes */ + memset(((char*)p->payload) + optlen, 0, optlen_aligned - optlen); + } +#if CHECKSUM_GEN_IP_INLINE + for (i = 0; i < optlen_aligned/2; i++) { + chk_sum += ((u16_t*)p->payload)[i]; + } +#endif /* CHECKSUM_GEN_IP_INLINE */ + } +#endif /* IP_OPTIONS_SEND */ + /* generate IP header */ + if (pbuf_header(p, IP_HLEN)) { + LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip_output: not enough room for IP header in pbuf\n")); + + IP_STATS_INC(ip.err); + snmp_inc_ipoutdiscards(); + return ERR_BUF; + } + + iphdr = (struct ip_hdr *)p->payload; + LWIP_ASSERT("check that first pbuf can hold struct ip_hdr", + (p->len >= sizeof(struct ip_hdr))); + + IPH_TTL_SET(iphdr, ttl); + IPH_PROTO_SET(iphdr, proto); +#if CHECKSUM_GEN_IP_INLINE + chk_sum += LWIP_MAKE_U16(proto, ttl); +#endif /* CHECKSUM_GEN_IP_INLINE */ + + /* dest cannot be NULL here */ + ip_addr_copy(iphdr->dest, *dest); +#if CHECKSUM_GEN_IP_INLINE + chk_sum += ip4_addr_get_u32(&iphdr->dest) & 0xFFFF; + chk_sum += ip4_addr_get_u32(&iphdr->dest) >> 16; +#endif /* CHECKSUM_GEN_IP_INLINE */ + + IPH_VHL_SET(iphdr, 4, ip_hlen / 4); + IPH_TOS_SET(iphdr, tos); +#if CHECKSUM_GEN_IP_INLINE + chk_sum += LWIP_MAKE_U16(tos, iphdr->_v_hl); +#endif /* CHECKSUM_GEN_IP_INLINE */ + IPH_LEN_SET(iphdr, htons(p->tot_len)); +#if CHECKSUM_GEN_IP_INLINE + chk_sum += iphdr->_len; +#endif /* CHECKSUM_GEN_IP_INLINE */ + IPH_OFFSET_SET(iphdr, 0); + IPH_ID_SET(iphdr, htons(ip_id)); +#if CHECKSUM_GEN_IP_INLINE + chk_sum += iphdr->_id; +#endif /* CHECKSUM_GEN_IP_INLINE */ + ++ip_id; + + if (ip_addr_isany(src)) { + ip_addr_copy(iphdr->src, netif->ip_addr); + } else { + /* src cannot be NULL here */ + ip_addr_copy(iphdr->src, *src); + } + +#if CHECKSUM_GEN_IP_INLINE + chk_sum += ip4_addr_get_u32(&iphdr->src) & 0xFFFF; + chk_sum += ip4_addr_get_u32(&iphdr->src) >> 16; + chk_sum = (chk_sum >> 16) + (chk_sum & 0xFFFF); + chk_sum = (chk_sum >> 16) + chk_sum; + chk_sum = ~chk_sum; + iphdr->_chksum = chk_sum; /* network order */ +#else /* CHECKSUM_GEN_IP_INLINE */ + IPH_CHKSUM_SET(iphdr, 0); +#if CHECKSUM_GEN_IP + IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, ip_hlen)); +#endif +#endif /* CHECKSUM_GEN_IP_INLINE */ + } else { + /* IP header already included in p */ + iphdr = (struct ip_hdr *)p->payload; + ip_addr_copy(dest_addr, iphdr->dest); + dest = &dest_addr; + } + + IP_STATS_INC(ip.xmit); + + LWIP_DEBUGF(IP_DEBUG, ("ip_output_if: %c%c%"U16_F"\n", netif->name[0], netif->name[1], netif->num)); + ip_debug_print(p); + +#if ENABLE_LOOPBACK + if (ip_addr_cmp(dest, &netif->ip_addr)) { + /* Packet to self, enqueue it for loopback */ + LWIP_DEBUGF(IP_DEBUG, ("netif_loop_output()")); + return netif_loop_output(netif, p, dest); + } +#if LWIP_IGMP + if ((p->flags & PBUF_FLAG_MCASTLOOP) != 0) { + netif_loop_output(netif, p, dest); + } +#endif /* LWIP_IGMP */ +#endif /* ENABLE_LOOPBACK */ +#if IP_FRAG + /* don't fragment if interface has mtu set to 0 [loopif] */ + if (netif->mtu && (p->tot_len > netif->mtu)) { + return ip_frag(p, netif, dest); + } +#endif /* IP_FRAG */ + + LWIP_DEBUGF(IP_DEBUG, ("netif->output()")); + return netif->output(netif, p, dest); +} + +/** + * Simple interface to ip_output_if. It finds the outgoing network + * interface and calls upon ip_output_if to do the actual work. + * + * @param p the packet to send (p->payload points to the data, e.g. next + protocol header; if dest == IP_HDRINCL, p already includes an IP + header and p->payload points to that IP header) + * @param src the source IP address to send from (if src == IP_ADDR_ANY, the + * IP address of the netif used to send is used as source address) + * @param dest the destination IP address to send the packet to + * @param ttl the TTL value to be set in the IP header + * @param tos the TOS value to be set in the IP header + * @param proto the PROTOCOL to be set in the IP header + * + * @return ERR_RTE if no route is found + * see ip_output_if() for more return values + */ +err_t +ip_output(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest, + u8_t ttl, u8_t tos, u8_t proto) +{ + struct netif *netif; + + /* pbufs passed to IP must have a ref-count of 1 as their payload pointer + gets altered as the packet is passed down the stack */ + LWIP_ASSERT("p->ref == 1", p->ref == 1); + + if ((netif = ip_route(dest)) == NULL) { + LWIP_DEBUGF(IP_DEBUG, ("ip_output: No route to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", + ip4_addr1_16(dest), ip4_addr2_16(dest), ip4_addr3_16(dest), ip4_addr4_16(dest))); + IP_STATS_INC(ip.rterr); + return ERR_RTE; + } + + return ip_output_if(p, src, dest, ttl, tos, proto, netif); +} + +#if LWIP_NETIF_HWADDRHINT +/** Like ip_output, but takes and addr_hint pointer that is passed on to netif->addr_hint + * before calling ip_output_if. + * + * @param p the packet to send (p->payload points to the data, e.g. next + protocol header; if dest == IP_HDRINCL, p already includes an IP + header and p->payload points to that IP header) + * @param src the source IP address to send from (if src == IP_ADDR_ANY, the + * IP address of the netif used to send is used as source address) + * @param dest the destination IP address to send the packet to + * @param ttl the TTL value to be set in the IP header + * @param tos the TOS value to be set in the IP header + * @param proto the PROTOCOL to be set in the IP header + * @param addr_hint address hint pointer set to netif->addr_hint before + * calling ip_output_if() + * + * @return ERR_RTE if no route is found + * see ip_output_if() for more return values + */ +err_t +ip_output_hinted(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest, + u8_t ttl, u8_t tos, u8_t proto, u8_t *addr_hint) +{ + struct netif *netif; + err_t err; + + /* pbufs passed to IP must have a ref-count of 1 as their payload pointer + gets altered as the packet is passed down the stack */ + LWIP_ASSERT("p->ref == 1", p->ref == 1); + + if ((netif = ip_route(dest)) == NULL) { + LWIP_DEBUGF(IP_DEBUG, ("ip_output: No route to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", + ip4_addr1_16(dest), ip4_addr2_16(dest), ip4_addr3_16(dest), ip4_addr4_16(dest))); + IP_STATS_INC(ip.rterr); + return ERR_RTE; + } + + NETIF_SET_HWADDRHINT(netif, addr_hint); + err = ip_output_if(p, src, dest, ttl, tos, proto, netif); + NETIF_SET_HWADDRHINT(netif, NULL); + + return err; +} +#endif /* LWIP_NETIF_HWADDRHINT*/ + +#if IP_DEBUG +/* Print an IP header by using LWIP_DEBUGF + * @param p an IP packet, p->payload pointing to the IP header + */ +void +ip_debug_print(struct pbuf *p) +{ + struct ip_hdr *iphdr = (struct ip_hdr *)p->payload; + + LWIP_DEBUGF(IP_DEBUG, ("IP header:\n")); + LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n")); + LWIP_DEBUGF(IP_DEBUG, ("|%2"S16_F" |%2"S16_F" | 0x%02"X16_F" | %5"U16_F" | (v, hl, tos, len)\n", + IPH_V(iphdr), + IPH_HL(iphdr), + IPH_TOS(iphdr), + ntohs(IPH_LEN(iphdr)))); + LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n")); + LWIP_DEBUGF(IP_DEBUG, ("| %5"U16_F" |%"U16_F"%"U16_F"%"U16_F"| %4"U16_F" | (id, flags, offset)\n", + ntohs(IPH_ID(iphdr)), + ntohs(IPH_OFFSET(iphdr)) >> 15 & 1, + ntohs(IPH_OFFSET(iphdr)) >> 14 & 1, + ntohs(IPH_OFFSET(iphdr)) >> 13 & 1, + ntohs(IPH_OFFSET(iphdr)) & IP_OFFMASK)); + LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n")); + LWIP_DEBUGF(IP_DEBUG, ("| %3"U16_F" | %3"U16_F" | 0x%04"X16_F" | (ttl, proto, chksum)\n", + IPH_TTL(iphdr), + IPH_PROTO(iphdr), + ntohs(IPH_CHKSUM(iphdr)))); + LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n")); + LWIP_DEBUGF(IP_DEBUG, ("| %3"U16_F" | %3"U16_F" | %3"U16_F" | %3"U16_F" | (src)\n", + ip4_addr1_16(&iphdr->src), + ip4_addr2_16(&iphdr->src), + ip4_addr3_16(&iphdr->src), + ip4_addr4_16(&iphdr->src))); + LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n")); + LWIP_DEBUGF(IP_DEBUG, ("| %3"U16_F" | %3"U16_F" | %3"U16_F" | %3"U16_F" | (dest)\n", + ip4_addr1_16(&iphdr->dest), + ip4_addr2_16(&iphdr->dest), + ip4_addr3_16(&iphdr->dest), + ip4_addr4_16(&iphdr->dest))); + LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n")); +} +#endif /* IP_DEBUG */ diff --git a/src/lwip-1.4.1/src/core/ipv4/ip_addr.c b/src/lwip-1.4.1/src/core/ipv4/ip_addr.c new file mode 100644 index 0000000..8f633ff --- /dev/null +++ b/src/lwip-1.4.1/src/core/ipv4/ip_addr.c @@ -0,0 +1,312 @@ +/** + * @file + * This is the IPv4 address tools implementation. + * + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#include "lwip/opt.h" +#include "lwip/ip_addr.h" +#include "lwip/netif.h" + +/* used by IP_ADDR_ANY and IP_ADDR_BROADCAST in ip_addr.h */ +const ip_addr_t ip_addr_any = { IPADDR_ANY }; +const ip_addr_t ip_addr_broadcast = { IPADDR_BROADCAST }; + +/** + * Determine if an address is a broadcast address on a network interface + * + * @param addr address to be checked + * @param netif the network interface against which the address is checked + * @return returns non-zero if the address is a broadcast address + */ +u8_t +ip4_addr_isbroadcast(u32_t addr, const struct netif *netif) +{ + ip_addr_t ipaddr; + ip4_addr_set_u32(&ipaddr, addr); + + /* all ones (broadcast) or all zeroes (old skool broadcast) */ + if ((~addr == IPADDR_ANY) || + (addr == IPADDR_ANY)) { + return 1; + /* no broadcast support on this network interface? */ + } else if ((netif->flags & NETIF_FLAG_BROADCAST) == 0) { + /* the given address cannot be a broadcast address + * nor can we check against any broadcast addresses */ + return 0; + /* address matches network interface address exactly? => no broadcast */ + } else if (addr == ip4_addr_get_u32(&netif->ip_addr)) { + return 0; + /* on the same (sub) network... */ + } else if (ip_addr_netcmp(&ipaddr, &(netif->ip_addr), &(netif->netmask)) + /* ...and host identifier bits are all ones? =>... */ + && ((addr & ~ip4_addr_get_u32(&netif->netmask)) == + (IPADDR_BROADCAST & ~ip4_addr_get_u32(&netif->netmask)))) { + /* => network broadcast address */ + return 1; + } else { + return 0; + } +} + +/** Checks if a netmask is valid (starting with ones, then only zeros) + * + * @param netmask the IPv4 netmask to check (in network byte order!) + * @return 1 if the netmask is valid, 0 if it is not + */ +u8_t +ip4_addr_netmask_valid(u32_t netmask) +{ + u32_t mask; + u32_t nm_hostorder = lwip_htonl(netmask); + + /* first, check for the first zero */ + for (mask = 1UL << 31 ; mask != 0; mask >>= 1) { + if ((nm_hostorder & mask) == 0) { + break; + } + } + /* then check that there is no one */ + for (; mask != 0; mask >>= 1) { + if ((nm_hostorder & mask) != 0) { + /* there is a one after the first zero -> invalid */ + return 0; + } + } + /* no one after the first zero -> valid */ + return 1; +} + +/* Here for now until needed in other places in lwIP */ +#ifndef isprint +#define in_range(c, lo, up) ((u8_t)c >= lo && (u8_t)c <= up) +#define isprint(c) in_range(c, 0x20, 0x7f) +#define isdigit(c) in_range(c, '0', '9') +#define isxdigit(c) (isdigit(c) || in_range(c, 'a', 'f') || in_range(c, 'A', 'F')) +#define islower(c) in_range(c, 'a', 'z') +#define isspace(c) (c == ' ' || c == '\f' || c == '\n' || c == '\r' || c == '\t' || c == '\v') +#endif + +/** + * Ascii internet address interpretation routine. + * The value returned is in network order. + * + * @param cp IP address in ascii represenation (e.g. "127.0.0.1") + * @return ip address in network order + */ +u32_t +ipaddr_addr(const char *cp) +{ + ip_addr_t val; + + if (ipaddr_aton(cp, &val)) { + return ip4_addr_get_u32(&val); + } + return (IPADDR_NONE); +} + +/** + * Check whether "cp" is a valid ascii representation + * of an Internet address and convert to a binary address. + * Returns 1 if the address is valid, 0 if not. + * This replaces inet_addr, the return value from which + * cannot distinguish between failure and a local broadcast address. + * + * @param cp IP address in ascii represenation (e.g. "127.0.0.1") + * @param addr pointer to which to save the ip address in network order + * @return 1 if cp could be converted to addr, 0 on failure + */ +int +ipaddr_aton(const char *cp, ip_addr_t *addr) +{ + u32_t val; + u8_t base; + char c; + u32_t parts[4]; + u32_t *pp = parts; + + c = *cp; + for (;;) { + /* + * Collect number up to ``.''. + * Values are specified as for C: + * 0x=hex, 0=octal, 1-9=decimal. + */ + if (!isdigit(c)) + return (0); + val = 0; + base = 10; + if (c == '0') { + c = *++cp; + if (c == 'x' || c == 'X') { + base = 16; + c = *++cp; + } else + base = 8; + } + for (;;) { + if (isdigit(c)) { + val = (val * base) + (int)(c - '0'); + c = *++cp; + } else if (base == 16 && isxdigit(c)) { + val = (val << 4) | (int)(c + 10 - (islower(c) ? 'a' : 'A')); + c = *++cp; + } else + break; + } + if (c == '.') { + /* + * Internet format: + * a.b.c.d + * a.b.c (with c treated as 16 bits) + * a.b (with b treated as 24 bits) + */ + if (pp >= parts + 3) { + return (0); + } + *pp++ = val; + c = *++cp; + } else + break; + } + /* + * Check for trailing characters. + */ + if (c != '\0' && !isspace(c)) { + return (0); + } + /* + * Concoct the address according to + * the number of parts specified. + */ + switch (pp - parts + 1) { + + case 0: + return (0); /* initial nondigit */ + + case 1: /* a -- 32 bits */ + break; + + case 2: /* a.b -- 8.24 bits */ + if (val > 0xffffffUL) { + return (0); + } + val |= parts[0] << 24; + break; + + case 3: /* a.b.c -- 8.8.16 bits */ + if (val > 0xffff) { + return (0); + } + val |= (parts[0] << 24) | (parts[1] << 16); + break; + + case 4: /* a.b.c.d -- 8.8.8.8 bits */ + if (val > 0xff) { + return (0); + } + val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8); + break; + default: + LWIP_ASSERT("unhandled", 0); + break; + } + if (addr) { + ip4_addr_set_u32(addr, htonl(val)); + } + return (1); +} + +/** + * Convert numeric IP address into decimal dotted ASCII representation. + * returns ptr to static buffer; not reentrant! + * + * @param addr ip address in network order to convert + * @return pointer to a global static (!) buffer that holds the ASCII + * represenation of addr + */ +char * +ipaddr_ntoa(const ip_addr_t *addr) +{ + static char str[16]; + return ipaddr_ntoa_r(addr, str, 16); +} + +/** + * Same as ipaddr_ntoa, but reentrant since a user-supplied buffer is used. + * + * @param addr ip address in network order to convert + * @param buf target buffer where the string is stored + * @param buflen length of buf + * @return either pointer to buf which now holds the ASCII + * representation of addr or NULL if buf was too small + */ +char *ipaddr_ntoa_r(const ip_addr_t *addr, char *buf, int buflen) +{ + u32_t s_addr; + char inv[3]; + char *rp; + u8_t *ap; + u8_t rem; + u8_t n; + u8_t i; + int len = 0; + + s_addr = ip4_addr_get_u32(addr); + + rp = buf; + ap = (u8_t *)&s_addr; + for(n = 0; n < 4; n++) { + i = 0; + do { + rem = *ap % (u8_t)10; + *ap /= (u8_t)10; + inv[i++] = '0' + rem; + } while(*ap); + while(i--) { + if (len++ >= buflen) { + return NULL; + } + *rp++ = inv[i]; + } + if (len++ >= buflen) { + return NULL; + } + *rp++ = '.'; + ap++; + } + *--rp = 0; + return buf; +} diff --git a/src/lwip-1.4.1/src/core/ipv4/ip_frag.c b/src/lwip-1.4.1/src/core/ipv4/ip_frag.c new file mode 100644 index 0000000..8d18434 --- /dev/null +++ b/src/lwip-1.4.1/src/core/ipv4/ip_frag.c @@ -0,0 +1,863 @@ +/** + * @file + * This is the IPv4 packet segmentation and reassembly implementation. + * + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Jani Monoses + * Simon Goldschmidt + * original reassembly code by Adam Dunkels + * + */ + +#include "lwip/opt.h" +#include "lwip/ip_frag.h" +#include "lwip/def.h" +#include "lwip/inet_chksum.h" +#include "lwip/netif.h" +#include "lwip/snmp.h" +#include "lwip/stats.h" +#include "lwip/icmp.h" + +#include + +#if IP_REASSEMBLY +/** + * The IP reassembly code currently has the following limitations: + * - IP header options are not supported + * - fragments must not overlap (e.g. due to different routes), + * currently, overlapping or duplicate fragments are thrown away + * if IP_REASS_CHECK_OVERLAP=1 (the default)! + * + * @todo: work with IP header options + */ + +/** Setting this to 0, you can turn off checking the fragments for overlapping + * regions. The code gets a little smaller. Only use this if you know that + * overlapping won't occur on your network! */ +#ifndef IP_REASS_CHECK_OVERLAP +#define IP_REASS_CHECK_OVERLAP 1 +#endif /* IP_REASS_CHECK_OVERLAP */ + +/** Set to 0 to prevent freeing the oldest datagram when the reassembly buffer is + * full (IP_REASS_MAX_PBUFS pbufs are enqueued). The code gets a little smaller. + * Datagrams will be freed by timeout only. Especially useful when MEMP_NUM_REASSDATA + * is set to 1, so one datagram can be reassembled at a time, only. */ +#ifndef IP_REASS_FREE_OLDEST +#define IP_REASS_FREE_OLDEST 1 +#endif /* IP_REASS_FREE_OLDEST */ + +#define IP_REASS_FLAG_LASTFRAG 0x01 + +/** This is a helper struct which holds the starting + * offset and the ending offset of this fragment to + * easily chain the fragments. + * It has the same packing requirements as the IP header, since it replaces + * the IP header in memory in incoming fragments (after copying it) to keep + * track of the various fragments. (-> If the IP header doesn't need packing, + * this struct doesn't need packing, too.) + */ +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct ip_reass_helper { + PACK_STRUCT_FIELD(struct pbuf *next_pbuf); + PACK_STRUCT_FIELD(u16_t start); + PACK_STRUCT_FIELD(u16_t end); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +#define IP_ADDRESSES_AND_ID_MATCH(iphdrA, iphdrB) \ + (ip_addr_cmp(&(iphdrA)->src, &(iphdrB)->src) && \ + ip_addr_cmp(&(iphdrA)->dest, &(iphdrB)->dest) && \ + IPH_ID(iphdrA) == IPH_ID(iphdrB)) ? 1 : 0 + +/* global variables */ +static struct ip_reassdata *reassdatagrams; +static u16_t ip_reass_pbufcount; + +/* function prototypes */ +static void ip_reass_dequeue_datagram(struct ip_reassdata *ipr, struct ip_reassdata *prev); +static int ip_reass_free_complete_datagram(struct ip_reassdata *ipr, struct ip_reassdata *prev); + +/** + * Reassembly timer base function + * for both NO_SYS == 0 and 1 (!). + * + * Should be called every 1000 msec (defined by IP_TMR_INTERVAL). + */ +void +ip_reass_tmr(void) +{ + struct ip_reassdata *r, *prev = NULL; + + r = reassdatagrams; + while (r != NULL) { + /* Decrement the timer. Once it reaches 0, + * clean up the incomplete fragment assembly */ + if (r->timer > 0) { + r->timer--; + LWIP_DEBUGF(IP_REASS_DEBUG, ("ip_reass_tmr: timer dec %"U16_F"\n",(u16_t)r->timer)); + prev = r; + r = r->next; + } else { + /* reassembly timed out */ + struct ip_reassdata *tmp; + LWIP_DEBUGF(IP_REASS_DEBUG, ("ip_reass_tmr: timer timed out\n")); + tmp = r; + /* get the next pointer before freeing */ + r = r->next; + /* free the helper struct and all enqueued pbufs */ + ip_reass_free_complete_datagram(tmp, prev); + } + } +} + +/** + * Free a datagram (struct ip_reassdata) and all its pbufs. + * Updates the total count of enqueued pbufs (ip_reass_pbufcount), + * SNMP counters and sends an ICMP time exceeded packet. + * + * @param ipr datagram to free + * @param prev the previous datagram in the linked list + * @return the number of pbufs freed + */ +static int +ip_reass_free_complete_datagram(struct ip_reassdata *ipr, struct ip_reassdata *prev) +{ + u16_t pbufs_freed = 0; + u8_t clen; + struct pbuf *p; + struct ip_reass_helper *iprh; + + LWIP_ASSERT("prev != ipr", prev != ipr); + if (prev != NULL) { + LWIP_ASSERT("prev->next == ipr", prev->next == ipr); + } + + snmp_inc_ipreasmfails(); +#if LWIP_ICMP + iprh = (struct ip_reass_helper *)ipr->p->payload; + if (iprh->start == 0) { + /* The first fragment was received, send ICMP time exceeded. */ + /* First, de-queue the first pbuf from r->p. */ + p = ipr->p; + ipr->p = iprh->next_pbuf; + /* Then, copy the original header into it. */ + SMEMCPY(p->payload, &ipr->iphdr, IP_HLEN); + icmp_time_exceeded(p, ICMP_TE_FRAG); + clen = pbuf_clen(p); + LWIP_ASSERT("pbufs_freed + clen <= 0xffff", pbufs_freed + clen <= 0xffff); + pbufs_freed += clen; + pbuf_free(p); + } +#endif /* LWIP_ICMP */ + + /* First, free all received pbufs. The individual pbufs need to be released + separately as they have not yet been chained */ + p = ipr->p; + while (p != NULL) { + struct pbuf *pcur; + iprh = (struct ip_reass_helper *)p->payload; + pcur = p; + /* get the next pointer before freeing */ + p = iprh->next_pbuf; + clen = pbuf_clen(pcur); + LWIP_ASSERT("pbufs_freed + clen <= 0xffff", pbufs_freed + clen <= 0xffff); + pbufs_freed += clen; + pbuf_free(pcur); + } + /* Then, unchain the struct ip_reassdata from the list and free it. */ + ip_reass_dequeue_datagram(ipr, prev); + LWIP_ASSERT("ip_reass_pbufcount >= clen", ip_reass_pbufcount >= pbufs_freed); + ip_reass_pbufcount -= pbufs_freed; + + return pbufs_freed; +} + +#if IP_REASS_FREE_OLDEST +/** + * Free the oldest datagram to make room for enqueueing new fragments. + * The datagram 'fraghdr' belongs to is not freed! + * + * @param fraghdr IP header of the current fragment + * @param pbufs_needed number of pbufs needed to enqueue + * (used for freeing other datagrams if not enough space) + * @return the number of pbufs freed + */ +static int +ip_reass_remove_oldest_datagram(struct ip_hdr *fraghdr, int pbufs_needed) +{ + /* @todo Can't we simply remove the last datagram in the + * linked list behind reassdatagrams? + */ + struct ip_reassdata *r, *oldest, *prev; + int pbufs_freed = 0, pbufs_freed_current; + int other_datagrams; + + /* Free datagrams until being allowed to enqueue 'pbufs_needed' pbufs, + * but don't free the datagram that 'fraghdr' belongs to! */ + do { + oldest = NULL; + prev = NULL; + other_datagrams = 0; + r = reassdatagrams; + while (r != NULL) { + if (!IP_ADDRESSES_AND_ID_MATCH(&r->iphdr, fraghdr)) { + /* Not the same datagram as fraghdr */ + other_datagrams++; + if (oldest == NULL) { + oldest = r; + } else if (r->timer <= oldest->timer) { + /* older than the previous oldest */ + oldest = r; + } + } + if (r->next != NULL) { + prev = r; + } + r = r->next; + } + if (oldest != NULL) { + pbufs_freed_current = ip_reass_free_complete_datagram(oldest, prev); + pbufs_freed += pbufs_freed_current; + } + } while ((pbufs_freed < pbufs_needed) && (other_datagrams > 1)); + return pbufs_freed; +} +#endif /* IP_REASS_FREE_OLDEST */ + +/** + * Enqueues a new fragment into the fragment queue + * @param fraghdr points to the new fragments IP hdr + * @param clen number of pbufs needed to enqueue (used for freeing other datagrams if not enough space) + * @return A pointer to the queue location into which the fragment was enqueued + */ +static struct ip_reassdata* +ip_reass_enqueue_new_datagram(struct ip_hdr *fraghdr, int clen) +{ + struct ip_reassdata* ipr; + /* No matching previous fragment found, allocate a new reassdata struct */ + ipr = (struct ip_reassdata *)memp_malloc(MEMP_REASSDATA); + if (ipr == NULL) { +#if IP_REASS_FREE_OLDEST + if (ip_reass_remove_oldest_datagram(fraghdr, clen) >= clen) { + ipr = (struct ip_reassdata *)memp_malloc(MEMP_REASSDATA); + } + if (ipr == NULL) +#endif /* IP_REASS_FREE_OLDEST */ + { + IPFRAG_STATS_INC(ip_frag.memerr); + LWIP_DEBUGF(IP_REASS_DEBUG,("Failed to alloc reassdata struct\n")); + return NULL; + } + } + memset(ipr, 0, sizeof(struct ip_reassdata)); + ipr->timer = IP_REASS_MAXAGE; + + /* enqueue the new structure to the front of the list */ + ipr->next = reassdatagrams; + reassdatagrams = ipr; + /* copy the ip header for later tests and input */ + /* @todo: no ip options supported? */ + SMEMCPY(&(ipr->iphdr), fraghdr, IP_HLEN); + return ipr; +} + +/** + * Dequeues a datagram from the datagram queue. Doesn't deallocate the pbufs. + * @param ipr points to the queue entry to dequeue + */ +static void +ip_reass_dequeue_datagram(struct ip_reassdata *ipr, struct ip_reassdata *prev) +{ + + /* dequeue the reass struct */ + if (reassdatagrams == ipr) { + /* it was the first in the list */ + reassdatagrams = ipr->next; + } else { + /* it wasn't the first, so it must have a valid 'prev' */ + LWIP_ASSERT("sanity check linked list", prev != NULL); + prev->next = ipr->next; + } + + /* now we can free the ip_reass struct */ + memp_free(MEMP_REASSDATA, ipr); +} + +/** + * Chain a new pbuf into the pbuf list that composes the datagram. The pbuf list + * will grow over time as new pbufs are rx. + * Also checks that the datagram passes basic continuity checks (if the last + * fragment was received at least once). + * @param root_p points to the 'root' pbuf for the current datagram being assembled. + * @param new_p points to the pbuf for the current fragment + * @return 0 if invalid, >0 otherwise + */ +static int +ip_reass_chain_frag_into_datagram_and_validate(struct ip_reassdata *ipr, struct pbuf *new_p) +{ + struct ip_reass_helper *iprh, *iprh_tmp, *iprh_prev=NULL; + struct pbuf *q; + u16_t offset,len; + struct ip_hdr *fraghdr; + int valid = 1; + + /* Extract length and fragment offset from current fragment */ + fraghdr = (struct ip_hdr*)new_p->payload; + len = ntohs(IPH_LEN(fraghdr)) - IPH_HL(fraghdr) * 4; + offset = (ntohs(IPH_OFFSET(fraghdr)) & IP_OFFMASK) * 8; + + /* overwrite the fragment's ip header from the pbuf with our helper struct, + * and setup the embedded helper structure. */ + /* make sure the struct ip_reass_helper fits into the IP header */ + LWIP_ASSERT("sizeof(struct ip_reass_helper) <= IP_HLEN", + sizeof(struct ip_reass_helper) <= IP_HLEN); + iprh = (struct ip_reass_helper*)new_p->payload; + iprh->next_pbuf = NULL; + iprh->start = offset; + iprh->end = offset + len; + + /* Iterate through until we either get to the end of the list (append), + * or we find on with a larger offset (insert). */ + for (q = ipr->p; q != NULL;) { + iprh_tmp = (struct ip_reass_helper*)q->payload; + if (iprh->start < iprh_tmp->start) { + /* the new pbuf should be inserted before this */ + iprh->next_pbuf = q; + if (iprh_prev != NULL) { + /* not the fragment with the lowest offset */ +#if IP_REASS_CHECK_OVERLAP + if ((iprh->start < iprh_prev->end) || (iprh->end > iprh_tmp->start)) { + /* fragment overlaps with previous or following, throw away */ + goto freepbuf; + } +#endif /* IP_REASS_CHECK_OVERLAP */ + iprh_prev->next_pbuf = new_p; + } else { + /* fragment with the lowest offset */ + ipr->p = new_p; + } + break; + } else if(iprh->start == iprh_tmp->start) { + /* received the same datagram twice: no need to keep the datagram */ + goto freepbuf; +#if IP_REASS_CHECK_OVERLAP + } else if(iprh->start < iprh_tmp->end) { + /* overlap: no need to keep the new datagram */ + goto freepbuf; +#endif /* IP_REASS_CHECK_OVERLAP */ + } else { + /* Check if the fragments received so far have no wholes. */ + if (iprh_prev != NULL) { + if (iprh_prev->end != iprh_tmp->start) { + /* There is a fragment missing between the current + * and the previous fragment */ + valid = 0; + } + } + } + q = iprh_tmp->next_pbuf; + iprh_prev = iprh_tmp; + } + + /* If q is NULL, then we made it to the end of the list. Determine what to do now */ + if (q == NULL) { + if (iprh_prev != NULL) { + /* this is (for now), the fragment with the highest offset: + * chain it to the last fragment */ +#if IP_REASS_CHECK_OVERLAP + LWIP_ASSERT("check fragments don't overlap", iprh_prev->end <= iprh->start); +#endif /* IP_REASS_CHECK_OVERLAP */ + iprh_prev->next_pbuf = new_p; + if (iprh_prev->end != iprh->start) { + valid = 0; + } + } else { +#if IP_REASS_CHECK_OVERLAP + LWIP_ASSERT("no previous fragment, this must be the first fragment!", + ipr->p == NULL); +#endif /* IP_REASS_CHECK_OVERLAP */ + /* this is the first fragment we ever received for this ip datagram */ + ipr->p = new_p; + } + } + + /* At this point, the validation part begins: */ + /* If we already received the last fragment */ + if ((ipr->flags & IP_REASS_FLAG_LASTFRAG) != 0) { + /* and had no wholes so far */ + if (valid) { + /* then check if the rest of the fragments is here */ + /* Check if the queue starts with the first datagram */ + if (((struct ip_reass_helper*)ipr->p->payload)->start != 0) { + valid = 0; + } else { + /* and check that there are no wholes after this datagram */ + iprh_prev = iprh; + q = iprh->next_pbuf; + while (q != NULL) { + iprh = (struct ip_reass_helper*)q->payload; + if (iprh_prev->end != iprh->start) { + valid = 0; + break; + } + iprh_prev = iprh; + q = iprh->next_pbuf; + } + /* if still valid, all fragments are received + * (because to the MF==0 already arrived */ + if (valid) { + LWIP_ASSERT("sanity check", ipr->p != NULL); + LWIP_ASSERT("sanity check", + ((struct ip_reass_helper*)ipr->p->payload) != iprh); + LWIP_ASSERT("validate_datagram:next_pbuf!=NULL", + iprh->next_pbuf == NULL); + LWIP_ASSERT("validate_datagram:datagram end!=datagram len", + iprh->end == ipr->datagram_len); + } + } + } + /* If valid is 0 here, there are some fragments missing in the middle + * (since MF == 0 has already arrived). Such datagrams simply time out if + * no more fragments are received... */ + return valid; + } + /* If we come here, not all fragments were received, yet! */ + return 0; /* not yet valid! */ +#if IP_REASS_CHECK_OVERLAP +freepbuf: + ip_reass_pbufcount -= pbuf_clen(new_p); + pbuf_free(new_p); + return 0; +#endif /* IP_REASS_CHECK_OVERLAP */ +} + +/** + * Reassembles incoming IP fragments into an IP datagram. + * + * @param p points to a pbuf chain of the fragment + * @return NULL if reassembly is incomplete, ? otherwise + */ +struct pbuf * +ip_reass(struct pbuf *p) +{ + struct pbuf *r; + struct ip_hdr *fraghdr; + struct ip_reassdata *ipr; + struct ip_reass_helper *iprh; + u16_t offset, len; + u8_t clen; + struct ip_reassdata *ipr_prev = NULL; + + IPFRAG_STATS_INC(ip_frag.recv); + snmp_inc_ipreasmreqds(); + + fraghdr = (struct ip_hdr*)p->payload; + + if ((IPH_HL(fraghdr) * 4) != IP_HLEN) { + LWIP_DEBUGF(IP_REASS_DEBUG,("ip_reass: IP options currently not supported!\n")); + IPFRAG_STATS_INC(ip_frag.err); + goto nullreturn; + } + + offset = (ntohs(IPH_OFFSET(fraghdr)) & IP_OFFMASK) * 8; + len = ntohs(IPH_LEN(fraghdr)) - IPH_HL(fraghdr) * 4; + + /* Check if we are allowed to enqueue more datagrams. */ + clen = pbuf_clen(p); + if ((ip_reass_pbufcount + clen) > IP_REASS_MAX_PBUFS) { +#if IP_REASS_FREE_OLDEST + if (!ip_reass_remove_oldest_datagram(fraghdr, clen) || + ((ip_reass_pbufcount + clen) > IP_REASS_MAX_PBUFS)) +#endif /* IP_REASS_FREE_OLDEST */ + { + /* No datagram could be freed and still too many pbufs enqueued */ + LWIP_DEBUGF(IP_REASS_DEBUG,("ip_reass: Overflow condition: pbufct=%d, clen=%d, MAX=%d\n", + ip_reass_pbufcount, clen, IP_REASS_MAX_PBUFS)); + IPFRAG_STATS_INC(ip_frag.memerr); + /* @todo: send ICMP time exceeded here? */ + /* drop this pbuf */ + goto nullreturn; + } + } + + /* Look for the datagram the fragment belongs to in the current datagram queue, + * remembering the previous in the queue for later dequeueing. */ + for (ipr = reassdatagrams; ipr != NULL; ipr = ipr->next) { + /* Check if the incoming fragment matches the one currently present + in the reassembly buffer. If so, we proceed with copying the + fragment into the buffer. */ + if (IP_ADDRESSES_AND_ID_MATCH(&ipr->iphdr, fraghdr)) { + LWIP_DEBUGF(IP_REASS_DEBUG, ("ip_reass: matching previous fragment ID=%"X16_F"\n", + ntohs(IPH_ID(fraghdr)))); + IPFRAG_STATS_INC(ip_frag.cachehit); + break; + } + ipr_prev = ipr; + } + + if (ipr == NULL) { + /* Enqueue a new datagram into the datagram queue */ + ipr = ip_reass_enqueue_new_datagram(fraghdr, clen); + /* Bail if unable to enqueue */ + if(ipr == NULL) { + goto nullreturn; + } + } else { + if (((ntohs(IPH_OFFSET(fraghdr)) & IP_OFFMASK) == 0) && + ((ntohs(IPH_OFFSET(&ipr->iphdr)) & IP_OFFMASK) != 0)) { + /* ipr->iphdr is not the header from the first fragment, but fraghdr is + * -> copy fraghdr into ipr->iphdr since we want to have the header + * of the first fragment (for ICMP time exceeded and later, for copying + * all options, if supported)*/ + SMEMCPY(&ipr->iphdr, fraghdr, IP_HLEN); + } + } + /* Track the current number of pbufs current 'in-flight', in order to limit + the number of fragments that may be enqueued at any one time */ + ip_reass_pbufcount += clen; + + /* At this point, we have either created a new entry or pointing + * to an existing one */ + + /* check for 'no more fragments', and update queue entry*/ + if ((IPH_OFFSET(fraghdr) & PP_NTOHS(IP_MF)) == 0) { + ipr->flags |= IP_REASS_FLAG_LASTFRAG; + ipr->datagram_len = offset + len; + LWIP_DEBUGF(IP_REASS_DEBUG, + ("ip_reass: last fragment seen, total len %"S16_F"\n", + ipr->datagram_len)); + } + /* find the right place to insert this pbuf */ + /* @todo: trim pbufs if fragments are overlapping */ + if (ip_reass_chain_frag_into_datagram_and_validate(ipr, p)) { + /* the totally last fragment (flag more fragments = 0) was received at least + * once AND all fragments are received */ + ipr->datagram_len += IP_HLEN; + + /* save the second pbuf before copying the header over the pointer */ + r = ((struct ip_reass_helper*)ipr->p->payload)->next_pbuf; + + /* copy the original ip header back to the first pbuf */ + fraghdr = (struct ip_hdr*)(ipr->p->payload); + SMEMCPY(fraghdr, &ipr->iphdr, IP_HLEN); + IPH_LEN_SET(fraghdr, htons(ipr->datagram_len)); + IPH_OFFSET_SET(fraghdr, 0); + IPH_CHKSUM_SET(fraghdr, 0); + /* @todo: do we need to set calculate the correct checksum? */ + IPH_CHKSUM_SET(fraghdr, inet_chksum(fraghdr, IP_HLEN)); + + p = ipr->p; + + /* chain together the pbufs contained within the reass_data list. */ + while(r != NULL) { + iprh = (struct ip_reass_helper*)r->payload; + + /* hide the ip header for every succeding fragment */ + pbuf_header(r, -IP_HLEN); + pbuf_cat(p, r); + r = iprh->next_pbuf; + } + /* release the sources allocate for the fragment queue entry */ + ip_reass_dequeue_datagram(ipr, ipr_prev); + + /* and adjust the number of pbufs currently queued for reassembly. */ + ip_reass_pbufcount -= pbuf_clen(p); + + /* Return the pbuf chain */ + return p; + } + /* the datagram is not (yet?) reassembled completely */ + LWIP_DEBUGF(IP_REASS_DEBUG,("ip_reass_pbufcount: %d out\n", ip_reass_pbufcount)); + return NULL; + +nullreturn: + LWIP_DEBUGF(IP_REASS_DEBUG,("ip_reass: nullreturn\n")); + IPFRAG_STATS_INC(ip_frag.drop); + pbuf_free(p); + return NULL; +} +#endif /* IP_REASSEMBLY */ + +#if IP_FRAG +#if IP_FRAG_USES_STATIC_BUF +static u8_t buf[LWIP_MEM_ALIGN_SIZE(IP_FRAG_MAX_MTU + MEM_ALIGNMENT - 1)]; +#else /* IP_FRAG_USES_STATIC_BUF */ + +#if !LWIP_NETIF_TX_SINGLE_PBUF +/** Allocate a new struct pbuf_custom_ref */ +static struct pbuf_custom_ref* +ip_frag_alloc_pbuf_custom_ref(void) +{ + return (struct pbuf_custom_ref*)memp_malloc(MEMP_FRAG_PBUF); +} + +/** Free a struct pbuf_custom_ref */ +static void +ip_frag_free_pbuf_custom_ref(struct pbuf_custom_ref* p) +{ + LWIP_ASSERT("p != NULL", p != NULL); + memp_free(MEMP_FRAG_PBUF, p); +} + +/** Free-callback function to free a 'struct pbuf_custom_ref', called by + * pbuf_free. */ +static void +ipfrag_free_pbuf_custom(struct pbuf *p) +{ + struct pbuf_custom_ref *pcr = (struct pbuf_custom_ref*)p; + LWIP_ASSERT("pcr != NULL", pcr != NULL); + LWIP_ASSERT("pcr == p", (void*)pcr == (void*)p); + if (pcr->original != NULL) { + pbuf_free(pcr->original); + } + ip_frag_free_pbuf_custom_ref(pcr); +} +#endif /* !LWIP_NETIF_TX_SINGLE_PBUF */ +#endif /* IP_FRAG_USES_STATIC_BUF */ + +/** + * Fragment an IP datagram if too large for the netif. + * + * Chop the datagram in MTU sized chunks and send them in order + * by using a fixed size static memory buffer (PBUF_REF) or + * point PBUF_REFs into p (depending on IP_FRAG_USES_STATIC_BUF). + * + * @param p ip packet to send + * @param netif the netif on which to send + * @param dest destination ip address to which to send + * + * @return ERR_OK if sent successfully, err_t otherwise + */ +err_t +ip_frag(struct pbuf *p, struct netif *netif, ip_addr_t *dest) +{ + struct pbuf *rambuf; +#if IP_FRAG_USES_STATIC_BUF + struct pbuf *header; +#else +#if !LWIP_NETIF_TX_SINGLE_PBUF + struct pbuf *newpbuf; +#endif + struct ip_hdr *original_iphdr; +#endif + struct ip_hdr *iphdr; + u16_t nfb; + u16_t left, cop; + u16_t mtu = netif->mtu; + u16_t ofo, omf; + u16_t last; + u16_t poff = IP_HLEN; + u16_t tmp; +#if !IP_FRAG_USES_STATIC_BUF && !LWIP_NETIF_TX_SINGLE_PBUF + u16_t newpbuflen = 0; + u16_t left_to_copy; +#endif + + /* Get a RAM based MTU sized pbuf */ +#if IP_FRAG_USES_STATIC_BUF + /* When using a static buffer, we use a PBUF_REF, which we will + * use to reference the packet (without link header). + * Layer and length is irrelevant. + */ + rambuf = pbuf_alloc(PBUF_LINK, 0, PBUF_REF); + if (rambuf == NULL) { + LWIP_DEBUGF(IP_REASS_DEBUG, ("ip_frag: pbuf_alloc(PBUF_LINK, 0, PBUF_REF) failed\n")); + return ERR_MEM; + } + rambuf->tot_len = rambuf->len = mtu; + rambuf->payload = LWIP_MEM_ALIGN((void *)buf); + + /* Copy the IP header in it */ + iphdr = (struct ip_hdr *)rambuf->payload; + SMEMCPY(iphdr, p->payload, IP_HLEN); +#else /* IP_FRAG_USES_STATIC_BUF */ + original_iphdr = (struct ip_hdr *)p->payload; + iphdr = original_iphdr; +#endif /* IP_FRAG_USES_STATIC_BUF */ + + /* Save original offset */ + tmp = ntohs(IPH_OFFSET(iphdr)); + ofo = tmp & IP_OFFMASK; + omf = tmp & IP_MF; + + left = p->tot_len - IP_HLEN; + + nfb = (mtu - IP_HLEN) / 8; + + while (left) { + last = (left <= mtu - IP_HLEN); + + /* Set new offset and MF flag */ + tmp = omf | (IP_OFFMASK & (ofo)); + if (!last) { + tmp = tmp | IP_MF; + } + + /* Fill this fragment */ + cop = last ? left : nfb * 8; + +#if IP_FRAG_USES_STATIC_BUF + poff += pbuf_copy_partial(p, (u8_t*)iphdr + IP_HLEN, cop, poff); +#else /* IP_FRAG_USES_STATIC_BUF */ +#if LWIP_NETIF_TX_SINGLE_PBUF + rambuf = pbuf_alloc(PBUF_IP, cop, PBUF_RAM); + if (rambuf == NULL) { + return ERR_MEM; + } + LWIP_ASSERT("this needs a pbuf in one piece!", + (rambuf->len == rambuf->tot_len) && (rambuf->next == NULL)); + poff += pbuf_copy_partial(p, rambuf->payload, cop, poff); + /* make room for the IP header */ + if(pbuf_header(rambuf, IP_HLEN)) { + pbuf_free(rambuf); + return ERR_MEM; + } + /* fill in the IP header */ + SMEMCPY(rambuf->payload, original_iphdr, IP_HLEN); + iphdr = rambuf->payload; +#else /* LWIP_NETIF_TX_SINGLE_PBUF */ + /* When not using a static buffer, create a chain of pbufs. + * The first will be a PBUF_RAM holding the link and IP header. + * The rest will be PBUF_REFs mirroring the pbuf chain to be fragged, + * but limited to the size of an mtu. + */ + rambuf = pbuf_alloc(PBUF_LINK, IP_HLEN, PBUF_RAM); + if (rambuf == NULL) { + return ERR_MEM; + } + LWIP_ASSERT("this needs a pbuf in one piece!", + (p->len >= (IP_HLEN))); + SMEMCPY(rambuf->payload, original_iphdr, IP_HLEN); + iphdr = (struct ip_hdr *)rambuf->payload; + + /* Can just adjust p directly for needed offset. */ + p->payload = (u8_t *)p->payload + poff; + p->len -= poff; + + left_to_copy = cop; + while (left_to_copy) { + struct pbuf_custom_ref *pcr; + newpbuflen = (left_to_copy < p->len) ? left_to_copy : p->len; + /* Is this pbuf already empty? */ + if (!newpbuflen) { + p = p->next; + continue; + } + pcr = ip_frag_alloc_pbuf_custom_ref(); + if (pcr == NULL) { + pbuf_free(rambuf); + return ERR_MEM; + } + /* Mirror this pbuf, although we might not need all of it. */ + newpbuf = pbuf_alloced_custom(PBUF_RAW, newpbuflen, PBUF_REF, &pcr->pc, p->payload, newpbuflen); + if (newpbuf == NULL) { + ip_frag_free_pbuf_custom_ref(pcr); + pbuf_free(rambuf); + return ERR_MEM; + } + pbuf_ref(p); + pcr->original = p; + pcr->pc.custom_free_function = ipfrag_free_pbuf_custom; + + /* Add it to end of rambuf's chain, but using pbuf_cat, not pbuf_chain + * so that it is removed when pbuf_dechain is later called on rambuf. + */ + pbuf_cat(rambuf, newpbuf); + left_to_copy -= newpbuflen; + if (left_to_copy) { + p = p->next; + } + } + poff = newpbuflen; +#endif /* LWIP_NETIF_TX_SINGLE_PBUF */ +#endif /* IP_FRAG_USES_STATIC_BUF */ + + /* Correct header */ + IPH_OFFSET_SET(iphdr, htons(tmp)); + IPH_LEN_SET(iphdr, htons(cop + IP_HLEN)); + IPH_CHKSUM_SET(iphdr, 0); + IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, IP_HLEN)); + +#if IP_FRAG_USES_STATIC_BUF + if (last) { + pbuf_realloc(rambuf, left + IP_HLEN); + } + + /* This part is ugly: we alloc a RAM based pbuf for + * the link level header for each chunk and then + * free it.A PBUF_ROM style pbuf for which pbuf_header + * worked would make things simpler. + */ + header = pbuf_alloc(PBUF_LINK, 0, PBUF_RAM); + if (header != NULL) { + pbuf_chain(header, rambuf); + netif->output(netif, header, dest); + IPFRAG_STATS_INC(ip_frag.xmit); + snmp_inc_ipfragcreates(); + pbuf_free(header); + } else { + LWIP_DEBUGF(IP_REASS_DEBUG, ("ip_frag: pbuf_alloc() for header failed\n")); + pbuf_free(rambuf); + return ERR_MEM; + } +#else /* IP_FRAG_USES_STATIC_BUF */ + /* No need for separate header pbuf - we allowed room for it in rambuf + * when allocated. + */ + netif->output(netif, rambuf, dest); + IPFRAG_STATS_INC(ip_frag.xmit); + + /* Unfortunately we can't reuse rambuf - the hardware may still be + * using the buffer. Instead we free it (and the ensuing chain) and + * recreate it next time round the loop. If we're lucky the hardware + * will have already sent the packet, the free will really free, and + * there will be zero memory penalty. + */ + + pbuf_free(rambuf); +#endif /* IP_FRAG_USES_STATIC_BUF */ + left -= cop; + ofo += nfb; + } +#if IP_FRAG_USES_STATIC_BUF + pbuf_free(rambuf); +#endif /* IP_FRAG_USES_STATIC_BUF */ + snmp_inc_ipfragoks(); + return ERR_OK; +} +#endif /* IP_FRAG */ diff --git a/src/lwip-1.4.1/src/core/ipv6/README b/src/lwip-1.4.1/src/core/ipv6/README new file mode 100644 index 0000000..3620004 --- /dev/null +++ b/src/lwip-1.4.1/src/core/ipv6/README @@ -0,0 +1 @@ +IPv6 support in lwIP is very experimental. diff --git a/src/lwip-1.4.1/src/core/ipv6/icmp6.c b/src/lwip-1.4.1/src/core/ipv6/icmp6.c new file mode 100644 index 0000000..4fcc895 --- /dev/null +++ b/src/lwip-1.4.1/src/core/ipv6/icmp6.c @@ -0,0 +1,179 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +/* Some ICMP messages should be passed to the transport protocols. This + is not implemented. */ + +#include "lwip/opt.h" + +#if LWIP_ICMP /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/icmp.h" +#include "lwip/inet.h" +#include "lwip/ip.h" +#include "lwip/def.h" +#include "lwip/stats.h" + +void +icmp_input(struct pbuf *p, struct netif *inp) +{ + u8_t type; + struct icmp_echo_hdr *iecho; + struct ip_hdr *iphdr; + struct ip_addr tmpaddr; + + ICMP_STATS_INC(icmp.recv); + + /* TODO: check length before accessing payload! */ + + type = ((u8_t *)p->payload)[0]; + + switch (type) { + case ICMP6_ECHO: + LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: ping\n")); + + if (p->tot_len < sizeof(struct icmp_echo_hdr)) { + LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: bad ICMP echo received\n")); + + pbuf_free(p); + ICMP_STATS_INC(icmp.lenerr); + return; + } + iecho = p->payload; + iphdr = (struct ip_hdr *)((u8_t *)p->payload - IP_HLEN); + if (inet_chksum_pbuf(p) != 0) { + LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: checksum failed for received ICMP echo (%"X16_F")\n", inet_chksum_pseudo(p, &(iphdr->src), &(iphdr->dest), IP_PROTO_ICMP, p->tot_len))); + ICMP_STATS_INC(icmp.chkerr); + /* return;*/ + } + LWIP_DEBUGF(ICMP_DEBUG, ("icmp: p->len %"S16_F" p->tot_len %"S16_F"\n", p->len, p->tot_len)); + ip_addr_set(&tmpaddr, &(iphdr->src)); + ip_addr_set(&(iphdr->src), &(iphdr->dest)); + ip_addr_set(&(iphdr->dest), &tmpaddr); + iecho->type = ICMP6_ER; + /* adjust the checksum */ + if (iecho->chksum >= htons(0xffff - (ICMP6_ECHO << 8))) { + iecho->chksum += htons(ICMP6_ECHO << 8) + 1; + } else { + iecho->chksum += htons(ICMP6_ECHO << 8); + } + LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: checksum failed for received ICMP echo (%"X16_F")\n", inet_chksum_pseudo(p, &(iphdr->src), &(iphdr->dest), IP_PROTO_ICMP, p->tot_len))); + ICMP_STATS_INC(icmp.xmit); + + /* LWIP_DEBUGF("icmp: p->len %"U16_F" p->tot_len %"U16_F"\n", p->len, p->tot_len);*/ + ip_output_if (p, &(iphdr->src), IP_HDRINCL, + iphdr->hoplim, IP_PROTO_ICMP, inp); + break; + default: + LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: ICMP type %"S16_F" not supported.\n", (s16_t)type)); + ICMP_STATS_INC(icmp.proterr); + ICMP_STATS_INC(icmp.drop); + } + + pbuf_free(p); +} + +void +icmp_dest_unreach(struct pbuf *p, enum icmp_dur_type t) +{ + struct pbuf *q; + struct ip_hdr *iphdr; + struct icmp_dur_hdr *idur; + + /* @todo: can this be PBUF_LINK instead of PBUF_IP? */ + q = pbuf_alloc(PBUF_IP, 8 + IP_HLEN + 8, PBUF_RAM); + /* ICMP header + IP header + 8 bytes of data */ + if (q == NULL) { + LWIP_DEBUGF(ICMP_DEBUG, ("icmp_dest_unreach: failed to allocate pbuf for ICMP packet.\n")); + pbuf_free(p); + return; + } + LWIP_ASSERT("check that first pbuf can hold icmp message", + (q->len >= (8 + IP_HLEN + 8))); + + iphdr = p->payload; + + idur = q->payload; + idur->type = (u8_t)ICMP6_DUR; + idur->icode = (u8_t)t; + + SMEMCPY((u8_t *)q->payload + 8, p->payload, IP_HLEN + 8); + + /* calculate checksum */ + idur->chksum = 0; + idur->chksum = inet_chksum(idur, q->len); + ICMP_STATS_INC(icmp.xmit); + + ip_output(q, NULL, + (struct ip_addr *)&(iphdr->src), ICMP_TTL, IP_PROTO_ICMP); + pbuf_free(q); +} + +void +icmp_time_exceeded(struct pbuf *p, enum icmp_te_type t) +{ + struct pbuf *q; + struct ip_hdr *iphdr; + struct icmp_te_hdr *tehdr; + + LWIP_DEBUGF(ICMP_DEBUG, ("icmp_time_exceeded\n")); + + /* @todo: can this be PBUF_LINK instead of PBUF_IP? */ + q = pbuf_alloc(PBUF_IP, 8 + IP_HLEN + 8, PBUF_RAM); + /* ICMP header + IP header + 8 bytes of data */ + if (q == NULL) { + LWIP_DEBUGF(ICMP_DEBUG, ("icmp_dest_unreach: failed to allocate pbuf for ICMP packet.\n")); + pbuf_free(p); + return; + } + LWIP_ASSERT("check that first pbuf can hold icmp message", + (q->len >= (8 + IP_HLEN + 8))); + + iphdr = p->payload; + + tehdr = q->payload; + tehdr->type = (u8_t)ICMP6_TE; + tehdr->icode = (u8_t)t; + + /* copy fields from original packet */ + SMEMCPY((u8_t *)q->payload + 8, (u8_t *)p->payload, IP_HLEN + 8); + + /* calculate checksum */ + tehdr->chksum = 0; + tehdr->chksum = inet_chksum(tehdr, q->len); + ICMP_STATS_INC(icmp.xmit); + ip_output(q, NULL, + (struct ip_addr *)&(iphdr->src), ICMP_TTL, IP_PROTO_ICMP); + pbuf_free(q); +} + +#endif /* LWIP_ICMP */ diff --git a/src/lwip-1.4.1/src/core/ipv6/inet6.c b/src/lwip-1.4.1/src/core/ipv6/inet6.c new file mode 100644 index 0000000..c3de85c --- /dev/null +++ b/src/lwip-1.4.1/src/core/ipv6/inet6.c @@ -0,0 +1,163 @@ +/** + * @file + * Functions common to all TCP/IPv6 modules, such as the Internet checksum and the + * byte order functions. + * + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#include "lwip/opt.h" + +#include "lwip/def.h" +#include "lwip/inet.h" + +/* chksum: + * + * Sums up all 16 bit words in a memory portion. Also includes any odd byte. + * This function is used by the other checksum functions. + * + * For now, this is not optimized. Must be optimized for the particular processor + * arcitecture on which it is to run. Preferebly coded in assembler. + */ + +static u32_t +chksum(void *dataptr, u16_t len) +{ + u16_t *sdataptr = dataptr; + u32_t acc; + + + for(acc = 0; len > 1; len -= 2) { + acc += *sdataptr++; + } + + /* add up any odd byte */ + if (len == 1) { + acc += htons((u16_t)(*(u8_t *)dataptr) << 8); + } + + return acc; + +} + +/* inet_chksum_pseudo: + * + * Calculates the pseudo Internet checksum used by TCP and UDP for a pbuf chain. + */ + +u16_t +inet_chksum_pseudo(struct pbuf *p, + struct ip_addr *src, struct ip_addr *dest, + u8_t proto, u32_t proto_len) +{ + u32_t acc; + struct pbuf *q; + u8_t swapped, i; + + acc = 0; + swapped = 0; + for(q = p; q != NULL; q = q->next) { + acc += chksum(q->payload, q->len); + while (acc >> 16) { + acc = (acc & 0xffff) + (acc >> 16); + } + if (q->len % 2 != 0) { + swapped = 1 - swapped; + acc = ((acc & 0xff) << 8) | ((acc & 0xff00) >> 8); + } + } + + if (swapped) { + acc = ((acc & 0xff) << 8) | ((acc & 0xff00) >> 8); + } + + for(i = 0; i < 8; i++) { + acc += ((u16_t *)src->addr)[i] & 0xffff; + acc += ((u16_t *)dest->addr)[i] & 0xffff; + while (acc >> 16) { + acc = (acc & 0xffff) + (acc >> 16); + } + } + acc += (u16_t)htons((u16_t)proto); + acc += ((u16_t *)&proto_len)[0] & 0xffff; + acc += ((u16_t *)&proto_len)[1] & 0xffff; + + while (acc >> 16) { + acc = (acc & 0xffff) + (acc >> 16); + } + return ~(acc & 0xffff); +} + +/* inet_chksum: + * + * Calculates the Internet checksum over a portion of memory. Used primarely for IP + * and ICMP. + */ + +u16_t +inet_chksum(void *dataptr, u16_t len) +{ + u32_t acc, sum; + + acc = chksum(dataptr, len); + sum = (acc & 0xffff) + (acc >> 16); + sum += (sum >> 16); + return ~(sum & 0xffff); +} + +u16_t +inet_chksum_pbuf(struct pbuf *p) +{ + u32_t acc; + struct pbuf *q; + u8_t swapped; + + acc = 0; + swapped = 0; + for(q = p; q != NULL; q = q->next) { + acc += chksum(q->payload, q->len); + while (acc >> 16) { + acc = (acc & 0xffff) + (acc >> 16); + } + if (q->len % 2 != 0) { + swapped = 1 - swapped; + acc = (acc & 0xff << 8) | (acc & 0xff00 >> 8); + } + } + + if (swapped) { + acc = ((acc & 0xff) << 8) | ((acc & 0xff00) >> 8); + } + return ~(acc & 0xffff); +} diff --git a/src/lwip-1.4.1/src/core/ipv6/ip6.c b/src/lwip-1.4.1/src/core/ipv6/ip6.c new file mode 100644 index 0000000..ad59b72 --- /dev/null +++ b/src/lwip-1.4.1/src/core/ipv6/ip6.c @@ -0,0 +1,397 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + + + +/* ip.c + * + * This is the code for the IP layer for IPv6. + * + */ + + +#include "lwip/opt.h" + +#include "lwip/def.h" +#include "lwip/mem.h" +#include "lwip/ip.h" +#include "lwip/inet.h" +#include "lwip/netif.h" +#include "lwip/icmp.h" +#include "lwip/udp.h" +#include "lwip/tcp_impl.h" + +#include "lwip/stats.h" + +#include "arch/perf.h" + +/* ip_init: + * + * Initializes the IP layer. + */ + +void +ip_init(void) +{ +} + +/* ip_route: + * + * Finds the appropriate network interface for a given IP address. It searches the + * list of network interfaces linearly. A match is found if the masked IP address of + * the network interface equals the masked IP address given to the function. + */ + +struct netif * +ip_route(struct ip_addr *dest) +{ + struct netif *netif; + + for(netif = netif_list; netif != NULL; netif = netif->next) { + if (ip_addr_netcmp(dest, &(netif->ip_addr), &(netif->netmask))) { + return netif; + } + } + + return netif_default; +} + +/* ip_forward: + * + * Forwards an IP packet. It finds an appropriate route for the packet, decrements + * the TTL value of the packet, adjusts the checksum and outputs the packet on the + * appropriate interface. + */ + +static void +ip_forward(struct pbuf *p, struct ip_hdr *iphdr) +{ + struct netif *netif; + + PERF_START; + + if ((netif = ip_route((struct ip_addr *)&(iphdr->dest))) == NULL) { + + LWIP_DEBUGF(IP_DEBUG, ("ip_input: no forwarding route found for ")); +#if IP_DEBUG + ip_addr_debug_print(IP_DEBUG, ((struct ip_addr *)&(iphdr->dest))); +#endif /* IP_DEBUG */ + LWIP_DEBUGF(IP_DEBUG, ("\n")); + pbuf_free(p); + return; + } + /* Decrement TTL and send ICMP if ttl == 0. */ + if (--iphdr->hoplim == 0) { +#if LWIP_ICMP + /* Don't send ICMP messages in response to ICMP messages */ + if (iphdr->nexthdr != IP_PROTO_ICMP) { + icmp_time_exceeded(p, ICMP_TE_TTL); + } +#endif /* LWIP_ICMP */ + pbuf_free(p); + return; + } + + /* Incremental update of the IP checksum. */ + /* if (iphdr->chksum >= htons(0xffff - 0x100)) { + iphdr->chksum += htons(0x100) + 1; + } else { + iphdr->chksum += htons(0x100); + }*/ + + + LWIP_DEBUGF(IP_DEBUG, ("ip_forward: forwarding packet to ")); +#if IP_DEBUG + ip_addr_debug_print(IP_DEBUG, ((struct ip_addr *)&(iphdr->dest))); +#endif /* IP_DEBUG */ + LWIP_DEBUGF(IP_DEBUG, ("\n")); + + IP_STATS_INC(ip.fw); + IP_STATS_INC(ip.xmit); + + PERF_STOP("ip_forward"); + + netif->output(netif, p, (struct ip_addr *)&(iphdr->dest)); +} + +/* ip_input: + * + * This function is called by the network interface device driver when an IP packet is + * received. The function does the basic checks of the IP header such as packet size + * being at least larger than the header size etc. If the packet was not destined for + * us, the packet is forwarded (using ip_forward). The IP checksum is always checked. + * + * Finally, the packet is sent to the upper layer protocol input function. + */ + +void +ip_input(struct pbuf *p, struct netif *inp) { + struct ip_hdr *iphdr; + struct netif *netif; + + + PERF_START; + +#if IP_DEBUG + ip_debug_print(p); +#endif /* IP_DEBUG */ + + + IP_STATS_INC(ip.recv); + + /* identify the IP header */ + iphdr = p->payload; + + + if (iphdr->v != 6) { + LWIP_DEBUGF(IP_DEBUG, ("IP packet dropped due to bad version number\n")); +#if IP_DEBUG + ip_debug_print(p); +#endif /* IP_DEBUG */ + pbuf_free(p); + IP_STATS_INC(ip.err); + IP_STATS_INC(ip.drop); + return; + } + + /* is this packet for us? */ + for(netif = netif_list; netif != NULL; netif = netif->next) { +#if IP_DEBUG + LWIP_DEBUGF(IP_DEBUG, ("ip_input: iphdr->dest ")); + ip_addr_debug_print(IP_DEBUG, ((struct ip_addr *)&(iphdr->dest))); + LWIP_DEBUGF(IP_DEBUG, ("netif->ip_addr ")); + ip_addr_debug_print(IP_DEBUG, ((struct ip_addr *)&(iphdr->dest))); + LWIP_DEBUGF(IP_DEBUG, ("\n")); +#endif /* IP_DEBUG */ + if (ip_addr_cmp(&(iphdr->dest), &(netif->ip_addr))) { + break; + } + } + + + if (netif == NULL) { + /* packet not for us, route or discard */ +#if IP_FORWARD + ip_forward(p, iphdr); +#endif + pbuf_free(p); + return; + } + + pbuf_realloc(p, IP_HLEN + ntohs(iphdr->len)); + + /* send to upper layers */ +#if IP_DEBUG + /* LWIP_DEBUGF("ip_input: \n"); + ip_debug_print(p); + LWIP_DEBUGF("ip_input: p->len %"U16_F" p->tot_len %"U16_F"\n", p->len, p->tot_len);*/ +#endif /* IP_DEBUG */ + + if(pbuf_header(p, -IP_HLEN)) { + LWIP_ASSERT("Can't move over header in packet", 0); + return; + } + + switch (iphdr->nexthdr) { + case IP_PROTO_UDP: + udp_input(p, inp); + break; + case IP_PROTO_TCP: + tcp_input(p, inp); + break; +#if LWIP_ICMP + case IP_PROTO_ICMP: + icmp_input(p, inp); + break; +#endif /* LWIP_ICMP */ + default: +#if LWIP_ICMP + /* send ICMP destination protocol unreachable */ + icmp_dest_unreach(p, ICMP_DUR_PROTO); +#endif /* LWIP_ICMP */ + pbuf_free(p); + LWIP_DEBUGF(IP_DEBUG, ("Unsupported transport protocol %"U16_F"\n", + iphdr->nexthdr)); + + IP_STATS_INC(ip.proterr); + IP_STATS_INC(ip.drop); + } + PERF_STOP("ip_input"); +} + + +/* ip_output_if: + * + * Sends an IP packet on a network interface. This function constructs the IP header + * and calculates the IP header checksum. If the source IP address is NULL, + * the IP address of the outgoing network interface is filled in as source address. + */ + +err_t +ip_output_if (struct pbuf *p, struct ip_addr *src, struct ip_addr *dest, + u8_t ttl, + u8_t proto, struct netif *netif) +{ + struct ip_hdr *iphdr; + + PERF_START; + + LWIP_DEBUGF(IP_DEBUG, ("len %"U16_F" tot_len %"U16_F"\n", p->len, p->tot_len)); + if (pbuf_header(p, IP_HLEN)) { + LWIP_DEBUGF(IP_DEBUG, ("ip_output: not enough room for IP header in pbuf\n")); + IP_STATS_INC(ip.err); + + return ERR_BUF; + } + LWIP_DEBUGF(IP_DEBUG, ("len %"U16_F" tot_len %"U16_F"\n", p->len, p->tot_len)); + + iphdr = p->payload; + + + if (dest != IP_HDRINCL) { + LWIP_DEBUGF(IP_DEBUG, ("!IP_HDRLINCL\n")); + iphdr->hoplim = ttl; + iphdr->nexthdr = proto; + iphdr->len = htons(p->tot_len - IP_HLEN); + ip_addr_set(&(iphdr->dest), dest); + + iphdr->v = 6; + + if (ip_addr_isany(src)) { + ip_addr_set(&(iphdr->src), &(netif->ip_addr)); + } else { + ip_addr_set(&(iphdr->src), src); + } + + } else { + dest = &(iphdr->dest); + } + + IP_STATS_INC(ip.xmit); + + LWIP_DEBUGF(IP_DEBUG, ("ip_output_if: %c%c (len %"U16_F")\n", netif->name[0], netif->name[1], p->tot_len)); +#if IP_DEBUG + ip_debug_print(p); +#endif /* IP_DEBUG */ + + PERF_STOP("ip_output_if"); + return netif->output(netif, p, dest); +} + +/* ip_output: + * + * Simple interface to ip_output_if. It finds the outgoing network interface and + * calls upon ip_output_if to do the actual work. + */ + +err_t +ip_output(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest, + u8_t ttl, u8_t proto) +{ + struct netif *netif; + if ((netif = ip_route(dest)) == NULL) { + LWIP_DEBUGF(IP_DEBUG, ("ip_output: No route to 0x%"X32_F"\n", dest->addr)); + IP_STATS_INC(ip.rterr); + return ERR_RTE; + } + + return ip_output_if (p, src, dest, ttl, proto, netif); +} + +#if LWIP_NETIF_HWADDRHINT +err_t +ip_output_hinted(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest, + u8_t ttl, u8_t tos, u8_t proto, u8_t *addr_hint) +{ + struct netif *netif; + err_t err; + + if ((netif = ip_route(dest)) == NULL) { + LWIP_DEBUGF(IP_DEBUG, ("ip_output: No route to 0x%"X32_F"\n", dest->addr)); + IP_STATS_INC(ip.rterr); + return ERR_RTE; + } + + LWIP_NETIF_HWADDRHINT(netif, addr_hint); + err = ip_output_if(p, src, dest, ttl, tos, proto, netif); + LWIP_NETIF_HWADDRHINT(netif, NULL); + + return err; +} +#endif /* LWIP_NETIF_HWADDRHINT*/ + +#if IP_DEBUG +void +ip_debug_print(struct pbuf *p) +{ + struct ip_hdr *iphdr = p->payload; + + LWIP_DEBUGF(IP_DEBUG, ("IP header:\n")); + LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n")); + LWIP_DEBUGF(IP_DEBUG, ("|%2"S16_F" | %"X16_F"%"X16_F" | %"X16_F"%"X16_F" | (v, traffic class, flow label)\n", + iphdr->v, + iphdr->tclass1, iphdr->tclass2, + iphdr->flow1, iphdr->flow2)); + LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n")); + LWIP_DEBUGF(IP_DEBUG, ("| %5"U16_F" | %2"U16_F" | %2"U16_F" | (len, nexthdr, hoplim)\n", + ntohs(iphdr->len), + iphdr->nexthdr, + iphdr->hoplim)); + LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n")); + LWIP_DEBUGF(IP_DEBUG, ("| %4"X32_F" | %4"X32_F" | (src)\n", + (ntohl(iphdr->src.addr[0]) >> 16) & 0xffff, + ntohl(iphdr->src.addr[0]) & 0xffff)); + LWIP_DEBUGF(IP_DEBUG, ("| %4"X32_F" | %4"X32_F" | (src)\n", + (ntohl(iphdr->src.addr[1]) >> 16) & 0xffff, + ntohl(iphdr->src.addr[1]) & 0xffff)); + LWIP_DEBUGF(IP_DEBUG, ("| %4"X32_F" | %4"X32_F" | (src)\n", + (ntohl(iphdr->src.addr[2]) >> 16) & 0xffff, + ntohl(iphdr->src.addr[2]) & 0xffff)); + LWIP_DEBUGF(IP_DEBUG, ("| %4"X32_F" | %4"X32_F" | (src)\n", + (ntohl(iphdr->src.addr[3]) >> 16) & 0xffff, + ntohl(iphdr->src.addr[3]) & 0xffff)); + LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n")); + LWIP_DEBUGF(IP_DEBUG, ("| %4"X32_F" | %4"X32_F" | (dest)\n", + (ntohl(iphdr->dest.addr[0]) >> 16) & 0xffff, + ntohl(iphdr->dest.addr[0]) & 0xffff)); + LWIP_DEBUGF(IP_DEBUG, ("| %4"X32_F" | %4"X32_F" | (dest)\n", + (ntohl(iphdr->dest.addr[1]) >> 16) & 0xffff, + ntohl(iphdr->dest.addr[1]) & 0xffff)); + LWIP_DEBUGF(IP_DEBUG, ("| %4"X32_F" | %4"X32_F" | (dest)\n", + (ntohl(iphdr->dest.addr[2]) >> 16) & 0xffff, + ntohl(iphdr->dest.addr[2]) & 0xffff)); + LWIP_DEBUGF(IP_DEBUG, ("| %4"X32_F" | %4"X32_F" | (dest)\n", + (ntohl(iphdr->dest.addr[3]) >> 16) & 0xffff, + ntohl(iphdr->dest.addr[3]) & 0xffff)); + LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n")); +} +#endif /* IP_DEBUG */ diff --git a/src/lwip-1.4.1/src/core/ipv6/ip6_addr.c b/src/lwip-1.4.1/src/core/ipv6/ip6_addr.c new file mode 100644 index 0000000..2da6cea --- /dev/null +++ b/src/lwip-1.4.1/src/core/ipv6/ip6_addr.c @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#include "lwip/opt.h" +#include "lwip/ip_addr.h" +#include "lwip/inet.h" + +u8_t +ip_addr_netcmp(struct ip_addr *addr1, struct ip_addr *addr2, + struct ip_addr *mask) +{ + return((addr1->addr[0] & mask->addr[0]) == (addr2->addr[0] & mask->addr[0]) && + (addr1->addr[1] & mask->addr[1]) == (addr2->addr[1] & mask->addr[1]) && + (addr1->addr[2] & mask->addr[2]) == (addr2->addr[2] & mask->addr[2]) && + (addr1->addr[3] & mask->addr[3]) == (addr2->addr[3] & mask->addr[3])); + +} + +u8_t +ip_addr_cmp(struct ip_addr *addr1, struct ip_addr *addr2) +{ + return(addr1->addr[0] == addr2->addr[0] && + addr1->addr[1] == addr2->addr[1] && + addr1->addr[2] == addr2->addr[2] && + addr1->addr[3] == addr2->addr[3]); +} + +void +ip_addr_set(struct ip_addr *dest, struct ip_addr *src) +{ + SMEMCPY(dest, src, sizeof(struct ip_addr)); + /* dest->addr[0] = src->addr[0]; + dest->addr[1] = src->addr[1]; + dest->addr[2] = src->addr[2]; + dest->addr[3] = src->addr[3];*/ +} + +u8_t +ip_addr_isany(struct ip_addr *addr) +{ + if (addr == NULL) return 1; + return((addr->addr[0] | addr->addr[1] | addr->addr[2] | addr->addr[3]) == 0); +} diff --git a/src/lwip-1.4.1/src/core/mem.c b/src/lwip-1.4.1/src/core/mem.c new file mode 100644 index 0000000..1659a2c --- /dev/null +++ b/src/lwip-1.4.1/src/core/mem.c @@ -0,0 +1,659 @@ +/** + * @file + * Dynamic memory manager + * + * This is a lightweight replacement for the standard C library malloc(). + * + * If you want to use the standard C library malloc() instead, define + * MEM_LIBC_MALLOC to 1 in your lwipopts.h + * + * To let mem_malloc() use pools (prevents fragmentation and is much faster than + * a heap but might waste some memory), define MEM_USE_POOLS to 1, define + * MEM_USE_CUSTOM_POOLS to 1 and create a file "lwippools.h" that includes a list + * of pools like this (more pools can be added between _START and _END): + * + * Define three pools with sizes 256, 512, and 1512 bytes + * LWIP_MALLOC_MEMPOOL_START + * LWIP_MALLOC_MEMPOOL(20, 256) + * LWIP_MALLOC_MEMPOOL(10, 512) + * LWIP_MALLOC_MEMPOOL(5, 1512) + * LWIP_MALLOC_MEMPOOL_END + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * Simon Goldschmidt + * + */ + +#include "lwip/opt.h" + +#if !MEM_LIBC_MALLOC /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/def.h" +#include "lwip/mem.h" +#include "lwip/sys.h" +#include "lwip/stats.h" +#include "lwip/err.h" + +#include + +#if MEM_USE_POOLS +/* lwIP head implemented with different sized pools */ + +/** + * Allocate memory: determine the smallest pool that is big enough + * to contain an element of 'size' and get an element from that pool. + * + * @param size the size in bytes of the memory needed + * @return a pointer to the allocated memory or NULL if the pool is empty + */ +void * +mem_malloc(mem_size_t size) +{ + void *ret; + struct memp_malloc_helper *element; + memp_t poolnr; + mem_size_t required_size = size + LWIP_MEM_ALIGN_SIZE(sizeof(struct memp_malloc_helper)); + + for (poolnr = MEMP_POOL_FIRST; poolnr <= MEMP_POOL_LAST; poolnr = (memp_t)(poolnr + 1)) { +#if MEM_USE_POOLS_TRY_BIGGER_POOL +again: +#endif /* MEM_USE_POOLS_TRY_BIGGER_POOL */ + /* is this pool big enough to hold an element of the required size + plus a struct memp_malloc_helper that saves the pool this element came from? */ + if (required_size <= memp_sizes[poolnr]) { + break; + } + } + if (poolnr > MEMP_POOL_LAST) { + LWIP_ASSERT("mem_malloc(): no pool is that big!", 0); + return NULL; + } + element = (struct memp_malloc_helper*)memp_malloc(poolnr); + if (element == NULL) { + /* No need to DEBUGF or ASSERT: This error is already + taken care of in memp.c */ +#if MEM_USE_POOLS_TRY_BIGGER_POOL + /** Try a bigger pool if this one is empty! */ + if (poolnr < MEMP_POOL_LAST) { + poolnr++; + goto again; + } +#endif /* MEM_USE_POOLS_TRY_BIGGER_POOL */ + return NULL; + } + + /* save the pool number this element came from */ + element->poolnr = poolnr; + /* and return a pointer to the memory directly after the struct memp_malloc_helper */ + ret = (u8_t*)element + LWIP_MEM_ALIGN_SIZE(sizeof(struct memp_malloc_helper)); + + return ret; +} + +/** + * Free memory previously allocated by mem_malloc. Loads the pool number + * and calls memp_free with that pool number to put the element back into + * its pool + * + * @param rmem the memory element to free + */ +void +mem_free(void *rmem) +{ + struct memp_malloc_helper *hmem; + + LWIP_ASSERT("rmem != NULL", (rmem != NULL)); + LWIP_ASSERT("rmem == MEM_ALIGN(rmem)", (rmem == LWIP_MEM_ALIGN(rmem))); + + /* get the original struct memp_malloc_helper */ + hmem = (struct memp_malloc_helper*)(void*)((u8_t*)rmem - LWIP_MEM_ALIGN_SIZE(sizeof(struct memp_malloc_helper))); + + LWIP_ASSERT("hmem != NULL", (hmem != NULL)); + LWIP_ASSERT("hmem == MEM_ALIGN(hmem)", (hmem == LWIP_MEM_ALIGN(hmem))); + LWIP_ASSERT("hmem->poolnr < MEMP_MAX", (hmem->poolnr < MEMP_MAX)); + + /* and put it in the pool we saved earlier */ + memp_free(hmem->poolnr, hmem); +} + +#else /* MEM_USE_POOLS */ +/* lwIP replacement for your libc malloc() */ + +/** + * The heap is made up as a list of structs of this type. + * This does not have to be aligned since for getting its size, + * we only use the macro SIZEOF_STRUCT_MEM, which automatically alignes. + */ +struct mem { + /** index (-> ram[next]) of the next struct */ + mem_size_t next; + /** index (-> ram[prev]) of the previous struct */ + mem_size_t prev; + /** 1: this area is used; 0: this area is unused */ + u8_t used; +}; + +/** All allocated blocks will be MIN_SIZE bytes big, at least! + * MIN_SIZE can be overridden to suit your needs. Smaller values save space, + * larger values could prevent too small blocks to fragment the RAM too much. */ +#ifndef MIN_SIZE +#define MIN_SIZE 12 +#endif /* MIN_SIZE */ +/* some alignment macros: we define them here for better source code layout */ +#define MIN_SIZE_ALIGNED LWIP_MEM_ALIGN_SIZE(MIN_SIZE) +#define SIZEOF_STRUCT_MEM LWIP_MEM_ALIGN_SIZE(sizeof(struct mem)) +#define MEM_SIZE_ALIGNED LWIP_MEM_ALIGN_SIZE(MEM_SIZE) + +/** If you want to relocate the heap to external memory, simply define + * LWIP_RAM_HEAP_POINTER as a void-pointer to that location. + * If so, make sure the memory at that location is big enough (see below on + * how that space is calculated). */ +#ifndef LWIP_RAM_HEAP_POINTER +/** the heap. we need one struct mem at the end and some room for alignment */ +u8_t ram_heap[MEM_SIZE_ALIGNED + (2*SIZEOF_STRUCT_MEM) + MEM_ALIGNMENT]; +#define LWIP_RAM_HEAP_POINTER ram_heap +#endif /* LWIP_RAM_HEAP_POINTER */ + +/** pointer to the heap (ram_heap): for alignment, ram is now a pointer instead of an array */ +static u8_t *ram; +/** the last entry, always unused! */ +static struct mem *ram_end; +/** pointer to the lowest free block, this is used for faster search */ +static struct mem *lfree; + +/** concurrent access protection */ +#if !NO_SYS +static sys_mutex_t mem_mutex; +#endif + +#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT + +static volatile u8_t mem_free_count; + +/* Allow mem_free from other (e.g. interrupt) context */ +#define LWIP_MEM_FREE_DECL_PROTECT() SYS_ARCH_DECL_PROTECT(lev_free) +#define LWIP_MEM_FREE_PROTECT() SYS_ARCH_PROTECT(lev_free) +#define LWIP_MEM_FREE_UNPROTECT() SYS_ARCH_UNPROTECT(lev_free) +#define LWIP_MEM_ALLOC_DECL_PROTECT() SYS_ARCH_DECL_PROTECT(lev_alloc) +#define LWIP_MEM_ALLOC_PROTECT() SYS_ARCH_PROTECT(lev_alloc) +#define LWIP_MEM_ALLOC_UNPROTECT() SYS_ARCH_UNPROTECT(lev_alloc) + +#else /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */ + +/* Protect the heap only by using a semaphore */ +#define LWIP_MEM_FREE_DECL_PROTECT() +#define LWIP_MEM_FREE_PROTECT() sys_mutex_lock(&mem_mutex) +#define LWIP_MEM_FREE_UNPROTECT() sys_mutex_unlock(&mem_mutex) +/* mem_malloc is protected using semaphore AND LWIP_MEM_ALLOC_PROTECT */ +#define LWIP_MEM_ALLOC_DECL_PROTECT() +#define LWIP_MEM_ALLOC_PROTECT() +#define LWIP_MEM_ALLOC_UNPROTECT() + +#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */ + + +/** + * "Plug holes" by combining adjacent empty struct mems. + * After this function is through, there should not exist + * one empty struct mem pointing to another empty struct mem. + * + * @param mem this points to a struct mem which just has been freed + * @internal this function is only called by mem_free() and mem_trim() + * + * This assumes access to the heap is protected by the calling function + * already. + */ +static void +plug_holes(struct mem *mem) +{ + struct mem *nmem; + struct mem *pmem; + + LWIP_ASSERT("plug_holes: mem >= ram", (u8_t *)mem >= ram); + LWIP_ASSERT("plug_holes: mem < ram_end", (u8_t *)mem < (u8_t *)ram_end); + LWIP_ASSERT("plug_holes: mem->used == 0", mem->used == 0); + + /* plug hole forward */ + LWIP_ASSERT("plug_holes: mem->next <= MEM_SIZE_ALIGNED", mem->next <= MEM_SIZE_ALIGNED); + + nmem = (struct mem *)(void *)&ram[mem->next]; + if (mem != nmem && nmem->used == 0 && (u8_t *)nmem != (u8_t *)ram_end) { + /* if mem->next is unused and not end of ram, combine mem and mem->next */ + if (lfree == nmem) { + lfree = mem; + } + mem->next = nmem->next; + ((struct mem *)(void *)&ram[nmem->next])->prev = (mem_size_t)((u8_t *)mem - ram); + } + + /* plug hole backward */ + pmem = (struct mem *)(void *)&ram[mem->prev]; + if (pmem != mem && pmem->used == 0) { + /* if mem->prev is unused, combine mem and mem->prev */ + if (lfree == mem) { + lfree = pmem; + } + pmem->next = mem->next; + ((struct mem *)(void *)&ram[mem->next])->prev = (mem_size_t)((u8_t *)pmem - ram); + } +} + +/** + * Zero the heap and initialize start, end and lowest-free + */ +void +mem_init(void) +{ + struct mem *mem; + + LWIP_ASSERT("Sanity check alignment", + (SIZEOF_STRUCT_MEM & (MEM_ALIGNMENT-1)) == 0); + + /* align the heap */ + ram = (u8_t *)LWIP_MEM_ALIGN(LWIP_RAM_HEAP_POINTER); + /* initialize the start of the heap */ + mem = (struct mem *)(void *)ram; + mem->next = MEM_SIZE_ALIGNED; + mem->prev = 0; + mem->used = 0; + /* initialize the end of the heap */ + ram_end = (struct mem *)(void *)&ram[MEM_SIZE_ALIGNED]; + ram_end->used = 1; + ram_end->next = MEM_SIZE_ALIGNED; + ram_end->prev = MEM_SIZE_ALIGNED; + + /* initialize the lowest-free pointer to the start of the heap */ + lfree = (struct mem *)(void *)ram; + + MEM_STATS_AVAIL(avail, MEM_SIZE_ALIGNED); + + if(sys_mutex_new(&mem_mutex) != ERR_OK) { + LWIP_ASSERT("failed to create mem_mutex", 0); + } +} + +/** + * Put a struct mem back on the heap + * + * @param rmem is the data portion of a struct mem as returned by a previous + * call to mem_malloc() + */ +void +mem_free(void *rmem) +{ + struct mem *mem; + LWIP_MEM_FREE_DECL_PROTECT(); + + if (rmem == NULL) { + LWIP_DEBUGF(MEM_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("mem_free(p == NULL) was called.\n")); + return; + } + LWIP_ASSERT("mem_free: sanity check alignment", (((mem_ptr_t)rmem) & (MEM_ALIGNMENT-1)) == 0); + + LWIP_ASSERT("mem_free: legal memory", (u8_t *)rmem >= (u8_t *)ram && + (u8_t *)rmem < (u8_t *)ram_end); + + if ((u8_t *)rmem < (u8_t *)ram || (u8_t *)rmem >= (u8_t *)ram_end) { + SYS_ARCH_DECL_PROTECT(lev); + LWIP_DEBUGF(MEM_DEBUG | LWIP_DBG_LEVEL_SEVERE, ("mem_free: illegal memory\n")); + /* protect mem stats from concurrent access */ + SYS_ARCH_PROTECT(lev); + MEM_STATS_INC(illegal); + SYS_ARCH_UNPROTECT(lev); + return; + } + /* protect the heap from concurrent access */ + LWIP_MEM_FREE_PROTECT(); + /* Get the corresponding struct mem ... */ + mem = (struct mem *)(void *)((u8_t *)rmem - SIZEOF_STRUCT_MEM); + /* ... which has to be in a used state ... */ + LWIP_ASSERT("mem_free: mem->used", mem->used); + /* ... and is now unused. */ + mem->used = 0; + + if (mem < lfree) { + /* the newly freed struct is now the lowest */ + lfree = mem; + } + + MEM_STATS_DEC_USED(used, mem->next - (mem_size_t)(((u8_t *)mem - ram))); + + /* finally, see if prev or next are free also */ + plug_holes(mem); +#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT + mem_free_count = 1; +#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */ + LWIP_MEM_FREE_UNPROTECT(); +} + +/** + * Shrink memory returned by mem_malloc(). + * + * @param rmem pointer to memory allocated by mem_malloc the is to be shrinked + * @param newsize required size after shrinking (needs to be smaller than or + * equal to the previous size) + * @return for compatibility reasons: is always == rmem, at the moment + * or NULL if newsize is > old size, in which case rmem is NOT touched + * or freed! + */ +void * +mem_trim(void *rmem, mem_size_t newsize) +{ + mem_size_t size; + mem_size_t ptr, ptr2; + struct mem *mem, *mem2; + /* use the FREE_PROTECT here: it protects with sem OR SYS_ARCH_PROTECT */ + LWIP_MEM_FREE_DECL_PROTECT(); + + /* Expand the size of the allocated memory region so that we can + adjust for alignment. */ + newsize = LWIP_MEM_ALIGN_SIZE(newsize); + + if(newsize < MIN_SIZE_ALIGNED) { + /* every data block must be at least MIN_SIZE_ALIGNED long */ + newsize = MIN_SIZE_ALIGNED; + } + + if (newsize > MEM_SIZE_ALIGNED) { + return NULL; + } + + LWIP_ASSERT("mem_trim: legal memory", (u8_t *)rmem >= (u8_t *)ram && + (u8_t *)rmem < (u8_t *)ram_end); + + if ((u8_t *)rmem < (u8_t *)ram || (u8_t *)rmem >= (u8_t *)ram_end) { + SYS_ARCH_DECL_PROTECT(lev); + LWIP_DEBUGF(MEM_DEBUG | LWIP_DBG_LEVEL_SEVERE, ("mem_trim: illegal memory\n")); + /* protect mem stats from concurrent access */ + SYS_ARCH_PROTECT(lev); + MEM_STATS_INC(illegal); + SYS_ARCH_UNPROTECT(lev); + return rmem; + } + /* Get the corresponding struct mem ... */ + mem = (struct mem *)(void *)((u8_t *)rmem - SIZEOF_STRUCT_MEM); + /* ... and its offset pointer */ + ptr = (mem_size_t)((u8_t *)mem - ram); + + size = mem->next - ptr - SIZEOF_STRUCT_MEM; + LWIP_ASSERT("mem_trim can only shrink memory", newsize <= size); + if (newsize > size) { + /* not supported */ + return NULL; + } + if (newsize == size) { + /* No change in size, simply return */ + return rmem; + } + + /* protect the heap from concurrent access */ + LWIP_MEM_FREE_PROTECT(); + + mem2 = (struct mem *)(void *)&ram[mem->next]; + if(mem2->used == 0) { + /* The next struct is unused, we can simply move it at little */ + mem_size_t next; + /* remember the old next pointer */ + next = mem2->next; + /* create new struct mem which is moved directly after the shrinked mem */ + ptr2 = ptr + SIZEOF_STRUCT_MEM + newsize; + if (lfree == mem2) { + lfree = (struct mem *)(void *)&ram[ptr2]; + } + mem2 = (struct mem *)(void *)&ram[ptr2]; + mem2->used = 0; + /* restore the next pointer */ + mem2->next = next; + /* link it back to mem */ + mem2->prev = ptr; + /* link mem to it */ + mem->next = ptr2; + /* last thing to restore linked list: as we have moved mem2, + * let 'mem2->next->prev' point to mem2 again. but only if mem2->next is not + * the end of the heap */ + if (mem2->next != MEM_SIZE_ALIGNED) { + ((struct mem *)(void *)&ram[mem2->next])->prev = ptr2; + } + MEM_STATS_DEC_USED(used, (size - newsize)); + /* no need to plug holes, we've already done that */ + } else if (newsize + SIZEOF_STRUCT_MEM + MIN_SIZE_ALIGNED <= size) { + /* Next struct is used but there's room for another struct mem with + * at least MIN_SIZE_ALIGNED of data. + * Old size ('size') must be big enough to contain at least 'newsize' plus a struct mem + * ('SIZEOF_STRUCT_MEM') with some data ('MIN_SIZE_ALIGNED'). + * @todo we could leave out MIN_SIZE_ALIGNED. We would create an empty + * region that couldn't hold data, but when mem->next gets freed, + * the 2 regions would be combined, resulting in more free memory */ + ptr2 = ptr + SIZEOF_STRUCT_MEM + newsize; + mem2 = (struct mem *)(void *)&ram[ptr2]; + if (mem2 < lfree) { + lfree = mem2; + } + mem2->used = 0; + mem2->next = mem->next; + mem2->prev = ptr; + mem->next = ptr2; + if (mem2->next != MEM_SIZE_ALIGNED) { + ((struct mem *)(void *)&ram[mem2->next])->prev = ptr2; + } + MEM_STATS_DEC_USED(used, (size - newsize)); + /* the original mem->next is used, so no need to plug holes! */ + } + /* else { + next struct mem is used but size between mem and mem2 is not big enough + to create another struct mem + -> don't do anyhting. + -> the remaining space stays unused since it is too small + } */ +#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT + mem_free_count = 1; +#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */ + LWIP_MEM_FREE_UNPROTECT(); + return rmem; +} + +/** + * Adam's mem_malloc() plus solution for bug #17922 + * Allocate a block of memory with a minimum of 'size' bytes. + * + * @param size is the minimum size of the requested block in bytes. + * @return pointer to allocated memory or NULL if no free memory was found. + * + * Note that the returned value will always be aligned (as defined by MEM_ALIGNMENT). + */ +void * +mem_malloc(mem_size_t size) +{ + mem_size_t ptr, ptr2; + struct mem *mem, *mem2; +#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT + u8_t local_mem_free_count = 0; +#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */ + LWIP_MEM_ALLOC_DECL_PROTECT(); + + if (size == 0) { + return NULL; + } + + /* Expand the size of the allocated memory region so that we can + adjust for alignment. */ + size = LWIP_MEM_ALIGN_SIZE(size); + + if(size < MIN_SIZE_ALIGNED) { + /* every data block must be at least MIN_SIZE_ALIGNED long */ + size = MIN_SIZE_ALIGNED; + } + + if (size > MEM_SIZE_ALIGNED) { + return NULL; + } + + /* protect the heap from concurrent access */ + sys_mutex_lock(&mem_mutex); + LWIP_MEM_ALLOC_PROTECT(); +#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT + /* run as long as a mem_free disturbed mem_malloc or mem_trim */ + do { + local_mem_free_count = 0; +#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */ + + /* Scan through the heap searching for a free block that is big enough, + * beginning with the lowest free block. + */ + for (ptr = (mem_size_t)((u8_t *)lfree - ram); ptr < MEM_SIZE_ALIGNED - size; + ptr = ((struct mem *)(void *)&ram[ptr])->next) { + mem = (struct mem *)(void *)&ram[ptr]; +#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT + mem_free_count = 0; + LWIP_MEM_ALLOC_UNPROTECT(); + /* allow mem_free or mem_trim to run */ + LWIP_MEM_ALLOC_PROTECT(); + if (mem_free_count != 0) { + /* If mem_free or mem_trim have run, we have to restart since they + could have altered our current struct mem. */ + local_mem_free_count = 1; + break; + } +#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */ + + if ((!mem->used) && + (mem->next - (ptr + SIZEOF_STRUCT_MEM)) >= size) { + /* mem is not used and at least perfect fit is possible: + * mem->next - (ptr + SIZEOF_STRUCT_MEM) gives us the 'user data size' of mem */ + + if (mem->next - (ptr + SIZEOF_STRUCT_MEM) >= (size + SIZEOF_STRUCT_MEM + MIN_SIZE_ALIGNED)) { + /* (in addition to the above, we test if another struct mem (SIZEOF_STRUCT_MEM) containing + * at least MIN_SIZE_ALIGNED of data also fits in the 'user data space' of 'mem') + * -> split large block, create empty remainder, + * remainder must be large enough to contain MIN_SIZE_ALIGNED data: if + * mem->next - (ptr + (2*SIZEOF_STRUCT_MEM)) == size, + * struct mem would fit in but no data between mem2 and mem2->next + * @todo we could leave out MIN_SIZE_ALIGNED. We would create an empty + * region that couldn't hold data, but when mem->next gets freed, + * the 2 regions would be combined, resulting in more free memory + */ + ptr2 = ptr + SIZEOF_STRUCT_MEM + size; + /* create mem2 struct */ + mem2 = (struct mem *)(void *)&ram[ptr2]; + mem2->used = 0; + mem2->next = mem->next; + mem2->prev = ptr; + /* and insert it between mem and mem->next */ + mem->next = ptr2; + mem->used = 1; + + if (mem2->next != MEM_SIZE_ALIGNED) { + ((struct mem *)(void *)&ram[mem2->next])->prev = ptr2; + } + MEM_STATS_INC_USED(used, (size + SIZEOF_STRUCT_MEM)); + } else { + /* (a mem2 struct does no fit into the user data space of mem and mem->next will always + * be used at this point: if not we have 2 unused structs in a row, plug_holes should have + * take care of this). + * -> near fit or excact fit: do not split, no mem2 creation + * also can't move mem->next directly behind mem, since mem->next + * will always be used at this point! + */ + mem->used = 1; + MEM_STATS_INC_USED(used, mem->next - (mem_size_t)((u8_t *)mem - ram)); + } +#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT +mem_malloc_adjust_lfree: +#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */ + if (mem == lfree) { + struct mem *cur = lfree; + /* Find next free block after mem and update lowest free pointer */ + while (cur->used && cur != ram_end) { +#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT + mem_free_count = 0; + LWIP_MEM_ALLOC_UNPROTECT(); + /* prevent high interrupt latency... */ + LWIP_MEM_ALLOC_PROTECT(); + if (mem_free_count != 0) { + /* If mem_free or mem_trim have run, we have to restart since they + could have altered our current struct mem or lfree. */ + goto mem_malloc_adjust_lfree; + } +#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */ + cur = (struct mem *)(void *)&ram[cur->next]; + } + lfree = cur; + LWIP_ASSERT("mem_malloc: !lfree->used", ((lfree == ram_end) || (!lfree->used))); + } + LWIP_MEM_ALLOC_UNPROTECT(); + sys_mutex_unlock(&mem_mutex); + LWIP_ASSERT("mem_malloc: allocated memory not above ram_end.", + (mem_ptr_t)mem + SIZEOF_STRUCT_MEM + size <= (mem_ptr_t)ram_end); + LWIP_ASSERT("mem_malloc: allocated memory properly aligned.", + ((mem_ptr_t)mem + SIZEOF_STRUCT_MEM) % MEM_ALIGNMENT == 0); + LWIP_ASSERT("mem_malloc: sanity check alignment", + (((mem_ptr_t)mem) & (MEM_ALIGNMENT-1)) == 0); + + return (u8_t *)mem + SIZEOF_STRUCT_MEM; + } + } +#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT + /* if we got interrupted by a mem_free, try again */ + } while(local_mem_free_count != 0); +#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */ + LWIP_DEBUGF(MEM_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("mem_malloc: could not allocate %"S16_F" bytes\n", (s16_t)size)); + MEM_STATS_INC(err); + LWIP_MEM_ALLOC_UNPROTECT(); + sys_mutex_unlock(&mem_mutex); + return NULL; +} + +#endif /* MEM_USE_POOLS */ +/** + * Contiguously allocates enough space for count objects that are size bytes + * of memory each and returns a pointer to the allocated memory. + * + * The allocated memory is filled with bytes of value zero. + * + * @param count number of objects to allocate + * @param size size of the objects to allocate + * @return pointer to allocated memory / NULL pointer if there is an error + */ +void *mem_calloc(mem_size_t count, mem_size_t size) +{ + void *p; + + /* allocate 'count' objects of size 'size' */ + p = mem_malloc(count * size); + if (p) { + /* zero the memory */ + memset(p, 0, count * size); + } + return p; +} + +#endif /* !MEM_LIBC_MALLOC */ diff --git a/src/lwip-1.4.1/src/core/memp.c b/src/lwip-1.4.1/src/core/memp.c new file mode 100644 index 0000000..9f680e2 --- /dev/null +++ b/src/lwip-1.4.1/src/core/memp.c @@ -0,0 +1,470 @@ +/** + * @file + * Dynamic pool memory manager + * + * lwIP has dedicated pools for many structures (netconn, protocol control blocks, + * packet buffers, ...). All these pools are managed here. + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#include "lwip/opt.h" + +#include "lwip/memp.h" +#include "lwip/pbuf.h" +#include "lwip/udp.h" +#include "lwip/raw.h" +#include "lwip/tcp_impl.h" +#include "lwip/igmp.h" +#include "lwip/api.h" +#include "lwip/api_msg.h" +#include "lwip/tcpip.h" +#include "lwip/sys.h" +#include "lwip/timers.h" +#include "lwip/stats.h" +#include "netif/etharp.h" +#include "lwip/ip_frag.h" +#include "lwip/snmp_structs.h" +#include "lwip/snmp_msg.h" +#include "lwip/dns.h" +#include "netif/ppp_oe.h" + +#include + +#if !MEMP_MEM_MALLOC /* don't build if not configured for use in lwipopts.h */ + +struct memp { + struct memp *next; +#if MEMP_OVERFLOW_CHECK + const char *file; + int line; +#endif /* MEMP_OVERFLOW_CHECK */ +}; + +#if MEMP_OVERFLOW_CHECK +/* if MEMP_OVERFLOW_CHECK is turned on, we reserve some bytes at the beginning + * and at the end of each element, initialize them as 0xcd and check + * them later. */ +/* If MEMP_OVERFLOW_CHECK is >= 2, on every call to memp_malloc or memp_free, + * every single element in each pool is checked! + * This is VERY SLOW but also very helpful. */ +/* MEMP_SANITY_REGION_BEFORE and MEMP_SANITY_REGION_AFTER can be overridden in + * lwipopts.h to change the amount reserved for checking. */ +#ifndef MEMP_SANITY_REGION_BEFORE +#define MEMP_SANITY_REGION_BEFORE 16 +#endif /* MEMP_SANITY_REGION_BEFORE*/ +#if MEMP_SANITY_REGION_BEFORE > 0 +#define MEMP_SANITY_REGION_BEFORE_ALIGNED LWIP_MEM_ALIGN_SIZE(MEMP_SANITY_REGION_BEFORE) +#else +#define MEMP_SANITY_REGION_BEFORE_ALIGNED 0 +#endif /* MEMP_SANITY_REGION_BEFORE*/ +#ifndef MEMP_SANITY_REGION_AFTER +#define MEMP_SANITY_REGION_AFTER 16 +#endif /* MEMP_SANITY_REGION_AFTER*/ +#if MEMP_SANITY_REGION_AFTER > 0 +#define MEMP_SANITY_REGION_AFTER_ALIGNED LWIP_MEM_ALIGN_SIZE(MEMP_SANITY_REGION_AFTER) +#else +#define MEMP_SANITY_REGION_AFTER_ALIGNED 0 +#endif /* MEMP_SANITY_REGION_AFTER*/ + +/* MEMP_SIZE: save space for struct memp and for sanity check */ +#define MEMP_SIZE (LWIP_MEM_ALIGN_SIZE(sizeof(struct memp)) + MEMP_SANITY_REGION_BEFORE_ALIGNED) +#define MEMP_ALIGN_SIZE(x) (LWIP_MEM_ALIGN_SIZE(x) + MEMP_SANITY_REGION_AFTER_ALIGNED) + +#else /* MEMP_OVERFLOW_CHECK */ + +/* No sanity checks + * We don't need to preserve the struct memp while not allocated, so we + * can save a little space and set MEMP_SIZE to 0. + */ +#define MEMP_SIZE 0 +#define MEMP_ALIGN_SIZE(x) (LWIP_MEM_ALIGN_SIZE(x)) + +#endif /* MEMP_OVERFLOW_CHECK */ + +/** This array holds the first free element of each pool. + * Elements form a linked list. */ +static struct memp *memp_tab[MEMP_MAX]; + +#else /* MEMP_MEM_MALLOC */ + +#define MEMP_ALIGN_SIZE(x) (LWIP_MEM_ALIGN_SIZE(x)) + +#endif /* MEMP_MEM_MALLOC */ + +/** This array holds the element sizes of each pool. */ +#if !MEM_USE_POOLS && !MEMP_MEM_MALLOC +static +#endif +const u16_t memp_sizes[MEMP_MAX] = { +#define LWIP_MEMPOOL(name,num,size,desc) LWIP_MEM_ALIGN_SIZE(size), +#include "lwip/memp_std.h" +}; + +#if !MEMP_MEM_MALLOC /* don't build if not configured for use in lwipopts.h */ + +/** This array holds the number of elements in each pool. */ +static const u16_t memp_num[MEMP_MAX] = { +#define LWIP_MEMPOOL(name,num,size,desc) (num), +#include "lwip/memp_std.h" +}; + +/** This array holds a textual description of each pool. */ +#ifdef LWIP_DEBUG +static const char *memp_desc[MEMP_MAX] = { +#define LWIP_MEMPOOL(name,num,size,desc) (desc), +#include "lwip/memp_std.h" +}; +#endif /* LWIP_DEBUG */ + +#if MEMP_SEPARATE_POOLS + +/** This creates each memory pool. These are named memp_memory_XXX_base (where + * XXX is the name of the pool defined in memp_std.h). + * To relocate a pool, declare it as extern in cc.h. Example for GCC: + * extern u8_t __attribute__((section(".onchip_mem"))) memp_memory_UDP_PCB_base[]; + */ +#define LWIP_MEMPOOL(name,num,size,desc) u8_t memp_memory_ ## name ## _base \ + [((num) * (MEMP_SIZE + MEMP_ALIGN_SIZE(size)))]; +#include "lwip/memp_std.h" + +/** This array holds the base of each memory pool. */ +static u8_t *const memp_bases[] = { +#define LWIP_MEMPOOL(name,num,size,desc) memp_memory_ ## name ## _base, +#include "lwip/memp_std.h" +}; + +#else /* MEMP_SEPARATE_POOLS */ + +/** This is the actual memory used by the pools (all pools in one big block). */ +static u8_t memp_memory[MEM_ALIGNMENT - 1 +#define LWIP_MEMPOOL(name,num,size,desc) + ( (num) * (MEMP_SIZE + MEMP_ALIGN_SIZE(size) ) ) +#include "lwip/memp_std.h" +]; + +#endif /* MEMP_SEPARATE_POOLS */ + +#if MEMP_SANITY_CHECK +/** + * Check that memp-lists don't form a circle, using "Floyd's cycle-finding algorithm". + */ +static int +memp_sanity(void) +{ + s16_t i; + struct memp *t, *h; + + for (i = 0; i < MEMP_MAX; i++) { + t = memp_tab[i]; + if(t != NULL) { + for (h = t->next; (t != NULL) && (h != NULL); t = t->next, + h = (((h->next != NULL) && (h->next->next != NULL)) ? h->next->next : NULL)) { + if (t == h) { + return 0; + } + } + } + } + return 1; +} +#endif /* MEMP_SANITY_CHECK*/ +#if MEMP_OVERFLOW_CHECK +#if defined(LWIP_DEBUG) && MEMP_STATS +static const char * memp_overflow_names[] = { +#define LWIP_MEMPOOL(name,num,size,desc) "/"desc, +#include "lwip/memp_std.h" + }; +#endif + +/** + * Check if a memp element was victim of an overflow + * (e.g. the restricted area after it has been altered) + * + * @param p the memp element to check + * @param memp_type the pool p comes from + */ +static void +memp_overflow_check_element_overflow(struct memp *p, u16_t memp_type) +{ + u16_t k; + u8_t *m; +#if MEMP_SANITY_REGION_AFTER_ALIGNED > 0 + m = (u8_t*)p + MEMP_SIZE + memp_sizes[memp_type]; + for (k = 0; k < MEMP_SANITY_REGION_AFTER_ALIGNED; k++) { + if (m[k] != 0xcd) { + char errstr[128] = "detected memp overflow in pool "; + char digit[] = "0"; + if(memp_type >= 10) { + digit[0] = '0' + (memp_type/10); + strcat(errstr, digit); + } + digit[0] = '0' + (memp_type%10); + strcat(errstr, digit); +#if defined(LWIP_DEBUG) && MEMP_STATS + strcat(errstr, memp_overflow_names[memp_type]); +#endif + LWIP_ASSERT(errstr, 0); + } + } +#endif +} + +/** + * Check if a memp element was victim of an underflow + * (e.g. the restricted area before it has been altered) + * + * @param p the memp element to check + * @param memp_type the pool p comes from + */ +static void +memp_overflow_check_element_underflow(struct memp *p, u16_t memp_type) +{ + u16_t k; + u8_t *m; +#if MEMP_SANITY_REGION_BEFORE_ALIGNED > 0 + m = (u8_t*)p + MEMP_SIZE - MEMP_SANITY_REGION_BEFORE_ALIGNED; + for (k = 0; k < MEMP_SANITY_REGION_BEFORE_ALIGNED; k++) { + if (m[k] != 0xcd) { + char errstr[128] = "detected memp underflow in pool "; + char digit[] = "0"; + if(memp_type >= 10) { + digit[0] = '0' + (memp_type/10); + strcat(errstr, digit); + } + digit[0] = '0' + (memp_type%10); + strcat(errstr, digit); +#if defined(LWIP_DEBUG) && MEMP_STATS + strcat(errstr, memp_overflow_names[memp_type]); +#endif + LWIP_ASSERT(errstr, 0); + } + } +#endif +} + +/** + * Do an overflow check for all elements in every pool. + * + * @see memp_overflow_check_element for a description of the check + */ +static void +memp_overflow_check_all(void) +{ + u16_t i, j; + struct memp *p; + + p = (struct memp *)LWIP_MEM_ALIGN(memp_memory); + for (i = 0; i < MEMP_MAX; ++i) { + p = p; + for (j = 0; j < memp_num[i]; ++j) { + memp_overflow_check_element_overflow(p, i); + p = (struct memp*)((u8_t*)p + MEMP_SIZE + memp_sizes[i] + MEMP_SANITY_REGION_AFTER_ALIGNED); + } + } + p = (struct memp *)LWIP_MEM_ALIGN(memp_memory); + for (i = 0; i < MEMP_MAX; ++i) { + p = p; + for (j = 0; j < memp_num[i]; ++j) { + memp_overflow_check_element_underflow(p, i); + p = (struct memp*)((u8_t*)p + MEMP_SIZE + memp_sizes[i] + MEMP_SANITY_REGION_AFTER_ALIGNED); + } + } +} + +/** + * Initialize the restricted areas of all memp elements in every pool. + */ +static void +memp_overflow_init(void) +{ + u16_t i, j; + struct memp *p; + u8_t *m; + + p = (struct memp *)LWIP_MEM_ALIGN(memp_memory); + for (i = 0; i < MEMP_MAX; ++i) { + p = p; + for (j = 0; j < memp_num[i]; ++j) { +#if MEMP_SANITY_REGION_BEFORE_ALIGNED > 0 + m = (u8_t*)p + MEMP_SIZE - MEMP_SANITY_REGION_BEFORE_ALIGNED; + memset(m, 0xcd, MEMP_SANITY_REGION_BEFORE_ALIGNED); +#endif +#if MEMP_SANITY_REGION_AFTER_ALIGNED > 0 + m = (u8_t*)p + MEMP_SIZE + memp_sizes[i]; + memset(m, 0xcd, MEMP_SANITY_REGION_AFTER_ALIGNED); +#endif + p = (struct memp*)((u8_t*)p + MEMP_SIZE + memp_sizes[i] + MEMP_SANITY_REGION_AFTER_ALIGNED); + } + } +} +#endif /* MEMP_OVERFLOW_CHECK */ + +/** + * Initialize this module. + * + * Carves out memp_memory into linked lists for each pool-type. + */ +void +memp_init(void) +{ + struct memp *memp; + u16_t i, j; + + for (i = 0; i < MEMP_MAX; ++i) { + MEMP_STATS_AVAIL(used, i, 0); + MEMP_STATS_AVAIL(max, i, 0); + MEMP_STATS_AVAIL(err, i, 0); + MEMP_STATS_AVAIL(avail, i, memp_num[i]); + } + +#if !MEMP_SEPARATE_POOLS + memp = (struct memp *)LWIP_MEM_ALIGN(memp_memory); +#endif /* !MEMP_SEPARATE_POOLS */ + /* for every pool: */ + for (i = 0; i < MEMP_MAX; ++i) { + memp_tab[i] = NULL; +#if MEMP_SEPARATE_POOLS + memp = (struct memp*)memp_bases[i]; +#endif /* MEMP_SEPARATE_POOLS */ + /* create a linked list of memp elements */ + for (j = 0; j < memp_num[i]; ++j) { + memp->next = memp_tab[i]; + memp_tab[i] = memp; + memp = (struct memp *)(void *)((u8_t *)memp + MEMP_SIZE + memp_sizes[i] +#if MEMP_OVERFLOW_CHECK + + MEMP_SANITY_REGION_AFTER_ALIGNED +#endif + ); + } + } +#if MEMP_OVERFLOW_CHECK + memp_overflow_init(); + /* check everything a first time to see if it worked */ + memp_overflow_check_all(); +#endif /* MEMP_OVERFLOW_CHECK */ +} + +/** + * Get an element from a specific pool. + * + * @param type the pool to get an element from + * + * the debug version has two more parameters: + * @param file file name calling this function + * @param line number of line where this function is called + * + * @return a pointer to the allocated memory or a NULL pointer on error + */ +void * +#if !MEMP_OVERFLOW_CHECK +memp_malloc(memp_t type) +#else +memp_malloc_fn(memp_t type, const char* file, const int line) +#endif +{ + struct memp *memp; + SYS_ARCH_DECL_PROTECT(old_level); + + LWIP_ERROR("memp_malloc: type < MEMP_MAX", (type < MEMP_MAX), return NULL;); + + SYS_ARCH_PROTECT(old_level); +#if MEMP_OVERFLOW_CHECK >= 2 + memp_overflow_check_all(); +#endif /* MEMP_OVERFLOW_CHECK >= 2 */ + + memp = memp_tab[type]; + + if (memp != NULL) { + memp_tab[type] = memp->next; +#if MEMP_OVERFLOW_CHECK + memp->next = NULL; + memp->file = file; + memp->line = line; +#endif /* MEMP_OVERFLOW_CHECK */ + MEMP_STATS_INC_USED(used, type); + LWIP_ASSERT("memp_malloc: memp properly aligned", + ((mem_ptr_t)memp % MEM_ALIGNMENT) == 0); + memp = (struct memp*)(void *)((u8_t*)memp + MEMP_SIZE); + } else { + LWIP_DEBUGF(MEMP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("memp_malloc: out of memory in pool %s\n", memp_desc[type])); + MEMP_STATS_INC(err, type); + } + + SYS_ARCH_UNPROTECT(old_level); + + return memp; +} + +/** + * Put an element back into its pool. + * + * @param type the pool where to put mem + * @param mem the memp element to free + */ +void +memp_free(memp_t type, void *mem) +{ + struct memp *memp; + SYS_ARCH_DECL_PROTECT(old_level); + + if (mem == NULL) { + return; + } + LWIP_ASSERT("memp_free: mem properly aligned", + ((mem_ptr_t)mem % MEM_ALIGNMENT) == 0); + + memp = (struct memp *)(void *)((u8_t*)mem - MEMP_SIZE); + + SYS_ARCH_PROTECT(old_level); +#if MEMP_OVERFLOW_CHECK +#if MEMP_OVERFLOW_CHECK >= 2 + memp_overflow_check_all(); +#else + memp_overflow_check_element_overflow(memp, type); + memp_overflow_check_element_underflow(memp, type); +#endif /* MEMP_OVERFLOW_CHECK >= 2 */ +#endif /* MEMP_OVERFLOW_CHECK */ + + MEMP_STATS_DEC(used, type); + + memp->next = memp_tab[type]; + memp_tab[type] = memp; + +#if MEMP_SANITY_CHECK + LWIP_ASSERT("memp sanity", memp_sanity()); +#endif /* MEMP_SANITY_CHECK */ + + SYS_ARCH_UNPROTECT(old_level); +} + +#endif /* MEMP_MEM_MALLOC */ diff --git a/src/lwip-1.4.1/src/core/netif.c b/src/lwip-1.4.1/src/core/netif.c new file mode 100644 index 0000000..4a02e77 --- /dev/null +++ b/src/lwip-1.4.1/src/core/netif.c @@ -0,0 +1,774 @@ +/** + * @file + * lwIP network interface abstraction + * + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#include "lwip/opt.h" + +#include "lwip/def.h" +#include "lwip/ip_addr.h" +#include "lwip/netif.h" +#include "lwip/tcp_impl.h" +#include "lwip/snmp.h" +#include "lwip/igmp.h" +#include "netif/etharp.h" +#include "lwip/stats.h" +#if ENABLE_LOOPBACK +#include "lwip/sys.h" +#if LWIP_NETIF_LOOPBACK_MULTITHREADING +#include "lwip/tcpip.h" +#endif /* LWIP_NETIF_LOOPBACK_MULTITHREADING */ +#endif /* ENABLE_LOOPBACK */ + +#if LWIP_AUTOIP +#include "lwip/autoip.h" +#endif /* LWIP_AUTOIP */ +#if LWIP_DHCP +#include "lwip/dhcp.h" +#endif /* LWIP_DHCP */ + +#if LWIP_NETIF_STATUS_CALLBACK +#define NETIF_STATUS_CALLBACK(n) do{ if (n->status_callback) { (n->status_callback)(n); }}while(0) +#else +#define NETIF_STATUS_CALLBACK(n) +#endif /* LWIP_NETIF_STATUS_CALLBACK */ + +#if LWIP_NETIF_LINK_CALLBACK +#define NETIF_LINK_CALLBACK(n) do{ if (n->link_callback) { (n->link_callback)(n); }}while(0) +#else +#define NETIF_LINK_CALLBACK(n) +#endif /* LWIP_NETIF_LINK_CALLBACK */ + +struct netif *netif_list; +struct netif *netif_default; + +static u8_t netif_num; + +#if LWIP_HAVE_LOOPIF +static struct netif loop_netif; + +/** + * Initialize a lwip network interface structure for a loopback interface + * + * @param netif the lwip network interface structure for this loopif + * @return ERR_OK if the loopif is initialized + * ERR_MEM if private data couldn't be allocated + */ +static err_t +netif_loopif_init(struct netif *netif) +{ + /* initialize the snmp variables and counters inside the struct netif + * ifSpeed: no assumption can be made! + */ + NETIF_INIT_SNMP(netif, snmp_ifType_softwareLoopback, 0); + + netif->name[0] = 'l'; + netif->name[1] = 'o'; + netif->output = netif_loop_output; + return ERR_OK; +} +#endif /* LWIP_HAVE_LOOPIF */ + +void +netif_init(void) +{ +#if LWIP_HAVE_LOOPIF + ip_addr_t loop_ipaddr, loop_netmask, loop_gw; + IP4_ADDR(&loop_gw, 127,0,0,1); + IP4_ADDR(&loop_ipaddr, 127,0,0,1); + IP4_ADDR(&loop_netmask, 255,0,0,0); + +#if NO_SYS + netif_add(&loop_netif, &loop_ipaddr, &loop_netmask, &loop_gw, NULL, netif_loopif_init, ip_input); +#else /* NO_SYS */ + netif_add(&loop_netif, &loop_ipaddr, &loop_netmask, &loop_gw, NULL, netif_loopif_init, tcpip_input); +#endif /* NO_SYS */ + netif_set_up(&loop_netif); + +#endif /* LWIP_HAVE_LOOPIF */ +} + +/** + * Add a network interface to the list of lwIP netifs. + * + * @param netif a pre-allocated netif structure + * @param ipaddr IP address for the new netif + * @param netmask network mask for the new netif + * @param gw default gateway IP address for the new netif + * @param state opaque data passed to the new netif + * @param init callback function that initializes the interface + * @param input callback function that is called to pass + * ingress packets up in the protocol layer stack. + * + * @return netif, or NULL if failed. + */ +struct netif * +netif_add(struct netif *netif, ip_addr_t *ipaddr, ip_addr_t *netmask, + ip_addr_t *gw, void *state, netif_init_fn init, netif_input_fn input) +{ + + LWIP_ASSERT("No init function given", init != NULL); + + /* reset new interface configuration state */ + ip_addr_set_zero(&netif->ip_addr); + ip_addr_set_zero(&netif->netmask); + ip_addr_set_zero(&netif->gw); + netif->flags = 0; +#if LWIP_DHCP + /* netif not under DHCP control by default */ + netif->dhcp = NULL; +#endif /* LWIP_DHCP */ +#if LWIP_AUTOIP + /* netif not under AutoIP control by default */ + netif->autoip = NULL; +#endif /* LWIP_AUTOIP */ +#if LWIP_NETIF_STATUS_CALLBACK + netif->status_callback = NULL; +#endif /* LWIP_NETIF_STATUS_CALLBACK */ +#if LWIP_NETIF_LINK_CALLBACK + netif->link_callback = NULL; +#endif /* LWIP_NETIF_LINK_CALLBACK */ +#if LWIP_IGMP + netif->igmp_mac_filter = NULL; +#endif /* LWIP_IGMP */ +#if ENABLE_LOOPBACK + netif->loop_first = NULL; + netif->loop_last = NULL; +#endif /* ENABLE_LOOPBACK */ + + /* remember netif specific state information data */ + netif->state = state; + netif->num = netif_num++; + netif->input = input; + NETIF_SET_HWADDRHINT(netif, NULL); +#if ENABLE_LOOPBACK && LWIP_LOOPBACK_MAX_PBUFS + netif->loop_cnt_current = 0; +#endif /* ENABLE_LOOPBACK && LWIP_LOOPBACK_MAX_PBUFS */ + + netif_set_addr(netif, ipaddr, netmask, gw); + + /* call user specified initialization function for netif */ + if (init(netif) != ERR_OK) { + return NULL; + } + + /* add this netif to the list */ + netif->next = netif_list; + netif_list = netif; + snmp_inc_iflist(); + +#if LWIP_IGMP + /* start IGMP processing */ + if (netif->flags & NETIF_FLAG_IGMP) { + igmp_start(netif); + } +#endif /* LWIP_IGMP */ + + LWIP_DEBUGF(NETIF_DEBUG, ("netif: added interface %c%c IP addr ", + netif->name[0], netif->name[1])); + ip_addr_debug_print(NETIF_DEBUG, ipaddr); + LWIP_DEBUGF(NETIF_DEBUG, (" netmask ")); + ip_addr_debug_print(NETIF_DEBUG, netmask); + LWIP_DEBUGF(NETIF_DEBUG, (" gw ")); + ip_addr_debug_print(NETIF_DEBUG, gw); + LWIP_DEBUGF(NETIF_DEBUG, ("\n")); + return netif; +} + +/** + * Change IP address configuration for a network interface (including netmask + * and default gateway). + * + * @param netif the network interface to change + * @param ipaddr the new IP address + * @param netmask the new netmask + * @param gw the new default gateway + */ +void +netif_set_addr(struct netif *netif, ip_addr_t *ipaddr, ip_addr_t *netmask, + ip_addr_t *gw) +{ + netif_set_ipaddr(netif, ipaddr); + netif_set_netmask(netif, netmask); + netif_set_gw(netif, gw); +} + +/** + * Remove a network interface from the list of lwIP netifs. + * + * @param netif the network interface to remove + */ +void +netif_remove(struct netif *netif) +{ + if (netif == NULL) { + return; + } + +#if LWIP_IGMP + /* stop IGMP processing */ + if (netif->flags & NETIF_FLAG_IGMP) { + igmp_stop(netif); + } +#endif /* LWIP_IGMP */ + if (netif_is_up(netif)) { + /* set netif down before removing (call callback function) */ + netif_set_down(netif); + } + + snmp_delete_ipaddridx_tree(netif); + + /* is it the first netif? */ + if (netif_list == netif) { + netif_list = netif->next; + } else { + /* look for netif further down the list */ + struct netif * tmpNetif; + for (tmpNetif = netif_list; tmpNetif != NULL; tmpNetif = tmpNetif->next) { + if (tmpNetif->next == netif) { + tmpNetif->next = netif->next; + break; + } + } + if (tmpNetif == NULL) + return; /* we didn't find any netif today */ + } + snmp_dec_iflist(); + /* this netif is default? */ + if (netif_default == netif) { + /* reset default netif */ + netif_set_default(NULL); + } +#if LWIP_NETIF_REMOVE_CALLBACK + if (netif->remove_callback) { + netif->remove_callback(netif); + } +#endif /* LWIP_NETIF_REMOVE_CALLBACK */ + LWIP_DEBUGF( NETIF_DEBUG, ("netif_remove: removed netif\n") ); +} + +/** + * Find a network interface by searching for its name + * + * @param name the name of the netif (like netif->name) plus concatenated number + * in ascii representation (e.g. 'en0') + */ +struct netif * +netif_find(char *name) +{ + struct netif *netif; + u8_t num; + + if (name == NULL) { + return NULL; + } + + num = name[2] - '0'; + + for(netif = netif_list; netif != NULL; netif = netif->next) { + if (num == netif->num && + name[0] == netif->name[0] && + name[1] == netif->name[1]) { + LWIP_DEBUGF(NETIF_DEBUG, ("netif_find: found %c%c\n", name[0], name[1])); + return netif; + } + } + LWIP_DEBUGF(NETIF_DEBUG, ("netif_find: didn't find %c%c\n", name[0], name[1])); + return NULL; +} + +/** + * Change the IP address of a network interface + * + * @param netif the network interface to change + * @param ipaddr the new IP address + * + * @note call netif_set_addr() if you also want to change netmask and + * default gateway + */ +void +netif_set_ipaddr(struct netif *netif, ip_addr_t *ipaddr) +{ + /* TODO: Handling of obsolete pcbs */ + /* See: http://mail.gnu.org/archive/html/lwip-users/2003-03/msg00118.html */ +#if LWIP_TCP + struct tcp_pcb *pcb; + struct tcp_pcb_listen *lpcb; + + /* address is actually being changed? */ + if (ipaddr && (ip_addr_cmp(ipaddr, &(netif->ip_addr))) == 0) { + /* extern struct tcp_pcb *tcp_active_pcbs; defined by tcp.h */ + LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_STATE, ("netif_set_ipaddr: netif address being changed\n")); + pcb = tcp_active_pcbs; + while (pcb != NULL) { + /* PCB bound to current local interface address? */ + if (ip_addr_cmp(&(pcb->local_ip), &(netif->ip_addr)) +#if LWIP_AUTOIP + /* connections to link-local addresses must persist (RFC3927 ch. 1.9) */ + && !ip_addr_islinklocal(&(pcb->local_ip)) +#endif /* LWIP_AUTOIP */ + ) { + /* this connection must be aborted */ + struct tcp_pcb *next = pcb->next; + LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_STATE, ("netif_set_ipaddr: aborting TCP pcb %p\n", (void *)pcb)); + tcp_abort(pcb); + pcb = next; + } else { + pcb = pcb->next; + } + } + for (lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next) { + /* PCB bound to current local interface address? */ + if ((!(ip_addr_isany(&(lpcb->local_ip)))) && + (ip_addr_cmp(&(lpcb->local_ip), &(netif->ip_addr)))) { + /* The PCB is listening to the old ipaddr and + * is set to listen to the new one instead */ + ip_addr_set(&(lpcb->local_ip), ipaddr); + } + } + } +#endif + snmp_delete_ipaddridx_tree(netif); + snmp_delete_iprteidx_tree(0,netif); + /* set new IP address to netif */ + ip_addr_set(&(netif->ip_addr), ipaddr); + snmp_insert_ipaddridx_tree(netif); + snmp_insert_iprteidx_tree(0,netif); + + LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("netif: IP address of interface %c%c set to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", + netif->name[0], netif->name[1], + ip4_addr1_16(&netif->ip_addr), + ip4_addr2_16(&netif->ip_addr), + ip4_addr3_16(&netif->ip_addr), + ip4_addr4_16(&netif->ip_addr))); +} + +/** + * Change the default gateway for a network interface + * + * @param netif the network interface to change + * @param gw the new default gateway + * + * @note call netif_set_addr() if you also want to change ip address and netmask + */ +void +netif_set_gw(struct netif *netif, ip_addr_t *gw) +{ + ip_addr_set(&(netif->gw), gw); + LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("netif: GW address of interface %c%c set to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", + netif->name[0], netif->name[1], + ip4_addr1_16(&netif->gw), + ip4_addr2_16(&netif->gw), + ip4_addr3_16(&netif->gw), + ip4_addr4_16(&netif->gw))); +} + +/** + * Change the netmask of a network interface + * + * @param netif the network interface to change + * @param netmask the new netmask + * + * @note call netif_set_addr() if you also want to change ip address and + * default gateway + */ +void +netif_set_netmask(struct netif *netif, ip_addr_t *netmask) +{ + snmp_delete_iprteidx_tree(0, netif); + /* set new netmask to netif */ + ip_addr_set(&(netif->netmask), netmask); + snmp_insert_iprteidx_tree(0, netif); + LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("netif: netmask of interface %c%c set to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", + netif->name[0], netif->name[1], + ip4_addr1_16(&netif->netmask), + ip4_addr2_16(&netif->netmask), + ip4_addr3_16(&netif->netmask), + ip4_addr4_16(&netif->netmask))); +} + +/** + * Set a network interface as the default network interface + * (used to output all packets for which no specific route is found) + * + * @param netif the default network interface + */ +void +netif_set_default(struct netif *netif) +{ + if (netif == NULL) { + /* remove default route */ + snmp_delete_iprteidx_tree(1, netif); + } else { + /* install default route */ + snmp_insert_iprteidx_tree(1, netif); + } + netif_default = netif; + LWIP_DEBUGF(NETIF_DEBUG, ("netif: setting default interface %c%c\n", + netif ? netif->name[0] : '\'', netif ? netif->name[1] : '\'')); +} + +/** + * Bring an interface up, available for processing + * traffic. + * + * @note: Enabling DHCP on a down interface will make it come + * up once configured. + * + * @see dhcp_start() + */ +void netif_set_up(struct netif *netif) +{ + if (!(netif->flags & NETIF_FLAG_UP)) { + netif->flags |= NETIF_FLAG_UP; + +#if LWIP_SNMP + snmp_get_sysuptime(&netif->ts); +#endif /* LWIP_SNMP */ + + NETIF_STATUS_CALLBACK(netif); + + if (netif->flags & NETIF_FLAG_LINK_UP) { +#if LWIP_ARP + /* For Ethernet network interfaces, we would like to send a "gratuitous ARP" */ + if (netif->flags & (NETIF_FLAG_ETHARP)) { + etharp_gratuitous(netif); + } +#endif /* LWIP_ARP */ + +#if LWIP_IGMP + /* resend IGMP memberships */ + if (netif->flags & NETIF_FLAG_IGMP) { + igmp_report_groups( netif); + } +#endif /* LWIP_IGMP */ + } + } +} + +/** + * Bring an interface down, disabling any traffic processing. + * + * @note: Enabling DHCP on a down interface will make it come + * up once configured. + * + * @see dhcp_start() + */ +void netif_set_down(struct netif *netif) +{ + if (netif->flags & NETIF_FLAG_UP) { + netif->flags &= ~NETIF_FLAG_UP; +#if LWIP_SNMP + snmp_get_sysuptime(&netif->ts); +#endif + +#if LWIP_ARP + if (netif->flags & NETIF_FLAG_ETHARP) { + etharp_cleanup_netif(netif); + } +#endif /* LWIP_ARP */ + NETIF_STATUS_CALLBACK(netif); + } +} + +#if LWIP_NETIF_STATUS_CALLBACK +/** + * Set callback to be called when interface is brought up/down + */ +void netif_set_status_callback(struct netif *netif, netif_status_callback_fn status_callback) +{ + if (netif) { + netif->status_callback = status_callback; + } +} +#endif /* LWIP_NETIF_STATUS_CALLBACK */ + +#if LWIP_NETIF_REMOVE_CALLBACK +/** + * Set callback to be called when the interface has been removed + */ +void +netif_set_remove_callback(struct netif *netif, netif_status_callback_fn remove_callback) +{ + if (netif) { + netif->remove_callback = remove_callback; + } +} +#endif /* LWIP_NETIF_REMOVE_CALLBACK */ + +/** + * Called by a driver when its link goes up + */ +void netif_set_link_up(struct netif *netif ) +{ + if (!(netif->flags & NETIF_FLAG_LINK_UP)) { + netif->flags |= NETIF_FLAG_LINK_UP; + +#if LWIP_DHCP + if (netif->dhcp) { + dhcp_network_changed(netif); + } +#endif /* LWIP_DHCP */ + +#if LWIP_AUTOIP + if (netif->autoip) { + autoip_network_changed(netif); + } +#endif /* LWIP_AUTOIP */ + + if (netif->flags & NETIF_FLAG_UP) { +#if LWIP_ARP + /* For Ethernet network interfaces, we would like to send a "gratuitous ARP" */ + if (netif->flags & NETIF_FLAG_ETHARP) { + etharp_gratuitous(netif); + } +#endif /* LWIP_ARP */ + +#if LWIP_IGMP + /* resend IGMP memberships */ + if (netif->flags & NETIF_FLAG_IGMP) { + igmp_report_groups( netif); + } +#endif /* LWIP_IGMP */ + } + NETIF_LINK_CALLBACK(netif); + } +} + +/** + * Called by a driver when its link goes down + */ +void netif_set_link_down(struct netif *netif ) +{ + if (netif->flags & NETIF_FLAG_LINK_UP) { + netif->flags &= ~NETIF_FLAG_LINK_UP; + NETIF_LINK_CALLBACK(netif); + } +} + +#if LWIP_NETIF_LINK_CALLBACK +/** + * Set callback to be called when link is brought up/down + */ +void netif_set_link_callback(struct netif *netif, netif_status_callback_fn link_callback) +{ + if (netif) { + netif->link_callback = link_callback; + } +} +#endif /* LWIP_NETIF_LINK_CALLBACK */ + +#if ENABLE_LOOPBACK +/** + * Send an IP packet to be received on the same netif (loopif-like). + * The pbuf is simply copied and handed back to netif->input. + * In multithreaded mode, this is done directly since netif->input must put + * the packet on a queue. + * In callback mode, the packet is put on an internal queue and is fed to + * netif->input by netif_poll(). + * + * @param netif the lwip network interface structure + * @param p the (IP) packet to 'send' + * @param ipaddr the ip address to send the packet to (not used) + * @return ERR_OK if the packet has been sent + * ERR_MEM if the pbuf used to copy the packet couldn't be allocated + */ +err_t +netif_loop_output(struct netif *netif, struct pbuf *p, + ip_addr_t *ipaddr) +{ + struct pbuf *r; + err_t err; + struct pbuf *last; +#if LWIP_LOOPBACK_MAX_PBUFS + u8_t clen = 0; +#endif /* LWIP_LOOPBACK_MAX_PBUFS */ + /* If we have a loopif, SNMP counters are adjusted for it, + * if not they are adjusted for 'netif'. */ +#if LWIP_SNMP +#if LWIP_HAVE_LOOPIF + struct netif *stats_if = &loop_netif; +#else /* LWIP_HAVE_LOOPIF */ + struct netif *stats_if = netif; +#endif /* LWIP_HAVE_LOOPIF */ +#endif /* LWIP_SNMP */ + SYS_ARCH_DECL_PROTECT(lev); + LWIP_UNUSED_ARG(ipaddr); + + /* Allocate a new pbuf */ + r = pbuf_alloc(PBUF_LINK, p->tot_len, PBUF_RAM); + if (r == NULL) { + LINK_STATS_INC(link.memerr); + LINK_STATS_INC(link.drop); + snmp_inc_ifoutdiscards(stats_if); + return ERR_MEM; + } +#if LWIP_LOOPBACK_MAX_PBUFS + clen = pbuf_clen(r); + /* check for overflow or too many pbuf on queue */ + if(((netif->loop_cnt_current + clen) < netif->loop_cnt_current) || + ((netif->loop_cnt_current + clen) > LWIP_LOOPBACK_MAX_PBUFS)) { + pbuf_free(r); + LINK_STATS_INC(link.memerr); + LINK_STATS_INC(link.drop); + snmp_inc_ifoutdiscards(stats_if); + return ERR_MEM; + } + netif->loop_cnt_current += clen; +#endif /* LWIP_LOOPBACK_MAX_PBUFS */ + + /* Copy the whole pbuf queue p into the single pbuf r */ + if ((err = pbuf_copy(r, p)) != ERR_OK) { + pbuf_free(r); + LINK_STATS_INC(link.memerr); + LINK_STATS_INC(link.drop); + snmp_inc_ifoutdiscards(stats_if); + return err; + } + + /* Put the packet on a linked list which gets emptied through calling + netif_poll(). */ + + /* let last point to the last pbuf in chain r */ + for (last = r; last->next != NULL; last = last->next); + + SYS_ARCH_PROTECT(lev); + if(netif->loop_first != NULL) { + LWIP_ASSERT("if first != NULL, last must also be != NULL", netif->loop_last != NULL); + netif->loop_last->next = r; + netif->loop_last = last; + } else { + netif->loop_first = r; + netif->loop_last = last; + } + SYS_ARCH_UNPROTECT(lev); + + LINK_STATS_INC(link.xmit); + snmp_add_ifoutoctets(stats_if, p->tot_len); + snmp_inc_ifoutucastpkts(stats_if); + +#if LWIP_NETIF_LOOPBACK_MULTITHREADING + /* For multithreading environment, schedule a call to netif_poll */ + tcpip_callback((tcpip_callback_fn)netif_poll, netif); +#endif /* LWIP_NETIF_LOOPBACK_MULTITHREADING */ + + return ERR_OK; +} + +/** + * Call netif_poll() in the main loop of your application. This is to prevent + * reentering non-reentrant functions like tcp_input(). Packets passed to + * netif_loop_output() are put on a list that is passed to netif->input() by + * netif_poll(). + */ +void +netif_poll(struct netif *netif) +{ + struct pbuf *in; + /* If we have a loopif, SNMP counters are adjusted for it, + * if not they are adjusted for 'netif'. */ +#if LWIP_SNMP +#if LWIP_HAVE_LOOPIF + struct netif *stats_if = &loop_netif; +#else /* LWIP_HAVE_LOOPIF */ + struct netif *stats_if = netif; +#endif /* LWIP_HAVE_LOOPIF */ +#endif /* LWIP_SNMP */ + SYS_ARCH_DECL_PROTECT(lev); + + do { + /* Get a packet from the list. With SYS_LIGHTWEIGHT_PROT=1, this is protected */ + SYS_ARCH_PROTECT(lev); + in = netif->loop_first; + if (in != NULL) { + struct pbuf *in_end = in; +#if LWIP_LOOPBACK_MAX_PBUFS + u8_t clen = pbuf_clen(in); + /* adjust the number of pbufs on queue */ + LWIP_ASSERT("netif->loop_cnt_current underflow", + ((netif->loop_cnt_current - clen) < netif->loop_cnt_current)); + netif->loop_cnt_current -= clen; +#endif /* LWIP_LOOPBACK_MAX_PBUFS */ + while (in_end->len != in_end->tot_len) { + LWIP_ASSERT("bogus pbuf: len != tot_len but next == NULL!", in_end->next != NULL); + in_end = in_end->next; + } + /* 'in_end' now points to the last pbuf from 'in' */ + if (in_end == netif->loop_last) { + /* this was the last pbuf in the list */ + netif->loop_first = netif->loop_last = NULL; + } else { + /* pop the pbuf off the list */ + netif->loop_first = in_end->next; + LWIP_ASSERT("should not be null since first != last!", netif->loop_first != NULL); + } + /* De-queue the pbuf from its successors on the 'loop_' list. */ + in_end->next = NULL; + } + SYS_ARCH_UNPROTECT(lev); + + if (in != NULL) { + LINK_STATS_INC(link.recv); + snmp_add_ifinoctets(stats_if, in->tot_len); + snmp_inc_ifinucastpkts(stats_if); + /* loopback packets are always IP packets! */ + if (ip_input(in, netif) != ERR_OK) { + pbuf_free(in); + } + /* Don't reference the packet any more! */ + in = NULL; + } + /* go on while there is a packet on the list */ + } while (netif->loop_first != NULL); +} + +#if !LWIP_NETIF_LOOPBACK_MULTITHREADING +/** + * Calls netif_poll() for every netif on the netif_list. + */ +void +netif_poll_all(void) +{ + struct netif *netif = netif_list; + /* loop through netifs */ + while (netif != NULL) { + netif_poll(netif); + /* proceed to next network interface */ + netif = netif->next; + } +} +#endif /* !LWIP_NETIF_LOOPBACK_MULTITHREADING */ +#endif /* ENABLE_LOOPBACK */ diff --git a/src/lwip-1.4.1/src/core/pbuf.c b/src/lwip-1.4.1/src/core/pbuf.c new file mode 100644 index 0000000..1e5e53b --- /dev/null +++ b/src/lwip-1.4.1/src/core/pbuf.c @@ -0,0 +1,1179 @@ +/** + * @file + * Packet buffer management + * + * Packets are built from the pbuf data structure. It supports dynamic + * memory allocation for packet contents or can reference externally + * managed packet contents both in RAM and ROM. Quick allocation for + * incoming packets is provided through pools with fixed sized pbufs. + * + * A packet may span over multiple pbufs, chained as a singly linked + * list. This is called a "pbuf chain". + * + * Multiple packets may be queued, also using this singly linked list. + * This is called a "packet queue". + * + * So, a packet queue consists of one or more pbuf chains, each of + * which consist of one or more pbufs. CURRENTLY, PACKET QUEUES ARE + * NOT SUPPORTED!!! Use helper structs to queue multiple packets. + * + * The differences between a pbuf chain and a packet queue are very + * precise but subtle. + * + * The last pbuf of a packet has a ->tot_len field that equals the + * ->len field. It can be found by traversing the list. If the last + * pbuf of a packet has a ->next field other than NULL, more packets + * are on the queue. + * + * Therefore, looping through a pbuf of a single packet, has an + * loop end condition (tot_len == p->len), NOT (next == NULL). + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#include "lwip/opt.h" + +#include "lwip/stats.h" +#include "lwip/def.h" +#include "lwip/mem.h" +#include "lwip/memp.h" +#include "lwip/pbuf.h" +#include "lwip/sys.h" +#include "arch/perf.h" +#if LWIP_TCP && TCP_QUEUE_OOSEQ +#include "lwip/tcp_impl.h" +#endif +#if LWIP_CHECKSUM_ON_COPY +#include "lwip/inet_chksum.h" +#endif + +#include + +#define SIZEOF_STRUCT_PBUF LWIP_MEM_ALIGN_SIZE(sizeof(struct pbuf)) +/* Since the pool is created in memp, PBUF_POOL_BUFSIZE will be automatically + aligned there. Therefore, PBUF_POOL_BUFSIZE_ALIGNED can be used here. */ +#define PBUF_POOL_BUFSIZE_ALIGNED LWIP_MEM_ALIGN_SIZE(PBUF_POOL_BUFSIZE) + +#if !LWIP_TCP || !TCP_QUEUE_OOSEQ || !PBUF_POOL_FREE_OOSEQ +#define PBUF_POOL_IS_EMPTY() +#else /* !LWIP_TCP || !TCP_QUEUE_OOSEQ || !PBUF_POOL_FREE_OOSEQ */ + +#if !NO_SYS +#ifndef PBUF_POOL_FREE_OOSEQ_QUEUE_CALL +#include "lwip/tcpip.h" +#define PBUF_POOL_FREE_OOSEQ_QUEUE_CALL() do { \ + if(tcpip_callback_with_block(pbuf_free_ooseq_callback, NULL, 0) != ERR_OK) { \ + SYS_ARCH_PROTECT(old_level); \ + pbuf_free_ooseq_pending = 0; \ + SYS_ARCH_UNPROTECT(old_level); \ + } } while(0) +#endif /* PBUF_POOL_FREE_OOSEQ_QUEUE_CALL */ +#endif /* !NO_SYS */ + +volatile u8_t pbuf_free_ooseq_pending; +#define PBUF_POOL_IS_EMPTY() pbuf_pool_is_empty() + +/** + * Attempt to reclaim some memory from queued out-of-sequence TCP segments + * if we run out of pool pbufs. It's better to give priority to new packets + * if we're running out. + * + * This must be done in the correct thread context therefore this function + * can only be used with NO_SYS=0 and through tcpip_callback. + */ +#if !NO_SYS +static +#endif /* !NO_SYS */ +void +pbuf_free_ooseq(void) +{ + struct tcp_pcb* pcb; + SYS_ARCH_DECL_PROTECT(old_level); + + SYS_ARCH_PROTECT(old_level); + pbuf_free_ooseq_pending = 0; + SYS_ARCH_UNPROTECT(old_level); + + for (pcb = tcp_active_pcbs; NULL != pcb; pcb = pcb->next) { + if (NULL != pcb->ooseq) { + /** Free the ooseq pbufs of one PCB only */ + LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_free_ooseq: freeing out-of-sequence pbufs\n")); + tcp_segs_free(pcb->ooseq); + pcb->ooseq = NULL; + return; + } + } +} + +#if !NO_SYS +/** + * Just a callback function for tcpip_timeout() that calls pbuf_free_ooseq(). + */ +static void +pbuf_free_ooseq_callback(void *arg) +{ + LWIP_UNUSED_ARG(arg); + pbuf_free_ooseq(); +} +#endif /* !NO_SYS */ + +/** Queue a call to pbuf_free_ooseq if not already queued. */ +static void +pbuf_pool_is_empty(void) +{ +#ifndef PBUF_POOL_FREE_OOSEQ_QUEUE_CALL + SYS_ARCH_DECL_PROTECT(old_level); + SYS_ARCH_PROTECT(old_level); + pbuf_free_ooseq_pending = 1; + SYS_ARCH_UNPROTECT(old_level); +#else /* PBUF_POOL_FREE_OOSEQ_QUEUE_CALL */ + u8_t queued; + SYS_ARCH_DECL_PROTECT(old_level); + SYS_ARCH_PROTECT(old_level); + queued = pbuf_free_ooseq_pending; + pbuf_free_ooseq_pending = 1; + SYS_ARCH_UNPROTECT(old_level); + + if(!queued) { + /* queue a call to pbuf_free_ooseq if not already queued */ + PBUF_POOL_FREE_OOSEQ_QUEUE_CALL(); + } +#endif /* PBUF_POOL_FREE_OOSEQ_QUEUE_CALL */ +} +#endif /* !LWIP_TCP || !TCP_QUEUE_OOSEQ || !PBUF_POOL_FREE_OOSEQ */ + +/** + * Allocates a pbuf of the given type (possibly a chain for PBUF_POOL type). + * + * The actual memory allocated for the pbuf is determined by the + * layer at which the pbuf is allocated and the requested size + * (from the size parameter). + * + * @param layer flag to define header size + * @param length size of the pbuf's payload + * @param type this parameter decides how and where the pbuf + * should be allocated as follows: + * + * - PBUF_RAM: buffer memory for pbuf is allocated as one large + * chunk. This includes protocol headers as well. + * - PBUF_ROM: no buffer memory is allocated for the pbuf, even for + * protocol headers. Additional headers must be prepended + * by allocating another pbuf and chain in to the front of + * the ROM pbuf. It is assumed that the memory used is really + * similar to ROM in that it is immutable and will not be + * changed. Memory which is dynamic should generally not + * be attached to PBUF_ROM pbufs. Use PBUF_REF instead. + * - PBUF_REF: no buffer memory is allocated for the pbuf, even for + * protocol headers. It is assumed that the pbuf is only + * being used in a single thread. If the pbuf gets queued, + * then pbuf_take should be called to copy the buffer. + * - PBUF_POOL: the pbuf is allocated as a pbuf chain, with pbufs from + * the pbuf pool that is allocated during pbuf_init(). + * + * @return the allocated pbuf. If multiple pbufs where allocated, this + * is the first pbuf of a pbuf chain. + */ +struct pbuf * +pbuf_alloc(pbuf_layer layer, u16_t length, pbuf_type type) +{ + struct pbuf *p, *q, *r; + u16_t offset; + s32_t rem_len; /* remaining length */ + LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_alloc(length=%"U16_F")\n", length)); + + /* determine header offset */ + switch (layer) { + case PBUF_TRANSPORT: + /* add room for transport (often TCP) layer header */ + offset = PBUF_LINK_HLEN + PBUF_IP_HLEN + PBUF_TRANSPORT_HLEN; + break; + case PBUF_IP: + /* add room for IP layer header */ + offset = PBUF_LINK_HLEN + PBUF_IP_HLEN; + break; + case PBUF_LINK: + /* add room for link layer header */ + offset = PBUF_LINK_HLEN; + break; + case PBUF_RAW: + offset = 0; + break; + default: + LWIP_ASSERT("pbuf_alloc: bad pbuf layer", 0); + return NULL; + } + + switch (type) { + case PBUF_POOL: + /* allocate head of pbuf chain into p */ + p = (struct pbuf *)memp_malloc(MEMP_PBUF_POOL); + LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_alloc: allocated pbuf %p\n", (void *)p)); + if (p == NULL) { + PBUF_POOL_IS_EMPTY(); + return NULL; + } + p->type = type; + p->next = NULL; + + /* make the payload pointer point 'offset' bytes into pbuf data memory */ + p->payload = LWIP_MEM_ALIGN((void *)((u8_t *)p + (SIZEOF_STRUCT_PBUF + offset))); + LWIP_ASSERT("pbuf_alloc: pbuf p->payload properly aligned", + ((mem_ptr_t)p->payload % MEM_ALIGNMENT) == 0); + /* the total length of the pbuf chain is the requested size */ + p->tot_len = length; + /* set the length of the first pbuf in the chain */ + p->len = LWIP_MIN(length, PBUF_POOL_BUFSIZE_ALIGNED - LWIP_MEM_ALIGN_SIZE(offset)); + LWIP_ASSERT("check p->payload + p->len does not overflow pbuf", + ((u8_t*)p->payload + p->len <= + (u8_t*)p + SIZEOF_STRUCT_PBUF + PBUF_POOL_BUFSIZE_ALIGNED)); + LWIP_ASSERT("PBUF_POOL_BUFSIZE must be bigger than MEM_ALIGNMENT", + (PBUF_POOL_BUFSIZE_ALIGNED - LWIP_MEM_ALIGN_SIZE(offset)) > 0 ); + /* set reference count (needed here in case we fail) */ + p->ref = 1; + + /* now allocate the tail of the pbuf chain */ + + /* remember first pbuf for linkage in next iteration */ + r = p; + /* remaining length to be allocated */ + rem_len = length - p->len; + /* any remaining pbufs to be allocated? */ + while (rem_len > 0) { + q = (struct pbuf *)memp_malloc(MEMP_PBUF_POOL); + if (q == NULL) { + PBUF_POOL_IS_EMPTY(); + /* free chain so far allocated */ + pbuf_free(p); + /* bail out unsuccesfully */ + return NULL; + } + q->type = type; + q->flags = 0; + q->next = NULL; + /* make previous pbuf point to this pbuf */ + r->next = q; + /* set total length of this pbuf and next in chain */ + LWIP_ASSERT("rem_len < max_u16_t", rem_len < 0xffff); + q->tot_len = (u16_t)rem_len; + /* this pbuf length is pool size, unless smaller sized tail */ + q->len = LWIP_MIN((u16_t)rem_len, PBUF_POOL_BUFSIZE_ALIGNED); + q->payload = (void *)((u8_t *)q + SIZEOF_STRUCT_PBUF); + LWIP_ASSERT("pbuf_alloc: pbuf q->payload properly aligned", + ((mem_ptr_t)q->payload % MEM_ALIGNMENT) == 0); + LWIP_ASSERT("check p->payload + p->len does not overflow pbuf", + ((u8_t*)p->payload + p->len <= + (u8_t*)p + SIZEOF_STRUCT_PBUF + PBUF_POOL_BUFSIZE_ALIGNED)); + q->ref = 1; + /* calculate remaining length to be allocated */ + rem_len -= q->len; + /* remember this pbuf for linkage in next iteration */ + r = q; + } + /* end of chain */ + /*r->next = NULL;*/ + + break; + case PBUF_RAM: + /* If pbuf is to be allocated in RAM, allocate memory for it. */ + p = (struct pbuf*)mem_malloc(LWIP_MEM_ALIGN_SIZE(SIZEOF_STRUCT_PBUF + offset) + LWIP_MEM_ALIGN_SIZE(length)); + if (p == NULL) { + return NULL; + } + /* Set up internal structure of the pbuf. */ + p->payload = LWIP_MEM_ALIGN((void *)((u8_t *)p + SIZEOF_STRUCT_PBUF + offset)); + p->len = p->tot_len = length; + p->next = NULL; + p->type = type; + + LWIP_ASSERT("pbuf_alloc: pbuf->payload properly aligned", + ((mem_ptr_t)p->payload % MEM_ALIGNMENT) == 0); + break; + /* pbuf references existing (non-volatile static constant) ROM payload? */ + case PBUF_ROM: + /* pbuf references existing (externally allocated) RAM payload? */ + case PBUF_REF: + /* only allocate memory for the pbuf structure */ + p = (struct pbuf *)memp_malloc(MEMP_PBUF); + if (p == NULL) { + LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_LEVEL_SERIOUS, + ("pbuf_alloc: Could not allocate MEMP_PBUF for PBUF_%s.\n", + (type == PBUF_ROM) ? "ROM" : "REF")); + return NULL; + } + /* caller must set this field properly, afterwards */ + p->payload = NULL; + p->len = p->tot_len = length; + p->next = NULL; + p->type = type; + break; + default: + LWIP_ASSERT("pbuf_alloc: erroneous type", 0); + return NULL; + } + /* set reference count */ + p->ref = 1; + /* set flags */ + p->flags = 0; + LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_alloc(length=%"U16_F") == %p\n", length, (void *)p)); + return p; +} + +#if LWIP_SUPPORT_CUSTOM_PBUF +/** Initialize a custom pbuf (already allocated). + * + * @param layer flag to define header size + * @param length size of the pbuf's payload + * @param type type of the pbuf (only used to treat the pbuf accordingly, as + * this function allocates no memory) + * @param p pointer to the custom pbuf to initialize (already allocated) + * @param payload_mem pointer to the buffer that is used for payload and headers, + * must be at least big enough to hold 'length' plus the header size, + * may be NULL if set later. + * ATTENTION: The caller is responsible for correct alignment of this buffer!! + * @param payload_mem_len the size of the 'payload_mem' buffer, must be at least + * big enough to hold 'length' plus the header size + */ +struct pbuf* +pbuf_alloced_custom(pbuf_layer l, u16_t length, pbuf_type type, struct pbuf_custom *p, + void *payload_mem, u16_t payload_mem_len) +{ + u16_t offset; + LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_alloced_custom(length=%"U16_F")\n", length)); + + /* determine header offset */ + switch (l) { + case PBUF_TRANSPORT: + /* add room for transport (often TCP) layer header */ + offset = PBUF_LINK_HLEN + PBUF_IP_HLEN + PBUF_TRANSPORT_HLEN; + break; + case PBUF_IP: + /* add room for IP layer header */ + offset = PBUF_LINK_HLEN + PBUF_IP_HLEN; + break; + case PBUF_LINK: + /* add room for link layer header */ + offset = PBUF_LINK_HLEN; + break; + case PBUF_RAW: + offset = 0; + break; + default: + LWIP_ASSERT("pbuf_alloced_custom: bad pbuf layer", 0); + return NULL; + } + + if (LWIP_MEM_ALIGN_SIZE(offset) + length > payload_mem_len) { + LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_LEVEL_WARNING, ("pbuf_alloced_custom(length=%"U16_F") buffer too short\n", length)); + return NULL; + } + + p->pbuf.next = NULL; + if (payload_mem != NULL) { + p->pbuf.payload = (u8_t *)payload_mem + LWIP_MEM_ALIGN_SIZE(offset); + } else { + p->pbuf.payload = NULL; + } + p->pbuf.flags = PBUF_FLAG_IS_CUSTOM; + p->pbuf.len = p->pbuf.tot_len = length; + p->pbuf.type = type; + p->pbuf.ref = 1; + return &p->pbuf; +} +#endif /* LWIP_SUPPORT_CUSTOM_PBUF */ + +/** + * Shrink a pbuf chain to a desired length. + * + * @param p pbuf to shrink. + * @param new_len desired new length of pbuf chain + * + * Depending on the desired length, the first few pbufs in a chain might + * be skipped and left unchanged. The new last pbuf in the chain will be + * resized, and any remaining pbufs will be freed. + * + * @note If the pbuf is ROM/REF, only the ->tot_len and ->len fields are adjusted. + * @note May not be called on a packet queue. + * + * @note Despite its name, pbuf_realloc cannot grow the size of a pbuf (chain). + */ +void +pbuf_realloc(struct pbuf *p, u16_t new_len) +{ + struct pbuf *q; + u16_t rem_len; /* remaining length */ + s32_t grow; + + LWIP_ASSERT("pbuf_realloc: p != NULL", p != NULL); + LWIP_ASSERT("pbuf_realloc: sane p->type", p->type == PBUF_POOL || + p->type == PBUF_ROM || + p->type == PBUF_RAM || + p->type == PBUF_REF); + + /* desired length larger than current length? */ + if (new_len >= p->tot_len) { + /* enlarging not yet supported */ + return; + } + + /* the pbuf chain grows by (new_len - p->tot_len) bytes + * (which may be negative in case of shrinking) */ + grow = new_len - p->tot_len; + + /* first, step over any pbufs that should remain in the chain */ + rem_len = new_len; + q = p; + /* should this pbuf be kept? */ + while (rem_len > q->len) { + /* decrease remaining length by pbuf length */ + rem_len -= q->len; + /* decrease total length indicator */ + LWIP_ASSERT("grow < max_u16_t", grow < 0xffff); + q->tot_len += (u16_t)grow; + /* proceed to next pbuf in chain */ + q = q->next; + LWIP_ASSERT("pbuf_realloc: q != NULL", q != NULL); + } + /* we have now reached the new last pbuf (in q) */ + /* rem_len == desired length for pbuf q */ + + /* shrink allocated memory for PBUF_RAM */ + /* (other types merely adjust their length fields */ + if ((q->type == PBUF_RAM) && (rem_len != q->len)) { + /* reallocate and adjust the length of the pbuf that will be split */ + q = (struct pbuf *)mem_trim(q, (u16_t)((u8_t *)q->payload - (u8_t *)q) + rem_len); + LWIP_ASSERT("mem_trim returned q == NULL", q != NULL); + } + /* adjust length fields for new last pbuf */ + q->len = rem_len; + q->tot_len = q->len; + + /* any remaining pbufs in chain? */ + if (q->next != NULL) { + /* free remaining pbufs in chain */ + pbuf_free(q->next); + } + /* q is last packet in chain */ + q->next = NULL; + +} + +/** + * Adjusts the payload pointer to hide or reveal headers in the payload. + * + * Adjusts the ->payload pointer so that space for a header + * (dis)appears in the pbuf payload. + * + * The ->payload, ->tot_len and ->len fields are adjusted. + * + * @param p pbuf to change the header size. + * @param header_size_increment Number of bytes to increment header size which + * increases the size of the pbuf. New space is on the front. + * (Using a negative value decreases the header size.) + * If hdr_size_inc is 0, this function does nothing and returns succesful. + * + * PBUF_ROM and PBUF_REF type buffers cannot have their sizes increased, so + * the call will fail. A check is made that the increase in header size does + * not move the payload pointer in front of the start of the buffer. + * @return non-zero on failure, zero on success. + * + */ +u8_t +pbuf_header(struct pbuf *p, s16_t header_size_increment) +{ + u16_t type; + void *payload; + u16_t increment_magnitude; + + LWIP_ASSERT("p != NULL", p != NULL); + if ((header_size_increment == 0) || (p == NULL)) { + return 0; + } + + if (header_size_increment < 0){ + increment_magnitude = -header_size_increment; + /* Check that we aren't going to move off the end of the pbuf */ + LWIP_ERROR("increment_magnitude <= p->len", (increment_magnitude <= p->len), return 1;); + } else { + increment_magnitude = header_size_increment; +#if 0 + /* Can't assert these as some callers speculatively call + pbuf_header() to see if it's OK. Will return 1 below instead. */ + /* Check that we've got the correct type of pbuf to work with */ + LWIP_ASSERT("p->type == PBUF_RAM || p->type == PBUF_POOL", + p->type == PBUF_RAM || p->type == PBUF_POOL); + /* Check that we aren't going to move off the beginning of the pbuf */ + LWIP_ASSERT("p->payload - increment_magnitude >= p + SIZEOF_STRUCT_PBUF", + (u8_t *)p->payload - increment_magnitude >= (u8_t *)p + SIZEOF_STRUCT_PBUF); +#endif + } + + type = p->type; + /* remember current payload pointer */ + payload = p->payload; + + /* pbuf types containing payloads? */ + if (type == PBUF_RAM || type == PBUF_POOL) { + /* set new payload pointer */ + p->payload = (u8_t *)p->payload - header_size_increment; + /* boundary check fails? */ + if ((u8_t *)p->payload < (u8_t *)p + SIZEOF_STRUCT_PBUF) { + LWIP_DEBUGF( PBUF_DEBUG | LWIP_DBG_LEVEL_SERIOUS, + ("pbuf_header: failed as %p < %p (not enough space for new header size)\n", + (void *)p->payload, (void *)(p + 1))); + /* restore old payload pointer */ + p->payload = payload; + /* bail out unsuccesfully */ + return 1; + } + /* pbuf types refering to external payloads? */ + } else if (type == PBUF_REF || type == PBUF_ROM) { + /* hide a header in the payload? */ + if ((header_size_increment < 0) && (increment_magnitude <= p->len)) { + /* increase payload pointer */ + p->payload = (u8_t *)p->payload - header_size_increment; + } else { + /* cannot expand payload to front (yet!) + * bail out unsuccesfully */ + return 1; + } + } else { + /* Unknown type */ + LWIP_ASSERT("bad pbuf type", 0); + return 1; + } + /* modify pbuf length fields */ + p->len += header_size_increment; + p->tot_len += header_size_increment; + + LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_header: old %p new %p (%"S16_F")\n", + (void *)payload, (void *)p->payload, header_size_increment)); + + return 0; +} + +/** + * Dereference a pbuf chain or queue and deallocate any no-longer-used + * pbufs at the head of this chain or queue. + * + * Decrements the pbuf reference count. If it reaches zero, the pbuf is + * deallocated. + * + * For a pbuf chain, this is repeated for each pbuf in the chain, + * up to the first pbuf which has a non-zero reference count after + * decrementing. So, when all reference counts are one, the whole + * chain is free'd. + * + * @param p The pbuf (chain) to be dereferenced. + * + * @return the number of pbufs that were de-allocated + * from the head of the chain. + * + * @note MUST NOT be called on a packet queue (Not verified to work yet). + * @note the reference counter of a pbuf equals the number of pointers + * that refer to the pbuf (or into the pbuf). + * + * @internal examples: + * + * Assuming existing chains a->b->c with the following reference + * counts, calling pbuf_free(a) results in: + * + * 1->2->3 becomes ...1->3 + * 3->3->3 becomes 2->3->3 + * 1->1->2 becomes ......1 + * 2->1->1 becomes 1->1->1 + * 1->1->1 becomes ....... + * + */ +u8_t +pbuf_free(struct pbuf *p) +{ + u16_t type; + struct pbuf *q; + u8_t count; + + if (p == NULL) { + LWIP_ASSERT("p != NULL", p != NULL); + /* if assertions are disabled, proceed with debug output */ + LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_LEVEL_SERIOUS, + ("pbuf_free(p == NULL) was called.\n")); + return 0; + } + LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_free(%p)\n", (void *)p)); + + PERF_START; + + LWIP_ASSERT("pbuf_free: sane type", + p->type == PBUF_RAM || p->type == PBUF_ROM || + p->type == PBUF_REF || p->type == PBUF_POOL); + + count = 0; + /* de-allocate all consecutive pbufs from the head of the chain that + * obtain a zero reference count after decrementing*/ + while (p != NULL) { + u16_t ref; + SYS_ARCH_DECL_PROTECT(old_level); + /* Since decrementing ref cannot be guaranteed to be a single machine operation + * we must protect it. We put the new ref into a local variable to prevent + * further protection. */ + SYS_ARCH_PROTECT(old_level); + /* all pbufs in a chain are referenced at least once */ + LWIP_ASSERT("pbuf_free: p->ref > 0", p->ref > 0); + /* decrease reference count (number of pointers to pbuf) */ + ref = --(p->ref); + SYS_ARCH_UNPROTECT(old_level); + /* this pbuf is no longer referenced to? */ + if (ref == 0) { + /* remember next pbuf in chain for next iteration */ + q = p->next; + LWIP_DEBUGF( PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_free: deallocating %p\n", (void *)p)); + type = p->type; +#if LWIP_SUPPORT_CUSTOM_PBUF + /* is this a custom pbuf? */ + if ((p->flags & PBUF_FLAG_IS_CUSTOM) != 0) { + struct pbuf_custom *pc = (struct pbuf_custom*)p; + LWIP_ASSERT("pc->custom_free_function != NULL", pc->custom_free_function != NULL); + pc->custom_free_function(p); + } else +#endif /* LWIP_SUPPORT_CUSTOM_PBUF */ + { + /* is this a pbuf from the pool? */ + if (type == PBUF_POOL) { + memp_free(MEMP_PBUF_POOL, p); + /* is this a ROM or RAM referencing pbuf? */ + } else if (type == PBUF_ROM || type == PBUF_REF) { + memp_free(MEMP_PBUF, p); + /* type == PBUF_RAM */ + } else { + mem_free(p); + } + } + count++; + /* proceed to next pbuf */ + p = q; + /* p->ref > 0, this pbuf is still referenced to */ + /* (and so the remaining pbufs in chain as well) */ + } else { + LWIP_DEBUGF( PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_free: %p has ref %"U16_F", ending here.\n", (void *)p, ref)); + /* stop walking through the chain */ + p = NULL; + } + } + PERF_STOP("pbuf_free"); + /* return number of de-allocated pbufs */ + return count; +} + +/** + * Count number of pbufs in a chain + * + * @param p first pbuf of chain + * @return the number of pbufs in a chain + */ + +u8_t +pbuf_clen(struct pbuf *p) +{ + u8_t len; + + len = 0; + while (p != NULL) { + ++len; + p = p->next; + } + return len; +} + +/** + * Increment the reference count of the pbuf. + * + * @param p pbuf to increase reference counter of + * + */ +void +pbuf_ref(struct pbuf *p) +{ + SYS_ARCH_DECL_PROTECT(old_level); + /* pbuf given? */ + if (p != NULL) { + SYS_ARCH_PROTECT(old_level); + ++(p->ref); + SYS_ARCH_UNPROTECT(old_level); + } +} + +/** + * Concatenate two pbufs (each may be a pbuf chain) and take over + * the caller's reference of the tail pbuf. + * + * @note The caller MAY NOT reference the tail pbuf afterwards. + * Use pbuf_chain() for that purpose. + * + * @see pbuf_chain() + */ + +void +pbuf_cat(struct pbuf *h, struct pbuf *t) +{ + struct pbuf *p; + + LWIP_ERROR("(h != NULL) && (t != NULL) (programmer violates API)", + ((h != NULL) && (t != NULL)), return;); + + /* proceed to last pbuf of chain */ + for (p = h; p->next != NULL; p = p->next) { + /* add total length of second chain to all totals of first chain */ + p->tot_len += t->tot_len; + } + /* { p is last pbuf of first h chain, p->next == NULL } */ + LWIP_ASSERT("p->tot_len == p->len (of last pbuf in chain)", p->tot_len == p->len); + LWIP_ASSERT("p->next == NULL", p->next == NULL); + /* add total length of second chain to last pbuf total of first chain */ + p->tot_len += t->tot_len; + /* chain last pbuf of head (p) with first of tail (t) */ + p->next = t; + /* p->next now references t, but the caller will drop its reference to t, + * so netto there is no change to the reference count of t. + */ +} + +/** + * Chain two pbufs (or pbuf chains) together. + * + * The caller MUST call pbuf_free(t) once it has stopped + * using it. Use pbuf_cat() instead if you no longer use t. + * + * @param h head pbuf (chain) + * @param t tail pbuf (chain) + * @note The pbufs MUST belong to the same packet. + * @note MAY NOT be called on a packet queue. + * + * The ->tot_len fields of all pbufs of the head chain are adjusted. + * The ->next field of the last pbuf of the head chain is adjusted. + * The ->ref field of the first pbuf of the tail chain is adjusted. + * + */ +void +pbuf_chain(struct pbuf *h, struct pbuf *t) +{ + pbuf_cat(h, t); + /* t is now referenced by h */ + pbuf_ref(t); + LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_chain: %p references %p\n", (void *)h, (void *)t)); +} + +/** + * Dechains the first pbuf from its succeeding pbufs in the chain. + * + * Makes p->tot_len field equal to p->len. + * @param p pbuf to dechain + * @return remainder of the pbuf chain, or NULL if it was de-allocated. + * @note May not be called on a packet queue. + */ +struct pbuf * +pbuf_dechain(struct pbuf *p) +{ + struct pbuf *q; + u8_t tail_gone = 1; + /* tail */ + q = p->next; + /* pbuf has successor in chain? */ + if (q != NULL) { + /* assert tot_len invariant: (p->tot_len == p->len + (p->next? p->next->tot_len: 0) */ + LWIP_ASSERT("p->tot_len == p->len + q->tot_len", q->tot_len == p->tot_len - p->len); + /* enforce invariant if assertion is disabled */ + q->tot_len = p->tot_len - p->len; + /* decouple pbuf from remainder */ + p->next = NULL; + /* total length of pbuf p is its own length only */ + p->tot_len = p->len; + /* q is no longer referenced by p, free it */ + LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_dechain: unreferencing %p\n", (void *)q)); + tail_gone = pbuf_free(q); + if (tail_gone > 0) { + LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, + ("pbuf_dechain: deallocated %p (as it is no longer referenced)\n", (void *)q)); + } + /* return remaining tail or NULL if deallocated */ + } + /* assert tot_len invariant: (p->tot_len == p->len + (p->next? p->next->tot_len: 0) */ + LWIP_ASSERT("p->tot_len == p->len", p->tot_len == p->len); + return ((tail_gone > 0) ? NULL : q); +} + +/** + * + * Create PBUF_RAM copies of pbufs. + * + * Used to queue packets on behalf of the lwIP stack, such as + * ARP based queueing. + * + * @note You MUST explicitly use p = pbuf_take(p); + * + * @note Only one packet is copied, no packet queue! + * + * @param p_to pbuf destination of the copy + * @param p_from pbuf source of the copy + * + * @return ERR_OK if pbuf was copied + * ERR_ARG if one of the pbufs is NULL or p_to is not big + * enough to hold p_from + */ +err_t +pbuf_copy(struct pbuf *p_to, struct pbuf *p_from) +{ + u16_t offset_to=0, offset_from=0, len; + + LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_copy(%p, %p)\n", + (void*)p_to, (void*)p_from)); + + /* is the target big enough to hold the source? */ + LWIP_ERROR("pbuf_copy: target not big enough to hold source", ((p_to != NULL) && + (p_from != NULL) && (p_to->tot_len >= p_from->tot_len)), return ERR_ARG;); + + /* iterate through pbuf chain */ + do + { + /* copy one part of the original chain */ + if ((p_to->len - offset_to) >= (p_from->len - offset_from)) { + /* complete current p_from fits into current p_to */ + len = p_from->len - offset_from; + } else { + /* current p_from does not fit into current p_to */ + len = p_to->len - offset_to; + } + MEMCPY((u8_t*)p_to->payload + offset_to, (u8_t*)p_from->payload + offset_from, len); + offset_to += len; + offset_from += len; + LWIP_ASSERT("offset_to <= p_to->len", offset_to <= p_to->len); + LWIP_ASSERT("offset_from <= p_from->len", offset_from <= p_from->len); + if (offset_from >= p_from->len) { + /* on to next p_from (if any) */ + offset_from = 0; + p_from = p_from->next; + } + if (offset_to == p_to->len) { + /* on to next p_to (if any) */ + offset_to = 0; + p_to = p_to->next; + LWIP_ERROR("p_to != NULL", (p_to != NULL) || (p_from == NULL) , return ERR_ARG;); + } + + if((p_from != NULL) && (p_from->len == p_from->tot_len)) { + /* don't copy more than one packet! */ + LWIP_ERROR("pbuf_copy() does not allow packet queues!\n", + (p_from->next == NULL), return ERR_VAL;); + } + if((p_to != NULL) && (p_to->len == p_to->tot_len)) { + /* don't copy more than one packet! */ + LWIP_ERROR("pbuf_copy() does not allow packet queues!\n", + (p_to->next == NULL), return ERR_VAL;); + } + } while (p_from); + LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_copy: end of chain reached.\n")); + return ERR_OK; +} + +/** + * Copy (part of) the contents of a packet buffer + * to an application supplied buffer. + * + * @param buf the pbuf from which to copy data + * @param dataptr the application supplied buffer + * @param len length of data to copy (dataptr must be big enough). No more + * than buf->tot_len will be copied, irrespective of len + * @param offset offset into the packet buffer from where to begin copying len bytes + * @return the number of bytes copied, or 0 on failure + */ +u16_t +pbuf_copy_partial(struct pbuf *buf, void *dataptr, u16_t len, u16_t offset) +{ + struct pbuf *p; + u16_t left; + u16_t buf_copy_len; + u16_t copied_total = 0; + + LWIP_ERROR("pbuf_copy_partial: invalid buf", (buf != NULL), return 0;); + LWIP_ERROR("pbuf_copy_partial: invalid dataptr", (dataptr != NULL), return 0;); + + left = 0; + + if((buf == NULL) || (dataptr == NULL)) { + return 0; + } + + /* Note some systems use byte copy if dataptr or one of the pbuf payload pointers are unaligned. */ + for(p = buf; len != 0 && p != NULL; p = p->next) { + if ((offset != 0) && (offset >= p->len)) { + /* don't copy from this buffer -> on to the next */ + offset -= p->len; + } else { + /* copy from this buffer. maybe only partially. */ + buf_copy_len = p->len - offset; + if (buf_copy_len > len) + buf_copy_len = len; + /* copy the necessary parts of the buffer */ + MEMCPY(&((char*)dataptr)[left], &((char*)p->payload)[offset], buf_copy_len); + copied_total += buf_copy_len; + left += buf_copy_len; + len -= buf_copy_len; + offset = 0; + } + } + return copied_total; +} + +/** + * Copy application supplied data into a pbuf. + * This function can only be used to copy the equivalent of buf->tot_len data. + * + * @param buf pbuf to fill with data + * @param dataptr application supplied data buffer + * @param len length of the application supplied data buffer + * + * @return ERR_OK if successful, ERR_MEM if the pbuf is not big enough + */ +err_t +pbuf_take(struct pbuf *buf, const void *dataptr, u16_t len) +{ + struct pbuf *p; + u16_t buf_copy_len; + u16_t total_copy_len = len; + u16_t copied_total = 0; + + LWIP_ERROR("pbuf_take: invalid buf", (buf != NULL), return 0;); + LWIP_ERROR("pbuf_take: invalid dataptr", (dataptr != NULL), return 0;); + + if ((buf == NULL) || (dataptr == NULL) || (buf->tot_len < len)) { + return ERR_ARG; + } + + /* Note some systems use byte copy if dataptr or one of the pbuf payload pointers are unaligned. */ + for(p = buf; total_copy_len != 0; p = p->next) { + LWIP_ASSERT("pbuf_take: invalid pbuf", p != NULL); + buf_copy_len = total_copy_len; + if (buf_copy_len > p->len) { + /* this pbuf cannot hold all remaining data */ + buf_copy_len = p->len; + } + /* copy the necessary parts of the buffer */ + MEMCPY(p->payload, &((char*)dataptr)[copied_total], buf_copy_len); + total_copy_len -= buf_copy_len; + copied_total += buf_copy_len; + } + LWIP_ASSERT("did not copy all data", total_copy_len == 0 && copied_total == len); + return ERR_OK; +} + +/** + * Creates a single pbuf out of a queue of pbufs. + * + * @remark: Either the source pbuf 'p' is freed by this function or the original + * pbuf 'p' is returned, therefore the caller has to check the result! + * + * @param p the source pbuf + * @param layer pbuf_layer of the new pbuf + * + * @return a new, single pbuf (p->next is NULL) + * or the old pbuf if allocation fails + */ +struct pbuf* +pbuf_coalesce(struct pbuf *p, pbuf_layer layer) +{ + struct pbuf *q; + err_t err; + if (p->next == NULL) { + return p; + } + q = pbuf_alloc(layer, p->tot_len, PBUF_RAM); + if (q == NULL) { + /* @todo: what do we do now? */ + return p; + } + err = pbuf_copy(q, p); + LWIP_ASSERT("pbuf_copy failed", err == ERR_OK); + pbuf_free(p); + return q; +} + +#if LWIP_CHECKSUM_ON_COPY +/** + * Copies data into a single pbuf (*not* into a pbuf queue!) and updates + * the checksum while copying + * + * @param p the pbuf to copy data into + * @param start_offset offset of p->payload where to copy the data to + * @param dataptr data to copy into the pbuf + * @param len length of data to copy into the pbuf + * @param chksum pointer to the checksum which is updated + * @return ERR_OK if successful, another error if the data does not fit + * within the (first) pbuf (no pbuf queues!) + */ +err_t +pbuf_fill_chksum(struct pbuf *p, u16_t start_offset, const void *dataptr, + u16_t len, u16_t *chksum) +{ + u32_t acc; + u16_t copy_chksum; + char *dst_ptr; + LWIP_ASSERT("p != NULL", p != NULL); + LWIP_ASSERT("dataptr != NULL", dataptr != NULL); + LWIP_ASSERT("chksum != NULL", chksum != NULL); + LWIP_ASSERT("len != 0", len != 0); + + if ((start_offset >= p->len) || (start_offset + len > p->len)) { + return ERR_ARG; + } + + dst_ptr = ((char*)p->payload) + start_offset; + copy_chksum = LWIP_CHKSUM_COPY(dst_ptr, dataptr, len); + if ((start_offset & 1) != 0) { + copy_chksum = SWAP_BYTES_IN_WORD(copy_chksum); + } + acc = *chksum; + acc += copy_chksum; + *chksum = FOLD_U32T(acc); + return ERR_OK; +} +#endif /* LWIP_CHECKSUM_ON_COPY */ + + /** Get one byte from the specified position in a pbuf + * WARNING: returns zero for offset >= p->tot_len + * + * @param p pbuf to parse + * @param offset offset into p of the byte to return + * @return byte at an offset into p OR ZERO IF 'offset' >= p->tot_len + */ +u8_t +pbuf_get_at(struct pbuf* p, u16_t offset) +{ + u16_t copy_from = offset; + struct pbuf* q = p; + + /* get the correct pbuf */ + while ((q != NULL) && (q->len <= copy_from)) { + copy_from -= q->len; + q = q->next; + } + /* return requested data if pbuf is OK */ + if ((q != NULL) && (q->len > copy_from)) { + return ((u8_t*)q->payload)[copy_from]; + } + return 0; +} + +/** Compare pbuf contents at specified offset with memory s2, both of length n + * + * @param p pbuf to compare + * @param offset offset into p at wich to start comparing + * @param s2 buffer to compare + * @param n length of buffer to compare + * @return zero if equal, nonzero otherwise + * (0xffff if p is too short, diffoffset+1 otherwise) + */ +u16_t +pbuf_memcmp(struct pbuf* p, u16_t offset, const void* s2, u16_t n) +{ + u16_t start = offset; + struct pbuf* q = p; + + /* get the correct pbuf */ + while ((q != NULL) && (q->len <= start)) { + start -= q->len; + q = q->next; + } + /* return requested data if pbuf is OK */ + if ((q != NULL) && (q->len > start)) { + u16_t i; + for(i = 0; i < n; i++) { + u8_t a = pbuf_get_at(q, start + i); + u8_t b = ((u8_t*)s2)[i]; + if (a != b) { + return i+1; + } + } + return 0; + } + return 0xffff; +} + +/** Find occurrence of mem (with length mem_len) in pbuf p, starting at offset + * start_offset. + * + * @param p pbuf to search, maximum length is 0xFFFE since 0xFFFF is used as + * return value 'not found' + * @param mem search for the contents of this buffer + * @param mem_len length of 'mem' + * @param start_offset offset into p at which to start searching + * @return 0xFFFF if substr was not found in p or the index where it was found + */ +u16_t +pbuf_memfind(struct pbuf* p, const void* mem, u16_t mem_len, u16_t start_offset) +{ + u16_t i; + u16_t max = p->tot_len - mem_len; + if (p->tot_len >= mem_len + start_offset) { + for(i = start_offset; i <= max; ) { + u16_t plus = pbuf_memcmp(p, i, mem, mem_len); + if (plus == 0) { + return i; + } else { + i += plus; + } + } + } + return 0xFFFF; +} + +/** Find occurrence of substr with length substr_len in pbuf p, start at offset + * start_offset + * WARNING: in contrast to strstr(), this one does not stop at the first \0 in + * the pbuf/source string! + * + * @param p pbuf to search, maximum length is 0xFFFE since 0xFFFF is used as + * return value 'not found' + * @param substr string to search for in p, maximum length is 0xFFFE + * @return 0xFFFF if substr was not found in p or the index where it was found + */ +u16_t +pbuf_strstr(struct pbuf* p, const char* substr) +{ + size_t substr_len; + if ((substr == NULL) || (substr[0] == 0) || (p->tot_len == 0xFFFF)) { + return 0xFFFF; + } + substr_len = strlen(substr); + if (substr_len >= 0xFFFF) { + return 0xFFFF; + } + return pbuf_memfind(p, substr, (u16_t)substr_len, 0); +} diff --git a/src/lwip-1.4.1/src/core/raw.c b/src/lwip-1.4.1/src/core/raw.c new file mode 100644 index 0000000..7160c0f --- /dev/null +++ b/src/lwip-1.4.1/src/core/raw.c @@ -0,0 +1,350 @@ +/** + * @file + * Implementation of raw protocol PCBs for low-level handling of + * different types of protocols besides (or overriding) those + * already available in lwIP. + * + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#include "lwip/opt.h" + +#if LWIP_RAW /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/def.h" +#include "lwip/memp.h" +#include "lwip/ip_addr.h" +#include "lwip/netif.h" +#include "lwip/raw.h" +#include "lwip/stats.h" +#include "arch/perf.h" + +#include + +/** The list of RAW PCBs */ +static struct raw_pcb *raw_pcbs; + +/** + * Determine if in incoming IP packet is covered by a RAW PCB + * and if so, pass it to a user-provided receive callback function. + * + * Given an incoming IP datagram (as a chain of pbufs) this function + * finds a corresponding RAW PCB and calls the corresponding receive + * callback function. + * + * @param p pbuf to be demultiplexed to a RAW PCB. + * @param inp network interface on which the datagram was received. + * @return - 1 if the packet has been eaten by a RAW PCB receive + * callback function. The caller MAY NOT not reference the + * packet any longer, and MAY NOT call pbuf_free(). + * @return - 0 if packet is not eaten (pbuf is still referenced by the + * caller). + * + */ +u8_t +raw_input(struct pbuf *p, struct netif *inp) +{ + struct raw_pcb *pcb, *prev; + struct ip_hdr *iphdr; + s16_t proto; + u8_t eaten = 0; + + LWIP_UNUSED_ARG(inp); + + iphdr = (struct ip_hdr *)p->payload; + proto = IPH_PROTO(iphdr); + + prev = NULL; + pcb = raw_pcbs; + /* loop through all raw pcbs until the packet is eaten by one */ + /* this allows multiple pcbs to match against the packet by design */ + while ((eaten == 0) && (pcb != NULL)) { + if ((pcb->protocol == proto) && + (ip_addr_isany(&pcb->local_ip) || + ip_addr_cmp(&(pcb->local_ip), ¤t_iphdr_dest))) { +#if IP_SOF_BROADCAST_RECV + /* broadcast filter? */ + if (ip_get_option(pcb, SOF_BROADCAST) || !ip_addr_isbroadcast(¤t_iphdr_dest, inp)) +#endif /* IP_SOF_BROADCAST_RECV */ + { + /* receive callback function available? */ + if (pcb->recv != NULL) { + /* the receive callback function did not eat the packet? */ + if (pcb->recv(pcb->recv_arg, pcb, p, ip_current_src_addr()) != 0) { + /* receive function ate the packet */ + p = NULL; + eaten = 1; + if (prev != NULL) { + /* move the pcb to the front of raw_pcbs so that is + found faster next time */ + prev->next = pcb->next; + pcb->next = raw_pcbs; + raw_pcbs = pcb; + } + } + } + /* no receive callback function was set for this raw PCB */ + } + /* drop the packet */ + } + prev = pcb; + pcb = pcb->next; + } + return eaten; +} + +/** + * Bind a RAW PCB. + * + * @param pcb RAW PCB to be bound with a local address ipaddr. + * @param ipaddr local IP address to bind with. Use IP_ADDR_ANY to + * bind to all local interfaces. + * + * @return lwIP error code. + * - ERR_OK. Successful. No error occured. + * - ERR_USE. The specified IP address is already bound to by + * another RAW PCB. + * + * @see raw_disconnect() + */ +err_t +raw_bind(struct raw_pcb *pcb, ip_addr_t *ipaddr) +{ + ip_addr_set(&pcb->local_ip, ipaddr); + return ERR_OK; +} + +/** + * Connect an RAW PCB. This function is required by upper layers + * of lwip. Using the raw api you could use raw_sendto() instead + * + * This will associate the RAW PCB with the remote address. + * + * @param pcb RAW PCB to be connected with remote address ipaddr and port. + * @param ipaddr remote IP address to connect with. + * + * @return lwIP error code + * + * @see raw_disconnect() and raw_sendto() + */ +err_t +raw_connect(struct raw_pcb *pcb, ip_addr_t *ipaddr) +{ + ip_addr_set(&pcb->remote_ip, ipaddr); + return ERR_OK; +} + + +/** + * Set the callback function for received packets that match the + * raw PCB's protocol and binding. + * + * The callback function MUST either + * - eat the packet by calling pbuf_free() and returning non-zero. The + * packet will not be passed to other raw PCBs or other protocol layers. + * - not free the packet, and return zero. The packet will be matched + * against further PCBs and/or forwarded to another protocol layers. + * + * @return non-zero if the packet was free()d, zero if the packet remains + * available for others. + */ +void +raw_recv(struct raw_pcb *pcb, raw_recv_fn recv, void *recv_arg) +{ + /* remember recv() callback and user data */ + pcb->recv = recv; + pcb->recv_arg = recv_arg; +} + +/** + * Send the raw IP packet to the given address. Note that actually you cannot + * modify the IP headers (this is inconsistent with the receive callback where + * you actually get the IP headers), you can only specify the IP payload here. + * It requires some more changes in lwIP. (there will be a raw_send() function + * then.) + * + * @param pcb the raw pcb which to send + * @param p the IP payload to send + * @param ipaddr the destination address of the IP packet + * + */ +err_t +raw_sendto(struct raw_pcb *pcb, struct pbuf *p, ip_addr_t *ipaddr) +{ + err_t err; + struct netif *netif; + ip_addr_t *src_ip; + struct pbuf *q; /* q will be sent down the stack */ + + LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_TRACE, ("raw_sendto\n")); + + /* not enough space to add an IP header to first pbuf in given p chain? */ + if (pbuf_header(p, IP_HLEN)) { + /* allocate header in new pbuf */ + q = pbuf_alloc(PBUF_IP, 0, PBUF_RAM); + /* new header pbuf could not be allocated? */ + if (q == NULL) { + LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("raw_sendto: could not allocate header\n")); + return ERR_MEM; + } + if (p->tot_len != 0) { + /* chain header q in front of given pbuf p */ + pbuf_chain(q, p); + } + /* { first pbuf q points to header pbuf } */ + LWIP_DEBUGF(RAW_DEBUG, ("raw_sendto: added header pbuf %p before given pbuf %p\n", (void *)q, (void *)p)); + } else { + /* first pbuf q equals given pbuf */ + q = p; + if(pbuf_header(q, -IP_HLEN)) { + LWIP_ASSERT("Can't restore header we just removed!", 0); + return ERR_MEM; + } + } + + if ((netif = ip_route(ipaddr)) == NULL) { + LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_LEVEL_WARNING, ("raw_sendto: No route to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", + ip4_addr1_16(ipaddr), ip4_addr2_16(ipaddr), ip4_addr3_16(ipaddr), ip4_addr4_16(ipaddr))); + /* free any temporary header pbuf allocated by pbuf_header() */ + if (q != p) { + pbuf_free(q); + } + return ERR_RTE; + } + +#if IP_SOF_BROADCAST + /* broadcast filter? */ + if (!ip_get_option(pcb, SOF_BROADCAST) && ip_addr_isbroadcast(ipaddr, netif)) { + LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_LEVEL_WARNING, ("raw_sendto: SOF_BROADCAST not enabled on pcb %p\n", (void *)pcb)); + /* free any temporary header pbuf allocated by pbuf_header() */ + if (q != p) { + pbuf_free(q); + } + return ERR_VAL; + } +#endif /* IP_SOF_BROADCAST */ + + if (ip_addr_isany(&pcb->local_ip)) { + /* use outgoing network interface IP address as source address */ + src_ip = &(netif->ip_addr); + } else { + /* use RAW PCB local IP address as source address */ + src_ip = &(pcb->local_ip); + } + + NETIF_SET_HWADDRHINT(netif, &pcb->addr_hint); + err = ip_output_if (q, src_ip, ipaddr, pcb->ttl, pcb->tos, pcb->protocol, netif); + NETIF_SET_HWADDRHINT(netif, NULL); + + /* did we chain a header earlier? */ + if (q != p) { + /* free the header */ + pbuf_free(q); + } + return err; +} + +/** + * Send the raw IP packet to the address given by raw_connect() + * + * @param pcb the raw pcb which to send + * @param p the IP payload to send + * + */ +err_t +raw_send(struct raw_pcb *pcb, struct pbuf *p) +{ + return raw_sendto(pcb, p, &pcb->remote_ip); +} + +/** + * Remove an RAW PCB. + * + * @param pcb RAW PCB to be removed. The PCB is removed from the list of + * RAW PCB's and the data structure is freed from memory. + * + * @see raw_new() + */ +void +raw_remove(struct raw_pcb *pcb) +{ + struct raw_pcb *pcb2; + /* pcb to be removed is first in list? */ + if (raw_pcbs == pcb) { + /* make list start at 2nd pcb */ + raw_pcbs = raw_pcbs->next; + /* pcb not 1st in list */ + } else { + for(pcb2 = raw_pcbs; pcb2 != NULL; pcb2 = pcb2->next) { + /* find pcb in raw_pcbs list */ + if (pcb2->next != NULL && pcb2->next == pcb) { + /* remove pcb from list */ + pcb2->next = pcb->next; + } + } + } + memp_free(MEMP_RAW_PCB, pcb); +} + +/** + * Create a RAW PCB. + * + * @return The RAW PCB which was created. NULL if the PCB data structure + * could not be allocated. + * + * @param proto the protocol number of the IPs payload (e.g. IP_PROTO_ICMP) + * + * @see raw_remove() + */ +struct raw_pcb * +raw_new(u8_t proto) +{ + struct raw_pcb *pcb; + + LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_TRACE, ("raw_new\n")); + + pcb = (struct raw_pcb *)memp_malloc(MEMP_RAW_PCB); + /* could allocate RAW PCB? */ + if (pcb != NULL) { + /* initialize PCB to all zeroes */ + memset(pcb, 0, sizeof(struct raw_pcb)); + pcb->protocol = proto; + pcb->ttl = RAW_TTL; + pcb->next = raw_pcbs; + raw_pcbs = pcb; + } + return pcb; +} + +#endif /* LWIP_RAW */ diff --git a/src/lwip-1.4.1/src/core/snmp/asn1_dec.c b/src/lwip-1.4.1/src/core/snmp/asn1_dec.c new file mode 100644 index 0000000..1d56582 --- /dev/null +++ b/src/lwip-1.4.1/src/core/snmp/asn1_dec.c @@ -0,0 +1,657 @@ +/** + * @file + * Abstract Syntax Notation One (ISO 8824, 8825) decoding + * + * @todo not optimised (yet), favor correctness over speed, favor speed over size + */ + +/* + * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * Author: Christiaan Simons + */ + +#include "lwip/opt.h" + +#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/snmp_asn1.h" + +/** + * Retrieves type field from incoming pbuf chain. + * + * @param p points to a pbuf holding an ASN1 coded type field + * @param ofs points to the offset within the pbuf chain of the ASN1 coded type field + * @param type return ASN1 type + * @return ERR_OK if successfull, ERR_ARG if we can't (or won't) decode + */ +err_t +snmp_asn1_dec_type(struct pbuf *p, u16_t ofs, u8_t *type) +{ + u16_t plen, base; + u8_t *msg_ptr; + + plen = 0; + while (p != NULL) + { + base = plen; + plen += p->len; + if (ofs < plen) + { + msg_ptr = (u8_t*)p->payload; + msg_ptr += ofs - base; + *type = *msg_ptr; + return ERR_OK; + } + p = p->next; + } + /* p == NULL, ofs >= plen */ + return ERR_ARG; +} + +/** + * Decodes length field from incoming pbuf chain into host length. + * + * @param p points to a pbuf holding an ASN1 coded length + * @param ofs points to the offset within the pbuf chain of the ASN1 coded length + * @param octets_used returns number of octets used by the length code + * @param length return host order length, upto 64k + * @return ERR_OK if successfull, ERR_ARG if we can't (or won't) decode + */ +err_t +snmp_asn1_dec_length(struct pbuf *p, u16_t ofs, u8_t *octets_used, u16_t *length) +{ + u16_t plen, base; + u8_t *msg_ptr; + + plen = 0; + while (p != NULL) + { + base = plen; + plen += p->len; + if (ofs < plen) + { + msg_ptr = (u8_t*)p->payload; + msg_ptr += ofs - base; + + if (*msg_ptr < 0x80) + { + /* primitive definite length format */ + *octets_used = 1; + *length = *msg_ptr; + return ERR_OK; + } + else if (*msg_ptr == 0x80) + { + /* constructed indefinite length format, termination with two zero octets */ + u8_t zeros; + u8_t i; + + *length = 0; + zeros = 0; + while (zeros != 2) + { + i = 2; + while (i > 0) + { + i--; + (*length) += 1; + ofs += 1; + if (ofs >= plen) + { + /* next octet in next pbuf */ + p = p->next; + if (p == NULL) { return ERR_ARG; } + msg_ptr = (u8_t*)p->payload; + plen += p->len; + } + else + { + /* next octet in same pbuf */ + msg_ptr++; + } + if (*msg_ptr == 0) + { + zeros++; + if (zeros == 2) + { + /* stop while (i > 0) */ + i = 0; + } + } + else + { + zeros = 0; + } + } + } + *octets_used = 1; + return ERR_OK; + } + else if (*msg_ptr == 0x81) + { + /* constructed definite length format, one octet */ + ofs += 1; + if (ofs >= plen) + { + /* next octet in next pbuf */ + p = p->next; + if (p == NULL) { return ERR_ARG; } + msg_ptr = (u8_t*)p->payload; + } + else + { + /* next octet in same pbuf */ + msg_ptr++; + } + *length = *msg_ptr; + *octets_used = 2; + return ERR_OK; + } + else if (*msg_ptr == 0x82) + { + u8_t i; + + /* constructed definite length format, two octets */ + i = 2; + while (i > 0) + { + i--; + ofs += 1; + if (ofs >= plen) + { + /* next octet in next pbuf */ + p = p->next; + if (p == NULL) { return ERR_ARG; } + msg_ptr = (u8_t*)p->payload; + plen += p->len; + } + else + { + /* next octet in same pbuf */ + msg_ptr++; + } + if (i == 0) + { + /* least significant length octet */ + *length |= *msg_ptr; + } + else + { + /* most significant length octet */ + *length = (*msg_ptr) << 8; + } + } + *octets_used = 3; + return ERR_OK; + } + else + { + /* constructed definite length format 3..127 octets, this is too big (>64k) */ + /** @todo: do we need to accept inefficient codings with many leading zero's? */ + *octets_used = 1 + ((*msg_ptr) & 0x7f); + return ERR_ARG; + } + } + p = p->next; + } + + /* p == NULL, ofs >= plen */ + return ERR_ARG; +} + +/** + * Decodes positive integer (counter, gauge, timeticks) into u32_t. + * + * @param p points to a pbuf holding an ASN1 coded integer + * @param ofs points to the offset within the pbuf chain of the ASN1 coded integer + * @param len length of the coded integer field + * @param value return host order integer + * @return ERR_OK if successfull, ERR_ARG if we can't (or won't) decode + * + * @note ASN coded integers are _always_ signed. E.g. +0xFFFF is coded + * as 0x00,0xFF,0xFF. Note the leading sign octet. A positive value + * of 0xFFFFFFFF is preceded with 0x00 and the length is 5 octets!! + */ +err_t +snmp_asn1_dec_u32t(struct pbuf *p, u16_t ofs, u16_t len, u32_t *value) +{ + u16_t plen, base; + u8_t *msg_ptr; + + plen = 0; + while (p != NULL) + { + base = plen; + plen += p->len; + if (ofs < plen) + { + msg_ptr = (u8_t*)p->payload; + msg_ptr += ofs - base; + if ((len > 0) && (len < 6)) + { + /* start from zero */ + *value = 0; + if (*msg_ptr & 0x80) + { + /* negative, expecting zero sign bit! */ + return ERR_ARG; + } + else + { + /* positive */ + if ((len > 1) && (*msg_ptr == 0)) + { + /* skip leading "sign byte" octet 0x00 */ + len--; + ofs += 1; + if (ofs >= plen) + { + /* next octet in next pbuf */ + p = p->next; + if (p == NULL) { return ERR_ARG; } + msg_ptr = (u8_t*)p->payload; + plen += p->len; + } + else + { + /* next octet in same pbuf */ + msg_ptr++; + } + } + } + /* OR octets with value */ + while (len > 1) + { + len--; + *value |= *msg_ptr; + *value <<= 8; + ofs += 1; + if (ofs >= plen) + { + /* next octet in next pbuf */ + p = p->next; + if (p == NULL) { return ERR_ARG; } + msg_ptr = (u8_t*)p->payload; + plen += p->len; + } + else + { + /* next octet in same pbuf */ + msg_ptr++; + } + } + *value |= *msg_ptr; + return ERR_OK; + } + else + { + return ERR_ARG; + } + } + p = p->next; + } + /* p == NULL, ofs >= plen */ + return ERR_ARG; +} + +/** + * Decodes integer into s32_t. + * + * @param p points to a pbuf holding an ASN1 coded integer + * @param ofs points to the offset within the pbuf chain of the ASN1 coded integer + * @param len length of the coded integer field + * @param value return host order integer + * @return ERR_OK if successfull, ERR_ARG if we can't (or won't) decode + * + * @note ASN coded integers are _always_ signed! + */ +err_t +snmp_asn1_dec_s32t(struct pbuf *p, u16_t ofs, u16_t len, s32_t *value) +{ + u16_t plen, base; + u8_t *msg_ptr; +#if BYTE_ORDER == LITTLE_ENDIAN + u8_t *lsb_ptr = (u8_t*)value; +#endif +#if BYTE_ORDER == BIG_ENDIAN + u8_t *lsb_ptr = (u8_t*)value + sizeof(s32_t) - 1; +#endif + u8_t sign; + + plen = 0; + while (p != NULL) + { + base = plen; + plen += p->len; + if (ofs < plen) + { + msg_ptr = (u8_t*)p->payload; + msg_ptr += ofs - base; + if ((len > 0) && (len < 5)) + { + if (*msg_ptr & 0x80) + { + /* negative, start from -1 */ + *value = -1; + sign = 1; + } + else + { + /* positive, start from 0 */ + *value = 0; + sign = 0; + } + /* OR/AND octets with value */ + while (len > 1) + { + len--; + if (sign) + { + *lsb_ptr &= *msg_ptr; + *value <<= 8; + *lsb_ptr |= 255; + } + else + { + *lsb_ptr |= *msg_ptr; + *value <<= 8; + } + ofs += 1; + if (ofs >= plen) + { + /* next octet in next pbuf */ + p = p->next; + if (p == NULL) { return ERR_ARG; } + msg_ptr = (u8_t*)p->payload; + plen += p->len; + } + else + { + /* next octet in same pbuf */ + msg_ptr++; + } + } + if (sign) + { + *lsb_ptr &= *msg_ptr; + } + else + { + *lsb_ptr |= *msg_ptr; + } + return ERR_OK; + } + else + { + return ERR_ARG; + } + } + p = p->next; + } + /* p == NULL, ofs >= plen */ + return ERR_ARG; +} + +/** + * Decodes object identifier from incoming message into array of s32_t. + * + * @param p points to a pbuf holding an ASN1 coded object identifier + * @param ofs points to the offset within the pbuf chain of the ASN1 coded object identifier + * @param len length of the coded object identifier + * @param oid return object identifier struct + * @return ERR_OK if successfull, ERR_ARG if we can't (or won't) decode + */ +err_t +snmp_asn1_dec_oid(struct pbuf *p, u16_t ofs, u16_t len, struct snmp_obj_id *oid) +{ + u16_t plen, base; + u8_t *msg_ptr; + s32_t *oid_ptr; + + plen = 0; + while (p != NULL) + { + base = plen; + plen += p->len; + if (ofs < plen) + { + msg_ptr = (u8_t*)p->payload; + msg_ptr += ofs - base; + + oid->len = 0; + oid_ptr = &oid->id[0]; + if (len > 0) + { + /* first compressed octet */ + if (*msg_ptr == 0x2B) + { + /* (most) common case 1.3 (iso.org) */ + *oid_ptr = 1; + oid_ptr++; + *oid_ptr = 3; + oid_ptr++; + } + else if (*msg_ptr < 40) + { + *oid_ptr = 0; + oid_ptr++; + *oid_ptr = *msg_ptr; + oid_ptr++; + } + else if (*msg_ptr < 80) + { + *oid_ptr = 1; + oid_ptr++; + *oid_ptr = (*msg_ptr) - 40; + oid_ptr++; + } + else + { + *oid_ptr = 2; + oid_ptr++; + *oid_ptr = (*msg_ptr) - 80; + oid_ptr++; + } + oid->len = 2; + } + else + { + /* accepting zero length identifiers e.g. for + getnext operation. uncommon but valid */ + return ERR_OK; + } + len--; + if (len > 0) + { + ofs += 1; + if (ofs >= plen) + { + /* next octet in next pbuf */ + p = p->next; + if (p == NULL) { return ERR_ARG; } + msg_ptr = (u8_t*)p->payload; + plen += p->len; + } + else + { + /* next octet in same pbuf */ + msg_ptr++; + } + } + while ((len > 0) && (oid->len < LWIP_SNMP_OBJ_ID_LEN)) + { + /* sub-identifier uses multiple octets */ + if (*msg_ptr & 0x80) + { + s32_t sub_id = 0; + + while ((*msg_ptr & 0x80) && (len > 1)) + { + len--; + sub_id = (sub_id << 7) + (*msg_ptr & ~0x80); + ofs += 1; + if (ofs >= plen) + { + /* next octet in next pbuf */ + p = p->next; + if (p == NULL) { return ERR_ARG; } + msg_ptr = (u8_t*)p->payload; + plen += p->len; + } + else + { + /* next octet in same pbuf */ + msg_ptr++; + } + } + if (!(*msg_ptr & 0x80) && (len > 0)) + { + /* last octet sub-identifier */ + len--; + sub_id = (sub_id << 7) + *msg_ptr; + *oid_ptr = sub_id; + } + } + else + { + /* !(*msg_ptr & 0x80) sub-identifier uses single octet */ + len--; + *oid_ptr = *msg_ptr; + } + if (len > 0) + { + /* remaining oid bytes available ... */ + ofs += 1; + if (ofs >= plen) + { + /* next octet in next pbuf */ + p = p->next; + if (p == NULL) { return ERR_ARG; } + msg_ptr = (u8_t*)p->payload; + plen += p->len; + } + else + { + /* next octet in same pbuf */ + msg_ptr++; + } + } + oid_ptr++; + oid->len++; + } + if (len == 0) + { + /* len == 0, end of oid */ + return ERR_OK; + } + else + { + /* len > 0, oid->len == LWIP_SNMP_OBJ_ID_LEN or malformed encoding */ + return ERR_ARG; + } + + } + p = p->next; + } + /* p == NULL, ofs >= plen */ + return ERR_ARG; +} + +/** + * Decodes (copies) raw data (ip-addresses, octet strings, opaque encoding) + * from incoming message into array. + * + * @param p points to a pbuf holding an ASN1 coded raw data + * @param ofs points to the offset within the pbuf chain of the ASN1 coded raw data + * @param len length of the coded raw data (zero is valid, e.g. empty string!) + * @param raw_len length of the raw return value + * @param raw return raw bytes + * @return ERR_OK if successfull, ERR_ARG if we can't (or won't) decode + */ +err_t +snmp_asn1_dec_raw(struct pbuf *p, u16_t ofs, u16_t len, u16_t raw_len, u8_t *raw) +{ + u16_t plen, base; + u8_t *msg_ptr; + + if (len > 0) + { + plen = 0; + while (p != NULL) + { + base = plen; + plen += p->len; + if (ofs < plen) + { + msg_ptr = (u8_t*)p->payload; + msg_ptr += ofs - base; + if (raw_len >= len) + { + while (len > 1) + { + /* copy len - 1 octets */ + len--; + *raw = *msg_ptr; + raw++; + ofs += 1; + if (ofs >= plen) + { + /* next octet in next pbuf */ + p = p->next; + if (p == NULL) { return ERR_ARG; } + msg_ptr = (u8_t*)p->payload; + plen += p->len; + } + else + { + /* next octet in same pbuf */ + msg_ptr++; + } + } + /* copy last octet */ + *raw = *msg_ptr; + return ERR_OK; + } + else + { + /* raw_len < len, not enough dst space */ + return ERR_ARG; + } + } + p = p->next; + } + /* p == NULL, ofs >= plen */ + return ERR_ARG; + } + else + { + /* len == 0, empty string */ + return ERR_OK; + } +} + +#endif /* LWIP_SNMP */ diff --git a/src/lwip-1.4.1/src/core/snmp/asn1_enc.c b/src/lwip-1.4.1/src/core/snmp/asn1_enc.c new file mode 100644 index 0000000..64dfc5f --- /dev/null +++ b/src/lwip-1.4.1/src/core/snmp/asn1_enc.c @@ -0,0 +1,611 @@ +/** + * @file + * Abstract Syntax Notation One (ISO 8824, 8825) encoding + * + * @todo not optimised (yet), favor correctness over speed, favor speed over size + */ + +/* + * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * Author: Christiaan Simons + */ + +#include "lwip/opt.h" + +#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/snmp_asn1.h" + +/** + * Returns octet count for length. + * + * @param length + * @param octets_needed points to the return value + */ +void +snmp_asn1_enc_length_cnt(u16_t length, u8_t *octets_needed) +{ + if (length < 0x80U) + { + *octets_needed = 1; + } + else if (length < 0x100U) + { + *octets_needed = 2; + } + else + { + *octets_needed = 3; + } +} + +/** + * Returns octet count for an u32_t. + * + * @param value + * @param octets_needed points to the return value + * + * @note ASN coded integers are _always_ signed. E.g. +0xFFFF is coded + * as 0x00,0xFF,0xFF. Note the leading sign octet. A positive value + * of 0xFFFFFFFF is preceded with 0x00 and the length is 5 octets!! + */ +void +snmp_asn1_enc_u32t_cnt(u32_t value, u16_t *octets_needed) +{ + if (value < 0x80UL) + { + *octets_needed = 1; + } + else if (value < 0x8000UL) + { + *octets_needed = 2; + } + else if (value < 0x800000UL) + { + *octets_needed = 3; + } + else if (value < 0x80000000UL) + { + *octets_needed = 4; + } + else + { + *octets_needed = 5; + } +} + +/** + * Returns octet count for an s32_t. + * + * @param value + * @param octets_needed points to the return value + * + * @note ASN coded integers are _always_ signed. + */ +void +snmp_asn1_enc_s32t_cnt(s32_t value, u16_t *octets_needed) +{ + if (value < 0) + { + value = ~value; + } + if (value < 0x80L) + { + *octets_needed = 1; + } + else if (value < 0x8000L) + { + *octets_needed = 2; + } + else if (value < 0x800000L) + { + *octets_needed = 3; + } + else + { + *octets_needed = 4; + } +} + +/** + * Returns octet count for an object identifier. + * + * @param ident_len object identifier array length + * @param ident points to object identifier array + * @param octets_needed points to the return value + */ +void +snmp_asn1_enc_oid_cnt(u8_t ident_len, s32_t *ident, u16_t *octets_needed) +{ + s32_t sub_id; + u8_t cnt; + + cnt = 0; + if (ident_len > 1) + { + /* compressed prefix in one octet */ + cnt++; + ident_len -= 2; + ident += 2; + } + while(ident_len > 0) + { + ident_len--; + sub_id = *ident; + + sub_id >>= 7; + cnt++; + while(sub_id > 0) + { + sub_id >>= 7; + cnt++; + } + ident++; + } + *octets_needed = cnt; +} + +/** + * Encodes ASN type field into a pbuf chained ASN1 msg. + * + * @param p points to output pbuf to encode value into + * @param ofs points to the offset within the pbuf chain + * @param type input ASN1 type + * @return ERR_OK if successfull, ERR_ARG if we can't (or won't) encode + */ +err_t +snmp_asn1_enc_type(struct pbuf *p, u16_t ofs, u8_t type) +{ + u16_t plen, base; + u8_t *msg_ptr; + + plen = 0; + while (p != NULL) + { + base = plen; + plen += p->len; + if (ofs < plen) + { + msg_ptr = (u8_t*)p->payload; + msg_ptr += ofs - base; + *msg_ptr = type; + return ERR_OK; + } + p = p->next; + } + /* p == NULL, ofs >= plen */ + return ERR_ARG; +} + +/** + * Encodes host order length field into a pbuf chained ASN1 msg. + * + * @param p points to output pbuf to encode length into + * @param ofs points to the offset within the pbuf chain + * @param length is the host order length to be encoded + * @return ERR_OK if successfull, ERR_ARG if we can't (or won't) encode + */ +err_t +snmp_asn1_enc_length(struct pbuf *p, u16_t ofs, u16_t length) +{ + u16_t plen, base; + u8_t *msg_ptr; + + plen = 0; + while (p != NULL) + { + base = plen; + plen += p->len; + if (ofs < plen) + { + msg_ptr = (u8_t*)p->payload; + msg_ptr += ofs - base; + + if (length < 0x80) + { + *msg_ptr = (u8_t)length; + return ERR_OK; + } + else if (length < 0x100) + { + *msg_ptr = 0x81; + ofs += 1; + if (ofs >= plen) + { + /* next octet in next pbuf */ + p = p->next; + if (p == NULL) { return ERR_ARG; } + msg_ptr = (u8_t*)p->payload; + } + else + { + /* next octet in same pbuf */ + msg_ptr++; + } + *msg_ptr = (u8_t)length; + return ERR_OK; + } + else + { + u8_t i; + + /* length >= 0x100 && length <= 0xFFFF */ + *msg_ptr = 0x82; + i = 2; + while (i > 0) + { + i--; + ofs += 1; + if (ofs >= plen) + { + /* next octet in next pbuf */ + p = p->next; + if (p == NULL) { return ERR_ARG; } + msg_ptr = (u8_t*)p->payload; + plen += p->len; + } + else + { + /* next octet in same pbuf */ + msg_ptr++; + } + if (i == 0) + { + /* least significant length octet */ + *msg_ptr = (u8_t)length; + } + else + { + /* most significant length octet */ + *msg_ptr = (u8_t)(length >> 8); + } + } + return ERR_OK; + } + } + p = p->next; + } + /* p == NULL, ofs >= plen */ + return ERR_ARG; +} + +/** + * Encodes u32_t (counter, gauge, timeticks) into a pbuf chained ASN1 msg. + * + * @param p points to output pbuf to encode value into + * @param ofs points to the offset within the pbuf chain + * @param octets_needed encoding length (from snmp_asn1_enc_u32t_cnt()) + * @param value is the host order u32_t value to be encoded + * @return ERR_OK if successfull, ERR_ARG if we can't (or won't) encode + * + * @see snmp_asn1_enc_u32t_cnt() + */ +err_t +snmp_asn1_enc_u32t(struct pbuf *p, u16_t ofs, u16_t octets_needed, u32_t value) +{ + u16_t plen, base; + u8_t *msg_ptr; + + plen = 0; + while (p != NULL) + { + base = plen; + plen += p->len; + if (ofs < plen) + { + msg_ptr = (u8_t*)p->payload; + msg_ptr += ofs - base; + + if (octets_needed == 5) + { + /* not enough bits in 'value' add leading 0x00 */ + octets_needed--; + *msg_ptr = 0x00; + ofs += 1; + if (ofs >= plen) + { + /* next octet in next pbuf */ + p = p->next; + if (p == NULL) { return ERR_ARG; } + msg_ptr = (u8_t*)p->payload; + plen += p->len; + } + else + { + /* next octet in same pbuf */ + msg_ptr++; + } + } + while (octets_needed > 1) + { + octets_needed--; + *msg_ptr = (u8_t)(value >> (octets_needed << 3)); + ofs += 1; + if (ofs >= plen) + { + /* next octet in next pbuf */ + p = p->next; + if (p == NULL) { return ERR_ARG; } + msg_ptr = (u8_t*)p->payload; + plen += p->len; + } + else + { + /* next octet in same pbuf */ + msg_ptr++; + } + } + /* (only) one least significant octet */ + *msg_ptr = (u8_t)value; + return ERR_OK; + } + p = p->next; + } + /* p == NULL, ofs >= plen */ + return ERR_ARG; +} + +/** + * Encodes s32_t integer into a pbuf chained ASN1 msg. + * + * @param p points to output pbuf to encode value into + * @param ofs points to the offset within the pbuf chain + * @param octets_needed encoding length (from snmp_asn1_enc_s32t_cnt()) + * @param value is the host order s32_t value to be encoded + * @return ERR_OK if successfull, ERR_ARG if we can't (or won't) encode + * + * @see snmp_asn1_enc_s32t_cnt() + */ +err_t +snmp_asn1_enc_s32t(struct pbuf *p, u16_t ofs, u16_t octets_needed, s32_t value) +{ + u16_t plen, base; + u8_t *msg_ptr; + + plen = 0; + while (p != NULL) + { + base = plen; + plen += p->len; + if (ofs < plen) + { + msg_ptr = (u8_t*)p->payload; + msg_ptr += ofs - base; + + while (octets_needed > 1) + { + octets_needed--; + *msg_ptr = (u8_t)(value >> (octets_needed << 3)); + ofs += 1; + if (ofs >= plen) + { + /* next octet in next pbuf */ + p = p->next; + if (p == NULL) { return ERR_ARG; } + msg_ptr = (u8_t*)p->payload; + plen += p->len; + } + else + { + /* next octet in same pbuf */ + msg_ptr++; + } + } + /* (only) one least significant octet */ + *msg_ptr = (u8_t)value; + return ERR_OK; + } + p = p->next; + } + /* p == NULL, ofs >= plen */ + return ERR_ARG; +} + +/** + * Encodes object identifier into a pbuf chained ASN1 msg. + * + * @param p points to output pbuf to encode oid into + * @param ofs points to the offset within the pbuf chain + * @param ident_len object identifier array length + * @param ident points to object identifier array + * @return ERR_OK if successfull, ERR_ARG if we can't (or won't) encode + */ +err_t +snmp_asn1_enc_oid(struct pbuf *p, u16_t ofs, u8_t ident_len, s32_t *ident) +{ + u16_t plen, base; + u8_t *msg_ptr; + + plen = 0; + while (p != NULL) + { + base = plen; + plen += p->len; + if (ofs < plen) + { + msg_ptr = (u8_t*)p->payload; + msg_ptr += ofs - base; + + if (ident_len > 1) + { + if ((ident[0] == 1) && (ident[1] == 3)) + { + /* compressed (most common) prefix .iso.org */ + *msg_ptr = 0x2b; + } + else + { + /* calculate prefix */ + *msg_ptr = (u8_t)((ident[0] * 40) + ident[1]); + } + ofs += 1; + if (ofs >= plen) + { + /* next octet in next pbuf */ + p = p->next; + if (p == NULL) { return ERR_ARG; } + msg_ptr = (u8_t*)p->payload; + plen += p->len; + } + else + { + /* next octet in same pbuf */ + msg_ptr++; + } + ident_len -= 2; + ident += 2; + } + else + { +/* @bug: allow empty varbinds for symmetry (we must decode them for getnext), allow partial compression?? */ + /* ident_len <= 1, at least we need zeroDotZero (0.0) (ident_len == 2) */ + return ERR_ARG; + } + while (ident_len > 0) + { + s32_t sub_id; + u8_t shift, tail; + + ident_len--; + sub_id = *ident; + tail = 0; + shift = 28; + while(shift > 0) + { + u8_t code; + + code = (u8_t)(sub_id >> shift); + if ((code != 0) || (tail != 0)) + { + tail = 1; + *msg_ptr = code | 0x80; + ofs += 1; + if (ofs >= plen) + { + /* next octet in next pbuf */ + p = p->next; + if (p == NULL) { return ERR_ARG; } + msg_ptr = (u8_t*)p->payload; + plen += p->len; + } + else + { + /* next octet in same pbuf */ + msg_ptr++; + } + } + shift -= 7; + } + *msg_ptr = (u8_t)sub_id & 0x7F; + if (ident_len > 0) + { + ofs += 1; + if (ofs >= plen) + { + /* next octet in next pbuf */ + p = p->next; + if (p == NULL) { return ERR_ARG; } + msg_ptr = (u8_t*)p->payload; + plen += p->len; + } + else + { + /* next octet in same pbuf */ + msg_ptr++; + } + } + /* proceed to next sub-identifier */ + ident++; + } + return ERR_OK; + } + p = p->next; + } + /* p == NULL, ofs >= plen */ + return ERR_ARG; +} + +/** + * Encodes raw data (octet string, opaque) into a pbuf chained ASN1 msg. + * + * @param p points to output pbuf to encode raw data into + * @param ofs points to the offset within the pbuf chain + * @param raw_len raw data length + * @param raw points raw data + * @return ERR_OK if successfull, ERR_ARG if we can't (or won't) encode + */ +err_t +snmp_asn1_enc_raw(struct pbuf *p, u16_t ofs, u16_t raw_len, u8_t *raw) +{ + u16_t plen, base; + u8_t *msg_ptr; + + plen = 0; + while (p != NULL) + { + base = plen; + plen += p->len; + if (ofs < plen) + { + msg_ptr = (u8_t*)p->payload; + msg_ptr += ofs - base; + + while (raw_len > 1) + { + /* copy raw_len - 1 octets */ + raw_len--; + *msg_ptr = *raw; + raw++; + ofs += 1; + if (ofs >= plen) + { + /* next octet in next pbuf */ + p = p->next; + if (p == NULL) { return ERR_ARG; } + msg_ptr = (u8_t*)p->payload; + plen += p->len; + } + else + { + /* next octet in same pbuf */ + msg_ptr++; + } + } + if (raw_len > 0) + { + /* copy last or single octet */ + *msg_ptr = *raw; + } + return ERR_OK; + } + p = p->next; + } + /* p == NULL, ofs >= plen */ + return ERR_ARG; +} + +#endif /* LWIP_SNMP */ diff --git a/src/lwip-1.4.1/src/core/snmp/mib2.c b/src/lwip-1.4.1/src/core/snmp/mib2.c new file mode 100644 index 0000000..4775ba9 --- /dev/null +++ b/src/lwip-1.4.1/src/core/snmp/mib2.c @@ -0,0 +1,4146 @@ +/** + * @file + * Management Information Base II (RFC1213) objects and functions. + * + * @note the object identifiers for this MIB-2 and private MIB tree + * must be kept in sorted ascending order. This to ensure correct getnext operation. + */ + +/* + * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * Author: Christiaan Simons + */ + +#include "lwip/opt.h" + +#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/snmp.h" +#include "lwip/netif.h" +#include "lwip/ip.h" +#include "lwip/ip_frag.h" +#include "lwip/mem.h" +#include "lwip/tcp_impl.h" +#include "lwip/udp.h" +#include "lwip/snmp_asn1.h" +#include "lwip/snmp_structs.h" +#include "lwip/sys.h" +#include "netif/etharp.h" + +/** + * IANA assigned enterprise ID for lwIP is 26381 + * @see http://www.iana.org/assignments/enterprise-numbers + * + * @note this enterprise ID is assigned to the lwIP project, + * all object identifiers living under this ID are assigned + * by the lwIP maintainers (contact Christiaan Simons)! + * @note don't change this define, use snmp_set_sysobjid() + * + * If you need to create your own private MIB you'll need + * to apply for your own enterprise ID with IANA: + * http://www.iana.org/numbers.html + */ +#define SNMP_ENTERPRISE_ID 26381 +#define SNMP_SYSOBJID_LEN 7 +#define SNMP_SYSOBJID {1, 3, 6, 1, 4, 1, SNMP_ENTERPRISE_ID} + +#ifndef SNMP_SYSSERVICES +#define SNMP_SYSSERVICES ((1 << 6) | (1 << 3) | ((IP_FORWARD) << 2)) +#endif + +#ifndef SNMP_GET_SYSUPTIME +#define SNMP_GET_SYSUPTIME(sysuptime) (sysuptime = (sys_now() / 10)) +#endif + +static void system_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od); +static void system_get_value(struct obj_def *od, u16_t len, void *value); +static u8_t system_set_test(struct obj_def *od, u16_t len, void *value); +static void system_set_value(struct obj_def *od, u16_t len, void *value); +static void interfaces_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od); +static void interfaces_get_value(struct obj_def *od, u16_t len, void *value); +static void ifentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od); +static void ifentry_get_value(struct obj_def *od, u16_t len, void *value); +#if !SNMP_SAFE_REQUESTS +static u8_t ifentry_set_test (struct obj_def *od, u16_t len, void *value); +static void ifentry_set_value (struct obj_def *od, u16_t len, void *value); +#endif /* SNMP_SAFE_REQUESTS */ +static void atentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od); +static void atentry_get_value(struct obj_def *od, u16_t len, void *value); +static void ip_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od); +static void ip_get_value(struct obj_def *od, u16_t len, void *value); +static u8_t ip_set_test(struct obj_def *od, u16_t len, void *value); +static void ip_addrentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od); +static void ip_addrentry_get_value(struct obj_def *od, u16_t len, void *value); +static void ip_rteentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od); +static void ip_rteentry_get_value(struct obj_def *od, u16_t len, void *value); +static void ip_ntomentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od); +static void ip_ntomentry_get_value(struct obj_def *od, u16_t len, void *value); +static void icmp_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od); +static void icmp_get_value(struct obj_def *od, u16_t len, void *value); +#if LWIP_TCP +static void tcp_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od); +static void tcp_get_value(struct obj_def *od, u16_t len, void *value); +#ifdef THIS_SEEMS_UNUSED +static void tcpconnentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od); +static void tcpconnentry_get_value(struct obj_def *od, u16_t len, void *value); +#endif +#endif +static void udp_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od); +static void udp_get_value(struct obj_def *od, u16_t len, void *value); +static void udpentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od); +static void udpentry_get_value(struct obj_def *od, u16_t len, void *value); +static void snmp_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od); +static void snmp_get_value(struct obj_def *od, u16_t len, void *value); +static u8_t snmp_set_test(struct obj_def *od, u16_t len, void *value); +static void snmp_set_value(struct obj_def *od, u16_t len, void *value); + + +/* snmp .1.3.6.1.2.1.11 */ +const mib_scalar_node snmp_scalar = { + &snmp_get_object_def, + &snmp_get_value, + &snmp_set_test, + &snmp_set_value, + MIB_NODE_SC, + 0 +}; +const s32_t snmp_ids[28] = { + 1, 2, 3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 24, 25, 26, 27, 28, 29, 30 +}; +struct mib_node* const snmp_nodes[28] = { + (struct mib_node*)&snmp_scalar, (struct mib_node*)&snmp_scalar, + (struct mib_node*)&snmp_scalar, (struct mib_node*)&snmp_scalar, + (struct mib_node*)&snmp_scalar, (struct mib_node*)&snmp_scalar, + (struct mib_node*)&snmp_scalar, (struct mib_node*)&snmp_scalar, + (struct mib_node*)&snmp_scalar, (struct mib_node*)&snmp_scalar, + (struct mib_node*)&snmp_scalar, (struct mib_node*)&snmp_scalar, + (struct mib_node*)&snmp_scalar, (struct mib_node*)&snmp_scalar, + (struct mib_node*)&snmp_scalar, (struct mib_node*)&snmp_scalar, + (struct mib_node*)&snmp_scalar, (struct mib_node*)&snmp_scalar, + (struct mib_node*)&snmp_scalar, (struct mib_node*)&snmp_scalar, + (struct mib_node*)&snmp_scalar, (struct mib_node*)&snmp_scalar, + (struct mib_node*)&snmp_scalar, (struct mib_node*)&snmp_scalar, + (struct mib_node*)&snmp_scalar, (struct mib_node*)&snmp_scalar, + (struct mib_node*)&snmp_scalar, (struct mib_node*)&snmp_scalar +}; +const struct mib_array_node snmp = { + &noleafs_get_object_def, + &noleafs_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_AR, + 28, + snmp_ids, + snmp_nodes +}; + +/* dot3 and EtherLike MIB not planned. (transmission .1.3.6.1.2.1.10) */ +/* historical (some say hysterical). (cmot .1.3.6.1.2.1.9) */ +/* lwIP has no EGP, thus may not implement it. (egp .1.3.6.1.2.1.8) */ + +/* udp .1.3.6.1.2.1.7 */ +/** index root node for udpTable */ +struct mib_list_rootnode udp_root = { + &noleafs_get_object_def, + &noleafs_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_LR, + 0, + NULL, + NULL, + 0 +}; +const s32_t udpentry_ids[2] = { 1, 2 }; +struct mib_node* const udpentry_nodes[2] = { + (struct mib_node*)&udp_root, (struct mib_node*)&udp_root, +}; +const struct mib_array_node udpentry = { + &noleafs_get_object_def, + &noleafs_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_AR, + 2, + udpentry_ids, + udpentry_nodes +}; + +s32_t udptable_id = 1; +struct mib_node* udptable_node = (struct mib_node*)&udpentry; +struct mib_ram_array_node udptable = { + &noleafs_get_object_def, + &noleafs_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_RA, + 0, + &udptable_id, + &udptable_node +}; + +const mib_scalar_node udp_scalar = { + &udp_get_object_def, + &udp_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_SC, + 0 +}; +const s32_t udp_ids[5] = { 1, 2, 3, 4, 5 }; +struct mib_node* const udp_nodes[5] = { + (struct mib_node*)&udp_scalar, (struct mib_node*)&udp_scalar, + (struct mib_node*)&udp_scalar, (struct mib_node*)&udp_scalar, + (struct mib_node*)&udptable +}; +const struct mib_array_node udp = { + &noleafs_get_object_def, + &noleafs_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_AR, + 5, + udp_ids, + udp_nodes +}; + +/* tcp .1.3.6.1.2.1.6 */ +#if LWIP_TCP +/* only if the TCP protocol is available may implement this group */ +/** index root node for tcpConnTable */ +struct mib_list_rootnode tcpconntree_root = { + &noleafs_get_object_def, + &noleafs_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_LR, + 0, + NULL, + NULL, + 0 +}; +const s32_t tcpconnentry_ids[5] = { 1, 2, 3, 4, 5 }; +struct mib_node* const tcpconnentry_nodes[5] = { + (struct mib_node*)&tcpconntree_root, (struct mib_node*)&tcpconntree_root, + (struct mib_node*)&tcpconntree_root, (struct mib_node*)&tcpconntree_root, + (struct mib_node*)&tcpconntree_root +}; +const struct mib_array_node tcpconnentry = { + &noleafs_get_object_def, + &noleafs_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_AR, + 5, + tcpconnentry_ids, + tcpconnentry_nodes +}; + +s32_t tcpconntable_id = 1; +struct mib_node* tcpconntable_node = (struct mib_node*)&tcpconnentry; +struct mib_ram_array_node tcpconntable = { + &noleafs_get_object_def, + &noleafs_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_RA, +/** @todo update maxlength when inserting / deleting from table + 0 when table is empty, 1 when more than one entry */ + 0, + &tcpconntable_id, + &tcpconntable_node +}; + +const mib_scalar_node tcp_scalar = { + &tcp_get_object_def, + &tcp_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_SC, + 0 +}; +const s32_t tcp_ids[15] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }; +struct mib_node* const tcp_nodes[15] = { + (struct mib_node*)&tcp_scalar, (struct mib_node*)&tcp_scalar, + (struct mib_node*)&tcp_scalar, (struct mib_node*)&tcp_scalar, + (struct mib_node*)&tcp_scalar, (struct mib_node*)&tcp_scalar, + (struct mib_node*)&tcp_scalar, (struct mib_node*)&tcp_scalar, + (struct mib_node*)&tcp_scalar, (struct mib_node*)&tcp_scalar, + (struct mib_node*)&tcp_scalar, (struct mib_node*)&tcp_scalar, + (struct mib_node*)&tcpconntable, (struct mib_node*)&tcp_scalar, + (struct mib_node*)&tcp_scalar +}; +const struct mib_array_node tcp = { + &noleafs_get_object_def, + &noleafs_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_AR, + 15, + tcp_ids, + tcp_nodes +}; +#endif + +/* icmp .1.3.6.1.2.1.5 */ +const mib_scalar_node icmp_scalar = { + &icmp_get_object_def, + &icmp_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_SC, + 0 +}; +const s32_t icmp_ids[26] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26 }; +struct mib_node* const icmp_nodes[26] = { + (struct mib_node*)&icmp_scalar, (struct mib_node*)&icmp_scalar, + (struct mib_node*)&icmp_scalar, (struct mib_node*)&icmp_scalar, + (struct mib_node*)&icmp_scalar, (struct mib_node*)&icmp_scalar, + (struct mib_node*)&icmp_scalar, (struct mib_node*)&icmp_scalar, + (struct mib_node*)&icmp_scalar, (struct mib_node*)&icmp_scalar, + (struct mib_node*)&icmp_scalar, (struct mib_node*)&icmp_scalar, + (struct mib_node*)&icmp_scalar, (struct mib_node*)&icmp_scalar, + (struct mib_node*)&icmp_scalar, (struct mib_node*)&icmp_scalar, + (struct mib_node*)&icmp_scalar, (struct mib_node*)&icmp_scalar, + (struct mib_node*)&icmp_scalar, (struct mib_node*)&icmp_scalar, + (struct mib_node*)&icmp_scalar, (struct mib_node*)&icmp_scalar, + (struct mib_node*)&icmp_scalar, (struct mib_node*)&icmp_scalar, + (struct mib_node*)&icmp_scalar, (struct mib_node*)&icmp_scalar +}; +const struct mib_array_node icmp = { + &noleafs_get_object_def, + &noleafs_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_AR, + 26, + icmp_ids, + icmp_nodes +}; + +/** index root node for ipNetToMediaTable */ +struct mib_list_rootnode ipntomtree_root = { + &noleafs_get_object_def, + &noleafs_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_LR, + 0, + NULL, + NULL, + 0 +}; +const s32_t ipntomentry_ids[4] = { 1, 2, 3, 4 }; +struct mib_node* const ipntomentry_nodes[4] = { + (struct mib_node*)&ipntomtree_root, (struct mib_node*)&ipntomtree_root, + (struct mib_node*)&ipntomtree_root, (struct mib_node*)&ipntomtree_root +}; +const struct mib_array_node ipntomentry = { + &noleafs_get_object_def, + &noleafs_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_AR, + 4, + ipntomentry_ids, + ipntomentry_nodes +}; + +s32_t ipntomtable_id = 1; +struct mib_node* ipntomtable_node = (struct mib_node*)&ipntomentry; +struct mib_ram_array_node ipntomtable = { + &noleafs_get_object_def, + &noleafs_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_RA, + 0, + &ipntomtable_id, + &ipntomtable_node +}; + +/** index root node for ipRouteTable */ +struct mib_list_rootnode iprtetree_root = { + &noleafs_get_object_def, + &noleafs_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_LR, + 0, + NULL, + NULL, + 0 +}; +const s32_t iprteentry_ids[13] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 }; +struct mib_node* const iprteentry_nodes[13] = { + (struct mib_node*)&iprtetree_root, (struct mib_node*)&iprtetree_root, + (struct mib_node*)&iprtetree_root, (struct mib_node*)&iprtetree_root, + (struct mib_node*)&iprtetree_root, (struct mib_node*)&iprtetree_root, + (struct mib_node*)&iprtetree_root, (struct mib_node*)&iprtetree_root, + (struct mib_node*)&iprtetree_root, (struct mib_node*)&iprtetree_root, + (struct mib_node*)&iprtetree_root, (struct mib_node*)&iprtetree_root, + (struct mib_node*)&iprtetree_root +}; +const struct mib_array_node iprteentry = { + &noleafs_get_object_def, + &noleafs_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_AR, + 13, + iprteentry_ids, + iprteentry_nodes +}; + +s32_t iprtetable_id = 1; +struct mib_node* iprtetable_node = (struct mib_node*)&iprteentry; +struct mib_ram_array_node iprtetable = { + &noleafs_get_object_def, + &noleafs_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_RA, + 0, + &iprtetable_id, + &iprtetable_node +}; + +/** index root node for ipAddrTable */ +struct mib_list_rootnode ipaddrtree_root = { + &noleafs_get_object_def, + &noleafs_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_LR, + 0, + NULL, + NULL, + 0 +}; +const s32_t ipaddrentry_ids[5] = { 1, 2, 3, 4, 5 }; +struct mib_node* const ipaddrentry_nodes[5] = { + (struct mib_node*)&ipaddrtree_root, + (struct mib_node*)&ipaddrtree_root, + (struct mib_node*)&ipaddrtree_root, + (struct mib_node*)&ipaddrtree_root, + (struct mib_node*)&ipaddrtree_root +}; +const struct mib_array_node ipaddrentry = { + &noleafs_get_object_def, + &noleafs_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_AR, + 5, + ipaddrentry_ids, + ipaddrentry_nodes +}; + +s32_t ipaddrtable_id = 1; +struct mib_node* ipaddrtable_node = (struct mib_node*)&ipaddrentry; +struct mib_ram_array_node ipaddrtable = { + &noleafs_get_object_def, + &noleafs_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_RA, + 0, + &ipaddrtable_id, + &ipaddrtable_node +}; + +/* ip .1.3.6.1.2.1.4 */ +const mib_scalar_node ip_scalar = { + &ip_get_object_def, + &ip_get_value, + &ip_set_test, + &noleafs_set_value, + MIB_NODE_SC, + 0 +}; +const s32_t ip_ids[23] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23 }; +struct mib_node* const ip_nodes[23] = { + (struct mib_node*)&ip_scalar, (struct mib_node*)&ip_scalar, + (struct mib_node*)&ip_scalar, (struct mib_node*)&ip_scalar, + (struct mib_node*)&ip_scalar, (struct mib_node*)&ip_scalar, + (struct mib_node*)&ip_scalar, (struct mib_node*)&ip_scalar, + (struct mib_node*)&ip_scalar, (struct mib_node*)&ip_scalar, + (struct mib_node*)&ip_scalar, (struct mib_node*)&ip_scalar, + (struct mib_node*)&ip_scalar, (struct mib_node*)&ip_scalar, + (struct mib_node*)&ip_scalar, (struct mib_node*)&ip_scalar, + (struct mib_node*)&ip_scalar, (struct mib_node*)&ip_scalar, + (struct mib_node*)&ip_scalar, (struct mib_node*)&ipaddrtable, + (struct mib_node*)&iprtetable, (struct mib_node*)&ipntomtable, + (struct mib_node*)&ip_scalar +}; +const struct mib_array_node mib2_ip = { + &noleafs_get_object_def, + &noleafs_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_AR, + 23, + ip_ids, + ip_nodes +}; + +/** index root node for atTable */ +struct mib_list_rootnode arptree_root = { + &noleafs_get_object_def, + &noleafs_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_LR, + 0, + NULL, + NULL, + 0 +}; +const s32_t atentry_ids[3] = { 1, 2, 3 }; +struct mib_node* const atentry_nodes[3] = { + (struct mib_node*)&arptree_root, + (struct mib_node*)&arptree_root, + (struct mib_node*)&arptree_root +}; +const struct mib_array_node atentry = { + &noleafs_get_object_def, + &noleafs_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_AR, + 3, + atentry_ids, + atentry_nodes +}; + +const s32_t attable_id = 1; +struct mib_node* const attable_node = (struct mib_node*)&atentry; +const struct mib_array_node attable = { + &noleafs_get_object_def, + &noleafs_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_AR, + 1, + &attable_id, + &attable_node +}; + +/* at .1.3.6.1.2.1.3 */ +s32_t at_id = 1; +struct mib_node* mib2_at_node = (struct mib_node*)&attable; +struct mib_ram_array_node at = { + &noleafs_get_object_def, + &noleafs_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_RA, + 0, + &at_id, + &mib2_at_node +}; + +/** index root node for ifTable */ +struct mib_list_rootnode iflist_root = { + &ifentry_get_object_def, + &ifentry_get_value, +#if SNMP_SAFE_REQUESTS + &noleafs_set_test, + &noleafs_set_value, +#else /* SNMP_SAFE_REQUESTS */ + &ifentry_set_test, + &ifentry_set_value, +#endif /* SNMP_SAFE_REQUESTS */ + MIB_NODE_LR, + 0, + NULL, + NULL, + 0 +}; +const s32_t ifentry_ids[22] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22 }; +struct mib_node* const ifentry_nodes[22] = { + (struct mib_node*)&iflist_root, (struct mib_node*)&iflist_root, + (struct mib_node*)&iflist_root, (struct mib_node*)&iflist_root, + (struct mib_node*)&iflist_root, (struct mib_node*)&iflist_root, + (struct mib_node*)&iflist_root, (struct mib_node*)&iflist_root, + (struct mib_node*)&iflist_root, (struct mib_node*)&iflist_root, + (struct mib_node*)&iflist_root, (struct mib_node*)&iflist_root, + (struct mib_node*)&iflist_root, (struct mib_node*)&iflist_root, + (struct mib_node*)&iflist_root, (struct mib_node*)&iflist_root, + (struct mib_node*)&iflist_root, (struct mib_node*)&iflist_root, + (struct mib_node*)&iflist_root, (struct mib_node*)&iflist_root, + (struct mib_node*)&iflist_root, (struct mib_node*)&iflist_root +}; +const struct mib_array_node ifentry = { + &noleafs_get_object_def, + &noleafs_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_AR, + 22, + ifentry_ids, + ifentry_nodes +}; + +s32_t iftable_id = 1; +struct mib_node* iftable_node = (struct mib_node*)&ifentry; +struct mib_ram_array_node iftable = { + &noleafs_get_object_def, + &noleafs_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_RA, + 0, + &iftable_id, + &iftable_node +}; + +/* interfaces .1.3.6.1.2.1.2 */ +const mib_scalar_node interfaces_scalar = { + &interfaces_get_object_def, + &interfaces_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_SC, + 0 +}; +const s32_t interfaces_ids[2] = { 1, 2 }; +struct mib_node* const interfaces_nodes[2] = { + (struct mib_node*)&interfaces_scalar, (struct mib_node*)&iftable +}; +const struct mib_array_node interfaces = { + &noleafs_get_object_def, + &noleafs_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_AR, + 2, + interfaces_ids, + interfaces_nodes +}; + + +/* 0 1 2 3 4 5 6 */ +/* system .1.3.6.1.2.1.1 */ +const mib_scalar_node sys_tem_scalar = { + &system_get_object_def, + &system_get_value, + &system_set_test, + &system_set_value, + MIB_NODE_SC, + 0 +}; +const s32_t sys_tem_ids[7] = { 1, 2, 3, 4, 5, 6, 7 }; +struct mib_node* const sys_tem_nodes[7] = { + (struct mib_node*)&sys_tem_scalar, (struct mib_node*)&sys_tem_scalar, + (struct mib_node*)&sys_tem_scalar, (struct mib_node*)&sys_tem_scalar, + (struct mib_node*)&sys_tem_scalar, (struct mib_node*)&sys_tem_scalar, + (struct mib_node*)&sys_tem_scalar +}; +/* work around name issue with 'sys_tem', some compiler(s?) seem to reserve 'system' */ +const struct mib_array_node sys_tem = { + &noleafs_get_object_def, + &noleafs_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_AR, + 7, + sys_tem_ids, + sys_tem_nodes +}; + +/* mib-2 .1.3.6.1.2.1 */ +#if LWIP_TCP +#define MIB2_GROUPS 8 +#else +#define MIB2_GROUPS 7 +#endif +const s32_t mib2_ids[MIB2_GROUPS] = +{ + 1, + 2, + 3, + 4, + 5, +#if LWIP_TCP + 6, +#endif + 7, + 11 +}; +struct mib_node* const mib2_nodes[MIB2_GROUPS] = { + (struct mib_node*)&sys_tem, + (struct mib_node*)&interfaces, + (struct mib_node*)&at, + (struct mib_node*)&mib2_ip, + (struct mib_node*)&icmp, +#if LWIP_TCP + (struct mib_node*)&tcp, +#endif + (struct mib_node*)&udp, + (struct mib_node*)&snmp +}; + +const struct mib_array_node mib2 = { + &noleafs_get_object_def, + &noleafs_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_AR, + MIB2_GROUPS, + mib2_ids, + mib2_nodes +}; + +/* mgmt .1.3.6.1.2 */ +const s32_t mgmt_ids[1] = { 1 }; +struct mib_node* const mgmt_nodes[1] = { (struct mib_node*)&mib2 }; +const struct mib_array_node mgmt = { + &noleafs_get_object_def, + &noleafs_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_AR, + 1, + mgmt_ids, + mgmt_nodes +}; + +/* internet .1.3.6.1 */ +#if SNMP_PRIVATE_MIB +/* When using a private MIB, you have to create a file 'private_mib.h' that contains + * a 'struct mib_array_node mib_private' which contains your MIB. */ +s32_t internet_ids[2] = { 2, 4 }; +struct mib_node* const internet_nodes[2] = { (struct mib_node*)&mgmt, (struct mib_node*)&mib_private }; +const struct mib_array_node internet = { + &noleafs_get_object_def, + &noleafs_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_AR, + 2, + internet_ids, + internet_nodes +}; +#else +const s32_t internet_ids[1] = { 2 }; +struct mib_node* const internet_nodes[1] = { (struct mib_node*)&mgmt }; +const struct mib_array_node internet = { + &noleafs_get_object_def, + &noleafs_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_AR, + 1, + internet_ids, + internet_nodes +}; +#endif + +/** mib-2.system.sysObjectID */ +static struct snmp_obj_id sysobjid = {SNMP_SYSOBJID_LEN, SNMP_SYSOBJID}; +/** enterprise ID for generic TRAPs, .iso.org.dod.internet.mgmt.mib-2.snmp */ +static struct snmp_obj_id snmpgrp_id = {7,{1,3,6,1,2,1,11}}; +/** mib-2.system.sysServices */ +static const s32_t sysservices = SNMP_SYSSERVICES; + +/** mib-2.system.sysDescr */ +static const u8_t sysdescr_len_default = 4; +static const u8_t sysdescr_default[] = "lwIP"; +static u8_t* sysdescr_len_ptr = (u8_t*)&sysdescr_len_default; +static u8_t* sysdescr_ptr = (u8_t*)&sysdescr_default[0]; +/** mib-2.system.sysContact */ +static const u8_t syscontact_len_default = 0; +static const u8_t syscontact_default[] = ""; +static u8_t* syscontact_len_ptr = (u8_t*)&syscontact_len_default; +static u8_t* syscontact_ptr = (u8_t*)&syscontact_default[0]; +/** mib-2.system.sysName */ +static const u8_t sysname_len_default = 8; +static const u8_t sysname_default[] = "FQDN-unk"; +static u8_t* sysname_len_ptr = (u8_t*)&sysname_len_default; +static u8_t* sysname_ptr = (u8_t*)&sysname_default[0]; +/** mib-2.system.sysLocation */ +static const u8_t syslocation_len_default = 0; +static const u8_t syslocation_default[] = ""; +static u8_t* syslocation_len_ptr = (u8_t*)&syslocation_len_default; +static u8_t* syslocation_ptr = (u8_t*)&syslocation_default[0]; +/** mib-2.snmp.snmpEnableAuthenTraps */ +static const u8_t snmpenableauthentraps_default = 2; /* disabled */ +static u8_t* snmpenableauthentraps_ptr = (u8_t*)&snmpenableauthentraps_default; + +/** mib-2.interfaces.ifTable.ifEntry.ifSpecific (zeroDotZero) */ +static const struct snmp_obj_id ifspecific = {2, {0, 0}}; +/** mib-2.ip.ipRouteTable.ipRouteEntry.ipRouteInfo (zeroDotZero) */ +static const struct snmp_obj_id iprouteinfo = {2, {0, 0}}; + + + +/* mib-2.system counter(s) */ +static u32_t sysuptime = 0; + +/* mib-2.ip counter(s) */ +static u32_t ipinreceives = 0, + ipinhdrerrors = 0, + ipinaddrerrors = 0, + ipforwdatagrams = 0, + ipinunknownprotos = 0, + ipindiscards = 0, + ipindelivers = 0, + ipoutrequests = 0, + ipoutdiscards = 0, + ipoutnoroutes = 0, + ipreasmreqds = 0, + ipreasmoks = 0, + ipreasmfails = 0, + ipfragoks = 0, + ipfragfails = 0, + ipfragcreates = 0, + iproutingdiscards = 0; +/* mib-2.icmp counter(s) */ +static u32_t icmpinmsgs = 0, + icmpinerrors = 0, + icmpindestunreachs = 0, + icmpintimeexcds = 0, + icmpinparmprobs = 0, + icmpinsrcquenchs = 0, + icmpinredirects = 0, + icmpinechos = 0, + icmpinechoreps = 0, + icmpintimestamps = 0, + icmpintimestampreps = 0, + icmpinaddrmasks = 0, + icmpinaddrmaskreps = 0, + icmpoutmsgs = 0, + icmpouterrors = 0, + icmpoutdestunreachs = 0, + icmpouttimeexcds = 0, + icmpoutparmprobs = 0, + icmpoutsrcquenchs = 0, + icmpoutredirects = 0, + icmpoutechos = 0, + icmpoutechoreps = 0, + icmpouttimestamps = 0, + icmpouttimestampreps = 0, + icmpoutaddrmasks = 0, + icmpoutaddrmaskreps = 0; +/* mib-2.tcp counter(s) */ +static u32_t tcpactiveopens = 0, + tcppassiveopens = 0, + tcpattemptfails = 0, + tcpestabresets = 0, + tcpinsegs = 0, + tcpoutsegs = 0, + tcpretranssegs = 0, + tcpinerrs = 0, + tcpoutrsts = 0; +/* mib-2.udp counter(s) */ +static u32_t udpindatagrams = 0, + udpnoports = 0, + udpinerrors = 0, + udpoutdatagrams = 0; +/* mib-2.snmp counter(s) */ +static u32_t snmpinpkts = 0, + snmpoutpkts = 0, + snmpinbadversions = 0, + snmpinbadcommunitynames = 0, + snmpinbadcommunityuses = 0, + snmpinasnparseerrs = 0, + snmpintoobigs = 0, + snmpinnosuchnames = 0, + snmpinbadvalues = 0, + snmpinreadonlys = 0, + snmpingenerrs = 0, + snmpintotalreqvars = 0, + snmpintotalsetvars = 0, + snmpingetrequests = 0, + snmpingetnexts = 0, + snmpinsetrequests = 0, + snmpingetresponses = 0, + snmpintraps = 0, + snmpouttoobigs = 0, + snmpoutnosuchnames = 0, + snmpoutbadvalues = 0, + snmpoutgenerrs = 0, + snmpoutgetrequests = 0, + snmpoutgetnexts = 0, + snmpoutsetrequests = 0, + snmpoutgetresponses = 0, + snmpouttraps = 0; + + + +/* prototypes of the following functions are in lwip/src/include/lwip/snmp.h */ +/** + * Copy octet string. + * + * @param dst points to destination + * @param src points to source + * @param n number of octets to copy. + */ +static void ocstrncpy(u8_t *dst, u8_t *src, u16_t n) +{ + u16_t i = n; + while (i > 0) { + i--; + *dst++ = *src++; + } +} + +/** + * Copy object identifier (s32_t) array. + * + * @param dst points to destination + * @param src points to source + * @param n number of sub identifiers to copy. + */ +void objectidncpy(s32_t *dst, s32_t *src, u8_t n) +{ + u8_t i = n; + while(i > 0) { + i--; + *dst++ = *src++; + } +} + +/** + * Initializes sysDescr pointers. + * + * @param str if non-NULL then copy str pointer + * @param len points to string length, excluding zero terminator + */ +void snmp_set_sysdesr(u8_t *str, u8_t *len) +{ + if (str != NULL) + { + sysdescr_ptr = str; + sysdescr_len_ptr = len; + } +} + +void snmp_get_sysobjid_ptr(struct snmp_obj_id **oid) +{ + *oid = &sysobjid; +} + +/** + * Initializes sysObjectID value. + * + * @param oid points to stuct snmp_obj_id to copy + */ +void snmp_set_sysobjid(struct snmp_obj_id *oid) +{ + sysobjid = *oid; +} + +/** + * Must be called at regular 10 msec interval from a timer interrupt + * or signal handler depending on your runtime environment. + */ +void snmp_inc_sysuptime(void) +{ + sysuptime++; +} + +void snmp_add_sysuptime(u32_t value) +{ + sysuptime+=value; +} + +void snmp_get_sysuptime(u32_t *value) +{ + SNMP_GET_SYSUPTIME(sysuptime); + *value = sysuptime; +} + +/** + * Initializes sysContact pointers, + * e.g. ptrs to non-volatile memory external to lwIP. + * + * @param ocstr if non-NULL then copy str pointer + * @param ocstrlen points to string length, excluding zero terminator + */ +void snmp_set_syscontact(u8_t *ocstr, u8_t *ocstrlen) +{ + if (ocstr != NULL) + { + syscontact_ptr = ocstr; + syscontact_len_ptr = ocstrlen; + } +} + +/** + * Initializes sysName pointers, + * e.g. ptrs to non-volatile memory external to lwIP. + * + * @param ocstr if non-NULL then copy str pointer + * @param ocstrlen points to string length, excluding zero terminator + */ +void snmp_set_sysname(u8_t *ocstr, u8_t *ocstrlen) +{ + if (ocstr != NULL) + { + sysname_ptr = ocstr; + sysname_len_ptr = ocstrlen; + } +} + +/** + * Initializes sysLocation pointers, + * e.g. ptrs to non-volatile memory external to lwIP. + * + * @param ocstr if non-NULL then copy str pointer + * @param ocstrlen points to string length, excluding zero terminator + */ +void snmp_set_syslocation(u8_t *ocstr, u8_t *ocstrlen) +{ + if (ocstr != NULL) + { + syslocation_ptr = ocstr; + syslocation_len_ptr = ocstrlen; + } +} + + +void snmp_add_ifinoctets(struct netif *ni, u32_t value) +{ + ni->ifinoctets += value; +} + +void snmp_inc_ifinucastpkts(struct netif *ni) +{ + (ni->ifinucastpkts)++; +} + +void snmp_inc_ifinnucastpkts(struct netif *ni) +{ + (ni->ifinnucastpkts)++; +} + +void snmp_inc_ifindiscards(struct netif *ni) +{ + (ni->ifindiscards)++; +} + +void snmp_add_ifoutoctets(struct netif *ni, u32_t value) +{ + ni->ifoutoctets += value; +} + +void snmp_inc_ifoutucastpkts(struct netif *ni) +{ + (ni->ifoutucastpkts)++; +} + +void snmp_inc_ifoutnucastpkts(struct netif *ni) +{ + (ni->ifoutnucastpkts)++; +} + +void snmp_inc_ifoutdiscards(struct netif *ni) +{ + (ni->ifoutdiscards)++; +} + +void snmp_inc_iflist(void) +{ + struct mib_list_node *if_node = NULL; + + snmp_mib_node_insert(&iflist_root, iflist_root.count + 1, &if_node); + /* enable getnext traversal on filled table */ + iftable.maxlength = 1; +} + +void snmp_dec_iflist(void) +{ + snmp_mib_node_delete(&iflist_root, iflist_root.tail); + /* disable getnext traversal on empty table */ + if(iflist_root.count == 0) iftable.maxlength = 0; +} + +/** + * Inserts ARP table indexes (.xIfIndex.xNetAddress) + * into arp table index trees (both atTable and ipNetToMediaTable). + */ +void snmp_insert_arpidx_tree(struct netif *ni, ip_addr_t *ip) +{ + struct mib_list_rootnode *at_rn; + struct mib_list_node *at_node; + s32_t arpidx[5]; + u8_t level, tree; + + LWIP_ASSERT("ni != NULL", ni != NULL); + snmp_netiftoifindex(ni, &arpidx[0]); + snmp_iptooid(ip, &arpidx[1]); + + for (tree = 0; tree < 2; tree++) + { + if (tree == 0) + { + at_rn = &arptree_root; + } + else + { + at_rn = &ipntomtree_root; + } + for (level = 0; level < 5; level++) + { + at_node = NULL; + snmp_mib_node_insert(at_rn, arpidx[level], &at_node); + if ((level != 4) && (at_node != NULL)) + { + if (at_node->nptr == NULL) + { + at_rn = snmp_mib_lrn_alloc(); + at_node->nptr = (struct mib_node*)at_rn; + if (at_rn != NULL) + { + if (level == 3) + { + if (tree == 0) + { + at_rn->get_object_def = atentry_get_object_def; + at_rn->get_value = atentry_get_value; + } + else + { + at_rn->get_object_def = ip_ntomentry_get_object_def; + at_rn->get_value = ip_ntomentry_get_value; + } + at_rn->set_test = noleafs_set_test; + at_rn->set_value = noleafs_set_value; + } + } + else + { + /* at_rn == NULL, malloc failure */ + LWIP_DEBUGF(SNMP_MIB_DEBUG,("snmp_insert_arpidx_tree() insert failed, mem full")); + break; + } + } + else + { + at_rn = (struct mib_list_rootnode*)at_node->nptr; + } + } + } + } + /* enable getnext traversal on filled tables */ + at.maxlength = 1; + ipntomtable.maxlength = 1; +} + +/** + * Removes ARP table indexes (.xIfIndex.xNetAddress) + * from arp table index trees. + */ +void snmp_delete_arpidx_tree(struct netif *ni, ip_addr_t *ip) +{ + struct mib_list_rootnode *at_rn, *next, *del_rn[5]; + struct mib_list_node *at_n, *del_n[5]; + s32_t arpidx[5]; + u8_t fc, tree, level, del_cnt; + + snmp_netiftoifindex(ni, &arpidx[0]); + snmp_iptooid(ip, &arpidx[1]); + + for (tree = 0; tree < 2; tree++) + { + /* mark nodes for deletion */ + if (tree == 0) + { + at_rn = &arptree_root; + } + else + { + at_rn = &ipntomtree_root; + } + level = 0; + del_cnt = 0; + while ((level < 5) && (at_rn != NULL)) + { + fc = snmp_mib_node_find(at_rn, arpidx[level], &at_n); + if (fc == 0) + { + /* arpidx[level] does not exist */ + del_cnt = 0; + at_rn = NULL; + } + else if (fc == 1) + { + del_rn[del_cnt] = at_rn; + del_n[del_cnt] = at_n; + del_cnt++; + at_rn = (struct mib_list_rootnode*)(at_n->nptr); + } + else if (fc == 2) + { + /* reset delete (2 or more childs) */ + del_cnt = 0; + at_rn = (struct mib_list_rootnode*)(at_n->nptr); + } + level++; + } + /* delete marked index nodes */ + while (del_cnt > 0) + { + del_cnt--; + + at_rn = del_rn[del_cnt]; + at_n = del_n[del_cnt]; + + next = snmp_mib_node_delete(at_rn, at_n); + if (next != NULL) + { + LWIP_ASSERT("next_count == 0",next->count == 0); + snmp_mib_lrn_free(next); + } + } + } + /* disable getnext traversal on empty tables */ + if(arptree_root.count == 0) at.maxlength = 0; + if(ipntomtree_root.count == 0) ipntomtable.maxlength = 0; +} + +void snmp_inc_ipinreceives(void) +{ + ipinreceives++; +} + +void snmp_inc_ipinhdrerrors(void) +{ + ipinhdrerrors++; +} + +void snmp_inc_ipinaddrerrors(void) +{ + ipinaddrerrors++; +} + +void snmp_inc_ipforwdatagrams(void) +{ + ipforwdatagrams++; +} + +void snmp_inc_ipinunknownprotos(void) +{ + ipinunknownprotos++; +} + +void snmp_inc_ipindiscards(void) +{ + ipindiscards++; +} + +void snmp_inc_ipindelivers(void) +{ + ipindelivers++; +} + +void snmp_inc_ipoutrequests(void) +{ + ipoutrequests++; +} + +void snmp_inc_ipoutdiscards(void) +{ + ipoutdiscards++; +} + +void snmp_inc_ipoutnoroutes(void) +{ + ipoutnoroutes++; +} + +void snmp_inc_ipreasmreqds(void) +{ + ipreasmreqds++; +} + +void snmp_inc_ipreasmoks(void) +{ + ipreasmoks++; +} + +void snmp_inc_ipreasmfails(void) +{ + ipreasmfails++; +} + +void snmp_inc_ipfragoks(void) +{ + ipfragoks++; +} + +void snmp_inc_ipfragfails(void) +{ + ipfragfails++; +} + +void snmp_inc_ipfragcreates(void) +{ + ipfragcreates++; +} + +void snmp_inc_iproutingdiscards(void) +{ + iproutingdiscards++; +} + +/** + * Inserts ipAddrTable indexes (.ipAdEntAddr) + * into index tree. + */ +void snmp_insert_ipaddridx_tree(struct netif *ni) +{ + struct mib_list_rootnode *ipa_rn; + struct mib_list_node *ipa_node; + s32_t ipaddridx[4]; + u8_t level; + + LWIP_ASSERT("ni != NULL", ni != NULL); + snmp_iptooid(&ni->ip_addr, &ipaddridx[0]); + + level = 0; + ipa_rn = &ipaddrtree_root; + while (level < 4) + { + ipa_node = NULL; + snmp_mib_node_insert(ipa_rn, ipaddridx[level], &ipa_node); + if ((level != 3) && (ipa_node != NULL)) + { + if (ipa_node->nptr == NULL) + { + ipa_rn = snmp_mib_lrn_alloc(); + ipa_node->nptr = (struct mib_node*)ipa_rn; + if (ipa_rn != NULL) + { + if (level == 2) + { + ipa_rn->get_object_def = ip_addrentry_get_object_def; + ipa_rn->get_value = ip_addrentry_get_value; + ipa_rn->set_test = noleafs_set_test; + ipa_rn->set_value = noleafs_set_value; + } + } + else + { + /* ipa_rn == NULL, malloc failure */ + LWIP_DEBUGF(SNMP_MIB_DEBUG,("snmp_insert_ipaddridx_tree() insert failed, mem full")); + break; + } + } + else + { + ipa_rn = (struct mib_list_rootnode*)ipa_node->nptr; + } + } + level++; + } + /* enable getnext traversal on filled table */ + ipaddrtable.maxlength = 1; +} + +/** + * Removes ipAddrTable indexes (.ipAdEntAddr) + * from index tree. + */ +void snmp_delete_ipaddridx_tree(struct netif *ni) +{ + struct mib_list_rootnode *ipa_rn, *next, *del_rn[4]; + struct mib_list_node *ipa_n, *del_n[4]; + s32_t ipaddridx[4]; + u8_t fc, level, del_cnt; + + LWIP_ASSERT("ni != NULL", ni != NULL); + snmp_iptooid(&ni->ip_addr, &ipaddridx[0]); + + /* mark nodes for deletion */ + level = 0; + del_cnt = 0; + ipa_rn = &ipaddrtree_root; + while ((level < 4) && (ipa_rn != NULL)) + { + fc = snmp_mib_node_find(ipa_rn, ipaddridx[level], &ipa_n); + if (fc == 0) + { + /* ipaddridx[level] does not exist */ + del_cnt = 0; + ipa_rn = NULL; + } + else if (fc == 1) + { + del_rn[del_cnt] = ipa_rn; + del_n[del_cnt] = ipa_n; + del_cnt++; + ipa_rn = (struct mib_list_rootnode*)(ipa_n->nptr); + } + else if (fc == 2) + { + /* reset delete (2 or more childs) */ + del_cnt = 0; + ipa_rn = (struct mib_list_rootnode*)(ipa_n->nptr); + } + level++; + } + /* delete marked index nodes */ + while (del_cnt > 0) + { + del_cnt--; + + ipa_rn = del_rn[del_cnt]; + ipa_n = del_n[del_cnt]; + + next = snmp_mib_node_delete(ipa_rn, ipa_n); + if (next != NULL) + { + LWIP_ASSERT("next_count == 0",next->count == 0); + snmp_mib_lrn_free(next); + } + } + /* disable getnext traversal on empty table */ + if (ipaddrtree_root.count == 0) ipaddrtable.maxlength = 0; +} + +/** + * Inserts ipRouteTable indexes (.ipRouteDest) + * into index tree. + * + * @param dflt non-zero for the default rte, zero for network rte + * @param ni points to network interface for this rte + * + * @todo record sysuptime for _this_ route when it is installed + * (needed for ipRouteAge) in the netif. + */ +void snmp_insert_iprteidx_tree(u8_t dflt, struct netif *ni) +{ + u8_t insert = 0; + ip_addr_t dst; + + if (dflt != 0) + { + /* the default route 0.0.0.0 */ + ip_addr_set_any(&dst); + insert = 1; + } + else + { + /* route to the network address */ + ip_addr_get_network(&dst, &ni->ip_addr, &ni->netmask); + /* exclude 0.0.0.0 network (reserved for default rte) */ + if (!ip_addr_isany(&dst)) { + insert = 1; + } + } + if (insert) + { + struct mib_list_rootnode *iprte_rn; + struct mib_list_node *iprte_node; + s32_t iprteidx[4]; + u8_t level; + + snmp_iptooid(&dst, &iprteidx[0]); + level = 0; + iprte_rn = &iprtetree_root; + while (level < 4) + { + iprte_node = NULL; + snmp_mib_node_insert(iprte_rn, iprteidx[level], &iprte_node); + if ((level != 3) && (iprte_node != NULL)) + { + if (iprte_node->nptr == NULL) + { + iprte_rn = snmp_mib_lrn_alloc(); + iprte_node->nptr = (struct mib_node*)iprte_rn; + if (iprte_rn != NULL) + { + if (level == 2) + { + iprte_rn->get_object_def = ip_rteentry_get_object_def; + iprte_rn->get_value = ip_rteentry_get_value; + iprte_rn->set_test = noleafs_set_test; + iprte_rn->set_value = noleafs_set_value; + } + } + else + { + /* iprte_rn == NULL, malloc failure */ + LWIP_DEBUGF(SNMP_MIB_DEBUG,("snmp_insert_iprteidx_tree() insert failed, mem full")); + break; + } + } + else + { + iprte_rn = (struct mib_list_rootnode*)iprte_node->nptr; + } + } + level++; + } + } + /* enable getnext traversal on filled table */ + iprtetable.maxlength = 1; +} + +/** + * Removes ipRouteTable indexes (.ipRouteDest) + * from index tree. + * + * @param dflt non-zero for the default rte, zero for network rte + * @param ni points to network interface for this rte or NULL + * for default route to be removed. + */ +void snmp_delete_iprteidx_tree(u8_t dflt, struct netif *ni) +{ + u8_t del = 0; + ip_addr_t dst; + + if (dflt != 0) + { + /* the default route 0.0.0.0 */ + ip_addr_set_any(&dst); + del = 1; + } + else + { + /* route to the network address */ + ip_addr_get_network(&dst, &ni->ip_addr, &ni->netmask); + /* exclude 0.0.0.0 network (reserved for default rte) */ + if (!ip_addr_isany(&dst)) { + del = 1; + } + } + if (del) + { + struct mib_list_rootnode *iprte_rn, *next, *del_rn[4]; + struct mib_list_node *iprte_n, *del_n[4]; + s32_t iprteidx[4]; + u8_t fc, level, del_cnt; + + snmp_iptooid(&dst, &iprteidx[0]); + /* mark nodes for deletion */ + level = 0; + del_cnt = 0; + iprte_rn = &iprtetree_root; + while ((level < 4) && (iprte_rn != NULL)) + { + fc = snmp_mib_node_find(iprte_rn, iprteidx[level], &iprte_n); + if (fc == 0) + { + /* iprteidx[level] does not exist */ + del_cnt = 0; + iprte_rn = NULL; + } + else if (fc == 1) + { + del_rn[del_cnt] = iprte_rn; + del_n[del_cnt] = iprte_n; + del_cnt++; + iprte_rn = (struct mib_list_rootnode*)(iprte_n->nptr); + } + else if (fc == 2) + { + /* reset delete (2 or more childs) */ + del_cnt = 0; + iprte_rn = (struct mib_list_rootnode*)(iprte_n->nptr); + } + level++; + } + /* delete marked index nodes */ + while (del_cnt > 0) + { + del_cnt--; + + iprte_rn = del_rn[del_cnt]; + iprte_n = del_n[del_cnt]; + + next = snmp_mib_node_delete(iprte_rn, iprte_n); + if (next != NULL) + { + LWIP_ASSERT("next_count == 0",next->count == 0); + snmp_mib_lrn_free(next); + } + } + } + /* disable getnext traversal on empty table */ + if (iprtetree_root.count == 0) iprtetable.maxlength = 0; +} + + +void snmp_inc_icmpinmsgs(void) +{ + icmpinmsgs++; +} + +void snmp_inc_icmpinerrors(void) +{ + icmpinerrors++; +} + +void snmp_inc_icmpindestunreachs(void) +{ + icmpindestunreachs++; +} + +void snmp_inc_icmpintimeexcds(void) +{ + icmpintimeexcds++; +} + +void snmp_inc_icmpinparmprobs(void) +{ + icmpinparmprobs++; +} + +void snmp_inc_icmpinsrcquenchs(void) +{ + icmpinsrcquenchs++; +} + +void snmp_inc_icmpinredirects(void) +{ + icmpinredirects++; +} + +void snmp_inc_icmpinechos(void) +{ + icmpinechos++; +} + +void snmp_inc_icmpinechoreps(void) +{ + icmpinechoreps++; +} + +void snmp_inc_icmpintimestamps(void) +{ + icmpintimestamps++; +} + +void snmp_inc_icmpintimestampreps(void) +{ + icmpintimestampreps++; +} + +void snmp_inc_icmpinaddrmasks(void) +{ + icmpinaddrmasks++; +} + +void snmp_inc_icmpinaddrmaskreps(void) +{ + icmpinaddrmaskreps++; +} + +void snmp_inc_icmpoutmsgs(void) +{ + icmpoutmsgs++; +} + +void snmp_inc_icmpouterrors(void) +{ + icmpouterrors++; +} + +void snmp_inc_icmpoutdestunreachs(void) +{ + icmpoutdestunreachs++; +} + +void snmp_inc_icmpouttimeexcds(void) +{ + icmpouttimeexcds++; +} + +void snmp_inc_icmpoutparmprobs(void) +{ + icmpoutparmprobs++; +} + +void snmp_inc_icmpoutsrcquenchs(void) +{ + icmpoutsrcquenchs++; +} + +void snmp_inc_icmpoutredirects(void) +{ + icmpoutredirects++; +} + +void snmp_inc_icmpoutechos(void) +{ + icmpoutechos++; +} + +void snmp_inc_icmpoutechoreps(void) +{ + icmpoutechoreps++; +} + +void snmp_inc_icmpouttimestamps(void) +{ + icmpouttimestamps++; +} + +void snmp_inc_icmpouttimestampreps(void) +{ + icmpouttimestampreps++; +} + +void snmp_inc_icmpoutaddrmasks(void) +{ + icmpoutaddrmasks++; +} + +void snmp_inc_icmpoutaddrmaskreps(void) +{ + icmpoutaddrmaskreps++; +} + +void snmp_inc_tcpactiveopens(void) +{ + tcpactiveopens++; +} + +void snmp_inc_tcppassiveopens(void) +{ + tcppassiveopens++; +} + +void snmp_inc_tcpattemptfails(void) +{ + tcpattemptfails++; +} + +void snmp_inc_tcpestabresets(void) +{ + tcpestabresets++; +} + +void snmp_inc_tcpinsegs(void) +{ + tcpinsegs++; +} + +void snmp_inc_tcpoutsegs(void) +{ + tcpoutsegs++; +} + +void snmp_inc_tcpretranssegs(void) +{ + tcpretranssegs++; +} + +void snmp_inc_tcpinerrs(void) +{ + tcpinerrs++; +} + +void snmp_inc_tcpoutrsts(void) +{ + tcpoutrsts++; +} + +void snmp_inc_udpindatagrams(void) +{ + udpindatagrams++; +} + +void snmp_inc_udpnoports(void) +{ + udpnoports++; +} + +void snmp_inc_udpinerrors(void) +{ + udpinerrors++; +} + +void snmp_inc_udpoutdatagrams(void) +{ + udpoutdatagrams++; +} + +/** + * Inserts udpTable indexes (.udpLocalAddress.udpLocalPort) + * into index tree. + */ +void snmp_insert_udpidx_tree(struct udp_pcb *pcb) +{ + struct mib_list_rootnode *udp_rn; + struct mib_list_node *udp_node; + s32_t udpidx[5]; + u8_t level; + + LWIP_ASSERT("pcb != NULL", pcb != NULL); + snmp_iptooid(&pcb->local_ip, &udpidx[0]); + udpidx[4] = pcb->local_port; + + udp_rn = &udp_root; + for (level = 0; level < 5; level++) + { + udp_node = NULL; + snmp_mib_node_insert(udp_rn, udpidx[level], &udp_node); + if ((level != 4) && (udp_node != NULL)) + { + if (udp_node->nptr == NULL) + { + udp_rn = snmp_mib_lrn_alloc(); + udp_node->nptr = (struct mib_node*)udp_rn; + if (udp_rn != NULL) + { + if (level == 3) + { + udp_rn->get_object_def = udpentry_get_object_def; + udp_rn->get_value = udpentry_get_value; + udp_rn->set_test = noleafs_set_test; + udp_rn->set_value = noleafs_set_value; + } + } + else + { + /* udp_rn == NULL, malloc failure */ + LWIP_DEBUGF(SNMP_MIB_DEBUG,("snmp_insert_udpidx_tree() insert failed, mem full")); + break; + } + } + else + { + udp_rn = (struct mib_list_rootnode*)udp_node->nptr; + } + } + } + udptable.maxlength = 1; +} + +/** + * Removes udpTable indexes (.udpLocalAddress.udpLocalPort) + * from index tree. + */ +void snmp_delete_udpidx_tree(struct udp_pcb *pcb) +{ + struct udp_pcb *npcb; + struct mib_list_rootnode *udp_rn, *next, *del_rn[5]; + struct mib_list_node *udp_n, *del_n[5]; + s32_t udpidx[5]; + u8_t bindings, fc, level, del_cnt; + + LWIP_ASSERT("pcb != NULL", pcb != NULL); + snmp_iptooid(&pcb->local_ip, &udpidx[0]); + udpidx[4] = pcb->local_port; + + /* count PCBs for a given binding + (e.g. when reusing ports or for temp output PCBs) */ + bindings = 0; + npcb = udp_pcbs; + while ((npcb != NULL)) + { + if (ip_addr_cmp(&npcb->local_ip, &pcb->local_ip) && + (npcb->local_port == udpidx[4])) + { + bindings++; + } + npcb = npcb->next; + } + if (bindings == 1) + { + /* selectively remove */ + /* mark nodes for deletion */ + level = 0; + del_cnt = 0; + udp_rn = &udp_root; + while ((level < 5) && (udp_rn != NULL)) + { + fc = snmp_mib_node_find(udp_rn, udpidx[level], &udp_n); + if (fc == 0) + { + /* udpidx[level] does not exist */ + del_cnt = 0; + udp_rn = NULL; + } + else if (fc == 1) + { + del_rn[del_cnt] = udp_rn; + del_n[del_cnt] = udp_n; + del_cnt++; + udp_rn = (struct mib_list_rootnode*)(udp_n->nptr); + } + else if (fc == 2) + { + /* reset delete (2 or more childs) */ + del_cnt = 0; + udp_rn = (struct mib_list_rootnode*)(udp_n->nptr); + } + level++; + } + /* delete marked index nodes */ + while (del_cnt > 0) + { + del_cnt--; + + udp_rn = del_rn[del_cnt]; + udp_n = del_n[del_cnt]; + + next = snmp_mib_node_delete(udp_rn, udp_n); + if (next != NULL) + { + LWIP_ASSERT("next_count == 0",next->count == 0); + snmp_mib_lrn_free(next); + } + } + } + /* disable getnext traversal on empty table */ + if (udp_root.count == 0) udptable.maxlength = 0; +} + + +void snmp_inc_snmpinpkts(void) +{ + snmpinpkts++; +} + +void snmp_inc_snmpoutpkts(void) +{ + snmpoutpkts++; +} + +void snmp_inc_snmpinbadversions(void) +{ + snmpinbadversions++; +} + +void snmp_inc_snmpinbadcommunitynames(void) +{ + snmpinbadcommunitynames++; +} + +void snmp_inc_snmpinbadcommunityuses(void) +{ + snmpinbadcommunityuses++; +} + +void snmp_inc_snmpinasnparseerrs(void) +{ + snmpinasnparseerrs++; +} + +void snmp_inc_snmpintoobigs(void) +{ + snmpintoobigs++; +} + +void snmp_inc_snmpinnosuchnames(void) +{ + snmpinnosuchnames++; +} + +void snmp_inc_snmpinbadvalues(void) +{ + snmpinbadvalues++; +} + +void snmp_inc_snmpinreadonlys(void) +{ + snmpinreadonlys++; +} + +void snmp_inc_snmpingenerrs(void) +{ + snmpingenerrs++; +} + +void snmp_add_snmpintotalreqvars(u8_t value) +{ + snmpintotalreqvars += value; +} + +void snmp_add_snmpintotalsetvars(u8_t value) +{ + snmpintotalsetvars += value; +} + +void snmp_inc_snmpingetrequests(void) +{ + snmpingetrequests++; +} + +void snmp_inc_snmpingetnexts(void) +{ + snmpingetnexts++; +} + +void snmp_inc_snmpinsetrequests(void) +{ + snmpinsetrequests++; +} + +void snmp_inc_snmpingetresponses(void) +{ + snmpingetresponses++; +} + +void snmp_inc_snmpintraps(void) +{ + snmpintraps++; +} + +void snmp_inc_snmpouttoobigs(void) +{ + snmpouttoobigs++; +} + +void snmp_inc_snmpoutnosuchnames(void) +{ + snmpoutnosuchnames++; +} + +void snmp_inc_snmpoutbadvalues(void) +{ + snmpoutbadvalues++; +} + +void snmp_inc_snmpoutgenerrs(void) +{ + snmpoutgenerrs++; +} + +void snmp_inc_snmpoutgetrequests(void) +{ + snmpoutgetrequests++; +} + +void snmp_inc_snmpoutgetnexts(void) +{ + snmpoutgetnexts++; +} + +void snmp_inc_snmpoutsetrequests(void) +{ + snmpoutsetrequests++; +} + +void snmp_inc_snmpoutgetresponses(void) +{ + snmpoutgetresponses++; +} + +void snmp_inc_snmpouttraps(void) +{ + snmpouttraps++; +} + +void snmp_get_snmpgrpid_ptr(struct snmp_obj_id **oid) +{ + *oid = &snmpgrp_id; +} + +void snmp_set_snmpenableauthentraps(u8_t *value) +{ + if (value != NULL) + { + snmpenableauthentraps_ptr = value; + } +} + +void snmp_get_snmpenableauthentraps(u8_t *value) +{ + *value = *snmpenableauthentraps_ptr; +} + +void +noleafs_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od) +{ + LWIP_UNUSED_ARG(ident_len); + LWIP_UNUSED_ARG(ident); + od->instance = MIB_OBJECT_NONE; +} + +void +noleafs_get_value(struct obj_def *od, u16_t len, void *value) +{ + LWIP_UNUSED_ARG(od); + LWIP_UNUSED_ARG(len); + LWIP_UNUSED_ARG(value); +} + +u8_t +noleafs_set_test(struct obj_def *od, u16_t len, void *value) +{ + LWIP_UNUSED_ARG(od); + LWIP_UNUSED_ARG(len); + LWIP_UNUSED_ARG(value); + /* can't set */ + return 0; +} + +void +noleafs_set_value(struct obj_def *od, u16_t len, void *value) +{ + LWIP_UNUSED_ARG(od); + LWIP_UNUSED_ARG(len); + LWIP_UNUSED_ARG(value); +} + + +/** + * Returns systems object definitions. + * + * @param ident_len the address length (2) + * @param ident points to objectname.0 (object id trailer) + * @param od points to object definition. + */ +static void +system_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od) +{ + u8_t id; + + /* return to object name, adding index depth (1) */ + ident_len += 1; + ident -= 1; + if (ident_len == 2) + { + od->id_inst_len = ident_len; + od->id_inst_ptr = ident; + + LWIP_ASSERT("invalid id", (ident[0] >= 0) && (ident[0] <= 0xff)); + id = (u8_t)ident[0]; + LWIP_DEBUGF(SNMP_MIB_DEBUG,("get_object_def system.%"U16_F".0\n",(u16_t)id)); + switch (id) + { + case 1: /* sysDescr */ + od->instance = MIB_OBJECT_SCALAR; + od->access = MIB_OBJECT_READ_ONLY; + od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR); + od->v_len = *sysdescr_len_ptr; + break; + case 2: /* sysObjectID */ + od->instance = MIB_OBJECT_SCALAR; + od->access = MIB_OBJECT_READ_ONLY; + od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OBJ_ID); + od->v_len = sysobjid.len * sizeof(s32_t); + break; + case 3: /* sysUpTime */ + od->instance = MIB_OBJECT_SCALAR; + od->access = MIB_OBJECT_READ_ONLY; + od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_TIMETICKS); + od->v_len = sizeof(u32_t); + break; + case 4: /* sysContact */ + od->instance = MIB_OBJECT_SCALAR; + od->access = MIB_OBJECT_READ_WRITE; + od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR); + od->v_len = *syscontact_len_ptr; + break; + case 5: /* sysName */ + od->instance = MIB_OBJECT_SCALAR; + od->access = MIB_OBJECT_READ_WRITE; + od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR); + od->v_len = *sysname_len_ptr; + break; + case 6: /* sysLocation */ + od->instance = MIB_OBJECT_SCALAR; + od->access = MIB_OBJECT_READ_WRITE; + od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR); + od->v_len = *syslocation_len_ptr; + break; + case 7: /* sysServices */ + od->instance = MIB_OBJECT_SCALAR; + od->access = MIB_OBJECT_READ_ONLY; + od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG); + od->v_len = sizeof(s32_t); + break; + default: + LWIP_DEBUGF(SNMP_MIB_DEBUG,("system_get_object_def: no such object\n")); + od->instance = MIB_OBJECT_NONE; + break; + }; + } + else + { + LWIP_DEBUGF(SNMP_MIB_DEBUG,("system_get_object_def: no scalar\n")); + od->instance = MIB_OBJECT_NONE; + } +} + +/** + * Returns system object value. + * + * @param ident_len the address length (2) + * @param ident points to objectname.0 (object id trailer) + * @param len return value space (in bytes) + * @param value points to (varbind) space to copy value into. + */ +static void +system_get_value(struct obj_def *od, u16_t len, void *value) +{ + u8_t id; + + LWIP_ASSERT("invalid id", (od->id_inst_ptr[0] >= 0) && (od->id_inst_ptr[0] <= 0xff)); + id = (u8_t)od->id_inst_ptr[0]; + switch (id) + { + case 1: /* sysDescr */ + ocstrncpy((u8_t*)value, sysdescr_ptr, len); + break; + case 2: /* sysObjectID */ + objectidncpy((s32_t*)value, (s32_t*)sysobjid.id, (u8_t)(len / sizeof(s32_t))); + break; + case 3: /* sysUpTime */ + { + snmp_get_sysuptime((u32_t*)value); + } + break; + case 4: /* sysContact */ + ocstrncpy((u8_t*)value, syscontact_ptr, len); + break; + case 5: /* sysName */ + ocstrncpy((u8_t*)value, sysname_ptr, len); + break; + case 6: /* sysLocation */ + ocstrncpy((u8_t*)value, syslocation_ptr, len); + break; + case 7: /* sysServices */ + { + s32_t *sint_ptr = (s32_t*)value; + *sint_ptr = sysservices; + } + break; + }; +} + +static u8_t +system_set_test(struct obj_def *od, u16_t len, void *value) +{ + u8_t id, set_ok; + + LWIP_UNUSED_ARG(value); + set_ok = 0; + LWIP_ASSERT("invalid id", (od->id_inst_ptr[0] >= 0) && (od->id_inst_ptr[0] <= 0xff)); + id = (u8_t)od->id_inst_ptr[0]; + switch (id) + { + case 4: /* sysContact */ + if ((syscontact_ptr != syscontact_default) && + (len <= 255)) + { + set_ok = 1; + } + break; + case 5: /* sysName */ + if ((sysname_ptr != sysname_default) && + (len <= 255)) + { + set_ok = 1; + } + break; + case 6: /* sysLocation */ + if ((syslocation_ptr != syslocation_default) && + (len <= 255)) + { + set_ok = 1; + } + break; + }; + return set_ok; +} + +static void +system_set_value(struct obj_def *od, u16_t len, void *value) +{ + u8_t id; + + LWIP_ASSERT("invalid len", len <= 0xff); + LWIP_ASSERT("invalid id", (od->id_inst_ptr[0] >= 0) && (od->id_inst_ptr[0] <= 0xff)); + id = (u8_t)od->id_inst_ptr[0]; + switch (id) + { + case 4: /* sysContact */ + ocstrncpy(syscontact_ptr, (u8_t*)value, len); + *syscontact_len_ptr = (u8_t)len; + break; + case 5: /* sysName */ + ocstrncpy(sysname_ptr, (u8_t*)value, len); + *sysname_len_ptr = (u8_t)len; + break; + case 6: /* sysLocation */ + ocstrncpy(syslocation_ptr, (u8_t*)value, len); + *syslocation_len_ptr = (u8_t)len; + break; + }; +} + +/** + * Returns interfaces.ifnumber object definition. + * + * @param ident_len the address length (2) + * @param ident points to objectname.index + * @param od points to object definition. + */ +static void +interfaces_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od) +{ + /* return to object name, adding index depth (1) */ + ident_len += 1; + ident -= 1; + if (ident_len == 2) + { + od->id_inst_len = ident_len; + od->id_inst_ptr = ident; + + od->instance = MIB_OBJECT_SCALAR; + od->access = MIB_OBJECT_READ_ONLY; + od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG); + od->v_len = sizeof(s32_t); + } + else + { + LWIP_DEBUGF(SNMP_MIB_DEBUG,("interfaces_get_object_def: no scalar\n")); + od->instance = MIB_OBJECT_NONE; + } +} + +/** + * Returns interfaces.ifnumber object value. + * + * @param ident_len the address length (2) + * @param ident points to objectname.0 (object id trailer) + * @param len return value space (in bytes) + * @param value points to (varbind) space to copy value into. + */ +static void +interfaces_get_value(struct obj_def *od, u16_t len, void *value) +{ + LWIP_UNUSED_ARG(len); + if (od->id_inst_ptr[0] == 1) + { + s32_t *sint_ptr = (s32_t*)value; + *sint_ptr = iflist_root.count; + } +} + +/** + * Returns ifentry object definitions. + * + * @param ident_len the address length (2) + * @param ident points to objectname.index + * @param od points to object definition. + */ +static void +ifentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od) +{ + u8_t id; + + /* return to object name, adding index depth (1) */ + ident_len += 1; + ident -= 1; + if (ident_len == 2) + { + od->id_inst_len = ident_len; + od->id_inst_ptr = ident; + + LWIP_ASSERT("invalid id", (ident[0] >= 0) && (ident[0] <= 0xff)); + id = (u8_t)ident[0]; + LWIP_DEBUGF(SNMP_MIB_DEBUG,("get_object_def ifentry.%"U16_F"\n",(u16_t)id)); + switch (id) + { + case 1: /* ifIndex */ + case 3: /* ifType */ + case 4: /* ifMtu */ + case 8: /* ifOperStatus */ + od->instance = MIB_OBJECT_TAB; + od->access = MIB_OBJECT_READ_ONLY; + od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG); + od->v_len = sizeof(s32_t); + break; + case 2: /* ifDescr */ + od->instance = MIB_OBJECT_TAB; + od->access = MIB_OBJECT_READ_ONLY; + od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR); + /** @todo this should be some sort of sizeof(struct netif.name) */ + od->v_len = 2; + break; + case 5: /* ifSpeed */ + case 21: /* ifOutQLen */ + od->instance = MIB_OBJECT_TAB; + od->access = MIB_OBJECT_READ_ONLY; + od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_GAUGE); + od->v_len = sizeof(u32_t); + break; + case 6: /* ifPhysAddress */ + { + struct netif *netif; + + snmp_ifindextonetif(ident[1], &netif); + od->instance = MIB_OBJECT_TAB; + od->access = MIB_OBJECT_READ_ONLY; + od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR); + od->v_len = netif->hwaddr_len; + } + break; + case 7: /* ifAdminStatus */ + od->instance = MIB_OBJECT_TAB; + od->access = MIB_OBJECT_READ_WRITE; + od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG); + od->v_len = sizeof(s32_t); + break; + case 9: /* ifLastChange */ + od->instance = MIB_OBJECT_TAB; + od->access = MIB_OBJECT_READ_ONLY; + od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_TIMETICKS); + od->v_len = sizeof(u32_t); + break; + case 10: /* ifInOctets */ + case 11: /* ifInUcastPkts */ + case 12: /* ifInNUcastPkts */ + case 13: /* ifInDiscarts */ + case 14: /* ifInErrors */ + case 15: /* ifInUnkownProtos */ + case 16: /* ifOutOctets */ + case 17: /* ifOutUcastPkts */ + case 18: /* ifOutNUcastPkts */ + case 19: /* ifOutDiscarts */ + case 20: /* ifOutErrors */ + od->instance = MIB_OBJECT_TAB; + od->access = MIB_OBJECT_READ_ONLY; + od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_COUNTER); + od->v_len = sizeof(u32_t); + break; + case 22: /* ifSpecific */ + /** @note returning zeroDotZero (0.0) no media specific MIB support */ + od->instance = MIB_OBJECT_TAB; + od->access = MIB_OBJECT_READ_ONLY; + od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OBJ_ID); + od->v_len = ifspecific.len * sizeof(s32_t); + break; + default: + LWIP_DEBUGF(SNMP_MIB_DEBUG,("ifentry_get_object_def: no such object\n")); + od->instance = MIB_OBJECT_NONE; + break; + }; + } + else + { + LWIP_DEBUGF(SNMP_MIB_DEBUG,("ifentry_get_object_def: no scalar\n")); + od->instance = MIB_OBJECT_NONE; + } +} + +/** + * Returns ifentry object value. + * + * @param ident_len the address length (2) + * @param ident points to objectname.0 (object id trailer) + * @param len return value space (in bytes) + * @param value points to (varbind) space to copy value into. + */ +static void +ifentry_get_value(struct obj_def *od, u16_t len, void *value) +{ + struct netif *netif; + u8_t id; + + snmp_ifindextonetif(od->id_inst_ptr[1], &netif); + LWIP_ASSERT("invalid id", (od->id_inst_ptr[0] >= 0) && (od->id_inst_ptr[0] <= 0xff)); + id = (u8_t)od->id_inst_ptr[0]; + switch (id) + { + case 1: /* ifIndex */ + { + s32_t *sint_ptr = (s32_t*)value; + *sint_ptr = od->id_inst_ptr[1]; + } + break; + case 2: /* ifDescr */ + ocstrncpy((u8_t*)value, (u8_t*)netif->name, len); + break; + case 3: /* ifType */ + { + s32_t *sint_ptr = (s32_t*)value; + *sint_ptr = netif->link_type; + } + break; + case 4: /* ifMtu */ + { + s32_t *sint_ptr = (s32_t*)value; + *sint_ptr = netif->mtu; + } + break; + case 5: /* ifSpeed */ + { + u32_t *uint_ptr = (u32_t*)value; + *uint_ptr = netif->link_speed; + } + break; + case 6: /* ifPhysAddress */ + ocstrncpy((u8_t*)value, netif->hwaddr, len); + break; + case 7: /* ifAdminStatus */ + { + s32_t *sint_ptr = (s32_t*)value; + if (netif_is_up(netif)) + { + if (netif_is_link_up(netif)) + { + *sint_ptr = 1; /* up */ + } + else + { + *sint_ptr = 7; /* lowerLayerDown */ + } + } + else + { + *sint_ptr = 2; /* down */ + } + } + break; + case 8: /* ifOperStatus */ + { + s32_t *sint_ptr = (s32_t*)value; + if (netif_is_up(netif)) + { + *sint_ptr = 1; + } + else + { + *sint_ptr = 2; + } + } + break; + case 9: /* ifLastChange */ + { + u32_t *uint_ptr = (u32_t*)value; + *uint_ptr = netif->ts; + } + break; + case 10: /* ifInOctets */ + { + u32_t *uint_ptr = (u32_t*)value; + *uint_ptr = netif->ifinoctets; + } + break; + case 11: /* ifInUcastPkts */ + { + u32_t *uint_ptr = (u32_t*)value; + *uint_ptr = netif->ifinucastpkts; + } + break; + case 12: /* ifInNUcastPkts */ + { + u32_t *uint_ptr = (u32_t*)value; + *uint_ptr = netif->ifinnucastpkts; + } + break; + case 13: /* ifInDiscarts */ + { + u32_t *uint_ptr = (u32_t*)value; + *uint_ptr = netif->ifindiscards; + } + break; + case 14: /* ifInErrors */ + case 15: /* ifInUnkownProtos */ + /** @todo add these counters! */ + { + u32_t *uint_ptr = (u32_t*)value; + *uint_ptr = 0; + } + break; + case 16: /* ifOutOctets */ + { + u32_t *uint_ptr = (u32_t*)value; + *uint_ptr = netif->ifoutoctets; + } + break; + case 17: /* ifOutUcastPkts */ + { + u32_t *uint_ptr = (u32_t*)value; + *uint_ptr = netif->ifoutucastpkts; + } + break; + case 18: /* ifOutNUcastPkts */ + { + u32_t *uint_ptr = (u32_t*)value; + *uint_ptr = netif->ifoutnucastpkts; + } + break; + case 19: /* ifOutDiscarts */ + { + u32_t *uint_ptr = (u32_t*)value; + *uint_ptr = netif->ifoutdiscards; + } + break; + case 20: /* ifOutErrors */ + /** @todo add this counter! */ + { + u32_t *uint_ptr = (u32_t*)value; + *uint_ptr = 0; + } + break; + case 21: /* ifOutQLen */ + /** @todo figure out if this must be 0 (no queue) or 1? */ + { + u32_t *uint_ptr = (u32_t*)value; + *uint_ptr = 0; + } + break; + case 22: /* ifSpecific */ + objectidncpy((s32_t*)value, (s32_t*)ifspecific.id, (u8_t)(len / sizeof(s32_t))); + break; + }; +} + +#if !SNMP_SAFE_REQUESTS +static u8_t +ifentry_set_test(struct obj_def *od, u16_t len, void *value) +{ + struct netif *netif; + u8_t id, set_ok; + LWIP_UNUSED_ARG(len); + + set_ok = 0; + snmp_ifindextonetif(od->id_inst_ptr[1], &netif); + id = (u8_t)od->id_inst_ptr[0]; + switch (id) + { + case 7: /* ifAdminStatus */ + { + s32_t *sint_ptr = (s32_t*)value; + if (*sint_ptr == 1 || *sint_ptr == 2) + set_ok = 1; + } + break; + } + return set_ok; +} + +static void +ifentry_set_value(struct obj_def *od, u16_t len, void *value) +{ + struct netif *netif; + u8_t id; + LWIP_UNUSED_ARG(len); + + snmp_ifindextonetif(od->id_inst_ptr[1], &netif); + id = (u8_t)od->id_inst_ptr[0]; + switch (id) + { + case 7: /* ifAdminStatus */ + { + s32_t *sint_ptr = (s32_t*)value; + if (*sint_ptr == 1) + { + netif_set_up(netif); + } + else if (*sint_ptr == 2) + { + netif_set_down(netif); + } + } + break; + } +} +#endif /* SNMP_SAFE_REQUESTS */ + +/** + * Returns atentry object definitions. + * + * @param ident_len the address length (6) + * @param ident points to objectname.atifindex.atnetaddress + * @param od points to object definition. + */ +static void +atentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od) +{ + /* return to object name, adding index depth (5) */ + ident_len += 5; + ident -= 5; + + if (ident_len == 6) + { + od->id_inst_len = ident_len; + od->id_inst_ptr = ident; + + switch (ident[0]) + { + case 1: /* atIfIndex */ + od->instance = MIB_OBJECT_TAB; + od->access = MIB_OBJECT_READ_WRITE; + od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG); + od->v_len = sizeof(s32_t); + break; + case 2: /* atPhysAddress */ + od->instance = MIB_OBJECT_TAB; + od->access = MIB_OBJECT_READ_WRITE; + od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR); + od->v_len = 6; /** @todo try to use netif::hwaddr_len */ + break; + case 3: /* atNetAddress */ + od->instance = MIB_OBJECT_TAB; + od->access = MIB_OBJECT_READ_WRITE; + od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_IPADDR); + od->v_len = 4; + break; + default: + LWIP_DEBUGF(SNMP_MIB_DEBUG,("atentry_get_object_def: no such object\n")); + od->instance = MIB_OBJECT_NONE; + break; + } + } + else + { + LWIP_DEBUGF(SNMP_MIB_DEBUG,("atentry_get_object_def: no scalar\n")); + od->instance = MIB_OBJECT_NONE; + } +} + +static void +atentry_get_value(struct obj_def *od, u16_t len, void *value) +{ +#if LWIP_ARP + u8_t id; + struct eth_addr* ethaddr_ret; + ip_addr_t* ipaddr_ret; +#endif /* LWIP_ARP */ + ip_addr_t ip; + struct netif *netif; + + LWIP_UNUSED_ARG(len); + LWIP_UNUSED_ARG(value);/* if !LWIP_ARP */ + + snmp_ifindextonetif(od->id_inst_ptr[1], &netif); + snmp_oidtoip(&od->id_inst_ptr[2], &ip); + +#if LWIP_ARP /** @todo implement a netif_find_addr */ + if (etharp_find_addr(netif, &ip, ðaddr_ret, &ipaddr_ret) > -1) + { + LWIP_ASSERT("invalid id", (od->id_inst_ptr[0] >= 0) && (od->id_inst_ptr[0] <= 0xff)); + id = (u8_t)od->id_inst_ptr[0]; + switch (id) + { + case 1: /* atIfIndex */ + { + s32_t *sint_ptr = (s32_t*)value; + *sint_ptr = od->id_inst_ptr[1]; + } + break; + case 2: /* atPhysAddress */ + { + struct eth_addr *dst = (struct eth_addr*)value; + + *dst = *ethaddr_ret; + } + break; + case 3: /* atNetAddress */ + { + ip_addr_t *dst = (ip_addr_t*)value; + + *dst = *ipaddr_ret; + } + break; + } + } +#endif /* LWIP_ARP */ +} + +static void +ip_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od) +{ + u8_t id; + + /* return to object name, adding index depth (1) */ + ident_len += 1; + ident -= 1; + if (ident_len == 2) + { + od->id_inst_len = ident_len; + od->id_inst_ptr = ident; + + LWIP_ASSERT("invalid id", (ident[0] >= 0) && (ident[0] <= 0xff)); + id = (u8_t)ident[0]; + LWIP_DEBUGF(SNMP_MIB_DEBUG,("get_object_def ip.%"U16_F".0\n",(u16_t)id)); + switch (id) + { + case 1: /* ipForwarding */ + case 2: /* ipDefaultTTL */ + od->instance = MIB_OBJECT_SCALAR; + od->access = MIB_OBJECT_READ_WRITE; + od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG); + od->v_len = sizeof(s32_t); + break; + case 3: /* ipInReceives */ + case 4: /* ipInHdrErrors */ + case 5: /* ipInAddrErrors */ + case 6: /* ipForwDatagrams */ + case 7: /* ipInUnknownProtos */ + case 8: /* ipInDiscards */ + case 9: /* ipInDelivers */ + case 10: /* ipOutRequests */ + case 11: /* ipOutDiscards */ + case 12: /* ipOutNoRoutes */ + case 14: /* ipReasmReqds */ + case 15: /* ipReasmOKs */ + case 16: /* ipReasmFails */ + case 17: /* ipFragOKs */ + case 18: /* ipFragFails */ + case 19: /* ipFragCreates */ + case 23: /* ipRoutingDiscards */ + od->instance = MIB_OBJECT_SCALAR; + od->access = MIB_OBJECT_READ_ONLY; + od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_COUNTER); + od->v_len = sizeof(u32_t); + break; + case 13: /* ipReasmTimeout */ + od->instance = MIB_OBJECT_SCALAR; + od->access = MIB_OBJECT_READ_ONLY; + od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG); + od->v_len = sizeof(s32_t); + break; + default: + LWIP_DEBUGF(SNMP_MIB_DEBUG,("ip_get_object_def: no such object\n")); + od->instance = MIB_OBJECT_NONE; + break; + }; + } + else + { + LWIP_DEBUGF(SNMP_MIB_DEBUG,("ip_get_object_def: no scalar\n")); + od->instance = MIB_OBJECT_NONE; + } +} + +static void +ip_get_value(struct obj_def *od, u16_t len, void *value) +{ + u8_t id; + + LWIP_UNUSED_ARG(len); + LWIP_ASSERT("invalid id", (od->id_inst_ptr[0] >= 0) && (od->id_inst_ptr[0] <= 0xff)); + id = (u8_t)od->id_inst_ptr[0]; + switch (id) + { + case 1: /* ipForwarding */ + { + s32_t *sint_ptr = (s32_t*)value; +#if IP_FORWARD + /* forwarding */ + *sint_ptr = 1; +#else + /* not-forwarding */ + *sint_ptr = 2; +#endif + } + break; + case 2: /* ipDefaultTTL */ + { + s32_t *sint_ptr = (s32_t*)value; + *sint_ptr = IP_DEFAULT_TTL; + } + break; + case 3: /* ipInReceives */ + { + u32_t *uint_ptr = (u32_t*)value; + *uint_ptr = ipinreceives; + } + break; + case 4: /* ipInHdrErrors */ + { + u32_t *uint_ptr = (u32_t*)value; + *uint_ptr = ipinhdrerrors; + } + break; + case 5: /* ipInAddrErrors */ + { + u32_t *uint_ptr = (u32_t*)value; + *uint_ptr = ipinaddrerrors; + } + break; + case 6: /* ipForwDatagrams */ + { + u32_t *uint_ptr = (u32_t*)value; + *uint_ptr = ipforwdatagrams; + } + break; + case 7: /* ipInUnknownProtos */ + { + u32_t *uint_ptr = (u32_t*)value; + *uint_ptr = ipinunknownprotos; + } + break; + case 8: /* ipInDiscards */ + { + u32_t *uint_ptr = (u32_t*)value; + *uint_ptr = ipindiscards; + } + break; + case 9: /* ipInDelivers */ + { + u32_t *uint_ptr = (u32_t*)value; + *uint_ptr = ipindelivers; + } + break; + case 10: /* ipOutRequests */ + { + u32_t *uint_ptr = (u32_t*)value; + *uint_ptr = ipoutrequests; + } + break; + case 11: /* ipOutDiscards */ + { + u32_t *uint_ptr = (u32_t*)value; + *uint_ptr = ipoutdiscards; + } + break; + case 12: /* ipOutNoRoutes */ + { + u32_t *uint_ptr = (u32_t*)value; + *uint_ptr = ipoutnoroutes; + } + break; + case 13: /* ipReasmTimeout */ + { + s32_t *sint_ptr = (s32_t*)value; +#if IP_REASSEMBLY + *sint_ptr = IP_REASS_MAXAGE; +#else + *sint_ptr = 0; +#endif + } + break; + case 14: /* ipReasmReqds */ + { + u32_t *uint_ptr = (u32_t*)value; + *uint_ptr = ipreasmreqds; + } + break; + case 15: /* ipReasmOKs */ + { + u32_t *uint_ptr = (u32_t*)value; + *uint_ptr = ipreasmoks; + } + break; + case 16: /* ipReasmFails */ + { + u32_t *uint_ptr = (u32_t*)value; + *uint_ptr = ipreasmfails; + } + break; + case 17: /* ipFragOKs */ + { + u32_t *uint_ptr = (u32_t*)value; + *uint_ptr = ipfragoks; + } + break; + case 18: /* ipFragFails */ + { + u32_t *uint_ptr = (u32_t*)value; + *uint_ptr = ipfragfails; + } + break; + case 19: /* ipFragCreates */ + { + u32_t *uint_ptr = (u32_t*)value; + *uint_ptr = ipfragcreates; + } + break; + case 23: /* ipRoutingDiscards */ + /** @todo can lwIP discard routes at all?? hardwire this to 0?? */ + { + u32_t *uint_ptr = (u32_t*)value; + *uint_ptr = iproutingdiscards; + } + break; + }; +} + +/** + * Test ip object value before setting. + * + * @param od is the object definition + * @param len return value space (in bytes) + * @param value points to (varbind) space to copy value from. + * + * @note we allow set if the value matches the hardwired value, + * otherwise return badvalue. + */ +static u8_t +ip_set_test(struct obj_def *od, u16_t len, void *value) +{ + u8_t id, set_ok; + s32_t *sint_ptr = (s32_t*)value; + + LWIP_UNUSED_ARG(len); + set_ok = 0; + LWIP_ASSERT("invalid id", (od->id_inst_ptr[0] >= 0) && (od->id_inst_ptr[0] <= 0xff)); + id = (u8_t)od->id_inst_ptr[0]; + switch (id) + { + case 1: /* ipForwarding */ +#if IP_FORWARD + /* forwarding */ + if (*sint_ptr == 1) +#else + /* not-forwarding */ + if (*sint_ptr == 2) +#endif + { + set_ok = 1; + } + break; + case 2: /* ipDefaultTTL */ + if (*sint_ptr == IP_DEFAULT_TTL) + { + set_ok = 1; + } + break; + }; + return set_ok; +} + +static void +ip_addrentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od) +{ + /* return to object name, adding index depth (4) */ + ident_len += 4; + ident -= 4; + + if (ident_len == 5) + { + u8_t id; + + od->id_inst_len = ident_len; + od->id_inst_ptr = ident; + + LWIP_ASSERT("invalid id", (ident[0] >= 0) && (ident[0] <= 0xff)); + id = (u8_t)ident[0]; + switch (id) + { + case 1: /* ipAdEntAddr */ + case 3: /* ipAdEntNetMask */ + od->instance = MIB_OBJECT_TAB; + od->access = MIB_OBJECT_READ_ONLY; + od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_IPADDR); + od->v_len = 4; + break; + case 2: /* ipAdEntIfIndex */ + case 4: /* ipAdEntBcastAddr */ + case 5: /* ipAdEntReasmMaxSize */ + od->instance = MIB_OBJECT_TAB; + od->access = MIB_OBJECT_READ_ONLY; + od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG); + od->v_len = sizeof(s32_t); + break; + default: + LWIP_DEBUGF(SNMP_MIB_DEBUG,("ip_addrentry_get_object_def: no such object\n")); + od->instance = MIB_OBJECT_NONE; + break; + } + } + else + { + LWIP_DEBUGF(SNMP_MIB_DEBUG,("ip_addrentry_get_object_def: no scalar\n")); + od->instance = MIB_OBJECT_NONE; + } +} + +static void +ip_addrentry_get_value(struct obj_def *od, u16_t len, void *value) +{ + u8_t id; + u16_t ifidx; + ip_addr_t ip; + struct netif *netif = netif_list; + + LWIP_UNUSED_ARG(len); + snmp_oidtoip(&od->id_inst_ptr[1], &ip); + ifidx = 0; + while ((netif != NULL) && !ip_addr_cmp(&ip, &netif->ip_addr)) + { + netif = netif->next; + ifidx++; + } + + if (netif != NULL) + { + LWIP_ASSERT("invalid id", (od->id_inst_ptr[0] >= 0) && (od->id_inst_ptr[0] <= 0xff)); + id = (u8_t)od->id_inst_ptr[0]; + switch (id) + { + case 1: /* ipAdEntAddr */ + { + ip_addr_t *dst = (ip_addr_t*)value; + *dst = netif->ip_addr; + } + break; + case 2: /* ipAdEntIfIndex */ + { + s32_t *sint_ptr = (s32_t*)value; + *sint_ptr = ifidx + 1; + } + break; + case 3: /* ipAdEntNetMask */ + { + ip_addr_t *dst = (ip_addr_t*)value; + *dst = netif->netmask; + } + break; + case 4: /* ipAdEntBcastAddr */ + { + s32_t *sint_ptr = (s32_t*)value; + + /* lwIP oddity, there's no broadcast + address in the netif we can rely on */ + *sint_ptr = IPADDR_BROADCAST & 1; + } + break; + case 5: /* ipAdEntReasmMaxSize */ + { + s32_t *sint_ptr = (s32_t*)value; +#if IP_REASSEMBLY + /* @todo The theoretical maximum is IP_REASS_MAX_PBUFS * size of the pbufs, + * but only if receiving one fragmented packet at a time. + * The current solution is to calculate for 2 simultaneous packets... + */ + *sint_ptr = (IP_HLEN + ((IP_REASS_MAX_PBUFS/2) * + (PBUF_POOL_BUFSIZE - PBUF_LINK_HLEN - IP_HLEN))); +#else + /** @todo returning MTU would be a bad thing and + returning a wild guess like '576' isn't good either */ + *sint_ptr = 0; +#endif + } + break; + } + } +} + +/** + * @note + * lwIP IP routing is currently using the network addresses in netif_list. + * if no suitable network IP is found in netif_list, the default_netif is used. + */ +static void +ip_rteentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od) +{ + u8_t id; + + /* return to object name, adding index depth (4) */ + ident_len += 4; + ident -= 4; + + if (ident_len == 5) + { + od->id_inst_len = ident_len; + od->id_inst_ptr = ident; + + LWIP_ASSERT("invalid id", (ident[0] >= 0) && (ident[0] <= 0xff)); + id = (u8_t)ident[0]; + switch (id) + { + case 1: /* ipRouteDest */ + case 7: /* ipRouteNextHop */ + case 11: /* ipRouteMask */ + od->instance = MIB_OBJECT_TAB; + od->access = MIB_OBJECT_READ_WRITE; + od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_IPADDR); + od->v_len = 4; + break; + case 2: /* ipRouteIfIndex */ + case 3: /* ipRouteMetric1 */ + case 4: /* ipRouteMetric2 */ + case 5: /* ipRouteMetric3 */ + case 6: /* ipRouteMetric4 */ + case 8: /* ipRouteType */ + case 10: /* ipRouteAge */ + case 12: /* ipRouteMetric5 */ + od->instance = MIB_OBJECT_TAB; + od->access = MIB_OBJECT_READ_WRITE; + od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG); + od->v_len = sizeof(s32_t); + break; + case 9: /* ipRouteProto */ + od->instance = MIB_OBJECT_TAB; + od->access = MIB_OBJECT_READ_ONLY; + od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG); + od->v_len = sizeof(s32_t); + break; + case 13: /* ipRouteInfo */ + /** @note returning zeroDotZero (0.0) no routing protocol specific MIB */ + od->instance = MIB_OBJECT_TAB; + od->access = MIB_OBJECT_READ_ONLY; + od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OBJ_ID); + od->v_len = iprouteinfo.len * sizeof(s32_t); + break; + default: + LWIP_DEBUGF(SNMP_MIB_DEBUG,("ip_rteentry_get_object_def: no such object\n")); + od->instance = MIB_OBJECT_NONE; + break; + } + } + else + { + LWIP_DEBUGF(SNMP_MIB_DEBUG,("ip_rteentry_get_object_def: no scalar\n")); + od->instance = MIB_OBJECT_NONE; + } +} + +static void +ip_rteentry_get_value(struct obj_def *od, u16_t len, void *value) +{ + struct netif *netif; + ip_addr_t dest; + s32_t *ident; + u8_t id; + + ident = od->id_inst_ptr; + snmp_oidtoip(&ident[1], &dest); + + if (ip_addr_isany(&dest)) + { + /* ip_route() uses default netif for default route */ + netif = netif_default; + } + else + { + /* not using ip_route(), need exact match! */ + netif = netif_list; + while ((netif != NULL) && + !ip_addr_netcmp(&dest, &(netif->ip_addr), &(netif->netmask)) ) + { + netif = netif->next; + } + } + if (netif != NULL) + { + LWIP_ASSERT("invalid id", (ident[0] >= 0) && (ident[0] <= 0xff)); + id = (u8_t)ident[0]; + switch (id) + { + case 1: /* ipRouteDest */ + { + ip_addr_t *dst = (ip_addr_t*)value; + + if (ip_addr_isany(&dest)) + { + /* default rte has 0.0.0.0 dest */ + ip_addr_set_zero(dst); + } + else + { + /* netifs have netaddress dest */ + ip_addr_get_network(dst, &netif->ip_addr, &netif->netmask); + } + } + break; + case 2: /* ipRouteIfIndex */ + { + s32_t *sint_ptr = (s32_t*)value; + + snmp_netiftoifindex(netif, sint_ptr); + } + break; + case 3: /* ipRouteMetric1 */ + { + s32_t *sint_ptr = (s32_t*)value; + + if (ip_addr_isany(&dest)) + { + /* default rte has metric 1 */ + *sint_ptr = 1; + } + else + { + /* other rtes have metric 0 */ + *sint_ptr = 0; + } + } + break; + case 4: /* ipRouteMetric2 */ + case 5: /* ipRouteMetric3 */ + case 6: /* ipRouteMetric4 */ + case 12: /* ipRouteMetric5 */ + { + s32_t *sint_ptr = (s32_t*)value; + /* not used */ + *sint_ptr = -1; + } + break; + case 7: /* ipRouteNextHop */ + { + ip_addr_t *dst = (ip_addr_t*)value; + + if (ip_addr_isany(&dest)) + { + /* default rte: gateway */ + *dst = netif->gw; + } + else + { + /* other rtes: netif ip_addr */ + *dst = netif->ip_addr; + } + } + break; + case 8: /* ipRouteType */ + { + s32_t *sint_ptr = (s32_t*)value; + + if (ip_addr_isany(&dest)) + { + /* default rte is indirect */ + *sint_ptr = 4; + } + else + { + /* other rtes are direct */ + *sint_ptr = 3; + } + } + break; + case 9: /* ipRouteProto */ + { + s32_t *sint_ptr = (s32_t*)value; + /* locally defined routes */ + *sint_ptr = 2; + } + break; + case 10: /* ipRouteAge */ + { + s32_t *sint_ptr = (s32_t*)value; + /** @todo (sysuptime - timestamp last change) / 100 + @see snmp_insert_iprteidx_tree() */ + *sint_ptr = 0; + } + break; + case 11: /* ipRouteMask */ + { + ip_addr_t *dst = (ip_addr_t*)value; + + if (ip_addr_isany(&dest)) + { + /* default rte use 0.0.0.0 mask */ + ip_addr_set_zero(dst); + } + else + { + /* other rtes use netmask */ + *dst = netif->netmask; + } + } + break; + case 13: /* ipRouteInfo */ + objectidncpy((s32_t*)value, (s32_t*)iprouteinfo.id, (u8_t)(len / sizeof(s32_t))); + break; + } + } +} + +static void +ip_ntomentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od) +{ + /* return to object name, adding index depth (5) */ + ident_len += 5; + ident -= 5; + + if (ident_len == 6) + { + u8_t id; + + od->id_inst_len = ident_len; + od->id_inst_ptr = ident; + + LWIP_ASSERT("invalid id", (ident[0] >= 0) && (ident[0] <= 0xff)); + id = (u8_t)ident[0]; + switch (id) + { + case 1: /* ipNetToMediaIfIndex */ + case 4: /* ipNetToMediaType */ + od->instance = MIB_OBJECT_TAB; + od->access = MIB_OBJECT_READ_WRITE; + od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG); + od->v_len = sizeof(s32_t); + break; + case 2: /* ipNetToMediaPhysAddress */ + od->instance = MIB_OBJECT_TAB; + od->access = MIB_OBJECT_READ_WRITE; + od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR); + od->v_len = 6; /** @todo try to use netif::hwaddr_len */ + break; + case 3: /* ipNetToMediaNetAddress */ + od->instance = MIB_OBJECT_TAB; + od->access = MIB_OBJECT_READ_WRITE; + od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_IPADDR); + od->v_len = 4; + break; + default: + LWIP_DEBUGF(SNMP_MIB_DEBUG,("ip_ntomentry_get_object_def: no such object\n")); + od->instance = MIB_OBJECT_NONE; + break; + } + } + else + { + LWIP_DEBUGF(SNMP_MIB_DEBUG,("ip_ntomentry_get_object_def: no scalar\n")); + od->instance = MIB_OBJECT_NONE; + } +} + +static void +ip_ntomentry_get_value(struct obj_def *od, u16_t len, void *value) +{ +#if LWIP_ARP + u8_t id; + struct eth_addr* ethaddr_ret; + ip_addr_t* ipaddr_ret; +#endif /* LWIP_ARP */ + ip_addr_t ip; + struct netif *netif; + + LWIP_UNUSED_ARG(len); + LWIP_UNUSED_ARG(value);/* if !LWIP_ARP */ + + snmp_ifindextonetif(od->id_inst_ptr[1], &netif); + snmp_oidtoip(&od->id_inst_ptr[2], &ip); + +#if LWIP_ARP /** @todo implement a netif_find_addr */ + if (etharp_find_addr(netif, &ip, ðaddr_ret, &ipaddr_ret) > -1) + { + LWIP_ASSERT("invalid id", (od->id_inst_ptr[0] >= 0) && (od->id_inst_ptr[0] <= 0xff)); + id = (u8_t)od->id_inst_ptr[0]; + switch (id) + { + case 1: /* ipNetToMediaIfIndex */ + { + s32_t *sint_ptr = (s32_t*)value; + *sint_ptr = od->id_inst_ptr[1]; + } + break; + case 2: /* ipNetToMediaPhysAddress */ + { + struct eth_addr *dst = (struct eth_addr*)value; + + *dst = *ethaddr_ret; + } + break; + case 3: /* ipNetToMediaNetAddress */ + { + ip_addr_t *dst = (ip_addr_t*)value; + + *dst = *ipaddr_ret; + } + break; + case 4: /* ipNetToMediaType */ + { + s32_t *sint_ptr = (s32_t*)value; + /* dynamic (?) */ + *sint_ptr = 3; + } + break; + } + } +#endif /* LWIP_ARP */ +} + +static void +icmp_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od) +{ + /* return to object name, adding index depth (1) */ + ident_len += 1; + ident -= 1; + if ((ident_len == 2) && + (ident[0] > 0) && (ident[0] < 27)) + { + od->id_inst_len = ident_len; + od->id_inst_ptr = ident; + + od->instance = MIB_OBJECT_SCALAR; + od->access = MIB_OBJECT_READ_ONLY; + od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_COUNTER); + od->v_len = sizeof(u32_t); + } + else + { + LWIP_DEBUGF(SNMP_MIB_DEBUG,("icmp_get_object_def: no scalar\n")); + od->instance = MIB_OBJECT_NONE; + } +} + +static void +icmp_get_value(struct obj_def *od, u16_t len, void *value) +{ + u32_t *uint_ptr = (u32_t*)value; + u8_t id; + + LWIP_UNUSED_ARG(len); + LWIP_ASSERT("invalid id", (od->id_inst_ptr[0] >= 0) && (od->id_inst_ptr[0] <= 0xff)); + id = (u8_t)od->id_inst_ptr[0]; + switch (id) + { + case 1: /* icmpInMsgs */ + *uint_ptr = icmpinmsgs; + break; + case 2: /* icmpInErrors */ + *uint_ptr = icmpinerrors; + break; + case 3: /* icmpInDestUnreachs */ + *uint_ptr = icmpindestunreachs; + break; + case 4: /* icmpInTimeExcds */ + *uint_ptr = icmpintimeexcds; + break; + case 5: /* icmpInParmProbs */ + *uint_ptr = icmpinparmprobs; + break; + case 6: /* icmpInSrcQuenchs */ + *uint_ptr = icmpinsrcquenchs; + break; + case 7: /* icmpInRedirects */ + *uint_ptr = icmpinredirects; + break; + case 8: /* icmpInEchos */ + *uint_ptr = icmpinechos; + break; + case 9: /* icmpInEchoReps */ + *uint_ptr = icmpinechoreps; + break; + case 10: /* icmpInTimestamps */ + *uint_ptr = icmpintimestamps; + break; + case 11: /* icmpInTimestampReps */ + *uint_ptr = icmpintimestampreps; + break; + case 12: /* icmpInAddrMasks */ + *uint_ptr = icmpinaddrmasks; + break; + case 13: /* icmpInAddrMaskReps */ + *uint_ptr = icmpinaddrmaskreps; + break; + case 14: /* icmpOutMsgs */ + *uint_ptr = icmpoutmsgs; + break; + case 15: /* icmpOutErrors */ + *uint_ptr = icmpouterrors; + break; + case 16: /* icmpOutDestUnreachs */ + *uint_ptr = icmpoutdestunreachs; + break; + case 17: /* icmpOutTimeExcds */ + *uint_ptr = icmpouttimeexcds; + break; + case 18: /* icmpOutParmProbs */ + *uint_ptr = icmpoutparmprobs; + break; + case 19: /* icmpOutSrcQuenchs */ + *uint_ptr = icmpoutsrcquenchs; + break; + case 20: /* icmpOutRedirects */ + *uint_ptr = icmpoutredirects; + break; + case 21: /* icmpOutEchos */ + *uint_ptr = icmpoutechos; + break; + case 22: /* icmpOutEchoReps */ + *uint_ptr = icmpoutechoreps; + break; + case 23: /* icmpOutTimestamps */ + *uint_ptr = icmpouttimestamps; + break; + case 24: /* icmpOutTimestampReps */ + *uint_ptr = icmpouttimestampreps; + break; + case 25: /* icmpOutAddrMasks */ + *uint_ptr = icmpoutaddrmasks; + break; + case 26: /* icmpOutAddrMaskReps */ + *uint_ptr = icmpoutaddrmaskreps; + break; + } +} + +#if LWIP_TCP +/** @todo tcp grp */ +static void +tcp_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od) +{ + u8_t id; + + /* return to object name, adding index depth (1) */ + ident_len += 1; + ident -= 1; + if (ident_len == 2) + { + od->id_inst_len = ident_len; + od->id_inst_ptr = ident; + + LWIP_ASSERT("invalid id", (ident[0] >= 0) && (ident[0] <= 0xff)); + id = (u8_t)ident[0]; + LWIP_DEBUGF(SNMP_MIB_DEBUG,("get_object_def tcp.%"U16_F".0\n",(u16_t)id)); + + switch (id) + { + case 1: /* tcpRtoAlgorithm */ + case 2: /* tcpRtoMin */ + case 3: /* tcpRtoMax */ + case 4: /* tcpMaxConn */ + od->instance = MIB_OBJECT_SCALAR; + od->access = MIB_OBJECT_READ_ONLY; + od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG); + od->v_len = sizeof(s32_t); + break; + case 5: /* tcpActiveOpens */ + case 6: /* tcpPassiveOpens */ + case 7: /* tcpAttemptFails */ + case 8: /* tcpEstabResets */ + case 10: /* tcpInSegs */ + case 11: /* tcpOutSegs */ + case 12: /* tcpRetransSegs */ + case 14: /* tcpInErrs */ + case 15: /* tcpOutRsts */ + od->instance = MIB_OBJECT_SCALAR; + od->access = MIB_OBJECT_READ_ONLY; + od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_COUNTER); + od->v_len = sizeof(u32_t); + break; + case 9: /* tcpCurrEstab */ + od->instance = MIB_OBJECT_TAB; + od->access = MIB_OBJECT_READ_ONLY; + od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_GAUGE); + od->v_len = sizeof(u32_t); + break; + default: + LWIP_DEBUGF(SNMP_MIB_DEBUG,("tcp_get_object_def: no such object\n")); + od->instance = MIB_OBJECT_NONE; + break; + }; + } + else + { + LWIP_DEBUGF(SNMP_MIB_DEBUG,("tcp_get_object_def: no scalar\n")); + od->instance = MIB_OBJECT_NONE; + } +} + +static void +tcp_get_value(struct obj_def *od, u16_t len, void *value) +{ + u32_t *uint_ptr = (u32_t*)value; + s32_t *sint_ptr = (s32_t*)value; + u8_t id; + + LWIP_UNUSED_ARG(len); + LWIP_ASSERT("invalid id", (od->id_inst_ptr[0] >= 0) && (od->id_inst_ptr[0] <= 0xff)); + id = (u8_t)od->id_inst_ptr[0]; + switch (id) + { + case 1: /* tcpRtoAlgorithm, vanj(4) */ + *sint_ptr = 4; + break; + case 2: /* tcpRtoMin */ + /* @todo not the actual value, a guess, + needs to be calculated */ + *sint_ptr = 1000; + break; + case 3: /* tcpRtoMax */ + /* @todo not the actual value, a guess, + needs to be calculated */ + *sint_ptr = 60000; + break; + case 4: /* tcpMaxConn */ + *sint_ptr = MEMP_NUM_TCP_PCB; + break; + case 5: /* tcpActiveOpens */ + *uint_ptr = tcpactiveopens; + break; + case 6: /* tcpPassiveOpens */ + *uint_ptr = tcppassiveopens; + break; + case 7: /* tcpAttemptFails */ + *uint_ptr = tcpattemptfails; + break; + case 8: /* tcpEstabResets */ + *uint_ptr = tcpestabresets; + break; + case 9: /* tcpCurrEstab */ + { + u16_t tcpcurrestab = 0; + struct tcp_pcb *pcb = tcp_active_pcbs; + while (pcb != NULL) + { + if ((pcb->state == ESTABLISHED) || + (pcb->state == CLOSE_WAIT)) + { + tcpcurrestab++; + } + pcb = pcb->next; + } + *uint_ptr = tcpcurrestab; + } + break; + case 10: /* tcpInSegs */ + *uint_ptr = tcpinsegs; + break; + case 11: /* tcpOutSegs */ + *uint_ptr = tcpoutsegs; + break; + case 12: /* tcpRetransSegs */ + *uint_ptr = tcpretranssegs; + break; + case 14: /* tcpInErrs */ + *uint_ptr = tcpinerrs; + break; + case 15: /* tcpOutRsts */ + *uint_ptr = tcpoutrsts; + break; + } +} +#ifdef THIS_SEEMS_UNUSED +static void +tcpconnentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od) +{ + /* return to object name, adding index depth (10) */ + ident_len += 10; + ident -= 10; + + if (ident_len == 11) + { + u8_t id; + + od->id_inst_len = ident_len; + od->id_inst_ptr = ident; + + id = ident[0]; + LWIP_DEBUGF(SNMP_MIB_DEBUG,("get_object_def tcp.%"U16_F".0\n",(u16_t)id)); + + switch (id) + { + case 1: /* tcpConnState */ + od->instance = MIB_OBJECT_TAB; + od->access = MIB_OBJECT_READ_WRITE; + od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG); + od->v_len = sizeof(s32_t); + break; + case 2: /* tcpConnLocalAddress */ + case 4: /* tcpConnRemAddress */ + od->instance = MIB_OBJECT_TAB; + od->access = MIB_OBJECT_READ_ONLY; + od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_IPADDR); + od->v_len = 4; + break; + case 3: /* tcpConnLocalPort */ + case 5: /* tcpConnRemPort */ + od->instance = MIB_OBJECT_TAB; + od->access = MIB_OBJECT_READ_ONLY; + od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG); + od->v_len = sizeof(s32_t); + break; + default: + LWIP_DEBUGF(SNMP_MIB_DEBUG,("tcpconnentry_get_object_def: no such object\n")); + od->instance = MIB_OBJECT_NONE; + break; + }; + } + else + { + LWIP_DEBUGF(SNMP_MIB_DEBUG,("tcpconnentry_get_object_def: no such object\n")); + od->instance = MIB_OBJECT_NONE; + } +} + +static void +tcpconnentry_get_value(struct obj_def *od, u16_t len, void *value) +{ + ip_addr_t lip, rip; + u16_t lport, rport; + s32_t *ident; + + ident = od->id_inst_ptr; + snmp_oidtoip(&ident[1], &lip); + lport = ident[5]; + snmp_oidtoip(&ident[6], &rip); + rport = ident[10]; + + /** @todo find matching PCB */ +} +#endif /* if 0 */ +#endif + +static void +udp_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od) +{ + /* return to object name, adding index depth (1) */ + ident_len += 1; + ident -= 1; + if ((ident_len == 2) && + (ident[0] > 0) && (ident[0] < 6)) + { + od->id_inst_len = ident_len; + od->id_inst_ptr = ident; + + od->instance = MIB_OBJECT_SCALAR; + od->access = MIB_OBJECT_READ_ONLY; + od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_COUNTER); + od->v_len = sizeof(u32_t); + } + else + { + LWIP_DEBUGF(SNMP_MIB_DEBUG,("udp_get_object_def: no scalar\n")); + od->instance = MIB_OBJECT_NONE; + } +} + +static void +udp_get_value(struct obj_def *od, u16_t len, void *value) +{ + u32_t *uint_ptr = (u32_t*)value; + u8_t id; + + LWIP_UNUSED_ARG(len); + LWIP_ASSERT("invalid id", (od->id_inst_ptr[0] >= 0) && (od->id_inst_ptr[0] <= 0xff)); + id = (u8_t)od->id_inst_ptr[0]; + switch (id) + { + case 1: /* udpInDatagrams */ + *uint_ptr = udpindatagrams; + break; + case 2: /* udpNoPorts */ + *uint_ptr = udpnoports; + break; + case 3: /* udpInErrors */ + *uint_ptr = udpinerrors; + break; + case 4: /* udpOutDatagrams */ + *uint_ptr = udpoutdatagrams; + break; + } +} + +static void +udpentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od) +{ + /* return to object name, adding index depth (5) */ + ident_len += 5; + ident -= 5; + + if (ident_len == 6) + { + od->id_inst_len = ident_len; + od->id_inst_ptr = ident; + + switch (ident[0]) + { + case 1: /* udpLocalAddress */ + od->instance = MIB_OBJECT_TAB; + od->access = MIB_OBJECT_READ_ONLY; + od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_IPADDR); + od->v_len = 4; + break; + case 2: /* udpLocalPort */ + od->instance = MIB_OBJECT_TAB; + od->access = MIB_OBJECT_READ_ONLY; + od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG); + od->v_len = sizeof(s32_t); + break; + default: + LWIP_DEBUGF(SNMP_MIB_DEBUG,("udpentry_get_object_def: no such object\n")); + od->instance = MIB_OBJECT_NONE; + break; + } + } + else + { + LWIP_DEBUGF(SNMP_MIB_DEBUG,("udpentry_get_object_def: no scalar\n")); + od->instance = MIB_OBJECT_NONE; + } +} + +static void +udpentry_get_value(struct obj_def *od, u16_t len, void *value) +{ + u8_t id; + struct udp_pcb *pcb; + ip_addr_t ip; + u16_t port; + + LWIP_UNUSED_ARG(len); + snmp_oidtoip(&od->id_inst_ptr[1], &ip); + LWIP_ASSERT("invalid port", (od->id_inst_ptr[5] >= 0) && (od->id_inst_ptr[5] <= 0xffff)); + port = (u16_t)od->id_inst_ptr[5]; + + pcb = udp_pcbs; + while ((pcb != NULL) && + !(ip_addr_cmp(&pcb->local_ip, &ip) && + (pcb->local_port == port))) + { + pcb = pcb->next; + } + + if (pcb != NULL) + { + LWIP_ASSERT("invalid id", (od->id_inst_ptr[0] >= 0) && (od->id_inst_ptr[0] <= 0xff)); + id = (u8_t)od->id_inst_ptr[0]; + switch (id) + { + case 1: /* udpLocalAddress */ + { + ip_addr_t *dst = (ip_addr_t*)value; + *dst = pcb->local_ip; + } + break; + case 2: /* udpLocalPort */ + { + s32_t *sint_ptr = (s32_t*)value; + *sint_ptr = pcb->local_port; + } + break; + } + } +} + +static void +snmp_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od) +{ + /* return to object name, adding index depth (1) */ + ident_len += 1; + ident -= 1; + if (ident_len == 2) + { + u8_t id; + + od->id_inst_len = ident_len; + od->id_inst_ptr = ident; + + LWIP_ASSERT("invalid id", (ident[0] >= 0) && (ident[0] <= 0xff)); + id = (u8_t)ident[0]; + switch (id) + { + case 1: /* snmpInPkts */ + case 2: /* snmpOutPkts */ + case 3: /* snmpInBadVersions */ + case 4: /* snmpInBadCommunityNames */ + case 5: /* snmpInBadCommunityUses */ + case 6: /* snmpInASNParseErrs */ + case 8: /* snmpInTooBigs */ + case 9: /* snmpInNoSuchNames */ + case 10: /* snmpInBadValues */ + case 11: /* snmpInReadOnlys */ + case 12: /* snmpInGenErrs */ + case 13: /* snmpInTotalReqVars */ + case 14: /* snmpInTotalSetVars */ + case 15: /* snmpInGetRequests */ + case 16: /* snmpInGetNexts */ + case 17: /* snmpInSetRequests */ + case 18: /* snmpInGetResponses */ + case 19: /* snmpInTraps */ + case 20: /* snmpOutTooBigs */ + case 21: /* snmpOutNoSuchNames */ + case 22: /* snmpOutBadValues */ + case 24: /* snmpOutGenErrs */ + case 25: /* snmpOutGetRequests */ + case 26: /* snmpOutGetNexts */ + case 27: /* snmpOutSetRequests */ + case 28: /* snmpOutGetResponses */ + case 29: /* snmpOutTraps */ + od->instance = MIB_OBJECT_SCALAR; + od->access = MIB_OBJECT_READ_ONLY; + od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_COUNTER); + od->v_len = sizeof(u32_t); + break; + case 30: /* snmpEnableAuthenTraps */ + od->instance = MIB_OBJECT_SCALAR; + od->access = MIB_OBJECT_READ_WRITE; + od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG); + od->v_len = sizeof(s32_t); + break; + default: + LWIP_DEBUGF(SNMP_MIB_DEBUG,("snmp_get_object_def: no such object\n")); + od->instance = MIB_OBJECT_NONE; + break; + }; + } + else + { + LWIP_DEBUGF(SNMP_MIB_DEBUG,("snmp_get_object_def: no scalar\n")); + od->instance = MIB_OBJECT_NONE; + } +} + +static void +snmp_get_value(struct obj_def *od, u16_t len, void *value) +{ + u32_t *uint_ptr = (u32_t*)value; + u8_t id; + + LWIP_UNUSED_ARG(len); + LWIP_ASSERT("invalid id", (od->id_inst_ptr[0] >= 0) && (od->id_inst_ptr[0] <= 0xff)); + id = (u8_t)od->id_inst_ptr[0]; + switch (id) + { + case 1: /* snmpInPkts */ + *uint_ptr = snmpinpkts; + break; + case 2: /* snmpOutPkts */ + *uint_ptr = snmpoutpkts; + break; + case 3: /* snmpInBadVersions */ + *uint_ptr = snmpinbadversions; + break; + case 4: /* snmpInBadCommunityNames */ + *uint_ptr = snmpinbadcommunitynames; + break; + case 5: /* snmpInBadCommunityUses */ + *uint_ptr = snmpinbadcommunityuses; + break; + case 6: /* snmpInASNParseErrs */ + *uint_ptr = snmpinasnparseerrs; + break; + case 8: /* snmpInTooBigs */ + *uint_ptr = snmpintoobigs; + break; + case 9: /* snmpInNoSuchNames */ + *uint_ptr = snmpinnosuchnames; + break; + case 10: /* snmpInBadValues */ + *uint_ptr = snmpinbadvalues; + break; + case 11: /* snmpInReadOnlys */ + *uint_ptr = snmpinreadonlys; + break; + case 12: /* snmpInGenErrs */ + *uint_ptr = snmpingenerrs; + break; + case 13: /* snmpInTotalReqVars */ + *uint_ptr = snmpintotalreqvars; + break; + case 14: /* snmpInTotalSetVars */ + *uint_ptr = snmpintotalsetvars; + break; + case 15: /* snmpInGetRequests */ + *uint_ptr = snmpingetrequests; + break; + case 16: /* snmpInGetNexts */ + *uint_ptr = snmpingetnexts; + break; + case 17: /* snmpInSetRequests */ + *uint_ptr = snmpinsetrequests; + break; + case 18: /* snmpInGetResponses */ + *uint_ptr = snmpingetresponses; + break; + case 19: /* snmpInTraps */ + *uint_ptr = snmpintraps; + break; + case 20: /* snmpOutTooBigs */ + *uint_ptr = snmpouttoobigs; + break; + case 21: /* snmpOutNoSuchNames */ + *uint_ptr = snmpoutnosuchnames; + break; + case 22: /* snmpOutBadValues */ + *uint_ptr = snmpoutbadvalues; + break; + case 24: /* snmpOutGenErrs */ + *uint_ptr = snmpoutgenerrs; + break; + case 25: /* snmpOutGetRequests */ + *uint_ptr = snmpoutgetrequests; + break; + case 26: /* snmpOutGetNexts */ + *uint_ptr = snmpoutgetnexts; + break; + case 27: /* snmpOutSetRequests */ + *uint_ptr = snmpoutsetrequests; + break; + case 28: /* snmpOutGetResponses */ + *uint_ptr = snmpoutgetresponses; + break; + case 29: /* snmpOutTraps */ + *uint_ptr = snmpouttraps; + break; + case 30: /* snmpEnableAuthenTraps */ + *uint_ptr = *snmpenableauthentraps_ptr; + break; + }; +} + +/** + * Test snmp object value before setting. + * + * @param od is the object definition + * @param len return value space (in bytes) + * @param value points to (varbind) space to copy value from. + */ +static u8_t +snmp_set_test(struct obj_def *od, u16_t len, void *value) +{ + u8_t id, set_ok; + + LWIP_UNUSED_ARG(len); + set_ok = 0; + LWIP_ASSERT("invalid id", (od->id_inst_ptr[0] >= 0) && (od->id_inst_ptr[0] <= 0xff)); + id = (u8_t)od->id_inst_ptr[0]; + if (id == 30) + { + /* snmpEnableAuthenTraps */ + s32_t *sint_ptr = (s32_t*)value; + + if (snmpenableauthentraps_ptr != &snmpenableauthentraps_default) + { + /* we should have writable non-volatile mem here */ + if ((*sint_ptr == 1) || (*sint_ptr == 2)) + { + set_ok = 1; + } + } + else + { + /* const or hardwired value */ + if (*sint_ptr == snmpenableauthentraps_default) + { + set_ok = 1; + } + } + } + return set_ok; +} + +static void +snmp_set_value(struct obj_def *od, u16_t len, void *value) +{ + u8_t id; + + LWIP_UNUSED_ARG(len); + LWIP_ASSERT("invalid id", (od->id_inst_ptr[0] >= 0) && (od->id_inst_ptr[0] <= 0xff)); + id = (u8_t)od->id_inst_ptr[0]; + if (id == 30) + { + /* snmpEnableAuthenTraps */ + /* @todo @fixme: which kind of pointer is 'value'? s32_t or u8_t??? */ + u8_t *ptr = (u8_t*)value; + *snmpenableauthentraps_ptr = *ptr; + } +} + +#endif /* LWIP_SNMP */ diff --git a/src/lwip-1.4.1/src/core/snmp/mib_structs.c b/src/lwip-1.4.1/src/core/snmp/mib_structs.c new file mode 100644 index 0000000..2f185cb --- /dev/null +++ b/src/lwip-1.4.1/src/core/snmp/mib_structs.c @@ -0,0 +1,1174 @@ +/** + * @file + * MIB tree access/construction functions. + */ + +/* + * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * Author: Christiaan Simons + */ + +#include "lwip/opt.h" + +#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/snmp_structs.h" +#include "lwip/memp.h" +#include "lwip/netif.h" + +/** .iso.org.dod.internet address prefix, @see snmp_iso_*() */ +const s32_t prefix[4] = {1, 3, 6, 1}; + +#define NODE_STACK_SIZE (LWIP_SNMP_OBJ_ID_LEN) +/** node stack entry (old news?) */ +struct nse +{ + /** right child */ + struct mib_node* r_ptr; + /** right child identifier */ + s32_t r_id; + /** right child next level */ + u8_t r_nl; +}; +static u8_t node_stack_cnt; +static struct nse node_stack[NODE_STACK_SIZE]; + +/** + * Pushes nse struct onto stack. + */ +static void +push_node(struct nse* node) +{ + LWIP_ASSERT("node_stack_cnt < NODE_STACK_SIZE",node_stack_cnt < NODE_STACK_SIZE); + LWIP_DEBUGF(SNMP_MIB_DEBUG,("push_node() node=%p id=%"S32_F"\n",(void*)(node->r_ptr),node->r_id)); + if (node_stack_cnt < NODE_STACK_SIZE) + { + node_stack[node_stack_cnt] = *node; + node_stack_cnt++; + } +} + +/** + * Pops nse struct from stack. + */ +static void +pop_node(struct nse* node) +{ + if (node_stack_cnt > 0) + { + node_stack_cnt--; + *node = node_stack[node_stack_cnt]; + } + LWIP_DEBUGF(SNMP_MIB_DEBUG,("pop_node() node=%p id=%"S32_F"\n",(void *)(node->r_ptr),node->r_id)); +} + +/** + * Conversion from ifIndex to lwIP netif + * @param ifindex is a s32_t object sub-identifier + * @param netif points to returned netif struct pointer + */ +void +snmp_ifindextonetif(s32_t ifindex, struct netif **netif) +{ + struct netif *nif = netif_list; + s32_t i, ifidx; + + ifidx = ifindex - 1; + i = 0; + while ((nif != NULL) && (i < ifidx)) + { + nif = nif->next; + i++; + } + *netif = nif; +} + +/** + * Conversion from lwIP netif to ifIndex + * @param netif points to a netif struct + * @param ifidx points to s32_t object sub-identifier + */ +void +snmp_netiftoifindex(struct netif *netif, s32_t *ifidx) +{ + struct netif *nif = netif_list; + u16_t i; + + i = 0; + while ((nif != NULL) && (nif != netif)) + { + nif = nif->next; + i++; + } + *ifidx = i+1; +} + +/** + * Conversion from oid to lwIP ip_addr + * @param ident points to s32_t ident[4] input + * @param ip points to output struct + */ +void +snmp_oidtoip(s32_t *ident, ip_addr_t *ip) +{ + IP4_ADDR(ip, ident[0], ident[1], ident[2], ident[3]); +} + +/** + * Conversion from lwIP ip_addr to oid + * @param ip points to input struct + * @param ident points to s32_t ident[4] output + */ +void +snmp_iptooid(ip_addr_t *ip, s32_t *ident) +{ + ident[0] = ip4_addr1(ip); + ident[1] = ip4_addr2(ip); + ident[2] = ip4_addr3(ip); + ident[3] = ip4_addr4(ip); +} + +struct mib_list_node * +snmp_mib_ln_alloc(s32_t id) +{ + struct mib_list_node *ln; + + ln = (struct mib_list_node *)memp_malloc(MEMP_SNMP_NODE); + if (ln != NULL) + { + ln->prev = NULL; + ln->next = NULL; + ln->objid = id; + ln->nptr = NULL; + } + return ln; +} + +void +snmp_mib_ln_free(struct mib_list_node *ln) +{ + memp_free(MEMP_SNMP_NODE, ln); +} + +struct mib_list_rootnode * +snmp_mib_lrn_alloc(void) +{ + struct mib_list_rootnode *lrn; + + lrn = (struct mib_list_rootnode*)memp_malloc(MEMP_SNMP_ROOTNODE); + if (lrn != NULL) + { + lrn->get_object_def = noleafs_get_object_def; + lrn->get_value = noleafs_get_value; + lrn->set_test = noleafs_set_test; + lrn->set_value = noleafs_set_value; + lrn->node_type = MIB_NODE_LR; + lrn->maxlength = 0; + lrn->head = NULL; + lrn->tail = NULL; + lrn->count = 0; + } + return lrn; +} + +void +snmp_mib_lrn_free(struct mib_list_rootnode *lrn) +{ + memp_free(MEMP_SNMP_ROOTNODE, lrn); +} + +/** + * Inserts node in idx list in a sorted + * (ascending order) fashion and + * allocates the node if needed. + * + * @param rn points to the root node + * @param objid is the object sub identifier + * @param insn points to a pointer to the inserted node + * used for constructing the tree. + * @return -1 if failed, 1 if inserted, 2 if present. + */ +s8_t +snmp_mib_node_insert(struct mib_list_rootnode *rn, s32_t objid, struct mib_list_node **insn) +{ + struct mib_list_node *nn; + s8_t insert; + + LWIP_ASSERT("rn != NULL",rn != NULL); + + /* -1 = malloc failure, 0 = not inserted, 1 = inserted, 2 = was present */ + insert = 0; + if (rn->head == NULL) + { + /* empty list, add first node */ + LWIP_DEBUGF(SNMP_MIB_DEBUG,("alloc empty list objid==%"S32_F"\n",objid)); + nn = snmp_mib_ln_alloc(objid); + if (nn != NULL) + { + rn->head = nn; + rn->tail = nn; + *insn = nn; + insert = 1; + } + else + { + insert = -1; + } + } + else + { + struct mib_list_node *n; + /* at least one node is present */ + n = rn->head; + while ((n != NULL) && (insert == 0)) + { + if (n->objid == objid) + { + /* node is already there */ + LWIP_DEBUGF(SNMP_MIB_DEBUG,("node already there objid==%"S32_F"\n",objid)); + *insn = n; + insert = 2; + } + else if (n->objid < objid) + { + if (n->next == NULL) + { + /* alloc and insert at the tail */ + LWIP_DEBUGF(SNMP_MIB_DEBUG,("alloc ins tail objid==%"S32_F"\n",objid)); + nn = snmp_mib_ln_alloc(objid); + if (nn != NULL) + { + nn->next = NULL; + nn->prev = n; + n->next = nn; + rn->tail = nn; + *insn = nn; + insert = 1; + } + else + { + /* insertion failure */ + insert = -1; + } + } + else + { + /* there's more to explore: traverse list */ + LWIP_DEBUGF(SNMP_MIB_DEBUG,("traverse list\n")); + n = n->next; + } + } + else + { + /* n->objid > objid */ + /* alloc and insert between n->prev and n */ + LWIP_DEBUGF(SNMP_MIB_DEBUG,("alloc ins n->prev, objid==%"S32_F", n\n",objid)); + nn = snmp_mib_ln_alloc(objid); + if (nn != NULL) + { + if (n->prev == NULL) + { + /* insert at the head */ + nn->next = n; + nn->prev = NULL; + rn->head = nn; + n->prev = nn; + } + else + { + /* insert in the middle */ + nn->next = n; + nn->prev = n->prev; + n->prev->next = nn; + n->prev = nn; + } + *insn = nn; + insert = 1; + } + else + { + /* insertion failure */ + insert = -1; + } + } + } + } + if (insert == 1) + { + rn->count += 1; + } + LWIP_ASSERT("insert != 0",insert != 0); + return insert; +} + +/** + * Finds node in idx list and returns deletion mark. + * + * @param rn points to the root node + * @param objid is the object sub identifier + * @param fn returns pointer to found node + * @return 0 if not found, 1 if deletable, + * 2 can't delete (2 or more children), 3 not a list_node + */ +s8_t +snmp_mib_node_find(struct mib_list_rootnode *rn, s32_t objid, struct mib_list_node **fn) +{ + s8_t fc; + struct mib_list_node *n; + + LWIP_ASSERT("rn != NULL",rn != NULL); + n = rn->head; + while ((n != NULL) && (n->objid != objid)) + { + n = n->next; + } + if (n == NULL) + { + fc = 0; + } + else if (n->nptr == NULL) + { + /* leaf, can delete node */ + fc = 1; + } + else + { + struct mib_list_rootnode *r; + + if (n->nptr->node_type == MIB_NODE_LR) + { + r = (struct mib_list_rootnode *)n->nptr; + if (r->count > 1) + { + /* can't delete node */ + fc = 2; + } + else + { + /* count <= 1, can delete node */ + fc = 1; + } + } + else + { + /* other node type */ + fc = 3; + } + } + *fn = n; + return fc; +} + +/** + * Removes node from idx list + * if it has a single child left. + * + * @param rn points to the root node + * @param n points to the node to delete + * @return the nptr to be freed by caller + */ +struct mib_list_rootnode * +snmp_mib_node_delete(struct mib_list_rootnode *rn, struct mib_list_node *n) +{ + struct mib_list_rootnode *next; + + LWIP_ASSERT("rn != NULL",rn != NULL); + LWIP_ASSERT("n != NULL",n != NULL); + + /* caller must remove this sub-tree */ + next = (struct mib_list_rootnode*)(n->nptr); + rn->count -= 1; + + if (n == rn->head) + { + rn->head = n->next; + if (n->next != NULL) + { + /* not last node, new list begin */ + n->next->prev = NULL; + } + } + else if (n == rn->tail) + { + rn->tail = n->prev; + if (n->prev != NULL) + { + /* not last node, new list end */ + n->prev->next = NULL; + } + } + else + { + /* node must be in the middle */ + n->prev->next = n->next; + n->next->prev = n->prev; + } + LWIP_DEBUGF(SNMP_MIB_DEBUG,("free list objid==%"S32_F"\n",n->objid)); + snmp_mib_ln_free(n); + if (rn->count == 0) + { + rn->head = NULL; + rn->tail = NULL; + } + return next; +} + + + +/** + * Searches tree for the supplied (scalar?) object identifier. + * + * @param node points to the root of the tree ('.internet') + * @param ident_len the length of the supplied object identifier + * @param ident points to the array of sub identifiers + * @param np points to the found object instance (return) + * @return pointer to the requested parent (!) node if success, NULL otherwise + */ +struct mib_node * +snmp_search_tree(struct mib_node *node, u8_t ident_len, s32_t *ident, struct snmp_name_ptr *np) +{ + u8_t node_type, ext_level; + + ext_level = 0; + LWIP_DEBUGF(SNMP_MIB_DEBUG,("node==%p *ident==%"S32_F"\n",(void*)node,*ident)); + while (node != NULL) + { + node_type = node->node_type; + if ((node_type == MIB_NODE_AR) || (node_type == MIB_NODE_RA)) + { + struct mib_array_node *an; + u16_t i; + + if (ident_len > 0) + { + /* array node (internal ROM or RAM, fixed length) */ + an = (struct mib_array_node *)node; + i = 0; + while ((i < an->maxlength) && (an->objid[i] != *ident)) + { + i++; + } + if (i < an->maxlength) + { + /* found it, if available proceed to child, otherwise inspect leaf */ + LWIP_DEBUGF(SNMP_MIB_DEBUG,("an->objid[%"U16_F"]==%"S32_F" *ident==%"S32_F"\n",i,an->objid[i],*ident)); + if (an->nptr[i] == NULL) + { + /* a scalar leaf OR table, + inspect remaining instance number / table index */ + np->ident_len = ident_len; + np->ident = ident; + return (struct mib_node*)an; + } + else + { + /* follow next child pointer */ + ident++; + ident_len--; + node = an->nptr[i]; + } + } + else + { + /* search failed, identifier mismatch (nosuchname) */ + LWIP_DEBUGF(SNMP_MIB_DEBUG,("an search failed *ident==%"S32_F"\n",*ident)); + return NULL; + } + } + else + { + /* search failed, short object identifier (nosuchname) */ + LWIP_DEBUGF(SNMP_MIB_DEBUG,("an search failed, short object identifier\n")); + return NULL; + } + } + else if(node_type == MIB_NODE_LR) + { + struct mib_list_rootnode *lrn; + struct mib_list_node *ln; + + if (ident_len > 0) + { + /* list root node (internal 'RAM', variable length) */ + lrn = (struct mib_list_rootnode *)node; + ln = lrn->head; + /* iterate over list, head to tail */ + while ((ln != NULL) && (ln->objid != *ident)) + { + ln = ln->next; + } + if (ln != NULL) + { + /* found it, proceed to child */; + LWIP_DEBUGF(SNMP_MIB_DEBUG,("ln->objid==%"S32_F" *ident==%"S32_F"\n",ln->objid,*ident)); + if (ln->nptr == NULL) + { + np->ident_len = ident_len; + np->ident = ident; + return (struct mib_node*)lrn; + } + else + { + /* follow next child pointer */ + ident_len--; + ident++; + node = ln->nptr; + } + } + else + { + /* search failed */ + LWIP_DEBUGF(SNMP_MIB_DEBUG,("ln search failed *ident==%"S32_F"\n",*ident)); + return NULL; + } + } + else + { + /* search failed, short object identifier (nosuchname) */ + LWIP_DEBUGF(SNMP_MIB_DEBUG,("ln search failed, short object identifier\n")); + return NULL; + } + } + else if(node_type == MIB_NODE_EX) + { + struct mib_external_node *en; + u16_t i, len; + + if (ident_len > 0) + { + /* external node (addressing and access via functions) */ + en = (struct mib_external_node *)node; + + i = 0; + len = en->level_length(en->addr_inf,ext_level); + while ((i < len) && (en->ident_cmp(en->addr_inf,ext_level,i,*ident) != 0)) + { + i++; + } + if (i < len) + { + s32_t debug_id; + + en->get_objid(en->addr_inf,ext_level,i,&debug_id); + LWIP_DEBUGF(SNMP_MIB_DEBUG,("en->objid==%"S32_F" *ident==%"S32_F"\n",debug_id,*ident)); + if ((ext_level + 1) == en->tree_levels) + { + np->ident_len = ident_len; + np->ident = ident; + return (struct mib_node*)en; + } + else + { + /* found it, proceed to child */ + ident_len--; + ident++; + ext_level++; + } + } + else + { + /* search failed */ + LWIP_DEBUGF(SNMP_MIB_DEBUG,("en search failed *ident==%"S32_F"\n",*ident)); + return NULL; + } + } + else + { + /* search failed, short object identifier (nosuchname) */ + LWIP_DEBUGF(SNMP_MIB_DEBUG,("en search failed, short object identifier\n")); + return NULL; + } + } + else if (node_type == MIB_NODE_SC) + { + mib_scalar_node *sn; + + sn = (mib_scalar_node *)node; + if ((ident_len == 1) && (*ident == 0)) + { + np->ident_len = ident_len; + np->ident = ident; + return (struct mib_node*)sn; + } + else + { + /* search failed, short object identifier (nosuchname) */ + LWIP_DEBUGF(SNMP_MIB_DEBUG,("search failed, invalid object identifier length\n")); + return NULL; + } + } + else + { + /* unknown node_type */ + LWIP_DEBUGF(SNMP_MIB_DEBUG,("search failed node_type %"U16_F" unkown\n",(u16_t)node_type)); + return NULL; + } + } + /* done, found nothing */ + LWIP_DEBUGF(SNMP_MIB_DEBUG,("search failed node==%p\n",(void*)node)); + return NULL; +} + +/** + * Test table for presence of at least one table entry. + */ +static u8_t +empty_table(struct mib_node *node) +{ + u8_t node_type; + u8_t empty = 0; + + if (node != NULL) + { + node_type = node->node_type; + if (node_type == MIB_NODE_LR) + { + struct mib_list_rootnode *lrn; + lrn = (struct mib_list_rootnode *)node; + if ((lrn->count == 0) || (lrn->head == NULL)) + { + empty = 1; + } + } + else if ((node_type == MIB_NODE_AR) || (node_type == MIB_NODE_RA)) + { + struct mib_array_node *an; + an = (struct mib_array_node *)node; + if ((an->maxlength == 0) || (an->nptr == NULL)) + { + empty = 1; + } + } + else if (node_type == MIB_NODE_EX) + { + struct mib_external_node *en; + en = (struct mib_external_node *)node; + if (en->tree_levels == 0) + { + empty = 1; + } + } + } + return empty; +} + +/** + * Tree expansion. + */ +struct mib_node * +snmp_expand_tree(struct mib_node *node, u8_t ident_len, s32_t *ident, struct snmp_obj_id *oidret) +{ + u8_t node_type, ext_level, climb_tree; + + ext_level = 0; + /* reset node stack */ + node_stack_cnt = 0; + while (node != NULL) + { + climb_tree = 0; + node_type = node->node_type; + if ((node_type == MIB_NODE_AR) || (node_type == MIB_NODE_RA)) + { + struct mib_array_node *an; + u16_t i; + + /* array node (internal ROM or RAM, fixed length) */ + an = (struct mib_array_node *)node; + if (ident_len > 0) + { + i = 0; + while ((i < an->maxlength) && (an->objid[i] < *ident)) + { + i++; + } + if (i < an->maxlength) + { + LWIP_DEBUGF(SNMP_MIB_DEBUG,("an->objid[%"U16_F"]==%"S32_F" *ident==%"S32_F"\n",i,an->objid[i],*ident)); + /* add identifier to oidret */ + oidret->id[oidret->len] = an->objid[i]; + (oidret->len)++; + + if (an->nptr[i] == NULL) + { + LWIP_DEBUGF(SNMP_MIB_DEBUG,("leaf node\n")); + /* leaf node (e.g. in a fixed size table) */ + if (an->objid[i] > *ident) + { + return (struct mib_node*)an; + } + else if ((i + 1) < an->maxlength) + { + /* an->objid[i] == *ident */ + (oidret->len)--; + oidret->id[oidret->len] = an->objid[i + 1]; + (oidret->len)++; + return (struct mib_node*)an; + } + else + { + /* (i + 1) == an->maxlength */ + (oidret->len)--; + climb_tree = 1; + } + } + else + { + u8_t j; + struct nse cur_node; + + LWIP_DEBUGF(SNMP_MIB_DEBUG,("non-leaf node\n")); + /* non-leaf, store right child ptr and id */ + LWIP_ASSERT("i < 0xff", i < 0xff); + j = (u8_t)i + 1; + while ((j < an->maxlength) && (empty_table(an->nptr[j]))) + { + j++; + } + if (j < an->maxlength) + { + cur_node.r_ptr = an->nptr[j]; + cur_node.r_id = an->objid[j]; + cur_node.r_nl = 0; + } + else + { + cur_node.r_ptr = NULL; + } + push_node(&cur_node); + if (an->objid[i] == *ident) + { + ident_len--; + ident++; + } + else + { + /* an->objid[i] < *ident */ + ident_len = 0; + } + /* follow next child pointer */ + node = an->nptr[i]; + } + } + else + { + /* i == an->maxlength */ + climb_tree = 1; + } + } + else + { + u8_t j; + /* ident_len == 0, complete with leftmost '.thing' */ + j = 0; + while ((j < an->maxlength) && empty_table(an->nptr[j])) + { + j++; + } + if (j < an->maxlength) + { + LWIP_DEBUGF(SNMP_MIB_DEBUG,("left an->objid[j]==%"S32_F"\n",an->objid[j])); + oidret->id[oidret->len] = an->objid[j]; + (oidret->len)++; + if (an->nptr[j] == NULL) + { + /* leaf node */ + return (struct mib_node*)an; + } + else + { + /* no leaf, continue */ + node = an->nptr[j]; + } + } + else + { + /* j == an->maxlength */ + climb_tree = 1; + } + } + } + else if(node_type == MIB_NODE_LR) + { + struct mib_list_rootnode *lrn; + struct mib_list_node *ln; + + /* list root node (internal 'RAM', variable length) */ + lrn = (struct mib_list_rootnode *)node; + if (ident_len > 0) + { + ln = lrn->head; + /* iterate over list, head to tail */ + while ((ln != NULL) && (ln->objid < *ident)) + { + ln = ln->next; + } + if (ln != NULL) + { + LWIP_DEBUGF(SNMP_MIB_DEBUG,("ln->objid==%"S32_F" *ident==%"S32_F"\n",ln->objid,*ident)); + oidret->id[oidret->len] = ln->objid; + (oidret->len)++; + if (ln->nptr == NULL) + { + /* leaf node */ + if (ln->objid > *ident) + { + return (struct mib_node*)lrn; + } + else if (ln->next != NULL) + { + /* ln->objid == *ident */ + (oidret->len)--; + oidret->id[oidret->len] = ln->next->objid; + (oidret->len)++; + return (struct mib_node*)lrn; + } + else + { + /* ln->next == NULL */ + (oidret->len)--; + climb_tree = 1; + } + } + else + { + struct mib_list_node *jn; + struct nse cur_node; + + /* non-leaf, store right child ptr and id */ + jn = ln->next; + while ((jn != NULL) && empty_table(jn->nptr)) + { + jn = jn->next; + } + if (jn != NULL) + { + cur_node.r_ptr = jn->nptr; + cur_node.r_id = jn->objid; + cur_node.r_nl = 0; + } + else + { + cur_node.r_ptr = NULL; + } + push_node(&cur_node); + if (ln->objid == *ident) + { + ident_len--; + ident++; + } + else + { + /* ln->objid < *ident */ + ident_len = 0; + } + /* follow next child pointer */ + node = ln->nptr; + } + + } + else + { + /* ln == NULL */ + climb_tree = 1; + } + } + else + { + struct mib_list_node *jn; + /* ident_len == 0, complete with leftmost '.thing' */ + jn = lrn->head; + while ((jn != NULL) && empty_table(jn->nptr)) + { + jn = jn->next; + } + if (jn != NULL) + { + LWIP_DEBUGF(SNMP_MIB_DEBUG,("left jn->objid==%"S32_F"\n",jn->objid)); + oidret->id[oidret->len] = jn->objid; + (oidret->len)++; + if (jn->nptr == NULL) + { + /* leaf node */ + LWIP_DEBUGF(SNMP_MIB_DEBUG,("jn->nptr == NULL\n")); + return (struct mib_node*)lrn; + } + else + { + /* no leaf, continue */ + node = jn->nptr; + } + } + else + { + /* jn == NULL */ + climb_tree = 1; + } + } + } + else if(node_type == MIB_NODE_EX) + { + struct mib_external_node *en; + s32_t ex_id; + + /* external node (addressing and access via functions) */ + en = (struct mib_external_node *)node; + if (ident_len > 0) + { + u16_t i, len; + + i = 0; + len = en->level_length(en->addr_inf,ext_level); + while ((i < len) && (en->ident_cmp(en->addr_inf,ext_level,i,*ident) < 0)) + { + i++; + } + if (i < len) + { + /* add identifier to oidret */ + en->get_objid(en->addr_inf,ext_level,i,&ex_id); + LWIP_DEBUGF(SNMP_MIB_DEBUG,("en->objid[%"U16_F"]==%"S32_F" *ident==%"S32_F"\n",i,ex_id,*ident)); + oidret->id[oidret->len] = ex_id; + (oidret->len)++; + + if ((ext_level + 1) == en->tree_levels) + { + LWIP_DEBUGF(SNMP_MIB_DEBUG,("leaf node\n")); + /* leaf node */ + if (ex_id > *ident) + { + return (struct mib_node*)en; + } + else if ((i + 1) < len) + { + /* ex_id == *ident */ + en->get_objid(en->addr_inf,ext_level,i + 1,&ex_id); + (oidret->len)--; + oidret->id[oidret->len] = ex_id; + (oidret->len)++; + return (struct mib_node*)en; + } + else + { + /* (i + 1) == len */ + (oidret->len)--; + climb_tree = 1; + } + } + else + { + u8_t j; + struct nse cur_node; + + LWIP_DEBUGF(SNMP_MIB_DEBUG,("non-leaf node\n")); + /* non-leaf, store right child ptr and id */ + LWIP_ASSERT("i < 0xff", i < 0xff); + j = (u8_t)i + 1; + if (j < len) + { + /* right node is the current external node */ + cur_node.r_ptr = node; + en->get_objid(en->addr_inf,ext_level,j,&cur_node.r_id); + cur_node.r_nl = ext_level + 1; + } + else + { + cur_node.r_ptr = NULL; + } + push_node(&cur_node); + if (en->ident_cmp(en->addr_inf,ext_level,i,*ident) == 0) + { + ident_len--; + ident++; + } + else + { + /* external id < *ident */ + ident_len = 0; + } + /* proceed to child */ + ext_level++; + } + } + else + { + /* i == len (en->level_len()) */ + climb_tree = 1; + } + } + else + { + /* ident_len == 0, complete with leftmost '.thing' */ + en->get_objid(en->addr_inf,ext_level,0,&ex_id); + LWIP_DEBUGF(SNMP_MIB_DEBUG,("left en->objid==%"S32_F"\n",ex_id)); + oidret->id[oidret->len] = ex_id; + (oidret->len)++; + if ((ext_level + 1) == en->tree_levels) + { + /* leaf node */ + LWIP_DEBUGF(SNMP_MIB_DEBUG,("(ext_level + 1) == en->tree_levels\n")); + return (struct mib_node*)en; + } + else + { + /* no leaf, proceed to child */ + ext_level++; + } + } + } + else if(node_type == MIB_NODE_SC) + { + mib_scalar_node *sn; + + /* scalar node */ + sn = (mib_scalar_node *)node; + if (ident_len > 0) + { + /* at .0 */ + climb_tree = 1; + } + else + { + /* ident_len == 0, complete object identifier */ + oidret->id[oidret->len] = 0; + (oidret->len)++; + /* leaf node */ + LWIP_DEBUGF(SNMP_MIB_DEBUG,("completed scalar leaf\n")); + return (struct mib_node*)sn; + } + } + else + { + /* unknown/unhandled node_type */ + LWIP_DEBUGF(SNMP_MIB_DEBUG,("expand failed node_type %"U16_F" unkown\n",(u16_t)node_type)); + return NULL; + } + + if (climb_tree) + { + struct nse child; + + /* find right child ptr */ + child.r_ptr = NULL; + child.r_id = 0; + child.r_nl = 0; + while ((node_stack_cnt > 0) && (child.r_ptr == NULL)) + { + pop_node(&child); + /* trim returned oid */ + (oidret->len)--; + } + if (child.r_ptr != NULL) + { + /* incoming ident is useless beyond this point */ + ident_len = 0; + oidret->id[oidret->len] = child.r_id; + oidret->len++; + node = child.r_ptr; + ext_level = child.r_nl; + } + else + { + /* tree ends here ... */ + LWIP_DEBUGF(SNMP_MIB_DEBUG,("expand failed, tree ends here\n")); + return NULL; + } + } + } + /* done, found nothing */ + LWIP_DEBUGF(SNMP_MIB_DEBUG,("expand failed node==%p\n",(void*)node)); + return NULL; +} + +/** + * Test object identifier for the iso.org.dod.internet prefix. + * + * @param ident_len the length of the supplied object identifier + * @param ident points to the array of sub identifiers + * @return 1 if it matches, 0 otherwise + */ +u8_t +snmp_iso_prefix_tst(u8_t ident_len, s32_t *ident) +{ + if ((ident_len > 3) && + (ident[0] == 1) && (ident[1] == 3) && + (ident[2] == 6) && (ident[3] == 1)) + { + return 1; + } + else + { + return 0; + } +} + +/** + * Expands object identifier to the iso.org.dod.internet + * prefix for use in getnext operation. + * + * @param ident_len the length of the supplied object identifier + * @param ident points to the array of sub identifiers + * @param oidret points to returned expanded object identifier + * @return 1 if it matches, 0 otherwise + * + * @note ident_len 0 is allowed, expanding to the first known object id!! + */ +u8_t +snmp_iso_prefix_expand(u8_t ident_len, s32_t *ident, struct snmp_obj_id *oidret) +{ + const s32_t *prefix_ptr; + s32_t *ret_ptr; + u8_t i; + + i = 0; + prefix_ptr = &prefix[0]; + ret_ptr = &oidret->id[0]; + ident_len = ((ident_len < 4)?ident_len:4); + while ((i < ident_len) && ((*ident) <= (*prefix_ptr))) + { + *ret_ptr++ = *prefix_ptr++; + ident++; + i++; + } + if (i == ident_len) + { + /* match, complete missing bits */ + while (i < 4) + { + *ret_ptr++ = *prefix_ptr++; + i++; + } + oidret->len = i; + return 1; + } + else + { + /* i != ident_len */ + return 0; + } +} + +#endif /* LWIP_SNMP */ diff --git a/src/lwip-1.4.1/src/core/snmp/msg_in.c b/src/lwip-1.4.1/src/core/snmp/msg_in.c new file mode 100644 index 0000000..be940c6 --- /dev/null +++ b/src/lwip-1.4.1/src/core/snmp/msg_in.c @@ -0,0 +1,1453 @@ +/** + * @file + * SNMP input message processing (RFC1157). + */ + +/* + * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * Author: Christiaan Simons + */ + +#include "lwip/opt.h" + +#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/snmp.h" +#include "lwip/snmp_asn1.h" +#include "lwip/snmp_msg.h" +#include "lwip/snmp_structs.h" +#include "lwip/ip_addr.h" +#include "lwip/memp.h" +#include "lwip/udp.h" +#include "lwip/stats.h" + +#include + +/* public (non-static) constants */ +/** SNMP v1 == 0 */ +const s32_t snmp_version = 0; +/** default SNMP community string */ +const char snmp_publiccommunity[7] = "public"; + +/* statically allocated buffers for SNMP_CONCURRENT_REQUESTS */ +struct snmp_msg_pstat msg_input_list[SNMP_CONCURRENT_REQUESTS]; +/* UDP Protocol Control Block */ +struct udp_pcb *snmp1_pcb; + +static void snmp_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, ip_addr_t *addr, u16_t port); +static err_t snmp_pdu_header_check(struct pbuf *p, u16_t ofs, u16_t pdu_len, u16_t *ofs_ret, struct snmp_msg_pstat *m_stat); +static err_t snmp_pdu_dec_varbindlist(struct pbuf *p, u16_t ofs, u16_t *ofs_ret, struct snmp_msg_pstat *m_stat); + + +/** + * Starts SNMP Agent. + * Allocates UDP pcb and binds it to IP_ADDR_ANY port 161. + */ +void +snmp_init(void) +{ + struct snmp_msg_pstat *msg_ps; + u8_t i; + + snmp1_pcb = udp_new(); + if (snmp1_pcb != NULL) + { + udp_recv(snmp1_pcb, snmp_recv, (void *)SNMP_IN_PORT); + udp_bind(snmp1_pcb, IP_ADDR_ANY, SNMP_IN_PORT); + } + msg_ps = &msg_input_list[0]; + for (i=0; istate = SNMP_MSG_EMPTY; + msg_ps->error_index = 0; + msg_ps->error_status = SNMP_ES_NOERROR; + msg_ps++; + } + trap_msg.pcb = snmp1_pcb; + +#ifdef SNMP_PRIVATE_MIB_INIT + /* If defined, this must be a function-like define to initialize the + * private MIB after the stack has been initialized. + * The private MIB can also be initialized in tcpip_callback (or after + * the stack is initialized), this define is only for convenience. */ + SNMP_PRIVATE_MIB_INIT(); +#endif /* SNMP_PRIVATE_MIB_INIT */ + + /* The coldstart trap will only be output + if our outgoing interface is up & configured */ + snmp_coldstart_trap(); +} + +static void +snmp_error_response(struct snmp_msg_pstat *msg_ps, u8_t error) +{ + /* move names back from outvb to invb */ + int v; + struct snmp_varbind *vbi = msg_ps->invb.head; + struct snmp_varbind *vbo = msg_ps->outvb.head; + for (v=0; vvb_idx; v++) { + vbi->ident_len = vbo->ident_len; + vbo->ident_len = 0; + vbi->ident = vbo->ident; + vbo->ident = NULL; + vbi = vbi->next; + vbo = vbo->next; + } + /* free outvb */ + snmp_varbind_list_free(&msg_ps->outvb); + /* we send invb back */ + msg_ps->outvb = msg_ps->invb; + msg_ps->invb.head = NULL; + msg_ps->invb.tail = NULL; + msg_ps->invb.count = 0; + msg_ps->error_status = error; + /* error index must be 0 for error too big */ + msg_ps->error_index = (error != SNMP_ES_TOOBIG) ? (1 + msg_ps->vb_idx) : 0; + snmp_send_response(msg_ps); + snmp_varbind_list_free(&msg_ps->outvb); + msg_ps->state = SNMP_MSG_EMPTY; +} + +static void +snmp_ok_response(struct snmp_msg_pstat *msg_ps) +{ + err_t err_ret; + + err_ret = snmp_send_response(msg_ps); + if (err_ret == ERR_MEM) + { + /* serious memory problem, can't return tooBig */ + } + else + { + LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_msg_event = %"S32_F"\n",msg_ps->error_status)); + } + /* free varbinds (if available) */ + snmp_varbind_list_free(&msg_ps->invb); + snmp_varbind_list_free(&msg_ps->outvb); + msg_ps->state = SNMP_MSG_EMPTY; +} + +/** + * Service an internal or external event for SNMP GET. + * + * @param request_id identifies requests from 0 to (SNMP_CONCURRENT_REQUESTS-1) + * @param msg_ps points to the assosicated message process state + */ +static void +snmp_msg_get_event(u8_t request_id, struct snmp_msg_pstat *msg_ps) +{ + LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_msg_get_event: msg_ps->state==%"U16_F"\n",(u16_t)msg_ps->state)); + + if (msg_ps->state == SNMP_MSG_EXTERNAL_GET_OBJDEF) + { + struct mib_external_node *en; + struct snmp_name_ptr np; + + /* get_object_def() answer*/ + en = msg_ps->ext_mib_node; + np = msg_ps->ext_name_ptr; + + /* translate answer into a known lifeform */ + en->get_object_def_a(request_id, np.ident_len, np.ident, &msg_ps->ext_object_def); + if ((msg_ps->ext_object_def.instance != MIB_OBJECT_NONE) && + (msg_ps->ext_object_def.access & MIB_ACCESS_READ)) + { + msg_ps->state = SNMP_MSG_EXTERNAL_GET_VALUE; + en->get_value_q(request_id, &msg_ps->ext_object_def); + } + else + { + en->get_object_def_pc(request_id, np.ident_len, np.ident); + /* search failed, object id points to unknown object (nosuchname) */ + snmp_error_response(msg_ps,SNMP_ES_NOSUCHNAME); + } + } + else if (msg_ps->state == SNMP_MSG_EXTERNAL_GET_VALUE) + { + struct mib_external_node *en; + struct snmp_varbind *vb; + + /* get_value() answer */ + en = msg_ps->ext_mib_node; + + /* allocate output varbind */ + vb = (struct snmp_varbind *)memp_malloc(MEMP_SNMP_VARBIND); + if (vb != NULL) + { + vb->next = NULL; + vb->prev = NULL; + + /* move name from invb to outvb */ + vb->ident = msg_ps->vb_ptr->ident; + vb->ident_len = msg_ps->vb_ptr->ident_len; + /* ensure this memory is refereced once only */ + msg_ps->vb_ptr->ident = NULL; + msg_ps->vb_ptr->ident_len = 0; + + vb->value_type = msg_ps->ext_object_def.asn_type; + LWIP_ASSERT("invalid length", msg_ps->ext_object_def.v_len <= 0xff); + vb->value_len = (u8_t)msg_ps->ext_object_def.v_len; + if (vb->value_len > 0) + { + LWIP_ASSERT("SNMP_MAX_OCTET_STRING_LEN is configured too low", vb->value_len <= SNMP_MAX_VALUE_SIZE); + vb->value = memp_malloc(MEMP_SNMP_VALUE); + if (vb->value != NULL) + { + en->get_value_a(request_id, &msg_ps->ext_object_def, vb->value_len, vb->value); + snmp_varbind_tail_add(&msg_ps->outvb, vb); + /* search again (if vb_idx < msg_ps->invb.count) */ + msg_ps->state = SNMP_MSG_SEARCH_OBJ; + msg_ps->vb_idx += 1; + } + else + { + en->get_value_pc(request_id, &msg_ps->ext_object_def); + LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_msg_event: no variable space\n")); + msg_ps->vb_ptr->ident = vb->ident; + msg_ps->vb_ptr->ident_len = vb->ident_len; + memp_free(MEMP_SNMP_VARBIND, vb); + snmp_error_response(msg_ps,SNMP_ES_TOOBIG); + } + } + else + { + /* vb->value_len == 0, empty value (e.g. empty string) */ + en->get_value_a(request_id, &msg_ps->ext_object_def, 0, NULL); + vb->value = NULL; + snmp_varbind_tail_add(&msg_ps->outvb, vb); + /* search again (if vb_idx < msg_ps->invb.count) */ + msg_ps->state = SNMP_MSG_SEARCH_OBJ; + msg_ps->vb_idx += 1; + } + } + else + { + en->get_value_pc(request_id, &msg_ps->ext_object_def); + LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_msg_event: no outvb space\n")); + snmp_error_response(msg_ps,SNMP_ES_TOOBIG); + } + } + + while ((msg_ps->state == SNMP_MSG_SEARCH_OBJ) && + (msg_ps->vb_idx < msg_ps->invb.count)) + { + struct mib_node *mn; + struct snmp_name_ptr np; + + if (msg_ps->vb_idx == 0) + { + msg_ps->vb_ptr = msg_ps->invb.head; + } + else + { + msg_ps->vb_ptr = msg_ps->vb_ptr->next; + } + /** test object identifier for .iso.org.dod.internet prefix */ + if (snmp_iso_prefix_tst(msg_ps->vb_ptr->ident_len, msg_ps->vb_ptr->ident)) + { + mn = snmp_search_tree((struct mib_node*)&internet, msg_ps->vb_ptr->ident_len - 4, + msg_ps->vb_ptr->ident + 4, &np); + if (mn != NULL) + { + if (mn->node_type == MIB_NODE_EX) + { + /* external object */ + struct mib_external_node *en = (struct mib_external_node*)mn; + + msg_ps->state = SNMP_MSG_EXTERNAL_GET_OBJDEF; + /* save en && args in msg_ps!! */ + msg_ps->ext_mib_node = en; + msg_ps->ext_name_ptr = np; + + en->get_object_def_q(en->addr_inf, request_id, np.ident_len, np.ident); + } + else + { + /* internal object */ + struct obj_def object_def; + + msg_ps->state = SNMP_MSG_INTERNAL_GET_OBJDEF; + mn->get_object_def(np.ident_len, np.ident, &object_def); + if ((object_def.instance != MIB_OBJECT_NONE) && + (object_def.access & MIB_ACCESS_READ)) + { + mn = mn; + } + else + { + /* search failed, object id points to unknown object (nosuchname) */ + mn = NULL; + } + if (mn != NULL) + { + struct snmp_varbind *vb; + + msg_ps->state = SNMP_MSG_INTERNAL_GET_VALUE; + /* allocate output varbind */ + vb = (struct snmp_varbind *)memp_malloc(MEMP_SNMP_VARBIND); + if (vb != NULL) + { + vb->next = NULL; + vb->prev = NULL; + + /* move name from invb to outvb */ + vb->ident = msg_ps->vb_ptr->ident; + vb->ident_len = msg_ps->vb_ptr->ident_len; + /* ensure this memory is refereced once only */ + msg_ps->vb_ptr->ident = NULL; + msg_ps->vb_ptr->ident_len = 0; + + vb->value_type = object_def.asn_type; + LWIP_ASSERT("invalid length", object_def.v_len <= 0xff); + vb->value_len = (u8_t)object_def.v_len; + if (vb->value_len > 0) + { + LWIP_ASSERT("SNMP_MAX_OCTET_STRING_LEN is configured too low", + vb->value_len <= SNMP_MAX_VALUE_SIZE); + vb->value = memp_malloc(MEMP_SNMP_VALUE); + if (vb->value != NULL) + { + mn->get_value(&object_def, vb->value_len, vb->value); + snmp_varbind_tail_add(&msg_ps->outvb, vb); + msg_ps->state = SNMP_MSG_SEARCH_OBJ; + msg_ps->vb_idx += 1; + } + else + { + LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_msg_event: couldn't allocate variable space\n")); + msg_ps->vb_ptr->ident = vb->ident; + msg_ps->vb_ptr->ident_len = vb->ident_len; + vb->ident = NULL; + vb->ident_len = 0; + memp_free(MEMP_SNMP_VARBIND, vb); + snmp_error_response(msg_ps,SNMP_ES_TOOBIG); + } + } + else + { + /* vb->value_len == 0, empty value (e.g. empty string) */ + vb->value = NULL; + snmp_varbind_tail_add(&msg_ps->outvb, vb); + msg_ps->state = SNMP_MSG_SEARCH_OBJ; + msg_ps->vb_idx += 1; + } + } + else + { + LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_msg_event: couldn't allocate outvb space\n")); + snmp_error_response(msg_ps,SNMP_ES_TOOBIG); + } + } + } + } + } + else + { + mn = NULL; + } + if (mn == NULL) + { + /* mn == NULL, noSuchName */ + snmp_error_response(msg_ps,SNMP_ES_NOSUCHNAME); + } + } + if ((msg_ps->state == SNMP_MSG_SEARCH_OBJ) && + (msg_ps->vb_idx == msg_ps->invb.count)) + { + snmp_ok_response(msg_ps); + } +} + +/** + * Service an internal or external event for SNMP GETNEXT. + * + * @param request_id identifies requests from 0 to (SNMP_CONCURRENT_REQUESTS-1) + * @param msg_ps points to the assosicated message process state + */ +static void +snmp_msg_getnext_event(u8_t request_id, struct snmp_msg_pstat *msg_ps) +{ + LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_msg_getnext_event: msg_ps->state==%"U16_F"\n",(u16_t)msg_ps->state)); + + if (msg_ps->state == SNMP_MSG_EXTERNAL_GET_OBJDEF) + { + struct mib_external_node *en; + + /* get_object_def() answer*/ + en = msg_ps->ext_mib_node; + + /* translate answer into a known lifeform */ + en->get_object_def_a(request_id, 1, &msg_ps->ext_oid.id[msg_ps->ext_oid.len - 1], &msg_ps->ext_object_def); + if (msg_ps->ext_object_def.instance != MIB_OBJECT_NONE) + { + msg_ps->state = SNMP_MSG_EXTERNAL_GET_VALUE; + en->get_value_q(request_id, &msg_ps->ext_object_def); + } + else + { + en->get_object_def_pc(request_id, 1, &msg_ps->ext_oid.id[msg_ps->ext_oid.len - 1]); + /* search failed, object id points to unknown object (nosuchname) */ + snmp_error_response(msg_ps,SNMP_ES_NOSUCHNAME); + } + } + else if (msg_ps->state == SNMP_MSG_EXTERNAL_GET_VALUE) + { + struct mib_external_node *en; + struct snmp_varbind *vb; + + /* get_value() answer */ + en = msg_ps->ext_mib_node; + + LWIP_ASSERT("invalid length", msg_ps->ext_object_def.v_len <= 0xff); + vb = snmp_varbind_alloc(&msg_ps->ext_oid, + msg_ps->ext_object_def.asn_type, + (u8_t)msg_ps->ext_object_def.v_len); + if (vb != NULL) + { + en->get_value_a(request_id, &msg_ps->ext_object_def, vb->value_len, vb->value); + snmp_varbind_tail_add(&msg_ps->outvb, vb); + msg_ps->state = SNMP_MSG_SEARCH_OBJ; + msg_ps->vb_idx += 1; + } + else + { + en->get_value_pc(request_id, &msg_ps->ext_object_def); + LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_msg_getnext_event: couldn't allocate outvb space\n")); + snmp_error_response(msg_ps,SNMP_ES_TOOBIG); + } + } + + while ((msg_ps->state == SNMP_MSG_SEARCH_OBJ) && + (msg_ps->vb_idx < msg_ps->invb.count)) + { + struct mib_node *mn; + struct snmp_obj_id oid; + + if (msg_ps->vb_idx == 0) + { + msg_ps->vb_ptr = msg_ps->invb.head; + } + else + { + msg_ps->vb_ptr = msg_ps->vb_ptr->next; + } + if (snmp_iso_prefix_expand(msg_ps->vb_ptr->ident_len, msg_ps->vb_ptr->ident, &oid)) + { + if (msg_ps->vb_ptr->ident_len > 3) + { + /* can offset ident_len and ident */ + mn = snmp_expand_tree((struct mib_node*)&internet, + msg_ps->vb_ptr->ident_len - 4, + msg_ps->vb_ptr->ident + 4, &oid); + } + else + { + /* can't offset ident_len -4, ident + 4 */ + mn = snmp_expand_tree((struct mib_node*)&internet, 0, NULL, &oid); + } + } + else + { + mn = NULL; + } + if (mn != NULL) + { + if (mn->node_type == MIB_NODE_EX) + { + /* external object */ + struct mib_external_node *en = (struct mib_external_node*)mn; + + msg_ps->state = SNMP_MSG_EXTERNAL_GET_OBJDEF; + /* save en && args in msg_ps!! */ + msg_ps->ext_mib_node = en; + msg_ps->ext_oid = oid; + + en->get_object_def_q(en->addr_inf, request_id, 1, &oid.id[oid.len - 1]); + } + else + { + /* internal object */ + struct obj_def object_def; + struct snmp_varbind *vb; + + msg_ps->state = SNMP_MSG_INTERNAL_GET_OBJDEF; + mn->get_object_def(1, &oid.id[oid.len - 1], &object_def); + + LWIP_ASSERT("invalid length", object_def.v_len <= 0xff); + vb = snmp_varbind_alloc(&oid, object_def.asn_type, (u8_t)object_def.v_len); + if (vb != NULL) + { + msg_ps->state = SNMP_MSG_INTERNAL_GET_VALUE; + mn->get_value(&object_def, object_def.v_len, vb->value); + snmp_varbind_tail_add(&msg_ps->outvb, vb); + msg_ps->state = SNMP_MSG_SEARCH_OBJ; + msg_ps->vb_idx += 1; + } + else + { + LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_recv couldn't allocate outvb space\n")); + snmp_error_response(msg_ps,SNMP_ES_TOOBIG); + } + } + } + if (mn == NULL) + { + /* mn == NULL, noSuchName */ + snmp_error_response(msg_ps,SNMP_ES_NOSUCHNAME); + } + } + if ((msg_ps->state == SNMP_MSG_SEARCH_OBJ) && + (msg_ps->vb_idx == msg_ps->invb.count)) + { + snmp_ok_response(msg_ps); + } +} + +/** + * Service an internal or external event for SNMP SET. + * + * @param request_id identifies requests from 0 to (SNMP_CONCURRENT_REQUESTS-1) + * @param msg_ps points to the assosicated message process state + */ +static void +snmp_msg_set_event(u8_t request_id, struct snmp_msg_pstat *msg_ps) +{ + LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_msg_set_event: msg_ps->state==%"U16_F"\n",(u16_t)msg_ps->state)); + + if (msg_ps->state == SNMP_MSG_EXTERNAL_GET_OBJDEF) + { + struct mib_external_node *en; + struct snmp_name_ptr np; + + /* get_object_def() answer*/ + en = msg_ps->ext_mib_node; + np = msg_ps->ext_name_ptr; + + /* translate answer into a known lifeform */ + en->get_object_def_a(request_id, np.ident_len, np.ident, &msg_ps->ext_object_def); + if (msg_ps->ext_object_def.instance != MIB_OBJECT_NONE) + { + msg_ps->state = SNMP_MSG_EXTERNAL_SET_TEST; + en->set_test_q(request_id, &msg_ps->ext_object_def); + } + else + { + en->get_object_def_pc(request_id, np.ident_len, np.ident); + /* search failed, object id points to unknown object (nosuchname) */ + snmp_error_response(msg_ps,SNMP_ES_NOSUCHNAME); + } + } + else if (msg_ps->state == SNMP_MSG_EXTERNAL_SET_TEST) + { + struct mib_external_node *en; + + /* set_test() answer*/ + en = msg_ps->ext_mib_node; + + if (msg_ps->ext_object_def.access & MIB_ACCESS_WRITE) + { + if ((msg_ps->ext_object_def.asn_type == msg_ps->vb_ptr->value_type) && + (en->set_test_a(request_id,&msg_ps->ext_object_def, + msg_ps->vb_ptr->value_len,msg_ps->vb_ptr->value) != 0)) + { + msg_ps->state = SNMP_MSG_SEARCH_OBJ; + msg_ps->vb_idx += 1; + } + else + { + en->set_test_pc(request_id,&msg_ps->ext_object_def); + /* bad value */ + snmp_error_response(msg_ps,SNMP_ES_BADVALUE); + } + } + else + { + en->set_test_pc(request_id,&msg_ps->ext_object_def); + /* object not available for set */ + snmp_error_response(msg_ps,SNMP_ES_NOSUCHNAME); + } + } + else if (msg_ps->state == SNMP_MSG_EXTERNAL_GET_OBJDEF_S) + { + struct mib_external_node *en; + struct snmp_name_ptr np; + + /* get_object_def() answer*/ + en = msg_ps->ext_mib_node; + np = msg_ps->ext_name_ptr; + + /* translate answer into a known lifeform */ + en->get_object_def_a(request_id, np.ident_len, np.ident, &msg_ps->ext_object_def); + if (msg_ps->ext_object_def.instance != MIB_OBJECT_NONE) + { + msg_ps->state = SNMP_MSG_EXTERNAL_SET_VALUE; + en->set_value_q(request_id, &msg_ps->ext_object_def, + msg_ps->vb_ptr->value_len,msg_ps->vb_ptr->value); + } + else + { + en->get_object_def_pc(request_id, np.ident_len, np.ident); + /* set_value failed, object has disappeared for some odd reason?? */ + snmp_error_response(msg_ps,SNMP_ES_GENERROR); + } + } + else if (msg_ps->state == SNMP_MSG_EXTERNAL_SET_VALUE) + { + struct mib_external_node *en; + + /** set_value_a() */ + en = msg_ps->ext_mib_node; + en->set_value_a(request_id, &msg_ps->ext_object_def, + msg_ps->vb_ptr->value_len, msg_ps->vb_ptr->value); + + /** @todo use set_value_pc() if toobig */ + msg_ps->state = SNMP_MSG_INTERNAL_SET_VALUE; + msg_ps->vb_idx += 1; + } + + /* test all values before setting */ + while ((msg_ps->state == SNMP_MSG_SEARCH_OBJ) && + (msg_ps->vb_idx < msg_ps->invb.count)) + { + struct mib_node *mn; + struct snmp_name_ptr np; + + if (msg_ps->vb_idx == 0) + { + msg_ps->vb_ptr = msg_ps->invb.head; + } + else + { + msg_ps->vb_ptr = msg_ps->vb_ptr->next; + } + /** test object identifier for .iso.org.dod.internet prefix */ + if (snmp_iso_prefix_tst(msg_ps->vb_ptr->ident_len, msg_ps->vb_ptr->ident)) + { + mn = snmp_search_tree((struct mib_node*)&internet, msg_ps->vb_ptr->ident_len - 4, + msg_ps->vb_ptr->ident + 4, &np); + if (mn != NULL) + { + if (mn->node_type == MIB_NODE_EX) + { + /* external object */ + struct mib_external_node *en = (struct mib_external_node*)mn; + + msg_ps->state = SNMP_MSG_EXTERNAL_GET_OBJDEF; + /* save en && args in msg_ps!! */ + msg_ps->ext_mib_node = en; + msg_ps->ext_name_ptr = np; + + en->get_object_def_q(en->addr_inf, request_id, np.ident_len, np.ident); + } + else + { + /* internal object */ + struct obj_def object_def; + + msg_ps->state = SNMP_MSG_INTERNAL_GET_OBJDEF; + mn->get_object_def(np.ident_len, np.ident, &object_def); + if (object_def.instance != MIB_OBJECT_NONE) + { + mn = mn; + } + else + { + /* search failed, object id points to unknown object (nosuchname) */ + mn = NULL; + } + if (mn != NULL) + { + msg_ps->state = SNMP_MSG_INTERNAL_SET_TEST; + + if (object_def.access & MIB_ACCESS_WRITE) + { + if ((object_def.asn_type == msg_ps->vb_ptr->value_type) && + (mn->set_test(&object_def,msg_ps->vb_ptr->value_len,msg_ps->vb_ptr->value) != 0)) + { + msg_ps->state = SNMP_MSG_SEARCH_OBJ; + msg_ps->vb_idx += 1; + } + else + { + /* bad value */ + snmp_error_response(msg_ps,SNMP_ES_BADVALUE); + } + } + else + { + /* object not available for set */ + snmp_error_response(msg_ps,SNMP_ES_NOSUCHNAME); + } + } + } + } + } + else + { + mn = NULL; + } + if (mn == NULL) + { + /* mn == NULL, noSuchName */ + snmp_error_response(msg_ps,SNMP_ES_NOSUCHNAME); + } + } + + if ((msg_ps->state == SNMP_MSG_SEARCH_OBJ) && + (msg_ps->vb_idx == msg_ps->invb.count)) + { + msg_ps->vb_idx = 0; + msg_ps->state = SNMP_MSG_INTERNAL_SET_VALUE; + } + + /* set all values "atomically" (be as "atomic" as possible) */ + while ((msg_ps->state == SNMP_MSG_INTERNAL_SET_VALUE) && + (msg_ps->vb_idx < msg_ps->invb.count)) + { + struct mib_node *mn; + struct snmp_name_ptr np; + + if (msg_ps->vb_idx == 0) + { + msg_ps->vb_ptr = msg_ps->invb.head; + } + else + { + msg_ps->vb_ptr = msg_ps->vb_ptr->next; + } + /* skip iso prefix test, was done previously while settesting() */ + mn = snmp_search_tree((struct mib_node*)&internet, msg_ps->vb_ptr->ident_len - 4, + msg_ps->vb_ptr->ident + 4, &np); + /* check if object is still available + (e.g. external hot-plug thingy present?) */ + if (mn != NULL) + { + if (mn->node_type == MIB_NODE_EX) + { + /* external object */ + struct mib_external_node *en = (struct mib_external_node*)mn; + + msg_ps->state = SNMP_MSG_EXTERNAL_GET_OBJDEF_S; + /* save en && args in msg_ps!! */ + msg_ps->ext_mib_node = en; + msg_ps->ext_name_ptr = np; + + en->get_object_def_q(en->addr_inf, request_id, np.ident_len, np.ident); + } + else + { + /* internal object */ + struct obj_def object_def; + + msg_ps->state = SNMP_MSG_INTERNAL_GET_OBJDEF_S; + mn->get_object_def(np.ident_len, np.ident, &object_def); + msg_ps->state = SNMP_MSG_INTERNAL_SET_VALUE; + mn->set_value(&object_def,msg_ps->vb_ptr->value_len,msg_ps->vb_ptr->value); + msg_ps->vb_idx += 1; + } + } + } + if ((msg_ps->state == SNMP_MSG_INTERNAL_SET_VALUE) && + (msg_ps->vb_idx == msg_ps->invb.count)) + { + /* simply echo the input if we can set it + @todo do we need to return the actual value? + e.g. if value is silently modified or behaves sticky? */ + msg_ps->outvb = msg_ps->invb; + msg_ps->invb.head = NULL; + msg_ps->invb.tail = NULL; + msg_ps->invb.count = 0; + snmp_ok_response(msg_ps); + } +} + + +/** + * Handle one internal or external event. + * Called for one async event. (recv external/private answer) + * + * @param request_id identifies requests from 0 to (SNMP_CONCURRENT_REQUESTS-1) + */ +void +snmp_msg_event(u8_t request_id) +{ + struct snmp_msg_pstat *msg_ps; + + if (request_id < SNMP_CONCURRENT_REQUESTS) + { + msg_ps = &msg_input_list[request_id]; + if (msg_ps->rt == SNMP_ASN1_PDU_GET_NEXT_REQ) + { + snmp_msg_getnext_event(request_id, msg_ps); + } + else if (msg_ps->rt == SNMP_ASN1_PDU_GET_REQ) + { + snmp_msg_get_event(request_id, msg_ps); + } + else if(msg_ps->rt == SNMP_ASN1_PDU_SET_REQ) + { + snmp_msg_set_event(request_id, msg_ps); + } + } +} + + +/* lwIP UDP receive callback function */ +static void +snmp_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, ip_addr_t *addr, u16_t port) +{ + struct snmp_msg_pstat *msg_ps; + u8_t req_idx; + err_t err_ret; + u16_t payload_len = p->tot_len; + u16_t payload_ofs = 0; + u16_t varbind_ofs = 0; + + /* suppress unused argument warning */ + LWIP_UNUSED_ARG(arg); + + /* traverse input message process list, look for SNMP_MSG_EMPTY */ + msg_ps = &msg_input_list[0]; + req_idx = 0; + while ((req_idx < SNMP_CONCURRENT_REQUESTS) && (msg_ps->state != SNMP_MSG_EMPTY)) + { + req_idx++; + msg_ps++; + } + if (req_idx == SNMP_CONCURRENT_REQUESTS) + { + /* exceeding number of concurrent requests */ + pbuf_free(p); + return; + } + + /* accepting request */ + snmp_inc_snmpinpkts(); + /* record used 'protocol control block' */ + msg_ps->pcb = pcb; + /* source address (network order) */ + msg_ps->sip = *addr; + /* source port (host order (lwIP oddity)) */ + msg_ps->sp = port; + + /* check total length, version, community, pdu type */ + err_ret = snmp_pdu_header_check(p, payload_ofs, payload_len, &varbind_ofs, msg_ps); + /* Only accept requests and requests without error (be robust) */ + /* Reject response and trap headers or error requests as input! */ + if ((err_ret != ERR_OK) || + ((msg_ps->rt != SNMP_ASN1_PDU_GET_REQ) && + (msg_ps->rt != SNMP_ASN1_PDU_GET_NEXT_REQ) && + (msg_ps->rt != SNMP_ASN1_PDU_SET_REQ)) || + ((msg_ps->error_status != SNMP_ES_NOERROR) || + (msg_ps->error_index != 0)) ) + { + /* header check failed drop request silently, do not return error! */ + pbuf_free(p); + LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_pdu_header_check() failed\n")); + return; + } + LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_recv ok, community %s\n", msg_ps->community)); + + /* Builds a list of variable bindings. Copy the varbinds from the pbuf + chain to glue them when these are divided over two or more pbuf's. */ + err_ret = snmp_pdu_dec_varbindlist(p, varbind_ofs, &varbind_ofs, msg_ps); + /* we've decoded the incoming message, release input msg now */ + pbuf_free(p); + if ((err_ret != ERR_OK) || (msg_ps->invb.count == 0)) + { + /* varbind-list decode failed, or varbind list empty. + drop request silently, do not return error! + (errors are only returned for a specific varbind failure) */ + LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_pdu_dec_varbindlist() failed\n")); + return; + } + + msg_ps->error_status = SNMP_ES_NOERROR; + msg_ps->error_index = 0; + /* find object for each variable binding */ + msg_ps->state = SNMP_MSG_SEARCH_OBJ; + /* first variable binding from list to inspect */ + msg_ps->vb_idx = 0; + + LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_recv varbind cnt=%"U16_F"\n",(u16_t)msg_ps->invb.count)); + + /* handle input event and as much objects as possible in one go */ + snmp_msg_event(req_idx); +} + +/** + * Checks and decodes incoming SNMP message header, logs header errors. + * + * @param p points to pbuf chain of SNMP message (UDP payload) + * @param ofs points to first octet of SNMP message + * @param pdu_len the length of the UDP payload + * @param ofs_ret returns the ofset of the variable bindings + * @param m_stat points to the current message request state return + * @return + * - ERR_OK SNMP header is sane and accepted + * - ERR_ARG SNMP header is either malformed or rejected + */ +static err_t +snmp_pdu_header_check(struct pbuf *p, u16_t ofs, u16_t pdu_len, u16_t *ofs_ret, struct snmp_msg_pstat *m_stat) +{ + err_t derr; + u16_t len, ofs_base; + u8_t len_octets; + u8_t type; + s32_t version; + + ofs_base = ofs; + snmp_asn1_dec_type(p, ofs, &type); + derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len); + if ((derr != ERR_OK) || + (pdu_len != (1 + len_octets + len)) || + (type != (SNMP_ASN1_UNIV | SNMP_ASN1_CONSTR | SNMP_ASN1_SEQ))) + { + snmp_inc_snmpinasnparseerrs(); + return ERR_ARG; + } + ofs += (1 + len_octets); + snmp_asn1_dec_type(p, ofs, &type); + derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len); + if ((derr != ERR_OK) || (type != (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG))) + { + /* can't decode or no integer (version) */ + snmp_inc_snmpinasnparseerrs(); + return ERR_ARG; + } + derr = snmp_asn1_dec_s32t(p, ofs + 1 + len_octets, len, &version); + if (derr != ERR_OK) + { + /* can't decode */ + snmp_inc_snmpinasnparseerrs(); + return ERR_ARG; + } + if (version != 0) + { + /* not version 1 */ + snmp_inc_snmpinbadversions(); + return ERR_ARG; + } + ofs += (1 + len_octets + len); + snmp_asn1_dec_type(p, ofs, &type); + derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len); + if ((derr != ERR_OK) || (type != (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR))) + { + /* can't decode or no octet string (community) */ + snmp_inc_snmpinasnparseerrs(); + return ERR_ARG; + } + derr = snmp_asn1_dec_raw(p, ofs + 1 + len_octets, len, SNMP_COMMUNITY_STR_LEN, m_stat->community); + if (derr != ERR_OK) + { + snmp_inc_snmpinasnparseerrs(); + return ERR_ARG; + } + /* add zero terminator */ + len = ((len < (SNMP_COMMUNITY_STR_LEN))?(len):(SNMP_COMMUNITY_STR_LEN)); + m_stat->community[len] = 0; + m_stat->com_strlen = (u8_t)len; + if (strncmp(snmp_publiccommunity, (const char*)m_stat->community, SNMP_COMMUNITY_STR_LEN) != 0) + { + /** @todo: move this if we need to check more names */ + snmp_inc_snmpinbadcommunitynames(); + snmp_authfail_trap(); + return ERR_ARG; + } + ofs += (1 + len_octets + len); + snmp_asn1_dec_type(p, ofs, &type); + derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len); + if (derr != ERR_OK) + { + snmp_inc_snmpinasnparseerrs(); + return ERR_ARG; + } + switch(type) + { + case (SNMP_ASN1_CONTXT | SNMP_ASN1_CONSTR | SNMP_ASN1_PDU_GET_REQ): + /* GetRequest PDU */ + snmp_inc_snmpingetrequests(); + derr = ERR_OK; + break; + case (SNMP_ASN1_CONTXT | SNMP_ASN1_CONSTR | SNMP_ASN1_PDU_GET_NEXT_REQ): + /* GetNextRequest PDU */ + snmp_inc_snmpingetnexts(); + derr = ERR_OK; + break; + case (SNMP_ASN1_CONTXT | SNMP_ASN1_CONSTR | SNMP_ASN1_PDU_GET_RESP): + /* GetResponse PDU */ + snmp_inc_snmpingetresponses(); + derr = ERR_ARG; + break; + case (SNMP_ASN1_CONTXT | SNMP_ASN1_CONSTR | SNMP_ASN1_PDU_SET_REQ): + /* SetRequest PDU */ + snmp_inc_snmpinsetrequests(); + derr = ERR_OK; + break; + case (SNMP_ASN1_CONTXT | SNMP_ASN1_CONSTR | SNMP_ASN1_PDU_TRAP): + /* Trap PDU */ + snmp_inc_snmpintraps(); + derr = ERR_ARG; + break; + default: + snmp_inc_snmpinasnparseerrs(); + derr = ERR_ARG; + break; + } + if (derr != ERR_OK) + { + /* unsupported input PDU for this agent (no parse error) */ + return ERR_ARG; + } + m_stat->rt = type & 0x1F; + ofs += (1 + len_octets); + if (len != (pdu_len - (ofs - ofs_base))) + { + /* decoded PDU length does not equal actual payload length */ + snmp_inc_snmpinasnparseerrs(); + return ERR_ARG; + } + snmp_asn1_dec_type(p, ofs, &type); + derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len); + if ((derr != ERR_OK) || (type != (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG))) + { + /* can't decode or no integer (request ID) */ + snmp_inc_snmpinasnparseerrs(); + return ERR_ARG; + } + derr = snmp_asn1_dec_s32t(p, ofs + 1 + len_octets, len, &m_stat->rid); + if (derr != ERR_OK) + { + /* can't decode */ + snmp_inc_snmpinasnparseerrs(); + return ERR_ARG; + } + ofs += (1 + len_octets + len); + snmp_asn1_dec_type(p, ofs, &type); + derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len); + if ((derr != ERR_OK) || (type != (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG))) + { + /* can't decode or no integer (error-status) */ + snmp_inc_snmpinasnparseerrs(); + return ERR_ARG; + } + /* must be noError (0) for incoming requests. + log errors for mib-2 completeness and for debug purposes */ + derr = snmp_asn1_dec_s32t(p, ofs + 1 + len_octets, len, &m_stat->error_status); + if (derr != ERR_OK) + { + /* can't decode */ + snmp_inc_snmpinasnparseerrs(); + return ERR_ARG; + } + switch (m_stat->error_status) + { + case SNMP_ES_TOOBIG: + snmp_inc_snmpintoobigs(); + break; + case SNMP_ES_NOSUCHNAME: + snmp_inc_snmpinnosuchnames(); + break; + case SNMP_ES_BADVALUE: + snmp_inc_snmpinbadvalues(); + break; + case SNMP_ES_READONLY: + snmp_inc_snmpinreadonlys(); + break; + case SNMP_ES_GENERROR: + snmp_inc_snmpingenerrs(); + break; + } + ofs += (1 + len_octets + len); + snmp_asn1_dec_type(p, ofs, &type); + derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len); + if ((derr != ERR_OK) || (type != (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG))) + { + /* can't decode or no integer (error-index) */ + snmp_inc_snmpinasnparseerrs(); + return ERR_ARG; + } + /* must be 0 for incoming requests. + decode anyway to catch bad integers (and dirty tricks) */ + derr = snmp_asn1_dec_s32t(p, ofs + 1 + len_octets, len, &m_stat->error_index); + if (derr != ERR_OK) + { + /* can't decode */ + snmp_inc_snmpinasnparseerrs(); + return ERR_ARG; + } + ofs += (1 + len_octets + len); + *ofs_ret = ofs; + return ERR_OK; +} + +static err_t +snmp_pdu_dec_varbindlist(struct pbuf *p, u16_t ofs, u16_t *ofs_ret, struct snmp_msg_pstat *m_stat) +{ + err_t derr; + u16_t len, vb_len; + u8_t len_octets; + u8_t type; + + /* variable binding list */ + snmp_asn1_dec_type(p, ofs, &type); + derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &vb_len); + if ((derr != ERR_OK) || + (type != (SNMP_ASN1_UNIV | SNMP_ASN1_CONSTR | SNMP_ASN1_SEQ))) + { + snmp_inc_snmpinasnparseerrs(); + return ERR_ARG; + } + ofs += (1 + len_octets); + + /* start with empty list */ + m_stat->invb.count = 0; + m_stat->invb.head = NULL; + m_stat->invb.tail = NULL; + + while (vb_len > 0) + { + struct snmp_obj_id oid, oid_value; + struct snmp_varbind *vb; + + snmp_asn1_dec_type(p, ofs, &type); + derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len); + if ((derr != ERR_OK) || + (type != (SNMP_ASN1_UNIV | SNMP_ASN1_CONSTR | SNMP_ASN1_SEQ)) || + (len == 0) || (len > vb_len)) + { + snmp_inc_snmpinasnparseerrs(); + /* free varbinds (if available) */ + snmp_varbind_list_free(&m_stat->invb); + return ERR_ARG; + } + ofs += (1 + len_octets); + vb_len -= (1 + len_octets); + + snmp_asn1_dec_type(p, ofs, &type); + derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len); + if ((derr != ERR_OK) || (type != (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OBJ_ID))) + { + /* can't decode object name length */ + snmp_inc_snmpinasnparseerrs(); + /* free varbinds (if available) */ + snmp_varbind_list_free(&m_stat->invb); + return ERR_ARG; + } + derr = snmp_asn1_dec_oid(p, ofs + 1 + len_octets, len, &oid); + if (derr != ERR_OK) + { + /* can't decode object name */ + snmp_inc_snmpinasnparseerrs(); + /* free varbinds (if available) */ + snmp_varbind_list_free(&m_stat->invb); + return ERR_ARG; + } + ofs += (1 + len_octets + len); + vb_len -= (1 + len_octets + len); + + snmp_asn1_dec_type(p, ofs, &type); + derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len); + if (derr != ERR_OK) + { + /* can't decode object value length */ + snmp_inc_snmpinasnparseerrs(); + /* free varbinds (if available) */ + snmp_varbind_list_free(&m_stat->invb); + return ERR_ARG; + } + + switch (type) + { + case (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG): + vb = snmp_varbind_alloc(&oid, type, sizeof(s32_t)); + if (vb != NULL) + { + s32_t *vptr = (s32_t*)vb->value; + + derr = snmp_asn1_dec_s32t(p, ofs + 1 + len_octets, len, vptr); + snmp_varbind_tail_add(&m_stat->invb, vb); + } + else + { + derr = ERR_ARG; + } + break; + case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_COUNTER): + case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_GAUGE): + case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_TIMETICKS): + vb = snmp_varbind_alloc(&oid, type, sizeof(u32_t)); + if (vb != NULL) + { + u32_t *vptr = (u32_t*)vb->value; + + derr = snmp_asn1_dec_u32t(p, ofs + 1 + len_octets, len, vptr); + snmp_varbind_tail_add(&m_stat->invb, vb); + } + else + { + derr = ERR_ARG; + } + break; + case (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR): + case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_OPAQUE): + LWIP_ASSERT("invalid length", len <= 0xff); + vb = snmp_varbind_alloc(&oid, type, (u8_t)len); + if (vb != NULL) + { + derr = snmp_asn1_dec_raw(p, ofs + 1 + len_octets, len, vb->value_len, (u8_t*)vb->value); + snmp_varbind_tail_add(&m_stat->invb, vb); + } + else + { + derr = ERR_ARG; + } + break; + case (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_NUL): + vb = snmp_varbind_alloc(&oid, type, 0); + if (vb != NULL) + { + snmp_varbind_tail_add(&m_stat->invb, vb); + derr = ERR_OK; + } + else + { + derr = ERR_ARG; + } + break; + case (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OBJ_ID): + derr = snmp_asn1_dec_oid(p, ofs + 1 + len_octets, len, &oid_value); + if (derr == ERR_OK) + { + vb = snmp_varbind_alloc(&oid, type, oid_value.len * sizeof(s32_t)); + if (vb != NULL) + { + u8_t i = oid_value.len; + s32_t *vptr = (s32_t*)vb->value; + + while(i > 0) + { + i--; + vptr[i] = oid_value.id[i]; + } + snmp_varbind_tail_add(&m_stat->invb, vb); + derr = ERR_OK; + } + else + { + derr = ERR_ARG; + } + } + break; + case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_IPADDR): + if (len == 4) + { + /* must be exactly 4 octets! */ + vb = snmp_varbind_alloc(&oid, type, 4); + if (vb != NULL) + { + derr = snmp_asn1_dec_raw(p, ofs + 1 + len_octets, len, vb->value_len, (u8_t*)vb->value); + snmp_varbind_tail_add(&m_stat->invb, vb); + } + else + { + derr = ERR_ARG; + } + } + else + { + derr = ERR_ARG; + } + break; + default: + derr = ERR_ARG; + break; + } + if (derr != ERR_OK) + { + snmp_inc_snmpinasnparseerrs(); + /* free varbinds (if available) */ + snmp_varbind_list_free(&m_stat->invb); + return ERR_ARG; + } + ofs += (1 + len_octets + len); + vb_len -= (1 + len_octets + len); + } + + if (m_stat->rt == SNMP_ASN1_PDU_SET_REQ) + { + snmp_add_snmpintotalsetvars(m_stat->invb.count); + } + else + { + snmp_add_snmpintotalreqvars(m_stat->invb.count); + } + + *ofs_ret = ofs; + return ERR_OK; +} + +struct snmp_varbind* +snmp_varbind_alloc(struct snmp_obj_id *oid, u8_t type, u8_t len) +{ + struct snmp_varbind *vb; + + vb = (struct snmp_varbind *)memp_malloc(MEMP_SNMP_VARBIND); + if (vb != NULL) + { + u8_t i; + + vb->next = NULL; + vb->prev = NULL; + i = oid->len; + vb->ident_len = i; + if (i > 0) + { + LWIP_ASSERT("SNMP_MAX_TREE_DEPTH is configured too low", i <= SNMP_MAX_TREE_DEPTH); + /* allocate array of s32_t for our object identifier */ + vb->ident = (s32_t*)memp_malloc(MEMP_SNMP_VALUE); + if (vb->ident == NULL) + { + LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_varbind_alloc: couldn't allocate ident value space\n")); + memp_free(MEMP_SNMP_VARBIND, vb); + return NULL; + } + while(i > 0) + { + i--; + vb->ident[i] = oid->id[i]; + } + } + else + { + /* i == 0, pass zero length object identifier */ + vb->ident = NULL; + } + vb->value_type = type; + vb->value_len = len; + if (len > 0) + { + LWIP_ASSERT("SNMP_MAX_OCTET_STRING_LEN is configured too low", vb->value_len <= SNMP_MAX_VALUE_SIZE); + /* allocate raw bytes for our object value */ + vb->value = memp_malloc(MEMP_SNMP_VALUE); + if (vb->value == NULL) + { + LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_varbind_alloc: couldn't allocate value space\n")); + if (vb->ident != NULL) + { + memp_free(MEMP_SNMP_VALUE, vb->ident); + } + memp_free(MEMP_SNMP_VARBIND, vb); + return NULL; + } + } + else + { + /* ASN1_NUL type, or zero length ASN1_OC_STR */ + vb->value = NULL; + } + } + else + { + LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_varbind_alloc: couldn't allocate varbind space\n")); + } + return vb; +} + +void +snmp_varbind_free(struct snmp_varbind *vb) +{ + if (vb->value != NULL ) + { + memp_free(MEMP_SNMP_VALUE, vb->value); + } + if (vb->ident != NULL ) + { + memp_free(MEMP_SNMP_VALUE, vb->ident); + } + memp_free(MEMP_SNMP_VARBIND, vb); +} + +void +snmp_varbind_list_free(struct snmp_varbind_root *root) +{ + struct snmp_varbind *vb, *prev; + + vb = root->tail; + while ( vb != NULL ) + { + prev = vb->prev; + snmp_varbind_free(vb); + vb = prev; + } + root->count = 0; + root->head = NULL; + root->tail = NULL; +} + +void +snmp_varbind_tail_add(struct snmp_varbind_root *root, struct snmp_varbind *vb) +{ + if (root->count == 0) + { + /* add first varbind to list */ + root->head = vb; + root->tail = vb; + } + else + { + /* add nth varbind to list tail */ + root->tail->next = vb; + vb->prev = root->tail; + root->tail = vb; + } + root->count += 1; +} + +struct snmp_varbind* +snmp_varbind_tail_remove(struct snmp_varbind_root *root) +{ + struct snmp_varbind* vb; + + if (root->count > 0) + { + /* remove tail varbind */ + vb = root->tail; + root->tail = vb->prev; + vb->prev->next = NULL; + root->count -= 1; + } + else + { + /* nothing to remove */ + vb = NULL; + } + return vb; +} + +#endif /* LWIP_SNMP */ diff --git a/src/lwip-1.4.1/src/core/snmp/msg_out.c b/src/lwip-1.4.1/src/core/snmp/msg_out.c new file mode 100644 index 0000000..485f076 --- /dev/null +++ b/src/lwip-1.4.1/src/core/snmp/msg_out.c @@ -0,0 +1,674 @@ +/** + * @file + * SNMP output message processing (RFC1157). + * + * Output responses and traps are build in two passes: + * + * Pass 0: iterate over the output message backwards to determine encoding lengths + * Pass 1: the actual forward encoding of internal form into ASN1 + * + * The single-pass encoding method described by Comer & Stevens + * requires extra buffer space and copying for reversal of the packet. + * The buffer requirement can be prohibitively large for big payloads + * (>= 484) therefore we use the two encoding passes. + */ + +/* + * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * Author: Christiaan Simons + */ + +#include "lwip/opt.h" + +#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/udp.h" +#include "lwip/netif.h" +#include "lwip/snmp.h" +#include "lwip/snmp_asn1.h" +#include "lwip/snmp_msg.h" + +struct snmp_trap_dst +{ + /* destination IP address in network order */ + ip_addr_t dip; + /* set to 0 when disabled, >0 when enabled */ + u8_t enable; +}; +struct snmp_trap_dst trap_dst[SNMP_TRAP_DESTINATIONS]; + +/** TRAP message structure */ +struct snmp_msg_trap trap_msg; + +static u16_t snmp_resp_header_sum(struct snmp_msg_pstat *m_stat, u16_t vb_len); +static u16_t snmp_trap_header_sum(struct snmp_msg_trap *m_trap, u16_t vb_len); +static u16_t snmp_varbind_list_sum(struct snmp_varbind_root *root); + +static u16_t snmp_resp_header_enc(struct snmp_msg_pstat *m_stat, struct pbuf *p); +static u16_t snmp_trap_header_enc(struct snmp_msg_trap *m_trap, struct pbuf *p); +static u16_t snmp_varbind_list_enc(struct snmp_varbind_root *root, struct pbuf *p, u16_t ofs); + +/** + * Sets enable switch for this trap destination. + * @param dst_idx index in 0 .. SNMP_TRAP_DESTINATIONS-1 + * @param enable switch if 0 destination is disabled >0 enabled. + */ +void +snmp_trap_dst_enable(u8_t dst_idx, u8_t enable) +{ + if (dst_idx < SNMP_TRAP_DESTINATIONS) + { + trap_dst[dst_idx].enable = enable; + } +} + +/** + * Sets IPv4 address for this trap destination. + * @param dst_idx index in 0 .. SNMP_TRAP_DESTINATIONS-1 + * @param dst IPv4 address in host order. + */ +void +snmp_trap_dst_ip_set(u8_t dst_idx, ip_addr_t *dst) +{ + if (dst_idx < SNMP_TRAP_DESTINATIONS) + { + ip_addr_set(&trap_dst[dst_idx].dip, dst); + } +} + +/** + * Sends a 'getresponse' message to the request originator. + * + * @param m_stat points to the current message request state source + * @return ERR_OK when success, ERR_MEM if we're out of memory + * + * @note the caller is responsible for filling in outvb in the m_stat + * and provide error-status and index (except for tooBig errors) ... + */ +err_t +snmp_send_response(struct snmp_msg_pstat *m_stat) +{ + struct snmp_varbind_root emptyvb = {NULL, NULL, 0, 0, 0}; + struct pbuf *p; + u16_t tot_len; + err_t err; + + /* pass 0, calculate length fields */ + tot_len = snmp_varbind_list_sum(&m_stat->outvb); + tot_len = snmp_resp_header_sum(m_stat, tot_len); + + /* try allocating pbuf(s) for complete response */ + p = pbuf_alloc(PBUF_TRANSPORT, tot_len, PBUF_POOL); + if (p == NULL) + { + LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_snd_response() tooBig\n")); + + /* can't construct reply, return error-status tooBig */ + m_stat->error_status = SNMP_ES_TOOBIG; + m_stat->error_index = 0; + /* pass 0, recalculate lengths, for empty varbind-list */ + tot_len = snmp_varbind_list_sum(&emptyvb); + tot_len = snmp_resp_header_sum(m_stat, tot_len); + /* retry allocation once for header and empty varbind-list */ + p = pbuf_alloc(PBUF_TRANSPORT, tot_len, PBUF_POOL); + } + if (p != NULL) + { + /* first pbuf alloc try or retry alloc success */ + u16_t ofs; + + LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_snd_response() p != NULL\n")); + + /* pass 1, size error, encode packet ino the pbuf(s) */ + ofs = snmp_resp_header_enc(m_stat, p); + snmp_varbind_list_enc(&m_stat->outvb, p, ofs); + + switch (m_stat->error_status) + { + case SNMP_ES_TOOBIG: + snmp_inc_snmpouttoobigs(); + break; + case SNMP_ES_NOSUCHNAME: + snmp_inc_snmpoutnosuchnames(); + break; + case SNMP_ES_BADVALUE: + snmp_inc_snmpoutbadvalues(); + break; + case SNMP_ES_GENERROR: + snmp_inc_snmpoutgenerrs(); + break; + } + snmp_inc_snmpoutgetresponses(); + snmp_inc_snmpoutpkts(); + + /** @todo do we need separate rx and tx pcbs for threaded case? */ + /** connect to the originating source */ + udp_connect(m_stat->pcb, &m_stat->sip, m_stat->sp); + err = udp_send(m_stat->pcb, p); + if (err == ERR_MEM) + { + /** @todo release some memory, retry and return tooBig? tooMuchHassle? */ + err = ERR_MEM; + } + else + { + err = ERR_OK; + } + /** disassociate remote address and port with this pcb */ + udp_disconnect(m_stat->pcb); + + pbuf_free(p); + LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_snd_response() done\n")); + return err; + } + else + { + /* first pbuf alloc try or retry alloc failed + very low on memory, couldn't return tooBig */ + return ERR_MEM; + } +} + + +/** + * Sends an generic or enterprise specific trap message. + * + * @param generic_trap is the trap code + * @param eoid points to enterprise object identifier + * @param specific_trap used for enterprise traps when generic_trap == 6 + * @return ERR_OK when success, ERR_MEM if we're out of memory + * + * @note the caller is responsible for filling in outvb in the trap_msg + * @note the use of the enterpise identifier field + * is per RFC1215. + * Use .iso.org.dod.internet.mgmt.mib-2.snmp for generic traps + * and .iso.org.dod.internet.private.enterprises.yourenterprise + * (sysObjectID) for specific traps. + */ +err_t +snmp_send_trap(s8_t generic_trap, struct snmp_obj_id *eoid, s32_t specific_trap) +{ + struct snmp_trap_dst *td; + struct netif *dst_if; + ip_addr_t dst_ip; + struct pbuf *p; + u16_t i,tot_len; + + for (i=0, td = &trap_dst[0]; ienable != 0) && !ip_addr_isany(&td->dip)) + { + /* network order trap destination */ + ip_addr_copy(trap_msg.dip, td->dip); + /* lookup current source address for this dst */ + dst_if = ip_route(&td->dip); + ip_addr_copy(dst_ip, dst_if->ip_addr); + /* @todo: what about IPv6? */ + trap_msg.sip_raw[0] = ip4_addr1(&dst_ip); + trap_msg.sip_raw[1] = ip4_addr2(&dst_ip); + trap_msg.sip_raw[2] = ip4_addr3(&dst_ip); + trap_msg.sip_raw[3] = ip4_addr4(&dst_ip); + trap_msg.gen_trap = generic_trap; + trap_msg.spc_trap = specific_trap; + if (generic_trap == SNMP_GENTRAP_ENTERPRISESPC) + { + /* enterprise-Specific trap */ + trap_msg.enterprise = eoid; + } + else + { + /* generic (MIB-II) trap */ + snmp_get_snmpgrpid_ptr(&trap_msg.enterprise); + } + snmp_get_sysuptime(&trap_msg.ts); + + /* pass 0, calculate length fields */ + tot_len = snmp_varbind_list_sum(&trap_msg.outvb); + tot_len = snmp_trap_header_sum(&trap_msg, tot_len); + + /* allocate pbuf(s) */ + p = pbuf_alloc(PBUF_TRANSPORT, tot_len, PBUF_POOL); + if (p != NULL) + { + u16_t ofs; + + /* pass 1, encode packet ino the pbuf(s) */ + ofs = snmp_trap_header_enc(&trap_msg, p); + snmp_varbind_list_enc(&trap_msg.outvb, p, ofs); + + snmp_inc_snmpouttraps(); + snmp_inc_snmpoutpkts(); + + /** send to the TRAP destination */ + udp_sendto(trap_msg.pcb, p, &trap_msg.dip, SNMP_TRAP_PORT); + + pbuf_free(p); + } + else + { + return ERR_MEM; + } + } + } + return ERR_OK; +} + +void +snmp_coldstart_trap(void) +{ + trap_msg.outvb.head = NULL; + trap_msg.outvb.tail = NULL; + trap_msg.outvb.count = 0; + snmp_send_trap(SNMP_GENTRAP_COLDSTART, NULL, 0); +} + +void +snmp_authfail_trap(void) +{ + u8_t enable; + snmp_get_snmpenableauthentraps(&enable); + if (enable == 1) + { + trap_msg.outvb.head = NULL; + trap_msg.outvb.tail = NULL; + trap_msg.outvb.count = 0; + snmp_send_trap(SNMP_GENTRAP_AUTHFAIL, NULL, 0); + } +} + +/** + * Sums response header field lengths from tail to head and + * returns resp_header_lengths for second encoding pass. + * + * @param vb_len varbind-list length + * @param rhl points to returned header lengths + * @return the required lenght for encoding the response header + */ +static u16_t +snmp_resp_header_sum(struct snmp_msg_pstat *m_stat, u16_t vb_len) +{ + u16_t tot_len; + struct snmp_resp_header_lengths *rhl; + + rhl = &m_stat->rhl; + tot_len = vb_len; + snmp_asn1_enc_s32t_cnt(m_stat->error_index, &rhl->erridxlen); + snmp_asn1_enc_length_cnt(rhl->erridxlen, &rhl->erridxlenlen); + tot_len += 1 + rhl->erridxlenlen + rhl->erridxlen; + + snmp_asn1_enc_s32t_cnt(m_stat->error_status, &rhl->errstatlen); + snmp_asn1_enc_length_cnt(rhl->errstatlen, &rhl->errstatlenlen); + tot_len += 1 + rhl->errstatlenlen + rhl->errstatlen; + + snmp_asn1_enc_s32t_cnt(m_stat->rid, &rhl->ridlen); + snmp_asn1_enc_length_cnt(rhl->ridlen, &rhl->ridlenlen); + tot_len += 1 + rhl->ridlenlen + rhl->ridlen; + + rhl->pdulen = tot_len; + snmp_asn1_enc_length_cnt(rhl->pdulen, &rhl->pdulenlen); + tot_len += 1 + rhl->pdulenlen; + + rhl->comlen = m_stat->com_strlen; + snmp_asn1_enc_length_cnt(rhl->comlen, &rhl->comlenlen); + tot_len += 1 + rhl->comlenlen + rhl->comlen; + + snmp_asn1_enc_s32t_cnt(snmp_version, &rhl->verlen); + snmp_asn1_enc_length_cnt(rhl->verlen, &rhl->verlenlen); + tot_len += 1 + rhl->verlen + rhl->verlenlen; + + rhl->seqlen = tot_len; + snmp_asn1_enc_length_cnt(rhl->seqlen, &rhl->seqlenlen); + tot_len += 1 + rhl->seqlenlen; + + return tot_len; +} + +/** + * Sums trap header field lengths from tail to head and + * returns trap_header_lengths for second encoding pass. + * + * @param vb_len varbind-list length + * @param thl points to returned header lengths + * @return the required lenght for encoding the trap header + */ +static u16_t +snmp_trap_header_sum(struct snmp_msg_trap *m_trap, u16_t vb_len) +{ + u16_t tot_len; + struct snmp_trap_header_lengths *thl; + + thl = &m_trap->thl; + tot_len = vb_len; + + snmp_asn1_enc_u32t_cnt(m_trap->ts, &thl->tslen); + snmp_asn1_enc_length_cnt(thl->tslen, &thl->tslenlen); + tot_len += 1 + thl->tslen + thl->tslenlen; + + snmp_asn1_enc_s32t_cnt(m_trap->spc_trap, &thl->strplen); + snmp_asn1_enc_length_cnt(thl->strplen, &thl->strplenlen); + tot_len += 1 + thl->strplen + thl->strplenlen; + + snmp_asn1_enc_s32t_cnt(m_trap->gen_trap, &thl->gtrplen); + snmp_asn1_enc_length_cnt(thl->gtrplen, &thl->gtrplenlen); + tot_len += 1 + thl->gtrplen + thl->gtrplenlen; + + thl->aaddrlen = 4; + snmp_asn1_enc_length_cnt(thl->aaddrlen, &thl->aaddrlenlen); + tot_len += 1 + thl->aaddrlen + thl->aaddrlenlen; + + snmp_asn1_enc_oid_cnt(m_trap->enterprise->len, &m_trap->enterprise->id[0], &thl->eidlen); + snmp_asn1_enc_length_cnt(thl->eidlen, &thl->eidlenlen); + tot_len += 1 + thl->eidlen + thl->eidlenlen; + + thl->pdulen = tot_len; + snmp_asn1_enc_length_cnt(thl->pdulen, &thl->pdulenlen); + tot_len += 1 + thl->pdulenlen; + + thl->comlen = sizeof(snmp_publiccommunity) - 1; + snmp_asn1_enc_length_cnt(thl->comlen, &thl->comlenlen); + tot_len += 1 + thl->comlenlen + thl->comlen; + + snmp_asn1_enc_s32t_cnt(snmp_version, &thl->verlen); + snmp_asn1_enc_length_cnt(thl->verlen, &thl->verlenlen); + tot_len += 1 + thl->verlen + thl->verlenlen; + + thl->seqlen = tot_len; + snmp_asn1_enc_length_cnt(thl->seqlen, &thl->seqlenlen); + tot_len += 1 + thl->seqlenlen; + + return tot_len; +} + +/** + * Sums varbind lengths from tail to head and + * annotates lengths in varbind for second encoding pass. + * + * @param root points to the root of the variable binding list + * @return the required lenght for encoding the variable bindings + */ +static u16_t +snmp_varbind_list_sum(struct snmp_varbind_root *root) +{ + struct snmp_varbind *vb; + u32_t *uint_ptr; + s32_t *sint_ptr; + u16_t tot_len; + + tot_len = 0; + vb = root->tail; + while ( vb != NULL ) + { + /* encoded value lenght depends on type */ + switch (vb->value_type) + { + case (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG): + sint_ptr = (s32_t*)vb->value; + snmp_asn1_enc_s32t_cnt(*sint_ptr, &vb->vlen); + break; + case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_COUNTER): + case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_GAUGE): + case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_TIMETICKS): + uint_ptr = (u32_t*)vb->value; + snmp_asn1_enc_u32t_cnt(*uint_ptr, &vb->vlen); + break; + case (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR): + case (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_NUL): + case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_IPADDR): + case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_OPAQUE): + vb->vlen = vb->value_len; + break; + case (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OBJ_ID): + sint_ptr = (s32_t*)vb->value; + snmp_asn1_enc_oid_cnt(vb->value_len / sizeof(s32_t), sint_ptr, &vb->vlen); + break; + default: + /* unsupported type */ + vb->vlen = 0; + break; + }; + /* encoding length of value length field */ + snmp_asn1_enc_length_cnt(vb->vlen, &vb->vlenlen); + snmp_asn1_enc_oid_cnt(vb->ident_len, vb->ident, &vb->olen); + snmp_asn1_enc_length_cnt(vb->olen, &vb->olenlen); + + vb->seqlen = 1 + vb->vlenlen + vb->vlen; + vb->seqlen += 1 + vb->olenlen + vb->olen; + snmp_asn1_enc_length_cnt(vb->seqlen, &vb->seqlenlen); + + /* varbind seq */ + tot_len += 1 + vb->seqlenlen + vb->seqlen; + + vb = vb->prev; + } + + /* varbind-list seq */ + root->seqlen = tot_len; + snmp_asn1_enc_length_cnt(root->seqlen, &root->seqlenlen); + tot_len += 1 + root->seqlenlen; + + return tot_len; +} + +/** + * Encodes response header from head to tail. + */ +static u16_t +snmp_resp_header_enc(struct snmp_msg_pstat *m_stat, struct pbuf *p) +{ + u16_t ofs; + + ofs = 0; + snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_CONSTR | SNMP_ASN1_SEQ)); + ofs += 1; + snmp_asn1_enc_length(p, ofs, m_stat->rhl.seqlen); + ofs += m_stat->rhl.seqlenlen; + + snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG)); + ofs += 1; + snmp_asn1_enc_length(p, ofs, m_stat->rhl.verlen); + ofs += m_stat->rhl.verlenlen; + snmp_asn1_enc_s32t(p, ofs, m_stat->rhl.verlen, snmp_version); + ofs += m_stat->rhl.verlen; + + snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR)); + ofs += 1; + snmp_asn1_enc_length(p, ofs, m_stat->rhl.comlen); + ofs += m_stat->rhl.comlenlen; + snmp_asn1_enc_raw(p, ofs, m_stat->rhl.comlen, m_stat->community); + ofs += m_stat->rhl.comlen; + + snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_CONTXT | SNMP_ASN1_CONSTR | SNMP_ASN1_PDU_GET_RESP)); + ofs += 1; + snmp_asn1_enc_length(p, ofs, m_stat->rhl.pdulen); + ofs += m_stat->rhl.pdulenlen; + + snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG)); + ofs += 1; + snmp_asn1_enc_length(p, ofs, m_stat->rhl.ridlen); + ofs += m_stat->rhl.ridlenlen; + snmp_asn1_enc_s32t(p, ofs, m_stat->rhl.ridlen, m_stat->rid); + ofs += m_stat->rhl.ridlen; + + snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG)); + ofs += 1; + snmp_asn1_enc_length(p, ofs, m_stat->rhl.errstatlen); + ofs += m_stat->rhl.errstatlenlen; + snmp_asn1_enc_s32t(p, ofs, m_stat->rhl.errstatlen, m_stat->error_status); + ofs += m_stat->rhl.errstatlen; + + snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG)); + ofs += 1; + snmp_asn1_enc_length(p, ofs, m_stat->rhl.erridxlen); + ofs += m_stat->rhl.erridxlenlen; + snmp_asn1_enc_s32t(p, ofs, m_stat->rhl.erridxlen, m_stat->error_index); + ofs += m_stat->rhl.erridxlen; + + return ofs; +} + +/** + * Encodes trap header from head to tail. + */ +static u16_t +snmp_trap_header_enc(struct snmp_msg_trap *m_trap, struct pbuf *p) +{ + u16_t ofs; + + ofs = 0; + snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_CONSTR | SNMP_ASN1_SEQ)); + ofs += 1; + snmp_asn1_enc_length(p, ofs, m_trap->thl.seqlen); + ofs += m_trap->thl.seqlenlen; + + snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG)); + ofs += 1; + snmp_asn1_enc_length(p, ofs, m_trap->thl.verlen); + ofs += m_trap->thl.verlenlen; + snmp_asn1_enc_s32t(p, ofs, m_trap->thl.verlen, snmp_version); + ofs += m_trap->thl.verlen; + + snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR)); + ofs += 1; + snmp_asn1_enc_length(p, ofs, m_trap->thl.comlen); + ofs += m_trap->thl.comlenlen; + snmp_asn1_enc_raw(p, ofs, m_trap->thl.comlen, (u8_t *)&snmp_publiccommunity[0]); + ofs += m_trap->thl.comlen; + + snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_CONTXT | SNMP_ASN1_CONSTR | SNMP_ASN1_PDU_TRAP)); + ofs += 1; + snmp_asn1_enc_length(p, ofs, m_trap->thl.pdulen); + ofs += m_trap->thl.pdulenlen; + + snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OBJ_ID)); + ofs += 1; + snmp_asn1_enc_length(p, ofs, m_trap->thl.eidlen); + ofs += m_trap->thl.eidlenlen; + snmp_asn1_enc_oid(p, ofs, m_trap->enterprise->len, &m_trap->enterprise->id[0]); + ofs += m_trap->thl.eidlen; + + snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_IPADDR)); + ofs += 1; + snmp_asn1_enc_length(p, ofs, m_trap->thl.aaddrlen); + ofs += m_trap->thl.aaddrlenlen; + snmp_asn1_enc_raw(p, ofs, m_trap->thl.aaddrlen, &m_trap->sip_raw[0]); + ofs += m_trap->thl.aaddrlen; + + snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG)); + ofs += 1; + snmp_asn1_enc_length(p, ofs, m_trap->thl.gtrplen); + ofs += m_trap->thl.gtrplenlen; + snmp_asn1_enc_u32t(p, ofs, m_trap->thl.gtrplen, m_trap->gen_trap); + ofs += m_trap->thl.gtrplen; + + snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG)); + ofs += 1; + snmp_asn1_enc_length(p, ofs, m_trap->thl.strplen); + ofs += m_trap->thl.strplenlen; + snmp_asn1_enc_u32t(p, ofs, m_trap->thl.strplen, m_trap->spc_trap); + ofs += m_trap->thl.strplen; + + snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_TIMETICKS)); + ofs += 1; + snmp_asn1_enc_length(p, ofs, m_trap->thl.tslen); + ofs += m_trap->thl.tslenlen; + snmp_asn1_enc_u32t(p, ofs, m_trap->thl.tslen, m_trap->ts); + ofs += m_trap->thl.tslen; + + return ofs; +} + +/** + * Encodes varbind list from head to tail. + */ +static u16_t +snmp_varbind_list_enc(struct snmp_varbind_root *root, struct pbuf *p, u16_t ofs) +{ + struct snmp_varbind *vb; + s32_t *sint_ptr; + u32_t *uint_ptr; + u8_t *raw_ptr; + + snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_CONSTR | SNMP_ASN1_SEQ)); + ofs += 1; + snmp_asn1_enc_length(p, ofs, root->seqlen); + ofs += root->seqlenlen; + + vb = root->head; + while ( vb != NULL ) + { + snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_CONSTR | SNMP_ASN1_SEQ)); + ofs += 1; + snmp_asn1_enc_length(p, ofs, vb->seqlen); + ofs += vb->seqlenlen; + + snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OBJ_ID)); + ofs += 1; + snmp_asn1_enc_length(p, ofs, vb->olen); + ofs += vb->olenlen; + snmp_asn1_enc_oid(p, ofs, vb->ident_len, &vb->ident[0]); + ofs += vb->olen; + + snmp_asn1_enc_type(p, ofs, vb->value_type); + ofs += 1; + snmp_asn1_enc_length(p, ofs, vb->vlen); + ofs += vb->vlenlen; + + switch (vb->value_type) + { + case (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG): + sint_ptr = (s32_t*)vb->value; + snmp_asn1_enc_s32t(p, ofs, vb->vlen, *sint_ptr); + break; + case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_COUNTER): + case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_GAUGE): + case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_TIMETICKS): + uint_ptr = (u32_t*)vb->value; + snmp_asn1_enc_u32t(p, ofs, vb->vlen, *uint_ptr); + break; + case (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR): + case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_IPADDR): + case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_OPAQUE): + raw_ptr = (u8_t*)vb->value; + snmp_asn1_enc_raw(p, ofs, vb->vlen, raw_ptr); + break; + case (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_NUL): + break; + case (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OBJ_ID): + sint_ptr = (s32_t*)vb->value; + snmp_asn1_enc_oid(p, ofs, vb->value_len / sizeof(s32_t), sint_ptr); + break; + default: + /* unsupported type */ + break; + }; + ofs += vb->vlen; + vb = vb->next; + } + return ofs; +} + +#endif /* LWIP_SNMP */ diff --git a/src/lwip-1.4.1/src/core/stats.c b/src/lwip-1.4.1/src/core/stats.c new file mode 100644 index 0000000..8ea8249 --- /dev/null +++ b/src/lwip-1.4.1/src/core/stats.c @@ -0,0 +1,176 @@ +/** + * @file + * Statistics module + * + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#include "lwip/opt.h" + +#if LWIP_STATS /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/def.h" +#include "lwip/stats.h" +#include "lwip/mem.h" + +#include + +struct stats_ lwip_stats; + +void stats_init(void) +{ +#ifdef LWIP_DEBUG +#if MEMP_STATS + const char * memp_names[] = { +#define LWIP_MEMPOOL(name,num,size,desc) desc, +#include "lwip/memp_std.h" + }; + int i; + for (i = 0; i < MEMP_MAX; i++) { + lwip_stats.memp[i].name = memp_names[i]; + } +#endif /* MEMP_STATS */ +#if MEM_STATS + lwip_stats.mem.name = "MEM"; +#endif /* MEM_STATS */ +#endif /* LWIP_DEBUG */ +} + +#if LWIP_STATS_DISPLAY +void +stats_display_proto(struct stats_proto *proto, const char *name) +{ + LWIP_PLATFORM_DIAG(("\n%s\n\t", name)); + LWIP_PLATFORM_DIAG(("xmit: %"STAT_COUNTER_F"\n\t", proto->xmit)); + LWIP_PLATFORM_DIAG(("recv: %"STAT_COUNTER_F"\n\t", proto->recv)); + LWIP_PLATFORM_DIAG(("fw: %"STAT_COUNTER_F"\n\t", proto->fw)); + LWIP_PLATFORM_DIAG(("drop: %"STAT_COUNTER_F"\n\t", proto->drop)); + LWIP_PLATFORM_DIAG(("chkerr: %"STAT_COUNTER_F"\n\t", proto->chkerr)); + LWIP_PLATFORM_DIAG(("lenerr: %"STAT_COUNTER_F"\n\t", proto->lenerr)); + LWIP_PLATFORM_DIAG(("memerr: %"STAT_COUNTER_F"\n\t", proto->memerr)); + LWIP_PLATFORM_DIAG(("rterr: %"STAT_COUNTER_F"\n\t", proto->rterr)); + LWIP_PLATFORM_DIAG(("proterr: %"STAT_COUNTER_F"\n\t", proto->proterr)); + LWIP_PLATFORM_DIAG(("opterr: %"STAT_COUNTER_F"\n\t", proto->opterr)); + LWIP_PLATFORM_DIAG(("err: %"STAT_COUNTER_F"\n\t", proto->err)); + LWIP_PLATFORM_DIAG(("cachehit: %"STAT_COUNTER_F"\n", proto->cachehit)); +} + +#if IGMP_STATS +void +stats_display_igmp(struct stats_igmp *igmp) +{ + LWIP_PLATFORM_DIAG(("\nIGMP\n\t")); + LWIP_PLATFORM_DIAG(("xmit: %"STAT_COUNTER_F"\n\t", igmp->xmit)); + LWIP_PLATFORM_DIAG(("recv: %"STAT_COUNTER_F"\n\t", igmp->recv)); + LWIP_PLATFORM_DIAG(("drop: %"STAT_COUNTER_F"\n\t", igmp->drop)); + LWIP_PLATFORM_DIAG(("chkerr: %"STAT_COUNTER_F"\n\t", igmp->chkerr)); + LWIP_PLATFORM_DIAG(("lenerr: %"STAT_COUNTER_F"\n\t", igmp->lenerr)); + LWIP_PLATFORM_DIAG(("memerr: %"STAT_COUNTER_F"\n\t", igmp->memerr)); + LWIP_PLATFORM_DIAG(("proterr: %"STAT_COUNTER_F"\n\t", igmp->proterr)); + LWIP_PLATFORM_DIAG(("rx_v1: %"STAT_COUNTER_F"\n\t", igmp->rx_v1)); + LWIP_PLATFORM_DIAG(("rx_group: %"STAT_COUNTER_F"\n", igmp->rx_group)); + LWIP_PLATFORM_DIAG(("rx_general: %"STAT_COUNTER_F"\n", igmp->rx_general)); + LWIP_PLATFORM_DIAG(("rx_report: %"STAT_COUNTER_F"\n\t", igmp->rx_report)); + LWIP_PLATFORM_DIAG(("tx_join: %"STAT_COUNTER_F"\n\t", igmp->tx_join)); + LWIP_PLATFORM_DIAG(("tx_leave: %"STAT_COUNTER_F"\n\t", igmp->tx_leave)); + LWIP_PLATFORM_DIAG(("tx_report: %"STAT_COUNTER_F"\n\t", igmp->tx_report)); +} +#endif /* IGMP_STATS */ + +#if MEM_STATS || MEMP_STATS +void +stats_display_mem(struct stats_mem *mem, const char *name) +{ + LWIP_PLATFORM_DIAG(("\nMEM %s\n\t", name)); + LWIP_PLATFORM_DIAG(("avail: %"U32_F"\n\t", (u32_t)mem->avail)); + LWIP_PLATFORM_DIAG(("used: %"U32_F"\n\t", (u32_t)mem->used)); + LWIP_PLATFORM_DIAG(("max: %"U32_F"\n\t", (u32_t)mem->max)); + LWIP_PLATFORM_DIAG(("err: %"U32_F"\n", (u32_t)mem->err)); +} + +#if MEMP_STATS +void +stats_display_memp(struct stats_mem *mem, int index) +{ + char * memp_names[] = { +#define LWIP_MEMPOOL(name,num,size,desc) desc, +#include "lwip/memp_std.h" + }; + if(index < MEMP_MAX) { + stats_display_mem(mem, memp_names[index]); + } +} +#endif /* MEMP_STATS */ +#endif /* MEM_STATS || MEMP_STATS */ + +#if SYS_STATS +void +stats_display_sys(struct stats_sys *sys) +{ + LWIP_PLATFORM_DIAG(("\nSYS\n\t")); + LWIP_PLATFORM_DIAG(("sem.used: %"U32_F"\n\t", (u32_t)sys->sem.used)); + LWIP_PLATFORM_DIAG(("sem.max: %"U32_F"\n\t", (u32_t)sys->sem.max)); + LWIP_PLATFORM_DIAG(("sem.err: %"U32_F"\n\t", (u32_t)sys->sem.err)); + LWIP_PLATFORM_DIAG(("mutex.used: %"U32_F"\n\t", (u32_t)sys->mutex.used)); + LWIP_PLATFORM_DIAG(("mutex.max: %"U32_F"\n\t", (u32_t)sys->mutex.max)); + LWIP_PLATFORM_DIAG(("mutex.err: %"U32_F"\n\t", (u32_t)sys->mutex.err)); + LWIP_PLATFORM_DIAG(("mbox.used: %"U32_F"\n\t", (u32_t)sys->mbox.used)); + LWIP_PLATFORM_DIAG(("mbox.max: %"U32_F"\n\t", (u32_t)sys->mbox.max)); + LWIP_PLATFORM_DIAG(("mbox.err: %"U32_F"\n\t", (u32_t)sys->mbox.err)); +} +#endif /* SYS_STATS */ + +void +stats_display(void) +{ + s16_t i; + + LINK_STATS_DISPLAY(); + ETHARP_STATS_DISPLAY(); + IPFRAG_STATS_DISPLAY(); + IP_STATS_DISPLAY(); + IGMP_STATS_DISPLAY(); + ICMP_STATS_DISPLAY(); + UDP_STATS_DISPLAY(); + TCP_STATS_DISPLAY(); + MEM_STATS_DISPLAY(); + for (i = 0; i < MEMP_MAX; i++) { + MEMP_STATS_DISPLAY(i); + } + SYS_STATS_DISPLAY(); +} +#endif /* LWIP_STATS_DISPLAY */ + +#endif /* LWIP_STATS */ + diff --git a/src/lwip-1.4.1/src/core/sys.c b/src/lwip-1.4.1/src/core/sys.c new file mode 100644 index 0000000..f177737 --- /dev/null +++ b/src/lwip-1.4.1/src/core/sys.c @@ -0,0 +1,68 @@ +/** + * @file + * lwIP Operating System abstraction + * + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#include "lwip/opt.h" + +#include "lwip/sys.h" + +/* Most of the functions defined in sys.h must be implemented in the + * architecture-dependent file sys_arch.c */ + +#if !NO_SYS + +#ifndef sys_msleep +/** + * Sleep for some ms. Timeouts are NOT processed while sleeping. + * + * @param ms number of milliseconds to sleep + */ +void +sys_msleep(u32_t ms) +{ + if (ms > 0) { + sys_sem_t delaysem; + err_t err = sys_sem_new(&delaysem, 0); + if (err == ERR_OK) { + sys_arch_sem_wait(&delaysem, ms); + sys_sem_free(&delaysem); + } + } +} +#endif /* sys_msleep */ + +#endif /* !NO_SYS */ diff --git a/src/lwip-1.4.1/src/core/tcp.c b/src/lwip-1.4.1/src/core/tcp.c new file mode 100644 index 0000000..b710d2e --- /dev/null +++ b/src/lwip-1.4.1/src/core/tcp.c @@ -0,0 +1,1742 @@ +/** + * @file + * Transmission Control Protocol for IP + * + * This file contains common functions for the TCP implementation, such as functinos + * for manipulating the data structures and the TCP timer functions. TCP functions + * related to input and output is found in tcp_in.c and tcp_out.c respectively. + * + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#include "lwip/opt.h" + +#if LWIP_TCP /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/def.h" +#include "lwip/mem.h" +#include "lwip/memp.h" +#include "lwip/snmp.h" +#include "lwip/tcp.h" +#include "lwip/tcp_impl.h" +#include "lwip/debug.h" +#include "lwip/stats.h" + +#include + +#ifndef TCP_LOCAL_PORT_RANGE_START +/* From http://www.iana.org/assignments/port-numbers: + "The Dynamic and/or Private Ports are those from 49152 through 65535" */ +#define TCP_LOCAL_PORT_RANGE_START 0xc000 +#define TCP_LOCAL_PORT_RANGE_END 0xffff +#define TCP_ENSURE_LOCAL_PORT_RANGE(port) (((port) & ~TCP_LOCAL_PORT_RANGE_START) + TCP_LOCAL_PORT_RANGE_START) +#endif + +#if LWIP_TCP_KEEPALIVE +#define TCP_KEEP_DUR(pcb) ((pcb)->keep_cnt * (pcb)->keep_intvl) +#define TCP_KEEP_INTVL(pcb) ((pcb)->keep_intvl) +#else /* LWIP_TCP_KEEPALIVE */ +#define TCP_KEEP_DUR(pcb) TCP_MAXIDLE +#define TCP_KEEP_INTVL(pcb) TCP_KEEPINTVL_DEFAULT +#endif /* LWIP_TCP_KEEPALIVE */ + +const char * const tcp_state_str[] = { + "CLOSED", + "LISTEN", + "SYN_SENT", + "SYN_RCVD", + "ESTABLISHED", + "FIN_WAIT_1", + "FIN_WAIT_2", + "CLOSE_WAIT", + "CLOSING", + "LAST_ACK", + "TIME_WAIT" +}; + +/* last local TCP port */ +static u16_t tcp_port = TCP_LOCAL_PORT_RANGE_START; + +/* Incremented every coarse grained timer shot (typically every 500 ms). */ +u32_t tcp_ticks; +const u8_t tcp_backoff[13] = + { 1, 2, 3, 4, 5, 6, 7, 7, 7, 7, 7, 7, 7}; + /* Times per slowtmr hits */ +const u8_t tcp_persist_backoff[7] = { 3, 6, 12, 24, 48, 96, 120 }; + +/* The TCP PCB lists. */ + +/** List of all TCP PCBs bound but not yet (connected || listening) */ +struct tcp_pcb *tcp_bound_pcbs; +/** List of all TCP PCBs in LISTEN state */ +union tcp_listen_pcbs_t tcp_listen_pcbs; +/** List of all TCP PCBs that are in a state in which + * they accept or send data. */ +struct tcp_pcb *tcp_active_pcbs; +/** List of all TCP PCBs in TIME-WAIT state */ +struct tcp_pcb *tcp_tw_pcbs; + +#define NUM_TCP_PCB_LISTS 4 +#define NUM_TCP_PCB_LISTS_NO_TIME_WAIT 3 +/** An array with all (non-temporary) PCB lists, mainly used for smaller code size */ +struct tcp_pcb ** const tcp_pcb_lists[] = {&tcp_listen_pcbs.pcbs, &tcp_bound_pcbs, + &tcp_active_pcbs, &tcp_tw_pcbs}; + +/** Only used for temporary storage. */ +struct tcp_pcb *tcp_tmp_pcb; + +u8_t tcp_active_pcbs_changed; + +/** Timer counter to handle calling slow-timer from tcp_tmr() */ +static u8_t tcp_timer; +static u8_t tcp_timer_ctr; +static u16_t tcp_new_port(void); + +/** + * Initialize this module. + */ +void +tcp_init(void) +{ +#if LWIP_RANDOMIZE_INITIAL_LOCAL_PORTS && defined(LWIP_RAND) + tcp_port = TCP_ENSURE_LOCAL_PORT_RANGE(LWIP_RAND()); +#endif /* LWIP_RANDOMIZE_INITIAL_LOCAL_PORTS && defined(LWIP_RAND) */ +} + +/** + * Called periodically to dispatch TCP timers. + */ +void +tcp_tmr(void) +{ + /* Call tcp_fasttmr() every 250 ms */ + tcp_fasttmr(); + + if (++tcp_timer & 1) { + /* Call tcp_tmr() every 500 ms, i.e., every other timer + tcp_tmr() is called. */ + tcp_slowtmr(); + } +} + +/** + * Closes the TX side of a connection held by the PCB. + * For tcp_close(), a RST is sent if the application didn't receive all data + * (tcp_recved() not called for all data passed to recv callback). + * + * Listening pcbs are freed and may not be referenced any more. + * Connection pcbs are freed if not yet connected and may not be referenced + * any more. If a connection is established (at least SYN received or in + * a closing state), the connection is closed, and put in a closing state. + * The pcb is then automatically freed in tcp_slowtmr(). It is therefore + * unsafe to reference it. + * + * @param pcb the tcp_pcb to close + * @return ERR_OK if connection has been closed + * another err_t if closing failed and pcb is not freed + */ +static err_t +tcp_close_shutdown(struct tcp_pcb *pcb, u8_t rst_on_unacked_data) +{ + err_t err; + + if (rst_on_unacked_data && ((pcb->state == ESTABLISHED) || (pcb->state == CLOSE_WAIT))) { + if ((pcb->refused_data != NULL) || (pcb->rcv_wnd != TCP_WND)) { + /* Not all data received by application, send RST to tell the remote + side about this. */ + LWIP_ASSERT("pcb->flags & TF_RXCLOSED", pcb->flags & TF_RXCLOSED); + + /* don't call tcp_abort here: we must not deallocate the pcb since + that might not be expected when calling tcp_close */ + tcp_rst(pcb->snd_nxt, pcb->rcv_nxt, &pcb->local_ip, &pcb->remote_ip, + pcb->local_port, pcb->remote_port); + + tcp_pcb_purge(pcb); + TCP_RMV_ACTIVE(pcb); + if (pcb->state == ESTABLISHED) { + /* move to TIME_WAIT since we close actively */ + pcb->state = TIME_WAIT; + TCP_REG(&tcp_tw_pcbs, pcb); + } else { + /* CLOSE_WAIT: deallocate the pcb since we already sent a RST for it */ + memp_free(MEMP_TCP_PCB, pcb); + } + return ERR_OK; + } + } + + switch (pcb->state) { + case CLOSED: + /* Closing a pcb in the CLOSED state might seem erroneous, + * however, it is in this state once allocated and as yet unused + * and the user needs some way to free it should the need arise. + * Calling tcp_close() with a pcb that has already been closed, (i.e. twice) + * or for a pcb that has been used and then entered the CLOSED state + * is erroneous, but this should never happen as the pcb has in those cases + * been freed, and so any remaining handles are bogus. */ + err = ERR_OK; + if (pcb->local_port != 0) { + TCP_RMV(&tcp_bound_pcbs, pcb); + } + memp_free(MEMP_TCP_PCB, pcb); + pcb = NULL; + break; + case LISTEN: + err = ERR_OK; + tcp_pcb_remove(&tcp_listen_pcbs.pcbs, pcb); + memp_free(MEMP_TCP_PCB_LISTEN, pcb); + pcb = NULL; + break; + case SYN_SENT: + err = ERR_OK; + TCP_PCB_REMOVE_ACTIVE(pcb); + memp_free(MEMP_TCP_PCB, pcb); + pcb = NULL; + snmp_inc_tcpattemptfails(); + break; + case SYN_RCVD: + err = tcp_send_fin(pcb); + if (err == ERR_OK) { + snmp_inc_tcpattemptfails(); + pcb->state = FIN_WAIT_1; + } + break; + case ESTABLISHED: + err = tcp_send_fin(pcb); + if (err == ERR_OK) { + snmp_inc_tcpestabresets(); + pcb->state = FIN_WAIT_1; + } + break; + case CLOSE_WAIT: + err = tcp_send_fin(pcb); + if (err == ERR_OK) { + snmp_inc_tcpestabresets(); + pcb->state = LAST_ACK; + } + break; + default: + /* Has already been closed, do nothing. */ + err = ERR_OK; + pcb = NULL; + break; + } + + if (pcb != NULL && err == ERR_OK) { + /* To ensure all data has been sent when tcp_close returns, we have + to make sure tcp_output doesn't fail. + Since we don't really have to ensure all data has been sent when tcp_close + returns (unsent data is sent from tcp timer functions, also), we don't care + for the return value of tcp_output for now. */ + /* @todo: When implementing SO_LINGER, this must be changed somehow: + If SOF_LINGER is set, the data should be sent and acked before close returns. + This can only be valid for sequential APIs, not for the raw API. */ + tcp_output(pcb); + } + return err; +} + +/** + * Closes the connection held by the PCB. + * + * Listening pcbs are freed and may not be referenced any more. + * Connection pcbs are freed if not yet connected and may not be referenced + * any more. If a connection is established (at least SYN received or in + * a closing state), the connection is closed, and put in a closing state. + * The pcb is then automatically freed in tcp_slowtmr(). It is therefore + * unsafe to reference it (unless an error is returned). + * + * @param pcb the tcp_pcb to close + * @return ERR_OK if connection has been closed + * another err_t if closing failed and pcb is not freed + */ +err_t +tcp_close(struct tcp_pcb *pcb) +{ +#if TCP_DEBUG + LWIP_DEBUGF(TCP_DEBUG, ("tcp_close: closing in ")); + tcp_debug_print_state(pcb->state); +#endif /* TCP_DEBUG */ + + if (pcb->state != LISTEN) { + /* Set a flag not to receive any more data... */ + pcb->flags |= TF_RXCLOSED; + } + /* ... and close */ + return tcp_close_shutdown(pcb, 1); +} + +/** + * Causes all or part of a full-duplex connection of this PCB to be shut down. + * This doesn't deallocate the PCB unless shutting down both sides! + * Shutting down both sides is the same as calling tcp_close, so if it succeds, + * the PCB should not be referenced any more. + * + * @param pcb PCB to shutdown + * @param shut_rx shut down receive side if this is != 0 + * @param shut_tx shut down send side if this is != 0 + * @return ERR_OK if shutdown succeeded (or the PCB has already been shut down) + * another err_t on error. + */ +err_t +tcp_shutdown(struct tcp_pcb *pcb, int shut_rx, int shut_tx) +{ + if (pcb->state == LISTEN) { + return ERR_CONN; + } + if (shut_rx) { + /* shut down the receive side: set a flag not to receive any more data... */ + pcb->flags |= TF_RXCLOSED; + if (shut_tx) { + /* shutting down the tx AND rx side is the same as closing for the raw API */ + return tcp_close_shutdown(pcb, 1); + } + /* ... and free buffered data */ + if (pcb->refused_data != NULL) { + pbuf_free(pcb->refused_data); + pcb->refused_data = NULL; + } + } + if (shut_tx) { + /* This can't happen twice since if it succeeds, the pcb's state is changed. + Only close in these states as the others directly deallocate the PCB */ + switch (pcb->state) { + case SYN_RCVD: + case ESTABLISHED: + case CLOSE_WAIT: + return tcp_close_shutdown(pcb, shut_rx); + default: + /* Not (yet?) connected, cannot shutdown the TX side as that would bring us + into CLOSED state, where the PCB is deallocated. */ + return ERR_CONN; + } + } + return ERR_OK; +} + +/** + * Abandons a connection and optionally sends a RST to the remote + * host. Deletes the local protocol control block. This is done when + * a connection is killed because of shortage of memory. + * + * @param pcb the tcp_pcb to abort + * @param reset boolean to indicate whether a reset should be sent + */ +void +tcp_abandon(struct tcp_pcb *pcb, int reset) +{ + u32_t seqno, ackno; +#if LWIP_CALLBACK_API + tcp_err_fn errf; +#endif /* LWIP_CALLBACK_API */ + void *errf_arg; + + /* pcb->state LISTEN not allowed here */ + LWIP_ASSERT("don't call tcp_abort/tcp_abandon for listen-pcbs", + pcb->state != LISTEN); + /* Figure out on which TCP PCB list we are, and remove us. If we + are in an active state, call the receive function associated with + the PCB with a NULL argument, and send an RST to the remote end. */ + if (pcb->state == TIME_WAIT) { + tcp_pcb_remove(&tcp_tw_pcbs, pcb); + memp_free(MEMP_TCP_PCB, pcb); + } else { + seqno = pcb->snd_nxt; + ackno = pcb->rcv_nxt; +#if LWIP_CALLBACK_API + errf = pcb->errf; +#endif /* LWIP_CALLBACK_API */ + errf_arg = pcb->callback_arg; + TCP_PCB_REMOVE_ACTIVE(pcb); + if (pcb->unacked != NULL) { + tcp_segs_free(pcb->unacked); + } + if (pcb->unsent != NULL) { + tcp_segs_free(pcb->unsent); + } +#if TCP_QUEUE_OOSEQ + if (pcb->ooseq != NULL) { + tcp_segs_free(pcb->ooseq); + } +#endif /* TCP_QUEUE_OOSEQ */ + if (reset) { + LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_abandon: sending RST\n")); + tcp_rst(seqno, ackno, &pcb->local_ip, &pcb->remote_ip, pcb->local_port, pcb->remote_port); + } + memp_free(MEMP_TCP_PCB, pcb); + TCP_EVENT_ERR(errf, errf_arg, ERR_ABRT); + } +} + +/** + * Aborts the connection by sending a RST (reset) segment to the remote + * host. The pcb is deallocated. This function never fails. + * + * ATTENTION: When calling this from one of the TCP callbacks, make + * sure you always return ERR_ABRT (and never return ERR_ABRT otherwise + * or you will risk accessing deallocated memory or memory leaks! + * + * @param pcb the tcp pcb to abort + */ +void +tcp_abort(struct tcp_pcb *pcb) +{ + tcp_abandon(pcb, 1); +} + +/** + * Binds the connection to a local portnumber and IP address. If the + * IP address is not given (i.e., ipaddr == NULL), the IP address of + * the outgoing network interface is used instead. + * + * @param pcb the tcp_pcb to bind (no check is done whether this pcb is + * already bound!) + * @param ipaddr the local ip address to bind to (use IP_ADDR_ANY to bind + * to any local address + * @param port the local port to bind to + * @return ERR_USE if the port is already in use + * ERR_VAL if bind failed because the PCB is not in a valid state + * ERR_OK if bound + */ +err_t +tcp_bind(struct tcp_pcb *pcb, ip_addr_t *ipaddr, u16_t port) +{ + int i; + int max_pcb_list = NUM_TCP_PCB_LISTS; + struct tcp_pcb *cpcb; + + LWIP_ERROR("tcp_bind: can only bind in state CLOSED", pcb->state == CLOSED, return ERR_VAL); + +#if SO_REUSE + /* Unless the REUSEADDR flag is set, + we have to check the pcbs in TIME-WAIT state, also. + We do not dump TIME_WAIT pcb's; they can still be matched by incoming + packets using both local and remote IP addresses and ports to distinguish. + */ + if (ip_get_option(pcb, SOF_REUSEADDR)) { + max_pcb_list = NUM_TCP_PCB_LISTS_NO_TIME_WAIT; + } +#endif /* SO_REUSE */ + + if (port == 0) { + port = tcp_new_port(); + if (port == 0) { + return ERR_BUF; + } + } + + /* Check if the address already is in use (on all lists) */ + for (i = 0; i < max_pcb_list; i++) { + for(cpcb = *tcp_pcb_lists[i]; cpcb != NULL; cpcb = cpcb->next) { + if (cpcb->local_port == port) { +#if SO_REUSE + /* Omit checking for the same port if both pcbs have REUSEADDR set. + For SO_REUSEADDR, the duplicate-check for a 5-tuple is done in + tcp_connect. */ + if (!ip_get_option(pcb, SOF_REUSEADDR) || + !ip_get_option(cpcb, SOF_REUSEADDR)) +#endif /* SO_REUSE */ + { + if (ip_addr_isany(&(cpcb->local_ip)) || + ip_addr_isany(ipaddr) || + ip_addr_cmp(&(cpcb->local_ip), ipaddr)) { + return ERR_USE; + } + } + } + } + } + + if (!ip_addr_isany(ipaddr)) { + pcb->local_ip = *ipaddr; + } + pcb->local_port = port; + TCP_REG(&tcp_bound_pcbs, pcb); + LWIP_DEBUGF(TCP_DEBUG, ("tcp_bind: bind to port %"U16_F"\n", port)); + return ERR_OK; +} +#if LWIP_CALLBACK_API +/** + * Default accept callback if no accept callback is specified by the user. + */ +static err_t +tcp_accept_null(void *arg, struct tcp_pcb *pcb, err_t err) +{ + LWIP_UNUSED_ARG(arg); + LWIP_UNUSED_ARG(pcb); + LWIP_UNUSED_ARG(err); + + return ERR_ABRT; +} +#endif /* LWIP_CALLBACK_API */ + +/** + * Set the state of the connection to be LISTEN, which means that it + * is able to accept incoming connections. The protocol control block + * is reallocated in order to consume less memory. Setting the + * connection to LISTEN is an irreversible process. + * + * @param pcb the original tcp_pcb + * @param backlog the incoming connections queue limit + * @return tcp_pcb used for listening, consumes less memory. + * + * @note The original tcp_pcb is freed. This function therefore has to be + * called like this: + * tpcb = tcp_listen(tpcb); + */ +struct tcp_pcb * +tcp_listen_with_backlog(struct tcp_pcb *pcb, u8_t backlog) +{ + struct tcp_pcb_listen *lpcb; + + LWIP_UNUSED_ARG(backlog); + LWIP_ERROR("tcp_listen: pcb already connected", pcb->state == CLOSED, return NULL); + + /* already listening? */ + if (pcb->state == LISTEN) { + return pcb; + } +#if SO_REUSE + if (ip_get_option(pcb, SOF_REUSEADDR)) { + /* Since SOF_REUSEADDR allows reusing a local address before the pcb's usage + is declared (listen-/connection-pcb), we have to make sure now that + this port is only used once for every local IP. */ + for(lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next) { + if (lpcb->local_port == pcb->local_port) { + if (ip_addr_cmp(&lpcb->local_ip, &pcb->local_ip)) { + /* this address/port is already used */ + return NULL; + } + } + } + } +#endif /* SO_REUSE */ + lpcb = (struct tcp_pcb_listen *)memp_malloc(MEMP_TCP_PCB_LISTEN); + if (lpcb == NULL) { + return NULL; + } + lpcb->callback_arg = pcb->callback_arg; + lpcb->local_port = pcb->local_port; + lpcb->state = LISTEN; + lpcb->prio = pcb->prio; + lpcb->so_options = pcb->so_options; + ip_set_option(lpcb, SOF_ACCEPTCONN); + lpcb->ttl = pcb->ttl; + lpcb->tos = pcb->tos; + ip_addr_copy(lpcb->local_ip, pcb->local_ip); + if (pcb->local_port != 0) { + TCP_RMV(&tcp_bound_pcbs, pcb); + } + memp_free(MEMP_TCP_PCB, pcb); +#if LWIP_CALLBACK_API + lpcb->accept = tcp_accept_null; +#endif /* LWIP_CALLBACK_API */ +#if TCP_LISTEN_BACKLOG + lpcb->accepts_pending = 0; + lpcb->backlog = (backlog ? backlog : 1); +#endif /* TCP_LISTEN_BACKLOG */ + TCP_REG(&tcp_listen_pcbs.pcbs, (struct tcp_pcb *)lpcb); + return (struct tcp_pcb *)lpcb; +} + +/** + * Update the state that tracks the available window space to advertise. + * + * Returns how much extra window would be advertised if we sent an + * update now. + */ +u32_t tcp_update_rcv_ann_wnd(struct tcp_pcb *pcb) +{ + u32_t new_right_edge = pcb->rcv_nxt + pcb->rcv_wnd; + + if (TCP_SEQ_GEQ(new_right_edge, pcb->rcv_ann_right_edge + LWIP_MIN((TCP_WND / 2), pcb->mss))) { + /* we can advertise more window */ + pcb->rcv_ann_wnd = pcb->rcv_wnd; + return new_right_edge - pcb->rcv_ann_right_edge; + } else { + if (TCP_SEQ_GT(pcb->rcv_nxt, pcb->rcv_ann_right_edge)) { + /* Can happen due to other end sending out of advertised window, + * but within actual available (but not yet advertised) window */ + pcb->rcv_ann_wnd = 0; + } else { + /* keep the right edge of window constant */ + u32_t new_rcv_ann_wnd = pcb->rcv_ann_right_edge - pcb->rcv_nxt; + LWIP_ASSERT("new_rcv_ann_wnd <= 0xffff", new_rcv_ann_wnd <= 0xffff); + pcb->rcv_ann_wnd = (u16_t)new_rcv_ann_wnd; + } + return 0; + } +} + +/** + * This function should be called by the application when it has + * processed the data. The purpose is to advertise a larger window + * when the data has been processed. + * + * @param pcb the tcp_pcb for which data is read + * @param len the amount of bytes that have been read by the application + */ +void +tcp_recved(struct tcp_pcb *pcb, u16_t len) +{ + int wnd_inflation; + + /* pcb->state LISTEN not allowed here */ + LWIP_ASSERT("don't call tcp_recved for listen-pcbs", + pcb->state != LISTEN); + LWIP_ASSERT("tcp_recved: len would wrap rcv_wnd\n", + len <= 0xffff - pcb->rcv_wnd ); + + pcb->rcv_wnd += len; + if (pcb->rcv_wnd > TCP_WND) { + pcb->rcv_wnd = TCP_WND; + } + + wnd_inflation = tcp_update_rcv_ann_wnd(pcb); + + /* If the change in the right edge of window is significant (default + * watermark is TCP_WND/4), then send an explicit update now. + * Otherwise wait for a packet to be sent in the normal course of + * events (or more window to be available later) */ + if (wnd_inflation >= TCP_WND_UPDATE_THRESHOLD) { + tcp_ack_now(pcb); + tcp_output(pcb); + } + + LWIP_DEBUGF(TCP_DEBUG, ("tcp_recved: recveived %"U16_F" bytes, wnd %"U16_F" (%"U16_F").\n", + len, pcb->rcv_wnd, TCP_WND - pcb->rcv_wnd)); +} + +/** + * Allocate a new local TCP port. + * + * @return a new (free) local TCP port number + */ +static u16_t +tcp_new_port(void) +{ + u8_t i; + u16_t n = 0; + struct tcp_pcb *pcb; + +again: + if (tcp_port++ == TCP_LOCAL_PORT_RANGE_END) { + tcp_port = TCP_LOCAL_PORT_RANGE_START; + } + /* Check all PCB lists. */ + for (i = 0; i < NUM_TCP_PCB_LISTS; i++) { + for(pcb = *tcp_pcb_lists[i]; pcb != NULL; pcb = pcb->next) { + if (pcb->local_port == tcp_port) { + if (++n > (TCP_LOCAL_PORT_RANGE_END - TCP_LOCAL_PORT_RANGE_START)) { + return 0; + } + goto again; + } + } + } + return tcp_port; +} + +/** + * Connects to another host. The function given as the "connected" + * argument will be called when the connection has been established. + * + * @param pcb the tcp_pcb used to establish the connection + * @param ipaddr the remote ip address to connect to + * @param port the remote tcp port to connect to + * @param connected callback function to call when connected (or on error) + * @return ERR_VAL if invalid arguments are given + * ERR_OK if connect request has been sent + * other err_t values if connect request couldn't be sent + */ +err_t +tcp_connect(struct tcp_pcb *pcb, ip_addr_t *ipaddr, u16_t port, + tcp_connected_fn connected) +{ + err_t ret; + u32_t iss; + u16_t old_local_port; + + LWIP_ERROR("tcp_connect: can only connect from state CLOSED", pcb->state == CLOSED, return ERR_ISCONN); + + LWIP_DEBUGF(TCP_DEBUG, ("tcp_connect to port %"U16_F"\n", port)); + if (ipaddr != NULL) { + pcb->remote_ip = *ipaddr; + } else { + return ERR_VAL; + } + pcb->remote_port = port; + + /* check if we have a route to the remote host */ + if (ip_addr_isany(&(pcb->local_ip))) { + /* no local IP address set, yet. */ + struct netif *netif = ip_route(&(pcb->remote_ip)); + if (netif == NULL) { + /* Don't even try to send a SYN packet if we have no route + since that will fail. */ + return ERR_RTE; + } + /* Use the netif's IP address as local address. */ + ip_addr_copy(pcb->local_ip, netif->ip_addr); + } + + old_local_port = pcb->local_port; + if (pcb->local_port == 0) { + pcb->local_port = tcp_new_port(); + if (pcb->local_port == 0) { + return ERR_BUF; + } + } +#if SO_REUSE + if (ip_get_option(pcb, SOF_REUSEADDR)) { + /* Since SOF_REUSEADDR allows reusing a local address, we have to make sure + now that the 5-tuple is unique. */ + struct tcp_pcb *cpcb; + int i; + /* Don't check listen- and bound-PCBs, check active- and TIME-WAIT PCBs. */ + for (i = 2; i < NUM_TCP_PCB_LISTS; i++) { + for(cpcb = *tcp_pcb_lists[i]; cpcb != NULL; cpcb = cpcb->next) { + if ((cpcb->local_port == pcb->local_port) && + (cpcb->remote_port == port) && + ip_addr_cmp(&cpcb->local_ip, &pcb->local_ip) && + ip_addr_cmp(&cpcb->remote_ip, ipaddr)) { + /* linux returns EISCONN here, but ERR_USE should be OK for us */ + return ERR_USE; + } + } + } + } +#endif /* SO_REUSE */ + iss = tcp_next_iss(); + pcb->rcv_nxt = 0; + pcb->snd_nxt = iss; + pcb->lastack = iss - 1; + pcb->snd_lbb = iss - 1; + pcb->rcv_wnd = TCP_WND; + pcb->rcv_ann_wnd = TCP_WND; + pcb->rcv_ann_right_edge = pcb->rcv_nxt; + pcb->snd_wnd = TCP_WND; + /* As initial send MSS, we use TCP_MSS but limit it to 536. + The send MSS is updated when an MSS option is received. */ + pcb->mss = (TCP_MSS > 536) ? 536 : TCP_MSS; +#if TCP_CALCULATE_EFF_SEND_MSS + pcb->mss = tcp_eff_send_mss(pcb->mss, ipaddr); +#endif /* TCP_CALCULATE_EFF_SEND_MSS */ + pcb->cwnd = 1; + pcb->ssthresh = pcb->mss * 10; +#if LWIP_CALLBACK_API + pcb->connected = connected; +#else /* LWIP_CALLBACK_API */ + LWIP_UNUSED_ARG(connected); +#endif /* LWIP_CALLBACK_API */ + + /* Send a SYN together with the MSS option. */ + ret = tcp_enqueue_flags(pcb, TCP_SYN); + if (ret == ERR_OK) { + /* SYN segment was enqueued, changed the pcbs state now */ + pcb->state = SYN_SENT; + if (old_local_port != 0) { + TCP_RMV(&tcp_bound_pcbs, pcb); + } + TCP_REG_ACTIVE(pcb); + snmp_inc_tcpactiveopens(); + + tcp_output(pcb); + } + return ret; +} + +/** + * Called every 500 ms and implements the retransmission timer and the timer that + * removes PCBs that have been in TIME-WAIT for enough time. It also increments + * various timers such as the inactivity timer in each PCB. + * + * Automatically called from tcp_tmr(). + */ +void +tcp_slowtmr(void) +{ + struct tcp_pcb *pcb, *prev; + u16_t eff_wnd; + u8_t pcb_remove; /* flag if a PCB should be removed */ + u8_t pcb_reset; /* flag if a RST should be sent when removing */ + err_t err; + + err = ERR_OK; + + ++tcp_ticks; + ++tcp_timer_ctr; + +tcp_slowtmr_start: + /* Steps through all of the active PCBs. */ + prev = NULL; + pcb = tcp_active_pcbs; + if (pcb == NULL) { + LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: no active pcbs\n")); + } + while (pcb != NULL) { + LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: processing active pcb\n")); + LWIP_ASSERT("tcp_slowtmr: active pcb->state != CLOSED\n", pcb->state != CLOSED); + LWIP_ASSERT("tcp_slowtmr: active pcb->state != LISTEN\n", pcb->state != LISTEN); + LWIP_ASSERT("tcp_slowtmr: active pcb->state != TIME-WAIT\n", pcb->state != TIME_WAIT); + if (pcb->last_timer == tcp_timer_ctr) { + /* skip this pcb, we have already processed it */ + pcb = pcb->next; + continue; + } + pcb->last_timer = tcp_timer_ctr; + + pcb_remove = 0; + pcb_reset = 0; + + if (pcb->state == SYN_SENT && pcb->nrtx == TCP_SYNMAXRTX) { + ++pcb_remove; + LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: max SYN retries reached\n")); + } + else if (pcb->nrtx == TCP_MAXRTX) { + ++pcb_remove; + LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: max DATA retries reached\n")); + } else { + if (pcb->persist_backoff > 0) { + /* If snd_wnd is zero, use persist timer to send 1 byte probes + * instead of using the standard retransmission mechanism. */ + pcb->persist_cnt++; + if (pcb->persist_cnt >= tcp_persist_backoff[pcb->persist_backoff-1]) { + pcb->persist_cnt = 0; + if (pcb->persist_backoff < sizeof(tcp_persist_backoff)) { + pcb->persist_backoff++; + } + tcp_zero_window_probe(pcb); + } + } else { + /* Increase the retransmission timer if it is running */ + if(pcb->rtime >= 0) { + ++pcb->rtime; + } + + if (pcb->unacked != NULL && pcb->rtime >= pcb->rto) { + /* Time for a retransmission. */ + LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_slowtmr: rtime %"S16_F + " pcb->rto %"S16_F"\n", + pcb->rtime, pcb->rto)); + + /* Double retransmission time-out unless we are trying to + * connect to somebody (i.e., we are in SYN_SENT). */ + if (pcb->state != SYN_SENT) { + pcb->rto = ((pcb->sa >> 3) + pcb->sv) << tcp_backoff[pcb->nrtx]; + } + + /* Reset the retransmission timer. */ + pcb->rtime = 0; + + /* Reduce congestion window and ssthresh. */ + eff_wnd = LWIP_MIN(pcb->cwnd, pcb->snd_wnd); + pcb->ssthresh = eff_wnd >> 1; + if (pcb->ssthresh < (pcb->mss << 1)) { + pcb->ssthresh = (pcb->mss << 1); + } + pcb->cwnd = pcb->mss; + LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_slowtmr: cwnd %"U16_F + " ssthresh %"U16_F"\n", + pcb->cwnd, pcb->ssthresh)); + + /* The following needs to be called AFTER cwnd is set to one + mss - STJ */ + tcp_rexmit_rto(pcb); + } + } + } + /* Check if this PCB has stayed too long in FIN-WAIT-2 */ + if (pcb->state == FIN_WAIT_2) { + /* If this PCB is in FIN_WAIT_2 because of SHUT_WR don't let it time out. */ + if (pcb->flags & TF_RXCLOSED) { + /* PCB was fully closed (either through close() or SHUT_RDWR): + normal FIN-WAIT timeout handling. */ + if ((u32_t)(tcp_ticks - pcb->tmr) > + TCP_FIN_WAIT_TIMEOUT / TCP_SLOW_INTERVAL) { + ++pcb_remove; + LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: removing pcb stuck in FIN-WAIT-2\n")); + } + } + } + + /* Check if KEEPALIVE should be sent */ + if(ip_get_option(pcb, SOF_KEEPALIVE) && + ((pcb->state == ESTABLISHED) || + (pcb->state == CLOSE_WAIT))) { + if((u32_t)(tcp_ticks - pcb->tmr) > + (pcb->keep_idle + TCP_KEEP_DUR(pcb)) / TCP_SLOW_INTERVAL) + { + LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: KEEPALIVE timeout. Aborting connection to %"U16_F".%"U16_F".%"U16_F".%"U16_F".\n", + ip4_addr1_16(&pcb->remote_ip), ip4_addr2_16(&pcb->remote_ip), + ip4_addr3_16(&pcb->remote_ip), ip4_addr4_16(&pcb->remote_ip))); + + ++pcb_remove; + ++pcb_reset; + } + else if((u32_t)(tcp_ticks - pcb->tmr) > + (pcb->keep_idle + pcb->keep_cnt_sent * TCP_KEEP_INTVL(pcb)) + / TCP_SLOW_INTERVAL) + { + tcp_keepalive(pcb); + pcb->keep_cnt_sent++; + } + } + + /* If this PCB has queued out of sequence data, but has been + inactive for too long, will drop the data (it will eventually + be retransmitted). */ +#if TCP_QUEUE_OOSEQ + if (pcb->ooseq != NULL && + (u32_t)tcp_ticks - pcb->tmr >= pcb->rto * TCP_OOSEQ_TIMEOUT) { + tcp_segs_free(pcb->ooseq); + pcb->ooseq = NULL; + LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_slowtmr: dropping OOSEQ queued data\n")); + } +#endif /* TCP_QUEUE_OOSEQ */ + + /* Check if this PCB has stayed too long in SYN-RCVD */ + if (pcb->state == SYN_RCVD) { + if ((u32_t)(tcp_ticks - pcb->tmr) > + TCP_SYN_RCVD_TIMEOUT / TCP_SLOW_INTERVAL) { + ++pcb_remove; + LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: removing pcb stuck in SYN-RCVD\n")); + } + } + + /* Check if this PCB has stayed too long in LAST-ACK */ + if (pcb->state == LAST_ACK) { + if ((u32_t)(tcp_ticks - pcb->tmr) > 2 * TCP_MSL / TCP_SLOW_INTERVAL) { + ++pcb_remove; + LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: removing pcb stuck in LAST-ACK\n")); + } + } + + /* If the PCB should be removed, do it. */ + if (pcb_remove) { + struct tcp_pcb *pcb2; + tcp_err_fn err_fn; + void *err_arg; + tcp_pcb_purge(pcb); + /* Remove PCB from tcp_active_pcbs list. */ + if (prev != NULL) { + LWIP_ASSERT("tcp_slowtmr: middle tcp != tcp_active_pcbs", pcb != tcp_active_pcbs); + prev->next = pcb->next; + } else { + /* This PCB was the first. */ + LWIP_ASSERT("tcp_slowtmr: first pcb == tcp_active_pcbs", tcp_active_pcbs == pcb); + tcp_active_pcbs = pcb->next; + } + + if (pcb_reset) { + tcp_rst(pcb->snd_nxt, pcb->rcv_nxt, &pcb->local_ip, &pcb->remote_ip, + pcb->local_port, pcb->remote_port); + } + + err_fn = pcb->errf; + err_arg = pcb->callback_arg; + pcb2 = pcb; + pcb = pcb->next; + memp_free(MEMP_TCP_PCB, pcb2); + + tcp_active_pcbs_changed = 0; + TCP_EVENT_ERR(err_fn, err_arg, ERR_ABRT); + if (tcp_active_pcbs_changed) { + goto tcp_slowtmr_start; + } + } else { + /* get the 'next' element now and work with 'prev' below (in case of abort) */ + prev = pcb; + pcb = pcb->next; + + /* We check if we should poll the connection. */ + ++prev->polltmr; + if (prev->polltmr >= prev->pollinterval) { + prev->polltmr = 0; + LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: polling application\n")); + tcp_active_pcbs_changed = 0; + TCP_EVENT_POLL(prev, err); + if (tcp_active_pcbs_changed) { + goto tcp_slowtmr_start; + } + /* if err == ERR_ABRT, 'prev' is already deallocated */ + if (err == ERR_OK) { + tcp_output(prev); + } + } + } + } + + + /* Steps through all of the TIME-WAIT PCBs. */ + prev = NULL; + pcb = tcp_tw_pcbs; + while (pcb != NULL) { + LWIP_ASSERT("tcp_slowtmr: TIME-WAIT pcb->state == TIME-WAIT", pcb->state == TIME_WAIT); + pcb_remove = 0; + + /* Check if this PCB has stayed long enough in TIME-WAIT */ + if ((u32_t)(tcp_ticks - pcb->tmr) > 2 * TCP_MSL / TCP_SLOW_INTERVAL) { + ++pcb_remove; + } + + + + /* If the PCB should be removed, do it. */ + if (pcb_remove) { + struct tcp_pcb *pcb2; + tcp_pcb_purge(pcb); + /* Remove PCB from tcp_tw_pcbs list. */ + if (prev != NULL) { + LWIP_ASSERT("tcp_slowtmr: middle tcp != tcp_tw_pcbs", pcb != tcp_tw_pcbs); + prev->next = pcb->next; + } else { + /* This PCB was the first. */ + LWIP_ASSERT("tcp_slowtmr: first pcb == tcp_tw_pcbs", tcp_tw_pcbs == pcb); + tcp_tw_pcbs = pcb->next; + } + pcb2 = pcb; + pcb = pcb->next; + memp_free(MEMP_TCP_PCB, pcb2); + } else { + prev = pcb; + pcb = pcb->next; + } + } +} + +/** + * Is called every TCP_FAST_INTERVAL (250 ms) and process data previously + * "refused" by upper layer (application) and sends delayed ACKs. + * + * Automatically called from tcp_tmr(). + */ +void +tcp_fasttmr(void) +{ + struct tcp_pcb *pcb; + + ++tcp_timer_ctr; + +tcp_fasttmr_start: + pcb = tcp_active_pcbs; + + while(pcb != NULL) { + if (pcb->last_timer != tcp_timer_ctr) { + struct tcp_pcb *next; + pcb->last_timer = tcp_timer_ctr; + /* send delayed ACKs */ + if (pcb->flags & TF_ACK_DELAY) { + LWIP_DEBUGF(TCP_DEBUG, ("tcp_fasttmr: delayed ACK\n")); + tcp_ack_now(pcb); + tcp_output(pcb); + pcb->flags &= ~(TF_ACK_DELAY | TF_ACK_NOW); + } + + next = pcb->next; + + /* If there is data which was previously "refused" by upper layer */ + if (pcb->refused_data != NULL) { + tcp_active_pcbs_changed = 0; + tcp_process_refused_data(pcb); + if (tcp_active_pcbs_changed) { + /* application callback has changed the pcb list: restart the loop */ + goto tcp_fasttmr_start; + } + } + pcb = next; + } + } +} + +/** Pass pcb->refused_data to the recv callback */ +err_t +tcp_process_refused_data(struct tcp_pcb *pcb) +{ + err_t err; + u8_t refused_flags = pcb->refused_data->flags; + /* set pcb->refused_data to NULL in case the callback frees it and then + closes the pcb */ + struct pbuf *refused_data = pcb->refused_data; + pcb->refused_data = NULL; + /* Notify again application with data previously received. */ + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: notify kept packet\n")); + TCP_EVENT_RECV(pcb, refused_data, ERR_OK, err); + if (err == ERR_OK) { + /* did refused_data include a FIN? */ + if (refused_flags & PBUF_FLAG_TCP_FIN) { + /* correct rcv_wnd as the application won't call tcp_recved() + for the FIN's seqno */ + if (pcb->rcv_wnd != TCP_WND) { + pcb->rcv_wnd++; + } + TCP_EVENT_CLOSED(pcb, err); + if (err == ERR_ABRT) { + return ERR_ABRT; + } + } + } else if (err == ERR_ABRT) { + /* if err == ERR_ABRT, 'pcb' is already deallocated */ + /* Drop incoming packets because pcb is "full" (only if the incoming + segment contains data). */ + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: drop incoming packets, because pcb is \"full\"\n")); + return ERR_ABRT; + } else { + /* data is still refused, pbuf is still valid (go on for ACK-only packets) */ + pcb->refused_data = refused_data; + } + return ERR_OK; +} + +/** + * Deallocates a list of TCP segments (tcp_seg structures). + * + * @param seg tcp_seg list of TCP segments to free + */ +void +tcp_segs_free(struct tcp_seg *seg) +{ + while (seg != NULL) { + struct tcp_seg *next = seg->next; + tcp_seg_free(seg); + seg = next; + } +} + +/** + * Frees a TCP segment (tcp_seg structure). + * + * @param seg single tcp_seg to free + */ +void +tcp_seg_free(struct tcp_seg *seg) +{ + if (seg != NULL) { + if (seg->p != NULL) { + pbuf_free(seg->p); +#if TCP_DEBUG + seg->p = NULL; +#endif /* TCP_DEBUG */ + } + memp_free(MEMP_TCP_SEG, seg); + } +} + +/** + * Sets the priority of a connection. + * + * @param pcb the tcp_pcb to manipulate + * @param prio new priority + */ +void +tcp_setprio(struct tcp_pcb *pcb, u8_t prio) +{ + pcb->prio = prio; +} + +#if TCP_QUEUE_OOSEQ +/** + * Returns a copy of the given TCP segment. + * The pbuf and data are not copied, only the pointers + * + * @param seg the old tcp_seg + * @return a copy of seg + */ +struct tcp_seg * +tcp_seg_copy(struct tcp_seg *seg) +{ + struct tcp_seg *cseg; + + cseg = (struct tcp_seg *)memp_malloc(MEMP_TCP_SEG); + if (cseg == NULL) { + return NULL; + } + SMEMCPY((u8_t *)cseg, (const u8_t *)seg, sizeof(struct tcp_seg)); + pbuf_ref(cseg->p); + return cseg; +} +#endif /* TCP_QUEUE_OOSEQ */ + +#if LWIP_CALLBACK_API +/** + * Default receive callback that is called if the user didn't register + * a recv callback for the pcb. + */ +err_t +tcp_recv_null(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err) +{ + LWIP_UNUSED_ARG(arg); + if (p != NULL) { + tcp_recved(pcb, p->tot_len); + pbuf_free(p); + } else if (err == ERR_OK) { + return tcp_close(pcb); + } + return ERR_OK; +} +#endif /* LWIP_CALLBACK_API */ + +/** + * Kills the oldest active connection that has the same or lower priority than + * 'prio'. + * + * @param prio minimum priority + */ +static void +tcp_kill_prio(u8_t prio) +{ + struct tcp_pcb *pcb, *inactive; + u32_t inactivity; + u8_t mprio; + + + mprio = TCP_PRIO_MAX; + + /* We kill the oldest active connection that has lower priority than prio. */ + inactivity = 0; + inactive = NULL; + for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) { + if (pcb->prio <= prio && + pcb->prio <= mprio && + (u32_t)(tcp_ticks - pcb->tmr) >= inactivity) { + inactivity = tcp_ticks - pcb->tmr; + inactive = pcb; + mprio = pcb->prio; + } + } + if (inactive != NULL) { + LWIP_DEBUGF(TCP_DEBUG, ("tcp_kill_prio: killing oldest PCB %p (%"S32_F")\n", + (void *)inactive, inactivity)); + tcp_abort(inactive); + } +} + +/** + * Kills the oldest connection that is in TIME_WAIT state. + * Called from tcp_alloc() if no more connections are available. + */ +static void +tcp_kill_timewait(void) +{ + struct tcp_pcb *pcb, *inactive; + u32_t inactivity; + + inactivity = 0; + inactive = NULL; + /* Go through the list of TIME_WAIT pcbs and get the oldest pcb. */ + for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) { + if ((u32_t)(tcp_ticks - pcb->tmr) >= inactivity) { + inactivity = tcp_ticks - pcb->tmr; + inactive = pcb; + } + } + if (inactive != NULL) { + LWIP_DEBUGF(TCP_DEBUG, ("tcp_kill_timewait: killing oldest TIME-WAIT PCB %p (%"S32_F")\n", + (void *)inactive, inactivity)); + tcp_abort(inactive); + } +} + +/** + * Allocate a new tcp_pcb structure. + * + * @param prio priority for the new pcb + * @return a new tcp_pcb that initially is in state CLOSED + */ +struct tcp_pcb * +tcp_alloc(u8_t prio) +{ + struct tcp_pcb *pcb; + u32_t iss; + + pcb = (struct tcp_pcb *)memp_malloc(MEMP_TCP_PCB); + if (pcb == NULL) { + /* Try killing oldest connection in TIME-WAIT. */ + LWIP_DEBUGF(TCP_DEBUG, ("tcp_alloc: killing off oldest TIME-WAIT connection\n")); + tcp_kill_timewait(); + /* Try to allocate a tcp_pcb again. */ + pcb = (struct tcp_pcb *)memp_malloc(MEMP_TCP_PCB); + if (pcb == NULL) { + /* Try killing active connections with lower priority than the new one. */ + LWIP_DEBUGF(TCP_DEBUG, ("tcp_alloc: killing connection with prio lower than %d\n", prio)); + tcp_kill_prio(prio); + /* Try to allocate a tcp_pcb again. */ + pcb = (struct tcp_pcb *)memp_malloc(MEMP_TCP_PCB); + if (pcb != NULL) { + /* adjust err stats: memp_malloc failed twice before */ + MEMP_STATS_DEC(err, MEMP_TCP_PCB); + } + } + if (pcb != NULL) { + /* adjust err stats: timewait PCB was freed above */ + MEMP_STATS_DEC(err, MEMP_TCP_PCB); + } + } + if (pcb != NULL) { + memset(pcb, 0, sizeof(struct tcp_pcb)); + pcb->prio = prio; + pcb->snd_buf = TCP_SND_BUF; + pcb->snd_queuelen = 0; + pcb->rcv_wnd = TCP_WND; + pcb->rcv_ann_wnd = TCP_WND; + pcb->tos = 0; + pcb->ttl = TCP_TTL; + /* As initial send MSS, we use TCP_MSS but limit it to 536. + The send MSS is updated when an MSS option is received. */ + pcb->mss = (TCP_MSS > 536) ? 536 : TCP_MSS; + pcb->rto = 3000 / TCP_SLOW_INTERVAL; + pcb->sa = 0; + pcb->sv = 3000 / TCP_SLOW_INTERVAL; + pcb->rtime = -1; + pcb->cwnd = 1; + iss = tcp_next_iss(); + pcb->snd_wl2 = iss; + pcb->snd_nxt = iss; + pcb->lastack = iss; + pcb->snd_lbb = iss; + pcb->tmr = tcp_ticks; + pcb->last_timer = tcp_timer_ctr; + + pcb->polltmr = 0; + +#if LWIP_CALLBACK_API + pcb->recv = tcp_recv_null; +#endif /* LWIP_CALLBACK_API */ + + /* Init KEEPALIVE timer */ + pcb->keep_idle = TCP_KEEPIDLE_DEFAULT; + +#if LWIP_TCP_KEEPALIVE + pcb->keep_intvl = TCP_KEEPINTVL_DEFAULT; + pcb->keep_cnt = TCP_KEEPCNT_DEFAULT; +#endif /* LWIP_TCP_KEEPALIVE */ + + pcb->keep_cnt_sent = 0; + } + return pcb; +} + +/** + * Creates a new TCP protocol control block but doesn't place it on + * any of the TCP PCB lists. + * The pcb is not put on any list until binding using tcp_bind(). + * + * @internal: Maybe there should be a idle TCP PCB list where these + * PCBs are put on. Port reservation using tcp_bind() is implemented but + * allocated pcbs that are not bound can't be killed automatically if wanting + * to allocate a pcb with higher prio (@see tcp_kill_prio()) + * + * @return a new tcp_pcb that initially is in state CLOSED + */ +struct tcp_pcb * +tcp_new(void) +{ + return tcp_alloc(TCP_PRIO_NORMAL); +} + +/** + * Used to specify the argument that should be passed callback + * functions. + * + * @param pcb tcp_pcb to set the callback argument + * @param arg void pointer argument to pass to callback functions + */ +void +tcp_arg(struct tcp_pcb *pcb, void *arg) +{ + /* This function is allowed to be called for both listen pcbs and + connection pcbs. */ + pcb->callback_arg = arg; +} +#if LWIP_CALLBACK_API + +/** + * Used to specify the function that should be called when a TCP + * connection receives data. + * + * @param pcb tcp_pcb to set the recv callback + * @param recv callback function to call for this pcb when data is received + */ +void +tcp_recv(struct tcp_pcb *pcb, tcp_recv_fn recv) +{ + LWIP_ASSERT("invalid socket state for recv callback", pcb->state != LISTEN); + pcb->recv = recv; +} + +/** + * Used to specify the function that should be called when TCP data + * has been successfully delivered to the remote host. + * + * @param pcb tcp_pcb to set the sent callback + * @param sent callback function to call for this pcb when data is successfully sent + */ +void +tcp_sent(struct tcp_pcb *pcb, tcp_sent_fn sent) +{ + LWIP_ASSERT("invalid socket state for sent callback", pcb->state != LISTEN); + pcb->sent = sent; +} + +/** + * Used to specify the function that should be called when a fatal error + * has occured on the connection. + * + * @param pcb tcp_pcb to set the err callback + * @param err callback function to call for this pcb when a fatal error + * has occured on the connection + */ +void +tcp_err(struct tcp_pcb *pcb, tcp_err_fn err) +{ + LWIP_ASSERT("invalid socket state for err callback", pcb->state != LISTEN); + pcb->errf = err; +} + +/** + * Used for specifying the function that should be called when a + * LISTENing connection has been connected to another host. + * + * @param pcb tcp_pcb to set the accept callback + * @param accept callback function to call for this pcb when LISTENing + * connection has been connected to another host + */ +void +tcp_accept(struct tcp_pcb *pcb, tcp_accept_fn accept) +{ + /* This function is allowed to be called for both listen pcbs and + connection pcbs. */ + pcb->accept = accept; +} +#endif /* LWIP_CALLBACK_API */ + + +/** + * Used to specify the function that should be called periodically + * from TCP. The interval is specified in terms of the TCP coarse + * timer interval, which is called twice a second. + * + */ +void +tcp_poll(struct tcp_pcb *pcb, tcp_poll_fn poll, u8_t interval) +{ + LWIP_ASSERT("invalid socket state for poll", pcb->state != LISTEN); +#if LWIP_CALLBACK_API + pcb->poll = poll; +#else /* LWIP_CALLBACK_API */ + LWIP_UNUSED_ARG(poll); +#endif /* LWIP_CALLBACK_API */ + pcb->pollinterval = interval; +} + +/** + * Purges a TCP PCB. Removes any buffered data and frees the buffer memory + * (pcb->ooseq, pcb->unsent and pcb->unacked are freed). + * + * @param pcb tcp_pcb to purge. The pcb itself is not deallocated! + */ +void +tcp_pcb_purge(struct tcp_pcb *pcb) +{ + if (pcb->state != CLOSED && + pcb->state != TIME_WAIT && + pcb->state != LISTEN) { + + LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge\n")); + +#if TCP_LISTEN_BACKLOG + if (pcb->state == SYN_RCVD) { + /* Need to find the corresponding listen_pcb and decrease its accepts_pending */ + struct tcp_pcb_listen *lpcb; + LWIP_ASSERT("tcp_pcb_purge: pcb->state == SYN_RCVD but tcp_listen_pcbs is NULL", + tcp_listen_pcbs.listen_pcbs != NULL); + for (lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next) { + if ((lpcb->local_port == pcb->local_port) && + (ip_addr_isany(&lpcb->local_ip) || + ip_addr_cmp(&pcb->local_ip, &lpcb->local_ip))) { + /* port and address of the listen pcb match the timed-out pcb */ + LWIP_ASSERT("tcp_pcb_purge: listen pcb does not have accepts pending", + lpcb->accepts_pending > 0); + lpcb->accepts_pending--; + break; + } + } + } +#endif /* TCP_LISTEN_BACKLOG */ + + + if (pcb->refused_data != NULL) { + LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge: data left on ->refused_data\n")); + pbuf_free(pcb->refused_data); + pcb->refused_data = NULL; + } + if (pcb->unsent != NULL) { + LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge: not all data sent\n")); + } + if (pcb->unacked != NULL) { + LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge: data left on ->unacked\n")); + } +#if TCP_QUEUE_OOSEQ + if (pcb->ooseq != NULL) { + LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge: data left on ->ooseq\n")); + } + tcp_segs_free(pcb->ooseq); + pcb->ooseq = NULL; +#endif /* TCP_QUEUE_OOSEQ */ + + /* Stop the retransmission timer as it will expect data on unacked + queue if it fires */ + pcb->rtime = -1; + + tcp_segs_free(pcb->unsent); + tcp_segs_free(pcb->unacked); + pcb->unacked = pcb->unsent = NULL; +#if TCP_OVERSIZE + pcb->unsent_oversize = 0; +#endif /* TCP_OVERSIZE */ + } +} + +/** + * Purges the PCB and removes it from a PCB list. Any delayed ACKs are sent first. + * + * @param pcblist PCB list to purge. + * @param pcb tcp_pcb to purge. The pcb itself is NOT deallocated! + */ +void +tcp_pcb_remove(struct tcp_pcb **pcblist, struct tcp_pcb *pcb) +{ + TCP_RMV(pcblist, pcb); + + tcp_pcb_purge(pcb); + + /* if there is an outstanding delayed ACKs, send it */ + if (pcb->state != TIME_WAIT && + pcb->state != LISTEN && + pcb->flags & TF_ACK_DELAY) { + pcb->flags |= TF_ACK_NOW; + tcp_output(pcb); + } + + if (pcb->state != LISTEN) { + LWIP_ASSERT("unsent segments leaking", pcb->unsent == NULL); + LWIP_ASSERT("unacked segments leaking", pcb->unacked == NULL); +#if TCP_QUEUE_OOSEQ + LWIP_ASSERT("ooseq segments leaking", pcb->ooseq == NULL); +#endif /* TCP_QUEUE_OOSEQ */ + } + + pcb->state = CLOSED; + + LWIP_ASSERT("tcp_pcb_remove: tcp_pcbs_sane()", tcp_pcbs_sane()); +} + +/** + * Calculates a new initial sequence number for new connections. + * + * @return u32_t pseudo random sequence number + */ +u32_t +tcp_next_iss(void) +{ + static u32_t iss = 6510; + + iss += tcp_ticks; /* XXX */ + return iss; +} + +#if TCP_CALCULATE_EFF_SEND_MSS +/** + * Calcluates the effective send mss that can be used for a specific IP address + * by using ip_route to determin the netif used to send to the address and + * calculating the minimum of TCP_MSS and that netif's mtu (if set). + */ +u16_t +tcp_eff_send_mss(u16_t sendmss, ip_addr_t *addr) +{ + u16_t mss_s; + struct netif *outif; + + outif = ip_route(addr); + if ((outif != NULL) && (outif->mtu != 0)) { + mss_s = outif->mtu - IP_HLEN - TCP_HLEN; + /* RFC 1122, chap 4.2.2.6: + * Eff.snd.MSS = min(SendMSS+20, MMS_S) - TCPhdrsize - IPoptionsize + * We correct for TCP options in tcp_write(), and don't support IP options. + */ + sendmss = LWIP_MIN(sendmss, mss_s); + } + return sendmss; +} +#endif /* TCP_CALCULATE_EFF_SEND_MSS */ + +const char* +tcp_debug_state_str(enum tcp_state s) +{ + return tcp_state_str[s]; +} + +#if TCP_DEBUG || TCP_INPUT_DEBUG || TCP_OUTPUT_DEBUG +/** + * Print a tcp header for debugging purposes. + * + * @param tcphdr pointer to a struct tcp_hdr + */ +void +tcp_debug_print(struct tcp_hdr *tcphdr) +{ + LWIP_DEBUGF(TCP_DEBUG, ("TCP header:\n")); + LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n")); + LWIP_DEBUGF(TCP_DEBUG, ("| %5"U16_F" | %5"U16_F" | (src port, dest port)\n", + ntohs(tcphdr->src), ntohs(tcphdr->dest))); + LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n")); + LWIP_DEBUGF(TCP_DEBUG, ("| %010"U32_F" | (seq no)\n", + ntohl(tcphdr->seqno))); + LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n")); + LWIP_DEBUGF(TCP_DEBUG, ("| %010"U32_F" | (ack no)\n", + ntohl(tcphdr->ackno))); + LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n")); + LWIP_DEBUGF(TCP_DEBUG, ("| %2"U16_F" | |%"U16_F"%"U16_F"%"U16_F"%"U16_F"%"U16_F"%"U16_F"| %5"U16_F" | (hdrlen, flags (", + TCPH_HDRLEN(tcphdr), + TCPH_FLAGS(tcphdr) >> 5 & 1, + TCPH_FLAGS(tcphdr) >> 4 & 1, + TCPH_FLAGS(tcphdr) >> 3 & 1, + TCPH_FLAGS(tcphdr) >> 2 & 1, + TCPH_FLAGS(tcphdr) >> 1 & 1, + TCPH_FLAGS(tcphdr) & 1, + ntohs(tcphdr->wnd))); + tcp_debug_print_flags(TCPH_FLAGS(tcphdr)); + LWIP_DEBUGF(TCP_DEBUG, ("), win)\n")); + LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n")); + LWIP_DEBUGF(TCP_DEBUG, ("| 0x%04"X16_F" | %5"U16_F" | (chksum, urgp)\n", + ntohs(tcphdr->chksum), ntohs(tcphdr->urgp))); + LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n")); +} + +/** + * Print a tcp state for debugging purposes. + * + * @param s enum tcp_state to print + */ +void +tcp_debug_print_state(enum tcp_state s) +{ + LWIP_DEBUGF(TCP_DEBUG, ("State: %s\n", tcp_state_str[s])); +} + +/** + * Print tcp flags for debugging purposes. + * + * @param flags tcp flags, all active flags are printed + */ +void +tcp_debug_print_flags(u8_t flags) +{ + if (flags & TCP_FIN) { + LWIP_DEBUGF(TCP_DEBUG, ("FIN ")); + } + if (flags & TCP_SYN) { + LWIP_DEBUGF(TCP_DEBUG, ("SYN ")); + } + if (flags & TCP_RST) { + LWIP_DEBUGF(TCP_DEBUG, ("RST ")); + } + if (flags & TCP_PSH) { + LWIP_DEBUGF(TCP_DEBUG, ("PSH ")); + } + if (flags & TCP_ACK) { + LWIP_DEBUGF(TCP_DEBUG, ("ACK ")); + } + if (flags & TCP_URG) { + LWIP_DEBUGF(TCP_DEBUG, ("URG ")); + } + if (flags & TCP_ECE) { + LWIP_DEBUGF(TCP_DEBUG, ("ECE ")); + } + if (flags & TCP_CWR) { + LWIP_DEBUGF(TCP_DEBUG, ("CWR ")); + } + LWIP_DEBUGF(TCP_DEBUG, ("\n")); +} + +/** + * Print all tcp_pcbs in every list for debugging purposes. + */ +void +tcp_debug_print_pcbs(void) +{ + struct tcp_pcb *pcb; + LWIP_DEBUGF(TCP_DEBUG, ("Active PCB states:\n")); + for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) { + LWIP_DEBUGF(TCP_DEBUG, ("Local port %"U16_F", foreign port %"U16_F" snd_nxt %"U32_F" rcv_nxt %"U32_F" ", + pcb->local_port, pcb->remote_port, + pcb->snd_nxt, pcb->rcv_nxt)); + tcp_debug_print_state(pcb->state); + } + LWIP_DEBUGF(TCP_DEBUG, ("Listen PCB states:\n")); + for(pcb = (struct tcp_pcb *)tcp_listen_pcbs.pcbs; pcb != NULL; pcb = pcb->next) { + LWIP_DEBUGF(TCP_DEBUG, ("Local port %"U16_F", foreign port %"U16_F" snd_nxt %"U32_F" rcv_nxt %"U32_F" ", + pcb->local_port, pcb->remote_port, + pcb->snd_nxt, pcb->rcv_nxt)); + tcp_debug_print_state(pcb->state); + } + LWIP_DEBUGF(TCP_DEBUG, ("TIME-WAIT PCB states:\n")); + for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) { + LWIP_DEBUGF(TCP_DEBUG, ("Local port %"U16_F", foreign port %"U16_F" snd_nxt %"U32_F" rcv_nxt %"U32_F" ", + pcb->local_port, pcb->remote_port, + pcb->snd_nxt, pcb->rcv_nxt)); + tcp_debug_print_state(pcb->state); + } +} + +/** + * Check state consistency of the tcp_pcb lists. + */ +s16_t +tcp_pcbs_sane(void) +{ + struct tcp_pcb *pcb; + for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) { + LWIP_ASSERT("tcp_pcbs_sane: active pcb->state != CLOSED", pcb->state != CLOSED); + LWIP_ASSERT("tcp_pcbs_sane: active pcb->state != LISTEN", pcb->state != LISTEN); + LWIP_ASSERT("tcp_pcbs_sane: active pcb->state != TIME-WAIT", pcb->state != TIME_WAIT); + } + for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) { + LWIP_ASSERT("tcp_pcbs_sane: tw pcb->state == TIME-WAIT", pcb->state == TIME_WAIT); + } + return 1; +} +#endif /* TCP_DEBUG */ + +#endif /* LWIP_TCP */ diff --git a/src/lwip-1.4.1/src/core/tcp_in.c b/src/lwip-1.4.1/src/core/tcp_in.c new file mode 100644 index 0000000..4ec971a --- /dev/null +++ b/src/lwip-1.4.1/src/core/tcp_in.c @@ -0,0 +1,1619 @@ +/** + * @file + * Transmission Control Protocol, incoming traffic + * + * The input processing functions of the TCP layer. + * + * These functions are generally called in the order (ip_input() ->) + * tcp_input() -> * tcp_process() -> tcp_receive() (-> application). + * + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#include "lwip/opt.h" + +#if LWIP_TCP /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/tcp_impl.h" +#include "lwip/def.h" +#include "lwip/ip_addr.h" +#include "lwip/netif.h" +#include "lwip/mem.h" +#include "lwip/memp.h" +#include "lwip/inet_chksum.h" +#include "lwip/stats.h" +#include "lwip/snmp.h" +#include "arch/perf.h" + +/* These variables are global to all functions involved in the input + processing of TCP segments. They are set by the tcp_input() + function. */ +static struct tcp_seg inseg; +static struct tcp_hdr *tcphdr; +static struct ip_hdr *iphdr; +static u32_t seqno, ackno; +static u8_t flags; +static u16_t tcplen; + +static u8_t recv_flags; +static struct pbuf *recv_data; + +struct tcp_pcb *tcp_input_pcb; + +/* Forward declarations. */ +static err_t tcp_process(struct tcp_pcb *pcb); +static void tcp_receive(struct tcp_pcb *pcb); +static void tcp_parseopt(struct tcp_pcb *pcb); + +static err_t tcp_listen_input(struct tcp_pcb_listen *pcb); +static err_t tcp_timewait_input(struct tcp_pcb *pcb); + +/** + * The initial input processing of TCP. It verifies the TCP header, demultiplexes + * the segment between the PCBs and passes it on to tcp_process(), which implements + * the TCP finite state machine. This function is called by the IP layer (in + * ip_input()). + * + * @param p received TCP segment to process (p->payload pointing to the IP header) + * @param inp network interface on which this segment was received + */ +void +tcp_input(struct pbuf *p, struct netif *inp) +{ + struct tcp_pcb *pcb, *prev; + struct tcp_pcb_listen *lpcb; +#if SO_REUSE + struct tcp_pcb *lpcb_prev = NULL; + struct tcp_pcb_listen *lpcb_any = NULL; +#endif /* SO_REUSE */ + u8_t hdrlen; + err_t err; + + PERF_START; + + TCP_STATS_INC(tcp.recv); + snmp_inc_tcpinsegs(); + + iphdr = (struct ip_hdr *)p->payload; + tcphdr = (struct tcp_hdr *)((u8_t *)p->payload + IPH_HL(iphdr) * 4); + +#if TCP_INPUT_DEBUG + tcp_debug_print(tcphdr); +#endif + + /* remove header from payload */ + if (pbuf_header(p, -((s16_t)(IPH_HL(iphdr) * 4))) || (p->tot_len < sizeof(struct tcp_hdr))) { + /* drop short packets */ + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: short packet (%"U16_F" bytes) discarded\n", p->tot_len)); + TCP_STATS_INC(tcp.lenerr); + goto dropped; + } + + /* Don't even process incoming broadcasts/multicasts. */ + if (ip_addr_isbroadcast(¤t_iphdr_dest, inp) || + ip_addr_ismulticast(¤t_iphdr_dest)) { + TCP_STATS_INC(tcp.proterr); + goto dropped; + } + +#if CHECKSUM_CHECK_TCP + /* Verify TCP checksum. */ + if (inet_chksum_pseudo(p, ip_current_src_addr(), ip_current_dest_addr(), + IP_PROTO_TCP, p->tot_len) != 0) { + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: packet discarded due to failing checksum 0x%04"X16_F"\n", + inet_chksum_pseudo(p, ip_current_src_addr(), ip_current_dest_addr(), + IP_PROTO_TCP, p->tot_len))); +#if TCP_DEBUG + tcp_debug_print(tcphdr); +#endif /* TCP_DEBUG */ + TCP_STATS_INC(tcp.chkerr); + goto dropped; + } +#endif + + /* Move the payload pointer in the pbuf so that it points to the + TCP data instead of the TCP header. */ + hdrlen = TCPH_HDRLEN(tcphdr); + if(pbuf_header(p, -(hdrlen * 4))){ + /* drop short packets */ + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: short packet\n")); + TCP_STATS_INC(tcp.lenerr); + goto dropped; + } + + /* Convert fields in TCP header to host byte order. */ + tcphdr->src = ntohs(tcphdr->src); + tcphdr->dest = ntohs(tcphdr->dest); + seqno = tcphdr->seqno = ntohl(tcphdr->seqno); + ackno = tcphdr->ackno = ntohl(tcphdr->ackno); + tcphdr->wnd = ntohs(tcphdr->wnd); + + flags = TCPH_FLAGS(tcphdr); + tcplen = p->tot_len + ((flags & (TCP_FIN | TCP_SYN)) ? 1 : 0); + + /* Demultiplex an incoming segment. First, we check if it is destined + for an active connection. */ + prev = NULL; + + + for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) { + LWIP_ASSERT("tcp_input: active pcb->state != CLOSED", pcb->state != CLOSED); + LWIP_ASSERT("tcp_input: active pcb->state != TIME-WAIT", pcb->state != TIME_WAIT); + LWIP_ASSERT("tcp_input: active pcb->state != LISTEN", pcb->state != LISTEN); + if (pcb->remote_port == tcphdr->src && + pcb->local_port == tcphdr->dest && + ip_addr_cmp(&(pcb->remote_ip), ¤t_iphdr_src) && + ip_addr_cmp(&(pcb->local_ip), ¤t_iphdr_dest)) { + + /* Move this PCB to the front of the list so that subsequent + lookups will be faster (we exploit locality in TCP segment + arrivals). */ + LWIP_ASSERT("tcp_input: pcb->next != pcb (before cache)", pcb->next != pcb); + if (prev != NULL) { + prev->next = pcb->next; + pcb->next = tcp_active_pcbs; + tcp_active_pcbs = pcb; + } + LWIP_ASSERT("tcp_input: pcb->next != pcb (after cache)", pcb->next != pcb); + break; + } + prev = pcb; + } + + if (pcb == NULL) { + /* If it did not go to an active connection, we check the connections + in the TIME-WAIT state. */ + for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) { + LWIP_ASSERT("tcp_input: TIME-WAIT pcb->state == TIME-WAIT", pcb->state == TIME_WAIT); + if (pcb->remote_port == tcphdr->src && + pcb->local_port == tcphdr->dest && + ip_addr_cmp(&(pcb->remote_ip), ¤t_iphdr_src) && + ip_addr_cmp(&(pcb->local_ip), ¤t_iphdr_dest)) { + /* We don't really care enough to move this PCB to the front + of the list since we are not very likely to receive that + many segments for connections in TIME-WAIT. */ + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: packed for TIME_WAITing connection.\n")); + tcp_timewait_input(pcb); + pbuf_free(p); + return; + } + } + + /* Finally, if we still did not get a match, we check all PCBs that + are LISTENing for incoming connections. */ + prev = NULL; + for(lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next) { + if (lpcb->local_port == tcphdr->dest) { +#if SO_REUSE + if (ip_addr_cmp(&(lpcb->local_ip), ¤t_iphdr_dest)) { + /* found an exact match */ + break; + } else if(ip_addr_isany(&(lpcb->local_ip))) { + /* found an ANY-match */ + lpcb_any = lpcb; + lpcb_prev = prev; + } +#else /* SO_REUSE */ + if (ip_addr_cmp(&(lpcb->local_ip), ¤t_iphdr_dest) || + ip_addr_isany(&(lpcb->local_ip))) { + /* found a match */ + break; + } +#endif /* SO_REUSE */ + } + prev = (struct tcp_pcb *)lpcb; + } +#if SO_REUSE + /* first try specific local IP */ + if (lpcb == NULL) { + /* only pass to ANY if no specific local IP has been found */ + lpcb = lpcb_any; + prev = lpcb_prev; + } +#endif /* SO_REUSE */ + if (lpcb != NULL) { + /* Move this PCB to the front of the list so that subsequent + lookups will be faster (we exploit locality in TCP segment + arrivals). */ + if (prev != NULL) { + ((struct tcp_pcb_listen *)prev)->next = lpcb->next; + /* our successor is the remainder of the listening list */ + lpcb->next = tcp_listen_pcbs.listen_pcbs; + /* put this listening pcb at the head of the listening list */ + tcp_listen_pcbs.listen_pcbs = lpcb; + } + + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: packed for LISTENing connection.\n")); + tcp_listen_input(lpcb); + pbuf_free(p); + return; + } + } + +#if TCP_INPUT_DEBUG + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("+-+-+-+-+-+-+-+-+-+-+-+-+-+- tcp_input: flags ")); + tcp_debug_print_flags(TCPH_FLAGS(tcphdr)); + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n")); +#endif /* TCP_INPUT_DEBUG */ + + + if (pcb != NULL) { + /* The incoming segment belongs to a connection. */ +#if TCP_INPUT_DEBUG +#if TCP_DEBUG + tcp_debug_print_state(pcb->state); +#endif /* TCP_DEBUG */ +#endif /* TCP_INPUT_DEBUG */ + + /* Set up a tcp_seg structure. */ + inseg.next = NULL; + inseg.len = p->tot_len; + inseg.p = p; + inseg.tcphdr = tcphdr; + + recv_data = NULL; + recv_flags = 0; + + if (flags & TCP_PSH) { + p->flags |= PBUF_FLAG_PUSH; + } + + /* If there is data which was previously "refused" by upper layer */ + if (pcb->refused_data != NULL) { + if ((tcp_process_refused_data(pcb) == ERR_ABRT) || + ((pcb->refused_data != NULL) && (tcplen > 0))) { + /* pcb has been aborted or refused data is still refused and the new + segment contains data */ + TCP_STATS_INC(tcp.drop); + snmp_inc_tcpinerrs(); + goto aborted; + } + } + tcp_input_pcb = pcb; + err = tcp_process(pcb); + /* A return value of ERR_ABRT means that tcp_abort() was called + and that the pcb has been freed. If so, we don't do anything. */ + if (err != ERR_ABRT) { + if (recv_flags & TF_RESET) { + /* TF_RESET means that the connection was reset by the other + end. We then call the error callback to inform the + application that the connection is dead before we + deallocate the PCB. */ + TCP_EVENT_ERR(pcb->errf, pcb->callback_arg, ERR_RST); + tcp_pcb_remove(&tcp_active_pcbs, pcb); + memp_free(MEMP_TCP_PCB, pcb); + } else if (recv_flags & TF_CLOSED) { + /* The connection has been closed and we will deallocate the + PCB. */ + if (!(pcb->flags & TF_RXCLOSED)) { + /* Connection closed although the application has only shut down the + tx side: call the PCB's err callback and indicate the closure to + ensure the application doesn't continue using the PCB. */ + TCP_EVENT_ERR(pcb->errf, pcb->callback_arg, ERR_CLSD); + } + tcp_pcb_remove(&tcp_active_pcbs, pcb); + memp_free(MEMP_TCP_PCB, pcb); + } else { + err = ERR_OK; + /* If the application has registered a "sent" function to be + called when new send buffer space is available, we call it + now. */ + if (pcb->acked > 0) { + TCP_EVENT_SENT(pcb, pcb->acked, err); + if (err == ERR_ABRT) { + goto aborted; + } + } + + if (recv_data != NULL) { + LWIP_ASSERT("pcb->refused_data == NULL", pcb->refused_data == NULL); + if (pcb->flags & TF_RXCLOSED) { + /* received data although already closed -> abort (send RST) to + notify the remote host that not all data has been processed */ + pbuf_free(recv_data); + tcp_abort(pcb); + goto aborted; + } + + /* Notify application that data has been received. */ + TCP_EVENT_RECV(pcb, recv_data, ERR_OK, err); + if (err == ERR_ABRT) { + goto aborted; + } + + /* If the upper layer can't receive this data, store it */ + if (err != ERR_OK) { + pcb->refused_data = recv_data; + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: keep incoming packet, because pcb is \"full\"\n")); + } + } + + /* If a FIN segment was received, we call the callback + function with a NULL buffer to indicate EOF. */ + if (recv_flags & TF_GOT_FIN) { + if (pcb->refused_data != NULL) { + /* Delay this if we have refused data. */ + pcb->refused_data->flags |= PBUF_FLAG_TCP_FIN; + } else { + /* correct rcv_wnd as the application won't call tcp_recved() + for the FIN's seqno */ + if (pcb->rcv_wnd != TCP_WND) { + pcb->rcv_wnd++; + } + TCP_EVENT_CLOSED(pcb, err); + if (err == ERR_ABRT) { + goto aborted; + } + } + } + + tcp_input_pcb = NULL; + /* Try to send something out. */ + tcp_output(pcb); +#if TCP_INPUT_DEBUG +#if TCP_DEBUG + tcp_debug_print_state(pcb->state); +#endif /* TCP_DEBUG */ +#endif /* TCP_INPUT_DEBUG */ + } + } + /* Jump target if pcb has been aborted in a callback (by calling tcp_abort()). + Below this line, 'pcb' may not be dereferenced! */ +aborted: + tcp_input_pcb = NULL; + recv_data = NULL; + + /* give up our reference to inseg.p */ + if (inseg.p != NULL) + { + pbuf_free(inseg.p); + inseg.p = NULL; + } + } else { + + /* If no matching PCB was found, send a TCP RST (reset) to the + sender. */ + LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_input: no PCB match found, resetting.\n")); + if (!(TCPH_FLAGS(tcphdr) & TCP_RST)) { + TCP_STATS_INC(tcp.proterr); + TCP_STATS_INC(tcp.drop); + tcp_rst(ackno, seqno + tcplen, + ip_current_dest_addr(), ip_current_src_addr(), + tcphdr->dest, tcphdr->src); + } + pbuf_free(p); + } + + LWIP_ASSERT("tcp_input: tcp_pcbs_sane()", tcp_pcbs_sane()); + PERF_STOP("tcp_input"); + return; +dropped: + TCP_STATS_INC(tcp.drop); + snmp_inc_tcpinerrs(); + pbuf_free(p); +} + +/** + * Called by tcp_input() when a segment arrives for a listening + * connection (from tcp_input()). + * + * @param pcb the tcp_pcb_listen for which a segment arrived + * @return ERR_OK if the segment was processed + * another err_t on error + * + * @note the return value is not (yet?) used in tcp_input() + * @note the segment which arrived is saved in global variables, therefore only the pcb + * involved is passed as a parameter to this function + */ +static err_t +tcp_listen_input(struct tcp_pcb_listen *pcb) +{ + struct tcp_pcb *npcb; + err_t rc; + + if (flags & TCP_RST) { + /* An incoming RST should be ignored. Return. */ + return ERR_OK; + } + + /* In the LISTEN state, we check for incoming SYN segments, + creates a new PCB, and responds with a SYN|ACK. */ + if (flags & TCP_ACK) { + /* For incoming segments with the ACK flag set, respond with a + RST. */ + LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_listen_input: ACK in LISTEN, sending reset\n")); + tcp_rst(ackno, seqno + tcplen, ip_current_dest_addr(), + ip_current_src_addr(), tcphdr->dest, tcphdr->src); + } else if (flags & TCP_SYN) { + LWIP_DEBUGF(TCP_DEBUG, ("TCP connection request %"U16_F" -> %"U16_F".\n", tcphdr->src, tcphdr->dest)); +#if TCP_LISTEN_BACKLOG + if (pcb->accepts_pending >= pcb->backlog) { + LWIP_DEBUGF(TCP_DEBUG, ("tcp_listen_input: listen backlog exceeded for port %"U16_F"\n", tcphdr->dest)); + return ERR_ABRT; + } +#endif /* TCP_LISTEN_BACKLOG */ + npcb = tcp_alloc(pcb->prio); + /* If a new PCB could not be created (probably due to lack of memory), + we don't do anything, but rely on the sender will retransmit the + SYN at a time when we have more memory available. */ + if (npcb == NULL) { + LWIP_DEBUGF(TCP_DEBUG, ("tcp_listen_input: could not allocate PCB\n")); + TCP_STATS_INC(tcp.memerr); + return ERR_MEM; + } +#if TCP_LISTEN_BACKLOG + pcb->accepts_pending++; +#endif /* TCP_LISTEN_BACKLOG */ + /* Set up the new PCB. */ + ip_addr_copy(npcb->local_ip, current_iphdr_dest); + npcb->local_port = pcb->local_port; + ip_addr_copy(npcb->remote_ip, current_iphdr_src); + npcb->remote_port = tcphdr->src; + npcb->state = SYN_RCVD; + npcb->rcv_nxt = seqno + 1; + npcb->rcv_ann_right_edge = npcb->rcv_nxt; + npcb->snd_wnd = tcphdr->wnd; + npcb->snd_wnd_max = tcphdr->wnd; + npcb->ssthresh = npcb->snd_wnd; + npcb->snd_wl1 = seqno - 1;/* initialise to seqno-1 to force window update */ + npcb->callback_arg = pcb->callback_arg; +#if LWIP_CALLBACK_API + npcb->accept = pcb->accept; +#endif /* LWIP_CALLBACK_API */ + /* inherit socket options */ + npcb->so_options = pcb->so_options & SOF_INHERITED; + /* Register the new PCB so that we can begin receiving segments + for it. */ + TCP_REG_ACTIVE(npcb); + + /* Parse any options in the SYN. */ + tcp_parseopt(npcb); +#if TCP_CALCULATE_EFF_SEND_MSS + npcb->mss = tcp_eff_send_mss(npcb->mss, &(npcb->remote_ip)); +#endif /* TCP_CALCULATE_EFF_SEND_MSS */ + + snmp_inc_tcppassiveopens(); + + /* Send a SYN|ACK together with the MSS option. */ + rc = tcp_enqueue_flags(npcb, TCP_SYN | TCP_ACK); + if (rc != ERR_OK) { + tcp_abandon(npcb, 0); + return rc; + } + return tcp_output(npcb); + } + return ERR_OK; +} + +/** + * Called by tcp_input() when a segment arrives for a connection in + * TIME_WAIT. + * + * @param pcb the tcp_pcb for which a segment arrived + * + * @note the segment which arrived is saved in global variables, therefore only the pcb + * involved is passed as a parameter to this function + */ +static err_t +tcp_timewait_input(struct tcp_pcb *pcb) +{ + /* RFC 1337: in TIME_WAIT, ignore RST and ACK FINs + any 'acceptable' segments */ + /* RFC 793 3.9 Event Processing - Segment Arrives: + * - first check sequence number - we skip that one in TIME_WAIT (always + * acceptable since we only send ACKs) + * - second check the RST bit (... return) */ + if (flags & TCP_RST) { + return ERR_OK; + } + /* - fourth, check the SYN bit, */ + if (flags & TCP_SYN) { + /* If an incoming segment is not acceptable, an acknowledgment + should be sent in reply */ + if (TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt, pcb->rcv_nxt+pcb->rcv_wnd)) { + /* If the SYN is in the window it is an error, send a reset */ + tcp_rst(ackno, seqno + tcplen, ip_current_dest_addr(), ip_current_src_addr(), + tcphdr->dest, tcphdr->src); + return ERR_OK; + } + } else if (flags & TCP_FIN) { + /* - eighth, check the FIN bit: Remain in the TIME-WAIT state. + Restart the 2 MSL time-wait timeout.*/ + pcb->tmr = tcp_ticks; + } + + if ((tcplen > 0)) { + /* Acknowledge data, FIN or out-of-window SYN */ + pcb->flags |= TF_ACK_NOW; + return tcp_output(pcb); + } + return ERR_OK; +} + +/** + * Implements the TCP state machine. Called by tcp_input. In some + * states tcp_receive() is called to receive data. The tcp_seg + * argument will be freed by the caller (tcp_input()) unless the + * recv_data pointer in the pcb is set. + * + * @param pcb the tcp_pcb for which a segment arrived + * + * @note the segment which arrived is saved in global variables, therefore only the pcb + * involved is passed as a parameter to this function + */ +static err_t +tcp_process(struct tcp_pcb *pcb) +{ + struct tcp_seg *rseg; + u8_t acceptable = 0; + err_t err; + + err = ERR_OK; + + /* Process incoming RST segments. */ + if (flags & TCP_RST) { + /* First, determine if the reset is acceptable. */ + if (pcb->state == SYN_SENT) { + if (ackno == pcb->snd_nxt) { + acceptable = 1; + } + } else { + if (TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt, + pcb->rcv_nxt+pcb->rcv_wnd)) { + acceptable = 1; + } + } + + if (acceptable) { + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_process: Connection RESET\n")); + LWIP_ASSERT("tcp_input: pcb->state != CLOSED", pcb->state != CLOSED); + recv_flags |= TF_RESET; + pcb->flags &= ~TF_ACK_DELAY; + return ERR_RST; + } else { + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_process: unacceptable reset seqno %"U32_F" rcv_nxt %"U32_F"\n", + seqno, pcb->rcv_nxt)); + LWIP_DEBUGF(TCP_DEBUG, ("tcp_process: unacceptable reset seqno %"U32_F" rcv_nxt %"U32_F"\n", + seqno, pcb->rcv_nxt)); + return ERR_OK; + } + } + + if ((flags & TCP_SYN) && (pcb->state != SYN_SENT && pcb->state != SYN_RCVD)) { + /* Cope with new connection attempt after remote end crashed */ + tcp_ack_now(pcb); + return ERR_OK; + } + + if ((pcb->flags & TF_RXCLOSED) == 0) { + /* Update the PCB (in)activity timer unless rx is closed (see tcp_shutdown) */ + pcb->tmr = tcp_ticks; + } + pcb->keep_cnt_sent = 0; + + tcp_parseopt(pcb); + + /* Do different things depending on the TCP state. */ + switch (pcb->state) { + case SYN_SENT: + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("SYN-SENT: ackno %"U32_F" pcb->snd_nxt %"U32_F" unacked %"U32_F"\n", ackno, + pcb->snd_nxt, ntohl(pcb->unacked->tcphdr->seqno))); + /* received SYN ACK with expected sequence number? */ + if ((flags & TCP_ACK) && (flags & TCP_SYN) + && ackno == ntohl(pcb->unacked->tcphdr->seqno) + 1) { + pcb->snd_buf++; + pcb->rcv_nxt = seqno + 1; + pcb->rcv_ann_right_edge = pcb->rcv_nxt; + pcb->lastack = ackno; + pcb->snd_wnd = tcphdr->wnd; + pcb->snd_wnd_max = tcphdr->wnd; + pcb->snd_wl1 = seqno - 1; /* initialise to seqno - 1 to force window update */ + pcb->state = ESTABLISHED; + +#if TCP_CALCULATE_EFF_SEND_MSS + pcb->mss = tcp_eff_send_mss(pcb->mss, &(pcb->remote_ip)); +#endif /* TCP_CALCULATE_EFF_SEND_MSS */ + + /* Set ssthresh again after changing pcb->mss (already set in tcp_connect + * but for the default value of pcb->mss) */ + pcb->ssthresh = pcb->mss * 10; + + pcb->cwnd = ((pcb->cwnd == 1) ? (pcb->mss * 2) : pcb->mss); + LWIP_ASSERT("pcb->snd_queuelen > 0", (pcb->snd_queuelen > 0)); + --pcb->snd_queuelen; + LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_process: SYN-SENT --queuelen %"U16_F"\n", (u16_t)pcb->snd_queuelen)); + rseg = pcb->unacked; + pcb->unacked = rseg->next; + tcp_seg_free(rseg); + + /* If there's nothing left to acknowledge, stop the retransmit + timer, otherwise reset it to start again */ + if(pcb->unacked == NULL) + pcb->rtime = -1; + else { + pcb->rtime = 0; + pcb->nrtx = 0; + } + + /* Call the user specified function to call when sucessfully + * connected. */ + TCP_EVENT_CONNECTED(pcb, ERR_OK, err); + if (err == ERR_ABRT) { + return ERR_ABRT; + } + tcp_ack_now(pcb); + } + /* received ACK? possibly a half-open connection */ + else if (flags & TCP_ACK) { + /* send a RST to bring the other side in a non-synchronized state. */ + tcp_rst(ackno, seqno + tcplen, ip_current_dest_addr(), ip_current_src_addr(), + tcphdr->dest, tcphdr->src); + } + break; + case SYN_RCVD: + if (flags & TCP_ACK) { + /* expected ACK number? */ + if (TCP_SEQ_BETWEEN(ackno, pcb->lastack+1, pcb->snd_nxt)) { + u16_t old_cwnd; + pcb->state = ESTABLISHED; + LWIP_DEBUGF(TCP_DEBUG, ("TCP connection established %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest)); +#if LWIP_CALLBACK_API + LWIP_ASSERT("pcb->accept != NULL", pcb->accept != NULL); +#endif + /* Call the accept function. */ + TCP_EVENT_ACCEPT(pcb, ERR_OK, err); + if (err != ERR_OK) { + /* If the accept function returns with an error, we abort + * the connection. */ + /* Already aborted? */ + if (err != ERR_ABRT) { + tcp_abort(pcb); + } + return ERR_ABRT; + } + old_cwnd = pcb->cwnd; + /* If there was any data contained within this ACK, + * we'd better pass it on to the application as well. */ + tcp_receive(pcb); + + /* Prevent ACK for SYN to generate a sent event */ + if (pcb->acked != 0) { + pcb->acked--; + } + + pcb->cwnd = ((old_cwnd == 1) ? (pcb->mss * 2) : pcb->mss); + + if (recv_flags & TF_GOT_FIN) { + tcp_ack_now(pcb); + pcb->state = CLOSE_WAIT; + } + } else { + /* incorrect ACK number, send RST */ + tcp_rst(ackno, seqno + tcplen, ip_current_dest_addr(), ip_current_src_addr(), + tcphdr->dest, tcphdr->src); + } + } else if ((flags & TCP_SYN) && (seqno == pcb->rcv_nxt - 1)) { + /* Looks like another copy of the SYN - retransmit our SYN-ACK */ + tcp_rexmit(pcb); + } + break; + case CLOSE_WAIT: + /* FALLTHROUGH */ + case ESTABLISHED: + tcp_receive(pcb); + if (recv_flags & TF_GOT_FIN) { /* passive close */ + tcp_ack_now(pcb); + pcb->state = CLOSE_WAIT; + } + break; + case FIN_WAIT_1: + tcp_receive(pcb); + if (recv_flags & TF_GOT_FIN) { + if ((flags & TCP_ACK) && (ackno == pcb->snd_nxt)) { + LWIP_DEBUGF(TCP_DEBUG, + ("TCP connection closed: FIN_WAIT_1 %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest)); + tcp_ack_now(pcb); + tcp_pcb_purge(pcb); + TCP_RMV_ACTIVE(pcb); + pcb->state = TIME_WAIT; + TCP_REG(&tcp_tw_pcbs, pcb); + } else { + tcp_ack_now(pcb); + pcb->state = CLOSING; + } + } else if ((flags & TCP_ACK) && (ackno == pcb->snd_nxt)) { + pcb->state = FIN_WAIT_2; + } + break; + case FIN_WAIT_2: + tcp_receive(pcb); + if (recv_flags & TF_GOT_FIN) { + LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed: FIN_WAIT_2 %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest)); + tcp_ack_now(pcb); + tcp_pcb_purge(pcb); + TCP_RMV_ACTIVE(pcb); + pcb->state = TIME_WAIT; + TCP_REG(&tcp_tw_pcbs, pcb); + } + break; + case CLOSING: + tcp_receive(pcb); + if (flags & TCP_ACK && ackno == pcb->snd_nxt) { + LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed: CLOSING %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest)); + tcp_pcb_purge(pcb); + TCP_RMV_ACTIVE(pcb); + pcb->state = TIME_WAIT; + TCP_REG(&tcp_tw_pcbs, pcb); + } + break; + case LAST_ACK: + tcp_receive(pcb); + if (flags & TCP_ACK && ackno == pcb->snd_nxt) { + LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed: LAST_ACK %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest)); + /* bugfix #21699: don't set pcb->state to CLOSED here or we risk leaking segments */ + recv_flags |= TF_CLOSED; + } + break; + default: + break; + } + return ERR_OK; +} + +#if TCP_QUEUE_OOSEQ +/** + * Insert segment into the list (segments covered with new one will be deleted) + * + * Called from tcp_receive() + */ +static void +tcp_oos_insert_segment(struct tcp_seg *cseg, struct tcp_seg *next) +{ + struct tcp_seg *old_seg; + + if (TCPH_FLAGS(cseg->tcphdr) & TCP_FIN) { + /* received segment overlaps all following segments */ + tcp_segs_free(next); + next = NULL; + } + else { + /* delete some following segments + oos queue may have segments with FIN flag */ + while (next && + TCP_SEQ_GEQ((seqno + cseg->len), + (next->tcphdr->seqno + next->len))) { + /* cseg with FIN already processed */ + if (TCPH_FLAGS(next->tcphdr) & TCP_FIN) { + TCPH_SET_FLAG(cseg->tcphdr, TCP_FIN); + } + old_seg = next; + next = next->next; + tcp_seg_free(old_seg); + } + if (next && + TCP_SEQ_GT(seqno + cseg->len, next->tcphdr->seqno)) { + /* We need to trim the incoming segment. */ + cseg->len = (u16_t)(next->tcphdr->seqno - seqno); + pbuf_realloc(cseg->p, cseg->len); + } + } + cseg->next = next; +} +#endif /* TCP_QUEUE_OOSEQ */ + +/** + * Called by tcp_process. Checks if the given segment is an ACK for outstanding + * data, and if so frees the memory of the buffered data. Next, is places the + * segment on any of the receive queues (pcb->recved or pcb->ooseq). If the segment + * is buffered, the pbuf is referenced by pbuf_ref so that it will not be freed until + * it has been removed from the buffer. + * + * If the incoming segment constitutes an ACK for a segment that was used for RTT + * estimation, the RTT is estimated here as well. + * + * Called from tcp_process(). + */ +static void +tcp_receive(struct tcp_pcb *pcb) +{ + struct tcp_seg *next; +#if TCP_QUEUE_OOSEQ + struct tcp_seg *prev, *cseg; +#endif /* TCP_QUEUE_OOSEQ */ + struct pbuf *p; + s32_t off; + s16_t m; + u32_t right_wnd_edge; + u16_t new_tot_len; + int found_dupack = 0; +#if TCP_OOSEQ_MAX_BYTES || TCP_OOSEQ_MAX_PBUFS + u32_t ooseq_blen; + u16_t ooseq_qlen; +#endif /* TCP_OOSEQ_MAX_BYTES || TCP_OOSEQ_MAX_PBUFS */ + + LWIP_ASSERT("tcp_receive: wrong state", pcb->state >= ESTABLISHED); + + if (flags & TCP_ACK) { + right_wnd_edge = pcb->snd_wnd + pcb->snd_wl2; + + /* Update window. */ + if (TCP_SEQ_LT(pcb->snd_wl1, seqno) || + (pcb->snd_wl1 == seqno && TCP_SEQ_LT(pcb->snd_wl2, ackno)) || + (pcb->snd_wl2 == ackno && tcphdr->wnd > pcb->snd_wnd)) { + pcb->snd_wnd = tcphdr->wnd; + /* keep track of the biggest window announced by the remote host to calculate + the maximum segment size */ + if (pcb->snd_wnd_max < tcphdr->wnd) { + pcb->snd_wnd_max = tcphdr->wnd; + } + pcb->snd_wl1 = seqno; + pcb->snd_wl2 = ackno; + if (pcb->snd_wnd == 0) { + if (pcb->persist_backoff == 0) { + /* start persist timer */ + pcb->persist_cnt = 0; + pcb->persist_backoff = 1; + } + } else if (pcb->persist_backoff > 0) { + /* stop persist timer */ + pcb->persist_backoff = 0; + } + LWIP_DEBUGF(TCP_WND_DEBUG, ("tcp_receive: window update %"U16_F"\n", pcb->snd_wnd)); +#if TCP_WND_DEBUG + } else { + if (pcb->snd_wnd != tcphdr->wnd) { + LWIP_DEBUGF(TCP_WND_DEBUG, + ("tcp_receive: no window update lastack %"U32_F" ackno %" + U32_F" wl1 %"U32_F" seqno %"U32_F" wl2 %"U32_F"\n", + pcb->lastack, ackno, pcb->snd_wl1, seqno, pcb->snd_wl2)); + } +#endif /* TCP_WND_DEBUG */ + } + + /* (From Stevens TCP/IP Illustrated Vol II, p970.) Its only a + * duplicate ack if: + * 1) It doesn't ACK new data + * 2) length of received packet is zero (i.e. no payload) + * 3) the advertised window hasn't changed + * 4) There is outstanding unacknowledged data (retransmission timer running) + * 5) The ACK is == biggest ACK sequence number so far seen (snd_una) + * + * If it passes all five, should process as a dupack: + * a) dupacks < 3: do nothing + * b) dupacks == 3: fast retransmit + * c) dupacks > 3: increase cwnd + * + * If it only passes 1-3, should reset dupack counter (and add to + * stats, which we don't do in lwIP) + * + * If it only passes 1, should reset dupack counter + * + */ + + /* Clause 1 */ + if (TCP_SEQ_LEQ(ackno, pcb->lastack)) { + pcb->acked = 0; + /* Clause 2 */ + if (tcplen == 0) { + /* Clause 3 */ + if (pcb->snd_wl2 + pcb->snd_wnd == right_wnd_edge){ + /* Clause 4 */ + if (pcb->rtime >= 0) { + /* Clause 5 */ + if (pcb->lastack == ackno) { + found_dupack = 1; + if ((u8_t)(pcb->dupacks + 1) > pcb->dupacks) { + ++pcb->dupacks; + } + if (pcb->dupacks > 3) { + /* Inflate the congestion window, but not if it means that + the value overflows. */ + if ((u16_t)(pcb->cwnd + pcb->mss) > pcb->cwnd) { + pcb->cwnd += pcb->mss; + } + } else if (pcb->dupacks == 3) { + /* Do fast retransmit */ + tcp_rexmit_fast(pcb); + } + } + } + } + } + /* If Clause (1) or more is true, but not a duplicate ack, reset + * count of consecutive duplicate acks */ + if (!found_dupack) { + pcb->dupacks = 0; + } + } else if (TCP_SEQ_BETWEEN(ackno, pcb->lastack+1, pcb->snd_nxt)){ + /* We come here when the ACK acknowledges new data. */ + + /* Reset the "IN Fast Retransmit" flag, since we are no longer + in fast retransmit. Also reset the congestion window to the + slow start threshold. */ + if (pcb->flags & TF_INFR) { + pcb->flags &= ~TF_INFR; + pcb->cwnd = pcb->ssthresh; + } + + /* Reset the number of retransmissions. */ + pcb->nrtx = 0; + + /* Reset the retransmission time-out. */ + pcb->rto = (pcb->sa >> 3) + pcb->sv; + + /* Update the send buffer space. Diff between the two can never exceed 64K? */ + pcb->acked = (u16_t)(ackno - pcb->lastack); + + pcb->snd_buf += pcb->acked; + + /* Reset the fast retransmit variables. */ + pcb->dupacks = 0; + pcb->lastack = ackno; + + /* Update the congestion control variables (cwnd and + ssthresh). */ + if (pcb->state >= ESTABLISHED) { + if (pcb->cwnd < pcb->ssthresh) { + if ((u16_t)(pcb->cwnd + pcb->mss) > pcb->cwnd) { + pcb->cwnd += pcb->mss; + } + LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_receive: slow start cwnd %"U16_F"\n", pcb->cwnd)); + } else { + u16_t new_cwnd = (pcb->cwnd + pcb->mss * pcb->mss / pcb->cwnd); + if (new_cwnd > pcb->cwnd) { + pcb->cwnd = new_cwnd; + } + LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_receive: congestion avoidance cwnd %"U16_F"\n", pcb->cwnd)); + } + } + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: ACK for %"U32_F", unacked->seqno %"U32_F":%"U32_F"\n", + ackno, + pcb->unacked != NULL? + ntohl(pcb->unacked->tcphdr->seqno): 0, + pcb->unacked != NULL? + ntohl(pcb->unacked->tcphdr->seqno) + TCP_TCPLEN(pcb->unacked): 0)); + + /* Remove segment from the unacknowledged list if the incoming + ACK acknowlegdes them. */ + while (pcb->unacked != NULL && + TCP_SEQ_LEQ(ntohl(pcb->unacked->tcphdr->seqno) + + TCP_TCPLEN(pcb->unacked), ackno)) { + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: removing %"U32_F":%"U32_F" from pcb->unacked\n", + ntohl(pcb->unacked->tcphdr->seqno), + ntohl(pcb->unacked->tcphdr->seqno) + + TCP_TCPLEN(pcb->unacked))); + + next = pcb->unacked; + pcb->unacked = pcb->unacked->next; + + LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_receive: queuelen %"U16_F" ... ", (u16_t)pcb->snd_queuelen)); + LWIP_ASSERT("pcb->snd_queuelen >= pbuf_clen(next->p)", (pcb->snd_queuelen >= pbuf_clen(next->p))); + /* Prevent ACK for FIN to generate a sent event */ + if ((pcb->acked != 0) && ((TCPH_FLAGS(next->tcphdr) & TCP_FIN) != 0)) { + pcb->acked--; + } + + pcb->snd_queuelen -= pbuf_clen(next->p); + tcp_seg_free(next); + + LWIP_DEBUGF(TCP_QLEN_DEBUG, ("%"U16_F" (after freeing unacked)\n", (u16_t)pcb->snd_queuelen)); + if (pcb->snd_queuelen != 0) { + LWIP_ASSERT("tcp_receive: valid queue length", pcb->unacked != NULL || + pcb->unsent != NULL); + } + } + + /* If there's nothing left to acknowledge, stop the retransmit + timer, otherwise reset it to start again */ + if(pcb->unacked == NULL) + pcb->rtime = -1; + else + pcb->rtime = 0; + + pcb->polltmr = 0; + } else { + /* Fix bug bug #21582: out of sequence ACK, didn't really ack anything */ + pcb->acked = 0; + } + + /* We go through the ->unsent list to see if any of the segments + on the list are acknowledged by the ACK. This may seem + strange since an "unsent" segment shouldn't be acked. The + rationale is that lwIP puts all outstanding segments on the + ->unsent list after a retransmission, so these segments may + in fact have been sent once. */ + while (pcb->unsent != NULL && + TCP_SEQ_BETWEEN(ackno, ntohl(pcb->unsent->tcphdr->seqno) + + TCP_TCPLEN(pcb->unsent), pcb->snd_nxt)) { + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: removing %"U32_F":%"U32_F" from pcb->unsent\n", + ntohl(pcb->unsent->tcphdr->seqno), ntohl(pcb->unsent->tcphdr->seqno) + + TCP_TCPLEN(pcb->unsent))); + + next = pcb->unsent; + pcb->unsent = pcb->unsent->next; +#if TCP_OVERSIZE + if (pcb->unsent == NULL) { + pcb->unsent_oversize = 0; + } +#endif /* TCP_OVERSIZE */ + LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_receive: queuelen %"U16_F" ... ", (u16_t)pcb->snd_queuelen)); + LWIP_ASSERT("pcb->snd_queuelen >= pbuf_clen(next->p)", (pcb->snd_queuelen >= pbuf_clen(next->p))); + /* Prevent ACK for FIN to generate a sent event */ + if ((pcb->acked != 0) && ((TCPH_FLAGS(next->tcphdr) & TCP_FIN) != 0)) { + pcb->acked--; + } + pcb->snd_queuelen -= pbuf_clen(next->p); + tcp_seg_free(next); + LWIP_DEBUGF(TCP_QLEN_DEBUG, ("%"U16_F" (after freeing unsent)\n", (u16_t)pcb->snd_queuelen)); + if (pcb->snd_queuelen != 0) { + LWIP_ASSERT("tcp_receive: valid queue length", + pcb->unacked != NULL || pcb->unsent != NULL); + } + } + /* End of ACK for new data processing. */ + + LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: pcb->rttest %"U32_F" rtseq %"U32_F" ackno %"U32_F"\n", + pcb->rttest, pcb->rtseq, ackno)); + + /* RTT estimation calculations. This is done by checking if the + incoming segment acknowledges the segment we use to take a + round-trip time measurement. */ + if (pcb->rttest && TCP_SEQ_LT(pcb->rtseq, ackno)) { + /* diff between this shouldn't exceed 32K since this are tcp timer ticks + and a round-trip shouldn't be that long... */ + m = (s16_t)(tcp_ticks - pcb->rttest); + + LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: experienced rtt %"U16_F" ticks (%"U16_F" msec).\n", + m, m * TCP_SLOW_INTERVAL)); + + /* This is taken directly from VJs original code in his paper */ + m = m - (pcb->sa >> 3); + pcb->sa += m; + if (m < 0) { + m = -m; + } + m = m - (pcb->sv >> 2); + pcb->sv += m; + pcb->rto = (pcb->sa >> 3) + pcb->sv; + + LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: RTO %"U16_F" (%"U16_F" milliseconds)\n", + pcb->rto, pcb->rto * TCP_SLOW_INTERVAL)); + + pcb->rttest = 0; + } + } + + /* If the incoming segment contains data, we must process it + further unless the pcb already received a FIN. + (RFC 793, chapeter 3.9, "SEGMENT ARRIVES" in states CLOSE-WAIT, CLOSING, + LAST-ACK and TIME-WAIT: "Ignore the segment text.") */ + if ((tcplen > 0) && (pcb->state < CLOSE_WAIT)) { + /* This code basically does three things: + + +) If the incoming segment contains data that is the next + in-sequence data, this data is passed to the application. This + might involve trimming the first edge of the data. The rcv_nxt + variable and the advertised window are adjusted. + + +) If the incoming segment has data that is above the next + sequence number expected (->rcv_nxt), the segment is placed on + the ->ooseq queue. This is done by finding the appropriate + place in the ->ooseq queue (which is ordered by sequence + number) and trim the segment in both ends if needed. An + immediate ACK is sent to indicate that we received an + out-of-sequence segment. + + +) Finally, we check if the first segment on the ->ooseq queue + now is in sequence (i.e., if rcv_nxt >= ooseq->seqno). If + rcv_nxt > ooseq->seqno, we must trim the first edge of the + segment on ->ooseq before we adjust rcv_nxt. The data in the + segments that are now on sequence are chained onto the + incoming segment so that we only need to call the application + once. + */ + + /* First, we check if we must trim the first edge. We have to do + this if the sequence number of the incoming segment is less + than rcv_nxt, and the sequence number plus the length of the + segment is larger than rcv_nxt. */ + /* if (TCP_SEQ_LT(seqno, pcb->rcv_nxt)){ + if (TCP_SEQ_LT(pcb->rcv_nxt, seqno + tcplen)) {*/ + if (TCP_SEQ_BETWEEN(pcb->rcv_nxt, seqno + 1, seqno + tcplen - 1)){ + /* Trimming the first edge is done by pushing the payload + pointer in the pbuf downwards. This is somewhat tricky since + we do not want to discard the full contents of the pbuf up to + the new starting point of the data since we have to keep the + TCP header which is present in the first pbuf in the chain. + + What is done is really quite a nasty hack: the first pbuf in + the pbuf chain is pointed to by inseg.p. Since we need to be + able to deallocate the whole pbuf, we cannot change this + inseg.p pointer to point to any of the later pbufs in the + chain. Instead, we point the ->payload pointer in the first + pbuf to data in one of the later pbufs. We also set the + inseg.data pointer to point to the right place. This way, the + ->p pointer will still point to the first pbuf, but the + ->p->payload pointer will point to data in another pbuf. + + After we are done with adjusting the pbuf pointers we must + adjust the ->data pointer in the seg and the segment + length.*/ + + off = pcb->rcv_nxt - seqno; + p = inseg.p; + LWIP_ASSERT("inseg.p != NULL", inseg.p); + LWIP_ASSERT("insane offset!", (off < 0x7fff)); + if (inseg.p->len < off) { + LWIP_ASSERT("pbuf too short!", (((s32_t)inseg.p->tot_len) >= off)); + new_tot_len = (u16_t)(inseg.p->tot_len - off); + while (p->len < off) { + off -= p->len; + /* KJM following line changed (with addition of new_tot_len var) + to fix bug #9076 + inseg.p->tot_len -= p->len; */ + p->tot_len = new_tot_len; + p->len = 0; + p = p->next; + } + if(pbuf_header(p, (s16_t)-off)) { + /* Do we need to cope with this failing? Assert for now */ + LWIP_ASSERT("pbuf_header failed", 0); + } + } else { + if(pbuf_header(inseg.p, (s16_t)-off)) { + /* Do we need to cope with this failing? Assert for now */ + LWIP_ASSERT("pbuf_header failed", 0); + } + } + inseg.len -= (u16_t)(pcb->rcv_nxt - seqno); + inseg.tcphdr->seqno = seqno = pcb->rcv_nxt; + } + else { + if (TCP_SEQ_LT(seqno, pcb->rcv_nxt)){ + /* the whole segment is < rcv_nxt */ + /* must be a duplicate of a packet that has already been correctly handled */ + + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: duplicate seqno %"U32_F"\n", seqno)); + tcp_ack_now(pcb); + } + } + + /* The sequence number must be within the window (above rcv_nxt + and below rcv_nxt + rcv_wnd) in order to be further + processed. */ + if (TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt, + pcb->rcv_nxt + pcb->rcv_wnd - 1)){ + if (pcb->rcv_nxt == seqno) { + /* The incoming segment is the next in sequence. We check if + we have to trim the end of the segment and update rcv_nxt + and pass the data to the application. */ + tcplen = TCP_TCPLEN(&inseg); + + if (tcplen > pcb->rcv_wnd) { + LWIP_DEBUGF(TCP_INPUT_DEBUG, + ("tcp_receive: other end overran receive window" + "seqno %"U32_F" len %"U16_F" right edge %"U32_F"\n", + seqno, tcplen, pcb->rcv_nxt + pcb->rcv_wnd)); + if (TCPH_FLAGS(inseg.tcphdr) & TCP_FIN) { + /* Must remove the FIN from the header as we're trimming + * that byte of sequence-space from the packet */ + TCPH_FLAGS_SET(inseg.tcphdr, TCPH_FLAGS(inseg.tcphdr) &~ TCP_FIN); + } + /* Adjust length of segment to fit in the window. */ + inseg.len = pcb->rcv_wnd; + if (TCPH_FLAGS(inseg.tcphdr) & TCP_SYN) { + inseg.len -= 1; + } + pbuf_realloc(inseg.p, inseg.len); + tcplen = TCP_TCPLEN(&inseg); + LWIP_ASSERT("tcp_receive: segment not trimmed correctly to rcv_wnd\n", + (seqno + tcplen) == (pcb->rcv_nxt + pcb->rcv_wnd)); + } +#if TCP_QUEUE_OOSEQ + /* Received in-sequence data, adjust ooseq data if: + - FIN has been received or + - inseq overlaps with ooseq */ + if (pcb->ooseq != NULL) { + if (TCPH_FLAGS(inseg.tcphdr) & TCP_FIN) { + LWIP_DEBUGF(TCP_INPUT_DEBUG, + ("tcp_receive: received in-order FIN, binning ooseq queue\n")); + /* Received in-order FIN means anything that was received + * out of order must now have been received in-order, so + * bin the ooseq queue */ + while (pcb->ooseq != NULL) { + struct tcp_seg *old_ooseq = pcb->ooseq; + pcb->ooseq = pcb->ooseq->next; + tcp_seg_free(old_ooseq); + } + } else { + next = pcb->ooseq; + /* Remove all segments on ooseq that are covered by inseg already. + * FIN is copied from ooseq to inseg if present. */ + while (next && + TCP_SEQ_GEQ(seqno + tcplen, + next->tcphdr->seqno + next->len)) { + /* inseg cannot have FIN here (already processed above) */ + if (TCPH_FLAGS(next->tcphdr) & TCP_FIN && + (TCPH_FLAGS(inseg.tcphdr) & TCP_SYN) == 0) { + TCPH_SET_FLAG(inseg.tcphdr, TCP_FIN); + tcplen = TCP_TCPLEN(&inseg); + } + prev = next; + next = next->next; + tcp_seg_free(prev); + } + /* Now trim right side of inseg if it overlaps with the first + * segment on ooseq */ + if (next && + TCP_SEQ_GT(seqno + tcplen, + next->tcphdr->seqno)) { + /* inseg cannot have FIN here (already processed above) */ + inseg.len = (u16_t)(next->tcphdr->seqno - seqno); + if (TCPH_FLAGS(inseg.tcphdr) & TCP_SYN) { + inseg.len -= 1; + } + pbuf_realloc(inseg.p, inseg.len); + tcplen = TCP_TCPLEN(&inseg); + LWIP_ASSERT("tcp_receive: segment not trimmed correctly to ooseq queue\n", + (seqno + tcplen) == next->tcphdr->seqno); + } + pcb->ooseq = next; + } + } +#endif /* TCP_QUEUE_OOSEQ */ + + pcb->rcv_nxt = seqno + tcplen; + + /* Update the receiver's (our) window. */ + LWIP_ASSERT("tcp_receive: tcplen > rcv_wnd\n", pcb->rcv_wnd >= tcplen); + pcb->rcv_wnd -= tcplen; + + tcp_update_rcv_ann_wnd(pcb); + + /* If there is data in the segment, we make preparations to + pass this up to the application. The ->recv_data variable + is used for holding the pbuf that goes to the + application. The code for reassembling out-of-sequence data + chains its data on this pbuf as well. + + If the segment was a FIN, we set the TF_GOT_FIN flag that will + be used to indicate to the application that the remote side has + closed its end of the connection. */ + if (inseg.p->tot_len > 0) { + recv_data = inseg.p; + /* Since this pbuf now is the responsibility of the + application, we delete our reference to it so that we won't + (mistakingly) deallocate it. */ + inseg.p = NULL; + } + if (TCPH_FLAGS(inseg.tcphdr) & TCP_FIN) { + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: received FIN.\n")); + recv_flags |= TF_GOT_FIN; + } + +#if TCP_QUEUE_OOSEQ + /* We now check if we have segments on the ->ooseq queue that + are now in sequence. */ + while (pcb->ooseq != NULL && + pcb->ooseq->tcphdr->seqno == pcb->rcv_nxt) { + + cseg = pcb->ooseq; + seqno = pcb->ooseq->tcphdr->seqno; + + pcb->rcv_nxt += TCP_TCPLEN(cseg); + LWIP_ASSERT("tcp_receive: ooseq tcplen > rcv_wnd\n", + pcb->rcv_wnd >= TCP_TCPLEN(cseg)); + pcb->rcv_wnd -= TCP_TCPLEN(cseg); + + tcp_update_rcv_ann_wnd(pcb); + + if (cseg->p->tot_len > 0) { + /* Chain this pbuf onto the pbuf that we will pass to + the application. */ + if (recv_data) { + pbuf_cat(recv_data, cseg->p); + } else { + recv_data = cseg->p; + } + cseg->p = NULL; + } + if (TCPH_FLAGS(cseg->tcphdr) & TCP_FIN) { + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: dequeued FIN.\n")); + recv_flags |= TF_GOT_FIN; + if (pcb->state == ESTABLISHED) { /* force passive close or we can move to active close */ + pcb->state = CLOSE_WAIT; + } + } + + pcb->ooseq = cseg->next; + tcp_seg_free(cseg); + } +#endif /* TCP_QUEUE_OOSEQ */ + + + /* Acknowledge the segment(s). */ + tcp_ack(pcb); + + } else { + /* We get here if the incoming segment is out-of-sequence. */ + tcp_send_empty_ack(pcb); +#if TCP_QUEUE_OOSEQ + /* We queue the segment on the ->ooseq queue. */ + if (pcb->ooseq == NULL) { + pcb->ooseq = tcp_seg_copy(&inseg); + } else { + /* If the queue is not empty, we walk through the queue and + try to find a place where the sequence number of the + incoming segment is between the sequence numbers of the + previous and the next segment on the ->ooseq queue. That is + the place where we put the incoming segment. If needed, we + trim the second edges of the previous and the incoming + segment so that it will fit into the sequence. + + If the incoming segment has the same sequence number as a + segment on the ->ooseq queue, we discard the segment that + contains less data. */ + + prev = NULL; + for(next = pcb->ooseq; next != NULL; next = next->next) { + if (seqno == next->tcphdr->seqno) { + /* The sequence number of the incoming segment is the + same as the sequence number of the segment on + ->ooseq. We check the lengths to see which one to + discard. */ + if (inseg.len > next->len) { + /* The incoming segment is larger than the old + segment. We replace some segments with the new + one. */ + cseg = tcp_seg_copy(&inseg); + if (cseg != NULL) { + if (prev != NULL) { + prev->next = cseg; + } else { + pcb->ooseq = cseg; + } + tcp_oos_insert_segment(cseg, next); + } + break; + } else { + /* Either the lenghts are the same or the incoming + segment was smaller than the old one; in either + case, we ditch the incoming segment. */ + break; + } + } else { + if (prev == NULL) { + if (TCP_SEQ_LT(seqno, next->tcphdr->seqno)) { + /* The sequence number of the incoming segment is lower + than the sequence number of the first segment on the + queue. We put the incoming segment first on the + queue. */ + cseg = tcp_seg_copy(&inseg); + if (cseg != NULL) { + pcb->ooseq = cseg; + tcp_oos_insert_segment(cseg, next); + } + break; + } + } else { + /*if (TCP_SEQ_LT(prev->tcphdr->seqno, seqno) && + TCP_SEQ_LT(seqno, next->tcphdr->seqno)) {*/ + if (TCP_SEQ_BETWEEN(seqno, prev->tcphdr->seqno+1, next->tcphdr->seqno-1)) { + /* The sequence number of the incoming segment is in + between the sequence numbers of the previous and + the next segment on ->ooseq. We trim trim the previous + segment, delete next segments that included in received segment + and trim received, if needed. */ + cseg = tcp_seg_copy(&inseg); + if (cseg != NULL) { + if (TCP_SEQ_GT(prev->tcphdr->seqno + prev->len, seqno)) { + /* We need to trim the prev segment. */ + prev->len = (u16_t)(seqno - prev->tcphdr->seqno); + pbuf_realloc(prev->p, prev->len); + } + prev->next = cseg; + tcp_oos_insert_segment(cseg, next); + } + break; + } + } + /* If the "next" segment is the last segment on the + ooseq queue, we add the incoming segment to the end + of the list. */ + if (next->next == NULL && + TCP_SEQ_GT(seqno, next->tcphdr->seqno)) { + if (TCPH_FLAGS(next->tcphdr) & TCP_FIN) { + /* segment "next" already contains all data */ + break; + } + next->next = tcp_seg_copy(&inseg); + if (next->next != NULL) { + if (TCP_SEQ_GT(next->tcphdr->seqno + next->len, seqno)) { + /* We need to trim the last segment. */ + next->len = (u16_t)(seqno - next->tcphdr->seqno); + pbuf_realloc(next->p, next->len); + } + /* check if the remote side overruns our receive window */ + if ((u32_t)tcplen + seqno > pcb->rcv_nxt + (u32_t)pcb->rcv_wnd) { + LWIP_DEBUGF(TCP_INPUT_DEBUG, + ("tcp_receive: other end overran receive window" + "seqno %"U32_F" len %"U16_F" right edge %"U32_F"\n", + seqno, tcplen, pcb->rcv_nxt + pcb->rcv_wnd)); + if (TCPH_FLAGS(next->next->tcphdr) & TCP_FIN) { + /* Must remove the FIN from the header as we're trimming + * that byte of sequence-space from the packet */ + TCPH_FLAGS_SET(next->next->tcphdr, TCPH_FLAGS(next->next->tcphdr) &~ TCP_FIN); + } + /* Adjust length of segment to fit in the window. */ + next->next->len = pcb->rcv_nxt + pcb->rcv_wnd - seqno; + pbuf_realloc(next->next->p, next->next->len); + tcplen = TCP_TCPLEN(next->next); + LWIP_ASSERT("tcp_receive: segment not trimmed correctly to rcv_wnd\n", + (seqno + tcplen) == (pcb->rcv_nxt + pcb->rcv_wnd)); + } + } + break; + } + } + prev = next; + } + } +#if TCP_OOSEQ_MAX_BYTES || TCP_OOSEQ_MAX_PBUFS + /* Check that the data on ooseq doesn't exceed one of the limits + and throw away everything above that limit. */ + ooseq_blen = 0; + ooseq_qlen = 0; + prev = NULL; + for(next = pcb->ooseq; next != NULL; prev = next, next = next->next) { + struct pbuf *p = next->p; + ooseq_blen += p->tot_len; + ooseq_qlen += pbuf_clen(p); + if ((ooseq_blen > TCP_OOSEQ_MAX_BYTES) || + (ooseq_qlen > TCP_OOSEQ_MAX_PBUFS)) { + /* too much ooseq data, dump this and everything after it */ + tcp_segs_free(next); + if (prev == NULL) { + /* first ooseq segment is too much, dump the whole queue */ + pcb->ooseq = NULL; + } else { + /* just dump 'next' and everything after it */ + prev->next = NULL; + } + break; + } + } +#endif /* TCP_OOSEQ_MAX_BYTES || TCP_OOSEQ_MAX_PBUFS */ +#endif /* TCP_QUEUE_OOSEQ */ + } + } else { + /* The incoming segment is not withing the window. */ + tcp_send_empty_ack(pcb); + } + } else { + /* Segments with length 0 is taken care of here. Segments that + fall out of the window are ACKed. */ + /*if (TCP_SEQ_GT(pcb->rcv_nxt, seqno) || + TCP_SEQ_GEQ(seqno, pcb->rcv_nxt + pcb->rcv_wnd)) {*/ + if(!TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt, pcb->rcv_nxt + pcb->rcv_wnd-1)){ + tcp_ack_now(pcb); + } + } +} + +/** + * Parses the options contained in the incoming segment. + * + * Called from tcp_listen_input() and tcp_process(). + * Currently, only the MSS option is supported! + * + * @param pcb the tcp_pcb for which a segment arrived + */ +static void +tcp_parseopt(struct tcp_pcb *pcb) +{ + u16_t c, max_c; + u16_t mss; + u8_t *opts, opt; +#if LWIP_TCP_TIMESTAMPS + u32_t tsval; +#endif + + opts = (u8_t *)tcphdr + TCP_HLEN; + + /* Parse the TCP MSS option, if present. */ + if(TCPH_HDRLEN(tcphdr) > 0x5) { + max_c = (TCPH_HDRLEN(tcphdr) - 5) << 2; + for (c = 0; c < max_c; ) { + opt = opts[c]; + switch (opt) { + case 0x00: + /* End of options. */ + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: EOL\n")); + return; + case 0x01: + /* NOP option. */ + ++c; + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: NOP\n")); + break; + case 0x02: + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: MSS\n")); + if (opts[c + 1] != 0x04 || c + 0x04 > max_c) { + /* Bad length */ + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: bad length\n")); + return; + } + /* An MSS option with the right option length. */ + mss = (opts[c + 2] << 8) | opts[c + 3]; + /* Limit the mss to the configured TCP_MSS and prevent division by zero */ + pcb->mss = ((mss > TCP_MSS) || (mss == 0)) ? TCP_MSS : mss; + /* Advance to next option */ + c += 0x04; + break; +#if LWIP_TCP_TIMESTAMPS + case 0x08: + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: TS\n")); + if (opts[c + 1] != 0x0A || c + 0x0A > max_c) { + /* Bad length */ + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: bad length\n")); + return; + } + /* TCP timestamp option with valid length */ + tsval = (opts[c+2]) | (opts[c+3] << 8) | + (opts[c+4] << 16) | (opts[c+5] << 24); + if (flags & TCP_SYN) { + pcb->ts_recent = ntohl(tsval); + pcb->flags |= TF_TIMESTAMP; + } else if (TCP_SEQ_BETWEEN(pcb->ts_lastacksent, seqno, seqno+tcplen)) { + pcb->ts_recent = ntohl(tsval); + } + /* Advance to next option */ + c += 0x0A; + break; +#endif + default: + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: other\n")); + if (opts[c + 1] == 0) { + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: bad length\n")); + /* If the length field is zero, the options are malformed + and we don't process them further. */ + return; + } + /* All other options have a length field, so that we easily + can skip past them. */ + c += opts[c + 1]; + } + } + } +} + +#endif /* LWIP_TCP */ diff --git a/src/lwip-1.4.1/src/core/tcp_out.c b/src/lwip-1.4.1/src/core/tcp_out.c new file mode 100644 index 0000000..ee19fe0 --- /dev/null +++ b/src/lwip-1.4.1/src/core/tcp_out.c @@ -0,0 +1,1485 @@ +/** + * @file + * Transmission Control Protocol, outgoing traffic + * + * The output functions of TCP. + * + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#include "lwip/opt.h" + +#if LWIP_TCP /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/tcp_impl.h" +#include "lwip/def.h" +#include "lwip/mem.h" +#include "lwip/memp.h" +#include "lwip/ip_addr.h" +#include "lwip/netif.h" +#include "lwip/inet_chksum.h" +#include "lwip/stats.h" +#include "lwip/snmp.h" +#if LWIP_TCP_TIMESTAMPS +#include "lwip/sys.h" +#endif + +#include + +/* Define some copy-macros for checksum-on-copy so that the code looks + nicer by preventing too many ifdef's. */ +#if TCP_CHECKSUM_ON_COPY +#define TCP_DATA_COPY(dst, src, len, seg) do { \ + tcp_seg_add_chksum(LWIP_CHKSUM_COPY(dst, src, len), \ + len, &seg->chksum, &seg->chksum_swapped); \ + seg->flags |= TF_SEG_DATA_CHECKSUMMED; } while(0) +#define TCP_DATA_COPY2(dst, src, len, chksum, chksum_swapped) \ + tcp_seg_add_chksum(LWIP_CHKSUM_COPY(dst, src, len), len, chksum, chksum_swapped); +#else /* TCP_CHECKSUM_ON_COPY*/ +#define TCP_DATA_COPY(dst, src, len, seg) MEMCPY(dst, src, len) +#define TCP_DATA_COPY2(dst, src, len, chksum, chksum_swapped) MEMCPY(dst, src, len) +#endif /* TCP_CHECKSUM_ON_COPY*/ + +/** Define this to 1 for an extra check that the output checksum is valid + * (usefule when the checksum is generated by the application, not the stack) */ +#ifndef TCP_CHECKSUM_ON_COPY_SANITY_CHECK +#define TCP_CHECKSUM_ON_COPY_SANITY_CHECK 0 +#endif + +/* Forward declarations.*/ +static void tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb); + +/** Allocate a pbuf and create a tcphdr at p->payload, used for output + * functions other than the default tcp_output -> tcp_output_segment + * (e.g. tcp_send_empty_ack, etc.) + * + * @param pcb tcp pcb for which to send a packet (used to initialize tcp_hdr) + * @param optlen length of header-options + * @param datalen length of tcp data to reserve in pbuf + * @param seqno_be seqno in network byte order (big-endian) + * @return pbuf with p->payload being the tcp_hdr + */ +static struct pbuf * +tcp_output_alloc_header(struct tcp_pcb *pcb, u16_t optlen, u16_t datalen, + u32_t seqno_be /* already in network byte order */) +{ + struct tcp_hdr *tcphdr; + struct pbuf *p = pbuf_alloc(PBUF_IP, TCP_HLEN + optlen + datalen, PBUF_RAM); + if (p != NULL) { + LWIP_ASSERT("check that first pbuf can hold struct tcp_hdr", + (p->len >= TCP_HLEN + optlen)); + tcphdr = (struct tcp_hdr *)p->payload; + tcphdr->src = htons(pcb->local_port); + tcphdr->dest = htons(pcb->remote_port); + tcphdr->seqno = seqno_be; + tcphdr->ackno = htonl(pcb->rcv_nxt); + TCPH_HDRLEN_FLAGS_SET(tcphdr, (5 + optlen / 4), TCP_ACK); + tcphdr->wnd = htons(pcb->rcv_ann_wnd); + tcphdr->chksum = 0; + tcphdr->urgp = 0; + + /* If we're sending a packet, update the announced right window edge */ + pcb->rcv_ann_right_edge = pcb->rcv_nxt + pcb->rcv_ann_wnd; + } + return p; +} + +/** + * Called by tcp_close() to send a segment including FIN flag but not data. + * + * @param pcb the tcp_pcb over which to send a segment + * @return ERR_OK if sent, another err_t otherwise + */ +err_t +tcp_send_fin(struct tcp_pcb *pcb) +{ + /* first, try to add the fin to the last unsent segment */ + if (pcb->unsent != NULL) { + struct tcp_seg *last_unsent; + for (last_unsent = pcb->unsent; last_unsent->next != NULL; + last_unsent = last_unsent->next); + + if ((TCPH_FLAGS(last_unsent->tcphdr) & (TCP_SYN | TCP_FIN | TCP_RST)) == 0) { + /* no SYN/FIN/RST flag in the header, we can add the FIN flag */ + TCPH_SET_FLAG(last_unsent->tcphdr, TCP_FIN); + pcb->flags |= TF_FIN; + return ERR_OK; + } + } + /* no data, no length, flags, copy=1, no optdata */ + return tcp_enqueue_flags(pcb, TCP_FIN); +} + +/** + * Create a TCP segment with prefilled header. + * + * Called by tcp_write and tcp_enqueue_flags. + * + * @param pcb Protocol control block for the TCP connection. + * @param p pbuf that is used to hold the TCP header. + * @param flags TCP flags for header. + * @param seqno TCP sequence number of this packet + * @param optflags options to include in TCP header + * @return a new tcp_seg pointing to p, or NULL. + * The TCP header is filled in except ackno and wnd. + * p is freed on failure. + */ +static struct tcp_seg * +tcp_create_segment(struct tcp_pcb *pcb, struct pbuf *p, u8_t flags, u32_t seqno, u8_t optflags) +{ + struct tcp_seg *seg; + u8_t optlen = LWIP_TCP_OPT_LENGTH(optflags); + + if ((seg = (struct tcp_seg *)memp_malloc(MEMP_TCP_SEG)) == NULL) { + LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_create_segment: no memory.\n")); + pbuf_free(p); + return NULL; + } + seg->flags = optflags; + seg->next = NULL; + seg->p = p; + seg->len = p->tot_len - optlen; +#if TCP_OVERSIZE_DBGCHECK + seg->oversize_left = 0; +#endif /* TCP_OVERSIZE_DBGCHECK */ +#if TCP_CHECKSUM_ON_COPY + seg->chksum = 0; + seg->chksum_swapped = 0; + /* check optflags */ + LWIP_ASSERT("invalid optflags passed: TF_SEG_DATA_CHECKSUMMED", + (optflags & TF_SEG_DATA_CHECKSUMMED) == 0); +#endif /* TCP_CHECKSUM_ON_COPY */ + + /* build TCP header */ + if (pbuf_header(p, TCP_HLEN)) { + LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_create_segment: no room for TCP header in pbuf.\n")); + TCP_STATS_INC(tcp.err); + tcp_seg_free(seg); + return NULL; + } + seg->tcphdr = (struct tcp_hdr *)seg->p->payload; + seg->tcphdr->src = htons(pcb->local_port); + seg->tcphdr->dest = htons(pcb->remote_port); + seg->tcphdr->seqno = htonl(seqno); + /* ackno is set in tcp_output */ + TCPH_HDRLEN_FLAGS_SET(seg->tcphdr, (5 + optlen / 4), flags); + /* wnd and chksum are set in tcp_output */ + seg->tcphdr->urgp = 0; + return seg; +} + +/** + * Allocate a PBUF_RAM pbuf, perhaps with extra space at the end. + * + * This function is like pbuf_alloc(layer, length, PBUF_RAM) except + * there may be extra bytes available at the end. + * + * @param layer flag to define header size. + * @param length size of the pbuf's payload. + * @param max_length maximum usable size of payload+oversize. + * @param oversize pointer to a u16_t that will receive the number of usable tail bytes. + * @param pcb The TCP connection that willo enqueue the pbuf. + * @param apiflags API flags given to tcp_write. + * @param first_seg true when this pbuf will be used in the first enqueued segment. + * @param + */ +#if TCP_OVERSIZE +static struct pbuf * +tcp_pbuf_prealloc(pbuf_layer layer, u16_t length, u16_t max_length, + u16_t *oversize, struct tcp_pcb *pcb, u8_t apiflags, + u8_t first_seg) +{ + struct pbuf *p; + u16_t alloc = length; + +#if LWIP_NETIF_TX_SINGLE_PBUF + LWIP_UNUSED_ARG(max_length); + LWIP_UNUSED_ARG(pcb); + LWIP_UNUSED_ARG(apiflags); + LWIP_UNUSED_ARG(first_seg); + /* always create MSS-sized pbufs */ + alloc = max_length; +#else /* LWIP_NETIF_TX_SINGLE_PBUF */ + if (length < max_length) { + /* Should we allocate an oversized pbuf, or just the minimum + * length required? If tcp_write is going to be called again + * before this segment is transmitted, we want the oversized + * buffer. If the segment will be transmitted immediately, we can + * save memory by allocating only length. We use a simple + * heuristic based on the following information: + * + * Did the user set TCP_WRITE_FLAG_MORE? + * + * Will the Nagle algorithm defer transmission of this segment? + */ + if ((apiflags & TCP_WRITE_FLAG_MORE) || + (!(pcb->flags & TF_NODELAY) && + (!first_seg || + pcb->unsent != NULL || + pcb->unacked != NULL))) { + alloc = LWIP_MIN(max_length, LWIP_MEM_ALIGN_SIZE(length + TCP_OVERSIZE)); + } + } +#endif /* LWIP_NETIF_TX_SINGLE_PBUF */ + p = pbuf_alloc(layer, alloc, PBUF_RAM); + if (p == NULL) { + return NULL; + } + LWIP_ASSERT("need unchained pbuf", p->next == NULL); + *oversize = p->len - length; + /* trim p->len to the currently used size */ + p->len = p->tot_len = length; + return p; +} +#else /* TCP_OVERSIZE */ +#define tcp_pbuf_prealloc(layer, length, mx, os, pcb, api, fst) pbuf_alloc((layer), (length), PBUF_RAM) +#endif /* TCP_OVERSIZE */ + +#if TCP_CHECKSUM_ON_COPY +/** Add a checksum of newly added data to the segment */ +static void +tcp_seg_add_chksum(u16_t chksum, u16_t len, u16_t *seg_chksum, + u8_t *seg_chksum_swapped) +{ + u32_t helper; + /* add chksum to old chksum and fold to u16_t */ + helper = chksum + *seg_chksum; + chksum = FOLD_U32T(helper); + if ((len & 1) != 0) { + *seg_chksum_swapped = 1 - *seg_chksum_swapped; + chksum = SWAP_BYTES_IN_WORD(chksum); + } + *seg_chksum = chksum; +} +#endif /* TCP_CHECKSUM_ON_COPY */ + +/** Checks if tcp_write is allowed or not (checks state, snd_buf and snd_queuelen). + * + * @param pcb the tcp pcb to check for + * @param len length of data to send (checked agains snd_buf) + * @return ERR_OK if tcp_write is allowed to proceed, another err_t otherwise + */ +static err_t +tcp_write_checks(struct tcp_pcb *pcb, u16_t len) +{ + /* connection is in invalid state for data transmission? */ + if ((pcb->state != ESTABLISHED) && + (pcb->state != CLOSE_WAIT) && + (pcb->state != SYN_SENT) && + (pcb->state != SYN_RCVD)) { + LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_STATE | LWIP_DBG_LEVEL_SEVERE, ("tcp_write() called in invalid state\n")); + return ERR_CONN; + } else if (len == 0) { + return ERR_OK; + } + + /* fail on too much data */ + if (len > pcb->snd_buf) { + LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 3, ("tcp_write: too much data (len=%"U16_F" > snd_buf=%"U16_F")\n", + len, pcb->snd_buf)); + pcb->flags |= TF_NAGLEMEMERR; + return ERR_MEM; + } + + LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_write: queuelen: %"U16_F"\n", (u16_t)pcb->snd_queuelen)); + + /* If total number of pbufs on the unsent/unacked queues exceeds the + * configured maximum, return an error */ + /* check for configured max queuelen and possible overflow */ + if ((pcb->snd_queuelen >= TCP_SND_QUEUELEN) || (pcb->snd_queuelen > TCP_SNDQUEUELEN_OVERFLOW)) { + LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 3, ("tcp_write: too long queue %"U16_F" (max %"U16_F")\n", + pcb->snd_queuelen, TCP_SND_QUEUELEN)); + TCP_STATS_INC(tcp.memerr); + pcb->flags |= TF_NAGLEMEMERR; + return ERR_MEM; + } + if (pcb->snd_queuelen != 0) { + LWIP_ASSERT("tcp_write: pbufs on queue => at least one queue non-empty", + pcb->unacked != NULL || pcb->unsent != NULL); + } else { + LWIP_ASSERT("tcp_write: no pbufs on queue => both queues empty", + pcb->unacked == NULL && pcb->unsent == NULL); + } + return ERR_OK; +} + +/** + * Write data for sending (but does not send it immediately). + * + * It waits in the expectation of more data being sent soon (as + * it can send them more efficiently by combining them together). + * To prompt the system to send data now, call tcp_output() after + * calling tcp_write(). + * + * @param pcb Protocol control block for the TCP connection to enqueue data for. + * @param arg Pointer to the data to be enqueued for sending. + * @param len Data length in bytes + * @param apiflags combination of following flags : + * - TCP_WRITE_FLAG_COPY (0x01) data will be copied into memory belonging to the stack + * - TCP_WRITE_FLAG_MORE (0x02) for TCP connection, PSH flag will be set on last segment sent, + * @return ERR_OK if enqueued, another err_t on error + */ +err_t +tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags) +{ + struct pbuf *concat_p = NULL; + struct tcp_seg *last_unsent = NULL, *seg = NULL, *prev_seg = NULL, *queue = NULL; + u16_t pos = 0; /* position in 'arg' data */ + u16_t queuelen; + u8_t optlen = 0; + u8_t optflags = 0; +#if TCP_OVERSIZE + u16_t oversize = 0; + u16_t oversize_used = 0; +#endif /* TCP_OVERSIZE */ +#if TCP_CHECKSUM_ON_COPY + u16_t concat_chksum = 0; + u8_t concat_chksum_swapped = 0; + u16_t concat_chksummed = 0; +#endif /* TCP_CHECKSUM_ON_COPY */ + err_t err; + /* don't allocate segments bigger than half the maximum window we ever received */ + u16_t mss_local = LWIP_MIN(pcb->mss, pcb->snd_wnd_max/2); + +#if LWIP_NETIF_TX_SINGLE_PBUF + /* Always copy to try to create single pbufs for TX */ + apiflags |= TCP_WRITE_FLAG_COPY; +#endif /* LWIP_NETIF_TX_SINGLE_PBUF */ + + LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_write(pcb=%p, data=%p, len=%"U16_F", apiflags=%"U16_F")\n", + (void *)pcb, arg, len, (u16_t)apiflags)); + LWIP_ERROR("tcp_write: arg == NULL (programmer violates API)", + arg != NULL, return ERR_ARG;); + + err = tcp_write_checks(pcb, len); + if (err != ERR_OK) { + return err; + } + queuelen = pcb->snd_queuelen; + +#if LWIP_TCP_TIMESTAMPS + if ((pcb->flags & TF_TIMESTAMP)) { + optflags = TF_SEG_OPTS_TS; + optlen = LWIP_TCP_OPT_LENGTH(TF_SEG_OPTS_TS); + } +#endif /* LWIP_TCP_TIMESTAMPS */ + + + /* + * TCP segmentation is done in three phases with increasing complexity: + * + * 1. Copy data directly into an oversized pbuf. + * 2. Chain a new pbuf to the end of pcb->unsent. + * 3. Create new segments. + * + * We may run out of memory at any point. In that case we must + * return ERR_MEM and not change anything in pcb. Therefore, all + * changes are recorded in local variables and committed at the end + * of the function. Some pcb fields are maintained in local copies: + * + * queuelen = pcb->snd_queuelen + * oversize = pcb->unsent_oversize + * + * These variables are set consistently by the phases: + * + * seg points to the last segment tampered with. + * + * pos records progress as data is segmented. + */ + + /* Find the tail of the unsent queue. */ + if (pcb->unsent != NULL) { + u16_t space; + u16_t unsent_optlen; + + /* @todo: this could be sped up by keeping last_unsent in the pcb */ + for (last_unsent = pcb->unsent; last_unsent->next != NULL; + last_unsent = last_unsent->next); + + /* Usable space at the end of the last unsent segment */ + unsent_optlen = LWIP_TCP_OPT_LENGTH(last_unsent->flags); + space = mss_local - (last_unsent->len + unsent_optlen); + + /* + * Phase 1: Copy data directly into an oversized pbuf. + * + * The number of bytes copied is recorded in the oversize_used + * variable. The actual copying is done at the bottom of the + * function. + */ +#if TCP_OVERSIZE +#if TCP_OVERSIZE_DBGCHECK + /* check that pcb->unsent_oversize matches last_unsent->unsent_oversize */ + LWIP_ASSERT("unsent_oversize mismatch (pcb vs. last_unsent)", + pcb->unsent_oversize == last_unsent->oversize_left); +#endif /* TCP_OVERSIZE_DBGCHECK */ + oversize = pcb->unsent_oversize; + if (oversize > 0) { + LWIP_ASSERT("inconsistent oversize vs. space", oversize_used <= space); + seg = last_unsent; + oversize_used = oversize < len ? oversize : len; + pos += oversize_used; + oversize -= oversize_used; + space -= oversize_used; + } + /* now we are either finished or oversize is zero */ + LWIP_ASSERT("inconsistend oversize vs. len", (oversize == 0) || (pos == len)); +#endif /* TCP_OVERSIZE */ + + /* + * Phase 2: Chain a new pbuf to the end of pcb->unsent. + * + * We don't extend segments containing SYN/FIN flags or options + * (len==0). The new pbuf is kept in concat_p and pbuf_cat'ed at + * the end. + */ + if ((pos < len) && (space > 0) && (last_unsent->len > 0)) { + u16_t seglen = space < len - pos ? space : len - pos; + seg = last_unsent; + + /* Create a pbuf with a copy or reference to seglen bytes. We + * can use PBUF_RAW here since the data appears in the middle of + * a segment. A header will never be prepended. */ + if (apiflags & TCP_WRITE_FLAG_COPY) { + /* Data is copied */ + if ((concat_p = tcp_pbuf_prealloc(PBUF_RAW, seglen, space, &oversize, pcb, apiflags, 1)) == NULL) { + LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, + ("tcp_write : could not allocate memory for pbuf copy size %"U16_F"\n", + seglen)); + goto memerr; + } +#if TCP_OVERSIZE_DBGCHECK + last_unsent->oversize_left += oversize; +#endif /* TCP_OVERSIZE_DBGCHECK */ + TCP_DATA_COPY2(concat_p->payload, (u8_t*)arg + pos, seglen, &concat_chksum, &concat_chksum_swapped); +#if TCP_CHECKSUM_ON_COPY + concat_chksummed += seglen; +#endif /* TCP_CHECKSUM_ON_COPY */ + } else { + /* Data is not copied */ + if ((concat_p = pbuf_alloc(PBUF_RAW, seglen, PBUF_ROM)) == NULL) { + LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, + ("tcp_write: could not allocate memory for zero-copy pbuf\n")); + goto memerr; + } +#if TCP_CHECKSUM_ON_COPY + /* calculate the checksum of nocopy-data */ + tcp_seg_add_chksum(~inet_chksum((u8_t*)arg + pos, seglen), seglen, + &concat_chksum, &concat_chksum_swapped); + concat_chksummed += seglen; +#endif /* TCP_CHECKSUM_ON_COPY */ + /* reference the non-volatile payload data */ + concat_p->payload = (u8_t*)arg + pos; + } + + pos += seglen; + queuelen += pbuf_clen(concat_p); + } + } else { +#if TCP_OVERSIZE + LWIP_ASSERT("unsent_oversize mismatch (pcb->unsent is NULL)", + pcb->unsent_oversize == 0); +#endif /* TCP_OVERSIZE */ + } + + /* + * Phase 3: Create new segments. + * + * The new segments are chained together in the local 'queue' + * variable, ready to be appended to pcb->unsent. + */ + while (pos < len) { + struct pbuf *p; + u16_t left = len - pos; + u16_t max_len = mss_local - optlen; + u16_t seglen = left > max_len ? max_len : left; +#if TCP_CHECKSUM_ON_COPY + u16_t chksum = 0; + u8_t chksum_swapped = 0; +#endif /* TCP_CHECKSUM_ON_COPY */ + + if (apiflags & TCP_WRITE_FLAG_COPY) { + /* If copy is set, memory should be allocated and data copied + * into pbuf */ + if ((p = tcp_pbuf_prealloc(PBUF_TRANSPORT, seglen + optlen, mss_local, &oversize, pcb, apiflags, queue == NULL)) == NULL) { + LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_write : could not allocate memory for pbuf copy size %"U16_F"\n", seglen)); + goto memerr; + } + LWIP_ASSERT("tcp_write: check that first pbuf can hold the complete seglen", + (p->len >= seglen)); + TCP_DATA_COPY2((char *)p->payload + optlen, (u8_t*)arg + pos, seglen, &chksum, &chksum_swapped); + } else { + /* Copy is not set: First allocate a pbuf for holding the data. + * Since the referenced data is available at least until it is + * sent out on the link (as it has to be ACKed by the remote + * party) we can safely use PBUF_ROM instead of PBUF_REF here. + */ + struct pbuf *p2; +#if TCP_OVERSIZE + LWIP_ASSERT("oversize == 0", oversize == 0); +#endif /* TCP_OVERSIZE */ + if ((p2 = pbuf_alloc(PBUF_TRANSPORT, seglen, PBUF_ROM)) == NULL) { + LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_write: could not allocate memory for zero-copy pbuf\n")); + goto memerr; + } +#if TCP_CHECKSUM_ON_COPY + /* calculate the checksum of nocopy-data */ + chksum = ~inet_chksum((u8_t*)arg + pos, seglen); +#endif /* TCP_CHECKSUM_ON_COPY */ + /* reference the non-volatile payload data */ + p2->payload = (u8_t*)arg + pos; + + /* Second, allocate a pbuf for the headers. */ + if ((p = pbuf_alloc(PBUF_TRANSPORT, optlen, PBUF_RAM)) == NULL) { + /* If allocation fails, we have to deallocate the data pbuf as + * well. */ + pbuf_free(p2); + LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_write: could not allocate memory for header pbuf\n")); + goto memerr; + } + /* Concatenate the headers and data pbufs together. */ + pbuf_cat(p/*header*/, p2/*data*/); + } + + queuelen += pbuf_clen(p); + + /* Now that there are more segments queued, we check again if the + * length of the queue exceeds the configured maximum or + * overflows. */ + if ((queuelen > TCP_SND_QUEUELEN) || (queuelen > TCP_SNDQUEUELEN_OVERFLOW)) { + LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_write: queue too long %"U16_F" (%"U16_F")\n", queuelen, TCP_SND_QUEUELEN)); + pbuf_free(p); + goto memerr; + } + + if ((seg = tcp_create_segment(pcb, p, 0, pcb->snd_lbb + pos, optflags)) == NULL) { + goto memerr; + } +#if TCP_OVERSIZE_DBGCHECK + seg->oversize_left = oversize; +#endif /* TCP_OVERSIZE_DBGCHECK */ +#if TCP_CHECKSUM_ON_COPY + seg->chksum = chksum; + seg->chksum_swapped = chksum_swapped; + seg->flags |= TF_SEG_DATA_CHECKSUMMED; +#endif /* TCP_CHECKSUM_ON_COPY */ + + /* first segment of to-be-queued data? */ + if (queue == NULL) { + queue = seg; + } else { + /* Attach the segment to the end of the queued segments */ + LWIP_ASSERT("prev_seg != NULL", prev_seg != NULL); + prev_seg->next = seg; + } + /* remember last segment of to-be-queued data for next iteration */ + prev_seg = seg; + + LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_TRACE, ("tcp_write: queueing %"U32_F":%"U32_F"\n", + ntohl(seg->tcphdr->seqno), + ntohl(seg->tcphdr->seqno) + TCP_TCPLEN(seg))); + + pos += seglen; + } + + /* + * All three segmentation phases were successful. We can commit the + * transaction. + */ + + /* + * Phase 1: If data has been added to the preallocated tail of + * last_unsent, we update the length fields of the pbuf chain. + */ +#if TCP_OVERSIZE + if (oversize_used > 0) { + struct pbuf *p; + /* Bump tot_len of whole chain, len of tail */ + for (p = last_unsent->p; p; p = p->next) { + p->tot_len += oversize_used; + if (p->next == NULL) { + TCP_DATA_COPY((char *)p->payload + p->len, arg, oversize_used, last_unsent); + p->len += oversize_used; + } + } + last_unsent->len += oversize_used; +#if TCP_OVERSIZE_DBGCHECK + LWIP_ASSERT("last_unsent->oversize_left >= oversize_used", + last_unsent->oversize_left >= oversize_used); + last_unsent->oversize_left -= oversize_used; +#endif /* TCP_OVERSIZE_DBGCHECK */ + } + pcb->unsent_oversize = oversize; +#endif /* TCP_OVERSIZE */ + + /* + * Phase 2: concat_p can be concatenated onto last_unsent->p + */ + if (concat_p != NULL) { + LWIP_ASSERT("tcp_write: cannot concatenate when pcb->unsent is empty", + (last_unsent != NULL)); + pbuf_cat(last_unsent->p, concat_p); + last_unsent->len += concat_p->tot_len; +#if TCP_CHECKSUM_ON_COPY + if (concat_chksummed) { + tcp_seg_add_chksum(concat_chksum, concat_chksummed, &last_unsent->chksum, + &last_unsent->chksum_swapped); + last_unsent->flags |= TF_SEG_DATA_CHECKSUMMED; + } +#endif /* TCP_CHECKSUM_ON_COPY */ + } + + /* + * Phase 3: Append queue to pcb->unsent. Queue may be NULL, but that + * is harmless + */ + if (last_unsent == NULL) { + pcb->unsent = queue; + } else { + last_unsent->next = queue; + } + + /* + * Finally update the pcb state. + */ + pcb->snd_lbb += len; + pcb->snd_buf -= len; + pcb->snd_queuelen = queuelen; + + LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_write: %"S16_F" (after enqueued)\n", + pcb->snd_queuelen)); + if (pcb->snd_queuelen != 0) { + LWIP_ASSERT("tcp_write: valid queue length", + pcb->unacked != NULL || pcb->unsent != NULL); + } + + /* Set the PSH flag in the last segment that we enqueued. */ + if (seg != NULL && seg->tcphdr != NULL && ((apiflags & TCP_WRITE_FLAG_MORE)==0)) { + TCPH_SET_FLAG(seg->tcphdr, TCP_PSH); + } + + return ERR_OK; +memerr: + pcb->flags |= TF_NAGLEMEMERR; + TCP_STATS_INC(tcp.memerr); + + if (concat_p != NULL) { + pbuf_free(concat_p); + } + if (queue != NULL) { + tcp_segs_free(queue); + } + if (pcb->snd_queuelen != 0) { + LWIP_ASSERT("tcp_write: valid queue length", pcb->unacked != NULL || + pcb->unsent != NULL); + } + LWIP_DEBUGF(TCP_QLEN_DEBUG | LWIP_DBG_STATE, ("tcp_write: %"S16_F" (with mem err)\n", pcb->snd_queuelen)); + return ERR_MEM; +} + +/** + * Enqueue TCP options for transmission. + * + * Called by tcp_connect(), tcp_listen_input(), and tcp_send_ctrl(). + * + * @param pcb Protocol control block for the TCP connection. + * @param flags TCP header flags to set in the outgoing segment. + * @param optdata pointer to TCP options, or NULL. + * @param optlen length of TCP options in bytes. + */ +err_t +tcp_enqueue_flags(struct tcp_pcb *pcb, u8_t flags) +{ + struct pbuf *p; + struct tcp_seg *seg; + u8_t optflags = 0; + u8_t optlen = 0; + + LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_enqueue_flags: queuelen: %"U16_F"\n", (u16_t)pcb->snd_queuelen)); + + LWIP_ASSERT("tcp_enqueue_flags: need either TCP_SYN or TCP_FIN in flags (programmer violates API)", + (flags & (TCP_SYN | TCP_FIN)) != 0); + + /* check for configured max queuelen and possible overflow */ + if ((pcb->snd_queuelen >= TCP_SND_QUEUELEN) || (pcb->snd_queuelen > TCP_SNDQUEUELEN_OVERFLOW)) { + LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 3, ("tcp_enqueue_flags: too long queue %"U16_F" (max %"U16_F")\n", + pcb->snd_queuelen, TCP_SND_QUEUELEN)); + TCP_STATS_INC(tcp.memerr); + pcb->flags |= TF_NAGLEMEMERR; + return ERR_MEM; + } + + if (flags & TCP_SYN) { + optflags = TF_SEG_OPTS_MSS; + } +#if LWIP_TCP_TIMESTAMPS + if ((pcb->flags & TF_TIMESTAMP)) { + optflags |= TF_SEG_OPTS_TS; + } +#endif /* LWIP_TCP_TIMESTAMPS */ + optlen = LWIP_TCP_OPT_LENGTH(optflags); + + /* tcp_enqueue_flags is always called with either SYN or FIN in flags. + * We need one available snd_buf byte to do that. + * This means we can't send FIN while snd_buf==0. A better fix would be to + * not include SYN and FIN sequence numbers in the snd_buf count. */ + if (pcb->snd_buf == 0) { + LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 3, ("tcp_enqueue_flags: no send buffer available\n")); + TCP_STATS_INC(tcp.memerr); + return ERR_MEM; + } + + /* Allocate pbuf with room for TCP header + options */ + if ((p = pbuf_alloc(PBUF_TRANSPORT, optlen, PBUF_RAM)) == NULL) { + pcb->flags |= TF_NAGLEMEMERR; + TCP_STATS_INC(tcp.memerr); + return ERR_MEM; + } + LWIP_ASSERT("tcp_enqueue_flags: check that first pbuf can hold optlen", + (p->len >= optlen)); + + /* Allocate memory for tcp_seg, and fill in fields. */ + if ((seg = tcp_create_segment(pcb, p, flags, pcb->snd_lbb, optflags)) == NULL) { + pcb->flags |= TF_NAGLEMEMERR; + TCP_STATS_INC(tcp.memerr); + return ERR_MEM; + } + LWIP_ASSERT("seg->tcphdr not aligned", ((mem_ptr_t)seg->tcphdr % MEM_ALIGNMENT) == 0); + LWIP_ASSERT("tcp_enqueue_flags: invalid segment length", seg->len == 0); + + LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_TRACE, + ("tcp_enqueue_flags: queueing %"U32_F":%"U32_F" (0x%"X16_F")\n", + ntohl(seg->tcphdr->seqno), + ntohl(seg->tcphdr->seqno) + TCP_TCPLEN(seg), + (u16_t)flags)); + + /* Now append seg to pcb->unsent queue */ + if (pcb->unsent == NULL) { + pcb->unsent = seg; + } else { + struct tcp_seg *useg; + for (useg = pcb->unsent; useg->next != NULL; useg = useg->next); + useg->next = seg; + } +#if TCP_OVERSIZE + /* The new unsent tail has no space */ + pcb->unsent_oversize = 0; +#endif /* TCP_OVERSIZE */ + + /* SYN and FIN bump the sequence number */ + if ((flags & TCP_SYN) || (flags & TCP_FIN)) { + pcb->snd_lbb++; + /* optlen does not influence snd_buf */ + pcb->snd_buf--; + } + if (flags & TCP_FIN) { + pcb->flags |= TF_FIN; + } + + /* update number of segments on the queues */ + pcb->snd_queuelen += pbuf_clen(seg->p); + LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_enqueue_flags: %"S16_F" (after enqueued)\n", pcb->snd_queuelen)); + if (pcb->snd_queuelen != 0) { + LWIP_ASSERT("tcp_enqueue_flags: invalid queue length", + pcb->unacked != NULL || pcb->unsent != NULL); + } + + return ERR_OK; +} + +#if LWIP_TCP_TIMESTAMPS +/* Build a timestamp option (12 bytes long) at the specified options pointer) + * + * @param pcb tcp_pcb + * @param opts option pointer where to store the timestamp option + */ +static void +tcp_build_timestamp_option(struct tcp_pcb *pcb, u32_t *opts) +{ + /* Pad with two NOP options to make everything nicely aligned */ + opts[0] = PP_HTONL(0x0101080A); + opts[1] = htonl(sys_now()); + opts[2] = htonl(pcb->ts_recent); +} +#endif + +/** Send an ACK without data. + * + * @param pcb Protocol control block for the TCP connection to send the ACK + */ +err_t +tcp_send_empty_ack(struct tcp_pcb *pcb) +{ + struct pbuf *p; + struct tcp_hdr *tcphdr; + u8_t optlen = 0; + +#if LWIP_TCP_TIMESTAMPS + if (pcb->flags & TF_TIMESTAMP) { + optlen = LWIP_TCP_OPT_LENGTH(TF_SEG_OPTS_TS); + } +#endif + + p = tcp_output_alloc_header(pcb, optlen, 0, htonl(pcb->snd_nxt)); + if (p == NULL) { + LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_output: (ACK) could not allocate pbuf\n")); + return ERR_BUF; + } + tcphdr = (struct tcp_hdr *)p->payload; + LWIP_DEBUGF(TCP_OUTPUT_DEBUG, + ("tcp_output: sending ACK for %"U32_F"\n", pcb->rcv_nxt)); + /* remove ACK flags from the PCB, as we send an empty ACK now */ + pcb->flags &= ~(TF_ACK_DELAY | TF_ACK_NOW); + + /* NB. MSS option is only sent on SYNs, so ignore it here */ +#if LWIP_TCP_TIMESTAMPS + pcb->ts_lastacksent = pcb->rcv_nxt; + + if (pcb->flags & TF_TIMESTAMP) { + tcp_build_timestamp_option(pcb, (u32_t *)(tcphdr + 1)); + } +#endif + +#if CHECKSUM_GEN_TCP + tcphdr->chksum = inet_chksum_pseudo(p, &(pcb->local_ip), &(pcb->remote_ip), + IP_PROTO_TCP, p->tot_len); +#endif +#if LWIP_NETIF_HWADDRHINT + ip_output_hinted(p, &(pcb->local_ip), &(pcb->remote_ip), pcb->ttl, pcb->tos, + IP_PROTO_TCP, &(pcb->addr_hint)); +#else /* LWIP_NETIF_HWADDRHINT*/ + ip_output(p, &(pcb->local_ip), &(pcb->remote_ip), pcb->ttl, pcb->tos, + IP_PROTO_TCP); +#endif /* LWIP_NETIF_HWADDRHINT*/ + pbuf_free(p); + + return ERR_OK; +} + +/** + * Find out what we can send and send it + * + * @param pcb Protocol control block for the TCP connection to send data + * @return ERR_OK if data has been sent or nothing to send + * another err_t on error + */ +err_t +tcp_output(struct tcp_pcb *pcb) +{ + struct tcp_seg *seg, *useg; + u32_t wnd, snd_nxt; +#if TCP_CWND_DEBUG + s16_t i = 0; +#endif /* TCP_CWND_DEBUG */ + + /* pcb->state LISTEN not allowed here */ + LWIP_ASSERT("don't call tcp_output for listen-pcbs", + pcb->state != LISTEN); + + /* First, check if we are invoked by the TCP input processing + code. If so, we do not output anything. Instead, we rely on the + input processing code to call us when input processing is done + with. */ + if (tcp_input_pcb == pcb) { + return ERR_OK; + } + + wnd = LWIP_MIN(pcb->snd_wnd, pcb->cwnd); + + seg = pcb->unsent; + + /* If the TF_ACK_NOW flag is set and no data will be sent (either + * because the ->unsent queue is empty or because the window does + * not allow it), construct an empty ACK segment and send it. + * + * If data is to be sent, we will just piggyback the ACK (see below). + */ + if (pcb->flags & TF_ACK_NOW && + (seg == NULL || + ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len > wnd)) { + return tcp_send_empty_ack(pcb); + } + + /* useg should point to last segment on unacked queue */ + useg = pcb->unacked; + if (useg != NULL) { + for (; useg->next != NULL; useg = useg->next); + } + +#if TCP_OUTPUT_DEBUG + if (seg == NULL) { + LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_output: nothing to send (%p)\n", + (void*)pcb->unsent)); + } +#endif /* TCP_OUTPUT_DEBUG */ +#if TCP_CWND_DEBUG + if (seg == NULL) { + LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_output: snd_wnd %"U16_F + ", cwnd %"U16_F", wnd %"U32_F + ", seg == NULL, ack %"U32_F"\n", + pcb->snd_wnd, pcb->cwnd, wnd, pcb->lastack)); + } else { + LWIP_DEBUGF(TCP_CWND_DEBUG, + ("tcp_output: snd_wnd %"U16_F", cwnd %"U16_F", wnd %"U32_F + ", effwnd %"U32_F", seq %"U32_F", ack %"U32_F"\n", + pcb->snd_wnd, pcb->cwnd, wnd, + ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len, + ntohl(seg->tcphdr->seqno), pcb->lastack)); + } +#endif /* TCP_CWND_DEBUG */ + /* data available and window allows it to be sent? */ + while (seg != NULL && + ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len <= wnd) { + LWIP_ASSERT("RST not expected here!", + (TCPH_FLAGS(seg->tcphdr) & TCP_RST) == 0); + /* Stop sending if the nagle algorithm would prevent it + * Don't stop: + * - if tcp_write had a memory error before (prevent delayed ACK timeout) or + * - if FIN was already enqueued for this PCB (SYN is always alone in a segment - + * either seg->next != NULL or pcb->unacked == NULL; + * RST is no sent using tcp_write/tcp_output. + */ + if((tcp_do_output_nagle(pcb) == 0) && + ((pcb->flags & (TF_NAGLEMEMERR | TF_FIN)) == 0)){ + break; + } +#if TCP_CWND_DEBUG + LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_output: snd_wnd %"U16_F", cwnd %"U16_F", wnd %"U32_F", effwnd %"U32_F", seq %"U32_F", ack %"U32_F", i %"S16_F"\n", + pcb->snd_wnd, pcb->cwnd, wnd, + ntohl(seg->tcphdr->seqno) + seg->len - + pcb->lastack, + ntohl(seg->tcphdr->seqno), pcb->lastack, i)); + ++i; +#endif /* TCP_CWND_DEBUG */ + + pcb->unsent = seg->next; + + if (pcb->state != SYN_SENT) { + TCPH_SET_FLAG(seg->tcphdr, TCP_ACK); + pcb->flags &= ~(TF_ACK_DELAY | TF_ACK_NOW); + } + + tcp_output_segment(seg, pcb); + snd_nxt = ntohl(seg->tcphdr->seqno) + TCP_TCPLEN(seg); + if (TCP_SEQ_LT(pcb->snd_nxt, snd_nxt)) { + pcb->snd_nxt = snd_nxt; + } + /* put segment on unacknowledged list if length > 0 */ + if (TCP_TCPLEN(seg) > 0) { + seg->next = NULL; + /* unacked list is empty? */ + if (pcb->unacked == NULL) { + pcb->unacked = seg; + useg = seg; + /* unacked list is not empty? */ + } else { + /* In the case of fast retransmit, the packet should not go to the tail + * of the unacked queue, but rather somewhere before it. We need to check for + * this case. -STJ Jul 27, 2004 */ + if (TCP_SEQ_LT(ntohl(seg->tcphdr->seqno), ntohl(useg->tcphdr->seqno))) { + /* add segment to before tail of unacked list, keeping the list sorted */ + struct tcp_seg **cur_seg = &(pcb->unacked); + while (*cur_seg && + TCP_SEQ_LT(ntohl((*cur_seg)->tcphdr->seqno), ntohl(seg->tcphdr->seqno))) { + cur_seg = &((*cur_seg)->next ); + } + seg->next = (*cur_seg); + (*cur_seg) = seg; + } else { + /* add segment to tail of unacked list */ + useg->next = seg; + useg = useg->next; + } + } + /* do not queue empty segments on the unacked list */ + } else { + tcp_seg_free(seg); + } + seg = pcb->unsent; + } +#if TCP_OVERSIZE + if (pcb->unsent == NULL) { + /* last unsent has been removed, reset unsent_oversize */ + pcb->unsent_oversize = 0; + } +#endif /* TCP_OVERSIZE */ + + pcb->flags &= ~TF_NAGLEMEMERR; + return ERR_OK; +} + +/** + * Called by tcp_output() to actually send a TCP segment over IP. + * + * @param seg the tcp_seg to send + * @param pcb the tcp_pcb for the TCP connection used to send the segment + */ +static void +tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb) +{ + u16_t len; + struct netif *netif; + u32_t *opts; + + /** @bug Exclude retransmitted segments from this count. */ + snmp_inc_tcpoutsegs(); + + /* The TCP header has already been constructed, but the ackno and + wnd fields remain. */ + seg->tcphdr->ackno = htonl(pcb->rcv_nxt); + + /* advertise our receive window size in this TCP segment */ + seg->tcphdr->wnd = htons(pcb->rcv_ann_wnd); + + pcb->rcv_ann_right_edge = pcb->rcv_nxt + pcb->rcv_ann_wnd; + + /* Add any requested options. NB MSS option is only set on SYN + packets, so ignore it here */ + opts = (u32_t *)(void *)(seg->tcphdr + 1); + if (seg->flags & TF_SEG_OPTS_MSS) { + u16_t mss; +#if TCP_CALCULATE_EFF_SEND_MSS + mss = tcp_eff_send_mss(TCP_MSS, &pcb->remote_ip); +#else /* TCP_CALCULATE_EFF_SEND_MSS */ + mss = TCP_MSS; +#endif /* TCP_CALCULATE_EFF_SEND_MSS */ + *opts = TCP_BUILD_MSS_OPTION(mss); + opts += 1; + } +#if LWIP_TCP_TIMESTAMPS + pcb->ts_lastacksent = pcb->rcv_nxt; + + if (seg->flags & TF_SEG_OPTS_TS) { + tcp_build_timestamp_option(pcb, opts); + opts += 3; + } +#endif + + /* Set retransmission timer running if it is not currently enabled + This must be set before checking the route. */ + if (pcb->rtime == -1) { + pcb->rtime = 0; + } + + /* If we don't have a local IP address, we get one by + calling ip_route(). */ + if (ip_addr_isany(&(pcb->local_ip))) { + netif = ip_route(&(pcb->remote_ip)); + if (netif == NULL) { + return; + } + ip_addr_copy(pcb->local_ip, netif->ip_addr); + } + + if (pcb->rttest == 0) { + pcb->rttest = tcp_ticks; + pcb->rtseq = ntohl(seg->tcphdr->seqno); + + LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_output_segment: rtseq %"U32_F"\n", pcb->rtseq)); + } + LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_output_segment: %"U32_F":%"U32_F"\n", + htonl(seg->tcphdr->seqno), htonl(seg->tcphdr->seqno) + + seg->len)); + + len = (u16_t)((u8_t *)seg->tcphdr - (u8_t *)seg->p->payload); + + seg->p->len -= len; + seg->p->tot_len -= len; + + seg->p->payload = seg->tcphdr; + + seg->tcphdr->chksum = 0; +#if CHECKSUM_GEN_TCP +#if TCP_CHECKSUM_ON_COPY + { + u32_t acc; +#if TCP_CHECKSUM_ON_COPY_SANITY_CHECK + u16_t chksum_slow = inet_chksum_pseudo(seg->p, &(pcb->local_ip), + &(pcb->remote_ip), + IP_PROTO_TCP, seg->p->tot_len); +#endif /* TCP_CHECKSUM_ON_COPY_SANITY_CHECK */ + if ((seg->flags & TF_SEG_DATA_CHECKSUMMED) == 0) { + LWIP_ASSERT("data included but not checksummed", + seg->p->tot_len == (TCPH_HDRLEN(seg->tcphdr) * 4)); + } + + /* rebuild TCP header checksum (TCP header changes for retransmissions!) */ + acc = inet_chksum_pseudo_partial(seg->p, &(pcb->local_ip), + &(pcb->remote_ip), + IP_PROTO_TCP, seg->p->tot_len, TCPH_HDRLEN(seg->tcphdr) * 4); + /* add payload checksum */ + if (seg->chksum_swapped) { + seg->chksum = SWAP_BYTES_IN_WORD(seg->chksum); + seg->chksum_swapped = 0; + } + acc += (u16_t)~(seg->chksum); + seg->tcphdr->chksum = FOLD_U32T(acc); +#if TCP_CHECKSUM_ON_COPY_SANITY_CHECK + if (chksum_slow != seg->tcphdr->chksum) { + LWIP_DEBUGF(TCP_DEBUG | LWIP_DBG_LEVEL_WARNING, + ("tcp_output_segment: calculated checksum is %"X16_F" instead of %"X16_F"\n", + seg->tcphdr->chksum, chksum_slow)); + seg->tcphdr->chksum = chksum_slow; + } +#endif /* TCP_CHECKSUM_ON_COPY_SANITY_CHECK */ + } +#else /* TCP_CHECKSUM_ON_COPY */ + seg->tcphdr->chksum = inet_chksum_pseudo(seg->p, &(pcb->local_ip), + &(pcb->remote_ip), + IP_PROTO_TCP, seg->p->tot_len); +#endif /* TCP_CHECKSUM_ON_COPY */ +#endif /* CHECKSUM_GEN_TCP */ + TCP_STATS_INC(tcp.xmit); + +#if LWIP_NETIF_HWADDRHINT + ip_output_hinted(seg->p, &(pcb->local_ip), &(pcb->remote_ip), pcb->ttl, pcb->tos, + IP_PROTO_TCP, &(pcb->addr_hint)); +#else /* LWIP_NETIF_HWADDRHINT*/ + ip_output(seg->p, &(pcb->local_ip), &(pcb->remote_ip), pcb->ttl, pcb->tos, + IP_PROTO_TCP); +#endif /* LWIP_NETIF_HWADDRHINT*/ +} + +/** + * Send a TCP RESET packet (empty segment with RST flag set) either to + * abort a connection or to show that there is no matching local connection + * for a received segment. + * + * Called by tcp_abort() (to abort a local connection), tcp_input() (if no + * matching local pcb was found), tcp_listen_input() (if incoming segment + * has ACK flag set) and tcp_process() (received segment in the wrong state) + * + * Since a RST segment is in most cases not sent for an active connection, + * tcp_rst() has a number of arguments that are taken from a tcp_pcb for + * most other segment output functions. + * + * @param seqno the sequence number to use for the outgoing segment + * @param ackno the acknowledge number to use for the outgoing segment + * @param local_ip the local IP address to send the segment from + * @param remote_ip the remote IP address to send the segment to + * @param local_port the local TCP port to send the segment from + * @param remote_port the remote TCP port to send the segment to + */ +void +tcp_rst(u32_t seqno, u32_t ackno, + ip_addr_t *local_ip, ip_addr_t *remote_ip, + u16_t local_port, u16_t remote_port) +{ + struct pbuf *p; + struct tcp_hdr *tcphdr; + p = pbuf_alloc(PBUF_IP, TCP_HLEN, PBUF_RAM); + if (p == NULL) { + LWIP_DEBUGF(TCP_DEBUG, ("tcp_rst: could not allocate memory for pbuf\n")); + return; + } + LWIP_ASSERT("check that first pbuf can hold struct tcp_hdr", + (p->len >= sizeof(struct tcp_hdr))); + + tcphdr = (struct tcp_hdr *)p->payload; + tcphdr->src = htons(local_port); + tcphdr->dest = htons(remote_port); + tcphdr->seqno = htonl(seqno); + tcphdr->ackno = htonl(ackno); + TCPH_HDRLEN_FLAGS_SET(tcphdr, TCP_HLEN/4, TCP_RST | TCP_ACK); + tcphdr->wnd = PP_HTONS(TCP_WND); + tcphdr->chksum = 0; + tcphdr->urgp = 0; + +#if CHECKSUM_GEN_TCP + tcphdr->chksum = inet_chksum_pseudo(p, local_ip, remote_ip, + IP_PROTO_TCP, p->tot_len); +#endif + TCP_STATS_INC(tcp.xmit); + snmp_inc_tcpoutrsts(); + /* Send output with hardcoded TTL since we have no access to the pcb */ + ip_output(p, local_ip, remote_ip, TCP_TTL, 0, IP_PROTO_TCP); + pbuf_free(p); + LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_rst: seqno %"U32_F" ackno %"U32_F".\n", seqno, ackno)); +} + +/** + * Requeue all unacked segments for retransmission + * + * Called by tcp_slowtmr() for slow retransmission. + * + * @param pcb the tcp_pcb for which to re-enqueue all unacked segments + */ +void +tcp_rexmit_rto(struct tcp_pcb *pcb) +{ + struct tcp_seg *seg; + + if (pcb->unacked == NULL) { + return; + } + + /* Move all unacked segments to the head of the unsent queue */ + for (seg = pcb->unacked; seg->next != NULL; seg = seg->next); + /* concatenate unsent queue after unacked queue */ + seg->next = pcb->unsent; + /* unsent queue is the concatenated queue (of unacked, unsent) */ + pcb->unsent = pcb->unacked; + /* unacked queue is now empty */ + pcb->unacked = NULL; + /* last unsent hasn't changed, no need to reset unsent_oversize */ + + /* increment number of retransmissions */ + ++pcb->nrtx; + + /* Don't take any RTT measurements after retransmitting. */ + pcb->rttest = 0; + + /* Do the actual retransmission */ + tcp_output(pcb); +} + +/** + * Requeue the first unacked segment for retransmission + * + * Called by tcp_receive() for fast retramsmit. + * + * @param pcb the tcp_pcb for which to retransmit the first unacked segment + */ +void +tcp_rexmit(struct tcp_pcb *pcb) +{ + struct tcp_seg *seg; + struct tcp_seg **cur_seg; + + if (pcb->unacked == NULL) { + return; + } + + /* Move the first unacked segment to the unsent queue */ + /* Keep the unsent queue sorted. */ + seg = pcb->unacked; + pcb->unacked = seg->next; + + cur_seg = &(pcb->unsent); + while (*cur_seg && + TCP_SEQ_LT(ntohl((*cur_seg)->tcphdr->seqno), ntohl(seg->tcphdr->seqno))) { + cur_seg = &((*cur_seg)->next ); + } + seg->next = *cur_seg; + *cur_seg = seg; +#if TCP_OVERSIZE + if (seg->next == NULL) { + /* the retransmitted segment is last in unsent, so reset unsent_oversize */ + pcb->unsent_oversize = 0; + } +#endif /* TCP_OVERSIZE */ + + ++pcb->nrtx; + + /* Don't take any rtt measurements after retransmitting. */ + pcb->rttest = 0; + + /* Do the actual retransmission. */ + snmp_inc_tcpretranssegs(); + /* No need to call tcp_output: we are always called from tcp_input() + and thus tcp_output directly returns. */ +} + + +/** + * Handle retransmission after three dupacks received + * + * @param pcb the tcp_pcb for which to retransmit the first unacked segment + */ +void +tcp_rexmit_fast(struct tcp_pcb *pcb) +{ + if (pcb->unacked != NULL && !(pcb->flags & TF_INFR)) { + /* This is fast retransmit. Retransmit the first unacked segment. */ + LWIP_DEBUGF(TCP_FR_DEBUG, + ("tcp_receive: dupacks %"U16_F" (%"U32_F + "), fast retransmit %"U32_F"\n", + (u16_t)pcb->dupacks, pcb->lastack, + ntohl(pcb->unacked->tcphdr->seqno))); + tcp_rexmit(pcb); + + /* Set ssthresh to half of the minimum of the current + * cwnd and the advertised window */ + if (pcb->cwnd > pcb->snd_wnd) { + pcb->ssthresh = pcb->snd_wnd / 2; + } else { + pcb->ssthresh = pcb->cwnd / 2; + } + + /* The minimum value for ssthresh should be 2 MSS */ + if (pcb->ssthresh < 2*pcb->mss) { + LWIP_DEBUGF(TCP_FR_DEBUG, + ("tcp_receive: The minimum value for ssthresh %"U16_F + " should be min 2 mss %"U16_F"...\n", + pcb->ssthresh, 2*pcb->mss)); + pcb->ssthresh = 2*pcb->mss; + } + + pcb->cwnd = pcb->ssthresh + 3 * pcb->mss; + pcb->flags |= TF_INFR; + } +} + + +/** + * Send keepalive packets to keep a connection active although + * no data is sent over it. + * + * Called by tcp_slowtmr() + * + * @param pcb the tcp_pcb for which to send a keepalive packet + */ +void +tcp_keepalive(struct tcp_pcb *pcb) +{ + struct pbuf *p; + struct tcp_hdr *tcphdr; + + LWIP_DEBUGF(TCP_DEBUG, ("tcp_keepalive: sending KEEPALIVE probe to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", + ip4_addr1_16(&pcb->remote_ip), ip4_addr2_16(&pcb->remote_ip), + ip4_addr3_16(&pcb->remote_ip), ip4_addr4_16(&pcb->remote_ip))); + + LWIP_DEBUGF(TCP_DEBUG, ("tcp_keepalive: tcp_ticks %"U32_F" pcb->tmr %"U32_F" pcb->keep_cnt_sent %"U16_F"\n", + tcp_ticks, pcb->tmr, pcb->keep_cnt_sent)); + + p = tcp_output_alloc_header(pcb, 0, 0, htonl(pcb->snd_nxt - 1)); + if(p == NULL) { + LWIP_DEBUGF(TCP_DEBUG, + ("tcp_keepalive: could not allocate memory for pbuf\n")); + return; + } + tcphdr = (struct tcp_hdr *)p->payload; + +#if CHECKSUM_GEN_TCP + tcphdr->chksum = inet_chksum_pseudo(p, &pcb->local_ip, &pcb->remote_ip, + IP_PROTO_TCP, p->tot_len); +#endif + TCP_STATS_INC(tcp.xmit); + + /* Send output to IP */ +#if LWIP_NETIF_HWADDRHINT + ip_output_hinted(p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl, 0, IP_PROTO_TCP, + &(pcb->addr_hint)); +#else /* LWIP_NETIF_HWADDRHINT*/ + ip_output(p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl, 0, IP_PROTO_TCP); +#endif /* LWIP_NETIF_HWADDRHINT*/ + + pbuf_free(p); + + LWIP_DEBUGF(TCP_DEBUG, ("tcp_keepalive: seqno %"U32_F" ackno %"U32_F".\n", + pcb->snd_nxt - 1, pcb->rcv_nxt)); +} + + +/** + * Send persist timer zero-window probes to keep a connection active + * when a window update is lost. + * + * Called by tcp_slowtmr() + * + * @param pcb the tcp_pcb for which to send a zero-window probe packet + */ +void +tcp_zero_window_probe(struct tcp_pcb *pcb) +{ + struct pbuf *p; + struct tcp_hdr *tcphdr; + struct tcp_seg *seg; + u16_t len; + u8_t is_fin; + + LWIP_DEBUGF(TCP_DEBUG, + ("tcp_zero_window_probe: sending ZERO WINDOW probe to %" + U16_F".%"U16_F".%"U16_F".%"U16_F"\n", + ip4_addr1_16(&pcb->remote_ip), ip4_addr2_16(&pcb->remote_ip), + ip4_addr3_16(&pcb->remote_ip), ip4_addr4_16(&pcb->remote_ip))); + + LWIP_DEBUGF(TCP_DEBUG, + ("tcp_zero_window_probe: tcp_ticks %"U32_F + " pcb->tmr %"U32_F" pcb->keep_cnt_sent %"U16_F"\n", + tcp_ticks, pcb->tmr, pcb->keep_cnt_sent)); + + seg = pcb->unacked; + + if(seg == NULL) { + seg = pcb->unsent; + } + if(seg == NULL) { + return; + } + + is_fin = ((TCPH_FLAGS(seg->tcphdr) & TCP_FIN) != 0) && (seg->len == 0); + /* we want to send one seqno: either FIN or data (no options) */ + len = is_fin ? 0 : 1; + + p = tcp_output_alloc_header(pcb, 0, len, seg->tcphdr->seqno); + if(p == NULL) { + LWIP_DEBUGF(TCP_DEBUG, ("tcp_zero_window_probe: no memory for pbuf\n")); + return; + } + tcphdr = (struct tcp_hdr *)p->payload; + + if (is_fin) { + /* FIN segment, no data */ + TCPH_FLAGS_SET(tcphdr, TCP_ACK | TCP_FIN); + } else { + /* Data segment, copy in one byte from the head of the unacked queue */ + char *d = ((char *)p->payload + TCP_HLEN); + /* Depending on whether the segment has already been sent (unacked) or not + (unsent), seg->p->payload points to the IP header or TCP header. + Ensure we copy the first TCP data byte: */ + pbuf_copy_partial(seg->p, d, 1, seg->p->tot_len - seg->len); + } + +#if CHECKSUM_GEN_TCP + tcphdr->chksum = inet_chksum_pseudo(p, &pcb->local_ip, &pcb->remote_ip, + IP_PROTO_TCP, p->tot_len); +#endif + TCP_STATS_INC(tcp.xmit); + + /* Send output to IP */ +#if LWIP_NETIF_HWADDRHINT + ip_output_hinted(p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl, 0, IP_PROTO_TCP, + &(pcb->addr_hint)); +#else /* LWIP_NETIF_HWADDRHINT*/ + ip_output(p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl, 0, IP_PROTO_TCP); +#endif /* LWIP_NETIF_HWADDRHINT*/ + + pbuf_free(p); + + LWIP_DEBUGF(TCP_DEBUG, ("tcp_zero_window_probe: seqno %"U32_F + " ackno %"U32_F".\n", + pcb->snd_nxt - 1, pcb->rcv_nxt)); +} +#endif /* LWIP_TCP */ diff --git a/src/lwip-1.4.1/src/core/timers.c b/src/lwip-1.4.1/src/core/timers.c new file mode 100644 index 0000000..e308466 --- /dev/null +++ b/src/lwip-1.4.1/src/core/timers.c @@ -0,0 +1,487 @@ +/** + * @file + * Stack-internal timers implementation. + * This file includes timer callbacks for stack-internal timers as well as + * functions to set up or stop timers and check for expired timers. + * + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * Simon Goldschmidt + * + */ + +#include "lwip/opt.h" + +#include "lwip/timers.h" +#include "lwip/tcp_impl.h" + +#if LWIP_TIMERS + +#include "lwip/def.h" +#include "lwip/memp.h" +#include "lwip/tcpip.h" + +#include "lwip/ip_frag.h" +#include "netif/etharp.h" +#include "lwip/dhcp.h" +#include "lwip/autoip.h" +#include "lwip/igmp.h" +#include "lwip/dns.h" +#include "lwip/sys.h" +#include "lwip/pbuf.h" + + +/** The one and only timeout list */ +static struct sys_timeo *next_timeout; +#if NO_SYS +static u32_t timeouts_last_time; +#endif /* NO_SYS */ + +#if LWIP_TCP +/** global variable that shows if the tcp timer is currently scheduled or not */ +static int tcpip_tcp_timer_active; + +/** + * Timer callback function that calls tcp_tmr() and reschedules itself. + * + * @param arg unused argument + */ +static void +tcpip_tcp_timer(void *arg) +{ + LWIP_UNUSED_ARG(arg); + + /* call TCP timer handler */ + tcp_tmr(); + /* timer still needed? */ + if (tcp_active_pcbs || tcp_tw_pcbs) { + /* restart timer */ + sys_timeout(TCP_TMR_INTERVAL, tcpip_tcp_timer, NULL); + } else { + /* disable timer */ + tcpip_tcp_timer_active = 0; + } +} + +/** + * Called from TCP_REG when registering a new PCB: + * the reason is to have the TCP timer only running when + * there are active (or time-wait) PCBs. + */ +void +tcp_timer_needed(void) +{ + /* timer is off but needed again? */ + if (!tcpip_tcp_timer_active && (tcp_active_pcbs || tcp_tw_pcbs)) { + /* enable and start timer */ + tcpip_tcp_timer_active = 1; + sys_timeout(TCP_TMR_INTERVAL, tcpip_tcp_timer, NULL); + } +} +#endif /* LWIP_TCP */ + +#if IP_REASSEMBLY +/** + * Timer callback function that calls ip_reass_tmr() and reschedules itself. + * + * @param arg unused argument + */ +static void +ip_reass_timer(void *arg) +{ + LWIP_UNUSED_ARG(arg); + LWIP_DEBUGF(TIMERS_DEBUG, ("tcpip: ip_reass_tmr()\n")); + ip_reass_tmr(); + sys_timeout(IP_TMR_INTERVAL, ip_reass_timer, NULL); +} +#endif /* IP_REASSEMBLY */ + +#if LWIP_ARP +/** + * Timer callback function that calls etharp_tmr() and reschedules itself. + * + * @param arg unused argument + */ +static void +arp_timer(void *arg) +{ + LWIP_UNUSED_ARG(arg); + LWIP_DEBUGF(TIMERS_DEBUG, ("tcpip: etharp_tmr()\n")); + etharp_tmr(); + sys_timeout(ARP_TMR_INTERVAL, arp_timer, NULL); +} +#endif /* LWIP_ARP */ + +#if LWIP_DHCP +/** + * Timer callback function that calls dhcp_coarse_tmr() and reschedules itself. + * + * @param arg unused argument + */ +static void +dhcp_timer_coarse(void *arg) +{ + LWIP_UNUSED_ARG(arg); + LWIP_DEBUGF(TIMERS_DEBUG, ("tcpip: dhcp_coarse_tmr()\n")); + dhcp_coarse_tmr(); + sys_timeout(DHCP_COARSE_TIMER_MSECS, dhcp_timer_coarse, NULL); +} + +/** + * Timer callback function that calls dhcp_fine_tmr() and reschedules itself. + * + * @param arg unused argument + */ +static void +dhcp_timer_fine(void *arg) +{ + LWIP_UNUSED_ARG(arg); + LWIP_DEBUGF(TIMERS_DEBUG, ("tcpip: dhcp_fine_tmr()\n")); + dhcp_fine_tmr(); + sys_timeout(DHCP_FINE_TIMER_MSECS, dhcp_timer_fine, NULL); +} +#endif /* LWIP_DHCP */ + +#if LWIP_AUTOIP +/** + * Timer callback function that calls autoip_tmr() and reschedules itself. + * + * @param arg unused argument + */ +static void +autoip_timer(void *arg) +{ + LWIP_UNUSED_ARG(arg); + LWIP_DEBUGF(TIMERS_DEBUG, ("tcpip: autoip_tmr()\n")); + autoip_tmr(); + sys_timeout(AUTOIP_TMR_INTERVAL, autoip_timer, NULL); +} +#endif /* LWIP_AUTOIP */ + +#if LWIP_IGMP +/** + * Timer callback function that calls igmp_tmr() and reschedules itself. + * + * @param arg unused argument + */ +static void +igmp_timer(void *arg) +{ + LWIP_UNUSED_ARG(arg); + LWIP_DEBUGF(TIMERS_DEBUG, ("tcpip: igmp_tmr()\n")); + igmp_tmr(); + sys_timeout(IGMP_TMR_INTERVAL, igmp_timer, NULL); +} +#endif /* LWIP_IGMP */ + +#if LWIP_DNS +/** + * Timer callback function that calls dns_tmr() and reschedules itself. + * + * @param arg unused argument + */ +static void +dns_timer(void *arg) +{ + LWIP_UNUSED_ARG(arg); + LWIP_DEBUGF(TIMERS_DEBUG, ("tcpip: dns_tmr()\n")); + dns_tmr(); + sys_timeout(DNS_TMR_INTERVAL, dns_timer, NULL); +} +#endif /* LWIP_DNS */ + +/** Initialize this module */ +void sys_timeouts_init(void) +{ +#if IP_REASSEMBLY + sys_timeout(IP_TMR_INTERVAL, ip_reass_timer, NULL); +#endif /* IP_REASSEMBLY */ +#if LWIP_ARP + sys_timeout(ARP_TMR_INTERVAL, arp_timer, NULL); +#endif /* LWIP_ARP */ +#if LWIP_DHCP + sys_timeout(DHCP_COARSE_TIMER_MSECS, dhcp_timer_coarse, NULL); + sys_timeout(DHCP_FINE_TIMER_MSECS, dhcp_timer_fine, NULL); +#endif /* LWIP_DHCP */ +#if LWIP_AUTOIP + sys_timeout(AUTOIP_TMR_INTERVAL, autoip_timer, NULL); +#endif /* LWIP_AUTOIP */ +#if LWIP_IGMP + sys_timeout(IGMP_TMR_INTERVAL, igmp_timer, NULL); +#endif /* LWIP_IGMP */ +#if LWIP_DNS + sys_timeout(DNS_TMR_INTERVAL, dns_timer, NULL); +#endif /* LWIP_DNS */ + +#if NO_SYS + /* Initialise timestamp for sys_check_timeouts */ + timeouts_last_time = sys_now(); +#endif +} + +/** + * Create a one-shot timer (aka timeout). Timeouts are processed in the + * following cases: + * - while waiting for a message using sys_timeouts_mbox_fetch() + * - by calling sys_check_timeouts() (NO_SYS==1 only) + * + * @param msecs time in milliseconds after that the timer should expire + * @param handler callback function to call when msecs have elapsed + * @param arg argument to pass to the callback function + */ +#if LWIP_DEBUG_TIMERNAMES +void +sys_timeout_debug(u32_t msecs, sys_timeout_handler handler, void *arg, const char* handler_name) +#else /* LWIP_DEBUG_TIMERNAMES */ +void +sys_timeout(u32_t msecs, sys_timeout_handler handler, void *arg) +#endif /* LWIP_DEBUG_TIMERNAMES */ +{ + struct sys_timeo *timeout, *t; + + timeout = (struct sys_timeo *)memp_malloc(MEMP_SYS_TIMEOUT); + if (timeout == NULL) { + LWIP_ASSERT("sys_timeout: timeout != NULL, pool MEMP_SYS_TIMEOUT is empty", timeout != NULL); + return; + } + timeout->next = NULL; + timeout->h = handler; + timeout->arg = arg; + timeout->time = msecs; +#if LWIP_DEBUG_TIMERNAMES + timeout->handler_name = handler_name; + LWIP_DEBUGF(TIMERS_DEBUG, ("sys_timeout: %p msecs=%"U32_F" handler=%s arg=%p\n", + (void *)timeout, msecs, handler_name, (void *)arg)); +#endif /* LWIP_DEBUG_TIMERNAMES */ + + if (next_timeout == NULL) { + next_timeout = timeout; + return; + } + + if (next_timeout->time > msecs) { + next_timeout->time -= msecs; + timeout->next = next_timeout; + next_timeout = timeout; + } else { + for(t = next_timeout; t != NULL; t = t->next) { + timeout->time -= t->time; + if (t->next == NULL || t->next->time > timeout->time) { + if (t->next != NULL) { + t->next->time -= timeout->time; + } + timeout->next = t->next; + t->next = timeout; + break; + } + } + } +} + +/** + * Go through timeout list (for this task only) and remove the first matching + * entry, even though the timeout has not triggered yet. + * + * @note This function only works as expected if there is only one timeout + * calling 'handler' in the list of timeouts. + * + * @param handler callback function that would be called by the timeout + * @param arg callback argument that would be passed to handler +*/ +void +sys_untimeout(sys_timeout_handler handler, void *arg) +{ + struct sys_timeo *prev_t, *t; + + if (next_timeout == NULL) { + return; + } + + for (t = next_timeout, prev_t = NULL; t != NULL; prev_t = t, t = t->next) { + if ((t->h == handler) && (t->arg == arg)) { + /* We have a match */ + /* Unlink from previous in list */ + if (prev_t == NULL) { + next_timeout = t->next; + } else { + prev_t->next = t->next; + } + /* If not the last one, add time of this one back to next */ + if (t->next != NULL) { + t->next->time += t->time; + } + memp_free(MEMP_SYS_TIMEOUT, t); + return; + } + } + return; +} + +#if NO_SYS + +/** Handle timeouts for NO_SYS==1 (i.e. without using + * tcpip_thread/sys_timeouts_mbox_fetch(). Uses sys_now() to call timeout + * handler functions when timeouts expire. + * + * Must be called periodically from your main loop. + */ +void +sys_check_timeouts(void) +{ + if (next_timeout) { + struct sys_timeo *tmptimeout; + u32_t diff; + sys_timeout_handler handler; + void *arg; + u8_t had_one; + u32_t now; + + now = sys_now(); + /* this cares for wraparounds */ + diff = now - timeouts_last_time; + do + { +#if PBUF_POOL_FREE_OOSEQ + PBUF_CHECK_FREE_OOSEQ(); +#endif /* PBUF_POOL_FREE_OOSEQ */ + had_one = 0; + tmptimeout = next_timeout; + if (tmptimeout && (tmptimeout->time <= diff)) { + /* timeout has expired */ + had_one = 1; + timeouts_last_time = now; + diff -= tmptimeout->time; + next_timeout = tmptimeout->next; + handler = tmptimeout->h; + arg = tmptimeout->arg; +#if LWIP_DEBUG_TIMERNAMES + if (handler != NULL) { + LWIP_DEBUGF(TIMERS_DEBUG, ("sct calling h=%s arg=%p\n", + tmptimeout->handler_name, arg)); + } +#endif /* LWIP_DEBUG_TIMERNAMES */ + memp_free(MEMP_SYS_TIMEOUT, tmptimeout); + if (handler != NULL) { + handler(arg); + } + } + /* repeat until all expired timers have been called */ + }while(had_one); + } +} + +/** Set back the timestamp of the last call to sys_check_timeouts() + * This is necessary if sys_check_timeouts() hasn't been called for a long + * time (e.g. while saving energy) to prevent all timer functions of that + * period being called. + */ +void +sys_restart_timeouts(void) +{ + timeouts_last_time = sys_now(); +} + +#else /* NO_SYS */ + +/** + * Wait (forever) for a message to arrive in an mbox. + * While waiting, timeouts are processed. + * + * @param mbox the mbox to fetch the message from + * @param msg the place to store the message + */ +void +sys_timeouts_mbox_fetch(sys_mbox_t *mbox, void **msg) +{ + u32_t time_needed; + struct sys_timeo *tmptimeout; + sys_timeout_handler handler; + void *arg; + + again: + if (!next_timeout) { + time_needed = sys_arch_mbox_fetch(mbox, msg, 0); + } else { + if (next_timeout->time > 0) { + time_needed = sys_arch_mbox_fetch(mbox, msg, next_timeout->time); + } else { + time_needed = SYS_ARCH_TIMEOUT; + } + + if (time_needed == SYS_ARCH_TIMEOUT) { + /* If time == SYS_ARCH_TIMEOUT, a timeout occured before a message + could be fetched. We should now call the timeout handler and + deallocate the memory allocated for the timeout. */ + tmptimeout = next_timeout; + next_timeout = tmptimeout->next; + handler = tmptimeout->h; + arg = tmptimeout->arg; +#if LWIP_DEBUG_TIMERNAMES + if (handler != NULL) { + LWIP_DEBUGF(TIMERS_DEBUG, ("stmf calling h=%s arg=%p\n", + tmptimeout->handler_name, arg)); + } +#endif /* LWIP_DEBUG_TIMERNAMES */ + memp_free(MEMP_SYS_TIMEOUT, tmptimeout); + if (handler != NULL) { + /* For LWIP_TCPIP_CORE_LOCKING, lock the core before calling the + timeout handler function. */ + LOCK_TCPIP_CORE(); + handler(arg); + UNLOCK_TCPIP_CORE(); + } + LWIP_TCPIP_THREAD_ALIVE(); + + /* We try again to fetch a message from the mbox. */ + goto again; + } else { + /* If time != SYS_ARCH_TIMEOUT, a message was received before the timeout + occured. The time variable is set to the number of + milliseconds we waited for the message. */ + if (time_needed < next_timeout->time) { + next_timeout->time -= time_needed; + } else { + next_timeout->time = 0; + } + } + } +} + +#endif /* NO_SYS */ + +#else /* LWIP_TIMERS */ +/* Satisfy the TCP code which calls this function */ +void +tcp_timer_needed(void) +{ +} +#endif /* LWIP_TIMERS */ diff --git a/src/lwip-1.4.1/src/core/udp.c b/src/lwip-1.4.1/src/core/udp.c new file mode 100644 index 0000000..32c7d38 --- /dev/null +++ b/src/lwip-1.4.1/src/core/udp.c @@ -0,0 +1,1013 @@ +/** + * @file + * User Datagram Protocol module + * + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + + +/* udp.c + * + * The code for the User Datagram Protocol UDP & UDPLite (RFC 3828). + * + */ + +/* @todo Check the use of '(struct udp_pcb).chksum_len_rx'! + */ + +#include "lwip/opt.h" + +#if LWIP_UDP /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/udp.h" +#include "lwip/def.h" +#include "lwip/memp.h" +#include "lwip/inet_chksum.h" +#include "lwip/ip_addr.h" +#include "lwip/netif.h" +#include "lwip/icmp.h" +#include "lwip/stats.h" +#include "lwip/snmp.h" +#include "arch/perf.h" +#include "lwip/dhcp.h" + +#include + +#ifndef UDP_LOCAL_PORT_RANGE_START +/* From http://www.iana.org/assignments/port-numbers: + "The Dynamic and/or Private Ports are those from 49152 through 65535" */ +#define UDP_LOCAL_PORT_RANGE_START 0xc000 +#define UDP_LOCAL_PORT_RANGE_END 0xffff +#define UDP_ENSURE_LOCAL_PORT_RANGE(port) (((port) & ~UDP_LOCAL_PORT_RANGE_START) + UDP_LOCAL_PORT_RANGE_START) +#endif + +/* last local UDP port */ +static u16_t udp_port = UDP_LOCAL_PORT_RANGE_START; + +/* The list of UDP PCBs */ +/* exported in udp.h (was static) */ +struct udp_pcb *udp_pcbs; + +/** + * Initialize this module. + */ +void +udp_init(void) +{ +#if LWIP_RANDOMIZE_INITIAL_LOCAL_PORTS && defined(LWIP_RAND) + udp_port = UDP_ENSURE_LOCAL_PORT_RANGE(LWIP_RAND()); +#endif /* LWIP_RANDOMIZE_INITIAL_LOCAL_PORTS && defined(LWIP_RAND) */ +} + +/** + * Allocate a new local UDP port. + * + * @return a new (free) local UDP port number + */ +static u16_t +udp_new_port(void) +{ + u16_t n = 0; + struct udp_pcb *pcb; + +again: + if (udp_port++ == UDP_LOCAL_PORT_RANGE_END) { + udp_port = UDP_LOCAL_PORT_RANGE_START; + } + /* Check all PCBs. */ + for(pcb = udp_pcbs; pcb != NULL; pcb = pcb->next) { + if (pcb->local_port == udp_port) { + if (++n > (UDP_LOCAL_PORT_RANGE_END - UDP_LOCAL_PORT_RANGE_START)) { + return 0; + } + goto again; + } + } + return udp_port; +#if 0 + struct udp_pcb *ipcb = udp_pcbs; + while ((ipcb != NULL) && (udp_port != UDP_LOCAL_PORT_RANGE_END)) { + if (ipcb->local_port == udp_port) { + /* port is already used by another udp_pcb */ + udp_port++; + /* restart scanning all udp pcbs */ + ipcb = udp_pcbs; + } else { + /* go on with next udp pcb */ + ipcb = ipcb->next; + } + } + if (ipcb != NULL) { + return 0; + } + return udp_port; +#endif +} + +/** + * Process an incoming UDP datagram. + * + * Given an incoming UDP datagram (as a chain of pbufs) this function + * finds a corresponding UDP PCB and hands over the pbuf to the pcbs + * recv function. If no pcb is found or the datagram is incorrect, the + * pbuf is freed. + * + * @param p pbuf to be demultiplexed to a UDP PCB. + * @param inp network interface on which the datagram was received. + * + */ +void +udp_input(struct pbuf *p, struct netif *inp) +{ + struct udp_hdr *udphdr; + struct udp_pcb *pcb, *prev; + struct udp_pcb *uncon_pcb; + struct ip_hdr *iphdr; + u16_t src, dest; + u8_t local_match; + u8_t broadcast; + + PERF_START; + + UDP_STATS_INC(udp.recv); + + iphdr = (struct ip_hdr *)p->payload; + + /* Check minimum length (IP header + UDP header) + * and move payload pointer to UDP header */ + if (p->tot_len < (IPH_HL(iphdr) * 4 + UDP_HLEN) || pbuf_header(p, -(s16_t)(IPH_HL(iphdr) * 4))) { + /* drop short packets */ + LWIP_DEBUGF(UDP_DEBUG, + ("udp_input: short UDP datagram (%"U16_F" bytes) discarded\n", p->tot_len)); + UDP_STATS_INC(udp.lenerr); + UDP_STATS_INC(udp.drop); + snmp_inc_udpinerrors(); + pbuf_free(p); + goto end; + } + + udphdr = (struct udp_hdr *)p->payload; + + /* is broadcast packet ? */ + broadcast = ip_addr_isbroadcast(¤t_iphdr_dest, inp); + + LWIP_DEBUGF(UDP_DEBUG, ("udp_input: received datagram of length %"U16_F"\n", p->tot_len)); + + /* convert src and dest ports to host byte order */ + src = ntohs(udphdr->src); + dest = ntohs(udphdr->dest); + + udp_debug_print(udphdr); + + /* print the UDP source and destination */ + LWIP_DEBUGF(UDP_DEBUG, + ("udp (%"U16_F".%"U16_F".%"U16_F".%"U16_F", %"U16_F") <-- " + "(%"U16_F".%"U16_F".%"U16_F".%"U16_F", %"U16_F")\n", + ip4_addr1_16(&iphdr->dest), ip4_addr2_16(&iphdr->dest), + ip4_addr3_16(&iphdr->dest), ip4_addr4_16(&iphdr->dest), ntohs(udphdr->dest), + ip4_addr1_16(&iphdr->src), ip4_addr2_16(&iphdr->src), + ip4_addr3_16(&iphdr->src), ip4_addr4_16(&iphdr->src), ntohs(udphdr->src))); + +#if LWIP_DHCP + pcb = NULL; + /* when LWIP_DHCP is active, packets to DHCP_CLIENT_PORT may only be processed by + the dhcp module, no other UDP pcb may use the local UDP port DHCP_CLIENT_PORT */ + if (dest == DHCP_CLIENT_PORT) { + /* all packets for DHCP_CLIENT_PORT not coming from DHCP_SERVER_PORT are dropped! */ + if (src == DHCP_SERVER_PORT) { + if ((inp->dhcp != NULL) && (inp->dhcp->pcb != NULL)) { + /* accept the packe if + (- broadcast or directed to us) -> DHCP is link-layer-addressed, local ip is always ANY! + - inp->dhcp->pcb->remote == ANY or iphdr->src */ + if ((ip_addr_isany(&inp->dhcp->pcb->remote_ip) || + ip_addr_cmp(&(inp->dhcp->pcb->remote_ip), ¤t_iphdr_src))) { + pcb = inp->dhcp->pcb; + } + } + } + } else +#endif /* LWIP_DHCP */ + { + prev = NULL; + local_match = 0; + uncon_pcb = NULL; + /* Iterate through the UDP pcb list for a matching pcb. + * 'Perfect match' pcbs (connected to the remote port & ip address) are + * preferred. If no perfect match is found, the first unconnected pcb that + * matches the local port and ip address gets the datagram. */ + for (pcb = udp_pcbs; pcb != NULL; pcb = pcb->next) { + local_match = 0; + /* print the PCB local and remote address */ + LWIP_DEBUGF(UDP_DEBUG, + ("pcb (%"U16_F".%"U16_F".%"U16_F".%"U16_F", %"U16_F") --- " + "(%"U16_F".%"U16_F".%"U16_F".%"U16_F", %"U16_F")\n", + ip4_addr1_16(&pcb->local_ip), ip4_addr2_16(&pcb->local_ip), + ip4_addr3_16(&pcb->local_ip), ip4_addr4_16(&pcb->local_ip), pcb->local_port, + ip4_addr1_16(&pcb->remote_ip), ip4_addr2_16(&pcb->remote_ip), + ip4_addr3_16(&pcb->remote_ip), ip4_addr4_16(&pcb->remote_ip), pcb->remote_port)); + + /* compare PCB local addr+port to UDP destination addr+port */ + if (pcb->local_port == dest) { + if ( + (!broadcast && ip_addr_isany(&pcb->local_ip)) || + ip_addr_cmp(&(pcb->local_ip), ¤t_iphdr_dest) || +#if LWIP_IGMP + ip_addr_ismulticast(¤t_iphdr_dest) || +#endif /* LWIP_IGMP */ +#if IP_SOF_BROADCAST_RECV + (broadcast && ip_get_option(pcb, SOF_BROADCAST) && + (ip_addr_isany(&pcb->local_ip) || + ip_addr_netcmp(&pcb->local_ip, ip_current_dest_addr(), &inp->netmask)))) { +#else /* IP_SOF_BROADCAST_RECV */ + (broadcast && + (ip_addr_isany(&pcb->local_ip) || + ip_addr_netcmp(&pcb->local_ip, ip_current_dest_addr(), &inp->netmask)))) { +#endif /* IP_SOF_BROADCAST_RECV */ + local_match = 1; + if ((uncon_pcb == NULL) && + ((pcb->flags & UDP_FLAGS_CONNECTED) == 0)) { + /* the first unconnected matching PCB */ + uncon_pcb = pcb; + } + } + } + /* compare PCB remote addr+port to UDP source addr+port */ + if ((local_match != 0) && + (pcb->remote_port == src) && + (ip_addr_isany(&pcb->remote_ip) || + ip_addr_cmp(&(pcb->remote_ip), ¤t_iphdr_src))) { + /* the first fully matching PCB */ + if (prev != NULL) { + /* move the pcb to the front of udp_pcbs so that is + found faster next time */ + prev->next = pcb->next; + pcb->next = udp_pcbs; + udp_pcbs = pcb; + } else { + UDP_STATS_INC(udp.cachehit); + } + break; + } + prev = pcb; + } + /* no fully matching pcb found? then look for an unconnected pcb */ + if (pcb == NULL) { + pcb = uncon_pcb; + } + } + + /* Check checksum if this is a match or if it was directed at us. */ + if (pcb != NULL || ip_addr_cmp(&inp->ip_addr, ¤t_iphdr_dest)) { + LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, ("udp_input: calculating checksum\n")); +#if LWIP_UDPLITE + if (IPH_PROTO(iphdr) == IP_PROTO_UDPLITE) { + /* Do the UDP Lite checksum */ +#if CHECKSUM_CHECK_UDP + u16_t chklen = ntohs(udphdr->len); + if (chklen < sizeof(struct udp_hdr)) { + if (chklen == 0) { + /* For UDP-Lite, checksum length of 0 means checksum + over the complete packet (See RFC 3828 chap. 3.1) */ + chklen = p->tot_len; + } else { + /* At least the UDP-Lite header must be covered by the + checksum! (Again, see RFC 3828 chap. 3.1) */ + UDP_STATS_INC(udp.chkerr); + UDP_STATS_INC(udp.drop); + snmp_inc_udpinerrors(); + pbuf_free(p); + goto end; + } + } + if (inet_chksum_pseudo_partial(p, ¤t_iphdr_src, ¤t_iphdr_dest, + IP_PROTO_UDPLITE, p->tot_len, chklen) != 0) { + LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, + ("udp_input: UDP Lite datagram discarded due to failing checksum\n")); + UDP_STATS_INC(udp.chkerr); + UDP_STATS_INC(udp.drop); + snmp_inc_udpinerrors(); + pbuf_free(p); + goto end; + } +#endif /* CHECKSUM_CHECK_UDP */ + } else +#endif /* LWIP_UDPLITE */ + { +#if CHECKSUM_CHECK_UDP + if (udphdr->chksum != 0) { + if (inet_chksum_pseudo(p, ip_current_src_addr(), ip_current_dest_addr(), + IP_PROTO_UDP, p->tot_len) != 0) { + LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, + ("udp_input: UDP datagram discarded due to failing checksum\n")); + UDP_STATS_INC(udp.chkerr); + UDP_STATS_INC(udp.drop); + snmp_inc_udpinerrors(); + pbuf_free(p); + goto end; + } + } +#endif /* CHECKSUM_CHECK_UDP */ + } + if(pbuf_header(p, -UDP_HLEN)) { + /* Can we cope with this failing? Just assert for now */ + LWIP_ASSERT("pbuf_header failed\n", 0); + UDP_STATS_INC(udp.drop); + snmp_inc_udpinerrors(); + pbuf_free(p); + goto end; + } + if (pcb != NULL) { + snmp_inc_udpindatagrams(); +#if SO_REUSE && SO_REUSE_RXTOALL + if ((broadcast || ip_addr_ismulticast(¤t_iphdr_dest)) && + ip_get_option(pcb, SOF_REUSEADDR)) { + /* pass broadcast- or multicast packets to all multicast pcbs + if SOF_REUSEADDR is set on the first match */ + struct udp_pcb *mpcb; + u8_t p_header_changed = 0; + for (mpcb = udp_pcbs; mpcb != NULL; mpcb = mpcb->next) { + if (mpcb != pcb) { + /* compare PCB local addr+port to UDP destination addr+port */ + if ((mpcb->local_port == dest) && + ((!broadcast && ip_addr_isany(&mpcb->local_ip)) || + ip_addr_cmp(&(mpcb->local_ip), ¤t_iphdr_dest) || +#if LWIP_IGMP + ip_addr_ismulticast(¤t_iphdr_dest) || +#endif /* LWIP_IGMP */ +#if IP_SOF_BROADCAST_RECV + (broadcast && ip_get_option(mpcb, SOF_BROADCAST)))) { +#else /* IP_SOF_BROADCAST_RECV */ + (broadcast))) { +#endif /* IP_SOF_BROADCAST_RECV */ + /* pass a copy of the packet to all local matches */ + if (mpcb->recv != NULL) { + struct pbuf *q; + /* for that, move payload to IP header again */ + if (p_header_changed == 0) { + pbuf_header(p, (s16_t)((IPH_HL(iphdr) * 4) + UDP_HLEN)); + p_header_changed = 1; + } + q = pbuf_alloc(PBUF_RAW, p->tot_len, PBUF_RAM); + if (q != NULL) { + err_t err = pbuf_copy(q, p); + if (err == ERR_OK) { + /* move payload to UDP data */ + pbuf_header(q, -(s16_t)((IPH_HL(iphdr) * 4) + UDP_HLEN)); + mpcb->recv(mpcb->recv_arg, mpcb, q, ip_current_src_addr(), src); + } + } + } + } + } + } + if (p_header_changed) { + /* and move payload to UDP data again */ + pbuf_header(p, -(s16_t)((IPH_HL(iphdr) * 4) + UDP_HLEN)); + } + } +#endif /* SO_REUSE && SO_REUSE_RXTOALL */ + /* callback */ + if (pcb->recv != NULL) { + /* now the recv function is responsible for freeing p */ + pcb->recv(pcb->recv_arg, pcb, p, ip_current_src_addr(), src); + } else { + /* no recv function registered? then we have to free the pbuf! */ + pbuf_free(p); + goto end; + } + } else { + LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, ("udp_input: not for us.\n")); + +#if LWIP_ICMP + /* No match was found, send ICMP destination port unreachable unless + destination address was broadcast/multicast. */ + if (!broadcast && + !ip_addr_ismulticast(¤t_iphdr_dest)) { + /* move payload pointer back to ip header */ + pbuf_header(p, (IPH_HL(iphdr) * 4) + UDP_HLEN); + LWIP_ASSERT("p->payload == iphdr", (p->payload == iphdr)); + icmp_dest_unreach(p, ICMP_DUR_PORT); + } +#endif /* LWIP_ICMP */ + UDP_STATS_INC(udp.proterr); + UDP_STATS_INC(udp.drop); + snmp_inc_udpnoports(); + pbuf_free(p); + } + } else { + pbuf_free(p); + } +end: + PERF_STOP("udp_input"); +} + +/** + * Send data using UDP. + * + * @param pcb UDP PCB used to send the data. + * @param p chain of pbuf's to be sent. + * + * The datagram will be sent to the current remote_ip & remote_port + * stored in pcb. If the pcb is not bound to a port, it will + * automatically be bound to a random port. + * + * @return lwIP error code. + * - ERR_OK. Successful. No error occured. + * - ERR_MEM. Out of memory. + * - ERR_RTE. Could not find route to destination address. + * - More errors could be returned by lower protocol layers. + * + * @see udp_disconnect() udp_sendto() + */ +err_t +udp_send(struct udp_pcb *pcb, struct pbuf *p) +{ + /* send to the packet using remote ip and port stored in the pcb */ + return udp_sendto(pcb, p, &pcb->remote_ip, pcb->remote_port); +} + +#if LWIP_CHECKSUM_ON_COPY +/** Same as udp_send() but with checksum + */ +err_t +udp_send_chksum(struct udp_pcb *pcb, struct pbuf *p, + u8_t have_chksum, u16_t chksum) +{ + /* send to the packet using remote ip and port stored in the pcb */ + return udp_sendto_chksum(pcb, p, &pcb->remote_ip, pcb->remote_port, + have_chksum, chksum); +} +#endif /* LWIP_CHECKSUM_ON_COPY */ + +/** + * Send data to a specified address using UDP. + * + * @param pcb UDP PCB used to send the data. + * @param p chain of pbuf's to be sent. + * @param dst_ip Destination IP address. + * @param dst_port Destination UDP port. + * + * dst_ip & dst_port are expected to be in the same byte order as in the pcb. + * + * If the PCB already has a remote address association, it will + * be restored after the data is sent. + * + * @return lwIP error code (@see udp_send for possible error codes) + * + * @see udp_disconnect() udp_send() + */ +err_t +udp_sendto(struct udp_pcb *pcb, struct pbuf *p, + ip_addr_t *dst_ip, u16_t dst_port) +{ +#if LWIP_CHECKSUM_ON_COPY + return udp_sendto_chksum(pcb, p, dst_ip, dst_port, 0, 0); +} + +/** Same as udp_sendto(), but with checksum */ +err_t +udp_sendto_chksum(struct udp_pcb *pcb, struct pbuf *p, ip_addr_t *dst_ip, + u16_t dst_port, u8_t have_chksum, u16_t chksum) +{ +#endif /* LWIP_CHECKSUM_ON_COPY */ + struct netif *netif; + + LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, ("udp_send\n")); + + /* find the outgoing network interface for this packet */ +#if LWIP_IGMP + netif = ip_route((ip_addr_ismulticast(dst_ip))?(&(pcb->multicast_ip)):(dst_ip)); +#else + netif = ip_route(dst_ip); +#endif /* LWIP_IGMP */ + + /* no outgoing network interface could be found? */ + if (netif == NULL) { + LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("udp_send: No route to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", + ip4_addr1_16(dst_ip), ip4_addr2_16(dst_ip), ip4_addr3_16(dst_ip), ip4_addr4_16(dst_ip))); + UDP_STATS_INC(udp.rterr); + return ERR_RTE; + } +#if LWIP_CHECKSUM_ON_COPY + return udp_sendto_if_chksum(pcb, p, dst_ip, dst_port, netif, have_chksum, chksum); +#else /* LWIP_CHECKSUM_ON_COPY */ + return udp_sendto_if(pcb, p, dst_ip, dst_port, netif); +#endif /* LWIP_CHECKSUM_ON_COPY */ +} + +/** + * Send data to a specified address using UDP. + * The netif used for sending can be specified. + * + * This function exists mainly for DHCP, to be able to send UDP packets + * on a netif that is still down. + * + * @param pcb UDP PCB used to send the data. + * @param p chain of pbuf's to be sent. + * @param dst_ip Destination IP address. + * @param dst_port Destination UDP port. + * @param netif the netif used for sending. + * + * dst_ip & dst_port are expected to be in the same byte order as in the pcb. + * + * @return lwIP error code (@see udp_send for possible error codes) + * + * @see udp_disconnect() udp_send() + */ +err_t +udp_sendto_if(struct udp_pcb *pcb, struct pbuf *p, + ip_addr_t *dst_ip, u16_t dst_port, struct netif *netif) +{ +#if LWIP_CHECKSUM_ON_COPY + return udp_sendto_if_chksum(pcb, p, dst_ip, dst_port, netif, 0, 0); +} + +/** Same as udp_sendto_if(), but with checksum */ +err_t +udp_sendto_if_chksum(struct udp_pcb *pcb, struct pbuf *p, ip_addr_t *dst_ip, + u16_t dst_port, struct netif *netif, u8_t have_chksum, + u16_t chksum) +{ +#endif /* LWIP_CHECKSUM_ON_COPY */ + struct udp_hdr *udphdr; + ip_addr_t *src_ip; + err_t err; + struct pbuf *q; /* q will be sent down the stack */ + +#if IP_SOF_BROADCAST + /* broadcast filter? */ + if (!ip_get_option(pcb, SOF_BROADCAST) && ip_addr_isbroadcast(dst_ip, netif)) { + LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, + ("udp_sendto_if: SOF_BROADCAST not enabled on pcb %p\n", (void *)pcb)); + return ERR_VAL; + } +#endif /* IP_SOF_BROADCAST */ + + /* if the PCB is not yet bound to a port, bind it here */ + if (pcb->local_port == 0) { + LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, ("udp_send: not yet bound to a port, binding now\n")); + err = udp_bind(pcb, &pcb->local_ip, pcb->local_port); + if (err != ERR_OK) { + LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("udp_send: forced port bind failed\n")); + return err; + } + } + + /* not enough space to add an UDP header to first pbuf in given p chain? */ + if (pbuf_header(p, UDP_HLEN)) { + /* allocate header in a separate new pbuf */ + q = pbuf_alloc(PBUF_IP, UDP_HLEN, PBUF_RAM); + /* new header pbuf could not be allocated? */ + if (q == NULL) { + LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("udp_send: could not allocate header\n")); + return ERR_MEM; + } + if (p->tot_len != 0) { + /* chain header q in front of given pbuf p (only if p contains data) */ + pbuf_chain(q, p); + } + /* first pbuf q points to header pbuf */ + LWIP_DEBUGF(UDP_DEBUG, + ("udp_send: added header pbuf %p before given pbuf %p\n", (void *)q, (void *)p)); + } else { + /* adding space for header within p succeeded */ + /* first pbuf q equals given pbuf */ + q = p; + LWIP_DEBUGF(UDP_DEBUG, ("udp_send: added header in given pbuf %p\n", (void *)p)); + } + LWIP_ASSERT("check that first pbuf can hold struct udp_hdr", + (q->len >= sizeof(struct udp_hdr))); + /* q now represents the packet to be sent */ + udphdr = (struct udp_hdr *)q->payload; + udphdr->src = htons(pcb->local_port); + udphdr->dest = htons(dst_port); + /* in UDP, 0 checksum means 'no checksum' */ + udphdr->chksum = 0x0000; + + /* Multicast Loop? */ +#if LWIP_IGMP + if (ip_addr_ismulticast(dst_ip) && ((pcb->flags & UDP_FLAGS_MULTICAST_LOOP) != 0)) { + q->flags |= PBUF_FLAG_MCASTLOOP; + } +#endif /* LWIP_IGMP */ + + + /* PCB local address is IP_ANY_ADDR? */ + if (ip_addr_isany(&pcb->local_ip)) { + /* use outgoing network interface IP address as source address */ + src_ip = &(netif->ip_addr); + } else { + /* check if UDP PCB local IP address is correct + * this could be an old address if netif->ip_addr has changed */ + if (!ip_addr_cmp(&(pcb->local_ip), &(netif->ip_addr))) { + /* local_ip doesn't match, drop the packet */ + if (q != p) { + /* free the header pbuf */ + pbuf_free(q); + q = NULL; + /* p is still referenced by the caller, and will live on */ + } + return ERR_VAL; + } + /* use UDP PCB local IP address as source address */ + src_ip = &(pcb->local_ip); + } + + LWIP_DEBUGF(UDP_DEBUG, ("udp_send: sending datagram of length %"U16_F"\n", q->tot_len)); + +#if LWIP_UDPLITE + /* UDP Lite protocol? */ + if (pcb->flags & UDP_FLAGS_UDPLITE) { + u16_t chklen, chklen_hdr; + LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP LITE packet length %"U16_F"\n", q->tot_len)); + /* set UDP message length in UDP header */ + chklen_hdr = chklen = pcb->chksum_len_tx; + if ((chklen < sizeof(struct udp_hdr)) || (chklen > q->tot_len)) { + if (chklen != 0) { + LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP LITE pcb->chksum_len is illegal: %"U16_F"\n", chklen)); + } + /* For UDP-Lite, checksum length of 0 means checksum + over the complete packet. (See RFC 3828 chap. 3.1) + At least the UDP-Lite header must be covered by the + checksum, therefore, if chksum_len has an illegal + value, we generate the checksum over the complete + packet to be safe. */ + chklen_hdr = 0; + chklen = q->tot_len; + } + udphdr->len = htons(chklen_hdr); + /* calculate checksum */ +#if CHECKSUM_GEN_UDP + udphdr->chksum = inet_chksum_pseudo_partial(q, src_ip, dst_ip, + IP_PROTO_UDPLITE, q->tot_len, +#if !LWIP_CHECKSUM_ON_COPY + chklen); +#else /* !LWIP_CHECKSUM_ON_COPY */ + (have_chksum ? UDP_HLEN : chklen)); + if (have_chksum) { + u32_t acc; + acc = udphdr->chksum + (u16_t)~(chksum); + udphdr->chksum = FOLD_U32T(acc); + } +#endif /* !LWIP_CHECKSUM_ON_COPY */ + + /* chksum zero must become 0xffff, as zero means 'no checksum' */ + if (udphdr->chksum == 0x0000) { + udphdr->chksum = 0xffff; + } +#endif /* CHECKSUM_GEN_UDP */ + /* output to IP */ + LWIP_DEBUGF(UDP_DEBUG, ("udp_send: ip_output_if (,,,,IP_PROTO_UDPLITE,)\n")); + NETIF_SET_HWADDRHINT(netif, &pcb->addr_hint); + err = ip_output_if(q, src_ip, dst_ip, pcb->ttl, pcb->tos, IP_PROTO_UDPLITE, netif); + NETIF_SET_HWADDRHINT(netif, NULL); + } else +#endif /* LWIP_UDPLITE */ + { /* UDP */ + LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP packet length %"U16_F"\n", q->tot_len)); + udphdr->len = htons(q->tot_len); + /* calculate checksum */ +#if CHECKSUM_GEN_UDP + if ((pcb->flags & UDP_FLAGS_NOCHKSUM) == 0) { + u16_t udpchksum; +#if LWIP_CHECKSUM_ON_COPY + if (have_chksum) { + u32_t acc; + udpchksum = inet_chksum_pseudo_partial(q, src_ip, dst_ip, IP_PROTO_UDP, + q->tot_len, UDP_HLEN); + acc = udpchksum + (u16_t)~(chksum); + udpchksum = FOLD_U32T(acc); + } else +#endif /* LWIP_CHECKSUM_ON_COPY */ + { + udpchksum = inet_chksum_pseudo(q, src_ip, dst_ip, IP_PROTO_UDP, q->tot_len); + } + + /* chksum zero must become 0xffff, as zero means 'no checksum' */ + if (udpchksum == 0x0000) { + udpchksum = 0xffff; + } + udphdr->chksum = udpchksum; + } +#endif /* CHECKSUM_GEN_UDP */ + LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP checksum 0x%04"X16_F"\n", udphdr->chksum)); + LWIP_DEBUGF(UDP_DEBUG, ("udp_send: ip_output_if (,,,,IP_PROTO_UDP,)\n")); + /* output to IP */ + NETIF_SET_HWADDRHINT(netif, &pcb->addr_hint); + err = ip_output_if(q, src_ip, dst_ip, pcb->ttl, pcb->tos, IP_PROTO_UDP, netif); + NETIF_SET_HWADDRHINT(netif, NULL); + } + /* TODO: must this be increased even if error occured? */ + snmp_inc_udpoutdatagrams(); + + /* did we chain a separate header pbuf earlier? */ + if (q != p) { + /* free the header pbuf */ + pbuf_free(q); + q = NULL; + /* p is still referenced by the caller, and will live on */ + } + + UDP_STATS_INC(udp.xmit); + return err; +} + +/** + * Bind an UDP PCB. + * + * @param pcb UDP PCB to be bound with a local address ipaddr and port. + * @param ipaddr local IP address to bind with. Use IP_ADDR_ANY to + * bind to all local interfaces. + * @param port local UDP port to bind with. Use 0 to automatically bind + * to a random port between UDP_LOCAL_PORT_RANGE_START and + * UDP_LOCAL_PORT_RANGE_END. + * + * ipaddr & port are expected to be in the same byte order as in the pcb. + * + * @return lwIP error code. + * - ERR_OK. Successful. No error occured. + * - ERR_USE. The specified ipaddr and port are already bound to by + * another UDP PCB. + * + * @see udp_disconnect() + */ +err_t +udp_bind(struct udp_pcb *pcb, ip_addr_t *ipaddr, u16_t port) +{ + struct udp_pcb *ipcb; + u8_t rebind; + + LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, ("udp_bind(ipaddr = ")); + ip_addr_debug_print(UDP_DEBUG, ipaddr); + LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, (", port = %"U16_F")\n", port)); + + rebind = 0; + /* Check for double bind and rebind of the same pcb */ + for (ipcb = udp_pcbs; ipcb != NULL; ipcb = ipcb->next) { + /* is this UDP PCB already on active list? */ + if (pcb == ipcb) { + /* pcb may occur at most once in active list */ + LWIP_ASSERT("rebind == 0", rebind == 0); + /* pcb already in list, just rebind */ + rebind = 1; + } + + /* By default, we don't allow to bind to a port that any other udp + PCB is alread bound to, unless *all* PCBs with that port have tha + REUSEADDR flag set. */ +#if SO_REUSE + else if (!ip_get_option(pcb, SOF_REUSEADDR) && + !ip_get_option(ipcb, SOF_REUSEADDR)) { +#else /* SO_REUSE */ + /* port matches that of PCB in list and REUSEADDR not set -> reject */ + else { +#endif /* SO_REUSE */ + if ((ipcb->local_port == port) && + /* IP address matches, or one is IP_ADDR_ANY? */ + (ip_addr_isany(&(ipcb->local_ip)) || + ip_addr_isany(ipaddr) || + ip_addr_cmp(&(ipcb->local_ip), ipaddr))) { + /* other PCB already binds to this local IP and port */ + LWIP_DEBUGF(UDP_DEBUG, + ("udp_bind: local port %"U16_F" already bound by another pcb\n", port)); + return ERR_USE; + } + } + } + + ip_addr_set(&pcb->local_ip, ipaddr); + + /* no port specified? */ + if (port == 0) { + port = udp_new_port(); + if (port == 0) { + /* no more ports available in local range */ + LWIP_DEBUGF(UDP_DEBUG, ("udp_bind: out of free UDP ports\n")); + return ERR_USE; + } + } + pcb->local_port = port; + snmp_insert_udpidx_tree(pcb); + /* pcb not active yet? */ + if (rebind == 0) { + /* place the PCB on the active list if not already there */ + pcb->next = udp_pcbs; + udp_pcbs = pcb; + } + LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, + ("udp_bind: bound to %"U16_F".%"U16_F".%"U16_F".%"U16_F", port %"U16_F"\n", + ip4_addr1_16(&pcb->local_ip), ip4_addr2_16(&pcb->local_ip), + ip4_addr3_16(&pcb->local_ip), ip4_addr4_16(&pcb->local_ip), + pcb->local_port)); + return ERR_OK; +} +/** + * Connect an UDP PCB. + * + * This will associate the UDP PCB with the remote address. + * + * @param pcb UDP PCB to be connected with remote address ipaddr and port. + * @param ipaddr remote IP address to connect with. + * @param port remote UDP port to connect with. + * + * @return lwIP error code + * + * ipaddr & port are expected to be in the same byte order as in the pcb. + * + * The udp pcb is bound to a random local port if not already bound. + * + * @see udp_disconnect() + */ +err_t +udp_connect(struct udp_pcb *pcb, ip_addr_t *ipaddr, u16_t port) +{ + struct udp_pcb *ipcb; + + if (pcb->local_port == 0) { + err_t err = udp_bind(pcb, &pcb->local_ip, pcb->local_port); + if (err != ERR_OK) { + return err; + } + } + + ip_addr_set(&pcb->remote_ip, ipaddr); + pcb->remote_port = port; + pcb->flags |= UDP_FLAGS_CONNECTED; +/** TODO: this functionality belongs in upper layers */ +#ifdef LWIP_UDP_TODO + /* Nail down local IP for netconn_addr()/getsockname() */ + if (ip_addr_isany(&pcb->local_ip) && !ip_addr_isany(&pcb->remote_ip)) { + struct netif *netif; + + if ((netif = ip_route(&(pcb->remote_ip))) == NULL) { + LWIP_DEBUGF(UDP_DEBUG, ("udp_connect: No route to 0x%lx\n", pcb->remote_ip.addr)); + UDP_STATS_INC(udp.rterr); + return ERR_RTE; + } + /** TODO: this will bind the udp pcb locally, to the interface which + is used to route output packets to the remote address. However, we + might want to accept incoming packets on any interface! */ + pcb->local_ip = netif->ip_addr; + } else if (ip_addr_isany(&pcb->remote_ip)) { + pcb->local_ip.addr = 0; + } +#endif + LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, + ("udp_connect: connected to %"U16_F".%"U16_F".%"U16_F".%"U16_F",port %"U16_F"\n", + ip4_addr1_16(&pcb->local_ip), ip4_addr2_16(&pcb->local_ip), + ip4_addr3_16(&pcb->local_ip), ip4_addr4_16(&pcb->local_ip), + pcb->local_port)); + + /* Insert UDP PCB into the list of active UDP PCBs. */ + for (ipcb = udp_pcbs; ipcb != NULL; ipcb = ipcb->next) { + if (pcb == ipcb) { + /* already on the list, just return */ + return ERR_OK; + } + } + /* PCB not yet on the list, add PCB now */ + pcb->next = udp_pcbs; + udp_pcbs = pcb; + return ERR_OK; +} + +/** + * Disconnect a UDP PCB + * + * @param pcb the udp pcb to disconnect. + */ +void +udp_disconnect(struct udp_pcb *pcb) +{ + /* reset remote address association */ + ip_addr_set_any(&pcb->remote_ip); + pcb->remote_port = 0; + /* mark PCB as unconnected */ + pcb->flags &= ~UDP_FLAGS_CONNECTED; +} + +/** + * Set a receive callback for a UDP PCB + * + * This callback will be called when receiving a datagram for the pcb. + * + * @param pcb the pcb for wich to set the recv callback + * @param recv function pointer of the callback function + * @param recv_arg additional argument to pass to the callback function + */ +void +udp_recv(struct udp_pcb *pcb, udp_recv_fn recv, void *recv_arg) +{ + /* remember recv() callback and user data */ + pcb->recv = recv; + pcb->recv_arg = recv_arg; +} + +/** + * Remove an UDP PCB. + * + * @param pcb UDP PCB to be removed. The PCB is removed from the list of + * UDP PCB's and the data structure is freed from memory. + * + * @see udp_new() + */ +void +udp_remove(struct udp_pcb *pcb) +{ + struct udp_pcb *pcb2; + + snmp_delete_udpidx_tree(pcb); + /* pcb to be removed is first in list? */ + if (udp_pcbs == pcb) { + /* make list start at 2nd pcb */ + udp_pcbs = udp_pcbs->next; + /* pcb not 1st in list */ + } else { + for (pcb2 = udp_pcbs; pcb2 != NULL; pcb2 = pcb2->next) { + /* find pcb in udp_pcbs list */ + if (pcb2->next != NULL && pcb2->next == pcb) { + /* remove pcb from list */ + pcb2->next = pcb->next; + } + } + } + memp_free(MEMP_UDP_PCB, pcb); +} + +/** + * Create a UDP PCB. + * + * @return The UDP PCB which was created. NULL if the PCB data structure + * could not be allocated. + * + * @see udp_remove() + */ +struct udp_pcb * +udp_new(void) +{ + struct udp_pcb *pcb; + pcb = (struct udp_pcb *)memp_malloc(MEMP_UDP_PCB); + /* could allocate UDP PCB? */ + if (pcb != NULL) { + /* UDP Lite: by initializing to all zeroes, chksum_len is set to 0 + * which means checksum is generated over the whole datagram per default + * (recommended as default by RFC 3828). */ + /* initialize PCB to all zeroes */ + memset(pcb, 0, sizeof(struct udp_pcb)); + pcb->ttl = UDP_TTL; + } + return pcb; +} + +#if UDP_DEBUG +/** + * Print UDP header information for debug purposes. + * + * @param udphdr pointer to the udp header in memory. + */ +void +udp_debug_print(struct udp_hdr *udphdr) +{ + LWIP_DEBUGF(UDP_DEBUG, ("UDP header:\n")); + LWIP_DEBUGF(UDP_DEBUG, ("+-------------------------------+\n")); + LWIP_DEBUGF(UDP_DEBUG, ("| %5"U16_F" | %5"U16_F" | (src port, dest port)\n", + ntohs(udphdr->src), ntohs(udphdr->dest))); + LWIP_DEBUGF(UDP_DEBUG, ("+-------------------------------+\n")); + LWIP_DEBUGF(UDP_DEBUG, ("| %5"U16_F" | 0x%04"X16_F" | (len, chksum)\n", + ntohs(udphdr->len), ntohs(udphdr->chksum))); + LWIP_DEBUGF(UDP_DEBUG, ("+-------------------------------+\n")); +} +#endif /* UDP_DEBUG */ + +#endif /* LWIP_UDP */ diff --git a/src/lwip-1.4.1/src/include/arch/cc.h b/src/lwip-1.4.1/src/include/arch/cc.h new file mode 100644 index 0000000..5d3970e --- /dev/null +++ b/src/lwip-1.4.1/src/include/arch/cc.h @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2001-2003 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __CC_H__ +#define __CC_H__ + +#include "cpu.h" + +typedef unsigned char u8_t; +typedef signed char s8_t; +typedef unsigned short u16_t; +typedef signed short s16_t; +typedef unsigned long u32_t; +typedef signed long s32_t; +typedef u32_t mem_ptr_t; +/* typedef int sys_prot_t; */ + + + +/* define compiler specific symbols */ +#if defined (__ICCARM__) + +#define PACK_STRUCT_BEGIN +#define PACK_STRUCT_STRUCT +#define PACK_STRUCT_END +#define PACK_STRUCT_FIELD(x) x +#define PACK_STRUCT_USE_INCLUDES + +#elif defined (__CC_ARM) + +#define PACK_STRUCT_BEGIN __packed +#define PACK_STRUCT_STRUCT +#define PACK_STRUCT_END +#define PACK_STRUCT_FIELD(x) x + +#elif defined (__GNUC__) + +#define PACK_STRUCT_BEGIN +#define PACK_STRUCT_STRUCT __attribute__ ((__packed__)) +#define PACK_STRUCT_END +#define PACK_STRUCT_FIELD(x) x + +#elif defined (__TASKING__) + +#define PACK_STRUCT_BEGIN +#define PACK_STRUCT_STRUCT +#define PACK_STRUCT_END +#define PACK_STRUCT_FIELD(x) x + +#endif + +#define LWIP_PLATFORM_ASSERT(x) do { if(!(x)) while(1); } while(0) + +#endif /* __CC_H__ */ diff --git a/src/lwip-1.4.1/src/include/arch/cpu.h b/src/lwip-1.4.1/src/include/arch/cpu.h new file mode 100644 index 0000000..0d7115b --- /dev/null +++ b/src/lwip-1.4.1/src/include/arch/cpu.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2001-2003 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __CPU_H__ +#define __CPU_H__ +#ifdef BYTE_ORDER +#undef BYTE_ORDER +#endif +#define BYTE_ORDER LITTLE_ENDIAN + +#endif /* __CPU_H__ */ diff --git a/src/lwip-1.4.1/src/include/arch/perf.h b/src/lwip-1.4.1/src/include/arch/perf.h new file mode 100644 index 0000000..334d42a --- /dev/null +++ b/src/lwip-1.4.1/src/include/arch/perf.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2001-2003 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __PERF_H__ +#define __PERF_H__ + +#define PERF_START /* null definition */ +#define PERF_STOP(x) /* null definition */ + +#endif /* __PERF_H__ */ diff --git a/src/lwip-1.4.1/src/include/ipv4/lwip/autoip.h b/src/lwip-1.4.1/src/include/ipv4/lwip/autoip.h new file mode 100644 index 0000000..e62b72e --- /dev/null +++ b/src/lwip-1.4.1/src/include/ipv4/lwip/autoip.h @@ -0,0 +1,118 @@ +/** + * @file + * + * AutoIP Automatic LinkLocal IP Configuration + */ + +/* + * + * Copyright (c) 2007 Dominik Spies + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * Author: Dominik Spies + * + * This is a AutoIP implementation for the lwIP TCP/IP stack. It aims to conform + * with RFC 3927. + * + * + * Please coordinate changes and requests with Dominik Spies + * + */ + +#ifndef __LWIP_AUTOIP_H__ +#define __LWIP_AUTOIP_H__ + +#include "lwip/opt.h" + +#if LWIP_AUTOIP /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/netif.h" +#include "lwip/udp.h" +#include "netif/etharp.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* AutoIP Timing */ +#define AUTOIP_TMR_INTERVAL 100 +#define AUTOIP_TICKS_PER_SECOND (1000 / AUTOIP_TMR_INTERVAL) + +/* RFC 3927 Constants */ +#define PROBE_WAIT 1 /* second (initial random delay) */ +#define PROBE_MIN 1 /* second (minimum delay till repeated probe) */ +#define PROBE_MAX 2 /* seconds (maximum delay till repeated probe) */ +#define PROBE_NUM 3 /* (number of probe packets) */ +#define ANNOUNCE_NUM 2 /* (number of announcement packets) */ +#define ANNOUNCE_INTERVAL 2 /* seconds (time between announcement packets) */ +#define ANNOUNCE_WAIT 2 /* seconds (delay before announcing) */ +#define MAX_CONFLICTS 10 /* (max conflicts before rate limiting) */ +#define RATE_LIMIT_INTERVAL 60 /* seconds (delay between successive attempts) */ +#define DEFEND_INTERVAL 10 /* seconds (min. wait between defensive ARPs) */ + +/* AutoIP client states */ +#define AUTOIP_STATE_OFF 0 +#define AUTOIP_STATE_PROBING 1 +#define AUTOIP_STATE_ANNOUNCING 2 +#define AUTOIP_STATE_BOUND 3 + +struct autoip +{ + ip_addr_t llipaddr; /* the currently selected, probed, announced or used LL IP-Address */ + u8_t state; /* current AutoIP state machine state */ + u8_t sent_num; /* sent number of probes or announces, dependent on state */ + u16_t ttw; /* ticks to wait, tick is AUTOIP_TMR_INTERVAL long */ + u8_t lastconflict; /* ticks until a conflict can be solved by defending */ + u8_t tried_llipaddr; /* total number of probed/used Link Local IP-Addresses */ +}; + + +#define autoip_init() /* Compatibility define, no init needed. */ + +/** Set a struct autoip allocated by the application to work with */ +void autoip_set_struct(struct netif *netif, struct autoip *autoip); + +/** Start AutoIP client */ +err_t autoip_start(struct netif *netif); + +/** Stop AutoIP client */ +err_t autoip_stop(struct netif *netif); + +/** Handles every incoming ARP Packet, called by etharp_arp_input */ +void autoip_arp_reply(struct netif *netif, struct etharp_hdr *hdr); + +/** Has to be called in loop every AUTOIP_TMR_INTERVAL milliseconds */ +void autoip_tmr(void); + +/** Handle a possible change in the network configuration */ +void autoip_network_changed(struct netif *netif); + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_AUTOIP */ + +#endif /* __LWIP_AUTOIP_H__ */ diff --git a/src/lwip-1.4.1/src/include/ipv4/lwip/icmp.h b/src/lwip-1.4.1/src/include/ipv4/lwip/icmp.h new file mode 100644 index 0000000..d47a7d8 --- /dev/null +++ b/src/lwip-1.4.1/src/include/ipv4/lwip/icmp.h @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __LWIP_ICMP_H__ +#define __LWIP_ICMP_H__ + +#include "lwip/opt.h" +#include "lwip/pbuf.h" +#include "lwip/ip_addr.h" +#include "lwip/netif.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define ICMP_ER 0 /* echo reply */ +#define ICMP_DUR 3 /* destination unreachable */ +#define ICMP_SQ 4 /* source quench */ +#define ICMP_RD 5 /* redirect */ +#define ICMP_ECHO 8 /* echo */ +#define ICMP_TE 11 /* time exceeded */ +#define ICMP_PP 12 /* parameter problem */ +#define ICMP_TS 13 /* timestamp */ +#define ICMP_TSR 14 /* timestamp reply */ +#define ICMP_IRQ 15 /* information request */ +#define ICMP_IR 16 /* information reply */ + +enum icmp_dur_type { + ICMP_DUR_NET = 0, /* net unreachable */ + ICMP_DUR_HOST = 1, /* host unreachable */ + ICMP_DUR_PROTO = 2, /* protocol unreachable */ + ICMP_DUR_PORT = 3, /* port unreachable */ + ICMP_DUR_FRAG = 4, /* fragmentation needed and DF set */ + ICMP_DUR_SR = 5 /* source route failed */ +}; + +enum icmp_te_type { + ICMP_TE_TTL = 0, /* time to live exceeded in transit */ + ICMP_TE_FRAG = 1 /* fragment reassembly time exceeded */ +}; + +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +/** This is the standard ICMP header only that the u32_t data + * is splitted to two u16_t like ICMP echo needs it. + * This header is also used for other ICMP types that do not + * use the data part. + */ +PACK_STRUCT_BEGIN +struct icmp_echo_hdr { + PACK_STRUCT_FIELD(u8_t type); + PACK_STRUCT_FIELD(u8_t code); + PACK_STRUCT_FIELD(u16_t chksum); + PACK_STRUCT_FIELD(u16_t id); + PACK_STRUCT_FIELD(u16_t seqno); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +#define ICMPH_TYPE(hdr) ((hdr)->type) +#define ICMPH_CODE(hdr) ((hdr)->code) + +/** Combines type and code to an u16_t */ +#define ICMPH_TYPE_SET(hdr, t) ((hdr)->type = (t)) +#define ICMPH_CODE_SET(hdr, c) ((hdr)->code = (c)) + + +#if LWIP_ICMP /* don't build if not configured for use in lwipopts.h */ + +void icmp_input(struct pbuf *p, struct netif *inp); +void icmp_dest_unreach(struct pbuf *p, enum icmp_dur_type t); +void icmp_time_exceeded(struct pbuf *p, enum icmp_te_type t); + +#endif /* LWIP_ICMP */ + +#ifdef __cplusplus +} +#endif + +#endif /* __LWIP_ICMP_H__ */ diff --git a/src/lwip-1.4.1/src/include/ipv4/lwip/igmp.h b/src/lwip-1.4.1/src/include/ipv4/lwip/igmp.h new file mode 100644 index 0000000..8aabac2 --- /dev/null +++ b/src/lwip-1.4.1/src/include/ipv4/lwip/igmp.h @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2002 CITEL Technologies Ltd. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of CITEL Technologies Ltd nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY CITEL TECHNOLOGIES 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 CITEL TECHNOLOGIES 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. + * + * This file is a contribution to the lwIP TCP/IP stack. + * The Swedish Institute of Computer Science and Adam Dunkels + * are specifically granted permission to redistribute this + * source code. +*/ + +#ifndef __LWIP_IGMP_H__ +#define __LWIP_IGMP_H__ + +#include "lwip/opt.h" +#include "lwip/ip_addr.h" +#include "lwip/netif.h" +#include "lwip/pbuf.h" + +#if LWIP_IGMP /* don't build if not configured for use in lwipopts.h */ + +#ifdef __cplusplus +extern "C" { +#endif + + +/* IGMP timer */ +#define IGMP_TMR_INTERVAL 100 /* Milliseconds */ +#define IGMP_V1_DELAYING_MEMBER_TMR (1000/IGMP_TMR_INTERVAL) +#define IGMP_JOIN_DELAYING_MEMBER_TMR (500 /IGMP_TMR_INTERVAL) + +/* MAC Filter Actions, these are passed to a netif's + * igmp_mac_filter callback function. */ +#define IGMP_DEL_MAC_FILTER 0 +#define IGMP_ADD_MAC_FILTER 1 + + +/** + * igmp group structure - there is + * a list of groups for each interface + * these should really be linked from the interface, but + * if we keep them separate we will not affect the lwip original code + * too much + * + * There will be a group for the all systems group address but this + * will not run the state machine as it is used to kick off reports + * from all the other groups + */ +struct igmp_group { + /** next link */ + struct igmp_group *next; + /** interface on which the group is active */ + struct netif *netif; + /** multicast address */ + ip_addr_t group_address; + /** signifies we were the last person to report */ + u8_t last_reporter_flag; + /** current state of the group */ + u8_t group_state; + /** timer for reporting, negative is OFF */ + u16_t timer; + /** counter of simultaneous uses */ + u8_t use; +}; + +/* Prototypes */ +void igmp_init(void); +err_t igmp_start(struct netif *netif); +err_t igmp_stop(struct netif *netif); +void igmp_report_groups(struct netif *netif); +struct igmp_group *igmp_lookfor_group(struct netif *ifp, ip_addr_t *addr); +void igmp_input(struct pbuf *p, struct netif *inp, ip_addr_t *dest); +err_t igmp_joingroup(ip_addr_t *ifaddr, ip_addr_t *groupaddr); +err_t igmp_leavegroup(ip_addr_t *ifaddr, ip_addr_t *groupaddr); +void igmp_tmr(void); + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_IGMP */ + +#endif /* __LWIP_IGMP_H__ */ diff --git a/src/lwip-1.4.1/src/include/ipv4/lwip/inet.h b/src/lwip-1.4.1/src/include/ipv4/lwip/inet.h new file mode 100644 index 0000000..7bff49b --- /dev/null +++ b/src/lwip-1.4.1/src/include/ipv4/lwip/inet.h @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __LWIP_INET_H__ +#define __LWIP_INET_H__ + +#include "lwip/opt.h" +#include "lwip/def.h" +#include "lwip/ip_addr.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** For compatibility with BSD code */ +struct in_addr { + u32_t s_addr; +}; + +/** 255.255.255.255 */ +#define INADDR_NONE IPADDR_NONE +/** 127.0.0.1 */ +#define INADDR_LOOPBACK IPADDR_LOOPBACK +/** 0.0.0.0 */ +#define INADDR_ANY IPADDR_ANY +/** 255.255.255.255 */ +#define INADDR_BROADCAST IPADDR_BROADCAST + +/* Definitions of the bits in an Internet address integer. + + On subnets, host and network parts are found according to + the subnet mask, not these masks. */ +#define IN_CLASSA(a) IP_CLASSA(a) +#define IN_CLASSA_NET IP_CLASSA_NET +#define IN_CLASSA_NSHIFT IP_CLASSA_NSHIFT +#define IN_CLASSA_HOST IP_CLASSA_HOST +#define IN_CLASSA_MAX IP_CLASSA_MAX + +#define IN_CLASSB(b) IP_CLASSB(b) +#define IN_CLASSB_NET IP_CLASSB_NET +#define IN_CLASSB_NSHIFT IP_CLASSB_NSHIFT +#define IN_CLASSB_HOST IP_CLASSB_HOST +#define IN_CLASSB_MAX IP_CLASSB_MAX + +#define IN_CLASSC(c) IP_CLASSC(c) +#define IN_CLASSC_NET IP_CLASSC_NET +#define IN_CLASSC_NSHIFT IP_CLASSC_NSHIFT +#define IN_CLASSC_HOST IP_CLASSC_HOST +#define IN_CLASSC_MAX IP_CLASSC_MAX + +#define IN_CLASSD(d) IP_CLASSD(d) +#define IN_CLASSD_NET IP_CLASSD_NET /* These ones aren't really */ +#define IN_CLASSD_NSHIFT IP_CLASSD_NSHIFT /* net and host fields, but */ +#define IN_CLASSD_HOST IP_CLASSD_HOST /* routing needn't know. */ +#define IN_CLASSD_MAX IP_CLASSD_MAX + +#define IN_MULTICAST(a) IP_MULTICAST(a) + +#define IN_EXPERIMENTAL(a) IP_EXPERIMENTAL(a) +#define IN_BADCLASS(a) IP_BADCLASS(a) + +#define IN_LOOPBACKNET IP_LOOPBACKNET + +#define inet_addr_from_ipaddr(target_inaddr, source_ipaddr) ((target_inaddr)->s_addr = ip4_addr_get_u32(source_ipaddr)) +#define inet_addr_to_ipaddr(target_ipaddr, source_inaddr) (ip4_addr_set_u32(target_ipaddr, (source_inaddr)->s_addr)) +/* ATTENTION: the next define only works because both s_addr and ip_addr_t are an u32_t effectively! */ +#define inet_addr_to_ipaddr_p(target_ipaddr_p, source_inaddr) ((target_ipaddr_p) = (ip_addr_t*)&((source_inaddr)->s_addr)) + +/* directly map this to the lwip internal functions */ +#define inet_addr(cp) ipaddr_addr(cp) +#define inet_aton(cp, addr) ipaddr_aton(cp, (ip_addr_t*)addr) +#define inet_ntoa(addr) ipaddr_ntoa((ip_addr_t*)&(addr)) +#define inet_ntoa_r(addr, buf, buflen) ipaddr_ntoa_r((ip_addr_t*)&(addr), buf, buflen) + +#ifdef __cplusplus +} +#endif + +#endif /* __LWIP_INET_H__ */ diff --git a/src/lwip-1.4.1/src/include/ipv4/lwip/inet_chksum.h b/src/lwip-1.4.1/src/include/ipv4/lwip/inet_chksum.h new file mode 100644 index 0000000..79a2d90 --- /dev/null +++ b/src/lwip-1.4.1/src/include/ipv4/lwip/inet_chksum.h @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __LWIP_INET_CHKSUM_H__ +#define __LWIP_INET_CHKSUM_H__ + +#include "lwip/opt.h" + +#include "lwip/pbuf.h" +#include "lwip/ip_addr.h" + +/** Swap the bytes in an u16_t: much like htons() for little-endian */ +#ifndef SWAP_BYTES_IN_WORD +#if LWIP_PLATFORM_BYTESWAP && (BYTE_ORDER == LITTLE_ENDIAN) +/* little endian and PLATFORM_BYTESWAP defined */ +#define SWAP_BYTES_IN_WORD(w) LWIP_PLATFORM_HTONS(w) +#else /* LWIP_PLATFORM_BYTESWAP && (BYTE_ORDER == LITTLE_ENDIAN) */ +/* can't use htons on big endian (or PLATFORM_BYTESWAP not defined)... */ +#define SWAP_BYTES_IN_WORD(w) (((w) & 0xff) << 8) | (((w) & 0xff00) >> 8) +#endif /* LWIP_PLATFORM_BYTESWAP && (BYTE_ORDER == LITTLE_ENDIAN)*/ +#endif /* SWAP_BYTES_IN_WORD */ + +/** Split an u32_t in two u16_ts and add them up */ +#ifndef FOLD_U32T +#define FOLD_U32T(u) (((u) >> 16) + ((u) & 0x0000ffffUL)) +#endif + +#if LWIP_CHECKSUM_ON_COPY +/** Function-like macro: same as MEMCPY but returns the checksum of copied data + as u16_t */ +#ifndef LWIP_CHKSUM_COPY +#define LWIP_CHKSUM_COPY(dst, src, len) lwip_chksum_copy(dst, src, len) +#ifndef LWIP_CHKSUM_COPY_ALGORITHM +#define LWIP_CHKSUM_COPY_ALGORITHM 1 +#endif /* LWIP_CHKSUM_COPY_ALGORITHM */ +#endif /* LWIP_CHKSUM_COPY */ +#else /* LWIP_CHECKSUM_ON_COPY */ +#define LWIP_CHKSUM_COPY_ALGORITHM 0 +#endif /* LWIP_CHECKSUM_ON_COPY */ + +#ifdef __cplusplus +extern "C" { +#endif + +u16_t inet_chksum(void *dataptr, u16_t len); +u16_t inet_chksum_pbuf(struct pbuf *p); +u16_t inet_chksum_pseudo(struct pbuf *p, + ip_addr_t *src, ip_addr_t *dest, + u8_t proto, u16_t proto_len); +u16_t inet_chksum_pseudo_partial(struct pbuf *p, + ip_addr_t *src, ip_addr_t *dest, + u8_t proto, u16_t proto_len, u16_t chksum_len); +#if LWIP_CHKSUM_COPY_ALGORITHM +u16_t lwip_chksum_copy(void *dst, const void *src, u16_t len); +#endif /* LWIP_CHKSUM_COPY_ALGORITHM */ + +#ifdef __cplusplus +} +#endif + +#endif /* __LWIP_INET_H__ */ + diff --git a/src/lwip-1.4.1/src/include/ipv4/lwip/ip.h b/src/lwip-1.4.1/src/include/ipv4/lwip/ip.h new file mode 100644 index 0000000..00c83a0 --- /dev/null +++ b/src/lwip-1.4.1/src/include/ipv4/lwip/ip.h @@ -0,0 +1,223 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __LWIP_IP_H__ +#define __LWIP_IP_H__ + +#include "lwip/opt.h" + +#include "lwip/def.h" +#include "lwip/pbuf.h" +#include "lwip/ip_addr.h" +#include "lwip/err.h" +#include "lwip/netif.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** Currently, the function ip_output_if_opt() is only used with IGMP */ +#define IP_OPTIONS_SEND LWIP_IGMP + +#define IP_HLEN 20 + +#define IP_PROTO_ICMP 1 +#define IP_PROTO_IGMP 2 +#define IP_PROTO_UDP 17 +#define IP_PROTO_UDPLITE 136 +#define IP_PROTO_TCP 6 + +/* This is passed as the destination address to ip_output_if (not + to ip_output), meaning that an IP header already is constructed + in the pbuf. This is used when TCP retransmits. */ +#ifdef IP_HDRINCL +#undef IP_HDRINCL +#endif /* IP_HDRINCL */ +#define IP_HDRINCL NULL + +#if LWIP_NETIF_HWADDRHINT +#define IP_PCB_ADDRHINT ;u8_t addr_hint +#else +#define IP_PCB_ADDRHINT +#endif /* LWIP_NETIF_HWADDRHINT */ + +/* This is the common part of all PCB types. It needs to be at the + beginning of a PCB type definition. It is located here so that + changes to this common part are made in one location instead of + having to change all PCB structs. */ +#define IP_PCB \ + /* ip addresses in network byte order */ \ + ip_addr_t local_ip; \ + ip_addr_t remote_ip; \ + /* Socket options */ \ + u8_t so_options; \ + /* Type Of Service */ \ + u8_t tos; \ + /* Time To Live */ \ + u8_t ttl \ + /* link layer address resolution hint */ \ + IP_PCB_ADDRHINT + +struct ip_pcb { +/* Common members of all PCB types */ + IP_PCB; +}; + +/* + * Option flags per-socket. These are the same like SO_XXX. + */ +/*#define SOF_DEBUG 0x01U Unimplemented: turn on debugging info recording */ +#define SOF_ACCEPTCONN 0x02U /* socket has had listen() */ +#define SOF_REUSEADDR 0x04U /* allow local address reuse */ +#define SOF_KEEPALIVE 0x08U /* keep connections alive */ +/*#define SOF_DONTROUTE 0x10U Unimplemented: just use interface addresses */ +#define SOF_BROADCAST 0x20U /* permit to send and to receive broadcast messages (see IP_SOF_BROADCAST option) */ +/*#define SOF_USELOOPBACK 0x40U Unimplemented: bypass hardware when possible */ +#define SOF_LINGER 0x80U /* linger on close if data present */ +/*#define SOF_OOBINLINE 0x0100U Unimplemented: leave received OOB data in line */ +/*#define SOF_REUSEPORT 0x0200U Unimplemented: allow local address & port reuse */ + +/* These flags are inherited (e.g. from a listen-pcb to a connection-pcb): */ +#define SOF_INHERITED (SOF_REUSEADDR|SOF_KEEPALIVE|SOF_LINGER/*|SOF_DEBUG|SOF_DONTROUTE|SOF_OOBINLINE*/) + + +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct ip_hdr { + /* version / header length */ + PACK_STRUCT_FIELD(u8_t _v_hl); + /* type of service */ + PACK_STRUCT_FIELD(u8_t _tos); + /* total length */ + PACK_STRUCT_FIELD(u16_t _len); + /* identification */ + PACK_STRUCT_FIELD(u16_t _id); + /* fragment offset field */ + PACK_STRUCT_FIELD(u16_t _offset); +#define IP_RF 0x8000U /* reserved fragment flag */ +#define IP_DF 0x4000U /* dont fragment flag */ +#define IP_MF 0x2000U /* more fragments flag */ +#define IP_OFFMASK 0x1fffU /* mask for fragmenting bits */ + /* time to live */ + PACK_STRUCT_FIELD(u8_t _ttl); + /* protocol*/ + PACK_STRUCT_FIELD(u8_t _proto); + /* checksum */ + PACK_STRUCT_FIELD(u16_t _chksum); + /* source and destination IP addresses */ + PACK_STRUCT_FIELD(ip_addr_p_t src); + PACK_STRUCT_FIELD(ip_addr_p_t dest); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +#define IPH_V(hdr) ((hdr)->_v_hl >> 4) +#define IPH_HL(hdr) ((hdr)->_v_hl & 0x0f) +#define IPH_TOS(hdr) ((hdr)->_tos) +#define IPH_LEN(hdr) ((hdr)->_len) +#define IPH_ID(hdr) ((hdr)->_id) +#define IPH_OFFSET(hdr) ((hdr)->_offset) +#define IPH_TTL(hdr) ((hdr)->_ttl) +#define IPH_PROTO(hdr) ((hdr)->_proto) +#define IPH_CHKSUM(hdr) ((hdr)->_chksum) + +#define IPH_VHL_SET(hdr, v, hl) (hdr)->_v_hl = (((v) << 4) | (hl)) +#define IPH_TOS_SET(hdr, tos) (hdr)->_tos = (tos) +#define IPH_LEN_SET(hdr, len) (hdr)->_len = (len) +#define IPH_ID_SET(hdr, id) (hdr)->_id = (id) +#define IPH_OFFSET_SET(hdr, off) (hdr)->_offset = (off) +#define IPH_TTL_SET(hdr, ttl) (hdr)->_ttl = (u8_t)(ttl) +#define IPH_PROTO_SET(hdr, proto) (hdr)->_proto = (u8_t)(proto) +#define IPH_CHKSUM_SET(hdr, chksum) (hdr)->_chksum = (chksum) + +/** The interface that provided the packet for the current callback invocation. */ +extern struct netif *current_netif; +/** Header of the input packet currently being processed. */ +extern const struct ip_hdr *current_header; +/** Source IP address of current_header */ +extern ip_addr_t current_iphdr_src; +/** Destination IP address of current_header */ +extern ip_addr_t current_iphdr_dest; + +#define ip_init() /* Compatibility define, not init needed. */ +struct netif *ip_route(ip_addr_t *dest); +err_t ip_input(struct pbuf *p, struct netif *inp); +err_t ip_output(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest, + u8_t ttl, u8_t tos, u8_t proto); +err_t ip_output_if(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest, + u8_t ttl, u8_t tos, u8_t proto, + struct netif *netif); +#if LWIP_NETIF_HWADDRHINT +err_t ip_output_hinted(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest, + u8_t ttl, u8_t tos, u8_t proto, u8_t *addr_hint); +#endif /* LWIP_NETIF_HWADDRHINT */ +#if IP_OPTIONS_SEND +err_t ip_output_if_opt(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest, + u8_t ttl, u8_t tos, u8_t proto, struct netif *netif, void *ip_options, + u16_t optlen); +#endif /* IP_OPTIONS_SEND */ +/** Get the interface that received the current packet. + * This function must only be called from a receive callback (udp_recv, + * raw_recv, tcp_accept). It will return NULL otherwise. */ +#define ip_current_netif() (current_netif) +/** Get the IP header of the current packet. + * This function must only be called from a receive callback (udp_recv, + * raw_recv, tcp_accept). It will return NULL otherwise. */ +#define ip_current_header() (current_header) +/** Source IP address of current_header */ +#define ip_current_src_addr() (¤t_iphdr_src) +/** Destination IP address of current_header */ +#define ip_current_dest_addr() (¤t_iphdr_dest) + +/** Gets an IP pcb option (SOF_* flags) */ +#define ip_get_option(pcb, opt) ((pcb)->so_options & (opt)) +/** Sets an IP pcb option (SOF_* flags) */ +#define ip_set_option(pcb, opt) ((pcb)->so_options |= (opt)) +/** Resets an IP pcb option (SOF_* flags) */ +#define ip_reset_option(pcb, opt) ((pcb)->so_options &= ~(opt)) + +#if IP_DEBUG +void ip_debug_print(struct pbuf *p); +#else +#define ip_debug_print(p) +#endif /* IP_DEBUG */ + +#ifdef __cplusplus +} +#endif + +#endif /* __LWIP_IP_H__ */ + + diff --git a/src/lwip-1.4.1/src/include/ipv4/lwip/ip_addr.h b/src/lwip-1.4.1/src/include/ipv4/lwip/ip_addr.h new file mode 100644 index 0000000..77f84e0 --- /dev/null +++ b/src/lwip-1.4.1/src/include/ipv4/lwip/ip_addr.h @@ -0,0 +1,244 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __LWIP_IP_ADDR_H__ +#define __LWIP_IP_ADDR_H__ + +#include "lwip/opt.h" +#include "lwip/def.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* This is the aligned version of ip_addr_t, + used as local variable, on the stack, etc. */ +struct ip_addr { + u32_t addr; +}; + +/* This is the packed version of ip_addr_t, + used in network headers that are itself packed */ +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct ip_addr_packed { + PACK_STRUCT_FIELD(u32_t addr); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +/** ip_addr_t uses a struct for convenience only, so that the same defines can + * operate both on ip_addr_t as well as on ip_addr_p_t. */ +typedef struct ip_addr ip_addr_t; +typedef struct ip_addr_packed ip_addr_p_t; + +/* + * struct ipaddr2 is used in the definition of the ARP packet format in + * order to support compilers that don't have structure packing. + */ +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct ip_addr2 { + PACK_STRUCT_FIELD(u16_t addrw[2]); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +/* Forward declaration to not include netif.h */ +struct netif; + +extern const ip_addr_t ip_addr_any; +extern const ip_addr_t ip_addr_broadcast; + +/** IP_ADDR_ can be used as a fixed IP address + * for the wildcard and the broadcast address + */ +#define IP_ADDR_ANY ((ip_addr_t *)&ip_addr_any) +#define IP_ADDR_BROADCAST ((ip_addr_t *)&ip_addr_broadcast) + +/** 255.255.255.255 */ +#define IPADDR_NONE ((u32_t)0xffffffffUL) +/** 127.0.0.1 */ +#define IPADDR_LOOPBACK ((u32_t)0x7f000001UL) +/** 0.0.0.0 */ +#define IPADDR_ANY ((u32_t)0x00000000UL) +/** 255.255.255.255 */ +#define IPADDR_BROADCAST ((u32_t)0xffffffffUL) + +/* Definitions of the bits in an Internet address integer. + + On subnets, host and network parts are found according to + the subnet mask, not these masks. */ +#define IP_CLASSA(a) ((((u32_t)(a)) & 0x80000000UL) == 0) +#define IP_CLASSA_NET 0xff000000 +#define IP_CLASSA_NSHIFT 24 +#define IP_CLASSA_HOST (0xffffffff & ~IP_CLASSA_NET) +#define IP_CLASSA_MAX 128 + +#define IP_CLASSB(a) ((((u32_t)(a)) & 0xc0000000UL) == 0x80000000UL) +#define IP_CLASSB_NET 0xffff0000 +#define IP_CLASSB_NSHIFT 16 +#define IP_CLASSB_HOST (0xffffffff & ~IP_CLASSB_NET) +#define IP_CLASSB_MAX 65536 + +#define IP_CLASSC(a) ((((u32_t)(a)) & 0xe0000000UL) == 0xc0000000UL) +#define IP_CLASSC_NET 0xffffff00 +#define IP_CLASSC_NSHIFT 8 +#define IP_CLASSC_HOST (0xffffffff & ~IP_CLASSC_NET) + +#define IP_CLASSD(a) (((u32_t)(a) & 0xf0000000UL) == 0xe0000000UL) +#define IP_CLASSD_NET 0xf0000000 /* These ones aren't really */ +#define IP_CLASSD_NSHIFT 28 /* net and host fields, but */ +#define IP_CLASSD_HOST 0x0fffffff /* routing needn't know. */ +#define IP_MULTICAST(a) IP_CLASSD(a) + +#define IP_EXPERIMENTAL(a) (((u32_t)(a) & 0xf0000000UL) == 0xf0000000UL) +#define IP_BADCLASS(a) (((u32_t)(a) & 0xf0000000UL) == 0xf0000000UL) + +#define IP_LOOPBACKNET 127 /* official! */ + + +#if BYTE_ORDER == BIG_ENDIAN +/** Set an IP address given by the four byte-parts */ +#define IP4_ADDR(ipaddr, a,b,c,d) \ + (ipaddr)->addr = ((u32_t)((a) & 0xff) << 24) | \ + ((u32_t)((b) & 0xff) << 16) | \ + ((u32_t)((c) & 0xff) << 8) | \ + (u32_t)((d) & 0xff) +#else +/** Set an IP address given by the four byte-parts. + Little-endian version that prevents the use of htonl. */ +#define IP4_ADDR(ipaddr, a,b,c,d) \ + (ipaddr)->addr = ((u32_t)((d) & 0xff) << 24) | \ + ((u32_t)((c) & 0xff) << 16) | \ + ((u32_t)((b) & 0xff) << 8) | \ + (u32_t)((a) & 0xff) +#endif + +/** MEMCPY-like copying of IP addresses where addresses are known to be + * 16-bit-aligned if the port is correctly configured (so a port could define + * this to copying 2 u16_t's) - no NULL-pointer-checking needed. */ +#ifndef IPADDR2_COPY +#define IPADDR2_COPY(dest, src) SMEMCPY(dest, src, sizeof(ip_addr_t)) +#endif + +/** Copy IP address - faster than ip_addr_set: no NULL check */ +#define ip_addr_copy(dest, src) ((dest).addr = (src).addr) +/** Safely copy one IP address to another (src may be NULL) */ +#define ip_addr_set(dest, src) ((dest)->addr = \ + ((src) == NULL ? 0 : \ + (src)->addr)) +/** Set complete address to zero */ +#define ip_addr_set_zero(ipaddr) ((ipaddr)->addr = 0) +/** Set address to IPADDR_ANY (no need for htonl()) */ +#define ip_addr_set_any(ipaddr) ((ipaddr)->addr = IPADDR_ANY) +/** Set address to loopback address */ +#define ip_addr_set_loopback(ipaddr) ((ipaddr)->addr = PP_HTONL(IPADDR_LOOPBACK)) +/** Safely copy one IP address to another and change byte order + * from host- to network-order. */ +#define ip_addr_set_hton(dest, src) ((dest)->addr = \ + ((src) == NULL ? 0:\ + htonl((src)->addr))) +/** IPv4 only: set the IP address given as an u32_t */ +#define ip4_addr_set_u32(dest_ipaddr, src_u32) ((dest_ipaddr)->addr = (src_u32)) +/** IPv4 only: get the IP address as an u32_t */ +#define ip4_addr_get_u32(src_ipaddr) ((src_ipaddr)->addr) + +/** Get the network address by combining host address with netmask */ +#define ip_addr_get_network(target, host, netmask) ((target)->addr = ((host)->addr) & ((netmask)->addr)) + +/** + * Determine if two address are on the same network. + * + * @arg addr1 IP address 1 + * @arg addr2 IP address 2 + * @arg mask network identifier mask + * @return !0 if the network identifiers of both address match + */ +#define ip_addr_netcmp(addr1, addr2, mask) (((addr1)->addr & \ + (mask)->addr) == \ + ((addr2)->addr & \ + (mask)->addr)) +#define ip_addr_cmp(addr1, addr2) ((addr1)->addr == (addr2)->addr) + +#define ip_addr_isany(addr1) ((addr1) == NULL || (addr1)->addr == IPADDR_ANY) + +#define ip_addr_isbroadcast(ipaddr, netif) ip4_addr_isbroadcast((ipaddr)->addr, (netif)) +u8_t ip4_addr_isbroadcast(u32_t addr, const struct netif *netif); + +#define ip_addr_netmask_valid(netmask) ip4_addr_netmask_valid((netmask)->addr) +u8_t ip4_addr_netmask_valid(u32_t netmask); + +#define ip_addr_ismulticast(addr1) (((addr1)->addr & PP_HTONL(0xf0000000UL)) == PP_HTONL(0xe0000000UL)) + +#define ip_addr_islinklocal(addr1) (((addr1)->addr & PP_HTONL(0xffff0000UL)) == PP_HTONL(0xa9fe0000UL)) + +#define ip_addr_debug_print(debug, ipaddr) \ + LWIP_DEBUGF(debug, ("%"U16_F".%"U16_F".%"U16_F".%"U16_F, \ + ipaddr != NULL ? ip4_addr1_16(ipaddr) : 0, \ + ipaddr != NULL ? ip4_addr2_16(ipaddr) : 0, \ + ipaddr != NULL ? ip4_addr3_16(ipaddr) : 0, \ + ipaddr != NULL ? ip4_addr4_16(ipaddr) : 0)) + +/* Get one byte from the 4-byte address */ +#define ip4_addr1(ipaddr) (((u8_t*)(ipaddr))[0]) +#define ip4_addr2(ipaddr) (((u8_t*)(ipaddr))[1]) +#define ip4_addr3(ipaddr) (((u8_t*)(ipaddr))[2]) +#define ip4_addr4(ipaddr) (((u8_t*)(ipaddr))[3]) +/* These are cast to u16_t, with the intent that they are often arguments + * to printf using the U16_F format from cc.h. */ +#define ip4_addr1_16(ipaddr) ((u16_t)ip4_addr1(ipaddr)) +#define ip4_addr2_16(ipaddr) ((u16_t)ip4_addr2(ipaddr)) +#define ip4_addr3_16(ipaddr) ((u16_t)ip4_addr3(ipaddr)) +#define ip4_addr4_16(ipaddr) ((u16_t)ip4_addr4(ipaddr)) + +/** For backwards compatibility */ +#define ip_ntoa(ipaddr) ipaddr_ntoa(ipaddr) + +u32_t ipaddr_addr(const char *cp); +int ipaddr_aton(const char *cp, ip_addr_t *addr); +/** returns ptr to static buffer; not reentrant! */ +char *ipaddr_ntoa(const ip_addr_t *addr); +char *ipaddr_ntoa_r(const ip_addr_t *addr, char *buf, int buflen); + +#ifdef __cplusplus +} +#endif + +#endif /* __LWIP_IP_ADDR_H__ */ diff --git a/src/lwip-1.4.1/src/include/ipv4/lwip/ip_frag.h b/src/lwip-1.4.1/src/include/ipv4/lwip/ip_frag.h new file mode 100644 index 0000000..77b5eb1 --- /dev/null +++ b/src/lwip-1.4.1/src/include/ipv4/lwip/ip_frag.h @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Jani Monoses + * + */ + +#ifndef __LWIP_IP_FRAG_H__ +#define __LWIP_IP_FRAG_H__ + +#include "lwip/opt.h" +#include "lwip/err.h" +#include "lwip/pbuf.h" +#include "lwip/netif.h" +#include "lwip/ip_addr.h" +#include "lwip/ip.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if IP_REASSEMBLY +/* The IP reassembly timer interval in milliseconds. */ +#define IP_TMR_INTERVAL 1000 + +/* IP reassembly helper struct. + * This is exported because memp needs to know the size. + */ +struct ip_reassdata { + struct ip_reassdata *next; + struct pbuf *p; + struct ip_hdr iphdr; + u16_t datagram_len; + u8_t flags; + u8_t timer; +}; + +void ip_reass_init(void); +void ip_reass_tmr(void); +struct pbuf * ip_reass(struct pbuf *p); +#endif /* IP_REASSEMBLY */ + +#if IP_FRAG +#if !IP_FRAG_USES_STATIC_BUF && !LWIP_NETIF_TX_SINGLE_PBUF +/** A custom pbuf that holds a reference to another pbuf, which is freed + * when this custom pbuf is freed. This is used to create a custom PBUF_REF + * that points into the original pbuf. */ +struct pbuf_custom_ref { + /** 'base class' */ + struct pbuf_custom pc; + /** pointer to the original pbuf that is referenced */ + struct pbuf *original; +}; +#endif /* !IP_FRAG_USES_STATIC_BUF && !LWIP_NETIF_TX_SINGLE_PBUF */ + +err_t ip_frag(struct pbuf *p, struct netif *netif, ip_addr_t *dest); +#endif /* IP_FRAG */ + +#ifdef __cplusplus +} +#endif + +#endif /* __LWIP_IP_FRAG_H__ */ diff --git a/src/lwip-1.4.1/src/include/ipv6/lwip/icmp.h b/src/lwip-1.4.1/src/include/ipv6/lwip/icmp.h new file mode 100644 index 0000000..87e9ffd --- /dev/null +++ b/src/lwip-1.4.1/src/include/ipv6/lwip/icmp.h @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __LWIP_ICMP_H__ +#define __LWIP_ICMP_H__ + +#include "lwip/opt.h" + +#if LWIP_ICMP /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/pbuf.h" +#include "lwip/netif.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define ICMP6_DUR 1 +#define ICMP6_TE 3 +#define ICMP6_ECHO 128 /* echo */ +#define ICMP6_ER 129 /* echo reply */ + + +enum icmp_dur_type { + ICMP_DUR_NET = 0, /* net unreachable */ + ICMP_DUR_HOST = 1, /* host unreachable */ + ICMP_DUR_PROTO = 2, /* protocol unreachable */ + ICMP_DUR_PORT = 3, /* port unreachable */ + ICMP_DUR_FRAG = 4, /* fragmentation needed and DF set */ + ICMP_DUR_SR = 5 /* source route failed */ +}; + +enum icmp_te_type { + ICMP_TE_TTL = 0, /* time to live exceeded in transit */ + ICMP_TE_FRAG = 1 /* fragment reassembly time exceeded */ +}; + +void icmp_input(struct pbuf *p, struct netif *inp); + +void icmp_dest_unreach(struct pbuf *p, enum icmp_dur_type t); +void icmp_time_exceeded(struct pbuf *p, enum icmp_te_type t); + +struct icmp_echo_hdr { + u8_t type; + u8_t icode; + u16_t chksum; + u16_t id; + u16_t seqno; +}; + +struct icmp_dur_hdr { + u8_t type; + u8_t icode; + u16_t chksum; + u32_t unused; +}; + +struct icmp_te_hdr { + u8_t type; + u8_t icode; + u16_t chksum; + u32_t unused; +}; + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_ICMP */ + +#endif /* __LWIP_ICMP_H__ */ + diff --git a/src/lwip-1.4.1/src/include/ipv6/lwip/inet.h b/src/lwip-1.4.1/src/include/ipv6/lwip/inet.h new file mode 100644 index 0000000..de1a0b6 --- /dev/null +++ b/src/lwip-1.4.1/src/include/ipv6/lwip/inet.h @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __LWIP_INET_H__ +#define __LWIP_INET_H__ + +#include "lwip/opt.h" +#include "lwip/pbuf.h" +#include "lwip/ip_addr.h" + +#ifdef __cplusplus +extern "C" { +#endif + +u16_t inet_chksum(void *data, u16_t len); +u16_t inet_chksum_pbuf(struct pbuf *p); +u16_t inet_chksum_pseudo(struct pbuf *p, + struct ip_addr *src, struct ip_addr *dest, + u8_t proto, u32_t proto_len); + +u32_t inet_addr(const char *cp); +s8_t inet_aton(const char *cp, struct in_addr *addr); + +#ifndef _MACHINE_ENDIAN_H_ +#ifndef _NETINET_IN_H +#ifndef _LINUX_BYTEORDER_GENERIC_H +u16_t htons(u16_t n); +u16_t ntohs(u16_t n); +u32_t htonl(u32_t n); +u32_t ntohl(u32_t n); +#endif /* _LINUX_BYTEORDER_GENERIC_H */ +#endif /* _NETINET_IN_H */ +#endif /* _MACHINE_ENDIAN_H_ */ + +#ifdef __cplusplus +} +#endif + +#endif /* __LWIP_INET_H__ */ + diff --git a/src/lwip-1.4.1/src/include/ipv6/lwip/ip.h b/src/lwip-1.4.1/src/include/ipv6/lwip/ip.h new file mode 100644 index 0000000..a01cfc6 --- /dev/null +++ b/src/lwip-1.4.1/src/include/ipv6/lwip/ip.h @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __LWIP_IP_H__ +#define __LWIP_IP_H__ + +#include "lwip/opt.h" +#include "lwip/def.h" +#include "lwip/pbuf.h" +#include "lwip/ip_addr.h" + +#include "lwip/err.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define IP_HLEN 40 + +#define IP_PROTO_ICMP 58 +#define IP_PROTO_UDP 17 +#define IP_PROTO_UDPLITE 136 +#define IP_PROTO_TCP 6 + +/* This is passed as the destination address to ip_output_if (not + to ip_output), meaning that an IP header already is constructed + in the pbuf. This is used when TCP retransmits. */ +#ifdef IP_HDRINCL +#undef IP_HDRINCL +#endif /* IP_HDRINCL */ +#define IP_HDRINCL NULL + +#if LWIP_NETIF_HWADDRHINT +#define IP_PCB_ADDRHINT ;u8_t addr_hint +#else +#define IP_PCB_ADDRHINT +#endif /* LWIP_NETIF_HWADDRHINT */ + +/* This is the common part of all PCB types. It needs to be at the + beginning of a PCB type definition. It is located here so that + changes to this common part are made in one location instead of + having to change all PCB structs. */ +#define IP_PCB struct ip_addr local_ip; \ + struct ip_addr remote_ip; \ + /* Socket options */ \ + u16_t so_options; \ + /* Type Of Service */ \ + u8_t tos; \ + /* Time To Live */ \ + u8_t ttl; \ + /* link layer address resolution hint */ \ + IP_PCB_ADDRHINT + + +/* The IPv6 header. */ +struct ip_hdr { +#if BYTE_ORDER == LITTLE_ENDIAN + u8_t tclass1:4, v:4; + u8_t flow1:4, tclass2:4; +#else + u8_t v:4, tclass1:4; + u8_t tclass2:8, flow1:4; +#endif + u16_t flow2; + u16_t len; /* payload length */ + u8_t nexthdr; /* next header */ + u8_t hoplim; /* hop limit (TTL) */ + struct ip_addr src, dest; /* source and destination IP addresses */ +}; + +#define IPH_PROTO(hdr) (iphdr->nexthdr) + +void ip_init(void); + +#include "lwip/netif.h" + +struct netif *ip_route(struct ip_addr *dest); + +void ip_input(struct pbuf *p, struct netif *inp); + +/* source and destination addresses in network byte order, please */ +err_t ip_output(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest, + u8_t ttl, u8_t proto); + +err_t ip_output_if(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest, + u8_t ttl, u8_t proto, + struct netif *netif); + +#define ip_current_netif() NULL +#define ip_current_header() NULL + +#if IP_DEBUG +void ip_debug_print(struct pbuf *p); +#endif /* IP_DEBUG */ + +#ifdef __cplusplus +} +#endif + +#endif /* __LWIP_IP_H__ */ + + diff --git a/src/lwip-1.4.1/src/include/ipv6/lwip/ip_addr.h b/src/lwip-1.4.1/src/include/ipv6/lwip/ip_addr.h new file mode 100644 index 0000000..b2d8ae5 --- /dev/null +++ b/src/lwip-1.4.1/src/include/ipv6/lwip/ip_addr.h @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __LWIP_IP_ADDR_H__ +#define __LWIP_IP_ADDR_H__ + +#include "lwip/opt.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define IP_ADDR_ANY 0 + +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN + struct ip_addr { + PACK_STRUCT_FIELD(u32_t addr[4]); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +/* + * struct ipaddr2 is used in the definition of the ARP packet format in + * order to support compilers that don't have structure packing. + */ +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct ip_addr2 { + PACK_STRUCT_FIELD(u16_t addrw[2]); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +#define IP6_ADDR(ipaddr, a,b,c,d,e,f,g,h) do { (ipaddr)->addr[0] = htonl((u32_t)((a & 0xffff) << 16) | (b & 0xffff)); \ + (ipaddr)->addr[1] = htonl(((c & 0xffff) << 16) | (d & 0xffff)); \ + (ipaddr)->addr[2] = htonl(((e & 0xffff) << 16) | (f & 0xffff)); \ + (ipaddr)->addr[3] = htonl(((g & 0xffff) << 16) | (h & 0xffff)); } while(0) + +u8_t ip_addr_netcmp(struct ip_addr *addr1, struct ip_addr *addr2, + struct ip_addr *mask); +u8_t ip_addr_cmp(struct ip_addr *addr1, struct ip_addr *addr2); +void ip_addr_set(struct ip_addr *dest, struct ip_addr *src); +u8_t ip_addr_isany(struct ip_addr *addr); + +#define ip_addr_debug_print(debug, ipaddr) \ + LWIP_DEBUGF(debug, ("%"X32_F":%"X32_F":%"X32_F":%"X32_F":%"X32_F":%"X32_F":%"X32_F":%"X32_F"\n", \ + (ntohl(ipaddr->addr[0]) >> 16) & 0xffff, \ + ntohl(ipaddr->addr[0]) & 0xffff, \ + (ntohl(ipaddr->addr[1]) >> 16) & 0xffff, \ + ntohl(ipaddr->addr[1]) & 0xffff, \ + (ntohl(ipaddr->addr[2]) >> 16) & 0xffff, \ + ntohl(ipaddr->addr[2]) & 0xffff, \ + (ntohl(ipaddr->addr[3]) >> 16) & 0xffff, \ + ntohl(ipaddr->addr[3]) & 0xffff)); + +#ifdef __cplusplus +} +#endif + +#endif /* __LWIP_IP_ADDR_H__ */ diff --git a/src/lwip-1.4.1/src/include/lwip/api.h b/src/lwip-1.4.1/src/include/lwip/api.h new file mode 100644 index 0000000..7a9fa93 --- /dev/null +++ b/src/lwip-1.4.1/src/include/lwip/api.h @@ -0,0 +1,297 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __LWIP_API_H__ +#define __LWIP_API_H__ + +#include "lwip/opt.h" + +#if LWIP_NETCONN /* don't build if not configured for use in lwipopts.h */ + +#include /* for size_t */ + +#include "lwip/netbuf.h" +#include "lwip/sys.h" +#include "lwip/ip_addr.h" +#include "lwip/err.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Throughout this file, IP addresses and port numbers are expected to be in + * the same byte order as in the corresponding pcb. + */ + +/* Flags for netconn_write (u8_t) */ +#define NETCONN_NOFLAG 0x00 +#define NETCONN_NOCOPY 0x00 /* Only for source code compatibility */ +#define NETCONN_COPY 0x01 +#define NETCONN_MORE 0x02 +#define NETCONN_DONTBLOCK 0x04 + +/* Flags for struct netconn.flags (u8_t) */ +/** TCP: when data passed to netconn_write doesn't fit into the send buffer, + this temporarily stores whether to wake up the original application task + if data couldn't be sent in the first try. */ +#define NETCONN_FLAG_WRITE_DELAYED 0x01 +/** Should this netconn avoid blocking? */ +#define NETCONN_FLAG_NON_BLOCKING 0x02 +/** Was the last connect action a non-blocking one? */ +#define NETCONN_FLAG_IN_NONBLOCKING_CONNECT 0x04 +/** If this is set, a TCP netconn must call netconn_recved() to update + the TCP receive window (done automatically if not set). */ +#define NETCONN_FLAG_NO_AUTO_RECVED 0x08 +/** If a nonblocking write has been rejected before, poll_tcp needs to + check if the netconn is writable again */ +#define NETCONN_FLAG_CHECK_WRITESPACE 0x10 + + +/* Helpers to process several netconn_types by the same code */ +#define NETCONNTYPE_GROUP(t) (t&0xF0) +#define NETCONNTYPE_DATAGRAM(t) (t&0xE0) + +/** Protocol family and type of the netconn */ +enum netconn_type { + NETCONN_INVALID = 0, + /* NETCONN_TCP Group */ + NETCONN_TCP = 0x10, + /* NETCONN_UDP Group */ + NETCONN_UDP = 0x20, + NETCONN_UDPLITE = 0x21, + NETCONN_UDPNOCHKSUM= 0x22, + /* NETCONN_RAW Group */ + NETCONN_RAW = 0x40 +}; + +/** Current state of the netconn. Non-TCP netconns are always + * in state NETCONN_NONE! */ +enum netconn_state { + NETCONN_NONE, + NETCONN_WRITE, + NETCONN_LISTEN, + NETCONN_CONNECT, + NETCONN_CLOSE +}; + +/** Use to inform the callback function about changes */ +enum netconn_evt { + NETCONN_EVT_RCVPLUS, + NETCONN_EVT_RCVMINUS, + NETCONN_EVT_SENDPLUS, + NETCONN_EVT_SENDMINUS, + NETCONN_EVT_ERROR +}; + +#if LWIP_IGMP +/** Used for netconn_join_leave_group() */ +enum netconn_igmp { + NETCONN_JOIN, + NETCONN_LEAVE +}; +#endif /* LWIP_IGMP */ + +/* forward-declare some structs to avoid to include their headers */ +struct ip_pcb; +struct tcp_pcb; +struct udp_pcb; +struct raw_pcb; +struct netconn; +struct api_msg_msg; + +/** A callback prototype to inform about events for a netconn */ +typedef void (* netconn_callback)(struct netconn *, enum netconn_evt, u16_t len); + +/** A netconn descriptor */ +struct netconn { + /** type of the netconn (TCP, UDP or RAW) */ + enum netconn_type type; + /** current state of the netconn */ + enum netconn_state state; + /** the lwIP internal protocol control block */ + union { + struct ip_pcb *ip; + struct tcp_pcb *tcp; + struct udp_pcb *udp; + struct raw_pcb *raw; + } pcb; + /** the last error this netconn had */ + err_t last_err; + /** sem that is used to synchroneously execute functions in the core context */ + sys_sem_t op_completed; + /** mbox where received packets are stored until they are fetched + by the netconn application thread (can grow quite big) */ + sys_mbox_t recvmbox; +#if LWIP_TCP + /** mbox where new connections are stored until processed + by the application thread */ + sys_mbox_t acceptmbox; +#endif /* LWIP_TCP */ + /** only used for socket layer */ +#if LWIP_SOCKET + int socket; +#endif /* LWIP_SOCKET */ +#if LWIP_SO_SNDTIMEO + /** timeout to wait for sending data (which means enqueueing data for sending + in internal buffers) */ + s32_t send_timeout; +#endif /* LWIP_SO_RCVTIMEO */ +#if LWIP_SO_RCVTIMEO + /** timeout to wait for new data to be received + (or connections to arrive for listening netconns) */ + int recv_timeout; +#endif /* LWIP_SO_RCVTIMEO */ +#if LWIP_SO_RCVBUF + /** maximum amount of bytes queued in recvmbox + not used for TCP: adjust TCP_WND instead! */ + int recv_bufsize; + /** number of bytes currently in recvmbox to be received, + tested against recv_bufsize to limit bytes on recvmbox + for UDP and RAW, used for FIONREAD */ + s16_t recv_avail; +#endif /* LWIP_SO_RCVBUF */ + /** flags holding more netconn-internal state, see NETCONN_FLAG_* defines */ + u8_t flags; +#if LWIP_TCP + /** TCP: when data passed to netconn_write doesn't fit into the send buffer, + this temporarily stores how much is already sent. */ + size_t write_offset; + /** TCP: when data passed to netconn_write doesn't fit into the send buffer, + this temporarily stores the message. + Also used during connect and close. */ + struct api_msg_msg *current_msg; +#endif /* LWIP_TCP */ + /** A callback function that is informed about events for this netconn */ + netconn_callback callback; +}; + +/** Register an Network connection event */ +#define API_EVENT(c,e,l) if (c->callback) { \ + (*c->callback)(c, e, l); \ + } + +/** Set conn->last_err to err but don't overwrite fatal errors */ +#define NETCONN_SET_SAFE_ERR(conn, err) do { \ + SYS_ARCH_DECL_PROTECT(lev); \ + SYS_ARCH_PROTECT(lev); \ + if (!ERR_IS_FATAL((conn)->last_err)) { \ + (conn)->last_err = err; \ + } \ + SYS_ARCH_UNPROTECT(lev); \ +} while(0); + +/* Network connection functions: */ +#define netconn_new(t) netconn_new_with_proto_and_callback(t, 0, NULL) +#define netconn_new_with_callback(t, c) netconn_new_with_proto_and_callback(t, 0, c) +struct +netconn *netconn_new_with_proto_and_callback(enum netconn_type t, u8_t proto, + netconn_callback callback); +err_t netconn_delete(struct netconn *conn); +/** Get the type of a netconn (as enum netconn_type). */ +#define netconn_type(conn) (conn->type) + +err_t netconn_getaddr(struct netconn *conn, ip_addr_t *addr, + u16_t *port, u8_t local); +#define netconn_peer(c,i,p) netconn_getaddr(c,i,p,0) +#define netconn_addr(c,i,p) netconn_getaddr(c,i,p,1) + +err_t netconn_bind(struct netconn *conn, ip_addr_t *addr, u16_t port); +err_t netconn_connect(struct netconn *conn, ip_addr_t *addr, u16_t port); +err_t netconn_disconnect (struct netconn *conn); +err_t netconn_listen_with_backlog(struct netconn *conn, u8_t backlog); +#define netconn_listen(conn) netconn_listen_with_backlog(conn, TCP_DEFAULT_LISTEN_BACKLOG) +err_t netconn_accept(struct netconn *conn, struct netconn **new_conn); +err_t netconn_recv(struct netconn *conn, struct netbuf **new_buf); +err_t netconn_recv_tcp_pbuf(struct netconn *conn, struct pbuf **new_buf); +void netconn_recved(struct netconn *conn, u32_t length); +err_t netconn_sendto(struct netconn *conn, struct netbuf *buf, + ip_addr_t *addr, u16_t port); +err_t netconn_send(struct netconn *conn, struct netbuf *buf); +err_t netconn_write_partly(struct netconn *conn, const void *dataptr, size_t size, + u8_t apiflags, size_t *bytes_written); +#define netconn_write(conn, dataptr, size, apiflags) \ + netconn_write_partly(conn, dataptr, size, apiflags, NULL) +err_t netconn_close(struct netconn *conn); +err_t netconn_shutdown(struct netconn *conn, u8_t shut_rx, u8_t shut_tx); + +#if LWIP_IGMP +err_t netconn_join_leave_group(struct netconn *conn, ip_addr_t *multiaddr, + ip_addr_t *netif_addr, enum netconn_igmp join_or_leave); +#endif /* LWIP_IGMP */ +#if LWIP_DNS +err_t netconn_gethostbyname(const char *name, ip_addr_t *addr); +#endif /* LWIP_DNS */ + +#define netconn_err(conn) ((conn)->last_err) +#define netconn_recv_bufsize(conn) ((conn)->recv_bufsize) + +/** Set the blocking status of netconn calls (@todo: write/send is missing) */ +#define netconn_set_nonblocking(conn, val) do { if(val) { \ + (conn)->flags |= NETCONN_FLAG_NON_BLOCKING; \ +} else { \ + (conn)->flags &= ~ NETCONN_FLAG_NON_BLOCKING; }} while(0) +/** Get the blocking status of netconn calls (@todo: write/send is missing) */ +#define netconn_is_nonblocking(conn) (((conn)->flags & NETCONN_FLAG_NON_BLOCKING) != 0) + +/** TCP: Set the no-auto-recved status of netconn calls (see NETCONN_FLAG_NO_AUTO_RECVED) */ +#define netconn_set_noautorecved(conn, val) do { if(val) { \ + (conn)->flags |= NETCONN_FLAG_NO_AUTO_RECVED; \ +} else { \ + (conn)->flags &= ~ NETCONN_FLAG_NO_AUTO_RECVED; }} while(0) +/** TCP: Get the no-auto-recved status of netconn calls (see NETCONN_FLAG_NO_AUTO_RECVED) */ +#define netconn_get_noautorecved(conn) (((conn)->flags & NETCONN_FLAG_NO_AUTO_RECVED) != 0) + +#if LWIP_SO_SNDTIMEO +/** Set the send timeout in milliseconds */ +#define netconn_set_sendtimeout(conn, timeout) ((conn)->send_timeout = (timeout)) +/** Get the send timeout in milliseconds */ +#define netconn_get_sendtimeout(conn) ((conn)->send_timeout) +#endif /* LWIP_SO_SNDTIMEO */ +#if LWIP_SO_RCVTIMEO +/** Set the receive timeout in milliseconds */ +#define netconn_set_recvtimeout(conn, timeout) ((conn)->recv_timeout = (timeout)) +/** Get the receive timeout in milliseconds */ +#define netconn_get_recvtimeout(conn) ((conn)->recv_timeout) +#endif /* LWIP_SO_RCVTIMEO */ +#if LWIP_SO_RCVBUF +/** Set the receive buffer in bytes */ +#define netconn_set_recvbufsize(conn, recvbufsize) ((conn)->recv_bufsize = (recvbufsize)) +/** Get the receive buffer in bytes */ +#define netconn_get_recvbufsize(conn) ((conn)->recv_bufsize) +#endif /* LWIP_SO_RCVBUF*/ + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_NETCONN */ + +#endif /* __LWIP_API_H__ */ diff --git a/src/lwip-1.4.1/src/include/lwip/api_msg.h b/src/lwip-1.4.1/src/include/lwip/api_msg.h new file mode 100644 index 0000000..f9e1c7d --- /dev/null +++ b/src/lwip-1.4.1/src/include/lwip/api_msg.h @@ -0,0 +1,177 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __LWIP_API_MSG_H__ +#define __LWIP_API_MSG_H__ + +#include "lwip/opt.h" + +#if LWIP_NETCONN /* don't build if not configured for use in lwipopts.h */ + +#include /* for size_t */ + +#include "lwip/ip_addr.h" +#include "lwip/err.h" +#include "lwip/sys.h" +#include "lwip/igmp.h" +#include "lwip/api.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* For the netconn API, these values are use as a bitmask! */ +#define NETCONN_SHUT_RD 1 +#define NETCONN_SHUT_WR 2 +#define NETCONN_SHUT_RDWR (NETCONN_SHUT_RD | NETCONN_SHUT_WR) + +/* IP addresses and port numbers are expected to be in + * the same byte order as in the corresponding pcb. + */ +/** This struct includes everything that is necessary to execute a function + for a netconn in another thread context (mainly used to process netconns + in the tcpip_thread context to be thread safe). */ +struct api_msg_msg { + /** The netconn which to process - always needed: it includes the semaphore + which is used to block the application thread until the function finished. */ + struct netconn *conn; + /** The return value of the function executed in tcpip_thread. */ + err_t err; + /** Depending on the executed function, one of these union members is used */ + union { + /** used for do_send */ + struct netbuf *b; + /** used for do_newconn */ + struct { + u8_t proto; + } n; + /** used for do_bind and do_connect */ + struct { + ip_addr_t *ipaddr; + u16_t port; + } bc; + /** used for do_getaddr */ + struct { + ip_addr_t *ipaddr; + u16_t *port; + u8_t local; + } ad; + /** used for do_write */ + struct { + const void *dataptr; + size_t len; + u8_t apiflags; +#if LWIP_SO_SNDTIMEO + u32_t time_started; +#endif /* LWIP_SO_SNDTIMEO */ + } w; + /** used for do_recv */ + struct { + u32_t len; + } r; + /** used for do_close (/shutdown) */ + struct { + u8_t shut; + } sd; +#if LWIP_IGMP + /** used for do_join_leave_group */ + struct { + ip_addr_t *multiaddr; + ip_addr_t *netif_addr; + enum netconn_igmp join_or_leave; + } jl; +#endif /* LWIP_IGMP */ +#if TCP_LISTEN_BACKLOG + struct { + u8_t backlog; + } lb; +#endif /* TCP_LISTEN_BACKLOG */ + } msg; +}; + +/** This struct contains a function to execute in another thread context and + a struct api_msg_msg that serves as an argument for this function. + This is passed to tcpip_apimsg to execute functions in tcpip_thread context. */ +struct api_msg { + /** function to execute in tcpip_thread context */ + void (* function)(struct api_msg_msg *msg); + /** arguments for this function */ + struct api_msg_msg msg; +}; + +#if LWIP_DNS +/** As do_gethostbyname requires more arguments but doesn't require a netconn, + it has its own struct (to avoid struct api_msg getting bigger than necessary). + do_gethostbyname must be called using tcpip_callback instead of tcpip_apimsg + (see netconn_gethostbyname). */ +struct dns_api_msg { + /** Hostname to query or dotted IP address string */ + const char *name; + /** Rhe resolved address is stored here */ + ip_addr_t *addr; + /** This semaphore is posted when the name is resolved, the application thread + should wait on it. */ + sys_sem_t *sem; + /** Errors are given back here */ + err_t *err; +}; +#endif /* LWIP_DNS */ + +void do_newconn ( struct api_msg_msg *msg); +void do_delconn ( struct api_msg_msg *msg); +void do_bind ( struct api_msg_msg *msg); +void do_connect ( struct api_msg_msg *msg); +void do_disconnect ( struct api_msg_msg *msg); +void do_listen ( struct api_msg_msg *msg); +void do_send ( struct api_msg_msg *msg); +void do_recv ( struct api_msg_msg *msg); +void do_write ( struct api_msg_msg *msg); +void do_getaddr ( struct api_msg_msg *msg); +void do_close ( struct api_msg_msg *msg); +void do_shutdown ( struct api_msg_msg *msg); +#if LWIP_IGMP +void do_join_leave_group( struct api_msg_msg *msg); +#endif /* LWIP_IGMP */ + +#if LWIP_DNS +void do_gethostbyname(void *arg); +#endif /* LWIP_DNS */ + +struct netconn* netconn_alloc(enum netconn_type t, netconn_callback callback); +void netconn_free(struct netconn *conn); + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_NETCONN */ + +#endif /* __LWIP_API_MSG_H__ */ diff --git a/src/lwip-1.4.1/src/include/lwip/arch.h b/src/lwip-1.4.1/src/include/lwip/arch.h new file mode 100644 index 0000000..4d6df77 --- /dev/null +++ b/src/lwip-1.4.1/src/include/lwip/arch.h @@ -0,0 +1,217 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __LWIP_ARCH_H__ +#define __LWIP_ARCH_H__ + +#ifndef LITTLE_ENDIAN +#define LITTLE_ENDIAN 1234 +#endif + +#ifndef BIG_ENDIAN +#define BIG_ENDIAN 4321 +#endif + +#include "arch/cc.h" + +/** Temporary: define format string for size_t if not defined in cc.h */ +#ifndef SZT_F +#define SZT_F U32_F +#endif /* SZT_F */ +/** Temporary upgrade helper: define format string for u8_t as hex if not + defined in cc.h */ +#ifndef X8_F +#define X8_F "02x" +#endif /* X8_F */ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef PACK_STRUCT_BEGIN +#define PACK_STRUCT_BEGIN +#endif /* PACK_STRUCT_BEGIN */ + +#ifndef PACK_STRUCT_END +#define PACK_STRUCT_END +#endif /* PACK_STRUCT_END */ + +#ifndef PACK_STRUCT_FIELD +#define PACK_STRUCT_FIELD(x) x +#endif /* PACK_STRUCT_FIELD */ + + +#ifndef LWIP_UNUSED_ARG +#define LWIP_UNUSED_ARG(x) (void)x +#endif /* LWIP_UNUSED_ARG */ + + +#ifdef LWIP_PROVIDE_ERRNO + +#define EPERM 1 /* Operation not permitted */ +#define ENOENT 2 /* No such file or directory */ +#define ESRCH 3 /* No such process */ +#define EINTR 4 /* Interrupted system call */ +#define EIO 5 /* I/O error */ +#define ENXIO 6 /* No such device or address */ +#define E2BIG 7 /* Arg list too long */ +#define ENOEXEC 8 /* Exec format error */ +#define EBADF 9 /* Bad file number */ +#define ECHILD 10 /* No child processes */ +#define EAGAIN 11 /* Try again */ +#define ENOMEM 12 /* Out of memory */ +#define EACCES 13 /* Permission denied */ +#define EFAULT 14 /* Bad address */ +#define ENOTBLK 15 /* Block device required */ +#define EBUSY 16 /* Device or resource busy */ +#define EEXIST 17 /* File exists */ +#define EXDEV 18 /* Cross-device link */ +#define ENODEV 19 /* No such device */ +#define ENOTDIR 20 /* Not a directory */ +#define EISDIR 21 /* Is a directory */ +#define EINVAL 22 /* Invalid argument */ +#define ENFILE 23 /* File table overflow */ +#define EMFILE 24 /* Too many open files */ +#define ENOTTY 25 /* Not a typewriter */ +#define ETXTBSY 26 /* Text file busy */ +#define EFBIG 27 /* File too large */ +#define ENOSPC 28 /* No space left on device */ +#define ESPIPE 29 /* Illegal seek */ +#define EROFS 30 /* Read-only file system */ +#define EMLINK 31 /* Too many links */ +#define EPIPE 32 /* Broken pipe */ +#define EDOM 33 /* Math argument out of domain of func */ +#define ERANGE 34 /* Math result not representable */ +#define EDEADLK 35 /* Resource deadlock would occur */ +#define ENAMETOOLONG 36 /* File name too long */ +#define ENOLCK 37 /* No record locks available */ +#define ENOSYS 38 /* Function not implemented */ +#define ENOTEMPTY 39 /* Directory not empty */ +#define ELOOP 40 /* Too many symbolic links encountered */ +#define EWOULDBLOCK EAGAIN /* Operation would block */ +#define ENOMSG 42 /* No message of desired type */ +#define EIDRM 43 /* Identifier removed */ +#define ECHRNG 44 /* Channel number out of range */ +#define EL2NSYNC 45 /* Level 2 not synchronized */ +#define EL3HLT 46 /* Level 3 halted */ +#define EL3RST 47 /* Level 3 reset */ +#define ELNRNG 48 /* Link number out of range */ +#define EUNATCH 49 /* Protocol driver not attached */ +#define ENOCSI 50 /* No CSI structure available */ +#define EL2HLT 51 /* Level 2 halted */ +#define EBADE 52 /* Invalid exchange */ +#define EBADR 53 /* Invalid request descriptor */ +#define EXFULL 54 /* Exchange full */ +#define ENOANO 55 /* No anode */ +#define EBADRQC 56 /* Invalid request code */ +#define EBADSLT 57 /* Invalid slot */ + +#define EDEADLOCK EDEADLK + +#define EBFONT 59 /* Bad font file format */ +#define ENOSTR 60 /* Device not a stream */ +#define ENODATA 61 /* No data available */ +#define ETIME 62 /* Timer expired */ +#define ENOSR 63 /* Out of streams resources */ +#define ENONET 64 /* Machine is not on the network */ +#define ENOPKG 65 /* Package not installed */ +#define EREMOTE 66 /* Object is remote */ +#define ENOLINK 67 /* Link has been severed */ +#define EADV 68 /* Advertise error */ +#define ESRMNT 69 /* Srmount error */ +#define ECOMM 70 /* Communication error on send */ +#define EPROTO 71 /* Protocol error */ +#define EMULTIHOP 72 /* Multihop attempted */ +#define EDOTDOT 73 /* RFS specific error */ +#define EBADMSG 74 /* Not a data message */ +#define EOVERFLOW 75 /* Value too large for defined data type */ +#define ENOTUNIQ 76 /* Name not unique on network */ +#define EBADFD 77 /* File descriptor in bad state */ +#define EREMCHG 78 /* Remote address changed */ +#define ELIBACC 79 /* Can not access a needed shared library */ +#define ELIBBAD 80 /* Accessing a corrupted shared library */ +#define ELIBSCN 81 /* .lib section in a.out corrupted */ +#define ELIBMAX 82 /* Attempting to link in too many shared libraries */ +#define ELIBEXEC 83 /* Cannot exec a shared library directly */ +#define EILSEQ 84 /* Illegal byte sequence */ +#define ERESTART 85 /* Interrupted system call should be restarted */ +#define ESTRPIPE 86 /* Streams pipe error */ +#define EUSERS 87 /* Too many users */ +#define ENOTSOCK 88 /* Socket operation on non-socket */ +#define EDESTADDRREQ 89 /* Destination address required */ +#define EMSGSIZE 90 /* Message too long */ +#define EPROTOTYPE 91 /* Protocol wrong type for socket */ +#define ENOPROTOOPT 92 /* Protocol not available */ +#define EPROTONOSUPPORT 93 /* Protocol not supported */ +#define ESOCKTNOSUPPORT 94 /* Socket type not supported */ +#define EOPNOTSUPP 95 /* Operation not supported on transport endpoint */ +#define EPFNOSUPPORT 96 /* Protocol family not supported */ +#define EAFNOSUPPORT 97 /* Address family not supported by protocol */ +#define EADDRINUSE 98 /* Address already in use */ +#define EADDRNOTAVAIL 99 /* Cannot assign requested address */ +#define ENETDOWN 100 /* Network is down */ +#define ENETUNREACH 101 /* Network is unreachable */ +#define ENETRESET 102 /* Network dropped connection because of reset */ +#define ECONNABORTED 103 /* Software caused connection abort */ +#define ECONNRESET 104 /* Connection reset by peer */ +#define ENOBUFS 105 /* No buffer space available */ +#define EISCONN 106 /* Transport endpoint is already connected */ +#define ENOTCONN 107 /* Transport endpoint is not connected */ +#define ESHUTDOWN 108 /* Cannot send after transport endpoint shutdown */ +#define ETOOMANYREFS 109 /* Too many references: cannot splice */ +#define ETIMEDOUT 110 /* Connection timed out */ +#define ECONNREFUSED 111 /* Connection refused */ +#define EHOSTDOWN 112 /* Host is down */ +#define EHOSTUNREACH 113 /* No route to host */ +#define EALREADY 114 /* Operation already in progress */ +#define EINPROGRESS 115 /* Operation now in progress */ +#define ESTALE 116 /* Stale NFS file handle */ +#define EUCLEAN 117 /* Structure needs cleaning */ +#define ENOTNAM 118 /* Not a XENIX named type file */ +#define ENAVAIL 119 /* No XENIX semaphores available */ +#define EISNAM 120 /* Is a named type file */ +#define EREMOTEIO 121 /* Remote I/O error */ +#define EDQUOT 122 /* Quota exceeded */ + +#define ENOMEDIUM 123 /* No medium found */ +#define EMEDIUMTYPE 124 /* Wrong medium type */ + +#ifndef errno +extern int errno; +#endif + +#endif /* LWIP_PROVIDE_ERRNO */ + +#ifdef __cplusplus +} +#endif + +#endif /* __LWIP_ARCH_H__ */ diff --git a/src/lwip-1.4.1/src/include/lwip/debug.h b/src/lwip-1.4.1/src/include/lwip/debug.h new file mode 100644 index 0000000..0fe0413 --- /dev/null +++ b/src/lwip-1.4.1/src/include/lwip/debug.h @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __LWIP_DEBUG_H__ +#define __LWIP_DEBUG_H__ + +#include "lwip/arch.h" +#include "lwip/opt.h" + +/** lower two bits indicate debug level + * - 0 all + * - 1 warning + * - 2 serious + * - 3 severe + */ +#define LWIP_DBG_LEVEL_ALL 0x00 +#define LWIP_DBG_LEVEL_OFF LWIP_DBG_LEVEL_ALL /* compatibility define only */ +#define LWIP_DBG_LEVEL_WARNING 0x01 /* bad checksums, dropped packets, ... */ +#define LWIP_DBG_LEVEL_SERIOUS 0x02 /* memory allocation failures, ... */ +#define LWIP_DBG_LEVEL_SEVERE 0x03 +#define LWIP_DBG_MASK_LEVEL 0x03 + +/** flag for LWIP_DEBUGF to enable that debug message */ +#define LWIP_DBG_ON 0x80U +/** flag for LWIP_DEBUGF to disable that debug message */ +#define LWIP_DBG_OFF 0x00U + +/** flag for LWIP_DEBUGF indicating a tracing message (to follow program flow) */ +#define LWIP_DBG_TRACE 0x40U +/** flag for LWIP_DEBUGF indicating a state debug message (to follow module states) */ +#define LWIP_DBG_STATE 0x20U +/** flag for LWIP_DEBUGF indicating newly added code, not thoroughly tested yet */ +#define LWIP_DBG_FRESH 0x10U +/** flag for LWIP_DEBUGF to halt after printing this debug message */ +#define LWIP_DBG_HALT 0x08U + +#ifndef LWIP_NOASSERT +#define LWIP_ASSERT(message, assertion) do { if(!(assertion)) \ + LWIP_PLATFORM_ASSERT(message); } while(0) +#else /* LWIP_NOASSERT */ +#define LWIP_ASSERT(message, assertion) +#endif /* LWIP_NOASSERT */ + +/** if "expression" isn't true, then print "message" and execute "handler" expression */ +#ifndef LWIP_ERROR +#define LWIP_ERROR(message, expression, handler) do { if (!(expression)) { \ + LWIP_PLATFORM_ASSERT(message); handler;}} while(0) +#endif /* LWIP_ERROR */ + +#ifdef LWIP_DEBUG +/** print debug message only if debug message type is enabled... + * AND is of correct type AND is at least LWIP_DBG_LEVEL + */ +#define LWIP_DEBUGF(debug, message) do { \ + if ( \ + ((debug) & LWIP_DBG_ON) && \ + ((debug) & LWIP_DBG_TYPES_ON) && \ + ((s16_t)((debug) & LWIP_DBG_MASK_LEVEL) >= LWIP_DBG_MIN_LEVEL)) { \ + LWIP_PLATFORM_DIAG(message); \ + if ((debug) & LWIP_DBG_HALT) { \ + while(1); \ + } \ + } \ + } while(0) + +#else /* LWIP_DEBUG */ +#define LWIP_DEBUGF(debug, message) +#endif /* LWIP_DEBUG */ + +#endif /* __LWIP_DEBUG_H__ */ + diff --git a/src/lwip-1.4.1/src/include/lwip/def.h b/src/lwip-1.4.1/src/include/lwip/def.h new file mode 100644 index 0000000..73a1b56 --- /dev/null +++ b/src/lwip-1.4.1/src/include/lwip/def.h @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __LWIP_DEF_H__ +#define __LWIP_DEF_H__ + +/* arch.h might define NULL already */ +#include "lwip/arch.h" +#include "lwip/opt.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define LWIP_MAX(x , y) (((x) > (y)) ? (x) : (y)) +#define LWIP_MIN(x , y) (((x) < (y)) ? (x) : (y)) + +#ifndef NULL +#define NULL ((void *)0) +#endif + +/* Endianess-optimized shifting of two u8_t to create one u16_t */ +#if BYTE_ORDER == LITTLE_ENDIAN +#define LWIP_MAKE_U16(a, b) ((a << 8) | b) +#else +#define LWIP_MAKE_U16(a, b) ((b << 8) | a) +#endif + +#ifndef LWIP_PLATFORM_BYTESWAP +#define LWIP_PLATFORM_BYTESWAP 0 +#endif + +#ifndef LWIP_PREFIX_BYTEORDER_FUNCS +/* workaround for naming collisions on some platforms */ + +#ifdef htons +#undef htons +#endif /* htons */ +#ifdef htonl +#undef htonl +#endif /* htonl */ +#ifdef ntohs +#undef ntohs +#endif /* ntohs */ +#ifdef ntohl +#undef ntohl +#endif /* ntohl */ + +#define htons(x) lwip_htons(x) +#define ntohs(x) lwip_ntohs(x) +#define htonl(x) lwip_htonl(x) +#define ntohl(x) lwip_ntohl(x) +#endif /* LWIP_PREFIX_BYTEORDER_FUNCS */ + +#if BYTE_ORDER == BIG_ENDIAN +#define lwip_htons(x) (x) +#define lwip_ntohs(x) (x) +#define lwip_htonl(x) (x) +#define lwip_ntohl(x) (x) +#define PP_HTONS(x) (x) +#define PP_NTOHS(x) (x) +#define PP_HTONL(x) (x) +#define PP_NTOHL(x) (x) +#else /* BYTE_ORDER != BIG_ENDIAN */ +#if LWIP_PLATFORM_BYTESWAP +#define lwip_htons(x) LWIP_PLATFORM_HTONS(x) +#define lwip_ntohs(x) LWIP_PLATFORM_HTONS(x) +#define lwip_htonl(x) LWIP_PLATFORM_HTONL(x) +#define lwip_ntohl(x) LWIP_PLATFORM_HTONL(x) +#else /* LWIP_PLATFORM_BYTESWAP */ +u16_t lwip_htons(u16_t x); +u16_t lwip_ntohs(u16_t x); +u32_t lwip_htonl(u32_t x); +u32_t lwip_ntohl(u32_t x); +#endif /* LWIP_PLATFORM_BYTESWAP */ + +/* These macros should be calculated by the preprocessor and are used + with compile-time constants only (so that there is no little-endian + overhead at runtime). */ +#define PP_HTONS(x) ((((x) & 0xff) << 8) | (((x) & 0xff00) >> 8)) +#define PP_NTOHS(x) PP_HTONS(x) +#define PP_HTONL(x) ((((x) & 0xff) << 24) | \ + (((x) & 0xff00) << 8) | \ + (((x) & 0xff0000UL) >> 8) | \ + (((x) & 0xff000000UL) >> 24)) +#define PP_NTOHL(x) PP_HTONL(x) + +#endif /* BYTE_ORDER == BIG_ENDIAN */ + +#ifdef __cplusplus +} +#endif + +#endif /* __LWIP_DEF_H__ */ + diff --git a/src/lwip-1.4.1/src/include/lwip/dhcp.h b/src/lwip-1.4.1/src/include/lwip/dhcp.h new file mode 100644 index 0000000..32d9338 --- /dev/null +++ b/src/lwip-1.4.1/src/include/lwip/dhcp.h @@ -0,0 +1,242 @@ +/** @file + */ + +#ifndef __LWIP_DHCP_H__ +#define __LWIP_DHCP_H__ + +#include "lwip/opt.h" + +#if LWIP_DHCP /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/netif.h" +#include "lwip/udp.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** period (in seconds) of the application calling dhcp_coarse_tmr() */ +#define DHCP_COARSE_TIMER_SECS 60 +/** period (in milliseconds) of the application calling dhcp_coarse_tmr() */ +#define DHCP_COARSE_TIMER_MSECS (DHCP_COARSE_TIMER_SECS * 1000UL) +/** period (in milliseconds) of the application calling dhcp_fine_tmr() */ +#define DHCP_FINE_TIMER_MSECS 500 + +#define DHCP_CHADDR_LEN 16U +#define DHCP_SNAME_LEN 64U +#define DHCP_FILE_LEN 128U + +struct dhcp +{ + /** transaction identifier of last sent request */ + u32_t xid; + /** our connection to the DHCP server */ + struct udp_pcb *pcb; + /** incoming msg */ + struct dhcp_msg *msg_in; + /** current DHCP state machine state */ + u8_t state; + /** retries of current request */ + u8_t tries; +#if LWIP_DHCP_AUTOIP_COOP + u8_t autoip_coop_state; +#endif + u8_t subnet_mask_given; + + struct pbuf *p_out; /* pbuf of outcoming msg */ + struct dhcp_msg *msg_out; /* outgoing msg */ + u16_t options_out_len; /* outgoing msg options length */ + u16_t request_timeout; /* #ticks with period DHCP_FINE_TIMER_SECS for request timeout */ + u16_t t1_timeout; /* #ticks with period DHCP_COARSE_TIMER_SECS for renewal time */ + u16_t t2_timeout; /* #ticks with period DHCP_COARSE_TIMER_SECS for rebind time */ + ip_addr_t server_ip_addr; /* dhcp server address that offered this lease */ + ip_addr_t offered_ip_addr; + ip_addr_t offered_sn_mask; + ip_addr_t offered_gw_addr; + + u32_t offered_t0_lease; /* lease period (in seconds) */ + u32_t offered_t1_renew; /* recommended renew time (usually 50% of lease period) */ + u32_t offered_t2_rebind; /* recommended rebind time (usually 66% of lease period) */ + /* @todo: LWIP_DHCP_BOOTP_FILE configuration option? + integrate with possible TFTP-client for booting? */ +#if LWIP_DHCP_BOOTP_FILE + ip_addr_t offered_si_addr; + char boot_file_name[DHCP_FILE_LEN]; +#endif /* LWIP_DHCP_BOOTPFILE */ +}; + +/* MUST be compiled with "pack structs" or equivalent! */ +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +/** minimum set of fields of any DHCP message */ +struct dhcp_msg +{ + PACK_STRUCT_FIELD(u8_t op); + PACK_STRUCT_FIELD(u8_t htype); + PACK_STRUCT_FIELD(u8_t hlen); + PACK_STRUCT_FIELD(u8_t hops); + PACK_STRUCT_FIELD(u32_t xid); + PACK_STRUCT_FIELD(u16_t secs); + PACK_STRUCT_FIELD(u16_t flags); + PACK_STRUCT_FIELD(ip_addr_p_t ciaddr); + PACK_STRUCT_FIELD(ip_addr_p_t yiaddr); + PACK_STRUCT_FIELD(ip_addr_p_t siaddr); + PACK_STRUCT_FIELD(ip_addr_p_t giaddr); + PACK_STRUCT_FIELD(u8_t chaddr[DHCP_CHADDR_LEN]); + PACK_STRUCT_FIELD(u8_t sname[DHCP_SNAME_LEN]); + PACK_STRUCT_FIELD(u8_t file[DHCP_FILE_LEN]); + PACK_STRUCT_FIELD(u32_t cookie); +#define DHCP_MIN_OPTIONS_LEN 68U +/** make sure user does not configure this too small */ +#if ((defined(DHCP_OPTIONS_LEN)) && (DHCP_OPTIONS_LEN < DHCP_MIN_OPTIONS_LEN)) +# undef DHCP_OPTIONS_LEN +#endif +/** allow this to be configured in lwipopts.h, but not too small */ +#if (!defined(DHCP_OPTIONS_LEN)) +/** set this to be sufficient for your options in outgoing DHCP msgs */ +# define DHCP_OPTIONS_LEN DHCP_MIN_OPTIONS_LEN +#endif + PACK_STRUCT_FIELD(u8_t options[DHCP_OPTIONS_LEN]); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +void dhcp_set_struct(struct netif *netif, struct dhcp *dhcp); +/** Remove a struct dhcp previously set to the netif using dhcp_set_struct() */ +#define dhcp_remove_struct(netif) do { (netif)->dhcp = NULL; } while(0) +void dhcp_cleanup(struct netif *netif); +/** start DHCP configuration */ +err_t dhcp_start(struct netif *netif); +/** enforce early lease renewal (not needed normally)*/ +err_t dhcp_renew(struct netif *netif); +/** release the DHCP lease, usually called before dhcp_stop()*/ +err_t dhcp_release(struct netif *netif); +/** stop DHCP configuration */ +void dhcp_stop(struct netif *netif); +/** inform server of our manual IP address */ +void dhcp_inform(struct netif *netif); +/** Handle a possible change in the network configuration */ +void dhcp_network_changed(struct netif *netif); + +/** if enabled, check whether the offered IP address is not in use, using ARP */ +#if DHCP_DOES_ARP_CHECK +void dhcp_arp_reply(struct netif *netif, ip_addr_t *addr); +#endif + +/** to be called every minute */ +void dhcp_coarse_tmr(void); +/** to be called every half second */ +void dhcp_fine_tmr(void); + +/** DHCP message item offsets and length */ +#define DHCP_OP_OFS 0 +#define DHCP_HTYPE_OFS 1 +#define DHCP_HLEN_OFS 2 +#define DHCP_HOPS_OFS 3 +#define DHCP_XID_OFS 4 +#define DHCP_SECS_OFS 8 +#define DHCP_FLAGS_OFS 10 +#define DHCP_CIADDR_OFS 12 +#define DHCP_YIADDR_OFS 16 +#define DHCP_SIADDR_OFS 20 +#define DHCP_GIADDR_OFS 24 +#define DHCP_CHADDR_OFS 28 +#define DHCP_SNAME_OFS 44 +#define DHCP_FILE_OFS 108 +#define DHCP_MSG_LEN 236 + +#define DHCP_COOKIE_OFS DHCP_MSG_LEN +#define DHCP_OPTIONS_OFS (DHCP_MSG_LEN + 4) + +#define DHCP_CLIENT_PORT 68 +#define DHCP_SERVER_PORT 67 + +/** DHCP client states */ +#define DHCP_OFF 0 +#define DHCP_REQUESTING 1 +#define DHCP_INIT 2 +#define DHCP_REBOOTING 3 +#define DHCP_REBINDING 4 +#define DHCP_RENEWING 5 +#define DHCP_SELECTING 6 +#define DHCP_INFORMING 7 +#define DHCP_CHECKING 8 +#define DHCP_PERMANENT 9 +#define DHCP_BOUND 10 +/** not yet implemented #define DHCP_RELEASING 11 */ +#define DHCP_BACKING_OFF 12 + +/** AUTOIP cooperatation flags */ +#define DHCP_AUTOIP_COOP_STATE_OFF 0 +#define DHCP_AUTOIP_COOP_STATE_ON 1 + +#define DHCP_BOOTREQUEST 1 +#define DHCP_BOOTREPLY 2 + +/** DHCP message types */ +#define DHCP_DISCOVER 1 +#define DHCP_OFFER 2 +#define DHCP_REQUEST 3 +#define DHCP_DECLINE 4 +#define DHCP_ACK 5 +#define DHCP_NAK 6 +#define DHCP_RELEASE 7 +#define DHCP_INFORM 8 + +/** DHCP hardware type, currently only ethernet is supported */ +#define DHCP_HTYPE_ETH 1 + +#define DHCP_MAGIC_COOKIE 0x63825363UL + +/* This is a list of options for BOOTP and DHCP, see RFC 2132 for descriptions */ + +/** BootP options */ +#define DHCP_OPTION_PAD 0 +#define DHCP_OPTION_SUBNET_MASK 1 /* RFC 2132 3.3 */ +#define DHCP_OPTION_ROUTER 3 +#define DHCP_OPTION_DNS_SERVER 6 +#define DHCP_OPTION_HOSTNAME 12 +#define DHCP_OPTION_IP_TTL 23 +#define DHCP_OPTION_MTU 26 +#define DHCP_OPTION_BROADCAST 28 +#define DHCP_OPTION_TCP_TTL 37 +#define DHCP_OPTION_END 255 + +/** DHCP options */ +#define DHCP_OPTION_REQUESTED_IP 50 /* RFC 2132 9.1, requested IP address */ +#define DHCP_OPTION_LEASE_TIME 51 /* RFC 2132 9.2, time in seconds, in 4 bytes */ +#define DHCP_OPTION_OVERLOAD 52 /* RFC2132 9.3, use file and/or sname field for options */ + +#define DHCP_OPTION_MESSAGE_TYPE 53 /* RFC 2132 9.6, important for DHCP */ +#define DHCP_OPTION_MESSAGE_TYPE_LEN 1 + +#define DHCP_OPTION_SERVER_ID 54 /* RFC 2132 9.7, server IP address */ +#define DHCP_OPTION_PARAMETER_REQUEST_LIST 55 /* RFC 2132 9.8, requested option types */ + +#define DHCP_OPTION_MAX_MSG_SIZE 57 /* RFC 2132 9.10, message size accepted >= 576 */ +#define DHCP_OPTION_MAX_MSG_SIZE_LEN 2 + +#define DHCP_OPTION_T1 58 /* T1 renewal time */ +#define DHCP_OPTION_T2 59 /* T2 rebinding time */ +#define DHCP_OPTION_US 60 +#define DHCP_OPTION_CLIENT_ID 61 +#define DHCP_OPTION_TFTP_SERVERNAME 66 +#define DHCP_OPTION_BOOTFILE 67 + +/** possible combinations of overloading the file and sname fields with options */ +#define DHCP_OVERLOAD_NONE 0 +#define DHCP_OVERLOAD_FILE 1 +#define DHCP_OVERLOAD_SNAME 2 +#define DHCP_OVERLOAD_SNAME_FILE 3 + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_DHCP */ + +#endif /*__LWIP_DHCP_H__*/ diff --git a/src/lwip-1.4.1/src/include/lwip/dns.h b/src/lwip-1.4.1/src/include/lwip/dns.h new file mode 100644 index 0000000..6c7d9b0 --- /dev/null +++ b/src/lwip-1.4.1/src/include/lwip/dns.h @@ -0,0 +1,124 @@ +/** + * lwip DNS resolver header file. + + * Author: Jim Pettinato + * April 2007 + + * ported from uIP resolv.c Copyright (c) 2002-2003, Adam Dunkels. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 __LWIP_DNS_H__ +#define __LWIP_DNS_H__ + +#include "lwip/opt.h" + +#if LWIP_DNS /* don't build if not configured for use in lwipopts.h */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** DNS timer period */ +#define DNS_TMR_INTERVAL 1000 + +/** DNS field TYPE used for "Resource Records" */ +#define DNS_RRTYPE_A 1 /* a host address */ +#define DNS_RRTYPE_NS 2 /* an authoritative name server */ +#define DNS_RRTYPE_MD 3 /* a mail destination (Obsolete - use MX) */ +#define DNS_RRTYPE_MF 4 /* a mail forwarder (Obsolete - use MX) */ +#define DNS_RRTYPE_CNAME 5 /* the canonical name for an alias */ +#define DNS_RRTYPE_SOA 6 /* marks the start of a zone of authority */ +#define DNS_RRTYPE_MB 7 /* a mailbox domain name (EXPERIMENTAL) */ +#define DNS_RRTYPE_MG 8 /* a mail group member (EXPERIMENTAL) */ +#define DNS_RRTYPE_MR 9 /* a mail rename domain name (EXPERIMENTAL) */ +#define DNS_RRTYPE_NULL 10 /* a null RR (EXPERIMENTAL) */ +#define DNS_RRTYPE_WKS 11 /* a well known service description */ +#define DNS_RRTYPE_PTR 12 /* a domain name pointer */ +#define DNS_RRTYPE_HINFO 13 /* host information */ +#define DNS_RRTYPE_MINFO 14 /* mailbox or mail list information */ +#define DNS_RRTYPE_MX 15 /* mail exchange */ +#define DNS_RRTYPE_TXT 16 /* text strings */ + +/** DNS field CLASS used for "Resource Records" */ +#define DNS_RRCLASS_IN 1 /* the Internet */ +#define DNS_RRCLASS_CS 2 /* the CSNET class (Obsolete - used only for examples in some obsolete RFCs) */ +#define DNS_RRCLASS_CH 3 /* the CHAOS class */ +#define DNS_RRCLASS_HS 4 /* Hesiod [Dyer 87] */ +#define DNS_RRCLASS_FLUSH 0x800 /* Flush bit */ + +/* The size used for the next line is rather a hack, but it prevents including socket.h in all files + that include memp.h, and that would possibly break portability (since socket.h defines some types + and constants possibly already define by the OS). + Calculation rule: + sizeof(struct addrinfo) + sizeof(struct sockaddr_in) + DNS_MAX_NAME_LENGTH + 1 byte zero-termination */ +#define NETDB_ELEM_SIZE (32 + 16 + DNS_MAX_NAME_LENGTH + 1) + +#if DNS_LOCAL_HOSTLIST +/** struct used for local host-list */ +struct local_hostlist_entry { + /** static hostname */ + const char *name; + /** static host address in network byteorder */ + ip_addr_t addr; + struct local_hostlist_entry *next; +}; +#if DNS_LOCAL_HOSTLIST_IS_DYNAMIC +#ifndef DNS_LOCAL_HOSTLIST_MAX_NAMELEN +#define DNS_LOCAL_HOSTLIST_MAX_NAMELEN DNS_MAX_NAME_LENGTH +#endif +#define LOCALHOSTLIST_ELEM_SIZE ((sizeof(struct local_hostlist_entry) + DNS_LOCAL_HOSTLIST_MAX_NAMELEN + 1)) +#endif /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC */ +#endif /* DNS_LOCAL_HOSTLIST */ + +/** Callback which is invoked when a hostname is found. + * A function of this type must be implemented by the application using the DNS resolver. + * @param name pointer to the name that was looked up. + * @param ipaddr pointer to an ip_addr_t containing the IP address of the hostname, + * or NULL if the name could not be found (or on any other error). + * @param callback_arg a user-specified callback argument passed to dns_gethostbyname +*/ +typedef void (*dns_found_callback)(const char *name, ip_addr_t *ipaddr, void *callback_arg); + +void dns_init(void); +void dns_tmr(void); +void dns_setserver(u8_t numdns, ip_addr_t *dnsserver); +ip_addr_t dns_getserver(u8_t numdns); +err_t dns_gethostbyname(const char *hostname, ip_addr_t *addr, + dns_found_callback found, void *callback_arg); + +#if DNS_LOCAL_HOSTLIST && DNS_LOCAL_HOSTLIST_IS_DYNAMIC +int dns_local_removehost(const char *hostname, const ip_addr_t *addr); +err_t dns_local_addhost(const char *hostname, const ip_addr_t *addr); +#endif /* DNS_LOCAL_HOSTLIST && DNS_LOCAL_HOSTLIST_IS_DYNAMIC */ + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_DNS */ + +#endif /* __LWIP_DNS_H__ */ diff --git a/src/lwip-1.4.1/src/include/lwip/err.h b/src/lwip-1.4.1/src/include/lwip/err.h new file mode 100644 index 0000000..ac90772 --- /dev/null +++ b/src/lwip-1.4.1/src/include/lwip/err.h @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __LWIP_ERR_H__ +#define __LWIP_ERR_H__ + +#include "lwip/opt.h" +#include "lwip/arch.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** Define LWIP_ERR_T in cc.h if you want to use + * a different type for your platform (must be signed). */ +#ifdef LWIP_ERR_T +typedef LWIP_ERR_T err_t; +#else /* LWIP_ERR_T */ +typedef s8_t err_t; +#endif /* LWIP_ERR_T*/ + +/* Definitions for error constants. */ + +#define ERR_OK 0 /* No error, everything OK. */ +#define ERR_MEM -1 /* Out of memory error. */ +#define ERR_BUF -2 /* Buffer error. */ +#define ERR_TIMEOUT -3 /* Timeout. */ +#define ERR_RTE -4 /* Routing problem. */ +#define ERR_INPROGRESS -5 /* Operation in progress */ +#define ERR_VAL -6 /* Illegal value. */ +#define ERR_WOULDBLOCK -7 /* Operation would block. */ +#define ERR_USE -8 /* Address in use. */ +#define ERR_ISCONN -9 /* Already connected. */ + +#define ERR_IS_FATAL(e) ((e) < ERR_ISCONN) + +#define ERR_ABRT -10 /* Connection aborted. */ +#define ERR_RST -11 /* Connection reset. */ +#define ERR_CLSD -12 /* Connection closed. */ +#define ERR_CONN -13 /* Not connected. */ + +#define ERR_ARG -14 /* Illegal argument. */ + +#define ERR_IF -15 /* Low-level netif error */ + + +#ifdef LWIP_DEBUG +extern const char *lwip_strerr(err_t err); +#else +#define lwip_strerr(x) "" +#endif /* LWIP_DEBUG */ + +#ifdef __cplusplus +} +#endif + +#endif /* __LWIP_ERR_H__ */ diff --git a/src/lwip-1.4.1/src/include/lwip/init.h b/src/lwip-1.4.1/src/include/lwip/init.h new file mode 100644 index 0000000..3238534 --- /dev/null +++ b/src/lwip-1.4.1/src/include/lwip/init.h @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __LWIP_INIT_H__ +#define __LWIP_INIT_H__ + +#include "lwip/opt.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** X.x.x: Major version of the stack */ +#define LWIP_VERSION_MAJOR 1U +/** x.X.x: Minor version of the stack */ +#define LWIP_VERSION_MINOR 4U +/** x.x.X: Revision of the stack */ +#define LWIP_VERSION_REVISION 1U +/** For release candidates, this is set to 1..254 + * For official releases, this is set to 255 (LWIP_RC_RELEASE) + * For development versions (CVS), this is set to 0 (LWIP_RC_DEVELOPMENT) */ +#define LWIP_VERSION_RC 255U + +/** LWIP_VERSION_RC is set to LWIP_RC_RELEASE for official releases */ +#define LWIP_RC_RELEASE 255U +/** LWIP_VERSION_RC is set to LWIP_RC_DEVELOPMENT for CVS versions */ +#define LWIP_RC_DEVELOPMENT 0U + +#define LWIP_VERSION_IS_RELEASE (LWIP_VERSION_RC == LWIP_RC_RELEASE) +#define LWIP_VERSION_IS_DEVELOPMENT (LWIP_VERSION_RC == LWIP_RC_DEVELOPMENT) +#define LWIP_VERSION_IS_RC ((LWIP_VERSION_RC != LWIP_RC_RELEASE) && (LWIP_VERSION_RC != LWIP_RC_DEVELOPMENT)) + +/** Provides the version of the stack */ +#define LWIP_VERSION (LWIP_VERSION_MAJOR << 24 | LWIP_VERSION_MINOR << 16 | \ + LWIP_VERSION_REVISION << 8 | LWIP_VERSION_RC) + +/* Modules initialization */ +void lwip_init(void); + +#ifdef __cplusplus +} +#endif + +#endif /* __LWIP_INIT_H__ */ diff --git a/src/lwip-1.4.1/src/include/lwip/mem.h b/src/lwip-1.4.1/src/include/lwip/mem.h new file mode 100644 index 0000000..5bb906b --- /dev/null +++ b/src/lwip-1.4.1/src/include/lwip/mem.h @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __LWIP_MEM_H__ +#define __LWIP_MEM_H__ + +#include "lwip/opt.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if MEM_LIBC_MALLOC + +#include /* for size_t */ + +typedef size_t mem_size_t; +#define MEM_SIZE_F SZT_F + +/* aliases for C library malloc() */ +#define mem_init() +/* in case C library malloc() needs extra protection, + * allow these defines to be overridden. + */ +#ifndef mem_free +#define mem_free free +#endif +#ifndef mem_malloc +#define mem_malloc malloc +#endif +#ifndef mem_calloc +#define mem_calloc calloc +#endif +/* Since there is no C library allocation function to shrink memory without + moving it, define this to nothing. */ +#ifndef mem_trim +#define mem_trim(mem, size) (mem) +#endif +#else /* MEM_LIBC_MALLOC */ + +/* MEM_SIZE would have to be aligned, but using 64000 here instead of + * 65535 leaves some room for alignment... + */ +#if MEM_SIZE > 64000L +typedef u32_t mem_size_t; +#define MEM_SIZE_F U32_F +#else +typedef u16_t mem_size_t; +#define MEM_SIZE_F U16_F +#endif /* MEM_SIZE > 64000 */ + +#if MEM_USE_POOLS +/** mem_init is not used when using pools instead of a heap */ +#define mem_init() +/** mem_trim is not used when using pools instead of a heap: + we can't free part of a pool element and don't want to copy the rest */ +#define mem_trim(mem, size) (mem) +#else /* MEM_USE_POOLS */ +/* lwIP alternative malloc */ +void mem_init(void); +void *mem_trim(void *mem, mem_size_t size); +#endif /* MEM_USE_POOLS */ +void *mem_malloc(mem_size_t size); +void *mem_calloc(mem_size_t count, mem_size_t size); +void mem_free(void *mem); +#endif /* MEM_LIBC_MALLOC */ + +/** Calculate memory size for an aligned buffer - returns the next highest + * multiple of MEM_ALIGNMENT (e.g. LWIP_MEM_ALIGN_SIZE(3) and + * LWIP_MEM_ALIGN_SIZE(4) will both yield 4 for MEM_ALIGNMENT == 4). + */ +#ifndef LWIP_MEM_ALIGN_SIZE +#define LWIP_MEM_ALIGN_SIZE(size) (((size) + MEM_ALIGNMENT - 1) & ~(MEM_ALIGNMENT-1)) +#endif + +/** Calculate safe memory size for an aligned buffer when using an unaligned + * type as storage. This includes a safety-margin on (MEM_ALIGNMENT - 1) at the + * start (e.g. if buffer is u8_t[] and actual data will be u32_t*) + */ +#ifndef LWIP_MEM_ALIGN_BUFFER +#define LWIP_MEM_ALIGN_BUFFER(size) (((size) + MEM_ALIGNMENT - 1)) +#endif + +/** Align a memory pointer to the alignment defined by MEM_ALIGNMENT + * so that ADDR % MEM_ALIGNMENT == 0 + */ +#ifndef LWIP_MEM_ALIGN +#define LWIP_MEM_ALIGN(addr) ((void *)(((mem_ptr_t)(addr) + MEM_ALIGNMENT - 1) & ~(mem_ptr_t)(MEM_ALIGNMENT-1))) +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* __LWIP_MEM_H__ */ diff --git a/src/lwip-1.4.1/src/include/lwip/memp.h b/src/lwip-1.4.1/src/include/lwip/memp.h new file mode 100644 index 0000000..f0d0739 --- /dev/null +++ b/src/lwip-1.4.1/src/include/lwip/memp.h @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#ifndef __LWIP_MEMP_H__ +#define __LWIP_MEMP_H__ + +#include "lwip/opt.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Create the list of all memory pools managed by memp. MEMP_MAX represents a NULL pool at the end */ +typedef enum { +#define LWIP_MEMPOOL(name,num,size,desc) MEMP_##name, +#include "lwip/memp_std.h" + MEMP_MAX +} memp_t; + +#if MEM_USE_POOLS +/* Use a helper type to get the start and end of the user "memory pools" for mem_malloc */ +typedef enum { + /* Get the first (via: + MEMP_POOL_HELPER_START = ((u8_t) 1*MEMP_POOL_A + 0*MEMP_POOL_B + 0*MEMP_POOL_C + 0)*/ + MEMP_POOL_HELPER_FIRST = ((u8_t) +#define LWIP_MEMPOOL(name,num,size,desc) +#define LWIP_MALLOC_MEMPOOL_START 1 +#define LWIP_MALLOC_MEMPOOL(num, size) * MEMP_POOL_##size + 0 +#define LWIP_MALLOC_MEMPOOL_END +#include "lwip/memp_std.h" + ) , + /* Get the last (via: + MEMP_POOL_HELPER_END = ((u8_t) 0 + MEMP_POOL_A*0 + MEMP_POOL_B*0 + MEMP_POOL_C*1) */ + MEMP_POOL_HELPER_LAST = ((u8_t) +#define LWIP_MEMPOOL(name,num,size,desc) +#define LWIP_MALLOC_MEMPOOL_START +#define LWIP_MALLOC_MEMPOOL(num, size) 0 + MEMP_POOL_##size * +#define LWIP_MALLOC_MEMPOOL_END 1 +#include "lwip/memp_std.h" + ) +} memp_pool_helper_t; + +/* The actual start and stop values are here (cast them over) + We use this helper type and these defines so we can avoid using const memp_t values */ +#define MEMP_POOL_FIRST ((memp_t) MEMP_POOL_HELPER_FIRST) +#define MEMP_POOL_LAST ((memp_t) MEMP_POOL_HELPER_LAST) +#endif /* MEM_USE_POOLS */ + +#if MEMP_MEM_MALLOC || MEM_USE_POOLS +extern const u16_t memp_sizes[MEMP_MAX]; +#endif /* MEMP_MEM_MALLOC || MEM_USE_POOLS */ + +#if MEMP_MEM_MALLOC + +#include "mem.h" + +#define memp_init() +#define memp_malloc(type) mem_malloc(memp_sizes[type]) +#define memp_free(type, mem) mem_free(mem) + +#else /* MEMP_MEM_MALLOC */ + +#if MEM_USE_POOLS +/** This structure is used to save the pool one element came from. */ +struct memp_malloc_helper +{ + memp_t poolnr; +}; +#endif /* MEM_USE_POOLS */ + +void memp_init(void); + +#if MEMP_OVERFLOW_CHECK +void *memp_malloc_fn(memp_t type, const char* file, const int line); +#define memp_malloc(t) memp_malloc_fn((t), __FILE__, __LINE__) +#else +void *memp_malloc(memp_t type); +#endif +void memp_free(memp_t type, void *mem); + +#endif /* MEMP_MEM_MALLOC */ + +#ifdef __cplusplus +} +#endif + +#endif /* __LWIP_MEMP_H__ */ diff --git a/src/lwip-1.4.1/src/include/lwip/memp_std.h b/src/lwip-1.4.1/src/include/lwip/memp_std.h new file mode 100644 index 0000000..461ed1a --- /dev/null +++ b/src/lwip-1.4.1/src/include/lwip/memp_std.h @@ -0,0 +1,122 @@ +/* + * SETUP: Make sure we define everything we will need. + * + * We have create three types of pools: + * 1) MEMPOOL - standard pools + * 2) MALLOC_MEMPOOL - to be used by mem_malloc in mem.c + * 3) PBUF_MEMPOOL - a mempool of pbuf's, so include space for the pbuf struct + * + * If the include'r doesn't require any special treatment of each of the types + * above, then will declare #2 & #3 to be just standard mempools. + */ +#ifndef LWIP_MALLOC_MEMPOOL +/* This treats "malloc pools" just like any other pool. + The pools are a little bigger to provide 'size' as the amount of user data. */ +#define LWIP_MALLOC_MEMPOOL(num, size) LWIP_MEMPOOL(POOL_##size, num, (size + sizeof(struct memp_malloc_helper)), "MALLOC_"#size) +#define LWIP_MALLOC_MEMPOOL_START +#define LWIP_MALLOC_MEMPOOL_END +#endif /* LWIP_MALLOC_MEMPOOL */ + +#ifndef LWIP_PBUF_MEMPOOL +/* This treats "pbuf pools" just like any other pool. + * Allocates buffers for a pbuf struct AND a payload size */ +#define LWIP_PBUF_MEMPOOL(name, num, payload, desc) LWIP_MEMPOOL(name, num, (MEMP_ALIGN_SIZE(sizeof(struct pbuf)) + MEMP_ALIGN_SIZE(payload)), desc) +#endif /* LWIP_PBUF_MEMPOOL */ + + +/* + * A list of internal pools used by LWIP. + * + * LWIP_MEMPOOL(pool_name, number_elements, element_size, pool_description) + * creates a pool name MEMP_pool_name. description is used in stats.c + */ +#if LWIP_RAW +LWIP_MEMPOOL(RAW_PCB, MEMP_NUM_RAW_PCB, sizeof(struct raw_pcb), "RAW_PCB") +#endif /* LWIP_RAW */ + +#if LWIP_UDP +LWIP_MEMPOOL(UDP_PCB, MEMP_NUM_UDP_PCB, sizeof(struct udp_pcb), "UDP_PCB") +#endif /* LWIP_UDP */ + +#if LWIP_TCP +LWIP_MEMPOOL(TCP_PCB, MEMP_NUM_TCP_PCB, sizeof(struct tcp_pcb), "TCP_PCB") +LWIP_MEMPOOL(TCP_PCB_LISTEN, MEMP_NUM_TCP_PCB_LISTEN, sizeof(struct tcp_pcb_listen), "TCP_PCB_LISTEN") +LWIP_MEMPOOL(TCP_SEG, MEMP_NUM_TCP_SEG, sizeof(struct tcp_seg), "TCP_SEG") +#endif /* LWIP_TCP */ + +#if IP_REASSEMBLY +LWIP_MEMPOOL(REASSDATA, MEMP_NUM_REASSDATA, sizeof(struct ip_reassdata), "REASSDATA") +#endif /* IP_REASSEMBLY */ +#if IP_FRAG && !IP_FRAG_USES_STATIC_BUF && !LWIP_NETIF_TX_SINGLE_PBUF +LWIP_MEMPOOL(FRAG_PBUF, MEMP_NUM_FRAG_PBUF, sizeof(struct pbuf_custom_ref),"FRAG_PBUF") +#endif /* IP_FRAG && !IP_FRAG_USES_STATIC_BUF && !LWIP_NETIF_TX_SINGLE_PBUF */ + +#if LWIP_NETCONN +LWIP_MEMPOOL(NETBUF, MEMP_NUM_NETBUF, sizeof(struct netbuf), "NETBUF") +LWIP_MEMPOOL(NETCONN, MEMP_NUM_NETCONN, sizeof(struct netconn), "NETCONN") +#endif /* LWIP_NETCONN */ + +#if NO_SYS==0 +LWIP_MEMPOOL(TCPIP_MSG_API, MEMP_NUM_TCPIP_MSG_API, sizeof(struct tcpip_msg), "TCPIP_MSG_API") +#if !LWIP_TCPIP_CORE_LOCKING_INPUT +LWIP_MEMPOOL(TCPIP_MSG_INPKT,MEMP_NUM_TCPIP_MSG_INPKT, sizeof(struct tcpip_msg), "TCPIP_MSG_INPKT") +#endif /* !LWIP_TCPIP_CORE_LOCKING_INPUT */ +#endif /* NO_SYS==0 */ + +#if LWIP_ARP && ARP_QUEUEING +LWIP_MEMPOOL(ARP_QUEUE, MEMP_NUM_ARP_QUEUE, sizeof(struct etharp_q_entry), "ARP_QUEUE") +#endif /* LWIP_ARP && ARP_QUEUEING */ + +#if LWIP_IGMP +LWIP_MEMPOOL(IGMP_GROUP, MEMP_NUM_IGMP_GROUP, sizeof(struct igmp_group), "IGMP_GROUP") +#endif /* LWIP_IGMP */ + +#if (!NO_SYS || (NO_SYS && !NO_SYS_NO_TIMERS)) /* LWIP_TIMERS */ +LWIP_MEMPOOL(SYS_TIMEOUT, MEMP_NUM_SYS_TIMEOUT, sizeof(struct sys_timeo), "SYS_TIMEOUT") +#endif /* LWIP_TIMERS */ + +#if LWIP_SNMP +LWIP_MEMPOOL(SNMP_ROOTNODE, MEMP_NUM_SNMP_ROOTNODE, sizeof(struct mib_list_rootnode), "SNMP_ROOTNODE") +LWIP_MEMPOOL(SNMP_NODE, MEMP_NUM_SNMP_NODE, sizeof(struct mib_list_node), "SNMP_NODE") +LWIP_MEMPOOL(SNMP_VARBIND, MEMP_NUM_SNMP_VARBIND, sizeof(struct snmp_varbind), "SNMP_VARBIND") +LWIP_MEMPOOL(SNMP_VALUE, MEMP_NUM_SNMP_VALUE, SNMP_MAX_VALUE_SIZE, "SNMP_VALUE") +#endif /* LWIP_SNMP */ +#if LWIP_DNS && LWIP_SOCKET +LWIP_MEMPOOL(NETDB, MEMP_NUM_NETDB, NETDB_ELEM_SIZE, "NETDB") +#endif /* LWIP_DNS && LWIP_SOCKET */ +#if LWIP_DNS && DNS_LOCAL_HOSTLIST && DNS_LOCAL_HOSTLIST_IS_DYNAMIC +LWIP_MEMPOOL(LOCALHOSTLIST, MEMP_NUM_LOCALHOSTLIST, LOCALHOSTLIST_ELEM_SIZE, "LOCALHOSTLIST") +#endif /* LWIP_DNS && DNS_LOCAL_HOSTLIST && DNS_LOCAL_HOSTLIST_IS_DYNAMIC */ +#if PPP_SUPPORT && PPPOE_SUPPORT +LWIP_MEMPOOL(PPPOE_IF, MEMP_NUM_PPPOE_INTERFACES, sizeof(struct pppoe_softc), "PPPOE_IF") +#endif /* PPP_SUPPORT && PPPOE_SUPPORT */ + +/* + * A list of pools of pbuf's used by LWIP. + * + * LWIP_PBUF_MEMPOOL(pool_name, number_elements, pbuf_payload_size, pool_description) + * creates a pool name MEMP_pool_name. description is used in stats.c + * This allocates enough space for the pbuf struct and a payload. + * (Example: pbuf_payload_size=0 allocates only size for the struct) + */ +LWIP_PBUF_MEMPOOL(PBUF, MEMP_NUM_PBUF, 0, "PBUF_REF/ROM") +LWIP_PBUF_MEMPOOL(PBUF_POOL, PBUF_POOL_SIZE, PBUF_POOL_BUFSIZE, "PBUF_POOL") + + +/* + * Allow for user-defined pools; this must be explicitly set in lwipopts.h + * since the default is to NOT look for lwippools.h + */ +#if MEMP_USE_CUSTOM_POOLS +#include "lwippools.h" +#endif /* MEMP_USE_CUSTOM_POOLS */ + +/* + * REQUIRED CLEANUP: Clear up so we don't get "multiply defined" error later + * (#undef is ignored for something that is not defined) + */ +#undef LWIP_MEMPOOL +#undef LWIP_MALLOC_MEMPOOL +#undef LWIP_MALLOC_MEMPOOL_START +#undef LWIP_MALLOC_MEMPOOL_END +#undef LWIP_PBUF_MEMPOOL diff --git a/src/lwip-1.4.1/src/include/lwip/netbuf.h b/src/lwip-1.4.1/src/include/lwip/netbuf.h new file mode 100644 index 0000000..7d247d7 --- /dev/null +++ b/src/lwip-1.4.1/src/include/lwip/netbuf.h @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __LWIP_NETBUF_H__ +#define __LWIP_NETBUF_H__ + +#include "lwip/opt.h" +#include "lwip/pbuf.h" +#include "lwip/ip_addr.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** This netbuf has dest-addr/port set */ +#define NETBUF_FLAG_DESTADDR 0x01 +/** This netbuf includes a checksum */ +#define NETBUF_FLAG_CHKSUM 0x02 + +struct netbuf { + struct pbuf *p, *ptr; + ip_addr_t addr; + u16_t port; +#if LWIP_NETBUF_RECVINFO || LWIP_CHECKSUM_ON_COPY +#if LWIP_CHECKSUM_ON_COPY + u8_t flags; +#endif /* LWIP_CHECKSUM_ON_COPY */ + u16_t toport_chksum; +#if LWIP_NETBUF_RECVINFO + ip_addr_t toaddr; +#endif /* LWIP_NETBUF_RECVINFO */ +#endif /* LWIP_NETBUF_RECVINFO || LWIP_CHECKSUM_ON_COPY */ +}; + +/* Network buffer functions: */ +struct netbuf * netbuf_new (void); +void netbuf_delete (struct netbuf *buf); +void * netbuf_alloc (struct netbuf *buf, u16_t size); +void netbuf_free (struct netbuf *buf); +err_t netbuf_ref (struct netbuf *buf, + const void *dataptr, u16_t size); +void netbuf_chain (struct netbuf *head, + struct netbuf *tail); + +err_t netbuf_data (struct netbuf *buf, + void **dataptr, u16_t *len); +s8_t netbuf_next (struct netbuf *buf); +void netbuf_first (struct netbuf *buf); + + +#define netbuf_copy_partial(buf, dataptr, len, offset) \ + pbuf_copy_partial((buf)->p, (dataptr), (len), (offset)) +#define netbuf_copy(buf,dataptr,len) netbuf_copy_partial(buf, dataptr, len, 0) +#define netbuf_take(buf, dataptr, len) pbuf_take((buf)->p, dataptr, len) +#define netbuf_len(buf) ((buf)->p->tot_len) +#define netbuf_fromaddr(buf) (&((buf)->addr)) +#define netbuf_set_fromaddr(buf, fromaddr) ip_addr_set((&(buf)->addr), fromaddr) +#define netbuf_fromport(buf) ((buf)->port) +#if LWIP_NETBUF_RECVINFO +#define netbuf_destaddr(buf) (&((buf)->toaddr)) +#define netbuf_set_destaddr(buf, destaddr) ip_addr_set((&(buf)->addr), destaddr) +#define netbuf_destport(buf) (((buf)->flags & NETBUF_FLAG_DESTADDR) ? (buf)->toport_chksum : 0) +#endif /* LWIP_NETBUF_RECVINFO */ +#if LWIP_CHECKSUM_ON_COPY +#define netbuf_set_chksum(buf, chksum) do { (buf)->flags = NETBUF_FLAG_CHKSUM; \ + (buf)->toport_chksum = chksum; } while(0) +#endif /* LWIP_CHECKSUM_ON_COPY */ + +#ifdef __cplusplus +} +#endif + +#endif /* __LWIP_NETBUF_H__ */ diff --git a/src/lwip-1.4.1/src/include/lwip/netdb.h b/src/lwip-1.4.1/src/include/lwip/netdb.h new file mode 100644 index 0000000..7587e2f --- /dev/null +++ b/src/lwip-1.4.1/src/include/lwip/netdb.h @@ -0,0 +1,124 @@ +/* + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Simon Goldschmidt + * + */ +#ifndef __LWIP_NETDB_H__ +#define __LWIP_NETDB_H__ + +#include "lwip/opt.h" + +#if LWIP_DNS && LWIP_SOCKET + +#include /* for size_t */ + +#include "lwip/inet.h" +#include "lwip/sockets.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* some rarely used options */ +#ifndef LWIP_DNS_API_DECLARE_H_ERRNO +#define LWIP_DNS_API_DECLARE_H_ERRNO 1 +#endif + +#ifndef LWIP_DNS_API_DEFINE_ERRORS +#define LWIP_DNS_API_DEFINE_ERRORS 1 +#endif + +#ifndef LWIP_DNS_API_DECLARE_STRUCTS +#define LWIP_DNS_API_DECLARE_STRUCTS 1 +#endif + +#if LWIP_DNS_API_DEFINE_ERRORS +/** Errors used by the DNS API functions, h_errno can be one of them */ +#define EAI_NONAME 200 +#define EAI_SERVICE 201 +#define EAI_FAIL 202 +#define EAI_MEMORY 203 + +#define HOST_NOT_FOUND 210 +#define NO_DATA 211 +#define NO_RECOVERY 212 +#define TRY_AGAIN 213 +#endif /* LWIP_DNS_API_DEFINE_ERRORS */ + +#if LWIP_DNS_API_DECLARE_STRUCTS +struct hostent { + char *h_name; /* Official name of the host. */ + char **h_aliases; /* A pointer to an array of pointers to alternative host names, + terminated by a null pointer. */ + int h_addrtype; /* Address type. */ + int h_length; /* The length, in bytes, of the address. */ + char **h_addr_list; /* A pointer to an array of pointers to network addresses (in + network byte order) for the host, terminated by a null pointer. */ +#define h_addr h_addr_list[0] /* for backward compatibility */ +}; + +struct addrinfo { + int ai_flags; /* Input flags. */ + int ai_family; /* Address family of socket. */ + int ai_socktype; /* Socket type. */ + int ai_protocol; /* Protocol of socket. */ + socklen_t ai_addrlen; /* Length of socket address. */ + struct sockaddr *ai_addr; /* Socket address of socket. */ + char *ai_canonname; /* Canonical name of service location. */ + struct addrinfo *ai_next; /* Pointer to next in list. */ +}; +#endif /* LWIP_DNS_API_DECLARE_STRUCTS */ + +#if LWIP_DNS_API_DECLARE_H_ERRNO +/* application accessable error code set by the DNS API functions */ +extern int h_errno; +#endif /* LWIP_DNS_API_DECLARE_H_ERRNO*/ + +struct hostent *lwip_gethostbyname(const char *name); +int lwip_gethostbyname_r(const char *name, struct hostent *ret, char *buf, + size_t buflen, struct hostent **result, int *h_errnop); +void lwip_freeaddrinfo(struct addrinfo *ai); +int lwip_getaddrinfo(const char *nodename, + const char *servname, + const struct addrinfo *hints, + struct addrinfo **res); + +#if LWIP_COMPAT_SOCKETS +#define gethostbyname(name) lwip_gethostbyname(name) +#define gethostbyname_r(name, ret, buf, buflen, result, h_errnop) \ + lwip_gethostbyname_r(name, ret, buf, buflen, result, h_errnop) +#define freeaddrinfo(addrinfo) lwip_freeaddrinfo(addrinfo) +#define getaddrinfo(nodname, servname, hints, res) \ + lwip_getaddrinfo(nodname, servname, hints, res) +#endif /* LWIP_COMPAT_SOCKETS */ + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_DNS && LWIP_SOCKET */ + +#endif /* __LWIP_NETDB_H__ */ diff --git a/src/lwip-1.4.1/src/include/lwip/netif.h b/src/lwip-1.4.1/src/include/lwip/netif.h new file mode 100644 index 0000000..f7e4937 --- /dev/null +++ b/src/lwip-1.4.1/src/include/lwip/netif.h @@ -0,0 +1,328 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __LWIP_NETIF_H__ +#define __LWIP_NETIF_H__ + +#include "lwip/opt.h" + +#define ENABLE_LOOPBACK (LWIP_NETIF_LOOPBACK || LWIP_HAVE_LOOPIF) + +#include "lwip/err.h" + +#include "lwip/ip_addr.h" + +#include "lwip/def.h" +#include "lwip/pbuf.h" +#if LWIP_DHCP +struct dhcp; +#endif +#if LWIP_AUTOIP +struct autoip; +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* Throughout this file, IP addresses are expected to be in + * the same byte order as in IP_PCB. */ + +/** must be the maximum of all used hardware address lengths + across all types of interfaces in use */ +#define NETIF_MAX_HWADDR_LEN 6U + +/** Whether the network interface is 'up'. This is + * a software flag used to control whether this network + * interface is enabled and processes traffic. + * It is set by the startup code (for static IP configuration) or + * by dhcp/autoip when an address has been assigned. + */ +#define NETIF_FLAG_UP 0x01U +/** If set, the netif has broadcast capability. + * Set by the netif driver in its init function. */ +#define NETIF_FLAG_BROADCAST 0x02U +/** If set, the netif is one end of a point-to-point connection. + * Set by the netif driver in its init function. */ +#define NETIF_FLAG_POINTTOPOINT 0x04U +/** If set, the interface is configured using DHCP. + * Set by the DHCP code when starting or stopping DHCP. */ +#define NETIF_FLAG_DHCP 0x08U +/** If set, the interface has an active link + * (set by the network interface driver). + * Either set by the netif driver in its init function (if the link + * is up at that time) or at a later point once the link comes up + * (if link detection is supported by the hardware). */ +#define NETIF_FLAG_LINK_UP 0x10U +/** If set, the netif is an ethernet device using ARP. + * Set by the netif driver in its init function. + * Used to check input packet types and use of DHCP. */ +#define NETIF_FLAG_ETHARP 0x20U +/** If set, the netif is an ethernet device. It might not use + * ARP or TCP/IP if it is used for PPPoE only. + */ +#define NETIF_FLAG_ETHERNET 0x40U +/** If set, the netif has IGMP capability. + * Set by the netif driver in its init function. */ +#define NETIF_FLAG_IGMP 0x80U + +/** Function prototype for netif init functions. Set up flags and output/linkoutput + * callback functions in this function. + * + * @param netif The netif to initialize + */ +typedef err_t (*netif_init_fn)(struct netif *netif); +/** Function prototype for netif->input functions. This function is saved as 'input' + * callback function in the netif struct. Call it when a packet has been received. + * + * @param p The received packet, copied into a pbuf + * @param inp The netif which received the packet + */ +typedef err_t (*netif_input_fn)(struct pbuf *p, struct netif *inp); +/** Function prototype for netif->output functions. Called by lwIP when a packet + * shall be sent. For ethernet netif, set this to 'etharp_output' and set + * 'linkoutput'. + * + * @param netif The netif which shall send a packet + * @param p The packet to send (p->payload points to IP header) + * @param ipaddr The IP address to which the packet shall be sent + */ +typedef err_t (*netif_output_fn)(struct netif *netif, struct pbuf *p, + ip_addr_t *ipaddr); +/** Function prototype for netif->linkoutput functions. Only used for ethernet + * netifs. This function is called by ARP when a packet shall be sent. + * + * @param netif The netif which shall send a packet + * @param p The packet to send (raw ethernet packet) + */ +typedef err_t (*netif_linkoutput_fn)(struct netif *netif, struct pbuf *p); +/** Function prototype for netif status- or link-callback functions. */ +typedef void (*netif_status_callback_fn)(struct netif *netif); +/** Function prototype for netif igmp_mac_filter functions */ +typedef err_t (*netif_igmp_mac_filter_fn)(struct netif *netif, + ip_addr_t *group, u8_t action); + +/** Generic data structure used for all lwIP network interfaces. + * The following fields should be filled in by the initialization + * function for the device driver: hwaddr_len, hwaddr[], mtu, flags */ +struct netif { + /** pointer to next in linked list */ + struct netif *next; + + /** IP address configuration in network byte order */ + ip_addr_t ip_addr; + ip_addr_t netmask; + ip_addr_t gw; + + /** This function is called by the network device driver + * to pass a packet up the TCP/IP stack. */ + netif_input_fn input; + /** This function is called by the IP module when it wants + * to send a packet on the interface. This function typically + * first resolves the hardware address, then sends the packet. */ + netif_output_fn output; + /** This function is called by the ARP module when it wants + * to send a packet on the interface. This function outputs + * the pbuf as-is on the link medium. */ + netif_linkoutput_fn linkoutput; +#if LWIP_NETIF_STATUS_CALLBACK + /** This function is called when the netif state is set to up or down + */ + netif_status_callback_fn status_callback; +#endif /* LWIP_NETIF_STATUS_CALLBACK */ +#if LWIP_NETIF_LINK_CALLBACK + /** This function is called when the netif link is set to up or down + */ + netif_status_callback_fn link_callback; +#endif /* LWIP_NETIF_LINK_CALLBACK */ +#if LWIP_NETIF_REMOVE_CALLBACK + /** This function is called when the netif has been removed */ + netif_status_callback_fn remove_callback; +#endif /* LWIP_NETIF_REMOVE_CALLBACK */ + /** This field can be set by the device driver and could point + * to state information for the device. */ + void *state; +#if LWIP_DHCP + /** the DHCP client state information for this netif */ + struct dhcp *dhcp; +#endif /* LWIP_DHCP */ +#if LWIP_AUTOIP + /** the AutoIP client state information for this netif */ + struct autoip *autoip; +#endif +#if LWIP_NETIF_HOSTNAME + /* the hostname for this netif, NULL is a valid value */ + char* hostname; +#endif /* LWIP_NETIF_HOSTNAME */ + /** maximum transfer unit (in bytes) */ + u16_t mtu; + /** number of bytes used in hwaddr */ + u8_t hwaddr_len; + /** link level hardware address of this interface */ + u8_t hwaddr[NETIF_MAX_HWADDR_LEN]; + /** flags (see NETIF_FLAG_ above) */ + u8_t flags; + /** descriptive abbreviation */ + char name[2]; + /** number of this interface */ + u8_t num; +#if LWIP_SNMP + /** link type (from "snmp_ifType" enum from snmp.h) */ + u8_t link_type; + /** (estimate) link speed */ + u32_t link_speed; + /** timestamp at last change made (up/down) */ + u32_t ts; + /** counters */ + u32_t ifinoctets; + u32_t ifinucastpkts; + u32_t ifinnucastpkts; + u32_t ifindiscards; + u32_t ifoutoctets; + u32_t ifoutucastpkts; + u32_t ifoutnucastpkts; + u32_t ifoutdiscards; +#endif /* LWIP_SNMP */ +#if LWIP_IGMP + /** This function could be called to add or delete a entry in the multicast + filter table of the ethernet MAC.*/ + netif_igmp_mac_filter_fn igmp_mac_filter; +#endif /* LWIP_IGMP */ +#if LWIP_NETIF_HWADDRHINT + u8_t *addr_hint; +#endif /* LWIP_NETIF_HWADDRHINT */ +#if ENABLE_LOOPBACK + /* List of packets to be queued for ourselves. */ + struct pbuf *loop_first; + struct pbuf *loop_last; +#if LWIP_LOOPBACK_MAX_PBUFS + u16_t loop_cnt_current; +#endif /* LWIP_LOOPBACK_MAX_PBUFS */ +#endif /* ENABLE_LOOPBACK */ +}; + +#if LWIP_SNMP +#define NETIF_INIT_SNMP(netif, type, speed) \ + /* use "snmp_ifType" enum from snmp.h for "type", snmp_ifType_ethernet_csmacd by example */ \ + (netif)->link_type = (type); \ + /* your link speed here (units: bits per second) */ \ + (netif)->link_speed = (speed); \ + (netif)->ts = 0; \ + (netif)->ifinoctets = 0; \ + (netif)->ifinucastpkts = 0; \ + (netif)->ifinnucastpkts = 0; \ + (netif)->ifindiscards = 0; \ + (netif)->ifoutoctets = 0; \ + (netif)->ifoutucastpkts = 0; \ + (netif)->ifoutnucastpkts = 0; \ + (netif)->ifoutdiscards = 0 +#else /* LWIP_SNMP */ +#define NETIF_INIT_SNMP(netif, type, speed) +#endif /* LWIP_SNMP */ + + +/** The list of network interfaces. */ +extern struct netif *netif_list; +/** The default network interface. */ +extern struct netif *netif_default; + +void netif_init(void); + +struct netif *netif_add(struct netif *netif, ip_addr_t *ipaddr, ip_addr_t *netmask, + ip_addr_t *gw, void *state, netif_init_fn init, netif_input_fn input); + +void +netif_set_addr(struct netif *netif, ip_addr_t *ipaddr, ip_addr_t *netmask, + ip_addr_t *gw); +void netif_remove(struct netif * netif); + +/* Returns a network interface given its name. The name is of the form + "et0", where the first two letters are the "name" field in the + netif structure, and the digit is in the num field in the same + structure. */ +struct netif *netif_find(char *name); + +void netif_set_default(struct netif *netif); + +void netif_set_ipaddr(struct netif *netif, ip_addr_t *ipaddr); +void netif_set_netmask(struct netif *netif, ip_addr_t *netmask); +void netif_set_gw(struct netif *netif, ip_addr_t *gw); + +void netif_set_up(struct netif *netif); +void netif_set_down(struct netif *netif); +/** Ask if an interface is up */ +#define netif_is_up(netif) (((netif)->flags & NETIF_FLAG_UP) ? (u8_t)1 : (u8_t)0) + +#if LWIP_NETIF_STATUS_CALLBACK +void netif_set_status_callback(struct netif *netif, netif_status_callback_fn status_callback); +#endif /* LWIP_NETIF_STATUS_CALLBACK */ +#if LWIP_NETIF_REMOVE_CALLBACK +void netif_set_remove_callback(struct netif *netif, netif_status_callback_fn remove_callback); +#endif /* LWIP_NETIF_REMOVE_CALLBACK */ + +void netif_set_link_up(struct netif *netif); +void netif_set_link_down(struct netif *netif); +/** Ask if a link is up */ +#define netif_is_link_up(netif) (((netif)->flags & NETIF_FLAG_LINK_UP) ? (u8_t)1 : (u8_t)0) + +#if LWIP_NETIF_LINK_CALLBACK +void netif_set_link_callback(struct netif *netif, netif_status_callback_fn link_callback); +#endif /* LWIP_NETIF_LINK_CALLBACK */ + +#if LWIP_NETIF_HOSTNAME +#define netif_set_hostname(netif, name) do { if((netif) != NULL) { (netif)->hostname = name; }}while(0) +#define netif_get_hostname(netif) (((netif) != NULL) ? ((netif)->hostname) : NULL) +#endif /* LWIP_NETIF_HOSTNAME */ + +#if LWIP_IGMP +#define netif_set_igmp_mac_filter(netif, function) do { if((netif) != NULL) { (netif)->igmp_mac_filter = function; }}while(0) +#define netif_get_igmp_mac_filter(netif) (((netif) != NULL) ? ((netif)->igmp_mac_filter) : NULL) +#endif /* LWIP_IGMP */ + +#if ENABLE_LOOPBACK +err_t netif_loop_output(struct netif *netif, struct pbuf *p, ip_addr_t *dest_ip); +void netif_poll(struct netif *netif); +#if !LWIP_NETIF_LOOPBACK_MULTITHREADING +void netif_poll_all(void); +#endif /* !LWIP_NETIF_LOOPBACK_MULTITHREADING */ +#endif /* ENABLE_LOOPBACK */ + +#if LWIP_NETIF_HWADDRHINT +#define NETIF_SET_HWADDRHINT(netif, hint) ((netif)->addr_hint = (hint)) +#else /* LWIP_NETIF_HWADDRHINT */ +#define NETIF_SET_HWADDRHINT(netif, hint) +#endif /* LWIP_NETIF_HWADDRHINT */ + +#ifdef __cplusplus +} +#endif + +#endif /* __LWIP_NETIF_H__ */ diff --git a/src/lwip-1.4.1/src/include/lwip/netifapi.h b/src/lwip-1.4.1/src/include/lwip/netifapi.h new file mode 100644 index 0000000..33318ef --- /dev/null +++ b/src/lwip-1.4.1/src/include/lwip/netifapi.h @@ -0,0 +1,108 @@ +/* + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * This file is part of the lwIP TCP/IP stack. + * + */ + +#ifndef __LWIP_NETIFAPI_H__ +#define __LWIP_NETIFAPI_H__ + +#include "lwip/opt.h" + +#if LWIP_NETIF_API /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/sys.h" +#include "lwip/netif.h" +#include "lwip/dhcp.h" +#include "lwip/autoip.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void (*netifapi_void_fn)(struct netif *netif); +typedef err_t (*netifapi_errt_fn)(struct netif *netif); + +struct netifapi_msg_msg { +#if !LWIP_TCPIP_CORE_LOCKING + sys_sem_t sem; +#endif /* !LWIP_TCPIP_CORE_LOCKING */ + err_t err; + struct netif *netif; + union { + struct { + ip_addr_t *ipaddr; + ip_addr_t *netmask; + ip_addr_t *gw; + void *state; + netif_init_fn init; + netif_input_fn input; + } add; + struct { + netifapi_void_fn voidfunc; + netifapi_errt_fn errtfunc; + } common; + } msg; +}; + +struct netifapi_msg { + void (* function)(struct netifapi_msg_msg *msg); + struct netifapi_msg_msg msg; +}; + + +/* API for application */ +err_t netifapi_netif_add ( struct netif *netif, + ip_addr_t *ipaddr, + ip_addr_t *netmask, + ip_addr_t *gw, + void *state, + netif_init_fn init, + netif_input_fn input); + +err_t netifapi_netif_set_addr ( struct netif *netif, + ip_addr_t *ipaddr, + ip_addr_t *netmask, + ip_addr_t *gw ); + +err_t netifapi_netif_common ( struct netif *netif, + netifapi_void_fn voidfunc, + netifapi_errt_fn errtfunc); + +#define netifapi_netif_remove(n) netifapi_netif_common(n, netif_remove, NULL) +#define netifapi_netif_set_up(n) netifapi_netif_common(n, netif_set_up, NULL) +#define netifapi_netif_set_down(n) netifapi_netif_common(n, netif_set_down, NULL) +#define netifapi_netif_set_default(n) netifapi_netif_common(n, netif_set_default, NULL) +#define netifapi_dhcp_start(n) netifapi_netif_common(n, NULL, dhcp_start) +#define netifapi_dhcp_stop(n) netifapi_netif_common(n, dhcp_stop, NULL) +#define netifapi_autoip_start(n) netifapi_netif_common(n, NULL, autoip_start) +#define netifapi_autoip_stop(n) netifapi_netif_common(n, NULL, autoip_stop) + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_NETIF_API */ + +#endif /* __LWIP_NETIFAPI_H__ */ diff --git a/src/lwip-1.4.1/src/include/lwip/opt.h b/src/lwip-1.4.1/src/include/lwip/opt.h new file mode 100644 index 0000000..b7726cd --- /dev/null +++ b/src/lwip-1.4.1/src/include/lwip/opt.h @@ -0,0 +1,2133 @@ +/** + * @file + * + * lwIP Options Configuration + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __LWIP_OPT_H__ +#define __LWIP_OPT_H__ + +/* + * Include user defined options first. Anything not defined in these files + * will be set to standard values. Override anything you dont like! + */ +#include "lwipopts.h" +#include "lwip/debug.h" + +/* + ----------------------------------------------- + ---------- Platform specific locking ---------- + ----------------------------------------------- +*/ + +/** + * SYS_LIGHTWEIGHT_PROT==1: if you want inter-task protection for certain + * critical regions during buffer allocation, deallocation and memory + * allocation and deallocation. + */ +#ifndef SYS_LIGHTWEIGHT_PROT +#define SYS_LIGHTWEIGHT_PROT 0 +#endif + +/** + * NO_SYS==1: Provides VERY minimal functionality. Otherwise, + * use lwIP facilities. + */ +#ifndef NO_SYS +#define NO_SYS 0 +#endif + +/** + * NO_SYS_NO_TIMERS==1: Drop support for sys_timeout when NO_SYS==1 + * Mainly for compatibility to old versions. + */ +#ifndef NO_SYS_NO_TIMERS +#define NO_SYS_NO_TIMERS 0 +#endif + +/** + * MEMCPY: override this if you have a faster implementation at hand than the + * one included in your C library + */ +#ifndef MEMCPY +#define MEMCPY(dst,src,len) memcpy(dst,src,len) +#endif + +/** + * SMEMCPY: override this with care! Some compilers (e.g. gcc) can inline a + * call to memcpy() if the length is known at compile time and is small. + */ +#ifndef SMEMCPY +#define SMEMCPY(dst,src,len) memcpy(dst,src,len) +#endif + +/* + ------------------------------------ + ---------- Memory options ---------- + ------------------------------------ +*/ +/** + * MEM_LIBC_MALLOC==1: Use malloc/free/realloc provided by your C-library + * instead of the lwip internal allocator. Can save code size if you + * already use it. + */ +#ifndef MEM_LIBC_MALLOC +#define MEM_LIBC_MALLOC 0 +#endif + +/** +* MEMP_MEM_MALLOC==1: Use mem_malloc/mem_free instead of the lwip pool allocator. +* Especially useful with MEM_LIBC_MALLOC but handle with care regarding execution +* speed and usage from interrupts! +*/ +#ifndef MEMP_MEM_MALLOC +#define MEMP_MEM_MALLOC 0 +#endif + +/** + * MEM_ALIGNMENT: should be set to the alignment of the CPU + * 4 byte alignment -> #define MEM_ALIGNMENT 4 + * 2 byte alignment -> #define MEM_ALIGNMENT 2 + */ +#ifndef MEM_ALIGNMENT +#define MEM_ALIGNMENT 1 +#endif + +/** + * MEM_SIZE: the size of the heap memory. If the application will send + * a lot of data that needs to be copied, this should be set high. + */ +#ifndef MEM_SIZE +#define MEM_SIZE 1600 +#endif + +/** + * MEMP_SEPARATE_POOLS: if defined to 1, each pool is placed in its own array. + * This can be used to individually change the location of each pool. + * Default is one big array for all pools + */ +#ifndef MEMP_SEPARATE_POOLS +#define MEMP_SEPARATE_POOLS 0 +#endif + +/** + * MEMP_OVERFLOW_CHECK: memp overflow protection reserves a configurable + * amount of bytes before and after each memp element in every pool and fills + * it with a prominent default value. + * MEMP_OVERFLOW_CHECK == 0 no checking + * MEMP_OVERFLOW_CHECK == 1 checks each element when it is freed + * MEMP_OVERFLOW_CHECK >= 2 checks each element in every pool every time + * memp_malloc() or memp_free() is called (useful but slow!) + */ +#ifndef MEMP_OVERFLOW_CHECK +#define MEMP_OVERFLOW_CHECK 0 +#endif + +/** + * MEMP_SANITY_CHECK==1: run a sanity check after each memp_free() to make + * sure that there are no cycles in the linked lists. + */ +#ifndef MEMP_SANITY_CHECK +#define MEMP_SANITY_CHECK 0 +#endif + +/** + * MEM_USE_POOLS==1: Use an alternative to malloc() by allocating from a set + * of memory pools of various sizes. When mem_malloc is called, an element of + * the smallest pool that can provide the length needed is returned. + * To use this, MEMP_USE_CUSTOM_POOLS also has to be enabled. + */ +#ifndef MEM_USE_POOLS +#define MEM_USE_POOLS 0 +#endif + +/** + * MEM_USE_POOLS_TRY_BIGGER_POOL==1: if one malloc-pool is empty, try the next + * bigger pool - WARNING: THIS MIGHT WASTE MEMORY but it can make a system more + * reliable. */ +#ifndef MEM_USE_POOLS_TRY_BIGGER_POOL +#define MEM_USE_POOLS_TRY_BIGGER_POOL 0 +#endif + +/** + * MEMP_USE_CUSTOM_POOLS==1: whether to include a user file lwippools.h + * that defines additional pools beyond the "standard" ones required + * by lwIP. If you set this to 1, you must have lwippools.h in your + * inlude path somewhere. + */ +#ifndef MEMP_USE_CUSTOM_POOLS +#define MEMP_USE_CUSTOM_POOLS 0 +#endif + +/** + * Set this to 1 if you want to free PBUF_RAM pbufs (or call mem_free()) from + * interrupt context (or another context that doesn't allow waiting for a + * semaphore). + * If set to 1, mem_malloc will be protected by a semaphore and SYS_ARCH_PROTECT, + * while mem_free will only use SYS_ARCH_PROTECT. mem_malloc SYS_ARCH_UNPROTECTs + * with each loop so that mem_free can run. + * + * ATTENTION: As you can see from the above description, this leads to dis-/ + * enabling interrupts often, which can be slow! Also, on low memory, mem_malloc + * can need longer. + * + * If you don't want that, at least for NO_SYS=0, you can still use the following + * functions to enqueue a deallocation call which then runs in the tcpip_thread + * context: + * - pbuf_free_callback(p); + * - mem_free_callback(m); + */ +#ifndef LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT +#define LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT 0 +#endif + +/* + ------------------------------------------------ + ---------- Internal Memory Pool Sizes ---------- + ------------------------------------------------ +*/ +/** + * MEMP_NUM_PBUF: the number of memp struct pbufs (used for PBUF_ROM and PBUF_REF). + * If the application sends a lot of data out of ROM (or other static memory), + * this should be set high. + */ +#ifndef MEMP_NUM_PBUF +#define MEMP_NUM_PBUF 16 +#endif + +/** + * MEMP_NUM_RAW_PCB: Number of raw connection PCBs + * (requires the LWIP_RAW option) + */ +#ifndef MEMP_NUM_RAW_PCB +#define MEMP_NUM_RAW_PCB 4 +#endif + +/** + * MEMP_NUM_UDP_PCB: the number of UDP protocol control blocks. One + * per active UDP "connection". + * (requires the LWIP_UDP option) + */ +#ifndef MEMP_NUM_UDP_PCB +#define MEMP_NUM_UDP_PCB 4 +#endif + +/** + * MEMP_NUM_TCP_PCB: the number of simulatenously active TCP connections. + * (requires the LWIP_TCP option) + */ +#ifndef MEMP_NUM_TCP_PCB +#define MEMP_NUM_TCP_PCB 5 +#endif + +/** + * MEMP_NUM_TCP_PCB_LISTEN: the number of listening TCP connections. + * (requires the LWIP_TCP option) + */ +#ifndef MEMP_NUM_TCP_PCB_LISTEN +#define MEMP_NUM_TCP_PCB_LISTEN 8 +#endif + +/** + * MEMP_NUM_TCP_SEG: the number of simultaneously queued TCP segments. + * (requires the LWIP_TCP option) + */ +#ifndef MEMP_NUM_TCP_SEG +#define MEMP_NUM_TCP_SEG 16 +#endif + +/** + * MEMP_NUM_REASSDATA: the number of IP packets simultaneously queued for + * reassembly (whole packets, not fragments!) + */ +#ifndef MEMP_NUM_REASSDATA +#define MEMP_NUM_REASSDATA 5 +#endif + +/** + * MEMP_NUM_FRAG_PBUF: the number of IP fragments simultaneously sent + * (fragments, not whole packets!). + * This is only used with IP_FRAG_USES_STATIC_BUF==0 and + * LWIP_NETIF_TX_SINGLE_PBUF==0 and only has to be > 1 with DMA-enabled MACs + * where the packet is not yet sent when netif->output returns. + */ +#ifndef MEMP_NUM_FRAG_PBUF +#define MEMP_NUM_FRAG_PBUF 15 +#endif + +/** + * MEMP_NUM_ARP_QUEUE: the number of simulateously queued outgoing + * packets (pbufs) that are waiting for an ARP request (to resolve + * their destination address) to finish. + * (requires the ARP_QUEUEING option) + */ +#ifndef MEMP_NUM_ARP_QUEUE +#define MEMP_NUM_ARP_QUEUE 30 +#endif + +/** + * MEMP_NUM_IGMP_GROUP: The number of multicast groups whose network interfaces + * can be members et the same time (one per netif - allsystems group -, plus one + * per netif membership). + * (requires the LWIP_IGMP option) + */ +#ifndef MEMP_NUM_IGMP_GROUP +#define MEMP_NUM_IGMP_GROUP 8 +#endif + +/** + * MEMP_NUM_SYS_TIMEOUT: the number of simulateously active timeouts. + * (requires NO_SYS==0) + * The default number of timeouts is calculated here for all enabled modules. + * The formula expects settings to be either '0' or '1'. + */ +#ifndef MEMP_NUM_SYS_TIMEOUT +#define MEMP_NUM_SYS_TIMEOUT (LWIP_TCP + IP_REASSEMBLY + LWIP_ARP + (2*LWIP_DHCP) + LWIP_AUTOIP + LWIP_IGMP + LWIP_DNS + PPP_SUPPORT) +#endif + +/** + * MEMP_NUM_NETBUF: the number of struct netbufs. + * (only needed if you use the sequential API, like api_lib.c) + */ +#ifndef MEMP_NUM_NETBUF +#define MEMP_NUM_NETBUF 2 +#endif + +/** + * MEMP_NUM_NETCONN: the number of struct netconns. + * (only needed if you use the sequential API, like api_lib.c) + */ +#ifndef MEMP_NUM_NETCONN +#define MEMP_NUM_NETCONN 4 +#endif + +/** + * MEMP_NUM_TCPIP_MSG_API: the number of struct tcpip_msg, which are used + * for callback/timeout API communication. + * (only needed if you use tcpip.c) + */ +#ifndef MEMP_NUM_TCPIP_MSG_API +#define MEMP_NUM_TCPIP_MSG_API 8 +#endif + +/** + * MEMP_NUM_TCPIP_MSG_INPKT: the number of struct tcpip_msg, which are used + * for incoming packets. + * (only needed if you use tcpip.c) + */ +#ifndef MEMP_NUM_TCPIP_MSG_INPKT +#define MEMP_NUM_TCPIP_MSG_INPKT 8 +#endif + +/** + * MEMP_NUM_SNMP_NODE: the number of leafs in the SNMP tree. + */ +#ifndef MEMP_NUM_SNMP_NODE +#define MEMP_NUM_SNMP_NODE 50 +#endif + +/** + * MEMP_NUM_SNMP_ROOTNODE: the number of branches in the SNMP tree. + * Every branch has one leaf (MEMP_NUM_SNMP_NODE) at least! + */ +#ifndef MEMP_NUM_SNMP_ROOTNODE +#define MEMP_NUM_SNMP_ROOTNODE 30 +#endif + +/** + * MEMP_NUM_SNMP_VARBIND: the number of concurrent requests (does not have to + * be changed normally) - 2 of these are used per request (1 for input, + * 1 for output) + */ +#ifndef MEMP_NUM_SNMP_VARBIND +#define MEMP_NUM_SNMP_VARBIND 2 +#endif + +/** + * MEMP_NUM_SNMP_VALUE: the number of OID or values concurrently used + * (does not have to be changed normally) - 3 of these are used per request + * (1 for the value read and 2 for OIDs - input and output) + */ +#ifndef MEMP_NUM_SNMP_VALUE +#define MEMP_NUM_SNMP_VALUE 3 +#endif + +/** + * MEMP_NUM_NETDB: the number of concurrently running lwip_addrinfo() calls + * (before freeing the corresponding memory using lwip_freeaddrinfo()). + */ +#ifndef MEMP_NUM_NETDB +#define MEMP_NUM_NETDB 1 +#endif + +/** + * MEMP_NUM_LOCALHOSTLIST: the number of host entries in the local host list + * if DNS_LOCAL_HOSTLIST_IS_DYNAMIC==1. + */ +#ifndef MEMP_NUM_LOCALHOSTLIST +#define MEMP_NUM_LOCALHOSTLIST 1 +#endif + +/** + * MEMP_NUM_PPPOE_INTERFACES: the number of concurrently active PPPoE + * interfaces (only used with PPPOE_SUPPORT==1) + */ +#ifndef MEMP_NUM_PPPOE_INTERFACES +#define MEMP_NUM_PPPOE_INTERFACES 1 +#endif + +/** + * PBUF_POOL_SIZE: the number of buffers in the pbuf pool. + */ +#ifndef PBUF_POOL_SIZE +#define PBUF_POOL_SIZE 4 +#endif + +/* + --------------------------------- + ---------- ARP options ---------- + --------------------------------- +*/ +/** + * LWIP_ARP==1: Enable ARP functionality. + */ +#ifndef LWIP_ARP +#define LWIP_ARP 1 +#endif + +/** + * ARP_TABLE_SIZE: Number of active MAC-IP address pairs cached. + */ +#ifndef ARP_TABLE_SIZE +#define ARP_TABLE_SIZE 10 +#endif + +/** + * ARP_QUEUEING==1: Multiple outgoing packets are queued during hardware address + * resolution. By default, only the most recent packet is queued per IP address. + * This is sufficient for most protocols and mainly reduces TCP connection + * startup time. Set this to 1 if you know your application sends more than one + * packet in a row to an IP address that is not in the ARP cache. + */ +#ifndef ARP_QUEUEING +#define ARP_QUEUEING 0 +#endif + +/** + * ETHARP_TRUST_IP_MAC==1: Incoming IP packets cause the ARP table to be + * updated with the source MAC and IP addresses supplied in the packet. + * You may want to disable this if you do not trust LAN peers to have the + * correct addresses, or as a limited approach to attempt to handle + * spoofing. If disabled, lwIP will need to make a new ARP request if + * the peer is not already in the ARP table, adding a little latency. + * The peer *is* in the ARP table if it requested our address before. + * Also notice that this slows down input processing of every IP packet! + */ +#ifndef ETHARP_TRUST_IP_MAC +#define ETHARP_TRUST_IP_MAC 0 +#endif + +/** + * ETHARP_SUPPORT_VLAN==1: support receiving ethernet packets with VLAN header. + * Additionally, you can define ETHARP_VLAN_CHECK to an u16_t VLAN ID to check. + * If ETHARP_VLAN_CHECK is defined, only VLAN-traffic for this VLAN is accepted. + * If ETHARP_VLAN_CHECK is not defined, all traffic is accepted. + * Alternatively, define a function/define ETHARP_VLAN_CHECK_FN(eth_hdr, vlan) + * that returns 1 to accept a packet or 0 to drop a packet. + */ +#ifndef ETHARP_SUPPORT_VLAN +#define ETHARP_SUPPORT_VLAN 0 +#endif + +/** LWIP_ETHERNET==1: enable ethernet support for PPPoE even though ARP + * might be disabled + */ +#ifndef LWIP_ETHERNET +#define LWIP_ETHERNET (LWIP_ARP || PPPOE_SUPPORT) +#endif + +/** ETH_PAD_SIZE: number of bytes added before the ethernet header to ensure + * alignment of payload after that header. Since the header is 14 bytes long, + * without this padding e.g. addresses in the IP header will not be aligned + * on a 32-bit boundary, so setting this to 2 can speed up 32-bit-platforms. + */ +#ifndef ETH_PAD_SIZE +#define ETH_PAD_SIZE 0 +#endif + +/** ETHARP_SUPPORT_STATIC_ENTRIES==1: enable code to support static ARP table + * entries (using etharp_add_static_entry/etharp_remove_static_entry). + */ +#ifndef ETHARP_SUPPORT_STATIC_ENTRIES +#define ETHARP_SUPPORT_STATIC_ENTRIES 0 +#endif + + +/* + -------------------------------- + ---------- IP options ---------- + -------------------------------- +*/ +/** + * IP_FORWARD==1: Enables the ability to forward IP packets across network + * interfaces. If you are going to run lwIP on a device with only one network + * interface, define this to 0. + */ +#ifndef IP_FORWARD +#define IP_FORWARD 0 +#endif + +/** + * IP_OPTIONS_ALLOWED: Defines the behavior for IP options. + * IP_OPTIONS_ALLOWED==0: All packets with IP options are dropped. + * IP_OPTIONS_ALLOWED==1: IP options are allowed (but not parsed). + */ +#ifndef IP_OPTIONS_ALLOWED +#define IP_OPTIONS_ALLOWED 1 +#endif + +/** + * IP_REASSEMBLY==1: Reassemble incoming fragmented IP packets. Note that + * this option does not affect outgoing packet sizes, which can be controlled + * via IP_FRAG. + */ +#ifndef IP_REASSEMBLY +#define IP_REASSEMBLY 1 +#endif + +/** + * IP_FRAG==1: Fragment outgoing IP packets if their size exceeds MTU. Note + * that this option does not affect incoming packet sizes, which can be + * controlled via IP_REASSEMBLY. + */ +#ifndef IP_FRAG +#define IP_FRAG 1 +#endif + +/** + * IP_REASS_MAXAGE: Maximum time (in multiples of IP_TMR_INTERVAL - so seconds, normally) + * a fragmented IP packet waits for all fragments to arrive. If not all fragments arrived + * in this time, the whole packet is discarded. + */ +#ifndef IP_REASS_MAXAGE +#define IP_REASS_MAXAGE 3 +#endif + +/** + * IP_REASS_MAX_PBUFS: Total maximum amount of pbufs waiting to be reassembled. + * Since the received pbufs are enqueued, be sure to configure + * PBUF_POOL_SIZE > IP_REASS_MAX_PBUFS so that the stack is still able to receive + * packets even if the maximum amount of fragments is enqueued for reassembly! + */ +#ifndef IP_REASS_MAX_PBUFS +#define IP_REASS_MAX_PBUFS 10 +#endif + +/** + * IP_FRAG_USES_STATIC_BUF==1: Use a static MTU-sized buffer for IP + * fragmentation. Otherwise pbufs are allocated and reference the original + * packet data to be fragmented (or with LWIP_NETIF_TX_SINGLE_PBUF==1, + * new PBUF_RAM pbufs are used for fragments). + * ATTENTION: IP_FRAG_USES_STATIC_BUF==1 may not be used for DMA-enabled MACs! + */ +#ifndef IP_FRAG_USES_STATIC_BUF +#define IP_FRAG_USES_STATIC_BUF 0 +#endif + +/** + * IP_FRAG_MAX_MTU: Assumed max MTU on any interface for IP frag buffer + * (requires IP_FRAG_USES_STATIC_BUF==1) + */ +#if IP_FRAG_USES_STATIC_BUF && !defined(IP_FRAG_MAX_MTU) +#define IP_FRAG_MAX_MTU 1500 +#endif + +/** + * IP_DEFAULT_TTL: Default value for Time-To-Live used by transport layers. + */ +#ifndef IP_DEFAULT_TTL +#define IP_DEFAULT_TTL 255 +#endif + +/** + * IP_SOF_BROADCAST=1: Use the SOF_BROADCAST field to enable broadcast + * filter per pcb on udp and raw send operations. To enable broadcast filter + * on recv operations, you also have to set IP_SOF_BROADCAST_RECV=1. + */ +#ifndef IP_SOF_BROADCAST +#define IP_SOF_BROADCAST 0 +#endif + +/** + * IP_SOF_BROADCAST_RECV (requires IP_SOF_BROADCAST=1) enable the broadcast + * filter on recv operations. + */ +#ifndef IP_SOF_BROADCAST_RECV +#define IP_SOF_BROADCAST_RECV 0 +#endif + +/** + * IP_FORWARD_ALLOW_TX_ON_RX_NETIF==1: allow ip_forward() to send packets back + * out on the netif where it was received. This should only be used for + * wireless networks. + * ATTENTION: When this is 1, make sure your netif driver correctly marks incoming + * link-layer-broadcast/multicast packets as such using the corresponding pbuf flags! + */ +#ifndef IP_FORWARD_ALLOW_TX_ON_RX_NETIF +#define IP_FORWARD_ALLOW_TX_ON_RX_NETIF 0 +#endif + +/** + * LWIP_RANDOMIZE_INITIAL_LOCAL_PORTS==1: randomize the local port for the first + * local TCP/UDP pcb (default==0). This can prevent creating predictable port + * numbers after booting a device. + */ +#ifndef LWIP_RANDOMIZE_INITIAL_LOCAL_PORTS +#define LWIP_RANDOMIZE_INITIAL_LOCAL_PORTS 0 +#endif + +/* + ---------------------------------- + ---------- ICMP options ---------- + ---------------------------------- +*/ +/** + * LWIP_ICMP==1: Enable ICMP module inside the IP stack. + * Be careful, disable that make your product non-compliant to RFC1122 + */ +#ifndef LWIP_ICMP +#define LWIP_ICMP 1 +#endif + +/** + * ICMP_TTL: Default value for Time-To-Live used by ICMP packets. + */ +#ifndef ICMP_TTL +#define ICMP_TTL (IP_DEFAULT_TTL) +#endif + +/** + * LWIP_BROADCAST_PING==1: respond to broadcast pings (default is unicast only) + */ +#ifndef LWIP_BROADCAST_PING +#define LWIP_BROADCAST_PING 0 +#endif + +/** + * LWIP_MULTICAST_PING==1: respond to multicast pings (default is unicast only) + */ +#ifndef LWIP_MULTICAST_PING +#define LWIP_MULTICAST_PING 0 +#endif + +/* + --------------------------------- + ---------- RAW options ---------- + --------------------------------- +*/ +/** + * LWIP_RAW==1: Enable application layer to hook into the IP layer itself. + */ +#ifndef LWIP_RAW +#define LWIP_RAW 1 +#endif + +/** + * LWIP_RAW==1: Enable application layer to hook into the IP layer itself. + */ +#ifndef RAW_TTL +#define RAW_TTL (IP_DEFAULT_TTL) +#endif + +/* + ---------------------------------- + ---------- DHCP options ---------- + ---------------------------------- +*/ +/** + * LWIP_DHCP==1: Enable DHCP module. + */ +#ifndef LWIP_DHCP +#define LWIP_DHCP 0 +#endif + +/** + * DHCP_DOES_ARP_CHECK==1: Do an ARP check on the offered address. + */ +#ifndef DHCP_DOES_ARP_CHECK +#define DHCP_DOES_ARP_CHECK ((LWIP_DHCP) && (LWIP_ARP)) +#endif + +/* + ------------------------------------ + ---------- AUTOIP options ---------- + ------------------------------------ +*/ +/** + * LWIP_AUTOIP==1: Enable AUTOIP module. + */ +#ifndef LWIP_AUTOIP +#define LWIP_AUTOIP 0 +#endif + +/** + * LWIP_DHCP_AUTOIP_COOP==1: Allow DHCP and AUTOIP to be both enabled on + * the same interface at the same time. + */ +#ifndef LWIP_DHCP_AUTOIP_COOP +#define LWIP_DHCP_AUTOIP_COOP 0 +#endif + +/** + * LWIP_DHCP_AUTOIP_COOP_TRIES: Set to the number of DHCP DISCOVER probes + * that should be sent before falling back on AUTOIP. This can be set + * as low as 1 to get an AutoIP address very quickly, but you should + * be prepared to handle a changing IP address when DHCP overrides + * AutoIP. + */ +#ifndef LWIP_DHCP_AUTOIP_COOP_TRIES +#define LWIP_DHCP_AUTOIP_COOP_TRIES 9 +#endif + +/* + ---------------------------------- + ---------- SNMP options ---------- + ---------------------------------- +*/ +/** + * LWIP_SNMP==1: Turn on SNMP module. UDP must be available for SNMP + * transport. + */ +#ifndef LWIP_SNMP +#define LWIP_SNMP 0 +#endif + +/** + * SNMP_CONCURRENT_REQUESTS: Number of concurrent requests the module will + * allow. At least one request buffer is required. + * Does not have to be changed unless external MIBs answer request asynchronously + */ +#ifndef SNMP_CONCURRENT_REQUESTS +#define SNMP_CONCURRENT_REQUESTS 1 +#endif + +/** + * SNMP_TRAP_DESTINATIONS: Number of trap destinations. At least one trap + * destination is required + */ +#ifndef SNMP_TRAP_DESTINATIONS +#define SNMP_TRAP_DESTINATIONS 1 +#endif + +/** + * SNMP_PRIVATE_MIB: + * When using a private MIB, you have to create a file 'private_mib.h' that contains + * a 'struct mib_array_node mib_private' which contains your MIB. + */ +#ifndef SNMP_PRIVATE_MIB +#define SNMP_PRIVATE_MIB 0 +#endif + +/** + * Only allow SNMP write actions that are 'safe' (e.g. disabeling netifs is not + * a safe action and disabled when SNMP_SAFE_REQUESTS = 1). + * Unsafe requests are disabled by default! + */ +#ifndef SNMP_SAFE_REQUESTS +#define SNMP_SAFE_REQUESTS 1 +#endif + +/** + * The maximum length of strings used. This affects the size of + * MEMP_SNMP_VALUE elements. + */ +#ifndef SNMP_MAX_OCTET_STRING_LEN +#define SNMP_MAX_OCTET_STRING_LEN 127 +#endif + +/** + * The maximum depth of the SNMP tree. + * With private MIBs enabled, this depends on your MIB! + * This affects the size of MEMP_SNMP_VALUE elements. + */ +#ifndef SNMP_MAX_TREE_DEPTH +#define SNMP_MAX_TREE_DEPTH 15 +#endif + +/** + * The size of the MEMP_SNMP_VALUE elements, normally calculated from + * SNMP_MAX_OCTET_STRING_LEN and SNMP_MAX_TREE_DEPTH. + */ +#ifndef SNMP_MAX_VALUE_SIZE +#define SNMP_MAX_VALUE_SIZE LWIP_MAX((SNMP_MAX_OCTET_STRING_LEN)+1, sizeof(s32_t)*(SNMP_MAX_TREE_DEPTH)) +#endif + +/* + ---------------------------------- + ---------- IGMP options ---------- + ---------------------------------- +*/ +/** + * LWIP_IGMP==1: Turn on IGMP module. + */ +#ifndef LWIP_IGMP +#define LWIP_IGMP 0 +#endif + +/* + ---------------------------------- + ---------- DNS options ----------- + ---------------------------------- +*/ +/** + * LWIP_DNS==1: Turn on DNS module. UDP must be available for DNS + * transport. + */ +#ifndef LWIP_DNS +#define LWIP_DNS 0 +#endif + +/** DNS maximum number of entries to maintain locally. */ +#ifndef DNS_TABLE_SIZE +#define DNS_TABLE_SIZE 4 +#endif + +/** DNS maximum host name length supported in the name table. */ +#ifndef DNS_MAX_NAME_LENGTH +#define DNS_MAX_NAME_LENGTH 256 +#endif + +/** The maximum of DNS servers */ +#ifndef DNS_MAX_SERVERS +#define DNS_MAX_SERVERS 2 +#endif + +/** DNS do a name checking between the query and the response. */ +#ifndef DNS_DOES_NAME_CHECK +#define DNS_DOES_NAME_CHECK 1 +#endif + +/** DNS message max. size. Default value is RFC compliant. */ +#ifndef DNS_MSG_SIZE +#define DNS_MSG_SIZE 512 +#endif + +/** DNS_LOCAL_HOSTLIST: Implements a local host-to-address list. If enabled, + * you have to define + * #define DNS_LOCAL_HOSTLIST_INIT {{"host1", 0x123}, {"host2", 0x234}} + * (an array of structs name/address, where address is an u32_t in network + * byte order). + * + * Instead, you can also use an external function: + * #define DNS_LOOKUP_LOCAL_EXTERN(x) extern u32_t my_lookup_function(const char *name) + * that returns the IP address or INADDR_NONE if not found. + */ +#ifndef DNS_LOCAL_HOSTLIST +#define DNS_LOCAL_HOSTLIST 0 +#endif /* DNS_LOCAL_HOSTLIST */ + +/** If this is turned on, the local host-list can be dynamically changed + * at runtime. */ +#ifndef DNS_LOCAL_HOSTLIST_IS_DYNAMIC +#define DNS_LOCAL_HOSTLIST_IS_DYNAMIC 0 +#endif /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC */ + +/* + --------------------------------- + ---------- UDP options ---------- + --------------------------------- +*/ +/** + * LWIP_UDP==1: Turn on UDP. + */ +#ifndef LWIP_UDP +#define LWIP_UDP 1 +#endif + +/** + * LWIP_UDPLITE==1: Turn on UDP-Lite. (Requires LWIP_UDP) + */ +#ifndef LWIP_UDPLITE +#define LWIP_UDPLITE 0 +#endif + +/** + * UDP_TTL: Default Time-To-Live value. + */ +#ifndef UDP_TTL +#define UDP_TTL (IP_DEFAULT_TTL) +#endif + +/** + * LWIP_NETBUF_RECVINFO==1: append destination addr and port to every netbuf. + */ +#ifndef LWIP_NETBUF_RECVINFO +#define LWIP_NETBUF_RECVINFO 0 +#endif + +/* + --------------------------------- + ---------- TCP options ---------- + --------------------------------- +*/ +/** + * LWIP_TCP==1: Turn on TCP. + */ +#ifndef LWIP_TCP +#define LWIP_TCP 1 +#endif + +/** + * TCP_TTL: Default Time-To-Live value. + */ +#ifndef TCP_TTL +#define TCP_TTL (IP_DEFAULT_TTL) +#endif + +/** + * TCP_WND: The size of a TCP window. This must be at least + * (2 * TCP_MSS) for things to work well + */ +#ifndef TCP_WND +#define TCP_WND (4 * TCP_MSS) +#endif + +/** + * TCP_MAXRTX: Maximum number of retransmissions of data segments. + */ +#ifndef TCP_MAXRTX +#define TCP_MAXRTX 12 +#endif + +/** + * TCP_SYNMAXRTX: Maximum number of retransmissions of SYN segments. + */ +#ifndef TCP_SYNMAXRTX +#define TCP_SYNMAXRTX 6 +#endif + +/** + * TCP_QUEUE_OOSEQ==1: TCP will queue segments that arrive out of order. + * Define to 0 if your device is low on memory. + */ +#ifndef TCP_QUEUE_OOSEQ +#define TCP_QUEUE_OOSEQ (LWIP_TCP) +#endif + +/** + * TCP_MSS: TCP Maximum segment size. (default is 536, a conservative default, + * you might want to increase this.) + * For the receive side, this MSS is advertised to the remote side + * when opening a connection. For the transmit size, this MSS sets + * an upper limit on the MSS advertised by the remote host. + */ +#ifndef TCP_MSS +#define TCP_MSS 536 +#endif + +/** + * TCP_CALCULATE_EFF_SEND_MSS: "The maximum size of a segment that TCP really + * sends, the 'effective send MSS,' MUST be the smaller of the send MSS (which + * reflects the available reassembly buffer size at the remote host) and the + * largest size permitted by the IP layer" (RFC 1122) + * Setting this to 1 enables code that checks TCP_MSS against the MTU of the + * netif used for a connection and limits the MSS if it would be too big otherwise. + */ +#ifndef TCP_CALCULATE_EFF_SEND_MSS +#define TCP_CALCULATE_EFF_SEND_MSS 1 +#endif + + +/** + * TCP_SND_BUF: TCP sender buffer space (bytes). + * To achieve good performance, this should be at least 2 * TCP_MSS. + */ +#ifndef TCP_SND_BUF +#define TCP_SND_BUF (2 * TCP_MSS) +#endif + +/** + * TCP_SND_QUEUELEN: TCP sender buffer space (pbufs). This must be at least + * as much as (2 * TCP_SND_BUF/TCP_MSS) for things to work. + */ +#ifndef TCP_SND_QUEUELEN +#define TCP_SND_QUEUELEN ((4 * (TCP_SND_BUF) + (TCP_MSS - 1))/(TCP_MSS)) +#endif + +/** + * TCP_SNDLOWAT: TCP writable space (bytes). This must be less than + * TCP_SND_BUF. It is the amount of space which must be available in the + * TCP snd_buf for select to return writable (combined with TCP_SNDQUEUELOWAT). + */ +#ifndef TCP_SNDLOWAT +#define TCP_SNDLOWAT LWIP_MIN(LWIP_MAX(((TCP_SND_BUF)/2), (2 * TCP_MSS) + 1), (TCP_SND_BUF) - 1) +#endif + +/** + * TCP_SNDQUEUELOWAT: TCP writable bufs (pbuf count). This must be less + * than TCP_SND_QUEUELEN. If the number of pbufs queued on a pcb drops below + * this number, select returns writable (combined with TCP_SNDLOWAT). + */ +#ifndef TCP_SNDQUEUELOWAT +#define TCP_SNDQUEUELOWAT LWIP_MAX(((TCP_SND_QUEUELEN)/2), 5) +#endif + +/** + * TCP_OOSEQ_MAX_BYTES: The maximum number of bytes queued on ooseq per pcb. + * Default is 0 (no limit). Only valid for TCP_QUEUE_OOSEQ==0. + */ +#ifndef TCP_OOSEQ_MAX_BYTES +#define TCP_OOSEQ_MAX_BYTES 0 +#endif + +/** + * TCP_OOSEQ_MAX_PBUFS: The maximum number of pbufs queued on ooseq per pcb. + * Default is 0 (no limit). Only valid for TCP_QUEUE_OOSEQ==0. + */ +#ifndef TCP_OOSEQ_MAX_PBUFS +#define TCP_OOSEQ_MAX_PBUFS 0 +#endif + +/** + * TCP_LISTEN_BACKLOG: Enable the backlog option for tcp listen pcb. + */ +#ifndef TCP_LISTEN_BACKLOG +#define TCP_LISTEN_BACKLOG 0 +#endif + +/** + * The maximum allowed backlog for TCP listen netconns. + * This backlog is used unless another is explicitly specified. + * 0xff is the maximum (u8_t). + */ +#ifndef TCP_DEFAULT_LISTEN_BACKLOG +#define TCP_DEFAULT_LISTEN_BACKLOG 0xff +#endif + +/** + * TCP_OVERSIZE: The maximum number of bytes that tcp_write may + * allocate ahead of time in an attempt to create shorter pbuf chains + * for transmission. The meaningful range is 0 to TCP_MSS. Some + * suggested values are: + * + * 0: Disable oversized allocation. Each tcp_write() allocates a new + pbuf (old behaviour). + * 1: Allocate size-aligned pbufs with minimal excess. Use this if your + * scatter-gather DMA requires aligned fragments. + * 128: Limit the pbuf/memory overhead to 20%. + * TCP_MSS: Try to create unfragmented TCP packets. + * TCP_MSS/4: Try to create 4 fragments or less per TCP packet. + */ +#ifndef TCP_OVERSIZE +#define TCP_OVERSIZE TCP_MSS +#endif + +/** + * LWIP_TCP_TIMESTAMPS==1: support the TCP timestamp option. + */ +#ifndef LWIP_TCP_TIMESTAMPS +#define LWIP_TCP_TIMESTAMPS 0 +#endif + +/** + * TCP_WND_UPDATE_THRESHOLD: difference in window to trigger an + * explicit window update + */ +#ifndef TCP_WND_UPDATE_THRESHOLD +#define TCP_WND_UPDATE_THRESHOLD (TCP_WND / 4) +#endif + +/** + * LWIP_EVENT_API and LWIP_CALLBACK_API: Only one of these should be set to 1. + * LWIP_EVENT_API==1: The user defines lwip_tcp_event() to receive all + * events (accept, sent, etc) that happen in the system. + * LWIP_CALLBACK_API==1: The PCB callback function is called directly + * for the event. This is the default. + */ +#if !defined(LWIP_EVENT_API) && !defined(LWIP_CALLBACK_API) +#define LWIP_EVENT_API 0 +#define LWIP_CALLBACK_API 1 +#endif + + +/* + ---------------------------------- + ---------- Pbuf options ---------- + ---------------------------------- +*/ +/** + * PBUF_LINK_HLEN: the number of bytes that should be allocated for a + * link level header. The default is 14, the standard value for + * Ethernet. + */ +#ifndef PBUF_LINK_HLEN +#define PBUF_LINK_HLEN (14 + ETH_PAD_SIZE) +#endif + +/** + * PBUF_POOL_BUFSIZE: the size of each pbuf in the pbuf pool. The default is + * designed to accomodate single full size TCP frame in one pbuf, including + * TCP_MSS, IP header, and link header. + */ +#ifndef PBUF_POOL_BUFSIZE +#define PBUF_POOL_BUFSIZE LWIP_MEM_ALIGN_SIZE(TCP_MSS+40+PBUF_LINK_HLEN) +#endif + +/* + ------------------------------------------------ + ---------- Network Interfaces options ---------- + ------------------------------------------------ +*/ +/** + * LWIP_NETIF_HOSTNAME==1: use DHCP_OPTION_HOSTNAME with netif's hostname + * field. + */ +#ifndef LWIP_NETIF_HOSTNAME +#define LWIP_NETIF_HOSTNAME 0 +#endif + +/** + * LWIP_NETIF_API==1: Support netif api (in netifapi.c) + */ +#ifndef LWIP_NETIF_API +#define LWIP_NETIF_API 0 +#endif + +/** + * LWIP_NETIF_STATUS_CALLBACK==1: Support a callback function whenever an interface + * changes its up/down status (i.e., due to DHCP IP acquistion) + */ +#ifndef LWIP_NETIF_STATUS_CALLBACK +#define LWIP_NETIF_STATUS_CALLBACK 0 +#endif + +/** + * LWIP_NETIF_LINK_CALLBACK==1: Support a callback function from an interface + * whenever the link changes (i.e., link down) + */ +#ifndef LWIP_NETIF_LINK_CALLBACK +#define LWIP_NETIF_LINK_CALLBACK 0 +#endif + +/** + * LWIP_NETIF_REMOVE_CALLBACK==1: Support a callback function that is called + * when a netif has been removed + */ +#ifndef LWIP_NETIF_REMOVE_CALLBACK +#define LWIP_NETIF_REMOVE_CALLBACK 0 +#endif + +/** + * LWIP_NETIF_HWADDRHINT==1: Cache link-layer-address hints (e.g. table + * indices) in struct netif. TCP and UDP can make use of this to prevent + * scanning the ARP table for every sent packet. While this is faster for big + * ARP tables or many concurrent connections, it might be counterproductive + * if you have a tiny ARP table or if there never are concurrent connections. + */ +#ifndef LWIP_NETIF_HWADDRHINT +#define LWIP_NETIF_HWADDRHINT 0 +#endif + +/** + * LWIP_NETIF_LOOPBACK==1: Support sending packets with a destination IP + * address equal to the netif IP address, looping them back up the stack. + */ +#ifndef LWIP_NETIF_LOOPBACK +#define LWIP_NETIF_LOOPBACK 0 +#endif + +/** + * LWIP_LOOPBACK_MAX_PBUFS: Maximum number of pbufs on queue for loopback + * sending for each netif (0 = disabled) + */ +#ifndef LWIP_LOOPBACK_MAX_PBUFS +#define LWIP_LOOPBACK_MAX_PBUFS 0 +#endif + +/** + * LWIP_NETIF_LOOPBACK_MULTITHREADING: Indicates whether threading is enabled in + * the system, as netifs must change how they behave depending on this setting + * for the LWIP_NETIF_LOOPBACK option to work. + * Setting this is needed to avoid reentering non-reentrant functions like + * tcp_input(). + * LWIP_NETIF_LOOPBACK_MULTITHREADING==1: Indicates that the user is using a + * multithreaded environment like tcpip.c. In this case, netif->input() + * is called directly. + * LWIP_NETIF_LOOPBACK_MULTITHREADING==0: Indicates a polling (or NO_SYS) setup. + * The packets are put on a list and netif_poll() must be called in + * the main application loop. + */ +#ifndef LWIP_NETIF_LOOPBACK_MULTITHREADING +#define LWIP_NETIF_LOOPBACK_MULTITHREADING (!NO_SYS) +#endif + +/** + * LWIP_NETIF_TX_SINGLE_PBUF: if this is set to 1, lwIP tries to put all data + * to be sent into one single pbuf. This is for compatibility with DMA-enabled + * MACs that do not support scatter-gather. + * Beware that this might involve CPU-memcpy before transmitting that would not + * be needed without this flag! Use this only if you need to! + * + * @todo: TCP and IP-frag do not work with this, yet: + */ +#ifndef LWIP_NETIF_TX_SINGLE_PBUF +#define LWIP_NETIF_TX_SINGLE_PBUF 0 +#endif /* LWIP_NETIF_TX_SINGLE_PBUF */ + +/* + ------------------------------------ + ---------- LOOPIF options ---------- + ------------------------------------ +*/ +/** + * LWIP_HAVE_LOOPIF==1: Support loop interface (127.0.0.1) and loopif.c + */ +#ifndef LWIP_HAVE_LOOPIF +#define LWIP_HAVE_LOOPIF 0 +#endif + +/* + ------------------------------------ + ---------- SLIPIF options ---------- + ------------------------------------ +*/ +/** + * LWIP_HAVE_SLIPIF==1: Support slip interface and slipif.c + */ +#ifndef LWIP_HAVE_SLIPIF +#define LWIP_HAVE_SLIPIF 0 +#endif + +/* + ------------------------------------ + ---------- Thread options ---------- + ------------------------------------ +*/ +/** + * TCPIP_THREAD_NAME: The name assigned to the main tcpip thread. + */ +#ifndef TCPIP_THREAD_NAME +#define TCPIP_THREAD_NAME "tcpip_thread" +#endif + +/** + * TCPIP_THREAD_STACKSIZE: The stack size used by the main tcpip thread. + * The stack size value itself is platform-dependent, but is passed to + * sys_thread_new() when the thread is created. + */ +#ifndef TCPIP_THREAD_STACKSIZE +#define TCPIP_THREAD_STACKSIZE 0 +#endif + +/** + * TCPIP_THREAD_PRIO: The priority assigned to the main tcpip thread. + * The priority value itself is platform-dependent, but is passed to + * sys_thread_new() when the thread is created. + */ +#ifndef TCPIP_THREAD_PRIO +#define TCPIP_THREAD_PRIO 1 +#endif + +/** + * TCPIP_MBOX_SIZE: The mailbox size for the tcpip thread messages + * The queue size value itself is platform-dependent, but is passed to + * sys_mbox_new() when tcpip_init is called. + */ +#ifndef TCPIP_MBOX_SIZE +#define TCPIP_MBOX_SIZE 0 +#endif + +/** + * SLIPIF_THREAD_NAME: The name assigned to the slipif_loop thread. + */ +#ifndef SLIPIF_THREAD_NAME +#define SLIPIF_THREAD_NAME "slipif_loop" +#endif + +/** + * SLIP_THREAD_STACKSIZE: The stack size used by the slipif_loop thread. + * The stack size value itself is platform-dependent, but is passed to + * sys_thread_new() when the thread is created. + */ +#ifndef SLIPIF_THREAD_STACKSIZE +#define SLIPIF_THREAD_STACKSIZE 0 +#endif + +/** + * SLIPIF_THREAD_PRIO: The priority assigned to the slipif_loop thread. + * The priority value itself is platform-dependent, but is passed to + * sys_thread_new() when the thread is created. + */ +#ifndef SLIPIF_THREAD_PRIO +#define SLIPIF_THREAD_PRIO 1 +#endif + +/** + * PPP_THREAD_NAME: The name assigned to the pppInputThread. + */ +#ifndef PPP_THREAD_NAME +#define PPP_THREAD_NAME "pppInputThread" +#endif + +/** + * PPP_THREAD_STACKSIZE: The stack size used by the pppInputThread. + * The stack size value itself is platform-dependent, but is passed to + * sys_thread_new() when the thread is created. + */ +#ifndef PPP_THREAD_STACKSIZE +#define PPP_THREAD_STACKSIZE 0 +#endif + +/** + * PPP_THREAD_PRIO: The priority assigned to the pppInputThread. + * The priority value itself is platform-dependent, but is passed to + * sys_thread_new() when the thread is created. + */ +#ifndef PPP_THREAD_PRIO +#define PPP_THREAD_PRIO 1 +#endif + +/** + * DEFAULT_THREAD_NAME: The name assigned to any other lwIP thread. + */ +#ifndef DEFAULT_THREAD_NAME +#define DEFAULT_THREAD_NAME "lwIP" +#endif + +/** + * 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. + */ +#ifndef DEFAULT_THREAD_STACKSIZE +#define DEFAULT_THREAD_STACKSIZE 0 +#endif + +/** + * 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. + */ +#ifndef DEFAULT_THREAD_PRIO +#define DEFAULT_THREAD_PRIO 1 +#endif + +/** + * 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. + */ +#ifndef DEFAULT_RAW_RECVMBOX_SIZE +#define DEFAULT_RAW_RECVMBOX_SIZE 0 +#endif + +/** + * DEFAULT_UDP_RECVMBOX_SIZE: The mailbox size for the incoming packets on a + * NETCONN_UDP. The queue size value itself is platform-dependent, but is passed + * to sys_mbox_new() when the recvmbox is created. + */ +#ifndef DEFAULT_UDP_RECVMBOX_SIZE +#define DEFAULT_UDP_RECVMBOX_SIZE 0 +#endif + +/** + * DEFAULT_TCP_RECVMBOX_SIZE: The mailbox size for the incoming packets on a + * NETCONN_TCP. The queue size value itself is platform-dependent, but is passed + * to sys_mbox_new() when the recvmbox is created. + */ +#ifndef DEFAULT_TCP_RECVMBOX_SIZE +#define DEFAULT_TCP_RECVMBOX_SIZE 0 +#endif + +/** + * DEFAULT_ACCEPTMBOX_SIZE: The mailbox size for the incoming connections. + * The queue size value itself is platform-dependent, but is passed to + * sys_mbox_new() when the acceptmbox is created. + */ +#ifndef DEFAULT_ACCEPTMBOX_SIZE +#define DEFAULT_ACCEPTMBOX_SIZE 0 +#endif + +/* + ---------------------------------------------- + ---------- Sequential layer options ---------- + ---------------------------------------------- +*/ +/** + * LWIP_TCPIP_CORE_LOCKING: (EXPERIMENTAL!) + * Don't use it if you're not an active lwIP project member + */ +#ifndef LWIP_TCPIP_CORE_LOCKING +#define LWIP_TCPIP_CORE_LOCKING 0 +#endif + +/** + * LWIP_TCPIP_CORE_LOCKING_INPUT: (EXPERIMENTAL!) + * Don't use it if you're not an active lwIP project member + */ +#ifndef LWIP_TCPIP_CORE_LOCKING_INPUT +#define LWIP_TCPIP_CORE_LOCKING_INPUT 0 +#endif + +/** + * LWIP_NETCONN==1: Enable Netconn API (require to use api_lib.c) + */ +#ifndef LWIP_NETCONN +#define LWIP_NETCONN 1 +#endif + +/** LWIP_TCPIP_TIMEOUT==1: Enable tcpip_timeout/tcpip_untimeout tod create + * timers running in tcpip_thread from another thread. + */ +#ifndef LWIP_TCPIP_TIMEOUT +#define LWIP_TCPIP_TIMEOUT 1 +#endif + +/* + ------------------------------------ + ---------- Socket options ---------- + ------------------------------------ +*/ +/** + * LWIP_SOCKET==1: Enable Socket API (require to use sockets.c) + */ +#ifndef LWIP_SOCKET +#define LWIP_SOCKET 1 +#endif + +/** + * LWIP_COMPAT_SOCKETS==1: Enable BSD-style sockets functions names. + * (only used if you use sockets.c) + */ +#ifndef LWIP_COMPAT_SOCKETS +#define LWIP_COMPAT_SOCKETS 1 +#endif + +/** + * LWIP_POSIX_SOCKETS_IO_NAMES==1: Enable POSIX-style sockets functions names. + * Disable this option if you use a POSIX operating system that uses the same + * names (read, write & close). (only used if you use sockets.c) + */ +#ifndef LWIP_POSIX_SOCKETS_IO_NAMES +#define LWIP_POSIX_SOCKETS_IO_NAMES 1 +#endif + +/** + * LWIP_TCP_KEEPALIVE==1: Enable TCP_KEEPIDLE, TCP_KEEPINTVL and TCP_KEEPCNT + * options processing. Note that TCP_KEEPIDLE and TCP_KEEPINTVL have to be set + * in seconds. (does not require sockets.c, and will affect tcp.c) + */ +#ifndef LWIP_TCP_KEEPALIVE +#define LWIP_TCP_KEEPALIVE 0 +#endif + +/** + * LWIP_SO_SNDTIMEO==1: Enable send timeout for sockets/netconns and + * SO_SNDTIMEO processing. + */ +#ifndef LWIP_SO_SNDTIMEO +#define LWIP_SO_SNDTIMEO 0 +#endif + +/** + * LWIP_SO_RCVTIMEO==1: Enable receive timeout for sockets/netconns and + * SO_RCVTIMEO processing. + */ +#ifndef LWIP_SO_RCVTIMEO +#define LWIP_SO_RCVTIMEO 0 +#endif + +/** + * LWIP_SO_RCVBUF==1: Enable SO_RCVBUF processing. + */ +#ifndef LWIP_SO_RCVBUF +#define LWIP_SO_RCVBUF 0 +#endif + +/** + * If LWIP_SO_RCVBUF is used, this is the default value for recv_bufsize. + */ +#ifndef RECV_BUFSIZE_DEFAULT +#define RECV_BUFSIZE_DEFAULT INT_MAX +#endif + +/** + * SO_REUSE==1: Enable SO_REUSEADDR option. + */ +#ifndef SO_REUSE +#define SO_REUSE 0 +#endif + +/** + * SO_REUSE_RXTOALL==1: Pass a copy of incoming broadcast/multicast packets + * to all local matches if SO_REUSEADDR is turned on. + * WARNING: Adds a memcpy for every packet if passing to more than one pcb! + */ +#ifndef SO_REUSE_RXTOALL +#define SO_REUSE_RXTOALL 0 +#endif + +/* + ---------------------------------------- + ---------- Statistics options ---------- + ---------------------------------------- +*/ +/** + * LWIP_STATS==1: Enable statistics collection in lwip_stats. + */ +#ifndef LWIP_STATS +#define LWIP_STATS 1 +#endif + +#if LWIP_STATS + +/** + * LWIP_STATS_DISPLAY==1: Compile in the statistics output functions. + */ +#ifndef LWIP_STATS_DISPLAY +#define LWIP_STATS_DISPLAY 0 +#endif + +/** + * LINK_STATS==1: Enable link stats. + */ +#ifndef LINK_STATS +#define LINK_STATS 1 +#endif + +/** + * ETHARP_STATS==1: Enable etharp stats. + */ +#ifndef ETHARP_STATS +#define ETHARP_STATS (LWIP_ARP) +#endif + +/** + * IP_STATS==1: Enable IP stats. + */ +#ifndef IP_STATS +#define IP_STATS 1 +#endif + +/** + * IPFRAG_STATS==1: Enable IP fragmentation stats. Default is + * on if using either frag or reass. + */ +#ifndef IPFRAG_STATS +#define IPFRAG_STATS (IP_REASSEMBLY || IP_FRAG) +#endif + +/** + * ICMP_STATS==1: Enable ICMP stats. + */ +#ifndef ICMP_STATS +#define ICMP_STATS 1 +#endif + +/** + * IGMP_STATS==1: Enable IGMP stats. + */ +#ifndef IGMP_STATS +#define IGMP_STATS (LWIP_IGMP) +#endif + +/** + * UDP_STATS==1: Enable UDP stats. Default is on if + * UDP enabled, otherwise off. + */ +#ifndef UDP_STATS +#define UDP_STATS (LWIP_UDP) +#endif + +/** + * TCP_STATS==1: Enable TCP stats. Default is on if TCP + * enabled, otherwise off. + */ +#ifndef TCP_STATS +#define TCP_STATS (LWIP_TCP) +#endif + +/** + * MEM_STATS==1: Enable mem.c stats. + */ +#ifndef MEM_STATS +#define MEM_STATS ((MEM_LIBC_MALLOC == 0) && (MEM_USE_POOLS == 0)) +#endif + +/** + * MEMP_STATS==1: Enable memp.c pool stats. + */ +#ifndef MEMP_STATS +#define MEMP_STATS (MEMP_MEM_MALLOC == 0) +#endif + +/** + * SYS_STATS==1: Enable system stats (sem and mbox counts, etc). + */ +#ifndef SYS_STATS +#define SYS_STATS (NO_SYS == 0) +#endif + +#else + +#define LINK_STATS 0 +#define IP_STATS 0 +#define IPFRAG_STATS 0 +#define ICMP_STATS 0 +#define IGMP_STATS 0 +#define UDP_STATS 0 +#define TCP_STATS 0 +#define MEM_STATS 0 +#define MEMP_STATS 0 +#define SYS_STATS 0 +#define LWIP_STATS_DISPLAY 0 + +#endif /* LWIP_STATS */ + +/* + --------------------------------- + ---------- PPP options ---------- + --------------------------------- +*/ +/** + * PPP_SUPPORT==1: Enable PPP. + */ +#ifndef PPP_SUPPORT +#define PPP_SUPPORT 0 +#endif + +/** + * PPPOE_SUPPORT==1: Enable PPP Over Ethernet + */ +#ifndef PPPOE_SUPPORT +#define PPPOE_SUPPORT 0 +#endif + +/** + * PPPOS_SUPPORT==1: Enable PPP Over Serial + */ +#ifndef PPPOS_SUPPORT +#define PPPOS_SUPPORT PPP_SUPPORT +#endif + +#if PPP_SUPPORT + +/** + * NUM_PPP: Max PPP sessions. + */ +#ifndef NUM_PPP +#define NUM_PPP 1 +#endif + +/** + * PAP_SUPPORT==1: Support PAP. + */ +#ifndef PAP_SUPPORT +#define PAP_SUPPORT 0 +#endif + +/** + * CHAP_SUPPORT==1: Support CHAP. + */ +#ifndef CHAP_SUPPORT +#define CHAP_SUPPORT 0 +#endif + +/** + * MSCHAP_SUPPORT==1: Support MSCHAP. CURRENTLY NOT SUPPORTED! DO NOT SET! + */ +#ifndef MSCHAP_SUPPORT +#define MSCHAP_SUPPORT 0 +#endif + +/** + * CBCP_SUPPORT==1: Support CBCP. CURRENTLY NOT SUPPORTED! DO NOT SET! + */ +#ifndef CBCP_SUPPORT +#define CBCP_SUPPORT 0 +#endif + +/** + * CCP_SUPPORT==1: Support CCP. CURRENTLY NOT SUPPORTED! DO NOT SET! + */ +#ifndef CCP_SUPPORT +#define CCP_SUPPORT 0 +#endif + +/** + * VJ_SUPPORT==1: Support VJ header compression. + */ +#ifndef VJ_SUPPORT +#define VJ_SUPPORT 0 +#endif + +/** + * MD5_SUPPORT==1: Support MD5 (see also CHAP). + */ +#ifndef MD5_SUPPORT +#define MD5_SUPPORT 0 +#endif + +/* + * Timeouts + */ +#ifndef FSM_DEFTIMEOUT +#define FSM_DEFTIMEOUT 6 /* Timeout time in seconds */ +#endif + +#ifndef FSM_DEFMAXTERMREQS +#define FSM_DEFMAXTERMREQS 2 /* Maximum Terminate-Request transmissions */ +#endif + +#ifndef FSM_DEFMAXCONFREQS +#define FSM_DEFMAXCONFREQS 10 /* Maximum Configure-Request transmissions */ +#endif + +#ifndef FSM_DEFMAXNAKLOOPS +#define FSM_DEFMAXNAKLOOPS 5 /* Maximum number of nak loops */ +#endif + +#ifndef UPAP_DEFTIMEOUT +#define UPAP_DEFTIMEOUT 6 /* Timeout (seconds) for retransmitting req */ +#endif + +#ifndef UPAP_DEFREQTIME +#define UPAP_DEFREQTIME 30 /* Time to wait for auth-req from peer */ +#endif + +#ifndef CHAP_DEFTIMEOUT +#define CHAP_DEFTIMEOUT 6 /* Timeout time in seconds */ +#endif + +#ifndef CHAP_DEFTRANSMITS +#define CHAP_DEFTRANSMITS 10 /* max # times to send challenge */ +#endif + +/* Interval in seconds between keepalive echo requests, 0 to disable. */ +#ifndef LCP_ECHOINTERVAL +#define LCP_ECHOINTERVAL 0 +#endif + +/* Number of unanswered echo requests before failure. */ +#ifndef LCP_MAXECHOFAILS +#define LCP_MAXECHOFAILS 3 +#endif + +/* Max Xmit idle time (in jiffies) before resend flag char. */ +#ifndef PPP_MAXIDLEFLAG +#define PPP_MAXIDLEFLAG 100 +#endif + +/* + * Packet sizes + * + * Note - lcp shouldn't be allowed to negotiate stuff outside these + * limits. See lcp.h in the pppd directory. + * (XXX - these constants should simply be shared by lcp.c instead + * of living in lcp.h) + */ +#define PPP_MTU 1500 /* Default MTU (size of Info field) */ +#ifndef PPP_MAXMTU +/* #define PPP_MAXMTU 65535 - (PPP_HDRLEN + PPP_FCSLEN) */ +#define PPP_MAXMTU 1500 /* Largest MTU we allow */ +#endif +#define PPP_MINMTU 64 +#define PPP_MRU 1500 /* default MRU = max length of info field */ +#define PPP_MAXMRU 1500 /* Largest MRU we allow */ +#ifndef PPP_DEFMRU +#define PPP_DEFMRU 296 /* Try for this */ +#endif +#define PPP_MINMRU 128 /* No MRUs below this */ + +#ifndef MAXNAMELEN +#define MAXNAMELEN 256 /* max length of hostname or name for auth */ +#endif +#ifndef MAXSECRETLEN +#define MAXSECRETLEN 256 /* max length of password or secret */ +#endif + +#endif /* PPP_SUPPORT */ + +/* + -------------------------------------- + ---------- Checksum options ---------- + -------------------------------------- +*/ +/** + * CHECKSUM_GEN_IP==1: Generate checksums in software for outgoing IP packets. + */ +#ifndef CHECKSUM_GEN_IP +#define CHECKSUM_GEN_IP 1 +#endif + +/** + * CHECKSUM_GEN_UDP==1: Generate checksums in software for outgoing UDP packets. + */ +#ifndef CHECKSUM_GEN_UDP +#define CHECKSUM_GEN_UDP 1 +#endif + +/** + * CHECKSUM_GEN_TCP==1: Generate checksums in software for outgoing TCP packets. + */ +#ifndef CHECKSUM_GEN_TCP +#define CHECKSUM_GEN_TCP 1 +#endif + +/** + * CHECKSUM_GEN_ICMP==1: Generate checksums in software for outgoing ICMP packets. + */ +#ifndef CHECKSUM_GEN_ICMP +#define CHECKSUM_GEN_ICMP 1 +#endif + +/** + * CHECKSUM_CHECK_IP==1: Check checksums in software for incoming IP packets. + */ +#ifndef CHECKSUM_CHECK_IP +#define CHECKSUM_CHECK_IP 1 +#endif + +/** + * CHECKSUM_CHECK_UDP==1: Check checksums in software for incoming UDP packets. + */ +#ifndef CHECKSUM_CHECK_UDP +#define CHECKSUM_CHECK_UDP 1 +#endif + +/** + * CHECKSUM_CHECK_TCP==1: Check checksums in software for incoming TCP packets. + */ +#ifndef CHECKSUM_CHECK_TCP +#define CHECKSUM_CHECK_TCP 1 +#endif + +/** + * LWIP_CHECKSUM_ON_COPY==1: Calculate checksum when copying data from + * application buffers to pbufs. + */ +#ifndef LWIP_CHECKSUM_ON_COPY +#define LWIP_CHECKSUM_ON_COPY 0 +#endif + +/* + --------------------------------------- + ---------- Hook options --------------- + --------------------------------------- +*/ + +/* Hooks are undefined by default, define them to a function if you need them. */ + +/** + * LWIP_HOOK_IP4_INPUT(pbuf, input_netif): + * - called from ip_input() (IPv4) + * - pbuf: received struct pbuf passed to ip_input() + * - input_netif: struct netif on which the packet has been received + * Return values: + * - 0: Hook has not consumed the packet, packet is processed as normal + * - != 0: Hook has consumed the packet. + * If the hook consumed the packet, 'pbuf' is in the responsibility of the hook + * (i.e. free it when done). + */ + +/** + * LWIP_HOOK_IP4_ROUTE(dest): + * - called from ip_route() (IPv4) + * - dest: destination IPv4 address + * Returns the destination netif or NULL if no destination netif is found. In + * that case, ip_route() continues as normal. + */ + +/* + --------------------------------------- + ---------- Debugging options ---------- + --------------------------------------- +*/ +/** + * LWIP_DBG_MIN_LEVEL: After masking, the value of the debug is + * compared against this value. If it is smaller, then debugging + * messages are written. + */ +#ifndef LWIP_DBG_MIN_LEVEL +#define LWIP_DBG_MIN_LEVEL LWIP_DBG_LEVEL_ALL +#endif + +/** + * LWIP_DBG_TYPES_ON: A mask that can be used to globally enable/disable + * debug messages of certain types. + */ +#ifndef LWIP_DBG_TYPES_ON +#define LWIP_DBG_TYPES_ON LWIP_DBG_ON +#endif + +/** + * ETHARP_DEBUG: Enable debugging in etharp.c. + */ +#ifndef ETHARP_DEBUG +#define ETHARP_DEBUG LWIP_DBG_OFF +#endif + +/** + * NETIF_DEBUG: Enable debugging in netif.c. + */ +#ifndef NETIF_DEBUG +#define NETIF_DEBUG LWIP_DBG_OFF +#endif + +/** + * PBUF_DEBUG: Enable debugging in pbuf.c. + */ +#ifndef PBUF_DEBUG +#define PBUF_DEBUG LWIP_DBG_OFF +#endif + +/** + * API_LIB_DEBUG: Enable debugging in api_lib.c. + */ +#ifndef API_LIB_DEBUG +#define API_LIB_DEBUG LWIP_DBG_OFF +#endif + +/** + * API_MSG_DEBUG: Enable debugging in api_msg.c. + */ +#ifndef API_MSG_DEBUG +#define API_MSG_DEBUG LWIP_DBG_OFF +#endif + +/** + * SOCKETS_DEBUG: Enable debugging in sockets.c. + */ +#ifndef SOCKETS_DEBUG +#define SOCKETS_DEBUG LWIP_DBG_OFF +#endif + +/** + * ICMP_DEBUG: Enable debugging in icmp.c. + */ +#ifndef ICMP_DEBUG +#define ICMP_DEBUG LWIP_DBG_OFF +#endif + +/** + * IGMP_DEBUG: Enable debugging in igmp.c. + */ +#ifndef IGMP_DEBUG +#define IGMP_DEBUG LWIP_DBG_OFF +#endif + +/** + * INET_DEBUG: Enable debugging in inet.c. + */ +#ifndef INET_DEBUG +#define INET_DEBUG LWIP_DBG_OFF +#endif + +/** + * IP_DEBUG: Enable debugging for IP. + */ +#ifndef IP_DEBUG +#define IP_DEBUG LWIP_DBG_OFF +#endif + +/** + * IP_REASS_DEBUG: Enable debugging in ip_frag.c for both frag & reass. + */ +#ifndef IP_REASS_DEBUG +#define IP_REASS_DEBUG LWIP_DBG_OFF +#endif + +/** + * RAW_DEBUG: Enable debugging in raw.c. + */ +#ifndef RAW_DEBUG +#define RAW_DEBUG LWIP_DBG_OFF +#endif + +/** + * MEM_DEBUG: Enable debugging in mem.c. + */ +#ifndef MEM_DEBUG +#define MEM_DEBUG LWIP_DBG_OFF +#endif + +/** + * MEMP_DEBUG: Enable debugging in memp.c. + */ +#ifndef MEMP_DEBUG +#define MEMP_DEBUG LWIP_DBG_OFF +#endif + +/** + * SYS_DEBUG: Enable debugging in sys.c. + */ +#ifndef SYS_DEBUG +#define SYS_DEBUG LWIP_DBG_OFF +#endif + +/** + * TIMERS_DEBUG: Enable debugging in timers.c. + */ +#ifndef TIMERS_DEBUG +#define TIMERS_DEBUG LWIP_DBG_OFF +#endif + +/** + * TCP_DEBUG: Enable debugging for TCP. + */ +#ifndef TCP_DEBUG +#define TCP_DEBUG LWIP_DBG_OFF +#endif + +/** + * TCP_INPUT_DEBUG: Enable debugging in tcp_in.c for incoming debug. + */ +#ifndef TCP_INPUT_DEBUG +#define TCP_INPUT_DEBUG LWIP_DBG_OFF +#endif + +/** + * TCP_FR_DEBUG: Enable debugging in tcp_in.c for fast retransmit. + */ +#ifndef TCP_FR_DEBUG +#define TCP_FR_DEBUG LWIP_DBG_OFF +#endif + +/** + * TCP_RTO_DEBUG: Enable debugging in TCP for retransmit + * timeout. + */ +#ifndef TCP_RTO_DEBUG +#define TCP_RTO_DEBUG LWIP_DBG_OFF +#endif + +/** + * TCP_CWND_DEBUG: Enable debugging for TCP congestion window. + */ +#ifndef TCP_CWND_DEBUG +#define TCP_CWND_DEBUG LWIP_DBG_OFF +#endif + +/** + * TCP_WND_DEBUG: Enable debugging in tcp_in.c for window updating. + */ +#ifndef TCP_WND_DEBUG +#define TCP_WND_DEBUG LWIP_DBG_OFF +#endif + +/** + * TCP_OUTPUT_DEBUG: Enable debugging in tcp_out.c output functions. + */ +#ifndef TCP_OUTPUT_DEBUG +#define TCP_OUTPUT_DEBUG LWIP_DBG_OFF +#endif + +/** + * TCP_RST_DEBUG: Enable debugging for TCP with the RST message. + */ +#ifndef TCP_RST_DEBUG +#define TCP_RST_DEBUG LWIP_DBG_OFF +#endif + +/** + * TCP_QLEN_DEBUG: Enable debugging for TCP queue lengths. + */ +#ifndef TCP_QLEN_DEBUG +#define TCP_QLEN_DEBUG LWIP_DBG_OFF +#endif + +/** + * UDP_DEBUG: Enable debugging in UDP. + */ +#ifndef UDP_DEBUG +#define UDP_DEBUG LWIP_DBG_OFF +#endif + +/** + * TCPIP_DEBUG: Enable debugging in tcpip.c. + */ +#ifndef TCPIP_DEBUG +#define TCPIP_DEBUG LWIP_DBG_OFF +#endif + +/** + * PPP_DEBUG: Enable debugging for PPP. + */ +#ifndef PPP_DEBUG +#define PPP_DEBUG LWIP_DBG_OFF +#endif + +/** + * SLIP_DEBUG: Enable debugging in slipif.c. + */ +#ifndef SLIP_DEBUG +#define SLIP_DEBUG LWIP_DBG_OFF +#endif + +/** + * DHCP_DEBUG: Enable debugging in dhcp.c. + */ +#ifndef DHCP_DEBUG +#define DHCP_DEBUG LWIP_DBG_OFF +#endif + +/** + * AUTOIP_DEBUG: Enable debugging in autoip.c. + */ +#ifndef AUTOIP_DEBUG +#define AUTOIP_DEBUG LWIP_DBG_OFF +#endif + +/** + * SNMP_MSG_DEBUG: Enable debugging for SNMP messages. + */ +#ifndef SNMP_MSG_DEBUG +#define SNMP_MSG_DEBUG LWIP_DBG_OFF +#endif + +/** + * SNMP_MIB_DEBUG: Enable debugging for SNMP MIBs. + */ +#ifndef SNMP_MIB_DEBUG +#define SNMP_MIB_DEBUG LWIP_DBG_OFF +#endif + +/** + * DNS_DEBUG: Enable debugging for DNS. + */ +#ifndef DNS_DEBUG +#define DNS_DEBUG LWIP_DBG_OFF +#endif + +#endif /* __LWIP_OPT_H__ */ diff --git a/src/lwip-1.4.1/src/include/lwip/pbuf.h b/src/lwip-1.4.1/src/include/lwip/pbuf.h new file mode 100644 index 0000000..99cf20a --- /dev/null +++ b/src/lwip-1.4.1/src/include/lwip/pbuf.h @@ -0,0 +1,178 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#ifndef __LWIP_PBUF_H__ +#define __LWIP_PBUF_H__ + +#include "lwip/opt.h" +#include "lwip/err.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** Currently, the pbuf_custom code is only needed for one specific configuration + * of IP_FRAG */ +#define LWIP_SUPPORT_CUSTOM_PBUF (IP_FRAG && !IP_FRAG_USES_STATIC_BUF && !LWIP_NETIF_TX_SINGLE_PBUF) + +#define PBUF_TRANSPORT_HLEN 20 +#define PBUF_IP_HLEN 20 + +typedef enum { + PBUF_TRANSPORT, + PBUF_IP, + PBUF_LINK, + PBUF_RAW +} pbuf_layer; + +typedef enum { + PBUF_RAM, /* pbuf data is stored in RAM */ + PBUF_ROM, /* pbuf data is stored in ROM */ + PBUF_REF, /* pbuf comes from the pbuf pool */ + PBUF_POOL /* pbuf payload refers to RAM */ +} pbuf_type; + + +/** indicates this packet's data should be immediately passed to the application */ +#define PBUF_FLAG_PUSH 0x01U +/** indicates this is a custom pbuf: pbuf_free and pbuf_header handle such a + a pbuf differently */ +#define PBUF_FLAG_IS_CUSTOM 0x02U +/** indicates this pbuf is UDP multicast to be looped back */ +#define PBUF_FLAG_MCASTLOOP 0x04U +/** indicates this pbuf was received as link-level broadcast */ +#define PBUF_FLAG_LLBCAST 0x08U +/** indicates this pbuf was received as link-level multicast */ +#define PBUF_FLAG_LLMCAST 0x10U +/** indicates this pbuf includes a TCP FIN flag */ +#define PBUF_FLAG_TCP_FIN 0x20U + +struct pbuf { + /** next pbuf in singly linked pbuf chain */ + struct pbuf *next; + + /** pointer to the actual data in the buffer */ + void *payload; + + /** + * total length of this buffer and all next buffers in chain + * belonging to the same packet. + * + * For non-queue packet chains this is the invariant: + * p->tot_len == p->len + (p->next? p->next->tot_len: 0) + */ + u16_t tot_len; + + /** length of this buffer */ + u16_t len; + + /** pbuf_type as u8_t instead of enum to save space */ + u8_t /*pbuf_type*/ type; + + /** misc flags */ + u8_t flags; + + /** + * the reference count always equals the number of pointers + * that refer to this pbuf. This can be pointers from an application, + * the stack itself, or pbuf->next pointers from a chain. + */ + u16_t ref; +}; + +#if LWIP_SUPPORT_CUSTOM_PBUF +/** Prototype for a function to free a custom pbuf */ +typedef void (*pbuf_free_custom_fn)(struct pbuf *p); + +/** A custom pbuf: like a pbuf, but following a function pointer to free it. */ +struct pbuf_custom { + /** The actual pbuf */ + struct pbuf pbuf; + /** This function is called when pbuf_free deallocates this pbuf(_custom) */ + pbuf_free_custom_fn custom_free_function; +}; +#endif /* LWIP_SUPPORT_CUSTOM_PBUF */ + +#if LWIP_TCP && TCP_QUEUE_OOSEQ +/** Define this to 0 to prevent freeing ooseq pbufs when the PBUF_POOL is empty */ +#ifndef PBUF_POOL_FREE_OOSEQ +#define PBUF_POOL_FREE_OOSEQ 1 +#endif /* PBUF_POOL_FREE_OOSEQ */ +#if NO_SYS && PBUF_POOL_FREE_OOSEQ +extern volatile u8_t pbuf_free_ooseq_pending; +void pbuf_free_ooseq(void); +/** When not using sys_check_timeouts(), call PBUF_CHECK_FREE_OOSEQ() + at regular intervals from main level to check if ooseq pbufs need to be + freed! */ +#define PBUF_CHECK_FREE_OOSEQ() do { if(pbuf_free_ooseq_pending) { \ + /* pbuf_alloc() reported PBUF_POOL to be empty -> try to free some \ + ooseq queued pbufs now */ \ + pbuf_free_ooseq(); }}while(0) +#endif /* NO_SYS && PBUF_POOL_FREE_OOSEQ*/ +#endif /* LWIP_TCP && TCP_QUEUE_OOSEQ */ + +/* Initializes the pbuf module. This call is empty for now, but may not be in future. */ +#define pbuf_init() + +struct pbuf *pbuf_alloc(pbuf_layer l, u16_t length, pbuf_type type); +#if LWIP_SUPPORT_CUSTOM_PBUF +struct pbuf *pbuf_alloced_custom(pbuf_layer l, u16_t length, pbuf_type type, + struct pbuf_custom *p, void *payload_mem, + u16_t payload_mem_len); +#endif /* LWIP_SUPPORT_CUSTOM_PBUF */ +void pbuf_realloc(struct pbuf *p, u16_t size); +u8_t pbuf_header(struct pbuf *p, s16_t header_size); +void pbuf_ref(struct pbuf *p); +u8_t pbuf_free(struct pbuf *p); +u8_t pbuf_clen(struct pbuf *p); +void pbuf_cat(struct pbuf *head, struct pbuf *tail); +void pbuf_chain(struct pbuf *head, struct pbuf *tail); +struct pbuf *pbuf_dechain(struct pbuf *p); +err_t pbuf_copy(struct pbuf *p_to, struct pbuf *p_from); +u16_t pbuf_copy_partial(struct pbuf *p, void *dataptr, u16_t len, u16_t offset); +err_t pbuf_take(struct pbuf *buf, const void *dataptr, u16_t len); +struct pbuf *pbuf_coalesce(struct pbuf *p, pbuf_layer layer); +#if LWIP_CHECKSUM_ON_COPY +err_t pbuf_fill_chksum(struct pbuf *p, u16_t start_offset, const void *dataptr, + u16_t len, u16_t *chksum); +#endif /* LWIP_CHECKSUM_ON_COPY */ + +u8_t pbuf_get_at(struct pbuf* p, u16_t offset); +u16_t pbuf_memcmp(struct pbuf* p, u16_t offset, const void* s2, u16_t n); +u16_t pbuf_memfind(struct pbuf* p, const void* mem, u16_t mem_len, u16_t start_offset); +u16_t pbuf_strstr(struct pbuf* p, const char* substr); + +#ifdef __cplusplus +} +#endif + +#endif /* __LWIP_PBUF_H__ */ diff --git a/src/lwip-1.4.1/src/include/lwip/raw.h b/src/lwip-1.4.1/src/include/lwip/raw.h new file mode 100644 index 0000000..17d0a1c --- /dev/null +++ b/src/lwip-1.4.1/src/include/lwip/raw.h @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __LWIP_RAW_H__ +#define __LWIP_RAW_H__ + +#include "lwip/opt.h" + +#if LWIP_RAW /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/pbuf.h" +#include "lwip/def.h" +#include "lwip/ip.h" +#include "lwip/ip_addr.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct raw_pcb; + +/** Function prototype for raw pcb receive callback functions. + * @param arg user supplied argument (raw_pcb.recv_arg) + * @param pcb the raw_pcb which received data + * @param p the packet buffer that was received + * @param addr the remote IP address from which the packet was received + * @return 1 if the packet was 'eaten' (aka. deleted), + * 0 if the packet lives on + * If returning 1, the callback is responsible for freeing the pbuf + * if it's not used any more. + */ +typedef u8_t (*raw_recv_fn)(void *arg, struct raw_pcb *pcb, struct pbuf *p, + ip_addr_t *addr); + +struct raw_pcb { + /* Common members of all PCB types */ + IP_PCB; + + struct raw_pcb *next; + + u8_t protocol; + + /** receive callback function */ + raw_recv_fn recv; + /* user-supplied argument for the recv callback */ + void *recv_arg; +}; + +/* The following functions is the application layer interface to the + RAW code. */ +struct raw_pcb * raw_new (u8_t proto); +void raw_remove (struct raw_pcb *pcb); +err_t raw_bind (struct raw_pcb *pcb, ip_addr_t *ipaddr); +err_t raw_connect (struct raw_pcb *pcb, ip_addr_t *ipaddr); + +void raw_recv (struct raw_pcb *pcb, raw_recv_fn recv, void *recv_arg); +err_t raw_sendto (struct raw_pcb *pcb, struct pbuf *p, ip_addr_t *ipaddr); +err_t raw_send (struct raw_pcb *pcb, struct pbuf *p); + +/* The following functions are the lower layer interface to RAW. */ +u8_t raw_input (struct pbuf *p, struct netif *inp); +#define raw_init() /* Compatibility define, not init needed. */ + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_RAW */ + +#endif /* __LWIP_RAW_H__ */ diff --git a/src/lwip-1.4.1/src/include/lwip/sio.h b/src/lwip-1.4.1/src/include/lwip/sio.h new file mode 100644 index 0000000..28ae2f2 --- /dev/null +++ b/src/lwip-1.4.1/src/include/lwip/sio.h @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * This file is part of the lwIP TCP/IP stack. + */ + +/* + * This is the interface to the platform specific serial IO module + * It needs to be implemented by those platforms which need SLIP or PPP + */ + +#ifndef __SIO_H__ +#define __SIO_H__ + +#include "lwip/arch.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* If you want to define sio_fd_t elsewhere or differently, + define this in your cc.h file. */ +#ifndef __sio_fd_t_defined +typedef void * sio_fd_t; +#endif + +/* The following functions can be defined to something else in your cc.h file + or be implemented in your custom sio.c file. */ + +#ifndef sio_open +/** + * Opens a serial device for communication. + * + * @param devnum device number + * @return handle to serial device if successful, NULL otherwise + */ +sio_fd_t sio_open(u8_t devnum); +#endif + +#ifndef sio_send +/** + * Sends a single character to the serial device. + * + * @param c character to send + * @param fd serial device handle + * + * @note This function will block until the character can be sent. + */ +void sio_send(u8_t c, sio_fd_t fd); +#endif + +#ifndef sio_recv +/** + * Receives a single character from the serial device. + * + * @param fd serial device handle + * + * @note This function will block until a character is received. + */ +u8_t sio_recv(sio_fd_t fd); +#endif + +#ifndef sio_read +/** + * Reads from the serial device. + * + * @param fd serial device handle + * @param data pointer to data buffer for receiving + * @param len maximum length (in bytes) of data to receive + * @return number of bytes actually received - may be 0 if aborted by sio_read_abort + * + * @note This function will block until data can be received. The blocking + * can be cancelled by calling sio_read_abort(). + */ +u32_t sio_read(sio_fd_t fd, u8_t *data, u32_t len); +#endif + +#ifndef sio_tryread +/** + * Tries to read from the serial device. Same as sio_read but returns + * immediately if no data is available and never blocks. + * + * @param fd serial device handle + * @param data pointer to data buffer for receiving + * @param len maximum length (in bytes) of data to receive + * @return number of bytes actually received + */ +u32_t sio_tryread(sio_fd_t fd, u8_t *data, u32_t len); +#endif + +#ifndef sio_write +/** + * Writes to the serial device. + * + * @param fd serial device handle + * @param data pointer to data to send + * @param len length (in bytes) of data to send + * @return number of bytes actually sent + * + * @note This function will block until all data can be sent. + */ +u32_t sio_write(sio_fd_t fd, u8_t *data, u32_t len); +#endif + +#ifndef sio_read_abort +/** + * Aborts a blocking sio_read() call. + * + * @param fd serial device handle + */ +void sio_read_abort(sio_fd_t fd); +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* __SIO_H__ */ diff --git a/src/lwip-1.4.1/src/include/lwip/snmp.h b/src/lwip-1.4.1/src/include/lwip/snmp.h new file mode 100644 index 0000000..2ed043d --- /dev/null +++ b/src/lwip-1.4.1/src/include/lwip/snmp.h @@ -0,0 +1,367 @@ +/* + * Copyright (c) 2001, 2002 Leon Woestenberg + * Copyright (c) 2001, 2002 Axon Digital Design B.V., The Netherlands. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Leon Woestenberg + * + */ +#ifndef __LWIP_SNMP_H__ +#define __LWIP_SNMP_H__ + +#include "lwip/opt.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#include "lwip/ip_addr.h" + +struct udp_pcb; +struct netif; + +/** + * @see RFC1213, "MIB-II, 6. Definitions" + */ +enum snmp_ifType { + snmp_ifType_other=1, /* none of the following */ + snmp_ifType_regular1822, + snmp_ifType_hdh1822, + snmp_ifType_ddn_x25, + snmp_ifType_rfc877_x25, + snmp_ifType_ethernet_csmacd, + snmp_ifType_iso88023_csmacd, + snmp_ifType_iso88024_tokenBus, + snmp_ifType_iso88025_tokenRing, + snmp_ifType_iso88026_man, + snmp_ifType_starLan, + snmp_ifType_proteon_10Mbit, + snmp_ifType_proteon_80Mbit, + snmp_ifType_hyperchannel, + snmp_ifType_fddi, + snmp_ifType_lapb, + snmp_ifType_sdlc, + snmp_ifType_ds1, /* T-1 */ + snmp_ifType_e1, /* european equiv. of T-1 */ + snmp_ifType_basicISDN, + snmp_ifType_primaryISDN, /* proprietary serial */ + snmp_ifType_propPointToPointSerial, + snmp_ifType_ppp, + snmp_ifType_softwareLoopback, + snmp_ifType_eon, /* CLNP over IP [11] */ + snmp_ifType_ethernet_3Mbit, + snmp_ifType_nsip, /* XNS over IP */ + snmp_ifType_slip, /* generic SLIP */ + snmp_ifType_ultra, /* ULTRA technologies */ + snmp_ifType_ds3, /* T-3 */ + snmp_ifType_sip, /* SMDS */ + snmp_ifType_frame_relay +}; + +#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */ + +/** SNMP "sysuptime" Interval */ +#define SNMP_SYSUPTIME_INTERVAL 10 + +/** fixed maximum length for object identifier type */ +#define LWIP_SNMP_OBJ_ID_LEN 32 + +/** internal object identifier representation */ +struct snmp_obj_id +{ + u8_t len; + s32_t id[LWIP_SNMP_OBJ_ID_LEN]; +}; + +/* system */ +void snmp_set_sysdesr(u8_t* str, u8_t* len); +void snmp_set_sysobjid(struct snmp_obj_id *oid); +void snmp_get_sysobjid_ptr(struct snmp_obj_id **oid); +void snmp_inc_sysuptime(void); +void snmp_add_sysuptime(u32_t value); +void snmp_get_sysuptime(u32_t *value); +void snmp_set_syscontact(u8_t *ocstr, u8_t *ocstrlen); +void snmp_set_sysname(u8_t *ocstr, u8_t *ocstrlen); +void snmp_set_syslocation(u8_t *ocstr, u8_t *ocstrlen); + +/* network interface */ +void snmp_add_ifinoctets(struct netif *ni, u32_t value); +void snmp_inc_ifinucastpkts(struct netif *ni); +void snmp_inc_ifinnucastpkts(struct netif *ni); +void snmp_inc_ifindiscards(struct netif *ni); +void snmp_add_ifoutoctets(struct netif *ni, u32_t value); +void snmp_inc_ifoutucastpkts(struct netif *ni); +void snmp_inc_ifoutnucastpkts(struct netif *ni); +void snmp_inc_ifoutdiscards(struct netif *ni); +void snmp_inc_iflist(void); +void snmp_dec_iflist(void); + +/* ARP (for atTable and ipNetToMediaTable) */ +void snmp_insert_arpidx_tree(struct netif *ni, ip_addr_t *ip); +void snmp_delete_arpidx_tree(struct netif *ni, ip_addr_t *ip); + +/* IP */ +void snmp_inc_ipinreceives(void); +void snmp_inc_ipinhdrerrors(void); +void snmp_inc_ipinaddrerrors(void); +void snmp_inc_ipforwdatagrams(void); +void snmp_inc_ipinunknownprotos(void); +void snmp_inc_ipindiscards(void); +void snmp_inc_ipindelivers(void); +void snmp_inc_ipoutrequests(void); +void snmp_inc_ipoutdiscards(void); +void snmp_inc_ipoutnoroutes(void); +void snmp_inc_ipreasmreqds(void); +void snmp_inc_ipreasmoks(void); +void snmp_inc_ipreasmfails(void); +void snmp_inc_ipfragoks(void); +void snmp_inc_ipfragfails(void); +void snmp_inc_ipfragcreates(void); +void snmp_inc_iproutingdiscards(void); +void snmp_insert_ipaddridx_tree(struct netif *ni); +void snmp_delete_ipaddridx_tree(struct netif *ni); +void snmp_insert_iprteidx_tree(u8_t dflt, struct netif *ni); +void snmp_delete_iprteidx_tree(u8_t dflt, struct netif *ni); + +/* ICMP */ +void snmp_inc_icmpinmsgs(void); +void snmp_inc_icmpinerrors(void); +void snmp_inc_icmpindestunreachs(void); +void snmp_inc_icmpintimeexcds(void); +void snmp_inc_icmpinparmprobs(void); +void snmp_inc_icmpinsrcquenchs(void); +void snmp_inc_icmpinredirects(void); +void snmp_inc_icmpinechos(void); +void snmp_inc_icmpinechoreps(void); +void snmp_inc_icmpintimestamps(void); +void snmp_inc_icmpintimestampreps(void); +void snmp_inc_icmpinaddrmasks(void); +void snmp_inc_icmpinaddrmaskreps(void); +void snmp_inc_icmpoutmsgs(void); +void snmp_inc_icmpouterrors(void); +void snmp_inc_icmpoutdestunreachs(void); +void snmp_inc_icmpouttimeexcds(void); +void snmp_inc_icmpoutparmprobs(void); +void snmp_inc_icmpoutsrcquenchs(void); +void snmp_inc_icmpoutredirects(void); +void snmp_inc_icmpoutechos(void); +void snmp_inc_icmpoutechoreps(void); +void snmp_inc_icmpouttimestamps(void); +void snmp_inc_icmpouttimestampreps(void); +void snmp_inc_icmpoutaddrmasks(void); +void snmp_inc_icmpoutaddrmaskreps(void); + +/* TCP */ +void snmp_inc_tcpactiveopens(void); +void snmp_inc_tcppassiveopens(void); +void snmp_inc_tcpattemptfails(void); +void snmp_inc_tcpestabresets(void); +void snmp_inc_tcpinsegs(void); +void snmp_inc_tcpoutsegs(void); +void snmp_inc_tcpretranssegs(void); +void snmp_inc_tcpinerrs(void); +void snmp_inc_tcpoutrsts(void); + +/* UDP */ +void snmp_inc_udpindatagrams(void); +void snmp_inc_udpnoports(void); +void snmp_inc_udpinerrors(void); +void snmp_inc_udpoutdatagrams(void); +void snmp_insert_udpidx_tree(struct udp_pcb *pcb); +void snmp_delete_udpidx_tree(struct udp_pcb *pcb); + +/* SNMP */ +void snmp_inc_snmpinpkts(void); +void snmp_inc_snmpoutpkts(void); +void snmp_inc_snmpinbadversions(void); +void snmp_inc_snmpinbadcommunitynames(void); +void snmp_inc_snmpinbadcommunityuses(void); +void snmp_inc_snmpinasnparseerrs(void); +void snmp_inc_snmpintoobigs(void); +void snmp_inc_snmpinnosuchnames(void); +void snmp_inc_snmpinbadvalues(void); +void snmp_inc_snmpinreadonlys(void); +void snmp_inc_snmpingenerrs(void); +void snmp_add_snmpintotalreqvars(u8_t value); +void snmp_add_snmpintotalsetvars(u8_t value); +void snmp_inc_snmpingetrequests(void); +void snmp_inc_snmpingetnexts(void); +void snmp_inc_snmpinsetrequests(void); +void snmp_inc_snmpingetresponses(void); +void snmp_inc_snmpintraps(void); +void snmp_inc_snmpouttoobigs(void); +void snmp_inc_snmpoutnosuchnames(void); +void snmp_inc_snmpoutbadvalues(void); +void snmp_inc_snmpoutgenerrs(void); +void snmp_inc_snmpoutgetrequests(void); +void snmp_inc_snmpoutgetnexts(void); +void snmp_inc_snmpoutsetrequests(void); +void snmp_inc_snmpoutgetresponses(void); +void snmp_inc_snmpouttraps(void); +void snmp_get_snmpgrpid_ptr(struct snmp_obj_id **oid); +void snmp_set_snmpenableauthentraps(u8_t *value); +void snmp_get_snmpenableauthentraps(u8_t *value); + +/* LWIP_SNMP support not available */ +/* define everything to be empty */ +#else + +/* system */ +#define snmp_set_sysdesr(str, len) +#define snmp_set_sysobjid(oid); +#define snmp_get_sysobjid_ptr(oid) +#define snmp_inc_sysuptime() +#define snmp_add_sysuptime(value) +#define snmp_get_sysuptime(value) +#define snmp_set_syscontact(ocstr, ocstrlen); +#define snmp_set_sysname(ocstr, ocstrlen); +#define snmp_set_syslocation(ocstr, ocstrlen); + +/* network interface */ +#define snmp_add_ifinoctets(ni,value) +#define snmp_inc_ifinucastpkts(ni) +#define snmp_inc_ifinnucastpkts(ni) +#define snmp_inc_ifindiscards(ni) +#define snmp_add_ifoutoctets(ni,value) +#define snmp_inc_ifoutucastpkts(ni) +#define snmp_inc_ifoutnucastpkts(ni) +#define snmp_inc_ifoutdiscards(ni) +#define snmp_inc_iflist() +#define snmp_dec_iflist() + +/* ARP */ +#define snmp_insert_arpidx_tree(ni,ip) +#define snmp_delete_arpidx_tree(ni,ip) + +/* IP */ +#define snmp_inc_ipinreceives() +#define snmp_inc_ipinhdrerrors() +#define snmp_inc_ipinaddrerrors() +#define snmp_inc_ipforwdatagrams() +#define snmp_inc_ipinunknownprotos() +#define snmp_inc_ipindiscards() +#define snmp_inc_ipindelivers() +#define snmp_inc_ipoutrequests() +#define snmp_inc_ipoutdiscards() +#define snmp_inc_ipoutnoroutes() +#define snmp_inc_ipreasmreqds() +#define snmp_inc_ipreasmoks() +#define snmp_inc_ipreasmfails() +#define snmp_inc_ipfragoks() +#define snmp_inc_ipfragfails() +#define snmp_inc_ipfragcreates() +#define snmp_inc_iproutingdiscards() +#define snmp_insert_ipaddridx_tree(ni) +#define snmp_delete_ipaddridx_tree(ni) +#define snmp_insert_iprteidx_tree(dflt, ni) +#define snmp_delete_iprteidx_tree(dflt, ni) + +/* ICMP */ +#define snmp_inc_icmpinmsgs() +#define snmp_inc_icmpinerrors() +#define snmp_inc_icmpindestunreachs() +#define snmp_inc_icmpintimeexcds() +#define snmp_inc_icmpinparmprobs() +#define snmp_inc_icmpinsrcquenchs() +#define snmp_inc_icmpinredirects() +#define snmp_inc_icmpinechos() +#define snmp_inc_icmpinechoreps() +#define snmp_inc_icmpintimestamps() +#define snmp_inc_icmpintimestampreps() +#define snmp_inc_icmpinaddrmasks() +#define snmp_inc_icmpinaddrmaskreps() +#define snmp_inc_icmpoutmsgs() +#define snmp_inc_icmpouterrors() +#define snmp_inc_icmpoutdestunreachs() +#define snmp_inc_icmpouttimeexcds() +#define snmp_inc_icmpoutparmprobs() +#define snmp_inc_icmpoutsrcquenchs() +#define snmp_inc_icmpoutredirects() +#define snmp_inc_icmpoutechos() +#define snmp_inc_icmpoutechoreps() +#define snmp_inc_icmpouttimestamps() +#define snmp_inc_icmpouttimestampreps() +#define snmp_inc_icmpoutaddrmasks() +#define snmp_inc_icmpoutaddrmaskreps() +/* TCP */ +#define snmp_inc_tcpactiveopens() +#define snmp_inc_tcppassiveopens() +#define snmp_inc_tcpattemptfails() +#define snmp_inc_tcpestabresets() +#define snmp_inc_tcpinsegs() +#define snmp_inc_tcpoutsegs() +#define snmp_inc_tcpretranssegs() +#define snmp_inc_tcpinerrs() +#define snmp_inc_tcpoutrsts() + +/* UDP */ +#define snmp_inc_udpindatagrams() +#define snmp_inc_udpnoports() +#define snmp_inc_udpinerrors() +#define snmp_inc_udpoutdatagrams() +#define snmp_insert_udpidx_tree(pcb) +#define snmp_delete_udpidx_tree(pcb) + +/* SNMP */ +#define snmp_inc_snmpinpkts() +#define snmp_inc_snmpoutpkts() +#define snmp_inc_snmpinbadversions() +#define snmp_inc_snmpinbadcommunitynames() +#define snmp_inc_snmpinbadcommunityuses() +#define snmp_inc_snmpinasnparseerrs() +#define snmp_inc_snmpintoobigs() +#define snmp_inc_snmpinnosuchnames() +#define snmp_inc_snmpinbadvalues() +#define snmp_inc_snmpinreadonlys() +#define snmp_inc_snmpingenerrs() +#define snmp_add_snmpintotalreqvars(value) +#define snmp_add_snmpintotalsetvars(value) +#define snmp_inc_snmpingetrequests() +#define snmp_inc_snmpingetnexts() +#define snmp_inc_snmpinsetrequests() +#define snmp_inc_snmpingetresponses() +#define snmp_inc_snmpintraps() +#define snmp_inc_snmpouttoobigs() +#define snmp_inc_snmpoutnosuchnames() +#define snmp_inc_snmpoutbadvalues() +#define snmp_inc_snmpoutgenerrs() +#define snmp_inc_snmpoutgetrequests() +#define snmp_inc_snmpoutgetnexts() +#define snmp_inc_snmpoutsetrequests() +#define snmp_inc_snmpoutgetresponses() +#define snmp_inc_snmpouttraps() +#define snmp_get_snmpgrpid_ptr(oid) +#define snmp_set_snmpenableauthentraps(value) +#define snmp_get_snmpenableauthentraps(value) + +#endif /* LWIP_SNMP */ + +#ifdef __cplusplus +} +#endif + +#endif /* __LWIP_SNMP_H__ */ diff --git a/src/lwip-1.4.1/src/include/lwip/snmp_asn1.h b/src/lwip-1.4.1/src/include/lwip/snmp_asn1.h new file mode 100644 index 0000000..605fa3f --- /dev/null +++ b/src/lwip-1.4.1/src/include/lwip/snmp_asn1.h @@ -0,0 +1,101 @@ +/** + * @file + * Abstract Syntax Notation One (ISO 8824, 8825) codec. + */ + +/* + * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * Author: Christiaan Simons + */ + +#ifndef __LWIP_SNMP_ASN1_H__ +#define __LWIP_SNMP_ASN1_H__ + +#include "lwip/opt.h" +#include "lwip/err.h" +#include "lwip/pbuf.h" +#include "lwip/snmp.h" + +#if LWIP_SNMP + +#ifdef __cplusplus +extern "C" { +#endif + +#define SNMP_ASN1_UNIV (0) /* (!0x80 | !0x40) */ +#define SNMP_ASN1_APPLIC (0x40) /* (!0x80 | 0x40) */ +#define SNMP_ASN1_CONTXT (0x80) /* ( 0x80 | !0x40) */ + +#define SNMP_ASN1_CONSTR (0x20) /* ( 0x20) */ +#define SNMP_ASN1_PRIMIT (0) /* (!0x20) */ + +/* universal tags */ +#define SNMP_ASN1_INTEG 2 +#define SNMP_ASN1_OC_STR 4 +#define SNMP_ASN1_NUL 5 +#define SNMP_ASN1_OBJ_ID 6 +#define SNMP_ASN1_SEQ 16 + +/* application specific (SNMP) tags */ +#define SNMP_ASN1_IPADDR 0 /* octet string size(4) */ +#define SNMP_ASN1_COUNTER 1 /* u32_t */ +#define SNMP_ASN1_GAUGE 2 /* u32_t */ +#define SNMP_ASN1_TIMETICKS 3 /* u32_t */ +#define SNMP_ASN1_OPAQUE 4 /* octet string */ + +/* context specific (SNMP) tags */ +#define SNMP_ASN1_PDU_GET_REQ 0 +#define SNMP_ASN1_PDU_GET_NEXT_REQ 1 +#define SNMP_ASN1_PDU_GET_RESP 2 +#define SNMP_ASN1_PDU_SET_REQ 3 +#define SNMP_ASN1_PDU_TRAP 4 + +err_t snmp_asn1_dec_type(struct pbuf *p, u16_t ofs, u8_t *type); +err_t snmp_asn1_dec_length(struct pbuf *p, u16_t ofs, u8_t *octets_used, u16_t *length); +err_t snmp_asn1_dec_u32t(struct pbuf *p, u16_t ofs, u16_t len, u32_t *value); +err_t snmp_asn1_dec_s32t(struct pbuf *p, u16_t ofs, u16_t len, s32_t *value); +err_t snmp_asn1_dec_oid(struct pbuf *p, u16_t ofs, u16_t len, struct snmp_obj_id *oid); +err_t snmp_asn1_dec_raw(struct pbuf *p, u16_t ofs, u16_t len, u16_t raw_len, u8_t *raw); + +void snmp_asn1_enc_length_cnt(u16_t length, u8_t *octets_needed); +void snmp_asn1_enc_u32t_cnt(u32_t value, u16_t *octets_needed); +void snmp_asn1_enc_s32t_cnt(s32_t value, u16_t *octets_needed); +void snmp_asn1_enc_oid_cnt(u8_t ident_len, s32_t *ident, u16_t *octets_needed); +err_t snmp_asn1_enc_type(struct pbuf *p, u16_t ofs, u8_t type); +err_t snmp_asn1_enc_length(struct pbuf *p, u16_t ofs, u16_t length); +err_t snmp_asn1_enc_u32t(struct pbuf *p, u16_t ofs, u16_t octets_needed, u32_t value); +err_t snmp_asn1_enc_s32t(struct pbuf *p, u16_t ofs, u16_t octets_needed, s32_t value); +err_t snmp_asn1_enc_oid(struct pbuf *p, u16_t ofs, u8_t ident_len, s32_t *ident); +err_t snmp_asn1_enc_raw(struct pbuf *p, u16_t ofs, u16_t raw_len, u8_t *raw); + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_SNMP */ + +#endif /* __LWIP_SNMP_ASN1_H__ */ diff --git a/src/lwip-1.4.1/src/include/lwip/snmp_msg.h b/src/lwip-1.4.1/src/include/lwip/snmp_msg.h new file mode 100644 index 0000000..1183e3a --- /dev/null +++ b/src/lwip-1.4.1/src/include/lwip/snmp_msg.h @@ -0,0 +1,315 @@ +/** + * @file + * SNMP Agent message handling structures. + */ + +/* + * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * Author: Christiaan Simons + */ + +#ifndef __LWIP_SNMP_MSG_H__ +#define __LWIP_SNMP_MSG_H__ + +#include "lwip/opt.h" +#include "lwip/snmp.h" +#include "lwip/snmp_structs.h" +#include "lwip/ip_addr.h" +#include "lwip/err.h" + +#if LWIP_SNMP + +#if SNMP_PRIVATE_MIB +/* When using a private MIB, you have to create a file 'private_mib.h' that contains + * a 'struct mib_array_node mib_private' which contains your MIB. */ +#include "private_mib.h" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* The listen port of the SNMP agent. Clients have to make their requests to + this port. Most standard clients won't work if you change this! */ +#ifndef SNMP_IN_PORT +#define SNMP_IN_PORT 161 +#endif +/* The remote port the SNMP agent sends traps to. Most standard trap sinks won't + work if you change this! */ +#ifndef SNMP_TRAP_PORT +#define SNMP_TRAP_PORT 162 +#endif + +#define SNMP_ES_NOERROR 0 +#define SNMP_ES_TOOBIG 1 +#define SNMP_ES_NOSUCHNAME 2 +#define SNMP_ES_BADVALUE 3 +#define SNMP_ES_READONLY 4 +#define SNMP_ES_GENERROR 5 + +#define SNMP_GENTRAP_COLDSTART 0 +#define SNMP_GENTRAP_WARMSTART 1 +#define SNMP_GENTRAP_AUTHFAIL 4 +#define SNMP_GENTRAP_ENTERPRISESPC 6 + +struct snmp_varbind +{ + /* next pointer, NULL for last in list */ + struct snmp_varbind *next; + /* previous pointer, NULL for first in list */ + struct snmp_varbind *prev; + + /* object identifier length (in s32_t) */ + u8_t ident_len; + /* object identifier array */ + s32_t *ident; + + /* object value ASN1 type */ + u8_t value_type; + /* object value length (in u8_t) */ + u8_t value_len; + /* object value */ + void *value; + + /* encoding varbind seq length length */ + u8_t seqlenlen; + /* encoding object identifier length length */ + u8_t olenlen; + /* encoding object value length length */ + u8_t vlenlen; + /* encoding varbind seq length */ + u16_t seqlen; + /* encoding object identifier length */ + u16_t olen; + /* encoding object value length */ + u16_t vlen; +}; + +struct snmp_varbind_root +{ + struct snmp_varbind *head; + struct snmp_varbind *tail; + /* number of variable bindings in list */ + u8_t count; + /* encoding varbind-list seq length length */ + u8_t seqlenlen; + /* encoding varbind-list seq length */ + u16_t seqlen; +}; + +/** output response message header length fields */ +struct snmp_resp_header_lengths +{ + /* encoding error-index length length */ + u8_t erridxlenlen; + /* encoding error-status length length */ + u8_t errstatlenlen; + /* encoding request id length length */ + u8_t ridlenlen; + /* encoding pdu length length */ + u8_t pdulenlen; + /* encoding community length length */ + u8_t comlenlen; + /* encoding version length length */ + u8_t verlenlen; + /* encoding sequence length length */ + u8_t seqlenlen; + + /* encoding error-index length */ + u16_t erridxlen; + /* encoding error-status length */ + u16_t errstatlen; + /* encoding request id length */ + u16_t ridlen; + /* encoding pdu length */ + u16_t pdulen; + /* encoding community length */ + u16_t comlen; + /* encoding version length */ + u16_t verlen; + /* encoding sequence length */ + u16_t seqlen; +}; + +/** output response message header length fields */ +struct snmp_trap_header_lengths +{ + /* encoding timestamp length length */ + u8_t tslenlen; + /* encoding specific-trap length length */ + u8_t strplenlen; + /* encoding generic-trap length length */ + u8_t gtrplenlen; + /* encoding agent-addr length length */ + u8_t aaddrlenlen; + /* encoding enterprise-id length length */ + u8_t eidlenlen; + /* encoding pdu length length */ + u8_t pdulenlen; + /* encoding community length length */ + u8_t comlenlen; + /* encoding version length length */ + u8_t verlenlen; + /* encoding sequence length length */ + u8_t seqlenlen; + + /* encoding timestamp length */ + u16_t tslen; + /* encoding specific-trap length */ + u16_t strplen; + /* encoding generic-trap length */ + u16_t gtrplen; + /* encoding agent-addr length */ + u16_t aaddrlen; + /* encoding enterprise-id length */ + u16_t eidlen; + /* encoding pdu length */ + u16_t pdulen; + /* encoding community length */ + u16_t comlen; + /* encoding version length */ + u16_t verlen; + /* encoding sequence length */ + u16_t seqlen; +}; + +/* Accepting new SNMP messages. */ +#define SNMP_MSG_EMPTY 0 +/* Search for matching object for variable binding. */ +#define SNMP_MSG_SEARCH_OBJ 1 +/* Perform SNMP operation on in-memory object. + Pass-through states, for symmetry only. */ +#define SNMP_MSG_INTERNAL_GET_OBJDEF 2 +#define SNMP_MSG_INTERNAL_GET_VALUE 3 +#define SNMP_MSG_INTERNAL_SET_TEST 4 +#define SNMP_MSG_INTERNAL_GET_OBJDEF_S 5 +#define SNMP_MSG_INTERNAL_SET_VALUE 6 +/* Perform SNMP operation on object located externally. + In theory this could be used for building a proxy agent. + Practical use is for an enterprise spc. app. gateway. */ +#define SNMP_MSG_EXTERNAL_GET_OBJDEF 7 +#define SNMP_MSG_EXTERNAL_GET_VALUE 8 +#define SNMP_MSG_EXTERNAL_SET_TEST 9 +#define SNMP_MSG_EXTERNAL_GET_OBJDEF_S 10 +#define SNMP_MSG_EXTERNAL_SET_VALUE 11 + +#define SNMP_COMMUNITY_STR_LEN 64 +struct snmp_msg_pstat +{ + /* lwIP local port (161) binding */ + struct udp_pcb *pcb; + /* source IP address */ + ip_addr_t sip; + /* source UDP port */ + u16_t sp; + /* request type */ + u8_t rt; + /* request ID */ + s32_t rid; + /* error status */ + s32_t error_status; + /* error index */ + s32_t error_index; + /* community name (zero terminated) */ + u8_t community[SNMP_COMMUNITY_STR_LEN + 1]; + /* community string length (exclusive zero term) */ + u8_t com_strlen; + /* one out of MSG_EMPTY, MSG_DEMUX, MSG_INTERNAL, MSG_EXTERNAL_x */ + u8_t state; + /* saved arguments for MSG_EXTERNAL_x */ + struct mib_external_node *ext_mib_node; + struct snmp_name_ptr ext_name_ptr; + struct obj_def ext_object_def; + struct snmp_obj_id ext_oid; + /* index into input variable binding list */ + u8_t vb_idx; + /* ptr into input variable binding list */ + struct snmp_varbind *vb_ptr; + /* list of variable bindings from input */ + struct snmp_varbind_root invb; + /* list of variable bindings to output */ + struct snmp_varbind_root outvb; + /* output response lengths used in ASN encoding */ + struct snmp_resp_header_lengths rhl; +}; + +struct snmp_msg_trap +{ + /* lwIP local port (161) binding */ + struct udp_pcb *pcb; + /* destination IP address in network order */ + ip_addr_t dip; + + /* source enterprise ID (sysObjectID) */ + struct snmp_obj_id *enterprise; + /* source IP address, raw network order format */ + u8_t sip_raw[4]; + /* generic trap code */ + u32_t gen_trap; + /* specific trap code */ + u32_t spc_trap; + /* timestamp */ + u32_t ts; + /* list of variable bindings to output */ + struct snmp_varbind_root outvb; + /* output trap lengths used in ASN encoding */ + struct snmp_trap_header_lengths thl; +}; + +/** Agent Version constant, 0 = v1 oddity */ +extern const s32_t snmp_version; +/** Agent default "public" community string */ +extern const char snmp_publiccommunity[7]; + +extern struct snmp_msg_trap trap_msg; + +/** Agent setup, start listening to port 161. */ +void snmp_init(void); +void snmp_trap_dst_enable(u8_t dst_idx, u8_t enable); +void snmp_trap_dst_ip_set(u8_t dst_idx, ip_addr_t *dst); + +/** Varbind-list functions. */ +struct snmp_varbind* snmp_varbind_alloc(struct snmp_obj_id *oid, u8_t type, u8_t len); +void snmp_varbind_free(struct snmp_varbind *vb); +void snmp_varbind_list_free(struct snmp_varbind_root *root); +void snmp_varbind_tail_add(struct snmp_varbind_root *root, struct snmp_varbind *vb); +struct snmp_varbind* snmp_varbind_tail_remove(struct snmp_varbind_root *root); + +/** Handle an internal (recv) or external (private response) event. */ +void snmp_msg_event(u8_t request_id); +err_t snmp_send_response(struct snmp_msg_pstat *m_stat); +err_t snmp_send_trap(s8_t generic_trap, struct snmp_obj_id *eoid, s32_t specific_trap); +void snmp_coldstart_trap(void); +void snmp_authfail_trap(void); + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_SNMP */ + +#endif /* __LWIP_SNMP_MSG_H__ */ diff --git a/src/lwip-1.4.1/src/include/lwip/snmp_structs.h b/src/lwip-1.4.1/src/include/lwip/snmp_structs.h new file mode 100644 index 0000000..0d3b46a --- /dev/null +++ b/src/lwip-1.4.1/src/include/lwip/snmp_structs.h @@ -0,0 +1,268 @@ +/** + * @file + * Generic MIB tree structures. + * + * @todo namespace prefixes + */ + +/* + * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * Author: Christiaan Simons + */ + +#ifndef __LWIP_SNMP_STRUCTS_H__ +#define __LWIP_SNMP_STRUCTS_H__ + +#include "lwip/opt.h" + +#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/snmp.h" + +#if SNMP_PRIVATE_MIB +/* When using a private MIB, you have to create a file 'private_mib.h' that contains + * a 'struct mib_array_node mib_private' which contains your MIB. */ +#include "private_mib.h" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* MIB object instance */ +#define MIB_OBJECT_NONE 0 +#define MIB_OBJECT_SCALAR 1 +#define MIB_OBJECT_TAB 2 + +/* MIB access types */ +#define MIB_ACCESS_READ 1 +#define MIB_ACCESS_WRITE 2 + +/* MIB object access */ +#define MIB_OBJECT_READ_ONLY MIB_ACCESS_READ +#define MIB_OBJECT_READ_WRITE (MIB_ACCESS_READ | MIB_ACCESS_WRITE) +#define MIB_OBJECT_WRITE_ONLY MIB_ACCESS_WRITE +#define MIB_OBJECT_NOT_ACCESSIBLE 0 + +/** object definition returned by (get_object_def)() */ +struct obj_def +{ + /* MIB_OBJECT_NONE (0), MIB_OBJECT_SCALAR (1), MIB_OBJECT_TAB (2) */ + u8_t instance; + /* 0 read-only, 1 read-write, 2 write-only, 3 not-accessible */ + u8_t access; + /* ASN type for this object */ + u8_t asn_type; + /* value length (host length) */ + u16_t v_len; + /* length of instance part of supplied object identifier */ + u8_t id_inst_len; + /* instance part of supplied object identifier */ + s32_t *id_inst_ptr; +}; + +struct snmp_name_ptr +{ + u8_t ident_len; + s32_t *ident; +}; + +/** MIB const scalar (.0) node */ +#define MIB_NODE_SC 0x01 +/** MIB const array node */ +#define MIB_NODE_AR 0x02 +/** MIB array node (mem_malloced from RAM) */ +#define MIB_NODE_RA 0x03 +/** MIB list root node (mem_malloced from RAM) */ +#define MIB_NODE_LR 0x04 +/** MIB node for external objects */ +#define MIB_NODE_EX 0x05 + +/** node "base class" layout, the mandatory fields for a node */ +struct mib_node +{ + /** returns struct obj_def for the given object identifier */ + void (*get_object_def)(u8_t ident_len, s32_t *ident, struct obj_def *od); + /** returns object value for the given object identifier, + @note the caller must allocate at least len bytes for the value */ + void (*get_value)(struct obj_def *od, u16_t len, void *value); + /** tests length and/or range BEFORE setting */ + u8_t (*set_test)(struct obj_def *od, u16_t len, void *value); + /** sets object value, only to be called when set_test() */ + void (*set_value)(struct obj_def *od, u16_t len, void *value); + /** One out of MIB_NODE_AR, MIB_NODE_LR or MIB_NODE_EX */ + u8_t node_type; + /* array or max list length */ + u16_t maxlength; +}; + +/** derived node for scalars .0 index */ +typedef struct mib_node mib_scalar_node; + +/** derived node, points to a fixed size const array + of sub-identifiers plus a 'child' pointer */ +struct mib_array_node +{ + /* inherited "base class" members */ + void (*get_object_def)(u8_t ident_len, s32_t *ident, struct obj_def *od); + void (*get_value)(struct obj_def *od, u16_t len, void *value); + u8_t (*set_test)(struct obj_def *od, u16_t len, void *value); + void (*set_value)(struct obj_def *od, u16_t len, void *value); + + u8_t node_type; + u16_t maxlength; + + /* additional struct members */ + const s32_t *objid; + struct mib_node* const *nptr; +}; + +/** derived node, points to a fixed size mem_malloced array + of sub-identifiers plus a 'child' pointer */ +struct mib_ram_array_node +{ + /* inherited "base class" members */ + void (*get_object_def)(u8_t ident_len, s32_t *ident, struct obj_def *od); + void (*get_value)(struct obj_def *od, u16_t len, void *value); + u8_t (*set_test)(struct obj_def *od, u16_t len, void *value); + void (*set_value)(struct obj_def *od, u16_t len, void *value); + + u8_t node_type; + u16_t maxlength; + + /* aditional struct members */ + s32_t *objid; + struct mib_node **nptr; +}; + +struct mib_list_node +{ + struct mib_list_node *prev; + struct mib_list_node *next; + s32_t objid; + struct mib_node *nptr; +}; + +/** derived node, points to a doubly linked list + of sub-identifiers plus a 'child' pointer */ +struct mib_list_rootnode +{ + /* inherited "base class" members */ + void (*get_object_def)(u8_t ident_len, s32_t *ident, struct obj_def *od); + void (*get_value)(struct obj_def *od, u16_t len, void *value); + u8_t (*set_test)(struct obj_def *od, u16_t len, void *value); + void (*set_value)(struct obj_def *od, u16_t len, void *value); + + u8_t node_type; + u16_t maxlength; + + /* additional struct members */ + struct mib_list_node *head; + struct mib_list_node *tail; + /* counts list nodes in list */ + u16_t count; +}; + +/** derived node, has access functions for mib object in external memory or device + using 'tree_level' and 'idx', with a range 0 .. (level_length() - 1) */ +struct mib_external_node +{ + /* inherited "base class" members */ + void (*get_object_def)(u8_t ident_len, s32_t *ident, struct obj_def *od); + void (*get_value)(struct obj_def *od, u16_t len, void *value); + u8_t (*set_test)(struct obj_def *od, u16_t len, void *value); + void (*set_value)(struct obj_def *od, u16_t len, void *value); + + u8_t node_type; + u16_t maxlength; + + /* additional struct members */ + /** points to an external (in memory) record of some sort of addressing + information, passed to and interpreted by the funtions below */ + void* addr_inf; + /** tree levels under this node */ + u8_t tree_levels; + /** number of objects at this level */ + u16_t (*level_length)(void* addr_inf, u8_t level); + /** compares object sub identifier with external id + return zero when equal, nonzero when unequal */ + s32_t (*ident_cmp)(void* addr_inf, u8_t level, u16_t idx, s32_t sub_id); + void (*get_objid)(void* addr_inf, u8_t level, u16_t idx, s32_t *sub_id); + + /** async Questions */ + void (*get_object_def_q)(void* addr_inf, u8_t rid, u8_t ident_len, s32_t *ident); + void (*get_value_q)(u8_t rid, struct obj_def *od); + void (*set_test_q)(u8_t rid, struct obj_def *od); + void (*set_value_q)(u8_t rid, struct obj_def *od, u16_t len, void *value); + /** async Answers */ + void (*get_object_def_a)(u8_t rid, u8_t ident_len, s32_t *ident, struct obj_def *od); + void (*get_value_a)(u8_t rid, struct obj_def *od, u16_t len, void *value); + u8_t (*set_test_a)(u8_t rid, struct obj_def *od, u16_t len, void *value); + void (*set_value_a)(u8_t rid, struct obj_def *od, u16_t len, void *value); + /** async Panic Close (agent returns error reply, + e.g. used for external transaction cleanup) */ + void (*get_object_def_pc)(u8_t rid, u8_t ident_len, s32_t *ident); + void (*get_value_pc)(u8_t rid, struct obj_def *od); + void (*set_test_pc)(u8_t rid, struct obj_def *od); + void (*set_value_pc)(u8_t rid, struct obj_def *od); +}; + +/** export MIB tree from mib2.c */ +extern const struct mib_array_node internet; + +/** dummy function pointers for non-leaf MIB nodes from mib2.c */ +void noleafs_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od); +void noleafs_get_value(struct obj_def *od, u16_t len, void *value); +u8_t noleafs_set_test(struct obj_def *od, u16_t len, void *value); +void noleafs_set_value(struct obj_def *od, u16_t len, void *value); + +void snmp_oidtoip(s32_t *ident, ip_addr_t *ip); +void snmp_iptooid(ip_addr_t *ip, s32_t *ident); +void snmp_ifindextonetif(s32_t ifindex, struct netif **netif); +void snmp_netiftoifindex(struct netif *netif, s32_t *ifidx); + +struct mib_list_node* snmp_mib_ln_alloc(s32_t id); +void snmp_mib_ln_free(struct mib_list_node *ln); +struct mib_list_rootnode* snmp_mib_lrn_alloc(void); +void snmp_mib_lrn_free(struct mib_list_rootnode *lrn); + +s8_t snmp_mib_node_insert(struct mib_list_rootnode *rn, s32_t objid, struct mib_list_node **insn); +s8_t snmp_mib_node_find(struct mib_list_rootnode *rn, s32_t objid, struct mib_list_node **fn); +struct mib_list_rootnode *snmp_mib_node_delete(struct mib_list_rootnode *rn, struct mib_list_node *n); + +struct mib_node* snmp_search_tree(struct mib_node *node, u8_t ident_len, s32_t *ident, struct snmp_name_ptr *np); +struct mib_node* snmp_expand_tree(struct mib_node *node, u8_t ident_len, s32_t *ident, struct snmp_obj_id *oidret); +u8_t snmp_iso_prefix_tst(u8_t ident_len, s32_t *ident); +u8_t snmp_iso_prefix_expand(u8_t ident_len, s32_t *ident, struct snmp_obj_id *oidret); + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_SNMP */ + +#endif /* __LWIP_SNMP_STRUCTS_H__ */ diff --git a/src/lwip-1.4.1/src/include/lwip/sockets.h b/src/lwip-1.4.1/src/include/lwip/sockets.h new file mode 100644 index 0000000..3ea32f1 --- /dev/null +++ b/src/lwip-1.4.1/src/include/lwip/sockets.h @@ -0,0 +1,379 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + + +#ifndef __LWIP_SOCKETS_H__ +#define __LWIP_SOCKETS_H__ + +#include "lwip/opt.h" + +#if LWIP_SOCKET /* don't build if not configured for use in lwipopts.h */ + +#include /* for size_t */ + +#include "lwip/ip_addr.h" +#include "lwip/inet.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* members are in network byte order */ +struct sockaddr_in { + u8_t sin_len; + u8_t sin_family; + u16_t sin_port; + struct in_addr sin_addr; + char sin_zero[8]; +}; + +struct sockaddr { + u8_t sa_len; + u8_t sa_family; + char sa_data[14]; +}; + +/* If your port already typedef's socklen_t, define SOCKLEN_T_DEFINED + to prevent this code from redefining it. */ +#if !defined(socklen_t) && !defined(SOCKLEN_T_DEFINED) +typedef u32_t socklen_t; +#endif + +/* Socket protocol types (TCP/UDP/RAW) */ +#define SOCK_STREAM 1 +#define SOCK_DGRAM 2 +#define SOCK_RAW 3 + +/* + * Option flags per-socket. These must match the SOF_ flags in ip.h (checked in init.c) + */ +#define SO_DEBUG 0x0001 /* Unimplemented: turn on debugging info recording */ +#define SO_ACCEPTCONN 0x0002 /* socket has had listen() */ +#define SO_REUSEADDR 0x0004 /* Allow local address reuse */ +#define SO_KEEPALIVE 0x0008 /* keep connections alive */ +#define SO_DONTROUTE 0x0010 /* Unimplemented: just use interface addresses */ +#define SO_BROADCAST 0x0020 /* permit to send and to receive broadcast messages (see IP_SOF_BROADCAST option) */ +#define SO_USELOOPBACK 0x0040 /* Unimplemented: bypass hardware when possible */ +#define SO_LINGER 0x0080 /* linger on close if data present */ +#define SO_OOBINLINE 0x0100 /* Unimplemented: leave received OOB data in line */ +#define SO_REUSEPORT 0x0200 /* Unimplemented: allow local address & port reuse */ + +#define SO_DONTLINGER ((int)(~SO_LINGER)) + +/* + * Additional options, not kept in so_options. + */ +#define SO_SNDBUF 0x1001 /* Unimplemented: send buffer size */ +#define SO_RCVBUF 0x1002 /* receive buffer size */ +#define SO_SNDLOWAT 0x1003 /* Unimplemented: send low-water mark */ +#define SO_RCVLOWAT 0x1004 /* Unimplemented: receive low-water mark */ +#define SO_SNDTIMEO 0x1005 /* Unimplemented: send timeout */ +#define SO_RCVTIMEO 0x1006 /* receive timeout */ +#define SO_ERROR 0x1007 /* get error status and clear */ +#define SO_TYPE 0x1008 /* get socket type */ +#define SO_CONTIMEO 0x1009 /* Unimplemented: connect timeout */ +#define SO_NO_CHECK 0x100a /* don't create UDP checksum */ + + +/* + * Structure used for manipulating linger option. + */ +struct linger { + int l_onoff; /* option on/off */ + int l_linger; /* linger time */ +}; + +/* + * Level number for (get/set)sockopt() to apply to socket itself. + */ +#define SOL_SOCKET 0xfff /* options for socket level */ + + +#define AF_UNSPEC 0 +#define AF_INET 2 +#define PF_INET AF_INET +#define PF_UNSPEC AF_UNSPEC + +#define IPPROTO_IP 0 +#define IPPROTO_TCP 6 +#define IPPROTO_UDP 17 +#define IPPROTO_UDPLITE 136 + +/* Flags we can use with send and recv. */ +#define MSG_PEEK 0x01 /* Peeks at an incoming message */ +#define MSG_WAITALL 0x02 /* Unimplemented: Requests that the function block until the full amount of data requested can be returned */ +#define MSG_OOB 0x04 /* Unimplemented: Requests out-of-band data. The significance and semantics of out-of-band data are protocol-specific */ +#define MSG_DONTWAIT 0x08 /* Nonblocking i/o for this operation only */ +#define MSG_MORE 0x10 /* Sender will send more */ + + +/* + * Options for level IPPROTO_IP + */ +#define IP_TOS 1 +#define IP_TTL 2 + +#if LWIP_TCP +/* + * Options for level IPPROTO_TCP + */ +#define TCP_NODELAY 0x01 /* don't delay send to coalesce packets */ +#define TCP_KEEPALIVE 0x02 /* send KEEPALIVE probes when idle for pcb->keep_idle milliseconds */ +#define TCP_KEEPIDLE 0x03 /* set pcb->keep_idle - Same as TCP_KEEPALIVE, but use seconds for get/setsockopt */ +#define TCP_KEEPINTVL 0x04 /* set pcb->keep_intvl - Use seconds for get/setsockopt */ +#define TCP_KEEPCNT 0x05 /* set pcb->keep_cnt - Use number of probes sent for get/setsockopt */ +#endif /* LWIP_TCP */ + +#if LWIP_UDP && LWIP_UDPLITE +/* + * Options for level IPPROTO_UDPLITE + */ +#define UDPLITE_SEND_CSCOV 0x01 /* sender checksum coverage */ +#define UDPLITE_RECV_CSCOV 0x02 /* minimal receiver checksum coverage */ +#endif /* LWIP_UDP && LWIP_UDPLITE*/ + + +#if LWIP_IGMP +/* + * Options and types for UDP multicast traffic handling + */ +#define IP_ADD_MEMBERSHIP 3 +#define IP_DROP_MEMBERSHIP 4 +#define IP_MULTICAST_TTL 5 +#define IP_MULTICAST_IF 6 +#define IP_MULTICAST_LOOP 7 + +typedef struct ip_mreq { + struct in_addr imr_multiaddr; /* IP multicast address of group */ + struct in_addr imr_interface; /* local IP address of interface */ +} ip_mreq; +#endif /* LWIP_IGMP */ + +/* + * The Type of Service provides an indication of the abstract + * parameters of the quality of service desired. These parameters are + * to be used to guide the selection of the actual service parameters + * when transmitting a datagram through a particular network. Several + * networks offer service precedence, which somehow treats high + * precedence traffic as more important than other traffic (generally + * by accepting only traffic above a certain precedence at time of high + * load). The major choice is a three way tradeoff between low-delay, + * high-reliability, and high-throughput. + * The use of the Delay, Throughput, and Reliability indications may + * increase the cost (in some sense) of the service. In many networks + * better performance for one of these parameters is coupled with worse + * performance on another. Except for very unusual cases at most two + * of these three indications should be set. + */ +#define IPTOS_TOS_MASK 0x1E +#define IPTOS_TOS(tos) ((tos) & IPTOS_TOS_MASK) +#define IPTOS_LOWDELAY 0x10 +#define IPTOS_THROUGHPUT 0x08 +#define IPTOS_RELIABILITY 0x04 +#define IPTOS_LOWCOST 0x02 +#define IPTOS_MINCOST IPTOS_LOWCOST + +/* + * The Network Control precedence designation is intended to be used + * within a network only. The actual use and control of that + * designation is up to each network. The Internetwork Control + * designation is intended for use by gateway control originators only. + * If the actual use of these precedence designations is of concern to + * a particular network, it is the responsibility of that network to + * control the access to, and use of, those precedence designations. + */ +#define IPTOS_PREC_MASK 0xe0 +#define IPTOS_PREC(tos) ((tos) & IPTOS_PREC_MASK) +#define IPTOS_PREC_NETCONTROL 0xe0 +#define IPTOS_PREC_INTERNETCONTROL 0xc0 +#define IPTOS_PREC_CRITIC_ECP 0xa0 +#define IPTOS_PREC_FLASHOVERRIDE 0x80 +#define IPTOS_PREC_FLASH 0x60 +#define IPTOS_PREC_IMMEDIATE 0x40 +#define IPTOS_PREC_PRIORITY 0x20 +#define IPTOS_PREC_ROUTINE 0x00 + + +/* + * Commands for ioctlsocket(), taken from the BSD file fcntl.h. + * lwip_ioctl only supports FIONREAD and FIONBIO, for now + * + * Ioctl's have the command encoded in the lower word, + * and the size of any in or out parameters in the upper + * word. The high 2 bits of the upper word are used + * to encode the in/out status of the parameter; for now + * we restrict parameters to at most 128 bytes. + */ +#if !defined(FIONREAD) || !defined(FIONBIO) +#define IOCPARM_MASK 0x7fU /* parameters must be < 128 bytes */ +#define IOC_VOID 0x20000000UL /* no parameters */ +#define IOC_OUT 0x40000000UL /* copy out parameters */ +#define IOC_IN 0x80000000UL /* copy in parameters */ +#define IOC_INOUT (IOC_IN|IOC_OUT) + /* 0x20000000 distinguishes new & + old ioctl's */ +#define _IO(x,y) (IOC_VOID|((x)<<8)|(y)) + +#define _IOR(x,y,t) (IOC_OUT|(((long)sizeof(t)&IOCPARM_MASK)<<16)|((x)<<8)|(y)) + +#define _IOW(x,y,t) (IOC_IN|(((long)sizeof(t)&IOCPARM_MASK)<<16)|((x)<<8)|(y)) +#endif /* !defined(FIONREAD) || !defined(FIONBIO) */ + +#ifndef FIONREAD +#define FIONREAD _IOR('f', 127, unsigned long) /* get # bytes to read */ +#endif +#ifndef FIONBIO +#define FIONBIO _IOW('f', 126, unsigned long) /* set/clear non-blocking i/o */ +#endif + +/* Socket I/O Controls: unimplemented */ +#ifndef SIOCSHIWAT +#define SIOCSHIWAT _IOW('s', 0, unsigned long) /* set high watermark */ +#define SIOCGHIWAT _IOR('s', 1, unsigned long) /* get high watermark */ +#define SIOCSLOWAT _IOW('s', 2, unsigned long) /* set low watermark */ +#define SIOCGLOWAT _IOR('s', 3, unsigned long) /* get low watermark */ +#define SIOCATMARK _IOR('s', 7, unsigned long) /* at oob mark? */ +#endif + +/* commands for fnctl */ +#ifndef F_GETFL +#define F_GETFL 3 +#endif +#ifndef F_SETFL +#define F_SETFL 4 +#endif + +/* File status flags and file access modes for fnctl, + these are bits in an int. */ +#ifndef O_NONBLOCK +#define O_NONBLOCK 1 /* nonblocking I/O */ +#endif +#ifndef O_NDELAY +#define O_NDELAY 1 /* same as O_NONBLOCK, for compatibility */ +#endif + +#ifndef SHUT_RD + #define SHUT_RD 0 + #define SHUT_WR 1 + #define SHUT_RDWR 2 +#endif + +/* FD_SET used for lwip_select */ +#ifndef FD_SET + #undef FD_SETSIZE + /* Make FD_SETSIZE match NUM_SOCKETS in socket.c */ + #define FD_SETSIZE MEMP_NUM_NETCONN + #define FD_SET(n, p) ((p)->fd_bits[(n)/8] |= (1 << ((n) & 7))) + #define FD_CLR(n, p) ((p)->fd_bits[(n)/8] &= ~(1 << ((n) & 7))) + #define FD_ISSET(n,p) ((p)->fd_bits[(n)/8] & (1 << ((n) & 7))) + #define FD_ZERO(p) memset((void*)(p),0,sizeof(*(p))) + + typedef struct fd_set { + unsigned char fd_bits [(FD_SETSIZE+7)/8]; + } fd_set; + +#endif /* FD_SET */ + +/** LWIP_TIMEVAL_PRIVATE: if you want to use the struct timeval provided + * by your system, set this to 0 and include in cc.h */ +#ifndef LWIP_TIMEVAL_PRIVATE +#define LWIP_TIMEVAL_PRIVATE 1 +#endif + +#if LWIP_TIMEVAL_PRIVATE +struct timeval { + long tv_sec; /* seconds */ + long tv_usec; /* and microseconds */ +}; +#endif /* LWIP_TIMEVAL_PRIVATE */ + +void lwip_socket_init(void); + +int lwip_accept(int s, struct sockaddr *addr, socklen_t *addrlen); +int lwip_bind(int s, const struct sockaddr *name, socklen_t namelen); +int lwip_shutdown(int s, int how); +int lwip_getpeername (int s, struct sockaddr *name, socklen_t *namelen); +int lwip_getsockname (int s, struct sockaddr *name, socklen_t *namelen); +int lwip_getsockopt (int s, int level, int optname, void *optval, socklen_t *optlen); +int lwip_setsockopt (int s, int level, int optname, const void *optval, socklen_t optlen); +int lwip_close(int s); +int lwip_connect(int s, const struct sockaddr *name, socklen_t namelen); +int lwip_listen(int s, int backlog); +int lwip_recv(int s, void *mem, size_t len, int flags); +int lwip_read(int s, void *mem, size_t len); +int lwip_recvfrom(int s, void *mem, size_t len, int flags, + struct sockaddr *from, socklen_t *fromlen); +int lwip_send(int s, const void *dataptr, size_t size, int flags); +int lwip_sendto(int s, const void *dataptr, size_t size, int flags, + const struct sockaddr *to, socklen_t tolen); +int lwip_socket(int domain, int type, int protocol); +int lwip_write(int s, const void *dataptr, size_t size); +int lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset, + struct timeval *timeout); +int lwip_ioctl(int s, long cmd, void *argp); +int lwip_fcntl(int s, int cmd, int val); + +#if LWIP_COMPAT_SOCKETS +#define accept(a,b,c) lwip_accept(a,b,c) +#define bind(a,b,c) lwip_bind(a,b,c) +#define shutdown(a,b) lwip_shutdown(a,b) +#define closesocket(s) lwip_close(s) +#define connect(a,b,c) lwip_connect(a,b,c) +#define getsockname(a,b,c) lwip_getsockname(a,b,c) +#define getpeername(a,b,c) lwip_getpeername(a,b,c) +#define setsockopt(a,b,c,d,e) lwip_setsockopt(a,b,c,d,e) +#define getsockopt(a,b,c,d,e) lwip_getsockopt(a,b,c,d,e) +#define listen(a,b) lwip_listen(a,b) +#define recv(a,b,c,d) lwip_recv(a,b,c,d) +#define recvfrom(a,b,c,d,e,f) lwip_recvfrom(a,b,c,d,e,f) +#define send(a,b,c,d) lwip_send(a,b,c,d) +#define sendto(a,b,c,d,e,f) lwip_sendto(a,b,c,d,e,f) +#define socket(a,b,c) lwip_socket(a,b,c) +#define select(a,b,c,d,e) lwip_select(a,b,c,d,e) +#define ioctlsocket(a,b,c) lwip_ioctl(a,b,c) + +#if LWIP_POSIX_SOCKETS_IO_NAMES +#define read(a,b,c) lwip_read(a,b,c) +#define write(a,b,c) lwip_write(a,b,c) +#define close(s) lwip_close(s) +#define fcntl(a,b,c) lwip_fcntl(a,b,c) +#endif /* LWIP_POSIX_SOCKETS_IO_NAMES */ + +#endif /* LWIP_COMPAT_SOCKETS */ + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_SOCKET */ + +#endif /* __LWIP_SOCKETS_H__ */ diff --git a/src/lwip-1.4.1/src/include/lwip/stats.h b/src/lwip-1.4.1/src/include/lwip/stats.h new file mode 100644 index 0000000..1f5152a --- /dev/null +++ b/src/lwip-1.4.1/src/include/lwip/stats.h @@ -0,0 +1,292 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __LWIP_STATS_H__ +#define __LWIP_STATS_H__ + +#include "lwip/opt.h" + +#include "lwip/mem.h" +#include "lwip/memp.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if LWIP_STATS + +#ifndef LWIP_STATS_LARGE +#define LWIP_STATS_LARGE 0 +#endif + +#if LWIP_STATS_LARGE +#define STAT_COUNTER u32_t +#define STAT_COUNTER_F U32_F +#else +#define STAT_COUNTER u16_t +#define STAT_COUNTER_F U16_F +#endif + +struct stats_proto { + STAT_COUNTER xmit; /* Transmitted packets. */ + STAT_COUNTER recv; /* Received packets. */ + STAT_COUNTER fw; /* Forwarded packets. */ + STAT_COUNTER drop; /* Dropped packets. */ + STAT_COUNTER chkerr; /* Checksum error. */ + STAT_COUNTER lenerr; /* Invalid length error. */ + STAT_COUNTER memerr; /* Out of memory error. */ + STAT_COUNTER rterr; /* Routing error. */ + STAT_COUNTER proterr; /* Protocol error. */ + STAT_COUNTER opterr; /* Error in options. */ + STAT_COUNTER err; /* Misc error. */ + STAT_COUNTER cachehit; +}; + +struct stats_igmp { + STAT_COUNTER xmit; /* Transmitted packets. */ + STAT_COUNTER recv; /* Received packets. */ + STAT_COUNTER drop; /* Dropped packets. */ + STAT_COUNTER chkerr; /* Checksum error. */ + STAT_COUNTER lenerr; /* Invalid length error. */ + STAT_COUNTER memerr; /* Out of memory error. */ + STAT_COUNTER proterr; /* Protocol error. */ + STAT_COUNTER rx_v1; /* Received v1 frames. */ + STAT_COUNTER rx_group; /* Received group-specific queries. */ + STAT_COUNTER rx_general; /* Received general queries. */ + STAT_COUNTER rx_report; /* Received reports. */ + STAT_COUNTER tx_join; /* Sent joins. */ + STAT_COUNTER tx_leave; /* Sent leaves. */ + STAT_COUNTER tx_report; /* Sent reports. */ +}; + +struct stats_mem { +#ifdef LWIP_DEBUG + const char *name; +#endif /* LWIP_DEBUG */ + mem_size_t avail; + mem_size_t used; + mem_size_t max; + STAT_COUNTER err; + STAT_COUNTER illegal; +}; + +struct stats_syselem { + STAT_COUNTER used; + STAT_COUNTER max; + STAT_COUNTER err; +}; + +struct stats_sys { + struct stats_syselem sem; + struct stats_syselem mutex; + struct stats_syselem mbox; +}; + +struct stats_ { +#if LINK_STATS + struct stats_proto link; +#endif +#if ETHARP_STATS + struct stats_proto etharp; +#endif +#if IPFRAG_STATS + struct stats_proto ip_frag; +#endif +#if IP_STATS + struct stats_proto ip; +#endif +#if ICMP_STATS + struct stats_proto icmp; +#endif +#if IGMP_STATS + struct stats_igmp igmp; +#endif +#if UDP_STATS + struct stats_proto udp; +#endif +#if TCP_STATS + struct stats_proto tcp; +#endif +#if MEM_STATS + struct stats_mem mem; +#endif +#if MEMP_STATS + struct stats_mem memp[MEMP_MAX]; +#endif +#if SYS_STATS + struct stats_sys sys; +#endif +}; + +extern struct stats_ lwip_stats; + +void stats_init(void); + +#define STATS_INC(x) ++lwip_stats.x +#define STATS_DEC(x) --lwip_stats.x +#define STATS_INC_USED(x, y) do { lwip_stats.x.used += y; \ + if (lwip_stats.x.max < lwip_stats.x.used) { \ + lwip_stats.x.max = lwip_stats.x.used; \ + } \ + } while(0) +#else /* LWIP_STATS */ +#define stats_init() +#define STATS_INC(x) +#define STATS_DEC(x) +#define STATS_INC_USED(x) +#endif /* LWIP_STATS */ + +#if TCP_STATS +#define TCP_STATS_INC(x) STATS_INC(x) +#define TCP_STATS_DISPLAY() stats_display_proto(&lwip_stats.tcp, "TCP") +#else +#define TCP_STATS_INC(x) +#define TCP_STATS_DISPLAY() +#endif + +#if UDP_STATS +#define UDP_STATS_INC(x) STATS_INC(x) +#define UDP_STATS_DISPLAY() stats_display_proto(&lwip_stats.udp, "UDP") +#else +#define UDP_STATS_INC(x) +#define UDP_STATS_DISPLAY() +#endif + +#if ICMP_STATS +#define ICMP_STATS_INC(x) STATS_INC(x) +#define ICMP_STATS_DISPLAY() stats_display_proto(&lwip_stats.icmp, "ICMP") +#else +#define ICMP_STATS_INC(x) +#define ICMP_STATS_DISPLAY() +#endif + +#if IGMP_STATS +#define IGMP_STATS_INC(x) STATS_INC(x) +#define IGMP_STATS_DISPLAY() stats_display_igmp(&lwip_stats.igmp) +#else +#define IGMP_STATS_INC(x) +#define IGMP_STATS_DISPLAY() +#endif + +#if IP_STATS +#define IP_STATS_INC(x) STATS_INC(x) +#define IP_STATS_DISPLAY() stats_display_proto(&lwip_stats.ip, "IP") +#else +#define IP_STATS_INC(x) +#define IP_STATS_DISPLAY() +#endif + +#if IPFRAG_STATS +#define IPFRAG_STATS_INC(x) STATS_INC(x) +#define IPFRAG_STATS_DISPLAY() stats_display_proto(&lwip_stats.ip_frag, "IP_FRAG") +#else +#define IPFRAG_STATS_INC(x) +#define IPFRAG_STATS_DISPLAY() +#endif + +#if ETHARP_STATS +#define ETHARP_STATS_INC(x) STATS_INC(x) +#define ETHARP_STATS_DISPLAY() stats_display_proto(&lwip_stats.etharp, "ETHARP") +#else +#define ETHARP_STATS_INC(x) +#define ETHARP_STATS_DISPLAY() +#endif + +#if LINK_STATS +#define LINK_STATS_INC(x) STATS_INC(x) +#define LINK_STATS_DISPLAY() stats_display_proto(&lwip_stats.link, "LINK") +#else +#define LINK_STATS_INC(x) +#define LINK_STATS_DISPLAY() +#endif + +#if MEM_STATS +#define MEM_STATS_AVAIL(x, y) lwip_stats.mem.x = y +#define MEM_STATS_INC(x) STATS_INC(mem.x) +#define MEM_STATS_INC_USED(x, y) STATS_INC_USED(mem, y) +#define MEM_STATS_DEC_USED(x, y) lwip_stats.mem.x -= y +#define MEM_STATS_DISPLAY() stats_display_mem(&lwip_stats.mem, "HEAP") +#else +#define MEM_STATS_AVAIL(x, y) +#define MEM_STATS_INC(x) +#define MEM_STATS_INC_USED(x, y) +#define MEM_STATS_DEC_USED(x, y) +#define MEM_STATS_DISPLAY() +#endif + +#if MEMP_STATS +#define MEMP_STATS_AVAIL(x, i, y) lwip_stats.memp[i].x = y +#define MEMP_STATS_INC(x, i) STATS_INC(memp[i].x) +#define MEMP_STATS_DEC(x, i) STATS_DEC(memp[i].x) +#define MEMP_STATS_INC_USED(x, i) STATS_INC_USED(memp[i], 1) +#define MEMP_STATS_DISPLAY(i) stats_display_memp(&lwip_stats.memp[i], i) +#else +#define MEMP_STATS_AVAIL(x, i, y) +#define MEMP_STATS_INC(x, i) +#define MEMP_STATS_DEC(x, i) +#define MEMP_STATS_INC_USED(x, i) +#define MEMP_STATS_DISPLAY(i) +#endif + +#if SYS_STATS +#define SYS_STATS_INC(x) STATS_INC(sys.x) +#define SYS_STATS_DEC(x) STATS_DEC(sys.x) +#define SYS_STATS_INC_USED(x) STATS_INC_USED(sys.x, 1) +#define SYS_STATS_DISPLAY() stats_display_sys(&lwip_stats.sys) +#else +#define SYS_STATS_INC(x) +#define SYS_STATS_DEC(x) +#define SYS_STATS_INC_USED(x) +#define SYS_STATS_DISPLAY() +#endif + +/* Display of statistics */ +#if LWIP_STATS_DISPLAY +void stats_display(void); +void stats_display_proto(struct stats_proto *proto, const char *name); +void stats_display_igmp(struct stats_igmp *igmp); +void stats_display_mem(struct stats_mem *mem, const char *name); +void stats_display_memp(struct stats_mem *mem, int index); +void stats_display_sys(struct stats_sys *sys); +#else /* LWIP_STATS_DISPLAY */ +#define stats_display() +#define stats_display_proto(proto, name) +#define stats_display_igmp(igmp) +#define stats_display_mem(mem, name) +#define stats_display_memp(mem, index) +#define stats_display_sys(sys) +#endif /* LWIP_STATS_DISPLAY */ + +#ifdef __cplusplus +} +#endif + +#endif /* __LWIP_STATS_H__ */ diff --git a/src/lwip-1.4.1/src/include/lwip/sys.h b/src/lwip-1.4.1/src/include/lwip/sys.h new file mode 100644 index 0000000..dc93513 --- /dev/null +++ b/src/lwip-1.4.1/src/include/lwip/sys.h @@ -0,0 +1,337 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __LWIP_SYS_H__ +#define __LWIP_SYS_H__ + +#include "lwip/opt.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if NO_SYS + +/* For a totally minimal and standalone system, we provide null + definitions of the sys_ functions. */ +typedef u8_t sys_sem_t; +typedef u8_t sys_mutex_t; +typedef u8_t sys_mbox_t; + +#define sys_sem_new(s, c) ERR_OK +#define sys_sem_signal(s) +#define sys_sem_wait(s) +#define sys_arch_sem_wait(s,t) +#define sys_sem_free(s) +#define sys_sem_valid(s) 0 +#define sys_sem_set_invalid(s) +#define sys_mutex_new(mu) ERR_OK +#define sys_mutex_lock(mu) +#define sys_mutex_unlock(mu) +#define sys_mutex_free(mu) +#define sys_mutex_valid(mu) 0 +#define sys_mutex_set_invalid(mu) +#define sys_mbox_new(m, s) ERR_OK +#define sys_mbox_fetch(m,d) +#define sys_mbox_tryfetch(m,d) +#define sys_mbox_post(m,d) +#define sys_mbox_trypost(m,d) +#define sys_mbox_free(m) +#define sys_mbox_valid(m) +#define sys_mbox_set_invalid(m) + +#define sys_thread_new(n,t,a,s,p) + +#define sys_msleep(t) + +#else /* NO_SYS */ + +/** Return code for timeouts from sys_arch_mbox_fetch and sys_arch_sem_wait */ +#define SYS_ARCH_TIMEOUT 0xffffffffUL + +/** sys_mbox_tryfetch() returns SYS_MBOX_EMPTY if appropriate. + * For now we use the same magic value, but we allow this to change in future. + */ +#define SYS_MBOX_EMPTY SYS_ARCH_TIMEOUT + +#include "lwip/err.h" +#include "arch/sys_arch.h" + +/** Function prototype for thread functions */ +typedef void (*lwip_thread_fn)(void *arg); + +/* Function prototypes for functions to be implemented by platform ports + (in sys_arch.c) */ + +/* Mutex functions: */ + +/** Define LWIP_COMPAT_MUTEX if the port has no mutexes and binary semaphores + should be used instead */ +#if LWIP_COMPAT_MUTEX +/* for old ports that don't have mutexes: define them to binary semaphores */ +#define sys_mutex_t sys_sem_t +#define sys_mutex_new(mutex) sys_sem_new(mutex, 1) +#define sys_mutex_lock(mutex) sys_sem_wait(mutex) +#define sys_mutex_unlock(mutex) sys_sem_signal(mutex) +#define sys_mutex_free(mutex) sys_sem_free(mutex) +#define sys_mutex_valid(mutex) sys_sem_valid(mutex) +#define sys_mutex_set_invalid(mutex) sys_sem_set_invalid(mutex) + +#else /* LWIP_COMPAT_MUTEX */ + +/** Create a new mutex + * @param mutex pointer to the mutex to create + * @return a new mutex */ +err_t sys_mutex_new(sys_mutex_t *mutex); +/** Lock a mutex + * @param mutex the mutex to lock */ +void sys_mutex_lock(sys_mutex_t *mutex); +/** Unlock a mutex + * @param mutex the mutex to unlock */ +void sys_mutex_unlock(sys_mutex_t *mutex); +/** Delete a semaphore + * @param mutex the mutex to delete */ +void sys_mutex_free(sys_mutex_t *mutex); +#ifndef sys_mutex_valid +/** Check if a mutex is valid/allocated: return 1 for valid, 0 for invalid */ +int sys_mutex_valid(sys_mutex_t *mutex); +#endif +#ifndef sys_mutex_set_invalid +/** Set a mutex invalid so that sys_mutex_valid returns 0 */ +void sys_mutex_set_invalid(sys_mutex_t *mutex); +#endif +#endif /* LWIP_COMPAT_MUTEX */ + +/* Semaphore functions: */ + +/** Create a new semaphore + * @param sem pointer to the semaphore to create + * @param count initial count of the semaphore + * @return ERR_OK if successful, another err_t otherwise */ +err_t sys_sem_new(sys_sem_t *sem, u8_t count); +/** Signals a semaphore + * @param sem the semaphore to signal */ +void sys_sem_signal(sys_sem_t *sem); +/** Wait for a semaphore for the specified timeout + * @param sem the semaphore to wait for + * @param timeout timeout in milliseconds to wait (0 = wait forever) + * @return time (in milliseconds) waited for the semaphore + * or SYS_ARCH_TIMEOUT on timeout */ +u32_t sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout); +/** Delete a semaphore + * @param sem semaphore to delete */ +void sys_sem_free(sys_sem_t *sem); +/** Wait for a semaphore - forever/no timeout */ +#define sys_sem_wait(sem) sys_arch_sem_wait(sem, 0) +#ifndef sys_sem_valid +/** Check if a sempahore is valid/allocated: return 1 for valid, 0 for invalid */ +int sys_sem_valid(sys_sem_t *sem); +#endif +#ifndef sys_sem_set_invalid +/** Set a semaphore invalid so that sys_sem_valid returns 0 */ +void sys_sem_set_invalid(sys_sem_t *sem); +#endif + +/* Time functions. */ +#ifndef sys_msleep +void sys_msleep(u32_t ms); /* only has a (close to) 1 jiffy resolution. */ +#endif + +/* Mailbox functions. */ + +/** Create a new mbox of specified size + * @param mbox pointer to the mbox to create + * @param size (miminum) number of messages in this mbox + * @return ERR_OK if successful, another err_t otherwise */ +err_t sys_mbox_new(sys_mbox_t *mbox, int size); +/** Post a message to an mbox - may not fail + * -> blocks if full, only used from tasks not from ISR + * @param mbox mbox to posts the message + * @param msg message to post (ATTENTION: can be NULL) */ +void sys_mbox_post(sys_mbox_t *mbox, void *msg); +/** Try to post a message to an mbox - may fail if full or ISR + * @param mbox mbox to posts the message + * @param msg message to post (ATTENTION: can be NULL) */ +err_t sys_mbox_trypost(sys_mbox_t *mbox, void *msg); +/** Wait for a new message to arrive in the mbox + * @param mbox mbox to get a message from + * @param msg pointer where the message is stored + * @param timeout maximum time (in milliseconds) to wait for a message + * @return time (in milliseconds) waited for a message, may be 0 if not waited + or SYS_ARCH_TIMEOUT on timeout + * The returned time has to be accurate to prevent timer jitter! */ +u32_t sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout); +/* Allow port to override with a macro, e.g. special timout for sys_arch_mbox_fetch() */ +#ifndef sys_arch_mbox_tryfetch +/** Wait for a new message to arrive in the mbox + * @param mbox mbox to get a message from + * @param msg pointer where the message is stored + * @param timeout maximum time (in milliseconds) to wait for a message + * @return 0 (milliseconds) if a message has been received + * or SYS_MBOX_EMPTY if the mailbox is empty */ +u32_t sys_arch_mbox_tryfetch(sys_mbox_t *mbox, void **msg); +#endif +/** For now, we map straight to sys_arch implementation. */ +#define sys_mbox_tryfetch(mbox, msg) sys_arch_mbox_tryfetch(mbox, msg) +/** Delete an mbox + * @param mbox mbox to delete */ +void sys_mbox_free(sys_mbox_t *mbox); +#define sys_mbox_fetch(mbox, msg) sys_arch_mbox_fetch(mbox, msg, 0) +#ifndef sys_mbox_valid +/** Check if an mbox is valid/allocated: return 1 for valid, 0 for invalid */ +int sys_mbox_valid(sys_mbox_t *mbox); +#endif +#ifndef sys_mbox_set_invalid +/** Set an mbox invalid so that sys_mbox_valid returns 0 */ +void sys_mbox_set_invalid(sys_mbox_t *mbox); +#endif + +/** The only thread function: + * Creates a new thread + * @param name human-readable name for the thread (used for debugging purposes) + * @param thread thread-function + * @param arg parameter passed to 'thread' + * @param stacksize stack size in bytes for the new thread (may be ignored by ports) + * @param prio priority of the new thread (may be ignored by ports) */ +sys_thread_t sys_thread_new(const char *name, lwip_thread_fn thread, void *arg, int stacksize, int prio); + +#endif /* NO_SYS */ + +/* sys_init() must be called before anthing else. */ +void sys_init(void); + +#ifndef sys_jiffies +/** Ticks/jiffies since power up. */ +u32_t sys_jiffies(void); +#endif + +/** Returns the current time in milliseconds, + * may be the same as sys_jiffies or at least based on it. */ +u32_t sys_now(void); + +/* Critical Region Protection */ +/* These functions must be implemented in the sys_arch.c file. + In some implementations they can provide a more light-weight protection + mechanism than using semaphores. Otherwise semaphores can be used for + implementation */ +#ifndef SYS_ARCH_PROTECT +/** SYS_LIGHTWEIGHT_PROT + * define SYS_LIGHTWEIGHT_PROT in lwipopts.h if you want inter-task protection + * for certain critical regions during buffer allocation, deallocation and memory + * allocation and deallocation. + */ +#if SYS_LIGHTWEIGHT_PROT + +/** SYS_ARCH_DECL_PROTECT + * declare a protection variable. This macro will default to defining a variable of + * type sys_prot_t. If a particular port needs a different implementation, then + * this macro may be defined in sys_arch.h. + */ +#define SYS_ARCH_DECL_PROTECT(lev) sys_prot_t lev +/** SYS_ARCH_PROTECT + * Perform a "fast" protect. This could be implemented by + * disabling interrupts for an embedded system or by using a semaphore or + * mutex. The implementation should allow calling SYS_ARCH_PROTECT when + * already protected. The old protection level is returned in the variable + * "lev". This macro will default to calling the sys_arch_protect() function + * which should be implemented in sys_arch.c. If a particular port needs a + * different implementation, then this macro may be defined in sys_arch.h + */ +#define SYS_ARCH_PROTECT(lev) lev = sys_arch_protect() +/** SYS_ARCH_UNPROTECT + * Perform a "fast" set of the protection level to "lev". This could be + * implemented by setting the interrupt level to "lev" within the MACRO or by + * using a semaphore or mutex. This macro will default to calling the + * sys_arch_unprotect() function which should be implemented in + * sys_arch.c. If a particular port needs a different implementation, then + * this macro may be defined in sys_arch.h + */ +#define SYS_ARCH_UNPROTECT(lev) sys_arch_unprotect(lev) +sys_prot_t sys_arch_protect(void); +void sys_arch_unprotect(sys_prot_t pval); + +#else + +#define SYS_ARCH_DECL_PROTECT(lev) +#define SYS_ARCH_PROTECT(lev) +#define SYS_ARCH_UNPROTECT(lev) + +#endif /* SYS_LIGHTWEIGHT_PROT */ + +#endif /* SYS_ARCH_PROTECT */ + +/* + * Macros to set/get and increase/decrease variables in a thread-safe way. + * Use these for accessing variable that are used from more than one thread. + */ + +#ifndef SYS_ARCH_INC +#define SYS_ARCH_INC(var, val) do { \ + SYS_ARCH_DECL_PROTECT(old_level); \ + SYS_ARCH_PROTECT(old_level); \ + var += val; \ + SYS_ARCH_UNPROTECT(old_level); \ + } while(0) +#endif /* SYS_ARCH_INC */ + +#ifndef SYS_ARCH_DEC +#define SYS_ARCH_DEC(var, val) do { \ + SYS_ARCH_DECL_PROTECT(old_level); \ + SYS_ARCH_PROTECT(old_level); \ + var -= val; \ + SYS_ARCH_UNPROTECT(old_level); \ + } while(0) +#endif /* SYS_ARCH_DEC */ + +#ifndef SYS_ARCH_GET +#define SYS_ARCH_GET(var, ret) do { \ + SYS_ARCH_DECL_PROTECT(old_level); \ + SYS_ARCH_PROTECT(old_level); \ + ret = var; \ + SYS_ARCH_UNPROTECT(old_level); \ + } while(0) +#endif /* SYS_ARCH_GET */ + +#ifndef SYS_ARCH_SET +#define SYS_ARCH_SET(var, val) do { \ + SYS_ARCH_DECL_PROTECT(old_level); \ + SYS_ARCH_PROTECT(old_level); \ + var = val; \ + SYS_ARCH_UNPROTECT(old_level); \ + } while(0) +#endif /* SYS_ARCH_SET */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __LWIP_SYS_H__ */ diff --git a/src/lwip-1.4.1/src/include/lwip/tcp.h b/src/lwip-1.4.1/src/include/lwip/tcp.h new file mode 100644 index 0000000..c6e61ad --- /dev/null +++ b/src/lwip-1.4.1/src/include/lwip/tcp.h @@ -0,0 +1,379 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __LWIP_TCP_H__ +#define __LWIP_TCP_H__ + +#include "lwip/opt.h" + +#if LWIP_TCP /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/mem.h" +#include "lwip/pbuf.h" +#include "lwip/ip.h" +#include "lwip/icmp.h" +#include "lwip/err.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct tcp_pcb; + +/** Function prototype for tcp accept callback functions. Called when a new + * connection can be accepted on a listening pcb. + * + * @param arg Additional argument to pass to the callback function (@see tcp_arg()) + * @param newpcb The new connection pcb + * @param err An error code if there has been an error accepting. + * Only return ERR_ABRT if you have called tcp_abort from within the + * callback function! + */ +typedef err_t (*tcp_accept_fn)(void *arg, struct tcp_pcb *newpcb, err_t err); + +/** Function prototype for tcp receive callback functions. Called when data has + * been received. + * + * @param arg Additional argument to pass to the callback function (@see tcp_arg()) + * @param tpcb The connection pcb which received data + * @param p The received data (or NULL when the connection has been closed!) + * @param err An error code if there has been an error receiving + * Only return ERR_ABRT if you have called tcp_abort from within the + * callback function! + */ +typedef err_t (*tcp_recv_fn)(void *arg, struct tcp_pcb *tpcb, + struct pbuf *p, err_t err); + +/** Function prototype for tcp sent callback functions. Called when sent data has + * been acknowledged by the remote side. Use it to free corresponding resources. + * This also means that the pcb has now space available to send new data. + * + * @param arg Additional argument to pass to the callback function (@see tcp_arg()) + * @param tpcb The connection pcb for which data has been acknowledged + * @param len The amount of bytes acknowledged + * @return ERR_OK: try to send some data by calling tcp_output + * Only return ERR_ABRT if you have called tcp_abort from within the + * callback function! + */ +typedef err_t (*tcp_sent_fn)(void *arg, struct tcp_pcb *tpcb, + u16_t len); + +/** Function prototype for tcp poll callback functions. Called periodically as + * specified by @see tcp_poll. + * + * @param arg Additional argument to pass to the callback function (@see tcp_arg()) + * @param tpcb tcp pcb + * @return ERR_OK: try to send some data by calling tcp_output + * Only return ERR_ABRT if you have called tcp_abort from within the + * callback function! + */ +typedef err_t (*tcp_poll_fn)(void *arg, struct tcp_pcb *tpcb); + +/** Function prototype for tcp error callback functions. Called when the pcb + * receives a RST or is unexpectedly closed for any other reason. + * + * @note The corresponding pcb is already freed when this callback is called! + * + * @param arg Additional argument to pass to the callback function (@see tcp_arg()) + * @param err Error code to indicate why the pcb has been closed + * ERR_ABRT: aborted through tcp_abort or by a TCP timer + * ERR_RST: the connection was reset by the remote host + */ +typedef void (*tcp_err_fn)(void *arg, err_t err); + +/** Function prototype for tcp connected callback functions. Called when a pcb + * is connected to the remote side after initiating a connection attempt by + * calling tcp_connect(). + * + * @param arg Additional argument to pass to the callback function (@see tcp_arg()) + * @param tpcb The connection pcb which is connected + * @param err An unused error code, always ERR_OK currently ;-) TODO! + * Only return ERR_ABRT if you have called tcp_abort from within the + * callback function! + * + * @note When a connection attempt fails, the error callback is currently called! + */ +typedef err_t (*tcp_connected_fn)(void *arg, struct tcp_pcb *tpcb, err_t err); + +enum tcp_state { + CLOSED = 0, + LISTEN = 1, + SYN_SENT = 2, + SYN_RCVD = 3, + ESTABLISHED = 4, + FIN_WAIT_1 = 5, + FIN_WAIT_2 = 6, + CLOSE_WAIT = 7, + CLOSING = 8, + LAST_ACK = 9, + TIME_WAIT = 10 +}; + +#if LWIP_CALLBACK_API + /* Function to call when a listener has been connected. + * @param arg user-supplied argument (tcp_pcb.callback_arg) + * @param pcb a new tcp_pcb that now is connected + * @param err an error argument (TODO: that is current always ERR_OK?) + * @return ERR_OK: accept the new connection, + * any other err_t abortsthe new connection + */ +#define DEF_ACCEPT_CALLBACK tcp_accept_fn accept; +#else /* LWIP_CALLBACK_API */ +#define DEF_ACCEPT_CALLBACK +#endif /* LWIP_CALLBACK_API */ + +/** + * members common to struct tcp_pcb and struct tcp_listen_pcb + */ +#define TCP_PCB_COMMON(type) \ + type *next; /* for the linked list */ \ + void *callback_arg; \ + /* the accept callback for listen- and normal pcbs, if LWIP_CALLBACK_API */ \ + DEF_ACCEPT_CALLBACK \ + enum tcp_state state; /* TCP state */ \ + u8_t prio; \ + /* ports are in host byte order */ \ + u16_t local_port + + +/* the TCP protocol control block */ +struct tcp_pcb { +/** common PCB members */ + IP_PCB; +/** protocol specific PCB members */ + TCP_PCB_COMMON(struct tcp_pcb); + + /* ports are in host byte order */ + u16_t remote_port; + + u8_t flags; +#define TF_ACK_DELAY ((u8_t)0x01U) /* Delayed ACK. */ +#define TF_ACK_NOW ((u8_t)0x02U) /* Immediate ACK. */ +#define TF_INFR ((u8_t)0x04U) /* In fast recovery. */ +#define TF_TIMESTAMP ((u8_t)0x08U) /* Timestamp option enabled */ +#define TF_RXCLOSED ((u8_t)0x10U) /* rx closed by tcp_shutdown */ +#define TF_FIN ((u8_t)0x20U) /* Connection was closed locally (FIN segment enqueued). */ +#define TF_NODELAY ((u8_t)0x40U) /* Disable Nagle algorithm */ +#define TF_NAGLEMEMERR ((u8_t)0x80U) /* nagle enabled, memerr, try to output to prevent delayed ACK to happen */ + + /* the rest of the fields are in host byte order + as we have to do some math with them */ + + /* Timers */ + u8_t polltmr, pollinterval; + u8_t last_timer; + u32_t tmr; + + /* receiver variables */ + u32_t rcv_nxt; /* next seqno expected */ + u16_t rcv_wnd; /* receiver window available */ + u16_t rcv_ann_wnd; /* receiver window to announce */ + u32_t rcv_ann_right_edge; /* announced right edge of window */ + + /* Retransmission timer. */ + s16_t rtime; + + u16_t mss; /* maximum segment size */ + + /* RTT (round trip time) estimation variables */ + u32_t rttest; /* RTT estimate in 500ms ticks */ + u32_t rtseq; /* sequence number being timed */ + s16_t sa, sv; /* @todo document this */ + + s16_t rto; /* retransmission time-out */ + u8_t nrtx; /* number of retransmissions */ + + /* fast retransmit/recovery */ + u8_t dupacks; + u32_t lastack; /* Highest acknowledged seqno. */ + + /* congestion avoidance/control variables */ + u16_t cwnd; + u16_t ssthresh; + + /* sender variables */ + u32_t snd_nxt; /* next new seqno to be sent */ + u32_t snd_wl1, snd_wl2; /* Sequence and acknowledgement numbers of last + window update. */ + u32_t snd_lbb; /* Sequence number of next byte to be buffered. */ + u16_t snd_wnd; /* sender window */ + u16_t snd_wnd_max; /* the maximum sender window announced by the remote host */ + + u16_t acked; + + u16_t snd_buf; /* Available buffer space for sending (in bytes). */ +#define TCP_SNDQUEUELEN_OVERFLOW (0xffffU-3) + u16_t snd_queuelen; /* Available buffer space for sending (in tcp_segs). */ + +#if TCP_OVERSIZE + /* Extra bytes available at the end of the last pbuf in unsent. */ + u16_t unsent_oversize; +#endif /* TCP_OVERSIZE */ + + /* These are ordered by sequence number: */ + struct tcp_seg *unsent; /* Unsent (queued) segments. */ + struct tcp_seg *unacked; /* Sent but unacknowledged segments. */ +#if TCP_QUEUE_OOSEQ + struct tcp_seg *ooseq; /* Received out of sequence segments. */ +#endif /* TCP_QUEUE_OOSEQ */ + + struct pbuf *refused_data; /* Data previously received but not yet taken by upper layer */ + +#if LWIP_CALLBACK_API + /* Function to be called when more send buffer space is available. */ + tcp_sent_fn sent; + /* Function to be called when (in-sequence) data has arrived. */ + tcp_recv_fn recv; + /* Function to be called when a connection has been set up. */ + tcp_connected_fn connected; + /* Function which is called periodically. */ + tcp_poll_fn poll; + /* Function to be called whenever a fatal error occurs. */ + tcp_err_fn errf; +#endif /* LWIP_CALLBACK_API */ + +#if LWIP_TCP_TIMESTAMPS + u32_t ts_lastacksent; + u32_t ts_recent; +#endif /* LWIP_TCP_TIMESTAMPS */ + + /* idle time before KEEPALIVE is sent */ + u32_t keep_idle; +#if LWIP_TCP_KEEPALIVE + u32_t keep_intvl; + u32_t keep_cnt; +#endif /* LWIP_TCP_KEEPALIVE */ + + /* Persist timer counter */ + u8_t persist_cnt; + /* Persist timer back-off */ + u8_t persist_backoff; + + /* KEEPALIVE counter */ + u8_t keep_cnt_sent; +}; + +struct tcp_pcb_listen { +/* Common members of all PCB types */ + IP_PCB; +/* Protocol specific PCB members */ + TCP_PCB_COMMON(struct tcp_pcb_listen); + +#if TCP_LISTEN_BACKLOG + u8_t backlog; + u8_t accepts_pending; +#endif /* TCP_LISTEN_BACKLOG */ +}; + +#if LWIP_EVENT_API + +enum lwip_event { + LWIP_EVENT_ACCEPT, + LWIP_EVENT_SENT, + LWIP_EVENT_RECV, + LWIP_EVENT_CONNECTED, + LWIP_EVENT_POLL, + LWIP_EVENT_ERR +}; + +err_t lwip_tcp_event(void *arg, struct tcp_pcb *pcb, + enum lwip_event, + struct pbuf *p, + u16_t size, + err_t err); + +#endif /* LWIP_EVENT_API */ + +/* Application program's interface: */ +struct tcp_pcb * tcp_new (void); + +void tcp_arg (struct tcp_pcb *pcb, void *arg); +void tcp_accept (struct tcp_pcb *pcb, tcp_accept_fn accept); +void tcp_recv (struct tcp_pcb *pcb, tcp_recv_fn recv); +void tcp_sent (struct tcp_pcb *pcb, tcp_sent_fn sent); +void tcp_poll (struct tcp_pcb *pcb, tcp_poll_fn poll, u8_t interval); +void tcp_err (struct tcp_pcb *pcb, tcp_err_fn err); + +#define tcp_mss(pcb) (((pcb)->flags & TF_TIMESTAMP) ? ((pcb)->mss - 12) : (pcb)->mss) +#define tcp_sndbuf(pcb) ((pcb)->snd_buf) +#define tcp_sndqueuelen(pcb) ((pcb)->snd_queuelen) +#define tcp_nagle_disable(pcb) ((pcb)->flags |= TF_NODELAY) +#define tcp_nagle_enable(pcb) ((pcb)->flags &= ~TF_NODELAY) +#define tcp_nagle_disabled(pcb) (((pcb)->flags & TF_NODELAY) != 0) + +#if TCP_LISTEN_BACKLOG +#define tcp_accepted(pcb) do { \ + LWIP_ASSERT("pcb->state == LISTEN (called for wrong pcb?)", pcb->state == LISTEN); \ + (((struct tcp_pcb_listen *)(pcb))->accepts_pending--); } while(0) +#else /* TCP_LISTEN_BACKLOG */ +#define tcp_accepted(pcb) LWIP_ASSERT("pcb->state == LISTEN (called for wrong pcb?)", \ + (pcb)->state == LISTEN) +#endif /* TCP_LISTEN_BACKLOG */ + +void tcp_recved (struct tcp_pcb *pcb, u16_t len); +err_t tcp_bind (struct tcp_pcb *pcb, ip_addr_t *ipaddr, + u16_t port); +err_t tcp_connect (struct tcp_pcb *pcb, ip_addr_t *ipaddr, + u16_t port, tcp_connected_fn connected); + +struct tcp_pcb * tcp_listen_with_backlog(struct tcp_pcb *pcb, u8_t backlog); +#define tcp_listen(pcb) tcp_listen_with_backlog(pcb, TCP_DEFAULT_LISTEN_BACKLOG) + +void tcp_abort (struct tcp_pcb *pcb); +err_t tcp_close (struct tcp_pcb *pcb); +err_t tcp_shutdown(struct tcp_pcb *pcb, int shut_rx, int shut_tx); + +/* Flags for "apiflags" parameter in tcp_write */ +#define TCP_WRITE_FLAG_COPY 0x01 +#define TCP_WRITE_FLAG_MORE 0x02 + +err_t tcp_write (struct tcp_pcb *pcb, const void *dataptr, u16_t len, + u8_t apiflags); + +void tcp_setprio (struct tcp_pcb *pcb, u8_t prio); + +#define TCP_PRIO_MIN 1 +#define TCP_PRIO_NORMAL 64 +#define TCP_PRIO_MAX 127 + +err_t tcp_output (struct tcp_pcb *pcb); + + +const char* tcp_debug_state_str(enum tcp_state s); + + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_TCP */ + +#endif /* __LWIP_TCP_H__ */ diff --git a/src/lwip-1.4.1/src/include/lwip/tcp_impl.h b/src/lwip-1.4.1/src/include/lwip/tcp_impl.h new file mode 100644 index 0000000..173de44 --- /dev/null +++ b/src/lwip-1.4.1/src/include/lwip/tcp_impl.h @@ -0,0 +1,486 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __LWIP_TCP_IMPL_H__ +#define __LWIP_TCP_IMPL_H__ + +#include "lwip/opt.h" + +#if LWIP_TCP /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/tcp.h" +#include "lwip/mem.h" +#include "lwip/pbuf.h" +#include "lwip/ip.h" +#include "lwip/icmp.h" +#include "lwip/err.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Functions for interfacing with TCP: */ + +/* Lower layer interface to TCP: */ +void tcp_init (void); /* Initialize this module. */ +void tcp_tmr (void); /* Must be called every + TCP_TMR_INTERVAL + ms. (Typically 250 ms). */ +/* It is also possible to call these two functions at the right + intervals (instead of calling tcp_tmr()). */ +void tcp_slowtmr (void); +void tcp_fasttmr (void); + + +/* Only used by IP to pass a TCP segment to TCP: */ +void tcp_input (struct pbuf *p, struct netif *inp); +/* Used within the TCP code only: */ +struct tcp_pcb * tcp_alloc (u8_t prio); +void tcp_abandon (struct tcp_pcb *pcb, int reset); +err_t tcp_send_empty_ack(struct tcp_pcb *pcb); +void tcp_rexmit (struct tcp_pcb *pcb); +void tcp_rexmit_rto (struct tcp_pcb *pcb); +void tcp_rexmit_fast (struct tcp_pcb *pcb); +u32_t tcp_update_rcv_ann_wnd(struct tcp_pcb *pcb); +err_t tcp_process_refused_data(struct tcp_pcb *pcb); + +/** + * This is the Nagle algorithm: try to combine user data to send as few TCP + * segments as possible. Only send if + * - no previously transmitted data on the connection remains unacknowledged or + * - the TF_NODELAY flag is set (nagle algorithm turned off for this pcb) or + * - the only unsent segment is at least pcb->mss bytes long (or there is more + * than one unsent segment - with lwIP, this can happen although unsent->len < mss) + * - or if we are in fast-retransmit (TF_INFR) + */ +#define tcp_do_output_nagle(tpcb) ((((tpcb)->unacked == NULL) || \ + ((tpcb)->flags & (TF_NODELAY | TF_INFR)) || \ + (((tpcb)->unsent != NULL) && (((tpcb)->unsent->next != NULL) || \ + ((tpcb)->unsent->len >= (tpcb)->mss))) || \ + ((tcp_sndbuf(tpcb) == 0) || (tcp_sndqueuelen(tpcb) >= TCP_SND_QUEUELEN)) \ + ) ? 1 : 0) +#define tcp_output_nagle(tpcb) (tcp_do_output_nagle(tpcb) ? tcp_output(tpcb) : ERR_OK) + + +#define TCP_SEQ_LT(a,b) ((s32_t)((u32_t)(a) - (u32_t)(b)) < 0) +#define TCP_SEQ_LEQ(a,b) ((s32_t)((u32_t)(a) - (u32_t)(b)) <= 0) +#define TCP_SEQ_GT(a,b) ((s32_t)((u32_t)(a) - (u32_t)(b)) > 0) +#define TCP_SEQ_GEQ(a,b) ((s32_t)((u32_t)(a) - (u32_t)(b)) >= 0) +/* is b<=a<=c? */ +#if 0 /* see bug #10548 */ +#define TCP_SEQ_BETWEEN(a,b,c) ((c)-(b) >= (a)-(b)) +#endif +#define TCP_SEQ_BETWEEN(a,b,c) (TCP_SEQ_GEQ(a,b) && TCP_SEQ_LEQ(a,c)) +#define TCP_FIN 0x01U +#define TCP_SYN 0x02U +#define TCP_RST 0x04U +#define TCP_PSH 0x08U +#define TCP_ACK 0x10U +#define TCP_URG 0x20U +#define TCP_ECE 0x40U +#define TCP_CWR 0x80U + +#define TCP_FLAGS 0x3fU + +/* Length of the TCP header, excluding options. */ +#define TCP_HLEN 20 + +#ifndef TCP_TMR_INTERVAL +#define TCP_TMR_INTERVAL 250 /* The TCP timer interval in milliseconds. */ +#endif /* TCP_TMR_INTERVAL */ + +#ifndef TCP_FAST_INTERVAL +#define TCP_FAST_INTERVAL TCP_TMR_INTERVAL /* the fine grained timeout in milliseconds */ +#endif /* TCP_FAST_INTERVAL */ + +#ifndef TCP_SLOW_INTERVAL +#define TCP_SLOW_INTERVAL (2*TCP_TMR_INTERVAL) /* the coarse grained timeout in milliseconds */ +#endif /* TCP_SLOW_INTERVAL */ + +#define TCP_FIN_WAIT_TIMEOUT 20000 /* milliseconds */ +#define TCP_SYN_RCVD_TIMEOUT 20000 /* milliseconds */ + +#define TCP_OOSEQ_TIMEOUT 6U /* x RTO */ + +#ifndef TCP_MSL +#define TCP_MSL 60000UL /* The maximum segment lifetime in milliseconds */ +#endif + +/* Keepalive values, compliant with RFC 1122. Don't change this unless you know what you're doing */ +#ifndef TCP_KEEPIDLE_DEFAULT +#define TCP_KEEPIDLE_DEFAULT 7200000UL /* Default KEEPALIVE timer in milliseconds */ +#endif + +#ifndef TCP_KEEPINTVL_DEFAULT +#define TCP_KEEPINTVL_DEFAULT 75000UL /* Default Time between KEEPALIVE probes in milliseconds */ +#endif + +#ifndef TCP_KEEPCNT_DEFAULT +#define TCP_KEEPCNT_DEFAULT 9U /* Default Counter for KEEPALIVE probes */ +#endif + +#define TCP_MAXIDLE TCP_KEEPCNT_DEFAULT * TCP_KEEPINTVL_DEFAULT /* Maximum KEEPALIVE probe time */ + +/* Fields are (of course) in network byte order. + * Some fields are converted to host byte order in tcp_input(). + */ +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct tcp_hdr { + PACK_STRUCT_FIELD(u16_t src); + PACK_STRUCT_FIELD(u16_t dest); + PACK_STRUCT_FIELD(u32_t seqno); + PACK_STRUCT_FIELD(u32_t ackno); + PACK_STRUCT_FIELD(u16_t _hdrlen_rsvd_flags); + PACK_STRUCT_FIELD(u16_t wnd); + PACK_STRUCT_FIELD(u16_t chksum); + PACK_STRUCT_FIELD(u16_t urgp); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +#define TCPH_HDRLEN(phdr) (ntohs((phdr)->_hdrlen_rsvd_flags) >> 12) +#define TCPH_FLAGS(phdr) (ntohs((phdr)->_hdrlen_rsvd_flags) & TCP_FLAGS) + +#define TCPH_HDRLEN_SET(phdr, len) (phdr)->_hdrlen_rsvd_flags = htons(((len) << 12) | TCPH_FLAGS(phdr)) +#define TCPH_FLAGS_SET(phdr, flags) (phdr)->_hdrlen_rsvd_flags = (((phdr)->_hdrlen_rsvd_flags & PP_HTONS((u16_t)(~(u16_t)(TCP_FLAGS)))) | htons(flags)) +#define TCPH_HDRLEN_FLAGS_SET(phdr, len, flags) (phdr)->_hdrlen_rsvd_flags = htons(((len) << 12) | (flags)) + +#define TCPH_SET_FLAG(phdr, flags ) (phdr)->_hdrlen_rsvd_flags = ((phdr)->_hdrlen_rsvd_flags | htons(flags)) +#define TCPH_UNSET_FLAG(phdr, flags) (phdr)->_hdrlen_rsvd_flags = htons(ntohs((phdr)->_hdrlen_rsvd_flags) | (TCPH_FLAGS(phdr) & ~(flags)) ) + +#define TCP_TCPLEN(seg) ((seg)->len + ((TCPH_FLAGS((seg)->tcphdr) & (TCP_FIN | TCP_SYN)) != 0)) + +/** Flags used on input processing, not on pcb->flags +*/ +#define TF_RESET (u8_t)0x08U /* Connection was reset. */ +#define TF_CLOSED (u8_t)0x10U /* Connection was sucessfully closed. */ +#define TF_GOT_FIN (u8_t)0x20U /* Connection was closed by the remote end. */ + + +#if LWIP_EVENT_API + +#define TCP_EVENT_ACCEPT(pcb,err,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\ + LWIP_EVENT_ACCEPT, NULL, 0, err) +#define TCP_EVENT_SENT(pcb,space,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\ + LWIP_EVENT_SENT, NULL, space, ERR_OK) +#define TCP_EVENT_RECV(pcb,p,err,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\ + LWIP_EVENT_RECV, (p), 0, (err)) +#define TCP_EVENT_CLOSED(pcb,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\ + LWIP_EVENT_RECV, NULL, 0, ERR_OK) +#define TCP_EVENT_CONNECTED(pcb,err,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\ + LWIP_EVENT_CONNECTED, NULL, 0, (err)) +#define TCP_EVENT_POLL(pcb,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\ + LWIP_EVENT_POLL, NULL, 0, ERR_OK) +#define TCP_EVENT_ERR(errf,arg,err) lwip_tcp_event((arg), NULL, \ + LWIP_EVENT_ERR, NULL, 0, (err)) + +#else /* LWIP_EVENT_API */ + +#define TCP_EVENT_ACCEPT(pcb,err,ret) \ + do { \ + if((pcb)->accept != NULL) \ + (ret) = (pcb)->accept((pcb)->callback_arg,(pcb),(err)); \ + else (ret) = ERR_ARG; \ + } while (0) + +#define TCP_EVENT_SENT(pcb,space,ret) \ + do { \ + if((pcb)->sent != NULL) \ + (ret) = (pcb)->sent((pcb)->callback_arg,(pcb),(space)); \ + else (ret) = ERR_OK; \ + } while (0) + +#define TCP_EVENT_RECV(pcb,p,err,ret) \ + do { \ + if((pcb)->recv != NULL) { \ + (ret) = (pcb)->recv((pcb)->callback_arg,(pcb),(p),(err));\ + } else { \ + (ret) = tcp_recv_null(NULL, (pcb), (p), (err)); \ + } \ + } while (0) + +#define TCP_EVENT_CLOSED(pcb,ret) \ + do { \ + if(((pcb)->recv != NULL)) { \ + (ret) = (pcb)->recv((pcb)->callback_arg,(pcb),NULL,ERR_OK);\ + } else { \ + (ret) = ERR_OK; \ + } \ + } while (0) + +#define TCP_EVENT_CONNECTED(pcb,err,ret) \ + do { \ + if((pcb)->connected != NULL) \ + (ret) = (pcb)->connected((pcb)->callback_arg,(pcb),(err)); \ + else (ret) = ERR_OK; \ + } while (0) + +#define TCP_EVENT_POLL(pcb,ret) \ + do { \ + if((pcb)->poll != NULL) \ + (ret) = (pcb)->poll((pcb)->callback_arg,(pcb)); \ + else (ret) = ERR_OK; \ + } while (0) + +#define TCP_EVENT_ERR(errf,arg,err) \ + do { \ + if((errf) != NULL) \ + (errf)((arg),(err)); \ + } while (0) + +#endif /* LWIP_EVENT_API */ + +/** Enabled extra-check for TCP_OVERSIZE if LWIP_DEBUG is enabled */ +#if TCP_OVERSIZE && defined(LWIP_DEBUG) +#define TCP_OVERSIZE_DBGCHECK 1 +#else +#define TCP_OVERSIZE_DBGCHECK 0 +#endif + +/** Don't generate checksum on copy if CHECKSUM_GEN_TCP is disabled */ +#define TCP_CHECKSUM_ON_COPY (LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_TCP) + +/* This structure represents a TCP segment on the unsent, unacked and ooseq queues */ +struct tcp_seg { + struct tcp_seg *next; /* used when putting segements on a queue */ + struct pbuf *p; /* buffer containing data + TCP header */ + u16_t len; /* the TCP length of this segment */ +#if TCP_OVERSIZE_DBGCHECK + u16_t oversize_left; /* Extra bytes available at the end of the last + pbuf in unsent (used for asserting vs. + tcp_pcb.unsent_oversized only) */ +#endif /* TCP_OVERSIZE_DBGCHECK */ +#if TCP_CHECKSUM_ON_COPY + u16_t chksum; + u8_t chksum_swapped; +#endif /* TCP_CHECKSUM_ON_COPY */ + u8_t flags; +#define TF_SEG_OPTS_MSS (u8_t)0x01U /* Include MSS option. */ +#define TF_SEG_OPTS_TS (u8_t)0x02U /* Include timestamp option. */ +#define TF_SEG_DATA_CHECKSUMMED (u8_t)0x04U /* ALL data (not the header) is + checksummed into 'chksum' */ + struct tcp_hdr *tcphdr; /* the TCP header */ +}; + +#define LWIP_TCP_OPT_LENGTH(flags) \ + (flags & TF_SEG_OPTS_MSS ? 4 : 0) + \ + (flags & TF_SEG_OPTS_TS ? 12 : 0) + +/** This returns a TCP header option for MSS in an u32_t */ +#define TCP_BUILD_MSS_OPTION(mss) htonl(0x02040000 | ((mss) & 0xFFFF)) + +/* Global variables: */ +extern struct tcp_pcb *tcp_input_pcb; +extern u32_t tcp_ticks; +extern u8_t tcp_active_pcbs_changed; + +/* The TCP PCB lists. */ +union tcp_listen_pcbs_t { /* List of all TCP PCBs in LISTEN state. */ + struct tcp_pcb_listen *listen_pcbs; + struct tcp_pcb *pcbs; +}; +extern struct tcp_pcb *tcp_bound_pcbs; +extern union tcp_listen_pcbs_t tcp_listen_pcbs; +extern struct tcp_pcb *tcp_active_pcbs; /* List of all TCP PCBs that are in a + state in which they accept or send + data. */ +extern struct tcp_pcb *tcp_tw_pcbs; /* List of all TCP PCBs in TIME-WAIT. */ + +extern struct tcp_pcb *tcp_tmp_pcb; /* Only used for temporary storage. */ + +/* Axioms about the above lists: + 1) Every TCP PCB that is not CLOSED is in one of the lists. + 2) A PCB is only in one of the lists. + 3) All PCBs in the tcp_listen_pcbs list is in LISTEN state. + 4) All PCBs in the tcp_tw_pcbs list is in TIME-WAIT state. +*/ +/* Define two macros, TCP_REG and TCP_RMV that registers a TCP PCB + with a PCB list or removes a PCB from a list, respectively. */ +#ifndef TCP_DEBUG_PCB_LISTS +#define TCP_DEBUG_PCB_LISTS 0 +#endif +#if TCP_DEBUG_PCB_LISTS +#define TCP_REG(pcbs, npcb) do {\ + LWIP_DEBUGF(TCP_DEBUG, ("TCP_REG %p local port %d\n", (npcb), (npcb)->local_port)); \ + for(tcp_tmp_pcb = *(pcbs); \ + tcp_tmp_pcb != NULL; \ + tcp_tmp_pcb = tcp_tmp_pcb->next) { \ + LWIP_ASSERT("TCP_REG: already registered\n", tcp_tmp_pcb != (npcb)); \ + } \ + LWIP_ASSERT("TCP_REG: pcb->state != CLOSED", ((pcbs) == &tcp_bound_pcbs) || ((npcb)->state != CLOSED)); \ + (npcb)->next = *(pcbs); \ + LWIP_ASSERT("TCP_REG: npcb->next != npcb", (npcb)->next != (npcb)); \ + *(pcbs) = (npcb); \ + LWIP_ASSERT("TCP_RMV: tcp_pcbs sane", tcp_pcbs_sane()); \ + tcp_timer_needed(); \ + } while(0) +#define TCP_RMV(pcbs, npcb) do { \ + LWIP_ASSERT("TCP_RMV: pcbs != NULL", *(pcbs) != NULL); \ + LWIP_DEBUGF(TCP_DEBUG, ("TCP_RMV: removing %p from %p\n", (npcb), *(pcbs))); \ + if(*(pcbs) == (npcb)) { \ + *(pcbs) = (*pcbs)->next; \ + } else for(tcp_tmp_pcb = *(pcbs); tcp_tmp_pcb != NULL; tcp_tmp_pcb = tcp_tmp_pcb->next) { \ + if(tcp_tmp_pcb->next == (npcb)) { \ + tcp_tmp_pcb->next = (npcb)->next; \ + break; \ + } \ + } \ + (npcb)->next = NULL; \ + LWIP_ASSERT("TCP_RMV: tcp_pcbs sane", tcp_pcbs_sane()); \ + LWIP_DEBUGF(TCP_DEBUG, ("TCP_RMV: removed %p from %p\n", (npcb), *(pcbs))); \ + } while(0) + +#else /* LWIP_DEBUG */ + +#define TCP_REG(pcbs, npcb) \ + do { \ + (npcb)->next = *pcbs; \ + *(pcbs) = (npcb); \ + tcp_timer_needed(); \ + } while (0) + +#define TCP_RMV(pcbs, npcb) \ + do { \ + if(*(pcbs) == (npcb)) { \ + (*(pcbs)) = (*pcbs)->next; \ + } \ + else { \ + for(tcp_tmp_pcb = *pcbs; \ + tcp_tmp_pcb != NULL; \ + tcp_tmp_pcb = tcp_tmp_pcb->next) { \ + if(tcp_tmp_pcb->next == (npcb)) { \ + tcp_tmp_pcb->next = (npcb)->next; \ + break; \ + } \ + } \ + } \ + (npcb)->next = NULL; \ + } while(0) + +#endif /* LWIP_DEBUG */ + +#define TCP_REG_ACTIVE(npcb) \ + do { \ + TCP_REG(&tcp_active_pcbs, npcb); \ + tcp_active_pcbs_changed = 1; \ + } while (0) + +#define TCP_RMV_ACTIVE(npcb) \ + do { \ + TCP_RMV(&tcp_active_pcbs, npcb); \ + tcp_active_pcbs_changed = 1; \ + } while (0) + +#define TCP_PCB_REMOVE_ACTIVE(pcb) \ + do { \ + tcp_pcb_remove(&tcp_active_pcbs, pcb); \ + tcp_active_pcbs_changed = 1; \ + } while (0) + + +/* Internal functions: */ +struct tcp_pcb *tcp_pcb_copy(struct tcp_pcb *pcb); +void tcp_pcb_purge(struct tcp_pcb *pcb); +void tcp_pcb_remove(struct tcp_pcb **pcblist, struct tcp_pcb *pcb); + +void tcp_segs_free(struct tcp_seg *seg); +void tcp_seg_free(struct tcp_seg *seg); +struct tcp_seg *tcp_seg_copy(struct tcp_seg *seg); + +#define tcp_ack(pcb) \ + do { \ + if((pcb)->flags & TF_ACK_DELAY) { \ + (pcb)->flags &= ~TF_ACK_DELAY; \ + (pcb)->flags |= TF_ACK_NOW; \ + } \ + else { \ + (pcb)->flags |= TF_ACK_DELAY; \ + } \ + } while (0) + +#define tcp_ack_now(pcb) \ + do { \ + (pcb)->flags |= TF_ACK_NOW; \ + } while (0) + +err_t tcp_send_fin(struct tcp_pcb *pcb); +err_t tcp_enqueue_flags(struct tcp_pcb *pcb, u8_t flags); + +void tcp_rexmit_seg(struct tcp_pcb *pcb, struct tcp_seg *seg); + +void tcp_rst(u32_t seqno, u32_t ackno, + ip_addr_t *local_ip, ip_addr_t *remote_ip, + u16_t local_port, u16_t remote_port); + +u32_t tcp_next_iss(void); + +void tcp_keepalive(struct tcp_pcb *pcb); +void tcp_zero_window_probe(struct tcp_pcb *pcb); + +#if TCP_CALCULATE_EFF_SEND_MSS +u16_t tcp_eff_send_mss(u16_t sendmss, ip_addr_t *addr); +#endif /* TCP_CALCULATE_EFF_SEND_MSS */ + +#if LWIP_CALLBACK_API +err_t tcp_recv_null(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err); +#endif /* LWIP_CALLBACK_API */ + +#if TCP_DEBUG || TCP_INPUT_DEBUG || TCP_OUTPUT_DEBUG +void tcp_debug_print(struct tcp_hdr *tcphdr); +void tcp_debug_print_flags(u8_t flags); +void tcp_debug_print_state(enum tcp_state s); +void tcp_debug_print_pcbs(void); +s16_t tcp_pcbs_sane(void); +#else +# define tcp_debug_print(tcphdr) +# define tcp_debug_print_flags(flags) +# define tcp_debug_print_state(s) +# define tcp_debug_print_pcbs() +# define tcp_pcbs_sane() 1 +#endif /* TCP_DEBUG */ + +/** External function (implemented in timers.c), called when TCP detects + * that a timer is needed (i.e. active- or time-wait-pcb found). */ +void tcp_timer_needed(void); + + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_TCP */ + +#endif /* __LWIP_TCP_H__ */ diff --git a/src/lwip-1.4.1/src/include/lwip/tcpip.h b/src/lwip-1.4.1/src/include/lwip/tcpip.h new file mode 100644 index 0000000..637476e --- /dev/null +++ b/src/lwip-1.4.1/src/include/lwip/tcpip.h @@ -0,0 +1,167 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __LWIP_TCPIP_H__ +#define __LWIP_TCPIP_H__ + +#include "lwip/opt.h" + +#if !NO_SYS /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/api_msg.h" +#include "lwip/netifapi.h" +#include "lwip/pbuf.h" +#include "lwip/api.h" +#include "lwip/sys.h" +#include "lwip/timers.h" +#include "lwip/netif.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** Define this to something that triggers a watchdog. This is called from + * tcpip_thread after processing a message. */ +#ifndef LWIP_TCPIP_THREAD_ALIVE +#define LWIP_TCPIP_THREAD_ALIVE() +#endif + +#if LWIP_TCPIP_CORE_LOCKING +/** The global semaphore to lock the stack. */ +extern sys_mutex_t lock_tcpip_core; +#define LOCK_TCPIP_CORE() sys_mutex_lock(&lock_tcpip_core) +#define UNLOCK_TCPIP_CORE() sys_mutex_unlock(&lock_tcpip_core) +#define TCPIP_APIMSG(m) tcpip_apimsg_lock(m) +#define TCPIP_APIMSG_ACK(m) +#define TCPIP_NETIFAPI(m) tcpip_netifapi_lock(m) +#define TCPIP_NETIFAPI_ACK(m) +#else /* LWIP_TCPIP_CORE_LOCKING */ +#define LOCK_TCPIP_CORE() +#define UNLOCK_TCPIP_CORE() +#define TCPIP_APIMSG(m) tcpip_apimsg(m) +#define TCPIP_APIMSG_ACK(m) sys_sem_signal(&m->conn->op_completed) +#define TCPIP_NETIFAPI(m) tcpip_netifapi(m) +#define TCPIP_NETIFAPI_ACK(m) sys_sem_signal(&m->sem) +#endif /* LWIP_TCPIP_CORE_LOCKING */ + +/** Function prototype for the init_done function passed to tcpip_init */ +typedef void (*tcpip_init_done_fn)(void *arg); +/** Function prototype for functions passed to tcpip_callback() */ +typedef void (*tcpip_callback_fn)(void *ctx); + +/* Forward declarations */ +struct tcpip_callback_msg; + +void tcpip_init(tcpip_init_done_fn tcpip_init_done, void *arg); + +#if LWIP_NETCONN +err_t tcpip_apimsg(struct api_msg *apimsg); +#if LWIP_TCPIP_CORE_LOCKING +err_t tcpip_apimsg_lock(struct api_msg *apimsg); +#endif /* LWIP_TCPIP_CORE_LOCKING */ +#endif /* LWIP_NETCONN */ + +err_t tcpip_input(struct pbuf *p, struct netif *inp); + +#if LWIP_NETIF_API +err_t tcpip_netifapi(struct netifapi_msg *netifapimsg); +#if LWIP_TCPIP_CORE_LOCKING +err_t tcpip_netifapi_lock(struct netifapi_msg *netifapimsg); +#endif /* LWIP_TCPIP_CORE_LOCKING */ +#endif /* LWIP_NETIF_API */ + +err_t tcpip_callback_with_block(tcpip_callback_fn function, void *ctx, u8_t block); +#define tcpip_callback(f, ctx) tcpip_callback_with_block(f, ctx, 1) + +struct tcpip_callback_msg* tcpip_callbackmsg_new(tcpip_callback_fn function, void *ctx); +void tcpip_callbackmsg_delete(struct tcpip_callback_msg* msg); +err_t tcpip_trycallback(struct tcpip_callback_msg* msg); + +/* free pbufs or heap memory from another context without blocking */ +err_t pbuf_free_callback(struct pbuf *p); +err_t mem_free_callback(void *m); + +#if LWIP_TCPIP_TIMEOUT +err_t tcpip_timeout(u32_t msecs, sys_timeout_handler h, void *arg); +err_t tcpip_untimeout(sys_timeout_handler h, void *arg); +#endif /* LWIP_TCPIP_TIMEOUT */ + +enum tcpip_msg_type { +#if LWIP_NETCONN + TCPIP_MSG_API, +#endif /* LWIP_NETCONN */ + TCPIP_MSG_INPKT, +#if LWIP_NETIF_API + TCPIP_MSG_NETIFAPI, +#endif /* LWIP_NETIF_API */ +#if LWIP_TCPIP_TIMEOUT + TCPIP_MSG_TIMEOUT, + TCPIP_MSG_UNTIMEOUT, +#endif /* LWIP_TCPIP_TIMEOUT */ + TCPIP_MSG_CALLBACK, + TCPIP_MSG_CALLBACK_STATIC +}; + +struct tcpip_msg { + enum tcpip_msg_type type; + sys_sem_t *sem; + union { +#if LWIP_NETCONN + struct api_msg *apimsg; +#endif /* LWIP_NETCONN */ +#if LWIP_NETIF_API + struct netifapi_msg *netifapimsg; +#endif /* LWIP_NETIF_API */ + struct { + struct pbuf *p; + struct netif *netif; + } inp; + struct { + tcpip_callback_fn function; + void *ctx; + } cb; +#if LWIP_TCPIP_TIMEOUT + struct { + u32_t msecs; + sys_timeout_handler h; + void *arg; + } tmo; +#endif /* LWIP_TCPIP_TIMEOUT */ + } msg; +}; + +#ifdef __cplusplus +} +#endif + +#endif /* !NO_SYS */ + +#endif /* __LWIP_TCPIP_H__ */ diff --git a/src/lwip-1.4.1/src/include/lwip/timers.h b/src/lwip-1.4.1/src/include/lwip/timers.h new file mode 100644 index 0000000..04e78e0 --- /dev/null +++ b/src/lwip-1.4.1/src/include/lwip/timers.h @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * Simon Goldschmidt + * + */ +#ifndef __LWIP_TIMERS_H__ +#define __LWIP_TIMERS_H__ + +#include "lwip/opt.h" + +/* Timers are not supported when NO_SYS==1 and NO_SYS_NO_TIMERS==1 */ +#define LWIP_TIMERS (!NO_SYS || (NO_SYS && !NO_SYS_NO_TIMERS)) + +#if LWIP_TIMERS + +#include "lwip/err.h" +#if !NO_SYS +#include "lwip/sys.h" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef LWIP_DEBUG_TIMERNAMES +#ifdef LWIP_DEBUG +#define LWIP_DEBUG_TIMERNAMES SYS_DEBUG +#else /* LWIP_DEBUG */ +#define LWIP_DEBUG_TIMERNAMES 0 +#endif /* LWIP_DEBUG*/ +#endif + +/** Function prototype for a timeout callback function. Register such a function + * using sys_timeout(). + * + * @param arg Additional argument to pass to the function - set up by sys_timeout() + */ +typedef void (* sys_timeout_handler)(void *arg); + +struct sys_timeo { + struct sys_timeo *next; + u32_t time; + sys_timeout_handler h; + void *arg; +#if LWIP_DEBUG_TIMERNAMES + const char* handler_name; +#endif /* LWIP_DEBUG_TIMERNAMES */ +}; + +void sys_timeouts_init(void); + +#if LWIP_DEBUG_TIMERNAMES +void sys_timeout_debug(u32_t msecs, sys_timeout_handler handler, void *arg, const char* handler_name); +#define sys_timeout(msecs, handler, arg) sys_timeout_debug(msecs, handler, arg, #handler) +#else /* LWIP_DEBUG_TIMERNAMES */ +void sys_timeout(u32_t msecs, sys_timeout_handler handler, void *arg); +#endif /* LWIP_DEBUG_TIMERNAMES */ + +void sys_untimeout(sys_timeout_handler handler, void *arg); +#if NO_SYS +void sys_check_timeouts(void); +void sys_restart_timeouts(void); +#else /* NO_SYS */ +void sys_timeouts_mbox_fetch(sys_mbox_t *mbox, void **msg); +#endif /* NO_SYS */ + + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_TIMERS */ +#endif /* __LWIP_TIMERS_H__ */ diff --git a/src/lwip-1.4.1/src/include/lwip/udp.h b/src/lwip-1.4.1/src/include/lwip/udp.h new file mode 100644 index 0000000..f1e6d3f --- /dev/null +++ b/src/lwip-1.4.1/src/include/lwip/udp.h @@ -0,0 +1,171 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __LWIP_UDP_H__ +#define __LWIP_UDP_H__ + +#include "lwip/opt.h" + +#if LWIP_UDP /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/pbuf.h" +#include "lwip/netif.h" +#include "lwip/ip_addr.h" +#include "lwip/ip.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define UDP_HLEN 8 + +/* Fields are (of course) in network byte order. */ +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct udp_hdr { + PACK_STRUCT_FIELD(u16_t src); + PACK_STRUCT_FIELD(u16_t dest); /* src/dest UDP ports */ + PACK_STRUCT_FIELD(u16_t len); + PACK_STRUCT_FIELD(u16_t chksum); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +#define UDP_FLAGS_NOCHKSUM 0x01U +#define UDP_FLAGS_UDPLITE 0x02U +#define UDP_FLAGS_CONNECTED 0x04U +#define UDP_FLAGS_MULTICAST_LOOP 0x08U + +struct udp_pcb; + +/** Function prototype for udp pcb receive callback functions + * addr and port are in same byte order as in the pcb + * The callback is responsible for freeing the pbuf + * if it's not used any more. + * + * ATTENTION: Be aware that 'addr' points into the pbuf 'p' so freeing this pbuf + * makes 'addr' invalid, too. + * + * @param arg user supplied argument (udp_pcb.recv_arg) + * @param pcb the udp_pcb which received data + * @param p the packet buffer that was received + * @param addr the remote IP address from which the packet was received + * @param port the remote port from which the packet was received + */ +typedef void (*udp_recv_fn)(void *arg, struct udp_pcb *pcb, struct pbuf *p, + ip_addr_t *addr, u16_t port); + + +struct udp_pcb { +/* Common members of all PCB types */ + IP_PCB; + +/* Protocol specific PCB members */ + + struct udp_pcb *next; + + u8_t flags; + /** ports are in host byte order */ + u16_t local_port, remote_port; + +#if LWIP_IGMP + /** outgoing network interface for multicast packets */ + ip_addr_t multicast_ip; +#endif /* LWIP_IGMP */ + +#if LWIP_UDPLITE + /** used for UDP_LITE only */ + u16_t chksum_len_rx, chksum_len_tx; +#endif /* LWIP_UDPLITE */ + + /** receive callback function */ + udp_recv_fn recv; + /** user-supplied argument for the recv callback */ + void *recv_arg; +}; +/* udp_pcbs export for exernal reference (e.g. SNMP agent) */ +extern struct udp_pcb *udp_pcbs; + +/* The following functions is the application layer interface to the + UDP code. */ +struct udp_pcb * udp_new (void); +void udp_remove (struct udp_pcb *pcb); +err_t udp_bind (struct udp_pcb *pcb, ip_addr_t *ipaddr, + u16_t port); +err_t udp_connect (struct udp_pcb *pcb, ip_addr_t *ipaddr, + u16_t port); +void udp_disconnect (struct udp_pcb *pcb); +void udp_recv (struct udp_pcb *pcb, udp_recv_fn recv, + void *recv_arg); +err_t udp_sendto_if (struct udp_pcb *pcb, struct pbuf *p, + ip_addr_t *dst_ip, u16_t dst_port, + struct netif *netif); +err_t udp_sendto (struct udp_pcb *pcb, struct pbuf *p, + ip_addr_t *dst_ip, u16_t dst_port); +err_t udp_send (struct udp_pcb *pcb, struct pbuf *p); + +#if LWIP_CHECKSUM_ON_COPY +err_t udp_sendto_if_chksum(struct udp_pcb *pcb, struct pbuf *p, + ip_addr_t *dst_ip, u16_t dst_port, + struct netif *netif, u8_t have_chksum, + u16_t chksum); +err_t udp_sendto_chksum(struct udp_pcb *pcb, struct pbuf *p, + ip_addr_t *dst_ip, u16_t dst_port, + u8_t have_chksum, u16_t chksum); +err_t udp_send_chksum(struct udp_pcb *pcb, struct pbuf *p, + u8_t have_chksum, u16_t chksum); +#endif /* LWIP_CHECKSUM_ON_COPY */ + +#define udp_flags(pcb) ((pcb)->flags) +#define udp_setflags(pcb, f) ((pcb)->flags = (f)) + +/* The following functions are the lower layer interface to UDP. */ +void udp_input (struct pbuf *p, struct netif *inp); + +void udp_init (void); + +#if UDP_DEBUG +void udp_debug_print(struct udp_hdr *udphdr); +#else +#define udp_debug_print(udphdr) +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_UDP */ + +#endif /* __LWIP_UDP_H__ */ diff --git a/src/lwip-1.4.1/src/include/lwipopts.h b/src/lwip-1.4.1/src/include/lwipopts.h new file mode 100644 index 0000000..2331959 --- /dev/null +++ b/src/lwip-1.4.1/src/include/lwipopts.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2001-2003 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Simon Goldschmidt + * + */ +#ifndef __LWIPOPTS_H__ +#define __LWIPOPTS_H__ + +/* Prevent having to link sys_arch.c (we don't test the API layers in unit tests) */ +#define NO_SYS 1 +#define MEM_ALIGNMENT 4 +#define LWIP_RAW 1 +#define LWIP_NETCONN 0 +#define LWIP_SOCKET 0 +#define LWIP_DHCP 0 +#define LWIP_ICMP 1 +#define LWIP_UDP 1 +#define LWIP_TCP 1 +#define ETH_PAD_SIZE 0 +#define LWIP_IP_ACCEPT_UDP_PORT(p) ((p) == PP_NTOHS(67)) + +#define TCP_MSS (1500 /*mtu*/ - 20 /*iphdr*/ - 20 /*tcphhr*/) +#define TCP_SND_BUF (2 * TCP_MSS) + +#define ETHARP_SUPPORT_STATIC_ENTRIES 1 + +#define LWIP_HTTPD_CGI 0 +#define LWIP_HTTPD_SSI 0 +#define LWIP_HTTPD_SSI_INCLUDE_TAG 0 + +#endif /* __LWIPOPTS_H__ */ diff --git a/src/lwip-1.4.1/src/include/lwippools.h b/src/lwip-1.4.1/src/include/lwippools.h new file mode 100644 index 0000000..d91c180 --- /dev/null +++ b/src/lwip-1.4.1/src/include/lwippools.h @@ -0,0 +1,10 @@ +//#ifndef LWIPPOOLS_H +//#define LWIPPOOLS_H + +LWIP_MALLOC_MEMPOOL_START +LWIP_MALLOC_MEMPOOL(4, 256) +LWIP_MALLOC_MEMPOOL(2, 512) +LWIP_MALLOC_MEMPOOL(1, 1024) +LWIP_MALLOC_MEMPOOL_END + +//#endif diff --git a/src/lwip-1.4.1/src/include/netif/etharp.h b/src/lwip-1.4.1/src/include/netif/etharp.h new file mode 100644 index 0000000..859608d --- /dev/null +++ b/src/lwip-1.4.1/src/include/netif/etharp.h @@ -0,0 +1,222 @@ +/* + * Copyright (c) 2001-2003 Swedish Institute of Computer Science. + * Copyright (c) 2003-2004 Leon Woestenberg + * Copyright (c) 2003-2004 Axon Digital Design B.V., The Netherlands. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#ifndef __NETIF_ETHARP_H__ +#define __NETIF_ETHARP_H__ + +#include "lwip/opt.h" + +#if LWIP_ARP || LWIP_ETHERNET /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/pbuf.h" +#include "lwip/ip_addr.h" +#include "lwip/netif.h" +#include "lwip/ip.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef ETHARP_HWADDR_LEN +#define ETHARP_HWADDR_LEN 6 +#endif + +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct eth_addr { + PACK_STRUCT_FIELD(u8_t addr[ETHARP_HWADDR_LEN]); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +/** Ethernet header */ +struct eth_hdr { +#if ETH_PAD_SIZE + PACK_STRUCT_FIELD(u8_t padding[ETH_PAD_SIZE]); +#endif + PACK_STRUCT_FIELD(struct eth_addr dest); + PACK_STRUCT_FIELD(struct eth_addr src); + PACK_STRUCT_FIELD(u16_t type); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +#define SIZEOF_ETH_HDR (14 + ETH_PAD_SIZE) + +#if ETHARP_SUPPORT_VLAN + +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +/** VLAN header inserted between ethernet header and payload + * if 'type' in ethernet header is ETHTYPE_VLAN. + * See IEEE802.Q */ +struct eth_vlan_hdr { + PACK_STRUCT_FIELD(u16_t prio_vid); + PACK_STRUCT_FIELD(u16_t tpid); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +#define SIZEOF_VLAN_HDR 4 +#define VLAN_ID(vlan_hdr) (htons((vlan_hdr)->prio_vid) & 0xFFF) + +#endif /* ETHARP_SUPPORT_VLAN */ + +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +/** the ARP message, see RFC 826 ("Packet format") */ +struct etharp_hdr { + PACK_STRUCT_FIELD(u16_t hwtype); + PACK_STRUCT_FIELD(u16_t proto); + PACK_STRUCT_FIELD(u8_t hwlen); + PACK_STRUCT_FIELD(u8_t protolen); + PACK_STRUCT_FIELD(u16_t opcode); + PACK_STRUCT_FIELD(struct eth_addr shwaddr); + PACK_STRUCT_FIELD(struct ip_addr2 sipaddr); + PACK_STRUCT_FIELD(struct eth_addr dhwaddr); + PACK_STRUCT_FIELD(struct ip_addr2 dipaddr); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +#define SIZEOF_ETHARP_HDR 28 +#define SIZEOF_ETHARP_PACKET (SIZEOF_ETH_HDR + SIZEOF_ETHARP_HDR) + +/** 5 seconds period */ +#define ARP_TMR_INTERVAL 5000 + +#define ETHTYPE_ARP 0x0806U +#define ETHTYPE_IP 0x0800U +#define ETHTYPE_VLAN 0x8100U +#define ETHTYPE_PPPOEDISC 0x8863U /* PPP Over Ethernet Discovery Stage */ +#define ETHTYPE_PPPOE 0x8864U /* PPP Over Ethernet Session Stage */ + +/** MEMCPY-like macro to copy to/from struct eth_addr's that are local variables + * or known to be 32-bit aligned within the protocol header. */ +#ifndef ETHADDR32_COPY +#define ETHADDR32_COPY(src, dst) SMEMCPY(src, dst, ETHARP_HWADDR_LEN) +#endif + +/** MEMCPY-like macro to copy to/from struct eth_addr's that are no local + * variables and known to be 16-bit aligned within the protocol header. */ +#ifndef ETHADDR16_COPY +#define ETHADDR16_COPY(src, dst) SMEMCPY(src, dst, ETHARP_HWADDR_LEN) +#endif + +#if LWIP_ARP /* don't build if not configured for use in lwipopts.h */ + +/** ARP message types (opcodes) */ +#define ARP_REQUEST 1 +#define ARP_REPLY 2 + +/** Define this to 1 and define LWIP_ARP_FILTER_NETIF_FN(pbuf, netif, type) + * to a filter function that returns the correct netif when using multiple + * netifs on one hardware interface where the netif's low-level receive + * routine cannot decide for the correct netif (e.g. when mapping multiple + * IP addresses to one hardware interface). + */ +#ifndef LWIP_ARP_FILTER_NETIF +#define LWIP_ARP_FILTER_NETIF 0 +#endif + +#if ARP_QUEUEING +/** struct for queueing outgoing packets for unknown address + * defined here to be accessed by memp.h + */ +struct etharp_q_entry { + struct etharp_q_entry *next; + struct pbuf *p; +}; +#endif /* ARP_QUEUEING */ + +#define etharp_init() /* Compatibility define, not init needed. */ +void etharp_tmr(void); +s8_t etharp_find_addr(struct netif *netif, ip_addr_t *ipaddr, + struct eth_addr **eth_ret, ip_addr_t **ip_ret); +err_t etharp_output(struct netif *netif, struct pbuf *q, ip_addr_t *ipaddr); +err_t etharp_query(struct netif *netif, ip_addr_t *ipaddr, struct pbuf *q); +err_t etharp_request(struct netif *netif, ip_addr_t *ipaddr); +/** For Ethernet network interfaces, we might want to send "gratuitous ARP"; + * this is an ARP packet sent by a node in order to spontaneously cause other + * nodes to update an entry in their ARP cache. + * From RFC 3220 "IP Mobility Support for IPv4" section 4.6. */ +#define etharp_gratuitous(netif) etharp_request((netif), &(netif)->ip_addr) +void etharp_cleanup_netif(struct netif *netif); + +#if ETHARP_SUPPORT_STATIC_ENTRIES +err_t etharp_add_static_entry(ip_addr_t *ipaddr, struct eth_addr *ethaddr); +err_t etharp_remove_static_entry(ip_addr_t *ipaddr); +#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */ + +#if LWIP_AUTOIP +err_t etharp_raw(struct netif *netif, const struct eth_addr *ethsrc_addr, + const struct eth_addr *ethdst_addr, + const struct eth_addr *hwsrc_addr, const ip_addr_t *ipsrc_addr, + const struct eth_addr *hwdst_addr, const ip_addr_t *ipdst_addr, + const u16_t opcode); +#endif /* LWIP_AUTOIP */ + +#endif /* LWIP_ARP */ + +err_t ethernet_input(struct pbuf *p, struct netif *netif); + +#define eth_addr_cmp(addr1, addr2) (memcmp((addr1)->addr, (addr2)->addr, ETHARP_HWADDR_LEN) == 0) + +extern const struct eth_addr ethbroadcast, ethzero; + +#endif /* LWIP_ARP || LWIP_ETHERNET */ + +#ifdef __cplusplus +} +#endif + +#endif /* __NETIF_ARP_H__ */ diff --git a/src/lwip-1.4.1/src/include/netif/ppp_oe.h b/src/lwip-1.4.1/src/include/netif/ppp_oe.h new file mode 100644 index 0000000..e1cdfa5 --- /dev/null +++ b/src/lwip-1.4.1/src/include/netif/ppp_oe.h @@ -0,0 +1,190 @@ +/***************************************************************************** +* ppp_oe.h - PPP Over Ethernet implementation for lwIP. +* +* Copyright (c) 2006 by Marc Boucher, Services Informatiques (MBSI) inc. +* +* The authors hereby grant permission to use, copy, modify, distribute, +* and license this software and its documentation for any purpose, provided +* that existing copyright notices are retained in all copies and that this +* notice and the following disclaimer are included verbatim in any +* distributions. No written agreement, license, or royalty fee is required +* for any of the authorized uses. +* +* THIS SOFTWARE IS PROVIDED BY THE 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 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. +* +****************************************************************************** +* REVISION HISTORY +* +* 06-01-01 Marc Boucher +* Ported to lwIP. +*****************************************************************************/ + + + +/* based on NetBSD: if_pppoe.c,v 1.64 2006/01/31 23:50:15 martin Exp */ + +/*- + * Copyright (c) 2002 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Martin Husemann . + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 PPP_OE_H +#define PPP_OE_H + +#include "lwip/opt.h" + +#if PPPOE_SUPPORT > 0 + +#include "netif/etharp.h" + +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct pppoehdr { + PACK_STRUCT_FIELD(u8_t vertype); + PACK_STRUCT_FIELD(u8_t code); + PACK_STRUCT_FIELD(u16_t session); + PACK_STRUCT_FIELD(u16_t plen); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct pppoetag { + PACK_STRUCT_FIELD(u16_t tag); + PACK_STRUCT_FIELD(u16_t len); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + + +#define PPPOE_STATE_INITIAL 0 +#define PPPOE_STATE_PADI_SENT 1 +#define PPPOE_STATE_PADR_SENT 2 +#define PPPOE_STATE_SESSION 3 +#define PPPOE_STATE_CLOSING 4 +/* passive */ +#define PPPOE_STATE_PADO_SENT 1 + +#define PPPOE_HEADERLEN sizeof(struct pppoehdr) +#define PPPOE_VERTYPE 0x11 /* VER=1, TYPE = 1 */ + +#define PPPOE_TAG_EOL 0x0000 /* end of list */ +#define PPPOE_TAG_SNAME 0x0101 /* service name */ +#define PPPOE_TAG_ACNAME 0x0102 /* access concentrator name */ +#define PPPOE_TAG_HUNIQUE 0x0103 /* host unique */ +#define PPPOE_TAG_ACCOOKIE 0x0104 /* AC cookie */ +#define PPPOE_TAG_VENDOR 0x0105 /* vendor specific */ +#define PPPOE_TAG_RELAYSID 0x0110 /* relay session id */ +#define PPPOE_TAG_SNAME_ERR 0x0201 /* service name error */ +#define PPPOE_TAG_ACSYS_ERR 0x0202 /* AC system error */ +#define PPPOE_TAG_GENERIC_ERR 0x0203 /* gerneric error */ + +#define PPPOE_CODE_PADI 0x09 /* Active Discovery Initiation */ +#define PPPOE_CODE_PADO 0x07 /* Active Discovery Offer */ +#define PPPOE_CODE_PADR 0x19 /* Active Discovery Request */ +#define PPPOE_CODE_PADS 0x65 /* Active Discovery Session confirmation */ +#define PPPOE_CODE_PADT 0xA7 /* Active Discovery Terminate */ + +#ifndef ETHERMTU +#define ETHERMTU 1500 +#endif + +/* two byte PPP protocol discriminator, then IP data */ +#define PPPOE_MAXMTU (ETHERMTU-PPPOE_HEADERLEN-2) + +#ifndef PPPOE_MAX_AC_COOKIE_LEN +#define PPPOE_MAX_AC_COOKIE_LEN 64 +#endif + +struct pppoe_softc { + struct pppoe_softc *next; + struct netif *sc_ethif; /* ethernet interface we are using */ + int sc_pd; /* ppp unit number */ + void (*sc_linkStatusCB)(int pd, int up); + + int sc_state; /* discovery phase or session connected */ + struct eth_addr sc_dest; /* hardware address of concentrator */ + u16_t sc_session; /* PPPoE session id */ + +#ifdef PPPOE_TODO + char *sc_service_name; /* if != NULL: requested name of service */ + char *sc_concentrator_name; /* if != NULL: requested concentrator id */ +#endif /* PPPOE_TODO */ + u8_t sc_ac_cookie[PPPOE_MAX_AC_COOKIE_LEN]; /* content of AC cookie we must echo back */ + size_t sc_ac_cookie_len; /* length of cookie data */ +#ifdef PPPOE_SERVER + u8_t *sc_hunique; /* content of host unique we must echo back */ + size_t sc_hunique_len; /* length of host unique */ +#endif + int sc_padi_retried; /* number of PADI retries already done */ + int sc_padr_retried; /* number of PADR retries already done */ +}; + + +#define pppoe_init() /* compatibility define, no initialization needed */ + +err_t pppoe_create(struct netif *ethif, int pd, void (*linkStatusCB)(int pd, int up), struct pppoe_softc **scptr); +err_t pppoe_destroy(struct netif *ifp); + +int pppoe_connect(struct pppoe_softc *sc); +void pppoe_disconnect(struct pppoe_softc *sc); + +void pppoe_disc_input(struct netif *netif, struct pbuf *p); +void pppoe_data_input(struct netif *netif, struct pbuf *p); + +err_t pppoe_xmit(struct pppoe_softc *sc, struct pbuf *pb); + +/** used in ppp.c */ +#define PPPOE_HDRLEN (sizeof(struct eth_hdr) + PPPOE_HEADERLEN) + +#endif /* PPPOE_SUPPORT */ + +#endif /* PPP_OE_H */ diff --git a/src/lwip-1.4.1/src/include/netif/slipif.h b/src/lwip-1.4.1/src/include/netif/slipif.h new file mode 100644 index 0000000..7b6ce5e --- /dev/null +++ b/src/lwip-1.4.1/src/include/netif/slipif.h @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2001, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __NETIF_SLIPIF_H__ +#define __NETIF_SLIPIF_H__ + +#include "lwip/opt.h" +#include "lwip/netif.h" + +/** Set this to 1 to start a thread that blocks reading on the serial line + * (using sio_read()). + */ +#ifndef SLIP_USE_RX_THREAD +#define SLIP_USE_RX_THREAD !NO_SYS +#endif + +/** Set this to 1 to enable functions to pass in RX bytes from ISR context. + * If enabled, slipif_received_byte[s]() process incoming bytes and put assembled + * packets on a queue, which is fed into lwIP from slipif_poll(). + * If disabled, slipif_poll() polls the serila line (using sio_tryread()). + */ +#ifndef SLIP_RX_FROM_ISR +#define SLIP_RX_FROM_ISR 0 +#endif + +/** Set this to 1 (default for SLIP_RX_FROM_ISR) to queue incoming packets + * received by slipif_received_byte[s]() as long as PBUF_POOL pbufs are available. + * If disabled, packets will be dropped if more than one packet is received. + */ +#ifndef SLIP_RX_QUEUE +#define SLIP_RX_QUEUE SLIP_RX_FROM_ISR +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +err_t slipif_init(struct netif * netif); +void slipif_poll(struct netif *netif); +#if SLIP_RX_FROM_ISR +void slipif_process_rxqueue(struct netif *netif); +void slipif_received_byte(struct netif *netif, u8_t data); +void slipif_received_bytes(struct netif *netif, u8_t *data, u8_t len); +#endif /* SLIP_RX_FROM_ISR */ + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/src/lwip-1.4.1/src/include/posix/netdb.h b/src/lwip-1.4.1/src/include/posix/netdb.h new file mode 100644 index 0000000..7134032 --- /dev/null +++ b/src/lwip-1.4.1/src/include/posix/netdb.h @@ -0,0 +1,33 @@ +/** + * @file + * This file is a posix wrapper for lwip/netdb.h. + */ + +/* + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * This file is part of the lwIP TCP/IP stack. + * + */ + +#include "lwip/netdb.h" diff --git a/src/lwip-1.4.1/src/include/posix/sys/socket.h b/src/lwip-1.4.1/src/include/posix/sys/socket.h new file mode 100644 index 0000000..f7c7066 --- /dev/null +++ b/src/lwip-1.4.1/src/include/posix/sys/socket.h @@ -0,0 +1,33 @@ +/** + * @file + * This file is a posix wrapper for lwip/sockets.h. + */ + +/* + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * This file is part of the lwIP TCP/IP stack. + * + */ + +#include "lwip/sockets.h" diff --git a/src/lwip-1.4.1/src/netif/FILES b/src/lwip-1.4.1/src/netif/FILES new file mode 100644 index 0000000..099dbf3 --- /dev/null +++ b/src/lwip-1.4.1/src/netif/FILES @@ -0,0 +1,29 @@ +This directory contains generic network interface device drivers that +do not contain any hardware or architecture specific code. The files +are: + +etharp.c + Implements the ARP (Address Resolution Protocol) over + Ethernet. The code in this file should be used together with + Ethernet device drivers. Note that this module has been + largely made Ethernet independent so you should be able to + adapt this for other link layers (such as Firewire). + +ethernetif.c + An example of how an Ethernet device driver could look. This + file can be used as a "skeleton" for developing new Ethernet + network device drivers. It uses the etharp.c ARP code. + +loopif.c + A "loopback" network interface driver. It requires configuration + through the define LWIP_LOOPIF_MULTITHREADING (see opt.h). + +slipif.c + A generic implementation of the SLIP (Serial Line IP) + protocol. It requires a sio (serial I/O) module to work. + +ppp/ Point-to-Point Protocol stack + The PPP stack has been ported from ucip (http://ucip.sourceforge.net). + It matches quite well to pppd 2.3.1 (http://ppp.samba.org), although + compared to that, it has some modifications for embedded systems and + the source code has been reordered a bit. \ No newline at end of file diff --git a/src/lwip-1.4.1/src/netif/etharp.c b/src/lwip-1.4.1/src/netif/etharp.c new file mode 100644 index 0000000..5e382d1 --- /dev/null +++ b/src/lwip-1.4.1/src/netif/etharp.c @@ -0,0 +1,1399 @@ +/** + * @file + * Address Resolution Protocol module for IP over Ethernet + * + * Functionally, ARP is divided into two parts. The first maps an IP address + * to a physical address when sending a packet, and the second part answers + * requests from other machines for our physical address. + * + * This implementation complies with RFC 826 (Ethernet ARP). It supports + * Gratuitious ARP from RFC3220 (IP Mobility Support for IPv4) section 4.6 + * if an interface calls etharp_gratuitous(our_netif) upon address change. + */ + +/* + * Copyright (c) 2001-2003 Swedish Institute of Computer Science. + * Copyright (c) 2003-2004 Leon Woestenberg + * Copyright (c) 2003-2004 Axon Digital Design B.V., The Netherlands. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * This file is part of the lwIP TCP/IP stack. + * + */ + +#include "lwip/opt.h" + +#if LWIP_ARP || LWIP_ETHERNET + +#include "lwip/ip_addr.h" +#include "lwip/def.h" +#include "lwip/ip.h" +#include "lwip/stats.h" +#include "lwip/snmp.h" +#include "lwip/dhcp.h" +#include "lwip/autoip.h" +#include "netif/etharp.h" + +#if PPPOE_SUPPORT +#include "netif/ppp_oe.h" +#endif /* PPPOE_SUPPORT */ + +#include + +const struct eth_addr ethbroadcast = {{0xff,0xff,0xff,0xff,0xff,0xff}}; +const struct eth_addr ethzero = {{0,0,0,0,0,0}}; + +/** The 24-bit IANA multicast OUI is 01-00-5e: */ +#define LL_MULTICAST_ADDR_0 0x01 +#define LL_MULTICAST_ADDR_1 0x00 +#define LL_MULTICAST_ADDR_2 0x5e + +#if LWIP_ARP /* don't build if not configured for use in lwipopts.h */ + +/** the time an ARP entry stays valid after its last update, + * for ARP_TMR_INTERVAL = 5000, this is + * (240 * 5) seconds = 20 minutes. + */ +#define ARP_MAXAGE 240 +/** Re-request a used ARP entry 1 minute before it would expire to prevent + * breaking a steadily used connection because the ARP entry timed out. */ +#define ARP_AGE_REREQUEST_USED (ARP_MAXAGE - 12) + +/** the time an ARP entry stays pending after first request, + * for ARP_TMR_INTERVAL = 5000, this is + * (2 * 5) seconds = 10 seconds. + * + * @internal Keep this number at least 2, otherwise it might + * run out instantly if the timeout occurs directly after a request. + */ +#define ARP_MAXPENDING 2 + +#define HWTYPE_ETHERNET 1 + +enum etharp_state { + ETHARP_STATE_EMPTY = 0, + ETHARP_STATE_PENDING, + ETHARP_STATE_STABLE, + ETHARP_STATE_STABLE_REREQUESTING +#if ETHARP_SUPPORT_STATIC_ENTRIES + ,ETHARP_STATE_STATIC +#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */ +}; + +struct etharp_entry { +#if ARP_QUEUEING + /** Pointer to queue of pending outgoing packets on this ARP entry. */ + struct etharp_q_entry *q; +#else /* ARP_QUEUEING */ + /** Pointer to a single pending outgoing packet on this ARP entry. */ + struct pbuf *q; +#endif /* ARP_QUEUEING */ + ip_addr_t ipaddr; + struct netif *netif; + struct eth_addr ethaddr; + u8_t state; + u8_t ctime; +}; + +static struct etharp_entry arp_table[ARP_TABLE_SIZE]; + +#if !LWIP_NETIF_HWADDRHINT +static u8_t etharp_cached_entry; +#endif /* !LWIP_NETIF_HWADDRHINT */ + +/** Try hard to create a new entry - we want the IP address to appear in + the cache (even if this means removing an active entry or so). */ +#define ETHARP_FLAG_TRY_HARD 1 +#define ETHARP_FLAG_FIND_ONLY 2 +#if ETHARP_SUPPORT_STATIC_ENTRIES +#define ETHARP_FLAG_STATIC_ENTRY 4 +#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */ + +#if LWIP_NETIF_HWADDRHINT +#define ETHARP_SET_HINT(netif, hint) if (((netif) != NULL) && ((netif)->addr_hint != NULL)) \ + *((netif)->addr_hint) = (hint); +#else /* LWIP_NETIF_HWADDRHINT */ +#define ETHARP_SET_HINT(netif, hint) (etharp_cached_entry = (hint)) +#endif /* LWIP_NETIF_HWADDRHINT */ + + +/* Some checks, instead of etharp_init(): */ +#if (LWIP_ARP && (ARP_TABLE_SIZE > 0x7f)) + #error "ARP_TABLE_SIZE must fit in an s8_t, you have to reduce it in your lwipopts.h" +#endif + + +#if ARP_QUEUEING +/** + * Free a complete queue of etharp entries + * + * @param q a qeueue of etharp_q_entry's to free + */ +static void +free_etharp_q(struct etharp_q_entry *q) +{ + struct etharp_q_entry *r; + LWIP_ASSERT("q != NULL", q != NULL); + LWIP_ASSERT("q->p != NULL", q->p != NULL); + while (q) { + r = q; + q = q->next; + LWIP_ASSERT("r->p != NULL", (r->p != NULL)); + pbuf_free(r->p); + memp_free(MEMP_ARP_QUEUE, r); + } +} +#else /* ARP_QUEUEING */ + +/** Compatibility define: free the queued pbuf */ +#define free_etharp_q(q) pbuf_free(q) + +#endif /* ARP_QUEUEING */ + +/** Clean up ARP table entries */ +static void +etharp_free_entry(int i) +{ + /* remove from SNMP ARP index tree */ + snmp_delete_arpidx_tree(arp_table[i].netif, &arp_table[i].ipaddr); + /* and empty packet queue */ + if (arp_table[i].q != NULL) { + /* remove all queued packets */ + LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_free_entry: freeing entry %"U16_F", packet queue %p.\n", (u16_t)i, (void *)(arp_table[i].q))); + free_etharp_q(arp_table[i].q); + arp_table[i].q = NULL; + } + /* recycle entry for re-use */ + arp_table[i].state = ETHARP_STATE_EMPTY; +#ifdef LWIP_DEBUG + /* for debugging, clean out the complete entry */ + arp_table[i].ctime = 0; + arp_table[i].netif = NULL; + ip_addr_set_zero(&arp_table[i].ipaddr); + arp_table[i].ethaddr = ethzero; +#endif /* LWIP_DEBUG */ +} + +/** + * Clears expired entries in the ARP table. + * + * This function should be called every ETHARP_TMR_INTERVAL milliseconds (5 seconds), + * in order to expire entries in the ARP table. + */ +void +etharp_tmr(void) +{ + u8_t i; + + LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_timer\n")); + /* remove expired entries from the ARP table */ + for (i = 0; i < ARP_TABLE_SIZE; ++i) { + u8_t state = arp_table[i].state; + if (state != ETHARP_STATE_EMPTY +#if ETHARP_SUPPORT_STATIC_ENTRIES + && (state != ETHARP_STATE_STATIC) +#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */ + ) { + arp_table[i].ctime++; + if ((arp_table[i].ctime >= ARP_MAXAGE) || + ((arp_table[i].state == ETHARP_STATE_PENDING) && + (arp_table[i].ctime >= ARP_MAXPENDING))) { + /* pending or stable entry has become old! */ + LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_timer: expired %s entry %"U16_F".\n", + arp_table[i].state >= ETHARP_STATE_STABLE ? "stable" : "pending", (u16_t)i)); + /* clean up entries that have just been expired */ + etharp_free_entry(i); + } + else if (arp_table[i].state == ETHARP_STATE_STABLE_REREQUESTING) { + /* Reset state to stable, so that the next transmitted packet will + re-send an ARP request. */ + arp_table[i].state = ETHARP_STATE_STABLE; + } +#if ARP_QUEUEING + /* still pending entry? (not expired) */ + if (arp_table[i].state == ETHARP_STATE_PENDING) { + /* resend an ARP query here? */ + } +#endif /* ARP_QUEUEING */ + } + } +} + +/** + * Search the ARP table for a matching or new entry. + * + * If an IP address is given, return a pending or stable ARP entry that matches + * the address. If no match is found, create a new entry with this address set, + * but in state ETHARP_EMPTY. The caller must check and possibly change the + * state of the returned entry. + * + * If ipaddr is NULL, return a initialized new entry in state ETHARP_EMPTY. + * + * In all cases, attempt to create new entries from an empty entry. If no + * empty entries are available and ETHARP_FLAG_TRY_HARD flag is set, recycle + * old entries. Heuristic choose the least important entry for recycling. + * + * @param ipaddr IP address to find in ARP cache, or to add if not found. + * @param flags @see definition of ETHARP_FLAG_* + * @param netif netif related to this address (used for NETIF_HWADDRHINT) + * + * @return The ARP entry index that matched or is created, ERR_MEM if no + * entry is found or could be recycled. + */ +static s8_t +etharp_find_entry(ip_addr_t *ipaddr, u8_t flags) +{ + s8_t old_pending = ARP_TABLE_SIZE, old_stable = ARP_TABLE_SIZE; + s8_t empty = ARP_TABLE_SIZE; + u8_t i = 0, age_pending = 0, age_stable = 0; + /* oldest entry with packets on queue */ + s8_t old_queue = ARP_TABLE_SIZE; + /* its age */ + u8_t age_queue = 0; + + /** + * a) do a search through the cache, remember candidates + * b) select candidate entry + * c) create new entry + */ + + /* a) in a single search sweep, do all of this + * 1) remember the first empty entry (if any) + * 2) remember the oldest stable entry (if any) + * 3) remember the oldest pending entry without queued packets (if any) + * 4) remember the oldest pending entry with queued packets (if any) + * 5) search for a matching IP entry, either pending or stable + * until 5 matches, or all entries are searched for. + */ + + for (i = 0; i < ARP_TABLE_SIZE; ++i) { + u8_t state = arp_table[i].state; + /* no empty entry found yet and now we do find one? */ + if ((empty == ARP_TABLE_SIZE) && (state == ETHARP_STATE_EMPTY)) { + LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_find_entry: found empty entry %"U16_F"\n", (u16_t)i)); + /* remember first empty entry */ + empty = i; + } else if (state != ETHARP_STATE_EMPTY) { + LWIP_ASSERT("state == ETHARP_STATE_PENDING || state >= ETHARP_STATE_STABLE", + state == ETHARP_STATE_PENDING || state >= ETHARP_STATE_STABLE); + /* if given, does IP address match IP address in ARP entry? */ + if (ipaddr && ip_addr_cmp(ipaddr, &arp_table[i].ipaddr)) { + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: found matching entry %"U16_F"\n", (u16_t)i)); + /* found exact IP address match, simply bail out */ + return i; + } + /* pending entry? */ + if (state == ETHARP_STATE_PENDING) { + /* pending with queued packets? */ + if (arp_table[i].q != NULL) { + if (arp_table[i].ctime >= age_queue) { + old_queue = i; + age_queue = arp_table[i].ctime; + } + } else + /* pending without queued packets? */ + { + if (arp_table[i].ctime >= age_pending) { + old_pending = i; + age_pending = arp_table[i].ctime; + } + } + /* stable entry? */ + } else if (state >= ETHARP_STATE_STABLE) { +#if ETHARP_SUPPORT_STATIC_ENTRIES + /* don't record old_stable for static entries since they never expire */ + if (state < ETHARP_STATE_STATIC) +#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */ + { + /* remember entry with oldest stable entry in oldest, its age in maxtime */ + if (arp_table[i].ctime >= age_stable) { + old_stable = i; + age_stable = arp_table[i].ctime; + } + } + } + } + } + /* { we have no match } => try to create a new entry */ + + /* don't create new entry, only search? */ + if (((flags & ETHARP_FLAG_FIND_ONLY) != 0) || + /* or no empty entry found and not allowed to recycle? */ + ((empty == ARP_TABLE_SIZE) && ((flags & ETHARP_FLAG_TRY_HARD) == 0))) { + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: no empty entry found and not allowed to recycle\n")); + return (s8_t)ERR_MEM; + } + + /* b) choose the least destructive entry to recycle: + * 1) empty entry + * 2) oldest stable entry + * 3) oldest pending entry without queued packets + * 4) oldest pending entry with queued packets + * + * { ETHARP_FLAG_TRY_HARD is set at this point } + */ + + /* 1) empty entry available? */ + if (empty < ARP_TABLE_SIZE) { + i = empty; + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: selecting empty entry %"U16_F"\n", (u16_t)i)); + } else { + /* 2) found recyclable stable entry? */ + if (old_stable < ARP_TABLE_SIZE) { + /* recycle oldest stable*/ + i = old_stable; + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: selecting oldest stable entry %"U16_F"\n", (u16_t)i)); + /* no queued packets should exist on stable entries */ + LWIP_ASSERT("arp_table[i].q == NULL", arp_table[i].q == NULL); + /* 3) found recyclable pending entry without queued packets? */ + } else if (old_pending < ARP_TABLE_SIZE) { + /* recycle oldest pending */ + i = old_pending; + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: selecting oldest pending entry %"U16_F" (without queue)\n", (u16_t)i)); + /* 4) found recyclable pending entry with queued packets? */ + } else if (old_queue < ARP_TABLE_SIZE) { + /* recycle oldest pending (queued packets are free in etharp_free_entry) */ + i = old_queue; + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: selecting oldest pending entry %"U16_F", freeing packet queue %p\n", (u16_t)i, (void *)(arp_table[i].q))); + /* no empty or recyclable entries found */ + } else { + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: no empty or recyclable entries found\n")); + return (s8_t)ERR_MEM; + } + + /* { empty or recyclable entry found } */ + LWIP_ASSERT("i < ARP_TABLE_SIZE", i < ARP_TABLE_SIZE); + etharp_free_entry(i); + } + + LWIP_ASSERT("i < ARP_TABLE_SIZE", i < ARP_TABLE_SIZE); + LWIP_ASSERT("arp_table[i].state == ETHARP_STATE_EMPTY", + arp_table[i].state == ETHARP_STATE_EMPTY); + + /* IP address given? */ + if (ipaddr != NULL) { + /* set IP address */ + ip_addr_copy(arp_table[i].ipaddr, *ipaddr); + } + arp_table[i].ctime = 0; + return (err_t)i; +} + +/** + * Send an IP packet on the network using netif->linkoutput + * The ethernet header is filled in before sending. + * + * @params netif the lwIP network interface on which to send the packet + * @params p the packet to send, p->payload pointing to the (uninitialized) ethernet header + * @params src the source MAC address to be copied into the ethernet header + * @params dst the destination MAC address to be copied into the ethernet header + * @return ERR_OK if the packet was sent, any other err_t on failure + */ +static err_t +etharp_send_ip(struct netif *netif, struct pbuf *p, struct eth_addr *src, struct eth_addr *dst) +{ + struct eth_hdr *ethhdr = (struct eth_hdr *)p->payload; + + LWIP_ASSERT("netif->hwaddr_len must be the same as ETHARP_HWADDR_LEN for etharp!", + (netif->hwaddr_len == ETHARP_HWADDR_LEN)); + ETHADDR32_COPY(ðhdr->dest, dst); + ETHADDR16_COPY(ðhdr->src, src); + ethhdr->type = PP_HTONS(ETHTYPE_IP); + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_send_ip: sending packet %p\n", (void *)p)); + /* send the packet */ + return netif->linkoutput(netif, p); +} + +/** + * Update (or insert) a IP/MAC address pair in the ARP cache. + * + * If a pending entry is resolved, any queued packets will be sent + * at this point. + * + * @param netif netif related to this entry (used for NETIF_ADDRHINT) + * @param ipaddr IP address of the inserted ARP entry. + * @param ethaddr Ethernet address of the inserted ARP entry. + * @param flags @see definition of ETHARP_FLAG_* + * + * @return + * - ERR_OK Succesfully updated ARP cache. + * - ERR_MEM If we could not add a new ARP entry when ETHARP_FLAG_TRY_HARD was set. + * - ERR_ARG Non-unicast address given, those will not appear in ARP cache. + * + * @see pbuf_free() + */ +static err_t +etharp_update_arp_entry(struct netif *netif, ip_addr_t *ipaddr, struct eth_addr *ethaddr, u8_t flags) +{ + s8_t i; + LWIP_ASSERT("netif->hwaddr_len == ETHARP_HWADDR_LEN", netif->hwaddr_len == ETHARP_HWADDR_LEN); + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_update_arp_entry: %"U16_F".%"U16_F".%"U16_F".%"U16_F" - %02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F"\n", + ip4_addr1_16(ipaddr), ip4_addr2_16(ipaddr), ip4_addr3_16(ipaddr), ip4_addr4_16(ipaddr), + ethaddr->addr[0], ethaddr->addr[1], ethaddr->addr[2], + ethaddr->addr[3], ethaddr->addr[4], ethaddr->addr[5])); + /* non-unicast address? */ + if (ip_addr_isany(ipaddr) || + ip_addr_isbroadcast(ipaddr, netif) || + ip_addr_ismulticast(ipaddr)) { + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_update_arp_entry: will not add non-unicast IP address to ARP cache\n")); + return ERR_ARG; + } + /* find or create ARP entry */ + i = etharp_find_entry(ipaddr, flags); + /* bail out if no entry could be found */ + if (i < 0) { + return (err_t)i; + } + +#if ETHARP_SUPPORT_STATIC_ENTRIES + if (flags & ETHARP_FLAG_STATIC_ENTRY) { + /* record static type */ + arp_table[i].state = ETHARP_STATE_STATIC; + } else +#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */ + { + /* mark it stable */ + arp_table[i].state = ETHARP_STATE_STABLE; + } + + /* record network interface */ + arp_table[i].netif = netif; + /* insert in SNMP ARP index tree */ + snmp_insert_arpidx_tree(netif, &arp_table[i].ipaddr); + + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_update_arp_entry: updating stable entry %"S16_F"\n", (s16_t)i)); + /* update address */ + ETHADDR32_COPY(&arp_table[i].ethaddr, ethaddr); + /* reset time stamp */ + arp_table[i].ctime = 0; + /* this is where we will send out queued packets! */ +#if ARP_QUEUEING + while (arp_table[i].q != NULL) { + struct pbuf *p; + /* remember remainder of queue */ + struct etharp_q_entry *q = arp_table[i].q; + /* pop first item off the queue */ + arp_table[i].q = q->next; + /* get the packet pointer */ + p = q->p; + /* now queue entry can be freed */ + memp_free(MEMP_ARP_QUEUE, q); +#else /* ARP_QUEUEING */ + if (arp_table[i].q != NULL) { + struct pbuf *p = arp_table[i].q; + arp_table[i].q = NULL; +#endif /* ARP_QUEUEING */ + /* send the queued IP packet */ + etharp_send_ip(netif, p, (struct eth_addr*)(netif->hwaddr), ethaddr); + /* free the queued IP packet */ + pbuf_free(p); + } + return ERR_OK; +} + +#if ETHARP_SUPPORT_STATIC_ENTRIES +/** Add a new static entry to the ARP table. If an entry exists for the + * specified IP address, this entry is overwritten. + * If packets are queued for the specified IP address, they are sent out. + * + * @param ipaddr IP address for the new static entry + * @param ethaddr ethernet address for the new static entry + * @return @see return values of etharp_add_static_entry + */ +err_t +etharp_add_static_entry(ip_addr_t *ipaddr, struct eth_addr *ethaddr) +{ + struct netif *netif; + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_add_static_entry: %"U16_F".%"U16_F".%"U16_F".%"U16_F" - %02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F"\n", + ip4_addr1_16(ipaddr), ip4_addr2_16(ipaddr), ip4_addr3_16(ipaddr), ip4_addr4_16(ipaddr), + ethaddr->addr[0], ethaddr->addr[1], ethaddr->addr[2], + ethaddr->addr[3], ethaddr->addr[4], ethaddr->addr[5])); + + netif = ip_route(ipaddr); + if (netif == NULL) { + return ERR_RTE; + } + + return etharp_update_arp_entry(netif, ipaddr, ethaddr, ETHARP_FLAG_TRY_HARD | ETHARP_FLAG_STATIC_ENTRY); +} + +/** Remove a static entry from the ARP table previously added with a call to + * etharp_add_static_entry. + * + * @param ipaddr IP address of the static entry to remove + * @return ERR_OK: entry removed + * ERR_MEM: entry wasn't found + * ERR_ARG: entry wasn't a static entry but a dynamic one + */ +err_t +etharp_remove_static_entry(ip_addr_t *ipaddr) +{ + s8_t i; + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_remove_static_entry: %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", + ip4_addr1_16(ipaddr), ip4_addr2_16(ipaddr), ip4_addr3_16(ipaddr), ip4_addr4_16(ipaddr))); + + /* find or create ARP entry */ + i = etharp_find_entry(ipaddr, ETHARP_FLAG_FIND_ONLY); + /* bail out if no entry could be found */ + if (i < 0) { + return (err_t)i; + } + + if (arp_table[i].state != ETHARP_STATE_STATIC) { + /* entry wasn't a static entry, cannot remove it */ + return ERR_ARG; + } + /* entry found, free it */ + etharp_free_entry(i); + return ERR_OK; +} +#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */ + +/** + * Remove all ARP table entries of the specified netif. + * + * @param netif points to a network interface + */ +void etharp_cleanup_netif(struct netif *netif) +{ + u8_t i; + + for (i = 0; i < ARP_TABLE_SIZE; ++i) { + u8_t state = arp_table[i].state; + if ((state != ETHARP_STATE_EMPTY) && (arp_table[i].netif == netif)) { + etharp_free_entry(i); + } + } +} + +/** + * Finds (stable) ethernet/IP address pair from ARP table + * using interface and IP address index. + * @note the addresses in the ARP table are in network order! + * + * @param netif points to interface index + * @param ipaddr points to the (network order) IP address index + * @param eth_ret points to return pointer + * @param ip_ret points to return pointer + * @return table index if found, -1 otherwise + */ +s8_t +etharp_find_addr(struct netif *netif, ip_addr_t *ipaddr, + struct eth_addr **eth_ret, ip_addr_t **ip_ret) +{ + s8_t i; + + LWIP_ASSERT("eth_ret != NULL && ip_ret != NULL", + eth_ret != NULL && ip_ret != NULL); + + LWIP_UNUSED_ARG(netif); + + i = etharp_find_entry(ipaddr, ETHARP_FLAG_FIND_ONLY); + if((i >= 0) && (arp_table[i].state >= ETHARP_STATE_STABLE)) { + *eth_ret = &arp_table[i].ethaddr; + *ip_ret = &arp_table[i].ipaddr; + return i; + } + return -1; +} + +#if ETHARP_TRUST_IP_MAC +/** + * Updates the ARP table using the given IP packet. + * + * Uses the incoming IP packet's source address to update the + * ARP cache for the local network. The function does not alter + * or free the packet. This function must be called before the + * packet p is passed to the IP layer. + * + * @param netif The lwIP network interface on which the IP packet pbuf arrived. + * @param p The IP packet that arrived on netif. + * + * @return NULL + * + * @see pbuf_free() + */ +static void +etharp_ip_input(struct netif *netif, struct pbuf *p) +{ + struct eth_hdr *ethhdr; + struct ip_hdr *iphdr; + ip_addr_t iphdr_src; + LWIP_ERROR("netif != NULL", (netif != NULL), return;); + + /* Only insert an entry if the source IP address of the + incoming IP packet comes from a host on the local network. */ + ethhdr = (struct eth_hdr *)p->payload; + iphdr = (struct ip_hdr *)((u8_t*)ethhdr + SIZEOF_ETH_HDR); +#if ETHARP_SUPPORT_VLAN + if (ethhdr->type == PP_HTONS(ETHTYPE_VLAN)) { + iphdr = (struct ip_hdr *)((u8_t*)ethhdr + SIZEOF_ETH_HDR + SIZEOF_VLAN_HDR); + } +#endif /* ETHARP_SUPPORT_VLAN */ + + ip_addr_copy(iphdr_src, iphdr->src); + + /* source is not on the local network? */ + if (!ip_addr_netcmp(&iphdr_src, &(netif->ip_addr), &(netif->netmask))) { + /* do nothing */ + return; + } + + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_ip_input: updating ETHARP table.\n")); + /* update the source IP address in the cache, if present */ + /* @todo We could use ETHARP_FLAG_TRY_HARD if we think we are going to talk + * back soon (for example, if the destination IP address is ours. */ + etharp_update_arp_entry(netif, &iphdr_src, &(ethhdr->src), ETHARP_FLAG_FIND_ONLY); +} +#endif /* ETHARP_TRUST_IP_MAC */ + +/** + * Responds to ARP requests to us. Upon ARP replies to us, add entry to cache + * send out queued IP packets. Updates cache with snooped address pairs. + * + * Should be called for incoming ARP packets. The pbuf in the argument + * is freed by this function. + * + * @param netif The lwIP network interface on which the ARP packet pbuf arrived. + * @param ethaddr Ethernet address of netif. + * @param p The ARP packet that arrived on netif. Is freed by this function. + * + * @return NULL + * + * @see pbuf_free() + */ +static void +etharp_arp_input(struct netif *netif, struct eth_addr *ethaddr, struct pbuf *p) +{ + struct etharp_hdr *hdr; + struct eth_hdr *ethhdr; + /* these are aligned properly, whereas the ARP header fields might not be */ + ip_addr_t sipaddr, dipaddr; + u8_t for_us; +#if LWIP_AUTOIP + const u8_t * ethdst_hwaddr; +#endif /* LWIP_AUTOIP */ + + LWIP_ERROR("netif != NULL", (netif != NULL), return;); + + /* drop short ARP packets: we have to check for p->len instead of p->tot_len here + since a struct etharp_hdr is pointed to p->payload, so it musn't be chained! */ + if (p->len < SIZEOF_ETHARP_PACKET) { + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, + ("etharp_arp_input: packet dropped, too short (%"S16_F"/%"S16_F")\n", p->tot_len, + (s16_t)SIZEOF_ETHARP_PACKET)); + ETHARP_STATS_INC(etharp.lenerr); + ETHARP_STATS_INC(etharp.drop); + pbuf_free(p); + return; + } + + ethhdr = (struct eth_hdr *)p->payload; + hdr = (struct etharp_hdr *)((u8_t*)ethhdr + SIZEOF_ETH_HDR); +#if ETHARP_SUPPORT_VLAN + if (ethhdr->type == PP_HTONS(ETHTYPE_VLAN)) { + hdr = (struct etharp_hdr *)(((u8_t*)ethhdr) + SIZEOF_ETH_HDR + SIZEOF_VLAN_HDR); + } +#endif /* ETHARP_SUPPORT_VLAN */ + + /* RFC 826 "Packet Reception": */ + if ((hdr->hwtype != PP_HTONS(HWTYPE_ETHERNET)) || + (hdr->hwlen != ETHARP_HWADDR_LEN) || + (hdr->protolen != sizeof(ip_addr_t)) || + (hdr->proto != PP_HTONS(ETHTYPE_IP))) { + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, + ("etharp_arp_input: packet dropped, wrong hw type, hwlen, proto, protolen or ethernet type (%"U16_F"/%"U16_F"/%"U16_F"/%"U16_F")\n", + hdr->hwtype, hdr->hwlen, hdr->proto, hdr->protolen)); + ETHARP_STATS_INC(etharp.proterr); + ETHARP_STATS_INC(etharp.drop); + pbuf_free(p); + return; + } + ETHARP_STATS_INC(etharp.recv); + +#if LWIP_AUTOIP + /* We have to check if a host already has configured our random + * created link local address and continously check if there is + * a host with this IP-address so we can detect collisions */ + autoip_arp_reply(netif, hdr); +#endif /* LWIP_AUTOIP */ + + /* Copy struct ip_addr2 to aligned ip_addr, to support compilers without + * structure packing (not using structure copy which breaks strict-aliasing rules). */ + IPADDR2_COPY(&sipaddr, &hdr->sipaddr); + IPADDR2_COPY(&dipaddr, &hdr->dipaddr); + + /* this interface is not configured? */ + if (ip_addr_isany(&netif->ip_addr)) { + for_us = 0; + } else { + /* ARP packet directed to us? */ + for_us = (u8_t)ip_addr_cmp(&dipaddr, &(netif->ip_addr)); + } + + /* ARP message directed to us? + -> add IP address in ARP cache; assume requester wants to talk to us, + can result in directly sending the queued packets for this host. + ARP message not directed to us? + -> update the source IP address in the cache, if present */ + etharp_update_arp_entry(netif, &sipaddr, &(hdr->shwaddr), + for_us ? ETHARP_FLAG_TRY_HARD : ETHARP_FLAG_FIND_ONLY); + + /* now act on the message itself */ + switch (hdr->opcode) { + /* ARP request? */ + case PP_HTONS(ARP_REQUEST): + /* ARP request. If it asked for our address, we send out a + * reply. In any case, we time-stamp any existing ARP entry, + * and possiby send out an IP packet that was queued on it. */ + + LWIP_DEBUGF (ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_arp_input: incoming ARP request\n")); + /* ARP request for our address? */ + if (for_us) { + + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_arp_input: replying to ARP request for our IP address\n")); + /* Re-use pbuf to send ARP reply. + Since we are re-using an existing pbuf, we can't call etharp_raw since + that would allocate a new pbuf. */ + hdr->opcode = htons(ARP_REPLY); + + IPADDR2_COPY(&hdr->dipaddr, &hdr->sipaddr); + IPADDR2_COPY(&hdr->sipaddr, &netif->ip_addr); + + LWIP_ASSERT("netif->hwaddr_len must be the same as ETHARP_HWADDR_LEN for etharp!", + (netif->hwaddr_len == ETHARP_HWADDR_LEN)); +#if LWIP_AUTOIP + /* If we are using Link-Local, all ARP packets that contain a Link-Local + * 'sender IP address' MUST be sent using link-layer broadcast instead of + * link-layer unicast. (See RFC3927 Section 2.5, last paragraph) */ + ethdst_hwaddr = ip_addr_islinklocal(&netif->ip_addr) ? (u8_t*)(ethbroadcast.addr) : hdr->shwaddr.addr; +#endif /* LWIP_AUTOIP */ + + ETHADDR16_COPY(&hdr->dhwaddr, &hdr->shwaddr); +#if LWIP_AUTOIP + ETHADDR16_COPY(ðhdr->dest, ethdst_hwaddr); +#else /* LWIP_AUTOIP */ + ETHADDR16_COPY(ðhdr->dest, &hdr->shwaddr); +#endif /* LWIP_AUTOIP */ + ETHADDR16_COPY(&hdr->shwaddr, ethaddr); + ETHADDR16_COPY(ðhdr->src, ethaddr); + + /* hwtype, hwaddr_len, proto, protolen and the type in the ethernet header + are already correct, we tested that before */ + + /* return ARP reply */ + netif->linkoutput(netif, p); + /* we are not configured? */ + } else if (ip_addr_isany(&netif->ip_addr)) { + /* { for_us == 0 and netif->ip_addr.addr == 0 } */ + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_arp_input: we are unconfigured, ARP request ignored.\n")); + /* request was not directed to us */ + } else { + /* { for_us == 0 and netif->ip_addr.addr != 0 } */ + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_arp_input: ARP request was not for us.\n")); + } + break; + case PP_HTONS(ARP_REPLY): + /* ARP reply. We already updated the ARP cache earlier. */ + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_arp_input: incoming ARP reply\n")); +#if (LWIP_DHCP && DHCP_DOES_ARP_CHECK) + /* DHCP wants to know about ARP replies from any host with an + * IP address also offered to us by the DHCP server. We do not + * want to take a duplicate IP address on a single network. + * @todo How should we handle redundant (fail-over) interfaces? */ + dhcp_arp_reply(netif, &sipaddr); +#endif /* (LWIP_DHCP && DHCP_DOES_ARP_CHECK) */ + break; + default: + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_arp_input: ARP unknown opcode type %"S16_F"\n", htons(hdr->opcode))); + ETHARP_STATS_INC(etharp.err); + break; + } + /* free ARP packet */ + pbuf_free(p); +} + +/** Just a small helper function that sends a pbuf to an ethernet address + * in the arp_table specified by the index 'arp_idx'. + */ +static err_t +etharp_output_to_arp_index(struct netif *netif, struct pbuf *q, u8_t arp_idx) +{ + LWIP_ASSERT("arp_table[arp_idx].state >= ETHARP_STATE_STABLE", + arp_table[arp_idx].state >= ETHARP_STATE_STABLE); + /* if arp table entry is about to expire: re-request it, + but only if its state is ETHARP_STATE_STABLE to prevent flooding the + network with ARP requests if this address is used frequently. */ + if ((arp_table[arp_idx].state == ETHARP_STATE_STABLE) && + (arp_table[arp_idx].ctime >= ARP_AGE_REREQUEST_USED)) { + if (etharp_request(netif, &arp_table[arp_idx].ipaddr) == ERR_OK) { + arp_table[arp_idx].state = ETHARP_STATE_STABLE_REREQUESTING; + } + } + + return etharp_send_ip(netif, q, (struct eth_addr*)(netif->hwaddr), + &arp_table[arp_idx].ethaddr); +} + +/** + * Resolve and fill-in Ethernet address header for outgoing IP packet. + * + * For IP multicast and broadcast, corresponding Ethernet addresses + * are selected and the packet is transmitted on the link. + * + * For unicast addresses, the packet is submitted to etharp_query(). In + * case the IP address is outside the local network, the IP address of + * the gateway is used. + * + * @param netif The lwIP network interface which the IP packet will be sent on. + * @param q The pbuf(s) containing the IP packet to be sent. + * @param ipaddr The IP address of the packet destination. + * + * @return + * - ERR_RTE No route to destination (no gateway to external networks), + * or the return type of either etharp_query() or etharp_send_ip(). + */ +err_t +etharp_output(struct netif *netif, struct pbuf *q, ip_addr_t *ipaddr) +{ + struct eth_addr *dest; + struct eth_addr mcastaddr; + ip_addr_t *dst_addr = ipaddr; + + LWIP_ASSERT("netif != NULL", netif != NULL); + LWIP_ASSERT("q != NULL", q != NULL); + LWIP_ASSERT("ipaddr != NULL", ipaddr != NULL); + + /* make room for Ethernet header - should not fail */ + if (pbuf_header(q, sizeof(struct eth_hdr)) != 0) { + /* bail out */ + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, + ("etharp_output: could not allocate room for header.\n")); + LINK_STATS_INC(link.lenerr); + return ERR_BUF; + } + + /* Determine on destination hardware address. Broadcasts and multicasts + * are special, other IP addresses are looked up in the ARP table. */ + + /* broadcast destination IP address? */ + if (ip_addr_isbroadcast(ipaddr, netif)) { + /* broadcast on Ethernet also */ + dest = (struct eth_addr *)ðbroadcast; + /* multicast destination IP address? */ + } else if (ip_addr_ismulticast(ipaddr)) { + /* Hash IP multicast address to MAC address.*/ + mcastaddr.addr[0] = LL_MULTICAST_ADDR_0; + mcastaddr.addr[1] = LL_MULTICAST_ADDR_1; + mcastaddr.addr[2] = LL_MULTICAST_ADDR_2; + mcastaddr.addr[3] = ip4_addr2(ipaddr) & 0x7f; + mcastaddr.addr[4] = ip4_addr3(ipaddr); + mcastaddr.addr[5] = ip4_addr4(ipaddr); + /* destination Ethernet address is multicast */ + dest = &mcastaddr; + /* unicast destination IP address? */ + } else { + s8_t i; + /* outside local network? if so, this can neither be a global broadcast nor + a subnet broadcast. */ + if (!ip_addr_netcmp(ipaddr, &(netif->ip_addr), &(netif->netmask)) && + !ip_addr_islinklocal(ipaddr)) { +#if LWIP_AUTOIP + struct ip_hdr *iphdr = (struct ip_hdr*)((u8_t*)q->payload + + sizeof(struct eth_hdr)); + /* According to RFC 3297, chapter 2.6.2 (Forwarding Rules), a packet with + a link-local source address must always be "directly to its destination + on the same physical link. The host MUST NOT send the packet to any + router for forwarding". */ + if (!ip_addr_islinklocal(&iphdr->src)) +#endif /* LWIP_AUTOIP */ + { + /* interface has default gateway? */ + if (!ip_addr_isany(&netif->gw)) { + /* send to hardware address of default gateway IP address */ + dst_addr = &(netif->gw); + /* no default gateway available */ + } else { + /* no route to destination error (default gateway missing) */ + return ERR_RTE; + } + } + } +#if LWIP_NETIF_HWADDRHINT + if (netif->addr_hint != NULL) { + /* per-pcb cached entry was given */ + u8_t etharp_cached_entry = *(netif->addr_hint); + if (etharp_cached_entry < ARP_TABLE_SIZE) { +#endif /* LWIP_NETIF_HWADDRHINT */ + if ((arp_table[etharp_cached_entry].state >= ETHARP_STATE_STABLE) && + (ip_addr_cmp(dst_addr, &arp_table[etharp_cached_entry].ipaddr))) { + /* the per-pcb-cached entry is stable and the right one! */ + ETHARP_STATS_INC(etharp.cachehit); + return etharp_output_to_arp_index(netif, q, etharp_cached_entry); + } +#if LWIP_NETIF_HWADDRHINT + } + } +#endif /* LWIP_NETIF_HWADDRHINT */ + + /* find stable entry: do this here since this is a critical path for + throughput and etharp_find_entry() is kind of slow */ + for (i = 0; i < ARP_TABLE_SIZE; i++) { + if ((arp_table[i].state >= ETHARP_STATE_STABLE) && + (ip_addr_cmp(dst_addr, &arp_table[i].ipaddr))) { + /* found an existing, stable entry */ + ETHARP_SET_HINT(netif, i); + return etharp_output_to_arp_index(netif, q, i); + } + } + /* no stable entry found, use the (slower) query function: + queue on destination Ethernet address belonging to ipaddr */ + return etharp_query(netif, dst_addr, q); + } + + /* continuation for multicast/broadcast destinations */ + /* obtain source Ethernet address of the given interface */ + /* send packet directly on the link */ + return etharp_send_ip(netif, q, (struct eth_addr*)(netif->hwaddr), dest); +} + +/** + * Send an ARP request for the given IP address and/or queue a packet. + * + * If the IP address was not yet in the cache, a pending ARP cache entry + * is added and an ARP request is sent for the given address. The packet + * is queued on this entry. + * + * If the IP address was already pending in the cache, a new ARP request + * is sent for the given address. The packet is queued on this entry. + * + * If the IP address was already stable in the cache, and a packet is + * given, it is directly sent and no ARP request is sent out. + * + * If the IP address was already stable in the cache, and no packet is + * given, an ARP request is sent out. + * + * @param netif The lwIP network interface on which ipaddr + * must be queried for. + * @param ipaddr The IP address to be resolved. + * @param q If non-NULL, a pbuf that must be delivered to the IP address. + * q is not freed by this function. + * + * @note q must only be ONE packet, not a packet queue! + * + * @return + * - ERR_BUF Could not make room for Ethernet header. + * - ERR_MEM Hardware address unknown, and no more ARP entries available + * to query for address or queue the packet. + * - ERR_MEM Could not queue packet due to memory shortage. + * - ERR_RTE No route to destination (no gateway to external networks). + * - ERR_ARG Non-unicast address given, those will not appear in ARP cache. + * + */ +err_t +etharp_query(struct netif *netif, ip_addr_t *ipaddr, struct pbuf *q) +{ + struct eth_addr * srcaddr = (struct eth_addr *)netif->hwaddr; + err_t result = ERR_MEM; + s8_t i; /* ARP entry index */ + + /* non-unicast address? */ + if (ip_addr_isbroadcast(ipaddr, netif) || + ip_addr_ismulticast(ipaddr) || + ip_addr_isany(ipaddr)) { + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: will not add non-unicast IP address to ARP cache\n")); + return ERR_ARG; + } + + /* find entry in ARP cache, ask to create entry if queueing packet */ + i = etharp_find_entry(ipaddr, ETHARP_FLAG_TRY_HARD); + + /* could not find or create entry? */ + if (i < 0) { + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: could not create ARP entry\n")); + if (q) { + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: packet dropped\n")); + ETHARP_STATS_INC(etharp.memerr); + } + return (err_t)i; + } + + /* mark a fresh entry as pending (we just sent a request) */ + if (arp_table[i].state == ETHARP_STATE_EMPTY) { + arp_table[i].state = ETHARP_STATE_PENDING; + } + + /* { i is either a STABLE or (new or existing) PENDING entry } */ + LWIP_ASSERT("arp_table[i].state == PENDING or STABLE", + ((arp_table[i].state == ETHARP_STATE_PENDING) || + (arp_table[i].state >= ETHARP_STATE_STABLE))); + + /* do we have a pending entry? or an implicit query request? */ + if ((arp_table[i].state == ETHARP_STATE_PENDING) || (q == NULL)) { + /* try to resolve it; send out ARP request */ + result = etharp_request(netif, ipaddr); + if (result != ERR_OK) { + /* ARP request couldn't be sent */ + /* We don't re-send arp request in etharp_tmr, but we still queue packets, + since this failure could be temporary, and the next packet calling + etharp_query again could lead to sending the queued packets. */ + } + if (q == NULL) { + return result; + } + } + + /* packet given? */ + LWIP_ASSERT("q != NULL", q != NULL); + /* stable entry? */ + if (arp_table[i].state >= ETHARP_STATE_STABLE) { + /* we have a valid IP->Ethernet address mapping */ + ETHARP_SET_HINT(netif, i); + /* send the packet */ + result = etharp_send_ip(netif, q, srcaddr, &(arp_table[i].ethaddr)); + /* pending entry? (either just created or already pending */ + } else if (arp_table[i].state == ETHARP_STATE_PENDING) { + /* entry is still pending, queue the given packet 'q' */ + struct pbuf *p; + int copy_needed = 0; + /* IF q includes a PBUF_REF, PBUF_POOL or PBUF_RAM, we have no choice but + * to copy the whole queue into a new PBUF_RAM (see bug #11400) + * PBUF_ROMs can be left as they are, since ROM must not get changed. */ + p = q; + while (p) { + LWIP_ASSERT("no packet queues allowed!", (p->len != p->tot_len) || (p->next == 0)); + if(p->type != PBUF_ROM) { + copy_needed = 1; + break; + } + p = p->next; + } + if(copy_needed) { + /* copy the whole packet into new pbufs */ + p = pbuf_alloc(PBUF_RAW, p->tot_len, PBUF_RAM); + if(p != NULL) { + if (pbuf_copy(p, q) != ERR_OK) { + pbuf_free(p); + p = NULL; + } + } + } else { + /* referencing the old pbuf is enough */ + p = q; + pbuf_ref(p); + } + /* packet could be taken over? */ + if (p != NULL) { + /* queue packet ... */ +#if ARP_QUEUEING + struct etharp_q_entry *new_entry; + /* allocate a new arp queue entry */ + new_entry = (struct etharp_q_entry *)memp_malloc(MEMP_ARP_QUEUE); + if (new_entry != NULL) { + new_entry->next = 0; + new_entry->p = p; + if(arp_table[i].q != NULL) { + /* queue was already existent, append the new entry to the end */ + struct etharp_q_entry *r; + r = arp_table[i].q; + while (r->next != NULL) { + r = r->next; + } + r->next = new_entry; + } else { + /* queue did not exist, first item in queue */ + arp_table[i].q = new_entry; + } + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: queued packet %p on ARP entry %"S16_F"\n", (void *)q, (s16_t)i)); + result = ERR_OK; + } else { + /* the pool MEMP_ARP_QUEUE is empty */ + pbuf_free(p); + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: could not queue a copy of PBUF_REF packet %p (out of memory)\n", (void *)q)); + result = ERR_MEM; + } +#else /* ARP_QUEUEING */ + /* always queue one packet per ARP request only, freeing a previously queued packet */ + if (arp_table[i].q != NULL) { + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: dropped previously queued packet %p for ARP entry %"S16_F"\n", (void *)q, (s16_t)i)); + pbuf_free(arp_table[i].q); + } + arp_table[i].q = p; + result = ERR_OK; + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: queued packet %p on ARP entry %"S16_F"\n", (void *)q, (s16_t)i)); +#endif /* ARP_QUEUEING */ + } else { + ETHARP_STATS_INC(etharp.memerr); + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: could not queue a copy of PBUF_REF packet %p (out of memory)\n", (void *)q)); + result = ERR_MEM; + } + } + return result; +} + +/** + * Send a raw ARP packet (opcode and all addresses can be modified) + * + * @param netif the lwip network interface on which to send the ARP packet + * @param ethsrc_addr the source MAC address for the ethernet header + * @param ethdst_addr the destination MAC address for the ethernet header + * @param hwsrc_addr the source MAC address for the ARP protocol header + * @param ipsrc_addr the source IP address for the ARP protocol header + * @param hwdst_addr the destination MAC address for the ARP protocol header + * @param ipdst_addr the destination IP address for the ARP protocol header + * @param opcode the type of the ARP packet + * @return ERR_OK if the ARP packet has been sent + * ERR_MEM if the ARP packet couldn't be allocated + * any other err_t on failure + */ +#if !LWIP_AUTOIP +static +#endif /* LWIP_AUTOIP */ +err_t +etharp_raw(struct netif *netif, const struct eth_addr *ethsrc_addr, + const struct eth_addr *ethdst_addr, + const struct eth_addr *hwsrc_addr, const ip_addr_t *ipsrc_addr, + const struct eth_addr *hwdst_addr, const ip_addr_t *ipdst_addr, + const u16_t opcode) +{ + struct pbuf *p; + err_t result = ERR_OK; + struct eth_hdr *ethhdr; + struct etharp_hdr *hdr; +#if LWIP_AUTOIP + const u8_t * ethdst_hwaddr; +#endif /* LWIP_AUTOIP */ + + LWIP_ASSERT("netif != NULL", netif != NULL); + + /* allocate a pbuf for the outgoing ARP request packet */ + p = pbuf_alloc(PBUF_RAW, SIZEOF_ETHARP_PACKET, PBUF_RAM); + /* could allocate a pbuf for an ARP request? */ + if (p == NULL) { + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, + ("etharp_raw: could not allocate pbuf for ARP request.\n")); + ETHARP_STATS_INC(etharp.memerr); + return ERR_MEM; + } + LWIP_ASSERT("check that first pbuf can hold struct etharp_hdr", + (p->len >= SIZEOF_ETHARP_PACKET)); + + ethhdr = (struct eth_hdr *)p->payload; + hdr = (struct etharp_hdr *)((u8_t*)ethhdr + SIZEOF_ETH_HDR); + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_raw: sending raw ARP packet.\n")); + hdr->opcode = htons(opcode); + + LWIP_ASSERT("netif->hwaddr_len must be the same as ETHARP_HWADDR_LEN for etharp!", + (netif->hwaddr_len == ETHARP_HWADDR_LEN)); +#if LWIP_AUTOIP + /* If we are using Link-Local, all ARP packets that contain a Link-Local + * 'sender IP address' MUST be sent using link-layer broadcast instead of + * link-layer unicast. (See RFC3927 Section 2.5, last paragraph) */ + ethdst_hwaddr = ip_addr_islinklocal(ipsrc_addr) ? (u8_t*)(ethbroadcast.addr) : ethdst_addr->addr; +#endif /* LWIP_AUTOIP */ + /* Write the ARP MAC-Addresses */ + ETHADDR16_COPY(&hdr->shwaddr, hwsrc_addr); + ETHADDR16_COPY(&hdr->dhwaddr, hwdst_addr); + /* Write the Ethernet MAC-Addresses */ +#if LWIP_AUTOIP + ETHADDR16_COPY(ðhdr->dest, ethdst_hwaddr); +#else /* LWIP_AUTOIP */ + ETHADDR16_COPY(ðhdr->dest, ethdst_addr); +#endif /* LWIP_AUTOIP */ + ETHADDR16_COPY(ðhdr->src, ethsrc_addr); + /* Copy struct ip_addr2 to aligned ip_addr, to support compilers without + * structure packing. */ + IPADDR2_COPY(&hdr->sipaddr, ipsrc_addr); + IPADDR2_COPY(&hdr->dipaddr, ipdst_addr); + + hdr->hwtype = PP_HTONS(HWTYPE_ETHERNET); + hdr->proto = PP_HTONS(ETHTYPE_IP); + /* set hwlen and protolen */ + hdr->hwlen = ETHARP_HWADDR_LEN; + hdr->protolen = sizeof(ip_addr_t); + + ethhdr->type = PP_HTONS(ETHTYPE_ARP); + /* send ARP query */ + result = netif->linkoutput(netif, p); + ETHARP_STATS_INC(etharp.xmit); + /* free ARP query packet */ + pbuf_free(p); + p = NULL; + /* could not allocate pbuf for ARP request */ + + return result; +} + +/** + * Send an ARP request packet asking for ipaddr. + * + * @param netif the lwip network interface on which to send the request + * @param ipaddr the IP address for which to ask + * @return ERR_OK if the request has been sent + * ERR_MEM if the ARP packet couldn't be allocated + * any other err_t on failure + */ +err_t +etharp_request(struct netif *netif, ip_addr_t *ipaddr) +{ + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_request: sending ARP request.\n")); + return etharp_raw(netif, (struct eth_addr *)netif->hwaddr, ðbroadcast, + (struct eth_addr *)netif->hwaddr, &netif->ip_addr, ðzero, + ipaddr, ARP_REQUEST); +} +#endif /* LWIP_ARP */ + +/** + * Process received ethernet frames. Using this function instead of directly + * calling ip_input and passing ARP frames through etharp in ethernetif_input, + * the ARP cache is protected from concurrent access. + * + * @param p the recevied packet, p->payload pointing to the ethernet header + * @param netif the network interface on which the packet was received + */ +err_t +ethernet_input(struct pbuf *p, struct netif *netif) +{ + struct eth_hdr* ethhdr; + u16_t type; +#if LWIP_ARP || ETHARP_SUPPORT_VLAN + s16_t ip_hdr_offset = SIZEOF_ETH_HDR; +#endif /* LWIP_ARP || ETHARP_SUPPORT_VLAN */ + + if (p->len <= SIZEOF_ETH_HDR) { + /* a packet with only an ethernet header (or less) is not valid for us */ + ETHARP_STATS_INC(etharp.proterr); + ETHARP_STATS_INC(etharp.drop); + goto free_and_return; + } + + /* points to packet payload, which starts with an Ethernet header */ + ethhdr = (struct eth_hdr *)p->payload; + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, + ("ethernet_input: dest:%"X8_F":%"X8_F":%"X8_F":%"X8_F":%"X8_F":%"X8_F", src:%"X8_F":%"X8_F":%"X8_F":%"X8_F":%"X8_F":%"X8_F", type:%"X16_F"\n", + (unsigned)ethhdr->dest.addr[0], (unsigned)ethhdr->dest.addr[1], (unsigned)ethhdr->dest.addr[2], + (unsigned)ethhdr->dest.addr[3], (unsigned)ethhdr->dest.addr[4], (unsigned)ethhdr->dest.addr[5], + (unsigned)ethhdr->src.addr[0], (unsigned)ethhdr->src.addr[1], (unsigned)ethhdr->src.addr[2], + (unsigned)ethhdr->src.addr[3], (unsigned)ethhdr->src.addr[4], (unsigned)ethhdr->src.addr[5], + (unsigned)htons(ethhdr->type))); + + type = ethhdr->type; +#if ETHARP_SUPPORT_VLAN + if (type == PP_HTONS(ETHTYPE_VLAN)) { + struct eth_vlan_hdr *vlan = (struct eth_vlan_hdr*)(((char*)ethhdr) + SIZEOF_ETH_HDR); + if (p->len <= SIZEOF_ETH_HDR + SIZEOF_VLAN_HDR) { + /* a packet with only an ethernet/vlan header (or less) is not valid for us */ + ETHARP_STATS_INC(etharp.proterr); + ETHARP_STATS_INC(etharp.drop); + goto free_and_return; + } +#if defined(ETHARP_VLAN_CHECK) || defined(ETHARP_VLAN_CHECK_FN) /* if not, allow all VLANs */ +#ifdef ETHARP_VLAN_CHECK_FN + if (!ETHARP_VLAN_CHECK_FN(ethhdr, vlan)) { +#elif defined(ETHARP_VLAN_CHECK) + if (VLAN_ID(vlan) != ETHARP_VLAN_CHECK) { +#endif + /* silently ignore this packet: not for our VLAN */ + pbuf_free(p); + return ERR_OK; + } +#endif /* defined(ETHARP_VLAN_CHECK) || defined(ETHARP_VLAN_CHECK_FN) */ + type = vlan->tpid; + ip_hdr_offset = SIZEOF_ETH_HDR + SIZEOF_VLAN_HDR; + } +#endif /* ETHARP_SUPPORT_VLAN */ + +#if LWIP_ARP_FILTER_NETIF + netif = LWIP_ARP_FILTER_NETIF_FN(p, netif, htons(type)); +#endif /* LWIP_ARP_FILTER_NETIF*/ + + if (ethhdr->dest.addr[0] & 1) { + /* this might be a multicast or broadcast packet */ + if (ethhdr->dest.addr[0] == LL_MULTICAST_ADDR_0) { + if ((ethhdr->dest.addr[1] == LL_MULTICAST_ADDR_1) && + (ethhdr->dest.addr[2] == LL_MULTICAST_ADDR_2)) { + /* mark the pbuf as link-layer multicast */ + p->flags |= PBUF_FLAG_LLMCAST; + } + } else if (eth_addr_cmp(ðhdr->dest, ðbroadcast)) { + /* mark the pbuf as link-layer broadcast */ + p->flags |= PBUF_FLAG_LLBCAST; + } + } + + switch (type) { +#if LWIP_ARP + /* IP packet? */ + case PP_HTONS(ETHTYPE_IP): + if (!(netif->flags & NETIF_FLAG_ETHARP)) { + goto free_and_return; + } +#if ETHARP_TRUST_IP_MAC + /* update ARP table */ + etharp_ip_input(netif, p); +#endif /* ETHARP_TRUST_IP_MAC */ + /* skip Ethernet header */ + if(pbuf_header(p, -ip_hdr_offset)) { + LWIP_ASSERT("Can't move over header in packet", 0); + goto free_and_return; + } else { + /* pass to IP layer */ + ip_input(p, netif); + } + break; + + case PP_HTONS(ETHTYPE_ARP): + if (!(netif->flags & NETIF_FLAG_ETHARP)) { + goto free_and_return; + } + /* pass p to ARP module */ + etharp_arp_input(netif, (struct eth_addr*)(netif->hwaddr), p); + break; +#endif /* LWIP_ARP */ +#if PPPOE_SUPPORT + case PP_HTONS(ETHTYPE_PPPOEDISC): /* PPP Over Ethernet Discovery Stage */ + pppoe_disc_input(netif, p); + break; + + case PP_HTONS(ETHTYPE_PPPOE): /* PPP Over Ethernet Session Stage */ + pppoe_data_input(netif, p); + break; +#endif /* PPPOE_SUPPORT */ + + default: + ETHARP_STATS_INC(etharp.proterr); + ETHARP_STATS_INC(etharp.drop); + goto free_and_return; + } + + /* This means the pbuf is freed or consumed, + so the caller doesn't have to free it again */ + return ERR_OK; + +free_and_return: + pbuf_free(p); + return ERR_OK; +} +#endif /* LWIP_ARP || LWIP_ETHERNET */ diff --git a/src/lwip-1.4.1/src/netif/ethernetif.c b/src/lwip-1.4.1/src/netif/ethernetif.c new file mode 100644 index 0000000..8ec40be --- /dev/null +++ b/src/lwip-1.4.1/src/netif/ethernetif.c @@ -0,0 +1,317 @@ +/** + * @file + * Ethernet Interface Skeleton + * + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +/* + * This file is a skeleton for developing Ethernet network interface + * drivers for lwIP. Add code to the low_level functions and do a + * search-and-replace for the word "ethernetif" to replace it with + * something that better describes your network interface. + */ + +#include "lwip/opt.h" + +#if 0 /* don't build, this is only a skeleton, see previous comment */ + +#include "lwip/def.h" +#include "lwip/mem.h" +#include "lwip/pbuf.h" +#include +#include +#include "netif/etharp.h" +#include "netif/ppp_oe.h" + +/* Define those to better describe your network interface. */ +#define IFNAME0 'e' +#define IFNAME1 'n' + +/** + * Helper struct to hold private data used to operate your ethernet interface. + * Keeping the ethernet address of the MAC in this struct is not necessary + * as it is already kept in the struct netif. + * But this is only an example, anyway... + */ +struct ethernetif { + struct eth_addr *ethaddr; + /* Add whatever per-interface state that is needed here. */ +}; + +/* Forward declarations. */ +static void ethernetif_input(struct netif *netif); + +/** + * In this function, the hardware should be initialized. + * Called from ethernetif_init(). + * + * @param netif the already initialized lwip network interface structure + * for this ethernetif + */ +static void +low_level_init(struct netif *netif) +{ + struct ethernetif *ethernetif = netif->state; + + /* set MAC hardware address length */ + netif->hwaddr_len = ETHARP_HWADDR_LEN; + + /* set MAC hardware address */ + netif->hwaddr[0] = ; + ... + netif->hwaddr[5] = ; + + /* maximum transfer unit */ + netif->mtu = 1500; + + /* device capabilities */ + /* don't set NETIF_FLAG_ETHARP if this device is not an ethernet one */ + netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP; + + /* Do whatever else is needed to initialize interface. */ +} + +/** + * This function should do the actual transmission of the packet. The packet is + * contained in the pbuf that is passed to the function. This pbuf + * might be chained. + * + * @param netif the lwip network interface structure for this ethernetif + * @param p the MAC packet to send (e.g. IP packet including MAC addresses and type) + * @return ERR_OK if the packet could be sent + * an err_t value if the packet couldn't be sent + * + * @note Returning ERR_MEM here if a DMA queue of your MAC is full can lead to + * strange results. You might consider waiting for space in the DMA queue + * to become availale since the stack doesn't retry to send a packet + * dropped because of memory failure (except for the TCP timers). + */ + +static err_t +low_level_output(struct netif *netif, struct pbuf *p) +{ + struct ethernetif *ethernetif = netif->state; + struct pbuf *q; + + initiate transfer(); + +#if ETH_PAD_SIZE + pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */ +#endif + + for(q = p; q != NULL; q = q->next) { + /* Send the data from the pbuf to the interface, one pbuf at a + time. The size of the data in each pbuf is kept in the ->len + variable. */ + send data from(q->payload, q->len); + } + + signal that packet should be sent(); + +#if ETH_PAD_SIZE + pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */ +#endif + + LINK_STATS_INC(link.xmit); + + return ERR_OK; +} + +/** + * Should allocate a pbuf and transfer the bytes of the incoming + * packet from the interface into the pbuf. + * + * @param netif the lwip network interface structure for this ethernetif + * @return a pbuf filled with the received packet (including MAC header) + * NULL on memory error + */ +static struct pbuf * +low_level_input(struct netif *netif) +{ + struct ethernetif *ethernetif = netif->state; + struct pbuf *p, *q; + u16_t len; + + /* Obtain the size of the packet and put it into the "len" + variable. */ + len = ; + +#if ETH_PAD_SIZE + len += ETH_PAD_SIZE; /* allow room for Ethernet padding */ +#endif + + /* We allocate a pbuf chain of pbufs from the pool. */ + p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL); + + if (p != NULL) { + +#if ETH_PAD_SIZE + pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */ +#endif + + /* We iterate over the pbuf chain until we have read the entire + * packet into the pbuf. */ + for(q = p; q != NULL; q = q->next) { + /* Read enough bytes to fill this pbuf in the chain. The + * available data in the pbuf is given by the q->len + * variable. + * This does not necessarily have to be a memcpy, you can also preallocate + * pbufs for a DMA-enabled MAC and after receiving truncate it to the + * actually received size. In this case, ensure the tot_len member of the + * pbuf is the sum of the chained pbuf len members. + */ + read data into(q->payload, q->len); + } + acknowledge that packet has been read(); + +#if ETH_PAD_SIZE + pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */ +#endif + + LINK_STATS_INC(link.recv); + } else { + drop packet(); + LINK_STATS_INC(link.memerr); + LINK_STATS_INC(link.drop); + } + + return p; +} + +/** + * This function should be called when a packet is ready to be read + * from the interface. It uses the function low_level_input() that + * should handle the actual reception of bytes from the network + * interface. Then the type of the received packet is determined and + * the appropriate input function is called. + * + * @param netif the lwip network interface structure for this ethernetif + */ +static void +ethernetif_input(struct netif *netif) +{ + struct ethernetif *ethernetif; + struct eth_hdr *ethhdr; + struct pbuf *p; + + ethernetif = netif->state; + + /* move received packet into a new pbuf */ + p = low_level_input(netif); + /* no packet could be read, silently ignore this */ + if (p == NULL) return; + /* points to packet payload, which starts with an Ethernet header */ + ethhdr = p->payload; + + switch (htons(ethhdr->type)) { + /* IP or ARP packet? */ + case ETHTYPE_IP: + case ETHTYPE_ARP: +#if PPPOE_SUPPORT + /* PPPoE packet? */ + case ETHTYPE_PPPOEDISC: + case ETHTYPE_PPPOE: +#endif /* PPPOE_SUPPORT */ + /* full packet send to tcpip_thread to process */ + if (netif->input(p, netif)!=ERR_OK) + { LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: IP input error\n")); + pbuf_free(p); + p = NULL; + } + break; + + default: + pbuf_free(p); + p = NULL; + break; + } +} + +/** + * Should be called at the beginning of the program to set up the + * network interface. It calls the function low_level_init() to do the + * actual setup of the hardware. + * + * This function should be passed as a parameter to netif_add(). + * + * @param netif the lwip network interface structure for this ethernetif + * @return ERR_OK if the loopif is initialized + * ERR_MEM if private data couldn't be allocated + * any other err_t on error + */ +err_t +ethernetif_init(struct netif *netif) +{ + struct ethernetif *ethernetif; + + LWIP_ASSERT("netif != NULL", (netif != NULL)); + + ethernetif = mem_malloc(sizeof(struct ethernetif)); + if (ethernetif == NULL) { + LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_init: out of memory\n")); + return ERR_MEM; + } + +#if LWIP_NETIF_HOSTNAME + /* Initialize interface hostname */ + netif->hostname = "lwip"; +#endif /* LWIP_NETIF_HOSTNAME */ + + /* + * Initialize the snmp variables and counters inside the struct netif. + * The last argument should be replaced with your link speed, in units + * of bits per second. + */ + NETIF_INIT_SNMP(netif, snmp_ifType_ethernet_csmacd, LINK_SPEED_OF_YOUR_NETIF_IN_BPS); + + netif->state = ethernetif; + netif->name[0] = IFNAME0; + netif->name[1] = IFNAME1; + /* We directly use etharp_output() here to save a function call. + * You can instead declare your own function an call etharp_output() + * from it if you have to do some checks before sending (e.g. if link + * is available...) */ + netif->output = etharp_output; + netif->linkoutput = low_level_output; + + ethernetif->ethaddr = (struct eth_addr *)&(netif->hwaddr[0]); + + /* initialize the hardware */ + low_level_init(netif); + + return ERR_OK; +} + +#endif /* 0 */ diff --git a/src/lwip-1.4.1/src/netif/ppp/auth.c b/src/lwip-1.4.1/src/netif/ppp/auth.c new file mode 100644 index 0000000..0fd87a3 --- /dev/null +++ b/src/lwip-1.4.1/src/netif/ppp/auth.c @@ -0,0 +1,1334 @@ +/***************************************************************************** +* auth.c - Network Authentication and Phase Control program file. +* +* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. +* Copyright (c) 1997 by Global Election Systems Inc. All rights reserved. +* +* The authors hereby grant permission to use, copy, modify, distribute, +* and license this software and its documentation for any purpose, provided +* that existing copyright notices are retained in all copies and that this +* notice and the following disclaimer are included verbatim in any +* distributions. No written agreement, license, or royalty fee is required +* for any of the authorized uses. +* +* THIS SOFTWARE IS PROVIDED BY THE 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 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. +* +****************************************************************************** +* REVISION HISTORY +* +* 03-01-01 Marc Boucher +* Ported to lwIP. +* 97-12-08 Guy Lancaster , Global Election Systems Inc. +* Ported from public pppd code. +*****************************************************************************/ +/* + * auth.c - PPP authentication and phase control. + * + * Copyright (c) 1993 The Australian National University. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by the Australian National University. The name of the University + * may not be used to endorse or promote products derived from this + * software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Copyright (c) 1989 Carnegie Mellon University. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by Carnegie Mellon University. The name of the + * University may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#include "lwip/opt.h" + +#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ + +#include "ppp_impl.h" +#include "pppdebug.h" + +#include "fsm.h" +#include "lcp.h" +#include "pap.h" +#include "chap.h" +#include "auth.h" +#include "ipcp.h" + +#if CBCP_SUPPORT +#include "cbcp.h" +#endif /* CBCP_SUPPORT */ + +#include "lwip/inet.h" + +#include + +#if 0 /* UNUSED */ +/* Bits in scan_authfile return value */ +#define NONWILD_SERVER 1 +#define NONWILD_CLIENT 2 + +#define ISWILD(word) (word[0] == '*' && word[1] == 0) +#endif /* UNUSED */ + +#if PAP_SUPPORT || CHAP_SUPPORT +/* The name by which the peer authenticated itself to us. */ +static char peer_authname[MAXNAMELEN]; +#endif /* PAP_SUPPORT || CHAP_SUPPORT */ + +/* Records which authentication operations haven't completed yet. */ +static int auth_pending[NUM_PPP]; + +/* Set if we have successfully called plogin() */ +static int logged_in; + +/* Set if we have run the /etc/ppp/auth-up script. */ +static int did_authup; /* @todo, we don't need this in lwip*/ + +/* List of addresses which the peer may use. */ +static struct wordlist *addresses[NUM_PPP]; + +#if 0 /* UNUSED */ +/* Wordlist giving addresses which the peer may use + without authenticating itself. */ +static struct wordlist *noauth_addrs; + +/* Extra options to apply, from the secrets file entry for the peer. */ +static struct wordlist *extra_options; +#endif /* UNUSED */ + +/* Number of network protocols which we have opened. */ +static int num_np_open; + +/* Number of network protocols which have come up. */ +static int num_np_up; + +#if PAP_SUPPORT || CHAP_SUPPORT +/* Set if we got the contents of passwd[] from the pap-secrets file. */ +static int passwd_from_file; +#endif /* PAP_SUPPORT || CHAP_SUPPORT */ + +#if 0 /* UNUSED */ +/* Set if we require authentication only because we have a default route. */ +static bool default_auth; + +/* Hook to enable a plugin to control the idle time limit */ +int (*idle_time_hook) __P((struct ppp_idle *)) = NULL; + +/* Hook for a plugin to say whether we can possibly authenticate any peer */ +int (*pap_check_hook) __P((void)) = NULL; + +/* Hook for a plugin to check the PAP user and password */ +int (*pap_auth_hook) __P((char *user, char *passwd, char **msgp, + struct wordlist **paddrs, + struct wordlist **popts)) = NULL; + +/* Hook for a plugin to know about the PAP user logout */ +void (*pap_logout_hook) __P((void)) = NULL; + +/* Hook for a plugin to get the PAP password for authenticating us */ +int (*pap_passwd_hook) __P((char *user, char *passwd)) = NULL; + +/* + * This is used to ensure that we don't start an auth-up/down + * script while one is already running. + */ +enum script_state { + s_down, + s_up +}; + +static enum script_state auth_state = s_down; +static enum script_state auth_script_state = s_down; +static pid_t auth_script_pid = 0; + +/* + * Option variables. + * lwip: some of these are present in the ppp_settings structure + */ +bool uselogin = 0; /* Use /etc/passwd for checking PAP */ +bool cryptpap = 0; /* Passwords in pap-secrets are encrypted */ +bool refuse_pap = 0; /* Don't wanna auth. ourselves with PAP */ +bool refuse_chap = 0; /* Don't wanna auth. ourselves with CHAP */ +bool usehostname = 0; /* Use hostname for our_name */ +bool auth_required = 0; /* Always require authentication from peer */ +bool allow_any_ip = 0; /* Allow peer to use any IP address */ +bool explicit_remote = 0; /* User specified explicit remote name */ +char remote_name[MAXNAMELEN]; /* Peer's name for authentication */ + +#endif /* UNUSED */ + +/* Bits in auth_pending[] */ +#define PAP_WITHPEER 1 +#define PAP_PEER 2 +#define CHAP_WITHPEER 4 +#define CHAP_PEER 8 + +/* @todo, move this somewhere */ +/* Used for storing a sequence of words. Usually malloced. */ +struct wordlist { + struct wordlist *next; + char word[1]; +}; + + +extern char *crypt (const char *, const char *); + +/* Prototypes for procedures local to this file. */ + +static void network_phase (int); +static void check_idle (void *); +static void connect_time_expired (void *); +#if 0 +static int plogin (char *, char *, char **, int *); +#endif +static void plogout (void); +static int null_login (int); +static int get_pap_passwd (int, char *, char *); +static int have_pap_secret (void); +static int have_chap_secret (char *, char *, u32_t); +static int ip_addr_check (u32_t, struct wordlist *); + +#if 0 /* PAP_SUPPORT || CHAP_SUPPORT */ +static int scan_authfile (FILE *, char *, char *, char *, + struct wordlist **, struct wordlist **, + char *); +static void free_wordlist (struct wordlist *); +static void auth_script (char *); +static void auth_script_done (void *); +static void set_allowed_addrs (int unit, struct wordlist *addrs); +static int some_ip_ok (struct wordlist *); +static int setupapfile (char **); +static int privgroup (char **); +static int set_noauth_addr (char **); +static void check_access (FILE *, char *); +#endif /* 0 */ /* PAP_SUPPORT || CHAP_SUPPORT */ + +#if 0 /* UNUSED */ +/* + * Authentication-related options. + */ +option_t auth_options[] = { + { "require-pap", o_bool, &lcp_wantoptions[0].neg_upap, + "Require PAP authentication from peer", 1, &auth_required }, + { "+pap", o_bool, &lcp_wantoptions[0].neg_upap, + "Require PAP authentication from peer", 1, &auth_required }, + { "refuse-pap", o_bool, &refuse_pap, + "Don't agree to auth to peer with PAP", 1 }, + { "-pap", o_bool, &refuse_pap, + "Don't allow PAP authentication with peer", 1 }, + { "require-chap", o_bool, &lcp_wantoptions[0].neg_chap, + "Require CHAP authentication from peer", 1, &auth_required }, + { "+chap", o_bool, &lcp_wantoptions[0].neg_chap, + "Require CHAP authentication from peer", 1, &auth_required }, + { "refuse-chap", o_bool, &refuse_chap, + "Don't agree to auth to peer with CHAP", 1 }, + { "-chap", o_bool, &refuse_chap, + "Don't allow CHAP authentication with peer", 1 }, + { "name", o_string, our_name, + "Set local name for authentication", + OPT_PRIV|OPT_STATIC, NULL, MAXNAMELEN }, + { "user", o_string, user, + "Set name for auth with peer", OPT_STATIC, NULL, MAXNAMELEN }, + { "usehostname", o_bool, &usehostname, + "Must use hostname for authentication", 1 }, + { "remotename", o_string, remote_name, + "Set remote name for authentication", OPT_STATIC, + &explicit_remote, MAXNAMELEN }, + { "auth", o_bool, &auth_required, + "Require authentication from peer", 1 }, + { "noauth", o_bool, &auth_required, + "Don't require peer to authenticate", OPT_PRIV, &allow_any_ip }, + { "login", o_bool, &uselogin, + "Use system password database for PAP", 1 }, + { "papcrypt", o_bool, &cryptpap, + "PAP passwords are encrypted", 1 }, + { "+ua", o_special, (void *)setupapfile, + "Get PAP user and password from file" }, + { "password", o_string, passwd, + "Password for authenticating us to the peer", OPT_STATIC, + NULL, MAXSECRETLEN }, + { "privgroup", o_special, (void *)privgroup, + "Allow group members to use privileged options", OPT_PRIV }, + { "allow-ip", o_special, (void *)set_noauth_addr, + "Set IP address(es) which can be used without authentication", + OPT_PRIV }, + { NULL } +}; +#endif /* UNUSED */ +#if 0 /* UNUSED */ +/* + * setupapfile - specifies UPAP info for authenticating with peer. + */ +static int +setupapfile(char **argv) +{ + FILE * ufile; + int l; + + lcp_allowoptions[0].neg_upap = 1; + + /* open user info file */ + seteuid(getuid()); + ufile = fopen(*argv, "r"); + seteuid(0); + if (ufile == NULL) { + option_error("unable to open user login data file %s", *argv); + return 0; + } + check_access(ufile, *argv); + + /* get username */ + if (fgets(user, MAXNAMELEN - 1, ufile) == NULL + || fgets(passwd, MAXSECRETLEN - 1, ufile) == NULL){ + option_error("unable to read user login data file %s", *argv); + return 0; + } + fclose(ufile); + + /* get rid of newlines */ + l = strlen(user); + if (l > 0 && user[l-1] == '\n') + user[l-1] = 0; + l = strlen(passwd); + if (l > 0 && passwd[l-1] == '\n') + passwd[l-1] = 0; + + return (1); +} +#endif /* UNUSED */ + +#if 0 /* UNUSED */ +/* + * privgroup - allow members of the group to have privileged access. + */ +static int +privgroup(char **argv) +{ + struct group *g; + int i; + + g = getgrnam(*argv); + if (g == 0) { + option_error("group %s is unknown", *argv); + return 0; + } + for (i = 0; i < ngroups; ++i) { + if (groups[i] == g->gr_gid) { + privileged = 1; + break; + } + } + return 1; +} +#endif + +#if 0 /* UNUSED */ +/* + * set_noauth_addr - set address(es) that can be used without authentication. + * Equivalent to specifying an entry like `"" * "" addr' in pap-secrets. + */ +static int +set_noauth_addr(char **argv) +{ + char *addr = *argv; + int l = strlen(addr); + struct wordlist *wp; + + wp = (struct wordlist *) malloc(sizeof(struct wordlist) + l + 1); + if (wp == NULL) + novm("allow-ip argument"); + wp->word = (char *) (wp + 1); + wp->next = noauth_addrs; + BCOPY(addr, wp->word, l); + noauth_addrs = wp; + return 1; +} +#endif /* UNUSED */ + +/* + * An Open on LCP has requested a change from Dead to Establish phase. + * Do what's necessary to bring the physical layer up. + */ +void +link_required(int unit) +{ + LWIP_UNUSED_ARG(unit); + + AUTHDEBUG(LOG_INFO, ("link_required: %d\n", unit)); +} + +/* + * LCP has terminated the link; go to the Dead phase and take the + * physical layer down. + */ +void +link_terminated(int unit) +{ + AUTHDEBUG(LOG_INFO, ("link_terminated: %d\n", unit)); + if (lcp_phase[unit] == PHASE_DEAD) { + return; + } + if (logged_in) { + plogout(); + } + lcp_phase[unit] = PHASE_DEAD; + AUTHDEBUG(LOG_NOTICE, ("Connection terminated.\n")); + pppLinkTerminated(unit); +} + +/* + * LCP has gone down; it will either die or try to re-establish. + */ +void +link_down(int unit) +{ + int i; + struct protent *protp; + + AUTHDEBUG(LOG_INFO, ("link_down: %d\n", unit)); + + if (did_authup) { + /* XXX Do link down processing. */ + did_authup = 0; + } + for (i = 0; (protp = ppp_protocols[i]) != NULL; ++i) { + if (!protp->enabled_flag) { + continue; + } + if (protp->protocol != PPP_LCP && protp->lowerdown != NULL) { + (*protp->lowerdown)(unit); + } + if (protp->protocol < 0xC000 && protp->close != NULL) { + (*protp->close)(unit, "LCP down"); + } + } + num_np_open = 0; /* number of network protocols we have opened */ + num_np_up = 0; /* Number of network protocols which have come up */ + + if (lcp_phase[unit] != PHASE_DEAD) { + lcp_phase[unit] = PHASE_TERMINATE; + } + pppLinkDown(unit); +} + +/* + * The link is established. + * Proceed to the Dead, Authenticate or Network phase as appropriate. + */ +void +link_established(int unit) +{ + int auth; + int i; + struct protent *protp; + lcp_options *wo = &lcp_wantoptions[unit]; + lcp_options *go = &lcp_gotoptions[unit]; +#if PAP_SUPPORT || CHAP_SUPPORT + lcp_options *ho = &lcp_hisoptions[unit]; +#endif /* PAP_SUPPORT || CHAP_SUPPORT */ + + AUTHDEBUG(LOG_INFO, ("link_established: unit %d; Lowering up all protocols...\n", unit)); + /* + * Tell higher-level protocols that LCP is up. + */ + for (i = 0; (protp = ppp_protocols[i]) != NULL; ++i) { + if (protp->protocol != PPP_LCP && protp->enabled_flag && protp->lowerup != NULL) { + (*protp->lowerup)(unit); + } + } + if (ppp_settings.auth_required && !(go->neg_chap || go->neg_upap)) { + /* + * We wanted the peer to authenticate itself, and it refused: + * treat it as though it authenticated with PAP using a username + * of "" and a password of "". If that's not OK, boot it out. + */ + if (!wo->neg_upap || !null_login(unit)) { + AUTHDEBUG(LOG_WARNING, ("peer refused to authenticate\n")); + lcp_close(unit, "peer refused to authenticate"); + return; + } + } + + lcp_phase[unit] = PHASE_AUTHENTICATE; + auth = 0; +#if CHAP_SUPPORT + if (go->neg_chap) { + ChapAuthPeer(unit, ppp_settings.our_name, go->chap_mdtype); + auth |= CHAP_PEER; + } +#endif /* CHAP_SUPPORT */ +#if PAP_SUPPORT && CHAP_SUPPORT + else +#endif /* PAP_SUPPORT && CHAP_SUPPORT */ +#if PAP_SUPPORT + if (go->neg_upap) { + upap_authpeer(unit); + auth |= PAP_PEER; + } +#endif /* PAP_SUPPORT */ +#if CHAP_SUPPORT + if (ho->neg_chap) { + ChapAuthWithPeer(unit, ppp_settings.user, ho->chap_mdtype); + auth |= CHAP_WITHPEER; + } +#endif /* CHAP_SUPPORT */ +#if PAP_SUPPORT && CHAP_SUPPORT + else +#endif /* PAP_SUPPORT && CHAP_SUPPORT */ +#if PAP_SUPPORT + if (ho->neg_upap) { + if (ppp_settings.passwd[0] == 0) { + passwd_from_file = 1; + if (!get_pap_passwd(unit, ppp_settings.user, ppp_settings.passwd)) { + AUTHDEBUG(LOG_ERR, ("No secret found for PAP login\n")); + } + } + upap_authwithpeer(unit, ppp_settings.user, ppp_settings.passwd); + auth |= PAP_WITHPEER; + } +#endif /* PAP_SUPPORT */ + auth_pending[unit] = auth; + + if (!auth) { + network_phase(unit); + } +} + +/* + * Proceed to the network phase. + */ +static void +network_phase(int unit) +{ + int i; + struct protent *protp; + lcp_options *go = &lcp_gotoptions[unit]; + + /* + * If the peer had to authenticate, run the auth-up script now. + */ + if ((go->neg_chap || go->neg_upap) && !did_authup) { + /* XXX Do setup for peer authentication. */ + did_authup = 1; + } + +#if CBCP_SUPPORT + /* + * If we negotiated callback, do it now. + */ + if (go->neg_cbcp) { + lcp_phase[unit] = PHASE_CALLBACK; + (*cbcp_protent.open)(unit); + return; + } +#endif /* CBCP_SUPPORT */ + + lcp_phase[unit] = PHASE_NETWORK; + for (i = 0; (protp = ppp_protocols[i]) != NULL; ++i) { + if (protp->protocol < 0xC000 && protp->enabled_flag && protp->open != NULL) { + (*protp->open)(unit); + if (protp->protocol != PPP_CCP) { + ++num_np_open; + } + } + } + + if (num_np_open == 0) { + /* nothing to do */ + lcp_close(0, "No network protocols running"); + } +} +/* @todo: add void start_networks(void) here (pppd 2.3.11) */ + +/* + * The peer has failed to authenticate himself using `protocol'. + */ +void +auth_peer_fail(int unit, u16_t protocol) +{ + LWIP_UNUSED_ARG(protocol); + + AUTHDEBUG(LOG_INFO, ("auth_peer_fail: %d proto=%X\n", unit, protocol)); + /* + * Authentication failure: take the link down + */ + lcp_close(unit, "Authentication failed"); +} + + +#if PAP_SUPPORT || CHAP_SUPPORT +/* + * The peer has been successfully authenticated using `protocol'. + */ +void +auth_peer_success(int unit, u16_t protocol, char *name, int namelen) +{ + int pbit; + + AUTHDEBUG(LOG_INFO, ("auth_peer_success: %d proto=%X\n", unit, protocol)); + switch (protocol) { + case PPP_CHAP: + pbit = CHAP_PEER; + break; + case PPP_PAP: + pbit = PAP_PEER; + break; + default: + AUTHDEBUG(LOG_WARNING, ("auth_peer_success: unknown protocol %x\n", protocol)); + return; + } + + /* + * Save the authenticated name of the peer for later. + */ + if (namelen > (int)sizeof(peer_authname) - 1) { + namelen = sizeof(peer_authname) - 1; + } + BCOPY(name, peer_authname, namelen); + peer_authname[namelen] = 0; + + /* + * If there is no more authentication still to be done, + * proceed to the network (or callback) phase. + */ + if ((auth_pending[unit] &= ~pbit) == 0) { + network_phase(unit); + } +} + +/* + * We have failed to authenticate ourselves to the peer using `protocol'. + */ +void +auth_withpeer_fail(int unit, u16_t protocol) +{ + int errCode = PPPERR_AUTHFAIL; + + LWIP_UNUSED_ARG(protocol); + + AUTHDEBUG(LOG_INFO, ("auth_withpeer_fail: %d proto=%X\n", unit, protocol)); + if (passwd_from_file) { + BZERO(ppp_settings.passwd, MAXSECRETLEN); + } + + /* + * We've failed to authenticate ourselves to our peer. + * He'll probably take the link down, and there's not much + * we can do except wait for that. + */ + pppIOCtl(unit, PPPCTLS_ERRCODE, &errCode); + lcp_close(unit, "Failed to authenticate ourselves to peer"); +} + +/* + * We have successfully authenticated ourselves with the peer using `protocol'. + */ +void +auth_withpeer_success(int unit, u16_t protocol) +{ + int pbit; + + AUTHDEBUG(LOG_INFO, ("auth_withpeer_success: %d proto=%X\n", unit, protocol)); + switch (protocol) { + case PPP_CHAP: + pbit = CHAP_WITHPEER; + break; + case PPP_PAP: + if (passwd_from_file) { + BZERO(ppp_settings.passwd, MAXSECRETLEN); + } + pbit = PAP_WITHPEER; + break; + default: + AUTHDEBUG(LOG_WARNING, ("auth_peer_success: unknown protocol %x\n", protocol)); + pbit = 0; + } + + /* + * If there is no more authentication still being done, + * proceed to the network (or callback) phase. + */ + if ((auth_pending[unit] &= ~pbit) == 0) { + network_phase(unit); + } +} +#endif /* PAP_SUPPORT || CHAP_SUPPORT */ + + +/* + * np_up - a network protocol has come up. + */ +void +np_up(int unit, u16_t proto) +{ + LWIP_UNUSED_ARG(unit); + LWIP_UNUSED_ARG(proto); + + AUTHDEBUG(LOG_INFO, ("np_up: %d proto=%X\n", unit, proto)); + if (num_np_up == 0) { + AUTHDEBUG(LOG_INFO, ("np_up: maxconnect=%d idle_time_limit=%d\n",ppp_settings.maxconnect,ppp_settings.idle_time_limit)); + /* + * At this point we consider that the link has come up successfully. + */ + if (ppp_settings.idle_time_limit > 0) { + TIMEOUT(check_idle, NULL, ppp_settings.idle_time_limit); + } + + /* + * Set a timeout to close the connection once the maximum + * connect time has expired. + */ + if (ppp_settings.maxconnect > 0) { + TIMEOUT(connect_time_expired, 0, ppp_settings.maxconnect); + } + } + ++num_np_up; +} + +/* + * np_down - a network protocol has gone down. + */ +void +np_down(int unit, u16_t proto) +{ + LWIP_UNUSED_ARG(unit); + LWIP_UNUSED_ARG(proto); + + AUTHDEBUG(LOG_INFO, ("np_down: %d proto=%X\n", unit, proto)); + if (--num_np_up == 0 && ppp_settings.idle_time_limit > 0) { + UNTIMEOUT(check_idle, NULL); + } +} + +/* + * np_finished - a network protocol has finished using the link. + */ +void +np_finished(int unit, u16_t proto) +{ + LWIP_UNUSED_ARG(unit); + LWIP_UNUSED_ARG(proto); + + AUTHDEBUG(LOG_INFO, ("np_finished: %d proto=%X\n", unit, proto)); + if (--num_np_open <= 0) { + /* no further use for the link: shut up shop. */ + lcp_close(0, "No network protocols running"); + } +} + +/* + * check_idle - check whether the link has been idle for long + * enough that we can shut it down. + */ +static void +check_idle(void *arg) +{ + struct ppp_idle idle; + u_short itime; + + LWIP_UNUSED_ARG(arg); + if (!get_idle_time(0, &idle)) { + return; + } + itime = LWIP_MIN(idle.xmit_idle, idle.recv_idle); + if (itime >= ppp_settings.idle_time_limit) { + /* link is idle: shut it down. */ + AUTHDEBUG(LOG_INFO, ("Terminating connection due to lack of activity.\n")); + lcp_close(0, "Link inactive"); + } else { + TIMEOUT(check_idle, NULL, ppp_settings.idle_time_limit - itime); + } +} + +/* + * connect_time_expired - log a message and close the connection. + */ +static void +connect_time_expired(void *arg) +{ + LWIP_UNUSED_ARG(arg); + + AUTHDEBUG(LOG_INFO, ("Connect time expired\n")); + lcp_close(0, "Connect time expired"); /* Close connection */ +} + +#if 0 /* UNUSED */ +/* + * auth_check_options - called to check authentication options. + */ +void +auth_check_options(void) +{ + lcp_options *wo = &lcp_wantoptions[0]; + int can_auth; + ipcp_options *ipwo = &ipcp_wantoptions[0]; + u32_t remote; + + /* Default our_name to hostname, and user to our_name */ + if (ppp_settings.our_name[0] == 0 || ppp_settings.usehostname) { + strcpy(ppp_settings.our_name, ppp_settings.hostname); + } + + if (ppp_settings.user[0] == 0) { + strcpy(ppp_settings.user, ppp_settings.our_name); + } + + /* If authentication is required, ask peer for CHAP or PAP. */ + if (ppp_settings.auth_required && !wo->neg_chap && !wo->neg_upap) { + wo->neg_chap = 1; + wo->neg_upap = 1; + } + + /* + * Check whether we have appropriate secrets to use + * to authenticate the peer. + */ + can_auth = wo->neg_upap && have_pap_secret(); + if (!can_auth && wo->neg_chap) { + remote = ipwo->accept_remote? 0: ipwo->hisaddr; + can_auth = have_chap_secret(ppp_settings.remote_name, ppp_settings.our_name, remote); + } + + if (ppp_settings.auth_required && !can_auth) { + ppp_panic("No auth secret"); + } +} +#endif /* UNUSED */ + +/* + * auth_reset - called when LCP is starting negotiations to recheck + * authentication options, i.e. whether we have appropriate secrets + * to use for authenticating ourselves and/or the peer. + */ +void +auth_reset(int unit) +{ + lcp_options *go = &lcp_gotoptions[unit]; + lcp_options *ao = &lcp_allowoptions[0]; + ipcp_options *ipwo = &ipcp_wantoptions[0]; + u32_t remote; + + AUTHDEBUG(LOG_INFO, ("auth_reset: %d\n", unit)); + ao->neg_upap = !ppp_settings.refuse_pap && (ppp_settings.passwd[0] != 0 || get_pap_passwd(unit, NULL, NULL)); + ao->neg_chap = !ppp_settings.refuse_chap && ppp_settings.passwd[0] != 0 /*have_chap_secret(ppp_settings.user, ppp_settings.remote_name, (u32_t)0)*/; + + if (go->neg_upap && !have_pap_secret()) { + go->neg_upap = 0; + } + if (go->neg_chap) { + remote = ipwo->accept_remote? 0: ipwo->hisaddr; + if (!have_chap_secret(ppp_settings.remote_name, ppp_settings.our_name, remote)) { + go->neg_chap = 0; + } + } +} + +#if PAP_SUPPORT +/* + * check_passwd - Check the user name and passwd against the PAP secrets + * file. If requested, also check against the system password database, + * and login the user if OK. + * + * returns: + * UPAP_AUTHNAK: Authentication failed. + * UPAP_AUTHACK: Authentication succeeded. + * In either case, msg points to an appropriate message. + */ +u_char +check_passwd( int unit, char *auser, int userlen, char *apasswd, int passwdlen, char **msg, int *msglen) +{ +#if 1 /* XXX Assume all entries OK. */ + LWIP_UNUSED_ARG(unit); + LWIP_UNUSED_ARG(auser); + LWIP_UNUSED_ARG(userlen); + LWIP_UNUSED_ARG(apasswd); + LWIP_UNUSED_ARG(passwdlen); + LWIP_UNUSED_ARG(msglen); + *msg = (char *) 0; + return UPAP_AUTHACK; /* XXX Assume all entries OK. */ +#else + u_char ret = 0; + struct wordlist *addrs = NULL; + char passwd[256], user[256]; + char secret[MAXWORDLEN]; + static u_short attempts = 0; + + /* + * Make copies of apasswd and auser, then null-terminate them. + */ + BCOPY(apasswd, passwd, passwdlen); + passwd[passwdlen] = '\0'; + BCOPY(auser, user, userlen); + user[userlen] = '\0'; + *msg = (char *) 0; + + /* XXX Validate user name and password. */ + ret = UPAP_AUTHACK; /* XXX Assume all entries OK. */ + + if (ret == UPAP_AUTHNAK) { + if (*msg == (char *) 0) { + *msg = "Login incorrect"; + } + *msglen = strlen(*msg); + /* + * Frustrate passwd stealer programs. + * Allow 10 tries, but start backing off after 3 (stolen from login). + * On 10'th, drop the connection. + */ + if (attempts++ >= 10) { + AUTHDEBUG(LOG_WARNING, ("%d LOGIN FAILURES BY %s\n", attempts, user)); + /*ppp_panic("Excess Bad Logins");*/ + } + if (attempts > 3) { + /* @todo: this was sleep(), i.e. seconds, not milliseconds + * I don't think we really need this in lwIP - we would block tcpip_thread! + */ + /*sys_msleep((attempts - 3) * 5);*/ + } + if (addrs != NULL) { + free_wordlist(addrs); + } + } else { + attempts = 0; /* Reset count */ + if (*msg == (char *) 0) { + *msg = "Login ok"; + } + *msglen = strlen(*msg); + set_allowed_addrs(unit, addrs); + } + + BZERO(passwd, sizeof(passwd)); + BZERO(secret, sizeof(secret)); + + return ret; +#endif +} +#endif /* PAP_SUPPORT */ + +#if 0 /* UNUSED */ +/* + * This function is needed for PAM. + */ + +#ifdef USE_PAM + +/* lwip does not support PAM*/ + +#endif /* USE_PAM */ + +#endif /* UNUSED */ + + +#if 0 /* UNUSED */ +/* + * plogin - Check the user name and password against the system + * password database, and login the user if OK. + * + * returns: + * UPAP_AUTHNAK: Login failed. + * UPAP_AUTHACK: Login succeeded. + * In either case, msg points to an appropriate message. + */ +static int +plogin(char *user, char *passwd, char **msg, int *msglen) +{ + + LWIP_UNUSED_ARG(user); + LWIP_UNUSED_ARG(passwd); + LWIP_UNUSED_ARG(msg); + LWIP_UNUSED_ARG(msglen); + + + /* The new lines are here align the file when + * compared against the pppd 2.3.11 code */ + + + + + + + + + + + + + + + + + /* XXX Fail until we decide that we want to support logins. */ + return (UPAP_AUTHNAK); +} +#endif + + + +/* + * plogout - Logout the user. + */ +static void +plogout(void) +{ + logged_in = 0; +} + +/* + * null_login - Check if a username of "" and a password of "" are + * acceptable, and iff so, set the list of acceptable IP addresses + * and return 1. + */ +static int +null_login(int unit) +{ + LWIP_UNUSED_ARG(unit); + /* XXX Fail until we decide that we want to support logins. */ + return 0; +} + + +/* + * get_pap_passwd - get a password for authenticating ourselves with + * our peer using PAP. Returns 1 on success, 0 if no suitable password + * could be found. + */ +static int +get_pap_passwd(int unit, char *user, char *passwd) +{ + LWIP_UNUSED_ARG(unit); +/* normally we would reject PAP if no password is provided, + but this causes problems with some providers (like CHT in Taiwan) + who incorrectly request PAP and expect a bogus/empty password, so + always provide a default user/passwd of "none"/"none" + + @todo: This should be configured by the user, instead of being hardcoded here! +*/ + if(user) { + strcpy(user, "none"); + } + if(passwd) { + strcpy(passwd, "none"); + } + return 1; +} + +/* + * have_pap_secret - check whether we have a PAP file with any + * secrets that we could possibly use for authenticating the peer. + */ +static int +have_pap_secret(void) +{ + /* XXX Fail until we set up our passwords. */ + return 0; +} + +/* + * have_chap_secret - check whether we have a CHAP file with a + * secret that we could possibly use for authenticating `client' + * on `server'. Either can be the null string, meaning we don't + * know the identity yet. + */ +static int +have_chap_secret(char *client, char *server, u32_t remote) +{ + LWIP_UNUSED_ARG(client); + LWIP_UNUSED_ARG(server); + LWIP_UNUSED_ARG(remote); + + /* XXX Fail until we set up our passwords. */ + return 0; +} +#if CHAP_SUPPORT + +/* + * get_secret - open the CHAP secret file and return the secret + * for authenticating the given client on the given server. + * (We could be either client or server). + */ +int +get_secret(int unit, char *client, char *server, char *secret, int *secret_len, int save_addrs) +{ +#if 1 + int len; + struct wordlist *addrs; + + LWIP_UNUSED_ARG(unit); + LWIP_UNUSED_ARG(server); + LWIP_UNUSED_ARG(save_addrs); + + addrs = NULL; + + if(!client || !client[0] || strcmp(client, ppp_settings.user)) { + return 0; + } + + len = (int)strlen(ppp_settings.passwd); + if (len > MAXSECRETLEN) { + AUTHDEBUG(LOG_ERR, ("Secret for %s on %s is too long\n", client, server)); + len = MAXSECRETLEN; + } + + BCOPY(ppp_settings.passwd, secret, len); + *secret_len = len; + + return 1; +#else + int ret = 0, len; + struct wordlist *addrs; + char secbuf[MAXWORDLEN]; + + addrs = NULL; + secbuf[0] = 0; + + /* XXX Find secret. */ + if (ret < 0) { + return 0; + } + + if (save_addrs) { + set_allowed_addrs(unit, addrs); + } + + len = strlen(secbuf); + if (len > MAXSECRETLEN) { + AUTHDEBUG(LOG_ERR, ("Secret for %s on %s is too long\n", client, server)); + len = MAXSECRETLEN; + } + + BCOPY(secbuf, secret, len); + BZERO(secbuf, sizeof(secbuf)); + *secret_len = len; + + return 1; +#endif +} +#endif /* CHAP_SUPPORT */ + + +#if 0 /* PAP_SUPPORT || CHAP_SUPPORT */ +/* + * set_allowed_addrs() - set the list of allowed addresses. + */ +static void +set_allowed_addrs(int unit, struct wordlist *addrs) +{ + if (addresses[unit] != NULL) { + free_wordlist(addresses[unit]); + } + addresses[unit] = addrs; + +#if 0 + /* + * If there's only one authorized address we might as well + * ask our peer for that one right away + */ + if (addrs != NULL && addrs->next == NULL) { + char *p = addrs->word; + struct ipcp_options *wo = &ipcp_wantoptions[unit]; + u32_t a; + struct hostent *hp; + + if (wo->hisaddr == 0 && *p != '!' && *p != '-' && strchr(p, '/') == NULL) { + hp = gethostbyname(p); + if (hp != NULL && hp->h_addrtype == AF_INET) { + a = *(u32_t *)hp->h_addr; + } else { + a = inet_addr(p); + } + if (a != (u32_t) -1) { + wo->hisaddr = a; + } + } + } +#endif +} +#endif /* 0 */ /* PAP_SUPPORT || CHAP_SUPPORT */ + +/* + * auth_ip_addr - check whether the peer is authorized to use + * a given IP address. Returns 1 if authorized, 0 otherwise. + */ +int +auth_ip_addr(int unit, u32_t addr) +{ + return ip_addr_check(addr, addresses[unit]); +} + +static int /* @todo: integrate this funtion into auth_ip_addr()*/ +ip_addr_check(u32_t addr, struct wordlist *addrs) +{ + /* don't allow loopback or multicast address */ + if (bad_ip_adrs(addr)) { + return 0; + } + + if (addrs == NULL) { + return !ppp_settings.auth_required; /* no addresses authorized */ + } + + /* XXX All other addresses allowed. */ + return 1; +} + +/* + * bad_ip_adrs - return 1 if the IP address is one we don't want + * to use, such as an address in the loopback net or a multicast address. + * addr is in network byte order. + */ +int +bad_ip_adrs(u32_t addr) +{ + addr = ntohl(addr); + return (addr >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET + || IN_MULTICAST(addr) || IN_BADCLASS(addr); +} + +#if 0 /* UNUSED */ /* PAP_SUPPORT || CHAP_SUPPORT */ +/* + * some_ip_ok - check a wordlist to see if it authorizes any + * IP address(es). + */ +static int +some_ip_ok(struct wordlist *addrs) +{ + for (; addrs != 0; addrs = addrs->next) { + if (addrs->word[0] == '-') + break; + if (addrs->word[0] != '!') + return 1; /* some IP address is allowed */ + } + return 0; +} + +/* + * check_access - complain if a secret file has too-liberal permissions. + */ +static void +check_access(FILE *f, char *filename) +{ + struct stat sbuf; + + if (fstat(fileno(f), &sbuf) < 0) { + warn("cannot stat secret file %s: %m", filename); + } else if ((sbuf.st_mode & (S_IRWXG | S_IRWXO)) != 0) { + warn("Warning - secret file %s has world and/or group access", + filename); + } +} + + +/* + * scan_authfile - Scan an authorization file for a secret suitable + * for authenticating `client' on `server'. The return value is -1 + * if no secret is found, otherwise >= 0. The return value has + * NONWILD_CLIENT set if the secret didn't have "*" for the client, and + * NONWILD_SERVER set if the secret didn't have "*" for the server. + * Any following words on the line up to a "--" (i.e. address authorization + * info) are placed in a wordlist and returned in *addrs. Any + * following words (extra options) are placed in a wordlist and + * returned in *opts. + * We assume secret is NULL or points to MAXWORDLEN bytes of space. + */ +static int +scan_authfile(FILE *f, char *client, char *server, char *secret, struct wordlist **addrs, struct wordlist **opts, char *filename) +{ + /* We do not (currently) need this in lwip */ + return 0; /* dummy */ +} +/* + * free_wordlist - release memory allocated for a wordlist. + */ +static void +free_wordlist(struct wordlist *wp) +{ + struct wordlist *next; + + while (wp != NULL) { + next = wp->next; + free(wp); + wp = next; + } +} + +/* + * auth_script_done - called when the auth-up or auth-down script + * has finished. + */ +static void +auth_script_done(void *arg) +{ + auth_script_pid = 0; + switch (auth_script_state) { + case s_up: + if (auth_state == s_down) { + auth_script_state = s_down; + auth_script(_PATH_AUTHDOWN); + } + break; + case s_down: + if (auth_state == s_up) { + auth_script_state = s_up; + auth_script(_PATH_AUTHUP); + } + break; + } +} + +/* + * auth_script - execute a script with arguments + * interface-name peer-name real-user tty speed + */ +static void +auth_script(char *script) +{ + char strspeed[32]; + struct passwd *pw; + char struid[32]; + char *user_name; + char *argv[8]; + + if ((pw = getpwuid(getuid())) != NULL && pw->pw_name != NULL) + user_name = pw->pw_name; + else { + slprintf(struid, sizeof(struid), "%d", getuid()); + user_name = struid; + } + slprintf(strspeed, sizeof(strspeed), "%d", baud_rate); + + argv[0] = script; + argv[1] = ifname; + argv[2] = peer_authname; + argv[3] = user_name; + argv[4] = devnam; + argv[5] = strspeed; + argv[6] = NULL; + + auth_script_pid = run_program(script, argv, 0, auth_script_done, NULL); +} +#endif /* 0 */ /* PAP_SUPPORT || CHAP_SUPPORT */ +#endif /* PPP_SUPPORT */ diff --git a/src/lwip-1.4.1/src/netif/ppp/auth.h b/src/lwip-1.4.1/src/netif/ppp/auth.h new file mode 100644 index 0000000..a8069ec --- /dev/null +++ b/src/lwip-1.4.1/src/netif/ppp/auth.h @@ -0,0 +1,111 @@ +/***************************************************************************** +* auth.h - PPP Authentication and phase control header file. +* +* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. +* portions Copyright (c) 1998 Global Election Systems Inc. +* +* The authors hereby grant permission to use, copy, modify, distribute, +* and license this software and its documentation for any purpose, provided +* that existing copyright notices are retained in all copies and that this +* notice and the following disclaimer are included verbatim in any +* distributions. No written agreement, license, or royalty fee is required +* for any of the authorized uses. +* +* THIS SOFTWARE IS PROVIDED BY THE 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 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. +* +****************************************************************************** +* REVISION HISTORY +* +* 03-01-01 Marc Boucher +* Ported to lwIP. +* 97-12-04 Guy Lancaster , Global Election Systems Inc. +* Original derived from BSD pppd.h. +*****************************************************************************/ +/* + * pppd.h - PPP daemon global declarations. + * + * Copyright (c) 1989 Carnegie Mellon University. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by Carnegie Mellon University. The name of the + * University may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + */ + +#ifndef AUTH_H +#define AUTH_H + +/*********************** +*** PUBLIC FUNCTIONS *** +***********************/ + +/* we are starting to use the link */ +void link_required (int); + +/* we are finished with the link */ +void link_terminated (int); + +/* the LCP layer has left the Opened state */ +void link_down (int); + +/* the link is up; authenticate now */ +void link_established (int); + +/* a network protocol has come up */ +void np_up (int, u16_t); + +/* a network protocol has gone down */ +void np_down (int, u16_t); + +/* a network protocol no longer needs link */ +void np_finished (int, u16_t); + +/* peer failed to authenticate itself */ +void auth_peer_fail (int, u16_t); + +/* peer successfully authenticated itself */ +void auth_peer_success (int, u16_t, char *, int); + +/* we failed to authenticate ourselves */ +void auth_withpeer_fail (int, u16_t); + +/* we successfully authenticated ourselves */ +void auth_withpeer_success (int, u16_t); + +/* check authentication options supplied */ +void auth_check_options (void); + +/* check what secrets we have */ +void auth_reset (int); + +/* Check peer-supplied username/password */ +u_char check_passwd (int, char *, int, char *, int, char **, int *); + +/* get "secret" for chap */ +int get_secret (int, char *, char *, char *, int *, int); + +/* check if IP address is authorized */ +int auth_ip_addr (int, u32_t); + +/* check if IP address is unreasonable */ +int bad_ip_adrs (u32_t); + +#endif /* AUTH_H */ diff --git a/src/lwip-1.4.1/src/netif/ppp/chap.c b/src/lwip-1.4.1/src/netif/ppp/chap.c new file mode 100644 index 0000000..f10e27d --- /dev/null +++ b/src/lwip-1.4.1/src/netif/ppp/chap.c @@ -0,0 +1,908 @@ +/*** WARNING - THIS HAS NEVER BEEN FINISHED ***/ +/***************************************************************************** +* chap.c - Network Challenge Handshake Authentication Protocol program file. +* +* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. +* portions Copyright (c) 1997 by Global Election Systems Inc. +* +* The authors hereby grant permission to use, copy, modify, distribute, +* and license this software and its documentation for any purpose, provided +* that existing copyright notices are retained in all copies and that this +* notice and the following disclaimer are included verbatim in any +* distributions. No written agreement, license, or royalty fee is required +* for any of the authorized uses. +* +* THIS SOFTWARE IS PROVIDED BY THE 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 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. +* +****************************************************************************** +* REVISION HISTORY +* +* 03-01-01 Marc Boucher +* Ported to lwIP. +* 97-12-04 Guy Lancaster , Global Election Systems Inc. +* Original based on BSD chap.c. +*****************************************************************************/ +/* + * chap.c - Challenge Handshake Authentication Protocol. + * + * Copyright (c) 1993 The Australian National University. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by the Australian National University. The name of the University + * may not be used to endorse or promote products derived from this + * software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Copyright (c) 1991 Gregory M. Christy. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by Gregory M. Christy. The name of the author may not be used to + * endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#include "lwip/opt.h" + +#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ + +#if CHAP_SUPPORT /* don't build if not configured for use in lwipopts.h */ + +#include "ppp_impl.h" +#include "pppdebug.h" + +#include "magic.h" +#include "randm.h" +#include "auth.h" +#include "md5.h" +#include "chap.h" +#include "chpms.h" + +#include + +#if 0 /* UNUSED */ +/* + * Command-line options. + */ +static option_t chap_option_list[] = { + { "chap-restart", o_int, &chap[0].timeouttime, + "Set timeout for CHAP" }, + { "chap-max-challenge", o_int, &chap[0].max_transmits, + "Set max #xmits for challenge" }, + { "chap-interval", o_int, &chap[0].chal_interval, + "Set interval for rechallenge" }, +#ifdef MSLANMAN + { "ms-lanman", o_bool, &ms_lanman, + "Use LanMan passwd when using MS-CHAP", 1 }, +#endif + { NULL } +}; +#endif /* UNUSED */ + +/* + * Protocol entry points. + */ +static void ChapInit (int); +static void ChapLowerUp (int); +static void ChapLowerDown (int); +static void ChapInput (int, u_char *, int); +static void ChapProtocolReject (int); +#if PPP_ADDITIONAL_CALLBACKS +static int ChapPrintPkt (u_char *, int, void (*) (void *, char *, ...), void *); +#endif + +struct protent chap_protent = { + PPP_CHAP, + ChapInit, + ChapInput, + ChapProtocolReject, + ChapLowerUp, + ChapLowerDown, + NULL, + NULL, +#if PPP_ADDITIONAL_CALLBACKS + ChapPrintPkt, + NULL, +#endif /* PPP_ADDITIONAL_CALLBACKS */ + 1, + "CHAP", +#if PPP_ADDITIONAL_CALLBACKS + NULL, + NULL, + NULL +#endif /* PPP_ADDITIONAL_CALLBACKS */ +}; + +chap_state chap[NUM_PPP]; /* CHAP state; one for each unit */ + +static void ChapChallengeTimeout (void *); +static void ChapResponseTimeout (void *); +static void ChapReceiveChallenge (chap_state *, u_char *, u_char, int); +static void ChapRechallenge (void *); +static void ChapReceiveResponse (chap_state *, u_char *, int, int); +static void ChapReceiveSuccess(chap_state *cstate, u_char *inp, u_char id, int len); +static void ChapReceiveFailure(chap_state *cstate, u_char *inp, u_char id, int len); +static void ChapSendStatus (chap_state *, int); +static void ChapSendChallenge (chap_state *); +static void ChapSendResponse (chap_state *); +static void ChapGenChallenge (chap_state *); + +/* + * ChapInit - Initialize a CHAP unit. + */ +static void +ChapInit(int unit) +{ + chap_state *cstate = &chap[unit]; + + BZERO(cstate, sizeof(*cstate)); + cstate->unit = unit; + cstate->clientstate = CHAPCS_INITIAL; + cstate->serverstate = CHAPSS_INITIAL; + cstate->timeouttime = CHAP_DEFTIMEOUT; + cstate->max_transmits = CHAP_DEFTRANSMITS; + /* random number generator is initialized in magic_init */ +} + + +/* + * ChapAuthWithPeer - Authenticate us with our peer (start client). + * + */ +void +ChapAuthWithPeer(int unit, char *our_name, u_char digest) +{ + chap_state *cstate = &chap[unit]; + + cstate->resp_name = our_name; + cstate->resp_type = digest; + + if (cstate->clientstate == CHAPCS_INITIAL || + cstate->clientstate == CHAPCS_PENDING) { + /* lower layer isn't up - wait until later */ + cstate->clientstate = CHAPCS_PENDING; + return; + } + + /* + * We get here as a result of LCP coming up. + * So even if CHAP was open before, we will + * have to re-authenticate ourselves. + */ + cstate->clientstate = CHAPCS_LISTEN; +} + + +/* + * ChapAuthPeer - Authenticate our peer (start server). + */ +void +ChapAuthPeer(int unit, char *our_name, u_char digest) +{ + chap_state *cstate = &chap[unit]; + + cstate->chal_name = our_name; + cstate->chal_type = digest; + + if (cstate->serverstate == CHAPSS_INITIAL || + cstate->serverstate == CHAPSS_PENDING) { + /* lower layer isn't up - wait until later */ + cstate->serverstate = CHAPSS_PENDING; + return; + } + + ChapGenChallenge(cstate); + ChapSendChallenge(cstate); /* crank it up dude! */ + cstate->serverstate = CHAPSS_INITIAL_CHAL; +} + + +/* + * ChapChallengeTimeout - Timeout expired on sending challenge. + */ +static void +ChapChallengeTimeout(void *arg) +{ + chap_state *cstate = (chap_state *) arg; + + /* if we aren't sending challenges, don't worry. then again we */ + /* probably shouldn't be here either */ + if (cstate->serverstate != CHAPSS_INITIAL_CHAL && + cstate->serverstate != CHAPSS_RECHALLENGE) { + return; + } + + if (cstate->chal_transmits >= cstate->max_transmits) { + /* give up on peer */ + CHAPDEBUG(LOG_ERR, ("Peer failed to respond to CHAP challenge\n")); + cstate->serverstate = CHAPSS_BADAUTH; + auth_peer_fail(cstate->unit, PPP_CHAP); + return; + } + + ChapSendChallenge(cstate); /* Re-send challenge */ +} + + +/* + * ChapResponseTimeout - Timeout expired on sending response. + */ +static void +ChapResponseTimeout(void *arg) +{ + chap_state *cstate = (chap_state *) arg; + + /* if we aren't sending a response, don't worry. */ + if (cstate->clientstate != CHAPCS_RESPONSE) { + return; + } + + ChapSendResponse(cstate); /* re-send response */ +} + + +/* + * ChapRechallenge - Time to challenge the peer again. + */ +static void +ChapRechallenge(void *arg) +{ + chap_state *cstate = (chap_state *) arg; + + /* if we aren't sending a response, don't worry. */ + if (cstate->serverstate != CHAPSS_OPEN) { + return; + } + + ChapGenChallenge(cstate); + ChapSendChallenge(cstate); + cstate->serverstate = CHAPSS_RECHALLENGE; +} + + +/* + * ChapLowerUp - The lower layer is up. + * + * Start up if we have pending requests. + */ +static void +ChapLowerUp(int unit) +{ + chap_state *cstate = &chap[unit]; + + if (cstate->clientstate == CHAPCS_INITIAL) { + cstate->clientstate = CHAPCS_CLOSED; + } else if (cstate->clientstate == CHAPCS_PENDING) { + cstate->clientstate = CHAPCS_LISTEN; + } + + if (cstate->serverstate == CHAPSS_INITIAL) { + cstate->serverstate = CHAPSS_CLOSED; + } else if (cstate->serverstate == CHAPSS_PENDING) { + ChapGenChallenge(cstate); + ChapSendChallenge(cstate); + cstate->serverstate = CHAPSS_INITIAL_CHAL; + } +} + + +/* + * ChapLowerDown - The lower layer is down. + * + * Cancel all timeouts. + */ +static void +ChapLowerDown(int unit) +{ + chap_state *cstate = &chap[unit]; + + /* Timeout(s) pending? Cancel if so. */ + if (cstate->serverstate == CHAPSS_INITIAL_CHAL || + cstate->serverstate == CHAPSS_RECHALLENGE) { + UNTIMEOUT(ChapChallengeTimeout, cstate); + } else if (cstate->serverstate == CHAPSS_OPEN + && cstate->chal_interval != 0) { + UNTIMEOUT(ChapRechallenge, cstate); + } + if (cstate->clientstate == CHAPCS_RESPONSE) { + UNTIMEOUT(ChapResponseTimeout, cstate); + } + cstate->clientstate = CHAPCS_INITIAL; + cstate->serverstate = CHAPSS_INITIAL; +} + + +/* + * ChapProtocolReject - Peer doesn't grok CHAP. + */ +static void +ChapProtocolReject(int unit) +{ + chap_state *cstate = &chap[unit]; + + if (cstate->serverstate != CHAPSS_INITIAL && + cstate->serverstate != CHAPSS_CLOSED) { + auth_peer_fail(unit, PPP_CHAP); + } + if (cstate->clientstate != CHAPCS_INITIAL && + cstate->clientstate != CHAPCS_CLOSED) { + auth_withpeer_fail(unit, PPP_CHAP); /* lwip: just sets the PPP error code on this unit to PPPERR_AUTHFAIL */ + } + ChapLowerDown(unit); /* shutdown chap */ +} + + +/* + * ChapInput - Input CHAP packet. + */ +static void +ChapInput(int unit, u_char *inpacket, int packet_len) +{ + chap_state *cstate = &chap[unit]; + u_char *inp; + u_char code, id; + int len; + + /* + * Parse header (code, id and length). + * If packet too short, drop it. + */ + inp = inpacket; + if (packet_len < CHAP_HEADERLEN) { + CHAPDEBUG(LOG_INFO, ("ChapInput: rcvd short header.\n")); + return; + } + GETCHAR(code, inp); + GETCHAR(id, inp); + GETSHORT(len, inp); + if (len < CHAP_HEADERLEN) { + CHAPDEBUG(LOG_INFO, ("ChapInput: rcvd illegal length.\n")); + return; + } + if (len > packet_len) { + CHAPDEBUG(LOG_INFO, ("ChapInput: rcvd short packet.\n")); + return; + } + len -= CHAP_HEADERLEN; + + /* + * Action depends on code (as in fact it usually does :-). + */ + switch (code) { + case CHAP_CHALLENGE: + ChapReceiveChallenge(cstate, inp, id, len); + break; + + case CHAP_RESPONSE: + ChapReceiveResponse(cstate, inp, id, len); + break; + + case CHAP_FAILURE: + ChapReceiveFailure(cstate, inp, id, len); + break; + + case CHAP_SUCCESS: + ChapReceiveSuccess(cstate, inp, id, len); + break; + + default: /* Need code reject? */ + CHAPDEBUG(LOG_WARNING, ("Unknown CHAP code (%d) received.\n", code)); + break; + } +} + + +/* + * ChapReceiveChallenge - Receive Challenge and send Response. + */ +static void +ChapReceiveChallenge(chap_state *cstate, u_char *inp, u_char id, int len) +{ + int rchallenge_len; + u_char *rchallenge; + int secret_len; + char secret[MAXSECRETLEN]; + char rhostname[256]; + MD5_CTX mdContext; + u_char hash[MD5_SIGNATURE_SIZE]; + + CHAPDEBUG(LOG_INFO, ("ChapReceiveChallenge: Rcvd id %d.\n", id)); + if (cstate->clientstate == CHAPCS_CLOSED || + cstate->clientstate == CHAPCS_PENDING) { + CHAPDEBUG(LOG_INFO, ("ChapReceiveChallenge: in state %d\n", + cstate->clientstate)); + return; + } + + if (len < 2) { + CHAPDEBUG(LOG_INFO, ("ChapReceiveChallenge: rcvd short packet.\n")); + return; + } + + GETCHAR(rchallenge_len, inp); + len -= sizeof (u_char) + rchallenge_len; /* now name field length */ + if (len < 0) { + CHAPDEBUG(LOG_INFO, ("ChapReceiveChallenge: rcvd short packet.\n")); + return; + } + rchallenge = inp; + INCPTR(rchallenge_len, inp); + + if (len >= (int)sizeof(rhostname)) { + len = sizeof(rhostname) - 1; + } + BCOPY(inp, rhostname, len); + rhostname[len] = '\000'; + + CHAPDEBUG(LOG_INFO, ("ChapReceiveChallenge: received name field '%s'\n", + rhostname)); + + /* Microsoft doesn't send their name back in the PPP packet */ + if (ppp_settings.remote_name[0] != 0 && (ppp_settings.explicit_remote || rhostname[0] == 0)) { + strncpy(rhostname, ppp_settings.remote_name, sizeof(rhostname)); + rhostname[sizeof(rhostname) - 1] = 0; + CHAPDEBUG(LOG_INFO, ("ChapReceiveChallenge: using '%s' as remote name\n", + rhostname)); + } + + /* get secret for authenticating ourselves with the specified host */ + if (!get_secret(cstate->unit, cstate->resp_name, rhostname, + secret, &secret_len, 0)) { + secret_len = 0; /* assume null secret if can't find one */ + CHAPDEBUG(LOG_WARNING, ("No CHAP secret found for authenticating us to %s\n", + rhostname)); + } + + /* cancel response send timeout if necessary */ + if (cstate->clientstate == CHAPCS_RESPONSE) { + UNTIMEOUT(ChapResponseTimeout, cstate); + } + + cstate->resp_id = id; + cstate->resp_transmits = 0; + + /* generate MD based on negotiated type */ + switch (cstate->resp_type) { + + case CHAP_DIGEST_MD5: + MD5Init(&mdContext); + MD5Update(&mdContext, &cstate->resp_id, 1); + MD5Update(&mdContext, (u_char*)secret, secret_len); + MD5Update(&mdContext, rchallenge, rchallenge_len); + MD5Final(hash, &mdContext); + BCOPY(hash, cstate->response, MD5_SIGNATURE_SIZE); + cstate->resp_length = MD5_SIGNATURE_SIZE; + break; + +#if MSCHAP_SUPPORT + case CHAP_MICROSOFT: + ChapMS(cstate, rchallenge, rchallenge_len, secret, secret_len); + break; +#endif + + default: + CHAPDEBUG(LOG_INFO, ("unknown digest type %d\n", cstate->resp_type)); + return; + } + + BZERO(secret, sizeof(secret)); + ChapSendResponse(cstate); +} + + +/* + * ChapReceiveResponse - Receive and process response. + */ +static void +ChapReceiveResponse(chap_state *cstate, u_char *inp, int id, int len) +{ + u_char *remmd, remmd_len; + int secret_len, old_state; + int code; + char rhostname[256]; + MD5_CTX mdContext; + char secret[MAXSECRETLEN]; + u_char hash[MD5_SIGNATURE_SIZE]; + + CHAPDEBUG(LOG_INFO, ("ChapReceiveResponse: Rcvd id %d.\n", id)); + + if (cstate->serverstate == CHAPSS_CLOSED || + cstate->serverstate == CHAPSS_PENDING) { + CHAPDEBUG(LOG_INFO, ("ChapReceiveResponse: in state %d\n", + cstate->serverstate)); + return; + } + + if (id != cstate->chal_id) { + return; /* doesn't match ID of last challenge */ + } + + /* + * If we have received a duplicate or bogus Response, + * we have to send the same answer (Success/Failure) + * as we did for the first Response we saw. + */ + if (cstate->serverstate == CHAPSS_OPEN) { + ChapSendStatus(cstate, CHAP_SUCCESS); + return; + } + if (cstate->serverstate == CHAPSS_BADAUTH) { + ChapSendStatus(cstate, CHAP_FAILURE); + return; + } + + if (len < 2) { + CHAPDEBUG(LOG_INFO, ("ChapReceiveResponse: rcvd short packet.\n")); + return; + } + GETCHAR(remmd_len, inp); /* get length of MD */ + remmd = inp; /* get pointer to MD */ + INCPTR(remmd_len, inp); + + len -= sizeof (u_char) + remmd_len; + if (len < 0) { + CHAPDEBUG(LOG_INFO, ("ChapReceiveResponse: rcvd short packet.\n")); + return; + } + + UNTIMEOUT(ChapChallengeTimeout, cstate); + + if (len >= (int)sizeof(rhostname)) { + len = sizeof(rhostname) - 1; + } + BCOPY(inp, rhostname, len); + rhostname[len] = '\000'; + + CHAPDEBUG(LOG_INFO, ("ChapReceiveResponse: received name field: %s\n", + rhostname)); + + /* + * Get secret for authenticating them with us, + * do the hash ourselves, and compare the result. + */ + code = CHAP_FAILURE; + if (!get_secret(cstate->unit, rhostname, cstate->chal_name, + secret, &secret_len, 1)) { + CHAPDEBUG(LOG_WARNING, ("No CHAP secret found for authenticating %s\n", + rhostname)); + } else { + /* generate MD based on negotiated type */ + switch (cstate->chal_type) { + + case CHAP_DIGEST_MD5: /* only MD5 is defined for now */ + if (remmd_len != MD5_SIGNATURE_SIZE) { + break; /* it's not even the right length */ + } + MD5Init(&mdContext); + MD5Update(&mdContext, &cstate->chal_id, 1); + MD5Update(&mdContext, (u_char*)secret, secret_len); + MD5Update(&mdContext, cstate->challenge, cstate->chal_len); + MD5Final(hash, &mdContext); + + /* compare local and remote MDs and send the appropriate status */ + if (memcmp (hash, remmd, MD5_SIGNATURE_SIZE) == 0) { + code = CHAP_SUCCESS; /* they are the same! */ + } + break; + + default: + CHAPDEBUG(LOG_INFO, ("unknown digest type %d\n", cstate->chal_type)); + } + } + + BZERO(secret, sizeof(secret)); + ChapSendStatus(cstate, code); + + if (code == CHAP_SUCCESS) { + old_state = cstate->serverstate; + cstate->serverstate = CHAPSS_OPEN; + if (old_state == CHAPSS_INITIAL_CHAL) { + auth_peer_success(cstate->unit, PPP_CHAP, rhostname, len); + } + if (cstate->chal_interval != 0) { + TIMEOUT(ChapRechallenge, cstate, cstate->chal_interval); + } + } else { + CHAPDEBUG(LOG_ERR, ("CHAP peer authentication failed\n")); + cstate->serverstate = CHAPSS_BADAUTH; + auth_peer_fail(cstate->unit, PPP_CHAP); + } +} + +/* + * ChapReceiveSuccess - Receive Success + */ +static void +ChapReceiveSuccess(chap_state *cstate, u_char *inp, u_char id, int len) +{ + LWIP_UNUSED_ARG(id); + LWIP_UNUSED_ARG(inp); + + CHAPDEBUG(LOG_INFO, ("ChapReceiveSuccess: Rcvd id %d.\n", id)); + + if (cstate->clientstate == CHAPCS_OPEN) { + /* presumably an answer to a duplicate response */ + return; + } + + if (cstate->clientstate != CHAPCS_RESPONSE) { + /* don't know what this is */ + CHAPDEBUG(LOG_INFO, ("ChapReceiveSuccess: in state %d\n", + cstate->clientstate)); + return; + } + + UNTIMEOUT(ChapResponseTimeout, cstate); + + /* + * Print message. + */ + if (len > 0) { + PRINTMSG(inp, len); + } + + cstate->clientstate = CHAPCS_OPEN; + + auth_withpeer_success(cstate->unit, PPP_CHAP); +} + + +/* + * ChapReceiveFailure - Receive failure. + */ +static void +ChapReceiveFailure(chap_state *cstate, u_char *inp, u_char id, int len) +{ + LWIP_UNUSED_ARG(id); + LWIP_UNUSED_ARG(inp); + + CHAPDEBUG(LOG_INFO, ("ChapReceiveFailure: Rcvd id %d.\n", id)); + + if (cstate->clientstate != CHAPCS_RESPONSE) { + /* don't know what this is */ + CHAPDEBUG(LOG_INFO, ("ChapReceiveFailure: in state %d\n", + cstate->clientstate)); + return; + } + + UNTIMEOUT(ChapResponseTimeout, cstate); + + /* + * Print message. + */ + if (len > 0) { + PRINTMSG(inp, len); + } + + CHAPDEBUG(LOG_ERR, ("CHAP authentication failed\n")); + auth_withpeer_fail(cstate->unit, PPP_CHAP); /* lwip: just sets the PPP error code on this unit to PPPERR_AUTHFAIL */ +} + + +/* + * ChapSendChallenge - Send an Authenticate challenge. + */ +static void +ChapSendChallenge(chap_state *cstate) +{ + u_char *outp; + int chal_len, name_len; + int outlen; + + chal_len = cstate->chal_len; + name_len = (int)strlen(cstate->chal_name); + outlen = CHAP_HEADERLEN + sizeof (u_char) + chal_len + name_len; + outp = outpacket_buf[cstate->unit]; + + MAKEHEADER(outp, PPP_CHAP); /* paste in a CHAP header */ + + PUTCHAR(CHAP_CHALLENGE, outp); + PUTCHAR(cstate->chal_id, outp); + PUTSHORT(outlen, outp); + + PUTCHAR(chal_len, outp); /* put length of challenge */ + BCOPY(cstate->challenge, outp, chal_len); + INCPTR(chal_len, outp); + + BCOPY(cstate->chal_name, outp, name_len); /* append hostname */ + + pppWrite(cstate->unit, outpacket_buf[cstate->unit], outlen + PPP_HDRLEN); + + CHAPDEBUG(LOG_INFO, ("ChapSendChallenge: Sent id %d.\n", cstate->chal_id)); + + TIMEOUT(ChapChallengeTimeout, cstate, cstate->timeouttime); + ++cstate->chal_transmits; +} + + +/* + * ChapSendStatus - Send a status response (ack or nak). + */ +static void +ChapSendStatus(chap_state *cstate, int code) +{ + u_char *outp; + int outlen, msglen; + char msg[256]; /* @todo: this can be a char*, no strcpy needed */ + + if (code == CHAP_SUCCESS) { + strcpy(msg, "Welcome!"); + } else { + strcpy(msg, "I don't like you. Go 'way."); + } + msglen = (int)strlen(msg); + + outlen = CHAP_HEADERLEN + msglen; + outp = outpacket_buf[cstate->unit]; + + MAKEHEADER(outp, PPP_CHAP); /* paste in a header */ + + PUTCHAR(code, outp); + PUTCHAR(cstate->chal_id, outp); + PUTSHORT(outlen, outp); + BCOPY(msg, outp, msglen); + pppWrite(cstate->unit, outpacket_buf[cstate->unit], outlen + PPP_HDRLEN); + + CHAPDEBUG(LOG_INFO, ("ChapSendStatus: Sent code %d, id %d.\n", code, + cstate->chal_id)); +} + +/* + * ChapGenChallenge is used to generate a pseudo-random challenge string of + * a pseudo-random length between min_len and max_len. The challenge + * string and its length are stored in *cstate, and various other fields of + * *cstate are initialized. + */ + +static void +ChapGenChallenge(chap_state *cstate) +{ + int chal_len; + u_char *ptr = cstate->challenge; + int i; + + /* pick a random challenge length between MIN_CHALLENGE_LENGTH and + MAX_CHALLENGE_LENGTH */ + chal_len = (unsigned) + ((((magic() >> 16) * + (MAX_CHALLENGE_LENGTH - MIN_CHALLENGE_LENGTH)) >> 16) + + MIN_CHALLENGE_LENGTH); + LWIP_ASSERT("chal_len <= 0xff", chal_len <= 0xffff); + cstate->chal_len = (u_char)chal_len; + cstate->chal_id = ++cstate->id; + cstate->chal_transmits = 0; + + /* generate a random string */ + for (i = 0; i < chal_len; i++ ) { + *ptr++ = (char) (magic() & 0xff); + } +} + +/* + * ChapSendResponse - send a response packet with values as specified + * in *cstate. + */ +/* ARGSUSED */ +static void +ChapSendResponse(chap_state *cstate) +{ + u_char *outp; + int outlen, md_len, name_len; + + md_len = cstate->resp_length; + name_len = (int)strlen(cstate->resp_name); + outlen = CHAP_HEADERLEN + sizeof (u_char) + md_len + name_len; + outp = outpacket_buf[cstate->unit]; + + MAKEHEADER(outp, PPP_CHAP); + + PUTCHAR(CHAP_RESPONSE, outp); /* we are a response */ + PUTCHAR(cstate->resp_id, outp); /* copy id from challenge packet */ + PUTSHORT(outlen, outp); /* packet length */ + + PUTCHAR(md_len, outp); /* length of MD */ + BCOPY(cstate->response, outp, md_len); /* copy MD to buffer */ + INCPTR(md_len, outp); + + BCOPY(cstate->resp_name, outp, name_len); /* append our name */ + + /* send the packet */ + pppWrite(cstate->unit, outpacket_buf[cstate->unit], outlen + PPP_HDRLEN); + + cstate->clientstate = CHAPCS_RESPONSE; + TIMEOUT(ChapResponseTimeout, cstate, cstate->timeouttime); + ++cstate->resp_transmits; +} + +#if PPP_ADDITIONAL_CALLBACKS +static char *ChapCodenames[] = { + "Challenge", "Response", "Success", "Failure" +}; +/* + * ChapPrintPkt - print the contents of a CHAP packet. + */ +static int +ChapPrintPkt( u_char *p, int plen, void (*printer) (void *, char *, ...), void *arg) +{ + int code, id, len; + int clen, nlen; + u_char x; + + if (plen < CHAP_HEADERLEN) { + return 0; + } + GETCHAR(code, p); + GETCHAR(id, p); + GETSHORT(len, p); + if (len < CHAP_HEADERLEN || len > plen) { + return 0; + } + + if (code >= 1 && code <= sizeof(ChapCodenames) / sizeof(char *)) { + printer(arg, " %s", ChapCodenames[code-1]); + } else { + printer(arg, " code=0x%x", code); + } + printer(arg, " id=0x%x", id); + len -= CHAP_HEADERLEN; + switch (code) { + case CHAP_CHALLENGE: + case CHAP_RESPONSE: + if (len < 1) { + break; + } + clen = p[0]; + if (len < clen + 1) { + break; + } + ++p; + nlen = len - clen - 1; + printer(arg, " <"); + for (; clen > 0; --clen) { + GETCHAR(x, p); + printer(arg, "%.2x", x); + } + printer(arg, ">, name = %.*Z", nlen, p); + break; + case CHAP_FAILURE: + case CHAP_SUCCESS: + printer(arg, " %.*Z", len, p); + break; + default: + for (clen = len; clen > 0; --clen) { + GETCHAR(x, p); + printer(arg, " %.2x", x); + } + } + + return len + CHAP_HEADERLEN; +} +#endif /* PPP_ADDITIONAL_CALLBACKS */ + +#endif /* CHAP_SUPPORT */ + +#endif /* PPP_SUPPORT */ diff --git a/src/lwip-1.4.1/src/netif/ppp/chap.h b/src/lwip-1.4.1/src/netif/ppp/chap.h new file mode 100644 index 0000000..fedcab8 --- /dev/null +++ b/src/lwip-1.4.1/src/netif/ppp/chap.h @@ -0,0 +1,150 @@ +/***************************************************************************** +* chap.h - Network Challenge Handshake Authentication Protocol header file. +* +* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. +* portions Copyright (c) 1998 Global Election Systems Inc. +* +* The authors hereby grant permission to use, copy, modify, distribute, +* and license this software and its documentation for any purpose, provided +* that existing copyright notices are retained in all copies and that this +* notice and the following disclaimer are included verbatim in any +* distributions. No written agreement, license, or royalty fee is required +* for any of the authorized uses. +* +* THIS SOFTWARE IS PROVIDED BY THE 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 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. +* +****************************************************************************** +* REVISION HISTORY +* +* 03-01-01 Marc Boucher +* Ported to lwIP. +* 97-12-03 Guy Lancaster , Global Election Systems Inc. +* Original built from BSD network code. +******************************************************************************/ +/* + * chap.h - Challenge Handshake Authentication Protocol definitions. + * + * Copyright (c) 1993 The Australian National University. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by the Australian National University. The name of the University + * may not be used to endorse or promote products derived from this + * software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Copyright (c) 1991 Gregory M. Christy + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by the author. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * $Id: chap.h,v 1.6 2010/01/24 13:19:34 goldsimon Exp $ + */ + +#ifndef CHAP_H +#define CHAP_H + +/* Code + ID + length */ +#define CHAP_HEADERLEN 4 + +/* + * CHAP codes. + */ + +#define CHAP_DIGEST_MD5 5 /* use MD5 algorithm */ +#define MD5_SIGNATURE_SIZE 16 /* 16 bytes in a MD5 message digest */ +#define CHAP_MICROSOFT 0x80 /* use Microsoft-compatible alg. */ +#define MS_CHAP_RESPONSE_LEN 49 /* Response length for MS-CHAP */ + +#define CHAP_CHALLENGE 1 +#define CHAP_RESPONSE 2 +#define CHAP_SUCCESS 3 +#define CHAP_FAILURE 4 + +/* + * Challenge lengths (for challenges we send) and other limits. + */ +#define MIN_CHALLENGE_LENGTH 32 +#define MAX_CHALLENGE_LENGTH 64 +#define MAX_RESPONSE_LENGTH 64 /* sufficient for MD5 or MS-CHAP */ + +/* + * Each interface is described by a chap structure. + */ + +typedef struct chap_state { + int unit; /* Interface unit number */ + int clientstate; /* Client state */ + int serverstate; /* Server state */ + u_char challenge[MAX_CHALLENGE_LENGTH]; /* last challenge string sent */ + u_char chal_len; /* challenge length */ + u_char chal_id; /* ID of last challenge */ + u_char chal_type; /* hash algorithm for challenges */ + u_char id; /* Current id */ + char *chal_name; /* Our name to use with challenge */ + int chal_interval; /* Time until we challenge peer again */ + int timeouttime; /* Timeout time in seconds */ + int max_transmits; /* Maximum # of challenge transmissions */ + int chal_transmits; /* Number of transmissions of challenge */ + int resp_transmits; /* Number of transmissions of response */ + u_char response[MAX_RESPONSE_LENGTH]; /* Response to send */ + u_char resp_length; /* length of response */ + u_char resp_id; /* ID for response messages */ + u_char resp_type; /* hash algorithm for responses */ + char *resp_name; /* Our name to send with response */ +} chap_state; + + +/* + * Client (peer) states. + */ +#define CHAPCS_INITIAL 0 /* Lower layer down, not opened */ +#define CHAPCS_CLOSED 1 /* Lower layer up, not opened */ +#define CHAPCS_PENDING 2 /* Auth us to peer when lower up */ +#define CHAPCS_LISTEN 3 /* Listening for a challenge */ +#define CHAPCS_RESPONSE 4 /* Sent response, waiting for status */ +#define CHAPCS_OPEN 5 /* We've received Success */ + +/* + * Server (authenticator) states. + */ +#define CHAPSS_INITIAL 0 /* Lower layer down, not opened */ +#define CHAPSS_CLOSED 1 /* Lower layer up, not opened */ +#define CHAPSS_PENDING 2 /* Auth peer when lower up */ +#define CHAPSS_INITIAL_CHAL 3 /* We've sent the first challenge */ +#define CHAPSS_OPEN 4 /* We've sent a Success msg */ +#define CHAPSS_RECHALLENGE 5 /* We've sent another challenge */ +#define CHAPSS_BADAUTH 6 /* We've sent a Failure msg */ + +extern chap_state chap[]; + +void ChapAuthWithPeer (int, char *, u_char); +void ChapAuthPeer (int, char *, u_char); + +extern struct protent chap_protent; + +#endif /* CHAP_H */ diff --git a/src/lwip-1.4.1/src/netif/ppp/chpms.c b/src/lwip-1.4.1/src/netif/ppp/chpms.c new file mode 100644 index 0000000..81a887b --- /dev/null +++ b/src/lwip-1.4.1/src/netif/ppp/chpms.c @@ -0,0 +1,396 @@ +/*** WARNING - THIS CODE HAS NOT BEEN FINISHED! ***/ +/*** The original PPPD code is written in a way to require either the UNIX DES + encryption functions encrypt(3) and setkey(3) or the DES library libdes. + Since both is not included in lwIP, MSCHAP currently does not work! */ +/***************************************************************************** +* chpms.c - Network MicroSoft Challenge Handshake Authentication Protocol program file. +* +* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. +* Copyright (c) 1997 by Global Election Systems Inc. All rights reserved. +* +* The authors hereby grant permission to use, copy, modify, distribute, +* and license this software and its documentation for any purpose, provided +* that existing copyright notices are retained in all copies and that this +* notice and the following disclaimer are included verbatim in any +* distributions. No written agreement, license, or royalty fee is required +* for any of the authorized uses. +* +* THIS SOFTWARE IS PROVIDED BY THE 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 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. +* +****************************************************************************** +* REVISION HISTORY +* +* 03-01-01 Marc Boucher +* Ported to lwIP. +* 97-12-08 Guy Lancaster , Global Election Systems Inc. +* Original based on BSD chap_ms.c. +*****************************************************************************/ +/* + * chap_ms.c - Microsoft MS-CHAP compatible implementation. + * + * Copyright (c) 1995 Eric Rosenquist, Strata Software Limited. + * http://www.strataware.com/ + * + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by Eric Rosenquist. The name of the author may not be used to + * endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +/* + * Modifications by Lauri Pesonen / lpesonen@clinet.fi, april 1997 + * + * Implemented LANManager type password response to MS-CHAP challenges. + * Now pppd provides both NT style and LANMan style blocks, and the + * prefered is set by option "ms-lanman". Default is to use NT. + * The hash text (StdText) was taken from Win95 RASAPI32.DLL. + * + * You should also use DOMAIN\\USERNAME as described in README.MSCHAP80 + */ + +#define USE_CRYPT + +#include "lwip/opt.h" + +#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ + +#if MSCHAP_SUPPORT /* don't build if not configured for use in lwipopts.h */ + +#include "ppp_impl.h" +#include "pppdebug.h" + +#include "md4.h" +#ifndef USE_CRYPT +#include "des.h" +#endif +#include "chap.h" +#include "chpms.h" + +#include + + +/*************************/ +/*** LOCAL DEFINITIONS ***/ +/*************************/ + + +/************************/ +/*** LOCAL DATA TYPES ***/ +/************************/ +typedef struct { + u_char LANManResp[24]; + u_char NTResp[24]; + u_char UseNT; /* If 1, ignore the LANMan response field */ +} MS_ChapResponse; +/* We use MS_CHAP_RESPONSE_LEN, rather than sizeof(MS_ChapResponse), + in case this struct gets padded. */ + + + +/***********************************/ +/*** LOCAL FUNCTION DECLARATIONS ***/ +/***********************************/ + +/* XXX Don't know what to do with these. */ +extern void setkey(const char *); +extern void encrypt(char *, int); + +static void DesEncrypt (u_char *, u_char *, u_char *); +static void MakeKey (u_char *, u_char *); + +#ifdef USE_CRYPT +static void Expand (u_char *, u_char *); +static void Collapse (u_char *, u_char *); +#endif + +static void ChallengeResponse( + u_char *challenge, /* IN 8 octets */ + u_char *pwHash, /* IN 16 octets */ + u_char *response /* OUT 24 octets */ +); +static void ChapMS_NT( + char *rchallenge, + int rchallenge_len, + char *secret, + int secret_len, + MS_ChapResponse *response +); +static u_char Get7Bits( + u_char *input, + int startBit +); + +static void +ChallengeResponse( u_char *challenge, /* IN 8 octets */ + u_char *pwHash, /* IN 16 octets */ + u_char *response /* OUT 24 octets */) +{ + u_char ZPasswordHash[21]; + + BZERO(ZPasswordHash, sizeof(ZPasswordHash)); + BCOPY(pwHash, ZPasswordHash, 16); + +#if 0 + log_packet(ZPasswordHash, sizeof(ZPasswordHash), "ChallengeResponse - ZPasswordHash", LOG_DEBUG); +#endif + + DesEncrypt(challenge, ZPasswordHash + 0, response + 0); + DesEncrypt(challenge, ZPasswordHash + 7, response + 8); + DesEncrypt(challenge, ZPasswordHash + 14, response + 16); + +#if 0 + log_packet(response, 24, "ChallengeResponse - response", LOG_DEBUG); +#endif +} + + +#ifdef USE_CRYPT +static void +DesEncrypt( u_char *clear, /* IN 8 octets */ + u_char *key, /* IN 7 octets */ + u_char *cipher /* OUT 8 octets */) +{ + u_char des_key[8]; + u_char crypt_key[66]; + u_char des_input[66]; + + MakeKey(key, des_key); + + Expand(des_key, crypt_key); + setkey((char*)crypt_key); + +#if 0 + CHAPDEBUG(LOG_INFO, ("DesEncrypt: 8 octet input : %02X%02X%02X%02X%02X%02X%02X%02X\n", + clear[0], clear[1], clear[2], clear[3], clear[4], clear[5], clear[6], clear[7])); +#endif + + Expand(clear, des_input); + encrypt((char*)des_input, 0); + Collapse(des_input, cipher); + +#if 0 + CHAPDEBUG(LOG_INFO, ("DesEncrypt: 8 octet output: %02X%02X%02X%02X%02X%02X%02X%02X\n", + cipher[0], cipher[1], cipher[2], cipher[3], cipher[4], cipher[5], cipher[6], cipher[7])); +#endif +} + +#else /* USE_CRYPT */ + +static void +DesEncrypt( u_char *clear, /* IN 8 octets */ + u_char *key, /* IN 7 octets */ + u_char *cipher /* OUT 8 octets */) +{ + des_cblock des_key; + des_key_schedule key_schedule; + + MakeKey(key, des_key); + + des_set_key(&des_key, key_schedule); + +#if 0 + CHAPDEBUG(LOG_INFO, ("DesEncrypt: 8 octet input : %02X%02X%02X%02X%02X%02X%02X%02X\n", + clear[0], clear[1], clear[2], clear[3], clear[4], clear[5], clear[6], clear[7])); +#endif + + des_ecb_encrypt((des_cblock *)clear, (des_cblock *)cipher, key_schedule, 1); + +#if 0 + CHAPDEBUG(LOG_INFO, ("DesEncrypt: 8 octet output: %02X%02X%02X%02X%02X%02X%02X%02X\n", + cipher[0], cipher[1], cipher[2], cipher[3], cipher[4], cipher[5], cipher[6], cipher[7])); +#endif +} + +#endif /* USE_CRYPT */ + + +static u_char +Get7Bits( u_char *input, int startBit) +{ + register unsigned int word; + + word = (unsigned)input[startBit / 8] << 8; + word |= (unsigned)input[startBit / 8 + 1]; + + word >>= 15 - (startBit % 8 + 7); + + return word & 0xFE; +} + +#ifdef USE_CRYPT + +/* in == 8-byte string (expanded version of the 56-bit key) + * out == 64-byte string where each byte is either 1 or 0 + * Note that the low-order "bit" is always ignored by by setkey() + */ +static void +Expand(u_char *in, u_char *out) +{ + int j, c; + int i; + + for(i = 0; i < 64; in++){ + c = *in; + for(j = 7; j >= 0; j--) { + *out++ = (c >> j) & 01; + } + i += 8; + } +} + +/* The inverse of Expand + */ +static void +Collapse(u_char *in, u_char *out) +{ + int j; + int i; + unsigned int c; + + for (i = 0; i < 64; i += 8, out++) { + c = 0; + for (j = 7; j >= 0; j--, in++) { + c |= *in << j; + } + *out = c & 0xff; + } +} +#endif + +static void +MakeKey( u_char *key, /* IN 56 bit DES key missing parity bits */ + u_char *des_key /* OUT 64 bit DES key with parity bits added */) +{ + des_key[0] = Get7Bits(key, 0); + des_key[1] = Get7Bits(key, 7); + des_key[2] = Get7Bits(key, 14); + des_key[3] = Get7Bits(key, 21); + des_key[4] = Get7Bits(key, 28); + des_key[5] = Get7Bits(key, 35); + des_key[6] = Get7Bits(key, 42); + des_key[7] = Get7Bits(key, 49); + +#ifndef USE_CRYPT + des_set_odd_parity((des_cblock *)des_key); +#endif + +#if 0 + CHAPDEBUG(LOG_INFO, ("MakeKey: 56-bit input : %02X%02X%02X%02X%02X%02X%02X\n", + key[0], key[1], key[2], key[3], key[4], key[5], key[6])); + CHAPDEBUG(LOG_INFO, ("MakeKey: 64-bit output: %02X%02X%02X%02X%02X%02X%02X%02X\n", + des_key[0], des_key[1], des_key[2], des_key[3], des_key[4], des_key[5], des_key[6], des_key[7])); +#endif +} + +static void +ChapMS_NT( char *rchallenge, + int rchallenge_len, + char *secret, + int secret_len, + MS_ChapResponse *response) +{ + int i; + MDstruct md4Context; + u_char unicodePassword[MAX_NT_PASSWORD * 2]; + static int low_byte_first = -1; + + LWIP_UNUSED_ARG(rchallenge_len); + + /* Initialize the Unicode version of the secret (== password). */ + /* This implicitly supports 8-bit ISO8859/1 characters. */ + BZERO(unicodePassword, sizeof(unicodePassword)); + for (i = 0; i < secret_len; i++) { + unicodePassword[i * 2] = (u_char)secret[i]; + } + MDbegin(&md4Context); + MDupdate(&md4Context, unicodePassword, secret_len * 2 * 8); /* Unicode is 2 bytes/char, *8 for bit count */ + + if (low_byte_first == -1) { + low_byte_first = (PP_HTONS((unsigned short int)1) != 1); + } + if (low_byte_first == 0) { + /* @todo: arg type - u_long* or u_int* ? */ + MDreverse((unsigned int*)&md4Context); /* sfb 961105 */ + } + + MDupdate(&md4Context, NULL, 0); /* Tell MD4 we're done */ + + ChallengeResponse((u_char*)rchallenge, (u_char*)md4Context.buffer, response->NTResp); +} + +#ifdef MSLANMAN +static u_char *StdText = (u_char *)"KGS!@#$%"; /* key from rasapi32.dll */ + +static void +ChapMS_LANMan( char *rchallenge, + int rchallenge_len, + char *secret, + int secret_len, + MS_ChapResponse *response) +{ + int i; + u_char UcasePassword[MAX_NT_PASSWORD]; /* max is actually 14 */ + u_char PasswordHash[16]; + + /* LANMan password is case insensitive */ + BZERO(UcasePassword, sizeof(UcasePassword)); + for (i = 0; i < secret_len; i++) { + UcasePassword[i] = (u_char)toupper(secret[i]); + } + DesEncrypt( StdText, UcasePassword + 0, PasswordHash + 0 ); + DesEncrypt( StdText, UcasePassword + 7, PasswordHash + 8 ); + ChallengeResponse(rchallenge, PasswordHash, response->LANManResp); +} +#endif + +void +ChapMS( chap_state *cstate, char *rchallenge, int rchallenge_len, char *secret, int secret_len) +{ + MS_ChapResponse response; +#ifdef MSLANMAN + extern int ms_lanman; +#endif + +#if 0 + CHAPDEBUG(LOG_INFO, ("ChapMS: secret is '%.*s'\n", secret_len, secret)); +#endif + BZERO(&response, sizeof(response)); + + /* Calculate both always */ + ChapMS_NT(rchallenge, rchallenge_len, secret, secret_len, &response); + +#ifdef MSLANMAN + ChapMS_LANMan(rchallenge, rchallenge_len, secret, secret_len, &response); + + /* prefered method is set by option */ + response.UseNT = !ms_lanman; +#else + response.UseNT = 1; +#endif + + BCOPY(&response, cstate->response, MS_CHAP_RESPONSE_LEN); + cstate->resp_length = MS_CHAP_RESPONSE_LEN; +} + +#endif /* MSCHAP_SUPPORT */ + +#endif /* PPP_SUPPORT */ diff --git a/src/lwip-1.4.1/src/netif/ppp/chpms.h b/src/lwip-1.4.1/src/netif/ppp/chpms.h new file mode 100644 index 0000000..df070fb --- /dev/null +++ b/src/lwip-1.4.1/src/netif/ppp/chpms.h @@ -0,0 +1,64 @@ +/***************************************************************************** +* chpms.h - Network Microsoft Challenge Handshake Protocol header file. +* +* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. +* portions Copyright (c) 1998 Global Election Systems Inc. +* +* The authors hereby grant permission to use, copy, modify, distribute, +* and license this software and its documentation for any purpose, provided +* that existing copyright notices are retained in all copies and that this +* notice and the following disclaimer are included verbatim in any +* distributions. No written agreement, license, or royalty fee is required +* for any of the authorized uses. +* +* THIS SOFTWARE IS PROVIDED BY THE 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 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. +* +****************************************************************************** +* REVISION HISTORY +* +* 03-01-01 Marc Boucher +* Ported to lwIP. +* 98-01-30 Guy Lancaster , Global Election Systems Inc. +* Original built from BSD network code. +******************************************************************************/ +/* + * chap.h - Challenge Handshake Authentication Protocol definitions. + * + * Copyright (c) 1995 Eric Rosenquist, Strata Software Limited. + * http://www.strataware.com/ + * + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by Eric Rosenquist. The name of the author may not be used to + * endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * $Id: chpms.h,v 1.5 2007/12/19 20:47:23 fbernon Exp $ + */ + +#ifndef CHPMS_H +#define CHPMS_H + +#define MAX_NT_PASSWORD 256 /* Maximum number of (Unicode) chars in an NT password */ + +void ChapMS (chap_state *, char *, int, char *, int); + +#endif /* CHPMS_H */ diff --git a/src/lwip-1.4.1/src/netif/ppp/fsm.c b/src/lwip-1.4.1/src/netif/ppp/fsm.c new file mode 100644 index 0000000..e8a254e --- /dev/null +++ b/src/lwip-1.4.1/src/netif/ppp/fsm.c @@ -0,0 +1,890 @@ +/***************************************************************************** +* fsm.c - Network Control Protocol Finite State Machine program file. +* +* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. +* portions Copyright (c) 1997 by Global Election Systems Inc. +* +* The authors hereby grant permission to use, copy, modify, distribute, +* and license this software and its documentation for any purpose, provided +* that existing copyright notices are retained in all copies and that this +* notice and the following disclaimer are included verbatim in any +* distributions. No written agreement, license, or royalty fee is required +* for any of the authorized uses. +* +* THIS SOFTWARE IS PROVIDED BY THE 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 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. +* +****************************************************************************** +* REVISION HISTORY +* +* 03-01-01 Marc Boucher +* Ported to lwIP. +* 97-12-01 Guy Lancaster , Global Election Systems Inc. +* Original based on BSD fsm.c. +*****************************************************************************/ +/* + * fsm.c - {Link, IP} Control Protocol Finite State Machine. + * + * Copyright (c) 1989 Carnegie Mellon University. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by Carnegie Mellon University. The name of the + * University may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +/* + * TODO: + * Randomize fsm id on link/init. + * Deal with variable outgoing MTU. + */ + +#include "lwip/opt.h" + +#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ + +#include "ppp_impl.h" +#include "pppdebug.h" + +#include "fsm.h" + +#include + +#if PPP_DEBUG +static const char *ppperr_strerr[] = { + "LS_INITIAL", /* LS_INITIAL 0 */ + "LS_STARTING", /* LS_STARTING 1 */ + "LS_CLOSED", /* LS_CLOSED 2 */ + "LS_STOPPED", /* LS_STOPPED 3 */ + "LS_CLOSING", /* LS_CLOSING 4 */ + "LS_STOPPING", /* LS_STOPPING 5 */ + "LS_REQSENT", /* LS_REQSENT 6 */ + "LS_ACKRCVD", /* LS_ACKRCVD 7 */ + "LS_ACKSENT", /* LS_ACKSENT 8 */ + "LS_OPENED" /* LS_OPENED 9 */ +}; +#endif /* PPP_DEBUG */ + +static void fsm_timeout (void *); +static void fsm_rconfreq (fsm *, u_char, u_char *, int); +static void fsm_rconfack (fsm *, int, u_char *, int); +static void fsm_rconfnakrej (fsm *, int, int, u_char *, int); +static void fsm_rtermreq (fsm *, int, u_char *, int); +static void fsm_rtermack (fsm *); +static void fsm_rcoderej (fsm *, u_char *, int); +static void fsm_sconfreq (fsm *, int); + +#define PROTO_NAME(f) ((f)->callbacks->proto_name) + +int peer_mru[NUM_PPP]; + + +/* + * fsm_init - Initialize fsm. + * + * Initialize fsm state. + */ +void +fsm_init(fsm *f) +{ + f->state = LS_INITIAL; + f->flags = 0; + f->id = 0; /* XXX Start with random id? */ + f->timeouttime = FSM_DEFTIMEOUT; + f->maxconfreqtransmits = FSM_DEFMAXCONFREQS; + f->maxtermtransmits = FSM_DEFMAXTERMREQS; + f->maxnakloops = FSM_DEFMAXNAKLOOPS; + f->term_reason_len = 0; +} + + +/* + * fsm_lowerup - The lower layer is up. + */ +void +fsm_lowerup(fsm *f) +{ + int oldState = f->state; + + LWIP_UNUSED_ARG(oldState); + + switch( f->state ) { + case LS_INITIAL: + f->state = LS_CLOSED; + break; + + case LS_STARTING: + if( f->flags & OPT_SILENT ) { + f->state = LS_STOPPED; + } else { + /* Send an initial configure-request */ + fsm_sconfreq(f, 0); + f->state = LS_REQSENT; + } + break; + + default: + FSMDEBUG(LOG_INFO, ("%s: Up event in state %d (%s)!\n", + PROTO_NAME(f), f->state, ppperr_strerr[f->state])); + } + + FSMDEBUG(LOG_INFO, ("%s: lowerup state %d (%s) -> %d (%s)\n", + PROTO_NAME(f), oldState, ppperr_strerr[oldState], f->state, ppperr_strerr[f->state])); +} + + +/* + * fsm_lowerdown - The lower layer is down. + * + * Cancel all timeouts and inform upper layers. + */ +void +fsm_lowerdown(fsm *f) +{ + int oldState = f->state; + + LWIP_UNUSED_ARG(oldState); + + switch( f->state ) { + case LS_CLOSED: + f->state = LS_INITIAL; + break; + + case LS_STOPPED: + f->state = LS_STARTING; + if( f->callbacks->starting ) { + (*f->callbacks->starting)(f); + } + break; + + case LS_CLOSING: + f->state = LS_INITIAL; + UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ + break; + + case LS_STOPPING: + case LS_REQSENT: + case LS_ACKRCVD: + case LS_ACKSENT: + f->state = LS_STARTING; + UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ + break; + + case LS_OPENED: + if( f->callbacks->down ) { + (*f->callbacks->down)(f); + } + f->state = LS_STARTING; + break; + + default: + FSMDEBUG(LOG_INFO, ("%s: Down event in state %d (%s)!\n", + PROTO_NAME(f), f->state, ppperr_strerr[f->state])); + } + + FSMDEBUG(LOG_INFO, ("%s: lowerdown state %d (%s) -> %d (%s)\n", + PROTO_NAME(f), oldState, ppperr_strerr[oldState], f->state, ppperr_strerr[f->state])); +} + + +/* + * fsm_open - Link is allowed to come up. + */ +void +fsm_open(fsm *f) +{ + int oldState = f->state; + + LWIP_UNUSED_ARG(oldState); + + switch( f->state ) { + case LS_INITIAL: + f->state = LS_STARTING; + if( f->callbacks->starting ) { + (*f->callbacks->starting)(f); + } + break; + + case LS_CLOSED: + if( f->flags & OPT_SILENT ) { + f->state = LS_STOPPED; + } else { + /* Send an initial configure-request */ + fsm_sconfreq(f, 0); + f->state = LS_REQSENT; + } + break; + + case LS_CLOSING: + f->state = LS_STOPPING; + /* fall through */ + case LS_STOPPED: + case LS_OPENED: + if( f->flags & OPT_RESTART ) { + fsm_lowerdown(f); + fsm_lowerup(f); + } + break; + } + + FSMDEBUG(LOG_INFO, ("%s: open state %d (%s) -> %d (%s)\n", + PROTO_NAME(f), oldState, ppperr_strerr[oldState], f->state, ppperr_strerr[f->state])); +} + +#if 0 /* backport pppd 2.4.4b1; */ +/* + * terminate_layer - Start process of shutting down the FSM + * + * Cancel any timeout running, notify upper layers we're done, and + * send a terminate-request message as configured. + */ +static void +terminate_layer(fsm *f, int nextstate) +{ + /* @todo */ +} +#endif + +/* + * fsm_close - Start closing connection. + * + * Cancel timeouts and either initiate close or possibly go directly to + * the LS_CLOSED state. + */ +void +fsm_close(fsm *f, char *reason) +{ + int oldState = f->state; + + LWIP_UNUSED_ARG(oldState); + + f->term_reason = reason; + f->term_reason_len = (reason == NULL ? 0 : (int)strlen(reason)); + switch( f->state ) { + case LS_STARTING: + f->state = LS_INITIAL; + break; + case LS_STOPPED: + f->state = LS_CLOSED; + break; + case LS_STOPPING: + f->state = LS_CLOSING; + break; + + case LS_REQSENT: + case LS_ACKRCVD: + case LS_ACKSENT: + case LS_OPENED: + if( f->state != LS_OPENED ) { + UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ + } else if( f->callbacks->down ) { + (*f->callbacks->down)(f); /* Inform upper layers we're down */ + } + /* Init restart counter, send Terminate-Request */ + f->retransmits = f->maxtermtransmits; + fsm_sdata(f, TERMREQ, f->reqid = ++f->id, + (u_char *) f->term_reason, f->term_reason_len); + TIMEOUT(fsm_timeout, f, f->timeouttime); + --f->retransmits; + + f->state = LS_CLOSING; + break; + } + + FSMDEBUG(LOG_INFO, ("%s: close reason=%s state %d (%s) -> %d (%s)\n", + PROTO_NAME(f), reason, oldState, ppperr_strerr[oldState], f->state, ppperr_strerr[f->state])); +} + + +/* + * fsm_timeout - Timeout expired. + */ +static void +fsm_timeout(void *arg) +{ + fsm *f = (fsm *) arg; + + switch (f->state) { + case LS_CLOSING: + case LS_STOPPING: + if( f->retransmits <= 0 ) { + FSMDEBUG(LOG_WARNING, ("%s: timeout sending Terminate-Request state=%d (%s)\n", + PROTO_NAME(f), f->state, ppperr_strerr[f->state])); + /* + * We've waited for an ack long enough. Peer probably heard us. + */ + f->state = (f->state == LS_CLOSING)? LS_CLOSED: LS_STOPPED; + if( f->callbacks->finished ) { + (*f->callbacks->finished)(f); + } + } else { + FSMDEBUG(LOG_WARNING, ("%s: timeout resending Terminate-Requests state=%d (%s)\n", + PROTO_NAME(f), f->state, ppperr_strerr[f->state])); + /* Send Terminate-Request */ + fsm_sdata(f, TERMREQ, f->reqid = ++f->id, + (u_char *) f->term_reason, f->term_reason_len); + TIMEOUT(fsm_timeout, f, f->timeouttime); + --f->retransmits; + } + break; + + case LS_REQSENT: + case LS_ACKRCVD: + case LS_ACKSENT: + if (f->retransmits <= 0) { + FSMDEBUG(LOG_WARNING, ("%s: timeout sending Config-Requests state=%d (%s)\n", + PROTO_NAME(f), f->state, ppperr_strerr[f->state])); + f->state = LS_STOPPED; + if( (f->flags & OPT_PASSIVE) == 0 && f->callbacks->finished ) { + (*f->callbacks->finished)(f); + } + } else { + FSMDEBUG(LOG_WARNING, ("%s: timeout resending Config-Request state=%d (%s)\n", + PROTO_NAME(f), f->state, ppperr_strerr[f->state])); + /* Retransmit the configure-request */ + if (f->callbacks->retransmit) { + (*f->callbacks->retransmit)(f); + } + fsm_sconfreq(f, 1); /* Re-send Configure-Request */ + if( f->state == LS_ACKRCVD ) { + f->state = LS_REQSENT; + } + } + break; + + default: + FSMDEBUG(LOG_INFO, ("%s: UNHANDLED timeout event in state %d (%s)!\n", + PROTO_NAME(f), f->state, ppperr_strerr[f->state])); + } +} + + +/* + * fsm_input - Input packet. + */ +void +fsm_input(fsm *f, u_char *inpacket, int l) +{ + u_char *inp = inpacket; + u_char code, id; + int len; + + /* + * Parse header (code, id and length). + * If packet too short, drop it. + */ + if (l < HEADERLEN) { + FSMDEBUG(LOG_WARNING, ("fsm_input(%x): Rcvd short header.\n", + f->protocol)); + return; + } + GETCHAR(code, inp); + GETCHAR(id, inp); + GETSHORT(len, inp); + if (len < HEADERLEN) { + FSMDEBUG(LOG_INFO, ("fsm_input(%x): Rcvd illegal length.\n", + f->protocol)); + return; + } + if (len > l) { + FSMDEBUG(LOG_INFO, ("fsm_input(%x): Rcvd short packet.\n", + f->protocol)); + return; + } + len -= HEADERLEN; /* subtract header length */ + + if( f->state == LS_INITIAL || f->state == LS_STARTING ) { + FSMDEBUG(LOG_INFO, ("fsm_input(%x): Rcvd packet in state %d (%s).\n", + f->protocol, f->state, ppperr_strerr[f->state])); + return; + } + FSMDEBUG(LOG_INFO, ("fsm_input(%s):%d,%d,%d\n", PROTO_NAME(f), code, id, l)); + /* + * Action depends on code. + */ + switch (code) { + case CONFREQ: + fsm_rconfreq(f, id, inp, len); + break; + + case CONFACK: + fsm_rconfack(f, id, inp, len); + break; + + case CONFNAK: + case CONFREJ: + fsm_rconfnakrej(f, code, id, inp, len); + break; + + case TERMREQ: + fsm_rtermreq(f, id, inp, len); + break; + + case TERMACK: + fsm_rtermack(f); + break; + + case CODEREJ: + fsm_rcoderej(f, inp, len); + break; + + default: + FSMDEBUG(LOG_INFO, ("fsm_input(%s): default: \n", PROTO_NAME(f))); + if( !f->callbacks->extcode || + !(*f->callbacks->extcode)(f, code, id, inp, len) ) { + fsm_sdata(f, CODEREJ, ++f->id, inpacket, len + HEADERLEN); + } + break; + } +} + + +/* + * fsm_rconfreq - Receive Configure-Request. + */ +static void +fsm_rconfreq(fsm *f, u_char id, u_char *inp, int len) +{ + int code, reject_if_disagree; + + FSMDEBUG(LOG_INFO, ("fsm_rconfreq(%s): Rcvd id %d state=%d (%s)\n", + PROTO_NAME(f), id, f->state, ppperr_strerr[f->state])); + switch( f->state ) { + case LS_CLOSED: + /* Go away, we're closed */ + fsm_sdata(f, TERMACK, id, NULL, 0); + return; + case LS_CLOSING: + case LS_STOPPING: + return; + + case LS_OPENED: + /* Go down and restart negotiation */ + if( f->callbacks->down ) { + (*f->callbacks->down)(f); /* Inform upper layers */ + } + fsm_sconfreq(f, 0); /* Send initial Configure-Request */ + break; + + case LS_STOPPED: + /* Negotiation started by our peer */ + fsm_sconfreq(f, 0); /* Send initial Configure-Request */ + f->state = LS_REQSENT; + break; + } + + /* + * Pass the requested configuration options + * to protocol-specific code for checking. + */ + if (f->callbacks->reqci) { /* Check CI */ + reject_if_disagree = (f->nakloops >= f->maxnakloops); + code = (*f->callbacks->reqci)(f, inp, &len, reject_if_disagree); + } else if (len) { + code = CONFREJ; /* Reject all CI */ + } else { + code = CONFACK; + } + + /* send the Ack, Nak or Rej to the peer */ + fsm_sdata(f, (u_char)code, id, inp, len); + + if (code == CONFACK) { + if (f->state == LS_ACKRCVD) { + UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ + f->state = LS_OPENED; + if (f->callbacks->up) { + (*f->callbacks->up)(f); /* Inform upper layers */ + } + } else { + f->state = LS_ACKSENT; + } + f->nakloops = 0; + } else { + /* we sent CONFACK or CONFREJ */ + if (f->state != LS_ACKRCVD) { + f->state = LS_REQSENT; + } + if( code == CONFNAK ) { + ++f->nakloops; + } + } +} + + +/* + * fsm_rconfack - Receive Configure-Ack. + */ +static void +fsm_rconfack(fsm *f, int id, u_char *inp, int len) +{ + FSMDEBUG(LOG_INFO, ("fsm_rconfack(%s): Rcvd id %d state=%d (%s)\n", + PROTO_NAME(f), id, f->state, ppperr_strerr[f->state])); + + if (id != f->reqid || f->seen_ack) { /* Expected id? */ + return; /* Nope, toss... */ + } + if( !(f->callbacks->ackci? (*f->callbacks->ackci)(f, inp, len): (len == 0)) ) { + /* Ack is bad - ignore it */ + FSMDEBUG(LOG_INFO, ("%s: received bad Ack (length %d)\n", + PROTO_NAME(f), len)); + return; + } + f->seen_ack = 1; + + switch (f->state) { + case LS_CLOSED: + case LS_STOPPED: + fsm_sdata(f, TERMACK, (u_char)id, NULL, 0); + break; + + case LS_REQSENT: + f->state = LS_ACKRCVD; + f->retransmits = f->maxconfreqtransmits; + break; + + case LS_ACKRCVD: + /* Huh? an extra valid Ack? oh well... */ + UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ + fsm_sconfreq(f, 0); + f->state = LS_REQSENT; + break; + + case LS_ACKSENT: + UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ + f->state = LS_OPENED; + f->retransmits = f->maxconfreqtransmits; + if (f->callbacks->up) { + (*f->callbacks->up)(f); /* Inform upper layers */ + } + break; + + case LS_OPENED: + /* Go down and restart negotiation */ + if (f->callbacks->down) { + (*f->callbacks->down)(f); /* Inform upper layers */ + } + fsm_sconfreq(f, 0); /* Send initial Configure-Request */ + f->state = LS_REQSENT; + break; + } +} + + +/* + * fsm_rconfnakrej - Receive Configure-Nak or Configure-Reject. + */ +static void +fsm_rconfnakrej(fsm *f, int code, int id, u_char *inp, int len) +{ + int (*proc) (fsm *, u_char *, int); + int ret; + + FSMDEBUG(LOG_INFO, ("fsm_rconfnakrej(%s): Rcvd id %d state=%d (%s)\n", + PROTO_NAME(f), id, f->state, ppperr_strerr[f->state])); + + if (id != f->reqid || f->seen_ack) { /* Expected id? */ + return; /* Nope, toss... */ + } + proc = (code == CONFNAK)? f->callbacks->nakci: f->callbacks->rejci; + if (!proc || !((ret = proc(f, inp, len)))) { + /* Nak/reject is bad - ignore it */ + FSMDEBUG(LOG_INFO, ("%s: received bad %s (length %d)\n", + PROTO_NAME(f), (code==CONFNAK? "Nak": "reject"), len)); + return; + } + f->seen_ack = 1; + + switch (f->state) { + case LS_CLOSED: + case LS_STOPPED: + fsm_sdata(f, TERMACK, (u_char)id, NULL, 0); + break; + + case LS_REQSENT: + case LS_ACKSENT: + /* They didn't agree to what we wanted - try another request */ + UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ + if (ret < 0) { + f->state = LS_STOPPED; /* kludge for stopping CCP */ + } else { + fsm_sconfreq(f, 0); /* Send Configure-Request */ + } + break; + + case LS_ACKRCVD: + /* Got a Nak/reject when we had already had an Ack?? oh well... */ + UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ + fsm_sconfreq(f, 0); + f->state = LS_REQSENT; + break; + + case LS_OPENED: + /* Go down and restart negotiation */ + if (f->callbacks->down) { + (*f->callbacks->down)(f); /* Inform upper layers */ + } + fsm_sconfreq(f, 0); /* Send initial Configure-Request */ + f->state = LS_REQSENT; + break; + } +} + + +/* + * fsm_rtermreq - Receive Terminate-Req. + */ +static void +fsm_rtermreq(fsm *f, int id, u_char *p, int len) +{ + LWIP_UNUSED_ARG(p); + + FSMDEBUG(LOG_INFO, ("fsm_rtermreq(%s): Rcvd id %d state=%d (%s)\n", + PROTO_NAME(f), id, f->state, ppperr_strerr[f->state])); + + switch (f->state) { + case LS_ACKRCVD: + case LS_ACKSENT: + f->state = LS_REQSENT; /* Start over but keep trying */ + break; + + case LS_OPENED: + if (len > 0) { + FSMDEBUG(LOG_INFO, ("%s terminated by peer (%p)\n", PROTO_NAME(f), p)); + } else { + FSMDEBUG(LOG_INFO, ("%s terminated by peer\n", PROTO_NAME(f))); + } + if (f->callbacks->down) { + (*f->callbacks->down)(f); /* Inform upper layers */ + } + f->retransmits = 0; + f->state = LS_STOPPING; + TIMEOUT(fsm_timeout, f, f->timeouttime); + break; + } + + fsm_sdata(f, TERMACK, (u_char)id, NULL, 0); +} + + +/* + * fsm_rtermack - Receive Terminate-Ack. + */ +static void +fsm_rtermack(fsm *f) +{ + FSMDEBUG(LOG_INFO, ("fsm_rtermack(%s): state=%d (%s)\n", + PROTO_NAME(f), f->state, ppperr_strerr[f->state])); + + switch (f->state) { + case LS_CLOSING: + UNTIMEOUT(fsm_timeout, f); + f->state = LS_CLOSED; + if( f->callbacks->finished ) { + (*f->callbacks->finished)(f); + } + break; + + case LS_STOPPING: + UNTIMEOUT(fsm_timeout, f); + f->state = LS_STOPPED; + if( f->callbacks->finished ) { + (*f->callbacks->finished)(f); + } + break; + + case LS_ACKRCVD: + f->state = LS_REQSENT; + break; + + case LS_OPENED: + if (f->callbacks->down) { + (*f->callbacks->down)(f); /* Inform upper layers */ + } + fsm_sconfreq(f, 0); + break; + default: + FSMDEBUG(LOG_INFO, ("fsm_rtermack(%s): UNHANDLED state=%d (%s)!!!\n", + PROTO_NAME(f), f->state, ppperr_strerr[f->state])); + } +} + + +/* + * fsm_rcoderej - Receive an Code-Reject. + */ +static void +fsm_rcoderej(fsm *f, u_char *inp, int len) +{ + u_char code, id; + + FSMDEBUG(LOG_INFO, ("fsm_rcoderej(%s): state=%d (%s)\n", + PROTO_NAME(f), f->state, ppperr_strerr[f->state])); + + if (len < HEADERLEN) { + FSMDEBUG(LOG_INFO, ("fsm_rcoderej: Rcvd short Code-Reject packet!\n")); + return; + } + GETCHAR(code, inp); + GETCHAR(id, inp); + FSMDEBUG(LOG_WARNING, ("%s: Rcvd Code-Reject for code %d, id %d\n", + PROTO_NAME(f), code, id)); + + if( f->state == LS_ACKRCVD ) { + f->state = LS_REQSENT; + } +} + + +/* + * fsm_protreject - Peer doesn't speak this protocol. + * + * Treat this as a catastrophic error (RXJ-). + */ +void +fsm_protreject(fsm *f) +{ + switch( f->state ) { + case LS_CLOSING: + UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ + /* fall through */ + case LS_CLOSED: + f->state = LS_CLOSED; + if( f->callbacks->finished ) { + (*f->callbacks->finished)(f); + } + break; + + case LS_STOPPING: + case LS_REQSENT: + case LS_ACKRCVD: + case LS_ACKSENT: + UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ + /* fall through */ + case LS_STOPPED: + f->state = LS_STOPPED; + if( f->callbacks->finished ) { + (*f->callbacks->finished)(f); + } + break; + + case LS_OPENED: + if( f->callbacks->down ) { + (*f->callbacks->down)(f); + } + /* Init restart counter, send Terminate-Request */ + f->retransmits = f->maxtermtransmits; + fsm_sdata(f, TERMREQ, f->reqid = ++f->id, + (u_char *) f->term_reason, f->term_reason_len); + TIMEOUT(fsm_timeout, f, f->timeouttime); + --f->retransmits; + + f->state = LS_STOPPING; + break; + + default: + FSMDEBUG(LOG_INFO, ("%s: Protocol-reject event in state %d (%s)!\n", + PROTO_NAME(f), f->state, ppperr_strerr[f->state])); + } +} + + +/* + * fsm_sconfreq - Send a Configure-Request. + */ +static void +fsm_sconfreq(fsm *f, int retransmit) +{ + u_char *outp; + int cilen; + + if( f->state != LS_REQSENT && f->state != LS_ACKRCVD && f->state != LS_ACKSENT ) { + /* Not currently negotiating - reset options */ + if( f->callbacks->resetci ) { + (*f->callbacks->resetci)(f); + } + f->nakloops = 0; + } + + if( !retransmit ) { + /* New request - reset retransmission counter, use new ID */ + f->retransmits = f->maxconfreqtransmits; + f->reqid = ++f->id; + } + + f->seen_ack = 0; + + /* + * Make up the request packet + */ + outp = outpacket_buf[f->unit] + PPP_HDRLEN + HEADERLEN; + if( f->callbacks->cilen && f->callbacks->addci ) { + cilen = (*f->callbacks->cilen)(f); + if( cilen > peer_mru[f->unit] - (int)HEADERLEN ) { + cilen = peer_mru[f->unit] - HEADERLEN; + } + if (f->callbacks->addci) { + (*f->callbacks->addci)(f, outp, &cilen); + } + } else { + cilen = 0; + } + + /* send the request to our peer */ + fsm_sdata(f, CONFREQ, f->reqid, outp, cilen); + + /* start the retransmit timer */ + --f->retransmits; + TIMEOUT(fsm_timeout, f, f->timeouttime); + + FSMDEBUG(LOG_INFO, ("%s: sending Configure-Request, id %d\n", + PROTO_NAME(f), f->reqid)); +} + + +/* + * fsm_sdata - Send some data. + * + * Used for all packets sent to our peer by this module. + */ +void +fsm_sdata( fsm *f, u_char code, u_char id, u_char *data, int datalen) +{ + u_char *outp; + int outlen; + + /* Adjust length to be smaller than MTU */ + outp = outpacket_buf[f->unit]; + if (datalen > peer_mru[f->unit] - (int)HEADERLEN) { + datalen = peer_mru[f->unit] - HEADERLEN; + } + if (datalen && data != outp + PPP_HDRLEN + HEADERLEN) { + BCOPY(data, outp + PPP_HDRLEN + HEADERLEN, datalen); + } + outlen = datalen + HEADERLEN; + MAKEHEADER(outp, f->protocol); + PUTCHAR(code, outp); + PUTCHAR(id, outp); + PUTSHORT(outlen, outp); + pppWrite(f->unit, outpacket_buf[f->unit], outlen + PPP_HDRLEN); + FSMDEBUG(LOG_INFO, ("fsm_sdata(%s): Sent code %d,%d,%d.\n", + PROTO_NAME(f), code, id, outlen)); +} + +#endif /* PPP_SUPPORT */ diff --git a/src/lwip-1.4.1/src/netif/ppp/fsm.h b/src/lwip-1.4.1/src/netif/ppp/fsm.h new file mode 100644 index 0000000..8d41b5f --- /dev/null +++ b/src/lwip-1.4.1/src/netif/ppp/fsm.h @@ -0,0 +1,157 @@ +/***************************************************************************** +* fsm.h - Network Control Protocol Finite State Machine header file. +* +* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. +* Copyright (c) 1997 Global Election Systems Inc. +* +* The authors hereby grant permission to use, copy, modify, distribute, +* and license this software and its documentation for any purpose, provided +* that existing copyright notices are retained in all copies and that this +* notice and the following disclaimer are included verbatim in any +* distributions. No written agreement, license, or royalty fee is required +* for any of the authorized uses. +* +* THIS SOFTWARE IS PROVIDED BY THE 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 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. +* +****************************************************************************** +* REVISION HISTORY +* +* 03-01-01 Marc Boucher +* Ported to lwIP. +* 97-11-05 Guy Lancaster , Global Election Systems Inc. +* Original based on BSD code. +*****************************************************************************/ +/* + * fsm.h - {Link, IP} Control Protocol Finite State Machine definitions. + * + * Copyright (c) 1989 Carnegie Mellon University. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by Carnegie Mellon University. The name of the + * University may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * $Id: fsm.h,v 1.5 2009/12/31 17:08:08 goldsimon Exp $ + */ + +#ifndef FSM_H +#define FSM_H + +/* + * LCP Packet header = Code, id, length. + */ +#define HEADERLEN (sizeof (u_char) + sizeof (u_char) + sizeof (u_short)) + + +/* + * CP (LCP, IPCP, etc.) codes. + */ +#define CONFREQ 1 /* Configuration Request */ +#define CONFACK 2 /* Configuration Ack */ +#define CONFNAK 3 /* Configuration Nak */ +#define CONFREJ 4 /* Configuration Reject */ +#define TERMREQ 5 /* Termination Request */ +#define TERMACK 6 /* Termination Ack */ +#define CODEREJ 7 /* Code Reject */ + + +/* + * Each FSM is described by an fsm structure and fsm callbacks. + */ +typedef struct fsm { + int unit; /* Interface unit number */ + u_short protocol; /* Data Link Layer Protocol field value */ + int state; /* State */ + int flags; /* Contains option bits */ + u_char id; /* Current id */ + u_char reqid; /* Current request id */ + u_char seen_ack; /* Have received valid Ack/Nak/Rej to Req */ + int timeouttime; /* Timeout time in milliseconds */ + int maxconfreqtransmits; /* Maximum Configure-Request transmissions */ + int retransmits; /* Number of retransmissions left */ + int maxtermtransmits; /* Maximum Terminate-Request transmissions */ + int nakloops; /* Number of nak loops since last ack */ + int maxnakloops; /* Maximum number of nak loops tolerated */ + struct fsm_callbacks* callbacks; /* Callback routines */ + char* term_reason; /* Reason for closing protocol */ + int term_reason_len; /* Length of term_reason */ +} fsm; + + +typedef struct fsm_callbacks { + void (*resetci)(fsm*); /* Reset our Configuration Information */ + int (*cilen)(fsm*); /* Length of our Configuration Information */ + void (*addci)(fsm*, u_char*, int*); /* Add our Configuration Information */ + int (*ackci)(fsm*, u_char*, int); /* ACK our Configuration Information */ + int (*nakci)(fsm*, u_char*, int); /* NAK our Configuration Information */ + int (*rejci)(fsm*, u_char*, int); /* Reject our Configuration Information */ + int (*reqci)(fsm*, u_char*, int*, int); /* Request peer's Configuration Information */ + void (*up)(fsm*); /* Called when fsm reaches LS_OPENED state */ + void (*down)(fsm*); /* Called when fsm leaves LS_OPENED state */ + void (*starting)(fsm*); /* Called when we want the lower layer */ + void (*finished)(fsm*); /* Called when we don't want the lower layer */ + void (*protreject)(int); /* Called when Protocol-Reject received */ + void (*retransmit)(fsm*); /* Retransmission is necessary */ + int (*extcode)(fsm*, int, u_char, u_char*, int); /* Called when unknown code received */ + char *proto_name; /* String name for protocol (for messages) */ +} fsm_callbacks; + + +/* + * Link states. + */ +#define LS_INITIAL 0 /* Down, hasn't been opened */ +#define LS_STARTING 1 /* Down, been opened */ +#define LS_CLOSED 2 /* Up, hasn't been opened */ +#define LS_STOPPED 3 /* Open, waiting for down event */ +#define LS_CLOSING 4 /* Terminating the connection, not open */ +#define LS_STOPPING 5 /* Terminating, but open */ +#define LS_REQSENT 6 /* We've sent a Config Request */ +#define LS_ACKRCVD 7 /* We've received a Config Ack */ +#define LS_ACKSENT 8 /* We've sent a Config Ack */ +#define LS_OPENED 9 /* Connection available */ + +/* + * Flags - indicate options controlling FSM operation + */ +#define OPT_PASSIVE 1 /* Don't die if we don't get a response */ +#define OPT_RESTART 2 /* Treat 2nd OPEN as DOWN, UP */ +#define OPT_SILENT 4 /* Wait for peer to speak first */ + + +/* + * Prototypes + */ +void fsm_init (fsm*); +void fsm_lowerup (fsm*); +void fsm_lowerdown (fsm*); +void fsm_open (fsm*); +void fsm_close (fsm*, char*); +void fsm_input (fsm*, u_char*, int); +void fsm_protreject (fsm*); +void fsm_sdata (fsm*, u_char, u_char, u_char*, int); + + +/* + * Variables + */ +extern int peer_mru[]; /* currently negotiated peer MRU (per unit) */ + +#endif /* FSM_H */ diff --git a/src/lwip-1.4.1/src/netif/ppp/ipcp.c b/src/lwip-1.4.1/src/netif/ppp/ipcp.c new file mode 100644 index 0000000..f0ab2e0 --- /dev/null +++ b/src/lwip-1.4.1/src/netif/ppp/ipcp.c @@ -0,0 +1,1411 @@ +/** In contrast to pppd 2.3.1, DNS support has been added, proxy-ARP and + dial-on-demand has been stripped. */ +/***************************************************************************** +* ipcp.c - Network PPP IP Control Protocol program file. +* +* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. +* portions Copyright (c) 1997 by Global Election Systems Inc. +* +* The authors hereby grant permission to use, copy, modify, distribute, +* and license this software and its documentation for any purpose, provided +* that existing copyright notices are retained in all copies and that this +* notice and the following disclaimer are included verbatim in any +* distributions. No written agreement, license, or royalty fee is required +* for any of the authorized uses. +* +* THIS SOFTWARE IS PROVIDED BY THE 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 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. +* +****************************************************************************** +* REVISION HISTORY +* +* 03-01-01 Marc Boucher +* Ported to lwIP. +* 97-12-08 Guy Lancaster , Global Election Systems Inc. +* Original. +*****************************************************************************/ +/* + * ipcp.c - PPP IP Control Protocol. + * + * Copyright (c) 1989 Carnegie Mellon University. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by Carnegie Mellon University. The name of the + * University may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#include "lwip/opt.h" + +#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ + +#include "ppp_impl.h" +#include "pppdebug.h" + +#include "auth.h" +#include "fsm.h" +#include "vj.h" +#include "ipcp.h" + +#include "lwip/inet.h" + +#include + +/* #define OLD_CI_ADDRS 1 */ /* Support deprecated address negotiation. */ + +/* global vars */ +ipcp_options ipcp_wantoptions[NUM_PPP]; /* Options that we want to request */ +ipcp_options ipcp_gotoptions[NUM_PPP]; /* Options that peer ack'd */ +ipcp_options ipcp_allowoptions[NUM_PPP]; /* Options we allow peer to request */ +ipcp_options ipcp_hisoptions[NUM_PPP]; /* Options that we ack'd */ + +/* local vars */ +static int default_route_set[NUM_PPP]; /* Have set up a default route */ +static int cis_received[NUM_PPP]; /* # Conf-Reqs received */ + + +/* + * Callbacks for fsm code. (CI = Configuration Information) + */ +static void ipcp_resetci (fsm *); /* Reset our CI */ +static int ipcp_cilen (fsm *); /* Return length of our CI */ +static void ipcp_addci (fsm *, u_char *, int *); /* Add our CI */ +static int ipcp_ackci (fsm *, u_char *, int); /* Peer ack'd our CI */ +static int ipcp_nakci (fsm *, u_char *, int); /* Peer nak'd our CI */ +static int ipcp_rejci (fsm *, u_char *, int); /* Peer rej'd our CI */ +static int ipcp_reqci (fsm *, u_char *, int *, int); /* Rcv CI */ +static void ipcp_up (fsm *); /* We're UP */ +static void ipcp_down (fsm *); /* We're DOWN */ +#if PPP_ADDITIONAL_CALLBACKS +static void ipcp_script (fsm *, char *); /* Run an up/down script */ +#endif +static void ipcp_finished (fsm *); /* Don't need lower layer */ + + +fsm ipcp_fsm[NUM_PPP]; /* IPCP fsm structure */ + + +static fsm_callbacks ipcp_callbacks = { /* IPCP callback routines */ + ipcp_resetci, /* Reset our Configuration Information */ + ipcp_cilen, /* Length of our Configuration Information */ + ipcp_addci, /* Add our Configuration Information */ + ipcp_ackci, /* ACK our Configuration Information */ + ipcp_nakci, /* NAK our Configuration Information */ + ipcp_rejci, /* Reject our Configuration Information */ + ipcp_reqci, /* Request peer's Configuration Information */ + ipcp_up, /* Called when fsm reaches LS_OPENED state */ + ipcp_down, /* Called when fsm leaves LS_OPENED state */ + NULL, /* Called when we want the lower layer up */ + ipcp_finished, /* Called when we want the lower layer down */ + NULL, /* Called when Protocol-Reject received */ + NULL, /* Retransmission is necessary */ + NULL, /* Called to handle protocol-specific codes */ + "IPCP" /* String name of protocol */ +}; + +/* + * Protocol entry points from main code. + */ +static void ipcp_init (int); +static void ipcp_open (int); +static void ipcp_close (int, char *); +static void ipcp_lowerup (int); +static void ipcp_lowerdown (int); +static void ipcp_input (int, u_char *, int); +static void ipcp_protrej (int); + + +struct protent ipcp_protent = { + PPP_IPCP, + ipcp_init, + ipcp_input, + ipcp_protrej, + ipcp_lowerup, + ipcp_lowerdown, + ipcp_open, + ipcp_close, +#if PPP_ADDITIONAL_CALLBACKS + ipcp_printpkt, + NULL, +#endif /* PPP_ADDITIONAL_CALLBACKS */ + 1, + "IPCP", +#if PPP_ADDITIONAL_CALLBACKS + ip_check_options, + NULL, + ip_active_pkt +#endif /* PPP_ADDITIONAL_CALLBACKS */ +}; + +static void ipcp_clear_addrs (int); + +/* + * Lengths of configuration options. + */ +#define CILEN_VOID 2 +#define CILEN_COMPRESS 4 /* min length for compression protocol opt. */ +#define CILEN_VJ 6 /* length for RFC1332 Van-Jacobson opt. */ +#define CILEN_ADDR 6 /* new-style single address option */ +#define CILEN_ADDRS 10 /* old-style dual address option */ + + +#define CODENAME(x) ((x) == CONFACK ? "ACK" : \ + (x) == CONFNAK ? "NAK" : "REJ") + + +/* + * ipcp_init - Initialize IPCP. + */ +static void +ipcp_init(int unit) +{ + fsm *f = &ipcp_fsm[unit]; + ipcp_options *wo = &ipcp_wantoptions[unit]; + ipcp_options *ao = &ipcp_allowoptions[unit]; + + f->unit = unit; + f->protocol = PPP_IPCP; + f->callbacks = &ipcp_callbacks; + fsm_init(&ipcp_fsm[unit]); + + memset(wo, 0, sizeof(*wo)); + memset(ao, 0, sizeof(*ao)); + + wo->neg_addr = 1; + wo->ouraddr = 0; +#if VJ_SUPPORT + wo->neg_vj = 1; +#else /* VJ_SUPPORT */ + wo->neg_vj = 0; +#endif /* VJ_SUPPORT */ + wo->vj_protocol = IPCP_VJ_COMP; + wo->maxslotindex = MAX_SLOTS - 1; + wo->cflag = 0; + wo->default_route = 1; + + ao->neg_addr = 1; +#if VJ_SUPPORT + ao->neg_vj = 1; +#else /* VJ_SUPPORT */ + ao->neg_vj = 0; +#endif /* VJ_SUPPORT */ + ao->maxslotindex = MAX_SLOTS - 1; + ao->cflag = 1; + ao->default_route = 1; +} + + +/* + * ipcp_open - IPCP is allowed to come up. + */ +static void +ipcp_open(int unit) +{ + fsm_open(&ipcp_fsm[unit]); +} + + +/* + * ipcp_close - Take IPCP down. + */ +static void +ipcp_close(int unit, char *reason) +{ + fsm_close(&ipcp_fsm[unit], reason); +} + + +/* + * ipcp_lowerup - The lower layer is up. + */ +static void +ipcp_lowerup(int unit) +{ + fsm_lowerup(&ipcp_fsm[unit]); +} + + +/* + * ipcp_lowerdown - The lower layer is down. + */ +static void +ipcp_lowerdown(int unit) +{ + fsm_lowerdown(&ipcp_fsm[unit]); +} + + +/* + * ipcp_input - Input IPCP packet. + */ +static void +ipcp_input(int unit, u_char *p, int len) +{ + fsm_input(&ipcp_fsm[unit], p, len); +} + + +/* + * ipcp_protrej - A Protocol-Reject was received for IPCP. + * + * Pretend the lower layer went down, so we shut up. + */ +static void +ipcp_protrej(int unit) +{ + fsm_lowerdown(&ipcp_fsm[unit]); +} + + +/* + * ipcp_resetci - Reset our CI. + */ +static void +ipcp_resetci(fsm *f) +{ + ipcp_options *wo = &ipcp_wantoptions[f->unit]; + + wo->req_addr = wo->neg_addr && ipcp_allowoptions[f->unit].neg_addr; + if (wo->ouraddr == 0) { + wo->accept_local = 1; + } + if (wo->hisaddr == 0) { + wo->accept_remote = 1; + } + /* Request DNS addresses from the peer */ + wo->req_dns1 = ppp_settings.usepeerdns; + wo->req_dns2 = ppp_settings.usepeerdns; + ipcp_gotoptions[f->unit] = *wo; + cis_received[f->unit] = 0; +} + + +/* + * ipcp_cilen - Return length of our CI. + */ +static int +ipcp_cilen(fsm *f) +{ + ipcp_options *go = &ipcp_gotoptions[f->unit]; + ipcp_options *wo = &ipcp_wantoptions[f->unit]; + ipcp_options *ho = &ipcp_hisoptions[f->unit]; + +#define LENCIVJ(neg, old) (neg ? (old? CILEN_COMPRESS : CILEN_VJ) : 0) +#define LENCIADDR(neg, old) (neg ? (old? CILEN_ADDRS : CILEN_ADDR) : 0) +#define LENCIDNS(neg) (neg ? (CILEN_ADDR) : 0) + + /* + * First see if we want to change our options to the old + * forms because we have received old forms from the peer. + */ + if (wo->neg_addr && !go->neg_addr && !go->old_addrs) { + /* use the old style of address negotiation */ + go->neg_addr = 1; + go->old_addrs = 1; + } + if (wo->neg_vj && !go->neg_vj && !go->old_vj) { + /* try an older style of VJ negotiation */ + if (cis_received[f->unit] == 0) { + /* keep trying the new style until we see some CI from the peer */ + go->neg_vj = 1; + } else { + /* use the old style only if the peer did */ + if (ho->neg_vj && ho->old_vj) { + go->neg_vj = 1; + go->old_vj = 1; + go->vj_protocol = ho->vj_protocol; + } + } + } + + return (LENCIADDR(go->neg_addr, go->old_addrs) + + LENCIVJ(go->neg_vj, go->old_vj) + + LENCIDNS(go->req_dns1) + + LENCIDNS(go->req_dns2)); +} + + +/* + * ipcp_addci - Add our desired CIs to a packet. + */ +static void +ipcp_addci(fsm *f, u_char *ucp, int *lenp) +{ + ipcp_options *go = &ipcp_gotoptions[f->unit]; + int len = *lenp; + +#define ADDCIVJ(opt, neg, val, old, maxslotindex, cflag) \ + if (neg) { \ + int vjlen = old? CILEN_COMPRESS : CILEN_VJ; \ + if (len >= vjlen) { \ + PUTCHAR(opt, ucp); \ + PUTCHAR(vjlen, ucp); \ + PUTSHORT(val, ucp); \ + if (!old) { \ + PUTCHAR(maxslotindex, ucp); \ + PUTCHAR(cflag, ucp); \ + } \ + len -= vjlen; \ + } else { \ + neg = 0; \ + } \ + } + +#define ADDCIADDR(opt, neg, old, val1, val2) \ + if (neg) { \ + int addrlen = (old? CILEN_ADDRS: CILEN_ADDR); \ + if (len >= addrlen) { \ + u32_t l; \ + PUTCHAR(opt, ucp); \ + PUTCHAR(addrlen, ucp); \ + l = ntohl(val1); \ + PUTLONG(l, ucp); \ + if (old) { \ + l = ntohl(val2); \ + PUTLONG(l, ucp); \ + } \ + len -= addrlen; \ + } else { \ + neg = 0; \ + } \ + } + +#define ADDCIDNS(opt, neg, addr) \ + if (neg) { \ + if (len >= CILEN_ADDR) { \ + u32_t l; \ + PUTCHAR(opt, ucp); \ + PUTCHAR(CILEN_ADDR, ucp); \ + l = ntohl(addr); \ + PUTLONG(l, ucp); \ + len -= CILEN_ADDR; \ + } else { \ + neg = 0; \ + } \ + } + + ADDCIADDR((go->old_addrs? CI_ADDRS: CI_ADDR), go->neg_addr, + go->old_addrs, go->ouraddr, go->hisaddr); + + ADDCIVJ(CI_COMPRESSTYPE, go->neg_vj, go->vj_protocol, go->old_vj, + go->maxslotindex, go->cflag); + + ADDCIDNS(CI_MS_DNS1, go->req_dns1, go->dnsaddr[0]); + + ADDCIDNS(CI_MS_DNS2, go->req_dns2, go->dnsaddr[1]); + + *lenp -= len; +} + + +/* + * ipcp_ackci - Ack our CIs. + * + * Returns: + * 0 - Ack was bad. + * 1 - Ack was good. + */ +static int +ipcp_ackci(fsm *f, u_char *p, int len) +{ + ipcp_options *go = &ipcp_gotoptions[f->unit]; + u_short cilen, citype, cishort; + u32_t cilong; + u_char cimaxslotindex, cicflag; + + /* + * CIs must be in exactly the same order that we sent... + * Check packet length and CI length at each step. + * If we find any deviations, then this packet is bad. + */ + +#define ACKCIVJ(opt, neg, val, old, maxslotindex, cflag) \ + if (neg) { \ + int vjlen = old? CILEN_COMPRESS : CILEN_VJ; \ + if ((len -= vjlen) < 0) { \ + goto bad; \ + } \ + GETCHAR(citype, p); \ + GETCHAR(cilen, p); \ + if (cilen != vjlen || \ + citype != opt) { \ + goto bad; \ + } \ + GETSHORT(cishort, p); \ + if (cishort != val) { \ + goto bad; \ + } \ + if (!old) { \ + GETCHAR(cimaxslotindex, p); \ + if (cimaxslotindex != maxslotindex) { \ + goto bad; \ + } \ + GETCHAR(cicflag, p); \ + if (cicflag != cflag) { \ + goto bad; \ + } \ + } \ + } + +#define ACKCIADDR(opt, neg, old, val1, val2) \ + if (neg) { \ + int addrlen = (old? CILEN_ADDRS: CILEN_ADDR); \ + u32_t l; \ + if ((len -= addrlen) < 0) { \ + goto bad; \ + } \ + GETCHAR(citype, p); \ + GETCHAR(cilen, p); \ + if (cilen != addrlen || \ + citype != opt) { \ + goto bad; \ + } \ + GETLONG(l, p); \ + cilong = htonl(l); \ + if (val1 != cilong) { \ + goto bad; \ + } \ + if (old) { \ + GETLONG(l, p); \ + cilong = htonl(l); \ + if (val2 != cilong) { \ + goto bad; \ + } \ + } \ + } + +#define ACKCIDNS(opt, neg, addr) \ + if (neg) { \ + u32_t l; \ + if ((len -= CILEN_ADDR) < 0) { \ + goto bad; \ + } \ + GETCHAR(citype, p); \ + GETCHAR(cilen, p); \ + if (cilen != CILEN_ADDR || \ + citype != opt) { \ + goto bad; \ + } \ + GETLONG(l, p); \ + cilong = htonl(l); \ + if (addr != cilong) { \ + goto bad; \ + } \ + } + + ACKCIADDR((go->old_addrs? CI_ADDRS: CI_ADDR), go->neg_addr, + go->old_addrs, go->ouraddr, go->hisaddr); + + ACKCIVJ(CI_COMPRESSTYPE, go->neg_vj, go->vj_protocol, go->old_vj, + go->maxslotindex, go->cflag); + + ACKCIDNS(CI_MS_DNS1, go->req_dns1, go->dnsaddr[0]); + + ACKCIDNS(CI_MS_DNS2, go->req_dns2, go->dnsaddr[1]); + + /* + * If there are any remaining CIs, then this packet is bad. + */ + if (len != 0) { + goto bad; + } + return (1); + +bad: + IPCPDEBUG(LOG_INFO, ("ipcp_ackci: received bad Ack!\n")); + return (0); +} + +/* + * ipcp_nakci - Peer has sent a NAK for some of our CIs. + * This should not modify any state if the Nak is bad + * or if IPCP is in the LS_OPENED state. + * + * Returns: + * 0 - Nak was bad. + * 1 - Nak was good. + */ +static int +ipcp_nakci(fsm *f, u_char *p, int len) +{ + ipcp_options *go = &ipcp_gotoptions[f->unit]; + u_char cimaxslotindex, cicflag; + u_char citype, cilen, *next; + u_short cishort; + u32_t ciaddr1, ciaddr2, l, cidnsaddr; + ipcp_options no; /* options we've seen Naks for */ + ipcp_options try; /* options to request next time */ + + BZERO(&no, sizeof(no)); + try = *go; + + /* + * Any Nak'd CIs must be in exactly the same order that we sent. + * Check packet length and CI length at each step. + * If we find any deviations, then this packet is bad. + */ +#define NAKCIADDR(opt, neg, old, code) \ + if (go->neg && \ + len >= (cilen = (old? CILEN_ADDRS: CILEN_ADDR)) && \ + p[1] == cilen && \ + p[0] == opt) { \ + len -= cilen; \ + INCPTR(2, p); \ + GETLONG(l, p); \ + ciaddr1 = htonl(l); \ + if (old) { \ + GETLONG(l, p); \ + ciaddr2 = htonl(l); \ + no.old_addrs = 1; \ + } else { \ + ciaddr2 = 0; \ + } \ + no.neg = 1; \ + code \ + } + +#define NAKCIVJ(opt, neg, code) \ + if (go->neg && \ + ((cilen = p[1]) == CILEN_COMPRESS || cilen == CILEN_VJ) && \ + len >= cilen && \ + p[0] == opt) { \ + len -= cilen; \ + INCPTR(2, p); \ + GETSHORT(cishort, p); \ + no.neg = 1; \ + code \ + } + +#define NAKCIDNS(opt, neg, code) \ + if (go->neg && \ + ((cilen = p[1]) == CILEN_ADDR) && \ + len >= cilen && \ + p[0] == opt) { \ + len -= cilen; \ + INCPTR(2, p); \ + GETLONG(l, p); \ + cidnsaddr = htonl(l); \ + no.neg = 1; \ + code \ + } + + /* + * Accept the peer's idea of {our,his} address, if different + * from our idea, only if the accept_{local,remote} flag is set. + */ + NAKCIADDR((go->old_addrs? CI_ADDRS: CI_ADDR), neg_addr, go->old_addrs, + if (go->accept_local && ciaddr1) { /* Do we know our address? */ + try.ouraddr = ciaddr1; + IPCPDEBUG(LOG_INFO, ("local IP address %s\n", + inet_ntoa(ciaddr1))); + } + if (go->accept_remote && ciaddr2) { /* Does he know his? */ + try.hisaddr = ciaddr2; + IPCPDEBUG(LOG_INFO, ("remote IP address %s\n", + inet_ntoa(ciaddr2))); + } + ); + + /* + * Accept the peer's value of maxslotindex provided that it + * is less than what we asked for. Turn off slot-ID compression + * if the peer wants. Send old-style compress-type option if + * the peer wants. + */ + NAKCIVJ(CI_COMPRESSTYPE, neg_vj, + if (cilen == CILEN_VJ) { + GETCHAR(cimaxslotindex, p); + GETCHAR(cicflag, p); + if (cishort == IPCP_VJ_COMP) { + try.old_vj = 0; + if (cimaxslotindex < go->maxslotindex) { + try.maxslotindex = cimaxslotindex; + } + if (!cicflag) { + try.cflag = 0; + } + } else { + try.neg_vj = 0; + } + } else { + if (cishort == IPCP_VJ_COMP || cishort == IPCP_VJ_COMP_OLD) { + try.old_vj = 1; + try.vj_protocol = cishort; + } else { + try.neg_vj = 0; + } + } + ); + + NAKCIDNS(CI_MS_DNS1, req_dns1, + try.dnsaddr[0] = cidnsaddr; + IPCPDEBUG(LOG_INFO, ("primary DNS address %s\n", inet_ntoa(cidnsaddr))); + ); + + NAKCIDNS(CI_MS_DNS2, req_dns2, + try.dnsaddr[1] = cidnsaddr; + IPCPDEBUG(LOG_INFO, ("secondary DNS address %s\n", inet_ntoa(cidnsaddr))); + ); + + /* + * There may be remaining CIs, if the peer is requesting negotiation + * on an option that we didn't include in our request packet. + * If they want to negotiate about IP addresses, we comply. + * If they want us to ask for compression, we refuse. + */ + while (len > CILEN_VOID) { + GETCHAR(citype, p); + GETCHAR(cilen, p); + if( (len -= cilen) < 0 ) { + goto bad; + } + next = p + cilen - 2; + + switch (citype) { + case CI_COMPRESSTYPE: + if (go->neg_vj || no.neg_vj || + (cilen != CILEN_VJ && cilen != CILEN_COMPRESS)) { + goto bad; + } + no.neg_vj = 1; + break; + case CI_ADDRS: + if ((go->neg_addr && go->old_addrs) || no.old_addrs + || cilen != CILEN_ADDRS) { + goto bad; + } + try.neg_addr = 1; + try.old_addrs = 1; + GETLONG(l, p); + ciaddr1 = htonl(l); + if (ciaddr1 && go->accept_local) { + try.ouraddr = ciaddr1; + } + GETLONG(l, p); + ciaddr2 = htonl(l); + if (ciaddr2 && go->accept_remote) { + try.hisaddr = ciaddr2; + } + no.old_addrs = 1; + break; + case CI_ADDR: + if (go->neg_addr || no.neg_addr || cilen != CILEN_ADDR) { + goto bad; + } + try.old_addrs = 0; + GETLONG(l, p); + ciaddr1 = htonl(l); + if (ciaddr1 && go->accept_local) { + try.ouraddr = ciaddr1; + } + if (try.ouraddr != 0) { + try.neg_addr = 1; + } + no.neg_addr = 1; + break; + } + p = next; + } + + /* If there is still anything left, this packet is bad. */ + if (len != 0) { + goto bad; + } + + /* + * OK, the Nak is good. Now we can update state. + */ + if (f->state != LS_OPENED) { + *go = try; + } + + return 1; + +bad: + IPCPDEBUG(LOG_INFO, ("ipcp_nakci: received bad Nak!\n")); + return 0; +} + + +/* + * ipcp_rejci - Reject some of our CIs. + */ +static int +ipcp_rejci(fsm *f, u_char *p, int len) +{ + ipcp_options *go = &ipcp_gotoptions[f->unit]; + u_char cimaxslotindex, ciflag, cilen; + u_short cishort; + u32_t cilong; + ipcp_options try; /* options to request next time */ + + try = *go; + /* + * Any Rejected CIs must be in exactly the same order that we sent. + * Check packet length and CI length at each step. + * If we find any deviations, then this packet is bad. + */ +#define REJCIADDR(opt, neg, old, val1, val2) \ + if (go->neg && \ + len >= (cilen = old? CILEN_ADDRS: CILEN_ADDR) && \ + p[1] == cilen && \ + p[0] == opt) { \ + u32_t l; \ + len -= cilen; \ + INCPTR(2, p); \ + GETLONG(l, p); \ + cilong = htonl(l); \ + /* Check rejected value. */ \ + if (cilong != val1) { \ + goto bad; \ + } \ + if (old) { \ + GETLONG(l, p); \ + cilong = htonl(l); \ + /* Check rejected value. */ \ + if (cilong != val2) { \ + goto bad; \ + } \ + } \ + try.neg = 0; \ + } + +#define REJCIVJ(opt, neg, val, old, maxslot, cflag) \ + if (go->neg && \ + p[1] == (old? CILEN_COMPRESS : CILEN_VJ) && \ + len >= p[1] && \ + p[0] == opt) { \ + len -= p[1]; \ + INCPTR(2, p); \ + GETSHORT(cishort, p); \ + /* Check rejected value. */ \ + if (cishort != val) { \ + goto bad; \ + } \ + if (!old) { \ + GETCHAR(cimaxslotindex, p); \ + if (cimaxslotindex != maxslot) { \ + goto bad; \ + } \ + GETCHAR(ciflag, p); \ + if (ciflag != cflag) { \ + goto bad; \ + } \ + } \ + try.neg = 0; \ + } + +#define REJCIDNS(opt, neg, dnsaddr) \ + if (go->neg && \ + ((cilen = p[1]) == CILEN_ADDR) && \ + len >= cilen && \ + p[0] == opt) { \ + u32_t l; \ + len -= cilen; \ + INCPTR(2, p); \ + GETLONG(l, p); \ + cilong = htonl(l); \ + /* Check rejected value. */ \ + if (cilong != dnsaddr) { \ + goto bad; \ + } \ + try.neg = 0; \ + } + + REJCIADDR((go->old_addrs? CI_ADDRS: CI_ADDR), neg_addr, + go->old_addrs, go->ouraddr, go->hisaddr); + + REJCIVJ(CI_COMPRESSTYPE, neg_vj, go->vj_protocol, go->old_vj, + go->maxslotindex, go->cflag); + + REJCIDNS(CI_MS_DNS1, req_dns1, go->dnsaddr[0]); + + REJCIDNS(CI_MS_DNS2, req_dns2, go->dnsaddr[1]); + + /* + * If there are any remaining CIs, then this packet is bad. + */ + if (len != 0) { + goto bad; + } + /* + * Now we can update state. + */ + if (f->state != LS_OPENED) { + *go = try; + } + return 1; + +bad: + IPCPDEBUG(LOG_INFO, ("ipcp_rejci: received bad Reject!\n")); + return 0; +} + + +/* + * ipcp_reqci - Check the peer's requested CIs and send appropriate response. + * + * Returns: CONFACK, CONFNAK or CONFREJ and input packet modified + * appropriately. If reject_if_disagree is non-zero, doesn't return + * CONFNAK; returns CONFREJ if it can't return CONFACK. + */ +static int +ipcp_reqci(fsm *f, u_char *inp/* Requested CIs */,int *len/* Length of requested CIs */,int reject_if_disagree) +{ + ipcp_options *wo = &ipcp_wantoptions[f->unit]; + ipcp_options *ho = &ipcp_hisoptions[f->unit]; + ipcp_options *ao = &ipcp_allowoptions[f->unit]; +#ifdef OLD_CI_ADDRS + ipcp_options *go = &ipcp_gotoptions[f->unit]; +#endif + u_char *cip, *next; /* Pointer to current and next CIs */ + u_short cilen, citype; /* Parsed len, type */ + u_short cishort; /* Parsed short value */ + u32_t tl, ciaddr1; /* Parsed address values */ +#ifdef OLD_CI_ADDRS + u32_t ciaddr2; /* Parsed address values */ +#endif + int rc = CONFACK; /* Final packet return code */ + int orc; /* Individual option return code */ + u_char *p; /* Pointer to next char to parse */ + u_char *ucp = inp; /* Pointer to current output char */ + int l = *len; /* Length left */ + u_char maxslotindex, cflag; + int d; + + cis_received[f->unit] = 1; + + /* + * Reset all his options. + */ + BZERO(ho, sizeof(*ho)); + + /* + * Process all his options. + */ + next = inp; + while (l) { + orc = CONFACK; /* Assume success */ + cip = p = next; /* Remember begining of CI */ + if (l < 2 || /* Not enough data for CI header or */ + p[1] < 2 || /* CI length too small or */ + p[1] > l) { /* CI length too big? */ + IPCPDEBUG(LOG_INFO, ("ipcp_reqci: bad CI length!\n")); + orc = CONFREJ; /* Reject bad CI */ + cilen = (u_short)l;/* Reject till end of packet */ + l = 0; /* Don't loop again */ + goto endswitch; + } + GETCHAR(citype, p); /* Parse CI type */ + GETCHAR(cilen, p); /* Parse CI length */ + l -= cilen; /* Adjust remaining length */ + next += cilen; /* Step to next CI */ + + switch (citype) { /* Check CI type */ +#ifdef OLD_CI_ADDRS /* Need to save space... */ + case CI_ADDRS: + IPCPDEBUG(LOG_INFO, ("ipcp_reqci: received ADDRS\n")); + if (!ao->neg_addr || + cilen != CILEN_ADDRS) { /* Check CI length */ + orc = CONFREJ; /* Reject CI */ + break; + } + + /* + * If he has no address, or if we both have his address but + * disagree about it, then NAK it with our idea. + * In particular, if we don't know his address, but he does, + * then accept it. + */ + GETLONG(tl, p); /* Parse source address (his) */ + ciaddr1 = htonl(tl); + IPCPDEBUG(LOG_INFO, ("his addr %s\n", inet_ntoa(ciaddr1))); + if (ciaddr1 != wo->hisaddr + && (ciaddr1 == 0 || !wo->accept_remote)) { + orc = CONFNAK; + if (!reject_if_disagree) { + DECPTR(sizeof(u32_t), p); + tl = ntohl(wo->hisaddr); + PUTLONG(tl, p); + } + } else if (ciaddr1 == 0 && wo->hisaddr == 0) { + /* + * If neither we nor he knows his address, reject the option. + */ + orc = CONFREJ; + wo->req_addr = 0; /* don't NAK with 0.0.0.0 later */ + break; + } + + /* + * If he doesn't know our address, or if we both have our address + * but disagree about it, then NAK it with our idea. + */ + GETLONG(tl, p); /* Parse desination address (ours) */ + ciaddr2 = htonl(tl); + IPCPDEBUG(LOG_INFO, ("our addr %s\n", inet_ntoa(ciaddr2))); + if (ciaddr2 != wo->ouraddr) { + if (ciaddr2 == 0 || !wo->accept_local) { + orc = CONFNAK; + if (!reject_if_disagree) { + DECPTR(sizeof(u32_t), p); + tl = ntohl(wo->ouraddr); + PUTLONG(tl, p); + } + } else { + go->ouraddr = ciaddr2; /* accept peer's idea */ + } + } + + ho->neg_addr = 1; + ho->old_addrs = 1; + ho->hisaddr = ciaddr1; + ho->ouraddr = ciaddr2; + break; +#endif + + case CI_ADDR: + if (!ao->neg_addr) { + IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Reject ADDR not allowed\n")); + orc = CONFREJ; /* Reject CI */ + break; + } else if (cilen != CILEN_ADDR) { /* Check CI length */ + IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Reject ADDR bad len\n")); + orc = CONFREJ; /* Reject CI */ + break; + } + + /* + * If he has no address, or if we both have his address but + * disagree about it, then NAK it with our idea. + * In particular, if we don't know his address, but he does, + * then accept it. + */ + GETLONG(tl, p); /* Parse source address (his) */ + ciaddr1 = htonl(tl); + if (ciaddr1 != wo->hisaddr + && (ciaddr1 == 0 || !wo->accept_remote)) { + orc = CONFNAK; + if (!reject_if_disagree) { + DECPTR(sizeof(u32_t), p); + tl = ntohl(wo->hisaddr); + PUTLONG(tl, p); + } + IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Nak ADDR %s\n", inet_ntoa(ciaddr1))); + } else if (ciaddr1 == 0 && wo->hisaddr == 0) { + /* + * Don't ACK an address of 0.0.0.0 - reject it instead. + */ + IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Reject ADDR %s\n", inet_ntoa(ciaddr1))); + orc = CONFREJ; + wo->req_addr = 0; /* don't NAK with 0.0.0.0 later */ + break; + } + + ho->neg_addr = 1; + ho->hisaddr = ciaddr1; + IPCPDEBUG(LOG_INFO, ("ipcp_reqci: ADDR %s\n", inet_ntoa(ciaddr1))); + break; + + case CI_MS_DNS1: + case CI_MS_DNS2: + /* Microsoft primary or secondary DNS request */ + d = citype == CI_MS_DNS2; + + /* If we do not have a DNS address then we cannot send it */ + if (ao->dnsaddr[d] == 0 || + cilen != CILEN_ADDR) { /* Check CI length */ + IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Rejecting DNS%d Request\n", d+1)); + orc = CONFREJ; /* Reject CI */ + break; + } + GETLONG(tl, p); + if (htonl(tl) != ao->dnsaddr[d]) { + IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Naking DNS%d Request %s\n", + d+1, inet_ntoa(tl))); + DECPTR(sizeof(u32_t), p); + tl = ntohl(ao->dnsaddr[d]); + PUTLONG(tl, p); + orc = CONFNAK; + } + IPCPDEBUG(LOG_INFO, ("ipcp_reqci: received DNS%d Request\n", d+1)); + break; + + case CI_MS_WINS1: + case CI_MS_WINS2: + /* Microsoft primary or secondary WINS request */ + d = citype == CI_MS_WINS2; + IPCPDEBUG(LOG_INFO, ("ipcp_reqci: received WINS%d Request\n", d+1)); + + /* If we do not have a DNS address then we cannot send it */ + if (ao->winsaddr[d] == 0 || + cilen != CILEN_ADDR) { /* Check CI length */ + orc = CONFREJ; /* Reject CI */ + break; + } + GETLONG(tl, p); + if (htonl(tl) != ao->winsaddr[d]) { + DECPTR(sizeof(u32_t), p); + tl = ntohl(ao->winsaddr[d]); + PUTLONG(tl, p); + orc = CONFNAK; + } + break; + + case CI_COMPRESSTYPE: + if (!ao->neg_vj) { + IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Rejecting COMPRESSTYPE not allowed\n")); + orc = CONFREJ; + break; + } else if (cilen != CILEN_VJ && cilen != CILEN_COMPRESS) { + IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Rejecting COMPRESSTYPE len=%d\n", cilen)); + orc = CONFREJ; + break; + } + GETSHORT(cishort, p); + + if (!(cishort == IPCP_VJ_COMP || + (cishort == IPCP_VJ_COMP_OLD && cilen == CILEN_COMPRESS))) { + IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Rejecting COMPRESSTYPE %d\n", cishort)); + orc = CONFREJ; + break; + } + + ho->neg_vj = 1; + ho->vj_protocol = cishort; + if (cilen == CILEN_VJ) { + GETCHAR(maxslotindex, p); + if (maxslotindex > ao->maxslotindex) { + IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Naking VJ max slot %d\n", maxslotindex)); + orc = CONFNAK; + if (!reject_if_disagree) { + DECPTR(1, p); + PUTCHAR(ao->maxslotindex, p); + } + } + GETCHAR(cflag, p); + if (cflag && !ao->cflag) { + IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Naking VJ cflag %d\n", cflag)); + orc = CONFNAK; + if (!reject_if_disagree) { + DECPTR(1, p); + PUTCHAR(wo->cflag, p); + } + } + ho->maxslotindex = maxslotindex; + ho->cflag = cflag; + } else { + ho->old_vj = 1; + ho->maxslotindex = MAX_SLOTS - 1; + ho->cflag = 1; + } + IPCPDEBUG(LOG_INFO, ( + "ipcp_reqci: received COMPRESSTYPE p=%d old=%d maxslot=%d cflag=%d\n", + ho->vj_protocol, ho->old_vj, ho->maxslotindex, ho->cflag)); + break; + + default: + IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Rejecting unknown CI type %d\n", citype)); + orc = CONFREJ; + break; + } + +endswitch: + if (orc == CONFACK && /* Good CI */ + rc != CONFACK) { /* but prior CI wasnt? */ + continue; /* Don't send this one */ + } + + if (orc == CONFNAK) { /* Nak this CI? */ + if (reject_if_disagree) { /* Getting fed up with sending NAKs? */ + IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Rejecting too many naks\n")); + orc = CONFREJ; /* Get tough if so */ + } else { + if (rc == CONFREJ) { /* Rejecting prior CI? */ + continue; /* Don't send this one */ + } + if (rc == CONFACK) { /* Ack'd all prior CIs? */ + rc = CONFNAK; /* Not anymore... */ + ucp = inp; /* Backup */ + } + } + } + + if (orc == CONFREJ && /* Reject this CI */ + rc != CONFREJ) { /* but no prior ones? */ + rc = CONFREJ; + ucp = inp; /* Backup */ + } + + /* Need to move CI? */ + if (ucp != cip) { + BCOPY(cip, ucp, cilen); /* Move it */ + } + + /* Update output pointer */ + INCPTR(cilen, ucp); + } + + /* + * If we aren't rejecting this packet, and we want to negotiate + * their address, and they didn't send their address, then we + * send a NAK with a CI_ADDR option appended. We assume the + * input buffer is long enough that we can append the extra + * option safely. + */ + if (rc != CONFREJ && !ho->neg_addr && + wo->req_addr && !reject_if_disagree) { + IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Requesting peer address\n")); + if (rc == CONFACK) { + rc = CONFNAK; + ucp = inp; /* reset pointer */ + wo->req_addr = 0; /* don't ask again */ + } + PUTCHAR(CI_ADDR, ucp); + PUTCHAR(CILEN_ADDR, ucp); + tl = ntohl(wo->hisaddr); + PUTLONG(tl, ucp); + } + + *len = (int)(ucp - inp); /* Compute output length */ + IPCPDEBUG(LOG_INFO, ("ipcp_reqci: returning Configure-%s\n", CODENAME(rc))); + return (rc); /* Return final code */ +} + + +#if 0 +/* + * ip_check_options - check that any IP-related options are OK, + * and assign appropriate defaults. + */ +static void +ip_check_options(u_long localAddr) +{ + ipcp_options *wo = &ipcp_wantoptions[0]; + + /* + * Load our default IP address but allow the remote host to give us + * a new address. + */ + if (wo->ouraddr == 0 && !ppp_settings.disable_defaultip) { + wo->accept_local = 1; /* don't insist on this default value */ + wo->ouraddr = htonl(localAddr); + } +} +#endif + + +/* + * ipcp_up - IPCP has come UP. + * + * Configure the IP network interface appropriately and bring it up. + */ +static void +ipcp_up(fsm *f) +{ + u32_t mask; + ipcp_options *ho = &ipcp_hisoptions[f->unit]; + ipcp_options *go = &ipcp_gotoptions[f->unit]; + ipcp_options *wo = &ipcp_wantoptions[f->unit]; + + np_up(f->unit, PPP_IP); + IPCPDEBUG(LOG_INFO, ("ipcp: up\n")); + + /* + * We must have a non-zero IP address for both ends of the link. + */ + if (!ho->neg_addr) { + ho->hisaddr = wo->hisaddr; + } + + if (ho->hisaddr == 0) { + IPCPDEBUG(LOG_ERR, ("Could not determine remote IP address\n")); + ipcp_close(f->unit, "Could not determine remote IP address"); + return; + } + if (go->ouraddr == 0) { + IPCPDEBUG(LOG_ERR, ("Could not determine local IP address\n")); + ipcp_close(f->unit, "Could not determine local IP address"); + return; + } + + if (ppp_settings.usepeerdns && (go->dnsaddr[0] || go->dnsaddr[1])) { + /*pppGotDNSAddrs(go->dnsaddr[0], go->dnsaddr[1]);*/ + } + + /* + * Check that the peer is allowed to use the IP address it wants. + */ + if (!auth_ip_addr(f->unit, ho->hisaddr)) { + IPCPDEBUG(LOG_ERR, ("Peer is not authorized to use remote address %s\n", + inet_ntoa(ho->hisaddr))); + ipcp_close(f->unit, "Unauthorized remote IP address"); + return; + } + + /* set tcp compression */ + sifvjcomp(f->unit, ho->neg_vj, ho->cflag, ho->maxslotindex); + + /* + * Set IP addresses and (if specified) netmask. + */ + mask = GetMask(go->ouraddr); + + if (!sifaddr(f->unit, go->ouraddr, ho->hisaddr, mask, go->dnsaddr[0], go->dnsaddr[1])) { + IPCPDEBUG(LOG_WARNING, ("sifaddr failed\n")); + ipcp_close(f->unit, "Interface configuration failed"); + return; + } + + /* bring the interface up for IP */ + if (!sifup(f->unit)) { + IPCPDEBUG(LOG_WARNING, ("sifup failed\n")); + ipcp_close(f->unit, "Interface configuration failed"); + return; + } + + sifnpmode(f->unit, PPP_IP, NPMODE_PASS); + + /* assign a default route through the interface if required */ + if (ipcp_wantoptions[f->unit].default_route) { + if (sifdefaultroute(f->unit, go->ouraddr, ho->hisaddr)) { + default_route_set[f->unit] = 1; + } + } + + IPCPDEBUG(LOG_NOTICE, ("local IP address %s\n", inet_ntoa(go->ouraddr))); + IPCPDEBUG(LOG_NOTICE, ("remote IP address %s\n", inet_ntoa(ho->hisaddr))); + if (go->dnsaddr[0]) { + IPCPDEBUG(LOG_NOTICE, ("primary DNS address %s\n", inet_ntoa(go->dnsaddr[0]))); + } + if (go->dnsaddr[1]) { + IPCPDEBUG(LOG_NOTICE, ("secondary DNS address %s\n", inet_ntoa(go->dnsaddr[1]))); + } +} + + +/* + * ipcp_down - IPCP has gone DOWN. + * + * Take the IP network interface down, clear its addresses + * and delete routes through it. + */ +static void +ipcp_down(fsm *f) +{ + IPCPDEBUG(LOG_INFO, ("ipcp: down\n")); + np_down(f->unit, PPP_IP); + sifvjcomp(f->unit, 0, 0, 0); + + sifdown(f->unit); + ipcp_clear_addrs(f->unit); +} + + +/* + * ipcp_clear_addrs() - clear the interface addresses, routes, etc. + */ +static void +ipcp_clear_addrs(int unit) +{ + u32_t ouraddr, hisaddr; + + ouraddr = ipcp_gotoptions[unit].ouraddr; + hisaddr = ipcp_hisoptions[unit].hisaddr; + if (default_route_set[unit]) { + cifdefaultroute(unit, ouraddr, hisaddr); + default_route_set[unit] = 0; + } + cifaddr(unit, ouraddr, hisaddr); +} + + +/* + * ipcp_finished - possibly shut down the lower layers. + */ +static void +ipcp_finished(fsm *f) +{ + np_finished(f->unit, PPP_IP); +} + +#if PPP_ADDITIONAL_CALLBACKS +static int +ipcp_printpkt(u_char *p, int plen, void (*printer) (void *, char *, ...), void *arg) +{ + LWIP_UNUSED_ARG(p); + LWIP_UNUSED_ARG(plen); + LWIP_UNUSED_ARG(printer); + LWIP_UNUSED_ARG(arg); + return 0; +} + +/* + * ip_active_pkt - see if this IP packet is worth bringing the link up for. + * We don't bring the link up for IP fragments or for TCP FIN packets + * with no data. + */ +#define IP_HDRLEN 20 /* bytes */ +#define IP_OFFMASK 0x1fff +#define IPPROTO_TCP 6 +#define TCP_HDRLEN 20 +#define TH_FIN 0x01 + +/* + * We use these macros because the IP header may be at an odd address, + * and some compilers might use word loads to get th_off or ip_hl. + */ + +#define net_short(x) (((x)[0] << 8) + (x)[1]) +#define get_iphl(x) (((unsigned char *)(x))[0] & 0xF) +#define get_ipoff(x) net_short((unsigned char *)(x) + 6) +#define get_ipproto(x) (((unsigned char *)(x))[9]) +#define get_tcpoff(x) (((unsigned char *)(x))[12] >> 4) +#define get_tcpflags(x) (((unsigned char *)(x))[13]) + +static int +ip_active_pkt(u_char *pkt, int len) +{ + u_char *tcp; + int hlen; + + len -= PPP_HDRLEN; + pkt += PPP_HDRLEN; + if (len < IP_HDRLEN) { + return 0; + } + if ((get_ipoff(pkt) & IP_OFFMASK) != 0) { + return 0; + } + if (get_ipproto(pkt) != IPPROTO_TCP) { + return 1; + } + hlen = get_iphl(pkt) * 4; + if (len < hlen + TCP_HDRLEN) { + return 0; + } + tcp = pkt + hlen; + if ((get_tcpflags(tcp) & TH_FIN) != 0 && len == hlen + get_tcpoff(tcp) * 4) { + return 0; + } + return 1; +} +#endif /* PPP_ADDITIONAL_CALLBACKS */ + +#endif /* PPP_SUPPORT */ diff --git a/src/lwip-1.4.1/src/netif/ppp/ipcp.h b/src/lwip-1.4.1/src/netif/ppp/ipcp.h new file mode 100644 index 0000000..de03f46 --- /dev/null +++ b/src/lwip-1.4.1/src/netif/ppp/ipcp.h @@ -0,0 +1,106 @@ +/***************************************************************************** +* ipcp.h - PPP IP NCP: Internet Protocol Network Control Protocol header file. +* +* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. +* portions Copyright (c) 1997 Global Election Systems Inc. +* +* The authors hereby grant permission to use, copy, modify, distribute, +* and license this software and its documentation for any purpose, provided +* that existing copyright notices are retained in all copies and that this +* notice and the following disclaimer are included verbatim in any +* distributions. No written agreement, license, or royalty fee is required +* for any of the authorized uses. +* +* THIS SOFTWARE IS PROVIDED BY THE 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 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. +* +****************************************************************************** +* REVISION HISTORY +* +* 03-01-01 Marc Boucher +* Ported to lwIP. +* 97-12-04 Guy Lancaster , Global Election Systems Inc. +* Original derived from BSD codes. +*****************************************************************************/ +/* + * ipcp.h - IP Control Protocol definitions. + * + * Copyright (c) 1989 Carnegie Mellon University. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by Carnegie Mellon University. The name of the + * University may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * $Id: ipcp.h,v 1.4 2010/01/18 20:49:43 goldsimon Exp $ + */ + +#ifndef IPCP_H +#define IPCP_H + +/* + * Options. + */ +#define CI_ADDRS 1 /* IP Addresses */ +#define CI_COMPRESSTYPE 2 /* Compression Type */ +#define CI_ADDR 3 + +#define CI_MS_DNS1 129 /* Primary DNS value */ +#define CI_MS_WINS1 128 /* Primary WINS value */ +#define CI_MS_DNS2 131 /* Secondary DNS value */ +#define CI_MS_WINS2 130 /* Secondary WINS value */ + +#define IPCP_VJMODE_OLD 1 /* "old" mode (option # = 0x0037) */ +#define IPCP_VJMODE_RFC1172 2 /* "old-rfc"mode (option # = 0x002d) */ +#define IPCP_VJMODE_RFC1332 3 /* "new-rfc"mode (option # = 0x002d, */ + /* maxslot and slot number compression) */ + +#define IPCP_VJ_COMP 0x002d /* current value for VJ compression option */ +#define IPCP_VJ_COMP_OLD 0x0037 /* "old" (i.e, broken) value for VJ */ + /* compression option */ + +typedef struct ipcp_options { + u_int neg_addr : 1; /* Negotiate IP Address? */ + u_int old_addrs : 1; /* Use old (IP-Addresses) option? */ + u_int req_addr : 1; /* Ask peer to send IP address? */ + u_int default_route : 1; /* Assign default route through interface? */ + u_int proxy_arp : 1; /* Make proxy ARP entry for peer? */ + u_int neg_vj : 1; /* Van Jacobson Compression? */ + u_int old_vj : 1; /* use old (short) form of VJ option? */ + u_int accept_local : 1; /* accept peer's value for ouraddr */ + u_int accept_remote : 1; /* accept peer's value for hisaddr */ + u_int req_dns1 : 1; /* Ask peer to send primary DNS address? */ + u_int req_dns2 : 1; /* Ask peer to send secondary DNS address? */ + u_short vj_protocol; /* protocol value to use in VJ option */ + u_char maxslotindex; /* VJ slots - 1. */ + u_char cflag; /* VJ slot compression flag. */ + u32_t ouraddr, hisaddr; /* Addresses in NETWORK BYTE ORDER */ + u32_t dnsaddr[2]; /* Primary and secondary MS DNS entries */ + u32_t winsaddr[2]; /* Primary and secondary MS WINS entries */ +} ipcp_options; + +extern fsm ipcp_fsm[]; +extern ipcp_options ipcp_wantoptions[]; +extern ipcp_options ipcp_gotoptions[]; +extern ipcp_options ipcp_allowoptions[]; +extern ipcp_options ipcp_hisoptions[]; + +extern struct protent ipcp_protent; + +#endif /* IPCP_H */ diff --git a/src/lwip-1.4.1/src/netif/ppp/lcp.c b/src/lwip-1.4.1/src/netif/ppp/lcp.c new file mode 100644 index 0000000..54f758a --- /dev/null +++ b/src/lwip-1.4.1/src/netif/ppp/lcp.c @@ -0,0 +1,2066 @@ +/***************************************************************************** +* lcp.c - Network Link Control Protocol program file. +* +* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. +* portions Copyright (c) 1997 by Global Election Systems Inc. +* +* The authors hereby grant permission to use, copy, modify, distribute, +* and license this software and its documentation for any purpose, provided +* that existing copyright notices are retained in all copies and that this +* notice and the following disclaimer are included verbatim in any +* distributions. No written agreement, license, or royalty fee is required +* for any of the authorized uses. +* +* THIS SOFTWARE IS PROVIDED BY THE 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 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. +* +****************************************************************************** +* REVISION HISTORY +* +* 03-01-01 Marc Boucher +* Ported to lwIP. +* 97-12-01 Guy Lancaster , Global Election Systems Inc. +* Original. +*****************************************************************************/ + +/* + * lcp.c - PPP Link Control Protocol. + * + * Copyright (c) 1989 Carnegie Mellon University. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by Carnegie Mellon University. The name of the + * University may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + + +#include "lwip/opt.h" + +#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ + +#include "ppp_impl.h" +#include "pppdebug.h" + +#include "fsm.h" +#include "chap.h" +#include "magic.h" +#include "auth.h" +#include "lcp.h" + +#include + +#if PPPOE_SUPPORT +#include "netif/ppp_oe.h" +#else +#define PPPOE_MAXMTU PPP_MAXMRU +#endif + +#if 0 /* UNUSED */ +/* + * LCP-related command-line options. + */ +int lcp_echo_interval = 0; /* Interval between LCP echo-requests */ +int lcp_echo_fails = 0; /* Tolerance to unanswered echo-requests */ +bool lax_recv = 0; /* accept control chars in asyncmap */ + +static int setescape (char **); + +static option_t lcp_option_list[] = { + /* LCP options */ + /* list stripped for simplicity */ + {NULL} +}; +#endif /* UNUSED */ + +/* options */ +LinkPhase lcp_phase[NUM_PPP]; /* Phase of link session (RFC 1661) */ +static u_int lcp_echo_interval = LCP_ECHOINTERVAL; /* Interval between LCP echo-requests */ +static u_int lcp_echo_fails = LCP_MAXECHOFAILS; /* Tolerance to unanswered echo-requests */ + +/* global vars */ +static fsm lcp_fsm[NUM_PPP]; /* LCP fsm structure (global)*/ +lcp_options lcp_wantoptions[NUM_PPP]; /* Options that we want to request */ +lcp_options lcp_gotoptions[NUM_PPP]; /* Options that peer ack'd */ +lcp_options lcp_allowoptions[NUM_PPP]; /* Options we allow peer to request */ +lcp_options lcp_hisoptions[NUM_PPP]; /* Options that we ack'd */ +ext_accm xmit_accm[NUM_PPP]; /* extended transmit ACCM */ + +static u32_t lcp_echos_pending = 0; /* Number of outstanding echo msgs */ +static u32_t lcp_echo_number = 0; /* ID number of next echo frame */ +static u32_t lcp_echo_timer_running = 0; /* TRUE if a timer is running */ + +/* @todo: do we really need such a large buffer? The typical 1500 bytes seem too much. */ +static u_char nak_buffer[PPP_MRU]; /* where we construct a nak packet */ + +/* + * Callbacks for fsm code. (CI = Configuration Information) + */ +static void lcp_resetci (fsm*); /* Reset our CI */ +static int lcp_cilen (fsm*); /* Return length of our CI */ +static void lcp_addci (fsm*, u_char*, int*); /* Add our CI to pkt */ +static int lcp_ackci (fsm*, u_char*, int); /* Peer ack'd our CI */ +static int lcp_nakci (fsm*, u_char*, int); /* Peer nak'd our CI */ +static int lcp_rejci (fsm*, u_char*, int); /* Peer rej'd our CI */ +static int lcp_reqci (fsm*, u_char*, int*, int); /* Rcv peer CI */ +static void lcp_up (fsm*); /* We're UP */ +static void lcp_down (fsm*); /* We're DOWN */ +static void lcp_starting (fsm*); /* We need lower layer up */ +static void lcp_finished (fsm*); /* We need lower layer down */ +static int lcp_extcode (fsm*, int, u_char, u_char*, int); +static void lcp_rprotrej (fsm*, u_char*, int); + +/* + * routines to send LCP echos to peer + */ + +static void lcp_echo_lowerup (int); +static void lcp_echo_lowerdown (int); +static void LcpEchoTimeout (void*); +static void lcp_received_echo_reply (fsm*, int, u_char*, int); +static void LcpSendEchoRequest (fsm*); +static void LcpLinkFailure (fsm*); +static void LcpEchoCheck (fsm*); + +static fsm_callbacks lcp_callbacks = { /* LCP callback routines */ + lcp_resetci, /* Reset our Configuration Information */ + lcp_cilen, /* Length of our Configuration Information */ + lcp_addci, /* Add our Configuration Information */ + lcp_ackci, /* ACK our Configuration Information */ + lcp_nakci, /* NAK our Configuration Information */ + lcp_rejci, /* Reject our Configuration Information */ + lcp_reqci, /* Request peer's Configuration Information */ + lcp_up, /* Called when fsm reaches LS_OPENED state */ + lcp_down, /* Called when fsm leaves LS_OPENED state */ + lcp_starting, /* Called when we want the lower layer up */ + lcp_finished, /* Called when we want the lower layer down */ + NULL, /* Called when Protocol-Reject received */ + NULL, /* Retransmission is necessary */ + lcp_extcode, /* Called to handle LCP-specific codes */ + "LCP" /* String name of protocol */ +}; + +/* + * Protocol entry points. + * Some of these are called directly. + */ + +static void lcp_input (int, u_char *, int); +static void lcp_protrej (int); + +struct protent lcp_protent = { + PPP_LCP, + lcp_init, + lcp_input, + lcp_protrej, + lcp_lowerup, + lcp_lowerdown, + lcp_open, + lcp_close, +#if PPP_ADDITIONAL_CALLBACKS + lcp_printpkt, + NULL, +#endif /* PPP_ADDITIONAL_CALLBACKS */ + 1, + "LCP", +#if PPP_ADDITIONAL_CALLBACKS + NULL, + NULL, + NULL +#endif /* PPP_ADDITIONAL_CALLBACKS */ +}; + +int lcp_loopbackfail = DEFLOOPBACKFAIL; + +/* + * Length of each type of configuration option (in octets) + */ +#define CILEN_VOID 2 +#define CILEN_CHAR 3 +#define CILEN_SHORT 4 /* CILEN_VOID + sizeof(short) */ +#define CILEN_CHAP 5 /* CILEN_VOID + sizeof(short) + 1 */ +#define CILEN_LONG 6 /* CILEN_VOID + sizeof(long) */ +#define CILEN_LQR 8 /* CILEN_VOID + sizeof(short) + sizeof(long) */ +#define CILEN_CBCP 3 + +#define CODENAME(x) ((x) == CONFACK ? "ACK" : (x) == CONFNAK ? "NAK" : "REJ") + +#if 0 /* UNUSED */ +/* + * setescape - add chars to the set we escape on transmission. + */ +static int +setescape(argv) + char **argv; +{ + int n, ret; + char *p, *endp; + + p = *argv; + ret = 1; + while (*p) { + n = strtol(p, &endp, 16); + if (p == endp) { + option_error("escape parameter contains invalid hex number '%s'", p); + return 0; + } + p = endp; + if (n < 0 || n == 0x5E || n > 0xFF) { + option_error("can't escape character 0x%x", n); + ret = 0; + } else + xmit_accm[0][n >> 5] |= 1 << (n & 0x1F); + while (*p == ',' || *p == ' ') + ++p; + } + return ret; +} +#endif /* UNUSED */ + +/* + * lcp_init - Initialize LCP. + */ +void +lcp_init(int unit) +{ + fsm *f = &lcp_fsm[unit]; + lcp_options *wo = &lcp_wantoptions[unit]; + lcp_options *ao = &lcp_allowoptions[unit]; + + f->unit = unit; + f->protocol = PPP_LCP; + f->callbacks = &lcp_callbacks; + + fsm_init(f); + + wo->passive = 0; + wo->silent = 0; + wo->restart = 0; /* Set to 1 in kernels or multi-line implementations */ + wo->neg_mru = 1; + wo->mru = PPP_DEFMRU; + wo->neg_asyncmap = 1; + wo->asyncmap = 0x00000000l; /* Assume don't need to escape any ctl chars. */ + wo->neg_chap = 0; /* Set to 1 on server */ + wo->neg_upap = 0; /* Set to 1 on server */ + wo->chap_mdtype = CHAP_DIGEST_MD5; + wo->neg_magicnumber = 1; + wo->neg_pcompression = 1; + wo->neg_accompression = 1; + wo->neg_lqr = 0; /* no LQR implementation yet */ + wo->neg_cbcp = 0; + + ao->neg_mru = 1; + ao->mru = PPP_MAXMRU; + ao->neg_asyncmap = 1; + ao->asyncmap = 0x00000000l; /* Assume don't need to escape any ctl chars. */ + ao->neg_chap = (CHAP_SUPPORT != 0); + ao->chap_mdtype = CHAP_DIGEST_MD5; + ao->neg_upap = (PAP_SUPPORT != 0); + ao->neg_magicnumber = 1; + ao->neg_pcompression = 1; + ao->neg_accompression = 1; + ao->neg_lqr = 0; /* no LQR implementation yet */ + ao->neg_cbcp = (CBCP_SUPPORT != 0); + + /* + * Set transmit escape for the flag and escape characters plus anything + * set for the allowable options. + */ + memset(xmit_accm[unit], 0, sizeof(xmit_accm[0])); + xmit_accm[unit][15] = 0x60; + xmit_accm[unit][0] = (u_char)((ao->asyncmap & 0xFF)); + xmit_accm[unit][1] = (u_char)((ao->asyncmap >> 8) & 0xFF); + xmit_accm[unit][2] = (u_char)((ao->asyncmap >> 16) & 0xFF); + xmit_accm[unit][3] = (u_char)((ao->asyncmap >> 24) & 0xFF); + LCPDEBUG(LOG_INFO, ("lcp_init: xmit_accm=%X %X %X %X\n", + xmit_accm[unit][0], + xmit_accm[unit][1], + xmit_accm[unit][2], + xmit_accm[unit][3])); + + lcp_phase[unit] = PHASE_INITIALIZE; +} + + +/* + * lcp_open - LCP is allowed to come up. + */ +void +lcp_open(int unit) +{ + fsm *f = &lcp_fsm[unit]; + lcp_options *wo = &lcp_wantoptions[unit]; + + f->flags = 0; + if (wo->passive) { + f->flags |= OPT_PASSIVE; + } + if (wo->silent) { + f->flags |= OPT_SILENT; + } + fsm_open(f); + + lcp_phase[unit] = PHASE_ESTABLISH; +} + + +/* + * lcp_close - Take LCP down. + */ +void +lcp_close(int unit, char *reason) +{ + fsm *f = &lcp_fsm[unit]; + + if (lcp_phase[unit] != PHASE_DEAD) { + lcp_phase[unit] = PHASE_TERMINATE; + } + if (f->state == LS_STOPPED && f->flags & (OPT_PASSIVE|OPT_SILENT)) { + /* + * This action is not strictly according to the FSM in RFC1548, + * but it does mean that the program terminates if you do an + * lcp_close() in passive/silent mode when a connection hasn't + * been established. + */ + f->state = LS_CLOSED; + lcp_finished(f); + } else { + fsm_close(f, reason); + } +} + + +/* + * lcp_lowerup - The lower layer is up. + */ +void +lcp_lowerup(int unit) +{ + lcp_options *wo = &lcp_wantoptions[unit]; + + /* + * Don't use A/C or protocol compression on transmission, + * but accept A/C and protocol compressed packets + * if we are going to ask for A/C and protocol compression. + */ + ppp_set_xaccm(unit, &xmit_accm[unit]); + ppp_send_config(unit, PPP_MRU, 0xffffffffl, 0, 0); + ppp_recv_config(unit, PPP_MRU, 0x00000000l, + wo->neg_pcompression, wo->neg_accompression); + peer_mru[unit] = PPP_MRU; + lcp_allowoptions[unit].asyncmap = (u_long)xmit_accm[unit][0] + | ((u_long)xmit_accm[unit][1] << 8) + | ((u_long)xmit_accm[unit][2] << 16) + | ((u_long)xmit_accm[unit][3] << 24); + LCPDEBUG(LOG_INFO, ("lcp_lowerup: asyncmap=%X %X %X %X\n", + xmit_accm[unit][3], + xmit_accm[unit][2], + xmit_accm[unit][1], + xmit_accm[unit][0])); + + fsm_lowerup(&lcp_fsm[unit]); +} + + +/* + * lcp_lowerdown - The lower layer is down. + */ +void +lcp_lowerdown(int unit) +{ + fsm_lowerdown(&lcp_fsm[unit]); +} + + +/* + * lcp_input - Input LCP packet. + */ +static void +lcp_input(int unit, u_char *p, int len) +{ + fsm *f = &lcp_fsm[unit]; + + fsm_input(f, p, len); +} + + +/* + * lcp_extcode - Handle a LCP-specific code. + */ +static int +lcp_extcode(fsm *f, int code, u_char id, u_char *inp, int len) +{ + u_char *magp; + + switch( code ){ + case PROTREJ: + lcp_rprotrej(f, inp, len); + break; + + case ECHOREQ: + if (f->state != LS_OPENED) { + break; + } + LCPDEBUG(LOG_INFO, ("lcp: Echo-Request, Rcvd id %d\n", id)); + magp = inp; + PUTLONG(lcp_gotoptions[f->unit].magicnumber, magp); + fsm_sdata(f, ECHOREP, id, inp, len); + break; + + case ECHOREP: + lcp_received_echo_reply(f, id, inp, len); + break; + + case DISCREQ: + break; + + default: + return 0; + } + return 1; +} + + +/* + * lcp_rprotrej - Receive an Protocol-Reject. + * + * Figure out which protocol is rejected and inform it. + */ +static void +lcp_rprotrej(fsm *f, u_char *inp, int len) +{ + int i; + struct protent *protp; + u_short prot; + + if (len < (int)sizeof (u_short)) { + LCPDEBUG(LOG_INFO, ("lcp_rprotrej: Rcvd short Protocol-Reject packet!\n")); + return; + } + + GETSHORT(prot, inp); + + LCPDEBUG(LOG_INFO, ("lcp_rprotrej: Rcvd Protocol-Reject packet for %x!\n", prot)); + + /* + * Protocol-Reject packets received in any state other than the LCP + * LS_OPENED state SHOULD be silently discarded. + */ + if( f->state != LS_OPENED ) { + LCPDEBUG(LOG_INFO, ("Protocol-Reject discarded: LCP in state %d\n", f->state)); + return; + } + + /* + * Upcall the proper Protocol-Reject routine. + */ + for (i = 0; (protp = ppp_protocols[i]) != NULL; ++i) { + if (protp->protocol == prot && protp->enabled_flag) { + (*protp->protrej)(f->unit); + return; + } + } + + LCPDEBUG(LOG_WARNING, ("Protocol-Reject for unsupported protocol 0x%x\n", prot)); +} + + +/* + * lcp_protrej - A Protocol-Reject was received. + */ +static void +lcp_protrej(int unit) +{ + LWIP_UNUSED_ARG(unit); + /* + * Can't reject LCP! + */ + LCPDEBUG(LOG_WARNING, ("lcp_protrej: Received Protocol-Reject for LCP!\n")); + fsm_protreject(&lcp_fsm[unit]); +} + + +/* + * lcp_sprotrej - Send a Protocol-Reject for some protocol. + */ +void +lcp_sprotrej(int unit, u_char *p, int len) +{ + /* + * Send back the protocol and the information field of the + * rejected packet. We only get here if LCP is in the LS_OPENED state. + */ + + fsm_sdata(&lcp_fsm[unit], PROTREJ, ++lcp_fsm[unit].id, p, len); +} + + +/* + * lcp_resetci - Reset our CI. + */ +static void +lcp_resetci(fsm *f) +{ + lcp_wantoptions[f->unit].magicnumber = magic(); + lcp_wantoptions[f->unit].numloops = 0; + lcp_gotoptions[f->unit] = lcp_wantoptions[f->unit]; + peer_mru[f->unit] = PPP_MRU; + auth_reset(f->unit); +} + + +/* + * lcp_cilen - Return length of our CI. + */ +static int +lcp_cilen(fsm *f) +{ + lcp_options *go = &lcp_gotoptions[f->unit]; + +#define LENCIVOID(neg) ((neg) ? CILEN_VOID : 0) +#define LENCICHAP(neg) ((neg) ? CILEN_CHAP : 0) +#define LENCISHORT(neg) ((neg) ? CILEN_SHORT : 0) +#define LENCILONG(neg) ((neg) ? CILEN_LONG : 0) +#define LENCILQR(neg) ((neg) ? CILEN_LQR: 0) +#define LENCICBCP(neg) ((neg) ? CILEN_CBCP: 0) + /* + * NB: we only ask for one of CHAP and UPAP, even if we will + * accept either. + */ + return (LENCISHORT(go->neg_mru && go->mru != PPP_DEFMRU) + + LENCILONG(go->neg_asyncmap && go->asyncmap != 0xFFFFFFFFl) + + LENCICHAP(go->neg_chap) + + LENCISHORT(!go->neg_chap && go->neg_upap) + + LENCILQR(go->neg_lqr) + + LENCICBCP(go->neg_cbcp) + + LENCILONG(go->neg_magicnumber) + + LENCIVOID(go->neg_pcompression) + + LENCIVOID(go->neg_accompression)); +} + + +/* + * lcp_addci - Add our desired CIs to a packet. + */ +static void +lcp_addci(fsm *f, u_char *ucp, int *lenp) +{ + lcp_options *go = &lcp_gotoptions[f->unit]; + u_char *start_ucp = ucp; + +#define ADDCIVOID(opt, neg) \ + if (neg) { \ + LCPDEBUG(LOG_INFO, ("lcp_addci: opt=%d\n", opt)); \ + PUTCHAR(opt, ucp); \ + PUTCHAR(CILEN_VOID, ucp); \ + } +#define ADDCISHORT(opt, neg, val) \ + if (neg) { \ + LCPDEBUG(LOG_INFO, ("lcp_addci: INT opt=%d %X\n", opt, val)); \ + PUTCHAR(opt, ucp); \ + PUTCHAR(CILEN_SHORT, ucp); \ + PUTSHORT(val, ucp); \ + } +#define ADDCICHAP(opt, neg, val, digest) \ + if (neg) { \ + LCPDEBUG(LOG_INFO, ("lcp_addci: CHAP opt=%d %X\n", opt, val)); \ + PUTCHAR(opt, ucp); \ + PUTCHAR(CILEN_CHAP, ucp); \ + PUTSHORT(val, ucp); \ + PUTCHAR(digest, ucp); \ + } +#define ADDCILONG(opt, neg, val) \ + if (neg) { \ + LCPDEBUG(LOG_INFO, ("lcp_addci: L opt=%d %lX\n", opt, val)); \ + PUTCHAR(opt, ucp); \ + PUTCHAR(CILEN_LONG, ucp); \ + PUTLONG(val, ucp); \ + } +#define ADDCILQR(opt, neg, val) \ + if (neg) { \ + LCPDEBUG(LOG_INFO, ("lcp_addci: LQR opt=%d %lX\n", opt, val)); \ + PUTCHAR(opt, ucp); \ + PUTCHAR(CILEN_LQR, ucp); \ + PUTSHORT(PPP_LQR, ucp); \ + PUTLONG(val, ucp); \ + } +#define ADDCICHAR(opt, neg, val) \ + if (neg) { \ + LCPDEBUG(LOG_INFO, ("lcp_addci: CHAR opt=%d %X '%z'\n", opt, val, val)); \ + PUTCHAR(opt, ucp); \ + PUTCHAR(CILEN_CHAR, ucp); \ + PUTCHAR(val, ucp); \ + } + + ADDCISHORT(CI_MRU, go->neg_mru && go->mru != PPP_DEFMRU, go->mru); + ADDCILONG(CI_ASYNCMAP, go->neg_asyncmap && go->asyncmap != 0xFFFFFFFFl, go->asyncmap); + ADDCICHAP(CI_AUTHTYPE, go->neg_chap, PPP_CHAP, go->chap_mdtype); + ADDCISHORT(CI_AUTHTYPE, !go->neg_chap && go->neg_upap, PPP_PAP); + ADDCILQR(CI_QUALITY, go->neg_lqr, go->lqr_period); + ADDCICHAR(CI_CALLBACK, go->neg_cbcp, CBCP_OPT); + ADDCILONG(CI_MAGICNUMBER, go->neg_magicnumber, go->magicnumber); + ADDCIVOID(CI_PCOMPRESSION, go->neg_pcompression); + ADDCIVOID(CI_ACCOMPRESSION, go->neg_accompression); + + if (ucp - start_ucp != *lenp) { + /* this should never happen, because peer_mtu should be 1500 */ + LCPDEBUG(LOG_ERR, ("Bug in lcp_addci: wrong length\n")); + } +} + + +/* + * lcp_ackci - Ack our CIs. + * This should not modify any state if the Ack is bad. + * + * Returns: + * 0 - Ack was bad. + * 1 - Ack was good. + */ +static int +lcp_ackci(fsm *f, u_char *p, int len) +{ + lcp_options *go = &lcp_gotoptions[f->unit]; + u_char cilen, citype, cichar; + u_short cishort; + u32_t cilong; + + /* + * CIs must be in exactly the same order that we sent. + * Check packet length and CI length at each step. + * If we find any deviations, then this packet is bad. + */ +#define ACKCIVOID(opt, neg) \ + if (neg) { \ + if ((len -= CILEN_VOID) < 0) \ + goto bad; \ + GETCHAR(citype, p); \ + GETCHAR(cilen, p); \ + if (cilen != CILEN_VOID || citype != opt) \ + goto bad; \ + } +#define ACKCISHORT(opt, neg, val) \ + if (neg) { \ + if ((len -= CILEN_SHORT) < 0) \ + goto bad; \ + GETCHAR(citype, p); \ + GETCHAR(cilen, p); \ + if (cilen != CILEN_SHORT || citype != opt) \ + goto bad; \ + GETSHORT(cishort, p); \ + if (cishort != val) \ + goto bad; \ + } +#define ACKCICHAR(opt, neg, val) \ + if (neg) { \ + if ((len -= CILEN_CHAR) < 0) \ + goto bad; \ + GETCHAR(citype, p); \ + GETCHAR(cilen, p); \ + if (cilen != CILEN_CHAR || citype != opt) \ + goto bad; \ + GETCHAR(cichar, p); \ + if (cichar != val) \ + goto bad; \ + } +#define ACKCICHAP(opt, neg, val, digest) \ + if (neg) { \ + if ((len -= CILEN_CHAP) < 0) \ + goto bad; \ + GETCHAR(citype, p); \ + GETCHAR(cilen, p); \ + if (cilen != CILEN_CHAP || citype != opt) \ + goto bad; \ + GETSHORT(cishort, p); \ + if (cishort != val) \ + goto bad; \ + GETCHAR(cichar, p); \ + if (cichar != digest) \ + goto bad; \ + } +#define ACKCILONG(opt, neg, val) \ + if (neg) { \ + if ((len -= CILEN_LONG) < 0) \ + goto bad; \ + GETCHAR(citype, p); \ + GETCHAR(cilen, p); \ + if (cilen != CILEN_LONG || citype != opt) \ + goto bad; \ + GETLONG(cilong, p); \ + if (cilong != val) \ + goto bad; \ + } +#define ACKCILQR(opt, neg, val) \ + if (neg) { \ + if ((len -= CILEN_LQR) < 0) \ + goto bad; \ + GETCHAR(citype, p); \ + GETCHAR(cilen, p); \ + if (cilen != CILEN_LQR || citype != opt) \ + goto bad; \ + GETSHORT(cishort, p); \ + if (cishort != PPP_LQR) \ + goto bad; \ + GETLONG(cilong, p); \ + if (cilong != val) \ + goto bad; \ + } + + ACKCISHORT(CI_MRU, go->neg_mru && go->mru != PPP_DEFMRU, go->mru); + ACKCILONG(CI_ASYNCMAP, go->neg_asyncmap && go->asyncmap != 0xFFFFFFFFl, go->asyncmap); + ACKCICHAP(CI_AUTHTYPE, go->neg_chap, PPP_CHAP, go->chap_mdtype); + ACKCISHORT(CI_AUTHTYPE, !go->neg_chap && go->neg_upap, PPP_PAP); + ACKCILQR(CI_QUALITY, go->neg_lqr, go->lqr_period); + ACKCICHAR(CI_CALLBACK, go->neg_cbcp, CBCP_OPT); + ACKCILONG(CI_MAGICNUMBER, go->neg_magicnumber, go->magicnumber); + ACKCIVOID(CI_PCOMPRESSION, go->neg_pcompression); + ACKCIVOID(CI_ACCOMPRESSION, go->neg_accompression); + + /* + * If there are any remaining CIs, then this packet is bad. + */ + if (len != 0) { + goto bad; + } + LCPDEBUG(LOG_INFO, ("lcp_acki: Ack\n")); + return (1); +bad: + LCPDEBUG(LOG_WARNING, ("lcp_acki: received bad Ack!\n")); + return (0); +} + + +/* + * lcp_nakci - Peer has sent a NAK for some of our CIs. + * This should not modify any state if the Nak is bad + * or if LCP is in the LS_OPENED state. + * + * Returns: + * 0 - Nak was bad. + * 1 - Nak was good. + */ +static int +lcp_nakci(fsm *f, u_char *p, int len) +{ + lcp_options *go = &lcp_gotoptions[f->unit]; + lcp_options *wo = &lcp_wantoptions[f->unit]; + u_char citype, cichar, *next; + u_short cishort; + u32_t cilong; + lcp_options no; /* options we've seen Naks for */ + lcp_options try; /* options to request next time */ + int looped_back = 0; + int cilen; + + BZERO(&no, sizeof(no)); + try = *go; + + /* + * Any Nak'd CIs must be in exactly the same order that we sent. + * Check packet length and CI length at each step. + * If we find any deviations, then this packet is bad. + */ +#define NAKCIVOID(opt, neg, code) \ + if (go->neg && \ + len >= CILEN_VOID && \ + p[1] == CILEN_VOID && \ + p[0] == opt) { \ + len -= CILEN_VOID; \ + INCPTR(CILEN_VOID, p); \ + no.neg = 1; \ + code \ + } +#define NAKCICHAP(opt, neg, code) \ + if (go->neg && \ + len >= CILEN_CHAP && \ + p[1] == CILEN_CHAP && \ + p[0] == opt) { \ + len -= CILEN_CHAP; \ + INCPTR(2, p); \ + GETSHORT(cishort, p); \ + GETCHAR(cichar, p); \ + no.neg = 1; \ + code \ + } +#define NAKCICHAR(opt, neg, code) \ + if (go->neg && \ + len >= CILEN_CHAR && \ + p[1] == CILEN_CHAR && \ + p[0] == opt) { \ + len -= CILEN_CHAR; \ + INCPTR(2, p); \ + GETCHAR(cichar, p); \ + no.neg = 1; \ + code \ + } +#define NAKCISHORT(opt, neg, code) \ + if (go->neg && \ + len >= CILEN_SHORT && \ + p[1] == CILEN_SHORT && \ + p[0] == opt) { \ + len -= CILEN_SHORT; \ + INCPTR(2, p); \ + GETSHORT(cishort, p); \ + no.neg = 1; \ + code \ + } +#define NAKCILONG(opt, neg, code) \ + if (go->neg && \ + len >= CILEN_LONG && \ + p[1] == CILEN_LONG && \ + p[0] == opt) { \ + len -= CILEN_LONG; \ + INCPTR(2, p); \ + GETLONG(cilong, p); \ + no.neg = 1; \ + code \ + } +#define NAKCILQR(opt, neg, code) \ + if (go->neg && \ + len >= CILEN_LQR && \ + p[1] == CILEN_LQR && \ + p[0] == opt) { \ + len -= CILEN_LQR; \ + INCPTR(2, p); \ + GETSHORT(cishort, p); \ + GETLONG(cilong, p); \ + no.neg = 1; \ + code \ + } + + /* + * We don't care if they want to send us smaller packets than + * we want. Therefore, accept any MRU less than what we asked for, + * but then ignore the new value when setting the MRU in the kernel. + * If they send us a bigger MRU than what we asked, accept it, up to + * the limit of the default MRU we'd get if we didn't negotiate. + */ + if (go->neg_mru && go->mru != PPP_DEFMRU) { + NAKCISHORT(CI_MRU, neg_mru, + if (cishort <= wo->mru || cishort < PPP_DEFMRU) { + try.mru = cishort; + } + ); + } + + /* + * Add any characters they want to our (receive-side) asyncmap. + */ + if (go->neg_asyncmap && go->asyncmap != 0xFFFFFFFFl) { + NAKCILONG(CI_ASYNCMAP, neg_asyncmap, + try.asyncmap = go->asyncmap | cilong; + ); + } + + /* + * If they've nak'd our authentication-protocol, check whether + * they are proposing a different protocol, or a different + * hash algorithm for CHAP. + */ + if ((go->neg_chap || go->neg_upap) + && len >= CILEN_SHORT + && p[0] == CI_AUTHTYPE && p[1] >= CILEN_SHORT && p[1] <= len) { + cilen = p[1]; + len -= cilen; + no.neg_chap = go->neg_chap; + no.neg_upap = go->neg_upap; + INCPTR(2, p); + GETSHORT(cishort, p); + if (cishort == PPP_PAP && cilen == CILEN_SHORT) { + /* + * If we were asking for CHAP, they obviously don't want to do it. + * If we weren't asking for CHAP, then we were asking for PAP, + * in which case this Nak is bad. + */ + if (!go->neg_chap) { + goto bad; + } + try.neg_chap = 0; + + } else if (cishort == PPP_CHAP && cilen == CILEN_CHAP) { + GETCHAR(cichar, p); + if (go->neg_chap) { + /* + * We were asking for CHAP/MD5; they must want a different + * algorithm. If they can't do MD5, we'll have to stop + * asking for CHAP. + */ + if (cichar != go->chap_mdtype) { + try.neg_chap = 0; + } + } else { + /* + * Stop asking for PAP if we were asking for it. + */ + try.neg_upap = 0; + } + + } else { + /* + * We don't recognize what they're suggesting. + * Stop asking for what we were asking for. + */ + if (go->neg_chap) { + try.neg_chap = 0; + } else { + try.neg_upap = 0; + } + p += cilen - CILEN_SHORT; + } + } + + /* + * If they can't cope with our link quality protocol, we'll have + * to stop asking for LQR. We haven't got any other protocol. + * If they Nak the reporting period, take their value XXX ? + */ + NAKCILQR(CI_QUALITY, neg_lqr, + if (cishort != PPP_LQR) { + try.neg_lqr = 0; + } else { + try.lqr_period = cilong; + } + ); + + /* + * Only implementing CBCP...not the rest of the callback options + */ + NAKCICHAR(CI_CALLBACK, neg_cbcp, + try.neg_cbcp = 0; + ); + + /* + * Check for a looped-back line. + */ + NAKCILONG(CI_MAGICNUMBER, neg_magicnumber, + try.magicnumber = magic(); + looped_back = 1; + ); + + /* + * Peer shouldn't send Nak for protocol compression or + * address/control compression requests; they should send + * a Reject instead. If they send a Nak, treat it as a Reject. + */ + NAKCIVOID(CI_PCOMPRESSION, neg_pcompression, + try.neg_pcompression = 0; + ); + NAKCIVOID(CI_ACCOMPRESSION, neg_accompression, + try.neg_accompression = 0; + ); + + /* + * There may be remaining CIs, if the peer is requesting negotiation + * on an option that we didn't include in our request packet. + * If we see an option that we requested, or one we've already seen + * in this packet, then this packet is bad. + * If we wanted to respond by starting to negotiate on the requested + * option(s), we could, but we don't, because except for the + * authentication type and quality protocol, if we are not negotiating + * an option, it is because we were told not to. + * For the authentication type, the Nak from the peer means + * `let me authenticate myself with you' which is a bit pointless. + * For the quality protocol, the Nak means `ask me to send you quality + * reports', but if we didn't ask for them, we don't want them. + * An option we don't recognize represents the peer asking to + * negotiate some option we don't support, so ignore it. + */ + while (len > CILEN_VOID) { + GETCHAR(citype, p); + GETCHAR(cilen, p); + if (cilen < CILEN_VOID || (len -= cilen) < 0) { + goto bad; + } + next = p + cilen - 2; + + switch (citype) { + case CI_MRU: + if ((go->neg_mru && go->mru != PPP_DEFMRU) + || no.neg_mru || cilen != CILEN_SHORT) { + goto bad; + } + GETSHORT(cishort, p); + if (cishort < PPP_DEFMRU) { + try.mru = cishort; + } + break; + case CI_ASYNCMAP: + if ((go->neg_asyncmap && go->asyncmap != 0xFFFFFFFFl) + || no.neg_asyncmap || cilen != CILEN_LONG) { + goto bad; + } + break; + case CI_AUTHTYPE: + if (go->neg_chap || no.neg_chap || go->neg_upap || no.neg_upap) { + goto bad; + } + break; + case CI_MAGICNUMBER: + if (go->neg_magicnumber || no.neg_magicnumber || + cilen != CILEN_LONG) { + goto bad; + } + break; + case CI_PCOMPRESSION: + if (go->neg_pcompression || no.neg_pcompression + || cilen != CILEN_VOID) { + goto bad; + } + break; + case CI_ACCOMPRESSION: + if (go->neg_accompression || no.neg_accompression + || cilen != CILEN_VOID) { + goto bad; + } + break; + case CI_QUALITY: + if (go->neg_lqr || no.neg_lqr || cilen != CILEN_LQR) { + goto bad; + } + break; + } + p = next; + } + + /* If there is still anything left, this packet is bad. */ + if (len != 0) { + goto bad; + } + + /* + * OK, the Nak is good. Now we can update state. + */ + if (f->state != LS_OPENED) { + if (looped_back) { + if (++try.numloops >= lcp_loopbackfail) { + LCPDEBUG(LOG_NOTICE, ("Serial line is looped back.\n")); + lcp_close(f->unit, "Loopback detected"); + } + } else { + try.numloops = 0; + } + *go = try; + } + + return 1; + +bad: + LCPDEBUG(LOG_WARNING, ("lcp_nakci: received bad Nak!\n")); + return 0; +} + + +/* + * lcp_rejci - Peer has Rejected some of our CIs. + * This should not modify any state if the Reject is bad + * or if LCP is in the LS_OPENED state. + * + * Returns: + * 0 - Reject was bad. + * 1 - Reject was good. + */ +static int +lcp_rejci(fsm *f, u_char *p, int len) +{ + lcp_options *go = &lcp_gotoptions[f->unit]; + u_char cichar; + u_short cishort; + u32_t cilong; + lcp_options try; /* options to request next time */ + + try = *go; + + /* + * Any Rejected CIs must be in exactly the same order that we sent. + * Check packet length and CI length at each step. + * If we find any deviations, then this packet is bad. + */ +#define REJCIVOID(opt, neg) \ + if (go->neg && \ + len >= CILEN_VOID && \ + p[1] == CILEN_VOID && \ + p[0] == opt) { \ + len -= CILEN_VOID; \ + INCPTR(CILEN_VOID, p); \ + try.neg = 0; \ + LCPDEBUG(LOG_INFO, ("lcp_rejci: void opt %d rejected\n", opt)); \ + } +#define REJCISHORT(opt, neg, val) \ + if (go->neg && \ + len >= CILEN_SHORT && \ + p[1] == CILEN_SHORT && \ + p[0] == opt) { \ + len -= CILEN_SHORT; \ + INCPTR(2, p); \ + GETSHORT(cishort, p); \ + /* Check rejected value. */ \ + if (cishort != val) { \ + goto bad; \ + } \ + try.neg = 0; \ + LCPDEBUG(LOG_INFO, ("lcp_rejci: short opt %d rejected\n", opt)); \ + } +#define REJCICHAP(opt, neg, val, digest) \ + if (go->neg && \ + len >= CILEN_CHAP && \ + p[1] == CILEN_CHAP && \ + p[0] == opt) { \ + len -= CILEN_CHAP; \ + INCPTR(2, p); \ + GETSHORT(cishort, p); \ + GETCHAR(cichar, p); \ + /* Check rejected value. */ \ + if (cishort != val || cichar != digest) { \ + goto bad; \ + } \ + try.neg = 0; \ + try.neg_upap = 0; \ + LCPDEBUG(LOG_INFO, ("lcp_rejci: chap opt %d rejected\n", opt)); \ + } +#define REJCILONG(opt, neg, val) \ + if (go->neg && \ + len >= CILEN_LONG && \ + p[1] == CILEN_LONG && \ + p[0] == opt) { \ + len -= CILEN_LONG; \ + INCPTR(2, p); \ + GETLONG(cilong, p); \ + /* Check rejected value. */ \ + if (cilong != val) { \ + goto bad; \ + } \ + try.neg = 0; \ + LCPDEBUG(LOG_INFO, ("lcp_rejci: long opt %d rejected\n", opt)); \ + } +#define REJCILQR(opt, neg, val) \ + if (go->neg && \ + len >= CILEN_LQR && \ + p[1] == CILEN_LQR && \ + p[0] == opt) { \ + len -= CILEN_LQR; \ + INCPTR(2, p); \ + GETSHORT(cishort, p); \ + GETLONG(cilong, p); \ + /* Check rejected value. */ \ + if (cishort != PPP_LQR || cilong != val) { \ + goto bad; \ + } \ + try.neg = 0; \ + LCPDEBUG(LOG_INFO, ("lcp_rejci: LQR opt %d rejected\n", opt)); \ + } +#define REJCICBCP(opt, neg, val) \ + if (go->neg && \ + len >= CILEN_CBCP && \ + p[1] == CILEN_CBCP && \ + p[0] == opt) { \ + len -= CILEN_CBCP; \ + INCPTR(2, p); \ + GETCHAR(cichar, p); \ + /* Check rejected value. */ \ + if (cichar != val) { \ + goto bad; \ + } \ + try.neg = 0; \ + LCPDEBUG(LOG_INFO, ("lcp_rejci: Callback opt %d rejected\n", opt)); \ + } + + REJCISHORT(CI_MRU, neg_mru, go->mru); + REJCILONG(CI_ASYNCMAP, neg_asyncmap, go->asyncmap); + REJCICHAP(CI_AUTHTYPE, neg_chap, PPP_CHAP, go->chap_mdtype); + if (!go->neg_chap) { + REJCISHORT(CI_AUTHTYPE, neg_upap, PPP_PAP); + } + REJCILQR(CI_QUALITY, neg_lqr, go->lqr_period); + REJCICBCP(CI_CALLBACK, neg_cbcp, CBCP_OPT); + REJCILONG(CI_MAGICNUMBER, neg_magicnumber, go->magicnumber); + REJCIVOID(CI_PCOMPRESSION, neg_pcompression); + REJCIVOID(CI_ACCOMPRESSION, neg_accompression); + + /* + * If there are any remaining CIs, then this packet is bad. + */ + if (len != 0) { + goto bad; + } + /* + * Now we can update state. + */ + if (f->state != LS_OPENED) { + *go = try; + } + return 1; + +bad: + LCPDEBUG(LOG_WARNING, ("lcp_rejci: received bad Reject!\n")); + return 0; +} + + +/* + * lcp_reqci - Check the peer's requested CIs and send appropriate response. + * + * Returns: CONFACK, CONFNAK or CONFREJ and input packet modified + * appropriately. If reject_if_disagree is non-zero, doesn't return + * CONFNAK; returns CONFREJ if it can't return CONFACK. + */ +static int +lcp_reqci(fsm *f, + u_char *inp, /* Requested CIs */ + int *lenp, /* Length of requested CIs */ + int reject_if_disagree) +{ + lcp_options *go = &lcp_gotoptions[f->unit]; + lcp_options *ho = &lcp_hisoptions[f->unit]; + lcp_options *ao = &lcp_allowoptions[f->unit]; + u_char *cip, *next; /* Pointer to current and next CIs */ + int cilen, citype; /* Parsed len, type */ + u_char cichar; /* Parsed char value */ + u_short cishort; /* Parsed short value */ + u32_t cilong; /* Parse long value */ + int rc = CONFACK; /* Final packet return code */ + int orc; /* Individual option return code */ + u_char *p; /* Pointer to next char to parse */ + u_char *rejp; /* Pointer to next char in reject frame */ + u_char *nakp; /* Pointer to next char in Nak frame */ + int l = *lenp; /* Length left */ +#if TRACELCP > 0 + char traceBuf[80]; + size_t traceNdx = 0; +#endif + + /* + * Reset all his options. + */ + BZERO(ho, sizeof(*ho)); + + /* + * Process all his options. + */ + next = inp; + nakp = nak_buffer; + rejp = inp; + while (l) { + orc = CONFACK; /* Assume success */ + cip = p = next; /* Remember begining of CI */ + if (l < 2 || /* Not enough data for CI header or */ + p[1] < 2 || /* CI length too small or */ + p[1] > l) { /* CI length too big? */ + LCPDEBUG(LOG_WARNING, ("lcp_reqci: bad CI length!\n")); + orc = CONFREJ; /* Reject bad CI */ + cilen = l; /* Reject till end of packet */ + l = 0; /* Don't loop again */ + citype = 0; + goto endswitch; + } + GETCHAR(citype, p); /* Parse CI type */ + GETCHAR(cilen, p); /* Parse CI length */ + l -= cilen; /* Adjust remaining length */ + next += cilen; /* Step to next CI */ + + switch (citype) { /* Check CI type */ + case CI_MRU: + if (!ao->neg_mru) { /* Allow option? */ + LCPDEBUG(LOG_INFO, ("lcp_reqci: Reject MRU - not allowed\n")); + orc = CONFREJ; /* Reject CI */ + break; + } else if (cilen != CILEN_SHORT) { /* Check CI length */ + LCPDEBUG(LOG_INFO, ("lcp_reqci: Reject MRU - bad length\n")); + orc = CONFREJ; /* Reject CI */ + break; + } + GETSHORT(cishort, p); /* Parse MRU */ + + /* + * He must be able to receive at least our minimum. + * No need to check a maximum. If he sends a large number, + * we'll just ignore it. + */ + if (cishort < PPP_MINMRU) { + LCPDEBUG(LOG_INFO, ("lcp_reqci: Nak - MRU too small\n")); + orc = CONFNAK; /* Nak CI */ + PUTCHAR(CI_MRU, nakp); + PUTCHAR(CILEN_SHORT, nakp); + PUTSHORT(PPP_MINMRU, nakp); /* Give him a hint */ + break; + } + ho->neg_mru = 1; /* Remember he sent MRU */ + ho->mru = cishort; /* And remember value */ +#if TRACELCP > 0 + snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " MRU %d", cishort); + traceNdx = strlen(traceBuf); +#endif + break; + + case CI_ASYNCMAP: + if (!ao->neg_asyncmap) { + LCPDEBUG(LOG_INFO, ("lcp_reqci: Reject ASYNCMAP not allowed\n")); + orc = CONFREJ; + break; + } else if (cilen != CILEN_LONG) { + LCPDEBUG(LOG_INFO, ("lcp_reqci: Reject ASYNCMAP bad length\n")); + orc = CONFREJ; + break; + } + GETLONG(cilong, p); + + /* + * Asyncmap must have set at least the bits + * which are set in lcp_allowoptions[unit].asyncmap. + */ + if ((ao->asyncmap & ~cilong) != 0) { + LCPDEBUG(LOG_INFO, ("lcp_reqci: Nak ASYNCMAP %lX missing %lX\n", + cilong, ao->asyncmap)); + orc = CONFNAK; + PUTCHAR(CI_ASYNCMAP, nakp); + PUTCHAR(CILEN_LONG, nakp); + PUTLONG(ao->asyncmap | cilong, nakp); + break; + } + ho->neg_asyncmap = 1; + ho->asyncmap = cilong; +#if TRACELCP > 0 + snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " ASYNCMAP=%lX", cilong); + traceNdx = strlen(traceBuf); +#endif + break; + + case CI_AUTHTYPE: + if (cilen < CILEN_SHORT) { + LCPDEBUG(LOG_INFO, ("lcp_reqci: Reject AUTHTYPE missing arg\n")); + orc = CONFREJ; + break; + } else if (!(ao->neg_upap || ao->neg_chap)) { + /* + * Reject the option if we're not willing to authenticate. + */ + LCPDEBUG(LOG_INFO, ("lcp_reqci: Reject AUTHTYPE not allowed\n")); + orc = CONFREJ; + break; + } + GETSHORT(cishort, p); + + /* + * Authtype must be UPAP or CHAP. + * + * Note: if both ao->neg_upap and ao->neg_chap are set, + * and the peer sends a Configure-Request with two + * authenticate-protocol requests, one for CHAP and one + * for UPAP, then we will reject the second request. + * Whether we end up doing CHAP or UPAP depends then on + * the ordering of the CIs in the peer's Configure-Request. + */ + + if (cishort == PPP_PAP) { + if (ho->neg_chap) { /* we've already accepted CHAP */ + LCPDEBUG(LOG_WARNING, ("lcp_reqci: Reject AUTHTYPE PAP already accepted\n")); + orc = CONFREJ; + break; + } else if (cilen != CILEN_SHORT) { + LCPDEBUG(LOG_WARNING, ("lcp_reqci: Reject AUTHTYPE PAP bad len\n")); + orc = CONFREJ; + break; + } + if (!ao->neg_upap) { /* we don't want to do PAP */ + LCPDEBUG(LOG_WARNING, ("lcp_reqci: Nak AUTHTYPE PAP not allowed\n")); + orc = CONFNAK; /* NAK it and suggest CHAP */ + PUTCHAR(CI_AUTHTYPE, nakp); + PUTCHAR(CILEN_CHAP, nakp); + PUTSHORT(PPP_CHAP, nakp); + PUTCHAR(ao->chap_mdtype, nakp); + break; + } + ho->neg_upap = 1; +#if TRACELCP > 0 + snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " PAP (%X)", cishort); + traceNdx = strlen(traceBuf); +#endif + break; + } + if (cishort == PPP_CHAP) { + if (ho->neg_upap) { /* we've already accepted PAP */ + LCPDEBUG(LOG_WARNING, ("lcp_reqci: Reject AUTHTYPE CHAP accepted PAP\n")); + orc = CONFREJ; + break; + } else if (cilen != CILEN_CHAP) { + LCPDEBUG(LOG_WARNING, ("lcp_reqci: Reject AUTHTYPE CHAP bad len\n")); + orc = CONFREJ; + break; + } + if (!ao->neg_chap) { /* we don't want to do CHAP */ + LCPDEBUG(LOG_WARNING, ("lcp_reqci: Nak AUTHTYPE CHAP not allowed\n")); + orc = CONFNAK; /* NAK it and suggest PAP */ + PUTCHAR(CI_AUTHTYPE, nakp); + PUTCHAR(CILEN_SHORT, nakp); + PUTSHORT(PPP_PAP, nakp); + break; + } + GETCHAR(cichar, p); /* get digest type*/ + if (cichar != CHAP_DIGEST_MD5 +#if MSCHAP_SUPPORT + && cichar != CHAP_MICROSOFT +#endif + ) { + LCPDEBUG(LOG_WARNING, ("lcp_reqci: Nak AUTHTYPE CHAP digest=%d\n", (int)cichar)); + orc = CONFNAK; + PUTCHAR(CI_AUTHTYPE, nakp); + PUTCHAR(CILEN_CHAP, nakp); + PUTSHORT(PPP_CHAP, nakp); + PUTCHAR(ao->chap_mdtype, nakp); + break; + } +#if TRACELCP > 0 + snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " CHAP %X,%d", cishort, (int)cichar); + traceNdx = strlen(traceBuf); +#endif + ho->chap_mdtype = cichar; /* save md type */ + ho->neg_chap = 1; + break; + } + + /* + * We don't recognize the protocol they're asking for. + * Nak it with something we're willing to do. + * (At this point we know ao->neg_upap || ao->neg_chap.) + */ + orc = CONFNAK; + PUTCHAR(CI_AUTHTYPE, nakp); + if (ao->neg_chap) { + LCPDEBUG(LOG_WARNING, ("lcp_reqci: Nak AUTHTYPE %d req CHAP\n", cishort)); + PUTCHAR(CILEN_CHAP, nakp); + PUTSHORT(PPP_CHAP, nakp); + PUTCHAR(ao->chap_mdtype, nakp); + } else { + LCPDEBUG(LOG_WARNING, ("lcp_reqci: Nak AUTHTYPE %d req PAP\n", cishort)); + PUTCHAR(CILEN_SHORT, nakp); + PUTSHORT(PPP_PAP, nakp); + } + break; + + case CI_QUALITY: + GETSHORT(cishort, p); + GETLONG(cilong, p); +#if TRACELCP > 0 + snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " QUALITY (%x %x)", cishort, (unsigned int) cilong); + traceNdx = strlen(traceBuf); +#endif + + if (!ao->neg_lqr || + cilen != CILEN_LQR) { + orc = CONFREJ; + break; + } + + /* + * Check the protocol and the reporting period. + * XXX When should we Nak this, and what with? + */ + if (cishort != PPP_LQR) { + orc = CONFNAK; + PUTCHAR(CI_QUALITY, nakp); + PUTCHAR(CILEN_LQR, nakp); + PUTSHORT(PPP_LQR, nakp); + PUTLONG(ao->lqr_period, nakp); + break; + } + break; + + case CI_MAGICNUMBER: + if (!(ao->neg_magicnumber || go->neg_magicnumber) || + cilen != CILEN_LONG) { + orc = CONFREJ; + break; + } + GETLONG(cilong, p); +#if TRACELCP > 0 + snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " MAGICNUMBER (%lX)", cilong); + traceNdx = strlen(traceBuf); +#endif + + /* + * He must have a different magic number. + */ + if (go->neg_magicnumber && + cilong == go->magicnumber) { + cilong = magic(); /* Don't put magic() inside macro! */ + orc = CONFNAK; + PUTCHAR(CI_MAGICNUMBER, nakp); + PUTCHAR(CILEN_LONG, nakp); + PUTLONG(cilong, nakp); + break; + } + ho->neg_magicnumber = 1; + ho->magicnumber = cilong; + break; + + + case CI_PCOMPRESSION: +#if TRACELCP > 0 + snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " PCOMPRESSION"); + traceNdx = strlen(traceBuf); +#endif + if (!ao->neg_pcompression || + cilen != CILEN_VOID) { + orc = CONFREJ; + break; + } + ho->neg_pcompression = 1; + break; + + case CI_ACCOMPRESSION: +#if TRACELCP > 0 + snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " ACCOMPRESSION"); + traceNdx = strlen(traceBuf); +#endif + if (!ao->neg_accompression || + cilen != CILEN_VOID) { + orc = CONFREJ; + break; + } + ho->neg_accompression = 1; + break; + + case CI_MRRU: +#if TRACELCP > 0 + snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " CI_MRRU"); + traceNdx = strlen(traceBuf); +#endif + orc = CONFREJ; + break; + + case CI_SSNHF: +#if TRACELCP > 0 + snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " CI_SSNHF"); + traceNdx = strlen(traceBuf); +#endif + orc = CONFREJ; + break; + + case CI_EPDISC: +#if TRACELCP > 0 + snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " CI_EPDISC"); + traceNdx = strlen(traceBuf); +#endif + orc = CONFREJ; + break; + + default: +#if TRACELCP + snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " unknown %d", citype); + traceNdx = strlen(traceBuf); +#endif + orc = CONFREJ; + break; + } + + endswitch: +#if TRACELCP + if (traceNdx >= 80 - 32) { + LCPDEBUG(LOG_INFO, ("lcp_reqci: rcvd%s\n", traceBuf)); + traceNdx = 0; + } +#endif + if (orc == CONFACK && /* Good CI */ + rc != CONFACK) { /* but prior CI wasnt? */ + continue; /* Don't send this one */ + } + + if (orc == CONFNAK) { /* Nak this CI? */ + if (reject_if_disagree /* Getting fed up with sending NAKs? */ + && citype != CI_MAGICNUMBER) { + orc = CONFREJ; /* Get tough if so */ + } else { + if (rc == CONFREJ) { /* Rejecting prior CI? */ + continue; /* Don't send this one */ + } + rc = CONFNAK; + } + } + if (orc == CONFREJ) { /* Reject this CI */ + rc = CONFREJ; + if (cip != rejp) { /* Need to move rejected CI? */ + BCOPY(cip, rejp, cilen); /* Move it */ + } + INCPTR(cilen, rejp); /* Update output pointer */ + } + } + + /* + * If we wanted to send additional NAKs (for unsent CIs), the + * code would go here. The extra NAKs would go at *nakp. + * At present there are no cases where we want to ask the + * peer to negotiate an option. + */ + + switch (rc) { + case CONFACK: + *lenp = (int)(next - inp); + break; + case CONFNAK: + /* + * Copy the Nak'd options from the nak_buffer to the caller's buffer. + */ + *lenp = (int)(nakp - nak_buffer); + BCOPY(nak_buffer, inp, *lenp); + break; + case CONFREJ: + *lenp = (int)(rejp - inp); + break; + } + +#if TRACELCP > 0 + if (traceNdx > 0) { + LCPDEBUG(LOG_INFO, ("lcp_reqci: %s\n", traceBuf)); + } +#endif + LCPDEBUG(LOG_INFO, ("lcp_reqci: returning CONF%s.\n", CODENAME(rc))); + return (rc); /* Return final code */ +} + + +/* + * lcp_up - LCP has come UP. + */ +static void +lcp_up(fsm *f) +{ + lcp_options *wo = &lcp_wantoptions[f->unit]; + lcp_options *ho = &lcp_hisoptions[f->unit]; + lcp_options *go = &lcp_gotoptions[f->unit]; + lcp_options *ao = &lcp_allowoptions[f->unit]; + + if (!go->neg_magicnumber) { + go->magicnumber = 0; + } + if (!ho->neg_magicnumber) { + ho->magicnumber = 0; + } + + /* + * Set our MTU to the smaller of the MTU we wanted and + * the MRU our peer wanted. If we negotiated an MRU, + * set our MRU to the larger of value we wanted and + * the value we got in the negotiation. + */ + ppp_send_config(f->unit, LWIP_MIN(ao->mru, (ho->neg_mru? ho->mru: PPP_MRU)), + (ho->neg_asyncmap? ho->asyncmap: 0xffffffffl), + ho->neg_pcompression, ho->neg_accompression); + /* + * If the asyncmap hasn't been negotiated, we really should + * set the receive asyncmap to ffffffff, but we set it to 0 + * for backwards contemptibility. + */ + ppp_recv_config(f->unit, (go->neg_mru? LWIP_MAX(wo->mru, go->mru): PPP_MRU), + (go->neg_asyncmap? go->asyncmap: 0x00000000), + go->neg_pcompression, go->neg_accompression); + + if (ho->neg_mru) { + peer_mru[f->unit] = ho->mru; + } + + lcp_echo_lowerup(f->unit); /* Enable echo messages */ + + link_established(f->unit); /* The link is up; authenticate now */ +} + + +/* + * lcp_down - LCP has gone DOWN. + * + * Alert other protocols. + */ +static void +lcp_down(fsm *f) +{ + lcp_options *go = &lcp_gotoptions[f->unit]; + + lcp_echo_lowerdown(f->unit); + + link_down(f->unit); + + ppp_send_config(f->unit, PPP_MRU, 0xffffffffl, 0, 0); + ppp_recv_config(f->unit, PPP_MRU, + (go->neg_asyncmap? go->asyncmap: 0x00000000), + go->neg_pcompression, go->neg_accompression); + peer_mru[f->unit] = PPP_MRU; +} + + +/* + * lcp_starting - LCP needs the lower layer up. + */ +static void +lcp_starting(fsm *f) +{ + link_required(f->unit); /* lwip: currently does nothing */ +} + + +/* + * lcp_finished - LCP has finished with the lower layer. + */ +static void +lcp_finished(fsm *f) +{ + link_terminated(f->unit); /* we are finished with the link */ +} + + +#if PPP_ADDITIONAL_CALLBACKS +/* + * print_string - print a readable representation of a string using + * printer. + */ +static void +print_string( char *p, int len, void (*printer) (void *, char *, ...), void *arg) +{ + int c; + + printer(arg, "\""); + for (; len > 0; --len) { + c = *p++; + if (' ' <= c && c <= '~') { + if (c == '\\' || c == '"') { + printer(arg, "\\"); + } + printer(arg, "%c", c); + } else { + switch (c) { + case '\n': + printer(arg, "\\n"); + break; + case '\r': + printer(arg, "\\r"); + break; + case '\t': + printer(arg, "\\t"); + break; + default: + printer(arg, "\\%.3o", c); + } + } + } + printer(arg, "\""); +} + + +/* + * lcp_printpkt - print the contents of an LCP packet. + */ +static char *lcp_codenames[] = { + "ConfReq", "ConfAck", "ConfNak", "ConfRej", + "TermReq", "TermAck", "CodeRej", "ProtRej", + "EchoReq", "EchoRep", "DiscReq" +}; + +static int +lcp_printpkt( u_char *p, int plen, void (*printer) (void *, char *, ...), void *arg) +{ + int code, id, len, olen; + u_char *pstart, *optend; + u_short cishort; + u32_t cilong; + + if (plen < HEADERLEN) { + return 0; + } + pstart = p; + GETCHAR(code, p); + GETCHAR(id, p); + GETSHORT(len, p); + if (len < HEADERLEN || len > plen) { + return 0; + } + + if (code >= 1 && code <= sizeof(lcp_codenames) / sizeof(char *)) { + printer(arg, " %s", lcp_codenames[code-1]); + } else { + printer(arg, " code=0x%x", code); + } + printer(arg, " id=0x%x", id); + len -= HEADERLEN; + switch (code) { + case CONFREQ: + case CONFACK: + case CONFNAK: + case CONFREJ: + /* print option list */ + while (len >= 2) { + GETCHAR(code, p); + GETCHAR(olen, p); + p -= 2; + if (olen < 2 || olen > len) { + break; + } + printer(arg, " <"); + len -= olen; + optend = p + olen; + switch (code) { + case CI_MRU: + if (olen == CILEN_SHORT) { + p += 2; + GETSHORT(cishort, p); + printer(arg, "mru %d", cishort); + } + break; + case CI_ASYNCMAP: + if (olen == CILEN_LONG) { + p += 2; + GETLONG(cilong, p); + printer(arg, "asyncmap 0x%lx", cilong); + } + break; + case CI_AUTHTYPE: + if (olen >= CILEN_SHORT) { + p += 2; + printer(arg, "auth "); + GETSHORT(cishort, p); + switch (cishort) { + case PPP_PAP: + printer(arg, "pap"); + break; + case PPP_CHAP: + printer(arg, "chap"); + break; + default: + printer(arg, "0x%x", cishort); + } + } + break; + case CI_QUALITY: + if (olen >= CILEN_SHORT) { + p += 2; + printer(arg, "quality "); + GETSHORT(cishort, p); + switch (cishort) { + case PPP_LQR: + printer(arg, "lqr"); + break; + default: + printer(arg, "0x%x", cishort); + } + } + break; + case CI_CALLBACK: + if (olen >= CILEN_CHAR) { + p += 2; + printer(arg, "callback "); + GETSHORT(cishort, p); + switch (cishort) { + case CBCP_OPT: + printer(arg, "CBCP"); + break; + default: + printer(arg, "0x%x", cishort); + } + } + break; + case CI_MAGICNUMBER: + if (olen == CILEN_LONG) { + p += 2; + GETLONG(cilong, p); + printer(arg, "magic 0x%x", cilong); + } + break; + case CI_PCOMPRESSION: + if (olen == CILEN_VOID) { + p += 2; + printer(arg, "pcomp"); + } + break; + case CI_ACCOMPRESSION: + if (olen == CILEN_VOID) { + p += 2; + printer(arg, "accomp"); + } + break; + } + while (p < optend) { + GETCHAR(code, p); + printer(arg, " %.2x", code); + } + printer(arg, ">"); + } + break; + + case TERMACK: + case TERMREQ: + if (len > 0 && *p >= ' ' && *p < 0x7f) { + printer(arg, " "); + print_string((char*)p, len, printer, arg); + p += len; + len = 0; + } + break; + + case ECHOREQ: + case ECHOREP: + case DISCREQ: + if (len >= 4) { + GETLONG(cilong, p); + printer(arg, " magic=0x%x", cilong); + p += 4; + len -= 4; + } + break; + } + + /* print the rest of the bytes in the packet */ + for (; len > 0; --len) { + GETCHAR(code, p); + printer(arg, " %.2x", code); + } + + return (int)(p - pstart); +} +#endif /* PPP_ADDITIONAL_CALLBACKS */ + +/* + * Time to shut down the link because there is nothing out there. + */ +static void +LcpLinkFailure (fsm *f) +{ + if (f->state == LS_OPENED) { + LCPDEBUG(LOG_INFO, ("No response to %d echo-requests\n", lcp_echos_pending)); + LCPDEBUG(LOG_NOTICE, ("Serial link appears to be disconnected.\n")); + lcp_close(f->unit, "Peer not responding"); + } +} + +/* + * Timer expired for the LCP echo requests from this process. + */ +static void +LcpEchoCheck (fsm *f) +{ + LcpSendEchoRequest (f); + + /* + * Start the timer for the next interval. + */ + LWIP_ASSERT("lcp_echo_timer_running == 0", lcp_echo_timer_running == 0); + + TIMEOUT (LcpEchoTimeout, f, lcp_echo_interval); + lcp_echo_timer_running = 1; +} + +/* + * LcpEchoTimeout - Timer expired on the LCP echo + */ +static void +LcpEchoTimeout (void *arg) +{ + if (lcp_echo_timer_running != 0) { + lcp_echo_timer_running = 0; + LcpEchoCheck ((fsm *) arg); + } +} + +/* + * LcpEchoReply - LCP has received a reply to the echo + */ +static void +lcp_received_echo_reply (fsm *f, int id, u_char *inp, int len) +{ + u32_t magic; + + LWIP_UNUSED_ARG(id); + + /* Check the magic number - don't count replies from ourselves. */ + if (len < 4) { + LCPDEBUG(LOG_WARNING, ("lcp: received short Echo-Reply, length %d\n", len)); + return; + } + GETLONG(magic, inp); + if (lcp_gotoptions[f->unit].neg_magicnumber && magic == lcp_gotoptions[f->unit].magicnumber) { + LCPDEBUG(LOG_WARNING, ("appear to have received our own echo-reply!\n")); + return; + } + + /* Reset the number of outstanding echo frames */ + lcp_echos_pending = 0; +} + +/* + * LcpSendEchoRequest - Send an echo request frame to the peer + */ +static void +LcpSendEchoRequest (fsm *f) +{ + u32_t lcp_magic; + u_char pkt[4], *pktp; + + /* + * Detect the failure of the peer at this point. + */ + if (lcp_echo_fails != 0) { + if (lcp_echos_pending >= lcp_echo_fails) { + LcpLinkFailure(f); + lcp_echos_pending = 0; + } + } + + /* + * Make and send the echo request frame. + */ + if (f->state == LS_OPENED) { + lcp_magic = lcp_gotoptions[f->unit].magicnumber; + pktp = pkt; + PUTLONG(lcp_magic, pktp); + fsm_sdata(f, ECHOREQ, (u_char)(lcp_echo_number++ & 0xFF), pkt, (int)(pktp - pkt)); + ++lcp_echos_pending; + } +} + +/* + * lcp_echo_lowerup - Start the timer for the LCP frame + */ + +static void +lcp_echo_lowerup (int unit) +{ + fsm *f = &lcp_fsm[unit]; + + /* Clear the parameters for generating echo frames */ + lcp_echos_pending = 0; + lcp_echo_number = 0; + lcp_echo_timer_running = 0; + + /* If a timeout interval is specified then start the timer */ + if (lcp_echo_interval != 0) { + LcpEchoCheck (f); + } +} + +/* + * lcp_echo_lowerdown - Stop the timer for the LCP frame + */ + +static void +lcp_echo_lowerdown (int unit) +{ + fsm *f = &lcp_fsm[unit]; + + if (lcp_echo_timer_running != 0) { + UNTIMEOUT (LcpEchoTimeout, f); + lcp_echo_timer_running = 0; + } +} + +#endif /* PPP_SUPPORT */ diff --git a/src/lwip-1.4.1/src/netif/ppp/lcp.h b/src/lwip-1.4.1/src/netif/ppp/lcp.h new file mode 100644 index 0000000..b9201ee --- /dev/null +++ b/src/lwip-1.4.1/src/netif/ppp/lcp.h @@ -0,0 +1,151 @@ +/***************************************************************************** +* lcp.h - Network Link Control Protocol header file. +* +* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. +* portions Copyright (c) 1997 Global Election Systems Inc. +* +* The authors hereby grant permission to use, copy, modify, distribute, +* and license this software and its documentation for any purpose, provided +* that existing copyright notices are retained in all copies and that this +* notice and the following disclaimer are included verbatim in any +* distributions. No written agreement, license, or royalty fee is required +* for any of the authorized uses. +* +* THIS SOFTWARE IS PROVIDED BY THE 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 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. +* +****************************************************************************** +* REVISION HISTORY +* +* 03-01-01 Marc Boucher +* Ported to lwIP. +* 97-11-05 Guy Lancaster , Global Election Systems Inc. +* Original derived from BSD codes. +*****************************************************************************/ +/* + * lcp.h - Link Control Protocol definitions. + * + * Copyright (c) 1989 Carnegie Mellon University. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by Carnegie Mellon University. The name of the + * University may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * $Id: lcp.h,v 1.4 2010/01/18 20:49:43 goldsimon Exp $ + */ + +#ifndef LCP_H +#define LCP_H +/* + * Options. + */ +#define CI_MRU 1 /* Maximum Receive Unit */ +#define CI_ASYNCMAP 2 /* Async Control Character Map */ +#define CI_AUTHTYPE 3 /* Authentication Type */ +#define CI_QUALITY 4 /* Quality Protocol */ +#define CI_MAGICNUMBER 5 /* Magic Number */ +#define CI_PCOMPRESSION 7 /* Protocol Field Compression */ +#define CI_ACCOMPRESSION 8 /* Address/Control Field Compression */ +#define CI_CALLBACK 13 /* callback */ +#define CI_MRRU 17 /* max reconstructed receive unit; multilink */ +#define CI_SSNHF 18 /* short sequence numbers for multilink */ +#define CI_EPDISC 19 /* endpoint discriminator */ + +/* + * LCP-specific packet types (code numbers). + */ +#define PROTREJ 8 /* Protocol Reject */ +#define ECHOREQ 9 /* Echo Request */ +#define ECHOREP 10 /* Echo Reply */ +#define DISCREQ 11 /* Discard Request */ +#define CBCP_OPT 6 /* Use callback control protocol */ + +/* + * The state of options is described by an lcp_options structure. + */ +typedef struct lcp_options { + u_int passive : 1; /* Don't die if we don't get a response */ + u_int silent : 1; /* Wait for the other end to start first */ + u_int restart : 1; /* Restart vs. exit after close */ + u_int neg_mru : 1; /* Negotiate the MRU? */ + u_int neg_asyncmap : 1; /* Negotiate the async map? */ + u_int neg_upap : 1; /* Ask for UPAP authentication? */ + u_int neg_chap : 1; /* Ask for CHAP authentication? */ + u_int neg_magicnumber : 1; /* Ask for magic number? */ + u_int neg_pcompression : 1; /* HDLC Protocol Field Compression? */ + u_int neg_accompression : 1; /* HDLC Address/Control Field Compression? */ + u_int neg_lqr : 1; /* Negotiate use of Link Quality Reports */ + u_int neg_cbcp : 1; /* Negotiate use of CBCP */ +#ifdef PPP_MULTILINK + u_int neg_mrru : 1; /* Negotiate multilink MRRU */ + u_int neg_ssnhf : 1; /* Negotiate short sequence numbers */ + u_int neg_endpoint : 1; /* Negotiate endpoint discriminator */ +#endif + u_short mru; /* Value of MRU */ +#ifdef PPP_MULTILINK + u_short mrru; /* Value of MRRU, and multilink enable */ +#endif + u_char chap_mdtype; /* which MD type (hashing algorithm) */ + u32_t asyncmap; /* Value of async map */ + u32_t magicnumber; + int numloops; /* Number of loops during magic number neg. */ + u32_t lqr_period; /* Reporting period for LQR 1/100ths second */ +#ifdef PPP_MULTILINK + struct epdisc endpoint; /* endpoint discriminator */ +#endif +} lcp_options; + +/* + * Values for phase from BSD pppd.h based on RFC 1661. + */ +typedef enum { + PHASE_DEAD = 0, + PHASE_INITIALIZE, + PHASE_ESTABLISH, + PHASE_AUTHENTICATE, + PHASE_CALLBACK, + PHASE_NETWORK, + PHASE_TERMINATE +} LinkPhase; + + + +extern LinkPhase lcp_phase[NUM_PPP]; /* Phase of link session (RFC 1661) */ +extern lcp_options lcp_wantoptions[]; +extern lcp_options lcp_gotoptions[]; +extern lcp_options lcp_allowoptions[]; +extern lcp_options lcp_hisoptions[]; +extern ext_accm xmit_accm[]; + + +void lcp_init (int); +void lcp_open (int); +void lcp_close (int, char *); +void lcp_lowerup (int); +void lcp_lowerdown(int); +void lcp_sprotrej (int, u_char *, int); /* send protocol reject */ + +extern struct protent lcp_protent; + +/* Default number of times we receive our magic number from the peer + before deciding the link is looped-back. */ +#define DEFLOOPBACKFAIL 10 + +#endif /* LCP_H */ diff --git a/src/lwip-1.4.1/src/netif/ppp/magic.c b/src/lwip-1.4.1/src/netif/ppp/magic.c new file mode 100644 index 0000000..3732a42 --- /dev/null +++ b/src/lwip-1.4.1/src/netif/ppp/magic.c @@ -0,0 +1,80 @@ +/***************************************************************************** +* magic.c - Network Random Number Generator program file. +* +* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. +* portions Copyright (c) 1997 by Global Election Systems Inc. +* +* The authors hereby grant permission to use, copy, modify, distribute, +* and license this software and its documentation for any purpose, provided +* that existing copyright notices are retained in all copies and that this +* notice and the following disclaimer are included verbatim in any +* distributions. No written agreement, license, or royalty fee is required +* for any of the authorized uses. +* +* THIS SOFTWARE IS PROVIDED BY THE 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 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. +* +****************************************************************************** +* REVISION HISTORY +* +* 03-01-01 Marc Boucher +* Ported to lwIP. +* 97-12-04 Guy Lancaster , Global Election Systems Inc. +* Original based on BSD magic.c. +*****************************************************************************/ +/* + * magic.c - PPP Magic Number routines. + * + * Copyright (c) 1989 Carnegie Mellon University. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by Carnegie Mellon University. The name of the + * University may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#include "lwip/opt.h" + +#if PPP_SUPPORT + +#include "ppp_impl.h" +#include "randm.h" +#include "magic.h" + + +/* + * magicInit - Initialize the magic number generator. + * + * Since we use another random number generator that has its own + * initialization, we do nothing here. + */ +void magicInit() +{ + return; +} + +/* + * magic - Returns the next magic number. + */ +u32_t magic() +{ + return avRandom(); +} + +#endif /* PPP_SUPPORT */ diff --git a/src/lwip-1.4.1/src/netif/ppp/magic.h b/src/lwip-1.4.1/src/netif/ppp/magic.h new file mode 100644 index 0000000..eba70d2 --- /dev/null +++ b/src/lwip-1.4.1/src/netif/ppp/magic.h @@ -0,0 +1,63 @@ +/***************************************************************************** +* magic.h - Network Random Number Generator header file. +* +* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. +* portions Copyright (c) 1997 Global Election Systems Inc. +* +* The authors hereby grant permission to use, copy, modify, distribute, +* and license this software and its documentation for any purpose, provided +* that existing copyright notices are retained in all copies and that this +* notice and the following disclaimer are included verbatim in any +* distributions. No written agreement, license, or royalty fee is required +* for any of the authorized uses. +* +* THIS SOFTWARE IS PROVIDED BY THE 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 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. +* +****************************************************************************** +* REVISION HISTORY +* +* 03-01-01 Marc Boucher +* Ported to lwIP. +* 97-12-04 Guy Lancaster , Global Election Systems Inc. +* Original derived from BSD codes. +*****************************************************************************/ +/* + * magic.h - PPP Magic Number definitions. + * + * Copyright (c) 1989 Carnegie Mellon University. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by Carnegie Mellon University. The name of the + * University may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * $Id: magic.h,v 1.3 2010/01/18 20:49:43 goldsimon Exp $ + */ + +#ifndef MAGIC_H +#define MAGIC_H + +/* Initialize the magic number generator */ +void magicInit(void); + +/* Returns the next magic number */ +u32_t magic(void); + +#endif /* MAGIC_H */ diff --git a/src/lwip-1.4.1/src/netif/ppp/md5.c b/src/lwip-1.4.1/src/netif/ppp/md5.c new file mode 100644 index 0000000..dc3cc75 --- /dev/null +++ b/src/lwip-1.4.1/src/netif/ppp/md5.c @@ -0,0 +1,320 @@ +/* + *********************************************************************** + ** md5.c -- the source code for MD5 routines ** + ** RSA Data Security, Inc. MD5 Message-Digest Algorithm ** + ** Created: 2/17/90 RLR ** + ** Revised: 1/91 SRD,AJ,BSK,JT Reference C ver., 7/10 constant corr. ** + *********************************************************************** + */ + +/* + *********************************************************************** + ** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved. ** + ** ** + ** License to copy and use this software is granted provided that ** + ** it is identified as the "RSA Data Security, Inc. MD5 Message- ** + ** Digest Algorithm" in all material mentioning or referencing this ** + ** software or this function. ** + ** ** + ** License is also granted to make and use derivative works ** + ** provided that such works are identified as "derived from the RSA ** + ** Data Security, Inc. MD5 Message-Digest Algorithm" in all ** + ** material mentioning or referencing the derived work. ** + ** ** + ** RSA Data Security, Inc. makes no representations concerning ** + ** either the merchantability of this software or the suitability ** + ** of this software for any particular purpose. It is provided "as ** + ** is" without express or implied warranty of any kind. ** + ** ** + ** These notices must be retained in any copies of any part of this ** + ** documentation and/or software. ** + *********************************************************************** + */ + +#include "lwip/opt.h" + +#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ + +#if CHAP_SUPPORT || MD5_SUPPORT + +#include "ppp_impl.h" +#include "pppdebug.h" + +#include "md5.h" + +#include + +/* + *********************************************************************** + ** Message-digest routines: ** + ** To form the message digest for a message M ** + ** (1) Initialize a context buffer mdContext using MD5Init ** + ** (2) Call MD5Update on mdContext and M ** + ** (3) Call MD5Final on mdContext ** + ** The message digest is now in mdContext->digest[0...15] ** + *********************************************************************** + */ + +/* forward declaration */ +static void Transform (u32_t *buf, u32_t *in); + +static unsigned char PADDING[64] = { + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +/* F, G, H and I are basic MD5 functions */ +#define F(x, y, z) (((x) & (y)) | ((~x) & (z))) +#define G(x, y, z) (((x) & (z)) | ((y) & (~z))) +#define H(x, y, z) ((x) ^ (y) ^ (z)) +#define I(x, y, z) ((y) ^ ((x) | (~z))) + +/* ROTATE_LEFT rotates x left n bits */ +#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) + +/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4 */ +/* Rotation is separate from addition to prevent recomputation */ +#define FF(a, b, c, d, x, s, ac) \ + {(a) += F ((b), (c), (d)) + (x) + (u32_t)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ + } +#define GG(a, b, c, d, x, s, ac) \ + {(a) += G ((b), (c), (d)) + (x) + (u32_t)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ + } +#define HH(a, b, c, d, x, s, ac) \ + {(a) += H ((b), (c), (d)) + (x) + (u32_t)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ + } +#define II(a, b, c, d, x, s, ac) \ + {(a) += I ((b), (c), (d)) + (x) + (u32_t)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ + } + +#ifdef __STDC__ +#define UL(x) x##UL +#else +#ifdef WIN32 +#define UL(x) x##UL +#else +#define UL(x) x +#endif +#endif + +/* The routine MD5Init initializes the message-digest context + mdContext. All fields are set to zero. + */ +void +MD5Init (MD5_CTX *mdContext) +{ + mdContext->i[0] = mdContext->i[1] = (u32_t)0; + + /* Load magic initialization constants. */ + mdContext->buf[0] = (u32_t)0x67452301UL; + mdContext->buf[1] = (u32_t)0xefcdab89UL; + mdContext->buf[2] = (u32_t)0x98badcfeUL; + mdContext->buf[3] = (u32_t)0x10325476UL; +} + +/* The routine MD5Update updates the message-digest context to + account for the presence of each of the characters inBuf[0..inLen-1] + in the message whose digest is being computed. + */ +void +MD5Update(MD5_CTX *mdContext, unsigned char *inBuf, unsigned int inLen) +{ + u32_t in[16]; + int mdi; + unsigned int i, ii; + +#if 0 + PPPDEBUG(LOG_INFO, ("MD5Update: %u:%.*H\n", inLen, LWIP_MIN(inLen, 20) * 2, inBuf)); + PPPDEBUG(LOG_INFO, ("MD5Update: %u:%s\n", inLen, inBuf)); +#endif + + /* compute number of bytes mod 64 */ + mdi = (int)((mdContext->i[0] >> 3) & 0x3F); + + /* update number of bits */ + if ((mdContext->i[0] + ((u32_t)inLen << 3)) < mdContext->i[0]) { + mdContext->i[1]++; + } + mdContext->i[0] += ((u32_t)inLen << 3); + mdContext->i[1] += ((u32_t)inLen >> 29); + + while (inLen--) { + /* add new character to buffer, increment mdi */ + mdContext->in[mdi++] = *inBuf++; + + /* transform if necessary */ + if (mdi == 0x40) { + for (i = 0, ii = 0; i < 16; i++, ii += 4) { + in[i] = (((u32_t)mdContext->in[ii+3]) << 24) | + (((u32_t)mdContext->in[ii+2]) << 16) | + (((u32_t)mdContext->in[ii+1]) << 8) | + ((u32_t)mdContext->in[ii]); + } + Transform (mdContext->buf, in); + mdi = 0; + } + } +} + +/* The routine MD5Final terminates the message-digest computation and + ends with the desired message digest in mdContext->digest[0...15]. + */ +void +MD5Final (unsigned char hash[], MD5_CTX *mdContext) +{ + u32_t in[16]; + int mdi; + unsigned int i, ii; + unsigned int padLen; + + /* save number of bits */ + in[14] = mdContext->i[0]; + in[15] = mdContext->i[1]; + + /* compute number of bytes mod 64 */ + mdi = (int)((mdContext->i[0] >> 3) & 0x3F); + + /* pad out to 56 mod 64 */ + padLen = (mdi < 56) ? (56 - mdi) : (120 - mdi); + MD5Update (mdContext, PADDING, padLen); + + /* append length in bits and transform */ + for (i = 0, ii = 0; i < 14; i++, ii += 4) { + in[i] = (((u32_t)mdContext->in[ii+3]) << 24) | + (((u32_t)mdContext->in[ii+2]) << 16) | + (((u32_t)mdContext->in[ii+1]) << 8) | + ((u32_t)mdContext->in[ii]); + } + Transform (mdContext->buf, in); + + /* store buffer in digest */ + for (i = 0, ii = 0; i < 4; i++, ii += 4) { + mdContext->digest[ii] = (unsigned char)(mdContext->buf[i] & 0xFF); + mdContext->digest[ii+1] = + (unsigned char)((mdContext->buf[i] >> 8) & 0xFF); + mdContext->digest[ii+2] = + (unsigned char)((mdContext->buf[i] >> 16) & 0xFF); + mdContext->digest[ii+3] = + (unsigned char)((mdContext->buf[i] >> 24) & 0xFF); + } + SMEMCPY(hash, mdContext->digest, 16); +} + +/* Basic MD5 step. Transforms buf based on in. + */ +static void +Transform (u32_t *buf, u32_t *in) +{ + u32_t a = buf[0], b = buf[1], c = buf[2], d = buf[3]; + + /* Round 1 */ +#define S11 7 +#define S12 12 +#define S13 17 +#define S14 22 + FF ( a, b, c, d, in[ 0], S11, UL(3614090360)); /* 1 */ + FF ( d, a, b, c, in[ 1], S12, UL(3905402710)); /* 2 */ + FF ( c, d, a, b, in[ 2], S13, UL( 606105819)); /* 3 */ + FF ( b, c, d, a, in[ 3], S14, UL(3250441966)); /* 4 */ + FF ( a, b, c, d, in[ 4], S11, UL(4118548399)); /* 5 */ + FF ( d, a, b, c, in[ 5], S12, UL(1200080426)); /* 6 */ + FF ( c, d, a, b, in[ 6], S13, UL(2821735955)); /* 7 */ + FF ( b, c, d, a, in[ 7], S14, UL(4249261313)); /* 8 */ + FF ( a, b, c, d, in[ 8], S11, UL(1770035416)); /* 9 */ + FF ( d, a, b, c, in[ 9], S12, UL(2336552879)); /* 10 */ + FF ( c, d, a, b, in[10], S13, UL(4294925233)); /* 11 */ + FF ( b, c, d, a, in[11], S14, UL(2304563134)); /* 12 */ + FF ( a, b, c, d, in[12], S11, UL(1804603682)); /* 13 */ + FF ( d, a, b, c, in[13], S12, UL(4254626195)); /* 14 */ + FF ( c, d, a, b, in[14], S13, UL(2792965006)); /* 15 */ + FF ( b, c, d, a, in[15], S14, UL(1236535329)); /* 16 */ + + /* Round 2 */ +#define S21 5 +#define S22 9 +#define S23 14 +#define S24 20 + GG ( a, b, c, d, in[ 1], S21, UL(4129170786)); /* 17 */ + GG ( d, a, b, c, in[ 6], S22, UL(3225465664)); /* 18 */ + GG ( c, d, a, b, in[11], S23, UL( 643717713)); /* 19 */ + GG ( b, c, d, a, in[ 0], S24, UL(3921069994)); /* 20 */ + GG ( a, b, c, d, in[ 5], S21, UL(3593408605)); /* 21 */ + GG ( d, a, b, c, in[10], S22, UL( 38016083)); /* 22 */ + GG ( c, d, a, b, in[15], S23, UL(3634488961)); /* 23 */ + GG ( b, c, d, a, in[ 4], S24, UL(3889429448)); /* 24 */ + GG ( a, b, c, d, in[ 9], S21, UL( 568446438)); /* 25 */ + GG ( d, a, b, c, in[14], S22, UL(3275163606)); /* 26 */ + GG ( c, d, a, b, in[ 3], S23, UL(4107603335)); /* 27 */ + GG ( b, c, d, a, in[ 8], S24, UL(1163531501)); /* 28 */ + GG ( a, b, c, d, in[13], S21, UL(2850285829)); /* 29 */ + GG ( d, a, b, c, in[ 2], S22, UL(4243563512)); /* 30 */ + GG ( c, d, a, b, in[ 7], S23, UL(1735328473)); /* 31 */ + GG ( b, c, d, a, in[12], S24, UL(2368359562)); /* 32 */ + + /* Round 3 */ +#define S31 4 +#define S32 11 +#define S33 16 +#define S34 23 + HH ( a, b, c, d, in[ 5], S31, UL(4294588738)); /* 33 */ + HH ( d, a, b, c, in[ 8], S32, UL(2272392833)); /* 34 */ + HH ( c, d, a, b, in[11], S33, UL(1839030562)); /* 35 */ + HH ( b, c, d, a, in[14], S34, UL(4259657740)); /* 36 */ + HH ( a, b, c, d, in[ 1], S31, UL(2763975236)); /* 37 */ + HH ( d, a, b, c, in[ 4], S32, UL(1272893353)); /* 38 */ + HH ( c, d, a, b, in[ 7], S33, UL(4139469664)); /* 39 */ + HH ( b, c, d, a, in[10], S34, UL(3200236656)); /* 40 */ + HH ( a, b, c, d, in[13], S31, UL( 681279174)); /* 41 */ + HH ( d, a, b, c, in[ 0], S32, UL(3936430074)); /* 42 */ + HH ( c, d, a, b, in[ 3], S33, UL(3572445317)); /* 43 */ + HH ( b, c, d, a, in[ 6], S34, UL( 76029189)); /* 44 */ + HH ( a, b, c, d, in[ 9], S31, UL(3654602809)); /* 45 */ + HH ( d, a, b, c, in[12], S32, UL(3873151461)); /* 46 */ + HH ( c, d, a, b, in[15], S33, UL( 530742520)); /* 47 */ + HH ( b, c, d, a, in[ 2], S34, UL(3299628645)); /* 48 */ + + /* Round 4 */ +#define S41 6 +#define S42 10 +#define S43 15 +#define S44 21 + II ( a, b, c, d, in[ 0], S41, UL(4096336452)); /* 49 */ + II ( d, a, b, c, in[ 7], S42, UL(1126891415)); /* 50 */ + II ( c, d, a, b, in[14], S43, UL(2878612391)); /* 51 */ + II ( b, c, d, a, in[ 5], S44, UL(4237533241)); /* 52 */ + II ( a, b, c, d, in[12], S41, UL(1700485571)); /* 53 */ + II ( d, a, b, c, in[ 3], S42, UL(2399980690)); /* 54 */ + II ( c, d, a, b, in[10], S43, UL(4293915773)); /* 55 */ + II ( b, c, d, a, in[ 1], S44, UL(2240044497)); /* 56 */ + II ( a, b, c, d, in[ 8], S41, UL(1873313359)); /* 57 */ + II ( d, a, b, c, in[15], S42, UL(4264355552)); /* 58 */ + II ( c, d, a, b, in[ 6], S43, UL(2734768916)); /* 59 */ + II ( b, c, d, a, in[13], S44, UL(1309151649)); /* 60 */ + II ( a, b, c, d, in[ 4], S41, UL(4149444226)); /* 61 */ + II ( d, a, b, c, in[11], S42, UL(3174756917)); /* 62 */ + II ( c, d, a, b, in[ 2], S43, UL( 718787259)); /* 63 */ + II ( b, c, d, a, in[ 9], S44, UL(3951481745)); /* 64 */ + + buf[0] += a; + buf[1] += b; + buf[2] += c; + buf[3] += d; +} + +#endif /* CHAP_SUPPORT || MD5_SUPPORT */ + +#endif /* PPP_SUPPORT */ diff --git a/src/lwip-1.4.1/src/netif/ppp/md5.h b/src/lwip-1.4.1/src/netif/ppp/md5.h new file mode 100644 index 0000000..e129533 --- /dev/null +++ b/src/lwip-1.4.1/src/netif/ppp/md5.h @@ -0,0 +1,55 @@ +/* + *********************************************************************** + ** md5.h -- header file for implementation of MD5 ** + ** RSA Data Security, Inc. MD5 Message-Digest Algorithm ** + ** Created: 2/17/90 RLR ** + ** Revised: 12/27/90 SRD,AJ,BSK,JT Reference C version ** + ** Revised (for MD5): RLR 4/27/91 ** + ** -- G modified to have y&~z instead of y&z ** + ** -- FF, GG, HH modified to add in last register done ** + ** -- Access pattern: round 2 works mod 5, round 3 works mod 3 ** + ** -- distinct additive constant for each step ** + ** -- round 4 added, working mod 7 ** + *********************************************************************** + */ + +/* + *********************************************************************** + ** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved. ** + ** ** + ** License to copy and use this software is granted provided that ** + ** it is identified as the "RSA Data Security, Inc. MD5 Message- ** + ** Digest Algorithm" in all material mentioning or referencing this ** + ** software or this function. ** + ** ** + ** License is also granted to make and use derivative works ** + ** provided that such works are identified as "derived from the RSA ** + ** Data Security, Inc. MD5 Message-Digest Algorithm" in all ** + ** material mentioning or referencing the derived work. ** + ** ** + ** RSA Data Security, Inc. makes no representations concerning ** + ** either the merchantability of this software or the suitability ** + ** of this software for any particular purpose. It is provided "as ** + ** is" without express or implied warranty of any kind. ** + ** ** + ** These notices must be retained in any copies of any part of this ** + ** documentation and/or software. ** + *********************************************************************** + */ + +#ifndef MD5_H +#define MD5_H + +/* Data structure for MD5 (Message-Digest) computation */ +typedef struct { + u32_t i[2]; /* number of _bits_ handled mod 2^64 */ + u32_t buf[4]; /* scratch buffer */ + unsigned char in[64]; /* input buffer */ + unsigned char digest[16]; /* actual digest after MD5Final call */ +} MD5_CTX; + +void MD5Init ( MD5_CTX *mdContext); +void MD5Update( MD5_CTX *mdContext, unsigned char *inBuf, unsigned int inLen); +void MD5Final ( unsigned char hash[], MD5_CTX *mdContext); + +#endif /* MD5_H */ diff --git a/src/lwip-1.4.1/src/netif/ppp/pap.c b/src/lwip-1.4.1/src/netif/ppp/pap.c new file mode 100644 index 0000000..5fb9f88 --- /dev/null +++ b/src/lwip-1.4.1/src/netif/ppp/pap.c @@ -0,0 +1,628 @@ +/***************************************************************************** +* pap.c - Network Password Authentication Protocol program file. +* +* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. +* portions Copyright (c) 1997 by Global Election Systems Inc. +* +* The authors hereby grant permission to use, copy, modify, distribute, +* and license this software and its documentation for any purpose, provided +* that existing copyright notices are retained in all copies and that this +* notice and the following disclaimer are included verbatim in any +* distributions. No written agreement, license, or royalty fee is required +* for any of the authorized uses. +* +* THIS SOFTWARE IS PROVIDED BY THE 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 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. +* +****************************************************************************** +* REVISION HISTORY +* +* 03-01-01 Marc Boucher +* Ported to lwIP. +* 97-12-12 Guy Lancaster , Global Election Systems Inc. +* Original. +*****************************************************************************/ +/* + * upap.c - User/Password Authentication Protocol. + * + * Copyright (c) 1989 Carnegie Mellon University. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by Carnegie Mellon University. The name of the + * University may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#include "lwip/opt.h" + +#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ + +#if PAP_SUPPORT /* don't build if not configured for use in lwipopts.h */ + +#include "ppp_impl.h" +#include "pppdebug.h" + +#include "auth.h" +#include "pap.h" + +#include + +#if 0 /* UNUSED */ +static bool hide_password = 1; + +/* + * Command-line options. + */ +static option_t pap_option_list[] = { + { "hide-password", o_bool, &hide_password, + "Don't output passwords to log", 1 }, + { "show-password", o_bool, &hide_password, + "Show password string in debug log messages", 0 }, + { "pap-restart", o_int, &upap[0].us_timeouttime, + "Set retransmit timeout for PAP" }, + { "pap-max-authreq", o_int, &upap[0].us_maxtransmits, + "Set max number of transmissions for auth-reqs" }, + { "pap-timeout", o_int, &upap[0].us_reqtimeout, + "Set time limit for peer PAP authentication" }, + { NULL } +}; +#endif + +/* + * Protocol entry points. + */ +static void upap_init (int); +static void upap_lowerup (int); +static void upap_lowerdown (int); +static void upap_input (int, u_char *, int); +static void upap_protrej (int); +#if PPP_ADDITIONAL_CALLBACKS +static int upap_printpkt (u_char *, int, void (*)(void *, char *, ...), void *); +#endif /* PPP_ADDITIONAL_CALLBACKS */ + +struct protent pap_protent = { + PPP_PAP, + upap_init, + upap_input, + upap_protrej, + upap_lowerup, + upap_lowerdown, + NULL, + NULL, +#if PPP_ADDITIONAL_CALLBACKS + upap_printpkt, + NULL, +#endif /* PPP_ADDITIONAL_CALLBACKS */ + 1, + "PAP", +#if PPP_ADDITIONAL_CALLBACKS + NULL, + NULL, + NULL +#endif /* PPP_ADDITIONAL_CALLBACKS */ +}; + +upap_state upap[NUM_PPP]; /* UPAP state; one for each unit */ + +static void upap_timeout (void *); +static void upap_reqtimeout(void *); +static void upap_rauthreq (upap_state *, u_char *, u_char, int); +static void upap_rauthack (upap_state *, u_char *, int, int); +static void upap_rauthnak (upap_state *, u_char *, int, int); +static void upap_sauthreq (upap_state *); +static void upap_sresp (upap_state *, u_char, u_char, char *, int); + + +/* + * upap_init - Initialize a UPAP unit. + */ +static void +upap_init(int unit) +{ + upap_state *u = &upap[unit]; + + UPAPDEBUG(LOG_INFO, ("upap_init: %d\n", unit)); + u->us_unit = unit; + u->us_user = NULL; + u->us_userlen = 0; + u->us_passwd = NULL; + u->us_passwdlen = 0; + u->us_clientstate = UPAPCS_INITIAL; + u->us_serverstate = UPAPSS_INITIAL; + u->us_id = 0; + u->us_timeouttime = UPAP_DEFTIMEOUT; + u->us_maxtransmits = 10; + u->us_reqtimeout = UPAP_DEFREQTIME; +} + +/* + * upap_authwithpeer - Authenticate us with our peer (start client). + * + * Set new state and send authenticate's. + */ +void +upap_authwithpeer(int unit, char *user, char *password) +{ + upap_state *u = &upap[unit]; + + UPAPDEBUG(LOG_INFO, ("upap_authwithpeer: %d user=%s password=%s s=%d\n", + unit, user, password, u->us_clientstate)); + + /* Save the username and password we're given */ + u->us_user = user; + u->us_userlen = (int)strlen(user); + u->us_passwd = password; + u->us_passwdlen = (int)strlen(password); + + u->us_transmits = 0; + + /* Lower layer up yet? */ + if (u->us_clientstate == UPAPCS_INITIAL || + u->us_clientstate == UPAPCS_PENDING) { + u->us_clientstate = UPAPCS_PENDING; + return; + } + + upap_sauthreq(u); /* Start protocol */ +} + + +/* + * upap_authpeer - Authenticate our peer (start server). + * + * Set new state. + */ +void +upap_authpeer(int unit) +{ + upap_state *u = &upap[unit]; + + /* Lower layer up yet? */ + if (u->us_serverstate == UPAPSS_INITIAL || + u->us_serverstate == UPAPSS_PENDING) { + u->us_serverstate = UPAPSS_PENDING; + return; + } + + u->us_serverstate = UPAPSS_LISTEN; + if (u->us_reqtimeout > 0) { + TIMEOUT(upap_reqtimeout, u, u->us_reqtimeout); + } +} + +/* + * upap_timeout - Retransmission timer for sending auth-reqs expired. + */ +static void +upap_timeout(void *arg) +{ + upap_state *u = (upap_state *) arg; + + UPAPDEBUG(LOG_INFO, ("upap_timeout: %d timeout %d expired s=%d\n", + u->us_unit, u->us_timeouttime, u->us_clientstate)); + + if (u->us_clientstate != UPAPCS_AUTHREQ) { + UPAPDEBUG(LOG_INFO, ("upap_timeout: not in AUTHREQ state!\n")); + return; + } + + if (u->us_transmits >= u->us_maxtransmits) { + /* give up in disgust */ + UPAPDEBUG(LOG_ERR, ("No response to PAP authenticate-requests\n")); + u->us_clientstate = UPAPCS_BADAUTH; + auth_withpeer_fail(u->us_unit, PPP_PAP); + return; + } + + upap_sauthreq(u); /* Send Authenticate-Request and set upap timeout*/ +} + + +/* + * upap_reqtimeout - Give up waiting for the peer to send an auth-req. + */ +static void +upap_reqtimeout(void *arg) +{ + upap_state *u = (upap_state *) arg; + + if (u->us_serverstate != UPAPSS_LISTEN) { + return; /* huh?? */ + } + + auth_peer_fail(u->us_unit, PPP_PAP); + u->us_serverstate = UPAPSS_BADAUTH; +} + + +/* + * upap_lowerup - The lower layer is up. + * + * Start authenticating if pending. + */ +static void +upap_lowerup(int unit) +{ + upap_state *u = &upap[unit]; + + UPAPDEBUG(LOG_INFO, ("upap_lowerup: init %d clientstate s=%d\n", unit, u->us_clientstate)); + + if (u->us_clientstate == UPAPCS_INITIAL) { + u->us_clientstate = UPAPCS_CLOSED; + } else if (u->us_clientstate == UPAPCS_PENDING) { + upap_sauthreq(u); /* send an auth-request */ + /* now client state is UPAPCS__AUTHREQ */ + } + + if (u->us_serverstate == UPAPSS_INITIAL) { + u->us_serverstate = UPAPSS_CLOSED; + } else if (u->us_serverstate == UPAPSS_PENDING) { + u->us_serverstate = UPAPSS_LISTEN; + if (u->us_reqtimeout > 0) { + TIMEOUT(upap_reqtimeout, u, u->us_reqtimeout); + } + } +} + + +/* + * upap_lowerdown - The lower layer is down. + * + * Cancel all timeouts. + */ +static void +upap_lowerdown(int unit) +{ + upap_state *u = &upap[unit]; + + UPAPDEBUG(LOG_INFO, ("upap_lowerdown: %d s=%d\n", unit, u->us_clientstate)); + + if (u->us_clientstate == UPAPCS_AUTHREQ) { /* Timeout pending? */ + UNTIMEOUT(upap_timeout, u); /* Cancel timeout */ + } + if (u->us_serverstate == UPAPSS_LISTEN && u->us_reqtimeout > 0) { + UNTIMEOUT(upap_reqtimeout, u); + } + + u->us_clientstate = UPAPCS_INITIAL; + u->us_serverstate = UPAPSS_INITIAL; +} + + +/* + * upap_protrej - Peer doesn't speak this protocol. + * + * This shouldn't happen. In any case, pretend lower layer went down. + */ +static void +upap_protrej(int unit) +{ + upap_state *u = &upap[unit]; + + if (u->us_clientstate == UPAPCS_AUTHREQ) { + UPAPDEBUG(LOG_ERR, ("PAP authentication failed due to protocol-reject\n")); + auth_withpeer_fail(unit, PPP_PAP); + } + if (u->us_serverstate == UPAPSS_LISTEN) { + UPAPDEBUG(LOG_ERR, ("PAP authentication of peer failed (protocol-reject)\n")); + auth_peer_fail(unit, PPP_PAP); + } + upap_lowerdown(unit); +} + + +/* + * upap_input - Input UPAP packet. + */ +static void +upap_input(int unit, u_char *inpacket, int l) +{ + upap_state *u = &upap[unit]; + u_char *inp; + u_char code, id; + int len; + + /* + * Parse header (code, id and length). + * If packet too short, drop it. + */ + inp = inpacket; + if (l < (int)UPAP_HEADERLEN) { + UPAPDEBUG(LOG_INFO, ("pap_input: rcvd short header.\n")); + return; + } + GETCHAR(code, inp); + GETCHAR(id, inp); + GETSHORT(len, inp); + if (len < (int)UPAP_HEADERLEN) { + UPAPDEBUG(LOG_INFO, ("pap_input: rcvd illegal length.\n")); + return; + } + if (len > l) { + UPAPDEBUG(LOG_INFO, ("pap_input: rcvd short packet.\n")); + return; + } + len -= UPAP_HEADERLEN; + + /* + * Action depends on code. + */ + switch (code) { + case UPAP_AUTHREQ: + upap_rauthreq(u, inp, id, len); + break; + + case UPAP_AUTHACK: + upap_rauthack(u, inp, id, len); + break; + + case UPAP_AUTHNAK: + upap_rauthnak(u, inp, id, len); + break; + + default: /* XXX Need code reject */ + UPAPDEBUG(LOG_INFO, ("pap_input: UNHANDLED default: code: %d, id: %d, len: %d.\n", code, id, len)); + break; + } +} + + +/* + * upap_rauth - Receive Authenticate. + */ +static void +upap_rauthreq(upap_state *u, u_char *inp, u_char id, int len) +{ + u_char ruserlen, rpasswdlen; + char *ruser, *rpasswd; + u_char retcode; + char *msg; + int msglen; + + UPAPDEBUG(LOG_INFO, ("pap_rauth: Rcvd id %d.\n", id)); + + if (u->us_serverstate < UPAPSS_LISTEN) { + return; + } + + /* + * If we receive a duplicate authenticate-request, we are + * supposed to return the same status as for the first request. + */ + if (u->us_serverstate == UPAPSS_OPEN) { + upap_sresp(u, UPAP_AUTHACK, id, "", 0); /* return auth-ack */ + return; + } + if (u->us_serverstate == UPAPSS_BADAUTH) { + upap_sresp(u, UPAP_AUTHNAK, id, "", 0); /* return auth-nak */ + return; + } + + /* + * Parse user/passwd. + */ + if (len < (int)sizeof (u_char)) { + UPAPDEBUG(LOG_INFO, ("pap_rauth: rcvd short packet.\n")); + return; + } + GETCHAR(ruserlen, inp); + len -= sizeof (u_char) + ruserlen + sizeof (u_char); + if (len < 0) { + UPAPDEBUG(LOG_INFO, ("pap_rauth: rcvd short packet.\n")); + return; + } + ruser = (char *) inp; + INCPTR(ruserlen, inp); + GETCHAR(rpasswdlen, inp); + if (len < rpasswdlen) { + UPAPDEBUG(LOG_INFO, ("pap_rauth: rcvd short packet.\n")); + return; + } + rpasswd = (char *) inp; + + /* + * Check the username and password given. + */ + retcode = check_passwd(u->us_unit, ruser, ruserlen, rpasswd, rpasswdlen, &msg, &msglen); + /* lwip: currently retcode is always UPAP_AUTHACK */ + BZERO(rpasswd, rpasswdlen); + + upap_sresp(u, retcode, id, msg, msglen); + + if (retcode == UPAP_AUTHACK) { + u->us_serverstate = UPAPSS_OPEN; + auth_peer_success(u->us_unit, PPP_PAP, ruser, ruserlen); + } else { + u->us_serverstate = UPAPSS_BADAUTH; + auth_peer_fail(u->us_unit, PPP_PAP); + } + + if (u->us_reqtimeout > 0) { + UNTIMEOUT(upap_reqtimeout, u); + } +} + + +/* + * upap_rauthack - Receive Authenticate-Ack. + */ +static void +upap_rauthack(upap_state *u, u_char *inp, int id, int len) +{ + u_char msglen; + char *msg; + + LWIP_UNUSED_ARG(id); + + UPAPDEBUG(LOG_INFO, ("pap_rauthack: Rcvd id %d s=%d\n", id, u->us_clientstate)); + + if (u->us_clientstate != UPAPCS_AUTHREQ) { /* XXX */ + UPAPDEBUG(LOG_INFO, ("pap_rauthack: us_clientstate != UPAPCS_AUTHREQ\n")); + return; + } + + /* + * Parse message. + */ + if (len < (int)sizeof (u_char)) { + UPAPDEBUG(LOG_INFO, ("pap_rauthack: ignoring missing msg-length.\n")); + } else { + GETCHAR(msglen, inp); + if (msglen > 0) { + len -= sizeof (u_char); + if (len < msglen) { + UPAPDEBUG(LOG_INFO, ("pap_rauthack: rcvd short packet.\n")); + return; + } + msg = (char *) inp; + PRINTMSG(msg, msglen); + } + } + UNTIMEOUT(upap_timeout, u); /* Cancel timeout */ + u->us_clientstate = UPAPCS_OPEN; + + auth_withpeer_success(u->us_unit, PPP_PAP); +} + + +/* + * upap_rauthnak - Receive Authenticate-Nak. + */ +static void +upap_rauthnak(upap_state *u, u_char *inp, int id, int len) +{ + u_char msglen; + char *msg; + + LWIP_UNUSED_ARG(id); + + UPAPDEBUG(LOG_INFO, ("pap_rauthnak: Rcvd id %d s=%d\n", id, u->us_clientstate)); + + if (u->us_clientstate != UPAPCS_AUTHREQ) { /* XXX */ + return; + } + + /* + * Parse message. + */ + if (len < sizeof (u_char)) { + UPAPDEBUG(LOG_INFO, ("pap_rauthnak: ignoring missing msg-length.\n")); + } else { + GETCHAR(msglen, inp); + if(msglen > 0) { + len -= sizeof (u_char); + if (len < msglen) { + UPAPDEBUG(LOG_INFO, ("pap_rauthnak: rcvd short packet.\n")); + return; + } + msg = (char *) inp; + PRINTMSG(msg, msglen); + } + } + + u->us_clientstate = UPAPCS_BADAUTH; + + UPAPDEBUG(LOG_ERR, ("PAP authentication failed\n")); + auth_withpeer_fail(u->us_unit, PPP_PAP); +} + + +/* + * upap_sauthreq - Send an Authenticate-Request. + */ +static void +upap_sauthreq(upap_state *u) +{ + u_char *outp; + int outlen; + + outlen = UPAP_HEADERLEN + 2 * sizeof (u_char) + + u->us_userlen + u->us_passwdlen; + outp = outpacket_buf[u->us_unit]; + + MAKEHEADER(outp, PPP_PAP); + + PUTCHAR(UPAP_AUTHREQ, outp); + PUTCHAR(++u->us_id, outp); + PUTSHORT(outlen, outp); + PUTCHAR(u->us_userlen, outp); + BCOPY(u->us_user, outp, u->us_userlen); + INCPTR(u->us_userlen, outp); + PUTCHAR(u->us_passwdlen, outp); + BCOPY(u->us_passwd, outp, u->us_passwdlen); + + pppWrite(u->us_unit, outpacket_buf[u->us_unit], outlen + PPP_HDRLEN); + + UPAPDEBUG(LOG_INFO, ("pap_sauth: Sent id %d\n", u->us_id)); + + TIMEOUT(upap_timeout, u, u->us_timeouttime); + ++u->us_transmits; + u->us_clientstate = UPAPCS_AUTHREQ; +} + + +/* + * upap_sresp - Send a response (ack or nak). + */ +static void +upap_sresp(upap_state *u, u_char code, u_char id, char *msg, int msglen) +{ + u_char *outp; + int outlen; + + outlen = UPAP_HEADERLEN + sizeof (u_char) + msglen; + outp = outpacket_buf[u->us_unit]; + MAKEHEADER(outp, PPP_PAP); + + PUTCHAR(code, outp); + PUTCHAR(id, outp); + PUTSHORT(outlen, outp); + PUTCHAR(msglen, outp); + BCOPY(msg, outp, msglen); + pppWrite(u->us_unit, outpacket_buf[u->us_unit], outlen + PPP_HDRLEN); + + UPAPDEBUG(LOG_INFO, ("pap_sresp: Sent code %d, id %d s=%d\n", code, id, u->us_clientstate)); +} + +#if PPP_ADDITIONAL_CALLBACKS +static char *upap_codenames[] = { + "AuthReq", "AuthAck", "AuthNak" +}; + +/* + * upap_printpkt - print the contents of a PAP packet. + */ +static int upap_printpkt( + u_char *p, + int plen, + void (*printer) (void *, char *, ...), + void *arg +) +{ + LWIP_UNUSED_ARG(p); + LWIP_UNUSED_ARG(plen); + LWIP_UNUSED_ARG(printer); + LWIP_UNUSED_ARG(arg); + return 0; +} +#endif /* PPP_ADDITIONAL_CALLBACKS */ + +#endif /* PAP_SUPPORT */ + +#endif /* PPP_SUPPORT */ diff --git a/src/lwip-1.4.1/src/netif/ppp/pap.h b/src/lwip-1.4.1/src/netif/ppp/pap.h new file mode 100644 index 0000000..c99a204 --- /dev/null +++ b/src/lwip-1.4.1/src/netif/ppp/pap.h @@ -0,0 +1,118 @@ +/***************************************************************************** +* pap.h - PPP Password Authentication Protocol header file. +* +* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. +* portions Copyright (c) 1997 Global Election Systems Inc. +* +* The authors hereby grant permission to use, copy, modify, distribute, +* and license this software and its documentation for any purpose, provided +* that existing copyright notices are retained in all copies and that this +* notice and the following disclaimer are included verbatim in any +* distributions. No written agreement, license, or royalty fee is required +* for any of the authorized uses. +* +* THIS SOFTWARE IS PROVIDED BY THE 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 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. +* +****************************************************************************** +* REVISION HISTORY +* +* 03-01-01 Marc Boucher +* Ported to lwIP. +* 97-12-04 Guy Lancaster , Global Election Systems Inc. +* Original derived from BSD codes. +*****************************************************************************/ +/* + * upap.h - User/Password Authentication Protocol definitions. + * + * Copyright (c) 1989 Carnegie Mellon University. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by Carnegie Mellon University. The name of the + * University may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifndef PAP_H +#define PAP_H + +#if PAP_SUPPORT /* don't build if not configured for use in lwipopts.h */ + +/* + * Packet header = Code, id, length. + */ +#define UPAP_HEADERLEN (sizeof (u_char) + sizeof (u_char) + sizeof (u_short)) + + +/* + * UPAP codes. + */ +#define UPAP_AUTHREQ 1 /* Authenticate-Request */ +#define UPAP_AUTHACK 2 /* Authenticate-Ack */ +#define UPAP_AUTHNAK 3 /* Authenticate-Nak */ + +/* + * Each interface is described by upap structure. + */ +typedef struct upap_state { + int us_unit; /* Interface unit number */ + const char *us_user; /* User */ + int us_userlen; /* User length */ + const char *us_passwd; /* Password */ + int us_passwdlen; /* Password length */ + int us_clientstate; /* Client state */ + int us_serverstate; /* Server state */ + u_char us_id; /* Current id */ + int us_timeouttime; /* Timeout (seconds) for auth-req retrans. */ + int us_transmits; /* Number of auth-reqs sent */ + int us_maxtransmits; /* Maximum number of auth-reqs to send */ + int us_reqtimeout; /* Time to wait for auth-req from peer */ +} upap_state; + +/* + * Client states. + */ +#define UPAPCS_INITIAL 0 /* Connection down */ +#define UPAPCS_CLOSED 1 /* Connection up, haven't requested auth */ +#define UPAPCS_PENDING 2 /* Connection down, have requested auth */ +#define UPAPCS_AUTHREQ 3 /* We've sent an Authenticate-Request */ +#define UPAPCS_OPEN 4 /* We've received an Ack */ +#define UPAPCS_BADAUTH 5 /* We've received a Nak */ + +/* + * Server states. + */ +#define UPAPSS_INITIAL 0 /* Connection down */ +#define UPAPSS_CLOSED 1 /* Connection up, haven't requested auth */ +#define UPAPSS_PENDING 2 /* Connection down, have requested auth */ +#define UPAPSS_LISTEN 3 /* Listening for an Authenticate */ +#define UPAPSS_OPEN 4 /* We've sent an Ack */ +#define UPAPSS_BADAUTH 5 /* We've sent a Nak */ + + +extern upap_state upap[]; + +void upap_authwithpeer (int, char *, char *); +void upap_authpeer (int); + +extern struct protent pap_protent; + +#endif /* PAP_SUPPORT */ + +#endif /* PAP_H */ diff --git a/src/lwip-1.4.1/src/netif/ppp/ppp.c b/src/lwip-1.4.1/src/netif/ppp/ppp.c new file mode 100644 index 0000000..8e8fae9 --- /dev/null +++ b/src/lwip-1.4.1/src/netif/ppp/ppp.c @@ -0,0 +1,2045 @@ +/***************************************************************************** +* ppp.c - Network Point to Point Protocol program file. +* +* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. +* portions Copyright (c) 1997 by Global Election Systems Inc. +* +* The authors hereby grant permission to use, copy, modify, distribute, +* and license this software and its documentation for any purpose, provided +* that existing copyright notices are retained in all copies and that this +* notice and the following disclaimer are included verbatim in any +* distributions. No written agreement, license, or royalty fee is required +* for any of the authorized uses. +* +* THIS SOFTWARE IS PROVIDED BY THE 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 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. +* +****************************************************************************** +* REVISION HISTORY +* +* 03-01-01 Marc Boucher +* Ported to lwIP. +* 97-11-05 Guy Lancaster , Global Election Systems Inc. +* Original. +*****************************************************************************/ + +/* + * ppp_defs.h - PPP definitions. + * + * if_pppvar.h - private structures and declarations for PPP. + * + * Copyright (c) 1994 The Australian National University. + * All rights reserved. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation is hereby granted, provided that the above copyright + * notice appears in all copies. This software is provided without any + * warranty, express or implied. The Australian National University + * makes no representations about the suitability of this software for + * any purpose. + * + * IN NO EVENT SHALL THE AUSTRALIAN NATIONAL UNIVERSITY BE LIABLE TO ANY + * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF + * THE AUSTRALIAN NATIONAL UNIVERSITY HAVE BEEN ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * THE AUSTRALIAN NATIONAL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE AUSTRALIAN NATIONAL UNIVERSITY HAS NO + * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, + * OR MODIFICATIONS. + */ + +/* + * if_ppp.h - Point-to-Point Protocol definitions. + * + * Copyright (c) 1989 Carnegie Mellon University. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by Carnegie Mellon University. The name of the + * University may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#include "lwip/opt.h" + +#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ + +#include "ppp_impl.h" +#include "lwip/ip.h" /* for ip_input() */ + +#include "pppdebug.h" + +#include "randm.h" +#include "fsm.h" +#if PAP_SUPPORT +#include "pap.h" +#endif /* PAP_SUPPORT */ +#if CHAP_SUPPORT +#include "chap.h" +#endif /* CHAP_SUPPORT */ +#include "ipcp.h" +#include "lcp.h" +#include "magic.h" +#include "auth.h" +#if VJ_SUPPORT +#include "vj.h" +#endif /* VJ_SUPPORT */ +#if PPPOE_SUPPORT +#include "netif/ppp_oe.h" +#endif /* PPPOE_SUPPORT */ + +#include "lwip/tcpip.h" +#include "lwip/api.h" +#include "lwip/snmp.h" + +#include + +/*************************/ +/*** LOCAL DEFINITIONS ***/ +/*************************/ + +/** PPP_INPROC_MULTITHREADED==1 call pppInput using tcpip_callback(). + * Set this to 0 if pppInProc is called inside tcpip_thread or with NO_SYS==1. + * Default is 1 for NO_SYS==0 (multithreaded) and 0 for NO_SYS==1 (single-threaded). + */ +#ifndef PPP_INPROC_MULTITHREADED +#define PPP_INPROC_MULTITHREADED (NO_SYS==0) +#endif + +/** PPP_INPROC_OWNTHREAD==1: start a dedicated RX thread per PPP session. + * Default is 0: call pppos_input() for received raw characters, charcater + * reception is up to the port */ +#ifndef PPP_INPROC_OWNTHREAD +#define PPP_INPROC_OWNTHREAD PPP_INPROC_MULTITHREADED +#endif + +#if PPP_INPROC_OWNTHREAD && !PPP_INPROC_MULTITHREADED + #error "PPP_INPROC_OWNTHREAD needs PPP_INPROC_MULTITHREADED==1" +#endif + +/* + * The basic PPP frame. + */ +#define PPP_ADDRESS(p) (((u_char *)(p))[0]) +#define PPP_CONTROL(p) (((u_char *)(p))[1]) +#define PPP_PROTOCOL(p) ((((u_char *)(p))[2] << 8) + ((u_char *)(p))[3]) + +/* PPP packet parser states. Current state indicates operation yet to be + * completed. */ +typedef enum { + PDIDLE = 0, /* Idle state - waiting. */ + PDSTART, /* Process start flag. */ + PDADDRESS, /* Process address field. */ + PDCONTROL, /* Process control field. */ + PDPROTOCOL1, /* Process protocol field 1. */ + PDPROTOCOL2, /* Process protocol field 2. */ + PDDATA /* Process data byte. */ +} PPPDevStates; + +#define ESCAPE_P(accm, c) ((accm)[(c) >> 3] & pppACCMMask[c & 0x07]) + +/************************/ +/*** LOCAL DATA TYPES ***/ +/************************/ + +/** RX buffer size: this may be configured smaller! */ +#ifndef PPPOS_RX_BUFSIZE +#define PPPOS_RX_BUFSIZE (PPP_MRU + PPP_HDRLEN) +#endif + +typedef struct PPPControlRx_s { + /** unit number / ppp descriptor */ + int pd; + /** the rx file descriptor */ + sio_fd_t fd; + /** receive buffer - encoded data is stored here */ +#if PPP_INPROC_OWNTHREAD + u_char rxbuf[PPPOS_RX_BUFSIZE]; +#endif /* PPP_INPROC_OWNTHREAD */ + + /* The input packet. */ + struct pbuf *inHead, *inTail; + +#if PPPOS_SUPPORT + u16_t inProtocol; /* The input protocol code. */ + u16_t inFCS; /* Input Frame Check Sequence value. */ +#endif /* PPPOS_SUPPORT */ + PPPDevStates inState; /* The input process state. */ + char inEscaped; /* Escape next character. */ + ext_accm inACCM; /* Async-Ctl-Char-Map for input. */ +} PPPControlRx; + +/* + * PPP interface control block. + */ +typedef struct PPPControl_s { + PPPControlRx rx; + char openFlag; /* True when in use. */ +#if PPPOE_SUPPORT + struct netif *ethif; + struct pppoe_softc *pppoe_sc; +#endif /* PPPOE_SUPPORT */ + int if_up; /* True when the interface is up. */ + int errCode; /* Code indicating why interface is down. */ +#if PPPOS_SUPPORT + sio_fd_t fd; /* File device ID of port. */ +#endif /* PPPOS_SUPPORT */ + u16_t mtu; /* Peer's mru */ + int pcomp; /* Does peer accept protocol compression? */ + int accomp; /* Does peer accept addr/ctl compression? */ + u_long lastXMit; /* Time of last transmission. */ + ext_accm outACCM; /* Async-Ctl-Char-Map for output. */ +#if PPPOS_SUPPORT && VJ_SUPPORT + int vjEnabled; /* Flag indicating VJ compression enabled. */ + struct vjcompress vjComp; /* Van Jacobson compression header. */ +#endif /* PPPOS_SUPPORT && VJ_SUPPORT */ + + struct netif netif; + + struct ppp_addrs addrs; + + void (*linkStatusCB)(void *ctx, int errCode, void *arg); + void *linkStatusCtx; + +} PPPControl; + + +/* + * Ioctl definitions. + */ + +struct npioctl { + int protocol; /* PPP procotol, e.g. PPP_IP */ + enum NPmode mode; +}; + + + +/***********************************/ +/*** LOCAL FUNCTION DECLARATIONS ***/ +/***********************************/ +#if PPPOS_SUPPORT +#if PPP_INPROC_OWNTHREAD +static void pppInputThread(void *arg); +#endif /* PPP_INPROC_OWNTHREAD */ +static void pppDrop(PPPControlRx *pcrx); +static void pppInProc(PPPControlRx *pcrx, u_char *s, int l); +static void pppFreeCurrentInputPacket(PPPControlRx *pcrx); +#endif /* PPPOS_SUPPORT */ + + +/******************************/ +/*** PUBLIC DATA STRUCTURES ***/ +/******************************/ +u_long subnetMask; + +static PPPControl pppControl[NUM_PPP]; /* The PPP interface control blocks. */ + +/* + * PPP Data Link Layer "protocol" table. + * One entry per supported protocol. + * The last entry must be NULL. + */ +struct protent *ppp_protocols[] = { + &lcp_protent, +#if PAP_SUPPORT + &pap_protent, +#endif /* PAP_SUPPORT */ +#if CHAP_SUPPORT + &chap_protent, +#endif /* CHAP_SUPPORT */ +#if CBCP_SUPPORT + &cbcp_protent, +#endif /* CBCP_SUPPORT */ + &ipcp_protent, +#if CCP_SUPPORT + &ccp_protent, +#endif /* CCP_SUPPORT */ + NULL +}; + + +/* + * Buffers for outgoing packets. This must be accessed only from the appropriate + * PPP task so that it doesn't need to be protected to avoid collisions. + */ +u_char outpacket_buf[NUM_PPP][PPP_MRU+PPP_HDRLEN]; + + +/*****************************/ +/*** LOCAL DATA STRUCTURES ***/ +/*****************************/ + +#if PPPOS_SUPPORT +/* + * FCS lookup table as calculated by genfcstab. + * @todo: smaller, slower implementation for lower memory footprint? + */ +static const u_short fcstab[256] = { + 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf, + 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7, + 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e, + 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876, + 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd, + 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5, + 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c, + 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974, + 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb, + 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3, + 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a, + 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72, + 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9, + 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1, + 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738, + 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70, + 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7, + 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff, + 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036, + 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e, + 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5, + 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd, + 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134, + 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c, + 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3, + 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb, + 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232, + 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a, + 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1, + 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9, + 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330, + 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78 +}; + +/* PPP's Asynchronous-Control-Character-Map. The mask array is used + * to select the specific bit for a character. */ +static u_char pppACCMMask[] = { + 0x01, + 0x02, + 0x04, + 0x08, + 0x10, + 0x20, + 0x40, + 0x80 +}; + +#if PPP_INPROC_OWNTHREAD +/** Wake up the task blocked in reading from serial line (if any) */ +static void +pppRecvWakeup(int pd) +{ + PPPDEBUG(LOG_DEBUG, ("pppRecvWakeup: unit %d\n", pd)); + if (pppControl[pd].openFlag != 0) { + sio_read_abort(pppControl[pd].fd); + } +} +#endif /* PPP_INPROC_OWNTHREAD */ +#endif /* PPPOS_SUPPORT */ + +void +pppLinkTerminated(int pd) +{ + PPPDEBUG(LOG_DEBUG, ("pppLinkTerminated: unit %d\n", pd)); + +#if PPPOE_SUPPORT + if (pppControl[pd].ethif) { + pppoe_disconnect(pppControl[pd].pppoe_sc); + } else +#endif /* PPPOE_SUPPORT */ + { +#if PPPOS_SUPPORT + PPPControl* pc; +#if PPP_INPROC_OWNTHREAD + pppRecvWakeup(pd); +#endif /* PPP_INPROC_OWNTHREAD */ + pc = &pppControl[pd]; + + PPPDEBUG(LOG_DEBUG, ("pppLinkTerminated: unit %d: linkStatusCB=%p errCode=%d\n", pd, pc->linkStatusCB, pc->errCode)); + if (pc->linkStatusCB) { + pc->linkStatusCB(pc->linkStatusCtx, pc->errCode ? pc->errCode : PPPERR_PROTOCOL, NULL); + } + + pc->openFlag = 0;/**/ +#endif /* PPPOS_SUPPORT */ + } + PPPDEBUG(LOG_DEBUG, ("pppLinkTerminated: finished.\n")); +} + +void +pppLinkDown(int pd) +{ + PPPDEBUG(LOG_DEBUG, ("pppLinkDown: unit %d\n", pd)); + +#if PPPOE_SUPPORT + if (pppControl[pd].ethif) { + pppoe_disconnect(pppControl[pd].pppoe_sc); + } else +#endif /* PPPOE_SUPPORT */ + { +#if PPPOS_SUPPORT && PPP_INPROC_OWNTHREAD + pppRecvWakeup(pd); +#endif /* PPPOS_SUPPORT && PPP_INPROC_OWNTHREAD*/ + } +} + +/** Initiate LCP open request */ +static void +pppStart(int pd) +{ + PPPDEBUG(LOG_DEBUG, ("pppStart: unit %d\n", pd)); + lcp_lowerup(pd); + lcp_open(pd); /* Start protocol */ + PPPDEBUG(LOG_DEBUG, ("pppStart: finished\n")); +} + +/** LCP close request */ +static void +pppStop(int pd) +{ + PPPDEBUG(LOG_DEBUG, ("pppStop: unit %d\n", pd)); + lcp_close(pd, "User request"); +} + +/** Called when carrier/link is lost */ +static void +pppHup(int pd) +{ + PPPDEBUG(LOG_DEBUG, ("pppHupCB: unit %d\n", pd)); + lcp_lowerdown(pd); + link_terminated(pd); +} + +/***********************************/ +/*** PUBLIC FUNCTION DEFINITIONS ***/ +/***********************************/ +/* Initialize the PPP subsystem. */ + +struct ppp_settings ppp_settings; + +void +pppInit(void) +{ + struct protent *protp; + int i, j; + + memset(&ppp_settings, 0, sizeof(ppp_settings)); + ppp_settings.usepeerdns = 1; + pppSetAuth(PPPAUTHTYPE_NONE, NULL, NULL); + + magicInit(); + + subnetMask = PP_HTONL(0xffffff00UL); + + for (i = 0; i < NUM_PPP; i++) { + /* Initialize each protocol to the standard option set. */ + for (j = 0; (protp = ppp_protocols[j]) != NULL; ++j) { + (*protp->init)(i); + } + } +} + +void +pppSetAuth(enum pppAuthType authType, const char *user, const char *passwd) +{ + switch(authType) { + case PPPAUTHTYPE_NONE: + default: +#ifdef LWIP_PPP_STRICT_PAP_REJECT + ppp_settings.refuse_pap = 1; +#else /* LWIP_PPP_STRICT_PAP_REJECT */ + /* some providers request pap and accept an empty login/pw */ + ppp_settings.refuse_pap = 0; +#endif /* LWIP_PPP_STRICT_PAP_REJECT */ + ppp_settings.refuse_chap = 1; + break; + + case PPPAUTHTYPE_ANY: + /* Warning: Using PPPAUTHTYPE_ANY might have security consequences. + * RFC 1994 says: + * + * In practice, within or associated with each PPP server, there is a + * database which associates "user" names with authentication + * information ("secrets"). It is not anticipated that a particular + * named user would be authenticated by multiple methods. This would + * make the user vulnerable to attacks which negotiate the least secure + * method from among a set (such as PAP rather than CHAP). If the same + * secret was used, PAP would reveal the secret to be used later with + * CHAP. + * + * Instead, for each user name there should be an indication of exactly + * one method used to authenticate that user name. If a user needs to + * make use of different authentication methods under different + * circumstances, then distinct user names SHOULD be employed, each of + * which identifies exactly one authentication method. + * + */ + ppp_settings.refuse_pap = 0; + ppp_settings.refuse_chap = 0; + break; + + case PPPAUTHTYPE_PAP: + ppp_settings.refuse_pap = 0; + ppp_settings.refuse_chap = 1; + break; + + case PPPAUTHTYPE_CHAP: + ppp_settings.refuse_pap = 1; + ppp_settings.refuse_chap = 0; + break; + } + + if(user) { + strncpy(ppp_settings.user, user, sizeof(ppp_settings.user)-1); + ppp_settings.user[sizeof(ppp_settings.user)-1] = '\0'; + } else { + ppp_settings.user[0] = '\0'; + } + + if(passwd) { + strncpy(ppp_settings.passwd, passwd, sizeof(ppp_settings.passwd)-1); + ppp_settings.passwd[sizeof(ppp_settings.passwd)-1] = '\0'; + } else { + ppp_settings.passwd[0] = '\0'; + } +} + +#if PPPOS_SUPPORT +/** Open a new PPP connection using the given I/O device. + * This initializes the PPP control block but does not + * attempt to negotiate the LCP session. If this port + * connects to a modem, the modem connection must be + * established before calling this. + * Return a new PPP connection descriptor on success or + * an error code (negative) on failure. + * + * pppOpen() is directly defined to this function. + */ +int +pppOverSerialOpen(sio_fd_t fd, pppLinkStatusCB_fn linkStatusCB, void *linkStatusCtx) +{ + PPPControl *pc; + int pd; + + if (linkStatusCB == NULL) { + /* PPP is single-threaded: without a callback, + * there is no way to know when the link is up. */ + return PPPERR_PARAM; + } + + /* Find a free PPP session descriptor. */ + for (pd = 0; pd < NUM_PPP && pppControl[pd].openFlag != 0; pd++); + + if (pd >= NUM_PPP) { + pd = PPPERR_OPEN; + } else { + pc = &pppControl[pd]; + /* input pbuf left over from last session? */ + pppFreeCurrentInputPacket(&pc->rx); + /* @todo: is this correct or do I overwrite something? */ + memset(pc, 0, sizeof(PPPControl)); + pc->rx.pd = pd; + pc->rx.fd = fd; + + pc->openFlag = 1; + pc->fd = fd; + +#if VJ_SUPPORT + vj_compress_init(&pc->vjComp); +#endif /* VJ_SUPPORT */ + + /* + * Default the in and out accm so that escape and flag characters + * are always escaped. + */ + pc->rx.inACCM[15] = 0x60; /* no need to protect since RX is not running */ + pc->outACCM[15] = 0x60; + + pc->linkStatusCB = linkStatusCB; + pc->linkStatusCtx = linkStatusCtx; + + /* + * Start the connection and handle incoming events (packet or timeout). + */ + PPPDEBUG(LOG_INFO, ("pppOverSerialOpen: unit %d: Connecting\n", pd)); + pppStart(pd); +#if PPP_INPROC_OWNTHREAD + sys_thread_new(PPP_THREAD_NAME, pppInputThread, (void*)&pc->rx, PPP_THREAD_STACKSIZE, PPP_THREAD_PRIO); +#endif /* PPP_INPROC_OWNTHREAD */ + } + + return pd; +} +#endif /* PPPOS_SUPPORT */ + +#if PPPOE_SUPPORT +static void pppOverEthernetLinkStatusCB(int pd, int up); + +void +pppOverEthernetClose(int pd) +{ + PPPControl* pc = &pppControl[pd]; + + /* *TJL* There's no lcp_deinit */ + lcp_close(pd, NULL); + + pppoe_destroy(&pc->netif); +} + +int pppOverEthernetOpen(struct netif *ethif, const char *service_name, const char *concentrator_name, + pppLinkStatusCB_fn linkStatusCB, void *linkStatusCtx) +{ + PPPControl *pc; + int pd; + + LWIP_UNUSED_ARG(service_name); + LWIP_UNUSED_ARG(concentrator_name); + + if (linkStatusCB == NULL) { + /* PPP is single-threaded: without a callback, + * there is no way to know when the link is up. */ + return PPPERR_PARAM; + } + + /* Find a free PPP session descriptor. Critical region? */ + for (pd = 0; pd < NUM_PPP && pppControl[pd].openFlag != 0; pd++); + if (pd >= NUM_PPP) { + pd = PPPERR_OPEN; + } else { + pc = &pppControl[pd]; + memset(pc, 0, sizeof(PPPControl)); + pc->openFlag = 1; + pc->ethif = ethif; + + pc->linkStatusCB = linkStatusCB; + pc->linkStatusCtx = linkStatusCtx; + + lcp_wantoptions[pd].mru = PPPOE_MAXMTU; + lcp_wantoptions[pd].neg_asyncmap = 0; + lcp_wantoptions[pd].neg_pcompression = 0; + lcp_wantoptions[pd].neg_accompression = 0; + + lcp_allowoptions[pd].mru = PPPOE_MAXMTU; + lcp_allowoptions[pd].neg_asyncmap = 0; + lcp_allowoptions[pd].neg_pcompression = 0; + lcp_allowoptions[pd].neg_accompression = 0; + + if(pppoe_create(ethif, pd, pppOverEthernetLinkStatusCB, &pc->pppoe_sc) != ERR_OK) { + pc->openFlag = 0; + return PPPERR_OPEN; + } + + pppoe_connect(pc->pppoe_sc); + } + + return pd; +} +#endif /* PPPOE_SUPPORT */ + + +/* Close a PPP connection and release the descriptor. + * Any outstanding packets in the queues are dropped. + * Return 0 on success, an error code on failure. */ +int +pppClose(int pd) +{ + PPPControl *pc = &pppControl[pd]; + int st = 0; + + PPPDEBUG(LOG_DEBUG, ("pppClose() called\n")); + + /* Disconnect */ +#if PPPOE_SUPPORT + if(pc->ethif) { + PPPDEBUG(LOG_DEBUG, ("pppClose: unit %d kill_link -> pppStop\n", pd)); + pc->errCode = PPPERR_USER; + /* This will leave us at PHASE_DEAD. */ + pppStop(pd); + } else +#endif /* PPPOE_SUPPORT */ + { +#if PPPOS_SUPPORT + PPPDEBUG(LOG_DEBUG, ("pppClose: unit %d kill_link -> pppStop\n", pd)); + pc->errCode = PPPERR_USER; + /* This will leave us at PHASE_DEAD. */ + pppStop(pd); +#if PPP_INPROC_OWNTHREAD + pppRecvWakeup(pd); +#endif /* PPP_INPROC_OWNTHREAD */ +#endif /* PPPOS_SUPPORT */ + } + + return st; +} + +/* This function is called when carrier is lost on the PPP channel. */ +void +pppSigHUP(int pd) +{ + PPPDEBUG(LOG_DEBUG, ("pppSigHUP: unit %d sig_hup -> pppHupCB\n", pd)); + pppHup(pd); +} + +#if PPPOS_SUPPORT +static void +nPut(PPPControl *pc, struct pbuf *nb) +{ + struct pbuf *b; + int c; + + for(b = nb; b != NULL; b = b->next) { + if((c = sio_write(pc->fd, b->payload, b->len)) != b->len) { + PPPDEBUG(LOG_WARNING, + ("PPP nPut: incomplete sio_write(fd:%"SZT_F", len:%d, c: 0x%"X8_F") c = %d\n", (size_t)pc->fd, b->len, c, c)); + LINK_STATS_INC(link.err); + pc->lastXMit = 0; /* prepend PPP_FLAG to next packet */ + snmp_inc_ifoutdiscards(&pc->netif); + pbuf_free(nb); + return; + } + } + + snmp_add_ifoutoctets(&pc->netif, nb->tot_len); + snmp_inc_ifoutucastpkts(&pc->netif); + pbuf_free(nb); + LINK_STATS_INC(link.xmit); +} + +/* + * pppAppend - append given character to end of given pbuf. If outACCM + * is not NULL and the character needs to be escaped, do so. + * If pbuf is full, append another. + * Return the current pbuf. + */ +static struct pbuf * +pppAppend(u_char c, struct pbuf *nb, ext_accm *outACCM) +{ + struct pbuf *tb = nb; + + /* Make sure there is room for the character and an escape code. + * Sure we don't quite fill the buffer if the character doesn't + * get escaped but is one character worth complicating this? */ + /* Note: We assume no packet header. */ + if (nb && (PBUF_POOL_BUFSIZE - nb->len) < 2) { + tb = pbuf_alloc(PBUF_RAW, 0, PBUF_POOL); + if (tb) { + nb->next = tb; + } else { + LINK_STATS_INC(link.memerr); + } + nb = tb; + } + + if (nb) { + if (outACCM && ESCAPE_P(*outACCM, c)) { + *((u_char*)nb->payload + nb->len++) = PPP_ESCAPE; + *((u_char*)nb->payload + nb->len++) = c ^ PPP_TRANS; + } else { + *((u_char*)nb->payload + nb->len++) = c; + } + } + + return tb; +} +#endif /* PPPOS_SUPPORT */ + +#if PPPOE_SUPPORT +static err_t +pppifOutputOverEthernet(int pd, struct pbuf *p) +{ + PPPControl *pc = &pppControl[pd]; + struct pbuf *pb; + u_short protocol = PPP_IP; + int i=0; + u16_t tot_len; + + /* @todo: try to use pbuf_header() here! */ + pb = pbuf_alloc(PBUF_LINK, PPPOE_HDRLEN + sizeof(protocol), PBUF_RAM); + if(!pb) { + LINK_STATS_INC(link.memerr); + LINK_STATS_INC(link.proterr); + snmp_inc_ifoutdiscards(&pc->netif); + return ERR_MEM; + } + + pbuf_header(pb, -(s16_t)PPPOE_HDRLEN); + + pc->lastXMit = sys_jiffies(); + + if (!pc->pcomp || protocol > 0xFF) { + *((u_char*)pb->payload + i++) = (protocol >> 8) & 0xFF; + } + *((u_char*)pb->payload + i) = protocol & 0xFF; + + pbuf_chain(pb, p); + tot_len = pb->tot_len; + + if(pppoe_xmit(pc->pppoe_sc, pb) != ERR_OK) { + LINK_STATS_INC(link.err); + snmp_inc_ifoutdiscards(&pc->netif); + return PPPERR_DEVICE; + } + + snmp_add_ifoutoctets(&pc->netif, tot_len); + snmp_inc_ifoutucastpkts(&pc->netif); + LINK_STATS_INC(link.xmit); + return ERR_OK; +} +#endif /* PPPOE_SUPPORT */ + +/* Send a packet on the given connection. */ +static err_t +pppifOutput(struct netif *netif, struct pbuf *pb, ip_addr_t *ipaddr) +{ + int pd = (int)(size_t)netif->state; + PPPControl *pc = &pppControl[pd]; +#if PPPOS_SUPPORT + u_short protocol = PPP_IP; + u_int fcsOut = PPP_INITFCS; + struct pbuf *headMB = NULL, *tailMB = NULL, *p; + u_char c; +#endif /* PPPOS_SUPPORT */ + + LWIP_UNUSED_ARG(ipaddr); + + /* Validate parameters. */ + /* We let any protocol value go through - it can't hurt us + * and the peer will just drop it if it's not accepting it. */ + if (pd < 0 || pd >= NUM_PPP || !pc->openFlag || !pb) { + PPPDEBUG(LOG_WARNING, ("pppifOutput[%d]: bad parms prot=%d pb=%p\n", + pd, PPP_IP, pb)); + LINK_STATS_INC(link.opterr); + LINK_STATS_INC(link.drop); + snmp_inc_ifoutdiscards(netif); + return ERR_ARG; + } + + /* Check that the link is up. */ + if (lcp_phase[pd] == PHASE_DEAD) { + PPPDEBUG(LOG_ERR, ("pppifOutput[%d]: link not up\n", pd)); + LINK_STATS_INC(link.rterr); + LINK_STATS_INC(link.drop); + snmp_inc_ifoutdiscards(netif); + return ERR_RTE; + } + +#if PPPOE_SUPPORT + if(pc->ethif) { + return pppifOutputOverEthernet(pd, pb); + } +#endif /* PPPOE_SUPPORT */ + +#if PPPOS_SUPPORT + /* Grab an output buffer. */ + headMB = pbuf_alloc(PBUF_RAW, 0, PBUF_POOL); + if (headMB == NULL) { + PPPDEBUG(LOG_WARNING, ("pppifOutput[%d]: first alloc fail\n", pd)); + LINK_STATS_INC(link.memerr); + LINK_STATS_INC(link.drop); + snmp_inc_ifoutdiscards(netif); + return ERR_MEM; + } + +#if VJ_SUPPORT + /* + * Attempt Van Jacobson header compression if VJ is configured and + * this is an IP packet. + */ + if (protocol == PPP_IP && pc->vjEnabled) { + switch (vj_compress_tcp(&pc->vjComp, pb)) { + case TYPE_IP: + /* No change... + protocol = PPP_IP_PROTOCOL; */ + break; + case TYPE_COMPRESSED_TCP: + protocol = PPP_VJC_COMP; + break; + case TYPE_UNCOMPRESSED_TCP: + protocol = PPP_VJC_UNCOMP; + break; + default: + PPPDEBUG(LOG_WARNING, ("pppifOutput[%d]: bad IP packet\n", pd)); + LINK_STATS_INC(link.proterr); + LINK_STATS_INC(link.drop); + snmp_inc_ifoutdiscards(netif); + pbuf_free(headMB); + return ERR_VAL; + } + } +#endif /* VJ_SUPPORT */ + + tailMB = headMB; + + /* Build the PPP header. */ + if ((sys_jiffies() - pc->lastXMit) >= PPP_MAXIDLEFLAG) { + tailMB = pppAppend(PPP_FLAG, tailMB, NULL); + } + + pc->lastXMit = sys_jiffies(); + if (!pc->accomp) { + fcsOut = PPP_FCS(fcsOut, PPP_ALLSTATIONS); + tailMB = pppAppend(PPP_ALLSTATIONS, tailMB, &pc->outACCM); + fcsOut = PPP_FCS(fcsOut, PPP_UI); + tailMB = pppAppend(PPP_UI, tailMB, &pc->outACCM); + } + if (!pc->pcomp || protocol > 0xFF) { + c = (protocol >> 8) & 0xFF; + fcsOut = PPP_FCS(fcsOut, c); + tailMB = pppAppend(c, tailMB, &pc->outACCM); + } + c = protocol & 0xFF; + fcsOut = PPP_FCS(fcsOut, c); + tailMB = pppAppend(c, tailMB, &pc->outACCM); + + /* Load packet. */ + for(p = pb; p; p = p->next) { + int n; + u_char *sPtr; + + sPtr = (u_char*)p->payload; + n = p->len; + while (n-- > 0) { + c = *sPtr++; + + /* Update FCS before checking for special characters. */ + fcsOut = PPP_FCS(fcsOut, c); + + /* Copy to output buffer escaping special characters. */ + tailMB = pppAppend(c, tailMB, &pc->outACCM); + } + } + + /* Add FCS and trailing flag. */ + c = ~fcsOut & 0xFF; + tailMB = pppAppend(c, tailMB, &pc->outACCM); + c = (~fcsOut >> 8) & 0xFF; + tailMB = pppAppend(c, tailMB, &pc->outACCM); + tailMB = pppAppend(PPP_FLAG, tailMB, NULL); + + /* If we failed to complete the packet, throw it away. */ + if (!tailMB) { + PPPDEBUG(LOG_WARNING, + ("pppifOutput[%d]: Alloc err - dropping proto=%d\n", + pd, protocol)); + pbuf_free(headMB); + LINK_STATS_INC(link.memerr); + LINK_STATS_INC(link.drop); + snmp_inc_ifoutdiscards(netif); + return ERR_MEM; + } + + /* Send it. */ + PPPDEBUG(LOG_INFO, ("pppifOutput[%d]: proto=0x%"X16_F"\n", pd, protocol)); + + nPut(pc, headMB); +#endif /* PPPOS_SUPPORT */ + + return ERR_OK; +} + +/* Get and set parameters for the given connection. + * Return 0 on success, an error code on failure. */ +int +pppIOCtl(int pd, int cmd, void *arg) +{ + PPPControl *pc = &pppControl[pd]; + int st = 0; + + if (pd < 0 || pd >= NUM_PPP) { + st = PPPERR_PARAM; + } else { + switch(cmd) { + case PPPCTLG_UPSTATUS: /* Get the PPP up status. */ + if (arg) { + *(int *)arg = (int)(pc->if_up); + } else { + st = PPPERR_PARAM; + } + break; + case PPPCTLS_ERRCODE: /* Set the PPP error code. */ + if (arg) { + pc->errCode = *(int *)arg; + } else { + st = PPPERR_PARAM; + } + break; + case PPPCTLG_ERRCODE: /* Get the PPP error code. */ + if (arg) { + *(int *)arg = (int)(pc->errCode); + } else { + st = PPPERR_PARAM; + } + break; +#if PPPOS_SUPPORT + case PPPCTLG_FD: /* Get the fd associated with the ppp */ + if (arg) { + *(sio_fd_t *)arg = pc->fd; + } else { + st = PPPERR_PARAM; + } + break; +#endif /* PPPOS_SUPPORT */ + default: + st = PPPERR_PARAM; + break; + } + } + + return st; +} + +/* + * Return the Maximum Transmission Unit for the given PPP connection. + */ +u_short +pppMTU(int pd) +{ + PPPControl *pc = &pppControl[pd]; + u_short st; + + /* Validate parameters. */ + if (pd < 0 || pd >= NUM_PPP || !pc->openFlag) { + st = 0; + } else { + st = pc->mtu; + } + + return st; +} + +#if PPPOE_SUPPORT +int +pppWriteOverEthernet(int pd, const u_char *s, int n) +{ + PPPControl *pc = &pppControl[pd]; + struct pbuf *pb; + + /* skip address & flags */ + s += 2; + n -= 2; + + LWIP_ASSERT("PPPOE_HDRLEN + n <= 0xffff", PPPOE_HDRLEN + n <= 0xffff); + pb = pbuf_alloc(PBUF_LINK, (u16_t)(PPPOE_HDRLEN + n), PBUF_RAM); + if(!pb) { + LINK_STATS_INC(link.memerr); + LINK_STATS_INC(link.proterr); + snmp_inc_ifoutdiscards(&pc->netif); + return PPPERR_ALLOC; + } + + pbuf_header(pb, -(s16_t)PPPOE_HDRLEN); + + pc->lastXMit = sys_jiffies(); + + MEMCPY(pb->payload, s, n); + + if(pppoe_xmit(pc->pppoe_sc, pb) != ERR_OK) { + LINK_STATS_INC(link.err); + snmp_inc_ifoutdiscards(&pc->netif); + return PPPERR_DEVICE; + } + + snmp_add_ifoutoctets(&pc->netif, (u16_t)n); + snmp_inc_ifoutucastpkts(&pc->netif); + LINK_STATS_INC(link.xmit); + return PPPERR_NONE; +} +#endif /* PPPOE_SUPPORT */ + +/* + * Write n characters to a ppp link. + * RETURN: >= 0 Number of characters written + * -1 Failed to write to device + */ +int +pppWrite(int pd, const u_char *s, int n) +{ + PPPControl *pc = &pppControl[pd]; +#if PPPOS_SUPPORT + u_char c; + u_int fcsOut; + struct pbuf *headMB, *tailMB; +#endif /* PPPOS_SUPPORT */ + +#if PPPOE_SUPPORT + if(pc->ethif) { + return pppWriteOverEthernet(pd, s, n); + } +#endif /* PPPOE_SUPPORT */ + +#if PPPOS_SUPPORT + headMB = pbuf_alloc(PBUF_RAW, 0, PBUF_POOL); + if (headMB == NULL) { + LINK_STATS_INC(link.memerr); + LINK_STATS_INC(link.proterr); + snmp_inc_ifoutdiscards(&pc->netif); + return PPPERR_ALLOC; + } + + tailMB = headMB; + + /* If the link has been idle, we'll send a fresh flag character to + * flush any noise. */ + if ((sys_jiffies() - pc->lastXMit) >= PPP_MAXIDLEFLAG) { + tailMB = pppAppend(PPP_FLAG, tailMB, NULL); + } + pc->lastXMit = sys_jiffies(); + + fcsOut = PPP_INITFCS; + /* Load output buffer. */ + while (n-- > 0) { + c = *s++; + + /* Update FCS before checking for special characters. */ + fcsOut = PPP_FCS(fcsOut, c); + + /* Copy to output buffer escaping special characters. */ + tailMB = pppAppend(c, tailMB, &pc->outACCM); + } + + /* Add FCS and trailing flag. */ + c = ~fcsOut & 0xFF; + tailMB = pppAppend(c, tailMB, &pc->outACCM); + c = (~fcsOut >> 8) & 0xFF; + tailMB = pppAppend(c, tailMB, &pc->outACCM); + tailMB = pppAppend(PPP_FLAG, tailMB, NULL); + + /* If we failed to complete the packet, throw it away. + * Otherwise send it. */ + if (!tailMB) { + PPPDEBUG(LOG_WARNING, + ("pppWrite[%d]: Alloc err - dropping pbuf len=%d\n", pd, headMB->len)); + /*"pppWrite[%d]: Alloc err - dropping %d:%.*H", pd, headMB->len, LWIP_MIN(headMB->len * 2, 40), headMB->payload)); */ + pbuf_free(headMB); + LINK_STATS_INC(link.memerr); + LINK_STATS_INC(link.proterr); + snmp_inc_ifoutdiscards(&pc->netif); + return PPPERR_ALLOC; + } + + PPPDEBUG(LOG_INFO, ("pppWrite[%d]: len=%d\n", pd, headMB->len)); + /* "pppWrite[%d]: %d:%.*H", pd, headMB->len, LWIP_MIN(headMB->len * 2, 40), headMB->payload)); */ + nPut(pc, headMB); +#endif /* PPPOS_SUPPORT */ + + return PPPERR_NONE; +} + +/* + * ppp_send_config - configure the transmit characteristics of + * the ppp interface. + */ +void +ppp_send_config( int unit, u16_t mtu, u32_t asyncmap, int pcomp, int accomp) +{ + PPPControl *pc = &pppControl[unit]; + int i; + + pc->mtu = mtu; + pc->pcomp = pcomp; + pc->accomp = accomp; + + /* Load the ACCM bits for the 32 control codes. */ + for (i = 0; i < 32/8; i++) { + pc->outACCM[i] = (u_char)((asyncmap >> (8 * i)) & 0xFF); + } + PPPDEBUG(LOG_INFO, ("ppp_send_config[%d]: outACCM=%X %X %X %X\n", + unit, + pc->outACCM[0], pc->outACCM[1], pc->outACCM[2], pc->outACCM[3])); +} + + +/* + * ppp_set_xaccm - set the extended transmit ACCM for the interface. + */ +void +ppp_set_xaccm(int unit, ext_accm *accm) +{ + SMEMCPY(pppControl[unit].outACCM, accm, sizeof(ext_accm)); + PPPDEBUG(LOG_INFO, ("ppp_set_xaccm[%d]: outACCM=%X %X %X %X\n", + unit, + pppControl[unit].outACCM[0], + pppControl[unit].outACCM[1], + pppControl[unit].outACCM[2], + pppControl[unit].outACCM[3])); +} + + +/* + * ppp_recv_config - configure the receive-side characteristics of + * the ppp interface. + */ +void +ppp_recv_config( int unit, int mru, u32_t asyncmap, int pcomp, int accomp) +{ + PPPControl *pc = &pppControl[unit]; + int i; + SYS_ARCH_DECL_PROTECT(lev); + + LWIP_UNUSED_ARG(accomp); + LWIP_UNUSED_ARG(pcomp); + LWIP_UNUSED_ARG(mru); + + /* Load the ACCM bits for the 32 control codes. */ + SYS_ARCH_PROTECT(lev); + for (i = 0; i < 32 / 8; i++) { + /* @todo: does this work? ext_accm has been modified from pppd! */ + pc->rx.inACCM[i] = (u_char)(asyncmap >> (i * 8)); + } + SYS_ARCH_UNPROTECT(lev); + PPPDEBUG(LOG_INFO, ("ppp_recv_config[%d]: inACCM=%X %X %X %X\n", + unit, + pc->rx.inACCM[0], pc->rx.inACCM[1], pc->rx.inACCM[2], pc->rx.inACCM[3])); +} + +#if 0 +/* + * ccp_test - ask kernel whether a given compression method + * is acceptable for use. Returns 1 if the method and parameters + * are OK, 0 if the method is known but the parameters are not OK + * (e.g. code size should be reduced), or -1 if the method is unknown. + */ +int +ccp_test( int unit, int opt_len, int for_transmit, u_char *opt_ptr) +{ + return 0; /* XXX Currently no compression. */ +} + +/* + * ccp_flags_set - inform kernel about the current state of CCP. + */ +void +ccp_flags_set(int unit, int isopen, int isup) +{ + /* XXX */ +} + +/* + * ccp_fatal_error - returns 1 if decompression was disabled as a + * result of an error detected after decompression of a packet, + * 0 otherwise. This is necessary because of patent nonsense. + */ +int +ccp_fatal_error(int unit) +{ + /* XXX */ + return 0; +} +#endif + +/* + * get_idle_time - return how long the link has been idle. + */ +int +get_idle_time(int u, struct ppp_idle *ip) +{ + /* XXX */ + LWIP_UNUSED_ARG(u); + LWIP_UNUSED_ARG(ip); + + return 0; +} + + +/* + * Return user specified netmask, modified by any mask we might determine + * for address `addr' (in network byte order). + * Here we scan through the system's list of interfaces, looking for + * any non-point-to-point interfaces which might appear to be on the same + * network as `addr'. If we find any, we OR in their netmask to the + * user-specified netmask. + */ +u32_t +GetMask(u32_t addr) +{ + u32_t mask, nmask; + + addr = htonl(addr); + if (IP_CLASSA(addr)) { /* determine network mask for address class */ + nmask = IP_CLASSA_NET; + } else if (IP_CLASSB(addr)) { + nmask = IP_CLASSB_NET; + } else { + nmask = IP_CLASSC_NET; + } + + /* class D nets are disallowed by bad_ip_adrs */ + mask = subnetMask | htonl(nmask); + + /* XXX + * Scan through the system's network interfaces. + * Get each netmask and OR them into our mask. + */ + + return mask; +} + +/* + * sifvjcomp - config tcp header compression + */ +int +sifvjcomp(int pd, int vjcomp, u8_t cidcomp, u8_t maxcid) +{ +#if PPPOS_SUPPORT && VJ_SUPPORT + PPPControl *pc = &pppControl[pd]; + + pc->vjEnabled = vjcomp; + pc->vjComp.compressSlot = cidcomp; + pc->vjComp.maxSlotIndex = maxcid; + PPPDEBUG(LOG_INFO, ("sifvjcomp: VJ compress enable=%d slot=%d max slot=%d\n", + vjcomp, cidcomp, maxcid)); +#else /* PPPOS_SUPPORT && VJ_SUPPORT */ + LWIP_UNUSED_ARG(pd); + LWIP_UNUSED_ARG(vjcomp); + LWIP_UNUSED_ARG(cidcomp); + LWIP_UNUSED_ARG(maxcid); +#endif /* PPPOS_SUPPORT && VJ_SUPPORT */ + + return 0; +} + +/* + * pppifNetifInit - netif init callback + */ +static err_t +pppifNetifInit(struct netif *netif) +{ + netif->name[0] = 'p'; + netif->name[1] = 'p'; + netif->output = pppifOutput; + netif->mtu = pppMTU((int)(size_t)netif->state); + netif->flags = NETIF_FLAG_POINTTOPOINT | NETIF_FLAG_LINK_UP; +#if LWIP_NETIF_HOSTNAME + /* @todo: Initialize interface hostname */ + /* netif_set_hostname(netif, "lwip"); */ +#endif /* LWIP_NETIF_HOSTNAME */ + return ERR_OK; +} + + +/* + * sifup - Config the interface up and enable IP packets to pass. + */ +int +sifup(int pd) +{ + PPPControl *pc = &pppControl[pd]; + int st = 1; + + if (pd < 0 || pd >= NUM_PPP || !pc->openFlag) { + st = 0; + PPPDEBUG(LOG_WARNING, ("sifup[%d]: bad parms\n", pd)); + } else { + netif_remove(&pc->netif); + if (netif_add(&pc->netif, &pc->addrs.our_ipaddr, &pc->addrs.netmask, + &pc->addrs.his_ipaddr, (void *)(size_t)pd, pppifNetifInit, ip_input)) { + netif_set_up(&pc->netif); + pc->if_up = 1; + pc->errCode = PPPERR_NONE; + + PPPDEBUG(LOG_DEBUG, ("sifup: unit %d: linkStatusCB=%p errCode=%d\n", pd, pc->linkStatusCB, pc->errCode)); + if (pc->linkStatusCB) { + pc->linkStatusCB(pc->linkStatusCtx, pc->errCode, &pc->addrs); + } + } else { + st = 0; + PPPDEBUG(LOG_ERR, ("sifup[%d]: netif_add failed\n", pd)); + } + } + + return st; +} + +/* + * sifnpmode - Set the mode for handling packets for a given NP. + */ +int +sifnpmode(int u, int proto, enum NPmode mode) +{ + LWIP_UNUSED_ARG(u); + LWIP_UNUSED_ARG(proto); + LWIP_UNUSED_ARG(mode); + return 0; +} + +/* + * sifdown - Config the interface down and disable IP. + */ +int +sifdown(int pd) +{ + PPPControl *pc = &pppControl[pd]; + int st = 1; + + if (pd < 0 || pd >= NUM_PPP || !pc->openFlag) { + st = 0; + PPPDEBUG(LOG_WARNING, ("sifdown[%d]: bad parms\n", pd)); + } else { + pc->if_up = 0; + /* make sure the netif status callback is called */ + netif_set_down(&pc->netif); + netif_remove(&pc->netif); + PPPDEBUG(LOG_DEBUG, ("sifdown: unit %d: linkStatusCB=%p errCode=%d\n", pd, pc->linkStatusCB, pc->errCode)); + if (pc->linkStatusCB) { + pc->linkStatusCB(pc->linkStatusCtx, PPPERR_CONNECT, NULL); + } + } + return st; +} + +/** + * sifaddr - Config the interface IP addresses and netmask. + * @param pd Interface unit ??? + * @param o Our IP address ??? + * @param h His IP address ??? + * @param m IP subnet mask ??? + * @param ns1 Primary DNS + * @param ns2 Secondary DNS + */ +int +sifaddr( int pd, u32_t o, u32_t h, u32_t m, u32_t ns1, u32_t ns2) +{ + PPPControl *pc = &pppControl[pd]; + int st = 1; + + if (pd < 0 || pd >= NUM_PPP || !pc->openFlag) { + st = 0; + PPPDEBUG(LOG_WARNING, ("sifup[%d]: bad parms\n", pd)); + } else { + SMEMCPY(&pc->addrs.our_ipaddr, &o, sizeof(o)); + SMEMCPY(&pc->addrs.his_ipaddr, &h, sizeof(h)); + SMEMCPY(&pc->addrs.netmask, &m, sizeof(m)); + SMEMCPY(&pc->addrs.dns1, &ns1, sizeof(ns1)); + SMEMCPY(&pc->addrs.dns2, &ns2, sizeof(ns2)); + } + return st; +} + +/** + * cifaddr - Clear the interface IP addresses, and delete routes + * through the interface if possible. + * @param pd Interface unit ??? + * @param o Our IP address ??? + * @param h IP broadcast address ??? + */ +int +cifaddr( int pd, u32_t o, u32_t h) +{ + PPPControl *pc = &pppControl[pd]; + int st = 1; + + LWIP_UNUSED_ARG(o); + LWIP_UNUSED_ARG(h); + if (pd < 0 || pd >= NUM_PPP || !pc->openFlag) { + st = 0; + PPPDEBUG(LOG_WARNING, ("sifup[%d]: bad parms\n", pd)); + } else { + IP4_ADDR(&pc->addrs.our_ipaddr, 0,0,0,0); + IP4_ADDR(&pc->addrs.his_ipaddr, 0,0,0,0); + IP4_ADDR(&pc->addrs.netmask, 255,255,255,0); + IP4_ADDR(&pc->addrs.dns1, 0,0,0,0); + IP4_ADDR(&pc->addrs.dns2, 0,0,0,0); + } + return st; +} + +/* + * sifdefaultroute - assign a default route through the address given. + */ +int +sifdefaultroute(int pd, u32_t l, u32_t g) +{ + PPPControl *pc = &pppControl[pd]; + int st = 1; + + LWIP_UNUSED_ARG(l); + LWIP_UNUSED_ARG(g); + + if (pd < 0 || pd >= NUM_PPP || !pc->openFlag) { + st = 0; + PPPDEBUG(LOG_WARNING, ("sifup[%d]: bad parms\n", pd)); + } else { + netif_set_default(&pc->netif); + } + + /* TODO: check how PPP handled the netMask, previously not set by ipSetDefault */ + + return st; +} + +/* + * cifdefaultroute - delete a default route through the address given. + */ +int +cifdefaultroute(int pd, u32_t l, u32_t g) +{ + PPPControl *pc = &pppControl[pd]; + int st = 1; + + LWIP_UNUSED_ARG(l); + LWIP_UNUSED_ARG(g); + + if (pd < 0 || pd >= NUM_PPP || !pc->openFlag) { + st = 0; + PPPDEBUG(LOG_WARNING, ("sifup[%d]: bad parms\n", pd)); + } else { + netif_set_default(NULL); + } + + return st; +} + +/**********************************/ +/*** LOCAL FUNCTION DEFINITIONS ***/ +/**********************************/ + +#if PPPOS_SUPPORT && PPP_INPROC_OWNTHREAD +/* The main PPP process function. This implements the state machine according + * to section 4 of RFC 1661: The Point-To-Point Protocol. */ +static void +pppInputThread(void *arg) +{ + int count; + PPPControlRx *pcrx = arg; + + while (lcp_phase[pcrx->pd] != PHASE_DEAD) { + count = sio_read(pcrx->fd, pcrx->rxbuf, PPPOS_RX_BUFSIZE); + if(count > 0) { + pppInProc(pcrx, pcrx->rxbuf, count); + } else { + /* nothing received, give other tasks a chance to run */ + sys_msleep(1); + } + } +} +#endif /* PPPOS_SUPPORT && PPP_INPROC_OWNTHREAD */ + +#if PPPOE_SUPPORT + +void +pppOverEthernetInitFailed(int pd) +{ + PPPControl* pc; + + pppHup(pd); + pppStop(pd); + + pc = &pppControl[pd]; + pppoe_destroy(&pc->netif); + pc->openFlag = 0; + + if(pc->linkStatusCB) { + pc->linkStatusCB(pc->linkStatusCtx, pc->errCode ? pc->errCode : PPPERR_PROTOCOL, NULL); + } +} + +static void +pppOverEthernetLinkStatusCB(int pd, int up) +{ + if(up) { + PPPDEBUG(LOG_INFO, ("pppOverEthernetLinkStatusCB: unit %d: Connecting\n", pd)); + pppStart(pd); + } else { + pppOverEthernetInitFailed(pd); + } +} +#endif /* PPPOE_SUPPORT */ + +struct pbuf * +pppSingleBuf(struct pbuf *p) +{ + struct pbuf *q, *b; + u_char *pl; + + if(p->tot_len == p->len) { + return p; + } + + q = pbuf_alloc(PBUF_RAW, p->tot_len, PBUF_RAM); + if(!q) { + PPPDEBUG(LOG_ERR, + ("pppSingleBuf: unable to alloc new buf (%d)\n", p->tot_len)); + return p; /* live dangerously */ + } + + for(b = p, pl = q->payload; b != NULL; b = b->next) { + MEMCPY(pl, b->payload, b->len); + pl += b->len; + } + + pbuf_free(p); + + return q; +} + +struct pppInputHeader { + int unit; + u16_t proto; +}; + +/* + * Pass the processed input packet to the appropriate handler. + * This function and all handlers run in the context of the tcpip_thread + */ +static void +pppInput(void *arg) +{ + struct pbuf *nb = (struct pbuf *)arg; + u16_t protocol; + int pd; + + pd = ((struct pppInputHeader *)nb->payload)->unit; + protocol = ((struct pppInputHeader *)nb->payload)->proto; + + if(pbuf_header(nb, -(int)sizeof(struct pppInputHeader))) { + LWIP_ASSERT("pbuf_header failed\n", 0); + goto drop; + } + + LINK_STATS_INC(link.recv); + snmp_inc_ifinucastpkts(&pppControl[pd].netif); + snmp_add_ifinoctets(&pppControl[pd].netif, nb->tot_len); + + /* + * Toss all non-LCP packets unless LCP is OPEN. + * Until we get past the authentication phase, toss all packets + * except LCP, LQR and authentication packets. + */ + if((lcp_phase[pd] <= PHASE_AUTHENTICATE) && (protocol != PPP_LCP)) { + if(!((protocol == PPP_LQR) || (protocol == PPP_PAP) || (protocol == PPP_CHAP)) || + (lcp_phase[pd] != PHASE_AUTHENTICATE)) { + PPPDEBUG(LOG_INFO, ("pppInput: discarding proto 0x%"X16_F" in phase %d\n", protocol, lcp_phase[pd])); + goto drop; + } + } + + switch(protocol) { + case PPP_VJC_COMP: /* VJ compressed TCP */ +#if PPPOS_SUPPORT && VJ_SUPPORT + PPPDEBUG(LOG_INFO, ("pppInput[%d]: vj_comp in pbuf len=%d\n", pd, nb->len)); + /* + * Clip off the VJ header and prepend the rebuilt TCP/IP header and + * pass the result to IP. + */ + if ((vj_uncompress_tcp(&nb, &pppControl[pd].vjComp) >= 0) && (pppControl[pd].netif.input)) { + pppControl[pd].netif.input(nb, &pppControl[pd].netif); + return; + } + /* Something's wrong so drop it. */ + PPPDEBUG(LOG_WARNING, ("pppInput[%d]: Dropping VJ compressed\n", pd)); +#else /* PPPOS_SUPPORT && VJ_SUPPORT */ + /* No handler for this protocol so drop the packet. */ + PPPDEBUG(LOG_INFO, ("pppInput[%d]: drop VJ Comp in %d:%s\n", pd, nb->len, nb->payload)); +#endif /* PPPOS_SUPPORT && VJ_SUPPORT */ + break; + + case PPP_VJC_UNCOMP: /* VJ uncompressed TCP */ +#if PPPOS_SUPPORT && VJ_SUPPORT + PPPDEBUG(LOG_INFO, ("pppInput[%d]: vj_un in pbuf len=%d\n", pd, nb->len)); + /* + * Process the TCP/IP header for VJ header compression and then pass + * the packet to IP. + */ + if ((vj_uncompress_uncomp(nb, &pppControl[pd].vjComp) >= 0) && pppControl[pd].netif.input) { + pppControl[pd].netif.input(nb, &pppControl[pd].netif); + return; + } + /* Something's wrong so drop it. */ + PPPDEBUG(LOG_WARNING, ("pppInput[%d]: Dropping VJ uncompressed\n", pd)); +#else /* PPPOS_SUPPORT && VJ_SUPPORT */ + /* No handler for this protocol so drop the packet. */ + PPPDEBUG(LOG_INFO, + ("pppInput[%d]: drop VJ UnComp in %d:.*H\n", + pd, nb->len, LWIP_MIN(nb->len * 2, 40), nb->payload)); +#endif /* PPPOS_SUPPORT && VJ_SUPPORT */ + break; + + case PPP_IP: /* Internet Protocol */ + PPPDEBUG(LOG_INFO, ("pppInput[%d]: ip in pbuf len=%d\n", pd, nb->len)); + if (pppControl[pd].netif.input) { + pppControl[pd].netif.input(nb, &pppControl[pd].netif); + return; + } + break; + + default: { + struct protent *protp; + int i; + + /* + * Upcall the proper protocol input routine. + */ + for (i = 0; (protp = ppp_protocols[i]) != NULL; ++i) { + if (protp->protocol == protocol && protp->enabled_flag) { + PPPDEBUG(LOG_INFO, ("pppInput[%d]: %s len=%d\n", pd, protp->name, nb->len)); + nb = pppSingleBuf(nb); + (*protp->input)(pd, nb->payload, nb->len); + PPPDEBUG(LOG_DETAIL, ("pppInput[%d]: packet processed\n", pd)); + goto out; + } + } + + /* No handler for this protocol so reject the packet. */ + PPPDEBUG(LOG_INFO, ("pppInput[%d]: rejecting unsupported proto 0x%"X16_F" len=%d\n", pd, protocol, nb->len)); + if (pbuf_header(nb, sizeof(protocol))) { + LWIP_ASSERT("pbuf_header failed\n", 0); + goto drop; + } +#if BYTE_ORDER == LITTLE_ENDIAN + protocol = htons(protocol); +#endif /* BYTE_ORDER == LITTLE_ENDIAN */ + SMEMCPY(nb->payload, &protocol, sizeof(protocol)); + lcp_sprotrej(pd, nb->payload, nb->len); + } + break; + } + +drop: + LINK_STATS_INC(link.drop); + snmp_inc_ifindiscards(&pppControl[pd].netif); + +out: + pbuf_free(nb); + return; +} + +#if PPPOS_SUPPORT +/* + * Drop the input packet. + */ +static void +pppFreeCurrentInputPacket(PPPControlRx *pcrx) +{ + if (pcrx->inHead != NULL) { + if (pcrx->inTail && (pcrx->inTail != pcrx->inHead)) { + pbuf_free(pcrx->inTail); + } + pbuf_free(pcrx->inHead); + pcrx->inHead = NULL; + } + pcrx->inTail = NULL; +} + +/* + * Drop the input packet and increase error counters. + */ +static void +pppDrop(PPPControlRx *pcrx) +{ + if (pcrx->inHead != NULL) { +#if 0 + PPPDEBUG(LOG_INFO, ("pppDrop: %d:%.*H\n", pcrx->inHead->len, min(60, pcrx->inHead->len * 2), pcrx->inHead->payload)); +#endif + PPPDEBUG(LOG_INFO, ("pppDrop: pbuf len=%d, addr %p\n", pcrx->inHead->len, (void*)pcrx->inHead)); + } + pppFreeCurrentInputPacket(pcrx); +#if VJ_SUPPORT + vj_uncompress_err(&pppControl[pcrx->pd].vjComp); +#endif /* VJ_SUPPORT */ + + LINK_STATS_INC(link.drop); + snmp_inc_ifindiscards(&pppControl[pcrx->pd].netif); +} + +#if !PPP_INPROC_OWNTHREAD +/** Pass received raw characters to PPPoS to be decoded. This function is + * thread-safe and can be called from a dedicated RX-thread or from a main-loop. + * + * @param pd PPP descriptor index, returned by pppOpen() + * @param data received data + * @param len length of received data + */ +void +pppos_input(int pd, u_char* data, int len) +{ + pppInProc(&pppControl[pd].rx, data, len); +} +#endif + +/** + * Process a received octet string. + */ +static void +pppInProc(PPPControlRx *pcrx, u_char *s, int l) +{ + struct pbuf *nextNBuf; + u_char curChar; + u_char escaped; + SYS_ARCH_DECL_PROTECT(lev); + + PPPDEBUG(LOG_DEBUG, ("pppInProc[%d]: got %d bytes\n", pcrx->pd, l)); + while (l-- > 0) { + curChar = *s++; + + SYS_ARCH_PROTECT(lev); + escaped = ESCAPE_P(pcrx->inACCM, curChar); + SYS_ARCH_UNPROTECT(lev); + /* Handle special characters. */ + if (escaped) { + /* Check for escape sequences. */ + /* XXX Note that this does not handle an escaped 0x5d character which + * would appear as an escape character. Since this is an ASCII ']' + * and there is no reason that I know of to escape it, I won't complicate + * the code to handle this case. GLL */ + if (curChar == PPP_ESCAPE) { + pcrx->inEscaped = 1; + /* Check for the flag character. */ + } else if (curChar == PPP_FLAG) { + /* If this is just an extra flag character, ignore it. */ + if (pcrx->inState <= PDADDRESS) { + /* ignore it */; + /* If we haven't received the packet header, drop what has come in. */ + } else if (pcrx->inState < PDDATA) { + PPPDEBUG(LOG_WARNING, + ("pppInProc[%d]: Dropping incomplete packet %d\n", + pcrx->pd, pcrx->inState)); + LINK_STATS_INC(link.lenerr); + pppDrop(pcrx); + /* If the fcs is invalid, drop the packet. */ + } else if (pcrx->inFCS != PPP_GOODFCS) { + PPPDEBUG(LOG_INFO, + ("pppInProc[%d]: Dropping bad fcs 0x%"X16_F" proto=0x%"X16_F"\n", + pcrx->pd, pcrx->inFCS, pcrx->inProtocol)); + /* Note: If you get lots of these, check for UART frame errors or try different baud rate */ + LINK_STATS_INC(link.chkerr); + pppDrop(pcrx); + /* Otherwise it's a good packet so pass it on. */ + } else { + struct pbuf *inp; + /* Trim off the checksum. */ + if(pcrx->inTail->len >= 2) { + pcrx->inTail->len -= 2; + + pcrx->inTail->tot_len = pcrx->inTail->len; + if (pcrx->inTail != pcrx->inHead) { + pbuf_cat(pcrx->inHead, pcrx->inTail); + } + } else { + pcrx->inTail->tot_len = pcrx->inTail->len; + if (pcrx->inTail != pcrx->inHead) { + pbuf_cat(pcrx->inHead, pcrx->inTail); + } + + pbuf_realloc(pcrx->inHead, pcrx->inHead->tot_len - 2); + } + + /* Dispatch the packet thereby consuming it. */ + inp = pcrx->inHead; + /* Packet consumed, release our references. */ + pcrx->inHead = NULL; + pcrx->inTail = NULL; +#if PPP_INPROC_MULTITHREADED + if(tcpip_callback_with_block(pppInput, inp, 0) != ERR_OK) { + PPPDEBUG(LOG_ERR, ("pppInProc[%d]: tcpip_callback() failed, dropping packet\n", pcrx->pd)); + pbuf_free(inp); + LINK_STATS_INC(link.drop); + snmp_inc_ifindiscards(&pppControl[pcrx->pd].netif); + } +#else /* PPP_INPROC_MULTITHREADED */ + pppInput(inp); +#endif /* PPP_INPROC_MULTITHREADED */ + } + + /* Prepare for a new packet. */ + pcrx->inFCS = PPP_INITFCS; + pcrx->inState = PDADDRESS; + pcrx->inEscaped = 0; + /* Other characters are usually control characters that may have + * been inserted by the physical layer so here we just drop them. */ + } else { + PPPDEBUG(LOG_WARNING, + ("pppInProc[%d]: Dropping ACCM char <%d>\n", pcrx->pd, curChar)); + } + /* Process other characters. */ + } else { + /* Unencode escaped characters. */ + if (pcrx->inEscaped) { + pcrx->inEscaped = 0; + curChar ^= PPP_TRANS; + } + + /* Process character relative to current state. */ + switch(pcrx->inState) { + case PDIDLE: /* Idle state - waiting. */ + /* Drop the character if it's not 0xff + * we would have processed a flag character above. */ + if (curChar != PPP_ALLSTATIONS) { + break; + } + + /* Fall through */ + case PDSTART: /* Process start flag. */ + /* Prepare for a new packet. */ + pcrx->inFCS = PPP_INITFCS; + + /* Fall through */ + case PDADDRESS: /* Process address field. */ + if (curChar == PPP_ALLSTATIONS) { + pcrx->inState = PDCONTROL; + break; + } + /* Else assume compressed address and control fields so + * fall through to get the protocol... */ + case PDCONTROL: /* Process control field. */ + /* If we don't get a valid control code, restart. */ + if (curChar == PPP_UI) { + pcrx->inState = PDPROTOCOL1; + break; + } +#if 0 + else { + PPPDEBUG(LOG_WARNING, + ("pppInProc[%d]: Invalid control <%d>\n", pcrx->pd, curChar)); + pcrx->inState = PDSTART; + } +#endif + case PDPROTOCOL1: /* Process protocol field 1. */ + /* If the lower bit is set, this is the end of the protocol + * field. */ + if (curChar & 1) { + pcrx->inProtocol = curChar; + pcrx->inState = PDDATA; + } else { + pcrx->inProtocol = (u_int)curChar << 8; + pcrx->inState = PDPROTOCOL2; + } + break; + case PDPROTOCOL2: /* Process protocol field 2. */ + pcrx->inProtocol |= curChar; + pcrx->inState = PDDATA; + break; + case PDDATA: /* Process data byte. */ + /* Make space to receive processed data. */ + if (pcrx->inTail == NULL || pcrx->inTail->len == PBUF_POOL_BUFSIZE) { + if (pcrx->inTail != NULL) { + pcrx->inTail->tot_len = pcrx->inTail->len; + if (pcrx->inTail != pcrx->inHead) { + pbuf_cat(pcrx->inHead, pcrx->inTail); + /* give up the inTail reference now */ + pcrx->inTail = NULL; + } + } + /* If we haven't started a packet, we need a packet header. */ + nextNBuf = pbuf_alloc(PBUF_RAW, 0, PBUF_POOL); + if (nextNBuf == NULL) { + /* No free buffers. Drop the input packet and let the + * higher layers deal with it. Continue processing + * the received pbuf chain in case a new packet starts. */ + PPPDEBUG(LOG_ERR, ("pppInProc[%d]: NO FREE MBUFS!\n", pcrx->pd)); + LINK_STATS_INC(link.memerr); + pppDrop(pcrx); + pcrx->inState = PDSTART; /* Wait for flag sequence. */ + break; + } + if (pcrx->inHead == NULL) { + struct pppInputHeader *pih = nextNBuf->payload; + + pih->unit = pcrx->pd; + pih->proto = pcrx->inProtocol; + + nextNBuf->len += sizeof(*pih); + + pcrx->inHead = nextNBuf; + } + pcrx->inTail = nextNBuf; + } + /* Load character into buffer. */ + ((u_char*)pcrx->inTail->payload)[pcrx->inTail->len++] = curChar; + break; + } + + /* update the frame check sequence number. */ + pcrx->inFCS = PPP_FCS(pcrx->inFCS, curChar); + } + } /* while (l-- > 0), all bytes processed */ + + avRandomize(); +} +#endif /* PPPOS_SUPPORT */ + +#if PPPOE_SUPPORT +void +pppInProcOverEthernet(int pd, struct pbuf *pb) +{ + struct pppInputHeader *pih; + u16_t inProtocol; + + if(pb->len < sizeof(inProtocol)) { + PPPDEBUG(LOG_ERR, ("pppInProcOverEthernet: too small for protocol field\n")); + goto drop; + } + + inProtocol = (((u8_t *)pb->payload)[0] << 8) | ((u8_t*)pb->payload)[1]; + + /* make room for pppInputHeader - should not fail */ + if (pbuf_header(pb, sizeof(*pih) - sizeof(inProtocol)) != 0) { + PPPDEBUG(LOG_ERR, ("pppInProcOverEthernet: could not allocate room for header\n")); + goto drop; + } + + pih = pb->payload; + + pih->unit = pd; + pih->proto = inProtocol; + + /* Dispatch the packet thereby consuming it. */ + pppInput(pb); + return; + +drop: + LINK_STATS_INC(link.drop); + snmp_inc_ifindiscards(&pppControl[pd].netif); + pbuf_free(pb); + return; +} +#endif /* PPPOE_SUPPORT */ + +#if LWIP_NETIF_STATUS_CALLBACK +/** Set the status callback of a PPP's netif + * + * @param pd The PPP descriptor returned by pppOpen() + * @param status_callback pointer to the status callback function + * + * @see netif_set_status_callback + */ +void +ppp_set_netif_statuscallback(int pd, netif_status_callback_fn status_callback) +{ + netif_set_status_callback(&pppControl[pd].netif, status_callback); +} +#endif /* LWIP_NETIF_STATUS_CALLBACK */ + +#if LWIP_NETIF_LINK_CALLBACK +/** Set the link callback of a PPP's netif + * + * @param pd The PPP descriptor returned by pppOpen() + * @param link_callback pointer to the link callback function + * + * @see netif_set_link_callback + */ +void +ppp_set_netif_linkcallback(int pd, netif_status_callback_fn link_callback) +{ + netif_set_link_callback(&pppControl[pd].netif, link_callback); +} +#endif /* LWIP_NETIF_LINK_CALLBACK */ + +#endif /* PPP_SUPPORT */ diff --git a/src/lwip-1.4.1/src/netif/ppp/ppp.h b/src/lwip-1.4.1/src/netif/ppp/ppp.h new file mode 100644 index 0000000..08d6e62 --- /dev/null +++ b/src/lwip-1.4.1/src/netif/ppp/ppp.h @@ -0,0 +1,201 @@ +/***************************************************************************** +* ppp.h - Network Point to Point Protocol header file. +* +* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. +* portions Copyright (c) 1997 Global Election Systems Inc. +* +* The authors hereby grant permission to use, copy, modify, distribute, +* and license this software and its documentation for any purpose, provided +* that existing copyright notices are retained in all copies and that this +* notice and the following disclaimer are included verbatim in any +* distributions. No written agreement, license, or royalty fee is required +* for any of the authorized uses. +* +* THIS SOFTWARE IS PROVIDED BY THE 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 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. +* +****************************************************************************** +* REVISION HISTORY +* +* 03-01-01 Marc Boucher +* Ported to lwIP. +* 97-11-05 Guy Lancaster , Global Election Systems Inc. +* Original derived from BSD codes. +*****************************************************************************/ + +#ifndef PPP_H +#define PPP_H + +#include "lwip/opt.h" + +#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/def.h" +#include "lwip/sio.h" +#include "lwip/stats.h" +#include "lwip/mem.h" +#include "lwip/netif.h" +#include "lwip/sys.h" +#include "lwip/timers.h" + + +#ifndef __u_char_defined + +/* Type definitions for BSD code. */ +typedef unsigned long u_long; +typedef unsigned int u_int; +typedef unsigned short u_short; +typedef unsigned char u_char; + +#endif + + +/************************* +*** PUBLIC DEFINITIONS *** +*************************/ + +/* Error codes. */ +#define PPPERR_NONE 0 /* No error. */ +#define PPPERR_PARAM -1 /* Invalid parameter. */ +#define PPPERR_OPEN -2 /* Unable to open PPP session. */ +#define PPPERR_DEVICE -3 /* Invalid I/O device for PPP. */ +#define PPPERR_ALLOC -4 /* Unable to allocate resources. */ +#define PPPERR_USER -5 /* User interrupt. */ +#define PPPERR_CONNECT -6 /* Connection lost. */ +#define PPPERR_AUTHFAIL -7 /* Failed authentication challenge. */ +#define PPPERR_PROTOCOL -8 /* Failed to meet protocol. */ + +/* + * PPP IOCTL commands. + */ +/* + * Get the up status - 0 for down, non-zero for up. The argument must + * point to an int. + */ +#define PPPCTLG_UPSTATUS 100 /* Get the up status - 0 down else up */ +#define PPPCTLS_ERRCODE 101 /* Set the error code */ +#define PPPCTLG_ERRCODE 102 /* Get the error code */ +#define PPPCTLG_FD 103 /* Get the fd associated with the ppp */ + +/************************ +*** PUBLIC DATA TYPES *** +************************/ + +struct ppp_addrs { + ip_addr_t our_ipaddr, his_ipaddr, netmask, dns1, dns2; +}; + + +/*********************** +*** PUBLIC FUNCTIONS *** +***********************/ + +/* Initialize the PPP subsystem. */ +void pppInit(void); + +/* Warning: Using PPPAUTHTYPE_ANY might have security consequences. + * RFC 1994 says: + * + * In practice, within or associated with each PPP server, there is a + * database which associates "user" names with authentication + * information ("secrets"). It is not anticipated that a particular + * named user would be authenticated by multiple methods. This would + * make the user vulnerable to attacks which negotiate the least secure + * method from among a set (such as PAP rather than CHAP). If the same + * secret was used, PAP would reveal the secret to be used later with + * CHAP. + * + * Instead, for each user name there should be an indication of exactly + * one method used to authenticate that user name. If a user needs to + * make use of different authentication methods under different + * circumstances, then distinct user names SHOULD be employed, each of + * which identifies exactly one authentication method. + * + */ +enum pppAuthType { + PPPAUTHTYPE_NONE, + PPPAUTHTYPE_ANY, + PPPAUTHTYPE_PAP, + PPPAUTHTYPE_CHAP +}; + +void pppSetAuth(enum pppAuthType authType, const char *user, const char *passwd); + +/* Link status callback function prototype */ +typedef void (*pppLinkStatusCB_fn)(void *ctx, int errCode, void *arg); + +#if PPPOS_SUPPORT +/* + * Open a new PPP connection using the given serial I/O device. + * This initializes the PPP control block but does not + * attempt to negotiate the LCP session. + * Return a new PPP connection descriptor on success or + * an error code (negative) on failure. + */ +int pppOverSerialOpen(sio_fd_t fd, pppLinkStatusCB_fn linkStatusCB, void *linkStatusCtx); +#endif /* PPPOS_SUPPORT */ + +#if PPPOE_SUPPORT +/* + * Open a new PPP Over Ethernet (PPPOE) connection. + */ +int pppOverEthernetOpen(struct netif *ethif, const char *service_name, const char *concentrator_name, + pppLinkStatusCB_fn linkStatusCB, void *linkStatusCtx); +#endif /* PPPOE_SUPPORT */ + +/* for source code compatibility */ +#define pppOpen(fd,cb,ls) pppOverSerialOpen(fd,cb,ls) + +/* + * Close a PPP connection and release the descriptor. + * Any outstanding packets in the queues are dropped. + * Return 0 on success, an error code on failure. + */ +int pppClose(int pd); + +/* + * Indicate to the PPP process that the line has disconnected. + */ +void pppSigHUP(int pd); + +/* + * Get and set parameters for the given connection. + * Return 0 on success, an error code on failure. + */ +int pppIOCtl(int pd, int cmd, void *arg); + +/* + * Return the Maximum Transmission Unit for the given PPP connection. + */ +u_short pppMTU(int pd); + +#if PPPOS_SUPPORT && !PPP_INPROC_OWNTHREAD +/* + * PPP over Serial: this is the input function to be called for received data. + * If PPP_INPROC_OWNTHREAD==1, a seperate input thread using the blocking + * sio_read() is used, so this is deactivated. + */ +void pppos_input(int pd, u_char* data, int len); +#endif /* PPPOS_SUPPORT && !PPP_INPROC_OWNTHREAD */ + + +#if LWIP_NETIF_STATUS_CALLBACK +/* Set an lwIP-style status-callback for the selected PPP device */ +void ppp_set_netif_statuscallback(int pd, netif_status_callback_fn status_callback); +#endif /* LWIP_NETIF_STATUS_CALLBACK */ +#if LWIP_NETIF_LINK_CALLBACK +/* Set an lwIP-style link-callback for the selected PPP device */ +void ppp_set_netif_linkcallback(int pd, netif_status_callback_fn link_callback); +#endif /* LWIP_NETIF_LINK_CALLBACK */ + +#endif /* PPP_SUPPORT */ + +#endif /* PPP_H */ diff --git a/src/lwip-1.4.1/src/netif/ppp/ppp_impl.h b/src/lwip-1.4.1/src/netif/ppp/ppp_impl.h new file mode 100644 index 0000000..89aea60 --- /dev/null +++ b/src/lwip-1.4.1/src/netif/ppp/ppp_impl.h @@ -0,0 +1,363 @@ +/***************************************************************************** +* ppp.h - Network Point to Point Protocol header file. +* +* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. +* portions Copyright (c) 1997 Global Election Systems Inc. +* +* The authors hereby grant permission to use, copy, modify, distribute, +* and license this software and its documentation for any purpose, provided +* that existing copyright notices are retained in all copies and that this +* notice and the following disclaimer are included verbatim in any +* distributions. No written agreement, license, or royalty fee is required +* for any of the authorized uses. +* +* THIS SOFTWARE IS PROVIDED BY THE 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 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. +* +****************************************************************************** +* REVISION HISTORY +* +* 03-01-01 Marc Boucher +* Ported to lwIP. +* 97-11-05 Guy Lancaster , Global Election Systems Inc. +* Original derived from BSD codes. +*****************************************************************************/ + +#ifndef PPP_IMPL_H +#define PPP_IMPL_H + +#include "lwip/opt.h" + +#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ + +#include "ppp.h" +#include "lwip/def.h" +#include "lwip/sio.h" +#include "lwip/stats.h" +#include "lwip/mem.h" +#include "lwip/netif.h" +#include "lwip/sys.h" +#include "lwip/timers.h" + +/** Some defines for code we skip compared to the original pppd. + * These are just here to minimise the use of the ugly "#if 0". */ +#define PPP_ADDITIONAL_CALLBACKS 0 + +/** Some error checks to test for unsupported code */ +#if CBCP_SUPPORT +#error "CBCP is not supported in lwIP PPP" +#endif +#if CCP_SUPPORT +#error "CCP is not supported in lwIP PPP" +#endif + +/* + * pppd.h - PPP daemon global declarations. + * + * Copyright (c) 1989 Carnegie Mellon University. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by Carnegie Mellon University. The name of the + * University may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + */ +/* + * ppp_defs.h - PPP definitions. + * + * Copyright (c) 1994 The Australian National University. + * All rights reserved. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation is hereby granted, provided that the above copyright + * notice appears in all copies. This software is provided without any + * warranty, express or implied. The Australian National University + * makes no representations about the suitability of this software for + * any purpose. + * + * IN NO EVENT SHALL THE AUSTRALIAN NATIONAL UNIVERSITY BE LIABLE TO ANY + * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF + * THE AUSTRALIAN NATIONAL UNIVERSITY HAVE BEEN ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * THE AUSTRALIAN NATIONAL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE AUSTRALIAN NATIONAL UNIVERSITY HAS NO + * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, + * OR MODIFICATIONS. + */ + +#define TIMEOUT(f, a, t) do { sys_untimeout((f), (a)); sys_timeout((t)*1000, (f), (a)); } while(0) +#define UNTIMEOUT(f, a) sys_untimeout((f), (a)) + + +/* + * Constants and structures defined by the internet system, + * Per RFC 790, September 1981, and numerous additions. + */ + +/* + * The basic PPP frame. + */ +#define PPP_HDRLEN 4 /* octets for standard ppp header */ +#define PPP_FCSLEN 2 /* octets for FCS */ + + +/* + * Significant octet values. + */ +#define PPP_ALLSTATIONS 0xff /* All-Stations broadcast address */ +#define PPP_UI 0x03 /* Unnumbered Information */ +#define PPP_FLAG 0x7e /* Flag Sequence */ +#define PPP_ESCAPE 0x7d /* Asynchronous Control Escape */ +#define PPP_TRANS 0x20 /* Asynchronous transparency modifier */ + +/* + * Protocol field values. + */ +#define PPP_IP 0x21 /* Internet Protocol */ +#define PPP_AT 0x29 /* AppleTalk Protocol */ +#define PPP_VJC_COMP 0x2d /* VJ compressed TCP */ +#define PPP_VJC_UNCOMP 0x2f /* VJ uncompressed TCP */ +#define PPP_COMP 0xfd /* compressed packet */ +#define PPP_IPCP 0x8021 /* IP Control Protocol */ +#define PPP_ATCP 0x8029 /* AppleTalk Control Protocol */ +#define PPP_CCP 0x80fd /* Compression Control Protocol */ +#define PPP_LCP 0xc021 /* Link Control Protocol */ +#define PPP_PAP 0xc023 /* Password Authentication Protocol */ +#define PPP_LQR 0xc025 /* Link Quality Report protocol */ +#define PPP_CHAP 0xc223 /* Cryptographic Handshake Auth. Protocol */ +#define PPP_CBCP 0xc029 /* Callback Control Protocol */ + +/* + * Values for FCS calculations. + */ +#define PPP_INITFCS 0xffff /* Initial FCS value */ +#define PPP_GOODFCS 0xf0b8 /* Good final FCS value */ +#define PPP_FCS(fcs, c) (((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff]) + +/* + * Extended asyncmap - allows any character to be escaped. + */ +typedef u_char ext_accm[32]; + +/* + * What to do with network protocol (NP) packets. + */ +enum NPmode { + NPMODE_PASS, /* pass the packet through */ + NPMODE_DROP, /* silently drop the packet */ + NPMODE_ERROR, /* return an error */ + NPMODE_QUEUE /* save it up for later. */ +}; + +/* + * Inline versions of get/put char/short/long. + * Pointer is advanced; we assume that both arguments + * are lvalues and will already be in registers. + * cp MUST be u_char *. + */ +#define GETCHAR(c, cp) { \ + (c) = *(cp)++; \ +} +#define PUTCHAR(c, cp) { \ + *(cp)++ = (u_char) (c); \ +} + + +#define GETSHORT(s, cp) { \ + (s) = *(cp); (cp)++; (s) <<= 8; \ + (s) |= *(cp); (cp)++; \ +} +#define PUTSHORT(s, cp) { \ + *(cp)++ = (u_char) ((s) >> 8); \ + *(cp)++ = (u_char) (s & 0xff); \ +} + +#define GETLONG(l, cp) { \ + (l) = *(cp); (cp)++; (l) <<= 8; \ + (l) |= *(cp); (cp)++; (l) <<= 8; \ + (l) |= *(cp); (cp)++; (l) <<= 8; \ + (l) |= *(cp); (cp)++; \ +} +#define PUTLONG(l, cp) { \ + *(cp)++ = (u_char) ((l) >> 24); \ + *(cp)++ = (u_char) ((l) >> 16); \ + *(cp)++ = (u_char) ((l) >> 8); \ + *(cp)++ = (u_char) (l); \ +} + + +#define INCPTR(n, cp) ((cp) += (n)) +#define DECPTR(n, cp) ((cp) -= (n)) + +#define BCMP(s0, s1, l) memcmp((u_char *)(s0), (u_char *)(s1), (l)) +#define BCOPY(s, d, l) MEMCPY((d), (s), (l)) +#define BZERO(s, n) memset(s, 0, n) + +#if PPP_DEBUG +#define PRINTMSG(m, l) { m[l] = '\0'; LWIP_DEBUGF(LOG_INFO, ("Remote message: %s\n", m)); } +#else /* PPP_DEBUG */ +#define PRINTMSG(m, l) +#endif /* PPP_DEBUG */ + +/* + * MAKEHEADER - Add PPP Header fields to a packet. + */ +#define MAKEHEADER(p, t) { \ + PUTCHAR(PPP_ALLSTATIONS, p); \ + PUTCHAR(PPP_UI, p); \ + PUTSHORT(t, p); } + +/************************ +*** PUBLIC DATA TYPES *** +************************/ + +/* + * The following struct gives the addresses of procedures to call + * for a particular protocol. + */ +struct protent { + u_short protocol; /* PPP protocol number */ + /* Initialization procedure */ + void (*init) (int unit); + /* Process a received packet */ + void (*input) (int unit, u_char *pkt, int len); + /* Process a received protocol-reject */ + void (*protrej) (int unit); + /* Lower layer has come up */ + void (*lowerup) (int unit); + /* Lower layer has gone down */ + void (*lowerdown) (int unit); + /* Open the protocol */ + void (*open) (int unit); + /* Close the protocol */ + void (*close) (int unit, char *reason); +#if PPP_ADDITIONAL_CALLBACKS + /* Print a packet in readable form */ + int (*printpkt) (u_char *pkt, int len, + void (*printer) (void *, char *, ...), + void *arg); + /* Process a received data packet */ + void (*datainput) (int unit, u_char *pkt, int len); +#endif /* PPP_ADDITIONAL_CALLBACKS */ + int enabled_flag; /* 0 if protocol is disabled */ + char *name; /* Text name of protocol */ +#if PPP_ADDITIONAL_CALLBACKS + /* Check requested options, assign defaults */ + void (*check_options) (u_long); + /* Configure interface for demand-dial */ + int (*demand_conf) (int unit); + /* Say whether to bring up link for this pkt */ + int (*active_pkt) (u_char *pkt, int len); +#endif /* PPP_ADDITIONAL_CALLBACKS */ +}; + +/* + * The following structure records the time in seconds since + * the last NP packet was sent or received. + */ +struct ppp_idle { + u_short xmit_idle; /* seconds since last NP packet sent */ + u_short recv_idle; /* seconds since last NP packet received */ +}; + +struct ppp_settings { + + u_int disable_defaultip : 1; /* Don't use hostname for default IP addrs */ + u_int auth_required : 1; /* Peer is required to authenticate */ + u_int explicit_remote : 1; /* remote_name specified with remotename opt */ + u_int refuse_pap : 1; /* Don't wanna auth. ourselves with PAP */ + u_int refuse_chap : 1; /* Don't wanna auth. ourselves with CHAP */ + u_int usehostname : 1; /* Use hostname for our_name */ + u_int usepeerdns : 1; /* Ask peer for DNS adds */ + + u_short idle_time_limit; /* Shut down link if idle for this long */ + int maxconnect; /* Maximum connect time (seconds) */ + + char user [MAXNAMELEN + 1]; /* Username for PAP */ + char passwd [MAXSECRETLEN + 1]; /* Password for PAP, secret for CHAP */ + char our_name [MAXNAMELEN + 1]; /* Our name for authentication purposes */ + char remote_name[MAXNAMELEN + 1]; /* Peer's name for authentication */ +}; + +/***************************** +*** PUBLIC DATA STRUCTURES *** +*****************************/ + +/* Buffers for outgoing packets. */ +extern u_char outpacket_buf[NUM_PPP][PPP_MRU+PPP_HDRLEN]; + +extern struct ppp_settings ppp_settings; + +extern struct protent *ppp_protocols[]; /* Table of pointers to supported protocols */ + + +/*********************** +*** PUBLIC FUNCTIONS *** +***********************/ + +/* + * Write n characters to a ppp link. + * RETURN: >= 0 Number of characters written, -1 Failed to write to device. + */ +int pppWrite(int pd, const u_char *s, int n); + +void pppInProcOverEthernet(int pd, struct pbuf *pb); + +struct pbuf *pppSingleBuf(struct pbuf *p); + +void pppLinkTerminated(int pd); + +void pppLinkDown(int pd); + +/* Configure i/f transmit parameters */ +void ppp_send_config (int, u16_t, u32_t, int, int); +/* Set extended transmit ACCM */ +void ppp_set_xaccm (int, ext_accm *); +/* Configure i/f receive parameters */ +void ppp_recv_config (int, int, u32_t, int, int); +/* Find out how long link has been idle */ +int get_idle_time (int, struct ppp_idle *); + +/* Configure VJ TCP header compression */ +int sifvjcomp (int, int, u8_t, u8_t); +/* Configure i/f down (for IP) */ +int sifup (int); +/* Set mode for handling packets for proto */ +int sifnpmode (int u, int proto, enum NPmode mode); +/* Configure i/f down (for IP) */ +int sifdown (int); +/* Configure IP addresses for i/f */ +int sifaddr (int, u32_t, u32_t, u32_t, u32_t, u32_t); +/* Reset i/f IP addresses */ +int cifaddr (int, u32_t, u32_t); +/* Create default route through i/f */ +int sifdefaultroute (int, u32_t, u32_t); +/* Delete default route through i/f */ +int cifdefaultroute (int, u32_t, u32_t); + +/* Get appropriate netmask for address */ +u32_t GetMask (u32_t); + +#endif /* PPP_SUPPORT */ + +#endif /* PPP_IMPL_H */ diff --git a/src/lwip-1.4.1/src/netif/ppp/ppp_oe.c b/src/lwip-1.4.1/src/netif/ppp/ppp_oe.c new file mode 100644 index 0000000..fdf52ae --- /dev/null +++ b/src/lwip-1.4.1/src/netif/ppp/ppp_oe.c @@ -0,0 +1,1132 @@ +/***************************************************************************** +* ppp_oe.c - PPP Over Ethernet implementation for lwIP. +* +* Copyright (c) 2006 by Marc Boucher, Services Informatiques (MBSI) inc. +* +* The authors hereby grant permission to use, copy, modify, distribute, +* and license this software and its documentation for any purpose, provided +* that existing copyright notices are retained in all copies and that this +* notice and the following disclaimer are included verbatim in any +* distributions. No written agreement, license, or royalty fee is required +* for any of the authorized uses. +* +* THIS SOFTWARE IS PROVIDED BY THE 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 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. +* +****************************************************************************** +* REVISION HISTORY +* +* 06-01-01 Marc Boucher +* Ported to lwIP. +*****************************************************************************/ + + + +/* based on NetBSD: if_pppoe.c,v 1.64 2006/01/31 23:50:15 martin Exp */ + +/*- + * Copyright (c) 2002 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Martin Husemann . + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + */ + +#include "lwip/opt.h" + +#if PPPOE_SUPPORT /* don't build if not configured for use in lwipopts.h */ + +#include "netif/ppp_oe.h" + +#include "ppp_impl.h" +#include "pppdebug.h" + +#include "lwip/timers.h" +#include "lwip/memp.h" + +#include +#include + + +/* Add a 16 bit unsigned value to a buffer pointed to by PTR */ +#define PPPOE_ADD_16(PTR, VAL) \ + *(PTR)++ = (u8_t)((VAL) / 256); \ + *(PTR)++ = (u8_t)((VAL) % 256) + +/* Add a complete PPPoE header to the buffer pointed to by PTR */ +#define PPPOE_ADD_HEADER(PTR, CODE, SESS, LEN) \ + *(PTR)++ = PPPOE_VERTYPE; \ + *(PTR)++ = (CODE); \ + PPPOE_ADD_16(PTR, SESS); \ + PPPOE_ADD_16(PTR, LEN) + +#define PPPOE_DISC_TIMEOUT (5*1000) /* base for quick timeout calculation */ +#define PPPOE_SLOW_RETRY (60*1000) /* persistent retry interval */ +#define PPPOE_DISC_MAXPADI 4 /* retry PADI four times (quickly) */ +#define PPPOE_DISC_MAXPADR 2 /* retry PADR twice */ + +#ifdef PPPOE_SERVER +#error "PPPOE_SERVER is not yet supported under lwIP!" +/* from if_spppsubr.c */ +#define IFF_PASSIVE IFF_LINK0 /* wait passively for connection */ +#endif + +#ifndef PPPOE_ERRORSTRING_LEN +#define PPPOE_ERRORSTRING_LEN 64 +#endif +static char pppoe_error_tmp[PPPOE_ERRORSTRING_LEN]; + + +/* input routines */ +static void pppoe_dispatch_disc_pkt(struct netif *, struct pbuf *); + +/* management routines */ +static int pppoe_do_disconnect(struct pppoe_softc *); +static void pppoe_abort_connect(struct pppoe_softc *); +static void pppoe_clear_softc(struct pppoe_softc *, const char *); + +/* internal timeout handling */ +static void pppoe_timeout(void *); + +/* sending actual protocol controll packets */ +static err_t pppoe_send_padi(struct pppoe_softc *); +static err_t pppoe_send_padr(struct pppoe_softc *); +#ifdef PPPOE_SERVER +static err_t pppoe_send_pado(struct pppoe_softc *); +static err_t pppoe_send_pads(struct pppoe_softc *); +#endif +static err_t pppoe_send_padt(struct netif *, u_int, const u8_t *); + +/* internal helper functions */ +static struct pppoe_softc * pppoe_find_softc_by_session(u_int, struct netif *); +static struct pppoe_softc * pppoe_find_softc_by_hunique(u8_t *, size_t, struct netif *); + +/** linked list of created pppoe interfaces */ +static struct pppoe_softc *pppoe_softc_list; + +err_t +pppoe_create(struct netif *ethif, int pd, void (*linkStatusCB)(int pd, int up), struct pppoe_softc **scptr) +{ + struct pppoe_softc *sc; + + sc = (struct pppoe_softc *)memp_malloc(MEMP_PPPOE_IF); + if (sc == NULL) { + *scptr = NULL; + return ERR_MEM; + } + memset(sc, 0, sizeof(struct pppoe_softc)); + + /* changed to real address later */ + MEMCPY(&sc->sc_dest, ethbroadcast.addr, sizeof(sc->sc_dest)); + + sc->sc_pd = pd; + sc->sc_linkStatusCB = linkStatusCB; + sc->sc_ethif = ethif; + + /* put the new interface at the head of the list */ + sc->next = pppoe_softc_list; + pppoe_softc_list = sc; + + *scptr = sc; + + return ERR_OK; +} + +err_t +pppoe_destroy(struct netif *ifp) +{ + struct pppoe_softc *sc, *prev = NULL; + + for (sc = pppoe_softc_list; sc != NULL; prev = sc, sc = sc->next) { + if (sc->sc_ethif == ifp) { + break; + } + } + + if(!(sc && (sc->sc_ethif == ifp))) { + return ERR_IF; + } + + sys_untimeout(pppoe_timeout, sc); + if (prev == NULL) { + /* remove sc from the head of the list */ + pppoe_softc_list = sc->next; + } else { + /* remove sc from the list */ + prev->next = sc->next; + } + +#ifdef PPPOE_TODO + if (sc->sc_concentrator_name) { + mem_free(sc->sc_concentrator_name); + } + if (sc->sc_service_name) { + mem_free(sc->sc_service_name); + } +#endif /* PPPOE_TODO */ + memp_free(MEMP_PPPOE_IF, sc); + + return ERR_OK; +} + +/* + * Find the interface handling the specified session. + * Note: O(number of sessions open), this is a client-side only, mean + * and lean implementation, so number of open sessions typically should + * be 1. + */ +static struct pppoe_softc * +pppoe_find_softc_by_session(u_int session, struct netif *rcvif) +{ + struct pppoe_softc *sc; + + if (session == 0) { + return NULL; + } + + for (sc = pppoe_softc_list; sc != NULL; sc = sc->next) { + if (sc->sc_state == PPPOE_STATE_SESSION + && sc->sc_session == session) { + if (sc->sc_ethif == rcvif) { + return sc; + } else { + return NULL; + } + } + } + return NULL; +} + +/* Check host unique token passed and return appropriate softc pointer, + * or NULL if token is bogus. */ +static struct pppoe_softc * +pppoe_find_softc_by_hunique(u8_t *token, size_t len, struct netif *rcvif) +{ + struct pppoe_softc *sc, *t; + + if (pppoe_softc_list == NULL) { + return NULL; + } + + if (len != sizeof sc) { + return NULL; + } + MEMCPY(&t, token, len); + + for (sc = pppoe_softc_list; sc != NULL; sc = sc->next) { + if (sc == t) { + break; + } + } + + if (sc == NULL) { + PPPDEBUG(LOG_DEBUG, ("pppoe: alien host unique tag, no session found\n")); + return NULL; + } + + /* should be safe to access *sc now */ + if (sc->sc_state < PPPOE_STATE_PADI_SENT || sc->sc_state >= PPPOE_STATE_SESSION) { + printf("%c%c%"U16_F": host unique tag found, but it belongs to a connection in state %d\n", + sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, sc->sc_state); + return NULL; + } + if (sc->sc_ethif != rcvif) { + printf("%c%c%"U16_F": wrong interface, not accepting host unique\n", + sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num); + return NULL; + } + return sc; +} + +static void +pppoe_linkstatus_up(struct pppoe_softc *sc) +{ + sc->sc_linkStatusCB(sc->sc_pd, 1); +} + +/* analyze and handle a single received packet while not in session state */ +static void +pppoe_dispatch_disc_pkt(struct netif *netif, struct pbuf *pb) +{ + u16_t tag, len; + u16_t session, plen; + struct pppoe_softc *sc; + const char *err_msg; + char devname[6]; + u8_t *ac_cookie; + u16_t ac_cookie_len; +#ifdef PPPOE_SERVER + u8_t *hunique; + size_t hunique_len; +#endif + struct pppoehdr *ph; + struct pppoetag pt; + int off, err, errortag; + struct eth_hdr *ethhdr; + + pb = pppSingleBuf(pb); + + strcpy(devname, "pppoe"); /* as long as we don't know which instance */ + err_msg = NULL; + errortag = 0; + if (pb->len < sizeof(*ethhdr)) { + goto done; + } + ethhdr = (struct eth_hdr *)pb->payload; + off = sizeof(*ethhdr); + + ac_cookie = NULL; + ac_cookie_len = 0; +#ifdef PPPOE_SERVER + hunique = NULL; + hunique_len = 0; +#endif + session = 0; + if (pb->len - off < PPPOE_HEADERLEN) { + printf("pppoe: packet too short: %d\n", pb->len); + goto done; + } + + ph = (struct pppoehdr *) (ethhdr + 1); + if (ph->vertype != PPPOE_VERTYPE) { + printf("pppoe: unknown version/type packet: 0x%x\n", ph->vertype); + goto done; + } + session = ntohs(ph->session); + plen = ntohs(ph->plen); + off += sizeof(*ph); + + if (plen + off > pb->len) { + printf("pppoe: packet content does not fit: data available = %d, packet size = %u\n", + pb->len - off, plen); + goto done; + } + if(pb->tot_len == pb->len) { + pb->tot_len = pb->len = (u16_t)off + plen; /* ignore trailing garbage */ + } + tag = 0; + len = 0; + sc = NULL; + while (off + sizeof(pt) <= pb->len) { + MEMCPY(&pt, (u8_t*)pb->payload + off, sizeof(pt)); + tag = ntohs(pt.tag); + len = ntohs(pt.len); + if (off + sizeof(pt) + len > pb->len) { + printf("pppoe: tag 0x%x len 0x%x is too long\n", tag, len); + goto done; + } + switch (tag) { + case PPPOE_TAG_EOL: + goto breakbreak; + case PPPOE_TAG_SNAME: + break; /* ignored */ + case PPPOE_TAG_ACNAME: + break; /* ignored */ + case PPPOE_TAG_HUNIQUE: + if (sc != NULL) { + break; + } +#ifdef PPPOE_SERVER + hunique = (u8_t*)pb->payload + off + sizeof(pt); + hunique_len = len; +#endif + sc = pppoe_find_softc_by_hunique((u8_t*)pb->payload + off + sizeof(pt), len, netif); + if (sc != NULL) { + snprintf(devname, sizeof(devname), "%c%c%"U16_F, sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num); + } + break; + case PPPOE_TAG_ACCOOKIE: + if (ac_cookie == NULL) { + ac_cookie = (u8_t*)pb->payload + off + sizeof(pt); + ac_cookie_len = len; + } + break; + case PPPOE_TAG_SNAME_ERR: + err_msg = "SERVICE NAME ERROR"; + errortag = 1; + break; + case PPPOE_TAG_ACSYS_ERR: + err_msg = "AC SYSTEM ERROR"; + errortag = 1; + break; + case PPPOE_TAG_GENERIC_ERR: + err_msg = "GENERIC ERROR"; + errortag = 1; + break; + } + if (err_msg) { + if (errortag && len) { + u16_t error_len = LWIP_MIN(len, sizeof(pppoe_error_tmp)-1); + strncpy(pppoe_error_tmp, (char*)pb->payload + off + sizeof(pt), error_len); + pppoe_error_tmp[error_len-1] = '\0'; + printf("%s: %s: %s\n", devname, err_msg, pppoe_error_tmp); + } else { + printf("%s: %s\n", devname, err_msg); + } + if (errortag) { + goto done; + } + } + off += sizeof(pt) + len; + } + +breakbreak:; + switch (ph->code) { + case PPPOE_CODE_PADI: +#ifdef PPPOE_SERVER + /* + * got service name, concentrator name, and/or host unique. + * ignore if we have no interfaces with IFF_PASSIVE|IFF_UP. + */ + if (LIST_EMPTY(&pppoe_softc_list)) { + goto done; + } + LIST_FOREACH(sc, &pppoe_softc_list, sc_list) { + if (!(sc->sc_sppp.pp_if.if_flags & IFF_UP)) { + continue; + } + if (!(sc->sc_sppp.pp_if.if_flags & IFF_PASSIVE)) { + continue; + } + if (sc->sc_state == PPPOE_STATE_INITIAL) { + break; + } + } + if (sc == NULL) { + /* printf("pppoe: free passive interface is not found\n"); */ + goto done; + } + if (hunique) { + if (sc->sc_hunique) { + mem_free(sc->sc_hunique); + } + sc->sc_hunique = mem_malloc(hunique_len); + if (sc->sc_hunique == NULL) { + goto done; + } + sc->sc_hunique_len = hunique_len; + MEMCPY(sc->sc_hunique, hunique, hunique_len); + } + MEMCPY(&sc->sc_dest, eh->ether_shost, sizeof sc->sc_dest); + sc->sc_state = PPPOE_STATE_PADO_SENT; + pppoe_send_pado(sc); + break; +#endif /* PPPOE_SERVER */ + case PPPOE_CODE_PADR: +#ifdef PPPOE_SERVER + /* + * get sc from ac_cookie if IFF_PASSIVE + */ + if (ac_cookie == NULL) { + /* be quiet if there is not a single pppoe instance */ + printf("pppoe: received PADR but not includes ac_cookie\n"); + goto done; + } + sc = pppoe_find_softc_by_hunique(ac_cookie, ac_cookie_len, netif); + if (sc == NULL) { + /* be quiet if there is not a single pppoe instance */ + if (!LIST_EMPTY(&pppoe_softc_list)) { + printf("pppoe: received PADR but could not find request for it\n"); + } + goto done; + } + if (sc->sc_state != PPPOE_STATE_PADO_SENT) { + printf("%c%c%"U16_F": received unexpected PADR\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num); + goto done; + } + if (hunique) { + if (sc->sc_hunique) { + mem_free(sc->sc_hunique); + } + sc->sc_hunique = mem_malloc(hunique_len); + if (sc->sc_hunique == NULL) { + goto done; + } + sc->sc_hunique_len = hunique_len; + MEMCPY(sc->sc_hunique, hunique, hunique_len); + } + pppoe_send_pads(sc); + sc->sc_state = PPPOE_STATE_SESSION; + pppoe_linkstatus_up(sc); /* notify upper layers */ + break; +#else + /* ignore, we are no access concentrator */ + goto done; +#endif /* PPPOE_SERVER */ + case PPPOE_CODE_PADO: + if (sc == NULL) { + /* be quiet if there is not a single pppoe instance */ + if (pppoe_softc_list != NULL) { + printf("pppoe: received PADO but could not find request for it\n"); + } + goto done; + } + if (sc->sc_state != PPPOE_STATE_PADI_SENT) { + printf("%c%c%"U16_F": received unexpected PADO\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num); + goto done; + } + if (ac_cookie) { + sc->sc_ac_cookie_len = ac_cookie_len; + MEMCPY(sc->sc_ac_cookie, ac_cookie, ac_cookie_len); + } + MEMCPY(&sc->sc_dest, ethhdr->src.addr, sizeof(sc->sc_dest.addr)); + sys_untimeout(pppoe_timeout, sc); + sc->sc_padr_retried = 0; + sc->sc_state = PPPOE_STATE_PADR_SENT; + if ((err = pppoe_send_padr(sc)) != 0) { + PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F": failed to send PADR, error=%d\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, err)); + } + sys_timeout(PPPOE_DISC_TIMEOUT * (1 + sc->sc_padr_retried), pppoe_timeout, sc); + break; + case PPPOE_CODE_PADS: + if (sc == NULL) { + goto done; + } + sc->sc_session = session; + sys_untimeout(pppoe_timeout, sc); + PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F": session 0x%x connected\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, session)); + sc->sc_state = PPPOE_STATE_SESSION; + pppoe_linkstatus_up(sc); /* notify upper layers */ + break; + case PPPOE_CODE_PADT: + if (sc == NULL) { + goto done; + } + pppoe_clear_softc(sc, "received PADT"); + break; + default: + if(sc) { + printf("%c%c%"U16_F": unknown code (0x%"X16_F") session = 0x%"X16_F"\n", + sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, + (u16_t)ph->code, session); + } else { + printf("pppoe: unknown code (0x%"X16_F") session = 0x%"X16_F"\n", (u16_t)ph->code, session); + } + break; + } + +done: + pbuf_free(pb); + return; +} + +void +pppoe_disc_input(struct netif *netif, struct pbuf *p) +{ + /* avoid error messages if there is not a single pppoe instance */ + if (pppoe_softc_list != NULL) { + pppoe_dispatch_disc_pkt(netif, p); + } else { + pbuf_free(p); + } +} + +void +pppoe_data_input(struct netif *netif, struct pbuf *pb) +{ + u16_t session, plen; + struct pppoe_softc *sc; + struct pppoehdr *ph; +#ifdef PPPOE_TERM_UNKNOWN_SESSIONS + u8_t shost[ETHER_ADDR_LEN]; +#endif + +#ifdef PPPOE_TERM_UNKNOWN_SESSIONS + MEMCPY(shost, ((struct eth_hdr *)pb->payload)->src.addr, sizeof(shost)); +#endif + if (pbuf_header(pb, -(int)sizeof(struct eth_hdr)) != 0) { + /* bail out */ + PPPDEBUG(LOG_ERR, ("pppoe_data_input: pbuf_header failed\n")); + LINK_STATS_INC(link.lenerr); + goto drop; + } + + pb = pppSingleBuf (pb); + + if (pb->len <= PPPOE_HEADERLEN) { + printf("pppoe (data): dropping too short packet: %d bytes\n", pb->len); + goto drop; + } + + if (pb->len < sizeof(*ph)) { + printf("pppoe_data_input: could not get PPPoE header\n"); + goto drop; + } + ph = (struct pppoehdr *)pb->payload; + + if (ph->vertype != PPPOE_VERTYPE) { + printf("pppoe (data): unknown version/type packet: 0x%x\n", ph->vertype); + goto drop; + } + if (ph->code != 0) { + goto drop; + } + + session = ntohs(ph->session); + sc = pppoe_find_softc_by_session(session, netif); + if (sc == NULL) { +#ifdef PPPOE_TERM_UNKNOWN_SESSIONS + printf("pppoe: input for unknown session 0x%x, sending PADT\n", session); + pppoe_send_padt(netif, session, shost); +#endif + goto drop; + } + + plen = ntohs(ph->plen); + + if (pbuf_header(pb, -(int)(PPPOE_HEADERLEN)) != 0) { + /* bail out */ + PPPDEBUG(LOG_ERR, ("pppoe_data_input: pbuf_header PPPOE_HEADERLEN failed\n")); + LINK_STATS_INC(link.lenerr); + goto drop; + } + + PPPDEBUG(LOG_DEBUG, ("pppoe_data_input: %c%c%"U16_F": pkthdr.len=%d, pppoe.len=%d\n", + sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, + pb->len, plen)); + + if (pb->len < plen) { + goto drop; + } + + pppInProcOverEthernet(sc->sc_pd, pb); + + return; + +drop: + pbuf_free(pb); +} + +static err_t +pppoe_output(struct pppoe_softc *sc, struct pbuf *pb) +{ + struct eth_hdr *ethhdr; + u16_t etype; + err_t res; + + if (!sc->sc_ethif) { + pbuf_free(pb); + return ERR_IF; + } + + ethhdr = (struct eth_hdr *)pb->payload; + etype = sc->sc_state == PPPOE_STATE_SESSION ? ETHTYPE_PPPOE : ETHTYPE_PPPOEDISC; + ethhdr->type = htons(etype); + MEMCPY(ethhdr->dest.addr, sc->sc_dest.addr, sizeof(ethhdr->dest.addr)); + MEMCPY(ethhdr->src.addr, ((struct eth_addr *)sc->sc_ethif->hwaddr)->addr, sizeof(ethhdr->src.addr)); + + PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F" (%x) state=%d, session=0x%x output -> %02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F", len=%d\n", + sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, etype, + sc->sc_state, sc->sc_session, + sc->sc_dest.addr[0], sc->sc_dest.addr[1], sc->sc_dest.addr[2], sc->sc_dest.addr[3], sc->sc_dest.addr[4], sc->sc_dest.addr[5], + pb->tot_len)); + + res = sc->sc_ethif->linkoutput(sc->sc_ethif, pb); + + pbuf_free(pb); + + return res; +} + +static err_t +pppoe_send_padi(struct pppoe_softc *sc) +{ + struct pbuf *pb; + u8_t *p; + int len; +#ifdef PPPOE_TODO + int l1 = 0, l2 = 0; /* XXX: gcc */ +#endif /* PPPOE_TODO */ + + if (sc->sc_state >PPPOE_STATE_PADI_SENT) { + PPPDEBUG(LOG_ERR, ("ERROR: pppoe_send_padi in state %d", sc->sc_state)); + } + + /* calculate length of frame (excluding ethernet header + pppoe header) */ + len = 2 + 2 + 2 + 2 + sizeof sc; /* service name tag is required, host unique is send too */ +#ifdef PPPOE_TODO + if (sc->sc_service_name != NULL) { + l1 = (int)strlen(sc->sc_service_name); + len += l1; + } + if (sc->sc_concentrator_name != NULL) { + l2 = (int)strlen(sc->sc_concentrator_name); + len += 2 + 2 + l2; + } +#endif /* PPPOE_TODO */ + LWIP_ASSERT("sizeof(struct eth_hdr) + PPPOE_HEADERLEN + len <= 0xffff", + sizeof(struct eth_hdr) + PPPOE_HEADERLEN + len <= 0xffff); + + /* allocate a buffer */ + pb = pbuf_alloc(PBUF_LINK, (u16_t)(sizeof(struct eth_hdr) + PPPOE_HEADERLEN + len), PBUF_RAM); + if (!pb) { + return ERR_MEM; + } + LWIP_ASSERT("pb->tot_len == pb->len", pb->tot_len == pb->len); + + p = (u8_t*)pb->payload + sizeof (struct eth_hdr); + /* fill in pkt */ + PPPOE_ADD_HEADER(p, PPPOE_CODE_PADI, 0, (u16_t)len); + PPPOE_ADD_16(p, PPPOE_TAG_SNAME); +#ifdef PPPOE_TODO + if (sc->sc_service_name != NULL) { + PPPOE_ADD_16(p, l1); + MEMCPY(p, sc->sc_service_name, l1); + p += l1; + } else +#endif /* PPPOE_TODO */ + { + PPPOE_ADD_16(p, 0); + } +#ifdef PPPOE_TODO + if (sc->sc_concentrator_name != NULL) { + PPPOE_ADD_16(p, PPPOE_TAG_ACNAME); + PPPOE_ADD_16(p, l2); + MEMCPY(p, sc->sc_concentrator_name, l2); + p += l2; + } +#endif /* PPPOE_TODO */ + PPPOE_ADD_16(p, PPPOE_TAG_HUNIQUE); + PPPOE_ADD_16(p, sizeof(sc)); + MEMCPY(p, &sc, sizeof sc); + + /* send pkt */ + return pppoe_output(sc, pb); +} + +static void +pppoe_timeout(void *arg) +{ + int retry_wait, err; + struct pppoe_softc *sc = (struct pppoe_softc*)arg; + + PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F": timeout\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num)); + + switch (sc->sc_state) { + case PPPOE_STATE_PADI_SENT: + /* + * We have two basic ways of retrying: + * - Quick retry mode: try a few times in short sequence + * - Slow retry mode: we already had a connection successfully + * established and will try infinitely (without user + * intervention) + * We only enter slow retry mode if IFF_LINK1 (aka autodial) + * is not set. + */ + + /* initialize for quick retry mode */ + retry_wait = PPPOE_DISC_TIMEOUT * (1 + sc->sc_padi_retried); + + sc->sc_padi_retried++; + if (sc->sc_padi_retried >= PPPOE_DISC_MAXPADI) { +#if 0 + if ((sc->sc_sppp.pp_if.if_flags & IFF_LINK1) == 0) { + /* slow retry mode */ + retry_wait = PPPOE_SLOW_RETRY; + } else +#endif + { + pppoe_abort_connect(sc); + return; + } + } + if ((err = pppoe_send_padi(sc)) != 0) { + sc->sc_padi_retried--; + PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F": failed to transmit PADI, error=%d\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, err)); + } + sys_timeout(retry_wait, pppoe_timeout, sc); + break; + + case PPPOE_STATE_PADR_SENT: + sc->sc_padr_retried++; + if (sc->sc_padr_retried >= PPPOE_DISC_MAXPADR) { + MEMCPY(&sc->sc_dest, ethbroadcast.addr, sizeof(sc->sc_dest)); + sc->sc_state = PPPOE_STATE_PADI_SENT; + sc->sc_padr_retried = 0; + if ((err = pppoe_send_padi(sc)) != 0) { + PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F": failed to send PADI, error=%d\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, err)); + } + sys_timeout(PPPOE_DISC_TIMEOUT * (1 + sc->sc_padi_retried), pppoe_timeout, sc); + return; + } + if ((err = pppoe_send_padr(sc)) != 0) { + sc->sc_padr_retried--; + PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F": failed to send PADR, error=%d\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, err)); + } + sys_timeout(PPPOE_DISC_TIMEOUT * (1 + sc->sc_padr_retried), pppoe_timeout, sc); + break; + case PPPOE_STATE_CLOSING: + pppoe_do_disconnect(sc); + break; + default: + return; /* all done, work in peace */ + } +} + +/* Start a connection (i.e. initiate discovery phase) */ +int +pppoe_connect(struct pppoe_softc *sc) +{ + int err; + + if (sc->sc_state != PPPOE_STATE_INITIAL) { + return EBUSY; + } + +#ifdef PPPOE_SERVER + /* wait PADI if IFF_PASSIVE */ + if ((sc->sc_sppp.pp_if.if_flags & IFF_PASSIVE)) { + return 0; + } +#endif + /* save state, in case we fail to send PADI */ + sc->sc_state = PPPOE_STATE_PADI_SENT; + sc->sc_padr_retried = 0; + err = pppoe_send_padi(sc); + PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F": failed to send PADI, error=%d\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, err)); + sys_timeout(PPPOE_DISC_TIMEOUT, pppoe_timeout, sc); + return err; +} + +/* disconnect */ +void +pppoe_disconnect(struct pppoe_softc *sc) +{ + if (sc->sc_state < PPPOE_STATE_SESSION) { + return; + } + /* + * Do not call pppoe_disconnect here, the upper layer state + * machine gets confused by this. We must return from this + * function and defer disconnecting to the timeout handler. + */ + sc->sc_state = PPPOE_STATE_CLOSING; + sys_timeout(20, pppoe_timeout, sc); +} + +static int +pppoe_do_disconnect(struct pppoe_softc *sc) +{ + int err; + + if (sc->sc_state < PPPOE_STATE_SESSION) { + err = EBUSY; + } else { + PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F": disconnecting\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num)); + err = pppoe_send_padt(sc->sc_ethif, sc->sc_session, (const u8_t *)&sc->sc_dest); + } + + /* cleanup softc */ + sc->sc_state = PPPOE_STATE_INITIAL; + MEMCPY(&sc->sc_dest, ethbroadcast.addr, sizeof(sc->sc_dest)); + sc->sc_ac_cookie_len = 0; +#ifdef PPPOE_SERVER + if (sc->sc_hunique) { + mem_free(sc->sc_hunique); + sc->sc_hunique = NULL; + } + sc->sc_hunique_len = 0; +#endif + sc->sc_session = 0; + + sc->sc_linkStatusCB(sc->sc_pd, 0); /* notify upper layers */ + + return err; +} + +/* Connection attempt aborted */ +static void +pppoe_abort_connect(struct pppoe_softc *sc) +{ + printf("%c%c%"U16_F": could not establish connection\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num); + sc->sc_state = PPPOE_STATE_CLOSING; + + sc->sc_linkStatusCB(sc->sc_pd, 0); /* notify upper layers */ + + /* clear connection state */ + MEMCPY(&sc->sc_dest, ethbroadcast.addr, sizeof(sc->sc_dest)); + sc->sc_state = PPPOE_STATE_INITIAL; +} + +/* Send a PADR packet */ +static err_t +pppoe_send_padr(struct pppoe_softc *sc) +{ + struct pbuf *pb; + u8_t *p; + size_t len; +#ifdef PPPOE_TODO + size_t l1 = 0; /* XXX: gcc */ +#endif /* PPPOE_TODO */ + + if (sc->sc_state != PPPOE_STATE_PADR_SENT) { + return ERR_CONN; + } + + len = 2 + 2 + 2 + 2 + sizeof(sc); /* service name, host unique */ +#ifdef PPPOE_TODO + if (sc->sc_service_name != NULL) { /* service name tag maybe empty */ + l1 = strlen(sc->sc_service_name); + len += l1; + } +#endif /* PPPOE_TODO */ + if (sc->sc_ac_cookie_len > 0) { + len += 2 + 2 + sc->sc_ac_cookie_len; /* AC cookie */ + } + LWIP_ASSERT("sizeof(struct eth_hdr) + PPPOE_HEADERLEN + len <= 0xffff", + sizeof(struct eth_hdr) + PPPOE_HEADERLEN + len <= 0xffff); + pb = pbuf_alloc(PBUF_LINK, (u16_t)(sizeof(struct eth_hdr) + PPPOE_HEADERLEN + len), PBUF_RAM); + if (!pb) { + return ERR_MEM; + } + LWIP_ASSERT("pb->tot_len == pb->len", pb->tot_len == pb->len); + p = (u8_t*)pb->payload + sizeof (struct eth_hdr); + PPPOE_ADD_HEADER(p, PPPOE_CODE_PADR, 0, len); + PPPOE_ADD_16(p, PPPOE_TAG_SNAME); +#ifdef PPPOE_TODO + if (sc->sc_service_name != NULL) { + PPPOE_ADD_16(p, l1); + MEMCPY(p, sc->sc_service_name, l1); + p += l1; + } else +#endif /* PPPOE_TODO */ + { + PPPOE_ADD_16(p, 0); + } + if (sc->sc_ac_cookie_len > 0) { + PPPOE_ADD_16(p, PPPOE_TAG_ACCOOKIE); + PPPOE_ADD_16(p, sc->sc_ac_cookie_len); + MEMCPY(p, sc->sc_ac_cookie, sc->sc_ac_cookie_len); + p += sc->sc_ac_cookie_len; + } + PPPOE_ADD_16(p, PPPOE_TAG_HUNIQUE); + PPPOE_ADD_16(p, sizeof(sc)); + MEMCPY(p, &sc, sizeof sc); + + return pppoe_output(sc, pb); +} + +/* send a PADT packet */ +static err_t +pppoe_send_padt(struct netif *outgoing_if, u_int session, const u8_t *dest) +{ + struct pbuf *pb; + struct eth_hdr *ethhdr; + err_t res; + u8_t *p; + + pb = pbuf_alloc(PBUF_LINK, sizeof(struct eth_hdr) + PPPOE_HEADERLEN, PBUF_RAM); + if (!pb) { + return ERR_MEM; + } + LWIP_ASSERT("pb->tot_len == pb->len", pb->tot_len == pb->len); + + ethhdr = (struct eth_hdr *)pb->payload; + ethhdr->type = PP_HTONS(ETHTYPE_PPPOEDISC); + MEMCPY(ethhdr->dest.addr, dest, sizeof(ethhdr->dest.addr)); + MEMCPY(ethhdr->src.addr, ((struct eth_addr *)outgoing_if->hwaddr)->addr, sizeof(ethhdr->src.addr)); + + p = (u8_t*)(ethhdr + 1); + PPPOE_ADD_HEADER(p, PPPOE_CODE_PADT, session, 0); + + res = outgoing_if->linkoutput(outgoing_if, pb); + + pbuf_free(pb); + + return res; +} + +#ifdef PPPOE_SERVER +static err_t +pppoe_send_pado(struct pppoe_softc *sc) +{ + struct pbuf *pb; + u8_t *p; + size_t len; + + if (sc->sc_state != PPPOE_STATE_PADO_SENT) { + return ERR_CONN; + } + + /* calc length */ + len = 0; + /* include ac_cookie */ + len += 2 + 2 + sizeof(sc); + /* include hunique */ + len += 2 + 2 + sc->sc_hunique_len; + pb = pbuf_alloc(PBUF_LINK, sizeof(struct eth_hdr) + PPPOE_HEADERLEN + len, PBUF_RAM); + if (!pb) { + return ERR_MEM; + } + LWIP_ASSERT("pb->tot_len == pb->len", pb->tot_len == pb->len); + p = (u8_t*)pb->payload + sizeof (struct eth_hdr); + PPPOE_ADD_HEADER(p, PPPOE_CODE_PADO, 0, len); + PPPOE_ADD_16(p, PPPOE_TAG_ACCOOKIE); + PPPOE_ADD_16(p, sizeof(sc)); + MEMCPY(p, &sc, sizeof(sc)); + p += sizeof(sc); + PPPOE_ADD_16(p, PPPOE_TAG_HUNIQUE); + PPPOE_ADD_16(p, sc->sc_hunique_len); + MEMCPY(p, sc->sc_hunique, sc->sc_hunique_len); + return pppoe_output(sc, pb); +} + +static err_t +pppoe_send_pads(struct pppoe_softc *sc) +{ + struct pbuf *pb; + u8_t *p; + size_t len, l1 = 0; /* XXX: gcc */ + + if (sc->sc_state != PPPOE_STATE_PADO_SENT) { + return ERR_CONN; + } + + sc->sc_session = mono_time.tv_sec % 0xff + 1; + /* calc length */ + len = 0; + /* include hunique */ + len += 2 + 2 + 2 + 2 + sc->sc_hunique_len; /* service name, host unique*/ + if (sc->sc_service_name != NULL) { /* service name tag maybe empty */ + l1 = strlen(sc->sc_service_name); + len += l1; + } + pb = pbuf_alloc(PBUF_LINK, sizeof(struct eth_hdr) + PPPOE_HEADERLEN + len, PBUF_RAM); + if (!pb) { + return ERR_MEM; + } + LWIP_ASSERT("pb->tot_len == pb->len", pb->tot_len == pb->len); + p = (u8_t*)pb->payload + sizeof (struct eth_hdr); + PPPOE_ADD_HEADER(p, PPPOE_CODE_PADS, sc->sc_session, len); + PPPOE_ADD_16(p, PPPOE_TAG_SNAME); + if (sc->sc_service_name != NULL) { + PPPOE_ADD_16(p, l1); + MEMCPY(p, sc->sc_service_name, l1); + p += l1; + } else { + PPPOE_ADD_16(p, 0); + } + PPPOE_ADD_16(p, PPPOE_TAG_HUNIQUE); + PPPOE_ADD_16(p, sc->sc_hunique_len); + MEMCPY(p, sc->sc_hunique, sc->sc_hunique_len); + return pppoe_output(sc, pb); +} +#endif + +err_t +pppoe_xmit(struct pppoe_softc *sc, struct pbuf *pb) +{ + u8_t *p; + size_t len; + + /* are we ready to process data yet? */ + if (sc->sc_state < PPPOE_STATE_SESSION) { + /*sppp_flush(&sc->sc_sppp.pp_if);*/ + pbuf_free(pb); + return ERR_CONN; + } + + len = pb->tot_len; + + /* make room for Ethernet header - should not fail */ + if (pbuf_header(pb, sizeof(struct eth_hdr) + PPPOE_HEADERLEN) != 0) { + /* bail out */ + PPPDEBUG(LOG_ERR, ("pppoe: %c%c%"U16_F": pppoe_xmit: could not allocate room for header\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num)); + LINK_STATS_INC(link.lenerr); + pbuf_free(pb); + return ERR_BUF; + } + + p = (u8_t*)pb->payload + sizeof(struct eth_hdr); + PPPOE_ADD_HEADER(p, 0, sc->sc_session, len); + + return pppoe_output(sc, pb); +} + +#if 0 /*def PFIL_HOOKS*/ +static int +pppoe_ifattach_hook(void *arg, struct pbuf **mp, struct netif *ifp, int dir) +{ + struct pppoe_softc *sc; + int s; + + if (mp != (struct pbuf **)PFIL_IFNET_DETACH) { + return 0; + } + + LIST_FOREACH(sc, &pppoe_softc_list, sc_list) { + if (sc->sc_ethif != ifp) { + continue; + } + if (sc->sc_sppp.pp_if.if_flags & IFF_UP) { + sc->sc_sppp.pp_if.if_flags &= ~(IFF_UP|IFF_RUNNING); + printf("%c%c%"U16_F": ethernet interface detached, going down\n", + sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num); + } + sc->sc_ethif = NULL; + pppoe_clear_softc(sc, "ethernet interface detached"); + } + + return 0; +} +#endif + +static void +pppoe_clear_softc(struct pppoe_softc *sc, const char *message) +{ + LWIP_UNUSED_ARG(message); + + /* stop timer */ + sys_untimeout(pppoe_timeout, sc); + PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F": session 0x%x terminated, %s\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, sc->sc_session, message)); + + /* fix our state */ + sc->sc_state = PPPOE_STATE_INITIAL; + + /* notify upper layers */ + sc->sc_linkStatusCB(sc->sc_pd, 0); + + /* clean up softc */ + MEMCPY(&sc->sc_dest, ethbroadcast.addr, sizeof(sc->sc_dest)); + sc->sc_ac_cookie_len = 0; + sc->sc_session = 0; +} + +#endif /* PPPOE_SUPPORT */ + diff --git a/src/lwip-1.4.1/src/netif/ppp/pppdebug.h b/src/lwip-1.4.1/src/netif/ppp/pppdebug.h new file mode 100644 index 0000000..8134997 --- /dev/null +++ b/src/lwip-1.4.1/src/netif/ppp/pppdebug.h @@ -0,0 +1,73 @@ +/***************************************************************************** +* pppdebug.h - System debugging utilities. +* +* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. +* portions Copyright (c) 1998 Global Election Systems Inc. +* portions Copyright (c) 2001 by Cognizant Pty Ltd. +* +* The authors hereby grant permission to use, copy, modify, distribute, +* and license this software and its documentation for any purpose, provided +* that existing copyright notices are retained in all copies and that this +* notice and the following disclaimer are included verbatim in any +* distributions. No written agreement, license, or royalty fee is required +* for any of the authorized uses. +* +* THIS SOFTWARE IS PROVIDED BY THE 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 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. +* +****************************************************************************** +* REVISION HISTORY (please don't use tabs!) +* +* 03-01-01 Marc Boucher +* Ported to lwIP. +* 98-07-29 Guy Lancaster , Global Election Systems Inc. +* Original. +* +***************************************************************************** +*/ +#ifndef PPPDEBUG_H +#define PPPDEBUG_H + +/* Trace levels. */ +#define LOG_CRITICAL (PPP_DEBUG | LWIP_DBG_LEVEL_SEVERE) +#define LOG_ERR (PPP_DEBUG | LWIP_DBG_LEVEL_SEVERE) +#define LOG_NOTICE (PPP_DEBUG | LWIP_DBG_LEVEL_WARNING) +#define LOG_WARNING (PPP_DEBUG | LWIP_DBG_LEVEL_WARNING) +#define LOG_INFO (PPP_DEBUG) +#define LOG_DETAIL (PPP_DEBUG) +#define LOG_DEBUG (PPP_DEBUG) + + +#define TRACELCP PPP_DEBUG + +#if PPP_DEBUG + +#define AUTHDEBUG(a, b) LWIP_DEBUGF(a, b) +#define IPCPDEBUG(a, b) LWIP_DEBUGF(a, b) +#define UPAPDEBUG(a, b) LWIP_DEBUGF(a, b) +#define LCPDEBUG(a, b) LWIP_DEBUGF(a, b) +#define FSMDEBUG(a, b) LWIP_DEBUGF(a, b) +#define CHAPDEBUG(a, b) LWIP_DEBUGF(a, b) +#define PPPDEBUG(a, b) LWIP_DEBUGF(a, b) + +#else /* PPP_DEBUG */ + +#define AUTHDEBUG(a, b) +#define IPCPDEBUG(a, b) +#define UPAPDEBUG(a, b) +#define LCPDEBUG(a, b) +#define FSMDEBUG(a, b) +#define CHAPDEBUG(a, b) +#define PPPDEBUG(a, b) + +#endif /* PPP_DEBUG */ + +#endif /* PPPDEBUG_H */ diff --git a/src/lwip-1.4.1/src/netif/ppp/randm.c b/src/lwip-1.4.1/src/netif/ppp/randm.c new file mode 100644 index 0000000..b736091 --- /dev/null +++ b/src/lwip-1.4.1/src/netif/ppp/randm.c @@ -0,0 +1,249 @@ +/***************************************************************************** +* randm.c - Random number generator program file. +* +* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. +* Copyright (c) 1998 by Global Election Systems Inc. +* +* The authors hereby grant permission to use, copy, modify, distribute, +* and license this software and its documentation for any purpose, provided +* that existing copyright notices are retained in all copies and that this +* notice and the following disclaimer are included verbatim in any +* distributions. No written agreement, license, or royalty fee is required +* for any of the authorized uses. +* +* THIS SOFTWARE IS PROVIDED BY THE 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 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. +* +****************************************************************************** +* REVISION HISTORY +* +* 03-01-01 Marc Boucher +* Ported to lwIP. +* 98-06-03 Guy Lancaster , Global Election Systems Inc. +* Extracted from avos. +*****************************************************************************/ + +#include "lwip/opt.h" + +#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ + +#include "md5.h" +#include "randm.h" + +#include "ppp_impl.h" +#include "pppdebug.h" + +#include + +#if MD5_SUPPORT /* this module depends on MD5 */ +#define RANDPOOLSZ 16 /* Bytes stored in the pool of randomness. */ + +/*****************************/ +/*** LOCAL DATA STRUCTURES ***/ +/*****************************/ +static char randPool[RANDPOOLSZ]; /* Pool of randomness. */ +static long randCount = 0; /* Pseudo-random incrementer */ + + +/***********************************/ +/*** PUBLIC FUNCTION DEFINITIONS ***/ +/***********************************/ +/* + * Initialize the random number generator. + * + * Since this is to be called on power up, we don't have much + * system randomess to work with. Here all we use is the + * real-time clock. We'll accumulate more randomness as soon + * as things start happening. + */ +void +avRandomInit() +{ + avChurnRand(NULL, 0); +} + +/* + * Churn the randomness pool on a random event. Call this early and often + * on random and semi-random system events to build randomness in time for + * usage. For randomly timed events, pass a null pointer and a zero length + * and this will use the system timer and other sources to add randomness. + * If new random data is available, pass a pointer to that and it will be + * included. + * + * Ref: Applied Cryptography 2nd Ed. by Bruce Schneier p. 427 + */ +void +avChurnRand(char *randData, u32_t randLen) +{ + MD5_CTX md5; + + /* LWIP_DEBUGF(LOG_INFO, ("churnRand: %u@%P\n", randLen, randData)); */ + MD5Init(&md5); + MD5Update(&md5, (u_char *)randPool, sizeof(randPool)); + if (randData) { + MD5Update(&md5, (u_char *)randData, randLen); + } else { + struct { + /* INCLUDE fields for any system sources of randomness */ + char foobar; + } sysData; + + /* Load sysData fields here. */ + MD5Update(&md5, (u_char *)&sysData, sizeof(sysData)); + } + MD5Final((u_char *)randPool, &md5); +/* LWIP_DEBUGF(LOG_INFO, ("churnRand: -> 0\n")); */ +} + +/* + * Use the random pool to generate random data. This degrades to pseudo + * random when used faster than randomness is supplied using churnRand(). + * Note: It's important that there be sufficient randomness in randPool + * before this is called for otherwise the range of the result may be + * narrow enough to make a search feasible. + * + * Ref: Applied Cryptography 2nd Ed. by Bruce Schneier p. 427 + * + * XXX Why does he not just call churnRand() for each block? Probably + * so that you don't ever publish the seed which could possibly help + * predict future values. + * XXX Why don't we preserve md5 between blocks and just update it with + * randCount each time? Probably there is a weakness but I wish that + * it was documented. + */ +void +avGenRand(char *buf, u32_t bufLen) +{ + MD5_CTX md5; + u_char tmp[16]; + u32_t n; + + while (bufLen > 0) { + n = LWIP_MIN(bufLen, RANDPOOLSZ); + MD5Init(&md5); + MD5Update(&md5, (u_char *)randPool, sizeof(randPool)); + MD5Update(&md5, (u_char *)&randCount, sizeof(randCount)); + MD5Final(tmp, &md5); + randCount++; + MEMCPY(buf, tmp, n); + buf += n; + bufLen -= n; + } +} + +/* + * Return a new random number. + */ +u32_t +avRandom() +{ + u32_t newRand; + + avGenRand((char *)&newRand, sizeof(newRand)); + + return newRand; +} + +#else /* MD5_SUPPORT */ + +/*****************************/ +/*** LOCAL DATA STRUCTURES ***/ +/*****************************/ +static int avRandomized = 0; /* Set when truely randomized. */ +static u32_t avRandomSeed = 0; /* Seed used for random number generation. */ + + +/***********************************/ +/*** PUBLIC FUNCTION DEFINITIONS ***/ +/***********************************/ +/* + * Initialize the random number generator. + * + * Here we attempt to compute a random number seed but even if + * it isn't random, we'll randomize it later. + * + * The current method uses the fields from the real time clock, + * the idle process counter, the millisecond counter, and the + * hardware timer tick counter. When this is invoked + * in startup(), then the idle counter and timer values may + * repeat after each boot and the real time clock may not be + * operational. Thus we call it again on the first random + * event. + */ +void +avRandomInit() +{ +#if 0 + /* Get a pointer into the last 4 bytes of clockBuf. */ + u32_t *lptr1 = (u32_t *)((char *)&clockBuf[3]); + + /* + * Initialize our seed using the real-time clock, the idle + * counter, the millisecond timer, and the hardware timer + * tick counter. The real-time clock and the hardware + * tick counter are the best sources of randomness but + * since the tick counter is only 16 bit (and truncated + * at that), the idle counter and millisecond timer + * (which may be small values) are added to help + * randomize the lower 16 bits of the seed. + */ + readClk(); + avRandomSeed += *(u32_t *)clockBuf + *lptr1 + OSIdleCtr + + ppp_mtime() + ((u32_t)TM1 << 16) + TM1; +#else + avRandomSeed += sys_jiffies(); /* XXX */ +#endif + + /* Initialize the Borland random number generator. */ + srand((unsigned)avRandomSeed); +} + +/* + * Randomize our random seed value. Here we use the fact that + * this function is called at *truely random* times by the polling + * and network functions. Here we only get 16 bits of new random + * value but we use the previous value to randomize the other 16 + * bits. + */ +void +avRandomize(void) +{ + static u32_t last_jiffies; + + if (!avRandomized) { + avRandomized = !0; + avRandomInit(); + /* The initialization function also updates the seed. */ + } else { + /* avRandomSeed += (avRandomSeed << 16) + TM1; */ + avRandomSeed += (sys_jiffies() - last_jiffies); /* XXX */ + } + last_jiffies = sys_jiffies(); +} + +/* + * Return a new random number. + * Here we use the Borland rand() function to supply a pseudo random + * number which we make truely random by combining it with our own + * seed which is randomized by truely random events. + * Thus the numbers will be truely random unless there have been no + * operator or network events in which case it will be pseudo random + * seeded by the real time clock. + */ +u32_t +avRandom() +{ + return ((((u32_t)rand() << 16) + rand()) + avRandomSeed); +} + +#endif /* MD5_SUPPORT */ + +#endif /* PPP_SUPPORT */ diff --git a/src/lwip-1.4.1/src/netif/ppp/randm.h b/src/lwip-1.4.1/src/netif/ppp/randm.h new file mode 100644 index 0000000..a0984b0 --- /dev/null +++ b/src/lwip-1.4.1/src/netif/ppp/randm.h @@ -0,0 +1,81 @@ +/***************************************************************************** +* randm.h - Random number generator header file. +* +* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. +* Copyright (c) 1998 Global Election Systems Inc. +* +* The authors hereby grant permission to use, copy, modify, distribute, +* and license this software and its documentation for any purpose, provided +* that existing copyright notices are retained in all copies and that this +* notice and the following disclaimer are included verbatim in any +* distributions. No written agreement, license, or royalty fee is required +* for any of the authorized uses. +* +* THIS SOFTWARE IS PROVIDED BY THE 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 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. +* +****************************************************************************** +* REVISION HISTORY +* +* 03-01-01 Marc Boucher +* Ported to lwIP. +* 98-05-29 Guy Lancaster , Global Election Systems Inc. +* Extracted from avos. +*****************************************************************************/ + +#ifndef RANDM_H +#define RANDM_H + +/*********************** +*** PUBLIC FUNCTIONS *** +***********************/ +/* + * Initialize the random number generator. + */ +void avRandomInit(void); + +/* + * Churn the randomness pool on a random event. Call this early and often + * on random and semi-random system events to build randomness in time for + * usage. For randomly timed events, pass a null pointer and a zero length + * and this will use the system timer and other sources to add randomness. + * If new random data is available, pass a pointer to that and it will be + * included. + */ +void avChurnRand(char *randData, u32_t randLen); + +/* + * Randomize our random seed value. To be called for truely random events + * such as user operations and network traffic. + */ +#if MD5_SUPPORT +#define avRandomize() avChurnRand(NULL, 0) +#else /* MD5_SUPPORT */ +void avRandomize(void); +#endif /* MD5_SUPPORT */ + +/* + * Use the random pool to generate random data. This degrades to pseudo + * random when used faster than randomness is supplied using churnRand(). + * Thus it's important to make sure that the results of this are not + * published directly because one could predict the next result to at + * least some degree. Also, it's important to get a good seed before + * the first use. + */ +void avGenRand(char *buf, u32_t bufLen); + +/* + * Return a new random number. + */ +u32_t avRandom(void); + + +#endif /* RANDM_H */ diff --git a/src/lwip-1.4.1/src/netif/ppp/vj.c b/src/lwip-1.4.1/src/netif/ppp/vj.c new file mode 100644 index 0000000..40fdad1 --- /dev/null +++ b/src/lwip-1.4.1/src/netif/ppp/vj.c @@ -0,0 +1,652 @@ +/* + * Routines to compress and uncompess tcp packets (for transmission + * over low speed serial lines. + * + * Copyright (c) 1989 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by the University of California, Berkeley. The name of the + * University may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Van Jacobson (van@helios.ee.lbl.gov), Dec 31, 1989: + * Initial distribution. + * + * Modified June 1993 by Paul Mackerras, paulus@cs.anu.edu.au, + * so that the entire packet being decompressed doesn't have + * to be in contiguous memory (just the compressed header). + * + * Modified March 1998 by Guy Lancaster, glanca@gesn.com, + * for a 16 bit processor. + */ + +#include "lwip/opt.h" + +#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ + +#include "ppp_impl.h" +#include "pppdebug.h" + +#include "vj.h" + +#include + +#if VJ_SUPPORT + +#if LINK_STATS +#define INCR(counter) ++comp->stats.counter +#else +#define INCR(counter) +#endif + +void +vj_compress_init(struct vjcompress *comp) +{ + register u_char i; + register struct cstate *tstate = comp->tstate; + +#if MAX_SLOTS == 0 + memset((char *)comp, 0, sizeof(*comp)); +#endif + comp->maxSlotIndex = MAX_SLOTS - 1; + comp->compressSlot = 0; /* Disable slot ID compression by default. */ + for (i = MAX_SLOTS - 1; i > 0; --i) { + tstate[i].cs_id = i; + tstate[i].cs_next = &tstate[i - 1]; + } + tstate[0].cs_next = &tstate[MAX_SLOTS - 1]; + tstate[0].cs_id = 0; + comp->last_cs = &tstate[0]; + comp->last_recv = 255; + comp->last_xmit = 255; + comp->flags = VJF_TOSS; +} + + +/* ENCODE encodes a number that is known to be non-zero. ENCODEZ + * checks for zero (since zero has to be encoded in the long, 3 byte + * form). + */ +#define ENCODE(n) { \ + if ((u_short)(n) >= 256) { \ + *cp++ = 0; \ + cp[1] = (u_char)(n); \ + cp[0] = (u_char)((n) >> 8); \ + cp += 2; \ + } else { \ + *cp++ = (u_char)(n); \ + } \ +} +#define ENCODEZ(n) { \ + if ((u_short)(n) >= 256 || (u_short)(n) == 0) { \ + *cp++ = 0; \ + cp[1] = (u_char)(n); \ + cp[0] = (u_char)((n) >> 8); \ + cp += 2; \ + } else { \ + *cp++ = (u_char)(n); \ + } \ +} + +#define DECODEL(f) { \ + if (*cp == 0) {\ + u32_t tmp = ntohl(f) + ((cp[1] << 8) | cp[2]); \ + (f) = htonl(tmp); \ + cp += 3; \ + } else { \ + u32_t tmp = ntohl(f) + (u32_t)*cp++; \ + (f) = htonl(tmp); \ + } \ +} + +#define DECODES(f) { \ + if (*cp == 0) {\ + u_short tmp = ntohs(f) + (((u_short)cp[1] << 8) | cp[2]); \ + (f) = htons(tmp); \ + cp += 3; \ + } else { \ + u_short tmp = ntohs(f) + (u_short)*cp++; \ + (f) = htons(tmp); \ + } \ +} + +#define DECODEU(f) { \ + if (*cp == 0) {\ + (f) = htons(((u_short)cp[1] << 8) | cp[2]); \ + cp += 3; \ + } else { \ + (f) = htons((u_short)*cp++); \ + } \ +} + +/* + * vj_compress_tcp - Attempt to do Van Jacobson header compression on a + * packet. This assumes that nb and comp are not null and that the first + * buffer of the chain contains a valid IP header. + * Return the VJ type code indicating whether or not the packet was + * compressed. + */ +u_int +vj_compress_tcp(struct vjcompress *comp, struct pbuf *pb) +{ + register struct ip_hdr *ip = (struct ip_hdr *)pb->payload; + register struct cstate *cs = comp->last_cs->cs_next; + register u_short hlen = IPH_HL(ip); + register struct tcp_hdr *oth; + register struct tcp_hdr *th; + register u_short deltaS, deltaA; + register u_long deltaL; + register u_int changes = 0; + u_char new_seq[16]; + register u_char *cp = new_seq; + + /* + * Check that the packet is IP proto TCP. + */ + if (IPH_PROTO(ip) != IP_PROTO_TCP) { + return (TYPE_IP); + } + + /* + * Bail if this is an IP fragment or if the TCP packet isn't + * `compressible' (i.e., ACK isn't set or some other control bit is + * set). + */ + if ((IPH_OFFSET(ip) & PP_HTONS(0x3fff)) || pb->tot_len < 40) { + return (TYPE_IP); + } + th = (struct tcp_hdr *)&((long *)ip)[hlen]; + if ((TCPH_FLAGS(th) & (TCP_SYN|TCP_FIN|TCP_RST|TCP_ACK)) != TCP_ACK) { + return (TYPE_IP); + } + /* + * Packet is compressible -- we're going to send either a + * COMPRESSED_TCP or UNCOMPRESSED_TCP packet. Either way we need + * to locate (or create) the connection state. Special case the + * most recently used connection since it's most likely to be used + * again & we don't have to do any reordering if it's used. + */ + INCR(vjs_packets); + if (!ip_addr_cmp(&ip->src, &cs->cs_ip.src) + || !ip_addr_cmp(&ip->dest, &cs->cs_ip.dest) + || *(long *)th != ((long *)&cs->cs_ip)[IPH_HL(&cs->cs_ip)]) { + /* + * Wasn't the first -- search for it. + * + * States are kept in a circularly linked list with + * last_cs pointing to the end of the list. The + * list is kept in lru order by moving a state to the + * head of the list whenever it is referenced. Since + * the list is short and, empirically, the connection + * we want is almost always near the front, we locate + * states via linear search. If we don't find a state + * for the datagram, the oldest state is (re-)used. + */ + register struct cstate *lcs; + register struct cstate *lastcs = comp->last_cs; + + do { + lcs = cs; cs = cs->cs_next; + INCR(vjs_searches); + if (ip_addr_cmp(&ip->src, &cs->cs_ip.src) + && ip_addr_cmp(&ip->dest, &cs->cs_ip.dest) + && *(long *)th == ((long *)&cs->cs_ip)[IPH_HL(&cs->cs_ip)]) { + goto found; + } + } while (cs != lastcs); + + /* + * Didn't find it -- re-use oldest cstate. Send an + * uncompressed packet that tells the other side what + * connection number we're using for this conversation. + * Note that since the state list is circular, the oldest + * state points to the newest and we only need to set + * last_cs to update the lru linkage. + */ + INCR(vjs_misses); + comp->last_cs = lcs; + hlen += TCPH_HDRLEN(th); + hlen <<= 2; + /* Check that the IP/TCP headers are contained in the first buffer. */ + if (hlen > pb->len) { + return (TYPE_IP); + } + goto uncompressed; + + found: + /* + * Found it -- move to the front on the connection list. + */ + if (cs == lastcs) { + comp->last_cs = lcs; + } else { + lcs->cs_next = cs->cs_next; + cs->cs_next = lastcs->cs_next; + lastcs->cs_next = cs; + } + } + + oth = (struct tcp_hdr *)&((long *)&cs->cs_ip)[hlen]; + deltaS = hlen; + hlen += TCPH_HDRLEN(th); + hlen <<= 2; + /* Check that the IP/TCP headers are contained in the first buffer. */ + if (hlen > pb->len) { + PPPDEBUG(LOG_INFO, ("vj_compress_tcp: header len %d spans buffers\n", hlen)); + return (TYPE_IP); + } + + /* + * Make sure that only what we expect to change changed. The first + * line of the `if' checks the IP protocol version, header length & + * type of service. The 2nd line checks the "Don't fragment" bit. + * The 3rd line checks the time-to-live and protocol (the protocol + * check is unnecessary but costless). The 4th line checks the TCP + * header length. The 5th line checks IP options, if any. The 6th + * line checks TCP options, if any. If any of these things are + * different between the previous & current datagram, we send the + * current datagram `uncompressed'. + */ + if (((u_short *)ip)[0] != ((u_short *)&cs->cs_ip)[0] + || ((u_short *)ip)[3] != ((u_short *)&cs->cs_ip)[3] + || ((u_short *)ip)[4] != ((u_short *)&cs->cs_ip)[4] + || TCPH_HDRLEN(th) != TCPH_HDRLEN(oth) + || (deltaS > 5 && BCMP(ip + 1, &cs->cs_ip + 1, (deltaS - 5) << 2)) + || (TCPH_HDRLEN(th) > 5 && BCMP(th + 1, oth + 1, (TCPH_HDRLEN(th) - 5) << 2))) { + goto uncompressed; + } + + /* + * Figure out which of the changing fields changed. The + * receiver expects changes in the order: urgent, window, + * ack, seq (the order minimizes the number of temporaries + * needed in this section of code). + */ + if (TCPH_FLAGS(th) & TCP_URG) { + deltaS = ntohs(th->urgp); + ENCODEZ(deltaS); + changes |= NEW_U; + } else if (th->urgp != oth->urgp) { + /* argh! URG not set but urp changed -- a sensible + * implementation should never do this but RFC793 + * doesn't prohibit the change so we have to deal + * with it. */ + goto uncompressed; + } + + if ((deltaS = (u_short)(ntohs(th->wnd) - ntohs(oth->wnd))) != 0) { + ENCODE(deltaS); + changes |= NEW_W; + } + + if ((deltaL = ntohl(th->ackno) - ntohl(oth->ackno)) != 0) { + if (deltaL > 0xffff) { + goto uncompressed; + } + deltaA = (u_short)deltaL; + ENCODE(deltaA); + changes |= NEW_A; + } + + if ((deltaL = ntohl(th->seqno) - ntohl(oth->seqno)) != 0) { + if (deltaL > 0xffff) { + goto uncompressed; + } + deltaS = (u_short)deltaL; + ENCODE(deltaS); + changes |= NEW_S; + } + + switch(changes) { + case 0: + /* + * Nothing changed. If this packet contains data and the + * last one didn't, this is probably a data packet following + * an ack (normal on an interactive connection) and we send + * it compressed. Otherwise it's probably a retransmit, + * retransmitted ack or window probe. Send it uncompressed + * in case the other side missed the compressed version. + */ + if (IPH_LEN(ip) != IPH_LEN(&cs->cs_ip) && + ntohs(IPH_LEN(&cs->cs_ip)) == hlen) { + break; + } + + /* (fall through) */ + + case SPECIAL_I: + case SPECIAL_D: + /* + * actual changes match one of our special case encodings -- + * send packet uncompressed. + */ + goto uncompressed; + + case NEW_S|NEW_A: + if (deltaS == deltaA && deltaS == ntohs(IPH_LEN(&cs->cs_ip)) - hlen) { + /* special case for echoed terminal traffic */ + changes = SPECIAL_I; + cp = new_seq; + } + break; + + case NEW_S: + if (deltaS == ntohs(IPH_LEN(&cs->cs_ip)) - hlen) { + /* special case for data xfer */ + changes = SPECIAL_D; + cp = new_seq; + } + break; + } + + deltaS = (u_short)(ntohs(IPH_ID(ip)) - ntohs(IPH_ID(&cs->cs_ip))); + if (deltaS != 1) { + ENCODEZ(deltaS); + changes |= NEW_I; + } + if (TCPH_FLAGS(th) & TCP_PSH) { + changes |= TCP_PUSH_BIT; + } + /* + * Grab the cksum before we overwrite it below. Then update our + * state with this packet's header. + */ + deltaA = ntohs(th->chksum); + BCOPY(ip, &cs->cs_ip, hlen); + + /* + * We want to use the original packet as our compressed packet. + * (cp - new_seq) is the number of bytes we need for compressed + * sequence numbers. In addition we need one byte for the change + * mask, one for the connection id and two for the tcp checksum. + * So, (cp - new_seq) + 4 bytes of header are needed. hlen is how + * many bytes of the original packet to toss so subtract the two to + * get the new packet size. + */ + deltaS = (u_short)(cp - new_seq); + if (!comp->compressSlot || comp->last_xmit != cs->cs_id) { + comp->last_xmit = cs->cs_id; + hlen -= deltaS + 4; + if(pbuf_header(pb, -hlen)){ + /* Can we cope with this failing? Just assert for now */ + LWIP_ASSERT("pbuf_header failed\n", 0); + } + cp = (u_char *)pb->payload; + *cp++ = (u_char)(changes | NEW_C); + *cp++ = cs->cs_id; + } else { + hlen -= deltaS + 3; + if(pbuf_header(pb, -hlen)) { + /* Can we cope with this failing? Just assert for now */ + LWIP_ASSERT("pbuf_header failed\n", 0); + } + cp = (u_char *)pb->payload; + *cp++ = (u_char)changes; + } + *cp++ = (u_char)(deltaA >> 8); + *cp++ = (u_char)deltaA; + BCOPY(new_seq, cp, deltaS); + INCR(vjs_compressed); + return (TYPE_COMPRESSED_TCP); + + /* + * Update connection state cs & send uncompressed packet (that is, + * a regular ip/tcp packet but with the 'conversation id' we hope + * to use on future compressed packets in the protocol field). + */ +uncompressed: + BCOPY(ip, &cs->cs_ip, hlen); + IPH_PROTO_SET(ip, cs->cs_id); + comp->last_xmit = cs->cs_id; + return (TYPE_UNCOMPRESSED_TCP); +} + +/* + * Called when we may have missed a packet. + */ +void +vj_uncompress_err(struct vjcompress *comp) +{ + comp->flags |= VJF_TOSS; + INCR(vjs_errorin); +} + +/* + * "Uncompress" a packet of type TYPE_UNCOMPRESSED_TCP. + * Return 0 on success, -1 on failure. + */ +int +vj_uncompress_uncomp(struct pbuf *nb, struct vjcompress *comp) +{ + register u_int hlen; + register struct cstate *cs; + register struct ip_hdr *ip; + + ip = (struct ip_hdr *)nb->payload; + hlen = IPH_HL(ip) << 2; + if (IPH_PROTO(ip) >= MAX_SLOTS + || hlen + sizeof(struct tcp_hdr) > nb->len + || (hlen += TCPH_HDRLEN(((struct tcp_hdr *)&((char *)ip)[hlen])) << 2) + > nb->len + || hlen > MAX_HDR) { + PPPDEBUG(LOG_INFO, ("vj_uncompress_uncomp: bad cid=%d, hlen=%d buflen=%d\n", + IPH_PROTO(ip), hlen, nb->len)); + comp->flags |= VJF_TOSS; + INCR(vjs_errorin); + return -1; + } + cs = &comp->rstate[comp->last_recv = IPH_PROTO(ip)]; + comp->flags &=~ VJF_TOSS; + IPH_PROTO_SET(ip, IP_PROTO_TCP); + BCOPY(ip, &cs->cs_ip, hlen); + cs->cs_hlen = (u_short)hlen; + INCR(vjs_uncompressedin); + return 0; +} + +/* + * Uncompress a packet of type TYPE_COMPRESSED_TCP. + * The packet is composed of a buffer chain and the first buffer + * must contain an accurate chain length. + * The first buffer must include the entire compressed TCP/IP header. + * This procedure replaces the compressed header with the uncompressed + * header and returns the length of the VJ header. + */ +int +vj_uncompress_tcp(struct pbuf **nb, struct vjcompress *comp) +{ + u_char *cp; + struct tcp_hdr *th; + struct cstate *cs; + u_short *bp; + struct pbuf *n0 = *nb; + u32_t tmp; + u_int vjlen, hlen, changes; + + INCR(vjs_compressedin); + cp = (u_char *)n0->payload; + changes = *cp++; + if (changes & NEW_C) { + /* + * Make sure the state index is in range, then grab the state. + * If we have a good state index, clear the 'discard' flag. + */ + if (*cp >= MAX_SLOTS) { + PPPDEBUG(LOG_INFO, ("vj_uncompress_tcp: bad cid=%d\n", *cp)); + goto bad; + } + + comp->flags &=~ VJF_TOSS; + comp->last_recv = *cp++; + } else { + /* + * this packet has an implicit state index. If we've + * had a line error since the last time we got an + * explicit state index, we have to toss the packet. + */ + if (comp->flags & VJF_TOSS) { + PPPDEBUG(LOG_INFO, ("vj_uncompress_tcp: tossing\n")); + INCR(vjs_tossed); + return (-1); + } + } + cs = &comp->rstate[comp->last_recv]; + hlen = IPH_HL(&cs->cs_ip) << 2; + th = (struct tcp_hdr *)&((u_char *)&cs->cs_ip)[hlen]; + th->chksum = htons((*cp << 8) | cp[1]); + cp += 2; + if (changes & TCP_PUSH_BIT) { + TCPH_SET_FLAG(th, TCP_PSH); + } else { + TCPH_UNSET_FLAG(th, TCP_PSH); + } + + switch (changes & SPECIALS_MASK) { + case SPECIAL_I: + { + register u32_t i = ntohs(IPH_LEN(&cs->cs_ip)) - cs->cs_hlen; + /* some compilers can't nest inline assembler.. */ + tmp = ntohl(th->ackno) + i; + th->ackno = htonl(tmp); + tmp = ntohl(th->seqno) + i; + th->seqno = htonl(tmp); + } + break; + + case SPECIAL_D: + /* some compilers can't nest inline assembler.. */ + tmp = ntohl(th->seqno) + ntohs(IPH_LEN(&cs->cs_ip)) - cs->cs_hlen; + th->seqno = htonl(tmp); + break; + + default: + if (changes & NEW_U) { + TCPH_SET_FLAG(th, TCP_URG); + DECODEU(th->urgp); + } else { + TCPH_UNSET_FLAG(th, TCP_URG); + } + if (changes & NEW_W) { + DECODES(th->wnd); + } + if (changes & NEW_A) { + DECODEL(th->ackno); + } + if (changes & NEW_S) { + DECODEL(th->seqno); + } + break; + } + if (changes & NEW_I) { + DECODES(cs->cs_ip._id); + } else { + IPH_ID_SET(&cs->cs_ip, ntohs(IPH_ID(&cs->cs_ip)) + 1); + IPH_ID_SET(&cs->cs_ip, htons(IPH_ID(&cs->cs_ip))); + } + + /* + * At this point, cp points to the first byte of data in the + * packet. Fill in the IP total length and update the IP + * header checksum. + */ + vjlen = (u_short)(cp - (u_char*)n0->payload); + if (n0->len < vjlen) { + /* + * We must have dropped some characters (crc should detect + * this but the old slip framing won't) + */ + PPPDEBUG(LOG_INFO, ("vj_uncompress_tcp: head buffer %d too short %d\n", + n0->len, vjlen)); + goto bad; + } + +#if BYTE_ORDER == LITTLE_ENDIAN + tmp = n0->tot_len - vjlen + cs->cs_hlen; + IPH_LEN_SET(&cs->cs_ip, htons((u_short)tmp)); +#else + IPH_LEN_SET(&cs->cs_ip, htons(n0->tot_len - vjlen + cs->cs_hlen)); +#endif + + /* recompute the ip header checksum */ + bp = (u_short *) &cs->cs_ip; + IPH_CHKSUM_SET(&cs->cs_ip, 0); + for (tmp = 0; hlen > 0; hlen -= 2) { + tmp += *bp++; + } + tmp = (tmp & 0xffff) + (tmp >> 16); + tmp = (tmp & 0xffff) + (tmp >> 16); + IPH_CHKSUM_SET(&cs->cs_ip, (u_short)(~tmp)); + + /* Remove the compressed header and prepend the uncompressed header. */ + if(pbuf_header(n0, -((s16_t)(vjlen)))) { + /* Can we cope with this failing? Just assert for now */ + LWIP_ASSERT("pbuf_header failed\n", 0); + goto bad; + } + + if(LWIP_MEM_ALIGN(n0->payload) != n0->payload) { + struct pbuf *np, *q; + u8_t *bufptr; + + np = pbuf_alloc(PBUF_RAW, n0->len + cs->cs_hlen, PBUF_POOL); + if(!np) { + PPPDEBUG(LOG_WARNING, ("vj_uncompress_tcp: realign failed\n")); + goto bad; + } + + if(pbuf_header(np, -cs->cs_hlen)) { + /* Can we cope with this failing? Just assert for now */ + LWIP_ASSERT("pbuf_header failed\n", 0); + goto bad; + } + + bufptr = n0->payload; + for(q = np; q != NULL; q = q->next) { + MEMCPY(q->payload, bufptr, q->len); + bufptr += q->len; + } + + if(n0->next) { + pbuf_chain(np, n0->next); + pbuf_dechain(n0); + } + pbuf_free(n0); + n0 = np; + } + + if(pbuf_header(n0, cs->cs_hlen)) { + struct pbuf *np; + + LWIP_ASSERT("vj_uncompress_tcp: cs->cs_hlen <= PBUF_POOL_BUFSIZE", cs->cs_hlen <= PBUF_POOL_BUFSIZE); + np = pbuf_alloc(PBUF_RAW, cs->cs_hlen, PBUF_POOL); + if(!np) { + PPPDEBUG(LOG_WARNING, ("vj_uncompress_tcp: prepend failed\n")); + goto bad; + } + pbuf_cat(np, n0); + n0 = np; + } + LWIP_ASSERT("n0->len >= cs->cs_hlen", n0->len >= cs->cs_hlen); + MEMCPY(n0->payload, &cs->cs_ip, cs->cs_hlen); + + *nb = n0; + + return vjlen; + +bad: + comp->flags |= VJF_TOSS; + INCR(vjs_errorin); + return (-1); +} + +#endif /* VJ_SUPPORT */ + +#endif /* PPP_SUPPORT */ diff --git a/src/lwip-1.4.1/src/netif/ppp/vj.h b/src/lwip-1.4.1/src/netif/ppp/vj.h new file mode 100644 index 0000000..fad1213 --- /dev/null +++ b/src/lwip-1.4.1/src/netif/ppp/vj.h @@ -0,0 +1,156 @@ +/* + * Definitions for tcp compression routines. + * + * $Id: vj.h,v 1.7 2010/02/22 17:52:09 goldsimon Exp $ + * + * Copyright (c) 1989 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by the University of California, Berkeley. The name of the + * University may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Van Jacobson (van@helios.ee.lbl.gov), Dec 31, 1989: + * - Initial distribution. + */ + +#ifndef VJ_H +#define VJ_H + +#include "lwip/ip.h" +#include "lwip/tcp_impl.h" + +#define MAX_SLOTS 16 /* must be > 2 and < 256 */ +#define MAX_HDR 128 + +/* + * Compressed packet format: + * + * The first octet contains the packet type (top 3 bits), TCP + * 'push' bit, and flags that indicate which of the 4 TCP sequence + * numbers have changed (bottom 5 bits). The next octet is a + * conversation number that associates a saved IP/TCP header with + * the compressed packet. The next two octets are the TCP checksum + * from the original datagram. The next 0 to 15 octets are + * sequence number changes, one change per bit set in the header + * (there may be no changes and there are two special cases where + * the receiver implicitly knows what changed -- see below). + * + * There are 5 numbers which can change (they are always inserted + * in the following order): TCP urgent pointer, window, + * acknowlegement, sequence number and IP ID. (The urgent pointer + * is different from the others in that its value is sent, not the + * change in value.) Since typical use of SLIP links is biased + * toward small packets (see comments on MTU/MSS below), changes + * use a variable length coding with one octet for numbers in the + * range 1 - 255 and 3 octets (0, MSB, LSB) for numbers in the + * range 256 - 65535 or 0. (If the change in sequence number or + * ack is more than 65535, an uncompressed packet is sent.) + */ + +/* + * Packet types (must not conflict with IP protocol version) + * + * The top nibble of the first octet is the packet type. There are + * three possible types: IP (not proto TCP or tcp with one of the + * control flags set); uncompressed TCP (a normal IP/TCP packet but + * with the 8-bit protocol field replaced by an 8-bit connection id -- + * this type of packet syncs the sender & receiver); and compressed + * TCP (described above). + * + * LSB of 4-bit field is TCP "PUSH" bit (a worthless anachronism) and + * is logically part of the 4-bit "changes" field that follows. Top + * three bits are actual packet type. For backward compatibility + * and in the interest of conserving bits, numbers are chosen so the + * IP protocol version number (4) which normally appears in this nibble + * means "IP packet". + */ + +/* packet types */ +#define TYPE_IP 0x40 +#define TYPE_UNCOMPRESSED_TCP 0x70 +#define TYPE_COMPRESSED_TCP 0x80 +#define TYPE_ERROR 0x00 + +/* Bits in first octet of compressed packet */ +#define NEW_C 0x40 /* flag bits for what changed in a packet */ +#define NEW_I 0x20 +#define NEW_S 0x08 +#define NEW_A 0x04 +#define NEW_W 0x02 +#define NEW_U 0x01 + +/* reserved, special-case values of above */ +#define SPECIAL_I (NEW_S|NEW_W|NEW_U) /* echoed interactive traffic */ +#define SPECIAL_D (NEW_S|NEW_A|NEW_W|NEW_U) /* unidirectional data */ +#define SPECIALS_MASK (NEW_S|NEW_A|NEW_W|NEW_U) + +#define TCP_PUSH_BIT 0x10 + + +/* + * "state" data for each active tcp conversation on the wire. This is + * basically a copy of the entire IP/TCP header from the last packet + * we saw from the conversation together with a small identifier + * the transmit & receive ends of the line use to locate saved header. + */ +struct cstate { + struct cstate *cs_next; /* next most recently used state (xmit only) */ + u_short cs_hlen; /* size of hdr (receive only) */ + u_char cs_id; /* connection # associated with this state */ + u_char cs_filler; + union { + char csu_hdr[MAX_HDR]; + struct ip_hdr csu_ip; /* ip/tcp hdr from most recent packet */ + } vjcs_u; +}; +#define cs_ip vjcs_u.csu_ip +#define cs_hdr vjcs_u.csu_hdr + + +struct vjstat { + unsigned long vjs_packets; /* outbound packets */ + unsigned long vjs_compressed; /* outbound compressed packets */ + unsigned long vjs_searches; /* searches for connection state */ + unsigned long vjs_misses; /* times couldn't find conn. state */ + unsigned long vjs_uncompressedin; /* inbound uncompressed packets */ + unsigned long vjs_compressedin; /* inbound compressed packets */ + unsigned long vjs_errorin; /* inbound unknown type packets */ + unsigned long vjs_tossed; /* inbound packets tossed because of error */ +}; + +/* + * all the state data for one serial line (we need one of these per line). + */ +struct vjcompress { + struct cstate *last_cs; /* most recently used tstate */ + u_char last_recv; /* last rcvd conn. id */ + u_char last_xmit; /* last sent conn. id */ + u_short flags; + u_char maxSlotIndex; + u_char compressSlot; /* Flag indicating OK to compress slot ID. */ +#if LINK_STATS + struct vjstat stats; +#endif + struct cstate tstate[MAX_SLOTS]; /* xmit connection states */ + struct cstate rstate[MAX_SLOTS]; /* receive connection states */ +}; + +/* flag values */ +#define VJF_TOSS 1U /* tossing rcvd frames because of input err */ + +extern void vj_compress_init (struct vjcompress *comp); +extern u_int vj_compress_tcp (struct vjcompress *comp, struct pbuf *pb); +extern void vj_uncompress_err (struct vjcompress *comp); +extern int vj_uncompress_uncomp(struct pbuf *nb, struct vjcompress *comp); +extern int vj_uncompress_tcp (struct pbuf **nb, struct vjcompress *comp); + +#endif /* VJ_H */ diff --git a/src/lwip-1.4.1/src/netif/slipif.c b/src/lwip-1.4.1/src/netif/slipif.c new file mode 100644 index 0000000..2777630 --- /dev/null +++ b/src/lwip-1.4.1/src/netif/slipif.c @@ -0,0 +1,510 @@ +/** + * @file + * SLIP Interface + * + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE 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. + * + * This file is built upon the file: src/arch/rtxc/netif/sioslip.c + * + * Author: Magnus Ivarsson + * Simon Goldschmidt + * + * Usage: This netif can be used in three ways: + * 1) For NO_SYS==0, an RX thread can be used which blocks on sio_read() + * until data is received. + * 2) In your main loop, call slipif_poll() to check for new RX bytes, + * completed packets are fed into netif->input(). + * 3) Call slipif_received_byte[s]() from your serial RX ISR and + * slipif_process_rxqueue() from your main loop. ISR level decodes + * packets and puts completed packets on a queue which is fed into + * the stack from the main loop (needs SYS_LIGHTWEIGHT_PROT for + * pbuf_alloc to work on ISR level!). + * + */ + +/* + * This is an arch independent SLIP netif. The specific serial hooks must be + * provided by another file. They are sio_open, sio_read/sio_tryread and sio_send + */ + +#include "netif/slipif.h" +#include "lwip/opt.h" + +#if LWIP_HAVE_SLIPIF + +#include "lwip/def.h" +#include "lwip/pbuf.h" +#include "lwip/stats.h" +#include "lwip/snmp.h" +#include "lwip/sio.h" +#include "lwip/sys.h" + +#define SLIP_END 0xC0 /* 0300: start and end of every packet */ +#define SLIP_ESC 0xDB /* 0333: escape start (one byte escaped data follows) */ +#define SLIP_ESC_END 0xDC /* 0334: following escape: original byte is 0xC0 (END) */ +#define SLIP_ESC_ESC 0xDD /* 0335: following escape: original byte is 0xDB (ESC) */ + +/** Maximum packet size that is received by this netif */ +#ifndef SLIP_MAX_SIZE +#define SLIP_MAX_SIZE 1500 +#endif + +/** Define this to the interface speed for SNMP + * (sio_fd is the sio_fd_t returned by sio_open). + * The default value of zero means 'unknown'. + */ +#ifndef SLIP_SIO_SPEED +#define SLIP_SIO_SPEED(sio_fd) 0 +#endif + +enum slipif_recv_state { + SLIP_RECV_NORMAL, + SLIP_RECV_ESCAPE, +}; + +struct slipif_priv { + sio_fd_t sd; + /* q is the whole pbuf chain for a packet, p is the current pbuf in the chain */ + struct pbuf *p, *q; + u8_t state; + u16_t i, recved; +#if SLIP_RX_FROM_ISR + struct pbuf *rxpackets; +#endif +}; + +/** + * Send a pbuf doing the necessary SLIP encapsulation + * + * Uses the serial layer's sio_send() + * + * @param netif the lwip network interface structure for this slipif + * @param p the pbuf chaing packet to send + * @param ipaddr the ip address to send the packet to (not used for slipif) + * @return always returns ERR_OK since the serial layer does not provide return values + */ +err_t +slipif_output(struct netif *netif, struct pbuf *p, ip_addr_t *ipaddr) +{ + struct slipif_priv *priv; + struct pbuf *q; + u16_t i; + u8_t c; + + LWIP_ASSERT("netif != NULL", (netif != NULL)); + LWIP_ASSERT("netif->state != NULL", (netif->state != NULL)); + LWIP_ASSERT("p != NULL", (p != NULL)); + + LWIP_UNUSED_ARG(ipaddr); + + LWIP_DEBUGF(SLIP_DEBUG, ("slipif_output(%"U16_F"): sending %"U16_F" bytes\n", (u16_t)netif->num, p->tot_len)); + priv = netif->state; + + /* Send pbuf out on the serial I/O device. */ + /* Start with packet delimiter. */ + sio_send(SLIP_END, priv->sd); + + for (q = p; q != NULL; q = q->next) { + for (i = 0; i < q->len; i++) { + c = ((u8_t *)q->payload)[i]; + switch (c) { + case SLIP_END: + /* need to escape this byte (0xC0 -> 0xDB, 0xDC) */ + sio_send(SLIP_ESC, priv->sd); + sio_send(SLIP_ESC_END, priv->sd); + break; + case SLIP_ESC: + /* need to escape this byte (0xDB -> 0xDB, 0xDD) */ + sio_send(SLIP_ESC, priv->sd); + sio_send(SLIP_ESC_ESC, priv->sd); + break; + default: + /* normal byte - no need for escaping */ + sio_send(c, priv->sd); + break; + } + } + } + /* End with packet delimiter. */ + sio_send(SLIP_END, priv->sd); + return ERR_OK; +} + +/** + * Handle the incoming SLIP stream character by character + * + * @param netif the lwip network interface structure for this slipif + * @param c received character (multiple calls to this function will + * return a complete packet, NULL is returned before - used for polling) + * @return The IP packet when SLIP_END is received + */ +static struct pbuf* +slipif_rxbyte(struct netif *netif, u8_t c) +{ + struct slipif_priv *priv; + struct pbuf *t; + + LWIP_ASSERT("netif != NULL", (netif != NULL)); + LWIP_ASSERT("netif->state != NULL", (netif->state != NULL)); + + priv = netif->state; + + switch (priv->state) { + case SLIP_RECV_NORMAL: + switch (c) { + case SLIP_END: + if (priv->recved > 0) { + /* Received whole packet. */ + /* Trim the pbuf to the size of the received packet. */ + pbuf_realloc(priv->q, priv->recved); + + LINK_STATS_INC(link.recv); + + LWIP_DEBUGF(SLIP_DEBUG, ("slipif: Got packet (%"U16_F" bytes)\n", priv->recved)); + t = priv->q; + priv->p = priv->q = NULL; + priv->i = priv->recved = 0; + return t; + } + return NULL; + case SLIP_ESC: + priv->state = SLIP_RECV_ESCAPE; + return NULL; + } /* end switch (c) */ + break; + case SLIP_RECV_ESCAPE: + /* un-escape END or ESC bytes, leave other bytes + (although that would be a protocol error) */ + switch (c) { + case SLIP_ESC_END: + c = SLIP_END; + break; + case SLIP_ESC_ESC: + c = SLIP_ESC; + break; + } + priv->state = SLIP_RECV_NORMAL; + break; + } /* end switch (priv->state) */ + + /* byte received, packet not yet completely received */ + if (priv->p == NULL) { + /* allocate a new pbuf */ + LWIP_DEBUGF(SLIP_DEBUG, ("slipif_input: alloc\n")); + priv->p = pbuf_alloc(PBUF_LINK, (PBUF_POOL_BUFSIZE - PBUF_LINK_HLEN), PBUF_POOL); + + if (priv->p == NULL) { + LINK_STATS_INC(link.drop); + LWIP_DEBUGF(SLIP_DEBUG, ("slipif_input: no new pbuf! (DROP)\n")); + /* don't process any further since we got no pbuf to receive to */ + return NULL; + } + + if (priv->q != NULL) { + /* 'chain' the pbuf to the existing chain */ + pbuf_cat(priv->q, priv->p); + } else { + /* p is the first pbuf in the chain */ + priv->q = priv->p; + } + } + + /* this automatically drops bytes if > SLIP_MAX_SIZE */ + if ((priv->p != NULL) && (priv->recved <= SLIP_MAX_SIZE)) { + ((u8_t *)priv->p->payload)[priv->i] = c; + priv->recved++; + priv->i++; + if (priv->i >= priv->p->len) { + /* on to the next pbuf */ + priv->i = 0; + if (priv->p->next != NULL && priv->p->next->len > 0) { + /* p is a chain, on to the next in the chain */ + priv->p = priv->p->next; + } else { + /* p is a single pbuf, set it to NULL so next time a new + * pbuf is allocated */ + priv->p = NULL; + } + } + } + return NULL; +} + +/** Like slipif_rxbyte, but passes completed packets to netif->input + * + * @param netif The lwip network interface structure for this slipif + * @param data received character + */ +static void +slipif_rxbyte_input(struct netif *netif, u8_t c) +{ + struct pbuf *p; + p = slipif_rxbyte(netif, c); + if (p != NULL) { + if (netif->input(p, netif) != ERR_OK) { + pbuf_free(p); + } + } +} + +#if SLIP_USE_RX_THREAD +/** + * The SLIP input thread. + * + * Feed the IP layer with incoming packets + * + * @param nf the lwip network interface structure for this slipif + */ +static void +slipif_loop_thread(void *nf) +{ + u8_t c; + struct netif *netif = (struct netif *)nf; + struct slipif_priv *priv = (struct slipif_priv *)netif->state; + + while (1) { + if (sio_read(priv->sd, &c, 1) > 0) { + slipif_rxbyte_input(netif, c); + } + } +} +#endif /* SLIP_USE_RX_THREAD */ + +/** + * SLIP netif initialization + * + * Call the arch specific sio_open and remember + * the opened device in the state field of the netif. + * + * @param netif the lwip network interface structure for this slipif + * @return ERR_OK if serial line could be opened, + * ERR_MEM if no memory could be allocated, + * ERR_IF is serial line couldn't be opened + * + * @note netif->num must contain the number of the serial port to open + * (0 by default). If netif->state is != NULL, it is interpreted as an + * u8_t pointer pointing to the serial port number instead of netif->num. + * + */ +err_t +slipif_init(struct netif *netif) +{ + struct slipif_priv *priv; + u8_t sio_num; + + LWIP_DEBUGF(SLIP_DEBUG, ("slipif_init: netif->num=%"U16_F"\n", (u16_t)netif->num)); + + /* Allocate private data */ + priv = (struct slipif_priv *)mem_malloc(sizeof(struct slipif_priv)); + if (!priv) { + return ERR_MEM; + } + + netif->name[0] = 's'; + netif->name[1] = 'l'; + netif->output = slipif_output; + netif->mtu = SLIP_MAX_SIZE; + netif->flags |= NETIF_FLAG_POINTTOPOINT; + + /* netif->state or netif->num contain the port number */ + if (netif->state != NULL) { + sio_num = *(u8_t*)netif->state; + } else { + sio_num = netif->num; + } + /* Try to open the serial port. */ + priv->sd = sio_open(sio_num); + if (!priv->sd) { + /* Opening the serial port failed. */ + mem_free(priv); + return ERR_IF; + } + + /* Initialize private data */ + priv->p = NULL; + priv->q = NULL; + priv->state = SLIP_RECV_NORMAL; + priv->i = 0; + priv->recved = 0; +#if SLIP_RX_FROM_ISR + priv->rxpackets = NULL; +#endif + + netif->state = priv; + + /* initialize the snmp variables and counters inside the struct netif */ + NETIF_INIT_SNMP(netif, snmp_ifType_slip, SLIP_SIO_SPEED(priv->sd)); + +#if SLIP_USE_RX_THREAD + /* Create a thread to poll the serial line. */ + sys_thread_new(SLIPIF_THREAD_NAME, slipif_loop_thread, netif, + SLIPIF_THREAD_STACKSIZE, SLIPIF_THREAD_PRIO); +#endif /* SLIP_USE_RX_THREAD */ + return ERR_OK; +} + +/** + * Polls the serial device and feeds the IP layer with incoming packets. + * + * @param netif The lwip network interface structure for this slipif + */ +void +slipif_poll(struct netif *netif) +{ + u8_t c; + struct slipif_priv *priv; + + LWIP_ASSERT("netif != NULL", (netif != NULL)); + LWIP_ASSERT("netif->state != NULL", (netif->state != NULL)); + + priv = (struct slipif_priv *)netif->state; + + while (sio_tryread(priv->sd, &c, 1) > 0) { + slipif_rxbyte_input(netif, c); + } +} + +#if SLIP_RX_FROM_ISR +/** + * Feeds the IP layer with incoming packets that were receive + * + * @param netif The lwip network interface structure for this slipif + */ +void +slipif_process_rxqueue(struct netif *netif) +{ + struct slipif_priv *priv; + SYS_ARCH_DECL_PROTECT(old_level); + + LWIP_ASSERT("netif != NULL", (netif != NULL)); + LWIP_ASSERT("netif->state != NULL", (netif->state != NULL)); + + priv = (struct slipif_priv *)netif->state; + + SYS_ARCH_PROTECT(old_level); + while (priv->rxpackets != NULL) { + struct pbuf *p = priv->rxpackets; +#if SLIP_RX_QUEUE + /* dequeue packet */ + struct pbuf *q = p; + while ((q->len != q->tot_len) && (q->next != NULL)) { + q = q->next; + } + priv->rxpackets = q->next; + q->next = NULL; +#else /* SLIP_RX_QUEUE */ + priv->rxpackets = NULL; +#endif /* SLIP_RX_QUEUE */ + SYS_ARCH_UNPROTECT(old_level); + if (netif->input(p, netif) != ERR_OK) { + pbuf_free(p); + } + SYS_ARCH_PROTECT(old_level); + } +} + +/** Like slipif_rxbyte, but queues completed packets. + * + * @param netif The lwip network interface structure for this slipif + * @param data Received serial byte + */ +static void +slipif_rxbyte_enqueue(struct netif *netif, u8_t data) +{ + struct pbuf *p; + struct slipif_priv *priv = (struct slipif_priv *)netif->state; + SYS_ARCH_DECL_PROTECT(old_level); + + p = slipif_rxbyte(netif, data); + if (p != NULL) { + SYS_ARCH_PROTECT(old_level); + if (priv->rxpackets != NULL) { +#if SLIP_RX_QUEUE + /* queue multiple pbufs */ + struct pbuf *q = p; + while(q->next != NULL) { + q = q->next; + } + q->next = p; + } else { +#else /* SLIP_RX_QUEUE */ + pbuf_free(priv->rxpackets); + } + { +#endif /* SLIP_RX_QUEUE */ + priv->rxpackets = p; + } + SYS_ARCH_UNPROTECT(old_level); + } +} + +/** + * Process a received byte, completed packets are put on a queue that is + * fed into IP through slipif_process_rxqueue(). + * + * This function can be called from ISR if SYS_LIGHTWEIGHT_PROT is enabled. + * + * @param netif The lwip network interface structure for this slipif + * @param data received character + */ +void +slipif_received_byte(struct netif *netif, u8_t data) +{ + LWIP_ASSERT("netif != NULL", (netif != NULL)); + LWIP_ASSERT("netif->state != NULL", (netif->state != NULL)); + slipif_rxbyte_enqueue(netif, data); +} + +/** + * Process multiple received byte, completed packets are put on a queue that is + * fed into IP through slipif_process_rxqueue(). + * + * This function can be called from ISR if SYS_LIGHTWEIGHT_PROT is enabled. + * + * @param netif The lwip network interface structure for this slipif + * @param data received character + * @param len Number of received characters + */ +void +slipif_received_bytes(struct netif *netif, u8_t *data, u8_t len) +{ + u8_t i; + u8_t *rxdata = data; + LWIP_ASSERT("netif != NULL", (netif != NULL)); + LWIP_ASSERT("netif->state != NULL", (netif->state != NULL)); + + for (i = 0; i < len; i++, rxdata++) { + slipif_rxbyte_enqueue(netif, *rxdata); + } +} +#endif /* SLIP_RX_FROM_ISR */ + +#endif /* LWIP_HAVE_SLIPIF */ diff --git a/src/lwip-1.4.1/test/unit/core/test_mem.c b/src/lwip-1.4.1/test/unit/core/test_mem.c new file mode 100644 index 0000000..d3a5d54 --- /dev/null +++ b/src/lwip-1.4.1/test/unit/core/test_mem.c @@ -0,0 +1,73 @@ +#include "test_mem.h" + +#include "lwip/mem.h" +#include "lwip/stats.h" + +#if !LWIP_STATS || !MEM_STATS +#error "This tests needs MEM-statistics enabled" +#endif +#if LWIP_DNS +#error "This test needs DNS turned off (as it mallocs on init)" +#endif + +/* Setups/teardown functions */ + +static void +mem_setup(void) +{ +} + +static void +mem_teardown(void) +{ +} + + +/* Test functions */ + +/** Call mem_malloc, mem_free and mem_trim and check stats */ +START_TEST(test_mem_one) +{ +#define SIZE1 16 +#define SIZE1_2 12 +#define SIZE2 16 + void *p1, *p2; + mem_size_t s1, s2; + LWIP_UNUSED_ARG(_i); + +#if LWIP_DNS + fail("This test needs DNS turned off (as it mallocs on init)"); +#endif + + fail_unless(lwip_stats.mem.used == 0); + + p1 = mem_malloc(SIZE1); + fail_unless(p1 != NULL); + fail_unless(lwip_stats.mem.used >= SIZE1); + s1 = lwip_stats.mem.used; + + p2 = mem_malloc(SIZE2); + fail_unless(p2 != NULL); + fail_unless(lwip_stats.mem.used >= SIZE2 + s1); + s2 = lwip_stats.mem.used; + + mem_trim(p1, SIZE1_2); + + mem_free(p2); + fail_unless(lwip_stats.mem.used <= s2 - SIZE2); + + mem_free(p1); + fail_unless(lwip_stats.mem.used == 0); +} +END_TEST + + +/** Create the suite including all tests for this module */ +Suite * +mem_suite(void) +{ + TFun tests[] = { + test_mem_one + }; + return create_suite("MEM", tests, sizeof(tests)/sizeof(TFun), mem_setup, mem_teardown); +} diff --git a/src/lwip-1.4.1/test/unit/core/test_mem.h b/src/lwip-1.4.1/test/unit/core/test_mem.h new file mode 100644 index 0000000..13803ed --- /dev/null +++ b/src/lwip-1.4.1/test/unit/core/test_mem.h @@ -0,0 +1,8 @@ +#ifndef __TEST_MEM_H__ +#define __TEST_MEM_H__ + +#include "../lwip_check.h" + +Suite *mem_suite(void); + +#endif diff --git a/src/lwip-1.4.1/test/unit/etharp/test_etharp.c b/src/lwip-1.4.1/test/unit/etharp/test_etharp.c new file mode 100644 index 0000000..cbbc950 --- /dev/null +++ b/src/lwip-1.4.1/test/unit/etharp/test_etharp.c @@ -0,0 +1,262 @@ +#include "test_etharp.h" + +#include "lwip/udp.h" +#include "netif/etharp.h" +#include "lwip/stats.h" + +#if !LWIP_STATS || !UDP_STATS || !MEMP_STATS || !ETHARP_STATS +#error "This tests needs UDP-, MEMP- and ETHARP-statistics enabled" +#endif +#if !ETHARP_SUPPORT_STATIC_ENTRIES +#error "This test needs ETHARP_SUPPORT_STATIC_ENTRIES enabled" +#endif + +static struct netif test_netif; +static ip_addr_t test_ipaddr, test_netmask, test_gw; +struct eth_addr test_ethaddr = {1,1,1,1,1,1}; +struct eth_addr test_ethaddr2 = {1,1,1,1,1,2}; +struct eth_addr test_ethaddr3 = {1,1,1,1,1,3}; +struct eth_addr test_ethaddr4 = {1,1,1,1,1,4}; +static int linkoutput_ctr; + +/* Helper functions */ +static void +etharp_remove_all(void) +{ + int i; + /* call etharp_tmr often enough to have all entries cleaned */ + for(i = 0; i < 0xff; i++) { + etharp_tmr(); + } +} + +static err_t +default_netif_linkoutput(struct netif *netif, struct pbuf *p) +{ + fail_unless(netif == &test_netif); + fail_unless(p != NULL); + linkoutput_ctr++; + return ERR_OK; +} + +static err_t +default_netif_init(struct netif *netif) +{ + fail_unless(netif != NULL); + netif->linkoutput = default_netif_linkoutput; + netif->output = etharp_output; + netif->mtu = 1500; + netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP; + netif->hwaddr_len = ETHARP_HWADDR_LEN; + return ERR_OK; +} + +static void +default_netif_add(void) +{ + IP4_ADDR(&test_gw, 192,168,0,1); + IP4_ADDR(&test_ipaddr, 192,168,0,1); + IP4_ADDR(&test_netmask, 255,255,0,0); + + fail_unless(netif_default == NULL); + netif_set_default(netif_add(&test_netif, &test_ipaddr, &test_netmask, + &test_gw, NULL, default_netif_init, NULL)); + netif_set_up(&test_netif); +} + +static void +default_netif_remove(void) +{ + fail_unless(netif_default == &test_netif); + netif_remove(&test_netif); +} + +static void +create_arp_response(ip_addr_t *adr) +{ + int k; + struct eth_hdr *ethhdr; + struct etharp_hdr *etharphdr; + struct pbuf *p = pbuf_alloc(PBUF_RAW, sizeof(struct eth_hdr) + sizeof(struct etharp_hdr), PBUF_RAM); + if(p == NULL) { + FAIL_RET(); + } + ethhdr = (struct eth_hdr*)p->payload; + etharphdr = (struct etharp_hdr*)(ethhdr + 1); + + ethhdr->dest = test_ethaddr; + ethhdr->src = test_ethaddr2; + ethhdr->type = htons(ETHTYPE_ARP); + + etharphdr->hwtype = htons(/*HWTYPE_ETHERNET*/ 1); + etharphdr->proto = htons(ETHTYPE_IP); + etharphdr->hwlen = ETHARP_HWADDR_LEN; + etharphdr->protolen = sizeof(ip_addr_t); + etharphdr->opcode = htons(ARP_REPLY); + + SMEMCPY(ðarphdr->sipaddr, adr, sizeof(ip_addr_t)); + SMEMCPY(ðarphdr->dipaddr, &test_ipaddr, sizeof(ip_addr_t)); + + k = 6; + while(k > 0) { + k--; + /* Write the ARP MAC-Addresses */ + etharphdr->shwaddr.addr[k] = test_ethaddr2.addr[k]; + etharphdr->dhwaddr.addr[k] = test_ethaddr.addr[k]; + /* Write the Ethernet MAC-Addresses */ + ethhdr->dest.addr[k] = test_ethaddr.addr[k]; + ethhdr->src.addr[k] = test_ethaddr2.addr[k]; + } + + ethernet_input(p, &test_netif); +} + +/* Setups/teardown functions */ + +static void +etharp_setup(void) +{ + etharp_remove_all(); + default_netif_add(); +} + +static void +etharp_teardown(void) +{ + etharp_remove_all(); + default_netif_remove(); +} + + +/* Test functions */ + +START_TEST(test_etharp_table) +{ +#if ETHARP_SUPPORT_STATIC_ENTRIES + err_t err; +#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */ + s8_t idx; + ip_addr_t *unused_ipaddr; + struct eth_addr *unused_ethaddr; + struct udp_pcb* pcb; + LWIP_UNUSED_ARG(_i); + + if (netif_default != &test_netif) { + fail("This test needs a default netif"); + } + + linkoutput_ctr = 0; + + pcb = udp_new(); + fail_unless(pcb != NULL); + if (pcb != NULL) { + ip_addr_t adrs[ARP_TABLE_SIZE + 2]; + int i; + for(i = 0; i < ARP_TABLE_SIZE + 2; i++) { + IP4_ADDR(&adrs[i], 192,168,0,i+2); + } + /* fill ARP-table with dynamic entries */ + for(i = 0; i < ARP_TABLE_SIZE; i++) { + struct pbuf *p = pbuf_alloc(PBUF_TRANSPORT, 10, PBUF_RAM); + fail_unless(p != NULL); + if (p != NULL) { + err_t err = udp_sendto(pcb, p, &adrs[i], 123); + fail_unless(err == ERR_OK); + /* etharp request sent? */ + fail_unless(linkoutput_ctr == (2*i) + 1); + pbuf_free(p); + + /* create an ARP response */ + create_arp_response(&adrs[i]); + /* queued UDP packet sent? */ + fail_unless(linkoutput_ctr == (2*i) + 2); + + idx = etharp_find_addr(NULL, &adrs[i], &unused_ethaddr, &unused_ipaddr); + fail_unless(idx == i); + etharp_tmr(); + } + } + linkoutput_ctr = 0; +#if ETHARP_SUPPORT_STATIC_ENTRIES + /* create one static entry */ + err = etharp_add_static_entry(&adrs[ARP_TABLE_SIZE], &test_ethaddr3); + fail_unless(err == ERR_OK); + idx = etharp_find_addr(NULL, &adrs[ARP_TABLE_SIZE], &unused_ethaddr, &unused_ipaddr); + fail_unless(idx == 0); + fail_unless(linkoutput_ctr == 0); +#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */ + + linkoutput_ctr = 0; + /* fill ARP-table with dynamic entries */ + for(i = 0; i < ARP_TABLE_SIZE; i++) { + struct pbuf *p = pbuf_alloc(PBUF_TRANSPORT, 10, PBUF_RAM); + fail_unless(p != NULL); + if (p != NULL) { + err_t err = udp_sendto(pcb, p, &adrs[i], 123); + fail_unless(err == ERR_OK); + /* etharp request sent? */ + fail_unless(linkoutput_ctr == (2*i) + 1); + pbuf_free(p); + + /* create an ARP response */ + create_arp_response(&adrs[i]); + /* queued UDP packet sent? */ + fail_unless(linkoutput_ctr == (2*i) + 2); + + idx = etharp_find_addr(NULL, &adrs[i], &unused_ethaddr, &unused_ipaddr); + if (i < ARP_TABLE_SIZE - 1) { + fail_unless(idx == i+1); + } else { + /* the last entry must not overwrite the static entry! */ + fail_unless(idx == 1); + } + etharp_tmr(); + } + } +#if ETHARP_SUPPORT_STATIC_ENTRIES + /* create a second static entry */ + err = etharp_add_static_entry(&adrs[ARP_TABLE_SIZE+1], &test_ethaddr4); + fail_unless(err == ERR_OK); + idx = etharp_find_addr(NULL, &adrs[ARP_TABLE_SIZE], &unused_ethaddr, &unused_ipaddr); + fail_unless(idx == 0); + idx = etharp_find_addr(NULL, &adrs[ARP_TABLE_SIZE+1], &unused_ethaddr, &unused_ipaddr); + fail_unless(idx == 2); + /* and remove it again */ + err = etharp_remove_static_entry(&adrs[ARP_TABLE_SIZE+1]); + fail_unless(err == ERR_OK); + idx = etharp_find_addr(NULL, &adrs[ARP_TABLE_SIZE], &unused_ethaddr, &unused_ipaddr); + fail_unless(idx == 0); + idx = etharp_find_addr(NULL, &adrs[ARP_TABLE_SIZE+1], &unused_ethaddr, &unused_ipaddr); + fail_unless(idx == -1); +#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */ + + /* check that static entries don't time out */ + etharp_remove_all(); + idx = etharp_find_addr(NULL, &adrs[ARP_TABLE_SIZE], &unused_ethaddr, &unused_ipaddr); + fail_unless(idx == 0); + +#if ETHARP_SUPPORT_STATIC_ENTRIES + /* remove the first static entry */ + err = etharp_remove_static_entry(&adrs[ARP_TABLE_SIZE]); + fail_unless(err == ERR_OK); + idx = etharp_find_addr(NULL, &adrs[ARP_TABLE_SIZE], &unused_ethaddr, &unused_ipaddr); + fail_unless(idx == -1); + idx = etharp_find_addr(NULL, &adrs[ARP_TABLE_SIZE+1], &unused_ethaddr, &unused_ipaddr); + fail_unless(idx == -1); +#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */ + + udp_remove(pcb); + } +} +END_TEST + + +/** Create the suite including all tests for this module */ +Suite * +etharp_suite(void) +{ + TFun tests[] = { + test_etharp_table + }; + return create_suite("ETHARP", tests, sizeof(tests)/sizeof(TFun), etharp_setup, etharp_teardown); +} diff --git a/src/lwip-1.4.1/test/unit/etharp/test_etharp.h b/src/lwip-1.4.1/test/unit/etharp/test_etharp.h new file mode 100644 index 0000000..96e00c3 --- /dev/null +++ b/src/lwip-1.4.1/test/unit/etharp/test_etharp.h @@ -0,0 +1,8 @@ +#ifndef __TEST_ETHARP_H__ +#define __TEST_ETHARP_H__ + +#include "../lwip_check.h" + +Suite* etharp_suite(void); + +#endif diff --git a/src/lwip-1.4.1/test/unit/lwip_check.h b/src/lwip-1.4.1/test/unit/lwip_check.h new file mode 100644 index 0000000..e27f55a --- /dev/null +++ b/src/lwip-1.4.1/test/unit/lwip_check.h @@ -0,0 +1,37 @@ +#ifndef __LWIP_CHECK_H__ +#define __LWIP_CHECK_H__ + +/* Common header file for lwIP unit tests using the check framework */ + +#include +#include +#include + +#define FAIL_RET() do { fail(); return; } while(0) +#define EXPECT(x) fail_unless(x) +#define EXPECT_RET(x) do { fail_unless(x); if(!(x)) { return; }} while(0) +#define EXPECT_RETX(x, y) do { fail_unless(x); if(!(x)) { return y; }} while(0) +#define EXPECT_RETNULL(x) EXPECT_RETX(x, NULL) + +/** typedef for a function returning a test suite */ +typedef Suite* (suite_getter_fn)(void); + +/** Create a test suite */ +static Suite* create_suite(const char* name, TFun *tests, size_t num_tests, SFun setup, SFun teardown) +{ + size_t i; + Suite *s = suite_create(name); + + for(i = 0; i < num_tests; i++) { + /* Core test case */ + TCase *tc_core = tcase_create("Core"); + if ((setup != NULL) || (teardown != NULL)) { + tcase_add_checked_fixture(tc_core, setup, teardown); + } + tcase_add_test(tc_core, tests[i]); + suite_add_tcase(s, tc_core); + } + return s; +} + +#endif /* __LWIP_CHECK_H__ */ diff --git a/src/lwip-1.4.1/test/unit/lwip_unittests.c b/src/lwip-1.4.1/test/unit/lwip_unittests.c new file mode 100644 index 0000000..4f537e6 --- /dev/null +++ b/src/lwip-1.4.1/test/unit/lwip_unittests.c @@ -0,0 +1,45 @@ +#include "lwip_check.h" + +#include "udp/test_udp.h" +#include "tcp/test_tcp.h" +#include "tcp/test_tcp_oos.h" +#include "core/test_mem.h" +#include "etharp/test_etharp.h" + +#include "lwip/init.h" + + +int main() +{ + int number_failed; + SRunner *sr; + size_t i; + suite_getter_fn* suites[] = { + udp_suite, + tcp_suite, + tcp_oos_suite, + mem_suite, + etharp_suite + }; + size_t num = sizeof(suites)/sizeof(void*); + LWIP_ASSERT("No suites defined", num > 0); + + lwip_init(); + + sr = srunner_create((suites[0])()); + for(i = 1; i < num; i++) { + srunner_add_suite(sr, ((suite_getter_fn*)suites[i])()); + } + +#ifdef LWIP_UNITTESTS_NOFORK + srunner_set_fork_status(sr, CK_NOFORK); +#endif +#ifdef LWIP_UNITTESTS_FORK + srunner_set_fork_status(sr, CK_FORK); +#endif + + srunner_run_all(sr, CK_NORMAL); + number_failed = srunner_ntests_failed(sr); + srunner_free(sr); + return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE; +} diff --git a/src/lwip-1.4.1/test/unit/lwipopts.h b/src/lwip-1.4.1/test/unit/lwipopts.h new file mode 100644 index 0000000..88e76d7 --- /dev/null +++ b/src/lwip-1.4.1/test/unit/lwipopts.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2001-2003 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Simon Goldschmidt + * + */ +#ifndef __LWIPOPTS_H__ +#define __LWIPOPTS_H__ + +/* Prevent having to link sys_arch.c (we don't test the API layers in unit tests) */ +#define NO_SYS 1 +#define LWIP_NETCONN 0 +#define LWIP_SOCKET 0 + +/* Minimal changes to opt.h required for tcp unit tests: */ +#define MEM_SIZE 16000 +#define TCP_SND_QUEUELEN 40 +#define MEMP_NUM_TCP_SEG TCP_SND_QUEUELEN +#define TCP_SND_BUF (12 * TCP_MSS) +#define TCP_WND (10 * TCP_MSS) + +/* Minimal changes to opt.h required for etharp unit tests: */ +#define ETHARP_SUPPORT_STATIC_ENTRIES 1 + +#endif /* __LWIPOPTS_H__ */ diff --git a/src/lwip-1.4.1/test/unit/tcp/tcp_helper.c b/src/lwip-1.4.1/test/unit/tcp/tcp_helper.c new file mode 100644 index 0000000..dd550f1 --- /dev/null +++ b/src/lwip-1.4.1/test/unit/tcp/tcp_helper.c @@ -0,0 +1,294 @@ +#include "tcp_helper.h" + +#include "lwip/tcp_impl.h" +#include "lwip/stats.h" +#include "lwip/pbuf.h" +#include "lwip/inet_chksum.h" + +#if !LWIP_STATS || !TCP_STATS || !MEMP_STATS +#error "This tests needs TCP- and MEMP-statistics enabled" +#endif + +/** Remove all pcbs on the given list. */ +static void +tcp_remove(struct tcp_pcb* pcb_list) +{ + struct tcp_pcb *pcb = pcb_list; + struct tcp_pcb *pcb2; + + while(pcb != NULL) { + pcb2 = pcb; + pcb = pcb->next; + tcp_abort(pcb2); + } +} + +/** Remove all pcbs on listen-, active- and time-wait-list (bound- isn't exported). */ +void +tcp_remove_all(void) +{ + tcp_remove(tcp_listen_pcbs.pcbs); + tcp_remove(tcp_active_pcbs); + tcp_remove(tcp_tw_pcbs); + fail_unless(lwip_stats.memp[MEMP_TCP_PCB].used == 0); + fail_unless(lwip_stats.memp[MEMP_TCP_PCB_LISTEN].used == 0); + fail_unless(lwip_stats.memp[MEMP_TCP_SEG].used == 0); + fail_unless(lwip_stats.memp[MEMP_PBUF_POOL].used == 0); +} + +/** Create a TCP segment usable for passing to tcp_input */ +static struct pbuf* +tcp_create_segment_wnd(ip_addr_t* src_ip, ip_addr_t* dst_ip, + u16_t src_port, u16_t dst_port, void* data, size_t data_len, + u32_t seqno, u32_t ackno, u8_t headerflags, u16_t wnd) +{ + struct pbuf *p, *q; + struct ip_hdr* iphdr; + struct tcp_hdr* tcphdr; + u16_t pbuf_len = (u16_t)(sizeof(struct ip_hdr) + sizeof(struct tcp_hdr) + data_len); + + p = pbuf_alloc(PBUF_RAW, pbuf_len, PBUF_POOL); + EXPECT_RETNULL(p != NULL); + /* first pbuf must be big enough to hold the headers */ + EXPECT_RETNULL(p->len >= (sizeof(struct ip_hdr) + sizeof(struct tcp_hdr))); + if (data_len > 0) { + /* first pbuf must be big enough to hold at least 1 data byte, too */ + EXPECT_RETNULL(p->len > (sizeof(struct ip_hdr) + sizeof(struct tcp_hdr))); + } + + for(q = p; q != NULL; q = q->next) { + memset(q->payload, 0, q->len); + } + + iphdr = p->payload; + /* fill IP header */ + iphdr->dest.addr = dst_ip->addr; + iphdr->src.addr = src_ip->addr; + IPH_VHL_SET(iphdr, 4, IP_HLEN / 4); + IPH_TOS_SET(iphdr, 0); + IPH_LEN_SET(iphdr, htons(p->tot_len)); + IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, IP_HLEN)); + + /* let p point to TCP header */ + pbuf_header(p, -(s16_t)sizeof(struct ip_hdr)); + + tcphdr = p->payload; + tcphdr->src = htons(src_port); + tcphdr->dest = htons(dst_port); + tcphdr->seqno = htonl(seqno); + tcphdr->ackno = htonl(ackno); + TCPH_HDRLEN_SET(tcphdr, sizeof(struct tcp_hdr)/4); + TCPH_FLAGS_SET(tcphdr, headerflags); + tcphdr->wnd = htons(wnd); + + if (data_len > 0) { + /* let p point to TCP data */ + pbuf_header(p, -(s16_t)sizeof(struct tcp_hdr)); + /* copy data */ + pbuf_take(p, data, data_len); + /* let p point to TCP header again */ + pbuf_header(p, sizeof(struct tcp_hdr)); + } + + /* calculate checksum */ + + tcphdr->chksum = inet_chksum_pseudo(p, src_ip, dst_ip, + IP_PROTO_TCP, p->tot_len); + + pbuf_header(p, sizeof(struct ip_hdr)); + + return p; +} + +/** Create a TCP segment usable for passing to tcp_input */ +struct pbuf* +tcp_create_segment(ip_addr_t* src_ip, ip_addr_t* dst_ip, + u16_t src_port, u16_t dst_port, void* data, size_t data_len, + u32_t seqno, u32_t ackno, u8_t headerflags) +{ + return tcp_create_segment_wnd(src_ip, dst_ip, src_port, dst_port, data, + data_len, seqno, ackno, headerflags, TCP_WND); +} + +/** Create a TCP segment usable for passing to tcp_input + * - IP-addresses, ports, seqno and ackno are taken from pcb + * - seqno and ackno can be altered with an offset + */ +struct pbuf* +tcp_create_rx_segment(struct tcp_pcb* pcb, void* data, size_t data_len, u32_t seqno_offset, + u32_t ackno_offset, u8_t headerflags) +{ + return tcp_create_segment(&pcb->remote_ip, &pcb->local_ip, pcb->remote_port, pcb->local_port, + data, data_len, pcb->rcv_nxt + seqno_offset, pcb->lastack + ackno_offset, headerflags); +} + +/** Create a TCP segment usable for passing to tcp_input + * - IP-addresses, ports, seqno and ackno are taken from pcb + * - seqno and ackno can be altered with an offset + * - TCP window can be adjusted + */ +struct pbuf* tcp_create_rx_segment_wnd(struct tcp_pcb* pcb, void* data, size_t data_len, + u32_t seqno_offset, u32_t ackno_offset, u8_t headerflags, u16_t wnd) +{ + return tcp_create_segment_wnd(&pcb->remote_ip, &pcb->local_ip, pcb->remote_port, pcb->local_port, + data, data_len, pcb->rcv_nxt + seqno_offset, pcb->lastack + ackno_offset, headerflags, wnd); +} + +/** Safely bring a tcp_pcb into the requested state */ +void +tcp_set_state(struct tcp_pcb* pcb, enum tcp_state state, ip_addr_t* local_ip, + ip_addr_t* remote_ip, u16_t local_port, u16_t remote_port) +{ + /* @todo: are these all states? */ + /* @todo: remove from previous list */ + pcb->state = state; + if (state == ESTABLISHED) { + TCP_REG(&tcp_active_pcbs, pcb); + pcb->local_ip.addr = local_ip->addr; + pcb->local_port = local_port; + pcb->remote_ip.addr = remote_ip->addr; + pcb->remote_port = remote_port; + } else if(state == LISTEN) { + TCP_REG(&tcp_listen_pcbs.pcbs, pcb); + pcb->local_ip.addr = local_ip->addr; + pcb->local_port = local_port; + } else if(state == TIME_WAIT) { + TCP_REG(&tcp_tw_pcbs, pcb); + pcb->local_ip.addr = local_ip->addr; + pcb->local_port = local_port; + pcb->remote_ip.addr = remote_ip->addr; + pcb->remote_port = remote_port; + } else { + fail(); + } +} + +void +test_tcp_counters_err(void* arg, err_t err) +{ + struct test_tcp_counters* counters = arg; + EXPECT_RET(arg != NULL); + counters->err_calls++; + counters->last_err = err; +} + +static void +test_tcp_counters_check_rxdata(struct test_tcp_counters* counters, struct pbuf* p) +{ + struct pbuf* q; + u32_t i, received; + if(counters->expected_data == NULL) { + /* no data to compare */ + return; + } + EXPECT_RET(counters->recved_bytes + p->tot_len <= counters->expected_data_len); + received = counters->recved_bytes; + for(q = p; q != NULL; q = q->next) { + char *data = q->payload; + for(i = 0; i < q->len; i++) { + EXPECT_RET(data[i] == counters->expected_data[received]); + received++; + } + } + EXPECT(received == counters->recved_bytes + p->tot_len); +} + +err_t +test_tcp_counters_recv(void* arg, struct tcp_pcb* pcb, struct pbuf* p, err_t err) +{ + struct test_tcp_counters* counters = arg; + EXPECT_RETX(arg != NULL, ERR_OK); + EXPECT_RETX(pcb != NULL, ERR_OK); + EXPECT_RETX(err == ERR_OK, ERR_OK); + + if (p != NULL) { + if (counters->close_calls == 0) { + counters->recv_calls++; + test_tcp_counters_check_rxdata(counters, p); + counters->recved_bytes += p->tot_len; + } else { + counters->recv_calls_after_close++; + counters->recved_bytes_after_close += p->tot_len; + } + pbuf_free(p); + } else { + counters->close_calls++; + } + EXPECT(counters->recv_calls_after_close == 0 && counters->recved_bytes_after_close == 0); + return ERR_OK; +} + +/** Allocate a pcb and set up the test_tcp_counters_* callbacks */ +struct tcp_pcb* +test_tcp_new_counters_pcb(struct test_tcp_counters* counters) +{ + struct tcp_pcb* pcb = tcp_new(); + if (pcb != NULL) { + /* set up args and callbacks */ + tcp_arg(pcb, counters); + tcp_recv(pcb, test_tcp_counters_recv); + tcp_err(pcb, test_tcp_counters_err); + pcb->snd_wnd = TCP_WND; + pcb->snd_wnd_max = TCP_WND; + } + return pcb; +} + +/** Calls tcp_input() after adjusting current_iphdr_dest */ +void test_tcp_input(struct pbuf *p, struct netif *inp) +{ + struct ip_hdr *iphdr = (struct ip_hdr*)p->payload; + ip_addr_copy(current_iphdr_dest, iphdr->dest); + ip_addr_copy(current_iphdr_src, iphdr->src); + current_netif = inp; + current_header = iphdr; + + tcp_input(p, inp); + + current_iphdr_dest.addr = 0; + current_iphdr_src.addr = 0; + current_netif = NULL; + current_header = NULL; +} + +static err_t test_tcp_netif_output(struct netif *netif, struct pbuf *p, + ip_addr_t *ipaddr) +{ + struct test_tcp_txcounters *txcounters = (struct test_tcp_txcounters*)netif->state; + LWIP_UNUSED_ARG(ipaddr); + txcounters->num_tx_calls++; + txcounters->num_tx_bytes += p->tot_len; + if (txcounters->copy_tx_packets) { + struct pbuf *p_copy = pbuf_alloc(PBUF_LINK, p->tot_len, PBUF_RAM); + err_t err; + EXPECT(p_copy != NULL); + err = pbuf_copy(p_copy, p); + EXPECT(err == ERR_OK); + if (txcounters->tx_packets == NULL) { + txcounters->tx_packets = p_copy; + } else { + pbuf_cat(txcounters->tx_packets, p_copy); + } + } + return ERR_OK; +} + +void test_tcp_init_netif(struct netif *netif, struct test_tcp_txcounters *txcounters, + ip_addr_t *ip_addr, ip_addr_t *netmask) +{ + struct netif *n; + memset(netif, 0, sizeof(struct netif)); + memset(txcounters, 0, sizeof(struct test_tcp_txcounters)); + netif->output = test_tcp_netif_output; + netif->state = txcounters; + netif->flags |= NETIF_FLAG_UP; + ip_addr_copy(netif->netmask, *netmask); + ip_addr_copy(netif->ip_addr, *ip_addr); + for (n = netif_list; n != NULL; n = n->next) { + if (n == netif) { + return; + } + } + netif->next = NULL; + netif_list = netif; +} diff --git a/src/lwip-1.4.1/test/unit/tcp/tcp_helper.h b/src/lwip-1.4.1/test/unit/tcp/tcp_helper.h new file mode 100644 index 0000000..4a72c93 --- /dev/null +++ b/src/lwip-1.4.1/test/unit/tcp/tcp_helper.h @@ -0,0 +1,52 @@ +#ifndef __TCP_HELPER_H__ +#define __TCP_HELPER_H__ + +#include "../lwip_check.h" +#include "lwip/arch.h" +#include "lwip/tcp.h" +#include "lwip/netif.h" + +/* counters used for test_tcp_counters_* callback functions */ +struct test_tcp_counters { + u32_t recv_calls; + u32_t recved_bytes; + u32_t recv_calls_after_close; + u32_t recved_bytes_after_close; + u32_t close_calls; + u32_t err_calls; + err_t last_err; + char* expected_data; + u32_t expected_data_len; +}; + +struct test_tcp_txcounters { + u32_t num_tx_calls; + u32_t num_tx_bytes; + u8_t copy_tx_packets; + struct pbuf *tx_packets; +}; + +/* Helper functions */ +void tcp_remove_all(void); + +struct pbuf* tcp_create_segment(ip_addr_t* src_ip, ip_addr_t* dst_ip, + u16_t src_port, u16_t dst_port, void* data, size_t data_len, + u32_t seqno, u32_t ackno, u8_t headerflags); +struct pbuf* tcp_create_rx_segment(struct tcp_pcb* pcb, void* data, size_t data_len, + u32_t seqno_offset, u32_t ackno_offset, u8_t headerflags); +struct pbuf* tcp_create_rx_segment_wnd(struct tcp_pcb* pcb, void* data, size_t data_len, + u32_t seqno_offset, u32_t ackno_offset, u8_t headerflags, u16_t wnd); +void tcp_set_state(struct tcp_pcb* pcb, enum tcp_state state, ip_addr_t* local_ip, + ip_addr_t* remote_ip, u16_t local_port, u16_t remote_port); +void test_tcp_counters_err(void* arg, err_t err); +err_t test_tcp_counters_recv(void* arg, struct tcp_pcb* pcb, struct pbuf* p, err_t err); + +struct tcp_pcb* test_tcp_new_counters_pcb(struct test_tcp_counters* counters); + +void test_tcp_input(struct pbuf *p, struct netif *inp); + +void test_tcp_init_netif(struct netif *netif, struct test_tcp_txcounters *txcounters, + ip_addr_t *ip_addr, ip_addr_t *netmask); + + +#endif diff --git a/src/lwip-1.4.1/test/unit/tcp/test_tcp.c b/src/lwip-1.4.1/test/unit/tcp/test_tcp.c new file mode 100644 index 0000000..6fd5be5 --- /dev/null +++ b/src/lwip-1.4.1/test/unit/tcp/test_tcp.c @@ -0,0 +1,667 @@ +#include "test_tcp.h" + +#include "lwip/tcp_impl.h" +#include "lwip/stats.h" +#include "tcp_helper.h" + +#ifdef _MSC_VER +#pragma warning(disable: 4307) /* we explicitly wrap around TCP seqnos */ +#endif + +#if !LWIP_STATS || !TCP_STATS || !MEMP_STATS +#error "This tests needs TCP- and MEMP-statistics enabled" +#endif +#if TCP_SND_BUF <= TCP_WND +#error "This tests needs TCP_SND_BUF to be > TCP_WND" +#endif + +static u8_t test_tcp_timer; + +/* our own version of tcp_tmr so we can reset fast/slow timer state */ +static void +test_tcp_tmr(void) +{ + tcp_fasttmr(); + if (++test_tcp_timer & 1) { + tcp_slowtmr(); + } +} + +/* Setups/teardown functions */ + +static void +tcp_setup(void) +{ + /* reset iss to default (6510) */ + tcp_ticks = 0; + tcp_ticks = 0 - (tcp_next_iss() - 6510); + tcp_next_iss(); + tcp_ticks = 0; + + test_tcp_timer = 0; + tcp_remove_all(); +} + +static void +tcp_teardown(void) +{ + netif_list = NULL; + tcp_remove_all(); +} + + +/* Test functions */ + +/** Call tcp_new() and tcp_abort() and test memp stats */ +START_TEST(test_tcp_new_abort) +{ + struct tcp_pcb* pcb; + LWIP_UNUSED_ARG(_i); + + fail_unless(lwip_stats.memp[MEMP_TCP_PCB].used == 0); + + pcb = tcp_new(); + fail_unless(pcb != NULL); + if (pcb != NULL) { + fail_unless(lwip_stats.memp[MEMP_TCP_PCB].used == 1); + tcp_abort(pcb); + fail_unless(lwip_stats.memp[MEMP_TCP_PCB].used == 0); + } +} +END_TEST + +/** Create an ESTABLISHED pcb and check if receive callback is called */ +START_TEST(test_tcp_recv_inseq) +{ + struct test_tcp_counters counters; + struct tcp_pcb* pcb; + struct pbuf* p; + char data[] = {1, 2, 3, 4}; + ip_addr_t remote_ip, local_ip; + u16_t data_len; + u16_t remote_port = 0x100, local_port = 0x101; + struct netif netif; + LWIP_UNUSED_ARG(_i); + + /* initialize local vars */ + memset(&netif, 0, sizeof(netif)); + IP4_ADDR(&local_ip, 192, 168, 1, 1); + IP4_ADDR(&remote_ip, 192, 168, 1, 2); + data_len = sizeof(data); + /* initialize counter struct */ + memset(&counters, 0, sizeof(counters)); + counters.expected_data_len = data_len; + counters.expected_data = data; + + /* create and initialize the pcb */ + pcb = test_tcp_new_counters_pcb(&counters); + EXPECT_RET(pcb != NULL); + tcp_set_state(pcb, ESTABLISHED, &local_ip, &remote_ip, local_port, remote_port); + + /* create a segment */ + p = tcp_create_rx_segment(pcb, counters.expected_data, data_len, 0, 0, 0); + EXPECT(p != NULL); + if (p != NULL) { + /* pass the segment to tcp_input */ + test_tcp_input(p, &netif); + /* check if counters are as expected */ + EXPECT(counters.close_calls == 0); + EXPECT(counters.recv_calls == 1); + EXPECT(counters.recved_bytes == data_len); + EXPECT(counters.err_calls == 0); + } + + /* make sure the pcb is freed */ + EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 1); + tcp_abort(pcb); + EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 0); +} +END_TEST + +/** Provoke fast retransmission by duplicate ACKs and then recover by ACKing all sent data. + * At the end, send more data. */ +START_TEST(test_tcp_fast_retx_recover) +{ + struct netif netif; + struct test_tcp_txcounters txcounters; + struct test_tcp_counters counters; + struct tcp_pcb* pcb; + struct pbuf* p; + char data1[] = { 1, 2, 3, 4}; + char data2[] = { 5, 6, 7, 8}; + char data3[] = { 9, 10, 11, 12}; + char data4[] = {13, 14, 15, 16}; + char data5[] = {17, 18, 19, 20}; + char data6[] = {21, 22, 23, 24}; + ip_addr_t remote_ip, local_ip, netmask; + u16_t remote_port = 0x100, local_port = 0x101; + err_t err; + LWIP_UNUSED_ARG(_i); + + /* initialize local vars */ + IP4_ADDR(&local_ip, 192, 168, 1, 1); + IP4_ADDR(&remote_ip, 192, 168, 1, 2); + IP4_ADDR(&netmask, 255, 255, 255, 0); + test_tcp_init_netif(&netif, &txcounters, &local_ip, &netmask); + memset(&counters, 0, sizeof(counters)); + + /* create and initialize the pcb */ + pcb = test_tcp_new_counters_pcb(&counters); + EXPECT_RET(pcb != NULL); + tcp_set_state(pcb, ESTABLISHED, &local_ip, &remote_ip, local_port, remote_port); + pcb->mss = TCP_MSS; + /* disable initial congestion window (we don't send a SYN here...) */ + pcb->cwnd = pcb->snd_wnd; + + /* send data1 */ + err = tcp_write(pcb, data1, sizeof(data1), TCP_WRITE_FLAG_COPY); + EXPECT_RET(err == ERR_OK); + err = tcp_output(pcb); + EXPECT_RET(err == ERR_OK); + EXPECT_RET(txcounters.num_tx_calls == 1); + EXPECT_RET(txcounters.num_tx_bytes == sizeof(data1) + sizeof(struct tcp_hdr) + sizeof(struct ip_hdr)); + memset(&txcounters, 0, sizeof(txcounters)); + /* "recv" ACK for data1 */ + p = tcp_create_rx_segment(pcb, NULL, 0, 0, 4, TCP_ACK); + EXPECT_RET(p != NULL); + test_tcp_input(p, &netif); + EXPECT_RET(txcounters.num_tx_calls == 0); + EXPECT_RET(pcb->unacked == NULL); + /* send data2 */ + err = tcp_write(pcb, data2, sizeof(data2), TCP_WRITE_FLAG_COPY); + EXPECT_RET(err == ERR_OK); + err = tcp_output(pcb); + EXPECT_RET(err == ERR_OK); + EXPECT_RET(txcounters.num_tx_calls == 1); + EXPECT_RET(txcounters.num_tx_bytes == sizeof(data2) + sizeof(struct tcp_hdr) + sizeof(struct ip_hdr)); + memset(&txcounters, 0, sizeof(txcounters)); + /* duplicate ACK for data1 (data2 is lost) */ + p = tcp_create_rx_segment(pcb, NULL, 0, 0, 0, TCP_ACK); + EXPECT_RET(p != NULL); + test_tcp_input(p, &netif); + EXPECT_RET(txcounters.num_tx_calls == 0); + EXPECT_RET(pcb->dupacks == 1); + /* send data3 */ + err = tcp_write(pcb, data3, sizeof(data3), TCP_WRITE_FLAG_COPY); + EXPECT_RET(err == ERR_OK); + err = tcp_output(pcb); + EXPECT_RET(err == ERR_OK); + /* nagle enabled, no tx calls */ + EXPECT_RET(txcounters.num_tx_calls == 0); + EXPECT_RET(txcounters.num_tx_bytes == 0); + memset(&txcounters, 0, sizeof(txcounters)); + /* 2nd duplicate ACK for data1 (data2 and data3 are lost) */ + p = tcp_create_rx_segment(pcb, NULL, 0, 0, 0, TCP_ACK); + EXPECT_RET(p != NULL); + test_tcp_input(p, &netif); + EXPECT_RET(txcounters.num_tx_calls == 0); + EXPECT_RET(pcb->dupacks == 2); + /* queue data4, don't send it (unsent-oversize is != 0) */ + err = tcp_write(pcb, data4, sizeof(data4), TCP_WRITE_FLAG_COPY); + EXPECT_RET(err == ERR_OK); + /* 3nd duplicate ACK for data1 (data2 and data3 are lost) -> fast retransmission */ + p = tcp_create_rx_segment(pcb, NULL, 0, 0, 0, TCP_ACK); + EXPECT_RET(p != NULL); + test_tcp_input(p, &netif); + /*EXPECT_RET(txcounters.num_tx_calls == 1);*/ + EXPECT_RET(pcb->dupacks == 3); + memset(&txcounters, 0, sizeof(txcounters)); + /* TODO: check expected data?*/ + + /* send data5, not output yet */ + err = tcp_write(pcb, data5, sizeof(data5), TCP_WRITE_FLAG_COPY); + EXPECT_RET(err == ERR_OK); + /*err = tcp_output(pcb); + EXPECT_RET(err == ERR_OK);*/ + EXPECT_RET(txcounters.num_tx_calls == 0); + EXPECT_RET(txcounters.num_tx_bytes == 0); + memset(&txcounters, 0, sizeof(txcounters)); + { + int i = 0; + do + { + err = tcp_write(pcb, data6, TCP_MSS, TCP_WRITE_FLAG_COPY); + i++; + }while(err == ERR_OK); + EXPECT_RET(err != ERR_OK); + } + err = tcp_output(pcb); + EXPECT_RET(err == ERR_OK); + /*EXPECT_RET(txcounters.num_tx_calls == 0); + EXPECT_RET(txcounters.num_tx_bytes == 0);*/ + memset(&txcounters, 0, sizeof(txcounters)); + + /* send even more data */ + err = tcp_write(pcb, data5, sizeof(data5), TCP_WRITE_FLAG_COPY); + EXPECT_RET(err == ERR_OK); + err = tcp_output(pcb); + EXPECT_RET(err == ERR_OK); + /* ...and even more data */ + err = tcp_write(pcb, data5, sizeof(data5), TCP_WRITE_FLAG_COPY); + EXPECT_RET(err == ERR_OK); + err = tcp_output(pcb); + EXPECT_RET(err == ERR_OK); + /* ...and even more data */ + err = tcp_write(pcb, data5, sizeof(data5), TCP_WRITE_FLAG_COPY); + EXPECT_RET(err == ERR_OK); + err = tcp_output(pcb); + EXPECT_RET(err == ERR_OK); + /* ...and even more data */ + err = tcp_write(pcb, data5, sizeof(data5), TCP_WRITE_FLAG_COPY); + EXPECT_RET(err == ERR_OK); + err = tcp_output(pcb); + EXPECT_RET(err == ERR_OK); + + /* send ACKs for data2 and data3 */ + p = tcp_create_rx_segment(pcb, NULL, 0, 0, 12, TCP_ACK); + EXPECT_RET(p != NULL); + test_tcp_input(p, &netif); + /*EXPECT_RET(txcounters.num_tx_calls == 0);*/ + + /* ...and even more data */ + err = tcp_write(pcb, data5, sizeof(data5), TCP_WRITE_FLAG_COPY); + EXPECT_RET(err == ERR_OK); + err = tcp_output(pcb); + EXPECT_RET(err == ERR_OK); + /* ...and even more data */ + err = tcp_write(pcb, data5, sizeof(data5), TCP_WRITE_FLAG_COPY); + EXPECT_RET(err == ERR_OK); + err = tcp_output(pcb); + EXPECT_RET(err == ERR_OK); + +#if 0 + /* create expected segment */ + p1 = tcp_create_rx_segment(pcb, counters.expected_data, data_len, 0, 0, 0); + EXPECT_RET(p != NULL); + if (p != NULL) { + /* pass the segment to tcp_input */ + test_tcp_input(p, &netif); + /* check if counters are as expected */ + EXPECT_RET(counters.close_calls == 0); + EXPECT_RET(counters.recv_calls == 1); + EXPECT_RET(counters.recved_bytes == data_len); + EXPECT_RET(counters.err_calls == 0); + } +#endif + /* make sure the pcb is freed */ + EXPECT_RET(lwip_stats.memp[MEMP_TCP_PCB].used == 1); + tcp_abort(pcb); + EXPECT_RET(lwip_stats.memp[MEMP_TCP_PCB].used == 0); +} +END_TEST + +static u8_t tx_data[TCP_WND*2]; + +static void +check_seqnos(struct tcp_seg *segs, int num_expected, u32_t *seqnos_expected) +{ + struct tcp_seg *s = segs; + int i; + for (i = 0; i < num_expected; i++, s = s->next) { + EXPECT_RET(s != NULL); + EXPECT(s->tcphdr->seqno == htonl(seqnos_expected[i])); + } + EXPECT(s == NULL); +} + +/** Send data with sequence numbers that wrap around the u32_t range. + * Then, provoke fast retransmission by duplicate ACKs and check that all + * segment lists are still properly sorted. */ +START_TEST(test_tcp_fast_rexmit_wraparound) +{ + struct netif netif; + struct test_tcp_txcounters txcounters; + struct test_tcp_counters counters; + struct tcp_pcb* pcb; + struct pbuf* p; + ip_addr_t remote_ip, local_ip, netmask; + u16_t remote_port = 0x100, local_port = 0x101; + err_t err; +#define SEQNO1 (0xFFFFFF00 - TCP_MSS) +#define ISS 6510 + u16_t i, sent_total = 0; + u32_t seqnos[] = { + SEQNO1, + SEQNO1 + (1 * TCP_MSS), + SEQNO1 + (2 * TCP_MSS), + SEQNO1 + (3 * TCP_MSS), + SEQNO1 + (4 * TCP_MSS), + SEQNO1 + (5 * TCP_MSS)}; + LWIP_UNUSED_ARG(_i); + + for (i = 0; i < sizeof(tx_data); i++) { + tx_data[i] = (u8_t)i; + } + + /* initialize local vars */ + IP4_ADDR(&local_ip, 192, 168, 1, 1); + IP4_ADDR(&remote_ip, 192, 168, 1, 2); + IP4_ADDR(&netmask, 255, 255, 255, 0); + test_tcp_init_netif(&netif, &txcounters, &local_ip, &netmask); + memset(&counters, 0, sizeof(counters)); + + /* create and initialize the pcb */ + tcp_ticks = SEQNO1 - ISS; + pcb = test_tcp_new_counters_pcb(&counters); + EXPECT_RET(pcb != NULL); + EXPECT(pcb->lastack == SEQNO1); + tcp_set_state(pcb, ESTABLISHED, &local_ip, &remote_ip, local_port, remote_port); + pcb->mss = TCP_MSS; + /* disable initial congestion window (we don't send a SYN here...) */ + pcb->cwnd = 2*TCP_MSS; + + /* send 6 mss-sized segments */ + for (i = 0; i < 6; i++) { + err = tcp_write(pcb, &tx_data[sent_total], TCP_MSS, TCP_WRITE_FLAG_COPY); + EXPECT_RET(err == ERR_OK); + sent_total += TCP_MSS; + } + check_seqnos(pcb->unsent, 6, seqnos); + EXPECT(pcb->unacked == NULL); + err = tcp_output(pcb); + EXPECT(txcounters.num_tx_calls == 2); + EXPECT(txcounters.num_tx_bytes == 2 * (TCP_MSS + 40U)); + memset(&txcounters, 0, sizeof(txcounters)); + + check_seqnos(pcb->unacked, 2, seqnos); + check_seqnos(pcb->unsent, 4, &seqnos[2]); + + /* ACK the first segment */ + p = tcp_create_rx_segment(pcb, NULL, 0, 0, TCP_MSS, TCP_ACK); + test_tcp_input(p, &netif); + /* ensure this didn't trigger a retransmission */ + EXPECT(txcounters.num_tx_calls == 1); + EXPECT(txcounters.num_tx_bytes == TCP_MSS + 40U); + memset(&txcounters, 0, sizeof(txcounters)); + check_seqnos(pcb->unacked, 2, &seqnos[1]); + check_seqnos(pcb->unsent, 3, &seqnos[3]); + + /* 3 dupacks */ + EXPECT(pcb->dupacks == 0); + p = tcp_create_rx_segment(pcb, NULL, 0, 0, 0, TCP_ACK); + test_tcp_input(p, &netif); + EXPECT(txcounters.num_tx_calls == 0); + EXPECT(pcb->dupacks == 1); + p = tcp_create_rx_segment(pcb, NULL, 0, 0, 0, TCP_ACK); + test_tcp_input(p, &netif); + EXPECT(txcounters.num_tx_calls == 0); + EXPECT(pcb->dupacks == 2); + /* 3rd dupack -> fast rexmit */ + p = tcp_create_rx_segment(pcb, NULL, 0, 0, 0, TCP_ACK); + test_tcp_input(p, &netif); + EXPECT(pcb->dupacks == 3); + EXPECT(txcounters.num_tx_calls == 4); + memset(&txcounters, 0, sizeof(txcounters)); + EXPECT(pcb->unsent == NULL); + check_seqnos(pcb->unacked, 5, &seqnos[1]); + + /* make sure the pcb is freed */ + EXPECT_RET(lwip_stats.memp[MEMP_TCP_PCB].used == 1); + tcp_abort(pcb); + EXPECT_RET(lwip_stats.memp[MEMP_TCP_PCB].used == 0); +} +END_TEST + +/** Send data with sequence numbers that wrap around the u32_t range. + * Then, provoke RTO retransmission and check that all + * segment lists are still properly sorted. */ +START_TEST(test_tcp_rto_rexmit_wraparound) +{ + struct netif netif; + struct test_tcp_txcounters txcounters; + struct test_tcp_counters counters; + struct tcp_pcb* pcb; + ip_addr_t remote_ip, local_ip, netmask; + u16_t remote_port = 0x100, local_port = 0x101; + err_t err; +#define SEQNO1 (0xFFFFFF00 - TCP_MSS) +#define ISS 6510 + u16_t i, sent_total = 0; + u32_t seqnos[] = { + SEQNO1, + SEQNO1 + (1 * TCP_MSS), + SEQNO1 + (2 * TCP_MSS), + SEQNO1 + (3 * TCP_MSS), + SEQNO1 + (4 * TCP_MSS), + SEQNO1 + (5 * TCP_MSS)}; + LWIP_UNUSED_ARG(_i); + + for (i = 0; i < sizeof(tx_data); i++) { + tx_data[i] = (u8_t)i; + } + + /* initialize local vars */ + IP4_ADDR(&local_ip, 192, 168, 1, 1); + IP4_ADDR(&remote_ip, 192, 168, 1, 2); + IP4_ADDR(&netmask, 255, 255, 255, 0); + test_tcp_init_netif(&netif, &txcounters, &local_ip, &netmask); + memset(&counters, 0, sizeof(counters)); + + /* create and initialize the pcb */ + tcp_ticks = 0; + tcp_ticks = 0 - tcp_next_iss(); + tcp_ticks = SEQNO1 - tcp_next_iss(); + pcb = test_tcp_new_counters_pcb(&counters); + EXPECT_RET(pcb != NULL); + EXPECT(pcb->lastack == SEQNO1); + tcp_set_state(pcb, ESTABLISHED, &local_ip, &remote_ip, local_port, remote_port); + pcb->mss = TCP_MSS; + /* disable initial congestion window (we don't send a SYN here...) */ + pcb->cwnd = 2*TCP_MSS; + + /* send 6 mss-sized segments */ + for (i = 0; i < 6; i++) { + err = tcp_write(pcb, &tx_data[sent_total], TCP_MSS, TCP_WRITE_FLAG_COPY); + EXPECT_RET(err == ERR_OK); + sent_total += TCP_MSS; + } + check_seqnos(pcb->unsent, 6, seqnos); + EXPECT(pcb->unacked == NULL); + err = tcp_output(pcb); + EXPECT(txcounters.num_tx_calls == 2); + EXPECT(txcounters.num_tx_bytes == 2 * (TCP_MSS + 40U)); + memset(&txcounters, 0, sizeof(txcounters)); + + check_seqnos(pcb->unacked, 2, seqnos); + check_seqnos(pcb->unsent, 4, &seqnos[2]); + + /* call the tcp timer some times */ + for (i = 0; i < 10; i++) { + test_tcp_tmr(); + EXPECT(txcounters.num_tx_calls == 0); + } + /* 11th call to tcp_tmr: RTO rexmit fires */ + test_tcp_tmr(); + EXPECT(txcounters.num_tx_calls == 1); + check_seqnos(pcb->unacked, 1, seqnos); + check_seqnos(pcb->unsent, 5, &seqnos[1]); + + /* fake greater cwnd */ + pcb->cwnd = pcb->snd_wnd; + /* send more data */ + err = tcp_output(pcb); + EXPECT(err == ERR_OK); + /* check queues are sorted */ + EXPECT(pcb->unsent == NULL); + check_seqnos(pcb->unacked, 6, seqnos); + + /* make sure the pcb is freed */ + EXPECT_RET(lwip_stats.memp[MEMP_TCP_PCB].used == 1); + tcp_abort(pcb); + EXPECT_RET(lwip_stats.memp[MEMP_TCP_PCB].used == 0); +} +END_TEST + +/** Provoke fast retransmission by duplicate ACKs and then recover by ACKing all sent data. + * At the end, send more data. */ +static void test_tcp_tx_full_window_lost(u8_t zero_window_probe_from_unsent) +{ + struct netif netif; + struct test_tcp_txcounters txcounters; + struct test_tcp_counters counters; + struct tcp_pcb* pcb; + struct pbuf *p; + ip_addr_t remote_ip, local_ip, netmask; + u16_t remote_port = 0x100, local_port = 0x101; + err_t err; + u16_t sent_total, i; + u8_t expected = 0xFE; + + for (i = 0; i < sizeof(tx_data); i++) { + u8_t d = (u8_t)i; + if (d == 0xFE) { + d = 0xF0; + } + tx_data[i] = d; + } + if (zero_window_probe_from_unsent) { + tx_data[TCP_WND] = expected; + } else { + tx_data[0] = expected; + } + + /* initialize local vars */ + IP4_ADDR(&local_ip, 192, 168, 1, 1); + IP4_ADDR(&remote_ip, 192, 168, 1, 2); + IP4_ADDR(&netmask, 255, 255, 255, 0); + test_tcp_init_netif(&netif, &txcounters, &local_ip, &netmask); + memset(&counters, 0, sizeof(counters)); + memset(&txcounters, 0, sizeof(txcounters)); + + /* create and initialize the pcb */ + pcb = test_tcp_new_counters_pcb(&counters); + EXPECT_RET(pcb != NULL); + tcp_set_state(pcb, ESTABLISHED, &local_ip, &remote_ip, local_port, remote_port); + pcb->mss = TCP_MSS; + /* disable initial congestion window (we don't send a SYN here...) */ + pcb->cwnd = pcb->snd_wnd; + + /* send a full window (minus 1 packets) of TCP data in MSS-sized chunks */ + sent_total = 0; + if ((TCP_WND - TCP_MSS) % TCP_MSS != 0) { + u16_t initial_data_len = (TCP_WND - TCP_MSS) % TCP_MSS; + err = tcp_write(pcb, &tx_data[sent_total], initial_data_len, TCP_WRITE_FLAG_COPY); + EXPECT_RET(err == ERR_OK); + err = tcp_output(pcb); + EXPECT_RET(err == ERR_OK); + EXPECT(txcounters.num_tx_calls == 1); + EXPECT(txcounters.num_tx_bytes == initial_data_len + 40U); + memset(&txcounters, 0, sizeof(txcounters)); + sent_total += initial_data_len; + } + for (; sent_total < (TCP_WND - TCP_MSS); sent_total += TCP_MSS) { + err = tcp_write(pcb, &tx_data[sent_total], TCP_MSS, TCP_WRITE_FLAG_COPY); + EXPECT_RET(err == ERR_OK); + err = tcp_output(pcb); + EXPECT_RET(err == ERR_OK); + EXPECT(txcounters.num_tx_calls == 1); + EXPECT(txcounters.num_tx_bytes == TCP_MSS + 40U); + memset(&txcounters, 0, sizeof(txcounters)); + } + EXPECT(sent_total == (TCP_WND - TCP_MSS)); + + /* now ACK the packet before the first */ + p = tcp_create_rx_segment(pcb, NULL, 0, 0, 0, TCP_ACK); + test_tcp_input(p, &netif); + /* ensure this didn't trigger a retransmission */ + EXPECT(txcounters.num_tx_calls == 0); + EXPECT(txcounters.num_tx_bytes == 0); + + EXPECT(pcb->persist_backoff == 0); + /* send the last packet, now a complete window has been sent */ + err = tcp_write(pcb, &tx_data[sent_total], TCP_MSS, TCP_WRITE_FLAG_COPY); + sent_total += TCP_MSS; + EXPECT_RET(err == ERR_OK); + err = tcp_output(pcb); + EXPECT_RET(err == ERR_OK); + EXPECT(txcounters.num_tx_calls == 1); + EXPECT(txcounters.num_tx_bytes == TCP_MSS + 40U); + memset(&txcounters, 0, sizeof(txcounters)); + EXPECT(pcb->persist_backoff == 0); + + if (zero_window_probe_from_unsent) { + /* ACK all data but close the TX window */ + p = tcp_create_rx_segment_wnd(pcb, NULL, 0, 0, TCP_WND, TCP_ACK, 0); + test_tcp_input(p, &netif); + /* ensure this didn't trigger any transmission */ + EXPECT(txcounters.num_tx_calls == 0); + EXPECT(txcounters.num_tx_bytes == 0); + EXPECT(pcb->persist_backoff == 1); + } + + /* send one byte more (out of window) -> persist timer starts */ + err = tcp_write(pcb, &tx_data[sent_total], 1, TCP_WRITE_FLAG_COPY); + EXPECT_RET(err == ERR_OK); + err = tcp_output(pcb); + EXPECT_RET(err == ERR_OK); + EXPECT(txcounters.num_tx_calls == 0); + EXPECT(txcounters.num_tx_bytes == 0); + memset(&txcounters, 0, sizeof(txcounters)); + if (!zero_window_probe_from_unsent) { + /* no persist timer unless a zero window announcement has been received */ + EXPECT(pcb->persist_backoff == 0); + } else { + EXPECT(pcb->persist_backoff == 1); + + /* call tcp_timer some more times to let persist timer count up */ + for (i = 0; i < 4; i++) { + test_tcp_tmr(); + EXPECT(txcounters.num_tx_calls == 0); + EXPECT(txcounters.num_tx_bytes == 0); + } + + /* this should trigger the zero-window-probe */ + txcounters.copy_tx_packets = 1; + test_tcp_tmr(); + txcounters.copy_tx_packets = 0; + EXPECT(txcounters.num_tx_calls == 1); + EXPECT(txcounters.num_tx_bytes == 1 + 40U); + EXPECT(txcounters.tx_packets != NULL); + if (txcounters.tx_packets != NULL) { + u8_t sent; + u16_t ret; + ret = pbuf_copy_partial(txcounters.tx_packets, &sent, 1, 40U); + EXPECT(ret == 1); + EXPECT(sent == expected); + } + if (txcounters.tx_packets != NULL) { + pbuf_free(txcounters.tx_packets); + txcounters.tx_packets = NULL; + } + } + + /* make sure the pcb is freed */ + EXPECT_RET(lwip_stats.memp[MEMP_TCP_PCB].used == 1); + tcp_abort(pcb); + EXPECT_RET(lwip_stats.memp[MEMP_TCP_PCB].used == 0); +} + +START_TEST(test_tcp_tx_full_window_lost_from_unsent) +{ + LWIP_UNUSED_ARG(_i); + test_tcp_tx_full_window_lost(1); +} +END_TEST + +START_TEST(test_tcp_tx_full_window_lost_from_unacked) +{ + LWIP_UNUSED_ARG(_i); + test_tcp_tx_full_window_lost(0); +} +END_TEST + +/** Create the suite including all tests for this module */ +Suite * +tcp_suite(void) +{ + TFun tests[] = { + test_tcp_new_abort, + test_tcp_recv_inseq, + test_tcp_fast_retx_recover, + test_tcp_fast_rexmit_wraparound, + test_tcp_rto_rexmit_wraparound, + test_tcp_tx_full_window_lost_from_unacked, + test_tcp_tx_full_window_lost_from_unsent + }; + return create_suite("TCP", tests, sizeof(tests)/sizeof(TFun), tcp_setup, tcp_teardown); +} diff --git a/src/lwip-1.4.1/test/unit/tcp/test_tcp.h b/src/lwip-1.4.1/test/unit/tcp/test_tcp.h new file mode 100644 index 0000000..f1c4a46 --- /dev/null +++ b/src/lwip-1.4.1/test/unit/tcp/test_tcp.h @@ -0,0 +1,8 @@ +#ifndef __TEST_TCP_H__ +#define __TEST_TCP_H__ + +#include "../lwip_check.h" + +Suite *tcp_suite(void); + +#endif diff --git a/src/lwip-1.4.1/test/unit/tcp/test_tcp_oos.c b/src/lwip-1.4.1/test/unit/tcp/test_tcp_oos.c new file mode 100644 index 0000000..764de1c --- /dev/null +++ b/src/lwip-1.4.1/test/unit/tcp/test_tcp_oos.c @@ -0,0 +1,944 @@ +#include "test_tcp_oos.h" + +#include "lwip/tcp_impl.h" +#include "lwip/stats.h" +#include "tcp_helper.h" + +#if !LWIP_STATS || !TCP_STATS || !MEMP_STATS +#error "This tests needs TCP- and MEMP-statistics enabled" +#endif +#if !TCP_QUEUE_OOSEQ +#error "This tests needs TCP_QUEUE_OOSEQ enabled" +#endif + +/** CHECK_SEGMENTS_ON_OOSEQ: + * 1: check count, seqno and len of segments on pcb->ooseq (strict) + * 0: only check that bytes are received in correct order (less strict) */ +#define CHECK_SEGMENTS_ON_OOSEQ 1 + +#if CHECK_SEGMENTS_ON_OOSEQ +#define EXPECT_OOSEQ(x) EXPECT(x) +#else +#define EXPECT_OOSEQ(x) +#endif + +/* helper functions */ + +/** Get the numbers of segments on the ooseq list */ +static int tcp_oos_count(struct tcp_pcb* pcb) +{ + int num = 0; + struct tcp_seg* seg = pcb->ooseq; + while(seg != NULL) { + num++; + seg = seg->next; + } + return num; +} + +/** Get the numbers of pbufs on the ooseq list */ +static int tcp_oos_pbuf_count(struct tcp_pcb* pcb) +{ + int num = 0; + struct tcp_seg* seg = pcb->ooseq; + while(seg != NULL) { + num += pbuf_clen(seg->p); + seg = seg->next; + } + return num; +} + +/** Get the seqno of a segment (by index) on the ooseq list + * + * @param pcb the pcb to check for ooseq segments + * @param seg_index index of the segment on the ooseq list + * @return seqno of the segment + */ +static u32_t +tcp_oos_seg_seqno(struct tcp_pcb* pcb, int seg_index) +{ + int num = 0; + struct tcp_seg* seg = pcb->ooseq; + + /* then check the actual segment */ + while(seg != NULL) { + if(num == seg_index) { + return seg->tcphdr->seqno; + } + num++; + seg = seg->next; + } + fail(); + return 0; +} + +/** Get the tcplen (datalen + SYN/FIN) of a segment (by index) on the ooseq list + * + * @param pcb the pcb to check for ooseq segments + * @param seg_index index of the segment on the ooseq list + * @return tcplen of the segment + */ +static int +tcp_oos_seg_tcplen(struct tcp_pcb* pcb, int seg_index) +{ + int num = 0; + struct tcp_seg* seg = pcb->ooseq; + + /* then check the actual segment */ + while(seg != NULL) { + if(num == seg_index) { + return TCP_TCPLEN(seg); + } + num++; + seg = seg->next; + } + fail(); + return -1; +} + +/** Get the tcplen (datalen + SYN/FIN) of all segments on the ooseq list + * + * @param pcb the pcb to check for ooseq segments + * @return tcplen of all segment + */ +static int +tcp_oos_tcplen(struct tcp_pcb* pcb) +{ + int len = 0; + struct tcp_seg* seg = pcb->ooseq; + + /* then check the actual segment */ + while(seg != NULL) { + len += TCP_TCPLEN(seg); + seg = seg->next; + } + return len; +} + +/* Setup/teardown functions */ + +static void +tcp_oos_setup(void) +{ + tcp_remove_all(); +} + +static void +tcp_oos_teardown(void) +{ + tcp_remove_all(); +} + + + +/* Test functions */ + +/** create multiple segments and pass them to tcp_input in a wrong + * order to see if ooseq-caching works correctly + * FIN is received in out-of-sequence segments only */ +START_TEST(test_tcp_recv_ooseq_FIN_OOSEQ) +{ + struct test_tcp_counters counters; + struct tcp_pcb* pcb; + struct pbuf *p_8_9, *p_4_8, *p_4_10, *p_2_14, *p_fin, *pinseq; + char data[] = { + 1, 2, 3, 4, + 5, 6, 7, 8, + 9, 10, 11, 12, + 13, 14, 15, 16}; + ip_addr_t remote_ip, local_ip; + u16_t data_len; + u16_t remote_port = 0x100, local_port = 0x101; + struct netif netif; + LWIP_UNUSED_ARG(_i); + + /* initialize local vars */ + memset(&netif, 0, sizeof(netif)); + IP4_ADDR(&local_ip, 192, 168, 1, 1); + IP4_ADDR(&remote_ip, 192, 168, 1, 2); + data_len = sizeof(data); + /* initialize counter struct */ + memset(&counters, 0, sizeof(counters)); + counters.expected_data_len = data_len; + counters.expected_data = data; + + /* create and initialize the pcb */ + pcb = test_tcp_new_counters_pcb(&counters); + EXPECT_RET(pcb != NULL); + tcp_set_state(pcb, ESTABLISHED, &local_ip, &remote_ip, local_port, remote_port); + + /* create segments */ + /* pinseq is sent as last segment! */ + pinseq = tcp_create_rx_segment(pcb, &data[0], 4, 0, 0, TCP_ACK); + /* p1: 8 bytes before FIN */ + /* seqno: 8..16 */ + p_8_9 = tcp_create_rx_segment(pcb, &data[8], 8, 8, 0, TCP_ACK|TCP_FIN); + /* p2: 4 bytes before p1, including the first 4 bytes of p1 (partly duplicate) */ + /* seqno: 4..11 */ + p_4_8 = tcp_create_rx_segment(pcb, &data[4], 8, 4, 0, TCP_ACK); + /* p3: same as p2 but 2 bytes longer */ + /* seqno: 4..13 */ + p_4_10 = tcp_create_rx_segment(pcb, &data[4], 10, 4, 0, TCP_ACK); + /* p4: 14 bytes before FIN, includes data from p1 and p2, plus partly from pinseq */ + /* seqno: 2..15 */ + p_2_14 = tcp_create_rx_segment(pcb, &data[2], 14, 2, 0, TCP_ACK); + /* FIN, seqno 16 */ + p_fin = tcp_create_rx_segment(pcb, NULL, 0,16, 0, TCP_ACK|TCP_FIN); + EXPECT(pinseq != NULL); + EXPECT(p_8_9 != NULL); + EXPECT(p_4_8 != NULL); + EXPECT(p_4_10 != NULL); + EXPECT(p_2_14 != NULL); + EXPECT(p_fin != NULL); + if ((pinseq != NULL) && (p_8_9 != NULL) && (p_4_8 != NULL) && (p_4_10 != NULL) && (p_2_14 != NULL) && (p_fin != NULL)) { + /* pass the segment to tcp_input */ + test_tcp_input(p_8_9, &netif); + /* check if counters are as expected */ + EXPECT(counters.close_calls == 0); + EXPECT(counters.recv_calls == 0); + EXPECT(counters.recved_bytes == 0); + EXPECT(counters.err_calls == 0); + /* check ooseq queue */ + EXPECT_OOSEQ(tcp_oos_count(pcb) == 1); + EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 8); + EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 9); /* includes FIN */ + + /* pass the segment to tcp_input */ + test_tcp_input(p_4_8, &netif); + /* check if counters are as expected */ + EXPECT(counters.close_calls == 0); + EXPECT(counters.recv_calls == 0); + EXPECT(counters.recved_bytes == 0); + EXPECT(counters.err_calls == 0); + /* check ooseq queue */ + EXPECT_OOSEQ(tcp_oos_count(pcb) == 2); + EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 4); + EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 4); + EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 1) == 8); + EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 1) == 9); /* includes FIN */ + + /* pass the segment to tcp_input */ + test_tcp_input(p_4_10, &netif); + /* check if counters are as expected */ + EXPECT(counters.close_calls == 0); + EXPECT(counters.recv_calls == 0); + EXPECT(counters.recved_bytes == 0); + EXPECT(counters.err_calls == 0); + /* ooseq queue: unchanged */ + EXPECT_OOSEQ(tcp_oos_count(pcb) == 2); + EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 4); + EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 4); + EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 1) == 8); + EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 1) == 9); /* includes FIN */ + + /* pass the segment to tcp_input */ + test_tcp_input(p_2_14, &netif); + /* check if counters are as expected */ + EXPECT(counters.close_calls == 0); + EXPECT(counters.recv_calls == 0); + EXPECT(counters.recved_bytes == 0); + EXPECT(counters.err_calls == 0); + /* check ooseq queue */ + EXPECT_OOSEQ(tcp_oos_count(pcb) == 1); + EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 2); + EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 15); /* includes FIN */ + + /* pass the segment to tcp_input */ + test_tcp_input(p_fin, &netif); + /* check if counters are as expected */ + EXPECT(counters.close_calls == 0); + EXPECT(counters.recv_calls == 0); + EXPECT(counters.recved_bytes == 0); + EXPECT(counters.err_calls == 0); + /* ooseq queue: unchanged */ + EXPECT_OOSEQ(tcp_oos_count(pcb) == 1); + EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 2); + EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 15); /* includes FIN */ + + /* pass the segment to tcp_input */ + test_tcp_input(pinseq, &netif); + /* check if counters are as expected */ + EXPECT(counters.close_calls == 1); + EXPECT(counters.recv_calls == 1); + EXPECT(counters.recved_bytes == data_len); + EXPECT(counters.err_calls == 0); + EXPECT(pcb->ooseq == NULL); + } + + /* make sure the pcb is freed */ + EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 1); + tcp_abort(pcb); + EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 0); +} +END_TEST + + +/** create multiple segments and pass them to tcp_input in a wrong + * order to see if ooseq-caching works correctly + * FIN is received IN-SEQUENCE at the end */ +START_TEST(test_tcp_recv_ooseq_FIN_INSEQ) +{ + struct test_tcp_counters counters; + struct tcp_pcb* pcb; + struct pbuf *p_1_2, *p_4_8, *p_3_11, *p_2_12, *p_15_1, *p_15_1a, *pinseq, *pinseqFIN; + char data[] = { + 1, 2, 3, 4, + 5, 6, 7, 8, + 9, 10, 11, 12, + 13, 14, 15, 16}; + ip_addr_t remote_ip, local_ip; + u16_t data_len; + u16_t remote_port = 0x100, local_port = 0x101; + struct netif netif; + LWIP_UNUSED_ARG(_i); + + /* initialize local vars */ + memset(&netif, 0, sizeof(netif)); + IP4_ADDR(&local_ip, 192, 168, 1, 1); + IP4_ADDR(&remote_ip, 192, 168, 1, 2); + data_len = sizeof(data); + /* initialize counter struct */ + memset(&counters, 0, sizeof(counters)); + counters.expected_data_len = data_len; + counters.expected_data = data; + + /* create and initialize the pcb */ + pcb = test_tcp_new_counters_pcb(&counters); + EXPECT_RET(pcb != NULL); + tcp_set_state(pcb, ESTABLISHED, &local_ip, &remote_ip, local_port, remote_port); + + /* create segments */ + /* p1: 7 bytes - 2 before FIN */ + /* seqno: 1..2 */ + p_1_2 = tcp_create_rx_segment(pcb, &data[1], 2, 1, 0, TCP_ACK); + /* p2: 4 bytes before p1, including the first 4 bytes of p1 (partly duplicate) */ + /* seqno: 4..11 */ + p_4_8 = tcp_create_rx_segment(pcb, &data[4], 8, 4, 0, TCP_ACK); + /* p3: same as p2 but 2 bytes longer and one byte more at the front */ + /* seqno: 3..13 */ + p_3_11 = tcp_create_rx_segment(pcb, &data[3], 11, 3, 0, TCP_ACK); + /* p4: 13 bytes - 2 before FIN - should be ignored as contained in p1 and p3 */ + /* seqno: 2..13 */ + p_2_12 = tcp_create_rx_segment(pcb, &data[2], 12, 2, 0, TCP_ACK); + /* pinseq is the first segment that is held back to create ooseq! */ + /* seqno: 0..3 */ + pinseq = tcp_create_rx_segment(pcb, &data[0], 4, 0, 0, TCP_ACK); + /* p5: last byte before FIN */ + /* seqno: 15 */ + p_15_1 = tcp_create_rx_segment(pcb, &data[15], 1, 15, 0, TCP_ACK); + /* p6: same as p5, should be ignored */ + p_15_1a= tcp_create_rx_segment(pcb, &data[15], 1, 15, 0, TCP_ACK); + /* pinseqFIN: last 2 bytes plus FIN */ + /* only segment containing seqno 14 and FIN */ + pinseqFIN = tcp_create_rx_segment(pcb, &data[14], 2, 14, 0, TCP_ACK|TCP_FIN); + EXPECT(pinseq != NULL); + EXPECT(p_1_2 != NULL); + EXPECT(p_4_8 != NULL); + EXPECT(p_3_11 != NULL); + EXPECT(p_2_12 != NULL); + EXPECT(p_15_1 != NULL); + EXPECT(p_15_1a != NULL); + EXPECT(pinseqFIN != NULL); + if ((pinseq != NULL) && (p_1_2 != NULL) && (p_4_8 != NULL) && (p_3_11 != NULL) && (p_2_12 != NULL) + && (p_15_1 != NULL) && (p_15_1a != NULL) && (pinseqFIN != NULL)) { + /* pass the segment to tcp_input */ + test_tcp_input(p_1_2, &netif); + /* check if counters are as expected */ + EXPECT(counters.close_calls == 0); + EXPECT(counters.recv_calls == 0); + EXPECT(counters.recved_bytes == 0); + EXPECT(counters.err_calls == 0); + /* check ooseq queue */ + EXPECT_OOSEQ(tcp_oos_count(pcb) == 1); + EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 1); + EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 2); + + /* pass the segment to tcp_input */ + test_tcp_input(p_4_8, &netif); + /* check if counters are as expected */ + EXPECT(counters.close_calls == 0); + EXPECT(counters.recv_calls == 0); + EXPECT(counters.recved_bytes == 0); + EXPECT(counters.err_calls == 0); + /* check ooseq queue */ + EXPECT_OOSEQ(tcp_oos_count(pcb) == 2); + EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 1); + EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 2); + EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 1) == 4); + EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 1) == 8); + + /* pass the segment to tcp_input */ + test_tcp_input(p_3_11, &netif); + /* check if counters are as expected */ + EXPECT(counters.close_calls == 0); + EXPECT(counters.recv_calls == 0); + EXPECT(counters.recved_bytes == 0); + EXPECT(counters.err_calls == 0); + /* check ooseq queue */ + EXPECT_OOSEQ(tcp_oos_count(pcb) == 2); + EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 1); + EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 2); + /* p_3_11 has removed p_4_8 from ooseq */ + EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 1) == 3); + EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 1) == 11); + + /* pass the segment to tcp_input */ + test_tcp_input(p_2_12, &netif); + /* check if counters are as expected */ + EXPECT(counters.close_calls == 0); + EXPECT(counters.recv_calls == 0); + EXPECT(counters.recved_bytes == 0); + EXPECT(counters.err_calls == 0); + /* check ooseq queue */ + EXPECT_OOSEQ(tcp_oos_count(pcb) == 2); + EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 1); + EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 1); + EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 1) == 2); + EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 1) == 12); + + /* pass the segment to tcp_input */ + test_tcp_input(pinseq, &netif); + /* check if counters are as expected */ + EXPECT(counters.close_calls == 0); + EXPECT(counters.recv_calls == 1); + EXPECT(counters.recved_bytes == 14); + EXPECT(counters.err_calls == 0); + EXPECT(pcb->ooseq == NULL); + + /* pass the segment to tcp_input */ + test_tcp_input(p_15_1, &netif); + /* check if counters are as expected */ + EXPECT(counters.close_calls == 0); + EXPECT(counters.recv_calls == 1); + EXPECT(counters.recved_bytes == 14); + EXPECT(counters.err_calls == 0); + /* check ooseq queue */ + EXPECT_OOSEQ(tcp_oos_count(pcb) == 1); + EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 15); + EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 1); + + /* pass the segment to tcp_input */ + test_tcp_input(p_15_1a, &netif); + /* check if counters are as expected */ + EXPECT(counters.close_calls == 0); + EXPECT(counters.recv_calls == 1); + EXPECT(counters.recved_bytes == 14); + EXPECT(counters.err_calls == 0); + /* check ooseq queue: unchanged */ + EXPECT_OOSEQ(tcp_oos_count(pcb) == 1); + EXPECT_OOSEQ(tcp_oos_seg_seqno(pcb, 0) == 15); + EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 1); + + /* pass the segment to tcp_input */ + test_tcp_input(pinseqFIN, &netif); + /* check if counters are as expected */ + EXPECT(counters.close_calls == 1); + EXPECT(counters.recv_calls == 2); + EXPECT(counters.recved_bytes == data_len); + EXPECT(counters.err_calls == 0); + EXPECT(pcb->ooseq == NULL); + } + + /* make sure the pcb is freed */ + EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 1); + tcp_abort(pcb); + EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 0); +} +END_TEST + +static char data_full_wnd[TCP_WND]; + +/** create multiple segments and pass them to tcp_input with the first segment missing + * to simulate overruning the rxwin with ooseq queueing enabled */ +START_TEST(test_tcp_recv_ooseq_overrun_rxwin) +{ +#if !TCP_OOSEQ_MAX_BYTES && !TCP_OOSEQ_MAX_PBUFS + int i, k; + struct test_tcp_counters counters; + struct tcp_pcb* pcb; + struct pbuf *pinseq, *p_ovr; + ip_addr_t remote_ip, local_ip; + u16_t remote_port = 0x100, local_port = 0x101; + struct netif netif; + int datalen = 0; + int datalen2; + + for(i = 0; i < sizeof(data_full_wnd); i++) { + data_full_wnd[i] = (char)i; + } + + /* initialize local vars */ + memset(&netif, 0, sizeof(netif)); + IP4_ADDR(&local_ip, 192, 168, 1, 1); + IP4_ADDR(&remote_ip, 192, 168, 1, 2); + /* initialize counter struct */ + memset(&counters, 0, sizeof(counters)); + counters.expected_data_len = TCP_WND; + counters.expected_data = data_full_wnd; + + /* create and initialize the pcb */ + pcb = test_tcp_new_counters_pcb(&counters); + EXPECT_RET(pcb != NULL); + tcp_set_state(pcb, ESTABLISHED, &local_ip, &remote_ip, local_port, remote_port); + pcb->rcv_nxt = 0x8000; + + /* create segments */ + /* pinseq is sent as last segment! */ + pinseq = tcp_create_rx_segment(pcb, &data_full_wnd[0], TCP_MSS, 0, 0, TCP_ACK); + + for(i = TCP_MSS, k = 0; i < TCP_WND; i += TCP_MSS, k++) { + int count, expected_datalen; + struct pbuf *p = tcp_create_rx_segment(pcb, &data_full_wnd[TCP_MSS*(k+1)], + TCP_MSS, TCP_MSS*(k+1), 0, TCP_ACK); + EXPECT_RET(p != NULL); + /* pass the segment to tcp_input */ + test_tcp_input(p, &netif); + /* check if counters are as expected */ + EXPECT(counters.close_calls == 0); + EXPECT(counters.recv_calls == 0); + EXPECT(counters.recved_bytes == 0); + EXPECT(counters.err_calls == 0); + /* check ooseq queue */ + count = tcp_oos_count(pcb); + EXPECT_OOSEQ(count == k+1); + datalen = tcp_oos_tcplen(pcb); + if (i + TCP_MSS < TCP_WND) { + expected_datalen = (k+1)*TCP_MSS; + } else { + expected_datalen = TCP_WND - TCP_MSS; + } + if (datalen != expected_datalen) { + EXPECT_OOSEQ(datalen == expected_datalen); + } + } + + /* pass in one more segment, cleary overrunning the rxwin */ + p_ovr = tcp_create_rx_segment(pcb, &data_full_wnd[TCP_MSS*(k+1)], TCP_MSS, TCP_MSS*(k+1), 0, TCP_ACK); + EXPECT_RET(p_ovr != NULL); + /* pass the segment to tcp_input */ + test_tcp_input(p_ovr, &netif); + /* check if counters are as expected */ + EXPECT(counters.close_calls == 0); + EXPECT(counters.recv_calls == 0); + EXPECT(counters.recved_bytes == 0); + EXPECT(counters.err_calls == 0); + /* check ooseq queue */ + EXPECT_OOSEQ(tcp_oos_count(pcb) == k); + datalen2 = tcp_oos_tcplen(pcb); + EXPECT_OOSEQ(datalen == datalen2); + + /* now pass inseq */ + test_tcp_input(pinseq, &netif); + EXPECT(pcb->ooseq == NULL); + + /* make sure the pcb is freed */ + EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 1); + tcp_abort(pcb); + EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 0); +#endif /* !TCP_OOSEQ_MAX_BYTES && !TCP_OOSEQ_MAX_PBUFS */ + LWIP_UNUSED_ARG(_i); +} +END_TEST + +START_TEST(test_tcp_recv_ooseq_max_bytes) +{ +#if TCP_OOSEQ_MAX_BYTES && (TCP_OOSEQ_MAX_BYTES < (TCP_WND + 1)) && (PBUF_POOL_BUFSIZE >= (TCP_MSS + PBUF_LINK_HLEN + PBUF_IP_HLEN + PBUF_TRANSPORT_HLEN)) + int i, k; + struct test_tcp_counters counters; + struct tcp_pcb* pcb; + struct pbuf *p_ovr; + ip_addr_t remote_ip, local_ip; + u16_t remote_port = 0x100, local_port = 0x101; + struct netif netif; + int datalen = 0; + int datalen2; + + for(i = 0; i < sizeof(data_full_wnd); i++) { + data_full_wnd[i] = (char)i; + } + + /* initialize local vars */ + memset(&netif, 0, sizeof(netif)); + IP4_ADDR(&local_ip, 192, 168, 1, 1); + IP4_ADDR(&remote_ip, 192, 168, 1, 2); + /* initialize counter struct */ + memset(&counters, 0, sizeof(counters)); + counters.expected_data_len = TCP_WND; + counters.expected_data = data_full_wnd; + + /* create and initialize the pcb */ + pcb = test_tcp_new_counters_pcb(&counters); + EXPECT_RET(pcb != NULL); + tcp_set_state(pcb, ESTABLISHED, &local_ip, &remote_ip, local_port, remote_port); + pcb->rcv_nxt = 0x8000; + + /* don't 'recv' the first segment (1 byte) so that all other segments will be ooseq */ + + /* create segments and 'recv' them */ + for(k = 1, i = 1; k < TCP_OOSEQ_MAX_BYTES; k += TCP_MSS, i++) { + int count; + struct pbuf *p = tcp_create_rx_segment(pcb, &data_full_wnd[k], + TCP_MSS, k, 0, TCP_ACK); + EXPECT_RET(p != NULL); + EXPECT_RET(p->next == NULL); + /* pass the segment to tcp_input */ + test_tcp_input(p, &netif); + /* check if counters are as expected */ + EXPECT(counters.close_calls == 0); + EXPECT(counters.recv_calls == 0); + EXPECT(counters.recved_bytes == 0); + EXPECT(counters.err_calls == 0); + /* check ooseq queue */ + count = tcp_oos_pbuf_count(pcb); + EXPECT_OOSEQ(count == i); + datalen = tcp_oos_tcplen(pcb); + EXPECT_OOSEQ(datalen == (i * TCP_MSS)); + } + + /* pass in one more segment, overrunning the limit */ + p_ovr = tcp_create_rx_segment(pcb, &data_full_wnd[k+1], 1, k+1, 0, TCP_ACK); + EXPECT_RET(p_ovr != NULL); + /* pass the segment to tcp_input */ + test_tcp_input(p_ovr, &netif); + /* check if counters are as expected */ + EXPECT(counters.close_calls == 0); + EXPECT(counters.recv_calls == 0); + EXPECT(counters.recved_bytes == 0); + EXPECT(counters.err_calls == 0); + /* check ooseq queue (ensure the new segment was not accepted) */ + EXPECT_OOSEQ(tcp_oos_count(pcb) == (i-1)); + datalen2 = tcp_oos_tcplen(pcb); + EXPECT_OOSEQ(datalen2 == ((i-1) * TCP_MSS)); + + /* make sure the pcb is freed */ + EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 1); + tcp_abort(pcb); + EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 0); +#endif /* TCP_OOSEQ_MAX_BYTES && (TCP_OOSEQ_MAX_BYTES < (TCP_WND + 1)) && (PBUF_POOL_BUFSIZE >= (TCP_MSS + PBUF_LINK_HLEN + PBUF_IP_HLEN + PBUF_TRANSPORT_HLEN)) */ + LWIP_UNUSED_ARG(_i); +} +END_TEST + +START_TEST(test_tcp_recv_ooseq_max_pbufs) +{ +#if TCP_OOSEQ_MAX_PBUFS && (TCP_OOSEQ_MAX_PBUFS < ((TCP_WND / TCP_MSS) + 1)) && (PBUF_POOL_BUFSIZE >= (TCP_MSS + PBUF_LINK_HLEN + PBUF_IP_HLEN + PBUF_TRANSPORT_HLEN)) + int i; + struct test_tcp_counters counters; + struct tcp_pcb* pcb; + struct pbuf *p_ovr; + ip_addr_t remote_ip, local_ip; + u16_t remote_port = 0x100, local_port = 0x101; + struct netif netif; + int datalen = 0; + int datalen2; + + for(i = 0; i < sizeof(data_full_wnd); i++) { + data_full_wnd[i] = (char)i; + } + + /* initialize local vars */ + memset(&netif, 0, sizeof(netif)); + IP4_ADDR(&local_ip, 192, 168, 1, 1); + IP4_ADDR(&remote_ip, 192, 168, 1, 2); + /* initialize counter struct */ + memset(&counters, 0, sizeof(counters)); + counters.expected_data_len = TCP_WND; + counters.expected_data = data_full_wnd; + + /* create and initialize the pcb */ + pcb = test_tcp_new_counters_pcb(&counters); + EXPECT_RET(pcb != NULL); + tcp_set_state(pcb, ESTABLISHED, &local_ip, &remote_ip, local_port, remote_port); + pcb->rcv_nxt = 0x8000; + + /* don't 'recv' the first segment (1 byte) so that all other segments will be ooseq */ + + /* create segments and 'recv' them */ + for(i = 1; i <= TCP_OOSEQ_MAX_PBUFS; i++) { + int count; + struct pbuf *p = tcp_create_rx_segment(pcb, &data_full_wnd[i], + 1, i, 0, TCP_ACK); + EXPECT_RET(p != NULL); + EXPECT_RET(p->next == NULL); + /* pass the segment to tcp_input */ + test_tcp_input(p, &netif); + /* check if counters are as expected */ + EXPECT(counters.close_calls == 0); + EXPECT(counters.recv_calls == 0); + EXPECT(counters.recved_bytes == 0); + EXPECT(counters.err_calls == 0); + /* check ooseq queue */ + count = tcp_oos_pbuf_count(pcb); + EXPECT_OOSEQ(count == i); + datalen = tcp_oos_tcplen(pcb); + EXPECT_OOSEQ(datalen == i); + } + + /* pass in one more segment, overrunning the limit */ + p_ovr = tcp_create_rx_segment(pcb, &data_full_wnd[i+1], 1, i+1, 0, TCP_ACK); + EXPECT_RET(p_ovr != NULL); + /* pass the segment to tcp_input */ + test_tcp_input(p_ovr, &netif); + /* check if counters are as expected */ + EXPECT(counters.close_calls == 0); + EXPECT(counters.recv_calls == 0); + EXPECT(counters.recved_bytes == 0); + EXPECT(counters.err_calls == 0); + /* check ooseq queue (ensure the new segment was not accepted) */ + EXPECT_OOSEQ(tcp_oos_count(pcb) == (i-1)); + datalen2 = tcp_oos_tcplen(pcb); + EXPECT_OOSEQ(datalen2 == (i-1)); + + /* make sure the pcb is freed */ + EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 1); + tcp_abort(pcb); + EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 0); +#endif /* TCP_OOSEQ_MAX_PBUFS && (TCP_OOSEQ_MAX_BYTES < (TCP_WND + 1)) && (PBUF_POOL_BUFSIZE >= (TCP_MSS + PBUF_LINK_HLEN + PBUF_IP_HLEN + PBUF_TRANSPORT_HLEN)) */ + LWIP_UNUSED_ARG(_i); +} +END_TEST + +static void +check_rx_counters(struct tcp_pcb *pcb, struct test_tcp_counters *counters, u32_t exp_close_calls, u32_t exp_rx_calls, + u32_t exp_rx_bytes, u32_t exp_err_calls, int exp_oos_count, int exp_oos_len) +{ + int oos_len; + EXPECT(counters->close_calls == exp_close_calls); + EXPECT(counters->recv_calls == exp_rx_calls); + EXPECT(counters->recved_bytes == exp_rx_bytes); + EXPECT(counters->err_calls == exp_err_calls); + /* check that pbuf is queued in ooseq */ + EXPECT_OOSEQ(tcp_oos_count(pcb) == exp_oos_count); + oos_len = tcp_oos_tcplen(pcb); + EXPECT_OOSEQ(exp_oos_len == oos_len); +} + +/* this test uses 4 packets: + * - data (len=TCP_MSS) + * - FIN + * - data after FIN (len=1) (invalid) + * - 2nd FIN (invalid) + * + * the parameter 'delay_packet' is a bitmask that choses which on these packets is ooseq + */ +static void test_tcp_recv_ooseq_double_FINs(int delay_packet) +{ + int i, k; + struct test_tcp_counters counters; + struct tcp_pcb* pcb; + struct pbuf *p_normal_fin, *p_data_after_fin, *p, *p_2nd_fin_ooseq; + ip_addr_t remote_ip, local_ip; + u16_t remote_port = 0x100, local_port = 0x101; + struct netif netif; + u32_t exp_rx_calls = 0, exp_rx_bytes = 0, exp_close_calls = 0, exp_oos_pbufs = 0, exp_oos_tcplen = 0; + int first_dropped = 0xff; + int last_dropped = 0; + + for(i = 0; i < sizeof(data_full_wnd); i++) { + data_full_wnd[i] = (char)i; + } + + /* initialize local vars */ + memset(&netif, 0, sizeof(netif)); + IP4_ADDR(&local_ip, 192, 168, 1, 1); + IP4_ADDR(&remote_ip, 192, 168, 1, 2); + /* initialize counter struct */ + memset(&counters, 0, sizeof(counters)); + counters.expected_data_len = TCP_WND; + counters.expected_data = data_full_wnd; + + /* create and initialize the pcb */ + pcb = test_tcp_new_counters_pcb(&counters); + EXPECT_RET(pcb != NULL); + tcp_set_state(pcb, ESTABLISHED, &local_ip, &remote_ip, local_port, remote_port); + pcb->rcv_nxt = 0x8000; + + /* create segments */ + p = tcp_create_rx_segment(pcb, &data_full_wnd[0], TCP_MSS, 0, 0, TCP_ACK); + p_normal_fin = tcp_create_rx_segment(pcb, NULL, 0, TCP_MSS, 0, TCP_ACK|TCP_FIN); + k = 1; + p_data_after_fin = tcp_create_rx_segment(pcb, &data_full_wnd[TCP_MSS+1], k, TCP_MSS+1, 0, TCP_ACK); + p_2nd_fin_ooseq = tcp_create_rx_segment(pcb, NULL, 0, TCP_MSS+1+k, 0, TCP_ACK|TCP_FIN); + + if(delay_packet & 1) { + /* drop normal data */ + first_dropped = 1; + last_dropped = 1; + } else { + /* send normal data */ + test_tcp_input(p, &netif); + exp_rx_calls++; + exp_rx_bytes += TCP_MSS; + } + /* check if counters are as expected */ + check_rx_counters(pcb, &counters, exp_close_calls, exp_rx_calls, exp_rx_bytes, 0, exp_oos_pbufs, exp_oos_tcplen); + + if(delay_packet & 2) { + /* drop FIN */ + if(first_dropped > 2) { + first_dropped = 2; + } + last_dropped = 2; + } else { + /* send FIN */ + test_tcp_input(p_normal_fin, &netif); + if (first_dropped < 2) { + /* already dropped packets, this one is ooseq */ + exp_oos_pbufs++; + exp_oos_tcplen++; + } else { + /* inseq */ + exp_close_calls++; + } + } + /* check if counters are as expected */ + check_rx_counters(pcb, &counters, exp_close_calls, exp_rx_calls, exp_rx_bytes, 0, exp_oos_pbufs, exp_oos_tcplen); + + if(delay_packet & 4) { + /* drop data-after-FIN */ + if(first_dropped > 3) { + first_dropped = 3; + } + last_dropped = 3; + } else { + /* send data-after-FIN */ + test_tcp_input(p_data_after_fin, &netif); + if (first_dropped < 3) { + /* already dropped packets, this one is ooseq */ + if (delay_packet & 2) { + /* correct FIN was ooseq */ + exp_oos_pbufs++; + exp_oos_tcplen += k; + } + } else { + /* inseq: no change */ + } + } + /* check if counters are as expected */ + check_rx_counters(pcb, &counters, exp_close_calls, exp_rx_calls, exp_rx_bytes, 0, exp_oos_pbufs, exp_oos_tcplen); + + if(delay_packet & 8) { + /* drop 2nd-FIN */ + if(first_dropped > 4) { + first_dropped = 4; + } + last_dropped = 4; + } else { + /* send 2nd-FIN */ + test_tcp_input(p_2nd_fin_ooseq, &netif); + if (first_dropped < 3) { + /* already dropped packets, this one is ooseq */ + if (delay_packet & 2) { + /* correct FIN was ooseq */ + exp_oos_pbufs++; + exp_oos_tcplen++; + } + } else { + /* inseq: no change */ + } + } + /* check if counters are as expected */ + check_rx_counters(pcb, &counters, exp_close_calls, exp_rx_calls, exp_rx_bytes, 0, exp_oos_pbufs, exp_oos_tcplen); + + if(delay_packet & 1) { + /* dropped normal data before */ + test_tcp_input(p, &netif); + exp_rx_calls++; + exp_rx_bytes += TCP_MSS; + if((delay_packet & 2) == 0) { + /* normal FIN was NOT delayed */ + exp_close_calls++; + exp_oos_pbufs = exp_oos_tcplen = 0; + } + } + /* check if counters are as expected */ + check_rx_counters(pcb, &counters, exp_close_calls, exp_rx_calls, exp_rx_bytes, 0, exp_oos_pbufs, exp_oos_tcplen); + + if(delay_packet & 2) { + /* dropped normal FIN before */ + test_tcp_input(p_normal_fin, &netif); + exp_close_calls++; + exp_oos_pbufs = exp_oos_tcplen = 0; + } + /* check if counters are as expected */ + check_rx_counters(pcb, &counters, exp_close_calls, exp_rx_calls, exp_rx_bytes, 0, exp_oos_pbufs, exp_oos_tcplen); + + if(delay_packet & 4) { + /* dropped data-after-FIN before */ + test_tcp_input(p_data_after_fin, &netif); + } + /* check if counters are as expected */ + check_rx_counters(pcb, &counters, exp_close_calls, exp_rx_calls, exp_rx_bytes, 0, exp_oos_pbufs, exp_oos_tcplen); + + if(delay_packet & 8) { + /* dropped 2nd-FIN before */ + test_tcp_input(p_2nd_fin_ooseq, &netif); + } + /* check if counters are as expected */ + check_rx_counters(pcb, &counters, exp_close_calls, exp_rx_calls, exp_rx_bytes, 0, exp_oos_pbufs, exp_oos_tcplen); + + /* check that ooseq data has been dumped */ + EXPECT(pcb->ooseq == NULL); + + /* make sure the pcb is freed */ + EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 1); + tcp_abort(pcb); + EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 0); +} + +/** create multiple segments and pass them to tcp_input with the first segment missing + * to simulate overruning the rxwin with ooseq queueing enabled */ +#define FIN_TEST(name, num) \ + START_TEST(name) \ + { \ + LWIP_UNUSED_ARG(_i); \ + test_tcp_recv_ooseq_double_FINs(num); \ + } \ + END_TEST +FIN_TEST(test_tcp_recv_ooseq_double_FIN_0, 0) +FIN_TEST(test_tcp_recv_ooseq_double_FIN_1, 1) +FIN_TEST(test_tcp_recv_ooseq_double_FIN_2, 2) +FIN_TEST(test_tcp_recv_ooseq_double_FIN_3, 3) +FIN_TEST(test_tcp_recv_ooseq_double_FIN_4, 4) +FIN_TEST(test_tcp_recv_ooseq_double_FIN_5, 5) +FIN_TEST(test_tcp_recv_ooseq_double_FIN_6, 6) +FIN_TEST(test_tcp_recv_ooseq_double_FIN_7, 7) +FIN_TEST(test_tcp_recv_ooseq_double_FIN_8, 8) +FIN_TEST(test_tcp_recv_ooseq_double_FIN_9, 9) +FIN_TEST(test_tcp_recv_ooseq_double_FIN_10, 10) +FIN_TEST(test_tcp_recv_ooseq_double_FIN_11, 11) +FIN_TEST(test_tcp_recv_ooseq_double_FIN_12, 12) +FIN_TEST(test_tcp_recv_ooseq_double_FIN_13, 13) +FIN_TEST(test_tcp_recv_ooseq_double_FIN_14, 14) +FIN_TEST(test_tcp_recv_ooseq_double_FIN_15, 15) + + +/** Create the suite including all tests for this module */ +Suite * +tcp_oos_suite(void) +{ + TFun tests[] = { + test_tcp_recv_ooseq_FIN_OOSEQ, + test_tcp_recv_ooseq_FIN_INSEQ, + test_tcp_recv_ooseq_overrun_rxwin, + test_tcp_recv_ooseq_max_bytes, + test_tcp_recv_ooseq_max_pbufs, + test_tcp_recv_ooseq_double_FIN_0, + test_tcp_recv_ooseq_double_FIN_1, + test_tcp_recv_ooseq_double_FIN_2, + test_tcp_recv_ooseq_double_FIN_3, + test_tcp_recv_ooseq_double_FIN_4, + test_tcp_recv_ooseq_double_FIN_5, + test_tcp_recv_ooseq_double_FIN_6, + test_tcp_recv_ooseq_double_FIN_7, + test_tcp_recv_ooseq_double_FIN_8, + test_tcp_recv_ooseq_double_FIN_9, + test_tcp_recv_ooseq_double_FIN_10, + test_tcp_recv_ooseq_double_FIN_11, + test_tcp_recv_ooseq_double_FIN_12, + test_tcp_recv_ooseq_double_FIN_13, + test_tcp_recv_ooseq_double_FIN_14, + test_tcp_recv_ooseq_double_FIN_15 + }; + return create_suite("TCP_OOS", tests, sizeof(tests)/sizeof(TFun), tcp_oos_setup, tcp_oos_teardown); +} diff --git a/src/lwip-1.4.1/test/unit/tcp/test_tcp_oos.h b/src/lwip-1.4.1/test/unit/tcp/test_tcp_oos.h new file mode 100644 index 0000000..5e411f0 --- /dev/null +++ b/src/lwip-1.4.1/test/unit/tcp/test_tcp_oos.h @@ -0,0 +1,8 @@ +#ifndef __TEST_TCP_OOS_H__ +#define __TEST_TCP_OOS_H__ + +#include "../lwip_check.h" + +Suite *tcp_oos_suite(void); + +#endif diff --git a/src/lwip-1.4.1/test/unit/udp/test_udp.c b/src/lwip-1.4.1/test/unit/udp/test_udp.c new file mode 100644 index 0000000..a2f02af --- /dev/null +++ b/src/lwip-1.4.1/test/unit/udp/test_udp.c @@ -0,0 +1,68 @@ +#include "test_udp.h" + +#include "lwip/udp.h" +#include "lwip/stats.h" + +#if !LWIP_STATS || !UDP_STATS || !MEMP_STATS +#error "This tests needs UDP- and MEMP-statistics enabled" +#endif + +/* Helper functions */ +static void +udp_remove_all(void) +{ + struct udp_pcb *pcb = udp_pcbs; + struct udp_pcb *pcb2; + + while(pcb != NULL) { + pcb2 = pcb; + pcb = pcb->next; + udp_remove(pcb2); + } + fail_unless(lwip_stats.memp[MEMP_UDP_PCB].used == 0); +} + +/* Setups/teardown functions */ + +static void +udp_setup(void) +{ + udp_remove_all(); +} + +static void +udp_teardown(void) +{ + udp_remove_all(); +} + + +/* Test functions */ + +START_TEST(test_udp_new_remove) +{ + struct udp_pcb* pcb; + LWIP_UNUSED_ARG(_i); + + fail_unless(lwip_stats.memp[MEMP_UDP_PCB].used == 0); + + pcb = udp_new(); + fail_unless(pcb != NULL); + if (pcb != NULL) { + fail_unless(lwip_stats.memp[MEMP_UDP_PCB].used == 1); + udp_remove(pcb); + fail_unless(lwip_stats.memp[MEMP_UDP_PCB].used == 0); + } +} +END_TEST + + +/** Create the suite including all tests for this module */ +Suite * +udp_suite(void) +{ + TFun tests[] = { + test_udp_new_remove, + }; + return create_suite("UDP", tests, sizeof(tests)/sizeof(TFun), udp_setup, udp_teardown); +} diff --git a/src/lwip-1.4.1/test/unit/udp/test_udp.h b/src/lwip-1.4.1/test/unit/udp/test_udp.h new file mode 100644 index 0000000..9335368 --- /dev/null +++ b/src/lwip-1.4.1/test/unit/udp/test_udp.h @@ -0,0 +1,8 @@ +#ifndef __TEST_UDP_H__ +#define __TEST_UDP_H__ + +#include "../lwip_check.h" + +Suite* udp_suite(void); + +#endif diff --git a/src/src/ecm_main.c b/src/src/ecm_main.c new file mode 100644 index 0000000..9799fff --- /dev/null +++ b/src/src/ecm_main.c @@ -0,0 +1,222 @@ +#include "usb_device.h" +static struct netif netif_data; +static uint8_t hwaddr[6] = {0x20,0x89,0x84,0x6A,0x96,0x00}; +static uint8_t ipaddr[4] = {192, 168, 7, 1}; +static uint8_t netmask[4] = {255, 255, 255, 0}; +static uint8_t gateway[4] = {0, 0, 0, 0}; +static struct pbuf *received_frame; + +static dhcp_entry_t entries[] = +{ + /* mac ip address subnet mask lease time */ + { {0}, {192, 168, 7, 2}, {255, 255, 255, 0}, 24 * 60 * 60 }, + { {0}, {192, 168, 7, 3}, {255, 255, 255, 0}, 24 * 60 * 60 }, + { {0}, {192, 168, 7, 4}, {255, 255, 255, 0}, 24 * 60 * 60 } +}; + +static dhcp_config_t dhcp_config = +{ + {192, 168, 7, 1}, 67, /* server address, port */ + {192, 168, 7, 1}, /* dns server */ + "stm", /* dns suffix */ + sizeof(entries) / sizeof(*entries), /* num entry */ + entries /* entries */ +}; + +/* this function is called by usbd_ecm.c during an ISR; it must not block */ +void usb_ecm_recv_callback(const uint8_t *data, int size) +{ + if (received_frame) + return; + + received_frame = pbuf_alloc(PBUF_RAW, size, PBUF_POOL); + if (!received_frame) + { + usb_ecm_recv_renew(); + return; + } + + memcpy(received_frame->payload, data, size); + received_frame->len = size; +} + +uint32_t sys_now() +{ + return (uint32_t)mtime(); +} + +TIMER_PROC(tcp_timer, TCP_TMR_INTERVAL, 1, NULL) +{ + tcp_tmr(); +} + +err_t output_fn(struct netif *netif, struct pbuf *p, ip_addr_t *ipaddr) +{ + return etharp_output(netif, p, ipaddr); +} + +err_t linkoutput_fn(struct netif *netif, struct pbuf *p) +{ + int i; + for (i = 0; i < 200; i++) + { + if (usb_ecm_can_xmit()) goto ready; + msleep(1); + } + return ERR_USE; +ready: + usb_ecm_xmit_packet(p); + return ERR_OK; +} + +err_t netif_init_cb(struct netif *netif) +{ + LWIP_ASSERT("netif != NULL", (netif != NULL)); + netif->mtu = ECM_MTU; + netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP | NETIF_FLAG_UP; + netif->state = NULL; + netif->name[0] = 'E'; + netif->name[1] = 'X'; + netif->linkoutput = linkoutput_fn; + netif->output = output_fn; + return ERR_OK; +} + +#define PADDR(ptr) ((ip_addr_t *)ptr) + +static void init_lwip() +{ + struct netif *netif = &netif_data; + + lwip_init(); + netif->hwaddr_len = 6; + memcpy(netif->hwaddr, hwaddr, 6); + + netif = netif_add(netif, PADDR(ipaddr), PADDR(netmask), PADDR(gateway), NULL, netif_init_cb, ip_input); + netif_set_default(netif); + + stmr_add(&tcp_timer); +} + + +bool dns_query_proc(const char *name, ip_addr_t *addr) +{ + if (strcmp(name, "run.stm") == 0 || strcmp(name, "www.run.stm") == 0) + { + addr->addr = *(uint32_t *)ipaddr; + return true; + } + return false; +} + + +/* +const char *state_cgi_handler(int index, int n_params, char *params[], char *values[]) +{ + return "/state.shtml"; +} + +bool alpha = false; +bool bravo = false; +bool charlie = false; + +const char *ctl_cgi_handler(int index, int n_params, char *params[], char *values[]) +{ + int i; + for (i = 0; i < n_params; i++) + { + if (strcmp(params[i], "a") == 0) alpha = *values[i] == '1'; + if (strcmp(params[i], "b") == 0) bravo = *values[i] == '1'; + if (strcmp(params[i], "c") == 0) charlie = *values[i] == '1'; + } + + return "/state.shtml"; +} +*/ + +// static const char *ssi_tags_table[] = +// { +// "systick", /* 0 */ +// "alpha", /* 1 */ +// "bravo", /* 2 */ +// "charlie" /* 3 */ +//}; + +/* +static const tCGI cgi_uri_table[] = +{ + { "/state.cgi", state_cgi_handler }, + { "/ctl.cgi", ctl_cgi_handler }, +}; +*/ + +//static u16_t ssi_handler(int index, char *insert, int ins_len) +//{ + // int res; + + // if (ins_len < 32) return 0; + +// switch (index) +// { +// case 0: /* systick */ +// res = snprintf(insert, ins_len, "%u", (unsigned)mtime()); +// break; +// case 1: /* alpha */ +// *insert = '0' + (alpha & 1); +// res = 1; +// break; +// case 2: /* bravo */ +// *insert = '0' + (bravo & 1); +// res = 1; +// break; +// case 3: /* charlie */ +// *insert = '0' + (charlie & 1); +// res = 1; +// break; +// } + +// return res; +//} + +static void service_traffic(void) +{ + struct pbuf *frame; + + /* retrieve and clear var set by usb_ecm_recv_callback() in ISR */ + __disable_irq(); + frame = received_frame; + received_frame = NULL; + __enable_irq(); + + if (!frame) + return; /* no packet was received */ + + /* packet was received, so handle it */ + ethernet_input(frame, &netif_data); + pbuf_free(frame); + + /* tell usbd_ecm.c it is OK to receive another packet */ + usb_ecm_recv_renew(); +} + +void ecm_main_init() +{ + time_init(); + init_lwip(); + + while (!netif_is_up(&netif_data)); + + while (dhserv_init(&dhcp_config) != ERR_OK); + + while (dnserv_init(PADDR(ipaddr), 53, dns_query_proc) != ERR_OK); + + //http_set_cgi_handlers(cgi_uri_table, sizeof(cgi_uri_table) / sizeof(*cgi_uri_table)); + //http_set_ssi_handler(ssi_handler, ssi_tags_table, sizeof(ssi_tags_table) / sizeof(*ssi_tags_table)); + // httpd_init(); +} + +void ecm_main_loop() +{ + service_traffic(); + stmr(); +} diff --git a/src/src/ecm_main.h b/src/src/ecm_main.h new file mode 100644 index 0000000..57f4a1b --- /dev/null +++ b/src/src/ecm_main.h @@ -0,0 +1,17 @@ +/* + * ecm_main.h + * + * Created on: May 6, 2020 + * Author: Administrator + */ + +#ifndef ECM_MAIN_H_ +#define ECM_MAIN_H_ + +void ecm_main_init();//初始化ecm_main,再main.c中调用 + +void ecm_main_loop();//循环调用,处理lwip包 + + + +#endif /* ECM_MAIN_H_ */ diff --git a/src/src/ecmhelper.h b/src/src/ecmhelper.h new file mode 100644 index 0000000..7ac44f4 --- /dev/null +++ b/src/src/ecmhelper.h @@ -0,0 +1,137 @@ +/* + USB descriptor macros for CDC-ECM + + Copyright (C) 2015,2016,2018 Peter Lawrence + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#ifndef __ECM_HELPER_H +#define __ECM_HELPER_H + +#include +#include "usbhelper.h" +#include "usbd_conf.h" + +//#define ECM_MAX_SEGMENT_SIZE 1514 +//调小以编译通过 +#define ECM_MAX_SEGMENT_SIZE 514 +struct ecm_interface +{ + struct interface_descriptor ctl_interface; + struct cdc_functional_descriptor_header cdc_ecm_header; + struct cdc_union_functional_descriptor cdc_ecm_union; + struct cdc_enet_functional_descriptor cdc_ecm_functional; + struct endpoint_descriptor ctl_ep; + struct interface_descriptor dat_interface; + struct endpoint_descriptor ep_in; + struct endpoint_descriptor ep_out; +}; + +/* macro to help generate CDC ECM USB descriptors */ + +#define ECM_DESCRIPTOR(NOTIFY_ITF, DATA_ITF, NOTIFY_EP, DATAOUT_EP, DATAIN_EP, IMAC_STRING) \ + { \ + .ctl_interface = { \ + /*Interface Descriptor */ \ + .bLength = sizeof(struct interface_descriptor), /* Interface Descriptor size */ \ + .bDescriptorType = USB_DESC_TYPE_INTERFACE, /* Interface */ \ + .bInterfaceNumber = NOTIFY_ITF, /* Number of Interface */ \ + .bAlternateSetting = 0x00, /* Alternate setting */ \ + .bNumEndpoints = 0x01, /* One endpoints used */ \ + .bInterfaceClass = 0x02, /* Communication Interface Class */ \ + .bInterfaceSubclass = 0x06, /* Ethernet Control Model */ \ + .bInterfaceProtocol = 0x00, /* No specific protocol */ \ + .iInterface = 0x00, \ + }, \ + \ + .cdc_ecm_header = { \ + /*Header Functional Descriptor*/ \ + .bFunctionLength = sizeof(struct cdc_functional_descriptor_header), /* bLength: Endpoint Descriptor size */ \ + .bDescriptorType = 0x24, /* bDescriptorType: CS_INTERFACE */ \ + .bDescriptorSubtype = 0x00, /* bDescriptorSubtype: Header Func Desc */ \ + .bcdCDC = USB_UINT16(0x0120), /* bcdCDC: spec release number */ \ + }, \ + \ + .cdc_ecm_union = { \ + /*Union Functional Descriptor*/ \ + .bFunctionLength = sizeof(struct cdc_union_functional_descriptor), \ + .bDescriptorType = 0x24, /* CS_INTERFACE */ \ + .bDescriptorSubtype = 0x06, /* Union func desc */ \ + .bMasterInterface = NOTIFY_ITF, /* Notify interface */ \ + .bSlaveInterface0 = DATA_ITF, /* Data Interface */ \ + }, \ + \ + .cdc_ecm_functional = { \ + /*Ethernet Networking Functional Descriptor*/ \ + .bFunctionLength = sizeof(struct cdc_enet_functional_descriptor), \ + .bDescriptorType = 0x24, /* CS_INTERFACE */ \ + .bDescriptorSubtype = 0x0F, /* Ethernet Networking */ \ + .iMACAddress = IMAC_STRING, /* mandatory string providing MAC address */ \ + .bmEthernetStatistics = {0,0,0,0}, \ + .wMaxSegmentSize = USB_UINT16(ECM_MAX_SEGMENT_SIZE), /* in bytes, usually 1514 */ \ + .wMCFilters = USB_UINT16(0), /* no filters */ \ + .bNumberPowerFilters = 0, /* no filters */ \ + }, \ + \ + .ctl_ep = { \ + /* Notify Endpoint Descriptor*/ \ + .bLength = sizeof(struct endpoint_descriptor), /* Endpoint Descriptor size */ \ + .bDescriptorType = USB_DESC_TYPE_ENDPOINT, /* Endpoint */ \ + .bEndpointAddress = NOTIFY_EP, \ + .bmAttributes = 0x03, /* Interrupt */ \ + .wMaxPacketSize = USB_UINT16(ECM_NOTIFICATION_IN_SZ), \ + .bInterval = 0xFF, \ + }, \ + \ + .dat_interface = { \ + /*Data class interface descriptor*/ \ + .bLength = sizeof(struct interface_descriptor), /* Endpoint Descriptor size */ \ + .bDescriptorType = USB_DESC_TYPE_INTERFACE, \ + .bInterfaceNumber = DATA_ITF, /* Number of Interface */ \ + .bAlternateSetting = 0x00, /* Alternate setting */ \ + .bNumEndpoints = 0x02, /* Two endpoints used */ \ + .bInterfaceClass = 0x0A, /* CDC */ \ + .bInterfaceSubclass = 0x00, \ + .bInterfaceProtocol = 0x00, \ + .iInterface = 0x00, \ + }, \ + \ + .ep_in = { \ + /* Data Endpoint IN Descriptor*/ \ + .bLength = sizeof(struct endpoint_descriptor), /* Endpoint Descriptor size */ \ + .bDescriptorType = USB_DESC_TYPE_ENDPOINT, /* Endpoint */ \ + .bEndpointAddress = DATAIN_EP, \ + .bmAttributes = 0x02, /* Bulk */ \ + .wMaxPacketSize = USB_UINT16(ECM_DATA_OUT_SZ), \ + .bInterval = 0x00 /* ignore for Bulk transfer */ \ + }, \ + \ + .ep_out = { \ + /* Data Endpoint OUT Descriptor */ \ + .bLength = sizeof(struct endpoint_descriptor), /* Endpoint Descriptor size */ \ + .bDescriptorType = USB_DESC_TYPE_ENDPOINT, /* Endpoint */ \ + .bEndpointAddress = DATAOUT_EP, \ + .bmAttributes = 0x02, /* Bulk */ \ + .wMaxPacketSize = USB_UINT16(ECM_DATA_IN_SZ), \ + .bInterval = 0x00, /* ignore for Bulk transfer */ \ + }, \ + }, + +#endif /* __ECM_HELPER_H */ diff --git a/src/src/time.c b/src/src/time.c new file mode 100644 index 0000000..adc5467 --- /dev/null +++ b/src/src/time.c @@ -0,0 +1,156 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015 by Sergey Fetisov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/* + * version: 1.0 demo (7.02.2015) + */ + +#include "time.h" + +volatile uint32_t sysTimeTicks; +volatile uint32_t sysTimeDelayCounter; + +void time_init(void) +{ +// if (SysTick_Config(SystemCoreClock / 1000)) +// while (1) {} /* Capture error */ +} + +//volatile uint32_t msAddition = 0; + +//void SysTick_Handler(void) +//{ + // msAddition++; /* +1 ms */ +//} + + +uint32_t mtime(void) +{ + /* + uint32_t ctrl; + static int32_t res; + uint32_t ticks; + + ctrl = SysTick->CTRL; + +read: + ticks = SysTick->VAL; + res = msAddition; + ctrl = SysTick->CTRL; + if (ctrl & SysTick_CTRL_COUNTFLAG_Msk) + goto read; + */ + return HAL_GetTick(); +} + +void msleep(int ms) +{ + uint32_t t = mtime(); + while (true) + { + uint32_t t1 = mtime(); + if (t1 - t >= ms) break; + if (t1 < t) break; /* overflow */ + } +} + +static stmr_t *stmrs = NULL; + +void stmr(void) +{ + stmr_t *tmr; + uint32_t time; + time = mtime(); + tmr = stmrs; + while (tmr != NULL) + { + stmr_t *t; + uint32_t elapsed; + t = tmr; + tmr = tmr->next; + if ((t->flags & STMR_ACTIVE) == 0) + continue; + elapsed = time; + elapsed -= t->event; + if (elapsed < t->period) + continue; + t->proc(t); + t->event = mtime(); + } +} + +void stmr_init(stmr_t *tmr) +{ + tmr->period = 0; + tmr->event = 0; + tmr->flags = 0; + tmr->data = NULL; + tmr->proc = NULL; + tmr->next = stmrs; + stmrs = tmr; +} + +void stmr_add(stmr_t *tmr) +{ + tmr->next = stmrs; + stmrs = tmr; +} + +void stmr_free(stmr_t *tmr) +{ + stmr_t *t; + + if (stmrs == NULL) + return; + + if (tmr == stmrs) + { + stmrs = tmr->next; + tmr->next = NULL; + return; + } + + t = stmrs; + while (t->next != NULL) + { + if (t->next == tmr) + { + t->next = tmr->next; + tmr->next = NULL; + return; + } + t = t->next; + } +} + +void stmr_stop(stmr_t *tmr) +{ + tmr->flags &= ~(uint32_t)STMR_ACTIVE; +} + +void stmr_run(stmr_t *tmr) +{ + tmr->flags |= STMR_ACTIVE; + tmr->event = mtime(); +} diff --git a/src/src/time.h b/src/src/time.h new file mode 100644 index 0000000..5d61eeb --- /dev/null +++ b/src/src/time.h @@ -0,0 +1,87 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015 by Sergey Fetisov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/* + * version: 1.0 demo (7.02.2015) + */ + +#ifndef SYSTEMTIME +#define SYSTEMTIME + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* general functions */ + +void time_init(void); /* time module initialization */ +uint32_t mtime(void); /* monotonic time with 1 ms precision */ +void msleep(int ms); /* sleep to n ms */ + +/* softeare timer types */ + +typedef struct stmr stmr_t; + +typedef void (*stmr_cb_t)(stmr_t *tmr); + +#define STMR_ACTIVE 1 + +struct stmr +{ + uint32_t period; /* timer period, ms. */ + uint32_t event; /* the last event, ms */ + uint32_t flags; /* STMR_XXX */ + void *data; /* user data */ + stmr_cb_t proc; /* timer proc */ + stmr_t *next; /* don't touch it */ +}; + +/* softeare timer functions */ + +void stmr(void); /* call it periodically */ +void stmr_init(stmr_t *tmr); /* init timer and adds to list */ +void stmr_add(stmr_t *tmr); /* adds timer to a timers list */ +void stmr_free(stmr_t *tmr); /* remove timer from the list */ +void stmr_stop(stmr_t *tmr); /* deactivate timer */ +void stmr_run(stmr_t *tmr); /* activate timer */ + +#define TIMER_PROC(name, period, active, data) \ +void name##_proc(stmr_t *tmr); \ +static stmr_t name = \ +{ \ + period, 0, active, data, \ + name##_proc, NULL \ +}; \ +void name##_proc(stmr_t *tmr) + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/src/usb_device.c b/src/src/usb_device.c new file mode 100644 index 0000000..b4eab87 --- /dev/null +++ b/src/src/usb_device.c @@ -0,0 +1,101 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file : usb_device.c + * @version : v2.0_Cube + * @brief : This file implements the USB Device + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2020 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Includes ------------------------------------------------------------------*/ + +#include "usb_device.h" +#include "usbd_core.h" +#include "usbd_desc.h" +#include "usbd_ecm.h" + +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +/* USER CODE BEGIN PV */ +/* Private variables ---------------------------------------------------------*/ + +/* USER CODE END PV */ + +/* USER CODE BEGIN PFP */ +/* Private function prototypes -----------------------------------------------*/ + +/* USER CODE END PFP */ + +/* USB Device Core handle declaration. */ +USBD_HandleTypeDef hUsbDeviceFS; + +/* + * -- Insert your variables declaration here -- + */ +/* USER CODE BEGIN 0 */ + +/* USER CODE END 0 */ + +/* + * -- Insert your external function declaration here -- + */ +/* USER CODE BEGIN 1 */ + +/* USER CODE END 1 */ + +/** + * Init USB device Library, add supported class and start the library + * @retval None + */ +void MX_USB_DEVICE_Init(void) +{ + /* USER CODE BEGIN USB_DEVICE_Init_PreTreatment */ + + /* USER CODE END USB_DEVICE_Init_PreTreatment */ + + /* Init Device Library, add supported class and start the library. */ + if (USBD_Init(&hUsbDeviceFS, &VCP_Desc, 0) != USBD_OK) + { + Error_Handler(); + } + if (USBD_RegisterClass(&hUsbDeviceFS, &USBD_ECM) != USBD_OK) + { + Error_Handler(); + } + if (USBD_ECM_RegisterInterface(&hUsbDeviceFS) != USBD_OK) + { + Error_Handler(); + } + if (USBD_Start(&hUsbDeviceFS) != USBD_OK) + { + Error_Handler(); + } + + /* USER CODE BEGIN USB_DEVICE_Init_PostTreatment */ + + /* USER CODE END USB_DEVICE_Init_PostTreatment */ +} + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/src/src/usb_device.h b/src/src/usb_device.h new file mode 100644 index 0000000..da43669 --- /dev/null +++ b/src/src/usb_device.h @@ -0,0 +1,130 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file : usb_device.h + * @version : v2.0_Cube + * @brief : Header for usb_device.c file. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2020 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __USB_DEVICE__H__ +#define __USB_DEVICE__H__ + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f0xx.h" +#include "stm32f0xx_hal.h" +#include "usbd_def.h" + +#include +#include +#include +#include "usbd_ecm.h" +#include "usbd_desc.h" +#include "usbd_conf.h" +#include "netif/etharp.h" +#include "lwip/init.h" +#include "lwip/netif.h" +#include "lwip/pbuf.h" +#include "lwip/icmp.h" +#include "lwip/udp.h" +#include "lwip/opt.h" +#include "lwip/arch.h" +#include "lwip/api.h" +#include "lwip/inet.h" +#include "lwip/dns.h" +#include "lwip/tcp_impl.h" +#include "lwip/tcp.h" +#include "time.h" +#include "httpd.h" +#include "dhserver.h" +#include "dnserver.h" +#include "ecm_main.h" + +/* USER CODE BEGIN INCLUDE */ + +/* USER CODE END INCLUDE */ + +/** @addtogroup USBD_OTG_DRIVER + * @{ + */ + +/** @defgroup USBD_DEVICE USBD_DEVICE + * @brief Device file for Usb otg low level driver. + * @{ + */ + +/** @defgroup USBD_DEVICE_Exported_Variables USBD_DEVICE_Exported_Variables + * @brief Public variables. + * @{ + */ + +/* Private variables ---------------------------------------------------------*/ +/* USER CODE BEGIN PV */ + +/* USER CODE END PV */ + +/* Private function prototypes -----------------------------------------------*/ +/* USER CODE BEGIN PFP */ + +/* USER CODE END PFP */ + +/* + * -- Insert your variables declaration here -- + */ +/* USER CODE BEGIN VARIABLES */ + +/* USER CODE END VARIABLES */ +/** + * @} + */ + +/** @defgroup USBD_DEVICE_Exported_FunctionsPrototype USBD_DEVICE_Exported_FunctionsPrototype + * @brief Declaration of public functions for Usb device. + * @{ + */ + +/** USB Device initialization function. */ +void MX_USB_DEVICE_Init(void); + +/* + * -- Insert functions declaration here -- + */ +/* USER CODE BEGIN FD */ + +/* USER CODE END FD */ +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __USB_DEVICE__H__ */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/src/src/usbd_conf.c b/src/src/usbd_conf.c new file mode 100644 index 0000000..1d24252 --- /dev/null +++ b/src/src/usbd_conf.c @@ -0,0 +1,442 @@ +/** + ****************************************************************************** + * @file USB_Device/CDC_Standalone/Src/usbd_conf.c + * @author MCD Application Team + * @version V1.0.0 + * @date 18-June-2014 + * @brief This file implements the USB Device library callbacks and MSP + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2014 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (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.st.com/software_license_agreement_liberty_v2 + * + * 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. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ + +#include "usbd_core.h" +#include "usbd_ecm.h" +#include "main.h" + +PCD_HandleTypeDef hpcd; /* used externally by stm32f0xx_it.c */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + +/******************************************************************************* + PCD BSP Routines +*******************************************************************************/ + +/** + * @brief Initializes the PCD MSP. + * @param hpcd: PCD handle + * @retval None + */ +#ifndef GPIO_SPEED_HIGH +#define GPIO_SPEED_HIGH GPIO_SPEED_FREQ_HIGH +#endif +void HAL_PCD_MspInit(PCD_HandleTypeDef *hpcd) +{ + GPIO_InitTypeDef GPIO_InitStruct; + + /* Enable the GPIOA clock */ + __HAL_RCC_GPIOA_CLK_ENABLE(); + + /* Configure USB DM and DP pins. + This is optional, and maintained only for user guidance. */ + GPIO_InitStruct.Pin = (GPIO_PIN_11 | GPIO_PIN_12); + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF2_USB; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + /* Enable USB FS Clock */ + __HAL_RCC_USB_CLK_ENABLE(); + + /* Set USB FS Interrupt priority */ + HAL_NVIC_SetPriority(USB_IRQn, 3 /* hard-coded: customize if needed */, 0); + + /* Enable USB FS Interrupt */ + HAL_NVIC_EnableIRQ(USB_IRQn); +} + +/** + * @brief De-Initializes the PCD MSP. + * @param hpcd: PCD handle + * @retval None + */ +void HAL_PCD_MspDeInit(PCD_HandleTypeDef *hpcd) +{ + /* Disable USB FS Clock */ + __HAL_RCC_USB_CLK_DISABLE(); +} + +/******************************************************************************* + LL Driver Callbacks (PCD -> USB Device Library) +*******************************************************************************/ + +/** + * @brief SOF callback. + * @param hpcd: PCD handle + * @retval None + */ +void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd) +{ + USBD_LL_SetupStage(hpcd->pData, (uint8_t *)hpcd->Setup); +} + +/** + * @brief SOF callback. + * @param hpcd: PCD handle + * @param epnum: Endpoint Number + * @retval None + */ +void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) +{ + USBD_LL_DataOutStage(hpcd->pData, epnum, hpcd->OUT_ep[epnum].xfer_buff); +} + +/** + * @brief SOF callback. + * @param hpcd: PCD handle + * @param epnum: Endpoint Number + * @retval None + */ +void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) +{ + USBD_LL_DataInStage(hpcd->pData, epnum, hpcd->IN_ep[epnum].xfer_buff); +} + +/** + * @brief SOF callback. + * @param hpcd: PCD handle + * @retval None + */ +void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd) +{ + USBD_LL_SOF(hpcd->pData); +} + +/** + * @brief SOF callback. + * @param hpcd: PCD handle + * @retval None + */ +void HAL_PCD_ResetCallback(PCD_HandleTypeDef *hpcd) +{ + USBD_LL_SetSpeed(hpcd->pData, USBD_SPEED_FULL); + /* Reset Device */ + USBD_LL_Reset(hpcd->pData); +} + +/** + * @brief SOF callback. + * @param hpcd: PCD handle + * @retval None + */ +void HAL_PCD_SuspendCallback(PCD_HandleTypeDef *hpcd) +{ +} + +/** + * @brief SOF callback. + * @param hpcd: PCD handle + * @retval None + */ +void HAL_PCD_ResumeCallback(PCD_HandleTypeDef *hpcd) +{ +} + +/** + * @brief SOF callback. + * @param hpcd: PCD handle + * @param epnum: Endpoint Number + * @retval None + */ +void HAL_PCD_ISOOUTIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) +{ + USBD_LL_IsoOUTIncomplete(hpcd->pData, epnum); +} + +/** + * @brief SOF callback. + * @param hpcd: PCD handle + * @param epnum: Endpoint Number + * @retval None + */ +void HAL_PCD_ISOINIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) +{ + USBD_LL_IsoINIncomplete(hpcd->pData, epnum); +} + +/** + * @brief SOF callback. + * @param hpcd: PCD handle + * @retval None + */ +void HAL_PCD_ConnectCallback(PCD_HandleTypeDef *hpcd) +{ + USBD_LL_DevConnected(hpcd->pData); +} + +/** + * @brief SOF callback. + * @param hpcd: PCD handle + * @retval None + */ +void HAL_PCD_DisconnectCallback(PCD_HandleTypeDef *hpcd) +{ + USBD_LL_DevDisconnected(hpcd->pData); +} + +/******************************************************************************* + LL Driver Interface (USB Device Library --> PCD) +*******************************************************************************/ + +/** + * @brief Initializes the Low Level portion of the Device driver. + * @param pdev: Device handle + * @retval USBD Status + */ +USBD_StatusTypeDef USBD_LL_Init(USBD_HandleTypeDef *pdev) +{ + uint32_t pma_address; + + /* Set LL Driver parameters */ + hpcd.Instance = USB; + hpcd.Init.ep0_mps = 0x40; + hpcd.Init.phy_itface = PCD_PHY_EMBEDDED; + hpcd.Init.speed = PCD_SPEED_FULL; + /* Link The driver to the stack */ + hpcd.pData = pdev; + pdev->pData = &hpcd; + /* Initialize LL Driver */ + HAL_PCD_Init(pdev->pData); + + /* + start address for PMA allocation: + ST's USB stack forces a BTABLE_ADDRESS at the start of PMA memory. The BTABLE occupied 8 bytes per endpoint. + we position the EP buffers starting immediately after this + */ + pma_address = 8 * MAX((sizeof(hpcd.IN_ep) / sizeof(*hpcd.IN_ep)), (sizeof(hpcd.OUT_ep) / sizeof(*hpcd.OUT_ep))); + + /* PMA allocation for EP0 */ + HAL_PCDEx_PMAConfig(pdev->pData, 0x00, PCD_SNG_BUF, pma_address =+ USB_MAX_EP0_SIZE); + HAL_PCDEx_PMAConfig(pdev->pData, 0x80, PCD_SNG_BUF, pma_address =+ USB_MAX_EP0_SIZE); + + /* PMA allocation for other endpoints */ + USBD_ECM_PMAConfig(pdev->pData, &pma_address); + + return USBD_OK; +} + +/** + * @brief De-Initializes the Low Level portion of the Device driver. + * @param pdev: Device handle + * @retval USBD Status + */ +USBD_StatusTypeDef USBD_LL_DeInit(USBD_HandleTypeDef *pdev) +{ + HAL_PCD_DeInit(pdev->pData); + return USBD_OK; +} + +/** + * @brief Starts the Low Level portion of the Device driver. + * @param pdev: Device handle + * @retval USBD Status + */ +USBD_StatusTypeDef USBD_LL_Start(USBD_HandleTypeDef *pdev) +{ + HAL_PCD_Start(pdev->pData); + return USBD_OK; +} + +/** + * @brief Stops the Low Level portion of the Device driver. + * @param pdev: Device handle + * @retval USBD Status + */ +USBD_StatusTypeDef USBD_LL_Stop(USBD_HandleTypeDef *pdev) +{ + HAL_PCD_Stop(pdev->pData); + return USBD_OK; +} + +/** + * @brief Opens an endpoint of the Low Level Driver. + * @param pdev: Device handle + * @param ep_addr: Endpoint Number + * @param ep_type: Endpoint Type + * @param ep_mps: Endpoint Max Packet Size + * @retval USBD Status + */ +USBD_StatusTypeDef USBD_LL_OpenEP(USBD_HandleTypeDef *pdev, + uint8_t ep_addr, + uint8_t ep_type, + uint16_t ep_mps) +{ + HAL_PCD_EP_Open(pdev->pData, + ep_addr, + ep_mps, + ep_type); + + return USBD_OK; +} + +/** + * @brief Closes an endpoint of the Low Level Driver. + * @param pdev: Device handle + * @param ep_addr: Endpoint Number + * @retval USBD Status + */ +USBD_StatusTypeDef USBD_LL_CloseEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr) +{ + HAL_PCD_EP_Close(pdev->pData, ep_addr); + return USBD_OK; +} + +/** + * @brief Flushes an endpoint of the Low Level Driver. + * @param pdev: Device handle + * @param ep_addr: Endpoint Number + * @retval USBD Status + */ +USBD_StatusTypeDef USBD_LL_FlushEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr) +{ + HAL_PCD_EP_Flush(pdev->pData, ep_addr); + return USBD_OK; +} + +/** + * @brief Sets a Stall condition on an endpoint of the Low Level Driver. + * @param pdev: Device handle + * @param ep_addr: Endpoint Number + * @retval USBD Status + */ +USBD_StatusTypeDef USBD_LL_StallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr) +{ + HAL_PCD_EP_SetStall(pdev->pData, ep_addr); + return USBD_OK; +} + +/** + * @brief Clears a Stall condition on an endpoint of the Low Level Driver. + * @param pdev: Device handle + * @param ep_addr: Endpoint Number + * @retval USBD Status + */ +USBD_StatusTypeDef USBD_LL_ClearStallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr) +{ + HAL_PCD_EP_ClrStall(pdev->pData, ep_addr); + return USBD_OK; +} + +/** + * @brief Returns Stall condition. + * @param pdev: Device handle + * @param ep_addr: Endpoint Number + * @retval Stall (1: Yes, 0: No) + */ +uint8_t USBD_LL_IsStallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr) +{ + PCD_HandleTypeDef *hpcd = pdev->pData; + + if((ep_addr & 0x80) == 0x80) + { + return hpcd->IN_ep[ep_addr & 0x7F].is_stall; + } + else + { + return hpcd->OUT_ep[ep_addr & 0x7F].is_stall; + } +} + +/** + * @brief Assigns a USB address to the device. + * @param pdev: Device handle + * @param ep_addr: Endpoint Number + * @retval USBD Status + */ +USBD_StatusTypeDef USBD_LL_SetUSBAddress(USBD_HandleTypeDef *pdev, uint8_t dev_addr) +{ + HAL_PCD_SetAddress(pdev->pData, dev_addr); + return USBD_OK; +} + +/** + * @brief Transmits data over an endpoint. + * @param pdev: Device handle + * @param ep_addr: Endpoint Number + * @param pbuf: Pointer to data to be sent + * @param size: Data size + * @retval USBD Status + */ +USBD_StatusTypeDef USBD_LL_Transmit(USBD_HandleTypeDef *pdev, + uint8_t ep_addr, + uint8_t *pbuf, + uint16_t size) +{ + HAL_StatusTypeDef outcome; + outcome = HAL_PCD_EP_Transmit(pdev->pData, ep_addr, pbuf, size); + return (HAL_OK == outcome) ? USBD_OK : USBD_BUSY; +} + +/** + * @brief Prepares an endpoint for reception. + * @param pdev: Device handle + * @param ep_addr: Endpoint Number + * @param pbuf: Pointer to data to be received + * @param size: Data size + * @retval USBD Status + */ +USBD_StatusTypeDef USBD_LL_PrepareReceive(USBD_HandleTypeDef *pdev, + uint8_t ep_addr, + uint8_t *pbuf, + uint16_t size) +{ + HAL_StatusTypeDef outcome; + outcome = HAL_PCD_EP_Receive(pdev->pData, ep_addr, pbuf, size); + return (HAL_OK == outcome) ? USBD_OK : USBD_BUSY; +} + +/** + * @brief Returns the last transfered packet size. + * @param pdev: Device handle + * @param ep_addr: Endpoint Number + * @retval Recived Data Size + */ +uint32_t USBD_LL_GetRxDataSize(USBD_HandleTypeDef *pdev, uint8_t ep_addr) +{ + return HAL_PCD_EP_GetRxCount(pdev->pData, ep_addr); +} + +/** + * @brief Delays routine for the USB Device Library. + * @param Delay: Delay in ms + * @retval None + */ +void USBD_LL_Delay(uint32_t Delay) +{ + HAL_Delay(Delay); +} + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/src/src/usbd_conf.h b/src/src/usbd_conf.h new file mode 100644 index 0000000..31101b6 --- /dev/null +++ b/src/src/usbd_conf.h @@ -0,0 +1,104 @@ +/** + ****************************************************************************** + * @file USB_Device/CDC_Standalone/Inc/usbd_conf.h + * @author MCD Application Team + * @version V1.0.0 + * @date 18-June-2014 + * @brief General low level driver configuration + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2014 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (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.st.com/software_license_agreement_liberty_v2 + * + * 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. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __USBD_CONF_H +#define __USBD_CONF_H + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" +#include +#include +#include +#include "main.h" +#include "stm32f0xx.h" +#include "stm32f0xx_hal.h" + +#define hpcd hpcd_USB_FS + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ +/* Common Config */ +#define ECM_NOTIFICATION_IN_EP 0x81 +#define ECM_DATA_IN_EP 0x82 +#define ECM_DATA_OUT_EP 0x03 + +#define ECM_NOTIFICATION_IN_SZ 64 +#define ECM_DATA_IN_SZ USB_FS_MAX_PACKET_SIZE +#define ECM_DATA_OUT_SZ USB_FS_MAX_PACKET_SIZE +#ifdef USBD_MAX_NUM_INTERFACES +#undef USBD_MAX_NUM_INTERFACES +#endif +#ifdef USBD_MAX_NUM_CONFIGURATION +#undef USBD_MAX_NUM_CONFIGURATION +#endif +#ifdef USBD_MAX_STR_DESC_SIZ +#undef USBD_MAX_STR_DESC_SIZ +#endif +#ifdef USBD_SELF_POWERED +#undef USBD_SELF_POWERED +#endif +#define USBD_MAX_NUM_INTERFACES 2 /* FIXME: must manually ensure this is 2x NUM_OF_ECM plus any other usage */ +#define USBD_MAX_NUM_CONFIGURATION 1 +#define USBD_MAX_STR_DESC_SIZ 0x100 +#define USBD_SUPPORT_USER_STRING 0 +#define USBD_SELF_POWERED 0 +#define USBD_DEBUG_LEVEL 0 + +/* Exported macro ------------------------------------------------------------*/ +/* Memory management macros */ + +/* DEBUG macros */ +#if (USBD_DEBUG_LEVEL > 0) +#define USBD_UsrLog(...) printf(__VA_ARGS__);\ + printf("\n"); +#else +#define USBD_UsrLog(...) +#endif + +#if (USBD_DEBUG_LEVEL > 1) + +#define USBD_ErrLog(...) printf("ERROR: ") ;\ + printf(__VA_ARGS__);\ + printf("\n"); +#else +#define USBD_ErrLog(...) +#endif + +#if (USBD_DEBUG_LEVEL > 2) +#define USBD_DbgLog(...) printf("DEBUG : ") ;\ + printf(__VA_ARGS__);\ + printf("\n"); +#else +#define USBD_DbgLog(...) +#endif + +/* Exported functions ------------------------------------------------------- */ + +#endif /* __USBD_CONF_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/src/src/usbd_core.c b/src/src/usbd_core.c new file mode 100644 index 0000000..cb25a63 --- /dev/null +++ b/src/src/usbd_core.c @@ -0,0 +1,536 @@ +/** + ****************************************************************************** + * @file usbd_core.c + * @author MCD Application Team + * @version V2.3.0 + * @date 04-November-2014 + * @brief This file provides all the USBD core functions. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT 2014 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (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.st.com/software_license_agreement_liberty_v2 + * + * 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. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_core.h" + +/** @addtogroup STM32_USBD_DEVICE_LIBRARY +* @{ +*/ + + +/** @defgroup USBD_CORE +* @brief usbd core module +* @{ +*/ + +/** @defgroup USBD_CORE_Private_TypesDefinitions +* @{ +*/ +/** +* @} +*/ + + +/** @defgroup USBD_CORE_Private_Defines +* @{ +*/ + +/** +* @} +*/ + + +/** @defgroup USBD_CORE_Private_Macros +* @{ +*/ +/** +* @} +*/ + + + + +/** @defgroup USBD_CORE_Private_FunctionPrototypes +* @{ +*/ + +/** +* @} +*/ + +/** @defgroup USBD_CORE_Private_Variables +* @{ +*/ + +/** +* @} +*/ + +/** @defgroup USBD_CORE_Private_Functions +* @{ +*/ + +/** +* @brief USBD_Init +* Initializes the device stack and load the class driver +* @param pdev: device instance +* @param pdesc: Descriptor structure address +* @param id: Low level core index +* @retval None +*/ +USBD_StatusTypeDef USBD_Init(USBD_HandleTypeDef *pdev, const USBD_DescriptorsTypeDef *pdesc, uint8_t id) +{ + /* Check whether the USB Host handle is valid */ + if(pdev == NULL) + { + USBD_ErrLog("Invalid Device handle"); + return USBD_FAIL; + } + + /* Unlink previous class*/ + if(pdev->pClass != NULL) + { + pdev->pClass = NULL; + } + + /* Assign USBD Descriptors */ + if(pdesc != NULL) + { + pdev->pDesc = pdesc; + } + + /* Set Device initial State */ + pdev->dev_state = USBD_STATE_DEFAULT; + pdev->id = id; + /* Initialize low level driver */ + USBD_LL_Init(pdev); + + return USBD_OK; +} + +/** +* @brief USBD_DeInit +* Re-Initialize th device library +* @param pdev: device instance +* @retval status: status +*/ +USBD_StatusTypeDef USBD_DeInit(USBD_HandleTypeDef *pdev) +{ + /* Set Default State */ + pdev->dev_state = USBD_STATE_DEFAULT; + + /* Free Class Resources */ + pdev->pClass->DeInit(pdev, pdev->dev_config); + + /* Stop the low level driver */ + USBD_LL_Stop(pdev); + + /* Initialize low level driver */ + USBD_LL_DeInit(pdev); + + return USBD_OK; +} + + +/** + * @brief USBD_RegisterClass + * Link class driver to Device Core. + * @param pDevice : Device Handle + * @param pclass: Class handle + * @retval USBD Status + */ +USBD_StatusTypeDef USBD_RegisterClass(USBD_HandleTypeDef *pdev, const USBD_ClassTypeDef *pclass) +{ + USBD_StatusTypeDef status = USBD_OK; + if(pclass != 0) + { + /* link the class to the USB Device handle */ + pdev->pClass = pclass; + status = USBD_OK; + } + else + { + USBD_ErrLog("Invalid Class handle"); + status = USBD_FAIL; + } + + return status; +} + +/** + * @brief USBD_Start + * Start the USB Device Core. + * @param pdev: Device Handle + * @retval USBD Status + */ +USBD_StatusTypeDef USBD_Start (USBD_HandleTypeDef *pdev) +{ + + /* Start the low level driver */ + USBD_LL_Start(pdev); + + return USBD_OK; +} + +/** + * @brief USBD_Stop + * Stop the USB Device Core. + * @param pdev: Device Handle + * @retval USBD Status + */ +USBD_StatusTypeDef USBD_Stop (USBD_HandleTypeDef *pdev) +{ + /* Free Class Resources */ + pdev->pClass->DeInit(pdev, pdev->dev_config); + + /* Stop the low level driver */ + USBD_LL_Stop(pdev); + + return USBD_OK; +} + +/** +* @brief USBD_SetClassConfig +* Configure device and start the interface +* @param pdev: device instance +* @param cfgidx: configuration index +* @retval status +*/ + +USBD_StatusTypeDef USBD_SetClassConfig(USBD_HandleTypeDef *pdev, uint8_t cfgidx) +{ + USBD_StatusTypeDef ret = USBD_FAIL; + + if(pdev->pClass != NULL) + { + /* Set configuration and Start the Class*/ + if(pdev->pClass->Init(pdev, cfgidx) == 0) + { + ret = USBD_OK; + } + } + return ret; +} + +/** +* @brief USBD_ClrClassConfig +* Clear current configuration +* @param pdev: device instance +* @param cfgidx: configuration index +* @retval status: USBD_StatusTypeDef +*/ +USBD_StatusTypeDef USBD_ClrClassConfig(USBD_HandleTypeDef *pdev, uint8_t cfgidx) +{ + /* Clear configuration and De-initialize the Class process*/ + pdev->pClass->DeInit(pdev, cfgidx); + return USBD_OK; +} + + +/** +* @brief USBD_SetupStage +* Handle the setup stage +* @param pdev: device instance +* @retval status +*/ +USBD_StatusTypeDef USBD_LL_SetupStage(USBD_HandleTypeDef *pdev, uint8_t *psetup) +{ + + USBD_ParseSetupRequest(&pdev->request, psetup); + + pdev->ep0_state = USBD_EP0_SETUP; + pdev->ep0_data_len = pdev->request.wLength; + + switch (pdev->request.bmRequest & 0x1F) + { + case USB_REQ_RECIPIENT_DEVICE: + USBD_StdDevReq (pdev, &pdev->request); + break; + + case USB_REQ_RECIPIENT_INTERFACE: + USBD_StdItfReq(pdev, &pdev->request); + break; + + case USB_REQ_RECIPIENT_ENDPOINT: + USBD_StdEPReq(pdev, &pdev->request); + break; + + default: + USBD_LL_StallEP(pdev , pdev->request.bmRequest & 0x80); + break; + } + return USBD_OK; +} + +/** +* @brief USBD_DataOutStage +* Handle data OUT stage +* @param pdev: device instance +* @param epnum: endpoint index +* @retval status +*/ +USBD_StatusTypeDef USBD_LL_DataOutStage(USBD_HandleTypeDef *pdev , uint8_t epnum, uint8_t *pdata) +{ + USBD_EndpointTypeDef *pep; + + if(epnum == 0) + { + pep = &pdev->ep_out[0]; + + if ( pdev->ep0_state == USBD_EP0_DATA_OUT) + { + if(pep->rem_length > pep->maxpacket) + { + pep->rem_length -= pep->maxpacket; + + USBD_CtlContinueRx (pdev, + pdata, + MIN(pep->rem_length ,pep->maxpacket)); + } + else + { + if((pdev->pClass->EP0_RxReady != NULL)&& + (pdev->dev_state == USBD_STATE_CONFIGURED)) + { + pdev->pClass->EP0_RxReady(pdev); + } + USBD_CtlSendStatus(pdev); + } + } + } + else if((pdev->pClass->DataOut != NULL)&& + (pdev->dev_state == USBD_STATE_CONFIGURED)) + { + pdev->pClass->DataOut(pdev, epnum); + } + return USBD_OK; +} + +/** +* @brief USBD_DataInStage +* Handle data in stage +* @param pdev: device instance +* @param epnum: endpoint index +* @retval status +*/ +USBD_StatusTypeDef USBD_LL_DataInStage(USBD_HandleTypeDef *pdev ,uint8_t epnum, uint8_t *pdata) +{ + USBD_EndpointTypeDef *pep; + + if(epnum == 0) + { + pep = &pdev->ep_in[0]; + + if ( pdev->ep0_state == USBD_EP0_DATA_IN) + { + if(pep->rem_length > pep->maxpacket) + { + pep->rem_length -= pep->maxpacket; + + USBD_CtlContinueSendData (pdev, + pdata, + pep->rem_length); + } + else + { /* last packet is MPS multiple, so send ZLP packet */ + if((pep->total_length % pep->maxpacket == 0) && + (pep->total_length >= pep->maxpacket) && + (pep->total_length < pdev->ep0_data_len )) + { + + USBD_CtlContinueSendData(pdev , NULL, 0); + pdev->ep0_data_len = 0; + } + else + { + if((pdev->pClass->EP0_TxSent != NULL)&& + (pdev->dev_state == USBD_STATE_CONFIGURED)) + { + pdev->pClass->EP0_TxSent(pdev); + } + USBD_CtlReceiveStatus(pdev); + } + } + } + } + else if((pdev->pClass->DataIn != NULL)&& + (pdev->dev_state == USBD_STATE_CONFIGURED)) + { + pdev->pClass->DataIn(pdev, epnum); + } + return USBD_OK; +} + +/** +* @brief USBD_LL_Reset +* Handle Reset event +* @param pdev: device instance +* @retval status +*/ + +USBD_StatusTypeDef USBD_LL_Reset(USBD_HandleTypeDef *pdev) +{ + /* Open EP0 OUT */ + USBD_LL_OpenEP(pdev, + 0x00, + USBD_EP_TYPE_CTRL, + USB_MAX_EP0_SIZE); + + pdev->ep_out[0].maxpacket = USB_MAX_EP0_SIZE; + + /* Open EP0 IN */ + USBD_LL_OpenEP(pdev, + 0x80, + USBD_EP_TYPE_CTRL, + USB_MAX_EP0_SIZE); + + pdev->ep_in[0].maxpacket = USB_MAX_EP0_SIZE; + /* Upon Reset call user call back */ + pdev->dev_state = USBD_STATE_DEFAULT; + + if (pdev->pClassData) + pdev->pClass->DeInit(pdev, pdev->dev_config); + + + return USBD_OK; +} + + + + +/** +* @brief USBD_LL_Reset +* Handle Reset event +* @param pdev: device instance +* @retval status +*/ +USBD_StatusTypeDef USBD_LL_SetSpeed(USBD_HandleTypeDef *pdev, USBD_SpeedTypeDef speed) +{ + pdev->dev_speed = speed; + return USBD_OK; +} + +/** +* @brief USBD_Suspend +* Handle Suspend event +* @param pdev: device instance +* @retval status +*/ + +USBD_StatusTypeDef USBD_LL_Suspend(USBD_HandleTypeDef *pdev) +{ + pdev->dev_old_state = pdev->dev_state; + pdev->dev_state = USBD_STATE_SUSPENDED; + return USBD_OK; +} + +/** +* @brief USBD_Resume +* Handle Resume event +* @param pdev: device instance +* @retval status +*/ + +USBD_StatusTypeDef USBD_LL_Resume(USBD_HandleTypeDef *pdev) +{ + pdev->dev_state = pdev->dev_old_state; + return USBD_OK; +} + +/** +* @brief USBD_SOF +* Handle SOF event +* @param pdev: device instance +* @retval status +*/ + +USBD_StatusTypeDef USBD_LL_SOF(USBD_HandleTypeDef *pdev) +{ + if(pdev->dev_state == USBD_STATE_CONFIGURED) + { + if(pdev->pClass->SOF != NULL) + { + pdev->pClass->SOF(pdev); + } + } + return USBD_OK; +} + +/** +* @brief USBD_IsoINIncomplete +* Handle iso in incomplete event +* @param pdev: device instance +* @retval status +*/ +USBD_StatusTypeDef USBD_LL_IsoINIncomplete(USBD_HandleTypeDef *pdev, uint8_t epnum) +{ + return USBD_OK; +} + +/** +* @brief USBD_IsoOUTIncomplete +* Handle iso out incomplete event +* @param pdev: device instance +* @retval status +*/ +USBD_StatusTypeDef USBD_LL_IsoOUTIncomplete(USBD_HandleTypeDef *pdev, uint8_t epnum) +{ + return USBD_OK; +} + +/** +* @brief USBD_DevConnected +* Handle device connection event +* @param pdev: device instance +* @retval status +*/ +USBD_StatusTypeDef USBD_LL_DevConnected(USBD_HandleTypeDef *pdev) +{ + return USBD_OK; +} + +/** +* @brief USBD_DevDisconnected +* Handle device disconnection event +* @param pdev: device instance +* @retval status +*/ +USBD_StatusTypeDef USBD_LL_DevDisconnected(USBD_HandleTypeDef *pdev) +{ + /* Free Class Resources */ + pdev->dev_state = USBD_STATE_DEFAULT; + pdev->pClass->DeInit(pdev, pdev->dev_config); + + return USBD_OK; +} +/** +* @} +*/ + + +/** +* @} +*/ + + +/** +* @} +*/ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ + diff --git a/src/src/usbd_core.h b/src/src/usbd_core.h new file mode 100644 index 0000000..d85638b --- /dev/null +++ b/src/src/usbd_core.h @@ -0,0 +1,165 @@ +/** + ****************************************************************************** + * @file usbd_core.h + * @author MCD Application Team + * @version V2.3.0 + * @date 04-November-2014 + * @brief Header file for usbd_core.c file + ****************************************************************************** + * @attention + * + *

© COPYRIGHT 2014 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (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.st.com/software_license_agreement_liberty_v2 + * + * 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. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __USBD_CORE_H +#define __USBD_CORE_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_conf.h" +#include "usbd_def.h" +#include "usbd_ioreq.h" +#include "usbd_ctlreq.h" + +/** @addtogroup STM32_USB_DEVICE_LIBRARY + * @{ + */ + +/** @defgroup USBD_CORE + * @brief This file is the Header file for usbd_core.c file + * @{ + */ + + +/** @defgroup USBD_CORE_Exported_Defines + * @{ + */ + +/** + * @} + */ + + +/** @defgroup USBD_CORE_Exported_TypesDefinitions + * @{ + */ + + +/** + * @} + */ + + + +/** @defgroup USBD_CORE_Exported_Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup USBD_CORE_Exported_Variables + * @{ + */ +#define USBD_SOF USBD_LL_SOF +/** + * @} + */ + +/** @defgroup USBD_CORE_Exported_FunctionsPrototype + * @{ + */ +USBD_StatusTypeDef USBD_Init(USBD_HandleTypeDef *pdev, const USBD_DescriptorsTypeDef *pdesc, uint8_t id); +USBD_StatusTypeDef USBD_DeInit(USBD_HandleTypeDef *pdev); +USBD_StatusTypeDef USBD_Start (USBD_HandleTypeDef *pdev); +USBD_StatusTypeDef USBD_Stop (USBD_HandleTypeDef *pdev); +USBD_StatusTypeDef USBD_RegisterClass(USBD_HandleTypeDef *pdev, const USBD_ClassTypeDef *pclass); +USBD_StatusTypeDef USBD_SetClassConfig(USBD_HandleTypeDef *pdev, uint8_t cfgidx); +USBD_StatusTypeDef USBD_ClrClassConfig(USBD_HandleTypeDef *pdev, uint8_t cfgidx); + +USBD_StatusTypeDef USBD_LL_SetupStage(USBD_HandleTypeDef *pdev, uint8_t *psetup); +USBD_StatusTypeDef USBD_LL_DataOutStage(USBD_HandleTypeDef *pdev , uint8_t epnum, uint8_t *pdata); +USBD_StatusTypeDef USBD_LL_DataInStage(USBD_HandleTypeDef *pdev , uint8_t epnum, uint8_t *pdata); + +USBD_StatusTypeDef USBD_LL_Reset(USBD_HandleTypeDef *pdev); +USBD_StatusTypeDef USBD_LL_SetSpeed(USBD_HandleTypeDef *pdev, USBD_SpeedTypeDef speed); +USBD_StatusTypeDef USBD_LL_Suspend(USBD_HandleTypeDef *pdev); +USBD_StatusTypeDef USBD_LL_Resume(USBD_HandleTypeDef *pdev); + +USBD_StatusTypeDef USBD_LL_SOF(USBD_HandleTypeDef *pdev); +USBD_StatusTypeDef USBD_LL_IsoINIncomplete(USBD_HandleTypeDef *pdev, uint8_t epnum); +USBD_StatusTypeDef USBD_LL_IsoOUTIncomplete(USBD_HandleTypeDef *pdev, uint8_t epnum); + +USBD_StatusTypeDef USBD_LL_DevConnected(USBD_HandleTypeDef *pdev); +USBD_StatusTypeDef USBD_LL_DevDisconnected(USBD_HandleTypeDef *pdev); + +/* USBD Low Level Driver */ +USBD_StatusTypeDef USBD_LL_Init (USBD_HandleTypeDef *pdev); +USBD_StatusTypeDef USBD_LL_DeInit (USBD_HandleTypeDef *pdev); +USBD_StatusTypeDef USBD_LL_Start(USBD_HandleTypeDef *pdev); +USBD_StatusTypeDef USBD_LL_Stop (USBD_HandleTypeDef *pdev); +USBD_StatusTypeDef USBD_LL_OpenEP (USBD_HandleTypeDef *pdev, + uint8_t ep_addr, + uint8_t ep_type, + uint16_t ep_mps); + +USBD_StatusTypeDef USBD_LL_CloseEP (USBD_HandleTypeDef *pdev, uint8_t ep_addr); +USBD_StatusTypeDef USBD_LL_FlushEP (USBD_HandleTypeDef *pdev, uint8_t ep_addr); +USBD_StatusTypeDef USBD_LL_StallEP (USBD_HandleTypeDef *pdev, uint8_t ep_addr); +USBD_StatusTypeDef USBD_LL_ClearStallEP (USBD_HandleTypeDef *pdev, uint8_t ep_addr); +uint8_t USBD_LL_IsStallEP (USBD_HandleTypeDef *pdev, uint8_t ep_addr); +USBD_StatusTypeDef USBD_LL_SetUSBAddress (USBD_HandleTypeDef *pdev, uint8_t dev_addr); +USBD_StatusTypeDef USBD_LL_Transmit (USBD_HandleTypeDef *pdev, + uint8_t ep_addr, + uint8_t *pbuf, + uint16_t size); + +USBD_StatusTypeDef USBD_LL_PrepareReceive(USBD_HandleTypeDef *pdev, + uint8_t ep_addr, + uint8_t *pbuf, + uint16_t size); + +uint32_t USBD_LL_GetRxDataSize (USBD_HandleTypeDef *pdev, uint8_t ep_addr); +void USBD_LL_Delay (uint32_t Delay); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __USBD_CORE_H */ + +/** + * @} + */ + +/** +* @} +*/ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ + + + diff --git a/src/src/usbd_ctlreq.c b/src/src/usbd_ctlreq.c new file mode 100644 index 0000000..dcd6189 --- /dev/null +++ b/src/src/usbd_ctlreq.c @@ -0,0 +1,722 @@ +/** + ****************************************************************************** + * @file usbd_req.c + * @author MCD Application Team + * @version V2.2.0 + * @date 13-June-2014 + * @brief This file provides the standard USB requests following chapter 9. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT 2014 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (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.st.com/software_license_agreement_liberty_v2 + * + * 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. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_ctlreq.h" +#include "usbd_ioreq.h" + + +/** @addtogroup STM32_USBD_STATE_DEVICE_LIBRARY + * @{ + */ + + +/** @defgroup USBD_REQ + * @brief USB standard requests module + * @{ + */ + +/** @defgroup USBD_REQ_Private_TypesDefinitions + * @{ + */ +/** + * @} + */ + + +/** @defgroup USBD_REQ_Private_Defines + * @{ + */ + +/** + * @} + */ + + +/** @defgroup USBD_REQ_Private_Macros + * @{ + */ +/** + * @} + */ + + +/** @defgroup USBD_REQ_Private_Variables + * @{ + */ +/** + * @} + */ + + +/** @defgroup USBD_REQ_Private_FunctionPrototypes + * @{ + */ +static void USBD_GetDescriptor(USBD_HandleTypeDef *pdev , + USBD_SetupReqTypedef *req); + +static void USBD_SetAddress(USBD_HandleTypeDef *pdev , + USBD_SetupReqTypedef *req); + +static void USBD_SetConfig(USBD_HandleTypeDef *pdev , + USBD_SetupReqTypedef *req); + +static void USBD_GetConfig(USBD_HandleTypeDef *pdev , + USBD_SetupReqTypedef *req); + +static void USBD_GetStatus(USBD_HandleTypeDef *pdev , + USBD_SetupReqTypedef *req); + +static void USBD_SetFeature(USBD_HandleTypeDef *pdev , + USBD_SetupReqTypedef *req); + +static void USBD_ClrFeature(USBD_HandleTypeDef *pdev , + USBD_SetupReqTypedef *req); + +static uint8_t USBD_GetLen(uint8_t *buf); + +/** + * @} + */ + + +/** @defgroup USBD_REQ_Private_Functions + * @{ + */ + + +/** +* @brief USBD_StdDevReq +* Handle standard usb device requests +* @param pdev: device instance +* @param req: usb request +* @retval status +*/ +USBD_StatusTypeDef USBD_StdDevReq (USBD_HandleTypeDef *pdev , USBD_SetupReqTypedef *req) +{ + USBD_StatusTypeDef ret = USBD_OK; + + switch (req->bRequest) + { + case USB_REQ_GET_DESCRIPTOR: + + USBD_GetDescriptor (pdev, req) ; + break; + + case USB_REQ_SET_ADDRESS: + USBD_SetAddress(pdev, req); + break; + + case USB_REQ_SET_CONFIGURATION: + USBD_SetConfig (pdev , req); + break; + + case USB_REQ_GET_CONFIGURATION: + USBD_GetConfig (pdev , req); + break; + + case USB_REQ_GET_STATUS: + USBD_GetStatus (pdev , req); + break; + + + case USB_REQ_SET_FEATURE: + USBD_SetFeature (pdev , req); + break; + + case USB_REQ_CLEAR_FEATURE: + USBD_ClrFeature (pdev , req); + break; + + default: + USBD_CtlError(pdev , req); + break; + } + + return ret; +} + +/** +* @brief USBD_StdItfReq +* Handle standard usb interface requests +* @param pdev: device instance +* @param req: usb request +* @retval status +*/ +USBD_StatusTypeDef USBD_StdItfReq (USBD_HandleTypeDef *pdev , USBD_SetupReqTypedef *req) +{ + USBD_StatusTypeDef ret = USBD_OK; + + switch (pdev->dev_state) + { + case USBD_STATE_CONFIGURED: + + if (LOBYTE(req->wIndex) <= USBD_MAX_NUM_INTERFACES) + { + pdev->pClass->Setup (pdev, req); + + if((req->wLength == 0)&& (ret == USBD_OK)) + { + USBD_CtlSendStatus(pdev); + } + } + else + { + USBD_CtlError(pdev , req); + } + break; + + default: + USBD_CtlError(pdev , req); + break; + } + return USBD_OK; +} + +/** +* @brief USBD_StdEPReq +* Handle standard usb endpoint requests +* @param pdev: device instance +* @param req: usb request +* @retval status +*/ +USBD_StatusTypeDef USBD_StdEPReq (USBD_HandleTypeDef *pdev , USBD_SetupReqTypedef *req) +{ + + uint8_t ep_addr; + USBD_StatusTypeDef ret = USBD_OK; + USBD_EndpointTypeDef *pep; + ep_addr = LOBYTE(req->wIndex); + + switch (req->bRequest) + { + + case USB_REQ_SET_FEATURE : + + switch (pdev->dev_state) + { + case USBD_STATE_ADDRESSED: + if ((ep_addr != 0x00) && (ep_addr != 0x80)) + { + USBD_LL_StallEP(pdev , ep_addr); + } + break; + + case USBD_STATE_CONFIGURED: + if (req->wValue == USB_FEATURE_EP_HALT) + { + if ((ep_addr != 0x00) && (ep_addr != 0x80)) + { + USBD_LL_StallEP(pdev , ep_addr); + + } + } + pdev->pClass->Setup (pdev, req); + USBD_CtlSendStatus(pdev); + + break; + + default: + USBD_CtlError(pdev , req); + break; + } + break; + + case USB_REQ_CLEAR_FEATURE : + + switch (pdev->dev_state) + { + case USBD_STATE_ADDRESSED: + if ((ep_addr != 0x00) && (ep_addr != 0x80)) + { + USBD_LL_StallEP(pdev , ep_addr); + } + break; + + case USBD_STATE_CONFIGURED: + if (req->wValue == USB_FEATURE_EP_HALT) + { + if ((ep_addr & 0x7F) != 0x00) + { + USBD_LL_ClearStallEP(pdev , ep_addr); + pdev->pClass->Setup (pdev, req); + } + USBD_CtlSendStatus(pdev); + } + break; + + default: + USBD_CtlError(pdev , req); + break; + } + break; + + case USB_REQ_GET_STATUS: + switch (pdev->dev_state) + { + case USBD_STATE_ADDRESSED: + if ((ep_addr & 0x7F) != 0x00) + { + USBD_LL_StallEP(pdev , ep_addr); + } + break; + + case USBD_STATE_CONFIGURED: + pep = ((ep_addr & 0x80) == 0x80) ? &pdev->ep_in[ep_addr & 0x7F]:\ + &pdev->ep_out[ep_addr & 0x7F]; + if(USBD_LL_IsStallEP(pdev, ep_addr)) + { + pep->status = 0x0001; + } + else + { + pep->status = 0x0000; + } + + USBD_CtlSendData (pdev, + (uint8_t *)&pep->status, + 2); + break; + + default: + USBD_CtlError(pdev , req); + break; + } + break; + + default: + break; + } + return ret; +} +/** +* @brief USBD_GetDescriptor +* Handle Get Descriptor requests +* @param pdev: device instance +* @param req: usb request +* @retval status +*/ +static void USBD_GetDescriptor(USBD_HandleTypeDef *pdev , + USBD_SetupReqTypedef *req) +{ + uint16_t len; + uint8_t *pbuf; + + + switch (req->wValue >> 8) + { + case USB_DESC_TYPE_DEVICE: + pbuf = pdev->pDesc->GetDeviceDescriptor(pdev->dev_speed, &len); + break; + + case USB_DESC_TYPE_CONFIGURATION: + pbuf = (uint8_t *)pdev->pClass->GetFSConfigDescriptor(&len); + break; + + case USB_DESC_TYPE_STRING: + switch ((uint8_t)(req->wValue)) + { + case USBD_IDX_LANGID_STR: + pbuf = pdev->pDesc->GetLangIDStrDescriptor(pdev->dev_speed, &len); + break; + + case USBD_IDX_MFC_STR: + pbuf = pdev->pDesc->GetManufacturerStrDescriptor(pdev->dev_speed, &len); + break; + + case USBD_IDX_PRODUCT_STR: + pbuf = pdev->pDesc->GetProductStrDescriptor(pdev->dev_speed, &len); + break; + + case USBD_IDX_SERIAL_STR: + pbuf = pdev->pDesc->GetSerialStrDescriptor(pdev->dev_speed, &len); + break; + + default: + USBD_CtlError(pdev , req); + return; + } + break; + + default: + USBD_CtlError(pdev , req); + return; + } + + if((len != 0)&& (req->wLength != 0)) + { + + len = MIN(len , req->wLength); + + USBD_CtlSendData (pdev, + pbuf, + len); + } + +} + +/** +* @brief USBD_SetAddress +* Set device address +* @param pdev: device instance +* @param req: usb request +* @retval status +*/ +static void USBD_SetAddress(USBD_HandleTypeDef *pdev , + USBD_SetupReqTypedef *req) +{ + uint8_t dev_addr; + + if ((req->wIndex == 0) && (req->wLength == 0)) + { + dev_addr = (uint8_t)(req->wValue) & 0x7F; + + if (pdev->dev_state == USBD_STATE_CONFIGURED) + { + USBD_CtlError(pdev , req); + } + else + { + pdev->dev_address = dev_addr; + USBD_LL_SetUSBAddress(pdev, dev_addr); + USBD_CtlSendStatus(pdev); + + if (dev_addr != 0) + { + pdev->dev_state = USBD_STATE_ADDRESSED; + } + else + { + pdev->dev_state = USBD_STATE_DEFAULT; + } + } + } + else + { + USBD_CtlError(pdev , req); + } +} + +/** +* @brief USBD_SetConfig +* Handle Set device configuration request +* @param pdev: device instance +* @param req: usb request +* @retval status +*/ +static void USBD_SetConfig(USBD_HandleTypeDef *pdev , + USBD_SetupReqTypedef *req) +{ + + static uint8_t cfgidx; + + cfgidx = (uint8_t)(req->wValue); + + if (cfgidx > USBD_MAX_NUM_CONFIGURATION ) + { + USBD_CtlError(pdev , req); + } + else + { + switch (pdev->dev_state) + { + case USBD_STATE_ADDRESSED: + if (cfgidx) + { + pdev->dev_config = cfgidx; + pdev->dev_state = USBD_STATE_CONFIGURED; + if(USBD_SetClassConfig(pdev , cfgidx) == USBD_FAIL) + { + USBD_CtlError(pdev , req); + return; + } + USBD_CtlSendStatus(pdev); + } + else + { + USBD_CtlSendStatus(pdev); + } + break; + + case USBD_STATE_CONFIGURED: + if (cfgidx == 0) + { + pdev->dev_state = USBD_STATE_ADDRESSED; + pdev->dev_config = cfgidx; + USBD_ClrClassConfig(pdev , cfgidx); + USBD_CtlSendStatus(pdev); + + } + else if (cfgidx != pdev->dev_config) + { + /* Clear old configuration */ + USBD_ClrClassConfig(pdev , pdev->dev_config); + + /* set new configuration */ + pdev->dev_config = cfgidx; + if(USBD_SetClassConfig(pdev , cfgidx) == USBD_FAIL) + { + USBD_CtlError(pdev , req); + return; + } + USBD_CtlSendStatus(pdev); + } + else + { + USBD_CtlSendStatus(pdev); + } + break; + + default: + USBD_CtlError(pdev , req); + break; + } + } +} + +/** +* @brief USBD_GetConfig +* Handle Get device configuration request +* @param pdev: device instance +* @param req: usb request +* @retval status +*/ +static void USBD_GetConfig(USBD_HandleTypeDef *pdev , + USBD_SetupReqTypedef *req) +{ + + if (req->wLength != 1) + { + USBD_CtlError(pdev , req); + } + else + { + switch (pdev->dev_state ) + { + case USBD_STATE_ADDRESSED: + pdev->dev_default_config = 0; + USBD_CtlSendData (pdev, + (uint8_t *)&pdev->dev_default_config, + 1); + break; + + case USBD_STATE_CONFIGURED: + + USBD_CtlSendData (pdev, + (uint8_t *)&pdev->dev_config, + 1); + break; + + default: + USBD_CtlError(pdev , req); + break; + } + } +} + +/** +* @brief USBD_GetStatus +* Handle Get Status request +* @param pdev: device instance +* @param req: usb request +* @retval status +*/ +static void USBD_GetStatus(USBD_HandleTypeDef *pdev , + USBD_SetupReqTypedef *req) +{ + + + switch (pdev->dev_state) + { + case USBD_STATE_ADDRESSED: + case USBD_STATE_CONFIGURED: + +#if ( USBD_SELF_POWERED == 1) + pdev->dev_config_status = USB_CONFIG_SELF_POWERED; +#else + pdev->dev_config_status = 0; +#endif + + if (pdev->dev_remote_wakeup) + { + pdev->dev_config_status |= USB_CONFIG_REMOTE_WAKEUP; + } + + USBD_CtlSendData (pdev, + (uint8_t *)& pdev->dev_config_status, + 2); + break; + + default : + USBD_CtlError(pdev , req); + break; + } +} + + +/** +* @brief USBD_SetFeature +* Handle Set device feature request +* @param pdev: device instance +* @param req: usb request +* @retval status +*/ +static void USBD_SetFeature(USBD_HandleTypeDef *pdev , + USBD_SetupReqTypedef *req) +{ + + if (req->wValue == USB_FEATURE_REMOTE_WAKEUP) + { + pdev->dev_remote_wakeup = 1; + pdev->pClass->Setup (pdev, req); + USBD_CtlSendStatus(pdev); + } + +} + + +/** +* @brief USBD_ClrFeature +* Handle clear device feature request +* @param pdev: device instance +* @param req: usb request +* @retval status +*/ +static void USBD_ClrFeature(USBD_HandleTypeDef *pdev , + USBD_SetupReqTypedef *req) +{ + switch (pdev->dev_state) + { + case USBD_STATE_ADDRESSED: + case USBD_STATE_CONFIGURED: + if (req->wValue == USB_FEATURE_REMOTE_WAKEUP) + { + pdev->dev_remote_wakeup = 0; + pdev->pClass->Setup (pdev, req); + USBD_CtlSendStatus(pdev); + } + break; + + default : + USBD_CtlError(pdev , req); + break; + } +} + +/** +* @brief USBD_ParseSetupRequest +* Copy buffer into setup structure +* @param pdev: device instance +* @param req: usb request +* @retval None +*/ + +void USBD_ParseSetupRequest(USBD_SetupReqTypedef *req, uint8_t *pdata) +{ + req->bmRequest = *(uint8_t *) (pdata); + req->bRequest = *(uint8_t *) (pdata + 1); + req->wValue = SWAPBYTE (pdata + 2); + req->wIndex = SWAPBYTE (pdata + 4); + req->wLength = SWAPBYTE (pdata + 6); + +} + +/** +* @brief USBD_CtlError +* Handle USB low level Error +* @param pdev: device instance +* @param req: usb request +* @retval None +*/ + +void USBD_CtlError( USBD_HandleTypeDef *pdev , + USBD_SetupReqTypedef *req) +{ + USBD_LL_StallEP(pdev , 0x80); + USBD_LL_StallEP(pdev , 0); +} + + +/** + * @brief USBD_GetString + * Convert Ascii string into unicode one + * @param desc : descriptor buffer + * @param unicode : Formatted string buffer (unicode) + * @param len : descriptor length + * @retval None + */ +void USBD_GetString(uint8_t *desc, uint8_t *unicode, uint16_t *len) +{ + uint8_t idx = 0; + + if (desc != NULL) + { + *len = USBD_GetLen(desc) * 2 + 2; + unicode[idx++] = *len; + unicode[idx++] = USB_DESC_TYPE_STRING; + + while (*desc != '\0') + { + unicode[idx++] = *desc++; + unicode[idx++] = 0x00; + } + } +} + +/** + * @brief USBD_GetLen + * return the string length + * @param buf : pointer to the ascii string buffer + * @retval string length + */ +static uint8_t USBD_GetLen(uint8_t *buf) +{ + uint8_t len = 0; + + while (*buf != '\0') + { + len++; + buf++; + } + + return len; +} +/** + * @} + */ + + +/** + * @} + */ + + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/src/src/usbd_ctlreq.h b/src/src/usbd_ctlreq.h new file mode 100644 index 0000000..0aa3c23 --- /dev/null +++ b/src/src/usbd_ctlreq.h @@ -0,0 +1,113 @@ +/** + ****************************************************************************** + * @file usbd_req.h + * @author MCD Application Team + * @version V2.3.0 + * @date 04-November-2014 + * @brief Header file for the usbd_req.c file + ****************************************************************************** + * @attention + * + *

© COPYRIGHT 2014 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (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.st.com/software_license_agreement_liberty_v2 + * + * 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. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __USB_REQUEST_H +#define __USB_REQUEST_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_def.h" + + +/** @addtogroup STM32_USB_DEVICE_LIBRARY + * @{ + */ + +/** @defgroup USBD_REQ + * @brief header file for the usbd_req.c file + * @{ + */ + +/** @defgroup USBD_REQ_Exported_Defines + * @{ + */ +/** + * @} + */ + + +/** @defgroup USBD_REQ_Exported_Types + * @{ + */ +/** + * @} + */ + + + +/** @defgroup USBD_REQ_Exported_Macros + * @{ + */ +/** + * @} + */ + +/** @defgroup USBD_REQ_Exported_Variables + * @{ + */ +/** + * @} + */ + +/** @defgroup USBD_REQ_Exported_FunctionsPrototype + * @{ + */ + +USBD_StatusTypeDef USBD_StdDevReq (USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); +USBD_StatusTypeDef USBD_StdItfReq (USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); +USBD_StatusTypeDef USBD_StdEPReq (USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); + + +void USBD_CtlError (USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); + +void USBD_ParseSetupRequest (USBD_SetupReqTypedef *req, uint8_t *pdata); + +void USBD_GetString (uint8_t *desc, uint8_t *unicode, uint16_t *len); +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __USB_REQUEST_H */ + +/** + * @} + */ + +/** +* @} +*/ + + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/src/src/usbd_def.h b/src/src/usbd_def.h new file mode 100644 index 0000000..5a23eb2 --- /dev/null +++ b/src/src/usbd_def.h @@ -0,0 +1,310 @@ +/** + ****************************************************************************** + * @file usbd_def.h + * @author MCD Application Team + * @version V2.2.0 + * @date 13-June-2014 + * @brief general defines for the usb device library + ****************************************************************************** + * @attention + * + *

© COPYRIGHT 2014 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (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.st.com/software_license_agreement_liberty_v2 + * + * 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. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ + +#ifndef __USBD_DEF_H +#define __USBD_DEF_H + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_conf.h" + +/** @addtogroup STM32_USBD_DEVICE_LIBRARY + * @{ + */ + +/** @defgroup USB_DEF + * @brief general defines for the usb device library file + * @{ + */ + +/** @defgroup USB_DEF_Exported_Defines + * @{ + */ + +#ifndef NULL +#define NULL ((void *)0) +#endif + + +#define USB_LEN_DEV_QUALIFIER_DESC 0x0A +#define USB_LEN_DEV_DESC 0x12 +#define USB_LEN_CFG_DESC 0x09 +#define USB_LEN_IF_DESC 0x09 +#define USB_LEN_EP_DESC 0x07 +#define USB_LEN_OTG_DESC 0x03 +#define USB_LEN_LANGID_STR_DESC 0x04 +#define USB_LEN_OTHER_SPEED_DESC_SIZ 0x09 + +#define USBD_IDX_LANGID_STR 0x00 +#define USBD_IDX_MFC_STR 0x01 +#define USBD_IDX_PRODUCT_STR 0x02 +#define USBD_IDX_SERIAL_STR 0x03 + +#define USB_REQ_TYPE_STANDARD 0x00 +#define USB_REQ_TYPE_CLASS 0x20 +#define USB_REQ_TYPE_VENDOR 0x40 +#define USB_REQ_TYPE_MASK 0x60 + +#define USB_REQ_RECIPIENT_DEVICE 0x00 +#define USB_REQ_RECIPIENT_INTERFACE 0x01 +#define USB_REQ_RECIPIENT_ENDPOINT 0x02 +#define USB_REQ_RECIPIENT_MASK 0x03 + +#define USB_REQ_GET_STATUS 0x00 +#define USB_REQ_CLEAR_FEATURE 0x01 +#define USB_REQ_SET_FEATURE 0x03 +#define USB_REQ_SET_ADDRESS 0x05 +#define USB_REQ_GET_DESCRIPTOR 0x06 +#define USB_REQ_SET_DESCRIPTOR 0x07 +#define USB_REQ_GET_CONFIGURATION 0x08 +#define USB_REQ_SET_CONFIGURATION 0x09 +#define USB_REQ_GET_INTERFACE 0x0A +#define USB_REQ_SET_INTERFACE 0x0B +#define USB_REQ_SYNCH_FRAME 0x0C + +#define USB_DESC_TYPE_DEVICE 1 +#define USB_DESC_TYPE_CONFIGURATION 2 +#define USB_DESC_TYPE_STRING 3 +#define USB_DESC_TYPE_INTERFACE 4 +#define USB_DESC_TYPE_ENDPOINT 5 +#define USB_DESC_TYPE_DEVICE_QUALIFIER 6 +#define USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION 7 + + +#define USB_CONFIG_REMOTE_WAKEUP 2 +#define USB_CONFIG_SELF_POWERED 1 + +#define USB_FEATURE_EP_HALT 0 +#define USB_FEATURE_REMOTE_WAKEUP 1 +#define USB_FEATURE_TEST_MODE 2 + + +#define USB_HS_MAX_PACKET_SIZE 512 +#define USB_FS_MAX_PACKET_SIZE 64 +#define USB_MAX_EP0_SIZE 64 + +/* Device Status */ +#define USBD_STATE_DEFAULT 1 +#define USBD_STATE_ADDRESSED 2 +#define USBD_STATE_CONFIGURED 3 +#define USBD_STATE_SUSPENDED 4 + + +/* EP0 State */ +#define USBD_EP0_IDLE 0 +#define USBD_EP0_SETUP 1 +#define USBD_EP0_DATA_IN 2 +#define USBD_EP0_DATA_OUT 3 +#define USBD_EP0_STATUS_IN 4 +#define USBD_EP0_STATUS_OUT 5 +#define USBD_EP0_STALL 6 + +#define USBD_EP_TYPE_CTRL 0 +#define USBD_EP_TYPE_ISOC 1 +#define USBD_EP_TYPE_BULK 2 +#define USBD_EP_TYPE_INTR 3 + + +/** + * @} + */ + + +/** @defgroup USBD_DEF_Exported_TypesDefinitions + * @{ + */ + +typedef struct usb_setup_req +{ + uint8_t bmRequest; + uint8_t bRequest; + uint16_t wValue; + uint16_t wIndex; + uint16_t wLength; +} USBD_SetupReqTypedef; + +struct _USBD_HandleTypeDef; + +typedef struct _Device_cb +{ + uint8_t (*Init) (struct _USBD_HandleTypeDef *pdev , uint8_t cfgidx); + uint8_t (*DeInit) (struct _USBD_HandleTypeDef *pdev , uint8_t cfgidx); + /* Control Endpoints*/ + uint8_t (*Setup) (struct _USBD_HandleTypeDef *pdev , USBD_SetupReqTypedef *req); + uint8_t (*EP0_TxSent) (struct _USBD_HandleTypeDef *pdev ); + uint8_t (*EP0_RxReady) (struct _USBD_HandleTypeDef *pdev ); + /* Class Specific Endpoints*/ + uint8_t (*DataIn) (struct _USBD_HandleTypeDef *pdev , uint8_t epnum); + uint8_t (*DataOut) (struct _USBD_HandleTypeDef *pdev , uint8_t epnum); + uint8_t (*SOF) (struct _USBD_HandleTypeDef *pdev); + uint8_t (*IsoINIncomplete) (struct _USBD_HandleTypeDef *pdev , uint8_t epnum); + uint8_t (*IsoOUTIncomplete) (struct _USBD_HandleTypeDef *pdev , uint8_t epnum); + + const uint8_t *(*GetFSConfigDescriptor)(uint16_t *length); +#if (USBD_SUPPORT_USER_STRING == 1) + uint8_t *(*GetUsrStrDescriptor)(struct _USBD_HandleTypeDef *pdev ,uint8_t index, uint16_t *length); +#endif + +} USBD_ClassTypeDef; + +/* Following USB Device Speed */ +typedef enum +{ + USBD_SPEED_HIGH = 0, + USBD_SPEED_FULL = 1, + USBD_SPEED_LOW = 2, +}USBD_SpeedTypeDef; + +/* Following USB Device status */ +typedef enum { + USBD_OK = 0, + USBD_BUSY, + USBD_FAIL, +}USBD_StatusTypeDef; + +/* USB Device descriptors structure */ +typedef struct +{ + uint8_t *(*GetDeviceDescriptor)( USBD_SpeedTypeDef speed , uint16_t *length); + uint8_t *(*GetLangIDStrDescriptor)( USBD_SpeedTypeDef speed , uint16_t *length); + uint8_t *(*GetManufacturerStrDescriptor)( USBD_SpeedTypeDef speed , uint16_t *length); + uint8_t *(*GetProductStrDescriptor)( USBD_SpeedTypeDef speed , uint16_t *length); + uint8_t *(*GetSerialStrDescriptor)( USBD_SpeedTypeDef speed , uint16_t *length); +} USBD_DescriptorsTypeDef; + +/* USB Device handle structure */ +typedef struct +{ + uint32_t status; + uint32_t total_length; + uint32_t rem_length; + uint32_t maxpacket; +} USBD_EndpointTypeDef; + +/* USB Device handle structure */ +typedef struct _USBD_HandleTypeDef +{ + uint8_t id; + uint32_t dev_config; + uint32_t dev_default_config; + uint32_t dev_config_status; + USBD_SpeedTypeDef dev_speed; + USBD_EndpointTypeDef ep_in[15]; + USBD_EndpointTypeDef ep_out[15]; + uint32_t ep0_state; + uint32_t ep0_data_len; + uint8_t dev_state; + uint8_t dev_old_state; + uint8_t dev_address; + uint8_t dev_connection_status; + uint32_t dev_remote_wakeup; + + USBD_SetupReqTypedef request; + const USBD_DescriptorsTypeDef *pDesc; + const USBD_ClassTypeDef *pClass; + void *pClassData; + void *pUserData; + void *pData; +} USBD_HandleTypeDef; + +/** + * @} + */ + + + +/** @defgroup USBD_DEF_Exported_Macros + * @{ + */ +#define SWAPBYTE(addr) (((uint16_t)(*((uint8_t *)(addr)))) + \ + (((uint16_t)(*(((uint8_t *)(addr)) + 1))) << 8)) + +#define LOBYTE(x) ((uint8_t)(x & 0x00FF)) +#define HIBYTE(x) ((uint8_t)((x & 0xFF00) >>8)) +#define MIN(a, b) (((a) < (b)) ? (a) : (b)) +#define MAX(a, b) (((a) > (b)) ? (a) : (b)) + + +#if defined ( __GNUC__ ) + #ifndef __weak + #define __weak __attribute__((weak)) + #endif /* __weak */ + #ifndef __packed + #define __packed __attribute__((__packed__)) + #endif /* __packed */ +#endif /* __GNUC__ */ + + +/* In HS mode and when the DMA is used, all variables and data structures dealing + with the DMA during the transaction process should be 4-bytes aligned */ + +#if defined (__GNUC__) /* GNU Compiler */ + #define __ALIGN_END __attribute__ ((aligned (4))) + #define __ALIGN_BEGIN +#else + #define __ALIGN_END + #if defined (__CC_ARM) /* ARM Compiler */ + #define __ALIGN_BEGIN __align(4) + #elif defined (__ICCARM__) /* IAR Compiler */ + #define __ALIGN_BEGIN + #elif defined (__TASKING__) /* TASKING Compiler */ + #define __ALIGN_BEGIN __align(4) + #endif /* __CC_ARM */ +#endif /* __GNUC__ */ + + +/** + * @} + */ + +/** @defgroup USBD_DEF_Exported_Variables + * @{ + */ + +/** + * @} + */ + +/** @defgroup USBD_DEF_Exported_FunctionsPrototype + * @{ + */ + +/** + * @} + */ + +#endif /* __USBD_DEF_H */ + +/** + * @} + */ + +/** +* @} +*/ +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/src/src/usbd_desc.c b/src/src/usbd_desc.c new file mode 100644 index 0000000..48753eb --- /dev/null +++ b/src/src/usbd_desc.c @@ -0,0 +1,223 @@ +/* + USB CDC-ECM for STM32F072 microcontroller + + Copyright (C) 2015,2016 Peter Lawrence + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +/* +Theory of operation: + +Leveraging the structs in usbhelper.h and ecmhelper.h, a USB descriptor for this device is created. +*/ + +#include "usbd_core.h" +#include "usbd_desc.h" +#include "usbd_conf.h" +#include "usbhelper.h" +#include "usbd_ecm.h" +#include "ecmhelper.h" + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +#define USBD_VID 0x483 /* temporary assignment */ +#define USBD_PID 0x5740 /* temporary assignment */ +#define USBD_LANGID_STRING 0x409 +#define USBD_MANUFACTURER_STRING "Acme" +#define USBD_PRODUCT_FS_STRING "ECM" + +/* Private macro -------------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +static uint8_t *USBD_VCP_DeviceDescriptor(USBD_SpeedTypeDef speed, uint16_t *length); +static uint8_t *USBD_VCP_LangIDStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length); +static uint8_t *USBD_VCP_ManufacturerStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length); +static uint8_t *USBD_VCP_ProductStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length); +static uint8_t *USBD_VCP_SerialStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length); +static uint8_t *USBD_VCP_ConfigStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length); +static uint8_t *USBD_VCP_InterfaceStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length); +static void IntToUnicode (uint32_t value, uint8_t *pbuf, uint8_t len); + +/* Private variables ---------------------------------------------------------*/ +const USBD_DescriptorsTypeDef VCP_Desc = +{ + USBD_VCP_DeviceDescriptor, + USBD_VCP_LangIDStrDescriptor, + USBD_VCP_ManufacturerStrDescriptor, + USBD_VCP_ProductStrDescriptor, + USBD_VCP_SerialStrDescriptor, +}; + +/* USB Standard Device Descriptor */ +static const struct device_descriptor hUSBDDeviceDesc = +{ + sizeof(hUSBDDeviceDesc), /* bLength */ + USB_DESC_TYPE_DEVICE, /* bDescriptorType */ + USB_UINT16(0x0200), /* bcdUSB */ + 0x00, /* bDeviceClass */ + 0x00, /* bDeviceSubClass */ + 0x00, /* bDeviceProtocol */ + USB_MAX_EP0_SIZE, /* bMaxPacketSize */ + USB_UINT16(USBD_VID), /* idVendor */ + USB_UINT16(USBD_PID), /* idProduct */ + USB_UINT16(0x0200), /* bcdDevice */ + USBD_IDX_MFC_STR, /* Index of manufacturer string */ + USBD_IDX_PRODUCT_STR, /* Index of product string */ + USBD_IDX_SERIAL_STR, /* Index of serial number string */ + USBD_MAX_NUM_CONFIGURATION /* bNumConfigurations */ +}; + +/* bespoke struct for this device; struct members are added and removed as needed */ +struct configuration_1 +{ + struct configuration_descriptor config; + struct ecm_interface ecm; +}; + +/* fully initialize the bespoke struct as a const */ +__ALIGN_BEGIN static const struct configuration_1 USBD_ECM_CfgFSDesc __ALIGN_END = +{ + .config = { + /*Configuration Descriptor*/ + sizeof(struct configuration_descriptor), /* bLength */ + USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType */ + USB_UINT16(sizeof(USBD_ECM_CfgFSDesc)), /* wTotalLength */ + USBD_MAX_NUM_INTERFACES, /* bNumInterfaces */ + 0x01, /* bConfigurationValue */ + 0x00, /* iConfiguration */ + 0x80, /* bmAttributes */ + 50, /* MaxPower */ + }, + + .ecm = ECM_DESCRIPTOR(/* Notify ITF */ 0x00, /* Data ITF */ 0x01, /* Notify EP */ ECM_NOTIFICATION_IN_EP, /* DataOut EP */ ECM_DATA_OUT_EP, /* DataIn EP */ ECM_DATA_IN_EP, /* iMACstring */ USBD_IDX_SERIAL_STR) +}; + +const uint8_t *const USBD_CfgFSDesc_pnt = (const uint8_t *)&USBD_ECM_CfgFSDesc; +const uint16_t USBD_CfgFSDesc_len = sizeof(USBD_ECM_CfgFSDesc); + +/* USB Standard Device Descriptor */ +static const uint8_t USBD_LangIDDesc[USB_LEN_LANGID_STR_DESC]= +{ + USB_LEN_LANGID_STR_DESC, + USB_DESC_TYPE_STRING, + LOBYTE(USBD_LANGID_STRING), + HIBYTE(USBD_LANGID_STRING), +}; + +static uint8_t USBD_StrDesc[USBD_MAX_STR_DESC_SIZ]; + +/** * @brief Returns the device descriptor. + * @param speed: Current device speed + * @param length: Pointer to data length variable + * @retval Pointer to descriptor buffer + */ +static uint8_t *USBD_VCP_DeviceDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) +{ + *length = sizeof(hUSBDDeviceDesc); + return (uint8_t*)&hUSBDDeviceDesc; +} + +/** + * @brief Returns the LangID string descriptor. + * @param speed: Current device speed + * @param length: Pointer to data length variable + * @retval Pointer to descriptor buffer + */ +static uint8_t *USBD_VCP_LangIDStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) +{ + *length = sizeof(USBD_LangIDDesc); + return (uint8_t*)USBD_LangIDDesc; +} + +/** + * @brief Returns the product string descriptor. + * @param speed: Current device speed + * @param length: Pointer to data length variable + * @retval Pointer to descriptor buffer + */ +static uint8_t *USBD_VCP_ProductStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) +{ + USBD_GetString((uint8_t *)USBD_PRODUCT_FS_STRING, USBD_StrDesc, length); + return USBD_StrDesc; +} + +/** + * @brief Returns the manufacturer string descriptor. + * @param speed: Current device speed + * @param length: Pointer to data length variable + * @retval Pointer to descriptor buffer + */ +static uint8_t *USBD_VCP_ManufacturerStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) +{ + USBD_GetString((uint8_t *)USBD_MANUFACTURER_STRING, USBD_StrDesc, length); + return USBD_StrDesc; +} + +/** + * @brief Returns the serial number string descriptor. + * @param speed: Current device speed + * @param length: Pointer to data length variable + * @retval Pointer to descriptor buffer + */ +static uint8_t *USBD_VCP_SerialStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) +{ + uint32_t deviceserial; + + /* + for some peculiar reason, ST doesn't define the unique ID registers in the HAL include files + the DEVICE_ID registers are documented in Chapter 33 of the RM0091 Reference Manual + */ + deviceserial = *(uint32_t*)(0x1FFFF7B0); /*DEVICE_ID2*/ + + USBD_StrDesc[0] = *length = 2 + 8*2 + 4*2; + USBD_StrDesc[1] = USB_DESC_TYPE_STRING; + /* set upper bits to ensure classification as locally administered */ + IntToUnicode (0x02020000, &USBD_StrDesc[2], 4); + /* set lower 32-bits using silicon serial number */ + IntToUnicode (deviceserial, &USBD_StrDesc[10], 8); + return USBD_StrDesc; +} + +/** + * @brief Convert Hex 32Bits value into char + * @param value: value to convert + * @param pbuf: pointer to the buffer + * @param len: buffer length + * @retval None + */ +static void IntToUnicode (uint32_t value, uint8_t *pbuf, uint8_t len) +{ + uint8_t idx = 0; + + for( idx = 0 ; idx < len ; idx ++) + { + if( ((value >> 28)) < 0xA ) + { + pbuf[ 2* idx] = (value >> 28) + '0'; + } + else + { + pbuf[2* idx] = (value >> 28) + 'A' - 10; + } + + value = value << 4; + + pbuf[ 2* idx + 1] = 0; + } +} diff --git a/src/src/usbd_desc.h b/src/src/usbd_desc.h new file mode 100644 index 0000000..bee8000 --- /dev/null +++ b/src/src/usbd_desc.h @@ -0,0 +1,15 @@ +#ifndef __USBD_DESC_H +#define __USBD_DESC_H + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_def.h" + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------- */ +extern const USBD_DescriptorsTypeDef VCP_Desc; +extern const uint8_t *const USBD_CfgFSDesc_pnt; +extern const uint16_t USBD_CfgFSDesc_len; + +#endif /* __USBD_DESC_H */ diff --git a/src/src/usbd_ecm.c b/src/src/usbd_ecm.c new file mode 100644 index 0000000..e50fcf9 --- /dev/null +++ b/src/src/usbd_ecm.c @@ -0,0 +1,303 @@ +/* + USB CDC-ECM for STM32F072 microcontroller + + Copyright (C) 2015,2016,2018 Peter Lawrence + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +/* +Theory of operation: + +Each incoming virtual Ethernet packet from the host arrives via ECM_DATA_OUT_EP. +It arrives in 64-byte chunks, and the last chunk will have a length of less than 64 (signifying a whole packet). +These chunks are accumulated in ecm_rx_buffer, and the whole packet is passed to the user's usb_ecm_recv_callback function. +The user indicates that another packet can be received (writing over the existing data) by calling usb_ecm_recv_renew(). + +Note that ST's stack may refuse to "renew", so OutboundTransferNeedsRenewal exists to mop up when this happens. + +Outgoing virtual Ethernet packets are sent to the host via ECM_DATA_IN_IP. +In theory, the ST stack can handle "multi-packet" automatically, but there seem to be issues with this. +So, as with receive packets, transmit packets are sent to the host in 64-byte chunks. +The user should call usb_ecm_can_xmit() to verify whether it is possible to transmit another packet. +The user then calls usb_ecm_xmit_packet() to transmit such a packet. +*/ + +#include "usbd_ecm.h" +#include "usbd_desc.h" + +/* USB handle declared in main.c */ +extern USBD_HandleTypeDef USBD_Device; + +extern void ECM_ReceivePacket(unsigned index, uint8_t *data, uint16_t length); + +/* local function prototyping */ + +static uint8_t USBD_ECM_Init (USBD_HandleTypeDef *pdev, uint8_t cfgidx); +static uint8_t USBD_ECM_DeInit (USBD_HandleTypeDef *pdev, uint8_t cfgidx); +static uint8_t USBD_ECM_Setup (USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); +static uint8_t USBD_ECM_DataIn (USBD_HandleTypeDef *pdev, uint8_t epnum); +static uint8_t USBD_ECM_DataOut (USBD_HandleTypeDef *pdev, uint8_t epnum); +static uint8_t USBD_ECM_EP0_RxReady (USBD_HandleTypeDef *pdev); +static const uint8_t *USBD_ECM_GetFSCfgDesc (uint16_t *length); +static uint8_t USBD_ECM_SOF (USBD_HandleTypeDef *pdev); + +static USBD_StatusTypeDef USBD_ECM_ReceivePacket (USBD_HandleTypeDef *pdev, unsigned index); + +/* class callbacks structure that is used by main.c */ +const USBD_ClassTypeDef USBD_ECM = +{ + .Init = USBD_ECM_Init, + .DeInit = USBD_ECM_DeInit, + .Setup = USBD_ECM_Setup, + .EP0_TxSent = NULL, + .EP0_RxReady = USBD_ECM_EP0_RxReady, + .DataIn = USBD_ECM_DataIn, + .DataOut = USBD_ECM_DataOut, + .SOF = USBD_ECM_SOF, + .IsoINIncomplete = NULL, + .IsoOUTIncomplete = NULL, + .GetFSConfigDescriptor = USBD_ECM_GetFSCfgDesc, +}; + +static USBD_HandleTypeDef *registered_pdev; + +__ALIGN_BEGIN static uint8_t ecm_rx_buffer[ECM_MAX_SEGMENT_SIZE] __ALIGN_END; +__ALIGN_BEGIN static uint8_t ecm_tx_buffer[ECM_MAX_SEGMENT_SIZE] __ALIGN_END; +__ALIGN_BEGIN static USBD_SetupReqTypedef notify __ALIGN_END = +{ + .bmRequest = 0x21, + .bRequest = 0 /* NETWORK_CONNECTION */, + .wValue = 1 /* Connected */, + .wLength = 0, +}; + +static int ecm_rx_index; +static bool can_xmit; +static bool OutboundTransferNeedsRenewal; +static uint8_t *ecm_tx_ptr; +static int ecm_tx_remaining; +static int ecm_tx_busy; +static int copy_length; + +void usb_ecm_recv_renew(void) +{ + USBD_StatusTypeDef outcome; + + outcome = USBD_LL_PrepareReceive(registered_pdev, ECM_DATA_OUT_EP, ecm_rx_buffer + ecm_rx_index, ECM_DATA_OUT_SZ); + + OutboundTransferNeedsRenewal = (USBD_OK != outcome); /* set if the HAL was busy so that we know to retry it */ +} + +static uint8_t USBD_ECM_Init (USBD_HandleTypeDef *pdev, uint8_t cfgidx) +{ + registered_pdev = pdev; + + /* Open EP IN */ + USBD_LL_OpenEP(pdev, ECM_DATA_IN_EP, USBD_EP_TYPE_BULK, ECM_DATA_IN_SZ); + + /* Open EP OUT */ + USBD_LL_OpenEP(pdev, ECM_DATA_OUT_EP, USBD_EP_TYPE_BULK, ECM_DATA_OUT_SZ); + + /* Open Command IN EP */ + USBD_LL_OpenEP(pdev, ECM_NOTIFICATION_IN_EP, USBD_EP_TYPE_INTR, ECM_NOTIFICATION_IN_SZ); + + usb_ecm_recv_renew(); + can_xmit = true; + OutboundTransferNeedsRenewal = false; + ecm_tx_busy = 0; + ecm_tx_remaining = 0; + + return USBD_OK; +} + +static uint8_t USBD_ECM_DeInit (USBD_HandleTypeDef *pdev, uint8_t cfgidx) +{ + registered_pdev = NULL; + + /* Close EP IN */ + USBD_LL_CloseEP(pdev, ECM_DATA_IN_EP); + + /* Close EP OUT */ + USBD_LL_CloseEP(pdev, ECM_DATA_OUT_EP); + + /* Close Command IN EP */ + USBD_LL_CloseEP(pdev, ECM_NOTIFICATION_IN_EP); + + can_xmit = false; + + return USBD_OK; +} + +static uint8_t USBD_ECM_Setup (USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) +{ + if (0x43 /* SET_ETHERNET_PACKET_FILTER */ == req->bRequest) + { + notify.wIndex = req->wIndex; + USBD_LL_Transmit(pdev, ECM_NOTIFICATION_IN_EP, (uint8_t *)¬ify, sizeof(notify)); + } + + return USBD_OK; +} + +static void ecm_incoming_attempt(void) +{ + int chunk_size; + + if (!ecm_tx_remaining || ecm_tx_busy) + return; + + chunk_size = ecm_tx_remaining; + if (chunk_size > ECM_DATA_IN_SZ) + chunk_size = ECM_DATA_IN_SZ; + + /* ST stack always returns a success code, so reading the return value is pointless */ + USBD_LL_Transmit(registered_pdev, ECM_DATA_IN_EP, ecm_tx_ptr, chunk_size); + + ecm_tx_ptr += chunk_size; + ecm_tx_remaining -= chunk_size; + ecm_tx_busy = 1; +} + +static uint8_t USBD_ECM_DataIn (USBD_HandleTypeDef *pdev, uint8_t epnum) +{ + if (ECM_DATA_IN_EP == (epnum | 0x80)) + { + ecm_tx_busy = 0; + if (0 == ecm_tx_remaining) + can_xmit = true; + ecm_incoming_attempt(); + } + + return USBD_OK; +} + +static uint8_t USBD_ECM_DataOut (USBD_HandleTypeDef *pdev, uint8_t epnum) +{ + uint32_t RxLength; + + if (ECM_DATA_OUT_EP != epnum) + return USBD_OK; + + /* Get the received data length */ + RxLength = USBD_LL_GetRxDataSize (pdev, epnum); + + ecm_rx_index += RxLength; + + if (RxLength < ECM_DATA_OUT_SZ) + { + usb_ecm_recv_callback(ecm_rx_buffer, ecm_rx_index); + ecm_rx_index = 0; + } + else + { + /* Initiate next USB packet transfer */ + usb_ecm_recv_renew(); + } + + return USBD_OK; +} + +static uint8_t USBD_ECM_SOF (USBD_HandleTypeDef *pdev) +{ + /* mop up for any failed USBD_LL_PrepareReceive() call */ + if (OutboundTransferNeedsRenewal) + usb_ecm_recv_renew(); + + if (ecm_tx_busy) + { + /* ugly hack for ST stack sometimes not providing the DataOut callback */ + if (++ecm_tx_busy > 32) + { + ecm_tx_busy = 0; + if (0 == ecm_tx_remaining) + can_xmit = true; + } + } + + ecm_incoming_attempt(); + + return USBD_OK; +} + +static uint8_t USBD_ECM_EP0_RxReady (USBD_HandleTypeDef *pdev) +{ + return USBD_OK; +} + +static const uint8_t *USBD_ECM_GetFSCfgDesc (uint16_t *length) +{ + *length = USBD_CfgFSDesc_len; + return USBD_CfgFSDesc_pnt; +} + +uint8_t USBD_ECM_RegisterInterface(USBD_HandleTypeDef *pdev) +{ + unsigned index; + + return USBD_OK; +} + +void USBD_ECM_PMAConfig(PCD_HandleTypeDef *hpcd, uint32_t *pma_address) +{ + /* allocate PMA memory for all endpoints associated with ECM */ + HAL_PCDEx_PMAConfig(hpcd, ECM_DATA_IN_EP, PCD_SNG_BUF, *pma_address); + *pma_address += ECM_DATA_IN_SZ; + HAL_PCDEx_PMAConfig(hpcd, ECM_DATA_OUT_EP, PCD_SNG_BUF, *pma_address); + *pma_address += ECM_DATA_OUT_SZ; + HAL_PCDEx_PMAConfig(hpcd, ECM_NOTIFICATION_IN_EP, PCD_SNG_BUF, *pma_address); + *pma_address += ECM_NOTIFICATION_IN_SZ; +} + +bool usb_ecm_can_xmit(void) +{ + bool outcome; + + __disable_irq(); + outcome = can_xmit; + __enable_irq(); + + return outcome; +} + +void usb_ecm_xmit_packet(struct pbuf *p) +{ + struct pbuf *q; + int packet_size; + uint8_t *data; + + if (!registered_pdev || !can_xmit) + return; + + data = ecm_tx_buffer; + packet_size = 0; + for(q = p; q != NULL; q = q->next) + { + memcpy(data, q->payload, q->len); + data += q->len; + packet_size += q->len; + } + + __disable_irq(); + can_xmit = false; + ecm_tx_ptr = ecm_tx_buffer; + ecm_tx_remaining = packet_size; + copy_length = packet_size; + __enable_irq(); +} diff --git a/src/src/usbd_ecm.h b/src/src/usbd_ecm.h new file mode 100644 index 0000000..2f2026f --- /dev/null +++ b/src/src/usbd_ecm.h @@ -0,0 +1,50 @@ +/* + USB CDC-ECM for STM32F072 microcontroller + + Copyright (C) 2015,2016,2018 Peter Lawrence + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#ifndef __USB_ECM_H_ +#define __USB_ECM_H_ + +#include +#include +#include "usbd_def.h" +#include "usbd_ioreq.h" +#include "netif/etharp.h" +#include "ecmhelper.h" + +#define ETH_HEADER_SIZE 14 +#define ECM_MTU (ECM_MAX_SEGMENT_SIZE - ETH_HEADER_SIZE) + +/* array of callback functions invoked by USBD_RegisterClass() in main.c */ +extern const USBD_ClassTypeDef USBD_ECM; + +uint8_t USBD_ECM_RegisterInterface(USBD_HandleTypeDef *pdev); +void USBD_ECM_PMAConfig(PCD_HandleTypeDef *hpcd, uint32_t *pma_address); + +void usb_ecm_recv_callback(const uint8_t *data, int size); +void usb_ecm_recv_renew(void); + +bool usb_ecm_can_xmit(void); +void usb_ecm_xmit_packet(struct pbuf *p); + +#endif // __USB_ECM_H_ diff --git a/src/src/usbd_ioreq.c b/src/src/usbd_ioreq.c new file mode 100644 index 0000000..ed1ae82 --- /dev/null +++ b/src/src/usbd_ioreq.c @@ -0,0 +1,236 @@ +/** + ****************************************************************************** + * @file usbd_ioreq.c + * @author MCD Application Team + * @version V2.3.0 + * @date 04-November-2014 + * @brief This file provides the IO requests APIs for control endpoints. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT 2014 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (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.st.com/software_license_agreement_liberty_v2 + * + * 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. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_ioreq.h" + +/** @addtogroup STM32_USB_DEVICE_LIBRARY + * @{ + */ + + +/** @defgroup USBD_IOREQ + * @brief control I/O requests module + * @{ + */ + +/** @defgroup USBD_IOREQ_Private_TypesDefinitions + * @{ + */ +/** + * @} + */ + + +/** @defgroup USBD_IOREQ_Private_Defines + * @{ + */ + +/** + * @} + */ + + +/** @defgroup USBD_IOREQ_Private_Macros + * @{ + */ +/** + * @} + */ + + +/** @defgroup USBD_IOREQ_Private_Variables + * @{ + */ + +/** + * @} + */ + + +/** @defgroup USBD_IOREQ_Private_FunctionPrototypes + * @{ + */ +/** + * @} + */ + + +/** @defgroup USBD_IOREQ_Private_Functions + * @{ + */ + +/** +* @brief USBD_CtlSendData +* send data on the ctl pipe +* @param pdev: device instance +* @param buff: pointer to data buffer +* @param len: length of data to be sent +* @retval status +*/ +USBD_StatusTypeDef USBD_CtlSendData (USBD_HandleTypeDef *pdev, + uint8_t *pbuf, + uint16_t len) +{ + /* Set EP0 State */ + pdev->ep0_state = USBD_EP0_DATA_IN; + pdev->ep_in[0].total_length = len; + pdev->ep_in[0].rem_length = len; + /* Start the transfer */ + USBD_LL_Transmit (pdev, 0x00, pbuf, len); + + return USBD_OK; +} + +/** +* @brief USBD_CtlContinueSendData +* continue sending data on the ctl pipe +* @param pdev: device instance +* @param buff: pointer to data buffer +* @param len: length of data to be sent +* @retval status +*/ +USBD_StatusTypeDef USBD_CtlContinueSendData (USBD_HandleTypeDef *pdev, + uint8_t *pbuf, + uint16_t len) +{ + /* Start the next transfer */ + USBD_LL_Transmit (pdev, 0x00, pbuf, len); + + return USBD_OK; +} + +/** +* @brief USBD_CtlPrepareRx +* receive data on the ctl pipe +* @param pdev: device instance +* @param buff: pointer to data buffer +* @param len: length of data to be received +* @retval status +*/ +USBD_StatusTypeDef USBD_CtlPrepareRx (USBD_HandleTypeDef *pdev, + uint8_t *pbuf, + uint16_t len) +{ + /* Set EP0 State */ + pdev->ep0_state = USBD_EP0_DATA_OUT; + pdev->ep_out[0].total_length = len; + pdev->ep_out[0].rem_length = len; + /* Start the transfer */ + USBD_LL_PrepareReceive (pdev, + 0, + pbuf, + len); + + return USBD_OK; +} + +/** +* @brief USBD_CtlContinueRx +* continue receive data on the ctl pipe +* @param pdev: device instance +* @param buff: pointer to data buffer +* @param len: length of data to be received +* @retval status +*/ +USBD_StatusTypeDef USBD_CtlContinueRx (USBD_HandleTypeDef *pdev, + uint8_t *pbuf, + uint16_t len) +{ + + USBD_LL_PrepareReceive (pdev, + 0, + pbuf, + len); + return USBD_OK; +} +/** +* @brief USBD_CtlSendStatus +* send zero lzngth packet on the ctl pipe +* @param pdev: device instance +* @retval status +*/ +USBD_StatusTypeDef USBD_CtlSendStatus (USBD_HandleTypeDef *pdev) +{ + + /* Set EP0 State */ + pdev->ep0_state = USBD_EP0_STATUS_IN; + + /* Start the transfer */ + USBD_LL_Transmit (pdev, 0x00, NULL, 0); + + return USBD_OK; +} + +/** +* @brief USBD_CtlReceiveStatus +* receive zero lzngth packet on the ctl pipe +* @param pdev: device instance +* @retval status +*/ +USBD_StatusTypeDef USBD_CtlReceiveStatus (USBD_HandleTypeDef *pdev) +{ + /* Set EP0 State */ + pdev->ep0_state = USBD_EP0_STATUS_OUT; + + /* Start the transfer */ + USBD_LL_PrepareReceive ( pdev, + 0, + NULL, + 0); + + return USBD_OK; +} + + +/** +* @brief USBD_GetRxCount +* returns the received data length +* @param pdev: device instance +* @param ep_addr: endpoint address +* @retval Rx Data blength +*/ +uint16_t USBD_GetRxCount (USBD_HandleTypeDef *pdev , uint8_t ep_addr) +{ + return USBD_LL_GetRxDataSize(pdev, ep_addr); +} + +/** + * @} + */ + + +/** + * @} + */ + + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/src/src/usbd_ioreq.h b/src/src/usbd_ioreq.h new file mode 100644 index 0000000..5e7c100 --- /dev/null +++ b/src/src/usbd_ioreq.h @@ -0,0 +1,128 @@ +/** + ****************************************************************************** + * @file usbd_ioreq.h + * @author MCD Application Team + * @version V2.3.0 + * @date 04-November-2014 + * @brief Header file for the usbd_ioreq.c file + ****************************************************************************** + * @attention + * + *

© COPYRIGHT 2014 STMicroelectronics

+ * + * Licensed under MCD-ST Liberty SW License Agreement V2, (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.st.com/software_license_agreement_liberty_v2 + * + * 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. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __USBD_IOREQ_H +#define __USBD_IOREQ_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_def.h" +#include "usbd_core.h" + +/** @addtogroup STM32_USB_DEVICE_LIBRARY + * @{ + */ + +/** @defgroup USBD_IOREQ + * @brief header file for the usbd_ioreq.c file + * @{ + */ + +/** @defgroup USBD_IOREQ_Exported_Defines + * @{ + */ +/** + * @} + */ + + +/** @defgroup USBD_IOREQ_Exported_Types + * @{ + */ + + +/** + * @} + */ + + + +/** @defgroup USBD_IOREQ_Exported_Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup USBD_IOREQ_Exported_Variables + * @{ + */ + +/** + * @} + */ + +/** @defgroup USBD_IOREQ_Exported_FunctionsPrototype + * @{ + */ + +USBD_StatusTypeDef USBD_CtlSendData (USBD_HandleTypeDef *pdev, + uint8_t *buf, + uint16_t len); + +USBD_StatusTypeDef USBD_CtlContinueSendData (USBD_HandleTypeDef *pdev, + uint8_t *pbuf, + uint16_t len); + +USBD_StatusTypeDef USBD_CtlPrepareRx (USBD_HandleTypeDef *pdev, + uint8_t *pbuf, + uint16_t len); + +USBD_StatusTypeDef USBD_CtlContinueRx (USBD_HandleTypeDef *pdev, + uint8_t *pbuf, + uint16_t len); + +USBD_StatusTypeDef USBD_CtlSendStatus (USBD_HandleTypeDef *pdev); + +USBD_StatusTypeDef USBD_CtlReceiveStatus (USBD_HandleTypeDef *pdev); + +uint16_t USBD_GetRxCount (USBD_HandleTypeDef *pdev , + uint8_t epnum); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __USBD_IOREQ_H */ + +/** + * @} + */ + +/** +* @} +*/ +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/src/src/usbhelper.h b/src/src/usbhelper.h new file mode 100644 index 0000000..3e048b1 --- /dev/null +++ b/src/src/usbhelper.h @@ -0,0 +1,155 @@ +/* + USB descriptor structs + + Copyright (C) 2015,2016 Peter Lawrence + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#ifndef __USB_MAGIC_H +#define __USB_MAGIC_H + +#include + +/* +IMPORTANT note to self: +all of these helper structs must *solely* use uint8_t-derived members +GCC doesn't seem to support packed structs any more, so to only way to avoid padding is to be uint8_t-only +*/ + +struct usb_uint16 +{ + uint8_t lo; + uint8_t hi; +}; + +#define USB_UINT16(x) { .lo = LOBYTE(x), .hi = HIBYTE(x) } + +struct device_descriptor +{ + uint8_t bLength; + uint8_t bDescriptorType; + struct usb_uint16 bcdUSB; + uint8_t bDeviceClass; + uint8_t bDeviceSubclass; + uint8_t bDeviceProtocol; + uint8_t bMaxPacketSize0; + struct usb_uint16 idVendor; + struct usb_uint16 idProduct; + struct usb_uint16 bcdDevice; + uint8_t iManufacturer; + uint8_t iProduct; + uint8_t iSerialNumber; + uint8_t bNumConfigurations; +}; + +struct configuration_descriptor +{ + uint8_t bLength; + uint8_t bDescriptorType; + struct usb_uint16 wTotalLength; + uint8_t bNumInterfaces; + uint8_t bConfigurationValue; + uint8_t iConfiguration; + uint8_t bmAttributes; + uint8_t bMaxPower; +}; + +struct interface_descriptor +{ + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bInterfaceNumber; + uint8_t bAlternateSetting; + uint8_t bNumEndpoints; + uint8_t bInterfaceClass; + uint8_t bInterfaceSubclass; + uint8_t bInterfaceProtocol; + uint8_t iInterface; +}; + +struct endpoint_descriptor +{ + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bEndpointAddress; + uint8_t bmAttributes; + struct usb_uint16 wMaxPacketSize; + uint8_t bInterval; +}; + +struct cdc_functional_descriptor_header +{ + uint8_t bFunctionLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubtype; + struct usb_uint16 bcdCDC; +}; + +struct cdc_acm_functional_descriptor +{ + uint8_t bFunctionLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubtype; + uint8_t bmCapabilities; +}; + +struct cdc_cm_functional_descriptor +{ + uint8_t bFunctionLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubtype; + uint8_t bmCapabilities; + uint8_t bDataInterface; +}; + +struct cdc_union_functional_descriptor +{ + uint8_t bFunctionLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubtype; + uint8_t bMasterInterface; + uint8_t bSlaveInterface0; +}; + +struct cdc_enet_functional_descriptor +{ + uint8_t bFunctionLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubtype; + uint8_t iMACAddress; + uint8_t bmEthernetStatistics[4]; + struct usb_uint16 wMaxSegmentSize; + struct usb_uint16 wMCFilters; + uint8_t bNumberPowerFilters; +}; + +struct interface_association_descriptor +{ + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bFirstInterface; + uint8_t bInterfaceCount; + uint8_t bFunctionClass; + uint8_t bFunctionSubClass; + uint8_t bFunctionProtocol; + uint8_t iFunction; +}; + +#endif /* __USB_MAGIC_H */ diff --git a/test/STM32F072C8T6/.cproject b/test/STM32F072C8T6/.cproject new file mode 100644 index 0000000..32416d3 --- /dev/null +++ b/test/STM32F072C8T6/.cproject @@ -0,0 +1,278 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/STM32F072C8T6/.mxproject b/test/STM32F072C8T6/.mxproject new file mode 100644 index 0000000..e9e6eb6 --- /dev/null +++ b/test/STM32F072C8T6/.mxproject @@ -0,0 +1,37 @@ +[PreviousLibFiles] +LibFiles=Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd_ex.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_usb.h;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.c;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc_ex.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_def.h;Drivers/STM32F0xx_HAL_Driver/Inc/Legacy/stm32_hal_legacy.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c_ex.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio_ex.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma_ex.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_cortex.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr_ex.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash_ex.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_exti.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_tim.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_tim_ex.h;Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_core.h;Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_ctlreq.h;Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_def.h;Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_ioreq.h;Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc/usbd_cdc.h;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.c;Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_core.c;Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ctlreq.c;Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ioreq.c;Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.c;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd_ex.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_usb.h;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.c;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc_ex.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_def.h;Drivers/STM32F0xx_HAL_Driver/Inc/Legacy/stm32_hal_legacy.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c_ex.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio_ex.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma_ex.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_cortex.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr_ex.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash_ex.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_exti.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_tim.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_tim_ex.h;Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_core.h;Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_ctlreq.h;Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_def.h;Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_ioreq.h;Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc/usbd_cdc.h;Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f072xb.h;Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f0xx.h;Drivers/CMSIS/Device/ST/STM32F0xx/Include/system_stm32f0xx.h;Drivers/CMSIS/Device/ST/STM32F0xx/Source/Templates/system_stm32f0xx.c;Drivers/CMSIS/Include/cmsis_armcc.h;Drivers/CMSIS/Include/cmsis_armclang.h;Drivers/CMSIS/Include/cmsis_compiler.h;Drivers/CMSIS/Include/cmsis_gcc.h;Drivers/CMSIS/Include/cmsis_iccarm.h;Drivers/CMSIS/Include/cmsis_version.h;Drivers/CMSIS/Include/core_armv8mbl.h;Drivers/CMSIS/Include/core_armv8mml.h;Drivers/CMSIS/Include/core_cm0.h;Drivers/CMSIS/Include/core_cm0plus.h;Drivers/CMSIS/Include/core_cm1.h;Drivers/CMSIS/Include/core_cm23.h;Drivers/CMSIS/Include/core_cm3.h;Drivers/CMSIS/Include/core_cm33.h;Drivers/CMSIS/Include/core_cm4.h;Drivers/CMSIS/Include/core_cm7.h;Drivers/CMSIS/Include/core_sc000.h;Drivers/CMSIS/Include/core_sc300.h;Drivers/CMSIS/Include/mpu_armv7.h;Drivers/CMSIS/Include/mpu_armv8.h;Drivers/CMSIS/Include/tz_context.h; + +[PreviousUsedCubeIDEFiles] +SourceFiles=Core\Src\main.c;USB_DEVICE\App\usb_device.c;USB_DEVICE\Target\usbd_conf.c;USB_DEVICE\App\usbd_desc.c;USB_DEVICE\App\usbd_cdc_if.c;Core\Src\stm32f0xx_it.c;Core\Src\stm32f0xx_hal_msp.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.c;Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_core.c;Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ctlreq.c;Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ioreq.c;Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.c;Core\Src/system_stm32f0xx.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.c;Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_core.c;Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ctlreq.c;Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ioreq.c;Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.c;Core\Src/system_stm32f0xx.c;Drivers/CMSIS/Device/ST/STM32F0xx/Source/Templates/system_stm32f0xx.c;;Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_core.c;Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ctlreq.c;Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ioreq.c;Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.c; +HeaderPath=Drivers\STM32F0xx_HAL_Driver\Inc;Drivers\STM32F0xx_HAL_Driver\Inc\Legacy;Middlewares\ST\STM32_USB_Device_Library\Core\Inc;Middlewares\ST\STM32_USB_Device_Library\Class\CDC\Inc;Drivers\CMSIS\Device\ST\STM32F0xx\Include;Drivers\CMSIS\Include;USB_DEVICE\App;USB_DEVICE\Target;Core\Inc; +CDefines=USE_HAL_DRIVER;STM32F072xB;USE_HAL_DRIVER;USE_HAL_DRIVER; + +[PreviousGenFiles] +AdvancedFolderStructure=true +HeaderFileListSize=7 +HeaderFiles#0=D:/project_in_git/CDC_ECM/test/STM32F072C8T6/USB_DEVICE/App/usb_device.h +HeaderFiles#1=D:/project_in_git/CDC_ECM/test/STM32F072C8T6/USB_DEVICE/Target/usbd_conf.h +HeaderFiles#2=D:/project_in_git/CDC_ECM/test/STM32F072C8T6/USB_DEVICE/App/usbd_desc.h +HeaderFiles#3=D:/project_in_git/CDC_ECM/test/STM32F072C8T6/USB_DEVICE/App/usbd_cdc_if.h +HeaderFiles#4=D:/project_in_git/CDC_ECM/test/STM32F072C8T6/Core/Inc/stm32f0xx_it.h +HeaderFiles#5=D:/project_in_git/CDC_ECM/test/STM32F072C8T6/Core/Inc/stm32f0xx_hal_conf.h +HeaderFiles#6=D:/project_in_git/CDC_ECM/test/STM32F072C8T6/Core/Inc/main.h +HeaderFolderListSize=3 +HeaderPath#0=D:/project_in_git/CDC_ECM/test/STM32F072C8T6/USB_DEVICE/App +HeaderPath#1=D:/project_in_git/CDC_ECM/test/STM32F072C8T6/USB_DEVICE/Target +HeaderPath#2=D:/project_in_git/CDC_ECM/test/STM32F072C8T6/Core/Inc +HeaderFiles=; +SourceFileListSize=7 +SourceFiles#0=D:/project_in_git/CDC_ECM/test/STM32F072C8T6/USB_DEVICE/App/usb_device.c +SourceFiles#1=D:/project_in_git/CDC_ECM/test/STM32F072C8T6/USB_DEVICE/Target/usbd_conf.c +SourceFiles#2=D:/project_in_git/CDC_ECM/test/STM32F072C8T6/USB_DEVICE/App/usbd_desc.c +SourceFiles#3=D:/project_in_git/CDC_ECM/test/STM32F072C8T6/USB_DEVICE/App/usbd_cdc_if.c +SourceFiles#4=D:/project_in_git/CDC_ECM/test/STM32F072C8T6/Core/Src/stm32f0xx_it.c +SourceFiles#5=D:/project_in_git/CDC_ECM/test/STM32F072C8T6/Core/Src/stm32f0xx_hal_msp.c +SourceFiles#6=D:/project_in_git/CDC_ECM/test/STM32F072C8T6/Core/Src/main.c +SourceFolderListSize=3 +SourcePath#0=D:/project_in_git/CDC_ECM/test/STM32F072C8T6/USB_DEVICE/App +SourcePath#1=D:/project_in_git/CDC_ECM/test/STM32F072C8T6/USB_DEVICE/Target +SourcePath#2=D:/project_in_git/CDC_ECM/test/STM32F072C8T6/Core/Src +SourceFiles=; + diff --git a/test/STM32F072C8T6/.project b/test/STM32F072C8T6/.project new file mode 100644 index 0000000..3508744 --- /dev/null +++ b/test/STM32F072C8T6/.project @@ -0,0 +1,40 @@ + + + stm32f072_ecm + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + com.st.stm32cube.ide.mcu.MCUProjectNature + com.st.stm32cube.ide.mcu.MCUCubeProjectNature + org.eclipse.cdt.core.cnature + com.st.stm32cube.ide.mcu.MCUCubeIdeServicesRevAProjectNature + com.st.stm32cube.ide.mcu.MCUAdvancedStructureProjectNature + com.st.stm32cube.ide.mcu.MCUEndUserDisabledTrustZoneProjectNature + com.st.stm32cube.ide.mcu.MCUSingleCpuProjectNature + com.st.stm32cube.ide.mcu.MCURootProjectNature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + ecm_src + 2 + $%7BPARENT-2-PROJECT_LOC%7D/src + + + diff --git a/test/STM32F072C8T6/.settings/language.settings.xml b/test/STM32F072C8T6/.settings/language.settings.xml new file mode 100644 index 0000000..b1e702c --- /dev/null +++ b/test/STM32F072C8T6/.settings/language.settings.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/STM32F072C8T6/Core/Inc/main.h b/test/STM32F072C8T6/Core/Inc/main.h new file mode 100644 index 0000000..a80f8f4 --- /dev/null +++ b/test/STM32F072C8T6/Core/Inc/main.h @@ -0,0 +1,71 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file : main.h + * @brief : Header for main.c file. + * This file contains the common defines of the application. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2020 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __MAIN_H +#define __MAIN_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f0xx_hal.h" + +/* Private includes ----------------------------------------------------------*/ +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +/* Exported types ------------------------------------------------------------*/ +/* USER CODE BEGIN ET */ + +/* USER CODE END ET */ + +/* Exported constants --------------------------------------------------------*/ +/* USER CODE BEGIN EC */ + +/* USER CODE END EC */ + +/* Exported macro ------------------------------------------------------------*/ +/* USER CODE BEGIN EM */ + +/* USER CODE END EM */ + +/* Exported functions prototypes ---------------------------------------------*/ +void Error_Handler(void); + +/* USER CODE BEGIN EFP */ + +/* USER CODE END EFP */ + +/* Private defines -----------------------------------------------------------*/ +/* USER CODE BEGIN Private defines */ + +/* USER CODE END Private defines */ + +#ifdef __cplusplus +} +#endif + +#endif /* __MAIN_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/test/STM32F072C8T6/Core/Inc/stm32f0xx_hal_conf.h b/test/STM32F072C8T6/Core/Inc/stm32f0xx_hal_conf.h new file mode 100644 index 0000000..63699da --- /dev/null +++ b/test/STM32F072C8T6/Core/Inc/stm32f0xx_hal_conf.h @@ -0,0 +1,319 @@ +/** + ****************************************************************************** + * @file stm32f0xx_hal_conf.h + * @brief HAL configuration file. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2016 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F0xx_HAL_CONF_H +#define __STM32F0xx_HAL_CONF_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ + +/* ########################## Module Selection ############################## */ +/** + * @brief This is the list of modules to be used in the HAL driver + */ +#define HAL_MODULE_ENABLED + /*#define HAL_ADC_MODULE_ENABLED */ +/*#define HAL_CRYP_MODULE_ENABLED */ +/*#define HAL_CAN_MODULE_ENABLED */ +/*#define HAL_CEC_MODULE_ENABLED */ +/*#define HAL_COMP_MODULE_ENABLED */ +/*#define HAL_CRC_MODULE_ENABLED */ +/*#define HAL_CRYP_MODULE_ENABLED */ +/*#define HAL_TSC_MODULE_ENABLED */ +/*#define HAL_DAC_MODULE_ENABLED */ +/*#define HAL_I2S_MODULE_ENABLED */ +/*#define HAL_IWDG_MODULE_ENABLED */ +/*#define HAL_LCD_MODULE_ENABLED */ +/*#define HAL_LPTIM_MODULE_ENABLED */ +/*#define HAL_RNG_MODULE_ENABLED */ +/*#define HAL_RTC_MODULE_ENABLED */ +/*#define HAL_SPI_MODULE_ENABLED */ +/*#define HAL_TIM_MODULE_ENABLED */ +/*#define HAL_UART_MODULE_ENABLED */ +/*#define HAL_USART_MODULE_ENABLED */ +/*#define HAL_IRDA_MODULE_ENABLED */ +/*#define HAL_SMARTCARD_MODULE_ENABLED */ +/*#define HAL_SMBUS_MODULE_ENABLED */ +/*#define HAL_WWDG_MODULE_ENABLED */ +#define HAL_PCD_MODULE_ENABLED +#define HAL_CORTEX_MODULE_ENABLED +#define HAL_DMA_MODULE_ENABLED +#define HAL_FLASH_MODULE_ENABLED +#define HAL_GPIO_MODULE_ENABLED +#define HAL_EXTI_MODULE_ENABLED +#define HAL_PWR_MODULE_ENABLED +#define HAL_RCC_MODULE_ENABLED +#define HAL_I2C_MODULE_ENABLED + +/* ########################## HSE/HSI Values adaptation ##################### */ +/** + * @brief Adjust the value of External High Speed oscillator (HSE) used in your application. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSE is used as system clock source, directly or through the PLL). + */ +#if !defined (HSE_VALUE) + #define HSE_VALUE ((uint32_t)8000000) /*!< Value of the External oscillator in Hz */ +#endif /* HSE_VALUE */ + +/** + * @brief In the following line adjust the External High Speed oscillator (HSE) Startup + * Timeout value + */ +#if !defined (HSE_STARTUP_TIMEOUT) + #define HSE_STARTUP_TIMEOUT ((uint32_t)100) /*!< Time out for HSE start up, in ms */ +#endif /* HSE_STARTUP_TIMEOUT */ + +/** + * @brief Internal High Speed oscillator (HSI) value. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSI is used as system clock source, directly or through the PLL). + */ +#if !defined (HSI_VALUE) + #define HSI_VALUE ((uint32_t)8000000) /*!< Value of the Internal oscillator in Hz*/ +#endif /* HSI_VALUE */ + +/** + * @brief In the following line adjust the Internal High Speed oscillator (HSI) Startup + * Timeout value + */ +#if !defined (HSI_STARTUP_TIMEOUT) + #define HSI_STARTUP_TIMEOUT ((uint32_t)5000) /*!< Time out for HSI start up */ +#endif /* HSI_STARTUP_TIMEOUT */ + +/** + * @brief Internal High Speed oscillator for ADC (HSI14) value. + */ +#if !defined (HSI14_VALUE) +#define HSI14_VALUE ((uint32_t)14000000) /*!< Value of the Internal High Speed oscillator for ADC in Hz. + The real value may vary depending on the variations + in voltage and temperature. */ +#endif /* HSI14_VALUE */ + +/** + * @brief Internal High Speed oscillator for USB (HSI48) value. + */ +#if !defined (HSI48_VALUE) +#define HSI48_VALUE ((uint32_t)48000000) /*!< Value of the Internal High Speed oscillator for USB in Hz. + The real value may vary depending on the variations + in voltage and temperature. */ +#endif /* HSI48_VALUE */ + +/** + * @brief Internal Low Speed oscillator (LSI) value. + */ +#if !defined (LSI_VALUE) + #define LSI_VALUE ((uint32_t)40000) +#endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz + The real value may vary depending on the variations + in voltage and temperature. */ +/** + * @brief External Low Speed oscillator (LSI) value. + */ +#if !defined (LSE_VALUE) + #define LSE_VALUE ((uint32_t)32768) /*!< Value of the External Low Speed oscillator in Hz */ +#endif /* LSE_VALUE */ + +#if !defined (LSE_STARTUP_TIMEOUT) + #define LSE_STARTUP_TIMEOUT ((uint32_t)5000) /*!< Time out for LSE start up, in ms */ +#endif /* LSE_STARTUP_TIMEOUT */ + +/* Tip: To avoid modifying this file each time you need to use different HSE, + === you can define the HSE value in your toolchain compiler preprocessor. */ + +/* ########################### System Configuration ######################### */ +/** + * @brief This is the HAL system configuration section + */ +#define VDD_VALUE ((uint32_t)3300) /*!< Value of VDD in mv */ +#define TICK_INT_PRIORITY ((uint32_t)0) /*!< tick interrupt priority (lowest by default) */ + /* Warning: Must be set to higher priority for HAL_Delay() */ + /* and HAL_GetTick() usage under interrupt context */ +#define USE_RTOS 0 +#define PREFETCH_ENABLE 1 +#define INSTRUCTION_CACHE_ENABLE 0 +#define DATA_CACHE_ENABLE 0 +#define USE_SPI_CRC 0U + +#define USE_HAL_ADC_REGISTER_CALLBACKS 0U /* ADC register callback disabled */ +#define USE_HAL_CAN_REGISTER_CALLBACKS 0U /* CAN register callback disabled */ +#define USE_HAL_COMP_REGISTER_CALLBACKS 0U /* COMP register callback disabled */ +#define USE_HAL_CEC_REGISTER_CALLBACKS 0U /* CEC register callback disabled */ +#define USE_HAL_DAC_REGISTER_CALLBACKS 0U /* DAC register callback disabled */ +#define USE_HAL_I2C_REGISTER_CALLBACKS 0U /* I2C register callback disabled */ +#define USE_HAL_SMBUS_REGISTER_CALLBACKS 0U /* SMBUS register callback disabled */ +#define USE_HAL_UART_REGISTER_CALLBACKS 0U /* UART register callback disabled */ +#define USE_HAL_USART_REGISTER_CALLBACKS 0U /* USART register callback disabled */ +#define USE_HAL_IRDA_REGISTER_CALLBACKS 0U /* IRDA register callback disabled */ +#define USE_HAL_SMARTCARD_REGISTER_CALLBACKS 0U /* SMARTCARD register callback disabled */ +#define USE_HAL_WWDG_REGISTER_CALLBACKS 0U /* WWDG register callback disabled */ +#define USE_HAL_RTC_REGISTER_CALLBACKS 0U /* RTC register callback disabled */ +#define USE_HAL_SPI_REGISTER_CALLBACKS 0U /* SPI register callback disabled */ +#define USE_HAL_I2S_REGISTER_CALLBACKS 0U /* I2S register callback disabled */ +#define USE_HAL_TIM_REGISTER_CALLBACKS 0U /* TIM register callback disabled */ +#define USE_HAL_TSC_REGISTER_CALLBACKS 0U /* TSC register callback disabled */ +#define USE_HAL_PCD_REGISTER_CALLBACKS 0U /* PCD register callback disabled */ + +/* ########################## Assert Selection ############################## */ +/** + * @brief Uncomment the line below to expanse the "assert_param" macro in the + * HAL drivers code + */ +/* #define USE_FULL_ASSERT 1U */ + +/* Includes ------------------------------------------------------------------*/ +/** + * @brief Include module's header file + */ + +#ifdef HAL_RCC_MODULE_ENABLED + #include "stm32f0xx_hal_rcc.h" +#endif /* HAL_RCC_MODULE_ENABLED */ + +#ifdef HAL_GPIO_MODULE_ENABLED + #include "stm32f0xx_hal_gpio.h" +#endif /* HAL_GPIO_MODULE_ENABLED */ + +#ifdef HAL_EXTI_MODULE_ENABLED + #include "stm32f0xx_hal_exti.h" +#endif /* HAL_EXTI_MODULE_ENABLED */ + +#ifdef HAL_DMA_MODULE_ENABLED + #include "stm32f0xx_hal_dma.h" +#endif /* HAL_DMA_MODULE_ENABLED */ + +#ifdef HAL_CORTEX_MODULE_ENABLED + #include "stm32f0xx_hal_cortex.h" +#endif /* HAL_CORTEX_MODULE_ENABLED */ + +#ifdef HAL_ADC_MODULE_ENABLED + #include "stm32f0xx_hal_adc.h" +#endif /* HAL_ADC_MODULE_ENABLED */ + +#ifdef HAL_CAN_MODULE_ENABLED + #include "stm32f0xx_hal_can.h" +#endif /* HAL_CAN_MODULE_ENABLED */ + +#ifdef HAL_CEC_MODULE_ENABLED + #include "stm32f0xx_hal_cec.h" +#endif /* HAL_CEC_MODULE_ENABLED */ + +#ifdef HAL_COMP_MODULE_ENABLED + #include "stm32f0xx_hal_comp.h" +#endif /* HAL_COMP_MODULE_ENABLED */ + +#ifdef HAL_CRC_MODULE_ENABLED + #include "stm32f0xx_hal_crc.h" +#endif /* HAL_CRC_MODULE_ENABLED */ + +#ifdef HAL_DAC_MODULE_ENABLED + #include "stm32f0xx_hal_dac.h" +#endif /* HAL_DAC_MODULE_ENABLED */ + +#ifdef HAL_FLASH_MODULE_ENABLED + #include "stm32f0xx_hal_flash.h" +#endif /* HAL_FLASH_MODULE_ENABLED */ + +#ifdef HAL_I2C_MODULE_ENABLED + #include "stm32f0xx_hal_i2c.h" +#endif /* HAL_I2C_MODULE_ENABLED */ + +#ifdef HAL_I2S_MODULE_ENABLED + #include "stm32f0xx_hal_i2s.h" +#endif /* HAL_I2S_MODULE_ENABLED */ + +#ifdef HAL_IRDA_MODULE_ENABLED + #include "stm32f0xx_hal_irda.h" +#endif /* HAL_IRDA_MODULE_ENABLED */ + +#ifdef HAL_IWDG_MODULE_ENABLED + #include "stm32f0xx_hal_iwdg.h" +#endif /* HAL_IWDG_MODULE_ENABLED */ + +#ifdef HAL_PCD_MODULE_ENABLED + #include "stm32f0xx_hal_pcd.h" +#endif /* HAL_PCD_MODULE_ENABLED */ + +#ifdef HAL_PWR_MODULE_ENABLED + #include "stm32f0xx_hal_pwr.h" +#endif /* HAL_PWR_MODULE_ENABLED */ + +#ifdef HAL_RTC_MODULE_ENABLED + #include "stm32f0xx_hal_rtc.h" +#endif /* HAL_RTC_MODULE_ENABLED */ + +#ifdef HAL_SMARTCARD_MODULE_ENABLED + #include "stm32f0xx_hal_smartcard.h" +#endif /* HAL_SMARTCARD_MODULE_ENABLED */ + +#ifdef HAL_SMBUS_MODULE_ENABLED + #include "stm32f0xx_hal_smbus.h" +#endif /* HAL_SMBUS_MODULE_ENABLED */ + +#ifdef HAL_SPI_MODULE_ENABLED + #include "stm32f0xx_hal_spi.h" +#endif /* HAL_SPI_MODULE_ENABLED */ + +#ifdef HAL_TIM_MODULE_ENABLED + #include "stm32f0xx_hal_tim.h" +#endif /* HAL_TIM_MODULE_ENABLED */ + +#ifdef HAL_TSC_MODULE_ENABLED + #include "stm32f0xx_hal_tsc.h" +#endif /* HAL_TSC_MODULE_ENABLED */ + +#ifdef HAL_UART_MODULE_ENABLED + #include "stm32f0xx_hal_uart.h" +#endif /* HAL_UART_MODULE_ENABLED */ + +#ifdef HAL_USART_MODULE_ENABLED + #include "stm32f0xx_hal_usart.h" +#endif /* HAL_USART_MODULE_ENABLED */ + +#ifdef HAL_WWDG_MODULE_ENABLED + #include "stm32f0xx_hal_wwdg.h" +#endif /* HAL_WWDG_MODULE_ENABLED */ + +/* Exported macro ------------------------------------------------------------*/ +#ifdef USE_FULL_ASSERT +/** + * @brief The assert_param macro is used for function's parameters check. + * @param expr If expr is false, it calls assert_failed function + * which reports the name of the source file and the source + * line number of the call that failed. + * If expr is true, it returns no value. + * @retval None + */ + #define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__)) +/* Exported functions ------------------------------------------------------- */ + void assert_failed(uint8_t* file, uint32_t line); +#else + #define assert_param(expr) ((void)0U) +#endif /* USE_FULL_ASSERT */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F0xx_HAL_CONF_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/test/STM32F072C8T6/Core/Inc/stm32f0xx_it.h b/test/STM32F072C8T6/Core/Inc/stm32f0xx_it.h new file mode 100644 index 0000000..18b27a4 --- /dev/null +++ b/test/STM32F072C8T6/Core/Inc/stm32f0xx_it.h @@ -0,0 +1,66 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file stm32f0xx_it.h + * @brief This file contains the headers of the interrupt handlers. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2020 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F0xx_IT_H +#define __STM32F0xx_IT_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Private includes ----------------------------------------------------------*/ +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +/* Exported types ------------------------------------------------------------*/ +/* USER CODE BEGIN ET */ + +/* USER CODE END ET */ + +/* Exported constants --------------------------------------------------------*/ +/* USER CODE BEGIN EC */ + +/* USER CODE END EC */ + +/* Exported macro ------------------------------------------------------------*/ +/* USER CODE BEGIN EM */ + +/* USER CODE END EM */ + +/* Exported functions prototypes ---------------------------------------------*/ +void NMI_Handler(void); +void HardFault_Handler(void); +void SVC_Handler(void); +void PendSV_Handler(void); +void SysTick_Handler(void); +void USB_IRQHandler(void); +/* USER CODE BEGIN EFP */ + +/* USER CODE END EFP */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F0xx_IT_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/test/STM32F072C8T6/Core/Src/main.c b/test/STM32F072C8T6/Core/Src/main.c new file mode 100644 index 0000000..dab8fc3 --- /dev/null +++ b/test/STM32F072C8T6/Core/Src/main.c @@ -0,0 +1,193 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file : main.c + * @brief : Main program body + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2020 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" +#include "usb_device.h" + +/* Private includes ----------------------------------------------------------*/ +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +/* Private typedef -----------------------------------------------------------*/ +/* USER CODE BEGIN PTD */ + +/* USER CODE END PTD */ + +/* Private define ------------------------------------------------------------*/ +/* USER CODE BEGIN PD */ +/* USER CODE END PD */ + +/* Private macro -------------------------------------------------------------*/ +/* USER CODE BEGIN PM */ + +/* USER CODE END PM */ + +/* Private variables ---------------------------------------------------------*/ + +/* USER CODE BEGIN PV */ + +/* USER CODE END PV */ + +/* Private function prototypes -----------------------------------------------*/ +void SystemClock_Config(void); +static void MX_GPIO_Init(void); +/* USER CODE BEGIN PFP */ + +/* USER CODE END PFP */ + +/* Private user code ---------------------------------------------------------*/ +/* USER CODE BEGIN 0 */ + +/* USER CODE END 0 */ + +/** + * @brief The application entry point. + * @retval int + */ +int main(void) +{ + /* USER CODE BEGIN 1 */ + + /* USER CODE END 1 */ + + /* MCU Configuration--------------------------------------------------------*/ + + /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ + HAL_Init(); + + /* USER CODE BEGIN Init */ + + /* USER CODE END Init */ + + /* Configure the system clock */ + SystemClock_Config(); + + /* USER CODE BEGIN SysInit */ + + /* USER CODE END SysInit */ + + /* Initialize all configured peripherals */ + MX_GPIO_Init(); + MX_USB_DEVICE_Init(); + /* USER CODE BEGIN 2 */ + ecm_main_init(); + /* USER CODE END 2 */ + + /* Infinite loop */ + /* USER CODE BEGIN WHILE */ + while (1) + { + /* USER CODE END WHILE */ + + /* USER CODE BEGIN 3 */ + ecm_main_loop(); + } + /* USER CODE END 3 */ +} + +/** + * @brief System Clock Configuration + * @retval None + */ +void SystemClock_Config(void) +{ + RCC_OscInitTypeDef RCC_OscInitStruct = {0}; + RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; + RCC_PeriphCLKInitTypeDef PeriphClkInit = {0}; + + /** Initializes the CPU, AHB and APB busses clocks + */ + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI48; + RCC_OscInitStruct.HSI48State = RCC_HSI48_ON; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; + if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) + { + Error_Handler(); + } + /** Initializes the CPU, AHB and APB busses clocks + */ + RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK + |RCC_CLOCKTYPE_PCLK1; + RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI48; + RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; + RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; + + if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK) + { + Error_Handler(); + } + PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USB; + PeriphClkInit.UsbClockSelection = RCC_USBCLKSOURCE_HSI48; + + if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) + { + Error_Handler(); + } +} + +/** + * @brief GPIO Initialization Function + * @param None + * @retval None + */ +static void MX_GPIO_Init(void) +{ + + /* GPIO Ports Clock Enable */ + __HAL_RCC_GPIOA_CLK_ENABLE(); + +} + +/* USER CODE BEGIN 4 */ + +/* USER CODE END 4 */ + +/** + * @brief This function is executed in case of error occurrence. + * @retval None + */ +void Error_Handler(void) +{ + /* USER CODE BEGIN Error_Handler_Debug */ + /* User can add his own implementation to report the HAL error return state */ + + /* USER CODE END Error_Handler_Debug */ +} + +#ifdef USE_FULL_ASSERT +/** + * @brief Reports the name of the source file and the source line number + * where the assert_param error has occurred. + * @param file: pointer to the source file name + * @param line: assert_param error line source number + * @retval None + */ +void assert_failed(uint8_t *file, uint32_t line) +{ + /* USER CODE BEGIN 6 */ + /* User can add his own implementation to report the file name and line number, + tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ + /* USER CODE END 6 */ +} +#endif /* USE_FULL_ASSERT */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/test/STM32F072C8T6/Core/Src/stm32f0xx_hal_msp.c b/test/STM32F072C8T6/Core/Src/stm32f0xx_hal_msp.c new file mode 100644 index 0000000..5fa4162 --- /dev/null +++ b/test/STM32F072C8T6/Core/Src/stm32f0xx_hal_msp.c @@ -0,0 +1,84 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * File Name : stm32f0xx_hal_msp.c + * Description : This file provides code for the MSP Initialization + * and de-Initialization codes. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2020 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +/* Private typedef -----------------------------------------------------------*/ +/* USER CODE BEGIN TD */ + +/* USER CODE END TD */ + +/* Private define ------------------------------------------------------------*/ +/* USER CODE BEGIN Define */ + +/* USER CODE END Define */ + +/* Private macro -------------------------------------------------------------*/ +/* USER CODE BEGIN Macro */ + +/* USER CODE END Macro */ + +/* Private variables ---------------------------------------------------------*/ +/* USER CODE BEGIN PV */ + +/* USER CODE END PV */ + +/* Private function prototypes -----------------------------------------------*/ +/* USER CODE BEGIN PFP */ + +/* USER CODE END PFP */ + +/* External functions --------------------------------------------------------*/ +/* USER CODE BEGIN ExternalFunctions */ + +/* USER CODE END ExternalFunctions */ + +/* USER CODE BEGIN 0 */ + +/* USER CODE END 0 */ +/** + * Initializes the Global MSP. + */ +void HAL_MspInit(void) +{ + /* USER CODE BEGIN MspInit 0 */ + + /* USER CODE END MspInit 0 */ + + __HAL_RCC_SYSCFG_CLK_ENABLE(); + __HAL_RCC_PWR_CLK_ENABLE(); + + /* System interrupt init*/ + + /* USER CODE BEGIN MspInit 1 */ + + /* USER CODE END MspInit 1 */ +} + +/* USER CODE BEGIN 1 */ + +/* USER CODE END 1 */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/test/STM32F072C8T6/Core/Src/stm32f0xx_it.c b/test/STM32F072C8T6/Core/Src/stm32f0xx_it.c new file mode 100644 index 0000000..7150668 --- /dev/null +++ b/test/STM32F072C8T6/Core/Src/stm32f0xx_it.c @@ -0,0 +1,158 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file stm32f0xx_it.c + * @brief Interrupt Service Routines. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2020 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" +#include "stm32f0xx_it.h" +/* Private includes ----------------------------------------------------------*/ +/* USER CODE BEGIN Includes */ +/* USER CODE END Includes */ + +/* Private typedef -----------------------------------------------------------*/ +/* USER CODE BEGIN TD */ + +/* USER CODE END TD */ + +/* Private define ------------------------------------------------------------*/ +/* USER CODE BEGIN PD */ + +/* USER CODE END PD */ + +/* Private macro -------------------------------------------------------------*/ +/* USER CODE BEGIN PM */ + +/* USER CODE END PM */ + +/* Private variables ---------------------------------------------------------*/ +/* USER CODE BEGIN PV */ +/* USER CODE END PV */ + +/* Private function prototypes -----------------------------------------------*/ +/* USER CODE BEGIN PFP */ + +/* USER CODE END PFP */ + +/* Private user code ---------------------------------------------------------*/ +/* USER CODE BEGIN 0 */ + +/* USER CODE END 0 */ + +/* External variables --------------------------------------------------------*/ +extern PCD_HandleTypeDef hpcd_USB_FS; +/* USER CODE BEGIN EV */ + +/* USER CODE END EV */ + +/******************************************************************************/ +/* Cortex-M0 Processor Interruption and Exception Handlers */ +/******************************************************************************/ +/** + * @brief This function handles Non maskable interrupt. + */ +void NMI_Handler(void) +{ + /* USER CODE BEGIN NonMaskableInt_IRQn 0 */ + + /* USER CODE END NonMaskableInt_IRQn 0 */ + /* USER CODE BEGIN NonMaskableInt_IRQn 1 */ + + /* USER CODE END NonMaskableInt_IRQn 1 */ +} + +/** + * @brief This function handles Hard fault interrupt. + */ +void HardFault_Handler(void) +{ + /* USER CODE BEGIN HardFault_IRQn 0 */ + + /* USER CODE END HardFault_IRQn 0 */ + while (1) + { + /* USER CODE BEGIN W1_HardFault_IRQn 0 */ + /* USER CODE END W1_HardFault_IRQn 0 */ + } +} + +/** + * @brief This function handles System service call via SWI instruction. + */ +void SVC_Handler(void) +{ + /* USER CODE BEGIN SVC_IRQn 0 */ + + /* USER CODE END SVC_IRQn 0 */ + /* USER CODE BEGIN SVC_IRQn 1 */ + + /* USER CODE END SVC_IRQn 1 */ +} + +/** + * @brief This function handles Pendable request for system service. + */ +void PendSV_Handler(void) +{ + /* USER CODE BEGIN PendSV_IRQn 0 */ + + /* USER CODE END PendSV_IRQn 0 */ + /* USER CODE BEGIN PendSV_IRQn 1 */ + + /* USER CODE END PendSV_IRQn 1 */ +} + +/** + * @brief This function handles System tick timer. + */ +void SysTick_Handler(void) +{ + /* USER CODE BEGIN SysTick_IRQn 0 */ + + /* USER CODE END SysTick_IRQn 0 */ + HAL_IncTick(); + /* USER CODE BEGIN SysTick_IRQn 1 */ + + /* USER CODE END SysTick_IRQn 1 */ +} + +/******************************************************************************/ +/* STM32F0xx Peripheral Interrupt Handlers */ +/* Add here the Interrupt Handlers for the used peripherals. */ +/* For the available peripheral interrupt handler names, */ +/* please refer to the startup file (startup_stm32f0xx.s). */ +/******************************************************************************/ + +/** + * @brief This function handles USB global interrupt / USB wake-up interrupt through EXTI line 18. + */ +void USB_IRQHandler(void) +{ + /* USER CODE BEGIN USB_IRQn 0 */ + + /* USER CODE END USB_IRQn 0 */ + HAL_PCD_IRQHandler(&hpcd_USB_FS); + /* USER CODE BEGIN USB_IRQn 1 */ + + /* USER CODE END USB_IRQn 1 */ +} + +/* USER CODE BEGIN 1 */ + +/* USER CODE END 1 */ +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/test/STM32F072C8T6/Core/Src/syscalls.c b/test/STM32F072C8T6/Core/Src/syscalls.c new file mode 100644 index 0000000..4ec9584 --- /dev/null +++ b/test/STM32F072C8T6/Core/Src/syscalls.c @@ -0,0 +1,159 @@ +/** + ****************************************************************************** + * @file syscalls.c + * @author Auto-generated by STM32CubeIDE + * @brief STM32CubeIDE Minimal System calls file + * + * For more information about which c-functions + * need which of these lowlevel functions + * please consult the Newlib libc-manual + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2020 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/* Includes */ +#include +#include +#include +#include +#include +#include +#include +#include + + +/* Variables */ +//#undef errno +extern int errno; +extern int __io_putchar(int ch) __attribute__((weak)); +extern int __io_getchar(void) __attribute__((weak)); + +register char * stack_ptr asm("sp"); + +char *__env[1] = { 0 }; +char **environ = __env; + + +/* Functions */ +void initialise_monitor_handles() +{ +} + +int _getpid(void) +{ + return 1; +} + +int _kill(int pid, int sig) +{ + errno = EINVAL; + return -1; +} + +void _exit (int status) +{ + _kill(status, -1); + while (1) {} /* Make sure we hang here */ +} + +__attribute__((weak)) int _read(int file, char *ptr, int len) +{ + int DataIdx; + + for (DataIdx = 0; DataIdx < len; DataIdx++) + { + *ptr++ = __io_getchar(); + } + +return len; +} + +__attribute__((weak)) int _write(int file, char *ptr, int len) +{ + int DataIdx; + + for (DataIdx = 0; DataIdx < len; DataIdx++) + { + __io_putchar(*ptr++); + } + return len; +} + +int _close(int file) +{ + return -1; +} + + +int _fstat(int file, struct stat *st) +{ + st->st_mode = S_IFCHR; + return 0; +} + +int _isatty(int file) +{ + return 1; +} + +int _lseek(int file, int ptr, int dir) +{ + return 0; +} + +int _open(char *path, int flags, ...) +{ + /* Pretend like we always fail */ + return -1; +} + +int _wait(int *status) +{ + errno = ECHILD; + return -1; +} + +int _unlink(char *name) +{ + errno = ENOENT; + return -1; +} + +int _times(struct tms *buf) +{ + return -1; +} + +int _stat(char *file, struct stat *st) +{ + st->st_mode = S_IFCHR; + return 0; +} + +int _link(char *old, char *new) +{ + errno = EMLINK; + return -1; +} + +int _fork(void) +{ + errno = EAGAIN; + return -1; +} + +int _execve(char *name, char **argv, char **env) +{ + errno = ENOMEM; + return -1; +} diff --git a/test/STM32F072C8T6/Core/Src/sysmem.c b/test/STM32F072C8T6/Core/Src/sysmem.c new file mode 100644 index 0000000..4665417 --- /dev/null +++ b/test/STM32F072C8T6/Core/Src/sysmem.c @@ -0,0 +1,58 @@ +/** + ****************************************************************************** + * @file sysmem.c + * @author Auto-generated by STM32CubeIDE + * @brief STM32CubeIDE Minimal System Memory calls file + * + * For more information about which c-functions + * need which of these lowlevel functions + * please consult the Newlib libc-manual + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2020 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/* Includes */ +#include +#include + +/* Variables */ +extern int errno; +register char * stack_ptr asm("sp"); + +/* Functions */ + +/** + _sbrk + Increase program data space. Malloc and related functions depend on this +**/ +caddr_t _sbrk(int incr) +{ + extern char end asm("end"); + static char *heap_end; + char *prev_heap_end; + + if (heap_end == 0) + heap_end = &end; + + prev_heap_end = heap_end; + if (heap_end + incr > stack_ptr) + { + errno = ENOMEM; + return (caddr_t) -1; + } + + heap_end += incr; + + return (caddr_t) prev_heap_end; +} + diff --git a/test/STM32F072C8T6/Core/Src/system_stm32f0xx.c b/test/STM32F072C8T6/Core/Src/system_stm32f0xx.c new file mode 100644 index 0000000..6a3202b --- /dev/null +++ b/test/STM32F072C8T6/Core/Src/system_stm32f0xx.c @@ -0,0 +1,265 @@ +/** + ****************************************************************************** + * @file system_stm32f0xx.c + * @author MCD Application Team + * @brief CMSIS Cortex-M0 Device Peripheral Access Layer System Source File. + * + * 1. This file provides two functions and one global variable to be called from + * user application: + * - SystemInit(): This function is called at startup just after reset and + * before branch to main program. This call is made inside + * the "startup_stm32f0xx.s" file. + * + * - SystemCoreClock variable: Contains the core clock (HCLK), it can be used + * by the user application to setup the SysTick + * timer or configure other parameters. + * + * - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must + * be called whenever the core clock is changed + * during program execution. + * + * 2. After each device reset the HSI (8 MHz) is used as system clock source. + * Then SystemInit() function is called, in "startup_stm32f0xx.s" file, to + * configure the system clock before to branch to main program. + * + * 3. This file configures the system clock as follows: + *============================================================================= + * Supported STM32F0xx device + *----------------------------------------------------------------------------- + * System Clock source | HSI + *----------------------------------------------------------------------------- + * SYSCLK(Hz) | 8000000 + *----------------------------------------------------------------------------- + * HCLK(Hz) | 8000000 + *----------------------------------------------------------------------------- + * AHB Prescaler | 1 + *----------------------------------------------------------------------------- + * APB1 Prescaler | 1 + *----------------------------------------------------------------------------- + *============================================================================= + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2016 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/** @addtogroup CMSIS + * @{ + */ + +/** @addtogroup stm32f0xx_system + * @{ + */ + +/** @addtogroup STM32F0xx_System_Private_Includes + * @{ + */ + +#include "stm32f0xx.h" + +/** + * @} + */ + +/** @addtogroup STM32F0xx_System_Private_TypesDefinitions + * @{ + */ + +/** + * @} + */ + +/** @addtogroup STM32F0xx_System_Private_Defines + * @{ + */ +#if !defined (HSE_VALUE) + #define HSE_VALUE ((uint32_t)8000000) /*!< Default value of the External oscillator in Hz. + This value can be provided and adapted by the user application. */ +#endif /* HSE_VALUE */ + +#if !defined (HSI_VALUE) + #define HSI_VALUE ((uint32_t)8000000) /*!< Default value of the Internal oscillator in Hz. + This value can be provided and adapted by the user application. */ +#endif /* HSI_VALUE */ + +#if !defined (HSI48_VALUE) +#define HSI48_VALUE ((uint32_t)48000000) /*!< Default value of the HSI48 Internal oscillator in Hz. + This value can be provided and adapted by the user application. */ +#endif /* HSI48_VALUE */ +/** + * @} + */ + +/** @addtogroup STM32F0xx_System_Private_Macros + * @{ + */ + +/** + * @} + */ + +/** @addtogroup STM32F0xx_System_Private_Variables + * @{ + */ + /* This variable is updated in three ways: + 1) by calling CMSIS function SystemCoreClockUpdate() + 2) by calling HAL API function HAL_RCC_GetHCLKFreq() + 3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency + Note: If you use this function to configure the system clock there is no need to + call the 2 first functions listed above, since SystemCoreClock variable is + updated automatically. + */ +uint32_t SystemCoreClock = 8000000; + +const uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9}; +const uint8_t APBPrescTable[8] = {0, 0, 0, 0, 1, 2, 3, 4}; + +/** + * @} + */ + +/** @addtogroup STM32F0xx_System_Private_FunctionPrototypes + * @{ + */ + +/** + * @} + */ + +/** @addtogroup STM32F0xx_System_Private_Functions + * @{ + */ + +/** + * @brief Setup the microcontroller system. + * @param None + * @retval None + */ +void SystemInit(void) +{ + /* NOTE :SystemInit(): This function is called at startup just after reset and + before branch to main program. This call is made inside + the "startup_stm32f0xx.s" file. + User can setups the default system clock (System clock source, PLL Multiplier + and Divider factors, AHB/APBx prescalers and Flash settings). + */ +} + +/** + * @brief Update SystemCoreClock variable according to Clock Register Values. + * The SystemCoreClock variable contains the core clock (HCLK), it can + * be used by the user application to setup the SysTick timer or configure + * other parameters. + * + * @note Each time the core clock (HCLK) changes, this function must be called + * to update SystemCoreClock variable value. Otherwise, any configuration + * based on this variable will be incorrect. + * + * @note - The system frequency computed by this function is not the real + * frequency in the chip. It is calculated based on the predefined + * constant and the selected clock source: + * + * - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(*) + * + * - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(**) + * + * - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(**) + * or HSI_VALUE(*) multiplied/divided by the PLL factors. + * + * (*) HSI_VALUE is a constant defined in stm32f0xx_hal.h file (default value + * 8 MHz) but the real value may vary depending on the variations + * in voltage and temperature. + * + * (**) HSE_VALUE is a constant defined in stm32f0xx_hal.h file (default value + * 8 MHz), user has to ensure that HSE_VALUE is same as the real + * frequency of the crystal used. Otherwise, this function may + * have wrong result. + * + * - The result of this function could be not correct when using fractional + * value for HSE crystal. + * + * @param None + * @retval None + */ +void SystemCoreClockUpdate (void) +{ + uint32_t tmp = 0, pllmull = 0, pllsource = 0, predivfactor = 0; + + /* Get SYSCLK source -------------------------------------------------------*/ + tmp = RCC->CFGR & RCC_CFGR_SWS; + + switch (tmp) + { + case RCC_CFGR_SWS_HSI: /* HSI used as system clock */ + SystemCoreClock = HSI_VALUE; + break; + case RCC_CFGR_SWS_HSE: /* HSE used as system clock */ + SystemCoreClock = HSE_VALUE; + break; + case RCC_CFGR_SWS_PLL: /* PLL used as system clock */ + /* Get PLL clock source and multiplication factor ----------------------*/ + pllmull = RCC->CFGR & RCC_CFGR_PLLMUL; + pllsource = RCC->CFGR & RCC_CFGR_PLLSRC; + pllmull = ( pllmull >> 18) + 2; + predivfactor = (RCC->CFGR2 & RCC_CFGR2_PREDIV) + 1; + + if (pllsource == RCC_CFGR_PLLSRC_HSE_PREDIV) + { + /* HSE used as PLL clock source : SystemCoreClock = HSE/PREDIV * PLLMUL */ + SystemCoreClock = (HSE_VALUE/predivfactor) * pllmull; + } +#if defined(STM32F042x6) || defined(STM32F048xx) || defined(STM32F072xB) || defined(STM32F078xx) || defined(STM32F091xC) || defined(STM32F098xx) + else if (pllsource == RCC_CFGR_PLLSRC_HSI48_PREDIV) + { + /* HSI48 used as PLL clock source : SystemCoreClock = HSI48/PREDIV * PLLMUL */ + SystemCoreClock = (HSI48_VALUE/predivfactor) * pllmull; + } +#endif /* STM32F042x6 || STM32F048xx || STM32F072xB || STM32F078xx || STM32F091xC || STM32F098xx */ + else + { +#if defined(STM32F042x6) || defined(STM32F048xx) || defined(STM32F070x6) \ + || defined(STM32F078xx) || defined(STM32F071xB) || defined(STM32F072xB) \ + || defined(STM32F070xB) || defined(STM32F091xC) || defined(STM32F098xx) || defined(STM32F030xC) + /* HSI used as PLL clock source : SystemCoreClock = HSI/PREDIV * PLLMUL */ + SystemCoreClock = (HSI_VALUE/predivfactor) * pllmull; +#else + /* HSI used as PLL clock source : SystemCoreClock = HSI/2 * PLLMUL */ + SystemCoreClock = (HSI_VALUE >> 1) * pllmull; +#endif /* STM32F042x6 || STM32F048xx || STM32F070x6 || + STM32F071xB || STM32F072xB || STM32F078xx || STM32F070xB || + STM32F091xC || STM32F098xx || STM32F030xC */ + } + break; + default: /* HSI used as system clock */ + SystemCoreClock = HSI_VALUE; + break; + } + /* Compute HCLK clock frequency ----------------*/ + /* Get HCLK prescaler */ + tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4)]; + /* HCLK clock frequency */ + SystemCoreClock >>= tmp; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ + diff --git a/test/STM32F072C8T6/Core/Startup/startup_stm32f072c8tx.s b/test/STM32F072C8T6/Core/Startup/startup_stm32f072c8tx.s new file mode 100644 index 0000000..9d431a9 --- /dev/null +++ b/test/STM32F072C8T6/Core/Startup/startup_stm32f072c8tx.s @@ -0,0 +1,294 @@ +/** + ****************************************************************************** + * @file startup_stm32f072xb.s + * @author MCD Application Team + * @brief STM32F072x8/STM32F072xB devices vector table for GCC toolchain. + * This module performs: + * - Set the initial SP + * - Set the initial PC == Reset_Handler, + * - Set the vector table entries with the exceptions ISR address + * - Branches to main in the C library (which eventually + * calls main()). + * After Reset the Cortex-M0 processor is in Thread mode, + * priority is Privileged, and the Stack is set to Main. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2016 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + + .syntax unified + .cpu cortex-m0 + .fpu softvfp + .thumb + +.global g_pfnVectors +.global Default_Handler + +/* start address for the initialization values of the .data section. +defined in linker script */ +.word _sidata +/* start address for the .data section. defined in linker script */ +.word _sdata +/* end address for the .data section. defined in linker script */ +.word _edata +/* start address for the .bss section. defined in linker script */ +.word _sbss +/* end address for the .bss section. defined in linker script */ +.word _ebss + + .section .text.Reset_Handler + .weak Reset_Handler + .type Reset_Handler, %function +Reset_Handler: + ldr r0, =_estack + mov sp, r0 /* set stack pointer */ + +/* Copy the data segment initializers from flash to SRAM */ + ldr r0, =_sdata + ldr r1, =_edata + ldr r2, =_sidata + movs r3, #0 + b LoopCopyDataInit + +CopyDataInit: + ldr r4, [r2, r3] + str r4, [r0, r3] + adds r3, r3, #4 + +LoopCopyDataInit: + adds r4, r0, r3 + cmp r4, r1 + bcc CopyDataInit + +/* Zero fill the bss segment. */ + ldr r2, =_sbss + ldr r4, =_ebss + movs r3, #0 + b LoopFillZerobss + +FillZerobss: + str r3, [r2] + adds r2, r2, #4 + +LoopFillZerobss: + cmp r2, r4 + bcc FillZerobss + +/* Call the clock system intitialization function.*/ + bl SystemInit +/* Call static constructors */ + bl __libc_init_array +/* Call the application's entry point.*/ + bl main + +LoopForever: + b LoopForever + + +.size Reset_Handler, .-Reset_Handler + +/** + * @brief This is the code that gets called when the processor receives an + * unexpected interrupt. This simply enters an infinite loop, preserving + * the system state for examination by a debugger. + * + * @param None + * @retval : None +*/ + .section .text.Default_Handler,"ax",%progbits +Default_Handler: +Infinite_Loop: + b Infinite_Loop + .size Default_Handler, .-Default_Handler +/****************************************************************************** +* +* The minimal vector table for a Cortex M0. Note that the proper constructs +* must be placed on this to ensure that it ends up at physical address +* 0x0000.0000. +* +******************************************************************************/ + .section .isr_vector,"a",%progbits + .type g_pfnVectors, %object + .size g_pfnVectors, .-g_pfnVectors + + +g_pfnVectors: + .word _estack + .word Reset_Handler + .word NMI_Handler + .word HardFault_Handler + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word SVC_Handler + .word 0 + .word 0 + .word PendSV_Handler + .word SysTick_Handler + .word WWDG_IRQHandler /* Window WatchDog */ + .word PVD_VDDIO2_IRQHandler /* PVD and VDDIO2 through EXTI Line detect */ + .word RTC_IRQHandler /* RTC through the EXTI line */ + .word FLASH_IRQHandler /* FLASH */ + .word RCC_CRS_IRQHandler /* RCC and CRS */ + .word EXTI0_1_IRQHandler /* EXTI Line 0 and 1 */ + .word EXTI2_3_IRQHandler /* EXTI Line 2 and 3 */ + .word EXTI4_15_IRQHandler /* EXTI Line 4 to 15 */ + .word TSC_IRQHandler /* TSC */ + .word DMA1_Channel1_IRQHandler /* DMA1 Channel 1 */ + .word DMA1_Channel2_3_IRQHandler /* DMA1 Channel 2 and Channel 3 */ + .word DMA1_Channel4_5_6_7_IRQHandler /* DMA1 Channel 4, Channel 5, Channel 6 and Channel 7*/ + .word ADC1_COMP_IRQHandler /* ADC1, COMP1 and COMP2 */ + .word TIM1_BRK_UP_TRG_COM_IRQHandler /* TIM1 Break, Update, Trigger and Commutation */ + .word TIM1_CC_IRQHandler /* TIM1 Capture Compare */ + .word TIM2_IRQHandler /* TIM2 */ + .word TIM3_IRQHandler /* TIM3 */ + .word TIM6_DAC_IRQHandler /* TIM6 and DAC */ + .word TIM7_IRQHandler /* TIM7 */ + .word TIM14_IRQHandler /* TIM14 */ + .word TIM15_IRQHandler /* TIM15 */ + .word TIM16_IRQHandler /* TIM16 */ + .word TIM17_IRQHandler /* TIM17 */ + .word I2C1_IRQHandler /* I2C1 */ + .word I2C2_IRQHandler /* I2C2 */ + .word SPI1_IRQHandler /* SPI1 */ + .word SPI2_IRQHandler /* SPI2 */ + .word USART1_IRQHandler /* USART1 */ + .word USART2_IRQHandler /* USART2 */ + .word USART3_4_IRQHandler /* USART3 and USART4 */ + .word CEC_CAN_IRQHandler /* CEC and CAN */ + .word USB_IRQHandler /* USB */ + +/******************************************************************************* +* +* Provide weak aliases for each Exception handler to the Default_Handler. +* As they are weak aliases, any function with the same name will override +* this definition. +* +*******************************************************************************/ + + .weak NMI_Handler + .thumb_set NMI_Handler,Default_Handler + + .weak HardFault_Handler + .thumb_set HardFault_Handler,Default_Handler + + .weak SVC_Handler + .thumb_set SVC_Handler,Default_Handler + + .weak PendSV_Handler + .thumb_set PendSV_Handler,Default_Handler + + .weak SysTick_Handler + .thumb_set SysTick_Handler,Default_Handler + + .weak WWDG_IRQHandler + .thumb_set WWDG_IRQHandler,Default_Handler + + .weak PVD_VDDIO2_IRQHandler + .thumb_set PVD_VDDIO2_IRQHandler,Default_Handler + + .weak RTC_IRQHandler + .thumb_set RTC_IRQHandler,Default_Handler + + .weak FLASH_IRQHandler + .thumb_set FLASH_IRQHandler,Default_Handler + + .weak RCC_CRS_IRQHandler + .thumb_set RCC_CRS_IRQHandler,Default_Handler + + .weak EXTI0_1_IRQHandler + .thumb_set EXTI0_1_IRQHandler,Default_Handler + + .weak EXTI2_3_IRQHandler + .thumb_set EXTI2_3_IRQHandler,Default_Handler + + .weak EXTI4_15_IRQHandler + .thumb_set EXTI4_15_IRQHandler,Default_Handler + + .weak TSC_IRQHandler + .thumb_set TSC_IRQHandler,Default_Handler + + .weak DMA1_Channel1_IRQHandler + .thumb_set DMA1_Channel1_IRQHandler,Default_Handler + + .weak DMA1_Channel2_3_IRQHandler + .thumb_set DMA1_Channel2_3_IRQHandler,Default_Handler + + .weak DMA1_Channel4_5_6_7_IRQHandler + .thumb_set DMA1_Channel4_5_6_7_IRQHandler,Default_Handler + + .weak ADC1_COMP_IRQHandler + .thumb_set ADC1_COMP_IRQHandler,Default_Handler + + .weak TIM1_BRK_UP_TRG_COM_IRQHandler + .thumb_set TIM1_BRK_UP_TRG_COM_IRQHandler,Default_Handler + + .weak TIM1_CC_IRQHandler + .thumb_set TIM1_CC_IRQHandler,Default_Handler + + .weak TIM2_IRQHandler + .thumb_set TIM2_IRQHandler,Default_Handler + + .weak TIM3_IRQHandler + .thumb_set TIM3_IRQHandler,Default_Handler + + .weak TIM6_DAC_IRQHandler + .thumb_set TIM6_DAC_IRQHandler,Default_Handler + + .weak TIM7_IRQHandler + .thumb_set TIM7_IRQHandler,Default_Handler + + .weak TIM14_IRQHandler + .thumb_set TIM14_IRQHandler,Default_Handler + + .weak TIM15_IRQHandler + .thumb_set TIM15_IRQHandler,Default_Handler + + .weak TIM16_IRQHandler + .thumb_set TIM16_IRQHandler,Default_Handler + + .weak TIM17_IRQHandler + .thumb_set TIM17_IRQHandler,Default_Handler + + .weak I2C1_IRQHandler + .thumb_set I2C1_IRQHandler,Default_Handler + + .weak I2C2_IRQHandler + .thumb_set I2C2_IRQHandler,Default_Handler + + .weak SPI1_IRQHandler + .thumb_set SPI1_IRQHandler,Default_Handler + + .weak SPI2_IRQHandler + .thumb_set SPI2_IRQHandler,Default_Handler + + .weak USART1_IRQHandler + .thumb_set USART1_IRQHandler,Default_Handler + + .weak USART2_IRQHandler + .thumb_set USART2_IRQHandler,Default_Handler + + .weak USART3_4_IRQHandler + .thumb_set USART3_4_IRQHandler,Default_Handler + + .weak CEC_CAN_IRQHandler + .thumb_set CEC_CAN_IRQHandler,Default_Handler + + .weak USB_IRQHandler + .thumb_set USB_IRQHandler,Default_Handler + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ + diff --git a/test/STM32F072C8T6/Debug/Core/Src/main.d b/test/STM32F072C8T6/Debug/Core/Src/main.d new file mode 100644 index 0000000..816a111 --- /dev/null +++ b/test/STM32F072C8T6/Debug/Core/Src/main.d @@ -0,0 +1,195 @@ +Core/Src/main.o: ../Core/Src/main.c ../Core/Inc/main.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal.h \ + ../Core/Inc/stm32f0xx_hal_conf.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_def.h \ + ../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f0xx.h \ + ../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f072xb.h \ + ../Drivers/CMSIS/Include/core_cm0.h \ + ../Drivers/CMSIS/Include/cmsis_version.h \ + ../Drivers/CMSIS/Include/cmsis_compiler.h \ + ../Drivers/CMSIS/Include/cmsis_gcc.h \ + ../Drivers/CMSIS/Device/ST/STM32F0xx/Include/system_stm32f0xx.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_exti.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_cortex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_usb.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr_ex.h \ + D:/project_in_git/CDC_ECM/src/src/usb_device.h \ + D:/project_in_git/CDC_ECM/src/src/usbd_def.h \ + D:/project_in_git/CDC_ECM/src/src/usbd_conf.h \ + D:/project_in_git/CDC_ECM/src/src/usbd_ecm.h \ + D:/project_in_git/CDC_ECM/src/src/usbd_ioreq.h \ + D:/project_in_git/CDC_ECM/src/src/usbd_core.h \ + D:/project_in_git/CDC_ECM/src/src/usbd_ctlreq.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/netif/etharp.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/opt.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwipopts.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/debug.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/arch.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cc.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cpu.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/pbuf.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/err.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/ip_addr.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/def.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/netif.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/ip.h \ + D:/project_in_git/CDC_ECM/src/src/ecmhelper.h \ + D:/project_in_git/CDC_ECM/src/src/usbhelper.h \ + D:/project_in_git/CDC_ECM/src/src/usbd_desc.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/init.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/icmp.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/udp.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/api.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/inet.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/dns.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/tcp_impl.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/tcp.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/mem.h \ + D:/project_in_git/CDC_ECM/src/src/time.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/apps/httpserver_raw/httpd.h \ + D:/project_in_git/CDC_ECM/src/dhcp-server/dhserver.h \ + D:/project_in_git/CDC_ECM/src/dns-server/dnserver.h \ + D:/project_in_git/CDC_ECM/src/src/ecm_main.h + +../Core/Inc/main.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal.h: + +../Core/Inc/stm32f0xx_hal_conf.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_def.h: + +../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f0xx.h: + +../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f072xb.h: + +../Drivers/CMSIS/Include/core_cm0.h: + +../Drivers/CMSIS/Include/cmsis_version.h: + +../Drivers/CMSIS/Include/cmsis_compiler.h: + +../Drivers/CMSIS/Include/cmsis_gcc.h: + +../Drivers/CMSIS/Device/ST/STM32F0xx/Include/system_stm32f0xx.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_exti.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_cortex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_usb.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr_ex.h: + +D:/project_in_git/CDC_ECM/src/src/usb_device.h: + +D:/project_in_git/CDC_ECM/src/src/usbd_def.h: + +D:/project_in_git/CDC_ECM/src/src/usbd_conf.h: + +D:/project_in_git/CDC_ECM/src/src/usbd_ecm.h: + +D:/project_in_git/CDC_ECM/src/src/usbd_ioreq.h: + +D:/project_in_git/CDC_ECM/src/src/usbd_core.h: + +D:/project_in_git/CDC_ECM/src/src/usbd_ctlreq.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/netif/etharp.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/opt.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwipopts.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/debug.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/arch.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cc.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cpu.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/pbuf.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/err.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/ip_addr.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/def.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/netif.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/ip.h: + +D:/project_in_git/CDC_ECM/src/src/ecmhelper.h: + +D:/project_in_git/CDC_ECM/src/src/usbhelper.h: + +D:/project_in_git/CDC_ECM/src/src/usbd_desc.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/init.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/icmp.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/udp.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/api.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/inet.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/dns.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/tcp_impl.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/tcp.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/mem.h: + +D:/project_in_git/CDC_ECM/src/src/time.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/apps/httpserver_raw/httpd.h: + +D:/project_in_git/CDC_ECM/src/dhcp-server/dhserver.h: + +D:/project_in_git/CDC_ECM/src/dns-server/dnserver.h: + +D:/project_in_git/CDC_ECM/src/src/ecm_main.h: diff --git a/test/STM32F072C8T6/Debug/Core/Src/main.o b/test/STM32F072C8T6/Debug/Core/Src/main.o new file mode 100644 index 0000000..3e7deb7 Binary files /dev/null and b/test/STM32F072C8T6/Debug/Core/Src/main.o differ diff --git a/test/STM32F072C8T6/Debug/Core/Src/main.su b/test/STM32F072C8T6/Debug/Core/Src/main.su new file mode 100644 index 0000000..54348a3 --- /dev/null +++ b/test/STM32F072C8T6/Debug/Core/Src/main.su @@ -0,0 +1,4 @@ +main.c:66:5:main 8 static +main.c:111:6:SystemClock_Config 112 static +main.c:152:13:MX_GPIO_Init 16 static +main.c:168:6:Error_Handler 8 static diff --git a/test/STM32F072C8T6/Debug/Core/Src/stm32f0xx_hal_msp.d b/test/STM32F072C8T6/Debug/Core/Src/stm32f0xx_hal_msp.d new file mode 100644 index 0000000..d643b30 --- /dev/null +++ b/test/STM32F072C8T6/Debug/Core/Src/stm32f0xx_hal_msp.d @@ -0,0 +1,84 @@ +Core/Src/stm32f0xx_hal_msp.o: ../Core/Src/stm32f0xx_hal_msp.c \ + ../Core/Inc/main.h ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal.h \ + ../Core/Inc/stm32f0xx_hal_conf.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_def.h \ + ../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f0xx.h \ + ../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f072xb.h \ + ../Drivers/CMSIS/Include/core_cm0.h \ + ../Drivers/CMSIS/Include/cmsis_version.h \ + ../Drivers/CMSIS/Include/cmsis_compiler.h \ + ../Drivers/CMSIS/Include/cmsis_gcc.h \ + ../Drivers/CMSIS/Device/ST/STM32F0xx/Include/system_stm32f0xx.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_exti.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_cortex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_usb.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr_ex.h + +../Core/Inc/main.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal.h: + +../Core/Inc/stm32f0xx_hal_conf.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_def.h: + +../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f0xx.h: + +../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f072xb.h: + +../Drivers/CMSIS/Include/core_cm0.h: + +../Drivers/CMSIS/Include/cmsis_version.h: + +../Drivers/CMSIS/Include/cmsis_compiler.h: + +../Drivers/CMSIS/Include/cmsis_gcc.h: + +../Drivers/CMSIS/Device/ST/STM32F0xx/Include/system_stm32f0xx.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_exti.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_cortex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_usb.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr_ex.h: diff --git a/test/STM32F072C8T6/Debug/Core/Src/stm32f0xx_hal_msp.o b/test/STM32F072C8T6/Debug/Core/Src/stm32f0xx_hal_msp.o new file mode 100644 index 0000000..74a6e2a Binary files /dev/null and b/test/STM32F072C8T6/Debug/Core/Src/stm32f0xx_hal_msp.o differ diff --git a/test/STM32F072C8T6/Debug/Core/Src/stm32f0xx_hal_msp.su b/test/STM32F072C8T6/Debug/Core/Src/stm32f0xx_hal_msp.su new file mode 100644 index 0000000..54dc9b0 --- /dev/null +++ b/test/STM32F072C8T6/Debug/Core/Src/stm32f0xx_hal_msp.su @@ -0,0 +1 @@ +stm32f0xx_hal_msp.c:64:6:HAL_MspInit 16 static diff --git a/test/STM32F072C8T6/Debug/Core/Src/stm32f0xx_it.d b/test/STM32F072C8T6/Debug/Core/Src/stm32f0xx_it.d new file mode 100644 index 0000000..191fda4 --- /dev/null +++ b/test/STM32F072C8T6/Debug/Core/Src/stm32f0xx_it.d @@ -0,0 +1,87 @@ +Core/Src/stm32f0xx_it.o: ../Core/Src/stm32f0xx_it.c ../Core/Inc/main.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal.h \ + ../Core/Inc/stm32f0xx_hal_conf.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_def.h \ + ../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f0xx.h \ + ../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f072xb.h \ + ../Drivers/CMSIS/Include/core_cm0.h \ + ../Drivers/CMSIS/Include/cmsis_version.h \ + ../Drivers/CMSIS/Include/cmsis_compiler.h \ + ../Drivers/CMSIS/Include/cmsis_gcc.h \ + ../Drivers/CMSIS/Device/ST/STM32F0xx/Include/system_stm32f0xx.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_exti.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_cortex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_usb.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr_ex.h \ + ../Core/Inc/stm32f0xx_it.h + +../Core/Inc/main.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal.h: + +../Core/Inc/stm32f0xx_hal_conf.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_def.h: + +../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f0xx.h: + +../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f072xb.h: + +../Drivers/CMSIS/Include/core_cm0.h: + +../Drivers/CMSIS/Include/cmsis_version.h: + +../Drivers/CMSIS/Include/cmsis_compiler.h: + +../Drivers/CMSIS/Include/cmsis_gcc.h: + +../Drivers/CMSIS/Device/ST/STM32F0xx/Include/system_stm32f0xx.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_exti.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_cortex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_usb.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr_ex.h: + +../Core/Inc/stm32f0xx_it.h: diff --git a/test/STM32F072C8T6/Debug/Core/Src/stm32f0xx_it.o b/test/STM32F072C8T6/Debug/Core/Src/stm32f0xx_it.o new file mode 100644 index 0000000..527d4b0 Binary files /dev/null and b/test/STM32F072C8T6/Debug/Core/Src/stm32f0xx_it.o differ diff --git a/test/STM32F072C8T6/Debug/Core/Src/stm32f0xx_it.su b/test/STM32F072C8T6/Debug/Core/Src/stm32f0xx_it.su new file mode 100644 index 0000000..f13ec87 --- /dev/null +++ b/test/STM32F072C8T6/Debug/Core/Src/stm32f0xx_it.su @@ -0,0 +1,6 @@ +stm32f0xx_it.c:69:6:NMI_Handler 8 static +stm32f0xx_it.c:82:6:HardFault_Handler 8 static +stm32f0xx_it.c:97:6:SVC_Handler 8 static +stm32f0xx_it.c:110:6:PendSV_Handler 8 static +stm32f0xx_it.c:123:6:SysTick_Handler 8 static +stm32f0xx_it.c:144:6:USB_IRQHandler 8 static diff --git a/test/STM32F072C8T6/Debug/Core/Src/subdir.mk b/test/STM32F072C8T6/Debug/Core/Src/subdir.mk new file mode 100644 index 0000000..e97d5e8 --- /dev/null +++ b/test/STM32F072C8T6/Debug/Core/Src/subdir.mk @@ -0,0 +1,44 @@ +################################################################################ +# Automatically-generated file. Do not edit! +################################################################################ + +# Add inputs and outputs from these tool invocations to the build variables +C_SRCS += \ +../Core/Src/main.c \ +../Core/Src/stm32f0xx_hal_msp.c \ +../Core/Src/stm32f0xx_it.c \ +../Core/Src/syscalls.c \ +../Core/Src/sysmem.c \ +../Core/Src/system_stm32f0xx.c + +OBJS += \ +./Core/Src/main.o \ +./Core/Src/stm32f0xx_hal_msp.o \ +./Core/Src/stm32f0xx_it.o \ +./Core/Src/syscalls.o \ +./Core/Src/sysmem.o \ +./Core/Src/system_stm32f0xx.o + +C_DEPS += \ +./Core/Src/main.d \ +./Core/Src/stm32f0xx_hal_msp.d \ +./Core/Src/stm32f0xx_it.d \ +./Core/Src/syscalls.d \ +./Core/Src/sysmem.d \ +./Core/Src/system_stm32f0xx.d + + +# Each subdirectory must supply rules for building sources it contributes +Core/Src/main.o: ../Core/Src/main.c + arm-none-eabi-gcc "$<" -mcpu=cortex-m0 -std=gnu11 -g3 -DUSE_HAL_DRIVER -DSTM32F072xB -DDEBUG -c -I"D:/project_in_git/CDC_ECM/src/dns-server" -I../USB_DEVICE/Target -I../Drivers/STM32F0xx_HAL_Driver/Inc/Legacy -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4" -I"D:/project_in_git/CDC_ECM/src" -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Drivers/STM32F0xx_HAL_Driver/Inc -I../Drivers/CMSIS/Include -I"D:/project_in_git/CDC_ECM/src/dhcp-server" -I../Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -I../USB_DEVICE/App -I../Drivers/CMSIS/Device/ST/STM32F0xx/Include -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include" -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/apps/httpserver_raw" -I"D:/project_in_git/CDC_ECM/src/src" -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"Core/Src/main.d" -MT"$@" --specs=nano.specs -mfloat-abi=soft -mthumb -o "$@" +Core/Src/stm32f0xx_hal_msp.o: ../Core/Src/stm32f0xx_hal_msp.c + arm-none-eabi-gcc "$<" -mcpu=cortex-m0 -std=gnu11 -g3 -DUSE_HAL_DRIVER -DSTM32F072xB -DDEBUG -c -I"D:/project_in_git/CDC_ECM/src/dns-server" -I../USB_DEVICE/Target -I../Drivers/STM32F0xx_HAL_Driver/Inc/Legacy -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4" -I"D:/project_in_git/CDC_ECM/src" -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Drivers/STM32F0xx_HAL_Driver/Inc -I../Drivers/CMSIS/Include -I"D:/project_in_git/CDC_ECM/src/dhcp-server" -I../Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -I../USB_DEVICE/App -I../Drivers/CMSIS/Device/ST/STM32F0xx/Include -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include" -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/apps/httpserver_raw" -I"D:/project_in_git/CDC_ECM/src/src" -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"Core/Src/stm32f0xx_hal_msp.d" -MT"$@" --specs=nano.specs -mfloat-abi=soft -mthumb -o "$@" +Core/Src/stm32f0xx_it.o: ../Core/Src/stm32f0xx_it.c + arm-none-eabi-gcc "$<" -mcpu=cortex-m0 -std=gnu11 -g3 -DUSE_HAL_DRIVER -DSTM32F072xB -DDEBUG -c -I"D:/project_in_git/CDC_ECM/src/dns-server" -I../USB_DEVICE/Target -I../Drivers/STM32F0xx_HAL_Driver/Inc/Legacy -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4" -I"D:/project_in_git/CDC_ECM/src" -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Drivers/STM32F0xx_HAL_Driver/Inc -I../Drivers/CMSIS/Include -I"D:/project_in_git/CDC_ECM/src/dhcp-server" -I../Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -I../USB_DEVICE/App -I../Drivers/CMSIS/Device/ST/STM32F0xx/Include -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include" -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/apps/httpserver_raw" -I"D:/project_in_git/CDC_ECM/src/src" -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"Core/Src/stm32f0xx_it.d" -MT"$@" --specs=nano.specs -mfloat-abi=soft -mthumb -o "$@" +Core/Src/syscalls.o: ../Core/Src/syscalls.c + arm-none-eabi-gcc "$<" -mcpu=cortex-m0 -std=gnu11 -g3 -DUSE_HAL_DRIVER -DSTM32F072xB -DDEBUG -c -I"D:/project_in_git/CDC_ECM/src/dns-server" -I../USB_DEVICE/Target -I../Drivers/STM32F0xx_HAL_Driver/Inc/Legacy -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4" -I"D:/project_in_git/CDC_ECM/src" -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Drivers/STM32F0xx_HAL_Driver/Inc -I../Drivers/CMSIS/Include -I"D:/project_in_git/CDC_ECM/src/dhcp-server" -I../Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -I../USB_DEVICE/App -I../Drivers/CMSIS/Device/ST/STM32F0xx/Include -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include" -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/apps/httpserver_raw" -I"D:/project_in_git/CDC_ECM/src/src" -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"Core/Src/syscalls.d" -MT"$@" --specs=nano.specs -mfloat-abi=soft -mthumb -o "$@" +Core/Src/sysmem.o: ../Core/Src/sysmem.c + arm-none-eabi-gcc "$<" -mcpu=cortex-m0 -std=gnu11 -g3 -DUSE_HAL_DRIVER -DSTM32F072xB -DDEBUG -c -I"D:/project_in_git/CDC_ECM/src/dns-server" -I../USB_DEVICE/Target -I../Drivers/STM32F0xx_HAL_Driver/Inc/Legacy -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4" -I"D:/project_in_git/CDC_ECM/src" -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Drivers/STM32F0xx_HAL_Driver/Inc -I../Drivers/CMSIS/Include -I"D:/project_in_git/CDC_ECM/src/dhcp-server" -I../Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -I../USB_DEVICE/App -I../Drivers/CMSIS/Device/ST/STM32F0xx/Include -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include" -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/apps/httpserver_raw" -I"D:/project_in_git/CDC_ECM/src/src" -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"Core/Src/sysmem.d" -MT"$@" --specs=nano.specs -mfloat-abi=soft -mthumb -o "$@" +Core/Src/system_stm32f0xx.o: ../Core/Src/system_stm32f0xx.c + arm-none-eabi-gcc "$<" -mcpu=cortex-m0 -std=gnu11 -g3 -DUSE_HAL_DRIVER -DSTM32F072xB -DDEBUG -c -I"D:/project_in_git/CDC_ECM/src/dns-server" -I../USB_DEVICE/Target -I../Drivers/STM32F0xx_HAL_Driver/Inc/Legacy -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4" -I"D:/project_in_git/CDC_ECM/src" -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Drivers/STM32F0xx_HAL_Driver/Inc -I../Drivers/CMSIS/Include -I"D:/project_in_git/CDC_ECM/src/dhcp-server" -I../Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -I../USB_DEVICE/App -I../Drivers/CMSIS/Device/ST/STM32F0xx/Include -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include" -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/apps/httpserver_raw" -I"D:/project_in_git/CDC_ECM/src/src" -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"Core/Src/system_stm32f0xx.d" -MT"$@" --specs=nano.specs -mfloat-abi=soft -mthumb -o "$@" + diff --git a/test/STM32F072C8T6/Debug/Core/Src/syscalls.d b/test/STM32F072C8T6/Debug/Core/Src/syscalls.d new file mode 100644 index 0000000..e14669a --- /dev/null +++ b/test/STM32F072C8T6/Debug/Core/Src/syscalls.d @@ -0,0 +1 @@ +Core/Src/syscalls.o: ../Core/Src/syscalls.c diff --git a/test/STM32F072C8T6/Debug/Core/Src/syscalls.o b/test/STM32F072C8T6/Debug/Core/Src/syscalls.o new file mode 100644 index 0000000..14f8b65 Binary files /dev/null and b/test/STM32F072C8T6/Debug/Core/Src/syscalls.o differ diff --git a/test/STM32F072C8T6/Debug/Core/Src/syscalls.su b/test/STM32F072C8T6/Debug/Core/Src/syscalls.su new file mode 100644 index 0000000..7b497b8 --- /dev/null +++ b/test/STM32F072C8T6/Debug/Core/Src/syscalls.su @@ -0,0 +1,18 @@ +syscalls.c:48:6:initialise_monitor_handles 8 static +syscalls.c:52:5:_getpid 8 static +syscalls.c:57:5:_kill 16 static +syscalls.c:63:6:_exit 16 static +syscalls.c:69:27:_read 32 static +syscalls.c:81:27:_write 32 static +syscalls.c:92:5:_close 16 static +syscalls.c:98:5:_fstat 16 static +syscalls.c:104:5:_isatty 16 static +syscalls.c:109:5:_lseek 24 static +syscalls.c:114:5:_open 20 static +syscalls.c:120:5:_wait 16 static +syscalls.c:126:5:_unlink 16 static +syscalls.c:132:5:_times 16 static +syscalls.c:137:5:_stat 16 static +syscalls.c:143:5:_link 16 static +syscalls.c:149:5:_fork 8 static +syscalls.c:155:5:_execve 24 static diff --git a/test/STM32F072C8T6/Debug/Core/Src/sysmem.d b/test/STM32F072C8T6/Debug/Core/Src/sysmem.d new file mode 100644 index 0000000..9492cfb --- /dev/null +++ b/test/STM32F072C8T6/Debug/Core/Src/sysmem.d @@ -0,0 +1 @@ +Core/Src/sysmem.o: ../Core/Src/sysmem.c diff --git a/test/STM32F072C8T6/Debug/Core/Src/sysmem.o b/test/STM32F072C8T6/Debug/Core/Src/sysmem.o new file mode 100644 index 0000000..4db0492 Binary files /dev/null and b/test/STM32F072C8T6/Debug/Core/Src/sysmem.o differ diff --git a/test/STM32F072C8T6/Debug/Core/Src/sysmem.su b/test/STM32F072C8T6/Debug/Core/Src/sysmem.su new file mode 100644 index 0000000..a6c758e --- /dev/null +++ b/test/STM32F072C8T6/Debug/Core/Src/sysmem.su @@ -0,0 +1 @@ +sysmem.c:38:9:_sbrk 24 static diff --git a/test/STM32F072C8T6/Debug/Core/Src/system_stm32f0xx.d b/test/STM32F072C8T6/Debug/Core/Src/system_stm32f0xx.d new file mode 100644 index 0000000..8548cca --- /dev/null +++ b/test/STM32F072C8T6/Debug/Core/Src/system_stm32f0xx.d @@ -0,0 +1,82 @@ +Core/Src/system_stm32f0xx.o: ../Core/Src/system_stm32f0xx.c \ + ../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f0xx.h \ + ../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f072xb.h \ + ../Drivers/CMSIS/Include/core_cm0.h \ + ../Drivers/CMSIS/Include/cmsis_version.h \ + ../Drivers/CMSIS/Include/cmsis_compiler.h \ + ../Drivers/CMSIS/Include/cmsis_gcc.h \ + ../Drivers/CMSIS/Device/ST/STM32F0xx/Include/system_stm32f0xx.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal.h \ + ../Core/Inc/stm32f0xx_hal_conf.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_def.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_exti.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_cortex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_usb.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr_ex.h + +../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f0xx.h: + +../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f072xb.h: + +../Drivers/CMSIS/Include/core_cm0.h: + +../Drivers/CMSIS/Include/cmsis_version.h: + +../Drivers/CMSIS/Include/cmsis_compiler.h: + +../Drivers/CMSIS/Include/cmsis_gcc.h: + +../Drivers/CMSIS/Device/ST/STM32F0xx/Include/system_stm32f0xx.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal.h: + +../Core/Inc/stm32f0xx_hal_conf.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_def.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_exti.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_cortex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_usb.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr_ex.h: diff --git a/test/STM32F072C8T6/Debug/Core/Src/system_stm32f0xx.o b/test/STM32F072C8T6/Debug/Core/Src/system_stm32f0xx.o new file mode 100644 index 0000000..397ee36 Binary files /dev/null and b/test/STM32F072C8T6/Debug/Core/Src/system_stm32f0xx.o differ diff --git a/test/STM32F072C8T6/Debug/Core/Src/system_stm32f0xx.su b/test/STM32F072C8T6/Debug/Core/Src/system_stm32f0xx.su new file mode 100644 index 0000000..b536b4b --- /dev/null +++ b/test/STM32F072C8T6/Debug/Core/Src/system_stm32f0xx.su @@ -0,0 +1,2 @@ +system_stm32f0xx.c:146:6:SystemInit 8 static +system_stm32f0xx.c:192:6:SystemCoreClockUpdate 24 static diff --git a/test/STM32F072C8T6/Debug/Core/Startup/startup_stm32f072c8tx.o b/test/STM32F072C8T6/Debug/Core/Startup/startup_stm32f072c8tx.o new file mode 100644 index 0000000..d458713 Binary files /dev/null and b/test/STM32F072C8T6/Debug/Core/Startup/startup_stm32f072c8tx.o differ diff --git a/test/STM32F072C8T6/Debug/Core/Startup/subdir.mk b/test/STM32F072C8T6/Debug/Core/Startup/subdir.mk new file mode 100644 index 0000000..3f4ba10 --- /dev/null +++ b/test/STM32F072C8T6/Debug/Core/Startup/subdir.mk @@ -0,0 +1,16 @@ +################################################################################ +# Automatically-generated file. Do not edit! +################################################################################ + +# Add inputs and outputs from these tool invocations to the build variables +S_SRCS += \ +../Core/Startup/startup_stm32f072c8tx.s + +OBJS += \ +./Core/Startup/startup_stm32f072c8tx.o + + +# Each subdirectory must supply rules for building sources it contributes +Core/Startup/%.o: ../Core/Startup/%.s + arm-none-eabi-gcc -mcpu=cortex-m0 -g3 -c -I"D:/project_in_git/CDC_ECM/src/dns-server" -I"D:/project_in_git/CDC_ECM/src/dhcp-server" -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4" -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include" -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/apps/httpserver_raw" -I"D:/project_in_git/CDC_ECM/src" -I"D:/project_in_git/CDC_ECM/src/src" -x assembler-with-cpp --specs=nano.specs -mfloat-abi=soft -mthumb -o "$@" "$<" + diff --git a/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.d b/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.d new file mode 100644 index 0000000..4233648 --- /dev/null +++ b/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.d @@ -0,0 +1,83 @@ +Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o: \ + ../Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.c \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal.h \ + ../Core/Inc/stm32f0xx_hal_conf.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_def.h \ + ../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f0xx.h \ + ../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f072xb.h \ + ../Drivers/CMSIS/Include/core_cm0.h \ + ../Drivers/CMSIS/Include/cmsis_version.h \ + ../Drivers/CMSIS/Include/cmsis_compiler.h \ + ../Drivers/CMSIS/Include/cmsis_gcc.h \ + ../Drivers/CMSIS/Device/ST/STM32F0xx/Include/system_stm32f0xx.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_exti.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_cortex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_usb.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr_ex.h + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal.h: + +../Core/Inc/stm32f0xx_hal_conf.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_def.h: + +../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f0xx.h: + +../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f072xb.h: + +../Drivers/CMSIS/Include/core_cm0.h: + +../Drivers/CMSIS/Include/cmsis_version.h: + +../Drivers/CMSIS/Include/cmsis_compiler.h: + +../Drivers/CMSIS/Include/cmsis_gcc.h: + +../Drivers/CMSIS/Device/ST/STM32F0xx/Include/system_stm32f0xx.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_exti.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_cortex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_usb.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr_ex.h: diff --git a/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o b/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o new file mode 100644 index 0000000..d9c8918 Binary files /dev/null and b/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o differ diff --git a/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.su b/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.su new file mode 100644 index 0000000..026e9f0 --- /dev/null +++ b/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.su @@ -0,0 +1,23 @@ +stm32f0xx_hal.c:141:19:HAL_Init 8 static +stm32f0xx_hal.c:165:19:HAL_DeInit 8 static +stm32f0xx_hal.c:188:13:HAL_MspInit 8 static +stm32f0xx_hal.c:199:13:HAL_MspDeInit 8 static +stm32f0xx_hal.c:222:26:HAL_InitTick 24 static +stm32f0xx_hal.c:281:13:HAL_IncTick 8 static +stm32f0xx_hal.c:292:17:HAL_GetTick 8 static +stm32f0xx_hal.c:301:10:HAL_GetTickPrio 8 static +stm32f0xx_hal.c:310:19:HAL_SetTickFreq 32 static +stm32f0xx_hal.c:342:21:HAL_GetTickFreq 8 static +stm32f0xx_hal.c:358:13:HAL_Delay 24 static +stm32f0xx_hal.c:384:13:HAL_SuspendTick 8 static +stm32f0xx_hal.c:401:13:HAL_ResumeTick 8 static +stm32f0xx_hal.c:411:10:HAL_GetHalVersion 8 static +stm32f0xx_hal.c:420:10:HAL_GetREVID 8 static +stm32f0xx_hal.c:429:10:HAL_GetDEVID 8 static +stm32f0xx_hal.c:438:10:HAL_GetUIDw0 8 static +stm32f0xx_hal.c:447:10:HAL_GetUIDw1 8 static +stm32f0xx_hal.c:456:10:HAL_GetUIDw2 8 static +stm32f0xx_hal.c:465:6:HAL_DBGMCU_EnableDBGStopMode 8 static +stm32f0xx_hal.c:474:6:HAL_DBGMCU_DisableDBGStopMode 8 static +stm32f0xx_hal.c:483:6:HAL_DBGMCU_EnableDBGStandbyMode 8 static +stm32f0xx_hal.c:492:6:HAL_DBGMCU_DisableDBGStandbyMode 8 static diff --git a/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.d b/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.d new file mode 100644 index 0000000..12a6aa3 --- /dev/null +++ b/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.d @@ -0,0 +1,83 @@ +Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o: \ + ../Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.c \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal.h \ + ../Core/Inc/stm32f0xx_hal_conf.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_def.h \ + ../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f0xx.h \ + ../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f072xb.h \ + ../Drivers/CMSIS/Include/core_cm0.h \ + ../Drivers/CMSIS/Include/cmsis_version.h \ + ../Drivers/CMSIS/Include/cmsis_compiler.h \ + ../Drivers/CMSIS/Include/cmsis_gcc.h \ + ../Drivers/CMSIS/Device/ST/STM32F0xx/Include/system_stm32f0xx.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_exti.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_cortex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_usb.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr_ex.h + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal.h: + +../Core/Inc/stm32f0xx_hal_conf.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_def.h: + +../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f0xx.h: + +../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f072xb.h: + +../Drivers/CMSIS/Include/core_cm0.h: + +../Drivers/CMSIS/Include/cmsis_version.h: + +../Drivers/CMSIS/Include/cmsis_compiler.h: + +../Drivers/CMSIS/Include/cmsis_gcc.h: + +../Drivers/CMSIS/Device/ST/STM32F0xx/Include/system_stm32f0xx.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_exti.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_cortex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_usb.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr_ex.h: diff --git a/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o b/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o new file mode 100644 index 0000000..21bf2ce Binary files /dev/null and b/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o differ diff --git a/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.su b/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.su new file mode 100644 index 0000000..ebbeae4 --- /dev/null +++ b/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.su @@ -0,0 +1,21 @@ +core_cm0.h:623:22:__NVIC_EnableIRQ 16 static +core_cm0.h:659:22:__NVIC_DisableIRQ 16 static,ignoring_inline_asm +core_cm0.h:678:26:__NVIC_GetPendingIRQ 16 static +core_cm0.h:697:22:__NVIC_SetPendingIRQ 16 static +core_cm0.h:712:22:__NVIC_ClearPendingIRQ 16 static +core_cm0.h:730:22:__NVIC_SetPriority 24 static +core_cm0.h:754:26:__NVIC_GetPriority 16 static +core_cm0.h:856:34:__NVIC_SystemReset 8 static,ignoring_inline_asm +core_cm0.h:920:26:SysTick_Config 16 static +stm32f0xx_hal_cortex.c:136:6:HAL_NVIC_SetPriority 24 static +stm32f0xx_hal_cortex.c:152:6:HAL_NVIC_EnableIRQ 16 static +stm32f0xx_hal_cortex.c:168:6:HAL_NVIC_DisableIRQ 16 static +stm32f0xx_hal_cortex.c:181:6:HAL_NVIC_SystemReset 8 static +stm32f0xx_hal_cortex.c:194:10:HAL_SYSTICK_Config 16 static +stm32f0xx_hal_cortex.c:226:10:HAL_NVIC_GetPriority 16 static +stm32f0xx_hal_cortex.c:239:6:HAL_NVIC_SetPendingIRQ 16 static +stm32f0xx_hal_cortex.c:257:10:HAL_NVIC_GetPendingIRQ 16 static +stm32f0xx_hal_cortex.c:273:6:HAL_NVIC_ClearPendingIRQ 16 static +stm32f0xx_hal_cortex.c:290:6:HAL_SYSTICK_CLKSourceConfig 16 static +stm32f0xx_hal_cortex.c:308:6:HAL_SYSTICK_IRQHandler 8 static +stm32f0xx_hal_cortex.c:317:13:HAL_SYSTICK_Callback 8 static diff --git a/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.d b/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.d new file mode 100644 index 0000000..df751ae --- /dev/null +++ b/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.d @@ -0,0 +1,83 @@ +Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o: \ + ../Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.c \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal.h \ + ../Core/Inc/stm32f0xx_hal_conf.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_def.h \ + ../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f0xx.h \ + ../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f072xb.h \ + ../Drivers/CMSIS/Include/core_cm0.h \ + ../Drivers/CMSIS/Include/cmsis_version.h \ + ../Drivers/CMSIS/Include/cmsis_compiler.h \ + ../Drivers/CMSIS/Include/cmsis_gcc.h \ + ../Drivers/CMSIS/Device/ST/STM32F0xx/Include/system_stm32f0xx.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_exti.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_cortex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_usb.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr_ex.h + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal.h: + +../Core/Inc/stm32f0xx_hal_conf.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_def.h: + +../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f0xx.h: + +../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f072xb.h: + +../Drivers/CMSIS/Include/core_cm0.h: + +../Drivers/CMSIS/Include/cmsis_version.h: + +../Drivers/CMSIS/Include/cmsis_compiler.h: + +../Drivers/CMSIS/Include/cmsis_gcc.h: + +../Drivers/CMSIS/Device/ST/STM32F0xx/Include/system_stm32f0xx.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_exti.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_cortex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_usb.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr_ex.h: diff --git a/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o b/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o new file mode 100644 index 0000000..3171e27 Binary files /dev/null and b/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o differ diff --git a/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.su b/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.su new file mode 100644 index 0000000..a290a3a --- /dev/null +++ b/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.su @@ -0,0 +1,14 @@ +stm32f0xx_hal_dma.c:138:19:HAL_DMA_Init 24 static +stm32f0xx_hal_dma.c:200:19:HAL_DMA_DeInit 16 static +stm32f0xx_hal_dma.c:282:19:HAL_DMA_Start 32 static +stm32f0xx_hal_dma.c:329:19:HAL_DMA_Start_IT 32 static +stm32f0xx_hal_dma.c:385:19:HAL_DMA_Abort 16 static +stm32f0xx_hal_dma.c:423:19:HAL_DMA_Abort_IT 24 static +stm32f0xx_hal_dma.c:469:19:HAL_DMA_PollForTransfer 32 static +stm32f0xx_hal_dma.c:570:6:HAL_DMA_IRQHandler 24 static +stm32f0xx_hal_dma.c:662:19:HAL_DMA_RegisterCallback 32 static +stm32f0xx_hal_dma.c:713:19:HAL_DMA_UnRegisterCallback 24 static +stm32f0xx_hal_dma.c:789:22:HAL_DMA_GetState 16 static +stm32f0xx_hal_dma.c:800:10:HAL_DMA_GetError 16 static +stm32f0xx_hal_dma.c:826:13:DMA_SetConfig 24 static +stm32f0xx_hal_dma.c:860:13:DMA_CalcBaseAndBitshift 16 static diff --git a/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.d b/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.d new file mode 100644 index 0000000..eb6bc5a --- /dev/null +++ b/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.d @@ -0,0 +1,83 @@ +Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o: \ + ../Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.c \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal.h \ + ../Core/Inc/stm32f0xx_hal_conf.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_def.h \ + ../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f0xx.h \ + ../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f072xb.h \ + ../Drivers/CMSIS/Include/core_cm0.h \ + ../Drivers/CMSIS/Include/cmsis_version.h \ + ../Drivers/CMSIS/Include/cmsis_compiler.h \ + ../Drivers/CMSIS/Include/cmsis_gcc.h \ + ../Drivers/CMSIS/Device/ST/STM32F0xx/Include/system_stm32f0xx.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_exti.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_cortex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_usb.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr_ex.h + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal.h: + +../Core/Inc/stm32f0xx_hal_conf.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_def.h: + +../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f0xx.h: + +../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f072xb.h: + +../Drivers/CMSIS/Include/core_cm0.h: + +../Drivers/CMSIS/Include/cmsis_version.h: + +../Drivers/CMSIS/Include/cmsis_compiler.h: + +../Drivers/CMSIS/Include/cmsis_gcc.h: + +../Drivers/CMSIS/Device/ST/STM32F0xx/Include/system_stm32f0xx.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_exti.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_cortex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_usb.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr_ex.h: diff --git a/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o b/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o new file mode 100644 index 0000000..2977daa Binary files /dev/null and b/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o differ diff --git a/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.su b/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.su new file mode 100644 index 0000000..3fe728b --- /dev/null +++ b/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.su @@ -0,0 +1,9 @@ +stm32f0xx_hal_exti.c:143:19:HAL_EXTI_SetConfigLine 32 static +stm32f0xx_hal_exti.c:238:19:HAL_EXTI_GetConfigLine 32 static +stm32f0xx_hal_exti.c:327:19:HAL_EXTI_ClearConfigLine 32 static +stm32f0xx_hal_exti.c:380:19:HAL_EXTI_RegisterCallback 32 static +stm32f0xx_hal_exti.c:405:19:HAL_EXTI_GetHandle 16 static +stm32f0xx_hal_exti.c:445:6:HAL_EXTI_IRQHandler 24 static +stm32f0xx_hal_exti.c:477:10:HAL_EXTI_GetPending 32 static +stm32f0xx_hal_exti.c:506:6:HAL_EXTI_ClearPending 24 static +stm32f0xx_hal_exti.c:527:6:HAL_EXTI_GenerateSWI 24 static diff --git a/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.d b/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.d new file mode 100644 index 0000000..0b9372a --- /dev/null +++ b/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.d @@ -0,0 +1,83 @@ +Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o: \ + ../Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.c \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal.h \ + ../Core/Inc/stm32f0xx_hal_conf.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_def.h \ + ../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f0xx.h \ + ../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f072xb.h \ + ../Drivers/CMSIS/Include/core_cm0.h \ + ../Drivers/CMSIS/Include/cmsis_version.h \ + ../Drivers/CMSIS/Include/cmsis_compiler.h \ + ../Drivers/CMSIS/Include/cmsis_gcc.h \ + ../Drivers/CMSIS/Device/ST/STM32F0xx/Include/system_stm32f0xx.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_exti.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_cortex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_usb.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr_ex.h + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal.h: + +../Core/Inc/stm32f0xx_hal_conf.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_def.h: + +../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f0xx.h: + +../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f072xb.h: + +../Drivers/CMSIS/Include/core_cm0.h: + +../Drivers/CMSIS/Include/cmsis_version.h: + +../Drivers/CMSIS/Include/cmsis_compiler.h: + +../Drivers/CMSIS/Include/cmsis_gcc.h: + +../Drivers/CMSIS/Device/ST/STM32F0xx/Include/system_stm32f0xx.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_exti.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_cortex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_usb.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr_ex.h: diff --git a/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o b/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o new file mode 100644 index 0000000..5b945d1 Binary files /dev/null and b/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o differ diff --git a/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.su b/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.su new file mode 100644 index 0000000..35b6a95 --- /dev/null +++ b/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.su @@ -0,0 +1,14 @@ +stm32f0xx_hal_flash.c:167:19:HAL_FLASH_Program 48 static +stm32f0xx_hal_flash.c:239:19:HAL_FLASH_Program_IT 40 static +stm32f0xx_hal_flash.c:285:6:HAL_FLASH_IRQHandler 24 static +stm32f0xx_hal_flash.c:428:13:HAL_FLASH_EndOfOperationCallback 16 static +stm32f0xx_hal_flash.c:446:13:HAL_FLASH_OperationErrorCallback 16 static +stm32f0xx_hal_flash.c:479:19:HAL_FLASH_Unlock 16 static +stm32f0xx_hal_flash.c:503:19:HAL_FLASH_Lock 8 static +stm32f0xx_hal_flash.c:515:19:HAL_FLASH_OB_Unlock 8 static +stm32f0xx_hal_flash.c:535:19:HAL_FLASH_OB_Lock 8 static +stm32f0xx_hal_flash.c:548:19:HAL_FLASH_OB_Launch 8 static +stm32f0xx_hal_flash.c:580:10:HAL_FLASH_GetError 8 static +stm32f0xx_hal_flash.c:603:13:FLASH_Program_HalfWord 16 static +stm32f0xx_hal_flash.c:620:19:FLASH_WaitForLastOperation 24 static +stm32f0xx_hal_flash.c:663:13:FLASH_SetErrorCode 16 static diff --git a/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.d b/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.d new file mode 100644 index 0000000..0e20dea --- /dev/null +++ b/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.d @@ -0,0 +1,83 @@ +Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o: \ + ../Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.c \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal.h \ + ../Core/Inc/stm32f0xx_hal_conf.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_def.h \ + ../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f0xx.h \ + ../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f072xb.h \ + ../Drivers/CMSIS/Include/core_cm0.h \ + ../Drivers/CMSIS/Include/cmsis_version.h \ + ../Drivers/CMSIS/Include/cmsis_compiler.h \ + ../Drivers/CMSIS/Include/cmsis_gcc.h \ + ../Drivers/CMSIS/Device/ST/STM32F0xx/Include/system_stm32f0xx.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_exti.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_cortex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_usb.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr_ex.h + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal.h: + +../Core/Inc/stm32f0xx_hal_conf.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_def.h: + +../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f0xx.h: + +../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f072xb.h: + +../Drivers/CMSIS/Include/core_cm0.h: + +../Drivers/CMSIS/Include/cmsis_version.h: + +../Drivers/CMSIS/Include/cmsis_compiler.h: + +../Drivers/CMSIS/Include/cmsis_gcc.h: + +../Drivers/CMSIS/Device/ST/STM32F0xx/Include/system_stm32f0xx.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_exti.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_cortex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_usb.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr_ex.h: diff --git a/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o b/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o new file mode 100644 index 0000000..cf70cd1 Binary files /dev/null and b/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o differ diff --git a/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.su b/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.su new file mode 100644 index 0000000..d797c73 --- /dev/null +++ b/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.su @@ -0,0 +1,16 @@ +stm32f0xx_hal_flash_ex.c:159:19:HAL_FLASHEx_Erase 32 static +stm32f0xx_hal_flash_ex.c:240:19:HAL_FLASHEx_Erase_IT 24 static +stm32f0xx_hal_flash_ex.c:313:19:HAL_FLASHEx_OBErase 24 static +stm32f0xx_hal_flash_ex.c:362:19:HAL_FLASHEx_OBProgram 32 static +stm32f0xx_hal_flash_ex.c:443:6:HAL_FLASHEx_OBGetConfig 16 static +stm32f0xx_hal_flash_ex.c:465:10:HAL_FLASHEx_OBGetUserData 24 static +stm32f0xx_hal_flash_ex.c:500:13:FLASH_MassErase 8 static +stm32f0xx_hal_flash_ex.c:521:26:FLASH_OB_EnableWRP 48 static +stm32f0xx_hal_flash_ex.c:637:26:FLASH_OB_DisableWRP 48 static +stm32f0xx_hal_flash_ex.c:751:26:FLASH_OB_RDP_LevelConfig 32 static +stm32f0xx_hal_flash_ex.c:802:26:FLASH_OB_UserConfig 32 static +stm32f0xx_hal_flash_ex.c:857:26:FLASH_OB_ProgramData 32 static +stm32f0xx_hal_flash_ex.c:890:17:FLASH_OB_GetWRP 8 static +stm32f0xx_hal_flash_ex.c:904:17:FLASH_OB_GetRDP 16 static +stm32f0xx_hal_flash_ex.c:931:16:FLASH_OB_GetUser 8 static +stm32f0xx_hal_flash_ex.c:960:6:FLASH_PageErase 16 static diff --git a/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.d b/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.d new file mode 100644 index 0000000..60f938b --- /dev/null +++ b/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.d @@ -0,0 +1,83 @@ +Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o: \ + ../Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.c \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal.h \ + ../Core/Inc/stm32f0xx_hal_conf.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_def.h \ + ../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f0xx.h \ + ../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f072xb.h \ + ../Drivers/CMSIS/Include/core_cm0.h \ + ../Drivers/CMSIS/Include/cmsis_version.h \ + ../Drivers/CMSIS/Include/cmsis_compiler.h \ + ../Drivers/CMSIS/Include/cmsis_gcc.h \ + ../Drivers/CMSIS/Device/ST/STM32F0xx/Include/system_stm32f0xx.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_exti.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_cortex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_usb.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr_ex.h + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal.h: + +../Core/Inc/stm32f0xx_hal_conf.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_def.h: + +../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f0xx.h: + +../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f072xb.h: + +../Drivers/CMSIS/Include/core_cm0.h: + +../Drivers/CMSIS/Include/cmsis_version.h: + +../Drivers/CMSIS/Include/cmsis_compiler.h: + +../Drivers/CMSIS/Include/cmsis_gcc.h: + +../Drivers/CMSIS/Device/ST/STM32F0xx/Include/system_stm32f0xx.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_exti.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_cortex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_usb.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr_ex.h: diff --git a/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o b/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o new file mode 100644 index 0000000..c1b4953 Binary files /dev/null and b/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o differ diff --git a/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.su b/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.su new file mode 100644 index 0000000..7945418 --- /dev/null +++ b/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.su @@ -0,0 +1,8 @@ +stm32f0xx_hal_gpio.c:177:6:HAL_GPIO_Init 32 static +stm32f0xx_hal_gpio.c:302:6:HAL_GPIO_DeInit 32 static +stm32f0xx_hal_gpio.c:384:15:HAL_GPIO_ReadPin 24 static +stm32f0xx_hal_gpio.c:417:6:HAL_GPIO_WritePin 16 static +stm32f0xx_hal_gpio.c:439:6:HAL_GPIO_TogglePin 16 static +stm32f0xx_hal_gpio.c:465:19:HAL_GPIO_LockPin 24 static +stm32f0xx_hal_gpio.c:500:6:HAL_GPIO_EXTI_IRQHandler 16 static +stm32f0xx_hal_gpio.c:515:13:HAL_GPIO_EXTI_Callback 16 static diff --git a/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.d b/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.d new file mode 100644 index 0000000..0ceb525 --- /dev/null +++ b/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.d @@ -0,0 +1,83 @@ +Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o: \ + ../Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.c \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal.h \ + ../Core/Inc/stm32f0xx_hal_conf.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_def.h \ + ../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f0xx.h \ + ../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f072xb.h \ + ../Drivers/CMSIS/Include/core_cm0.h \ + ../Drivers/CMSIS/Include/cmsis_version.h \ + ../Drivers/CMSIS/Include/cmsis_compiler.h \ + ../Drivers/CMSIS/Include/cmsis_gcc.h \ + ../Drivers/CMSIS/Device/ST/STM32F0xx/Include/system_stm32f0xx.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_exti.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_cortex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_usb.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr_ex.h + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal.h: + +../Core/Inc/stm32f0xx_hal_conf.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_def.h: + +../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f0xx.h: + +../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f072xb.h: + +../Drivers/CMSIS/Include/core_cm0.h: + +../Drivers/CMSIS/Include/cmsis_version.h: + +../Drivers/CMSIS/Include/cmsis_compiler.h: + +../Drivers/CMSIS/Include/cmsis_gcc.h: + +../Drivers/CMSIS/Device/ST/STM32F0xx/Include/system_stm32f0xx.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_exti.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_cortex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_usb.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr_ex.h: diff --git a/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o b/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o new file mode 100644 index 0000000..d30d338 Binary files /dev/null and b/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o differ diff --git a/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.su b/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.su new file mode 100644 index 0000000..e61d2df --- /dev/null +++ b/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.su @@ -0,0 +1,78 @@ +stm32f0xx_hal_i2c.c:469:19:HAL_I2C_Init 16 static +stm32f0xx_hal_i2c.c:578:19:HAL_I2C_DeInit 16 static +stm32f0xx_hal_i2c.c:624:13:HAL_I2C_MspInit 16 static +stm32f0xx_hal_i2c.c:640:13:HAL_I2C_MspDeInit 16 static +stm32f0xx_hal_i2c.c:1060:19:HAL_I2C_Master_Transmit 48 static +stm32f0xx_hal_i2c.c:1174:19:HAL_I2C_Master_Receive 48 static +stm32f0xx_hal_i2c.c:1287:19:HAL_I2C_Slave_Transmit 40 static +stm32f0xx_hal_i2c.c:1424:19:HAL_I2C_Slave_Receive 40 static +stm32f0xx_hal_i2c.c:1550:19:HAL_I2C_Master_Transmit_IT 48 static +stm32f0xx_hal_i2c.c:1619:19:HAL_I2C_Master_Receive_IT 48 static +stm32f0xx_hal_i2c.c:1686:19:HAL_I2C_Slave_Transmit_IT 24 static +stm32f0xx_hal_i2c.c:1735:19:HAL_I2C_Slave_Receive_IT 24 static +stm32f0xx_hal_i2c.c:1786:19:HAL_I2C_Master_Transmit_DMA 48 static +stm32f0xx_hal_i2c.c:1929:19:HAL_I2C_Master_Receive_DMA 48 static +stm32f0xx_hal_i2c.c:2070:19:HAL_I2C_Slave_Transmit_DMA 40 static +stm32f0xx_hal_i2c.c:2173:19:HAL_I2C_Slave_Receive_DMA 40 static +stm32f0xx_hal_i2c.c:2280:19:HAL_I2C_Mem_Write 48 static +stm32f0xx_hal_i2c.c:2415:19:HAL_I2C_Mem_Read 48 static +stm32f0xx_hal_i2c.c:2548:19:HAL_I2C_Mem_Write_IT 48 static +stm32f0xx_hal_i2c.c:2639:19:HAL_I2C_Mem_Read_IT 48 static +stm32f0xx_hal_i2c.c:2729:19:HAL_I2C_Mem_Write_DMA 56 static +stm32f0xx_hal_i2c.c:2873:19:HAL_I2C_Mem_Read_DMA 56 static +stm32f0xx_hal_i2c.c:3014:19:HAL_I2C_IsDeviceReady 48 static +stm32f0xx_hal_i2c.c:3156:19:HAL_I2C_Master_Seq_Transmit_IT 48 static +stm32f0xx_hal_i2c.c:3240:19:HAL_I2C_Master_Seq_Transmit_DMA 56 static +stm32f0xx_hal_i2c.c:3402:19:HAL_I2C_Master_Seq_Receive_IT 48 static +stm32f0xx_hal_i2c.c:3486:19:HAL_I2C_Master_Seq_Receive_DMA 56 static +stm32f0xx_hal_i2c.c:3646:19:HAL_I2C_Slave_Seq_Transmit_IT 24 static +stm32f0xx_hal_i2c.c:3741:19:HAL_I2C_Slave_Seq_Transmit_DMA 40 static +stm32f0xx_hal_i2c.c:3920:19:HAL_I2C_Slave_Seq_Receive_IT 24 static +stm32f0xx_hal_i2c.c:4015:19:HAL_I2C_Slave_Seq_Receive_DMA 40 static +stm32f0xx_hal_i2c.c:4190:19:HAL_I2C_EnableListen_IT 16 static +stm32f0xx_hal_i2c.c:4214:19:HAL_I2C_DisableListen_IT 24 static +stm32f0xx_hal_i2c.c:4247:19:HAL_I2C_Master_Abort_IT 24 static +stm32f0xx_hal_i2c.c:4297:6:HAL_I2C_EV_IRQHandler 24 static +stm32f0xx_hal_i2c.c:4316:6:HAL_I2C_ER_IRQHandler 32 static +stm32f0xx_hal_i2c.c:4365:13:HAL_I2C_MasterTxCpltCallback 16 static +stm32f0xx_hal_i2c.c:4381:13:HAL_I2C_MasterRxCpltCallback 16 static +stm32f0xx_hal_i2c.c:4396:13:HAL_I2C_SlaveTxCpltCallback 16 static +stm32f0xx_hal_i2c.c:4412:13:HAL_I2C_SlaveRxCpltCallback 16 static +stm32f0xx_hal_i2c.c:4430:13:HAL_I2C_AddrCallback 16 static +stm32f0xx_hal_i2c.c:4448:13:HAL_I2C_ListenCpltCallback 16 static +stm32f0xx_hal_i2c.c:4464:13:HAL_I2C_MemTxCpltCallback 16 static +stm32f0xx_hal_i2c.c:4480:13:HAL_I2C_MemRxCpltCallback 16 static +stm32f0xx_hal_i2c.c:4496:13:HAL_I2C_ErrorCallback 16 static +stm32f0xx_hal_i2c.c:4512:13:HAL_I2C_AbortCpltCallback 16 static +stm32f0xx_hal_i2c.c:4547:22:HAL_I2C_GetState 16 static +stm32f0xx_hal_i2c.c:4559:21:HAL_I2C_GetMode 16 static +stm32f0xx_hal_i2c.c:4570:10:HAL_I2C_GetError 16 static +stm32f0xx_hal_i2c.c:4595:26:I2C_Master_ISR_IT 48 static +stm32f0xx_hal_i2c.c:4732:26:I2C_Slave_ISR_IT 32 static +stm32f0xx_hal_i2c.c:4865:26:I2C_Master_ISR_DMA 48 static +stm32f0xx_hal_i2c.c:5000:26:I2C_Slave_ISR_DMA 32 static +stm32f0xx_hal_i2c.c:5122:26:I2C_RequestMemoryWrite 40 static +stm32f0xx_hal_i2c.c:5175:26:I2C_RequestMemoryRead 40 static +stm32f0xx_hal_i2c.c:5222:13:I2C_ITAddrCplt 32 static +stm32f0xx_hal_i2c.c:5317:13:I2C_ITMasterSeqCplt 16 static +stm32f0xx_hal_i2c.c:5370:13:I2C_ITSlaveSeqCplt 16 static +stm32f0xx_hal_i2c.c:5426:13:I2C_ITMasterCplt 24 static +stm32f0xx_hal_i2c.c:5545:13:I2C_ITSlaveCplt 24 static +stm32f0xx_hal_i2c.c:5682:13:I2C_ITListenCplt 16 static +stm32f0xx_hal_i2c.c:5733:13:I2C_ITError 24 static +stm32f0xx_hal_i2c.c:5851:13:I2C_Flush_TXDR 16 static +stm32f0xx_hal_i2c.c:5872:13:I2C_DMAMasterTransmitCplt 24 static +stm32f0xx_hal_i2c.c:5920:13:I2C_DMASlaveTransmitCplt 24 static +stm32f0xx_hal_i2c.c:5947:13:I2C_DMAMasterReceiveCplt 24 static +stm32f0xx_hal_i2c.c:5995:13:I2C_DMASlaveReceiveCplt 24 static +stm32f0xx_hal_i2c.c:6022:13:I2C_DMAError 24 static +stm32f0xx_hal_i2c.c:6039:13:I2C_DMAAbort 24 static +stm32f0xx_hal_i2c.c:6080:26:I2C_WaitOnFlagUntilTimeout 24 static +stm32f0xx_hal_i2c.c:6110:26:I2C_WaitOnTXISFlagUntilTimeout 24 static +stm32f0xx_hal_i2c.c:6147:26:I2C_WaitOnSTOPFlagUntilTimeout 24 static +stm32f0xx_hal_i2c.c:6181:26:I2C_WaitOnRXNEFlagUntilTimeout 24 static +stm32f0xx_hal_i2c.c:6244:26:I2C_IsAcknowledgeFailed 24 static +stm32f0xx_hal_i2c.c:6312:13:I2C_TransferConfig 32 static +stm32f0xx_hal_i2c.c:6331:13:I2C_Enable_IRQ 24 static +stm32f0xx_hal_i2c.c:6402:13:I2C_Disable_IRQ 24 static +stm32f0xx_hal_i2c.c:6465:13:I2C_ConvertOtherXferOptions 16 static diff --git a/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.d b/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.d new file mode 100644 index 0000000..bc708d0 --- /dev/null +++ b/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.d @@ -0,0 +1,83 @@ +Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o: \ + ../Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.c \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal.h \ + ../Core/Inc/stm32f0xx_hal_conf.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_def.h \ + ../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f0xx.h \ + ../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f072xb.h \ + ../Drivers/CMSIS/Include/core_cm0.h \ + ../Drivers/CMSIS/Include/cmsis_version.h \ + ../Drivers/CMSIS/Include/cmsis_compiler.h \ + ../Drivers/CMSIS/Include/cmsis_gcc.h \ + ../Drivers/CMSIS/Device/ST/STM32F0xx/Include/system_stm32f0xx.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_exti.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_cortex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_usb.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr_ex.h + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal.h: + +../Core/Inc/stm32f0xx_hal_conf.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_def.h: + +../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f0xx.h: + +../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f072xb.h: + +../Drivers/CMSIS/Include/core_cm0.h: + +../Drivers/CMSIS/Include/cmsis_version.h: + +../Drivers/CMSIS/Include/cmsis_compiler.h: + +../Drivers/CMSIS/Include/cmsis_gcc.h: + +../Drivers/CMSIS/Device/ST/STM32F0xx/Include/system_stm32f0xx.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_exti.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_cortex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_usb.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr_ex.h: diff --git a/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o b/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o new file mode 100644 index 0000000..89cc1fa Binary files /dev/null and b/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o differ diff --git a/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.su b/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.su new file mode 100644 index 0000000..80be4ab --- /dev/null +++ b/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.su @@ -0,0 +1,6 @@ +stm32f0xx_hal_i2c_ex.c:97:19:HAL_I2CEx_ConfigAnalogFilter 16 static +stm32f0xx_hal_i2c_ex.c:141:19:HAL_I2CEx_ConfigDigitalFilter 24 static +stm32f0xx_hal_i2c_ex.c:193:19:HAL_I2CEx_EnableWakeUp 16 static +stm32f0xx_hal_i2c_ex.c:232:19:HAL_I2CEx_DisableWakeUp 16 static +stm32f0xx_hal_i2c_ex.c:279:6:HAL_I2CEx_EnableFastModePlus 24 static +stm32f0xx_hal_i2c_ex.c:304:6:HAL_I2CEx_DisableFastModePlus 24 static diff --git a/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.d b/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.d new file mode 100644 index 0000000..743311c --- /dev/null +++ b/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.d @@ -0,0 +1,83 @@ +Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o: \ + ../Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.c \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal.h \ + ../Core/Inc/stm32f0xx_hal_conf.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_def.h \ + ../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f0xx.h \ + ../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f072xb.h \ + ../Drivers/CMSIS/Include/core_cm0.h \ + ../Drivers/CMSIS/Include/cmsis_version.h \ + ../Drivers/CMSIS/Include/cmsis_compiler.h \ + ../Drivers/CMSIS/Include/cmsis_gcc.h \ + ../Drivers/CMSIS/Device/ST/STM32F0xx/Include/system_stm32f0xx.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_exti.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_cortex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_usb.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr_ex.h + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal.h: + +../Core/Inc/stm32f0xx_hal_conf.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_def.h: + +../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f0xx.h: + +../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f072xb.h: + +../Drivers/CMSIS/Include/core_cm0.h: + +../Drivers/CMSIS/Include/cmsis_version.h: + +../Drivers/CMSIS/Include/cmsis_compiler.h: + +../Drivers/CMSIS/Include/cmsis_gcc.h: + +../Drivers/CMSIS/Device/ST/STM32F0xx/Include/system_stm32f0xx.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_exti.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_cortex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_usb.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr_ex.h: diff --git a/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o b/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o new file mode 100644 index 0000000..8962f30 Binary files /dev/null and b/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o differ diff --git a/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.su b/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.su new file mode 100644 index 0000000..5480520 --- /dev/null +++ b/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.su @@ -0,0 +1,33 @@ +stm32f0xx_hal_pcd.c:120:19:HAL_PCD_Init 64 static +stm32f0xx_hal_pcd.c:216:19:HAL_PCD_DeInit 16 static +stm32f0xx_hal_pcd.c:252:13:HAL_PCD_MspInit 16 static +stm32f0xx_hal_pcd.c:267:13:HAL_PCD_MspDeInit 16 static +stm32f0xx_hal_pcd.c:962:19:HAL_PCD_Start 16 static +stm32f0xx_hal_pcd.c:976:19:HAL_PCD_Stop 16 static +stm32f0xx_hal_pcd.c:994:6:HAL_PCD_IRQHandler 16 static +stm32f0xx_hal_pcd.c:1123:13:HAL_PCD_DataOutStageCallback 16 static +stm32f0xx_hal_pcd.c:1140:13:HAL_PCD_DataInStageCallback 16 static +stm32f0xx_hal_pcd.c:1155:13:HAL_PCD_SetupStageCallback 16 static +stm32f0xx_hal_pcd.c:1170:13:HAL_PCD_SOFCallback 16 static +stm32f0xx_hal_pcd.c:1185:13:HAL_PCD_ResetCallback 16 static +stm32f0xx_hal_pcd.c:1200:13:HAL_PCD_SuspendCallback 16 static +stm32f0xx_hal_pcd.c:1215:13:HAL_PCD_ResumeCallback 16 static +stm32f0xx_hal_pcd.c:1231:13:HAL_PCD_ISOOUTIncompleteCallback 16 static +stm32f0xx_hal_pcd.c:1248:13:HAL_PCD_ISOINIncompleteCallback 16 static +stm32f0xx_hal_pcd.c:1264:13:HAL_PCD_ConnectCallback 16 static +stm32f0xx_hal_pcd.c:1279:13:HAL_PCD_DisconnectCallback 16 static +stm32f0xx_hal_pcd.c:1313:19:HAL_PCD_DevConnect 16 static +stm32f0xx_hal_pcd.c:1326:19:HAL_PCD_DevDisconnect 16 static +stm32f0xx_hal_pcd.c:1340:19:HAL_PCD_SetAddress 16 static +stm32f0xx_hal_pcd.c:1356:19:HAL_PCD_EP_Open 32 static +stm32f0xx_hal_pcd.c:1400:19:HAL_PCD_EP_Close 24 static +stm32f0xx_hal_pcd.c:1431:19:HAL_PCD_EP_Receive 32 static +stm32f0xx_hal_pcd.c:1462:10:HAL_PCD_EP_GetRxCount 16 static +stm32f0xx_hal_pcd.c:1474:19:HAL_PCD_EP_Transmit 32 static +stm32f0xx_hal_pcd.c:1505:19:HAL_PCD_EP_SetStall 24 static +stm32f0xx_hal_pcd.c:1546:19:HAL_PCD_EP_ClrStall 24 static +stm32f0xx_hal_pcd.c:1582:19:HAL_PCD_EP_Flush 16 static +stm32f0xx_hal_pcd.c:1596:19:HAL_PCD_ActivateRemoteWakeup 16 static +stm32f0xx_hal_pcd.c:1606:19:HAL_PCD_DeActivateRemoteWakeup 16 static +stm32f0xx_hal_pcd.c:1635:18:HAL_PCD_GetState 16 static +stm32f0xx_hal_pcd.c:1659:26:PCD_EP_ISR_Handler 48 static diff --git a/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.d b/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.d new file mode 100644 index 0000000..66d5ddf --- /dev/null +++ b/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.d @@ -0,0 +1,83 @@ +Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o: \ + ../Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.c \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal.h \ + ../Core/Inc/stm32f0xx_hal_conf.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_def.h \ + ../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f0xx.h \ + ../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f072xb.h \ + ../Drivers/CMSIS/Include/core_cm0.h \ + ../Drivers/CMSIS/Include/cmsis_version.h \ + ../Drivers/CMSIS/Include/cmsis_compiler.h \ + ../Drivers/CMSIS/Include/cmsis_gcc.h \ + ../Drivers/CMSIS/Device/ST/STM32F0xx/Include/system_stm32f0xx.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_exti.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_cortex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_usb.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr_ex.h + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal.h: + +../Core/Inc/stm32f0xx_hal_conf.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_def.h: + +../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f0xx.h: + +../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f072xb.h: + +../Drivers/CMSIS/Include/core_cm0.h: + +../Drivers/CMSIS/Include/cmsis_version.h: + +../Drivers/CMSIS/Include/cmsis_compiler.h: + +../Drivers/CMSIS/Include/cmsis_gcc.h: + +../Drivers/CMSIS/Device/ST/STM32F0xx/Include/system_stm32f0xx.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_exti.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_cortex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_usb.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr_ex.h: diff --git a/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o b/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o new file mode 100644 index 0000000..a9d8a53 Binary files /dev/null and b/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o differ diff --git a/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.su b/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.su new file mode 100644 index 0000000..5add297 --- /dev/null +++ b/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.su @@ -0,0 +1,8 @@ +stm32f0xx_hal_pcd_ex.c:81:20:HAL_PCDEx_PMAConfig 40 static +stm32f0xx_hal_pcd_ex.c:123:19:HAL_PCDEx_ActivateBCD 24 static +stm32f0xx_hal_pcd_ex.c:144:19:HAL_PCDEx_DeActivateBCD 24 static +stm32f0xx_hal_pcd_ex.c:160:6:HAL_PCDEx_BCD_VBUSDetect 24 static +stm32f0xx_hal_pcd_ex.c:254:19:HAL_PCDEx_ActivateLPM 24 static +stm32f0xx_hal_pcd_ex.c:272:19:HAL_PCDEx_DeActivateLPM 24 static +stm32f0xx_hal_pcd_ex.c:292:13:HAL_PCDEx_LPM_Callback 16 static +stm32f0xx_hal_pcd_ex.c:309:13:HAL_PCDEx_BCD_Callback 16 static diff --git a/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.d b/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.d new file mode 100644 index 0000000..7c92e3f --- /dev/null +++ b/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.d @@ -0,0 +1,83 @@ +Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o: \ + ../Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.c \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal.h \ + ../Core/Inc/stm32f0xx_hal_conf.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_def.h \ + ../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f0xx.h \ + ../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f072xb.h \ + ../Drivers/CMSIS/Include/core_cm0.h \ + ../Drivers/CMSIS/Include/cmsis_version.h \ + ../Drivers/CMSIS/Include/cmsis_compiler.h \ + ../Drivers/CMSIS/Include/cmsis_gcc.h \ + ../Drivers/CMSIS/Device/ST/STM32F0xx/Include/system_stm32f0xx.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_exti.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_cortex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_usb.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr_ex.h + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal.h: + +../Core/Inc/stm32f0xx_hal_conf.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_def.h: + +../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f0xx.h: + +../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f072xb.h: + +../Drivers/CMSIS/Include/core_cm0.h: + +../Drivers/CMSIS/Include/cmsis_version.h: + +../Drivers/CMSIS/Include/cmsis_compiler.h: + +../Drivers/CMSIS/Include/cmsis_gcc.h: + +../Drivers/CMSIS/Device/ST/STM32F0xx/Include/system_stm32f0xx.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_exti.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_cortex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_usb.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr_ex.h: diff --git a/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o b/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o new file mode 100644 index 0000000..61e291b Binary files /dev/null and b/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o differ diff --git a/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.su b/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.su new file mode 100644 index 0000000..1b6b219 --- /dev/null +++ b/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.su @@ -0,0 +1,12 @@ +stm32f0xx_hal_pwr.c:75:6:HAL_PWR_DeInit 8 static +stm32f0xx_hal_pwr.c:88:6:HAL_PWR_EnableBkUpAccess 8 static +stm32f0xx_hal_pwr.c:100:6:HAL_PWR_DisableBkUpAccess 8 static +stm32f0xx_hal_pwr.c:231:6:HAL_PWR_EnableWakeUpPin 16 static +stm32f0xx_hal_pwr.c:246:6:HAL_PWR_DisableWakeUpPin 16 static +stm32f0xx_hal_pwr.c:269:6:HAL_PWR_EnterSLEEPMode 16 static,ignoring_inline_asm +stm32f0xx_hal_pwr.c:312:6:HAL_PWR_EnterSTOPMode 24 static,ignoring_inline_asm +stm32f0xx_hal_pwr.c:367:6:HAL_PWR_EnterSTANDBYMode 8 static,ignoring_inline_asm +stm32f0xx_hal_pwr.c:391:6:HAL_PWR_EnableSleepOnExit 8 static +stm32f0xx_hal_pwr.c:404:6:HAL_PWR_DisableSleepOnExit 8 static +stm32f0xx_hal_pwr.c:418:6:HAL_PWR_EnableSEVOnPend 8 static +stm32f0xx_hal_pwr.c:431:6:HAL_PWR_DisableSEVOnPend 8 static diff --git a/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.d b/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.d new file mode 100644 index 0000000..b1f6703 --- /dev/null +++ b/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.d @@ -0,0 +1,83 @@ +Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o: \ + ../Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.c \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal.h \ + ../Core/Inc/stm32f0xx_hal_conf.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_def.h \ + ../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f0xx.h \ + ../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f072xb.h \ + ../Drivers/CMSIS/Include/core_cm0.h \ + ../Drivers/CMSIS/Include/cmsis_version.h \ + ../Drivers/CMSIS/Include/cmsis_compiler.h \ + ../Drivers/CMSIS/Include/cmsis_gcc.h \ + ../Drivers/CMSIS/Device/ST/STM32F0xx/Include/system_stm32f0xx.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_exti.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_cortex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_usb.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr_ex.h + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal.h: + +../Core/Inc/stm32f0xx_hal_conf.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_def.h: + +../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f0xx.h: + +../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f072xb.h: + +../Drivers/CMSIS/Include/core_cm0.h: + +../Drivers/CMSIS/Include/cmsis_version.h: + +../Drivers/CMSIS/Include/cmsis_compiler.h: + +../Drivers/CMSIS/Include/cmsis_gcc.h: + +../Drivers/CMSIS/Device/ST/STM32F0xx/Include/system_stm32f0xx.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_exti.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_cortex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_usb.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr_ex.h: diff --git a/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o b/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o new file mode 100644 index 0000000..c76283d Binary files /dev/null and b/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o differ diff --git a/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.su b/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.su new file mode 100644 index 0000000..2d8f01c --- /dev/null +++ b/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.su @@ -0,0 +1,9 @@ +stm32f0xx_hal_pwr_ex.c:108:6:HAL_PWR_ConfigPVD 16 static +stm32f0xx_hal_pwr_ex.c:150:6:HAL_PWR_EnablePVD 8 static +stm32f0xx_hal_pwr_ex.c:159:6:HAL_PWR_DisablePVD 8 static +stm32f0xx_hal_pwr_ex.c:169:6:HAL_PWR_PVD_IRQHandler 8 static +stm32f0xx_hal_pwr_ex.c:186:13:HAL_PWR_PVDCallback 8 static +stm32f0xx_hal_pwr_ex.c:207:6:HAL_PWREx_EnableVddio2Monitor 8 static +stm32f0xx_hal_pwr_ex.c:217:6:HAL_PWREx_DisableVddio2Monitor 8 static +stm32f0xx_hal_pwr_ex.c:229:6:HAL_PWREx_Vddio2Monitor_IRQHandler 8 static +stm32f0xx_hal_pwr_ex.c:246:13:HAL_PWREx_Vddio2MonitorCallback 8 static diff --git a/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.d b/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.d new file mode 100644 index 0000000..6bf832e --- /dev/null +++ b/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.d @@ -0,0 +1,83 @@ +Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o: \ + ../Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.c \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal.h \ + ../Core/Inc/stm32f0xx_hal_conf.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_def.h \ + ../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f0xx.h \ + ../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f072xb.h \ + ../Drivers/CMSIS/Include/core_cm0.h \ + ../Drivers/CMSIS/Include/cmsis_version.h \ + ../Drivers/CMSIS/Include/cmsis_compiler.h \ + ../Drivers/CMSIS/Include/cmsis_gcc.h \ + ../Drivers/CMSIS/Device/ST/STM32F0xx/Include/system_stm32f0xx.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_exti.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_cortex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_usb.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr_ex.h + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal.h: + +../Core/Inc/stm32f0xx_hal_conf.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_def.h: + +../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f0xx.h: + +../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f072xb.h: + +../Drivers/CMSIS/Include/core_cm0.h: + +../Drivers/CMSIS/Include/cmsis_version.h: + +../Drivers/CMSIS/Include/cmsis_compiler.h: + +../Drivers/CMSIS/Include/cmsis_gcc.h: + +../Drivers/CMSIS/Device/ST/STM32F0xx/Include/system_stm32f0xx.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_exti.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_cortex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_usb.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr_ex.h: diff --git a/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o b/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o new file mode 100644 index 0000000..c2efbeb Binary files /dev/null and b/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o differ diff --git a/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.su b/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.su new file mode 100644 index 0000000..aa24f85 --- /dev/null +++ b/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.su @@ -0,0 +1,13 @@ +stm32f0xx_hal_rcc.c:210:19:HAL_RCC_DeInit 16 static +stm32f0xx_hal_rcc.c:300:19:HAL_RCC_OscConfig 40 static +stm32f0xx_hal_rcc.c:779:19:HAL_RCC_ClockConfig 24 static +stm32f0xx_hal_rcc.c:1018:6:HAL_RCC_MCOConfig 48 static +stm32f0xx_hal_rcc.c:1052:6:HAL_RCC_EnableCSS 8 static +stm32f0xx_hal_rcc.c:1061:6:HAL_RCC_DisableCSS 8 static +stm32f0xx_hal_rcc.c:1097:10:HAL_RCC_GetSysClockFreq 72 static +stm32f0xx_hal_rcc.c:1172:10:HAL_RCC_GetHCLKFreq 8 static +stm32f0xx_hal_rcc.c:1183:10:HAL_RCC_GetPCLK1Freq 8 static +stm32f0xx_hal_rcc.c:1196:6:HAL_RCC_GetOscConfig 16 static +stm32f0xx_hal_rcc.c:1298:6:HAL_RCC_GetClockConfig 16 static +stm32f0xx_hal_rcc.c:1324:6:HAL_RCC_NMI_IRQHandler 8 static +stm32f0xx_hal_rcc.c:1341:13:HAL_RCC_CSSCallback 8 static diff --git a/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.d b/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.d new file mode 100644 index 0000000..53234e7 --- /dev/null +++ b/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.d @@ -0,0 +1,83 @@ +Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o: \ + ../Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.c \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal.h \ + ../Core/Inc/stm32f0xx_hal_conf.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_def.h \ + ../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f0xx.h \ + ../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f072xb.h \ + ../Drivers/CMSIS/Include/core_cm0.h \ + ../Drivers/CMSIS/Include/cmsis_version.h \ + ../Drivers/CMSIS/Include/cmsis_compiler.h \ + ../Drivers/CMSIS/Include/cmsis_gcc.h \ + ../Drivers/CMSIS/Device/ST/STM32F0xx/Include/system_stm32f0xx.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_exti.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_cortex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_usb.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr_ex.h + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal.h: + +../Core/Inc/stm32f0xx_hal_conf.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_def.h: + +../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f0xx.h: + +../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f072xb.h: + +../Drivers/CMSIS/Include/core_cm0.h: + +../Drivers/CMSIS/Include/cmsis_version.h: + +../Drivers/CMSIS/Include/cmsis_compiler.h: + +../Drivers/CMSIS/Include/cmsis_gcc.h: + +../Drivers/CMSIS/Device/ST/STM32F0xx/Include/system_stm32f0xx.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_exti.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_cortex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_usb.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr_ex.h: diff --git a/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o b/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o new file mode 100644 index 0000000..9d97a3c Binary files /dev/null and b/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o differ diff --git a/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.su b/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.su new file mode 100644 index 0000000..c25bf0f --- /dev/null +++ b/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.su @@ -0,0 +1,12 @@ +stm32f0xx_hal_rcc_ex.c:104:19:HAL_RCCEx_PeriphCLKConfig 32 static +stm32f0xx_hal_rcc_ex.c:270:6:HAL_RCCEx_GetPeriphCLKConfig 16 static +stm32f0xx_hal_rcc_ex.c:370:10:HAL_RCCEx_GetPeriphCLKFreq 40 static +stm32f0xx_hal_rcc_ex.c:659:6:HAL_RCCEx_CRSConfig 24 static +stm32f0xx_hal_rcc_ex.c:701:6:HAL_RCCEx_CRSSoftwareSynchronizationGenerate 8 static +stm32f0xx_hal_rcc_ex.c:711:6:HAL_RCCEx_CRSGetSynchronizationInfo 16 static +stm32f0xx_hal_rcc_ex.c:744:10:HAL_RCCEx_CRSWaitSynchronization 24 static +stm32f0xx_hal_rcc_ex.c:827:6:HAL_RCCEx_CRS_IRQHandler 24 static +stm32f0xx_hal_rcc_ex.c:892:13:HAL_RCCEx_CRS_SyncOkCallback 8 static +stm32f0xx_hal_rcc_ex.c:903:13:HAL_RCCEx_CRS_SyncWarnCallback 8 static +stm32f0xx_hal_rcc_ex.c:914:13:HAL_RCCEx_CRS_ExpectedSyncCallback 8 static +stm32f0xx_hal_rcc_ex.c:930:13:HAL_RCCEx_CRS_ErrorCallback 16 static diff --git a/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.d b/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.d new file mode 100644 index 0000000..396ee4e --- /dev/null +++ b/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.d @@ -0,0 +1,83 @@ +Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o: \ + ../Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.c \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal.h \ + ../Core/Inc/stm32f0xx_hal_conf.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_def.h \ + ../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f0xx.h \ + ../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f072xb.h \ + ../Drivers/CMSIS/Include/core_cm0.h \ + ../Drivers/CMSIS/Include/cmsis_version.h \ + ../Drivers/CMSIS/Include/cmsis_compiler.h \ + ../Drivers/CMSIS/Include/cmsis_gcc.h \ + ../Drivers/CMSIS/Device/ST/STM32F0xx/Include/system_stm32f0xx.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_exti.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_cortex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_usb.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr_ex.h + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal.h: + +../Core/Inc/stm32f0xx_hal_conf.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_def.h: + +../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f0xx.h: + +../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f072xb.h: + +../Drivers/CMSIS/Include/core_cm0.h: + +../Drivers/CMSIS/Include/cmsis_version.h: + +../Drivers/CMSIS/Include/cmsis_compiler.h: + +../Drivers/CMSIS/Include/cmsis_gcc.h: + +../Drivers/CMSIS/Device/ST/STM32F0xx/Include/system_stm32f0xx.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_exti.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_cortex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_usb.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr_ex.h: diff --git a/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o b/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o new file mode 100644 index 0000000..90350d3 Binary files /dev/null and b/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o differ diff --git a/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.su b/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.su new file mode 100644 index 0000000..e69de29 diff --git a/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.d b/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.d new file mode 100644 index 0000000..9bfb43f --- /dev/null +++ b/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.d @@ -0,0 +1,83 @@ +Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o: \ + ../Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.c \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal.h \ + ../Core/Inc/stm32f0xx_hal_conf.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_def.h \ + ../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f0xx.h \ + ../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f072xb.h \ + ../Drivers/CMSIS/Include/core_cm0.h \ + ../Drivers/CMSIS/Include/cmsis_version.h \ + ../Drivers/CMSIS/Include/cmsis_compiler.h \ + ../Drivers/CMSIS/Include/cmsis_gcc.h \ + ../Drivers/CMSIS/Device/ST/STM32F0xx/Include/system_stm32f0xx.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_exti.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_cortex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_usb.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr_ex.h + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal.h: + +../Core/Inc/stm32f0xx_hal_conf.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_def.h: + +../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f0xx.h: + +../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f072xb.h: + +../Drivers/CMSIS/Include/core_cm0.h: + +../Drivers/CMSIS/Include/cmsis_version.h: + +../Drivers/CMSIS/Include/cmsis_compiler.h: + +../Drivers/CMSIS/Include/cmsis_gcc.h: + +../Drivers/CMSIS/Device/ST/STM32F0xx/Include/system_stm32f0xx.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_exti.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_cortex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_usb.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr_ex.h: diff --git a/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o b/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o new file mode 100644 index 0000000..857c975 Binary files /dev/null and b/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o differ diff --git a/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.su b/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.su new file mode 100644 index 0000000..e69de29 diff --git a/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.d b/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.d new file mode 100644 index 0000000..2607a76 --- /dev/null +++ b/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.d @@ -0,0 +1,83 @@ +Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o: \ + ../Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.c \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal.h \ + ../Core/Inc/stm32f0xx_hal_conf.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_def.h \ + ../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f0xx.h \ + ../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f072xb.h \ + ../Drivers/CMSIS/Include/core_cm0.h \ + ../Drivers/CMSIS/Include/cmsis_version.h \ + ../Drivers/CMSIS/Include/cmsis_compiler.h \ + ../Drivers/CMSIS/Include/cmsis_gcc.h \ + ../Drivers/CMSIS/Device/ST/STM32F0xx/Include/system_stm32f0xx.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_exti.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_cortex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_usb.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr_ex.h + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal.h: + +../Core/Inc/stm32f0xx_hal_conf.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_def.h: + +../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f0xx.h: + +../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f072xb.h: + +../Drivers/CMSIS/Include/core_cm0.h: + +../Drivers/CMSIS/Include/cmsis_version.h: + +../Drivers/CMSIS/Include/cmsis_compiler.h: + +../Drivers/CMSIS/Include/cmsis_gcc.h: + +../Drivers/CMSIS/Device/ST/STM32F0xx/Include/system_stm32f0xx.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_exti.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_cortex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_usb.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr_ex.h: diff --git a/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o b/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o new file mode 100644 index 0000000..dfc3bc7 Binary files /dev/null and b/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o differ diff --git a/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.su b/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.su new file mode 100644 index 0000000..daa1beb --- /dev/null +++ b/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.su @@ -0,0 +1,30 @@ +stm32f0xx_ll_usb.c:64:19:USB_CoreInit 24 static +stm32f0xx_ll_usb.c:84:19:USB_EnableGlobalInt 24 static +stm32f0xx_ll_usb.c:106:19:USB_DisableGlobalInt 24 static +stm32f0xx_ll_usb.c:130:19:USB_SetCurrentMode 16 static +stm32f0xx_ll_usb.c:151:19:USB_DevInit 24 static +stm32f0xx_ll_usb.c:182:19:USB_SetDevSpeed 16 static +stm32f0xx_ll_usb.c:204:19:USB_FlushTxFifo 16 static +stm32f0xx_ll_usb.c:223:19:USB_FlushRxFifo 16 static +stm32f0xx_ll_usb.c:242:19:USB_ActivateEndpoint 40 static +stm32f0xx_ll_usb.c:358:19:USB_DeactivateEndpoint 24 static +stm32f0xx_ll_usb.c:411:19:USB_EPStartXfer 96 static +stm32f0xx_ll_usb.c:499:19:USB_WritePacket 24 static +stm32f0xx_ll_usb.c:521:7:USB_ReadPacket 24 static +stm32f0xx_ll_usb.c:540:19:USB_EPSetStall 24 static +stm32f0xx_ll_usb.c:560:19:USB_EPClearStall 24 static +stm32f0xx_ll_usb.c:591:19:USB_StopDevice 16 static +stm32f0xx_ll_usb.c:612:20:USB_SetDevAddress 16 static +stm32f0xx_ll_usb.c:628:20:USB_DevConnect 16 static +stm32f0xx_ll_usb.c:641:20:USB_DevDisconnect 16 static +stm32f0xx_ll_usb.c:654:11:USB_ReadInterrupts 24 static +stm32f0xx_ll_usb.c:667:10:USB_ReadDevAllOutEpInterrupt 16 static +stm32f0xx_ll_usb.c:683:10:USB_ReadDevAllInEpInterrupt 16 static +stm32f0xx_ll_usb.c:701:10:USB_ReadDevOutEPInterrupt 16 static +stm32f0xx_ll_usb.c:720:10:USB_ReadDevInEPInterrupt 16 static +stm32f0xx_ll_usb.c:738:7:USB_ClearInterrupts 16 static +stm32f0xx_ll_usb.c:755:19:USB_EP0_OutStart 16 static +stm32f0xx_ll_usb.c:772:19:USB_ActivateRemoteWakeup 16 static +stm32f0xx_ll_usb.c:784:19:USB_DeActivateRemoteWakeup 16 static +stm32f0xx_ll_usb.c:798:6:USB_WritePMA 56 static +stm32f0xx_ll_usb.c:832:6:USB_ReadPMA 48 static diff --git a/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/subdir.mk b/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/subdir.mk new file mode 100644 index 0000000..ca2b203 --- /dev/null +++ b/test/STM32F072C8T6/Debug/Drivers/STM32F0xx_HAL_Driver/Src/subdir.mk @@ -0,0 +1,104 @@ +################################################################################ +# Automatically-generated file. Do not edit! +################################################################################ + +# Add inputs and outputs from these tool invocations to the build variables +C_SRCS += \ +../Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.c \ +../Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.c \ +../Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.c \ +../Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.c \ +../Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.c \ +../Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.c \ +../Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.c \ +../Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.c \ +../Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.c \ +../Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.c \ +../Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.c \ +../Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.c \ +../Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.c \ +../Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.c \ +../Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.c \ +../Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.c \ +../Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.c \ +../Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.c + +OBJS += \ +./Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o \ +./Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o \ +./Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o \ +./Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o \ +./Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o \ +./Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o \ +./Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o \ +./Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o \ +./Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o \ +./Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o \ +./Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o \ +./Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o \ +./Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o \ +./Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o \ +./Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o \ +./Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o \ +./Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o \ +./Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + +C_DEPS += \ +./Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.d \ +./Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.d \ +./Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.d \ +./Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.d \ +./Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.d \ +./Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.d \ +./Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.d \ +./Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.d \ +./Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.d \ +./Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.d \ +./Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.d \ +./Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.d \ +./Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.d \ +./Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.d \ +./Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.d \ +./Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.d \ +./Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.d \ +./Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.d + + +# Each subdirectory must supply rules for building sources it contributes +Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o: ../Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.c + arm-none-eabi-gcc "$<" -mcpu=cortex-m0 -std=gnu11 -g3 -DUSE_HAL_DRIVER -DSTM32F072xB -DDEBUG -c -I"D:/project_in_git/CDC_ECM/src/dns-server" -I../USB_DEVICE/Target -I../Drivers/STM32F0xx_HAL_Driver/Inc/Legacy -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4" -I"D:/project_in_git/CDC_ECM/src" -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Drivers/STM32F0xx_HAL_Driver/Inc -I../Drivers/CMSIS/Include -I"D:/project_in_git/CDC_ECM/src/dhcp-server" -I../Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -I../USB_DEVICE/App -I../Drivers/CMSIS/Device/ST/STM32F0xx/Include -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include" -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/apps/httpserver_raw" -I"D:/project_in_git/CDC_ECM/src/src" -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.d" -MT"$@" --specs=nano.specs -mfloat-abi=soft -mthumb -o "$@" +Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o: ../Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.c + arm-none-eabi-gcc "$<" -mcpu=cortex-m0 -std=gnu11 -g3 -DUSE_HAL_DRIVER -DSTM32F072xB -DDEBUG -c -I"D:/project_in_git/CDC_ECM/src/dns-server" -I../USB_DEVICE/Target -I../Drivers/STM32F0xx_HAL_Driver/Inc/Legacy -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4" -I"D:/project_in_git/CDC_ECM/src" -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Drivers/STM32F0xx_HAL_Driver/Inc -I../Drivers/CMSIS/Include -I"D:/project_in_git/CDC_ECM/src/dhcp-server" -I../Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -I../USB_DEVICE/App -I../Drivers/CMSIS/Device/ST/STM32F0xx/Include -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include" -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/apps/httpserver_raw" -I"D:/project_in_git/CDC_ECM/src/src" -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.d" -MT"$@" --specs=nano.specs -mfloat-abi=soft -mthumb -o "$@" +Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o: ../Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.c + arm-none-eabi-gcc "$<" -mcpu=cortex-m0 -std=gnu11 -g3 -DUSE_HAL_DRIVER -DSTM32F072xB -DDEBUG -c -I"D:/project_in_git/CDC_ECM/src/dns-server" -I../USB_DEVICE/Target -I../Drivers/STM32F0xx_HAL_Driver/Inc/Legacy -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4" -I"D:/project_in_git/CDC_ECM/src" -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Drivers/STM32F0xx_HAL_Driver/Inc -I../Drivers/CMSIS/Include -I"D:/project_in_git/CDC_ECM/src/dhcp-server" -I../Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -I../USB_DEVICE/App -I../Drivers/CMSIS/Device/ST/STM32F0xx/Include -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include" -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/apps/httpserver_raw" -I"D:/project_in_git/CDC_ECM/src/src" -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.d" -MT"$@" --specs=nano.specs -mfloat-abi=soft -mthumb -o "$@" +Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o: ../Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.c + arm-none-eabi-gcc "$<" -mcpu=cortex-m0 -std=gnu11 -g3 -DUSE_HAL_DRIVER -DSTM32F072xB -DDEBUG -c -I"D:/project_in_git/CDC_ECM/src/dns-server" -I../USB_DEVICE/Target -I../Drivers/STM32F0xx_HAL_Driver/Inc/Legacy -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4" -I"D:/project_in_git/CDC_ECM/src" -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Drivers/STM32F0xx_HAL_Driver/Inc -I../Drivers/CMSIS/Include -I"D:/project_in_git/CDC_ECM/src/dhcp-server" -I../Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -I../USB_DEVICE/App -I../Drivers/CMSIS/Device/ST/STM32F0xx/Include -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include" -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/apps/httpserver_raw" -I"D:/project_in_git/CDC_ECM/src/src" -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.d" -MT"$@" --specs=nano.specs -mfloat-abi=soft -mthumb -o "$@" +Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o: ../Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.c + arm-none-eabi-gcc "$<" -mcpu=cortex-m0 -std=gnu11 -g3 -DUSE_HAL_DRIVER -DSTM32F072xB -DDEBUG -c -I"D:/project_in_git/CDC_ECM/src/dns-server" -I../USB_DEVICE/Target -I../Drivers/STM32F0xx_HAL_Driver/Inc/Legacy -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4" -I"D:/project_in_git/CDC_ECM/src" -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Drivers/STM32F0xx_HAL_Driver/Inc -I../Drivers/CMSIS/Include -I"D:/project_in_git/CDC_ECM/src/dhcp-server" -I../Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -I../USB_DEVICE/App -I../Drivers/CMSIS/Device/ST/STM32F0xx/Include -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include" -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/apps/httpserver_raw" -I"D:/project_in_git/CDC_ECM/src/src" -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.d" -MT"$@" --specs=nano.specs -mfloat-abi=soft -mthumb -o "$@" +Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o: ../Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.c + arm-none-eabi-gcc "$<" -mcpu=cortex-m0 -std=gnu11 -g3 -DUSE_HAL_DRIVER -DSTM32F072xB -DDEBUG -c -I"D:/project_in_git/CDC_ECM/src/dns-server" -I../USB_DEVICE/Target -I../Drivers/STM32F0xx_HAL_Driver/Inc/Legacy -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4" -I"D:/project_in_git/CDC_ECM/src" -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Drivers/STM32F0xx_HAL_Driver/Inc -I../Drivers/CMSIS/Include -I"D:/project_in_git/CDC_ECM/src/dhcp-server" -I../Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -I../USB_DEVICE/App -I../Drivers/CMSIS/Device/ST/STM32F0xx/Include -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include" -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/apps/httpserver_raw" -I"D:/project_in_git/CDC_ECM/src/src" -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.d" -MT"$@" --specs=nano.specs -mfloat-abi=soft -mthumb -o "$@" +Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o: ../Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.c + arm-none-eabi-gcc "$<" -mcpu=cortex-m0 -std=gnu11 -g3 -DUSE_HAL_DRIVER -DSTM32F072xB -DDEBUG -c -I"D:/project_in_git/CDC_ECM/src/dns-server" -I../USB_DEVICE/Target -I../Drivers/STM32F0xx_HAL_Driver/Inc/Legacy -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4" -I"D:/project_in_git/CDC_ECM/src" -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Drivers/STM32F0xx_HAL_Driver/Inc -I../Drivers/CMSIS/Include -I"D:/project_in_git/CDC_ECM/src/dhcp-server" -I../Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -I../USB_DEVICE/App -I../Drivers/CMSIS/Device/ST/STM32F0xx/Include -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include" -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/apps/httpserver_raw" -I"D:/project_in_git/CDC_ECM/src/src" -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.d" -MT"$@" --specs=nano.specs -mfloat-abi=soft -mthumb -o "$@" +Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o: ../Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.c + arm-none-eabi-gcc "$<" -mcpu=cortex-m0 -std=gnu11 -g3 -DUSE_HAL_DRIVER -DSTM32F072xB -DDEBUG -c -I"D:/project_in_git/CDC_ECM/src/dns-server" -I../USB_DEVICE/Target -I../Drivers/STM32F0xx_HAL_Driver/Inc/Legacy -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4" -I"D:/project_in_git/CDC_ECM/src" -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Drivers/STM32F0xx_HAL_Driver/Inc -I../Drivers/CMSIS/Include -I"D:/project_in_git/CDC_ECM/src/dhcp-server" -I../Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -I../USB_DEVICE/App -I../Drivers/CMSIS/Device/ST/STM32F0xx/Include -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include" -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/apps/httpserver_raw" -I"D:/project_in_git/CDC_ECM/src/src" -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.d" -MT"$@" --specs=nano.specs -mfloat-abi=soft -mthumb -o "$@" +Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o: ../Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.c + arm-none-eabi-gcc "$<" -mcpu=cortex-m0 -std=gnu11 -g3 -DUSE_HAL_DRIVER -DSTM32F072xB -DDEBUG -c -I"D:/project_in_git/CDC_ECM/src/dns-server" -I../USB_DEVICE/Target -I../Drivers/STM32F0xx_HAL_Driver/Inc/Legacy -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4" -I"D:/project_in_git/CDC_ECM/src" -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Drivers/STM32F0xx_HAL_Driver/Inc -I../Drivers/CMSIS/Include -I"D:/project_in_git/CDC_ECM/src/dhcp-server" -I../Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -I../USB_DEVICE/App -I../Drivers/CMSIS/Device/ST/STM32F0xx/Include -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include" -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/apps/httpserver_raw" -I"D:/project_in_git/CDC_ECM/src/src" -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.d" -MT"$@" --specs=nano.specs -mfloat-abi=soft -mthumb -o "$@" +Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o: ../Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.c + arm-none-eabi-gcc "$<" -mcpu=cortex-m0 -std=gnu11 -g3 -DUSE_HAL_DRIVER -DSTM32F072xB -DDEBUG -c -I"D:/project_in_git/CDC_ECM/src/dns-server" -I../USB_DEVICE/Target -I../Drivers/STM32F0xx_HAL_Driver/Inc/Legacy -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4" -I"D:/project_in_git/CDC_ECM/src" -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Drivers/STM32F0xx_HAL_Driver/Inc -I../Drivers/CMSIS/Include -I"D:/project_in_git/CDC_ECM/src/dhcp-server" -I../Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -I../USB_DEVICE/App -I../Drivers/CMSIS/Device/ST/STM32F0xx/Include -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include" -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/apps/httpserver_raw" -I"D:/project_in_git/CDC_ECM/src/src" -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.d" -MT"$@" --specs=nano.specs -mfloat-abi=soft -mthumb -o "$@" +Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o: ../Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.c + arm-none-eabi-gcc "$<" -mcpu=cortex-m0 -std=gnu11 -g3 -DUSE_HAL_DRIVER -DSTM32F072xB -DDEBUG -c -I"D:/project_in_git/CDC_ECM/src/dns-server" -I../USB_DEVICE/Target -I../Drivers/STM32F0xx_HAL_Driver/Inc/Legacy -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4" -I"D:/project_in_git/CDC_ECM/src" -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Drivers/STM32F0xx_HAL_Driver/Inc -I../Drivers/CMSIS/Include -I"D:/project_in_git/CDC_ECM/src/dhcp-server" -I../Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -I../USB_DEVICE/App -I../Drivers/CMSIS/Device/ST/STM32F0xx/Include -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include" -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/apps/httpserver_raw" -I"D:/project_in_git/CDC_ECM/src/src" -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.d" -MT"$@" --specs=nano.specs -mfloat-abi=soft -mthumb -o "$@" +Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o: ../Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.c + arm-none-eabi-gcc "$<" -mcpu=cortex-m0 -std=gnu11 -g3 -DUSE_HAL_DRIVER -DSTM32F072xB -DDEBUG -c -I"D:/project_in_git/CDC_ECM/src/dns-server" -I../USB_DEVICE/Target -I../Drivers/STM32F0xx_HAL_Driver/Inc/Legacy -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4" -I"D:/project_in_git/CDC_ECM/src" -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Drivers/STM32F0xx_HAL_Driver/Inc -I../Drivers/CMSIS/Include -I"D:/project_in_git/CDC_ECM/src/dhcp-server" -I../Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -I../USB_DEVICE/App -I../Drivers/CMSIS/Device/ST/STM32F0xx/Include -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include" -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/apps/httpserver_raw" -I"D:/project_in_git/CDC_ECM/src/src" -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.d" -MT"$@" --specs=nano.specs -mfloat-abi=soft -mthumb -o "$@" +Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o: ../Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.c + arm-none-eabi-gcc "$<" -mcpu=cortex-m0 -std=gnu11 -g3 -DUSE_HAL_DRIVER -DSTM32F072xB -DDEBUG -c -I"D:/project_in_git/CDC_ECM/src/dns-server" -I../USB_DEVICE/Target -I../Drivers/STM32F0xx_HAL_Driver/Inc/Legacy -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4" -I"D:/project_in_git/CDC_ECM/src" -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Drivers/STM32F0xx_HAL_Driver/Inc -I../Drivers/CMSIS/Include -I"D:/project_in_git/CDC_ECM/src/dhcp-server" -I../Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -I../USB_DEVICE/App -I../Drivers/CMSIS/Device/ST/STM32F0xx/Include -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include" -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/apps/httpserver_raw" -I"D:/project_in_git/CDC_ECM/src/src" -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.d" -MT"$@" --specs=nano.specs -mfloat-abi=soft -mthumb -o "$@" +Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o: ../Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.c + arm-none-eabi-gcc "$<" -mcpu=cortex-m0 -std=gnu11 -g3 -DUSE_HAL_DRIVER -DSTM32F072xB -DDEBUG -c -I"D:/project_in_git/CDC_ECM/src/dns-server" -I../USB_DEVICE/Target -I../Drivers/STM32F0xx_HAL_Driver/Inc/Legacy -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4" -I"D:/project_in_git/CDC_ECM/src" -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Drivers/STM32F0xx_HAL_Driver/Inc -I../Drivers/CMSIS/Include -I"D:/project_in_git/CDC_ECM/src/dhcp-server" -I../Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -I../USB_DEVICE/App -I../Drivers/CMSIS/Device/ST/STM32F0xx/Include -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include" -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/apps/httpserver_raw" -I"D:/project_in_git/CDC_ECM/src/src" -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.d" -MT"$@" --specs=nano.specs -mfloat-abi=soft -mthumb -o "$@" +Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o: ../Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.c + arm-none-eabi-gcc "$<" -mcpu=cortex-m0 -std=gnu11 -g3 -DUSE_HAL_DRIVER -DSTM32F072xB -DDEBUG -c -I"D:/project_in_git/CDC_ECM/src/dns-server" -I../USB_DEVICE/Target -I../Drivers/STM32F0xx_HAL_Driver/Inc/Legacy -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4" -I"D:/project_in_git/CDC_ECM/src" -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Drivers/STM32F0xx_HAL_Driver/Inc -I../Drivers/CMSIS/Include -I"D:/project_in_git/CDC_ECM/src/dhcp-server" -I../Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -I../USB_DEVICE/App -I../Drivers/CMSIS/Device/ST/STM32F0xx/Include -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include" -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/apps/httpserver_raw" -I"D:/project_in_git/CDC_ECM/src/src" -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.d" -MT"$@" --specs=nano.specs -mfloat-abi=soft -mthumb -o "$@" +Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o: ../Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.c + arm-none-eabi-gcc "$<" -mcpu=cortex-m0 -std=gnu11 -g3 -DUSE_HAL_DRIVER -DSTM32F072xB -DDEBUG -c -I"D:/project_in_git/CDC_ECM/src/dns-server" -I../USB_DEVICE/Target -I../Drivers/STM32F0xx_HAL_Driver/Inc/Legacy -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4" -I"D:/project_in_git/CDC_ECM/src" -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Drivers/STM32F0xx_HAL_Driver/Inc -I../Drivers/CMSIS/Include -I"D:/project_in_git/CDC_ECM/src/dhcp-server" -I../Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -I../USB_DEVICE/App -I../Drivers/CMSIS/Device/ST/STM32F0xx/Include -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include" -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/apps/httpserver_raw" -I"D:/project_in_git/CDC_ECM/src/src" -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.d" -MT"$@" --specs=nano.specs -mfloat-abi=soft -mthumb -o "$@" +Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o: ../Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.c + arm-none-eabi-gcc "$<" -mcpu=cortex-m0 -std=gnu11 -g3 -DUSE_HAL_DRIVER -DSTM32F072xB -DDEBUG -c -I"D:/project_in_git/CDC_ECM/src/dns-server" -I../USB_DEVICE/Target -I../Drivers/STM32F0xx_HAL_Driver/Inc/Legacy -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4" -I"D:/project_in_git/CDC_ECM/src" -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Drivers/STM32F0xx_HAL_Driver/Inc -I../Drivers/CMSIS/Include -I"D:/project_in_git/CDC_ECM/src/dhcp-server" -I../Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -I../USB_DEVICE/App -I../Drivers/CMSIS/Device/ST/STM32F0xx/Include -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include" -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/apps/httpserver_raw" -I"D:/project_in_git/CDC_ECM/src/src" -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.d" -MT"$@" --specs=nano.specs -mfloat-abi=soft -mthumb -o "$@" +Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o: ../Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.c + arm-none-eabi-gcc "$<" -mcpu=cortex-m0 -std=gnu11 -g3 -DUSE_HAL_DRIVER -DSTM32F072xB -DDEBUG -c -I"D:/project_in_git/CDC_ECM/src/dns-server" -I../USB_DEVICE/Target -I../Drivers/STM32F0xx_HAL_Driver/Inc/Legacy -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4" -I"D:/project_in_git/CDC_ECM/src" -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Drivers/STM32F0xx_HAL_Driver/Inc -I../Drivers/CMSIS/Include -I"D:/project_in_git/CDC_ECM/src/dhcp-server" -I../Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -I../USB_DEVICE/App -I../Drivers/CMSIS/Device/ST/STM32F0xx/Include -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include" -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/apps/httpserver_raw" -I"D:/project_in_git/CDC_ECM/src/src" -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.d" -MT"$@" --specs=nano.specs -mfloat-abi=soft -mthumb -o "$@" + diff --git a/test/STM32F072C8T6/Debug/ecm_src/dhcp-server/dhserver.d b/test/STM32F072C8T6/Debug/ecm_src/dhcp-server/dhserver.d new file mode 100644 index 0000000..e4636ad --- /dev/null +++ b/test/STM32F072C8T6/Debug/ecm_src/dhcp-server/dhserver.d @@ -0,0 +1,47 @@ +ecm_src/dhcp-server/dhserver.o: \ + D:/project_in_git/CDC_ECM/src/dhcp-server/dhserver.c \ + D:/project_in_git/CDC_ECM/src/dhcp-server/dhserver.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/err.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/opt.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwipopts.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/debug.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/arch.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cc.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cpu.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/udp.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/pbuf.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/netif.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/ip_addr.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/def.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/ip.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/netif/etharp.h + +D:/project_in_git/CDC_ECM/src/dhcp-server/dhserver.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/err.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/opt.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwipopts.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/debug.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/arch.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cc.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cpu.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/udp.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/pbuf.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/netif.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/ip_addr.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/def.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/ip.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/netif/etharp.h: diff --git a/test/STM32F072C8T6/Debug/ecm_src/dhcp-server/dhserver.o b/test/STM32F072C8T6/Debug/ecm_src/dhcp-server/dhserver.o new file mode 100644 index 0000000..73510aa Binary files /dev/null and b/test/STM32F072C8T6/Debug/ecm_src/dhcp-server/dhserver.o differ diff --git a/test/STM32F072C8T6/Debug/ecm_src/dhcp-server/dhserver.su b/test/STM32F072C8T6/Debug/ecm_src/dhcp-server/dhserver.su new file mode 100644 index 0000000..ca62e1c --- /dev/null +++ b/test/STM32F072C8T6/Debug/ecm_src/dhcp-server/dhserver.su @@ -0,0 +1,12 @@ +dhserver.c:99:17:get_ip 24 static +dhserver.c:106:13:set_ip 16 static +dhserver.c:111:22:entry_by_ip 24 static +dhserver.c:120:22:entry_by_mac 24 static +dhserver.c:129:22:is_vacant 16 static +dhserver.c:134:22:vacant_address 16 static +dhserver.c:143:22:free_entry 16 static +dhserver.c:148:10:find_dhcp_option 32 static +dhserver.c:162:5:fill_options 32 static +dhserver.c:230:13:udp_recv_proc 80 static +dhserver.c:320:7:dhserv_init 32 static +dhserver.c:339:6:dhserv_free 8 static diff --git a/test/STM32F072C8T6/Debug/ecm_src/dhcp-server/subdir.mk b/test/STM32F072C8T6/Debug/ecm_src/dhcp-server/subdir.mk new file mode 100644 index 0000000..1f0e77a --- /dev/null +++ b/test/STM32F072C8T6/Debug/ecm_src/dhcp-server/subdir.mk @@ -0,0 +1,19 @@ +################################################################################ +# Automatically-generated file. Do not edit! +################################################################################ + +# Add inputs and outputs from these tool invocations to the build variables +C_SRCS += \ +D:/project_in_git/CDC_ECM/src/dhcp-server/dhserver.c + +OBJS += \ +./ecm_src/dhcp-server/dhserver.o + +C_DEPS += \ +./ecm_src/dhcp-server/dhserver.d + + +# Each subdirectory must supply rules for building sources it contributes +ecm_src/dhcp-server/dhserver.o: D:/project_in_git/CDC_ECM/src/dhcp-server/dhserver.c + arm-none-eabi-gcc "$<" -mcpu=cortex-m0 -std=gnu11 -g3 -DUSE_HAL_DRIVER -DSTM32F072xB -DDEBUG -c -I"D:/project_in_git/CDC_ECM/src/dns-server" -I../USB_DEVICE/Target -I../Drivers/STM32F0xx_HAL_Driver/Inc/Legacy -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4" -I"D:/project_in_git/CDC_ECM/src" -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Drivers/STM32F0xx_HAL_Driver/Inc -I../Drivers/CMSIS/Include -I"D:/project_in_git/CDC_ECM/src/dhcp-server" -I../Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -I../USB_DEVICE/App -I../Drivers/CMSIS/Device/ST/STM32F0xx/Include -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include" -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/apps/httpserver_raw" -I"D:/project_in_git/CDC_ECM/src/src" -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"ecm_src/dhcp-server/dhserver.d" -MT"$@" --specs=nano.specs -mfloat-abi=soft -mthumb -o "$@" + diff --git a/test/STM32F072C8T6/Debug/ecm_src/dns-server/dnserver.d b/test/STM32F072C8T6/Debug/ecm_src/dns-server/dnserver.d new file mode 100644 index 0000000..ef033f3 --- /dev/null +++ b/test/STM32F072C8T6/Debug/ecm_src/dns-server/dnserver.d @@ -0,0 +1,47 @@ +ecm_src/dns-server/dnserver.o: \ + D:/project_in_git/CDC_ECM/src/dns-server/dnserver.c \ + D:/project_in_git/CDC_ECM/src/dns-server/dnserver.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/def.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/arch.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cc.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cpu.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/opt.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwipopts.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/debug.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/err.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/udp.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/pbuf.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/netif.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/ip_addr.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/ip.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/netif/etharp.h + +D:/project_in_git/CDC_ECM/src/dns-server/dnserver.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/def.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/arch.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cc.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cpu.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/opt.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwipopts.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/debug.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/err.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/udp.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/pbuf.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/netif.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/ip_addr.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/ip.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/netif/etharp.h: diff --git a/test/STM32F072C8T6/Debug/ecm_src/dns-server/dnserver.o b/test/STM32F072C8T6/Debug/ecm_src/dns-server/dnserver.o new file mode 100644 index 0000000..6466bcb Binary files /dev/null and b/test/STM32F072C8T6/Debug/ecm_src/dns-server/dnserver.o differ diff --git a/test/STM32F072C8T6/Debug/ecm_src/dns-server/dnserver.su b/test/STM32F072C8T6/Debug/ecm_src/dns-server/dnserver.su new file mode 100644 index 0000000..33ae6b6 --- /dev/null +++ b/test/STM32F072C8T6/Debug/ecm_src/dns-server/dnserver.su @@ -0,0 +1,5 @@ +dnserver.c:86:17:get_uint16 32 static +dnserver.c:93:12:parse_next_query 48 static +dnserver.c:133:13:udp_recv_proc 56 static +dnserver.c:174:7:dnserv_init 40 static +dnserver.c:193:6:dnserv_free 8 static diff --git a/test/STM32F072C8T6/Debug/ecm_src/dns-server/subdir.mk b/test/STM32F072C8T6/Debug/ecm_src/dns-server/subdir.mk new file mode 100644 index 0000000..628d52d --- /dev/null +++ b/test/STM32F072C8T6/Debug/ecm_src/dns-server/subdir.mk @@ -0,0 +1,19 @@ +################################################################################ +# Automatically-generated file. Do not edit! +################################################################################ + +# Add inputs and outputs from these tool invocations to the build variables +C_SRCS += \ +D:/project_in_git/CDC_ECM/src/dns-server/dnserver.c + +OBJS += \ +./ecm_src/dns-server/dnserver.o + +C_DEPS += \ +./ecm_src/dns-server/dnserver.d + + +# Each subdirectory must supply rules for building sources it contributes +ecm_src/dns-server/dnserver.o: D:/project_in_git/CDC_ECM/src/dns-server/dnserver.c + arm-none-eabi-gcc "$<" -mcpu=cortex-m0 -std=gnu11 -g3 -DUSE_HAL_DRIVER -DSTM32F072xB -DDEBUG -c -I"D:/project_in_git/CDC_ECM/src/dns-server" -I../USB_DEVICE/Target -I../Drivers/STM32F0xx_HAL_Driver/Inc/Legacy -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4" -I"D:/project_in_git/CDC_ECM/src" -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Drivers/STM32F0xx_HAL_Driver/Inc -I../Drivers/CMSIS/Include -I"D:/project_in_git/CDC_ECM/src/dhcp-server" -I../Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -I../USB_DEVICE/App -I../Drivers/CMSIS/Device/ST/STM32F0xx/Include -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include" -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/apps/httpserver_raw" -I"D:/project_in_git/CDC_ECM/src/src" -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"ecm_src/dns-server/dnserver.d" -MT"$@" --specs=nano.specs -mfloat-abi=soft -mthumb -o "$@" + diff --git a/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/def.d b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/def.d new file mode 100644 index 0000000..35c2c8a --- /dev/null +++ b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/def.d @@ -0,0 +1,23 @@ +ecm_src/lwip-1.4.1/src/core/def.o: \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/core/def.c \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/opt.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwipopts.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/debug.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/arch.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cc.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cpu.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/def.h + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/opt.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwipopts.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/debug.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/arch.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cc.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cpu.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/def.h: diff --git a/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/def.o b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/def.o new file mode 100644 index 0000000..d2781d8 Binary files /dev/null and b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/def.o differ diff --git a/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/def.su b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/def.su new file mode 100644 index 0000000..7f157bd --- /dev/null +++ b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/def.su @@ -0,0 +1,4 @@ +def.c:64:1:lwip_htons 16 static +def.c:76:1:lwip_ntohs 16 static +def.c:88:1:lwip_htonl 16 static +def.c:103:1:lwip_ntohl 16 static diff --git a/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/dhcp.d b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/dhcp.d new file mode 100644 index 0000000..ba25afb --- /dev/null +++ b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/dhcp.d @@ -0,0 +1,20 @@ +ecm_src/lwip-1.4.1/src/core/dhcp.o: \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/core/dhcp.c \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/opt.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwipopts.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/debug.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/arch.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cc.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cpu.h + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/opt.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwipopts.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/debug.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/arch.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cc.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cpu.h: diff --git a/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/dhcp.o b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/dhcp.o new file mode 100644 index 0000000..e224193 Binary files /dev/null and b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/dhcp.o differ diff --git a/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/dhcp.su b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/dhcp.su new file mode 100644 index 0000000..e69de29 diff --git a/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/dns.d b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/dns.d new file mode 100644 index 0000000..87f5203 --- /dev/null +++ b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/dns.d @@ -0,0 +1,20 @@ +ecm_src/lwip-1.4.1/src/core/dns.o: \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/core/dns.c \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/opt.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwipopts.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/debug.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/arch.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cc.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cpu.h + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/opt.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwipopts.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/debug.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/arch.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cc.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cpu.h: diff --git a/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/dns.o b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/dns.o new file mode 100644 index 0000000..b67a0dd Binary files /dev/null and b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/dns.o differ diff --git a/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/dns.su b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/dns.su new file mode 100644 index 0000000..e69de29 diff --git a/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/init.d b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/init.d new file mode 100644 index 0000000..195de25 --- /dev/null +++ b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/init.d @@ -0,0 +1,101 @@ +ecm_src/lwip-1.4.1/src/core/init.o: \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/core/init.c \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/opt.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwipopts.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/debug.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/arch.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cc.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cpu.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/init.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/stats.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/mem.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/memp.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/memp_std.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/sys.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/pbuf.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/err.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/netif.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/ip_addr.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/def.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/sockets.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/ip.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/raw.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/udp.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/tcp_impl.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/tcp.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/icmp.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/snmp_msg.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/snmp.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/snmp_structs.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/autoip.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/igmp.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/dns.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/timers.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/netif/etharp.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/api.h + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/opt.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwipopts.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/debug.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/arch.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cc.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cpu.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/init.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/stats.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/mem.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/memp.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/memp_std.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/sys.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/pbuf.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/err.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/netif.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/ip_addr.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/def.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/sockets.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/ip.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/raw.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/udp.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/tcp_impl.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/tcp.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/icmp.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/snmp_msg.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/snmp.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/snmp_structs.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/autoip.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/igmp.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/dns.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/timers.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/netif/etharp.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/api.h: diff --git a/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/init.o b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/init.o new file mode 100644 index 0000000..2dcf2e4 Binary files /dev/null and b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/init.o differ diff --git a/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/init.su b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/init.su new file mode 100644 index 0000000..8db7c7c --- /dev/null +++ b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/init.su @@ -0,0 +1 @@ +init.c:289:1:lwip_init 8 static diff --git a/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/ipv4/autoip.d b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/ipv4/autoip.d new file mode 100644 index 0000000..aa706db --- /dev/null +++ b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/ipv4/autoip.d @@ -0,0 +1,20 @@ +ecm_src/lwip-1.4.1/src/core/ipv4/autoip.o: \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/core/ipv4/autoip.c \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/opt.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwipopts.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/debug.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/arch.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cc.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cpu.h + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/opt.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwipopts.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/debug.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/arch.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cc.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cpu.h: diff --git a/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/ipv4/autoip.o b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/ipv4/autoip.o new file mode 100644 index 0000000..240ba61 Binary files /dev/null and b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/ipv4/autoip.o differ diff --git a/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/ipv4/autoip.su b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/ipv4/autoip.su new file mode 100644 index 0000000..e69de29 diff --git a/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/ipv4/icmp.d b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/ipv4/icmp.d new file mode 100644 index 0000000..1f00370 --- /dev/null +++ b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/ipv4/icmp.d @@ -0,0 +1,59 @@ +ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o: \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/core/ipv4/icmp.c \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/opt.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwipopts.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/debug.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/arch.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cc.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cpu.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/icmp.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/pbuf.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/err.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/ip_addr.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/def.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/netif.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/inet_chksum.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/ip.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/stats.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/mem.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/memp.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/memp_std.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/snmp.h + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/opt.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwipopts.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/debug.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/arch.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cc.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cpu.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/icmp.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/pbuf.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/err.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/ip_addr.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/def.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/netif.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/inet_chksum.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/ip.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/stats.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/mem.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/memp.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/memp_std.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/snmp.h: diff --git a/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o new file mode 100644 index 0000000..af02c74 Binary files /dev/null and b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o differ diff --git a/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/ipv4/icmp.su b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/ipv4/icmp.su new file mode 100644 index 0000000..2ff90f8 --- /dev/null +++ b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/ipv4/icmp.su @@ -0,0 +1,4 @@ +icmp.c:77:1:icmp_input 64 static +icmp.c:261:1:icmp_dest_unreach 16 static +icmp.c:275:1:icmp_time_exceeded 16 static +icmp.c:291:1:icmp_send_response 48 static diff --git a/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/ipv4/igmp.d b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/ipv4/igmp.d new file mode 100644 index 0000000..e10cce0 --- /dev/null +++ b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/ipv4/igmp.d @@ -0,0 +1,20 @@ +ecm_src/lwip-1.4.1/src/core/ipv4/igmp.o: \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/core/ipv4/igmp.c \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/opt.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwipopts.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/debug.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/arch.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cc.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cpu.h + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/opt.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwipopts.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/debug.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/arch.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cc.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cpu.h: diff --git a/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/ipv4/igmp.o b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/ipv4/igmp.o new file mode 100644 index 0000000..6f21146 Binary files /dev/null and b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/ipv4/igmp.o differ diff --git a/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/ipv4/igmp.su b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/ipv4/igmp.su new file mode 100644 index 0000000..e69de29 diff --git a/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/ipv4/inet.d b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/ipv4/inet.d new file mode 100644 index 0000000..7df87db --- /dev/null +++ b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/ipv4/inet.d @@ -0,0 +1,29 @@ +ecm_src/lwip-1.4.1/src/core/ipv4/inet.o: \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/core/ipv4/inet.c \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/opt.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwipopts.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/debug.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/arch.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cc.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cpu.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/inet.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/def.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/ip_addr.h + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/opt.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwipopts.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/debug.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/arch.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cc.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cpu.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/inet.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/def.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/ip_addr.h: diff --git a/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/ipv4/inet.o b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/ipv4/inet.o new file mode 100644 index 0000000..f308edf Binary files /dev/null and b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/ipv4/inet.o differ diff --git a/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/ipv4/inet.su b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/ipv4/inet.su new file mode 100644 index 0000000..e69de29 diff --git a/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.d b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.d new file mode 100644 index 0000000..63fc22b --- /dev/null +++ b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.d @@ -0,0 +1,35 @@ +ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o: \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/core/ipv4/inet_chksum.c \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/opt.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwipopts.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/debug.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/arch.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cc.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cpu.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/inet_chksum.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/pbuf.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/err.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/ip_addr.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/def.h + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/opt.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwipopts.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/debug.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/arch.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cc.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cpu.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/inet_chksum.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/pbuf.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/err.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/ip_addr.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/def.h: diff --git a/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o new file mode 100644 index 0000000..634503c Binary files /dev/null and b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o differ diff --git a/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.su b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.su new file mode 100644 index 0000000..60aee89 --- /dev/null +++ b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.su @@ -0,0 +1,5 @@ +inet_chksum.c:135:1:lwip_standard_chksum 40 static +inet_chksum.c:272:1:inet_chksum_pseudo 40 static +inet_chksum.c:332:1:inet_chksum_pseudo_partial 48 static +inet_chksum.c:396:1:inet_chksum 16 static +inet_chksum.c:409:1:inet_chksum_pbuf 32 static diff --git a/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/ipv4/ip.d b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/ipv4/ip.d new file mode 100644 index 0000000..f1cfe01 --- /dev/null +++ b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/ipv4/ip.d @@ -0,0 +1,86 @@ +ecm_src/lwip-1.4.1/src/core/ipv4/ip.o: \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/core/ipv4/ip.c \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/opt.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwipopts.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/debug.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/arch.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cc.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cpu.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/ip.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/def.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/pbuf.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/err.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/ip_addr.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/netif.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/mem.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/ip_frag.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/inet_chksum.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/icmp.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/igmp.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/raw.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/udp.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/tcp_impl.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/tcp.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/snmp.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/dhcp.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/autoip.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/stats.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/memp.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/memp_std.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/perf.h + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/opt.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwipopts.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/debug.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/arch.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cc.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cpu.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/ip.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/def.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/pbuf.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/err.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/ip_addr.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/netif.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/mem.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/ip_frag.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/inet_chksum.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/icmp.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/igmp.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/raw.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/udp.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/tcp_impl.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/tcp.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/snmp.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/dhcp.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/autoip.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/stats.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/memp.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/memp_std.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/perf.h: diff --git a/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/ipv4/ip.o b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/ipv4/ip.o new file mode 100644 index 0000000..2d99abd Binary files /dev/null and b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/ipv4/ip.o differ diff --git a/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/ipv4/ip.su b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/ipv4/ip.su new file mode 100644 index 0000000..7915814 --- /dev/null +++ b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/ipv4/ip.su @@ -0,0 +1,4 @@ +ip.c:124:1:ip_route 24 static +ip.c:305:1:ip_input 48 static +ip.c:641:1:ip_output_if 48 static +ip.c:818:1:ip_output 56 static diff --git a/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.d b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.d new file mode 100644 index 0000000..672ac8d --- /dev/null +++ b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.d @@ -0,0 +1,35 @@ +ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o: \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/core/ipv4/ip_addr.c \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/opt.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwipopts.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/debug.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/arch.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cc.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cpu.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/ip_addr.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/def.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/netif.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/err.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/pbuf.h + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/opt.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwipopts.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/debug.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/arch.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cc.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cpu.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/ip_addr.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/def.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/netif.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/err.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/pbuf.h: diff --git a/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o new file mode 100644 index 0000000..a5fcbcb Binary files /dev/null and b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o differ diff --git a/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.su b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.su new file mode 100644 index 0000000..e62a3f5 --- /dev/null +++ b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.su @@ -0,0 +1,6 @@ +ip_addr.c:55:1:ip4_addr_isbroadcast 24 static +ip_addr.c:90:1:ip4_addr_netmask_valid 24 static +ip_addr.c:130:1:ipaddr_addr 24 static +ip_addr.c:152:1:ipaddr_aton 48 static +ip_addr.c:261:1:ipaddr_ntoa 16 static +ip_addr.c:276:7:ipaddr_ntoa_r 64 static diff --git a/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.d b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.d new file mode 100644 index 0000000..d2bf1b1 --- /dev/null +++ b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.d @@ -0,0 +1,62 @@ +ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o: \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/core/ipv4/ip_frag.c \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/opt.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwipopts.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/debug.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/arch.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cc.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cpu.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/ip_frag.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/err.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/pbuf.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/netif.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/ip_addr.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/def.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/ip.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/inet_chksum.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/snmp.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/stats.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/mem.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/memp.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/memp_std.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/icmp.h + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/opt.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwipopts.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/debug.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/arch.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cc.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cpu.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/ip_frag.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/err.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/pbuf.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/netif.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/ip_addr.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/def.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/ip.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/inet_chksum.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/snmp.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/stats.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/mem.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/memp.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/memp_std.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/icmp.h: diff --git a/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o new file mode 100644 index 0000000..b2fe8fe Binary files /dev/null and b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o differ diff --git a/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.su b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.su new file mode 100644 index 0000000..21bd790 --- /dev/null +++ b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.su @@ -0,0 +1,11 @@ +ip_frag.c:122:1:ip_reass_tmr 24 static +ip_frag.c:158:1:ip_reass_free_complete_datagram 48 static +ip_frag.c:221:1:ip_reass_remove_oldest_datagram 40 static +ip_frag.c:269:1:ip_reass_enqueue_new_datagram 24 static +ip_frag.c:304:1:ip_reass_dequeue_datagram 16 static +ip_frag.c:331:1:ip_reass_chain_frag_into_datagram_and_validate 64 static +ip_frag.c:476:1:ip_reass 56 static +ip_frag.c:624:1:ip_frag_alloc_pbuf_custom_ref 8 static +ip_frag.c:631:1:ip_frag_free_pbuf_custom_ref 16 static +ip_frag.c:640:1:ipfrag_free_pbuf_custom 24 static +ip_frag.c:667:1:ip_frag 96 static diff --git a/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/ipv4/subdir.mk b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/ipv4/subdir.mk new file mode 100644 index 0000000..05f098d --- /dev/null +++ b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/ipv4/subdir.mk @@ -0,0 +1,54 @@ +################################################################################ +# Automatically-generated file. Do not edit! +################################################################################ + +# Add inputs and outputs from these tool invocations to the build variables +C_SRCS += \ +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/core/ipv4/autoip.c \ +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/core/ipv4/icmp.c \ +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/core/ipv4/igmp.c \ +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/core/ipv4/inet.c \ +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/core/ipv4/inet_chksum.c \ +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/core/ipv4/ip.c \ +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/core/ipv4/ip_addr.c \ +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/core/ipv4/ip_frag.c + +OBJS += \ +./ecm_src/lwip-1.4.1/src/core/ipv4/autoip.o \ +./ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o \ +./ecm_src/lwip-1.4.1/src/core/ipv4/igmp.o \ +./ecm_src/lwip-1.4.1/src/core/ipv4/inet.o \ +./ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o \ +./ecm_src/lwip-1.4.1/src/core/ipv4/ip.o \ +./ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o \ +./ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + +C_DEPS += \ +./ecm_src/lwip-1.4.1/src/core/ipv4/autoip.d \ +./ecm_src/lwip-1.4.1/src/core/ipv4/icmp.d \ +./ecm_src/lwip-1.4.1/src/core/ipv4/igmp.d \ +./ecm_src/lwip-1.4.1/src/core/ipv4/inet.d \ +./ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.d \ +./ecm_src/lwip-1.4.1/src/core/ipv4/ip.d \ +./ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.d \ +./ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.d + + +# Each subdirectory must supply rules for building sources it contributes +ecm_src/lwip-1.4.1/src/core/ipv4/autoip.o: D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/core/ipv4/autoip.c + arm-none-eabi-gcc "$<" -mcpu=cortex-m0 -std=gnu11 -g3 -DUSE_HAL_DRIVER -DSTM32F072xB -DDEBUG -c -I"D:/project_in_git/CDC_ECM/src/dns-server" -I../USB_DEVICE/Target -I../Drivers/STM32F0xx_HAL_Driver/Inc/Legacy -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4" -I"D:/project_in_git/CDC_ECM/src" -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Drivers/STM32F0xx_HAL_Driver/Inc -I../Drivers/CMSIS/Include -I"D:/project_in_git/CDC_ECM/src/dhcp-server" -I../Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -I../USB_DEVICE/App -I../Drivers/CMSIS/Device/ST/STM32F0xx/Include -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include" -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/apps/httpserver_raw" -I"D:/project_in_git/CDC_ECM/src/src" -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"ecm_src/lwip-1.4.1/src/core/ipv4/autoip.d" -MT"$@" --specs=nano.specs -mfloat-abi=soft -mthumb -o "$@" +ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o: D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/core/ipv4/icmp.c + arm-none-eabi-gcc "$<" -mcpu=cortex-m0 -std=gnu11 -g3 -DUSE_HAL_DRIVER -DSTM32F072xB -DDEBUG -c -I"D:/project_in_git/CDC_ECM/src/dns-server" -I../USB_DEVICE/Target -I../Drivers/STM32F0xx_HAL_Driver/Inc/Legacy -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4" -I"D:/project_in_git/CDC_ECM/src" -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Drivers/STM32F0xx_HAL_Driver/Inc -I../Drivers/CMSIS/Include -I"D:/project_in_git/CDC_ECM/src/dhcp-server" -I../Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -I../USB_DEVICE/App -I../Drivers/CMSIS/Device/ST/STM32F0xx/Include -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include" -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/apps/httpserver_raw" -I"D:/project_in_git/CDC_ECM/src/src" -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"ecm_src/lwip-1.4.1/src/core/ipv4/icmp.d" -MT"$@" --specs=nano.specs -mfloat-abi=soft -mthumb -o "$@" +ecm_src/lwip-1.4.1/src/core/ipv4/igmp.o: D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/core/ipv4/igmp.c + arm-none-eabi-gcc "$<" -mcpu=cortex-m0 -std=gnu11 -g3 -DUSE_HAL_DRIVER -DSTM32F072xB -DDEBUG -c -I"D:/project_in_git/CDC_ECM/src/dns-server" -I../USB_DEVICE/Target -I../Drivers/STM32F0xx_HAL_Driver/Inc/Legacy -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4" -I"D:/project_in_git/CDC_ECM/src" -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Drivers/STM32F0xx_HAL_Driver/Inc -I../Drivers/CMSIS/Include -I"D:/project_in_git/CDC_ECM/src/dhcp-server" -I../Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -I../USB_DEVICE/App -I../Drivers/CMSIS/Device/ST/STM32F0xx/Include -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include" -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/apps/httpserver_raw" -I"D:/project_in_git/CDC_ECM/src/src" -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"ecm_src/lwip-1.4.1/src/core/ipv4/igmp.d" -MT"$@" --specs=nano.specs -mfloat-abi=soft -mthumb -o "$@" +ecm_src/lwip-1.4.1/src/core/ipv4/inet.o: D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/core/ipv4/inet.c + arm-none-eabi-gcc "$<" -mcpu=cortex-m0 -std=gnu11 -g3 -DUSE_HAL_DRIVER -DSTM32F072xB -DDEBUG -c -I"D:/project_in_git/CDC_ECM/src/dns-server" -I../USB_DEVICE/Target -I../Drivers/STM32F0xx_HAL_Driver/Inc/Legacy -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4" -I"D:/project_in_git/CDC_ECM/src" -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Drivers/STM32F0xx_HAL_Driver/Inc -I../Drivers/CMSIS/Include -I"D:/project_in_git/CDC_ECM/src/dhcp-server" -I../Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -I../USB_DEVICE/App -I../Drivers/CMSIS/Device/ST/STM32F0xx/Include -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include" -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/apps/httpserver_raw" -I"D:/project_in_git/CDC_ECM/src/src" -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"ecm_src/lwip-1.4.1/src/core/ipv4/inet.d" -MT"$@" --specs=nano.specs -mfloat-abi=soft -mthumb -o "$@" +ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o: D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/core/ipv4/inet_chksum.c + arm-none-eabi-gcc "$<" -mcpu=cortex-m0 -std=gnu11 -g3 -DUSE_HAL_DRIVER -DSTM32F072xB -DDEBUG -c -I"D:/project_in_git/CDC_ECM/src/dns-server" -I../USB_DEVICE/Target -I../Drivers/STM32F0xx_HAL_Driver/Inc/Legacy -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4" -I"D:/project_in_git/CDC_ECM/src" -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Drivers/STM32F0xx_HAL_Driver/Inc -I../Drivers/CMSIS/Include -I"D:/project_in_git/CDC_ECM/src/dhcp-server" -I../Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -I../USB_DEVICE/App -I../Drivers/CMSIS/Device/ST/STM32F0xx/Include -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include" -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/apps/httpserver_raw" -I"D:/project_in_git/CDC_ECM/src/src" -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.d" -MT"$@" --specs=nano.specs -mfloat-abi=soft -mthumb -o "$@" +ecm_src/lwip-1.4.1/src/core/ipv4/ip.o: D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/core/ipv4/ip.c + arm-none-eabi-gcc "$<" -mcpu=cortex-m0 -std=gnu11 -g3 -DUSE_HAL_DRIVER -DSTM32F072xB -DDEBUG -c -I"D:/project_in_git/CDC_ECM/src/dns-server" -I../USB_DEVICE/Target -I../Drivers/STM32F0xx_HAL_Driver/Inc/Legacy -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4" -I"D:/project_in_git/CDC_ECM/src" -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Drivers/STM32F0xx_HAL_Driver/Inc -I../Drivers/CMSIS/Include -I"D:/project_in_git/CDC_ECM/src/dhcp-server" -I../Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -I../USB_DEVICE/App -I../Drivers/CMSIS/Device/ST/STM32F0xx/Include -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include" -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/apps/httpserver_raw" -I"D:/project_in_git/CDC_ECM/src/src" -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"ecm_src/lwip-1.4.1/src/core/ipv4/ip.d" -MT"$@" --specs=nano.specs -mfloat-abi=soft -mthumb -o "$@" +ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o: D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/core/ipv4/ip_addr.c + arm-none-eabi-gcc "$<" -mcpu=cortex-m0 -std=gnu11 -g3 -DUSE_HAL_DRIVER -DSTM32F072xB -DDEBUG -c -I"D:/project_in_git/CDC_ECM/src/dns-server" -I../USB_DEVICE/Target -I../Drivers/STM32F0xx_HAL_Driver/Inc/Legacy -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4" -I"D:/project_in_git/CDC_ECM/src" -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Drivers/STM32F0xx_HAL_Driver/Inc -I../Drivers/CMSIS/Include -I"D:/project_in_git/CDC_ECM/src/dhcp-server" -I../Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -I../USB_DEVICE/App -I../Drivers/CMSIS/Device/ST/STM32F0xx/Include -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include" -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/apps/httpserver_raw" -I"D:/project_in_git/CDC_ECM/src/src" -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.d" -MT"$@" --specs=nano.specs -mfloat-abi=soft -mthumb -o "$@" +ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o: D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/core/ipv4/ip_frag.c + arm-none-eabi-gcc "$<" -mcpu=cortex-m0 -std=gnu11 -g3 -DUSE_HAL_DRIVER -DSTM32F072xB -DDEBUG -c -I"D:/project_in_git/CDC_ECM/src/dns-server" -I../USB_DEVICE/Target -I../Drivers/STM32F0xx_HAL_Driver/Inc/Legacy -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4" -I"D:/project_in_git/CDC_ECM/src" -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Drivers/STM32F0xx_HAL_Driver/Inc -I../Drivers/CMSIS/Include -I"D:/project_in_git/CDC_ECM/src/dhcp-server" -I../Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -I../USB_DEVICE/App -I../Drivers/CMSIS/Device/ST/STM32F0xx/Include -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include" -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/apps/httpserver_raw" -I"D:/project_in_git/CDC_ECM/src/src" -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.d" -MT"$@" --specs=nano.specs -mfloat-abi=soft -mthumb -o "$@" + diff --git a/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/mem.d b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/mem.d new file mode 100644 index 0000000..537b3ea --- /dev/null +++ b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/mem.d @@ -0,0 +1,41 @@ +ecm_src/lwip-1.4.1/src/core/mem.o: \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/core/mem.c \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/opt.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwipopts.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/debug.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/arch.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cc.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cpu.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/def.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/mem.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/sys.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/stats.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/memp.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/memp_std.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/err.h + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/opt.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwipopts.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/debug.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/arch.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cc.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cpu.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/def.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/mem.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/sys.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/stats.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/memp.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/memp_std.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/err.h: diff --git a/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/mem.o b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/mem.o new file mode 100644 index 0000000..0a9ea67 Binary files /dev/null and b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/mem.o differ diff --git a/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/mem.su b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/mem.su new file mode 100644 index 0000000..6516be0 --- /dev/null +++ b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/mem.su @@ -0,0 +1,6 @@ +mem.c:236:1:plug_holes 24 static +mem.c:274:1:mem_init 16 static +mem.c:311:1:mem_free 24 static +mem.c:369:1:mem_trim 32 static +mem.c:494:1:mem_malloc 40 static +mem.c:646:7:mem_calloc 24 static diff --git a/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/memp.d b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/memp.d new file mode 100644 index 0000000..3d42f72 --- /dev/null +++ b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/memp.d @@ -0,0 +1,104 @@ +ecm_src/lwip-1.4.1/src/core/memp.o: \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/core/memp.c \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/opt.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwipopts.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/debug.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/arch.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cc.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cpu.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/memp.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/memp_std.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/pbuf.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/err.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/udp.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/netif.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/ip_addr.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/def.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/ip.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/raw.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/tcp_impl.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/tcp.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/mem.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/icmp.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/igmp.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/api.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/api_msg.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/tcpip.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/sys.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/timers.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/stats.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/netif/etharp.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/ip_frag.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/snmp_structs.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/snmp_msg.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/snmp.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/dns.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/netif/ppp_oe.h + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/opt.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwipopts.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/debug.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/arch.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cc.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cpu.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/memp.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/memp_std.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/pbuf.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/err.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/udp.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/netif.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/ip_addr.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/def.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/ip.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/raw.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/tcp_impl.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/tcp.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/mem.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/icmp.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/igmp.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/api.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/api_msg.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/tcpip.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/sys.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/timers.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/stats.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/netif/etharp.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/ip_frag.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/snmp_structs.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/snmp_msg.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/snmp.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/dns.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/netif/ppp_oe.h: diff --git a/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/memp.o b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/memp.o new file mode 100644 index 0000000..d77fe82 Binary files /dev/null and b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/memp.o differ diff --git a/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/memp.su b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/memp.su new file mode 100644 index 0000000..ed92580 --- /dev/null +++ b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/memp.su @@ -0,0 +1,3 @@ +memp.c:338:1:memp_init 24 static +memp.c:390:1:memp_malloc 32 static +memp.c:435:1:memp_free 32 static diff --git a/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/netif.d b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/netif.d new file mode 100644 index 0000000..6a1efb3 --- /dev/null +++ b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/netif.d @@ -0,0 +1,68 @@ +ecm_src/lwip-1.4.1/src/core/netif.o: \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/core/netif.c \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/opt.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwipopts.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/debug.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/arch.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cc.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cpu.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/def.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/ip_addr.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/netif.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/err.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/pbuf.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/tcp_impl.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/tcp.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/mem.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/ip.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/icmp.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/snmp.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/igmp.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/netif/etharp.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/stats.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/memp.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/memp_std.h + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/opt.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwipopts.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/debug.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/arch.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cc.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cpu.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/def.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/ip_addr.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/netif.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/err.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/pbuf.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/tcp_impl.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/tcp.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/mem.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/ip.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/icmp.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/snmp.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/igmp.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/netif/etharp.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/stats.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/memp.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/memp_std.h: diff --git a/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/netif.o b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/netif.o new file mode 100644 index 0000000..b4097b7 Binary files /dev/null and b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/netif.o differ diff --git a/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/netif.su b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/netif.su new file mode 100644 index 0000000..8174dca --- /dev/null +++ b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/netif.su @@ -0,0 +1,13 @@ +netif.c:106:1:netif_init 8 static +netif.c:139:1:netif_add 24 static +netif.c:221:1:netif_set_addr 24 static +netif.c:235:1:netif_remove 24 static +netif.c:290:1:netif_find 24 static +netif.c:323:1:netif_set_ipaddr 32 static +netif.c:388:1:netif_set_gw 16 static +netif.c:409:1:netif_set_netmask 16 static +netif.c:430:1:netif_set_default 16 static +netif.c:453:6:netif_set_up 16 static +netif.c:490:6:netif_set_down 16 static +netif.c:535:6:netif_set_link_up 16 static +netif.c:574:6:netif_set_link_down 16 static diff --git a/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/pbuf.d b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/pbuf.d new file mode 100644 index 0000000..7c3d4a4 --- /dev/null +++ b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/pbuf.d @@ -0,0 +1,65 @@ +ecm_src/lwip-1.4.1/src/core/pbuf.o: \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/core/pbuf.c \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/opt.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwipopts.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/debug.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/arch.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cc.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cpu.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/stats.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/mem.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/memp.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/memp_std.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/def.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/pbuf.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/err.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/sys.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/perf.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/tcp_impl.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/tcp.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/ip.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/ip_addr.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/netif.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/icmp.h + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/opt.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwipopts.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/debug.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/arch.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cc.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cpu.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/stats.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/mem.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/memp.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/memp_std.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/def.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/pbuf.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/err.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/sys.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/perf.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/tcp_impl.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/tcp.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/ip.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/ip_addr.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/netif.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/icmp.h: diff --git a/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/pbuf.o b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/pbuf.o new file mode 100644 index 0000000..aa277d5 Binary files /dev/null and b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/pbuf.o differ diff --git a/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/pbuf.su b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/pbuf.su new file mode 100644 index 0000000..ffcb0ae --- /dev/null +++ b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/pbuf.su @@ -0,0 +1,20 @@ +pbuf.c:118:1:pbuf_free_ooseq 16 static +pbuf.c:152:1:pbuf_pool_is_empty 8 static +pbuf.c:207:1:pbuf_alloc 48 static +pbuf.c:367:1:pbuf_alloced_custom 32 static +pbuf.c:430:1:pbuf_realloc 32 static +pbuf.c:511:1:pbuf_header 24 static +pbuf.c:618:1:pbuf_free 32 static +pbuf.c:704:1:pbuf_clen 24 static +pbuf.c:723:1:pbuf_ref 16 static +pbuf.c:745:1:pbuf_cat 24 static +pbuf.c:786:1:pbuf_chain 16 static +pbuf.c:803:1:pbuf_dechain 32 static +pbuf.c:852:1:pbuf_copy 40 static +pbuf.c:918:1:pbuf_copy_partial 48 static +pbuf.c:966:1:pbuf_take 48 static +pbuf.c:1010:1:pbuf_coalesce 32 static +pbuf.c:1077:1:pbuf_get_at 24 static +pbuf.c:1104:1:pbuf_memcmp 56 static +pbuf.c:1140:1:pbuf_memfind 48 static +pbuf.c:1168:1:pbuf_strstr 24 static diff --git a/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/raw.d b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/raw.d new file mode 100644 index 0000000..b6c34d4 --- /dev/null +++ b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/raw.d @@ -0,0 +1,56 @@ +ecm_src/lwip-1.4.1/src/core/raw.o: \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/core/raw.c \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/opt.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwipopts.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/debug.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/arch.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cc.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cpu.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/def.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/memp.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/memp_std.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/ip_addr.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/netif.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/err.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/pbuf.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/raw.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/ip.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/stats.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/mem.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/perf.h + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/opt.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwipopts.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/debug.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/arch.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cc.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cpu.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/def.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/memp.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/memp_std.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/ip_addr.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/netif.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/err.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/pbuf.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/raw.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/ip.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/stats.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/mem.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/perf.h: diff --git a/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/raw.o b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/raw.o new file mode 100644 index 0000000..b9d8cdf Binary files /dev/null and b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/raw.o differ diff --git a/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/raw.su b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/raw.su new file mode 100644 index 0000000..4757728 --- /dev/null +++ b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/raw.su @@ -0,0 +1,8 @@ +raw.c:76:1:raw_input 48 static +raw.c:142:1:raw_bind 16 static +raw.c:162:1:raw_connect 16 static +raw.c:183:1:raw_recv 24 static +raw.c:203:1:raw_sendto 72 static +raw.c:286:1:raw_send 16 static +raw.c:300:1:raw_remove 24 static +raw.c:331:1:raw_new 24 static diff --git a/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/stats.d b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/stats.d new file mode 100644 index 0000000..23a2dfc --- /dev/null +++ b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/stats.d @@ -0,0 +1,35 @@ +ecm_src/lwip-1.4.1/src/core/stats.o: \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/core/stats.c \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/opt.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwipopts.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/debug.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/arch.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cc.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cpu.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/def.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/stats.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/mem.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/memp.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/memp_std.h + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/opt.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwipopts.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/debug.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/arch.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cc.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cpu.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/def.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/stats.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/mem.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/memp.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/memp_std.h: diff --git a/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/stats.o b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/stats.o new file mode 100644 index 0000000..6739449 Binary files /dev/null and b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/stats.o differ diff --git a/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/stats.su b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/stats.su new file mode 100644 index 0000000..2b11c65 --- /dev/null +++ b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/stats.su @@ -0,0 +1 @@ +stats.c:51:6:stats_init 8 static diff --git a/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/subdir.mk b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/subdir.mk new file mode 100644 index 0000000..9ae66d3 --- /dev/null +++ b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/subdir.mk @@ -0,0 +1,94 @@ +################################################################################ +# Automatically-generated file. Do not edit! +################################################################################ + +# Add inputs and outputs from these tool invocations to the build variables +C_SRCS += \ +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/core/def.c \ +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/core/dhcp.c \ +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/core/dns.c \ +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/core/init.c \ +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/core/mem.c \ +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/core/memp.c \ +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/core/netif.c \ +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/core/pbuf.c \ +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/core/raw.c \ +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/core/stats.c \ +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/core/sys.c \ +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/core/tcp.c \ +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/core/tcp_in.c \ +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/core/tcp_out.c \ +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/core/timers.c \ +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/core/udp.c + +OBJS += \ +./ecm_src/lwip-1.4.1/src/core/def.o \ +./ecm_src/lwip-1.4.1/src/core/dhcp.o \ +./ecm_src/lwip-1.4.1/src/core/dns.o \ +./ecm_src/lwip-1.4.1/src/core/init.o \ +./ecm_src/lwip-1.4.1/src/core/mem.o \ +./ecm_src/lwip-1.4.1/src/core/memp.o \ +./ecm_src/lwip-1.4.1/src/core/netif.o \ +./ecm_src/lwip-1.4.1/src/core/pbuf.o \ +./ecm_src/lwip-1.4.1/src/core/raw.o \ +./ecm_src/lwip-1.4.1/src/core/stats.o \ +./ecm_src/lwip-1.4.1/src/core/sys.o \ +./ecm_src/lwip-1.4.1/src/core/tcp.o \ +./ecm_src/lwip-1.4.1/src/core/tcp_in.o \ +./ecm_src/lwip-1.4.1/src/core/tcp_out.o \ +./ecm_src/lwip-1.4.1/src/core/timers.o \ +./ecm_src/lwip-1.4.1/src/core/udp.o + +C_DEPS += \ +./ecm_src/lwip-1.4.1/src/core/def.d \ +./ecm_src/lwip-1.4.1/src/core/dhcp.d \ +./ecm_src/lwip-1.4.1/src/core/dns.d \ +./ecm_src/lwip-1.4.1/src/core/init.d \ +./ecm_src/lwip-1.4.1/src/core/mem.d \ +./ecm_src/lwip-1.4.1/src/core/memp.d \ +./ecm_src/lwip-1.4.1/src/core/netif.d \ +./ecm_src/lwip-1.4.1/src/core/pbuf.d \ +./ecm_src/lwip-1.4.1/src/core/raw.d \ +./ecm_src/lwip-1.4.1/src/core/stats.d \ +./ecm_src/lwip-1.4.1/src/core/sys.d \ +./ecm_src/lwip-1.4.1/src/core/tcp.d \ +./ecm_src/lwip-1.4.1/src/core/tcp_in.d \ +./ecm_src/lwip-1.4.1/src/core/tcp_out.d \ +./ecm_src/lwip-1.4.1/src/core/timers.d \ +./ecm_src/lwip-1.4.1/src/core/udp.d + + +# Each subdirectory must supply rules for building sources it contributes +ecm_src/lwip-1.4.1/src/core/def.o: D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/core/def.c + arm-none-eabi-gcc "$<" -mcpu=cortex-m0 -std=gnu11 -g3 -DUSE_HAL_DRIVER -DSTM32F072xB -DDEBUG -c -I"D:/project_in_git/CDC_ECM/src/dns-server" -I../USB_DEVICE/Target -I../Drivers/STM32F0xx_HAL_Driver/Inc/Legacy -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4" -I"D:/project_in_git/CDC_ECM/src" -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Drivers/STM32F0xx_HAL_Driver/Inc -I../Drivers/CMSIS/Include -I"D:/project_in_git/CDC_ECM/src/dhcp-server" -I../Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -I../USB_DEVICE/App -I../Drivers/CMSIS/Device/ST/STM32F0xx/Include -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include" -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/apps/httpserver_raw" -I"D:/project_in_git/CDC_ECM/src/src" -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"ecm_src/lwip-1.4.1/src/core/def.d" -MT"$@" --specs=nano.specs -mfloat-abi=soft -mthumb -o "$@" +ecm_src/lwip-1.4.1/src/core/dhcp.o: D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/core/dhcp.c + arm-none-eabi-gcc "$<" -mcpu=cortex-m0 -std=gnu11 -g3 -DUSE_HAL_DRIVER -DSTM32F072xB -DDEBUG -c -I"D:/project_in_git/CDC_ECM/src/dns-server" -I../USB_DEVICE/Target -I../Drivers/STM32F0xx_HAL_Driver/Inc/Legacy -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4" -I"D:/project_in_git/CDC_ECM/src" -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Drivers/STM32F0xx_HAL_Driver/Inc -I../Drivers/CMSIS/Include -I"D:/project_in_git/CDC_ECM/src/dhcp-server" -I../Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -I../USB_DEVICE/App -I../Drivers/CMSIS/Device/ST/STM32F0xx/Include -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include" -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/apps/httpserver_raw" -I"D:/project_in_git/CDC_ECM/src/src" -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"ecm_src/lwip-1.4.1/src/core/dhcp.d" -MT"$@" --specs=nano.specs -mfloat-abi=soft -mthumb -o "$@" +ecm_src/lwip-1.4.1/src/core/dns.o: D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/core/dns.c + arm-none-eabi-gcc "$<" -mcpu=cortex-m0 -std=gnu11 -g3 -DUSE_HAL_DRIVER -DSTM32F072xB -DDEBUG -c -I"D:/project_in_git/CDC_ECM/src/dns-server" -I../USB_DEVICE/Target -I../Drivers/STM32F0xx_HAL_Driver/Inc/Legacy -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4" -I"D:/project_in_git/CDC_ECM/src" -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Drivers/STM32F0xx_HAL_Driver/Inc -I../Drivers/CMSIS/Include -I"D:/project_in_git/CDC_ECM/src/dhcp-server" -I../Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -I../USB_DEVICE/App -I../Drivers/CMSIS/Device/ST/STM32F0xx/Include -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include" -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/apps/httpserver_raw" -I"D:/project_in_git/CDC_ECM/src/src" -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"ecm_src/lwip-1.4.1/src/core/dns.d" -MT"$@" --specs=nano.specs -mfloat-abi=soft -mthumb -o "$@" +ecm_src/lwip-1.4.1/src/core/init.o: D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/core/init.c + arm-none-eabi-gcc "$<" -mcpu=cortex-m0 -std=gnu11 -g3 -DUSE_HAL_DRIVER -DSTM32F072xB -DDEBUG -c -I"D:/project_in_git/CDC_ECM/src/dns-server" -I../USB_DEVICE/Target -I../Drivers/STM32F0xx_HAL_Driver/Inc/Legacy -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4" -I"D:/project_in_git/CDC_ECM/src" -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Drivers/STM32F0xx_HAL_Driver/Inc -I../Drivers/CMSIS/Include -I"D:/project_in_git/CDC_ECM/src/dhcp-server" -I../Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -I../USB_DEVICE/App -I../Drivers/CMSIS/Device/ST/STM32F0xx/Include -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include" -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/apps/httpserver_raw" -I"D:/project_in_git/CDC_ECM/src/src" -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"ecm_src/lwip-1.4.1/src/core/init.d" -MT"$@" --specs=nano.specs -mfloat-abi=soft -mthumb -o "$@" +ecm_src/lwip-1.4.1/src/core/mem.o: D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/core/mem.c + arm-none-eabi-gcc "$<" -mcpu=cortex-m0 -std=gnu11 -g3 -DUSE_HAL_DRIVER -DSTM32F072xB -DDEBUG -c -I"D:/project_in_git/CDC_ECM/src/dns-server" -I../USB_DEVICE/Target -I../Drivers/STM32F0xx_HAL_Driver/Inc/Legacy -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4" -I"D:/project_in_git/CDC_ECM/src" -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Drivers/STM32F0xx_HAL_Driver/Inc -I../Drivers/CMSIS/Include -I"D:/project_in_git/CDC_ECM/src/dhcp-server" -I../Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -I../USB_DEVICE/App -I../Drivers/CMSIS/Device/ST/STM32F0xx/Include -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include" -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/apps/httpserver_raw" -I"D:/project_in_git/CDC_ECM/src/src" -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"ecm_src/lwip-1.4.1/src/core/mem.d" -MT"$@" --specs=nano.specs -mfloat-abi=soft -mthumb -o "$@" +ecm_src/lwip-1.4.1/src/core/memp.o: D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/core/memp.c + arm-none-eabi-gcc "$<" -mcpu=cortex-m0 -std=gnu11 -g3 -DUSE_HAL_DRIVER -DSTM32F072xB -DDEBUG -c -I"D:/project_in_git/CDC_ECM/src/dns-server" -I../USB_DEVICE/Target -I../Drivers/STM32F0xx_HAL_Driver/Inc/Legacy -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4" -I"D:/project_in_git/CDC_ECM/src" -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Drivers/STM32F0xx_HAL_Driver/Inc -I../Drivers/CMSIS/Include -I"D:/project_in_git/CDC_ECM/src/dhcp-server" -I../Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -I../USB_DEVICE/App -I../Drivers/CMSIS/Device/ST/STM32F0xx/Include -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include" -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/apps/httpserver_raw" -I"D:/project_in_git/CDC_ECM/src/src" -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"ecm_src/lwip-1.4.1/src/core/memp.d" -MT"$@" --specs=nano.specs -mfloat-abi=soft -mthumb -o "$@" +ecm_src/lwip-1.4.1/src/core/netif.o: D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/core/netif.c + arm-none-eabi-gcc "$<" -mcpu=cortex-m0 -std=gnu11 -g3 -DUSE_HAL_DRIVER -DSTM32F072xB -DDEBUG -c -I"D:/project_in_git/CDC_ECM/src/dns-server" -I../USB_DEVICE/Target -I../Drivers/STM32F0xx_HAL_Driver/Inc/Legacy -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4" -I"D:/project_in_git/CDC_ECM/src" -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Drivers/STM32F0xx_HAL_Driver/Inc -I../Drivers/CMSIS/Include -I"D:/project_in_git/CDC_ECM/src/dhcp-server" -I../Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -I../USB_DEVICE/App -I../Drivers/CMSIS/Device/ST/STM32F0xx/Include -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include" -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/apps/httpserver_raw" -I"D:/project_in_git/CDC_ECM/src/src" -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"ecm_src/lwip-1.4.1/src/core/netif.d" -MT"$@" --specs=nano.specs -mfloat-abi=soft -mthumb -o "$@" +ecm_src/lwip-1.4.1/src/core/pbuf.o: D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/core/pbuf.c + arm-none-eabi-gcc "$<" -mcpu=cortex-m0 -std=gnu11 -g3 -DUSE_HAL_DRIVER -DSTM32F072xB -DDEBUG -c -I"D:/project_in_git/CDC_ECM/src/dns-server" -I../USB_DEVICE/Target -I../Drivers/STM32F0xx_HAL_Driver/Inc/Legacy -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4" -I"D:/project_in_git/CDC_ECM/src" -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Drivers/STM32F0xx_HAL_Driver/Inc -I../Drivers/CMSIS/Include -I"D:/project_in_git/CDC_ECM/src/dhcp-server" -I../Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -I../USB_DEVICE/App -I../Drivers/CMSIS/Device/ST/STM32F0xx/Include -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include" -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/apps/httpserver_raw" -I"D:/project_in_git/CDC_ECM/src/src" -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"ecm_src/lwip-1.4.1/src/core/pbuf.d" -MT"$@" --specs=nano.specs -mfloat-abi=soft -mthumb -o "$@" +ecm_src/lwip-1.4.1/src/core/raw.o: D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/core/raw.c + arm-none-eabi-gcc "$<" -mcpu=cortex-m0 -std=gnu11 -g3 -DUSE_HAL_DRIVER -DSTM32F072xB -DDEBUG -c -I"D:/project_in_git/CDC_ECM/src/dns-server" -I../USB_DEVICE/Target -I../Drivers/STM32F0xx_HAL_Driver/Inc/Legacy -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4" -I"D:/project_in_git/CDC_ECM/src" -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Drivers/STM32F0xx_HAL_Driver/Inc -I../Drivers/CMSIS/Include -I"D:/project_in_git/CDC_ECM/src/dhcp-server" -I../Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -I../USB_DEVICE/App -I../Drivers/CMSIS/Device/ST/STM32F0xx/Include -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include" -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/apps/httpserver_raw" -I"D:/project_in_git/CDC_ECM/src/src" -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"ecm_src/lwip-1.4.1/src/core/raw.d" -MT"$@" --specs=nano.specs -mfloat-abi=soft -mthumb -o "$@" +ecm_src/lwip-1.4.1/src/core/stats.o: D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/core/stats.c + arm-none-eabi-gcc "$<" -mcpu=cortex-m0 -std=gnu11 -g3 -DUSE_HAL_DRIVER -DSTM32F072xB -DDEBUG -c -I"D:/project_in_git/CDC_ECM/src/dns-server" -I../USB_DEVICE/Target -I../Drivers/STM32F0xx_HAL_Driver/Inc/Legacy -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4" -I"D:/project_in_git/CDC_ECM/src" -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Drivers/STM32F0xx_HAL_Driver/Inc -I../Drivers/CMSIS/Include -I"D:/project_in_git/CDC_ECM/src/dhcp-server" -I../Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -I../USB_DEVICE/App -I../Drivers/CMSIS/Device/ST/STM32F0xx/Include -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include" -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/apps/httpserver_raw" -I"D:/project_in_git/CDC_ECM/src/src" -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"ecm_src/lwip-1.4.1/src/core/stats.d" -MT"$@" --specs=nano.specs -mfloat-abi=soft -mthumb -o "$@" +ecm_src/lwip-1.4.1/src/core/sys.o: D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/core/sys.c + arm-none-eabi-gcc "$<" -mcpu=cortex-m0 -std=gnu11 -g3 -DUSE_HAL_DRIVER -DSTM32F072xB -DDEBUG -c -I"D:/project_in_git/CDC_ECM/src/dns-server" -I../USB_DEVICE/Target -I../Drivers/STM32F0xx_HAL_Driver/Inc/Legacy -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4" -I"D:/project_in_git/CDC_ECM/src" -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Drivers/STM32F0xx_HAL_Driver/Inc -I../Drivers/CMSIS/Include -I"D:/project_in_git/CDC_ECM/src/dhcp-server" -I../Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -I../USB_DEVICE/App -I../Drivers/CMSIS/Device/ST/STM32F0xx/Include -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include" -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/apps/httpserver_raw" -I"D:/project_in_git/CDC_ECM/src/src" -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"ecm_src/lwip-1.4.1/src/core/sys.d" -MT"$@" --specs=nano.specs -mfloat-abi=soft -mthumb -o "$@" +ecm_src/lwip-1.4.1/src/core/tcp.o: D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/core/tcp.c + arm-none-eabi-gcc "$<" -mcpu=cortex-m0 -std=gnu11 -g3 -DUSE_HAL_DRIVER -DSTM32F072xB -DDEBUG -c -I"D:/project_in_git/CDC_ECM/src/dns-server" -I../USB_DEVICE/Target -I../Drivers/STM32F0xx_HAL_Driver/Inc/Legacy -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4" -I"D:/project_in_git/CDC_ECM/src" -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Drivers/STM32F0xx_HAL_Driver/Inc -I../Drivers/CMSIS/Include -I"D:/project_in_git/CDC_ECM/src/dhcp-server" -I../Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -I../USB_DEVICE/App -I../Drivers/CMSIS/Device/ST/STM32F0xx/Include -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include" -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/apps/httpserver_raw" -I"D:/project_in_git/CDC_ECM/src/src" -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"ecm_src/lwip-1.4.1/src/core/tcp.d" -MT"$@" --specs=nano.specs -mfloat-abi=soft -mthumb -o "$@" +ecm_src/lwip-1.4.1/src/core/tcp_in.o: D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/core/tcp_in.c + arm-none-eabi-gcc "$<" -mcpu=cortex-m0 -std=gnu11 -g3 -DUSE_HAL_DRIVER -DSTM32F072xB -DDEBUG -c -I"D:/project_in_git/CDC_ECM/src/dns-server" -I../USB_DEVICE/Target -I../Drivers/STM32F0xx_HAL_Driver/Inc/Legacy -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4" -I"D:/project_in_git/CDC_ECM/src" -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Drivers/STM32F0xx_HAL_Driver/Inc -I../Drivers/CMSIS/Include -I"D:/project_in_git/CDC_ECM/src/dhcp-server" -I../Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -I../USB_DEVICE/App -I../Drivers/CMSIS/Device/ST/STM32F0xx/Include -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include" -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/apps/httpserver_raw" -I"D:/project_in_git/CDC_ECM/src/src" -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"ecm_src/lwip-1.4.1/src/core/tcp_in.d" -MT"$@" --specs=nano.specs -mfloat-abi=soft -mthumb -o "$@" +ecm_src/lwip-1.4.1/src/core/tcp_out.o: D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/core/tcp_out.c + arm-none-eabi-gcc "$<" -mcpu=cortex-m0 -std=gnu11 -g3 -DUSE_HAL_DRIVER -DSTM32F072xB -DDEBUG -c -I"D:/project_in_git/CDC_ECM/src/dns-server" -I../USB_DEVICE/Target -I../Drivers/STM32F0xx_HAL_Driver/Inc/Legacy -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4" -I"D:/project_in_git/CDC_ECM/src" -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Drivers/STM32F0xx_HAL_Driver/Inc -I../Drivers/CMSIS/Include -I"D:/project_in_git/CDC_ECM/src/dhcp-server" -I../Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -I../USB_DEVICE/App -I../Drivers/CMSIS/Device/ST/STM32F0xx/Include -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include" -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/apps/httpserver_raw" -I"D:/project_in_git/CDC_ECM/src/src" -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"ecm_src/lwip-1.4.1/src/core/tcp_out.d" -MT"$@" --specs=nano.specs -mfloat-abi=soft -mthumb -o "$@" +ecm_src/lwip-1.4.1/src/core/timers.o: D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/core/timers.c + arm-none-eabi-gcc "$<" -mcpu=cortex-m0 -std=gnu11 -g3 -DUSE_HAL_DRIVER -DSTM32F072xB -DDEBUG -c -I"D:/project_in_git/CDC_ECM/src/dns-server" -I../USB_DEVICE/Target -I../Drivers/STM32F0xx_HAL_Driver/Inc/Legacy -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4" -I"D:/project_in_git/CDC_ECM/src" -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Drivers/STM32F0xx_HAL_Driver/Inc -I../Drivers/CMSIS/Include -I"D:/project_in_git/CDC_ECM/src/dhcp-server" -I../Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -I../USB_DEVICE/App -I../Drivers/CMSIS/Device/ST/STM32F0xx/Include -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include" -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/apps/httpserver_raw" -I"D:/project_in_git/CDC_ECM/src/src" -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"ecm_src/lwip-1.4.1/src/core/timers.d" -MT"$@" --specs=nano.specs -mfloat-abi=soft -mthumb -o "$@" +ecm_src/lwip-1.4.1/src/core/udp.o: D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/core/udp.c + arm-none-eabi-gcc "$<" -mcpu=cortex-m0 -std=gnu11 -g3 -DUSE_HAL_DRIVER -DSTM32F072xB -DDEBUG -c -I"D:/project_in_git/CDC_ECM/src/dns-server" -I../USB_DEVICE/Target -I../Drivers/STM32F0xx_HAL_Driver/Inc/Legacy -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4" -I"D:/project_in_git/CDC_ECM/src" -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Drivers/STM32F0xx_HAL_Driver/Inc -I../Drivers/CMSIS/Include -I"D:/project_in_git/CDC_ECM/src/dhcp-server" -I../Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -I../USB_DEVICE/App -I../Drivers/CMSIS/Device/ST/STM32F0xx/Include -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include" -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/apps/httpserver_raw" -I"D:/project_in_git/CDC_ECM/src/src" -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"ecm_src/lwip-1.4.1/src/core/udp.d" -MT"$@" --specs=nano.specs -mfloat-abi=soft -mthumb -o "$@" + diff --git a/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/sys.d b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/sys.d new file mode 100644 index 0000000..3ef0fd0 --- /dev/null +++ b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/sys.d @@ -0,0 +1,23 @@ +ecm_src/lwip-1.4.1/src/core/sys.o: \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/core/sys.c \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/opt.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwipopts.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/debug.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/arch.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cc.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cpu.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/sys.h + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/opt.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwipopts.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/debug.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/arch.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cc.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cpu.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/sys.h: diff --git a/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/sys.o b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/sys.o new file mode 100644 index 0000000..ced218d Binary files /dev/null and b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/sys.o differ diff --git a/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/sys.su b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/sys.su new file mode 100644 index 0000000..e69de29 diff --git a/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/tcp.d b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/tcp.d new file mode 100644 index 0000000..dd2cb58 --- /dev/null +++ b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/tcp.d @@ -0,0 +1,62 @@ +ecm_src/lwip-1.4.1/src/core/tcp.o: \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/core/tcp.c \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/opt.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwipopts.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/debug.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/arch.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cc.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cpu.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/def.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/mem.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/memp.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/memp_std.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/snmp.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/ip_addr.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/tcp.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/pbuf.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/err.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/ip.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/netif.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/icmp.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/tcp_impl.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/stats.h + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/opt.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwipopts.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/debug.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/arch.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cc.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cpu.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/def.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/mem.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/memp.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/memp_std.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/snmp.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/ip_addr.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/tcp.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/pbuf.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/err.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/ip.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/netif.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/icmp.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/tcp_impl.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/stats.h: diff --git a/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/tcp.o b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/tcp.o new file mode 100644 index 0000000..cf90f0f Binary files /dev/null and b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/tcp.o differ diff --git a/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/tcp.su b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/tcp.su new file mode 100644 index 0000000..7249da6 --- /dev/null +++ b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/tcp.su @@ -0,0 +1,37 @@ +tcp.c:130:1:tcp_init 8 static +tcp.c:141:1:tcp_tmr 8 static +tcp.c:170:1:tcp_close_shutdown 40 static +tcp.c:285:1:tcp_close 16 static +tcp.c:313:1:tcp_shutdown 24 static +tcp.c:357:1:tcp_abandon 48 static +tcp.c:413:1:tcp_abort 16 static +tcp.c:433:1:tcp_bind 48 static +tcp.c:494:1:tcp_accept_null 24 static +tcp.c:519:1:tcp_listen_with_backlog 24 static +tcp.c:579:7:tcp_update_rcv_ann_wnd 24 static +tcp.c:611:1:tcp_recved 24 static +tcp.c:647:1:tcp_new_port 16 static +tcp.c:684:1:tcp_connect 48 static +tcp.c:788:1:tcp_slowtmr 56 static +tcp.c:1046:1:tcp_fasttmr 16 static +tcp.c:1085:1:tcp_process_refused_data 32 static +tcp.c:1128:1:tcp_segs_free 24 static +tcp.c:1143:1:tcp_seg_free 16 static +tcp.c:1163:1:tcp_setprio 16 static +tcp.c:1177:1:tcp_seg_copy 24 static +tcp.c:1197:1:tcp_recv_null 24 static +tcp.c:1217:1:tcp_kill_prio 32 static +tcp.c:1250:1:tcp_kill_timewait 24 static +tcp.c:1278:1:tcp_alloc 24 static +tcp.c:1363:1:tcp_new 8 static +tcp.c:1376:1:tcp_arg 16 static +tcp.c:1392:1:tcp_recv 16 static +tcp.c:1406:1:tcp_sent 16 static +tcp.c:1421:1:tcp_err 16 static +tcp.c:1436:1:tcp_accept 16 static +tcp.c:1452:1:tcp_poll 24 static +tcp.c:1470:1:tcp_pcb_purge 16 static +tcp.c:1538:1:tcp_pcb_remove 16 static +tcp.c:1571:1:tcp_next_iss 8 static +tcp.c:1586:1:tcp_eff_send_mss 32 static +tcp.c:1605:1:tcp_debug_state_str 16 static diff --git a/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/tcp_in.d b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/tcp_in.d new file mode 100644 index 0000000..fa804df --- /dev/null +++ b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/tcp_in.d @@ -0,0 +1,68 @@ +ecm_src/lwip-1.4.1/src/core/tcp_in.o: \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/core/tcp_in.c \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/opt.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwipopts.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/debug.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/arch.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cc.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cpu.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/tcp_impl.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/tcp.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/mem.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/pbuf.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/err.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/ip.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/def.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/ip_addr.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/netif.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/icmp.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/memp.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/memp_std.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/inet_chksum.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/stats.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/snmp.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/perf.h + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/opt.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwipopts.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/debug.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/arch.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cc.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cpu.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/tcp_impl.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/tcp.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/mem.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/pbuf.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/err.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/ip.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/def.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/ip_addr.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/netif.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/icmp.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/memp.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/memp_std.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/inet_chksum.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/stats.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/snmp.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/perf.h: diff --git a/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/tcp_in.o b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/tcp_in.o new file mode 100644 index 0000000..069b60e Binary files /dev/null and b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/tcp_in.o differ diff --git a/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/tcp_in.su b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/tcp_in.su new file mode 100644 index 0000000..639f7db --- /dev/null +++ b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/tcp_in.su @@ -0,0 +1,7 @@ +tcp_in.c:92:1:tcp_input 48 static +tcp_in.c:440:1:tcp_listen_input 40 static +tcp_in.c:529:1:tcp_timewait_input 32 static +tcp_in.c:575:1:tcp_process 40 static +tcp_in.c:800:1:tcp_oos_insert_segment 32 static +tcp_in.c:847:1:tcp_receive 72 static +tcp_in.c:1542:1:tcp_parseopt 32 static diff --git a/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/tcp_out.d b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/tcp_out.d new file mode 100644 index 0000000..f4720c9 --- /dev/null +++ b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/tcp_out.d @@ -0,0 +1,65 @@ +ecm_src/lwip-1.4.1/src/core/tcp_out.o: \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/core/tcp_out.c \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/opt.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwipopts.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/debug.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/arch.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cc.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cpu.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/tcp_impl.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/tcp.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/mem.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/pbuf.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/err.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/ip.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/def.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/ip_addr.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/netif.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/icmp.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/memp.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/memp_std.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/inet_chksum.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/stats.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/snmp.h + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/opt.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwipopts.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/debug.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/arch.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cc.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cpu.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/tcp_impl.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/tcp.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/mem.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/pbuf.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/err.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/ip.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/def.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/ip_addr.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/netif.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/icmp.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/memp.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/memp_std.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/inet_chksum.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/stats.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/snmp.h: diff --git a/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/tcp_out.o b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/tcp_out.o new file mode 100644 index 0000000..66bd127 Binary files /dev/null and b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/tcp_out.o differ diff --git a/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/tcp_out.su b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/tcp_out.su new file mode 100644 index 0000000..10e9832 --- /dev/null +++ b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/tcp_out.su @@ -0,0 +1,16 @@ +tcp_out.c:94:1:tcp_output_alloc_header 40 static +tcp_out.c:125:1:tcp_send_fin 32 static +tcp_out.c:159:1:tcp_create_segment 40 static +tcp_out.c:219:1:tcp_pbuf_prealloc 40 static +tcp_out.c:294:1:tcp_write_checks 16 static +tcp_out.c:354:1:tcp_write 112 static +tcp_out.c:722:1:tcp_enqueue_flags 56 static +tcp_out.c:842:1:tcp_send_empty_ack 48 static +tcp_out.c:898:1:tcp_output 48 static +tcp_out.c:1049:1:tcp_output_segment 48 static +tcp_out.c:1195:1:tcp_rst 48 static +tcp_out.c:1239:1:tcp_rexmit_rto 24 static +tcp_out.c:1275:1:tcp_rexmit 32 static +tcp_out.c:1321:1:tcp_rexmit_fast 16 static +tcp_out.c:1364:1:tcp_keepalive 40 static +tcp_out.c:1414:1:tcp_zero_window_probe 56 static diff --git a/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/timers.d b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/timers.d new file mode 100644 index 0000000..64f381b --- /dev/null +++ b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/timers.d @@ -0,0 +1,83 @@ +ecm_src/lwip-1.4.1/src/core/timers.o: \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/core/timers.c \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/opt.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwipopts.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/debug.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/arch.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cc.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cpu.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/timers.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/err.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/tcp_impl.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/tcp.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/mem.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/pbuf.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/ip.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/def.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/ip_addr.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/netif.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/icmp.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/memp.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/memp_std.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/tcpip.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/ip_frag.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/netif/etharp.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/dhcp.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/autoip.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/igmp.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/dns.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/sys.h + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/opt.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwipopts.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/debug.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/arch.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cc.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cpu.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/timers.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/err.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/tcp_impl.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/tcp.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/mem.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/pbuf.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/ip.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/def.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/ip_addr.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/netif.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/icmp.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/memp.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/memp_std.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/tcpip.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/ip_frag.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/netif/etharp.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/dhcp.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/autoip.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/igmp.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/dns.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/sys.h: diff --git a/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/timers.o b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/timers.o new file mode 100644 index 0000000..72891ca Binary files /dev/null and b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/timers.o differ diff --git a/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/timers.su b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/timers.su new file mode 100644 index 0000000..24918b9 --- /dev/null +++ b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/timers.su @@ -0,0 +1,9 @@ +timers.c:79:1:tcpip_tcp_timer 16 static +timers.c:101:1:tcp_timer_needed 8 static +timers.c:119:1:ip_reass_timer 16 static +timers.c:135:1:arp_timer 16 static +timers.c:223:6:sys_timeouts_init 8 static +timers.c:266:1:sys_timeout 32 static +timers.c:321:1:sys_untimeout 24 static +timers.c:358:1:sys_check_timeouts 32 static +timers.c:408:1:sys_restart_timeouts 8 static diff --git a/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/udp.d b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/udp.d new file mode 100644 index 0000000..5a61d0b --- /dev/null +++ b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/udp.d @@ -0,0 +1,68 @@ +ecm_src/lwip-1.4.1/src/core/udp.o: \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/core/udp.c \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/opt.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwipopts.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/debug.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/arch.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cc.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cpu.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/udp.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/pbuf.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/err.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/netif.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/ip_addr.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/def.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/ip.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/memp.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/memp_std.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/inet_chksum.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/icmp.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/stats.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/mem.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/snmp.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/perf.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/dhcp.h + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/opt.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwipopts.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/debug.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/arch.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cc.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cpu.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/udp.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/pbuf.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/err.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/netif.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/ip_addr.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/def.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/ip.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/memp.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/memp_std.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/inet_chksum.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/icmp.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/stats.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/mem.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/snmp.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/perf.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/dhcp.h: diff --git a/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/udp.o b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/udp.o new file mode 100644 index 0000000..426b132 Binary files /dev/null and b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/udp.o differ diff --git a/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/udp.su b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/udp.su new file mode 100644 index 0000000..4bda437 --- /dev/null +++ b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/core/udp.su @@ -0,0 +1,12 @@ +udp.c:86:1:udp_init 8 static +udp.c:99:1:udp_new_port 16 static +udp.c:151:1:udp_input 64 static +udp.c:454:1:udp_send 16 static +udp.c:491:1:udp_sendto 48 static +udp.c:549:1:udp_sendto_if 72 static +udp.c:766:1:udp_bind 40 static +udp.c:853:1:udp_connect 40 static +udp.c:911:1:udp_disconnect 16 static +udp.c:930:1:udp_recv 24 static +udp.c:946:1:udp_remove 24 static +udp.c:977:1:udp_new 16 static diff --git a/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/netif/etharp.d b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/netif/etharp.d new file mode 100644 index 0000000..9cd36d8 --- /dev/null +++ b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/netif/etharp.d @@ -0,0 +1,62 @@ +ecm_src/lwip-1.4.1/src/netif/etharp.o: \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/netif/etharp.c \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/opt.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwipopts.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/debug.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/arch.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cc.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cpu.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/ip_addr.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/def.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/ip.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/pbuf.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/err.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/netif.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/stats.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/mem.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/memp.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/memp_std.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/snmp.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/dhcp.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/autoip.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/netif/etharp.h + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/opt.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwipopts.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/debug.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/arch.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cc.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cpu.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/ip_addr.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/def.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/ip.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/pbuf.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/err.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/netif.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/stats.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/mem.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/memp.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/memp_std.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/snmp.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/dhcp.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/autoip.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/netif/etharp.h: diff --git a/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/netif/etharp.o b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/netif/etharp.o new file mode 100644 index 0000000..9382b84 Binary files /dev/null and b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/netif/etharp.o differ diff --git a/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/netif/etharp.su b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/netif/etharp.su new file mode 100644 index 0000000..e6ac178 --- /dev/null +++ b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/netif/etharp.su @@ -0,0 +1,16 @@ +etharp.c:177:1:etharp_free_entry 16 static +etharp.c:206:1:etharp_tmr 16 static +etharp.c:266:1:etharp_find_entry 32 static +etharp.c:415:1:etharp_send_ip 32 static +etharp.c:448:1:etharp_update_arp_entry 40 static +etharp.c:526:1:etharp_add_static_entry 24 static +etharp.c:551:1:etharp_remove_static_entry 32 static +etharp.c:579:6:etharp_cleanup_netif 32 static +etharp.c:603:1:etharp_find_addr 40 static +etharp.c:688:1:etharp_arp_input 56 static +etharp.c:842:1:etharp_output_to_arp_index 32 static +etharp.c:879:1:etharp_output 40 static +etharp.c:1016:1:etharp_query 56 static +etharp.c:1175:1:etharp_raw 48 static +etharp.c:1259:1:etharp_request 40 static +etharp.c:1277:1:ethernet_input 32 static diff --git a/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/netif/ethernetif.d b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/netif/ethernetif.d new file mode 100644 index 0000000..aaad379 --- /dev/null +++ b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/netif/ethernetif.d @@ -0,0 +1,20 @@ +ecm_src/lwip-1.4.1/src/netif/ethernetif.o: \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/netif/ethernetif.c \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/opt.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwipopts.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/debug.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/arch.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cc.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cpu.h + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/opt.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwipopts.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/debug.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/arch.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cc.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cpu.h: diff --git a/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/netif/ethernetif.o b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/netif/ethernetif.o new file mode 100644 index 0000000..2a9653d Binary files /dev/null and b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/netif/ethernetif.o differ diff --git a/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/netif/ethernetif.su b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/netif/ethernetif.su new file mode 100644 index 0000000..e69de29 diff --git a/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/netif/subdir.mk b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/netif/subdir.mk new file mode 100644 index 0000000..e2119d6 --- /dev/null +++ b/test/STM32F072C8T6/Debug/ecm_src/lwip-1.4.1/src/netif/subdir.mk @@ -0,0 +1,24 @@ +################################################################################ +# Automatically-generated file. Do not edit! +################################################################################ + +# Add inputs and outputs from these tool invocations to the build variables +C_SRCS += \ +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/netif/etharp.c \ +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/netif/ethernetif.c + +OBJS += \ +./ecm_src/lwip-1.4.1/src/netif/etharp.o \ +./ecm_src/lwip-1.4.1/src/netif/ethernetif.o + +C_DEPS += \ +./ecm_src/lwip-1.4.1/src/netif/etharp.d \ +./ecm_src/lwip-1.4.1/src/netif/ethernetif.d + + +# Each subdirectory must supply rules for building sources it contributes +ecm_src/lwip-1.4.1/src/netif/etharp.o: D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/netif/etharp.c + arm-none-eabi-gcc "$<" -mcpu=cortex-m0 -std=gnu11 -g3 -DUSE_HAL_DRIVER -DSTM32F072xB -DDEBUG -c -I"D:/project_in_git/CDC_ECM/src/dns-server" -I../USB_DEVICE/Target -I../Drivers/STM32F0xx_HAL_Driver/Inc/Legacy -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4" -I"D:/project_in_git/CDC_ECM/src" -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Drivers/STM32F0xx_HAL_Driver/Inc -I../Drivers/CMSIS/Include -I"D:/project_in_git/CDC_ECM/src/dhcp-server" -I../Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -I../USB_DEVICE/App -I../Drivers/CMSIS/Device/ST/STM32F0xx/Include -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include" -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/apps/httpserver_raw" -I"D:/project_in_git/CDC_ECM/src/src" -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"ecm_src/lwip-1.4.1/src/netif/etharp.d" -MT"$@" --specs=nano.specs -mfloat-abi=soft -mthumb -o "$@" +ecm_src/lwip-1.4.1/src/netif/ethernetif.o: D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/netif/ethernetif.c + arm-none-eabi-gcc "$<" -mcpu=cortex-m0 -std=gnu11 -g3 -DUSE_HAL_DRIVER -DSTM32F072xB -DDEBUG -c -I"D:/project_in_git/CDC_ECM/src/dns-server" -I../USB_DEVICE/Target -I../Drivers/STM32F0xx_HAL_Driver/Inc/Legacy -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4" -I"D:/project_in_git/CDC_ECM/src" -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Drivers/STM32F0xx_HAL_Driver/Inc -I../Drivers/CMSIS/Include -I"D:/project_in_git/CDC_ECM/src/dhcp-server" -I../Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -I../USB_DEVICE/App -I../Drivers/CMSIS/Device/ST/STM32F0xx/Include -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include" -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/apps/httpserver_raw" -I"D:/project_in_git/CDC_ECM/src/src" -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"ecm_src/lwip-1.4.1/src/netif/ethernetif.d" -MT"$@" --specs=nano.specs -mfloat-abi=soft -mthumb -o "$@" + diff --git a/test/STM32F072C8T6/Debug/ecm_src/src/ecm_main.d b/test/STM32F072C8T6/Debug/ecm_src/src/ecm_main.d new file mode 100644 index 0000000..7f28de9 --- /dev/null +++ b/test/STM32F072C8T6/Debug/ecm_src/src/ecm_main.d @@ -0,0 +1,195 @@ +ecm_src/src/ecm_main.o: D:/project_in_git/CDC_ECM/src/src/ecm_main.c \ + D:/project_in_git/CDC_ECM/src/src/usb_device.h \ + ../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f0xx.h \ + ../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f072xb.h \ + ../Drivers/CMSIS/Include/core_cm0.h \ + ../Drivers/CMSIS/Include/cmsis_version.h \ + ../Drivers/CMSIS/Include/cmsis_compiler.h \ + ../Drivers/CMSIS/Include/cmsis_gcc.h \ + ../Drivers/CMSIS/Device/ST/STM32F0xx/Include/system_stm32f0xx.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal.h \ + ../Core/Inc/stm32f0xx_hal_conf.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_def.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_exti.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_cortex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_usb.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr_ex.h \ + D:/project_in_git/CDC_ECM/src/src/usbd_def.h \ + D:/project_in_git/CDC_ECM/src/src/usbd_conf.h ../Core/Inc/main.h \ + D:/project_in_git/CDC_ECM/src/src/usbd_ecm.h \ + D:/project_in_git/CDC_ECM/src/src/usbd_ioreq.h \ + D:/project_in_git/CDC_ECM/src/src/usbd_core.h \ + D:/project_in_git/CDC_ECM/src/src/usbd_ctlreq.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/netif/etharp.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/opt.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwipopts.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/debug.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/arch.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cc.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cpu.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/pbuf.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/err.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/ip_addr.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/def.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/netif.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/ip.h \ + D:/project_in_git/CDC_ECM/src/src/ecmhelper.h \ + D:/project_in_git/CDC_ECM/src/src/usbhelper.h \ + D:/project_in_git/CDC_ECM/src/src/usbd_desc.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/init.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/icmp.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/udp.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/api.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/inet.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/dns.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/tcp_impl.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/tcp.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/mem.h \ + D:/project_in_git/CDC_ECM/src/src/time.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/apps/httpserver_raw/httpd.h \ + D:/project_in_git/CDC_ECM/src/dhcp-server/dhserver.h \ + D:/project_in_git/CDC_ECM/src/dns-server/dnserver.h \ + D:/project_in_git/CDC_ECM/src/src/ecm_main.h + +D:/project_in_git/CDC_ECM/src/src/usb_device.h: + +../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f0xx.h: + +../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f072xb.h: + +../Drivers/CMSIS/Include/core_cm0.h: + +../Drivers/CMSIS/Include/cmsis_version.h: + +../Drivers/CMSIS/Include/cmsis_compiler.h: + +../Drivers/CMSIS/Include/cmsis_gcc.h: + +../Drivers/CMSIS/Device/ST/STM32F0xx/Include/system_stm32f0xx.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal.h: + +../Core/Inc/stm32f0xx_hal_conf.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_def.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_exti.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_cortex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_usb.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr_ex.h: + +D:/project_in_git/CDC_ECM/src/src/usbd_def.h: + +D:/project_in_git/CDC_ECM/src/src/usbd_conf.h: + +../Core/Inc/main.h: + +D:/project_in_git/CDC_ECM/src/src/usbd_ecm.h: + +D:/project_in_git/CDC_ECM/src/src/usbd_ioreq.h: + +D:/project_in_git/CDC_ECM/src/src/usbd_core.h: + +D:/project_in_git/CDC_ECM/src/src/usbd_ctlreq.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/netif/etharp.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/opt.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwipopts.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/debug.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/arch.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cc.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cpu.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/pbuf.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/err.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/ip_addr.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/def.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/netif.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/ip.h: + +D:/project_in_git/CDC_ECM/src/src/ecmhelper.h: + +D:/project_in_git/CDC_ECM/src/src/usbhelper.h: + +D:/project_in_git/CDC_ECM/src/src/usbd_desc.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/init.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/icmp.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/udp.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/api.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/inet.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/dns.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/tcp_impl.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/tcp.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/mem.h: + +D:/project_in_git/CDC_ECM/src/src/time.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/apps/httpserver_raw/httpd.h: + +D:/project_in_git/CDC_ECM/src/dhcp-server/dhserver.h: + +D:/project_in_git/CDC_ECM/src/dns-server/dnserver.h: + +D:/project_in_git/CDC_ECM/src/src/ecm_main.h: diff --git a/test/STM32F072C8T6/Debug/ecm_src/src/ecm_main.o b/test/STM32F072C8T6/Debug/ecm_src/src/ecm_main.o new file mode 100644 index 0000000..f7af34a Binary files /dev/null and b/test/STM32F072C8T6/Debug/ecm_src/src/ecm_main.o differ diff --git a/test/STM32F072C8T6/Debug/ecm_src/src/ecm_main.su b/test/STM32F072C8T6/Debug/ecm_src/src/ecm_main.su new file mode 100644 index 0000000..edf0cc6 --- /dev/null +++ b/test/STM32F072C8T6/Debug/ecm_src/src/ecm_main.su @@ -0,0 +1,11 @@ +ecm_main.c:27:6:usb_ecm_recv_callback 16 static +ecm_main.c:43:10:sys_now 8 static +ecm_main.c:48:1:tcp_timer_proc 16 static +ecm_main.c:53:7:output_fn 24 static +ecm_main.c:58:7:linkoutput_fn 24 static +ecm_main.c:72:7:netif_init_cb 16 static +ecm_main.c:87:13:init_lwip 40 static +ecm_main.c:102:6:dns_query_proc 16 static +ecm_main.c:181:13:service_traffic 16 static,ignoring_inline_asm +ecm_main.c:202:6:ecm_main_init 8 static +ecm_main.c:218:6:ecm_main_loop 8 static diff --git a/test/STM32F072C8T6/Debug/ecm_src/src/subdir.mk b/test/STM32F072C8T6/Debug/ecm_src/src/subdir.mk new file mode 100644 index 0000000..32bdacb --- /dev/null +++ b/test/STM32F072C8T6/Debug/ecm_src/src/subdir.mk @@ -0,0 +1,59 @@ +################################################################################ +# Automatically-generated file. Do not edit! +################################################################################ + +# Add inputs and outputs from these tool invocations to the build variables +C_SRCS += \ +D:/project_in_git/CDC_ECM/src/src/ecm_main.c \ +D:/project_in_git/CDC_ECM/src/src/time.c \ +D:/project_in_git/CDC_ECM/src/src/usb_device.c \ +D:/project_in_git/CDC_ECM/src/src/usbd_conf.c \ +D:/project_in_git/CDC_ECM/src/src/usbd_core.c \ +D:/project_in_git/CDC_ECM/src/src/usbd_ctlreq.c \ +D:/project_in_git/CDC_ECM/src/src/usbd_desc.c \ +D:/project_in_git/CDC_ECM/src/src/usbd_ecm.c \ +D:/project_in_git/CDC_ECM/src/src/usbd_ioreq.c + +OBJS += \ +./ecm_src/src/ecm_main.o \ +./ecm_src/src/time.o \ +./ecm_src/src/usb_device.o \ +./ecm_src/src/usbd_conf.o \ +./ecm_src/src/usbd_core.o \ +./ecm_src/src/usbd_ctlreq.o \ +./ecm_src/src/usbd_desc.o \ +./ecm_src/src/usbd_ecm.o \ +./ecm_src/src/usbd_ioreq.o + +C_DEPS += \ +./ecm_src/src/ecm_main.d \ +./ecm_src/src/time.d \ +./ecm_src/src/usb_device.d \ +./ecm_src/src/usbd_conf.d \ +./ecm_src/src/usbd_core.d \ +./ecm_src/src/usbd_ctlreq.d \ +./ecm_src/src/usbd_desc.d \ +./ecm_src/src/usbd_ecm.d \ +./ecm_src/src/usbd_ioreq.d + + +# Each subdirectory must supply rules for building sources it contributes +ecm_src/src/ecm_main.o: D:/project_in_git/CDC_ECM/src/src/ecm_main.c + arm-none-eabi-gcc "$<" -mcpu=cortex-m0 -std=gnu11 -g3 -DUSE_HAL_DRIVER -DSTM32F072xB -DDEBUG -c -I"D:/project_in_git/CDC_ECM/src/dns-server" -I../USB_DEVICE/Target -I../Drivers/STM32F0xx_HAL_Driver/Inc/Legacy -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4" -I"D:/project_in_git/CDC_ECM/src" -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Drivers/STM32F0xx_HAL_Driver/Inc -I../Drivers/CMSIS/Include -I"D:/project_in_git/CDC_ECM/src/dhcp-server" -I../Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -I../USB_DEVICE/App -I../Drivers/CMSIS/Device/ST/STM32F0xx/Include -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include" -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/apps/httpserver_raw" -I"D:/project_in_git/CDC_ECM/src/src" -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"ecm_src/src/ecm_main.d" -MT"$@" --specs=nano.specs -mfloat-abi=soft -mthumb -o "$@" +ecm_src/src/time.o: D:/project_in_git/CDC_ECM/src/src/time.c + arm-none-eabi-gcc "$<" -mcpu=cortex-m0 -std=gnu11 -g3 -DUSE_HAL_DRIVER -DSTM32F072xB -DDEBUG -c -I"D:/project_in_git/CDC_ECM/src/dns-server" -I../USB_DEVICE/Target -I../Drivers/STM32F0xx_HAL_Driver/Inc/Legacy -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4" -I"D:/project_in_git/CDC_ECM/src" -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Drivers/STM32F0xx_HAL_Driver/Inc -I../Drivers/CMSIS/Include -I"D:/project_in_git/CDC_ECM/src/dhcp-server" -I../Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -I../USB_DEVICE/App -I../Drivers/CMSIS/Device/ST/STM32F0xx/Include -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include" -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/apps/httpserver_raw" -I"D:/project_in_git/CDC_ECM/src/src" -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"ecm_src/src/time.d" -MT"$@" --specs=nano.specs -mfloat-abi=soft -mthumb -o "$@" +ecm_src/src/usb_device.o: D:/project_in_git/CDC_ECM/src/src/usb_device.c + arm-none-eabi-gcc "$<" -mcpu=cortex-m0 -std=gnu11 -g3 -DUSE_HAL_DRIVER -DSTM32F072xB -DDEBUG -c -I"D:/project_in_git/CDC_ECM/src/dns-server" -I../USB_DEVICE/Target -I../Drivers/STM32F0xx_HAL_Driver/Inc/Legacy -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4" -I"D:/project_in_git/CDC_ECM/src" -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Drivers/STM32F0xx_HAL_Driver/Inc -I../Drivers/CMSIS/Include -I"D:/project_in_git/CDC_ECM/src/dhcp-server" -I../Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -I../USB_DEVICE/App -I../Drivers/CMSIS/Device/ST/STM32F0xx/Include -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include" -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/apps/httpserver_raw" -I"D:/project_in_git/CDC_ECM/src/src" -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"ecm_src/src/usb_device.d" -MT"$@" --specs=nano.specs -mfloat-abi=soft -mthumb -o "$@" +ecm_src/src/usbd_conf.o: D:/project_in_git/CDC_ECM/src/src/usbd_conf.c + arm-none-eabi-gcc "$<" -mcpu=cortex-m0 -std=gnu11 -g3 -DUSE_HAL_DRIVER -DSTM32F072xB -DDEBUG -c -I"D:/project_in_git/CDC_ECM/src/dns-server" -I../USB_DEVICE/Target -I../Drivers/STM32F0xx_HAL_Driver/Inc/Legacy -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4" -I"D:/project_in_git/CDC_ECM/src" -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Drivers/STM32F0xx_HAL_Driver/Inc -I../Drivers/CMSIS/Include -I"D:/project_in_git/CDC_ECM/src/dhcp-server" -I../Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -I../USB_DEVICE/App -I../Drivers/CMSIS/Device/ST/STM32F0xx/Include -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include" -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/apps/httpserver_raw" -I"D:/project_in_git/CDC_ECM/src/src" -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"ecm_src/src/usbd_conf.d" -MT"$@" --specs=nano.specs -mfloat-abi=soft -mthumb -o "$@" +ecm_src/src/usbd_core.o: D:/project_in_git/CDC_ECM/src/src/usbd_core.c + arm-none-eabi-gcc "$<" -mcpu=cortex-m0 -std=gnu11 -g3 -DUSE_HAL_DRIVER -DSTM32F072xB -DDEBUG -c -I"D:/project_in_git/CDC_ECM/src/dns-server" -I../USB_DEVICE/Target -I../Drivers/STM32F0xx_HAL_Driver/Inc/Legacy -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4" -I"D:/project_in_git/CDC_ECM/src" -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Drivers/STM32F0xx_HAL_Driver/Inc -I../Drivers/CMSIS/Include -I"D:/project_in_git/CDC_ECM/src/dhcp-server" -I../Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -I../USB_DEVICE/App -I../Drivers/CMSIS/Device/ST/STM32F0xx/Include -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include" -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/apps/httpserver_raw" -I"D:/project_in_git/CDC_ECM/src/src" -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"ecm_src/src/usbd_core.d" -MT"$@" --specs=nano.specs -mfloat-abi=soft -mthumb -o "$@" +ecm_src/src/usbd_ctlreq.o: D:/project_in_git/CDC_ECM/src/src/usbd_ctlreq.c + arm-none-eabi-gcc "$<" -mcpu=cortex-m0 -std=gnu11 -g3 -DUSE_HAL_DRIVER -DSTM32F072xB -DDEBUG -c -I"D:/project_in_git/CDC_ECM/src/dns-server" -I../USB_DEVICE/Target -I../Drivers/STM32F0xx_HAL_Driver/Inc/Legacy -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4" -I"D:/project_in_git/CDC_ECM/src" -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Drivers/STM32F0xx_HAL_Driver/Inc -I../Drivers/CMSIS/Include -I"D:/project_in_git/CDC_ECM/src/dhcp-server" -I../Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -I../USB_DEVICE/App -I../Drivers/CMSIS/Device/ST/STM32F0xx/Include -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include" -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/apps/httpserver_raw" -I"D:/project_in_git/CDC_ECM/src/src" -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"ecm_src/src/usbd_ctlreq.d" -MT"$@" --specs=nano.specs -mfloat-abi=soft -mthumb -o "$@" +ecm_src/src/usbd_desc.o: D:/project_in_git/CDC_ECM/src/src/usbd_desc.c + arm-none-eabi-gcc "$<" -mcpu=cortex-m0 -std=gnu11 -g3 -DUSE_HAL_DRIVER -DSTM32F072xB -DDEBUG -c -I"D:/project_in_git/CDC_ECM/src/dns-server" -I../USB_DEVICE/Target -I../Drivers/STM32F0xx_HAL_Driver/Inc/Legacy -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4" -I"D:/project_in_git/CDC_ECM/src" -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Drivers/STM32F0xx_HAL_Driver/Inc -I../Drivers/CMSIS/Include -I"D:/project_in_git/CDC_ECM/src/dhcp-server" -I../Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -I../USB_DEVICE/App -I../Drivers/CMSIS/Device/ST/STM32F0xx/Include -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include" -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/apps/httpserver_raw" -I"D:/project_in_git/CDC_ECM/src/src" -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"ecm_src/src/usbd_desc.d" -MT"$@" --specs=nano.specs -mfloat-abi=soft -mthumb -o "$@" +ecm_src/src/usbd_ecm.o: D:/project_in_git/CDC_ECM/src/src/usbd_ecm.c + arm-none-eabi-gcc "$<" -mcpu=cortex-m0 -std=gnu11 -g3 -DUSE_HAL_DRIVER -DSTM32F072xB -DDEBUG -c -I"D:/project_in_git/CDC_ECM/src/dns-server" -I../USB_DEVICE/Target -I../Drivers/STM32F0xx_HAL_Driver/Inc/Legacy -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4" -I"D:/project_in_git/CDC_ECM/src" -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Drivers/STM32F0xx_HAL_Driver/Inc -I../Drivers/CMSIS/Include -I"D:/project_in_git/CDC_ECM/src/dhcp-server" -I../Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -I../USB_DEVICE/App -I../Drivers/CMSIS/Device/ST/STM32F0xx/Include -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include" -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/apps/httpserver_raw" -I"D:/project_in_git/CDC_ECM/src/src" -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"ecm_src/src/usbd_ecm.d" -MT"$@" --specs=nano.specs -mfloat-abi=soft -mthumb -o "$@" +ecm_src/src/usbd_ioreq.o: D:/project_in_git/CDC_ECM/src/src/usbd_ioreq.c + arm-none-eabi-gcc "$<" -mcpu=cortex-m0 -std=gnu11 -g3 -DUSE_HAL_DRIVER -DSTM32F072xB -DDEBUG -c -I"D:/project_in_git/CDC_ECM/src/dns-server" -I../USB_DEVICE/Target -I../Drivers/STM32F0xx_HAL_Driver/Inc/Legacy -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4" -I"D:/project_in_git/CDC_ECM/src" -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -I../Drivers/STM32F0xx_HAL_Driver/Inc -I../Drivers/CMSIS/Include -I"D:/project_in_git/CDC_ECM/src/dhcp-server" -I../Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -I../USB_DEVICE/App -I../Drivers/CMSIS/Device/ST/STM32F0xx/Include -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include" -I"D:/project_in_git/CDC_ECM/src/lwip-1.4.1/apps/httpserver_raw" -I"D:/project_in_git/CDC_ECM/src/src" -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"ecm_src/src/usbd_ioreq.d" -MT"$@" --specs=nano.specs -mfloat-abi=soft -mthumb -o "$@" + diff --git a/test/STM32F072C8T6/Debug/ecm_src/src/time.d b/test/STM32F072C8T6/Debug/ecm_src/src/time.d new file mode 100644 index 0000000..b63e4fa --- /dev/null +++ b/test/STM32F072C8T6/Debug/ecm_src/src/time.d @@ -0,0 +1,85 @@ +ecm_src/src/time.o: D:/project_in_git/CDC_ECM/src/src/time.c \ + D:/project_in_git/CDC_ECM/src/src/time.h \ + ../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f0xx.h \ + ../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f072xb.h \ + ../Drivers/CMSIS/Include/core_cm0.h \ + ../Drivers/CMSIS/Include/cmsis_version.h \ + ../Drivers/CMSIS/Include/cmsis_compiler.h \ + ../Drivers/CMSIS/Include/cmsis_gcc.h \ + ../Drivers/CMSIS/Device/ST/STM32F0xx/Include/system_stm32f0xx.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal.h \ + ../Core/Inc/stm32f0xx_hal_conf.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_def.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_exti.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_cortex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_usb.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr_ex.h + +D:/project_in_git/CDC_ECM/src/src/time.h: + +../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f0xx.h: + +../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f072xb.h: + +../Drivers/CMSIS/Include/core_cm0.h: + +../Drivers/CMSIS/Include/cmsis_version.h: + +../Drivers/CMSIS/Include/cmsis_compiler.h: + +../Drivers/CMSIS/Include/cmsis_gcc.h: + +../Drivers/CMSIS/Device/ST/STM32F0xx/Include/system_stm32f0xx.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal.h: + +../Core/Inc/stm32f0xx_hal_conf.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_def.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_exti.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_cortex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_usb.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr_ex.h: diff --git a/test/STM32F072C8T6/Debug/ecm_src/src/time.o b/test/STM32F072C8T6/Debug/ecm_src/src/time.o new file mode 100644 index 0000000..13ac3b3 Binary files /dev/null and b/test/STM32F072C8T6/Debug/ecm_src/src/time.o differ diff --git a/test/STM32F072C8T6/Debug/ecm_src/src/time.su b/test/STM32F072C8T6/Debug/ecm_src/src/time.su new file mode 100644 index 0000000..8da1b3f --- /dev/null +++ b/test/STM32F072C8T6/Debug/ecm_src/src/time.su @@ -0,0 +1,9 @@ +time.c:34:6:time_init 8 static +time.c:48:10:mtime 8 static +time.c:67:6:msleep 24 static +time.c:80:6:stmr 24 static +time.c:103:6:stmr_init 16 static +time.c:114:6:stmr_add 16 static +time.c:120:6:stmr_free 24 static +time.c:147:6:stmr_stop 16 static +time.c:152:6:stmr_run 16 static diff --git a/test/STM32F072C8T6/Debug/ecm_src/src/usb_device.d b/test/STM32F072C8T6/Debug/ecm_src/src/usb_device.d new file mode 100644 index 0000000..1e04a2b --- /dev/null +++ b/test/STM32F072C8T6/Debug/ecm_src/src/usb_device.d @@ -0,0 +1,195 @@ +ecm_src/src/usb_device.o: D:/project_in_git/CDC_ECM/src/src/usb_device.c \ + D:/project_in_git/CDC_ECM/src/src/usb_device.h \ + ../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f0xx.h \ + ../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f072xb.h \ + ../Drivers/CMSIS/Include/core_cm0.h \ + ../Drivers/CMSIS/Include/cmsis_version.h \ + ../Drivers/CMSIS/Include/cmsis_compiler.h \ + ../Drivers/CMSIS/Include/cmsis_gcc.h \ + ../Drivers/CMSIS/Device/ST/STM32F0xx/Include/system_stm32f0xx.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal.h \ + ../Core/Inc/stm32f0xx_hal_conf.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_def.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_exti.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_cortex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_usb.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr_ex.h \ + D:/project_in_git/CDC_ECM/src/src/usbd_def.h \ + D:/project_in_git/CDC_ECM/src/src/usbd_conf.h ../Core/Inc/main.h \ + D:/project_in_git/CDC_ECM/src/src/usbd_ecm.h \ + D:/project_in_git/CDC_ECM/src/src/usbd_ioreq.h \ + D:/project_in_git/CDC_ECM/src/src/usbd_core.h \ + D:/project_in_git/CDC_ECM/src/src/usbd_ctlreq.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/netif/etharp.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/opt.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwipopts.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/debug.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/arch.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cc.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cpu.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/pbuf.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/err.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/ip_addr.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/def.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/netif.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/ip.h \ + D:/project_in_git/CDC_ECM/src/src/ecmhelper.h \ + D:/project_in_git/CDC_ECM/src/src/usbhelper.h \ + D:/project_in_git/CDC_ECM/src/src/usbd_desc.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/init.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/icmp.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/udp.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/api.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/inet.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/dns.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/tcp_impl.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/tcp.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/mem.h \ + D:/project_in_git/CDC_ECM/src/src/time.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/apps/httpserver_raw/httpd.h \ + D:/project_in_git/CDC_ECM/src/dhcp-server/dhserver.h \ + D:/project_in_git/CDC_ECM/src/dns-server/dnserver.h \ + D:/project_in_git/CDC_ECM/src/src/ecm_main.h + +D:/project_in_git/CDC_ECM/src/src/usb_device.h: + +../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f0xx.h: + +../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f072xb.h: + +../Drivers/CMSIS/Include/core_cm0.h: + +../Drivers/CMSIS/Include/cmsis_version.h: + +../Drivers/CMSIS/Include/cmsis_compiler.h: + +../Drivers/CMSIS/Include/cmsis_gcc.h: + +../Drivers/CMSIS/Device/ST/STM32F0xx/Include/system_stm32f0xx.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal.h: + +../Core/Inc/stm32f0xx_hal_conf.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_def.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_exti.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_cortex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_usb.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr_ex.h: + +D:/project_in_git/CDC_ECM/src/src/usbd_def.h: + +D:/project_in_git/CDC_ECM/src/src/usbd_conf.h: + +../Core/Inc/main.h: + +D:/project_in_git/CDC_ECM/src/src/usbd_ecm.h: + +D:/project_in_git/CDC_ECM/src/src/usbd_ioreq.h: + +D:/project_in_git/CDC_ECM/src/src/usbd_core.h: + +D:/project_in_git/CDC_ECM/src/src/usbd_ctlreq.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/netif/etharp.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/opt.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwipopts.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/debug.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/arch.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cc.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cpu.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/pbuf.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/err.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/ip_addr.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/def.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/netif.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/ip.h: + +D:/project_in_git/CDC_ECM/src/src/ecmhelper.h: + +D:/project_in_git/CDC_ECM/src/src/usbhelper.h: + +D:/project_in_git/CDC_ECM/src/src/usbd_desc.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/init.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/icmp.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/udp.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/api.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/inet.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/dns.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/tcp_impl.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/tcp.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/mem.h: + +D:/project_in_git/CDC_ECM/src/src/time.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/apps/httpserver_raw/httpd.h: + +D:/project_in_git/CDC_ECM/src/dhcp-server/dhserver.h: + +D:/project_in_git/CDC_ECM/src/dns-server/dnserver.h: + +D:/project_in_git/CDC_ECM/src/src/ecm_main.h: diff --git a/test/STM32F072C8T6/Debug/ecm_src/src/usb_device.o b/test/STM32F072C8T6/Debug/ecm_src/src/usb_device.o new file mode 100644 index 0000000..01f3144 Binary files /dev/null and b/test/STM32F072C8T6/Debug/ecm_src/src/usb_device.o differ diff --git a/test/STM32F072C8T6/Debug/ecm_src/src/usb_device.su b/test/STM32F072C8T6/Debug/ecm_src/src/usb_device.su new file mode 100644 index 0000000..dc166cb --- /dev/null +++ b/test/STM32F072C8T6/Debug/ecm_src/src/usb_device.su @@ -0,0 +1 @@ +usb_device.c:64:6:MX_USB_DEVICE_Init 8 static diff --git a/test/STM32F072C8T6/Debug/ecm_src/src/usbd_conf.d b/test/STM32F072C8T6/Debug/ecm_src/src/usbd_conf.d new file mode 100644 index 0000000..052a844 --- /dev/null +++ b/test/STM32F072C8T6/Debug/ecm_src/src/usbd_conf.d @@ -0,0 +1,147 @@ +ecm_src/src/usbd_conf.o: D:/project_in_git/CDC_ECM/src/src/usbd_conf.c \ + D:/project_in_git/CDC_ECM/src/src/usbd_core.h \ + D:/project_in_git/CDC_ECM/src/src/usbd_conf.h ../Core/Inc/main.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal.h \ + ../Core/Inc/stm32f0xx_hal_conf.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_def.h \ + ../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f0xx.h \ + ../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f072xb.h \ + ../Drivers/CMSIS/Include/core_cm0.h \ + ../Drivers/CMSIS/Include/cmsis_version.h \ + ../Drivers/CMSIS/Include/cmsis_compiler.h \ + ../Drivers/CMSIS/Include/cmsis_gcc.h \ + ../Drivers/CMSIS/Device/ST/STM32F0xx/Include/system_stm32f0xx.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_exti.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_cortex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_usb.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr_ex.h \ + D:/project_in_git/CDC_ECM/src/src/usbd_def.h \ + D:/project_in_git/CDC_ECM/src/src/usbd_ioreq.h \ + D:/project_in_git/CDC_ECM/src/src/usbd_ctlreq.h \ + D:/project_in_git/CDC_ECM/src/src/usbd_ecm.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/netif/etharp.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/opt.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwipopts.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/debug.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/arch.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cc.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cpu.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/pbuf.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/err.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/ip_addr.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/def.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/netif.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/ip.h \ + D:/project_in_git/CDC_ECM/src/src/ecmhelper.h \ + D:/project_in_git/CDC_ECM/src/src/usbhelper.h + +D:/project_in_git/CDC_ECM/src/src/usbd_core.h: + +D:/project_in_git/CDC_ECM/src/src/usbd_conf.h: + +../Core/Inc/main.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal.h: + +../Core/Inc/stm32f0xx_hal_conf.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_def.h: + +../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f0xx.h: + +../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f072xb.h: + +../Drivers/CMSIS/Include/core_cm0.h: + +../Drivers/CMSIS/Include/cmsis_version.h: + +../Drivers/CMSIS/Include/cmsis_compiler.h: + +../Drivers/CMSIS/Include/cmsis_gcc.h: + +../Drivers/CMSIS/Device/ST/STM32F0xx/Include/system_stm32f0xx.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_exti.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_cortex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_usb.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr_ex.h: + +D:/project_in_git/CDC_ECM/src/src/usbd_def.h: + +D:/project_in_git/CDC_ECM/src/src/usbd_ioreq.h: + +D:/project_in_git/CDC_ECM/src/src/usbd_ctlreq.h: + +D:/project_in_git/CDC_ECM/src/src/usbd_ecm.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/netif/etharp.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/opt.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwipopts.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/debug.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/arch.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cc.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cpu.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/pbuf.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/err.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/ip_addr.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/def.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/netif.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/ip.h: + +D:/project_in_git/CDC_ECM/src/src/ecmhelper.h: + +D:/project_in_git/CDC_ECM/src/src/usbhelper.h: diff --git a/test/STM32F072C8T6/Debug/ecm_src/src/usbd_conf.o b/test/STM32F072C8T6/Debug/ecm_src/src/usbd_conf.o new file mode 100644 index 0000000..8750eba Binary files /dev/null and b/test/STM32F072C8T6/Debug/ecm_src/src/usbd_conf.o differ diff --git a/test/STM32F072C8T6/Debug/ecm_src/src/usbd_conf.su b/test/STM32F072C8T6/Debug/ecm_src/src/usbd_conf.su new file mode 100644 index 0000000..8efc360 --- /dev/null +++ b/test/STM32F072C8T6/Debug/ecm_src/src/usbd_conf.su @@ -0,0 +1,28 @@ +usbd_conf.c:55:6:HAL_PCD_MspInit 48 static +usbd_conf.c:86:6:HAL_PCD_MspDeInit 16 static +usbd_conf.c:101:6:HAL_PCD_SetupStageCallback 16 static +usbd_conf.c:112:6:HAL_PCD_DataOutStageCallback 16 static +usbd_conf.c:123:6:HAL_PCD_DataInStageCallback 16 static +usbd_conf.c:133:6:HAL_PCD_SOFCallback 16 static +usbd_conf.c:143:6:HAL_PCD_ResetCallback 16 static +usbd_conf.c:155:6:HAL_PCD_SuspendCallback 16 static +usbd_conf.c:164:6:HAL_PCD_ResumeCallback 16 static +usbd_conf.c:174:6:HAL_PCD_ISOOUTIncompleteCallback 16 static +usbd_conf.c:185:6:HAL_PCD_ISOINIncompleteCallback 16 static +usbd_conf.c:195:6:HAL_PCD_ConnectCallback 16 static +usbd_conf.c:205:6:HAL_PCD_DisconnectCallback 16 static +usbd_conf.c:219:20:USBD_LL_Init 24 static +usbd_conf.c:256:20:USBD_LL_DeInit 16 static +usbd_conf.c:267:20:USBD_LL_Start 16 static +usbd_conf.c:278:20:USBD_LL_Stop 16 static +usbd_conf.c:292:20:USBD_LL_OpenEP 24 static +usbd_conf.c:311:20:USBD_LL_CloseEP 16 static +usbd_conf.c:323:20:USBD_LL_FlushEP 16 static +usbd_conf.c:335:20:USBD_LL_StallEP 16 static +usbd_conf.c:347:20:USBD_LL_ClearStallEP 16 static +usbd_conf.c:359:9:USBD_LL_IsStallEP 24 static +usbd_conf.c:379:20:USBD_LL_SetUSBAddress 16 static +usbd_conf.c:393:20:USBD_LL_Transmit 48 static +usbd_conf.c:411:20:USBD_LL_PrepareReceive 48 static +usbd_conf.c:427:10:USBD_LL_GetRxDataSize 16 static +usbd_conf.c:437:6:USBD_LL_Delay 16 static diff --git a/test/STM32F072C8T6/Debug/ecm_src/src/usbd_core.d b/test/STM32F072C8T6/Debug/ecm_src/src/usbd_core.d new file mode 100644 index 0000000..3eb0540 --- /dev/null +++ b/test/STM32F072C8T6/Debug/ecm_src/src/usbd_core.d @@ -0,0 +1,99 @@ +ecm_src/src/usbd_core.o: D:/project_in_git/CDC_ECM/src/src/usbd_core.c \ + D:/project_in_git/CDC_ECM/src/src/usbd_core.h \ + D:/project_in_git/CDC_ECM/src/src/usbd_conf.h ../Core/Inc/main.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal.h \ + ../Core/Inc/stm32f0xx_hal_conf.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_def.h \ + ../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f0xx.h \ + ../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f072xb.h \ + ../Drivers/CMSIS/Include/core_cm0.h \ + ../Drivers/CMSIS/Include/cmsis_version.h \ + ../Drivers/CMSIS/Include/cmsis_compiler.h \ + ../Drivers/CMSIS/Include/cmsis_gcc.h \ + ../Drivers/CMSIS/Device/ST/STM32F0xx/Include/system_stm32f0xx.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_exti.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_cortex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_usb.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr_ex.h \ + D:/project_in_git/CDC_ECM/src/src/usbd_def.h \ + D:/project_in_git/CDC_ECM/src/src/usbd_ioreq.h \ + D:/project_in_git/CDC_ECM/src/src/usbd_ctlreq.h + +D:/project_in_git/CDC_ECM/src/src/usbd_core.h: + +D:/project_in_git/CDC_ECM/src/src/usbd_conf.h: + +../Core/Inc/main.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal.h: + +../Core/Inc/stm32f0xx_hal_conf.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_def.h: + +../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f0xx.h: + +../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f072xb.h: + +../Drivers/CMSIS/Include/core_cm0.h: + +../Drivers/CMSIS/Include/cmsis_version.h: + +../Drivers/CMSIS/Include/cmsis_compiler.h: + +../Drivers/CMSIS/Include/cmsis_gcc.h: + +../Drivers/CMSIS/Device/ST/STM32F0xx/Include/system_stm32f0xx.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_exti.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_cortex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_usb.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr_ex.h: + +D:/project_in_git/CDC_ECM/src/src/usbd_def.h: + +D:/project_in_git/CDC_ECM/src/src/usbd_ioreq.h: + +D:/project_in_git/CDC_ECM/src/src/usbd_ctlreq.h: diff --git a/test/STM32F072C8T6/Debug/ecm_src/src/usbd_core.o b/test/STM32F072C8T6/Debug/ecm_src/src/usbd_core.o new file mode 100644 index 0000000..92e10c3 Binary files /dev/null and b/test/STM32F072C8T6/Debug/ecm_src/src/usbd_core.o differ diff --git a/test/STM32F072C8T6/Debug/ecm_src/src/usbd_core.su b/test/STM32F072C8T6/Debug/ecm_src/src/usbd_core.su new file mode 100644 index 0000000..7716652 --- /dev/null +++ b/test/STM32F072C8T6/Debug/ecm_src/src/usbd_core.su @@ -0,0 +1,19 @@ +usbd_core.c:96:20:USBD_Init 24 static +usbd_core.c:132:20:USBD_DeInit 16 static +usbd_core.c:157:21:USBD_RegisterClass 24 static +usbd_core.c:181:21:USBD_Start 16 static +usbd_core.c:196:21:USBD_Stop 16 static +usbd_core.c:215:20:USBD_SetClassConfig 24 static +usbd_core.c:237:20:USBD_ClrClassConfig 16 static +usbd_core.c:251:20:USBD_LL_SetupStage 16 static +usbd_core.c:287:20:USBD_LL_DataOutStage 32 static +usbd_core.c:331:20:USBD_LL_DataInStage 32 static +usbd_core.c:386:20:USBD_LL_Reset 16 static +usbd_core.c:422:20:USBD_LL_SetSpeed 16 static +usbd_core.c:435:20:USBD_LL_Suspend 16 static +usbd_core.c:449:20:USBD_LL_Resume 16 static +usbd_core.c:462:20:USBD_LL_SOF 16 static +usbd_core.c:480:20:USBD_LL_IsoINIncomplete 16 static +usbd_core.c:491:20:USBD_LL_IsoOUTIncomplete 16 static +usbd_core.c:502:20:USBD_LL_DevConnected 16 static +usbd_core.c:513:20:USBD_LL_DevDisconnected 16 static diff --git a/test/STM32F072C8T6/Debug/ecm_src/src/usbd_ctlreq.d b/test/STM32F072C8T6/Debug/ecm_src/src/usbd_ctlreq.d new file mode 100644 index 0000000..c23c113 --- /dev/null +++ b/test/STM32F072C8T6/Debug/ecm_src/src/usbd_ctlreq.d @@ -0,0 +1,100 @@ +ecm_src/src/usbd_ctlreq.o: \ + D:/project_in_git/CDC_ECM/src/src/usbd_ctlreq.c \ + D:/project_in_git/CDC_ECM/src/src/usbd_ctlreq.h \ + D:/project_in_git/CDC_ECM/src/src/usbd_def.h \ + D:/project_in_git/CDC_ECM/src/src/usbd_conf.h ../Core/Inc/main.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal.h \ + ../Core/Inc/stm32f0xx_hal_conf.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_def.h \ + ../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f0xx.h \ + ../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f072xb.h \ + ../Drivers/CMSIS/Include/core_cm0.h \ + ../Drivers/CMSIS/Include/cmsis_version.h \ + ../Drivers/CMSIS/Include/cmsis_compiler.h \ + ../Drivers/CMSIS/Include/cmsis_gcc.h \ + ../Drivers/CMSIS/Device/ST/STM32F0xx/Include/system_stm32f0xx.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_exti.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_cortex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_usb.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr_ex.h \ + D:/project_in_git/CDC_ECM/src/src/usbd_ioreq.h \ + D:/project_in_git/CDC_ECM/src/src/usbd_core.h + +D:/project_in_git/CDC_ECM/src/src/usbd_ctlreq.h: + +D:/project_in_git/CDC_ECM/src/src/usbd_def.h: + +D:/project_in_git/CDC_ECM/src/src/usbd_conf.h: + +../Core/Inc/main.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal.h: + +../Core/Inc/stm32f0xx_hal_conf.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_def.h: + +../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f0xx.h: + +../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f072xb.h: + +../Drivers/CMSIS/Include/core_cm0.h: + +../Drivers/CMSIS/Include/cmsis_version.h: + +../Drivers/CMSIS/Include/cmsis_compiler.h: + +../Drivers/CMSIS/Include/cmsis_gcc.h: + +../Drivers/CMSIS/Device/ST/STM32F0xx/Include/system_stm32f0xx.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_exti.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_cortex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_usb.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr_ex.h: + +D:/project_in_git/CDC_ECM/src/src/usbd_ioreq.h: + +D:/project_in_git/CDC_ECM/src/src/usbd_core.h: diff --git a/test/STM32F072C8T6/Debug/ecm_src/src/usbd_ctlreq.o b/test/STM32F072C8T6/Debug/ecm_src/src/usbd_ctlreq.o new file mode 100644 index 0000000..e8d509a Binary files /dev/null and b/test/STM32F072C8T6/Debug/ecm_src/src/usbd_ctlreq.o differ diff --git a/test/STM32F072C8T6/Debug/ecm_src/src/usbd_ctlreq.su b/test/STM32F072C8T6/Debug/ecm_src/src/usbd_ctlreq.su new file mode 100644 index 0000000..26978ba --- /dev/null +++ b/test/STM32F072C8T6/Debug/ecm_src/src/usbd_ctlreq.su @@ -0,0 +1,14 @@ +usbd_ctlreq.c:119:21:USBD_StdDevReq 24 static +usbd_ctlreq.c:170:21:USBD_StdItfReq 24 static +usbd_ctlreq.c:207:21:USBD_StdEPReq 24 static +usbd_ctlreq.c:323:13:USBD_GetDescriptor 24 static +usbd_ctlreq.c:389:13:USBD_SetAddress 32 static +usbd_ctlreq.c:431:13:USBD_SetConfig 16 static +usbd_ctlreq.c:508:13:USBD_GetConfig 16 static +usbd_ctlreq.c:548:13:USBD_GetStatus 16 static +usbd_ctlreq.c:588:13:USBD_SetFeature 16 static +usbd_ctlreq.c:609:13:USBD_ClrFeature 16 static +usbd_ctlreq.c:638:6:USBD_ParseSetupRequest 16 static +usbd_ctlreq.c:656:6:USBD_CtlError 16 static +usbd_ctlreq.c:672:6:USBD_GetString 40 static +usbd_ctlreq.c:696:16:USBD_GetLen 24 static diff --git a/test/STM32F072C8T6/Debug/ecm_src/src/usbd_desc.d b/test/STM32F072C8T6/Debug/ecm_src/src/usbd_desc.d new file mode 100644 index 0000000..35254bc --- /dev/null +++ b/test/STM32F072C8T6/Debug/ecm_src/src/usbd_desc.d @@ -0,0 +1,150 @@ +ecm_src/src/usbd_desc.o: D:/project_in_git/CDC_ECM/src/src/usbd_desc.c \ + D:/project_in_git/CDC_ECM/src/src/usbd_core.h \ + D:/project_in_git/CDC_ECM/src/src/usbd_conf.h ../Core/Inc/main.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal.h \ + ../Core/Inc/stm32f0xx_hal_conf.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_def.h \ + ../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f0xx.h \ + ../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f072xb.h \ + ../Drivers/CMSIS/Include/core_cm0.h \ + ../Drivers/CMSIS/Include/cmsis_version.h \ + ../Drivers/CMSIS/Include/cmsis_compiler.h \ + ../Drivers/CMSIS/Include/cmsis_gcc.h \ + ../Drivers/CMSIS/Device/ST/STM32F0xx/Include/system_stm32f0xx.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_exti.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_cortex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_usb.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr_ex.h \ + D:/project_in_git/CDC_ECM/src/src/usbd_def.h \ + D:/project_in_git/CDC_ECM/src/src/usbd_ioreq.h \ + D:/project_in_git/CDC_ECM/src/src/usbd_ctlreq.h \ + D:/project_in_git/CDC_ECM/src/src/usbd_desc.h \ + D:/project_in_git/CDC_ECM/src/src/usbhelper.h \ + D:/project_in_git/CDC_ECM/src/src/usbd_ecm.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/netif/etharp.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/opt.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwipopts.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/debug.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/arch.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cc.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cpu.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/pbuf.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/err.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/ip_addr.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/def.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/netif.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/ip.h \ + D:/project_in_git/CDC_ECM/src/src/ecmhelper.h + +D:/project_in_git/CDC_ECM/src/src/usbd_core.h: + +D:/project_in_git/CDC_ECM/src/src/usbd_conf.h: + +../Core/Inc/main.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal.h: + +../Core/Inc/stm32f0xx_hal_conf.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_def.h: + +../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f0xx.h: + +../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f072xb.h: + +../Drivers/CMSIS/Include/core_cm0.h: + +../Drivers/CMSIS/Include/cmsis_version.h: + +../Drivers/CMSIS/Include/cmsis_compiler.h: + +../Drivers/CMSIS/Include/cmsis_gcc.h: + +../Drivers/CMSIS/Device/ST/STM32F0xx/Include/system_stm32f0xx.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_exti.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_cortex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_usb.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr_ex.h: + +D:/project_in_git/CDC_ECM/src/src/usbd_def.h: + +D:/project_in_git/CDC_ECM/src/src/usbd_ioreq.h: + +D:/project_in_git/CDC_ECM/src/src/usbd_ctlreq.h: + +D:/project_in_git/CDC_ECM/src/src/usbd_desc.h: + +D:/project_in_git/CDC_ECM/src/src/usbhelper.h: + +D:/project_in_git/CDC_ECM/src/src/usbd_ecm.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/netif/etharp.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/opt.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwipopts.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/debug.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/arch.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cc.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cpu.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/pbuf.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/err.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/ip_addr.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/def.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/netif.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/ip.h: + +D:/project_in_git/CDC_ECM/src/src/ecmhelper.h: diff --git a/test/STM32F072C8T6/Debug/ecm_src/src/usbd_desc.o b/test/STM32F072C8T6/Debug/ecm_src/src/usbd_desc.o new file mode 100644 index 0000000..5fae0dd Binary files /dev/null and b/test/STM32F072C8T6/Debug/ecm_src/src/usbd_desc.o differ diff --git a/test/STM32F072C8T6/Debug/ecm_src/src/usbd_desc.su b/test/STM32F072C8T6/Debug/ecm_src/src/usbd_desc.su new file mode 100644 index 0000000..f71c1c1 --- /dev/null +++ b/test/STM32F072C8T6/Debug/ecm_src/src/usbd_desc.su @@ -0,0 +1,6 @@ +usbd_desc.c:130:17:USBD_VCP_DeviceDescriptor 16 static +usbd_desc.c:142:17:USBD_VCP_LangIDStrDescriptor 16 static +usbd_desc.c:154:17:USBD_VCP_ProductStrDescriptor 16 static +usbd_desc.c:166:17:USBD_VCP_ManufacturerStrDescriptor 16 static +usbd_desc.c:178:17:USBD_VCP_SerialStrDescriptor 24 static +usbd_desc.c:204:13:IntToUnicode 32 static diff --git a/test/STM32F072C8T6/Debug/ecm_src/src/usbd_ecm.d b/test/STM32F072C8T6/Debug/ecm_src/src/usbd_ecm.d new file mode 100644 index 0000000..1de378b --- /dev/null +++ b/test/STM32F072C8T6/Debug/ecm_src/src/usbd_ecm.d @@ -0,0 +1,150 @@ +ecm_src/src/usbd_ecm.o: D:/project_in_git/CDC_ECM/src/src/usbd_ecm.c \ + D:/project_in_git/CDC_ECM/src/src/usbd_ecm.h \ + D:/project_in_git/CDC_ECM/src/src/usbd_def.h \ + D:/project_in_git/CDC_ECM/src/src/usbd_conf.h ../Core/Inc/main.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal.h \ + ../Core/Inc/stm32f0xx_hal_conf.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_def.h \ + ../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f0xx.h \ + ../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f072xb.h \ + ../Drivers/CMSIS/Include/core_cm0.h \ + ../Drivers/CMSIS/Include/cmsis_version.h \ + ../Drivers/CMSIS/Include/cmsis_compiler.h \ + ../Drivers/CMSIS/Include/cmsis_gcc.h \ + ../Drivers/CMSIS/Device/ST/STM32F0xx/Include/system_stm32f0xx.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_exti.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_cortex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_usb.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr_ex.h \ + D:/project_in_git/CDC_ECM/src/src/usbd_ioreq.h \ + D:/project_in_git/CDC_ECM/src/src/usbd_core.h \ + D:/project_in_git/CDC_ECM/src/src/usbd_ctlreq.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/netif/etharp.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/opt.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwipopts.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/debug.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/arch.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cc.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cpu.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/pbuf.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/err.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/ip_addr.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/def.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/netif.h \ + D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/ip.h \ + D:/project_in_git/CDC_ECM/src/src/ecmhelper.h \ + D:/project_in_git/CDC_ECM/src/src/usbhelper.h \ + D:/project_in_git/CDC_ECM/src/src/usbd_desc.h + +D:/project_in_git/CDC_ECM/src/src/usbd_ecm.h: + +D:/project_in_git/CDC_ECM/src/src/usbd_def.h: + +D:/project_in_git/CDC_ECM/src/src/usbd_conf.h: + +../Core/Inc/main.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal.h: + +../Core/Inc/stm32f0xx_hal_conf.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_def.h: + +../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f0xx.h: + +../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f072xb.h: + +../Drivers/CMSIS/Include/core_cm0.h: + +../Drivers/CMSIS/Include/cmsis_version.h: + +../Drivers/CMSIS/Include/cmsis_compiler.h: + +../Drivers/CMSIS/Include/cmsis_gcc.h: + +../Drivers/CMSIS/Device/ST/STM32F0xx/Include/system_stm32f0xx.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_exti.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_cortex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_usb.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr_ex.h: + +D:/project_in_git/CDC_ECM/src/src/usbd_ioreq.h: + +D:/project_in_git/CDC_ECM/src/src/usbd_core.h: + +D:/project_in_git/CDC_ECM/src/src/usbd_ctlreq.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/netif/etharp.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/opt.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwipopts.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/debug.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/arch.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cc.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/arch/cpu.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/pbuf.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/err.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/ip_addr.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/def.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/lwip/netif.h: + +D:/project_in_git/CDC_ECM/src/lwip-1.4.1/src/include/ipv4/lwip/ip.h: + +D:/project_in_git/CDC_ECM/src/src/ecmhelper.h: + +D:/project_in_git/CDC_ECM/src/src/usbhelper.h: + +D:/project_in_git/CDC_ECM/src/src/usbd_desc.h: diff --git a/test/STM32F072C8T6/Debug/ecm_src/src/usbd_ecm.o b/test/STM32F072C8T6/Debug/ecm_src/src/usbd_ecm.o new file mode 100644 index 0000000..299b609 Binary files /dev/null and b/test/STM32F072C8T6/Debug/ecm_src/src/usbd_ecm.o differ diff --git a/test/STM32F072C8T6/Debug/ecm_src/src/usbd_ecm.su b/test/STM32F072C8T6/Debug/ecm_src/src/usbd_ecm.su new file mode 100644 index 0000000..569f076 --- /dev/null +++ b/test/STM32F072C8T6/Debug/ecm_src/src/usbd_ecm.su @@ -0,0 +1,14 @@ +usbd_ecm.c:99:6:usb_ecm_recv_renew 24 static +usbd_ecm.c:108:16:USBD_ECM_Init 16 static +usbd_ecm.c:130:16:USBD_ECM_DeInit 16 static +usbd_ecm.c:148:16:USBD_ECM_Setup 16 static +usbd_ecm.c:159:13:ecm_incoming_attempt 16 static +usbd_ecm.c:178:16:USBD_ECM_DataIn 16 static +usbd_ecm.c:191:16:USBD_ECM_DataOut 24 static +usbd_ecm.c:217:16:USBD_ECM_SOF 16 static +usbd_ecm.c:239:16:USBD_ECM_EP0_RxReady 16 static +usbd_ecm.c:244:23:USBD_ECM_GetFSCfgDesc 16 static +usbd_ecm.c:250:9:USBD_ECM_RegisterInterface 16 static +usbd_ecm.c:257:6:USBD_ECM_PMAConfig 16 static +usbd_ecm.c:268:6:usb_ecm_can_xmit 16 static,ignoring_inline_asm +usbd_ecm.c:279:6:usb_ecm_xmit_packet 32 static,ignoring_inline_asm diff --git a/test/STM32F072C8T6/Debug/ecm_src/src/usbd_ioreq.d b/test/STM32F072C8T6/Debug/ecm_src/src/usbd_ioreq.d new file mode 100644 index 0000000..722e478 --- /dev/null +++ b/test/STM32F072C8T6/Debug/ecm_src/src/usbd_ioreq.d @@ -0,0 +1,99 @@ +ecm_src/src/usbd_ioreq.o: D:/project_in_git/CDC_ECM/src/src/usbd_ioreq.c \ + D:/project_in_git/CDC_ECM/src/src/usbd_ioreq.h \ + D:/project_in_git/CDC_ECM/src/src/usbd_def.h \ + D:/project_in_git/CDC_ECM/src/src/usbd_conf.h ../Core/Inc/main.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal.h \ + ../Core/Inc/stm32f0xx_hal_conf.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_def.h \ + ../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f0xx.h \ + ../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f072xb.h \ + ../Drivers/CMSIS/Include/core_cm0.h \ + ../Drivers/CMSIS/Include/cmsis_version.h \ + ../Drivers/CMSIS/Include/cmsis_compiler.h \ + ../Drivers/CMSIS/Include/cmsis_gcc.h \ + ../Drivers/CMSIS/Device/ST/STM32F0xx/Include/system_stm32f0xx.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_exti.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_cortex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_usb.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd_ex.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr.h \ + ../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr_ex.h \ + D:/project_in_git/CDC_ECM/src/src/usbd_core.h \ + D:/project_in_git/CDC_ECM/src/src/usbd_ctlreq.h + +D:/project_in_git/CDC_ECM/src/src/usbd_ioreq.h: + +D:/project_in_git/CDC_ECM/src/src/usbd_def.h: + +D:/project_in_git/CDC_ECM/src/src/usbd_conf.h: + +../Core/Inc/main.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal.h: + +../Core/Inc/stm32f0xx_hal_conf.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_def.h: + +../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f0xx.h: + +../Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f072xb.h: + +../Drivers/CMSIS/Include/core_cm0.h: + +../Drivers/CMSIS/Include/cmsis_version.h: + +../Drivers/CMSIS/Include/cmsis_compiler.h: + +../Drivers/CMSIS/Include/cmsis_gcc.h: + +../Drivers/CMSIS/Device/ST/STM32F0xx/Include/system_stm32f0xx.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_exti.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_cortex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_usb.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd_ex.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr.h: + +../Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr_ex.h: + +D:/project_in_git/CDC_ECM/src/src/usbd_core.h: + +D:/project_in_git/CDC_ECM/src/src/usbd_ctlreq.h: diff --git a/test/STM32F072C8T6/Debug/ecm_src/src/usbd_ioreq.o b/test/STM32F072C8T6/Debug/ecm_src/src/usbd_ioreq.o new file mode 100644 index 0000000..0223039 Binary files /dev/null and b/test/STM32F072C8T6/Debug/ecm_src/src/usbd_ioreq.o differ diff --git a/test/STM32F072C8T6/Debug/ecm_src/src/usbd_ioreq.su b/test/STM32F072C8T6/Debug/ecm_src/src/usbd_ioreq.su new file mode 100644 index 0000000..1af94d4 --- /dev/null +++ b/test/STM32F072C8T6/Debug/ecm_src/src/usbd_ioreq.su @@ -0,0 +1,7 @@ +usbd_ioreq.c:95:21:USBD_CtlSendData 24 static +usbd_ioreq.c:117:21:USBD_CtlContinueSendData 24 static +usbd_ioreq.c:135:21:USBD_CtlPrepareRx 24 static +usbd_ioreq.c:160:21:USBD_CtlContinueRx 24 static +usbd_ioreq.c:177:21:USBD_CtlSendStatus 16 static +usbd_ioreq.c:195:21:USBD_CtlReceiveStatus 16 static +usbd_ioreq.c:217:11:USBD_GetRxCount 16 static diff --git a/test/STM32F072C8T6/Debug/makefile b/test/STM32F072C8T6/Debug/makefile new file mode 100644 index 0000000..01baad0 --- /dev/null +++ b/test/STM32F072C8T6/Debug/makefile @@ -0,0 +1,79 @@ +################################################################################ +# Automatically-generated file. Do not edit! +################################################################################ + +-include ../makefile.init + +RM := rm -rf + +# All of the sources participating in the build are defined here +-include sources.mk +-include ecm_src/src/subdir.mk +-include ecm_src/lwip-1.4.1/src/netif/subdir.mk +-include ecm_src/lwip-1.4.1/src/core/ipv4/subdir.mk +-include ecm_src/lwip-1.4.1/src/core/subdir.mk +-include ecm_src/dns-server/subdir.mk +-include ecm_src/dhcp-server/subdir.mk +-include Drivers/STM32F0xx_HAL_Driver/Src/subdir.mk +-include Core/Startup/subdir.mk +-include Core/Src/subdir.mk +-include subdir.mk +-include objects.mk + +ifneq ($(MAKECMDGOALS),clean) +ifneq ($(strip $(C_DEPS)),) +-include $(C_DEPS) +endif +endif + +-include ../makefile.defs + +# Add inputs and outputs from these tool invocations to the build variables +EXECUTABLES += \ +stm32f072_ecm.elf \ + +SIZE_OUTPUT += \ +default.size.stdout \ + +OBJDUMP_LIST += \ +stm32f072_ecm.list \ + +OBJCOPY_BIN += \ +stm32f072_ecm.bin \ + + +# All Target +all: stm32f072_ecm.elf secondary-outputs + +# Tool invocations +stm32f072_ecm.elf: $(OBJS) $(USER_OBJS) D:\project_in_git\CDC_ECM\test\STM32F072C8T6\STM32F072C8TX_FLASH.ld + arm-none-eabi-gcc -o "stm32f072_ecm.elf" @"objects.list" $(USER_OBJS) $(LIBS) -mcpu=cortex-m0 -T"D:\project_in_git\CDC_ECM\test\STM32F072C8T6\STM32F072C8TX_FLASH.ld" --specs=nosys.specs -Wl,-Map="stm32f072_ecm.map" -Wl,--gc-sections -static --specs=nano.specs -mfloat-abi=soft -mthumb -Wl,--start-group -lc -lm -Wl,--end-group + @echo 'Finished building target: $@' + @echo ' ' + +default.size.stdout: $(EXECUTABLES) + arm-none-eabi-size $(EXECUTABLES) + @echo 'Finished building: $@' + @echo ' ' + +stm32f072_ecm.list: $(EXECUTABLES) + arm-none-eabi-objdump -h -S $(EXECUTABLES) > "stm32f072_ecm.list" + @echo 'Finished building: $@' + @echo ' ' + +stm32f072_ecm.bin: $(EXECUTABLES) + arm-none-eabi-objcopy -O binary $(EXECUTABLES) "stm32f072_ecm.bin" + @echo 'Finished building: $@' + @echo ' ' + +# Other Targets +clean: + -$(RM) * + -@echo ' ' + +secondary-outputs: $(SIZE_OUTPUT) $(OBJDUMP_LIST) $(OBJCOPY_BIN) + +.PHONY: all clean dependents +.SECONDARY: + +-include ../makefile.targets diff --git a/test/STM32F072C8T6/Debug/objects.list b/test/STM32F072C8T6/Debug/objects.list new file mode 100644 index 0000000..508d35a --- /dev/null +++ b/test/STM32F072C8T6/Debug/objects.list @@ -0,0 +1,62 @@ +"Core/Src/main.o" +"Core/Src/stm32f0xx_hal_msp.o" +"Core/Src/stm32f0xx_it.o" +"Core/Src/syscalls.o" +"Core/Src/sysmem.o" +"Core/Src/system_stm32f0xx.o" +"Core/Startup/startup_stm32f072c8tx.o" +"Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o" +"Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o" +"Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o" +"Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o" +"Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o" +"Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o" +"Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o" +"Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o" +"Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o" +"Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o" +"Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o" +"Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o" +"Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o" +"Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o" +"Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o" +"Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o" +"Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o" +"Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o" +"ecm_src/dhcp-server/dhserver.o" +"ecm_src/dns-server/dnserver.o" +"ecm_src/lwip-1.4.1/src/core/def.o" +"ecm_src/lwip-1.4.1/src/core/dhcp.o" +"ecm_src/lwip-1.4.1/src/core/dns.o" +"ecm_src/lwip-1.4.1/src/core/init.o" +"ecm_src/lwip-1.4.1/src/core/mem.o" +"ecm_src/lwip-1.4.1/src/core/memp.o" +"ecm_src/lwip-1.4.1/src/core/netif.o" +"ecm_src/lwip-1.4.1/src/core/pbuf.o" +"ecm_src/lwip-1.4.1/src/core/raw.o" +"ecm_src/lwip-1.4.1/src/core/stats.o" +"ecm_src/lwip-1.4.1/src/core/sys.o" +"ecm_src/lwip-1.4.1/src/core/tcp.o" +"ecm_src/lwip-1.4.1/src/core/tcp_in.o" +"ecm_src/lwip-1.4.1/src/core/tcp_out.o" +"ecm_src/lwip-1.4.1/src/core/timers.o" +"ecm_src/lwip-1.4.1/src/core/udp.o" +"ecm_src/lwip-1.4.1/src/core/ipv4/autoip.o" +"ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o" +"ecm_src/lwip-1.4.1/src/core/ipv4/igmp.o" +"ecm_src/lwip-1.4.1/src/core/ipv4/inet.o" +"ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o" +"ecm_src/lwip-1.4.1/src/core/ipv4/ip.o" +"ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o" +"ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o" +"ecm_src/lwip-1.4.1/src/netif/etharp.o" +"ecm_src/lwip-1.4.1/src/netif/ethernetif.o" +"ecm_src/src/ecm_main.o" +"ecm_src/src/time.o" +"ecm_src/src/usb_device.o" +"ecm_src/src/usbd_conf.o" +"ecm_src/src/usbd_core.o" +"ecm_src/src/usbd_ctlreq.o" +"ecm_src/src/usbd_desc.o" +"ecm_src/src/usbd_ecm.o" +"ecm_src/src/usbd_ioreq.o" diff --git a/test/STM32F072C8T6/Debug/objects.mk b/test/STM32F072C8T6/Debug/objects.mk new file mode 100644 index 0000000..dc31e16 --- /dev/null +++ b/test/STM32F072C8T6/Debug/objects.mk @@ -0,0 +1,8 @@ +################################################################################ +# Automatically-generated file. Do not edit! +################################################################################ + +USER_OBJS := + +LIBS := + diff --git a/test/STM32F072C8T6/Debug/sources.mk b/test/STM32F072C8T6/Debug/sources.mk new file mode 100644 index 0000000..97dd53e --- /dev/null +++ b/test/STM32F072C8T6/Debug/sources.mk @@ -0,0 +1,29 @@ +################################################################################ +# Automatically-generated file. Do not edit! +################################################################################ + +ELF_SRCS := +OBJ_SRCS := +S_SRCS := +C_SRCS := +S_UPPER_SRCS := +O_SRCS := +SIZE_OUTPUT := +OBJDUMP_LIST := +EXECUTABLES := +OBJS := +C_DEPS := +OBJCOPY_BIN := + +# Every subdirectory with source files must be described here +SUBDIRS := \ +Core/Src \ +Core/Startup \ +Drivers/STM32F0xx_HAL_Driver/Src \ +ecm_src/dhcp-server \ +ecm_src/dns-server \ +ecm_src/lwip-1.4.1/src/core \ +ecm_src/lwip-1.4.1/src/core/ipv4 \ +ecm_src/lwip-1.4.1/src/netif \ +ecm_src/src \ + diff --git a/test/STM32F072C8T6/Debug/stm32f072_ecm.bin b/test/STM32F072C8T6/Debug/stm32f072_ecm.bin new file mode 100644 index 0000000..1b331f7 Binary files /dev/null and b/test/STM32F072C8T6/Debug/stm32f072_ecm.bin differ diff --git a/test/STM32F072C8T6/Debug/stm32f072_ecm.elf b/test/STM32F072C8T6/Debug/stm32f072_ecm.elf new file mode 100644 index 0000000..8455fb6 Binary files /dev/null and b/test/STM32F072C8T6/Debug/stm32f072_ecm.elf differ diff --git a/test/STM32F072C8T6/Debug/stm32f072_ecm.list b/test/STM32F072C8T6/Debug/stm32f072_ecm.list new file mode 100644 index 0000000..750d244 --- /dev/null +++ b/test/STM32F072C8T6/Debug/stm32f072_ecm.list @@ -0,0 +1,43014 @@ + +stm32f072_ecm.elf: file format elf32-littlearm + +Sections: +Idx Name Size VMA LMA File off Algn + 0 .isr_vector 000000c0 08000000 08000000 00010000 2**0 + CONTENTS, ALLOC, LOAD, READONLY, DATA + 1 .text 0000fc1c 080000c0 080000c0 000100c0 2**2 + CONTENTS, ALLOC, LOAD, READONLY, CODE + 2 .rodata 000001cc 0800fcdc 0800fcdc 0001fcdc 2**2 + CONTENTS, ALLOC, LOAD, READONLY, DATA + 3 .ARM.extab 00000000 0800fea8 0800fea8 0002009c 2**0 + CONTENTS + 4 .ARM 00000000 0800fea8 0800fea8 0002009c 2**0 + CONTENTS + 5 .preinit_array 00000000 0800fea8 0800fea8 0002009c 2**0 + CONTENTS, ALLOC, LOAD, DATA + 6 .init_array 00000004 0800fea8 0800fea8 0001fea8 2**2 + CONTENTS, ALLOC, LOAD, DATA + 7 .fini_array 00000004 0800feac 0800feac 0001feac 2**2 + CONTENTS, ALLOC, LOAD, DATA + 8 .data 0000009c 20000000 0800feb0 00020000 2**2 + CONTENTS, ALLOC, LOAD, DATA + 9 .bss 0000369c 2000009c 0800ff4c 0002009c 2**2 + ALLOC + 10 ._user_heap_stack 00000600 20003738 0800ff4c 00023738 2**0 + ALLOC + 11 .ARM.attributes 00000028 00000000 00000000 0002009c 2**0 + CONTENTS, READONLY + 12 .debug_info 00029068 00000000 00000000 000200c4 2**0 + CONTENTS, READONLY, DEBUGGING + 13 .debug_abbrev 00005bb1 00000000 00000000 0004912c 2**0 + CONTENTS, READONLY, DEBUGGING + 14 .debug_aranges 000012c8 00000000 00000000 0004ece0 2**3 + CONTENTS, READONLY, DEBUGGING + 15 .debug_ranges 000010e0 00000000 00000000 0004ffa8 2**3 + CONTENTS, READONLY, DEBUGGING + 16 .debug_macro 0001cd20 00000000 00000000 00051088 2**0 + CONTENTS, READONLY, DEBUGGING + 17 .debug_line 000169ee 00000000 00000000 0006dda8 2**0 + CONTENTS, READONLY, DEBUGGING + 18 .debug_str 00082af5 00000000 00000000 00084796 2**0 + CONTENTS, READONLY, DEBUGGING + 19 .comment 0000007b 00000000 00000000 0010728b 2**0 + CONTENTS, READONLY + 20 .debug_frame 00003e20 00000000 00000000 00107308 2**2 + CONTENTS, READONLY, DEBUGGING + +Disassembly of section .text: + +080000c0 <__do_global_dtors_aux>: + 80000c0: b510 push {r4, lr} + 80000c2: 4c06 ldr r4, [pc, #24] ; (80000dc <__do_global_dtors_aux+0x1c>) + 80000c4: 7823 ldrb r3, [r4, #0] + 80000c6: 2b00 cmp r3, #0 + 80000c8: d107 bne.n 80000da <__do_global_dtors_aux+0x1a> + 80000ca: 4b05 ldr r3, [pc, #20] ; (80000e0 <__do_global_dtors_aux+0x20>) + 80000cc: 2b00 cmp r3, #0 + 80000ce: d002 beq.n 80000d6 <__do_global_dtors_aux+0x16> + 80000d0: 4804 ldr r0, [pc, #16] ; (80000e4 <__do_global_dtors_aux+0x24>) + 80000d2: e000 b.n 80000d6 <__do_global_dtors_aux+0x16> + 80000d4: bf00 nop + 80000d6: 2301 movs r3, #1 + 80000d8: 7023 strb r3, [r4, #0] + 80000da: bd10 pop {r4, pc} + 80000dc: 2000009c .word 0x2000009c + 80000e0: 00000000 .word 0x00000000 + 80000e4: 0800fcc4 .word 0x0800fcc4 + +080000e8 : + 80000e8: 4b04 ldr r3, [pc, #16] ; (80000fc ) + 80000ea: b510 push {r4, lr} + 80000ec: 2b00 cmp r3, #0 + 80000ee: d003 beq.n 80000f8 + 80000f0: 4903 ldr r1, [pc, #12] ; (8000100 ) + 80000f2: 4804 ldr r0, [pc, #16] ; (8000104 ) + 80000f4: e000 b.n 80000f8 + 80000f6: bf00 nop + 80000f8: bd10 pop {r4, pc} + 80000fa: 46c0 nop ; (mov r8, r8) + 80000fc: 00000000 .word 0x00000000 + 8000100: 200000a0 .word 0x200000a0 + 8000104: 0800fcc4 .word 0x0800fcc4 + +08000108 : + 8000108: 7802 ldrb r2, [r0, #0] + 800010a: 780b ldrb r3, [r1, #0] + 800010c: 2a00 cmp r2, #0 + 800010e: d003 beq.n 8000118 + 8000110: 3001 adds r0, #1 + 8000112: 3101 adds r1, #1 + 8000114: 429a cmp r2, r3 + 8000116: d0f7 beq.n 8000108 + 8000118: 1ad0 subs r0, r2, r3 + 800011a: 4770 bx lr + +0800011c : + 800011c: 2300 movs r3, #0 + 800011e: 5cc2 ldrb r2, [r0, r3] + 8000120: 3301 adds r3, #1 + 8000122: 2a00 cmp r2, #0 + 8000124: d1fb bne.n 800011e + 8000126: 1e58 subs r0, r3, #1 + 8000128: 4770 bx lr + ... + +0800012c <__udivsi3>: + 800012c: 2200 movs r2, #0 + 800012e: 0843 lsrs r3, r0, #1 + 8000130: 428b cmp r3, r1 + 8000132: d374 bcc.n 800021e <__udivsi3+0xf2> + 8000134: 0903 lsrs r3, r0, #4 + 8000136: 428b cmp r3, r1 + 8000138: d35f bcc.n 80001fa <__udivsi3+0xce> + 800013a: 0a03 lsrs r3, r0, #8 + 800013c: 428b cmp r3, r1 + 800013e: d344 bcc.n 80001ca <__udivsi3+0x9e> + 8000140: 0b03 lsrs r3, r0, #12 + 8000142: 428b cmp r3, r1 + 8000144: d328 bcc.n 8000198 <__udivsi3+0x6c> + 8000146: 0c03 lsrs r3, r0, #16 + 8000148: 428b cmp r3, r1 + 800014a: d30d bcc.n 8000168 <__udivsi3+0x3c> + 800014c: 22ff movs r2, #255 ; 0xff + 800014e: 0209 lsls r1, r1, #8 + 8000150: ba12 rev r2, r2 + 8000152: 0c03 lsrs r3, r0, #16 + 8000154: 428b cmp r3, r1 + 8000156: d302 bcc.n 800015e <__udivsi3+0x32> + 8000158: 1212 asrs r2, r2, #8 + 800015a: 0209 lsls r1, r1, #8 + 800015c: d065 beq.n 800022a <__udivsi3+0xfe> + 800015e: 0b03 lsrs r3, r0, #12 + 8000160: 428b cmp r3, r1 + 8000162: d319 bcc.n 8000198 <__udivsi3+0x6c> + 8000164: e000 b.n 8000168 <__udivsi3+0x3c> + 8000166: 0a09 lsrs r1, r1, #8 + 8000168: 0bc3 lsrs r3, r0, #15 + 800016a: 428b cmp r3, r1 + 800016c: d301 bcc.n 8000172 <__udivsi3+0x46> + 800016e: 03cb lsls r3, r1, #15 + 8000170: 1ac0 subs r0, r0, r3 + 8000172: 4152 adcs r2, r2 + 8000174: 0b83 lsrs r3, r0, #14 + 8000176: 428b cmp r3, r1 + 8000178: d301 bcc.n 800017e <__udivsi3+0x52> + 800017a: 038b lsls r3, r1, #14 + 800017c: 1ac0 subs r0, r0, r3 + 800017e: 4152 adcs r2, r2 + 8000180: 0b43 lsrs r3, r0, #13 + 8000182: 428b cmp r3, r1 + 8000184: d301 bcc.n 800018a <__udivsi3+0x5e> + 8000186: 034b lsls r3, r1, #13 + 8000188: 1ac0 subs r0, r0, r3 + 800018a: 4152 adcs r2, r2 + 800018c: 0b03 lsrs r3, r0, #12 + 800018e: 428b cmp r3, r1 + 8000190: d301 bcc.n 8000196 <__udivsi3+0x6a> + 8000192: 030b lsls r3, r1, #12 + 8000194: 1ac0 subs r0, r0, r3 + 8000196: 4152 adcs r2, r2 + 8000198: 0ac3 lsrs r3, r0, #11 + 800019a: 428b cmp r3, r1 + 800019c: d301 bcc.n 80001a2 <__udivsi3+0x76> + 800019e: 02cb lsls r3, r1, #11 + 80001a0: 1ac0 subs r0, r0, r3 + 80001a2: 4152 adcs r2, r2 + 80001a4: 0a83 lsrs r3, r0, #10 + 80001a6: 428b cmp r3, r1 + 80001a8: d301 bcc.n 80001ae <__udivsi3+0x82> + 80001aa: 028b lsls r3, r1, #10 + 80001ac: 1ac0 subs r0, r0, r3 + 80001ae: 4152 adcs r2, r2 + 80001b0: 0a43 lsrs r3, r0, #9 + 80001b2: 428b cmp r3, r1 + 80001b4: d301 bcc.n 80001ba <__udivsi3+0x8e> + 80001b6: 024b lsls r3, r1, #9 + 80001b8: 1ac0 subs r0, r0, r3 + 80001ba: 4152 adcs r2, r2 + 80001bc: 0a03 lsrs r3, r0, #8 + 80001be: 428b cmp r3, r1 + 80001c0: d301 bcc.n 80001c6 <__udivsi3+0x9a> + 80001c2: 020b lsls r3, r1, #8 + 80001c4: 1ac0 subs r0, r0, r3 + 80001c6: 4152 adcs r2, r2 + 80001c8: d2cd bcs.n 8000166 <__udivsi3+0x3a> + 80001ca: 09c3 lsrs r3, r0, #7 + 80001cc: 428b cmp r3, r1 + 80001ce: d301 bcc.n 80001d4 <__udivsi3+0xa8> + 80001d0: 01cb lsls r3, r1, #7 + 80001d2: 1ac0 subs r0, r0, r3 + 80001d4: 4152 adcs r2, r2 + 80001d6: 0983 lsrs r3, r0, #6 + 80001d8: 428b cmp r3, r1 + 80001da: d301 bcc.n 80001e0 <__udivsi3+0xb4> + 80001dc: 018b lsls r3, r1, #6 + 80001de: 1ac0 subs r0, r0, r3 + 80001e0: 4152 adcs r2, r2 + 80001e2: 0943 lsrs r3, r0, #5 + 80001e4: 428b cmp r3, r1 + 80001e6: d301 bcc.n 80001ec <__udivsi3+0xc0> + 80001e8: 014b lsls r3, r1, #5 + 80001ea: 1ac0 subs r0, r0, r3 + 80001ec: 4152 adcs r2, r2 + 80001ee: 0903 lsrs r3, r0, #4 + 80001f0: 428b cmp r3, r1 + 80001f2: d301 bcc.n 80001f8 <__udivsi3+0xcc> + 80001f4: 010b lsls r3, r1, #4 + 80001f6: 1ac0 subs r0, r0, r3 + 80001f8: 4152 adcs r2, r2 + 80001fa: 08c3 lsrs r3, r0, #3 + 80001fc: 428b cmp r3, r1 + 80001fe: d301 bcc.n 8000204 <__udivsi3+0xd8> + 8000200: 00cb lsls r3, r1, #3 + 8000202: 1ac0 subs r0, r0, r3 + 8000204: 4152 adcs r2, r2 + 8000206: 0883 lsrs r3, r0, #2 + 8000208: 428b cmp r3, r1 + 800020a: d301 bcc.n 8000210 <__udivsi3+0xe4> + 800020c: 008b lsls r3, r1, #2 + 800020e: 1ac0 subs r0, r0, r3 + 8000210: 4152 adcs r2, r2 + 8000212: 0843 lsrs r3, r0, #1 + 8000214: 428b cmp r3, r1 + 8000216: d301 bcc.n 800021c <__udivsi3+0xf0> + 8000218: 004b lsls r3, r1, #1 + 800021a: 1ac0 subs r0, r0, r3 + 800021c: 4152 adcs r2, r2 + 800021e: 1a41 subs r1, r0, r1 + 8000220: d200 bcs.n 8000224 <__udivsi3+0xf8> + 8000222: 4601 mov r1, r0 + 8000224: 4152 adcs r2, r2 + 8000226: 4610 mov r0, r2 + 8000228: 4770 bx lr + 800022a: e7ff b.n 800022c <__udivsi3+0x100> + 800022c: b501 push {r0, lr} + 800022e: 2000 movs r0, #0 + 8000230: f000 f8f0 bl 8000414 <__aeabi_idiv0> + 8000234: bd02 pop {r1, pc} + 8000236: 46c0 nop ; (mov r8, r8) + +08000238 <__aeabi_uidivmod>: + 8000238: 2900 cmp r1, #0 + 800023a: d0f7 beq.n 800022c <__udivsi3+0x100> + 800023c: e776 b.n 800012c <__udivsi3> + 800023e: 4770 bx lr + +08000240 <__divsi3>: + 8000240: 4603 mov r3, r0 + 8000242: 430b orrs r3, r1 + 8000244: d47f bmi.n 8000346 <__divsi3+0x106> + 8000246: 2200 movs r2, #0 + 8000248: 0843 lsrs r3, r0, #1 + 800024a: 428b cmp r3, r1 + 800024c: d374 bcc.n 8000338 <__divsi3+0xf8> + 800024e: 0903 lsrs r3, r0, #4 + 8000250: 428b cmp r3, r1 + 8000252: d35f bcc.n 8000314 <__divsi3+0xd4> + 8000254: 0a03 lsrs r3, r0, #8 + 8000256: 428b cmp r3, r1 + 8000258: d344 bcc.n 80002e4 <__divsi3+0xa4> + 800025a: 0b03 lsrs r3, r0, #12 + 800025c: 428b cmp r3, r1 + 800025e: d328 bcc.n 80002b2 <__divsi3+0x72> + 8000260: 0c03 lsrs r3, r0, #16 + 8000262: 428b cmp r3, r1 + 8000264: d30d bcc.n 8000282 <__divsi3+0x42> + 8000266: 22ff movs r2, #255 ; 0xff + 8000268: 0209 lsls r1, r1, #8 + 800026a: ba12 rev r2, r2 + 800026c: 0c03 lsrs r3, r0, #16 + 800026e: 428b cmp r3, r1 + 8000270: d302 bcc.n 8000278 <__divsi3+0x38> + 8000272: 1212 asrs r2, r2, #8 + 8000274: 0209 lsls r1, r1, #8 + 8000276: d065 beq.n 8000344 <__divsi3+0x104> + 8000278: 0b03 lsrs r3, r0, #12 + 800027a: 428b cmp r3, r1 + 800027c: d319 bcc.n 80002b2 <__divsi3+0x72> + 800027e: e000 b.n 8000282 <__divsi3+0x42> + 8000280: 0a09 lsrs r1, r1, #8 + 8000282: 0bc3 lsrs r3, r0, #15 + 8000284: 428b cmp r3, r1 + 8000286: d301 bcc.n 800028c <__divsi3+0x4c> + 8000288: 03cb lsls r3, r1, #15 + 800028a: 1ac0 subs r0, r0, r3 + 800028c: 4152 adcs r2, r2 + 800028e: 0b83 lsrs r3, r0, #14 + 8000290: 428b cmp r3, r1 + 8000292: d301 bcc.n 8000298 <__divsi3+0x58> + 8000294: 038b lsls r3, r1, #14 + 8000296: 1ac0 subs r0, r0, r3 + 8000298: 4152 adcs r2, r2 + 800029a: 0b43 lsrs r3, r0, #13 + 800029c: 428b cmp r3, r1 + 800029e: d301 bcc.n 80002a4 <__divsi3+0x64> + 80002a0: 034b lsls r3, r1, #13 + 80002a2: 1ac0 subs r0, r0, r3 + 80002a4: 4152 adcs r2, r2 + 80002a6: 0b03 lsrs r3, r0, #12 + 80002a8: 428b cmp r3, r1 + 80002aa: d301 bcc.n 80002b0 <__divsi3+0x70> + 80002ac: 030b lsls r3, r1, #12 + 80002ae: 1ac0 subs r0, r0, r3 + 80002b0: 4152 adcs r2, r2 + 80002b2: 0ac3 lsrs r3, r0, #11 + 80002b4: 428b cmp r3, r1 + 80002b6: d301 bcc.n 80002bc <__divsi3+0x7c> + 80002b8: 02cb lsls r3, r1, #11 + 80002ba: 1ac0 subs r0, r0, r3 + 80002bc: 4152 adcs r2, r2 + 80002be: 0a83 lsrs r3, r0, #10 + 80002c0: 428b cmp r3, r1 + 80002c2: d301 bcc.n 80002c8 <__divsi3+0x88> + 80002c4: 028b lsls r3, r1, #10 + 80002c6: 1ac0 subs r0, r0, r3 + 80002c8: 4152 adcs r2, r2 + 80002ca: 0a43 lsrs r3, r0, #9 + 80002cc: 428b cmp r3, r1 + 80002ce: d301 bcc.n 80002d4 <__divsi3+0x94> + 80002d0: 024b lsls r3, r1, #9 + 80002d2: 1ac0 subs r0, r0, r3 + 80002d4: 4152 adcs r2, r2 + 80002d6: 0a03 lsrs r3, r0, #8 + 80002d8: 428b cmp r3, r1 + 80002da: d301 bcc.n 80002e0 <__divsi3+0xa0> + 80002dc: 020b lsls r3, r1, #8 + 80002de: 1ac0 subs r0, r0, r3 + 80002e0: 4152 adcs r2, r2 + 80002e2: d2cd bcs.n 8000280 <__divsi3+0x40> + 80002e4: 09c3 lsrs r3, r0, #7 + 80002e6: 428b cmp r3, r1 + 80002e8: d301 bcc.n 80002ee <__divsi3+0xae> + 80002ea: 01cb lsls r3, r1, #7 + 80002ec: 1ac0 subs r0, r0, r3 + 80002ee: 4152 adcs r2, r2 + 80002f0: 0983 lsrs r3, r0, #6 + 80002f2: 428b cmp r3, r1 + 80002f4: d301 bcc.n 80002fa <__divsi3+0xba> + 80002f6: 018b lsls r3, r1, #6 + 80002f8: 1ac0 subs r0, r0, r3 + 80002fa: 4152 adcs r2, r2 + 80002fc: 0943 lsrs r3, r0, #5 + 80002fe: 428b cmp r3, r1 + 8000300: d301 bcc.n 8000306 <__divsi3+0xc6> + 8000302: 014b lsls r3, r1, #5 + 8000304: 1ac0 subs r0, r0, r3 + 8000306: 4152 adcs r2, r2 + 8000308: 0903 lsrs r3, r0, #4 + 800030a: 428b cmp r3, r1 + 800030c: d301 bcc.n 8000312 <__divsi3+0xd2> + 800030e: 010b lsls r3, r1, #4 + 8000310: 1ac0 subs r0, r0, r3 + 8000312: 4152 adcs r2, r2 + 8000314: 08c3 lsrs r3, r0, #3 + 8000316: 428b cmp r3, r1 + 8000318: d301 bcc.n 800031e <__divsi3+0xde> + 800031a: 00cb lsls r3, r1, #3 + 800031c: 1ac0 subs r0, r0, r3 + 800031e: 4152 adcs r2, r2 + 8000320: 0883 lsrs r3, r0, #2 + 8000322: 428b cmp r3, r1 + 8000324: d301 bcc.n 800032a <__divsi3+0xea> + 8000326: 008b lsls r3, r1, #2 + 8000328: 1ac0 subs r0, r0, r3 + 800032a: 4152 adcs r2, r2 + 800032c: 0843 lsrs r3, r0, #1 + 800032e: 428b cmp r3, r1 + 8000330: d301 bcc.n 8000336 <__divsi3+0xf6> + 8000332: 004b lsls r3, r1, #1 + 8000334: 1ac0 subs r0, r0, r3 + 8000336: 4152 adcs r2, r2 + 8000338: 1a41 subs r1, r0, r1 + 800033a: d200 bcs.n 800033e <__divsi3+0xfe> + 800033c: 4601 mov r1, r0 + 800033e: 4152 adcs r2, r2 + 8000340: 4610 mov r0, r2 + 8000342: 4770 bx lr + 8000344: e05d b.n 8000402 <__divsi3+0x1c2> + 8000346: 0fca lsrs r2, r1, #31 + 8000348: d000 beq.n 800034c <__divsi3+0x10c> + 800034a: 4249 negs r1, r1 + 800034c: 1003 asrs r3, r0, #32 + 800034e: d300 bcc.n 8000352 <__divsi3+0x112> + 8000350: 4240 negs r0, r0 + 8000352: 4053 eors r3, r2 + 8000354: 2200 movs r2, #0 + 8000356: 469c mov ip, r3 + 8000358: 0903 lsrs r3, r0, #4 + 800035a: 428b cmp r3, r1 + 800035c: d32d bcc.n 80003ba <__divsi3+0x17a> + 800035e: 0a03 lsrs r3, r0, #8 + 8000360: 428b cmp r3, r1 + 8000362: d312 bcc.n 800038a <__divsi3+0x14a> + 8000364: 22fc movs r2, #252 ; 0xfc + 8000366: 0189 lsls r1, r1, #6 + 8000368: ba12 rev r2, r2 + 800036a: 0a03 lsrs r3, r0, #8 + 800036c: 428b cmp r3, r1 + 800036e: d30c bcc.n 800038a <__divsi3+0x14a> + 8000370: 0189 lsls r1, r1, #6 + 8000372: 1192 asrs r2, r2, #6 + 8000374: 428b cmp r3, r1 + 8000376: d308 bcc.n 800038a <__divsi3+0x14a> + 8000378: 0189 lsls r1, r1, #6 + 800037a: 1192 asrs r2, r2, #6 + 800037c: 428b cmp r3, r1 + 800037e: d304 bcc.n 800038a <__divsi3+0x14a> + 8000380: 0189 lsls r1, r1, #6 + 8000382: d03a beq.n 80003fa <__divsi3+0x1ba> + 8000384: 1192 asrs r2, r2, #6 + 8000386: e000 b.n 800038a <__divsi3+0x14a> + 8000388: 0989 lsrs r1, r1, #6 + 800038a: 09c3 lsrs r3, r0, #7 + 800038c: 428b cmp r3, r1 + 800038e: d301 bcc.n 8000394 <__divsi3+0x154> + 8000390: 01cb lsls r3, r1, #7 + 8000392: 1ac0 subs r0, r0, r3 + 8000394: 4152 adcs r2, r2 + 8000396: 0983 lsrs r3, r0, #6 + 8000398: 428b cmp r3, r1 + 800039a: d301 bcc.n 80003a0 <__divsi3+0x160> + 800039c: 018b lsls r3, r1, #6 + 800039e: 1ac0 subs r0, r0, r3 + 80003a0: 4152 adcs r2, r2 + 80003a2: 0943 lsrs r3, r0, #5 + 80003a4: 428b cmp r3, r1 + 80003a6: d301 bcc.n 80003ac <__divsi3+0x16c> + 80003a8: 014b lsls r3, r1, #5 + 80003aa: 1ac0 subs r0, r0, r3 + 80003ac: 4152 adcs r2, r2 + 80003ae: 0903 lsrs r3, r0, #4 + 80003b0: 428b cmp r3, r1 + 80003b2: d301 bcc.n 80003b8 <__divsi3+0x178> + 80003b4: 010b lsls r3, r1, #4 + 80003b6: 1ac0 subs r0, r0, r3 + 80003b8: 4152 adcs r2, r2 + 80003ba: 08c3 lsrs r3, r0, #3 + 80003bc: 428b cmp r3, r1 + 80003be: d301 bcc.n 80003c4 <__divsi3+0x184> + 80003c0: 00cb lsls r3, r1, #3 + 80003c2: 1ac0 subs r0, r0, r3 + 80003c4: 4152 adcs r2, r2 + 80003c6: 0883 lsrs r3, r0, #2 + 80003c8: 428b cmp r3, r1 + 80003ca: d301 bcc.n 80003d0 <__divsi3+0x190> + 80003cc: 008b lsls r3, r1, #2 + 80003ce: 1ac0 subs r0, r0, r3 + 80003d0: 4152 adcs r2, r2 + 80003d2: d2d9 bcs.n 8000388 <__divsi3+0x148> + 80003d4: 0843 lsrs r3, r0, #1 + 80003d6: 428b cmp r3, r1 + 80003d8: d301 bcc.n 80003de <__divsi3+0x19e> + 80003da: 004b lsls r3, r1, #1 + 80003dc: 1ac0 subs r0, r0, r3 + 80003de: 4152 adcs r2, r2 + 80003e0: 1a41 subs r1, r0, r1 + 80003e2: d200 bcs.n 80003e6 <__divsi3+0x1a6> + 80003e4: 4601 mov r1, r0 + 80003e6: 4663 mov r3, ip + 80003e8: 4152 adcs r2, r2 + 80003ea: 105b asrs r3, r3, #1 + 80003ec: 4610 mov r0, r2 + 80003ee: d301 bcc.n 80003f4 <__divsi3+0x1b4> + 80003f0: 4240 negs r0, r0 + 80003f2: 2b00 cmp r3, #0 + 80003f4: d500 bpl.n 80003f8 <__divsi3+0x1b8> + 80003f6: 4249 negs r1, r1 + 80003f8: 4770 bx lr + 80003fa: 4663 mov r3, ip + 80003fc: 105b asrs r3, r3, #1 + 80003fe: d300 bcc.n 8000402 <__divsi3+0x1c2> + 8000400: 4240 negs r0, r0 + 8000402: b501 push {r0, lr} + 8000404: 2000 movs r0, #0 + 8000406: f000 f805 bl 8000414 <__aeabi_idiv0> + 800040a: bd02 pop {r1, pc} + +0800040c <__aeabi_idivmod>: + 800040c: 2900 cmp r1, #0 + 800040e: d0f8 beq.n 8000402 <__divsi3+0x1c2> + 8000410: e716 b.n 8000240 <__divsi3> + 8000412: 4770 bx lr + +08000414 <__aeabi_idiv0>: + 8000414: 4770 bx lr + 8000416: 46c0 nop ; (mov r8, r8) + +08000418
: +/** + * @brief The application entry point. + * @retval int + */ +int main(void) +{ + 8000418: b580 push {r7, lr} + 800041a: af00 add r7, sp, #0 + /* USER CODE END 1 */ + + /* MCU Configuration--------------------------------------------------------*/ + + /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ + HAL_Init(); + 800041c: f000 f8f8 bl 8000610 + /* USER CODE BEGIN Init */ + + /* USER CODE END Init */ + + /* Configure the system clock */ + SystemClock_Config(); + 8000420: f000 f809 bl 8000436 + /* USER CODE BEGIN SysInit */ + + /* USER CODE END SysInit */ + + /* Initialize all configured peripherals */ + MX_GPIO_Init(); + 8000424: f000 f85c bl 80004e0 + MX_USB_DEVICE_Init(); + 8000428: f00d ff76 bl 800e318 + /* USER CODE BEGIN 2 */ + ecm_main_init(); + 800042c: f00d fece bl 800e1cc + while (1) + { + /* USER CODE END WHILE */ + + /* USER CODE BEGIN 3 */ + ecm_main_loop(); + 8000430: f00d fef6 bl 800e220 + 8000434: e7fc b.n 8000430 + +08000436 : +/** + * @brief System Clock Configuration + * @retval None + */ +void SystemClock_Config(void) +{ + 8000436: b590 push {r4, r7, lr} + 8000438: b099 sub sp, #100 ; 0x64 + 800043a: af00 add r7, sp, #0 + RCC_OscInitTypeDef RCC_OscInitStruct = {0}; + 800043c: 242c movs r4, #44 ; 0x2c + 800043e: 193b adds r3, r7, r4 + 8000440: 0018 movs r0, r3 + 8000442: 2334 movs r3, #52 ; 0x34 + 8000444: 001a movs r2, r3 + 8000446: 2100 movs r1, #0 + 8000448: f00f fc34 bl 800fcb4 + RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; + 800044c: 231c movs r3, #28 + 800044e: 18fb adds r3, r7, r3 + 8000450: 0018 movs r0, r3 + 8000452: 2310 movs r3, #16 + 8000454: 001a movs r2, r3 + 8000456: 2100 movs r1, #0 + 8000458: f00f fc2c bl 800fcb4 + RCC_PeriphCLKInitTypeDef PeriphClkInit = {0}; + 800045c: 003b movs r3, r7 + 800045e: 0018 movs r0, r3 + 8000460: 231c movs r3, #28 + 8000462: 001a movs r2, r3 + 8000464: 2100 movs r1, #0 + 8000466: f00f fc25 bl 800fcb4 + + /** Initializes the CPU, AHB and APB busses clocks + */ + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI48; + 800046a: 193b adds r3, r7, r4 + 800046c: 2220 movs r2, #32 + 800046e: 601a str r2, [r3, #0] + RCC_OscInitStruct.HSI48State = RCC_HSI48_ON; + 8000470: 193b adds r3, r7, r4 + 8000472: 2201 movs r2, #1 + 8000474: 621a str r2, [r3, #32] + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; + 8000476: 193b adds r3, r7, r4 + 8000478: 2200 movs r2, #0 + 800047a: 625a str r2, [r3, #36] ; 0x24 + if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) + 800047c: 193b adds r3, r7, r4 + 800047e: 0018 movs r0, r3 + 8000480: f001 fba0 bl 8001bc4 + 8000484: 1e03 subs r3, r0, #0 + 8000486: d001 beq.n 800048c + { + Error_Handler(); + 8000488: f000 f842 bl 8000510 + } + /** Initializes the CPU, AHB and APB busses clocks + */ + RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK + 800048c: 211c movs r1, #28 + 800048e: 187b adds r3, r7, r1 + 8000490: 2207 movs r2, #7 + 8000492: 601a str r2, [r3, #0] + |RCC_CLOCKTYPE_PCLK1; + RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI48; + 8000494: 187b adds r3, r7, r1 + 8000496: 2203 movs r2, #3 + 8000498: 605a str r2, [r3, #4] + RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; + 800049a: 187b adds r3, r7, r1 + 800049c: 2200 movs r2, #0 + 800049e: 609a str r2, [r3, #8] + RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; + 80004a0: 187b adds r3, r7, r1 + 80004a2: 2200 movs r2, #0 + 80004a4: 60da str r2, [r3, #12] + + if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK) + 80004a6: 187b adds r3, r7, r1 + 80004a8: 2101 movs r1, #1 + 80004aa: 0018 movs r0, r3 + 80004ac: f001 ff10 bl 80022d0 + 80004b0: 1e03 subs r3, r0, #0 + 80004b2: d001 beq.n 80004b8 + { + Error_Handler(); + 80004b4: f000 f82c bl 8000510 + } + PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USB; + 80004b8: 003b movs r3, r7 + 80004ba: 2280 movs r2, #128 ; 0x80 + 80004bc: 0292 lsls r2, r2, #10 + 80004be: 601a str r2, [r3, #0] + PeriphClkInit.UsbClockSelection = RCC_USBCLKSOURCE_HSI48; + 80004c0: 003b movs r3, r7 + 80004c2: 2200 movs r2, #0 + 80004c4: 619a str r2, [r3, #24] + + if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) + 80004c6: 003b movs r3, r7 + 80004c8: 0018 movs r0, r3 + 80004ca: f002 f859 bl 8002580 + 80004ce: 1e03 subs r3, r0, #0 + 80004d0: d001 beq.n 80004d6 + { + Error_Handler(); + 80004d2: f000 f81d bl 8000510 + } +} + 80004d6: 46c0 nop ; (mov r8, r8) + 80004d8: 46bd mov sp, r7 + 80004da: b019 add sp, #100 ; 0x64 + 80004dc: bd90 pop {r4, r7, pc} + ... + +080004e0 : + * @brief GPIO Initialization Function + * @param None + * @retval None + */ +static void MX_GPIO_Init(void) +{ + 80004e0: b580 push {r7, lr} + 80004e2: b082 sub sp, #8 + 80004e4: af00 add r7, sp, #0 + + /* GPIO Ports Clock Enable */ + __HAL_RCC_GPIOA_CLK_ENABLE(); + 80004e6: 4b09 ldr r3, [pc, #36] ; (800050c ) + 80004e8: 695a ldr r2, [r3, #20] + 80004ea: 4b08 ldr r3, [pc, #32] ; (800050c ) + 80004ec: 2180 movs r1, #128 ; 0x80 + 80004ee: 0289 lsls r1, r1, #10 + 80004f0: 430a orrs r2, r1 + 80004f2: 615a str r2, [r3, #20] + 80004f4: 4b05 ldr r3, [pc, #20] ; (800050c ) + 80004f6: 695a ldr r2, [r3, #20] + 80004f8: 2380 movs r3, #128 ; 0x80 + 80004fa: 029b lsls r3, r3, #10 + 80004fc: 4013 ands r3, r2 + 80004fe: 607b str r3, [r7, #4] + 8000500: 687b ldr r3, [r7, #4] + +} + 8000502: 46c0 nop ; (mov r8, r8) + 8000504: 46bd mov sp, r7 + 8000506: b002 add sp, #8 + 8000508: bd80 pop {r7, pc} + 800050a: 46c0 nop ; (mov r8, r8) + 800050c: 40021000 .word 0x40021000 + +08000510 : +/** + * @brief This function is executed in case of error occurrence. + * @retval None + */ +void Error_Handler(void) +{ + 8000510: b580 push {r7, lr} + 8000512: af00 add r7, sp, #0 + /* USER CODE BEGIN Error_Handler_Debug */ + /* User can add his own implementation to report the HAL error return state */ + + /* USER CODE END Error_Handler_Debug */ +} + 8000514: 46c0 nop ; (mov r8, r8) + 8000516: 46bd mov sp, r7 + 8000518: bd80 pop {r7, pc} + ... + +0800051c : +/* USER CODE END 0 */ +/** + * Initializes the Global MSP. + */ +void HAL_MspInit(void) +{ + 800051c: b580 push {r7, lr} + 800051e: b082 sub sp, #8 + 8000520: af00 add r7, sp, #0 + /* USER CODE BEGIN MspInit 0 */ + + /* USER CODE END MspInit 0 */ + + __HAL_RCC_SYSCFG_CLK_ENABLE(); + 8000522: 4b0f ldr r3, [pc, #60] ; (8000560 ) + 8000524: 699a ldr r2, [r3, #24] + 8000526: 4b0e ldr r3, [pc, #56] ; (8000560 ) + 8000528: 2101 movs r1, #1 + 800052a: 430a orrs r2, r1 + 800052c: 619a str r2, [r3, #24] + 800052e: 4b0c ldr r3, [pc, #48] ; (8000560 ) + 8000530: 699b ldr r3, [r3, #24] + 8000532: 2201 movs r2, #1 + 8000534: 4013 ands r3, r2 + 8000536: 607b str r3, [r7, #4] + 8000538: 687b ldr r3, [r7, #4] + __HAL_RCC_PWR_CLK_ENABLE(); + 800053a: 4b09 ldr r3, [pc, #36] ; (8000560 ) + 800053c: 69da ldr r2, [r3, #28] + 800053e: 4b08 ldr r3, [pc, #32] ; (8000560 ) + 8000540: 2180 movs r1, #128 ; 0x80 + 8000542: 0549 lsls r1, r1, #21 + 8000544: 430a orrs r2, r1 + 8000546: 61da str r2, [r3, #28] + 8000548: 4b05 ldr r3, [pc, #20] ; (8000560 ) + 800054a: 69da ldr r2, [r3, #28] + 800054c: 2380 movs r3, #128 ; 0x80 + 800054e: 055b lsls r3, r3, #21 + 8000550: 4013 ands r3, r2 + 8000552: 603b str r3, [r7, #0] + 8000554: 683b ldr r3, [r7, #0] + /* System interrupt init*/ + + /* USER CODE BEGIN MspInit 1 */ + + /* USER CODE END MspInit 1 */ +} + 8000556: 46c0 nop ; (mov r8, r8) + 8000558: 46bd mov sp, r7 + 800055a: b002 add sp, #8 + 800055c: bd80 pop {r7, pc} + 800055e: 46c0 nop ; (mov r8, r8) + 8000560: 40021000 .word 0x40021000 + +08000564 : +/******************************************************************************/ +/** + * @brief This function handles Non maskable interrupt. + */ +void NMI_Handler(void) +{ + 8000564: b580 push {r7, lr} + 8000566: af00 add r7, sp, #0 + + /* USER CODE END NonMaskableInt_IRQn 0 */ + /* USER CODE BEGIN NonMaskableInt_IRQn 1 */ + + /* USER CODE END NonMaskableInt_IRQn 1 */ +} + 8000568: 46c0 nop ; (mov r8, r8) + 800056a: 46bd mov sp, r7 + 800056c: bd80 pop {r7, pc} + +0800056e : + +/** + * @brief This function handles Hard fault interrupt. + */ +void HardFault_Handler(void) +{ + 800056e: b580 push {r7, lr} + 8000570: af00 add r7, sp, #0 + /* USER CODE BEGIN HardFault_IRQn 0 */ + + /* USER CODE END HardFault_IRQn 0 */ + while (1) + 8000572: e7fe b.n 8000572 + +08000574 : + +/** + * @brief This function handles System service call via SWI instruction. + */ +void SVC_Handler(void) +{ + 8000574: b580 push {r7, lr} + 8000576: af00 add r7, sp, #0 + + /* USER CODE END SVC_IRQn 0 */ + /* USER CODE BEGIN SVC_IRQn 1 */ + + /* USER CODE END SVC_IRQn 1 */ +} + 8000578: 46c0 nop ; (mov r8, r8) + 800057a: 46bd mov sp, r7 + 800057c: bd80 pop {r7, pc} + +0800057e : + +/** + * @brief This function handles Pendable request for system service. + */ +void PendSV_Handler(void) +{ + 800057e: b580 push {r7, lr} + 8000580: af00 add r7, sp, #0 + + /* USER CODE END PendSV_IRQn 0 */ + /* USER CODE BEGIN PendSV_IRQn 1 */ + + /* USER CODE END PendSV_IRQn 1 */ +} + 8000582: 46c0 nop ; (mov r8, r8) + 8000584: 46bd mov sp, r7 + 8000586: bd80 pop {r7, pc} + +08000588 : + +/** + * @brief This function handles System tick timer. + */ +void SysTick_Handler(void) +{ + 8000588: b580 push {r7, lr} + 800058a: af00 add r7, sp, #0 + /* USER CODE BEGIN SysTick_IRQn 0 */ + + /* USER CODE END SysTick_IRQn 0 */ + HAL_IncTick(); + 800058c: f000 f888 bl 80006a0 + /* USER CODE BEGIN SysTick_IRQn 1 */ + + /* USER CODE END SysTick_IRQn 1 */ +} + 8000590: 46c0 nop ; (mov r8, r8) + 8000592: 46bd mov sp, r7 + 8000594: bd80 pop {r7, pc} + ... + +08000598 : + +/** + * @brief This function handles USB global interrupt / USB wake-up interrupt through EXTI line 18. + */ +void USB_IRQHandler(void) +{ + 8000598: b580 push {r7, lr} + 800059a: af00 add r7, sp, #0 + /* USER CODE BEGIN USB_IRQn 0 */ + + /* USER CODE END USB_IRQn 0 */ + HAL_PCD_IRQHandler(&hpcd_USB_FS); + 800059c: 4b03 ldr r3, [pc, #12] ; (80005ac ) + 800059e: 0018 movs r0, r3 + 80005a0: f000 fbfa bl 8000d98 + /* USER CODE BEGIN USB_IRQn 1 */ + + /* USER CODE END USB_IRQn 1 */ +} + 80005a4: 46c0 nop ; (mov r8, r8) + 80005a6: 46bd mov sp, r7 + 80005a8: bd80 pop {r7, pc} + 80005aa: 46c0 nop ; (mov r8, r8) + 80005ac: 200034c4 .word 0x200034c4 + +080005b0 : + * @brief Setup the microcontroller system. + * @param None + * @retval None + */ +void SystemInit(void) +{ + 80005b0: b580 push {r7, lr} + 80005b2: af00 add r7, sp, #0 + before branch to main program. This call is made inside + the "startup_stm32f0xx.s" file. + User can setups the default system clock (System clock source, PLL Multiplier + and Divider factors, AHB/APBx prescalers and Flash settings). + */ +} + 80005b4: 46c0 nop ; (mov r8, r8) + 80005b6: 46bd mov sp, r7 + 80005b8: bd80 pop {r7, pc} + ... + +080005bc : + + .section .text.Reset_Handler + .weak Reset_Handler + .type Reset_Handler, %function +Reset_Handler: + ldr r0, =_estack + 80005bc: 480d ldr r0, [pc, #52] ; (80005f4 ) + mov sp, r0 /* set stack pointer */ + 80005be: 4685 mov sp, r0 + +/* Copy the data segment initializers from flash to SRAM */ + ldr r0, =_sdata + 80005c0: 480d ldr r0, [pc, #52] ; (80005f8 ) + ldr r1, =_edata + 80005c2: 490e ldr r1, [pc, #56] ; (80005fc ) + ldr r2, =_sidata + 80005c4: 4a0e ldr r2, [pc, #56] ; (8000600 ) + movs r3, #0 + 80005c6: 2300 movs r3, #0 + b LoopCopyDataInit + 80005c8: e002 b.n 80005d0 + +080005ca : + +CopyDataInit: + ldr r4, [r2, r3] + 80005ca: 58d4 ldr r4, [r2, r3] + str r4, [r0, r3] + 80005cc: 50c4 str r4, [r0, r3] + adds r3, r3, #4 + 80005ce: 3304 adds r3, #4 + +080005d0 : + +LoopCopyDataInit: + adds r4, r0, r3 + 80005d0: 18c4 adds r4, r0, r3 + cmp r4, r1 + 80005d2: 428c cmp r4, r1 + bcc CopyDataInit + 80005d4: d3f9 bcc.n 80005ca + +/* Zero fill the bss segment. */ + ldr r2, =_sbss + 80005d6: 4a0b ldr r2, [pc, #44] ; (8000604 ) + ldr r4, =_ebss + 80005d8: 4c0b ldr r4, [pc, #44] ; (8000608 ) + movs r3, #0 + 80005da: 2300 movs r3, #0 + b LoopFillZerobss + 80005dc: e001 b.n 80005e2 + +080005de : + +FillZerobss: + str r3, [r2] + 80005de: 6013 str r3, [r2, #0] + adds r2, r2, #4 + 80005e0: 3204 adds r2, #4 + +080005e2 : + +LoopFillZerobss: + cmp r2, r4 + 80005e2: 42a2 cmp r2, r4 + bcc FillZerobss + 80005e4: d3fb bcc.n 80005de + +/* Call the clock system intitialization function.*/ + bl SystemInit + 80005e6: f7ff ffe3 bl 80005b0 +/* Call static constructors */ + bl __libc_init_array + 80005ea: f00f fb27 bl 800fc3c <__libc_init_array> +/* Call the application's entry point.*/ + bl main + 80005ee: f7ff ff13 bl 8000418
+ +080005f2 : + +LoopForever: + b LoopForever + 80005f2: e7fe b.n 80005f2 + ldr r0, =_estack + 80005f4: 20004000 .word 0x20004000 + ldr r0, =_sdata + 80005f8: 20000000 .word 0x20000000 + ldr r1, =_edata + 80005fc: 2000009c .word 0x2000009c + ldr r2, =_sidata + 8000600: 0800feb0 .word 0x0800feb0 + ldr r2, =_sbss + 8000604: 2000009c .word 0x2000009c + ldr r4, =_ebss + 8000608: 20003738 .word 0x20003738 + +0800060c : + * @retval : None +*/ + .section .text.Default_Handler,"ax",%progbits +Default_Handler: +Infinite_Loop: + b Infinite_Loop + 800060c: e7fe b.n 800060c + ... + +08000610 : + * In the default implementation,Systick is used as source of time base. + * The tick variable is incremented each 1ms in its ISR. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_Init(void) +{ + 8000610: b580 push {r7, lr} + 8000612: af00 add r7, sp, #0 + /* Configure Flash prefetch */ +#if (PREFETCH_ENABLE != 0) + __HAL_FLASH_PREFETCH_BUFFER_ENABLE(); + 8000614: 4b07 ldr r3, [pc, #28] ; (8000634 ) + 8000616: 681a ldr r2, [r3, #0] + 8000618: 4b06 ldr r3, [pc, #24] ; (8000634 ) + 800061a: 2110 movs r1, #16 + 800061c: 430a orrs r2, r1 + 800061e: 601a str r2, [r3, #0] +#endif /* PREFETCH_ENABLE */ + + /* Use systick as time base source and configure 1ms tick (default clock after Reset is HSI) */ + + HAL_InitTick(TICK_INT_PRIORITY); + 8000620: 2000 movs r0, #0 + 8000622: f000 f809 bl 8000638 + + /* Init the low level hardware */ + HAL_MspInit(); + 8000626: f7ff ff79 bl 800051c + + /* Return function status */ + return HAL_OK; + 800062a: 2300 movs r3, #0 +} + 800062c: 0018 movs r0, r3 + 800062e: 46bd mov sp, r7 + 8000630: bd80 pop {r7, pc} + 8000632: 46c0 nop ; (mov r8, r8) + 8000634: 40022000 .word 0x40022000 + +08000638 : + * implementation in user file. + * @param TickPriority Tick interrupt priority. + * @retval HAL status + */ +__weak HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority) +{ + 8000638: b590 push {r4, r7, lr} + 800063a: b083 sub sp, #12 + 800063c: af00 add r7, sp, #0 + 800063e: 6078 str r0, [r7, #4] + /*Configure the SysTick to have interrupt in 1ms time basis*/ + if (HAL_SYSTICK_Config(SystemCoreClock / (1000U / uwTickFreq)) > 0U) + 8000640: 4b14 ldr r3, [pc, #80] ; (8000694 ) + 8000642: 681c ldr r4, [r3, #0] + 8000644: 4b14 ldr r3, [pc, #80] ; (8000698 ) + 8000646: 781b ldrb r3, [r3, #0] + 8000648: 0019 movs r1, r3 + 800064a: 23fa movs r3, #250 ; 0xfa + 800064c: 0098 lsls r0, r3, #2 + 800064e: f7ff fd6d bl 800012c <__udivsi3> + 8000652: 0003 movs r3, r0 + 8000654: 0019 movs r1, r3 + 8000656: 0020 movs r0, r4 + 8000658: f7ff fd68 bl 800012c <__udivsi3> + 800065c: 0003 movs r3, r0 + 800065e: 0018 movs r0, r3 + 8000660: f000 f90b bl 800087a + 8000664: 1e03 subs r3, r0, #0 + 8000666: d001 beq.n 800066c + { + return HAL_ERROR; + 8000668: 2301 movs r3, #1 + 800066a: e00f b.n 800068c + } + + /* Configure the SysTick IRQ priority */ + if (TickPriority < (1UL << __NVIC_PRIO_BITS)) + 800066c: 687b ldr r3, [r7, #4] + 800066e: 2b03 cmp r3, #3 + 8000670: d80b bhi.n 800068a + { + HAL_NVIC_SetPriority(SysTick_IRQn, TickPriority, 0U); + 8000672: 6879 ldr r1, [r7, #4] + 8000674: 2301 movs r3, #1 + 8000676: 425b negs r3, r3 + 8000678: 2200 movs r2, #0 + 800067a: 0018 movs r0, r3 + 800067c: f000 f8d8 bl 8000830 + uwTickPrio = TickPriority; + 8000680: 4b06 ldr r3, [pc, #24] ; (800069c ) + 8000682: 687a ldr r2, [r7, #4] + 8000684: 601a str r2, [r3, #0] + { + return HAL_ERROR; + } + + /* Return function status */ + return HAL_OK; + 8000686: 2300 movs r3, #0 + 8000688: e000 b.n 800068c + return HAL_ERROR; + 800068a: 2301 movs r3, #1 +} + 800068c: 0018 movs r0, r3 + 800068e: 46bd mov sp, r7 + 8000690: b003 add sp, #12 + 8000692: bd90 pop {r4, r7, pc} + 8000694: 20000000 .word 0x20000000 + 8000698: 20000008 .word 0x20000008 + 800069c: 20000004 .word 0x20000004 + +080006a0 : + * @note This function is declared as __weak to be overwritten in case of other + * implementations in user file. + * @retval None + */ +__weak void HAL_IncTick(void) +{ + 80006a0: b580 push {r7, lr} + 80006a2: af00 add r7, sp, #0 + uwTick += uwTickFreq; + 80006a4: 4b05 ldr r3, [pc, #20] ; (80006bc ) + 80006a6: 781b ldrb r3, [r3, #0] + 80006a8: 001a movs r2, r3 + 80006aa: 4b05 ldr r3, [pc, #20] ; (80006c0 ) + 80006ac: 681b ldr r3, [r3, #0] + 80006ae: 18d2 adds r2, r2, r3 + 80006b0: 4b03 ldr r3, [pc, #12] ; (80006c0 ) + 80006b2: 601a str r2, [r3, #0] +} + 80006b4: 46c0 nop ; (mov r8, r8) + 80006b6: 46bd mov sp, r7 + 80006b8: bd80 pop {r7, pc} + 80006ba: 46c0 nop ; (mov r8, r8) + 80006bc: 20000008 .word 0x20000008 + 80006c0: 200028f0 .word 0x200028f0 + +080006c4 : + * @note This function is declared as __weak to be overwritten in case of other + * implementations in user file. + * @retval tick value + */ +__weak uint32_t HAL_GetTick(void) +{ + 80006c4: b580 push {r7, lr} + 80006c6: af00 add r7, sp, #0 + return uwTick; + 80006c8: 4b02 ldr r3, [pc, #8] ; (80006d4 ) + 80006ca: 681b ldr r3, [r3, #0] +} + 80006cc: 0018 movs r0, r3 + 80006ce: 46bd mov sp, r7 + 80006d0: bd80 pop {r7, pc} + 80006d2: 46c0 nop ; (mov r8, r8) + 80006d4: 200028f0 .word 0x200028f0 + +080006d8 <__NVIC_EnableIRQ>: + \details Enables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) +{ + 80006d8: b580 push {r7, lr} + 80006da: b082 sub sp, #8 + 80006dc: af00 add r7, sp, #0 + 80006de: 0002 movs r2, r0 + 80006e0: 1dfb adds r3, r7, #7 + 80006e2: 701a strb r2, [r3, #0] + if ((int32_t)(IRQn) >= 0) + 80006e4: 1dfb adds r3, r7, #7 + 80006e6: 781b ldrb r3, [r3, #0] + 80006e8: 2b7f cmp r3, #127 ; 0x7f + 80006ea: d809 bhi.n 8000700 <__NVIC_EnableIRQ+0x28> + { + NVIC->ISER[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + 80006ec: 1dfb adds r3, r7, #7 + 80006ee: 781b ldrb r3, [r3, #0] + 80006f0: 001a movs r2, r3 + 80006f2: 231f movs r3, #31 + 80006f4: 401a ands r2, r3 + 80006f6: 4b04 ldr r3, [pc, #16] ; (8000708 <__NVIC_EnableIRQ+0x30>) + 80006f8: 2101 movs r1, #1 + 80006fa: 4091 lsls r1, r2 + 80006fc: 000a movs r2, r1 + 80006fe: 601a str r2, [r3, #0] + } +} + 8000700: 46c0 nop ; (mov r8, r8) + 8000702: 46bd mov sp, r7 + 8000704: b002 add sp, #8 + 8000706: bd80 pop {r7, pc} + 8000708: e000e100 .word 0xe000e100 + +0800070c <__NVIC_SetPriority>: + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every processor exception. + */ +__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + 800070c: b590 push {r4, r7, lr} + 800070e: b083 sub sp, #12 + 8000710: af00 add r7, sp, #0 + 8000712: 0002 movs r2, r0 + 8000714: 6039 str r1, [r7, #0] + 8000716: 1dfb adds r3, r7, #7 + 8000718: 701a strb r2, [r3, #0] + if ((int32_t)(IRQn) >= 0) + 800071a: 1dfb adds r3, r7, #7 + 800071c: 781b ldrb r3, [r3, #0] + 800071e: 2b7f cmp r3, #127 ; 0x7f + 8000720: d828 bhi.n 8000774 <__NVIC_SetPriority+0x68> + { + NVIC->IP[_IP_IDX(IRQn)] = ((uint32_t)(NVIC->IP[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + 8000722: 4a2f ldr r2, [pc, #188] ; (80007e0 <__NVIC_SetPriority+0xd4>) + 8000724: 1dfb adds r3, r7, #7 + 8000726: 781b ldrb r3, [r3, #0] + 8000728: b25b sxtb r3, r3 + 800072a: 089b lsrs r3, r3, #2 + 800072c: 33c0 adds r3, #192 ; 0xc0 + 800072e: 009b lsls r3, r3, #2 + 8000730: 589b ldr r3, [r3, r2] + 8000732: 1dfa adds r2, r7, #7 + 8000734: 7812 ldrb r2, [r2, #0] + 8000736: 0011 movs r1, r2 + 8000738: 2203 movs r2, #3 + 800073a: 400a ands r2, r1 + 800073c: 00d2 lsls r2, r2, #3 + 800073e: 21ff movs r1, #255 ; 0xff + 8000740: 4091 lsls r1, r2 + 8000742: 000a movs r2, r1 + 8000744: 43d2 mvns r2, r2 + 8000746: 401a ands r2, r3 + 8000748: 0011 movs r1, r2 + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + 800074a: 683b ldr r3, [r7, #0] + 800074c: 019b lsls r3, r3, #6 + 800074e: 22ff movs r2, #255 ; 0xff + 8000750: 401a ands r2, r3 + 8000752: 1dfb adds r3, r7, #7 + 8000754: 781b ldrb r3, [r3, #0] + 8000756: 0018 movs r0, r3 + 8000758: 2303 movs r3, #3 + 800075a: 4003 ands r3, r0 + 800075c: 00db lsls r3, r3, #3 + 800075e: 409a lsls r2, r3 + NVIC->IP[_IP_IDX(IRQn)] = ((uint32_t)(NVIC->IP[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + 8000760: 481f ldr r0, [pc, #124] ; (80007e0 <__NVIC_SetPriority+0xd4>) + 8000762: 1dfb adds r3, r7, #7 + 8000764: 781b ldrb r3, [r3, #0] + 8000766: b25b sxtb r3, r3 + 8000768: 089b lsrs r3, r3, #2 + 800076a: 430a orrs r2, r1 + 800076c: 33c0 adds r3, #192 ; 0xc0 + 800076e: 009b lsls r3, r3, #2 + 8000770: 501a str r2, [r3, r0] + else + { + SCB->SHP[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } +} + 8000772: e031 b.n 80007d8 <__NVIC_SetPriority+0xcc> + SCB->SHP[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + 8000774: 4a1b ldr r2, [pc, #108] ; (80007e4 <__NVIC_SetPriority+0xd8>) + 8000776: 1dfb adds r3, r7, #7 + 8000778: 781b ldrb r3, [r3, #0] + 800077a: 0019 movs r1, r3 + 800077c: 230f movs r3, #15 + 800077e: 400b ands r3, r1 + 8000780: 3b08 subs r3, #8 + 8000782: 089b lsrs r3, r3, #2 + 8000784: 3306 adds r3, #6 + 8000786: 009b lsls r3, r3, #2 + 8000788: 18d3 adds r3, r2, r3 + 800078a: 3304 adds r3, #4 + 800078c: 681b ldr r3, [r3, #0] + 800078e: 1dfa adds r2, r7, #7 + 8000790: 7812 ldrb r2, [r2, #0] + 8000792: 0011 movs r1, r2 + 8000794: 2203 movs r2, #3 + 8000796: 400a ands r2, r1 + 8000798: 00d2 lsls r2, r2, #3 + 800079a: 21ff movs r1, #255 ; 0xff + 800079c: 4091 lsls r1, r2 + 800079e: 000a movs r2, r1 + 80007a0: 43d2 mvns r2, r2 + 80007a2: 401a ands r2, r3 + 80007a4: 0011 movs r1, r2 + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + 80007a6: 683b ldr r3, [r7, #0] + 80007a8: 019b lsls r3, r3, #6 + 80007aa: 22ff movs r2, #255 ; 0xff + 80007ac: 401a ands r2, r3 + 80007ae: 1dfb adds r3, r7, #7 + 80007b0: 781b ldrb r3, [r3, #0] + 80007b2: 0018 movs r0, r3 + 80007b4: 2303 movs r3, #3 + 80007b6: 4003 ands r3, r0 + 80007b8: 00db lsls r3, r3, #3 + 80007ba: 409a lsls r2, r3 + SCB->SHP[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + 80007bc: 4809 ldr r0, [pc, #36] ; (80007e4 <__NVIC_SetPriority+0xd8>) + 80007be: 1dfb adds r3, r7, #7 + 80007c0: 781b ldrb r3, [r3, #0] + 80007c2: 001c movs r4, r3 + 80007c4: 230f movs r3, #15 + 80007c6: 4023 ands r3, r4 + 80007c8: 3b08 subs r3, #8 + 80007ca: 089b lsrs r3, r3, #2 + 80007cc: 430a orrs r2, r1 + 80007ce: 3306 adds r3, #6 + 80007d0: 009b lsls r3, r3, #2 + 80007d2: 18c3 adds r3, r0, r3 + 80007d4: 3304 adds r3, #4 + 80007d6: 601a str r2, [r3, #0] +} + 80007d8: 46c0 nop ; (mov r8, r8) + 80007da: 46bd mov sp, r7 + 80007dc: b003 add sp, #12 + 80007de: bd90 pop {r4, r7, pc} + 80007e0: e000e100 .word 0xe000e100 + 80007e4: e000ed00 .word 0xe000ed00 + +080007e8 : + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + 80007e8: b580 push {r7, lr} + 80007ea: b082 sub sp, #8 + 80007ec: af00 add r7, sp, #0 + 80007ee: 6078 str r0, [r7, #4] + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + 80007f0: 687b ldr r3, [r7, #4] + 80007f2: 3b01 subs r3, #1 + 80007f4: 4a0c ldr r2, [pc, #48] ; (8000828 ) + 80007f6: 4293 cmp r3, r2 + 80007f8: d901 bls.n 80007fe + { + return (1UL); /* Reload value impossible */ + 80007fa: 2301 movs r3, #1 + 80007fc: e010 b.n 8000820 + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + 80007fe: 4b0b ldr r3, [pc, #44] ; (800082c ) + 8000800: 687a ldr r2, [r7, #4] + 8000802: 3a01 subs r2, #1 + 8000804: 605a str r2, [r3, #4] + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + 8000806: 2301 movs r3, #1 + 8000808: 425b negs r3, r3 + 800080a: 2103 movs r1, #3 + 800080c: 0018 movs r0, r3 + 800080e: f7ff ff7d bl 800070c <__NVIC_SetPriority> + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + 8000812: 4b06 ldr r3, [pc, #24] ; (800082c ) + 8000814: 2200 movs r2, #0 + 8000816: 609a str r2, [r3, #8] + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + 8000818: 4b04 ldr r3, [pc, #16] ; (800082c ) + 800081a: 2207 movs r2, #7 + 800081c: 601a str r2, [r3, #0] + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ + 800081e: 2300 movs r3, #0 +} + 8000820: 0018 movs r0, r3 + 8000822: 46bd mov sp, r7 + 8000824: b002 add sp, #8 + 8000826: bd80 pop {r7, pc} + 8000828: 00ffffff .word 0x00ffffff + 800082c: e000e010 .word 0xe000e010 + +08000830 : + * with stm32f0xx devices, this parameter is a dummy value and it is ignored, because + * no subpriority supported in Cortex M0 based products. + * @retval None + */ +void HAL_NVIC_SetPriority(IRQn_Type IRQn, uint32_t PreemptPriority, uint32_t SubPriority) +{ + 8000830: b580 push {r7, lr} + 8000832: b084 sub sp, #16 + 8000834: af00 add r7, sp, #0 + 8000836: 60b9 str r1, [r7, #8] + 8000838: 607a str r2, [r7, #4] + 800083a: 210f movs r1, #15 + 800083c: 187b adds r3, r7, r1 + 800083e: 1c02 adds r2, r0, #0 + 8000840: 701a strb r2, [r3, #0] + /* Check the parameters */ + assert_param(IS_NVIC_PREEMPTION_PRIORITY(PreemptPriority)); + NVIC_SetPriority(IRQn,PreemptPriority); + 8000842: 68ba ldr r2, [r7, #8] + 8000844: 187b adds r3, r7, r1 + 8000846: 781b ldrb r3, [r3, #0] + 8000848: b25b sxtb r3, r3 + 800084a: 0011 movs r1, r2 + 800084c: 0018 movs r0, r3 + 800084e: f7ff ff5d bl 800070c <__NVIC_SetPriority> +} + 8000852: 46c0 nop ; (mov r8, r8) + 8000854: 46bd mov sp, r7 + 8000856: b004 add sp, #16 + 8000858: bd80 pop {r7, pc} + +0800085a : + * This parameter can be an enumerator of IRQn_Type enumeration + * (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32f0xxxx.h)) + * @retval None + */ +void HAL_NVIC_EnableIRQ(IRQn_Type IRQn) +{ + 800085a: b580 push {r7, lr} + 800085c: b082 sub sp, #8 + 800085e: af00 add r7, sp, #0 + 8000860: 0002 movs r2, r0 + 8000862: 1dfb adds r3, r7, #7 + 8000864: 701a strb r2, [r3, #0] + /* Check the parameters */ + assert_param(IS_NVIC_DEVICE_IRQ(IRQn)); + + /* Enable interrupt */ + NVIC_EnableIRQ(IRQn); + 8000866: 1dfb adds r3, r7, #7 + 8000868: 781b ldrb r3, [r3, #0] + 800086a: b25b sxtb r3, r3 + 800086c: 0018 movs r0, r3 + 800086e: f7ff ff33 bl 80006d8 <__NVIC_EnableIRQ> +} + 8000872: 46c0 nop ; (mov r8, r8) + 8000874: 46bd mov sp, r7 + 8000876: b002 add sp, #8 + 8000878: bd80 pop {r7, pc} + +0800087a : + * @param TicksNumb Specifies the ticks Number of ticks between two interrupts. + * @retval status: - 0 Function succeeded. + * - 1 Function failed. + */ +uint32_t HAL_SYSTICK_Config(uint32_t TicksNumb) +{ + 800087a: b580 push {r7, lr} + 800087c: b082 sub sp, #8 + 800087e: af00 add r7, sp, #0 + 8000880: 6078 str r0, [r7, #4] + return SysTick_Config(TicksNumb); + 8000882: 687b ldr r3, [r7, #4] + 8000884: 0018 movs r0, r3 + 8000886: f7ff ffaf bl 80007e8 + 800088a: 0003 movs r3, r0 +} + 800088c: 0018 movs r0, r3 + 800088e: 46bd mov sp, r7 + 8000890: b002 add sp, #8 + 8000892: bd80 pop {r7, pc} + +08000894 : + * @param GPIO_Init pointer to a GPIO_InitTypeDef structure that contains + * the configuration information for the specified GPIO peripheral. + * @retval None + */ +void HAL_GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *GPIO_Init) +{ + 8000894: b580 push {r7, lr} + 8000896: b086 sub sp, #24 + 8000898: af00 add r7, sp, #0 + 800089a: 6078 str r0, [r7, #4] + 800089c: 6039 str r1, [r7, #0] + uint32_t position = 0x00u; + 800089e: 2300 movs r3, #0 + 80008a0: 617b str r3, [r7, #20] + assert_param(IS_GPIO_PIN(GPIO_Init->Pin)); + assert_param(IS_GPIO_MODE(GPIO_Init->Mode)); + assert_param(IS_GPIO_PULL(GPIO_Init->Pull)); + + /* Configure the port pins */ + while (((GPIO_Init->Pin) >> position) != 0x00u) + 80008a2: e155 b.n 8000b50 + { + /* Get current io position */ + iocurrent = (GPIO_Init->Pin) & (1uL << position); + 80008a4: 683b ldr r3, [r7, #0] + 80008a6: 681b ldr r3, [r3, #0] + 80008a8: 2101 movs r1, #1 + 80008aa: 697a ldr r2, [r7, #20] + 80008ac: 4091 lsls r1, r2 + 80008ae: 000a movs r2, r1 + 80008b0: 4013 ands r3, r2 + 80008b2: 60fb str r3, [r7, #12] + + if (iocurrent != 0x00u) + 80008b4: 68fb ldr r3, [r7, #12] + 80008b6: 2b00 cmp r3, #0 + 80008b8: d100 bne.n 80008bc + 80008ba: e146 b.n 8000b4a + { + /*--------------------- GPIO Mode Configuration ------------------------*/ + /* In case of Alternate function mode selection */ + if((GPIO_Init->Mode == GPIO_MODE_AF_PP) || (GPIO_Init->Mode == GPIO_MODE_AF_OD)) + 80008bc: 683b ldr r3, [r7, #0] + 80008be: 685b ldr r3, [r3, #4] + 80008c0: 2b02 cmp r3, #2 + 80008c2: d003 beq.n 80008cc + 80008c4: 683b ldr r3, [r7, #0] + 80008c6: 685b ldr r3, [r3, #4] + 80008c8: 2b12 cmp r3, #18 + 80008ca: d123 bne.n 8000914 + /* Check the Alternate function parameters */ + assert_param(IS_GPIO_AF_INSTANCE(GPIOx)); + assert_param(IS_GPIO_AF(GPIO_Init->Alternate)); + + /* Configure Alternate function mapped with the current IO */ + temp = GPIOx->AFR[position >> 3u]; + 80008cc: 697b ldr r3, [r7, #20] + 80008ce: 08da lsrs r2, r3, #3 + 80008d0: 687b ldr r3, [r7, #4] + 80008d2: 3208 adds r2, #8 + 80008d4: 0092 lsls r2, r2, #2 + 80008d6: 58d3 ldr r3, [r2, r3] + 80008d8: 613b str r3, [r7, #16] + temp &= ~(0xFu << ((position & 0x07u) * 4u)); + 80008da: 697b ldr r3, [r7, #20] + 80008dc: 2207 movs r2, #7 + 80008de: 4013 ands r3, r2 + 80008e0: 009b lsls r3, r3, #2 + 80008e2: 220f movs r2, #15 + 80008e4: 409a lsls r2, r3 + 80008e6: 0013 movs r3, r2 + 80008e8: 43da mvns r2, r3 + 80008ea: 693b ldr r3, [r7, #16] + 80008ec: 4013 ands r3, r2 + 80008ee: 613b str r3, [r7, #16] + temp |= ((GPIO_Init->Alternate) << ((position & 0x07u) * 4u)); + 80008f0: 683b ldr r3, [r7, #0] + 80008f2: 691a ldr r2, [r3, #16] + 80008f4: 697b ldr r3, [r7, #20] + 80008f6: 2107 movs r1, #7 + 80008f8: 400b ands r3, r1 + 80008fa: 009b lsls r3, r3, #2 + 80008fc: 409a lsls r2, r3 + 80008fe: 0013 movs r3, r2 + 8000900: 693a ldr r2, [r7, #16] + 8000902: 4313 orrs r3, r2 + 8000904: 613b str r3, [r7, #16] + GPIOx->AFR[position >> 3u] = temp; + 8000906: 697b ldr r3, [r7, #20] + 8000908: 08da lsrs r2, r3, #3 + 800090a: 687b ldr r3, [r7, #4] + 800090c: 3208 adds r2, #8 + 800090e: 0092 lsls r2, r2, #2 + 8000910: 6939 ldr r1, [r7, #16] + 8000912: 50d1 str r1, [r2, r3] + } + + /* Configure IO Direction mode (Input, Output, Alternate or Analog) */ + temp = GPIOx->MODER; + 8000914: 687b ldr r3, [r7, #4] + 8000916: 681b ldr r3, [r3, #0] + 8000918: 613b str r3, [r7, #16] + temp &= ~(GPIO_MODER_MODER0 << (position * 2u)); + 800091a: 697b ldr r3, [r7, #20] + 800091c: 005b lsls r3, r3, #1 + 800091e: 2203 movs r2, #3 + 8000920: 409a lsls r2, r3 + 8000922: 0013 movs r3, r2 + 8000924: 43da mvns r2, r3 + 8000926: 693b ldr r3, [r7, #16] + 8000928: 4013 ands r3, r2 + 800092a: 613b str r3, [r7, #16] + temp |= ((GPIO_Init->Mode & GPIO_MODE) << (position * 2u)); + 800092c: 683b ldr r3, [r7, #0] + 800092e: 685b ldr r3, [r3, #4] + 8000930: 2203 movs r2, #3 + 8000932: 401a ands r2, r3 + 8000934: 697b ldr r3, [r7, #20] + 8000936: 005b lsls r3, r3, #1 + 8000938: 409a lsls r2, r3 + 800093a: 0013 movs r3, r2 + 800093c: 693a ldr r2, [r7, #16] + 800093e: 4313 orrs r3, r2 + 8000940: 613b str r3, [r7, #16] + GPIOx->MODER = temp; + 8000942: 687b ldr r3, [r7, #4] + 8000944: 693a ldr r2, [r7, #16] + 8000946: 601a str r2, [r3, #0] + + /* In case of Output or Alternate function mode selection */ + if((GPIO_Init->Mode == GPIO_MODE_OUTPUT_PP) || (GPIO_Init->Mode == GPIO_MODE_AF_PP) || + 8000948: 683b ldr r3, [r7, #0] + 800094a: 685b ldr r3, [r3, #4] + 800094c: 2b01 cmp r3, #1 + 800094e: d00b beq.n 8000968 + 8000950: 683b ldr r3, [r7, #0] + 8000952: 685b ldr r3, [r3, #4] + 8000954: 2b02 cmp r3, #2 + 8000956: d007 beq.n 8000968 + (GPIO_Init->Mode == GPIO_MODE_OUTPUT_OD) || (GPIO_Init->Mode == GPIO_MODE_AF_OD)) + 8000958: 683b ldr r3, [r7, #0] + 800095a: 685b ldr r3, [r3, #4] + if((GPIO_Init->Mode == GPIO_MODE_OUTPUT_PP) || (GPIO_Init->Mode == GPIO_MODE_AF_PP) || + 800095c: 2b11 cmp r3, #17 + 800095e: d003 beq.n 8000968 + (GPIO_Init->Mode == GPIO_MODE_OUTPUT_OD) || (GPIO_Init->Mode == GPIO_MODE_AF_OD)) + 8000960: 683b ldr r3, [r7, #0] + 8000962: 685b ldr r3, [r3, #4] + 8000964: 2b12 cmp r3, #18 + 8000966: d130 bne.n 80009ca + { + /* Check the Speed parameter */ + assert_param(IS_GPIO_SPEED(GPIO_Init->Speed)); + /* Configure the IO Speed */ + temp = GPIOx->OSPEEDR; + 8000968: 687b ldr r3, [r7, #4] + 800096a: 689b ldr r3, [r3, #8] + 800096c: 613b str r3, [r7, #16] + temp &= ~(GPIO_OSPEEDER_OSPEEDR0 << (position * 2u)); + 800096e: 697b ldr r3, [r7, #20] + 8000970: 005b lsls r3, r3, #1 + 8000972: 2203 movs r2, #3 + 8000974: 409a lsls r2, r3 + 8000976: 0013 movs r3, r2 + 8000978: 43da mvns r2, r3 + 800097a: 693b ldr r3, [r7, #16] + 800097c: 4013 ands r3, r2 + 800097e: 613b str r3, [r7, #16] + temp |= (GPIO_Init->Speed << (position * 2u)); + 8000980: 683b ldr r3, [r7, #0] + 8000982: 68da ldr r2, [r3, #12] + 8000984: 697b ldr r3, [r7, #20] + 8000986: 005b lsls r3, r3, #1 + 8000988: 409a lsls r2, r3 + 800098a: 0013 movs r3, r2 + 800098c: 693a ldr r2, [r7, #16] + 800098e: 4313 orrs r3, r2 + 8000990: 613b str r3, [r7, #16] + GPIOx->OSPEEDR = temp; + 8000992: 687b ldr r3, [r7, #4] + 8000994: 693a ldr r2, [r7, #16] + 8000996: 609a str r2, [r3, #8] + + /* Configure the IO Output Type */ + temp = GPIOx->OTYPER; + 8000998: 687b ldr r3, [r7, #4] + 800099a: 685b ldr r3, [r3, #4] + 800099c: 613b str r3, [r7, #16] + temp &= ~(GPIO_OTYPER_OT_0 << position) ; + 800099e: 2201 movs r2, #1 + 80009a0: 697b ldr r3, [r7, #20] + 80009a2: 409a lsls r2, r3 + 80009a4: 0013 movs r3, r2 + 80009a6: 43da mvns r2, r3 + 80009a8: 693b ldr r3, [r7, #16] + 80009aa: 4013 ands r3, r2 + 80009ac: 613b str r3, [r7, #16] + temp |= (((GPIO_Init->Mode & GPIO_OUTPUT_TYPE) >> 4u) << position); + 80009ae: 683b ldr r3, [r7, #0] + 80009b0: 685b ldr r3, [r3, #4] + 80009b2: 091b lsrs r3, r3, #4 + 80009b4: 2201 movs r2, #1 + 80009b6: 401a ands r2, r3 + 80009b8: 697b ldr r3, [r7, #20] + 80009ba: 409a lsls r2, r3 + 80009bc: 0013 movs r3, r2 + 80009be: 693a ldr r2, [r7, #16] + 80009c0: 4313 orrs r3, r2 + 80009c2: 613b str r3, [r7, #16] + GPIOx->OTYPER = temp; + 80009c4: 687b ldr r3, [r7, #4] + 80009c6: 693a ldr r2, [r7, #16] + 80009c8: 605a str r2, [r3, #4] + } + + /* Activate the Pull-up or Pull down resistor for the current IO */ + temp = GPIOx->PUPDR; + 80009ca: 687b ldr r3, [r7, #4] + 80009cc: 68db ldr r3, [r3, #12] + 80009ce: 613b str r3, [r7, #16] + temp &= ~(GPIO_PUPDR_PUPDR0 << (position * 2u)); + 80009d0: 697b ldr r3, [r7, #20] + 80009d2: 005b lsls r3, r3, #1 + 80009d4: 2203 movs r2, #3 + 80009d6: 409a lsls r2, r3 + 80009d8: 0013 movs r3, r2 + 80009da: 43da mvns r2, r3 + 80009dc: 693b ldr r3, [r7, #16] + 80009de: 4013 ands r3, r2 + 80009e0: 613b str r3, [r7, #16] + temp |= ((GPIO_Init->Pull) << (position * 2u)); + 80009e2: 683b ldr r3, [r7, #0] + 80009e4: 689a ldr r2, [r3, #8] + 80009e6: 697b ldr r3, [r7, #20] + 80009e8: 005b lsls r3, r3, #1 + 80009ea: 409a lsls r2, r3 + 80009ec: 0013 movs r3, r2 + 80009ee: 693a ldr r2, [r7, #16] + 80009f0: 4313 orrs r3, r2 + 80009f2: 613b str r3, [r7, #16] + GPIOx->PUPDR = temp; + 80009f4: 687b ldr r3, [r7, #4] + 80009f6: 693a ldr r2, [r7, #16] + 80009f8: 60da str r2, [r3, #12] + + /*--------------------- EXTI Mode Configuration ------------------------*/ + /* Configure the External Interrupt or event for the current IO */ + if((GPIO_Init->Mode & EXTI_MODE) == EXTI_MODE) + 80009fa: 683b ldr r3, [r7, #0] + 80009fc: 685a ldr r2, [r3, #4] + 80009fe: 2380 movs r3, #128 ; 0x80 + 8000a00: 055b lsls r3, r3, #21 + 8000a02: 4013 ands r3, r2 + 8000a04: d100 bne.n 8000a08 + 8000a06: e0a0 b.n 8000b4a + { + /* Enable SYSCFG Clock */ + __HAL_RCC_SYSCFG_CLK_ENABLE(); + 8000a08: 4b57 ldr r3, [pc, #348] ; (8000b68 ) + 8000a0a: 699a ldr r2, [r3, #24] + 8000a0c: 4b56 ldr r3, [pc, #344] ; (8000b68 ) + 8000a0e: 2101 movs r1, #1 + 8000a10: 430a orrs r2, r1 + 8000a12: 619a str r2, [r3, #24] + 8000a14: 4b54 ldr r3, [pc, #336] ; (8000b68 ) + 8000a16: 699b ldr r3, [r3, #24] + 8000a18: 2201 movs r2, #1 + 8000a1a: 4013 ands r3, r2 + 8000a1c: 60bb str r3, [r7, #8] + 8000a1e: 68bb ldr r3, [r7, #8] + + temp = SYSCFG->EXTICR[position >> 2u]; + 8000a20: 4a52 ldr r2, [pc, #328] ; (8000b6c ) + 8000a22: 697b ldr r3, [r7, #20] + 8000a24: 089b lsrs r3, r3, #2 + 8000a26: 3302 adds r3, #2 + 8000a28: 009b lsls r3, r3, #2 + 8000a2a: 589b ldr r3, [r3, r2] + 8000a2c: 613b str r3, [r7, #16] + temp &= ~(0x0FuL << (4u * (position & 0x03u))); + 8000a2e: 697b ldr r3, [r7, #20] + 8000a30: 2203 movs r2, #3 + 8000a32: 4013 ands r3, r2 + 8000a34: 009b lsls r3, r3, #2 + 8000a36: 220f movs r2, #15 + 8000a38: 409a lsls r2, r3 + 8000a3a: 0013 movs r3, r2 + 8000a3c: 43da mvns r2, r3 + 8000a3e: 693b ldr r3, [r7, #16] + 8000a40: 4013 ands r3, r2 + 8000a42: 613b str r3, [r7, #16] + temp |= (GPIO_GET_INDEX(GPIOx) << (4u * (position & 0x03u))); + 8000a44: 687a ldr r2, [r7, #4] + 8000a46: 2390 movs r3, #144 ; 0x90 + 8000a48: 05db lsls r3, r3, #23 + 8000a4a: 429a cmp r2, r3 + 8000a4c: d019 beq.n 8000a82 + 8000a4e: 687b ldr r3, [r7, #4] + 8000a50: 4a47 ldr r2, [pc, #284] ; (8000b70 ) + 8000a52: 4293 cmp r3, r2 + 8000a54: d013 beq.n 8000a7e + 8000a56: 687b ldr r3, [r7, #4] + 8000a58: 4a46 ldr r2, [pc, #280] ; (8000b74 ) + 8000a5a: 4293 cmp r3, r2 + 8000a5c: d00d beq.n 8000a7a + 8000a5e: 687b ldr r3, [r7, #4] + 8000a60: 4a45 ldr r2, [pc, #276] ; (8000b78 ) + 8000a62: 4293 cmp r3, r2 + 8000a64: d007 beq.n 8000a76 + 8000a66: 687b ldr r3, [r7, #4] + 8000a68: 4a44 ldr r2, [pc, #272] ; (8000b7c ) + 8000a6a: 4293 cmp r3, r2 + 8000a6c: d101 bne.n 8000a72 + 8000a6e: 2304 movs r3, #4 + 8000a70: e008 b.n 8000a84 + 8000a72: 2305 movs r3, #5 + 8000a74: e006 b.n 8000a84 + 8000a76: 2303 movs r3, #3 + 8000a78: e004 b.n 8000a84 + 8000a7a: 2302 movs r3, #2 + 8000a7c: e002 b.n 8000a84 + 8000a7e: 2301 movs r3, #1 + 8000a80: e000 b.n 8000a84 + 8000a82: 2300 movs r3, #0 + 8000a84: 697a ldr r2, [r7, #20] + 8000a86: 2103 movs r1, #3 + 8000a88: 400a ands r2, r1 + 8000a8a: 0092 lsls r2, r2, #2 + 8000a8c: 4093 lsls r3, r2 + 8000a8e: 693a ldr r2, [r7, #16] + 8000a90: 4313 orrs r3, r2 + 8000a92: 613b str r3, [r7, #16] + SYSCFG->EXTICR[position >> 2u] = temp; + 8000a94: 4935 ldr r1, [pc, #212] ; (8000b6c ) + 8000a96: 697b ldr r3, [r7, #20] + 8000a98: 089b lsrs r3, r3, #2 + 8000a9a: 3302 adds r3, #2 + 8000a9c: 009b lsls r3, r3, #2 + 8000a9e: 693a ldr r2, [r7, #16] + 8000aa0: 505a str r2, [r3, r1] + + /* Clear EXTI line configuration */ + temp = EXTI->IMR; + 8000aa2: 4b37 ldr r3, [pc, #220] ; (8000b80 ) + 8000aa4: 681b ldr r3, [r3, #0] + 8000aa6: 613b str r3, [r7, #16] + temp &= ~(iocurrent); + 8000aa8: 68fb ldr r3, [r7, #12] + 8000aaa: 43da mvns r2, r3 + 8000aac: 693b ldr r3, [r7, #16] + 8000aae: 4013 ands r3, r2 + 8000ab0: 613b str r3, [r7, #16] + if((GPIO_Init->Mode & GPIO_MODE_IT) == GPIO_MODE_IT) + 8000ab2: 683b ldr r3, [r7, #0] + 8000ab4: 685a ldr r2, [r3, #4] + 8000ab6: 2380 movs r3, #128 ; 0x80 + 8000ab8: 025b lsls r3, r3, #9 + 8000aba: 4013 ands r3, r2 + 8000abc: d003 beq.n 8000ac6 + { + temp |= iocurrent; + 8000abe: 693a ldr r2, [r7, #16] + 8000ac0: 68fb ldr r3, [r7, #12] + 8000ac2: 4313 orrs r3, r2 + 8000ac4: 613b str r3, [r7, #16] + } + EXTI->IMR = temp; + 8000ac6: 4b2e ldr r3, [pc, #184] ; (8000b80 ) + 8000ac8: 693a ldr r2, [r7, #16] + 8000aca: 601a str r2, [r3, #0] + + temp = EXTI->EMR; + 8000acc: 4b2c ldr r3, [pc, #176] ; (8000b80 ) + 8000ace: 685b ldr r3, [r3, #4] + 8000ad0: 613b str r3, [r7, #16] + temp &= ~(iocurrent); + 8000ad2: 68fb ldr r3, [r7, #12] + 8000ad4: 43da mvns r2, r3 + 8000ad6: 693b ldr r3, [r7, #16] + 8000ad8: 4013 ands r3, r2 + 8000ada: 613b str r3, [r7, #16] + if((GPIO_Init->Mode & GPIO_MODE_EVT) == GPIO_MODE_EVT) + 8000adc: 683b ldr r3, [r7, #0] + 8000ade: 685a ldr r2, [r3, #4] + 8000ae0: 2380 movs r3, #128 ; 0x80 + 8000ae2: 029b lsls r3, r3, #10 + 8000ae4: 4013 ands r3, r2 + 8000ae6: d003 beq.n 8000af0 + { + temp |= iocurrent; + 8000ae8: 693a ldr r2, [r7, #16] + 8000aea: 68fb ldr r3, [r7, #12] + 8000aec: 4313 orrs r3, r2 + 8000aee: 613b str r3, [r7, #16] + } + EXTI->EMR = temp; + 8000af0: 4b23 ldr r3, [pc, #140] ; (8000b80 ) + 8000af2: 693a ldr r2, [r7, #16] + 8000af4: 605a str r2, [r3, #4] + + /* Clear Rising Falling edge configuration */ + temp = EXTI->RTSR; + 8000af6: 4b22 ldr r3, [pc, #136] ; (8000b80 ) + 8000af8: 689b ldr r3, [r3, #8] + 8000afa: 613b str r3, [r7, #16] + temp &= ~(iocurrent); + 8000afc: 68fb ldr r3, [r7, #12] + 8000afe: 43da mvns r2, r3 + 8000b00: 693b ldr r3, [r7, #16] + 8000b02: 4013 ands r3, r2 + 8000b04: 613b str r3, [r7, #16] + if((GPIO_Init->Mode & RISING_EDGE) == RISING_EDGE) + 8000b06: 683b ldr r3, [r7, #0] + 8000b08: 685a ldr r2, [r3, #4] + 8000b0a: 2380 movs r3, #128 ; 0x80 + 8000b0c: 035b lsls r3, r3, #13 + 8000b0e: 4013 ands r3, r2 + 8000b10: d003 beq.n 8000b1a + { + temp |= iocurrent; + 8000b12: 693a ldr r2, [r7, #16] + 8000b14: 68fb ldr r3, [r7, #12] + 8000b16: 4313 orrs r3, r2 + 8000b18: 613b str r3, [r7, #16] + } + EXTI->RTSR = temp; + 8000b1a: 4b19 ldr r3, [pc, #100] ; (8000b80 ) + 8000b1c: 693a ldr r2, [r7, #16] + 8000b1e: 609a str r2, [r3, #8] + + temp = EXTI->FTSR; + 8000b20: 4b17 ldr r3, [pc, #92] ; (8000b80 ) + 8000b22: 68db ldr r3, [r3, #12] + 8000b24: 613b str r3, [r7, #16] + temp &= ~(iocurrent); + 8000b26: 68fb ldr r3, [r7, #12] + 8000b28: 43da mvns r2, r3 + 8000b2a: 693b ldr r3, [r7, #16] + 8000b2c: 4013 ands r3, r2 + 8000b2e: 613b str r3, [r7, #16] + if((GPIO_Init->Mode & FALLING_EDGE) == FALLING_EDGE) + 8000b30: 683b ldr r3, [r7, #0] + 8000b32: 685a ldr r2, [r3, #4] + 8000b34: 2380 movs r3, #128 ; 0x80 + 8000b36: 039b lsls r3, r3, #14 + 8000b38: 4013 ands r3, r2 + 8000b3a: d003 beq.n 8000b44 + { + temp |= iocurrent; + 8000b3c: 693a ldr r2, [r7, #16] + 8000b3e: 68fb ldr r3, [r7, #12] + 8000b40: 4313 orrs r3, r2 + 8000b42: 613b str r3, [r7, #16] + } + EXTI->FTSR = temp; + 8000b44: 4b0e ldr r3, [pc, #56] ; (8000b80 ) + 8000b46: 693a ldr r2, [r7, #16] + 8000b48: 60da str r2, [r3, #12] + } + } + + position++; + 8000b4a: 697b ldr r3, [r7, #20] + 8000b4c: 3301 adds r3, #1 + 8000b4e: 617b str r3, [r7, #20] + while (((GPIO_Init->Pin) >> position) != 0x00u) + 8000b50: 683b ldr r3, [r7, #0] + 8000b52: 681a ldr r2, [r3, #0] + 8000b54: 697b ldr r3, [r7, #20] + 8000b56: 40da lsrs r2, r3 + 8000b58: 1e13 subs r3, r2, #0 + 8000b5a: d000 beq.n 8000b5e + 8000b5c: e6a2 b.n 80008a4 + } +} + 8000b5e: 46c0 nop ; (mov r8, r8) + 8000b60: 46bd mov sp, r7 + 8000b62: b006 add sp, #24 + 8000b64: bd80 pop {r7, pc} + 8000b66: 46c0 nop ; (mov r8, r8) + 8000b68: 40021000 .word 0x40021000 + 8000b6c: 40010000 .word 0x40010000 + 8000b70: 48000400 .word 0x48000400 + 8000b74: 48000800 .word 0x48000800 + 8000b78: 48000c00 .word 0x48000c00 + 8000b7c: 48001000 .word 0x48001000 + 8000b80: 40010400 .word 0x40010400 + +08000b84 : + * parameters in the PCD_InitTypeDef and initialize the associated handle. + * @param hpcd PCD handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_Init(PCD_HandleTypeDef *hpcd) +{ + 8000b84: b5f0 push {r4, r5, r6, r7, lr} + 8000b86: b08b sub sp, #44 ; 0x2c + 8000b88: af06 add r7, sp, #24 + 8000b8a: 6078 str r0, [r7, #4] + uint8_t i; + + /* Check the PCD handle allocation */ + if (hpcd == NULL) + 8000b8c: 687b ldr r3, [r7, #4] + 8000b8e: 2b00 cmp r3, #0 + 8000b90: d101 bne.n 8000b96 + { + return HAL_ERROR; + 8000b92: 2301 movs r3, #1 + 8000b94: e0d4 b.n 8000d40 + } + + /* Check the parameters */ + assert_param(IS_PCD_ALL_INSTANCE(hpcd->Instance)); + + if (hpcd->State == HAL_PCD_STATE_RESET) + 8000b96: 687b ldr r3, [r7, #4] + 8000b98: 4a6b ldr r2, [pc, #428] ; (8000d48 ) + 8000b9a: 5c9b ldrb r3, [r3, r2] + 8000b9c: b2db uxtb r3, r3 + 8000b9e: 2b00 cmp r3, #0 + 8000ba0: d108 bne.n 8000bb4 + { + /* Allocate lock resource and initialize it */ + hpcd->Lock = HAL_UNLOCKED; + 8000ba2: 687a ldr r2, [r7, #4] + 8000ba4: 238a movs r3, #138 ; 0x8a + 8000ba6: 009b lsls r3, r3, #2 + 8000ba8: 2100 movs r1, #0 + 8000baa: 54d1 strb r1, [r2, r3] + + /* Init the low level hardware */ + hpcd->MspInitCallback(hpcd); +#else + /* Init the low level hardware : GPIO, CLOCK, NVIC... */ + HAL_PCD_MspInit(hpcd); + 8000bac: 687b ldr r3, [r7, #4] + 8000bae: 0018 movs r0, r3 + 8000bb0: f00d fbe2 bl 800e378 +#endif /* (USE_HAL_PCD_REGISTER_CALLBACKS) */ + } + + hpcd->State = HAL_PCD_STATE_BUSY; + 8000bb4: 687b ldr r3, [r7, #4] + 8000bb6: 4a64 ldr r2, [pc, #400] ; (8000d48 ) + 8000bb8: 2103 movs r1, #3 + 8000bba: 5499 strb r1, [r3, r2] + + /* Disable the Interrupts */ + __HAL_PCD_DISABLE(hpcd); + 8000bbc: 687b ldr r3, [r7, #4] + 8000bbe: 681b ldr r3, [r3, #0] + 8000bc0: 0018 movs r0, r3 + 8000bc2: f001 fdf7 bl 80027b4 + + /* Init endpoints structures */ + for (i = 0U; i < hpcd->Init.dev_endpoints; i++) + 8000bc6: 230f movs r3, #15 + 8000bc8: 18fb adds r3, r7, r3 + 8000bca: 2200 movs r2, #0 + 8000bcc: 701a strb r2, [r3, #0] + 8000bce: e043 b.n 8000c58 + { + /* Init ep structure */ + hpcd->IN_ep[i].is_in = 1U; + 8000bd0: 200f movs r0, #15 + 8000bd2: 183b adds r3, r7, r0 + 8000bd4: 781b ldrb r3, [r3, #0] + 8000bd6: 687a ldr r2, [r7, #4] + 8000bd8: 2129 movs r1, #41 ; 0x29 + 8000bda: 015b lsls r3, r3, #5 + 8000bdc: 18d3 adds r3, r2, r3 + 8000bde: 185b adds r3, r3, r1 + 8000be0: 2201 movs r2, #1 + 8000be2: 701a strb r2, [r3, #0] + hpcd->IN_ep[i].num = i; + 8000be4: 183b adds r3, r7, r0 + 8000be6: 781b ldrb r3, [r3, #0] + 8000be8: 687a ldr r2, [r7, #4] + 8000bea: 2128 movs r1, #40 ; 0x28 + 8000bec: 015b lsls r3, r3, #5 + 8000bee: 18d3 adds r3, r2, r3 + 8000bf0: 185b adds r3, r3, r1 + 8000bf2: 183a adds r2, r7, r0 + 8000bf4: 7812 ldrb r2, [r2, #0] + 8000bf6: 701a strb r2, [r3, #0] + hpcd->IN_ep[i].tx_fifo_num = i; + 8000bf8: 183b adds r3, r7, r0 + 8000bfa: 781b ldrb r3, [r3, #0] + 8000bfc: 183a adds r2, r7, r0 + 8000bfe: 7812 ldrb r2, [r2, #0] + 8000c00: b291 uxth r1, r2 + 8000c02: 687a ldr r2, [r7, #4] + 8000c04: 015b lsls r3, r3, #5 + 8000c06: 18d3 adds r3, r2, r3 + 8000c08: 3336 adds r3, #54 ; 0x36 + 8000c0a: 1c0a adds r2, r1, #0 + 8000c0c: 801a strh r2, [r3, #0] + /* Control until ep is activated */ + hpcd->IN_ep[i].type = EP_TYPE_CTRL; + 8000c0e: 183b adds r3, r7, r0 + 8000c10: 781b ldrb r3, [r3, #0] + 8000c12: 687a ldr r2, [r7, #4] + 8000c14: 212b movs r1, #43 ; 0x2b + 8000c16: 015b lsls r3, r3, #5 + 8000c18: 18d3 adds r3, r2, r3 + 8000c1a: 185b adds r3, r3, r1 + 8000c1c: 2200 movs r2, #0 + 8000c1e: 701a strb r2, [r3, #0] + hpcd->IN_ep[i].maxpacket = 0U; + 8000c20: 183b adds r3, r7, r0 + 8000c22: 781b ldrb r3, [r3, #0] + 8000c24: 687a ldr r2, [r7, #4] + 8000c26: 015b lsls r3, r3, #5 + 8000c28: 18d3 adds r3, r2, r3 + 8000c2a: 3338 adds r3, #56 ; 0x38 + 8000c2c: 2200 movs r2, #0 + 8000c2e: 601a str r2, [r3, #0] + hpcd->IN_ep[i].xfer_buff = 0U; + 8000c30: 183b adds r3, r7, r0 + 8000c32: 781b ldrb r3, [r3, #0] + 8000c34: 687a ldr r2, [r7, #4] + 8000c36: 015b lsls r3, r3, #5 + 8000c38: 18d3 adds r3, r2, r3 + 8000c3a: 333c adds r3, #60 ; 0x3c + 8000c3c: 2200 movs r2, #0 + 8000c3e: 601a str r2, [r3, #0] + hpcd->IN_ep[i].xfer_len = 0U; + 8000c40: 183b adds r3, r7, r0 + 8000c42: 781a ldrb r2, [r3, #0] + 8000c44: 687b ldr r3, [r7, #4] + 8000c46: 3202 adds r2, #2 + 8000c48: 0152 lsls r2, r2, #5 + 8000c4a: 2100 movs r1, #0 + 8000c4c: 50d1 str r1, [r2, r3] + for (i = 0U; i < hpcd->Init.dev_endpoints; i++) + 8000c4e: 183b adds r3, r7, r0 + 8000c50: 781a ldrb r2, [r3, #0] + 8000c52: 183b adds r3, r7, r0 + 8000c54: 3201 adds r2, #1 + 8000c56: 701a strb r2, [r3, #0] + 8000c58: 230f movs r3, #15 + 8000c5a: 18fb adds r3, r7, r3 + 8000c5c: 781a ldrb r2, [r3, #0] + 8000c5e: 687b ldr r3, [r7, #4] + 8000c60: 685b ldr r3, [r3, #4] + 8000c62: 429a cmp r2, r3 + 8000c64: d3b4 bcc.n 8000bd0 + } + + for (i = 0U; i < hpcd->Init.dev_endpoints; i++) + 8000c66: 230f movs r3, #15 + 8000c68: 18fb adds r3, r7, r3 + 8000c6a: 2200 movs r2, #0 + 8000c6c: 701a strb r2, [r3, #0] + 8000c6e: e03f b.n 8000cf0 + { + hpcd->OUT_ep[i].is_in = 0U; + 8000c70: 200f movs r0, #15 + 8000c72: 183b adds r3, r7, r0 + 8000c74: 781a ldrb r2, [r3, #0] + 8000c76: 6879 ldr r1, [r7, #4] + 8000c78: 232a movs r3, #42 ; 0x2a + 8000c7a: 33ff adds r3, #255 ; 0xff + 8000c7c: 0152 lsls r2, r2, #5 + 8000c7e: 188a adds r2, r1, r2 + 8000c80: 18d3 adds r3, r2, r3 + 8000c82: 2200 movs r2, #0 + 8000c84: 701a strb r2, [r3, #0] + hpcd->OUT_ep[i].num = i; + 8000c86: 183b adds r3, r7, r0 + 8000c88: 781a ldrb r2, [r3, #0] + 8000c8a: 6879 ldr r1, [r7, #4] + 8000c8c: 2394 movs r3, #148 ; 0x94 + 8000c8e: 005b lsls r3, r3, #1 + 8000c90: 0152 lsls r2, r2, #5 + 8000c92: 188a adds r2, r1, r2 + 8000c94: 18d3 adds r3, r2, r3 + 8000c96: 183a adds r2, r7, r0 + 8000c98: 7812 ldrb r2, [r2, #0] + 8000c9a: 701a strb r2, [r3, #0] + /* Control until ep is activated */ + hpcd->OUT_ep[i].type = EP_TYPE_CTRL; + 8000c9c: 183b adds r3, r7, r0 + 8000c9e: 781a ldrb r2, [r3, #0] + 8000ca0: 6879 ldr r1, [r7, #4] + 8000ca2: 232c movs r3, #44 ; 0x2c + 8000ca4: 33ff adds r3, #255 ; 0xff + 8000ca6: 0152 lsls r2, r2, #5 + 8000ca8: 188a adds r2, r1, r2 + 8000caa: 18d3 adds r3, r2, r3 + 8000cac: 2200 movs r2, #0 + 8000cae: 701a strb r2, [r3, #0] + hpcd->OUT_ep[i].maxpacket = 0U; + 8000cb0: 183b adds r3, r7, r0 + 8000cb2: 781a ldrb r2, [r3, #0] + 8000cb4: 6879 ldr r1, [r7, #4] + 8000cb6: 239c movs r3, #156 ; 0x9c + 8000cb8: 005b lsls r3, r3, #1 + 8000cba: 0152 lsls r2, r2, #5 + 8000cbc: 188a adds r2, r1, r2 + 8000cbe: 18d3 adds r3, r2, r3 + 8000cc0: 2200 movs r2, #0 + 8000cc2: 601a str r2, [r3, #0] + hpcd->OUT_ep[i].xfer_buff = 0U; + 8000cc4: 183b adds r3, r7, r0 + 8000cc6: 781a ldrb r2, [r3, #0] + 8000cc8: 6879 ldr r1, [r7, #4] + 8000cca: 239e movs r3, #158 ; 0x9e + 8000ccc: 005b lsls r3, r3, #1 + 8000cce: 0152 lsls r2, r2, #5 + 8000cd0: 188a adds r2, r1, r2 + 8000cd2: 18d3 adds r3, r2, r3 + 8000cd4: 2200 movs r2, #0 + 8000cd6: 601a str r2, [r3, #0] + hpcd->OUT_ep[i].xfer_len = 0U; + 8000cd8: 183b adds r3, r7, r0 + 8000cda: 781a ldrb r2, [r3, #0] + 8000cdc: 687b ldr r3, [r7, #4] + 8000cde: 320a adds r2, #10 + 8000ce0: 0152 lsls r2, r2, #5 + 8000ce2: 2100 movs r1, #0 + 8000ce4: 50d1 str r1, [r2, r3] + for (i = 0U; i < hpcd->Init.dev_endpoints; i++) + 8000ce6: 183b adds r3, r7, r0 + 8000ce8: 781a ldrb r2, [r3, #0] + 8000cea: 183b adds r3, r7, r0 + 8000cec: 3201 adds r2, #1 + 8000cee: 701a strb r2, [r3, #0] + 8000cf0: 230f movs r3, #15 + 8000cf2: 18fb adds r3, r7, r3 + 8000cf4: 781a ldrb r2, [r3, #0] + 8000cf6: 687b ldr r3, [r7, #4] + 8000cf8: 685b ldr r3, [r3, #4] + 8000cfa: 429a cmp r2, r3 + 8000cfc: d3b8 bcc.n 8000c70 + } + + /* Init Device */ + (void)USB_DevInit(hpcd->Instance, hpcd->Init); + 8000cfe: 687b ldr r3, [r7, #4] + 8000d00: 6818 ldr r0, [r3, #0] + 8000d02: 687b ldr r3, [r7, #4] + 8000d04: 466a mov r2, sp + 8000d06: 0011 movs r1, r2 + 8000d08: 001a movs r2, r3 + 8000d0a: 3210 adds r2, #16 + 8000d0c: ca70 ldmia r2!, {r4, r5, r6} + 8000d0e: c170 stmia r1!, {r4, r5, r6} + 8000d10: ca30 ldmia r2!, {r4, r5} + 8000d12: c130 stmia r1!, {r4, r5} + 8000d14: 6859 ldr r1, [r3, #4] + 8000d16: 689a ldr r2, [r3, #8] + 8000d18: 68db ldr r3, [r3, #12] + 8000d1a: f001 fd6b bl 80027f4 + + hpcd->USB_Address = 0U; + 8000d1e: 687b ldr r3, [r7, #4] + 8000d20: 2224 movs r2, #36 ; 0x24 + 8000d22: 2100 movs r1, #0 + 8000d24: 5499 strb r1, [r3, r2] + hpcd->State = HAL_PCD_STATE_READY; + 8000d26: 687b ldr r3, [r7, #4] + 8000d28: 4a07 ldr r2, [pc, #28] ; (8000d48 ) + 8000d2a: 2101 movs r1, #1 + 8000d2c: 5499 strb r1, [r3, r2] + + /* Activate LPM */ + if (hpcd->Init.lpm_enable == 1U) + 8000d2e: 687b ldr r3, [r7, #4] + 8000d30: 69db ldr r3, [r3, #28] + 8000d32: 2b01 cmp r3, #1 + 8000d34: d103 bne.n 8000d3e + { + (void)HAL_PCDEx_ActivateLPM(hpcd); + 8000d36: 687b ldr r3, [r7, #4] + 8000d38: 0018 movs r0, r3 + 8000d3a: f000 ff0d bl 8001b58 + } + + return HAL_OK; + 8000d3e: 2300 movs r3, #0 +} + 8000d40: 0018 movs r0, r3 + 8000d42: 46bd mov sp, r7 + 8000d44: b005 add sp, #20 + 8000d46: bdf0 pop {r4, r5, r6, r7, pc} + 8000d48: 00000229 .word 0x00000229 + +08000d4c : + * @brief Start the USB device + * @param hpcd PCD handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_Start(PCD_HandleTypeDef *hpcd) +{ + 8000d4c: b580 push {r7, lr} + 8000d4e: b082 sub sp, #8 + 8000d50: af00 add r7, sp, #0 + 8000d52: 6078 str r0, [r7, #4] + __HAL_LOCK(hpcd); + 8000d54: 687a ldr r2, [r7, #4] + 8000d56: 238a movs r3, #138 ; 0x8a + 8000d58: 009b lsls r3, r3, #2 + 8000d5a: 5cd3 ldrb r3, [r2, r3] + 8000d5c: 2b01 cmp r3, #1 + 8000d5e: d101 bne.n 8000d64 + 8000d60: 2302 movs r3, #2 + 8000d62: e014 b.n 8000d8e + 8000d64: 687a ldr r2, [r7, #4] + 8000d66: 238a movs r3, #138 ; 0x8a + 8000d68: 009b lsls r3, r3, #2 + 8000d6a: 2101 movs r1, #1 + 8000d6c: 54d1 strb r1, [r2, r3] + (void)USB_DevConnect(hpcd->Instance); + 8000d6e: 687b ldr r3, [r7, #4] + 8000d70: 681b ldr r3, [r3, #0] + 8000d72: 0018 movs r0, r3 + 8000d74: f002 fd96 bl 80038a4 + __HAL_PCD_ENABLE(hpcd); + 8000d78: 687b ldr r3, [r7, #4] + 8000d7a: 681b ldr r3, [r3, #0] + 8000d7c: 0018 movs r0, r3 + 8000d7e: f001 fcff bl 8002780 + __HAL_UNLOCK(hpcd); + 8000d82: 687a ldr r2, [r7, #4] + 8000d84: 238a movs r3, #138 ; 0x8a + 8000d86: 009b lsls r3, r3, #2 + 8000d88: 2100 movs r1, #0 + 8000d8a: 54d1 strb r1, [r2, r3] + return HAL_OK; + 8000d8c: 2300 movs r3, #0 +} + 8000d8e: 0018 movs r0, r3 + 8000d90: 46bd mov sp, r7 + 8000d92: b002 add sp, #8 + 8000d94: bd80 pop {r7, pc} + ... + +08000d98 : + * @brief This function handles PCD interrupt request. + * @param hpcd PCD handle + * @retval HAL status + */ +void HAL_PCD_IRQHandler(PCD_HandleTypeDef *hpcd) +{ + 8000d98: b580 push {r7, lr} + 8000d9a: b082 sub sp, #8 + 8000d9c: af00 add r7, sp, #0 + 8000d9e: 6078 str r0, [r7, #4] + if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_CTR)) + 8000da0: 687b ldr r3, [r7, #4] + 8000da2: 681b ldr r3, [r3, #0] + 8000da4: 0018 movs r0, r3 + 8000da6: f002 fd93 bl 80038d0 + 8000daa: 0002 movs r2, r0 + 8000dac: 2380 movs r3, #128 ; 0x80 + 8000dae: 021b lsls r3, r3, #8 + 8000db0: 401a ands r2, r3 + 8000db2: 2380 movs r3, #128 ; 0x80 + 8000db4: 021b lsls r3, r3, #8 + 8000db6: 429a cmp r2, r3 + 8000db8: d103 bne.n 8000dc2 + { + /* servicing of the endpoint correct transfer interrupt */ + /* clear of the CTR flag into the sub */ + (void)PCD_EP_ISR_Handler(hpcd); + 8000dba: 687b ldr r3, [r7, #4] + 8000dbc: 0018 movs r0, r3 + 8000dbe: f000 fbaf bl 8001520 + } + + if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_RESET)) + 8000dc2: 687b ldr r3, [r7, #4] + 8000dc4: 681b ldr r3, [r3, #0] + 8000dc6: 0018 movs r0, r3 + 8000dc8: f002 fd82 bl 80038d0 + 8000dcc: 0002 movs r2, r0 + 8000dce: 2380 movs r3, #128 ; 0x80 + 8000dd0: 00db lsls r3, r3, #3 + 8000dd2: 401a ands r2, r3 + 8000dd4: 2380 movs r3, #128 ; 0x80 + 8000dd6: 00db lsls r3, r3, #3 + 8000dd8: 429a cmp r2, r3 + 8000dda: d114 bne.n 8000e06 + { + __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_RESET); + 8000ddc: 687b ldr r3, [r7, #4] + 8000dde: 681b ldr r3, [r3, #0] + 8000de0: 2244 movs r2, #68 ; 0x44 + 8000de2: 5a9b ldrh r3, [r3, r2] + 8000de4: b29a uxth r2, r3 + 8000de6: 687b ldr r3, [r7, #4] + 8000de8: 681b ldr r3, [r3, #0] + 8000dea: 49a8 ldr r1, [pc, #672] ; (800108c ) + 8000dec: 400a ands r2, r1 + 8000dee: b291 uxth r1, r2 + 8000df0: 2244 movs r2, #68 ; 0x44 + 8000df2: 5299 strh r1, [r3, r2] + +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) + hpcd->ResetCallback(hpcd); +#else + HAL_PCD_ResetCallback(hpcd); + 8000df4: 687b ldr r3, [r7, #4] + 8000df6: 0018 movs r0, r3 + 8000df8: f00d fb60 bl 800e4bc +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ + + (void)HAL_PCD_SetAddress(hpcd, 0U); + 8000dfc: 687b ldr r3, [r7, #4] + 8000dfe: 2100 movs r1, #0 + 8000e00: 0018 movs r0, r3 + 8000e02: f000 f951 bl 80010a8 + } + + if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_PMAOVR)) + 8000e06: 687b ldr r3, [r7, #4] + 8000e08: 681b ldr r3, [r3, #0] + 8000e0a: 0018 movs r0, r3 + 8000e0c: f002 fd60 bl 80038d0 + 8000e10: 0002 movs r2, r0 + 8000e12: 2380 movs r3, #128 ; 0x80 + 8000e14: 01db lsls r3, r3, #7 + 8000e16: 401a ands r2, r3 + 8000e18: 2380 movs r3, #128 ; 0x80 + 8000e1a: 01db lsls r3, r3, #7 + 8000e1c: 429a cmp r2, r3 + 8000e1e: d10b bne.n 8000e38 + { + __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_PMAOVR); + 8000e20: 687b ldr r3, [r7, #4] + 8000e22: 681b ldr r3, [r3, #0] + 8000e24: 2244 movs r2, #68 ; 0x44 + 8000e26: 5a9b ldrh r3, [r3, r2] + 8000e28: b29a uxth r2, r3 + 8000e2a: 687b ldr r3, [r7, #4] + 8000e2c: 681b ldr r3, [r3, #0] + 8000e2e: 4998 ldr r1, [pc, #608] ; (8001090 ) + 8000e30: 400a ands r2, r1 + 8000e32: b291 uxth r1, r2 + 8000e34: 2244 movs r2, #68 ; 0x44 + 8000e36: 5299 strh r1, [r3, r2] + } + + if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_ERR)) + 8000e38: 687b ldr r3, [r7, #4] + 8000e3a: 681b ldr r3, [r3, #0] + 8000e3c: 0018 movs r0, r3 + 8000e3e: f002 fd47 bl 80038d0 + 8000e42: 0002 movs r2, r0 + 8000e44: 2380 movs r3, #128 ; 0x80 + 8000e46: 019b lsls r3, r3, #6 + 8000e48: 401a ands r2, r3 + 8000e4a: 2380 movs r3, #128 ; 0x80 + 8000e4c: 019b lsls r3, r3, #6 + 8000e4e: 429a cmp r2, r3 + 8000e50: d10b bne.n 8000e6a + { + __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_ERR); + 8000e52: 687b ldr r3, [r7, #4] + 8000e54: 681b ldr r3, [r3, #0] + 8000e56: 2244 movs r2, #68 ; 0x44 + 8000e58: 5a9b ldrh r3, [r3, r2] + 8000e5a: b29a uxth r2, r3 + 8000e5c: 687b ldr r3, [r7, #4] + 8000e5e: 681b ldr r3, [r3, #0] + 8000e60: 498c ldr r1, [pc, #560] ; (8001094 ) + 8000e62: 400a ands r2, r1 + 8000e64: b291 uxth r1, r2 + 8000e66: 2244 movs r2, #68 ; 0x44 + 8000e68: 5299 strh r1, [r3, r2] + } + + if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_WKUP)) + 8000e6a: 687b ldr r3, [r7, #4] + 8000e6c: 681b ldr r3, [r3, #0] + 8000e6e: 0018 movs r0, r3 + 8000e70: f002 fd2e bl 80038d0 + 8000e74: 0002 movs r2, r0 + 8000e76: 2380 movs r3, #128 ; 0x80 + 8000e78: 015b lsls r3, r3, #5 + 8000e7a: 401a ands r2, r3 + 8000e7c: 2380 movs r3, #128 ; 0x80 + 8000e7e: 015b lsls r3, r3, #5 + 8000e80: 429a cmp r2, r3 + 8000e82: d137 bne.n 8000ef4 + { + hpcd->Instance->CNTR &= (uint16_t) ~(USB_CNTR_LPMODE); + 8000e84: 687b ldr r3, [r7, #4] + 8000e86: 681b ldr r3, [r3, #0] + 8000e88: 2240 movs r2, #64 ; 0x40 + 8000e8a: 5a9b ldrh r3, [r3, r2] + 8000e8c: b29a uxth r2, r3 + 8000e8e: 687b ldr r3, [r7, #4] + 8000e90: 681b ldr r3, [r3, #0] + 8000e92: 2104 movs r1, #4 + 8000e94: 438a bics r2, r1 + 8000e96: b291 uxth r1, r2 + 8000e98: 2240 movs r2, #64 ; 0x40 + 8000e9a: 5299 strh r1, [r3, r2] + hpcd->Instance->CNTR &= (uint16_t) ~(USB_CNTR_FSUSP); + 8000e9c: 687b ldr r3, [r7, #4] + 8000e9e: 681b ldr r3, [r3, #0] + 8000ea0: 2240 movs r2, #64 ; 0x40 + 8000ea2: 5a9b ldrh r3, [r3, r2] + 8000ea4: b29a uxth r2, r3 + 8000ea6: 687b ldr r3, [r7, #4] + 8000ea8: 681b ldr r3, [r3, #0] + 8000eaa: 2108 movs r1, #8 + 8000eac: 438a bics r2, r1 + 8000eae: b291 uxth r1, r2 + 8000eb0: 2240 movs r2, #64 ; 0x40 + 8000eb2: 5299 strh r1, [r3, r2] + + if (hpcd->LPM_State == LPM_L1) + 8000eb4: 687a ldr r2, [r7, #4] + 8000eb6: 2398 movs r3, #152 ; 0x98 + 8000eb8: 009b lsls r3, r3, #2 + 8000eba: 5cd3 ldrb r3, [r2, r3] + 8000ebc: 2b01 cmp r3, #1 + 8000ebe: d109 bne.n 8000ed4 + { + hpcd->LPM_State = LPM_L0; + 8000ec0: 687a ldr r2, [r7, #4] + 8000ec2: 2398 movs r3, #152 ; 0x98 + 8000ec4: 009b lsls r3, r3, #2 + 8000ec6: 2100 movs r1, #0 + 8000ec8: 54d1 strb r1, [r2, r3] +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) + hpcd->LPMCallback(hpcd, PCD_LPM_L0_ACTIVE); +#else + HAL_PCDEx_LPM_Callback(hpcd, PCD_LPM_L0_ACTIVE); + 8000eca: 687b ldr r3, [r7, #4] + 8000ecc: 2100 movs r1, #0 + 8000ece: 0018 movs r0, r3 + 8000ed0: f000 fe6c bl 8001bac + } + +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) + hpcd->ResumeCallback(hpcd); +#else + HAL_PCD_ResumeCallback(hpcd); + 8000ed4: 687b ldr r3, [r7, #4] + 8000ed6: 0018 movs r0, r3 + 8000ed8: f00d fb0f bl 800e4fa +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ + + __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_WKUP); + 8000edc: 687b ldr r3, [r7, #4] + 8000ede: 681b ldr r3, [r3, #0] + 8000ee0: 2244 movs r2, #68 ; 0x44 + 8000ee2: 5a9b ldrh r3, [r3, r2] + 8000ee4: b29a uxth r2, r3 + 8000ee6: 687b ldr r3, [r7, #4] + 8000ee8: 681b ldr r3, [r3, #0] + 8000eea: 496b ldr r1, [pc, #428] ; (8001098 ) + 8000eec: 400a ands r2, r1 + 8000eee: b291 uxth r1, r2 + 8000ef0: 2244 movs r2, #68 ; 0x44 + 8000ef2: 5299 strh r1, [r3, r2] + } + + if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_SUSP)) + 8000ef4: 687b ldr r3, [r7, #4] + 8000ef6: 681b ldr r3, [r3, #0] + 8000ef8: 0018 movs r0, r3 + 8000efa: f002 fce9 bl 80038d0 + 8000efe: 0002 movs r2, r0 + 8000f00: 2380 movs r3, #128 ; 0x80 + 8000f02: 011b lsls r3, r3, #4 + 8000f04: 401a ands r2, r3 + 8000f06: 2380 movs r3, #128 ; 0x80 + 8000f08: 011b lsls r3, r3, #4 + 8000f0a: 429a cmp r2, r3 + 8000f0c: d134 bne.n 8000f78 + { + /* Force low-power mode in the macrocell */ + hpcd->Instance->CNTR |= USB_CNTR_FSUSP; + 8000f0e: 687b ldr r3, [r7, #4] + 8000f10: 681b ldr r3, [r3, #0] + 8000f12: 2240 movs r2, #64 ; 0x40 + 8000f14: 5a9b ldrh r3, [r3, r2] + 8000f16: b29a uxth r2, r3 + 8000f18: 687b ldr r3, [r7, #4] + 8000f1a: 681b ldr r3, [r3, #0] + 8000f1c: 2108 movs r1, #8 + 8000f1e: 430a orrs r2, r1 + 8000f20: b291 uxth r1, r2 + 8000f22: 2240 movs r2, #64 ; 0x40 + 8000f24: 5299 strh r1, [r3, r2] + + /* clear of the ISTR bit must be done after setting of CNTR_FSUSP */ + __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_SUSP); + 8000f26: 687b ldr r3, [r7, #4] + 8000f28: 681b ldr r3, [r3, #0] + 8000f2a: 2244 movs r2, #68 ; 0x44 + 8000f2c: 5a9b ldrh r3, [r3, r2] + 8000f2e: b29a uxth r2, r3 + 8000f30: 687b ldr r3, [r7, #4] + 8000f32: 681b ldr r3, [r3, #0] + 8000f34: 4959 ldr r1, [pc, #356] ; (800109c ) + 8000f36: 400a ands r2, r1 + 8000f38: b291 uxth r1, r2 + 8000f3a: 2244 movs r2, #68 ; 0x44 + 8000f3c: 5299 strh r1, [r3, r2] + + hpcd->Instance->CNTR |= USB_CNTR_LPMODE; + 8000f3e: 687b ldr r3, [r7, #4] + 8000f40: 681b ldr r3, [r3, #0] + 8000f42: 2240 movs r2, #64 ; 0x40 + 8000f44: 5a9b ldrh r3, [r3, r2] + 8000f46: b29a uxth r2, r3 + 8000f48: 687b ldr r3, [r7, #4] + 8000f4a: 681b ldr r3, [r3, #0] + 8000f4c: 2104 movs r1, #4 + 8000f4e: 430a orrs r2, r1 + 8000f50: b291 uxth r1, r2 + 8000f52: 2240 movs r2, #64 ; 0x40 + 8000f54: 5299 strh r1, [r3, r2] + + if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_WKUP) == 0U) + 8000f56: 687b ldr r3, [r7, #4] + 8000f58: 681b ldr r3, [r3, #0] + 8000f5a: 0018 movs r0, r3 + 8000f5c: f002 fcb8 bl 80038d0 + 8000f60: 0002 movs r2, r0 + 8000f62: 2380 movs r3, #128 ; 0x80 + 8000f64: 015b lsls r3, r3, #5 + 8000f66: 401a ands r2, r3 + 8000f68: 2380 movs r3, #128 ; 0x80 + 8000f6a: 015b lsls r3, r3, #5 + 8000f6c: 429a cmp r2, r3 + 8000f6e: d003 beq.n 8000f78 + { +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) + hpcd->SuspendCallback(hpcd); +#else + HAL_PCD_SuspendCallback(hpcd); + 8000f70: 687b ldr r3, [r7, #4] + 8000f72: 0018 movs r0, r3 + 8000f74: f00d fab9 bl 800e4ea +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ + } + } + + /* Handle LPM Interrupt */ + if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_L1REQ)) + 8000f78: 687b ldr r3, [r7, #4] + 8000f7a: 681b ldr r3, [r3, #0] + 8000f7c: 0018 movs r0, r3 + 8000f7e: f002 fca7 bl 80038d0 + 8000f82: 0002 movs r2, r0 + 8000f84: 2380 movs r3, #128 ; 0x80 + 8000f86: 4013 ands r3, r2 + 8000f88: 2b80 cmp r3, #128 ; 0x80 + 8000f8a: d145 bne.n 8001018 + { + __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_L1REQ); + 8000f8c: 687b ldr r3, [r7, #4] + 8000f8e: 681b ldr r3, [r3, #0] + 8000f90: 2244 movs r2, #68 ; 0x44 + 8000f92: 5a9b ldrh r3, [r3, r2] + 8000f94: b29a uxth r2, r3 + 8000f96: 687b ldr r3, [r7, #4] + 8000f98: 681b ldr r3, [r3, #0] + 8000f9a: 2180 movs r1, #128 ; 0x80 + 8000f9c: 438a bics r2, r1 + 8000f9e: b291 uxth r1, r2 + 8000fa0: 2244 movs r2, #68 ; 0x44 + 8000fa2: 5299 strh r1, [r3, r2] + if (hpcd->LPM_State == LPM_L0) + 8000fa4: 687a ldr r2, [r7, #4] + 8000fa6: 2398 movs r3, #152 ; 0x98 + 8000fa8: 009b lsls r3, r3, #2 + 8000faa: 5cd3 ldrb r3, [r2, r3] + 8000fac: 2b00 cmp r3, #0 + 8000fae: d12f bne.n 8001010 + { + /* Force suspend and low-power mode before going to L1 state*/ + hpcd->Instance->CNTR |= USB_CNTR_LPMODE; + 8000fb0: 687b ldr r3, [r7, #4] + 8000fb2: 681b ldr r3, [r3, #0] + 8000fb4: 2240 movs r2, #64 ; 0x40 + 8000fb6: 5a9b ldrh r3, [r3, r2] + 8000fb8: b29a uxth r2, r3 + 8000fba: 687b ldr r3, [r7, #4] + 8000fbc: 681b ldr r3, [r3, #0] + 8000fbe: 2104 movs r1, #4 + 8000fc0: 430a orrs r2, r1 + 8000fc2: b291 uxth r1, r2 + 8000fc4: 2240 movs r2, #64 ; 0x40 + 8000fc6: 5299 strh r1, [r3, r2] + hpcd->Instance->CNTR |= USB_CNTR_FSUSP; + 8000fc8: 687b ldr r3, [r7, #4] + 8000fca: 681b ldr r3, [r3, #0] + 8000fcc: 2240 movs r2, #64 ; 0x40 + 8000fce: 5a9b ldrh r3, [r3, r2] + 8000fd0: b29a uxth r2, r3 + 8000fd2: 687b ldr r3, [r7, #4] + 8000fd4: 681b ldr r3, [r3, #0] + 8000fd6: 2108 movs r1, #8 + 8000fd8: 430a orrs r2, r1 + 8000fda: b291 uxth r1, r2 + 8000fdc: 2240 movs r2, #64 ; 0x40 + 8000fde: 5299 strh r1, [r3, r2] + + hpcd->LPM_State = LPM_L1; + 8000fe0: 687a ldr r2, [r7, #4] + 8000fe2: 2398 movs r3, #152 ; 0x98 + 8000fe4: 009b lsls r3, r3, #2 + 8000fe6: 2101 movs r1, #1 + 8000fe8: 54d1 strb r1, [r2, r3] + hpcd->BESL = ((uint32_t)hpcd->Instance->LPMCSR & USB_LPMCSR_BESL) >> 2; + 8000fea: 687b ldr r3, [r7, #4] + 8000fec: 681b ldr r3, [r3, #0] + 8000fee: 2254 movs r2, #84 ; 0x54 + 8000ff0: 5a9b ldrh r3, [r3, r2] + 8000ff2: b29b uxth r3, r3 + 8000ff4: 089b lsrs r3, r3, #2 + 8000ff6: 223c movs r2, #60 ; 0x3c + 8000ff8: 4013 ands r3, r2 + 8000ffa: 0019 movs r1, r3 + 8000ffc: 687a ldr r2, [r7, #4] + 8000ffe: 2399 movs r3, #153 ; 0x99 + 8001000: 009b lsls r3, r3, #2 + 8001002: 50d1 str r1, [r2, r3] +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) + hpcd->LPMCallback(hpcd, PCD_LPM_L1_ACTIVE); +#else + HAL_PCDEx_LPM_Callback(hpcd, PCD_LPM_L1_ACTIVE); + 8001004: 687b ldr r3, [r7, #4] + 8001006: 2101 movs r1, #1 + 8001008: 0018 movs r0, r3 + 800100a: f000 fdcf bl 8001bac + 800100e: e003 b.n 8001018 + else + { +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) + hpcd->SuspendCallback(hpcd); +#else + HAL_PCD_SuspendCallback(hpcd); + 8001010: 687b ldr r3, [r7, #4] + 8001012: 0018 movs r0, r3 + 8001014: f00d fa69 bl 800e4ea +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ + } + } + + if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_SOF)) + 8001018: 687b ldr r3, [r7, #4] + 800101a: 681b ldr r3, [r3, #0] + 800101c: 0018 movs r0, r3 + 800101e: f002 fc57 bl 80038d0 + 8001022: 0002 movs r2, r0 + 8001024: 2380 movs r3, #128 ; 0x80 + 8001026: 009b lsls r3, r3, #2 + 8001028: 401a ands r2, r3 + 800102a: 2380 movs r3, #128 ; 0x80 + 800102c: 009b lsls r3, r3, #2 + 800102e: 429a cmp r2, r3 + 8001030: d10f bne.n 8001052 + { + __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_SOF); + 8001032: 687b ldr r3, [r7, #4] + 8001034: 681b ldr r3, [r3, #0] + 8001036: 2244 movs r2, #68 ; 0x44 + 8001038: 5a9b ldrh r3, [r3, r2] + 800103a: b29a uxth r2, r3 + 800103c: 687b ldr r3, [r7, #4] + 800103e: 681b ldr r3, [r3, #0] + 8001040: 4917 ldr r1, [pc, #92] ; (80010a0 ) + 8001042: 400a ands r2, r1 + 8001044: b291 uxth r1, r2 + 8001046: 2244 movs r2, #68 ; 0x44 + 8001048: 5299 strh r1, [r3, r2] + +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) + hpcd->SOFCallback(hpcd); +#else + HAL_PCD_SOFCallback(hpcd); + 800104a: 687b ldr r3, [r7, #4] + 800104c: 0018 movs r0, r3 + 800104e: f00d fa26 bl 800e49e +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ + } + + if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_ESOF)) + 8001052: 687b ldr r3, [r7, #4] + 8001054: 681b ldr r3, [r3, #0] + 8001056: 0018 movs r0, r3 + 8001058: f002 fc3a bl 80038d0 + 800105c: 0002 movs r2, r0 + 800105e: 2380 movs r3, #128 ; 0x80 + 8001060: 005b lsls r3, r3, #1 + 8001062: 401a ands r2, r3 + 8001064: 2380 movs r3, #128 ; 0x80 + 8001066: 005b lsls r3, r3, #1 + 8001068: 429a cmp r2, r3 + 800106a: d10b bne.n 8001084 + { + /* clear ESOF flag in ISTR */ + __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_ESOF); + 800106c: 687b ldr r3, [r7, #4] + 800106e: 681b ldr r3, [r3, #0] + 8001070: 2244 movs r2, #68 ; 0x44 + 8001072: 5a9b ldrh r3, [r3, r2] + 8001074: b29a uxth r2, r3 + 8001076: 687b ldr r3, [r7, #4] + 8001078: 681b ldr r3, [r3, #0] + 800107a: 490a ldr r1, [pc, #40] ; (80010a4 ) + 800107c: 400a ands r2, r1 + 800107e: b291 uxth r1, r2 + 8001080: 2244 movs r2, #68 ; 0x44 + 8001082: 5299 strh r1, [r3, r2] + } +} + 8001084: 46c0 nop ; (mov r8, r8) + 8001086: 46bd mov sp, r7 + 8001088: b002 add sp, #8 + 800108a: bd80 pop {r7, pc} + 800108c: fffffbff .word 0xfffffbff + 8001090: ffffbfff .word 0xffffbfff + 8001094: ffffdfff .word 0xffffdfff + 8001098: ffffefff .word 0xffffefff + 800109c: fffff7ff .word 0xfffff7ff + 80010a0: fffffdff .word 0xfffffdff + 80010a4: fffffeff .word 0xfffffeff + +080010a8 : + * @param hpcd PCD handle + * @param address new device address + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_SetAddress(PCD_HandleTypeDef *hpcd, uint8_t address) +{ + 80010a8: b580 push {r7, lr} + 80010aa: b082 sub sp, #8 + 80010ac: af00 add r7, sp, #0 + 80010ae: 6078 str r0, [r7, #4] + 80010b0: 000a movs r2, r1 + 80010b2: 1cfb adds r3, r7, #3 + 80010b4: 701a strb r2, [r3, #0] + __HAL_LOCK(hpcd); + 80010b6: 687a ldr r2, [r7, #4] + 80010b8: 238a movs r3, #138 ; 0x8a + 80010ba: 009b lsls r3, r3, #2 + 80010bc: 5cd3 ldrb r3, [r2, r3] + 80010be: 2b01 cmp r3, #1 + 80010c0: d101 bne.n 80010c6 + 80010c2: 2302 movs r3, #2 + 80010c4: e017 b.n 80010f6 + 80010c6: 687a ldr r2, [r7, #4] + 80010c8: 238a movs r3, #138 ; 0x8a + 80010ca: 009b lsls r3, r3, #2 + 80010cc: 2101 movs r1, #1 + 80010ce: 54d1 strb r1, [r2, r3] + hpcd->USB_Address = address; + 80010d0: 687b ldr r3, [r7, #4] + 80010d2: 1cfa adds r2, r7, #3 + 80010d4: 2124 movs r1, #36 ; 0x24 + 80010d6: 7812 ldrb r2, [r2, #0] + 80010d8: 545a strb r2, [r3, r1] + (void)USB_SetDevAddress(hpcd->Instance, address); + 80010da: 687b ldr r3, [r7, #4] + 80010dc: 681a ldr r2, [r3, #0] + 80010de: 1cfb adds r3, r7, #3 + 80010e0: 781b ldrb r3, [r3, #0] + 80010e2: 0019 movs r1, r3 + 80010e4: 0010 movs r0, r2 + 80010e6: f002 fbc9 bl 800387c + __HAL_UNLOCK(hpcd); + 80010ea: 687a ldr r2, [r7, #4] + 80010ec: 238a movs r3, #138 ; 0x8a + 80010ee: 009b lsls r3, r3, #2 + 80010f0: 2100 movs r1, #0 + 80010f2: 54d1 strb r1, [r2, r3] + return HAL_OK; + 80010f4: 2300 movs r3, #0 +} + 80010f6: 0018 movs r0, r3 + 80010f8: 46bd mov sp, r7 + 80010fa: b002 add sp, #8 + 80010fc: bd80 pop {r7, pc} + +080010fe : + * @param ep_mps endpoint max packet size + * @param ep_type endpoint type + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_EP_Open(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint16_t ep_mps, uint8_t ep_type) +{ + 80010fe: b590 push {r4, r7, lr} + 8001100: b085 sub sp, #20 + 8001102: af00 add r7, sp, #0 + 8001104: 6078 str r0, [r7, #4] + 8001106: 000c movs r4, r1 + 8001108: 0010 movs r0, r2 + 800110a: 0019 movs r1, r3 + 800110c: 1cfb adds r3, r7, #3 + 800110e: 1c22 adds r2, r4, #0 + 8001110: 701a strb r2, [r3, #0] + 8001112: 003b movs r3, r7 + 8001114: 1c02 adds r2, r0, #0 + 8001116: 801a strh r2, [r3, #0] + 8001118: 1cbb adds r3, r7, #2 + 800111a: 1c0a adds r2, r1, #0 + 800111c: 701a strb r2, [r3, #0] + HAL_StatusTypeDef ret = HAL_OK; + 800111e: 230b movs r3, #11 + 8001120: 18fb adds r3, r7, r3 + 8001122: 2200 movs r2, #0 + 8001124: 701a strb r2, [r3, #0] + PCD_EPTypeDef *ep; + + if ((ep_addr & 0x80U) == 0x80U) + 8001126: 1cfb adds r3, r7, #3 + 8001128: 781b ldrb r3, [r3, #0] + 800112a: b25b sxtb r3, r3 + 800112c: 2b00 cmp r3, #0 + 800112e: da0c bge.n 800114a + { + ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK]; + 8001130: 1cfb adds r3, r7, #3 + 8001132: 781b ldrb r3, [r3, #0] + 8001134: 2207 movs r2, #7 + 8001136: 4013 ands r3, r2 + 8001138: 015b lsls r3, r3, #5 + 800113a: 3328 adds r3, #40 ; 0x28 + 800113c: 687a ldr r2, [r7, #4] + 800113e: 18d3 adds r3, r2, r3 + 8001140: 60fb str r3, [r7, #12] + ep->is_in = 1U; + 8001142: 68fb ldr r3, [r7, #12] + 8001144: 2201 movs r2, #1 + 8001146: 705a strb r2, [r3, #1] + 8001148: e00c b.n 8001164 + } + else + { + ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK]; + 800114a: 1cfb adds r3, r7, #3 + 800114c: 781b ldrb r3, [r3, #0] + 800114e: 2207 movs r2, #7 + 8001150: 4013 ands r3, r2 + 8001152: 015b lsls r3, r3, #5 + 8001154: 3329 adds r3, #41 ; 0x29 + 8001156: 33ff adds r3, #255 ; 0xff + 8001158: 687a ldr r2, [r7, #4] + 800115a: 18d3 adds r3, r2, r3 + 800115c: 60fb str r3, [r7, #12] + ep->is_in = 0U; + 800115e: 68fb ldr r3, [r7, #12] + 8001160: 2200 movs r2, #0 + 8001162: 705a strb r2, [r3, #1] + } + + ep->num = ep_addr & EP_ADDR_MSK; + 8001164: 1cfb adds r3, r7, #3 + 8001166: 781b ldrb r3, [r3, #0] + 8001168: 2207 movs r2, #7 + 800116a: 4013 ands r3, r2 + 800116c: b2da uxtb r2, r3 + 800116e: 68fb ldr r3, [r7, #12] + 8001170: 701a strb r2, [r3, #0] + ep->maxpacket = ep_mps; + 8001172: 003b movs r3, r7 + 8001174: 881a ldrh r2, [r3, #0] + 8001176: 68fb ldr r3, [r7, #12] + 8001178: 611a str r2, [r3, #16] + ep->type = ep_type; + 800117a: 68fb ldr r3, [r7, #12] + 800117c: 1cba adds r2, r7, #2 + 800117e: 7812 ldrb r2, [r2, #0] + 8001180: 70da strb r2, [r3, #3] + + if (ep->is_in != 0U) + 8001182: 68fb ldr r3, [r7, #12] + 8001184: 785b ldrb r3, [r3, #1] + 8001186: 2b00 cmp r3, #0 + 8001188: d004 beq.n 8001194 + { + /* Assign a Tx FIFO */ + ep->tx_fifo_num = ep->num; + 800118a: 68fb ldr r3, [r7, #12] + 800118c: 781b ldrb r3, [r3, #0] + 800118e: b29a uxth r2, r3 + 8001190: 68fb ldr r3, [r7, #12] + 8001192: 81da strh r2, [r3, #14] + } + /* Set initial data PID. */ + if (ep_type == EP_TYPE_BULK) + 8001194: 1cbb adds r3, r7, #2 + 8001196: 781b ldrb r3, [r3, #0] + 8001198: 2b02 cmp r3, #2 + 800119a: d102 bne.n 80011a2 + { + ep->data_pid_start = 0U; + 800119c: 68fb ldr r3, [r7, #12] + 800119e: 2200 movs r2, #0 + 80011a0: 711a strb r2, [r3, #4] + } + + __HAL_LOCK(hpcd); + 80011a2: 687a ldr r2, [r7, #4] + 80011a4: 238a movs r3, #138 ; 0x8a + 80011a6: 009b lsls r3, r3, #2 + 80011a8: 5cd3 ldrb r3, [r2, r3] + 80011aa: 2b01 cmp r3, #1 + 80011ac: d101 bne.n 80011b2 + 80011ae: 2302 movs r3, #2 + 80011b0: e013 b.n 80011da + 80011b2: 687a ldr r2, [r7, #4] + 80011b4: 238a movs r3, #138 ; 0x8a + 80011b6: 009b lsls r3, r3, #2 + 80011b8: 2101 movs r1, #1 + 80011ba: 54d1 strb r1, [r2, r3] + (void)USB_ActivateEndpoint(hpcd->Instance, ep); + 80011bc: 687b ldr r3, [r7, #4] + 80011be: 681b ldr r3, [r3, #0] + 80011c0: 68fa ldr r2, [r7, #12] + 80011c2: 0011 movs r1, r2 + 80011c4: 0018 movs r0, r3 + 80011c6: f001 fb45 bl 8002854 + __HAL_UNLOCK(hpcd); + 80011ca: 687a ldr r2, [r7, #4] + 80011cc: 238a movs r3, #138 ; 0x8a + 80011ce: 009b lsls r3, r3, #2 + 80011d0: 2100 movs r1, #0 + 80011d2: 54d1 strb r1, [r2, r3] + + return ret; + 80011d4: 230b movs r3, #11 + 80011d6: 18fb adds r3, r7, r3 + 80011d8: 781b ldrb r3, [r3, #0] +} + 80011da: 0018 movs r0, r3 + 80011dc: 46bd mov sp, r7 + 80011de: b005 add sp, #20 + 80011e0: bd90 pop {r4, r7, pc} + +080011e2 : + * @param hpcd PCD handle + * @param ep_addr endpoint address + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_EP_Close(PCD_HandleTypeDef *hpcd, uint8_t ep_addr) +{ + 80011e2: b580 push {r7, lr} + 80011e4: b084 sub sp, #16 + 80011e6: af00 add r7, sp, #0 + 80011e8: 6078 str r0, [r7, #4] + 80011ea: 000a movs r2, r1 + 80011ec: 1cfb adds r3, r7, #3 + 80011ee: 701a strb r2, [r3, #0] + PCD_EPTypeDef *ep; + + if ((ep_addr & 0x80U) == 0x80U) + 80011f0: 1cfb adds r3, r7, #3 + 80011f2: 781b ldrb r3, [r3, #0] + 80011f4: b25b sxtb r3, r3 + 80011f6: 2b00 cmp r3, #0 + 80011f8: da0c bge.n 8001214 + { + ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK]; + 80011fa: 1cfb adds r3, r7, #3 + 80011fc: 781b ldrb r3, [r3, #0] + 80011fe: 2207 movs r2, #7 + 8001200: 4013 ands r3, r2 + 8001202: 015b lsls r3, r3, #5 + 8001204: 3328 adds r3, #40 ; 0x28 + 8001206: 687a ldr r2, [r7, #4] + 8001208: 18d3 adds r3, r2, r3 + 800120a: 60fb str r3, [r7, #12] + ep->is_in = 1U; + 800120c: 68fb ldr r3, [r7, #12] + 800120e: 2201 movs r2, #1 + 8001210: 705a strb r2, [r3, #1] + 8001212: e00c b.n 800122e + } + else + { + ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK]; + 8001214: 1cfb adds r3, r7, #3 + 8001216: 781b ldrb r3, [r3, #0] + 8001218: 2207 movs r2, #7 + 800121a: 4013 ands r3, r2 + 800121c: 015b lsls r3, r3, #5 + 800121e: 3329 adds r3, #41 ; 0x29 + 8001220: 33ff adds r3, #255 ; 0xff + 8001222: 687a ldr r2, [r7, #4] + 8001224: 18d3 adds r3, r2, r3 + 8001226: 60fb str r3, [r7, #12] + ep->is_in = 0U; + 8001228: 68fb ldr r3, [r7, #12] + 800122a: 2200 movs r2, #0 + 800122c: 705a strb r2, [r3, #1] + } + ep->num = ep_addr & EP_ADDR_MSK; + 800122e: 1cfb adds r3, r7, #3 + 8001230: 781b ldrb r3, [r3, #0] + 8001232: 2207 movs r2, #7 + 8001234: 4013 ands r3, r2 + 8001236: b2da uxtb r2, r3 + 8001238: 68fb ldr r3, [r7, #12] + 800123a: 701a strb r2, [r3, #0] + + __HAL_LOCK(hpcd); + 800123c: 687a ldr r2, [r7, #4] + 800123e: 238a movs r3, #138 ; 0x8a + 8001240: 009b lsls r3, r3, #2 + 8001242: 5cd3 ldrb r3, [r2, r3] + 8001244: 2b01 cmp r3, #1 + 8001246: d101 bne.n 800124c + 8001248: 2302 movs r3, #2 + 800124a: e011 b.n 8001270 + 800124c: 687a ldr r2, [r7, #4] + 800124e: 238a movs r3, #138 ; 0x8a + 8001250: 009b lsls r3, r3, #2 + 8001252: 2101 movs r1, #1 + 8001254: 54d1 strb r1, [r2, r3] + (void)USB_DeactivateEndpoint(hpcd->Instance, ep); + 8001256: 687b ldr r3, [r7, #4] + 8001258: 681b ldr r3, [r3, #0] + 800125a: 68fa ldr r2, [r7, #12] + 800125c: 0011 movs r1, r2 + 800125e: 0018 movs r0, r3 + 8001260: f001 fdf0 bl 8002e44 + __HAL_UNLOCK(hpcd); + 8001264: 687a ldr r2, [r7, #4] + 8001266: 238a movs r3, #138 ; 0x8a + 8001268: 009b lsls r3, r3, #2 + 800126a: 2100 movs r1, #0 + 800126c: 54d1 strb r1, [r2, r3] + return HAL_OK; + 800126e: 2300 movs r3, #0 +} + 8001270: 0018 movs r0, r3 + 8001272: 46bd mov sp, r7 + 8001274: b004 add sp, #16 + 8001276: bd80 pop {r7, pc} + +08001278 : + * @param pBuf pointer to the reception buffer + * @param len amount of data to be received + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_EP_Receive(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len) +{ + 8001278: b580 push {r7, lr} + 800127a: b086 sub sp, #24 + 800127c: af00 add r7, sp, #0 + 800127e: 60f8 str r0, [r7, #12] + 8001280: 607a str r2, [r7, #4] + 8001282: 603b str r3, [r7, #0] + 8001284: 200b movs r0, #11 + 8001286: 183b adds r3, r7, r0 + 8001288: 1c0a adds r2, r1, #0 + 800128a: 701a strb r2, [r3, #0] + PCD_EPTypeDef *ep; + + ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK]; + 800128c: 0001 movs r1, r0 + 800128e: 187b adds r3, r7, r1 + 8001290: 781b ldrb r3, [r3, #0] + 8001292: 2207 movs r2, #7 + 8001294: 4013 ands r3, r2 + 8001296: 015b lsls r3, r3, #5 + 8001298: 3329 adds r3, #41 ; 0x29 + 800129a: 33ff adds r3, #255 ; 0xff + 800129c: 68fa ldr r2, [r7, #12] + 800129e: 18d3 adds r3, r2, r3 + 80012a0: 617b str r3, [r7, #20] + + /*setup and start the Xfer */ + ep->xfer_buff = pBuf; + 80012a2: 697b ldr r3, [r7, #20] + 80012a4: 687a ldr r2, [r7, #4] + 80012a6: 615a str r2, [r3, #20] + ep->xfer_len = len; + 80012a8: 697b ldr r3, [r7, #20] + 80012aa: 683a ldr r2, [r7, #0] + 80012ac: 619a str r2, [r3, #24] + ep->xfer_count = 0U; + 80012ae: 697b ldr r3, [r7, #20] + 80012b0: 2200 movs r2, #0 + 80012b2: 61da str r2, [r3, #28] + ep->is_in = 0U; + 80012b4: 697b ldr r3, [r7, #20] + 80012b6: 2200 movs r2, #0 + 80012b8: 705a strb r2, [r3, #1] + ep->num = ep_addr & EP_ADDR_MSK; + 80012ba: 187b adds r3, r7, r1 + 80012bc: 781b ldrb r3, [r3, #0] + 80012be: 2207 movs r2, #7 + 80012c0: 4013 ands r3, r2 + 80012c2: b2da uxtb r2, r3 + 80012c4: 697b ldr r3, [r7, #20] + 80012c6: 701a strb r2, [r3, #0] + + if ((ep_addr & EP_ADDR_MSK) == 0U) + 80012c8: 187b adds r3, r7, r1 + 80012ca: 781b ldrb r3, [r3, #0] + 80012cc: 2207 movs r2, #7 + 80012ce: 4013 ands r3, r2 + 80012d0: d107 bne.n 80012e2 + { + (void)USB_EP0StartXfer(hpcd->Instance, ep); + 80012d2: 68fb ldr r3, [r7, #12] + 80012d4: 681b ldr r3, [r3, #0] + 80012d6: 697a ldr r2, [r7, #20] + 80012d8: 0011 movs r1, r2 + 80012da: 0018 movs r0, r3 + 80012dc: f001 ff28 bl 8003130 + 80012e0: e006 b.n 80012f0 + } + else + { + (void)USB_EPStartXfer(hpcd->Instance, ep); + 80012e2: 68fb ldr r3, [r7, #12] + 80012e4: 681b ldr r3, [r3, #0] + 80012e6: 697a ldr r2, [r7, #20] + 80012e8: 0011 movs r1, r2 + 80012ea: 0018 movs r0, r3 + 80012ec: f001 ff20 bl 8003130 + } + + return HAL_OK; + 80012f0: 2300 movs r3, #0 +} + 80012f2: 0018 movs r0, r3 + 80012f4: 46bd mov sp, r7 + 80012f6: b006 add sp, #24 + 80012f8: bd80 pop {r7, pc} + +080012fa : + * @param hpcd PCD handle + * @param ep_addr endpoint address + * @retval Data Size + */ +uint32_t HAL_PCD_EP_GetRxCount(PCD_HandleTypeDef *hpcd, uint8_t ep_addr) +{ + 80012fa: b580 push {r7, lr} + 80012fc: b082 sub sp, #8 + 80012fe: af00 add r7, sp, #0 + 8001300: 6078 str r0, [r7, #4] + 8001302: 000a movs r2, r1 + 8001304: 1cfb adds r3, r7, #3 + 8001306: 701a strb r2, [r3, #0] + return hpcd->OUT_ep[ep_addr & EP_ADDR_MSK].xfer_count; + 8001308: 1cfb adds r3, r7, #3 + 800130a: 781b ldrb r3, [r3, #0] + 800130c: 2207 movs r2, #7 + 800130e: 4013 ands r3, r2 + 8001310: 687a ldr r2, [r7, #4] + 8001312: 330a adds r3, #10 + 8001314: 015b lsls r3, r3, #5 + 8001316: 18d3 adds r3, r2, r3 + 8001318: 3304 adds r3, #4 + 800131a: 681b ldr r3, [r3, #0] +} + 800131c: 0018 movs r0, r3 + 800131e: 46bd mov sp, r7 + 8001320: b002 add sp, #8 + 8001322: bd80 pop {r7, pc} + +08001324 : + * @param pBuf pointer to the transmission buffer + * @param len amount of data to be sent + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_EP_Transmit(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len) +{ + 8001324: b580 push {r7, lr} + 8001326: b086 sub sp, #24 + 8001328: af00 add r7, sp, #0 + 800132a: 60f8 str r0, [r7, #12] + 800132c: 607a str r2, [r7, #4] + 800132e: 603b str r3, [r7, #0] + 8001330: 200b movs r0, #11 + 8001332: 183b adds r3, r7, r0 + 8001334: 1c0a adds r2, r1, #0 + 8001336: 701a strb r2, [r3, #0] + PCD_EPTypeDef *ep; + + ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK]; + 8001338: 0001 movs r1, r0 + 800133a: 187b adds r3, r7, r1 + 800133c: 781b ldrb r3, [r3, #0] + 800133e: 2207 movs r2, #7 + 8001340: 4013 ands r3, r2 + 8001342: 015b lsls r3, r3, #5 + 8001344: 3328 adds r3, #40 ; 0x28 + 8001346: 68fa ldr r2, [r7, #12] + 8001348: 18d3 adds r3, r2, r3 + 800134a: 617b str r3, [r7, #20] + + /*setup and start the Xfer */ + ep->xfer_buff = pBuf; + 800134c: 697b ldr r3, [r7, #20] + 800134e: 687a ldr r2, [r7, #4] + 8001350: 615a str r2, [r3, #20] + ep->xfer_len = len; + 8001352: 697b ldr r3, [r7, #20] + 8001354: 683a ldr r2, [r7, #0] + 8001356: 619a str r2, [r3, #24] + ep->xfer_count = 0U; + 8001358: 697b ldr r3, [r7, #20] + 800135a: 2200 movs r2, #0 + 800135c: 61da str r2, [r3, #28] + ep->is_in = 1U; + 800135e: 697b ldr r3, [r7, #20] + 8001360: 2201 movs r2, #1 + 8001362: 705a strb r2, [r3, #1] + ep->num = ep_addr & EP_ADDR_MSK; + 8001364: 187b adds r3, r7, r1 + 8001366: 781b ldrb r3, [r3, #0] + 8001368: 2207 movs r2, #7 + 800136a: 4013 ands r3, r2 + 800136c: b2da uxtb r2, r3 + 800136e: 697b ldr r3, [r7, #20] + 8001370: 701a strb r2, [r3, #0] + + if ((ep_addr & EP_ADDR_MSK) == 0U) + 8001372: 187b adds r3, r7, r1 + 8001374: 781b ldrb r3, [r3, #0] + 8001376: 2207 movs r2, #7 + 8001378: 4013 ands r3, r2 + 800137a: d107 bne.n 800138c + { + (void)USB_EP0StartXfer(hpcd->Instance, ep); + 800137c: 68fb ldr r3, [r7, #12] + 800137e: 681b ldr r3, [r3, #0] + 8001380: 697a ldr r2, [r7, #20] + 8001382: 0011 movs r1, r2 + 8001384: 0018 movs r0, r3 + 8001386: f001 fed3 bl 8003130 + 800138a: e006 b.n 800139a + } + else + { + (void)USB_EPStartXfer(hpcd->Instance, ep); + 800138c: 68fb ldr r3, [r7, #12] + 800138e: 681b ldr r3, [r3, #0] + 8001390: 697a ldr r2, [r7, #20] + 8001392: 0011 movs r1, r2 + 8001394: 0018 movs r0, r3 + 8001396: f001 fecb bl 8003130 + } + + return HAL_OK; + 800139a: 2300 movs r3, #0 +} + 800139c: 0018 movs r0, r3 + 800139e: 46bd mov sp, r7 + 80013a0: b006 add sp, #24 + 80013a2: bd80 pop {r7, pc} + +080013a4 : + * @param hpcd PCD handle + * @param ep_addr endpoint address + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_EP_SetStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr) +{ + 80013a4: b580 push {r7, lr} + 80013a6: b084 sub sp, #16 + 80013a8: af00 add r7, sp, #0 + 80013aa: 6078 str r0, [r7, #4] + 80013ac: 000a movs r2, r1 + 80013ae: 1cfb adds r3, r7, #3 + 80013b0: 701a strb r2, [r3, #0] + PCD_EPTypeDef *ep; + + if (((uint32_t)ep_addr & EP_ADDR_MSK) > hpcd->Init.dev_endpoints) + 80013b2: 1cfb adds r3, r7, #3 + 80013b4: 781b ldrb r3, [r3, #0] + 80013b6: 2207 movs r2, #7 + 80013b8: 401a ands r2, r3 + 80013ba: 687b ldr r3, [r7, #4] + 80013bc: 685b ldr r3, [r3, #4] + 80013be: 429a cmp r2, r3 + 80013c0: d901 bls.n 80013c6 + { + return HAL_ERROR; + 80013c2: 2301 movs r3, #1 + 80013c4: e050 b.n 8001468 + } + + if ((0x80U & ep_addr) == 0x80U) + 80013c6: 1cfb adds r3, r7, #3 + 80013c8: 781b ldrb r3, [r3, #0] + 80013ca: b25b sxtb r3, r3 + 80013cc: 2b00 cmp r3, #0 + 80013ce: da0c bge.n 80013ea + { + ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK]; + 80013d0: 1cfb adds r3, r7, #3 + 80013d2: 781b ldrb r3, [r3, #0] + 80013d4: 2207 movs r2, #7 + 80013d6: 4013 ands r3, r2 + 80013d8: 015b lsls r3, r3, #5 + 80013da: 3328 adds r3, #40 ; 0x28 + 80013dc: 687a ldr r2, [r7, #4] + 80013de: 18d3 adds r3, r2, r3 + 80013e0: 60fb str r3, [r7, #12] + ep->is_in = 1U; + 80013e2: 68fb ldr r3, [r7, #12] + 80013e4: 2201 movs r2, #1 + 80013e6: 705a strb r2, [r3, #1] + 80013e8: e00a b.n 8001400 + } + else + { + ep = &hpcd->OUT_ep[ep_addr]; + 80013ea: 1cfb adds r3, r7, #3 + 80013ec: 781b ldrb r3, [r3, #0] + 80013ee: 015b lsls r3, r3, #5 + 80013f0: 3329 adds r3, #41 ; 0x29 + 80013f2: 33ff adds r3, #255 ; 0xff + 80013f4: 687a ldr r2, [r7, #4] + 80013f6: 18d3 adds r3, r2, r3 + 80013f8: 60fb str r3, [r7, #12] + ep->is_in = 0U; + 80013fa: 68fb ldr r3, [r7, #12] + 80013fc: 2200 movs r2, #0 + 80013fe: 705a strb r2, [r3, #1] + } + + ep->is_stall = 1U; + 8001400: 68fb ldr r3, [r7, #12] + 8001402: 2201 movs r2, #1 + 8001404: 709a strb r2, [r3, #2] + ep->num = ep_addr & EP_ADDR_MSK; + 8001406: 1cfb adds r3, r7, #3 + 8001408: 781b ldrb r3, [r3, #0] + 800140a: 2207 movs r2, #7 + 800140c: 4013 ands r3, r2 + 800140e: b2da uxtb r2, r3 + 8001410: 68fb ldr r3, [r7, #12] + 8001412: 701a strb r2, [r3, #0] + + __HAL_LOCK(hpcd); + 8001414: 687a ldr r2, [r7, #4] + 8001416: 238a movs r3, #138 ; 0x8a + 8001418: 009b lsls r3, r3, #2 + 800141a: 5cd3 ldrb r3, [r2, r3] + 800141c: 2b01 cmp r3, #1 + 800141e: d101 bne.n 8001424 + 8001420: 2302 movs r3, #2 + 8001422: e021 b.n 8001468 + 8001424: 687a ldr r2, [r7, #4] + 8001426: 238a movs r3, #138 ; 0x8a + 8001428: 009b lsls r3, r3, #2 + 800142a: 2101 movs r1, #1 + 800142c: 54d1 strb r1, [r2, r3] + + (void)USB_EPSetStall(hpcd->Instance, ep); + 800142e: 687b ldr r3, [r7, #4] + 8001430: 681b ldr r3, [r3, #0] + 8001432: 68fa ldr r2, [r7, #12] + 8001434: 0011 movs r1, r2 + 8001436: 0018 movs r0, r3 + 8001438: f002 f94c bl 80036d4 + if ((ep_addr & EP_ADDR_MSK) == 0U) + 800143c: 1cfb adds r3, r7, #3 + 800143e: 781b ldrb r3, [r3, #0] + 8001440: 2207 movs r2, #7 + 8001442: 4013 ands r3, r2 + 8001444: d10a bne.n 800145c + { + (void)USB_EP0_OutStart(hpcd->Instance, (uint8_t *)hpcd->Setup); + 8001446: 687b ldr r3, [r7, #4] + 8001448: 681a ldr r2, [r3, #0] + 800144a: 687b ldr r3, [r7, #4] + 800144c: 218c movs r1, #140 ; 0x8c + 800144e: 0089 lsls r1, r1, #2 + 8001450: 468c mov ip, r1 + 8001452: 4463 add r3, ip + 8001454: 0019 movs r1, r3 + 8001456: 0010 movs r0, r2 + 8001458: f002 fa48 bl 80038ec + } + __HAL_UNLOCK(hpcd); + 800145c: 687a ldr r2, [r7, #4] + 800145e: 238a movs r3, #138 ; 0x8a + 8001460: 009b lsls r3, r3, #2 + 8001462: 2100 movs r1, #0 + 8001464: 54d1 strb r1, [r2, r3] + + return HAL_OK; + 8001466: 2300 movs r3, #0 +} + 8001468: 0018 movs r0, r3 + 800146a: 46bd mov sp, r7 + 800146c: b004 add sp, #16 + 800146e: bd80 pop {r7, pc} + +08001470 : + * @param hpcd PCD handle + * @param ep_addr endpoint address + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_EP_ClrStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr) +{ + 8001470: b580 push {r7, lr} + 8001472: b084 sub sp, #16 + 8001474: af00 add r7, sp, #0 + 8001476: 6078 str r0, [r7, #4] + 8001478: 000a movs r2, r1 + 800147a: 1cfb adds r3, r7, #3 + 800147c: 701a strb r2, [r3, #0] + PCD_EPTypeDef *ep; + + if (((uint32_t)ep_addr & 0x0FU) > hpcd->Init.dev_endpoints) + 800147e: 1cfb adds r3, r7, #3 + 8001480: 781b ldrb r3, [r3, #0] + 8001482: 220f movs r2, #15 + 8001484: 401a ands r2, r3 + 8001486: 687b ldr r3, [r7, #4] + 8001488: 685b ldr r3, [r3, #4] + 800148a: 429a cmp r2, r3 + 800148c: d901 bls.n 8001492 + { + return HAL_ERROR; + 800148e: 2301 movs r3, #1 + 8001490: e042 b.n 8001518 + } + + if ((0x80U & ep_addr) == 0x80U) + 8001492: 1cfb adds r3, r7, #3 + 8001494: 781b ldrb r3, [r3, #0] + 8001496: b25b sxtb r3, r3 + 8001498: 2b00 cmp r3, #0 + 800149a: da0c bge.n 80014b6 + { + ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK]; + 800149c: 1cfb adds r3, r7, #3 + 800149e: 781b ldrb r3, [r3, #0] + 80014a0: 2207 movs r2, #7 + 80014a2: 4013 ands r3, r2 + 80014a4: 015b lsls r3, r3, #5 + 80014a6: 3328 adds r3, #40 ; 0x28 + 80014a8: 687a ldr r2, [r7, #4] + 80014aa: 18d3 adds r3, r2, r3 + 80014ac: 60fb str r3, [r7, #12] + ep->is_in = 1U; + 80014ae: 68fb ldr r3, [r7, #12] + 80014b0: 2201 movs r2, #1 + 80014b2: 705a strb r2, [r3, #1] + 80014b4: e00c b.n 80014d0 + } + else + { + ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK]; + 80014b6: 1cfb adds r3, r7, #3 + 80014b8: 781b ldrb r3, [r3, #0] + 80014ba: 2207 movs r2, #7 + 80014bc: 4013 ands r3, r2 + 80014be: 015b lsls r3, r3, #5 + 80014c0: 3329 adds r3, #41 ; 0x29 + 80014c2: 33ff adds r3, #255 ; 0xff + 80014c4: 687a ldr r2, [r7, #4] + 80014c6: 18d3 adds r3, r2, r3 + 80014c8: 60fb str r3, [r7, #12] + ep->is_in = 0U; + 80014ca: 68fb ldr r3, [r7, #12] + 80014cc: 2200 movs r2, #0 + 80014ce: 705a strb r2, [r3, #1] + } + + ep->is_stall = 0U; + 80014d0: 68fb ldr r3, [r7, #12] + 80014d2: 2200 movs r2, #0 + 80014d4: 709a strb r2, [r3, #2] + ep->num = ep_addr & EP_ADDR_MSK; + 80014d6: 1cfb adds r3, r7, #3 + 80014d8: 781b ldrb r3, [r3, #0] + 80014da: 2207 movs r2, #7 + 80014dc: 4013 ands r3, r2 + 80014de: b2da uxtb r2, r3 + 80014e0: 68fb ldr r3, [r7, #12] + 80014e2: 701a strb r2, [r3, #0] + + __HAL_LOCK(hpcd); + 80014e4: 687a ldr r2, [r7, #4] + 80014e6: 238a movs r3, #138 ; 0x8a + 80014e8: 009b lsls r3, r3, #2 + 80014ea: 5cd3 ldrb r3, [r2, r3] + 80014ec: 2b01 cmp r3, #1 + 80014ee: d101 bne.n 80014f4 + 80014f0: 2302 movs r3, #2 + 80014f2: e011 b.n 8001518 + 80014f4: 687a ldr r2, [r7, #4] + 80014f6: 238a movs r3, #138 ; 0x8a + 80014f8: 009b lsls r3, r3, #2 + 80014fa: 2101 movs r1, #1 + 80014fc: 54d1 strb r1, [r2, r3] + (void)USB_EPClearStall(hpcd->Instance, ep); + 80014fe: 687b ldr r3, [r7, #4] + 8001500: 681b ldr r3, [r3, #0] + 8001502: 68fa ldr r2, [r7, #12] + 8001504: 0011 movs r1, r2 + 8001506: 0018 movs r0, r3 + 8001508: f002 f926 bl 8003758 + __HAL_UNLOCK(hpcd); + 800150c: 687a ldr r2, [r7, #4] + 800150e: 238a movs r3, #138 ; 0x8a + 8001510: 009b lsls r3, r3, #2 + 8001512: 2100 movs r1, #0 + 8001514: 54d1 strb r1, [r2, r3] + + return HAL_OK; + 8001516: 2300 movs r3, #0 +} + 8001518: 0018 movs r0, r3 + 800151a: 46bd mov sp, r7 + 800151c: b004 add sp, #16 + 800151e: bd80 pop {r7, pc} + +08001520 : + * @brief This function handles PCD Endpoint interrupt request. + * @param hpcd PCD handle + * @retval HAL status + */ +static HAL_StatusTypeDef PCD_EP_ISR_Handler(PCD_HandleTypeDef *hpcd) +{ + 8001520: b590 push {r4, r7, lr} + 8001522: b089 sub sp, #36 ; 0x24 + 8001524: af00 add r7, sp, #0 + 8001526: 6078 str r0, [r7, #4] + uint16_t wIstr; + uint16_t wEPVal; + uint8_t epindex; + + /* stay in loop while pending interrupts */ + while ((hpcd->Instance->ISTR & USB_ISTR_CTR) != 0U) + 8001528: e2b3 b.n 8001a92 + { + wIstr = hpcd->Instance->ISTR; + 800152a: 687b ldr r3, [r7, #4] + 800152c: 681a ldr r2, [r3, #0] + 800152e: 2016 movs r0, #22 + 8001530: 183b adds r3, r7, r0 + 8001532: 2144 movs r1, #68 ; 0x44 + 8001534: 5a52 ldrh r2, [r2, r1] + 8001536: 801a strh r2, [r3, #0] + /* extract highest priority endpoint number */ + epindex = (uint8_t)(wIstr & USB_ISTR_EP_ID); + 8001538: 183b adds r3, r7, r0 + 800153a: 881b ldrh r3, [r3, #0] + 800153c: b2da uxtb r2, r3 + 800153e: 2015 movs r0, #21 + 8001540: 183b adds r3, r7, r0 + 8001542: 210f movs r1, #15 + 8001544: 400a ands r2, r1 + 8001546: 701a strb r2, [r3, #0] + + if (epindex == 0U) + 8001548: 183b adds r3, r7, r0 + 800154a: 781b ldrb r3, [r3, #0] + 800154c: 2b00 cmp r3, #0 + 800154e: d000 beq.n 8001552 + 8001550: e141 b.n 80017d6 + { + /* Decode and service control endpoint interrupt */ + + /* DIR bit = origin of the interrupt */ + if ((wIstr & USB_ISTR_DIR) == 0U) + 8001552: 2316 movs r3, #22 + 8001554: 18fb adds r3, r7, r3 + 8001556: 881b ldrh r3, [r3, #0] + 8001558: 2210 movs r2, #16 + 800155a: 4013 ands r3, r2 + 800155c: d14e bne.n 80015fc + { + /* DIR = 0 */ + + /* DIR = 0 => IN int */ + /* DIR = 0 implies that (EP_CTR_TX = 1) always */ + PCD_CLEAR_TX_EP_CTR(hpcd->Instance, PCD_ENDP0); + 800155e: 687b ldr r3, [r7, #4] + 8001560: 681b ldr r3, [r3, #0] + 8001562: 881b ldrh r3, [r3, #0] + 8001564: b29b uxth r3, r3 + 8001566: 4aca ldr r2, [pc, #808] ; (8001890 ) + 8001568: 4013 ands r3, r2 + 800156a: b29c uxth r4, r3 + 800156c: 687b ldr r3, [r7, #4] + 800156e: 681b ldr r3, [r3, #0] + 8001570: 4ac8 ldr r2, [pc, #800] ; (8001894 ) + 8001572: 4322 orrs r2, r4 + 8001574: b292 uxth r2, r2 + 8001576: 801a strh r2, [r3, #0] + ep = &hpcd->IN_ep[0]; + 8001578: 687b ldr r3, [r7, #4] + 800157a: 3328 adds r3, #40 ; 0x28 + 800157c: 60fb str r3, [r7, #12] + + ep->xfer_count = PCD_GET_EP_TX_CNT(hpcd->Instance, ep->num); + 800157e: 687b ldr r3, [r7, #4] + 8001580: 681b ldr r3, [r3, #0] + 8001582: 2250 movs r2, #80 ; 0x50 + 8001584: 5a9b ldrh r3, [r3, r2] + 8001586: b29b uxth r3, r3 + 8001588: 001a movs r2, r3 + 800158a: 68fb ldr r3, [r7, #12] + 800158c: 781b ldrb r3, [r3, #0] + 800158e: 00db lsls r3, r3, #3 + 8001590: 18d2 adds r2, r2, r3 + 8001592: 687b ldr r3, [r7, #4] + 8001594: 681b ldr r3, [r3, #0] + 8001596: 18d3 adds r3, r2, r3 + 8001598: 4abf ldr r2, [pc, #764] ; (8001898 ) + 800159a: 4694 mov ip, r2 + 800159c: 4463 add r3, ip + 800159e: 881b ldrh r3, [r3, #0] + 80015a0: 059b lsls r3, r3, #22 + 80015a2: 0d9a lsrs r2, r3, #22 + 80015a4: 68fb ldr r3, [r7, #12] + 80015a6: 61da str r2, [r3, #28] + ep->xfer_buff += ep->xfer_count; + 80015a8: 68fb ldr r3, [r7, #12] + 80015aa: 695a ldr r2, [r3, #20] + 80015ac: 68fb ldr r3, [r7, #12] + 80015ae: 69db ldr r3, [r3, #28] + 80015b0: 18d2 adds r2, r2, r3 + 80015b2: 68fb ldr r3, [r7, #12] + 80015b4: 615a str r2, [r3, #20] + + /* TX COMPLETE */ +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) + hpcd->DataInStageCallback(hpcd, 0U); +#else + HAL_PCD_DataInStageCallback(hpcd, 0U); + 80015b6: 687b ldr r3, [r7, #4] + 80015b8: 2100 movs r1, #0 + 80015ba: 0018 movs r0, r3 + 80015bc: f00c ff54 bl 800e468 +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ + + if ((hpcd->USB_Address > 0U) && (ep->xfer_len == 0U)) + 80015c0: 687b ldr r3, [r7, #4] + 80015c2: 2224 movs r2, #36 ; 0x24 + 80015c4: 5c9b ldrb r3, [r3, r2] + 80015c6: b2db uxtb r3, r3 + 80015c8: 2b00 cmp r3, #0 + 80015ca: d100 bne.n 80015ce + 80015cc: e261 b.n 8001a92 + 80015ce: 68fb ldr r3, [r7, #12] + 80015d0: 699b ldr r3, [r3, #24] + 80015d2: 2b00 cmp r3, #0 + 80015d4: d000 beq.n 80015d8 + 80015d6: e25c b.n 8001a92 + { + hpcd->Instance->DADDR = ((uint16_t)hpcd->USB_Address | USB_DADDR_EF); + 80015d8: 687b ldr r3, [r7, #4] + 80015da: 2224 movs r2, #36 ; 0x24 + 80015dc: 5c9b ldrb r3, [r3, r2] + 80015de: b2db uxtb r3, r3 + 80015e0: 2280 movs r2, #128 ; 0x80 + 80015e2: 4252 negs r2, r2 + 80015e4: 4313 orrs r3, r2 + 80015e6: b2da uxtb r2, r3 + 80015e8: 687b ldr r3, [r7, #4] + 80015ea: 681b ldr r3, [r3, #0] + 80015ec: b291 uxth r1, r2 + 80015ee: 224c movs r2, #76 ; 0x4c + 80015f0: 5299 strh r1, [r3, r2] + hpcd->USB_Address = 0U; + 80015f2: 687b ldr r3, [r7, #4] + 80015f4: 2224 movs r2, #36 ; 0x24 + 80015f6: 2100 movs r1, #0 + 80015f8: 5499 strb r1, [r3, r2] + 80015fa: e24a b.n 8001a92 + { + /* DIR = 1 */ + + /* DIR = 1 & CTR_RX => SETUP or OUT int */ + /* DIR = 1 & (CTR_TX | CTR_RX) => 2 int pending */ + ep = &hpcd->OUT_ep[0]; + 80015fc: 687b ldr r3, [r7, #4] + 80015fe: 3329 adds r3, #41 ; 0x29 + 8001600: 33ff adds r3, #255 ; 0xff + 8001602: 60fb str r3, [r7, #12] + wEPVal = PCD_GET_ENDPOINT(hpcd->Instance, PCD_ENDP0); + 8001604: 687b ldr r3, [r7, #4] + 8001606: 681a ldr r2, [r3, #0] + 8001608: 2112 movs r1, #18 + 800160a: 187b adds r3, r7, r1 + 800160c: 8812 ldrh r2, [r2, #0] + 800160e: 801a strh r2, [r3, #0] + + if ((wEPVal & USB_EP_SETUP) != 0U) + 8001610: 187b adds r3, r7, r1 + 8001612: 881a ldrh r2, [r3, #0] + 8001614: 2380 movs r3, #128 ; 0x80 + 8001616: 011b lsls r3, r3, #4 + 8001618: 4013 ands r3, r2 + 800161a: d033 beq.n 8001684 + { + /* Get SETUP Packet*/ + ep->xfer_count = PCD_GET_EP_RX_CNT(hpcd->Instance, ep->num); + 800161c: 687b ldr r3, [r7, #4] + 800161e: 681b ldr r3, [r3, #0] + 8001620: 2250 movs r2, #80 ; 0x50 + 8001622: 5a9b ldrh r3, [r3, r2] + 8001624: b29b uxth r3, r3 + 8001626: 001a movs r2, r3 + 8001628: 68fb ldr r3, [r7, #12] + 800162a: 781b ldrb r3, [r3, #0] + 800162c: 00db lsls r3, r3, #3 + 800162e: 18d2 adds r2, r2, r3 + 8001630: 687b ldr r3, [r7, #4] + 8001632: 681b ldr r3, [r3, #0] + 8001634: 18d3 adds r3, r2, r3 + 8001636: 4a99 ldr r2, [pc, #612] ; (800189c ) + 8001638: 4694 mov ip, r2 + 800163a: 4463 add r3, ip + 800163c: 881b ldrh r3, [r3, #0] + 800163e: 059b lsls r3, r3, #22 + 8001640: 0d9a lsrs r2, r3, #22 + 8001642: 68fb ldr r3, [r7, #12] + 8001644: 61da str r2, [r3, #28] + + USB_ReadPMA(hpcd->Instance, (uint8_t *)hpcd->Setup, + 8001646: 687b ldr r3, [r7, #4] + 8001648: 6818 ldr r0, [r3, #0] + 800164a: 687b ldr r3, [r7, #4] + 800164c: 228c movs r2, #140 ; 0x8c + 800164e: 0092 lsls r2, r2, #2 + 8001650: 1899 adds r1, r3, r2 + 8001652: 68fb ldr r3, [r7, #12] + 8001654: 88da ldrh r2, [r3, #6] + ep->pmaadress, (uint16_t)ep->xfer_count); + 8001656: 68fb ldr r3, [r7, #12] + 8001658: 69db ldr r3, [r3, #28] + USB_ReadPMA(hpcd->Instance, (uint8_t *)hpcd->Setup, + 800165a: b29b uxth r3, r3 + 800165c: f002 f993 bl 8003986 + + /* SETUP bit kept frozen while CTR_RX = 1*/ + PCD_CLEAR_RX_EP_CTR(hpcd->Instance, PCD_ENDP0); + 8001660: 687b ldr r3, [r7, #4] + 8001662: 681b ldr r3, [r3, #0] + 8001664: 881b ldrh r3, [r3, #0] + 8001666: b29b uxth r3, r3 + 8001668: 4a8d ldr r2, [pc, #564] ; (80018a0 ) + 800166a: 4013 ands r3, r2 + 800166c: b29c uxth r4, r3 + 800166e: 687b ldr r3, [r7, #4] + 8001670: 681b ldr r3, [r3, #0] + 8001672: 2280 movs r2, #128 ; 0x80 + 8001674: 4322 orrs r2, r4 + 8001676: b292 uxth r2, r2 + 8001678: 801a strh r2, [r3, #0] + + /* Process SETUP Packet*/ +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) + hpcd->SetupStageCallback(hpcd); +#else + HAL_PCD_SetupStageCallback(hpcd); + 800167a: 687b ldr r3, [r7, #4] + 800167c: 0018 movs r0, r3 + 800167e: f00c fec1 bl 800e404 + 8001682: e206 b.n 8001a92 +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ + } + + else if ((wEPVal & USB_EP_CTR_RX) != 0U) + 8001684: 2312 movs r3, #18 + 8001686: 18fb adds r3, r7, r3 + 8001688: 2200 movs r2, #0 + 800168a: 5e9b ldrsh r3, [r3, r2] + 800168c: 2b00 cmp r3, #0 + 800168e: db00 blt.n 8001692 + 8001690: e1ff b.n 8001a92 + { + PCD_CLEAR_RX_EP_CTR(hpcd->Instance, PCD_ENDP0); + 8001692: 687b ldr r3, [r7, #4] + 8001694: 681b ldr r3, [r3, #0] + 8001696: 881b ldrh r3, [r3, #0] + 8001698: b29b uxth r3, r3 + 800169a: 4a81 ldr r2, [pc, #516] ; (80018a0 ) + 800169c: 4013 ands r3, r2 + 800169e: b29c uxth r4, r3 + 80016a0: 687b ldr r3, [r7, #4] + 80016a2: 681b ldr r3, [r3, #0] + 80016a4: 2280 movs r2, #128 ; 0x80 + 80016a6: 4322 orrs r2, r4 + 80016a8: b292 uxth r2, r2 + 80016aa: 801a strh r2, [r3, #0] + + /* Get Control Data OUT Packet*/ + ep->xfer_count = PCD_GET_EP_RX_CNT(hpcd->Instance, ep->num); + 80016ac: 687b ldr r3, [r7, #4] + 80016ae: 681b ldr r3, [r3, #0] + 80016b0: 2250 movs r2, #80 ; 0x50 + 80016b2: 5a9b ldrh r3, [r3, r2] + 80016b4: b29b uxth r3, r3 + 80016b6: 001a movs r2, r3 + 80016b8: 68fb ldr r3, [r7, #12] + 80016ba: 781b ldrb r3, [r3, #0] + 80016bc: 00db lsls r3, r3, #3 + 80016be: 18d2 adds r2, r2, r3 + 80016c0: 687b ldr r3, [r7, #4] + 80016c2: 681b ldr r3, [r3, #0] + 80016c4: 18d3 adds r3, r2, r3 + 80016c6: 4a75 ldr r2, [pc, #468] ; (800189c ) + 80016c8: 4694 mov ip, r2 + 80016ca: 4463 add r3, ip + 80016cc: 881b ldrh r3, [r3, #0] + 80016ce: 059b lsls r3, r3, #22 + 80016d0: 0d9a lsrs r2, r3, #22 + 80016d2: 68fb ldr r3, [r7, #12] + 80016d4: 61da str r2, [r3, #28] + + if ((ep->xfer_count != 0U) && (ep->xfer_buff != 0U)) + 80016d6: 68fb ldr r3, [r7, #12] + 80016d8: 69db ldr r3, [r3, #28] + 80016da: 2b00 cmp r3, #0 + 80016dc: d01a beq.n 8001714 + 80016de: 68fb ldr r3, [r7, #12] + 80016e0: 695b ldr r3, [r3, #20] + 80016e2: 2b00 cmp r3, #0 + 80016e4: d016 beq.n 8001714 + { + USB_ReadPMA(hpcd->Instance, ep->xfer_buff, + 80016e6: 687b ldr r3, [r7, #4] + 80016e8: 6818 ldr r0, [r3, #0] + 80016ea: 68fb ldr r3, [r7, #12] + 80016ec: 6959 ldr r1, [r3, #20] + 80016ee: 68fb ldr r3, [r7, #12] + 80016f0: 88da ldrh r2, [r3, #6] + ep->pmaadress, (uint16_t)ep->xfer_count); + 80016f2: 68fb ldr r3, [r7, #12] + 80016f4: 69db ldr r3, [r3, #28] + USB_ReadPMA(hpcd->Instance, ep->xfer_buff, + 80016f6: b29b uxth r3, r3 + 80016f8: f002 f945 bl 8003986 + + ep->xfer_buff += ep->xfer_count; + 80016fc: 68fb ldr r3, [r7, #12] + 80016fe: 695a ldr r2, [r3, #20] + 8001700: 68fb ldr r3, [r7, #12] + 8001702: 69db ldr r3, [r3, #28] + 8001704: 18d2 adds r2, r2, r3 + 8001706: 68fb ldr r3, [r7, #12] + 8001708: 615a str r2, [r3, #20] + + /* Process Control Data OUT Packet*/ +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) + hpcd->DataOutStageCallback(hpcd, 0U); +#else + HAL_PCD_DataOutStageCallback(hpcd, 0U); + 800170a: 687b ldr r3, [r7, #4] + 800170c: 2100 movs r1, #0 + 800170e: 0018 movs r0, r3 + 8001710: f00c fe8d bl 800e42e +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ + } + + PCD_SET_EP_RX_CNT(hpcd->Instance, PCD_ENDP0, ep->maxpacket); + 8001714: 687b ldr r3, [r7, #4] + 8001716: 681b ldr r3, [r3, #0] + 8001718: 001c movs r4, r3 + 800171a: 687b ldr r3, [r7, #4] + 800171c: 681b ldr r3, [r3, #0] + 800171e: 2250 movs r2, #80 ; 0x50 + 8001720: 5a9b ldrh r3, [r3, r2] + 8001722: b29b uxth r3, r3 + 8001724: 18e4 adds r4, r4, r3 + 8001726: 4b5d ldr r3, [pc, #372] ; (800189c ) + 8001728: 18e3 adds r3, r4, r3 + 800172a: 60bb str r3, [r7, #8] + 800172c: 68fb ldr r3, [r7, #12] + 800172e: 691b ldr r3, [r3, #16] + 8001730: 2b00 cmp r3, #0 + 8001732: d10e bne.n 8001752 + 8001734: 68bb ldr r3, [r7, #8] + 8001736: 881b ldrh r3, [r3, #0] + 8001738: 4a5a ldr r2, [pc, #360] ; (80018a4 ) + 800173a: 4013 ands r3, r2 + 800173c: b29a uxth r2, r3 + 800173e: 68bb ldr r3, [r7, #8] + 8001740: 801a strh r2, [r3, #0] + 8001742: 68bb ldr r3, [r7, #8] + 8001744: 881b ldrh r3, [r3, #0] + 8001746: 4a53 ldr r2, [pc, #332] ; (8001894 ) + 8001748: 4313 orrs r3, r2 + 800174a: b29a uxth r2, r3 + 800174c: 68bb ldr r3, [r7, #8] + 800174e: 801a strh r2, [r3, #0] + 8001750: e02b b.n 80017aa + 8001752: 68fb ldr r3, [r7, #12] + 8001754: 691b ldr r3, [r3, #16] + 8001756: 2b3e cmp r3, #62 ; 0x3e + 8001758: d812 bhi.n 8001780 + 800175a: 68fb ldr r3, [r7, #12] + 800175c: 691b ldr r3, [r3, #16] + 800175e: 085b lsrs r3, r3, #1 + 8001760: 61bb str r3, [r7, #24] + 8001762: 68fb ldr r3, [r7, #12] + 8001764: 691b ldr r3, [r3, #16] + 8001766: 2201 movs r2, #1 + 8001768: 4013 ands r3, r2 + 800176a: d002 beq.n 8001772 + 800176c: 69bb ldr r3, [r7, #24] + 800176e: 3301 adds r3, #1 + 8001770: 61bb str r3, [r7, #24] + 8001772: 69bb ldr r3, [r7, #24] + 8001774: b29b uxth r3, r3 + 8001776: 029b lsls r3, r3, #10 + 8001778: b29a uxth r2, r3 + 800177a: 68bb ldr r3, [r7, #8] + 800177c: 801a strh r2, [r3, #0] + 800177e: e014 b.n 80017aa + 8001780: 68fb ldr r3, [r7, #12] + 8001782: 691b ldr r3, [r3, #16] + 8001784: 095b lsrs r3, r3, #5 + 8001786: 61bb str r3, [r7, #24] + 8001788: 68fb ldr r3, [r7, #12] + 800178a: 691b ldr r3, [r3, #16] + 800178c: 221f movs r2, #31 + 800178e: 4013 ands r3, r2 + 8001790: d102 bne.n 8001798 + 8001792: 69bb ldr r3, [r7, #24] + 8001794: 3b01 subs r3, #1 + 8001796: 61bb str r3, [r7, #24] + 8001798: 69bb ldr r3, [r7, #24] + 800179a: b29b uxth r3, r3 + 800179c: 029b lsls r3, r3, #10 + 800179e: b29b uxth r3, r3 + 80017a0: 4a3c ldr r2, [pc, #240] ; (8001894 ) + 80017a2: 4313 orrs r3, r2 + 80017a4: b29a uxth r2, r3 + 80017a6: 68bb ldr r3, [r7, #8] + 80017a8: 801a strh r2, [r3, #0] + PCD_SET_EP_RX_STATUS(hpcd->Instance, PCD_ENDP0, USB_EP_RX_VALID); + 80017aa: 687b ldr r3, [r7, #4] + 80017ac: 681b ldr r3, [r3, #0] + 80017ae: 881b ldrh r3, [r3, #0] + 80017b0: b29b uxth r3, r3 + 80017b2: 4a3d ldr r2, [pc, #244] ; (80018a8 ) + 80017b4: 4013 ands r3, r2 + 80017b6: b29c uxth r4, r3 + 80017b8: 2380 movs r3, #128 ; 0x80 + 80017ba: 015b lsls r3, r3, #5 + 80017bc: 4063 eors r3, r4 + 80017be: b29c uxth r4, r3 + 80017c0: 2380 movs r3, #128 ; 0x80 + 80017c2: 019b lsls r3, r3, #6 + 80017c4: 4063 eors r3, r4 + 80017c6: b29c uxth r4, r3 + 80017c8: 687b ldr r3, [r7, #4] + 80017ca: 681b ldr r3, [r3, #0] + 80017cc: 4a37 ldr r2, [pc, #220] ; (80018ac ) + 80017ce: 4322 orrs r2, r4 + 80017d0: b292 uxth r2, r2 + 80017d2: 801a strh r2, [r3, #0] + 80017d4: e15d b.n 8001a92 + else + { + /* Decode and service non control endpoints interrupt */ + + /* process related endpoint register */ + wEPVal = PCD_GET_ENDPOINT(hpcd->Instance, epindex); + 80017d6: 687b ldr r3, [r7, #4] + 80017d8: 681b ldr r3, [r3, #0] + 80017da: 001a movs r2, r3 + 80017dc: 2315 movs r3, #21 + 80017de: 18fb adds r3, r7, r3 + 80017e0: 781b ldrb r3, [r3, #0] + 80017e2: 009b lsls r3, r3, #2 + 80017e4: 18d2 adds r2, r2, r3 + 80017e6: 2112 movs r1, #18 + 80017e8: 187b adds r3, r7, r1 + 80017ea: 8812 ldrh r2, [r2, #0] + 80017ec: 801a strh r2, [r3, #0] + if ((wEPVal & USB_EP_CTR_RX) != 0U) + 80017ee: 187b adds r3, r7, r1 + 80017f0: 2200 movs r2, #0 + 80017f2: 5e9b ldrsh r3, [r3, r2] + 80017f4: 2b00 cmp r3, #0 + 80017f6: db00 blt.n 80017fa + 80017f8: e0f5 b.n 80019e6 + { + /* clear int flag */ + PCD_CLEAR_RX_EP_CTR(hpcd->Instance, epindex); + 80017fa: 687b ldr r3, [r7, #4] + 80017fc: 681b ldr r3, [r3, #0] + 80017fe: 001a movs r2, r3 + 8001800: 2115 movs r1, #21 + 8001802: 187b adds r3, r7, r1 + 8001804: 781b ldrb r3, [r3, #0] + 8001806: 009b lsls r3, r3, #2 + 8001808: 18d3 adds r3, r2, r3 + 800180a: 881b ldrh r3, [r3, #0] + 800180c: b29b uxth r3, r3 + 800180e: 4a24 ldr r2, [pc, #144] ; (80018a0 ) + 8001810: 4013 ands r3, r2 + 8001812: b29c uxth r4, r3 + 8001814: 687b ldr r3, [r7, #4] + 8001816: 681b ldr r3, [r3, #0] + 8001818: 001a movs r2, r3 + 800181a: 187b adds r3, r7, r1 + 800181c: 781b ldrb r3, [r3, #0] + 800181e: 009b lsls r3, r3, #2 + 8001820: 18d3 adds r3, r2, r3 + 8001822: 2280 movs r2, #128 ; 0x80 + 8001824: 4322 orrs r2, r4 + 8001826: b292 uxth r2, r2 + 8001828: 801a strh r2, [r3, #0] + ep = &hpcd->OUT_ep[epindex]; + 800182a: 187b adds r3, r7, r1 + 800182c: 781b ldrb r3, [r3, #0] + 800182e: 015b lsls r3, r3, #5 + 8001830: 3329 adds r3, #41 ; 0x29 + 8001832: 33ff adds r3, #255 ; 0xff + 8001834: 687a ldr r2, [r7, #4] + 8001836: 18d3 adds r3, r2, r3 + 8001838: 60fb str r3, [r7, #12] + + /* OUT double Buffering*/ + if (ep->doublebuffer == 0U) + 800183a: 68fb ldr r3, [r7, #12] + 800183c: 7b1b ldrb r3, [r3, #12] + 800183e: 2b00 cmp r3, #0 + 8001840: d136 bne.n 80018b0 + { + count = (uint16_t)PCD_GET_EP_RX_CNT(hpcd->Instance, ep->num); + 8001842: 687b ldr r3, [r7, #4] + 8001844: 681b ldr r3, [r3, #0] + 8001846: 2250 movs r2, #80 ; 0x50 + 8001848: 5a9b ldrh r3, [r3, r2] + 800184a: b29b uxth r3, r3 + 800184c: 001a movs r2, r3 + 800184e: 68fb ldr r3, [r7, #12] + 8001850: 781b ldrb r3, [r3, #0] + 8001852: 00db lsls r3, r3, #3 + 8001854: 18d2 adds r2, r2, r3 + 8001856: 687b ldr r3, [r7, #4] + 8001858: 681b ldr r3, [r3, #0] + 800185a: 18d3 adds r3, r2, r3 + 800185c: 4a0f ldr r2, [pc, #60] ; (800189c ) + 800185e: 4694 mov ip, r2 + 8001860: 4463 add r3, ip + 8001862: 881a ldrh r2, [r3, #0] + 8001864: 211e movs r1, #30 + 8001866: 187b adds r3, r7, r1 + 8001868: 0592 lsls r2, r2, #22 + 800186a: 0d92 lsrs r2, r2, #22 + 800186c: 801a strh r2, [r3, #0] + if (count != 0U) + 800186e: 187b adds r3, r7, r1 + 8001870: 881b ldrh r3, [r3, #0] + 8001872: 2b00 cmp r3, #0 + 8001874: d100 bne.n 8001878 + 8001876: e08b b.n 8001990 + { + USB_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaadress, count); + 8001878: 687b ldr r3, [r7, #4] + 800187a: 6818 ldr r0, [r3, #0] + 800187c: 68fb ldr r3, [r7, #12] + 800187e: 6959 ldr r1, [r3, #20] + 8001880: 68fb ldr r3, [r7, #12] + 8001882: 88da ldrh r2, [r3, #6] + 8001884: 231e movs r3, #30 + 8001886: 18fb adds r3, r7, r3 + 8001888: 881b ldrh r3, [r3, #0] + 800188a: f002 f87c bl 8003986 + 800188e: e07f b.n 8001990 + 8001890: ffff8f0f .word 0xffff8f0f + 8001894: ffff8000 .word 0xffff8000 + 8001898: 00000402 .word 0x00000402 + 800189c: 00000406 .word 0x00000406 + 80018a0: 00000f8f .word 0x00000f8f + 80018a4: ffff83ff .word 0xffff83ff + 80018a8: ffffbf8f .word 0xffffbf8f + 80018ac: ffff8080 .word 0xffff8080 + } + } + else + { + if ((PCD_GET_ENDPOINT(hpcd->Instance, ep->num) & USB_EP_DTOG_RX) != 0U) + 80018b0: 687b ldr r3, [r7, #4] + 80018b2: 681b ldr r3, [r3, #0] + 80018b4: 001a movs r2, r3 + 80018b6: 68fb ldr r3, [r7, #12] + 80018b8: 781b ldrb r3, [r3, #0] + 80018ba: 009b lsls r3, r3, #2 + 80018bc: 18d3 adds r3, r2, r3 + 80018be: 881b ldrh r3, [r3, #0] + 80018c0: b29b uxth r3, r3 + 80018c2: 001a movs r2, r3 + 80018c4: 2380 movs r3, #128 ; 0x80 + 80018c6: 01db lsls r3, r3, #7 + 80018c8: 4013 ands r3, r2 + 80018ca: d025 beq.n 8001918 + { + /*read from endpoint BUF0Addr buffer*/ + count = (uint16_t)PCD_GET_EP_DBUF0_CNT(hpcd->Instance, ep->num); + 80018cc: 687b ldr r3, [r7, #4] + 80018ce: 681b ldr r3, [r3, #0] + 80018d0: 2250 movs r2, #80 ; 0x50 + 80018d2: 5a9b ldrh r3, [r3, r2] + 80018d4: b29b uxth r3, r3 + 80018d6: 001a movs r2, r3 + 80018d8: 68fb ldr r3, [r7, #12] + 80018da: 781b ldrb r3, [r3, #0] + 80018dc: 00db lsls r3, r3, #3 + 80018de: 18d2 adds r2, r2, r3 + 80018e0: 687b ldr r3, [r7, #4] + 80018e2: 681b ldr r3, [r3, #0] + 80018e4: 18d3 adds r3, r2, r3 + 80018e6: 4a72 ldr r2, [pc, #456] ; (8001ab0 ) + 80018e8: 4694 mov ip, r2 + 80018ea: 4463 add r3, ip + 80018ec: 881a ldrh r2, [r3, #0] + 80018ee: 211e movs r1, #30 + 80018f0: 187b adds r3, r7, r1 + 80018f2: 0592 lsls r2, r2, #22 + 80018f4: 0d92 lsrs r2, r2, #22 + 80018f6: 801a strh r2, [r3, #0] + if (count != 0U) + 80018f8: 187b adds r3, r7, r1 + 80018fa: 881b ldrh r3, [r3, #0] + 80018fc: 2b00 cmp r3, #0 + 80018fe: d030 beq.n 8001962 + { + USB_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaaddr0, count); + 8001900: 687b ldr r3, [r7, #4] + 8001902: 6818 ldr r0, [r3, #0] + 8001904: 68fb ldr r3, [r7, #12] + 8001906: 6959 ldr r1, [r3, #20] + 8001908: 68fb ldr r3, [r7, #12] + 800190a: 891a ldrh r2, [r3, #8] + 800190c: 231e movs r3, #30 + 800190e: 18fb adds r3, r7, r3 + 8001910: 881b ldrh r3, [r3, #0] + 8001912: f002 f838 bl 8003986 + 8001916: e024 b.n 8001962 + } + } + else + { + /*read from endpoint BUF1Addr buffer*/ + count = (uint16_t)PCD_GET_EP_DBUF1_CNT(hpcd->Instance, ep->num); + 8001918: 687b ldr r3, [r7, #4] + 800191a: 681b ldr r3, [r3, #0] + 800191c: 2250 movs r2, #80 ; 0x50 + 800191e: 5a9b ldrh r3, [r3, r2] + 8001920: b29b uxth r3, r3 + 8001922: 001a movs r2, r3 + 8001924: 68fb ldr r3, [r7, #12] + 8001926: 781b ldrb r3, [r3, #0] + 8001928: 00db lsls r3, r3, #3 + 800192a: 18d2 adds r2, r2, r3 + 800192c: 687b ldr r3, [r7, #4] + 800192e: 681b ldr r3, [r3, #0] + 8001930: 18d3 adds r3, r2, r3 + 8001932: 4a60 ldr r2, [pc, #384] ; (8001ab4 ) + 8001934: 4694 mov ip, r2 + 8001936: 4463 add r3, ip + 8001938: 881a ldrh r2, [r3, #0] + 800193a: 211e movs r1, #30 + 800193c: 187b adds r3, r7, r1 + 800193e: 0592 lsls r2, r2, #22 + 8001940: 0d92 lsrs r2, r2, #22 + 8001942: 801a strh r2, [r3, #0] + if (count != 0U) + 8001944: 187b adds r3, r7, r1 + 8001946: 881b ldrh r3, [r3, #0] + 8001948: 2b00 cmp r3, #0 + 800194a: d00a beq.n 8001962 + { + USB_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaaddr1, count); + 800194c: 687b ldr r3, [r7, #4] + 800194e: 6818 ldr r0, [r3, #0] + 8001950: 68fb ldr r3, [r7, #12] + 8001952: 6959 ldr r1, [r3, #20] + 8001954: 68fb ldr r3, [r7, #12] + 8001956: 895a ldrh r2, [r3, #10] + 8001958: 231e movs r3, #30 + 800195a: 18fb adds r3, r7, r3 + 800195c: 881b ldrh r3, [r3, #0] + 800195e: f002 f812 bl 8003986 + } + } + /* free EP OUT Buffer */ + PCD_FreeUserBuffer(hpcd->Instance, ep->num, 0U); + 8001962: 687b ldr r3, [r7, #4] + 8001964: 681b ldr r3, [r3, #0] + 8001966: 001a movs r2, r3 + 8001968: 68fb ldr r3, [r7, #12] + 800196a: 781b ldrb r3, [r3, #0] + 800196c: 009b lsls r3, r3, #2 + 800196e: 18d3 adds r3, r2, r3 + 8001970: 881b ldrh r3, [r3, #0] + 8001972: b29b uxth r3, r3 + 8001974: 4a50 ldr r2, [pc, #320] ; (8001ab8 ) + 8001976: 4013 ands r3, r2 + 8001978: b29c uxth r4, r3 + 800197a: 687b ldr r3, [r7, #4] + 800197c: 681b ldr r3, [r3, #0] + 800197e: 001a movs r2, r3 + 8001980: 68fb ldr r3, [r7, #12] + 8001982: 781b ldrb r3, [r3, #0] + 8001984: 009b lsls r3, r3, #2 + 8001986: 18d3 adds r3, r2, r3 + 8001988: 4a4c ldr r2, [pc, #304] ; (8001abc ) + 800198a: 4322 orrs r2, r4 + 800198c: b292 uxth r2, r2 + 800198e: 801a strh r2, [r3, #0] + } + /*multi-packet on the NON control OUT endpoint*/ + ep->xfer_count += count; + 8001990: 68fb ldr r3, [r7, #12] + 8001992: 69da ldr r2, [r3, #28] + 8001994: 211e movs r1, #30 + 8001996: 187b adds r3, r7, r1 + 8001998: 881b ldrh r3, [r3, #0] + 800199a: 18d2 adds r2, r2, r3 + 800199c: 68fb ldr r3, [r7, #12] + 800199e: 61da str r2, [r3, #28] + ep->xfer_buff += count; + 80019a0: 68fb ldr r3, [r7, #12] + 80019a2: 695a ldr r2, [r3, #20] + 80019a4: 187b adds r3, r7, r1 + 80019a6: 881b ldrh r3, [r3, #0] + 80019a8: 18d2 adds r2, r2, r3 + 80019aa: 68fb ldr r3, [r7, #12] + 80019ac: 615a str r2, [r3, #20] + + if ((ep->xfer_len == 0U) || (count < ep->maxpacket)) + 80019ae: 68fb ldr r3, [r7, #12] + 80019b0: 699b ldr r3, [r3, #24] + 80019b2: 2b00 cmp r3, #0 + 80019b4: d006 beq.n 80019c4 + 80019b6: 231e movs r3, #30 + 80019b8: 18fb adds r3, r7, r3 + 80019ba: 881a ldrh r2, [r3, #0] + 80019bc: 68fb ldr r3, [r7, #12] + 80019be: 691b ldr r3, [r3, #16] + 80019c0: 429a cmp r2, r3 + 80019c2: d207 bcs.n 80019d4 + { + /* RX COMPLETE */ +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) + hpcd->DataOutStageCallback(hpcd, ep->num); +#else + HAL_PCD_DataOutStageCallback(hpcd, ep->num); + 80019c4: 68fb ldr r3, [r7, #12] + 80019c6: 781a ldrb r2, [r3, #0] + 80019c8: 687b ldr r3, [r7, #4] + 80019ca: 0011 movs r1, r2 + 80019cc: 0018 movs r0, r3 + 80019ce: f00c fd2e bl 800e42e + 80019d2: e008 b.n 80019e6 +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ + } + else + { + (void)HAL_PCD_EP_Receive(hpcd, ep->num, ep->xfer_buff, ep->xfer_len); + 80019d4: 68fb ldr r3, [r7, #12] + 80019d6: 7819 ldrb r1, [r3, #0] + 80019d8: 68fb ldr r3, [r7, #12] + 80019da: 695a ldr r2, [r3, #20] + 80019dc: 68fb ldr r3, [r7, #12] + 80019de: 699b ldr r3, [r3, #24] + 80019e0: 6878 ldr r0, [r7, #4] + 80019e2: f7ff fc49 bl 8001278 + } + + } /* if((wEPVal & EP_CTR_RX) */ + + if ((wEPVal & USB_EP_CTR_TX) != 0U) + 80019e6: 2312 movs r3, #18 + 80019e8: 18fb adds r3, r7, r3 + 80019ea: 881b ldrh r3, [r3, #0] + 80019ec: 2280 movs r2, #128 ; 0x80 + 80019ee: 4013 ands r3, r2 + 80019f0: d04f beq.n 8001a92 + { + ep = &hpcd->IN_ep[epindex]; + 80019f2: 2115 movs r1, #21 + 80019f4: 187b adds r3, r7, r1 + 80019f6: 781b ldrb r3, [r3, #0] + 80019f8: 015b lsls r3, r3, #5 + 80019fa: 3328 adds r3, #40 ; 0x28 + 80019fc: 687a ldr r2, [r7, #4] + 80019fe: 18d3 adds r3, r2, r3 + 8001a00: 60fb str r3, [r7, #12] + + /* clear int flag */ + PCD_CLEAR_TX_EP_CTR(hpcd->Instance, epindex); + 8001a02: 687b ldr r3, [r7, #4] + 8001a04: 681b ldr r3, [r3, #0] + 8001a06: 001a movs r2, r3 + 8001a08: 187b adds r3, r7, r1 + 8001a0a: 781b ldrb r3, [r3, #0] + 8001a0c: 009b lsls r3, r3, #2 + 8001a0e: 18d3 adds r3, r2, r3 + 8001a10: 881b ldrh r3, [r3, #0] + 8001a12: b29b uxth r3, r3 + 8001a14: 4a2a ldr r2, [pc, #168] ; (8001ac0 ) + 8001a16: 4013 ands r3, r2 + 8001a18: b29c uxth r4, r3 + 8001a1a: 687b ldr r3, [r7, #4] + 8001a1c: 681b ldr r3, [r3, #0] + 8001a1e: 001a movs r2, r3 + 8001a20: 187b adds r3, r7, r1 + 8001a22: 781b ldrb r3, [r3, #0] + 8001a24: 009b lsls r3, r3, #2 + 8001a26: 18d3 adds r3, r2, r3 + 8001a28: 4a26 ldr r2, [pc, #152] ; (8001ac4 ) + 8001a2a: 4322 orrs r2, r4 + 8001a2c: b292 uxth r2, r2 + 8001a2e: 801a strh r2, [r3, #0] + + /*multi-packet on the NON control IN endpoint*/ + ep->xfer_count = PCD_GET_EP_TX_CNT(hpcd->Instance, ep->num); + 8001a30: 687b ldr r3, [r7, #4] + 8001a32: 681b ldr r3, [r3, #0] + 8001a34: 2250 movs r2, #80 ; 0x50 + 8001a36: 5a9b ldrh r3, [r3, r2] + 8001a38: b29b uxth r3, r3 + 8001a3a: 001a movs r2, r3 + 8001a3c: 68fb ldr r3, [r7, #12] + 8001a3e: 781b ldrb r3, [r3, #0] + 8001a40: 00db lsls r3, r3, #3 + 8001a42: 18d2 adds r2, r2, r3 + 8001a44: 687b ldr r3, [r7, #4] + 8001a46: 681b ldr r3, [r3, #0] + 8001a48: 18d3 adds r3, r2, r3 + 8001a4a: 4a19 ldr r2, [pc, #100] ; (8001ab0 ) + 8001a4c: 4694 mov ip, r2 + 8001a4e: 4463 add r3, ip + 8001a50: 881b ldrh r3, [r3, #0] + 8001a52: 059b lsls r3, r3, #22 + 8001a54: 0d9a lsrs r2, r3, #22 + 8001a56: 68fb ldr r3, [r7, #12] + 8001a58: 61da str r2, [r3, #28] + ep->xfer_buff += ep->xfer_count; + 8001a5a: 68fb ldr r3, [r7, #12] + 8001a5c: 695a ldr r2, [r3, #20] + 8001a5e: 68fb ldr r3, [r7, #12] + 8001a60: 69db ldr r3, [r3, #28] + 8001a62: 18d2 adds r2, r2, r3 + 8001a64: 68fb ldr r3, [r7, #12] + 8001a66: 615a str r2, [r3, #20] + + /* Zero Length Packet? */ + if (ep->xfer_len == 0U) + 8001a68: 68fb ldr r3, [r7, #12] + 8001a6a: 699b ldr r3, [r3, #24] + 8001a6c: 2b00 cmp r3, #0 + 8001a6e: d107 bne.n 8001a80 + { + /* TX COMPLETE */ +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) + hpcd->DataInStageCallback(hpcd, ep->num); +#else + HAL_PCD_DataInStageCallback(hpcd, ep->num); + 8001a70: 68fb ldr r3, [r7, #12] + 8001a72: 781a ldrb r2, [r3, #0] + 8001a74: 687b ldr r3, [r7, #4] + 8001a76: 0011 movs r1, r2 + 8001a78: 0018 movs r0, r3 + 8001a7a: f00c fcf5 bl 800e468 + 8001a7e: e008 b.n 8001a92 +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ + } + else + { + (void)HAL_PCD_EP_Transmit(hpcd, ep->num, ep->xfer_buff, ep->xfer_len); + 8001a80: 68fb ldr r3, [r7, #12] + 8001a82: 7819 ldrb r1, [r3, #0] + 8001a84: 68fb ldr r3, [r7, #12] + 8001a86: 695a ldr r2, [r3, #20] + 8001a88: 68fb ldr r3, [r7, #12] + 8001a8a: 699b ldr r3, [r3, #24] + 8001a8c: 6878 ldr r0, [r7, #4] + 8001a8e: f7ff fc49 bl 8001324 + while ((hpcd->Instance->ISTR & USB_ISTR_CTR) != 0U) + 8001a92: 687b ldr r3, [r7, #4] + 8001a94: 681b ldr r3, [r3, #0] + 8001a96: 2244 movs r2, #68 ; 0x44 + 8001a98: 5a9b ldrh r3, [r3, r2] + 8001a9a: b29b uxth r3, r3 + 8001a9c: b21b sxth r3, r3 + 8001a9e: 2b00 cmp r3, #0 + 8001aa0: da00 bge.n 8001aa4 + 8001aa2: e542 b.n 800152a + } + } + } + } + return HAL_OK; + 8001aa4: 2300 movs r3, #0 +} + 8001aa6: 0018 movs r0, r3 + 8001aa8: 46bd mov sp, r7 + 8001aaa: b009 add sp, #36 ; 0x24 + 8001aac: bd90 pop {r4, r7, pc} + 8001aae: 46c0 nop ; (mov r8, r8) + 8001ab0: 00000402 .word 0x00000402 + 8001ab4: 00000406 .word 0x00000406 + 8001ab8: ffff8f8f .word 0xffff8f8f + 8001abc: ffff80c0 .word 0xffff80c0 + 8001ac0: ffff8f0f .word 0xffff8f0f + 8001ac4: ffff8000 .word 0xffff8000 + +08001ac8 : + +HAL_StatusTypeDef HAL_PCDEx_PMAConfig(PCD_HandleTypeDef *hpcd, + uint16_t ep_addr, + uint16_t ep_kind, + uint32_t pmaadress) +{ + 8001ac8: b590 push {r4, r7, lr} + 8001aca: b087 sub sp, #28 + 8001acc: af00 add r7, sp, #0 + 8001ace: 60f8 str r0, [r7, #12] + 8001ad0: 0008 movs r0, r1 + 8001ad2: 0011 movs r1, r2 + 8001ad4: 607b str r3, [r7, #4] + 8001ad6: 240a movs r4, #10 + 8001ad8: 193b adds r3, r7, r4 + 8001ada: 1c02 adds r2, r0, #0 + 8001adc: 801a strh r2, [r3, #0] + 8001ade: 2308 movs r3, #8 + 8001ae0: 18fb adds r3, r7, r3 + 8001ae2: 1c0a adds r2, r1, #0 + 8001ae4: 801a strh r2, [r3, #0] + PCD_EPTypeDef *ep; + + /* initialize ep structure*/ + if ((0x80U & ep_addr) == 0x80U) + 8001ae6: 193b adds r3, r7, r4 + 8001ae8: 881b ldrh r3, [r3, #0] + 8001aea: 2280 movs r2, #128 ; 0x80 + 8001aec: 4013 ands r3, r2 + 8001aee: b29b uxth r3, r3 + 8001af0: 2b00 cmp r3, #0 + 8001af2: d00a beq.n 8001b0a + { + ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK]; + 8001af4: 230a movs r3, #10 + 8001af6: 18fb adds r3, r7, r3 + 8001af8: 881b ldrh r3, [r3, #0] + 8001afa: 2207 movs r2, #7 + 8001afc: 4013 ands r3, r2 + 8001afe: 015b lsls r3, r3, #5 + 8001b00: 3328 adds r3, #40 ; 0x28 + 8001b02: 68fa ldr r2, [r7, #12] + 8001b04: 18d3 adds r3, r2, r3 + 8001b06: 617b str r3, [r7, #20] + 8001b08: e008 b.n 8001b1c + } + else + { + ep = &hpcd->OUT_ep[ep_addr]; + 8001b0a: 230a movs r3, #10 + 8001b0c: 18fb adds r3, r7, r3 + 8001b0e: 881b ldrh r3, [r3, #0] + 8001b10: 015b lsls r3, r3, #5 + 8001b12: 3329 adds r3, #41 ; 0x29 + 8001b14: 33ff adds r3, #255 ; 0xff + 8001b16: 68fa ldr r2, [r7, #12] + 8001b18: 18d3 adds r3, r2, r3 + 8001b1a: 617b str r3, [r7, #20] + } + + /* Here we check if the endpoint is single or double Buffer*/ + if (ep_kind == PCD_SNG_BUF) + 8001b1c: 2308 movs r3, #8 + 8001b1e: 18fb adds r3, r7, r3 + 8001b20: 881b ldrh r3, [r3, #0] + 8001b22: 2b00 cmp r3, #0 + 8001b24: d107 bne.n 8001b36 + { + /* Single Buffer */ + ep->doublebuffer = 0U; + 8001b26: 697b ldr r3, [r7, #20] + 8001b28: 2200 movs r2, #0 + 8001b2a: 731a strb r2, [r3, #12] + /* Configure the PMA */ + ep->pmaadress = (uint16_t)pmaadress; + 8001b2c: 687b ldr r3, [r7, #4] + 8001b2e: b29a uxth r2, r3 + 8001b30: 697b ldr r3, [r7, #20] + 8001b32: 80da strh r2, [r3, #6] + 8001b34: e00b b.n 8001b4e + } + else /* USB_DBL_BUF */ + { + /* Double Buffer Endpoint */ + ep->doublebuffer = 1U; + 8001b36: 697b ldr r3, [r7, #20] + 8001b38: 2201 movs r2, #1 + 8001b3a: 731a strb r2, [r3, #12] + /* Configure the PMA */ + ep->pmaaddr0 = (uint16_t)(pmaadress & 0xFFFFU); + 8001b3c: 687b ldr r3, [r7, #4] + 8001b3e: b29a uxth r2, r3 + 8001b40: 697b ldr r3, [r7, #20] + 8001b42: 811a strh r2, [r3, #8] + ep->pmaaddr1 = (uint16_t)((pmaadress & 0xFFFF0000U) >> 16); + 8001b44: 687b ldr r3, [r7, #4] + 8001b46: 0c1b lsrs r3, r3, #16 + 8001b48: b29a uxth r2, r3 + 8001b4a: 697b ldr r3, [r7, #20] + 8001b4c: 815a strh r2, [r3, #10] + } + + return HAL_OK; + 8001b4e: 2300 movs r3, #0 +} + 8001b50: 0018 movs r0, r3 + 8001b52: 46bd mov sp, r7 + 8001b54: b007 add sp, #28 + 8001b56: bd90 pop {r4, r7, pc} + +08001b58 : + * @brief Activate LPM feature. + * @param hpcd PCD handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCDEx_ActivateLPM(PCD_HandleTypeDef *hpcd) +{ + 8001b58: b580 push {r7, lr} + 8001b5a: b084 sub sp, #16 + 8001b5c: af00 add r7, sp, #0 + 8001b5e: 6078 str r0, [r7, #4] + + USB_TypeDef *USBx = hpcd->Instance; + 8001b60: 687b ldr r3, [r7, #4] + 8001b62: 681b ldr r3, [r3, #0] + 8001b64: 60fb str r3, [r7, #12] + hpcd->lpm_active = 1U; + 8001b66: 687a ldr r2, [r7, #4] + 8001b68: 239a movs r3, #154 ; 0x9a + 8001b6a: 009b lsls r3, r3, #2 + 8001b6c: 2101 movs r1, #1 + 8001b6e: 50d1 str r1, [r2, r3] + hpcd->LPM_State = LPM_L0; + 8001b70: 687a ldr r2, [r7, #4] + 8001b72: 2398 movs r3, #152 ; 0x98 + 8001b74: 009b lsls r3, r3, #2 + 8001b76: 2100 movs r1, #0 + 8001b78: 54d1 strb r1, [r2, r3] + + USBx->LPMCSR |= USB_LPMCSR_LMPEN; + 8001b7a: 68fb ldr r3, [r7, #12] + 8001b7c: 2254 movs r2, #84 ; 0x54 + 8001b7e: 5a9b ldrh r3, [r3, r2] + 8001b80: b29b uxth r3, r3 + 8001b82: 2201 movs r2, #1 + 8001b84: 4313 orrs r3, r2 + 8001b86: b299 uxth r1, r3 + 8001b88: 68fb ldr r3, [r7, #12] + 8001b8a: 2254 movs r2, #84 ; 0x54 + 8001b8c: 5299 strh r1, [r3, r2] + USBx->LPMCSR |= USB_LPMCSR_LPMACK; + 8001b8e: 68fb ldr r3, [r7, #12] + 8001b90: 2254 movs r2, #84 ; 0x54 + 8001b92: 5a9b ldrh r3, [r3, r2] + 8001b94: b29b uxth r3, r3 + 8001b96: 2202 movs r2, #2 + 8001b98: 4313 orrs r3, r2 + 8001b9a: b299 uxth r1, r3 + 8001b9c: 68fb ldr r3, [r7, #12] + 8001b9e: 2254 movs r2, #84 ; 0x54 + 8001ba0: 5299 strh r1, [r3, r2] + + return HAL_OK; + 8001ba2: 2300 movs r3, #0 +} + 8001ba4: 0018 movs r0, r3 + 8001ba6: 46bd mov sp, r7 + 8001ba8: b004 add sp, #16 + 8001baa: bd80 pop {r7, pc} + +08001bac : + * @param hpcd PCD handle + * @param msg LPM message + * @retval HAL status + */ +__weak void HAL_PCDEx_LPM_Callback(PCD_HandleTypeDef *hpcd, PCD_LPM_MsgTypeDef msg) +{ + 8001bac: b580 push {r7, lr} + 8001bae: b082 sub sp, #8 + 8001bb0: af00 add r7, sp, #0 + 8001bb2: 6078 str r0, [r7, #4] + 8001bb4: 000a movs r2, r1 + 8001bb6: 1cfb adds r3, r7, #3 + 8001bb8: 701a strb r2, [r3, #0] + UNUSED(msg); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_PCDEx_LPM_Callback could be implemented in the user file + */ +} + 8001bba: 46c0 nop ; (mov r8, r8) + 8001bbc: 46bd mov sp, r7 + 8001bbe: b002 add sp, #8 + 8001bc0: bd80 pop {r7, pc} + ... + +08001bc4 : + * supported by this macro. User should request a transition to HSE Off + * first and then HSE On or HSE Bypass. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RCC_OscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct) +{ + 8001bc4: b580 push {r7, lr} + 8001bc6: b088 sub sp, #32 + 8001bc8: af00 add r7, sp, #0 + 8001bca: 6078 str r0, [r7, #4] + uint32_t tickstart; + uint32_t pll_config; + uint32_t pll_config2; + + /* Check Null pointer */ + if(RCC_OscInitStruct == NULL) + 8001bcc: 687b ldr r3, [r7, #4] + 8001bce: 2b00 cmp r3, #0 + 8001bd0: d102 bne.n 8001bd8 + { + return HAL_ERROR; + 8001bd2: 2301 movs r3, #1 + 8001bd4: f000 fb76 bl 80022c4 + + /* Check the parameters */ + assert_param(IS_RCC_OSCILLATORTYPE(RCC_OscInitStruct->OscillatorType)); + + /*------------------------------- HSE Configuration ------------------------*/ + if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSE) == RCC_OSCILLATORTYPE_HSE) + 8001bd8: 687b ldr r3, [r7, #4] + 8001bda: 681b ldr r3, [r3, #0] + 8001bdc: 2201 movs r2, #1 + 8001bde: 4013 ands r3, r2 + 8001be0: d100 bne.n 8001be4 + 8001be2: e08e b.n 8001d02 + { + /* Check the parameters */ + assert_param(IS_RCC_HSE(RCC_OscInitStruct->HSEState)); + + /* When the HSE is used as system clock or clock source for PLL in these cases it is not allowed to be disabled */ + if((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_HSE) + 8001be4: 4bc5 ldr r3, [pc, #788] ; (8001efc ) + 8001be6: 685b ldr r3, [r3, #4] + 8001be8: 220c movs r2, #12 + 8001bea: 4013 ands r3, r2 + 8001bec: 2b04 cmp r3, #4 + 8001bee: d00e beq.n 8001c0e + || ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && (__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_HSE))) + 8001bf0: 4bc2 ldr r3, [pc, #776] ; (8001efc ) + 8001bf2: 685b ldr r3, [r3, #4] + 8001bf4: 220c movs r2, #12 + 8001bf6: 4013 ands r3, r2 + 8001bf8: 2b08 cmp r3, #8 + 8001bfa: d117 bne.n 8001c2c + 8001bfc: 4bbf ldr r3, [pc, #764] ; (8001efc ) + 8001bfe: 685a ldr r2, [r3, #4] + 8001c00: 23c0 movs r3, #192 ; 0xc0 + 8001c02: 025b lsls r3, r3, #9 + 8001c04: 401a ands r2, r3 + 8001c06: 2380 movs r3, #128 ; 0x80 + 8001c08: 025b lsls r3, r3, #9 + 8001c0a: 429a cmp r2, r3 + 8001c0c: d10e bne.n 8001c2c + { + if((__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) != RESET) && (RCC_OscInitStruct->HSEState == RCC_HSE_OFF)) + 8001c0e: 4bbb ldr r3, [pc, #748] ; (8001efc ) + 8001c10: 681a ldr r2, [r3, #0] + 8001c12: 2380 movs r3, #128 ; 0x80 + 8001c14: 029b lsls r3, r3, #10 + 8001c16: 4013 ands r3, r2 + 8001c18: d100 bne.n 8001c1c + 8001c1a: e071 b.n 8001d00 + 8001c1c: 687b ldr r3, [r7, #4] + 8001c1e: 685b ldr r3, [r3, #4] + 8001c20: 2b00 cmp r3, #0 + 8001c22: d000 beq.n 8001c26 + 8001c24: e06c b.n 8001d00 + { + return HAL_ERROR; + 8001c26: 2301 movs r3, #1 + 8001c28: f000 fb4c bl 80022c4 + } + } + else + { + /* Set the new HSE configuration ---------------------------------------*/ + __HAL_RCC_HSE_CONFIG(RCC_OscInitStruct->HSEState); + 8001c2c: 687b ldr r3, [r7, #4] + 8001c2e: 685b ldr r3, [r3, #4] + 8001c30: 2b01 cmp r3, #1 + 8001c32: d107 bne.n 8001c44 + 8001c34: 4bb1 ldr r3, [pc, #708] ; (8001efc ) + 8001c36: 681a ldr r2, [r3, #0] + 8001c38: 4bb0 ldr r3, [pc, #704] ; (8001efc ) + 8001c3a: 2180 movs r1, #128 ; 0x80 + 8001c3c: 0249 lsls r1, r1, #9 + 8001c3e: 430a orrs r2, r1 + 8001c40: 601a str r2, [r3, #0] + 8001c42: e02f b.n 8001ca4 + 8001c44: 687b ldr r3, [r7, #4] + 8001c46: 685b ldr r3, [r3, #4] + 8001c48: 2b00 cmp r3, #0 + 8001c4a: d10c bne.n 8001c66 + 8001c4c: 4bab ldr r3, [pc, #684] ; (8001efc ) + 8001c4e: 681a ldr r2, [r3, #0] + 8001c50: 4baa ldr r3, [pc, #680] ; (8001efc ) + 8001c52: 49ab ldr r1, [pc, #684] ; (8001f00 ) + 8001c54: 400a ands r2, r1 + 8001c56: 601a str r2, [r3, #0] + 8001c58: 4ba8 ldr r3, [pc, #672] ; (8001efc ) + 8001c5a: 681a ldr r2, [r3, #0] + 8001c5c: 4ba7 ldr r3, [pc, #668] ; (8001efc ) + 8001c5e: 49a9 ldr r1, [pc, #676] ; (8001f04 ) + 8001c60: 400a ands r2, r1 + 8001c62: 601a str r2, [r3, #0] + 8001c64: e01e b.n 8001ca4 + 8001c66: 687b ldr r3, [r7, #4] + 8001c68: 685b ldr r3, [r3, #4] + 8001c6a: 2b05 cmp r3, #5 + 8001c6c: d10e bne.n 8001c8c + 8001c6e: 4ba3 ldr r3, [pc, #652] ; (8001efc ) + 8001c70: 681a ldr r2, [r3, #0] + 8001c72: 4ba2 ldr r3, [pc, #648] ; (8001efc ) + 8001c74: 2180 movs r1, #128 ; 0x80 + 8001c76: 02c9 lsls r1, r1, #11 + 8001c78: 430a orrs r2, r1 + 8001c7a: 601a str r2, [r3, #0] + 8001c7c: 4b9f ldr r3, [pc, #636] ; (8001efc ) + 8001c7e: 681a ldr r2, [r3, #0] + 8001c80: 4b9e ldr r3, [pc, #632] ; (8001efc ) + 8001c82: 2180 movs r1, #128 ; 0x80 + 8001c84: 0249 lsls r1, r1, #9 + 8001c86: 430a orrs r2, r1 + 8001c88: 601a str r2, [r3, #0] + 8001c8a: e00b b.n 8001ca4 + 8001c8c: 4b9b ldr r3, [pc, #620] ; (8001efc ) + 8001c8e: 681a ldr r2, [r3, #0] + 8001c90: 4b9a ldr r3, [pc, #616] ; (8001efc ) + 8001c92: 499b ldr r1, [pc, #620] ; (8001f00 ) + 8001c94: 400a ands r2, r1 + 8001c96: 601a str r2, [r3, #0] + 8001c98: 4b98 ldr r3, [pc, #608] ; (8001efc ) + 8001c9a: 681a ldr r2, [r3, #0] + 8001c9c: 4b97 ldr r3, [pc, #604] ; (8001efc ) + 8001c9e: 4999 ldr r1, [pc, #612] ; (8001f04 ) + 8001ca0: 400a ands r2, r1 + 8001ca2: 601a str r2, [r3, #0] + + + /* Check the HSE State */ + if(RCC_OscInitStruct->HSEState != RCC_HSE_OFF) + 8001ca4: 687b ldr r3, [r7, #4] + 8001ca6: 685b ldr r3, [r3, #4] + 8001ca8: 2b00 cmp r3, #0 + 8001caa: d014 beq.n 8001cd6 + { + /* Get Start Tick */ + tickstart = HAL_GetTick(); + 8001cac: f7fe fd0a bl 80006c4 + 8001cb0: 0003 movs r3, r0 + 8001cb2: 61bb str r3, [r7, #24] + + /* Wait till HSE is ready */ + while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) == RESET) + 8001cb4: e008 b.n 8001cc8 + { + if((HAL_GetTick() - tickstart ) > HSE_TIMEOUT_VALUE) + 8001cb6: f7fe fd05 bl 80006c4 + 8001cba: 0002 movs r2, r0 + 8001cbc: 69bb ldr r3, [r7, #24] + 8001cbe: 1ad3 subs r3, r2, r3 + 8001cc0: 2b64 cmp r3, #100 ; 0x64 + 8001cc2: d901 bls.n 8001cc8 + { + return HAL_TIMEOUT; + 8001cc4: 2303 movs r3, #3 + 8001cc6: e2fd b.n 80022c4 + while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) == RESET) + 8001cc8: 4b8c ldr r3, [pc, #560] ; (8001efc ) + 8001cca: 681a ldr r2, [r3, #0] + 8001ccc: 2380 movs r3, #128 ; 0x80 + 8001cce: 029b lsls r3, r3, #10 + 8001cd0: 4013 ands r3, r2 + 8001cd2: d0f0 beq.n 8001cb6 + 8001cd4: e015 b.n 8001d02 + } + } + else + { + /* Get Start Tick */ + tickstart = HAL_GetTick(); + 8001cd6: f7fe fcf5 bl 80006c4 + 8001cda: 0003 movs r3, r0 + 8001cdc: 61bb str r3, [r7, #24] + + /* Wait till HSE is disabled */ + while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) != RESET) + 8001cde: e008 b.n 8001cf2 + { + if((HAL_GetTick() - tickstart ) > HSE_TIMEOUT_VALUE) + 8001ce0: f7fe fcf0 bl 80006c4 + 8001ce4: 0002 movs r2, r0 + 8001ce6: 69bb ldr r3, [r7, #24] + 8001ce8: 1ad3 subs r3, r2, r3 + 8001cea: 2b64 cmp r3, #100 ; 0x64 + 8001cec: d901 bls.n 8001cf2 + { + return HAL_TIMEOUT; + 8001cee: 2303 movs r3, #3 + 8001cf0: e2e8 b.n 80022c4 + while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) != RESET) + 8001cf2: 4b82 ldr r3, [pc, #520] ; (8001efc ) + 8001cf4: 681a ldr r2, [r3, #0] + 8001cf6: 2380 movs r3, #128 ; 0x80 + 8001cf8: 029b lsls r3, r3, #10 + 8001cfa: 4013 ands r3, r2 + 8001cfc: d1f0 bne.n 8001ce0 + 8001cfe: e000 b.n 8001d02 + if((__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) != RESET) && (RCC_OscInitStruct->HSEState == RCC_HSE_OFF)) + 8001d00: 46c0 nop ; (mov r8, r8) + } + } + } + } + /*----------------------------- HSI Configuration --------------------------*/ + if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSI) == RCC_OSCILLATORTYPE_HSI) + 8001d02: 687b ldr r3, [r7, #4] + 8001d04: 681b ldr r3, [r3, #0] + 8001d06: 2202 movs r2, #2 + 8001d08: 4013 ands r3, r2 + 8001d0a: d100 bne.n 8001d0e + 8001d0c: e06c b.n 8001de8 + /* Check the parameters */ + assert_param(IS_RCC_HSI(RCC_OscInitStruct->HSIState)); + assert_param(IS_RCC_CALIBRATION_VALUE(RCC_OscInitStruct->HSICalibrationValue)); + + /* Check if HSI is used as system clock or as PLL source when PLL is selected as system clock */ + if((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_HSI) + 8001d0e: 4b7b ldr r3, [pc, #492] ; (8001efc ) + 8001d10: 685b ldr r3, [r3, #4] + 8001d12: 220c movs r2, #12 + 8001d14: 4013 ands r3, r2 + 8001d16: d00e beq.n 8001d36 + || ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && (__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_HSI))) + 8001d18: 4b78 ldr r3, [pc, #480] ; (8001efc ) + 8001d1a: 685b ldr r3, [r3, #4] + 8001d1c: 220c movs r2, #12 + 8001d1e: 4013 ands r3, r2 + 8001d20: 2b08 cmp r3, #8 + 8001d22: d11f bne.n 8001d64 + 8001d24: 4b75 ldr r3, [pc, #468] ; (8001efc ) + 8001d26: 685a ldr r2, [r3, #4] + 8001d28: 23c0 movs r3, #192 ; 0xc0 + 8001d2a: 025b lsls r3, r3, #9 + 8001d2c: 401a ands r2, r3 + 8001d2e: 2380 movs r3, #128 ; 0x80 + 8001d30: 021b lsls r3, r3, #8 + 8001d32: 429a cmp r2, r3 + 8001d34: d116 bne.n 8001d64 + { + /* When HSI is used as system clock it will not disabled */ + if((__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) != RESET) && (RCC_OscInitStruct->HSIState != RCC_HSI_ON)) + 8001d36: 4b71 ldr r3, [pc, #452] ; (8001efc ) + 8001d38: 681b ldr r3, [r3, #0] + 8001d3a: 2202 movs r2, #2 + 8001d3c: 4013 ands r3, r2 + 8001d3e: d005 beq.n 8001d4c + 8001d40: 687b ldr r3, [r7, #4] + 8001d42: 68db ldr r3, [r3, #12] + 8001d44: 2b01 cmp r3, #1 + 8001d46: d001 beq.n 8001d4c + { + return HAL_ERROR; + 8001d48: 2301 movs r3, #1 + 8001d4a: e2bb b.n 80022c4 + } + /* Otherwise, just the calibration is allowed */ + else + { + /* Adjusts the Internal High Speed oscillator (HSI) calibration value.*/ + __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->HSICalibrationValue); + 8001d4c: 4b6b ldr r3, [pc, #428] ; (8001efc ) + 8001d4e: 681b ldr r3, [r3, #0] + 8001d50: 22f8 movs r2, #248 ; 0xf8 + 8001d52: 4393 bics r3, r2 + 8001d54: 0019 movs r1, r3 + 8001d56: 687b ldr r3, [r7, #4] + 8001d58: 691b ldr r3, [r3, #16] + 8001d5a: 00da lsls r2, r3, #3 + 8001d5c: 4b67 ldr r3, [pc, #412] ; (8001efc ) + 8001d5e: 430a orrs r2, r1 + 8001d60: 601a str r2, [r3, #0] + if((__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) != RESET) && (RCC_OscInitStruct->HSIState != RCC_HSI_ON)) + 8001d62: e041 b.n 8001de8 + } + } + else + { + /* Check the HSI State */ + if(RCC_OscInitStruct->HSIState != RCC_HSI_OFF) + 8001d64: 687b ldr r3, [r7, #4] + 8001d66: 68db ldr r3, [r3, #12] + 8001d68: 2b00 cmp r3, #0 + 8001d6a: d024 beq.n 8001db6 + { + /* Enable the Internal High Speed oscillator (HSI). */ + __HAL_RCC_HSI_ENABLE(); + 8001d6c: 4b63 ldr r3, [pc, #396] ; (8001efc ) + 8001d6e: 681a ldr r2, [r3, #0] + 8001d70: 4b62 ldr r3, [pc, #392] ; (8001efc ) + 8001d72: 2101 movs r1, #1 + 8001d74: 430a orrs r2, r1 + 8001d76: 601a str r2, [r3, #0] + + /* Get Start Tick */ + tickstart = HAL_GetTick(); + 8001d78: f7fe fca4 bl 80006c4 + 8001d7c: 0003 movs r3, r0 + 8001d7e: 61bb str r3, [r7, #24] + + /* Wait till HSI is ready */ + while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) == RESET) + 8001d80: e008 b.n 8001d94 + { + if((HAL_GetTick() - tickstart ) > HSI_TIMEOUT_VALUE) + 8001d82: f7fe fc9f bl 80006c4 + 8001d86: 0002 movs r2, r0 + 8001d88: 69bb ldr r3, [r7, #24] + 8001d8a: 1ad3 subs r3, r2, r3 + 8001d8c: 2b02 cmp r3, #2 + 8001d8e: d901 bls.n 8001d94 + { + return HAL_TIMEOUT; + 8001d90: 2303 movs r3, #3 + 8001d92: e297 b.n 80022c4 + while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) == RESET) + 8001d94: 4b59 ldr r3, [pc, #356] ; (8001efc ) + 8001d96: 681b ldr r3, [r3, #0] + 8001d98: 2202 movs r2, #2 + 8001d9a: 4013 ands r3, r2 + 8001d9c: d0f1 beq.n 8001d82 + } + } + + /* Adjusts the Internal High Speed oscillator (HSI) calibration value.*/ + __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->HSICalibrationValue); + 8001d9e: 4b57 ldr r3, [pc, #348] ; (8001efc ) + 8001da0: 681b ldr r3, [r3, #0] + 8001da2: 22f8 movs r2, #248 ; 0xf8 + 8001da4: 4393 bics r3, r2 + 8001da6: 0019 movs r1, r3 + 8001da8: 687b ldr r3, [r7, #4] + 8001daa: 691b ldr r3, [r3, #16] + 8001dac: 00da lsls r2, r3, #3 + 8001dae: 4b53 ldr r3, [pc, #332] ; (8001efc ) + 8001db0: 430a orrs r2, r1 + 8001db2: 601a str r2, [r3, #0] + 8001db4: e018 b.n 8001de8 + } + else + { + /* Disable the Internal High Speed oscillator (HSI). */ + __HAL_RCC_HSI_DISABLE(); + 8001db6: 4b51 ldr r3, [pc, #324] ; (8001efc ) + 8001db8: 681a ldr r2, [r3, #0] + 8001dba: 4b50 ldr r3, [pc, #320] ; (8001efc ) + 8001dbc: 2101 movs r1, #1 + 8001dbe: 438a bics r2, r1 + 8001dc0: 601a str r2, [r3, #0] + + /* Get Start Tick */ + tickstart = HAL_GetTick(); + 8001dc2: f7fe fc7f bl 80006c4 + 8001dc6: 0003 movs r3, r0 + 8001dc8: 61bb str r3, [r7, #24] + + /* Wait till HSI is disabled */ + while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) != RESET) + 8001dca: e008 b.n 8001dde + { + if((HAL_GetTick() - tickstart ) > HSI_TIMEOUT_VALUE) + 8001dcc: f7fe fc7a bl 80006c4 + 8001dd0: 0002 movs r2, r0 + 8001dd2: 69bb ldr r3, [r7, #24] + 8001dd4: 1ad3 subs r3, r2, r3 + 8001dd6: 2b02 cmp r3, #2 + 8001dd8: d901 bls.n 8001dde + { + return HAL_TIMEOUT; + 8001dda: 2303 movs r3, #3 + 8001ddc: e272 b.n 80022c4 + while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) != RESET) + 8001dde: 4b47 ldr r3, [pc, #284] ; (8001efc ) + 8001de0: 681b ldr r3, [r3, #0] + 8001de2: 2202 movs r2, #2 + 8001de4: 4013 ands r3, r2 + 8001de6: d1f1 bne.n 8001dcc + } + } + } + } + /*------------------------------ LSI Configuration -------------------------*/ + if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSI) == RCC_OSCILLATORTYPE_LSI) + 8001de8: 687b ldr r3, [r7, #4] + 8001dea: 681b ldr r3, [r3, #0] + 8001dec: 2208 movs r2, #8 + 8001dee: 4013 ands r3, r2 + 8001df0: d036 beq.n 8001e60 + { + /* Check the parameters */ + assert_param(IS_RCC_LSI(RCC_OscInitStruct->LSIState)); + + /* Check the LSI State */ + if(RCC_OscInitStruct->LSIState != RCC_LSI_OFF) + 8001df2: 687b ldr r3, [r7, #4] + 8001df4: 69db ldr r3, [r3, #28] + 8001df6: 2b00 cmp r3, #0 + 8001df8: d019 beq.n 8001e2e + { + /* Enable the Internal Low Speed oscillator (LSI). */ + __HAL_RCC_LSI_ENABLE(); + 8001dfa: 4b40 ldr r3, [pc, #256] ; (8001efc ) + 8001dfc: 6a5a ldr r2, [r3, #36] ; 0x24 + 8001dfe: 4b3f ldr r3, [pc, #252] ; (8001efc ) + 8001e00: 2101 movs r1, #1 + 8001e02: 430a orrs r2, r1 + 8001e04: 625a str r2, [r3, #36] ; 0x24 + + /* Get Start Tick */ + tickstart = HAL_GetTick(); + 8001e06: f7fe fc5d bl 80006c4 + 8001e0a: 0003 movs r3, r0 + 8001e0c: 61bb str r3, [r7, #24] + + /* Wait till LSI is ready */ + while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSIRDY) == RESET) + 8001e0e: e008 b.n 8001e22 + { + if((HAL_GetTick() - tickstart ) > LSI_TIMEOUT_VALUE) + 8001e10: f7fe fc58 bl 80006c4 + 8001e14: 0002 movs r2, r0 + 8001e16: 69bb ldr r3, [r7, #24] + 8001e18: 1ad3 subs r3, r2, r3 + 8001e1a: 2b02 cmp r3, #2 + 8001e1c: d901 bls.n 8001e22 + { + return HAL_TIMEOUT; + 8001e1e: 2303 movs r3, #3 + 8001e20: e250 b.n 80022c4 + while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSIRDY) == RESET) + 8001e22: 4b36 ldr r3, [pc, #216] ; (8001efc ) + 8001e24: 6a5b ldr r3, [r3, #36] ; 0x24 + 8001e26: 2202 movs r2, #2 + 8001e28: 4013 ands r3, r2 + 8001e2a: d0f1 beq.n 8001e10 + 8001e2c: e018 b.n 8001e60 + } + } + else + { + /* Disable the Internal Low Speed oscillator (LSI). */ + __HAL_RCC_LSI_DISABLE(); + 8001e2e: 4b33 ldr r3, [pc, #204] ; (8001efc ) + 8001e30: 6a5a ldr r2, [r3, #36] ; 0x24 + 8001e32: 4b32 ldr r3, [pc, #200] ; (8001efc ) + 8001e34: 2101 movs r1, #1 + 8001e36: 438a bics r2, r1 + 8001e38: 625a str r2, [r3, #36] ; 0x24 + + /* Get Start Tick */ + tickstart = HAL_GetTick(); + 8001e3a: f7fe fc43 bl 80006c4 + 8001e3e: 0003 movs r3, r0 + 8001e40: 61bb str r3, [r7, #24] + + /* Wait till LSI is disabled */ + while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSIRDY) != RESET) + 8001e42: e008 b.n 8001e56 + { + if((HAL_GetTick() - tickstart ) > LSI_TIMEOUT_VALUE) + 8001e44: f7fe fc3e bl 80006c4 + 8001e48: 0002 movs r2, r0 + 8001e4a: 69bb ldr r3, [r7, #24] + 8001e4c: 1ad3 subs r3, r2, r3 + 8001e4e: 2b02 cmp r3, #2 + 8001e50: d901 bls.n 8001e56 + { + return HAL_TIMEOUT; + 8001e52: 2303 movs r3, #3 + 8001e54: e236 b.n 80022c4 + while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSIRDY) != RESET) + 8001e56: 4b29 ldr r3, [pc, #164] ; (8001efc ) + 8001e58: 6a5b ldr r3, [r3, #36] ; 0x24 + 8001e5a: 2202 movs r2, #2 + 8001e5c: 4013 ands r3, r2 + 8001e5e: d1f1 bne.n 8001e44 + } + } + } + } + /*------------------------------ LSE Configuration -------------------------*/ + if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSE) == RCC_OSCILLATORTYPE_LSE) + 8001e60: 687b ldr r3, [r7, #4] + 8001e62: 681b ldr r3, [r3, #0] + 8001e64: 2204 movs r2, #4 + 8001e66: 4013 ands r3, r2 + 8001e68: d100 bne.n 8001e6c + 8001e6a: e0b5 b.n 8001fd8 + { + FlagStatus pwrclkchanged = RESET; + 8001e6c: 231f movs r3, #31 + 8001e6e: 18fb adds r3, r7, r3 + 8001e70: 2200 movs r2, #0 + 8001e72: 701a strb r2, [r3, #0] + /* Check the parameters */ + assert_param(IS_RCC_LSE(RCC_OscInitStruct->LSEState)); + + /* Update LSE configuration in Backup Domain control register */ + /* Requires to enable write access to Backup Domain of necessary */ + if(__HAL_RCC_PWR_IS_CLK_DISABLED()) + 8001e74: 4b21 ldr r3, [pc, #132] ; (8001efc ) + 8001e76: 69da ldr r2, [r3, #28] + 8001e78: 2380 movs r3, #128 ; 0x80 + 8001e7a: 055b lsls r3, r3, #21 + 8001e7c: 4013 ands r3, r2 + 8001e7e: d111 bne.n 8001ea4 + { + __HAL_RCC_PWR_CLK_ENABLE(); + 8001e80: 4b1e ldr r3, [pc, #120] ; (8001efc ) + 8001e82: 69da ldr r2, [r3, #28] + 8001e84: 4b1d ldr r3, [pc, #116] ; (8001efc ) + 8001e86: 2180 movs r1, #128 ; 0x80 + 8001e88: 0549 lsls r1, r1, #21 + 8001e8a: 430a orrs r2, r1 + 8001e8c: 61da str r2, [r3, #28] + 8001e8e: 4b1b ldr r3, [pc, #108] ; (8001efc ) + 8001e90: 69da ldr r2, [r3, #28] + 8001e92: 2380 movs r3, #128 ; 0x80 + 8001e94: 055b lsls r3, r3, #21 + 8001e96: 4013 ands r3, r2 + 8001e98: 60fb str r3, [r7, #12] + 8001e9a: 68fb ldr r3, [r7, #12] + pwrclkchanged = SET; + 8001e9c: 231f movs r3, #31 + 8001e9e: 18fb adds r3, r7, r3 + 8001ea0: 2201 movs r2, #1 + 8001ea2: 701a strb r2, [r3, #0] + } + + if(HAL_IS_BIT_CLR(PWR->CR, PWR_CR_DBP)) + 8001ea4: 4b18 ldr r3, [pc, #96] ; (8001f08 ) + 8001ea6: 681a ldr r2, [r3, #0] + 8001ea8: 2380 movs r3, #128 ; 0x80 + 8001eaa: 005b lsls r3, r3, #1 + 8001eac: 4013 ands r3, r2 + 8001eae: d11a bne.n 8001ee6 + { + /* Enable write access to Backup domain */ + SET_BIT(PWR->CR, PWR_CR_DBP); + 8001eb0: 4b15 ldr r3, [pc, #84] ; (8001f08 ) + 8001eb2: 681a ldr r2, [r3, #0] + 8001eb4: 4b14 ldr r3, [pc, #80] ; (8001f08 ) + 8001eb6: 2180 movs r1, #128 ; 0x80 + 8001eb8: 0049 lsls r1, r1, #1 + 8001eba: 430a orrs r2, r1 + 8001ebc: 601a str r2, [r3, #0] + + /* Wait for Backup domain Write protection disable */ + tickstart = HAL_GetTick(); + 8001ebe: f7fe fc01 bl 80006c4 + 8001ec2: 0003 movs r3, r0 + 8001ec4: 61bb str r3, [r7, #24] + + while(HAL_IS_BIT_CLR(PWR->CR, PWR_CR_DBP)) + 8001ec6: e008 b.n 8001eda + { + if((HAL_GetTick() - tickstart) > RCC_DBP_TIMEOUT_VALUE) + 8001ec8: f7fe fbfc bl 80006c4 + 8001ecc: 0002 movs r2, r0 + 8001ece: 69bb ldr r3, [r7, #24] + 8001ed0: 1ad3 subs r3, r2, r3 + 8001ed2: 2b64 cmp r3, #100 ; 0x64 + 8001ed4: d901 bls.n 8001eda + { + return HAL_TIMEOUT; + 8001ed6: 2303 movs r3, #3 + 8001ed8: e1f4 b.n 80022c4 + while(HAL_IS_BIT_CLR(PWR->CR, PWR_CR_DBP)) + 8001eda: 4b0b ldr r3, [pc, #44] ; (8001f08 ) + 8001edc: 681a ldr r2, [r3, #0] + 8001ede: 2380 movs r3, #128 ; 0x80 + 8001ee0: 005b lsls r3, r3, #1 + 8001ee2: 4013 ands r3, r2 + 8001ee4: d0f0 beq.n 8001ec8 + } + } + } + + /* Set the new LSE configuration -----------------------------------------*/ + __HAL_RCC_LSE_CONFIG(RCC_OscInitStruct->LSEState); + 8001ee6: 687b ldr r3, [r7, #4] + 8001ee8: 689b ldr r3, [r3, #8] + 8001eea: 2b01 cmp r3, #1 + 8001eec: d10e bne.n 8001f0c + 8001eee: 4b03 ldr r3, [pc, #12] ; (8001efc ) + 8001ef0: 6a1a ldr r2, [r3, #32] + 8001ef2: 4b02 ldr r3, [pc, #8] ; (8001efc ) + 8001ef4: 2101 movs r1, #1 + 8001ef6: 430a orrs r2, r1 + 8001ef8: 621a str r2, [r3, #32] + 8001efa: e035 b.n 8001f68 + 8001efc: 40021000 .word 0x40021000 + 8001f00: fffeffff .word 0xfffeffff + 8001f04: fffbffff .word 0xfffbffff + 8001f08: 40007000 .word 0x40007000 + 8001f0c: 687b ldr r3, [r7, #4] + 8001f0e: 689b ldr r3, [r3, #8] + 8001f10: 2b00 cmp r3, #0 + 8001f12: d10c bne.n 8001f2e + 8001f14: 4bca ldr r3, [pc, #808] ; (8002240 ) + 8001f16: 6a1a ldr r2, [r3, #32] + 8001f18: 4bc9 ldr r3, [pc, #804] ; (8002240 ) + 8001f1a: 2101 movs r1, #1 + 8001f1c: 438a bics r2, r1 + 8001f1e: 621a str r2, [r3, #32] + 8001f20: 4bc7 ldr r3, [pc, #796] ; (8002240 ) + 8001f22: 6a1a ldr r2, [r3, #32] + 8001f24: 4bc6 ldr r3, [pc, #792] ; (8002240 ) + 8001f26: 2104 movs r1, #4 + 8001f28: 438a bics r2, r1 + 8001f2a: 621a str r2, [r3, #32] + 8001f2c: e01c b.n 8001f68 + 8001f2e: 687b ldr r3, [r7, #4] + 8001f30: 689b ldr r3, [r3, #8] + 8001f32: 2b05 cmp r3, #5 + 8001f34: d10c bne.n 8001f50 + 8001f36: 4bc2 ldr r3, [pc, #776] ; (8002240 ) + 8001f38: 6a1a ldr r2, [r3, #32] + 8001f3a: 4bc1 ldr r3, [pc, #772] ; (8002240 ) + 8001f3c: 2104 movs r1, #4 + 8001f3e: 430a orrs r2, r1 + 8001f40: 621a str r2, [r3, #32] + 8001f42: 4bbf ldr r3, [pc, #764] ; (8002240 ) + 8001f44: 6a1a ldr r2, [r3, #32] + 8001f46: 4bbe ldr r3, [pc, #760] ; (8002240 ) + 8001f48: 2101 movs r1, #1 + 8001f4a: 430a orrs r2, r1 + 8001f4c: 621a str r2, [r3, #32] + 8001f4e: e00b b.n 8001f68 + 8001f50: 4bbb ldr r3, [pc, #748] ; (8002240 ) + 8001f52: 6a1a ldr r2, [r3, #32] + 8001f54: 4bba ldr r3, [pc, #744] ; (8002240 ) + 8001f56: 2101 movs r1, #1 + 8001f58: 438a bics r2, r1 + 8001f5a: 621a str r2, [r3, #32] + 8001f5c: 4bb8 ldr r3, [pc, #736] ; (8002240 ) + 8001f5e: 6a1a ldr r2, [r3, #32] + 8001f60: 4bb7 ldr r3, [pc, #732] ; (8002240 ) + 8001f62: 2104 movs r1, #4 + 8001f64: 438a bics r2, r1 + 8001f66: 621a str r2, [r3, #32] + /* Check the LSE State */ + if(RCC_OscInitStruct->LSEState != RCC_LSE_OFF) + 8001f68: 687b ldr r3, [r7, #4] + 8001f6a: 689b ldr r3, [r3, #8] + 8001f6c: 2b00 cmp r3, #0 + 8001f6e: d014 beq.n 8001f9a + { + /* Get Start Tick */ + tickstart = HAL_GetTick(); + 8001f70: f7fe fba8 bl 80006c4 + 8001f74: 0003 movs r3, r0 + 8001f76: 61bb str r3, [r7, #24] + + /* Wait till LSE is ready */ + while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET) + 8001f78: e009 b.n 8001f8e + { + if((HAL_GetTick() - tickstart ) > RCC_LSE_TIMEOUT_VALUE) + 8001f7a: f7fe fba3 bl 80006c4 + 8001f7e: 0002 movs r2, r0 + 8001f80: 69bb ldr r3, [r7, #24] + 8001f82: 1ad3 subs r3, r2, r3 + 8001f84: 4aaf ldr r2, [pc, #700] ; (8002244 ) + 8001f86: 4293 cmp r3, r2 + 8001f88: d901 bls.n 8001f8e + { + return HAL_TIMEOUT; + 8001f8a: 2303 movs r3, #3 + 8001f8c: e19a b.n 80022c4 + while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET) + 8001f8e: 4bac ldr r3, [pc, #688] ; (8002240 ) + 8001f90: 6a1b ldr r3, [r3, #32] + 8001f92: 2202 movs r2, #2 + 8001f94: 4013 ands r3, r2 + 8001f96: d0f0 beq.n 8001f7a + 8001f98: e013 b.n 8001fc2 + } + } + else + { + /* Get Start Tick */ + tickstart = HAL_GetTick(); + 8001f9a: f7fe fb93 bl 80006c4 + 8001f9e: 0003 movs r3, r0 + 8001fa0: 61bb str r3, [r7, #24] + + /* Wait till LSE is disabled */ + while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) != RESET) + 8001fa2: e009 b.n 8001fb8 + { + if((HAL_GetTick() - tickstart ) > RCC_LSE_TIMEOUT_VALUE) + 8001fa4: f7fe fb8e bl 80006c4 + 8001fa8: 0002 movs r2, r0 + 8001faa: 69bb ldr r3, [r7, #24] + 8001fac: 1ad3 subs r3, r2, r3 + 8001fae: 4aa5 ldr r2, [pc, #660] ; (8002244 ) + 8001fb0: 4293 cmp r3, r2 + 8001fb2: d901 bls.n 8001fb8 + { + return HAL_TIMEOUT; + 8001fb4: 2303 movs r3, #3 + 8001fb6: e185 b.n 80022c4 + while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) != RESET) + 8001fb8: 4ba1 ldr r3, [pc, #644] ; (8002240 ) + 8001fba: 6a1b ldr r3, [r3, #32] + 8001fbc: 2202 movs r2, #2 + 8001fbe: 4013 ands r3, r2 + 8001fc0: d1f0 bne.n 8001fa4 + } + } + } + + /* Require to disable power clock if necessary */ + if(pwrclkchanged == SET) + 8001fc2: 231f movs r3, #31 + 8001fc4: 18fb adds r3, r7, r3 + 8001fc6: 781b ldrb r3, [r3, #0] + 8001fc8: 2b01 cmp r3, #1 + 8001fca: d105 bne.n 8001fd8 + { + __HAL_RCC_PWR_CLK_DISABLE(); + 8001fcc: 4b9c ldr r3, [pc, #624] ; (8002240 ) + 8001fce: 69da ldr r2, [r3, #28] + 8001fd0: 4b9b ldr r3, [pc, #620] ; (8002240 ) + 8001fd2: 499d ldr r1, [pc, #628] ; (8002248 ) + 8001fd4: 400a ands r2, r1 + 8001fd6: 61da str r2, [r3, #28] + } + } + + /*----------------------------- HSI14 Configuration --------------------------*/ + if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSI14) == RCC_OSCILLATORTYPE_HSI14) + 8001fd8: 687b ldr r3, [r7, #4] + 8001fda: 681b ldr r3, [r3, #0] + 8001fdc: 2210 movs r2, #16 + 8001fde: 4013 ands r3, r2 + 8001fe0: d063 beq.n 80020aa + /* Check the parameters */ + assert_param(IS_RCC_HSI14(RCC_OscInitStruct->HSI14State)); + assert_param(IS_RCC_CALIBRATION_VALUE(RCC_OscInitStruct->HSI14CalibrationValue)); + + /* Check the HSI14 State */ + if(RCC_OscInitStruct->HSI14State == RCC_HSI14_ON) + 8001fe2: 687b ldr r3, [r7, #4] + 8001fe4: 695b ldr r3, [r3, #20] + 8001fe6: 2b01 cmp r3, #1 + 8001fe8: d12a bne.n 8002040 + { + /* Disable ADC control of the Internal High Speed oscillator HSI14 */ + __HAL_RCC_HSI14ADC_DISABLE(); + 8001fea: 4b95 ldr r3, [pc, #596] ; (8002240 ) + 8001fec: 6b5a ldr r2, [r3, #52] ; 0x34 + 8001fee: 4b94 ldr r3, [pc, #592] ; (8002240 ) + 8001ff0: 2104 movs r1, #4 + 8001ff2: 430a orrs r2, r1 + 8001ff4: 635a str r2, [r3, #52] ; 0x34 + + /* Enable the Internal High Speed oscillator (HSI). */ + __HAL_RCC_HSI14_ENABLE(); + 8001ff6: 4b92 ldr r3, [pc, #584] ; (8002240 ) + 8001ff8: 6b5a ldr r2, [r3, #52] ; 0x34 + 8001ffa: 4b91 ldr r3, [pc, #580] ; (8002240 ) + 8001ffc: 2101 movs r1, #1 + 8001ffe: 430a orrs r2, r1 + 8002000: 635a str r2, [r3, #52] ; 0x34 + + /* Get Start Tick */ + tickstart = HAL_GetTick(); + 8002002: f7fe fb5f bl 80006c4 + 8002006: 0003 movs r3, r0 + 8002008: 61bb str r3, [r7, #24] + + /* Wait till HSI is ready */ + while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSI14RDY) == RESET) + 800200a: e008 b.n 800201e + { + if((HAL_GetTick() - tickstart) > HSI14_TIMEOUT_VALUE) + 800200c: f7fe fb5a bl 80006c4 + 8002010: 0002 movs r2, r0 + 8002012: 69bb ldr r3, [r7, #24] + 8002014: 1ad3 subs r3, r2, r3 + 8002016: 2b02 cmp r3, #2 + 8002018: d901 bls.n 800201e + { + return HAL_TIMEOUT; + 800201a: 2303 movs r3, #3 + 800201c: e152 b.n 80022c4 + while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSI14RDY) == RESET) + 800201e: 4b88 ldr r3, [pc, #544] ; (8002240 ) + 8002020: 6b5b ldr r3, [r3, #52] ; 0x34 + 8002022: 2202 movs r2, #2 + 8002024: 4013 ands r3, r2 + 8002026: d0f1 beq.n 800200c + } + } + + /* Adjusts the Internal High Speed oscillator 14Mhz (HSI14) calibration value. */ + __HAL_RCC_HSI14_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->HSI14CalibrationValue); + 8002028: 4b85 ldr r3, [pc, #532] ; (8002240 ) + 800202a: 6b5b ldr r3, [r3, #52] ; 0x34 + 800202c: 22f8 movs r2, #248 ; 0xf8 + 800202e: 4393 bics r3, r2 + 8002030: 0019 movs r1, r3 + 8002032: 687b ldr r3, [r7, #4] + 8002034: 699b ldr r3, [r3, #24] + 8002036: 00da lsls r2, r3, #3 + 8002038: 4b81 ldr r3, [pc, #516] ; (8002240 ) + 800203a: 430a orrs r2, r1 + 800203c: 635a str r2, [r3, #52] ; 0x34 + 800203e: e034 b.n 80020aa + } + else if(RCC_OscInitStruct->HSI14State == RCC_HSI14_ADC_CONTROL) + 8002040: 687b ldr r3, [r7, #4] + 8002042: 695b ldr r3, [r3, #20] + 8002044: 3305 adds r3, #5 + 8002046: d111 bne.n 800206c + { + /* Enable ADC control of the Internal High Speed oscillator HSI14 */ + __HAL_RCC_HSI14ADC_ENABLE(); + 8002048: 4b7d ldr r3, [pc, #500] ; (8002240 ) + 800204a: 6b5a ldr r2, [r3, #52] ; 0x34 + 800204c: 4b7c ldr r3, [pc, #496] ; (8002240 ) + 800204e: 2104 movs r1, #4 + 8002050: 438a bics r2, r1 + 8002052: 635a str r2, [r3, #52] ; 0x34 + + /* Adjusts the Internal High Speed oscillator 14Mhz (HSI14) calibration value. */ + __HAL_RCC_HSI14_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->HSI14CalibrationValue); + 8002054: 4b7a ldr r3, [pc, #488] ; (8002240 ) + 8002056: 6b5b ldr r3, [r3, #52] ; 0x34 + 8002058: 22f8 movs r2, #248 ; 0xf8 + 800205a: 4393 bics r3, r2 + 800205c: 0019 movs r1, r3 + 800205e: 687b ldr r3, [r7, #4] + 8002060: 699b ldr r3, [r3, #24] + 8002062: 00da lsls r2, r3, #3 + 8002064: 4b76 ldr r3, [pc, #472] ; (8002240 ) + 8002066: 430a orrs r2, r1 + 8002068: 635a str r2, [r3, #52] ; 0x34 + 800206a: e01e b.n 80020aa + } + else + { + /* Disable ADC control of the Internal High Speed oscillator HSI14 */ + __HAL_RCC_HSI14ADC_DISABLE(); + 800206c: 4b74 ldr r3, [pc, #464] ; (8002240 ) + 800206e: 6b5a ldr r2, [r3, #52] ; 0x34 + 8002070: 4b73 ldr r3, [pc, #460] ; (8002240 ) + 8002072: 2104 movs r1, #4 + 8002074: 430a orrs r2, r1 + 8002076: 635a str r2, [r3, #52] ; 0x34 + + /* Disable the Internal High Speed oscillator (HSI). */ + __HAL_RCC_HSI14_DISABLE(); + 8002078: 4b71 ldr r3, [pc, #452] ; (8002240 ) + 800207a: 6b5a ldr r2, [r3, #52] ; 0x34 + 800207c: 4b70 ldr r3, [pc, #448] ; (8002240 ) + 800207e: 2101 movs r1, #1 + 8002080: 438a bics r2, r1 + 8002082: 635a str r2, [r3, #52] ; 0x34 + + /* Get Start Tick */ + tickstart = HAL_GetTick(); + 8002084: f7fe fb1e bl 80006c4 + 8002088: 0003 movs r3, r0 + 800208a: 61bb str r3, [r7, #24] + + /* Wait till HSI is ready */ + while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSI14RDY) != RESET) + 800208c: e008 b.n 80020a0 + { + if((HAL_GetTick() - tickstart) > HSI14_TIMEOUT_VALUE) + 800208e: f7fe fb19 bl 80006c4 + 8002092: 0002 movs r2, r0 + 8002094: 69bb ldr r3, [r7, #24] + 8002096: 1ad3 subs r3, r2, r3 + 8002098: 2b02 cmp r3, #2 + 800209a: d901 bls.n 80020a0 + { + return HAL_TIMEOUT; + 800209c: 2303 movs r3, #3 + 800209e: e111 b.n 80022c4 + while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSI14RDY) != RESET) + 80020a0: 4b67 ldr r3, [pc, #412] ; (8002240 ) + 80020a2: 6b5b ldr r3, [r3, #52] ; 0x34 + 80020a4: 2202 movs r2, #2 + 80020a6: 4013 ands r3, r2 + 80020a8: d1f1 bne.n 800208e + } + } + +#if defined(RCC_HSI48_SUPPORT) + /*----------------------------- HSI48 Configuration --------------------------*/ + if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSI48) == RCC_OSCILLATORTYPE_HSI48) + 80020aa: 687b ldr r3, [r7, #4] + 80020ac: 681b ldr r3, [r3, #0] + 80020ae: 2220 movs r2, #32 + 80020b0: 4013 ands r3, r2 + 80020b2: d05c beq.n 800216e + { + /* Check the parameters */ + assert_param(IS_RCC_HSI48(RCC_OscInitStruct->HSI48State)); + + /* When the HSI48 is used as system clock it is not allowed to be disabled */ + if((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_HSI48) || + 80020b4: 4b62 ldr r3, [pc, #392] ; (8002240 ) + 80020b6: 685b ldr r3, [r3, #4] + 80020b8: 220c movs r2, #12 + 80020ba: 4013 ands r3, r2 + 80020bc: 2b0c cmp r3, #12 + 80020be: d00e beq.n 80020de + ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && (__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_HSI48))) + 80020c0: 4b5f ldr r3, [pc, #380] ; (8002240 ) + 80020c2: 685b ldr r3, [r3, #4] + 80020c4: 220c movs r2, #12 + 80020c6: 4013 ands r3, r2 + if((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_HSI48) || + 80020c8: 2b08 cmp r3, #8 + 80020ca: d114 bne.n 80020f6 + ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && (__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_HSI48))) + 80020cc: 4b5c ldr r3, [pc, #368] ; (8002240 ) + 80020ce: 685a ldr r2, [r3, #4] + 80020d0: 23c0 movs r3, #192 ; 0xc0 + 80020d2: 025b lsls r3, r3, #9 + 80020d4: 401a ands r2, r3 + 80020d6: 23c0 movs r3, #192 ; 0xc0 + 80020d8: 025b lsls r3, r3, #9 + 80020da: 429a cmp r2, r3 + 80020dc: d10b bne.n 80020f6 + { + if((__HAL_RCC_GET_FLAG(RCC_FLAG_HSI48RDY) != RESET) && (RCC_OscInitStruct->HSI48State != RCC_HSI48_ON)) + 80020de: 4b58 ldr r3, [pc, #352] ; (8002240 ) + 80020e0: 6b5a ldr r2, [r3, #52] ; 0x34 + 80020e2: 2380 movs r3, #128 ; 0x80 + 80020e4: 025b lsls r3, r3, #9 + 80020e6: 4013 ands r3, r2 + 80020e8: d040 beq.n 800216c + 80020ea: 687b ldr r3, [r7, #4] + 80020ec: 6a1b ldr r3, [r3, #32] + 80020ee: 2b01 cmp r3, #1 + 80020f0: d03c beq.n 800216c + { + return HAL_ERROR; + 80020f2: 2301 movs r3, #1 + 80020f4: e0e6 b.n 80022c4 + } + } + else + { + /* Check the HSI48 State */ + if(RCC_OscInitStruct->HSI48State != RCC_HSI48_OFF) + 80020f6: 687b ldr r3, [r7, #4] + 80020f8: 6a1b ldr r3, [r3, #32] + 80020fa: 2b00 cmp r3, #0 + 80020fc: d01b beq.n 8002136 + { + /* Enable the Internal High Speed oscillator (HSI48). */ + __HAL_RCC_HSI48_ENABLE(); + 80020fe: 4b50 ldr r3, [pc, #320] ; (8002240 ) + 8002100: 6b5a ldr r2, [r3, #52] ; 0x34 + 8002102: 4b4f ldr r3, [pc, #316] ; (8002240 ) + 8002104: 2180 movs r1, #128 ; 0x80 + 8002106: 0249 lsls r1, r1, #9 + 8002108: 430a orrs r2, r1 + 800210a: 635a str r2, [r3, #52] ; 0x34 + + /* Get Start Tick */ + tickstart = HAL_GetTick(); + 800210c: f7fe fada bl 80006c4 + 8002110: 0003 movs r3, r0 + 8002112: 61bb str r3, [r7, #24] + + /* Wait till HSI48 is ready */ + while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSI48RDY) == RESET) + 8002114: e008 b.n 8002128 + { + if((HAL_GetTick() - tickstart) > HSI48_TIMEOUT_VALUE) + 8002116: f7fe fad5 bl 80006c4 + 800211a: 0002 movs r2, r0 + 800211c: 69bb ldr r3, [r7, #24] + 800211e: 1ad3 subs r3, r2, r3 + 8002120: 2b02 cmp r3, #2 + 8002122: d901 bls.n 8002128 + { + return HAL_TIMEOUT; + 8002124: 2303 movs r3, #3 + 8002126: e0cd b.n 80022c4 + while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSI48RDY) == RESET) + 8002128: 4b45 ldr r3, [pc, #276] ; (8002240 ) + 800212a: 6b5a ldr r2, [r3, #52] ; 0x34 + 800212c: 2380 movs r3, #128 ; 0x80 + 800212e: 025b lsls r3, r3, #9 + 8002130: 4013 ands r3, r2 + 8002132: d0f0 beq.n 8002116 + 8002134: e01b b.n 800216e + } + } + else + { + /* Disable the Internal High Speed oscillator (HSI48). */ + __HAL_RCC_HSI48_DISABLE(); + 8002136: 4b42 ldr r3, [pc, #264] ; (8002240 ) + 8002138: 6b5a ldr r2, [r3, #52] ; 0x34 + 800213a: 4b41 ldr r3, [pc, #260] ; (8002240 ) + 800213c: 4943 ldr r1, [pc, #268] ; (800224c ) + 800213e: 400a ands r2, r1 + 8002140: 635a str r2, [r3, #52] ; 0x34 + + /* Get Start Tick */ + tickstart = HAL_GetTick(); + 8002142: f7fe fabf bl 80006c4 + 8002146: 0003 movs r3, r0 + 8002148: 61bb str r3, [r7, #24] + + /* Wait till HSI48 is ready */ + while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSI48RDY) != RESET) + 800214a: e008 b.n 800215e + { + if((HAL_GetTick() - tickstart) > HSI48_TIMEOUT_VALUE) + 800214c: f7fe faba bl 80006c4 + 8002150: 0002 movs r2, r0 + 8002152: 69bb ldr r3, [r7, #24] + 8002154: 1ad3 subs r3, r2, r3 + 8002156: 2b02 cmp r3, #2 + 8002158: d901 bls.n 800215e + { + return HAL_TIMEOUT; + 800215a: 2303 movs r3, #3 + 800215c: e0b2 b.n 80022c4 + while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSI48RDY) != RESET) + 800215e: 4b38 ldr r3, [pc, #224] ; (8002240 ) + 8002160: 6b5a ldr r2, [r3, #52] ; 0x34 + 8002162: 2380 movs r3, #128 ; 0x80 + 8002164: 025b lsls r3, r3, #9 + 8002166: 4013 ands r3, r2 + 8002168: d1f0 bne.n 800214c + 800216a: e000 b.n 800216e + if((__HAL_RCC_GET_FLAG(RCC_FLAG_HSI48RDY) != RESET) && (RCC_OscInitStruct->HSI48State != RCC_HSI48_ON)) + 800216c: 46c0 nop ; (mov r8, r8) +#endif /* RCC_HSI48_SUPPORT */ + + /*-------------------------------- PLL Configuration -----------------------*/ + /* Check the parameters */ + assert_param(IS_RCC_PLL(RCC_OscInitStruct->PLL.PLLState)); + if ((RCC_OscInitStruct->PLL.PLLState) != RCC_PLL_NONE) + 800216e: 687b ldr r3, [r7, #4] + 8002170: 6a5b ldr r3, [r3, #36] ; 0x24 + 8002172: 2b00 cmp r3, #0 + 8002174: d100 bne.n 8002178 + 8002176: e0a4 b.n 80022c2 + { + /* Check if the PLL is used as system clock or not */ + if(__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_SYSCLKSOURCE_STATUS_PLLCLK) + 8002178: 4b31 ldr r3, [pc, #196] ; (8002240 ) + 800217a: 685b ldr r3, [r3, #4] + 800217c: 220c movs r2, #12 + 800217e: 4013 ands r3, r2 + 8002180: 2b08 cmp r3, #8 + 8002182: d100 bne.n 8002186 + 8002184: e078 b.n 8002278 + { + if((RCC_OscInitStruct->PLL.PLLState) == RCC_PLL_ON) + 8002186: 687b ldr r3, [r7, #4] + 8002188: 6a5b ldr r3, [r3, #36] ; 0x24 + 800218a: 2b02 cmp r3, #2 + 800218c: d14c bne.n 8002228 + assert_param(IS_RCC_PLLSOURCE(RCC_OscInitStruct->PLL.PLLSource)); + assert_param(IS_RCC_PLL_MUL(RCC_OscInitStruct->PLL.PLLMUL)); + assert_param(IS_RCC_PREDIV(RCC_OscInitStruct->PLL.PREDIV)); + + /* Disable the main PLL. */ + __HAL_RCC_PLL_DISABLE(); + 800218e: 4b2c ldr r3, [pc, #176] ; (8002240 ) + 8002190: 681a ldr r2, [r3, #0] + 8002192: 4b2b ldr r3, [pc, #172] ; (8002240 ) + 8002194: 492e ldr r1, [pc, #184] ; (8002250 ) + 8002196: 400a ands r2, r1 + 8002198: 601a str r2, [r3, #0] + + /* Get Start Tick */ + tickstart = HAL_GetTick(); + 800219a: f7fe fa93 bl 80006c4 + 800219e: 0003 movs r3, r0 + 80021a0: 61bb str r3, [r7, #24] + + /* Wait till PLL is disabled */ + while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) != RESET) + 80021a2: e008 b.n 80021b6 + { + if((HAL_GetTick() - tickstart ) > PLL_TIMEOUT_VALUE) + 80021a4: f7fe fa8e bl 80006c4 + 80021a8: 0002 movs r2, r0 + 80021aa: 69bb ldr r3, [r7, #24] + 80021ac: 1ad3 subs r3, r2, r3 + 80021ae: 2b02 cmp r3, #2 + 80021b0: d901 bls.n 80021b6 + { + return HAL_TIMEOUT; + 80021b2: 2303 movs r3, #3 + 80021b4: e086 b.n 80022c4 + while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) != RESET) + 80021b6: 4b22 ldr r3, [pc, #136] ; (8002240 ) + 80021b8: 681a ldr r2, [r3, #0] + 80021ba: 2380 movs r3, #128 ; 0x80 + 80021bc: 049b lsls r3, r3, #18 + 80021be: 4013 ands r3, r2 + 80021c0: d1f0 bne.n 80021a4 + } + } + + /* Configure the main PLL clock source, predivider and multiplication factor. */ + __HAL_RCC_PLL_CONFIG(RCC_OscInitStruct->PLL.PLLSource, + 80021c2: 4b1f ldr r3, [pc, #124] ; (8002240 ) + 80021c4: 6adb ldr r3, [r3, #44] ; 0x2c + 80021c6: 220f movs r2, #15 + 80021c8: 4393 bics r3, r2 + 80021ca: 0019 movs r1, r3 + 80021cc: 687b ldr r3, [r7, #4] + 80021ce: 6b1a ldr r2, [r3, #48] ; 0x30 + 80021d0: 4b1b ldr r3, [pc, #108] ; (8002240 ) + 80021d2: 430a orrs r2, r1 + 80021d4: 62da str r2, [r3, #44] ; 0x2c + 80021d6: 4b1a ldr r3, [pc, #104] ; (8002240 ) + 80021d8: 685b ldr r3, [r3, #4] + 80021da: 4a1e ldr r2, [pc, #120] ; (8002254 ) + 80021dc: 4013 ands r3, r2 + 80021de: 0019 movs r1, r3 + 80021e0: 687b ldr r3, [r7, #4] + 80021e2: 6ada ldr r2, [r3, #44] ; 0x2c + 80021e4: 687b ldr r3, [r7, #4] + 80021e6: 6a9b ldr r3, [r3, #40] ; 0x28 + 80021e8: 431a orrs r2, r3 + 80021ea: 4b15 ldr r3, [pc, #84] ; (8002240 ) + 80021ec: 430a orrs r2, r1 + 80021ee: 605a str r2, [r3, #4] + RCC_OscInitStruct->PLL.PREDIV, + RCC_OscInitStruct->PLL.PLLMUL); + /* Enable the main PLL. */ + __HAL_RCC_PLL_ENABLE(); + 80021f0: 4b13 ldr r3, [pc, #76] ; (8002240 ) + 80021f2: 681a ldr r2, [r3, #0] + 80021f4: 4b12 ldr r3, [pc, #72] ; (8002240 ) + 80021f6: 2180 movs r1, #128 ; 0x80 + 80021f8: 0449 lsls r1, r1, #17 + 80021fa: 430a orrs r2, r1 + 80021fc: 601a str r2, [r3, #0] + + /* Get Start Tick */ + tickstart = HAL_GetTick(); + 80021fe: f7fe fa61 bl 80006c4 + 8002202: 0003 movs r3, r0 + 8002204: 61bb str r3, [r7, #24] + + /* Wait till PLL is ready */ + while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) == RESET) + 8002206: e008 b.n 800221a + { + if((HAL_GetTick() - tickstart ) > PLL_TIMEOUT_VALUE) + 8002208: f7fe fa5c bl 80006c4 + 800220c: 0002 movs r2, r0 + 800220e: 69bb ldr r3, [r7, #24] + 8002210: 1ad3 subs r3, r2, r3 + 8002212: 2b02 cmp r3, #2 + 8002214: d901 bls.n 800221a + { + return HAL_TIMEOUT; + 8002216: 2303 movs r3, #3 + 8002218: e054 b.n 80022c4 + while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) == RESET) + 800221a: 4b09 ldr r3, [pc, #36] ; (8002240 ) + 800221c: 681a ldr r2, [r3, #0] + 800221e: 2380 movs r3, #128 ; 0x80 + 8002220: 049b lsls r3, r3, #18 + 8002222: 4013 ands r3, r2 + 8002224: d0f0 beq.n 8002208 + 8002226: e04c b.n 80022c2 + } + } + else + { + /* Disable the main PLL. */ + __HAL_RCC_PLL_DISABLE(); + 8002228: 4b05 ldr r3, [pc, #20] ; (8002240 ) + 800222a: 681a ldr r2, [r3, #0] + 800222c: 4b04 ldr r3, [pc, #16] ; (8002240 ) + 800222e: 4908 ldr r1, [pc, #32] ; (8002250 ) + 8002230: 400a ands r2, r1 + 8002232: 601a str r2, [r3, #0] + + /* Get Start Tick */ + tickstart = HAL_GetTick(); + 8002234: f7fe fa46 bl 80006c4 + 8002238: 0003 movs r3, r0 + 800223a: 61bb str r3, [r7, #24] + + /* Wait till PLL is disabled */ + while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) != RESET) + 800223c: e015 b.n 800226a + 800223e: 46c0 nop ; (mov r8, r8) + 8002240: 40021000 .word 0x40021000 + 8002244: 00001388 .word 0x00001388 + 8002248: efffffff .word 0xefffffff + 800224c: fffeffff .word 0xfffeffff + 8002250: feffffff .word 0xfeffffff + 8002254: ffc27fff .word 0xffc27fff + { + if((HAL_GetTick() - tickstart ) > PLL_TIMEOUT_VALUE) + 8002258: f7fe fa34 bl 80006c4 + 800225c: 0002 movs r2, r0 + 800225e: 69bb ldr r3, [r7, #24] + 8002260: 1ad3 subs r3, r2, r3 + 8002262: 2b02 cmp r3, #2 + 8002264: d901 bls.n 800226a + { + return HAL_TIMEOUT; + 8002266: 2303 movs r3, #3 + 8002268: e02c b.n 80022c4 + while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) != RESET) + 800226a: 4b18 ldr r3, [pc, #96] ; (80022cc ) + 800226c: 681a ldr r2, [r3, #0] + 800226e: 2380 movs r3, #128 ; 0x80 + 8002270: 049b lsls r3, r3, #18 + 8002272: 4013 ands r3, r2 + 8002274: d1f0 bne.n 8002258 + 8002276: e024 b.n 80022c2 + } + } + else + { + /* Check if there is a request to disable the PLL used as System clock source */ + if((RCC_OscInitStruct->PLL.PLLState) == RCC_PLL_OFF) + 8002278: 687b ldr r3, [r7, #4] + 800227a: 6a5b ldr r3, [r3, #36] ; 0x24 + 800227c: 2b01 cmp r3, #1 + 800227e: d101 bne.n 8002284 + { + return HAL_ERROR; + 8002280: 2301 movs r3, #1 + 8002282: e01f b.n 80022c4 + } + else + { + /* Do not return HAL_ERROR if request repeats the current configuration */ + pll_config = RCC->CFGR; + 8002284: 4b11 ldr r3, [pc, #68] ; (80022cc ) + 8002286: 685b ldr r3, [r3, #4] + 8002288: 617b str r3, [r7, #20] + pll_config2 = RCC->CFGR2; + 800228a: 4b10 ldr r3, [pc, #64] ; (80022cc ) + 800228c: 6adb ldr r3, [r3, #44] ; 0x2c + 800228e: 613b str r3, [r7, #16] + if((READ_BIT(pll_config, RCC_CFGR_PLLSRC) != RCC_OscInitStruct->PLL.PLLSource) || + 8002290: 697a ldr r2, [r7, #20] + 8002292: 23c0 movs r3, #192 ; 0xc0 + 8002294: 025b lsls r3, r3, #9 + 8002296: 401a ands r2, r3 + 8002298: 687b ldr r3, [r7, #4] + 800229a: 6a9b ldr r3, [r3, #40] ; 0x28 + 800229c: 429a cmp r2, r3 + 800229e: d10e bne.n 80022be + (READ_BIT(pll_config2, RCC_CFGR2_PREDIV) != RCC_OscInitStruct->PLL.PREDIV) || + 80022a0: 693b ldr r3, [r7, #16] + 80022a2: 220f movs r2, #15 + 80022a4: 401a ands r2, r3 + 80022a6: 687b ldr r3, [r7, #4] + 80022a8: 6b1b ldr r3, [r3, #48] ; 0x30 + if((READ_BIT(pll_config, RCC_CFGR_PLLSRC) != RCC_OscInitStruct->PLL.PLLSource) || + 80022aa: 429a cmp r2, r3 + 80022ac: d107 bne.n 80022be + (READ_BIT(pll_config, RCC_CFGR_PLLMUL) != RCC_OscInitStruct->PLL.PLLMUL)) + 80022ae: 697a ldr r2, [r7, #20] + 80022b0: 23f0 movs r3, #240 ; 0xf0 + 80022b2: 039b lsls r3, r3, #14 + 80022b4: 401a ands r2, r3 + 80022b6: 687b ldr r3, [r7, #4] + 80022b8: 6adb ldr r3, [r3, #44] ; 0x2c + (READ_BIT(pll_config2, RCC_CFGR2_PREDIV) != RCC_OscInitStruct->PLL.PREDIV) || + 80022ba: 429a cmp r2, r3 + 80022bc: d001 beq.n 80022c2 + { + return HAL_ERROR; + 80022be: 2301 movs r3, #1 + 80022c0: e000 b.n 80022c4 + } + } + } + } + + return HAL_OK; + 80022c2: 2300 movs r3, #0 +} + 80022c4: 0018 movs r0, r3 + 80022c6: 46bd mov sp, r7 + 80022c8: b008 add sp, #32 + 80022ca: bd80 pop {r7, pc} + 80022cc: 40021000 .word 0x40021000 + +080022d0 : + * You can use @ref HAL_RCC_GetClockConfig() function to know which clock is + * currently used as system clock source. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RCC_ClockConfig(RCC_ClkInitTypeDef *RCC_ClkInitStruct, uint32_t FLatency) +{ + 80022d0: b580 push {r7, lr} + 80022d2: b084 sub sp, #16 + 80022d4: af00 add r7, sp, #0 + 80022d6: 6078 str r0, [r7, #4] + 80022d8: 6039 str r1, [r7, #0] + uint32_t tickstart; + + /* Check Null pointer */ + if(RCC_ClkInitStruct == NULL) + 80022da: 687b ldr r3, [r7, #4] + 80022dc: 2b00 cmp r3, #0 + 80022de: d101 bne.n 80022e4 + { + return HAL_ERROR; + 80022e0: 2301 movs r3, #1 + 80022e2: e0bf b.n 8002464 + /* To correctly read data from FLASH memory, the number of wait states (LATENCY) + must be correctly programmed according to the frequency of the CPU clock + (HCLK) of the device. */ + + /* Increasing the number of wait states because of higher CPU frequency */ + if(FLatency > __HAL_FLASH_GET_LATENCY()) + 80022e4: 4b61 ldr r3, [pc, #388] ; (800246c ) + 80022e6: 681b ldr r3, [r3, #0] + 80022e8: 2201 movs r2, #1 + 80022ea: 4013 ands r3, r2 + 80022ec: 683a ldr r2, [r7, #0] + 80022ee: 429a cmp r2, r3 + 80022f0: d911 bls.n 8002316 + { + /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */ + __HAL_FLASH_SET_LATENCY(FLatency); + 80022f2: 4b5e ldr r3, [pc, #376] ; (800246c ) + 80022f4: 681b ldr r3, [r3, #0] + 80022f6: 2201 movs r2, #1 + 80022f8: 4393 bics r3, r2 + 80022fa: 0019 movs r1, r3 + 80022fc: 4b5b ldr r3, [pc, #364] ; (800246c ) + 80022fe: 683a ldr r2, [r7, #0] + 8002300: 430a orrs r2, r1 + 8002302: 601a str r2, [r3, #0] + + /* Check that the new number of wait states is taken into account to access the Flash + memory by reading the FLASH_ACR register */ + if(__HAL_FLASH_GET_LATENCY() != FLatency) + 8002304: 4b59 ldr r3, [pc, #356] ; (800246c ) + 8002306: 681b ldr r3, [r3, #0] + 8002308: 2201 movs r2, #1 + 800230a: 4013 ands r3, r2 + 800230c: 683a ldr r2, [r7, #0] + 800230e: 429a cmp r2, r3 + 8002310: d001 beq.n 8002316 + { + return HAL_ERROR; + 8002312: 2301 movs r3, #1 + 8002314: e0a6 b.n 8002464 + } + } + + /*-------------------------- HCLK Configuration --------------------------*/ + if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_HCLK) == RCC_CLOCKTYPE_HCLK) + 8002316: 687b ldr r3, [r7, #4] + 8002318: 681b ldr r3, [r3, #0] + 800231a: 2202 movs r2, #2 + 800231c: 4013 ands r3, r2 + 800231e: d015 beq.n 800234c + { + /* Set the highest APB divider in order to ensure that we do not go through + a non-spec phase whatever we decrease or increase HCLK. */ + if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK1) == RCC_CLOCKTYPE_PCLK1) + 8002320: 687b ldr r3, [r7, #4] + 8002322: 681b ldr r3, [r3, #0] + 8002324: 2204 movs r2, #4 + 8002326: 4013 ands r3, r2 + 8002328: d006 beq.n 8002338 + { + MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE, RCC_HCLK_DIV16); + 800232a: 4b51 ldr r3, [pc, #324] ; (8002470 ) + 800232c: 685a ldr r2, [r3, #4] + 800232e: 4b50 ldr r3, [pc, #320] ; (8002470 ) + 8002330: 21e0 movs r1, #224 ; 0xe0 + 8002332: 00c9 lsls r1, r1, #3 + 8002334: 430a orrs r2, r1 + 8002336: 605a str r2, [r3, #4] + } + + /* Set the new HCLK clock divider */ + assert_param(IS_RCC_HCLK(RCC_ClkInitStruct->AHBCLKDivider)); + MODIFY_REG(RCC->CFGR, RCC_CFGR_HPRE, RCC_ClkInitStruct->AHBCLKDivider); + 8002338: 4b4d ldr r3, [pc, #308] ; (8002470 ) + 800233a: 685b ldr r3, [r3, #4] + 800233c: 22f0 movs r2, #240 ; 0xf0 + 800233e: 4393 bics r3, r2 + 8002340: 0019 movs r1, r3 + 8002342: 687b ldr r3, [r7, #4] + 8002344: 689a ldr r2, [r3, #8] + 8002346: 4b4a ldr r3, [pc, #296] ; (8002470 ) + 8002348: 430a orrs r2, r1 + 800234a: 605a str r2, [r3, #4] + } + + /*------------------------- SYSCLK Configuration ---------------------------*/ + if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_SYSCLK) == RCC_CLOCKTYPE_SYSCLK) + 800234c: 687b ldr r3, [r7, #4] + 800234e: 681b ldr r3, [r3, #0] + 8002350: 2201 movs r2, #1 + 8002352: 4013 ands r3, r2 + 8002354: d04c beq.n 80023f0 + { + assert_param(IS_RCC_SYSCLKSOURCE(RCC_ClkInitStruct->SYSCLKSource)); + + /* HSE is selected as System Clock Source */ + if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_HSE) + 8002356: 687b ldr r3, [r7, #4] + 8002358: 685b ldr r3, [r3, #4] + 800235a: 2b01 cmp r3, #1 + 800235c: d107 bne.n 800236e + { + /* Check the HSE ready flag */ + if(__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) == RESET) + 800235e: 4b44 ldr r3, [pc, #272] ; (8002470 ) + 8002360: 681a ldr r2, [r3, #0] + 8002362: 2380 movs r3, #128 ; 0x80 + 8002364: 029b lsls r3, r3, #10 + 8002366: 4013 ands r3, r2 + 8002368: d120 bne.n 80023ac + { + return HAL_ERROR; + 800236a: 2301 movs r3, #1 + 800236c: e07a b.n 8002464 + } + } + /* PLL is selected as System Clock Source */ + else if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_PLLCLK) + 800236e: 687b ldr r3, [r7, #4] + 8002370: 685b ldr r3, [r3, #4] + 8002372: 2b02 cmp r3, #2 + 8002374: d107 bne.n 8002386 + { + /* Check the PLL ready flag */ + if(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) == RESET) + 8002376: 4b3e ldr r3, [pc, #248] ; (8002470 ) + 8002378: 681a ldr r2, [r3, #0] + 800237a: 2380 movs r3, #128 ; 0x80 + 800237c: 049b lsls r3, r3, #18 + 800237e: 4013 ands r3, r2 + 8002380: d114 bne.n 80023ac + { + return HAL_ERROR; + 8002382: 2301 movs r3, #1 + 8002384: e06e b.n 8002464 + } + } +#if defined(RCC_CFGR_SWS_HSI48) + /* HSI48 is selected as System Clock Source */ + else if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_HSI48) + 8002386: 687b ldr r3, [r7, #4] + 8002388: 685b ldr r3, [r3, #4] + 800238a: 2b03 cmp r3, #3 + 800238c: d107 bne.n 800239e + { + /* Check the HSI48 ready flag */ + if(__HAL_RCC_GET_FLAG(RCC_FLAG_HSI48RDY) == RESET) + 800238e: 4b38 ldr r3, [pc, #224] ; (8002470 ) + 8002390: 6b5a ldr r2, [r3, #52] ; 0x34 + 8002392: 2380 movs r3, #128 ; 0x80 + 8002394: 025b lsls r3, r3, #9 + 8002396: 4013 ands r3, r2 + 8002398: d108 bne.n 80023ac + { + return HAL_ERROR; + 800239a: 2301 movs r3, #1 + 800239c: e062 b.n 8002464 +#endif /* RCC_CFGR_SWS_HSI48 */ + /* HSI is selected as System Clock Source */ + else + { + /* Check the HSI ready flag */ + if(__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) == RESET) + 800239e: 4b34 ldr r3, [pc, #208] ; (8002470 ) + 80023a0: 681b ldr r3, [r3, #0] + 80023a2: 2202 movs r2, #2 + 80023a4: 4013 ands r3, r2 + 80023a6: d101 bne.n 80023ac + { + return HAL_ERROR; + 80023a8: 2301 movs r3, #1 + 80023aa: e05b b.n 8002464 + } + } + __HAL_RCC_SYSCLK_CONFIG(RCC_ClkInitStruct->SYSCLKSource); + 80023ac: 4b30 ldr r3, [pc, #192] ; (8002470 ) + 80023ae: 685b ldr r3, [r3, #4] + 80023b0: 2203 movs r2, #3 + 80023b2: 4393 bics r3, r2 + 80023b4: 0019 movs r1, r3 + 80023b6: 687b ldr r3, [r7, #4] + 80023b8: 685a ldr r2, [r3, #4] + 80023ba: 4b2d ldr r3, [pc, #180] ; (8002470 ) + 80023bc: 430a orrs r2, r1 + 80023be: 605a str r2, [r3, #4] + + /* Get Start Tick */ + tickstart = HAL_GetTick(); + 80023c0: f7fe f980 bl 80006c4 + 80023c4: 0003 movs r3, r0 + 80023c6: 60fb str r3, [r7, #12] + + while (__HAL_RCC_GET_SYSCLK_SOURCE() != (RCC_ClkInitStruct->SYSCLKSource << RCC_CFGR_SWS_Pos)) + 80023c8: e009 b.n 80023de + { + if((HAL_GetTick() - tickstart ) > CLOCKSWITCH_TIMEOUT_VALUE) + 80023ca: f7fe f97b bl 80006c4 + 80023ce: 0002 movs r2, r0 + 80023d0: 68fb ldr r3, [r7, #12] + 80023d2: 1ad3 subs r3, r2, r3 + 80023d4: 4a27 ldr r2, [pc, #156] ; (8002474 ) + 80023d6: 4293 cmp r3, r2 + 80023d8: d901 bls.n 80023de + { + return HAL_TIMEOUT; + 80023da: 2303 movs r3, #3 + 80023dc: e042 b.n 8002464 + while (__HAL_RCC_GET_SYSCLK_SOURCE() != (RCC_ClkInitStruct->SYSCLKSource << RCC_CFGR_SWS_Pos)) + 80023de: 4b24 ldr r3, [pc, #144] ; (8002470 ) + 80023e0: 685b ldr r3, [r3, #4] + 80023e2: 220c movs r2, #12 + 80023e4: 401a ands r2, r3 + 80023e6: 687b ldr r3, [r7, #4] + 80023e8: 685b ldr r3, [r3, #4] + 80023ea: 009b lsls r3, r3, #2 + 80023ec: 429a cmp r2, r3 + 80023ee: d1ec bne.n 80023ca + } + } + } + + /* Decreasing the number of wait states because of lower CPU frequency */ + if(FLatency < __HAL_FLASH_GET_LATENCY()) + 80023f0: 4b1e ldr r3, [pc, #120] ; (800246c ) + 80023f2: 681b ldr r3, [r3, #0] + 80023f4: 2201 movs r2, #1 + 80023f6: 4013 ands r3, r2 + 80023f8: 683a ldr r2, [r7, #0] + 80023fa: 429a cmp r2, r3 + 80023fc: d211 bcs.n 8002422 + { + /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */ + __HAL_FLASH_SET_LATENCY(FLatency); + 80023fe: 4b1b ldr r3, [pc, #108] ; (800246c ) + 8002400: 681b ldr r3, [r3, #0] + 8002402: 2201 movs r2, #1 + 8002404: 4393 bics r3, r2 + 8002406: 0019 movs r1, r3 + 8002408: 4b18 ldr r3, [pc, #96] ; (800246c ) + 800240a: 683a ldr r2, [r7, #0] + 800240c: 430a orrs r2, r1 + 800240e: 601a str r2, [r3, #0] + + /* Check that the new number of wait states is taken into account to access the Flash + memory by reading the FLASH_ACR register */ + if(__HAL_FLASH_GET_LATENCY() != FLatency) + 8002410: 4b16 ldr r3, [pc, #88] ; (800246c ) + 8002412: 681b ldr r3, [r3, #0] + 8002414: 2201 movs r2, #1 + 8002416: 4013 ands r3, r2 + 8002418: 683a ldr r2, [r7, #0] + 800241a: 429a cmp r2, r3 + 800241c: d001 beq.n 8002422 + { + return HAL_ERROR; + 800241e: 2301 movs r3, #1 + 8002420: e020 b.n 8002464 + } + } + + /*-------------------------- PCLK1 Configuration ---------------------------*/ + if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK1) == RCC_CLOCKTYPE_PCLK1) + 8002422: 687b ldr r3, [r7, #4] + 8002424: 681b ldr r3, [r3, #0] + 8002426: 2204 movs r2, #4 + 8002428: 4013 ands r3, r2 + 800242a: d009 beq.n 8002440 + { + assert_param(IS_RCC_PCLK(RCC_ClkInitStruct->APB1CLKDivider)); + MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE, RCC_ClkInitStruct->APB1CLKDivider); + 800242c: 4b10 ldr r3, [pc, #64] ; (8002470 ) + 800242e: 685b ldr r3, [r3, #4] + 8002430: 4a11 ldr r2, [pc, #68] ; (8002478 ) + 8002432: 4013 ands r3, r2 + 8002434: 0019 movs r1, r3 + 8002436: 687b ldr r3, [r7, #4] + 8002438: 68da ldr r2, [r3, #12] + 800243a: 4b0d ldr r3, [pc, #52] ; (8002470 ) + 800243c: 430a orrs r2, r1 + 800243e: 605a str r2, [r3, #4] + } + + /* Update the SystemCoreClock global variable */ + SystemCoreClock = HAL_RCC_GetSysClockFreq() >> AHBPrescTable[(RCC->CFGR & RCC_CFGR_HPRE)>> RCC_CFGR_HPRE_BITNUMBER]; + 8002440: f000 f820 bl 8002484 + 8002444: 0001 movs r1, r0 + 8002446: 4b0a ldr r3, [pc, #40] ; (8002470 ) + 8002448: 685b ldr r3, [r3, #4] + 800244a: 091b lsrs r3, r3, #4 + 800244c: 220f movs r2, #15 + 800244e: 4013 ands r3, r2 + 8002450: 4a0a ldr r2, [pc, #40] ; (800247c ) + 8002452: 5cd3 ldrb r3, [r2, r3] + 8002454: 000a movs r2, r1 + 8002456: 40da lsrs r2, r3 + 8002458: 4b09 ldr r3, [pc, #36] ; (8002480 ) + 800245a: 601a str r2, [r3, #0] + + /* Configure the source of time base considering new system clocks settings*/ + HAL_InitTick (TICK_INT_PRIORITY); + 800245c: 2000 movs r0, #0 + 800245e: f7fe f8eb bl 8000638 + + return HAL_OK; + 8002462: 2300 movs r3, #0 +} + 8002464: 0018 movs r0, r3 + 8002466: 46bd mov sp, r7 + 8002468: b004 add sp, #16 + 800246a: bd80 pop {r7, pc} + 800246c: 40022000 .word 0x40022000 + 8002470: 40021000 .word 0x40021000 + 8002474: 00001388 .word 0x00001388 + 8002478: fffff8ff .word 0xfffff8ff + 800247c: 0800fd28 .word 0x0800fd28 + 8002480: 20000000 .word 0x20000000 + +08002484 : + * right SYSCLK value. Otherwise, any configuration based on this function will be incorrect. + * + * @retval SYSCLK frequency + */ +uint32_t HAL_RCC_GetSysClockFreq(void) +{ + 8002484: b590 push {r4, r7, lr} + 8002486: b08f sub sp, #60 ; 0x3c + 8002488: af00 add r7, sp, #0 + const uint8_t aPLLMULFactorTable[16] = { 2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, + 800248a: 2314 movs r3, #20 + 800248c: 18fb adds r3, r7, r3 + 800248e: 4a37 ldr r2, [pc, #220] ; (800256c ) + 8002490: ca13 ldmia r2!, {r0, r1, r4} + 8002492: c313 stmia r3!, {r0, r1, r4} + 8002494: 6812 ldr r2, [r2, #0] + 8002496: 601a str r2, [r3, #0] + 10U, 11U, 12U, 13U, 14U, 15U, 16U, 16U}; + const uint8_t aPredivFactorTable[16] = { 1U, 2U, 3U, 4U, 5U, 6U, 7U, 8U, + 8002498: 1d3b adds r3, r7, #4 + 800249a: 4a35 ldr r2, [pc, #212] ; (8002570 ) + 800249c: ca13 ldmia r2!, {r0, r1, r4} + 800249e: c313 stmia r3!, {r0, r1, r4} + 80024a0: 6812 ldr r2, [r2, #0] + 80024a2: 601a str r2, [r3, #0] + 9U,10U, 11U, 12U, 13U, 14U, 15U, 16U}; + + uint32_t tmpreg = 0U, prediv = 0U, pllclk = 0U, pllmul = 0U; + 80024a4: 2300 movs r3, #0 + 80024a6: 62fb str r3, [r7, #44] ; 0x2c + 80024a8: 2300 movs r3, #0 + 80024aa: 62bb str r3, [r7, #40] ; 0x28 + 80024ac: 2300 movs r3, #0 + 80024ae: 637b str r3, [r7, #52] ; 0x34 + 80024b0: 2300 movs r3, #0 + 80024b2: 627b str r3, [r7, #36] ; 0x24 + uint32_t sysclockfreq = 0U; + 80024b4: 2300 movs r3, #0 + 80024b6: 633b str r3, [r7, #48] ; 0x30 + + tmpreg = RCC->CFGR; + 80024b8: 4b2e ldr r3, [pc, #184] ; (8002574 ) + 80024ba: 685b ldr r3, [r3, #4] + 80024bc: 62fb str r3, [r7, #44] ; 0x2c + + /* Get SYSCLK source -------------------------------------------------------*/ + switch (tmpreg & RCC_CFGR_SWS) + 80024be: 6afb ldr r3, [r7, #44] ; 0x2c + 80024c0: 220c movs r2, #12 + 80024c2: 4013 ands r3, r2 + 80024c4: 2b08 cmp r3, #8 + 80024c6: d006 beq.n 80024d6 + 80024c8: 2b0c cmp r3, #12 + 80024ca: d043 beq.n 8002554 + 80024cc: 2b04 cmp r3, #4 + 80024ce: d144 bne.n 800255a + { + case RCC_SYSCLKSOURCE_STATUS_HSE: /* HSE used as system clock */ + { + sysclockfreq = HSE_VALUE; + 80024d0: 4b29 ldr r3, [pc, #164] ; (8002578 ) + 80024d2: 633b str r3, [r7, #48] ; 0x30 + break; + 80024d4: e044 b.n 8002560 + } + case RCC_SYSCLKSOURCE_STATUS_PLLCLK: /* PLL used as system clock */ + { + pllmul = aPLLMULFactorTable[(uint32_t)(tmpreg & RCC_CFGR_PLLMUL) >> RCC_CFGR_PLLMUL_BITNUMBER]; + 80024d6: 6afb ldr r3, [r7, #44] ; 0x2c + 80024d8: 0c9b lsrs r3, r3, #18 + 80024da: 220f movs r2, #15 + 80024dc: 4013 ands r3, r2 + 80024de: 2214 movs r2, #20 + 80024e0: 18ba adds r2, r7, r2 + 80024e2: 5cd3 ldrb r3, [r2, r3] + 80024e4: 627b str r3, [r7, #36] ; 0x24 + prediv = aPredivFactorTable[(uint32_t)(RCC->CFGR2 & RCC_CFGR2_PREDIV) >> RCC_CFGR2_PREDIV_BITNUMBER]; + 80024e6: 4b23 ldr r3, [pc, #140] ; (8002574 ) + 80024e8: 6adb ldr r3, [r3, #44] ; 0x2c + 80024ea: 220f movs r2, #15 + 80024ec: 4013 ands r3, r2 + 80024ee: 1d3a adds r2, r7, #4 + 80024f0: 5cd3 ldrb r3, [r2, r3] + 80024f2: 62bb str r3, [r7, #40] ; 0x28 + if ((tmpreg & RCC_CFGR_PLLSRC) == RCC_PLLSOURCE_HSE) + 80024f4: 6afa ldr r2, [r7, #44] ; 0x2c + 80024f6: 23c0 movs r3, #192 ; 0xc0 + 80024f8: 025b lsls r3, r3, #9 + 80024fa: 401a ands r2, r3 + 80024fc: 2380 movs r3, #128 ; 0x80 + 80024fe: 025b lsls r3, r3, #9 + 8002500: 429a cmp r2, r3 + 8002502: d109 bne.n 8002518 + { + /* HSE used as PLL clock source : PLLCLK = HSE/PREDIV * PLLMUL */ + pllclk = (uint32_t)((uint64_t) HSE_VALUE / (uint64_t) (prediv)) * ((uint64_t) pllmul); + 8002504: 6ab9 ldr r1, [r7, #40] ; 0x28 + 8002506: 481c ldr r0, [pc, #112] ; (8002578 ) + 8002508: f7fd fe10 bl 800012c <__udivsi3> + 800250c: 0003 movs r3, r0 + 800250e: 001a movs r2, r3 + 8002510: 6a7b ldr r3, [r7, #36] ; 0x24 + 8002512: 4353 muls r3, r2 + 8002514: 637b str r3, [r7, #52] ; 0x34 + 8002516: e01a b.n 800254e + } +#if defined(RCC_CFGR_PLLSRC_HSI48_PREDIV) + else if ((tmpreg & RCC_CFGR_PLLSRC) == RCC_PLLSOURCE_HSI48) + 8002518: 6afa ldr r2, [r7, #44] ; 0x2c + 800251a: 23c0 movs r3, #192 ; 0xc0 + 800251c: 025b lsls r3, r3, #9 + 800251e: 401a ands r2, r3 + 8002520: 23c0 movs r3, #192 ; 0xc0 + 8002522: 025b lsls r3, r3, #9 + 8002524: 429a cmp r2, r3 + 8002526: d109 bne.n 800253c + { + /* HSI48 used as PLL clock source : PLLCLK = HSI48/PREDIV * PLLMUL */ + pllclk = (uint32_t)((uint64_t) HSI48_VALUE / (uint64_t) (prediv)) * ((uint64_t) pllmul); + 8002528: 6ab9 ldr r1, [r7, #40] ; 0x28 + 800252a: 4814 ldr r0, [pc, #80] ; (800257c ) + 800252c: f7fd fdfe bl 800012c <__udivsi3> + 8002530: 0003 movs r3, r0 + 8002532: 001a movs r2, r3 + 8002534: 6a7b ldr r3, [r7, #36] ; 0x24 + 8002536: 4353 muls r3, r2 + 8002538: 637b str r3, [r7, #52] ; 0x34 + 800253a: e008 b.n 800254e +#endif /* RCC_CFGR_PLLSRC_HSI48_PREDIV */ + else + { +#if (defined(STM32F042x6) || defined(STM32F048xx) || defined(STM32F070x6) || defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F078xx) || defined(STM32F070xB) || defined(STM32F091xC) || defined(STM32F098xx) || defined(STM32F030xC)) + /* HSI used as PLL clock source : PLLCLK = HSI/PREDIV * PLLMUL */ + pllclk = (uint32_t)((uint64_t) HSI_VALUE / (uint64_t) (prediv)) * ((uint64_t) pllmul); + 800253c: 6ab9 ldr r1, [r7, #40] ; 0x28 + 800253e: 480e ldr r0, [pc, #56] ; (8002578 ) + 8002540: f7fd fdf4 bl 800012c <__udivsi3> + 8002544: 0003 movs r3, r0 + 8002546: 001a movs r2, r3 + 8002548: 6a7b ldr r3, [r7, #36] ; 0x24 + 800254a: 4353 muls r3, r2 + 800254c: 637b str r3, [r7, #52] ; 0x34 +#else + /* HSI used as PLL clock source : PLLCLK = HSI/2 * PLLMUL */ + pllclk = (uint32_t)((uint64_t) (HSI_VALUE >> 1U) * ((uint64_t) pllmul)); +#endif + } + sysclockfreq = pllclk; + 800254e: 6b7b ldr r3, [r7, #52] ; 0x34 + 8002550: 633b str r3, [r7, #48] ; 0x30 + break; + 8002552: e005 b.n 8002560 + } +#if defined(RCC_CFGR_SWS_HSI48) + case RCC_SYSCLKSOURCE_STATUS_HSI48: /* HSI48 used as system clock source */ + { + sysclockfreq = HSI48_VALUE; + 8002554: 4b09 ldr r3, [pc, #36] ; (800257c ) + 8002556: 633b str r3, [r7, #48] ; 0x30 + break; + 8002558: e002 b.n 8002560 + } +#endif /* RCC_CFGR_SWS_HSI48 */ + case RCC_SYSCLKSOURCE_STATUS_HSI: /* HSI used as system clock source */ + default: /* HSI used as system clock */ + { + sysclockfreq = HSI_VALUE; + 800255a: 4b07 ldr r3, [pc, #28] ; (8002578 ) + 800255c: 633b str r3, [r7, #48] ; 0x30 + break; + 800255e: 46c0 nop ; (mov r8, r8) + } + } + return sysclockfreq; + 8002560: 6b3b ldr r3, [r7, #48] ; 0x30 +} + 8002562: 0018 movs r0, r3 + 8002564: 46bd mov sp, r7 + 8002566: b00f add sp, #60 ; 0x3c + 8002568: bd90 pop {r4, r7, pc} + 800256a: 46c0 nop ; (mov r8, r8) + 800256c: 0800fcdc .word 0x0800fcdc + 8002570: 0800fcec .word 0x0800fcec + 8002574: 40021000 .word 0x40021000 + 8002578: 007a1200 .word 0x007a1200 + 800257c: 02dc6c00 .word 0x02dc6c00 + +08002580 : + * the backup registers) and RCC_BDCR register are set to their reset values. + * + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit) +{ + 8002580: b580 push {r7, lr} + 8002582: b086 sub sp, #24 + 8002584: af00 add r7, sp, #0 + 8002586: 6078 str r0, [r7, #4] + uint32_t tickstart = 0U; + 8002588: 2300 movs r3, #0 + 800258a: 613b str r3, [r7, #16] + uint32_t temp_reg = 0U; + 800258c: 2300 movs r3, #0 + 800258e: 60fb str r3, [r7, #12] + + /* Check the parameters */ + assert_param(IS_RCC_PERIPHCLOCK(PeriphClkInit->PeriphClockSelection)); + + /*---------------------------- RTC configuration -------------------------------*/ + if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_RTC) == (RCC_PERIPHCLK_RTC)) + 8002590: 687b ldr r3, [r7, #4] + 8002592: 681a ldr r2, [r3, #0] + 8002594: 2380 movs r3, #128 ; 0x80 + 8002596: 025b lsls r3, r3, #9 + 8002598: 4013 ands r3, r2 + 800259a: d100 bne.n 800259e + 800259c: e08f b.n 80026be + { + /* check for RTC Parameters used to output RTCCLK */ + assert_param(IS_RCC_RTCCLKSOURCE(PeriphClkInit->RTCClockSelection)); + + FlagStatus pwrclkchanged = RESET; + 800259e: 2317 movs r3, #23 + 80025a0: 18fb adds r3, r7, r3 + 80025a2: 2200 movs r2, #0 + 80025a4: 701a strb r2, [r3, #0] + + /* As soon as function is called to change RTC clock source, activation of the + power domain is done. */ + /* Requires to enable write access to Backup Domain of necessary */ + if(__HAL_RCC_PWR_IS_CLK_DISABLED()) + 80025a6: 4b6f ldr r3, [pc, #444] ; (8002764 ) + 80025a8: 69da ldr r2, [r3, #28] + 80025aa: 2380 movs r3, #128 ; 0x80 + 80025ac: 055b lsls r3, r3, #21 + 80025ae: 4013 ands r3, r2 + 80025b0: d111 bne.n 80025d6 + { + __HAL_RCC_PWR_CLK_ENABLE(); + 80025b2: 4b6c ldr r3, [pc, #432] ; (8002764 ) + 80025b4: 69da ldr r2, [r3, #28] + 80025b6: 4b6b ldr r3, [pc, #428] ; (8002764 ) + 80025b8: 2180 movs r1, #128 ; 0x80 + 80025ba: 0549 lsls r1, r1, #21 + 80025bc: 430a orrs r2, r1 + 80025be: 61da str r2, [r3, #28] + 80025c0: 4b68 ldr r3, [pc, #416] ; (8002764 ) + 80025c2: 69da ldr r2, [r3, #28] + 80025c4: 2380 movs r3, #128 ; 0x80 + 80025c6: 055b lsls r3, r3, #21 + 80025c8: 4013 ands r3, r2 + 80025ca: 60bb str r3, [r7, #8] + 80025cc: 68bb ldr r3, [r7, #8] + pwrclkchanged = SET; + 80025ce: 2317 movs r3, #23 + 80025d0: 18fb adds r3, r7, r3 + 80025d2: 2201 movs r2, #1 + 80025d4: 701a strb r2, [r3, #0] + } + + if(HAL_IS_BIT_CLR(PWR->CR, PWR_CR_DBP)) + 80025d6: 4b64 ldr r3, [pc, #400] ; (8002768 ) + 80025d8: 681a ldr r2, [r3, #0] + 80025da: 2380 movs r3, #128 ; 0x80 + 80025dc: 005b lsls r3, r3, #1 + 80025de: 4013 ands r3, r2 + 80025e0: d11a bne.n 8002618 + { + /* Enable write access to Backup domain */ + SET_BIT(PWR->CR, PWR_CR_DBP); + 80025e2: 4b61 ldr r3, [pc, #388] ; (8002768 ) + 80025e4: 681a ldr r2, [r3, #0] + 80025e6: 4b60 ldr r3, [pc, #384] ; (8002768 ) + 80025e8: 2180 movs r1, #128 ; 0x80 + 80025ea: 0049 lsls r1, r1, #1 + 80025ec: 430a orrs r2, r1 + 80025ee: 601a str r2, [r3, #0] + + /* Wait for Backup domain Write protection disable */ + tickstart = HAL_GetTick(); + 80025f0: f7fe f868 bl 80006c4 + 80025f4: 0003 movs r3, r0 + 80025f6: 613b str r3, [r7, #16] + + while(HAL_IS_BIT_CLR(PWR->CR, PWR_CR_DBP)) + 80025f8: e008 b.n 800260c + { + if((HAL_GetTick() - tickstart) > RCC_DBP_TIMEOUT_VALUE) + 80025fa: f7fe f863 bl 80006c4 + 80025fe: 0002 movs r2, r0 + 8002600: 693b ldr r3, [r7, #16] + 8002602: 1ad3 subs r3, r2, r3 + 8002604: 2b64 cmp r3, #100 ; 0x64 + 8002606: d901 bls.n 800260c + { + return HAL_TIMEOUT; + 8002608: 2303 movs r3, #3 + 800260a: e0a6 b.n 800275a + while(HAL_IS_BIT_CLR(PWR->CR, PWR_CR_DBP)) + 800260c: 4b56 ldr r3, [pc, #344] ; (8002768 ) + 800260e: 681a ldr r2, [r3, #0] + 8002610: 2380 movs r3, #128 ; 0x80 + 8002612: 005b lsls r3, r3, #1 + 8002614: 4013 ands r3, r2 + 8002616: d0f0 beq.n 80025fa + } + } + } + + /* Reset the Backup domain only if the RTC Clock source selection is modified from reset value */ + temp_reg = (RCC->BDCR & RCC_BDCR_RTCSEL); + 8002618: 4b52 ldr r3, [pc, #328] ; (8002764 ) + 800261a: 6a1a ldr r2, [r3, #32] + 800261c: 23c0 movs r3, #192 ; 0xc0 + 800261e: 009b lsls r3, r3, #2 + 8002620: 4013 ands r3, r2 + 8002622: 60fb str r3, [r7, #12] + if((temp_reg != 0x00000000U) && (temp_reg != (PeriphClkInit->RTCClockSelection & RCC_BDCR_RTCSEL))) + 8002624: 68fb ldr r3, [r7, #12] + 8002626: 2b00 cmp r3, #0 + 8002628: d034 beq.n 8002694 + 800262a: 687b ldr r3, [r7, #4] + 800262c: 685a ldr r2, [r3, #4] + 800262e: 23c0 movs r3, #192 ; 0xc0 + 8002630: 009b lsls r3, r3, #2 + 8002632: 4013 ands r3, r2 + 8002634: 68fa ldr r2, [r7, #12] + 8002636: 429a cmp r2, r3 + 8002638: d02c beq.n 8002694 + { + /* Store the content of BDCR register before the reset of Backup Domain */ + temp_reg = (RCC->BDCR & ~(RCC_BDCR_RTCSEL)); + 800263a: 4b4a ldr r3, [pc, #296] ; (8002764 ) + 800263c: 6a1b ldr r3, [r3, #32] + 800263e: 4a4b ldr r2, [pc, #300] ; (800276c ) + 8002640: 4013 ands r3, r2 + 8002642: 60fb str r3, [r7, #12] + /* RTC Clock selection can be changed only if the Backup Domain is reset */ + __HAL_RCC_BACKUPRESET_FORCE(); + 8002644: 4b47 ldr r3, [pc, #284] ; (8002764 ) + 8002646: 6a1a ldr r2, [r3, #32] + 8002648: 4b46 ldr r3, [pc, #280] ; (8002764 ) + 800264a: 2180 movs r1, #128 ; 0x80 + 800264c: 0249 lsls r1, r1, #9 + 800264e: 430a orrs r2, r1 + 8002650: 621a str r2, [r3, #32] + __HAL_RCC_BACKUPRESET_RELEASE(); + 8002652: 4b44 ldr r3, [pc, #272] ; (8002764 ) + 8002654: 6a1a ldr r2, [r3, #32] + 8002656: 4b43 ldr r3, [pc, #268] ; (8002764 ) + 8002658: 4945 ldr r1, [pc, #276] ; (8002770 ) + 800265a: 400a ands r2, r1 + 800265c: 621a str r2, [r3, #32] + /* Restore the Content of BDCR register */ + RCC->BDCR = temp_reg; + 800265e: 4b41 ldr r3, [pc, #260] ; (8002764 ) + 8002660: 68fa ldr r2, [r7, #12] + 8002662: 621a str r2, [r3, #32] + + /* Wait for LSERDY if LSE was enabled */ + if (HAL_IS_BIT_SET(temp_reg, RCC_BDCR_LSEON)) + 8002664: 68fb ldr r3, [r7, #12] + 8002666: 2201 movs r2, #1 + 8002668: 4013 ands r3, r2 + 800266a: d013 beq.n 8002694 + { + /* Get Start Tick */ + tickstart = HAL_GetTick(); + 800266c: f7fe f82a bl 80006c4 + 8002670: 0003 movs r3, r0 + 8002672: 613b str r3, [r7, #16] + + /* Wait till LSE is ready */ + while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET) + 8002674: e009 b.n 800268a + { + if((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE) + 8002676: f7fe f825 bl 80006c4 + 800267a: 0002 movs r2, r0 + 800267c: 693b ldr r3, [r7, #16] + 800267e: 1ad3 subs r3, r2, r3 + 8002680: 4a3c ldr r2, [pc, #240] ; (8002774 ) + 8002682: 4293 cmp r3, r2 + 8002684: d901 bls.n 800268a + { + return HAL_TIMEOUT; + 8002686: 2303 movs r3, #3 + 8002688: e067 b.n 800275a + while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET) + 800268a: 4b36 ldr r3, [pc, #216] ; (8002764 ) + 800268c: 6a1b ldr r3, [r3, #32] + 800268e: 2202 movs r2, #2 + 8002690: 4013 ands r3, r2 + 8002692: d0f0 beq.n 8002676 + } + } + } + } + __HAL_RCC_RTC_CONFIG(PeriphClkInit->RTCClockSelection); + 8002694: 4b33 ldr r3, [pc, #204] ; (8002764 ) + 8002696: 6a1b ldr r3, [r3, #32] + 8002698: 4a34 ldr r2, [pc, #208] ; (800276c ) + 800269a: 4013 ands r3, r2 + 800269c: 0019 movs r1, r3 + 800269e: 687b ldr r3, [r7, #4] + 80026a0: 685a ldr r2, [r3, #4] + 80026a2: 4b30 ldr r3, [pc, #192] ; (8002764 ) + 80026a4: 430a orrs r2, r1 + 80026a6: 621a str r2, [r3, #32] + + /* Require to disable power clock if necessary */ + if(pwrclkchanged == SET) + 80026a8: 2317 movs r3, #23 + 80026aa: 18fb adds r3, r7, r3 + 80026ac: 781b ldrb r3, [r3, #0] + 80026ae: 2b01 cmp r3, #1 + 80026b0: d105 bne.n 80026be + { + __HAL_RCC_PWR_CLK_DISABLE(); + 80026b2: 4b2c ldr r3, [pc, #176] ; (8002764 ) + 80026b4: 69da ldr r2, [r3, #28] + 80026b6: 4b2b ldr r3, [pc, #172] ; (8002764 ) + 80026b8: 492f ldr r1, [pc, #188] ; (8002778 ) + 80026ba: 400a ands r2, r1 + 80026bc: 61da str r2, [r3, #28] + } + } + + /*------------------------------- USART1 Configuration ------------------------*/ + if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USART1) == RCC_PERIPHCLK_USART1) + 80026be: 687b ldr r3, [r7, #4] + 80026c0: 681b ldr r3, [r3, #0] + 80026c2: 2201 movs r2, #1 + 80026c4: 4013 ands r3, r2 + 80026c6: d009 beq.n 80026dc + { + /* Check the parameters */ + assert_param(IS_RCC_USART1CLKSOURCE(PeriphClkInit->Usart1ClockSelection)); + + /* Configure the USART1 clock source */ + __HAL_RCC_USART1_CONFIG(PeriphClkInit->Usart1ClockSelection); + 80026c8: 4b26 ldr r3, [pc, #152] ; (8002764 ) + 80026ca: 6b1b ldr r3, [r3, #48] ; 0x30 + 80026cc: 2203 movs r2, #3 + 80026ce: 4393 bics r3, r2 + 80026d0: 0019 movs r1, r3 + 80026d2: 687b ldr r3, [r7, #4] + 80026d4: 689a ldr r2, [r3, #8] + 80026d6: 4b23 ldr r3, [pc, #140] ; (8002764 ) + 80026d8: 430a orrs r2, r1 + 80026da: 631a str r2, [r3, #48] ; 0x30 + } + +#if defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F078xx)\ + || defined(STM32F091xC) || defined(STM32F098xx) + /*----------------------------- USART2 Configuration --------------------------*/ + if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USART2) == RCC_PERIPHCLK_USART2) + 80026dc: 687b ldr r3, [r7, #4] + 80026de: 681b ldr r3, [r3, #0] + 80026e0: 2202 movs r2, #2 + 80026e2: 4013 ands r3, r2 + 80026e4: d009 beq.n 80026fa + { + /* Check the parameters */ + assert_param(IS_RCC_USART2CLKSOURCE(PeriphClkInit->Usart2ClockSelection)); + + /* Configure the USART2 clock source */ + __HAL_RCC_USART2_CONFIG(PeriphClkInit->Usart2ClockSelection); + 80026e6: 4b1f ldr r3, [pc, #124] ; (8002764 ) + 80026e8: 6b1b ldr r3, [r3, #48] ; 0x30 + 80026ea: 4a24 ldr r2, [pc, #144] ; (800277c ) + 80026ec: 4013 ands r3, r2 + 80026ee: 0019 movs r1, r3 + 80026f0: 687b ldr r3, [r7, #4] + 80026f2: 68da ldr r2, [r3, #12] + 80026f4: 4b1b ldr r3, [pc, #108] ; (8002764 ) + 80026f6: 430a orrs r2, r1 + 80026f8: 631a str r2, [r3, #48] ; 0x30 + __HAL_RCC_USART3_CONFIG(PeriphClkInit->Usart3ClockSelection); + } +#endif /* STM32F091xC || STM32F098xx */ + + /*------------------------------ I2C1 Configuration ------------------------*/ + if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2C1) == RCC_PERIPHCLK_I2C1) + 80026fa: 687b ldr r3, [r7, #4] + 80026fc: 681b ldr r3, [r3, #0] + 80026fe: 2220 movs r2, #32 + 8002700: 4013 ands r3, r2 + 8002702: d009 beq.n 8002718 + { + /* Check the parameters */ + assert_param(IS_RCC_I2C1CLKSOURCE(PeriphClkInit->I2c1ClockSelection)); + + /* Configure the I2C1 clock source */ + __HAL_RCC_I2C1_CONFIG(PeriphClkInit->I2c1ClockSelection); + 8002704: 4b17 ldr r3, [pc, #92] ; (8002764 ) + 8002706: 6b1b ldr r3, [r3, #48] ; 0x30 + 8002708: 2210 movs r2, #16 + 800270a: 4393 bics r3, r2 + 800270c: 0019 movs r1, r3 + 800270e: 687b ldr r3, [r7, #4] + 8002710: 691a ldr r2, [r3, #16] + 8002712: 4b14 ldr r3, [pc, #80] ; (8002764 ) + 8002714: 430a orrs r2, r1 + 8002716: 631a str r2, [r3, #48] ; 0x30 + } + +#if defined(STM32F042x6) || defined(STM32F048xx) || defined(STM32F072xB) || defined(STM32F078xx) || defined(STM32F070xB) || defined(STM32F070x6) + /*------------------------------ USB Configuration ------------------------*/ + if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USB) == RCC_PERIPHCLK_USB) + 8002718: 687b ldr r3, [r7, #4] + 800271a: 681a ldr r2, [r3, #0] + 800271c: 2380 movs r3, #128 ; 0x80 + 800271e: 029b lsls r3, r3, #10 + 8002720: 4013 ands r3, r2 + 8002722: d009 beq.n 8002738 + { + /* Check the parameters */ + assert_param(IS_RCC_USBCLKSOURCE(PeriphClkInit->UsbClockSelection)); + + /* Configure the USB clock source */ + __HAL_RCC_USB_CONFIG(PeriphClkInit->UsbClockSelection); + 8002724: 4b0f ldr r3, [pc, #60] ; (8002764 ) + 8002726: 6b1b ldr r3, [r3, #48] ; 0x30 + 8002728: 2280 movs r2, #128 ; 0x80 + 800272a: 4393 bics r3, r2 + 800272c: 0019 movs r1, r3 + 800272e: 687b ldr r3, [r7, #4] + 8002730: 699a ldr r2, [r3, #24] + 8002732: 4b0c ldr r3, [pc, #48] ; (8002764 ) + 8002734: 430a orrs r2, r1 + 8002736: 631a str r2, [r3, #48] ; 0x30 +#if defined(STM32F042x6) || defined(STM32F048xx)\ + || defined(STM32F051x8) || defined(STM32F058xx)\ + || defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F078xx)\ + || defined(STM32F091xC) || defined(STM32F098xx) + /*------------------------------ CEC clock Configuration -------------------*/ + if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_CEC) == RCC_PERIPHCLK_CEC) + 8002738: 687b ldr r3, [r7, #4] + 800273a: 681a ldr r2, [r3, #0] + 800273c: 2380 movs r3, #128 ; 0x80 + 800273e: 00db lsls r3, r3, #3 + 8002740: 4013 ands r3, r2 + 8002742: d009 beq.n 8002758 + { + /* Check the parameters */ + assert_param(IS_RCC_CECCLKSOURCE(PeriphClkInit->CecClockSelection)); + + /* Configure the CEC clock source */ + __HAL_RCC_CEC_CONFIG(PeriphClkInit->CecClockSelection); + 8002744: 4b07 ldr r3, [pc, #28] ; (8002764 ) + 8002746: 6b1b ldr r3, [r3, #48] ; 0x30 + 8002748: 2240 movs r2, #64 ; 0x40 + 800274a: 4393 bics r3, r2 + 800274c: 0019 movs r1, r3 + 800274e: 687b ldr r3, [r7, #4] + 8002750: 695a ldr r2, [r3, #20] + 8002752: 4b04 ldr r3, [pc, #16] ; (8002764 ) + 8002754: 430a orrs r2, r1 + 8002756: 631a str r2, [r3, #48] ; 0x30 +#endif /* STM32F042x6 || STM32F048xx || */ + /* STM32F051x8 || STM32F058xx || */ + /* STM32F071xB || STM32F072xB || STM32F078xx || */ + /* STM32F091xC || STM32F098xx */ + + return HAL_OK; + 8002758: 2300 movs r3, #0 +} + 800275a: 0018 movs r0, r3 + 800275c: 46bd mov sp, r7 + 800275e: b006 add sp, #24 + 8002760: bd80 pop {r7, pc} + 8002762: 46c0 nop ; (mov r8, r8) + 8002764: 40021000 .word 0x40021000 + 8002768: 40007000 .word 0x40007000 + 800276c: fffffcff .word 0xfffffcff + 8002770: fffeffff .word 0xfffeffff + 8002774: 00001388 .word 0x00001388 + 8002778: efffffff .word 0xefffffff + 800277c: fffcffff .word 0xfffcffff + +08002780 : + * Enables the controller's Global Int in the AHB Config reg + * @param USBx : Selected device + * @retval HAL status + */ +HAL_StatusTypeDef USB_EnableGlobalInt(USB_TypeDef *USBx) +{ + 8002780: b580 push {r7, lr} + 8002782: b084 sub sp, #16 + 8002784: af00 add r7, sp, #0 + 8002786: 6078 str r0, [r7, #4] + uint16_t winterruptmask; + + /* Set winterruptmask variable */ + winterruptmask = USB_CNTR_CTRM | USB_CNTR_WKUPM | + 8002788: 210e movs r1, #14 + 800278a: 187b adds r3, r7, r1 + 800278c: 4a08 ldr r2, [pc, #32] ; (80027b0 ) + 800278e: 801a strh r2, [r3, #0] + USB_CNTR_SUSPM | USB_CNTR_ERRM | + USB_CNTR_SOFM | USB_CNTR_ESOFM | + USB_CNTR_RESETM | USB_CNTR_L1REQM; + + /* Set interrupt mask */ + USBx->CNTR |= winterruptmask; + 8002790: 687b ldr r3, [r7, #4] + 8002792: 2240 movs r2, #64 ; 0x40 + 8002794: 5a9b ldrh r3, [r3, r2] + 8002796: b29a uxth r2, r3 + 8002798: 187b adds r3, r7, r1 + 800279a: 881b ldrh r3, [r3, #0] + 800279c: 4313 orrs r3, r2 + 800279e: b299 uxth r1, r3 + 80027a0: 687b ldr r3, [r7, #4] + 80027a2: 2240 movs r2, #64 ; 0x40 + 80027a4: 5299 strh r1, [r3, r2] + + return HAL_OK; + 80027a6: 2300 movs r3, #0 +} + 80027a8: 0018 movs r0, r3 + 80027aa: 46bd mov sp, r7 + 80027ac: b004 add sp, #16 + 80027ae: bd80 pop {r7, pc} + 80027b0: ffffbf80 .word 0xffffbf80 + +080027b4 : + * Disable the controller's Global Int in the AHB Config reg + * @param USBx : Selected device + * @retval HAL status +*/ +HAL_StatusTypeDef USB_DisableGlobalInt(USB_TypeDef *USBx) +{ + 80027b4: b580 push {r7, lr} + 80027b6: b084 sub sp, #16 + 80027b8: af00 add r7, sp, #0 + 80027ba: 6078 str r0, [r7, #4] + uint16_t winterruptmask; + + /* Set winterruptmask variable */ + winterruptmask = USB_CNTR_CTRM | USB_CNTR_WKUPM | + 80027bc: 210e movs r1, #14 + 80027be: 187b adds r3, r7, r1 + 80027c0: 4a0b ldr r2, [pc, #44] ; (80027f0 ) + 80027c2: 801a strh r2, [r3, #0] + USB_CNTR_SUSPM | USB_CNTR_ERRM | + USB_CNTR_SOFM | USB_CNTR_ESOFM | + USB_CNTR_RESETM | USB_CNTR_L1REQM; + + /* Clear interrupt mask */ + USBx->CNTR &= ~winterruptmask; + 80027c4: 687b ldr r3, [r7, #4] + 80027c6: 2240 movs r2, #64 ; 0x40 + 80027c8: 5a9b ldrh r3, [r3, r2] + 80027ca: b29b uxth r3, r3 + 80027cc: b21b sxth r3, r3 + 80027ce: 187a adds r2, r7, r1 + 80027d0: 2100 movs r1, #0 + 80027d2: 5e52 ldrsh r2, [r2, r1] + 80027d4: 43d2 mvns r2, r2 + 80027d6: b212 sxth r2, r2 + 80027d8: 4013 ands r3, r2 + 80027da: b21b sxth r3, r3 + 80027dc: b299 uxth r1, r3 + 80027de: 687b ldr r3, [r7, #4] + 80027e0: 2240 movs r2, #64 ; 0x40 + 80027e2: 5299 strh r1, [r3, r2] + + return HAL_OK; + 80027e4: 2300 movs r3, #0 +} + 80027e6: 0018 movs r0, r3 + 80027e8: 46bd mov sp, r7 + 80027ea: b004 add sp, #16 + 80027ec: bd80 pop {r7, pc} + 80027ee: 46c0 nop ; (mov r8, r8) + 80027f0: ffffbf80 .word 0xffffbf80 + +080027f4 : + * @param cfg : pointer to a USB_CfgTypeDef structure that contains + * the configuration information for the specified USBx peripheral. + * @retval HAL status + */ +HAL_StatusTypeDef USB_DevInit(USB_TypeDef *USBx, USB_CfgTypeDef cfg) +{ + 80027f4: b084 sub sp, #16 + 80027f6: b590 push {r4, r7, lr} + 80027f8: 46c6 mov lr, r8 + 80027fa: b500 push {lr} + 80027fc: b082 sub sp, #8 + 80027fe: af00 add r7, sp, #0 + 8002800: 6078 str r0, [r7, #4] + 8002802: 2004 movs r0, #4 + 8002804: 2410 movs r4, #16 + 8002806: 46a4 mov ip, r4 + 8002808: 2408 movs r4, #8 + 800280a: 46a0 mov r8, r4 + 800280c: 44b8 add r8, r7 + 800280e: 44c4 add ip, r8 + 8002810: 4460 add r0, ip + 8002812: 6001 str r1, [r0, #0] + 8002814: 6042 str r2, [r0, #4] + 8002816: 6083 str r3, [r0, #8] + /* Prevent unused argument(s) compilation warning */ + UNUSED(cfg); + + /* Init Device */ + /*CNTR_FRES = 1*/ + USBx->CNTR = USB_CNTR_FRES; + 8002818: 687b ldr r3, [r7, #4] + 800281a: 2240 movs r2, #64 ; 0x40 + 800281c: 2101 movs r1, #1 + 800281e: 5299 strh r1, [r3, r2] + + /*CNTR_FRES = 0*/ + USBx->CNTR = 0; + 8002820: 687b ldr r3, [r7, #4] + 8002822: 2240 movs r2, #64 ; 0x40 + 8002824: 2100 movs r1, #0 + 8002826: 5299 strh r1, [r3, r2] + + /*Clear pending interrupts*/ + USBx->ISTR = 0; + 8002828: 687b ldr r3, [r7, #4] + 800282a: 2244 movs r2, #68 ; 0x44 + 800282c: 2100 movs r1, #0 + 800282e: 5299 strh r1, [r3, r2] + + /*Set Btable Address*/ + USBx->BTABLE = BTABLE_ADDRESS; + 8002830: 687b ldr r3, [r7, #4] + 8002832: 2250 movs r2, #80 ; 0x50 + 8002834: 2100 movs r1, #0 + 8002836: 5299 strh r1, [r3, r2] + + /* Enable USB Device Interrupt mask */ + (void)USB_EnableGlobalInt(USBx); + 8002838: 687b ldr r3, [r7, #4] + 800283a: 0018 movs r0, r3 + 800283c: f7ff ffa0 bl 8002780 + + return HAL_OK; + 8002840: 2300 movs r3, #0 +} + 8002842: 0018 movs r0, r3 + 8002844: 46bd mov sp, r7 + 8002846: b002 add sp, #8 + 8002848: bc04 pop {r2} + 800284a: 4690 mov r8, r2 + 800284c: bc90 pop {r4, r7} + 800284e: bc08 pop {r3} + 8002850: b004 add sp, #16 + 8002852: 4718 bx r3 + +08002854 : + * @param USBx : Selected device + * @param ep: pointer to endpoint structure + * @retval HAL status + */ +HAL_StatusTypeDef USB_ActivateEndpoint(USB_TypeDef *USBx, USB_EPTypeDef *ep) +{ + 8002854: b590 push {r4, r7, lr} + 8002856: b087 sub sp, #28 + 8002858: af00 add r7, sp, #0 + 800285a: 6078 str r0, [r7, #4] + 800285c: 6039 str r1, [r7, #0] + HAL_StatusTypeDef ret = HAL_OK; + 800285e: 2317 movs r3, #23 + 8002860: 18fb adds r3, r7, r3 + 8002862: 2200 movs r2, #0 + 8002864: 701a strb r2, [r3, #0] + uint16_t wEpRegVal; + + wEpRegVal = PCD_GET_ENDPOINT(USBx, ep->num) & USB_EP_T_MASK; + 8002866: 687a ldr r2, [r7, #4] + 8002868: 683b ldr r3, [r7, #0] + 800286a: 781b ldrb r3, [r3, #0] + 800286c: 009b lsls r3, r3, #2 + 800286e: 18d3 adds r3, r2, r3 + 8002870: 881b ldrh r3, [r3, #0] + 8002872: b29a uxth r2, r3 + 8002874: 2314 movs r3, #20 + 8002876: 18fb adds r3, r7, r3 + 8002878: 49b2 ldr r1, [pc, #712] ; (8002b44 ) + 800287a: 400a ands r2, r1 + 800287c: 801a strh r2, [r3, #0] + + /* initialize Endpoint */ + switch (ep->type) + 800287e: 683b ldr r3, [r7, #0] + 8002880: 78db ldrb r3, [r3, #3] + 8002882: 2b01 cmp r3, #1 + 8002884: d020 beq.n 80028c8 + 8002886: dc02 bgt.n 800288e + 8002888: 2b00 cmp r3, #0 + 800288a: d005 beq.n 8002898 + 800288c: e025 b.n 80028da + 800288e: 2b02 cmp r3, #2 + 8002890: d00b beq.n 80028aa + 8002892: 2b03 cmp r3, #3 + 8002894: d00f beq.n 80028b6 + 8002896: e020 b.n 80028da + { + case EP_TYPE_CTRL: + wEpRegVal |= USB_EP_CONTROL; + 8002898: 2214 movs r2, #20 + 800289a: 18bb adds r3, r7, r2 + 800289c: 18ba adds r2, r7, r2 + 800289e: 8812 ldrh r2, [r2, #0] + 80028a0: 2180 movs r1, #128 ; 0x80 + 80028a2: 0089 lsls r1, r1, #2 + 80028a4: 430a orrs r2, r1 + 80028a6: 801a strh r2, [r3, #0] + break; + 80028a8: e01c b.n 80028e4 + + case EP_TYPE_BULK: + wEpRegVal |= USB_EP_BULK; + 80028aa: 2214 movs r2, #20 + 80028ac: 18bb adds r3, r7, r2 + 80028ae: 18ba adds r2, r7, r2 + 80028b0: 8812 ldrh r2, [r2, #0] + 80028b2: 801a strh r2, [r3, #0] + break; + 80028b4: e016 b.n 80028e4 + + case EP_TYPE_INTR: + wEpRegVal |= USB_EP_INTERRUPT; + 80028b6: 2214 movs r2, #20 + 80028b8: 18bb adds r3, r7, r2 + 80028ba: 18ba adds r2, r7, r2 + 80028bc: 8812 ldrh r2, [r2, #0] + 80028be: 21c0 movs r1, #192 ; 0xc0 + 80028c0: 00c9 lsls r1, r1, #3 + 80028c2: 430a orrs r2, r1 + 80028c4: 801a strh r2, [r3, #0] + break; + 80028c6: e00d b.n 80028e4 + + case EP_TYPE_ISOC: + wEpRegVal |= USB_EP_ISOCHRONOUS; + 80028c8: 2214 movs r2, #20 + 80028ca: 18bb adds r3, r7, r2 + 80028cc: 18ba adds r2, r7, r2 + 80028ce: 8812 ldrh r2, [r2, #0] + 80028d0: 2180 movs r1, #128 ; 0x80 + 80028d2: 00c9 lsls r1, r1, #3 + 80028d4: 430a orrs r2, r1 + 80028d6: 801a strh r2, [r3, #0] + break; + 80028d8: e004 b.n 80028e4 + + default: + ret = HAL_ERROR; + 80028da: 2317 movs r3, #23 + 80028dc: 18fb adds r3, r7, r3 + 80028de: 2201 movs r2, #1 + 80028e0: 701a strb r2, [r3, #0] + break; + 80028e2: 46c0 nop ; (mov r8, r8) + } + + PCD_SET_ENDPOINT(USBx, ep->num, wEpRegVal | USB_EP_CTR_RX | USB_EP_CTR_TX); + 80028e4: 687a ldr r2, [r7, #4] + 80028e6: 683b ldr r3, [r7, #0] + 80028e8: 781b ldrb r3, [r3, #0] + 80028ea: 009b lsls r3, r3, #2 + 80028ec: 18d3 adds r3, r2, r3 + 80028ee: 2214 movs r2, #20 + 80028f0: 18ba adds r2, r7, r2 + 80028f2: 8812 ldrh r2, [r2, #0] + 80028f4: 4994 ldr r1, [pc, #592] ; (8002b48 ) + 80028f6: 430a orrs r2, r1 + 80028f8: b292 uxth r2, r2 + 80028fa: 801a strh r2, [r3, #0] + + PCD_SET_EP_ADDRESS(USBx, ep->num, ep->num); + 80028fc: 687a ldr r2, [r7, #4] + 80028fe: 683b ldr r3, [r7, #0] + 8002900: 781b ldrb r3, [r3, #0] + 8002902: 009b lsls r3, r3, #2 + 8002904: 18d3 adds r3, r2, r3 + 8002906: 881b ldrh r3, [r3, #0] + 8002908: b29b uxth r3, r3 + 800290a: b21b sxth r3, r3 + 800290c: 4a8f ldr r2, [pc, #572] ; (8002b4c ) + 800290e: 4013 ands r3, r2 + 8002910: b21a sxth r2, r3 + 8002912: 683b ldr r3, [r7, #0] + 8002914: 781b ldrb r3, [r3, #0] + 8002916: b21b sxth r3, r3 + 8002918: 4313 orrs r3, r2 + 800291a: b21b sxth r3, r3 + 800291c: b29c uxth r4, r3 + 800291e: 687a ldr r2, [r7, #4] + 8002920: 683b ldr r3, [r7, #0] + 8002922: 781b ldrb r3, [r3, #0] + 8002924: 009b lsls r3, r3, #2 + 8002926: 18d3 adds r3, r2, r3 + 8002928: 4a87 ldr r2, [pc, #540] ; (8002b48 ) + 800292a: 4322 orrs r2, r4 + 800292c: b292 uxth r2, r2 + 800292e: 801a strh r2, [r3, #0] + + if (ep->doublebuffer == 0U) + 8002930: 683b ldr r3, [r7, #0] + 8002932: 7b1b ldrb r3, [r3, #12] + 8002934: 2b00 cmp r3, #0 + 8002936: d000 beq.n 800293a + 8002938: e11a b.n 8002b70 + { + if (ep->is_in != 0U) + 800293a: 683b ldr r3, [r7, #0] + 800293c: 785b ldrb r3, [r3, #1] + 800293e: 2b00 cmp r3, #0 + 8002940: d062 beq.n 8002a08 + { + /*Set the endpoint Transmit buffer address */ + PCD_SET_EP_TX_ADDRESS(USBx, ep->num, ep->pmaadress); + 8002942: 687c ldr r4, [r7, #4] + 8002944: 687b ldr r3, [r7, #4] + 8002946: 2250 movs r2, #80 ; 0x50 + 8002948: 5a9b ldrh r3, [r3, r2] + 800294a: b29b uxth r3, r3 + 800294c: 18e4 adds r4, r4, r3 + 800294e: 683b ldr r3, [r7, #0] + 8002950: 781b ldrb r3, [r3, #0] + 8002952: 00db lsls r3, r3, #3 + 8002954: 18e3 adds r3, r4, r3 + 8002956: 2280 movs r2, #128 ; 0x80 + 8002958: 00d2 lsls r2, r2, #3 + 800295a: 4694 mov ip, r2 + 800295c: 4463 add r3, ip + 800295e: 001c movs r4, r3 + 8002960: 683b ldr r3, [r7, #0] + 8002962: 88db ldrh r3, [r3, #6] + 8002964: 085b lsrs r3, r3, #1 + 8002966: b29b uxth r3, r3 + 8002968: 18db adds r3, r3, r3 + 800296a: b29b uxth r3, r3 + 800296c: 8023 strh r3, [r4, #0] + PCD_CLEAR_TX_DTOG(USBx, ep->num); + 800296e: 687a ldr r2, [r7, #4] + 8002970: 683b ldr r3, [r7, #0] + 8002972: 781b ldrb r3, [r3, #0] + 8002974: 009b lsls r3, r3, #2 + 8002976: 18d3 adds r3, r2, r3 + 8002978: 881b ldrh r3, [r3, #0] + 800297a: b29c uxth r4, r3 + 800297c: 0022 movs r2, r4 + 800297e: 2340 movs r3, #64 ; 0x40 + 8002980: 4013 ands r3, r2 + 8002982: d012 beq.n 80029aa + 8002984: 687a ldr r2, [r7, #4] + 8002986: 683b ldr r3, [r7, #0] + 8002988: 781b ldrb r3, [r3, #0] + 800298a: 009b lsls r3, r3, #2 + 800298c: 18d3 adds r3, r2, r3 + 800298e: 881b ldrh r3, [r3, #0] + 8002990: b29b uxth r3, r3 + 8002992: 4a6e ldr r2, [pc, #440] ; (8002b4c ) + 8002994: 4013 ands r3, r2 + 8002996: b29c uxth r4, r3 + 8002998: 687a ldr r2, [r7, #4] + 800299a: 683b ldr r3, [r7, #0] + 800299c: 781b ldrb r3, [r3, #0] + 800299e: 009b lsls r3, r3, #2 + 80029a0: 18d3 adds r3, r2, r3 + 80029a2: 4a6b ldr r2, [pc, #428] ; (8002b50 ) + 80029a4: 4322 orrs r2, r4 + 80029a6: b292 uxth r2, r2 + 80029a8: 801a strh r2, [r3, #0] + + if (ep->type != EP_TYPE_ISOC) + 80029aa: 683b ldr r3, [r7, #0] + 80029ac: 78db ldrb r3, [r3, #3] + 80029ae: 2b01 cmp r3, #1 + 80029b0: d016 beq.n 80029e0 + { + /* Configure NAK status for the Endpoint */ + PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_NAK); + 80029b2: 687a ldr r2, [r7, #4] + 80029b4: 683b ldr r3, [r7, #0] + 80029b6: 781b ldrb r3, [r3, #0] + 80029b8: 009b lsls r3, r3, #2 + 80029ba: 18d3 adds r3, r2, r3 + 80029bc: 881b ldrh r3, [r3, #0] + 80029be: b29b uxth r3, r3 + 80029c0: 4a64 ldr r2, [pc, #400] ; (8002b54 ) + 80029c2: 4013 ands r3, r2 + 80029c4: b29c uxth r4, r3 + 80029c6: 2320 movs r3, #32 + 80029c8: 4063 eors r3, r4 + 80029ca: b29c uxth r4, r3 + 80029cc: 687a ldr r2, [r7, #4] + 80029ce: 683b ldr r3, [r7, #0] + 80029d0: 781b ldrb r3, [r3, #0] + 80029d2: 009b lsls r3, r3, #2 + 80029d4: 18d3 adds r3, r2, r3 + 80029d6: 4a5c ldr r2, [pc, #368] ; (8002b48 ) + 80029d8: 4322 orrs r2, r4 + 80029da: b292 uxth r2, r2 + 80029dc: 801a strh r2, [r3, #0] + 80029de: e21a b.n 8002e16 + } + else + { + /* Configure TX Endpoint to disabled state */ + PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS); + 80029e0: 687a ldr r2, [r7, #4] + 80029e2: 683b ldr r3, [r7, #0] + 80029e4: 781b ldrb r3, [r3, #0] + 80029e6: 009b lsls r3, r3, #2 + 80029e8: 18d3 adds r3, r2, r3 + 80029ea: 881b ldrh r3, [r3, #0] + 80029ec: b29b uxth r3, r3 + 80029ee: 4a59 ldr r2, [pc, #356] ; (8002b54 ) + 80029f0: 4013 ands r3, r2 + 80029f2: b29c uxth r4, r3 + 80029f4: 687a ldr r2, [r7, #4] + 80029f6: 683b ldr r3, [r7, #0] + 80029f8: 781b ldrb r3, [r3, #0] + 80029fa: 009b lsls r3, r3, #2 + 80029fc: 18d3 adds r3, r2, r3 + 80029fe: 4a52 ldr r2, [pc, #328] ; (8002b48 ) + 8002a00: 4322 orrs r2, r4 + 8002a02: b292 uxth r2, r2 + 8002a04: 801a strh r2, [r3, #0] + 8002a06: e206 b.n 8002e16 + } + } + else + { + /*Set the endpoint Receive buffer address */ + PCD_SET_EP_RX_ADDRESS(USBx, ep->num, ep->pmaadress); + 8002a08: 687c ldr r4, [r7, #4] + 8002a0a: 687b ldr r3, [r7, #4] + 8002a0c: 2250 movs r2, #80 ; 0x50 + 8002a0e: 5a9b ldrh r3, [r3, r2] + 8002a10: b29b uxth r3, r3 + 8002a12: 18e4 adds r4, r4, r3 + 8002a14: 683b ldr r3, [r7, #0] + 8002a16: 781b ldrb r3, [r3, #0] + 8002a18: 00db lsls r3, r3, #3 + 8002a1a: 18e3 adds r3, r4, r3 + 8002a1c: 4a4e ldr r2, [pc, #312] ; (8002b58 ) + 8002a1e: 4694 mov ip, r2 + 8002a20: 4463 add r3, ip + 8002a22: 001c movs r4, r3 + 8002a24: 683b ldr r3, [r7, #0] + 8002a26: 88db ldrh r3, [r3, #6] + 8002a28: 085b lsrs r3, r3, #1 + 8002a2a: b29b uxth r3, r3 + 8002a2c: 18db adds r3, r3, r3 + 8002a2e: b29b uxth r3, r3 + 8002a30: 8023 strh r3, [r4, #0] + /*Set the endpoint Receive buffer counter*/ + PCD_SET_EP_RX_CNT(USBx, ep->num, ep->maxpacket); + 8002a32: 687c ldr r4, [r7, #4] + 8002a34: 687b ldr r3, [r7, #4] + 8002a36: 2250 movs r2, #80 ; 0x50 + 8002a38: 5a9b ldrh r3, [r3, r2] + 8002a3a: b29b uxth r3, r3 + 8002a3c: 18e4 adds r4, r4, r3 + 8002a3e: 683b ldr r3, [r7, #0] + 8002a40: 781b ldrb r3, [r3, #0] + 8002a42: 00db lsls r3, r3, #3 + 8002a44: 18e3 adds r3, r4, r3 + 8002a46: 4a45 ldr r2, [pc, #276] ; (8002b5c ) + 8002a48: 4694 mov ip, r2 + 8002a4a: 4463 add r3, ip + 8002a4c: 60fb str r3, [r7, #12] + 8002a4e: 683b ldr r3, [r7, #0] + 8002a50: 691b ldr r3, [r3, #16] + 8002a52: 2b00 cmp r3, #0 + 8002a54: d10e bne.n 8002a74 + 8002a56: 68fb ldr r3, [r7, #12] + 8002a58: 881b ldrh r3, [r3, #0] + 8002a5a: 4a41 ldr r2, [pc, #260] ; (8002b60 ) + 8002a5c: 4013 ands r3, r2 + 8002a5e: b29a uxth r2, r3 + 8002a60: 68fb ldr r3, [r7, #12] + 8002a62: 801a strh r2, [r3, #0] + 8002a64: 68fb ldr r3, [r7, #12] + 8002a66: 881b ldrh r3, [r3, #0] + 8002a68: 4a3e ldr r2, [pc, #248] ; (8002b64 ) + 8002a6a: 4313 orrs r3, r2 + 8002a6c: b29a uxth r2, r3 + 8002a6e: 68fb ldr r3, [r7, #12] + 8002a70: 801a strh r2, [r3, #0] + 8002a72: e02b b.n 8002acc + 8002a74: 683b ldr r3, [r7, #0] + 8002a76: 691b ldr r3, [r3, #16] + 8002a78: 2b3e cmp r3, #62 ; 0x3e + 8002a7a: d812 bhi.n 8002aa2 + 8002a7c: 683b ldr r3, [r7, #0] + 8002a7e: 691b ldr r3, [r3, #16] + 8002a80: 085b lsrs r3, r3, #1 + 8002a82: 613b str r3, [r7, #16] + 8002a84: 683b ldr r3, [r7, #0] + 8002a86: 691b ldr r3, [r3, #16] + 8002a88: 2201 movs r2, #1 + 8002a8a: 4013 ands r3, r2 + 8002a8c: d002 beq.n 8002a94 + 8002a8e: 693b ldr r3, [r7, #16] + 8002a90: 3301 adds r3, #1 + 8002a92: 613b str r3, [r7, #16] + 8002a94: 693b ldr r3, [r7, #16] + 8002a96: b29b uxth r3, r3 + 8002a98: 029b lsls r3, r3, #10 + 8002a9a: b29a uxth r2, r3 + 8002a9c: 68fb ldr r3, [r7, #12] + 8002a9e: 801a strh r2, [r3, #0] + 8002aa0: e014 b.n 8002acc + 8002aa2: 683b ldr r3, [r7, #0] + 8002aa4: 691b ldr r3, [r3, #16] + 8002aa6: 095b lsrs r3, r3, #5 + 8002aa8: 613b str r3, [r7, #16] + 8002aaa: 683b ldr r3, [r7, #0] + 8002aac: 691b ldr r3, [r3, #16] + 8002aae: 221f movs r2, #31 + 8002ab0: 4013 ands r3, r2 + 8002ab2: d102 bne.n 8002aba + 8002ab4: 693b ldr r3, [r7, #16] + 8002ab6: 3b01 subs r3, #1 + 8002ab8: 613b str r3, [r7, #16] + 8002aba: 693b ldr r3, [r7, #16] + 8002abc: b29b uxth r3, r3 + 8002abe: 029b lsls r3, r3, #10 + 8002ac0: b29b uxth r3, r3 + 8002ac2: 4a28 ldr r2, [pc, #160] ; (8002b64 ) + 8002ac4: 4313 orrs r3, r2 + 8002ac6: b29a uxth r2, r3 + 8002ac8: 68fb ldr r3, [r7, #12] + 8002aca: 801a strh r2, [r3, #0] + PCD_CLEAR_RX_DTOG(USBx, ep->num); + 8002acc: 687a ldr r2, [r7, #4] + 8002ace: 683b ldr r3, [r7, #0] + 8002ad0: 781b ldrb r3, [r3, #0] + 8002ad2: 009b lsls r3, r3, #2 + 8002ad4: 18d3 adds r3, r2, r3 + 8002ad6: 881b ldrh r3, [r3, #0] + 8002ad8: b29c uxth r4, r3 + 8002ada: 0022 movs r2, r4 + 8002adc: 2380 movs r3, #128 ; 0x80 + 8002ade: 01db lsls r3, r3, #7 + 8002ae0: 4013 ands r3, r2 + 8002ae2: d012 beq.n 8002b0a + 8002ae4: 687a ldr r2, [r7, #4] + 8002ae6: 683b ldr r3, [r7, #0] + 8002ae8: 781b ldrb r3, [r3, #0] + 8002aea: 009b lsls r3, r3, #2 + 8002aec: 18d3 adds r3, r2, r3 + 8002aee: 881b ldrh r3, [r3, #0] + 8002af0: b29b uxth r3, r3 + 8002af2: 4a16 ldr r2, [pc, #88] ; (8002b4c ) + 8002af4: 4013 ands r3, r2 + 8002af6: b29c uxth r4, r3 + 8002af8: 687a ldr r2, [r7, #4] + 8002afa: 683b ldr r3, [r7, #0] + 8002afc: 781b ldrb r3, [r3, #0] + 8002afe: 009b lsls r3, r3, #2 + 8002b00: 18d3 adds r3, r2, r3 + 8002b02: 4a19 ldr r2, [pc, #100] ; (8002b68 ) + 8002b04: 4322 orrs r2, r4 + 8002b06: b292 uxth r2, r2 + 8002b08: 801a strh r2, [r3, #0] + /* Configure VALID status for the Endpoint*/ + PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_VALID); + 8002b0a: 687a ldr r2, [r7, #4] + 8002b0c: 683b ldr r3, [r7, #0] + 8002b0e: 781b ldrb r3, [r3, #0] + 8002b10: 009b lsls r3, r3, #2 + 8002b12: 18d3 adds r3, r2, r3 + 8002b14: 881b ldrh r3, [r3, #0] + 8002b16: b29b uxth r3, r3 + 8002b18: 4a14 ldr r2, [pc, #80] ; (8002b6c ) + 8002b1a: 4013 ands r3, r2 + 8002b1c: b29c uxth r4, r3 + 8002b1e: 2380 movs r3, #128 ; 0x80 + 8002b20: 015b lsls r3, r3, #5 + 8002b22: 4063 eors r3, r4 + 8002b24: b29c uxth r4, r3 + 8002b26: 2380 movs r3, #128 ; 0x80 + 8002b28: 019b lsls r3, r3, #6 + 8002b2a: 4063 eors r3, r4 + 8002b2c: b29c uxth r4, r3 + 8002b2e: 687a ldr r2, [r7, #4] + 8002b30: 683b ldr r3, [r7, #0] + 8002b32: 781b ldrb r3, [r3, #0] + 8002b34: 009b lsls r3, r3, #2 + 8002b36: 18d3 adds r3, r2, r3 + 8002b38: 4a03 ldr r2, [pc, #12] ; (8002b48 ) + 8002b3a: 4322 orrs r2, r4 + 8002b3c: b292 uxth r2, r2 + 8002b3e: 801a strh r2, [r3, #0] + 8002b40: e169 b.n 8002e16 + 8002b42: 46c0 nop ; (mov r8, r8) + 8002b44: ffff898f .word 0xffff898f + 8002b48: ffff8080 .word 0xffff8080 + 8002b4c: ffff8f8f .word 0xffff8f8f + 8002b50: ffff80c0 .word 0xffff80c0 + 8002b54: ffff8fbf .word 0xffff8fbf + 8002b58: 00000404 .word 0x00000404 + 8002b5c: 00000406 .word 0x00000406 + 8002b60: ffff83ff .word 0xffff83ff + 8002b64: ffff8000 .word 0xffff8000 + 8002b68: ffffc080 .word 0xffffc080 + 8002b6c: ffffbf8f .word 0xffffbf8f + } + /*Double Buffer*/ + else + { + /* Set the endpoint as double buffered */ + PCD_SET_EP_DBUF(USBx, ep->num); + 8002b70: 687a ldr r2, [r7, #4] + 8002b72: 683b ldr r3, [r7, #0] + 8002b74: 781b ldrb r3, [r3, #0] + 8002b76: 009b lsls r3, r3, #2 + 8002b78: 18d3 adds r3, r2, r3 + 8002b7a: 881b ldrh r3, [r3, #0] + 8002b7c: b29b uxth r3, r3 + 8002b7e: 4aa9 ldr r2, [pc, #676] ; (8002e24 ) + 8002b80: 4013 ands r3, r2 + 8002b82: b29c uxth r4, r3 + 8002b84: 687a ldr r2, [r7, #4] + 8002b86: 683b ldr r3, [r7, #0] + 8002b88: 781b ldrb r3, [r3, #0] + 8002b8a: 009b lsls r3, r3, #2 + 8002b8c: 18d3 adds r3, r2, r3 + 8002b8e: 4aa6 ldr r2, [pc, #664] ; (8002e28 ) + 8002b90: 4322 orrs r2, r4 + 8002b92: b292 uxth r2, r2 + 8002b94: 801a strh r2, [r3, #0] + /* Set buffer address for double buffered mode */ + PCD_SET_EP_DBUF_ADDR(USBx, ep->num, ep->pmaaddr0, ep->pmaaddr1); + 8002b96: 687c ldr r4, [r7, #4] + 8002b98: 687b ldr r3, [r7, #4] + 8002b9a: 2250 movs r2, #80 ; 0x50 + 8002b9c: 5a9b ldrh r3, [r3, r2] + 8002b9e: b29b uxth r3, r3 + 8002ba0: 18e4 adds r4, r4, r3 + 8002ba2: 683b ldr r3, [r7, #0] + 8002ba4: 781b ldrb r3, [r3, #0] + 8002ba6: 00db lsls r3, r3, #3 + 8002ba8: 18e3 adds r3, r4, r3 + 8002baa: 2280 movs r2, #128 ; 0x80 + 8002bac: 00d2 lsls r2, r2, #3 + 8002bae: 4694 mov ip, r2 + 8002bb0: 4463 add r3, ip + 8002bb2: 001c movs r4, r3 + 8002bb4: 683b ldr r3, [r7, #0] + 8002bb6: 891b ldrh r3, [r3, #8] + 8002bb8: 085b lsrs r3, r3, #1 + 8002bba: b29b uxth r3, r3 + 8002bbc: 18db adds r3, r3, r3 + 8002bbe: b29b uxth r3, r3 + 8002bc0: 8023 strh r3, [r4, #0] + 8002bc2: 687c ldr r4, [r7, #4] + 8002bc4: 687b ldr r3, [r7, #4] + 8002bc6: 2250 movs r2, #80 ; 0x50 + 8002bc8: 5a9b ldrh r3, [r3, r2] + 8002bca: b29b uxth r3, r3 + 8002bcc: 18e4 adds r4, r4, r3 + 8002bce: 683b ldr r3, [r7, #0] + 8002bd0: 781b ldrb r3, [r3, #0] + 8002bd2: 00db lsls r3, r3, #3 + 8002bd4: 18e3 adds r3, r4, r3 + 8002bd6: 4a95 ldr r2, [pc, #596] ; (8002e2c ) + 8002bd8: 4694 mov ip, r2 + 8002bda: 4463 add r3, ip + 8002bdc: 001c movs r4, r3 + 8002bde: 683b ldr r3, [r7, #0] + 8002be0: 895b ldrh r3, [r3, #10] + 8002be2: 085b lsrs r3, r3, #1 + 8002be4: b29b uxth r3, r3 + 8002be6: 18db adds r3, r3, r3 + 8002be8: b29b uxth r3, r3 + 8002bea: 8023 strh r3, [r4, #0] + + if (ep->is_in == 0U) + 8002bec: 683b ldr r3, [r7, #0] + 8002bee: 785b ldrb r3, [r3, #1] + 8002bf0: 2b00 cmp r3, #0 + 8002bf2: d000 beq.n 8002bf6 + 8002bf4: e07e b.n 8002cf4 + { + /* Clear the data toggle bits for the endpoint IN/OUT */ + PCD_CLEAR_RX_DTOG(USBx, ep->num); + 8002bf6: 687a ldr r2, [r7, #4] + 8002bf8: 683b ldr r3, [r7, #0] + 8002bfa: 781b ldrb r3, [r3, #0] + 8002bfc: 009b lsls r3, r3, #2 + 8002bfe: 18d3 adds r3, r2, r3 + 8002c00: 881b ldrh r3, [r3, #0] + 8002c02: b29c uxth r4, r3 + 8002c04: 0022 movs r2, r4 + 8002c06: 2380 movs r3, #128 ; 0x80 + 8002c08: 01db lsls r3, r3, #7 + 8002c0a: 4013 ands r3, r2 + 8002c0c: d012 beq.n 8002c34 + 8002c0e: 687a ldr r2, [r7, #4] + 8002c10: 683b ldr r3, [r7, #0] + 8002c12: 781b ldrb r3, [r3, #0] + 8002c14: 009b lsls r3, r3, #2 + 8002c16: 18d3 adds r3, r2, r3 + 8002c18: 881b ldrh r3, [r3, #0] + 8002c1a: b29b uxth r3, r3 + 8002c1c: 4a81 ldr r2, [pc, #516] ; (8002e24 ) + 8002c1e: 4013 ands r3, r2 + 8002c20: b29c uxth r4, r3 + 8002c22: 687a ldr r2, [r7, #4] + 8002c24: 683b ldr r3, [r7, #0] + 8002c26: 781b ldrb r3, [r3, #0] + 8002c28: 009b lsls r3, r3, #2 + 8002c2a: 18d3 adds r3, r2, r3 + 8002c2c: 4a80 ldr r2, [pc, #512] ; (8002e30 ) + 8002c2e: 4322 orrs r2, r4 + 8002c30: b292 uxth r2, r2 + 8002c32: 801a strh r2, [r3, #0] + PCD_CLEAR_TX_DTOG(USBx, ep->num); + 8002c34: 687a ldr r2, [r7, #4] + 8002c36: 683b ldr r3, [r7, #0] + 8002c38: 781b ldrb r3, [r3, #0] + 8002c3a: 009b lsls r3, r3, #2 + 8002c3c: 18d3 adds r3, r2, r3 + 8002c3e: 881b ldrh r3, [r3, #0] + 8002c40: b29c uxth r4, r3 + 8002c42: 0022 movs r2, r4 + 8002c44: 2340 movs r3, #64 ; 0x40 + 8002c46: 4013 ands r3, r2 + 8002c48: d012 beq.n 8002c70 + 8002c4a: 687a ldr r2, [r7, #4] + 8002c4c: 683b ldr r3, [r7, #0] + 8002c4e: 781b ldrb r3, [r3, #0] + 8002c50: 009b lsls r3, r3, #2 + 8002c52: 18d3 adds r3, r2, r3 + 8002c54: 881b ldrh r3, [r3, #0] + 8002c56: b29b uxth r3, r3 + 8002c58: 4a72 ldr r2, [pc, #456] ; (8002e24 ) + 8002c5a: 4013 ands r3, r2 + 8002c5c: b29c uxth r4, r3 + 8002c5e: 687a ldr r2, [r7, #4] + 8002c60: 683b ldr r3, [r7, #0] + 8002c62: 781b ldrb r3, [r3, #0] + 8002c64: 009b lsls r3, r3, #2 + 8002c66: 18d3 adds r3, r2, r3 + 8002c68: 4a72 ldr r2, [pc, #456] ; (8002e34 ) + 8002c6a: 4322 orrs r2, r4 + 8002c6c: b292 uxth r2, r2 + 8002c6e: 801a strh r2, [r3, #0] + + /* Reset value of the data toggle bits for the endpoint out */ + PCD_TX_DTOG(USBx, ep->num); + 8002c70: 687a ldr r2, [r7, #4] + 8002c72: 683b ldr r3, [r7, #0] + 8002c74: 781b ldrb r3, [r3, #0] + 8002c76: 009b lsls r3, r3, #2 + 8002c78: 18d3 adds r3, r2, r3 + 8002c7a: 881b ldrh r3, [r3, #0] + 8002c7c: b29b uxth r3, r3 + 8002c7e: 4a69 ldr r2, [pc, #420] ; (8002e24 ) + 8002c80: 4013 ands r3, r2 + 8002c82: b29c uxth r4, r3 + 8002c84: 687a ldr r2, [r7, #4] + 8002c86: 683b ldr r3, [r7, #0] + 8002c88: 781b ldrb r3, [r3, #0] + 8002c8a: 009b lsls r3, r3, #2 + 8002c8c: 18d3 adds r3, r2, r3 + 8002c8e: 4a69 ldr r2, [pc, #420] ; (8002e34 ) + 8002c90: 4322 orrs r2, r4 + 8002c92: b292 uxth r2, r2 + 8002c94: 801a strh r2, [r3, #0] + + PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_VALID); + 8002c96: 687a ldr r2, [r7, #4] + 8002c98: 683b ldr r3, [r7, #0] + 8002c9a: 781b ldrb r3, [r3, #0] + 8002c9c: 009b lsls r3, r3, #2 + 8002c9e: 18d3 adds r3, r2, r3 + 8002ca0: 881b ldrh r3, [r3, #0] + 8002ca2: b29b uxth r3, r3 + 8002ca4: 4a64 ldr r2, [pc, #400] ; (8002e38 ) + 8002ca6: 4013 ands r3, r2 + 8002ca8: b29c uxth r4, r3 + 8002caa: 2380 movs r3, #128 ; 0x80 + 8002cac: 015b lsls r3, r3, #5 + 8002cae: 4063 eors r3, r4 + 8002cb0: b29c uxth r4, r3 + 8002cb2: 2380 movs r3, #128 ; 0x80 + 8002cb4: 019b lsls r3, r3, #6 + 8002cb6: 4063 eors r3, r4 + 8002cb8: b29c uxth r4, r3 + 8002cba: 687a ldr r2, [r7, #4] + 8002cbc: 683b ldr r3, [r7, #0] + 8002cbe: 781b ldrb r3, [r3, #0] + 8002cc0: 009b lsls r3, r3, #2 + 8002cc2: 18d3 adds r3, r2, r3 + 8002cc4: 4a5d ldr r2, [pc, #372] ; (8002e3c ) + 8002cc6: 4322 orrs r2, r4 + 8002cc8: b292 uxth r2, r2 + 8002cca: 801a strh r2, [r3, #0] + PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS); + 8002ccc: 687a ldr r2, [r7, #4] + 8002cce: 683b ldr r3, [r7, #0] + 8002cd0: 781b ldrb r3, [r3, #0] + 8002cd2: 009b lsls r3, r3, #2 + 8002cd4: 18d3 adds r3, r2, r3 + 8002cd6: 881b ldrh r3, [r3, #0] + 8002cd8: b29b uxth r3, r3 + 8002cda: 4a59 ldr r2, [pc, #356] ; (8002e40 ) + 8002cdc: 4013 ands r3, r2 + 8002cde: b29c uxth r4, r3 + 8002ce0: 687a ldr r2, [r7, #4] + 8002ce2: 683b ldr r3, [r7, #0] + 8002ce4: 781b ldrb r3, [r3, #0] + 8002ce6: 009b lsls r3, r3, #2 + 8002ce8: 18d3 adds r3, r2, r3 + 8002cea: 4a54 ldr r2, [pc, #336] ; (8002e3c ) + 8002cec: 4322 orrs r2, r4 + 8002cee: b292 uxth r2, r2 + 8002cf0: 801a strh r2, [r3, #0] + 8002cf2: e090 b.n 8002e16 + } + else + { + /* Clear the data toggle bits for the endpoint IN/OUT */ + PCD_CLEAR_RX_DTOG(USBx, ep->num); + 8002cf4: 687a ldr r2, [r7, #4] + 8002cf6: 683b ldr r3, [r7, #0] + 8002cf8: 781b ldrb r3, [r3, #0] + 8002cfa: 009b lsls r3, r3, #2 + 8002cfc: 18d3 adds r3, r2, r3 + 8002cfe: 881b ldrh r3, [r3, #0] + 8002d00: b29c uxth r4, r3 + 8002d02: 0022 movs r2, r4 + 8002d04: 2380 movs r3, #128 ; 0x80 + 8002d06: 01db lsls r3, r3, #7 + 8002d08: 4013 ands r3, r2 + 8002d0a: d012 beq.n 8002d32 + 8002d0c: 687a ldr r2, [r7, #4] + 8002d0e: 683b ldr r3, [r7, #0] + 8002d10: 781b ldrb r3, [r3, #0] + 8002d12: 009b lsls r3, r3, #2 + 8002d14: 18d3 adds r3, r2, r3 + 8002d16: 881b ldrh r3, [r3, #0] + 8002d18: b29b uxth r3, r3 + 8002d1a: 4a42 ldr r2, [pc, #264] ; (8002e24 ) + 8002d1c: 4013 ands r3, r2 + 8002d1e: b29c uxth r4, r3 + 8002d20: 687a ldr r2, [r7, #4] + 8002d22: 683b ldr r3, [r7, #0] + 8002d24: 781b ldrb r3, [r3, #0] + 8002d26: 009b lsls r3, r3, #2 + 8002d28: 18d3 adds r3, r2, r3 + 8002d2a: 4a41 ldr r2, [pc, #260] ; (8002e30 ) + 8002d2c: 4322 orrs r2, r4 + 8002d2e: b292 uxth r2, r2 + 8002d30: 801a strh r2, [r3, #0] + PCD_CLEAR_TX_DTOG(USBx, ep->num); + 8002d32: 687a ldr r2, [r7, #4] + 8002d34: 683b ldr r3, [r7, #0] + 8002d36: 781b ldrb r3, [r3, #0] + 8002d38: 009b lsls r3, r3, #2 + 8002d3a: 18d3 adds r3, r2, r3 + 8002d3c: 881b ldrh r3, [r3, #0] + 8002d3e: b29c uxth r4, r3 + 8002d40: 0022 movs r2, r4 + 8002d42: 2340 movs r3, #64 ; 0x40 + 8002d44: 4013 ands r3, r2 + 8002d46: d012 beq.n 8002d6e + 8002d48: 687a ldr r2, [r7, #4] + 8002d4a: 683b ldr r3, [r7, #0] + 8002d4c: 781b ldrb r3, [r3, #0] + 8002d4e: 009b lsls r3, r3, #2 + 8002d50: 18d3 adds r3, r2, r3 + 8002d52: 881b ldrh r3, [r3, #0] + 8002d54: b29b uxth r3, r3 + 8002d56: 4a33 ldr r2, [pc, #204] ; (8002e24 ) + 8002d58: 4013 ands r3, r2 + 8002d5a: b29c uxth r4, r3 + 8002d5c: 687a ldr r2, [r7, #4] + 8002d5e: 683b ldr r3, [r7, #0] + 8002d60: 781b ldrb r3, [r3, #0] + 8002d62: 009b lsls r3, r3, #2 + 8002d64: 18d3 adds r3, r2, r3 + 8002d66: 4a33 ldr r2, [pc, #204] ; (8002e34 ) + 8002d68: 4322 orrs r2, r4 + 8002d6a: b292 uxth r2, r2 + 8002d6c: 801a strh r2, [r3, #0] + PCD_RX_DTOG(USBx, ep->num); + 8002d6e: 687a ldr r2, [r7, #4] + 8002d70: 683b ldr r3, [r7, #0] + 8002d72: 781b ldrb r3, [r3, #0] + 8002d74: 009b lsls r3, r3, #2 + 8002d76: 18d3 adds r3, r2, r3 + 8002d78: 881b ldrh r3, [r3, #0] + 8002d7a: b29b uxth r3, r3 + 8002d7c: 4a29 ldr r2, [pc, #164] ; (8002e24 ) + 8002d7e: 4013 ands r3, r2 + 8002d80: b29c uxth r4, r3 + 8002d82: 687a ldr r2, [r7, #4] + 8002d84: 683b ldr r3, [r7, #0] + 8002d86: 781b ldrb r3, [r3, #0] + 8002d88: 009b lsls r3, r3, #2 + 8002d8a: 18d3 adds r3, r2, r3 + 8002d8c: 4a28 ldr r2, [pc, #160] ; (8002e30 ) + 8002d8e: 4322 orrs r2, r4 + 8002d90: b292 uxth r2, r2 + 8002d92: 801a strh r2, [r3, #0] + + if (ep->type != EP_TYPE_ISOC) + 8002d94: 683b ldr r3, [r7, #0] + 8002d96: 78db ldrb r3, [r3, #3] + 8002d98: 2b01 cmp r3, #1 + 8002d9a: d016 beq.n 8002dca + { + /* Configure NAK status for the Endpoint */ + PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_NAK); + 8002d9c: 687a ldr r2, [r7, #4] + 8002d9e: 683b ldr r3, [r7, #0] + 8002da0: 781b ldrb r3, [r3, #0] + 8002da2: 009b lsls r3, r3, #2 + 8002da4: 18d3 adds r3, r2, r3 + 8002da6: 881b ldrh r3, [r3, #0] + 8002da8: b29b uxth r3, r3 + 8002daa: 4a25 ldr r2, [pc, #148] ; (8002e40 ) + 8002dac: 4013 ands r3, r2 + 8002dae: b29c uxth r4, r3 + 8002db0: 2320 movs r3, #32 + 8002db2: 4063 eors r3, r4 + 8002db4: b29c uxth r4, r3 + 8002db6: 687a ldr r2, [r7, #4] + 8002db8: 683b ldr r3, [r7, #0] + 8002dba: 781b ldrb r3, [r3, #0] + 8002dbc: 009b lsls r3, r3, #2 + 8002dbe: 18d3 adds r3, r2, r3 + 8002dc0: 4a1e ldr r2, [pc, #120] ; (8002e3c ) + 8002dc2: 4322 orrs r2, r4 + 8002dc4: b292 uxth r2, r2 + 8002dc6: 801a strh r2, [r3, #0] + 8002dc8: e012 b.n 8002df0 + } + else + { + /* Configure TX Endpoint to disabled state */ + PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS); + 8002dca: 687a ldr r2, [r7, #4] + 8002dcc: 683b ldr r3, [r7, #0] + 8002dce: 781b ldrb r3, [r3, #0] + 8002dd0: 009b lsls r3, r3, #2 + 8002dd2: 18d3 adds r3, r2, r3 + 8002dd4: 881b ldrh r3, [r3, #0] + 8002dd6: b29b uxth r3, r3 + 8002dd8: 4a19 ldr r2, [pc, #100] ; (8002e40 ) + 8002dda: 4013 ands r3, r2 + 8002ddc: b29c uxth r4, r3 + 8002dde: 687a ldr r2, [r7, #4] + 8002de0: 683b ldr r3, [r7, #0] + 8002de2: 781b ldrb r3, [r3, #0] + 8002de4: 009b lsls r3, r3, #2 + 8002de6: 18d3 adds r3, r2, r3 + 8002de8: 4a14 ldr r2, [pc, #80] ; (8002e3c ) + 8002dea: 4322 orrs r2, r4 + 8002dec: b292 uxth r2, r2 + 8002dee: 801a strh r2, [r3, #0] + } + + PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_DIS); + 8002df0: 687a ldr r2, [r7, #4] + 8002df2: 683b ldr r3, [r7, #0] + 8002df4: 781b ldrb r3, [r3, #0] + 8002df6: 009b lsls r3, r3, #2 + 8002df8: 18d3 adds r3, r2, r3 + 8002dfa: 881b ldrh r3, [r3, #0] + 8002dfc: b29b uxth r3, r3 + 8002dfe: 4a0e ldr r2, [pc, #56] ; (8002e38 ) + 8002e00: 4013 ands r3, r2 + 8002e02: b29c uxth r4, r3 + 8002e04: 687a ldr r2, [r7, #4] + 8002e06: 683b ldr r3, [r7, #0] + 8002e08: 781b ldrb r3, [r3, #0] + 8002e0a: 009b lsls r3, r3, #2 + 8002e0c: 18d3 adds r3, r2, r3 + 8002e0e: 4a0b ldr r2, [pc, #44] ; (8002e3c ) + 8002e10: 4322 orrs r2, r4 + 8002e12: b292 uxth r2, r2 + 8002e14: 801a strh r2, [r3, #0] + } + } + + return ret; + 8002e16: 2317 movs r3, #23 + 8002e18: 18fb adds r3, r7, r3 + 8002e1a: 781b ldrb r3, [r3, #0] +} + 8002e1c: 0018 movs r0, r3 + 8002e1e: 46bd mov sp, r7 + 8002e20: b007 add sp, #28 + 8002e22: bd90 pop {r4, r7, pc} + 8002e24: ffff8f8f .word 0xffff8f8f + 8002e28: ffff8180 .word 0xffff8180 + 8002e2c: 00000404 .word 0x00000404 + 8002e30: ffffc080 .word 0xffffc080 + 8002e34: ffff80c0 .word 0xffff80c0 + 8002e38: ffffbf8f .word 0xffffbf8f + 8002e3c: ffff8080 .word 0xffff8080 + 8002e40: ffff8fbf .word 0xffff8fbf + +08002e44 : + * @param USBx : Selected device + * @param ep: pointer to endpoint structure + * @retval HAL status + */ +HAL_StatusTypeDef USB_DeactivateEndpoint(USB_TypeDef *USBx, USB_EPTypeDef *ep) +{ + 8002e44: b590 push {r4, r7, lr} + 8002e46: b083 sub sp, #12 + 8002e48: af00 add r7, sp, #0 + 8002e4a: 6078 str r0, [r7, #4] + 8002e4c: 6039 str r1, [r7, #0] + if (ep->doublebuffer == 0U) + 8002e4e: 683b ldr r3, [r7, #0] + 8002e50: 7b1b ldrb r3, [r3, #12] + 8002e52: 2b00 cmp r3, #0 + 8002e54: d168 bne.n 8002f28 + { + if (ep->is_in != 0U) + 8002e56: 683b ldr r3, [r7, #0] + 8002e58: 785b ldrb r3, [r3, #1] + 8002e5a: 2b00 cmp r3, #0 + 8002e5c: d031 beq.n 8002ec2 + { + PCD_CLEAR_TX_DTOG(USBx, ep->num); + 8002e5e: 687a ldr r2, [r7, #4] + 8002e60: 683b ldr r3, [r7, #0] + 8002e62: 781b ldrb r3, [r3, #0] + 8002e64: 009b lsls r3, r3, #2 + 8002e66: 18d3 adds r3, r2, r3 + 8002e68: 881b ldrh r3, [r3, #0] + 8002e6a: b29c uxth r4, r3 + 8002e6c: 0022 movs r2, r4 + 8002e6e: 2340 movs r3, #64 ; 0x40 + 8002e70: 4013 ands r3, r2 + 8002e72: d012 beq.n 8002e9a + 8002e74: 687a ldr r2, [r7, #4] + 8002e76: 683b ldr r3, [r7, #0] + 8002e78: 781b ldrb r3, [r3, #0] + 8002e7a: 009b lsls r3, r3, #2 + 8002e7c: 18d3 adds r3, r2, r3 + 8002e7e: 881b ldrh r3, [r3, #0] + 8002e80: b29b uxth r3, r3 + 8002e82: 4aa5 ldr r2, [pc, #660] ; (8003118 ) + 8002e84: 4013 ands r3, r2 + 8002e86: b29c uxth r4, r3 + 8002e88: 687a ldr r2, [r7, #4] + 8002e8a: 683b ldr r3, [r7, #0] + 8002e8c: 781b ldrb r3, [r3, #0] + 8002e8e: 009b lsls r3, r3, #2 + 8002e90: 18d3 adds r3, r2, r3 + 8002e92: 4aa2 ldr r2, [pc, #648] ; (800311c ) + 8002e94: 4322 orrs r2, r4 + 8002e96: b292 uxth r2, r2 + 8002e98: 801a strh r2, [r3, #0] + /* Configure DISABLE status for the Endpoint*/ + PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS); + 8002e9a: 687a ldr r2, [r7, #4] + 8002e9c: 683b ldr r3, [r7, #0] + 8002e9e: 781b ldrb r3, [r3, #0] + 8002ea0: 009b lsls r3, r3, #2 + 8002ea2: 18d3 adds r3, r2, r3 + 8002ea4: 881b ldrh r3, [r3, #0] + 8002ea6: b29b uxth r3, r3 + 8002ea8: 4a9d ldr r2, [pc, #628] ; (8003120 ) + 8002eaa: 4013 ands r3, r2 + 8002eac: b29c uxth r4, r3 + 8002eae: 687a ldr r2, [r7, #4] + 8002eb0: 683b ldr r3, [r7, #0] + 8002eb2: 781b ldrb r3, [r3, #0] + 8002eb4: 009b lsls r3, r3, #2 + 8002eb6: 18d3 adds r3, r2, r3 + 8002eb8: 4a9a ldr r2, [pc, #616] ; (8003124 ) + 8002eba: 4322 orrs r2, r4 + 8002ebc: b292 uxth r2, r2 + 8002ebe: 801a strh r2, [r3, #0] + 8002ec0: e124 b.n 800310c + } + else + { + PCD_CLEAR_RX_DTOG(USBx, ep->num); + 8002ec2: 687a ldr r2, [r7, #4] + 8002ec4: 683b ldr r3, [r7, #0] + 8002ec6: 781b ldrb r3, [r3, #0] + 8002ec8: 009b lsls r3, r3, #2 + 8002eca: 18d3 adds r3, r2, r3 + 8002ecc: 881b ldrh r3, [r3, #0] + 8002ece: b29c uxth r4, r3 + 8002ed0: 0022 movs r2, r4 + 8002ed2: 2380 movs r3, #128 ; 0x80 + 8002ed4: 01db lsls r3, r3, #7 + 8002ed6: 4013 ands r3, r2 + 8002ed8: d012 beq.n 8002f00 + 8002eda: 687a ldr r2, [r7, #4] + 8002edc: 683b ldr r3, [r7, #0] + 8002ede: 781b ldrb r3, [r3, #0] + 8002ee0: 009b lsls r3, r3, #2 + 8002ee2: 18d3 adds r3, r2, r3 + 8002ee4: 881b ldrh r3, [r3, #0] + 8002ee6: b29b uxth r3, r3 + 8002ee8: 4a8b ldr r2, [pc, #556] ; (8003118 ) + 8002eea: 4013 ands r3, r2 + 8002eec: b29c uxth r4, r3 + 8002eee: 687a ldr r2, [r7, #4] + 8002ef0: 683b ldr r3, [r7, #0] + 8002ef2: 781b ldrb r3, [r3, #0] + 8002ef4: 009b lsls r3, r3, #2 + 8002ef6: 18d3 adds r3, r2, r3 + 8002ef8: 4a8b ldr r2, [pc, #556] ; (8003128 ) + 8002efa: 4322 orrs r2, r4 + 8002efc: b292 uxth r2, r2 + 8002efe: 801a strh r2, [r3, #0] + /* Configure DISABLE status for the Endpoint*/ + PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_DIS); + 8002f00: 687a ldr r2, [r7, #4] + 8002f02: 683b ldr r3, [r7, #0] + 8002f04: 781b ldrb r3, [r3, #0] + 8002f06: 009b lsls r3, r3, #2 + 8002f08: 18d3 adds r3, r2, r3 + 8002f0a: 881b ldrh r3, [r3, #0] + 8002f0c: b29b uxth r3, r3 + 8002f0e: 4a87 ldr r2, [pc, #540] ; (800312c ) + 8002f10: 4013 ands r3, r2 + 8002f12: b29c uxth r4, r3 + 8002f14: 687a ldr r2, [r7, #4] + 8002f16: 683b ldr r3, [r7, #0] + 8002f18: 781b ldrb r3, [r3, #0] + 8002f1a: 009b lsls r3, r3, #2 + 8002f1c: 18d3 adds r3, r2, r3 + 8002f1e: 4a81 ldr r2, [pc, #516] ; (8003124 ) + 8002f20: 4322 orrs r2, r4 + 8002f22: b292 uxth r2, r2 + 8002f24: 801a strh r2, [r3, #0] + 8002f26: e0f1 b.n 800310c + } + } + /*Double Buffer*/ + else + { + if (ep->is_in == 0U) + 8002f28: 683b ldr r3, [r7, #0] + 8002f2a: 785b ldrb r3, [r3, #1] + 8002f2c: 2b00 cmp r3, #0 + 8002f2e: d000 beq.n 8002f32 + 8002f30: e076 b.n 8003020 + { + /* Clear the data toggle bits for the endpoint IN/OUT*/ + PCD_CLEAR_RX_DTOG(USBx, ep->num); + 8002f32: 687a ldr r2, [r7, #4] + 8002f34: 683b ldr r3, [r7, #0] + 8002f36: 781b ldrb r3, [r3, #0] + 8002f38: 009b lsls r3, r3, #2 + 8002f3a: 18d3 adds r3, r2, r3 + 8002f3c: 881b ldrh r3, [r3, #0] + 8002f3e: b29c uxth r4, r3 + 8002f40: 0022 movs r2, r4 + 8002f42: 2380 movs r3, #128 ; 0x80 + 8002f44: 01db lsls r3, r3, #7 + 8002f46: 4013 ands r3, r2 + 8002f48: d012 beq.n 8002f70 + 8002f4a: 687a ldr r2, [r7, #4] + 8002f4c: 683b ldr r3, [r7, #0] + 8002f4e: 781b ldrb r3, [r3, #0] + 8002f50: 009b lsls r3, r3, #2 + 8002f52: 18d3 adds r3, r2, r3 + 8002f54: 881b ldrh r3, [r3, #0] + 8002f56: b29b uxth r3, r3 + 8002f58: 4a6f ldr r2, [pc, #444] ; (8003118 ) + 8002f5a: 4013 ands r3, r2 + 8002f5c: b29c uxth r4, r3 + 8002f5e: 687a ldr r2, [r7, #4] + 8002f60: 683b ldr r3, [r7, #0] + 8002f62: 781b ldrb r3, [r3, #0] + 8002f64: 009b lsls r3, r3, #2 + 8002f66: 18d3 adds r3, r2, r3 + 8002f68: 4a6f ldr r2, [pc, #444] ; (8003128 ) + 8002f6a: 4322 orrs r2, r4 + 8002f6c: b292 uxth r2, r2 + 8002f6e: 801a strh r2, [r3, #0] + PCD_CLEAR_TX_DTOG(USBx, ep->num); + 8002f70: 687a ldr r2, [r7, #4] + 8002f72: 683b ldr r3, [r7, #0] + 8002f74: 781b ldrb r3, [r3, #0] + 8002f76: 009b lsls r3, r3, #2 + 8002f78: 18d3 adds r3, r2, r3 + 8002f7a: 881b ldrh r3, [r3, #0] + 8002f7c: b29c uxth r4, r3 + 8002f7e: 0022 movs r2, r4 + 8002f80: 2340 movs r3, #64 ; 0x40 + 8002f82: 4013 ands r3, r2 + 8002f84: d012 beq.n 8002fac + 8002f86: 687a ldr r2, [r7, #4] + 8002f88: 683b ldr r3, [r7, #0] + 8002f8a: 781b ldrb r3, [r3, #0] + 8002f8c: 009b lsls r3, r3, #2 + 8002f8e: 18d3 adds r3, r2, r3 + 8002f90: 881b ldrh r3, [r3, #0] + 8002f92: b29b uxth r3, r3 + 8002f94: 4a60 ldr r2, [pc, #384] ; (8003118 ) + 8002f96: 4013 ands r3, r2 + 8002f98: b29c uxth r4, r3 + 8002f9a: 687a ldr r2, [r7, #4] + 8002f9c: 683b ldr r3, [r7, #0] + 8002f9e: 781b ldrb r3, [r3, #0] + 8002fa0: 009b lsls r3, r3, #2 + 8002fa2: 18d3 adds r3, r2, r3 + 8002fa4: 4a5d ldr r2, [pc, #372] ; (800311c ) + 8002fa6: 4322 orrs r2, r4 + 8002fa8: b292 uxth r2, r2 + 8002faa: 801a strh r2, [r3, #0] + + /* Reset value of the data toggle bits for the endpoint out*/ + PCD_TX_DTOG(USBx, ep->num); + 8002fac: 687a ldr r2, [r7, #4] + 8002fae: 683b ldr r3, [r7, #0] + 8002fb0: 781b ldrb r3, [r3, #0] + 8002fb2: 009b lsls r3, r3, #2 + 8002fb4: 18d3 adds r3, r2, r3 + 8002fb6: 881b ldrh r3, [r3, #0] + 8002fb8: b29b uxth r3, r3 + 8002fba: 4a57 ldr r2, [pc, #348] ; (8003118 ) + 8002fbc: 4013 ands r3, r2 + 8002fbe: b29c uxth r4, r3 + 8002fc0: 687a ldr r2, [r7, #4] + 8002fc2: 683b ldr r3, [r7, #0] + 8002fc4: 781b ldrb r3, [r3, #0] + 8002fc6: 009b lsls r3, r3, #2 + 8002fc8: 18d3 adds r3, r2, r3 + 8002fca: 4a54 ldr r2, [pc, #336] ; (800311c ) + 8002fcc: 4322 orrs r2, r4 + 8002fce: b292 uxth r2, r2 + 8002fd0: 801a strh r2, [r3, #0] + + PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_DIS); + 8002fd2: 687a ldr r2, [r7, #4] + 8002fd4: 683b ldr r3, [r7, #0] + 8002fd6: 781b ldrb r3, [r3, #0] + 8002fd8: 009b lsls r3, r3, #2 + 8002fda: 18d3 adds r3, r2, r3 + 8002fdc: 881b ldrh r3, [r3, #0] + 8002fde: b29b uxth r3, r3 + 8002fe0: 4a52 ldr r2, [pc, #328] ; (800312c ) + 8002fe2: 4013 ands r3, r2 + 8002fe4: b29c uxth r4, r3 + 8002fe6: 687a ldr r2, [r7, #4] + 8002fe8: 683b ldr r3, [r7, #0] + 8002fea: 781b ldrb r3, [r3, #0] + 8002fec: 009b lsls r3, r3, #2 + 8002fee: 18d3 adds r3, r2, r3 + 8002ff0: 4a4c ldr r2, [pc, #304] ; (8003124 ) + 8002ff2: 4322 orrs r2, r4 + 8002ff4: b292 uxth r2, r2 + 8002ff6: 801a strh r2, [r3, #0] + PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS); + 8002ff8: 687a ldr r2, [r7, #4] + 8002ffa: 683b ldr r3, [r7, #0] + 8002ffc: 781b ldrb r3, [r3, #0] + 8002ffe: 009b lsls r3, r3, #2 + 8003000: 18d3 adds r3, r2, r3 + 8003002: 881b ldrh r3, [r3, #0] + 8003004: b29b uxth r3, r3 + 8003006: 4a46 ldr r2, [pc, #280] ; (8003120 ) + 8003008: 4013 ands r3, r2 + 800300a: b29c uxth r4, r3 + 800300c: 687a ldr r2, [r7, #4] + 800300e: 683b ldr r3, [r7, #0] + 8003010: 781b ldrb r3, [r3, #0] + 8003012: 009b lsls r3, r3, #2 + 8003014: 18d3 adds r3, r2, r3 + 8003016: 4a43 ldr r2, [pc, #268] ; (8003124 ) + 8003018: 4322 orrs r2, r4 + 800301a: b292 uxth r2, r2 + 800301c: 801a strh r2, [r3, #0] + 800301e: e075 b.n 800310c + } + else + { + /* Clear the data toggle bits for the endpoint IN/OUT*/ + PCD_CLEAR_RX_DTOG(USBx, ep->num); + 8003020: 687a ldr r2, [r7, #4] + 8003022: 683b ldr r3, [r7, #0] + 8003024: 781b ldrb r3, [r3, #0] + 8003026: 009b lsls r3, r3, #2 + 8003028: 18d3 adds r3, r2, r3 + 800302a: 881b ldrh r3, [r3, #0] + 800302c: b29c uxth r4, r3 + 800302e: 0022 movs r2, r4 + 8003030: 2380 movs r3, #128 ; 0x80 + 8003032: 01db lsls r3, r3, #7 + 8003034: 4013 ands r3, r2 + 8003036: d012 beq.n 800305e + 8003038: 687a ldr r2, [r7, #4] + 800303a: 683b ldr r3, [r7, #0] + 800303c: 781b ldrb r3, [r3, #0] + 800303e: 009b lsls r3, r3, #2 + 8003040: 18d3 adds r3, r2, r3 + 8003042: 881b ldrh r3, [r3, #0] + 8003044: b29b uxth r3, r3 + 8003046: 4a34 ldr r2, [pc, #208] ; (8003118 ) + 8003048: 4013 ands r3, r2 + 800304a: b29c uxth r4, r3 + 800304c: 687a ldr r2, [r7, #4] + 800304e: 683b ldr r3, [r7, #0] + 8003050: 781b ldrb r3, [r3, #0] + 8003052: 009b lsls r3, r3, #2 + 8003054: 18d3 adds r3, r2, r3 + 8003056: 4a34 ldr r2, [pc, #208] ; (8003128 ) + 8003058: 4322 orrs r2, r4 + 800305a: b292 uxth r2, r2 + 800305c: 801a strh r2, [r3, #0] + PCD_CLEAR_TX_DTOG(USBx, ep->num); + 800305e: 687a ldr r2, [r7, #4] + 8003060: 683b ldr r3, [r7, #0] + 8003062: 781b ldrb r3, [r3, #0] + 8003064: 009b lsls r3, r3, #2 + 8003066: 18d3 adds r3, r2, r3 + 8003068: 881b ldrh r3, [r3, #0] + 800306a: b29c uxth r4, r3 + 800306c: 0022 movs r2, r4 + 800306e: 2340 movs r3, #64 ; 0x40 + 8003070: 4013 ands r3, r2 + 8003072: d012 beq.n 800309a + 8003074: 687a ldr r2, [r7, #4] + 8003076: 683b ldr r3, [r7, #0] + 8003078: 781b ldrb r3, [r3, #0] + 800307a: 009b lsls r3, r3, #2 + 800307c: 18d3 adds r3, r2, r3 + 800307e: 881b ldrh r3, [r3, #0] + 8003080: b29b uxth r3, r3 + 8003082: 4a25 ldr r2, [pc, #148] ; (8003118 ) + 8003084: 4013 ands r3, r2 + 8003086: b29c uxth r4, r3 + 8003088: 687a ldr r2, [r7, #4] + 800308a: 683b ldr r3, [r7, #0] + 800308c: 781b ldrb r3, [r3, #0] + 800308e: 009b lsls r3, r3, #2 + 8003090: 18d3 adds r3, r2, r3 + 8003092: 4a22 ldr r2, [pc, #136] ; (800311c ) + 8003094: 4322 orrs r2, r4 + 8003096: b292 uxth r2, r2 + 8003098: 801a strh r2, [r3, #0] + PCD_RX_DTOG(USBx, ep->num); + 800309a: 687a ldr r2, [r7, #4] + 800309c: 683b ldr r3, [r7, #0] + 800309e: 781b ldrb r3, [r3, #0] + 80030a0: 009b lsls r3, r3, #2 + 80030a2: 18d3 adds r3, r2, r3 + 80030a4: 881b ldrh r3, [r3, #0] + 80030a6: b29b uxth r3, r3 + 80030a8: 4a1b ldr r2, [pc, #108] ; (8003118 ) + 80030aa: 4013 ands r3, r2 + 80030ac: b29c uxth r4, r3 + 80030ae: 687a ldr r2, [r7, #4] + 80030b0: 683b ldr r3, [r7, #0] + 80030b2: 781b ldrb r3, [r3, #0] + 80030b4: 009b lsls r3, r3, #2 + 80030b6: 18d3 adds r3, r2, r3 + 80030b8: 4a1b ldr r2, [pc, #108] ; (8003128 ) + 80030ba: 4322 orrs r2, r4 + 80030bc: b292 uxth r2, r2 + 80030be: 801a strh r2, [r3, #0] + /* Configure DISABLE status for the Endpoint*/ + PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS); + 80030c0: 687a ldr r2, [r7, #4] + 80030c2: 683b ldr r3, [r7, #0] + 80030c4: 781b ldrb r3, [r3, #0] + 80030c6: 009b lsls r3, r3, #2 + 80030c8: 18d3 adds r3, r2, r3 + 80030ca: 881b ldrh r3, [r3, #0] + 80030cc: b29b uxth r3, r3 + 80030ce: 4a14 ldr r2, [pc, #80] ; (8003120 ) + 80030d0: 4013 ands r3, r2 + 80030d2: b29c uxth r4, r3 + 80030d4: 687a ldr r2, [r7, #4] + 80030d6: 683b ldr r3, [r7, #0] + 80030d8: 781b ldrb r3, [r3, #0] + 80030da: 009b lsls r3, r3, #2 + 80030dc: 18d3 adds r3, r2, r3 + 80030de: 4a11 ldr r2, [pc, #68] ; (8003124 ) + 80030e0: 4322 orrs r2, r4 + 80030e2: b292 uxth r2, r2 + 80030e4: 801a strh r2, [r3, #0] + PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_DIS); + 80030e6: 687a ldr r2, [r7, #4] + 80030e8: 683b ldr r3, [r7, #0] + 80030ea: 781b ldrb r3, [r3, #0] + 80030ec: 009b lsls r3, r3, #2 + 80030ee: 18d3 adds r3, r2, r3 + 80030f0: 881b ldrh r3, [r3, #0] + 80030f2: b29b uxth r3, r3 + 80030f4: 4a0d ldr r2, [pc, #52] ; (800312c ) + 80030f6: 4013 ands r3, r2 + 80030f8: b29c uxth r4, r3 + 80030fa: 687a ldr r2, [r7, #4] + 80030fc: 683b ldr r3, [r7, #0] + 80030fe: 781b ldrb r3, [r3, #0] + 8003100: 009b lsls r3, r3, #2 + 8003102: 18d3 adds r3, r2, r3 + 8003104: 4a07 ldr r2, [pc, #28] ; (8003124 ) + 8003106: 4322 orrs r2, r4 + 8003108: b292 uxth r2, r2 + 800310a: 801a strh r2, [r3, #0] + } + } + + return HAL_OK; + 800310c: 2300 movs r3, #0 +} + 800310e: 0018 movs r0, r3 + 8003110: 46bd mov sp, r7 + 8003112: b003 add sp, #12 + 8003114: bd90 pop {r4, r7, pc} + 8003116: 46c0 nop ; (mov r8, r8) + 8003118: ffff8f8f .word 0xffff8f8f + 800311c: ffff80c0 .word 0xffff80c0 + 8003120: ffff8fbf .word 0xffff8fbf + 8003124: ffff8080 .word 0xffff8080 + 8003128: ffffc080 .word 0xffffc080 + 800312c: ffffbf8f .word 0xffffbf8f + +08003130 : + * @param USBx : Selected device + * @param ep: pointer to endpoint structure + * @retval HAL status + */ +HAL_StatusTypeDef USB_EPStartXfer(USB_TypeDef *USBx, USB_EPTypeDef *ep) +{ + 8003130: b590 push {r4, r7, lr} + 8003132: b095 sub sp, #84 ; 0x54 + 8003134: af00 add r7, sp, #0 + 8003136: 6078 str r0, [r7, #4] + 8003138: 6039 str r1, [r7, #0] + uint16_t pmabuffer; + uint32_t len; + + /* IN endpoint */ + if (ep->is_in == 1U) + 800313a: 683b ldr r3, [r7, #0] + 800313c: 785b ldrb r3, [r3, #1] + 800313e: 2b01 cmp r3, #1 + 8003140: d000 beq.n 8003144 + 8003142: e163 b.n 800340c + { + /*Multi packet transfer*/ + if (ep->xfer_len > ep->maxpacket) + 8003144: 683b ldr r3, [r7, #0] + 8003146: 699a ldr r2, [r3, #24] + 8003148: 683b ldr r3, [r7, #0] + 800314a: 691b ldr r3, [r3, #16] + 800314c: 429a cmp r2, r3 + 800314e: d909 bls.n 8003164 + { + len = ep->maxpacket; + 8003150: 683b ldr r3, [r7, #0] + 8003152: 691b ldr r3, [r3, #16] + 8003154: 64bb str r3, [r7, #72] ; 0x48 + ep->xfer_len -= len; + 8003156: 683b ldr r3, [r7, #0] + 8003158: 699a ldr r2, [r3, #24] + 800315a: 6cbb ldr r3, [r7, #72] ; 0x48 + 800315c: 1ad2 subs r2, r2, r3 + 800315e: 683b ldr r3, [r7, #0] + 8003160: 619a str r2, [r3, #24] + 8003162: e005 b.n 8003170 + } + else + { + len = ep->xfer_len; + 8003164: 683b ldr r3, [r7, #0] + 8003166: 699b ldr r3, [r3, #24] + 8003168: 64bb str r3, [r7, #72] ; 0x48 + ep->xfer_len = 0U; + 800316a: 683b ldr r3, [r7, #0] + 800316c: 2200 movs r2, #0 + 800316e: 619a str r2, [r3, #24] + } + + /* configure and validate Tx endpoint */ + if (ep->doublebuffer == 0U) + 8003170: 683b ldr r3, [r7, #0] + 8003172: 7b1b ldrb r3, [r3, #12] + 8003174: 2b00 cmp r3, #0 + 8003176: d11b bne.n 80031b0 + { + USB_WritePMA(USBx, ep->xfer_buff, ep->pmaadress, (uint16_t)len); + 8003178: 683b ldr r3, [r7, #0] + 800317a: 6959 ldr r1, [r3, #20] + 800317c: 683b ldr r3, [r7, #0] + 800317e: 88da ldrh r2, [r3, #6] + 8003180: 6cbb ldr r3, [r7, #72] ; 0x48 + 8003182: b29b uxth r3, r3 + 8003184: 6878 ldr r0, [r7, #4] + 8003186: f000 fbbb bl 8003900 + PCD_SET_EP_TX_CNT(USBx, ep->num, len); + 800318a: 687c ldr r4, [r7, #4] + 800318c: 687b ldr r3, [r7, #4] + 800318e: 2250 movs r2, #80 ; 0x50 + 8003190: 5a9b ldrh r3, [r3, r2] + 8003192: b29b uxth r3, r3 + 8003194: 18e4 adds r4, r4, r3 + 8003196: 683b ldr r3, [r7, #0] + 8003198: 781b ldrb r3, [r3, #0] + 800319a: 00db lsls r3, r3, #3 + 800319c: 18e3 adds r3, r4, r3 + 800319e: 4acc ldr r2, [pc, #816] ; (80034d0 ) + 80031a0: 4694 mov ip, r2 + 80031a2: 4463 add r3, ip + 80031a4: 60fb str r3, [r7, #12] + 80031a6: 6cbb ldr r3, [r7, #72] ; 0x48 + 80031a8: b29a uxth r2, r3 + 80031aa: 68fb ldr r3, [r7, #12] + 80031ac: 801a strh r2, [r3, #0] + 80031ae: e113 b.n 80033d8 + } + else + { + /* Write the data to the USB endpoint */ + if ((PCD_GET_ENDPOINT(USBx, ep->num) & USB_EP_DTOG_TX) != 0U) + 80031b0: 687a ldr r2, [r7, #4] + 80031b2: 683b ldr r3, [r7, #0] + 80031b4: 781b ldrb r3, [r3, #0] + 80031b6: 009b lsls r3, r3, #2 + 80031b8: 18d3 adds r3, r2, r3 + 80031ba: 881b ldrh r3, [r3, #0] + 80031bc: b29b uxth r3, r3 + 80031be: 001a movs r2, r3 + 80031c0: 2340 movs r3, #64 ; 0x40 + 80031c2: 4013 ands r3, r2 + 80031c4: d067 beq.n 8003296 + { + /* Set the Double buffer counter for pmabuffer1 */ + PCD_SET_EP_DBUF1_CNT(USBx, ep->num, ep->is_in, len); + 80031c6: 687c ldr r4, [r7, #4] + 80031c8: 683b ldr r3, [r7, #0] + 80031ca: 785b ldrb r3, [r3, #1] + 80031cc: 2b00 cmp r3, #0 + 80031ce: d147 bne.n 8003260 + 80031d0: 687c ldr r4, [r7, #4] + 80031d2: 687b ldr r3, [r7, #4] + 80031d4: 2250 movs r2, #80 ; 0x50 + 80031d6: 5a9b ldrh r3, [r3, r2] + 80031d8: b29b uxth r3, r3 + 80031da: 18e4 adds r4, r4, r3 + 80031dc: 683b ldr r3, [r7, #0] + 80031de: 781b ldrb r3, [r3, #0] + 80031e0: 00db lsls r3, r3, #3 + 80031e2: 18e3 adds r3, r4, r3 + 80031e4: 4abb ldr r2, [pc, #748] ; (80034d4 ) + 80031e6: 4694 mov ip, r2 + 80031e8: 4463 add r3, ip + 80031ea: 613b str r3, [r7, #16] + 80031ec: 6cbb ldr r3, [r7, #72] ; 0x48 + 80031ee: 2b00 cmp r3, #0 + 80031f0: d10e bne.n 8003210 + 80031f2: 693b ldr r3, [r7, #16] + 80031f4: 881b ldrh r3, [r3, #0] + 80031f6: 4ab8 ldr r2, [pc, #736] ; (80034d8 ) + 80031f8: 4013 ands r3, r2 + 80031fa: b29a uxth r2, r3 + 80031fc: 693b ldr r3, [r7, #16] + 80031fe: 801a strh r2, [r3, #0] + 8003200: 693b ldr r3, [r7, #16] + 8003202: 881b ldrh r3, [r3, #0] + 8003204: 4ab5 ldr r2, [pc, #724] ; (80034dc ) + 8003206: 4313 orrs r3, r2 + 8003208: b29a uxth r2, r3 + 800320a: 693b ldr r3, [r7, #16] + 800320c: 801a strh r2, [r3, #0] + 800320e: e03c b.n 800328a + 8003210: 6cbb ldr r3, [r7, #72] ; 0x48 + 8003212: 2b3e cmp r3, #62 ; 0x3e + 8003214: d810 bhi.n 8003238 + 8003216: 6cbb ldr r3, [r7, #72] ; 0x48 + 8003218: 085b lsrs r3, r3, #1 + 800321a: 647b str r3, [r7, #68] ; 0x44 + 800321c: 6cbb ldr r3, [r7, #72] ; 0x48 + 800321e: 2201 movs r2, #1 + 8003220: 4013 ands r3, r2 + 8003222: d002 beq.n 800322a + 8003224: 6c7b ldr r3, [r7, #68] ; 0x44 + 8003226: 3301 adds r3, #1 + 8003228: 647b str r3, [r7, #68] ; 0x44 + 800322a: 6c7b ldr r3, [r7, #68] ; 0x44 + 800322c: b29b uxth r3, r3 + 800322e: 029b lsls r3, r3, #10 + 8003230: b29a uxth r2, r3 + 8003232: 693b ldr r3, [r7, #16] + 8003234: 801a strh r2, [r3, #0] + 8003236: e028 b.n 800328a + 8003238: 6cbb ldr r3, [r7, #72] ; 0x48 + 800323a: 095b lsrs r3, r3, #5 + 800323c: 647b str r3, [r7, #68] ; 0x44 + 800323e: 6cbb ldr r3, [r7, #72] ; 0x48 + 8003240: 221f movs r2, #31 + 8003242: 4013 ands r3, r2 + 8003244: d102 bne.n 800324c + 8003246: 6c7b ldr r3, [r7, #68] ; 0x44 + 8003248: 3b01 subs r3, #1 + 800324a: 647b str r3, [r7, #68] ; 0x44 + 800324c: 6c7b ldr r3, [r7, #68] ; 0x44 + 800324e: b29b uxth r3, r3 + 8003250: 029b lsls r3, r3, #10 + 8003252: b29b uxth r3, r3 + 8003254: 4aa1 ldr r2, [pc, #644] ; (80034dc ) + 8003256: 4313 orrs r3, r2 + 8003258: b29a uxth r2, r3 + 800325a: 693b ldr r3, [r7, #16] + 800325c: 801a strh r2, [r3, #0] + 800325e: e014 b.n 800328a + 8003260: 683b ldr r3, [r7, #0] + 8003262: 785b ldrb r3, [r3, #1] + 8003264: 2b01 cmp r3, #1 + 8003266: d110 bne.n 800328a + 8003268: 687b ldr r3, [r7, #4] + 800326a: 2250 movs r2, #80 ; 0x50 + 800326c: 5a9b ldrh r3, [r3, r2] + 800326e: b29b uxth r3, r3 + 8003270: 18e4 adds r4, r4, r3 + 8003272: 683b ldr r3, [r7, #0] + 8003274: 781b ldrb r3, [r3, #0] + 8003276: 00db lsls r3, r3, #3 + 8003278: 18e3 adds r3, r4, r3 + 800327a: 4a96 ldr r2, [pc, #600] ; (80034d4 ) + 800327c: 4694 mov ip, r2 + 800327e: 4463 add r3, ip + 8003280: 617b str r3, [r7, #20] + 8003282: 6cbb ldr r3, [r7, #72] ; 0x48 + 8003284: b29a uxth r2, r3 + 8003286: 697b ldr r3, [r7, #20] + 8003288: 801a strh r2, [r3, #0] + pmabuffer = ep->pmaaddr1; + 800328a: 234e movs r3, #78 ; 0x4e + 800328c: 18fb adds r3, r7, r3 + 800328e: 683a ldr r2, [r7, #0] + 8003290: 8952 ldrh r2, [r2, #10] + 8003292: 801a strh r2, [r3, #0] + 8003294: e066 b.n 8003364 + } + else + { + /* Set the Double buffer counter for pmabuffer0 */ + PCD_SET_EP_DBUF0_CNT(USBx, ep->num, ep->is_in, len); + 8003296: 683b ldr r3, [r7, #0] + 8003298: 785b ldrb r3, [r3, #1] + 800329a: 2b00 cmp r3, #0 + 800329c: d147 bne.n 800332e + 800329e: 687c ldr r4, [r7, #4] + 80032a0: 687b ldr r3, [r7, #4] + 80032a2: 2250 movs r2, #80 ; 0x50 + 80032a4: 5a9b ldrh r3, [r3, r2] + 80032a6: b29b uxth r3, r3 + 80032a8: 18e4 adds r4, r4, r3 + 80032aa: 683b ldr r3, [r7, #0] + 80032ac: 781b ldrb r3, [r3, #0] + 80032ae: 00db lsls r3, r3, #3 + 80032b0: 18e3 adds r3, r4, r3 + 80032b2: 4a87 ldr r2, [pc, #540] ; (80034d0 ) + 80032b4: 4694 mov ip, r2 + 80032b6: 4463 add r3, ip + 80032b8: 61bb str r3, [r7, #24] + 80032ba: 6cbb ldr r3, [r7, #72] ; 0x48 + 80032bc: 2b00 cmp r3, #0 + 80032be: d10e bne.n 80032de + 80032c0: 69bb ldr r3, [r7, #24] + 80032c2: 881b ldrh r3, [r3, #0] + 80032c4: 4a84 ldr r2, [pc, #528] ; (80034d8 ) + 80032c6: 4013 ands r3, r2 + 80032c8: b29a uxth r2, r3 + 80032ca: 69bb ldr r3, [r7, #24] + 80032cc: 801a strh r2, [r3, #0] + 80032ce: 69bb ldr r3, [r7, #24] + 80032d0: 881b ldrh r3, [r3, #0] + 80032d2: 4a82 ldr r2, [pc, #520] ; (80034dc ) + 80032d4: 4313 orrs r3, r2 + 80032d6: b29a uxth r2, r3 + 80032d8: 69bb ldr r3, [r7, #24] + 80032da: 801a strh r2, [r3, #0] + 80032dc: e03d b.n 800335a + 80032de: 6cbb ldr r3, [r7, #72] ; 0x48 + 80032e0: 2b3e cmp r3, #62 ; 0x3e + 80032e2: d810 bhi.n 8003306 + 80032e4: 6cbb ldr r3, [r7, #72] ; 0x48 + 80032e6: 085b lsrs r3, r3, #1 + 80032e8: 643b str r3, [r7, #64] ; 0x40 + 80032ea: 6cbb ldr r3, [r7, #72] ; 0x48 + 80032ec: 2201 movs r2, #1 + 80032ee: 4013 ands r3, r2 + 80032f0: d002 beq.n 80032f8 + 80032f2: 6c3b ldr r3, [r7, #64] ; 0x40 + 80032f4: 3301 adds r3, #1 + 80032f6: 643b str r3, [r7, #64] ; 0x40 + 80032f8: 6c3b ldr r3, [r7, #64] ; 0x40 + 80032fa: b29b uxth r3, r3 + 80032fc: 029b lsls r3, r3, #10 + 80032fe: b29a uxth r2, r3 + 8003300: 69bb ldr r3, [r7, #24] + 8003302: 801a strh r2, [r3, #0] + 8003304: e029 b.n 800335a + 8003306: 6cbb ldr r3, [r7, #72] ; 0x48 + 8003308: 095b lsrs r3, r3, #5 + 800330a: 643b str r3, [r7, #64] ; 0x40 + 800330c: 6cbb ldr r3, [r7, #72] ; 0x48 + 800330e: 221f movs r2, #31 + 8003310: 4013 ands r3, r2 + 8003312: d102 bne.n 800331a + 8003314: 6c3b ldr r3, [r7, #64] ; 0x40 + 8003316: 3b01 subs r3, #1 + 8003318: 643b str r3, [r7, #64] ; 0x40 + 800331a: 6c3b ldr r3, [r7, #64] ; 0x40 + 800331c: b29b uxth r3, r3 + 800331e: 029b lsls r3, r3, #10 + 8003320: b29b uxth r3, r3 + 8003322: 4a6e ldr r2, [pc, #440] ; (80034dc ) + 8003324: 4313 orrs r3, r2 + 8003326: b29a uxth r2, r3 + 8003328: 69bb ldr r3, [r7, #24] + 800332a: 801a strh r2, [r3, #0] + 800332c: e015 b.n 800335a + 800332e: 683b ldr r3, [r7, #0] + 8003330: 785b ldrb r3, [r3, #1] + 8003332: 2b01 cmp r3, #1 + 8003334: d111 bne.n 800335a + 8003336: 687c ldr r4, [r7, #4] + 8003338: 687b ldr r3, [r7, #4] + 800333a: 2250 movs r2, #80 ; 0x50 + 800333c: 5a9b ldrh r3, [r3, r2] + 800333e: b29b uxth r3, r3 + 8003340: 18e4 adds r4, r4, r3 + 8003342: 683b ldr r3, [r7, #0] + 8003344: 781b ldrb r3, [r3, #0] + 8003346: 00db lsls r3, r3, #3 + 8003348: 18e3 adds r3, r4, r3 + 800334a: 4a61 ldr r2, [pc, #388] ; (80034d0 ) + 800334c: 4694 mov ip, r2 + 800334e: 4463 add r3, ip + 8003350: 61fb str r3, [r7, #28] + 8003352: 6cbb ldr r3, [r7, #72] ; 0x48 + 8003354: b29a uxth r2, r3 + 8003356: 69fb ldr r3, [r7, #28] + 8003358: 801a strh r2, [r3, #0] + pmabuffer = ep->pmaaddr0; + 800335a: 234e movs r3, #78 ; 0x4e + 800335c: 18fb adds r3, r7, r3 + 800335e: 683a ldr r2, [r7, #0] + 8003360: 8912 ldrh r2, [r2, #8] + 8003362: 801a strh r2, [r3, #0] + } + USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len); + 8003364: 683b ldr r3, [r7, #0] + 8003366: 6959 ldr r1, [r3, #20] + 8003368: 6cbb ldr r3, [r7, #72] ; 0x48 + 800336a: b29c uxth r4, r3 + 800336c: 234e movs r3, #78 ; 0x4e + 800336e: 18fb adds r3, r7, r3 + 8003370: 881a ldrh r2, [r3, #0] + 8003372: 6878 ldr r0, [r7, #4] + 8003374: 0023 movs r3, r4 + 8003376: f000 fac3 bl 8003900 + PCD_FreeUserBuffer(USBx, ep->num, ep->is_in); + 800337a: 683b ldr r3, [r7, #0] + 800337c: 785b ldrb r3, [r3, #1] + 800337e: 2b00 cmp r3, #0 + 8003380: d113 bne.n 80033aa + 8003382: 687a ldr r2, [r7, #4] + 8003384: 683b ldr r3, [r7, #0] + 8003386: 781b ldrb r3, [r3, #0] + 8003388: 009b lsls r3, r3, #2 + 800338a: 18d3 adds r3, r2, r3 + 800338c: 881b ldrh r3, [r3, #0] + 800338e: b29b uxth r3, r3 + 8003390: 4a53 ldr r2, [pc, #332] ; (80034e0 ) + 8003392: 4013 ands r3, r2 + 8003394: b29c uxth r4, r3 + 8003396: 687a ldr r2, [r7, #4] + 8003398: 683b ldr r3, [r7, #0] + 800339a: 781b ldrb r3, [r3, #0] + 800339c: 009b lsls r3, r3, #2 + 800339e: 18d3 adds r3, r2, r3 + 80033a0: 4a50 ldr r2, [pc, #320] ; (80034e4 ) + 80033a2: 4322 orrs r2, r4 + 80033a4: b292 uxth r2, r2 + 80033a6: 801a strh r2, [r3, #0] + 80033a8: e016 b.n 80033d8 + 80033aa: 683b ldr r3, [r7, #0] + 80033ac: 785b ldrb r3, [r3, #1] + 80033ae: 2b01 cmp r3, #1 + 80033b0: d112 bne.n 80033d8 + 80033b2: 687a ldr r2, [r7, #4] + 80033b4: 683b ldr r3, [r7, #0] + 80033b6: 781b ldrb r3, [r3, #0] + 80033b8: 009b lsls r3, r3, #2 + 80033ba: 18d3 adds r3, r2, r3 + 80033bc: 881b ldrh r3, [r3, #0] + 80033be: b29b uxth r3, r3 + 80033c0: 4a47 ldr r2, [pc, #284] ; (80034e0 ) + 80033c2: 4013 ands r3, r2 + 80033c4: b29c uxth r4, r3 + 80033c6: 687a ldr r2, [r7, #4] + 80033c8: 683b ldr r3, [r7, #0] + 80033ca: 781b ldrb r3, [r3, #0] + 80033cc: 009b lsls r3, r3, #2 + 80033ce: 18d3 adds r3, r2, r3 + 80033d0: 4a45 ldr r2, [pc, #276] ; (80034e8 ) + 80033d2: 4322 orrs r2, r4 + 80033d4: b292 uxth r2, r2 + 80033d6: 801a strh r2, [r3, #0] + } + + PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_VALID); + 80033d8: 687a ldr r2, [r7, #4] + 80033da: 683b ldr r3, [r7, #0] + 80033dc: 781b ldrb r3, [r3, #0] + 80033de: 009b lsls r3, r3, #2 + 80033e0: 18d3 adds r3, r2, r3 + 80033e2: 881b ldrh r3, [r3, #0] + 80033e4: b29b uxth r3, r3 + 80033e6: 4a41 ldr r2, [pc, #260] ; (80034ec ) + 80033e8: 4013 ands r3, r2 + 80033ea: b29c uxth r4, r3 + 80033ec: 2310 movs r3, #16 + 80033ee: 4063 eors r3, r4 + 80033f0: b29c uxth r4, r3 + 80033f2: 2320 movs r3, #32 + 80033f4: 4063 eors r3, r4 + 80033f6: b29c uxth r4, r3 + 80033f8: 687a ldr r2, [r7, #4] + 80033fa: 683b ldr r3, [r7, #0] + 80033fc: 781b ldrb r3, [r3, #0] + 80033fe: 009b lsls r3, r3, #2 + 8003400: 18d3 adds r3, r2, r3 + 8003402: 4a3b ldr r2, [pc, #236] ; (80034f0 ) + 8003404: 4322 orrs r2, r4 + 8003406: b292 uxth r2, r2 + 8003408: 801a strh r2, [r3, #0] + 800340a: e152 b.n 80036b2 + } + else /* OUT endpoint */ + { + /* Multi packet transfer*/ + if (ep->xfer_len > ep->maxpacket) + 800340c: 683b ldr r3, [r7, #0] + 800340e: 699a ldr r2, [r3, #24] + 8003410: 683b ldr r3, [r7, #0] + 8003412: 691b ldr r3, [r3, #16] + 8003414: 429a cmp r2, r3 + 8003416: d909 bls.n 800342c + { + len = ep->maxpacket; + 8003418: 683b ldr r3, [r7, #0] + 800341a: 691b ldr r3, [r3, #16] + 800341c: 64bb str r3, [r7, #72] ; 0x48 + ep->xfer_len -= len; + 800341e: 683b ldr r3, [r7, #0] + 8003420: 699a ldr r2, [r3, #24] + 8003422: 6cbb ldr r3, [r7, #72] ; 0x48 + 8003424: 1ad2 subs r2, r2, r3 + 8003426: 683b ldr r3, [r7, #0] + 8003428: 619a str r2, [r3, #24] + 800342a: e005 b.n 8003438 + } + else + { + len = ep->xfer_len; + 800342c: 683b ldr r3, [r7, #0] + 800342e: 699b ldr r3, [r3, #24] + 8003430: 64bb str r3, [r7, #72] ; 0x48 + ep->xfer_len = 0U; + 8003432: 683b ldr r3, [r7, #0] + 8003434: 2200 movs r2, #0 + 8003436: 619a str r2, [r3, #24] + } + + /* configure and validate Rx endpoint */ + if (ep->doublebuffer == 0U) + 8003438: 683b ldr r3, [r7, #0] + 800343a: 7b1b ldrb r3, [r3, #12] + 800343c: 2b00 cmp r3, #0 + 800343e: d159 bne.n 80034f4 + { + /*Set RX buffer count*/ + PCD_SET_EP_RX_CNT(USBx, ep->num, len); + 8003440: 687c ldr r4, [r7, #4] + 8003442: 687b ldr r3, [r7, #4] + 8003444: 2250 movs r2, #80 ; 0x50 + 8003446: 5a9b ldrh r3, [r3, r2] + 8003448: b29b uxth r3, r3 + 800344a: 18e4 adds r4, r4, r3 + 800344c: 683b ldr r3, [r7, #0] + 800344e: 781b ldrb r3, [r3, #0] + 8003450: 00db lsls r3, r3, #3 + 8003452: 18e3 adds r3, r4, r3 + 8003454: 4a1f ldr r2, [pc, #124] ; (80034d4 ) + 8003456: 4694 mov ip, r2 + 8003458: 4463 add r3, ip + 800345a: 623b str r3, [r7, #32] + 800345c: 6cbb ldr r3, [r7, #72] ; 0x48 + 800345e: 2b00 cmp r3, #0 + 8003460: d10e bne.n 8003480 + 8003462: 6a3b ldr r3, [r7, #32] + 8003464: 881b ldrh r3, [r3, #0] + 8003466: 4a1c ldr r2, [pc, #112] ; (80034d8 ) + 8003468: 4013 ands r3, r2 + 800346a: b29a uxth r2, r3 + 800346c: 6a3b ldr r3, [r7, #32] + 800346e: 801a strh r2, [r3, #0] + 8003470: 6a3b ldr r3, [r7, #32] + 8003472: 881b ldrh r3, [r3, #0] + 8003474: 4a19 ldr r2, [pc, #100] ; (80034dc ) + 8003476: 4313 orrs r3, r2 + 8003478: b29a uxth r2, r3 + 800347a: 6a3b ldr r3, [r7, #32] + 800347c: 801a strh r2, [r3, #0] + 800347e: e0fd b.n 800367c + 8003480: 6cbb ldr r3, [r7, #72] ; 0x48 + 8003482: 2b3e cmp r3, #62 ; 0x3e + 8003484: d810 bhi.n 80034a8 + 8003486: 6cbb ldr r3, [r7, #72] ; 0x48 + 8003488: 085b lsrs r3, r3, #1 + 800348a: 63fb str r3, [r7, #60] ; 0x3c + 800348c: 6cbb ldr r3, [r7, #72] ; 0x48 + 800348e: 2201 movs r2, #1 + 8003490: 4013 ands r3, r2 + 8003492: d002 beq.n 800349a + 8003494: 6bfb ldr r3, [r7, #60] ; 0x3c + 8003496: 3301 adds r3, #1 + 8003498: 63fb str r3, [r7, #60] ; 0x3c + 800349a: 6bfb ldr r3, [r7, #60] ; 0x3c + 800349c: b29b uxth r3, r3 + 800349e: 029b lsls r3, r3, #10 + 80034a0: b29a uxth r2, r3 + 80034a2: 6a3b ldr r3, [r7, #32] + 80034a4: 801a strh r2, [r3, #0] + 80034a6: e0e9 b.n 800367c + 80034a8: 6cbb ldr r3, [r7, #72] ; 0x48 + 80034aa: 095b lsrs r3, r3, #5 + 80034ac: 63fb str r3, [r7, #60] ; 0x3c + 80034ae: 6cbb ldr r3, [r7, #72] ; 0x48 + 80034b0: 221f movs r2, #31 + 80034b2: 4013 ands r3, r2 + 80034b4: d102 bne.n 80034bc + 80034b6: 6bfb ldr r3, [r7, #60] ; 0x3c + 80034b8: 3b01 subs r3, #1 + 80034ba: 63fb str r3, [r7, #60] ; 0x3c + 80034bc: 6bfb ldr r3, [r7, #60] ; 0x3c + 80034be: b29b uxth r3, r3 + 80034c0: 029b lsls r3, r3, #10 + 80034c2: b29b uxth r3, r3 + 80034c4: 4a05 ldr r2, [pc, #20] ; (80034dc ) + 80034c6: 4313 orrs r3, r2 + 80034c8: b29a uxth r2, r3 + 80034ca: 6a3b ldr r3, [r7, #32] + 80034cc: 801a strh r2, [r3, #0] + 80034ce: e0d5 b.n 800367c + 80034d0: 00000402 .word 0x00000402 + 80034d4: 00000406 .word 0x00000406 + 80034d8: ffff83ff .word 0xffff83ff + 80034dc: ffff8000 .word 0xffff8000 + 80034e0: ffff8f8f .word 0xffff8f8f + 80034e4: ffff80c0 .word 0xffff80c0 + 80034e8: ffffc080 .word 0xffffc080 + 80034ec: ffff8fbf .word 0xffff8fbf + 80034f0: ffff8080 .word 0xffff8080 + } + else + { + /*Set the Double buffer counter*/ + PCD_SET_EP_DBUF_CNT(USBx, ep->num, ep->is_in, len); + 80034f4: 683b ldr r3, [r7, #0] + 80034f6: 785b ldrb r3, [r3, #1] + 80034f8: 2b00 cmp r3, #0 + 80034fa: d147 bne.n 800358c + 80034fc: 687c ldr r4, [r7, #4] + 80034fe: 687b ldr r3, [r7, #4] + 8003500: 2250 movs r2, #80 ; 0x50 + 8003502: 5a9b ldrh r3, [r3, r2] + 8003504: b29b uxth r3, r3 + 8003506: 18e4 adds r4, r4, r3 + 8003508: 683b ldr r3, [r7, #0] + 800350a: 781b ldrb r3, [r3, #0] + 800350c: 00db lsls r3, r3, #3 + 800350e: 18e3 adds r3, r4, r3 + 8003510: 4a6a ldr r2, [pc, #424] ; (80036bc ) + 8003512: 4694 mov ip, r2 + 8003514: 4463 add r3, ip + 8003516: 62fb str r3, [r7, #44] ; 0x2c + 8003518: 6cbb ldr r3, [r7, #72] ; 0x48 + 800351a: 2b00 cmp r3, #0 + 800351c: d10e bne.n 800353c + 800351e: 6afb ldr r3, [r7, #44] ; 0x2c + 8003520: 881b ldrh r3, [r3, #0] + 8003522: 4a67 ldr r2, [pc, #412] ; (80036c0 ) + 8003524: 4013 ands r3, r2 + 8003526: b29a uxth r2, r3 + 8003528: 6afb ldr r3, [r7, #44] ; 0x2c + 800352a: 801a strh r2, [r3, #0] + 800352c: 6afb ldr r3, [r7, #44] ; 0x2c + 800352e: 881b ldrh r3, [r3, #0] + 8003530: 4a64 ldr r2, [pc, #400] ; (80036c4 ) + 8003532: 4313 orrs r3, r2 + 8003534: b29a uxth r2, r3 + 8003536: 6afb ldr r3, [r7, #44] ; 0x2c + 8003538: 801a strh r2, [r3, #0] + 800353a: e03d b.n 80035b8 + 800353c: 6cbb ldr r3, [r7, #72] ; 0x48 + 800353e: 2b3e cmp r3, #62 ; 0x3e + 8003540: d810 bhi.n 8003564 + 8003542: 6cbb ldr r3, [r7, #72] ; 0x48 + 8003544: 085b lsrs r3, r3, #1 + 8003546: 63bb str r3, [r7, #56] ; 0x38 + 8003548: 6cbb ldr r3, [r7, #72] ; 0x48 + 800354a: 2201 movs r2, #1 + 800354c: 4013 ands r3, r2 + 800354e: d002 beq.n 8003556 + 8003550: 6bbb ldr r3, [r7, #56] ; 0x38 + 8003552: 3301 adds r3, #1 + 8003554: 63bb str r3, [r7, #56] ; 0x38 + 8003556: 6bbb ldr r3, [r7, #56] ; 0x38 + 8003558: b29b uxth r3, r3 + 800355a: 029b lsls r3, r3, #10 + 800355c: b29a uxth r2, r3 + 800355e: 6afb ldr r3, [r7, #44] ; 0x2c + 8003560: 801a strh r2, [r3, #0] + 8003562: e029 b.n 80035b8 + 8003564: 6cbb ldr r3, [r7, #72] ; 0x48 + 8003566: 095b lsrs r3, r3, #5 + 8003568: 63bb str r3, [r7, #56] ; 0x38 + 800356a: 6cbb ldr r3, [r7, #72] ; 0x48 + 800356c: 221f movs r2, #31 + 800356e: 4013 ands r3, r2 + 8003570: d102 bne.n 8003578 + 8003572: 6bbb ldr r3, [r7, #56] ; 0x38 + 8003574: 3b01 subs r3, #1 + 8003576: 63bb str r3, [r7, #56] ; 0x38 + 8003578: 6bbb ldr r3, [r7, #56] ; 0x38 + 800357a: b29b uxth r3, r3 + 800357c: 029b lsls r3, r3, #10 + 800357e: b29b uxth r3, r3 + 8003580: 4a50 ldr r2, [pc, #320] ; (80036c4 ) + 8003582: 4313 orrs r3, r2 + 8003584: b29a uxth r2, r3 + 8003586: 6afb ldr r3, [r7, #44] ; 0x2c + 8003588: 801a strh r2, [r3, #0] + 800358a: e015 b.n 80035b8 + 800358c: 683b ldr r3, [r7, #0] + 800358e: 785b ldrb r3, [r3, #1] + 8003590: 2b01 cmp r3, #1 + 8003592: d111 bne.n 80035b8 + 8003594: 687c ldr r4, [r7, #4] + 8003596: 687b ldr r3, [r7, #4] + 8003598: 2250 movs r2, #80 ; 0x50 + 800359a: 5a9b ldrh r3, [r3, r2] + 800359c: b29b uxth r3, r3 + 800359e: 18e4 adds r4, r4, r3 + 80035a0: 683b ldr r3, [r7, #0] + 80035a2: 781b ldrb r3, [r3, #0] + 80035a4: 00db lsls r3, r3, #3 + 80035a6: 18e3 adds r3, r4, r3 + 80035a8: 4a44 ldr r2, [pc, #272] ; (80036bc ) + 80035aa: 4694 mov ip, r2 + 80035ac: 4463 add r3, ip + 80035ae: 633b str r3, [r7, #48] ; 0x30 + 80035b0: 6cbb ldr r3, [r7, #72] ; 0x48 + 80035b2: b29a uxth r2, r3 + 80035b4: 6b3b ldr r3, [r7, #48] ; 0x30 + 80035b6: 801a strh r2, [r3, #0] + 80035b8: 687c ldr r4, [r7, #4] + 80035ba: 683b ldr r3, [r7, #0] + 80035bc: 785b ldrb r3, [r3, #1] + 80035be: 2b00 cmp r3, #0 + 80035c0: d147 bne.n 8003652 + 80035c2: 687c ldr r4, [r7, #4] + 80035c4: 687b ldr r3, [r7, #4] + 80035c6: 2250 movs r2, #80 ; 0x50 + 80035c8: 5a9b ldrh r3, [r3, r2] + 80035ca: b29b uxth r3, r3 + 80035cc: 18e4 adds r4, r4, r3 + 80035ce: 683b ldr r3, [r7, #0] + 80035d0: 781b ldrb r3, [r3, #0] + 80035d2: 00db lsls r3, r3, #3 + 80035d4: 18e3 adds r3, r4, r3 + 80035d6: 4a3c ldr r2, [pc, #240] ; (80036c8 ) + 80035d8: 4694 mov ip, r2 + 80035da: 4463 add r3, ip + 80035dc: 627b str r3, [r7, #36] ; 0x24 + 80035de: 6cbb ldr r3, [r7, #72] ; 0x48 + 80035e0: 2b00 cmp r3, #0 + 80035e2: d10e bne.n 8003602 + 80035e4: 6a7b ldr r3, [r7, #36] ; 0x24 + 80035e6: 881b ldrh r3, [r3, #0] + 80035e8: 4a35 ldr r2, [pc, #212] ; (80036c0 ) + 80035ea: 4013 ands r3, r2 + 80035ec: b29a uxth r2, r3 + 80035ee: 6a7b ldr r3, [r7, #36] ; 0x24 + 80035f0: 801a strh r2, [r3, #0] + 80035f2: 6a7b ldr r3, [r7, #36] ; 0x24 + 80035f4: 881b ldrh r3, [r3, #0] + 80035f6: 4a33 ldr r2, [pc, #204] ; (80036c4 ) + 80035f8: 4313 orrs r3, r2 + 80035fa: b29a uxth r2, r3 + 80035fc: 6a7b ldr r3, [r7, #36] ; 0x24 + 80035fe: 801a strh r2, [r3, #0] + 8003600: e03c b.n 800367c + 8003602: 6cbb ldr r3, [r7, #72] ; 0x48 + 8003604: 2b3e cmp r3, #62 ; 0x3e + 8003606: d810 bhi.n 800362a + 8003608: 6cbb ldr r3, [r7, #72] ; 0x48 + 800360a: 085b lsrs r3, r3, #1 + 800360c: 637b str r3, [r7, #52] ; 0x34 + 800360e: 6cbb ldr r3, [r7, #72] ; 0x48 + 8003610: 2201 movs r2, #1 + 8003612: 4013 ands r3, r2 + 8003614: d002 beq.n 800361c + 8003616: 6b7b ldr r3, [r7, #52] ; 0x34 + 8003618: 3301 adds r3, #1 + 800361a: 637b str r3, [r7, #52] ; 0x34 + 800361c: 6b7b ldr r3, [r7, #52] ; 0x34 + 800361e: b29b uxth r3, r3 + 8003620: 029b lsls r3, r3, #10 + 8003622: b29a uxth r2, r3 + 8003624: 6a7b ldr r3, [r7, #36] ; 0x24 + 8003626: 801a strh r2, [r3, #0] + 8003628: e028 b.n 800367c + 800362a: 6cbb ldr r3, [r7, #72] ; 0x48 + 800362c: 095b lsrs r3, r3, #5 + 800362e: 637b str r3, [r7, #52] ; 0x34 + 8003630: 6cbb ldr r3, [r7, #72] ; 0x48 + 8003632: 221f movs r2, #31 + 8003634: 4013 ands r3, r2 + 8003636: d102 bne.n 800363e + 8003638: 6b7b ldr r3, [r7, #52] ; 0x34 + 800363a: 3b01 subs r3, #1 + 800363c: 637b str r3, [r7, #52] ; 0x34 + 800363e: 6b7b ldr r3, [r7, #52] ; 0x34 + 8003640: b29b uxth r3, r3 + 8003642: 029b lsls r3, r3, #10 + 8003644: b29b uxth r3, r3 + 8003646: 4a1f ldr r2, [pc, #124] ; (80036c4 ) + 8003648: 4313 orrs r3, r2 + 800364a: b29a uxth r2, r3 + 800364c: 6a7b ldr r3, [r7, #36] ; 0x24 + 800364e: 801a strh r2, [r3, #0] + 8003650: e014 b.n 800367c + 8003652: 683b ldr r3, [r7, #0] + 8003654: 785b ldrb r3, [r3, #1] + 8003656: 2b01 cmp r3, #1 + 8003658: d110 bne.n 800367c + 800365a: 687b ldr r3, [r7, #4] + 800365c: 2250 movs r2, #80 ; 0x50 + 800365e: 5a9b ldrh r3, [r3, r2] + 8003660: b29b uxth r3, r3 + 8003662: 18e4 adds r4, r4, r3 + 8003664: 683b ldr r3, [r7, #0] + 8003666: 781b ldrb r3, [r3, #0] + 8003668: 00db lsls r3, r3, #3 + 800366a: 18e3 adds r3, r4, r3 + 800366c: 4a16 ldr r2, [pc, #88] ; (80036c8 ) + 800366e: 4694 mov ip, r2 + 8003670: 4463 add r3, ip + 8003672: 62bb str r3, [r7, #40] ; 0x28 + 8003674: 6cbb ldr r3, [r7, #72] ; 0x48 + 8003676: b29a uxth r2, r3 + 8003678: 6abb ldr r3, [r7, #40] ; 0x28 + 800367a: 801a strh r2, [r3, #0] + } + + PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_VALID); + 800367c: 687a ldr r2, [r7, #4] + 800367e: 683b ldr r3, [r7, #0] + 8003680: 781b ldrb r3, [r3, #0] + 8003682: 009b lsls r3, r3, #2 + 8003684: 18d3 adds r3, r2, r3 + 8003686: 881b ldrh r3, [r3, #0] + 8003688: b29b uxth r3, r3 + 800368a: 4a10 ldr r2, [pc, #64] ; (80036cc ) + 800368c: 4013 ands r3, r2 + 800368e: b29c uxth r4, r3 + 8003690: 2380 movs r3, #128 ; 0x80 + 8003692: 015b lsls r3, r3, #5 + 8003694: 4063 eors r3, r4 + 8003696: b29c uxth r4, r3 + 8003698: 2380 movs r3, #128 ; 0x80 + 800369a: 019b lsls r3, r3, #6 + 800369c: 4063 eors r3, r4 + 800369e: b29c uxth r4, r3 + 80036a0: 687a ldr r2, [r7, #4] + 80036a2: 683b ldr r3, [r7, #0] + 80036a4: 781b ldrb r3, [r3, #0] + 80036a6: 009b lsls r3, r3, #2 + 80036a8: 18d3 adds r3, r2, r3 + 80036aa: 4a09 ldr r2, [pc, #36] ; (80036d0 ) + 80036ac: 4322 orrs r2, r4 + 80036ae: b292 uxth r2, r2 + 80036b0: 801a strh r2, [r3, #0] + } + + return HAL_OK; + 80036b2: 2300 movs r3, #0 +} + 80036b4: 0018 movs r0, r3 + 80036b6: 46bd mov sp, r7 + 80036b8: b015 add sp, #84 ; 0x54 + 80036ba: bd90 pop {r4, r7, pc} + 80036bc: 00000402 .word 0x00000402 + 80036c0: ffff83ff .word 0xffff83ff + 80036c4: ffff8000 .word 0xffff8000 + 80036c8: 00000406 .word 0x00000406 + 80036cc: ffffbf8f .word 0xffffbf8f + 80036d0: ffff8080 .word 0xffff8080 + +080036d4 : + * @param USBx : Selected device + * @param ep: pointer to endpoint structure + * @retval HAL status + */ +HAL_StatusTypeDef USB_EPSetStall(USB_TypeDef *USBx, USB_EPTypeDef *ep) +{ + 80036d4: b590 push {r4, r7, lr} + 80036d6: b083 sub sp, #12 + 80036d8: af00 add r7, sp, #0 + 80036da: 6078 str r0, [r7, #4] + 80036dc: 6039 str r1, [r7, #0] + if (ep->is_in != 0U) + 80036de: 683b ldr r3, [r7, #0] + 80036e0: 785b ldrb r3, [r3, #1] + 80036e2: 2b00 cmp r3, #0 + 80036e4: d016 beq.n 8003714 + { + PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_STALL); + 80036e6: 687a ldr r2, [r7, #4] + 80036e8: 683b ldr r3, [r7, #0] + 80036ea: 781b ldrb r3, [r3, #0] + 80036ec: 009b lsls r3, r3, #2 + 80036ee: 18d3 adds r3, r2, r3 + 80036f0: 881b ldrh r3, [r3, #0] + 80036f2: b29b uxth r3, r3 + 80036f4: 4a15 ldr r2, [pc, #84] ; (800374c ) + 80036f6: 4013 ands r3, r2 + 80036f8: b29c uxth r4, r3 + 80036fa: 2310 movs r3, #16 + 80036fc: 4063 eors r3, r4 + 80036fe: b29c uxth r4, r3 + 8003700: 687a ldr r2, [r7, #4] + 8003702: 683b ldr r3, [r7, #0] + 8003704: 781b ldrb r3, [r3, #0] + 8003706: 009b lsls r3, r3, #2 + 8003708: 18d3 adds r3, r2, r3 + 800370a: 4a11 ldr r2, [pc, #68] ; (8003750 ) + 800370c: 4322 orrs r2, r4 + 800370e: b292 uxth r2, r2 + 8003710: 801a strh r2, [r3, #0] + 8003712: e016 b.n 8003742 + } + else + { + PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_STALL); + 8003714: 687a ldr r2, [r7, #4] + 8003716: 683b ldr r3, [r7, #0] + 8003718: 781b ldrb r3, [r3, #0] + 800371a: 009b lsls r3, r3, #2 + 800371c: 18d3 adds r3, r2, r3 + 800371e: 881b ldrh r3, [r3, #0] + 8003720: b29b uxth r3, r3 + 8003722: 4a0c ldr r2, [pc, #48] ; (8003754 ) + 8003724: 4013 ands r3, r2 + 8003726: b29c uxth r4, r3 + 8003728: 2380 movs r3, #128 ; 0x80 + 800372a: 015b lsls r3, r3, #5 + 800372c: 4063 eors r3, r4 + 800372e: b29c uxth r4, r3 + 8003730: 687a ldr r2, [r7, #4] + 8003732: 683b ldr r3, [r7, #0] + 8003734: 781b ldrb r3, [r3, #0] + 8003736: 009b lsls r3, r3, #2 + 8003738: 18d3 adds r3, r2, r3 + 800373a: 4a05 ldr r2, [pc, #20] ; (8003750 ) + 800373c: 4322 orrs r2, r4 + 800373e: b292 uxth r2, r2 + 8003740: 801a strh r2, [r3, #0] + } + + return HAL_OK; + 8003742: 2300 movs r3, #0 +} + 8003744: 0018 movs r0, r3 + 8003746: 46bd mov sp, r7 + 8003748: b003 add sp, #12 + 800374a: bd90 pop {r4, r7, pc} + 800374c: ffff8fbf .word 0xffff8fbf + 8003750: ffff8080 .word 0xffff8080 + 8003754: ffffbf8f .word 0xffffbf8f + +08003758 : + * @param USBx : Selected device + * @param ep: pointer to endpoint structure + * @retval HAL status + */ +HAL_StatusTypeDef USB_EPClearStall(USB_TypeDef *USBx, USB_EPTypeDef *ep) +{ + 8003758: b590 push {r4, r7, lr} + 800375a: b083 sub sp, #12 + 800375c: af00 add r7, sp, #0 + 800375e: 6078 str r0, [r7, #4] + 8003760: 6039 str r1, [r7, #0] + if (ep->doublebuffer == 0U) + 8003762: 683b ldr r3, [r7, #0] + 8003764: 7b1b ldrb r3, [r3, #12] + 8003766: 2b00 cmp r3, #0 + 8003768: d000 beq.n 800376c + 800376a: e076 b.n 800385a + { + if (ep->is_in != 0U) + 800376c: 683b ldr r3, [r7, #0] + 800376e: 785b ldrb r3, [r3, #1] + 8003770: 2b00 cmp r3, #0 + 8003772: d038 beq.n 80037e6 + { + PCD_CLEAR_TX_DTOG(USBx, ep->num); + 8003774: 687a ldr r2, [r7, #4] + 8003776: 683b ldr r3, [r7, #0] + 8003778: 781b ldrb r3, [r3, #0] + 800377a: 009b lsls r3, r3, #2 + 800377c: 18d3 adds r3, r2, r3 + 800377e: 881b ldrh r3, [r3, #0] + 8003780: b29c uxth r4, r3 + 8003782: 0022 movs r2, r4 + 8003784: 2340 movs r3, #64 ; 0x40 + 8003786: 4013 ands r3, r2 + 8003788: d012 beq.n 80037b0 + 800378a: 687a ldr r2, [r7, #4] + 800378c: 683b ldr r3, [r7, #0] + 800378e: 781b ldrb r3, [r3, #0] + 8003790: 009b lsls r3, r3, #2 + 8003792: 18d3 adds r3, r2, r3 + 8003794: 881b ldrh r3, [r3, #0] + 8003796: b29b uxth r3, r3 + 8003798: 4a32 ldr r2, [pc, #200] ; (8003864 ) + 800379a: 4013 ands r3, r2 + 800379c: b29c uxth r4, r3 + 800379e: 687a ldr r2, [r7, #4] + 80037a0: 683b ldr r3, [r7, #0] + 80037a2: 781b ldrb r3, [r3, #0] + 80037a4: 009b lsls r3, r3, #2 + 80037a6: 18d3 adds r3, r2, r3 + 80037a8: 4a2f ldr r2, [pc, #188] ; (8003868 ) + 80037aa: 4322 orrs r2, r4 + 80037ac: b292 uxth r2, r2 + 80037ae: 801a strh r2, [r3, #0] + + if (ep->type != EP_TYPE_ISOC) + 80037b0: 683b ldr r3, [r7, #0] + 80037b2: 78db ldrb r3, [r3, #3] + 80037b4: 2b01 cmp r3, #1 + 80037b6: d050 beq.n 800385a + { + /* Configure NAK status for the Endpoint */ + PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_NAK); + 80037b8: 687a ldr r2, [r7, #4] + 80037ba: 683b ldr r3, [r7, #0] + 80037bc: 781b ldrb r3, [r3, #0] + 80037be: 009b lsls r3, r3, #2 + 80037c0: 18d3 adds r3, r2, r3 + 80037c2: 881b ldrh r3, [r3, #0] + 80037c4: b29b uxth r3, r3 + 80037c6: 4a29 ldr r2, [pc, #164] ; (800386c ) + 80037c8: 4013 ands r3, r2 + 80037ca: b29c uxth r4, r3 + 80037cc: 2320 movs r3, #32 + 80037ce: 4063 eors r3, r4 + 80037d0: b29c uxth r4, r3 + 80037d2: 687a ldr r2, [r7, #4] + 80037d4: 683b ldr r3, [r7, #0] + 80037d6: 781b ldrb r3, [r3, #0] + 80037d8: 009b lsls r3, r3, #2 + 80037da: 18d3 adds r3, r2, r3 + 80037dc: 4a24 ldr r2, [pc, #144] ; (8003870 ) + 80037de: 4322 orrs r2, r4 + 80037e0: b292 uxth r2, r2 + 80037e2: 801a strh r2, [r3, #0] + 80037e4: e039 b.n 800385a + } + } + else + { + PCD_CLEAR_RX_DTOG(USBx, ep->num); + 80037e6: 687a ldr r2, [r7, #4] + 80037e8: 683b ldr r3, [r7, #0] + 80037ea: 781b ldrb r3, [r3, #0] + 80037ec: 009b lsls r3, r3, #2 + 80037ee: 18d3 adds r3, r2, r3 + 80037f0: 881b ldrh r3, [r3, #0] + 80037f2: b29c uxth r4, r3 + 80037f4: 0022 movs r2, r4 + 80037f6: 2380 movs r3, #128 ; 0x80 + 80037f8: 01db lsls r3, r3, #7 + 80037fa: 4013 ands r3, r2 + 80037fc: d012 beq.n 8003824 + 80037fe: 687a ldr r2, [r7, #4] + 8003800: 683b ldr r3, [r7, #0] + 8003802: 781b ldrb r3, [r3, #0] + 8003804: 009b lsls r3, r3, #2 + 8003806: 18d3 adds r3, r2, r3 + 8003808: 881b ldrh r3, [r3, #0] + 800380a: b29b uxth r3, r3 + 800380c: 4a15 ldr r2, [pc, #84] ; (8003864 ) + 800380e: 4013 ands r3, r2 + 8003810: b29c uxth r4, r3 + 8003812: 687a ldr r2, [r7, #4] + 8003814: 683b ldr r3, [r7, #0] + 8003816: 781b ldrb r3, [r3, #0] + 8003818: 009b lsls r3, r3, #2 + 800381a: 18d3 adds r3, r2, r3 + 800381c: 4a15 ldr r2, [pc, #84] ; (8003874 ) + 800381e: 4322 orrs r2, r4 + 8003820: b292 uxth r2, r2 + 8003822: 801a strh r2, [r3, #0] + + /* Configure VALID status for the Endpoint*/ + PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_VALID); + 8003824: 687a ldr r2, [r7, #4] + 8003826: 683b ldr r3, [r7, #0] + 8003828: 781b ldrb r3, [r3, #0] + 800382a: 009b lsls r3, r3, #2 + 800382c: 18d3 adds r3, r2, r3 + 800382e: 881b ldrh r3, [r3, #0] + 8003830: b29b uxth r3, r3 + 8003832: 4a11 ldr r2, [pc, #68] ; (8003878 ) + 8003834: 4013 ands r3, r2 + 8003836: b29c uxth r4, r3 + 8003838: 2380 movs r3, #128 ; 0x80 + 800383a: 015b lsls r3, r3, #5 + 800383c: 4063 eors r3, r4 + 800383e: b29c uxth r4, r3 + 8003840: 2380 movs r3, #128 ; 0x80 + 8003842: 019b lsls r3, r3, #6 + 8003844: 4063 eors r3, r4 + 8003846: b29c uxth r4, r3 + 8003848: 687a ldr r2, [r7, #4] + 800384a: 683b ldr r3, [r7, #0] + 800384c: 781b ldrb r3, [r3, #0] + 800384e: 009b lsls r3, r3, #2 + 8003850: 18d3 adds r3, r2, r3 + 8003852: 4a07 ldr r2, [pc, #28] ; (8003870 ) + 8003854: 4322 orrs r2, r4 + 8003856: b292 uxth r2, r2 + 8003858: 801a strh r2, [r3, #0] + } + } + + return HAL_OK; + 800385a: 2300 movs r3, #0 +} + 800385c: 0018 movs r0, r3 + 800385e: 46bd mov sp, r7 + 8003860: b003 add sp, #12 + 8003862: bd90 pop {r4, r7, pc} + 8003864: ffff8f8f .word 0xffff8f8f + 8003868: ffff80c0 .word 0xffff80c0 + 800386c: ffff8fbf .word 0xffff8fbf + 8003870: ffff8080 .word 0xffff8080 + 8003874: ffffc080 .word 0xffffc080 + 8003878: ffffbf8f .word 0xffffbf8f + +0800387c : + * @param address : new device address to be assigned + * This parameter can be a value from 0 to 255 + * @retval HAL status + */ +HAL_StatusTypeDef USB_SetDevAddress(USB_TypeDef *USBx, uint8_t address) +{ + 800387c: b580 push {r7, lr} + 800387e: b082 sub sp, #8 + 8003880: af00 add r7, sp, #0 + 8003882: 6078 str r0, [r7, #4] + 8003884: 000a movs r2, r1 + 8003886: 1cfb adds r3, r7, #3 + 8003888: 701a strb r2, [r3, #0] + if (address == 0U) + 800388a: 1cfb adds r3, r7, #3 + 800388c: 781b ldrb r3, [r3, #0] + 800388e: 2b00 cmp r3, #0 + 8003890: d103 bne.n 800389a + { + /* set device address and enable function */ + USBx->DADDR = USB_DADDR_EF; + 8003892: 687b ldr r3, [r7, #4] + 8003894: 224c movs r2, #76 ; 0x4c + 8003896: 2180 movs r1, #128 ; 0x80 + 8003898: 5299 strh r1, [r3, r2] + } + + return HAL_OK; + 800389a: 2300 movs r3, #0 +} + 800389c: 0018 movs r0, r3 + 800389e: 46bd mov sp, r7 + 80038a0: b002 add sp, #8 + 80038a2: bd80 pop {r7, pc} + +080038a4 : + * @brief USB_DevConnect : Connect the USB device by enabling the pull-up/pull-down + * @param USBx : Selected device + * @retval HAL status + */ +HAL_StatusTypeDef USB_DevConnect(USB_TypeDef *USBx) +{ + 80038a4: b580 push {r7, lr} + 80038a6: b082 sub sp, #8 + 80038a8: af00 add r7, sp, #0 + 80038aa: 6078 str r0, [r7, #4] + /* Enabling DP Pull-UP bit to Connect internal PU resistor on USB DP line */ + USBx->BCDR |= USB_BCDR_DPPU; + 80038ac: 687b ldr r3, [r7, #4] + 80038ae: 2258 movs r2, #88 ; 0x58 + 80038b0: 5a9b ldrh r3, [r3, r2] + 80038b2: b29b uxth r3, r3 + 80038b4: 4a05 ldr r2, [pc, #20] ; (80038cc ) + 80038b6: 4313 orrs r3, r2 + 80038b8: b299 uxth r1, r3 + 80038ba: 687b ldr r3, [r7, #4] + 80038bc: 2258 movs r2, #88 ; 0x58 + 80038be: 5299 strh r1, [r3, r2] + + return HAL_OK; + 80038c0: 2300 movs r3, #0 +} + 80038c2: 0018 movs r0, r3 + 80038c4: 46bd mov sp, r7 + 80038c6: b002 add sp, #8 + 80038c8: bd80 pop {r7, pc} + 80038ca: 46c0 nop ; (mov r8, r8) + 80038cc: ffff8000 .word 0xffff8000 + +080038d0 : + * @brief USB_ReadInterrupts: return the global USB interrupt status + * @param USBx : Selected device + * @retval HAL status + */ +uint32_t USB_ReadInterrupts(USB_TypeDef *USBx) +{ + 80038d0: b580 push {r7, lr} + 80038d2: b084 sub sp, #16 + 80038d4: af00 add r7, sp, #0 + 80038d6: 6078 str r0, [r7, #4] + uint32_t tmpreg; + + tmpreg = USBx->ISTR; + 80038d8: 687b ldr r3, [r7, #4] + 80038da: 2244 movs r2, #68 ; 0x44 + 80038dc: 5a9b ldrh r3, [r3, r2] + 80038de: b29b uxth r3, r3 + 80038e0: 60fb str r3, [r7, #12] + return tmpreg; + 80038e2: 68fb ldr r3, [r7, #12] +} + 80038e4: 0018 movs r0, r3 + 80038e6: 46bd mov sp, r7 + 80038e8: b004 add sp, #16 + 80038ea: bd80 pop {r7, pc} + +080038ec : + * @param USBx Selected device + * @param psetup pointer to setup packet + * @retval HAL status + */ +HAL_StatusTypeDef USB_EP0_OutStart(USB_TypeDef *USBx, uint8_t *psetup) +{ + 80038ec: b580 push {r7, lr} + 80038ee: b082 sub sp, #8 + 80038f0: af00 add r7, sp, #0 + 80038f2: 6078 str r0, [r7, #4] + 80038f4: 6039 str r1, [r7, #0] + UNUSED(psetup); + /* NOTE : - This function is not required by USB Device FS peripheral, it is used + only by USB OTG FS peripheral. + - This function is added to ensure compatibility across platforms. + */ + return HAL_OK; + 80038f6: 2300 movs r3, #0 +} + 80038f8: 0018 movs r0, r3 + 80038fa: 46bd mov sp, r7 + 80038fc: b002 add sp, #8 + 80038fe: bd80 pop {r7, pc} + +08003900 : + * @param wPMABufAddr address into PMA. + * @param wNBytes: no. of bytes to be copied. + * @retval None + */ +void USB_WritePMA(USB_TypeDef *USBx, uint8_t *pbUsrBuf, uint16_t wPMABufAddr, uint16_t wNBytes) +{ + 8003900: b580 push {r7, lr} + 8003902: b08c sub sp, #48 ; 0x30 + 8003904: af00 add r7, sp, #0 + 8003906: 60f8 str r0, [r7, #12] + 8003908: 60b9 str r1, [r7, #8] + 800390a: 0019 movs r1, r3 + 800390c: 1dbb adds r3, r7, #6 + 800390e: 801a strh r2, [r3, #0] + 8003910: 1d3b adds r3, r7, #4 + 8003912: 1c0a adds r2, r1, #0 + 8003914: 801a strh r2, [r3, #0] + uint32_t n = ((uint32_t)wNBytes + 1U) >> 1; + 8003916: 1d3b adds r3, r7, #4 + 8003918: 881b ldrh r3, [r3, #0] + 800391a: 3301 adds r3, #1 + 800391c: 085b lsrs r3, r3, #1 + 800391e: 623b str r3, [r7, #32] + uint32_t BaseAddr = (uint32_t)USBx; + 8003920: 68fb ldr r3, [r7, #12] + 8003922: 61fb str r3, [r7, #28] + uint32_t i, temp1, temp2; + __IO uint16_t *pdwVal; + uint8_t *pBuf = pbUsrBuf; + 8003924: 68bb ldr r3, [r7, #8] + 8003926: 627b str r3, [r7, #36] ; 0x24 + + pdwVal = (__IO uint16_t *)(BaseAddr + 0x400U + ((uint32_t)wPMABufAddr * PMA_ACCESS)); + 8003928: 1dbb adds r3, r7, #6 + 800392a: 881a ldrh r2, [r3, #0] + 800392c: 69fb ldr r3, [r7, #28] + 800392e: 18d3 adds r3, r2, r3 + 8003930: 2280 movs r2, #128 ; 0x80 + 8003932: 00d2 lsls r2, r2, #3 + 8003934: 4694 mov ip, r2 + 8003936: 4463 add r3, ip + 8003938: 62bb str r3, [r7, #40] ; 0x28 + + for (i = n; i != 0U; i--) + 800393a: 6a3b ldr r3, [r7, #32] + 800393c: 62fb str r3, [r7, #44] ; 0x2c + 800393e: e01b b.n 8003978 + { + temp1 = *pBuf; + 8003940: 6a7b ldr r3, [r7, #36] ; 0x24 + 8003942: 781b ldrb r3, [r3, #0] + 8003944: 61bb str r3, [r7, #24] + pBuf++; + 8003946: 6a7b ldr r3, [r7, #36] ; 0x24 + 8003948: 3301 adds r3, #1 + 800394a: 627b str r3, [r7, #36] ; 0x24 + temp2 = temp1 | ((uint16_t)((uint16_t) *pBuf << 8)); + 800394c: 6a7b ldr r3, [r7, #36] ; 0x24 + 800394e: 781b ldrb r3, [r3, #0] + 8003950: b29b uxth r3, r3 + 8003952: 021b lsls r3, r3, #8 + 8003954: b29b uxth r3, r3 + 8003956: 001a movs r2, r3 + 8003958: 69bb ldr r3, [r7, #24] + 800395a: 4313 orrs r3, r2 + 800395c: 617b str r3, [r7, #20] + *pdwVal = (uint16_t)temp2; + 800395e: 697b ldr r3, [r7, #20] + 8003960: b29a uxth r2, r3 + 8003962: 6abb ldr r3, [r7, #40] ; 0x28 + 8003964: 801a strh r2, [r3, #0] + pdwVal++; + 8003966: 6abb ldr r3, [r7, #40] ; 0x28 + 8003968: 3302 adds r3, #2 + 800396a: 62bb str r3, [r7, #40] ; 0x28 + +#if PMA_ACCESS > 1U + pdwVal++; +#endif + + pBuf++; + 800396c: 6a7b ldr r3, [r7, #36] ; 0x24 + 800396e: 3301 adds r3, #1 + 8003970: 627b str r3, [r7, #36] ; 0x24 + for (i = n; i != 0U; i--) + 8003972: 6afb ldr r3, [r7, #44] ; 0x2c + 8003974: 3b01 subs r3, #1 + 8003976: 62fb str r3, [r7, #44] ; 0x2c + 8003978: 6afb ldr r3, [r7, #44] ; 0x2c + 800397a: 2b00 cmp r3, #0 + 800397c: d1e0 bne.n 8003940 + } +} + 800397e: 46c0 nop ; (mov r8, r8) + 8003980: 46bd mov sp, r7 + 8003982: b00c add sp, #48 ; 0x30 + 8003984: bd80 pop {r7, pc} + +08003986 : + * @param wPMABufAddr address into PMA. + * @param wNBytes: no. of bytes to be copied. + * @retval None + */ +void USB_ReadPMA(USB_TypeDef *USBx, uint8_t *pbUsrBuf, uint16_t wPMABufAddr, uint16_t wNBytes) +{ + 8003986: b580 push {r7, lr} + 8003988: b08a sub sp, #40 ; 0x28 + 800398a: af00 add r7, sp, #0 + 800398c: 60f8 str r0, [r7, #12] + 800398e: 60b9 str r1, [r7, #8] + 8003990: 0019 movs r1, r3 + 8003992: 1dbb adds r3, r7, #6 + 8003994: 801a strh r2, [r3, #0] + 8003996: 1d3b adds r3, r7, #4 + 8003998: 1c0a adds r2, r1, #0 + 800399a: 801a strh r2, [r3, #0] + uint32_t n = (uint32_t)wNBytes >> 1; + 800399c: 1d3b adds r3, r7, #4 + 800399e: 881b ldrh r3, [r3, #0] + 80039a0: 085b lsrs r3, r3, #1 + 80039a2: b29b uxth r3, r3 + 80039a4: 61bb str r3, [r7, #24] + uint32_t BaseAddr = (uint32_t)USBx; + 80039a6: 68fb ldr r3, [r7, #12] + 80039a8: 617b str r3, [r7, #20] + uint32_t i, temp; + __IO uint16_t *pdwVal; + uint8_t *pBuf = pbUsrBuf; + 80039aa: 68bb ldr r3, [r7, #8] + 80039ac: 61fb str r3, [r7, #28] + + pdwVal = (__IO uint16_t *)(BaseAddr + 0x400U + ((uint32_t)wPMABufAddr * PMA_ACCESS)); + 80039ae: 1dbb adds r3, r7, #6 + 80039b0: 881a ldrh r2, [r3, #0] + 80039b2: 697b ldr r3, [r7, #20] + 80039b4: 18d3 adds r3, r2, r3 + 80039b6: 2280 movs r2, #128 ; 0x80 + 80039b8: 00d2 lsls r2, r2, #3 + 80039ba: 4694 mov ip, r2 + 80039bc: 4463 add r3, ip + 80039be: 623b str r3, [r7, #32] + + for (i = n; i != 0U; i--) + 80039c0: 69bb ldr r3, [r7, #24] + 80039c2: 627b str r3, [r7, #36] ; 0x24 + 80039c4: e018 b.n 80039f8 + { + temp = *(__IO uint16_t *)pdwVal; + 80039c6: 6a3b ldr r3, [r7, #32] + 80039c8: 881b ldrh r3, [r3, #0] + 80039ca: b29b uxth r3, r3 + 80039cc: 613b str r3, [r7, #16] + pdwVal++; + 80039ce: 6a3b ldr r3, [r7, #32] + 80039d0: 3302 adds r3, #2 + 80039d2: 623b str r3, [r7, #32] + *pBuf = (uint8_t)((temp >> 0) & 0xFFU); + 80039d4: 693b ldr r3, [r7, #16] + 80039d6: b2da uxtb r2, r3 + 80039d8: 69fb ldr r3, [r7, #28] + 80039da: 701a strb r2, [r3, #0] + pBuf++; + 80039dc: 69fb ldr r3, [r7, #28] + 80039de: 3301 adds r3, #1 + 80039e0: 61fb str r3, [r7, #28] + *pBuf = (uint8_t)((temp >> 8) & 0xFFU); + 80039e2: 693b ldr r3, [r7, #16] + 80039e4: 0a1b lsrs r3, r3, #8 + 80039e6: b2da uxtb r2, r3 + 80039e8: 69fb ldr r3, [r7, #28] + 80039ea: 701a strb r2, [r3, #0] + pBuf++; + 80039ec: 69fb ldr r3, [r7, #28] + 80039ee: 3301 adds r3, #1 + 80039f0: 61fb str r3, [r7, #28] + for (i = n; i != 0U; i--) + 80039f2: 6a7b ldr r3, [r7, #36] ; 0x24 + 80039f4: 3b01 subs r3, #1 + 80039f6: 627b str r3, [r7, #36] ; 0x24 + 80039f8: 6a7b ldr r3, [r7, #36] ; 0x24 + 80039fa: 2b00 cmp r3, #0 + 80039fc: d1e3 bne.n 80039c6 +#if PMA_ACCESS > 1U + pdwVal++; +#endif + } + + if ((wNBytes % 2U) != 0U) + 80039fe: 1d3b adds r3, r7, #4 + 8003a00: 881b ldrh r3, [r3, #0] + 8003a02: 2201 movs r2, #1 + 8003a04: 4013 ands r3, r2 + 8003a06: b29b uxth r3, r3 + 8003a08: 2b00 cmp r3, #0 + 8003a0a: d007 beq.n 8003a1c + { + temp = *pdwVal; + 8003a0c: 6a3b ldr r3, [r7, #32] + 8003a0e: 881b ldrh r3, [r3, #0] + 8003a10: b29b uxth r3, r3 + 8003a12: 613b str r3, [r7, #16] + *pBuf = (uint8_t)((temp >> 0) & 0xFFU); + 8003a14: 693b ldr r3, [r7, #16] + 8003a16: b2da uxtb r2, r3 + 8003a18: 69fb ldr r3, [r7, #28] + 8003a1a: 701a strb r2, [r3, #0] + } +} + 8003a1c: 46c0 nop ; (mov r8, r8) + 8003a1e: 46bd mov sp, r7 + 8003a20: b00a add sp, #40 ; 0x28 + 8003a22: bd80 pop {r7, pc} + +08003a24 : +static dhcp_config_t *config = NULL; + +char magic_cookie[] = {0x63,0x82,0x53,0x63}; + +static uint32_t get_ip(const uint8_t *pnt) +{ + 8003a24: b580 push {r7, lr} + 8003a26: b084 sub sp, #16 + 8003a28: af00 add r7, sp, #0 + 8003a2a: 6078 str r0, [r7, #4] + uint32_t result; + memcpy(&result, pnt, sizeof(result)); + 8003a2c: 6879 ldr r1, [r7, #4] + 8003a2e: 230c movs r3, #12 + 8003a30: 18fb adds r3, r7, r3 + 8003a32: 2204 movs r2, #4 + 8003a34: 0018 movs r0, r3 + 8003a36: f00c f934 bl 800fca2 + return result; + 8003a3a: 68fb ldr r3, [r7, #12] +} + 8003a3c: 0018 movs r0, r3 + 8003a3e: 46bd mov sp, r7 + 8003a40: b004 add sp, #16 + 8003a42: bd80 pop {r7, pc} + +08003a44 : + +static void set_ip(uint8_t *pnt, uint32_t value) +{ + 8003a44: b580 push {r7, lr} + 8003a46: b082 sub sp, #8 + 8003a48: af00 add r7, sp, #0 + 8003a4a: 6078 str r0, [r7, #4] + 8003a4c: 6039 str r1, [r7, #0] + memcpy(pnt, &value, sizeof(value)); + 8003a4e: 0039 movs r1, r7 + 8003a50: 687b ldr r3, [r7, #4] + 8003a52: 2204 movs r2, #4 + 8003a54: 0018 movs r0, r3 + 8003a56: f00c f924 bl 800fca2 +} + 8003a5a: 46c0 nop ; (mov r8, r8) + 8003a5c: 46bd mov sp, r7 + 8003a5e: b002 add sp, #8 + 8003a60: bd80 pop {r7, pc} + ... + +08003a64 : + +static dhcp_entry_t *entry_by_ip(uint32_t ip) +{ + 8003a64: b580 push {r7, lr} + 8003a66: b084 sub sp, #16 + 8003a68: af00 add r7, sp, #0 + 8003a6a: 6078 str r0, [r7, #4] + int i; + for (i = 0; i < config->num_entry; i++) + 8003a6c: 2300 movs r3, #0 + 8003a6e: 60fb str r3, [r7, #12] + 8003a70: e01d b.n 8003aae + if (get_ip(config->entries[i].addr) == ip) + 8003a72: 4b14 ldr r3, [pc, #80] ; (8003ac4 ) + 8003a74: 681b ldr r3, [r3, #0] + 8003a76: 6959 ldr r1, [r3, #20] + 8003a78: 68fa ldr r2, [r7, #12] + 8003a7a: 0013 movs r3, r2 + 8003a7c: 009b lsls r3, r3, #2 + 8003a7e: 189b adds r3, r3, r2 + 8003a80: 009b lsls r3, r3, #2 + 8003a82: 18cb adds r3, r1, r3 + 8003a84: 3306 adds r3, #6 + 8003a86: 0018 movs r0, r3 + 8003a88: f7ff ffcc bl 8003a24 + 8003a8c: 0002 movs r2, r0 + 8003a8e: 687b ldr r3, [r7, #4] + 8003a90: 4293 cmp r3, r2 + 8003a92: d109 bne.n 8003aa8 + return &config->entries[i]; + 8003a94: 4b0b ldr r3, [pc, #44] ; (8003ac4 ) + 8003a96: 681b ldr r3, [r3, #0] + 8003a98: 6959 ldr r1, [r3, #20] + 8003a9a: 68fa ldr r2, [r7, #12] + 8003a9c: 0013 movs r3, r2 + 8003a9e: 009b lsls r3, r3, #2 + 8003aa0: 189b adds r3, r3, r2 + 8003aa2: 009b lsls r3, r3, #2 + 8003aa4: 18cb adds r3, r1, r3 + 8003aa6: e009 b.n 8003abc + for (i = 0; i < config->num_entry; i++) + 8003aa8: 68fb ldr r3, [r7, #12] + 8003aaa: 3301 adds r3, #1 + 8003aac: 60fb str r3, [r7, #12] + 8003aae: 4b05 ldr r3, [pc, #20] ; (8003ac4 ) + 8003ab0: 681b ldr r3, [r3, #0] + 8003ab2: 691b ldr r3, [r3, #16] + 8003ab4: 68fa ldr r2, [r7, #12] + 8003ab6: 429a cmp r2, r3 + 8003ab8: dbdb blt.n 8003a72 + return NULL; + 8003aba: 2300 movs r3, #0 +} + 8003abc: 0018 movs r0, r3 + 8003abe: 46bd mov sp, r7 + 8003ac0: b004 add sp, #16 + 8003ac2: bd80 pop {r7, pc} + 8003ac4: 200000bc .word 0x200000bc + +08003ac8 : + +static dhcp_entry_t *entry_by_mac(uint8_t *mac) +{ + 8003ac8: b580 push {r7, lr} + 8003aca: b084 sub sp, #16 + 8003acc: af00 add r7, sp, #0 + 8003ace: 6078 str r0, [r7, #4] + int i; + for (i = 0; i < config->num_entry; i++) + 8003ad0: 2300 movs r3, #0 + 8003ad2: 60fb str r3, [r7, #12] + 8003ad4: e01d b.n 8003b12 + if (memcmp(config->entries[i].mac, mac, 6) == 0) + 8003ad6: 4b14 ldr r3, [pc, #80] ; (8003b28 ) + 8003ad8: 681b ldr r3, [r3, #0] + 8003ada: 6959 ldr r1, [r3, #20] + 8003adc: 68fa ldr r2, [r7, #12] + 8003ade: 0013 movs r3, r2 + 8003ae0: 009b lsls r3, r3, #2 + 8003ae2: 189b adds r3, r3, r2 + 8003ae4: 009b lsls r3, r3, #2 + 8003ae6: 18cb adds r3, r1, r3 + 8003ae8: 0018 movs r0, r3 + 8003aea: 687b ldr r3, [r7, #4] + 8003aec: 2206 movs r2, #6 + 8003aee: 0019 movs r1, r3 + 8003af0: f00c f8c8 bl 800fc84 + 8003af4: 1e03 subs r3, r0, #0 + 8003af6: d109 bne.n 8003b0c + return &config->entries[i]; + 8003af8: 4b0b ldr r3, [pc, #44] ; (8003b28 ) + 8003afa: 681b ldr r3, [r3, #0] + 8003afc: 6959 ldr r1, [r3, #20] + 8003afe: 68fa ldr r2, [r7, #12] + 8003b00: 0013 movs r3, r2 + 8003b02: 009b lsls r3, r3, #2 + 8003b04: 189b adds r3, r3, r2 + 8003b06: 009b lsls r3, r3, #2 + 8003b08: 18cb adds r3, r1, r3 + 8003b0a: e009 b.n 8003b20 + for (i = 0; i < config->num_entry; i++) + 8003b0c: 68fb ldr r3, [r7, #12] + 8003b0e: 3301 adds r3, #1 + 8003b10: 60fb str r3, [r7, #12] + 8003b12: 4b05 ldr r3, [pc, #20] ; (8003b28 ) + 8003b14: 681b ldr r3, [r3, #0] + 8003b16: 691b ldr r3, [r3, #16] + 8003b18: 68fa ldr r2, [r7, #12] + 8003b1a: 429a cmp r2, r3 + 8003b1c: dbdb blt.n 8003ad6 + return NULL; + 8003b1e: 2300 movs r3, #0 +} + 8003b20: 0018 movs r0, r3 + 8003b22: 46bd mov sp, r7 + 8003b24: b004 add sp, #16 + 8003b26: bd80 pop {r7, pc} + 8003b28: 200000bc .word 0x200000bc + +08003b2c : + +static __inline bool is_vacant(dhcp_entry_t *entry) +{ + 8003b2c: b580 push {r7, lr} + 8003b2e: b082 sub sp, #8 + 8003b30: af00 add r7, sp, #0 + 8003b32: 6078 str r0, [r7, #4] + return memcmp("\0\0\0\0\0", entry->mac, 6) == 0; + 8003b34: 6879 ldr r1, [r7, #4] + 8003b36: 4b06 ldr r3, [pc, #24] ; (8003b50 ) + 8003b38: 2206 movs r2, #6 + 8003b3a: 0018 movs r0, r3 + 8003b3c: f00c f8a2 bl 800fc84 + 8003b40: 0003 movs r3, r0 + 8003b42: 425a negs r2, r3 + 8003b44: 4153 adcs r3, r2 + 8003b46: b2db uxtb r3, r3 +} + 8003b48: 0018 movs r0, r3 + 8003b4a: 46bd mov sp, r7 + 8003b4c: b002 add sp, #8 + 8003b4e: bd80 pop {r7, pc} + 8003b50: 0800fcfc .word 0x0800fcfc + +08003b54 : + +static dhcp_entry_t *vacant_address() +{ + 8003b54: b580 push {r7, lr} + 8003b56: b082 sub sp, #8 + 8003b58: af00 add r7, sp, #0 + int i; + for (i = 0; i < config->num_entry; i++) + 8003b5a: 2300 movs r3, #0 + 8003b5c: 607b str r3, [r7, #4] + 8003b5e: e01a b.n 8003b96 + if (is_vacant(config->entries + i)) + 8003b60: 4b12 ldr r3, [pc, #72] ; (8003bac ) + 8003b62: 681b ldr r3, [r3, #0] + 8003b64: 6959 ldr r1, [r3, #20] + 8003b66: 687a ldr r2, [r7, #4] + 8003b68: 0013 movs r3, r2 + 8003b6a: 009b lsls r3, r3, #2 + 8003b6c: 189b adds r3, r3, r2 + 8003b6e: 009b lsls r3, r3, #2 + 8003b70: 18cb adds r3, r1, r3 + 8003b72: 0018 movs r0, r3 + 8003b74: f7ff ffda bl 8003b2c + 8003b78: 1e03 subs r3, r0, #0 + 8003b7a: d009 beq.n 8003b90 + return config->entries + i; + 8003b7c: 4b0b ldr r3, [pc, #44] ; (8003bac ) + 8003b7e: 681b ldr r3, [r3, #0] + 8003b80: 6959 ldr r1, [r3, #20] + 8003b82: 687a ldr r2, [r7, #4] + 8003b84: 0013 movs r3, r2 + 8003b86: 009b lsls r3, r3, #2 + 8003b88: 189b adds r3, r3, r2 + 8003b8a: 009b lsls r3, r3, #2 + 8003b8c: 18cb adds r3, r1, r3 + 8003b8e: e009 b.n 8003ba4 + for (i = 0; i < config->num_entry; i++) + 8003b90: 687b ldr r3, [r7, #4] + 8003b92: 3301 adds r3, #1 + 8003b94: 607b str r3, [r7, #4] + 8003b96: 4b05 ldr r3, [pc, #20] ; (8003bac ) + 8003b98: 681b ldr r3, [r3, #0] + 8003b9a: 691b ldr r3, [r3, #16] + 8003b9c: 687a ldr r2, [r7, #4] + 8003b9e: 429a cmp r2, r3 + 8003ba0: dbde blt.n 8003b60 + return NULL; + 8003ba2: 2300 movs r3, #0 +} + 8003ba4: 0018 movs r0, r3 + 8003ba6: 46bd mov sp, r7 + 8003ba8: b002 add sp, #8 + 8003baa: bd80 pop {r7, pc} + 8003bac: 200000bc .word 0x200000bc + +08003bb0 : + +static __inline void free_entry(dhcp_entry_t *entry) +{ + 8003bb0: b580 push {r7, lr} + 8003bb2: b082 sub sp, #8 + 8003bb4: af00 add r7, sp, #0 + 8003bb6: 6078 str r0, [r7, #4] + memset(entry->mac, 0, 6); + 8003bb8: 687b ldr r3, [r7, #4] + 8003bba: 2206 movs r2, #6 + 8003bbc: 2100 movs r1, #0 + 8003bbe: 0018 movs r0, r3 + 8003bc0: f00c f878 bl 800fcb4 +} + 8003bc4: 46c0 nop ; (mov r8, r8) + 8003bc6: 46bd mov sp, r7 + 8003bc8: b002 add sp, #8 + 8003bca: bd80 pop {r7, pc} + +08003bcc : + +uint8_t *find_dhcp_option(uint8_t *attrs, int size, uint8_t attr) +{ + 8003bcc: b580 push {r7, lr} + 8003bce: b086 sub sp, #24 + 8003bd0: af00 add r7, sp, #0 + 8003bd2: 60f8 str r0, [r7, #12] + 8003bd4: 60b9 str r1, [r7, #8] + 8003bd6: 1dfb adds r3, r7, #7 + 8003bd8: 701a strb r2, [r3, #0] + int i = 0; + 8003bda: 2300 movs r3, #0 + 8003bdc: 617b str r3, [r7, #20] + while ((i + 1) < size) + 8003bde: e01d b.n 8003c1c + { + int next = i + attrs[i + 1] + 2; + 8003be0: 697b ldr r3, [r7, #20] + 8003be2: 3301 adds r3, #1 + 8003be4: 68fa ldr r2, [r7, #12] + 8003be6: 18d3 adds r3, r2, r3 + 8003be8: 781b ldrb r3, [r3, #0] + 8003bea: 001a movs r2, r3 + 8003bec: 697b ldr r3, [r7, #20] + 8003bee: 18d3 adds r3, r2, r3 + 8003bf0: 3302 adds r3, #2 + 8003bf2: 613b str r3, [r7, #16] + if (next > size) return NULL; + 8003bf4: 693a ldr r2, [r7, #16] + 8003bf6: 68bb ldr r3, [r7, #8] + 8003bf8: 429a cmp r2, r3 + 8003bfa: dd01 ble.n 8003c00 + 8003bfc: 2300 movs r3, #0 + 8003bfe: e013 b.n 8003c28 + if (attrs[i] == attr) + 8003c00: 697b ldr r3, [r7, #20] + 8003c02: 68fa ldr r2, [r7, #12] + 8003c04: 18d3 adds r3, r2, r3 + 8003c06: 781b ldrb r3, [r3, #0] + 8003c08: 1dfa adds r2, r7, #7 + 8003c0a: 7812 ldrb r2, [r2, #0] + 8003c0c: 429a cmp r2, r3 + 8003c0e: d103 bne.n 8003c18 + return attrs + i; + 8003c10: 697b ldr r3, [r7, #20] + 8003c12: 68fa ldr r2, [r7, #12] + 8003c14: 18d3 adds r3, r2, r3 + 8003c16: e007 b.n 8003c28 + i = next; + 8003c18: 693b ldr r3, [r7, #16] + 8003c1a: 617b str r3, [r7, #20] + while ((i + 1) < size) + 8003c1c: 697b ldr r3, [r7, #20] + 8003c1e: 3301 adds r3, #1 + 8003c20: 68ba ldr r2, [r7, #8] + 8003c22: 429a cmp r2, r3 + 8003c24: dcdc bgt.n 8003be0 + } + return NULL; + 8003c26: 2300 movs r3, #0 +} + 8003c28: 0018 movs r0, r3 + 8003c2a: 46bd mov sp, r7 + 8003c2c: b006 add sp, #24 + 8003c2e: bd80 pop {r7, pc} + +08003c30 : + uint32_t dns, + int lease_time, + uint32_t serverid, + uint32_t router, + uint32_t subnet) +{ + 8003c30: b580 push {r7, lr} + 8003c32: b086 sub sp, #24 + 8003c34: af00 add r7, sp, #0 + 8003c36: 60f8 str r0, [r7, #12] + 8003c38: 607a str r2, [r7, #4] + 8003c3a: 603b str r3, [r7, #0] + 8003c3c: 200b movs r0, #11 + 8003c3e: 183b adds r3, r7, r0 + 8003c40: 1c0a adds r2, r1, #0 + 8003c42: 701a strb r2, [r3, #0] + uint8_t *ptr = (uint8_t *)dest; + 8003c44: 68fb ldr r3, [r7, #12] + 8003c46: 617b str r3, [r7, #20] + /* ACK message type */ + *ptr++ = 53; + 8003c48: 697b ldr r3, [r7, #20] + 8003c4a: 1c5a adds r2, r3, #1 + 8003c4c: 617a str r2, [r7, #20] + 8003c4e: 2235 movs r2, #53 ; 0x35 + 8003c50: 701a strb r2, [r3, #0] + *ptr++ = 1; + 8003c52: 697b ldr r3, [r7, #20] + 8003c54: 1c5a adds r2, r3, #1 + 8003c56: 617a str r2, [r7, #20] + 8003c58: 2201 movs r2, #1 + 8003c5a: 701a strb r2, [r3, #0] + *ptr++ = msg_type; + 8003c5c: 697b ldr r3, [r7, #20] + 8003c5e: 1c5a adds r2, r3, #1 + 8003c60: 617a str r2, [r7, #20] + 8003c62: 183a adds r2, r7, r0 + 8003c64: 7812 ldrb r2, [r2, #0] + 8003c66: 701a strb r2, [r3, #0] + + /* dhcp server identifier */ + *ptr++ = DHCP_SERVERID; + 8003c68: 697b ldr r3, [r7, #20] + 8003c6a: 1c5a adds r2, r3, #1 + 8003c6c: 617a str r2, [r7, #20] + 8003c6e: 2236 movs r2, #54 ; 0x36 + 8003c70: 701a strb r2, [r3, #0] + *ptr++ = 4; + 8003c72: 697b ldr r3, [r7, #20] + 8003c74: 1c5a adds r2, r3, #1 + 8003c76: 617a str r2, [r7, #20] + 8003c78: 2204 movs r2, #4 + 8003c7a: 701a strb r2, [r3, #0] + set_ip(ptr, serverid); + 8003c7c: 6a7a ldr r2, [r7, #36] ; 0x24 + 8003c7e: 697b ldr r3, [r7, #20] + 8003c80: 0011 movs r1, r2 + 8003c82: 0018 movs r0, r3 + 8003c84: f7ff fede bl 8003a44 + ptr += 4; + 8003c88: 697b ldr r3, [r7, #20] + 8003c8a: 3304 adds r3, #4 + 8003c8c: 617b str r3, [r7, #20] + + /* lease time */ + *ptr++ = DHCP_LEASETIME; + 8003c8e: 697b ldr r3, [r7, #20] + 8003c90: 1c5a adds r2, r3, #1 + 8003c92: 617a str r2, [r7, #20] + 8003c94: 2233 movs r2, #51 ; 0x33 + 8003c96: 701a strb r2, [r3, #0] + *ptr++ = 4; + 8003c98: 697b ldr r3, [r7, #20] + 8003c9a: 1c5a adds r2, r3, #1 + 8003c9c: 617a str r2, [r7, #20] + 8003c9e: 2204 movs r2, #4 + 8003ca0: 701a strb r2, [r3, #0] + *ptr++ = (lease_time >> 24) & 0xFF; + 8003ca2: 6a3b ldr r3, [r7, #32] + 8003ca4: 0e19 lsrs r1, r3, #24 + 8003ca6: 697b ldr r3, [r7, #20] + 8003ca8: 1c5a adds r2, r3, #1 + 8003caa: 617a str r2, [r7, #20] + 8003cac: b2ca uxtb r2, r1 + 8003cae: 701a strb r2, [r3, #0] + *ptr++ = (lease_time >> 16) & 0xFF; + 8003cb0: 6a3b ldr r3, [r7, #32] + 8003cb2: 1419 asrs r1, r3, #16 + 8003cb4: 697b ldr r3, [r7, #20] + 8003cb6: 1c5a adds r2, r3, #1 + 8003cb8: 617a str r2, [r7, #20] + 8003cba: b2ca uxtb r2, r1 + 8003cbc: 701a strb r2, [r3, #0] + *ptr++ = (lease_time >> 8) & 0xFF; + 8003cbe: 6a3b ldr r3, [r7, #32] + 8003cc0: 1219 asrs r1, r3, #8 + 8003cc2: 697b ldr r3, [r7, #20] + 8003cc4: 1c5a adds r2, r3, #1 + 8003cc6: 617a str r2, [r7, #20] + 8003cc8: b2ca uxtb r2, r1 + 8003cca: 701a strb r2, [r3, #0] + *ptr++ = (lease_time >> 0) & 0xFF; + 8003ccc: 697b ldr r3, [r7, #20] + 8003cce: 1c5a adds r2, r3, #1 + 8003cd0: 617a str r2, [r7, #20] + 8003cd2: 6a3a ldr r2, [r7, #32] + 8003cd4: b2d2 uxtb r2, r2 + 8003cd6: 701a strb r2, [r3, #0] + + /* subnet mask */ + *ptr++ = DHCP_SUBNETMASK; + 8003cd8: 697b ldr r3, [r7, #20] + 8003cda: 1c5a adds r2, r3, #1 + 8003cdc: 617a str r2, [r7, #20] + 8003cde: 2201 movs r2, #1 + 8003ce0: 701a strb r2, [r3, #0] + *ptr++ = 4; + 8003ce2: 697b ldr r3, [r7, #20] + 8003ce4: 1c5a adds r2, r3, #1 + 8003ce6: 617a str r2, [r7, #20] + 8003ce8: 2204 movs r2, #4 + 8003cea: 701a strb r2, [r3, #0] + set_ip(ptr, subnet); + 8003cec: 6afa ldr r2, [r7, #44] ; 0x2c + 8003cee: 697b ldr r3, [r7, #20] + 8003cf0: 0011 movs r1, r2 + 8003cf2: 0018 movs r0, r3 + 8003cf4: f7ff fea6 bl 8003a44 + ptr += 4; + 8003cf8: 697b ldr r3, [r7, #20] + 8003cfa: 3304 adds r3, #4 + 8003cfc: 617b str r3, [r7, #20] + + /* router */ + if (router != 0) + 8003cfe: 6abb ldr r3, [r7, #40] ; 0x28 + 8003d00: 2b00 cmp r3, #0 + 8003d02: d012 beq.n 8003d2a + { + *ptr++ = DHCP_ROUTER; + 8003d04: 697b ldr r3, [r7, #20] + 8003d06: 1c5a adds r2, r3, #1 + 8003d08: 617a str r2, [r7, #20] + 8003d0a: 2203 movs r2, #3 + 8003d0c: 701a strb r2, [r3, #0] + *ptr++ = 4; + 8003d0e: 697b ldr r3, [r7, #20] + 8003d10: 1c5a adds r2, r3, #1 + 8003d12: 617a str r2, [r7, #20] + 8003d14: 2204 movs r2, #4 + 8003d16: 701a strb r2, [r3, #0] + set_ip(ptr, router); + 8003d18: 6aba ldr r2, [r7, #40] ; 0x28 + 8003d1a: 697b ldr r3, [r7, #20] + 8003d1c: 0011 movs r1, r2 + 8003d1e: 0018 movs r0, r3 + 8003d20: f7ff fe90 bl 8003a44 + ptr += 4; + 8003d24: 697b ldr r3, [r7, #20] + 8003d26: 3304 adds r3, #4 + 8003d28: 617b str r3, [r7, #20] + } + + /* domain name */ + if (domain != NULL) + 8003d2a: 687b ldr r3, [r7, #4] + 8003d2c: 2b00 cmp r3, #0 + 8003d2e: d01a beq.n 8003d66 + { + int len = strlen(domain); + 8003d30: 687b ldr r3, [r7, #4] + 8003d32: 0018 movs r0, r3 + 8003d34: f7fc f9f2 bl 800011c + 8003d38: 0003 movs r3, r0 + 8003d3a: 613b str r3, [r7, #16] + *ptr++ = DHCP_DNSDOMAIN; + 8003d3c: 697b ldr r3, [r7, #20] + 8003d3e: 1c5a adds r2, r3, #1 + 8003d40: 617a str r2, [r7, #20] + 8003d42: 220f movs r2, #15 + 8003d44: 701a strb r2, [r3, #0] + *ptr++ = len; + 8003d46: 697b ldr r3, [r7, #20] + 8003d48: 1c5a adds r2, r3, #1 + 8003d4a: 617a str r2, [r7, #20] + 8003d4c: 693a ldr r2, [r7, #16] + 8003d4e: b2d2 uxtb r2, r2 + 8003d50: 701a strb r2, [r3, #0] + memcpy(ptr, domain, len); + 8003d52: 693a ldr r2, [r7, #16] + 8003d54: 6879 ldr r1, [r7, #4] + 8003d56: 697b ldr r3, [r7, #20] + 8003d58: 0018 movs r0, r3 + 8003d5a: f00b ffa2 bl 800fca2 + ptr += len; + 8003d5e: 693b ldr r3, [r7, #16] + 8003d60: 697a ldr r2, [r7, #20] + 8003d62: 18d3 adds r3, r2, r3 + 8003d64: 617b str r3, [r7, #20] + } + + /* domain name server (DNS) */ + if (dns != 0) + 8003d66: 683b ldr r3, [r7, #0] + 8003d68: 2b00 cmp r3, #0 + 8003d6a: d012 beq.n 8003d92 + { + *ptr++ = DHCP_DNSSERVER; + 8003d6c: 697b ldr r3, [r7, #20] + 8003d6e: 1c5a adds r2, r3, #1 + 8003d70: 617a str r2, [r7, #20] + 8003d72: 2206 movs r2, #6 + 8003d74: 701a strb r2, [r3, #0] + *ptr++ = 4; + 8003d76: 697b ldr r3, [r7, #20] + 8003d78: 1c5a adds r2, r3, #1 + 8003d7a: 617a str r2, [r7, #20] + 8003d7c: 2204 movs r2, #4 + 8003d7e: 701a strb r2, [r3, #0] + set_ip(ptr, dns); + 8003d80: 683a ldr r2, [r7, #0] + 8003d82: 697b ldr r3, [r7, #20] + 8003d84: 0011 movs r1, r2 + 8003d86: 0018 movs r0, r3 + 8003d88: f7ff fe5c bl 8003a44 + ptr += 4; + 8003d8c: 697b ldr r3, [r7, #20] + 8003d8e: 3304 adds r3, #4 + 8003d90: 617b str r3, [r7, #20] + } + + /* end */ + *ptr++ = DHCP_END; + 8003d92: 697b ldr r3, [r7, #20] + 8003d94: 1c5a adds r2, r3, #1 + 8003d96: 617a str r2, [r7, #20] + 8003d98: 22ff movs r2, #255 ; 0xff + 8003d9a: 701a strb r2, [r3, #0] + return ptr - (uint8_t *)dest; + 8003d9c: 697a ldr r2, [r7, #20] + 8003d9e: 68fb ldr r3, [r7, #12] + 8003da0: 1ad3 subs r3, r2, r3 +} + 8003da2: 0018 movs r0, r3 + 8003da4: 46bd mov sp, r7 + 8003da6: b006 add sp, #24 + 8003da8: bd80 pop {r7, pc} + ... + +08003dac : + +static void udp_recv_proc(void *arg, struct udp_pcb *upcb, struct pbuf *p, struct ip_addr *addr, u16_t port) +{ + 8003dac: b5f0 push {r4, r5, r6, r7, lr} + 8003dae: 46c6 mov lr, r8 + 8003db0: b500 push {lr} + 8003db2: b08e sub sp, #56 ; 0x38 + 8003db4: af04 add r7, sp, #16 + 8003db6: 6178 str r0, [r7, #20] + 8003db8: 6139 str r1, [r7, #16] + 8003dba: 60fa str r2, [r7, #12] + 8003dbc: 60bb str r3, [r7, #8] + uint8_t *ptr; + dhcp_entry_t *entry; + struct pbuf *pp; + + int n = p->len; + 8003dbe: 68fb ldr r3, [r7, #12] + 8003dc0: 895b ldrh r3, [r3, #10] + 8003dc2: 623b str r3, [r7, #32] + if (n > sizeof(dhcp_data)) n = sizeof(dhcp_data); + 8003dc4: 6a3a ldr r2, [r7, #32] + 8003dc6: 2381 movs r3, #129 ; 0x81 + 8003dc8: 009b lsls r3, r3, #2 + 8003dca: 429a cmp r2, r3 + 8003dcc: d902 bls.n 8003dd4 + 8003dce: 2381 movs r3, #129 ; 0x81 + 8003dd0: 009b lsls r3, r3, #2 + 8003dd2: 623b str r3, [r7, #32] + memcpy(&dhcp_data, p->payload, n); + 8003dd4: 68fb ldr r3, [r7, #12] + 8003dd6: 6859 ldr r1, [r3, #4] + 8003dd8: 6a3a ldr r2, [r7, #32] + 8003dda: 4baa ldr r3, [pc, #680] ; (8004084 ) + 8003ddc: 0018 movs r0, r3 + 8003dde: f00b ff60 bl 800fca2 + switch (dhcp_data.dp_options[2]) + 8003de2: 4ba8 ldr r3, [pc, #672] ; (8004084 ) + 8003de4: 22f2 movs r2, #242 ; 0xf2 + 8003de6: 5c9b ldrb r3, [r3, r2] + 8003de8: 2b01 cmp r3, #1 + 8003dea: d003 beq.n 8003df4 + 8003dec: 2b03 cmp r3, #3 + 8003dee: d100 bne.n 8003df2 + 8003df0: e081 b.n 8003ef6 + udp_sendto(upcb, pp, IP_ADDR_BROADCAST, port); + pbuf_free(pp); + break; + + default: + break; + 8003df2: e13d b.n 8004070 + entry = entry_by_mac(dhcp_data.dp_chaddr); + 8003df4: 4ba4 ldr r3, [pc, #656] ; (8004088 ) + 8003df6: 0018 movs r0, r3 + 8003df8: f7ff fe66 bl 8003ac8 + 8003dfc: 0003 movs r3, r0 + 8003dfe: 627b str r3, [r7, #36] ; 0x24 + if (entry == NULL) entry = vacant_address(); + 8003e00: 6a7b ldr r3, [r7, #36] ; 0x24 + 8003e02: 2b00 cmp r3, #0 + 8003e04: d103 bne.n 8003e0e + 8003e06: f7ff fea5 bl 8003b54 + 8003e0a: 0003 movs r3, r0 + 8003e0c: 627b str r3, [r7, #36] ; 0x24 + if (entry == NULL) break; + 8003e0e: 6a7b ldr r3, [r7, #36] ; 0x24 + 8003e10: 2b00 cmp r3, #0 + 8003e12: d100 bne.n 8003e16 + 8003e14: e11f b.n 8004056 + dhcp_data.dp_op = 2; /* reply */ + 8003e16: 4b9b ldr r3, [pc, #620] ; (8004084 ) + 8003e18: 2202 movs r2, #2 + 8003e1a: 701a strb r2, [r3, #0] + dhcp_data.dp_secs = 0; + 8003e1c: 4b99 ldr r3, [pc, #612] ; (8004084 ) + 8003e1e: 2200 movs r2, #0 + 8003e20: 811a strh r2, [r3, #8] + dhcp_data.dp_flags = 0; + 8003e22: 4b98 ldr r3, [pc, #608] ; (8004084 ) + 8003e24: 2200 movs r2, #0 + 8003e26: 815a strh r2, [r3, #10] + set_ip(dhcp_data.dp_yiaddr, get_ip(entry->addr)); + 8003e28: 6a7b ldr r3, [r7, #36] ; 0x24 + 8003e2a: 3306 adds r3, #6 + 8003e2c: 0018 movs r0, r3 + 8003e2e: f7ff fdf9 bl 8003a24 + 8003e32: 0002 movs r2, r0 + 8003e34: 4b95 ldr r3, [pc, #596] ; (800408c ) + 8003e36: 0011 movs r1, r2 + 8003e38: 0018 movs r0, r3 + 8003e3a: f7ff fe03 bl 8003a44 + memcpy(dhcp_data.dp_magic, magic_cookie, 4); + 8003e3e: 4b94 ldr r3, [pc, #592] ; (8004090 ) + 8003e40: 681a ldr r2, [r3, #0] + 8003e42: 4b90 ldr r3, [pc, #576] ; (8004084 ) + 8003e44: 21ec movs r1, #236 ; 0xec + 8003e46: 505a str r2, [r3, r1] + memset(dhcp_data.dp_options, 0, sizeof(dhcp_data.dp_options)); + 8003e48: 2314 movs r3, #20 + 8003e4a: 33ff adds r3, #255 ; 0xff + 8003e4c: 001a movs r2, r3 + 8003e4e: 4b91 ldr r3, [pc, #580] ; (8004094 ) + 8003e50: 2100 movs r1, #0 + 8003e52: 0018 movs r0, r3 + 8003e54: f00b ff2e bl 800fcb4 + config->domain, + 8003e58: 4b8f ldr r3, [pc, #572] ; (8004098 ) + 8003e5a: 681b ldr r3, [r3, #0] + fill_options(dhcp_data.dp_options, + 8003e5c: 68dc ldr r4, [r3, #12] + get_ip(config->dns), + 8003e5e: 4b8e ldr r3, [pc, #568] ; (8004098 ) + 8003e60: 681b ldr r3, [r3, #0] + 8003e62: 3306 adds r3, #6 + fill_options(dhcp_data.dp_options, + 8003e64: 0018 movs r0, r3 + 8003e66: f7ff fddd bl 8003a24 + 8003e6a: 6078 str r0, [r7, #4] + entry->lease, + 8003e6c: 6a7b ldr r3, [r7, #36] ; 0x24 + 8003e6e: 691b ldr r3, [r3, #16] + fill_options(dhcp_data.dp_options, + 8003e70: 001d movs r5, r3 + get_ip(config->addr), + 8003e72: 4b89 ldr r3, [pc, #548] ; (8004098 ) + 8003e74: 681b ldr r3, [r3, #0] + fill_options(dhcp_data.dp_options, + 8003e76: 0018 movs r0, r3 + 8003e78: f7ff fdd4 bl 8003a24 + 8003e7c: 0006 movs r6, r0 + get_ip(config->addr), + 8003e7e: 4b86 ldr r3, [pc, #536] ; (8004098 ) + 8003e80: 681b ldr r3, [r3, #0] + fill_options(dhcp_data.dp_options, + 8003e82: 0018 movs r0, r3 + 8003e84: f7ff fdce bl 8003a24 + 8003e88: 4680 mov r8, r0 + get_ip(entry->subnet)); + 8003e8a: 6a7b ldr r3, [r7, #36] ; 0x24 + 8003e8c: 330a adds r3, #10 + fill_options(dhcp_data.dp_options, + 8003e8e: 0018 movs r0, r3 + 8003e90: f7ff fdc8 bl 8003a24 + 8003e94: 0003 movs r3, r0 + 8003e96: 487f ldr r0, [pc, #508] ; (8004094 ) + 8003e98: 9303 str r3, [sp, #12] + 8003e9a: 4642 mov r2, r8 + 8003e9c: 9202 str r2, [sp, #8] + 8003e9e: 9601 str r6, [sp, #4] + 8003ea0: 9500 str r5, [sp, #0] + 8003ea2: 687b ldr r3, [r7, #4] + 8003ea4: 0022 movs r2, r4 + 8003ea6: 2102 movs r1, #2 + 8003ea8: f7ff fec2 bl 8003c30 + pp = pbuf_alloc(PBUF_TRANSPORT, sizeof(dhcp_data), PBUF_POOL); + 8003eac: 2381 movs r3, #129 ; 0x81 + 8003eae: 009b lsls r3, r3, #2 + 8003eb0: 2203 movs r2, #3 + 8003eb2: 0019 movs r1, r3 + 8003eb4: 2000 movs r0, #0 + 8003eb6: f001 f969 bl 800518c + 8003eba: 0003 movs r3, r0 + 8003ebc: 61bb str r3, [r7, #24] + if (pp == NULL) break; + 8003ebe: 69bb ldr r3, [r7, #24] + 8003ec0: 2b00 cmp r3, #0 + 8003ec2: d100 bne.n 8003ec6 + 8003ec4: e0c9 b.n 800405a + memcpy(pp->payload, &dhcp_data, sizeof(dhcp_data)); + 8003ec6: 69bb ldr r3, [r7, #24] + 8003ec8: 6858 ldr r0, [r3, #4] + 8003eca: 2381 movs r3, #129 ; 0x81 + 8003ecc: 009a lsls r2, r3, #2 + 8003ece: 4b6d ldr r3, [pc, #436] ; (8004084 ) + 8003ed0: 0019 movs r1, r3 + 8003ed2: f00b fee6 bl 800fca2 + udp_sendto(upcb, pp, IP_ADDR_BROADCAST, port); + 8003ed6: 2338 movs r3, #56 ; 0x38 + 8003ed8: 2208 movs r2, #8 + 8003eda: 4694 mov ip, r2 + 8003edc: 44bc add ip, r7 + 8003ede: 4463 add r3, ip + 8003ee0: 881b ldrh r3, [r3, #0] + 8003ee2: 4a6e ldr r2, [pc, #440] ; (800409c ) + 8003ee4: 69b9 ldr r1, [r7, #24] + 8003ee6: 6938 ldr r0, [r7, #16] + 8003ee8: f006 fe80 bl 800abec + pbuf_free(pp); + 8003eec: 69bb ldr r3, [r7, #24] + 8003eee: 0018 movs r0, r3 + 8003ef0: f001 fbd8 bl 80056a4 + break; + 8003ef4: e0bc b.n 8004070 + ptr = find_dhcp_option(dhcp_data.dp_options, sizeof(dhcp_data.dp_options), DHCP_IPADDRESS); + 8003ef6: 2314 movs r3, #20 + 8003ef8: 33ff adds r3, #255 ; 0xff + 8003efa: 0019 movs r1, r3 + 8003efc: 4b65 ldr r3, [pc, #404] ; (8004094 ) + 8003efe: 2232 movs r2, #50 ; 0x32 + 8003f00: 0018 movs r0, r3 + 8003f02: f7ff fe63 bl 8003bcc + 8003f06: 0003 movs r3, r0 + 8003f08: 61fb str r3, [r7, #28] + if (ptr == NULL) break; + 8003f0a: 69fb ldr r3, [r7, #28] + 8003f0c: 2b00 cmp r3, #0 + 8003f0e: d100 bne.n 8003f12 + 8003f10: e0a5 b.n 800405e + if (ptr[1] != 4) break; + 8003f12: 69fb ldr r3, [r7, #28] + 8003f14: 3301 adds r3, #1 + 8003f16: 781b ldrb r3, [r3, #0] + 8003f18: 2b04 cmp r3, #4 + 8003f1a: d000 beq.n 8003f1e + 8003f1c: e0a1 b.n 8004062 + ptr += 2; + 8003f1e: 69fb ldr r3, [r7, #28] + 8003f20: 3302 adds r3, #2 + 8003f22: 61fb str r3, [r7, #28] + entry = entry_by_mac(dhcp_data.dp_chaddr); + 8003f24: 4b58 ldr r3, [pc, #352] ; (8004088 ) + 8003f26: 0018 movs r0, r3 + 8003f28: f7ff fdce bl 8003ac8 + 8003f2c: 0003 movs r3, r0 + 8003f2e: 627b str r3, [r7, #36] ; 0x24 + if (entry != NULL) free_entry(entry); + 8003f30: 6a7b ldr r3, [r7, #36] ; 0x24 + 8003f32: 2b00 cmp r3, #0 + 8003f34: d003 beq.n 8003f3e + 8003f36: 6a7b ldr r3, [r7, #36] ; 0x24 + 8003f38: 0018 movs r0, r3 + 8003f3a: f7ff fe39 bl 8003bb0 + entry = entry_by_ip(get_ip(ptr)); + 8003f3e: 69fb ldr r3, [r7, #28] + 8003f40: 0018 movs r0, r3 + 8003f42: f7ff fd6f bl 8003a24 + 8003f46: 0003 movs r3, r0 + 8003f48: 0018 movs r0, r3 + 8003f4a: f7ff fd8b bl 8003a64 + 8003f4e: 0003 movs r3, r0 + 8003f50: 627b str r3, [r7, #36] ; 0x24 + if (entry == NULL) break; + 8003f52: 6a7b ldr r3, [r7, #36] ; 0x24 + 8003f54: 2b00 cmp r3, #0 + 8003f56: d100 bne.n 8003f5a + 8003f58: e085 b.n 8004066 + if (!is_vacant(entry)) break; + 8003f5a: 6a7b ldr r3, [r7, #36] ; 0x24 + 8003f5c: 0018 movs r0, r3 + 8003f5e: f7ff fde5 bl 8003b2c + 8003f62: 0003 movs r3, r0 + 8003f64: 001a movs r2, r3 + 8003f66: 2301 movs r3, #1 + 8003f68: 4053 eors r3, r2 + 8003f6a: b2db uxtb r3, r3 + 8003f6c: 2b00 cmp r3, #0 + 8003f6e: d000 beq.n 8003f72 + 8003f70: e07b b.n 800406a + memcpy(dhcp_data.dp_yiaddr, ptr, 4); + 8003f72: 4b44 ldr r3, [pc, #272] ; (8004084 ) + 8003f74: 69fa ldr r2, [r7, #28] + 8003f76: 3310 adds r3, #16 + 8003f78: 0011 movs r1, r2 + 8003f7a: 2204 movs r2, #4 + 8003f7c: 0018 movs r0, r3 + 8003f7e: f00b fe90 bl 800fca2 + dhcp_data.dp_op = 2; /* reply */ + 8003f82: 4b40 ldr r3, [pc, #256] ; (8004084 ) + 8003f84: 2202 movs r2, #2 + 8003f86: 701a strb r2, [r3, #0] + dhcp_data.dp_secs = 0; + 8003f88: 4b3e ldr r3, [pc, #248] ; (8004084 ) + 8003f8a: 2200 movs r2, #0 + 8003f8c: 811a strh r2, [r3, #8] + dhcp_data.dp_flags = 0; + 8003f8e: 4b3d ldr r3, [pc, #244] ; (8004084 ) + 8003f90: 2200 movs r2, #0 + 8003f92: 815a strh r2, [r3, #10] + memcpy(dhcp_data.dp_magic, magic_cookie, 4); + 8003f94: 4b3e ldr r3, [pc, #248] ; (8004090 ) + 8003f96: 681a ldr r2, [r3, #0] + 8003f98: 4b3a ldr r3, [pc, #232] ; (8004084 ) + 8003f9a: 21ec movs r1, #236 ; 0xec + 8003f9c: 505a str r2, [r3, r1] + memset(dhcp_data.dp_options, 0, sizeof(dhcp_data.dp_options)); + 8003f9e: 2314 movs r3, #20 + 8003fa0: 33ff adds r3, #255 ; 0xff + 8003fa2: 001a movs r2, r3 + 8003fa4: 4b3b ldr r3, [pc, #236] ; (8004094 ) + 8003fa6: 2100 movs r1, #0 + 8003fa8: 0018 movs r0, r3 + 8003faa: f00b fe83 bl 800fcb4 + config->domain, + 8003fae: 4b3a ldr r3, [pc, #232] ; (8004098 ) + 8003fb0: 681b ldr r3, [r3, #0] + fill_options(dhcp_data.dp_options, + 8003fb2: 68dc ldr r4, [r3, #12] + get_ip(config->dns), + 8003fb4: 4b38 ldr r3, [pc, #224] ; (8004098 ) + 8003fb6: 681b ldr r3, [r3, #0] + 8003fb8: 3306 adds r3, #6 + fill_options(dhcp_data.dp_options, + 8003fba: 0018 movs r0, r3 + 8003fbc: f7ff fd32 bl 8003a24 + 8003fc0: 6078 str r0, [r7, #4] + entry->lease, + 8003fc2: 6a7b ldr r3, [r7, #36] ; 0x24 + 8003fc4: 691b ldr r3, [r3, #16] + fill_options(dhcp_data.dp_options, + 8003fc6: 001d movs r5, r3 + get_ip(config->addr), + 8003fc8: 4b33 ldr r3, [pc, #204] ; (8004098 ) + 8003fca: 681b ldr r3, [r3, #0] + fill_options(dhcp_data.dp_options, + 8003fcc: 0018 movs r0, r3 + 8003fce: f7ff fd29 bl 8003a24 + 8003fd2: 0006 movs r6, r0 + get_ip(config->addr), + 8003fd4: 4b30 ldr r3, [pc, #192] ; (8004098 ) + 8003fd6: 681b ldr r3, [r3, #0] + fill_options(dhcp_data.dp_options, + 8003fd8: 0018 movs r0, r3 + 8003fda: f7ff fd23 bl 8003a24 + 8003fde: 4680 mov r8, r0 + get_ip(entry->subnet)); + 8003fe0: 6a7b ldr r3, [r7, #36] ; 0x24 + 8003fe2: 330a adds r3, #10 + fill_options(dhcp_data.dp_options, + 8003fe4: 0018 movs r0, r3 + 8003fe6: f7ff fd1d bl 8003a24 + 8003fea: 0003 movs r3, r0 + 8003fec: 4829 ldr r0, [pc, #164] ; (8004094 ) + 8003fee: 9303 str r3, [sp, #12] + 8003ff0: 4642 mov r2, r8 + 8003ff2: 9202 str r2, [sp, #8] + 8003ff4: 9601 str r6, [sp, #4] + 8003ff6: 9500 str r5, [sp, #0] + 8003ff8: 687b ldr r3, [r7, #4] + 8003ffa: 0022 movs r2, r4 + 8003ffc: 2105 movs r1, #5 + 8003ffe: f7ff fe17 bl 8003c30 + pp = pbuf_alloc(PBUF_TRANSPORT, sizeof(dhcp_data), PBUF_POOL); + 8004002: 2381 movs r3, #129 ; 0x81 + 8004004: 009b lsls r3, r3, #2 + 8004006: 2203 movs r2, #3 + 8004008: 0019 movs r1, r3 + 800400a: 2000 movs r0, #0 + 800400c: f001 f8be bl 800518c + 8004010: 0003 movs r3, r0 + 8004012: 61bb str r3, [r7, #24] + if (pp == NULL) break; + 8004014: 69bb ldr r3, [r7, #24] + 8004016: 2b00 cmp r3, #0 + 8004018: d029 beq.n 800406e + memcpy(entry->mac, dhcp_data.dp_chaddr, 6); + 800401a: 6a7b ldr r3, [r7, #36] ; 0x24 + 800401c: 491a ldr r1, [pc, #104] ; (8004088 ) + 800401e: 2206 movs r2, #6 + 8004020: 0018 movs r0, r3 + 8004022: f00b fe3e bl 800fca2 + memcpy(pp->payload, &dhcp_data, sizeof(dhcp_data)); + 8004026: 69bb ldr r3, [r7, #24] + 8004028: 6858 ldr r0, [r3, #4] + 800402a: 2381 movs r3, #129 ; 0x81 + 800402c: 009a lsls r2, r3, #2 + 800402e: 4b15 ldr r3, [pc, #84] ; (8004084 ) + 8004030: 0019 movs r1, r3 + 8004032: f00b fe36 bl 800fca2 + udp_sendto(upcb, pp, IP_ADDR_BROADCAST, port); + 8004036: 2338 movs r3, #56 ; 0x38 + 8004038: 2208 movs r2, #8 + 800403a: 4694 mov ip, r2 + 800403c: 44bc add ip, r7 + 800403e: 4463 add r3, ip + 8004040: 881b ldrh r3, [r3, #0] + 8004042: 4a16 ldr r2, [pc, #88] ; (800409c ) + 8004044: 69b9 ldr r1, [r7, #24] + 8004046: 6938 ldr r0, [r7, #16] + 8004048: f006 fdd0 bl 800abec + pbuf_free(pp); + 800404c: 69bb ldr r3, [r7, #24] + 800404e: 0018 movs r0, r3 + 8004050: f001 fb28 bl 80056a4 + break; + 8004054: e00c b.n 8004070 + if (entry == NULL) break; + 8004056: 46c0 nop ; (mov r8, r8) + 8004058: e00a b.n 8004070 + if (pp == NULL) break; + 800405a: 46c0 nop ; (mov r8, r8) + 800405c: e008 b.n 8004070 + if (ptr == NULL) break; + 800405e: 46c0 nop ; (mov r8, r8) + 8004060: e006 b.n 8004070 + if (ptr[1] != 4) break; + 8004062: 46c0 nop ; (mov r8, r8) + 8004064: e004 b.n 8004070 + if (entry == NULL) break; + 8004066: 46c0 nop ; (mov r8, r8) + 8004068: e002 b.n 8004070 + if (!is_vacant(entry)) break; + 800406a: 46c0 nop ; (mov r8, r8) + 800406c: e000 b.n 8004070 + if (pp == NULL) break; + 800406e: 46c0 nop ; (mov r8, r8) + } + pbuf_free(p); + 8004070: 68fb ldr r3, [r7, #12] + 8004072: 0018 movs r0, r3 + 8004074: f001 fb16 bl 80056a4 +} + 8004078: 46c0 nop ; (mov r8, r8) + 800407a: 46bd mov sp, r7 + 800407c: b00a add sp, #40 ; 0x28 + 800407e: bc04 pop {r2} + 8004080: 4690 mov r8, r2 + 8004082: bdf0 pop {r4, r5, r6, r7, pc} + 8004084: 200028f4 .word 0x200028f4 + 8004088: 20002910 .word 0x20002910 + 800408c: 20002904 .word 0x20002904 + 8004090: 2000000c .word 0x2000000c + 8004094: 200029e4 .word 0x200029e4 + 8004098: 200000bc .word 0x200000bc + 800409c: 0800fdc4 .word 0x0800fdc4 + +080040a0 : + +err_t dhserv_init(dhcp_config_t *c) +{ + 80040a0: b5b0 push {r4, r5, r7, lr} + 80040a2: b084 sub sp, #16 + 80040a4: af00 add r7, sp, #0 + 80040a6: 6078 str r0, [r7, #4] + err_t err; + udp_init(); + 80040a8: f006 fbbe bl 800a828 + dhserv_free(); + 80040ac: f000 f83c bl 8004128 + pcb = udp_new(); + 80040b0: f006 ff98 bl 800afe4 + 80040b4: 0002 movs r2, r0 + 80040b6: 4b18 ldr r3, [pc, #96] ; (8004118 ) + 80040b8: 601a str r2, [r3, #0] + if (pcb == NULL) + 80040ba: 4b17 ldr r3, [pc, #92] ; (8004118 ) + 80040bc: 681b ldr r3, [r3, #0] + 80040be: 2b00 cmp r3, #0 + 80040c0: d102 bne.n 80040c8 + return ERR_MEM; + 80040c2: 2301 movs r3, #1 + 80040c4: 425b negs r3, r3 + 80040c6: e022 b.n 800410e + err = udp_bind(pcb, IP_ADDR_ANY, c->port); + 80040c8: 4b13 ldr r3, [pc, #76] ; (8004118 ) + 80040ca: 6818 ldr r0, [r3, #0] + 80040cc: 687b ldr r3, [r7, #4] + 80040ce: 889a ldrh r2, [r3, #4] + 80040d0: 250f movs r5, #15 + 80040d2: 197c adds r4, r7, r5 + 80040d4: 4b11 ldr r3, [pc, #68] ; (800411c ) + 80040d6: 0019 movs r1, r3 + 80040d8: f006 fed6 bl 800ae88 + 80040dc: 0003 movs r3, r0 + 80040de: 7023 strb r3, [r4, #0] + if (err != ERR_OK) + 80040e0: 197b adds r3, r7, r5 + 80040e2: 781b ldrb r3, [r3, #0] + 80040e4: b25b sxtb r3, r3 + 80040e6: 2b00 cmp r3, #0 + 80040e8: d006 beq.n 80040f8 + { + dhserv_free(); + 80040ea: f000 f81d bl 8004128 + return err; + 80040ee: 230f movs r3, #15 + 80040f0: 18fb adds r3, r7, r3 + 80040f2: 781b ldrb r3, [r3, #0] + 80040f4: b25b sxtb r3, r3 + 80040f6: e00a b.n 800410e + } + udp_recv(pcb, udp_recv_proc, NULL); + 80040f8: 4b07 ldr r3, [pc, #28] ; (8004118 ) + 80040fa: 681b ldr r3, [r3, #0] + 80040fc: 4908 ldr r1, [pc, #32] ; (8004120 ) + 80040fe: 2200 movs r2, #0 + 8004100: 0018 movs r0, r3 + 8004102: f006 ff2d bl 800af60 + config = c; + 8004106: 4b07 ldr r3, [pc, #28] ; (8004124 ) + 8004108: 687a ldr r2, [r7, #4] + 800410a: 601a str r2, [r3, #0] + return ERR_OK; + 800410c: 2300 movs r3, #0 +} + 800410e: 0018 movs r0, r3 + 8004110: 46bd mov sp, r7 + 8004112: b004 add sp, #16 + 8004114: bdb0 pop {r4, r5, r7, pc} + 8004116: 46c0 nop ; (mov r8, r8) + 8004118: 200000b8 .word 0x200000b8 + 800411c: 0800fdc0 .word 0x0800fdc0 + 8004120: 08003dad .word 0x08003dad + 8004124: 200000bc .word 0x200000bc + +08004128 : + +void dhserv_free(void) +{ + 8004128: b580 push {r7, lr} + 800412a: af00 add r7, sp, #0 + if (pcb == NULL) return; + 800412c: 4b07 ldr r3, [pc, #28] ; (800414c ) + 800412e: 681b ldr r3, [r3, #0] + 8004130: 2b00 cmp r3, #0 + 8004132: d008 beq.n 8004146 + udp_remove(pcb); + 8004134: 4b05 ldr r3, [pc, #20] ; (800414c ) + 8004136: 681b ldr r3, [r3, #0] + 8004138: 0018 movs r0, r3 + 800413a: f006 ff21 bl 800af80 + pcb = NULL; + 800413e: 4b03 ldr r3, [pc, #12] ; (800414c ) + 8004140: 2200 movs r2, #0 + 8004142: 601a str r2, [r3, #0] + 8004144: e000 b.n 8004148 + if (pcb == NULL) return; + 8004146: 46c0 nop ; (mov r8, r8) +} + 8004148: 46bd mov sp, r7 + 800414a: bd80 pop {r7, pc} + 800414c: 200000b8 .word 0x200000b8 + +08004150 : + uint16_t type; + uint16_t Class; +} dns_query_t; + +static uint16_t get_uint16(const uint8_t *pnt) +{ + 8004150: b590 push {r4, r7, lr} + 8004152: b085 sub sp, #20 + 8004154: af00 add r7, sp, #0 + 8004156: 6078 str r0, [r7, #4] + uint16_t result; + memcpy(&result, pnt, sizeof(result)); + 8004158: 6879 ldr r1, [r7, #4] + 800415a: 240e movs r4, #14 + 800415c: 193b adds r3, r7, r4 + 800415e: 2202 movs r2, #2 + 8004160: 0018 movs r0, r3 + 8004162: f00b fd9e bl 800fca2 + return result; + 8004166: 193b adds r3, r7, r4 + 8004168: 881b ldrh r3, [r3, #0] +} + 800416a: 0018 movs r0, r3 + 800416c: 46bd mov sp, r7 + 800416e: b005 add sp, #20 + 8004170: bd90 pop {r4, r7, pc} + +08004172 : + +static int parse_next_query(void *data, int size, dns_query_t *query) +{ + 8004172: b590 push {r4, r7, lr} + 8004174: b089 sub sp, #36 ; 0x24 + 8004176: af00 add r7, sp, #0 + 8004178: 60f8 str r0, [r7, #12] + 800417a: 60b9 str r1, [r7, #8] + 800417c: 607a str r2, [r7, #4] + int len; + int lables; + uint8_t *ptr; + + len = 0; + 800417e: 2300 movs r3, #0 + 8004180: 61fb str r3, [r7, #28] + lables = 0; + 8004182: 2300 movs r3, #0 + 8004184: 61bb str r3, [r7, #24] + ptr = (uint8_t *)data; + 8004186: 68fb ldr r3, [r7, #12] + 8004188: 617b str r3, [r7, #20] + + while (true) + { + uint8_t lable_len; + if (size <= 0) return -1; + 800418a: 68bb ldr r3, [r7, #8] + 800418c: 2b00 cmp r3, #0 + 800418e: dc02 bgt.n 8004196 + 8004190: 2301 movs r3, #1 + 8004192: 425b negs r3, r3 + 8004194: e075 b.n 8004282 + lable_len = *ptr++; + 8004196: 697b ldr r3, [r7, #20] + 8004198: 1c5a adds r2, r3, #1 + 800419a: 617a str r2, [r7, #20] + 800419c: 2113 movs r1, #19 + 800419e: 187a adds r2, r7, r1 + 80041a0: 781b ldrb r3, [r3, #0] + 80041a2: 7013 strb r3, [r2, #0] + size--; + 80041a4: 68bb ldr r3, [r7, #8] + 80041a6: 3b01 subs r3, #1 + 80041a8: 60bb str r3, [r7, #8] + if (lable_len == 0) break; + 80041aa: 187b adds r3, r7, r1 + 80041ac: 781b ldrb r3, [r3, #0] + 80041ae: 2b00 cmp r3, #0 + 80041b0: d040 beq.n 8004234 + if (lables > 0) + 80041b2: 69bb ldr r3, [r7, #24] + 80041b4: 2b00 cmp r3, #0 + 80041b6: dd0b ble.n 80041d0 + { + if (len == DNS_MAX_HOST_NAME_LEN) return -2; + 80041b8: 69fb ldr r3, [r7, #28] + 80041ba: 2b80 cmp r3, #128 ; 0x80 + 80041bc: d102 bne.n 80041c4 + 80041be: 2302 movs r3, #2 + 80041c0: 425b negs r3, r3 + 80041c2: e05e b.n 8004282 + query->name[len++] = '.'; + 80041c4: 69fb ldr r3, [r7, #28] + 80041c6: 1c5a adds r2, r3, #1 + 80041c8: 61fa str r2, [r7, #28] + 80041ca: 687a ldr r2, [r7, #4] + 80041cc: 212e movs r1, #46 ; 0x2e + 80041ce: 54d1 strb r1, [r2, r3] + } + if (lable_len > size) return -1; + 80041d0: 2313 movs r3, #19 + 80041d2: 18fb adds r3, r7, r3 + 80041d4: 781b ldrb r3, [r3, #0] + 80041d6: 68ba ldr r2, [r7, #8] + 80041d8: 429a cmp r2, r3 + 80041da: da02 bge.n 80041e2 + 80041dc: 2301 movs r3, #1 + 80041de: 425b negs r3, r3 + 80041e0: e04f b.n 8004282 + if (len + lable_len >= DNS_MAX_HOST_NAME_LEN) return -2; + 80041e2: 2313 movs r3, #19 + 80041e4: 18fb adds r3, r7, r3 + 80041e6: 781a ldrb r2, [r3, #0] + 80041e8: 69fb ldr r3, [r7, #28] + 80041ea: 18d3 adds r3, r2, r3 + 80041ec: 2b7f cmp r3, #127 ; 0x7f + 80041ee: dd02 ble.n 80041f6 + 80041f0: 2302 movs r3, #2 + 80041f2: 425b negs r3, r3 + 80041f4: e045 b.n 8004282 + memcpy(&query->name[len], ptr, lable_len); + 80041f6: 687a ldr r2, [r7, #4] + 80041f8: 69fb ldr r3, [r7, #28] + 80041fa: 18d0 adds r0, r2, r3 + 80041fc: 2113 movs r1, #19 + 80041fe: 000c movs r4, r1 + 8004200: 187b adds r3, r7, r1 + 8004202: 781a ldrb r2, [r3, #0] + 8004204: 697b ldr r3, [r7, #20] + 8004206: 0019 movs r1, r3 + 8004208: f00b fd4b bl 800fca2 + len += lable_len; + 800420c: 0021 movs r1, r4 + 800420e: 187b adds r3, r7, r1 + 8004210: 781b ldrb r3, [r3, #0] + 8004212: 69fa ldr r2, [r7, #28] + 8004214: 18d3 adds r3, r2, r3 + 8004216: 61fb str r3, [r7, #28] + ptr += lable_len; + 8004218: 187b adds r3, r7, r1 + 800421a: 781b ldrb r3, [r3, #0] + 800421c: 697a ldr r2, [r7, #20] + 800421e: 18d3 adds r3, r2, r3 + 8004220: 617b str r3, [r7, #20] + size -= lable_len; + 8004222: 187b adds r3, r7, r1 + 8004224: 781b ldrb r3, [r3, #0] + 8004226: 68ba ldr r2, [r7, #8] + 8004228: 1ad3 subs r3, r2, r3 + 800422a: 60bb str r3, [r7, #8] + lables++; + 800422c: 69bb ldr r3, [r7, #24] + 800422e: 3301 adds r3, #1 + 8004230: 61bb str r3, [r7, #24] + { + 8004232: e7aa b.n 800418a + if (lable_len == 0) break; + 8004234: 46c0 nop ; (mov r8, r8) + } + + if (size < 4) return -1; + 8004236: 68bb ldr r3, [r7, #8] + 8004238: 2b03 cmp r3, #3 + 800423a: dc02 bgt.n 8004242 + 800423c: 2301 movs r3, #1 + 800423e: 425b negs r3, r3 + 8004240: e01f b.n 8004282 + query->name[len] = 0; + 8004242: 687a ldr r2, [r7, #4] + 8004244: 69fb ldr r3, [r7, #28] + 8004246: 18d3 adds r3, r2, r3 + 8004248: 2200 movs r2, #0 + 800424a: 701a strb r2, [r3, #0] + query->type = get_uint16(ptr); + 800424c: 697b ldr r3, [r7, #20] + 800424e: 0018 movs r0, r3 + 8004250: f7ff ff7e bl 8004150 + 8004254: 0003 movs r3, r0 + 8004256: 0019 movs r1, r3 + 8004258: 687b ldr r3, [r7, #4] + 800425a: 2280 movs r2, #128 ; 0x80 + 800425c: 5299 strh r1, [r3, r2] + ptr += 2; + 800425e: 697b ldr r3, [r7, #20] + 8004260: 3302 adds r3, #2 + 8004262: 617b str r3, [r7, #20] + query->Class = get_uint16(ptr); + 8004264: 697b ldr r3, [r7, #20] + 8004266: 0018 movs r0, r3 + 8004268: f7ff ff72 bl 8004150 + 800426c: 0003 movs r3, r0 + 800426e: 0019 movs r1, r3 + 8004270: 687b ldr r3, [r7, #4] + 8004272: 2282 movs r2, #130 ; 0x82 + 8004274: 5299 strh r1, [r3, r2] + ptr += 2; + 8004276: 697b ldr r3, [r7, #20] + 8004278: 3302 adds r3, #2 + 800427a: 617b str r3, [r7, #20] + return ptr - (uint8_t *)data; + 800427c: 697a ldr r2, [r7, #20] + 800427e: 68fb ldr r3, [r7, #12] + 8004280: 1ad3 subs r3, r2, r3 +} + 8004282: 0018 movs r0, r3 + 8004284: 46bd mov sp, r7 + 8004286: b009 add sp, #36 ; 0x24 + 8004288: bd90 pop {r4, r7, pc} + ... + +0800428c : + +static void udp_recv_proc(void *arg, struct udp_pcb *upcb, struct pbuf *p, struct ip_addr *addr, u16_t port) +{ + 800428c: b590 push {r4, r7, lr} + 800428e: b08b sub sp, #44 ; 0x2c + 8004290: af00 add r7, sp, #0 + 8004292: 60f8 str r0, [r7, #12] + 8004294: 60b9 str r1, [r7, #8] + 8004296: 607a str r2, [r7, #4] + 8004298: 603b str r3, [r7, #0] + static dns_query_t query; + struct pbuf *out; + ip_addr_t host_addr; + dns_answer_t *answer; + + if (p->len <= sizeof(dns_header_t)) goto error; + 800429a: 687b ldr r3, [r7, #4] + 800429c: 895b ldrh r3, [r3, #10] + 800429e: 2b0c cmp r3, #12 + 80042a0: d800 bhi.n 80042a4 + 80042a2: e142 b.n 800452a + header = (dns_header_t *)p->payload; + 80042a4: 687b ldr r3, [r7, #4] + 80042a6: 685b ldr r3, [r3, #4] + 80042a8: 627b str r3, [r7, #36] ; 0x24 + if (header->flags.qr != 0) goto error; + 80042aa: 6a7b ldr r3, [r7, #36] ; 0x24 + 80042ac: 789b ldrb r3, [r3, #2] + 80042ae: 227f movs r2, #127 ; 0x7f + 80042b0: 4393 bics r3, r2 + 80042b2: b2db uxtb r3, r3 + 80042b4: 2b00 cmp r3, #0 + 80042b6: d000 beq.n 80042ba + 80042b8: e139 b.n 800452e + if (ntohs(header->n_record[0]) != 1) goto error; + 80042ba: 6a7b ldr r3, [r7, #36] ; 0x24 + 80042bc: 791a ldrb r2, [r3, #4] + 80042be: 795b ldrb r3, [r3, #5] + 80042c0: 021b lsls r3, r3, #8 + 80042c2: 4313 orrs r3, r2 + 80042c4: b29b uxth r3, r3 + 80042c6: 0018 movs r0, r3 + 80042c8: f000 f9ba bl 8004640 + 80042cc: 0003 movs r3, r0 + 80042ce: 2b01 cmp r3, #1 + 80042d0: d000 beq.n 80042d4 + 80042d2: e12e b.n 8004532 + + len = parse_next_query(header + 1, p->len - sizeof(dns_header_t), &query); + 80042d4: 6a7b ldr r3, [r7, #36] ; 0x24 + 80042d6: 330c adds r3, #12 + 80042d8: 0018 movs r0, r3 + 80042da: 687b ldr r3, [r7, #4] + 80042dc: 895b ldrh r3, [r3, #10] + 80042de: 3b0c subs r3, #12 + 80042e0: 0019 movs r1, r3 + 80042e2: 4b9b ldr r3, [pc, #620] ; (8004550 ) + 80042e4: 001a movs r2, r3 + 80042e6: f7ff ff44 bl 8004172 + 80042ea: 0003 movs r3, r0 + 80042ec: 623b str r3, [r7, #32] + if (len < 0) goto error; + 80042ee: 6a3b ldr r3, [r7, #32] + 80042f0: 2b00 cmp r3, #0 + 80042f2: da00 bge.n 80042f6 + 80042f4: e11f b.n 8004536 + if (!query_proc(query.name, &host_addr)) goto error; + 80042f6: 4b97 ldr r3, [pc, #604] ; (8004554 ) + 80042f8: 681b ldr r3, [r3, #0] + 80042fa: 2214 movs r2, #20 + 80042fc: 18b9 adds r1, r7, r2 + 80042fe: 4a94 ldr r2, [pc, #592] ; (8004550 ) + 8004300: 0010 movs r0, r2 + 8004302: 4798 blx r3 + 8004304: 0003 movs r3, r0 + 8004306: 001a movs r2, r3 + 8004308: 2301 movs r3, #1 + 800430a: 4053 eors r3, r2 + 800430c: b2db uxtb r3, r3 + 800430e: 2b00 cmp r3, #0 + 8004310: d000 beq.n 8004314 + 8004312: e112 b.n 800453a + + len += sizeof(dns_header_t); + 8004314: 6a3b ldr r3, [r7, #32] + 8004316: 330c adds r3, #12 + 8004318: 623b str r3, [r7, #32] + out = pbuf_alloc(PBUF_TRANSPORT, len + 16, PBUF_POOL); + 800431a: 6a3b ldr r3, [r7, #32] + 800431c: b29b uxth r3, r3 + 800431e: 3310 adds r3, #16 + 8004320: b29b uxth r3, r3 + 8004322: 2203 movs r2, #3 + 8004324: 0019 movs r1, r3 + 8004326: 2000 movs r0, #0 + 8004328: f000 ff30 bl 800518c + 800432c: 0003 movs r3, r0 + 800432e: 61fb str r3, [r7, #28] + if (out == NULL) goto error; + 8004330: 69fb ldr r3, [r7, #28] + 8004332: 2b00 cmp r3, #0 + 8004334: d100 bne.n 8004338 + 8004336: e102 b.n 800453e + + memcpy(out->payload, p->payload, len); + 8004338: 69fb ldr r3, [r7, #28] + 800433a: 6858 ldr r0, [r3, #4] + 800433c: 687b ldr r3, [r7, #4] + 800433e: 685b ldr r3, [r3, #4] + 8004340: 6a3a ldr r2, [r7, #32] + 8004342: 0019 movs r1, r3 + 8004344: f00b fcad bl 800fca2 + header = (dns_header_t *)out->payload; + 8004348: 69fb ldr r3, [r7, #28] + 800434a: 685b ldr r3, [r3, #4] + 800434c: 627b str r3, [r7, #36] ; 0x24 + header->flags.qr = 1; + 800434e: 6a7b ldr r3, [r7, #36] ; 0x24 + 8004350: 789a ldrb r2, [r3, #2] + 8004352: 2180 movs r1, #128 ; 0x80 + 8004354: 4249 negs r1, r1 + 8004356: 430a orrs r2, r1 + 8004358: 709a strb r2, [r3, #2] + header->n_record[1] = htons(1); + 800435a: 2001 movs r0, #1 + 800435c: f000 f95a bl 8004614 + 8004360: 0003 movs r3, r0 + 8004362: 001a movs r2, r3 + 8004364: 6a7b ldr r3, [r7, #36] ; 0x24 + 8004366: 21ff movs r1, #255 ; 0xff + 8004368: 4011 ands r1, r2 + 800436a: 000c movs r4, r1 + 800436c: 7999 ldrb r1, [r3, #6] + 800436e: 2000 movs r0, #0 + 8004370: 4001 ands r1, r0 + 8004372: 1c08 adds r0, r1, #0 + 8004374: 1c21 adds r1, r4, #0 + 8004376: 4301 orrs r1, r0 + 8004378: 7199 strb r1, [r3, #6] + 800437a: 0a12 lsrs r2, r2, #8 + 800437c: b290 uxth r0, r2 + 800437e: 79da ldrb r2, [r3, #7] + 8004380: 2100 movs r1, #0 + 8004382: 400a ands r2, r1 + 8004384: 1c11 adds r1, r2, #0 + 8004386: 1c02 adds r2, r0, #0 + 8004388: 430a orrs r2, r1 + 800438a: 71da strb r2, [r3, #7] + answer = (struct dns_answer *)((uint8_t *)out->payload + len); + 800438c: 69fb ldr r3, [r7, #28] + 800438e: 685a ldr r2, [r3, #4] + 8004390: 6a3b ldr r3, [r7, #32] + 8004392: 18d3 adds r3, r2, r3 + 8004394: 61bb str r3, [r7, #24] + answer->name = htons(0xC00C); + 8004396: 4b70 ldr r3, [pc, #448] ; (8004558 ) + 8004398: 0018 movs r0, r3 + 800439a: f000 f93b bl 8004614 + 800439e: 0003 movs r3, r0 + 80043a0: 001a movs r2, r3 + 80043a2: 69bb ldr r3, [r7, #24] + 80043a4: 21ff movs r1, #255 ; 0xff + 80043a6: 4011 ands r1, r2 + 80043a8: 000c movs r4, r1 + 80043aa: 7819 ldrb r1, [r3, #0] + 80043ac: 2000 movs r0, #0 + 80043ae: 4001 ands r1, r0 + 80043b0: 1c08 adds r0, r1, #0 + 80043b2: 1c21 adds r1, r4, #0 + 80043b4: 4301 orrs r1, r0 + 80043b6: 7019 strb r1, [r3, #0] + 80043b8: 0a12 lsrs r2, r2, #8 + 80043ba: b290 uxth r0, r2 + 80043bc: 785a ldrb r2, [r3, #1] + 80043be: 2100 movs r1, #0 + 80043c0: 400a ands r2, r1 + 80043c2: 1c11 adds r1, r2, #0 + 80043c4: 1c02 adds r2, r0, #0 + 80043c6: 430a orrs r2, r1 + 80043c8: 705a strb r2, [r3, #1] + answer->type = htons(1); + 80043ca: 2001 movs r0, #1 + 80043cc: f000 f922 bl 8004614 + 80043d0: 0003 movs r3, r0 + 80043d2: 001a movs r2, r3 + 80043d4: 69bb ldr r3, [r7, #24] + 80043d6: 21ff movs r1, #255 ; 0xff + 80043d8: 4011 ands r1, r2 + 80043da: 000c movs r4, r1 + 80043dc: 7899 ldrb r1, [r3, #2] + 80043de: 2000 movs r0, #0 + 80043e0: 4001 ands r1, r0 + 80043e2: 1c08 adds r0, r1, #0 + 80043e4: 1c21 adds r1, r4, #0 + 80043e6: 4301 orrs r1, r0 + 80043e8: 7099 strb r1, [r3, #2] + 80043ea: 0a12 lsrs r2, r2, #8 + 80043ec: b290 uxth r0, r2 + 80043ee: 78da ldrb r2, [r3, #3] + 80043f0: 2100 movs r1, #0 + 80043f2: 400a ands r2, r1 + 80043f4: 1c11 adds r1, r2, #0 + 80043f6: 1c02 adds r2, r0, #0 + 80043f8: 430a orrs r2, r1 + 80043fa: 70da strb r2, [r3, #3] + answer->Class = htons(1); + 80043fc: 2001 movs r0, #1 + 80043fe: f000 f909 bl 8004614 + 8004402: 0003 movs r3, r0 + 8004404: 001a movs r2, r3 + 8004406: 69bb ldr r3, [r7, #24] + 8004408: 21ff movs r1, #255 ; 0xff + 800440a: 4011 ands r1, r2 + 800440c: 000c movs r4, r1 + 800440e: 7919 ldrb r1, [r3, #4] + 8004410: 2000 movs r0, #0 + 8004412: 4001 ands r1, r0 + 8004414: 1c08 adds r0, r1, #0 + 8004416: 1c21 adds r1, r4, #0 + 8004418: 4301 orrs r1, r0 + 800441a: 7119 strb r1, [r3, #4] + 800441c: 0a12 lsrs r2, r2, #8 + 800441e: b290 uxth r0, r2 + 8004420: 795a ldrb r2, [r3, #5] + 8004422: 2100 movs r1, #0 + 8004424: 400a ands r2, r1 + 8004426: 1c11 adds r1, r2, #0 + 8004428: 1c02 adds r2, r0, #0 + 800442a: 430a orrs r2, r1 + 800442c: 715a strb r2, [r3, #5] + answer->ttl = htonl(32); + 800442e: 2020 movs r0, #32 + 8004430: f000 f916 bl 8004660 + 8004434: 0002 movs r2, r0 + 8004436: 69bb ldr r3, [r7, #24] + 8004438: 3306 adds r3, #6 + 800443a: 21ff movs r1, #255 ; 0xff + 800443c: 4011 ands r1, r2 + 800443e: 000c movs r4, r1 + 8004440: 7819 ldrb r1, [r3, #0] + 8004442: 2000 movs r0, #0 + 8004444: 4001 ands r1, r0 + 8004446: 1c08 adds r0, r1, #0 + 8004448: 1c21 adds r1, r4, #0 + 800444a: 4301 orrs r1, r0 + 800444c: 7019 strb r1, [r3, #0] + 800444e: 0a11 lsrs r1, r2, #8 + 8004450: 20ff movs r0, #255 ; 0xff + 8004452: 4001 ands r1, r0 + 8004454: 000c movs r4, r1 + 8004456: 7859 ldrb r1, [r3, #1] + 8004458: 2000 movs r0, #0 + 800445a: 4001 ands r1, r0 + 800445c: 1c08 adds r0, r1, #0 + 800445e: 1c21 adds r1, r4, #0 + 8004460: 4301 orrs r1, r0 + 8004462: 7059 strb r1, [r3, #1] + 8004464: 0c11 lsrs r1, r2, #16 + 8004466: 20ff movs r0, #255 ; 0xff + 8004468: 4001 ands r1, r0 + 800446a: 000c movs r4, r1 + 800446c: 7899 ldrb r1, [r3, #2] + 800446e: 2000 movs r0, #0 + 8004470: 4001 ands r1, r0 + 8004472: 1c08 adds r0, r1, #0 + 8004474: 1c21 adds r1, r4, #0 + 8004476: 4301 orrs r1, r0 + 8004478: 7099 strb r1, [r3, #2] + 800447a: 0e10 lsrs r0, r2, #24 + 800447c: 78da ldrb r2, [r3, #3] + 800447e: 2100 movs r1, #0 + 8004480: 400a ands r2, r1 + 8004482: 1c11 adds r1, r2, #0 + 8004484: 1c02 adds r2, r0, #0 + 8004486: 430a orrs r2, r1 + 8004488: 70da strb r2, [r3, #3] + answer->len = htons(4); + 800448a: 2004 movs r0, #4 + 800448c: f000 f8c2 bl 8004614 + 8004490: 0003 movs r3, r0 + 8004492: 001a movs r2, r3 + 8004494: 69bb ldr r3, [r7, #24] + 8004496: 21ff movs r1, #255 ; 0xff + 8004498: 4011 ands r1, r2 + 800449a: 000c movs r4, r1 + 800449c: 7a99 ldrb r1, [r3, #10] + 800449e: 2000 movs r0, #0 + 80044a0: 4001 ands r1, r0 + 80044a2: 1c08 adds r0, r1, #0 + 80044a4: 1c21 adds r1, r4, #0 + 80044a6: 4301 orrs r1, r0 + 80044a8: 7299 strb r1, [r3, #10] + 80044aa: 0a12 lsrs r2, r2, #8 + 80044ac: b290 uxth r0, r2 + 80044ae: 7ada ldrb r2, [r3, #11] + 80044b0: 2100 movs r1, #0 + 80044b2: 400a ands r2, r1 + 80044b4: 1c11 adds r1, r2, #0 + 80044b6: 1c02 adds r2, r0, #0 + 80044b8: 430a orrs r2, r1 + 80044ba: 72da strb r2, [r3, #11] + answer->addr = host_addr.addr; + 80044bc: 697a ldr r2, [r7, #20] + 80044be: 69bb ldr r3, [r7, #24] + 80044c0: 21ff movs r1, #255 ; 0xff + 80044c2: 4011 ands r1, r2 + 80044c4: 000c movs r4, r1 + 80044c6: 7b19 ldrb r1, [r3, #12] + 80044c8: 2000 movs r0, #0 + 80044ca: 4001 ands r1, r0 + 80044cc: 1c08 adds r0, r1, #0 + 80044ce: 1c21 adds r1, r4, #0 + 80044d0: 4301 orrs r1, r0 + 80044d2: 7319 strb r1, [r3, #12] + 80044d4: 0a11 lsrs r1, r2, #8 + 80044d6: 20ff movs r0, #255 ; 0xff + 80044d8: 4001 ands r1, r0 + 80044da: 000c movs r4, r1 + 80044dc: 7b59 ldrb r1, [r3, #13] + 80044de: 2000 movs r0, #0 + 80044e0: 4001 ands r1, r0 + 80044e2: 1c08 adds r0, r1, #0 + 80044e4: 1c21 adds r1, r4, #0 + 80044e6: 4301 orrs r1, r0 + 80044e8: 7359 strb r1, [r3, #13] + 80044ea: 0c11 lsrs r1, r2, #16 + 80044ec: 20ff movs r0, #255 ; 0xff + 80044ee: 4001 ands r1, r0 + 80044f0: 000c movs r4, r1 + 80044f2: 7b99 ldrb r1, [r3, #14] + 80044f4: 2000 movs r0, #0 + 80044f6: 4001 ands r1, r0 + 80044f8: 1c08 adds r0, r1, #0 + 80044fa: 1c21 adds r1, r4, #0 + 80044fc: 4301 orrs r1, r0 + 80044fe: 7399 strb r1, [r3, #14] + 8004500: 0e10 lsrs r0, r2, #24 + 8004502: 7bda ldrb r2, [r3, #15] + 8004504: 2100 movs r1, #0 + 8004506: 400a ands r2, r1 + 8004508: 1c11 adds r1, r2, #0 + 800450a: 1c02 adds r2, r0, #0 + 800450c: 430a orrs r2, r1 + 800450e: 73da strb r2, [r3, #15] + + udp_sendto(upcb, out, addr, port); + 8004510: 2338 movs r3, #56 ; 0x38 + 8004512: 18fb adds r3, r7, r3 + 8004514: 881b ldrh r3, [r3, #0] + 8004516: 683a ldr r2, [r7, #0] + 8004518: 69f9 ldr r1, [r7, #28] + 800451a: 68b8 ldr r0, [r7, #8] + 800451c: f006 fb66 bl 800abec + pbuf_free(out); + 8004520: 69fb ldr r3, [r7, #28] + 8004522: 0018 movs r0, r3 + 8004524: f001 f8be bl 80056a4 + 8004528: e00a b.n 8004540 + if (p->len <= sizeof(dns_header_t)) goto error; + 800452a: 46c0 nop ; (mov r8, r8) + 800452c: e008 b.n 8004540 + if (header->flags.qr != 0) goto error; + 800452e: 46c0 nop ; (mov r8, r8) + 8004530: e006 b.n 8004540 + if (ntohs(header->n_record[0]) != 1) goto error; + 8004532: 46c0 nop ; (mov r8, r8) + 8004534: e004 b.n 8004540 + if (len < 0) goto error; + 8004536: 46c0 nop ; (mov r8, r8) + 8004538: e002 b.n 8004540 + if (!query_proc(query.name, &host_addr)) goto error; + 800453a: 46c0 nop ; (mov r8, r8) + 800453c: e000 b.n 8004540 + if (out == NULL) goto error; + 800453e: 46c0 nop ; (mov r8, r8) + +error: + pbuf_free(p); + 8004540: 687b ldr r3, [r7, #4] + 8004542: 0018 movs r0, r3 + 8004544: f001 f8ae bl 80056a4 +} + 8004548: 46c0 nop ; (mov r8, r8) + 800454a: 46bd mov sp, r7 + 800454c: b00b add sp, #44 ; 0x2c + 800454e: bd90 pop {r4, r7, pc} + 8004550: 200000c8 .word 0x200000c8 + 8004554: 200000c4 .word 0x200000c4 + 8004558: 0000c00c .word 0x0000c00c + +0800455c : + +err_t dnserv_init(ip_addr_t *bind, uint16_t port, dns_query_proc_t qp) +{ + 800455c: b5b0 push {r4, r5, r7, lr} + 800455e: b086 sub sp, #24 + 8004560: af00 add r7, sp, #0 + 8004562: 60f8 str r0, [r7, #12] + 8004564: 607a str r2, [r7, #4] + 8004566: 230a movs r3, #10 + 8004568: 18fb adds r3, r7, r3 + 800456a: 1c0a adds r2, r1, #0 + 800456c: 801a strh r2, [r3, #0] + err_t err; + udp_init(); + 800456e: f006 f95b bl 800a828 + dnserv_free(); + 8004572: f000 f83b bl 80045ec + pcb = udp_new(); + 8004576: f006 fd35 bl 800afe4 + 800457a: 0002 movs r2, r0 + 800457c: 4b18 ldr r3, [pc, #96] ; (80045e0 ) + 800457e: 601a str r2, [r3, #0] + if (pcb == NULL) + 8004580: 4b17 ldr r3, [pc, #92] ; (80045e0 ) + 8004582: 681b ldr r3, [r3, #0] + 8004584: 2b00 cmp r3, #0 + 8004586: d102 bne.n 800458e + return ERR_MEM; + 8004588: 2301 movs r3, #1 + 800458a: 425b negs r3, r3 + 800458c: e023 b.n 80045d6 + err = udp_bind(pcb, bind, port); + 800458e: 4b14 ldr r3, [pc, #80] ; (80045e0 ) + 8004590: 6818 ldr r0, [r3, #0] + 8004592: 2517 movs r5, #23 + 8004594: 197c adds r4, r7, r5 + 8004596: 230a movs r3, #10 + 8004598: 18fb adds r3, r7, r3 + 800459a: 881a ldrh r2, [r3, #0] + 800459c: 68fb ldr r3, [r7, #12] + 800459e: 0019 movs r1, r3 + 80045a0: f006 fc72 bl 800ae88 + 80045a4: 0003 movs r3, r0 + 80045a6: 7023 strb r3, [r4, #0] + if (err != ERR_OK) + 80045a8: 197b adds r3, r7, r5 + 80045aa: 781b ldrb r3, [r3, #0] + 80045ac: b25b sxtb r3, r3 + 80045ae: 2b00 cmp r3, #0 + 80045b0: d006 beq.n 80045c0 + { + dnserv_free(); + 80045b2: f000 f81b bl 80045ec + return err; + 80045b6: 2317 movs r3, #23 + 80045b8: 18fb adds r3, r7, r3 + 80045ba: 781b ldrb r3, [r3, #0] + 80045bc: b25b sxtb r3, r3 + 80045be: e00a b.n 80045d6 + } + udp_recv(pcb, udp_recv_proc, NULL); + 80045c0: 4b07 ldr r3, [pc, #28] ; (80045e0 ) + 80045c2: 681b ldr r3, [r3, #0] + 80045c4: 4907 ldr r1, [pc, #28] ; (80045e4 ) + 80045c6: 2200 movs r2, #0 + 80045c8: 0018 movs r0, r3 + 80045ca: f006 fcc9 bl 800af60 + query_proc = qp; + 80045ce: 4b06 ldr r3, [pc, #24] ; (80045e8 ) + 80045d0: 687a ldr r2, [r7, #4] + 80045d2: 601a str r2, [r3, #0] + return ERR_OK; + 80045d4: 2300 movs r3, #0 +} + 80045d6: 0018 movs r0, r3 + 80045d8: 46bd mov sp, r7 + 80045da: b006 add sp, #24 + 80045dc: bdb0 pop {r4, r5, r7, pc} + 80045de: 46c0 nop ; (mov r8, r8) + 80045e0: 200000c0 .word 0x200000c0 + 80045e4: 0800428d .word 0x0800428d + 80045e8: 200000c4 .word 0x200000c4 + +080045ec : + +void dnserv_free() +{ + 80045ec: b580 push {r7, lr} + 80045ee: af00 add r7, sp, #0 + if (pcb == NULL) return; + 80045f0: 4b07 ldr r3, [pc, #28] ; (8004610 ) + 80045f2: 681b ldr r3, [r3, #0] + 80045f4: 2b00 cmp r3, #0 + 80045f6: d008 beq.n 800460a + udp_remove(pcb); + 80045f8: 4b05 ldr r3, [pc, #20] ; (8004610 ) + 80045fa: 681b ldr r3, [r3, #0] + 80045fc: 0018 movs r0, r3 + 80045fe: f006 fcbf bl 800af80 + pcb = NULL; + 8004602: 4b03 ldr r3, [pc, #12] ; (8004610 ) + 8004604: 2200 movs r2, #0 + 8004606: 601a str r2, [r3, #0] + 8004608: e000 b.n 800460c + if (pcb == NULL) return; + 800460a: 46c0 nop ; (mov r8, r8) +} + 800460c: 46bd mov sp, r7 + 800460e: bd80 pop {r7, pc} + 8004610: 200000c0 .word 0x200000c0 + +08004614 : + * @param n u16_t in host byte order + * @return n in network byte order + */ +u16_t +lwip_htons(u16_t n) +{ + 8004614: b580 push {r7, lr} + 8004616: b082 sub sp, #8 + 8004618: af00 add r7, sp, #0 + 800461a: 0002 movs r2, r0 + 800461c: 1dbb adds r3, r7, #6 + 800461e: 801a strh r2, [r3, #0] + return ((n & 0xff) << 8) | ((n & 0xff00) >> 8); + 8004620: 1dbb adds r3, r7, #6 + 8004622: 881b ldrh r3, [r3, #0] + 8004624: 021b lsls r3, r3, #8 + 8004626: b21a sxth r2, r3 + 8004628: 1dbb adds r3, r7, #6 + 800462a: 881b ldrh r3, [r3, #0] + 800462c: 0a1b lsrs r3, r3, #8 + 800462e: b29b uxth r3, r3 + 8004630: b21b sxth r3, r3 + 8004632: 4313 orrs r3, r2 + 8004634: b21b sxth r3, r3 + 8004636: b29b uxth r3, r3 +} + 8004638: 0018 movs r0, r3 + 800463a: 46bd mov sp, r7 + 800463c: b002 add sp, #8 + 800463e: bd80 pop {r7, pc} + +08004640 : + * @param n u16_t in network byte order + * @return n in host byte order + */ +u16_t +lwip_ntohs(u16_t n) +{ + 8004640: b580 push {r7, lr} + 8004642: b082 sub sp, #8 + 8004644: af00 add r7, sp, #0 + 8004646: 0002 movs r2, r0 + 8004648: 1dbb adds r3, r7, #6 + 800464a: 801a strh r2, [r3, #0] + return lwip_htons(n); + 800464c: 1dbb adds r3, r7, #6 + 800464e: 881b ldrh r3, [r3, #0] + 8004650: 0018 movs r0, r3 + 8004652: f7ff ffdf bl 8004614 + 8004656: 0003 movs r3, r0 +} + 8004658: 0018 movs r0, r3 + 800465a: 46bd mov sp, r7 + 800465c: b002 add sp, #8 + 800465e: bd80 pop {r7, pc} + +08004660 : + * @param n u32_t in host byte order + * @return n in network byte order + */ +u32_t +lwip_htonl(u32_t n) +{ + 8004660: b580 push {r7, lr} + 8004662: b082 sub sp, #8 + 8004664: af00 add r7, sp, #0 + 8004666: 6078 str r0, [r7, #4] + return ((n & 0xff) << 24) | + 8004668: 687b ldr r3, [r7, #4] + 800466a: 061a lsls r2, r3, #24 + ((n & 0xff00) << 8) | + 800466c: 687b ldr r3, [r7, #4] + 800466e: 0219 lsls r1, r3, #8 + 8004670: 23ff movs r3, #255 ; 0xff + 8004672: 041b lsls r3, r3, #16 + 8004674: 400b ands r3, r1 + return ((n & 0xff) << 24) | + 8004676: 431a orrs r2, r3 + ((n & 0xff0000UL) >> 8) | + 8004678: 687b ldr r3, [r7, #4] + 800467a: 0a19 lsrs r1, r3, #8 + 800467c: 23ff movs r3, #255 ; 0xff + 800467e: 021b lsls r3, r3, #8 + 8004680: 400b ands r3, r1 + ((n & 0xff00) << 8) | + 8004682: 431a orrs r2, r3 + ((n & 0xff000000UL) >> 24); + 8004684: 687b ldr r3, [r7, #4] + 8004686: 0e1b lsrs r3, r3, #24 + ((n & 0xff0000UL) >> 8) | + 8004688: 4313 orrs r3, r2 +} + 800468a: 0018 movs r0, r3 + 800468c: 46bd mov sp, r7 + 800468e: b002 add sp, #8 + 8004690: bd80 pop {r7, pc} + +08004692 : + * @param n u32_t in network byte order + * @return n in host byte order + */ +u32_t +lwip_ntohl(u32_t n) +{ + 8004692: b580 push {r7, lr} + 8004694: b082 sub sp, #8 + 8004696: af00 add r7, sp, #0 + 8004698: 6078 str r0, [r7, #4] + return lwip_htonl(n); + 800469a: 687b ldr r3, [r7, #4] + 800469c: 0018 movs r0, r3 + 800469e: f7ff ffdf bl 8004660 + 80046a2: 0003 movs r3, r0 +} + 80046a4: 0018 movs r0, r3 + 80046a6: 46bd mov sp, r7 + 80046a8: b002 add sp, #8 + 80046aa: bd80 pop {r7, pc} + +080046ac : +/** + * Perform Sanity check of user-configurable values, and initialize all modules. + */ +void +lwip_init(void) +{ + 80046ac: b580 push {r7, lr} + 80046ae: af00 add r7, sp, #0 + /* Modules initialization */ + stats_init(); + 80046b0: f001 fa76 bl 8005ba0 +#if !NO_SYS + sys_init(); +#endif /* !NO_SYS */ + mem_init(); + 80046b4: f000 f86c bl 8004790 + memp_init(); + 80046b8: f000 fb18 bl 8004cec + pbuf_init(); + netif_init(); + 80046bc: f000 fc6a bl 8004f94 +#endif /* LWIP_ARP */ +#if LWIP_RAW + raw_init(); +#endif /* LWIP_RAW */ +#if LWIP_UDP + udp_init(); + 80046c0: f006 f8b2 bl 800a828 +#endif /* LWIP_UDP */ +#if LWIP_TCP + tcp_init(); + 80046c4: f001 fa71 bl 8005baa +#if LWIP_DNS + dns_init(); +#endif /* LWIP_DNS */ + +#if LWIP_TIMERS + sys_timeouts_init(); + 80046c8: f006 f81e bl 800a708 +#endif /* LWIP_TIMERS */ +} + 80046cc: 46c0 nop ; (mov r8, r8) + 80046ce: 46bd mov sp, r7 + 80046d0: bd80 pop {r7, pc} + ... + +080046d4 : + * This assumes access to the heap is protected by the calling function + * already. + */ +static void +plug_holes(struct mem *mem) +{ + 80046d4: b580 push {r7, lr} + 80046d6: b084 sub sp, #16 + 80046d8: af00 add r7, sp, #0 + 80046da: 6078 str r0, [r7, #4] + LWIP_ASSERT("plug_holes: mem->used == 0", mem->used == 0); + + /* plug hole forward */ + LWIP_ASSERT("plug_holes: mem->next <= MEM_SIZE_ALIGNED", mem->next <= MEM_SIZE_ALIGNED); + + nmem = (struct mem *)(void *)&ram[mem->next]; + 80046dc: 4b29 ldr r3, [pc, #164] ; (8004784 ) + 80046de: 681b ldr r3, [r3, #0] + 80046e0: 687a ldr r2, [r7, #4] + 80046e2: 8812 ldrh r2, [r2, #0] + 80046e4: 189b adds r3, r3, r2 + 80046e6: 60fb str r3, [r7, #12] + if (mem != nmem && nmem->used == 0 && (u8_t *)nmem != (u8_t *)ram_end) { + 80046e8: 687a ldr r2, [r7, #4] + 80046ea: 68fb ldr r3, [r7, #12] + 80046ec: 429a cmp r2, r3 + 80046ee: d01f beq.n 8004730 + 80046f0: 68fb ldr r3, [r7, #12] + 80046f2: 791b ldrb r3, [r3, #4] + 80046f4: 2b00 cmp r3, #0 + 80046f6: d11b bne.n 8004730 + 80046f8: 4b23 ldr r3, [pc, #140] ; (8004788 ) + 80046fa: 681b ldr r3, [r3, #0] + 80046fc: 68fa ldr r2, [r7, #12] + 80046fe: 429a cmp r2, r3 + 8004700: d016 beq.n 8004730 + /* if mem->next is unused and not end of ram, combine mem and mem->next */ + if (lfree == nmem) { + 8004702: 4b22 ldr r3, [pc, #136] ; (800478c ) + 8004704: 681b ldr r3, [r3, #0] + 8004706: 68fa ldr r2, [r7, #12] + 8004708: 429a cmp r2, r3 + 800470a: d102 bne.n 8004712 + lfree = mem; + 800470c: 4b1f ldr r3, [pc, #124] ; (800478c ) + 800470e: 687a ldr r2, [r7, #4] + 8004710: 601a str r2, [r3, #0] + } + mem->next = nmem->next; + 8004712: 68fb ldr r3, [r7, #12] + 8004714: 881a ldrh r2, [r3, #0] + 8004716: 687b ldr r3, [r7, #4] + 8004718: 801a strh r2, [r3, #0] + ((struct mem *)(void *)&ram[nmem->next])->prev = (mem_size_t)((u8_t *)mem - ram); + 800471a: 687a ldr r2, [r7, #4] + 800471c: 4b19 ldr r3, [pc, #100] ; (8004784 ) + 800471e: 681b ldr r3, [r3, #0] + 8004720: 1ad1 subs r1, r2, r3 + 8004722: 4b18 ldr r3, [pc, #96] ; (8004784 ) + 8004724: 681b ldr r3, [r3, #0] + 8004726: 68fa ldr r2, [r7, #12] + 8004728: 8812 ldrh r2, [r2, #0] + 800472a: 189b adds r3, r3, r2 + 800472c: b28a uxth r2, r1 + 800472e: 805a strh r2, [r3, #2] + } + + /* plug hole backward */ + pmem = (struct mem *)(void *)&ram[mem->prev]; + 8004730: 4b14 ldr r3, [pc, #80] ; (8004784 ) + 8004732: 681b ldr r3, [r3, #0] + 8004734: 687a ldr r2, [r7, #4] + 8004736: 8852 ldrh r2, [r2, #2] + 8004738: 189b adds r3, r3, r2 + 800473a: 60bb str r3, [r7, #8] + if (pmem != mem && pmem->used == 0) { + 800473c: 68ba ldr r2, [r7, #8] + 800473e: 687b ldr r3, [r7, #4] + 8004740: 429a cmp r2, r3 + 8004742: d01a beq.n 800477a + 8004744: 68bb ldr r3, [r7, #8] + 8004746: 791b ldrb r3, [r3, #4] + 8004748: 2b00 cmp r3, #0 + 800474a: d116 bne.n 800477a + /* if mem->prev is unused, combine mem and mem->prev */ + if (lfree == mem) { + 800474c: 4b0f ldr r3, [pc, #60] ; (800478c ) + 800474e: 681b ldr r3, [r3, #0] + 8004750: 687a ldr r2, [r7, #4] + 8004752: 429a cmp r2, r3 + 8004754: d102 bne.n 800475c + lfree = pmem; + 8004756: 4b0d ldr r3, [pc, #52] ; (800478c ) + 8004758: 68ba ldr r2, [r7, #8] + 800475a: 601a str r2, [r3, #0] + } + pmem->next = mem->next; + 800475c: 687b ldr r3, [r7, #4] + 800475e: 881a ldrh r2, [r3, #0] + 8004760: 68bb ldr r3, [r7, #8] + 8004762: 801a strh r2, [r3, #0] + ((struct mem *)(void *)&ram[mem->next])->prev = (mem_size_t)((u8_t *)pmem - ram); + 8004764: 68ba ldr r2, [r7, #8] + 8004766: 4b07 ldr r3, [pc, #28] ; (8004784 ) + 8004768: 681b ldr r3, [r3, #0] + 800476a: 1ad1 subs r1, r2, r3 + 800476c: 4b05 ldr r3, [pc, #20] ; (8004784 ) + 800476e: 681b ldr r3, [r3, #0] + 8004770: 687a ldr r2, [r7, #4] + 8004772: 8812 ldrh r2, [r2, #0] + 8004774: 189b adds r3, r3, r2 + 8004776: b28a uxth r2, r1 + 8004778: 805a strh r2, [r3, #2] + } +} + 800477a: 46c0 nop ; (mov r8, r8) + 800477c: 46bd mov sp, r7 + 800477e: b004 add sp, #16 + 8004780: bd80 pop {r7, pc} + 8004782: 46c0 nop ; (mov r8, r8) + 8004784: 2000014c .word 0x2000014c + 8004788: 20000150 .word 0x20000150 + 800478c: 20000154 .word 0x20000154 + +08004790 : +/** + * Zero the heap and initialize start, end and lowest-free + */ +void +mem_init(void) +{ + 8004790: b580 push {r7, lr} + 8004792: b082 sub sp, #8 + 8004794: af00 add r7, sp, #0 + + LWIP_ASSERT("Sanity check alignment", + (SIZEOF_STRUCT_MEM & (MEM_ALIGNMENT-1)) == 0); + + /* align the heap */ + ram = (u8_t *)LWIP_MEM_ALIGN(LWIP_RAM_HEAP_POINTER); + 8004796: 4b1b ldr r3, [pc, #108] ; (8004804 ) + 8004798: 3303 adds r3, #3 + 800479a: 2203 movs r2, #3 + 800479c: 4393 bics r3, r2 + 800479e: 001a movs r2, r3 + 80047a0: 4b19 ldr r3, [pc, #100] ; (8004808 ) + 80047a2: 601a str r2, [r3, #0] + /* initialize the start of the heap */ + mem = (struct mem *)(void *)ram; + 80047a4: 4b18 ldr r3, [pc, #96] ; (8004808 ) + 80047a6: 681b ldr r3, [r3, #0] + 80047a8: 607b str r3, [r7, #4] + mem->next = MEM_SIZE_ALIGNED; + 80047aa: 687b ldr r3, [r7, #4] + 80047ac: 22c8 movs r2, #200 ; 0xc8 + 80047ae: 00d2 lsls r2, r2, #3 + 80047b0: 801a strh r2, [r3, #0] + mem->prev = 0; + 80047b2: 687b ldr r3, [r7, #4] + 80047b4: 2200 movs r2, #0 + 80047b6: 805a strh r2, [r3, #2] + mem->used = 0; + 80047b8: 687b ldr r3, [r7, #4] + 80047ba: 2200 movs r2, #0 + 80047bc: 711a strb r2, [r3, #4] + /* initialize the end of the heap */ + ram_end = (struct mem *)(void *)&ram[MEM_SIZE_ALIGNED]; + 80047be: 4b12 ldr r3, [pc, #72] ; (8004808 ) + 80047c0: 681b ldr r3, [r3, #0] + 80047c2: 22c8 movs r2, #200 ; 0xc8 + 80047c4: 00d2 lsls r2, r2, #3 + 80047c6: 189a adds r2, r3, r2 + 80047c8: 4b10 ldr r3, [pc, #64] ; (800480c ) + 80047ca: 601a str r2, [r3, #0] + ram_end->used = 1; + 80047cc: 4b0f ldr r3, [pc, #60] ; (800480c ) + 80047ce: 681b ldr r3, [r3, #0] + 80047d0: 2201 movs r2, #1 + 80047d2: 711a strb r2, [r3, #4] + ram_end->next = MEM_SIZE_ALIGNED; + 80047d4: 4b0d ldr r3, [pc, #52] ; (800480c ) + 80047d6: 681b ldr r3, [r3, #0] + 80047d8: 22c8 movs r2, #200 ; 0xc8 + 80047da: 00d2 lsls r2, r2, #3 + 80047dc: 801a strh r2, [r3, #0] + ram_end->prev = MEM_SIZE_ALIGNED; + 80047de: 4b0b ldr r3, [pc, #44] ; (800480c ) + 80047e0: 681b ldr r3, [r3, #0] + 80047e2: 22c8 movs r2, #200 ; 0xc8 + 80047e4: 00d2 lsls r2, r2, #3 + 80047e6: 805a strh r2, [r3, #2] + + /* initialize the lowest-free pointer to the start of the heap */ + lfree = (struct mem *)(void *)ram; + 80047e8: 4b07 ldr r3, [pc, #28] ; (8004808 ) + 80047ea: 681a ldr r2, [r3, #0] + 80047ec: 4b08 ldr r3, [pc, #32] ; (8004810 ) + 80047ee: 601a str r2, [r3, #0] + + MEM_STATS_AVAIL(avail, MEM_SIZE_ALIGNED); + 80047f0: 4b08 ldr r3, [pc, #32] ; (8004814 ) + 80047f2: 22a8 movs r2, #168 ; 0xa8 + 80047f4: 21c8 movs r1, #200 ; 0xc8 + 80047f6: 00c9 lsls r1, r1, #3 + 80047f8: 5299 strh r1, [r3, r2] + + if(sys_mutex_new(&mem_mutex) != ERR_OK) { + LWIP_ASSERT("failed to create mem_mutex", 0); + } +} + 80047fa: 46c0 nop ; (mov r8, r8) + 80047fc: 46bd mov sp, r7 + 80047fe: b002 add sp, #8 + 8004800: bd80 pop {r7, pc} + 8004802: 46c0 nop ; (mov r8, r8) + 8004804: 20002af8 .word 0x20002af8 + 8004808: 2000014c .word 0x2000014c + 800480c: 20000150 .word 0x20000150 + 8004810: 20000154 .word 0x20000154 + 8004814: 20003158 .word 0x20003158 + +08004818 : + * @param rmem is the data portion of a struct mem as returned by a previous + * call to mem_malloc() + */ +void +mem_free(void *rmem) +{ + 8004818: b580 push {r7, lr} + 800481a: b084 sub sp, #16 + 800481c: af00 add r7, sp, #0 + 800481e: 6078 str r0, [r7, #4] + struct mem *mem; + LWIP_MEM_FREE_DECL_PROTECT(); + + if (rmem == NULL) { + 8004820: 687b ldr r3, [r7, #4] + 8004822: 2b00 cmp r3, #0 + 8004824: d036 beq.n 8004894 + LWIP_ASSERT("mem_free: sanity check alignment", (((mem_ptr_t)rmem) & (MEM_ALIGNMENT-1)) == 0); + + LWIP_ASSERT("mem_free: legal memory", (u8_t *)rmem >= (u8_t *)ram && + (u8_t *)rmem < (u8_t *)ram_end); + + if ((u8_t *)rmem < (u8_t *)ram || (u8_t *)rmem >= (u8_t *)ram_end) { + 8004826: 4b1d ldr r3, [pc, #116] ; (800489c ) + 8004828: 681b ldr r3, [r3, #0] + 800482a: 687a ldr r2, [r7, #4] + 800482c: 429a cmp r2, r3 + 800482e: d304 bcc.n 800483a + 8004830: 4b1b ldr r3, [pc, #108] ; (80048a0 ) + 8004832: 681b ldr r3, [r3, #0] + 8004834: 687a ldr r2, [r7, #4] + 8004836: 429a cmp r2, r3 + 8004838: d308 bcc.n 800484c + SYS_ARCH_DECL_PROTECT(lev); + LWIP_DEBUGF(MEM_DEBUG | LWIP_DBG_LEVEL_SEVERE, ("mem_free: illegal memory\n")); + /* protect mem stats from concurrent access */ + SYS_ARCH_PROTECT(lev); + MEM_STATS_INC(illegal); + 800483a: 4b1a ldr r3, [pc, #104] ; (80048a4 ) + 800483c: 22b0 movs r2, #176 ; 0xb0 + 800483e: 5a9b ldrh r3, [r3, r2] + 8004840: 3301 adds r3, #1 + 8004842: b299 uxth r1, r3 + 8004844: 4b17 ldr r3, [pc, #92] ; (80048a4 ) + 8004846: 22b0 movs r2, #176 ; 0xb0 + 8004848: 5299 strh r1, [r3, r2] + SYS_ARCH_UNPROTECT(lev); + return; + 800484a: e024 b.n 8004896 + } + /* protect the heap from concurrent access */ + LWIP_MEM_FREE_PROTECT(); + /* Get the corresponding struct mem ... */ + mem = (struct mem *)(void *)((u8_t *)rmem - SIZEOF_STRUCT_MEM); + 800484c: 687b ldr r3, [r7, #4] + 800484e: 3b08 subs r3, #8 + 8004850: 60fb str r3, [r7, #12] + /* ... which has to be in a used state ... */ + LWIP_ASSERT("mem_free: mem->used", mem->used); + /* ... and is now unused. */ + mem->used = 0; + 8004852: 68fb ldr r3, [r7, #12] + 8004854: 2200 movs r2, #0 + 8004856: 711a strb r2, [r3, #4] + + if (mem < lfree) { + 8004858: 4b13 ldr r3, [pc, #76] ; (80048a8 ) + 800485a: 681b ldr r3, [r3, #0] + 800485c: 68fa ldr r2, [r7, #12] + 800485e: 429a cmp r2, r3 + 8004860: d202 bcs.n 8004868 + /* the newly freed struct is now the lowest */ + lfree = mem; + 8004862: 4b11 ldr r3, [pc, #68] ; (80048a8 ) + 8004864: 68fa ldr r2, [r7, #12] + 8004866: 601a str r2, [r3, #0] + } + + MEM_STATS_DEC_USED(used, mem->next - (mem_size_t)(((u8_t *)mem - ram))); + 8004868: 4b0e ldr r3, [pc, #56] ; (80048a4 ) + 800486a: 22aa movs r2, #170 ; 0xaa + 800486c: 5a9a ldrh r2, [r3, r2] + 800486e: 68f9 ldr r1, [r7, #12] + 8004870: 4b0a ldr r3, [pc, #40] ; (800489c ) + 8004872: 681b ldr r3, [r3, #0] + 8004874: 1acb subs r3, r1, r3 + 8004876: b299 uxth r1, r3 + 8004878: 68fb ldr r3, [r7, #12] + 800487a: 881b ldrh r3, [r3, #0] + 800487c: 1acb subs r3, r1, r3 + 800487e: b29b uxth r3, r3 + 8004880: 18d3 adds r3, r2, r3 + 8004882: b299 uxth r1, r3 + 8004884: 4b07 ldr r3, [pc, #28] ; (80048a4 ) + 8004886: 22aa movs r2, #170 ; 0xaa + 8004888: 5299 strh r1, [r3, r2] + + /* finally, see if prev or next are free also */ + plug_holes(mem); + 800488a: 68fb ldr r3, [r7, #12] + 800488c: 0018 movs r0, r3 + 800488e: f7ff ff21 bl 80046d4 + 8004892: e000 b.n 8004896 + return; + 8004894: 46c0 nop ; (mov r8, r8) +#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT + mem_free_count = 1; +#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */ + LWIP_MEM_FREE_UNPROTECT(); +} + 8004896: 46bd mov sp, r7 + 8004898: b004 add sp, #16 + 800489a: bd80 pop {r7, pc} + 800489c: 2000014c .word 0x2000014c + 80048a0: 20000150 .word 0x20000150 + 80048a4: 20003158 .word 0x20003158 + 80048a8: 20000154 .word 0x20000154 + +080048ac : + * or NULL if newsize is > old size, in which case rmem is NOT touched + * or freed! + */ +void * +mem_trim(void *rmem, mem_size_t newsize) +{ + 80048ac: b580 push {r7, lr} + 80048ae: b086 sub sp, #24 + 80048b0: af00 add r7, sp, #0 + 80048b2: 6078 str r0, [r7, #4] + 80048b4: 000a movs r2, r1 + 80048b6: 1cbb adds r3, r7, #2 + 80048b8: 801a strh r2, [r3, #0] + /* use the FREE_PROTECT here: it protects with sem OR SYS_ARCH_PROTECT */ + LWIP_MEM_FREE_DECL_PROTECT(); + + /* Expand the size of the allocated memory region so that we can + adjust for alignment. */ + newsize = LWIP_MEM_ALIGN_SIZE(newsize); + 80048ba: 1cbb adds r3, r7, #2 + 80048bc: 881b ldrh r3, [r3, #0] + 80048be: 3303 adds r3, #3 + 80048c0: b29a uxth r2, r3 + 80048c2: 1cbb adds r3, r7, #2 + 80048c4: 2103 movs r1, #3 + 80048c6: 438a bics r2, r1 + 80048c8: 801a strh r2, [r3, #0] + + if(newsize < MIN_SIZE_ALIGNED) { + 80048ca: 1cbb adds r3, r7, #2 + 80048cc: 881b ldrh r3, [r3, #0] + 80048ce: 2b0b cmp r3, #11 + 80048d0: d802 bhi.n 80048d8 + /* every data block must be at least MIN_SIZE_ALIGNED long */ + newsize = MIN_SIZE_ALIGNED; + 80048d2: 1cbb adds r3, r7, #2 + 80048d4: 220c movs r2, #12 + 80048d6: 801a strh r2, [r3, #0] + } + + if (newsize > MEM_SIZE_ALIGNED) { + 80048d8: 1cbb adds r3, r7, #2 + 80048da: 881a ldrh r2, [r3, #0] + 80048dc: 23c8 movs r3, #200 ; 0xc8 + 80048de: 00db lsls r3, r3, #3 + 80048e0: 429a cmp r2, r3 + 80048e2: d901 bls.n 80048e8 + return NULL; + 80048e4: 2300 movs r3, #0 + 80048e6: e0e8 b.n 8004aba + } + + LWIP_ASSERT("mem_trim: legal memory", (u8_t *)rmem >= (u8_t *)ram && + (u8_t *)rmem < (u8_t *)ram_end); + + if ((u8_t *)rmem < (u8_t *)ram || (u8_t *)rmem >= (u8_t *)ram_end) { + 80048e8: 4b76 ldr r3, [pc, #472] ; (8004ac4 ) + 80048ea: 681b ldr r3, [r3, #0] + 80048ec: 687a ldr r2, [r7, #4] + 80048ee: 429a cmp r2, r3 + 80048f0: d304 bcc.n 80048fc + 80048f2: 4b75 ldr r3, [pc, #468] ; (8004ac8 ) + 80048f4: 681b ldr r3, [r3, #0] + 80048f6: 687a ldr r2, [r7, #4] + 80048f8: 429a cmp r2, r3 + 80048fa: d309 bcc.n 8004910 + SYS_ARCH_DECL_PROTECT(lev); + LWIP_DEBUGF(MEM_DEBUG | LWIP_DBG_LEVEL_SEVERE, ("mem_trim: illegal memory\n")); + /* protect mem stats from concurrent access */ + SYS_ARCH_PROTECT(lev); + MEM_STATS_INC(illegal); + 80048fc: 4b73 ldr r3, [pc, #460] ; (8004acc ) + 80048fe: 22b0 movs r2, #176 ; 0xb0 + 8004900: 5a9b ldrh r3, [r3, r2] + 8004902: 3301 adds r3, #1 + 8004904: b299 uxth r1, r3 + 8004906: 4b71 ldr r3, [pc, #452] ; (8004acc ) + 8004908: 22b0 movs r2, #176 ; 0xb0 + 800490a: 5299 strh r1, [r3, r2] + SYS_ARCH_UNPROTECT(lev); + return rmem; + 800490c: 687b ldr r3, [r7, #4] + 800490e: e0d4 b.n 8004aba + } + /* Get the corresponding struct mem ... */ + mem = (struct mem *)(void *)((u8_t *)rmem - SIZEOF_STRUCT_MEM); + 8004910: 687b ldr r3, [r7, #4] + 8004912: 3b08 subs r3, #8 + 8004914: 617b str r3, [r7, #20] + /* ... and its offset pointer */ + ptr = (mem_size_t)((u8_t *)mem - ram); + 8004916: 697a ldr r2, [r7, #20] + 8004918: 4b6a ldr r3, [pc, #424] ; (8004ac4 ) + 800491a: 681b ldr r3, [r3, #0] + 800491c: 1ad2 subs r2, r2, r3 + 800491e: 2112 movs r1, #18 + 8004920: 187b adds r3, r7, r1 + 8004922: 801a strh r2, [r3, #0] + + size = mem->next - ptr - SIZEOF_STRUCT_MEM; + 8004924: 697b ldr r3, [r7, #20] + 8004926: 881a ldrh r2, [r3, #0] + 8004928: 187b adds r3, r7, r1 + 800492a: 881b ldrh r3, [r3, #0] + 800492c: 1ad3 subs r3, r2, r3 + 800492e: b29a uxth r2, r3 + 8004930: 2110 movs r1, #16 + 8004932: 187b adds r3, r7, r1 + 8004934: 3a08 subs r2, #8 + 8004936: 801a strh r2, [r3, #0] + LWIP_ASSERT("mem_trim can only shrink memory", newsize <= size); + if (newsize > size) { + 8004938: 1cba adds r2, r7, #2 + 800493a: 187b adds r3, r7, r1 + 800493c: 8812 ldrh r2, [r2, #0] + 800493e: 881b ldrh r3, [r3, #0] + 8004940: 429a cmp r2, r3 + 8004942: d901 bls.n 8004948 + /* not supported */ + return NULL; + 8004944: 2300 movs r3, #0 + 8004946: e0b8 b.n 8004aba + } + if (newsize == size) { + 8004948: 1cba adds r2, r7, #2 + 800494a: 2310 movs r3, #16 + 800494c: 18fb adds r3, r7, r3 + 800494e: 8812 ldrh r2, [r2, #0] + 8004950: 881b ldrh r3, [r3, #0] + 8004952: 429a cmp r2, r3 + 8004954: d101 bne.n 800495a + /* No change in size, simply return */ + return rmem; + 8004956: 687b ldr r3, [r7, #4] + 8004958: e0af b.n 8004aba + } + + /* protect the heap from concurrent access */ + LWIP_MEM_FREE_PROTECT(); + + mem2 = (struct mem *)(void *)&ram[mem->next]; + 800495a: 4b5a ldr r3, [pc, #360] ; (8004ac4 ) + 800495c: 681b ldr r3, [r3, #0] + 800495e: 697a ldr r2, [r7, #20] + 8004960: 8812 ldrh r2, [r2, #0] + 8004962: 189b adds r3, r3, r2 + 8004964: 60fb str r3, [r7, #12] + if(mem2->used == 0) { + 8004966: 68fb ldr r3, [r7, #12] + 8004968: 791b ldrb r3, [r3, #4] + 800496a: 2b00 cmp r3, #0 + 800496c: d153 bne.n 8004a16 + /* The next struct is unused, we can simply move it at little */ + mem_size_t next; + /* remember the old next pointer */ + next = mem2->next; + 800496e: 2308 movs r3, #8 + 8004970: 18fb adds r3, r7, r3 + 8004972: 68fa ldr r2, [r7, #12] + 8004974: 8812 ldrh r2, [r2, #0] + 8004976: 801a strh r2, [r3, #0] + /* create new struct mem which is moved directly after the shrinked mem */ + ptr2 = ptr + SIZEOF_STRUCT_MEM + newsize; + 8004978: 2312 movs r3, #18 + 800497a: 18fa adds r2, r7, r3 + 800497c: 1cbb adds r3, r7, #2 + 800497e: 8812 ldrh r2, [r2, #0] + 8004980: 881b ldrh r3, [r3, #0] + 8004982: 18d3 adds r3, r2, r3 + 8004984: b29a uxth r2, r3 + 8004986: 230a movs r3, #10 + 8004988: 18fb adds r3, r7, r3 + 800498a: 3208 adds r2, #8 + 800498c: 801a strh r2, [r3, #0] + if (lfree == mem2) { + 800498e: 4b50 ldr r3, [pc, #320] ; (8004ad0 ) + 8004990: 681b ldr r3, [r3, #0] + 8004992: 68fa ldr r2, [r7, #12] + 8004994: 429a cmp r2, r3 + 8004996: d107 bne.n 80049a8 + lfree = (struct mem *)(void *)&ram[ptr2]; + 8004998: 4b4a ldr r3, [pc, #296] ; (8004ac4 ) + 800499a: 681a ldr r2, [r3, #0] + 800499c: 230a movs r3, #10 + 800499e: 18fb adds r3, r7, r3 + 80049a0: 881b ldrh r3, [r3, #0] + 80049a2: 18d2 adds r2, r2, r3 + 80049a4: 4b4a ldr r3, [pc, #296] ; (8004ad0 ) + 80049a6: 601a str r2, [r3, #0] + } + mem2 = (struct mem *)(void *)&ram[ptr2]; + 80049a8: 4b46 ldr r3, [pc, #280] ; (8004ac4 ) + 80049aa: 681a ldr r2, [r3, #0] + 80049ac: 210a movs r1, #10 + 80049ae: 187b adds r3, r7, r1 + 80049b0: 881b ldrh r3, [r3, #0] + 80049b2: 18d3 adds r3, r2, r3 + 80049b4: 60fb str r3, [r7, #12] + mem2->used = 0; + 80049b6: 68fb ldr r3, [r7, #12] + 80049b8: 2200 movs r2, #0 + 80049ba: 711a strb r2, [r3, #4] + /* restore the next pointer */ + mem2->next = next; + 80049bc: 68fb ldr r3, [r7, #12] + 80049be: 2208 movs r2, #8 + 80049c0: 18ba adds r2, r7, r2 + 80049c2: 8812 ldrh r2, [r2, #0] + 80049c4: 801a strh r2, [r3, #0] + /* link it back to mem */ + mem2->prev = ptr; + 80049c6: 68fb ldr r3, [r7, #12] + 80049c8: 2212 movs r2, #18 + 80049ca: 18ba adds r2, r7, r2 + 80049cc: 8812 ldrh r2, [r2, #0] + 80049ce: 805a strh r2, [r3, #2] + /* link mem to it */ + mem->next = ptr2; + 80049d0: 697b ldr r3, [r7, #20] + 80049d2: 187a adds r2, r7, r1 + 80049d4: 8812 ldrh r2, [r2, #0] + 80049d6: 801a strh r2, [r3, #0] + /* last thing to restore linked list: as we have moved mem2, + * let 'mem2->next->prev' point to mem2 again. but only if mem2->next is not + * the end of the heap */ + if (mem2->next != MEM_SIZE_ALIGNED) { + 80049d8: 68fb ldr r3, [r7, #12] + 80049da: 881a ldrh r2, [r3, #0] + 80049dc: 23c8 movs r3, #200 ; 0xc8 + 80049de: 00db lsls r3, r3, #3 + 80049e0: 429a cmp r2, r3 + 80049e2: d008 beq.n 80049f6 + ((struct mem *)(void *)&ram[mem2->next])->prev = ptr2; + 80049e4: 4b37 ldr r3, [pc, #220] ; (8004ac4 ) + 80049e6: 681b ldr r3, [r3, #0] + 80049e8: 68fa ldr r2, [r7, #12] + 80049ea: 8812 ldrh r2, [r2, #0] + 80049ec: 189b adds r3, r3, r2 + 80049ee: 220a movs r2, #10 + 80049f0: 18ba adds r2, r7, r2 + 80049f2: 8812 ldrh r2, [r2, #0] + 80049f4: 805a strh r2, [r3, #2] + } + MEM_STATS_DEC_USED(used, (size - newsize)); + 80049f6: 4b35 ldr r3, [pc, #212] ; (8004acc ) + 80049f8: 22aa movs r2, #170 ; 0xaa + 80049fa: 5a9a ldrh r2, [r3, r2] + 80049fc: 1cb9 adds r1, r7, #2 + 80049fe: 2310 movs r3, #16 + 8004a00: 18fb adds r3, r7, r3 + 8004a02: 8809 ldrh r1, [r1, #0] + 8004a04: 881b ldrh r3, [r3, #0] + 8004a06: 1acb subs r3, r1, r3 + 8004a08: b29b uxth r3, r3 + 8004a0a: 18d3 adds r3, r2, r3 + 8004a0c: b299 uxth r1, r3 + 8004a0e: 4b2f ldr r3, [pc, #188] ; (8004acc ) + 8004a10: 22aa movs r2, #170 ; 0xaa + 8004a12: 5299 strh r1, [r3, r2] + 8004a14: e050 b.n 8004ab8 + /* no need to plug holes, we've already done that */ + } else if (newsize + SIZEOF_STRUCT_MEM + MIN_SIZE_ALIGNED <= size) { + 8004a16: 1cbb adds r3, r7, #2 + 8004a18: 881b ldrh r3, [r3, #0] + 8004a1a: 3314 adds r3, #20 + 8004a1c: 001a movs r2, r3 + 8004a1e: 2310 movs r3, #16 + 8004a20: 18fb adds r3, r7, r3 + 8004a22: 881b ldrh r3, [r3, #0] + 8004a24: 429a cmp r2, r3 + 8004a26: d847 bhi.n 8004ab8 + * Old size ('size') must be big enough to contain at least 'newsize' plus a struct mem + * ('SIZEOF_STRUCT_MEM') with some data ('MIN_SIZE_ALIGNED'). + * @todo we could leave out MIN_SIZE_ALIGNED. We would create an empty + * region that couldn't hold data, but when mem->next gets freed, + * the 2 regions would be combined, resulting in more free memory */ + ptr2 = ptr + SIZEOF_STRUCT_MEM + newsize; + 8004a28: 2312 movs r3, #18 + 8004a2a: 18fa adds r2, r7, r3 + 8004a2c: 1cbb adds r3, r7, #2 + 8004a2e: 8812 ldrh r2, [r2, #0] + 8004a30: 881b ldrh r3, [r3, #0] + 8004a32: 18d3 adds r3, r2, r3 + 8004a34: b29a uxth r2, r3 + 8004a36: 210a movs r1, #10 + 8004a38: 187b adds r3, r7, r1 + 8004a3a: 3208 adds r2, #8 + 8004a3c: 801a strh r2, [r3, #0] + mem2 = (struct mem *)(void *)&ram[ptr2]; + 8004a3e: 4b21 ldr r3, [pc, #132] ; (8004ac4 ) + 8004a40: 681a ldr r2, [r3, #0] + 8004a42: 187b adds r3, r7, r1 + 8004a44: 881b ldrh r3, [r3, #0] + 8004a46: 18d3 adds r3, r2, r3 + 8004a48: 60fb str r3, [r7, #12] + if (mem2 < lfree) { + 8004a4a: 4b21 ldr r3, [pc, #132] ; (8004ad0 ) + 8004a4c: 681b ldr r3, [r3, #0] + 8004a4e: 68fa ldr r2, [r7, #12] + 8004a50: 429a cmp r2, r3 + 8004a52: d202 bcs.n 8004a5a + lfree = mem2; + 8004a54: 4b1e ldr r3, [pc, #120] ; (8004ad0 ) + 8004a56: 68fa ldr r2, [r7, #12] + 8004a58: 601a str r2, [r3, #0] + } + mem2->used = 0; + 8004a5a: 68fb ldr r3, [r7, #12] + 8004a5c: 2200 movs r2, #0 + 8004a5e: 711a strb r2, [r3, #4] + mem2->next = mem->next; + 8004a60: 697b ldr r3, [r7, #20] + 8004a62: 881a ldrh r2, [r3, #0] + 8004a64: 68fb ldr r3, [r7, #12] + 8004a66: 801a strh r2, [r3, #0] + mem2->prev = ptr; + 8004a68: 68fb ldr r3, [r7, #12] + 8004a6a: 2212 movs r2, #18 + 8004a6c: 18ba adds r2, r7, r2 + 8004a6e: 8812 ldrh r2, [r2, #0] + 8004a70: 805a strh r2, [r3, #2] + mem->next = ptr2; + 8004a72: 697b ldr r3, [r7, #20] + 8004a74: 220a movs r2, #10 + 8004a76: 18ba adds r2, r7, r2 + 8004a78: 8812 ldrh r2, [r2, #0] + 8004a7a: 801a strh r2, [r3, #0] + if (mem2->next != MEM_SIZE_ALIGNED) { + 8004a7c: 68fb ldr r3, [r7, #12] + 8004a7e: 881a ldrh r2, [r3, #0] + 8004a80: 23c8 movs r3, #200 ; 0xc8 + 8004a82: 00db lsls r3, r3, #3 + 8004a84: 429a cmp r2, r3 + 8004a86: d008 beq.n 8004a9a + ((struct mem *)(void *)&ram[mem2->next])->prev = ptr2; + 8004a88: 4b0e ldr r3, [pc, #56] ; (8004ac4 ) + 8004a8a: 681b ldr r3, [r3, #0] + 8004a8c: 68fa ldr r2, [r7, #12] + 8004a8e: 8812 ldrh r2, [r2, #0] + 8004a90: 189b adds r3, r3, r2 + 8004a92: 220a movs r2, #10 + 8004a94: 18ba adds r2, r7, r2 + 8004a96: 8812 ldrh r2, [r2, #0] + 8004a98: 805a strh r2, [r3, #2] + } + MEM_STATS_DEC_USED(used, (size - newsize)); + 8004a9a: 4b0c ldr r3, [pc, #48] ; (8004acc ) + 8004a9c: 22aa movs r2, #170 ; 0xaa + 8004a9e: 5a9a ldrh r2, [r3, r2] + 8004aa0: 1cb9 adds r1, r7, #2 + 8004aa2: 2310 movs r3, #16 + 8004aa4: 18fb adds r3, r7, r3 + 8004aa6: 8809 ldrh r1, [r1, #0] + 8004aa8: 881b ldrh r3, [r3, #0] + 8004aaa: 1acb subs r3, r1, r3 + 8004aac: b29b uxth r3, r3 + 8004aae: 18d3 adds r3, r2, r3 + 8004ab0: b299 uxth r1, r3 + 8004ab2: 4b06 ldr r3, [pc, #24] ; (8004acc ) + 8004ab4: 22aa movs r2, #170 ; 0xaa + 8004ab6: 5299 strh r1, [r3, r2] + } */ +#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT + mem_free_count = 1; +#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */ + LWIP_MEM_FREE_UNPROTECT(); + return rmem; + 8004ab8: 687b ldr r3, [r7, #4] +} + 8004aba: 0018 movs r0, r3 + 8004abc: 46bd mov sp, r7 + 8004abe: b006 add sp, #24 + 8004ac0: bd80 pop {r7, pc} + 8004ac2: 46c0 nop ; (mov r8, r8) + 8004ac4: 2000014c .word 0x2000014c + 8004ac8: 20000150 .word 0x20000150 + 8004acc: 20003158 .word 0x20003158 + 8004ad0: 20000154 .word 0x20000154 + +08004ad4 : + * + * Note that the returned value will always be aligned (as defined by MEM_ALIGNMENT). + */ +void * +mem_malloc(mem_size_t size) +{ + 8004ad4: b580 push {r7, lr} + 8004ad6: b088 sub sp, #32 + 8004ad8: af00 add r7, sp, #0 + 8004ada: 0002 movs r2, r0 + 8004adc: 1dbb adds r3, r7, #6 + 8004ade: 801a strh r2, [r3, #0] +#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT + u8_t local_mem_free_count = 0; +#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */ + LWIP_MEM_ALLOC_DECL_PROTECT(); + + if (size == 0) { + 8004ae0: 1dbb adds r3, r7, #6 + 8004ae2: 881b ldrh r3, [r3, #0] + 8004ae4: 2b00 cmp r3, #0 + 8004ae6: d101 bne.n 8004aec + return NULL; + 8004ae8: 2300 movs r3, #0 + 8004aea: e0f2 b.n 8004cd2 + } + + /* Expand the size of the allocated memory region so that we can + adjust for alignment. */ + size = LWIP_MEM_ALIGN_SIZE(size); + 8004aec: 1dbb adds r3, r7, #6 + 8004aee: 881b ldrh r3, [r3, #0] + 8004af0: 3303 adds r3, #3 + 8004af2: b29a uxth r2, r3 + 8004af4: 1dbb adds r3, r7, #6 + 8004af6: 2103 movs r1, #3 + 8004af8: 438a bics r2, r1 + 8004afa: 801a strh r2, [r3, #0] + + if(size < MIN_SIZE_ALIGNED) { + 8004afc: 1dbb adds r3, r7, #6 + 8004afe: 881b ldrh r3, [r3, #0] + 8004b00: 2b0b cmp r3, #11 + 8004b02: d802 bhi.n 8004b0a + /* every data block must be at least MIN_SIZE_ALIGNED long */ + size = MIN_SIZE_ALIGNED; + 8004b04: 1dbb adds r3, r7, #6 + 8004b06: 220c movs r2, #12 + 8004b08: 801a strh r2, [r3, #0] + } + + if (size > MEM_SIZE_ALIGNED) { + 8004b0a: 1dbb adds r3, r7, #6 + 8004b0c: 881a ldrh r2, [r3, #0] + 8004b0e: 23c8 movs r3, #200 ; 0xc8 + 8004b10: 00db lsls r3, r3, #3 + 8004b12: 429a cmp r2, r3 + 8004b14: d901 bls.n 8004b1a + return NULL; + 8004b16: 2300 movs r3, #0 + 8004b18: e0db b.n 8004cd2 +#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */ + + /* Scan through the heap searching for a free block that is big enough, + * beginning with the lowest free block. + */ + for (ptr = (mem_size_t)((u8_t *)lfree - ram); ptr < MEM_SIZE_ALIGNED - size; + 8004b1a: 4b70 ldr r3, [pc, #448] ; (8004cdc ) + 8004b1c: 681b ldr r3, [r3, #0] + 8004b1e: 001a movs r2, r3 + 8004b20: 4b6f ldr r3, [pc, #444] ; (8004ce0 ) + 8004b22: 681b ldr r3, [r3, #0] + 8004b24: 1ad2 subs r2, r2, r3 + 8004b26: 231e movs r3, #30 + 8004b28: 18fb adds r3, r7, r3 + 8004b2a: 801a strh r2, [r3, #0] + 8004b2c: e0bd b.n 8004caa + ptr = ((struct mem *)(void *)&ram[ptr])->next) { + mem = (struct mem *)(void *)&ram[ptr]; + 8004b2e: 4b6c ldr r3, [pc, #432] ; (8004ce0 ) + 8004b30: 681a ldr r2, [r3, #0] + 8004b32: 231e movs r3, #30 + 8004b34: 18fb adds r3, r7, r3 + 8004b36: 881b ldrh r3, [r3, #0] + 8004b38: 18d3 adds r3, r2, r3 + 8004b3a: 617b str r3, [r7, #20] + local_mem_free_count = 1; + break; + } +#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */ + + if ((!mem->used) && + 8004b3c: 697b ldr r3, [r7, #20] + 8004b3e: 791b ldrb r3, [r3, #4] + 8004b40: 2b00 cmp r3, #0 + 8004b42: d000 beq.n 8004b46 + 8004b44: e0a8 b.n 8004c98 + (mem->next - (ptr + SIZEOF_STRUCT_MEM)) >= size) { + 8004b46: 697b ldr r3, [r7, #20] + 8004b48: 881b ldrh r3, [r3, #0] + 8004b4a: 001a movs r2, r3 + 8004b4c: 231e movs r3, #30 + 8004b4e: 18fb adds r3, r7, r3 + 8004b50: 881b ldrh r3, [r3, #0] + 8004b52: 1ad3 subs r3, r2, r3 + 8004b54: 3b08 subs r3, #8 + 8004b56: 001a movs r2, r3 + 8004b58: 1dbb adds r3, r7, #6 + 8004b5a: 881b ldrh r3, [r3, #0] + if ((!mem->used) && + 8004b5c: 429a cmp r2, r3 + 8004b5e: d200 bcs.n 8004b62 + 8004b60: e09a b.n 8004c98 + /* mem is not used and at least perfect fit is possible: + * mem->next - (ptr + SIZEOF_STRUCT_MEM) gives us the 'user data size' of mem */ + + if (mem->next - (ptr + SIZEOF_STRUCT_MEM) >= (size + SIZEOF_STRUCT_MEM + MIN_SIZE_ALIGNED)) { + 8004b62: 697b ldr r3, [r7, #20] + 8004b64: 881b ldrh r3, [r3, #0] + 8004b66: 001a movs r2, r3 + 8004b68: 231e movs r3, #30 + 8004b6a: 18fb adds r3, r7, r3 + 8004b6c: 881b ldrh r3, [r3, #0] + 8004b6e: 1ad3 subs r3, r2, r3 + 8004b70: 3b08 subs r3, #8 + 8004b72: 001a movs r2, r3 + 8004b74: 1dbb adds r3, r7, #6 + 8004b76: 881b ldrh r3, [r3, #0] + 8004b78: 3314 adds r3, #20 + 8004b7a: 429a cmp r2, r3 + 8004b7c: d34c bcc.n 8004c18 + * struct mem would fit in but no data between mem2 and mem2->next + * @todo we could leave out MIN_SIZE_ALIGNED. We would create an empty + * region that couldn't hold data, but when mem->next gets freed, + * the 2 regions would be combined, resulting in more free memory + */ + ptr2 = ptr + SIZEOF_STRUCT_MEM + size; + 8004b7e: 201e movs r0, #30 + 8004b80: 183a adds r2, r7, r0 + 8004b82: 1dbb adds r3, r7, #6 + 8004b84: 8812 ldrh r2, [r2, #0] + 8004b86: 881b ldrh r3, [r3, #0] + 8004b88: 18d3 adds r3, r2, r3 + 8004b8a: b29a uxth r2, r3 + 8004b8c: 2112 movs r1, #18 + 8004b8e: 187b adds r3, r7, r1 + 8004b90: 3208 adds r2, #8 + 8004b92: 801a strh r2, [r3, #0] + /* create mem2 struct */ + mem2 = (struct mem *)(void *)&ram[ptr2]; + 8004b94: 4b52 ldr r3, [pc, #328] ; (8004ce0 ) + 8004b96: 681a ldr r2, [r3, #0] + 8004b98: 187b adds r3, r7, r1 + 8004b9a: 881b ldrh r3, [r3, #0] + 8004b9c: 18d3 adds r3, r2, r3 + 8004b9e: 60fb str r3, [r7, #12] + mem2->used = 0; + 8004ba0: 68fb ldr r3, [r7, #12] + 8004ba2: 2200 movs r2, #0 + 8004ba4: 711a strb r2, [r3, #4] + mem2->next = mem->next; + 8004ba6: 697b ldr r3, [r7, #20] + 8004ba8: 881a ldrh r2, [r3, #0] + 8004baa: 68fb ldr r3, [r7, #12] + 8004bac: 801a strh r2, [r3, #0] + mem2->prev = ptr; + 8004bae: 68fb ldr r3, [r7, #12] + 8004bb0: 183a adds r2, r7, r0 + 8004bb2: 8812 ldrh r2, [r2, #0] + 8004bb4: 805a strh r2, [r3, #2] + /* and insert it between mem and mem->next */ + mem->next = ptr2; + 8004bb6: 697b ldr r3, [r7, #20] + 8004bb8: 187a adds r2, r7, r1 + 8004bba: 8812 ldrh r2, [r2, #0] + 8004bbc: 801a strh r2, [r3, #0] + mem->used = 1; + 8004bbe: 697b ldr r3, [r7, #20] + 8004bc0: 2201 movs r2, #1 + 8004bc2: 711a strb r2, [r3, #4] + + if (mem2->next != MEM_SIZE_ALIGNED) { + 8004bc4: 68fb ldr r3, [r7, #12] + 8004bc6: 881a ldrh r2, [r3, #0] + 8004bc8: 23c8 movs r3, #200 ; 0xc8 + 8004bca: 00db lsls r3, r3, #3 + 8004bcc: 429a cmp r2, r3 + 8004bce: d008 beq.n 8004be2 + ((struct mem *)(void *)&ram[mem2->next])->prev = ptr2; + 8004bd0: 4b43 ldr r3, [pc, #268] ; (8004ce0 ) + 8004bd2: 681b ldr r3, [r3, #0] + 8004bd4: 68fa ldr r2, [r7, #12] + 8004bd6: 8812 ldrh r2, [r2, #0] + 8004bd8: 189b adds r3, r3, r2 + 8004bda: 2212 movs r2, #18 + 8004bdc: 18ba adds r2, r7, r2 + 8004bde: 8812 ldrh r2, [r2, #0] + 8004be0: 805a strh r2, [r3, #2] + } + MEM_STATS_INC_USED(used, (size + SIZEOF_STRUCT_MEM)); + 8004be2: 4b40 ldr r3, [pc, #256] ; (8004ce4 ) + 8004be4: 22aa movs r2, #170 ; 0xaa + 8004be6: 5a9a ldrh r2, [r3, r2] + 8004be8: 1dbb adds r3, r7, #6 + 8004bea: 881b ldrh r3, [r3, #0] + 8004bec: 18d3 adds r3, r2, r3 + 8004bee: b29b uxth r3, r3 + 8004bf0: 3308 adds r3, #8 + 8004bf2: b299 uxth r1, r3 + 8004bf4: 4b3b ldr r3, [pc, #236] ; (8004ce4 ) + 8004bf6: 22aa movs r2, #170 ; 0xaa + 8004bf8: 5299 strh r1, [r3, r2] + 8004bfa: 4b3a ldr r3, [pc, #232] ; (8004ce4 ) + 8004bfc: 22ac movs r2, #172 ; 0xac + 8004bfe: 5a9a ldrh r2, [r3, r2] + 8004c00: 4b38 ldr r3, [pc, #224] ; (8004ce4 ) + 8004c02: 21aa movs r1, #170 ; 0xaa + 8004c04: 5a5b ldrh r3, [r3, r1] + 8004c06: 429a cmp r2, r3 + 8004c08: d228 bcs.n 8004c5c + 8004c0a: 4b36 ldr r3, [pc, #216] ; (8004ce4 ) + 8004c0c: 22aa movs r2, #170 ; 0xaa + 8004c0e: 5a99 ldrh r1, [r3, r2] + 8004c10: 4b34 ldr r3, [pc, #208] ; (8004ce4 ) + 8004c12: 22ac movs r2, #172 ; 0xac + 8004c14: 5299 strh r1, [r3, r2] + 8004c16: e021 b.n 8004c5c + * take care of this). + * -> near fit or excact fit: do not split, no mem2 creation + * also can't move mem->next directly behind mem, since mem->next + * will always be used at this point! + */ + mem->used = 1; + 8004c18: 697b ldr r3, [r7, #20] + 8004c1a: 2201 movs r2, #1 + 8004c1c: 711a strb r2, [r3, #4] + MEM_STATS_INC_USED(used, mem->next - (mem_size_t)((u8_t *)mem - ram)); + 8004c1e: 4b31 ldr r3, [pc, #196] ; (8004ce4 ) + 8004c20: 22aa movs r2, #170 ; 0xaa + 8004c22: 5a9a ldrh r2, [r3, r2] + 8004c24: 697b ldr r3, [r7, #20] + 8004c26: 8819 ldrh r1, [r3, #0] + 8004c28: 6978 ldr r0, [r7, #20] + 8004c2a: 4b2d ldr r3, [pc, #180] ; (8004ce0 ) + 8004c2c: 681b ldr r3, [r3, #0] + 8004c2e: 1ac3 subs r3, r0, r3 + 8004c30: b29b uxth r3, r3 + 8004c32: 1acb subs r3, r1, r3 + 8004c34: b29b uxth r3, r3 + 8004c36: 18d3 adds r3, r2, r3 + 8004c38: b299 uxth r1, r3 + 8004c3a: 4b2a ldr r3, [pc, #168] ; (8004ce4 ) + 8004c3c: 22aa movs r2, #170 ; 0xaa + 8004c3e: 5299 strh r1, [r3, r2] + 8004c40: 4b28 ldr r3, [pc, #160] ; (8004ce4 ) + 8004c42: 22ac movs r2, #172 ; 0xac + 8004c44: 5a9a ldrh r2, [r3, r2] + 8004c46: 4b27 ldr r3, [pc, #156] ; (8004ce4 ) + 8004c48: 21aa movs r1, #170 ; 0xaa + 8004c4a: 5a5b ldrh r3, [r3, r1] + 8004c4c: 429a cmp r2, r3 + 8004c4e: d205 bcs.n 8004c5c + 8004c50: 4b24 ldr r3, [pc, #144] ; (8004ce4 ) + 8004c52: 22aa movs r2, #170 ; 0xaa + 8004c54: 5a99 ldrh r1, [r3, r2] + 8004c56: 4b23 ldr r3, [pc, #140] ; (8004ce4 ) + 8004c58: 22ac movs r2, #172 ; 0xac + 8004c5a: 5299 strh r1, [r3, r2] + } +#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT +mem_malloc_adjust_lfree: +#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */ + if (mem == lfree) { + 8004c5c: 4b1f ldr r3, [pc, #124] ; (8004cdc ) + 8004c5e: 681b ldr r3, [r3, #0] + 8004c60: 697a ldr r2, [r7, #20] + 8004c62: 429a cmp r2, r3 + 8004c64: d115 bne.n 8004c92 + struct mem *cur = lfree; + 8004c66: 4b1d ldr r3, [pc, #116] ; (8004cdc ) + 8004c68: 681b ldr r3, [r3, #0] + 8004c6a: 61bb str r3, [r7, #24] + /* Find next free block after mem and update lowest free pointer */ + while (cur->used && cur != ram_end) { + 8004c6c: e005 b.n 8004c7a + /* If mem_free or mem_trim have run, we have to restart since they + could have altered our current struct mem or lfree. */ + goto mem_malloc_adjust_lfree; + } +#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */ + cur = (struct mem *)(void *)&ram[cur->next]; + 8004c6e: 4b1c ldr r3, [pc, #112] ; (8004ce0 ) + 8004c70: 681b ldr r3, [r3, #0] + 8004c72: 69ba ldr r2, [r7, #24] + 8004c74: 8812 ldrh r2, [r2, #0] + 8004c76: 189b adds r3, r3, r2 + 8004c78: 61bb str r3, [r7, #24] + while (cur->used && cur != ram_end) { + 8004c7a: 69bb ldr r3, [r7, #24] + 8004c7c: 791b ldrb r3, [r3, #4] + 8004c7e: 2b00 cmp r3, #0 + 8004c80: d004 beq.n 8004c8c + 8004c82: 4b19 ldr r3, [pc, #100] ; (8004ce8 ) + 8004c84: 681b ldr r3, [r3, #0] + 8004c86: 69ba ldr r2, [r7, #24] + 8004c88: 429a cmp r2, r3 + 8004c8a: d1f0 bne.n 8004c6e + } + lfree = cur; + 8004c8c: 4b13 ldr r3, [pc, #76] ; (8004cdc ) + 8004c8e: 69ba ldr r2, [r7, #24] + 8004c90: 601a str r2, [r3, #0] + LWIP_ASSERT("mem_malloc: allocated memory properly aligned.", + ((mem_ptr_t)mem + SIZEOF_STRUCT_MEM) % MEM_ALIGNMENT == 0); + LWIP_ASSERT("mem_malloc: sanity check alignment", + (((mem_ptr_t)mem) & (MEM_ALIGNMENT-1)) == 0); + + return (u8_t *)mem + SIZEOF_STRUCT_MEM; + 8004c92: 697b ldr r3, [r7, #20] + 8004c94: 3308 adds r3, #8 + 8004c96: e01c b.n 8004cd2 + ptr = ((struct mem *)(void *)&ram[ptr])->next) { + 8004c98: 4b11 ldr r3, [pc, #68] ; (8004ce0 ) + 8004c9a: 681a ldr r2, [r3, #0] + 8004c9c: 211e movs r1, #30 + 8004c9e: 187b adds r3, r7, r1 + 8004ca0: 881b ldrh r3, [r3, #0] + 8004ca2: 18d2 adds r2, r2, r3 + 8004ca4: 187b adds r3, r7, r1 + 8004ca6: 8812 ldrh r2, [r2, #0] + 8004ca8: 801a strh r2, [r3, #0] + for (ptr = (mem_size_t)((u8_t *)lfree - ram); ptr < MEM_SIZE_ALIGNED - size; + 8004caa: 231e movs r3, #30 + 8004cac: 18fb adds r3, r7, r3 + 8004cae: 881a ldrh r2, [r3, #0] + 8004cb0: 1dbb adds r3, r7, #6 + 8004cb2: 881b ldrh r3, [r3, #0] + 8004cb4: 21c8 movs r1, #200 ; 0xc8 + 8004cb6: 00c9 lsls r1, r1, #3 + 8004cb8: 1acb subs r3, r1, r3 + 8004cba: 429a cmp r2, r3 + 8004cbc: da00 bge.n 8004cc0 + 8004cbe: e736 b.n 8004b2e +#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT + /* if we got interrupted by a mem_free, try again */ + } while(local_mem_free_count != 0); +#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */ + LWIP_DEBUGF(MEM_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("mem_malloc: could not allocate %"S16_F" bytes\n", (s16_t)size)); + MEM_STATS_INC(err); + 8004cc0: 4b08 ldr r3, [pc, #32] ; (8004ce4 ) + 8004cc2: 22ae movs r2, #174 ; 0xae + 8004cc4: 5a9b ldrh r3, [r3, r2] + 8004cc6: 3301 adds r3, #1 + 8004cc8: b299 uxth r1, r3 + 8004cca: 4b06 ldr r3, [pc, #24] ; (8004ce4 ) + 8004ccc: 22ae movs r2, #174 ; 0xae + 8004cce: 5299 strh r1, [r3, r2] + LWIP_MEM_ALLOC_UNPROTECT(); + sys_mutex_unlock(&mem_mutex); + return NULL; + 8004cd0: 2300 movs r3, #0 +} + 8004cd2: 0018 movs r0, r3 + 8004cd4: 46bd mov sp, r7 + 8004cd6: b008 add sp, #32 + 8004cd8: bd80 pop {r7, pc} + 8004cda: 46c0 nop ; (mov r8, r8) + 8004cdc: 20000154 .word 0x20000154 + 8004ce0: 2000014c .word 0x2000014c + 8004ce4: 20003158 .word 0x20003158 + 8004ce8: 20000150 .word 0x20000150 + +08004cec : + * + * Carves out memp_memory into linked lists for each pool-type. + */ +void +memp_init(void) +{ + 8004cec: b590 push {r4, r7, lr} + 8004cee: b083 sub sp, #12 + 8004cf0: af00 add r7, sp, #0 + struct memp *memp; + u16_t i, j; + + for (i = 0; i < MEMP_MAX; ++i) { + 8004cf2: 1cbb adds r3, r7, #2 + 8004cf4: 2200 movs r2, #0 + 8004cf6: 801a strh r2, [r3, #0] + 8004cf8: e039 b.n 8004d6e + MEMP_STATS_AVAIL(used, i, 0); + 8004cfa: 1cbb adds r3, r7, #2 + 8004cfc: 881a ldrh r2, [r3, #0] + 8004cfe: 4940 ldr r1, [pc, #256] ; (8004e00 ) + 8004d00: 20b4 movs r0, #180 ; 0xb4 + 8004d02: 0013 movs r3, r2 + 8004d04: 009b lsls r3, r3, #2 + 8004d06: 189b adds r3, r3, r2 + 8004d08: 005b lsls r3, r3, #1 + 8004d0a: 18cb adds r3, r1, r3 + 8004d0c: 181b adds r3, r3, r0 + 8004d0e: 2200 movs r2, #0 + 8004d10: 801a strh r2, [r3, #0] + MEMP_STATS_AVAIL(max, i, 0); + 8004d12: 1cbb adds r3, r7, #2 + 8004d14: 881a ldrh r2, [r3, #0] + 8004d16: 493a ldr r1, [pc, #232] ; (8004e00 ) + 8004d18: 20b6 movs r0, #182 ; 0xb6 + 8004d1a: 0013 movs r3, r2 + 8004d1c: 009b lsls r3, r3, #2 + 8004d1e: 189b adds r3, r3, r2 + 8004d20: 005b lsls r3, r3, #1 + 8004d22: 18cb adds r3, r1, r3 + 8004d24: 181b adds r3, r3, r0 + 8004d26: 2200 movs r2, #0 + 8004d28: 801a strh r2, [r3, #0] + MEMP_STATS_AVAIL(err, i, 0); + 8004d2a: 1cbb adds r3, r7, #2 + 8004d2c: 881a ldrh r2, [r3, #0] + 8004d2e: 4934 ldr r1, [pc, #208] ; (8004e00 ) + 8004d30: 20b8 movs r0, #184 ; 0xb8 + 8004d32: 0013 movs r3, r2 + 8004d34: 009b lsls r3, r3, #2 + 8004d36: 189b adds r3, r3, r2 + 8004d38: 005b lsls r3, r3, #1 + 8004d3a: 18cb adds r3, r1, r3 + 8004d3c: 181b adds r3, r3, r0 + 8004d3e: 2200 movs r2, #0 + 8004d40: 801a strh r2, [r3, #0] + MEMP_STATS_AVAIL(avail, i, memp_num[i]); + 8004d42: 1cbb adds r3, r7, #2 + 8004d44: 8819 ldrh r1, [r3, #0] + 8004d46: 1cbb adds r3, r7, #2 + 8004d48: 881a ldrh r2, [r3, #0] + 8004d4a: 4b2e ldr r3, [pc, #184] ; (8004e04 ) + 8004d4c: 0049 lsls r1, r1, #1 + 8004d4e: 5acc ldrh r4, [r1, r3] + 8004d50: 492b ldr r1, [pc, #172] ; (8004e00 ) + 8004d52: 20b2 movs r0, #178 ; 0xb2 + 8004d54: 0013 movs r3, r2 + 8004d56: 009b lsls r3, r3, #2 + 8004d58: 189b adds r3, r3, r2 + 8004d5a: 005b lsls r3, r3, #1 + 8004d5c: 18cb adds r3, r1, r3 + 8004d5e: 181b adds r3, r3, r0 + 8004d60: 1c22 adds r2, r4, #0 + 8004d62: 801a strh r2, [r3, #0] + for (i = 0; i < MEMP_MAX; ++i) { + 8004d64: 1cbb adds r3, r7, #2 + 8004d66: 1cba adds r2, r7, #2 + 8004d68: 8812 ldrh r2, [r2, #0] + 8004d6a: 3201 adds r2, #1 + 8004d6c: 801a strh r2, [r3, #0] + 8004d6e: 1cbb adds r3, r7, #2 + 8004d70: 881b ldrh r3, [r3, #0] + 8004d72: 2b09 cmp r3, #9 + 8004d74: d9c1 bls.n 8004cfa + } + +#if !MEMP_SEPARATE_POOLS + memp = (struct memp *)LWIP_MEM_ALIGN(memp_memory); + 8004d76: 4b24 ldr r3, [pc, #144] ; (8004e08 ) + 8004d78: 3303 adds r3, #3 + 8004d7a: 2203 movs r2, #3 + 8004d7c: 4393 bics r3, r2 + 8004d7e: 607b str r3, [r7, #4] +#endif /* !MEMP_SEPARATE_POOLS */ + /* for every pool: */ + for (i = 0; i < MEMP_MAX; ++i) { + 8004d80: 1cbb adds r3, r7, #2 + 8004d82: 2200 movs r2, #0 + 8004d84: 801a strh r2, [r3, #0] + 8004d86: e032 b.n 8004dee + memp_tab[i] = NULL; + 8004d88: 1cbb adds r3, r7, #2 + 8004d8a: 881a ldrh r2, [r3, #0] + 8004d8c: 4b1f ldr r3, [pc, #124] ; (8004e0c ) + 8004d8e: 0092 lsls r2, r2, #2 + 8004d90: 2100 movs r1, #0 + 8004d92: 50d1 str r1, [r2, r3] +#if MEMP_SEPARATE_POOLS + memp = (struct memp*)memp_bases[i]; +#endif /* MEMP_SEPARATE_POOLS */ + /* create a linked list of memp elements */ + for (j = 0; j < memp_num[i]; ++j) { + 8004d94: 003b movs r3, r7 + 8004d96: 2200 movs r2, #0 + 8004d98: 801a strh r2, [r3, #0] + 8004d9a: e01a b.n 8004dd2 + memp->next = memp_tab[i]; + 8004d9c: 1cbb adds r3, r7, #2 + 8004d9e: 881a ldrh r2, [r3, #0] + 8004da0: 4b1a ldr r3, [pc, #104] ; (8004e0c ) + 8004da2: 0092 lsls r2, r2, #2 + 8004da4: 58d2 ldr r2, [r2, r3] + 8004da6: 687b ldr r3, [r7, #4] + 8004da8: 601a str r2, [r3, #0] + memp_tab[i] = memp; + 8004daa: 1cbb adds r3, r7, #2 + 8004dac: 881a ldrh r2, [r3, #0] + 8004dae: 4b17 ldr r3, [pc, #92] ; (8004e0c ) + 8004db0: 0092 lsls r2, r2, #2 + 8004db2: 6879 ldr r1, [r7, #4] + 8004db4: 50d1 str r1, [r2, r3] + memp = (struct memp *)(void *)((u8_t *)memp + MEMP_SIZE + memp_sizes[i] + 8004db6: 1cbb adds r3, r7, #2 + 8004db8: 881a ldrh r2, [r3, #0] + 8004dba: 4b15 ldr r3, [pc, #84] ; (8004e10 ) + 8004dbc: 0052 lsls r2, r2, #1 + 8004dbe: 5ad3 ldrh r3, [r2, r3] + 8004dc0: 001a movs r2, r3 + 8004dc2: 687b ldr r3, [r7, #4] + 8004dc4: 189b adds r3, r3, r2 + 8004dc6: 607b str r3, [r7, #4] + for (j = 0; j < memp_num[i]; ++j) { + 8004dc8: 003b movs r3, r7 + 8004dca: 003a movs r2, r7 + 8004dcc: 8812 ldrh r2, [r2, #0] + 8004dce: 3201 adds r2, #1 + 8004dd0: 801a strh r2, [r3, #0] + 8004dd2: 1cbb adds r3, r7, #2 + 8004dd4: 881a ldrh r2, [r3, #0] + 8004dd6: 4b0b ldr r3, [pc, #44] ; (8004e04 ) + 8004dd8: 0052 lsls r2, r2, #1 + 8004dda: 5ad3 ldrh r3, [r2, r3] + 8004ddc: 003a movs r2, r7 + 8004dde: 8812 ldrh r2, [r2, #0] + 8004de0: 429a cmp r2, r3 + 8004de2: d3db bcc.n 8004d9c + for (i = 0; i < MEMP_MAX; ++i) { + 8004de4: 1cbb adds r3, r7, #2 + 8004de6: 1cba adds r2, r7, #2 + 8004de8: 8812 ldrh r2, [r2, #0] + 8004dea: 3201 adds r2, #1 + 8004dec: 801a strh r2, [r3, #0] + 8004dee: 1cbb adds r3, r7, #2 + 8004df0: 881b ldrh r3, [r3, #0] + 8004df2: 2b09 cmp r3, #9 + 8004df4: d9c8 bls.n 8004d88 +#if MEMP_OVERFLOW_CHECK + memp_overflow_init(); + /* check everything a first time to see if it worked */ + memp_overflow_check_all(); +#endif /* MEMP_OVERFLOW_CHECK */ +} + 8004df6: 46c0 nop ; (mov r8, r8) + 8004df8: 46bd mov sp, r7 + 8004dfa: b003 add sp, #12 + 8004dfc: bd90 pop {r4, r7, pc} + 8004dfe: 46c0 nop ; (mov r8, r8) + 8004e00: 20003158 .word 0x20003158 + 8004e04: 0800fd4c .word 0x0800fd4c + 8004e08: 20000180 .word 0x20000180 + 8004e0c: 20000158 .word 0x20000158 + 8004e10: 0800fd38 .word 0x0800fd38 + +08004e14 : +#if !MEMP_OVERFLOW_CHECK +memp_malloc(memp_t type) +#else +memp_malloc_fn(memp_t type, const char* file, const int line) +#endif +{ + 8004e14: b590 push {r4, r7, lr} + 8004e16: b085 sub sp, #20 + 8004e18: af00 add r7, sp, #0 + 8004e1a: 0002 movs r2, r0 + 8004e1c: 1dfb adds r3, r7, #7 + 8004e1e: 701a strb r2, [r3, #0] + struct memp *memp; + SYS_ARCH_DECL_PROTECT(old_level); + + LWIP_ERROR("memp_malloc: type < MEMP_MAX", (type < MEMP_MAX), return NULL;); + 8004e20: 1dfb adds r3, r7, #7 + 8004e22: 781b ldrb r3, [r3, #0] + 8004e24: 2b09 cmp r3, #9 + 8004e26: d901 bls.n 8004e2c + 8004e28: 2300 movs r3, #0 + 8004e2a: e070 b.n 8004f0e + SYS_ARCH_PROTECT(old_level); +#if MEMP_OVERFLOW_CHECK >= 2 + memp_overflow_check_all(); +#endif /* MEMP_OVERFLOW_CHECK >= 2 */ + + memp = memp_tab[type]; + 8004e2c: 1dfb adds r3, r7, #7 + 8004e2e: 781a ldrb r2, [r3, #0] + 8004e30: 4b39 ldr r3, [pc, #228] ; (8004f18 ) + 8004e32: 0092 lsls r2, r2, #2 + 8004e34: 58d3 ldr r3, [r2, r3] + 8004e36: 60fb str r3, [r7, #12] + + if (memp != NULL) { + 8004e38: 68fb ldr r3, [r7, #12] + 8004e3a: 2b00 cmp r3, #0 + 8004e3c: d04f beq.n 8004ede + memp_tab[type] = memp->next; + 8004e3e: 1dfb adds r3, r7, #7 + 8004e40: 781a ldrb r2, [r3, #0] + 8004e42: 68fb ldr r3, [r7, #12] + 8004e44: 6819 ldr r1, [r3, #0] + 8004e46: 4b34 ldr r3, [pc, #208] ; (8004f18 ) + 8004e48: 0092 lsls r2, r2, #2 + 8004e4a: 50d1 str r1, [r2, r3] +#if MEMP_OVERFLOW_CHECK + memp->next = NULL; + memp->file = file; + memp->line = line; +#endif /* MEMP_OVERFLOW_CHECK */ + MEMP_STATS_INC_USED(used, type); + 8004e4c: 1dfb adds r3, r7, #7 + 8004e4e: 781a ldrb r2, [r3, #0] + 8004e50: 4932 ldr r1, [pc, #200] ; (8004f1c ) + 8004e52: 20b4 movs r0, #180 ; 0xb4 + 8004e54: 0013 movs r3, r2 + 8004e56: 009b lsls r3, r3, #2 + 8004e58: 189b adds r3, r3, r2 + 8004e5a: 005b lsls r3, r3, #1 + 8004e5c: 18cb adds r3, r1, r3 + 8004e5e: 181b adds r3, r3, r0 + 8004e60: 881b ldrh r3, [r3, #0] + 8004e62: 1dfa adds r2, r7, #7 + 8004e64: 7812 ldrb r2, [r2, #0] + 8004e66: 3301 adds r3, #1 + 8004e68: b29c uxth r4, r3 + 8004e6a: 492c ldr r1, [pc, #176] ; (8004f1c ) + 8004e6c: 20b4 movs r0, #180 ; 0xb4 + 8004e6e: 0013 movs r3, r2 + 8004e70: 009b lsls r3, r3, #2 + 8004e72: 189b adds r3, r3, r2 + 8004e74: 005b lsls r3, r3, #1 + 8004e76: 18cb adds r3, r1, r3 + 8004e78: 181b adds r3, r3, r0 + 8004e7a: 1c22 adds r2, r4, #0 + 8004e7c: 801a strh r2, [r3, #0] + 8004e7e: 1dfb adds r3, r7, #7 + 8004e80: 781a ldrb r2, [r3, #0] + 8004e82: 4926 ldr r1, [pc, #152] ; (8004f1c ) + 8004e84: 20b6 movs r0, #182 ; 0xb6 + 8004e86: 0013 movs r3, r2 + 8004e88: 009b lsls r3, r3, #2 + 8004e8a: 189b adds r3, r3, r2 + 8004e8c: 005b lsls r3, r3, #1 + 8004e8e: 18cb adds r3, r1, r3 + 8004e90: 181b adds r3, r3, r0 + 8004e92: 8819 ldrh r1, [r3, #0] + 8004e94: 1dfb adds r3, r7, #7 + 8004e96: 781a ldrb r2, [r3, #0] + 8004e98: 4820 ldr r0, [pc, #128] ; (8004f1c ) + 8004e9a: 24b4 movs r4, #180 ; 0xb4 + 8004e9c: 0013 movs r3, r2 + 8004e9e: 009b lsls r3, r3, #2 + 8004ea0: 189b adds r3, r3, r2 + 8004ea2: 005b lsls r3, r3, #1 + 8004ea4: 18c3 adds r3, r0, r3 + 8004ea6: 191b adds r3, r3, r4 + 8004ea8: 881b ldrh r3, [r3, #0] + 8004eaa: 4299 cmp r1, r3 + 8004eac: d22e bcs.n 8004f0c + 8004eae: 1dfb adds r3, r7, #7 + 8004eb0: 7819 ldrb r1, [r3, #0] + 8004eb2: 1dfb adds r3, r7, #7 + 8004eb4: 781a ldrb r2, [r3, #0] + 8004eb6: 4819 ldr r0, [pc, #100] ; (8004f1c ) + 8004eb8: 24b4 movs r4, #180 ; 0xb4 + 8004eba: 000b movs r3, r1 + 8004ebc: 009b lsls r3, r3, #2 + 8004ebe: 185b adds r3, r3, r1 + 8004ec0: 005b lsls r3, r3, #1 + 8004ec2: 18c3 adds r3, r0, r3 + 8004ec4: 191b adds r3, r3, r4 + 8004ec6: 881c ldrh r4, [r3, #0] + 8004ec8: 4914 ldr r1, [pc, #80] ; (8004f1c ) + 8004eca: 20b6 movs r0, #182 ; 0xb6 + 8004ecc: 0013 movs r3, r2 + 8004ece: 009b lsls r3, r3, #2 + 8004ed0: 189b adds r3, r3, r2 + 8004ed2: 005b lsls r3, r3, #1 + 8004ed4: 18cb adds r3, r1, r3 + 8004ed6: 181b adds r3, r3, r0 + 8004ed8: 1c22 adds r2, r4, #0 + 8004eda: 801a strh r2, [r3, #0] + 8004edc: e016 b.n 8004f0c + LWIP_ASSERT("memp_malloc: memp properly aligned", + ((mem_ptr_t)memp % MEM_ALIGNMENT) == 0); + memp = (struct memp*)(void *)((u8_t*)memp + MEMP_SIZE); + } else { + LWIP_DEBUGF(MEMP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("memp_malloc: out of memory in pool %s\n", memp_desc[type])); + MEMP_STATS_INC(err, type); + 8004ede: 1dfb adds r3, r7, #7 + 8004ee0: 781a ldrb r2, [r3, #0] + 8004ee2: 490e ldr r1, [pc, #56] ; (8004f1c ) + 8004ee4: 20b8 movs r0, #184 ; 0xb8 + 8004ee6: 0013 movs r3, r2 + 8004ee8: 009b lsls r3, r3, #2 + 8004eea: 189b adds r3, r3, r2 + 8004eec: 005b lsls r3, r3, #1 + 8004eee: 18cb adds r3, r1, r3 + 8004ef0: 181b adds r3, r3, r0 + 8004ef2: 881b ldrh r3, [r3, #0] + 8004ef4: 3301 adds r3, #1 + 8004ef6: b29c uxth r4, r3 + 8004ef8: 4908 ldr r1, [pc, #32] ; (8004f1c ) + 8004efa: 20b8 movs r0, #184 ; 0xb8 + 8004efc: 0013 movs r3, r2 + 8004efe: 009b lsls r3, r3, #2 + 8004f00: 189b adds r3, r3, r2 + 8004f02: 005b lsls r3, r3, #1 + 8004f04: 18cb adds r3, r1, r3 + 8004f06: 181b adds r3, r3, r0 + 8004f08: 1c22 adds r2, r4, #0 + 8004f0a: 801a strh r2, [r3, #0] + } + + SYS_ARCH_UNPROTECT(old_level); + + return memp; + 8004f0c: 68fb ldr r3, [r7, #12] +} + 8004f0e: 0018 movs r0, r3 + 8004f10: 46bd mov sp, r7 + 8004f12: b005 add sp, #20 + 8004f14: bd90 pop {r4, r7, pc} + 8004f16: 46c0 nop ; (mov r8, r8) + 8004f18: 20000158 .word 0x20000158 + 8004f1c: 20003158 .word 0x20003158 + +08004f20 : + * @param type the pool where to put mem + * @param mem the memp element to free + */ +void +memp_free(memp_t type, void *mem) +{ + 8004f20: b590 push {r4, r7, lr} + 8004f22: b085 sub sp, #20 + 8004f24: af00 add r7, sp, #0 + 8004f26: 0002 movs r2, r0 + 8004f28: 6039 str r1, [r7, #0] + 8004f2a: 1dfb adds r3, r7, #7 + 8004f2c: 701a strb r2, [r3, #0] + struct memp *memp; + SYS_ARCH_DECL_PROTECT(old_level); + + if (mem == NULL) { + 8004f2e: 683b ldr r3, [r7, #0] + 8004f30: 2b00 cmp r3, #0 + 8004f32: d026 beq.n 8004f82 + return; + } + LWIP_ASSERT("memp_free: mem properly aligned", + ((mem_ptr_t)mem % MEM_ALIGNMENT) == 0); + + memp = (struct memp *)(void *)((u8_t*)mem - MEMP_SIZE); + 8004f34: 683b ldr r3, [r7, #0] + 8004f36: 60fb str r3, [r7, #12] + memp_overflow_check_element_overflow(memp, type); + memp_overflow_check_element_underflow(memp, type); +#endif /* MEMP_OVERFLOW_CHECK >= 2 */ +#endif /* MEMP_OVERFLOW_CHECK */ + + MEMP_STATS_DEC(used, type); + 8004f38: 1dfb adds r3, r7, #7 + 8004f3a: 781a ldrb r2, [r3, #0] + 8004f3c: 4913 ldr r1, [pc, #76] ; (8004f8c ) + 8004f3e: 20b4 movs r0, #180 ; 0xb4 + 8004f40: 0013 movs r3, r2 + 8004f42: 009b lsls r3, r3, #2 + 8004f44: 189b adds r3, r3, r2 + 8004f46: 005b lsls r3, r3, #1 + 8004f48: 18cb adds r3, r1, r3 + 8004f4a: 181b adds r3, r3, r0 + 8004f4c: 881b ldrh r3, [r3, #0] + 8004f4e: 3b01 subs r3, #1 + 8004f50: b29c uxth r4, r3 + 8004f52: 490e ldr r1, [pc, #56] ; (8004f8c ) + 8004f54: 20b4 movs r0, #180 ; 0xb4 + 8004f56: 0013 movs r3, r2 + 8004f58: 009b lsls r3, r3, #2 + 8004f5a: 189b adds r3, r3, r2 + 8004f5c: 005b lsls r3, r3, #1 + 8004f5e: 18cb adds r3, r1, r3 + 8004f60: 181b adds r3, r3, r0 + 8004f62: 1c22 adds r2, r4, #0 + 8004f64: 801a strh r2, [r3, #0] + + memp->next = memp_tab[type]; + 8004f66: 1dfb adds r3, r7, #7 + 8004f68: 781a ldrb r2, [r3, #0] + 8004f6a: 4b09 ldr r3, [pc, #36] ; (8004f90 ) + 8004f6c: 0092 lsls r2, r2, #2 + 8004f6e: 58d2 ldr r2, [r2, r3] + 8004f70: 68fb ldr r3, [r7, #12] + 8004f72: 601a str r2, [r3, #0] + memp_tab[type] = memp; + 8004f74: 1dfb adds r3, r7, #7 + 8004f76: 781a ldrb r2, [r3, #0] + 8004f78: 4b05 ldr r3, [pc, #20] ; (8004f90 ) + 8004f7a: 0092 lsls r2, r2, #2 + 8004f7c: 68f9 ldr r1, [r7, #12] + 8004f7e: 50d1 str r1, [r2, r3] + 8004f80: e000 b.n 8004f84 + return; + 8004f82: 46c0 nop ; (mov r8, r8) +#if MEMP_SANITY_CHECK + LWIP_ASSERT("memp sanity", memp_sanity()); +#endif /* MEMP_SANITY_CHECK */ + + SYS_ARCH_UNPROTECT(old_level); +} + 8004f84: 46bd mov sp, r7 + 8004f86: b005 add sp, #20 + 8004f88: bd90 pop {r4, r7, pc} + 8004f8a: 46c0 nop ; (mov r8, r8) + 8004f8c: 20003158 .word 0x20003158 + 8004f90: 20000158 .word 0x20000158 + +08004f94 : +} +#endif /* LWIP_HAVE_LOOPIF */ + +void +netif_init(void) +{ + 8004f94: b580 push {r7, lr} + 8004f96: af00 add r7, sp, #0 + netif_add(&loop_netif, &loop_ipaddr, &loop_netmask, &loop_gw, NULL, netif_loopif_init, tcpip_input); +#endif /* NO_SYS */ + netif_set_up(&loop_netif); + +#endif /* LWIP_HAVE_LOOPIF */ +} + 8004f98: 46c0 nop ; (mov r8, r8) + 8004f9a: 46bd mov sp, r7 + 8004f9c: bd80 pop {r7, pc} + ... + +08004fa0 : + * @return netif, or NULL if failed. + */ +struct netif * +netif_add(struct netif *netif, ip_addr_t *ipaddr, ip_addr_t *netmask, + ip_addr_t *gw, void *state, netif_init_fn init, netif_input_fn input) +{ + 8004fa0: b580 push {r7, lr} + 8004fa2: b084 sub sp, #16 + 8004fa4: af00 add r7, sp, #0 + 8004fa6: 60f8 str r0, [r7, #12] + 8004fa8: 60b9 str r1, [r7, #8] + 8004faa: 607a str r2, [r7, #4] + 8004fac: 603b str r3, [r7, #0] + + LWIP_ASSERT("No init function given", init != NULL); + + /* reset new interface configuration state */ + ip_addr_set_zero(&netif->ip_addr); + 8004fae: 68fb ldr r3, [r7, #12] + 8004fb0: 2200 movs r2, #0 + 8004fb2: 605a str r2, [r3, #4] + ip_addr_set_zero(&netif->netmask); + 8004fb4: 68fb ldr r3, [r7, #12] + 8004fb6: 2200 movs r2, #0 + 8004fb8: 609a str r2, [r3, #8] + ip_addr_set_zero(&netif->gw); + 8004fba: 68fb ldr r3, [r7, #12] + 8004fbc: 2200 movs r2, #0 + 8004fbe: 60da str r2, [r3, #12] + netif->flags = 0; + 8004fc0: 68fb ldr r3, [r7, #12] + 8004fc2: 2229 movs r2, #41 ; 0x29 + 8004fc4: 2100 movs r1, #0 + 8004fc6: 5499 strb r1, [r3, r2] + netif->loop_first = NULL; + netif->loop_last = NULL; +#endif /* ENABLE_LOOPBACK */ + + /* remember netif specific state information data */ + netif->state = state; + 8004fc8: 68fb ldr r3, [r7, #12] + 8004fca: 69ba ldr r2, [r7, #24] + 8004fcc: 61da str r2, [r3, #28] + netif->num = netif_num++; + 8004fce: 4b13 ldr r3, [pc, #76] ; (800501c ) + 8004fd0: 781b ldrb r3, [r3, #0] + 8004fd2: 1c5a adds r2, r3, #1 + 8004fd4: b2d1 uxtb r1, r2 + 8004fd6: 4a11 ldr r2, [pc, #68] ; (800501c ) + 8004fd8: 7011 strb r1, [r2, #0] + 8004fda: 68fa ldr r2, [r7, #12] + 8004fdc: 212c movs r1, #44 ; 0x2c + 8004fde: 5453 strb r3, [r2, r1] + netif->input = input; + 8004fe0: 68fb ldr r3, [r7, #12] + 8004fe2: 6a3a ldr r2, [r7, #32] + 8004fe4: 611a str r2, [r3, #16] + NETIF_SET_HWADDRHINT(netif, NULL); +#if ENABLE_LOOPBACK && LWIP_LOOPBACK_MAX_PBUFS + netif->loop_cnt_current = 0; +#endif /* ENABLE_LOOPBACK && LWIP_LOOPBACK_MAX_PBUFS */ + + netif_set_addr(netif, ipaddr, netmask, gw); + 8004fe6: 683b ldr r3, [r7, #0] + 8004fe8: 687a ldr r2, [r7, #4] + 8004fea: 68b9 ldr r1, [r7, #8] + 8004fec: 68f8 ldr r0, [r7, #12] + 8004fee: f000 f819 bl 8005024 + + /* call user specified initialization function for netif */ + if (init(netif) != ERR_OK) { + 8004ff2: 68fa ldr r2, [r7, #12] + 8004ff4: 69fb ldr r3, [r7, #28] + 8004ff6: 0010 movs r0, r2 + 8004ff8: 4798 blx r3 + 8004ffa: 1e03 subs r3, r0, #0 + 8004ffc: d001 beq.n 8005002 + return NULL; + 8004ffe: 2300 movs r3, #0 + 8005000: e007 b.n 8005012 + } + + /* add this netif to the list */ + netif->next = netif_list; + 8005002: 4b07 ldr r3, [pc, #28] ; (8005020 ) + 8005004: 681a ldr r2, [r3, #0] + 8005006: 68fb ldr r3, [r7, #12] + 8005008: 601a str r2, [r3, #0] + netif_list = netif; + 800500a: 4b05 ldr r3, [pc, #20] ; (8005020 ) + 800500c: 68fa ldr r2, [r7, #12] + 800500e: 601a str r2, [r3, #0] + LWIP_DEBUGF(NETIF_DEBUG, (" netmask ")); + ip_addr_debug_print(NETIF_DEBUG, netmask); + LWIP_DEBUGF(NETIF_DEBUG, (" gw ")); + ip_addr_debug_print(NETIF_DEBUG, gw); + LWIP_DEBUGF(NETIF_DEBUG, ("\n")); + return netif; + 8005010: 68fb ldr r3, [r7, #12] +} + 8005012: 0018 movs r0, r3 + 8005014: 46bd mov sp, r7 + 8005016: b004 add sp, #16 + 8005018: bd80 pop {r7, pc} + 800501a: 46c0 nop ; (mov r8, r8) + 800501c: 20002273 .word 0x20002273 + 8005020: 2000314c .word 0x2000314c + +08005024 : + * @param gw the new default gateway + */ +void +netif_set_addr(struct netif *netif, ip_addr_t *ipaddr, ip_addr_t *netmask, + ip_addr_t *gw) +{ + 8005024: b580 push {r7, lr} + 8005026: b084 sub sp, #16 + 8005028: af00 add r7, sp, #0 + 800502a: 60f8 str r0, [r7, #12] + 800502c: 60b9 str r1, [r7, #8] + 800502e: 607a str r2, [r7, #4] + 8005030: 603b str r3, [r7, #0] + netif_set_ipaddr(netif, ipaddr); + 8005032: 68ba ldr r2, [r7, #8] + 8005034: 68fb ldr r3, [r7, #12] + 8005036: 0011 movs r1, r2 + 8005038: 0018 movs r0, r3 + 800503a: f000 f811 bl 8005060 + netif_set_netmask(netif, netmask); + 800503e: 687a ldr r2, [r7, #4] + 8005040: 68fb ldr r3, [r7, #12] + 8005042: 0011 movs r1, r2 + 8005044: 0018 movs r0, r3 + 8005046: f000 f877 bl 8005138 + netif_set_gw(netif, gw); + 800504a: 683a ldr r2, [r7, #0] + 800504c: 68fb ldr r3, [r7, #12] + 800504e: 0011 movs r1, r2 + 8005050: 0018 movs r0, r3 + 8005052: f000 f85f bl 8005114 +} + 8005056: 46c0 nop ; (mov r8, r8) + 8005058: 46bd mov sp, r7 + 800505a: b004 add sp, #16 + 800505c: bd80 pop {r7, pc} + ... + +08005060 : + * @note call netif_set_addr() if you also want to change netmask and + * default gateway + */ +void +netif_set_ipaddr(struct netif *netif, ip_addr_t *ipaddr) +{ + 8005060: b580 push {r7, lr} + 8005062: b086 sub sp, #24 + 8005064: af00 add r7, sp, #0 + 8005066: 6078 str r0, [r7, #4] + 8005068: 6039 str r1, [r7, #0] +#if LWIP_TCP + struct tcp_pcb *pcb; + struct tcp_pcb_listen *lpcb; + + /* address is actually being changed? */ + if (ipaddr && (ip_addr_cmp(ipaddr, &(netif->ip_addr))) == 0) { + 800506a: 683b ldr r3, [r7, #0] + 800506c: 2b00 cmp r3, #0 + 800506e: d03f beq.n 80050f0 + 8005070: 683b ldr r3, [r7, #0] + 8005072: 681a ldr r2, [r3, #0] + 8005074: 687b ldr r3, [r7, #4] + 8005076: 685b ldr r3, [r3, #4] + 8005078: 429a cmp r2, r3 + 800507a: d039 beq.n 80050f0 + /* extern struct tcp_pcb *tcp_active_pcbs; defined by tcp.h */ + LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_STATE, ("netif_set_ipaddr: netif address being changed\n")); + pcb = tcp_active_pcbs; + 800507c: 4b23 ldr r3, [pc, #140] ; (800510c ) + 800507e: 681b ldr r3, [r3, #0] + 8005080: 617b str r3, [r7, #20] + while (pcb != NULL) { + 8005082: e012 b.n 80050aa + /* PCB bound to current local interface address? */ + if (ip_addr_cmp(&(pcb->local_ip), &(netif->ip_addr)) + 8005084: 697b ldr r3, [r7, #20] + 8005086: 681a ldr r2, [r3, #0] + 8005088: 687b ldr r3, [r7, #4] + 800508a: 685b ldr r3, [r3, #4] + 800508c: 429a cmp r2, r3 + 800508e: d109 bne.n 80050a4 + /* connections to link-local addresses must persist (RFC3927 ch. 1.9) */ + && !ip_addr_islinklocal(&(pcb->local_ip)) +#endif /* LWIP_AUTOIP */ + ) { + /* this connection must be aborted */ + struct tcp_pcb *next = pcb->next; + 8005090: 697b ldr r3, [r7, #20] + 8005092: 68db ldr r3, [r3, #12] + 8005094: 60fb str r3, [r7, #12] + LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_STATE, ("netif_set_ipaddr: aborting TCP pcb %p\n", (void *)pcb)); + tcp_abort(pcb); + 8005096: 697b ldr r3, [r7, #20] + 8005098: 0018 movs r0, r3 + 800509a: f000 ff6f bl 8005f7c + pcb = next; + 800509e: 68fb ldr r3, [r7, #12] + 80050a0: 617b str r3, [r7, #20] + 80050a2: e002 b.n 80050aa + } else { + pcb = pcb->next; + 80050a4: 697b ldr r3, [r7, #20] + 80050a6: 68db ldr r3, [r3, #12] + 80050a8: 617b str r3, [r7, #20] + while (pcb != NULL) { + 80050aa: 697b ldr r3, [r7, #20] + 80050ac: 2b00 cmp r3, #0 + 80050ae: d1e9 bne.n 8005084 + } + } + for (lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next) { + 80050b0: 4b17 ldr r3, [pc, #92] ; (8005110 ) + 80050b2: 681b ldr r3, [r3, #0] + 80050b4: 613b str r3, [r7, #16] + 80050b6: e018 b.n 80050ea + /* PCB bound to current local interface address? */ + if ((!(ip_addr_isany(&(lpcb->local_ip)))) && + 80050b8: 693b ldr r3, [r7, #16] + 80050ba: 2b00 cmp r3, #0 + 80050bc: d012 beq.n 80050e4 + 80050be: 693b ldr r3, [r7, #16] + 80050c0: 681b ldr r3, [r3, #0] + 80050c2: 2b00 cmp r3, #0 + 80050c4: d00e beq.n 80050e4 + (ip_addr_cmp(&(lpcb->local_ip), &(netif->ip_addr)))) { + 80050c6: 693b ldr r3, [r7, #16] + 80050c8: 681a ldr r2, [r3, #0] + 80050ca: 687b ldr r3, [r7, #4] + 80050cc: 685b ldr r3, [r3, #4] + if ((!(ip_addr_isany(&(lpcb->local_ip)))) && + 80050ce: 429a cmp r2, r3 + 80050d0: d108 bne.n 80050e4 + /* The PCB is listening to the old ipaddr and + * is set to listen to the new one instead */ + ip_addr_set(&(lpcb->local_ip), ipaddr); + 80050d2: 683b ldr r3, [r7, #0] + 80050d4: 2b00 cmp r3, #0 + 80050d6: d002 beq.n 80050de + 80050d8: 683b ldr r3, [r7, #0] + 80050da: 681a ldr r2, [r3, #0] + 80050dc: e000 b.n 80050e0 + 80050de: 2200 movs r2, #0 + 80050e0: 693b ldr r3, [r7, #16] + 80050e2: 601a str r2, [r3, #0] + for (lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next) { + 80050e4: 693b ldr r3, [r7, #16] + 80050e6: 68db ldr r3, [r3, #12] + 80050e8: 613b str r3, [r7, #16] + 80050ea: 693b ldr r3, [r7, #16] + 80050ec: 2b00 cmp r3, #0 + 80050ee: d1e3 bne.n 80050b8 + } +#endif + snmp_delete_ipaddridx_tree(netif); + snmp_delete_iprteidx_tree(0,netif); + /* set new IP address to netif */ + ip_addr_set(&(netif->ip_addr), ipaddr); + 80050f0: 683b ldr r3, [r7, #0] + 80050f2: 2b00 cmp r3, #0 + 80050f4: d002 beq.n 80050fc + 80050f6: 683b ldr r3, [r7, #0] + 80050f8: 681a ldr r2, [r3, #0] + 80050fa: e000 b.n 80050fe + 80050fc: 2200 movs r2, #0 + 80050fe: 687b ldr r3, [r7, #4] + 8005100: 605a str r2, [r3, #4] + netif->name[0], netif->name[1], + ip4_addr1_16(&netif->ip_addr), + ip4_addr2_16(&netif->ip_addr), + ip4_addr3_16(&netif->ip_addr), + ip4_addr4_16(&netif->ip_addr))); +} + 8005102: 46c0 nop ; (mov r8, r8) + 8005104: 46bd mov sp, r7 + 8005106: b006 add sp, #24 + 8005108: bd80 pop {r7, pc} + 800510a: 46c0 nop ; (mov r8, r8) + 800510c: 20003274 .word 0x20003274 + 8005110: 2000327c .word 0x2000327c + +08005114 : + * + * @note call netif_set_addr() if you also want to change ip address and netmask + */ +void +netif_set_gw(struct netif *netif, ip_addr_t *gw) +{ + 8005114: b580 push {r7, lr} + 8005116: b082 sub sp, #8 + 8005118: af00 add r7, sp, #0 + 800511a: 6078 str r0, [r7, #4] + 800511c: 6039 str r1, [r7, #0] + ip_addr_set(&(netif->gw), gw); + 800511e: 683b ldr r3, [r7, #0] + 8005120: 2b00 cmp r3, #0 + 8005122: d002 beq.n 800512a + 8005124: 683b ldr r3, [r7, #0] + 8005126: 681a ldr r2, [r3, #0] + 8005128: e000 b.n 800512c + 800512a: 2200 movs r2, #0 + 800512c: 687b ldr r3, [r7, #4] + 800512e: 60da str r2, [r3, #12] + netif->name[0], netif->name[1], + ip4_addr1_16(&netif->gw), + ip4_addr2_16(&netif->gw), + ip4_addr3_16(&netif->gw), + ip4_addr4_16(&netif->gw))); +} + 8005130: 46c0 nop ; (mov r8, r8) + 8005132: 46bd mov sp, r7 + 8005134: b002 add sp, #8 + 8005136: bd80 pop {r7, pc} + +08005138 : + * @note call netif_set_addr() if you also want to change ip address and + * default gateway + */ +void +netif_set_netmask(struct netif *netif, ip_addr_t *netmask) +{ + 8005138: b580 push {r7, lr} + 800513a: b082 sub sp, #8 + 800513c: af00 add r7, sp, #0 + 800513e: 6078 str r0, [r7, #4] + 8005140: 6039 str r1, [r7, #0] + snmp_delete_iprteidx_tree(0, netif); + /* set new netmask to netif */ + ip_addr_set(&(netif->netmask), netmask); + 8005142: 683b ldr r3, [r7, #0] + 8005144: 2b00 cmp r3, #0 + 8005146: d002 beq.n 800514e + 8005148: 683b ldr r3, [r7, #0] + 800514a: 681a ldr r2, [r3, #0] + 800514c: e000 b.n 8005150 + 800514e: 2200 movs r2, #0 + 8005150: 687b ldr r3, [r7, #4] + 8005152: 609a str r2, [r3, #8] + netif->name[0], netif->name[1], + ip4_addr1_16(&netif->netmask), + ip4_addr2_16(&netif->netmask), + ip4_addr3_16(&netif->netmask), + ip4_addr4_16(&netif->netmask))); +} + 8005154: 46c0 nop ; (mov r8, r8) + 8005156: 46bd mov sp, r7 + 8005158: b002 add sp, #8 + 800515a: bd80 pop {r7, pc} + +0800515c : + * + * @param netif the default network interface + */ +void +netif_set_default(struct netif *netif) +{ + 800515c: b580 push {r7, lr} + 800515e: b082 sub sp, #8 + 8005160: af00 add r7, sp, #0 + 8005162: 6078 str r0, [r7, #4] + snmp_delete_iprteidx_tree(1, netif); + } else { + /* install default route */ + snmp_insert_iprteidx_tree(1, netif); + } + netif_default = netif; + 8005164: 4b03 ldr r3, [pc, #12] ; (8005174 ) + 8005166: 687a ldr r2, [r7, #4] + 8005168: 601a str r2, [r3, #0] + LWIP_DEBUGF(NETIF_DEBUG, ("netif: setting default interface %c%c\n", + netif ? netif->name[0] : '\'', netif ? netif->name[1] : '\'')); +} + 800516a: 46c0 nop ; (mov r8, r8) + 800516c: 46bd mov sp, r7 + 800516e: b002 add sp, #8 + 8005170: bd80 pop {r7, pc} + 8005172: 46c0 nop ; (mov r8, r8) + 8005174: 20003150 .word 0x20003150 + +08005178 : +#endif /* !NO_SYS */ + +/** Queue a call to pbuf_free_ooseq if not already queued. */ +static void +pbuf_pool_is_empty(void) +{ + 8005178: b580 push {r7, lr} + 800517a: af00 add r7, sp, #0 +#ifndef PBUF_POOL_FREE_OOSEQ_QUEUE_CALL + SYS_ARCH_DECL_PROTECT(old_level); + SYS_ARCH_PROTECT(old_level); + pbuf_free_ooseq_pending = 1; + 800517c: 4b02 ldr r3, [pc, #8] ; (8005188 ) + 800517e: 2201 movs r2, #1 + 8005180: 701a strb r2, [r3, #0] + if(!queued) { + /* queue a call to pbuf_free_ooseq if not already queued */ + PBUF_POOL_FREE_OOSEQ_QUEUE_CALL(); + } +#endif /* PBUF_POOL_FREE_OOSEQ_QUEUE_CALL */ +} + 8005182: 46c0 nop ; (mov r8, r8) + 8005184: 46bd mov sp, r7 + 8005186: bd80 pop {r7, pc} + 8005188: 20003154 .word 0x20003154 + +0800518c : + * @return the allocated pbuf. If multiple pbufs where allocated, this + * is the first pbuf of a pbuf chain. + */ +struct pbuf * +pbuf_alloc(pbuf_layer layer, u16_t length, pbuf_type type) +{ + 800518c: b590 push {r4, r7, lr} + 800518e: b089 sub sp, #36 ; 0x24 + 8005190: af00 add r7, sp, #0 + 8005192: 0004 movs r4, r0 + 8005194: 0008 movs r0, r1 + 8005196: 0011 movs r1, r2 + 8005198: 1dfb adds r3, r7, #7 + 800519a: 1c22 adds r2, r4, #0 + 800519c: 701a strb r2, [r3, #0] + 800519e: 1d3b adds r3, r7, #4 + 80051a0: 1c02 adds r2, r0, #0 + 80051a2: 801a strh r2, [r3, #0] + 80051a4: 1dbb adds r3, r7, #6 + 80051a6: 1c0a adds r2, r1, #0 + 80051a8: 701a strb r2, [r3, #0] + u16_t offset; + s32_t rem_len; /* remaining length */ + LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_alloc(length=%"U16_F")\n", length)); + + /* determine header offset */ + switch (layer) { + 80051aa: 1dfb adds r3, r7, #7 + 80051ac: 781b ldrb r3, [r3, #0] + 80051ae: 2b01 cmp r3, #1 + 80051b0: d00d beq.n 80051ce + 80051b2: dc02 bgt.n 80051ba + 80051b4: 2b00 cmp r3, #0 + 80051b6: d005 beq.n 80051c4 + 80051b8: e018 b.n 80051ec + 80051ba: 2b02 cmp r3, #2 + 80051bc: d00c beq.n 80051d8 + 80051be: 2b03 cmp r3, #3 + 80051c0: d00f beq.n 80051e2 + 80051c2: e013 b.n 80051ec + case PBUF_TRANSPORT: + /* add room for transport (often TCP) layer header */ + offset = PBUF_LINK_HLEN + PBUF_IP_HLEN + PBUF_TRANSPORT_HLEN; + 80051c4: 2316 movs r3, #22 + 80051c6: 18fb adds r3, r7, r3 + 80051c8: 2236 movs r2, #54 ; 0x36 + 80051ca: 801a strh r2, [r3, #0] + break; + 80051cc: e010 b.n 80051f0 + case PBUF_IP: + /* add room for IP layer header */ + offset = PBUF_LINK_HLEN + PBUF_IP_HLEN; + 80051ce: 2316 movs r3, #22 + 80051d0: 18fb adds r3, r7, r3 + 80051d2: 2222 movs r2, #34 ; 0x22 + 80051d4: 801a strh r2, [r3, #0] + break; + 80051d6: e00b b.n 80051f0 + case PBUF_LINK: + /* add room for link layer header */ + offset = PBUF_LINK_HLEN; + 80051d8: 2316 movs r3, #22 + 80051da: 18fb adds r3, r7, r3 + 80051dc: 220e movs r2, #14 + 80051de: 801a strh r2, [r3, #0] + break; + 80051e0: e006 b.n 80051f0 + case PBUF_RAW: + offset = 0; + 80051e2: 2316 movs r3, #22 + 80051e4: 18fb adds r3, r7, r3 + 80051e6: 2200 movs r2, #0 + 80051e8: 801a strh r2, [r3, #0] + break; + 80051ea: e001 b.n 80051f0 + default: + LWIP_ASSERT("pbuf_alloc: bad pbuf layer", 0); + return NULL; + 80051ec: 2300 movs r3, #0 + 80051ee: e0e9 b.n 80053c4 + } + + switch (type) { + 80051f0: 1dbb adds r3, r7, #6 + 80051f2: 781b ldrb r3, [r3, #0] + 80051f4: 2b02 cmp r3, #2 + 80051f6: dc06 bgt.n 8005206 + 80051f8: 2b01 cmp r3, #1 + 80051fa: db00 blt.n 80051fe + 80051fc: e0bc b.n 8005378 + 80051fe: 2b00 cmp r3, #0 + 8005200: d100 bne.n 8005204 + 8005202: e082 b.n 800530a + 8005204: e0d5 b.n 80053b2 + 8005206: 2b03 cmp r3, #3 + 8005208: d000 beq.n 800520c + 800520a: e0d2 b.n 80053b2 + case PBUF_POOL: + /* allocate head of pbuf chain into p */ + p = (struct pbuf *)memp_malloc(MEMP_PBUF_POOL); + 800520c: 2009 movs r0, #9 + 800520e: f7ff fe01 bl 8004e14 + 8005212: 0003 movs r3, r0 + 8005214: 61fb str r3, [r7, #28] + LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_alloc: allocated pbuf %p\n", (void *)p)); + if (p == NULL) { + 8005216: 69fb ldr r3, [r7, #28] + 8005218: 2b00 cmp r3, #0 + 800521a: d103 bne.n 8005224 + PBUF_POOL_IS_EMPTY(); + 800521c: f7ff ffac bl 8005178 + return NULL; + 8005220: 2300 movs r3, #0 + 8005222: e0cf b.n 80053c4 + } + p->type = type; + 8005224: 69fb ldr r3, [r7, #28] + 8005226: 1dba adds r2, r7, #6 + 8005228: 7812 ldrb r2, [r2, #0] + 800522a: 731a strb r2, [r3, #12] + p->next = NULL; + 800522c: 69fb ldr r3, [r7, #28] + 800522e: 2200 movs r2, #0 + 8005230: 601a str r2, [r3, #0] + + /* make the payload pointer point 'offset' bytes into pbuf data memory */ + p->payload = LWIP_MEM_ALIGN((void *)((u8_t *)p + (SIZEOF_STRUCT_PBUF + offset))); + 8005232: 2116 movs r1, #22 + 8005234: 187b adds r3, r7, r1 + 8005236: 881b ldrh r3, [r3, #0] + 8005238: 3310 adds r3, #16 + 800523a: 69fa ldr r2, [r7, #28] + 800523c: 18d3 adds r3, r2, r3 + 800523e: 3303 adds r3, #3 + 8005240: 2203 movs r2, #3 + 8005242: 4393 bics r3, r2 + 8005244: 001a movs r2, r3 + 8005246: 69fb ldr r3, [r7, #28] + 8005248: 605a str r2, [r3, #4] + LWIP_ASSERT("pbuf_alloc: pbuf p->payload properly aligned", + ((mem_ptr_t)p->payload % MEM_ALIGNMENT) == 0); + /* the total length of the pbuf chain is the requested size */ + p->tot_len = length; + 800524a: 69fb ldr r3, [r7, #28] + 800524c: 1d3a adds r2, r7, #4 + 800524e: 8812 ldrh r2, [r2, #0] + 8005250: 811a strh r2, [r3, #8] + /* set the length of the first pbuf in the chain */ + p->len = LWIP_MIN(length, PBUF_POOL_BUFSIZE_ALIGNED - LWIP_MEM_ALIGN_SIZE(offset)); + 8005252: 187b adds r3, r7, r1 + 8005254: 881b ldrh r3, [r3, #0] + 8005256: 3303 adds r3, #3 + 8005258: 2203 movs r2, #3 + 800525a: 4393 bics r3, r2 + 800525c: 4a5b ldr r2, [pc, #364] ; (80053cc ) + 800525e: 1ad2 subs r2, r2, r3 + 8005260: 1d3b adds r3, r7, #4 + 8005262: 881b ldrh r3, [r3, #0] + 8005264: 429a cmp r2, r3 + 8005266: dd00 ble.n 800526a + 8005268: 001a movs r2, r3 + 800526a: b292 uxth r2, r2 + 800526c: 69fb ldr r3, [r7, #28] + 800526e: 815a strh r2, [r3, #10] + ((u8_t*)p->payload + p->len <= + (u8_t*)p + SIZEOF_STRUCT_PBUF + PBUF_POOL_BUFSIZE_ALIGNED)); + LWIP_ASSERT("PBUF_POOL_BUFSIZE must be bigger than MEM_ALIGNMENT", + (PBUF_POOL_BUFSIZE_ALIGNED - LWIP_MEM_ALIGN_SIZE(offset)) > 0 ); + /* set reference count (needed here in case we fail) */ + p->ref = 1; + 8005270: 69fb ldr r3, [r7, #28] + 8005272: 2201 movs r2, #1 + 8005274: 81da strh r2, [r3, #14] + + /* now allocate the tail of the pbuf chain */ + + /* remember first pbuf for linkage in next iteration */ + r = p; + 8005276: 69fb ldr r3, [r7, #28] + 8005278: 61bb str r3, [r7, #24] + /* remaining length to be allocated */ + rem_len = length - p->len; + 800527a: 1d3b adds r3, r7, #4 + 800527c: 881b ldrh r3, [r3, #0] + 800527e: 69fa ldr r2, [r7, #28] + 8005280: 8952 ldrh r2, [r2, #10] + 8005282: 1a9b subs r3, r3, r2 + 8005284: 613b str r3, [r7, #16] + /* any remaining pbufs to be allocated? */ + while (rem_len > 0) { + 8005286: e03c b.n 8005302 + q = (struct pbuf *)memp_malloc(MEMP_PBUF_POOL); + 8005288: 2009 movs r0, #9 + 800528a: f7ff fdc3 bl 8004e14 + 800528e: 0003 movs r3, r0 + 8005290: 60fb str r3, [r7, #12] + if (q == NULL) { + 8005292: 68fb ldr r3, [r7, #12] + 8005294: 2b00 cmp r3, #0 + 8005296: d107 bne.n 80052a8 + PBUF_POOL_IS_EMPTY(); + 8005298: f7ff ff6e bl 8005178 + /* free chain so far allocated */ + pbuf_free(p); + 800529c: 69fb ldr r3, [r7, #28] + 800529e: 0018 movs r0, r3 + 80052a0: f000 fa00 bl 80056a4 + /* bail out unsuccesfully */ + return NULL; + 80052a4: 2300 movs r3, #0 + 80052a6: e08d b.n 80053c4 + } + q->type = type; + 80052a8: 68fb ldr r3, [r7, #12] + 80052aa: 1dba adds r2, r7, #6 + 80052ac: 7812 ldrb r2, [r2, #0] + 80052ae: 731a strb r2, [r3, #12] + q->flags = 0; + 80052b0: 68fb ldr r3, [r7, #12] + 80052b2: 2200 movs r2, #0 + 80052b4: 735a strb r2, [r3, #13] + q->next = NULL; + 80052b6: 68fb ldr r3, [r7, #12] + 80052b8: 2200 movs r2, #0 + 80052ba: 601a str r2, [r3, #0] + /* make previous pbuf point to this pbuf */ + r->next = q; + 80052bc: 69bb ldr r3, [r7, #24] + 80052be: 68fa ldr r2, [r7, #12] + 80052c0: 601a str r2, [r3, #0] + /* set total length of this pbuf and next in chain */ + LWIP_ASSERT("rem_len < max_u16_t", rem_len < 0xffff); + q->tot_len = (u16_t)rem_len; + 80052c2: 693b ldr r3, [r7, #16] + 80052c4: b29a uxth r2, r3 + 80052c6: 68fb ldr r3, [r7, #12] + 80052c8: 811a strh r2, [r3, #8] + /* this pbuf length is pool size, unless smaller sized tail */ + q->len = LWIP_MIN((u16_t)rem_len, PBUF_POOL_BUFSIZE_ALIGNED); + 80052ca: 693b ldr r3, [r7, #16] + 80052cc: b29b uxth r3, r3 + 80052ce: 1c19 adds r1, r3, #0 + 80052d0: b28b uxth r3, r1 + 80052d2: 4a3e ldr r2, [pc, #248] ; (80053cc ) + 80052d4: 4293 cmp r3, r2 + 80052d6: d901 bls.n 80052dc + 80052d8: 4b3c ldr r3, [pc, #240] ; (80053cc ) + 80052da: 1c19 adds r1, r3, #0 + 80052dc: b28a uxth r2, r1 + 80052de: 68fb ldr r3, [r7, #12] + 80052e0: 815a strh r2, [r3, #10] + q->payload = (void *)((u8_t *)q + SIZEOF_STRUCT_PBUF); + 80052e2: 68fb ldr r3, [r7, #12] + 80052e4: 3310 adds r3, #16 + 80052e6: 001a movs r2, r3 + 80052e8: 68fb ldr r3, [r7, #12] + 80052ea: 605a str r2, [r3, #4] + LWIP_ASSERT("pbuf_alloc: pbuf q->payload properly aligned", + ((mem_ptr_t)q->payload % MEM_ALIGNMENT) == 0); + LWIP_ASSERT("check p->payload + p->len does not overflow pbuf", + ((u8_t*)p->payload + p->len <= + (u8_t*)p + SIZEOF_STRUCT_PBUF + PBUF_POOL_BUFSIZE_ALIGNED)); + q->ref = 1; + 80052ec: 68fb ldr r3, [r7, #12] + 80052ee: 2201 movs r2, #1 + 80052f0: 81da strh r2, [r3, #14] + /* calculate remaining length to be allocated */ + rem_len -= q->len; + 80052f2: 68fb ldr r3, [r7, #12] + 80052f4: 895b ldrh r3, [r3, #10] + 80052f6: 001a movs r2, r3 + 80052f8: 693b ldr r3, [r7, #16] + 80052fa: 1a9b subs r3, r3, r2 + 80052fc: 613b str r3, [r7, #16] + /* remember this pbuf for linkage in next iteration */ + r = q; + 80052fe: 68fb ldr r3, [r7, #12] + 8005300: 61bb str r3, [r7, #24] + while (rem_len > 0) { + 8005302: 693b ldr r3, [r7, #16] + 8005304: 2b00 cmp r3, #0 + 8005306: dcbf bgt.n 8005288 + } + /* end of chain */ + /*r->next = NULL;*/ + + break; + 8005308: e055 b.n 80053b6 + case PBUF_RAM: + /* If pbuf is to be allocated in RAM, allocate memory for it. */ + p = (struct pbuf*)mem_malloc(LWIP_MEM_ALIGN_SIZE(SIZEOF_STRUCT_PBUF + offset) + LWIP_MEM_ALIGN_SIZE(length)); + 800530a: 2316 movs r3, #22 + 800530c: 18fb adds r3, r7, r3 + 800530e: 881b ldrh r3, [r3, #0] + 8005310: 3313 adds r3, #19 + 8005312: b29b uxth r3, r3 + 8005314: 2203 movs r2, #3 + 8005316: 4393 bics r3, r2 + 8005318: b29a uxth r2, r3 + 800531a: 1d3b adds r3, r7, #4 + 800531c: 881b ldrh r3, [r3, #0] + 800531e: 3303 adds r3, #3 + 8005320: b29b uxth r3, r3 + 8005322: 2103 movs r1, #3 + 8005324: 438b bics r3, r1 + 8005326: b29b uxth r3, r3 + 8005328: 18d3 adds r3, r2, r3 + 800532a: b29b uxth r3, r3 + 800532c: 0018 movs r0, r3 + 800532e: f7ff fbd1 bl 8004ad4 + 8005332: 0003 movs r3, r0 + 8005334: 61fb str r3, [r7, #28] + if (p == NULL) { + 8005336: 69fb ldr r3, [r7, #28] + 8005338: 2b00 cmp r3, #0 + 800533a: d101 bne.n 8005340 + return NULL; + 800533c: 2300 movs r3, #0 + 800533e: e041 b.n 80053c4 + } + /* Set up internal structure of the pbuf. */ + p->payload = LWIP_MEM_ALIGN((void *)((u8_t *)p + SIZEOF_STRUCT_PBUF + offset)); + 8005340: 2316 movs r3, #22 + 8005342: 18fb adds r3, r7, r3 + 8005344: 881b ldrh r3, [r3, #0] + 8005346: 3310 adds r3, #16 + 8005348: 69fa ldr r2, [r7, #28] + 800534a: 18d3 adds r3, r2, r3 + 800534c: 3303 adds r3, #3 + 800534e: 2203 movs r2, #3 + 8005350: 4393 bics r3, r2 + 8005352: 001a movs r2, r3 + 8005354: 69fb ldr r3, [r7, #28] + 8005356: 605a str r2, [r3, #4] + p->len = p->tot_len = length; + 8005358: 69fb ldr r3, [r7, #28] + 800535a: 1d3a adds r2, r7, #4 + 800535c: 8812 ldrh r2, [r2, #0] + 800535e: 811a strh r2, [r3, #8] + 8005360: 69fb ldr r3, [r7, #28] + 8005362: 891a ldrh r2, [r3, #8] + 8005364: 69fb ldr r3, [r7, #28] + 8005366: 815a strh r2, [r3, #10] + p->next = NULL; + 8005368: 69fb ldr r3, [r7, #28] + 800536a: 2200 movs r2, #0 + 800536c: 601a str r2, [r3, #0] + p->type = type; + 800536e: 69fb ldr r3, [r7, #28] + 8005370: 1dba adds r2, r7, #6 + 8005372: 7812 ldrb r2, [r2, #0] + 8005374: 731a strb r2, [r3, #12] + + LWIP_ASSERT("pbuf_alloc: pbuf->payload properly aligned", + ((mem_ptr_t)p->payload % MEM_ALIGNMENT) == 0); + break; + 8005376: e01e b.n 80053b6 + /* pbuf references existing (non-volatile static constant) ROM payload? */ + case PBUF_ROM: + /* pbuf references existing (externally allocated) RAM payload? */ + case PBUF_REF: + /* only allocate memory for the pbuf structure */ + p = (struct pbuf *)memp_malloc(MEMP_PBUF); + 8005378: 2008 movs r0, #8 + 800537a: f7ff fd4b bl 8004e14 + 800537e: 0003 movs r3, r0 + 8005380: 61fb str r3, [r7, #28] + if (p == NULL) { + 8005382: 69fb ldr r3, [r7, #28] + 8005384: 2b00 cmp r3, #0 + 8005386: d101 bne.n 800538c + LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_LEVEL_SERIOUS, + ("pbuf_alloc: Could not allocate MEMP_PBUF for PBUF_%s.\n", + (type == PBUF_ROM) ? "ROM" : "REF")); + return NULL; + 8005388: 2300 movs r3, #0 + 800538a: e01b b.n 80053c4 + } + /* caller must set this field properly, afterwards */ + p->payload = NULL; + 800538c: 69fb ldr r3, [r7, #28] + 800538e: 2200 movs r2, #0 + 8005390: 605a str r2, [r3, #4] + p->len = p->tot_len = length; + 8005392: 69fb ldr r3, [r7, #28] + 8005394: 1d3a adds r2, r7, #4 + 8005396: 8812 ldrh r2, [r2, #0] + 8005398: 811a strh r2, [r3, #8] + 800539a: 69fb ldr r3, [r7, #28] + 800539c: 891a ldrh r2, [r3, #8] + 800539e: 69fb ldr r3, [r7, #28] + 80053a0: 815a strh r2, [r3, #10] + p->next = NULL; + 80053a2: 69fb ldr r3, [r7, #28] + 80053a4: 2200 movs r2, #0 + 80053a6: 601a str r2, [r3, #0] + p->type = type; + 80053a8: 69fb ldr r3, [r7, #28] + 80053aa: 1dba adds r2, r7, #6 + 80053ac: 7812 ldrb r2, [r2, #0] + 80053ae: 731a strb r2, [r3, #12] + break; + 80053b0: e001 b.n 80053b6 + default: + LWIP_ASSERT("pbuf_alloc: erroneous type", 0); + return NULL; + 80053b2: 2300 movs r3, #0 + 80053b4: e006 b.n 80053c4 + } + /* set reference count */ + p->ref = 1; + 80053b6: 69fb ldr r3, [r7, #28] + 80053b8: 2201 movs r2, #1 + 80053ba: 81da strh r2, [r3, #14] + /* set flags */ + p->flags = 0; + 80053bc: 69fb ldr r3, [r7, #28] + 80053be: 2200 movs r2, #0 + 80053c0: 735a strb r2, [r3, #13] + LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_alloc(length=%"U16_F") == %p\n", length, (void *)p)); + return p; + 80053c2: 69fb ldr r3, [r7, #28] +} + 80053c4: 0018 movs r0, r3 + 80053c6: 46bd mov sp, r7 + 80053c8: b009 add sp, #36 ; 0x24 + 80053ca: bd90 pop {r4, r7, pc} + 80053cc: 000005ec .word 0x000005ec + +080053d0 : + * big enough to hold 'length' plus the header size + */ +struct pbuf* +pbuf_alloced_custom(pbuf_layer l, u16_t length, pbuf_type type, struct pbuf_custom *p, + void *payload_mem, u16_t payload_mem_len) +{ + 80053d0: b590 push {r4, r7, lr} + 80053d2: b085 sub sp, #20 + 80053d4: af00 add r7, sp, #0 + 80053d6: 0004 movs r4, r0 + 80053d8: 0008 movs r0, r1 + 80053da: 0011 movs r1, r2 + 80053dc: 603b str r3, [r7, #0] + 80053de: 1dfb adds r3, r7, #7 + 80053e0: 1c22 adds r2, r4, #0 + 80053e2: 701a strb r2, [r3, #0] + 80053e4: 1d3b adds r3, r7, #4 + 80053e6: 1c02 adds r2, r0, #0 + 80053e8: 801a strh r2, [r3, #0] + 80053ea: 1dbb adds r3, r7, #6 + 80053ec: 1c0a adds r2, r1, #0 + 80053ee: 701a strb r2, [r3, #0] + u16_t offset; + LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_alloced_custom(length=%"U16_F")\n", length)); + + /* determine header offset */ + switch (l) { + 80053f0: 1dfb adds r3, r7, #7 + 80053f2: 781b ldrb r3, [r3, #0] + 80053f4: 2b01 cmp r3, #1 + 80053f6: d00d beq.n 8005414 + 80053f8: dc02 bgt.n 8005400 + 80053fa: 2b00 cmp r3, #0 + 80053fc: d005 beq.n 800540a + 80053fe: e018 b.n 8005432 + 8005400: 2b02 cmp r3, #2 + 8005402: d00c beq.n 800541e + 8005404: 2b03 cmp r3, #3 + 8005406: d00f beq.n 8005428 + 8005408: e013 b.n 8005432 + case PBUF_TRANSPORT: + /* add room for transport (often TCP) layer header */ + offset = PBUF_LINK_HLEN + PBUF_IP_HLEN + PBUF_TRANSPORT_HLEN; + 800540a: 230e movs r3, #14 + 800540c: 18fb adds r3, r7, r3 + 800540e: 2236 movs r2, #54 ; 0x36 + 8005410: 801a strh r2, [r3, #0] + break; + 8005412: e010 b.n 8005436 + case PBUF_IP: + /* add room for IP layer header */ + offset = PBUF_LINK_HLEN + PBUF_IP_HLEN; + 8005414: 230e movs r3, #14 + 8005416: 18fb adds r3, r7, r3 + 8005418: 2222 movs r2, #34 ; 0x22 + 800541a: 801a strh r2, [r3, #0] + break; + 800541c: e00b b.n 8005436 + case PBUF_LINK: + /* add room for link layer header */ + offset = PBUF_LINK_HLEN; + 800541e: 230e movs r3, #14 + 8005420: 18fb adds r3, r7, r3 + 8005422: 220e movs r2, #14 + 8005424: 801a strh r2, [r3, #0] + break; + 8005426: e006 b.n 8005436 + case PBUF_RAW: + offset = 0; + 8005428: 230e movs r3, #14 + 800542a: 18fb adds r3, r7, r3 + 800542c: 2200 movs r2, #0 + 800542e: 801a strh r2, [r3, #0] + break; + 8005430: e001 b.n 8005436 + default: + LWIP_ASSERT("pbuf_alloced_custom: bad pbuf layer", 0); + return NULL; + 8005432: 2300 movs r3, #0 + 8005434: e039 b.n 80054aa + } + + if (LWIP_MEM_ALIGN_SIZE(offset) + length > payload_mem_len) { + 8005436: 230e movs r3, #14 + 8005438: 18fb adds r3, r7, r3 + 800543a: 881b ldrh r3, [r3, #0] + 800543c: 3303 adds r3, #3 + 800543e: 2203 movs r2, #3 + 8005440: 4393 bics r3, r2 + 8005442: 001a movs r2, r3 + 8005444: 1d3b adds r3, r7, #4 + 8005446: 881b ldrh r3, [r3, #0] + 8005448: 18d2 adds r2, r2, r3 + 800544a: 2324 movs r3, #36 ; 0x24 + 800544c: 18fb adds r3, r7, r3 + 800544e: 881b ldrh r3, [r3, #0] + 8005450: 429a cmp r2, r3 + 8005452: dd01 ble.n 8005458 + LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_LEVEL_WARNING, ("pbuf_alloced_custom(length=%"U16_F") buffer too short\n", length)); + return NULL; + 8005454: 2300 movs r3, #0 + 8005456: e028 b.n 80054aa + } + + p->pbuf.next = NULL; + 8005458: 683b ldr r3, [r7, #0] + 800545a: 2200 movs r2, #0 + 800545c: 601a str r2, [r3, #0] + if (payload_mem != NULL) { + 800545e: 6a3b ldr r3, [r7, #32] + 8005460: 2b00 cmp r3, #0 + 8005462: d00c beq.n 800547e + p->pbuf.payload = (u8_t *)payload_mem + LWIP_MEM_ALIGN_SIZE(offset); + 8005464: 230e movs r3, #14 + 8005466: 18fb adds r3, r7, r3 + 8005468: 881b ldrh r3, [r3, #0] + 800546a: 3303 adds r3, #3 + 800546c: 001a movs r2, r3 + 800546e: 2303 movs r3, #3 + 8005470: 439a bics r2, r3 + 8005472: 0013 movs r3, r2 + 8005474: 6a3a ldr r2, [r7, #32] + 8005476: 18d2 adds r2, r2, r3 + 8005478: 683b ldr r3, [r7, #0] + 800547a: 605a str r2, [r3, #4] + 800547c: e002 b.n 8005484 + } else { + p->pbuf.payload = NULL; + 800547e: 683b ldr r3, [r7, #0] + 8005480: 2200 movs r2, #0 + 8005482: 605a str r2, [r3, #4] + } + p->pbuf.flags = PBUF_FLAG_IS_CUSTOM; + 8005484: 683b ldr r3, [r7, #0] + 8005486: 2202 movs r2, #2 + 8005488: 735a strb r2, [r3, #13] + p->pbuf.len = p->pbuf.tot_len = length; + 800548a: 683b ldr r3, [r7, #0] + 800548c: 1d3a adds r2, r7, #4 + 800548e: 8812 ldrh r2, [r2, #0] + 8005490: 811a strh r2, [r3, #8] + 8005492: 683b ldr r3, [r7, #0] + 8005494: 891a ldrh r2, [r3, #8] + 8005496: 683b ldr r3, [r7, #0] + 8005498: 815a strh r2, [r3, #10] + p->pbuf.type = type; + 800549a: 683b ldr r3, [r7, #0] + 800549c: 1dba adds r2, r7, #6 + 800549e: 7812 ldrb r2, [r2, #0] + 80054a0: 731a strb r2, [r3, #12] + p->pbuf.ref = 1; + 80054a2: 683b ldr r3, [r7, #0] + 80054a4: 2201 movs r2, #1 + 80054a6: 81da strh r2, [r3, #14] + return &p->pbuf; + 80054a8: 683b ldr r3, [r7, #0] +} + 80054aa: 0018 movs r0, r3 + 80054ac: 46bd mov sp, r7 + 80054ae: b005 add sp, #20 + 80054b0: bd90 pop {r4, r7, pc} + +080054b2 : + * + * @note Despite its name, pbuf_realloc cannot grow the size of a pbuf (chain). + */ +void +pbuf_realloc(struct pbuf *p, u16_t new_len) +{ + 80054b2: b580 push {r7, lr} + 80054b4: b086 sub sp, #24 + 80054b6: af00 add r7, sp, #0 + 80054b8: 6078 str r0, [r7, #4] + 80054ba: 000a movs r2, r1 + 80054bc: 1cbb adds r3, r7, #2 + 80054be: 801a strh r2, [r3, #0] + struct pbuf *q; + u16_t rem_len; /* remaining length */ + s32_t grow; + + LWIP_ASSERT("pbuf_realloc: p != NULL", p != NULL); + LWIP_ASSERT("pbuf_realloc: sane p->type", p->type == PBUF_POOL || + 80054c0: 687b ldr r3, [r7, #4] + 80054c2: 7b1b ldrb r3, [r3, #12] + 80054c4: 2b03 cmp r3, #3 + 80054c6: d001 beq.n 80054cc + 80054c8: 687b ldr r3, [r7, #4] + 80054ca: 7b1b ldrb r3, [r3, #12] + p->type == PBUF_ROM || + p->type == PBUF_RAM || + p->type == PBUF_REF); + + /* desired length larger than current length? */ + if (new_len >= p->tot_len) { + 80054cc: 687b ldr r3, [r7, #4] + 80054ce: 891b ldrh r3, [r3, #8] + 80054d0: 1cba adds r2, r7, #2 + 80054d2: 8812 ldrh r2, [r2, #0] + 80054d4: 429a cmp r2, r3 + 80054d6: d25a bcs.n 800558e + return; + } + + /* the pbuf chain grows by (new_len - p->tot_len) bytes + * (which may be negative in case of shrinking) */ + grow = new_len - p->tot_len; + 80054d8: 1cbb adds r3, r7, #2 + 80054da: 881b ldrh r3, [r3, #0] + 80054dc: 687a ldr r2, [r7, #4] + 80054de: 8912 ldrh r2, [r2, #8] + 80054e0: 1a9b subs r3, r3, r2 + 80054e2: 60fb str r3, [r7, #12] + + /* first, step over any pbufs that should remain in the chain */ + rem_len = new_len; + 80054e4: 2312 movs r3, #18 + 80054e6: 18fb adds r3, r7, r3 + 80054e8: 1cba adds r2, r7, #2 + 80054ea: 8812 ldrh r2, [r2, #0] + 80054ec: 801a strh r2, [r3, #0] + q = p; + 80054ee: 687b ldr r3, [r7, #4] + 80054f0: 617b str r3, [r7, #20] + /* should this pbuf be kept? */ + while (rem_len > q->len) { + 80054f2: e012 b.n 800551a + /* decrease remaining length by pbuf length */ + rem_len -= q->len; + 80054f4: 697b ldr r3, [r7, #20] + 80054f6: 895a ldrh r2, [r3, #10] + 80054f8: 2112 movs r1, #18 + 80054fa: 187b adds r3, r7, r1 + 80054fc: 1879 adds r1, r7, r1 + 80054fe: 8809 ldrh r1, [r1, #0] + 8005500: 1a8a subs r2, r1, r2 + 8005502: 801a strh r2, [r3, #0] + /* decrease total length indicator */ + LWIP_ASSERT("grow < max_u16_t", grow < 0xffff); + q->tot_len += (u16_t)grow; + 8005504: 697b ldr r3, [r7, #20] + 8005506: 891a ldrh r2, [r3, #8] + 8005508: 68fb ldr r3, [r7, #12] + 800550a: b29b uxth r3, r3 + 800550c: 18d3 adds r3, r2, r3 + 800550e: b29a uxth r2, r3 + 8005510: 697b ldr r3, [r7, #20] + 8005512: 811a strh r2, [r3, #8] + /* proceed to next pbuf in chain */ + q = q->next; + 8005514: 697b ldr r3, [r7, #20] + 8005516: 681b ldr r3, [r3, #0] + 8005518: 617b str r3, [r7, #20] + while (rem_len > q->len) { + 800551a: 697b ldr r3, [r7, #20] + 800551c: 895b ldrh r3, [r3, #10] + 800551e: 2212 movs r2, #18 + 8005520: 18ba adds r2, r7, r2 + 8005522: 8812 ldrh r2, [r2, #0] + 8005524: 429a cmp r2, r3 + 8005526: d8e5 bhi.n 80054f4 + /* we have now reached the new last pbuf (in q) */ + /* rem_len == desired length for pbuf q */ + + /* shrink allocated memory for PBUF_RAM */ + /* (other types merely adjust their length fields */ + if ((q->type == PBUF_RAM) && (rem_len != q->len)) { + 8005528: 697b ldr r3, [r7, #20] + 800552a: 7b1b ldrb r3, [r3, #12] + 800552c: 2b00 cmp r3, #0 + 800552e: d118 bne.n 8005562 + 8005530: 697b ldr r3, [r7, #20] + 8005532: 895b ldrh r3, [r3, #10] + 8005534: 2212 movs r2, #18 + 8005536: 18ba adds r2, r7, r2 + 8005538: 8812 ldrh r2, [r2, #0] + 800553a: 429a cmp r2, r3 + 800553c: d011 beq.n 8005562 + /* reallocate and adjust the length of the pbuf that will be split */ + q = (struct pbuf *)mem_trim(q, (u16_t)((u8_t *)q->payload - (u8_t *)q) + rem_len); + 800553e: 697b ldr r3, [r7, #20] + 8005540: 685b ldr r3, [r3, #4] + 8005542: 001a movs r2, r3 + 8005544: 697b ldr r3, [r7, #20] + 8005546: 1ad3 subs r3, r2, r3 + 8005548: b29a uxth r2, r3 + 800554a: 2312 movs r3, #18 + 800554c: 18fb adds r3, r7, r3 + 800554e: 881b ldrh r3, [r3, #0] + 8005550: 18d3 adds r3, r2, r3 + 8005552: b29a uxth r2, r3 + 8005554: 697b ldr r3, [r7, #20] + 8005556: 0011 movs r1, r2 + 8005558: 0018 movs r0, r3 + 800555a: f7ff f9a7 bl 80048ac + 800555e: 0003 movs r3, r0 + 8005560: 617b str r3, [r7, #20] + LWIP_ASSERT("mem_trim returned q == NULL", q != NULL); + } + /* adjust length fields for new last pbuf */ + q->len = rem_len; + 8005562: 697b ldr r3, [r7, #20] + 8005564: 2212 movs r2, #18 + 8005566: 18ba adds r2, r7, r2 + 8005568: 8812 ldrh r2, [r2, #0] + 800556a: 815a strh r2, [r3, #10] + q->tot_len = q->len; + 800556c: 697b ldr r3, [r7, #20] + 800556e: 895a ldrh r2, [r3, #10] + 8005570: 697b ldr r3, [r7, #20] + 8005572: 811a strh r2, [r3, #8] + + /* any remaining pbufs in chain? */ + if (q->next != NULL) { + 8005574: 697b ldr r3, [r7, #20] + 8005576: 681b ldr r3, [r3, #0] + 8005578: 2b00 cmp r3, #0 + 800557a: d004 beq.n 8005586 + /* free remaining pbufs in chain */ + pbuf_free(q->next); + 800557c: 697b ldr r3, [r7, #20] + 800557e: 681b ldr r3, [r3, #0] + 8005580: 0018 movs r0, r3 + 8005582: f000 f88f bl 80056a4 + } + /* q is last packet in chain */ + q->next = NULL; + 8005586: 697b ldr r3, [r7, #20] + 8005588: 2200 movs r2, #0 + 800558a: 601a str r2, [r3, #0] + 800558c: e000 b.n 8005590 + return; + 800558e: 46c0 nop ; (mov r8, r8) + +} + 8005590: 46bd mov sp, r7 + 8005592: b006 add sp, #24 + 8005594: bd80 pop {r7, pc} + +08005596 : + * @return non-zero on failure, zero on success. + * + */ +u8_t +pbuf_header(struct pbuf *p, s16_t header_size_increment) +{ + 8005596: b580 push {r7, lr} + 8005598: b084 sub sp, #16 + 800559a: af00 add r7, sp, #0 + 800559c: 6078 str r0, [r7, #4] + 800559e: 000a movs r2, r1 + 80055a0: 1cbb adds r3, r7, #2 + 80055a2: 801a strh r2, [r3, #0] + u16_t type; + void *payload; + u16_t increment_magnitude; + + LWIP_ASSERT("p != NULL", p != NULL); + if ((header_size_increment == 0) || (p == NULL)) { + 80055a4: 1cbb adds r3, r7, #2 + 80055a6: 2200 movs r2, #0 + 80055a8: 5e9b ldrsh r3, [r3, r2] + 80055aa: 2b00 cmp r3, #0 + 80055ac: d002 beq.n 80055b4 + 80055ae: 687b ldr r3, [r7, #4] + 80055b0: 2b00 cmp r3, #0 + 80055b2: d101 bne.n 80055b8 + return 0; + 80055b4: 2300 movs r3, #0 + 80055b6: e071 b.n 800569c + } + + if (header_size_increment < 0){ + 80055b8: 1cbb adds r3, r7, #2 + 80055ba: 2200 movs r2, #0 + 80055bc: 5e9b ldrsh r3, [r3, r2] + 80055be: 2b00 cmp r3, #0 + 80055c0: da0d bge.n 80055de + increment_magnitude = -header_size_increment; + 80055c2: 1cbb adds r3, r7, #2 + 80055c4: 881a ldrh r2, [r3, #0] + 80055c6: 210e movs r1, #14 + 80055c8: 187b adds r3, r7, r1 + 80055ca: 4252 negs r2, r2 + 80055cc: 801a strh r2, [r3, #0] + /* Check that we aren't going to move off the end of the pbuf */ + LWIP_ERROR("increment_magnitude <= p->len", (increment_magnitude <= p->len), return 1;); + 80055ce: 687b ldr r3, [r7, #4] + 80055d0: 895b ldrh r3, [r3, #10] + 80055d2: 187a adds r2, r7, r1 + 80055d4: 8812 ldrh r2, [r2, #0] + 80055d6: 429a cmp r2, r3 + 80055d8: d906 bls.n 80055e8 + 80055da: 2301 movs r3, #1 + 80055dc: e05e b.n 800569c + } else { + increment_magnitude = header_size_increment; + 80055de: 230e movs r3, #14 + 80055e0: 18fb adds r3, r7, r3 + 80055e2: 1cba adds r2, r7, #2 + 80055e4: 8812 ldrh r2, [r2, #0] + 80055e6: 801a strh r2, [r3, #0] + LWIP_ASSERT("p->payload - increment_magnitude >= p + SIZEOF_STRUCT_PBUF", + (u8_t *)p->payload - increment_magnitude >= (u8_t *)p + SIZEOF_STRUCT_PBUF); +#endif + } + + type = p->type; + 80055e8: 687b ldr r3, [r7, #4] + 80055ea: 7b1a ldrb r2, [r3, #12] + 80055ec: 210c movs r1, #12 + 80055ee: 187b adds r3, r7, r1 + 80055f0: 801a strh r2, [r3, #0] + /* remember current payload pointer */ + payload = p->payload; + 80055f2: 687b ldr r3, [r7, #4] + 80055f4: 685b ldr r3, [r3, #4] + 80055f6: 60bb str r3, [r7, #8] + + /* pbuf types containing payloads? */ + if (type == PBUF_RAM || type == PBUF_POOL) { + 80055f8: 187b adds r3, r7, r1 + 80055fa: 881b ldrh r3, [r3, #0] + 80055fc: 2b00 cmp r3, #0 + 80055fe: d004 beq.n 800560a + 8005600: 230c movs r3, #12 + 8005602: 18fb adds r3, r7, r3 + 8005604: 881b ldrh r3, [r3, #0] + 8005606: 2b03 cmp r3, #3 + 8005608: d113 bne.n 8005632 + /* set new payload pointer */ + p->payload = (u8_t *)p->payload - header_size_increment; + 800560a: 687b ldr r3, [r7, #4] + 800560c: 685a ldr r2, [r3, #4] + 800560e: 1cbb adds r3, r7, #2 + 8005610: 2100 movs r1, #0 + 8005612: 5e5b ldrsh r3, [r3, r1] + 8005614: 425b negs r3, r3 + 8005616: 18d2 adds r2, r2, r3 + 8005618: 687b ldr r3, [r7, #4] + 800561a: 605a str r2, [r3, #4] + /* boundary check fails? */ + if ((u8_t *)p->payload < (u8_t *)p + SIZEOF_STRUCT_PBUF) { + 800561c: 687b ldr r3, [r7, #4] + 800561e: 685a ldr r2, [r3, #4] + 8005620: 687b ldr r3, [r7, #4] + 8005622: 3310 adds r3, #16 + 8005624: 429a cmp r2, r3 + 8005626: d228 bcs.n 800567a + LWIP_DEBUGF( PBUF_DEBUG | LWIP_DBG_LEVEL_SERIOUS, + ("pbuf_header: failed as %p < %p (not enough space for new header size)\n", + (void *)p->payload, (void *)(p + 1))); + /* restore old payload pointer */ + p->payload = payload; + 8005628: 687b ldr r3, [r7, #4] + 800562a: 68ba ldr r2, [r7, #8] + 800562c: 605a str r2, [r3, #4] + /* bail out unsuccesfully */ + return 1; + 800562e: 2301 movs r3, #1 + 8005630: e034 b.n 800569c + } + /* pbuf types refering to external payloads? */ + } else if (type == PBUF_REF || type == PBUF_ROM) { + 8005632: 230c movs r3, #12 + 8005634: 18fb adds r3, r7, r3 + 8005636: 881b ldrh r3, [r3, #0] + 8005638: 2b02 cmp r3, #2 + 800563a: d004 beq.n 8005646 + 800563c: 230c movs r3, #12 + 800563e: 18fb adds r3, r7, r3 + 8005640: 881b ldrh r3, [r3, #0] + 8005642: 2b01 cmp r3, #1 + 8005644: d117 bne.n 8005676 + /* hide a header in the payload? */ + if ((header_size_increment < 0) && (increment_magnitude <= p->len)) { + 8005646: 1cbb adds r3, r7, #2 + 8005648: 2200 movs r2, #0 + 800564a: 5e9b ldrsh r3, [r3, r2] + 800564c: 2b00 cmp r3, #0 + 800564e: da10 bge.n 8005672 + 8005650: 687b ldr r3, [r7, #4] + 8005652: 895b ldrh r3, [r3, #10] + 8005654: 220e movs r2, #14 + 8005656: 18ba adds r2, r7, r2 + 8005658: 8812 ldrh r2, [r2, #0] + 800565a: 429a cmp r2, r3 + 800565c: d809 bhi.n 8005672 + /* increase payload pointer */ + p->payload = (u8_t *)p->payload - header_size_increment; + 800565e: 687b ldr r3, [r7, #4] + 8005660: 685a ldr r2, [r3, #4] + 8005662: 1cbb adds r3, r7, #2 + 8005664: 2100 movs r1, #0 + 8005666: 5e5b ldrsh r3, [r3, r1] + 8005668: 425b negs r3, r3 + 800566a: 18d2 adds r2, r2, r3 + 800566c: 687b ldr r3, [r7, #4] + 800566e: 605a str r2, [r3, #4] + if ((header_size_increment < 0) && (increment_magnitude <= p->len)) { + 8005670: e003 b.n 800567a + } else { + /* cannot expand payload to front (yet!) + * bail out unsuccesfully */ + return 1; + 8005672: 2301 movs r3, #1 + 8005674: e012 b.n 800569c + } + } else { + /* Unknown type */ + LWIP_ASSERT("bad pbuf type", 0); + return 1; + 8005676: 2301 movs r3, #1 + 8005678: e010 b.n 800569c + } + /* modify pbuf length fields */ + p->len += header_size_increment; + 800567a: 687b ldr r3, [r7, #4] + 800567c: 895a ldrh r2, [r3, #10] + 800567e: 1cbb adds r3, r7, #2 + 8005680: 881b ldrh r3, [r3, #0] + 8005682: 18d3 adds r3, r2, r3 + 8005684: b29a uxth r2, r3 + 8005686: 687b ldr r3, [r7, #4] + 8005688: 815a strh r2, [r3, #10] + p->tot_len += header_size_increment; + 800568a: 687b ldr r3, [r7, #4] + 800568c: 891a ldrh r2, [r3, #8] + 800568e: 1cbb adds r3, r7, #2 + 8005690: 881b ldrh r3, [r3, #0] + 8005692: 18d3 adds r3, r2, r3 + 8005694: b29a uxth r2, r3 + 8005696: 687b ldr r3, [r7, #4] + 8005698: 811a strh r2, [r3, #8] + + LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_header: old %p new %p (%"S16_F")\n", + (void *)payload, (void *)p->payload, header_size_increment)); + + return 0; + 800569a: 2300 movs r3, #0 +} + 800569c: 0018 movs r0, r3 + 800569e: 46bd mov sp, r7 + 80056a0: b004 add sp, #16 + 80056a2: bd80 pop {r7, pc} + +080056a4 : + * 1->1->1 becomes ....... + * + */ +u8_t +pbuf_free(struct pbuf *p) +{ + 80056a4: b580 push {r7, lr} + 80056a6: b086 sub sp, #24 + 80056a8: af00 add r7, sp, #0 + 80056aa: 6078 str r0, [r7, #4] + u16_t type; + struct pbuf *q; + u8_t count; + + if (p == NULL) { + 80056ac: 687b ldr r3, [r7, #4] + 80056ae: 2b00 cmp r3, #0 + 80056b0: d101 bne.n 80056b6 + LWIP_ASSERT("p != NULL", p != NULL); + /* if assertions are disabled, proceed with debug output */ + LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_LEVEL_SERIOUS, + ("pbuf_free(p == NULL) was called.\n")); + return 0; + 80056b2: 2300 movs r3, #0 + 80056b4: e064 b.n 8005780 + } + LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_free(%p)\n", (void *)p)); + + PERF_START; + + LWIP_ASSERT("pbuf_free: sane type", + 80056b6: 687b ldr r3, [r7, #4] + 80056b8: 7b1b ldrb r3, [r3, #12] + 80056ba: 2b00 cmp r3, #0 + 80056bc: d001 beq.n 80056c2 + 80056be: 687b ldr r3, [r7, #4] + 80056c0: 7b1b ldrb r3, [r3, #12] + p->type == PBUF_RAM || p->type == PBUF_ROM || + p->type == PBUF_REF || p->type == PBUF_POOL); + + count = 0; + 80056c2: 2317 movs r3, #23 + 80056c4: 18fb adds r3, r7, r3 + 80056c6: 2200 movs r2, #0 + 80056c8: 701a strb r2, [r3, #0] + /* de-allocate all consecutive pbufs from the head of the chain that + * obtain a zero reference count after decrementing*/ + while (p != NULL) { + 80056ca: e053 b.n 8005774 + * further protection. */ + SYS_ARCH_PROTECT(old_level); + /* all pbufs in a chain are referenced at least once */ + LWIP_ASSERT("pbuf_free: p->ref > 0", p->ref > 0); + /* decrease reference count (number of pointers to pbuf) */ + ref = --(p->ref); + 80056cc: 687b ldr r3, [r7, #4] + 80056ce: 89db ldrh r3, [r3, #14] + 80056d0: 3b01 subs r3, #1 + 80056d2: b29a uxth r2, r3 + 80056d4: 687b ldr r3, [r7, #4] + 80056d6: 81da strh r2, [r3, #14] + 80056d8: 2114 movs r1, #20 + 80056da: 187b adds r3, r7, r1 + 80056dc: 687a ldr r2, [r7, #4] + 80056de: 89d2 ldrh r2, [r2, #14] + 80056e0: 801a strh r2, [r3, #0] + SYS_ARCH_UNPROTECT(old_level); + /* this pbuf is no longer referenced to? */ + if (ref == 0) { + 80056e2: 187b adds r3, r7, r1 + 80056e4: 881b ldrh r3, [r3, #0] + 80056e6: 2b00 cmp r3, #0 + 80056e8: d13d bne.n 8005766 + /* remember next pbuf in chain for next iteration */ + q = p->next; + 80056ea: 687b ldr r3, [r7, #4] + 80056ec: 681b ldr r3, [r3, #0] + 80056ee: 613b str r3, [r7, #16] + LWIP_DEBUGF( PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_free: deallocating %p\n", (void *)p)); + type = p->type; + 80056f0: 687b ldr r3, [r7, #4] + 80056f2: 7b1a ldrb r2, [r3, #12] + 80056f4: 230e movs r3, #14 + 80056f6: 18fb adds r3, r7, r3 + 80056f8: 801a strh r2, [r3, #0] +#if LWIP_SUPPORT_CUSTOM_PBUF + /* is this a custom pbuf? */ + if ((p->flags & PBUF_FLAG_IS_CUSTOM) != 0) { + 80056fa: 687b ldr r3, [r7, #4] + 80056fc: 7b5b ldrb r3, [r3, #13] + 80056fe: 001a movs r2, r3 + 8005700: 2302 movs r3, #2 + 8005702: 4013 ands r3, r2 + 8005704: d007 beq.n 8005716 + struct pbuf_custom *pc = (struct pbuf_custom*)p; + 8005706: 687b ldr r3, [r7, #4] + 8005708: 60bb str r3, [r7, #8] + LWIP_ASSERT("pc->custom_free_function != NULL", pc->custom_free_function != NULL); + pc->custom_free_function(p); + 800570a: 68bb ldr r3, [r7, #8] + 800570c: 691b ldr r3, [r3, #16] + 800570e: 687a ldr r2, [r7, #4] + 8005710: 0010 movs r0, r2 + 8005712: 4798 blx r3 + 8005714: e01e b.n 8005754 + } else +#endif /* LWIP_SUPPORT_CUSTOM_PBUF */ + { + /* is this a pbuf from the pool? */ + if (type == PBUF_POOL) { + 8005716: 230e movs r3, #14 + 8005718: 18fb adds r3, r7, r3 + 800571a: 881b ldrh r3, [r3, #0] + 800571c: 2b03 cmp r3, #3 + 800571e: d105 bne.n 800572c + memp_free(MEMP_PBUF_POOL, p); + 8005720: 687b ldr r3, [r7, #4] + 8005722: 0019 movs r1, r3 + 8005724: 2009 movs r0, #9 + 8005726: f7ff fbfb bl 8004f20 + 800572a: e013 b.n 8005754 + /* is this a ROM or RAM referencing pbuf? */ + } else if (type == PBUF_ROM || type == PBUF_REF) { + 800572c: 230e movs r3, #14 + 800572e: 18fb adds r3, r7, r3 + 8005730: 881b ldrh r3, [r3, #0] + 8005732: 2b01 cmp r3, #1 + 8005734: d004 beq.n 8005740 + 8005736: 230e movs r3, #14 + 8005738: 18fb adds r3, r7, r3 + 800573a: 881b ldrh r3, [r3, #0] + 800573c: 2b02 cmp r3, #2 + 800573e: d105 bne.n 800574c + memp_free(MEMP_PBUF, p); + 8005740: 687b ldr r3, [r7, #4] + 8005742: 0019 movs r1, r3 + 8005744: 2008 movs r0, #8 + 8005746: f7ff fbeb bl 8004f20 + 800574a: e003 b.n 8005754 + /* type == PBUF_RAM */ + } else { + mem_free(p); + 800574c: 687b ldr r3, [r7, #4] + 800574e: 0018 movs r0, r3 + 8005750: f7ff f862 bl 8004818 + } + } + count++; + 8005754: 2117 movs r1, #23 + 8005756: 187b adds r3, r7, r1 + 8005758: 781a ldrb r2, [r3, #0] + 800575a: 187b adds r3, r7, r1 + 800575c: 3201 adds r2, #1 + 800575e: 701a strb r2, [r3, #0] + /* proceed to next pbuf */ + p = q; + 8005760: 693b ldr r3, [r7, #16] + 8005762: 607b str r3, [r7, #4] + 8005764: e006 b.n 8005774 + /* p->ref > 0, this pbuf is still referenced to */ + /* (and so the remaining pbufs in chain as well) */ + } else { + LWIP_DEBUGF( PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_free: %p has ref %"U16_F", ending here.\n", (void *)p, ref)); + /* stop walking through the chain */ + p = NULL; + 8005766: 2300 movs r3, #0 + 8005768: 607b str r3, [r7, #4] + 800576a: 2217 movs r2, #23 + 800576c: 18bb adds r3, r7, r2 + 800576e: 18ba adds r2, r7, r2 + 8005770: 7812 ldrb r2, [r2, #0] + 8005772: 701a strb r2, [r3, #0] + while (p != NULL) { + 8005774: 687b ldr r3, [r7, #4] + 8005776: 2b00 cmp r3, #0 + 8005778: d1a8 bne.n 80056cc + } + } + PERF_STOP("pbuf_free"); + /* return number of de-allocated pbufs */ + return count; + 800577a: 2317 movs r3, #23 + 800577c: 18fb adds r3, r7, r3 + 800577e: 781b ldrb r3, [r3, #0] +} + 8005780: 0018 movs r0, r3 + 8005782: 46bd mov sp, r7 + 8005784: b006 add sp, #24 + 8005786: bd80 pop {r7, pc} + +08005788 : + * @return the number of pbufs in a chain + */ + +u8_t +pbuf_clen(struct pbuf *p) +{ + 8005788: b580 push {r7, lr} + 800578a: b084 sub sp, #16 + 800578c: af00 add r7, sp, #0 + 800578e: 6078 str r0, [r7, #4] + u8_t len; + + len = 0; + 8005790: 230f movs r3, #15 + 8005792: 18fb adds r3, r7, r3 + 8005794: 2200 movs r2, #0 + 8005796: 701a strb r2, [r3, #0] + while (p != NULL) { + 8005798: e008 b.n 80057ac + ++len; + 800579a: 220f movs r2, #15 + 800579c: 18bb adds r3, r7, r2 + 800579e: 18ba adds r2, r7, r2 + 80057a0: 7812 ldrb r2, [r2, #0] + 80057a2: 3201 adds r2, #1 + 80057a4: 701a strb r2, [r3, #0] + p = p->next; + 80057a6: 687b ldr r3, [r7, #4] + 80057a8: 681b ldr r3, [r3, #0] + 80057aa: 607b str r3, [r7, #4] + while (p != NULL) { + 80057ac: 687b ldr r3, [r7, #4] + 80057ae: 2b00 cmp r3, #0 + 80057b0: d1f3 bne.n 800579a + } + return len; + 80057b2: 230f movs r3, #15 + 80057b4: 18fb adds r3, r7, r3 + 80057b6: 781b ldrb r3, [r3, #0] +} + 80057b8: 0018 movs r0, r3 + 80057ba: 46bd mov sp, r7 + 80057bc: b004 add sp, #16 + 80057be: bd80 pop {r7, pc} + +080057c0 : + * @param p pbuf to increase reference counter of + * + */ +void +pbuf_ref(struct pbuf *p) +{ + 80057c0: b580 push {r7, lr} + 80057c2: b082 sub sp, #8 + 80057c4: af00 add r7, sp, #0 + 80057c6: 6078 str r0, [r7, #4] + SYS_ARCH_DECL_PROTECT(old_level); + /* pbuf given? */ + if (p != NULL) { + 80057c8: 687b ldr r3, [r7, #4] + 80057ca: 2b00 cmp r3, #0 + 80057cc: d005 beq.n 80057da + SYS_ARCH_PROTECT(old_level); + ++(p->ref); + 80057ce: 687b ldr r3, [r7, #4] + 80057d0: 89db ldrh r3, [r3, #14] + 80057d2: 3301 adds r3, #1 + 80057d4: b29a uxth r2, r3 + 80057d6: 687b ldr r3, [r7, #4] + 80057d8: 81da strh r2, [r3, #14] + SYS_ARCH_UNPROTECT(old_level); + } +} + 80057da: 46c0 nop ; (mov r8, r8) + 80057dc: 46bd mov sp, r7 + 80057de: b002 add sp, #8 + 80057e0: bd80 pop {r7, pc} + +080057e2 : + * @see pbuf_chain() + */ + +void +pbuf_cat(struct pbuf *h, struct pbuf *t) +{ + 80057e2: b580 push {r7, lr} + 80057e4: b084 sub sp, #16 + 80057e6: af00 add r7, sp, #0 + 80057e8: 6078 str r0, [r7, #4] + 80057ea: 6039 str r1, [r7, #0] + struct pbuf *p; + + LWIP_ERROR("(h != NULL) && (t != NULL) (programmer violates API)", + 80057ec: 687b ldr r3, [r7, #4] + 80057ee: 2b00 cmp r3, #0 + 80057f0: d020 beq.n 8005834 + 80057f2: 683b ldr r3, [r7, #0] + 80057f4: 2b00 cmp r3, #0 + 80057f6: d01d beq.n 8005834 + ((h != NULL) && (t != NULL)), return;); + + /* proceed to last pbuf of chain */ + for (p = h; p->next != NULL; p = p->next) { + 80057f8: 687b ldr r3, [r7, #4] + 80057fa: 60fb str r3, [r7, #12] + 80057fc: e00a b.n 8005814 + /* add total length of second chain to all totals of first chain */ + p->tot_len += t->tot_len; + 80057fe: 68fb ldr r3, [r7, #12] + 8005800: 891a ldrh r2, [r3, #8] + 8005802: 683b ldr r3, [r7, #0] + 8005804: 891b ldrh r3, [r3, #8] + 8005806: 18d3 adds r3, r2, r3 + 8005808: b29a uxth r2, r3 + 800580a: 68fb ldr r3, [r7, #12] + 800580c: 811a strh r2, [r3, #8] + for (p = h; p->next != NULL; p = p->next) { + 800580e: 68fb ldr r3, [r7, #12] + 8005810: 681b ldr r3, [r3, #0] + 8005812: 60fb str r3, [r7, #12] + 8005814: 68fb ldr r3, [r7, #12] + 8005816: 681b ldr r3, [r3, #0] + 8005818: 2b00 cmp r3, #0 + 800581a: d1f0 bne.n 80057fe + } + /* { p is last pbuf of first h chain, p->next == NULL } */ + LWIP_ASSERT("p->tot_len == p->len (of last pbuf in chain)", p->tot_len == p->len); + LWIP_ASSERT("p->next == NULL", p->next == NULL); + /* add total length of second chain to last pbuf total of first chain */ + p->tot_len += t->tot_len; + 800581c: 68fb ldr r3, [r7, #12] + 800581e: 891a ldrh r2, [r3, #8] + 8005820: 683b ldr r3, [r7, #0] + 8005822: 891b ldrh r3, [r3, #8] + 8005824: 18d3 adds r3, r2, r3 + 8005826: b29a uxth r2, r3 + 8005828: 68fb ldr r3, [r7, #12] + 800582a: 811a strh r2, [r3, #8] + /* chain last pbuf of head (p) with first of tail (t) */ + p->next = t; + 800582c: 68fb ldr r3, [r7, #12] + 800582e: 683a ldr r2, [r7, #0] + 8005830: 601a str r2, [r3, #0] + 8005832: e000 b.n 8005836 + LWIP_ERROR("(h != NULL) && (t != NULL) (programmer violates API)", + 8005834: 46c0 nop ; (mov r8, r8) + /* p->next now references t, but the caller will drop its reference to t, + * so netto there is no change to the reference count of t. + */ +} + 8005836: 46bd mov sp, r7 + 8005838: b004 add sp, #16 + 800583a: bd80 pop {r7, pc} + +0800583c : + * The ->ref field of the first pbuf of the tail chain is adjusted. + * + */ +void +pbuf_chain(struct pbuf *h, struct pbuf *t) +{ + 800583c: b580 push {r7, lr} + 800583e: b082 sub sp, #8 + 8005840: af00 add r7, sp, #0 + 8005842: 6078 str r0, [r7, #4] + 8005844: 6039 str r1, [r7, #0] + pbuf_cat(h, t); + 8005846: 683a ldr r2, [r7, #0] + 8005848: 687b ldr r3, [r7, #4] + 800584a: 0011 movs r1, r2 + 800584c: 0018 movs r0, r3 + 800584e: f7ff ffc8 bl 80057e2 + /* t is now referenced by h */ + pbuf_ref(t); + 8005852: 683b ldr r3, [r7, #0] + 8005854: 0018 movs r0, r3 + 8005856: f7ff ffb3 bl 80057c0 + LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_chain: %p references %p\n", (void *)h, (void *)t)); +} + 800585a: 46c0 nop ; (mov r8, r8) + 800585c: 46bd mov sp, r7 + 800585e: b002 add sp, #8 + 8005860: bd80 pop {r7, pc} + +08005862 : + * ERR_ARG if one of the pbufs is NULL or p_to is not big + * enough to hold p_from + */ +err_t +pbuf_copy(struct pbuf *p_to, struct pbuf *p_from) +{ + 8005862: b5f0 push {r4, r5, r6, r7, lr} + 8005864: b085 sub sp, #20 + 8005866: af00 add r7, sp, #0 + 8005868: 6078 str r0, [r7, #4] + 800586a: 6039 str r1, [r7, #0] + u16_t offset_to=0, offset_from=0, len; + 800586c: 230e movs r3, #14 + 800586e: 18fb adds r3, r7, r3 + 8005870: 2200 movs r2, #0 + 8005872: 801a strh r2, [r3, #0] + 8005874: 230c movs r3, #12 + 8005876: 18fb adds r3, r7, r3 + 8005878: 2200 movs r2, #0 + 800587a: 801a strh r2, [r3, #0] + + LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_copy(%p, %p)\n", + (void*)p_to, (void*)p_from)); + + /* is the target big enough to hold the source? */ + LWIP_ERROR("pbuf_copy: target not big enough to hold source", ((p_to != NULL) && + 800587c: 687b ldr r3, [r7, #4] + 800587e: 2b00 cmp r3, #0 + 8005880: d008 beq.n 8005894 + 8005882: 683b ldr r3, [r7, #0] + 8005884: 2b00 cmp r3, #0 + 8005886: d005 beq.n 8005894 + 8005888: 687b ldr r3, [r7, #4] + 800588a: 891a ldrh r2, [r3, #8] + 800588c: 683b ldr r3, [r7, #0] + 800588e: 891b ldrh r3, [r3, #8] + 8005890: 429a cmp r2, r3 + 8005892: d202 bcs.n 800589a + 8005894: 230e movs r3, #14 + 8005896: 425b negs r3, r3 + 8005898: e08c b.n 80059b4 + + /* iterate through pbuf chain */ + do + { + /* copy one part of the original chain */ + if ((p_to->len - offset_to) >= (p_from->len - offset_from)) { + 800589a: 687b ldr r3, [r7, #4] + 800589c: 895b ldrh r3, [r3, #10] + 800589e: 001a movs r2, r3 + 80058a0: 230e movs r3, #14 + 80058a2: 18fb adds r3, r7, r3 + 80058a4: 881b ldrh r3, [r3, #0] + 80058a6: 1ad2 subs r2, r2, r3 + 80058a8: 683b ldr r3, [r7, #0] + 80058aa: 895b ldrh r3, [r3, #10] + 80058ac: 0019 movs r1, r3 + 80058ae: 230c movs r3, #12 + 80058b0: 18fb adds r3, r7, r3 + 80058b2: 881b ldrh r3, [r3, #0] + 80058b4: 1acb subs r3, r1, r3 + 80058b6: 429a cmp r2, r3 + 80058b8: db09 blt.n 80058ce + /* complete current p_from fits into current p_to */ + len = p_from->len - offset_from; + 80058ba: 683b ldr r3, [r7, #0] + 80058bc: 8959 ldrh r1, [r3, #10] + 80058be: 230a movs r3, #10 + 80058c0: 18fb adds r3, r7, r3 + 80058c2: 220c movs r2, #12 + 80058c4: 18ba adds r2, r7, r2 + 80058c6: 8812 ldrh r2, [r2, #0] + 80058c8: 1a8a subs r2, r1, r2 + 80058ca: 801a strh r2, [r3, #0] + 80058cc: e008 b.n 80058e0 + } else { + /* current p_from does not fit into current p_to */ + len = p_to->len - offset_to; + 80058ce: 687b ldr r3, [r7, #4] + 80058d0: 8959 ldrh r1, [r3, #10] + 80058d2: 230a movs r3, #10 + 80058d4: 18fb adds r3, r7, r3 + 80058d6: 220e movs r2, #14 + 80058d8: 18ba adds r2, r7, r2 + 80058da: 8812 ldrh r2, [r2, #0] + 80058dc: 1a8a subs r2, r1, r2 + 80058de: 801a strh r2, [r3, #0] + } + MEMCPY((u8_t*)p_to->payload + offset_to, (u8_t*)p_from->payload + offset_from, len); + 80058e0: 687b ldr r3, [r7, #4] + 80058e2: 685a ldr r2, [r3, #4] + 80058e4: 250e movs r5, #14 + 80058e6: 197b adds r3, r7, r5 + 80058e8: 881b ldrh r3, [r3, #0] + 80058ea: 18d0 adds r0, r2, r3 + 80058ec: 683b ldr r3, [r7, #0] + 80058ee: 685a ldr r2, [r3, #4] + 80058f0: 240c movs r4, #12 + 80058f2: 193b adds r3, r7, r4 + 80058f4: 881b ldrh r3, [r3, #0] + 80058f6: 18d1 adds r1, r2, r3 + 80058f8: 260a movs r6, #10 + 80058fa: 19bb adds r3, r7, r6 + 80058fc: 881b ldrh r3, [r3, #0] + 80058fe: 001a movs r2, r3 + 8005900: f00a f9cf bl 800fca2 + offset_to += len; + 8005904: 197b adds r3, r7, r5 + 8005906: 1979 adds r1, r7, r5 + 8005908: 0030 movs r0, r6 + 800590a: 183a adds r2, r7, r0 + 800590c: 8809 ldrh r1, [r1, #0] + 800590e: 8812 ldrh r2, [r2, #0] + 8005910: 188a adds r2, r1, r2 + 8005912: 801a strh r2, [r3, #0] + offset_from += len; + 8005914: 193b adds r3, r7, r4 + 8005916: 1939 adds r1, r7, r4 + 8005918: 183a adds r2, r7, r0 + 800591a: 8809 ldrh r1, [r1, #0] + 800591c: 8812 ldrh r2, [r2, #0] + 800591e: 188a adds r2, r1, r2 + 8005920: 801a strh r2, [r3, #0] + LWIP_ASSERT("offset_to <= p_to->len", offset_to <= p_to->len); + LWIP_ASSERT("offset_from <= p_from->len", offset_from <= p_from->len); + if (offset_from >= p_from->len) { + 8005922: 683b ldr r3, [r7, #0] + 8005924: 895b ldrh r3, [r3, #10] + 8005926: 193a adds r2, r7, r4 + 8005928: 8812 ldrh r2, [r2, #0] + 800592a: 429a cmp r2, r3 + 800592c: d306 bcc.n 800593c + /* on to next p_from (if any) */ + offset_from = 0; + 800592e: 230c movs r3, #12 + 8005930: 18fb adds r3, r7, r3 + 8005932: 2200 movs r2, #0 + 8005934: 801a strh r2, [r3, #0] + p_from = p_from->next; + 8005936: 683b ldr r3, [r7, #0] + 8005938: 681b ldr r3, [r3, #0] + 800593a: 603b str r3, [r7, #0] + } + if (offset_to == p_to->len) { + 800593c: 687b ldr r3, [r7, #4] + 800593e: 895b ldrh r3, [r3, #10] + 8005940: 220e movs r2, #14 + 8005942: 18ba adds r2, r7, r2 + 8005944: 8812 ldrh r2, [r2, #0] + 8005946: 429a cmp r2, r3 + 8005948: d10f bne.n 800596a + /* on to next p_to (if any) */ + offset_to = 0; + 800594a: 230e movs r3, #14 + 800594c: 18fb adds r3, r7, r3 + 800594e: 2200 movs r2, #0 + 8005950: 801a strh r2, [r3, #0] + p_to = p_to->next; + 8005952: 687b ldr r3, [r7, #4] + 8005954: 681b ldr r3, [r3, #0] + 8005956: 607b str r3, [r7, #4] + LWIP_ERROR("p_to != NULL", (p_to != NULL) || (p_from == NULL) , return ERR_ARG;); + 8005958: 687b ldr r3, [r7, #4] + 800595a: 2b00 cmp r3, #0 + 800595c: d105 bne.n 800596a + 800595e: 683b ldr r3, [r7, #0] + 8005960: 2b00 cmp r3, #0 + 8005962: d002 beq.n 800596a + 8005964: 230e movs r3, #14 + 8005966: 425b negs r3, r3 + 8005968: e024 b.n 80059b4 + } + + if((p_from != NULL) && (p_from->len == p_from->tot_len)) { + 800596a: 683b ldr r3, [r7, #0] + 800596c: 2b00 cmp r3, #0 + 800596e: d00c beq.n 800598a + 8005970: 683b ldr r3, [r7, #0] + 8005972: 895a ldrh r2, [r3, #10] + 8005974: 683b ldr r3, [r7, #0] + 8005976: 891b ldrh r3, [r3, #8] + 8005978: 429a cmp r2, r3 + 800597a: d106 bne.n 800598a + /* don't copy more than one packet! */ + LWIP_ERROR("pbuf_copy() does not allow packet queues!\n", + 800597c: 683b ldr r3, [r7, #0] + 800597e: 681b ldr r3, [r3, #0] + 8005980: 2b00 cmp r3, #0 + 8005982: d002 beq.n 800598a + 8005984: 2306 movs r3, #6 + 8005986: 425b negs r3, r3 + 8005988: e014 b.n 80059b4 + (p_from->next == NULL), return ERR_VAL;); + } + if((p_to != NULL) && (p_to->len == p_to->tot_len)) { + 800598a: 687b ldr r3, [r7, #4] + 800598c: 2b00 cmp r3, #0 + 800598e: d00c beq.n 80059aa + 8005990: 687b ldr r3, [r7, #4] + 8005992: 895a ldrh r2, [r3, #10] + 8005994: 687b ldr r3, [r7, #4] + 8005996: 891b ldrh r3, [r3, #8] + 8005998: 429a cmp r2, r3 + 800599a: d106 bne.n 80059aa + /* don't copy more than one packet! */ + LWIP_ERROR("pbuf_copy() does not allow packet queues!\n", + 800599c: 687b ldr r3, [r7, #4] + 800599e: 681b ldr r3, [r3, #0] + 80059a0: 2b00 cmp r3, #0 + 80059a2: d002 beq.n 80059aa + 80059a4: 2306 movs r3, #6 + 80059a6: 425b negs r3, r3 + 80059a8: e004 b.n 80059b4 + (p_to->next == NULL), return ERR_VAL;); + } + } while (p_from); + 80059aa: 683b ldr r3, [r7, #0] + 80059ac: 2b00 cmp r3, #0 + 80059ae: d000 beq.n 80059b2 + 80059b0: e773 b.n 800589a + LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_copy: end of chain reached.\n")); + return ERR_OK; + 80059b2: 2300 movs r3, #0 +} + 80059b4: 0018 movs r0, r3 + 80059b6: 46bd mov sp, r7 + 80059b8: b005 add sp, #20 + 80059ba: bdf0 pop {r4, r5, r6, r7, pc} + +080059bc : + * @param offset offset into the packet buffer from where to begin copying len bytes + * @return the number of bytes copied, or 0 on failure + */ +u16_t +pbuf_copy_partial(struct pbuf *buf, void *dataptr, u16_t len, u16_t offset) +{ + 80059bc: b5b0 push {r4, r5, r7, lr} + 80059be: b088 sub sp, #32 + 80059c0: af00 add r7, sp, #0 + 80059c2: 60f8 str r0, [r7, #12] + 80059c4: 60b9 str r1, [r7, #8] + 80059c6: 0019 movs r1, r3 + 80059c8: 1dbb adds r3, r7, #6 + 80059ca: 801a strh r2, [r3, #0] + 80059cc: 1d3b adds r3, r7, #4 + 80059ce: 1c0a adds r2, r1, #0 + 80059d0: 801a strh r2, [r3, #0] + struct pbuf *p; + u16_t left; + u16_t buf_copy_len; + u16_t copied_total = 0; + 80059d2: 2316 movs r3, #22 + 80059d4: 18fb adds r3, r7, r3 + 80059d6: 2200 movs r2, #0 + 80059d8: 801a strh r2, [r3, #0] + + LWIP_ERROR("pbuf_copy_partial: invalid buf", (buf != NULL), return 0;); + 80059da: 68fb ldr r3, [r7, #12] + 80059dc: 2b00 cmp r3, #0 + 80059de: d101 bne.n 80059e4 + 80059e0: 2300 movs r3, #0 + 80059e2: e06f b.n 8005ac4 + LWIP_ERROR("pbuf_copy_partial: invalid dataptr", (dataptr != NULL), return 0;); + 80059e4: 68bb ldr r3, [r7, #8] + 80059e6: 2b00 cmp r3, #0 + 80059e8: d101 bne.n 80059ee + 80059ea: 2300 movs r3, #0 + 80059ec: e06a b.n 8005ac4 + + left = 0; + 80059ee: 231a movs r3, #26 + 80059f0: 18fb adds r3, r7, r3 + 80059f2: 2200 movs r2, #0 + 80059f4: 801a strh r2, [r3, #0] + + if((buf == NULL) || (dataptr == NULL)) { + 80059f6: 68fb ldr r3, [r7, #12] + 80059f8: 2b00 cmp r3, #0 + 80059fa: d002 beq.n 8005a02 + 80059fc: 68bb ldr r3, [r7, #8] + 80059fe: 2b00 cmp r3, #0 + 8005a00: d101 bne.n 8005a06 + return 0; + 8005a02: 2300 movs r3, #0 + 8005a04: e05e b.n 8005ac4 + } + + /* Note some systems use byte copy if dataptr or one of the pbuf payload pointers are unaligned. */ + for(p = buf; len != 0 && p != NULL; p = p->next) { + 8005a06: 68fb ldr r3, [r7, #12] + 8005a08: 61fb str r3, [r7, #28] + 8005a0a: e051 b.n 8005ab0 + if ((offset != 0) && (offset >= p->len)) { + 8005a0c: 1d3b adds r3, r7, #4 + 8005a0e: 881b ldrh r3, [r3, #0] + 8005a10: 2b00 cmp r3, #0 + 8005a12: d00d beq.n 8005a30 + 8005a14: 69fb ldr r3, [r7, #28] + 8005a16: 895b ldrh r3, [r3, #10] + 8005a18: 1d3a adds r2, r7, #4 + 8005a1a: 8812 ldrh r2, [r2, #0] + 8005a1c: 429a cmp r2, r3 + 8005a1e: d307 bcc.n 8005a30 + /* don't copy from this buffer -> on to the next */ + offset -= p->len; + 8005a20: 69fb ldr r3, [r7, #28] + 8005a22: 895a ldrh r2, [r3, #10] + 8005a24: 1d3b adds r3, r7, #4 + 8005a26: 1d39 adds r1, r7, #4 + 8005a28: 8809 ldrh r1, [r1, #0] + 8005a2a: 1a8a subs r2, r1, r2 + 8005a2c: 801a strh r2, [r3, #0] + 8005a2e: e03c b.n 8005aaa + } else { + /* copy from this buffer. maybe only partially. */ + buf_copy_len = p->len - offset; + 8005a30: 69fb ldr r3, [r7, #28] + 8005a32: 8959 ldrh r1, [r3, #10] + 8005a34: 2018 movs r0, #24 + 8005a36: 183b adds r3, r7, r0 + 8005a38: 1d3a adds r2, r7, #4 + 8005a3a: 8812 ldrh r2, [r2, #0] + 8005a3c: 1a8a subs r2, r1, r2 + 8005a3e: 801a strh r2, [r3, #0] + if (buf_copy_len > len) + 8005a40: 183a adds r2, r7, r0 + 8005a42: 1dbb adds r3, r7, #6 + 8005a44: 8812 ldrh r2, [r2, #0] + 8005a46: 881b ldrh r3, [r3, #0] + 8005a48: 429a cmp r2, r3 + 8005a4a: d904 bls.n 8005a56 + buf_copy_len = len; + 8005a4c: 2318 movs r3, #24 + 8005a4e: 18fb adds r3, r7, r3 + 8005a50: 1dba adds r2, r7, #6 + 8005a52: 8812 ldrh r2, [r2, #0] + 8005a54: 801a strh r2, [r3, #0] + /* copy the necessary parts of the buffer */ + MEMCPY(&((char*)dataptr)[left], &((char*)p->payload)[offset], buf_copy_len); + 8005a56: 251a movs r5, #26 + 8005a58: 197b adds r3, r7, r5 + 8005a5a: 881b ldrh r3, [r3, #0] + 8005a5c: 68ba ldr r2, [r7, #8] + 8005a5e: 18d0 adds r0, r2, r3 + 8005a60: 69fb ldr r3, [r7, #28] + 8005a62: 685a ldr r2, [r3, #4] + 8005a64: 1d3b adds r3, r7, #4 + 8005a66: 881b ldrh r3, [r3, #0] + 8005a68: 18d1 adds r1, r2, r3 + 8005a6a: 2418 movs r4, #24 + 8005a6c: 193b adds r3, r7, r4 + 8005a6e: 881b ldrh r3, [r3, #0] + 8005a70: 001a movs r2, r3 + 8005a72: f00a f916 bl 800fca2 + copied_total += buf_copy_len; + 8005a76: 2216 movs r2, #22 + 8005a78: 18bb adds r3, r7, r2 + 8005a7a: 18b9 adds r1, r7, r2 + 8005a7c: 0020 movs r0, r4 + 8005a7e: 183a adds r2, r7, r0 + 8005a80: 8809 ldrh r1, [r1, #0] + 8005a82: 8812 ldrh r2, [r2, #0] + 8005a84: 188a adds r2, r1, r2 + 8005a86: 801a strh r2, [r3, #0] + left += buf_copy_len; + 8005a88: 197b adds r3, r7, r5 + 8005a8a: 1979 adds r1, r7, r5 + 8005a8c: 183a adds r2, r7, r0 + 8005a8e: 8809 ldrh r1, [r1, #0] + 8005a90: 8812 ldrh r2, [r2, #0] + 8005a92: 188a adds r2, r1, r2 + 8005a94: 801a strh r2, [r3, #0] + len -= buf_copy_len; + 8005a96: 1dbb adds r3, r7, #6 + 8005a98: 1db9 adds r1, r7, #6 + 8005a9a: 183a adds r2, r7, r0 + 8005a9c: 8809 ldrh r1, [r1, #0] + 8005a9e: 8812 ldrh r2, [r2, #0] + 8005aa0: 1a8a subs r2, r1, r2 + 8005aa2: 801a strh r2, [r3, #0] + offset = 0; + 8005aa4: 1d3b adds r3, r7, #4 + 8005aa6: 2200 movs r2, #0 + 8005aa8: 801a strh r2, [r3, #0] + for(p = buf; len != 0 && p != NULL; p = p->next) { + 8005aaa: 69fb ldr r3, [r7, #28] + 8005aac: 681b ldr r3, [r3, #0] + 8005aae: 61fb str r3, [r7, #28] + 8005ab0: 1dbb adds r3, r7, #6 + 8005ab2: 881b ldrh r3, [r3, #0] + 8005ab4: 2b00 cmp r3, #0 + 8005ab6: d002 beq.n 8005abe + 8005ab8: 69fb ldr r3, [r7, #28] + 8005aba: 2b00 cmp r3, #0 + 8005abc: d1a6 bne.n 8005a0c + } + } + return copied_total; + 8005abe: 2316 movs r3, #22 + 8005ac0: 18fb adds r3, r7, r3 + 8005ac2: 881b ldrh r3, [r3, #0] +} + 8005ac4: 0018 movs r0, r3 + 8005ac6: 46bd mov sp, r7 + 8005ac8: b008 add sp, #32 + 8005aca: bdb0 pop {r4, r5, r7, pc} + +08005acc : + * caller). + * + */ +u8_t +raw_input(struct pbuf *p, struct netif *inp) +{ + 8005acc: b590 push {r4, r7, lr} + 8005ace: b089 sub sp, #36 ; 0x24 + 8005ad0: af00 add r7, sp, #0 + 8005ad2: 6078 str r0, [r7, #4] + 8005ad4: 6039 str r1, [r7, #0] + struct raw_pcb *pcb, *prev; + struct ip_hdr *iphdr; + s16_t proto; + u8_t eaten = 0; + 8005ad6: 2317 movs r3, #23 + 8005ad8: 18fb adds r3, r7, r3 + 8005ada: 2200 movs r2, #0 + 8005adc: 701a strb r2, [r3, #0] + + LWIP_UNUSED_ARG(inp); + + iphdr = (struct ip_hdr *)p->payload; + 8005ade: 687b ldr r3, [r7, #4] + 8005ae0: 685b ldr r3, [r3, #4] + 8005ae2: 613b str r3, [r7, #16] + proto = IPH_PROTO(iphdr); + 8005ae4: 693b ldr r3, [r7, #16] + 8005ae6: 7a5a ldrb r2, [r3, #9] + 8005ae8: 230e movs r3, #14 + 8005aea: 18fb adds r3, r7, r3 + 8005aec: 801a strh r2, [r3, #0] + + prev = NULL; + 8005aee: 2300 movs r3, #0 + 8005af0: 61bb str r3, [r7, #24] + pcb = raw_pcbs; + 8005af2: 4b28 ldr r3, [pc, #160] ; (8005b94 ) + 8005af4: 681b ldr r3, [r3, #0] + 8005af6: 61fb str r3, [r7, #28] + /* loop through all raw pcbs until the packet is eaten by one */ + /* this allows multiple pcbs to match against the packet by design */ + while ((eaten == 0) && (pcb != NULL)) { + 8005af8: e03c b.n 8005b74 + if ((pcb->protocol == proto) && + 8005afa: 69fb ldr r3, [r7, #28] + 8005afc: 7c1b ldrb r3, [r3, #16] + 8005afe: 001a movs r2, r3 + 8005b00: 230e movs r3, #14 + 8005b02: 18fb adds r3, r7, r3 + 8005b04: 2100 movs r1, #0 + 8005b06: 5e5b ldrsh r3, [r3, r1] + 8005b08: 429a cmp r2, r3 + 8005b0a: d12e bne.n 8005b6a + (ip_addr_isany(&pcb->local_ip) || + 8005b0c: 69fb ldr r3, [r7, #28] + if ((pcb->protocol == proto) && + 8005b0e: 2b00 cmp r3, #0 + 8005b10: d009 beq.n 8005b26 + (ip_addr_isany(&pcb->local_ip) || + 8005b12: 69fb ldr r3, [r7, #28] + 8005b14: 681b ldr r3, [r3, #0] + 8005b16: 2b00 cmp r3, #0 + 8005b18: d005 beq.n 8005b26 + ip_addr_cmp(&(pcb->local_ip), ¤t_iphdr_dest))) { + 8005b1a: 69fb ldr r3, [r7, #28] + 8005b1c: 681a ldr r2, [r3, #0] + 8005b1e: 4b1e ldr r3, [pc, #120] ; (8005b98 ) + 8005b20: 681b ldr r3, [r3, #0] + (ip_addr_isany(&pcb->local_ip) || + 8005b22: 429a cmp r2, r3 + 8005b24: d121 bne.n 8005b6a + /* broadcast filter? */ + if (ip_get_option(pcb, SOF_BROADCAST) || !ip_addr_isbroadcast(¤t_iphdr_dest, inp)) +#endif /* IP_SOF_BROADCAST_RECV */ + { + /* receive callback function available? */ + if (pcb->recv != NULL) { + 8005b26: 69fb ldr r3, [r7, #28] + 8005b28: 695b ldr r3, [r3, #20] + 8005b2a: 2b00 cmp r3, #0 + 8005b2c: d01d beq.n 8005b6a + /* the receive callback function did not eat the packet? */ + if (pcb->recv(pcb->recv_arg, pcb, p, ip_current_src_addr()) != 0) { + 8005b2e: 69fb ldr r3, [r7, #28] + 8005b30: 695c ldr r4, [r3, #20] + 8005b32: 69fb ldr r3, [r7, #28] + 8005b34: 6998 ldr r0, [r3, #24] + 8005b36: 4b19 ldr r3, [pc, #100] ; (8005b9c ) + 8005b38: 687a ldr r2, [r7, #4] + 8005b3a: 69f9 ldr r1, [r7, #28] + 8005b3c: 47a0 blx r4 + 8005b3e: 1e03 subs r3, r0, #0 + 8005b40: d013 beq.n 8005b6a + /* receive function ate the packet */ + p = NULL; + 8005b42: 2300 movs r3, #0 + 8005b44: 607b str r3, [r7, #4] + eaten = 1; + 8005b46: 2317 movs r3, #23 + 8005b48: 18fb adds r3, r7, r3 + 8005b4a: 2201 movs r2, #1 + 8005b4c: 701a strb r2, [r3, #0] + if (prev != NULL) { + 8005b4e: 69bb ldr r3, [r7, #24] + 8005b50: 2b00 cmp r3, #0 + 8005b52: d00a beq.n 8005b6a + /* move the pcb to the front of raw_pcbs so that is + found faster next time */ + prev->next = pcb->next; + 8005b54: 69fb ldr r3, [r7, #28] + 8005b56: 68da ldr r2, [r3, #12] + 8005b58: 69bb ldr r3, [r7, #24] + 8005b5a: 60da str r2, [r3, #12] + pcb->next = raw_pcbs; + 8005b5c: 4b0d ldr r3, [pc, #52] ; (8005b94 ) + 8005b5e: 681a ldr r2, [r3, #0] + 8005b60: 69fb ldr r3, [r7, #28] + 8005b62: 60da str r2, [r3, #12] + raw_pcbs = pcb; + 8005b64: 4b0b ldr r3, [pc, #44] ; (8005b94 ) + 8005b66: 69fa ldr r2, [r7, #28] + 8005b68: 601a str r2, [r3, #0] + } + /* no receive callback function was set for this raw PCB */ + } + /* drop the packet */ + } + prev = pcb; + 8005b6a: 69fb ldr r3, [r7, #28] + 8005b6c: 61bb str r3, [r7, #24] + pcb = pcb->next; + 8005b6e: 69fb ldr r3, [r7, #28] + 8005b70: 68db ldr r3, [r3, #12] + 8005b72: 61fb str r3, [r7, #28] + while ((eaten == 0) && (pcb != NULL)) { + 8005b74: 2317 movs r3, #23 + 8005b76: 18fb adds r3, r7, r3 + 8005b78: 781b ldrb r3, [r3, #0] + 8005b7a: 2b00 cmp r3, #0 + 8005b7c: d102 bne.n 8005b84 + 8005b7e: 69fb ldr r3, [r7, #28] + 8005b80: 2b00 cmp r3, #0 + 8005b82: d1ba bne.n 8005afa + } + return eaten; + 8005b84: 2317 movs r3, #23 + 8005b86: 18fb adds r3, r7, r3 + 8005b88: 781b ldrb r3, [r3, #0] +} + 8005b8a: 0018 movs r0, r3 + 8005b8c: 46bd mov sp, r7 + 8005b8e: b009 add sp, #36 ; 0x24 + 8005b90: bd90 pop {r4, r7, pc} + 8005b92: 46c0 nop ; (mov r8, r8) + 8005b94: 20002274 .word 0x20002274 + 8005b98: 2000329c .word 0x2000329c + 8005b9c: 20003294 .word 0x20003294 + +08005ba0 : +#include + +struct stats_ lwip_stats; + +void stats_init(void) +{ + 8005ba0: b580 push {r7, lr} + 8005ba2: af00 add r7, sp, #0 +#endif /* MEMP_STATS */ +#if MEM_STATS + lwip_stats.mem.name = "MEM"; +#endif /* MEM_STATS */ +#endif /* LWIP_DEBUG */ +} + 8005ba4: 46c0 nop ; (mov r8, r8) + 8005ba6: 46bd mov sp, r7 + 8005ba8: bd80 pop {r7, pc} + +08005baa : +/** + * Initialize this module. + */ +void +tcp_init(void) +{ + 8005baa: b580 push {r7, lr} + 8005bac: af00 add r7, sp, #0 +#if LWIP_RANDOMIZE_INITIAL_LOCAL_PORTS && defined(LWIP_RAND) + tcp_port = TCP_ENSURE_LOCAL_PORT_RANGE(LWIP_RAND()); +#endif /* LWIP_RANDOMIZE_INITIAL_LOCAL_PORTS && defined(LWIP_RAND) */ +} + 8005bae: 46c0 nop ; (mov r8, r8) + 8005bb0: 46bd mov sp, r7 + 8005bb2: bd80 pop {r7, pc} + +08005bb4 : +/** + * Called periodically to dispatch TCP timers. + */ +void +tcp_tmr(void) +{ + 8005bb4: b580 push {r7, lr} + 8005bb6: af00 add r7, sp, #0 + /* Call tcp_fasttmr() every 250 ms */ + tcp_fasttmr(); + 8005bb8: f000 fcd0 bl 800655c + + if (++tcp_timer & 1) { + 8005bbc: 4b08 ldr r3, [pc, #32] ; (8005be0 ) + 8005bbe: 781b ldrb r3, [r3, #0] + 8005bc0: 3301 adds r3, #1 + 8005bc2: b2da uxtb r2, r3 + 8005bc4: 4b06 ldr r3, [pc, #24] ; (8005be0 ) + 8005bc6: 701a strb r2, [r3, #0] + 8005bc8: 4b05 ldr r3, [pc, #20] ; (8005be0 ) + 8005bca: 781b ldrb r3, [r3, #0] + 8005bcc: 001a movs r2, r3 + 8005bce: 2301 movs r3, #1 + 8005bd0: 4013 ands r3, r2 + 8005bd2: d001 beq.n 8005bd8 + /* Call tcp_tmr() every 500 ms, i.e., every other timer + tcp_tmr() is called. */ + tcp_slowtmr(); + 8005bd4: f000 fa54 bl 8006080 + } +} + 8005bd8: 46c0 nop ; (mov r8, r8) + 8005bda: 46bd mov sp, r7 + 8005bdc: bd80 pop {r7, pc} + 8005bde: 46c0 nop ; (mov r8, r8) + 8005be0: 20002278 .word 0x20002278 + +08005be4 : + * @return ERR_OK if connection has been closed + * another err_t if closing failed and pcb is not freed + */ +static err_t +tcp_close_shutdown(struct tcp_pcb *pcb, u8_t rst_on_unacked_data) +{ + 8005be4: b5b0 push {r4, r5, r7, lr} + 8005be6: b086 sub sp, #24 + 8005be8: af02 add r7, sp, #8 + 8005bea: 6078 str r0, [r7, #4] + 8005bec: 000a movs r2, r1 + 8005bee: 1cfb adds r3, r7, #3 + 8005bf0: 701a strb r2, [r3, #0] + err_t err; + + if (rst_on_unacked_data && ((pcb->state == ESTABLISHED) || (pcb->state == CLOSE_WAIT))) { + 8005bf2: 1cfb adds r3, r7, #3 + 8005bf4: 781b ldrb r3, [r3, #0] + 8005bf6: 2b00 cmp r3, #0 + 8005bf8: d100 bne.n 8005bfc + 8005bfa: e068 b.n 8005cce + 8005bfc: 687b ldr r3, [r7, #4] + 8005bfe: 7e1b ldrb r3, [r3, #24] + 8005c00: 2b04 cmp r3, #4 + 8005c02: d003 beq.n 8005c0c + 8005c04: 687b ldr r3, [r7, #4] + 8005c06: 7e1b ldrb r3, [r3, #24] + 8005c08: 2b07 cmp r3, #7 + 8005c0a: d160 bne.n 8005cce + if ((pcb->refused_data != NULL) || (pcb->rcv_wnd != TCP_WND)) { + 8005c0c: 687b ldr r3, [r7, #4] + 8005c0e: 6f9b ldr r3, [r3, #120] ; 0x78 + 8005c10: 2b00 cmp r3, #0 + 8005c12: d104 bne.n 8005c1e + 8005c14: 687b ldr r3, [r7, #4] + 8005c16: 8d9b ldrh r3, [r3, #44] ; 0x2c + 8005c18: 4a8b ldr r2, [pc, #556] ; (8005e48 ) + 8005c1a: 4293 cmp r3, r2 + 8005c1c: d057 beq.n 8005cce + side about this. */ + LWIP_ASSERT("pcb->flags & TF_RXCLOSED", pcb->flags & TF_RXCLOSED); + + /* don't call tcp_abort here: we must not deallocate the pcb since + that might not be expected when calling tcp_close */ + tcp_rst(pcb->snd_nxt, pcb->rcv_nxt, &pcb->local_ip, &pcb->remote_ip, + 8005c1e: 687b ldr r3, [r7, #4] + 8005c20: 6d18 ldr r0, [r3, #80] ; 0x50 + 8005c22: 687b ldr r3, [r7, #4] + 8005c24: 6a99 ldr r1, [r3, #40] ; 0x28 + 8005c26: 687c ldr r4, [r7, #4] + 8005c28: 687b ldr r3, [r7, #4] + 8005c2a: 1d1d adds r5, r3, #4 + 8005c2c: 687b ldr r3, [r7, #4] + 8005c2e: 8b5b ldrh r3, [r3, #26] + 8005c30: 687a ldr r2, [r7, #4] + 8005c32: 8b92 ldrh r2, [r2, #28] + 8005c34: 9201 str r2, [sp, #4] + 8005c36: 9300 str r3, [sp, #0] + 8005c38: 002b movs r3, r5 + 8005c3a: 0022 movs r2, r4 + 8005c3c: f004 f9c6 bl 8009fcc + pcb->local_port, pcb->remote_port); + + tcp_pcb_purge(pcb); + 8005c40: 687b ldr r3, [r7, #4] + 8005c42: 0018 movs r0, r3 + 8005c44: f000 fef0 bl 8006a28 + TCP_RMV_ACTIVE(pcb); + 8005c48: 4b80 ldr r3, [pc, #512] ; (8005e4c ) + 8005c4a: 681b ldr r3, [r3, #0] + 8005c4c: 687a ldr r2, [r7, #4] + 8005c4e: 429a cmp r2, r3 + 8005c50: d105 bne.n 8005c5e + 8005c52: 4b7e ldr r3, [pc, #504] ; (8005e4c ) + 8005c54: 681b ldr r3, [r3, #0] + 8005c56: 68da ldr r2, [r3, #12] + 8005c58: 4b7c ldr r3, [pc, #496] ; (8005e4c ) + 8005c5a: 601a str r2, [r3, #0] + 8005c5c: e019 b.n 8005c92 + 8005c5e: 4b7b ldr r3, [pc, #492] ; (8005e4c ) + 8005c60: 681a ldr r2, [r3, #0] + 8005c62: 4b7b ldr r3, [pc, #492] ; (8005e50 ) + 8005c64: 601a str r2, [r3, #0] + 8005c66: e010 b.n 8005c8a + 8005c68: 4b79 ldr r3, [pc, #484] ; (8005e50 ) + 8005c6a: 681b ldr r3, [r3, #0] + 8005c6c: 68db ldr r3, [r3, #12] + 8005c6e: 687a ldr r2, [r7, #4] + 8005c70: 429a cmp r2, r3 + 8005c72: d105 bne.n 8005c80 + 8005c74: 4b76 ldr r3, [pc, #472] ; (8005e50 ) + 8005c76: 681b ldr r3, [r3, #0] + 8005c78: 687a ldr r2, [r7, #4] + 8005c7a: 68d2 ldr r2, [r2, #12] + 8005c7c: 60da str r2, [r3, #12] + 8005c7e: e008 b.n 8005c92 + 8005c80: 4b73 ldr r3, [pc, #460] ; (8005e50 ) + 8005c82: 681b ldr r3, [r3, #0] + 8005c84: 68da ldr r2, [r3, #12] + 8005c86: 4b72 ldr r3, [pc, #456] ; (8005e50 ) + 8005c88: 601a str r2, [r3, #0] + 8005c8a: 4b71 ldr r3, [pc, #452] ; (8005e50 ) + 8005c8c: 681b ldr r3, [r3, #0] + 8005c8e: 2b00 cmp r3, #0 + 8005c90: d1ea bne.n 8005c68 + 8005c92: 687b ldr r3, [r7, #4] + 8005c94: 2200 movs r2, #0 + 8005c96: 60da str r2, [r3, #12] + 8005c98: 4b6e ldr r3, [pc, #440] ; (8005e54 ) + 8005c9a: 2201 movs r2, #1 + 8005c9c: 701a strb r2, [r3, #0] + if (pcb->state == ESTABLISHED) { + 8005c9e: 687b ldr r3, [r7, #4] + 8005ca0: 7e1b ldrb r3, [r3, #24] + 8005ca2: 2b04 cmp r3, #4 + 8005ca4: d10c bne.n 8005cc0 + /* move to TIME_WAIT since we close actively */ + pcb->state = TIME_WAIT; + 8005ca6: 687b ldr r3, [r7, #4] + 8005ca8: 220a movs r2, #10 + 8005caa: 761a strb r2, [r3, #24] + TCP_REG(&tcp_tw_pcbs, pcb); + 8005cac: 4b6a ldr r3, [pc, #424] ; (8005e58 ) + 8005cae: 681a ldr r2, [r3, #0] + 8005cb0: 687b ldr r3, [r7, #4] + 8005cb2: 60da str r2, [r3, #12] + 8005cb4: 4b68 ldr r3, [pc, #416] ; (8005e58 ) + 8005cb6: 687a ldr r2, [r7, #4] + 8005cb8: 601a str r2, [r3, #0] + 8005cba: f004 fcdb bl 800a674 + 8005cbe: e004 b.n 8005cca + } else { + /* CLOSE_WAIT: deallocate the pcb since we already sent a RST for it */ + memp_free(MEMP_TCP_PCB, pcb); + 8005cc0: 687b ldr r3, [r7, #4] + 8005cc2: 0019 movs r1, r3 + 8005cc4: 2002 movs r0, #2 + 8005cc6: f7ff f92b bl 8004f20 + } + return ERR_OK; + 8005cca: 2300 movs r3, #0 + 8005ccc: e0b8 b.n 8005e40 + } + } + + switch (pcb->state) { + 8005cce: 687b ldr r3, [r7, #4] + 8005cd0: 7e1b ldrb r3, [r3, #24] + 8005cd2: 2b07 cmp r3, #7 + 8005cd4: d900 bls.n 8005cd8 + 8005cd6: e096 b.n 8005e06 + 8005cd8: 009a lsls r2, r3, #2 + 8005cda: 4b60 ldr r3, [pc, #384] ; (8005e5c ) + 8005cdc: 18d3 adds r3, r2, r3 + 8005cde: 681b ldr r3, [r3, #0] + 8005ce0: 469f mov pc, r3 + * and the user needs some way to free it should the need arise. + * Calling tcp_close() with a pcb that has already been closed, (i.e. twice) + * or for a pcb that has been used and then entered the CLOSED state + * is erroneous, but this should never happen as the pcb has in those cases + * been freed, and so any remaining handles are bogus. */ + err = ERR_OK; + 8005ce2: 230f movs r3, #15 + 8005ce4: 18fb adds r3, r7, r3 + 8005ce6: 2200 movs r2, #0 + 8005ce8: 701a strb r2, [r3, #0] + if (pcb->local_port != 0) { + 8005cea: 687b ldr r3, [r7, #4] + 8005cec: 8b5b ldrh r3, [r3, #26] + 8005cee: 2b00 cmp r3, #0 + 8005cf0: d027 beq.n 8005d42 + TCP_RMV(&tcp_bound_pcbs, pcb); + 8005cf2: 4b5b ldr r3, [pc, #364] ; (8005e60 ) + 8005cf4: 681b ldr r3, [r3, #0] + 8005cf6: 687a ldr r2, [r7, #4] + 8005cf8: 429a cmp r2, r3 + 8005cfa: d105 bne.n 8005d08 + 8005cfc: 4b58 ldr r3, [pc, #352] ; (8005e60 ) + 8005cfe: 681b ldr r3, [r3, #0] + 8005d00: 68da ldr r2, [r3, #12] + 8005d02: 4b57 ldr r3, [pc, #348] ; (8005e60 ) + 8005d04: 601a str r2, [r3, #0] + 8005d06: e019 b.n 8005d3c + 8005d08: 4b55 ldr r3, [pc, #340] ; (8005e60 ) + 8005d0a: 681a ldr r2, [r3, #0] + 8005d0c: 4b50 ldr r3, [pc, #320] ; (8005e50 ) + 8005d0e: 601a str r2, [r3, #0] + 8005d10: e010 b.n 8005d34 + 8005d12: 4b4f ldr r3, [pc, #316] ; (8005e50 ) + 8005d14: 681b ldr r3, [r3, #0] + 8005d16: 68db ldr r3, [r3, #12] + 8005d18: 687a ldr r2, [r7, #4] + 8005d1a: 429a cmp r2, r3 + 8005d1c: d105 bne.n 8005d2a + 8005d1e: 4b4c ldr r3, [pc, #304] ; (8005e50 ) + 8005d20: 681b ldr r3, [r3, #0] + 8005d22: 687a ldr r2, [r7, #4] + 8005d24: 68d2 ldr r2, [r2, #12] + 8005d26: 60da str r2, [r3, #12] + 8005d28: e008 b.n 8005d3c + 8005d2a: 4b49 ldr r3, [pc, #292] ; (8005e50 ) + 8005d2c: 681b ldr r3, [r3, #0] + 8005d2e: 68da ldr r2, [r3, #12] + 8005d30: 4b47 ldr r3, [pc, #284] ; (8005e50 ) + 8005d32: 601a str r2, [r3, #0] + 8005d34: 4b46 ldr r3, [pc, #280] ; (8005e50 ) + 8005d36: 681b ldr r3, [r3, #0] + 8005d38: 2b00 cmp r3, #0 + 8005d3a: d1ea bne.n 8005d12 + 8005d3c: 687b ldr r3, [r7, #4] + 8005d3e: 2200 movs r2, #0 + 8005d40: 60da str r2, [r3, #12] + } + memp_free(MEMP_TCP_PCB, pcb); + 8005d42: 687b ldr r3, [r7, #4] + 8005d44: 0019 movs r1, r3 + 8005d46: 2002 movs r0, #2 + 8005d48: f7ff f8ea bl 8004f20 + pcb = NULL; + 8005d4c: 2300 movs r3, #0 + 8005d4e: 607b str r3, [r7, #4] + break; + 8005d50: e065 b.n 8005e1e + case LISTEN: + err = ERR_OK; + 8005d52: 230f movs r3, #15 + 8005d54: 18fb adds r3, r7, r3 + 8005d56: 2200 movs r2, #0 + 8005d58: 701a strb r2, [r3, #0] + tcp_pcb_remove(&tcp_listen_pcbs.pcbs, pcb); + 8005d5a: 687a ldr r2, [r7, #4] + 8005d5c: 4b41 ldr r3, [pc, #260] ; (8005e64 ) + 8005d5e: 0011 movs r1, r2 + 8005d60: 0018 movs r0, r3 + 8005d62: f000 fea3 bl 8006aac + memp_free(MEMP_TCP_PCB_LISTEN, pcb); + 8005d66: 687b ldr r3, [r7, #4] + 8005d68: 0019 movs r1, r3 + 8005d6a: 2003 movs r0, #3 + 8005d6c: f7ff f8d8 bl 8004f20 + pcb = NULL; + 8005d70: 2300 movs r3, #0 + 8005d72: 607b str r3, [r7, #4] + break; + 8005d74: e053 b.n 8005e1e + case SYN_SENT: + err = ERR_OK; + 8005d76: 230f movs r3, #15 + 8005d78: 18fb adds r3, r7, r3 + 8005d7a: 2200 movs r2, #0 + 8005d7c: 701a strb r2, [r3, #0] + TCP_PCB_REMOVE_ACTIVE(pcb); + 8005d7e: 687a ldr r2, [r7, #4] + 8005d80: 4b32 ldr r3, [pc, #200] ; (8005e4c ) + 8005d82: 0011 movs r1, r2 + 8005d84: 0018 movs r0, r3 + 8005d86: f000 fe91 bl 8006aac + 8005d8a: 4b32 ldr r3, [pc, #200] ; (8005e54 ) + 8005d8c: 2201 movs r2, #1 + 8005d8e: 701a strb r2, [r3, #0] + memp_free(MEMP_TCP_PCB, pcb); + 8005d90: 687b ldr r3, [r7, #4] + 8005d92: 0019 movs r1, r3 + 8005d94: 2002 movs r0, #2 + 8005d96: f7ff f8c3 bl 8004f20 + pcb = NULL; + 8005d9a: 2300 movs r3, #0 + 8005d9c: 607b str r3, [r7, #4] + snmp_inc_tcpattemptfails(); + break; + 8005d9e: e03e b.n 8005e1e + case SYN_RCVD: + err = tcp_send_fin(pcb); + 8005da0: 250f movs r5, #15 + 8005da2: 197c adds r4, r7, r5 + 8005da4: 687b ldr r3, [r7, #4] + 8005da6: 0018 movs r0, r3 + 8005da8: f003 fb89 bl 80094be + 8005dac: 0003 movs r3, r0 + 8005dae: 7023 strb r3, [r4, #0] + if (err == ERR_OK) { + 8005db0: 197b adds r3, r7, r5 + 8005db2: 781b ldrb r3, [r3, #0] + 8005db4: b25b sxtb r3, r3 + 8005db6: 2b00 cmp r3, #0 + 8005db8: d12c bne.n 8005e14 + snmp_inc_tcpattemptfails(); + pcb->state = FIN_WAIT_1; + 8005dba: 687b ldr r3, [r7, #4] + 8005dbc: 2205 movs r2, #5 + 8005dbe: 761a strb r2, [r3, #24] + } + break; + 8005dc0: e028 b.n 8005e14 + case ESTABLISHED: + err = tcp_send_fin(pcb); + 8005dc2: 250f movs r5, #15 + 8005dc4: 197c adds r4, r7, r5 + 8005dc6: 687b ldr r3, [r7, #4] + 8005dc8: 0018 movs r0, r3 + 8005dca: f003 fb78 bl 80094be + 8005dce: 0003 movs r3, r0 + 8005dd0: 7023 strb r3, [r4, #0] + if (err == ERR_OK) { + 8005dd2: 197b adds r3, r7, r5 + 8005dd4: 781b ldrb r3, [r3, #0] + 8005dd6: b25b sxtb r3, r3 + 8005dd8: 2b00 cmp r3, #0 + 8005dda: d11d bne.n 8005e18 + snmp_inc_tcpestabresets(); + pcb->state = FIN_WAIT_1; + 8005ddc: 687b ldr r3, [r7, #4] + 8005dde: 2205 movs r2, #5 + 8005de0: 761a strb r2, [r3, #24] + } + break; + 8005de2: e019 b.n 8005e18 + case CLOSE_WAIT: + err = tcp_send_fin(pcb); + 8005de4: 250f movs r5, #15 + 8005de6: 197c adds r4, r7, r5 + 8005de8: 687b ldr r3, [r7, #4] + 8005dea: 0018 movs r0, r3 + 8005dec: f003 fb67 bl 80094be + 8005df0: 0003 movs r3, r0 + 8005df2: 7023 strb r3, [r4, #0] + if (err == ERR_OK) { + 8005df4: 197b adds r3, r7, r5 + 8005df6: 781b ldrb r3, [r3, #0] + 8005df8: b25b sxtb r3, r3 + 8005dfa: 2b00 cmp r3, #0 + 8005dfc: d10e bne.n 8005e1c + snmp_inc_tcpestabresets(); + pcb->state = LAST_ACK; + 8005dfe: 687b ldr r3, [r7, #4] + 8005e00: 2209 movs r2, #9 + 8005e02: 761a strb r2, [r3, #24] + } + break; + 8005e04: e00a b.n 8005e1c + default: + /* Has already been closed, do nothing. */ + err = ERR_OK; + 8005e06: 230f movs r3, #15 + 8005e08: 18fb adds r3, r7, r3 + 8005e0a: 2200 movs r2, #0 + 8005e0c: 701a strb r2, [r3, #0] + pcb = NULL; + 8005e0e: 2300 movs r3, #0 + 8005e10: 607b str r3, [r7, #4] + break; + 8005e12: e004 b.n 8005e1e + break; + 8005e14: 46c0 nop ; (mov r8, r8) + 8005e16: e002 b.n 8005e1e + break; + 8005e18: 46c0 nop ; (mov r8, r8) + 8005e1a: e000 b.n 8005e1e + break; + 8005e1c: 46c0 nop ; (mov r8, r8) + } + + if (pcb != NULL && err == ERR_OK) { + 8005e1e: 687b ldr r3, [r7, #4] + 8005e20: 2b00 cmp r3, #0 + 8005e22: d009 beq.n 8005e38 + 8005e24: 230f movs r3, #15 + 8005e26: 18fb adds r3, r7, r3 + 8005e28: 781b ldrb r3, [r3, #0] + 8005e2a: b25b sxtb r3, r3 + 8005e2c: 2b00 cmp r3, #0 + 8005e2e: d103 bne.n 8005e38 + returns (unsent data is sent from tcp timer functions, also), we don't care + for the return value of tcp_output for now. */ + /* @todo: When implementing SO_LINGER, this must be changed somehow: + If SOF_LINGER is set, the data should be sent and acked before close returns. + This can only be valid for sequential APIs, not for the raw API. */ + tcp_output(pcb); + 8005e30: 687b ldr r3, [r7, #4] + 8005e32: 0018 movs r0, r3 + 8005e34: f003 fdec bl 8009a10 + } + return err; + 8005e38: 230f movs r3, #15 + 8005e3a: 18fb adds r3, r7, r3 + 8005e3c: 781b ldrb r3, [r3, #0] + 8005e3e: b25b sxtb r3, r3 +} + 8005e40: 0018 movs r0, r3 + 8005e42: 46bd mov sp, r7 + 8005e44: b004 add sp, #16 + 8005e46: bdb0 pop {r4, r5, r7, pc} + 8005e48: 000016d0 .word 0x000016d0 + 8005e4c: 20003274 .word 0x20003274 + 8005e50: 20003280 .word 0x20003280 + 8005e54: 20003270 .word 0x20003270 + 8005e58: 20003288 .word 0x20003288 + 8005e5c: 0800fd78 .word 0x0800fd78 + 8005e60: 20003284 .word 0x20003284 + 8005e64: 2000327c .word 0x2000327c + +08005e68 : + * @return ERR_OK if connection has been closed + * another err_t if closing failed and pcb is not freed + */ +err_t +tcp_close(struct tcp_pcb *pcb) +{ + 8005e68: b580 push {r7, lr} + 8005e6a: b082 sub sp, #8 + 8005e6c: af00 add r7, sp, #0 + 8005e6e: 6078 str r0, [r7, #4] +#if TCP_DEBUG + LWIP_DEBUGF(TCP_DEBUG, ("tcp_close: closing in ")); + tcp_debug_print_state(pcb->state); +#endif /* TCP_DEBUG */ + + if (pcb->state != LISTEN) { + 8005e70: 687b ldr r3, [r7, #4] + 8005e72: 7e1b ldrb r3, [r3, #24] + 8005e74: 2b01 cmp r3, #1 + 8005e76: d006 beq.n 8005e86 + /* Set a flag not to receive any more data... */ + pcb->flags |= TF_RXCLOSED; + 8005e78: 687b ldr r3, [r7, #4] + 8005e7a: 7f9b ldrb r3, [r3, #30] + 8005e7c: 2210 movs r2, #16 + 8005e7e: 4313 orrs r3, r2 + 8005e80: b2da uxtb r2, r3 + 8005e82: 687b ldr r3, [r7, #4] + 8005e84: 779a strb r2, [r3, #30] + } + /* ... and close */ + return tcp_close_shutdown(pcb, 1); + 8005e86: 687b ldr r3, [r7, #4] + 8005e88: 2101 movs r1, #1 + 8005e8a: 0018 movs r0, r3 + 8005e8c: f7ff feaa bl 8005be4 + 8005e90: 0003 movs r3, r0 +} + 8005e92: 0018 movs r0, r3 + 8005e94: 46bd mov sp, r7 + 8005e96: b002 add sp, #8 + 8005e98: bd80 pop {r7, pc} + ... + +08005e9c : + * @param pcb the tcp_pcb to abort + * @param reset boolean to indicate whether a reset should be sent + */ +void +tcp_abandon(struct tcp_pcb *pcb, int reset) +{ + 8005e9c: b5b0 push {r4, r5, r7, lr} + 8005e9e: b088 sub sp, #32 + 8005ea0: af02 add r7, sp, #8 + 8005ea2: 6078 str r0, [r7, #4] + 8005ea4: 6039 str r1, [r7, #0] + LWIP_ASSERT("don't call tcp_abort/tcp_abandon for listen-pcbs", + pcb->state != LISTEN); + /* Figure out on which TCP PCB list we are, and remove us. If we + are in an active state, call the receive function associated with + the PCB with a NULL argument, and send an RST to the remote end. */ + if (pcb->state == TIME_WAIT) { + 8005ea6: 687b ldr r3, [r7, #4] + 8005ea8: 7e1b ldrb r3, [r3, #24] + 8005eaa: 2b0a cmp r3, #10 + 8005eac: d10b bne.n 8005ec6 + tcp_pcb_remove(&tcp_tw_pcbs, pcb); + 8005eae: 687a ldr r2, [r7, #4] + 8005eb0: 4b2f ldr r3, [pc, #188] ; (8005f70 ) + 8005eb2: 0011 movs r1, r2 + 8005eb4: 0018 movs r0, r3 + 8005eb6: f000 fdf9 bl 8006aac + memp_free(MEMP_TCP_PCB, pcb); + 8005eba: 687b ldr r3, [r7, #4] + 8005ebc: 0019 movs r1, r3 + 8005ebe: 2002 movs r0, #2 + 8005ec0: f7ff f82e bl 8004f20 + tcp_rst(seqno, ackno, &pcb->local_ip, &pcb->remote_ip, pcb->local_port, pcb->remote_port); + } + memp_free(MEMP_TCP_PCB, pcb); + TCP_EVENT_ERR(errf, errf_arg, ERR_ABRT); + } +} + 8005ec4: e050 b.n 8005f68 + seqno = pcb->snd_nxt; + 8005ec6: 687b ldr r3, [r7, #4] + 8005ec8: 6d1b ldr r3, [r3, #80] ; 0x50 + 8005eca: 617b str r3, [r7, #20] + ackno = pcb->rcv_nxt; + 8005ecc: 687b ldr r3, [r7, #4] + 8005ece: 6a9b ldr r3, [r3, #40] ; 0x28 + 8005ed0: 613b str r3, [r7, #16] + errf = pcb->errf; + 8005ed2: 687b ldr r3, [r7, #4] + 8005ed4: 228c movs r2, #140 ; 0x8c + 8005ed6: 589b ldr r3, [r3, r2] + 8005ed8: 60fb str r3, [r7, #12] + errf_arg = pcb->callback_arg; + 8005eda: 687b ldr r3, [r7, #4] + 8005edc: 691b ldr r3, [r3, #16] + 8005ede: 60bb str r3, [r7, #8] + TCP_PCB_REMOVE_ACTIVE(pcb); + 8005ee0: 687a ldr r2, [r7, #4] + 8005ee2: 4b24 ldr r3, [pc, #144] ; (8005f74 ) + 8005ee4: 0011 movs r1, r2 + 8005ee6: 0018 movs r0, r3 + 8005ee8: f000 fde0 bl 8006aac + 8005eec: 4b22 ldr r3, [pc, #136] ; (8005f78 ) + 8005eee: 2201 movs r2, #1 + 8005ef0: 701a strb r2, [r3, #0] + if (pcb->unacked != NULL) { + 8005ef2: 687b ldr r3, [r7, #4] + 8005ef4: 6f1b ldr r3, [r3, #112] ; 0x70 + 8005ef6: 2b00 cmp r3, #0 + 8005ef8: d004 beq.n 8005f04 + tcp_segs_free(pcb->unacked); + 8005efa: 687b ldr r3, [r7, #4] + 8005efc: 6f1b ldr r3, [r3, #112] ; 0x70 + 8005efe: 0018 movs r0, r3 + 8005f00: f000 fbf8 bl 80066f4 + if (pcb->unsent != NULL) { + 8005f04: 687b ldr r3, [r7, #4] + 8005f06: 6edb ldr r3, [r3, #108] ; 0x6c + 8005f08: 2b00 cmp r3, #0 + 8005f0a: d004 beq.n 8005f16 + tcp_segs_free(pcb->unsent); + 8005f0c: 687b ldr r3, [r7, #4] + 8005f0e: 6edb ldr r3, [r3, #108] ; 0x6c + 8005f10: 0018 movs r0, r3 + 8005f12: f000 fbef bl 80066f4 + if (pcb->ooseq != NULL) { + 8005f16: 687b ldr r3, [r7, #4] + 8005f18: 6f5b ldr r3, [r3, #116] ; 0x74 + 8005f1a: 2b00 cmp r3, #0 + 8005f1c: d004 beq.n 8005f28 + tcp_segs_free(pcb->ooseq); + 8005f1e: 687b ldr r3, [r7, #4] + 8005f20: 6f5b ldr r3, [r3, #116] ; 0x74 + 8005f22: 0018 movs r0, r3 + 8005f24: f000 fbe6 bl 80066f4 + if (reset) { + 8005f28: 683b ldr r3, [r7, #0] + 8005f2a: 2b00 cmp r3, #0 + 8005f2c: d00e beq.n 8005f4c + tcp_rst(seqno, ackno, &pcb->local_ip, &pcb->remote_ip, pcb->local_port, pcb->remote_port); + 8005f2e: 687c ldr r4, [r7, #4] + 8005f30: 687b ldr r3, [r7, #4] + 8005f32: 1d1d adds r5, r3, #4 + 8005f34: 687b ldr r3, [r7, #4] + 8005f36: 8b5b ldrh r3, [r3, #26] + 8005f38: 687a ldr r2, [r7, #4] + 8005f3a: 8b92 ldrh r2, [r2, #28] + 8005f3c: 6939 ldr r1, [r7, #16] + 8005f3e: 6978 ldr r0, [r7, #20] + 8005f40: 9201 str r2, [sp, #4] + 8005f42: 9300 str r3, [sp, #0] + 8005f44: 002b movs r3, r5 + 8005f46: 0022 movs r2, r4 + 8005f48: f004 f840 bl 8009fcc + memp_free(MEMP_TCP_PCB, pcb); + 8005f4c: 687b ldr r3, [r7, #4] + 8005f4e: 0019 movs r1, r3 + 8005f50: 2002 movs r0, #2 + 8005f52: f7fe ffe5 bl 8004f20 + TCP_EVENT_ERR(errf, errf_arg, ERR_ABRT); + 8005f56: 68fb ldr r3, [r7, #12] + 8005f58: 2b00 cmp r3, #0 + 8005f5a: d005 beq.n 8005f68 + 8005f5c: 230a movs r3, #10 + 8005f5e: 4259 negs r1, r3 + 8005f60: 68ba ldr r2, [r7, #8] + 8005f62: 68fb ldr r3, [r7, #12] + 8005f64: 0010 movs r0, r2 + 8005f66: 4798 blx r3 +} + 8005f68: 46c0 nop ; (mov r8, r8) + 8005f6a: 46bd mov sp, r7 + 8005f6c: b006 add sp, #24 + 8005f6e: bdb0 pop {r4, r5, r7, pc} + 8005f70: 20003288 .word 0x20003288 + 8005f74: 20003274 .word 0x20003274 + 8005f78: 20003270 .word 0x20003270 + +08005f7c : + * + * @param pcb the tcp pcb to abort + */ +void +tcp_abort(struct tcp_pcb *pcb) +{ + 8005f7c: b580 push {r7, lr} + 8005f7e: b082 sub sp, #8 + 8005f80: af00 add r7, sp, #0 + 8005f82: 6078 str r0, [r7, #4] + tcp_abandon(pcb, 1); + 8005f84: 687b ldr r3, [r7, #4] + 8005f86: 2101 movs r1, #1 + 8005f88: 0018 movs r0, r3 + 8005f8a: f7ff ff87 bl 8005e9c +} + 8005f8e: 46c0 nop ; (mov r8, r8) + 8005f90: 46bd mov sp, r7 + 8005f92: b002 add sp, #8 + 8005f94: bd80 pop {r7, pc} + ... + +08005f98 : + * + * Returns how much extra window would be advertised if we sent an + * update now. + */ +u32_t tcp_update_rcv_ann_wnd(struct tcp_pcb *pcb) +{ + 8005f98: b580 push {r7, lr} + 8005f9a: b084 sub sp, #16 + 8005f9c: af00 add r7, sp, #0 + 8005f9e: 6078 str r0, [r7, #4] + u32_t new_right_edge = pcb->rcv_nxt + pcb->rcv_wnd; + 8005fa0: 687b ldr r3, [r7, #4] + 8005fa2: 6a9b ldr r3, [r3, #40] ; 0x28 + 8005fa4: 687a ldr r2, [r7, #4] + 8005fa6: 8d92 ldrh r2, [r2, #44] ; 0x2c + 8005fa8: 189b adds r3, r3, r2 + 8005faa: 60fb str r3, [r7, #12] + + if (TCP_SEQ_GEQ(new_right_edge, pcb->rcv_ann_right_edge + LWIP_MIN((TCP_WND / 2), pcb->mss))) { + 8005fac: 687b ldr r3, [r7, #4] + 8005fae: 6b1b ldr r3, [r3, #48] ; 0x30 + 8005fb0: 687a ldr r2, [r7, #4] + 8005fb2: 8ed2 ldrh r2, [r2, #54] ; 0x36 + 8005fb4: 1c10 adds r0, r2, #0 + 8005fb6: b282 uxth r2, r0 + 8005fb8: 4916 ldr r1, [pc, #88] ; (8006014 ) + 8005fba: 428a cmp r2, r1 + 8005fbc: d901 bls.n 8005fc2 + 8005fbe: 4a15 ldr r2, [pc, #84] ; (8006014 ) + 8005fc0: 1c10 adds r0, r2, #0 + 8005fc2: b282 uxth r2, r0 + 8005fc4: 189b adds r3, r3, r2 + 8005fc6: 68fa ldr r2, [r7, #12] + 8005fc8: 1ad3 subs r3, r2, r3 + 8005fca: d408 bmi.n 8005fde + /* we can advertise more window */ + pcb->rcv_ann_wnd = pcb->rcv_wnd; + 8005fcc: 687b ldr r3, [r7, #4] + 8005fce: 8d9a ldrh r2, [r3, #44] ; 0x2c + 8005fd0: 687b ldr r3, [r7, #4] + 8005fd2: 85da strh r2, [r3, #46] ; 0x2e + return new_right_edge - pcb->rcv_ann_right_edge; + 8005fd4: 687b ldr r3, [r7, #4] + 8005fd6: 6b1b ldr r3, [r3, #48] ; 0x30 + 8005fd8: 68fa ldr r2, [r7, #12] + 8005fda: 1ad3 subs r3, r2, r3 + 8005fdc: e015 b.n 800600a + } else { + if (TCP_SEQ_GT(pcb->rcv_nxt, pcb->rcv_ann_right_edge)) { + 8005fde: 687b ldr r3, [r7, #4] + 8005fe0: 6a9a ldr r2, [r3, #40] ; 0x28 + 8005fe2: 687b ldr r3, [r7, #4] + 8005fe4: 6b1b ldr r3, [r3, #48] ; 0x30 + 8005fe6: 1ad3 subs r3, r2, r3 + 8005fe8: 2b00 cmp r3, #0 + 8005fea: dd03 ble.n 8005ff4 + /* Can happen due to other end sending out of advertised window, + * but within actual available (but not yet advertised) window */ + pcb->rcv_ann_wnd = 0; + 8005fec: 687b ldr r3, [r7, #4] + 8005fee: 2200 movs r2, #0 + 8005ff0: 85da strh r2, [r3, #46] ; 0x2e + 8005ff2: e009 b.n 8006008 + } else { + /* keep the right edge of window constant */ + u32_t new_rcv_ann_wnd = pcb->rcv_ann_right_edge - pcb->rcv_nxt; + 8005ff4: 687b ldr r3, [r7, #4] + 8005ff6: 6b1a ldr r2, [r3, #48] ; 0x30 + 8005ff8: 687b ldr r3, [r7, #4] + 8005ffa: 6a9b ldr r3, [r3, #40] ; 0x28 + 8005ffc: 1ad3 subs r3, r2, r3 + 8005ffe: 60bb str r3, [r7, #8] + LWIP_ASSERT("new_rcv_ann_wnd <= 0xffff", new_rcv_ann_wnd <= 0xffff); + pcb->rcv_ann_wnd = (u16_t)new_rcv_ann_wnd; + 8006000: 68bb ldr r3, [r7, #8] + 8006002: b29a uxth r2, r3 + 8006004: 687b ldr r3, [r7, #4] + 8006006: 85da strh r2, [r3, #46] ; 0x2e + } + return 0; + 8006008: 2300 movs r3, #0 + } +} + 800600a: 0018 movs r0, r3 + 800600c: 46bd mov sp, r7 + 800600e: b004 add sp, #16 + 8006010: bd80 pop {r7, pc} + 8006012: 46c0 nop ; (mov r8, r8) + 8006014: 00000b68 .word 0x00000b68 + +08006018 : + * @param pcb the tcp_pcb for which data is read + * @param len the amount of bytes that have been read by the application + */ +void +tcp_recved(struct tcp_pcb *pcb, u16_t len) +{ + 8006018: b580 push {r7, lr} + 800601a: b084 sub sp, #16 + 800601c: af00 add r7, sp, #0 + 800601e: 6078 str r0, [r7, #4] + 8006020: 000a movs r2, r1 + 8006022: 1cbb adds r3, r7, #2 + 8006024: 801a strh r2, [r3, #0] + LWIP_ASSERT("don't call tcp_recved for listen-pcbs", + pcb->state != LISTEN); + LWIP_ASSERT("tcp_recved: len would wrap rcv_wnd\n", + len <= 0xffff - pcb->rcv_wnd ); + + pcb->rcv_wnd += len; + 8006026: 687b ldr r3, [r7, #4] + 8006028: 8d9a ldrh r2, [r3, #44] ; 0x2c + 800602a: 1cbb adds r3, r7, #2 + 800602c: 881b ldrh r3, [r3, #0] + 800602e: 18d3 adds r3, r2, r3 + 8006030: b29a uxth r2, r3 + 8006032: 687b ldr r3, [r7, #4] + 8006034: 859a strh r2, [r3, #44] ; 0x2c + if (pcb->rcv_wnd > TCP_WND) { + 8006036: 687b ldr r3, [r7, #4] + 8006038: 8d9b ldrh r3, [r3, #44] ; 0x2c + 800603a: 4a0f ldr r2, [pc, #60] ; (8006078 ) + 800603c: 4293 cmp r3, r2 + 800603e: d902 bls.n 8006046 + pcb->rcv_wnd = TCP_WND; + 8006040: 687b ldr r3, [r7, #4] + 8006042: 4a0d ldr r2, [pc, #52] ; (8006078 ) + 8006044: 859a strh r2, [r3, #44] ; 0x2c + } + + wnd_inflation = tcp_update_rcv_ann_wnd(pcb); + 8006046: 687b ldr r3, [r7, #4] + 8006048: 0018 movs r0, r3 + 800604a: f7ff ffa5 bl 8005f98 + 800604e: 0003 movs r3, r0 + 8006050: 60fb str r3, [r7, #12] + + /* If the change in the right edge of window is significant (default + * watermark is TCP_WND/4), then send an explicit update now. + * Otherwise wait for a packet to be sent in the normal course of + * events (or more window to be available later) */ + if (wnd_inflation >= TCP_WND_UPDATE_THRESHOLD) { + 8006052: 68fb ldr r3, [r7, #12] + 8006054: 4a09 ldr r2, [pc, #36] ; (800607c ) + 8006056: 4293 cmp r3, r2 + 8006058: dd0a ble.n 8006070 + tcp_ack_now(pcb); + 800605a: 687b ldr r3, [r7, #4] + 800605c: 7f9b ldrb r3, [r3, #30] + 800605e: 2202 movs r2, #2 + 8006060: 4313 orrs r3, r2 + 8006062: b2da uxtb r2, r3 + 8006064: 687b ldr r3, [r7, #4] + 8006066: 779a strb r2, [r3, #30] + tcp_output(pcb); + 8006068: 687b ldr r3, [r7, #4] + 800606a: 0018 movs r0, r3 + 800606c: f003 fcd0 bl 8009a10 + } + + LWIP_DEBUGF(TCP_DEBUG, ("tcp_recved: recveived %"U16_F" bytes, wnd %"U16_F" (%"U16_F").\n", + len, pcb->rcv_wnd, TCP_WND - pcb->rcv_wnd)); +} + 8006070: 46c0 nop ; (mov r8, r8) + 8006072: 46bd mov sp, r7 + 8006074: b004 add sp, #16 + 8006076: bd80 pop {r7, pc} + 8006078: 000016d0 .word 0x000016d0 + 800607c: 000005b3 .word 0x000005b3 + +08006080 : + * + * Automatically called from tcp_tmr(). + */ +void +tcp_slowtmr(void) +{ + 8006080: b5b0 push {r4, r5, r7, lr} + 8006082: b08a sub sp, #40 ; 0x28 + 8006084: af02 add r7, sp, #8 + u16_t eff_wnd; + u8_t pcb_remove; /* flag if a PCB should be removed */ + u8_t pcb_reset; /* flag if a RST should be sent when removing */ + err_t err; + + err = ERR_OK; + 8006086: 2315 movs r3, #21 + 8006088: 18fb adds r3, r7, r3 + 800608a: 2200 movs r2, #0 + 800608c: 701a strb r2, [r3, #0] + + ++tcp_ticks; + 800608e: 4bc8 ldr r3, [pc, #800] ; (80063b0 ) + 8006090: 681b ldr r3, [r3, #0] + 8006092: 1c5a adds r2, r3, #1 + 8006094: 4bc6 ldr r3, [pc, #792] ; (80063b0 ) + 8006096: 601a str r2, [r3, #0] + ++tcp_timer_ctr; + 8006098: 4bc6 ldr r3, [pc, #792] ; (80063b4 ) + 800609a: 781b ldrb r3, [r3, #0] + 800609c: 3301 adds r3, #1 + 800609e: b2da uxtb r2, r3 + 80060a0: 4bc4 ldr r3, [pc, #784] ; (80063b4 ) + 80060a2: 701a strb r2, [r3, #0] + +tcp_slowtmr_start: + /* Steps through all of the active PCBs. */ + prev = NULL; + 80060a4: 2300 movs r3, #0 + 80060a6: 61bb str r3, [r7, #24] + pcb = tcp_active_pcbs; + 80060a8: 4bc3 ldr r3, [pc, #780] ; (80063b8 ) + 80060aa: 681b ldr r3, [r3, #0] + 80060ac: 61fb str r3, [r7, #28] + if (pcb == NULL) { + LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: no active pcbs\n")); + } + while (pcb != NULL) { + 80060ae: e206 b.n 80064be + LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: processing active pcb\n")); + LWIP_ASSERT("tcp_slowtmr: active pcb->state != CLOSED\n", pcb->state != CLOSED); + LWIP_ASSERT("tcp_slowtmr: active pcb->state != LISTEN\n", pcb->state != LISTEN); + LWIP_ASSERT("tcp_slowtmr: active pcb->state != TIME-WAIT\n", pcb->state != TIME_WAIT); + if (pcb->last_timer == tcp_timer_ctr) { + 80060b0: 69fb ldr r3, [r7, #28] + 80060b2: 2221 movs r2, #33 ; 0x21 + 80060b4: 5c9a ldrb r2, [r3, r2] + 80060b6: 4bbf ldr r3, [pc, #764] ; (80063b4 ) + 80060b8: 781b ldrb r3, [r3, #0] + 80060ba: 429a cmp r2, r3 + 80060bc: d103 bne.n 80060c6 + /* skip this pcb, we have already processed it */ + pcb = pcb->next; + 80060be: 69fb ldr r3, [r7, #28] + 80060c0: 68db ldr r3, [r3, #12] + 80060c2: 61fb str r3, [r7, #28] + continue; + 80060c4: e1fb b.n 80064be + } + pcb->last_timer = tcp_timer_ctr; + 80060c6: 4bbb ldr r3, [pc, #748] ; (80063b4 ) + 80060c8: 7819 ldrb r1, [r3, #0] + 80060ca: 69fb ldr r3, [r7, #28] + 80060cc: 2221 movs r2, #33 ; 0x21 + 80060ce: 5499 strb r1, [r3, r2] + + pcb_remove = 0; + 80060d0: 2317 movs r3, #23 + 80060d2: 18fb adds r3, r7, r3 + 80060d4: 2200 movs r2, #0 + 80060d6: 701a strb r2, [r3, #0] + pcb_reset = 0; + 80060d8: 2316 movs r3, #22 + 80060da: 18fb adds r3, r7, r3 + 80060dc: 2200 movs r2, #0 + 80060de: 701a strb r2, [r3, #0] + + if (pcb->state == SYN_SENT && pcb->nrtx == TCP_SYNMAXRTX) { + 80060e0: 69fb ldr r3, [r7, #28] + 80060e2: 7e1b ldrb r3, [r3, #24] + 80060e4: 2b02 cmp r3, #2 + 80060e6: d10b bne.n 8006100 + 80060e8: 69fb ldr r3, [r7, #28] + 80060ea: 2246 movs r2, #70 ; 0x46 + 80060ec: 5c9b ldrb r3, [r3, r2] + 80060ee: 2b06 cmp r3, #6 + 80060f0: d106 bne.n 8006100 + ++pcb_remove; + 80060f2: 2217 movs r2, #23 + 80060f4: 18bb adds r3, r7, r2 + 80060f6: 18ba adds r2, r7, r2 + 80060f8: 7812 ldrb r2, [r2, #0] + 80060fa: 3201 adds r2, #1 + 80060fc: 701a strb r2, [r3, #0] + 80060fe: e0a1 b.n 8006244 + LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: max SYN retries reached\n")); + } + else if (pcb->nrtx == TCP_MAXRTX) { + 8006100: 69fb ldr r3, [r7, #28] + 8006102: 2246 movs r2, #70 ; 0x46 + 8006104: 5c9b ldrb r3, [r3, r2] + 8006106: 2b0c cmp r3, #12 + 8006108: d106 bne.n 8006118 + ++pcb_remove; + 800610a: 2217 movs r2, #23 + 800610c: 18bb adds r3, r7, r2 + 800610e: 18ba adds r2, r7, r2 + 8006110: 7812 ldrb r2, [r2, #0] + 8006112: 3201 adds r2, #1 + 8006114: 701a strb r2, [r3, #0] + 8006116: e095 b.n 8006244 + LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: max DATA retries reached\n")); + } else { + if (pcb->persist_backoff > 0) { + 8006118: 69fb ldr r3, [r7, #28] + 800611a: 2295 movs r2, #149 ; 0x95 + 800611c: 5c9b ldrb r3, [r3, r2] + 800611e: 2b00 cmp r3, #0 + 8006120: d029 beq.n 8006176 + /* If snd_wnd is zero, use persist timer to send 1 byte probes + * instead of using the standard retransmission mechanism. */ + pcb->persist_cnt++; + 8006122: 69fb ldr r3, [r7, #28] + 8006124: 2294 movs r2, #148 ; 0x94 + 8006126: 5c9b ldrb r3, [r3, r2] + 8006128: 3301 adds r3, #1 + 800612a: b2d9 uxtb r1, r3 + 800612c: 69fb ldr r3, [r7, #28] + 800612e: 2294 movs r2, #148 ; 0x94 + 8006130: 5499 strb r1, [r3, r2] + if (pcb->persist_cnt >= tcp_persist_backoff[pcb->persist_backoff-1]) { + 8006132: 69fb ldr r3, [r7, #28] + 8006134: 2294 movs r2, #148 ; 0x94 + 8006136: 5c9a ldrb r2, [r3, r2] + 8006138: 69fb ldr r3, [r7, #28] + 800613a: 2195 movs r1, #149 ; 0x95 + 800613c: 5c5b ldrb r3, [r3, r1] + 800613e: 3b01 subs r3, #1 + 8006140: 499e ldr r1, [pc, #632] ; (80063bc ) + 8006142: 5ccb ldrb r3, [r1, r3] + 8006144: 429a cmp r2, r3 + 8006146: d200 bcs.n 800614a + 8006148: e07c b.n 8006244 + pcb->persist_cnt = 0; + 800614a: 69fb ldr r3, [r7, #28] + 800614c: 2294 movs r2, #148 ; 0x94 + 800614e: 2100 movs r1, #0 + 8006150: 5499 strb r1, [r3, r2] + if (pcb->persist_backoff < sizeof(tcp_persist_backoff)) { + 8006152: 69fb ldr r3, [r7, #28] + 8006154: 2295 movs r2, #149 ; 0x95 + 8006156: 5c9b ldrb r3, [r3, r2] + 8006158: 2b06 cmp r3, #6 + 800615a: d807 bhi.n 800616c + pcb->persist_backoff++; + 800615c: 69fb ldr r3, [r7, #28] + 800615e: 2295 movs r2, #149 ; 0x95 + 8006160: 5c9b ldrb r3, [r3, r2] + 8006162: 3301 adds r3, #1 + 8006164: b2d9 uxtb r1, r3 + 8006166: 69fb ldr r3, [r7, #28] + 8006168: 2295 movs r2, #149 ; 0x95 + 800616a: 5499 strb r1, [r3, r2] + } + tcp_zero_window_probe(pcb); + 800616c: 69fb ldr r3, [r7, #28] + 800616e: 0018 movs r0, r3 + 8006170: f004 f98c bl 800a48c + 8006174: e066 b.n 8006244 + } + } else { + /* Increase the retransmission timer if it is running */ + if(pcb->rtime >= 0) { + 8006176: 69fb ldr r3, [r7, #28] + 8006178: 2234 movs r2, #52 ; 0x34 + 800617a: 5e9b ldrsh r3, [r3, r2] + 800617c: 2b00 cmp r3, #0 + 800617e: db08 blt.n 8006192 + ++pcb->rtime; + 8006180: 69fb ldr r3, [r7, #28] + 8006182: 2234 movs r2, #52 ; 0x34 + 8006184: 5e9b ldrsh r3, [r3, r2] + 8006186: b29b uxth r3, r3 + 8006188: 3301 adds r3, #1 + 800618a: b29b uxth r3, r3 + 800618c: b21a sxth r2, r3 + 800618e: 69fb ldr r3, [r7, #28] + 8006190: 869a strh r2, [r3, #52] ; 0x34 + } + + if (pcb->unacked != NULL && pcb->rtime >= pcb->rto) { + 8006192: 69fb ldr r3, [r7, #28] + 8006194: 6f1b ldr r3, [r3, #112] ; 0x70 + 8006196: 2b00 cmp r3, #0 + 8006198: d054 beq.n 8006244 + 800619a: 69fb ldr r3, [r7, #28] + 800619c: 2234 movs r2, #52 ; 0x34 + 800619e: 5e9a ldrsh r2, [r3, r2] + 80061a0: 69fb ldr r3, [r7, #28] + 80061a2: 2144 movs r1, #68 ; 0x44 + 80061a4: 5e5b ldrsh r3, [r3, r1] + 80061a6: 429a cmp r2, r3 + 80061a8: db4c blt.n 8006244 + " pcb->rto %"S16_F"\n", + pcb->rtime, pcb->rto)); + + /* Double retransmission time-out unless we are trying to + * connect to somebody (i.e., we are in SYN_SENT). */ + if (pcb->state != SYN_SENT) { + 80061aa: 69fb ldr r3, [r7, #28] + 80061ac: 7e1b ldrb r3, [r3, #24] + 80061ae: 2b02 cmp r3, #2 + 80061b0: d014 beq.n 80061dc + pcb->rto = ((pcb->sa >> 3) + pcb->sv) << tcp_backoff[pcb->nrtx]; + 80061b2: 69fb ldr r3, [r7, #28] + 80061b4: 2240 movs r2, #64 ; 0x40 + 80061b6: 5e9b ldrsh r3, [r3, r2] + 80061b8: 10db asrs r3, r3, #3 + 80061ba: b21b sxth r3, r3 + 80061bc: 0019 movs r1, r3 + 80061be: 69fb ldr r3, [r7, #28] + 80061c0: 2242 movs r2, #66 ; 0x42 + 80061c2: 5e9b ldrsh r3, [r3, r2] + 80061c4: 18cb adds r3, r1, r3 + 80061c6: 69fa ldr r2, [r7, #28] + 80061c8: 2146 movs r1, #70 ; 0x46 + 80061ca: 5c52 ldrb r2, [r2, r1] + 80061cc: 0011 movs r1, r2 + 80061ce: 4a7c ldr r2, [pc, #496] ; (80063c0 ) + 80061d0: 5c52 ldrb r2, [r2, r1] + 80061d2: 4093 lsls r3, r2 + 80061d4: b219 sxth r1, r3 + 80061d6: 69fb ldr r3, [r7, #28] + 80061d8: 2244 movs r2, #68 ; 0x44 + 80061da: 5299 strh r1, [r3, r2] + } + + /* Reset the retransmission timer. */ + pcb->rtime = 0; + 80061dc: 69fb ldr r3, [r7, #28] + 80061de: 2200 movs r2, #0 + 80061e0: 869a strh r2, [r3, #52] ; 0x34 + + /* Reduce congestion window and ssthresh. */ + eff_wnd = LWIP_MIN(pcb->cwnd, pcb->snd_wnd); + 80061e2: 69fb ldr r3, [r7, #28] + 80061e4: 2260 movs r2, #96 ; 0x60 + 80061e6: 5a99 ldrh r1, [r3, r2] + 80061e8: 69fb ldr r3, [r7, #28] + 80061ea: 224c movs r2, #76 ; 0x4c + 80061ec: 5a9b ldrh r3, [r3, r2] + 80061ee: 220e movs r2, #14 + 80061f0: 18ba adds r2, r7, r2 + 80061f2: 1c1c adds r4, r3, #0 + 80061f4: 1c0b adds r3, r1, #0 + 80061f6: b298 uxth r0, r3 + 80061f8: b2a1 uxth r1, r4 + 80061fa: 4288 cmp r0, r1 + 80061fc: d900 bls.n 8006200 + 80061fe: 1c23 adds r3, r4, #0 + 8006200: 8013 strh r3, [r2, #0] + pcb->ssthresh = eff_wnd >> 1; + 8006202: 230e movs r3, #14 + 8006204: 18fb adds r3, r7, r3 + 8006206: 881b ldrh r3, [r3, #0] + 8006208: 085b lsrs r3, r3, #1 + 800620a: b299 uxth r1, r3 + 800620c: 69fb ldr r3, [r7, #28] + 800620e: 224e movs r2, #78 ; 0x4e + 8006210: 5299 strh r1, [r3, r2] + if (pcb->ssthresh < (pcb->mss << 1)) { + 8006212: 69fb ldr r3, [r7, #28] + 8006214: 224e movs r2, #78 ; 0x4e + 8006216: 5a9b ldrh r3, [r3, r2] + 8006218: 001a movs r2, r3 + 800621a: 69fb ldr r3, [r7, #28] + 800621c: 8edb ldrh r3, [r3, #54] ; 0x36 + 800621e: 005b lsls r3, r3, #1 + 8006220: 429a cmp r2, r3 + 8006222: da06 bge.n 8006232 + pcb->ssthresh = (pcb->mss << 1); + 8006224: 69fb ldr r3, [r7, #28] + 8006226: 8edb ldrh r3, [r3, #54] ; 0x36 + 8006228: 18db adds r3, r3, r3 + 800622a: b299 uxth r1, r3 + 800622c: 69fb ldr r3, [r7, #28] + 800622e: 224e movs r2, #78 ; 0x4e + 8006230: 5299 strh r1, [r3, r2] + } + pcb->cwnd = pcb->mss; + 8006232: 69fb ldr r3, [r7, #28] + 8006234: 8ed9 ldrh r1, [r3, #54] ; 0x36 + 8006236: 69fb ldr r3, [r7, #28] + 8006238: 224c movs r2, #76 ; 0x4c + 800623a: 5299 strh r1, [r3, r2] + " ssthresh %"U16_F"\n", + pcb->cwnd, pcb->ssthresh)); + + /* The following needs to be called AFTER cwnd is set to one + mss - STJ */ + tcp_rexmit_rto(pcb); + 800623c: 69fb ldr r3, [r7, #28] + 800623e: 0018 movs r0, r3 + 8006240: f003 ffe8 bl 800a214 + } + } + } + /* Check if this PCB has stayed too long in FIN-WAIT-2 */ + if (pcb->state == FIN_WAIT_2) { + 8006244: 69fb ldr r3, [r7, #28] + 8006246: 7e1b ldrb r3, [r3, #24] + 8006248: 2b06 cmp r3, #6 + 800624a: d112 bne.n 8006272 + /* If this PCB is in FIN_WAIT_2 because of SHUT_WR don't let it time out. */ + if (pcb->flags & TF_RXCLOSED) { + 800624c: 69fb ldr r3, [r7, #28] + 800624e: 7f9b ldrb r3, [r3, #30] + 8006250: 001a movs r2, r3 + 8006252: 2310 movs r3, #16 + 8006254: 4013 ands r3, r2 + 8006256: d00c beq.n 8006272 + /* PCB was fully closed (either through close() or SHUT_RDWR): + normal FIN-WAIT timeout handling. */ + if ((u32_t)(tcp_ticks - pcb->tmr) > + 8006258: 4b55 ldr r3, [pc, #340] ; (80063b0 ) + 800625a: 681a ldr r2, [r3, #0] + 800625c: 69fb ldr r3, [r7, #28] + 800625e: 6a5b ldr r3, [r3, #36] ; 0x24 + 8006260: 1ad3 subs r3, r2, r3 + 8006262: 2b28 cmp r3, #40 ; 0x28 + 8006264: d905 bls.n 8006272 + TCP_FIN_WAIT_TIMEOUT / TCP_SLOW_INTERVAL) { + ++pcb_remove; + 8006266: 2217 movs r2, #23 + 8006268: 18bb adds r3, r7, r2 + 800626a: 18ba adds r2, r7, r2 + 800626c: 7812 ldrb r2, [r2, #0] + 800626e: 3201 adds r2, #1 + 8006270: 701a strb r2, [r3, #0] + } + } + } + + /* Check if KEEPALIVE should be sent */ + if(ip_get_option(pcb, SOF_KEEPALIVE) && + 8006272: 69fb ldr r3, [r7, #28] + 8006274: 7a1b ldrb r3, [r3, #8] + 8006276: 001a movs r2, r3 + 8006278: 2308 movs r3, #8 + 800627a: 4013 ands r3, r2 + 800627c: d049 beq.n 8006312 + ((pcb->state == ESTABLISHED) || + 800627e: 69fb ldr r3, [r7, #28] + 8006280: 7e1b ldrb r3, [r3, #24] + if(ip_get_option(pcb, SOF_KEEPALIVE) && + 8006282: 2b04 cmp r3, #4 + 8006284: d003 beq.n 800628e + (pcb->state == CLOSE_WAIT))) { + 8006286: 69fb ldr r3, [r7, #28] + 8006288: 7e1b ldrb r3, [r3, #24] + ((pcb->state == ESTABLISHED) || + 800628a: 2b07 cmp r3, #7 + 800628c: d141 bne.n 8006312 + if((u32_t)(tcp_ticks - pcb->tmr) > + 800628e: 4b48 ldr r3, [pc, #288] ; (80063b0 ) + 8006290: 681a ldr r2, [r3, #0] + 8006292: 69fb ldr r3, [r7, #28] + 8006294: 6a5b ldr r3, [r3, #36] ; 0x24 + 8006296: 1ad4 subs r4, r2, r3 + (pcb->keep_idle + TCP_KEEP_DUR(pcb)) / TCP_SLOW_INTERVAL) + 8006298: 69fb ldr r3, [r7, #28] + 800629a: 2290 movs r2, #144 ; 0x90 + 800629c: 589b ldr r3, [r3, r2] + 800629e: 4a49 ldr r2, [pc, #292] ; (80063c4 ) + 80062a0: 189a adds r2, r3, r2 + 80062a2: 23fa movs r3, #250 ; 0xfa + 80062a4: 0059 lsls r1, r3, #1 + 80062a6: 0010 movs r0, r2 + 80062a8: f7f9 ff40 bl 800012c <__udivsi3> + 80062ac: 0003 movs r3, r0 + if((u32_t)(tcp_ticks - pcb->tmr) > + 80062ae: 429c cmp r4, r3 + 80062b0: d90c bls.n 80062cc + { + LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: KEEPALIVE timeout. Aborting connection to %"U16_F".%"U16_F".%"U16_F".%"U16_F".\n", + ip4_addr1_16(&pcb->remote_ip), ip4_addr2_16(&pcb->remote_ip), + ip4_addr3_16(&pcb->remote_ip), ip4_addr4_16(&pcb->remote_ip))); + + ++pcb_remove; + 80062b2: 2217 movs r2, #23 + 80062b4: 18bb adds r3, r7, r2 + 80062b6: 18ba adds r2, r7, r2 + 80062b8: 7812 ldrb r2, [r2, #0] + 80062ba: 3201 adds r2, #1 + 80062bc: 701a strb r2, [r3, #0] + ++pcb_reset; + 80062be: 2216 movs r2, #22 + 80062c0: 18bb adds r3, r7, r2 + 80062c2: 18ba adds r2, r7, r2 + 80062c4: 7812 ldrb r2, [r2, #0] + 80062c6: 3201 adds r2, #1 + 80062c8: 701a strb r2, [r3, #0] + 80062ca: e022 b.n 8006312 + } + else if((u32_t)(tcp_ticks - pcb->tmr) > + 80062cc: 4b38 ldr r3, [pc, #224] ; (80063b0 ) + 80062ce: 681a ldr r2, [r3, #0] + 80062d0: 69fb ldr r3, [r7, #28] + 80062d2: 6a5b ldr r3, [r3, #36] ; 0x24 + 80062d4: 1ad4 subs r4, r2, r3 + (pcb->keep_idle + pcb->keep_cnt_sent * TCP_KEEP_INTVL(pcb)) + 80062d6: 69fb ldr r3, [r7, #28] + 80062d8: 2290 movs r2, #144 ; 0x90 + 80062da: 589a ldr r2, [r3, r2] + 80062dc: 69fb ldr r3, [r7, #28] + 80062de: 2196 movs r1, #150 ; 0x96 + 80062e0: 5c5b ldrb r3, [r3, r1] + 80062e2: 0019 movs r1, r3 + 80062e4: 4b38 ldr r3, [pc, #224] ; (80063c8 ) + 80062e6: 434b muls r3, r1 + 80062e8: 18d2 adds r2, r2, r3 + / TCP_SLOW_INTERVAL) + 80062ea: 23fa movs r3, #250 ; 0xfa + 80062ec: 0059 lsls r1, r3, #1 + 80062ee: 0010 movs r0, r2 + 80062f0: f7f9 ff1c bl 800012c <__udivsi3> + 80062f4: 0003 movs r3, r0 + else if((u32_t)(tcp_ticks - pcb->tmr) > + 80062f6: 429c cmp r4, r3 + 80062f8: d90b bls.n 8006312 + { + tcp_keepalive(pcb); + 80062fa: 69fb ldr r3, [r7, #28] + 80062fc: 0018 movs r0, r3 + 80062fe: f004 f86d bl 800a3dc + pcb->keep_cnt_sent++; + 8006302: 69fb ldr r3, [r7, #28] + 8006304: 2296 movs r2, #150 ; 0x96 + 8006306: 5c9b ldrb r3, [r3, r2] + 8006308: 3301 adds r3, #1 + 800630a: b2d9 uxtb r1, r3 + 800630c: 69fb ldr r3, [r7, #28] + 800630e: 2296 movs r2, #150 ; 0x96 + 8006310: 5499 strb r1, [r3, r2] + + /* If this PCB has queued out of sequence data, but has been + inactive for too long, will drop the data (it will eventually + be retransmitted). */ +#if TCP_QUEUE_OOSEQ + if (pcb->ooseq != NULL && + 8006312: 69fb ldr r3, [r7, #28] + 8006314: 6f5b ldr r3, [r3, #116] ; 0x74 + 8006316: 2b00 cmp r3, #0 + 8006318: d016 beq.n 8006348 + (u32_t)tcp_ticks - pcb->tmr >= pcb->rto * TCP_OOSEQ_TIMEOUT) { + 800631a: 4b25 ldr r3, [pc, #148] ; (80063b0 ) + 800631c: 681a ldr r2, [r3, #0] + 800631e: 69fb ldr r3, [r7, #28] + 8006320: 6a5b ldr r3, [r3, #36] ; 0x24 + 8006322: 1ad2 subs r2, r2, r3 + 8006324: 69fb ldr r3, [r7, #28] + 8006326: 2144 movs r1, #68 ; 0x44 + 8006328: 5e5b ldrsh r3, [r3, r1] + 800632a: 0019 movs r1, r3 + 800632c: 000b movs r3, r1 + 800632e: 005b lsls r3, r3, #1 + 8006330: 185b adds r3, r3, r1 + 8006332: 005b lsls r3, r3, #1 + if (pcb->ooseq != NULL && + 8006334: 429a cmp r2, r3 + 8006336: d307 bcc.n 8006348 + tcp_segs_free(pcb->ooseq); + 8006338: 69fb ldr r3, [r7, #28] + 800633a: 6f5b ldr r3, [r3, #116] ; 0x74 + 800633c: 0018 movs r0, r3 + 800633e: f000 f9d9 bl 80066f4 + pcb->ooseq = NULL; + 8006342: 69fb ldr r3, [r7, #28] + 8006344: 2200 movs r2, #0 + 8006346: 675a str r2, [r3, #116] ; 0x74 + LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_slowtmr: dropping OOSEQ queued data\n")); + } +#endif /* TCP_QUEUE_OOSEQ */ + + /* Check if this PCB has stayed too long in SYN-RCVD */ + if (pcb->state == SYN_RCVD) { + 8006348: 69fb ldr r3, [r7, #28] + 800634a: 7e1b ldrb r3, [r3, #24] + 800634c: 2b03 cmp r3, #3 + 800634e: d10c bne.n 800636a + if ((u32_t)(tcp_ticks - pcb->tmr) > + 8006350: 4b17 ldr r3, [pc, #92] ; (80063b0 ) + 8006352: 681a ldr r2, [r3, #0] + 8006354: 69fb ldr r3, [r7, #28] + 8006356: 6a5b ldr r3, [r3, #36] ; 0x24 + 8006358: 1ad3 subs r3, r2, r3 + 800635a: 2b28 cmp r3, #40 ; 0x28 + 800635c: d905 bls.n 800636a + TCP_SYN_RCVD_TIMEOUT / TCP_SLOW_INTERVAL) { + ++pcb_remove; + 800635e: 2217 movs r2, #23 + 8006360: 18bb adds r3, r7, r2 + 8006362: 18ba adds r2, r7, r2 + 8006364: 7812 ldrb r2, [r2, #0] + 8006366: 3201 adds r2, #1 + 8006368: 701a strb r2, [r3, #0] + LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: removing pcb stuck in SYN-RCVD\n")); + } + } + + /* Check if this PCB has stayed too long in LAST-ACK */ + if (pcb->state == LAST_ACK) { + 800636a: 69fb ldr r3, [r7, #28] + 800636c: 7e1b ldrb r3, [r3, #24] + 800636e: 2b09 cmp r3, #9 + 8006370: d10c bne.n 800638c + if ((u32_t)(tcp_ticks - pcb->tmr) > 2 * TCP_MSL / TCP_SLOW_INTERVAL) { + 8006372: 4b0f ldr r3, [pc, #60] ; (80063b0 ) + 8006374: 681a ldr r2, [r3, #0] + 8006376: 69fb ldr r3, [r7, #28] + 8006378: 6a5b ldr r3, [r3, #36] ; 0x24 + 800637a: 1ad3 subs r3, r2, r3 + 800637c: 2bf0 cmp r3, #240 ; 0xf0 + 800637e: d905 bls.n 800638c + ++pcb_remove; + 8006380: 2217 movs r2, #23 + 8006382: 18bb adds r3, r7, r2 + 8006384: 18ba adds r2, r7, r2 + 8006386: 7812 ldrb r2, [r2, #0] + 8006388: 3201 adds r2, #1 + 800638a: 701a strb r2, [r3, #0] + LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: removing pcb stuck in LAST-ACK\n")); + } + } + + /* If the PCB should be removed, do it. */ + if (pcb_remove) { + 800638c: 2317 movs r3, #23 + 800638e: 18fb adds r3, r7, r3 + 8006390: 781b ldrb r3, [r3, #0] + 8006392: 2b00 cmp r3, #0 + 8006394: d056 beq.n 8006444 + struct tcp_pcb *pcb2; + tcp_err_fn err_fn; + void *err_arg; + tcp_pcb_purge(pcb); + 8006396: 69fb ldr r3, [r7, #28] + 8006398: 0018 movs r0, r3 + 800639a: f000 fb45 bl 8006a28 + /* Remove PCB from tcp_active_pcbs list. */ + if (prev != NULL) { + 800639e: 69bb ldr r3, [r7, #24] + 80063a0: 2b00 cmp r3, #0 + 80063a2: d013 beq.n 80063cc + LWIP_ASSERT("tcp_slowtmr: middle tcp != tcp_active_pcbs", pcb != tcp_active_pcbs); + prev->next = pcb->next; + 80063a4: 69fb ldr r3, [r7, #28] + 80063a6: 68da ldr r2, [r3, #12] + 80063a8: 69bb ldr r3, [r7, #24] + 80063aa: 60da str r2, [r3, #12] + 80063ac: e012 b.n 80063d4 + 80063ae: 46c0 nop ; (mov r8, r8) + 80063b0: 20003278 .word 0x20003278 + 80063b4: 20002279 .word 0x20002279 + 80063b8: 20003274 .word 0x20003274 + 80063bc: 0800fd70 .word 0x0800fd70 + 80063c0: 0800fd60 .word 0x0800fd60 + 80063c4: 000a4cb8 .word 0x000a4cb8 + 80063c8: 000124f8 .word 0x000124f8 + } else { + /* This PCB was the first. */ + LWIP_ASSERT("tcp_slowtmr: first pcb == tcp_active_pcbs", tcp_active_pcbs == pcb); + tcp_active_pcbs = pcb->next; + 80063cc: 69fb ldr r3, [r7, #28] + 80063ce: 68da ldr r2, [r3, #12] + 80063d0: 4b5e ldr r3, [pc, #376] ; (800654c ) + 80063d2: 601a str r2, [r3, #0] + } + + if (pcb_reset) { + 80063d4: 2316 movs r3, #22 + 80063d6: 18fb adds r3, r7, r3 + 80063d8: 781b ldrb r3, [r3, #0] + 80063da: 2b00 cmp r3, #0 + 80063dc: d010 beq.n 8006400 + tcp_rst(pcb->snd_nxt, pcb->rcv_nxt, &pcb->local_ip, &pcb->remote_ip, + 80063de: 69fb ldr r3, [r7, #28] + 80063e0: 6d18 ldr r0, [r3, #80] ; 0x50 + 80063e2: 69fb ldr r3, [r7, #28] + 80063e4: 6a99 ldr r1, [r3, #40] ; 0x28 + 80063e6: 69fc ldr r4, [r7, #28] + 80063e8: 69fb ldr r3, [r7, #28] + 80063ea: 1d1d adds r5, r3, #4 + 80063ec: 69fb ldr r3, [r7, #28] + 80063ee: 8b5b ldrh r3, [r3, #26] + 80063f0: 69fa ldr r2, [r7, #28] + 80063f2: 8b92 ldrh r2, [r2, #28] + 80063f4: 9201 str r2, [sp, #4] + 80063f6: 9300 str r3, [sp, #0] + 80063f8: 002b movs r3, r5 + 80063fa: 0022 movs r2, r4 + 80063fc: f003 fde6 bl 8009fcc + pcb->local_port, pcb->remote_port); + } + + err_fn = pcb->errf; + 8006400: 69fb ldr r3, [r7, #28] + 8006402: 228c movs r2, #140 ; 0x8c + 8006404: 589b ldr r3, [r3, r2] + 8006406: 60bb str r3, [r7, #8] + err_arg = pcb->callback_arg; + 8006408: 69fb ldr r3, [r7, #28] + 800640a: 691b ldr r3, [r3, #16] + 800640c: 607b str r3, [r7, #4] + pcb2 = pcb; + 800640e: 69fb ldr r3, [r7, #28] + 8006410: 603b str r3, [r7, #0] + pcb = pcb->next; + 8006412: 69fb ldr r3, [r7, #28] + 8006414: 68db ldr r3, [r3, #12] + 8006416: 61fb str r3, [r7, #28] + memp_free(MEMP_TCP_PCB, pcb2); + 8006418: 683b ldr r3, [r7, #0] + 800641a: 0019 movs r1, r3 + 800641c: 2002 movs r0, #2 + 800641e: f7fe fd7f bl 8004f20 + + tcp_active_pcbs_changed = 0; + 8006422: 4b4b ldr r3, [pc, #300] ; (8006550 ) + 8006424: 2200 movs r2, #0 + 8006426: 701a strb r2, [r3, #0] + TCP_EVENT_ERR(err_fn, err_arg, ERR_ABRT); + 8006428: 68bb ldr r3, [r7, #8] + 800642a: 2b00 cmp r3, #0 + 800642c: d005 beq.n 800643a + 800642e: 230a movs r3, #10 + 8006430: 4259 negs r1, r3 + 8006432: 687a ldr r2, [r7, #4] + 8006434: 68bb ldr r3, [r7, #8] + 8006436: 0010 movs r0, r2 + 8006438: 4798 blx r3 + if (tcp_active_pcbs_changed) { + 800643a: 4b45 ldr r3, [pc, #276] ; (8006550 ) + 800643c: 781b ldrb r3, [r3, #0] + 800643e: 2b00 cmp r3, #0 + 8006440: d03d beq.n 80064be + goto tcp_slowtmr_start; + 8006442: e62f b.n 80060a4 + } + } else { + /* get the 'next' element now and work with 'prev' below (in case of abort) */ + prev = pcb; + 8006444: 69fb ldr r3, [r7, #28] + 8006446: 61bb str r3, [r7, #24] + pcb = pcb->next; + 8006448: 69fb ldr r3, [r7, #28] + 800644a: 68db ldr r3, [r3, #12] + 800644c: 61fb str r3, [r7, #28] + + /* We check if we should poll the connection. */ + ++prev->polltmr; + 800644e: 69bb ldr r3, [r7, #24] + 8006450: 7fdb ldrb r3, [r3, #31] + 8006452: 3301 adds r3, #1 + 8006454: b2da uxtb r2, r3 + 8006456: 69bb ldr r3, [r7, #24] + 8006458: 77da strb r2, [r3, #31] + if (prev->polltmr >= prev->pollinterval) { + 800645a: 69bb ldr r3, [r7, #24] + 800645c: 7fda ldrb r2, [r3, #31] + 800645e: 69bb ldr r3, [r7, #24] + 8006460: 2120 movs r1, #32 + 8006462: 5c5b ldrb r3, [r3, r1] + 8006464: 429a cmp r2, r3 + 8006466: d32a bcc.n 80064be + prev->polltmr = 0; + 8006468: 69bb ldr r3, [r7, #24] + 800646a: 2200 movs r2, #0 + 800646c: 77da strb r2, [r3, #31] + LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: polling application\n")); + tcp_active_pcbs_changed = 0; + 800646e: 4b38 ldr r3, [pc, #224] ; (8006550 ) + 8006470: 2200 movs r2, #0 + 8006472: 701a strb r2, [r3, #0] + TCP_EVENT_POLL(prev, err); + 8006474: 69bb ldr r3, [r7, #24] + 8006476: 2288 movs r2, #136 ; 0x88 + 8006478: 589b ldr r3, [r3, r2] + 800647a: 2b00 cmp r3, #0 + 800647c: d00c beq.n 8006498 + 800647e: 69bb ldr r3, [r7, #24] + 8006480: 2288 movs r2, #136 ; 0x88 + 8006482: 589a ldr r2, [r3, r2] + 8006484: 69bb ldr r3, [r7, #24] + 8006486: 691b ldr r3, [r3, #16] + 8006488: 2115 movs r1, #21 + 800648a: 187c adds r4, r7, r1 + 800648c: 69b9 ldr r1, [r7, #24] + 800648e: 0018 movs r0, r3 + 8006490: 4790 blx r2 + 8006492: 0003 movs r3, r0 + 8006494: 7023 strb r3, [r4, #0] + 8006496: e003 b.n 80064a0 + 8006498: 2315 movs r3, #21 + 800649a: 18fb adds r3, r7, r3 + 800649c: 2200 movs r2, #0 + 800649e: 701a strb r2, [r3, #0] + if (tcp_active_pcbs_changed) { + 80064a0: 4b2b ldr r3, [pc, #172] ; (8006550 ) + 80064a2: 781b ldrb r3, [r3, #0] + 80064a4: 2b00 cmp r3, #0 + 80064a6: d000 beq.n 80064aa + goto tcp_slowtmr_start; + 80064a8: e5fc b.n 80060a4 + } + /* if err == ERR_ABRT, 'prev' is already deallocated */ + if (err == ERR_OK) { + 80064aa: 2315 movs r3, #21 + 80064ac: 18fb adds r3, r7, r3 + 80064ae: 781b ldrb r3, [r3, #0] + 80064b0: b25b sxtb r3, r3 + 80064b2: 2b00 cmp r3, #0 + 80064b4: d103 bne.n 80064be + tcp_output(prev); + 80064b6: 69bb ldr r3, [r7, #24] + 80064b8: 0018 movs r0, r3 + 80064ba: f003 faa9 bl 8009a10 + while (pcb != NULL) { + 80064be: 69fb ldr r3, [r7, #28] + 80064c0: 2b00 cmp r3, #0 + 80064c2: d000 beq.n 80064c6 + 80064c4: e5f4 b.n 80060b0 + } + } + + + /* Steps through all of the TIME-WAIT PCBs. */ + prev = NULL; + 80064c6: 2300 movs r3, #0 + 80064c8: 61bb str r3, [r7, #24] + pcb = tcp_tw_pcbs; + 80064ca: 4b22 ldr r3, [pc, #136] ; (8006554 ) + 80064cc: 681b ldr r3, [r3, #0] + 80064ce: 61fb str r3, [r7, #28] + while (pcb != NULL) { + 80064d0: e035 b.n 800653e + LWIP_ASSERT("tcp_slowtmr: TIME-WAIT pcb->state == TIME-WAIT", pcb->state == TIME_WAIT); + pcb_remove = 0; + 80064d2: 2317 movs r3, #23 + 80064d4: 18fb adds r3, r7, r3 + 80064d6: 2200 movs r2, #0 + 80064d8: 701a strb r2, [r3, #0] + + /* Check if this PCB has stayed long enough in TIME-WAIT */ + if ((u32_t)(tcp_ticks - pcb->tmr) > 2 * TCP_MSL / TCP_SLOW_INTERVAL) { + 80064da: 4b1f ldr r3, [pc, #124] ; (8006558 ) + 80064dc: 681a ldr r2, [r3, #0] + 80064de: 69fb ldr r3, [r7, #28] + 80064e0: 6a5b ldr r3, [r3, #36] ; 0x24 + 80064e2: 1ad3 subs r3, r2, r3 + 80064e4: 2bf0 cmp r3, #240 ; 0xf0 + 80064e6: d905 bls.n 80064f4 + ++pcb_remove; + 80064e8: 2217 movs r2, #23 + 80064ea: 18bb adds r3, r7, r2 + 80064ec: 18ba adds r2, r7, r2 + 80064ee: 7812 ldrb r2, [r2, #0] + 80064f0: 3201 adds r2, #1 + 80064f2: 701a strb r2, [r3, #0] + } + + + + /* If the PCB should be removed, do it. */ + if (pcb_remove) { + 80064f4: 2317 movs r3, #23 + 80064f6: 18fb adds r3, r7, r3 + 80064f8: 781b ldrb r3, [r3, #0] + 80064fa: 2b00 cmp r3, #0 + 80064fc: d01a beq.n 8006534 + struct tcp_pcb *pcb2; + tcp_pcb_purge(pcb); + 80064fe: 69fb ldr r3, [r7, #28] + 8006500: 0018 movs r0, r3 + 8006502: f000 fa91 bl 8006a28 + /* Remove PCB from tcp_tw_pcbs list. */ + if (prev != NULL) { + 8006506: 69bb ldr r3, [r7, #24] + 8006508: 2b00 cmp r3, #0 + 800650a: d004 beq.n 8006516 + LWIP_ASSERT("tcp_slowtmr: middle tcp != tcp_tw_pcbs", pcb != tcp_tw_pcbs); + prev->next = pcb->next; + 800650c: 69fb ldr r3, [r7, #28] + 800650e: 68da ldr r2, [r3, #12] + 8006510: 69bb ldr r3, [r7, #24] + 8006512: 60da str r2, [r3, #12] + 8006514: e003 b.n 800651e + } else { + /* This PCB was the first. */ + LWIP_ASSERT("tcp_slowtmr: first pcb == tcp_tw_pcbs", tcp_tw_pcbs == pcb); + tcp_tw_pcbs = pcb->next; + 8006516: 69fb ldr r3, [r7, #28] + 8006518: 68da ldr r2, [r3, #12] + 800651a: 4b0e ldr r3, [pc, #56] ; (8006554 ) + 800651c: 601a str r2, [r3, #0] + } + pcb2 = pcb; + 800651e: 69fb ldr r3, [r7, #28] + 8006520: 613b str r3, [r7, #16] + pcb = pcb->next; + 8006522: 69fb ldr r3, [r7, #28] + 8006524: 68db ldr r3, [r3, #12] + 8006526: 61fb str r3, [r7, #28] + memp_free(MEMP_TCP_PCB, pcb2); + 8006528: 693b ldr r3, [r7, #16] + 800652a: 0019 movs r1, r3 + 800652c: 2002 movs r0, #2 + 800652e: f7fe fcf7 bl 8004f20 + 8006532: e004 b.n 800653e + } else { + prev = pcb; + 8006534: 69fb ldr r3, [r7, #28] + 8006536: 61bb str r3, [r7, #24] + pcb = pcb->next; + 8006538: 69fb ldr r3, [r7, #28] + 800653a: 68db ldr r3, [r3, #12] + 800653c: 61fb str r3, [r7, #28] + while (pcb != NULL) { + 800653e: 69fb ldr r3, [r7, #28] + 8006540: 2b00 cmp r3, #0 + 8006542: d1c6 bne.n 80064d2 + } + } +} + 8006544: 46c0 nop ; (mov r8, r8) + 8006546: 46bd mov sp, r7 + 8006548: b008 add sp, #32 + 800654a: bdb0 pop {r4, r5, r7, pc} + 800654c: 20003274 .word 0x20003274 + 8006550: 20003270 .word 0x20003270 + 8006554: 20003288 .word 0x20003288 + 8006558: 20003278 .word 0x20003278 + +0800655c : + * + * Automatically called from tcp_tmr(). + */ +void +tcp_fasttmr(void) +{ + 800655c: b580 push {r7, lr} + 800655e: b082 sub sp, #8 + 8006560: af00 add r7, sp, #0 + struct tcp_pcb *pcb; + + ++tcp_timer_ctr; + 8006562: 4b25 ldr r3, [pc, #148] ; (80065f8 ) + 8006564: 781b ldrb r3, [r3, #0] + 8006566: 3301 adds r3, #1 + 8006568: b2da uxtb r2, r3 + 800656a: 4b23 ldr r3, [pc, #140] ; (80065f8 ) + 800656c: 701a strb r2, [r3, #0] + +tcp_fasttmr_start: + pcb = tcp_active_pcbs; + 800656e: 4b23 ldr r3, [pc, #140] ; (80065fc ) + 8006570: 681b ldr r3, [r3, #0] + 8006572: 607b str r3, [r7, #4] + + while(pcb != NULL) { + 8006574: e038 b.n 80065e8 + if (pcb->last_timer != tcp_timer_ctr) { + 8006576: 687b ldr r3, [r7, #4] + 8006578: 2221 movs r2, #33 ; 0x21 + 800657a: 5c9a ldrb r2, [r3, r2] + 800657c: 4b1e ldr r3, [pc, #120] ; (80065f8 ) + 800657e: 781b ldrb r3, [r3, #0] + 8006580: 429a cmp r2, r3 + 8006582: d031 beq.n 80065e8 + struct tcp_pcb *next; + pcb->last_timer = tcp_timer_ctr; + 8006584: 4b1c ldr r3, [pc, #112] ; (80065f8 ) + 8006586: 7819 ldrb r1, [r3, #0] + 8006588: 687b ldr r3, [r7, #4] + 800658a: 2221 movs r2, #33 ; 0x21 + 800658c: 5499 strb r1, [r3, r2] + /* send delayed ACKs */ + if (pcb->flags & TF_ACK_DELAY) { + 800658e: 687b ldr r3, [r7, #4] + 8006590: 7f9b ldrb r3, [r3, #30] + 8006592: 001a movs r2, r3 + 8006594: 2301 movs r3, #1 + 8006596: 4013 ands r3, r2 + 8006598: d011 beq.n 80065be + LWIP_DEBUGF(TCP_DEBUG, ("tcp_fasttmr: delayed ACK\n")); + tcp_ack_now(pcb); + 800659a: 687b ldr r3, [r7, #4] + 800659c: 7f9b ldrb r3, [r3, #30] + 800659e: 2202 movs r2, #2 + 80065a0: 4313 orrs r3, r2 + 80065a2: b2da uxtb r2, r3 + 80065a4: 687b ldr r3, [r7, #4] + 80065a6: 779a strb r2, [r3, #30] + tcp_output(pcb); + 80065a8: 687b ldr r3, [r7, #4] + 80065aa: 0018 movs r0, r3 + 80065ac: f003 fa30 bl 8009a10 + pcb->flags &= ~(TF_ACK_DELAY | TF_ACK_NOW); + 80065b0: 687b ldr r3, [r7, #4] + 80065b2: 7f9b ldrb r3, [r3, #30] + 80065b4: 2203 movs r2, #3 + 80065b6: 4393 bics r3, r2 + 80065b8: b2da uxtb r2, r3 + 80065ba: 687b ldr r3, [r7, #4] + 80065bc: 779a strb r2, [r3, #30] + } + + next = pcb->next; + 80065be: 687b ldr r3, [r7, #4] + 80065c0: 68db ldr r3, [r3, #12] + 80065c2: 603b str r3, [r7, #0] + + /* If there is data which was previously "refused" by upper layer */ + if (pcb->refused_data != NULL) { + 80065c4: 687b ldr r3, [r7, #4] + 80065c6: 6f9b ldr r3, [r3, #120] ; 0x78 + 80065c8: 2b00 cmp r3, #0 + 80065ca: d00b beq.n 80065e4 + tcp_active_pcbs_changed = 0; + 80065cc: 4b0c ldr r3, [pc, #48] ; (8006600 ) + 80065ce: 2200 movs r2, #0 + 80065d0: 701a strb r2, [r3, #0] + tcp_process_refused_data(pcb); + 80065d2: 687b ldr r3, [r7, #4] + 80065d4: 0018 movs r0, r3 + 80065d6: f000 f815 bl 8006604 + if (tcp_active_pcbs_changed) { + 80065da: 4b09 ldr r3, [pc, #36] ; (8006600 ) + 80065dc: 781b ldrb r3, [r3, #0] + 80065de: 2b00 cmp r3, #0 + 80065e0: d000 beq.n 80065e4 + /* application callback has changed the pcb list: restart the loop */ + goto tcp_fasttmr_start; + 80065e2: e7c4 b.n 800656e + } + } + pcb = next; + 80065e4: 683b ldr r3, [r7, #0] + 80065e6: 607b str r3, [r7, #4] + while(pcb != NULL) { + 80065e8: 687b ldr r3, [r7, #4] + 80065ea: 2b00 cmp r3, #0 + 80065ec: d1c3 bne.n 8006576 + } + } +} + 80065ee: 46c0 nop ; (mov r8, r8) + 80065f0: 46bd mov sp, r7 + 80065f2: b002 add sp, #8 + 80065f4: bd80 pop {r7, pc} + 80065f6: 46c0 nop ; (mov r8, r8) + 80065f8: 20002279 .word 0x20002279 + 80065fc: 20003274 .word 0x20003274 + 8006600: 20003270 .word 0x20003270 + +08006604 : + +/** Pass pcb->refused_data to the recv callback */ +err_t +tcp_process_refused_data(struct tcp_pcb *pcb) +{ + 8006604: b5b0 push {r4, r5, r7, lr} + 8006606: b084 sub sp, #16 + 8006608: af00 add r7, sp, #0 + 800660a: 6078 str r0, [r7, #4] + err_t err; + u8_t refused_flags = pcb->refused_data->flags; + 800660c: 687b ldr r3, [r7, #4] + 800660e: 6f9a ldr r2, [r3, #120] ; 0x78 + 8006610: 230e movs r3, #14 + 8006612: 18fb adds r3, r7, r3 + 8006614: 7b52 ldrb r2, [r2, #13] + 8006616: 701a strb r2, [r3, #0] + /* set pcb->refused_data to NULL in case the callback frees it and then + closes the pcb */ + struct pbuf *refused_data = pcb->refused_data; + 8006618: 687b ldr r3, [r7, #4] + 800661a: 6f9b ldr r3, [r3, #120] ; 0x78 + 800661c: 60bb str r3, [r7, #8] + pcb->refused_data = NULL; + 800661e: 687b ldr r3, [r7, #4] + 8006620: 2200 movs r2, #0 + 8006622: 679a str r2, [r3, #120] ; 0x78 + /* Notify again application with data previously received. */ + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: notify kept packet\n")); + TCP_EVENT_RECV(pcb, refused_data, ERR_OK, err); + 8006624: 687b ldr r3, [r7, #4] + 8006626: 2280 movs r2, #128 ; 0x80 + 8006628: 589b ldr r3, [r3, r2] + 800662a: 2b00 cmp r3, #0 + 800662c: d00d beq.n 800664a + 800662e: 687b ldr r3, [r7, #4] + 8006630: 2280 movs r2, #128 ; 0x80 + 8006632: 589d ldr r5, [r3, r2] + 8006634: 687b ldr r3, [r7, #4] + 8006636: 6918 ldr r0, [r3, #16] + 8006638: 230f movs r3, #15 + 800663a: 18fc adds r4, r7, r3 + 800663c: 68ba ldr r2, [r7, #8] + 800663e: 6879 ldr r1, [r7, #4] + 8006640: 2300 movs r3, #0 + 8006642: 47a8 blx r5 + 8006644: 0003 movs r3, r0 + 8006646: 7023 strb r3, [r4, #0] + 8006648: e009 b.n 800665e + 800664a: 230f movs r3, #15 + 800664c: 18fc adds r4, r7, r3 + 800664e: 68ba ldr r2, [r7, #8] + 8006650: 6879 ldr r1, [r7, #4] + 8006652: 2300 movs r3, #0 + 8006654: 2000 movs r0, #0 + 8006656: f000 f899 bl 800678c + 800665a: 0003 movs r3, r0 + 800665c: 7023 strb r3, [r4, #0] + if (err == ERR_OK) { + 800665e: 230f movs r3, #15 + 8006660: 18fb adds r3, r7, r3 + 8006662: 781b ldrb r3, [r3, #0] + 8006664: b25b sxtb r3, r3 + 8006666: 2b00 cmp r3, #0 + 8006668: d130 bne.n 80066cc + /* did refused_data include a FIN? */ + if (refused_flags & PBUF_FLAG_TCP_FIN) { + 800666a: 230e movs r3, #14 + 800666c: 18fb adds r3, r7, r3 + 800666e: 781b ldrb r3, [r3, #0] + 8006670: 2220 movs r2, #32 + 8006672: 4013 ands r3, r2 + 8006674: d036 beq.n 80066e4 + /* correct rcv_wnd as the application won't call tcp_recved() + for the FIN's seqno */ + if (pcb->rcv_wnd != TCP_WND) { + 8006676: 687b ldr r3, [r7, #4] + 8006678: 8d9b ldrh r3, [r3, #44] ; 0x2c + 800667a: 4a1d ldr r2, [pc, #116] ; (80066f0 ) + 800667c: 4293 cmp r3, r2 + 800667e: d005 beq.n 800668c + pcb->rcv_wnd++; + 8006680: 687b ldr r3, [r7, #4] + 8006682: 8d9b ldrh r3, [r3, #44] ; 0x2c + 8006684: 3301 adds r3, #1 + 8006686: b29a uxth r2, r3 + 8006688: 687b ldr r3, [r7, #4] + 800668a: 859a strh r2, [r3, #44] ; 0x2c + } + TCP_EVENT_CLOSED(pcb, err); + 800668c: 687b ldr r3, [r7, #4] + 800668e: 2280 movs r2, #128 ; 0x80 + 8006690: 589b ldr r3, [r3, r2] + 8006692: 2b00 cmp r3, #0 + 8006694: d00d beq.n 80066b2 + 8006696: 687b ldr r3, [r7, #4] + 8006698: 2280 movs r2, #128 ; 0x80 + 800669a: 589d ldr r5, [r3, r2] + 800669c: 687b ldr r3, [r7, #4] + 800669e: 6918 ldr r0, [r3, #16] + 80066a0: 230f movs r3, #15 + 80066a2: 18fc adds r4, r7, r3 + 80066a4: 6879 ldr r1, [r7, #4] + 80066a6: 2300 movs r3, #0 + 80066a8: 2200 movs r2, #0 + 80066aa: 47a8 blx r5 + 80066ac: 0003 movs r3, r0 + 80066ae: 7023 strb r3, [r4, #0] + 80066b0: e003 b.n 80066ba + 80066b2: 230f movs r3, #15 + 80066b4: 18fb adds r3, r7, r3 + 80066b6: 2200 movs r2, #0 + 80066b8: 701a strb r2, [r3, #0] + if (err == ERR_ABRT) { + 80066ba: 230f movs r3, #15 + 80066bc: 18fb adds r3, r7, r3 + 80066be: 781b ldrb r3, [r3, #0] + 80066c0: b25b sxtb r3, r3 + 80066c2: 330a adds r3, #10 + 80066c4: d10e bne.n 80066e4 + return ERR_ABRT; + 80066c6: 230a movs r3, #10 + 80066c8: 425b negs r3, r3 + 80066ca: e00c b.n 80066e6 + } + } + } else if (err == ERR_ABRT) { + 80066cc: 230f movs r3, #15 + 80066ce: 18fb adds r3, r7, r3 + 80066d0: 781b ldrb r3, [r3, #0] + 80066d2: b25b sxtb r3, r3 + 80066d4: 330a adds r3, #10 + 80066d6: d102 bne.n 80066de + /* if err == ERR_ABRT, 'pcb' is already deallocated */ + /* Drop incoming packets because pcb is "full" (only if the incoming + segment contains data). */ + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: drop incoming packets, because pcb is \"full\"\n")); + return ERR_ABRT; + 80066d8: 230a movs r3, #10 + 80066da: 425b negs r3, r3 + 80066dc: e003 b.n 80066e6 + } else { + /* data is still refused, pbuf is still valid (go on for ACK-only packets) */ + pcb->refused_data = refused_data; + 80066de: 687b ldr r3, [r7, #4] + 80066e0: 68ba ldr r2, [r7, #8] + 80066e2: 679a str r2, [r3, #120] ; 0x78 + } + return ERR_OK; + 80066e4: 2300 movs r3, #0 +} + 80066e6: 0018 movs r0, r3 + 80066e8: 46bd mov sp, r7 + 80066ea: b004 add sp, #16 + 80066ec: bdb0 pop {r4, r5, r7, pc} + 80066ee: 46c0 nop ; (mov r8, r8) + 80066f0: 000016d0 .word 0x000016d0 + +080066f4 : + * + * @param seg tcp_seg list of TCP segments to free + */ +void +tcp_segs_free(struct tcp_seg *seg) +{ + 80066f4: b580 push {r7, lr} + 80066f6: b084 sub sp, #16 + 80066f8: af00 add r7, sp, #0 + 80066fa: 6078 str r0, [r7, #4] + while (seg != NULL) { + 80066fc: e008 b.n 8006710 + struct tcp_seg *next = seg->next; + 80066fe: 687b ldr r3, [r7, #4] + 8006700: 681b ldr r3, [r3, #0] + 8006702: 60fb str r3, [r7, #12] + tcp_seg_free(seg); + 8006704: 687b ldr r3, [r7, #4] + 8006706: 0018 movs r0, r3 + 8006708: f000 f809 bl 800671e + seg = next; + 800670c: 68fb ldr r3, [r7, #12] + 800670e: 607b str r3, [r7, #4] + while (seg != NULL) { + 8006710: 687b ldr r3, [r7, #4] + 8006712: 2b00 cmp r3, #0 + 8006714: d1f3 bne.n 80066fe + } +} + 8006716: 46c0 nop ; (mov r8, r8) + 8006718: 46bd mov sp, r7 + 800671a: b004 add sp, #16 + 800671c: bd80 pop {r7, pc} + +0800671e : + * + * @param seg single tcp_seg to free + */ +void +tcp_seg_free(struct tcp_seg *seg) +{ + 800671e: b580 push {r7, lr} + 8006720: b082 sub sp, #8 + 8006722: af00 add r7, sp, #0 + 8006724: 6078 str r0, [r7, #4] + if (seg != NULL) { + 8006726: 687b ldr r3, [r7, #4] + 8006728: 2b00 cmp r3, #0 + 800672a: d00d beq.n 8006748 + if (seg->p != NULL) { + 800672c: 687b ldr r3, [r7, #4] + 800672e: 685b ldr r3, [r3, #4] + 8006730: 2b00 cmp r3, #0 + 8006732: d004 beq.n 800673e + pbuf_free(seg->p); + 8006734: 687b ldr r3, [r7, #4] + 8006736: 685b ldr r3, [r3, #4] + 8006738: 0018 movs r0, r3 + 800673a: f7fe ffb3 bl 80056a4 +#if TCP_DEBUG + seg->p = NULL; +#endif /* TCP_DEBUG */ + } + memp_free(MEMP_TCP_SEG, seg); + 800673e: 687b ldr r3, [r7, #4] + 8006740: 0019 movs r1, r3 + 8006742: 2004 movs r0, #4 + 8006744: f7fe fbec bl 8004f20 + } +} + 8006748: 46c0 nop ; (mov r8, r8) + 800674a: 46bd mov sp, r7 + 800674c: b002 add sp, #8 + 800674e: bd80 pop {r7, pc} + +08006750 : + * @param seg the old tcp_seg + * @return a copy of seg + */ +struct tcp_seg * +tcp_seg_copy(struct tcp_seg *seg) +{ + 8006750: b580 push {r7, lr} + 8006752: b084 sub sp, #16 + 8006754: af00 add r7, sp, #0 + 8006756: 6078 str r0, [r7, #4] + struct tcp_seg *cseg; + + cseg = (struct tcp_seg *)memp_malloc(MEMP_TCP_SEG); + 8006758: 2004 movs r0, #4 + 800675a: f7fe fb5b bl 8004e14 + 800675e: 0003 movs r3, r0 + 8006760: 60fb str r3, [r7, #12] + if (cseg == NULL) { + 8006762: 68fb ldr r3, [r7, #12] + 8006764: 2b00 cmp r3, #0 + 8006766: d101 bne.n 800676c + return NULL; + 8006768: 2300 movs r3, #0 + 800676a: e00b b.n 8006784 + } + SMEMCPY((u8_t *)cseg, (const u8_t *)seg, sizeof(struct tcp_seg)); + 800676c: 6879 ldr r1, [r7, #4] + 800676e: 68fb ldr r3, [r7, #12] + 8006770: 2210 movs r2, #16 + 8006772: 0018 movs r0, r3 + 8006774: f009 fa95 bl 800fca2 + pbuf_ref(cseg->p); + 8006778: 68fb ldr r3, [r7, #12] + 800677a: 685b ldr r3, [r3, #4] + 800677c: 0018 movs r0, r3 + 800677e: f7ff f81f bl 80057c0 + return cseg; + 8006782: 68fb ldr r3, [r7, #12] +} + 8006784: 0018 movs r0, r3 + 8006786: 46bd mov sp, r7 + 8006788: b004 add sp, #16 + 800678a: bd80 pop {r7, pc} + +0800678c : + * Default receive callback that is called if the user didn't register + * a recv callback for the pcb. + */ +err_t +tcp_recv_null(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err) +{ + 800678c: b580 push {r7, lr} + 800678e: b084 sub sp, #16 + 8006790: af00 add r7, sp, #0 + 8006792: 60f8 str r0, [r7, #12] + 8006794: 60b9 str r1, [r7, #8] + 8006796: 607a str r2, [r7, #4] + 8006798: 001a movs r2, r3 + 800679a: 1cfb adds r3, r7, #3 + 800679c: 701a strb r2, [r3, #0] + LWIP_UNUSED_ARG(arg); + if (p != NULL) { + 800679e: 687b ldr r3, [r7, #4] + 80067a0: 2b00 cmp r3, #0 + 80067a2: d00b beq.n 80067bc + tcp_recved(pcb, p->tot_len); + 80067a4: 687b ldr r3, [r7, #4] + 80067a6: 891a ldrh r2, [r3, #8] + 80067a8: 68bb ldr r3, [r7, #8] + 80067aa: 0011 movs r1, r2 + 80067ac: 0018 movs r0, r3 + 80067ae: f7ff fc33 bl 8006018 + pbuf_free(p); + 80067b2: 687b ldr r3, [r7, #4] + 80067b4: 0018 movs r0, r3 + 80067b6: f7fe ff75 bl 80056a4 + 80067ba: e00a b.n 80067d2 + } else if (err == ERR_OK) { + 80067bc: 1cfb adds r3, r7, #3 + 80067be: 781b ldrb r3, [r3, #0] + 80067c0: b25b sxtb r3, r3 + 80067c2: 2b00 cmp r3, #0 + 80067c4: d105 bne.n 80067d2 + return tcp_close(pcb); + 80067c6: 68bb ldr r3, [r7, #8] + 80067c8: 0018 movs r0, r3 + 80067ca: f7ff fb4d bl 8005e68 + 80067ce: 0003 movs r3, r0 + 80067d0: e000 b.n 80067d4 + } + return ERR_OK; + 80067d2: 2300 movs r3, #0 +} + 80067d4: 0018 movs r0, r3 + 80067d6: 46bd mov sp, r7 + 80067d8: b004 add sp, #16 + 80067da: bd80 pop {r7, pc} + +080067dc : + * + * @param prio minimum priority + */ +static void +tcp_kill_prio(u8_t prio) +{ + 80067dc: b580 push {r7, lr} + 80067de: b086 sub sp, #24 + 80067e0: af00 add r7, sp, #0 + 80067e2: 0002 movs r2, r0 + 80067e4: 1dfb adds r3, r7, #7 + 80067e6: 701a strb r2, [r3, #0] + struct tcp_pcb *pcb, *inactive; + u32_t inactivity; + u8_t mprio; + + + mprio = TCP_PRIO_MAX; + 80067e8: 230b movs r3, #11 + 80067ea: 18fb adds r3, r7, r3 + 80067ec: 227f movs r2, #127 ; 0x7f + 80067ee: 701a strb r2, [r3, #0] + + /* We kill the oldest active connection that has lower priority than prio. */ + inactivity = 0; + 80067f0: 2300 movs r3, #0 + 80067f2: 60fb str r3, [r7, #12] + inactive = NULL; + 80067f4: 2300 movs r3, #0 + 80067f6: 613b str r3, [r7, #16] + for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) { + 80067f8: 4b1b ldr r3, [pc, #108] ; (8006868 ) + 80067fa: 681b ldr r3, [r3, #0] + 80067fc: 617b str r3, [r7, #20] + 80067fe: e024 b.n 800684a + if (pcb->prio <= prio && + 8006800: 697b ldr r3, [r7, #20] + 8006802: 7e5b ldrb r3, [r3, #25] + 8006804: 1dfa adds r2, r7, #7 + 8006806: 7812 ldrb r2, [r2, #0] + 8006808: 429a cmp r2, r3 + 800680a: d31b bcc.n 8006844 + pcb->prio <= mprio && + 800680c: 697b ldr r3, [r7, #20] + 800680e: 7e5b ldrb r3, [r3, #25] + if (pcb->prio <= prio && + 8006810: 220b movs r2, #11 + 8006812: 18ba adds r2, r7, r2 + 8006814: 7812 ldrb r2, [r2, #0] + 8006816: 429a cmp r2, r3 + 8006818: d314 bcc.n 8006844 + (u32_t)(tcp_ticks - pcb->tmr) >= inactivity) { + 800681a: 4b14 ldr r3, [pc, #80] ; (800686c ) + 800681c: 681a ldr r2, [r3, #0] + 800681e: 697b ldr r3, [r7, #20] + 8006820: 6a5b ldr r3, [r3, #36] ; 0x24 + 8006822: 1ad3 subs r3, r2, r3 + pcb->prio <= mprio && + 8006824: 68fa ldr r2, [r7, #12] + 8006826: 429a cmp r2, r3 + 8006828: d80c bhi.n 8006844 + inactivity = tcp_ticks - pcb->tmr; + 800682a: 4b10 ldr r3, [pc, #64] ; (800686c ) + 800682c: 681a ldr r2, [r3, #0] + 800682e: 697b ldr r3, [r7, #20] + 8006830: 6a5b ldr r3, [r3, #36] ; 0x24 + 8006832: 1ad3 subs r3, r2, r3 + 8006834: 60fb str r3, [r7, #12] + inactive = pcb; + 8006836: 697b ldr r3, [r7, #20] + 8006838: 613b str r3, [r7, #16] + mprio = pcb->prio; + 800683a: 230b movs r3, #11 + 800683c: 18fb adds r3, r7, r3 + 800683e: 697a ldr r2, [r7, #20] + 8006840: 7e52 ldrb r2, [r2, #25] + 8006842: 701a strb r2, [r3, #0] + for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) { + 8006844: 697b ldr r3, [r7, #20] + 8006846: 68db ldr r3, [r3, #12] + 8006848: 617b str r3, [r7, #20] + 800684a: 697b ldr r3, [r7, #20] + 800684c: 2b00 cmp r3, #0 + 800684e: d1d7 bne.n 8006800 + } + } + if (inactive != NULL) { + 8006850: 693b ldr r3, [r7, #16] + 8006852: 2b00 cmp r3, #0 + 8006854: d003 beq.n 800685e + LWIP_DEBUGF(TCP_DEBUG, ("tcp_kill_prio: killing oldest PCB %p (%"S32_F")\n", + (void *)inactive, inactivity)); + tcp_abort(inactive); + 8006856: 693b ldr r3, [r7, #16] + 8006858: 0018 movs r0, r3 + 800685a: f7ff fb8f bl 8005f7c + } +} + 800685e: 46c0 nop ; (mov r8, r8) + 8006860: 46bd mov sp, r7 + 8006862: b006 add sp, #24 + 8006864: bd80 pop {r7, pc} + 8006866: 46c0 nop ; (mov r8, r8) + 8006868: 20003274 .word 0x20003274 + 800686c: 20003278 .word 0x20003278 + +08006870 : + * Kills the oldest connection that is in TIME_WAIT state. + * Called from tcp_alloc() if no more connections are available. + */ +static void +tcp_kill_timewait(void) +{ + 8006870: b580 push {r7, lr} + 8006872: b084 sub sp, #16 + 8006874: af00 add r7, sp, #0 + struct tcp_pcb *pcb, *inactive; + u32_t inactivity; + + inactivity = 0; + 8006876: 2300 movs r3, #0 + 8006878: 607b str r3, [r7, #4] + inactive = NULL; + 800687a: 2300 movs r3, #0 + 800687c: 60bb str r3, [r7, #8] + /* Go through the list of TIME_WAIT pcbs and get the oldest pcb. */ + for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) { + 800687e: 4b12 ldr r3, [pc, #72] ; (80068c8 ) + 8006880: 681b ldr r3, [r3, #0] + 8006882: 60fb str r3, [r7, #12] + 8006884: e012 b.n 80068ac + if ((u32_t)(tcp_ticks - pcb->tmr) >= inactivity) { + 8006886: 4b11 ldr r3, [pc, #68] ; (80068cc ) + 8006888: 681a ldr r2, [r3, #0] + 800688a: 68fb ldr r3, [r7, #12] + 800688c: 6a5b ldr r3, [r3, #36] ; 0x24 + 800688e: 1ad3 subs r3, r2, r3 + 8006890: 687a ldr r2, [r7, #4] + 8006892: 429a cmp r2, r3 + 8006894: d807 bhi.n 80068a6 + inactivity = tcp_ticks - pcb->tmr; + 8006896: 4b0d ldr r3, [pc, #52] ; (80068cc ) + 8006898: 681a ldr r2, [r3, #0] + 800689a: 68fb ldr r3, [r7, #12] + 800689c: 6a5b ldr r3, [r3, #36] ; 0x24 + 800689e: 1ad3 subs r3, r2, r3 + 80068a0: 607b str r3, [r7, #4] + inactive = pcb; + 80068a2: 68fb ldr r3, [r7, #12] + 80068a4: 60bb str r3, [r7, #8] + for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) { + 80068a6: 68fb ldr r3, [r7, #12] + 80068a8: 68db ldr r3, [r3, #12] + 80068aa: 60fb str r3, [r7, #12] + 80068ac: 68fb ldr r3, [r7, #12] + 80068ae: 2b00 cmp r3, #0 + 80068b0: d1e9 bne.n 8006886 + } + } + if (inactive != NULL) { + 80068b2: 68bb ldr r3, [r7, #8] + 80068b4: 2b00 cmp r3, #0 + 80068b6: d003 beq.n 80068c0 + LWIP_DEBUGF(TCP_DEBUG, ("tcp_kill_timewait: killing oldest TIME-WAIT PCB %p (%"S32_F")\n", + (void *)inactive, inactivity)); + tcp_abort(inactive); + 80068b8: 68bb ldr r3, [r7, #8] + 80068ba: 0018 movs r0, r3 + 80068bc: f7ff fb5e bl 8005f7c + } +} + 80068c0: 46c0 nop ; (mov r8, r8) + 80068c2: 46bd mov sp, r7 + 80068c4: b004 add sp, #16 + 80068c6: bd80 pop {r7, pc} + 80068c8: 20003288 .word 0x20003288 + 80068cc: 20003278 .word 0x20003278 + +080068d0 : + * @param prio priority for the new pcb + * @return a new tcp_pcb that initially is in state CLOSED + */ +struct tcp_pcb * +tcp_alloc(u8_t prio) +{ + 80068d0: b580 push {r7, lr} + 80068d2: b084 sub sp, #16 + 80068d4: af00 add r7, sp, #0 + 80068d6: 0002 movs r2, r0 + 80068d8: 1dfb adds r3, r7, #7 + 80068da: 701a strb r2, [r3, #0] + struct tcp_pcb *pcb; + u32_t iss; + + pcb = (struct tcp_pcb *)memp_malloc(MEMP_TCP_PCB); + 80068dc: 2002 movs r0, #2 + 80068de: f7fe fa99 bl 8004e14 + 80068e2: 0003 movs r3, r0 + 80068e4: 60fb str r3, [r7, #12] + if (pcb == NULL) { + 80068e6: 68fb ldr r3, [r7, #12] + 80068e8: 2b00 cmp r3, #0 + 80068ea: d129 bne.n 8006940 + /* Try killing oldest connection in TIME-WAIT. */ + LWIP_DEBUGF(TCP_DEBUG, ("tcp_alloc: killing off oldest TIME-WAIT connection\n")); + tcp_kill_timewait(); + 80068ec: f7ff ffc0 bl 8006870 + /* Try to allocate a tcp_pcb again. */ + pcb = (struct tcp_pcb *)memp_malloc(MEMP_TCP_PCB); + 80068f0: 2002 movs r0, #2 + 80068f2: f7fe fa8f bl 8004e14 + 80068f6: 0003 movs r3, r0 + 80068f8: 60fb str r3, [r7, #12] + if (pcb == NULL) { + 80068fa: 68fb ldr r3, [r7, #12] + 80068fc: 2b00 cmp r3, #0 + 80068fe: d114 bne.n 800692a + /* Try killing active connections with lower priority than the new one. */ + LWIP_DEBUGF(TCP_DEBUG, ("tcp_alloc: killing connection with prio lower than %d\n", prio)); + tcp_kill_prio(prio); + 8006900: 1dfb adds r3, r7, #7 + 8006902: 781b ldrb r3, [r3, #0] + 8006904: 0018 movs r0, r3 + 8006906: f7ff ff69 bl 80067dc + /* Try to allocate a tcp_pcb again. */ + pcb = (struct tcp_pcb *)memp_malloc(MEMP_TCP_PCB); + 800690a: 2002 movs r0, #2 + 800690c: f7fe fa82 bl 8004e14 + 8006910: 0003 movs r3, r0 + 8006912: 60fb str r3, [r7, #12] + if (pcb != NULL) { + 8006914: 68fb ldr r3, [r7, #12] + 8006916: 2b00 cmp r3, #0 + 8006918: d007 beq.n 800692a + /* adjust err stats: memp_malloc failed twice before */ + MEMP_STATS_DEC(err, MEMP_TCP_PCB); + 800691a: 4b3c ldr r3, [pc, #240] ; (8006a0c ) + 800691c: 22cc movs r2, #204 ; 0xcc + 800691e: 5a9b ldrh r3, [r3, r2] + 8006920: 3b01 subs r3, #1 + 8006922: b299 uxth r1, r3 + 8006924: 4b39 ldr r3, [pc, #228] ; (8006a0c ) + 8006926: 22cc movs r2, #204 ; 0xcc + 8006928: 5299 strh r1, [r3, r2] + } + } + if (pcb != NULL) { + 800692a: 68fb ldr r3, [r7, #12] + 800692c: 2b00 cmp r3, #0 + 800692e: d007 beq.n 8006940 + /* adjust err stats: timewait PCB was freed above */ + MEMP_STATS_DEC(err, MEMP_TCP_PCB); + 8006930: 4b36 ldr r3, [pc, #216] ; (8006a0c ) + 8006932: 22cc movs r2, #204 ; 0xcc + 8006934: 5a9b ldrh r3, [r3, r2] + 8006936: 3b01 subs r3, #1 + 8006938: b299 uxth r1, r3 + 800693a: 4b34 ldr r3, [pc, #208] ; (8006a0c ) + 800693c: 22cc movs r2, #204 ; 0xcc + 800693e: 5299 strh r1, [r3, r2] + } + } + if (pcb != NULL) { + 8006940: 68fb ldr r3, [r7, #12] + 8006942: 2b00 cmp r3, #0 + 8006944: d05d beq.n 8006a02 + memset(pcb, 0, sizeof(struct tcp_pcb)); + 8006946: 68fb ldr r3, [r7, #12] + 8006948: 2298 movs r2, #152 ; 0x98 + 800694a: 2100 movs r1, #0 + 800694c: 0018 movs r0, r3 + 800694e: f009 f9b1 bl 800fcb4 + pcb->prio = prio; + 8006952: 68fb ldr r3, [r7, #12] + 8006954: 1dfa adds r2, r7, #7 + 8006956: 7812 ldrb r2, [r2, #0] + 8006958: 765a strb r2, [r3, #25] + pcb->snd_buf = TCP_SND_BUF; + 800695a: 68fb ldr r3, [r7, #12] + 800695c: 2266 movs r2, #102 ; 0x66 + 800695e: 492c ldr r1, [pc, #176] ; (8006a10 ) + 8006960: 5299 strh r1, [r3, r2] + pcb->snd_queuelen = 0; + 8006962: 68fb ldr r3, [r7, #12] + 8006964: 2268 movs r2, #104 ; 0x68 + 8006966: 2100 movs r1, #0 + 8006968: 5299 strh r1, [r3, r2] + pcb->rcv_wnd = TCP_WND; + 800696a: 68fb ldr r3, [r7, #12] + 800696c: 4a29 ldr r2, [pc, #164] ; (8006a14 ) + 800696e: 859a strh r2, [r3, #44] ; 0x2c + pcb->rcv_ann_wnd = TCP_WND; + 8006970: 68fb ldr r3, [r7, #12] + 8006972: 4a28 ldr r2, [pc, #160] ; (8006a14 ) + 8006974: 85da strh r2, [r3, #46] ; 0x2e + pcb->tos = 0; + 8006976: 68fb ldr r3, [r7, #12] + 8006978: 2200 movs r2, #0 + 800697a: 725a strb r2, [r3, #9] + pcb->ttl = TCP_TTL; + 800697c: 68fb ldr r3, [r7, #12] + 800697e: 22ff movs r2, #255 ; 0xff + 8006980: 729a strb r2, [r3, #10] + /* As initial send MSS, we use TCP_MSS but limit it to 536. + The send MSS is updated when an MSS option is received. */ + pcb->mss = (TCP_MSS > 536) ? 536 : TCP_MSS; + 8006982: 68fb ldr r3, [r7, #12] + 8006984: 2286 movs r2, #134 ; 0x86 + 8006986: 0092 lsls r2, r2, #2 + 8006988: 86da strh r2, [r3, #54] ; 0x36 + pcb->rto = 3000 / TCP_SLOW_INTERVAL; + 800698a: 68fb ldr r3, [r7, #12] + 800698c: 2244 movs r2, #68 ; 0x44 + 800698e: 2106 movs r1, #6 + 8006990: 5299 strh r1, [r3, r2] + pcb->sa = 0; + 8006992: 68fb ldr r3, [r7, #12] + 8006994: 2240 movs r2, #64 ; 0x40 + 8006996: 2100 movs r1, #0 + 8006998: 5299 strh r1, [r3, r2] + pcb->sv = 3000 / TCP_SLOW_INTERVAL; + 800699a: 68fb ldr r3, [r7, #12] + 800699c: 2242 movs r2, #66 ; 0x42 + 800699e: 2106 movs r1, #6 + 80069a0: 5299 strh r1, [r3, r2] + pcb->rtime = -1; + 80069a2: 68fb ldr r3, [r7, #12] + 80069a4: 2201 movs r2, #1 + 80069a6: 4252 negs r2, r2 + 80069a8: 869a strh r2, [r3, #52] ; 0x34 + pcb->cwnd = 1; + 80069aa: 68fb ldr r3, [r7, #12] + 80069ac: 224c movs r2, #76 ; 0x4c + 80069ae: 2101 movs r1, #1 + 80069b0: 5299 strh r1, [r3, r2] + iss = tcp_next_iss(); + 80069b2: f000 f8cf bl 8006b54 + 80069b6: 0003 movs r3, r0 + 80069b8: 60bb str r3, [r7, #8] + pcb->snd_wl2 = iss; + 80069ba: 68fb ldr r3, [r7, #12] + 80069bc: 68ba ldr r2, [r7, #8] + 80069be: 659a str r2, [r3, #88] ; 0x58 + pcb->snd_nxt = iss; + 80069c0: 68fb ldr r3, [r7, #12] + 80069c2: 68ba ldr r2, [r7, #8] + 80069c4: 651a str r2, [r3, #80] ; 0x50 + pcb->lastack = iss; + 80069c6: 68fb ldr r3, [r7, #12] + 80069c8: 68ba ldr r2, [r7, #8] + 80069ca: 649a str r2, [r3, #72] ; 0x48 + pcb->snd_lbb = iss; + 80069cc: 68fb ldr r3, [r7, #12] + 80069ce: 68ba ldr r2, [r7, #8] + 80069d0: 65da str r2, [r3, #92] ; 0x5c + pcb->tmr = tcp_ticks; + 80069d2: 4b11 ldr r3, [pc, #68] ; (8006a18 ) + 80069d4: 681a ldr r2, [r3, #0] + 80069d6: 68fb ldr r3, [r7, #12] + 80069d8: 625a str r2, [r3, #36] ; 0x24 + pcb->last_timer = tcp_timer_ctr; + 80069da: 4b10 ldr r3, [pc, #64] ; (8006a1c ) + 80069dc: 7819 ldrb r1, [r3, #0] + 80069de: 68fb ldr r3, [r7, #12] + 80069e0: 2221 movs r2, #33 ; 0x21 + 80069e2: 5499 strb r1, [r3, r2] + + pcb->polltmr = 0; + 80069e4: 68fb ldr r3, [r7, #12] + 80069e6: 2200 movs r2, #0 + 80069e8: 77da strb r2, [r3, #31] + +#if LWIP_CALLBACK_API + pcb->recv = tcp_recv_null; + 80069ea: 68fb ldr r3, [r7, #12] + 80069ec: 2180 movs r1, #128 ; 0x80 + 80069ee: 4a0c ldr r2, [pc, #48] ; (8006a20 ) + 80069f0: 505a str r2, [r3, r1] +#endif /* LWIP_CALLBACK_API */ + + /* Init KEEPALIVE timer */ + pcb->keep_idle = TCP_KEEPIDLE_DEFAULT; + 80069f2: 68fb ldr r3, [r7, #12] + 80069f4: 2290 movs r2, #144 ; 0x90 + 80069f6: 490b ldr r1, [pc, #44] ; (8006a24 ) + 80069f8: 5099 str r1, [r3, r2] +#if LWIP_TCP_KEEPALIVE + pcb->keep_intvl = TCP_KEEPINTVL_DEFAULT; + pcb->keep_cnt = TCP_KEEPCNT_DEFAULT; +#endif /* LWIP_TCP_KEEPALIVE */ + + pcb->keep_cnt_sent = 0; + 80069fa: 68fb ldr r3, [r7, #12] + 80069fc: 2296 movs r2, #150 ; 0x96 + 80069fe: 2100 movs r1, #0 + 8006a00: 5499 strb r1, [r3, r2] + } + return pcb; + 8006a02: 68fb ldr r3, [r7, #12] +} + 8006a04: 0018 movs r0, r3 + 8006a06: 46bd mov sp, r7 + 8006a08: b004 add sp, #16 + 8006a0a: bd80 pop {r7, pc} + 8006a0c: 20003158 .word 0x20003158 + 8006a10: 00000b68 .word 0x00000b68 + 8006a14: 000016d0 .word 0x000016d0 + 8006a18: 20003278 .word 0x20003278 + 8006a1c: 20002279 .word 0x20002279 + 8006a20: 0800678d .word 0x0800678d + 8006a24: 006ddd00 .word 0x006ddd00 + +08006a28 : + * + * @param pcb tcp_pcb to purge. The pcb itself is not deallocated! + */ +void +tcp_pcb_purge(struct tcp_pcb *pcb) +{ + 8006a28: b580 push {r7, lr} + 8006a2a: b082 sub sp, #8 + 8006a2c: af00 add r7, sp, #0 + 8006a2e: 6078 str r0, [r7, #4] + if (pcb->state != CLOSED && + 8006a30: 687b ldr r3, [r7, #4] + 8006a32: 7e1b ldrb r3, [r3, #24] + 8006a34: 2b00 cmp r3, #0 + 8006a36: d034 beq.n 8006aa2 + pcb->state != TIME_WAIT && + 8006a38: 687b ldr r3, [r7, #4] + 8006a3a: 7e1b ldrb r3, [r3, #24] + if (pcb->state != CLOSED && + 8006a3c: 2b0a cmp r3, #10 + 8006a3e: d030 beq.n 8006aa2 + pcb->state != LISTEN) { + 8006a40: 687b ldr r3, [r7, #4] + 8006a42: 7e1b ldrb r3, [r3, #24] + pcb->state != TIME_WAIT && + 8006a44: 2b01 cmp r3, #1 + 8006a46: d02c beq.n 8006aa2 + } + } +#endif /* TCP_LISTEN_BACKLOG */ + + + if (pcb->refused_data != NULL) { + 8006a48: 687b ldr r3, [r7, #4] + 8006a4a: 6f9b ldr r3, [r3, #120] ; 0x78 + 8006a4c: 2b00 cmp r3, #0 + 8006a4e: d007 beq.n 8006a60 + LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge: data left on ->refused_data\n")); + pbuf_free(pcb->refused_data); + 8006a50: 687b ldr r3, [r7, #4] + 8006a52: 6f9b ldr r3, [r3, #120] ; 0x78 + 8006a54: 0018 movs r0, r3 + 8006a56: f7fe fe25 bl 80056a4 + pcb->refused_data = NULL; + 8006a5a: 687b ldr r3, [r7, #4] + 8006a5c: 2200 movs r2, #0 + 8006a5e: 679a str r2, [r3, #120] ; 0x78 + } +#if TCP_QUEUE_OOSEQ + if (pcb->ooseq != NULL) { + LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge: data left on ->ooseq\n")); + } + tcp_segs_free(pcb->ooseq); + 8006a60: 687b ldr r3, [r7, #4] + 8006a62: 6f5b ldr r3, [r3, #116] ; 0x74 + 8006a64: 0018 movs r0, r3 + 8006a66: f7ff fe45 bl 80066f4 + pcb->ooseq = NULL; + 8006a6a: 687b ldr r3, [r7, #4] + 8006a6c: 2200 movs r2, #0 + 8006a6e: 675a str r2, [r3, #116] ; 0x74 +#endif /* TCP_QUEUE_OOSEQ */ + + /* Stop the retransmission timer as it will expect data on unacked + queue if it fires */ + pcb->rtime = -1; + 8006a70: 687b ldr r3, [r7, #4] + 8006a72: 2201 movs r2, #1 + 8006a74: 4252 negs r2, r2 + 8006a76: 869a strh r2, [r3, #52] ; 0x34 + + tcp_segs_free(pcb->unsent); + 8006a78: 687b ldr r3, [r7, #4] + 8006a7a: 6edb ldr r3, [r3, #108] ; 0x6c + 8006a7c: 0018 movs r0, r3 + 8006a7e: f7ff fe39 bl 80066f4 + tcp_segs_free(pcb->unacked); + 8006a82: 687b ldr r3, [r7, #4] + 8006a84: 6f1b ldr r3, [r3, #112] ; 0x70 + 8006a86: 0018 movs r0, r3 + 8006a88: f7ff fe34 bl 80066f4 + pcb->unacked = pcb->unsent = NULL; + 8006a8c: 687b ldr r3, [r7, #4] + 8006a8e: 2200 movs r2, #0 + 8006a90: 66da str r2, [r3, #108] ; 0x6c + 8006a92: 687b ldr r3, [r7, #4] + 8006a94: 6eda ldr r2, [r3, #108] ; 0x6c + 8006a96: 687b ldr r3, [r7, #4] + 8006a98: 671a str r2, [r3, #112] ; 0x70 +#if TCP_OVERSIZE + pcb->unsent_oversize = 0; + 8006a9a: 687b ldr r3, [r7, #4] + 8006a9c: 226a movs r2, #106 ; 0x6a + 8006a9e: 2100 movs r1, #0 + 8006aa0: 5299 strh r1, [r3, r2] +#endif /* TCP_OVERSIZE */ + } +} + 8006aa2: 46c0 nop ; (mov r8, r8) + 8006aa4: 46bd mov sp, r7 + 8006aa6: b002 add sp, #8 + 8006aa8: bd80 pop {r7, pc} + ... + +08006aac : + * @param pcblist PCB list to purge. + * @param pcb tcp_pcb to purge. The pcb itself is NOT deallocated! + */ +void +tcp_pcb_remove(struct tcp_pcb **pcblist, struct tcp_pcb *pcb) +{ + 8006aac: b580 push {r7, lr} + 8006aae: b082 sub sp, #8 + 8006ab0: af00 add r7, sp, #0 + 8006ab2: 6078 str r0, [r7, #4] + 8006ab4: 6039 str r1, [r7, #0] + TCP_RMV(pcblist, pcb); + 8006ab6: 687b ldr r3, [r7, #4] + 8006ab8: 681b ldr r3, [r3, #0] + 8006aba: 683a ldr r2, [r7, #0] + 8006abc: 429a cmp r2, r3 + 8006abe: d105 bne.n 8006acc + 8006ac0: 687b ldr r3, [r7, #4] + 8006ac2: 681b ldr r3, [r3, #0] + 8006ac4: 68da ldr r2, [r3, #12] + 8006ac6: 687b ldr r3, [r7, #4] + 8006ac8: 601a str r2, [r3, #0] + 8006aca: e019 b.n 8006b00 + 8006acc: 687b ldr r3, [r7, #4] + 8006ace: 681a ldr r2, [r3, #0] + 8006ad0: 4b1f ldr r3, [pc, #124] ; (8006b50 ) + 8006ad2: 601a str r2, [r3, #0] + 8006ad4: e010 b.n 8006af8 + 8006ad6: 4b1e ldr r3, [pc, #120] ; (8006b50 ) + 8006ad8: 681b ldr r3, [r3, #0] + 8006ada: 68db ldr r3, [r3, #12] + 8006adc: 683a ldr r2, [r7, #0] + 8006ade: 429a cmp r2, r3 + 8006ae0: d105 bne.n 8006aee + 8006ae2: 4b1b ldr r3, [pc, #108] ; (8006b50 ) + 8006ae4: 681b ldr r3, [r3, #0] + 8006ae6: 683a ldr r2, [r7, #0] + 8006ae8: 68d2 ldr r2, [r2, #12] + 8006aea: 60da str r2, [r3, #12] + 8006aec: e008 b.n 8006b00 + 8006aee: 4b18 ldr r3, [pc, #96] ; (8006b50 ) + 8006af0: 681b ldr r3, [r3, #0] + 8006af2: 68da ldr r2, [r3, #12] + 8006af4: 4b16 ldr r3, [pc, #88] ; (8006b50 ) + 8006af6: 601a str r2, [r3, #0] + 8006af8: 4b15 ldr r3, [pc, #84] ; (8006b50 ) + 8006afa: 681b ldr r3, [r3, #0] + 8006afc: 2b00 cmp r3, #0 + 8006afe: d1ea bne.n 8006ad6 + 8006b00: 683b ldr r3, [r7, #0] + 8006b02: 2200 movs r2, #0 + 8006b04: 60da str r2, [r3, #12] + + tcp_pcb_purge(pcb); + 8006b06: 683b ldr r3, [r7, #0] + 8006b08: 0018 movs r0, r3 + 8006b0a: f7ff ff8d bl 8006a28 + + /* if there is an outstanding delayed ACKs, send it */ + if (pcb->state != TIME_WAIT && + 8006b0e: 683b ldr r3, [r7, #0] + 8006b10: 7e1b ldrb r3, [r3, #24] + 8006b12: 2b0a cmp r3, #10 + 8006b14: d014 beq.n 8006b40 + pcb->state != LISTEN && + 8006b16: 683b ldr r3, [r7, #0] + 8006b18: 7e1b ldrb r3, [r3, #24] + if (pcb->state != TIME_WAIT && + 8006b1a: 2b01 cmp r3, #1 + 8006b1c: d010 beq.n 8006b40 + pcb->flags & TF_ACK_DELAY) { + 8006b1e: 683b ldr r3, [r7, #0] + 8006b20: 7f9b ldrb r3, [r3, #30] + 8006b22: 001a movs r2, r3 + 8006b24: 2301 movs r3, #1 + 8006b26: 4013 ands r3, r2 + pcb->state != LISTEN && + 8006b28: d00a beq.n 8006b40 + pcb->flags |= TF_ACK_NOW; + 8006b2a: 683b ldr r3, [r7, #0] + 8006b2c: 7f9b ldrb r3, [r3, #30] + 8006b2e: 2202 movs r2, #2 + 8006b30: 4313 orrs r3, r2 + 8006b32: b2da uxtb r2, r3 + 8006b34: 683b ldr r3, [r7, #0] + 8006b36: 779a strb r2, [r3, #30] + tcp_output(pcb); + 8006b38: 683b ldr r3, [r7, #0] + 8006b3a: 0018 movs r0, r3 + 8006b3c: f002 ff68 bl 8009a10 +#if TCP_QUEUE_OOSEQ + LWIP_ASSERT("ooseq segments leaking", pcb->ooseq == NULL); +#endif /* TCP_QUEUE_OOSEQ */ + } + + pcb->state = CLOSED; + 8006b40: 683b ldr r3, [r7, #0] + 8006b42: 2200 movs r2, #0 + 8006b44: 761a strb r2, [r3, #24] + + LWIP_ASSERT("tcp_pcb_remove: tcp_pcbs_sane()", tcp_pcbs_sane()); +} + 8006b46: 46c0 nop ; (mov r8, r8) + 8006b48: 46bd mov sp, r7 + 8006b4a: b002 add sp, #8 + 8006b4c: bd80 pop {r7, pc} + 8006b4e: 46c0 nop ; (mov r8, r8) + 8006b50: 20003280 .word 0x20003280 + +08006b54 : + * + * @return u32_t pseudo random sequence number + */ +u32_t +tcp_next_iss(void) +{ + 8006b54: b580 push {r7, lr} + 8006b56: af00 add r7, sp, #0 + static u32_t iss = 6510; + + iss += tcp_ticks; /* XXX */ + 8006b58: 4b05 ldr r3, [pc, #20] ; (8006b70 ) + 8006b5a: 681a ldr r2, [r3, #0] + 8006b5c: 4b05 ldr r3, [pc, #20] ; (8006b74 ) + 8006b5e: 681b ldr r3, [r3, #0] + 8006b60: 18d2 adds r2, r2, r3 + 8006b62: 4b03 ldr r3, [pc, #12] ; (8006b70 ) + 8006b64: 601a str r2, [r3, #0] + return iss; + 8006b66: 4b02 ldr r3, [pc, #8] ; (8006b70 ) + 8006b68: 681b ldr r3, [r3, #0] +} + 8006b6a: 0018 movs r0, r3 + 8006b6c: 46bd mov sp, r7 + 8006b6e: bd80 pop {r7, pc} + 8006b70: 20000010 .word 0x20000010 + 8006b74: 20003278 .word 0x20003278 + +08006b78 : + * by using ip_route to determin the netif used to send to the address and + * calculating the minimum of TCP_MSS and that netif's mtu (if set). + */ +u16_t +tcp_eff_send_mss(u16_t sendmss, ip_addr_t *addr) +{ + 8006b78: b590 push {r4, r7, lr} + 8006b7a: b085 sub sp, #20 + 8006b7c: af00 add r7, sp, #0 + 8006b7e: 0002 movs r2, r0 + 8006b80: 6039 str r1, [r7, #0] + 8006b82: 1dbb adds r3, r7, #6 + 8006b84: 801a strh r2, [r3, #0] + u16_t mss_s; + struct netif *outif; + + outif = ip_route(addr); + 8006b86: 683b ldr r3, [r7, #0] + 8006b88: 0018 movs r0, r3 + 8006b8a: f004 fe5d bl 800b848 + 8006b8e: 0003 movs r3, r0 + 8006b90: 60fb str r3, [r7, #12] + if ((outif != NULL) && (outif->mtu != 0)) { + 8006b92: 68fb ldr r3, [r7, #12] + 8006b94: 2b00 cmp r3, #0 + 8006b96: d014 beq.n 8006bc2 + 8006b98: 68fb ldr r3, [r7, #12] + 8006b9a: 8c1b ldrh r3, [r3, #32] + 8006b9c: 2b00 cmp r3, #0 + 8006b9e: d010 beq.n 8006bc2 + mss_s = outif->mtu - IP_HLEN - TCP_HLEN; + 8006ba0: 68fb ldr r3, [r7, #12] + 8006ba2: 8c1a ldrh r2, [r3, #32] + 8006ba4: 210a movs r1, #10 + 8006ba6: 187b adds r3, r7, r1 + 8006ba8: 3a28 subs r2, #40 ; 0x28 + 8006baa: 801a strh r2, [r3, #0] + /* RFC 1122, chap 4.2.2.6: + * Eff.snd.MSS = min(SendMSS+20, MMS_S) - TCPhdrsize - IPoptionsize + * We correct for TCP options in tcp_write(), and don't support IP options. + */ + sendmss = LWIP_MIN(sendmss, mss_s); + 8006bac: 1dba adds r2, r7, #6 + 8006bae: 187b adds r3, r7, r1 + 8006bb0: 1db9 adds r1, r7, #6 + 8006bb2: 880c ldrh r4, [r1, #0] + 8006bb4: 881b ldrh r3, [r3, #0] + 8006bb6: b298 uxth r0, r3 + 8006bb8: b2a1 uxth r1, r4 + 8006bba: 4288 cmp r0, r1 + 8006bbc: d900 bls.n 8006bc0 + 8006bbe: 1c23 adds r3, r4, #0 + 8006bc0: 8013 strh r3, [r2, #0] + } + return sendmss; + 8006bc2: 1dbb adds r3, r7, #6 + 8006bc4: 881b ldrh r3, [r3, #0] +} + 8006bc6: 0018 movs r0, r3 + 8006bc8: 46bd mov sp, r7 + 8006bca: b005 add sp, #20 + 8006bcc: bd90 pop {r4, r7, pc} + ... + +08006bd0 : + * @param p received TCP segment to process (p->payload pointing to the IP header) + * @param inp network interface on which this segment was received + */ +void +tcp_input(struct pbuf *p, struct netif *inp) +{ + 8006bd0: b5b0 push {r4, r5, r7, lr} + 8006bd2: b088 sub sp, #32 + 8006bd4: af02 add r7, sp, #8 + 8006bd6: 6078 str r0, [r7, #4] + 8006bd8: 6039 str r1, [r7, #0] + u8_t hdrlen; + err_t err; + + PERF_START; + + TCP_STATS_INC(tcp.recv); + 8006bda: 4bd3 ldr r3, [pc, #844] ; (8006f28 ) + 8006bdc: 2292 movs r2, #146 ; 0x92 + 8006bde: 5a9b ldrh r3, [r3, r2] + 8006be0: 3301 adds r3, #1 + 8006be2: b299 uxth r1, r3 + 8006be4: 4bd0 ldr r3, [pc, #832] ; (8006f28 ) + 8006be6: 2292 movs r2, #146 ; 0x92 + 8006be8: 5299 strh r1, [r3, r2] + snmp_inc_tcpinsegs(); + + iphdr = (struct ip_hdr *)p->payload; + 8006bea: 687b ldr r3, [r7, #4] + 8006bec: 685a ldr r2, [r3, #4] + 8006bee: 4bcf ldr r3, [pc, #828] ; (8006f2c ) + 8006bf0: 601a str r2, [r3, #0] + tcphdr = (struct tcp_hdr *)((u8_t *)p->payload + IPH_HL(iphdr) * 4); + 8006bf2: 687b ldr r3, [r7, #4] + 8006bf4: 685a ldr r2, [r3, #4] + 8006bf6: 4bcd ldr r3, [pc, #820] ; (8006f2c ) + 8006bf8: 681b ldr r3, [r3, #0] + 8006bfa: 781b ldrb r3, [r3, #0] + 8006bfc: 0019 movs r1, r3 + 8006bfe: 230f movs r3, #15 + 8006c00: 400b ands r3, r1 + 8006c02: 009b lsls r3, r3, #2 + 8006c04: 18d2 adds r2, r2, r3 + 8006c06: 4bca ldr r3, [pc, #808] ; (8006f30 ) + 8006c08: 601a str r2, [r3, #0] +#if TCP_INPUT_DEBUG + tcp_debug_print(tcphdr); +#endif + + /* remove header from payload */ + if (pbuf_header(p, -((s16_t)(IPH_HL(iphdr) * 4))) || (p->tot_len < sizeof(struct tcp_hdr))) { + 8006c0a: 4bc8 ldr r3, [pc, #800] ; (8006f2c ) + 8006c0c: 681b ldr r3, [r3, #0] + 8006c0e: 781b ldrb r3, [r3, #0] + 8006c10: b29b uxth r3, r3 + 8006c12: 220f movs r2, #15 + 8006c14: 4013 ands r3, r2 + 8006c16: b29b uxth r3, r3 + 8006c18: 009b lsls r3, r3, #2 + 8006c1a: b29b uxth r3, r3 + 8006c1c: 425b negs r3, r3 + 8006c1e: b29b uxth r3, r3 + 8006c20: b21a sxth r2, r3 + 8006c22: 687b ldr r3, [r7, #4] + 8006c24: 0011 movs r1, r2 + 8006c26: 0018 movs r0, r3 + 8006c28: f7fe fcb5 bl 8005596 + 8006c2c: 1e03 subs r3, r0, #0 + 8006c2e: d103 bne.n 8006c38 + 8006c30: 687b ldr r3, [r7, #4] + 8006c32: 891b ldrh r3, [r3, #8] + 8006c34: 2b13 cmp r3, #19 + 8006c36: d809 bhi.n 8006c4c + /* drop short packets */ + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: short packet (%"U16_F" bytes) discarded\n", p->tot_len)); + TCP_STATS_INC(tcp.lenerr); + 8006c38: 4bbb ldr r3, [pc, #748] ; (8006f28 ) + 8006c3a: 229a movs r2, #154 ; 0x9a + 8006c3c: 5a9b ldrh r3, [r3, r2] + 8006c3e: 3301 adds r3, #1 + 8006c40: b299 uxth r1, r3 + 8006c42: 4bb9 ldr r3, [pc, #740] ; (8006f28 ) + 8006c44: 229a movs r2, #154 ; 0x9a + 8006c46: 5299 strh r1, [r3, r2] + goto dropped; + 8006c48: f000 fbf4 bl 8007434 + } + + /* Don't even process incoming broadcasts/multicasts. */ + if (ip_addr_isbroadcast(¤t_iphdr_dest, inp) || + 8006c4c: 4bb9 ldr r3, [pc, #740] ; (8006f34 ) + 8006c4e: 681b ldr r3, [r3, #0] + 8006c50: 683a ldr r2, [r7, #0] + 8006c52: 0011 movs r1, r2 + 8006c54: 0018 movs r0, r3 + 8006c56: f005 fa11 bl 800c07c + 8006c5a: 1e03 subs r3, r0, #0 + 8006c5c: d105 bne.n 8006c6a + ip_addr_ismulticast(¤t_iphdr_dest)) { + 8006c5e: 4bb5 ldr r3, [pc, #724] ; (8006f34 ) + 8006c60: 681b ldr r3, [r3, #0] + 8006c62: 22f0 movs r2, #240 ; 0xf0 + 8006c64: 4013 ands r3, r2 + if (ip_addr_isbroadcast(¤t_iphdr_dest, inp) || + 8006c66: 2be0 cmp r3, #224 ; 0xe0 + 8006c68: d109 bne.n 8006c7e + TCP_STATS_INC(tcp.proterr); + 8006c6a: 4baf ldr r3, [pc, #700] ; (8006f28 ) + 8006c6c: 22a0 movs r2, #160 ; 0xa0 + 8006c6e: 5a9b ldrh r3, [r3, r2] + 8006c70: 3301 adds r3, #1 + 8006c72: b299 uxth r1, r3 + 8006c74: 4bac ldr r3, [pc, #688] ; (8006f28 ) + 8006c76: 22a0 movs r2, #160 ; 0xa0 + 8006c78: 5299 strh r1, [r3, r2] + goto dropped; + 8006c7a: f000 fbdb bl 8007434 + } + +#if CHECKSUM_CHECK_TCP + /* Verify TCP checksum. */ + if (inet_chksum_pseudo(p, ip_current_src_addr(), ip_current_dest_addr(), + 8006c7e: 687b ldr r3, [r7, #4] + 8006c80: 891b ldrh r3, [r3, #8] + 8006c82: 4aac ldr r2, [pc, #688] ; (8006f34 ) + 8006c84: 49ac ldr r1, [pc, #688] ; (8006f38 ) + 8006c86: 6878 ldr r0, [r7, #4] + 8006c88: 9300 str r3, [sp, #0] + 8006c8a: 2306 movs r3, #6 + 8006c8c: f004 fcd5 bl 800b63a + 8006c90: 1e03 subs r3, r0, #0 + 8006c92: d009 beq.n 8006ca8 + inet_chksum_pseudo(p, ip_current_src_addr(), ip_current_dest_addr(), + IP_PROTO_TCP, p->tot_len))); +#if TCP_DEBUG + tcp_debug_print(tcphdr); +#endif /* TCP_DEBUG */ + TCP_STATS_INC(tcp.chkerr); + 8006c94: 4ba4 ldr r3, [pc, #656] ; (8006f28 ) + 8006c96: 2298 movs r2, #152 ; 0x98 + 8006c98: 5a9b ldrh r3, [r3, r2] + 8006c9a: 3301 adds r3, #1 + 8006c9c: b299 uxth r1, r3 + 8006c9e: 4ba2 ldr r3, [pc, #648] ; (8006f28 ) + 8006ca0: 2298 movs r2, #152 ; 0x98 + 8006ca2: 5299 strh r1, [r3, r2] + goto dropped; + 8006ca4: f000 fbc6 bl 8007434 + } +#endif + + /* Move the payload pointer in the pbuf so that it points to the + TCP data instead of the TCP header. */ + hdrlen = TCPH_HDRLEN(tcphdr); + 8006ca8: 4ba1 ldr r3, [pc, #644] ; (8006f30 ) + 8006caa: 681b ldr r3, [r3, #0] + 8006cac: 7b1a ldrb r2, [r3, #12] + 8006cae: 7b5b ldrb r3, [r3, #13] + 8006cb0: 021b lsls r3, r3, #8 + 8006cb2: 4313 orrs r3, r2 + 8006cb4: b29b uxth r3, r3 + 8006cb6: 0018 movs r0, r3 + 8006cb8: f7fd fcc2 bl 8004640 + 8006cbc: 0003 movs r3, r0 + 8006cbe: 0b1b lsrs r3, r3, #12 + 8006cc0: b29a uxth r2, r3 + 8006cc2: 210a movs r1, #10 + 8006cc4: 187b adds r3, r7, r1 + 8006cc6: 701a strb r2, [r3, #0] + if(pbuf_header(p, -(hdrlen * 4))){ + 8006cc8: 187b adds r3, r7, r1 + 8006cca: 781b ldrb r3, [r3, #0] + 8006ccc: b29b uxth r3, r3 + 8006cce: 1c1a adds r2, r3, #0 + 8006cd0: 0392 lsls r2, r2, #14 + 8006cd2: 1ad3 subs r3, r2, r3 + 8006cd4: 009b lsls r3, r3, #2 + 8006cd6: b29b uxth r3, r3 + 8006cd8: b21a sxth r2, r3 + 8006cda: 687b ldr r3, [r7, #4] + 8006cdc: 0011 movs r1, r2 + 8006cde: 0018 movs r0, r3 + 8006ce0: f7fe fc59 bl 8005596 + 8006ce4: 1e03 subs r3, r0, #0 + 8006ce6: d009 beq.n 8006cfc + /* drop short packets */ + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: short packet\n")); + TCP_STATS_INC(tcp.lenerr); + 8006ce8: 4b8f ldr r3, [pc, #572] ; (8006f28 ) + 8006cea: 229a movs r2, #154 ; 0x9a + 8006cec: 5a9b ldrh r3, [r3, r2] + 8006cee: 3301 adds r3, #1 + 8006cf0: b299 uxth r1, r3 + 8006cf2: 4b8d ldr r3, [pc, #564] ; (8006f28 ) + 8006cf4: 229a movs r2, #154 ; 0x9a + 8006cf6: 5299 strh r1, [r3, r2] + goto dropped; + 8006cf8: f000 fb9c bl 8007434 + } + + /* Convert fields in TCP header to host byte order. */ + tcphdr->src = ntohs(tcphdr->src); + 8006cfc: 4b8c ldr r3, [pc, #560] ; (8006f30 ) + 8006cfe: 681b ldr r3, [r3, #0] + 8006d00: 781a ldrb r2, [r3, #0] + 8006d02: 785b ldrb r3, [r3, #1] + 8006d04: 021b lsls r3, r3, #8 + 8006d06: 4313 orrs r3, r2 + 8006d08: b29a uxth r2, r3 + 8006d0a: 4b89 ldr r3, [pc, #548] ; (8006f30 ) + 8006d0c: 681c ldr r4, [r3, #0] + 8006d0e: 0010 movs r0, r2 + 8006d10: f7fd fc96 bl 8004640 + 8006d14: 0003 movs r3, r0 + 8006d16: 22ff movs r2, #255 ; 0xff + 8006d18: 401a ands r2, r3 + 8006d1a: 0010 movs r0, r2 + 8006d1c: 7822 ldrb r2, [r4, #0] + 8006d1e: 2100 movs r1, #0 + 8006d20: 400a ands r2, r1 + 8006d22: 1c11 adds r1, r2, #0 + 8006d24: 1c02 adds r2, r0, #0 + 8006d26: 430a orrs r2, r1 + 8006d28: 7022 strb r2, [r4, #0] + 8006d2a: 0a1b lsrs r3, r3, #8 + 8006d2c: b299 uxth r1, r3 + 8006d2e: 7863 ldrb r3, [r4, #1] + 8006d30: 2200 movs r2, #0 + 8006d32: 4013 ands r3, r2 + 8006d34: 1c1a adds r2, r3, #0 + 8006d36: 1c0b adds r3, r1, #0 + 8006d38: 4313 orrs r3, r2 + 8006d3a: 7063 strb r3, [r4, #1] + tcphdr->dest = ntohs(tcphdr->dest); + 8006d3c: 4b7c ldr r3, [pc, #496] ; (8006f30 ) + 8006d3e: 681b ldr r3, [r3, #0] + 8006d40: 789a ldrb r2, [r3, #2] + 8006d42: 78db ldrb r3, [r3, #3] + 8006d44: 021b lsls r3, r3, #8 + 8006d46: 4313 orrs r3, r2 + 8006d48: b29a uxth r2, r3 + 8006d4a: 4b79 ldr r3, [pc, #484] ; (8006f30 ) + 8006d4c: 681c ldr r4, [r3, #0] + 8006d4e: 0010 movs r0, r2 + 8006d50: f7fd fc76 bl 8004640 + 8006d54: 0003 movs r3, r0 + 8006d56: 22ff movs r2, #255 ; 0xff + 8006d58: 401a ands r2, r3 + 8006d5a: 0010 movs r0, r2 + 8006d5c: 78a2 ldrb r2, [r4, #2] + 8006d5e: 2100 movs r1, #0 + 8006d60: 400a ands r2, r1 + 8006d62: 1c11 adds r1, r2, #0 + 8006d64: 1c02 adds r2, r0, #0 + 8006d66: 430a orrs r2, r1 + 8006d68: 70a2 strb r2, [r4, #2] + 8006d6a: 0a1b lsrs r3, r3, #8 + 8006d6c: b299 uxth r1, r3 + 8006d6e: 78e3 ldrb r3, [r4, #3] + 8006d70: 2200 movs r2, #0 + 8006d72: 4013 ands r3, r2 + 8006d74: 1c1a adds r2, r3, #0 + 8006d76: 1c0b adds r3, r1, #0 + 8006d78: 4313 orrs r3, r2 + 8006d7a: 70e3 strb r3, [r4, #3] + seqno = tcphdr->seqno = ntohl(tcphdr->seqno); + 8006d7c: 4b6c ldr r3, [pc, #432] ; (8006f30 ) + 8006d7e: 681b ldr r3, [r3, #0] + 8006d80: 791a ldrb r2, [r3, #4] + 8006d82: 7959 ldrb r1, [r3, #5] + 8006d84: 0209 lsls r1, r1, #8 + 8006d86: 430a orrs r2, r1 + 8006d88: 7999 ldrb r1, [r3, #6] + 8006d8a: 0409 lsls r1, r1, #16 + 8006d8c: 430a orrs r2, r1 + 8006d8e: 79db ldrb r3, [r3, #7] + 8006d90: 061b lsls r3, r3, #24 + 8006d92: 4313 orrs r3, r2 + 8006d94: 001a movs r2, r3 + 8006d96: 4b66 ldr r3, [pc, #408] ; (8006f30 ) + 8006d98: 681c ldr r4, [r3, #0] + 8006d9a: 0010 movs r0, r2 + 8006d9c: f7fd fc79 bl 8004692 + 8006da0: 0003 movs r3, r0 + 8006da2: 22ff movs r2, #255 ; 0xff + 8006da4: 401a ands r2, r3 + 8006da6: 0010 movs r0, r2 + 8006da8: 7922 ldrb r2, [r4, #4] + 8006daa: 2100 movs r1, #0 + 8006dac: 400a ands r2, r1 + 8006dae: 1c11 adds r1, r2, #0 + 8006db0: 1c02 adds r2, r0, #0 + 8006db2: 430a orrs r2, r1 + 8006db4: 7122 strb r2, [r4, #4] + 8006db6: 0a1a lsrs r2, r3, #8 + 8006db8: 21ff movs r1, #255 ; 0xff + 8006dba: 400a ands r2, r1 + 8006dbc: 0010 movs r0, r2 + 8006dbe: 7962 ldrb r2, [r4, #5] + 8006dc0: 2100 movs r1, #0 + 8006dc2: 400a ands r2, r1 + 8006dc4: 1c11 adds r1, r2, #0 + 8006dc6: 1c02 adds r2, r0, #0 + 8006dc8: 430a orrs r2, r1 + 8006dca: 7162 strb r2, [r4, #5] + 8006dcc: 0c1a lsrs r2, r3, #16 + 8006dce: 21ff movs r1, #255 ; 0xff + 8006dd0: 400a ands r2, r1 + 8006dd2: 0010 movs r0, r2 + 8006dd4: 79a2 ldrb r2, [r4, #6] + 8006dd6: 2100 movs r1, #0 + 8006dd8: 400a ands r2, r1 + 8006dda: 1c11 adds r1, r2, #0 + 8006ddc: 1c02 adds r2, r0, #0 + 8006dde: 430a orrs r2, r1 + 8006de0: 71a2 strb r2, [r4, #6] + 8006de2: 0e19 lsrs r1, r3, #24 + 8006de4: 79e3 ldrb r3, [r4, #7] + 8006de6: 2200 movs r2, #0 + 8006de8: 4013 ands r3, r2 + 8006dea: 1c1a adds r2, r3, #0 + 8006dec: 1c0b adds r3, r1, #0 + 8006dee: 4313 orrs r3, r2 + 8006df0: 71e3 strb r3, [r4, #7] + 8006df2: 7923 ldrb r3, [r4, #4] + 8006df4: 7962 ldrb r2, [r4, #5] + 8006df6: 0212 lsls r2, r2, #8 + 8006df8: 4313 orrs r3, r2 + 8006dfa: 79a2 ldrb r2, [r4, #6] + 8006dfc: 0412 lsls r2, r2, #16 + 8006dfe: 4313 orrs r3, r2 + 8006e00: 79e2 ldrb r2, [r4, #7] + 8006e02: 0612 lsls r2, r2, #24 + 8006e04: 4313 orrs r3, r2 + 8006e06: 001a movs r2, r3 + 8006e08: 4b4c ldr r3, [pc, #304] ; (8006f3c ) + 8006e0a: 601a str r2, [r3, #0] + ackno = tcphdr->ackno = ntohl(tcphdr->ackno); + 8006e0c: 4b48 ldr r3, [pc, #288] ; (8006f30 ) + 8006e0e: 681b ldr r3, [r3, #0] + 8006e10: 7a1a ldrb r2, [r3, #8] + 8006e12: 7a59 ldrb r1, [r3, #9] + 8006e14: 0209 lsls r1, r1, #8 + 8006e16: 430a orrs r2, r1 + 8006e18: 7a99 ldrb r1, [r3, #10] + 8006e1a: 0409 lsls r1, r1, #16 + 8006e1c: 430a orrs r2, r1 + 8006e1e: 7adb ldrb r3, [r3, #11] + 8006e20: 061b lsls r3, r3, #24 + 8006e22: 4313 orrs r3, r2 + 8006e24: 001a movs r2, r3 + 8006e26: 4b42 ldr r3, [pc, #264] ; (8006f30 ) + 8006e28: 681c ldr r4, [r3, #0] + 8006e2a: 0010 movs r0, r2 + 8006e2c: f7fd fc31 bl 8004692 + 8006e30: 0003 movs r3, r0 + 8006e32: 22ff movs r2, #255 ; 0xff + 8006e34: 401a ands r2, r3 + 8006e36: 0010 movs r0, r2 + 8006e38: 7a22 ldrb r2, [r4, #8] + 8006e3a: 2100 movs r1, #0 + 8006e3c: 400a ands r2, r1 + 8006e3e: 1c11 adds r1, r2, #0 + 8006e40: 1c02 adds r2, r0, #0 + 8006e42: 430a orrs r2, r1 + 8006e44: 7222 strb r2, [r4, #8] + 8006e46: 0a1a lsrs r2, r3, #8 + 8006e48: 21ff movs r1, #255 ; 0xff + 8006e4a: 400a ands r2, r1 + 8006e4c: 0010 movs r0, r2 + 8006e4e: 7a62 ldrb r2, [r4, #9] + 8006e50: 2100 movs r1, #0 + 8006e52: 400a ands r2, r1 + 8006e54: 1c11 adds r1, r2, #0 + 8006e56: 1c02 adds r2, r0, #0 + 8006e58: 430a orrs r2, r1 + 8006e5a: 7262 strb r2, [r4, #9] + 8006e5c: 0c1a lsrs r2, r3, #16 + 8006e5e: 21ff movs r1, #255 ; 0xff + 8006e60: 400a ands r2, r1 + 8006e62: 0010 movs r0, r2 + 8006e64: 7aa2 ldrb r2, [r4, #10] + 8006e66: 2100 movs r1, #0 + 8006e68: 400a ands r2, r1 + 8006e6a: 1c11 adds r1, r2, #0 + 8006e6c: 1c02 adds r2, r0, #0 + 8006e6e: 430a orrs r2, r1 + 8006e70: 72a2 strb r2, [r4, #10] + 8006e72: 0e19 lsrs r1, r3, #24 + 8006e74: 7ae3 ldrb r3, [r4, #11] + 8006e76: 2200 movs r2, #0 + 8006e78: 4013 ands r3, r2 + 8006e7a: 1c1a adds r2, r3, #0 + 8006e7c: 1c0b adds r3, r1, #0 + 8006e7e: 4313 orrs r3, r2 + 8006e80: 72e3 strb r3, [r4, #11] + 8006e82: 7a23 ldrb r3, [r4, #8] + 8006e84: 7a62 ldrb r2, [r4, #9] + 8006e86: 0212 lsls r2, r2, #8 + 8006e88: 4313 orrs r3, r2 + 8006e8a: 7aa2 ldrb r2, [r4, #10] + 8006e8c: 0412 lsls r2, r2, #16 + 8006e8e: 4313 orrs r3, r2 + 8006e90: 7ae2 ldrb r2, [r4, #11] + 8006e92: 0612 lsls r2, r2, #24 + 8006e94: 4313 orrs r3, r2 + 8006e96: 001a movs r2, r3 + 8006e98: 4b29 ldr r3, [pc, #164] ; (8006f40 ) + 8006e9a: 601a str r2, [r3, #0] + tcphdr->wnd = ntohs(tcphdr->wnd); + 8006e9c: 4b24 ldr r3, [pc, #144] ; (8006f30 ) + 8006e9e: 681b ldr r3, [r3, #0] + 8006ea0: 7b9a ldrb r2, [r3, #14] + 8006ea2: 7bdb ldrb r3, [r3, #15] + 8006ea4: 021b lsls r3, r3, #8 + 8006ea6: 4313 orrs r3, r2 + 8006ea8: b29a uxth r2, r3 + 8006eaa: 4b21 ldr r3, [pc, #132] ; (8006f30 ) + 8006eac: 681c ldr r4, [r3, #0] + 8006eae: 0010 movs r0, r2 + 8006eb0: f7fd fbc6 bl 8004640 + 8006eb4: 0003 movs r3, r0 + 8006eb6: 22ff movs r2, #255 ; 0xff + 8006eb8: 401a ands r2, r3 + 8006eba: 0010 movs r0, r2 + 8006ebc: 7ba2 ldrb r2, [r4, #14] + 8006ebe: 2100 movs r1, #0 + 8006ec0: 400a ands r2, r1 + 8006ec2: 1c11 adds r1, r2, #0 + 8006ec4: 1c02 adds r2, r0, #0 + 8006ec6: 430a orrs r2, r1 + 8006ec8: 73a2 strb r2, [r4, #14] + 8006eca: 0a1b lsrs r3, r3, #8 + 8006ecc: b299 uxth r1, r3 + 8006ece: 7be3 ldrb r3, [r4, #15] + 8006ed0: 2200 movs r2, #0 + 8006ed2: 4013 ands r3, r2 + 8006ed4: 1c1a adds r2, r3, #0 + 8006ed6: 1c0b adds r3, r1, #0 + 8006ed8: 4313 orrs r3, r2 + 8006eda: 73e3 strb r3, [r4, #15] + + flags = TCPH_FLAGS(tcphdr); + 8006edc: 4b14 ldr r3, [pc, #80] ; (8006f30 ) + 8006ede: 681b ldr r3, [r3, #0] + 8006ee0: 7b1a ldrb r2, [r3, #12] + 8006ee2: 7b5b ldrb r3, [r3, #13] + 8006ee4: 021b lsls r3, r3, #8 + 8006ee6: 4313 orrs r3, r2 + 8006ee8: b29b uxth r3, r3 + 8006eea: 0018 movs r0, r3 + 8006eec: f7fd fba8 bl 8004640 + 8006ef0: 0003 movs r3, r0 + 8006ef2: b2db uxtb r3, r3 + 8006ef4: 223f movs r2, #63 ; 0x3f + 8006ef6: 4013 ands r3, r2 + 8006ef8: b2da uxtb r2, r3 + 8006efa: 4b12 ldr r3, [pc, #72] ; (8006f44 ) + 8006efc: 701a strb r2, [r3, #0] + tcplen = p->tot_len + ((flags & (TCP_FIN | TCP_SYN)) ? 1 : 0); + 8006efe: 687b ldr r3, [r7, #4] + 8006f00: 891a ldrh r2, [r3, #8] + 8006f02: 4b10 ldr r3, [pc, #64] ; (8006f44 ) + 8006f04: 781b ldrb r3, [r3, #0] + 8006f06: 0019 movs r1, r3 + 8006f08: 2303 movs r3, #3 + 8006f0a: 400b ands r3, r1 + 8006f0c: 1e59 subs r1, r3, #1 + 8006f0e: 418b sbcs r3, r1 + 8006f10: b2db uxtb r3, r3 + 8006f12: b29b uxth r3, r3 + 8006f14: 18d3 adds r3, r2, r3 + 8006f16: b29a uxth r2, r3 + 8006f18: 4b0b ldr r3, [pc, #44] ; (8006f48 ) + 8006f1a: 801a strh r2, [r3, #0] + + /* Demultiplex an incoming segment. First, we check if it is destined + for an active connection. */ + prev = NULL; + 8006f1c: 2300 movs r3, #0 + 8006f1e: 613b str r3, [r7, #16] + + + for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) { + 8006f20: 4b0a ldr r3, [pc, #40] ; (8006f4c ) + 8006f22: 681b ldr r3, [r3, #0] + 8006f24: 617b str r3, [r7, #20] + 8006f26: e049 b.n 8006fbc + 8006f28: 20003158 .word 0x20003158 + 8006f2c: 20002290 .word 0x20002290 + 8006f30: 2000228c .word 0x2000228c + 8006f34: 2000329c .word 0x2000329c + 8006f38: 20003294 .word 0x20003294 + 8006f3c: 20002294 .word 0x20002294 + 8006f40: 20002298 .word 0x20002298 + 8006f44: 2000229c .word 0x2000229c + 8006f48: 2000229e .word 0x2000229e + 8006f4c: 20003274 .word 0x20003274 + LWIP_ASSERT("tcp_input: active pcb->state != CLOSED", pcb->state != CLOSED); + LWIP_ASSERT("tcp_input: active pcb->state != TIME-WAIT", pcb->state != TIME_WAIT); + LWIP_ASSERT("tcp_input: active pcb->state != LISTEN", pcb->state != LISTEN); + if (pcb->remote_port == tcphdr->src && + 8006f50: 697b ldr r3, [r7, #20] + 8006f52: 8b9a ldrh r2, [r3, #28] + 8006f54: 4bcc ldr r3, [pc, #816] ; (8007288 ) + 8006f56: 681b ldr r3, [r3, #0] + 8006f58: 7819 ldrb r1, [r3, #0] + 8006f5a: 785b ldrb r3, [r3, #1] + 8006f5c: 021b lsls r3, r3, #8 + 8006f5e: 430b orrs r3, r1 + 8006f60: b29b uxth r3, r3 + 8006f62: 429a cmp r2, r3 + 8006f64: d125 bne.n 8006fb2 + pcb->local_port == tcphdr->dest && + 8006f66: 697b ldr r3, [r7, #20] + 8006f68: 8b5a ldrh r2, [r3, #26] + 8006f6a: 4bc7 ldr r3, [pc, #796] ; (8007288 ) + 8006f6c: 681b ldr r3, [r3, #0] + 8006f6e: 7899 ldrb r1, [r3, #2] + 8006f70: 78db ldrb r3, [r3, #3] + 8006f72: 021b lsls r3, r3, #8 + 8006f74: 430b orrs r3, r1 + 8006f76: b29b uxth r3, r3 + if (pcb->remote_port == tcphdr->src && + 8006f78: 429a cmp r2, r3 + 8006f7a: d11a bne.n 8006fb2 + ip_addr_cmp(&(pcb->remote_ip), ¤t_iphdr_src) && + 8006f7c: 697b ldr r3, [r7, #20] + 8006f7e: 685a ldr r2, [r3, #4] + 8006f80: 4bc2 ldr r3, [pc, #776] ; (800728c ) + 8006f82: 681b ldr r3, [r3, #0] + pcb->local_port == tcphdr->dest && + 8006f84: 429a cmp r2, r3 + 8006f86: d114 bne.n 8006fb2 + ip_addr_cmp(&(pcb->local_ip), ¤t_iphdr_dest)) { + 8006f88: 697b ldr r3, [r7, #20] + 8006f8a: 681a ldr r2, [r3, #0] + 8006f8c: 4bc0 ldr r3, [pc, #768] ; (8007290 ) + 8006f8e: 681b ldr r3, [r3, #0] + ip_addr_cmp(&(pcb->remote_ip), ¤t_iphdr_src) && + 8006f90: 429a cmp r2, r3 + 8006f92: d10e bne.n 8006fb2 + + /* Move this PCB to the front of the list so that subsequent + lookups will be faster (we exploit locality in TCP segment + arrivals). */ + LWIP_ASSERT("tcp_input: pcb->next != pcb (before cache)", pcb->next != pcb); + if (prev != NULL) { + 8006f94: 693b ldr r3, [r7, #16] + 8006f96: 2b00 cmp r3, #0 + 8006f98: d014 beq.n 8006fc4 + prev->next = pcb->next; + 8006f9a: 697b ldr r3, [r7, #20] + 8006f9c: 68da ldr r2, [r3, #12] + 8006f9e: 693b ldr r3, [r7, #16] + 8006fa0: 60da str r2, [r3, #12] + pcb->next = tcp_active_pcbs; + 8006fa2: 4bbc ldr r3, [pc, #752] ; (8007294 ) + 8006fa4: 681a ldr r2, [r3, #0] + 8006fa6: 697b ldr r3, [r7, #20] + 8006fa8: 60da str r2, [r3, #12] + tcp_active_pcbs = pcb; + 8006faa: 4bba ldr r3, [pc, #744] ; (8007294 ) + 8006fac: 697a ldr r2, [r7, #20] + 8006fae: 601a str r2, [r3, #0] + } + LWIP_ASSERT("tcp_input: pcb->next != pcb (after cache)", pcb->next != pcb); + break; + 8006fb0: e008 b.n 8006fc4 + } + prev = pcb; + 8006fb2: 697b ldr r3, [r7, #20] + 8006fb4: 613b str r3, [r7, #16] + for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) { + 8006fb6: 697b ldr r3, [r7, #20] + 8006fb8: 68db ldr r3, [r3, #12] + 8006fba: 617b str r3, [r7, #20] + 8006fbc: 697b ldr r3, [r7, #20] + 8006fbe: 2b00 cmp r3, #0 + 8006fc0: d1c6 bne.n 8006f50 + 8006fc2: e000 b.n 8006fc6 + break; + 8006fc4: 46c0 nop ; (mov r8, r8) + } + + if (pcb == NULL) { + 8006fc6: 697b ldr r3, [r7, #20] + 8006fc8: 2b00 cmp r3, #0 + 8006fca: d000 beq.n 8006fce + 8006fcc: e074 b.n 80070b8 + /* If it did not go to an active connection, we check the connections + in the TIME-WAIT state. */ + for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) { + 8006fce: 4bb2 ldr r3, [pc, #712] ; (8007298 ) + 8006fd0: 681b ldr r3, [r3, #0] + 8006fd2: 617b str r3, [r7, #20] + 8006fd4: e02d b.n 8007032 + LWIP_ASSERT("tcp_input: TIME-WAIT pcb->state == TIME-WAIT", pcb->state == TIME_WAIT); + if (pcb->remote_port == tcphdr->src && + 8006fd6: 697b ldr r3, [r7, #20] + 8006fd8: 8b9a ldrh r2, [r3, #28] + 8006fda: 4bab ldr r3, [pc, #684] ; (8007288 ) + 8006fdc: 681b ldr r3, [r3, #0] + 8006fde: 7819 ldrb r1, [r3, #0] + 8006fe0: 785b ldrb r3, [r3, #1] + 8006fe2: 021b lsls r3, r3, #8 + 8006fe4: 430b orrs r3, r1 + 8006fe6: b29b uxth r3, r3 + 8006fe8: 429a cmp r2, r3 + 8006fea: d11f bne.n 800702c + pcb->local_port == tcphdr->dest && + 8006fec: 697b ldr r3, [r7, #20] + 8006fee: 8b5a ldrh r2, [r3, #26] + 8006ff0: 4ba5 ldr r3, [pc, #660] ; (8007288 ) + 8006ff2: 681b ldr r3, [r3, #0] + 8006ff4: 7899 ldrb r1, [r3, #2] + 8006ff6: 78db ldrb r3, [r3, #3] + 8006ff8: 021b lsls r3, r3, #8 + 8006ffa: 430b orrs r3, r1 + 8006ffc: b29b uxth r3, r3 + if (pcb->remote_port == tcphdr->src && + 8006ffe: 429a cmp r2, r3 + 8007000: d114 bne.n 800702c + ip_addr_cmp(&(pcb->remote_ip), ¤t_iphdr_src) && + 8007002: 697b ldr r3, [r7, #20] + 8007004: 685a ldr r2, [r3, #4] + 8007006: 4ba1 ldr r3, [pc, #644] ; (800728c ) + 8007008: 681b ldr r3, [r3, #0] + pcb->local_port == tcphdr->dest && + 800700a: 429a cmp r2, r3 + 800700c: d10e bne.n 800702c + ip_addr_cmp(&(pcb->local_ip), ¤t_iphdr_dest)) { + 800700e: 697b ldr r3, [r7, #20] + 8007010: 681a ldr r2, [r3, #0] + 8007012: 4b9f ldr r3, [pc, #636] ; (8007290 ) + 8007014: 681b ldr r3, [r3, #0] + ip_addr_cmp(&(pcb->remote_ip), ¤t_iphdr_src) && + 8007016: 429a cmp r2, r3 + 8007018: d108 bne.n 800702c + /* We don't really care enough to move this PCB to the front + of the list since we are not very likely to receive that + many segments for connections in TIME-WAIT. */ + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: packed for TIME_WAITing connection.\n")); + tcp_timewait_input(pcb); + 800701a: 697b ldr r3, [r7, #20] + 800701c: 0018 movs r0, r3 + 800701e: f000 fb23 bl 8007668 + pbuf_free(p); + 8007022: 687b ldr r3, [r7, #4] + 8007024: 0018 movs r0, r3 + 8007026: f7fe fb3d bl 80056a4 + return; + 800702a: e211 b.n 8007450 + for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) { + 800702c: 697b ldr r3, [r7, #20] + 800702e: 68db ldr r3, [r3, #12] + 8007030: 617b str r3, [r7, #20] + 8007032: 697b ldr r3, [r7, #20] + 8007034: 2b00 cmp r3, #0 + 8007036: d1ce bne.n 8006fd6 + } + } + + /* Finally, if we still did not get a match, we check all PCBs that + are LISTENing for incoming connections. */ + prev = NULL; + 8007038: 2300 movs r3, #0 + 800703a: 613b str r3, [r7, #16] + for(lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next) { + 800703c: 4b97 ldr r3, [pc, #604] ; (800729c ) + 800703e: 681b ldr r3, [r3, #0] + 8007040: 60fb str r3, [r7, #12] + 8007042: e01c b.n 800707e + if (lpcb->local_port == tcphdr->dest) { + 8007044: 68fb ldr r3, [r7, #12] + 8007046: 8b5a ldrh r2, [r3, #26] + 8007048: 4b8f ldr r3, [pc, #572] ; (8007288 ) + 800704a: 681b ldr r3, [r3, #0] + 800704c: 7899 ldrb r1, [r3, #2] + 800704e: 78db ldrb r3, [r3, #3] + 8007050: 021b lsls r3, r3, #8 + 8007052: 430b orrs r3, r1 + 8007054: b29b uxth r3, r3 + 8007056: 429a cmp r2, r3 + 8007058: d10c bne.n 8007074 + /* found an ANY-match */ + lpcb_any = lpcb; + lpcb_prev = prev; + } +#else /* SO_REUSE */ + if (ip_addr_cmp(&(lpcb->local_ip), ¤t_iphdr_dest) || + 800705a: 68fb ldr r3, [r7, #12] + 800705c: 681a ldr r2, [r3, #0] + 800705e: 4b8c ldr r3, [pc, #560] ; (8007290 ) + 8007060: 681b ldr r3, [r3, #0] + 8007062: 429a cmp r2, r3 + 8007064: d00e beq.n 8007084 + ip_addr_isany(&(lpcb->local_ip))) { + 8007066: 68fb ldr r3, [r7, #12] + if (ip_addr_cmp(&(lpcb->local_ip), ¤t_iphdr_dest) || + 8007068: 2b00 cmp r3, #0 + 800706a: d00b beq.n 8007084 + ip_addr_isany(&(lpcb->local_ip))) { + 800706c: 68fb ldr r3, [r7, #12] + 800706e: 681b ldr r3, [r3, #0] + 8007070: 2b00 cmp r3, #0 + 8007072: d007 beq.n 8007084 + /* found a match */ + break; + } +#endif /* SO_REUSE */ + } + prev = (struct tcp_pcb *)lpcb; + 8007074: 68fb ldr r3, [r7, #12] + 8007076: 613b str r3, [r7, #16] + for(lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next) { + 8007078: 68fb ldr r3, [r7, #12] + 800707a: 68db ldr r3, [r3, #12] + 800707c: 60fb str r3, [r7, #12] + 800707e: 68fb ldr r3, [r7, #12] + 8007080: 2b00 cmp r3, #0 + 8007082: d1df bne.n 8007044 + /* only pass to ANY if no specific local IP has been found */ + lpcb = lpcb_any; + prev = lpcb_prev; + } +#endif /* SO_REUSE */ + if (lpcb != NULL) { + 8007084: 68fb ldr r3, [r7, #12] + 8007086: 2b00 cmp r3, #0 + 8007088: d016 beq.n 80070b8 + /* Move this PCB to the front of the list so that subsequent + lookups will be faster (we exploit locality in TCP segment + arrivals). */ + if (prev != NULL) { + 800708a: 693b ldr r3, [r7, #16] + 800708c: 2b00 cmp r3, #0 + 800708e: d00a beq.n 80070a6 + ((struct tcp_pcb_listen *)prev)->next = lpcb->next; + 8007090: 68fb ldr r3, [r7, #12] + 8007092: 68da ldr r2, [r3, #12] + 8007094: 693b ldr r3, [r7, #16] + 8007096: 60da str r2, [r3, #12] + /* our successor is the remainder of the listening list */ + lpcb->next = tcp_listen_pcbs.listen_pcbs; + 8007098: 4b80 ldr r3, [pc, #512] ; (800729c ) + 800709a: 681a ldr r2, [r3, #0] + 800709c: 68fb ldr r3, [r7, #12] + 800709e: 60da str r2, [r3, #12] + /* put this listening pcb at the head of the listening list */ + tcp_listen_pcbs.listen_pcbs = lpcb; + 80070a0: 4b7e ldr r3, [pc, #504] ; (800729c ) + 80070a2: 68fa ldr r2, [r7, #12] + 80070a4: 601a str r2, [r3, #0] + } + + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: packed for LISTENing connection.\n")); + tcp_listen_input(lpcb); + 80070a6: 68fb ldr r3, [r7, #12] + 80070a8: 0018 movs r0, r3 + 80070aa: f000 f9ed bl 8007488 + pbuf_free(p); + 80070ae: 687b ldr r3, [r7, #4] + 80070b0: 0018 movs r0, r3 + 80070b2: f7fe faf7 bl 80056a4 + return; + 80070b6: e1cb b.n 8007450 + tcp_debug_print_flags(TCPH_FLAGS(tcphdr)); + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n")); +#endif /* TCP_INPUT_DEBUG */ + + + if (pcb != NULL) { + 80070b8: 697b ldr r3, [r7, #20] + 80070ba: 2b00 cmp r3, #0 + 80070bc: d100 bne.n 80070c0 + 80070be: e176 b.n 80073ae + tcp_debug_print_state(pcb->state); +#endif /* TCP_DEBUG */ +#endif /* TCP_INPUT_DEBUG */ + + /* Set up a tcp_seg structure. */ + inseg.next = NULL; + 80070c0: 4b77 ldr r3, [pc, #476] ; (80072a0 ) + 80070c2: 2200 movs r2, #0 + 80070c4: 601a str r2, [r3, #0] + inseg.len = p->tot_len; + 80070c6: 687b ldr r3, [r7, #4] + 80070c8: 891a ldrh r2, [r3, #8] + 80070ca: 4b75 ldr r3, [pc, #468] ; (80072a0 ) + 80070cc: 811a strh r2, [r3, #8] + inseg.p = p; + 80070ce: 4b74 ldr r3, [pc, #464] ; (80072a0 ) + 80070d0: 687a ldr r2, [r7, #4] + 80070d2: 605a str r2, [r3, #4] + inseg.tcphdr = tcphdr; + 80070d4: 4b6c ldr r3, [pc, #432] ; (8007288 ) + 80070d6: 681a ldr r2, [r3, #0] + 80070d8: 4b71 ldr r3, [pc, #452] ; (80072a0 ) + 80070da: 60da str r2, [r3, #12] + + recv_data = NULL; + 80070dc: 4b71 ldr r3, [pc, #452] ; (80072a4 ) + 80070de: 2200 movs r2, #0 + 80070e0: 601a str r2, [r3, #0] + recv_flags = 0; + 80070e2: 4b71 ldr r3, [pc, #452] ; (80072a8 ) + 80070e4: 2200 movs r2, #0 + 80070e6: 701a strb r2, [r3, #0] + + if (flags & TCP_PSH) { + 80070e8: 4b70 ldr r3, [pc, #448] ; (80072ac ) + 80070ea: 781b ldrb r3, [r3, #0] + 80070ec: 001a movs r2, r3 + 80070ee: 2308 movs r3, #8 + 80070f0: 4013 ands r3, r2 + 80070f2: d006 beq.n 8007102 + p->flags |= PBUF_FLAG_PUSH; + 80070f4: 687b ldr r3, [r7, #4] + 80070f6: 7b5b ldrb r3, [r3, #13] + 80070f8: 2201 movs r2, #1 + 80070fa: 4313 orrs r3, r2 + 80070fc: b2da uxtb r2, r3 + 80070fe: 687b ldr r3, [r7, #4] + 8007100: 735a strb r2, [r3, #13] + } + + /* If there is data which was previously "refused" by upper layer */ + if (pcb->refused_data != NULL) { + 8007102: 697b ldr r3, [r7, #20] + 8007104: 6f9b ldr r3, [r3, #120] ; 0x78 + 8007106: 2b00 cmp r3, #0 + 8007108: d017 beq.n 800713a + if ((tcp_process_refused_data(pcb) == ERR_ABRT) || + 800710a: 697b ldr r3, [r7, #20] + 800710c: 0018 movs r0, r3 + 800710e: f7ff fa79 bl 8006604 + 8007112: 0003 movs r3, r0 + 8007114: 330a adds r3, #10 + 8007116: d007 beq.n 8007128 + ((pcb->refused_data != NULL) && (tcplen > 0))) { + 8007118: 697b ldr r3, [r7, #20] + 800711a: 6f9b ldr r3, [r3, #120] ; 0x78 + if ((tcp_process_refused_data(pcb) == ERR_ABRT) || + 800711c: 2b00 cmp r3, #0 + 800711e: d00c beq.n 800713a + ((pcb->refused_data != NULL) && (tcplen > 0))) { + 8007120: 4b63 ldr r3, [pc, #396] ; (80072b0 ) + 8007122: 881b ldrh r3, [r3, #0] + 8007124: 2b00 cmp r3, #0 + 8007126: d008 beq.n 800713a + /* pcb has been aborted or refused data is still refused and the new + segment contains data */ + TCP_STATS_INC(tcp.drop); + 8007128: 4b62 ldr r3, [pc, #392] ; (80072b4 ) + 800712a: 2296 movs r2, #150 ; 0x96 + 800712c: 5a9b ldrh r3, [r3, r2] + 800712e: 3301 adds r3, #1 + 8007130: b299 uxth r1, r3 + 8007132: 4b60 ldr r3, [pc, #384] ; (80072b4 ) + 8007134: 2296 movs r2, #150 ; 0x96 + 8007136: 5299 strh r1, [r3, r2] + snmp_inc_tcpinerrs(); + goto aborted; + 8007138: e126 b.n 8007388 + } + } + tcp_input_pcb = pcb; + 800713a: 4b5f ldr r3, [pc, #380] ; (80072b8 ) + 800713c: 697a ldr r2, [r7, #20] + 800713e: 601a str r2, [r3, #0] + err = tcp_process(pcb); + 8007140: 250b movs r5, #11 + 8007142: 197c adds r4, r7, r5 + 8007144: 697b ldr r3, [r7, #20] + 8007146: 0018 movs r0, r3 + 8007148: f000 fb02 bl 8007750 + 800714c: 0003 movs r3, r0 + 800714e: 7023 strb r3, [r4, #0] + /* A return value of ERR_ABRT means that tcp_abort() was called + and that the pcb has been freed. If so, we don't do anything. */ + if (err != ERR_ABRT) { + 8007150: 197b adds r3, r7, r5 + 8007152: 781b ldrb r3, [r3, #0] + 8007154: b25b sxtb r3, r3 + 8007156: 330a adds r3, #10 + 8007158: d100 bne.n 800715c + 800715a: e10e b.n 800737a + if (recv_flags & TF_RESET) { + 800715c: 4b52 ldr r3, [pc, #328] ; (80072a8 ) + 800715e: 781b ldrb r3, [r3, #0] + 8007160: 001a movs r2, r3 + 8007162: 2308 movs r3, #8 + 8007164: 4013 ands r3, r2 + 8007166: d019 beq.n 800719c + /* TF_RESET means that the connection was reset by the other + end. We then call the error callback to inform the + application that the connection is dead before we + deallocate the PCB. */ + TCP_EVENT_ERR(pcb->errf, pcb->callback_arg, ERR_RST); + 8007168: 697b ldr r3, [r7, #20] + 800716a: 228c movs r2, #140 ; 0x8c + 800716c: 589b ldr r3, [r3, r2] + 800716e: 2b00 cmp r3, #0 + 8007170: d008 beq.n 8007184 + 8007172: 697b ldr r3, [r7, #20] + 8007174: 228c movs r2, #140 ; 0x8c + 8007176: 589a ldr r2, [r3, r2] + 8007178: 697b ldr r3, [r7, #20] + 800717a: 6918 ldr r0, [r3, #16] + 800717c: 230b movs r3, #11 + 800717e: 425b negs r3, r3 + 8007180: 0019 movs r1, r3 + 8007182: 4790 blx r2 + tcp_pcb_remove(&tcp_active_pcbs, pcb); + 8007184: 697a ldr r2, [r7, #20] + 8007186: 4b43 ldr r3, [pc, #268] ; (8007294 ) + 8007188: 0011 movs r1, r2 + 800718a: 0018 movs r0, r3 + 800718c: f7ff fc8e bl 8006aac + memp_free(MEMP_TCP_PCB, pcb); + 8007190: 697b ldr r3, [r7, #20] + 8007192: 0019 movs r1, r3 + 8007194: 2002 movs r0, #2 + 8007196: f7fd fec3 bl 8004f20 + 800719a: e0f5 b.n 8007388 + } else if (recv_flags & TF_CLOSED) { + 800719c: 4b42 ldr r3, [pc, #264] ; (80072a8 ) + 800719e: 781b ldrb r3, [r3, #0] + 80071a0: 001a movs r2, r3 + 80071a2: 2310 movs r3, #16 + 80071a4: 4013 ands r3, r2 + 80071a6: d01f beq.n 80071e8 + /* The connection has been closed and we will deallocate the + PCB. */ + if (!(pcb->flags & TF_RXCLOSED)) { + 80071a8: 697b ldr r3, [r7, #20] + 80071aa: 7f9b ldrb r3, [r3, #30] + 80071ac: 001a movs r2, r3 + 80071ae: 2310 movs r3, #16 + 80071b0: 4013 ands r3, r2 + 80071b2: d10d bne.n 80071d0 + /* Connection closed although the application has only shut down the + tx side: call the PCB's err callback and indicate the closure to + ensure the application doesn't continue using the PCB. */ + TCP_EVENT_ERR(pcb->errf, pcb->callback_arg, ERR_CLSD); + 80071b4: 697b ldr r3, [r7, #20] + 80071b6: 228c movs r2, #140 ; 0x8c + 80071b8: 589b ldr r3, [r3, r2] + 80071ba: 2b00 cmp r3, #0 + 80071bc: d008 beq.n 80071d0 + 80071be: 697b ldr r3, [r7, #20] + 80071c0: 228c movs r2, #140 ; 0x8c + 80071c2: 589a ldr r2, [r3, r2] + 80071c4: 697b ldr r3, [r7, #20] + 80071c6: 6918 ldr r0, [r3, #16] + 80071c8: 230c movs r3, #12 + 80071ca: 425b negs r3, r3 + 80071cc: 0019 movs r1, r3 + 80071ce: 4790 blx r2 + } + tcp_pcb_remove(&tcp_active_pcbs, pcb); + 80071d0: 697a ldr r2, [r7, #20] + 80071d2: 4b30 ldr r3, [pc, #192] ; (8007294 ) + 80071d4: 0011 movs r1, r2 + 80071d6: 0018 movs r0, r3 + 80071d8: f7ff fc68 bl 8006aac + memp_free(MEMP_TCP_PCB, pcb); + 80071dc: 697b ldr r3, [r7, #20] + 80071de: 0019 movs r1, r3 + 80071e0: 2002 movs r0, #2 + 80071e2: f7fd fe9d bl 8004f20 + 80071e6: e0cf b.n 8007388 + } else { + err = ERR_OK; + 80071e8: 230b movs r3, #11 + 80071ea: 18fb adds r3, r7, r3 + 80071ec: 2200 movs r2, #0 + 80071ee: 701a strb r2, [r3, #0] + /* If the application has registered a "sent" function to be + called when new send buffer space is available, we call it + now. */ + if (pcb->acked > 0) { + 80071f0: 697b ldr r3, [r7, #20] + 80071f2: 2264 movs r2, #100 ; 0x64 + 80071f4: 5a9b ldrh r3, [r3, r2] + 80071f6: 2b00 cmp r3, #0 + 80071f8: d01d beq.n 8007236 + TCP_EVENT_SENT(pcb, pcb->acked, err); + 80071fa: 697b ldr r3, [r7, #20] + 80071fc: 6fdb ldr r3, [r3, #124] ; 0x7c + 80071fe: 2b00 cmp r3, #0 + 8007200: d00e beq.n 8007220 + 8007202: 697b ldr r3, [r7, #20] + 8007204: 6fdd ldr r5, [r3, #124] ; 0x7c + 8007206: 697b ldr r3, [r7, #20] + 8007208: 6918 ldr r0, [r3, #16] + 800720a: 697b ldr r3, [r7, #20] + 800720c: 2264 movs r2, #100 ; 0x64 + 800720e: 5a9a ldrh r2, [r3, r2] + 8007210: 230b movs r3, #11 + 8007212: 18fc adds r4, r7, r3 + 8007214: 697b ldr r3, [r7, #20] + 8007216: 0019 movs r1, r3 + 8007218: 47a8 blx r5 + 800721a: 0003 movs r3, r0 + 800721c: 7023 strb r3, [r4, #0] + 800721e: e003 b.n 8007228 + 8007220: 230b movs r3, #11 + 8007222: 18fb adds r3, r7, r3 + 8007224: 2200 movs r2, #0 + 8007226: 701a strb r2, [r3, #0] + if (err == ERR_ABRT) { + 8007228: 230b movs r3, #11 + 800722a: 18fb adds r3, r7, r3 + 800722c: 781b ldrb r3, [r3, #0] + 800722e: b25b sxtb r3, r3 + 8007230: 330a adds r3, #10 + 8007232: d100 bne.n 8007236 + 8007234: e0a3 b.n 800737e + goto aborted; + } + } + + if (recv_data != NULL) { + 8007236: 4b1b ldr r3, [pc, #108] ; (80072a4 ) + 8007238: 681b ldr r3, [r3, #0] + 800723a: 2b00 cmp r3, #0 + 800723c: d059 beq.n 80072f2 + LWIP_ASSERT("pcb->refused_data == NULL", pcb->refused_data == NULL); + if (pcb->flags & TF_RXCLOSED) { + 800723e: 697b ldr r3, [r7, #20] + 8007240: 7f9b ldrb r3, [r3, #30] + 8007242: 001a movs r2, r3 + 8007244: 2310 movs r3, #16 + 8007246: 4013 ands r3, r2 + 8007248: d009 beq.n 800725e + /* received data although already closed -> abort (send RST) to + notify the remote host that not all data has been processed */ + pbuf_free(recv_data); + 800724a: 4b16 ldr r3, [pc, #88] ; (80072a4 ) + 800724c: 681b ldr r3, [r3, #0] + 800724e: 0018 movs r0, r3 + 8007250: f7fe fa28 bl 80056a4 + tcp_abort(pcb); + 8007254: 697b ldr r3, [r7, #20] + 8007256: 0018 movs r0, r3 + 8007258: f7fe fe90 bl 8005f7c + goto aborted; + 800725c: e094 b.n 8007388 + } + + /* Notify application that data has been received. */ + TCP_EVENT_RECV(pcb, recv_data, ERR_OK, err); + 800725e: 697b ldr r3, [r7, #20] + 8007260: 2280 movs r2, #128 ; 0x80 + 8007262: 589b ldr r3, [r3, r2] + 8007264: 2b00 cmp r3, #0 + 8007266: d029 beq.n 80072bc + 8007268: 697b ldr r3, [r7, #20] + 800726a: 2280 movs r2, #128 ; 0x80 + 800726c: 589d ldr r5, [r3, r2] + 800726e: 697b ldr r3, [r7, #20] + 8007270: 6918 ldr r0, [r3, #16] + 8007272: 4b0c ldr r3, [pc, #48] ; (80072a4 ) + 8007274: 681a ldr r2, [r3, #0] + 8007276: 230b movs r3, #11 + 8007278: 18fc adds r4, r7, r3 + 800727a: 6979 ldr r1, [r7, #20] + 800727c: 2300 movs r3, #0 + 800727e: 47a8 blx r5 + 8007280: 0003 movs r3, r0 + 8007282: 7023 strb r3, [r4, #0] + 8007284: e025 b.n 80072d2 + 8007286: 46c0 nop ; (mov r8, r8) + 8007288: 2000228c .word 0x2000228c + 800728c: 20003294 .word 0x20003294 + 8007290: 2000329c .word 0x2000329c + 8007294: 20003274 .word 0x20003274 + 8007298: 20003288 .word 0x20003288 + 800729c: 2000327c .word 0x2000327c + 80072a0: 2000227c .word 0x2000227c + 80072a4: 200022a4 .word 0x200022a4 + 80072a8: 200022a0 .word 0x200022a0 + 80072ac: 2000229c .word 0x2000229c + 80072b0: 2000229e .word 0x2000229e + 80072b4: 20003158 .word 0x20003158 + 80072b8: 2000328c .word 0x2000328c + 80072bc: 4b66 ldr r3, [pc, #408] ; (8007458 ) + 80072be: 681a ldr r2, [r3, #0] + 80072c0: 230b movs r3, #11 + 80072c2: 18fc adds r4, r7, r3 + 80072c4: 6979 ldr r1, [r7, #20] + 80072c6: 2300 movs r3, #0 + 80072c8: 2000 movs r0, #0 + 80072ca: f7ff fa5f bl 800678c + 80072ce: 0003 movs r3, r0 + 80072d0: 7023 strb r3, [r4, #0] + if (err == ERR_ABRT) { + 80072d2: 230b movs r3, #11 + 80072d4: 18fb adds r3, r7, r3 + 80072d6: 781b ldrb r3, [r3, #0] + 80072d8: b25b sxtb r3, r3 + 80072da: 330a adds r3, #10 + 80072dc: d051 beq.n 8007382 + goto aborted; + } + + /* If the upper layer can't receive this data, store it */ + if (err != ERR_OK) { + 80072de: 230b movs r3, #11 + 80072e0: 18fb adds r3, r7, r3 + 80072e2: 781b ldrb r3, [r3, #0] + 80072e4: b25b sxtb r3, r3 + 80072e6: 2b00 cmp r3, #0 + 80072e8: d003 beq.n 80072f2 + pcb->refused_data = recv_data; + 80072ea: 4b5b ldr r3, [pc, #364] ; (8007458 ) + 80072ec: 681a ldr r2, [r3, #0] + 80072ee: 697b ldr r3, [r7, #20] + 80072f0: 679a str r2, [r3, #120] ; 0x78 + } + } + + /* If a FIN segment was received, we call the callback + function with a NULL buffer to indicate EOF. */ + if (recv_flags & TF_GOT_FIN) { + 80072f2: 4b5a ldr r3, [pc, #360] ; (800745c ) + 80072f4: 781b ldrb r3, [r3, #0] + 80072f6: 001a movs r2, r3 + 80072f8: 2320 movs r3, #32 + 80072fa: 4013 ands r3, r2 + 80072fc: d035 beq.n 800736a + if (pcb->refused_data != NULL) { + 80072fe: 697b ldr r3, [r7, #20] + 8007300: 6f9b ldr r3, [r3, #120] ; 0x78 + 8007302: 2b00 cmp r3, #0 + 8007304: d009 beq.n 800731a + /* Delay this if we have refused data. */ + pcb->refused_data->flags |= PBUF_FLAG_TCP_FIN; + 8007306: 697b ldr r3, [r7, #20] + 8007308: 6f9b ldr r3, [r3, #120] ; 0x78 + 800730a: 7b5a ldrb r2, [r3, #13] + 800730c: 697b ldr r3, [r7, #20] + 800730e: 6f9b ldr r3, [r3, #120] ; 0x78 + 8007310: 2120 movs r1, #32 + 8007312: 430a orrs r2, r1 + 8007314: b2d2 uxtb r2, r2 + 8007316: 735a strb r2, [r3, #13] + 8007318: e027 b.n 800736a + } else { + /* correct rcv_wnd as the application won't call tcp_recved() + for the FIN's seqno */ + if (pcb->rcv_wnd != TCP_WND) { + 800731a: 697b ldr r3, [r7, #20] + 800731c: 8d9b ldrh r3, [r3, #44] ; 0x2c + 800731e: 4a50 ldr r2, [pc, #320] ; (8007460 ) + 8007320: 4293 cmp r3, r2 + 8007322: d005 beq.n 8007330 + pcb->rcv_wnd++; + 8007324: 697b ldr r3, [r7, #20] + 8007326: 8d9b ldrh r3, [r3, #44] ; 0x2c + 8007328: 3301 adds r3, #1 + 800732a: b29a uxth r2, r3 + 800732c: 697b ldr r3, [r7, #20] + 800732e: 859a strh r2, [r3, #44] ; 0x2c + } + TCP_EVENT_CLOSED(pcb, err); + 8007330: 697b ldr r3, [r7, #20] + 8007332: 2280 movs r2, #128 ; 0x80 + 8007334: 589b ldr r3, [r3, r2] + 8007336: 2b00 cmp r3, #0 + 8007338: d00d beq.n 8007356 + 800733a: 697b ldr r3, [r7, #20] + 800733c: 2280 movs r2, #128 ; 0x80 + 800733e: 589d ldr r5, [r3, r2] + 8007340: 697b ldr r3, [r7, #20] + 8007342: 6918 ldr r0, [r3, #16] + 8007344: 230b movs r3, #11 + 8007346: 18fc adds r4, r7, r3 + 8007348: 6979 ldr r1, [r7, #20] + 800734a: 2300 movs r3, #0 + 800734c: 2200 movs r2, #0 + 800734e: 47a8 blx r5 + 8007350: 0003 movs r3, r0 + 8007352: 7023 strb r3, [r4, #0] + 8007354: e003 b.n 800735e + 8007356: 230b movs r3, #11 + 8007358: 18fb adds r3, r7, r3 + 800735a: 2200 movs r2, #0 + 800735c: 701a strb r2, [r3, #0] + if (err == ERR_ABRT) { + 800735e: 230b movs r3, #11 + 8007360: 18fb adds r3, r7, r3 + 8007362: 781b ldrb r3, [r3, #0] + 8007364: b25b sxtb r3, r3 + 8007366: 330a adds r3, #10 + 8007368: d00d beq.n 8007386 + goto aborted; + } + } + } + + tcp_input_pcb = NULL; + 800736a: 4b3e ldr r3, [pc, #248] ; (8007464 ) + 800736c: 2200 movs r2, #0 + 800736e: 601a str r2, [r3, #0] + /* Try to send something out. */ + tcp_output(pcb); + 8007370: 697b ldr r3, [r7, #20] + 8007372: 0018 movs r0, r3 + 8007374: f002 fb4c bl 8009a10 + 8007378: e006 b.n 8007388 +#endif /* TCP_INPUT_DEBUG */ + } + } + /* Jump target if pcb has been aborted in a callback (by calling tcp_abort()). + Below this line, 'pcb' may not be dereferenced! */ +aborted: + 800737a: 46c0 nop ; (mov r8, r8) + 800737c: e004 b.n 8007388 + goto aborted; + 800737e: 46c0 nop ; (mov r8, r8) + 8007380: e002 b.n 8007388 + goto aborted; + 8007382: 46c0 nop ; (mov r8, r8) + 8007384: e000 b.n 8007388 + goto aborted; + 8007386: 46c0 nop ; (mov r8, r8) + tcp_input_pcb = NULL; + 8007388: 4b36 ldr r3, [pc, #216] ; (8007464 ) + 800738a: 2200 movs r2, #0 + 800738c: 601a str r2, [r3, #0] + recv_data = NULL; + 800738e: 4b32 ldr r3, [pc, #200] ; (8007458 ) + 8007390: 2200 movs r2, #0 + 8007392: 601a str r2, [r3, #0] + + /* give up our reference to inseg.p */ + if (inseg.p != NULL) + 8007394: 4b34 ldr r3, [pc, #208] ; (8007468 ) + 8007396: 685b ldr r3, [r3, #4] + 8007398: 2b00 cmp r3, #0 + 800739a: d058 beq.n 800744e + { + pbuf_free(inseg.p); + 800739c: 4b32 ldr r3, [pc, #200] ; (8007468 ) + 800739e: 685b ldr r3, [r3, #4] + 80073a0: 0018 movs r0, r3 + 80073a2: f7fe f97f bl 80056a4 + inseg.p = NULL; + 80073a6: 4b30 ldr r3, [pc, #192] ; (8007468 ) + 80073a8: 2200 movs r2, #0 + 80073aa: 605a str r2, [r3, #4] + pbuf_free(p); + } + + LWIP_ASSERT("tcp_input: tcp_pcbs_sane()", tcp_pcbs_sane()); + PERF_STOP("tcp_input"); + return; + 80073ac: e04f b.n 800744e + if (!(TCPH_FLAGS(tcphdr) & TCP_RST)) { + 80073ae: 4b2f ldr r3, [pc, #188] ; (800746c ) + 80073b0: 681b ldr r3, [r3, #0] + 80073b2: 7b1a ldrb r2, [r3, #12] + 80073b4: 7b5b ldrb r3, [r3, #13] + 80073b6: 021b lsls r3, r3, #8 + 80073b8: 4313 orrs r3, r2 + 80073ba: b29b uxth r3, r3 + 80073bc: 0018 movs r0, r3 + 80073be: f7fd f93f bl 8004640 + 80073c2: 0003 movs r3, r0 + 80073c4: 001a movs r2, r3 + 80073c6: 2304 movs r3, #4 + 80073c8: 4013 ands r3, r2 + 80073ca: d12e bne.n 800742a + TCP_STATS_INC(tcp.proterr); + 80073cc: 4b28 ldr r3, [pc, #160] ; (8007470 ) + 80073ce: 22a0 movs r2, #160 ; 0xa0 + 80073d0: 5a9b ldrh r3, [r3, r2] + 80073d2: 3301 adds r3, #1 + 80073d4: b299 uxth r1, r3 + 80073d6: 4b26 ldr r3, [pc, #152] ; (8007470 ) + 80073d8: 22a0 movs r2, #160 ; 0xa0 + 80073da: 5299 strh r1, [r3, r2] + TCP_STATS_INC(tcp.drop); + 80073dc: 4b24 ldr r3, [pc, #144] ; (8007470 ) + 80073de: 2296 movs r2, #150 ; 0x96 + 80073e0: 5a9b ldrh r3, [r3, r2] + 80073e2: 3301 adds r3, #1 + 80073e4: b299 uxth r1, r3 + 80073e6: 4b22 ldr r3, [pc, #136] ; (8007470 ) + 80073e8: 2296 movs r2, #150 ; 0x96 + 80073ea: 5299 strh r1, [r3, r2] + tcp_rst(ackno, seqno + tcplen, + 80073ec: 4b21 ldr r3, [pc, #132] ; (8007474 ) + 80073ee: 6818 ldr r0, [r3, #0] + 80073f0: 4b21 ldr r3, [pc, #132] ; (8007478 ) + 80073f2: 881b ldrh r3, [r3, #0] + 80073f4: 001a movs r2, r3 + 80073f6: 4b21 ldr r3, [pc, #132] ; (800747c ) + 80073f8: 681b ldr r3, [r3, #0] + 80073fa: 18d4 adds r4, r2, r3 + tcphdr->dest, tcphdr->src); + 80073fc: 4b1b ldr r3, [pc, #108] ; (800746c ) + 80073fe: 681b ldr r3, [r3, #0] + tcp_rst(ackno, seqno + tcplen, + 8007400: 789a ldrb r2, [r3, #2] + 8007402: 78db ldrb r3, [r3, #3] + 8007404: 021b lsls r3, r3, #8 + 8007406: 4313 orrs r3, r2 + 8007408: b29a uxth r2, r3 + tcphdr->dest, tcphdr->src); + 800740a: 4b18 ldr r3, [pc, #96] ; (800746c ) + 800740c: 681b ldr r3, [r3, #0] + tcp_rst(ackno, seqno + tcplen, + 800740e: 7819 ldrb r1, [r3, #0] + 8007410: 785b ldrb r3, [r3, #1] + 8007412: 021b lsls r3, r3, #8 + 8007414: 430b orrs r3, r1 + 8007416: b29b uxth r3, r3 + 8007418: 4d19 ldr r5, [pc, #100] ; (8007480 ) + 800741a: 491a ldr r1, [pc, #104] ; (8007484 ) + 800741c: 9301 str r3, [sp, #4] + 800741e: 9200 str r2, [sp, #0] + 8007420: 002b movs r3, r5 + 8007422: 000a movs r2, r1 + 8007424: 0021 movs r1, r4 + 8007426: f002 fdd1 bl 8009fcc + pbuf_free(p); + 800742a: 687b ldr r3, [r7, #4] + 800742c: 0018 movs r0, r3 + 800742e: f7fe f939 bl 80056a4 + return; + 8007432: e00c b.n 800744e +dropped: + TCP_STATS_INC(tcp.drop); + 8007434: 4b0e ldr r3, [pc, #56] ; (8007470 ) + 8007436: 2296 movs r2, #150 ; 0x96 + 8007438: 5a9b ldrh r3, [r3, r2] + 800743a: 3301 adds r3, #1 + 800743c: b299 uxth r1, r3 + 800743e: 4b0c ldr r3, [pc, #48] ; (8007470 ) + 8007440: 2296 movs r2, #150 ; 0x96 + 8007442: 5299 strh r1, [r3, r2] + snmp_inc_tcpinerrs(); + pbuf_free(p); + 8007444: 687b ldr r3, [r7, #4] + 8007446: 0018 movs r0, r3 + 8007448: f7fe f92c bl 80056a4 + 800744c: e000 b.n 8007450 + return; + 800744e: 46c0 nop ; (mov r8, r8) +} + 8007450: 46bd mov sp, r7 + 8007452: b006 add sp, #24 + 8007454: bdb0 pop {r4, r5, r7, pc} + 8007456: 46c0 nop ; (mov r8, r8) + 8007458: 200022a4 .word 0x200022a4 + 800745c: 200022a0 .word 0x200022a0 + 8007460: 000016d0 .word 0x000016d0 + 8007464: 2000328c .word 0x2000328c + 8007468: 2000227c .word 0x2000227c + 800746c: 2000228c .word 0x2000228c + 8007470: 20003158 .word 0x20003158 + 8007474: 20002298 .word 0x20002298 + 8007478: 2000229e .word 0x2000229e + 800747c: 20002294 .word 0x20002294 + 8007480: 20003294 .word 0x20003294 + 8007484: 2000329c .word 0x2000329c + +08007488 : + * @note the segment which arrived is saved in global variables, therefore only the pcb + * involved is passed as a parameter to this function + */ +static err_t +tcp_listen_input(struct tcp_pcb_listen *pcb) +{ + 8007488: b5b0 push {r4, r5, r7, lr} + 800748a: b086 sub sp, #24 + 800748c: af02 add r7, sp, #8 + 800748e: 6078 str r0, [r7, #4] + struct tcp_pcb *npcb; + err_t rc; + + if (flags & TCP_RST) { + 8007490: 4b6b ldr r3, [pc, #428] ; (8007640 ) + 8007492: 781b ldrb r3, [r3, #0] + 8007494: 001a movs r2, r3 + 8007496: 2304 movs r3, #4 + 8007498: 4013 ands r3, r2 + 800749a: d001 beq.n 80074a0 + /* An incoming RST should be ignored. Return. */ + return ERR_OK; + 800749c: 2300 movs r3, #0 + 800749e: e0cb b.n 8007638 + } + + /* In the LISTEN state, we check for incoming SYN segments, + creates a new PCB, and responds with a SYN|ACK. */ + if (flags & TCP_ACK) { + 80074a0: 4b67 ldr r3, [pc, #412] ; (8007640 ) + 80074a2: 781b ldrb r3, [r3, #0] + 80074a4: 001a movs r2, r3 + 80074a6: 2310 movs r3, #16 + 80074a8: 4013 ands r3, r2 + 80074aa: d01f beq.n 80074ec + /* For incoming segments with the ACK flag set, respond with a + RST. */ + LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_listen_input: ACK in LISTEN, sending reset\n")); + tcp_rst(ackno, seqno + tcplen, ip_current_dest_addr(), + 80074ac: 4b65 ldr r3, [pc, #404] ; (8007644 ) + 80074ae: 6818 ldr r0, [r3, #0] + 80074b0: 4b65 ldr r3, [pc, #404] ; (8007648 ) + 80074b2: 881b ldrh r3, [r3, #0] + 80074b4: 001a movs r2, r3 + 80074b6: 4b65 ldr r3, [pc, #404] ; (800764c ) + 80074b8: 681b ldr r3, [r3, #0] + 80074ba: 18d4 adds r4, r2, r3 + ip_current_src_addr(), tcphdr->dest, tcphdr->src); + 80074bc: 4b64 ldr r3, [pc, #400] ; (8007650 ) + 80074be: 681b ldr r3, [r3, #0] + tcp_rst(ackno, seqno + tcplen, ip_current_dest_addr(), + 80074c0: 789a ldrb r2, [r3, #2] + 80074c2: 78db ldrb r3, [r3, #3] + 80074c4: 021b lsls r3, r3, #8 + 80074c6: 4313 orrs r3, r2 + 80074c8: b29a uxth r2, r3 + ip_current_src_addr(), tcphdr->dest, tcphdr->src); + 80074ca: 4b61 ldr r3, [pc, #388] ; (8007650 ) + 80074cc: 681b ldr r3, [r3, #0] + tcp_rst(ackno, seqno + tcplen, ip_current_dest_addr(), + 80074ce: 7819 ldrb r1, [r3, #0] + 80074d0: 785b ldrb r3, [r3, #1] + 80074d2: 021b lsls r3, r3, #8 + 80074d4: 430b orrs r3, r1 + 80074d6: b29b uxth r3, r3 + 80074d8: 4d5e ldr r5, [pc, #376] ; (8007654 ) + 80074da: 495f ldr r1, [pc, #380] ; (8007658 ) + 80074dc: 9301 str r3, [sp, #4] + 80074de: 9200 str r2, [sp, #0] + 80074e0: 002b movs r3, r5 + 80074e2: 000a movs r2, r1 + 80074e4: 0021 movs r1, r4 + 80074e6: f002 fd71 bl 8009fcc + 80074ea: e0a4 b.n 8007636 + } else if (flags & TCP_SYN) { + 80074ec: 4b54 ldr r3, [pc, #336] ; (8007640 ) + 80074ee: 781b ldrb r3, [r3, #0] + 80074f0: 001a movs r2, r3 + 80074f2: 2302 movs r3, #2 + 80074f4: 4013 ands r3, r2 + 80074f6: d100 bne.n 80074fa + 80074f8: e09d b.n 8007636 + if (pcb->accepts_pending >= pcb->backlog) { + LWIP_DEBUGF(TCP_DEBUG, ("tcp_listen_input: listen backlog exceeded for port %"U16_F"\n", tcphdr->dest)); + return ERR_ABRT; + } +#endif /* TCP_LISTEN_BACKLOG */ + npcb = tcp_alloc(pcb->prio); + 80074fa: 687b ldr r3, [r7, #4] + 80074fc: 7e5b ldrb r3, [r3, #25] + 80074fe: 0018 movs r0, r3 + 8007500: f7ff f9e6 bl 80068d0 + 8007504: 0003 movs r3, r0 + 8007506: 60fb str r3, [r7, #12] + /* If a new PCB could not be created (probably due to lack of memory), + we don't do anything, but rely on the sender will retransmit the + SYN at a time when we have more memory available. */ + if (npcb == NULL) { + 8007508: 68fb ldr r3, [r7, #12] + 800750a: 2b00 cmp r3, #0 + 800750c: d10a bne.n 8007524 + LWIP_DEBUGF(TCP_DEBUG, ("tcp_listen_input: could not allocate PCB\n")); + TCP_STATS_INC(tcp.memerr); + 800750e: 4b53 ldr r3, [pc, #332] ; (800765c ) + 8007510: 229c movs r2, #156 ; 0x9c + 8007512: 5a9b ldrh r3, [r3, r2] + 8007514: 3301 adds r3, #1 + 8007516: b299 uxth r1, r3 + 8007518: 4b50 ldr r3, [pc, #320] ; (800765c ) + 800751a: 229c movs r2, #156 ; 0x9c + 800751c: 5299 strh r1, [r3, r2] + return ERR_MEM; + 800751e: 2301 movs r3, #1 + 8007520: 425b negs r3, r3 + 8007522: e089 b.n 8007638 + } +#if TCP_LISTEN_BACKLOG + pcb->accepts_pending++; +#endif /* TCP_LISTEN_BACKLOG */ + /* Set up the new PCB. */ + ip_addr_copy(npcb->local_ip, current_iphdr_dest); + 8007524: 4b4c ldr r3, [pc, #304] ; (8007658 ) + 8007526: 681a ldr r2, [r3, #0] + 8007528: 68fb ldr r3, [r7, #12] + 800752a: 601a str r2, [r3, #0] + npcb->local_port = pcb->local_port; + 800752c: 687b ldr r3, [r7, #4] + 800752e: 8b5a ldrh r2, [r3, #26] + 8007530: 68fb ldr r3, [r7, #12] + 8007532: 835a strh r2, [r3, #26] + ip_addr_copy(npcb->remote_ip, current_iphdr_src); + 8007534: 4b47 ldr r3, [pc, #284] ; (8007654 ) + 8007536: 681a ldr r2, [r3, #0] + 8007538: 68fb ldr r3, [r7, #12] + 800753a: 605a str r2, [r3, #4] + npcb->remote_port = tcphdr->src; + 800753c: 4b44 ldr r3, [pc, #272] ; (8007650 ) + 800753e: 681b ldr r3, [r3, #0] + 8007540: 781a ldrb r2, [r3, #0] + 8007542: 785b ldrb r3, [r3, #1] + 8007544: 021b lsls r3, r3, #8 + 8007546: 4313 orrs r3, r2 + 8007548: b29a uxth r2, r3 + 800754a: 68fb ldr r3, [r7, #12] + 800754c: 839a strh r2, [r3, #28] + npcb->state = SYN_RCVD; + 800754e: 68fb ldr r3, [r7, #12] + 8007550: 2203 movs r2, #3 + 8007552: 761a strb r2, [r3, #24] + npcb->rcv_nxt = seqno + 1; + 8007554: 4b3d ldr r3, [pc, #244] ; (800764c ) + 8007556: 681b ldr r3, [r3, #0] + 8007558: 1c5a adds r2, r3, #1 + 800755a: 68fb ldr r3, [r7, #12] + 800755c: 629a str r2, [r3, #40] ; 0x28 + npcb->rcv_ann_right_edge = npcb->rcv_nxt; + 800755e: 68fb ldr r3, [r7, #12] + 8007560: 6a9a ldr r2, [r3, #40] ; 0x28 + 8007562: 68fb ldr r3, [r7, #12] + 8007564: 631a str r2, [r3, #48] ; 0x30 + npcb->snd_wnd = tcphdr->wnd; + 8007566: 4b3a ldr r3, [pc, #232] ; (8007650 ) + 8007568: 681b ldr r3, [r3, #0] + 800756a: 7b9a ldrb r2, [r3, #14] + 800756c: 7bdb ldrb r3, [r3, #15] + 800756e: 021b lsls r3, r3, #8 + 8007570: 4313 orrs r3, r2 + 8007572: b299 uxth r1, r3 + 8007574: 68fb ldr r3, [r7, #12] + 8007576: 2260 movs r2, #96 ; 0x60 + 8007578: 5299 strh r1, [r3, r2] + npcb->snd_wnd_max = tcphdr->wnd; + 800757a: 4b35 ldr r3, [pc, #212] ; (8007650 ) + 800757c: 681b ldr r3, [r3, #0] + 800757e: 7b9a ldrb r2, [r3, #14] + 8007580: 7bdb ldrb r3, [r3, #15] + 8007582: 021b lsls r3, r3, #8 + 8007584: 4313 orrs r3, r2 + 8007586: b299 uxth r1, r3 + 8007588: 68fb ldr r3, [r7, #12] + 800758a: 2262 movs r2, #98 ; 0x62 + 800758c: 5299 strh r1, [r3, r2] + npcb->ssthresh = npcb->snd_wnd; + 800758e: 68fb ldr r3, [r7, #12] + 8007590: 2260 movs r2, #96 ; 0x60 + 8007592: 5a99 ldrh r1, [r3, r2] + 8007594: 68fb ldr r3, [r7, #12] + 8007596: 224e movs r2, #78 ; 0x4e + 8007598: 5299 strh r1, [r3, r2] + npcb->snd_wl1 = seqno - 1;/* initialise to seqno-1 to force window update */ + 800759a: 4b2c ldr r3, [pc, #176] ; (800764c ) + 800759c: 681b ldr r3, [r3, #0] + 800759e: 1e5a subs r2, r3, #1 + 80075a0: 68fb ldr r3, [r7, #12] + 80075a2: 655a str r2, [r3, #84] ; 0x54 + npcb->callback_arg = pcb->callback_arg; + 80075a4: 687b ldr r3, [r7, #4] + 80075a6: 691a ldr r2, [r3, #16] + 80075a8: 68fb ldr r3, [r7, #12] + 80075aa: 611a str r2, [r3, #16] +#if LWIP_CALLBACK_API + npcb->accept = pcb->accept; + 80075ac: 687b ldr r3, [r7, #4] + 80075ae: 695a ldr r2, [r3, #20] + 80075b0: 68fb ldr r3, [r7, #12] + 80075b2: 615a str r2, [r3, #20] +#endif /* LWIP_CALLBACK_API */ + /* inherit socket options */ + npcb->so_options = pcb->so_options & SOF_INHERITED; + 80075b4: 687b ldr r3, [r7, #4] + 80075b6: 7a1b ldrb r3, [r3, #8] + 80075b8: 2273 movs r2, #115 ; 0x73 + 80075ba: 4393 bics r3, r2 + 80075bc: b2da uxtb r2, r3 + 80075be: 68fb ldr r3, [r7, #12] + 80075c0: 721a strb r2, [r3, #8] + /* Register the new PCB so that we can begin receiving segments + for it. */ + TCP_REG_ACTIVE(npcb); + 80075c2: 4b27 ldr r3, [pc, #156] ; (8007660 ) + 80075c4: 681a ldr r2, [r3, #0] + 80075c6: 68fb ldr r3, [r7, #12] + 80075c8: 60da str r2, [r3, #12] + 80075ca: 4b25 ldr r3, [pc, #148] ; (8007660 ) + 80075cc: 68fa ldr r2, [r7, #12] + 80075ce: 601a str r2, [r3, #0] + 80075d0: f003 f850 bl 800a674 + 80075d4: 4b23 ldr r3, [pc, #140] ; (8007664 ) + 80075d6: 2201 movs r2, #1 + 80075d8: 701a strb r2, [r3, #0] + + /* Parse any options in the SYN. */ + tcp_parseopt(npcb); + 80075da: 68fb ldr r3, [r7, #12] + 80075dc: 0018 movs r0, r3 + 80075de: f001 fdab bl 8009138 +#if TCP_CALCULATE_EFF_SEND_MSS + npcb->mss = tcp_eff_send_mss(npcb->mss, &(npcb->remote_ip)); + 80075e2: 68fb ldr r3, [r7, #12] + 80075e4: 8eda ldrh r2, [r3, #54] ; 0x36 + 80075e6: 68fb ldr r3, [r7, #12] + 80075e8: 3304 adds r3, #4 + 80075ea: 0019 movs r1, r3 + 80075ec: 0010 movs r0, r2 + 80075ee: f7ff fac3 bl 8006b78 + 80075f2: 0003 movs r3, r0 + 80075f4: 001a movs r2, r3 + 80075f6: 68fb ldr r3, [r7, #12] + 80075f8: 86da strh r2, [r3, #54] ; 0x36 +#endif /* TCP_CALCULATE_EFF_SEND_MSS */ + + snmp_inc_tcppassiveopens(); + + /* Send a SYN|ACK together with the MSS option. */ + rc = tcp_enqueue_flags(npcb, TCP_SYN | TCP_ACK); + 80075fa: 250b movs r5, #11 + 80075fc: 197c adds r4, r7, r5 + 80075fe: 68fb ldr r3, [r7, #12] + 8007600: 2112 movs r1, #18 + 8007602: 0018 movs r0, r3 + 8007604: f002 f8aa bl 800975c + 8007608: 0003 movs r3, r0 + 800760a: 7023 strb r3, [r4, #0] + if (rc != ERR_OK) { + 800760c: 197b adds r3, r7, r5 + 800760e: 781b ldrb r3, [r3, #0] + 8007610: b25b sxtb r3, r3 + 8007612: 2b00 cmp r3, #0 + 8007614: d009 beq.n 800762a + tcp_abandon(npcb, 0); + 8007616: 68fb ldr r3, [r7, #12] + 8007618: 2100 movs r1, #0 + 800761a: 0018 movs r0, r3 + 800761c: f7fe fc3e bl 8005e9c + return rc; + 8007620: 230b movs r3, #11 + 8007622: 18fb adds r3, r7, r3 + 8007624: 781b ldrb r3, [r3, #0] + 8007626: b25b sxtb r3, r3 + 8007628: e006 b.n 8007638 + } + return tcp_output(npcb); + 800762a: 68fb ldr r3, [r7, #12] + 800762c: 0018 movs r0, r3 + 800762e: f002 f9ef bl 8009a10 + 8007632: 0003 movs r3, r0 + 8007634: e000 b.n 8007638 + } + return ERR_OK; + 8007636: 2300 movs r3, #0 +} + 8007638: 0018 movs r0, r3 + 800763a: 46bd mov sp, r7 + 800763c: b004 add sp, #16 + 800763e: bdb0 pop {r4, r5, r7, pc} + 8007640: 2000229c .word 0x2000229c + 8007644: 20002298 .word 0x20002298 + 8007648: 2000229e .word 0x2000229e + 800764c: 20002294 .word 0x20002294 + 8007650: 2000228c .word 0x2000228c + 8007654: 20003294 .word 0x20003294 + 8007658: 2000329c .word 0x2000329c + 800765c: 20003158 .word 0x20003158 + 8007660: 20003274 .word 0x20003274 + 8007664: 20003270 .word 0x20003270 + +08007668 : + * @note the segment which arrived is saved in global variables, therefore only the pcb + * involved is passed as a parameter to this function + */ +static err_t +tcp_timewait_input(struct tcp_pcb *pcb) +{ + 8007668: b5b0 push {r4, r5, r7, lr} + 800766a: b084 sub sp, #16 + 800766c: af02 add r7, sp, #8 + 800766e: 6078 str r0, [r7, #4] + /* RFC 1337: in TIME_WAIT, ignore RST and ACK FINs + any 'acceptable' segments */ + /* RFC 793 3.9 Event Processing - Segment Arrives: + * - first check sequence number - we skip that one in TIME_WAIT (always + * acceptable since we only send ACKs) + * - second check the RST bit (... return) */ + if (flags & TCP_RST) { + 8007670: 4b2f ldr r3, [pc, #188] ; (8007730 ) + 8007672: 781b ldrb r3, [r3, #0] + 8007674: 001a movs r2, r3 + 8007676: 2304 movs r3, #4 + 8007678: 4013 ands r3, r2 + 800767a: d001 beq.n 8007680 + return ERR_OK; + 800767c: 2300 movs r3, #0 + 800767e: e052 b.n 8007726 + } + /* - fourth, check the SYN bit, */ + if (flags & TCP_SYN) { + 8007680: 4b2b ldr r3, [pc, #172] ; (8007730 ) + 8007682: 781b ldrb r3, [r3, #0] + 8007684: 001a movs r2, r3 + 8007686: 2302 movs r3, #2 + 8007688: 4013 ands r3, r2 + 800768a: d030 beq.n 80076ee + /* If an incoming segment is not acceptable, an acknowledgment + should be sent in reply */ + if (TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt, pcb->rcv_nxt+pcb->rcv_wnd)) { + 800768c: 4b29 ldr r3, [pc, #164] ; (8007734 ) + 800768e: 681a ldr r2, [r3, #0] + 8007690: 687b ldr r3, [r7, #4] + 8007692: 6a9b ldr r3, [r3, #40] ; 0x28 + 8007694: 1ad3 subs r3, r2, r3 + 8007696: d434 bmi.n 8007702 + 8007698: 4b26 ldr r3, [pc, #152] ; (8007734 ) + 800769a: 681a ldr r2, [r3, #0] + 800769c: 687b ldr r3, [r7, #4] + 800769e: 6a9b ldr r3, [r3, #40] ; 0x28 + 80076a0: 6879 ldr r1, [r7, #4] + 80076a2: 8d89 ldrh r1, [r1, #44] ; 0x2c + 80076a4: 185b adds r3, r3, r1 + 80076a6: 1ad3 subs r3, r2, r3 + 80076a8: 2b00 cmp r3, #0 + 80076aa: dc2a bgt.n 8007702 + /* If the SYN is in the window it is an error, send a reset */ + tcp_rst(ackno, seqno + tcplen, ip_current_dest_addr(), ip_current_src_addr(), + 80076ac: 4b22 ldr r3, [pc, #136] ; (8007738 ) + 80076ae: 6818 ldr r0, [r3, #0] + 80076b0: 4b22 ldr r3, [pc, #136] ; (800773c ) + 80076b2: 881b ldrh r3, [r3, #0] + 80076b4: 001a movs r2, r3 + 80076b6: 4b1f ldr r3, [pc, #124] ; (8007734 ) + 80076b8: 681b ldr r3, [r3, #0] + 80076ba: 18d4 adds r4, r2, r3 + tcphdr->dest, tcphdr->src); + 80076bc: 4b20 ldr r3, [pc, #128] ; (8007740 ) + 80076be: 681b ldr r3, [r3, #0] + tcp_rst(ackno, seqno + tcplen, ip_current_dest_addr(), ip_current_src_addr(), + 80076c0: 789a ldrb r2, [r3, #2] + 80076c2: 78db ldrb r3, [r3, #3] + 80076c4: 021b lsls r3, r3, #8 + 80076c6: 4313 orrs r3, r2 + 80076c8: b29a uxth r2, r3 + tcphdr->dest, tcphdr->src); + 80076ca: 4b1d ldr r3, [pc, #116] ; (8007740 ) + 80076cc: 681b ldr r3, [r3, #0] + tcp_rst(ackno, seqno + tcplen, ip_current_dest_addr(), ip_current_src_addr(), + 80076ce: 7819 ldrb r1, [r3, #0] + 80076d0: 785b ldrb r3, [r3, #1] + 80076d2: 021b lsls r3, r3, #8 + 80076d4: 430b orrs r3, r1 + 80076d6: b29b uxth r3, r3 + 80076d8: 4d1a ldr r5, [pc, #104] ; (8007744 ) + 80076da: 491b ldr r1, [pc, #108] ; (8007748 ) + 80076dc: 9301 str r3, [sp, #4] + 80076de: 9200 str r2, [sp, #0] + 80076e0: 002b movs r3, r5 + 80076e2: 000a movs r2, r1 + 80076e4: 0021 movs r1, r4 + 80076e6: f002 fc71 bl 8009fcc + return ERR_OK; + 80076ea: 2300 movs r3, #0 + 80076ec: e01b b.n 8007726 + } + } else if (flags & TCP_FIN) { + 80076ee: 4b10 ldr r3, [pc, #64] ; (8007730 ) + 80076f0: 781b ldrb r3, [r3, #0] + 80076f2: 001a movs r2, r3 + 80076f4: 2301 movs r3, #1 + 80076f6: 4013 ands r3, r2 + 80076f8: d003 beq.n 8007702 + /* - eighth, check the FIN bit: Remain in the TIME-WAIT state. + Restart the 2 MSL time-wait timeout.*/ + pcb->tmr = tcp_ticks; + 80076fa: 4b14 ldr r3, [pc, #80] ; (800774c ) + 80076fc: 681a ldr r2, [r3, #0] + 80076fe: 687b ldr r3, [r7, #4] + 8007700: 625a str r2, [r3, #36] ; 0x24 + } + + if ((tcplen > 0)) { + 8007702: 4b0e ldr r3, [pc, #56] ; (800773c ) + 8007704: 881b ldrh r3, [r3, #0] + 8007706: 2b00 cmp r3, #0 + 8007708: d00c beq.n 8007724 + /* Acknowledge data, FIN or out-of-window SYN */ + pcb->flags |= TF_ACK_NOW; + 800770a: 687b ldr r3, [r7, #4] + 800770c: 7f9b ldrb r3, [r3, #30] + 800770e: 2202 movs r2, #2 + 8007710: 4313 orrs r3, r2 + 8007712: b2da uxtb r2, r3 + 8007714: 687b ldr r3, [r7, #4] + 8007716: 779a strb r2, [r3, #30] + return tcp_output(pcb); + 8007718: 687b ldr r3, [r7, #4] + 800771a: 0018 movs r0, r3 + 800771c: f002 f978 bl 8009a10 + 8007720: 0003 movs r3, r0 + 8007722: e000 b.n 8007726 + } + return ERR_OK; + 8007724: 2300 movs r3, #0 +} + 8007726: 0018 movs r0, r3 + 8007728: 46bd mov sp, r7 + 800772a: b002 add sp, #8 + 800772c: bdb0 pop {r4, r5, r7, pc} + 800772e: 46c0 nop ; (mov r8, r8) + 8007730: 2000229c .word 0x2000229c + 8007734: 20002294 .word 0x20002294 + 8007738: 20002298 .word 0x20002298 + 800773c: 2000229e .word 0x2000229e + 8007740: 2000228c .word 0x2000228c + 8007744: 20003294 .word 0x20003294 + 8007748: 2000329c .word 0x2000329c + 800774c: 20003278 .word 0x20003278 + +08007750 : + * @note the segment which arrived is saved in global variables, therefore only the pcb + * involved is passed as a parameter to this function + */ +static err_t +tcp_process(struct tcp_pcb *pcb) +{ + 8007750: b5b0 push {r4, r5, r7, lr} + 8007752: b086 sub sp, #24 + 8007754: af02 add r7, sp, #8 + 8007756: 6078 str r0, [r7, #4] + struct tcp_seg *rseg; + u8_t acceptable = 0; + 8007758: 230f movs r3, #15 + 800775a: 18fb adds r3, r7, r3 + 800775c: 2200 movs r2, #0 + 800775e: 701a strb r2, [r3, #0] + err_t err; + + err = ERR_OK; + 8007760: 230e movs r3, #14 + 8007762: 18fb adds r3, r7, r3 + 8007764: 2200 movs r2, #0 + 8007766: 701a strb r2, [r3, #0] + + /* Process incoming RST segments. */ + if (flags & TCP_RST) { + 8007768: 4bd1 ldr r3, [pc, #836] ; (8007ab0 ) + 800776a: 781b ldrb r3, [r3, #0] + 800776c: 001a movs r2, r3 + 800776e: 2304 movs r3, #4 + 8007770: 4013 ands r3, r2 + 8007772: d03a beq.n 80077ea + /* First, determine if the reset is acceptable. */ + if (pcb->state == SYN_SENT) { + 8007774: 687b ldr r3, [r7, #4] + 8007776: 7e1b ldrb r3, [r3, #24] + 8007778: 2b02 cmp r3, #2 + 800777a: d10a bne.n 8007792 + if (ackno == pcb->snd_nxt) { + 800777c: 687b ldr r3, [r7, #4] + 800777e: 6d1a ldr r2, [r3, #80] ; 0x50 + 8007780: 4bcc ldr r3, [pc, #816] ; (8007ab4 ) + 8007782: 681b ldr r3, [r3, #0] + 8007784: 429a cmp r2, r3 + 8007786: d118 bne.n 80077ba + acceptable = 1; + 8007788: 230f movs r3, #15 + 800778a: 18fb adds r3, r7, r3 + 800778c: 2201 movs r2, #1 + 800778e: 701a strb r2, [r3, #0] + 8007790: e013 b.n 80077ba + } + } else { + if (TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt, + 8007792: 4bc9 ldr r3, [pc, #804] ; (8007ab8 ) + 8007794: 681a ldr r2, [r3, #0] + 8007796: 687b ldr r3, [r7, #4] + 8007798: 6a9b ldr r3, [r3, #40] ; 0x28 + 800779a: 1ad3 subs r3, r2, r3 + 800779c: d40d bmi.n 80077ba + 800779e: 4bc6 ldr r3, [pc, #792] ; (8007ab8 ) + 80077a0: 681a ldr r2, [r3, #0] + 80077a2: 687b ldr r3, [r7, #4] + 80077a4: 6a9b ldr r3, [r3, #40] ; 0x28 + 80077a6: 6879 ldr r1, [r7, #4] + 80077a8: 8d89 ldrh r1, [r1, #44] ; 0x2c + 80077aa: 185b adds r3, r3, r1 + 80077ac: 1ad3 subs r3, r2, r3 + 80077ae: 2b00 cmp r3, #0 + 80077b0: dc03 bgt.n 80077ba + pcb->rcv_nxt+pcb->rcv_wnd)) { + acceptable = 1; + 80077b2: 230f movs r3, #15 + 80077b4: 18fb adds r3, r7, r3 + 80077b6: 2201 movs r2, #1 + 80077b8: 701a strb r2, [r3, #0] + } + } + + if (acceptable) { + 80077ba: 230f movs r3, #15 + 80077bc: 18fb adds r3, r7, r3 + 80077be: 781b ldrb r3, [r3, #0] + 80077c0: 2b00 cmp r3, #0 + 80077c2: d010 beq.n 80077e6 + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_process: Connection RESET\n")); + LWIP_ASSERT("tcp_input: pcb->state != CLOSED", pcb->state != CLOSED); + recv_flags |= TF_RESET; + 80077c4: 4bbd ldr r3, [pc, #756] ; (8007abc ) + 80077c6: 781b ldrb r3, [r3, #0] + 80077c8: 2208 movs r2, #8 + 80077ca: 4313 orrs r3, r2 + 80077cc: b2da uxtb r2, r3 + 80077ce: 4bbb ldr r3, [pc, #748] ; (8007abc ) + 80077d0: 701a strb r2, [r3, #0] + pcb->flags &= ~TF_ACK_DELAY; + 80077d2: 687b ldr r3, [r7, #4] + 80077d4: 7f9b ldrb r3, [r3, #30] + 80077d6: 2201 movs r2, #1 + 80077d8: 4393 bics r3, r2 + 80077da: b2da uxtb r2, r3 + 80077dc: 687b ldr r3, [r7, #4] + 80077de: 779a strb r2, [r3, #30] + return ERR_RST; + 80077e0: 230b movs r3, #11 + 80077e2: 425b negs r3, r3 + 80077e4: e333 b.n 8007e4e + } else { + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_process: unacceptable reset seqno %"U32_F" rcv_nxt %"U32_F"\n", + seqno, pcb->rcv_nxt)); + LWIP_DEBUGF(TCP_DEBUG, ("tcp_process: unacceptable reset seqno %"U32_F" rcv_nxt %"U32_F"\n", + seqno, pcb->rcv_nxt)); + return ERR_OK; + 80077e6: 2300 movs r3, #0 + 80077e8: e331 b.n 8007e4e + } + } + + if ((flags & TCP_SYN) && (pcb->state != SYN_SENT && pcb->state != SYN_RCVD)) { + 80077ea: 4bb1 ldr r3, [pc, #708] ; (8007ab0 ) + 80077ec: 781b ldrb r3, [r3, #0] + 80077ee: 001a movs r2, r3 + 80077f0: 2302 movs r3, #2 + 80077f2: 4013 ands r3, r2 + 80077f4: d010 beq.n 8007818 + 80077f6: 687b ldr r3, [r7, #4] + 80077f8: 7e1b ldrb r3, [r3, #24] + 80077fa: 2b02 cmp r3, #2 + 80077fc: d00c beq.n 8007818 + 80077fe: 687b ldr r3, [r7, #4] + 8007800: 7e1b ldrb r3, [r3, #24] + 8007802: 2b03 cmp r3, #3 + 8007804: d008 beq.n 8007818 + /* Cope with new connection attempt after remote end crashed */ + tcp_ack_now(pcb); + 8007806: 687b ldr r3, [r7, #4] + 8007808: 7f9b ldrb r3, [r3, #30] + 800780a: 2202 movs r2, #2 + 800780c: 4313 orrs r3, r2 + 800780e: b2da uxtb r2, r3 + 8007810: 687b ldr r3, [r7, #4] + 8007812: 779a strb r2, [r3, #30] + return ERR_OK; + 8007814: 2300 movs r3, #0 + 8007816: e31a b.n 8007e4e + } + + if ((pcb->flags & TF_RXCLOSED) == 0) { + 8007818: 687b ldr r3, [r7, #4] + 800781a: 7f9b ldrb r3, [r3, #30] + 800781c: 001a movs r2, r3 + 800781e: 2310 movs r3, #16 + 8007820: 4013 ands r3, r2 + 8007822: d103 bne.n 800782c + /* Update the PCB (in)activity timer unless rx is closed (see tcp_shutdown) */ + pcb->tmr = tcp_ticks; + 8007824: 4ba6 ldr r3, [pc, #664] ; (8007ac0 ) + 8007826: 681a ldr r2, [r3, #0] + 8007828: 687b ldr r3, [r7, #4] + 800782a: 625a str r2, [r3, #36] ; 0x24 + } + pcb->keep_cnt_sent = 0; + 800782c: 687b ldr r3, [r7, #4] + 800782e: 2296 movs r2, #150 ; 0x96 + 8007830: 2100 movs r1, #0 + 8007832: 5499 strb r1, [r3, r2] + + tcp_parseopt(pcb); + 8007834: 687b ldr r3, [r7, #4] + 8007836: 0018 movs r0, r3 + 8007838: f001 fc7e bl 8009138 + + /* Do different things depending on the TCP state. */ + switch (pcb->state) { + 800783c: 687b ldr r3, [r7, #4] + 800783e: 7e1b ldrb r3, [r3, #24] + 8007840: 2b09 cmp r3, #9 + 8007842: d900 bls.n 8007846 + 8007844: e2f3 b.n 8007e2e + 8007846: 009a lsls r2, r3, #2 + 8007848: 4b9e ldr r3, [pc, #632] ; (8007ac4 ) + 800784a: 18d3 adds r3, r2, r3 + 800784c: 681b ldr r3, [r3, #0] + 800784e: 469f mov pc, r3 + case SYN_SENT: + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("SYN-SENT: ackno %"U32_F" pcb->snd_nxt %"U32_F" unacked %"U32_F"\n", ackno, + pcb->snd_nxt, ntohl(pcb->unacked->tcphdr->seqno))); + /* received SYN ACK with expected sequence number? */ + if ((flags & TCP_ACK) && (flags & TCP_SYN) + 8007850: 4b97 ldr r3, [pc, #604] ; (8007ab0 ) + 8007852: 781b ldrb r3, [r3, #0] + 8007854: 001a movs r2, r3 + 8007856: 2310 movs r3, #16 + 8007858: 4013 ands r3, r2 + 800785a: d100 bne.n 800785e + 800785c: e0be b.n 80079dc + 800785e: 4b94 ldr r3, [pc, #592] ; (8007ab0 ) + 8007860: 781b ldrb r3, [r3, #0] + 8007862: 001a movs r2, r3 + 8007864: 2302 movs r3, #2 + 8007866: 4013 ands r3, r2 + 8007868: d100 bne.n 800786c + 800786a: e0b7 b.n 80079dc + && ackno == ntohl(pcb->unacked->tcphdr->seqno) + 1) { + 800786c: 687b ldr r3, [r7, #4] + 800786e: 6f1b ldr r3, [r3, #112] ; 0x70 + 8007870: 68db ldr r3, [r3, #12] + 8007872: 791a ldrb r2, [r3, #4] + 8007874: 7959 ldrb r1, [r3, #5] + 8007876: 0209 lsls r1, r1, #8 + 8007878: 430a orrs r2, r1 + 800787a: 7999 ldrb r1, [r3, #6] + 800787c: 0409 lsls r1, r1, #16 + 800787e: 430a orrs r2, r1 + 8007880: 79db ldrb r3, [r3, #7] + 8007882: 061b lsls r3, r3, #24 + 8007884: 4313 orrs r3, r2 + 8007886: 0018 movs r0, r3 + 8007888: f7fc ff03 bl 8004692 + 800788c: 0003 movs r3, r0 + 800788e: 1c5a adds r2, r3, #1 + 8007890: 4b88 ldr r3, [pc, #544] ; (8007ab4 ) + 8007892: 681b ldr r3, [r3, #0] + 8007894: 429a cmp r2, r3 + 8007896: d000 beq.n 800789a + 8007898: e0a0 b.n 80079dc + pcb->snd_buf++; + 800789a: 687b ldr r3, [r7, #4] + 800789c: 2266 movs r2, #102 ; 0x66 + 800789e: 5a9b ldrh r3, [r3, r2] + 80078a0: 3301 adds r3, #1 + 80078a2: b299 uxth r1, r3 + 80078a4: 687b ldr r3, [r7, #4] + 80078a6: 2266 movs r2, #102 ; 0x66 + 80078a8: 5299 strh r1, [r3, r2] + pcb->rcv_nxt = seqno + 1; + 80078aa: 4b83 ldr r3, [pc, #524] ; (8007ab8 ) + 80078ac: 681b ldr r3, [r3, #0] + 80078ae: 1c5a adds r2, r3, #1 + 80078b0: 687b ldr r3, [r7, #4] + 80078b2: 629a str r2, [r3, #40] ; 0x28 + pcb->rcv_ann_right_edge = pcb->rcv_nxt; + 80078b4: 687b ldr r3, [r7, #4] + 80078b6: 6a9a ldr r2, [r3, #40] ; 0x28 + 80078b8: 687b ldr r3, [r7, #4] + 80078ba: 631a str r2, [r3, #48] ; 0x30 + pcb->lastack = ackno; + 80078bc: 4b7d ldr r3, [pc, #500] ; (8007ab4 ) + 80078be: 681a ldr r2, [r3, #0] + 80078c0: 687b ldr r3, [r7, #4] + 80078c2: 649a str r2, [r3, #72] ; 0x48 + pcb->snd_wnd = tcphdr->wnd; + 80078c4: 4b80 ldr r3, [pc, #512] ; (8007ac8 ) + 80078c6: 681b ldr r3, [r3, #0] + 80078c8: 7b9a ldrb r2, [r3, #14] + 80078ca: 7bdb ldrb r3, [r3, #15] + 80078cc: 021b lsls r3, r3, #8 + 80078ce: 4313 orrs r3, r2 + 80078d0: b299 uxth r1, r3 + 80078d2: 687b ldr r3, [r7, #4] + 80078d4: 2260 movs r2, #96 ; 0x60 + 80078d6: 5299 strh r1, [r3, r2] + pcb->snd_wnd_max = tcphdr->wnd; + 80078d8: 4b7b ldr r3, [pc, #492] ; (8007ac8 ) + 80078da: 681b ldr r3, [r3, #0] + 80078dc: 7b9a ldrb r2, [r3, #14] + 80078de: 7bdb ldrb r3, [r3, #15] + 80078e0: 021b lsls r3, r3, #8 + 80078e2: 4313 orrs r3, r2 + 80078e4: b299 uxth r1, r3 + 80078e6: 687b ldr r3, [r7, #4] + 80078e8: 2262 movs r2, #98 ; 0x62 + 80078ea: 5299 strh r1, [r3, r2] + pcb->snd_wl1 = seqno - 1; /* initialise to seqno - 1 to force window update */ + 80078ec: 4b72 ldr r3, [pc, #456] ; (8007ab8 ) + 80078ee: 681b ldr r3, [r3, #0] + 80078f0: 1e5a subs r2, r3, #1 + 80078f2: 687b ldr r3, [r7, #4] + 80078f4: 655a str r2, [r3, #84] ; 0x54 + pcb->state = ESTABLISHED; + 80078f6: 687b ldr r3, [r7, #4] + 80078f8: 2204 movs r2, #4 + 80078fa: 761a strb r2, [r3, #24] + +#if TCP_CALCULATE_EFF_SEND_MSS + pcb->mss = tcp_eff_send_mss(pcb->mss, &(pcb->remote_ip)); + 80078fc: 687b ldr r3, [r7, #4] + 80078fe: 8eda ldrh r2, [r3, #54] ; 0x36 + 8007900: 687b ldr r3, [r7, #4] + 8007902: 3304 adds r3, #4 + 8007904: 0019 movs r1, r3 + 8007906: 0010 movs r0, r2 + 8007908: f7ff f936 bl 8006b78 + 800790c: 0003 movs r3, r0 + 800790e: 001a movs r2, r3 + 8007910: 687b ldr r3, [r7, #4] + 8007912: 86da strh r2, [r3, #54] ; 0x36 +#endif /* TCP_CALCULATE_EFF_SEND_MSS */ + + /* Set ssthresh again after changing pcb->mss (already set in tcp_connect + * but for the default value of pcb->mss) */ + pcb->ssthresh = pcb->mss * 10; + 8007914: 687b ldr r3, [r7, #4] + 8007916: 8edb ldrh r3, [r3, #54] ; 0x36 + 8007918: 1c1a adds r2, r3, #0 + 800791a: 0092 lsls r2, r2, #2 + 800791c: 18d3 adds r3, r2, r3 + 800791e: 18db adds r3, r3, r3 + 8007920: b299 uxth r1, r3 + 8007922: 687b ldr r3, [r7, #4] + 8007924: 224e movs r2, #78 ; 0x4e + 8007926: 5299 strh r1, [r3, r2] + + pcb->cwnd = ((pcb->cwnd == 1) ? (pcb->mss * 2) : pcb->mss); + 8007928: 687b ldr r3, [r7, #4] + 800792a: 224c movs r2, #76 ; 0x4c + 800792c: 5a9b ldrh r3, [r3, r2] + 800792e: 2b01 cmp r3, #1 + 8007930: d104 bne.n 800793c + 8007932: 687b ldr r3, [r7, #4] + 8007934: 8edb ldrh r3, [r3, #54] ; 0x36 + 8007936: 18db adds r3, r3, r3 + 8007938: b29b uxth r3, r3 + 800793a: e001 b.n 8007940 + 800793c: 687b ldr r3, [r7, #4] + 800793e: 8edb ldrh r3, [r3, #54] ; 0x36 + 8007940: 687a ldr r2, [r7, #4] + 8007942: 214c movs r1, #76 ; 0x4c + 8007944: 5253 strh r3, [r2, r1] + LWIP_ASSERT("pcb->snd_queuelen > 0", (pcb->snd_queuelen > 0)); + --pcb->snd_queuelen; + 8007946: 687b ldr r3, [r7, #4] + 8007948: 2268 movs r2, #104 ; 0x68 + 800794a: 5a9b ldrh r3, [r3, r2] + 800794c: 3b01 subs r3, #1 + 800794e: b299 uxth r1, r3 + 8007950: 687b ldr r3, [r7, #4] + 8007952: 2268 movs r2, #104 ; 0x68 + 8007954: 5299 strh r1, [r3, r2] + LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_process: SYN-SENT --queuelen %"U16_F"\n", (u16_t)pcb->snd_queuelen)); + rseg = pcb->unacked; + 8007956: 687b ldr r3, [r7, #4] + 8007958: 6f1b ldr r3, [r3, #112] ; 0x70 + 800795a: 60bb str r3, [r7, #8] + pcb->unacked = rseg->next; + 800795c: 68bb ldr r3, [r7, #8] + 800795e: 681a ldr r2, [r3, #0] + 8007960: 687b ldr r3, [r7, #4] + 8007962: 671a str r2, [r3, #112] ; 0x70 + tcp_seg_free(rseg); + 8007964: 68bb ldr r3, [r7, #8] + 8007966: 0018 movs r0, r3 + 8007968: f7fe fed9 bl 800671e + + /* If there's nothing left to acknowledge, stop the retransmit + timer, otherwise reset it to start again */ + if(pcb->unacked == NULL) + 800796c: 687b ldr r3, [r7, #4] + 800796e: 6f1b ldr r3, [r3, #112] ; 0x70 + 8007970: 2b00 cmp r3, #0 + 8007972: d104 bne.n 800797e + pcb->rtime = -1; + 8007974: 687b ldr r3, [r7, #4] + 8007976: 2201 movs r2, #1 + 8007978: 4252 negs r2, r2 + 800797a: 869a strh r2, [r3, #52] ; 0x34 + 800797c: e006 b.n 800798c + else { + pcb->rtime = 0; + 800797e: 687b ldr r3, [r7, #4] + 8007980: 2200 movs r2, #0 + 8007982: 869a strh r2, [r3, #52] ; 0x34 + pcb->nrtx = 0; + 8007984: 687b ldr r3, [r7, #4] + 8007986: 2246 movs r2, #70 ; 0x46 + 8007988: 2100 movs r1, #0 + 800798a: 5499 strb r1, [r3, r2] + } + + /* Call the user specified function to call when sucessfully + * connected. */ + TCP_EVENT_CONNECTED(pcb, ERR_OK, err); + 800798c: 687b ldr r3, [r7, #4] + 800798e: 2284 movs r2, #132 ; 0x84 + 8007990: 589b ldr r3, [r3, r2] + 8007992: 2b00 cmp r3, #0 + 8007994: d00d beq.n 80079b2 + 8007996: 687b ldr r3, [r7, #4] + 8007998: 2284 movs r2, #132 ; 0x84 + 800799a: 589d ldr r5, [r3, r2] + 800799c: 687b ldr r3, [r7, #4] + 800799e: 691b ldr r3, [r3, #16] + 80079a0: 220e movs r2, #14 + 80079a2: 18bc adds r4, r7, r2 + 80079a4: 6879 ldr r1, [r7, #4] + 80079a6: 2200 movs r2, #0 + 80079a8: 0018 movs r0, r3 + 80079aa: 47a8 blx r5 + 80079ac: 0003 movs r3, r0 + 80079ae: 7023 strb r3, [r4, #0] + 80079b0: e003 b.n 80079ba + 80079b2: 230e movs r3, #14 + 80079b4: 18fb adds r3, r7, r3 + 80079b6: 2200 movs r2, #0 + 80079b8: 701a strb r2, [r3, #0] + if (err == ERR_ABRT) { + 80079ba: 230e movs r3, #14 + 80079bc: 18fb adds r3, r7, r3 + 80079be: 781b ldrb r3, [r3, #0] + 80079c0: b25b sxtb r3, r3 + 80079c2: 330a adds r3, #10 + 80079c4: d102 bne.n 80079cc + return ERR_ABRT; + 80079c6: 230a movs r3, #10 + 80079c8: 425b negs r3, r3 + 80079ca: e240 b.n 8007e4e + } + tcp_ack_now(pcb); + 80079cc: 687b ldr r3, [r7, #4] + 80079ce: 7f9b ldrb r3, [r3, #30] + 80079d0: 2202 movs r2, #2 + 80079d2: 4313 orrs r3, r2 + 80079d4: b2da uxtb r2, r3 + 80079d6: 687b ldr r3, [r7, #4] + 80079d8: 779a strb r2, [r3, #30] + else if (flags & TCP_ACK) { + /* send a RST to bring the other side in a non-synchronized state. */ + tcp_rst(ackno, seqno + tcplen, ip_current_dest_addr(), ip_current_src_addr(), + tcphdr->dest, tcphdr->src); + } + break; + 80079da: e22a b.n 8007e32 + else if (flags & TCP_ACK) { + 80079dc: 4b34 ldr r3, [pc, #208] ; (8007ab0 ) + 80079de: 781b ldrb r3, [r3, #0] + 80079e0: 001a movs r2, r3 + 80079e2: 2310 movs r3, #16 + 80079e4: 4013 ands r3, r2 + 80079e6: d100 bne.n 80079ea + 80079e8: e223 b.n 8007e32 + tcp_rst(ackno, seqno + tcplen, ip_current_dest_addr(), ip_current_src_addr(), + 80079ea: 4b32 ldr r3, [pc, #200] ; (8007ab4 ) + 80079ec: 6818 ldr r0, [r3, #0] + 80079ee: 4b37 ldr r3, [pc, #220] ; (8007acc ) + 80079f0: 881b ldrh r3, [r3, #0] + 80079f2: 001a movs r2, r3 + 80079f4: 4b30 ldr r3, [pc, #192] ; (8007ab8 ) + 80079f6: 681b ldr r3, [r3, #0] + 80079f8: 18d4 adds r4, r2, r3 + tcphdr->dest, tcphdr->src); + 80079fa: 4b33 ldr r3, [pc, #204] ; (8007ac8 ) + 80079fc: 681b ldr r3, [r3, #0] + tcp_rst(ackno, seqno + tcplen, ip_current_dest_addr(), ip_current_src_addr(), + 80079fe: 789a ldrb r2, [r3, #2] + 8007a00: 78db ldrb r3, [r3, #3] + 8007a02: 021b lsls r3, r3, #8 + 8007a04: 4313 orrs r3, r2 + 8007a06: b29a uxth r2, r3 + tcphdr->dest, tcphdr->src); + 8007a08: 4b2f ldr r3, [pc, #188] ; (8007ac8 ) + 8007a0a: 681b ldr r3, [r3, #0] + tcp_rst(ackno, seqno + tcplen, ip_current_dest_addr(), ip_current_src_addr(), + 8007a0c: 7819 ldrb r1, [r3, #0] + 8007a0e: 785b ldrb r3, [r3, #1] + 8007a10: 021b lsls r3, r3, #8 + 8007a12: 430b orrs r3, r1 + 8007a14: b29b uxth r3, r3 + 8007a16: 4d2e ldr r5, [pc, #184] ; (8007ad0 ) + 8007a18: 492e ldr r1, [pc, #184] ; (8007ad4 ) + 8007a1a: 9301 str r3, [sp, #4] + 8007a1c: 9200 str r2, [sp, #0] + 8007a1e: 002b movs r3, r5 + 8007a20: 000a movs r2, r1 + 8007a22: 0021 movs r1, r4 + 8007a24: f002 fad2 bl 8009fcc + break; + 8007a28: e203 b.n 8007e32 + case SYN_RCVD: + if (flags & TCP_ACK) { + 8007a2a: 4b21 ldr r3, [pc, #132] ; (8007ab0 ) + 8007a2c: 781b ldrb r3, [r3, #0] + 8007a2e: 001a movs r2, r3 + 8007a30: 2310 movs r3, #16 + 8007a32: 4013 ands r3, r2 + 8007a34: d100 bne.n 8007a38 + 8007a36: e0a6 b.n 8007b86 + /* expected ACK number? */ + if (TCP_SEQ_BETWEEN(ackno, pcb->lastack+1, pcb->snd_nxt)) { + 8007a38: 4b1e ldr r3, [pc, #120] ; (8007ab4 ) + 8007a3a: 681a ldr r2, [r3, #0] + 8007a3c: 687b ldr r3, [r7, #4] + 8007a3e: 6c9b ldr r3, [r3, #72] ; 0x48 + 8007a40: 1ad3 subs r3, r2, r3 + 8007a42: 3b01 subs r3, #1 + 8007a44: 2b00 cmp r3, #0 + 8007a46: da00 bge.n 8007a4a + 8007a48: e07d b.n 8007b46 + 8007a4a: 4b1a ldr r3, [pc, #104] ; (8007ab4 ) + 8007a4c: 681a ldr r2, [r3, #0] + 8007a4e: 687b ldr r3, [r7, #4] + 8007a50: 6d1b ldr r3, [r3, #80] ; 0x50 + 8007a52: 1ad3 subs r3, r2, r3 + 8007a54: 2b00 cmp r3, #0 + 8007a56: dd00 ble.n 8007a5a + 8007a58: e075 b.n 8007b46 + u16_t old_cwnd; + pcb->state = ESTABLISHED; + 8007a5a: 687b ldr r3, [r7, #4] + 8007a5c: 2204 movs r2, #4 + 8007a5e: 761a strb r2, [r3, #24] + LWIP_DEBUGF(TCP_DEBUG, ("TCP connection established %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest)); +#if LWIP_CALLBACK_API + LWIP_ASSERT("pcb->accept != NULL", pcb->accept != NULL); +#endif + /* Call the accept function. */ + TCP_EVENT_ACCEPT(pcb, ERR_OK, err); + 8007a60: 687b ldr r3, [r7, #4] + 8007a62: 695b ldr r3, [r3, #20] + 8007a64: 2b00 cmp r3, #0 + 8007a66: d00c beq.n 8007a82 + 8007a68: 687b ldr r3, [r7, #4] + 8007a6a: 695d ldr r5, [r3, #20] + 8007a6c: 687b ldr r3, [r7, #4] + 8007a6e: 691b ldr r3, [r3, #16] + 8007a70: 220e movs r2, #14 + 8007a72: 18bc adds r4, r7, r2 + 8007a74: 6879 ldr r1, [r7, #4] + 8007a76: 2200 movs r2, #0 + 8007a78: 0018 movs r0, r3 + 8007a7a: 47a8 blx r5 + 8007a7c: 0003 movs r3, r0 + 8007a7e: 7023 strb r3, [r4, #0] + 8007a80: e003 b.n 8007a8a + 8007a82: 230e movs r3, #14 + 8007a84: 18fb adds r3, r7, r3 + 8007a86: 22f2 movs r2, #242 ; 0xf2 + 8007a88: 701a strb r2, [r3, #0] + if (err != ERR_OK) { + 8007a8a: 230e movs r3, #14 + 8007a8c: 18fb adds r3, r7, r3 + 8007a8e: 781b ldrb r3, [r3, #0] + 8007a90: b25b sxtb r3, r3 + 8007a92: 2b00 cmp r3, #0 + 8007a94: d020 beq.n 8007ad8 + /* If the accept function returns with an error, we abort + * the connection. */ + /* Already aborted? */ + if (err != ERR_ABRT) { + 8007a96: 230e movs r3, #14 + 8007a98: 18fb adds r3, r7, r3 + 8007a9a: 781b ldrb r3, [r3, #0] + 8007a9c: b25b sxtb r3, r3 + 8007a9e: 330a adds r3, #10 + 8007aa0: d003 beq.n 8007aaa + tcp_abort(pcb); + 8007aa2: 687b ldr r3, [r7, #4] + 8007aa4: 0018 movs r0, r3 + 8007aa6: f7fe fa69 bl 8005f7c + } + return ERR_ABRT; + 8007aaa: 230a movs r3, #10 + 8007aac: 425b negs r3, r3 + 8007aae: e1ce b.n 8007e4e + 8007ab0: 2000229c .word 0x2000229c + 8007ab4: 20002298 .word 0x20002298 + 8007ab8: 20002294 .word 0x20002294 + 8007abc: 200022a0 .word 0x200022a0 + 8007ac0: 20003278 .word 0x20003278 + 8007ac4: 0800fd98 .word 0x0800fd98 + 8007ac8: 2000228c .word 0x2000228c + 8007acc: 2000229e .word 0x2000229e + 8007ad0: 20003294 .word 0x20003294 + 8007ad4: 2000329c .word 0x2000329c + } + old_cwnd = pcb->cwnd; + 8007ad8: 230c movs r3, #12 + 8007ada: 18fb adds r3, r7, r3 + 8007adc: 687a ldr r2, [r7, #4] + 8007ade: 214c movs r1, #76 ; 0x4c + 8007ae0: 5a52 ldrh r2, [r2, r1] + 8007ae2: 801a strh r2, [r3, #0] + /* If there was any data contained within this ACK, + * we'd better pass it on to the application as well. */ + tcp_receive(pcb); + 8007ae4: 687b ldr r3, [r7, #4] + 8007ae6: 0018 movs r0, r3 + 8007ae8: f000 fa7c bl 8007fe4 + + /* Prevent ACK for SYN to generate a sent event */ + if (pcb->acked != 0) { + 8007aec: 687b ldr r3, [r7, #4] + 8007aee: 2264 movs r2, #100 ; 0x64 + 8007af0: 5a9b ldrh r3, [r3, r2] + 8007af2: 2b00 cmp r3, #0 + 8007af4: d007 beq.n 8007b06 + pcb->acked--; + 8007af6: 687b ldr r3, [r7, #4] + 8007af8: 2264 movs r2, #100 ; 0x64 + 8007afa: 5a9b ldrh r3, [r3, r2] + 8007afc: 3b01 subs r3, #1 + 8007afe: b299 uxth r1, r3 + 8007b00: 687b ldr r3, [r7, #4] + 8007b02: 2264 movs r2, #100 ; 0x64 + 8007b04: 5299 strh r1, [r3, r2] + } + + pcb->cwnd = ((old_cwnd == 1) ? (pcb->mss * 2) : pcb->mss); + 8007b06: 230c movs r3, #12 + 8007b08: 18fb adds r3, r7, r3 + 8007b0a: 881b ldrh r3, [r3, #0] + 8007b0c: 2b01 cmp r3, #1 + 8007b0e: d104 bne.n 8007b1a + 8007b10: 687b ldr r3, [r7, #4] + 8007b12: 8edb ldrh r3, [r3, #54] ; 0x36 + 8007b14: 18db adds r3, r3, r3 + 8007b16: b29b uxth r3, r3 + 8007b18: e001 b.n 8007b1e + 8007b1a: 687b ldr r3, [r7, #4] + 8007b1c: 8edb ldrh r3, [r3, #54] ; 0x36 + 8007b1e: 687a ldr r2, [r7, #4] + 8007b20: 214c movs r1, #76 ; 0x4c + 8007b22: 5253 strh r3, [r2, r1] + + if (recv_flags & TF_GOT_FIN) { + 8007b24: 4bcc ldr r3, [pc, #816] ; (8007e58 ) + 8007b26: 781b ldrb r3, [r3, #0] + 8007b28: 001a movs r2, r3 + 8007b2a: 2320 movs r3, #32 + 8007b2c: 4013 ands r3, r2 + 8007b2e: d03e beq.n 8007bae + tcp_ack_now(pcb); + 8007b30: 687b ldr r3, [r7, #4] + 8007b32: 7f9b ldrb r3, [r3, #30] + 8007b34: 2202 movs r2, #2 + 8007b36: 4313 orrs r3, r2 + 8007b38: b2da uxtb r2, r3 + 8007b3a: 687b ldr r3, [r7, #4] + 8007b3c: 779a strb r2, [r3, #30] + pcb->state = CLOSE_WAIT; + 8007b3e: 687b ldr r3, [r7, #4] + 8007b40: 2207 movs r2, #7 + 8007b42: 761a strb r2, [r3, #24] + if (TCP_SEQ_BETWEEN(ackno, pcb->lastack+1, pcb->snd_nxt)) { + 8007b44: e033 b.n 8007bae + } + } else { + /* incorrect ACK number, send RST */ + tcp_rst(ackno, seqno + tcplen, ip_current_dest_addr(), ip_current_src_addr(), + 8007b46: 4bc5 ldr r3, [pc, #788] ; (8007e5c ) + 8007b48: 6818 ldr r0, [r3, #0] + 8007b4a: 4bc5 ldr r3, [pc, #788] ; (8007e60 ) + 8007b4c: 881b ldrh r3, [r3, #0] + 8007b4e: 001a movs r2, r3 + 8007b50: 4bc4 ldr r3, [pc, #784] ; (8007e64 ) + 8007b52: 681b ldr r3, [r3, #0] + 8007b54: 18d4 adds r4, r2, r3 + tcphdr->dest, tcphdr->src); + 8007b56: 4bc4 ldr r3, [pc, #784] ; (8007e68 ) + 8007b58: 681b ldr r3, [r3, #0] + tcp_rst(ackno, seqno + tcplen, ip_current_dest_addr(), ip_current_src_addr(), + 8007b5a: 789a ldrb r2, [r3, #2] + 8007b5c: 78db ldrb r3, [r3, #3] + 8007b5e: 021b lsls r3, r3, #8 + 8007b60: 4313 orrs r3, r2 + 8007b62: b29a uxth r2, r3 + tcphdr->dest, tcphdr->src); + 8007b64: 4bc0 ldr r3, [pc, #768] ; (8007e68 ) + 8007b66: 681b ldr r3, [r3, #0] + tcp_rst(ackno, seqno + tcplen, ip_current_dest_addr(), ip_current_src_addr(), + 8007b68: 7819 ldrb r1, [r3, #0] + 8007b6a: 785b ldrb r3, [r3, #1] + 8007b6c: 021b lsls r3, r3, #8 + 8007b6e: 430b orrs r3, r1 + 8007b70: b29b uxth r3, r3 + 8007b72: 4dbe ldr r5, [pc, #760] ; (8007e6c ) + 8007b74: 49be ldr r1, [pc, #760] ; (8007e70 ) + 8007b76: 9301 str r3, [sp, #4] + 8007b78: 9200 str r2, [sp, #0] + 8007b7a: 002b movs r3, r5 + 8007b7c: 000a movs r2, r1 + 8007b7e: 0021 movs r1, r4 + 8007b80: f002 fa24 bl 8009fcc + } + } else if ((flags & TCP_SYN) && (seqno == pcb->rcv_nxt - 1)) { + /* Looks like another copy of the SYN - retransmit our SYN-ACK */ + tcp_rexmit(pcb); + } + break; + 8007b84: e157 b.n 8007e36 + } else if ((flags & TCP_SYN) && (seqno == pcb->rcv_nxt - 1)) { + 8007b86: 4bbb ldr r3, [pc, #748] ; (8007e74 ) + 8007b88: 781b ldrb r3, [r3, #0] + 8007b8a: 001a movs r2, r3 + 8007b8c: 2302 movs r3, #2 + 8007b8e: 4013 ands r3, r2 + 8007b90: d100 bne.n 8007b94 + 8007b92: e150 b.n 8007e36 + 8007b94: 687b ldr r3, [r7, #4] + 8007b96: 6a9b ldr r3, [r3, #40] ; 0x28 + 8007b98: 1e5a subs r2, r3, #1 + 8007b9a: 4bb2 ldr r3, [pc, #712] ; (8007e64 ) + 8007b9c: 681b ldr r3, [r3, #0] + 8007b9e: 429a cmp r2, r3 + 8007ba0: d000 beq.n 8007ba4 + 8007ba2: e148 b.n 8007e36 + tcp_rexmit(pcb); + 8007ba4: 687b ldr r3, [r7, #4] + 8007ba6: 0018 movs r0, r3 + 8007ba8: f002 fb66 bl 800a278 + break; + 8007bac: e143 b.n 8007e36 + if (TCP_SEQ_BETWEEN(ackno, pcb->lastack+1, pcb->snd_nxt)) { + 8007bae: 46c0 nop ; (mov r8, r8) + break; + 8007bb0: e141 b.n 8007e36 + case CLOSE_WAIT: + /* FALLTHROUGH */ + case ESTABLISHED: + tcp_receive(pcb); + 8007bb2: 687b ldr r3, [r7, #4] + 8007bb4: 0018 movs r0, r3 + 8007bb6: f000 fa15 bl 8007fe4 + if (recv_flags & TF_GOT_FIN) { /* passive close */ + 8007bba: 4ba7 ldr r3, [pc, #668] ; (8007e58 ) + 8007bbc: 781b ldrb r3, [r3, #0] + 8007bbe: 001a movs r2, r3 + 8007bc0: 2320 movs r3, #32 + 8007bc2: 4013 ands r3, r2 + 8007bc4: d100 bne.n 8007bc8 + 8007bc6: e138 b.n 8007e3a + tcp_ack_now(pcb); + 8007bc8: 687b ldr r3, [r7, #4] + 8007bca: 7f9b ldrb r3, [r3, #30] + 8007bcc: 2202 movs r2, #2 + 8007bce: 4313 orrs r3, r2 + 8007bd0: b2da uxtb r2, r3 + 8007bd2: 687b ldr r3, [r7, #4] + 8007bd4: 779a strb r2, [r3, #30] + pcb->state = CLOSE_WAIT; + 8007bd6: 687b ldr r3, [r7, #4] + 8007bd8: 2207 movs r2, #7 + 8007bda: 761a strb r2, [r3, #24] + } + break; + 8007bdc: e12d b.n 8007e3a + case FIN_WAIT_1: + tcp_receive(pcb); + 8007bde: 687b ldr r3, [r7, #4] + 8007be0: 0018 movs r0, r3 + 8007be2: f000 f9ff bl 8007fe4 + if (recv_flags & TF_GOT_FIN) { + 8007be6: 4b9c ldr r3, [pc, #624] ; (8007e58 ) + 8007be8: 781b ldrb r3, [r3, #0] + 8007bea: 001a movs r2, r3 + 8007bec: 2320 movs r3, #32 + 8007bee: 4013 ands r3, r2 + 8007bf0: d059 beq.n 8007ca6 + if ((flags & TCP_ACK) && (ackno == pcb->snd_nxt)) { + 8007bf2: 4ba0 ldr r3, [pc, #640] ; (8007e74 ) + 8007bf4: 781b ldrb r3, [r3, #0] + 8007bf6: 001a movs r2, r3 + 8007bf8: 2310 movs r3, #16 + 8007bfa: 4013 ands r3, r2 + 8007bfc: d048 beq.n 8007c90 + 8007bfe: 687b ldr r3, [r7, #4] + 8007c00: 6d1a ldr r2, [r3, #80] ; 0x50 + 8007c02: 4b96 ldr r3, [pc, #600] ; (8007e5c ) + 8007c04: 681b ldr r3, [r3, #0] + 8007c06: 429a cmp r2, r3 + 8007c08: d142 bne.n 8007c90 + LWIP_DEBUGF(TCP_DEBUG, + ("TCP connection closed: FIN_WAIT_1 %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest)); + tcp_ack_now(pcb); + 8007c0a: 687b ldr r3, [r7, #4] + 8007c0c: 7f9b ldrb r3, [r3, #30] + 8007c0e: 2202 movs r2, #2 + 8007c10: 4313 orrs r3, r2 + 8007c12: b2da uxtb r2, r3 + 8007c14: 687b ldr r3, [r7, #4] + 8007c16: 779a strb r2, [r3, #30] + tcp_pcb_purge(pcb); + 8007c18: 687b ldr r3, [r7, #4] + 8007c1a: 0018 movs r0, r3 + 8007c1c: f7fe ff04 bl 8006a28 + TCP_RMV_ACTIVE(pcb); + 8007c20: 4b95 ldr r3, [pc, #596] ; (8007e78 ) + 8007c22: 681b ldr r3, [r3, #0] + 8007c24: 687a ldr r2, [r7, #4] + 8007c26: 429a cmp r2, r3 + 8007c28: d105 bne.n 8007c36 + 8007c2a: 4b93 ldr r3, [pc, #588] ; (8007e78 ) + 8007c2c: 681b ldr r3, [r3, #0] + 8007c2e: 68da ldr r2, [r3, #12] + 8007c30: 4b91 ldr r3, [pc, #580] ; (8007e78 ) + 8007c32: 601a str r2, [r3, #0] + 8007c34: e019 b.n 8007c6a + 8007c36: 4b90 ldr r3, [pc, #576] ; (8007e78 ) + 8007c38: 681a ldr r2, [r3, #0] + 8007c3a: 4b90 ldr r3, [pc, #576] ; (8007e7c ) + 8007c3c: 601a str r2, [r3, #0] + 8007c3e: e010 b.n 8007c62 + 8007c40: 4b8e ldr r3, [pc, #568] ; (8007e7c ) + 8007c42: 681b ldr r3, [r3, #0] + 8007c44: 68db ldr r3, [r3, #12] + 8007c46: 687a ldr r2, [r7, #4] + 8007c48: 429a cmp r2, r3 + 8007c4a: d105 bne.n 8007c58 + 8007c4c: 4b8b ldr r3, [pc, #556] ; (8007e7c ) + 8007c4e: 681b ldr r3, [r3, #0] + 8007c50: 687a ldr r2, [r7, #4] + 8007c52: 68d2 ldr r2, [r2, #12] + 8007c54: 60da str r2, [r3, #12] + 8007c56: e008 b.n 8007c6a + 8007c58: 4b88 ldr r3, [pc, #544] ; (8007e7c ) + 8007c5a: 681b ldr r3, [r3, #0] + 8007c5c: 68da ldr r2, [r3, #12] + 8007c5e: 4b87 ldr r3, [pc, #540] ; (8007e7c ) + 8007c60: 601a str r2, [r3, #0] + 8007c62: 4b86 ldr r3, [pc, #536] ; (8007e7c ) + 8007c64: 681b ldr r3, [r3, #0] + 8007c66: 2b00 cmp r3, #0 + 8007c68: d1ea bne.n 8007c40 + 8007c6a: 687b ldr r3, [r7, #4] + 8007c6c: 2200 movs r2, #0 + 8007c6e: 60da str r2, [r3, #12] + 8007c70: 4b83 ldr r3, [pc, #524] ; (8007e80 ) + 8007c72: 2201 movs r2, #1 + 8007c74: 701a strb r2, [r3, #0] + pcb->state = TIME_WAIT; + 8007c76: 687b ldr r3, [r7, #4] + 8007c78: 220a movs r2, #10 + 8007c7a: 761a strb r2, [r3, #24] + TCP_REG(&tcp_tw_pcbs, pcb); + 8007c7c: 4b81 ldr r3, [pc, #516] ; (8007e84 ) + 8007c7e: 681a ldr r2, [r3, #0] + 8007c80: 687b ldr r3, [r7, #4] + 8007c82: 60da str r2, [r3, #12] + 8007c84: 4b7f ldr r3, [pc, #508] ; (8007e84 ) + 8007c86: 687a ldr r2, [r7, #4] + 8007c88: 601a str r2, [r3, #0] + 8007c8a: f002 fcf3 bl 800a674 + pcb->state = CLOSING; + } + } else if ((flags & TCP_ACK) && (ackno == pcb->snd_nxt)) { + pcb->state = FIN_WAIT_2; + } + break; + 8007c8e: e0d6 b.n 8007e3e + tcp_ack_now(pcb); + 8007c90: 687b ldr r3, [r7, #4] + 8007c92: 7f9b ldrb r3, [r3, #30] + 8007c94: 2202 movs r2, #2 + 8007c96: 4313 orrs r3, r2 + 8007c98: b2da uxtb r2, r3 + 8007c9a: 687b ldr r3, [r7, #4] + 8007c9c: 779a strb r2, [r3, #30] + pcb->state = CLOSING; + 8007c9e: 687b ldr r3, [r7, #4] + 8007ca0: 2208 movs r2, #8 + 8007ca2: 761a strb r2, [r3, #24] + break; + 8007ca4: e0cb b.n 8007e3e + } else if ((flags & TCP_ACK) && (ackno == pcb->snd_nxt)) { + 8007ca6: 4b73 ldr r3, [pc, #460] ; (8007e74 ) + 8007ca8: 781b ldrb r3, [r3, #0] + 8007caa: 001a movs r2, r3 + 8007cac: 2310 movs r3, #16 + 8007cae: 4013 ands r3, r2 + 8007cb0: d100 bne.n 8007cb4 + 8007cb2: e0c4 b.n 8007e3e + 8007cb4: 687b ldr r3, [r7, #4] + 8007cb6: 6d1a ldr r2, [r3, #80] ; 0x50 + 8007cb8: 4b68 ldr r3, [pc, #416] ; (8007e5c ) + 8007cba: 681b ldr r3, [r3, #0] + 8007cbc: 429a cmp r2, r3 + 8007cbe: d000 beq.n 8007cc2 + 8007cc0: e0bd b.n 8007e3e + pcb->state = FIN_WAIT_2; + 8007cc2: 687b ldr r3, [r7, #4] + 8007cc4: 2206 movs r2, #6 + 8007cc6: 761a strb r2, [r3, #24] + break; + 8007cc8: e0b9 b.n 8007e3e + case FIN_WAIT_2: + tcp_receive(pcb); + 8007cca: 687b ldr r3, [r7, #4] + 8007ccc: 0018 movs r0, r3 + 8007cce: f000 f989 bl 8007fe4 + if (recv_flags & TF_GOT_FIN) { + 8007cd2: 4b61 ldr r3, [pc, #388] ; (8007e58 ) + 8007cd4: 781b ldrb r3, [r3, #0] + 8007cd6: 001a movs r2, r3 + 8007cd8: 2320 movs r3, #32 + 8007cda: 4013 ands r3, r2 + 8007cdc: d100 bne.n 8007ce0 + 8007cde: e0b0 b.n 8007e42 + LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed: FIN_WAIT_2 %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest)); + tcp_ack_now(pcb); + 8007ce0: 687b ldr r3, [r7, #4] + 8007ce2: 7f9b ldrb r3, [r3, #30] + 8007ce4: 2202 movs r2, #2 + 8007ce6: 4313 orrs r3, r2 + 8007ce8: b2da uxtb r2, r3 + 8007cea: 687b ldr r3, [r7, #4] + 8007cec: 779a strb r2, [r3, #30] + tcp_pcb_purge(pcb); + 8007cee: 687b ldr r3, [r7, #4] + 8007cf0: 0018 movs r0, r3 + 8007cf2: f7fe fe99 bl 8006a28 + TCP_RMV_ACTIVE(pcb); + 8007cf6: 4b60 ldr r3, [pc, #384] ; (8007e78 ) + 8007cf8: 681b ldr r3, [r3, #0] + 8007cfa: 687a ldr r2, [r7, #4] + 8007cfc: 429a cmp r2, r3 + 8007cfe: d105 bne.n 8007d0c + 8007d00: 4b5d ldr r3, [pc, #372] ; (8007e78 ) + 8007d02: 681b ldr r3, [r3, #0] + 8007d04: 68da ldr r2, [r3, #12] + 8007d06: 4b5c ldr r3, [pc, #368] ; (8007e78 ) + 8007d08: 601a str r2, [r3, #0] + 8007d0a: e019 b.n 8007d40 + 8007d0c: 4b5a ldr r3, [pc, #360] ; (8007e78 ) + 8007d0e: 681a ldr r2, [r3, #0] + 8007d10: 4b5a ldr r3, [pc, #360] ; (8007e7c ) + 8007d12: 601a str r2, [r3, #0] + 8007d14: e010 b.n 8007d38 + 8007d16: 4b59 ldr r3, [pc, #356] ; (8007e7c ) + 8007d18: 681b ldr r3, [r3, #0] + 8007d1a: 68db ldr r3, [r3, #12] + 8007d1c: 687a ldr r2, [r7, #4] + 8007d1e: 429a cmp r2, r3 + 8007d20: d105 bne.n 8007d2e + 8007d22: 4b56 ldr r3, [pc, #344] ; (8007e7c ) + 8007d24: 681b ldr r3, [r3, #0] + 8007d26: 687a ldr r2, [r7, #4] + 8007d28: 68d2 ldr r2, [r2, #12] + 8007d2a: 60da str r2, [r3, #12] + 8007d2c: e008 b.n 8007d40 + 8007d2e: 4b53 ldr r3, [pc, #332] ; (8007e7c ) + 8007d30: 681b ldr r3, [r3, #0] + 8007d32: 68da ldr r2, [r3, #12] + 8007d34: 4b51 ldr r3, [pc, #324] ; (8007e7c ) + 8007d36: 601a str r2, [r3, #0] + 8007d38: 4b50 ldr r3, [pc, #320] ; (8007e7c ) + 8007d3a: 681b ldr r3, [r3, #0] + 8007d3c: 2b00 cmp r3, #0 + 8007d3e: d1ea bne.n 8007d16 + 8007d40: 687b ldr r3, [r7, #4] + 8007d42: 2200 movs r2, #0 + 8007d44: 60da str r2, [r3, #12] + 8007d46: 4b4e ldr r3, [pc, #312] ; (8007e80 ) + 8007d48: 2201 movs r2, #1 + 8007d4a: 701a strb r2, [r3, #0] + pcb->state = TIME_WAIT; + 8007d4c: 687b ldr r3, [r7, #4] + 8007d4e: 220a movs r2, #10 + 8007d50: 761a strb r2, [r3, #24] + TCP_REG(&tcp_tw_pcbs, pcb); + 8007d52: 4b4c ldr r3, [pc, #304] ; (8007e84 ) + 8007d54: 681a ldr r2, [r3, #0] + 8007d56: 687b ldr r3, [r7, #4] + 8007d58: 60da str r2, [r3, #12] + 8007d5a: 4b4a ldr r3, [pc, #296] ; (8007e84 ) + 8007d5c: 687a ldr r2, [r7, #4] + 8007d5e: 601a str r2, [r3, #0] + 8007d60: f002 fc88 bl 800a674 + } + break; + 8007d64: e06d b.n 8007e42 + case CLOSING: + tcp_receive(pcb); + 8007d66: 687b ldr r3, [r7, #4] + 8007d68: 0018 movs r0, r3 + 8007d6a: f000 f93b bl 8007fe4 + if (flags & TCP_ACK && ackno == pcb->snd_nxt) { + 8007d6e: 4b41 ldr r3, [pc, #260] ; (8007e74 ) + 8007d70: 781b ldrb r3, [r3, #0] + 8007d72: 001a movs r2, r3 + 8007d74: 2310 movs r3, #16 + 8007d76: 4013 ands r3, r2 + 8007d78: d065 beq.n 8007e46 + 8007d7a: 687b ldr r3, [r7, #4] + 8007d7c: 6d1a ldr r2, [r3, #80] ; 0x50 + 8007d7e: 4b37 ldr r3, [pc, #220] ; (8007e5c ) + 8007d80: 681b ldr r3, [r3, #0] + 8007d82: 429a cmp r2, r3 + 8007d84: d15f bne.n 8007e46 + LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed: CLOSING %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest)); + tcp_pcb_purge(pcb); + 8007d86: 687b ldr r3, [r7, #4] + 8007d88: 0018 movs r0, r3 + 8007d8a: f7fe fe4d bl 8006a28 + TCP_RMV_ACTIVE(pcb); + 8007d8e: 4b3a ldr r3, [pc, #232] ; (8007e78 ) + 8007d90: 681b ldr r3, [r3, #0] + 8007d92: 687a ldr r2, [r7, #4] + 8007d94: 429a cmp r2, r3 + 8007d96: d105 bne.n 8007da4 + 8007d98: 4b37 ldr r3, [pc, #220] ; (8007e78 ) + 8007d9a: 681b ldr r3, [r3, #0] + 8007d9c: 68da ldr r2, [r3, #12] + 8007d9e: 4b36 ldr r3, [pc, #216] ; (8007e78 ) + 8007da0: 601a str r2, [r3, #0] + 8007da2: e019 b.n 8007dd8 + 8007da4: 4b34 ldr r3, [pc, #208] ; (8007e78 ) + 8007da6: 681a ldr r2, [r3, #0] + 8007da8: 4b34 ldr r3, [pc, #208] ; (8007e7c ) + 8007daa: 601a str r2, [r3, #0] + 8007dac: e010 b.n 8007dd0 + 8007dae: 4b33 ldr r3, [pc, #204] ; (8007e7c ) + 8007db0: 681b ldr r3, [r3, #0] + 8007db2: 68db ldr r3, [r3, #12] + 8007db4: 687a ldr r2, [r7, #4] + 8007db6: 429a cmp r2, r3 + 8007db8: d105 bne.n 8007dc6 + 8007dba: 4b30 ldr r3, [pc, #192] ; (8007e7c ) + 8007dbc: 681b ldr r3, [r3, #0] + 8007dbe: 687a ldr r2, [r7, #4] + 8007dc0: 68d2 ldr r2, [r2, #12] + 8007dc2: 60da str r2, [r3, #12] + 8007dc4: e008 b.n 8007dd8 + 8007dc6: 4b2d ldr r3, [pc, #180] ; (8007e7c ) + 8007dc8: 681b ldr r3, [r3, #0] + 8007dca: 68da ldr r2, [r3, #12] + 8007dcc: 4b2b ldr r3, [pc, #172] ; (8007e7c ) + 8007dce: 601a str r2, [r3, #0] + 8007dd0: 4b2a ldr r3, [pc, #168] ; (8007e7c ) + 8007dd2: 681b ldr r3, [r3, #0] + 8007dd4: 2b00 cmp r3, #0 + 8007dd6: d1ea bne.n 8007dae + 8007dd8: 687b ldr r3, [r7, #4] + 8007dda: 2200 movs r2, #0 + 8007ddc: 60da str r2, [r3, #12] + 8007dde: 4b28 ldr r3, [pc, #160] ; (8007e80 ) + 8007de0: 2201 movs r2, #1 + 8007de2: 701a strb r2, [r3, #0] + pcb->state = TIME_WAIT; + 8007de4: 687b ldr r3, [r7, #4] + 8007de6: 220a movs r2, #10 + 8007de8: 761a strb r2, [r3, #24] + TCP_REG(&tcp_tw_pcbs, pcb); + 8007dea: 4b26 ldr r3, [pc, #152] ; (8007e84 ) + 8007dec: 681a ldr r2, [r3, #0] + 8007dee: 687b ldr r3, [r7, #4] + 8007df0: 60da str r2, [r3, #12] + 8007df2: 4b24 ldr r3, [pc, #144] ; (8007e84 ) + 8007df4: 687a ldr r2, [r7, #4] + 8007df6: 601a str r2, [r3, #0] + 8007df8: f002 fc3c bl 800a674 + } + break; + 8007dfc: e023 b.n 8007e46 + case LAST_ACK: + tcp_receive(pcb); + 8007dfe: 687b ldr r3, [r7, #4] + 8007e00: 0018 movs r0, r3 + 8007e02: f000 f8ef bl 8007fe4 + if (flags & TCP_ACK && ackno == pcb->snd_nxt) { + 8007e06: 4b1b ldr r3, [pc, #108] ; (8007e74 ) + 8007e08: 781b ldrb r3, [r3, #0] + 8007e0a: 001a movs r2, r3 + 8007e0c: 2310 movs r3, #16 + 8007e0e: 4013 ands r3, r2 + 8007e10: d01b beq.n 8007e4a + 8007e12: 687b ldr r3, [r7, #4] + 8007e14: 6d1a ldr r2, [r3, #80] ; 0x50 + 8007e16: 4b11 ldr r3, [pc, #68] ; (8007e5c ) + 8007e18: 681b ldr r3, [r3, #0] + 8007e1a: 429a cmp r2, r3 + 8007e1c: d115 bne.n 8007e4a + LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed: LAST_ACK %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest)); + /* bugfix #21699: don't set pcb->state to CLOSED here or we risk leaking segments */ + recv_flags |= TF_CLOSED; + 8007e1e: 4b0e ldr r3, [pc, #56] ; (8007e58 ) + 8007e20: 781b ldrb r3, [r3, #0] + 8007e22: 2210 movs r2, #16 + 8007e24: 4313 orrs r3, r2 + 8007e26: b2da uxtb r2, r3 + 8007e28: 4b0b ldr r3, [pc, #44] ; (8007e58 ) + 8007e2a: 701a strb r2, [r3, #0] + } + break; + 8007e2c: e00d b.n 8007e4a + default: + break; + 8007e2e: 46c0 nop ; (mov r8, r8) + 8007e30: e00c b.n 8007e4c + break; + 8007e32: 46c0 nop ; (mov r8, r8) + 8007e34: e00a b.n 8007e4c + break; + 8007e36: 46c0 nop ; (mov r8, r8) + 8007e38: e008 b.n 8007e4c + break; + 8007e3a: 46c0 nop ; (mov r8, r8) + 8007e3c: e006 b.n 8007e4c + break; + 8007e3e: 46c0 nop ; (mov r8, r8) + 8007e40: e004 b.n 8007e4c + break; + 8007e42: 46c0 nop ; (mov r8, r8) + 8007e44: e002 b.n 8007e4c + break; + 8007e46: 46c0 nop ; (mov r8, r8) + 8007e48: e000 b.n 8007e4c + break; + 8007e4a: 46c0 nop ; (mov r8, r8) + } + return ERR_OK; + 8007e4c: 2300 movs r3, #0 +} + 8007e4e: 0018 movs r0, r3 + 8007e50: 46bd mov sp, r7 + 8007e52: b004 add sp, #16 + 8007e54: bdb0 pop {r4, r5, r7, pc} + 8007e56: 46c0 nop ; (mov r8, r8) + 8007e58: 200022a0 .word 0x200022a0 + 8007e5c: 20002298 .word 0x20002298 + 8007e60: 2000229e .word 0x2000229e + 8007e64: 20002294 .word 0x20002294 + 8007e68: 2000228c .word 0x2000228c + 8007e6c: 20003294 .word 0x20003294 + 8007e70: 2000329c .word 0x2000329c + 8007e74: 2000229c .word 0x2000229c + 8007e78: 20003274 .word 0x20003274 + 8007e7c: 20003280 .word 0x20003280 + 8007e80: 20003270 .word 0x20003270 + 8007e84: 20003288 .word 0x20003288 + +08007e88 : + * + * Called from tcp_receive() + */ +static void +tcp_oos_insert_segment(struct tcp_seg *cseg, struct tcp_seg *next) +{ + 8007e88: b590 push {r4, r7, lr} + 8007e8a: b085 sub sp, #20 + 8007e8c: af00 add r7, sp, #0 + 8007e8e: 6078 str r0, [r7, #4] + 8007e90: 6039 str r1, [r7, #0] + struct tcp_seg *old_seg; + + if (TCPH_FLAGS(cseg->tcphdr) & TCP_FIN) { + 8007e92: 687b ldr r3, [r7, #4] + 8007e94: 68db ldr r3, [r3, #12] + 8007e96: 7b1a ldrb r2, [r3, #12] + 8007e98: 7b5b ldrb r3, [r3, #13] + 8007e9a: 021b lsls r3, r3, #8 + 8007e9c: 4313 orrs r3, r2 + 8007e9e: b29b uxth r3, r3 + 8007ea0: 0018 movs r0, r3 + 8007ea2: f7fc fbcd bl 8004640 + 8007ea6: 0003 movs r3, r0 + 8007ea8: 001a movs r2, r3 + 8007eaa: 2301 movs r3, #1 + 8007eac: 4013 ands r3, r2 + 8007eae: d041 beq.n 8007f34 + /* received segment overlaps all following segments */ + tcp_segs_free(next); + 8007eb0: 683b ldr r3, [r7, #0] + 8007eb2: 0018 movs r0, r3 + 8007eb4: f7fe fc1e bl 80066f4 + next = NULL; + 8007eb8: 2300 movs r3, #0 + 8007eba: 603b str r3, [r7, #0] + 8007ebc: e089 b.n 8007fd2 + oos queue may have segments with FIN flag */ + while (next && + TCP_SEQ_GEQ((seqno + cseg->len), + (next->tcphdr->seqno + next->len))) { + /* cseg with FIN already processed */ + if (TCPH_FLAGS(next->tcphdr) & TCP_FIN) { + 8007ebe: 683b ldr r3, [r7, #0] + 8007ec0: 68db ldr r3, [r3, #12] + 8007ec2: 7b1a ldrb r2, [r3, #12] + 8007ec4: 7b5b ldrb r3, [r3, #13] + 8007ec6: 021b lsls r3, r3, #8 + 8007ec8: 4313 orrs r3, r2 + 8007eca: b29b uxth r3, r3 + 8007ecc: 0018 movs r0, r3 + 8007ece: f7fc fbb7 bl 8004640 + 8007ed2: 0003 movs r3, r0 + 8007ed4: 001a movs r2, r3 + 8007ed6: 2301 movs r3, #1 + 8007ed8: 4013 ands r3, r2 + 8007eda: d022 beq.n 8007f22 + TCPH_SET_FLAG(cseg->tcphdr, TCP_FIN); + 8007edc: 687b ldr r3, [r7, #4] + 8007ede: 68db ldr r3, [r3, #12] + 8007ee0: 7b1a ldrb r2, [r3, #12] + 8007ee2: 7b5b ldrb r3, [r3, #13] + 8007ee4: 021b lsls r3, r3, #8 + 8007ee6: 4313 orrs r3, r2 + 8007ee8: b29c uxth r4, r3 + 8007eea: 2001 movs r0, #1 + 8007eec: f7fc fb92 bl 8004614 + 8007ef0: 0003 movs r3, r0 + 8007ef2: 001a movs r2, r3 + 8007ef4: 687b ldr r3, [r7, #4] + 8007ef6: 68db ldr r3, [r3, #12] + 8007ef8: 4322 orrs r2, r4 + 8007efa: b292 uxth r2, r2 + 8007efc: 21ff movs r1, #255 ; 0xff + 8007efe: 4011 ands r1, r2 + 8007f00: 000c movs r4, r1 + 8007f02: 7b19 ldrb r1, [r3, #12] + 8007f04: 2000 movs r0, #0 + 8007f06: 4001 ands r1, r0 + 8007f08: 1c08 adds r0, r1, #0 + 8007f0a: 1c21 adds r1, r4, #0 + 8007f0c: 4301 orrs r1, r0 + 8007f0e: 7319 strb r1, [r3, #12] + 8007f10: 0a12 lsrs r2, r2, #8 + 8007f12: b290 uxth r0, r2 + 8007f14: 7b5a ldrb r2, [r3, #13] + 8007f16: 2100 movs r1, #0 + 8007f18: 400a ands r2, r1 + 8007f1a: 1c11 adds r1, r2, #0 + 8007f1c: 1c02 adds r2, r0, #0 + 8007f1e: 430a orrs r2, r1 + 8007f20: 735a strb r2, [r3, #13] + } + old_seg = next; + 8007f22: 683b ldr r3, [r7, #0] + 8007f24: 60fb str r3, [r7, #12] + next = next->next; + 8007f26: 683b ldr r3, [r7, #0] + 8007f28: 681b ldr r3, [r3, #0] + 8007f2a: 603b str r3, [r7, #0] + tcp_seg_free(old_seg); + 8007f2c: 68fb ldr r3, [r7, #12] + 8007f2e: 0018 movs r0, r3 + 8007f30: f7fe fbf5 bl 800671e + while (next && + 8007f34: 683b ldr r3, [r7, #0] + 8007f36: 2b00 cmp r3, #0 + 8007f38: d017 beq.n 8007f6a + TCP_SEQ_GEQ((seqno + cseg->len), + 8007f3a: 687b ldr r3, [r7, #4] + 8007f3c: 891b ldrh r3, [r3, #8] + 8007f3e: 001a movs r2, r3 + 8007f40: 4b27 ldr r3, [pc, #156] ; (8007fe0 ) + 8007f42: 681b ldr r3, [r3, #0] + 8007f44: 18d2 adds r2, r2, r3 + 8007f46: 683b ldr r3, [r7, #0] + 8007f48: 68db ldr r3, [r3, #12] + 8007f4a: 7919 ldrb r1, [r3, #4] + 8007f4c: 7958 ldrb r0, [r3, #5] + 8007f4e: 0200 lsls r0, r0, #8 + 8007f50: 4301 orrs r1, r0 + 8007f52: 7998 ldrb r0, [r3, #6] + 8007f54: 0400 lsls r0, r0, #16 + 8007f56: 4301 orrs r1, r0 + 8007f58: 79db ldrb r3, [r3, #7] + 8007f5a: 061b lsls r3, r3, #24 + 8007f5c: 430b orrs r3, r1 + 8007f5e: 0019 movs r1, r3 + 8007f60: 683b ldr r3, [r7, #0] + 8007f62: 891b ldrh r3, [r3, #8] + 8007f64: 18cb adds r3, r1, r3 + 8007f66: 1ad3 subs r3, r2, r3 + while (next && + 8007f68: d5a9 bpl.n 8007ebe + } + if (next && + 8007f6a: 683b ldr r3, [r7, #0] + 8007f6c: 2b00 cmp r3, #0 + 8007f6e: d030 beq.n 8007fd2 + TCP_SEQ_GT(seqno + cseg->len, next->tcphdr->seqno)) { + 8007f70: 687b ldr r3, [r7, #4] + 8007f72: 891b ldrh r3, [r3, #8] + 8007f74: 001a movs r2, r3 + 8007f76: 4b1a ldr r3, [pc, #104] ; (8007fe0 ) + 8007f78: 681b ldr r3, [r3, #0] + 8007f7a: 18d2 adds r2, r2, r3 + 8007f7c: 683b ldr r3, [r7, #0] + 8007f7e: 68db ldr r3, [r3, #12] + 8007f80: 7919 ldrb r1, [r3, #4] + 8007f82: 7958 ldrb r0, [r3, #5] + 8007f84: 0200 lsls r0, r0, #8 + 8007f86: 4301 orrs r1, r0 + 8007f88: 7998 ldrb r0, [r3, #6] + 8007f8a: 0400 lsls r0, r0, #16 + 8007f8c: 4301 orrs r1, r0 + 8007f8e: 79db ldrb r3, [r3, #7] + 8007f90: 061b lsls r3, r3, #24 + 8007f92: 430b orrs r3, r1 + 8007f94: 1ad3 subs r3, r2, r3 + if (next && + 8007f96: 2b00 cmp r3, #0 + 8007f98: dd1b ble.n 8007fd2 + /* We need to trim the incoming segment. */ + cseg->len = (u16_t)(next->tcphdr->seqno - seqno); + 8007f9a: 683b ldr r3, [r7, #0] + 8007f9c: 68db ldr r3, [r3, #12] + 8007f9e: 791a ldrb r2, [r3, #4] + 8007fa0: 7959 ldrb r1, [r3, #5] + 8007fa2: 0209 lsls r1, r1, #8 + 8007fa4: 430a orrs r2, r1 + 8007fa6: 7999 ldrb r1, [r3, #6] + 8007fa8: 0409 lsls r1, r1, #16 + 8007faa: 430a orrs r2, r1 + 8007fac: 79db ldrb r3, [r3, #7] + 8007fae: 061b lsls r3, r3, #24 + 8007fb0: 4313 orrs r3, r2 + 8007fb2: b29a uxth r2, r3 + 8007fb4: 4b0a ldr r3, [pc, #40] ; (8007fe0 ) + 8007fb6: 681b ldr r3, [r3, #0] + 8007fb8: b29b uxth r3, r3 + 8007fba: 1ad3 subs r3, r2, r3 + 8007fbc: b29a uxth r2, r3 + 8007fbe: 687b ldr r3, [r7, #4] + 8007fc0: 811a strh r2, [r3, #8] + pbuf_realloc(cseg->p, cseg->len); + 8007fc2: 687b ldr r3, [r7, #4] + 8007fc4: 685a ldr r2, [r3, #4] + 8007fc6: 687b ldr r3, [r7, #4] + 8007fc8: 891b ldrh r3, [r3, #8] + 8007fca: 0019 movs r1, r3 + 8007fcc: 0010 movs r0, r2 + 8007fce: f7fd fa70 bl 80054b2 + } + } + cseg->next = next; + 8007fd2: 687b ldr r3, [r7, #4] + 8007fd4: 683a ldr r2, [r7, #0] + 8007fd6: 601a str r2, [r3, #0] +} + 8007fd8: 46c0 nop ; (mov r8, r8) + 8007fda: 46bd mov sp, r7 + 8007fdc: b005 add sp, #20 + 8007fde: bd90 pop {r4, r7, pc} + 8007fe0: 20002294 .word 0x20002294 + +08007fe4 : + * + * Called from tcp_process(). + */ +static void +tcp_receive(struct tcp_pcb *pcb) +{ + 8007fe4: b5f0 push {r4, r5, r6, r7, lr} + 8007fe6: b08d sub sp, #52 ; 0x34 + 8007fe8: af00 add r7, sp, #0 + 8007fea: 6078 str r0, [r7, #4] + struct pbuf *p; + s32_t off; + s16_t m; + u32_t right_wnd_edge; + u16_t new_tot_len; + int found_dupack = 0; + 8007fec: 2300 movs r3, #0 + 8007fee: 61bb str r3, [r7, #24] + u16_t ooseq_qlen; +#endif /* TCP_OOSEQ_MAX_BYTES || TCP_OOSEQ_MAX_PBUFS */ + + LWIP_ASSERT("tcp_receive: wrong state", pcb->state >= ESTABLISHED); + + if (flags & TCP_ACK) { + 8007ff0: 4bba ldr r3, [pc, #744] ; (80082dc ) + 8007ff2: 781b ldrb r3, [r3, #0] + 8007ff4: 001a movs r2, r3 + 8007ff6: 2310 movs r3, #16 + 8007ff8: 4013 ands r3, r2 + 8007ffa: d100 bne.n 8007ffe + 8007ffc: e2ed b.n 80085da + right_wnd_edge = pcb->snd_wnd + pcb->snd_wl2; + 8007ffe: 687b ldr r3, [r7, #4] + 8008000: 2260 movs r2, #96 ; 0x60 + 8008002: 5a9b ldrh r3, [r3, r2] + 8008004: 001a movs r2, r3 + 8008006: 687b ldr r3, [r7, #4] + 8008008: 6d9b ldr r3, [r3, #88] ; 0x58 + 800800a: 18d3 adds r3, r2, r3 + 800800c: 617b str r3, [r7, #20] + + /* Update window. */ + if (TCP_SEQ_LT(pcb->snd_wl1, seqno) || + 800800e: 687b ldr r3, [r7, #4] + 8008010: 6d5a ldr r2, [r3, #84] ; 0x54 + 8008012: 4bb3 ldr r3, [pc, #716] ; (80082e0 ) + 8008014: 681b ldr r3, [r3, #0] + 8008016: 1ad3 subs r3, r2, r3 + 8008018: d41d bmi.n 8008056 + (pcb->snd_wl1 == seqno && TCP_SEQ_LT(pcb->snd_wl2, ackno)) || + 800801a: 687b ldr r3, [r7, #4] + 800801c: 6d5a ldr r2, [r3, #84] ; 0x54 + 800801e: 4bb0 ldr r3, [pc, #704] ; (80082e0 ) + 8008020: 681b ldr r3, [r3, #0] + if (TCP_SEQ_LT(pcb->snd_wl1, seqno) || + 8008022: 429a cmp r2, r3 + 8008024: d105 bne.n 8008032 + (pcb->snd_wl1 == seqno && TCP_SEQ_LT(pcb->snd_wl2, ackno)) || + 8008026: 687b ldr r3, [r7, #4] + 8008028: 6d9a ldr r2, [r3, #88] ; 0x58 + 800802a: 4bae ldr r3, [pc, #696] ; (80082e4 ) + 800802c: 681b ldr r3, [r3, #0] + 800802e: 1ad3 subs r3, r2, r3 + 8008030: d411 bmi.n 8008056 + (pcb->snd_wl2 == ackno && tcphdr->wnd > pcb->snd_wnd)) { + 8008032: 687b ldr r3, [r7, #4] + 8008034: 6d9a ldr r2, [r3, #88] ; 0x58 + 8008036: 4bab ldr r3, [pc, #684] ; (80082e4 ) + 8008038: 681b ldr r3, [r3, #0] + (pcb->snd_wl1 == seqno && TCP_SEQ_LT(pcb->snd_wl2, ackno)) || + 800803a: 429a cmp r2, r3 + 800803c: d14f bne.n 80080de + (pcb->snd_wl2 == ackno && tcphdr->wnd > pcb->snd_wnd)) { + 800803e: 4baa ldr r3, [pc, #680] ; (80082e8 ) + 8008040: 681b ldr r3, [r3, #0] + 8008042: 7b9a ldrb r2, [r3, #14] + 8008044: 7bdb ldrb r3, [r3, #15] + 8008046: 021b lsls r3, r3, #8 + 8008048: 4313 orrs r3, r2 + 800804a: b29a uxth r2, r3 + 800804c: 687b ldr r3, [r7, #4] + 800804e: 2160 movs r1, #96 ; 0x60 + 8008050: 5a5b ldrh r3, [r3, r1] + 8008052: 429a cmp r2, r3 + 8008054: d943 bls.n 80080de + pcb->snd_wnd = tcphdr->wnd; + 8008056: 4ba4 ldr r3, [pc, #656] ; (80082e8 ) + 8008058: 681b ldr r3, [r3, #0] + 800805a: 7b9a ldrb r2, [r3, #14] + 800805c: 7bdb ldrb r3, [r3, #15] + 800805e: 021b lsls r3, r3, #8 + 8008060: 4313 orrs r3, r2 + 8008062: b299 uxth r1, r3 + 8008064: 687b ldr r3, [r7, #4] + 8008066: 2260 movs r2, #96 ; 0x60 + 8008068: 5299 strh r1, [r3, r2] + /* keep track of the biggest window announced by the remote host to calculate + the maximum segment size */ + if (pcb->snd_wnd_max < tcphdr->wnd) { + 800806a: 687b ldr r3, [r7, #4] + 800806c: 2262 movs r2, #98 ; 0x62 + 800806e: 5a9a ldrh r2, [r3, r2] + 8008070: 4b9d ldr r3, [pc, #628] ; (80082e8 ) + 8008072: 681b ldr r3, [r3, #0] + 8008074: 7b99 ldrb r1, [r3, #14] + 8008076: 7bdb ldrb r3, [r3, #15] + 8008078: 021b lsls r3, r3, #8 + 800807a: 430b orrs r3, r1 + 800807c: b29b uxth r3, r3 + 800807e: 429a cmp r2, r3 + 8008080: d209 bcs.n 8008096 + pcb->snd_wnd_max = tcphdr->wnd; + 8008082: 4b99 ldr r3, [pc, #612] ; (80082e8 ) + 8008084: 681b ldr r3, [r3, #0] + 8008086: 7b9a ldrb r2, [r3, #14] + 8008088: 7bdb ldrb r3, [r3, #15] + 800808a: 021b lsls r3, r3, #8 + 800808c: 4313 orrs r3, r2 + 800808e: b299 uxth r1, r3 + 8008090: 687b ldr r3, [r7, #4] + 8008092: 2262 movs r2, #98 ; 0x62 + 8008094: 5299 strh r1, [r3, r2] + } + pcb->snd_wl1 = seqno; + 8008096: 4b92 ldr r3, [pc, #584] ; (80082e0 ) + 8008098: 681a ldr r2, [r3, #0] + 800809a: 687b ldr r3, [r7, #4] + 800809c: 655a str r2, [r3, #84] ; 0x54 + pcb->snd_wl2 = ackno; + 800809e: 4b91 ldr r3, [pc, #580] ; (80082e4 ) + 80080a0: 681a ldr r2, [r3, #0] + 80080a2: 687b ldr r3, [r7, #4] + 80080a4: 659a str r2, [r3, #88] ; 0x58 + if (pcb->snd_wnd == 0) { + 80080a6: 687b ldr r3, [r7, #4] + 80080a8: 2260 movs r2, #96 ; 0x60 + 80080aa: 5a9b ldrh r3, [r3, r2] + 80080ac: 2b00 cmp r3, #0 + 80080ae: d10d bne.n 80080cc + if (pcb->persist_backoff == 0) { + 80080b0: 687b ldr r3, [r7, #4] + 80080b2: 2295 movs r2, #149 ; 0x95 + 80080b4: 5c9b ldrb r3, [r3, r2] + 80080b6: 2b00 cmp r3, #0 + 80080b8: d111 bne.n 80080de + /* start persist timer */ + pcb->persist_cnt = 0; + 80080ba: 687b ldr r3, [r7, #4] + 80080bc: 2294 movs r2, #148 ; 0x94 + 80080be: 2100 movs r1, #0 + 80080c0: 5499 strb r1, [r3, r2] + pcb->persist_backoff = 1; + 80080c2: 687b ldr r3, [r7, #4] + 80080c4: 2295 movs r2, #149 ; 0x95 + 80080c6: 2101 movs r1, #1 + 80080c8: 5499 strb r1, [r3, r2] + 80080ca: e008 b.n 80080de + } + } else if (pcb->persist_backoff > 0) { + 80080cc: 687b ldr r3, [r7, #4] + 80080ce: 2295 movs r2, #149 ; 0x95 + 80080d0: 5c9b ldrb r3, [r3, r2] + 80080d2: 2b00 cmp r3, #0 + 80080d4: d003 beq.n 80080de + /* stop persist timer */ + pcb->persist_backoff = 0; + 80080d6: 687b ldr r3, [r7, #4] + 80080d8: 2295 movs r2, #149 ; 0x95 + 80080da: 2100 movs r1, #0 + 80080dc: 5499 strb r1, [r3, r2] + * If it only passes 1, should reset dupack counter + * + */ + + /* Clause 1 */ + if (TCP_SEQ_LEQ(ackno, pcb->lastack)) { + 80080de: 4b81 ldr r3, [pc, #516] ; (80082e4 ) + 80080e0: 681a ldr r2, [r3, #0] + 80080e2: 687b ldr r3, [r7, #4] + 80080e4: 6c9b ldr r3, [r3, #72] ; 0x48 + 80080e6: 1ad3 subs r3, r2, r3 + 80080e8: 2b00 cmp r3, #0 + 80080ea: dc58 bgt.n 800819e + pcb->acked = 0; + 80080ec: 687b ldr r3, [r7, #4] + 80080ee: 2264 movs r2, #100 ; 0x64 + 80080f0: 2100 movs r1, #0 + 80080f2: 5299 strh r1, [r3, r2] + /* Clause 2 */ + if (tcplen == 0) { + 80080f4: 4b7d ldr r3, [pc, #500] ; (80082ec ) + 80080f6: 881b ldrh r3, [r3, #0] + 80080f8: 2b00 cmp r3, #0 + 80080fa: d147 bne.n 800818c + /* Clause 3 */ + if (pcb->snd_wl2 + pcb->snd_wnd == right_wnd_edge){ + 80080fc: 687b ldr r3, [r7, #4] + 80080fe: 6d9b ldr r3, [r3, #88] ; 0x58 + 8008100: 687a ldr r2, [r7, #4] + 8008102: 2160 movs r1, #96 ; 0x60 + 8008104: 5a52 ldrh r2, [r2, r1] + 8008106: 189b adds r3, r3, r2 + 8008108: 697a ldr r2, [r7, #20] + 800810a: 429a cmp r2, r3 + 800810c: d13e bne.n 800818c + /* Clause 4 */ + if (pcb->rtime >= 0) { + 800810e: 687b ldr r3, [r7, #4] + 8008110: 2234 movs r2, #52 ; 0x34 + 8008112: 5e9b ldrsh r3, [r3, r2] + 8008114: 2b00 cmp r3, #0 + 8008116: db39 blt.n 800818c + /* Clause 5 */ + if (pcb->lastack == ackno) { + 8008118: 687b ldr r3, [r7, #4] + 800811a: 6c9a ldr r2, [r3, #72] ; 0x48 + 800811c: 4b71 ldr r3, [pc, #452] ; (80082e4 ) + 800811e: 681b ldr r3, [r3, #0] + 8008120: 429a cmp r2, r3 + 8008122: d133 bne.n 800818c + found_dupack = 1; + 8008124: 2301 movs r3, #1 + 8008126: 61bb str r3, [r7, #24] + if ((u8_t)(pcb->dupacks + 1) > pcb->dupacks) { + 8008128: 687b ldr r3, [r7, #4] + 800812a: 2247 movs r2, #71 ; 0x47 + 800812c: 5c9b ldrb r3, [r3, r2] + 800812e: 2bff cmp r3, #255 ; 0xff + 8008130: d007 beq.n 8008142 + ++pcb->dupacks; + 8008132: 687b ldr r3, [r7, #4] + 8008134: 2247 movs r2, #71 ; 0x47 + 8008136: 5c9b ldrb r3, [r3, r2] + 8008138: 3301 adds r3, #1 + 800813a: b2d9 uxtb r1, r3 + 800813c: 687b ldr r3, [r7, #4] + 800813e: 2247 movs r2, #71 ; 0x47 + 8008140: 5499 strb r1, [r3, r2] + } + if (pcb->dupacks > 3) { + 8008142: 687b ldr r3, [r7, #4] + 8008144: 2247 movs r2, #71 ; 0x47 + 8008146: 5c9b ldrb r3, [r3, r2] + 8008148: 2b03 cmp r3, #3 + 800814a: d916 bls.n 800817a + /* Inflate the congestion window, but not if it means that + the value overflows. */ + if ((u16_t)(pcb->cwnd + pcb->mss) > pcb->cwnd) { + 800814c: 687b ldr r3, [r7, #4] + 800814e: 224c movs r2, #76 ; 0x4c + 8008150: 5a9a ldrh r2, [r3, r2] + 8008152: 687b ldr r3, [r7, #4] + 8008154: 8edb ldrh r3, [r3, #54] ; 0x36 + 8008156: 18d3 adds r3, r2, r3 + 8008158: b29a uxth r2, r3 + 800815a: 687b ldr r3, [r7, #4] + 800815c: 214c movs r1, #76 ; 0x4c + 800815e: 5a5b ldrh r3, [r3, r1] + 8008160: 429a cmp r2, r3 + 8008162: d913 bls.n 800818c + pcb->cwnd += pcb->mss; + 8008164: 687b ldr r3, [r7, #4] + 8008166: 224c movs r2, #76 ; 0x4c + 8008168: 5a9a ldrh r2, [r3, r2] + 800816a: 687b ldr r3, [r7, #4] + 800816c: 8edb ldrh r3, [r3, #54] ; 0x36 + 800816e: 18d3 adds r3, r2, r3 + 8008170: b299 uxth r1, r3 + 8008172: 687b ldr r3, [r7, #4] + 8008174: 224c movs r2, #76 ; 0x4c + 8008176: 5299 strh r1, [r3, r2] + 8008178: e008 b.n 800818c + } + } else if (pcb->dupacks == 3) { + 800817a: 687b ldr r3, [r7, #4] + 800817c: 2247 movs r2, #71 ; 0x47 + 800817e: 5c9b ldrb r3, [r3, r2] + 8008180: 2b03 cmp r3, #3 + 8008182: d103 bne.n 800818c + /* Do fast retransmit */ + tcp_rexmit_fast(pcb); + 8008184: 687b ldr r3, [r7, #4] + 8008186: 0018 movs r0, r3 + 8008188: f002 f8d2 bl 800a330 + } + } + } + /* If Clause (1) or more is true, but not a duplicate ack, reset + * count of consecutive duplicate acks */ + if (!found_dupack) { + 800818c: 69bb ldr r3, [r7, #24] + 800818e: 2b00 cmp r3, #0 + 8008190: d000 beq.n 8008194 + 8008192: e184 b.n 800849e + pcb->dupacks = 0; + 8008194: 687b ldr r3, [r7, #4] + 8008196: 2247 movs r2, #71 ; 0x47 + 8008198: 2100 movs r1, #0 + 800819a: 5499 strb r1, [r3, r2] + 800819c: e17f b.n 800849e + } + } else if (TCP_SEQ_BETWEEN(ackno, pcb->lastack+1, pcb->snd_nxt)){ + 800819e: 4b51 ldr r3, [pc, #324] ; (80082e4 ) + 80081a0: 681a ldr r2, [r3, #0] + 80081a2: 687b ldr r3, [r7, #4] + 80081a4: 6c9b ldr r3, [r3, #72] ; 0x48 + 80081a6: 1ad3 subs r3, r2, r3 + 80081a8: 3b01 subs r3, #1 + 80081aa: 2b00 cmp r3, #0 + 80081ac: da00 bge.n 80081b0 + 80081ae: e125 b.n 80083fc + 80081b0: 4b4c ldr r3, [pc, #304] ; (80082e4 ) + 80081b2: 681a ldr r2, [r3, #0] + 80081b4: 687b ldr r3, [r7, #4] + 80081b6: 6d1b ldr r3, [r3, #80] ; 0x50 + 80081b8: 1ad3 subs r3, r2, r3 + 80081ba: 2b00 cmp r3, #0 + 80081bc: dd00 ble.n 80081c0 + 80081be: e11d b.n 80083fc + /* We come here when the ACK acknowledges new data. */ + + /* Reset the "IN Fast Retransmit" flag, since we are no longer + in fast retransmit. Also reset the congestion window to the + slow start threshold. */ + if (pcb->flags & TF_INFR) { + 80081c0: 687b ldr r3, [r7, #4] + 80081c2: 7f9b ldrb r3, [r3, #30] + 80081c4: 001a movs r2, r3 + 80081c6: 2304 movs r3, #4 + 80081c8: 4013 ands r3, r2 + 80081ca: d00c beq.n 80081e6 + pcb->flags &= ~TF_INFR; + 80081cc: 687b ldr r3, [r7, #4] + 80081ce: 7f9b ldrb r3, [r3, #30] + 80081d0: 2204 movs r2, #4 + 80081d2: 4393 bics r3, r2 + 80081d4: b2da uxtb r2, r3 + 80081d6: 687b ldr r3, [r7, #4] + 80081d8: 779a strb r2, [r3, #30] + pcb->cwnd = pcb->ssthresh; + 80081da: 687b ldr r3, [r7, #4] + 80081dc: 224e movs r2, #78 ; 0x4e + 80081de: 5a99 ldrh r1, [r3, r2] + 80081e0: 687b ldr r3, [r7, #4] + 80081e2: 224c movs r2, #76 ; 0x4c + 80081e4: 5299 strh r1, [r3, r2] + } + + /* Reset the number of retransmissions. */ + pcb->nrtx = 0; + 80081e6: 687b ldr r3, [r7, #4] + 80081e8: 2246 movs r2, #70 ; 0x46 + 80081ea: 2100 movs r1, #0 + 80081ec: 5499 strb r1, [r3, r2] + + /* Reset the retransmission time-out. */ + pcb->rto = (pcb->sa >> 3) + pcb->sv; + 80081ee: 687b ldr r3, [r7, #4] + 80081f0: 2240 movs r2, #64 ; 0x40 + 80081f2: 5e9b ldrsh r3, [r3, r2] + 80081f4: 10db asrs r3, r3, #3 + 80081f6: b21b sxth r3, r3 + 80081f8: b29a uxth r2, r3 + 80081fa: 687b ldr r3, [r7, #4] + 80081fc: 2142 movs r1, #66 ; 0x42 + 80081fe: 5e5b ldrsh r3, [r3, r1] + 8008200: b29b uxth r3, r3 + 8008202: 18d3 adds r3, r2, r3 + 8008204: b29b uxth r3, r3 + 8008206: b219 sxth r1, r3 + 8008208: 687b ldr r3, [r7, #4] + 800820a: 2244 movs r2, #68 ; 0x44 + 800820c: 5299 strh r1, [r3, r2] + + /* Update the send buffer space. Diff between the two can never exceed 64K? */ + pcb->acked = (u16_t)(ackno - pcb->lastack); + 800820e: 4b35 ldr r3, [pc, #212] ; (80082e4 ) + 8008210: 681b ldr r3, [r3, #0] + 8008212: b29a uxth r2, r3 + 8008214: 687b ldr r3, [r7, #4] + 8008216: 6c9b ldr r3, [r3, #72] ; 0x48 + 8008218: b29b uxth r3, r3 + 800821a: 1ad3 subs r3, r2, r3 + 800821c: b299 uxth r1, r3 + 800821e: 687b ldr r3, [r7, #4] + 8008220: 2264 movs r2, #100 ; 0x64 + 8008222: 5299 strh r1, [r3, r2] + + pcb->snd_buf += pcb->acked; + 8008224: 687b ldr r3, [r7, #4] + 8008226: 2266 movs r2, #102 ; 0x66 + 8008228: 5a9a ldrh r2, [r3, r2] + 800822a: 687b ldr r3, [r7, #4] + 800822c: 2164 movs r1, #100 ; 0x64 + 800822e: 5a5b ldrh r3, [r3, r1] + 8008230: 18d3 adds r3, r2, r3 + 8008232: b299 uxth r1, r3 + 8008234: 687b ldr r3, [r7, #4] + 8008236: 2266 movs r2, #102 ; 0x66 + 8008238: 5299 strh r1, [r3, r2] + + /* Reset the fast retransmit variables. */ + pcb->dupacks = 0; + 800823a: 687b ldr r3, [r7, #4] + 800823c: 2247 movs r2, #71 ; 0x47 + 800823e: 2100 movs r1, #0 + 8008240: 5499 strb r1, [r3, r2] + pcb->lastack = ackno; + 8008242: 4b28 ldr r3, [pc, #160] ; (80082e4 ) + 8008244: 681a ldr r2, [r3, #0] + 8008246: 687b ldr r3, [r7, #4] + 8008248: 649a str r2, [r3, #72] ; 0x48 + + /* Update the congestion control variables (cwnd and + ssthresh). */ + if (pcb->state >= ESTABLISHED) { + 800824a: 687b ldr r3, [r7, #4] + 800824c: 7e1b ldrb r3, [r3, #24] + 800824e: 2b03 cmp r3, #3 + 8008250: d800 bhi.n 8008254 + 8008252: e091 b.n 8008378 + if (pcb->cwnd < pcb->ssthresh) { + 8008254: 687b ldr r3, [r7, #4] + 8008256: 224c movs r2, #76 ; 0x4c + 8008258: 5a9a ldrh r2, [r3, r2] + 800825a: 687b ldr r3, [r7, #4] + 800825c: 214e movs r1, #78 ; 0x4e + 800825e: 5a5b ldrh r3, [r3, r1] + 8008260: 429a cmp r2, r3 + 8008262: d217 bcs.n 8008294 + if ((u16_t)(pcb->cwnd + pcb->mss) > pcb->cwnd) { + 8008264: 687b ldr r3, [r7, #4] + 8008266: 224c movs r2, #76 ; 0x4c + 8008268: 5a9a ldrh r2, [r3, r2] + 800826a: 687b ldr r3, [r7, #4] + 800826c: 8edb ldrh r3, [r3, #54] ; 0x36 + 800826e: 18d3 adds r3, r2, r3 + 8008270: b29a uxth r2, r3 + 8008272: 687b ldr r3, [r7, #4] + 8008274: 214c movs r1, #76 ; 0x4c + 8008276: 5a5b ldrh r3, [r3, r1] + 8008278: 429a cmp r2, r3 + 800827a: d800 bhi.n 800827e + 800827c: e07c b.n 8008378 + pcb->cwnd += pcb->mss; + 800827e: 687b ldr r3, [r7, #4] + 8008280: 224c movs r2, #76 ; 0x4c + 8008282: 5a9a ldrh r2, [r3, r2] + 8008284: 687b ldr r3, [r7, #4] + 8008286: 8edb ldrh r3, [r3, #54] ; 0x36 + 8008288: 18d3 adds r3, r2, r3 + 800828a: b299 uxth r1, r3 + 800828c: 687b ldr r3, [r7, #4] + 800828e: 224c movs r2, #76 ; 0x4c + 8008290: 5299 strh r1, [r3, r2] + 8008292: e071 b.n 8008378 + } + LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_receive: slow start cwnd %"U16_F"\n", pcb->cwnd)); + } else { + u16_t new_cwnd = (pcb->cwnd + pcb->mss * pcb->mss / pcb->cwnd); + 8008294: 687b ldr r3, [r7, #4] + 8008296: 224c movs r2, #76 ; 0x4c + 8008298: 5a9c ldrh r4, [r3, r2] + 800829a: 687b ldr r3, [r7, #4] + 800829c: 8edb ldrh r3, [r3, #54] ; 0x36 + 800829e: 001a movs r2, r3 + 80082a0: 687b ldr r3, [r7, #4] + 80082a2: 8edb ldrh r3, [r3, #54] ; 0x36 + 80082a4: 4353 muls r3, r2 + 80082a6: 0018 movs r0, r3 + 80082a8: 687b ldr r3, [r7, #4] + 80082aa: 224c movs r2, #76 ; 0x4c + 80082ac: 5a9b ldrh r3, [r3, r2] + 80082ae: 0019 movs r1, r3 + 80082b0: f7f7 ffc6 bl 8000240 <__divsi3> + 80082b4: 0003 movs r3, r0 + 80082b6: b29a uxth r2, r3 + 80082b8: 2112 movs r1, #18 + 80082ba: 187b adds r3, r7, r1 + 80082bc: 18a2 adds r2, r4, r2 + 80082be: 801a strh r2, [r3, #0] + if (new_cwnd > pcb->cwnd) { + 80082c0: 687b ldr r3, [r7, #4] + 80082c2: 224c movs r2, #76 ; 0x4c + 80082c4: 5a9b ldrh r3, [r3, r2] + 80082c6: 187a adds r2, r7, r1 + 80082c8: 8812 ldrh r2, [r2, #0] + 80082ca: 429a cmp r2, r3 + 80082cc: d954 bls.n 8008378 + pcb->cwnd = new_cwnd; + 80082ce: 687b ldr r3, [r7, #4] + 80082d0: 2212 movs r2, #18 + 80082d2: 18ba adds r2, r7, r2 + 80082d4: 214c movs r1, #76 ; 0x4c + 80082d6: 8812 ldrh r2, [r2, #0] + 80082d8: 525a strh r2, [r3, r1] + pcb->unacked != NULL? + ntohl(pcb->unacked->tcphdr->seqno) + TCP_TCPLEN(pcb->unacked): 0)); + + /* Remove segment from the unacknowledged list if the incoming + ACK acknowlegdes them. */ + while (pcb->unacked != NULL && + 80082da: e04d b.n 8008378 + 80082dc: 2000229c .word 0x2000229c + 80082e0: 20002294 .word 0x20002294 + 80082e4: 20002298 .word 0x20002298 + 80082e8: 2000228c .word 0x2000228c + 80082ec: 2000229e .word 0x2000229e + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: removing %"U32_F":%"U32_F" from pcb->unacked\n", + ntohl(pcb->unacked->tcphdr->seqno), + ntohl(pcb->unacked->tcphdr->seqno) + + TCP_TCPLEN(pcb->unacked))); + + next = pcb->unacked; + 80082f0: 687b ldr r3, [r7, #4] + 80082f2: 6f1b ldr r3, [r3, #112] ; 0x70 + 80082f4: 62fb str r3, [r7, #44] ; 0x2c + pcb->unacked = pcb->unacked->next; + 80082f6: 687b ldr r3, [r7, #4] + 80082f8: 6f1b ldr r3, [r3, #112] ; 0x70 + 80082fa: 681a ldr r2, [r3, #0] + 80082fc: 687b ldr r3, [r7, #4] + 80082fe: 671a str r2, [r3, #112] ; 0x70 + + LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_receive: queuelen %"U16_F" ... ", (u16_t)pcb->snd_queuelen)); + LWIP_ASSERT("pcb->snd_queuelen >= pbuf_clen(next->p)", (pcb->snd_queuelen >= pbuf_clen(next->p))); + 8008300: 6afb ldr r3, [r7, #44] ; 0x2c + 8008302: 685b ldr r3, [r3, #4] + 8008304: 0018 movs r0, r3 + 8008306: f7fd fa3f bl 8005788 + /* Prevent ACK for FIN to generate a sent event */ + if ((pcb->acked != 0) && ((TCPH_FLAGS(next->tcphdr) & TCP_FIN) != 0)) { + 800830a: 687b ldr r3, [r7, #4] + 800830c: 2264 movs r2, #100 ; 0x64 + 800830e: 5a9b ldrh r3, [r3, r2] + 8008310: 2b00 cmp r3, #0 + 8008312: d016 beq.n 8008342 + 8008314: 6afb ldr r3, [r7, #44] ; 0x2c + 8008316: 68db ldr r3, [r3, #12] + 8008318: 7b1a ldrb r2, [r3, #12] + 800831a: 7b5b ldrb r3, [r3, #13] + 800831c: 021b lsls r3, r3, #8 + 800831e: 4313 orrs r3, r2 + 8008320: b29b uxth r3, r3 + 8008322: 0018 movs r0, r3 + 8008324: f7fc f98c bl 8004640 + 8008328: 0003 movs r3, r0 + 800832a: 001a movs r2, r3 + 800832c: 2301 movs r3, #1 + 800832e: 4013 ands r3, r2 + 8008330: d007 beq.n 8008342 + pcb->acked--; + 8008332: 687b ldr r3, [r7, #4] + 8008334: 2264 movs r2, #100 ; 0x64 + 8008336: 5a9b ldrh r3, [r3, r2] + 8008338: 3b01 subs r3, #1 + 800833a: b299 uxth r1, r3 + 800833c: 687b ldr r3, [r7, #4] + 800833e: 2264 movs r2, #100 ; 0x64 + 8008340: 5299 strh r1, [r3, r2] + } + + pcb->snd_queuelen -= pbuf_clen(next->p); + 8008342: 6afb ldr r3, [r7, #44] ; 0x2c + 8008344: 685b ldr r3, [r3, #4] + 8008346: 0018 movs r0, r3 + 8008348: f7fd fa1e bl 8005788 + 800834c: 0003 movs r3, r0 + 800834e: 0019 movs r1, r3 + 8008350: 687b ldr r3, [r7, #4] + 8008352: 2268 movs r2, #104 ; 0x68 + 8008354: 5a9a ldrh r2, [r3, r2] + 8008356: b28b uxth r3, r1 + 8008358: 1ad3 subs r3, r2, r3 + 800835a: b299 uxth r1, r3 + 800835c: 687b ldr r3, [r7, #4] + 800835e: 2268 movs r2, #104 ; 0x68 + 8008360: 5299 strh r1, [r3, r2] + tcp_seg_free(next); + 8008362: 6afb ldr r3, [r7, #44] ; 0x2c + 8008364: 0018 movs r0, r3 + 8008366: f7fe f9da bl 800671e + + LWIP_DEBUGF(TCP_QLEN_DEBUG, ("%"U16_F" (after freeing unacked)\n", (u16_t)pcb->snd_queuelen)); + if (pcb->snd_queuelen != 0) { + 800836a: 687b ldr r3, [r7, #4] + 800836c: 2268 movs r2, #104 ; 0x68 + 800836e: 5a9b ldrh r3, [r3, r2] + 8008370: 2b00 cmp r3, #0 + 8008372: d001 beq.n 8008378 + LWIP_ASSERT("tcp_receive: valid queue length", pcb->unacked != NULL || + 8008374: 687b ldr r3, [r7, #4] + 8008376: 6f1b ldr r3, [r3, #112] ; 0x70 + while (pcb->unacked != NULL && + 8008378: 687b ldr r3, [r7, #4] + 800837a: 6f1b ldr r3, [r3, #112] ; 0x70 + 800837c: 2b00 cmp r3, #0 + 800837e: d02d beq.n 80083dc + TCP_SEQ_LEQ(ntohl(pcb->unacked->tcphdr->seqno) + + 8008380: 687b ldr r3, [r7, #4] + 8008382: 6f1b ldr r3, [r3, #112] ; 0x70 + 8008384: 68db ldr r3, [r3, #12] + 8008386: 791a ldrb r2, [r3, #4] + 8008388: 7959 ldrb r1, [r3, #5] + 800838a: 0209 lsls r1, r1, #8 + 800838c: 430a orrs r2, r1 + 800838e: 7999 ldrb r1, [r3, #6] + 8008390: 0409 lsls r1, r1, #16 + 8008392: 430a orrs r2, r1 + 8008394: 79db ldrb r3, [r3, #7] + 8008396: 061b lsls r3, r3, #24 + 8008398: 4313 orrs r3, r2 + 800839a: 0018 movs r0, r3 + 800839c: f7fc f979 bl 8004692 + 80083a0: 0004 movs r4, r0 + 80083a2: 687b ldr r3, [r7, #4] + 80083a4: 6f1b ldr r3, [r3, #112] ; 0x70 + 80083a6: 891b ldrh r3, [r3, #8] + 80083a8: 001d movs r5, r3 + 80083aa: 687b ldr r3, [r7, #4] + 80083ac: 6f1b ldr r3, [r3, #112] ; 0x70 + 80083ae: 68db ldr r3, [r3, #12] + 80083b0: 7b1a ldrb r2, [r3, #12] + 80083b2: 7b5b ldrb r3, [r3, #13] + 80083b4: 021b lsls r3, r3, #8 + 80083b6: 4313 orrs r3, r2 + 80083b8: b29b uxth r3, r3 + 80083ba: 0018 movs r0, r3 + 80083bc: f7fc f940 bl 8004640 + 80083c0: 0003 movs r3, r0 + 80083c2: 001a movs r2, r3 + 80083c4: 2303 movs r3, #3 + 80083c6: 4013 ands r3, r2 + 80083c8: 1e5a subs r2, r3, #1 + 80083ca: 4193 sbcs r3, r2 + 80083cc: b2db uxtb r3, r3 + 80083ce: 18eb adds r3, r5, r3 + 80083d0: 18e2 adds r2, r4, r3 + 80083d2: 4bd6 ldr r3, [pc, #856] ; (800872c ) + 80083d4: 681b ldr r3, [r3, #0] + 80083d6: 1ad3 subs r3, r2, r3 + while (pcb->unacked != NULL && + 80083d8: 2b00 cmp r3, #0 + 80083da: dd89 ble.n 80082f0 + } + } + + /* If there's nothing left to acknowledge, stop the retransmit + timer, otherwise reset it to start again */ + if(pcb->unacked == NULL) + 80083dc: 687b ldr r3, [r7, #4] + 80083de: 6f1b ldr r3, [r3, #112] ; 0x70 + 80083e0: 2b00 cmp r3, #0 + 80083e2: d104 bne.n 80083ee + pcb->rtime = -1; + 80083e4: 687b ldr r3, [r7, #4] + 80083e6: 2201 movs r2, #1 + 80083e8: 4252 negs r2, r2 + 80083ea: 869a strh r2, [r3, #52] ; 0x34 + 80083ec: e002 b.n 80083f4 + else + pcb->rtime = 0; + 80083ee: 687b ldr r3, [r7, #4] + 80083f0: 2200 movs r2, #0 + 80083f2: 869a strh r2, [r3, #52] ; 0x34 + + pcb->polltmr = 0; + 80083f4: 687b ldr r3, [r7, #4] + 80083f6: 2200 movs r2, #0 + 80083f8: 77da strb r2, [r3, #31] + 80083fa: e003 b.n 8008404 + } else { + /* Fix bug bug #21582: out of sequence ACK, didn't really ack anything */ + pcb->acked = 0; + 80083fc: 687b ldr r3, [r7, #4] + 80083fe: 2264 movs r2, #100 ; 0x64 + 8008400: 2100 movs r1, #0 + 8008402: 5299 strh r1, [r3, r2] + on the list are acknowledged by the ACK. This may seem + strange since an "unsent" segment shouldn't be acked. The + rationale is that lwIP puts all outstanding segments on the + ->unsent list after a retransmission, so these segments may + in fact have been sent once. */ + while (pcb->unsent != NULL && + 8008404: e04b b.n 800849e + TCP_TCPLEN(pcb->unsent), pcb->snd_nxt)) { + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: removing %"U32_F":%"U32_F" from pcb->unsent\n", + ntohl(pcb->unsent->tcphdr->seqno), ntohl(pcb->unsent->tcphdr->seqno) + + TCP_TCPLEN(pcb->unsent))); + + next = pcb->unsent; + 8008406: 687b ldr r3, [r7, #4] + 8008408: 6edb ldr r3, [r3, #108] ; 0x6c + 800840a: 62fb str r3, [r7, #44] ; 0x2c + pcb->unsent = pcb->unsent->next; + 800840c: 687b ldr r3, [r7, #4] + 800840e: 6edb ldr r3, [r3, #108] ; 0x6c + 8008410: 681a ldr r2, [r3, #0] + 8008412: 687b ldr r3, [r7, #4] + 8008414: 66da str r2, [r3, #108] ; 0x6c +#if TCP_OVERSIZE + if (pcb->unsent == NULL) { + 8008416: 687b ldr r3, [r7, #4] + 8008418: 6edb ldr r3, [r3, #108] ; 0x6c + 800841a: 2b00 cmp r3, #0 + 800841c: d103 bne.n 8008426 + pcb->unsent_oversize = 0; + 800841e: 687b ldr r3, [r7, #4] + 8008420: 226a movs r2, #106 ; 0x6a + 8008422: 2100 movs r1, #0 + 8008424: 5299 strh r1, [r3, r2] + } +#endif /* TCP_OVERSIZE */ + LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_receive: queuelen %"U16_F" ... ", (u16_t)pcb->snd_queuelen)); + LWIP_ASSERT("pcb->snd_queuelen >= pbuf_clen(next->p)", (pcb->snd_queuelen >= pbuf_clen(next->p))); + 8008426: 6afb ldr r3, [r7, #44] ; 0x2c + 8008428: 685b ldr r3, [r3, #4] + 800842a: 0018 movs r0, r3 + 800842c: f7fd f9ac bl 8005788 + /* Prevent ACK for FIN to generate a sent event */ + if ((pcb->acked != 0) && ((TCPH_FLAGS(next->tcphdr) & TCP_FIN) != 0)) { + 8008430: 687b ldr r3, [r7, #4] + 8008432: 2264 movs r2, #100 ; 0x64 + 8008434: 5a9b ldrh r3, [r3, r2] + 8008436: 2b00 cmp r3, #0 + 8008438: d016 beq.n 8008468 + 800843a: 6afb ldr r3, [r7, #44] ; 0x2c + 800843c: 68db ldr r3, [r3, #12] + 800843e: 7b1a ldrb r2, [r3, #12] + 8008440: 7b5b ldrb r3, [r3, #13] + 8008442: 021b lsls r3, r3, #8 + 8008444: 4313 orrs r3, r2 + 8008446: b29b uxth r3, r3 + 8008448: 0018 movs r0, r3 + 800844a: f7fc f8f9 bl 8004640 + 800844e: 0003 movs r3, r0 + 8008450: 001a movs r2, r3 + 8008452: 2301 movs r3, #1 + 8008454: 4013 ands r3, r2 + 8008456: d007 beq.n 8008468 + pcb->acked--; + 8008458: 687b ldr r3, [r7, #4] + 800845a: 2264 movs r2, #100 ; 0x64 + 800845c: 5a9b ldrh r3, [r3, r2] + 800845e: 3b01 subs r3, #1 + 8008460: b299 uxth r1, r3 + 8008462: 687b ldr r3, [r7, #4] + 8008464: 2264 movs r2, #100 ; 0x64 + 8008466: 5299 strh r1, [r3, r2] + } + pcb->snd_queuelen -= pbuf_clen(next->p); + 8008468: 6afb ldr r3, [r7, #44] ; 0x2c + 800846a: 685b ldr r3, [r3, #4] + 800846c: 0018 movs r0, r3 + 800846e: f7fd f98b bl 8005788 + 8008472: 0003 movs r3, r0 + 8008474: 0019 movs r1, r3 + 8008476: 687b ldr r3, [r7, #4] + 8008478: 2268 movs r2, #104 ; 0x68 + 800847a: 5a9a ldrh r2, [r3, r2] + 800847c: b28b uxth r3, r1 + 800847e: 1ad3 subs r3, r2, r3 + 8008480: b299 uxth r1, r3 + 8008482: 687b ldr r3, [r7, #4] + 8008484: 2268 movs r2, #104 ; 0x68 + 8008486: 5299 strh r1, [r3, r2] + tcp_seg_free(next); + 8008488: 6afb ldr r3, [r7, #44] ; 0x2c + 800848a: 0018 movs r0, r3 + 800848c: f7fe f947 bl 800671e + LWIP_DEBUGF(TCP_QLEN_DEBUG, ("%"U16_F" (after freeing unsent)\n", (u16_t)pcb->snd_queuelen)); + if (pcb->snd_queuelen != 0) { + 8008490: 687b ldr r3, [r7, #4] + 8008492: 2268 movs r2, #104 ; 0x68 + 8008494: 5a9b ldrh r3, [r3, r2] + 8008496: 2b00 cmp r3, #0 + 8008498: d001 beq.n 800849e + LWIP_ASSERT("tcp_receive: valid queue length", + 800849a: 687b ldr r3, [r7, #4] + 800849c: 6f1b ldr r3, [r3, #112] ; 0x70 + while (pcb->unsent != NULL && + 800849e: 687b ldr r3, [r7, #4] + 80084a0: 6edb ldr r3, [r3, #108] ; 0x6c + 80084a2: 2b00 cmp r3, #0 + 80084a4: d034 beq.n 8008510 + TCP_SEQ_BETWEEN(ackno, ntohl(pcb->unsent->tcphdr->seqno) + + 80084a6: 4ba1 ldr r3, [pc, #644] ; (800872c ) + 80084a8: 681c ldr r4, [r3, #0] + 80084aa: 687b ldr r3, [r7, #4] + 80084ac: 6edb ldr r3, [r3, #108] ; 0x6c + 80084ae: 68db ldr r3, [r3, #12] + 80084b0: 791a ldrb r2, [r3, #4] + 80084b2: 7959 ldrb r1, [r3, #5] + 80084b4: 0209 lsls r1, r1, #8 + 80084b6: 430a orrs r2, r1 + 80084b8: 7999 ldrb r1, [r3, #6] + 80084ba: 0409 lsls r1, r1, #16 + 80084bc: 430a orrs r2, r1 + 80084be: 79db ldrb r3, [r3, #7] + 80084c0: 061b lsls r3, r3, #24 + 80084c2: 4313 orrs r3, r2 + 80084c4: 0018 movs r0, r3 + 80084c6: f7fc f8e4 bl 8004692 + 80084ca: 0005 movs r5, r0 + 80084cc: 687b ldr r3, [r7, #4] + 80084ce: 6edb ldr r3, [r3, #108] ; 0x6c + 80084d0: 891b ldrh r3, [r3, #8] + 80084d2: 001e movs r6, r3 + 80084d4: 687b ldr r3, [r7, #4] + 80084d6: 6edb ldr r3, [r3, #108] ; 0x6c + 80084d8: 68db ldr r3, [r3, #12] + 80084da: 7b1a ldrb r2, [r3, #12] + 80084dc: 7b5b ldrb r3, [r3, #13] + 80084de: 021b lsls r3, r3, #8 + 80084e0: 4313 orrs r3, r2 + 80084e2: b29b uxth r3, r3 + 80084e4: 0018 movs r0, r3 + 80084e6: f7fc f8ab bl 8004640 + 80084ea: 0003 movs r3, r0 + 80084ec: 001a movs r2, r3 + 80084ee: 2303 movs r3, #3 + 80084f0: 4013 ands r3, r2 + 80084f2: 1e5a subs r2, r3, #1 + 80084f4: 4193 sbcs r3, r2 + 80084f6: b2db uxtb r3, r3 + 80084f8: 18f3 adds r3, r6, r3 + 80084fa: 18eb adds r3, r5, r3 + 80084fc: 1ae3 subs r3, r4, r3 + while (pcb->unsent != NULL && + 80084fe: d407 bmi.n 8008510 + TCP_SEQ_BETWEEN(ackno, ntohl(pcb->unsent->tcphdr->seqno) + + 8008500: 4b8a ldr r3, [pc, #552] ; (800872c ) + 8008502: 681a ldr r2, [r3, #0] + 8008504: 687b ldr r3, [r7, #4] + 8008506: 6d1b ldr r3, [r3, #80] ; 0x50 + 8008508: 1ad3 subs r3, r2, r3 + 800850a: 2b00 cmp r3, #0 + 800850c: dc00 bgt.n 8008510 + 800850e: e77a b.n 8008406 + pcb->rttest, pcb->rtseq, ackno)); + + /* RTT estimation calculations. This is done by checking if the + incoming segment acknowledges the segment we use to take a + round-trip time measurement. */ + if (pcb->rttest && TCP_SEQ_LT(pcb->rtseq, ackno)) { + 8008510: 687b ldr r3, [r7, #4] + 8008512: 6b9b ldr r3, [r3, #56] ; 0x38 + 8008514: 2b00 cmp r3, #0 + 8008516: d060 beq.n 80085da + 8008518: 687b ldr r3, [r7, #4] + 800851a: 6bda ldr r2, [r3, #60] ; 0x3c + 800851c: 4b83 ldr r3, [pc, #524] ; (800872c ) + 800851e: 681b ldr r3, [r3, #0] + 8008520: 1ad3 subs r3, r2, r3 + 8008522: d55a bpl.n 80085da + /* diff between this shouldn't exceed 32K since this are tcp timer ticks + and a round-trip shouldn't be that long... */ + m = (s16_t)(tcp_ticks - pcb->rttest); + 8008524: 4b82 ldr r3, [pc, #520] ; (8008730 ) + 8008526: 681b ldr r3, [r3, #0] + 8008528: b29a uxth r2, r3 + 800852a: 687b ldr r3, [r7, #4] + 800852c: 6b9b ldr r3, [r3, #56] ; 0x38 + 800852e: b29b uxth r3, r3 + 8008530: 1ad3 subs r3, r2, r3 + 8008532: b29a uxth r2, r3 + 8008534: 201e movs r0, #30 + 8008536: 183b adds r3, r7, r0 + 8008538: 801a strh r2, [r3, #0] + + LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: experienced rtt %"U16_F" ticks (%"U16_F" msec).\n", + m, m * TCP_SLOW_INTERVAL)); + + /* This is taken directly from VJs original code in his paper */ + m = m - (pcb->sa >> 3); + 800853a: 183b adds r3, r7, r0 + 800853c: 881a ldrh r2, [r3, #0] + 800853e: 687b ldr r3, [r7, #4] + 8008540: 2140 movs r1, #64 ; 0x40 + 8008542: 5e5b ldrsh r3, [r3, r1] + 8008544: 10db asrs r3, r3, #3 + 8008546: b21b sxth r3, r3 + 8008548: b29b uxth r3, r3 + 800854a: 1ad3 subs r3, r2, r3 + 800854c: b29a uxth r2, r3 + 800854e: 183b adds r3, r7, r0 + 8008550: 801a strh r2, [r3, #0] + pcb->sa += m; + 8008552: 687b ldr r3, [r7, #4] + 8008554: 2240 movs r2, #64 ; 0x40 + 8008556: 5e9b ldrsh r3, [r3, r2] + 8008558: b29a uxth r2, r3 + 800855a: 183b adds r3, r7, r0 + 800855c: 881b ldrh r3, [r3, #0] + 800855e: 18d3 adds r3, r2, r3 + 8008560: b29b uxth r3, r3 + 8008562: b219 sxth r1, r3 + 8008564: 687b ldr r3, [r7, #4] + 8008566: 2240 movs r2, #64 ; 0x40 + 8008568: 5299 strh r1, [r3, r2] + if (m < 0) { + 800856a: 183b adds r3, r7, r0 + 800856c: 2200 movs r2, #0 + 800856e: 5e9b ldrsh r3, [r3, r2] + 8008570: 2b00 cmp r3, #0 + 8008572: da06 bge.n 8008582 + m = -m; + 8008574: 211e movs r1, #30 + 8008576: 187b adds r3, r7, r1 + 8008578: 881b ldrh r3, [r3, #0] + 800857a: 425b negs r3, r3 + 800857c: b29a uxth r2, r3 + 800857e: 187b adds r3, r7, r1 + 8008580: 801a strh r2, [r3, #0] + } + m = m - (pcb->sv >> 2); + 8008582: 201e movs r0, #30 + 8008584: 183b adds r3, r7, r0 + 8008586: 881a ldrh r2, [r3, #0] + 8008588: 687b ldr r3, [r7, #4] + 800858a: 2142 movs r1, #66 ; 0x42 + 800858c: 5e5b ldrsh r3, [r3, r1] + 800858e: 109b asrs r3, r3, #2 + 8008590: b21b sxth r3, r3 + 8008592: b29b uxth r3, r3 + 8008594: 1ad3 subs r3, r2, r3 + 8008596: b29a uxth r2, r3 + 8008598: 183b adds r3, r7, r0 + 800859a: 801a strh r2, [r3, #0] + pcb->sv += m; + 800859c: 687b ldr r3, [r7, #4] + 800859e: 2242 movs r2, #66 ; 0x42 + 80085a0: 5e9b ldrsh r3, [r3, r2] + 80085a2: b29a uxth r2, r3 + 80085a4: 183b adds r3, r7, r0 + 80085a6: 881b ldrh r3, [r3, #0] + 80085a8: 18d3 adds r3, r2, r3 + 80085aa: b29b uxth r3, r3 + 80085ac: b219 sxth r1, r3 + 80085ae: 687b ldr r3, [r7, #4] + 80085b0: 2242 movs r2, #66 ; 0x42 + 80085b2: 5299 strh r1, [r3, r2] + pcb->rto = (pcb->sa >> 3) + pcb->sv; + 80085b4: 687b ldr r3, [r7, #4] + 80085b6: 2240 movs r2, #64 ; 0x40 + 80085b8: 5e9b ldrsh r3, [r3, r2] + 80085ba: 10db asrs r3, r3, #3 + 80085bc: b21b sxth r3, r3 + 80085be: b29a uxth r2, r3 + 80085c0: 687b ldr r3, [r7, #4] + 80085c2: 2142 movs r1, #66 ; 0x42 + 80085c4: 5e5b ldrsh r3, [r3, r1] + 80085c6: b29b uxth r3, r3 + 80085c8: 18d3 adds r3, r2, r3 + 80085ca: b29b uxth r3, r3 + 80085cc: b219 sxth r1, r3 + 80085ce: 687b ldr r3, [r7, #4] + 80085d0: 2244 movs r2, #68 ; 0x44 + 80085d2: 5299 strh r1, [r3, r2] + + LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: RTO %"U16_F" (%"U16_F" milliseconds)\n", + pcb->rto, pcb->rto * TCP_SLOW_INTERVAL)); + + pcb->rttest = 0; + 80085d4: 687b ldr r3, [r7, #4] + 80085d6: 2200 movs r2, #0 + 80085d8: 639a str r2, [r3, #56] ; 0x38 + + /* If the incoming segment contains data, we must process it + further unless the pcb already received a FIN. + (RFC 793, chapeter 3.9, "SEGMENT ARRIVES" in states CLOSE-WAIT, CLOSING, + LAST-ACK and TIME-WAIT: "Ignore the segment text.") */ + if ((tcplen > 0) && (pcb->state < CLOSE_WAIT)) { + 80085da: 4b56 ldr r3, [pc, #344] ; (8008734 ) + 80085dc: 881b ldrh r3, [r3, #0] + 80085de: 2b00 cmp r3, #0 + 80085e0: d101 bne.n 80085e6 + 80085e2: f000 fd83 bl 80090ec + 80085e6: 687b ldr r3, [r7, #4] + 80085e8: 7e1b ldrb r3, [r3, #24] + 80085ea: 2b06 cmp r3, #6 + 80085ec: d901 bls.n 80085f2 + 80085ee: f000 fd7d bl 80090ec + this if the sequence number of the incoming segment is less + than rcv_nxt, and the sequence number plus the length of the + segment is larger than rcv_nxt. */ + /* if (TCP_SEQ_LT(seqno, pcb->rcv_nxt)){ + if (TCP_SEQ_LT(pcb->rcv_nxt, seqno + tcplen)) {*/ + if (TCP_SEQ_BETWEEN(pcb->rcv_nxt, seqno + 1, seqno + tcplen - 1)){ + 80085f2: 687b ldr r3, [r7, #4] + 80085f4: 6a9a ldr r2, [r3, #40] ; 0x28 + 80085f6: 4b50 ldr r3, [pc, #320] ; (8008738 ) + 80085f8: 681b ldr r3, [r3, #0] + 80085fa: 1ad3 subs r3, r2, r3 + 80085fc: 3b01 subs r3, #1 + 80085fe: 2b00 cmp r3, #0 + 8008600: da00 bge.n 8008604 + 8008602: e09d b.n 8008740 + 8008604: 687b ldr r3, [r7, #4] + 8008606: 6a9a ldr r2, [r3, #40] ; 0x28 + 8008608: 4b4a ldr r3, [pc, #296] ; (8008734 ) + 800860a: 881b ldrh r3, [r3, #0] + 800860c: 0019 movs r1, r3 + 800860e: 4b4a ldr r3, [pc, #296] ; (8008738 ) + 8008610: 681b ldr r3, [r3, #0] + 8008612: 18cb adds r3, r1, r3 + 8008614: 1ad3 subs r3, r2, r3 + 8008616: 3301 adds r3, #1 + 8008618: 2b00 cmp r3, #0 + 800861a: dd00 ble.n 800861e + 800861c: e090 b.n 8008740 + + After we are done with adjusting the pbuf pointers we must + adjust the ->data pointer in the seg and the segment + length.*/ + + off = pcb->rcv_nxt - seqno; + 800861e: 687b ldr r3, [r7, #4] + 8008620: 6a9a ldr r2, [r3, #40] ; 0x28 + 8008622: 4b45 ldr r3, [pc, #276] ; (8008738 ) + 8008624: 681b ldr r3, [r3, #0] + 8008626: 1ad3 subs r3, r2, r3 + 8008628: 623b str r3, [r7, #32] + p = inseg.p; + 800862a: 4b44 ldr r3, [pc, #272] ; (800873c ) + 800862c: 685b ldr r3, [r3, #4] + 800862e: 627b str r3, [r7, #36] ; 0x24 + LWIP_ASSERT("inseg.p != NULL", inseg.p); + LWIP_ASSERT("insane offset!", (off < 0x7fff)); + if (inseg.p->len < off) { + 8008630: 4b42 ldr r3, [pc, #264] ; (800873c ) + 8008632: 685b ldr r3, [r3, #4] + 8008634: 895b ldrh r3, [r3, #10] + 8008636: 001a movs r2, r3 + 8008638: 6a3b ldr r3, [r7, #32] + 800863a: 4293 cmp r3, r2 + 800863c: dd2b ble.n 8008696 + LWIP_ASSERT("pbuf too short!", (((s32_t)inseg.p->tot_len) >= off)); + new_tot_len = (u16_t)(inseg.p->tot_len - off); + 800863e: 4b3f ldr r3, [pc, #252] ; (800873c ) + 8008640: 685b ldr r3, [r3, #4] + 8008642: 8919 ldrh r1, [r3, #8] + 8008644: 6a3b ldr r3, [r7, #32] + 8008646: b29a uxth r2, r3 + 8008648: 2310 movs r3, #16 + 800864a: 18fb adds r3, r7, r3 + 800864c: 1a8a subs r2, r1, r2 + 800864e: 801a strh r2, [r3, #0] + while (p->len < off) { + 8008650: e010 b.n 8008674 + off -= p->len; + 8008652: 6a7b ldr r3, [r7, #36] ; 0x24 + 8008654: 895b ldrh r3, [r3, #10] + 8008656: 001a movs r2, r3 + 8008658: 6a3b ldr r3, [r7, #32] + 800865a: 1a9b subs r3, r3, r2 + 800865c: 623b str r3, [r7, #32] + /* KJM following line changed (with addition of new_tot_len var) + to fix bug #9076 + inseg.p->tot_len -= p->len; */ + p->tot_len = new_tot_len; + 800865e: 6a7b ldr r3, [r7, #36] ; 0x24 + 8008660: 2210 movs r2, #16 + 8008662: 18ba adds r2, r7, r2 + 8008664: 8812 ldrh r2, [r2, #0] + 8008666: 811a strh r2, [r3, #8] + p->len = 0; + 8008668: 6a7b ldr r3, [r7, #36] ; 0x24 + 800866a: 2200 movs r2, #0 + 800866c: 815a strh r2, [r3, #10] + p = p->next; + 800866e: 6a7b ldr r3, [r7, #36] ; 0x24 + 8008670: 681b ldr r3, [r3, #0] + 8008672: 627b str r3, [r7, #36] ; 0x24 + while (p->len < off) { + 8008674: 6a7b ldr r3, [r7, #36] ; 0x24 + 8008676: 895b ldrh r3, [r3, #10] + 8008678: 001a movs r2, r3 + 800867a: 6a3b ldr r3, [r7, #32] + 800867c: 4293 cmp r3, r2 + 800867e: dce8 bgt.n 8008652 + } + if(pbuf_header(p, (s16_t)-off)) { + 8008680: 6a3b ldr r3, [r7, #32] + 8008682: b29b uxth r3, r3 + 8008684: 425b negs r3, r3 + 8008686: b29b uxth r3, r3 + 8008688: b21a sxth r2, r3 + 800868a: 6a7b ldr r3, [r7, #36] ; 0x24 + 800868c: 0011 movs r1, r2 + 800868e: 0018 movs r0, r3 + 8008690: f7fc ff81 bl 8005596 + 8008694: e00a b.n 80086ac + /* Do we need to cope with this failing? Assert for now */ + LWIP_ASSERT("pbuf_header failed", 0); + } + } else { + if(pbuf_header(inseg.p, (s16_t)-off)) { + 8008696: 4b29 ldr r3, [pc, #164] ; (800873c ) + 8008698: 685b ldr r3, [r3, #4] + 800869a: 6a3a ldr r2, [r7, #32] + 800869c: b292 uxth r2, r2 + 800869e: 4252 negs r2, r2 + 80086a0: b292 uxth r2, r2 + 80086a2: b212 sxth r2, r2 + 80086a4: 0011 movs r1, r2 + 80086a6: 0018 movs r0, r3 + 80086a8: f7fc ff75 bl 8005596 + /* Do we need to cope with this failing? Assert for now */ + LWIP_ASSERT("pbuf_header failed", 0); + } + } + inseg.len -= (u16_t)(pcb->rcv_nxt - seqno); + 80086ac: 4b23 ldr r3, [pc, #140] ; (800873c ) + 80086ae: 891a ldrh r2, [r3, #8] + 80086b0: 4b21 ldr r3, [pc, #132] ; (8008738 ) + 80086b2: 681b ldr r3, [r3, #0] + 80086b4: b299 uxth r1, r3 + 80086b6: 687b ldr r3, [r7, #4] + 80086b8: 6a9b ldr r3, [r3, #40] ; 0x28 + 80086ba: b29b uxth r3, r3 + 80086bc: 1acb subs r3, r1, r3 + 80086be: b29b uxth r3, r3 + 80086c0: 18d3 adds r3, r2, r3 + 80086c2: b29a uxth r2, r3 + 80086c4: 4b1d ldr r3, [pc, #116] ; (800873c ) + 80086c6: 811a strh r2, [r3, #8] + inseg.tcphdr->seqno = seqno = pcb->rcv_nxt; + 80086c8: 687b ldr r3, [r7, #4] + 80086ca: 6a9a ldr r2, [r3, #40] ; 0x28 + 80086cc: 4b1a ldr r3, [pc, #104] ; (8008738 ) + 80086ce: 601a str r2, [r3, #0] + 80086d0: 4b1a ldr r3, [pc, #104] ; (800873c ) + 80086d2: 68db ldr r3, [r3, #12] + 80086d4: 4a18 ldr r2, [pc, #96] ; (8008738 ) + 80086d6: 6812 ldr r2, [r2, #0] + 80086d8: 21ff movs r1, #255 ; 0xff + 80086da: 4011 ands r1, r2 + 80086dc: 000c movs r4, r1 + 80086de: 7919 ldrb r1, [r3, #4] + 80086e0: 2000 movs r0, #0 + 80086e2: 4001 ands r1, r0 + 80086e4: 1c08 adds r0, r1, #0 + 80086e6: 1c21 adds r1, r4, #0 + 80086e8: 4301 orrs r1, r0 + 80086ea: 7119 strb r1, [r3, #4] + 80086ec: 0a11 lsrs r1, r2, #8 + 80086ee: 20ff movs r0, #255 ; 0xff + 80086f0: 4001 ands r1, r0 + 80086f2: 000c movs r4, r1 + 80086f4: 7959 ldrb r1, [r3, #5] + 80086f6: 2000 movs r0, #0 + 80086f8: 4001 ands r1, r0 + 80086fa: 1c08 adds r0, r1, #0 + 80086fc: 1c21 adds r1, r4, #0 + 80086fe: 4301 orrs r1, r0 + 8008700: 7159 strb r1, [r3, #5] + 8008702: 0c11 lsrs r1, r2, #16 + 8008704: 20ff movs r0, #255 ; 0xff + 8008706: 4001 ands r1, r0 + 8008708: 000c movs r4, r1 + 800870a: 7999 ldrb r1, [r3, #6] + 800870c: 2000 movs r0, #0 + 800870e: 4001 ands r1, r0 + 8008710: 1c08 adds r0, r1, #0 + 8008712: 1c21 adds r1, r4, #0 + 8008714: 4301 orrs r1, r0 + 8008716: 7199 strb r1, [r3, #6] + 8008718: 0e10 lsrs r0, r2, #24 + 800871a: 79da ldrb r2, [r3, #7] + 800871c: 2100 movs r1, #0 + 800871e: 400a ands r2, r1 + 8008720: 1c11 adds r1, r2, #0 + 8008722: 1c02 adds r2, r0, #0 + 8008724: 430a orrs r2, r1 + 8008726: 71da strb r2, [r3, #7] + 8008728: e017 b.n 800875a + 800872a: 46c0 nop ; (mov r8, r8) + 800872c: 20002298 .word 0x20002298 + 8008730: 20003278 .word 0x20003278 + 8008734: 2000229e .word 0x2000229e + 8008738: 20002294 .word 0x20002294 + 800873c: 2000227c .word 0x2000227c + } + else { + if (TCP_SEQ_LT(seqno, pcb->rcv_nxt)){ + 8008740: 4b78 ldr r3, [pc, #480] ; (8008924 ) + 8008742: 681a ldr r2, [r3, #0] + 8008744: 687b ldr r3, [r7, #4] + 8008746: 6a9b ldr r3, [r3, #40] ; 0x28 + 8008748: 1ad3 subs r3, r2, r3 + 800874a: d506 bpl.n 800875a + /* the whole segment is < rcv_nxt */ + /* must be a duplicate of a packet that has already been correctly handled */ + + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: duplicate seqno %"U32_F"\n", seqno)); + tcp_ack_now(pcb); + 800874c: 687b ldr r3, [r7, #4] + 800874e: 7f9b ldrb r3, [r3, #30] + 8008750: 2202 movs r2, #2 + 8008752: 4313 orrs r3, r2 + 8008754: b2da uxtb r2, r3 + 8008756: 687b ldr r3, [r7, #4] + 8008758: 779a strb r2, [r3, #30] + } + + /* The sequence number must be within the window (above rcv_nxt + and below rcv_nxt + rcv_wnd) in order to be further + processed. */ + if (TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt, + 800875a: 4b72 ldr r3, [pc, #456] ; (8008924 ) + 800875c: 681a ldr r2, [r3, #0] + 800875e: 687b ldr r3, [r7, #4] + 8008760: 6a9b ldr r3, [r3, #40] ; 0x28 + 8008762: 1ad3 subs r3, r2, r3 + 8008764: d501 bpl.n 800876a + 8008766: f000 fcbb bl 80090e0 + 800876a: 4b6e ldr r3, [pc, #440] ; (8008924 ) + 800876c: 681a ldr r2, [r3, #0] + 800876e: 687b ldr r3, [r7, #4] + 8008770: 6a9b ldr r3, [r3, #40] ; 0x28 + 8008772: 6879 ldr r1, [r7, #4] + 8008774: 8d89 ldrh r1, [r1, #44] ; 0x2c + 8008776: 185b adds r3, r3, r1 + 8008778: 1ad3 subs r3, r2, r3 + 800877a: 3301 adds r3, #1 + 800877c: 2b00 cmp r3, #0 + 800877e: dd01 ble.n 8008784 + 8008780: f000 fcae bl 80090e0 + pcb->rcv_nxt + pcb->rcv_wnd - 1)){ + if (pcb->rcv_nxt == seqno) { + 8008784: 687b ldr r3, [r7, #4] + 8008786: 6a9a ldr r2, [r3, #40] ; 0x28 + 8008788: 4b66 ldr r3, [pc, #408] ; (8008924 ) + 800878a: 681b ldr r3, [r3, #0] + 800878c: 429a cmp r2, r3 + 800878e: d000 beq.n 8008792 + 8008790: e2be b.n 8008d10 + /* The incoming segment is the next in sequence. We check if + we have to trim the end of the segment and update rcv_nxt + and pass the data to the application. */ + tcplen = TCP_TCPLEN(&inseg); + 8008792: 4b65 ldr r3, [pc, #404] ; (8008928 ) + 8008794: 891c ldrh r4, [r3, #8] + 8008796: 4b64 ldr r3, [pc, #400] ; (8008928 ) + 8008798: 68db ldr r3, [r3, #12] + 800879a: 7b1a ldrb r2, [r3, #12] + 800879c: 7b5b ldrb r3, [r3, #13] + 800879e: 021b lsls r3, r3, #8 + 80087a0: 4313 orrs r3, r2 + 80087a2: b29b uxth r3, r3 + 80087a4: 0018 movs r0, r3 + 80087a6: f7fb ff4b bl 8004640 + 80087aa: 0003 movs r3, r0 + 80087ac: 001a movs r2, r3 + 80087ae: 2303 movs r3, #3 + 80087b0: 4013 ands r3, r2 + 80087b2: 1e5a subs r2, r3, #1 + 80087b4: 4193 sbcs r3, r2 + 80087b6: b2db uxtb r3, r3 + 80087b8: b29b uxth r3, r3 + 80087ba: 18e3 adds r3, r4, r3 + 80087bc: b29a uxth r2, r3 + 80087be: 4b5b ldr r3, [pc, #364] ; (800892c ) + 80087c0: 801a strh r2, [r3, #0] + + if (tcplen > pcb->rcv_wnd) { + 80087c2: 687b ldr r3, [r7, #4] + 80087c4: 8d9a ldrh r2, [r3, #44] ; 0x2c + 80087c6: 4b59 ldr r3, [pc, #356] ; (800892c ) + 80087c8: 881b ldrh r3, [r3, #0] + 80087ca: 429a cmp r2, r3 + 80087cc: d300 bcc.n 80087d0 + 80087ce: e07e b.n 80088ce + LWIP_DEBUGF(TCP_INPUT_DEBUG, + ("tcp_receive: other end overran receive window" + "seqno %"U32_F" len %"U16_F" right edge %"U32_F"\n", + seqno, tcplen, pcb->rcv_nxt + pcb->rcv_wnd)); + if (TCPH_FLAGS(inseg.tcphdr) & TCP_FIN) { + 80087d0: 4b55 ldr r3, [pc, #340] ; (8008928 ) + 80087d2: 68db ldr r3, [r3, #12] + 80087d4: 7b1a ldrb r2, [r3, #12] + 80087d6: 7b5b ldrb r3, [r3, #13] + 80087d8: 021b lsls r3, r3, #8 + 80087da: 4313 orrs r3, r2 + 80087dc: b29b uxth r3, r3 + 80087de: 0018 movs r0, r3 + 80087e0: f7fb ff2e bl 8004640 + 80087e4: 0003 movs r3, r0 + 80087e6: 001a movs r2, r3 + 80087e8: 2301 movs r3, #1 + 80087ea: 4013 ands r3, r2 + 80087ec: d036 beq.n 800885c + /* Must remove the FIN from the header as we're trimming + * that byte of sequence-space from the packet */ + TCPH_FLAGS_SET(inseg.tcphdr, TCPH_FLAGS(inseg.tcphdr) &~ TCP_FIN); + 80087ee: 4b4e ldr r3, [pc, #312] ; (8008928 ) + 80087f0: 68db ldr r3, [r3, #12] + 80087f2: 7b1a ldrb r2, [r3, #12] + 80087f4: 7b5b ldrb r3, [r3, #13] + 80087f6: 021b lsls r3, r3, #8 + 80087f8: 4313 orrs r3, r2 + 80087fa: b29b uxth r3, r3 + 80087fc: b21b sxth r3, r3 + 80087fe: 4a4c ldr r2, [pc, #304] ; (8008930 ) + 8008800: 4013 ands r3, r2 + 8008802: b21c sxth r4, r3 + 8008804: 4b48 ldr r3, [pc, #288] ; (8008928 ) + 8008806: 68db ldr r3, [r3, #12] + 8008808: 7b1a ldrb r2, [r3, #12] + 800880a: 7b5b ldrb r3, [r3, #13] + 800880c: 021b lsls r3, r3, #8 + 800880e: 4313 orrs r3, r2 + 8008810: b29b uxth r3, r3 + 8008812: 0018 movs r0, r3 + 8008814: f7fb ff14 bl 8004640 + 8008818: 0003 movs r3, r0 + 800881a: 001a movs r2, r3 + 800881c: 233e movs r3, #62 ; 0x3e + 800881e: 4013 ands r3, r2 + 8008820: b29b uxth r3, r3 + 8008822: 0018 movs r0, r3 + 8008824: f7fb fef6 bl 8004614 + 8008828: 0003 movs r3, r0 + 800882a: b21b sxth r3, r3 + 800882c: 4323 orrs r3, r4 + 800882e: b21a sxth r2, r3 + 8008830: 4b3d ldr r3, [pc, #244] ; (8008928 ) + 8008832: 68db ldr r3, [r3, #12] + 8008834: b292 uxth r2, r2 + 8008836: 21ff movs r1, #255 ; 0xff + 8008838: 4011 ands r1, r2 + 800883a: 000c movs r4, r1 + 800883c: 7b19 ldrb r1, [r3, #12] + 800883e: 2000 movs r0, #0 + 8008840: 4001 ands r1, r0 + 8008842: 1c08 adds r0, r1, #0 + 8008844: 1c21 adds r1, r4, #0 + 8008846: 4301 orrs r1, r0 + 8008848: 7319 strb r1, [r3, #12] + 800884a: 0a12 lsrs r2, r2, #8 + 800884c: b290 uxth r0, r2 + 800884e: 7b5a ldrb r2, [r3, #13] + 8008850: 2100 movs r1, #0 + 8008852: 400a ands r2, r1 + 8008854: 1c11 adds r1, r2, #0 + 8008856: 1c02 adds r2, r0, #0 + 8008858: 430a orrs r2, r1 + 800885a: 735a strb r2, [r3, #13] + } + /* Adjust length of segment to fit in the window. */ + inseg.len = pcb->rcv_wnd; + 800885c: 687b ldr r3, [r7, #4] + 800885e: 8d9a ldrh r2, [r3, #44] ; 0x2c + 8008860: 4b31 ldr r3, [pc, #196] ; (8008928 ) + 8008862: 811a strh r2, [r3, #8] + if (TCPH_FLAGS(inseg.tcphdr) & TCP_SYN) { + 8008864: 4b30 ldr r3, [pc, #192] ; (8008928 ) + 8008866: 68db ldr r3, [r3, #12] + 8008868: 7b1a ldrb r2, [r3, #12] + 800886a: 7b5b ldrb r3, [r3, #13] + 800886c: 021b lsls r3, r3, #8 + 800886e: 4313 orrs r3, r2 + 8008870: b29b uxth r3, r3 + 8008872: 0018 movs r0, r3 + 8008874: f7fb fee4 bl 8004640 + 8008878: 0003 movs r3, r0 + 800887a: 001a movs r2, r3 + 800887c: 2302 movs r3, #2 + 800887e: 4013 ands r3, r2 + 8008880: d005 beq.n 800888e + inseg.len -= 1; + 8008882: 4b29 ldr r3, [pc, #164] ; (8008928 ) + 8008884: 891b ldrh r3, [r3, #8] + 8008886: 3b01 subs r3, #1 + 8008888: b29a uxth r2, r3 + 800888a: 4b27 ldr r3, [pc, #156] ; (8008928 ) + 800888c: 811a strh r2, [r3, #8] + } + pbuf_realloc(inseg.p, inseg.len); + 800888e: 4b26 ldr r3, [pc, #152] ; (8008928 ) + 8008890: 685a ldr r2, [r3, #4] + 8008892: 4b25 ldr r3, [pc, #148] ; (8008928 ) + 8008894: 891b ldrh r3, [r3, #8] + 8008896: 0019 movs r1, r3 + 8008898: 0010 movs r0, r2 + 800889a: f7fc fe0a bl 80054b2 + tcplen = TCP_TCPLEN(&inseg); + 800889e: 4b22 ldr r3, [pc, #136] ; (8008928 ) + 80088a0: 891c ldrh r4, [r3, #8] + 80088a2: 4b21 ldr r3, [pc, #132] ; (8008928 ) + 80088a4: 68db ldr r3, [r3, #12] + 80088a6: 7b1a ldrb r2, [r3, #12] + 80088a8: 7b5b ldrb r3, [r3, #13] + 80088aa: 021b lsls r3, r3, #8 + 80088ac: 4313 orrs r3, r2 + 80088ae: b29b uxth r3, r3 + 80088b0: 0018 movs r0, r3 + 80088b2: f7fb fec5 bl 8004640 + 80088b6: 0003 movs r3, r0 + 80088b8: 001a movs r2, r3 + 80088ba: 2303 movs r3, #3 + 80088bc: 4013 ands r3, r2 + 80088be: 1e5a subs r2, r3, #1 + 80088c0: 4193 sbcs r3, r2 + 80088c2: b2db uxtb r3, r3 + 80088c4: b29b uxth r3, r3 + 80088c6: 18e3 adds r3, r4, r3 + 80088c8: b29a uxth r2, r3 + 80088ca: 4b18 ldr r3, [pc, #96] ; (800892c ) + 80088cc: 801a strh r2, [r3, #0] + } +#if TCP_QUEUE_OOSEQ + /* Received in-sequence data, adjust ooseq data if: + - FIN has been received or + - inseq overlaps with ooseq */ + if (pcb->ooseq != NULL) { + 80088ce: 687b ldr r3, [r7, #4] + 80088d0: 6f5b ldr r3, [r3, #116] ; 0x74 + 80088d2: 2b00 cmp r3, #0 + 80088d4: d100 bne.n 80088d8 + 80088d6: e10f b.n 8008af8 + if (TCPH_FLAGS(inseg.tcphdr) & TCP_FIN) { + 80088d8: 4b13 ldr r3, [pc, #76] ; (8008928 ) + 80088da: 68db ldr r3, [r3, #12] + 80088dc: 7b1a ldrb r2, [r3, #12] + 80088de: 7b5b ldrb r3, [r3, #13] + 80088e0: 021b lsls r3, r3, #8 + 80088e2: 4313 orrs r3, r2 + 80088e4: b29b uxth r3, r3 + 80088e6: 0018 movs r0, r3 + 80088e8: f7fb feaa bl 8004640 + 80088ec: 0003 movs r3, r0 + 80088ee: 001a movs r2, r3 + 80088f0: 2301 movs r3, #1 + 80088f2: 4013 ands r3, r2 + 80088f4: d011 beq.n 800891a + LWIP_DEBUGF(TCP_INPUT_DEBUG, + ("tcp_receive: received in-order FIN, binning ooseq queue\n")); + /* Received in-order FIN means anything that was received + * out of order must now have been received in-order, so + * bin the ooseq queue */ + while (pcb->ooseq != NULL) { + 80088f6: e00b b.n 8008910 + struct tcp_seg *old_ooseq = pcb->ooseq; + 80088f8: 687b ldr r3, [r7, #4] + 80088fa: 6f5b ldr r3, [r3, #116] ; 0x74 + 80088fc: 60bb str r3, [r7, #8] + pcb->ooseq = pcb->ooseq->next; + 80088fe: 687b ldr r3, [r7, #4] + 8008900: 6f5b ldr r3, [r3, #116] ; 0x74 + 8008902: 681a ldr r2, [r3, #0] + 8008904: 687b ldr r3, [r7, #4] + 8008906: 675a str r2, [r3, #116] ; 0x74 + tcp_seg_free(old_ooseq); + 8008908: 68bb ldr r3, [r7, #8] + 800890a: 0018 movs r0, r3 + 800890c: f7fd ff07 bl 800671e + while (pcb->ooseq != NULL) { + 8008910: 687b ldr r3, [r7, #4] + 8008912: 6f5b ldr r3, [r3, #116] ; 0x74 + 8008914: 2b00 cmp r3, #0 + 8008916: d1ef bne.n 80088f8 + 8008918: e0ee b.n 8008af8 + } + } else { + next = pcb->ooseq; + 800891a: 687b ldr r3, [r7, #4] + 800891c: 6f5b ldr r3, [r3, #116] ; 0x74 + 800891e: 62fb str r3, [r7, #44] ; 0x2c + /* Remove all segments on ooseq that are covered by inseg already. + * FIN is copied from ooseq to inseg if present. */ + while (next && + 8008920: e06a b.n 80089f8 + 8008922: 46c0 nop ; (mov r8, r8) + 8008924: 20002294 .word 0x20002294 + 8008928: 2000227c .word 0x2000227c + 800892c: 2000229e .word 0x2000229e + 8008930: ffffc0ff .word 0xffffc0ff + TCP_SEQ_GEQ(seqno + tcplen, + next->tcphdr->seqno + next->len)) { + /* inseg cannot have FIN here (already processed above) */ + if (TCPH_FLAGS(next->tcphdr) & TCP_FIN && + 8008934: 6afb ldr r3, [r7, #44] ; 0x2c + 8008936: 68db ldr r3, [r3, #12] + 8008938: 7b1a ldrb r2, [r3, #12] + 800893a: 7b5b ldrb r3, [r3, #13] + 800893c: 021b lsls r3, r3, #8 + 800893e: 4313 orrs r3, r2 + 8008940: b29b uxth r3, r3 + 8008942: 0018 movs r0, r3 + 8008944: f7fb fe7c bl 8004640 + 8008948: 0003 movs r3, r0 + 800894a: 001a movs r2, r3 + 800894c: 2301 movs r3, #1 + 800894e: 4013 ands r3, r2 + 8008950: d049 beq.n 80089e6 + (TCPH_FLAGS(inseg.tcphdr) & TCP_SYN) == 0) { + 8008952: 4bba ldr r3, [pc, #744] ; (8008c3c ) + 8008954: 68db ldr r3, [r3, #12] + 8008956: 7b1a ldrb r2, [r3, #12] + 8008958: 7b5b ldrb r3, [r3, #13] + 800895a: 021b lsls r3, r3, #8 + 800895c: 4313 orrs r3, r2 + 800895e: b29b uxth r3, r3 + 8008960: 0018 movs r0, r3 + 8008962: f7fb fe6d bl 8004640 + 8008966: 0003 movs r3, r0 + 8008968: 001a movs r2, r3 + 800896a: 2302 movs r3, #2 + 800896c: 4013 ands r3, r2 + if (TCPH_FLAGS(next->tcphdr) & TCP_FIN && + 800896e: d13a bne.n 80089e6 + TCPH_SET_FLAG(inseg.tcphdr, TCP_FIN); + 8008970: 4bb2 ldr r3, [pc, #712] ; (8008c3c ) + 8008972: 68db ldr r3, [r3, #12] + 8008974: 7b1a ldrb r2, [r3, #12] + 8008976: 7b5b ldrb r3, [r3, #13] + 8008978: 021b lsls r3, r3, #8 + 800897a: 4313 orrs r3, r2 + 800897c: b29c uxth r4, r3 + 800897e: 2001 movs r0, #1 + 8008980: f7fb fe48 bl 8004614 + 8008984: 0003 movs r3, r0 + 8008986: 001a movs r2, r3 + 8008988: 4bac ldr r3, [pc, #688] ; (8008c3c ) + 800898a: 68db ldr r3, [r3, #12] + 800898c: 4322 orrs r2, r4 + 800898e: b292 uxth r2, r2 + 8008990: 21ff movs r1, #255 ; 0xff + 8008992: 4011 ands r1, r2 + 8008994: 000c movs r4, r1 + 8008996: 7b19 ldrb r1, [r3, #12] + 8008998: 2000 movs r0, #0 + 800899a: 4001 ands r1, r0 + 800899c: 1c08 adds r0, r1, #0 + 800899e: 1c21 adds r1, r4, #0 + 80089a0: 4301 orrs r1, r0 + 80089a2: 7319 strb r1, [r3, #12] + 80089a4: 0a12 lsrs r2, r2, #8 + 80089a6: b290 uxth r0, r2 + 80089a8: 7b5a ldrb r2, [r3, #13] + 80089aa: 2100 movs r1, #0 + 80089ac: 400a ands r2, r1 + 80089ae: 1c11 adds r1, r2, #0 + 80089b0: 1c02 adds r2, r0, #0 + 80089b2: 430a orrs r2, r1 + 80089b4: 735a strb r2, [r3, #13] + tcplen = TCP_TCPLEN(&inseg); + 80089b6: 4ba1 ldr r3, [pc, #644] ; (8008c3c ) + 80089b8: 891c ldrh r4, [r3, #8] + 80089ba: 4ba0 ldr r3, [pc, #640] ; (8008c3c ) + 80089bc: 68db ldr r3, [r3, #12] + 80089be: 7b1a ldrb r2, [r3, #12] + 80089c0: 7b5b ldrb r3, [r3, #13] + 80089c2: 021b lsls r3, r3, #8 + 80089c4: 4313 orrs r3, r2 + 80089c6: b29b uxth r3, r3 + 80089c8: 0018 movs r0, r3 + 80089ca: f7fb fe39 bl 8004640 + 80089ce: 0003 movs r3, r0 + 80089d0: 001a movs r2, r3 + 80089d2: 2303 movs r3, #3 + 80089d4: 4013 ands r3, r2 + 80089d6: 1e5a subs r2, r3, #1 + 80089d8: 4193 sbcs r3, r2 + 80089da: b2db uxtb r3, r3 + 80089dc: b29b uxth r3, r3 + 80089de: 18e3 adds r3, r4, r3 + 80089e0: b29a uxth r2, r3 + 80089e2: 4b97 ldr r3, [pc, #604] ; (8008c40 ) + 80089e4: 801a strh r2, [r3, #0] + } + prev = next; + 80089e6: 6afb ldr r3, [r7, #44] ; 0x2c + 80089e8: 62bb str r3, [r7, #40] ; 0x28 + next = next->next; + 80089ea: 6afb ldr r3, [r7, #44] ; 0x2c + 80089ec: 681b ldr r3, [r3, #0] + 80089ee: 62fb str r3, [r7, #44] ; 0x2c + tcp_seg_free(prev); + 80089f0: 6abb ldr r3, [r7, #40] ; 0x28 + 80089f2: 0018 movs r0, r3 + 80089f4: f7fd fe93 bl 800671e + while (next && + 80089f8: 6afb ldr r3, [r7, #44] ; 0x2c + 80089fa: 2b00 cmp r3, #0 + 80089fc: d018 beq.n 8008a30 + TCP_SEQ_GEQ(seqno + tcplen, + 80089fe: 4b90 ldr r3, [pc, #576] ; (8008c40 ) + 8008a00: 881b ldrh r3, [r3, #0] + 8008a02: 001a movs r2, r3 + 8008a04: 4b8f ldr r3, [pc, #572] ; (8008c44 ) + 8008a06: 681b ldr r3, [r3, #0] + 8008a08: 18d2 adds r2, r2, r3 + 8008a0a: 6afb ldr r3, [r7, #44] ; 0x2c + 8008a0c: 68db ldr r3, [r3, #12] + 8008a0e: 7919 ldrb r1, [r3, #4] + 8008a10: 7958 ldrb r0, [r3, #5] + 8008a12: 0200 lsls r0, r0, #8 + 8008a14: 4301 orrs r1, r0 + 8008a16: 7998 ldrb r0, [r3, #6] + 8008a18: 0400 lsls r0, r0, #16 + 8008a1a: 4301 orrs r1, r0 + 8008a1c: 79db ldrb r3, [r3, #7] + 8008a1e: 061b lsls r3, r3, #24 + 8008a20: 430b orrs r3, r1 + 8008a22: 0019 movs r1, r3 + 8008a24: 6afb ldr r3, [r7, #44] ; 0x2c + 8008a26: 891b ldrh r3, [r3, #8] + 8008a28: 18cb adds r3, r1, r3 + 8008a2a: 1ad3 subs r3, r2, r3 + while (next && + 8008a2c: d400 bmi.n 8008a30 + 8008a2e: e781 b.n 8008934 + } + /* Now trim right side of inseg if it overlaps with the first + * segment on ooseq */ + if (next && + 8008a30: 6afb ldr r3, [r7, #44] ; 0x2c + 8008a32: 2b00 cmp r3, #0 + 8008a34: d05d beq.n 8008af2 + TCP_SEQ_GT(seqno + tcplen, + 8008a36: 4b82 ldr r3, [pc, #520] ; (8008c40 ) + 8008a38: 881b ldrh r3, [r3, #0] + 8008a3a: 001a movs r2, r3 + 8008a3c: 4b81 ldr r3, [pc, #516] ; (8008c44 ) + 8008a3e: 681b ldr r3, [r3, #0] + 8008a40: 18d2 adds r2, r2, r3 + 8008a42: 6afb ldr r3, [r7, #44] ; 0x2c + 8008a44: 68db ldr r3, [r3, #12] + 8008a46: 7919 ldrb r1, [r3, #4] + 8008a48: 7958 ldrb r0, [r3, #5] + 8008a4a: 0200 lsls r0, r0, #8 + 8008a4c: 4301 orrs r1, r0 + 8008a4e: 7998 ldrb r0, [r3, #6] + 8008a50: 0400 lsls r0, r0, #16 + 8008a52: 4301 orrs r1, r0 + 8008a54: 79db ldrb r3, [r3, #7] + 8008a56: 061b lsls r3, r3, #24 + 8008a58: 430b orrs r3, r1 + 8008a5a: 1ad3 subs r3, r2, r3 + if (next && + 8008a5c: 2b00 cmp r3, #0 + 8008a5e: dd48 ble.n 8008af2 + next->tcphdr->seqno)) { + /* inseg cannot have FIN here (already processed above) */ + inseg.len = (u16_t)(next->tcphdr->seqno - seqno); + 8008a60: 6afb ldr r3, [r7, #44] ; 0x2c + 8008a62: 68db ldr r3, [r3, #12] + 8008a64: 791a ldrb r2, [r3, #4] + 8008a66: 7959 ldrb r1, [r3, #5] + 8008a68: 0209 lsls r1, r1, #8 + 8008a6a: 430a orrs r2, r1 + 8008a6c: 7999 ldrb r1, [r3, #6] + 8008a6e: 0409 lsls r1, r1, #16 + 8008a70: 430a orrs r2, r1 + 8008a72: 79db ldrb r3, [r3, #7] + 8008a74: 061b lsls r3, r3, #24 + 8008a76: 4313 orrs r3, r2 + 8008a78: b29a uxth r2, r3 + 8008a7a: 4b72 ldr r3, [pc, #456] ; (8008c44 ) + 8008a7c: 681b ldr r3, [r3, #0] + 8008a7e: b29b uxth r3, r3 + 8008a80: 1ad3 subs r3, r2, r3 + 8008a82: b29a uxth r2, r3 + 8008a84: 4b6d ldr r3, [pc, #436] ; (8008c3c ) + 8008a86: 811a strh r2, [r3, #8] + if (TCPH_FLAGS(inseg.tcphdr) & TCP_SYN) { + 8008a88: 4b6c ldr r3, [pc, #432] ; (8008c3c ) + 8008a8a: 68db ldr r3, [r3, #12] + 8008a8c: 7b1a ldrb r2, [r3, #12] + 8008a8e: 7b5b ldrb r3, [r3, #13] + 8008a90: 021b lsls r3, r3, #8 + 8008a92: 4313 orrs r3, r2 + 8008a94: b29b uxth r3, r3 + 8008a96: 0018 movs r0, r3 + 8008a98: f7fb fdd2 bl 8004640 + 8008a9c: 0003 movs r3, r0 + 8008a9e: 001a movs r2, r3 + 8008aa0: 2302 movs r3, #2 + 8008aa2: 4013 ands r3, r2 + 8008aa4: d005 beq.n 8008ab2 + inseg.len -= 1; + 8008aa6: 4b65 ldr r3, [pc, #404] ; (8008c3c ) + 8008aa8: 891b ldrh r3, [r3, #8] + 8008aaa: 3b01 subs r3, #1 + 8008aac: b29a uxth r2, r3 + 8008aae: 4b63 ldr r3, [pc, #396] ; (8008c3c ) + 8008ab0: 811a strh r2, [r3, #8] + } + pbuf_realloc(inseg.p, inseg.len); + 8008ab2: 4b62 ldr r3, [pc, #392] ; (8008c3c ) + 8008ab4: 685a ldr r2, [r3, #4] + 8008ab6: 4b61 ldr r3, [pc, #388] ; (8008c3c ) + 8008ab8: 891b ldrh r3, [r3, #8] + 8008aba: 0019 movs r1, r3 + 8008abc: 0010 movs r0, r2 + 8008abe: f7fc fcf8 bl 80054b2 + tcplen = TCP_TCPLEN(&inseg); + 8008ac2: 4b5e ldr r3, [pc, #376] ; (8008c3c ) + 8008ac4: 891c ldrh r4, [r3, #8] + 8008ac6: 4b5d ldr r3, [pc, #372] ; (8008c3c ) + 8008ac8: 68db ldr r3, [r3, #12] + 8008aca: 7b1a ldrb r2, [r3, #12] + 8008acc: 7b5b ldrb r3, [r3, #13] + 8008ace: 021b lsls r3, r3, #8 + 8008ad0: 4313 orrs r3, r2 + 8008ad2: b29b uxth r3, r3 + 8008ad4: 0018 movs r0, r3 + 8008ad6: f7fb fdb3 bl 8004640 + 8008ada: 0003 movs r3, r0 + 8008adc: 001a movs r2, r3 + 8008ade: 2303 movs r3, #3 + 8008ae0: 4013 ands r3, r2 + 8008ae2: 1e5a subs r2, r3, #1 + 8008ae4: 4193 sbcs r3, r2 + 8008ae6: b2db uxtb r3, r3 + 8008ae8: b29b uxth r3, r3 + 8008aea: 18e3 adds r3, r4, r3 + 8008aec: b29a uxth r2, r3 + 8008aee: 4b54 ldr r3, [pc, #336] ; (8008c40 ) + 8008af0: 801a strh r2, [r3, #0] + LWIP_ASSERT("tcp_receive: segment not trimmed correctly to ooseq queue\n", + (seqno + tcplen) == next->tcphdr->seqno); + } + pcb->ooseq = next; + 8008af2: 687b ldr r3, [r7, #4] + 8008af4: 6afa ldr r2, [r7, #44] ; 0x2c + 8008af6: 675a str r2, [r3, #116] ; 0x74 + } + } +#endif /* TCP_QUEUE_OOSEQ */ + + pcb->rcv_nxt = seqno + tcplen; + 8008af8: 4b51 ldr r3, [pc, #324] ; (8008c40 ) + 8008afa: 881b ldrh r3, [r3, #0] + 8008afc: 001a movs r2, r3 + 8008afe: 4b51 ldr r3, [pc, #324] ; (8008c44 ) + 8008b00: 681b ldr r3, [r3, #0] + 8008b02: 18d2 adds r2, r2, r3 + 8008b04: 687b ldr r3, [r7, #4] + 8008b06: 629a str r2, [r3, #40] ; 0x28 + + /* Update the receiver's (our) window. */ + LWIP_ASSERT("tcp_receive: tcplen > rcv_wnd\n", pcb->rcv_wnd >= tcplen); + pcb->rcv_wnd -= tcplen; + 8008b08: 687b ldr r3, [r7, #4] + 8008b0a: 8d9a ldrh r2, [r3, #44] ; 0x2c + 8008b0c: 4b4c ldr r3, [pc, #304] ; (8008c40 ) + 8008b0e: 881b ldrh r3, [r3, #0] + 8008b10: 1ad3 subs r3, r2, r3 + 8008b12: b29a uxth r2, r3 + 8008b14: 687b ldr r3, [r7, #4] + 8008b16: 859a strh r2, [r3, #44] ; 0x2c + + tcp_update_rcv_ann_wnd(pcb); + 8008b18: 687b ldr r3, [r7, #4] + 8008b1a: 0018 movs r0, r3 + 8008b1c: f7fd fa3c bl 8005f98 + chains its data on this pbuf as well. + + If the segment was a FIN, we set the TF_GOT_FIN flag that will + be used to indicate to the application that the remote side has + closed its end of the connection. */ + if (inseg.p->tot_len > 0) { + 8008b20: 4b46 ldr r3, [pc, #280] ; (8008c3c ) + 8008b22: 685b ldr r3, [r3, #4] + 8008b24: 891b ldrh r3, [r3, #8] + 8008b26: 2b00 cmp r3, #0 + 8008b28: d006 beq.n 8008b38 + recv_data = inseg.p; + 8008b2a: 4b44 ldr r3, [pc, #272] ; (8008c3c ) + 8008b2c: 685a ldr r2, [r3, #4] + 8008b2e: 4b46 ldr r3, [pc, #280] ; (8008c48 ) + 8008b30: 601a str r2, [r3, #0] + /* Since this pbuf now is the responsibility of the + application, we delete our reference to it so that we won't + (mistakingly) deallocate it. */ + inseg.p = NULL; + 8008b32: 4b42 ldr r3, [pc, #264] ; (8008c3c ) + 8008b34: 2200 movs r2, #0 + 8008b36: 605a str r2, [r3, #4] + } + if (TCPH_FLAGS(inseg.tcphdr) & TCP_FIN) { + 8008b38: 4b40 ldr r3, [pc, #256] ; (8008c3c ) + 8008b3a: 68db ldr r3, [r3, #12] + 8008b3c: 7b1a ldrb r2, [r3, #12] + 8008b3e: 7b5b ldrb r3, [r3, #13] + 8008b40: 021b lsls r3, r3, #8 + 8008b42: 4313 orrs r3, r2 + 8008b44: b29b uxth r3, r3 + 8008b46: 0018 movs r0, r3 + 8008b48: f7fb fd7a bl 8004640 + 8008b4c: 0003 movs r3, r0 + 8008b4e: 001a movs r2, r3 + 8008b50: 2301 movs r3, #1 + 8008b52: 4013 ands r3, r2 + 8008b54: d100 bne.n 8008b58 + 8008b56: e0a7 b.n 8008ca8 + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: received FIN.\n")); + recv_flags |= TF_GOT_FIN; + 8008b58: 4b3c ldr r3, [pc, #240] ; (8008c4c ) + 8008b5a: 781b ldrb r3, [r3, #0] + 8008b5c: 2220 movs r2, #32 + 8008b5e: 4313 orrs r3, r2 + 8008b60: b2da uxtb r2, r3 + 8008b62: 4b3a ldr r3, [pc, #232] ; (8008c4c ) + 8008b64: 701a strb r2, [r3, #0] + } + +#if TCP_QUEUE_OOSEQ + /* We now check if we have segments on the ->ooseq queue that + are now in sequence. */ + while (pcb->ooseq != NULL && + 8008b66: e09f b.n 8008ca8 + pcb->ooseq->tcphdr->seqno == pcb->rcv_nxt) { + + cseg = pcb->ooseq; + 8008b68: 687b ldr r3, [r7, #4] + 8008b6a: 6f5b ldr r3, [r3, #116] ; 0x74 + 8008b6c: 60fb str r3, [r7, #12] + seqno = pcb->ooseq->tcphdr->seqno; + 8008b6e: 687b ldr r3, [r7, #4] + 8008b70: 6f5b ldr r3, [r3, #116] ; 0x74 + 8008b72: 68db ldr r3, [r3, #12] + 8008b74: 791a ldrb r2, [r3, #4] + 8008b76: 7959 ldrb r1, [r3, #5] + 8008b78: 0209 lsls r1, r1, #8 + 8008b7a: 430a orrs r2, r1 + 8008b7c: 7999 ldrb r1, [r3, #6] + 8008b7e: 0409 lsls r1, r1, #16 + 8008b80: 430a orrs r2, r1 + 8008b82: 79db ldrb r3, [r3, #7] + 8008b84: 061b lsls r3, r3, #24 + 8008b86: 4313 orrs r3, r2 + 8008b88: 001a movs r2, r3 + 8008b8a: 4b2e ldr r3, [pc, #184] ; (8008c44 ) + 8008b8c: 601a str r2, [r3, #0] + + pcb->rcv_nxt += TCP_TCPLEN(cseg); + 8008b8e: 68fb ldr r3, [r7, #12] + 8008b90: 891b ldrh r3, [r3, #8] + 8008b92: 001c movs r4, r3 + 8008b94: 68fb ldr r3, [r7, #12] + 8008b96: 68db ldr r3, [r3, #12] + 8008b98: 7b1a ldrb r2, [r3, #12] + 8008b9a: 7b5b ldrb r3, [r3, #13] + 8008b9c: 021b lsls r3, r3, #8 + 8008b9e: 4313 orrs r3, r2 + 8008ba0: b29b uxth r3, r3 + 8008ba2: 0018 movs r0, r3 + 8008ba4: f7fb fd4c bl 8004640 + 8008ba8: 0003 movs r3, r0 + 8008baa: 001a movs r2, r3 + 8008bac: 2303 movs r3, #3 + 8008bae: 4013 ands r3, r2 + 8008bb0: 1e5a subs r2, r3, #1 + 8008bb2: 4193 sbcs r3, r2 + 8008bb4: b2db uxtb r3, r3 + 8008bb6: 18e2 adds r2, r4, r3 + 8008bb8: 687b ldr r3, [r7, #4] + 8008bba: 6a9b ldr r3, [r3, #40] ; 0x28 + 8008bbc: 189a adds r2, r3, r2 + 8008bbe: 687b ldr r3, [r7, #4] + 8008bc0: 629a str r2, [r3, #40] ; 0x28 + LWIP_ASSERT("tcp_receive: ooseq tcplen > rcv_wnd\n", + 8008bc2: 68fb ldr r3, [r7, #12] + 8008bc4: 68db ldr r3, [r3, #12] + 8008bc6: 7b1a ldrb r2, [r3, #12] + 8008bc8: 7b5b ldrb r3, [r3, #13] + 8008bca: 021b lsls r3, r3, #8 + 8008bcc: 4313 orrs r3, r2 + 8008bce: b29b uxth r3, r3 + 8008bd0: 0018 movs r0, r3 + 8008bd2: f7fb fd35 bl 8004640 + pcb->rcv_wnd >= TCP_TCPLEN(cseg)); + pcb->rcv_wnd -= TCP_TCPLEN(cseg); + 8008bd6: 68fb ldr r3, [r7, #12] + 8008bd8: 891b ldrh r3, [r3, #8] + 8008bda: 001c movs r4, r3 + 8008bdc: 68fb ldr r3, [r7, #12] + 8008bde: 68db ldr r3, [r3, #12] + 8008be0: 7b1a ldrb r2, [r3, #12] + 8008be2: 7b5b ldrb r3, [r3, #13] + 8008be4: 021b lsls r3, r3, #8 + 8008be6: 4313 orrs r3, r2 + 8008be8: b29b uxth r3, r3 + 8008bea: 0018 movs r0, r3 + 8008bec: f7fb fd28 bl 8004640 + 8008bf0: 0003 movs r3, r0 + 8008bf2: 001a movs r2, r3 + 8008bf4: 2303 movs r3, #3 + 8008bf6: 4013 ands r3, r2 + 8008bf8: 1e5a subs r2, r3, #1 + 8008bfa: 4193 sbcs r3, r2 + 8008bfc: b2db uxtb r3, r3 + 8008bfe: 18e1 adds r1, r4, r3 + 8008c00: 687b ldr r3, [r7, #4] + 8008c02: 8d9a ldrh r2, [r3, #44] ; 0x2c + 8008c04: b28b uxth r3, r1 + 8008c06: 1ad3 subs r3, r2, r3 + 8008c08: b29a uxth r2, r3 + 8008c0a: 687b ldr r3, [r7, #4] + 8008c0c: 859a strh r2, [r3, #44] ; 0x2c + + tcp_update_rcv_ann_wnd(pcb); + 8008c0e: 687b ldr r3, [r7, #4] + 8008c10: 0018 movs r0, r3 + 8008c12: f7fd f9c1 bl 8005f98 + + if (cseg->p->tot_len > 0) { + 8008c16: 68fb ldr r3, [r7, #12] + 8008c18: 685b ldr r3, [r3, #4] + 8008c1a: 891b ldrh r3, [r3, #8] + 8008c1c: 2b00 cmp r3, #0 + 8008c1e: d01e beq.n 8008c5e + /* Chain this pbuf onto the pbuf that we will pass to + the application. */ + if (recv_data) { + 8008c20: 4b09 ldr r3, [pc, #36] ; (8008c48 ) + 8008c22: 681b ldr r3, [r3, #0] + 8008c24: 2b00 cmp r3, #0 + 8008c26: d013 beq.n 8008c50 + pbuf_cat(recv_data, cseg->p); + 8008c28: 4b07 ldr r3, [pc, #28] ; (8008c48 ) + 8008c2a: 681a ldr r2, [r3, #0] + 8008c2c: 68fb ldr r3, [r7, #12] + 8008c2e: 685b ldr r3, [r3, #4] + 8008c30: 0019 movs r1, r3 + 8008c32: 0010 movs r0, r2 + 8008c34: f7fc fdd5 bl 80057e2 + 8008c38: e00e b.n 8008c58 + 8008c3a: 46c0 nop ; (mov r8, r8) + 8008c3c: 2000227c .word 0x2000227c + 8008c40: 2000229e .word 0x2000229e + 8008c44: 20002294 .word 0x20002294 + 8008c48: 200022a4 .word 0x200022a4 + 8008c4c: 200022a0 .word 0x200022a0 + } else { + recv_data = cseg->p; + 8008c50: 68fb ldr r3, [r7, #12] + 8008c52: 685a ldr r2, [r3, #4] + 8008c54: 4b9b ldr r3, [pc, #620] ; (8008ec4 ) + 8008c56: 601a str r2, [r3, #0] + } + cseg->p = NULL; + 8008c58: 68fb ldr r3, [r7, #12] + 8008c5a: 2200 movs r2, #0 + 8008c5c: 605a str r2, [r3, #4] + } + if (TCPH_FLAGS(cseg->tcphdr) & TCP_FIN) { + 8008c5e: 68fb ldr r3, [r7, #12] + 8008c60: 68db ldr r3, [r3, #12] + 8008c62: 7b1a ldrb r2, [r3, #12] + 8008c64: 7b5b ldrb r3, [r3, #13] + 8008c66: 021b lsls r3, r3, #8 + 8008c68: 4313 orrs r3, r2 + 8008c6a: b29b uxth r3, r3 + 8008c6c: 0018 movs r0, r3 + 8008c6e: f7fb fce7 bl 8004640 + 8008c72: 0003 movs r3, r0 + 8008c74: 001a movs r2, r3 + 8008c76: 2301 movs r3, #1 + 8008c78: 4013 ands r3, r2 + 8008c7a: d00d beq.n 8008c98 + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: dequeued FIN.\n")); + recv_flags |= TF_GOT_FIN; + 8008c7c: 4b92 ldr r3, [pc, #584] ; (8008ec8 ) + 8008c7e: 781b ldrb r3, [r3, #0] + 8008c80: 2220 movs r2, #32 + 8008c82: 4313 orrs r3, r2 + 8008c84: b2da uxtb r2, r3 + 8008c86: 4b90 ldr r3, [pc, #576] ; (8008ec8 ) + 8008c88: 701a strb r2, [r3, #0] + if (pcb->state == ESTABLISHED) { /* force passive close or we can move to active close */ + 8008c8a: 687b ldr r3, [r7, #4] + 8008c8c: 7e1b ldrb r3, [r3, #24] + 8008c8e: 2b04 cmp r3, #4 + 8008c90: d102 bne.n 8008c98 + pcb->state = CLOSE_WAIT; + 8008c92: 687b ldr r3, [r7, #4] + 8008c94: 2207 movs r2, #7 + 8008c96: 761a strb r2, [r3, #24] + } + } + + pcb->ooseq = cseg->next; + 8008c98: 68fb ldr r3, [r7, #12] + 8008c9a: 681a ldr r2, [r3, #0] + 8008c9c: 687b ldr r3, [r7, #4] + 8008c9e: 675a str r2, [r3, #116] ; 0x74 + tcp_seg_free(cseg); + 8008ca0: 68fb ldr r3, [r7, #12] + 8008ca2: 0018 movs r0, r3 + 8008ca4: f7fd fd3b bl 800671e + while (pcb->ooseq != NULL && + 8008ca8: 687b ldr r3, [r7, #4] + 8008caa: 6f5b ldr r3, [r3, #116] ; 0x74 + 8008cac: 2b00 cmp r3, #0 + 8008cae: d012 beq.n 8008cd6 + pcb->ooseq->tcphdr->seqno == pcb->rcv_nxt) { + 8008cb0: 687b ldr r3, [r7, #4] + 8008cb2: 6f5b ldr r3, [r3, #116] ; 0x74 + 8008cb4: 68db ldr r3, [r3, #12] + 8008cb6: 791a ldrb r2, [r3, #4] + 8008cb8: 7959 ldrb r1, [r3, #5] + 8008cba: 0209 lsls r1, r1, #8 + 8008cbc: 430a orrs r2, r1 + 8008cbe: 7999 ldrb r1, [r3, #6] + 8008cc0: 0409 lsls r1, r1, #16 + 8008cc2: 430a orrs r2, r1 + 8008cc4: 79db ldrb r3, [r3, #7] + 8008cc6: 061b lsls r3, r3, #24 + 8008cc8: 4313 orrs r3, r2 + 8008cca: 001a movs r2, r3 + 8008ccc: 687b ldr r3, [r7, #4] + 8008cce: 6a9b ldr r3, [r3, #40] ; 0x28 + while (pcb->ooseq != NULL && + 8008cd0: 429a cmp r2, r3 + 8008cd2: d100 bne.n 8008cd6 + 8008cd4: e748 b.n 8008b68 + } +#endif /* TCP_QUEUE_OOSEQ */ + + + /* Acknowledge the segment(s). */ + tcp_ack(pcb); + 8008cd6: 687b ldr r3, [r7, #4] + 8008cd8: 7f9b ldrb r3, [r3, #30] + 8008cda: 001a movs r2, r3 + 8008cdc: 2301 movs r3, #1 + 8008cde: 4013 ands r3, r2 + 8008ce0: d00e beq.n 8008d00 + 8008ce2: 687b ldr r3, [r7, #4] + 8008ce4: 7f9b ldrb r3, [r3, #30] + 8008ce6: 2201 movs r2, #1 + 8008ce8: 4393 bics r3, r2 + 8008cea: b2da uxtb r2, r3 + 8008cec: 687b ldr r3, [r7, #4] + 8008cee: 779a strb r2, [r3, #30] + 8008cf0: 687b ldr r3, [r7, #4] + 8008cf2: 7f9b ldrb r3, [r3, #30] + 8008cf4: 2202 movs r2, #2 + 8008cf6: 4313 orrs r3, r2 + 8008cf8: b2da uxtb r2, r3 + 8008cfa: 687b ldr r3, [r7, #4] + 8008cfc: 779a strb r2, [r3, #30] + if (pcb->rcv_nxt == seqno) { + 8008cfe: e1f4 b.n 80090ea + tcp_ack(pcb); + 8008d00: 687b ldr r3, [r7, #4] + 8008d02: 7f9b ldrb r3, [r3, #30] + 8008d04: 2201 movs r2, #1 + 8008d06: 4313 orrs r3, r2 + 8008d08: b2da uxtb r2, r3 + 8008d0a: 687b ldr r3, [r7, #4] + 8008d0c: 779a strb r2, [r3, #30] + if (pcb->rcv_nxt == seqno) { + 8008d0e: e1ec b.n 80090ea + + } else { + /* We get here if the incoming segment is out-of-sequence. */ + tcp_send_empty_ack(pcb); + 8008d10: 687b ldr r3, [r7, #4] + 8008d12: 0018 movs r0, r3 + 8008d14: f000 fe1c bl 8009950 +#if TCP_QUEUE_OOSEQ + /* We queue the segment on the ->ooseq queue. */ + if (pcb->ooseq == NULL) { + 8008d18: 687b ldr r3, [r7, #4] + 8008d1a: 6f5b ldr r3, [r3, #116] ; 0x74 + 8008d1c: 2b00 cmp r3, #0 + 8008d1e: d107 bne.n 8008d30 + pcb->ooseq = tcp_seg_copy(&inseg); + 8008d20: 4b6a ldr r3, [pc, #424] ; (8008ecc ) + 8008d22: 0018 movs r0, r3 + 8008d24: f7fd fd14 bl 8006750 + 8008d28: 0002 movs r2, r0 + 8008d2a: 687b ldr r3, [r7, #4] + 8008d2c: 675a str r2, [r3, #116] ; 0x74 + if (pcb->rcv_nxt == seqno) { + 8008d2e: e1dc b.n 80090ea + + If the incoming segment has the same sequence number as a + segment on the ->ooseq queue, we discard the segment that + contains less data. */ + + prev = NULL; + 8008d30: 2300 movs r3, #0 + 8008d32: 62bb str r3, [r7, #40] ; 0x28 + for(next = pcb->ooseq; next != NULL; next = next->next) { + 8008d34: 687b ldr r3, [r7, #4] + 8008d36: 6f5b ldr r3, [r3, #116] ; 0x74 + 8008d38: 62fb str r3, [r7, #44] ; 0x2c + 8008d3a: e1c0 b.n 80090be + if (seqno == next->tcphdr->seqno) { + 8008d3c: 6afb ldr r3, [r7, #44] ; 0x2c + 8008d3e: 68db ldr r3, [r3, #12] + 8008d40: 791a ldrb r2, [r3, #4] + 8008d42: 7959 ldrb r1, [r3, #5] + 8008d44: 0209 lsls r1, r1, #8 + 8008d46: 430a orrs r2, r1 + 8008d48: 7999 ldrb r1, [r3, #6] + 8008d4a: 0409 lsls r1, r1, #16 + 8008d4c: 430a orrs r2, r1 + 8008d4e: 79db ldrb r3, [r3, #7] + 8008d50: 061b lsls r3, r3, #24 + 8008d52: 4313 orrs r3, r2 + 8008d54: 001a movs r2, r3 + 8008d56: 4b5e ldr r3, [pc, #376] ; (8008ed0 ) + 8008d58: 681b ldr r3, [r3, #0] + 8008d5a: 429a cmp r2, r3 + 8008d5c: d121 bne.n 8008da2 + /* The sequence number of the incoming segment is the + same as the sequence number of the segment on + ->ooseq. We check the lengths to see which one to + discard. */ + if (inseg.len > next->len) { + 8008d5e: 4b5b ldr r3, [pc, #364] ; (8008ecc ) + 8008d60: 891a ldrh r2, [r3, #8] + 8008d62: 6afb ldr r3, [r7, #44] ; 0x2c + 8008d64: 891b ldrh r3, [r3, #8] + 8008d66: 429a cmp r2, r3 + 8008d68: d800 bhi.n 8008d6c + 8008d6a: e1ad b.n 80090c8 + /* The incoming segment is larger than the old + segment. We replace some segments with the new + one. */ + cseg = tcp_seg_copy(&inseg); + 8008d6c: 4b57 ldr r3, [pc, #348] ; (8008ecc ) + 8008d6e: 0018 movs r0, r3 + 8008d70: f7fd fcee bl 8006750 + 8008d74: 0003 movs r3, r0 + 8008d76: 60fb str r3, [r7, #12] + if (cseg != NULL) { + 8008d78: 68fb ldr r3, [r7, #12] + 8008d7a: 2b00 cmp r3, #0 + 8008d7c: d100 bne.n 8008d80 + 8008d7e: e1a5 b.n 80090cc + if (prev != NULL) { + 8008d80: 6abb ldr r3, [r7, #40] ; 0x28 + 8008d82: 2b00 cmp r3, #0 + 8008d84: d003 beq.n 8008d8e + prev->next = cseg; + 8008d86: 6abb ldr r3, [r7, #40] ; 0x28 + 8008d88: 68fa ldr r2, [r7, #12] + 8008d8a: 601a str r2, [r3, #0] + 8008d8c: e002 b.n 8008d94 + } else { + pcb->ooseq = cseg; + 8008d8e: 687b ldr r3, [r7, #4] + 8008d90: 68fa ldr r2, [r7, #12] + 8008d92: 675a str r2, [r3, #116] ; 0x74 + } + tcp_oos_insert_segment(cseg, next); + 8008d94: 6afa ldr r2, [r7, #44] ; 0x2c + 8008d96: 68fb ldr r3, [r7, #12] + 8008d98: 0011 movs r1, r2 + 8008d9a: 0018 movs r0, r3 + 8008d9c: f7ff f874 bl 8007e88 + } + break; + 8008da0: e194 b.n 80090cc + segment was smaller than the old one; in either + case, we ditch the incoming segment. */ + break; + } + } else { + if (prev == NULL) { + 8008da2: 6abb ldr r3, [r7, #40] ; 0x28 + 8008da4: 2b00 cmp r3, #0 + 8008da6: d124 bne.n 8008df2 + if (TCP_SEQ_LT(seqno, next->tcphdr->seqno)) { + 8008da8: 4b49 ldr r3, [pc, #292] ; (8008ed0 ) + 8008daa: 681a ldr r2, [r3, #0] + 8008dac: 6afb ldr r3, [r7, #44] ; 0x2c + 8008dae: 68db ldr r3, [r3, #12] + 8008db0: 7919 ldrb r1, [r3, #4] + 8008db2: 7958 ldrb r0, [r3, #5] + 8008db4: 0200 lsls r0, r0, #8 + 8008db6: 4301 orrs r1, r0 + 8008db8: 7998 ldrb r0, [r3, #6] + 8008dba: 0400 lsls r0, r0, #16 + 8008dbc: 4301 orrs r1, r0 + 8008dbe: 79db ldrb r3, [r3, #7] + 8008dc0: 061b lsls r3, r3, #24 + 8008dc2: 430b orrs r3, r1 + 8008dc4: 1ad3 subs r3, r2, r3 + 8008dc6: d400 bmi.n 8008dca + 8008dc8: e084 b.n 8008ed4 + /* The sequence number of the incoming segment is lower + than the sequence number of the first segment on the + queue. We put the incoming segment first on the + queue. */ + cseg = tcp_seg_copy(&inseg); + 8008dca: 4b40 ldr r3, [pc, #256] ; (8008ecc ) + 8008dcc: 0018 movs r0, r3 + 8008dce: f7fd fcbf bl 8006750 + 8008dd2: 0003 movs r3, r0 + 8008dd4: 60fb str r3, [r7, #12] + if (cseg != NULL) { + 8008dd6: 68fb ldr r3, [r7, #12] + 8008dd8: 2b00 cmp r3, #0 + 8008dda: d100 bne.n 8008dde + 8008ddc: e178 b.n 80090d0 + pcb->ooseq = cseg; + 8008dde: 687b ldr r3, [r7, #4] + 8008de0: 68fa ldr r2, [r7, #12] + 8008de2: 675a str r2, [r3, #116] ; 0x74 + tcp_oos_insert_segment(cseg, next); + 8008de4: 6afa ldr r2, [r7, #44] ; 0x2c + 8008de6: 68fb ldr r3, [r7, #12] + 8008de8: 0011 movs r1, r2 + 8008dea: 0018 movs r0, r3 + 8008dec: f7ff f84c bl 8007e88 + } + break; + 8008df0: e16e b.n 80090d0 + } + } else { + /*if (TCP_SEQ_LT(prev->tcphdr->seqno, seqno) && + TCP_SEQ_LT(seqno, next->tcphdr->seqno)) {*/ + if (TCP_SEQ_BETWEEN(seqno, prev->tcphdr->seqno+1, next->tcphdr->seqno-1)) { + 8008df2: 4b37 ldr r3, [pc, #220] ; (8008ed0 ) + 8008df4: 681a ldr r2, [r3, #0] + 8008df6: 6abb ldr r3, [r7, #40] ; 0x28 + 8008df8: 68db ldr r3, [r3, #12] + 8008dfa: 7919 ldrb r1, [r3, #4] + 8008dfc: 7958 ldrb r0, [r3, #5] + 8008dfe: 0200 lsls r0, r0, #8 + 8008e00: 4301 orrs r1, r0 + 8008e02: 7998 ldrb r0, [r3, #6] + 8008e04: 0400 lsls r0, r0, #16 + 8008e06: 4301 orrs r1, r0 + 8008e08: 79db ldrb r3, [r3, #7] + 8008e0a: 061b lsls r3, r3, #24 + 8008e0c: 430b orrs r3, r1 + 8008e0e: 1ad3 subs r3, r2, r3 + 8008e10: 3b01 subs r3, #1 + 8008e12: 2b00 cmp r3, #0 + 8008e14: db5e blt.n 8008ed4 + 8008e16: 4b2e ldr r3, [pc, #184] ; (8008ed0 ) + 8008e18: 681a ldr r2, [r3, #0] + 8008e1a: 6afb ldr r3, [r7, #44] ; 0x2c + 8008e1c: 68db ldr r3, [r3, #12] + 8008e1e: 7919 ldrb r1, [r3, #4] + 8008e20: 7958 ldrb r0, [r3, #5] + 8008e22: 0200 lsls r0, r0, #8 + 8008e24: 4301 orrs r1, r0 + 8008e26: 7998 ldrb r0, [r3, #6] + 8008e28: 0400 lsls r0, r0, #16 + 8008e2a: 4301 orrs r1, r0 + 8008e2c: 79db ldrb r3, [r3, #7] + 8008e2e: 061b lsls r3, r3, #24 + 8008e30: 430b orrs r3, r1 + 8008e32: 1ad3 subs r3, r2, r3 + 8008e34: 3301 adds r3, #1 + 8008e36: 2b00 cmp r3, #0 + 8008e38: dc4c bgt.n 8008ed4 + /* The sequence number of the incoming segment is in + between the sequence numbers of the previous and + the next segment on ->ooseq. We trim trim the previous + segment, delete next segments that included in received segment + and trim received, if needed. */ + cseg = tcp_seg_copy(&inseg); + 8008e3a: 4b24 ldr r3, [pc, #144] ; (8008ecc ) + 8008e3c: 0018 movs r0, r3 + 8008e3e: f7fd fc87 bl 8006750 + 8008e42: 0003 movs r3, r0 + 8008e44: 60fb str r3, [r7, #12] + if (cseg != NULL) { + 8008e46: 68fb ldr r3, [r7, #12] + 8008e48: 2b00 cmp r3, #0 + 8008e4a: d100 bne.n 8008e4e + 8008e4c: e142 b.n 80090d4 + if (TCP_SEQ_GT(prev->tcphdr->seqno + prev->len, seqno)) { + 8008e4e: 6abb ldr r3, [r7, #40] ; 0x28 + 8008e50: 68db ldr r3, [r3, #12] + 8008e52: 791a ldrb r2, [r3, #4] + 8008e54: 7959 ldrb r1, [r3, #5] + 8008e56: 0209 lsls r1, r1, #8 + 8008e58: 430a orrs r2, r1 + 8008e5a: 7999 ldrb r1, [r3, #6] + 8008e5c: 0409 lsls r1, r1, #16 + 8008e5e: 430a orrs r2, r1 + 8008e60: 79db ldrb r3, [r3, #7] + 8008e62: 061b lsls r3, r3, #24 + 8008e64: 4313 orrs r3, r2 + 8008e66: 001a movs r2, r3 + 8008e68: 6abb ldr r3, [r7, #40] ; 0x28 + 8008e6a: 891b ldrh r3, [r3, #8] + 8008e6c: 18d2 adds r2, r2, r3 + 8008e6e: 4b18 ldr r3, [pc, #96] ; (8008ed0 ) + 8008e70: 681b ldr r3, [r3, #0] + 8008e72: 1ad3 subs r3, r2, r3 + 8008e74: 2b00 cmp r3, #0 + 8008e76: dd1b ble.n 8008eb0 + /* We need to trim the prev segment. */ + prev->len = (u16_t)(seqno - prev->tcphdr->seqno); + 8008e78: 4b15 ldr r3, [pc, #84] ; (8008ed0 ) + 8008e7a: 681b ldr r3, [r3, #0] + 8008e7c: b29a uxth r2, r3 + 8008e7e: 6abb ldr r3, [r7, #40] ; 0x28 + 8008e80: 68db ldr r3, [r3, #12] + 8008e82: 7919 ldrb r1, [r3, #4] + 8008e84: 7958 ldrb r0, [r3, #5] + 8008e86: 0200 lsls r0, r0, #8 + 8008e88: 4301 orrs r1, r0 + 8008e8a: 7998 ldrb r0, [r3, #6] + 8008e8c: 0400 lsls r0, r0, #16 + 8008e8e: 4301 orrs r1, r0 + 8008e90: 79db ldrb r3, [r3, #7] + 8008e92: 061b lsls r3, r3, #24 + 8008e94: 430b orrs r3, r1 + 8008e96: b29b uxth r3, r3 + 8008e98: 1ad3 subs r3, r2, r3 + 8008e9a: b29a uxth r2, r3 + 8008e9c: 6abb ldr r3, [r7, #40] ; 0x28 + 8008e9e: 811a strh r2, [r3, #8] + pbuf_realloc(prev->p, prev->len); + 8008ea0: 6abb ldr r3, [r7, #40] ; 0x28 + 8008ea2: 685a ldr r2, [r3, #4] + 8008ea4: 6abb ldr r3, [r7, #40] ; 0x28 + 8008ea6: 891b ldrh r3, [r3, #8] + 8008ea8: 0019 movs r1, r3 + 8008eaa: 0010 movs r0, r2 + 8008eac: f7fc fb01 bl 80054b2 + } + prev->next = cseg; + 8008eb0: 6abb ldr r3, [r7, #40] ; 0x28 + 8008eb2: 68fa ldr r2, [r7, #12] + 8008eb4: 601a str r2, [r3, #0] + tcp_oos_insert_segment(cseg, next); + 8008eb6: 6afa ldr r2, [r7, #44] ; 0x2c + 8008eb8: 68fb ldr r3, [r7, #12] + 8008eba: 0011 movs r1, r2 + 8008ebc: 0018 movs r0, r3 + 8008ebe: f7fe ffe3 bl 8007e88 + } + break; + 8008ec2: e107 b.n 80090d4 + 8008ec4: 200022a4 .word 0x200022a4 + 8008ec8: 200022a0 .word 0x200022a0 + 8008ecc: 2000227c .word 0x2000227c + 8008ed0: 20002294 .word 0x20002294 + } + } + /* If the "next" segment is the last segment on the + ooseq queue, we add the incoming segment to the end + of the list. */ + if (next->next == NULL && + 8008ed4: 6afb ldr r3, [r7, #44] ; 0x2c + 8008ed6: 681b ldr r3, [r3, #0] + 8008ed8: 2b00 cmp r3, #0 + 8008eda: d000 beq.n 8008ede + 8008edc: e0ea b.n 80090b4 + TCP_SEQ_GT(seqno, next->tcphdr->seqno)) { + 8008ede: 4b92 ldr r3, [pc, #584] ; (8009128 ) + 8008ee0: 681a ldr r2, [r3, #0] + 8008ee2: 6afb ldr r3, [r7, #44] ; 0x2c + 8008ee4: 68db ldr r3, [r3, #12] + 8008ee6: 7919 ldrb r1, [r3, #4] + 8008ee8: 7958 ldrb r0, [r3, #5] + 8008eea: 0200 lsls r0, r0, #8 + 8008eec: 4301 orrs r1, r0 + 8008eee: 7998 ldrb r0, [r3, #6] + 8008ef0: 0400 lsls r0, r0, #16 + 8008ef2: 4301 orrs r1, r0 + 8008ef4: 79db ldrb r3, [r3, #7] + 8008ef6: 061b lsls r3, r3, #24 + 8008ef8: 430b orrs r3, r1 + 8008efa: 1ad3 subs r3, r2, r3 + if (next->next == NULL && + 8008efc: 2b00 cmp r3, #0 + 8008efe: dc00 bgt.n 8008f02 + 8008f00: e0d8 b.n 80090b4 + if (TCPH_FLAGS(next->tcphdr) & TCP_FIN) { + 8008f02: 6afb ldr r3, [r7, #44] ; 0x2c + 8008f04: 68db ldr r3, [r3, #12] + 8008f06: 7b1a ldrb r2, [r3, #12] + 8008f08: 7b5b ldrb r3, [r3, #13] + 8008f0a: 021b lsls r3, r3, #8 + 8008f0c: 4313 orrs r3, r2 + 8008f0e: b29b uxth r3, r3 + 8008f10: 0018 movs r0, r3 + 8008f12: f7fb fb95 bl 8004640 + 8008f16: 0003 movs r3, r0 + 8008f18: 001a movs r2, r3 + 8008f1a: 2301 movs r3, #1 + 8008f1c: 4013 ands r3, r2 + 8008f1e: d000 beq.n 8008f22 + 8008f20: e0da b.n 80090d8 + /* segment "next" already contains all data */ + break; + } + next->next = tcp_seg_copy(&inseg); + 8008f22: 4b82 ldr r3, [pc, #520] ; (800912c ) + 8008f24: 0018 movs r0, r3 + 8008f26: f7fd fc13 bl 8006750 + 8008f2a: 0002 movs r2, r0 + 8008f2c: 6afb ldr r3, [r7, #44] ; 0x2c + 8008f2e: 601a str r2, [r3, #0] + if (next->next != NULL) { + 8008f30: 6afb ldr r3, [r7, #44] ; 0x2c + 8008f32: 681b ldr r3, [r3, #0] + 8008f34: 2b00 cmp r3, #0 + 8008f36: d100 bne.n 8008f3a + 8008f38: e0d0 b.n 80090dc + if (TCP_SEQ_GT(next->tcphdr->seqno + next->len, seqno)) { + 8008f3a: 6afb ldr r3, [r7, #44] ; 0x2c + 8008f3c: 68db ldr r3, [r3, #12] + 8008f3e: 791a ldrb r2, [r3, #4] + 8008f40: 7959 ldrb r1, [r3, #5] + 8008f42: 0209 lsls r1, r1, #8 + 8008f44: 430a orrs r2, r1 + 8008f46: 7999 ldrb r1, [r3, #6] + 8008f48: 0409 lsls r1, r1, #16 + 8008f4a: 430a orrs r2, r1 + 8008f4c: 79db ldrb r3, [r3, #7] + 8008f4e: 061b lsls r3, r3, #24 + 8008f50: 4313 orrs r3, r2 + 8008f52: 001a movs r2, r3 + 8008f54: 6afb ldr r3, [r7, #44] ; 0x2c + 8008f56: 891b ldrh r3, [r3, #8] + 8008f58: 18d2 adds r2, r2, r3 + 8008f5a: 4b73 ldr r3, [pc, #460] ; (8009128 ) + 8008f5c: 681b ldr r3, [r3, #0] + 8008f5e: 1ad3 subs r3, r2, r3 + 8008f60: 2b00 cmp r3, #0 + 8008f62: dd1b ble.n 8008f9c + /* We need to trim the last segment. */ + next->len = (u16_t)(seqno - next->tcphdr->seqno); + 8008f64: 4b70 ldr r3, [pc, #448] ; (8009128 ) + 8008f66: 681b ldr r3, [r3, #0] + 8008f68: b29a uxth r2, r3 + 8008f6a: 6afb ldr r3, [r7, #44] ; 0x2c + 8008f6c: 68db ldr r3, [r3, #12] + 8008f6e: 7919 ldrb r1, [r3, #4] + 8008f70: 7958 ldrb r0, [r3, #5] + 8008f72: 0200 lsls r0, r0, #8 + 8008f74: 4301 orrs r1, r0 + 8008f76: 7998 ldrb r0, [r3, #6] + 8008f78: 0400 lsls r0, r0, #16 + 8008f7a: 4301 orrs r1, r0 + 8008f7c: 79db ldrb r3, [r3, #7] + 8008f7e: 061b lsls r3, r3, #24 + 8008f80: 430b orrs r3, r1 + 8008f82: b29b uxth r3, r3 + 8008f84: 1ad3 subs r3, r2, r3 + 8008f86: b29a uxth r2, r3 + 8008f88: 6afb ldr r3, [r7, #44] ; 0x2c + 8008f8a: 811a strh r2, [r3, #8] + pbuf_realloc(next->p, next->len); + 8008f8c: 6afb ldr r3, [r7, #44] ; 0x2c + 8008f8e: 685a ldr r2, [r3, #4] + 8008f90: 6afb ldr r3, [r7, #44] ; 0x2c + 8008f92: 891b ldrh r3, [r3, #8] + 8008f94: 0019 movs r1, r3 + 8008f96: 0010 movs r0, r2 + 8008f98: f7fc fa8b bl 80054b2 + } + /* check if the remote side overruns our receive window */ + if ((u32_t)tcplen + seqno > pcb->rcv_nxt + (u32_t)pcb->rcv_wnd) { + 8008f9c: 4b64 ldr r3, [pc, #400] ; (8009130 ) + 8008f9e: 881b ldrh r3, [r3, #0] + 8008fa0: 001a movs r2, r3 + 8008fa2: 4b61 ldr r3, [pc, #388] ; (8009128 ) + 8008fa4: 681b ldr r3, [r3, #0] + 8008fa6: 18d2 adds r2, r2, r3 + 8008fa8: 687b ldr r3, [r7, #4] + 8008faa: 6a9b ldr r3, [r3, #40] ; 0x28 + 8008fac: 6879 ldr r1, [r7, #4] + 8008fae: 8d89 ldrh r1, [r1, #44] ; 0x2c + 8008fb0: 185b adds r3, r3, r1 + 8008fb2: 429a cmp r2, r3 + 8008fb4: d800 bhi.n 8008fb8 + 8008fb6: e091 b.n 80090dc + LWIP_DEBUGF(TCP_INPUT_DEBUG, + ("tcp_receive: other end overran receive window" + "seqno %"U32_F" len %"U16_F" right edge %"U32_F"\n", + seqno, tcplen, pcb->rcv_nxt + pcb->rcv_wnd)); + if (TCPH_FLAGS(next->next->tcphdr) & TCP_FIN) { + 8008fb8: 6afb ldr r3, [r7, #44] ; 0x2c + 8008fba: 681b ldr r3, [r3, #0] + 8008fbc: 68db ldr r3, [r3, #12] + 8008fbe: 7b1a ldrb r2, [r3, #12] + 8008fc0: 7b5b ldrb r3, [r3, #13] + 8008fc2: 021b lsls r3, r3, #8 + 8008fc4: 4313 orrs r3, r2 + 8008fc6: b29b uxth r3, r3 + 8008fc8: 0018 movs r0, r3 + 8008fca: f7fb fb39 bl 8004640 + 8008fce: 0003 movs r3, r0 + 8008fd0: 001a movs r2, r3 + 8008fd2: 2301 movs r3, #1 + 8008fd4: 4013 ands r3, r2 + 8008fd6: d039 beq.n 800904c + /* Must remove the FIN from the header as we're trimming + * that byte of sequence-space from the packet */ + TCPH_FLAGS_SET(next->next->tcphdr, TCPH_FLAGS(next->next->tcphdr) &~ TCP_FIN); + 8008fd8: 6afb ldr r3, [r7, #44] ; 0x2c + 8008fda: 681b ldr r3, [r3, #0] + 8008fdc: 68db ldr r3, [r3, #12] + 8008fde: 7b1a ldrb r2, [r3, #12] + 8008fe0: 7b5b ldrb r3, [r3, #13] + 8008fe2: 021b lsls r3, r3, #8 + 8008fe4: 4313 orrs r3, r2 + 8008fe6: b29b uxth r3, r3 + 8008fe8: b21b sxth r3, r3 + 8008fea: 4a52 ldr r2, [pc, #328] ; (8009134 ) + 8008fec: 4013 ands r3, r2 + 8008fee: b21c sxth r4, r3 + 8008ff0: 6afb ldr r3, [r7, #44] ; 0x2c + 8008ff2: 681b ldr r3, [r3, #0] + 8008ff4: 68db ldr r3, [r3, #12] + 8008ff6: 7b1a ldrb r2, [r3, #12] + 8008ff8: 7b5b ldrb r3, [r3, #13] + 8008ffa: 021b lsls r3, r3, #8 + 8008ffc: 4313 orrs r3, r2 + 8008ffe: b29b uxth r3, r3 + 8009000: 0018 movs r0, r3 + 8009002: f7fb fb1d bl 8004640 + 8009006: 0003 movs r3, r0 + 8009008: 001a movs r2, r3 + 800900a: 233e movs r3, #62 ; 0x3e + 800900c: 4013 ands r3, r2 + 800900e: b29b uxth r3, r3 + 8009010: 0018 movs r0, r3 + 8009012: f7fb faff bl 8004614 + 8009016: 0003 movs r3, r0 + 8009018: b21b sxth r3, r3 + 800901a: 4323 orrs r3, r4 + 800901c: b21a sxth r2, r3 + 800901e: 6afb ldr r3, [r7, #44] ; 0x2c + 8009020: 681b ldr r3, [r3, #0] + 8009022: 68db ldr r3, [r3, #12] + 8009024: b292 uxth r2, r2 + 8009026: 21ff movs r1, #255 ; 0xff + 8009028: 4011 ands r1, r2 + 800902a: 000c movs r4, r1 + 800902c: 7b19 ldrb r1, [r3, #12] + 800902e: 2000 movs r0, #0 + 8009030: 4001 ands r1, r0 + 8009032: 1c08 adds r0, r1, #0 + 8009034: 1c21 adds r1, r4, #0 + 8009036: 4301 orrs r1, r0 + 8009038: 7319 strb r1, [r3, #12] + 800903a: 0a12 lsrs r2, r2, #8 + 800903c: b290 uxth r0, r2 + 800903e: 7b5a ldrb r2, [r3, #13] + 8009040: 2100 movs r1, #0 + 8009042: 400a ands r2, r1 + 8009044: 1c11 adds r1, r2, #0 + 8009046: 1c02 adds r2, r0, #0 + 8009048: 430a orrs r2, r1 + 800904a: 735a strb r2, [r3, #13] + } + /* Adjust length of segment to fit in the window. */ + next->next->len = pcb->rcv_nxt + pcb->rcv_wnd - seqno; + 800904c: 687b ldr r3, [r7, #4] + 800904e: 6a9b ldr r3, [r3, #40] ; 0x28 + 8009050: b29a uxth r2, r3 + 8009052: 687b ldr r3, [r7, #4] + 8009054: 8d9b ldrh r3, [r3, #44] ; 0x2c + 8009056: 18d3 adds r3, r2, r3 + 8009058: b299 uxth r1, r3 + 800905a: 4b33 ldr r3, [pc, #204] ; (8009128 ) + 800905c: 681b ldr r3, [r3, #0] + 800905e: b29a uxth r2, r3 + 8009060: 6afb ldr r3, [r7, #44] ; 0x2c + 8009062: 681b ldr r3, [r3, #0] + 8009064: 1a8a subs r2, r1, r2 + 8009066: b292 uxth r2, r2 + 8009068: 811a strh r2, [r3, #8] + pbuf_realloc(next->next->p, next->next->len); + 800906a: 6afb ldr r3, [r7, #44] ; 0x2c + 800906c: 681b ldr r3, [r3, #0] + 800906e: 685a ldr r2, [r3, #4] + 8009070: 6afb ldr r3, [r7, #44] ; 0x2c + 8009072: 681b ldr r3, [r3, #0] + 8009074: 891b ldrh r3, [r3, #8] + 8009076: 0019 movs r1, r3 + 8009078: 0010 movs r0, r2 + 800907a: f7fc fa1a bl 80054b2 + tcplen = TCP_TCPLEN(next->next); + 800907e: 6afb ldr r3, [r7, #44] ; 0x2c + 8009080: 681b ldr r3, [r3, #0] + 8009082: 891c ldrh r4, [r3, #8] + 8009084: 6afb ldr r3, [r7, #44] ; 0x2c + 8009086: 681b ldr r3, [r3, #0] + 8009088: 68db ldr r3, [r3, #12] + 800908a: 7b1a ldrb r2, [r3, #12] + 800908c: 7b5b ldrb r3, [r3, #13] + 800908e: 021b lsls r3, r3, #8 + 8009090: 4313 orrs r3, r2 + 8009092: b29b uxth r3, r3 + 8009094: 0018 movs r0, r3 + 8009096: f7fb fad3 bl 8004640 + 800909a: 0003 movs r3, r0 + 800909c: 001a movs r2, r3 + 800909e: 2303 movs r3, #3 + 80090a0: 4013 ands r3, r2 + 80090a2: 1e5a subs r2, r3, #1 + 80090a4: 4193 sbcs r3, r2 + 80090a6: b2db uxtb r3, r3 + 80090a8: b29b uxth r3, r3 + 80090aa: 18e3 adds r3, r4, r3 + 80090ac: b29a uxth r2, r3 + 80090ae: 4b20 ldr r3, [pc, #128] ; (8009130 ) + 80090b0: 801a strh r2, [r3, #0] + LWIP_ASSERT("tcp_receive: segment not trimmed correctly to rcv_wnd\n", + (seqno + tcplen) == (pcb->rcv_nxt + pcb->rcv_wnd)); + } + } + break; + 80090b2: e013 b.n 80090dc + } + } + prev = next; + 80090b4: 6afb ldr r3, [r7, #44] ; 0x2c + 80090b6: 62bb str r3, [r7, #40] ; 0x28 + for(next = pcb->ooseq; next != NULL; next = next->next) { + 80090b8: 6afb ldr r3, [r7, #44] ; 0x2c + 80090ba: 681b ldr r3, [r3, #0] + 80090bc: 62fb str r3, [r7, #44] ; 0x2c + 80090be: 6afb ldr r3, [r7, #44] ; 0x2c + 80090c0: 2b00 cmp r3, #0 + 80090c2: d000 beq.n 80090c6 + 80090c4: e63a b.n 8008d3c + if (pcb->rcv_nxt == seqno) { + 80090c6: e010 b.n 80090ea + break; + 80090c8: 46c0 nop ; (mov r8, r8) + 80090ca: e00e b.n 80090ea + break; + 80090cc: 46c0 nop ; (mov r8, r8) + 80090ce: e00c b.n 80090ea + break; + 80090d0: 46c0 nop ; (mov r8, r8) + 80090d2: e00a b.n 80090ea + break; + 80090d4: 46c0 nop ; (mov r8, r8) + 80090d6: e008 b.n 80090ea + break; + 80090d8: 46c0 nop ; (mov r8, r8) + 80090da: e006 b.n 80090ea + break; + 80090dc: 46c0 nop ; (mov r8, r8) + if (pcb->rcv_nxt == seqno) { + 80090de: e004 b.n 80090ea +#endif /* TCP_OOSEQ_MAX_BYTES || TCP_OOSEQ_MAX_PBUFS */ +#endif /* TCP_QUEUE_OOSEQ */ + } + } else { + /* The incoming segment is not withing the window. */ + tcp_send_empty_ack(pcb); + 80090e0: 687b ldr r3, [r7, #4] + 80090e2: 0018 movs r0, r3 + 80090e4: f000 fc34 bl 8009950 + if (TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt, + 80090e8: e019 b.n 800911e + 80090ea: e018 b.n 800911e + } else { + /* Segments with length 0 is taken care of here. Segments that + fall out of the window are ACKed. */ + /*if (TCP_SEQ_GT(pcb->rcv_nxt, seqno) || + TCP_SEQ_GEQ(seqno, pcb->rcv_nxt + pcb->rcv_wnd)) {*/ + if(!TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt, pcb->rcv_nxt + pcb->rcv_wnd-1)){ + 80090ec: 4b0e ldr r3, [pc, #56] ; (8009128 ) + 80090ee: 681a ldr r2, [r3, #0] + 80090f0: 687b ldr r3, [r7, #4] + 80090f2: 6a9b ldr r3, [r3, #40] ; 0x28 + 80090f4: 1ad3 subs r3, r2, r3 + 80090f6: d40a bmi.n 800910e + 80090f8: 4b0b ldr r3, [pc, #44] ; (8009128 ) + 80090fa: 681a ldr r2, [r3, #0] + 80090fc: 687b ldr r3, [r7, #4] + 80090fe: 6a9b ldr r3, [r3, #40] ; 0x28 + 8009100: 6879 ldr r1, [r7, #4] + 8009102: 8d89 ldrh r1, [r1, #44] ; 0x2c + 8009104: 185b adds r3, r3, r1 + 8009106: 1ad3 subs r3, r2, r3 + 8009108: 3301 adds r3, #1 + 800910a: 2b00 cmp r3, #0 + 800910c: dd07 ble.n 800911e + tcp_ack_now(pcb); + 800910e: 687b ldr r3, [r7, #4] + 8009110: 7f9b ldrb r3, [r3, #30] + 8009112: 2202 movs r2, #2 + 8009114: 4313 orrs r3, r2 + 8009116: b2da uxtb r2, r3 + 8009118: 687b ldr r3, [r7, #4] + 800911a: 779a strb r2, [r3, #30] + } + } +} + 800911c: e7ff b.n 800911e + 800911e: 46c0 nop ; (mov r8, r8) + 8009120: 46bd mov sp, r7 + 8009122: b00d add sp, #52 ; 0x34 + 8009124: bdf0 pop {r4, r5, r6, r7, pc} + 8009126: 46c0 nop ; (mov r8, r8) + 8009128: 20002294 .word 0x20002294 + 800912c: 2000227c .word 0x2000227c + 8009130: 2000229e .word 0x2000229e + 8009134: ffffc0ff .word 0xffffc0ff + +08009138 : + * + * @param pcb the tcp_pcb for which a segment arrived + */ +static void +tcp_parseopt(struct tcp_pcb *pcb) +{ + 8009138: b580 push {r7, lr} + 800913a: b086 sub sp, #24 + 800913c: af00 add r7, sp, #0 + 800913e: 6078 str r0, [r7, #4] + u8_t *opts, opt; +#if LWIP_TCP_TIMESTAMPS + u32_t tsval; +#endif + + opts = (u8_t *)tcphdr + TCP_HLEN; + 8009140: 4b56 ldr r3, [pc, #344] ; (800929c ) + 8009142: 681b ldr r3, [r3, #0] + 8009144: 3314 adds r3, #20 + 8009146: 613b str r3, [r7, #16] + + /* Parse the TCP MSS option, if present. */ + if(TCPH_HDRLEN(tcphdr) > 0x5) { + 8009148: 4b54 ldr r3, [pc, #336] ; (800929c ) + 800914a: 681b ldr r3, [r3, #0] + 800914c: 7b1a ldrb r2, [r3, #12] + 800914e: 7b5b ldrb r3, [r3, #13] + 8009150: 021b lsls r3, r3, #8 + 8009152: 4313 orrs r3, r2 + 8009154: b29b uxth r3, r3 + 8009156: 0018 movs r0, r3 + 8009158: f7fb fa72 bl 8004640 + 800915c: 0003 movs r3, r0 + 800915e: 0b1b lsrs r3, r3, #12 + 8009160: b29b uxth r3, r3 + 8009162: 2b05 cmp r3, #5 + 8009164: d800 bhi.n 8009168 + 8009166: e095 b.n 8009294 + max_c = (TCPH_HDRLEN(tcphdr) - 5) << 2; + 8009168: 4b4c ldr r3, [pc, #304] ; (800929c ) + 800916a: 681b ldr r3, [r3, #0] + 800916c: 7b1a ldrb r2, [r3, #12] + 800916e: 7b5b ldrb r3, [r3, #13] + 8009170: 021b lsls r3, r3, #8 + 8009172: 4313 orrs r3, r2 + 8009174: b29b uxth r3, r3 + 8009176: 0018 movs r0, r3 + 8009178: f7fb fa62 bl 8004640 + 800917c: 0003 movs r3, r0 + 800917e: 0b1b lsrs r3, r3, #12 + 8009180: b29b uxth r3, r3 + 8009182: 3b05 subs r3, #5 + 8009184: b29a uxth r2, r3 + 8009186: 230e movs r3, #14 + 8009188: 18fb adds r3, r7, r3 + 800918a: 0092 lsls r2, r2, #2 + 800918c: 801a strh r2, [r3, #0] + for (c = 0; c < max_c; ) { + 800918e: 2316 movs r3, #22 + 8009190: 18fb adds r3, r7, r3 + 8009192: 2200 movs r2, #0 + 8009194: 801a strh r2, [r3, #0] + 8009196: e06e b.n 8009276 + opt = opts[c]; + 8009198: 2316 movs r3, #22 + 800919a: 18fb adds r3, r7, r3 + 800919c: 881b ldrh r3, [r3, #0] + 800919e: 693a ldr r2, [r7, #16] + 80091a0: 18d2 adds r2, r2, r3 + 80091a2: 210d movs r1, #13 + 80091a4: 187b adds r3, r7, r1 + 80091a6: 7812 ldrb r2, [r2, #0] + 80091a8: 701a strb r2, [r3, #0] + switch (opt) { + 80091aa: 187b adds r3, r7, r1 + 80091ac: 781b ldrb r3, [r3, #0] + 80091ae: 2b01 cmp r3, #1 + 80091b0: d005 beq.n 80091be + 80091b2: 2b02 cmp r3, #2 + 80091b4: d00a beq.n 80091cc + 80091b6: 2b00 cmp r3, #0 + 80091b8: d100 bne.n 80091bc + 80091ba: e066 b.n 800928a + 80091bc: e045 b.n 800924a + /* End of options. */ + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: EOL\n")); + return; + case 0x01: + /* NOP option. */ + ++c; + 80091be: 2216 movs r2, #22 + 80091c0: 18bb adds r3, r7, r2 + 80091c2: 18ba adds r2, r7, r2 + 80091c4: 8812 ldrh r2, [r2, #0] + 80091c6: 3201 adds r2, #1 + 80091c8: 801a strh r2, [r3, #0] + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: NOP\n")); + break; + 80091ca: e054 b.n 8009276 + case 0x02: + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: MSS\n")); + if (opts[c + 1] != 0x04 || c + 0x04 > max_c) { + 80091cc: 2316 movs r3, #22 + 80091ce: 18fb adds r3, r7, r3 + 80091d0: 881b ldrh r3, [r3, #0] + 80091d2: 3301 adds r3, #1 + 80091d4: 693a ldr r2, [r7, #16] + 80091d6: 18d3 adds r3, r2, r3 + 80091d8: 781b ldrb r3, [r3, #0] + 80091da: 2b04 cmp r3, #4 + 80091dc: d157 bne.n 800928e + 80091de: 2316 movs r3, #22 + 80091e0: 18fb adds r3, r7, r3 + 80091e2: 881b ldrh r3, [r3, #0] + 80091e4: 1d1a adds r2, r3, #4 + 80091e6: 230e movs r3, #14 + 80091e8: 18fb adds r3, r7, r3 + 80091ea: 881b ldrh r3, [r3, #0] + 80091ec: 429a cmp r2, r3 + 80091ee: dc4e bgt.n 800928e + /* Bad length */ + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: bad length\n")); + return; + } + /* An MSS option with the right option length. */ + mss = (opts[c + 2] << 8) | opts[c + 3]; + 80091f0: 2116 movs r1, #22 + 80091f2: 187b adds r3, r7, r1 + 80091f4: 881b ldrh r3, [r3, #0] + 80091f6: 3302 adds r3, #2 + 80091f8: 693a ldr r2, [r7, #16] + 80091fa: 18d3 adds r3, r2, r3 + 80091fc: 781b ldrb r3, [r3, #0] + 80091fe: 021b lsls r3, r3, #8 + 8009200: b21a sxth r2, r3 + 8009202: 187b adds r3, r7, r1 + 8009204: 881b ldrh r3, [r3, #0] + 8009206: 3303 adds r3, #3 + 8009208: 6939 ldr r1, [r7, #16] + 800920a: 18cb adds r3, r1, r3 + 800920c: 781b ldrb r3, [r3, #0] + 800920e: b21b sxth r3, r3 + 8009210: 4313 orrs r3, r2 + 8009212: b21a sxth r2, r3 + 8009214: 210a movs r1, #10 + 8009216: 187b adds r3, r7, r1 + 8009218: 801a strh r2, [r3, #0] + /* Limit the mss to the configured TCP_MSS and prevent division by zero */ + pcb->mss = ((mss > TCP_MSS) || (mss == 0)) ? TCP_MSS : mss; + 800921a: 187b adds r3, r7, r1 + 800921c: 881b ldrh r3, [r3, #0] + 800921e: 4a20 ldr r2, [pc, #128] ; (80092a0 ) + 8009220: 4293 cmp r3, r2 + 8009222: d808 bhi.n 8009236 + 8009224: 230a movs r3, #10 + 8009226: 18fb adds r3, r7, r3 + 8009228: 881b ldrh r3, [r3, #0] + 800922a: 2b00 cmp r3, #0 + 800922c: d003 beq.n 8009236 + 800922e: 230a movs r3, #10 + 8009230: 18fb adds r3, r7, r3 + 8009232: 881a ldrh r2, [r3, #0] + 8009234: e000 b.n 8009238 + 8009236: 4a1a ldr r2, [pc, #104] ; (80092a0 ) + 8009238: 687b ldr r3, [r7, #4] + 800923a: 86da strh r2, [r3, #54] ; 0x36 + /* Advance to next option */ + c += 0x04; + 800923c: 2216 movs r2, #22 + 800923e: 18bb adds r3, r7, r2 + 8009240: 18ba adds r2, r7, r2 + 8009242: 8812 ldrh r2, [r2, #0] + 8009244: 3204 adds r2, #4 + 8009246: 801a strh r2, [r3, #0] + break; + 8009248: e015 b.n 8009276 + c += 0x0A; + break; +#endif + default: + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: other\n")); + if (opts[c + 1] == 0) { + 800924a: 2316 movs r3, #22 + 800924c: 18fb adds r3, r7, r3 + 800924e: 881b ldrh r3, [r3, #0] + 8009250: 3301 adds r3, #1 + 8009252: 693a ldr r2, [r7, #16] + 8009254: 18d3 adds r3, r2, r3 + 8009256: 781b ldrb r3, [r3, #0] + 8009258: 2b00 cmp r3, #0 + 800925a: d01a beq.n 8009292 + and we don't process them further. */ + return; + } + /* All other options have a length field, so that we easily + can skip past them. */ + c += opts[c + 1]; + 800925c: 2016 movs r0, #22 + 800925e: 183b adds r3, r7, r0 + 8009260: 881b ldrh r3, [r3, #0] + 8009262: 3301 adds r3, #1 + 8009264: 693a ldr r2, [r7, #16] + 8009266: 18d3 adds r3, r2, r3 + 8009268: 781b ldrb r3, [r3, #0] + 800926a: b299 uxth r1, r3 + 800926c: 183b adds r3, r7, r0 + 800926e: 183a adds r2, r7, r0 + 8009270: 8812 ldrh r2, [r2, #0] + 8009272: 188a adds r2, r1, r2 + 8009274: 801a strh r2, [r3, #0] + for (c = 0; c < max_c; ) { + 8009276: 2316 movs r3, #22 + 8009278: 18fa adds r2, r7, r3 + 800927a: 230e movs r3, #14 + 800927c: 18fb adds r3, r7, r3 + 800927e: 8812 ldrh r2, [r2, #0] + 8009280: 881b ldrh r3, [r3, #0] + 8009282: 429a cmp r2, r3 + 8009284: d200 bcs.n 8009288 + 8009286: e787 b.n 8009198 + 8009288: e004 b.n 8009294 + return; + 800928a: 46c0 nop ; (mov r8, r8) + 800928c: e002 b.n 8009294 + return; + 800928e: 46c0 nop ; (mov r8, r8) + 8009290: e000 b.n 8009294 + return; + 8009292: 46c0 nop ; (mov r8, r8) + } + } + } +} + 8009294: 46bd mov sp, r7 + 8009296: b006 add sp, #24 + 8009298: bd80 pop {r7, pc} + 800929a: 46c0 nop ; (mov r8, r8) + 800929c: 2000228c .word 0x2000228c + 80092a0: 000005b4 .word 0x000005b4 + +080092a4 : + * @return pbuf with p->payload being the tcp_hdr + */ +static struct pbuf * +tcp_output_alloc_header(struct tcp_pcb *pcb, u16_t optlen, u16_t datalen, + u32_t seqno_be /* already in network byte order */) +{ + 80092a4: b590 push {r4, r7, lr} + 80092a6: b087 sub sp, #28 + 80092a8: af00 add r7, sp, #0 + 80092aa: 60f8 str r0, [r7, #12] + 80092ac: 0008 movs r0, r1 + 80092ae: 0011 movs r1, r2 + 80092b0: 607b str r3, [r7, #4] + 80092b2: 240a movs r4, #10 + 80092b4: 193b adds r3, r7, r4 + 80092b6: 1c02 adds r2, r0, #0 + 80092b8: 801a strh r2, [r3, #0] + 80092ba: 2008 movs r0, #8 + 80092bc: 183b adds r3, r7, r0 + 80092be: 1c0a adds r2, r1, #0 + 80092c0: 801a strh r2, [r3, #0] + struct tcp_hdr *tcphdr; + struct pbuf *p = pbuf_alloc(PBUF_IP, TCP_HLEN + optlen + datalen, PBUF_RAM); + 80092c2: 193a adds r2, r7, r4 + 80092c4: 183b adds r3, r7, r0 + 80092c6: 8812 ldrh r2, [r2, #0] + 80092c8: 881b ldrh r3, [r3, #0] + 80092ca: 18d3 adds r3, r2, r3 + 80092cc: b29b uxth r3, r3 + 80092ce: 3314 adds r3, #20 + 80092d0: b29b uxth r3, r3 + 80092d2: 2200 movs r2, #0 + 80092d4: 0019 movs r1, r3 + 80092d6: 2001 movs r0, #1 + 80092d8: f7fb ff58 bl 800518c + 80092dc: 0003 movs r3, r0 + 80092de: 617b str r3, [r7, #20] + if (p != NULL) { + 80092e0: 697b ldr r3, [r7, #20] + 80092e2: 2b00 cmp r3, #0 + 80092e4: d100 bne.n 80092e8 + 80092e6: e0e5 b.n 80094b4 + LWIP_ASSERT("check that first pbuf can hold struct tcp_hdr", + (p->len >= TCP_HLEN + optlen)); + tcphdr = (struct tcp_hdr *)p->payload; + 80092e8: 697b ldr r3, [r7, #20] + 80092ea: 685b ldr r3, [r3, #4] + 80092ec: 613b str r3, [r7, #16] + tcphdr->src = htons(pcb->local_port); + 80092ee: 68fb ldr r3, [r7, #12] + 80092f0: 8b5b ldrh r3, [r3, #26] + 80092f2: 0018 movs r0, r3 + 80092f4: f7fb f98e bl 8004614 + 80092f8: 0003 movs r3, r0 + 80092fa: 001a movs r2, r3 + 80092fc: 693b ldr r3, [r7, #16] + 80092fe: 21ff movs r1, #255 ; 0xff + 8009300: 4011 ands r1, r2 + 8009302: 000c movs r4, r1 + 8009304: 7819 ldrb r1, [r3, #0] + 8009306: 2000 movs r0, #0 + 8009308: 4001 ands r1, r0 + 800930a: 1c08 adds r0, r1, #0 + 800930c: 1c21 adds r1, r4, #0 + 800930e: 4301 orrs r1, r0 + 8009310: 7019 strb r1, [r3, #0] + 8009312: 0a12 lsrs r2, r2, #8 + 8009314: b290 uxth r0, r2 + 8009316: 785a ldrb r2, [r3, #1] + 8009318: 2100 movs r1, #0 + 800931a: 400a ands r2, r1 + 800931c: 1c11 adds r1, r2, #0 + 800931e: 1c02 adds r2, r0, #0 + 8009320: 430a orrs r2, r1 + 8009322: 705a strb r2, [r3, #1] + tcphdr->dest = htons(pcb->remote_port); + 8009324: 68fb ldr r3, [r7, #12] + 8009326: 8b9b ldrh r3, [r3, #28] + 8009328: 0018 movs r0, r3 + 800932a: f7fb f973 bl 8004614 + 800932e: 0003 movs r3, r0 + 8009330: 001a movs r2, r3 + 8009332: 693b ldr r3, [r7, #16] + 8009334: 21ff movs r1, #255 ; 0xff + 8009336: 4011 ands r1, r2 + 8009338: 000c movs r4, r1 + 800933a: 7899 ldrb r1, [r3, #2] + 800933c: 2000 movs r0, #0 + 800933e: 4001 ands r1, r0 + 8009340: 1c08 adds r0, r1, #0 + 8009342: 1c21 adds r1, r4, #0 + 8009344: 4301 orrs r1, r0 + 8009346: 7099 strb r1, [r3, #2] + 8009348: 0a12 lsrs r2, r2, #8 + 800934a: b290 uxth r0, r2 + 800934c: 78da ldrb r2, [r3, #3] + 800934e: 2100 movs r1, #0 + 8009350: 400a ands r2, r1 + 8009352: 1c11 adds r1, r2, #0 + 8009354: 1c02 adds r2, r0, #0 + 8009356: 430a orrs r2, r1 + 8009358: 70da strb r2, [r3, #3] + tcphdr->seqno = seqno_be; + 800935a: 693b ldr r3, [r7, #16] + 800935c: 1d3a adds r2, r7, #4 + 800935e: 7810 ldrb r0, [r2, #0] + 8009360: 791a ldrb r2, [r3, #4] + 8009362: 2100 movs r1, #0 + 8009364: 400a ands r2, r1 + 8009366: 1c11 adds r1, r2, #0 + 8009368: 1c02 adds r2, r0, #0 + 800936a: 430a orrs r2, r1 + 800936c: 711a strb r2, [r3, #4] + 800936e: 1d7a adds r2, r7, #5 + 8009370: 7810 ldrb r0, [r2, #0] + 8009372: 795a ldrb r2, [r3, #5] + 8009374: 2100 movs r1, #0 + 8009376: 400a ands r2, r1 + 8009378: 1c11 adds r1, r2, #0 + 800937a: 1c02 adds r2, r0, #0 + 800937c: 430a orrs r2, r1 + 800937e: 715a strb r2, [r3, #5] + 8009380: 1dba adds r2, r7, #6 + 8009382: 7810 ldrb r0, [r2, #0] + 8009384: 799a ldrb r2, [r3, #6] + 8009386: 2100 movs r1, #0 + 8009388: 400a ands r2, r1 + 800938a: 1c11 adds r1, r2, #0 + 800938c: 1c02 adds r2, r0, #0 + 800938e: 430a orrs r2, r1 + 8009390: 719a strb r2, [r3, #6] + 8009392: 1dfa adds r2, r7, #7 + 8009394: 7810 ldrb r0, [r2, #0] + 8009396: 79da ldrb r2, [r3, #7] + 8009398: 2100 movs r1, #0 + 800939a: 400a ands r2, r1 + 800939c: 1c11 adds r1, r2, #0 + 800939e: 1c02 adds r2, r0, #0 + 80093a0: 430a orrs r2, r1 + 80093a2: 71da strb r2, [r3, #7] + tcphdr->ackno = htonl(pcb->rcv_nxt); + 80093a4: 68fb ldr r3, [r7, #12] + 80093a6: 6a9b ldr r3, [r3, #40] ; 0x28 + 80093a8: 0018 movs r0, r3 + 80093aa: f7fb f959 bl 8004660 + 80093ae: 0002 movs r2, r0 + 80093b0: 693b ldr r3, [r7, #16] + 80093b2: 21ff movs r1, #255 ; 0xff + 80093b4: 4011 ands r1, r2 + 80093b6: 000c movs r4, r1 + 80093b8: 7a19 ldrb r1, [r3, #8] + 80093ba: 2000 movs r0, #0 + 80093bc: 4001 ands r1, r0 + 80093be: 1c08 adds r0, r1, #0 + 80093c0: 1c21 adds r1, r4, #0 + 80093c2: 4301 orrs r1, r0 + 80093c4: 7219 strb r1, [r3, #8] + 80093c6: 0a11 lsrs r1, r2, #8 + 80093c8: 20ff movs r0, #255 ; 0xff + 80093ca: 4001 ands r1, r0 + 80093cc: 000c movs r4, r1 + 80093ce: 7a59 ldrb r1, [r3, #9] + 80093d0: 2000 movs r0, #0 + 80093d2: 4001 ands r1, r0 + 80093d4: 1c08 adds r0, r1, #0 + 80093d6: 1c21 adds r1, r4, #0 + 80093d8: 4301 orrs r1, r0 + 80093da: 7259 strb r1, [r3, #9] + 80093dc: 0c11 lsrs r1, r2, #16 + 80093de: 20ff movs r0, #255 ; 0xff + 80093e0: 4001 ands r1, r0 + 80093e2: 000c movs r4, r1 + 80093e4: 7a99 ldrb r1, [r3, #10] + 80093e6: 2000 movs r0, #0 + 80093e8: 4001 ands r1, r0 + 80093ea: 1c08 adds r0, r1, #0 + 80093ec: 1c21 adds r1, r4, #0 + 80093ee: 4301 orrs r1, r0 + 80093f0: 7299 strb r1, [r3, #10] + 80093f2: 0e10 lsrs r0, r2, #24 + 80093f4: 7ada ldrb r2, [r3, #11] + 80093f6: 2100 movs r1, #0 + 80093f8: 400a ands r2, r1 + 80093fa: 1c11 adds r1, r2, #0 + 80093fc: 1c02 adds r2, r0, #0 + 80093fe: 430a orrs r2, r1 + 8009400: 72da strb r2, [r3, #11] + TCPH_HDRLEN_FLAGS_SET(tcphdr, (5 + optlen / 4), TCP_ACK); + 8009402: 230a movs r3, #10 + 8009404: 18fb adds r3, r7, r3 + 8009406: 881b ldrh r3, [r3, #0] + 8009408: 089b lsrs r3, r3, #2 + 800940a: b29b uxth r3, r3 + 800940c: 3305 adds r3, #5 + 800940e: b29b uxth r3, r3 + 8009410: 031b lsls r3, r3, #12 + 8009412: b29b uxth r3, r3 + 8009414: 2210 movs r2, #16 + 8009416: 4313 orrs r3, r2 + 8009418: b29b uxth r3, r3 + 800941a: 0018 movs r0, r3 + 800941c: f7fb f8fa bl 8004614 + 8009420: 0003 movs r3, r0 + 8009422: 001a movs r2, r3 + 8009424: 693b ldr r3, [r7, #16] + 8009426: 21ff movs r1, #255 ; 0xff + 8009428: 4011 ands r1, r2 + 800942a: 000c movs r4, r1 + 800942c: 7b19 ldrb r1, [r3, #12] + 800942e: 2000 movs r0, #0 + 8009430: 4001 ands r1, r0 + 8009432: 1c08 adds r0, r1, #0 + 8009434: 1c21 adds r1, r4, #0 + 8009436: 4301 orrs r1, r0 + 8009438: 7319 strb r1, [r3, #12] + 800943a: 0a12 lsrs r2, r2, #8 + 800943c: b290 uxth r0, r2 + 800943e: 7b5a ldrb r2, [r3, #13] + 8009440: 2100 movs r1, #0 + 8009442: 400a ands r2, r1 + 8009444: 1c11 adds r1, r2, #0 + 8009446: 1c02 adds r2, r0, #0 + 8009448: 430a orrs r2, r1 + 800944a: 735a strb r2, [r3, #13] + tcphdr->wnd = htons(pcb->rcv_ann_wnd); + 800944c: 68fb ldr r3, [r7, #12] + 800944e: 8ddb ldrh r3, [r3, #46] ; 0x2e + 8009450: 0018 movs r0, r3 + 8009452: f7fb f8df bl 8004614 + 8009456: 0003 movs r3, r0 + 8009458: 001a movs r2, r3 + 800945a: 693b ldr r3, [r7, #16] + 800945c: 21ff movs r1, #255 ; 0xff + 800945e: 4011 ands r1, r2 + 8009460: 000c movs r4, r1 + 8009462: 7b99 ldrb r1, [r3, #14] + 8009464: 2000 movs r0, #0 + 8009466: 4001 ands r1, r0 + 8009468: 1c08 adds r0, r1, #0 + 800946a: 1c21 adds r1, r4, #0 + 800946c: 4301 orrs r1, r0 + 800946e: 7399 strb r1, [r3, #14] + 8009470: 0a12 lsrs r2, r2, #8 + 8009472: b290 uxth r0, r2 + 8009474: 7bda ldrb r2, [r3, #15] + 8009476: 2100 movs r1, #0 + 8009478: 400a ands r2, r1 + 800947a: 1c11 adds r1, r2, #0 + 800947c: 1c02 adds r2, r0, #0 + 800947e: 430a orrs r2, r1 + 8009480: 73da strb r2, [r3, #15] + tcphdr->chksum = 0; + 8009482: 693b ldr r3, [r7, #16] + 8009484: 7c1a ldrb r2, [r3, #16] + 8009486: 2100 movs r1, #0 + 8009488: 400a ands r2, r1 + 800948a: 741a strb r2, [r3, #16] + 800948c: 7c5a ldrb r2, [r3, #17] + 800948e: 2100 movs r1, #0 + 8009490: 400a ands r2, r1 + 8009492: 745a strb r2, [r3, #17] + tcphdr->urgp = 0; + 8009494: 693b ldr r3, [r7, #16] + 8009496: 7c9a ldrb r2, [r3, #18] + 8009498: 2100 movs r1, #0 + 800949a: 400a ands r2, r1 + 800949c: 749a strb r2, [r3, #18] + 800949e: 7cda ldrb r2, [r3, #19] + 80094a0: 2100 movs r1, #0 + 80094a2: 400a ands r2, r1 + 80094a4: 74da strb r2, [r3, #19] + + /* If we're sending a packet, update the announced right window edge */ + pcb->rcv_ann_right_edge = pcb->rcv_nxt + pcb->rcv_ann_wnd; + 80094a6: 68fb ldr r3, [r7, #12] + 80094a8: 6a9b ldr r3, [r3, #40] ; 0x28 + 80094aa: 68fa ldr r2, [r7, #12] + 80094ac: 8dd2 ldrh r2, [r2, #46] ; 0x2e + 80094ae: 189a adds r2, r3, r2 + 80094b0: 68fb ldr r3, [r7, #12] + 80094b2: 631a str r2, [r3, #48] ; 0x30 + } + return p; + 80094b4: 697b ldr r3, [r7, #20] +} + 80094b6: 0018 movs r0, r3 + 80094b8: 46bd mov sp, r7 + 80094ba: b007 add sp, #28 + 80094bc: bd90 pop {r4, r7, pc} + +080094be : + * @param pcb the tcp_pcb over which to send a segment + * @return ERR_OK if sent, another err_t otherwise + */ +err_t +tcp_send_fin(struct tcp_pcb *pcb) +{ + 80094be: b590 push {r4, r7, lr} + 80094c0: b085 sub sp, #20 + 80094c2: af00 add r7, sp, #0 + 80094c4: 6078 str r0, [r7, #4] + /* first, try to add the fin to the last unsent segment */ + if (pcb->unsent != NULL) { + 80094c6: 687b ldr r3, [r7, #4] + 80094c8: 6edb ldr r3, [r3, #108] ; 0x6c + 80094ca: 2b00 cmp r3, #0 + 80094cc: d045 beq.n 800955a + struct tcp_seg *last_unsent; + for (last_unsent = pcb->unsent; last_unsent->next != NULL; + 80094ce: 687b ldr r3, [r7, #4] + 80094d0: 6edb ldr r3, [r3, #108] ; 0x6c + 80094d2: 60fb str r3, [r7, #12] + 80094d4: e002 b.n 80094dc + last_unsent = last_unsent->next); + 80094d6: 68fb ldr r3, [r7, #12] + 80094d8: 681b ldr r3, [r3, #0] + 80094da: 60fb str r3, [r7, #12] + for (last_unsent = pcb->unsent; last_unsent->next != NULL; + 80094dc: 68fb ldr r3, [r7, #12] + 80094de: 681b ldr r3, [r3, #0] + 80094e0: 2b00 cmp r3, #0 + 80094e2: d1f8 bne.n 80094d6 + + if ((TCPH_FLAGS(last_unsent->tcphdr) & (TCP_SYN | TCP_FIN | TCP_RST)) == 0) { + 80094e4: 68fb ldr r3, [r7, #12] + 80094e6: 68db ldr r3, [r3, #12] + 80094e8: 7b1a ldrb r2, [r3, #12] + 80094ea: 7b5b ldrb r3, [r3, #13] + 80094ec: 021b lsls r3, r3, #8 + 80094ee: 4313 orrs r3, r2 + 80094f0: b29b uxth r3, r3 + 80094f2: 0018 movs r0, r3 + 80094f4: f7fb f8a4 bl 8004640 + 80094f8: 0003 movs r3, r0 + 80094fa: 001a movs r2, r3 + 80094fc: 2307 movs r3, #7 + 80094fe: 4013 ands r3, r2 + 8009500: d12b bne.n 800955a + /* no SYN/FIN/RST flag in the header, we can add the FIN flag */ + TCPH_SET_FLAG(last_unsent->tcphdr, TCP_FIN); + 8009502: 68fb ldr r3, [r7, #12] + 8009504: 68db ldr r3, [r3, #12] + 8009506: 7b1a ldrb r2, [r3, #12] + 8009508: 7b5b ldrb r3, [r3, #13] + 800950a: 021b lsls r3, r3, #8 + 800950c: 4313 orrs r3, r2 + 800950e: b29c uxth r4, r3 + 8009510: 2001 movs r0, #1 + 8009512: f7fb f87f bl 8004614 + 8009516: 0003 movs r3, r0 + 8009518: 001a movs r2, r3 + 800951a: 68fb ldr r3, [r7, #12] + 800951c: 68db ldr r3, [r3, #12] + 800951e: 4322 orrs r2, r4 + 8009520: b292 uxth r2, r2 + 8009522: 21ff movs r1, #255 ; 0xff + 8009524: 4011 ands r1, r2 + 8009526: 000c movs r4, r1 + 8009528: 7b19 ldrb r1, [r3, #12] + 800952a: 2000 movs r0, #0 + 800952c: 4001 ands r1, r0 + 800952e: 1c08 adds r0, r1, #0 + 8009530: 1c21 adds r1, r4, #0 + 8009532: 4301 orrs r1, r0 + 8009534: 7319 strb r1, [r3, #12] + 8009536: 0a12 lsrs r2, r2, #8 + 8009538: b290 uxth r0, r2 + 800953a: 7b5a ldrb r2, [r3, #13] + 800953c: 2100 movs r1, #0 + 800953e: 400a ands r2, r1 + 8009540: 1c11 adds r1, r2, #0 + 8009542: 1c02 adds r2, r0, #0 + 8009544: 430a orrs r2, r1 + 8009546: 735a strb r2, [r3, #13] + pcb->flags |= TF_FIN; + 8009548: 687b ldr r3, [r7, #4] + 800954a: 7f9b ldrb r3, [r3, #30] + 800954c: 2220 movs r2, #32 + 800954e: 4313 orrs r3, r2 + 8009550: b2da uxtb r2, r3 + 8009552: 687b ldr r3, [r7, #4] + 8009554: 779a strb r2, [r3, #30] + return ERR_OK; + 8009556: 2300 movs r3, #0 + 8009558: e005 b.n 8009566 + } + } + /* no data, no length, flags, copy=1, no optdata */ + return tcp_enqueue_flags(pcb, TCP_FIN); + 800955a: 687b ldr r3, [r7, #4] + 800955c: 2101 movs r1, #1 + 800955e: 0018 movs r0, r3 + 8009560: f000 f8fc bl 800975c + 8009564: 0003 movs r3, r0 +} + 8009566: 0018 movs r0, r3 + 8009568: 46bd mov sp, r7 + 800956a: b005 add sp, #20 + 800956c: bd90 pop {r4, r7, pc} + ... + +08009570 : + * The TCP header is filled in except ackno and wnd. + * p is freed on failure. + */ +static struct tcp_seg * +tcp_create_segment(struct tcp_pcb *pcb, struct pbuf *p, u8_t flags, u32_t seqno, u8_t optflags) +{ + 8009570: b590 push {r4, r7, lr} + 8009572: b087 sub sp, #28 + 8009574: af00 add r7, sp, #0 + 8009576: 60f8 str r0, [r7, #12] + 8009578: 60b9 str r1, [r7, #8] + 800957a: 603b str r3, [r7, #0] + 800957c: 1dfb adds r3, r7, #7 + 800957e: 701a strb r2, [r3, #0] + struct tcp_seg *seg; + u8_t optlen = LWIP_TCP_OPT_LENGTH(optflags); + 8009580: 2028 movs r0, #40 ; 0x28 + 8009582: 183b adds r3, r7, r0 + 8009584: 781b ldrb r3, [r3, #0] + 8009586: 009b lsls r3, r3, #2 + 8009588: b2db uxtb r3, r3 + 800958a: 2204 movs r2, #4 + 800958c: 4013 ands r3, r2 + 800958e: b2d9 uxtb r1, r3 + 8009590: 183b adds r3, r7, r0 + 8009592: 781b ldrb r3, [r3, #0] + 8009594: 2202 movs r2, #2 + 8009596: 4013 ands r3, r2 + 8009598: d001 beq.n 800959e + 800959a: 230c movs r3, #12 + 800959c: e000 b.n 80095a0 + 800959e: 2300 movs r3, #0 + 80095a0: 2217 movs r2, #23 + 80095a2: 18ba adds r2, r7, r2 + 80095a4: 185b adds r3, r3, r1 + 80095a6: 7013 strb r3, [r2, #0] + + if ((seg = (struct tcp_seg *)memp_malloc(MEMP_TCP_SEG)) == NULL) { + 80095a8: 2004 movs r0, #4 + 80095aa: f7fb fc33 bl 8004e14 + 80095ae: 0003 movs r3, r0 + 80095b0: 613b str r3, [r7, #16] + 80095b2: 693b ldr r3, [r7, #16] + 80095b4: 2b00 cmp r3, #0 + 80095b6: d105 bne.n 80095c4 + LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_create_segment: no memory.\n")); + pbuf_free(p); + 80095b8: 68bb ldr r3, [r7, #8] + 80095ba: 0018 movs r0, r3 + 80095bc: f7fc f872 bl 80056a4 + return NULL; + 80095c0: 2300 movs r3, #0 + 80095c2: e0c5 b.n 8009750 + } + seg->flags = optflags; + 80095c4: 693b ldr r3, [r7, #16] + 80095c6: 2228 movs r2, #40 ; 0x28 + 80095c8: 18ba adds r2, r7, r2 + 80095ca: 7812 ldrb r2, [r2, #0] + 80095cc: 729a strb r2, [r3, #10] + seg->next = NULL; + 80095ce: 693b ldr r3, [r7, #16] + 80095d0: 2200 movs r2, #0 + 80095d2: 601a str r2, [r3, #0] + seg->p = p; + 80095d4: 693b ldr r3, [r7, #16] + 80095d6: 68ba ldr r2, [r7, #8] + 80095d8: 605a str r2, [r3, #4] + seg->len = p->tot_len - optlen; + 80095da: 68bb ldr r3, [r7, #8] + 80095dc: 891a ldrh r2, [r3, #8] + 80095de: 2317 movs r3, #23 + 80095e0: 18fb adds r3, r7, r3 + 80095e2: 781b ldrb r3, [r3, #0] + 80095e4: b29b uxth r3, r3 + 80095e6: 1ad3 subs r3, r2, r3 + 80095e8: b29a uxth r2, r3 + 80095ea: 693b ldr r3, [r7, #16] + 80095ec: 811a strh r2, [r3, #8] + LWIP_ASSERT("invalid optflags passed: TF_SEG_DATA_CHECKSUMMED", + (optflags & TF_SEG_DATA_CHECKSUMMED) == 0); +#endif /* TCP_CHECKSUM_ON_COPY */ + + /* build TCP header */ + if (pbuf_header(p, TCP_HLEN)) { + 80095ee: 68bb ldr r3, [r7, #8] + 80095f0: 2114 movs r1, #20 + 80095f2: 0018 movs r0, r3 + 80095f4: f7fb ffcf bl 8005596 + 80095f8: 1e03 subs r3, r0, #0 + 80095fa: d00d beq.n 8009618 + LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_create_segment: no room for TCP header in pbuf.\n")); + TCP_STATS_INC(tcp.err); + 80095fc: 4b56 ldr r3, [pc, #344] ; (8009758 ) + 80095fe: 22a4 movs r2, #164 ; 0xa4 + 8009600: 5a9b ldrh r3, [r3, r2] + 8009602: 3301 adds r3, #1 + 8009604: b299 uxth r1, r3 + 8009606: 4b54 ldr r3, [pc, #336] ; (8009758 ) + 8009608: 22a4 movs r2, #164 ; 0xa4 + 800960a: 5299 strh r1, [r3, r2] + tcp_seg_free(seg); + 800960c: 693b ldr r3, [r7, #16] + 800960e: 0018 movs r0, r3 + 8009610: f7fd f885 bl 800671e + return NULL; + 8009614: 2300 movs r3, #0 + 8009616: e09b b.n 8009750 + } + seg->tcphdr = (struct tcp_hdr *)seg->p->payload; + 8009618: 693b ldr r3, [r7, #16] + 800961a: 685b ldr r3, [r3, #4] + 800961c: 685a ldr r2, [r3, #4] + 800961e: 693b ldr r3, [r7, #16] + 8009620: 60da str r2, [r3, #12] + seg->tcphdr->src = htons(pcb->local_port); + 8009622: 68fb ldr r3, [r7, #12] + 8009624: 8b5a ldrh r2, [r3, #26] + 8009626: 693b ldr r3, [r7, #16] + 8009628: 68dc ldr r4, [r3, #12] + 800962a: 0010 movs r0, r2 + 800962c: f7fa fff2 bl 8004614 + 8009630: 0003 movs r3, r0 + 8009632: 22ff movs r2, #255 ; 0xff + 8009634: 401a ands r2, r3 + 8009636: 0010 movs r0, r2 + 8009638: 7822 ldrb r2, [r4, #0] + 800963a: 2100 movs r1, #0 + 800963c: 400a ands r2, r1 + 800963e: 1c11 adds r1, r2, #0 + 8009640: 1c02 adds r2, r0, #0 + 8009642: 430a orrs r2, r1 + 8009644: 7022 strb r2, [r4, #0] + 8009646: 0a1b lsrs r3, r3, #8 + 8009648: b299 uxth r1, r3 + 800964a: 7863 ldrb r3, [r4, #1] + 800964c: 2200 movs r2, #0 + 800964e: 4013 ands r3, r2 + 8009650: 1c1a adds r2, r3, #0 + 8009652: 1c0b adds r3, r1, #0 + 8009654: 4313 orrs r3, r2 + 8009656: 7063 strb r3, [r4, #1] + seg->tcphdr->dest = htons(pcb->remote_port); + 8009658: 68fb ldr r3, [r7, #12] + 800965a: 8b9a ldrh r2, [r3, #28] + 800965c: 693b ldr r3, [r7, #16] + 800965e: 68dc ldr r4, [r3, #12] + 8009660: 0010 movs r0, r2 + 8009662: f7fa ffd7 bl 8004614 + 8009666: 0003 movs r3, r0 + 8009668: 22ff movs r2, #255 ; 0xff + 800966a: 401a ands r2, r3 + 800966c: 0010 movs r0, r2 + 800966e: 78a2 ldrb r2, [r4, #2] + 8009670: 2100 movs r1, #0 + 8009672: 400a ands r2, r1 + 8009674: 1c11 adds r1, r2, #0 + 8009676: 1c02 adds r2, r0, #0 + 8009678: 430a orrs r2, r1 + 800967a: 70a2 strb r2, [r4, #2] + 800967c: 0a1b lsrs r3, r3, #8 + 800967e: b299 uxth r1, r3 + 8009680: 78e3 ldrb r3, [r4, #3] + 8009682: 2200 movs r2, #0 + 8009684: 4013 ands r3, r2 + 8009686: 1c1a adds r2, r3, #0 + 8009688: 1c0b adds r3, r1, #0 + 800968a: 4313 orrs r3, r2 + 800968c: 70e3 strb r3, [r4, #3] + seg->tcphdr->seqno = htonl(seqno); + 800968e: 693b ldr r3, [r7, #16] + 8009690: 68dc ldr r4, [r3, #12] + 8009692: 683b ldr r3, [r7, #0] + 8009694: 0018 movs r0, r3 + 8009696: f7fa ffe3 bl 8004660 + 800969a: 0003 movs r3, r0 + 800969c: 22ff movs r2, #255 ; 0xff + 800969e: 401a ands r2, r3 + 80096a0: 0010 movs r0, r2 + 80096a2: 7922 ldrb r2, [r4, #4] + 80096a4: 2100 movs r1, #0 + 80096a6: 400a ands r2, r1 + 80096a8: 1c11 adds r1, r2, #0 + 80096aa: 1c02 adds r2, r0, #0 + 80096ac: 430a orrs r2, r1 + 80096ae: 7122 strb r2, [r4, #4] + 80096b0: 0a1a lsrs r2, r3, #8 + 80096b2: 21ff movs r1, #255 ; 0xff + 80096b4: 400a ands r2, r1 + 80096b6: 0010 movs r0, r2 + 80096b8: 7962 ldrb r2, [r4, #5] + 80096ba: 2100 movs r1, #0 + 80096bc: 400a ands r2, r1 + 80096be: 1c11 adds r1, r2, #0 + 80096c0: 1c02 adds r2, r0, #0 + 80096c2: 430a orrs r2, r1 + 80096c4: 7162 strb r2, [r4, #5] + 80096c6: 0c1a lsrs r2, r3, #16 + 80096c8: 21ff movs r1, #255 ; 0xff + 80096ca: 400a ands r2, r1 + 80096cc: 0010 movs r0, r2 + 80096ce: 79a2 ldrb r2, [r4, #6] + 80096d0: 2100 movs r1, #0 + 80096d2: 400a ands r2, r1 + 80096d4: 1c11 adds r1, r2, #0 + 80096d6: 1c02 adds r2, r0, #0 + 80096d8: 430a orrs r2, r1 + 80096da: 71a2 strb r2, [r4, #6] + 80096dc: 0e19 lsrs r1, r3, #24 + 80096de: 79e3 ldrb r3, [r4, #7] + 80096e0: 2200 movs r2, #0 + 80096e2: 4013 ands r3, r2 + 80096e4: 1c1a adds r2, r3, #0 + 80096e6: 1c0b adds r3, r1, #0 + 80096e8: 4313 orrs r3, r2 + 80096ea: 71e3 strb r3, [r4, #7] + /* ackno is set in tcp_output */ + TCPH_HDRLEN_FLAGS_SET(seg->tcphdr, (5 + optlen / 4), flags); + 80096ec: 2317 movs r3, #23 + 80096ee: 18fb adds r3, r7, r3 + 80096f0: 781b ldrb r3, [r3, #0] + 80096f2: 089b lsrs r3, r3, #2 + 80096f4: b2db uxtb r3, r3 + 80096f6: 3305 adds r3, #5 + 80096f8: 031b lsls r3, r3, #12 + 80096fa: b21a sxth r2, r3 + 80096fc: 1dfb adds r3, r7, #7 + 80096fe: 781b ldrb r3, [r3, #0] + 8009700: b21b sxth r3, r3 + 8009702: 4313 orrs r3, r2 + 8009704: b21b sxth r3, r3 + 8009706: b29a uxth r2, r3 + 8009708: 693b ldr r3, [r7, #16] + 800970a: 68dc ldr r4, [r3, #12] + 800970c: 0010 movs r0, r2 + 800970e: f7fa ff81 bl 8004614 + 8009712: 0003 movs r3, r0 + 8009714: 22ff movs r2, #255 ; 0xff + 8009716: 401a ands r2, r3 + 8009718: 0010 movs r0, r2 + 800971a: 7b22 ldrb r2, [r4, #12] + 800971c: 2100 movs r1, #0 + 800971e: 400a ands r2, r1 + 8009720: 1c11 adds r1, r2, #0 + 8009722: 1c02 adds r2, r0, #0 + 8009724: 430a orrs r2, r1 + 8009726: 7322 strb r2, [r4, #12] + 8009728: 0a1b lsrs r3, r3, #8 + 800972a: b299 uxth r1, r3 + 800972c: 7b63 ldrb r3, [r4, #13] + 800972e: 2200 movs r2, #0 + 8009730: 4013 ands r3, r2 + 8009732: 1c1a adds r2, r3, #0 + 8009734: 1c0b adds r3, r1, #0 + 8009736: 4313 orrs r3, r2 + 8009738: 7363 strb r3, [r4, #13] + /* wnd and chksum are set in tcp_output */ + seg->tcphdr->urgp = 0; + 800973a: 693b ldr r3, [r7, #16] + 800973c: 68db ldr r3, [r3, #12] + 800973e: 7c9a ldrb r2, [r3, #18] + 8009740: 2100 movs r1, #0 + 8009742: 400a ands r2, r1 + 8009744: 749a strb r2, [r3, #18] + 8009746: 7cda ldrb r2, [r3, #19] + 8009748: 2100 movs r1, #0 + 800974a: 400a ands r2, r1 + 800974c: 74da strb r2, [r3, #19] + return seg; + 800974e: 693b ldr r3, [r7, #16] +} + 8009750: 0018 movs r0, r3 + 8009752: 46bd mov sp, r7 + 8009754: b007 add sp, #28 + 8009756: bd90 pop {r4, r7, pc} + 8009758: 20003158 .word 0x20003158 + +0800975c : + * @param optdata pointer to TCP options, or NULL. + * @param optlen length of TCP options in bytes. + */ +err_t +tcp_enqueue_flags(struct tcp_pcb *pcb, u8_t flags) +{ + 800975c: b590 push {r4, r7, lr} + 800975e: b08b sub sp, #44 ; 0x2c + 8009760: af02 add r7, sp, #8 + 8009762: 6078 str r0, [r7, #4] + 8009764: 000a movs r2, r1 + 8009766: 1cfb adds r3, r7, #3 + 8009768: 701a strb r2, [r3, #0] + struct pbuf *p; + struct tcp_seg *seg; + u8_t optflags = 0; + 800976a: 231f movs r3, #31 + 800976c: 18fb adds r3, r7, r3 + 800976e: 2200 movs r2, #0 + 8009770: 701a strb r2, [r3, #0] + u8_t optlen = 0; + 8009772: 2317 movs r3, #23 + 8009774: 18fb adds r3, r7, r3 + 8009776: 2200 movs r2, #0 + 8009778: 701a strb r2, [r3, #0] + + LWIP_ASSERT("tcp_enqueue_flags: need either TCP_SYN or TCP_FIN in flags (programmer violates API)", + (flags & (TCP_SYN | TCP_FIN)) != 0); + + /* check for configured max queuelen and possible overflow */ + if ((pcb->snd_queuelen >= TCP_SND_QUEUELEN) || (pcb->snd_queuelen > TCP_SNDQUEUELEN_OVERFLOW)) { + 800977a: 687b ldr r3, [r7, #4] + 800977c: 2268 movs r2, #104 ; 0x68 + 800977e: 5a9b ldrh r3, [r3, r2] + 8009780: 2b07 cmp r3, #7 + 8009782: d805 bhi.n 8009790 + 8009784: 687b ldr r3, [r7, #4] + 8009786: 2268 movs r2, #104 ; 0x68 + 8009788: 5a9b ldrh r3, [r3, r2] + 800978a: 4a6f ldr r2, [pc, #444] ; (8009948 ) + 800978c: 4293 cmp r3, r2 + 800978e: d912 bls.n 80097b6 + LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 3, ("tcp_enqueue_flags: too long queue %"U16_F" (max %"U16_F")\n", + pcb->snd_queuelen, TCP_SND_QUEUELEN)); + TCP_STATS_INC(tcp.memerr); + 8009790: 4b6e ldr r3, [pc, #440] ; (800994c ) + 8009792: 229c movs r2, #156 ; 0x9c + 8009794: 5a9b ldrh r3, [r3, r2] + 8009796: 3301 adds r3, #1 + 8009798: b299 uxth r1, r3 + 800979a: 4b6c ldr r3, [pc, #432] ; (800994c ) + 800979c: 229c movs r2, #156 ; 0x9c + 800979e: 5299 strh r1, [r3, r2] + pcb->flags |= TF_NAGLEMEMERR; + 80097a0: 687b ldr r3, [r7, #4] + 80097a2: 7f9b ldrb r3, [r3, #30] + 80097a4: 2280 movs r2, #128 ; 0x80 + 80097a6: 4252 negs r2, r2 + 80097a8: 4313 orrs r3, r2 + 80097aa: b2da uxtb r2, r3 + 80097ac: 687b ldr r3, [r7, #4] + 80097ae: 779a strb r2, [r3, #30] + return ERR_MEM; + 80097b0: 2301 movs r3, #1 + 80097b2: 425b negs r3, r3 + 80097b4: e0c3 b.n 800993e + } + + if (flags & TCP_SYN) { + 80097b6: 1cfb adds r3, r7, #3 + 80097b8: 781b ldrb r3, [r3, #0] + 80097ba: 2202 movs r2, #2 + 80097bc: 4013 ands r3, r2 + 80097be: d003 beq.n 80097c8 + optflags = TF_SEG_OPTS_MSS; + 80097c0: 231f movs r3, #31 + 80097c2: 18fb adds r3, r7, r3 + 80097c4: 2201 movs r2, #1 + 80097c6: 701a strb r2, [r3, #0] +#if LWIP_TCP_TIMESTAMPS + if ((pcb->flags & TF_TIMESTAMP)) { + optflags |= TF_SEG_OPTS_TS; + } +#endif /* LWIP_TCP_TIMESTAMPS */ + optlen = LWIP_TCP_OPT_LENGTH(optflags); + 80097c8: 201f movs r0, #31 + 80097ca: 183b adds r3, r7, r0 + 80097cc: 781b ldrb r3, [r3, #0] + 80097ce: 009b lsls r3, r3, #2 + 80097d0: b2db uxtb r3, r3 + 80097d2: 2204 movs r2, #4 + 80097d4: 4013 ands r3, r2 + 80097d6: b2d9 uxtb r1, r3 + 80097d8: 183b adds r3, r7, r0 + 80097da: 781b ldrb r3, [r3, #0] + 80097dc: 2202 movs r2, #2 + 80097de: 4013 ands r3, r2 + 80097e0: d001 beq.n 80097e6 + 80097e2: 230c movs r3, #12 + 80097e4: e000 b.n 80097e8 + 80097e6: 2300 movs r3, #0 + 80097e8: 2217 movs r2, #23 + 80097ea: 18ba adds r2, r7, r2 + 80097ec: 185b adds r3, r3, r1 + 80097ee: 7013 strb r3, [r2, #0] + + /* tcp_enqueue_flags is always called with either SYN or FIN in flags. + * We need one available snd_buf byte to do that. + * This means we can't send FIN while snd_buf==0. A better fix would be to + * not include SYN and FIN sequence numbers in the snd_buf count. */ + if (pcb->snd_buf == 0) { + 80097f0: 687b ldr r3, [r7, #4] + 80097f2: 2266 movs r2, #102 ; 0x66 + 80097f4: 5a9b ldrh r3, [r3, r2] + 80097f6: 2b00 cmp r3, #0 + 80097f8: d10a bne.n 8009810 + LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 3, ("tcp_enqueue_flags: no send buffer available\n")); + TCP_STATS_INC(tcp.memerr); + 80097fa: 4b54 ldr r3, [pc, #336] ; (800994c ) + 80097fc: 229c movs r2, #156 ; 0x9c + 80097fe: 5a9b ldrh r3, [r3, r2] + 8009800: 3301 adds r3, #1 + 8009802: b299 uxth r1, r3 + 8009804: 4b51 ldr r3, [pc, #324] ; (800994c ) + 8009806: 229c movs r2, #156 ; 0x9c + 8009808: 5299 strh r1, [r3, r2] + return ERR_MEM; + 800980a: 2301 movs r3, #1 + 800980c: 425b negs r3, r3 + 800980e: e096 b.n 800993e + } + + /* Allocate pbuf with room for TCP header + options */ + if ((p = pbuf_alloc(PBUF_TRANSPORT, optlen, PBUF_RAM)) == NULL) { + 8009810: 2317 movs r3, #23 + 8009812: 18fb adds r3, r7, r3 + 8009814: 781b ldrb r3, [r3, #0] + 8009816: b29b uxth r3, r3 + 8009818: 2200 movs r2, #0 + 800981a: 0019 movs r1, r3 + 800981c: 2000 movs r0, #0 + 800981e: f7fb fcb5 bl 800518c + 8009822: 0003 movs r3, r0 + 8009824: 613b str r3, [r7, #16] + 8009826: 693b ldr r3, [r7, #16] + 8009828: 2b00 cmp r3, #0 + 800982a: d112 bne.n 8009852 + pcb->flags |= TF_NAGLEMEMERR; + 800982c: 687b ldr r3, [r7, #4] + 800982e: 7f9b ldrb r3, [r3, #30] + 8009830: 2280 movs r2, #128 ; 0x80 + 8009832: 4252 negs r2, r2 + 8009834: 4313 orrs r3, r2 + 8009836: b2da uxtb r2, r3 + 8009838: 687b ldr r3, [r7, #4] + 800983a: 779a strb r2, [r3, #30] + TCP_STATS_INC(tcp.memerr); + 800983c: 4b43 ldr r3, [pc, #268] ; (800994c ) + 800983e: 229c movs r2, #156 ; 0x9c + 8009840: 5a9b ldrh r3, [r3, r2] + 8009842: 3301 adds r3, #1 + 8009844: b299 uxth r1, r3 + 8009846: 4b41 ldr r3, [pc, #260] ; (800994c ) + 8009848: 229c movs r2, #156 ; 0x9c + 800984a: 5299 strh r1, [r3, r2] + return ERR_MEM; + 800984c: 2301 movs r3, #1 + 800984e: 425b negs r3, r3 + 8009850: e075 b.n 800993e + } + LWIP_ASSERT("tcp_enqueue_flags: check that first pbuf can hold optlen", + (p->len >= optlen)); + + /* Allocate memory for tcp_seg, and fill in fields. */ + if ((seg = tcp_create_segment(pcb, p, flags, pcb->snd_lbb, optflags)) == NULL) { + 8009852: 687b ldr r3, [r7, #4] + 8009854: 6ddc ldr r4, [r3, #92] ; 0x5c + 8009856: 1cfb adds r3, r7, #3 + 8009858: 781a ldrb r2, [r3, #0] + 800985a: 6939 ldr r1, [r7, #16] + 800985c: 6878 ldr r0, [r7, #4] + 800985e: 231f movs r3, #31 + 8009860: 18fb adds r3, r7, r3 + 8009862: 781b ldrb r3, [r3, #0] + 8009864: 9300 str r3, [sp, #0] + 8009866: 0023 movs r3, r4 + 8009868: f7ff fe82 bl 8009570 + 800986c: 0003 movs r3, r0 + 800986e: 60fb str r3, [r7, #12] + 8009870: 68fb ldr r3, [r7, #12] + 8009872: 2b00 cmp r3, #0 + 8009874: d112 bne.n 800989c + pcb->flags |= TF_NAGLEMEMERR; + 8009876: 687b ldr r3, [r7, #4] + 8009878: 7f9b ldrb r3, [r3, #30] + 800987a: 2280 movs r2, #128 ; 0x80 + 800987c: 4252 negs r2, r2 + 800987e: 4313 orrs r3, r2 + 8009880: b2da uxtb r2, r3 + 8009882: 687b ldr r3, [r7, #4] + 8009884: 779a strb r2, [r3, #30] + TCP_STATS_INC(tcp.memerr); + 8009886: 4b31 ldr r3, [pc, #196] ; (800994c ) + 8009888: 229c movs r2, #156 ; 0x9c + 800988a: 5a9b ldrh r3, [r3, r2] + 800988c: 3301 adds r3, #1 + 800988e: b299 uxth r1, r3 + 8009890: 4b2e ldr r3, [pc, #184] ; (800994c ) + 8009892: 229c movs r2, #156 ; 0x9c + 8009894: 5299 strh r1, [r3, r2] + return ERR_MEM; + 8009896: 2301 movs r3, #1 + 8009898: 425b negs r3, r3 + 800989a: e050 b.n 800993e + ntohl(seg->tcphdr->seqno), + ntohl(seg->tcphdr->seqno) + TCP_TCPLEN(seg), + (u16_t)flags)); + + /* Now append seg to pcb->unsent queue */ + if (pcb->unsent == NULL) { + 800989c: 687b ldr r3, [r7, #4] + 800989e: 6edb ldr r3, [r3, #108] ; 0x6c + 80098a0: 2b00 cmp r3, #0 + 80098a2: d103 bne.n 80098ac + pcb->unsent = seg; + 80098a4: 687b ldr r3, [r7, #4] + 80098a6: 68fa ldr r2, [r7, #12] + 80098a8: 66da str r2, [r3, #108] ; 0x6c + 80098aa: e00d b.n 80098c8 + } else { + struct tcp_seg *useg; + for (useg = pcb->unsent; useg->next != NULL; useg = useg->next); + 80098ac: 687b ldr r3, [r7, #4] + 80098ae: 6edb ldr r3, [r3, #108] ; 0x6c + 80098b0: 61bb str r3, [r7, #24] + 80098b2: e002 b.n 80098ba + 80098b4: 69bb ldr r3, [r7, #24] + 80098b6: 681b ldr r3, [r3, #0] + 80098b8: 61bb str r3, [r7, #24] + 80098ba: 69bb ldr r3, [r7, #24] + 80098bc: 681b ldr r3, [r3, #0] + 80098be: 2b00 cmp r3, #0 + 80098c0: d1f8 bne.n 80098b4 + useg->next = seg; + 80098c2: 69bb ldr r3, [r7, #24] + 80098c4: 68fa ldr r2, [r7, #12] + 80098c6: 601a str r2, [r3, #0] + } +#if TCP_OVERSIZE + /* The new unsent tail has no space */ + pcb->unsent_oversize = 0; + 80098c8: 687b ldr r3, [r7, #4] + 80098ca: 226a movs r2, #106 ; 0x6a + 80098cc: 2100 movs r1, #0 + 80098ce: 5299 strh r1, [r3, r2] +#endif /* TCP_OVERSIZE */ + + /* SYN and FIN bump the sequence number */ + if ((flags & TCP_SYN) || (flags & TCP_FIN)) { + 80098d0: 1cfb adds r3, r7, #3 + 80098d2: 781b ldrb r3, [r3, #0] + 80098d4: 2202 movs r2, #2 + 80098d6: 4013 ands r3, r2 + 80098d8: d104 bne.n 80098e4 + 80098da: 1cfb adds r3, r7, #3 + 80098dc: 781b ldrb r3, [r3, #0] + 80098de: 2201 movs r2, #1 + 80098e0: 4013 ands r3, r2 + 80098e2: d00c beq.n 80098fe + pcb->snd_lbb++; + 80098e4: 687b ldr r3, [r7, #4] + 80098e6: 6ddb ldr r3, [r3, #92] ; 0x5c + 80098e8: 1c5a adds r2, r3, #1 + 80098ea: 687b ldr r3, [r7, #4] + 80098ec: 65da str r2, [r3, #92] ; 0x5c + /* optlen does not influence snd_buf */ + pcb->snd_buf--; + 80098ee: 687b ldr r3, [r7, #4] + 80098f0: 2266 movs r2, #102 ; 0x66 + 80098f2: 5a9b ldrh r3, [r3, r2] + 80098f4: 3b01 subs r3, #1 + 80098f6: b299 uxth r1, r3 + 80098f8: 687b ldr r3, [r7, #4] + 80098fa: 2266 movs r2, #102 ; 0x66 + 80098fc: 5299 strh r1, [r3, r2] + } + if (flags & TCP_FIN) { + 80098fe: 1cfb adds r3, r7, #3 + 8009900: 781b ldrb r3, [r3, #0] + 8009902: 2201 movs r2, #1 + 8009904: 4013 ands r3, r2 + 8009906: d006 beq.n 8009916 + pcb->flags |= TF_FIN; + 8009908: 687b ldr r3, [r7, #4] + 800990a: 7f9b ldrb r3, [r3, #30] + 800990c: 2220 movs r2, #32 + 800990e: 4313 orrs r3, r2 + 8009910: b2da uxtb r2, r3 + 8009912: 687b ldr r3, [r7, #4] + 8009914: 779a strb r2, [r3, #30] + } + + /* update number of segments on the queues */ + pcb->snd_queuelen += pbuf_clen(seg->p); + 8009916: 68fb ldr r3, [r7, #12] + 8009918: 685b ldr r3, [r3, #4] + 800991a: 0018 movs r0, r3 + 800991c: f7fb ff34 bl 8005788 + 8009920: 0003 movs r3, r0 + 8009922: 0019 movs r1, r3 + 8009924: 687b ldr r3, [r7, #4] + 8009926: 2268 movs r2, #104 ; 0x68 + 8009928: 5a9a ldrh r2, [r3, r2] + 800992a: b28b uxth r3, r1 + 800992c: 18d3 adds r3, r2, r3 + 800992e: b299 uxth r1, r3 + 8009930: 687b ldr r3, [r7, #4] + 8009932: 2268 movs r2, #104 ; 0x68 + 8009934: 5299 strh r1, [r3, r2] + LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_enqueue_flags: %"S16_F" (after enqueued)\n", pcb->snd_queuelen)); + if (pcb->snd_queuelen != 0) { + 8009936: 687b ldr r3, [r7, #4] + 8009938: 2268 movs r2, #104 ; 0x68 + 800993a: 5a9b ldrh r3, [r3, r2] + LWIP_ASSERT("tcp_enqueue_flags: invalid queue length", + pcb->unacked != NULL || pcb->unsent != NULL); + } + + return ERR_OK; + 800993c: 2300 movs r3, #0 +} + 800993e: 0018 movs r0, r3 + 8009940: 46bd mov sp, r7 + 8009942: b009 add sp, #36 ; 0x24 + 8009944: bd90 pop {r4, r7, pc} + 8009946: 46c0 nop ; (mov r8, r8) + 8009948: 0000fffc .word 0x0000fffc + 800994c: 20003158 .word 0x20003158 + +08009950 : + * + * @param pcb Protocol control block for the TCP connection to send the ACK + */ +err_t +tcp_send_empty_ack(struct tcp_pcb *pcb) +{ + 8009950: b5b0 push {r4, r5, r7, lr} + 8009952: b088 sub sp, #32 + 8009954: af02 add r7, sp, #8 + 8009956: 6078 str r0, [r7, #4] + struct pbuf *p; + struct tcp_hdr *tcphdr; + u8_t optlen = 0; + 8009958: 2117 movs r1, #23 + 800995a: 187b adds r3, r7, r1 + 800995c: 2200 movs r2, #0 + 800995e: 701a strb r2, [r3, #0] + if (pcb->flags & TF_TIMESTAMP) { + optlen = LWIP_TCP_OPT_LENGTH(TF_SEG_OPTS_TS); + } +#endif + + p = tcp_output_alloc_header(pcb, optlen, 0, htonl(pcb->snd_nxt)); + 8009960: 187b adds r3, r7, r1 + 8009962: 781b ldrb r3, [r3, #0] + 8009964: b29c uxth r4, r3 + 8009966: 687b ldr r3, [r7, #4] + 8009968: 6d1b ldr r3, [r3, #80] ; 0x50 + 800996a: 0018 movs r0, r3 + 800996c: f7fa fe78 bl 8004660 + 8009970: 0003 movs r3, r0 + 8009972: 6878 ldr r0, [r7, #4] + 8009974: 2200 movs r2, #0 + 8009976: 0021 movs r1, r4 + 8009978: f7ff fc94 bl 80092a4 + 800997c: 0003 movs r3, r0 + 800997e: 613b str r3, [r7, #16] + if (p == NULL) { + 8009980: 693b ldr r3, [r7, #16] + 8009982: 2b00 cmp r3, #0 + 8009984: d102 bne.n 800998c + LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_output: (ACK) could not allocate pbuf\n")); + return ERR_BUF; + 8009986: 2302 movs r3, #2 + 8009988: 425b negs r3, r3 + 800998a: e03d b.n 8009a08 + } + tcphdr = (struct tcp_hdr *)p->payload; + 800998c: 693b ldr r3, [r7, #16] + 800998e: 685b ldr r3, [r3, #4] + 8009990: 60fb str r3, [r7, #12] + LWIP_DEBUGF(TCP_OUTPUT_DEBUG, + ("tcp_output: sending ACK for %"U32_F"\n", pcb->rcv_nxt)); + /* remove ACK flags from the PCB, as we send an empty ACK now */ + pcb->flags &= ~(TF_ACK_DELAY | TF_ACK_NOW); + 8009992: 687b ldr r3, [r7, #4] + 8009994: 7f9b ldrb r3, [r3, #30] + 8009996: 2203 movs r2, #3 + 8009998: 4393 bics r3, r2 + 800999a: b2da uxtb r2, r3 + 800999c: 687b ldr r3, [r7, #4] + 800999e: 779a strb r2, [r3, #30] + tcp_build_timestamp_option(pcb, (u32_t *)(tcphdr + 1)); + } +#endif + +#if CHECKSUM_GEN_TCP + tcphdr->chksum = inet_chksum_pseudo(p, &(pcb->local_ip), &(pcb->remote_ip), + 80099a0: 6879 ldr r1, [r7, #4] + 80099a2: 687b ldr r3, [r7, #4] + 80099a4: 1d1a adds r2, r3, #4 + 80099a6: 693b ldr r3, [r7, #16] + 80099a8: 891b ldrh r3, [r3, #8] + 80099aa: 6938 ldr r0, [r7, #16] + 80099ac: 9300 str r3, [sp, #0] + 80099ae: 2306 movs r3, #6 + 80099b0: f001 fe43 bl 800b63a + 80099b4: 0003 movs r3, r0 + 80099b6: 001a movs r2, r3 + 80099b8: 68fb ldr r3, [r7, #12] + 80099ba: 21ff movs r1, #255 ; 0xff + 80099bc: 4011 ands r1, r2 + 80099be: 000c movs r4, r1 + 80099c0: 7c19 ldrb r1, [r3, #16] + 80099c2: 2000 movs r0, #0 + 80099c4: 4001 ands r1, r0 + 80099c6: 1c08 adds r0, r1, #0 + 80099c8: 1c21 adds r1, r4, #0 + 80099ca: 4301 orrs r1, r0 + 80099cc: 7419 strb r1, [r3, #16] + 80099ce: 0a12 lsrs r2, r2, #8 + 80099d0: b290 uxth r0, r2 + 80099d2: 7c5a ldrb r2, [r3, #17] + 80099d4: 2100 movs r1, #0 + 80099d6: 400a ands r2, r1 + 80099d8: 1c11 adds r1, r2, #0 + 80099da: 1c02 adds r2, r0, #0 + 80099dc: 430a orrs r2, r1 + 80099de: 745a strb r2, [r3, #17] +#endif +#if LWIP_NETIF_HWADDRHINT + ip_output_hinted(p, &(pcb->local_ip), &(pcb->remote_ip), pcb->ttl, pcb->tos, + IP_PROTO_TCP, &(pcb->addr_hint)); +#else /* LWIP_NETIF_HWADDRHINT*/ + ip_output(p, &(pcb->local_ip), &(pcb->remote_ip), pcb->ttl, pcb->tos, + 80099e0: 6879 ldr r1, [r7, #4] + 80099e2: 687b ldr r3, [r7, #4] + 80099e4: 1d1c adds r4, r3, #4 + 80099e6: 687b ldr r3, [r7, #4] + 80099e8: 7a9d ldrb r5, [r3, #10] + 80099ea: 687b ldr r3, [r7, #4] + 80099ec: 7a5b ldrb r3, [r3, #9] + 80099ee: 6938 ldr r0, [r7, #16] + 80099f0: 2206 movs r2, #6 + 80099f2: 9201 str r2, [sp, #4] + 80099f4: 9300 str r3, [sp, #0] + 80099f6: 002b movs r3, r5 + 80099f8: 0022 movs r2, r4 + 80099fa: f002 fb09 bl 800c010 + IP_PROTO_TCP); +#endif /* LWIP_NETIF_HWADDRHINT*/ + pbuf_free(p); + 80099fe: 693b ldr r3, [r7, #16] + 8009a00: 0018 movs r0, r3 + 8009a02: f7fb fe4f bl 80056a4 + + return ERR_OK; + 8009a06: 2300 movs r3, #0 +} + 8009a08: 0018 movs r0, r3 + 8009a0a: 46bd mov sp, r7 + 8009a0c: b006 add sp, #24 + 8009a0e: bdb0 pop {r4, r5, r7, pc} + +08009a10 : + * @return ERR_OK if data has been sent or nothing to send + * another err_t on error + */ +err_t +tcp_output(struct tcp_pcb *pcb) +{ + 8009a10: b5b0 push {r4, r5, r7, lr} + 8009a12: b088 sub sp, #32 + 8009a14: af00 add r7, sp, #0 + 8009a16: 6078 str r0, [r7, #4] + + /* First, check if we are invoked by the TCP input processing + code. If so, we do not output anything. Instead, we rely on the + input processing code to call us when input processing is done + with. */ + if (tcp_input_pcb == pcb) { + 8009a18: 4bcd ldr r3, [pc, #820] ; (8009d50 ) + 8009a1a: 681b ldr r3, [r3, #0] + 8009a1c: 687a ldr r2, [r7, #4] + 8009a1e: 429a cmp r2, r3 + 8009a20: d101 bne.n 8009a26 + return ERR_OK; + 8009a22: 2300 movs r3, #0 + 8009a24: e1a7 b.n 8009d76 + } + + wnd = LWIP_MIN(pcb->snd_wnd, pcb->cwnd); + 8009a26: 687b ldr r3, [r7, #4] + 8009a28: 2260 movs r2, #96 ; 0x60 + 8009a2a: 5a9a ldrh r2, [r3, r2] + 8009a2c: 687b ldr r3, [r7, #4] + 8009a2e: 214c movs r1, #76 ; 0x4c + 8009a30: 5a5b ldrh r3, [r3, r1] + 8009a32: 429a cmp r2, r3 + 8009a34: d203 bcs.n 8009a3e + 8009a36: 687b ldr r3, [r7, #4] + 8009a38: 2260 movs r2, #96 ; 0x60 + 8009a3a: 5a9b ldrh r3, [r3, r2] + 8009a3c: e002 b.n 8009a44 + 8009a3e: 687b ldr r3, [r7, #4] + 8009a40: 224c movs r2, #76 ; 0x4c + 8009a42: 5a9b ldrh r3, [r3, r2] + 8009a44: 613b str r3, [r7, #16] + + seg = pcb->unsent; + 8009a46: 687b ldr r3, [r7, #4] + 8009a48: 6edb ldr r3, [r3, #108] ; 0x6c + 8009a4a: 61fb str r3, [r7, #28] + * because the ->unsent queue is empty or because the window does + * not allow it), construct an empty ACK segment and send it. + * + * If data is to be sent, we will just piggyback the ACK (see below). + */ + if (pcb->flags & TF_ACK_NOW && + 8009a4c: 687b ldr r3, [r7, #4] + 8009a4e: 7f9b ldrb r3, [r3, #30] + 8009a50: 001a movs r2, r3 + 8009a52: 2302 movs r3, #2 + 8009a54: 4013 ands r3, r2 + 8009a56: d021 beq.n 8009a9c + 8009a58: 69fb ldr r3, [r7, #28] + 8009a5a: 2b00 cmp r3, #0 + 8009a5c: d018 beq.n 8009a90 + (seg == NULL || + ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len > wnd)) { + 8009a5e: 69fb ldr r3, [r7, #28] + 8009a60: 68db ldr r3, [r3, #12] + 8009a62: 791a ldrb r2, [r3, #4] + 8009a64: 7959 ldrb r1, [r3, #5] + 8009a66: 0209 lsls r1, r1, #8 + 8009a68: 430a orrs r2, r1 + 8009a6a: 7999 ldrb r1, [r3, #6] + 8009a6c: 0409 lsls r1, r1, #16 + 8009a6e: 430a orrs r2, r1 + 8009a70: 79db ldrb r3, [r3, #7] + 8009a72: 061b lsls r3, r3, #24 + 8009a74: 4313 orrs r3, r2 + 8009a76: 0018 movs r0, r3 + 8009a78: f7fa fe0b bl 8004692 + 8009a7c: 0002 movs r2, r0 + 8009a7e: 687b ldr r3, [r7, #4] + 8009a80: 6c9b ldr r3, [r3, #72] ; 0x48 + 8009a82: 1ad3 subs r3, r2, r3 + 8009a84: 69fa ldr r2, [r7, #28] + 8009a86: 8912 ldrh r2, [r2, #8] + 8009a88: 189b adds r3, r3, r2 + (seg == NULL || + 8009a8a: 693a ldr r2, [r7, #16] + 8009a8c: 429a cmp r2, r3 + 8009a8e: d205 bcs.n 8009a9c + return tcp_send_empty_ack(pcb); + 8009a90: 687b ldr r3, [r7, #4] + 8009a92: 0018 movs r0, r3 + 8009a94: f7ff ff5c bl 8009950 + 8009a98: 0003 movs r3, r0 + 8009a9a: e16c b.n 8009d76 + } + + /* useg should point to last segment on unacked queue */ + useg = pcb->unacked; + 8009a9c: 687b ldr r3, [r7, #4] + 8009a9e: 6f1b ldr r3, [r3, #112] ; 0x70 + 8009aa0: 61bb str r3, [r7, #24] + if (useg != NULL) { + 8009aa2: 69bb ldr r3, [r7, #24] + 8009aa4: 2b00 cmp r3, #0 + 8009aa6: d100 bne.n 8009aaa + 8009aa8: e133 b.n 8009d12 + for (; useg->next != NULL; useg = useg->next); + 8009aaa: e002 b.n 8009ab2 + 8009aac: 69bb ldr r3, [r7, #24] + 8009aae: 681b ldr r3, [r3, #0] + 8009ab0: 61bb str r3, [r7, #24] + 8009ab2: 69bb ldr r3, [r7, #24] + 8009ab4: 681b ldr r3, [r3, #0] + 8009ab6: 2b00 cmp r3, #0 + 8009ab8: d1f8 bne.n 8009aac + ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len, + ntohl(seg->tcphdr->seqno), pcb->lastack)); + } +#endif /* TCP_CWND_DEBUG */ + /* data available and window allows it to be sent? */ + while (seg != NULL && + 8009aba: e12a b.n 8009d12 + ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len <= wnd) { + LWIP_ASSERT("RST not expected here!", + 8009abc: 69fb ldr r3, [r7, #28] + 8009abe: 68db ldr r3, [r3, #12] + 8009ac0: 7b1a ldrb r2, [r3, #12] + 8009ac2: 7b5b ldrb r3, [r3, #13] + 8009ac4: 021b lsls r3, r3, #8 + 8009ac6: 4313 orrs r3, r2 + 8009ac8: b29b uxth r3, r3 + 8009aca: 0018 movs r0, r3 + 8009acc: f7fa fdb8 bl 8004640 + * - if tcp_write had a memory error before (prevent delayed ACK timeout) or + * - if FIN was already enqueued for this PCB (SYN is always alone in a segment - + * either seg->next != NULL or pcb->unacked == NULL; + * RST is no sent using tcp_write/tcp_output. + */ + if((tcp_do_output_nagle(pcb) == 0) && + 8009ad0: 687b ldr r3, [r7, #4] + 8009ad2: 6f1b ldr r3, [r3, #112] ; 0x70 + 8009ad4: 2b00 cmp r3, #0 + 8009ad6: d01f beq.n 8009b18 + 8009ad8: 687b ldr r3, [r7, #4] + 8009ada: 7f9b ldrb r3, [r3, #30] + 8009adc: 001a movs r2, r3 + 8009ade: 2344 movs r3, #68 ; 0x44 + 8009ae0: 4013 ands r3, r2 + 8009ae2: d119 bne.n 8009b18 + 8009ae4: 687b ldr r3, [r7, #4] + 8009ae6: 6edb ldr r3, [r3, #108] ; 0x6c + 8009ae8: 2b00 cmp r3, #0 + 8009aea: d00b beq.n 8009b04 + 8009aec: 687b ldr r3, [r7, #4] + 8009aee: 6edb ldr r3, [r3, #108] ; 0x6c + 8009af0: 681b ldr r3, [r3, #0] + 8009af2: 2b00 cmp r3, #0 + 8009af4: d110 bne.n 8009b18 + 8009af6: 687b ldr r3, [r7, #4] + 8009af8: 6edb ldr r3, [r3, #108] ; 0x6c + 8009afa: 891a ldrh r2, [r3, #8] + 8009afc: 687b ldr r3, [r7, #4] + 8009afe: 8edb ldrh r3, [r3, #54] ; 0x36 + 8009b00: 429a cmp r2, r3 + 8009b02: d209 bcs.n 8009b18 + 8009b04: 687b ldr r3, [r7, #4] + 8009b06: 2266 movs r2, #102 ; 0x66 + 8009b08: 5a9b ldrh r3, [r3, r2] + 8009b0a: 2b00 cmp r3, #0 + 8009b0c: d004 beq.n 8009b18 + 8009b0e: 687b ldr r3, [r7, #4] + 8009b10: 2268 movs r2, #104 ; 0x68 + 8009b12: 5a9b ldrh r3, [r3, r2] + 8009b14: 2b07 cmp r3, #7 + 8009b16: d901 bls.n 8009b1c + 8009b18: 2301 movs r3, #1 + 8009b1a: e000 b.n 8009b1e + 8009b1c: 2300 movs r3, #0 + 8009b1e: 2b00 cmp r3, #0 + 8009b20: d106 bne.n 8009b30 + ((pcb->flags & (TF_NAGLEMEMERR | TF_FIN)) == 0)){ + 8009b22: 687b ldr r3, [r7, #4] + 8009b24: 7f9b ldrb r3, [r3, #30] + 8009b26: 001a movs r2, r3 + 8009b28: 23a0 movs r3, #160 ; 0xa0 + 8009b2a: 4013 ands r3, r2 + if((tcp_do_output_nagle(pcb) == 0) && + 8009b2c: d100 bne.n 8009b30 + 8009b2e: e111 b.n 8009d54 + pcb->lastack, + ntohl(seg->tcphdr->seqno), pcb->lastack, i)); + ++i; +#endif /* TCP_CWND_DEBUG */ + + pcb->unsent = seg->next; + 8009b30: 69fb ldr r3, [r7, #28] + 8009b32: 681a ldr r2, [r3, #0] + 8009b34: 687b ldr r3, [r7, #4] + 8009b36: 66da str r2, [r3, #108] ; 0x6c + + if (pcb->state != SYN_SENT) { + 8009b38: 687b ldr r3, [r7, #4] + 8009b3a: 7e1b ldrb r3, [r3, #24] + 8009b3c: 2b02 cmp r3, #2 + 8009b3e: d029 beq.n 8009b94 + TCPH_SET_FLAG(seg->tcphdr, TCP_ACK); + 8009b40: 69fb ldr r3, [r7, #28] + 8009b42: 68db ldr r3, [r3, #12] + 8009b44: 7b1a ldrb r2, [r3, #12] + 8009b46: 7b5b ldrb r3, [r3, #13] + 8009b48: 021b lsls r3, r3, #8 + 8009b4a: 4313 orrs r3, r2 + 8009b4c: b29c uxth r4, r3 + 8009b4e: 2010 movs r0, #16 + 8009b50: f7fa fd60 bl 8004614 + 8009b54: 0003 movs r3, r0 + 8009b56: 001a movs r2, r3 + 8009b58: 69fb ldr r3, [r7, #28] + 8009b5a: 68db ldr r3, [r3, #12] + 8009b5c: 4322 orrs r2, r4 + 8009b5e: b292 uxth r2, r2 + 8009b60: 21ff movs r1, #255 ; 0xff + 8009b62: 4011 ands r1, r2 + 8009b64: 000c movs r4, r1 + 8009b66: 7b19 ldrb r1, [r3, #12] + 8009b68: 2000 movs r0, #0 + 8009b6a: 4001 ands r1, r0 + 8009b6c: 1c08 adds r0, r1, #0 + 8009b6e: 1c21 adds r1, r4, #0 + 8009b70: 4301 orrs r1, r0 + 8009b72: 7319 strb r1, [r3, #12] + 8009b74: 0a12 lsrs r2, r2, #8 + 8009b76: b290 uxth r0, r2 + 8009b78: 7b5a ldrb r2, [r3, #13] + 8009b7a: 2100 movs r1, #0 + 8009b7c: 400a ands r2, r1 + 8009b7e: 1c11 adds r1, r2, #0 + 8009b80: 1c02 adds r2, r0, #0 + 8009b82: 430a orrs r2, r1 + 8009b84: 735a strb r2, [r3, #13] + pcb->flags &= ~(TF_ACK_DELAY | TF_ACK_NOW); + 8009b86: 687b ldr r3, [r7, #4] + 8009b88: 7f9b ldrb r3, [r3, #30] + 8009b8a: 2203 movs r2, #3 + 8009b8c: 4393 bics r3, r2 + 8009b8e: b2da uxtb r2, r3 + 8009b90: 687b ldr r3, [r7, #4] + 8009b92: 779a strb r2, [r3, #30] + } + + tcp_output_segment(seg, pcb); + 8009b94: 687a ldr r2, [r7, #4] + 8009b96: 69fb ldr r3, [r7, #28] + 8009b98: 0011 movs r1, r2 + 8009b9a: 0018 movs r0, r3 + 8009b9c: f000 f8f0 bl 8009d80 + snd_nxt = ntohl(seg->tcphdr->seqno) + TCP_TCPLEN(seg); + 8009ba0: 69fb ldr r3, [r7, #28] + 8009ba2: 68db ldr r3, [r3, #12] + 8009ba4: 791a ldrb r2, [r3, #4] + 8009ba6: 7959 ldrb r1, [r3, #5] + 8009ba8: 0209 lsls r1, r1, #8 + 8009baa: 430a orrs r2, r1 + 8009bac: 7999 ldrb r1, [r3, #6] + 8009bae: 0409 lsls r1, r1, #16 + 8009bb0: 430a orrs r2, r1 + 8009bb2: 79db ldrb r3, [r3, #7] + 8009bb4: 061b lsls r3, r3, #24 + 8009bb6: 4313 orrs r3, r2 + 8009bb8: 0018 movs r0, r3 + 8009bba: f7fa fd6a bl 8004692 + 8009bbe: 0004 movs r4, r0 + 8009bc0: 69fb ldr r3, [r7, #28] + 8009bc2: 891b ldrh r3, [r3, #8] + 8009bc4: 001d movs r5, r3 + 8009bc6: 69fb ldr r3, [r7, #28] + 8009bc8: 68db ldr r3, [r3, #12] + 8009bca: 7b1a ldrb r2, [r3, #12] + 8009bcc: 7b5b ldrb r3, [r3, #13] + 8009bce: 021b lsls r3, r3, #8 + 8009bd0: 4313 orrs r3, r2 + 8009bd2: b29b uxth r3, r3 + 8009bd4: 0018 movs r0, r3 + 8009bd6: f7fa fd33 bl 8004640 + 8009bda: 0003 movs r3, r0 + 8009bdc: 001a movs r2, r3 + 8009bde: 2303 movs r3, #3 + 8009be0: 4013 ands r3, r2 + 8009be2: 1e5a subs r2, r3, #1 + 8009be4: 4193 sbcs r3, r2 + 8009be6: b2db uxtb r3, r3 + 8009be8: 18eb adds r3, r5, r3 + 8009bea: 18e3 adds r3, r4, r3 + 8009bec: 60fb str r3, [r7, #12] + if (TCP_SEQ_LT(pcb->snd_nxt, snd_nxt)) { + 8009bee: 687b ldr r3, [r7, #4] + 8009bf0: 6d1a ldr r2, [r3, #80] ; 0x50 + 8009bf2: 68fb ldr r3, [r7, #12] + 8009bf4: 1ad3 subs r3, r2, r3 + 8009bf6: d502 bpl.n 8009bfe + pcb->snd_nxt = snd_nxt; + 8009bf8: 687b ldr r3, [r7, #4] + 8009bfa: 68fa ldr r2, [r7, #12] + 8009bfc: 651a str r2, [r3, #80] ; 0x50 + } + /* put segment on unacknowledged list if length > 0 */ + if (TCP_TCPLEN(seg) > 0) { + 8009bfe: 69fb ldr r3, [r7, #28] + 8009c00: 891b ldrh r3, [r3, #8] + 8009c02: 001c movs r4, r3 + 8009c04: 69fb ldr r3, [r7, #28] + 8009c06: 68db ldr r3, [r3, #12] + 8009c08: 7b1a ldrb r2, [r3, #12] + 8009c0a: 7b5b ldrb r3, [r3, #13] + 8009c0c: 021b lsls r3, r3, #8 + 8009c0e: 4313 orrs r3, r2 + 8009c10: b29b uxth r3, r3 + 8009c12: 0018 movs r0, r3 + 8009c14: f7fa fd14 bl 8004640 + 8009c18: 0003 movs r3, r0 + 8009c1a: 001a movs r2, r3 + 8009c1c: 2303 movs r3, #3 + 8009c1e: 4013 ands r3, r2 + 8009c20: 1e5a subs r2, r3, #1 + 8009c22: 4193 sbcs r3, r2 + 8009c24: b2db uxtb r3, r3 + 8009c26: 18e3 adds r3, r4, r3 + 8009c28: 2b00 cmp r3, #0 + 8009c2a: dd6b ble.n 8009d04 + seg->next = NULL; + 8009c2c: 69fb ldr r3, [r7, #28] + 8009c2e: 2200 movs r2, #0 + 8009c30: 601a str r2, [r3, #0] + /* unacked list is empty? */ + if (pcb->unacked == NULL) { + 8009c32: 687b ldr r3, [r7, #4] + 8009c34: 6f1b ldr r3, [r3, #112] ; 0x70 + 8009c36: 2b00 cmp r3, #0 + 8009c38: d105 bne.n 8009c46 + pcb->unacked = seg; + 8009c3a: 687b ldr r3, [r7, #4] + 8009c3c: 69fa ldr r2, [r7, #28] + 8009c3e: 671a str r2, [r3, #112] ; 0x70 + useg = seg; + 8009c40: 69fb ldr r3, [r7, #28] + 8009c42: 61bb str r3, [r7, #24] + 8009c44: e062 b.n 8009d0c + /* unacked list is not empty? */ + } else { + /* In the case of fast retransmit, the packet should not go to the tail + * of the unacked queue, but rather somewhere before it. We need to check for + * this case. -STJ Jul 27, 2004 */ + if (TCP_SEQ_LT(ntohl(seg->tcphdr->seqno), ntohl(useg->tcphdr->seqno))) { + 8009c46: 69fb ldr r3, [r7, #28] + 8009c48: 68db ldr r3, [r3, #12] + 8009c4a: 791a ldrb r2, [r3, #4] + 8009c4c: 7959 ldrb r1, [r3, #5] + 8009c4e: 0209 lsls r1, r1, #8 + 8009c50: 430a orrs r2, r1 + 8009c52: 7999 ldrb r1, [r3, #6] + 8009c54: 0409 lsls r1, r1, #16 + 8009c56: 430a orrs r2, r1 + 8009c58: 79db ldrb r3, [r3, #7] + 8009c5a: 061b lsls r3, r3, #24 + 8009c5c: 4313 orrs r3, r2 + 8009c5e: 0018 movs r0, r3 + 8009c60: f7fa fd17 bl 8004692 + 8009c64: 0004 movs r4, r0 + 8009c66: 69bb ldr r3, [r7, #24] + 8009c68: 68db ldr r3, [r3, #12] + 8009c6a: 791a ldrb r2, [r3, #4] + 8009c6c: 7959 ldrb r1, [r3, #5] + 8009c6e: 0209 lsls r1, r1, #8 + 8009c70: 430a orrs r2, r1 + 8009c72: 7999 ldrb r1, [r3, #6] + 8009c74: 0409 lsls r1, r1, #16 + 8009c76: 430a orrs r2, r1 + 8009c78: 79db ldrb r3, [r3, #7] + 8009c7a: 061b lsls r3, r3, #24 + 8009c7c: 4313 orrs r3, r2 + 8009c7e: 0018 movs r0, r3 + 8009c80: f7fa fd07 bl 8004692 + 8009c84: 0003 movs r3, r0 + 8009c86: 1ae3 subs r3, r4, r3 + 8009c88: d535 bpl.n 8009cf6 + /* add segment to before tail of unacked list, keeping the list sorted */ + struct tcp_seg **cur_seg = &(pcb->unacked); + 8009c8a: 687b ldr r3, [r7, #4] + 8009c8c: 3370 adds r3, #112 ; 0x70 + 8009c8e: 617b str r3, [r7, #20] + while (*cur_seg && + 8009c90: e002 b.n 8009c98 + TCP_SEQ_LT(ntohl((*cur_seg)->tcphdr->seqno), ntohl(seg->tcphdr->seqno))) { + cur_seg = &((*cur_seg)->next ); + 8009c92: 697b ldr r3, [r7, #20] + 8009c94: 681b ldr r3, [r3, #0] + 8009c96: 617b str r3, [r7, #20] + while (*cur_seg && + 8009c98: 697b ldr r3, [r7, #20] + 8009c9a: 681b ldr r3, [r3, #0] + 8009c9c: 2b00 cmp r3, #0 + 8009c9e: d022 beq.n 8009ce6 + TCP_SEQ_LT(ntohl((*cur_seg)->tcphdr->seqno), ntohl(seg->tcphdr->seqno))) { + 8009ca0: 697b ldr r3, [r7, #20] + 8009ca2: 681b ldr r3, [r3, #0] + 8009ca4: 68db ldr r3, [r3, #12] + 8009ca6: 791a ldrb r2, [r3, #4] + 8009ca8: 7959 ldrb r1, [r3, #5] + 8009caa: 0209 lsls r1, r1, #8 + 8009cac: 430a orrs r2, r1 + 8009cae: 7999 ldrb r1, [r3, #6] + 8009cb0: 0409 lsls r1, r1, #16 + 8009cb2: 430a orrs r2, r1 + 8009cb4: 79db ldrb r3, [r3, #7] + 8009cb6: 061b lsls r3, r3, #24 + 8009cb8: 4313 orrs r3, r2 + 8009cba: 0018 movs r0, r3 + 8009cbc: f7fa fce9 bl 8004692 + 8009cc0: 0004 movs r4, r0 + 8009cc2: 69fb ldr r3, [r7, #28] + 8009cc4: 68db ldr r3, [r3, #12] + 8009cc6: 791a ldrb r2, [r3, #4] + 8009cc8: 7959 ldrb r1, [r3, #5] + 8009cca: 0209 lsls r1, r1, #8 + 8009ccc: 430a orrs r2, r1 + 8009cce: 7999 ldrb r1, [r3, #6] + 8009cd0: 0409 lsls r1, r1, #16 + 8009cd2: 430a orrs r2, r1 + 8009cd4: 79db ldrb r3, [r3, #7] + 8009cd6: 061b lsls r3, r3, #24 + 8009cd8: 4313 orrs r3, r2 + 8009cda: 0018 movs r0, r3 + 8009cdc: f7fa fcd9 bl 8004692 + 8009ce0: 0003 movs r3, r0 + 8009ce2: 1ae3 subs r3, r4, r3 + while (*cur_seg && + 8009ce4: d4d5 bmi.n 8009c92 + } + seg->next = (*cur_seg); + 8009ce6: 697b ldr r3, [r7, #20] + 8009ce8: 681a ldr r2, [r3, #0] + 8009cea: 69fb ldr r3, [r7, #28] + 8009cec: 601a str r2, [r3, #0] + (*cur_seg) = seg; + 8009cee: 697b ldr r3, [r7, #20] + 8009cf0: 69fa ldr r2, [r7, #28] + 8009cf2: 601a str r2, [r3, #0] + 8009cf4: e00a b.n 8009d0c + } else { + /* add segment to tail of unacked list */ + useg->next = seg; + 8009cf6: 69bb ldr r3, [r7, #24] + 8009cf8: 69fa ldr r2, [r7, #28] + 8009cfa: 601a str r2, [r3, #0] + useg = useg->next; + 8009cfc: 69bb ldr r3, [r7, #24] + 8009cfe: 681b ldr r3, [r3, #0] + 8009d00: 61bb str r3, [r7, #24] + 8009d02: e003 b.n 8009d0c + } + } + /* do not queue empty segments on the unacked list */ + } else { + tcp_seg_free(seg); + 8009d04: 69fb ldr r3, [r7, #28] + 8009d06: 0018 movs r0, r3 + 8009d08: f7fc fd09 bl 800671e + } + seg = pcb->unsent; + 8009d0c: 687b ldr r3, [r7, #4] + 8009d0e: 6edb ldr r3, [r3, #108] ; 0x6c + 8009d10: 61fb str r3, [r7, #28] + while (seg != NULL && + 8009d12: 69fb ldr r3, [r7, #28] + 8009d14: 2b00 cmp r3, #0 + 8009d16: d01e beq.n 8009d56 + ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len <= wnd) { + 8009d18: 69fb ldr r3, [r7, #28] + 8009d1a: 68db ldr r3, [r3, #12] + 8009d1c: 791a ldrb r2, [r3, #4] + 8009d1e: 7959 ldrb r1, [r3, #5] + 8009d20: 0209 lsls r1, r1, #8 + 8009d22: 430a orrs r2, r1 + 8009d24: 7999 ldrb r1, [r3, #6] + 8009d26: 0409 lsls r1, r1, #16 + 8009d28: 430a orrs r2, r1 + 8009d2a: 79db ldrb r3, [r3, #7] + 8009d2c: 061b lsls r3, r3, #24 + 8009d2e: 4313 orrs r3, r2 + 8009d30: 0018 movs r0, r3 + 8009d32: f7fa fcae bl 8004692 + 8009d36: 0002 movs r2, r0 + 8009d38: 687b ldr r3, [r7, #4] + 8009d3a: 6c9b ldr r3, [r3, #72] ; 0x48 + 8009d3c: 1ad3 subs r3, r2, r3 + 8009d3e: 69fa ldr r2, [r7, #28] + 8009d40: 8912 ldrh r2, [r2, #8] + 8009d42: 189b adds r3, r3, r2 + while (seg != NULL && + 8009d44: 693a ldr r2, [r7, #16] + 8009d46: 429a cmp r2, r3 + 8009d48: d300 bcc.n 8009d4c + 8009d4a: e6b7 b.n 8009abc + 8009d4c: e003 b.n 8009d56 + 8009d4e: 46c0 nop ; (mov r8, r8) + 8009d50: 2000328c .word 0x2000328c + break; + 8009d54: 46c0 nop ; (mov r8, r8) + } +#if TCP_OVERSIZE + if (pcb->unsent == NULL) { + 8009d56: 687b ldr r3, [r7, #4] + 8009d58: 6edb ldr r3, [r3, #108] ; 0x6c + 8009d5a: 2b00 cmp r3, #0 + 8009d5c: d103 bne.n 8009d66 + /* last unsent has been removed, reset unsent_oversize */ + pcb->unsent_oversize = 0; + 8009d5e: 687b ldr r3, [r7, #4] + 8009d60: 226a movs r2, #106 ; 0x6a + 8009d62: 2100 movs r1, #0 + 8009d64: 5299 strh r1, [r3, r2] + } +#endif /* TCP_OVERSIZE */ + + pcb->flags &= ~TF_NAGLEMEMERR; + 8009d66: 687b ldr r3, [r7, #4] + 8009d68: 7f9b ldrb r3, [r3, #30] + 8009d6a: 227f movs r2, #127 ; 0x7f + 8009d6c: 4013 ands r3, r2 + 8009d6e: b2da uxtb r2, r3 + 8009d70: 687b ldr r3, [r7, #4] + 8009d72: 779a strb r2, [r3, #30] + return ERR_OK; + 8009d74: 2300 movs r3, #0 +} + 8009d76: 0018 movs r0, r3 + 8009d78: 46bd mov sp, r7 + 8009d7a: b008 add sp, #32 + 8009d7c: bdb0 pop {r4, r5, r7, pc} + 8009d7e: 46c0 nop ; (mov r8, r8) + +08009d80 : + * @param seg the tcp_seg to send + * @param pcb the tcp_pcb for the TCP connection used to send the segment + */ +static void +tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb) +{ + 8009d80: b5b0 push {r4, r5, r7, lr} + 8009d82: b088 sub sp, #32 + 8009d84: af02 add r7, sp, #8 + 8009d86: 6078 str r0, [r7, #4] + 8009d88: 6039 str r1, [r7, #0] + /** @bug Exclude retransmitted segments from this count. */ + snmp_inc_tcpoutsegs(); + + /* The TCP header has already been constructed, but the ackno and + wnd fields remain. */ + seg->tcphdr->ackno = htonl(pcb->rcv_nxt); + 8009d8a: 683b ldr r3, [r7, #0] + 8009d8c: 6a9a ldr r2, [r3, #40] ; 0x28 + 8009d8e: 687b ldr r3, [r7, #4] + 8009d90: 68dc ldr r4, [r3, #12] + 8009d92: 0010 movs r0, r2 + 8009d94: f7fa fc64 bl 8004660 + 8009d98: 0003 movs r3, r0 + 8009d9a: 22ff movs r2, #255 ; 0xff + 8009d9c: 401a ands r2, r3 + 8009d9e: 0010 movs r0, r2 + 8009da0: 7a22 ldrb r2, [r4, #8] + 8009da2: 2100 movs r1, #0 + 8009da4: 400a ands r2, r1 + 8009da6: 1c11 adds r1, r2, #0 + 8009da8: 1c02 adds r2, r0, #0 + 8009daa: 430a orrs r2, r1 + 8009dac: 7222 strb r2, [r4, #8] + 8009dae: 0a1a lsrs r2, r3, #8 + 8009db0: 21ff movs r1, #255 ; 0xff + 8009db2: 400a ands r2, r1 + 8009db4: 0010 movs r0, r2 + 8009db6: 7a62 ldrb r2, [r4, #9] + 8009db8: 2100 movs r1, #0 + 8009dba: 400a ands r2, r1 + 8009dbc: 1c11 adds r1, r2, #0 + 8009dbe: 1c02 adds r2, r0, #0 + 8009dc0: 430a orrs r2, r1 + 8009dc2: 7262 strb r2, [r4, #9] + 8009dc4: 0c1a lsrs r2, r3, #16 + 8009dc6: 21ff movs r1, #255 ; 0xff + 8009dc8: 400a ands r2, r1 + 8009dca: 0010 movs r0, r2 + 8009dcc: 7aa2 ldrb r2, [r4, #10] + 8009dce: 2100 movs r1, #0 + 8009dd0: 400a ands r2, r1 + 8009dd2: 1c11 adds r1, r2, #0 + 8009dd4: 1c02 adds r2, r0, #0 + 8009dd6: 430a orrs r2, r1 + 8009dd8: 72a2 strb r2, [r4, #10] + 8009dda: 0e19 lsrs r1, r3, #24 + 8009ddc: 7ae3 ldrb r3, [r4, #11] + 8009dde: 2200 movs r2, #0 + 8009de0: 4013 ands r3, r2 + 8009de2: 1c1a adds r2, r3, #0 + 8009de4: 1c0b adds r3, r1, #0 + 8009de6: 4313 orrs r3, r2 + 8009de8: 72e3 strb r3, [r4, #11] + + /* advertise our receive window size in this TCP segment */ + seg->tcphdr->wnd = htons(pcb->rcv_ann_wnd); + 8009dea: 683b ldr r3, [r7, #0] + 8009dec: 8dda ldrh r2, [r3, #46] ; 0x2e + 8009dee: 687b ldr r3, [r7, #4] + 8009df0: 68dc ldr r4, [r3, #12] + 8009df2: 0010 movs r0, r2 + 8009df4: f7fa fc0e bl 8004614 + 8009df8: 0003 movs r3, r0 + 8009dfa: 22ff movs r2, #255 ; 0xff + 8009dfc: 401a ands r2, r3 + 8009dfe: 0010 movs r0, r2 + 8009e00: 7ba2 ldrb r2, [r4, #14] + 8009e02: 2100 movs r1, #0 + 8009e04: 400a ands r2, r1 + 8009e06: 1c11 adds r1, r2, #0 + 8009e08: 1c02 adds r2, r0, #0 + 8009e0a: 430a orrs r2, r1 + 8009e0c: 73a2 strb r2, [r4, #14] + 8009e0e: 0a1b lsrs r3, r3, #8 + 8009e10: b299 uxth r1, r3 + 8009e12: 7be3 ldrb r3, [r4, #15] + 8009e14: 2200 movs r2, #0 + 8009e16: 4013 ands r3, r2 + 8009e18: 1c1a adds r2, r3, #0 + 8009e1a: 1c0b adds r3, r1, #0 + 8009e1c: 4313 orrs r3, r2 + 8009e1e: 73e3 strb r3, [r4, #15] + + pcb->rcv_ann_right_edge = pcb->rcv_nxt + pcb->rcv_ann_wnd; + 8009e20: 683b ldr r3, [r7, #0] + 8009e22: 6a9b ldr r3, [r3, #40] ; 0x28 + 8009e24: 683a ldr r2, [r7, #0] + 8009e26: 8dd2 ldrh r2, [r2, #46] ; 0x2e + 8009e28: 189a adds r2, r3, r2 + 8009e2a: 683b ldr r3, [r7, #0] + 8009e2c: 631a str r2, [r3, #48] ; 0x30 + + /* Add any requested options. NB MSS option is only set on SYN + packets, so ignore it here */ + opts = (u32_t *)(void *)(seg->tcphdr + 1); + 8009e2e: 687b ldr r3, [r7, #4] + 8009e30: 68db ldr r3, [r3, #12] + 8009e32: 3314 adds r3, #20 + 8009e34: 617b str r3, [r7, #20] + if (seg->flags & TF_SEG_OPTS_MSS) { + 8009e36: 687b ldr r3, [r7, #4] + 8009e38: 7a9b ldrb r3, [r3, #10] + 8009e3a: 001a movs r2, r3 + 8009e3c: 2301 movs r3, #1 + 8009e3e: 4013 ands r3, r2 + 8009e40: d018 beq.n 8009e74 + u16_t mss; +#if TCP_CALCULATE_EFF_SEND_MSS + mss = tcp_eff_send_mss(TCP_MSS, &pcb->remote_ip); + 8009e42: 683b ldr r3, [r7, #0] + 8009e44: 3304 adds r3, #4 + 8009e46: 2512 movs r5, #18 + 8009e48: 197c adds r4, r7, r5 + 8009e4a: 4a5d ldr r2, [pc, #372] ; (8009fc0 ) + 8009e4c: 0019 movs r1, r3 + 8009e4e: 0010 movs r0, r2 + 8009e50: f7fc fe92 bl 8006b78 + 8009e54: 0003 movs r3, r0 + 8009e56: 8023 strh r3, [r4, #0] +#else /* TCP_CALCULATE_EFF_SEND_MSS */ + mss = TCP_MSS; +#endif /* TCP_CALCULATE_EFF_SEND_MSS */ + *opts = TCP_BUILD_MSS_OPTION(mss); + 8009e58: 197b adds r3, r7, r5 + 8009e5a: 881b ldrh r3, [r3, #0] + 8009e5c: 2281 movs r2, #129 ; 0x81 + 8009e5e: 0492 lsls r2, r2, #18 + 8009e60: 4313 orrs r3, r2 + 8009e62: 0018 movs r0, r3 + 8009e64: f7fa fbfc bl 8004660 + 8009e68: 0002 movs r2, r0 + 8009e6a: 697b ldr r3, [r7, #20] + 8009e6c: 601a str r2, [r3, #0] + opts += 1; + 8009e6e: 697b ldr r3, [r7, #20] + 8009e70: 3304 adds r3, #4 + 8009e72: 617b str r3, [r7, #20] + } +#endif + + /* Set retransmission timer running if it is not currently enabled + This must be set before checking the route. */ + if (pcb->rtime == -1) { + 8009e74: 683b ldr r3, [r7, #0] + 8009e76: 2234 movs r2, #52 ; 0x34 + 8009e78: 5e9b ldrsh r3, [r3, r2] + 8009e7a: 3301 adds r3, #1 + 8009e7c: d102 bne.n 8009e84 + pcb->rtime = 0; + 8009e7e: 683b ldr r3, [r7, #0] + 8009e80: 2200 movs r2, #0 + 8009e82: 869a strh r2, [r3, #52] ; 0x34 + } + + /* If we don't have a local IP address, we get one by + calling ip_route(). */ + if (ip_addr_isany(&(pcb->local_ip))) { + 8009e84: 683b ldr r3, [r7, #0] + 8009e86: 2b00 cmp r3, #0 + 8009e88: d003 beq.n 8009e92 + 8009e8a: 683b ldr r3, [r7, #0] + 8009e8c: 681b ldr r3, [r3, #0] + 8009e8e: 2b00 cmp r3, #0 + 8009e90: d10e bne.n 8009eb0 + netif = ip_route(&(pcb->remote_ip)); + 8009e92: 683b ldr r3, [r7, #0] + 8009e94: 3304 adds r3, #4 + 8009e96: 0018 movs r0, r3 + 8009e98: f001 fcd6 bl 800b848 + 8009e9c: 0003 movs r3, r0 + 8009e9e: 60fb str r3, [r7, #12] + if (netif == NULL) { + 8009ea0: 68fb ldr r3, [r7, #12] + 8009ea2: 2b00 cmp r3, #0 + 8009ea4: d100 bne.n 8009ea8 + 8009ea6: e086 b.n 8009fb6 + return; + } + ip_addr_copy(pcb->local_ip, netif->ip_addr); + 8009ea8: 68fb ldr r3, [r7, #12] + 8009eaa: 685a ldr r2, [r3, #4] + 8009eac: 683b ldr r3, [r7, #0] + 8009eae: 601a str r2, [r3, #0] + } + + if (pcb->rttest == 0) { + 8009eb0: 683b ldr r3, [r7, #0] + 8009eb2: 6b9b ldr r3, [r3, #56] ; 0x38 + 8009eb4: 2b00 cmp r3, #0 + 8009eb6: d115 bne.n 8009ee4 + pcb->rttest = tcp_ticks; + 8009eb8: 4b42 ldr r3, [pc, #264] ; (8009fc4 ) + 8009eba: 681a ldr r2, [r3, #0] + 8009ebc: 683b ldr r3, [r7, #0] + 8009ebe: 639a str r2, [r3, #56] ; 0x38 + pcb->rtseq = ntohl(seg->tcphdr->seqno); + 8009ec0: 687b ldr r3, [r7, #4] + 8009ec2: 68db ldr r3, [r3, #12] + 8009ec4: 791a ldrb r2, [r3, #4] + 8009ec6: 7959 ldrb r1, [r3, #5] + 8009ec8: 0209 lsls r1, r1, #8 + 8009eca: 430a orrs r2, r1 + 8009ecc: 7999 ldrb r1, [r3, #6] + 8009ece: 0409 lsls r1, r1, #16 + 8009ed0: 430a orrs r2, r1 + 8009ed2: 79db ldrb r3, [r3, #7] + 8009ed4: 061b lsls r3, r3, #24 + 8009ed6: 4313 orrs r3, r2 + 8009ed8: 0018 movs r0, r3 + 8009eda: f7fa fbda bl 8004692 + 8009ede: 0002 movs r2, r0 + 8009ee0: 683b ldr r3, [r7, #0] + 8009ee2: 63da str r2, [r3, #60] ; 0x3c + } + LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_output_segment: %"U32_F":%"U32_F"\n", + htonl(seg->tcphdr->seqno), htonl(seg->tcphdr->seqno) + + seg->len)); + + len = (u16_t)((u8_t *)seg->tcphdr - (u8_t *)seg->p->payload); + 8009ee4: 687b ldr r3, [r7, #4] + 8009ee6: 68db ldr r3, [r3, #12] + 8009ee8: 001a movs r2, r3 + 8009eea: 687b ldr r3, [r7, #4] + 8009eec: 685b ldr r3, [r3, #4] + 8009eee: 685b ldr r3, [r3, #4] + 8009ef0: 1ad2 subs r2, r2, r3 + 8009ef2: 200a movs r0, #10 + 8009ef4: 183b adds r3, r7, r0 + 8009ef6: 801a strh r2, [r3, #0] + + seg->p->len -= len; + 8009ef8: 687b ldr r3, [r7, #4] + 8009efa: 685b ldr r3, [r3, #4] + 8009efc: 8959 ldrh r1, [r3, #10] + 8009efe: 687b ldr r3, [r7, #4] + 8009f00: 685b ldr r3, [r3, #4] + 8009f02: 183a adds r2, r7, r0 + 8009f04: 8812 ldrh r2, [r2, #0] + 8009f06: 1a8a subs r2, r1, r2 + 8009f08: b292 uxth r2, r2 + 8009f0a: 815a strh r2, [r3, #10] + seg->p->tot_len -= len; + 8009f0c: 687b ldr r3, [r7, #4] + 8009f0e: 685b ldr r3, [r3, #4] + 8009f10: 8919 ldrh r1, [r3, #8] + 8009f12: 687b ldr r3, [r7, #4] + 8009f14: 685b ldr r3, [r3, #4] + 8009f16: 183a adds r2, r7, r0 + 8009f18: 8812 ldrh r2, [r2, #0] + 8009f1a: 1a8a subs r2, r1, r2 + 8009f1c: b292 uxth r2, r2 + 8009f1e: 811a strh r2, [r3, #8] + + seg->p->payload = seg->tcphdr; + 8009f20: 687b ldr r3, [r7, #4] + 8009f22: 685b ldr r3, [r3, #4] + 8009f24: 687a ldr r2, [r7, #4] + 8009f26: 68d2 ldr r2, [r2, #12] + 8009f28: 605a str r2, [r3, #4] + + seg->tcphdr->chksum = 0; + 8009f2a: 687b ldr r3, [r7, #4] + 8009f2c: 68db ldr r3, [r3, #12] + 8009f2e: 7c1a ldrb r2, [r3, #16] + 8009f30: 2100 movs r1, #0 + 8009f32: 400a ands r2, r1 + 8009f34: 741a strb r2, [r3, #16] + 8009f36: 7c5a ldrb r2, [r3, #17] + 8009f38: 2100 movs r1, #0 + 8009f3a: 400a ands r2, r1 + 8009f3c: 745a strb r2, [r3, #17] + seg->tcphdr->chksum = chksum_slow; + } +#endif /* TCP_CHECKSUM_ON_COPY_SANITY_CHECK */ + } +#else /* TCP_CHECKSUM_ON_COPY */ + seg->tcphdr->chksum = inet_chksum_pseudo(seg->p, &(pcb->local_ip), + 8009f3e: 687b ldr r3, [r7, #4] + 8009f40: 6858 ldr r0, [r3, #4] + 8009f42: 6839 ldr r1, [r7, #0] + 8009f44: 683b ldr r3, [r7, #0] + 8009f46: 1d1d adds r5, r3, #4 + &(pcb->remote_ip), + IP_PROTO_TCP, seg->p->tot_len); + 8009f48: 687b ldr r3, [r7, #4] + 8009f4a: 685b ldr r3, [r3, #4] + seg->tcphdr->chksum = inet_chksum_pseudo(seg->p, &(pcb->local_ip), + 8009f4c: 891a ldrh r2, [r3, #8] + 8009f4e: 687b ldr r3, [r7, #4] + 8009f50: 68dc ldr r4, [r3, #12] + 8009f52: 9200 str r2, [sp, #0] + 8009f54: 2306 movs r3, #6 + 8009f56: 002a movs r2, r5 + 8009f58: f001 fb6f bl 800b63a + 8009f5c: 0003 movs r3, r0 + 8009f5e: 22ff movs r2, #255 ; 0xff + 8009f60: 401a ands r2, r3 + 8009f62: 0010 movs r0, r2 + 8009f64: 7c22 ldrb r2, [r4, #16] + 8009f66: 2100 movs r1, #0 + 8009f68: 400a ands r2, r1 + 8009f6a: 1c11 adds r1, r2, #0 + 8009f6c: 1c02 adds r2, r0, #0 + 8009f6e: 430a orrs r2, r1 + 8009f70: 7422 strb r2, [r4, #16] + 8009f72: 0a1b lsrs r3, r3, #8 + 8009f74: b299 uxth r1, r3 + 8009f76: 7c63 ldrb r3, [r4, #17] + 8009f78: 2200 movs r2, #0 + 8009f7a: 4013 ands r3, r2 + 8009f7c: 1c1a adds r2, r3, #0 + 8009f7e: 1c0b adds r3, r1, #0 + 8009f80: 4313 orrs r3, r2 + 8009f82: 7463 strb r3, [r4, #17] +#endif /* TCP_CHECKSUM_ON_COPY */ +#endif /* CHECKSUM_GEN_TCP */ + TCP_STATS_INC(tcp.xmit); + 8009f84: 4b10 ldr r3, [pc, #64] ; (8009fc8 ) + 8009f86: 2290 movs r2, #144 ; 0x90 + 8009f88: 5a9b ldrh r3, [r3, r2] + 8009f8a: 3301 adds r3, #1 + 8009f8c: b299 uxth r1, r3 + 8009f8e: 4b0e ldr r3, [pc, #56] ; (8009fc8 ) + 8009f90: 2290 movs r2, #144 ; 0x90 + 8009f92: 5299 strh r1, [r3, r2] + +#if LWIP_NETIF_HWADDRHINT + ip_output_hinted(seg->p, &(pcb->local_ip), &(pcb->remote_ip), pcb->ttl, pcb->tos, + IP_PROTO_TCP, &(pcb->addr_hint)); +#else /* LWIP_NETIF_HWADDRHINT*/ + ip_output(seg->p, &(pcb->local_ip), &(pcb->remote_ip), pcb->ttl, pcb->tos, + 8009f94: 687b ldr r3, [r7, #4] + 8009f96: 6858 ldr r0, [r3, #4] + 8009f98: 6839 ldr r1, [r7, #0] + 8009f9a: 683b ldr r3, [r7, #0] + 8009f9c: 1d1c adds r4, r3, #4 + 8009f9e: 683b ldr r3, [r7, #0] + 8009fa0: 7a9d ldrb r5, [r3, #10] + 8009fa2: 683b ldr r3, [r7, #0] + 8009fa4: 7a5b ldrb r3, [r3, #9] + 8009fa6: 2206 movs r2, #6 + 8009fa8: 9201 str r2, [sp, #4] + 8009faa: 9300 str r3, [sp, #0] + 8009fac: 002b movs r3, r5 + 8009fae: 0022 movs r2, r4 + 8009fb0: f002 f82e bl 800c010 + 8009fb4: e000 b.n 8009fb8 + return; + 8009fb6: 46c0 nop ; (mov r8, r8) + IP_PROTO_TCP); +#endif /* LWIP_NETIF_HWADDRHINT*/ +} + 8009fb8: 46bd mov sp, r7 + 8009fba: b006 add sp, #24 + 8009fbc: bdb0 pop {r4, r5, r7, pc} + 8009fbe: 46c0 nop ; (mov r8, r8) + 8009fc0: 000005b4 .word 0x000005b4 + 8009fc4: 20003278 .word 0x20003278 + 8009fc8: 20003158 .word 0x20003158 + +08009fcc : + */ +void +tcp_rst(u32_t seqno, u32_t ackno, + ip_addr_t *local_ip, ip_addr_t *remote_ip, + u16_t local_port, u16_t remote_port) +{ + 8009fcc: b590 push {r4, r7, lr} + 8009fce: b089 sub sp, #36 ; 0x24 + 8009fd0: af02 add r7, sp, #8 + 8009fd2: 60f8 str r0, [r7, #12] + 8009fd4: 60b9 str r1, [r7, #8] + 8009fd6: 607a str r2, [r7, #4] + 8009fd8: 603b str r3, [r7, #0] + struct pbuf *p; + struct tcp_hdr *tcphdr; + p = pbuf_alloc(PBUF_IP, TCP_HLEN, PBUF_RAM); + 8009fda: 2200 movs r2, #0 + 8009fdc: 2114 movs r1, #20 + 8009fde: 2001 movs r0, #1 + 8009fe0: f7fb f8d4 bl 800518c + 8009fe4: 0003 movs r3, r0 + 8009fe6: 617b str r3, [r7, #20] + if (p == NULL) { + 8009fe8: 697b ldr r3, [r7, #20] + 8009fea: 2b00 cmp r3, #0 + 8009fec: d100 bne.n 8009ff0 + 8009fee: e108 b.n 800a202 + return; + } + LWIP_ASSERT("check that first pbuf can hold struct tcp_hdr", + (p->len >= sizeof(struct tcp_hdr))); + + tcphdr = (struct tcp_hdr *)p->payload; + 8009ff0: 697b ldr r3, [r7, #20] + 8009ff2: 685b ldr r3, [r3, #4] + 8009ff4: 613b str r3, [r7, #16] + tcphdr->src = htons(local_port); + 8009ff6: 2328 movs r3, #40 ; 0x28 + 8009ff8: 18fb adds r3, r7, r3 + 8009ffa: 881b ldrh r3, [r3, #0] + 8009ffc: 0018 movs r0, r3 + 8009ffe: f7fa fb09 bl 8004614 + 800a002: 0003 movs r3, r0 + 800a004: 001a movs r2, r3 + 800a006: 693b ldr r3, [r7, #16] + 800a008: 21ff movs r1, #255 ; 0xff + 800a00a: 4011 ands r1, r2 + 800a00c: 000c movs r4, r1 + 800a00e: 7819 ldrb r1, [r3, #0] + 800a010: 2000 movs r0, #0 + 800a012: 4001 ands r1, r0 + 800a014: 1c08 adds r0, r1, #0 + 800a016: 1c21 adds r1, r4, #0 + 800a018: 4301 orrs r1, r0 + 800a01a: 7019 strb r1, [r3, #0] + 800a01c: 0a12 lsrs r2, r2, #8 + 800a01e: b290 uxth r0, r2 + 800a020: 785a ldrb r2, [r3, #1] + 800a022: 2100 movs r1, #0 + 800a024: 400a ands r2, r1 + 800a026: 1c11 adds r1, r2, #0 + 800a028: 1c02 adds r2, r0, #0 + 800a02a: 430a orrs r2, r1 + 800a02c: 705a strb r2, [r3, #1] + tcphdr->dest = htons(remote_port); + 800a02e: 232c movs r3, #44 ; 0x2c + 800a030: 18fb adds r3, r7, r3 + 800a032: 881b ldrh r3, [r3, #0] + 800a034: 0018 movs r0, r3 + 800a036: f7fa faed bl 8004614 + 800a03a: 0003 movs r3, r0 + 800a03c: 001a movs r2, r3 + 800a03e: 693b ldr r3, [r7, #16] + 800a040: 21ff movs r1, #255 ; 0xff + 800a042: 4011 ands r1, r2 + 800a044: 000c movs r4, r1 + 800a046: 7899 ldrb r1, [r3, #2] + 800a048: 2000 movs r0, #0 + 800a04a: 4001 ands r1, r0 + 800a04c: 1c08 adds r0, r1, #0 + 800a04e: 1c21 adds r1, r4, #0 + 800a050: 4301 orrs r1, r0 + 800a052: 7099 strb r1, [r3, #2] + 800a054: 0a12 lsrs r2, r2, #8 + 800a056: b290 uxth r0, r2 + 800a058: 78da ldrb r2, [r3, #3] + 800a05a: 2100 movs r1, #0 + 800a05c: 400a ands r2, r1 + 800a05e: 1c11 adds r1, r2, #0 + 800a060: 1c02 adds r2, r0, #0 + 800a062: 430a orrs r2, r1 + 800a064: 70da strb r2, [r3, #3] + tcphdr->seqno = htonl(seqno); + 800a066: 68fb ldr r3, [r7, #12] + 800a068: 0018 movs r0, r3 + 800a06a: f7fa faf9 bl 8004660 + 800a06e: 0002 movs r2, r0 + 800a070: 693b ldr r3, [r7, #16] + 800a072: 21ff movs r1, #255 ; 0xff + 800a074: 4011 ands r1, r2 + 800a076: 000c movs r4, r1 + 800a078: 7919 ldrb r1, [r3, #4] + 800a07a: 2000 movs r0, #0 + 800a07c: 4001 ands r1, r0 + 800a07e: 1c08 adds r0, r1, #0 + 800a080: 1c21 adds r1, r4, #0 + 800a082: 4301 orrs r1, r0 + 800a084: 7119 strb r1, [r3, #4] + 800a086: 0a11 lsrs r1, r2, #8 + 800a088: 20ff movs r0, #255 ; 0xff + 800a08a: 4001 ands r1, r0 + 800a08c: 000c movs r4, r1 + 800a08e: 7959 ldrb r1, [r3, #5] + 800a090: 2000 movs r0, #0 + 800a092: 4001 ands r1, r0 + 800a094: 1c08 adds r0, r1, #0 + 800a096: 1c21 adds r1, r4, #0 + 800a098: 4301 orrs r1, r0 + 800a09a: 7159 strb r1, [r3, #5] + 800a09c: 0c11 lsrs r1, r2, #16 + 800a09e: 20ff movs r0, #255 ; 0xff + 800a0a0: 4001 ands r1, r0 + 800a0a2: 000c movs r4, r1 + 800a0a4: 7999 ldrb r1, [r3, #6] + 800a0a6: 2000 movs r0, #0 + 800a0a8: 4001 ands r1, r0 + 800a0aa: 1c08 adds r0, r1, #0 + 800a0ac: 1c21 adds r1, r4, #0 + 800a0ae: 4301 orrs r1, r0 + 800a0b0: 7199 strb r1, [r3, #6] + 800a0b2: 0e10 lsrs r0, r2, #24 + 800a0b4: 79da ldrb r2, [r3, #7] + 800a0b6: 2100 movs r1, #0 + 800a0b8: 400a ands r2, r1 + 800a0ba: 1c11 adds r1, r2, #0 + 800a0bc: 1c02 adds r2, r0, #0 + 800a0be: 430a orrs r2, r1 + 800a0c0: 71da strb r2, [r3, #7] + tcphdr->ackno = htonl(ackno); + 800a0c2: 68bb ldr r3, [r7, #8] + 800a0c4: 0018 movs r0, r3 + 800a0c6: f7fa facb bl 8004660 + 800a0ca: 0002 movs r2, r0 + 800a0cc: 693b ldr r3, [r7, #16] + 800a0ce: 21ff movs r1, #255 ; 0xff + 800a0d0: 4011 ands r1, r2 + 800a0d2: 000c movs r4, r1 + 800a0d4: 7a19 ldrb r1, [r3, #8] + 800a0d6: 2000 movs r0, #0 + 800a0d8: 4001 ands r1, r0 + 800a0da: 1c08 adds r0, r1, #0 + 800a0dc: 1c21 adds r1, r4, #0 + 800a0de: 4301 orrs r1, r0 + 800a0e0: 7219 strb r1, [r3, #8] + 800a0e2: 0a11 lsrs r1, r2, #8 + 800a0e4: 20ff movs r0, #255 ; 0xff + 800a0e6: 4001 ands r1, r0 + 800a0e8: 000c movs r4, r1 + 800a0ea: 7a59 ldrb r1, [r3, #9] + 800a0ec: 2000 movs r0, #0 + 800a0ee: 4001 ands r1, r0 + 800a0f0: 1c08 adds r0, r1, #0 + 800a0f2: 1c21 adds r1, r4, #0 + 800a0f4: 4301 orrs r1, r0 + 800a0f6: 7259 strb r1, [r3, #9] + 800a0f8: 0c11 lsrs r1, r2, #16 + 800a0fa: 20ff movs r0, #255 ; 0xff + 800a0fc: 4001 ands r1, r0 + 800a0fe: 000c movs r4, r1 + 800a100: 7a99 ldrb r1, [r3, #10] + 800a102: 2000 movs r0, #0 + 800a104: 4001 ands r1, r0 + 800a106: 1c08 adds r0, r1, #0 + 800a108: 1c21 adds r1, r4, #0 + 800a10a: 4301 orrs r1, r0 + 800a10c: 7299 strb r1, [r3, #10] + 800a10e: 0e10 lsrs r0, r2, #24 + 800a110: 7ada ldrb r2, [r3, #11] + 800a112: 2100 movs r1, #0 + 800a114: 400a ands r2, r1 + 800a116: 1c11 adds r1, r2, #0 + 800a118: 1c02 adds r2, r0, #0 + 800a11a: 430a orrs r2, r1 + 800a11c: 72da strb r2, [r3, #11] + TCPH_HDRLEN_FLAGS_SET(tcphdr, TCP_HLEN/4, TCP_RST | TCP_ACK); + 800a11e: 4b3b ldr r3, [pc, #236] ; (800a20c ) + 800a120: 0018 movs r0, r3 + 800a122: f7fa fa77 bl 8004614 + 800a126: 0003 movs r3, r0 + 800a128: 001a movs r2, r3 + 800a12a: 693b ldr r3, [r7, #16] + 800a12c: 21ff movs r1, #255 ; 0xff + 800a12e: 4011 ands r1, r2 + 800a130: 000c movs r4, r1 + 800a132: 7b19 ldrb r1, [r3, #12] + 800a134: 2000 movs r0, #0 + 800a136: 4001 ands r1, r0 + 800a138: 1c08 adds r0, r1, #0 + 800a13a: 1c21 adds r1, r4, #0 + 800a13c: 4301 orrs r1, r0 + 800a13e: 7319 strb r1, [r3, #12] + 800a140: 0a12 lsrs r2, r2, #8 + 800a142: b290 uxth r0, r2 + 800a144: 7b5a ldrb r2, [r3, #13] + 800a146: 2100 movs r1, #0 + 800a148: 400a ands r2, r1 + 800a14a: 1c11 adds r1, r2, #0 + 800a14c: 1c02 adds r2, r0, #0 + 800a14e: 430a orrs r2, r1 + 800a150: 735a strb r2, [r3, #13] + tcphdr->wnd = PP_HTONS(TCP_WND); + 800a152: 693b ldr r3, [r7, #16] + 800a154: 7b9a ldrb r2, [r3, #14] + 800a156: 2100 movs r1, #0 + 800a158: 400a ands r2, r1 + 800a15a: 1c11 adds r1, r2, #0 + 800a15c: 2216 movs r2, #22 + 800a15e: 430a orrs r2, r1 + 800a160: 739a strb r2, [r3, #14] + 800a162: 7bda ldrb r2, [r3, #15] + 800a164: 2100 movs r1, #0 + 800a166: 400a ands r2, r1 + 800a168: 1c11 adds r1, r2, #0 + 800a16a: 2230 movs r2, #48 ; 0x30 + 800a16c: 4252 negs r2, r2 + 800a16e: 430a orrs r2, r1 + 800a170: 73da strb r2, [r3, #15] + tcphdr->chksum = 0; + 800a172: 693b ldr r3, [r7, #16] + 800a174: 7c1a ldrb r2, [r3, #16] + 800a176: 2100 movs r1, #0 + 800a178: 400a ands r2, r1 + 800a17a: 741a strb r2, [r3, #16] + 800a17c: 7c5a ldrb r2, [r3, #17] + 800a17e: 2100 movs r1, #0 + 800a180: 400a ands r2, r1 + 800a182: 745a strb r2, [r3, #17] + tcphdr->urgp = 0; + 800a184: 693b ldr r3, [r7, #16] + 800a186: 7c9a ldrb r2, [r3, #18] + 800a188: 2100 movs r1, #0 + 800a18a: 400a ands r2, r1 + 800a18c: 749a strb r2, [r3, #18] + 800a18e: 7cda ldrb r2, [r3, #19] + 800a190: 2100 movs r1, #0 + 800a192: 400a ands r2, r1 + 800a194: 74da strb r2, [r3, #19] + +#if CHECKSUM_GEN_TCP + tcphdr->chksum = inet_chksum_pseudo(p, local_ip, remote_ip, + 800a196: 697b ldr r3, [r7, #20] + 800a198: 891b ldrh r3, [r3, #8] + 800a19a: 683a ldr r2, [r7, #0] + 800a19c: 6879 ldr r1, [r7, #4] + 800a19e: 6978 ldr r0, [r7, #20] + 800a1a0: 9300 str r3, [sp, #0] + 800a1a2: 2306 movs r3, #6 + 800a1a4: f001 fa49 bl 800b63a + 800a1a8: 0003 movs r3, r0 + 800a1aa: 001a movs r2, r3 + 800a1ac: 693b ldr r3, [r7, #16] + 800a1ae: 21ff movs r1, #255 ; 0xff + 800a1b0: 4011 ands r1, r2 + 800a1b2: 000c movs r4, r1 + 800a1b4: 7c19 ldrb r1, [r3, #16] + 800a1b6: 2000 movs r0, #0 + 800a1b8: 4001 ands r1, r0 + 800a1ba: 1c08 adds r0, r1, #0 + 800a1bc: 1c21 adds r1, r4, #0 + 800a1be: 4301 orrs r1, r0 + 800a1c0: 7419 strb r1, [r3, #16] + 800a1c2: 0a12 lsrs r2, r2, #8 + 800a1c4: b290 uxth r0, r2 + 800a1c6: 7c5a ldrb r2, [r3, #17] + 800a1c8: 2100 movs r1, #0 + 800a1ca: 400a ands r2, r1 + 800a1cc: 1c11 adds r1, r2, #0 + 800a1ce: 1c02 adds r2, r0, #0 + 800a1d0: 430a orrs r2, r1 + 800a1d2: 745a strb r2, [r3, #17] + IP_PROTO_TCP, p->tot_len); +#endif + TCP_STATS_INC(tcp.xmit); + 800a1d4: 4b0e ldr r3, [pc, #56] ; (800a210 ) + 800a1d6: 2290 movs r2, #144 ; 0x90 + 800a1d8: 5a9b ldrh r3, [r3, r2] + 800a1da: 3301 adds r3, #1 + 800a1dc: b299 uxth r1, r3 + 800a1de: 4b0c ldr r3, [pc, #48] ; (800a210 ) + 800a1e0: 2290 movs r2, #144 ; 0x90 + 800a1e2: 5299 strh r1, [r3, r2] + snmp_inc_tcpoutrsts(); + /* Send output with hardcoded TTL since we have no access to the pcb */ + ip_output(p, local_ip, remote_ip, TCP_TTL, 0, IP_PROTO_TCP); + 800a1e4: 683a ldr r2, [r7, #0] + 800a1e6: 6879 ldr r1, [r7, #4] + 800a1e8: 6978 ldr r0, [r7, #20] + 800a1ea: 2306 movs r3, #6 + 800a1ec: 9301 str r3, [sp, #4] + 800a1ee: 2300 movs r3, #0 + 800a1f0: 9300 str r3, [sp, #0] + 800a1f2: 23ff movs r3, #255 ; 0xff + 800a1f4: f001 ff0c bl 800c010 + pbuf_free(p); + 800a1f8: 697b ldr r3, [r7, #20] + 800a1fa: 0018 movs r0, r3 + 800a1fc: f7fb fa52 bl 80056a4 + 800a200: e000 b.n 800a204 + return; + 800a202: 46c0 nop ; (mov r8, r8) + LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_rst: seqno %"U32_F" ackno %"U32_F".\n", seqno, ackno)); +} + 800a204: 46bd mov sp, r7 + 800a206: b007 add sp, #28 + 800a208: bd90 pop {r4, r7, pc} + 800a20a: 46c0 nop ; (mov r8, r8) + 800a20c: 00005014 .word 0x00005014 + 800a210: 20003158 .word 0x20003158 + +0800a214 : + * + * @param pcb the tcp_pcb for which to re-enqueue all unacked segments + */ +void +tcp_rexmit_rto(struct tcp_pcb *pcb) +{ + 800a214: b580 push {r7, lr} + 800a216: b084 sub sp, #16 + 800a218: af00 add r7, sp, #0 + 800a21a: 6078 str r0, [r7, #4] + struct tcp_seg *seg; + + if (pcb->unacked == NULL) { + 800a21c: 687b ldr r3, [r7, #4] + 800a21e: 6f1b ldr r3, [r3, #112] ; 0x70 + 800a220: 2b00 cmp r3, #0 + 800a222: d025 beq.n 800a270 + return; + } + + /* Move all unacked segments to the head of the unsent queue */ + for (seg = pcb->unacked; seg->next != NULL; seg = seg->next); + 800a224: 687b ldr r3, [r7, #4] + 800a226: 6f1b ldr r3, [r3, #112] ; 0x70 + 800a228: 60fb str r3, [r7, #12] + 800a22a: e002 b.n 800a232 + 800a22c: 68fb ldr r3, [r7, #12] + 800a22e: 681b ldr r3, [r3, #0] + 800a230: 60fb str r3, [r7, #12] + 800a232: 68fb ldr r3, [r7, #12] + 800a234: 681b ldr r3, [r3, #0] + 800a236: 2b00 cmp r3, #0 + 800a238: d1f8 bne.n 800a22c + /* concatenate unsent queue after unacked queue */ + seg->next = pcb->unsent; + 800a23a: 687b ldr r3, [r7, #4] + 800a23c: 6eda ldr r2, [r3, #108] ; 0x6c + 800a23e: 68fb ldr r3, [r7, #12] + 800a240: 601a str r2, [r3, #0] + /* unsent queue is the concatenated queue (of unacked, unsent) */ + pcb->unsent = pcb->unacked; + 800a242: 687b ldr r3, [r7, #4] + 800a244: 6f1a ldr r2, [r3, #112] ; 0x70 + 800a246: 687b ldr r3, [r7, #4] + 800a248: 66da str r2, [r3, #108] ; 0x6c + /* unacked queue is now empty */ + pcb->unacked = NULL; + 800a24a: 687b ldr r3, [r7, #4] + 800a24c: 2200 movs r2, #0 + 800a24e: 671a str r2, [r3, #112] ; 0x70 + /* last unsent hasn't changed, no need to reset unsent_oversize */ + + /* increment number of retransmissions */ + ++pcb->nrtx; + 800a250: 687b ldr r3, [r7, #4] + 800a252: 2246 movs r2, #70 ; 0x46 + 800a254: 5c9b ldrb r3, [r3, r2] + 800a256: 3301 adds r3, #1 + 800a258: b2d9 uxtb r1, r3 + 800a25a: 687b ldr r3, [r7, #4] + 800a25c: 2246 movs r2, #70 ; 0x46 + 800a25e: 5499 strb r1, [r3, r2] + + /* Don't take any RTT measurements after retransmitting. */ + pcb->rttest = 0; + 800a260: 687b ldr r3, [r7, #4] + 800a262: 2200 movs r2, #0 + 800a264: 639a str r2, [r3, #56] ; 0x38 + + /* Do the actual retransmission */ + tcp_output(pcb); + 800a266: 687b ldr r3, [r7, #4] + 800a268: 0018 movs r0, r3 + 800a26a: f7ff fbd1 bl 8009a10 + 800a26e: e000 b.n 800a272 + return; + 800a270: 46c0 nop ; (mov r8, r8) +} + 800a272: 46bd mov sp, r7 + 800a274: b004 add sp, #16 + 800a276: bd80 pop {r7, pc} + +0800a278 : + * + * @param pcb the tcp_pcb for which to retransmit the first unacked segment + */ +void +tcp_rexmit(struct tcp_pcb *pcb) +{ + 800a278: b590 push {r4, r7, lr} + 800a27a: b085 sub sp, #20 + 800a27c: af00 add r7, sp, #0 + 800a27e: 6078 str r0, [r7, #4] + struct tcp_seg *seg; + struct tcp_seg **cur_seg; + + if (pcb->unacked == NULL) { + 800a280: 687b ldr r3, [r7, #4] + 800a282: 6f1b ldr r3, [r3, #112] ; 0x70 + 800a284: 2b00 cmp r3, #0 + 800a286: d04f beq.n 800a328 + return; + } + + /* Move the first unacked segment to the unsent queue */ + /* Keep the unsent queue sorted. */ + seg = pcb->unacked; + 800a288: 687b ldr r3, [r7, #4] + 800a28a: 6f1b ldr r3, [r3, #112] ; 0x70 + 800a28c: 60bb str r3, [r7, #8] + pcb->unacked = seg->next; + 800a28e: 68bb ldr r3, [r7, #8] + 800a290: 681a ldr r2, [r3, #0] + 800a292: 687b ldr r3, [r7, #4] + 800a294: 671a str r2, [r3, #112] ; 0x70 + + cur_seg = &(pcb->unsent); + 800a296: 687b ldr r3, [r7, #4] + 800a298: 336c adds r3, #108 ; 0x6c + 800a29a: 60fb str r3, [r7, #12] + while (*cur_seg && + 800a29c: e002 b.n 800a2a4 + TCP_SEQ_LT(ntohl((*cur_seg)->tcphdr->seqno), ntohl(seg->tcphdr->seqno))) { + cur_seg = &((*cur_seg)->next ); + 800a29e: 68fb ldr r3, [r7, #12] + 800a2a0: 681b ldr r3, [r3, #0] + 800a2a2: 60fb str r3, [r7, #12] + while (*cur_seg && + 800a2a4: 68fb ldr r3, [r7, #12] + 800a2a6: 681b ldr r3, [r3, #0] + 800a2a8: 2b00 cmp r3, #0 + 800a2aa: d022 beq.n 800a2f2 + TCP_SEQ_LT(ntohl((*cur_seg)->tcphdr->seqno), ntohl(seg->tcphdr->seqno))) { + 800a2ac: 68fb ldr r3, [r7, #12] + 800a2ae: 681b ldr r3, [r3, #0] + 800a2b0: 68db ldr r3, [r3, #12] + 800a2b2: 791a ldrb r2, [r3, #4] + 800a2b4: 7959 ldrb r1, [r3, #5] + 800a2b6: 0209 lsls r1, r1, #8 + 800a2b8: 430a orrs r2, r1 + 800a2ba: 7999 ldrb r1, [r3, #6] + 800a2bc: 0409 lsls r1, r1, #16 + 800a2be: 430a orrs r2, r1 + 800a2c0: 79db ldrb r3, [r3, #7] + 800a2c2: 061b lsls r3, r3, #24 + 800a2c4: 4313 orrs r3, r2 + 800a2c6: 0018 movs r0, r3 + 800a2c8: f7fa f9e3 bl 8004692 + 800a2cc: 0004 movs r4, r0 + 800a2ce: 68bb ldr r3, [r7, #8] + 800a2d0: 68db ldr r3, [r3, #12] + 800a2d2: 791a ldrb r2, [r3, #4] + 800a2d4: 7959 ldrb r1, [r3, #5] + 800a2d6: 0209 lsls r1, r1, #8 + 800a2d8: 430a orrs r2, r1 + 800a2da: 7999 ldrb r1, [r3, #6] + 800a2dc: 0409 lsls r1, r1, #16 + 800a2de: 430a orrs r2, r1 + 800a2e0: 79db ldrb r3, [r3, #7] + 800a2e2: 061b lsls r3, r3, #24 + 800a2e4: 4313 orrs r3, r2 + 800a2e6: 0018 movs r0, r3 + 800a2e8: f7fa f9d3 bl 8004692 + 800a2ec: 0003 movs r3, r0 + 800a2ee: 1ae3 subs r3, r4, r3 + while (*cur_seg && + 800a2f0: d4d5 bmi.n 800a29e + } + seg->next = *cur_seg; + 800a2f2: 68fb ldr r3, [r7, #12] + 800a2f4: 681a ldr r2, [r3, #0] + 800a2f6: 68bb ldr r3, [r7, #8] + 800a2f8: 601a str r2, [r3, #0] + *cur_seg = seg; + 800a2fa: 68fb ldr r3, [r7, #12] + 800a2fc: 68ba ldr r2, [r7, #8] + 800a2fe: 601a str r2, [r3, #0] +#if TCP_OVERSIZE + if (seg->next == NULL) { + 800a300: 68bb ldr r3, [r7, #8] + 800a302: 681b ldr r3, [r3, #0] + 800a304: 2b00 cmp r3, #0 + 800a306: d103 bne.n 800a310 + /* the retransmitted segment is last in unsent, so reset unsent_oversize */ + pcb->unsent_oversize = 0; + 800a308: 687b ldr r3, [r7, #4] + 800a30a: 226a movs r2, #106 ; 0x6a + 800a30c: 2100 movs r1, #0 + 800a30e: 5299 strh r1, [r3, r2] + } +#endif /* TCP_OVERSIZE */ + + ++pcb->nrtx; + 800a310: 687b ldr r3, [r7, #4] + 800a312: 2246 movs r2, #70 ; 0x46 + 800a314: 5c9b ldrb r3, [r3, r2] + 800a316: 3301 adds r3, #1 + 800a318: b2d9 uxtb r1, r3 + 800a31a: 687b ldr r3, [r7, #4] + 800a31c: 2246 movs r2, #70 ; 0x46 + 800a31e: 5499 strb r1, [r3, r2] + + /* Don't take any rtt measurements after retransmitting. */ + pcb->rttest = 0; + 800a320: 687b ldr r3, [r7, #4] + 800a322: 2200 movs r2, #0 + 800a324: 639a str r2, [r3, #56] ; 0x38 + 800a326: e000 b.n 800a32a + return; + 800a328: 46c0 nop ; (mov r8, r8) + + /* Do the actual retransmission. */ + snmp_inc_tcpretranssegs(); + /* No need to call tcp_output: we are always called from tcp_input() + and thus tcp_output directly returns. */ +} + 800a32a: 46bd mov sp, r7 + 800a32c: b005 add sp, #20 + 800a32e: bd90 pop {r4, r7, pc} + +0800a330 : + * + * @param pcb the tcp_pcb for which to retransmit the first unacked segment + */ +void +tcp_rexmit_fast(struct tcp_pcb *pcb) +{ + 800a330: b580 push {r7, lr} + 800a332: b082 sub sp, #8 + 800a334: af00 add r7, sp, #0 + 800a336: 6078 str r0, [r7, #4] + if (pcb->unacked != NULL && !(pcb->flags & TF_INFR)) { + 800a338: 687b ldr r3, [r7, #4] + 800a33a: 6f1b ldr r3, [r3, #112] ; 0x70 + 800a33c: 2b00 cmp r3, #0 + 800a33e: d048 beq.n 800a3d2 + 800a340: 687b ldr r3, [r7, #4] + 800a342: 7f9b ldrb r3, [r3, #30] + 800a344: 001a movs r2, r3 + 800a346: 2304 movs r3, #4 + 800a348: 4013 ands r3, r2 + 800a34a: d142 bne.n 800a3d2 + LWIP_DEBUGF(TCP_FR_DEBUG, + ("tcp_receive: dupacks %"U16_F" (%"U32_F + "), fast retransmit %"U32_F"\n", + (u16_t)pcb->dupacks, pcb->lastack, + ntohl(pcb->unacked->tcphdr->seqno))); + tcp_rexmit(pcb); + 800a34c: 687b ldr r3, [r7, #4] + 800a34e: 0018 movs r0, r3 + 800a350: f7ff ff92 bl 800a278 + + /* Set ssthresh to half of the minimum of the current + * cwnd and the advertised window */ + if (pcb->cwnd > pcb->snd_wnd) { + 800a354: 687b ldr r3, [r7, #4] + 800a356: 224c movs r2, #76 ; 0x4c + 800a358: 5a9a ldrh r2, [r3, r2] + 800a35a: 687b ldr r3, [r7, #4] + 800a35c: 2160 movs r1, #96 ; 0x60 + 800a35e: 5a5b ldrh r3, [r3, r1] + 800a360: 429a cmp r2, r3 + 800a362: d908 bls.n 800a376 + pcb->ssthresh = pcb->snd_wnd / 2; + 800a364: 687b ldr r3, [r7, #4] + 800a366: 2260 movs r2, #96 ; 0x60 + 800a368: 5a9b ldrh r3, [r3, r2] + 800a36a: 085b lsrs r3, r3, #1 + 800a36c: b299 uxth r1, r3 + 800a36e: 687b ldr r3, [r7, #4] + 800a370: 224e movs r2, #78 ; 0x4e + 800a372: 5299 strh r1, [r3, r2] + 800a374: e007 b.n 800a386 + } else { + pcb->ssthresh = pcb->cwnd / 2; + 800a376: 687b ldr r3, [r7, #4] + 800a378: 224c movs r2, #76 ; 0x4c + 800a37a: 5a9b ldrh r3, [r3, r2] + 800a37c: 085b lsrs r3, r3, #1 + 800a37e: b299 uxth r1, r3 + 800a380: 687b ldr r3, [r7, #4] + 800a382: 224e movs r2, #78 ; 0x4e + 800a384: 5299 strh r1, [r3, r2] + } + + /* The minimum value for ssthresh should be 2 MSS */ + if (pcb->ssthresh < 2*pcb->mss) { + 800a386: 687b ldr r3, [r7, #4] + 800a388: 224e movs r2, #78 ; 0x4e + 800a38a: 5a9b ldrh r3, [r3, r2] + 800a38c: 001a movs r2, r3 + 800a38e: 687b ldr r3, [r7, #4] + 800a390: 8edb ldrh r3, [r3, #54] ; 0x36 + 800a392: 005b lsls r3, r3, #1 + 800a394: 429a cmp r2, r3 + 800a396: da06 bge.n 800a3a6 + LWIP_DEBUGF(TCP_FR_DEBUG, + ("tcp_receive: The minimum value for ssthresh %"U16_F + " should be min 2 mss %"U16_F"...\n", + pcb->ssthresh, 2*pcb->mss)); + pcb->ssthresh = 2*pcb->mss; + 800a398: 687b ldr r3, [r7, #4] + 800a39a: 8edb ldrh r3, [r3, #54] ; 0x36 + 800a39c: 18db adds r3, r3, r3 + 800a39e: b299 uxth r1, r3 + 800a3a0: 687b ldr r3, [r7, #4] + 800a3a2: 224e movs r2, #78 ; 0x4e + 800a3a4: 5299 strh r1, [r3, r2] + } + + pcb->cwnd = pcb->ssthresh + 3 * pcb->mss; + 800a3a6: 687b ldr r3, [r7, #4] + 800a3a8: 224e movs r2, #78 ; 0x4e + 800a3aa: 5a9a ldrh r2, [r3, r2] + 800a3ac: 687b ldr r3, [r7, #4] + 800a3ae: 8edb ldrh r3, [r3, #54] ; 0x36 + 800a3b0: 1c19 adds r1, r3, #0 + 800a3b2: 1c0b adds r3, r1, #0 + 800a3b4: 18db adds r3, r3, r3 + 800a3b6: 185b adds r3, r3, r1 + 800a3b8: b29b uxth r3, r3 + 800a3ba: 18d3 adds r3, r2, r3 + 800a3bc: b299 uxth r1, r3 + 800a3be: 687b ldr r3, [r7, #4] + 800a3c0: 224c movs r2, #76 ; 0x4c + 800a3c2: 5299 strh r1, [r3, r2] + pcb->flags |= TF_INFR; + 800a3c4: 687b ldr r3, [r7, #4] + 800a3c6: 7f9b ldrb r3, [r3, #30] + 800a3c8: 2204 movs r2, #4 + 800a3ca: 4313 orrs r3, r2 + 800a3cc: b2da uxtb r2, r3 + 800a3ce: 687b ldr r3, [r7, #4] + 800a3d0: 779a strb r2, [r3, #30] + } +} + 800a3d2: 46c0 nop ; (mov r8, r8) + 800a3d4: 46bd mov sp, r7 + 800a3d6: b002 add sp, #8 + 800a3d8: bd80 pop {r7, pc} + ... + +0800a3dc : + * + * @param pcb the tcp_pcb for which to send a keepalive packet + */ +void +tcp_keepalive(struct tcp_pcb *pcb) +{ + 800a3dc: b590 push {r4, r7, lr} + 800a3de: b087 sub sp, #28 + 800a3e0: af02 add r7, sp, #8 + 800a3e2: 6078 str r0, [r7, #4] + ip4_addr3_16(&pcb->remote_ip), ip4_addr4_16(&pcb->remote_ip))); + + LWIP_DEBUGF(TCP_DEBUG, ("tcp_keepalive: tcp_ticks %"U32_F" pcb->tmr %"U32_F" pcb->keep_cnt_sent %"U16_F"\n", + tcp_ticks, pcb->tmr, pcb->keep_cnt_sent)); + + p = tcp_output_alloc_header(pcb, 0, 0, htonl(pcb->snd_nxt - 1)); + 800a3e4: 687b ldr r3, [r7, #4] + 800a3e6: 6d1b ldr r3, [r3, #80] ; 0x50 + 800a3e8: 3b01 subs r3, #1 + 800a3ea: 0018 movs r0, r3 + 800a3ec: f7fa f938 bl 8004660 + 800a3f0: 0003 movs r3, r0 + 800a3f2: 6878 ldr r0, [r7, #4] + 800a3f4: 2200 movs r2, #0 + 800a3f6: 2100 movs r1, #0 + 800a3f8: f7fe ff54 bl 80092a4 + 800a3fc: 0003 movs r3, r0 + 800a3fe: 60fb str r3, [r7, #12] + if(p == NULL) { + 800a400: 68fb ldr r3, [r7, #12] + 800a402: 2b00 cmp r3, #0 + 800a404: d03c beq.n 800a480 + LWIP_DEBUGF(TCP_DEBUG, + ("tcp_keepalive: could not allocate memory for pbuf\n")); + return; + } + tcphdr = (struct tcp_hdr *)p->payload; + 800a406: 68fb ldr r3, [r7, #12] + 800a408: 685b ldr r3, [r3, #4] + 800a40a: 60bb str r3, [r7, #8] + +#if CHECKSUM_GEN_TCP + tcphdr->chksum = inet_chksum_pseudo(p, &pcb->local_ip, &pcb->remote_ip, + 800a40c: 6879 ldr r1, [r7, #4] + 800a40e: 687b ldr r3, [r7, #4] + 800a410: 1d1a adds r2, r3, #4 + 800a412: 68fb ldr r3, [r7, #12] + 800a414: 891b ldrh r3, [r3, #8] + 800a416: 68f8 ldr r0, [r7, #12] + 800a418: 9300 str r3, [sp, #0] + 800a41a: 2306 movs r3, #6 + 800a41c: f001 f90d bl 800b63a + 800a420: 0003 movs r3, r0 + 800a422: 001a movs r2, r3 + 800a424: 68bb ldr r3, [r7, #8] + 800a426: 21ff movs r1, #255 ; 0xff + 800a428: 4011 ands r1, r2 + 800a42a: 000c movs r4, r1 + 800a42c: 7c19 ldrb r1, [r3, #16] + 800a42e: 2000 movs r0, #0 + 800a430: 4001 ands r1, r0 + 800a432: 1c08 adds r0, r1, #0 + 800a434: 1c21 adds r1, r4, #0 + 800a436: 4301 orrs r1, r0 + 800a438: 7419 strb r1, [r3, #16] + 800a43a: 0a12 lsrs r2, r2, #8 + 800a43c: b290 uxth r0, r2 + 800a43e: 7c5a ldrb r2, [r3, #17] + 800a440: 2100 movs r1, #0 + 800a442: 400a ands r2, r1 + 800a444: 1c11 adds r1, r2, #0 + 800a446: 1c02 adds r2, r0, #0 + 800a448: 430a orrs r2, r1 + 800a44a: 745a strb r2, [r3, #17] + IP_PROTO_TCP, p->tot_len); +#endif + TCP_STATS_INC(tcp.xmit); + 800a44c: 4b0e ldr r3, [pc, #56] ; (800a488 ) + 800a44e: 2290 movs r2, #144 ; 0x90 + 800a450: 5a9b ldrh r3, [r3, r2] + 800a452: 3301 adds r3, #1 + 800a454: b299 uxth r1, r3 + 800a456: 4b0c ldr r3, [pc, #48] ; (800a488 ) + 800a458: 2290 movs r2, #144 ; 0x90 + 800a45a: 5299 strh r1, [r3, r2] + /* Send output to IP */ +#if LWIP_NETIF_HWADDRHINT + ip_output_hinted(p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl, 0, IP_PROTO_TCP, + &(pcb->addr_hint)); +#else /* LWIP_NETIF_HWADDRHINT*/ + ip_output(p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl, 0, IP_PROTO_TCP); + 800a45c: 6879 ldr r1, [r7, #4] + 800a45e: 687b ldr r3, [r7, #4] + 800a460: 1d1a adds r2, r3, #4 + 800a462: 687b ldr r3, [r7, #4] + 800a464: 7a9c ldrb r4, [r3, #10] + 800a466: 68f8 ldr r0, [r7, #12] + 800a468: 2306 movs r3, #6 + 800a46a: 9301 str r3, [sp, #4] + 800a46c: 2300 movs r3, #0 + 800a46e: 9300 str r3, [sp, #0] + 800a470: 0023 movs r3, r4 + 800a472: f001 fdcd bl 800c010 +#endif /* LWIP_NETIF_HWADDRHINT*/ + + pbuf_free(p); + 800a476: 68fb ldr r3, [r7, #12] + 800a478: 0018 movs r0, r3 + 800a47a: f7fb f913 bl 80056a4 + 800a47e: e000 b.n 800a482 + return; + 800a480: 46c0 nop ; (mov r8, r8) + + LWIP_DEBUGF(TCP_DEBUG, ("tcp_keepalive: seqno %"U32_F" ackno %"U32_F".\n", + pcb->snd_nxt - 1, pcb->rcv_nxt)); +} + 800a482: 46bd mov sp, r7 + 800a484: b005 add sp, #20 + 800a486: bd90 pop {r4, r7, pc} + 800a488: 20003158 .word 0x20003158 + +0800a48c : + * + * @param pcb the tcp_pcb for which to send a zero-window probe packet + */ +void +tcp_zero_window_probe(struct tcp_pcb *pcb) +{ + 800a48c: b590 push {r4, r7, lr} + 800a48e: b08b sub sp, #44 ; 0x2c + 800a490: af02 add r7, sp, #8 + 800a492: 6078 str r0, [r7, #4] + LWIP_DEBUGF(TCP_DEBUG, + ("tcp_zero_window_probe: tcp_ticks %"U32_F + " pcb->tmr %"U32_F" pcb->keep_cnt_sent %"U16_F"\n", + tcp_ticks, pcb->tmr, pcb->keep_cnt_sent)); + + seg = pcb->unacked; + 800a494: 687b ldr r3, [r7, #4] + 800a496: 6f1b ldr r3, [r3, #112] ; 0x70 + 800a498: 61fb str r3, [r7, #28] + + if(seg == NULL) { + 800a49a: 69fb ldr r3, [r7, #28] + 800a49c: 2b00 cmp r3, #0 + 800a49e: d102 bne.n 800a4a6 + seg = pcb->unsent; + 800a4a0: 687b ldr r3, [r7, #4] + 800a4a2: 6edb ldr r3, [r3, #108] ; 0x6c + 800a4a4: 61fb str r3, [r7, #28] + } + if(seg == NULL) { + 800a4a6: 69fb ldr r3, [r7, #28] + 800a4a8: 2b00 cmp r3, #0 + 800a4aa: d100 bne.n 800a4ae + 800a4ac: e0b4 b.n 800a618 + return; + } + + is_fin = ((TCPH_FLAGS(seg->tcphdr) & TCP_FIN) != 0) && (seg->len == 0); + 800a4ae: 69fb ldr r3, [r7, #28] + 800a4b0: 68db ldr r3, [r3, #12] + 800a4b2: 7b1a ldrb r2, [r3, #12] + 800a4b4: 7b5b ldrb r3, [r3, #13] + 800a4b6: 021b lsls r3, r3, #8 + 800a4b8: 4313 orrs r3, r2 + 800a4ba: b29b uxth r3, r3 + 800a4bc: 0018 movs r0, r3 + 800a4be: f7fa f8bf bl 8004640 + 800a4c2: 0003 movs r3, r0 + 800a4c4: 001a movs r2, r3 + 800a4c6: 2301 movs r3, #1 + 800a4c8: 4013 ands r3, r2 + 800a4ca: d005 beq.n 800a4d8 + 800a4cc: 69fb ldr r3, [r7, #28] + 800a4ce: 891b ldrh r3, [r3, #8] + 800a4d0: 2b00 cmp r3, #0 + 800a4d2: d101 bne.n 800a4d8 + 800a4d4: 2201 movs r2, #1 + 800a4d6: e000 b.n 800a4da + 800a4d8: 2200 movs r2, #0 + 800a4da: 211b movs r1, #27 + 800a4dc: 187b adds r3, r7, r1 + 800a4de: 701a strb r2, [r3, #0] + /* we want to send one seqno: either FIN or data (no options) */ + len = is_fin ? 0 : 1; + 800a4e0: 187b adds r3, r7, r1 + 800a4e2: 781b ldrb r3, [r3, #0] + 800a4e4: 425a negs r2, r3 + 800a4e6: 4153 adcs r3, r2 + 800a4e8: b2da uxtb r2, r3 + 800a4ea: 2018 movs r0, #24 + 800a4ec: 183b adds r3, r7, r0 + 800a4ee: 801a strh r2, [r3, #0] + + p = tcp_output_alloc_header(pcb, 0, len, seg->tcphdr->seqno); + 800a4f0: 69fb ldr r3, [r7, #28] + 800a4f2: 68db ldr r3, [r3, #12] + 800a4f4: 791a ldrb r2, [r3, #4] + 800a4f6: 7959 ldrb r1, [r3, #5] + 800a4f8: 0209 lsls r1, r1, #8 + 800a4fa: 430a orrs r2, r1 + 800a4fc: 7999 ldrb r1, [r3, #6] + 800a4fe: 0409 lsls r1, r1, #16 + 800a500: 430a orrs r2, r1 + 800a502: 79db ldrb r3, [r3, #7] + 800a504: 061b lsls r3, r3, #24 + 800a506: 4313 orrs r3, r2 + 800a508: 0019 movs r1, r3 + 800a50a: 183b adds r3, r7, r0 + 800a50c: 881a ldrh r2, [r3, #0] + 800a50e: 6878 ldr r0, [r7, #4] + 800a510: 000b movs r3, r1 + 800a512: 2100 movs r1, #0 + 800a514: f7fe fec6 bl 80092a4 + 800a518: 0003 movs r3, r0 + 800a51a: 617b str r3, [r7, #20] + if(p == NULL) { + 800a51c: 697b ldr r3, [r7, #20] + 800a51e: 2b00 cmp r3, #0 + 800a520: d100 bne.n 800a524 + 800a522: e07b b.n 800a61c + LWIP_DEBUGF(TCP_DEBUG, ("tcp_zero_window_probe: no memory for pbuf\n")); + return; + } + tcphdr = (struct tcp_hdr *)p->payload; + 800a524: 697b ldr r3, [r7, #20] + 800a526: 685b ldr r3, [r3, #4] + 800a528: 613b str r3, [r7, #16] + + if (is_fin) { + 800a52a: 231b movs r3, #27 + 800a52c: 18fb adds r3, r7, r3 + 800a52e: 781b ldrb r3, [r3, #0] + 800a530: 2b00 cmp r3, #0 + 800a532: d026 beq.n 800a582 + /* FIN segment, no data */ + TCPH_FLAGS_SET(tcphdr, TCP_ACK | TCP_FIN); + 800a534: 693b ldr r3, [r7, #16] + 800a536: 7b1a ldrb r2, [r3, #12] + 800a538: 7b5b ldrb r3, [r3, #13] + 800a53a: 021b lsls r3, r3, #8 + 800a53c: 4313 orrs r3, r2 + 800a53e: b29b uxth r3, r3 + 800a540: b21b sxth r3, r3 + 800a542: 4a38 ldr r2, [pc, #224] ; (800a624 ) + 800a544: 4013 ands r3, r2 + 800a546: b21c sxth r4, r3 + 800a548: 2011 movs r0, #17 + 800a54a: f7fa f863 bl 8004614 + 800a54e: 0003 movs r3, r0 + 800a550: b21b sxth r3, r3 + 800a552: 4323 orrs r3, r4 + 800a554: b21b sxth r3, r3 + 800a556: b29a uxth r2, r3 + 800a558: 693b ldr r3, [r7, #16] + 800a55a: 21ff movs r1, #255 ; 0xff + 800a55c: 4011 ands r1, r2 + 800a55e: 000c movs r4, r1 + 800a560: 7b19 ldrb r1, [r3, #12] + 800a562: 2000 movs r0, #0 + 800a564: 4001 ands r1, r0 + 800a566: 1c08 adds r0, r1, #0 + 800a568: 1c21 adds r1, r4, #0 + 800a56a: 4301 orrs r1, r0 + 800a56c: 7319 strb r1, [r3, #12] + 800a56e: 0a12 lsrs r2, r2, #8 + 800a570: b290 uxth r0, r2 + 800a572: 7b5a ldrb r2, [r3, #13] + 800a574: 2100 movs r1, #0 + 800a576: 400a ands r2, r1 + 800a578: 1c11 adds r1, r2, #0 + 800a57a: 1c02 adds r2, r0, #0 + 800a57c: 430a orrs r2, r1 + 800a57e: 735a strb r2, [r3, #13] + 800a580: e010 b.n 800a5a4 + } else { + /* Data segment, copy in one byte from the head of the unacked queue */ + char *d = ((char *)p->payload + TCP_HLEN); + 800a582: 697b ldr r3, [r7, #20] + 800a584: 685b ldr r3, [r3, #4] + 800a586: 3314 adds r3, #20 + 800a588: 60fb str r3, [r7, #12] + /* Depending on whether the segment has already been sent (unacked) or not + (unsent), seg->p->payload points to the IP header or TCP header. + Ensure we copy the first TCP data byte: */ + pbuf_copy_partial(seg->p, d, 1, seg->p->tot_len - seg->len); + 800a58a: 69fb ldr r3, [r7, #28] + 800a58c: 6858 ldr r0, [r3, #4] + 800a58e: 69fb ldr r3, [r7, #28] + 800a590: 685b ldr r3, [r3, #4] + 800a592: 891a ldrh r2, [r3, #8] + 800a594: 69fb ldr r3, [r7, #28] + 800a596: 891b ldrh r3, [r3, #8] + 800a598: 1ad3 subs r3, r2, r3 + 800a59a: b29b uxth r3, r3 + 800a59c: 68f9 ldr r1, [r7, #12] + 800a59e: 2201 movs r2, #1 + 800a5a0: f7fb fa0c bl 80059bc + } + +#if CHECKSUM_GEN_TCP + tcphdr->chksum = inet_chksum_pseudo(p, &pcb->local_ip, &pcb->remote_ip, + 800a5a4: 6879 ldr r1, [r7, #4] + 800a5a6: 687b ldr r3, [r7, #4] + 800a5a8: 1d1a adds r2, r3, #4 + 800a5aa: 697b ldr r3, [r7, #20] + 800a5ac: 891b ldrh r3, [r3, #8] + 800a5ae: 6978 ldr r0, [r7, #20] + 800a5b0: 9300 str r3, [sp, #0] + 800a5b2: 2306 movs r3, #6 + 800a5b4: f001 f841 bl 800b63a + 800a5b8: 0003 movs r3, r0 + 800a5ba: 001a movs r2, r3 + 800a5bc: 693b ldr r3, [r7, #16] + 800a5be: 21ff movs r1, #255 ; 0xff + 800a5c0: 4011 ands r1, r2 + 800a5c2: 000c movs r4, r1 + 800a5c4: 7c19 ldrb r1, [r3, #16] + 800a5c6: 2000 movs r0, #0 + 800a5c8: 4001 ands r1, r0 + 800a5ca: 1c08 adds r0, r1, #0 + 800a5cc: 1c21 adds r1, r4, #0 + 800a5ce: 4301 orrs r1, r0 + 800a5d0: 7419 strb r1, [r3, #16] + 800a5d2: 0a12 lsrs r2, r2, #8 + 800a5d4: b290 uxth r0, r2 + 800a5d6: 7c5a ldrb r2, [r3, #17] + 800a5d8: 2100 movs r1, #0 + 800a5da: 400a ands r2, r1 + 800a5dc: 1c11 adds r1, r2, #0 + 800a5de: 1c02 adds r2, r0, #0 + 800a5e0: 430a orrs r2, r1 + 800a5e2: 745a strb r2, [r3, #17] + IP_PROTO_TCP, p->tot_len); +#endif + TCP_STATS_INC(tcp.xmit); + 800a5e4: 4b10 ldr r3, [pc, #64] ; (800a628 ) + 800a5e6: 2290 movs r2, #144 ; 0x90 + 800a5e8: 5a9b ldrh r3, [r3, r2] + 800a5ea: 3301 adds r3, #1 + 800a5ec: b299 uxth r1, r3 + 800a5ee: 4b0e ldr r3, [pc, #56] ; (800a628 ) + 800a5f0: 2290 movs r2, #144 ; 0x90 + 800a5f2: 5299 strh r1, [r3, r2] + /* Send output to IP */ +#if LWIP_NETIF_HWADDRHINT + ip_output_hinted(p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl, 0, IP_PROTO_TCP, + &(pcb->addr_hint)); +#else /* LWIP_NETIF_HWADDRHINT*/ + ip_output(p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl, 0, IP_PROTO_TCP); + 800a5f4: 6879 ldr r1, [r7, #4] + 800a5f6: 687b ldr r3, [r7, #4] + 800a5f8: 1d1a adds r2, r3, #4 + 800a5fa: 687b ldr r3, [r7, #4] + 800a5fc: 7a9c ldrb r4, [r3, #10] + 800a5fe: 6978 ldr r0, [r7, #20] + 800a600: 2306 movs r3, #6 + 800a602: 9301 str r3, [sp, #4] + 800a604: 2300 movs r3, #0 + 800a606: 9300 str r3, [sp, #0] + 800a608: 0023 movs r3, r4 + 800a60a: f001 fd01 bl 800c010 +#endif /* LWIP_NETIF_HWADDRHINT*/ + + pbuf_free(p); + 800a60e: 697b ldr r3, [r7, #20] + 800a610: 0018 movs r0, r3 + 800a612: f7fb f847 bl 80056a4 + 800a616: e002 b.n 800a61e + return; + 800a618: 46c0 nop ; (mov r8, r8) + 800a61a: e000 b.n 800a61e + return; + 800a61c: 46c0 nop ; (mov r8, r8) + + LWIP_DEBUGF(TCP_DEBUG, ("tcp_zero_window_probe: seqno %"U32_F + " ackno %"U32_F".\n", + pcb->snd_nxt - 1, pcb->rcv_nxt)); +} + 800a61e: 46bd mov sp, r7 + 800a620: b009 add sp, #36 ; 0x24 + 800a622: bd90 pop {r4, r7, pc} + 800a624: ffffc0ff .word 0xffffc0ff + 800a628: 20003158 .word 0x20003158 + +0800a62c : + * + * @param arg unused argument + */ +static void +tcpip_tcp_timer(void *arg) +{ + 800a62c: b580 push {r7, lr} + 800a62e: b082 sub sp, #8 + 800a630: af00 add r7, sp, #0 + 800a632: 6078 str r0, [r7, #4] + LWIP_UNUSED_ARG(arg); + + /* call TCP timer handler */ + tcp_tmr(); + 800a634: f7fb fabe bl 8005bb4 + /* timer still needed? */ + if (tcp_active_pcbs || tcp_tw_pcbs) { + 800a638: 4b0a ldr r3, [pc, #40] ; (800a664 ) + 800a63a: 681b ldr r3, [r3, #0] + 800a63c: 2b00 cmp r3, #0 + 800a63e: d103 bne.n 800a648 + 800a640: 4b09 ldr r3, [pc, #36] ; (800a668 ) + 800a642: 681b ldr r3, [r3, #0] + 800a644: 2b00 cmp r3, #0 + 800a646: d006 beq.n 800a656 + /* restart timer */ + sys_timeout(TCP_TMR_INTERVAL, tcpip_tcp_timer, NULL); + 800a648: 4b08 ldr r3, [pc, #32] ; (800a66c ) + 800a64a: 2200 movs r2, #0 + 800a64c: 0019 movs r1, r3 + 800a64e: 20fa movs r0, #250 ; 0xfa + 800a650: f000 f87a bl 800a748 + 800a654: e002 b.n 800a65c + } else { + /* disable timer */ + tcpip_tcp_timer_active = 0; + 800a656: 4b06 ldr r3, [pc, #24] ; (800a670 ) + 800a658: 2200 movs r2, #0 + 800a65a: 601a str r2, [r3, #0] + } +} + 800a65c: 46c0 nop ; (mov r8, r8) + 800a65e: 46bd mov sp, r7 + 800a660: b002 add sp, #8 + 800a662: bd80 pop {r7, pc} + 800a664: 20003274 .word 0x20003274 + 800a668: 20003288 .word 0x20003288 + 800a66c: 0800a62d .word 0x0800a62d + 800a670: 200022b0 .word 0x200022b0 + +0800a674 : + * the reason is to have the TCP timer only running when + * there are active (or time-wait) PCBs. + */ +void +tcp_timer_needed(void) +{ + 800a674: b580 push {r7, lr} + 800a676: af00 add r7, sp, #0 + /* timer is off but needed again? */ + if (!tcpip_tcp_timer_active && (tcp_active_pcbs || tcp_tw_pcbs)) { + 800a678: 4b0b ldr r3, [pc, #44] ; (800a6a8 ) + 800a67a: 681b ldr r3, [r3, #0] + 800a67c: 2b00 cmp r3, #0 + 800a67e: d110 bne.n 800a6a2 + 800a680: 4b0a ldr r3, [pc, #40] ; (800a6ac ) + 800a682: 681b ldr r3, [r3, #0] + 800a684: 2b00 cmp r3, #0 + 800a686: d103 bne.n 800a690 + 800a688: 4b09 ldr r3, [pc, #36] ; (800a6b0 ) + 800a68a: 681b ldr r3, [r3, #0] + 800a68c: 2b00 cmp r3, #0 + 800a68e: d008 beq.n 800a6a2 + /* enable and start timer */ + tcpip_tcp_timer_active = 1; + 800a690: 4b05 ldr r3, [pc, #20] ; (800a6a8 ) + 800a692: 2201 movs r2, #1 + 800a694: 601a str r2, [r3, #0] + sys_timeout(TCP_TMR_INTERVAL, tcpip_tcp_timer, NULL); + 800a696: 4b07 ldr r3, [pc, #28] ; (800a6b4 ) + 800a698: 2200 movs r2, #0 + 800a69a: 0019 movs r1, r3 + 800a69c: 20fa movs r0, #250 ; 0xfa + 800a69e: f000 f853 bl 800a748 + } +} + 800a6a2: 46c0 nop ; (mov r8, r8) + 800a6a4: 46bd mov sp, r7 + 800a6a6: bd80 pop {r7, pc} + 800a6a8: 200022b0 .word 0x200022b0 + 800a6ac: 20003274 .word 0x20003274 + 800a6b0: 20003288 .word 0x20003288 + 800a6b4: 0800a62d .word 0x0800a62d + +0800a6b8 : + * + * @param arg unused argument + */ +static void +ip_reass_timer(void *arg) +{ + 800a6b8: b580 push {r7, lr} + 800a6ba: b082 sub sp, #8 + 800a6bc: af00 add r7, sp, #0 + 800a6be: 6078 str r0, [r7, #4] + LWIP_UNUSED_ARG(arg); + LWIP_DEBUGF(TIMERS_DEBUG, ("tcpip: ip_reass_tmr()\n")); + ip_reass_tmr(); + 800a6c0: f001 fd14 bl 800c0ec + sys_timeout(IP_TMR_INTERVAL, ip_reass_timer, NULL); + 800a6c4: 4905 ldr r1, [pc, #20] ; (800a6dc ) + 800a6c6: 23fa movs r3, #250 ; 0xfa + 800a6c8: 009b lsls r3, r3, #2 + 800a6ca: 2200 movs r2, #0 + 800a6cc: 0018 movs r0, r3 + 800a6ce: f000 f83b bl 800a748 +} + 800a6d2: 46c0 nop ; (mov r8, r8) + 800a6d4: 46bd mov sp, r7 + 800a6d6: b002 add sp, #8 + 800a6d8: bd80 pop {r7, pc} + 800a6da: 46c0 nop ; (mov r8, r8) + 800a6dc: 0800a6b9 .word 0x0800a6b9 + +0800a6e0 : + * + * @param arg unused argument + */ +static void +arp_timer(void *arg) +{ + 800a6e0: b580 push {r7, lr} + 800a6e2: b082 sub sp, #8 + 800a6e4: af00 add r7, sp, #0 + 800a6e6: 6078 str r0, [r7, #4] + LWIP_UNUSED_ARG(arg); + LWIP_DEBUGF(TIMERS_DEBUG, ("tcpip: etharp_tmr()\n")); + etharp_tmr(); + 800a6e8: f002 fc58 bl 800cf9c + sys_timeout(ARP_TMR_INTERVAL, arp_timer, NULL); + 800a6ec: 4b04 ldr r3, [pc, #16] ; (800a700 ) + 800a6ee: 4805 ldr r0, [pc, #20] ; (800a704 ) + 800a6f0: 2200 movs r2, #0 + 800a6f2: 0019 movs r1, r3 + 800a6f4: f000 f828 bl 800a748 +} + 800a6f8: 46c0 nop ; (mov r8, r8) + 800a6fa: 46bd mov sp, r7 + 800a6fc: b002 add sp, #8 + 800a6fe: bd80 pop {r7, pc} + 800a700: 0800a6e1 .word 0x0800a6e1 + 800a704: 00001388 .word 0x00001388 + +0800a708 : +} +#endif /* LWIP_DNS */ + +/** Initialize this module */ +void sys_timeouts_init(void) +{ + 800a708: b580 push {r7, lr} + 800a70a: af00 add r7, sp, #0 +#if IP_REASSEMBLY + sys_timeout(IP_TMR_INTERVAL, ip_reass_timer, NULL); + 800a70c: 490a ldr r1, [pc, #40] ; (800a738 ) + 800a70e: 23fa movs r3, #250 ; 0xfa + 800a710: 009b lsls r3, r3, #2 + 800a712: 2200 movs r2, #0 + 800a714: 0018 movs r0, r3 + 800a716: f000 f817 bl 800a748 +#endif /* IP_REASSEMBLY */ +#if LWIP_ARP + sys_timeout(ARP_TMR_INTERVAL, arp_timer, NULL); + 800a71a: 4b08 ldr r3, [pc, #32] ; (800a73c ) + 800a71c: 4808 ldr r0, [pc, #32] ; (800a740 ) + 800a71e: 2200 movs r2, #0 + 800a720: 0019 movs r1, r3 + 800a722: f000 f811 bl 800a748 + sys_timeout(DNS_TMR_INTERVAL, dns_timer, NULL); +#endif /* LWIP_DNS */ + +#if NO_SYS + /* Initialise timestamp for sys_check_timeouts */ + timeouts_last_time = sys_now(); + 800a726: f003 fc5b bl 800dfe0 + 800a72a: 0002 movs r2, r0 + 800a72c: 4b05 ldr r3, [pc, #20] ; (800a744 ) + 800a72e: 601a str r2, [r3, #0] +#endif +} + 800a730: 46c0 nop ; (mov r8, r8) + 800a732: 46bd mov sp, r7 + 800a734: bd80 pop {r7, pc} + 800a736: 46c0 nop ; (mov r8, r8) + 800a738: 0800a6b9 .word 0x0800a6b9 + 800a73c: 0800a6e1 .word 0x0800a6e1 + 800a740: 00001388 .word 0x00001388 + 800a744: 200022ac .word 0x200022ac + +0800a748 : +sys_timeout_debug(u32_t msecs, sys_timeout_handler handler, void *arg, const char* handler_name) +#else /* LWIP_DEBUG_TIMERNAMES */ +void +sys_timeout(u32_t msecs, sys_timeout_handler handler, void *arg) +#endif /* LWIP_DEBUG_TIMERNAMES */ +{ + 800a748: b580 push {r7, lr} + 800a74a: b086 sub sp, #24 + 800a74c: af00 add r7, sp, #0 + 800a74e: 60f8 str r0, [r7, #12] + 800a750: 60b9 str r1, [r7, #8] + 800a752: 607a str r2, [r7, #4] + struct sys_timeo *timeout, *t; + + timeout = (struct sys_timeo *)memp_malloc(MEMP_SYS_TIMEOUT); + 800a754: 2007 movs r0, #7 + 800a756: f7fa fb5d bl 8004e14 + 800a75a: 0003 movs r3, r0 + 800a75c: 613b str r3, [r7, #16] + if (timeout == NULL) { + 800a75e: 693b ldr r3, [r7, #16] + 800a760: 2b00 cmp r3, #0 + 800a762: d05b beq.n 800a81c + LWIP_ASSERT("sys_timeout: timeout != NULL, pool MEMP_SYS_TIMEOUT is empty", timeout != NULL); + return; + } + timeout->next = NULL; + 800a764: 693b ldr r3, [r7, #16] + 800a766: 2200 movs r2, #0 + 800a768: 601a str r2, [r3, #0] + timeout->h = handler; + 800a76a: 693b ldr r3, [r7, #16] + 800a76c: 68ba ldr r2, [r7, #8] + 800a76e: 609a str r2, [r3, #8] + timeout->arg = arg; + 800a770: 693b ldr r3, [r7, #16] + 800a772: 687a ldr r2, [r7, #4] + 800a774: 60da str r2, [r3, #12] + timeout->time = msecs; + 800a776: 693b ldr r3, [r7, #16] + 800a778: 68fa ldr r2, [r7, #12] + 800a77a: 605a str r2, [r3, #4] + timeout->handler_name = handler_name; + LWIP_DEBUGF(TIMERS_DEBUG, ("sys_timeout: %p msecs=%"U32_F" handler=%s arg=%p\n", + (void *)timeout, msecs, handler_name, (void *)arg)); +#endif /* LWIP_DEBUG_TIMERNAMES */ + + if (next_timeout == NULL) { + 800a77c: 4b29 ldr r3, [pc, #164] ; (800a824 ) + 800a77e: 681b ldr r3, [r3, #0] + 800a780: 2b00 cmp r3, #0 + 800a782: d103 bne.n 800a78c + next_timeout = timeout; + 800a784: 4b27 ldr r3, [pc, #156] ; (800a824 ) + 800a786: 693a ldr r2, [r7, #16] + 800a788: 601a str r2, [r3, #0] + return; + 800a78a: e048 b.n 800a81e + } + + if (next_timeout->time > msecs) { + 800a78c: 4b25 ldr r3, [pc, #148] ; (800a824 ) + 800a78e: 681b ldr r3, [r3, #0] + 800a790: 685b ldr r3, [r3, #4] + 800a792: 68fa ldr r2, [r7, #12] + 800a794: 429a cmp r2, r3 + 800a796: d20f bcs.n 800a7b8 + next_timeout->time -= msecs; + 800a798: 4b22 ldr r3, [pc, #136] ; (800a824 ) + 800a79a: 681b ldr r3, [r3, #0] + 800a79c: 6859 ldr r1, [r3, #4] + 800a79e: 4b21 ldr r3, [pc, #132] ; (800a824 ) + 800a7a0: 681b ldr r3, [r3, #0] + 800a7a2: 68fa ldr r2, [r7, #12] + 800a7a4: 1a8a subs r2, r1, r2 + 800a7a6: 605a str r2, [r3, #4] + timeout->next = next_timeout; + 800a7a8: 4b1e ldr r3, [pc, #120] ; (800a824 ) + 800a7aa: 681a ldr r2, [r3, #0] + 800a7ac: 693b ldr r3, [r7, #16] + 800a7ae: 601a str r2, [r3, #0] + next_timeout = timeout; + 800a7b0: 4b1c ldr r3, [pc, #112] ; (800a824 ) + 800a7b2: 693a ldr r2, [r7, #16] + 800a7b4: 601a str r2, [r3, #0] + 800a7b6: e032 b.n 800a81e + } else { + for(t = next_timeout; t != NULL; t = t->next) { + 800a7b8: 4b1a ldr r3, [pc, #104] ; (800a824 ) + 800a7ba: 681b ldr r3, [r3, #0] + 800a7bc: 617b str r3, [r7, #20] + 800a7be: e029 b.n 800a814 + timeout->time -= t->time; + 800a7c0: 693b ldr r3, [r7, #16] + 800a7c2: 685a ldr r2, [r3, #4] + 800a7c4: 697b ldr r3, [r7, #20] + 800a7c6: 685b ldr r3, [r3, #4] + 800a7c8: 1ad2 subs r2, r2, r3 + 800a7ca: 693b ldr r3, [r7, #16] + 800a7cc: 605a str r2, [r3, #4] + if (t->next == NULL || t->next->time > timeout->time) { + 800a7ce: 697b ldr r3, [r7, #20] + 800a7d0: 681b ldr r3, [r3, #0] + 800a7d2: 2b00 cmp r3, #0 + 800a7d4: d006 beq.n 800a7e4 + 800a7d6: 697b ldr r3, [r7, #20] + 800a7d8: 681b ldr r3, [r3, #0] + 800a7da: 685a ldr r2, [r3, #4] + 800a7dc: 693b ldr r3, [r7, #16] + 800a7de: 685b ldr r3, [r3, #4] + 800a7e0: 429a cmp r2, r3 + 800a7e2: d914 bls.n 800a80e + if (t->next != NULL) { + 800a7e4: 697b ldr r3, [r7, #20] + 800a7e6: 681b ldr r3, [r3, #0] + 800a7e8: 2b00 cmp r3, #0 + 800a7ea: d008 beq.n 800a7fe + t->next->time -= timeout->time; + 800a7ec: 697b ldr r3, [r7, #20] + 800a7ee: 681b ldr r3, [r3, #0] + 800a7f0: 6859 ldr r1, [r3, #4] + 800a7f2: 693b ldr r3, [r7, #16] + 800a7f4: 685a ldr r2, [r3, #4] + 800a7f6: 697b ldr r3, [r7, #20] + 800a7f8: 681b ldr r3, [r3, #0] + 800a7fa: 1a8a subs r2, r1, r2 + 800a7fc: 605a str r2, [r3, #4] + } + timeout->next = t->next; + 800a7fe: 697b ldr r3, [r7, #20] + 800a800: 681a ldr r2, [r3, #0] + 800a802: 693b ldr r3, [r7, #16] + 800a804: 601a str r2, [r3, #0] + t->next = timeout; + 800a806: 697b ldr r3, [r7, #20] + 800a808: 693a ldr r2, [r7, #16] + 800a80a: 601a str r2, [r3, #0] + break; + 800a80c: e007 b.n 800a81e + for(t = next_timeout; t != NULL; t = t->next) { + 800a80e: 697b ldr r3, [r7, #20] + 800a810: 681b ldr r3, [r3, #0] + 800a812: 617b str r3, [r7, #20] + 800a814: 697b ldr r3, [r7, #20] + 800a816: 2b00 cmp r3, #0 + 800a818: d1d2 bne.n 800a7c0 + 800a81a: e000 b.n 800a81e + return; + 800a81c: 46c0 nop ; (mov r8, r8) + } + } + } +} + 800a81e: 46bd mov sp, r7 + 800a820: b006 add sp, #24 + 800a822: bd80 pop {r7, pc} + 800a824: 200022a8 .word 0x200022a8 + +0800a828 : +/** + * Initialize this module. + */ +void +udp_init(void) +{ + 800a828: b580 push {r7, lr} + 800a82a: af00 add r7, sp, #0 +#if LWIP_RANDOMIZE_INITIAL_LOCAL_PORTS && defined(LWIP_RAND) + udp_port = UDP_ENSURE_LOCAL_PORT_RANGE(LWIP_RAND()); +#endif /* LWIP_RANDOMIZE_INITIAL_LOCAL_PORTS && defined(LWIP_RAND) */ +} + 800a82c: 46c0 nop ; (mov r8, r8) + 800a82e: 46bd mov sp, r7 + 800a830: bd80 pop {r7, pc} + ... + +0800a834 : + * + * @return a new (free) local UDP port number + */ +static u16_t +udp_new_port(void) +{ + 800a834: b580 push {r7, lr} + 800a836: b082 sub sp, #8 + 800a838: af00 add r7, sp, #0 + u16_t n = 0; + 800a83a: 1dbb adds r3, r7, #6 + 800a83c: 2200 movs r2, #0 + 800a83e: 801a strh r2, [r3, #0] + struct udp_pcb *pcb; + +again: + if (udp_port++ == UDP_LOCAL_PORT_RANGE_END) { + 800a840: 4b16 ldr r3, [pc, #88] ; (800a89c ) + 800a842: 881b ldrh r3, [r3, #0] + 800a844: 1c5a adds r2, r3, #1 + 800a846: b291 uxth r1, r2 + 800a848: 4a14 ldr r2, [pc, #80] ; (800a89c ) + 800a84a: 8011 strh r1, [r2, #0] + 800a84c: 4a14 ldr r2, [pc, #80] ; (800a8a0 ) + 800a84e: 4293 cmp r3, r2 + 800a850: d102 bne.n 800a858 + udp_port = UDP_LOCAL_PORT_RANGE_START; + 800a852: 4b12 ldr r3, [pc, #72] ; (800a89c ) + 800a854: 4a13 ldr r2, [pc, #76] ; (800a8a4 ) + 800a856: 801a strh r2, [r3, #0] + } + /* Check all PCBs. */ + for(pcb = udp_pcbs; pcb != NULL; pcb = pcb->next) { + 800a858: 4b13 ldr r3, [pc, #76] ; (800a8a8 ) + 800a85a: 681b ldr r3, [r3, #0] + 800a85c: 603b str r3, [r7, #0] + 800a85e: e014 b.n 800a88a + if (pcb->local_port == udp_port) { + 800a860: 683b ldr r3, [r7, #0] + 800a862: 8a5a ldrh r2, [r3, #18] + 800a864: 4b0d ldr r3, [pc, #52] ; (800a89c ) + 800a866: 881b ldrh r3, [r3, #0] + 800a868: 429a cmp r2, r3 + 800a86a: d10b bne.n 800a884 + if (++n > (UDP_LOCAL_PORT_RANGE_END - UDP_LOCAL_PORT_RANGE_START)) { + 800a86c: 1dbb adds r3, r7, #6 + 800a86e: 1dba adds r2, r7, #6 + 800a870: 8812 ldrh r2, [r2, #0] + 800a872: 3201 adds r2, #1 + 800a874: 801a strh r2, [r3, #0] + 800a876: 1dbb adds r3, r7, #6 + 800a878: 881b ldrh r3, [r3, #0] + 800a87a: 4a0c ldr r2, [pc, #48] ; (800a8ac ) + 800a87c: 4293 cmp r3, r2 + 800a87e: d9df bls.n 800a840 + return 0; + 800a880: 2300 movs r3, #0 + 800a882: e007 b.n 800a894 + for(pcb = udp_pcbs; pcb != NULL; pcb = pcb->next) { + 800a884: 683b ldr r3, [r7, #0] + 800a886: 68db ldr r3, [r3, #12] + 800a888: 603b str r3, [r7, #0] + 800a88a: 683b ldr r3, [r7, #0] + 800a88c: 2b00 cmp r3, #0 + 800a88e: d1e7 bne.n 800a860 + } + goto again; + } + } + return udp_port; + 800a890: 4b02 ldr r3, [pc, #8] ; (800a89c ) + 800a892: 881b ldrh r3, [r3, #0] + if (ipcb != NULL) { + return 0; + } + return udp_port; +#endif +} + 800a894: 0018 movs r0, r3 + 800a896: 46bd mov sp, r7 + 800a898: b002 add sp, #8 + 800a89a: bd80 pop {r7, pc} + 800a89c: 20000014 .word 0x20000014 + 800a8a0: 0000ffff .word 0x0000ffff + 800a8a4: ffffc000 .word 0xffffc000 + 800a8a8: 20003290 .word 0x20003290 + 800a8ac: 00003fff .word 0x00003fff + +0800a8b0 : + * @param inp network interface on which the datagram was received. + * + */ +void +udp_input(struct pbuf *p, struct netif *inp) +{ + 800a8b0: b5b0 push {r4, r5, r7, lr} + 800a8b2: b08c sub sp, #48 ; 0x30 + 800a8b4: af02 add r7, sp, #8 + 800a8b6: 6078 str r0, [r7, #4] + 800a8b8: 6039 str r1, [r7, #0] + u8_t local_match; + u8_t broadcast; + + PERF_START; + + UDP_STATS_INC(udp.recv); + 800a8ba: 4bc4 ldr r3, [pc, #784] ; (800abcc ) + 800a8bc: 227a movs r2, #122 ; 0x7a + 800a8be: 5a9b ldrh r3, [r3, r2] + 800a8c0: 3301 adds r3, #1 + 800a8c2: b299 uxth r1, r3 + 800a8c4: 4bc1 ldr r3, [pc, #772] ; (800abcc ) + 800a8c6: 227a movs r2, #122 ; 0x7a + 800a8c8: 5299 strh r1, [r3, r2] + + iphdr = (struct ip_hdr *)p->payload; + 800a8ca: 687b ldr r3, [r7, #4] + 800a8cc: 685b ldr r3, [r3, #4] + 800a8ce: 617b str r3, [r7, #20] + + /* Check minimum length (IP header + UDP header) + * and move payload pointer to UDP header */ + if (p->tot_len < (IPH_HL(iphdr) * 4 + UDP_HLEN) || pbuf_header(p, -(s16_t)(IPH_HL(iphdr) * 4))) { + 800a8d0: 687b ldr r3, [r7, #4] + 800a8d2: 891b ldrh r3, [r3, #8] + 800a8d4: 001a movs r2, r3 + 800a8d6: 697b ldr r3, [r7, #20] + 800a8d8: 781b ldrb r3, [r3, #0] + 800a8da: 0019 movs r1, r3 + 800a8dc: 230f movs r3, #15 + 800a8de: 400b ands r3, r1 + 800a8e0: 3302 adds r3, #2 + 800a8e2: 009b lsls r3, r3, #2 + 800a8e4: 429a cmp r2, r3 + 800a8e6: db11 blt.n 800a90c + 800a8e8: 697b ldr r3, [r7, #20] + 800a8ea: 781b ldrb r3, [r3, #0] + 800a8ec: b29b uxth r3, r3 + 800a8ee: 220f movs r2, #15 + 800a8f0: 4013 ands r3, r2 + 800a8f2: b29b uxth r3, r3 + 800a8f4: 009b lsls r3, r3, #2 + 800a8f6: b29b uxth r3, r3 + 800a8f8: 425b negs r3, r3 + 800a8fa: b29b uxth r3, r3 + 800a8fc: b21a sxth r2, r3 + 800a8fe: 687b ldr r3, [r7, #4] + 800a900: 0011 movs r1, r2 + 800a902: 0018 movs r0, r3 + 800a904: f7fa fe47 bl 8005596 + 800a908: 1e03 subs r3, r0, #0 + 800a90a: d014 beq.n 800a936 + /* drop short packets */ + LWIP_DEBUGF(UDP_DEBUG, + ("udp_input: short UDP datagram (%"U16_F" bytes) discarded\n", p->tot_len)); + UDP_STATS_INC(udp.lenerr); + 800a90c: 4baf ldr r3, [pc, #700] ; (800abcc ) + 800a90e: 2282 movs r2, #130 ; 0x82 + 800a910: 5a9b ldrh r3, [r3, r2] + 800a912: 3301 adds r3, #1 + 800a914: b299 uxth r1, r3 + 800a916: 4bad ldr r3, [pc, #692] ; (800abcc ) + 800a918: 2282 movs r2, #130 ; 0x82 + 800a91a: 5299 strh r1, [r3, r2] + UDP_STATS_INC(udp.drop); + 800a91c: 4bab ldr r3, [pc, #684] ; (800abcc ) + 800a91e: 227e movs r2, #126 ; 0x7e + 800a920: 5a9b ldrh r3, [r3, r2] + 800a922: 3301 adds r3, #1 + 800a924: b299 uxth r1, r3 + 800a926: 4ba9 ldr r3, [pc, #676] ; (800abcc ) + 800a928: 227e movs r2, #126 ; 0x7e + 800a92a: 5299 strh r1, [r3, r2] + snmp_inc_udpinerrors(); + pbuf_free(p); + 800a92c: 687b ldr r3, [r7, #4] + 800a92e: 0018 movs r0, r3 + 800a930: f7fa feb8 bl 80056a4 + goto end; + 800a934: e156 b.n 800abe4 + } + + udphdr = (struct udp_hdr *)p->payload; + 800a936: 687b ldr r3, [r7, #4] + 800a938: 685b ldr r3, [r3, #4] + 800a93a: 613b str r3, [r7, #16] + + /* is broadcast packet ? */ + broadcast = ip_addr_isbroadcast(¤t_iphdr_dest, inp); + 800a93c: 4ba4 ldr r3, [pc, #656] ; (800abd0 ) + 800a93e: 681b ldr r3, [r3, #0] + 800a940: 220f movs r2, #15 + 800a942: 18bc adds r4, r7, r2 + 800a944: 683a ldr r2, [r7, #0] + 800a946: 0011 movs r1, r2 + 800a948: 0018 movs r0, r3 + 800a94a: f001 fb97 bl 800c07c + 800a94e: 0003 movs r3, r0 + 800a950: 7023 strb r3, [r4, #0] + + LWIP_DEBUGF(UDP_DEBUG, ("udp_input: received datagram of length %"U16_F"\n", p->tot_len)); + + /* convert src and dest ports to host byte order */ + src = ntohs(udphdr->src); + 800a952: 693b ldr r3, [r7, #16] + 800a954: 781a ldrb r2, [r3, #0] + 800a956: 785b ldrb r3, [r3, #1] + 800a958: 021b lsls r3, r3, #8 + 800a95a: 4313 orrs r3, r2 + 800a95c: b29b uxth r3, r3 + 800a95e: 220c movs r2, #12 + 800a960: 18bc adds r4, r7, r2 + 800a962: 0018 movs r0, r3 + 800a964: f7f9 fe6c bl 8004640 + 800a968: 0003 movs r3, r0 + 800a96a: 8023 strh r3, [r4, #0] + dest = ntohs(udphdr->dest); + 800a96c: 693b ldr r3, [r7, #16] + 800a96e: 789a ldrb r2, [r3, #2] + 800a970: 78db ldrb r3, [r3, #3] + 800a972: 021b lsls r3, r3, #8 + 800a974: 4313 orrs r3, r2 + 800a976: b29b uxth r3, r3 + 800a978: 220a movs r2, #10 + 800a97a: 18bc adds r4, r7, r2 + 800a97c: 0018 movs r0, r3 + 800a97e: f7f9 fe5f bl 8004640 + 800a982: 0003 movs r3, r0 + 800a984: 8023 strh r3, [r4, #0] + } + } + } else +#endif /* LWIP_DHCP */ + { + prev = NULL; + 800a986: 2300 movs r3, #0 + 800a988: 623b str r3, [r7, #32] + local_match = 0; + 800a98a: 231b movs r3, #27 + 800a98c: 18fb adds r3, r7, r3 + 800a98e: 2200 movs r2, #0 + 800a990: 701a strb r2, [r3, #0] + uncon_pcb = NULL; + 800a992: 2300 movs r3, #0 + 800a994: 61fb str r3, [r7, #28] + /* Iterate through the UDP pcb list for a matching pcb. + * 'Perfect match' pcbs (connected to the remote port & ip address) are + * preferred. If no perfect match is found, the first unconnected pcb that + * matches the local port and ip address gets the datagram. */ + for (pcb = udp_pcbs; pcb != NULL; pcb = pcb->next) { + 800a996: 4b8f ldr r3, [pc, #572] ; (800abd4 ) + 800a998: 681b ldr r3, [r3, #0] + 800a99a: 627b str r3, [r7, #36] ; 0x24 + 800a99c: e077 b.n 800aa8e + local_match = 0; + 800a99e: 231b movs r3, #27 + 800a9a0: 18fb adds r3, r7, r3 + 800a9a2: 2200 movs r2, #0 + 800a9a4: 701a strb r2, [r3, #0] + ip4_addr3_16(&pcb->local_ip), ip4_addr4_16(&pcb->local_ip), pcb->local_port, + ip4_addr1_16(&pcb->remote_ip), ip4_addr2_16(&pcb->remote_ip), + ip4_addr3_16(&pcb->remote_ip), ip4_addr4_16(&pcb->remote_ip), pcb->remote_port)); + + /* compare PCB local addr+port to UDP destination addr+port */ + if (pcb->local_port == dest) { + 800a9a6: 6a7b ldr r3, [r7, #36] ; 0x24 + 800a9a8: 8a5b ldrh r3, [r3, #18] + 800a9aa: 220a movs r2, #10 + 800a9ac: 18ba adds r2, r7, r2 + 800a9ae: 8812 ldrh r2, [r2, #0] + 800a9b0: 429a cmp r2, r3 + 800a9b2: d135 bne.n 800aa20 + if ( + 800a9b4: 230f movs r3, #15 + 800a9b6: 18fb adds r3, r7, r3 + 800a9b8: 781b ldrb r3, [r3, #0] + 800a9ba: 2b00 cmp r3, #0 + 800a9bc: d106 bne.n 800a9cc + (!broadcast && ip_addr_isany(&pcb->local_ip)) || + 800a9be: 6a7b ldr r3, [r7, #36] ; 0x24 + 800a9c0: 2b00 cmp r3, #0 + 800a9c2: d01e beq.n 800aa02 + 800a9c4: 6a7b ldr r3, [r7, #36] ; 0x24 + 800a9c6: 681b ldr r3, [r3, #0] + 800a9c8: 2b00 cmp r3, #0 + 800a9ca: d01a beq.n 800aa02 + ip_addr_cmp(&(pcb->local_ip), ¤t_iphdr_dest) || + 800a9cc: 6a7b ldr r3, [r7, #36] ; 0x24 + 800a9ce: 681a ldr r2, [r3, #0] + 800a9d0: 4b7f ldr r3, [pc, #508] ; (800abd0 ) + 800a9d2: 681b ldr r3, [r3, #0] + (!broadcast && ip_addr_isany(&pcb->local_ip)) || + 800a9d4: 429a cmp r2, r3 + 800a9d6: d014 beq.n 800aa02 + ip_addr_cmp(&(pcb->local_ip), ¤t_iphdr_dest) || + 800a9d8: 230f movs r3, #15 + 800a9da: 18fb adds r3, r7, r3 + 800a9dc: 781b ldrb r3, [r3, #0] + 800a9de: 2b00 cmp r3, #0 + 800a9e0: d01e beq.n 800aa20 + (broadcast && ip_get_option(pcb, SOF_BROADCAST) && + (ip_addr_isany(&pcb->local_ip) || + ip_addr_netcmp(&pcb->local_ip, ip_current_dest_addr(), &inp->netmask)))) { +#else /* IP_SOF_BROADCAST_RECV */ + (broadcast && + (ip_addr_isany(&pcb->local_ip) || + 800a9e2: 6a7b ldr r3, [r7, #36] ; 0x24 + (broadcast && + 800a9e4: 2b00 cmp r3, #0 + 800a9e6: d00c beq.n 800aa02 + (ip_addr_isany(&pcb->local_ip) || + 800a9e8: 6a7b ldr r3, [r7, #36] ; 0x24 + 800a9ea: 681b ldr r3, [r3, #0] + 800a9ec: 2b00 cmp r3, #0 + 800a9ee: d008 beq.n 800aa02 + ip_addr_netcmp(&pcb->local_ip, ip_current_dest_addr(), &inp->netmask)))) { + 800a9f0: 6a7b ldr r3, [r7, #36] ; 0x24 + 800a9f2: 681a ldr r2, [r3, #0] + 800a9f4: 4b76 ldr r3, [pc, #472] ; (800abd0 ) + 800a9f6: 681b ldr r3, [r3, #0] + 800a9f8: 405a eors r2, r3 + 800a9fa: 683b ldr r3, [r7, #0] + 800a9fc: 689b ldr r3, [r3, #8] + 800a9fe: 4013 ands r3, r2 + (ip_addr_isany(&pcb->local_ip) || + 800aa00: d10e bne.n 800aa20 +#endif /* IP_SOF_BROADCAST_RECV */ + local_match = 1; + 800aa02: 231b movs r3, #27 + 800aa04: 18fb adds r3, r7, r3 + 800aa06: 2201 movs r2, #1 + 800aa08: 701a strb r2, [r3, #0] + if ((uncon_pcb == NULL) && + 800aa0a: 69fb ldr r3, [r7, #28] + 800aa0c: 2b00 cmp r3, #0 + 800aa0e: d107 bne.n 800aa20 + ((pcb->flags & UDP_FLAGS_CONNECTED) == 0)) { + 800aa10: 6a7b ldr r3, [r7, #36] ; 0x24 + 800aa12: 7c1b ldrb r3, [r3, #16] + 800aa14: 001a movs r2, r3 + 800aa16: 2304 movs r3, #4 + 800aa18: 4013 ands r3, r2 + if ((uncon_pcb == NULL) && + 800aa1a: d101 bne.n 800aa20 + /* the first unconnected matching PCB */ + uncon_pcb = pcb; + 800aa1c: 6a7b ldr r3, [r7, #36] ; 0x24 + 800aa1e: 61fb str r3, [r7, #28] + } + } + } + /* compare PCB remote addr+port to UDP source addr+port */ + if ((local_match != 0) && + 800aa20: 231b movs r3, #27 + 800aa22: 18fb adds r3, r7, r3 + 800aa24: 781b ldrb r3, [r3, #0] + 800aa26: 2b00 cmp r3, #0 + 800aa28: d02c beq.n 800aa84 + (pcb->remote_port == src) && + 800aa2a: 6a7b ldr r3, [r7, #36] ; 0x24 + 800aa2c: 8a9b ldrh r3, [r3, #20] + if ((local_match != 0) && + 800aa2e: 220c movs r2, #12 + 800aa30: 18ba adds r2, r7, r2 + 800aa32: 8812 ldrh r2, [r2, #0] + 800aa34: 429a cmp r2, r3 + 800aa36: d125 bne.n 800aa84 + (ip_addr_isany(&pcb->remote_ip) || + 800aa38: 6a7b ldr r3, [r7, #36] ; 0x24 + 800aa3a: 3304 adds r3, #4 + (pcb->remote_port == src) && + 800aa3c: 2b00 cmp r3, #0 + 800aa3e: d009 beq.n 800aa54 + (ip_addr_isany(&pcb->remote_ip) || + 800aa40: 6a7b ldr r3, [r7, #36] ; 0x24 + 800aa42: 685b ldr r3, [r3, #4] + 800aa44: 2b00 cmp r3, #0 + 800aa46: d005 beq.n 800aa54 + ip_addr_cmp(&(pcb->remote_ip), ¤t_iphdr_src))) { + 800aa48: 6a7b ldr r3, [r7, #36] ; 0x24 + 800aa4a: 685a ldr r2, [r3, #4] + 800aa4c: 4b62 ldr r3, [pc, #392] ; (800abd8 ) + 800aa4e: 681b ldr r3, [r3, #0] + (ip_addr_isany(&pcb->remote_ip) || + 800aa50: 429a cmp r2, r3 + 800aa52: d117 bne.n 800aa84 + /* the first fully matching PCB */ + if (prev != NULL) { + 800aa54: 6a3b ldr r3, [r7, #32] + 800aa56: 2b00 cmp r3, #0 + 800aa58: d00b beq.n 800aa72 + /* move the pcb to the front of udp_pcbs so that is + found faster next time */ + prev->next = pcb->next; + 800aa5a: 6a7b ldr r3, [r7, #36] ; 0x24 + 800aa5c: 68da ldr r2, [r3, #12] + 800aa5e: 6a3b ldr r3, [r7, #32] + 800aa60: 60da str r2, [r3, #12] + pcb->next = udp_pcbs; + 800aa62: 4b5c ldr r3, [pc, #368] ; (800abd4 ) + 800aa64: 681a ldr r2, [r3, #0] + 800aa66: 6a7b ldr r3, [r7, #36] ; 0x24 + 800aa68: 60da str r2, [r3, #12] + udp_pcbs = pcb; + 800aa6a: 4b5a ldr r3, [pc, #360] ; (800abd4 ) + 800aa6c: 6a7a ldr r2, [r7, #36] ; 0x24 + 800aa6e: 601a str r2, [r3, #0] + } else { + UDP_STATS_INC(udp.cachehit); + } + break; + 800aa70: e011 b.n 800aa96 + UDP_STATS_INC(udp.cachehit); + 800aa72: 4b56 ldr r3, [pc, #344] ; (800abcc ) + 800aa74: 228e movs r2, #142 ; 0x8e + 800aa76: 5a9b ldrh r3, [r3, r2] + 800aa78: 3301 adds r3, #1 + 800aa7a: b299 uxth r1, r3 + 800aa7c: 4b53 ldr r3, [pc, #332] ; (800abcc ) + 800aa7e: 228e movs r2, #142 ; 0x8e + 800aa80: 5299 strh r1, [r3, r2] + break; + 800aa82: e008 b.n 800aa96 + } + prev = pcb; + 800aa84: 6a7b ldr r3, [r7, #36] ; 0x24 + 800aa86: 623b str r3, [r7, #32] + for (pcb = udp_pcbs; pcb != NULL; pcb = pcb->next) { + 800aa88: 6a7b ldr r3, [r7, #36] ; 0x24 + 800aa8a: 68db ldr r3, [r3, #12] + 800aa8c: 627b str r3, [r7, #36] ; 0x24 + 800aa8e: 6a7b ldr r3, [r7, #36] ; 0x24 + 800aa90: 2b00 cmp r3, #0 + 800aa92: d000 beq.n 800aa96 + 800aa94: e783 b.n 800a99e + } + /* no fully matching pcb found? then look for an unconnected pcb */ + if (pcb == NULL) { + 800aa96: 6a7b ldr r3, [r7, #36] ; 0x24 + 800aa98: 2b00 cmp r3, #0 + 800aa9a: d101 bne.n 800aaa0 + pcb = uncon_pcb; + 800aa9c: 69fb ldr r3, [r7, #28] + 800aa9e: 627b str r3, [r7, #36] ; 0x24 + } + } + + /* Check checksum if this is a match or if it was directed at us. */ + if (pcb != NULL || ip_addr_cmp(&inp->ip_addr, ¤t_iphdr_dest)) { + 800aaa0: 6a7b ldr r3, [r7, #36] ; 0x24 + 800aaa2: 2b00 cmp r3, #0 + 800aaa4: d106 bne.n 800aab4 + 800aaa6: 683b ldr r3, [r7, #0] + 800aaa8: 685a ldr r2, [r3, #4] + 800aaaa: 4b49 ldr r3, [pc, #292] ; (800abd0 ) + 800aaac: 681b ldr r3, [r3, #0] + 800aaae: 429a cmp r2, r3 + 800aab0: d000 beq.n 800aab4 + 800aab2: e093 b.n 800abdc +#endif /* CHECKSUM_CHECK_UDP */ + } else +#endif /* LWIP_UDPLITE */ + { +#if CHECKSUM_CHECK_UDP + if (udphdr->chksum != 0) { + 800aab4: 693b ldr r3, [r7, #16] + 800aab6: 799a ldrb r2, [r3, #6] + 800aab8: 79db ldrb r3, [r3, #7] + 800aaba: 021b lsls r3, r3, #8 + 800aabc: 4313 orrs r3, r2 + 800aabe: b29b uxth r3, r3 + 800aac0: 2b00 cmp r3, #0 + 800aac2: d01f beq.n 800ab04 + if (inet_chksum_pseudo(p, ip_current_src_addr(), ip_current_dest_addr(), + 800aac4: 687b ldr r3, [r7, #4] + 800aac6: 891b ldrh r3, [r3, #8] + 800aac8: 4a41 ldr r2, [pc, #260] ; (800abd0 ) + 800aaca: 4943 ldr r1, [pc, #268] ; (800abd8 ) + 800aacc: 6878 ldr r0, [r7, #4] + 800aace: 9300 str r3, [sp, #0] + 800aad0: 2311 movs r3, #17 + 800aad2: f000 fdb2 bl 800b63a + 800aad6: 1e03 subs r3, r0, #0 + 800aad8: d014 beq.n 800ab04 + IP_PROTO_UDP, p->tot_len) != 0) { + LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, + ("udp_input: UDP datagram discarded due to failing checksum\n")); + UDP_STATS_INC(udp.chkerr); + 800aada: 4b3c ldr r3, [pc, #240] ; (800abcc ) + 800aadc: 2280 movs r2, #128 ; 0x80 + 800aade: 5a9b ldrh r3, [r3, r2] + 800aae0: 3301 adds r3, #1 + 800aae2: b299 uxth r1, r3 + 800aae4: 4b39 ldr r3, [pc, #228] ; (800abcc ) + 800aae6: 2280 movs r2, #128 ; 0x80 + 800aae8: 5299 strh r1, [r3, r2] + UDP_STATS_INC(udp.drop); + 800aaea: 4b38 ldr r3, [pc, #224] ; (800abcc ) + 800aaec: 227e movs r2, #126 ; 0x7e + 800aaee: 5a9b ldrh r3, [r3, r2] + 800aaf0: 3301 adds r3, #1 + 800aaf2: b299 uxth r1, r3 + 800aaf4: 4b35 ldr r3, [pc, #212] ; (800abcc ) + 800aaf6: 227e movs r2, #126 ; 0x7e + 800aaf8: 5299 strh r1, [r3, r2] + snmp_inc_udpinerrors(); + pbuf_free(p); + 800aafa: 687b ldr r3, [r7, #4] + 800aafc: 0018 movs r0, r3 + 800aafe: f7fa fdd1 bl 80056a4 + goto end; + 800ab02: e06f b.n 800abe4 + } + } +#endif /* CHECKSUM_CHECK_UDP */ + } + if(pbuf_header(p, -UDP_HLEN)) { + 800ab04: 2308 movs r3, #8 + 800ab06: 425a negs r2, r3 + 800ab08: 687b ldr r3, [r7, #4] + 800ab0a: 0011 movs r1, r2 + 800ab0c: 0018 movs r0, r3 + 800ab0e: f7fa fd42 bl 8005596 + 800ab12: 1e03 subs r3, r0, #0 + 800ab14: d00c beq.n 800ab30 + /* Can we cope with this failing? Just assert for now */ + LWIP_ASSERT("pbuf_header failed\n", 0); + UDP_STATS_INC(udp.drop); + 800ab16: 4b2d ldr r3, [pc, #180] ; (800abcc ) + 800ab18: 227e movs r2, #126 ; 0x7e + 800ab1a: 5a9b ldrh r3, [r3, r2] + 800ab1c: 3301 adds r3, #1 + 800ab1e: b299 uxth r1, r3 + 800ab20: 4b2a ldr r3, [pc, #168] ; (800abcc ) + 800ab22: 227e movs r2, #126 ; 0x7e + 800ab24: 5299 strh r1, [r3, r2] + snmp_inc_udpinerrors(); + pbuf_free(p); + 800ab26: 687b ldr r3, [r7, #4] + 800ab28: 0018 movs r0, r3 + 800ab2a: f7fa fdbb bl 80056a4 + goto end; + 800ab2e: e059 b.n 800abe4 + } + if (pcb != NULL) { + 800ab30: 6a7b ldr r3, [r7, #36] ; 0x24 + 800ab32: 2b00 cmp r3, #0 + 800ab34: d016 beq.n 800ab64 + pbuf_header(p, -(s16_t)((IPH_HL(iphdr) * 4) + UDP_HLEN)); + } + } +#endif /* SO_REUSE && SO_REUSE_RXTOALL */ + /* callback */ + if (pcb->recv != NULL) { + 800ab36: 6a7b ldr r3, [r7, #36] ; 0x24 + 800ab38: 699b ldr r3, [r3, #24] + 800ab3a: 2b00 cmp r3, #0 + 800ab3c: d00d beq.n 800ab5a + /* now the recv function is responsible for freeing p */ + pcb->recv(pcb->recv_arg, pcb, p, ip_current_src_addr(), src); + 800ab3e: 6a7b ldr r3, [r7, #36] ; 0x24 + 800ab40: 699c ldr r4, [r3, #24] + 800ab42: 6a7b ldr r3, [r7, #36] ; 0x24 + 800ab44: 69d8 ldr r0, [r3, #28] + 800ab46: 4d24 ldr r5, [pc, #144] ; (800abd8 ) + 800ab48: 687a ldr r2, [r7, #4] + 800ab4a: 6a79 ldr r1, [r7, #36] ; 0x24 + 800ab4c: 230c movs r3, #12 + 800ab4e: 18fb adds r3, r7, r3 + 800ab50: 881b ldrh r3, [r3, #0] + 800ab52: 9300 str r3, [sp, #0] + 800ab54: 002b movs r3, r5 + 800ab56: 47a0 blx r4 + if (pcb != NULL) { + 800ab58: e044 b.n 800abe4 + } else { + /* no recv function registered? then we have to free the pbuf! */ + pbuf_free(p); + 800ab5a: 687b ldr r3, [r7, #4] + 800ab5c: 0018 movs r0, r3 + 800ab5e: f7fa fda1 bl 80056a4 + goto end; + 800ab62: e03f b.n 800abe4 + LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, ("udp_input: not for us.\n")); + +#if LWIP_ICMP + /* No match was found, send ICMP destination port unreachable unless + destination address was broadcast/multicast. */ + if (!broadcast && + 800ab64: 230f movs r3, #15 + 800ab66: 18fb adds r3, r7, r3 + 800ab68: 781b ldrb r3, [r3, #0] + 800ab6a: 2b00 cmp r3, #0 + 800ab6c: d119 bne.n 800aba2 + !ip_addr_ismulticast(¤t_iphdr_dest)) { + 800ab6e: 4b18 ldr r3, [pc, #96] ; (800abd0 ) + 800ab70: 681b ldr r3, [r3, #0] + 800ab72: 22f0 movs r2, #240 ; 0xf0 + 800ab74: 4013 ands r3, r2 + if (!broadcast && + 800ab76: 2be0 cmp r3, #224 ; 0xe0 + 800ab78: d013 beq.n 800aba2 + /* move payload pointer back to ip header */ + pbuf_header(p, (IPH_HL(iphdr) * 4) + UDP_HLEN); + 800ab7a: 697b ldr r3, [r7, #20] + 800ab7c: 781b ldrb r3, [r3, #0] + 800ab7e: 001a movs r2, r3 + 800ab80: 230f movs r3, #15 + 800ab82: 4013 ands r3, r2 + 800ab84: 3302 adds r3, #2 + 800ab86: b29b uxth r3, r3 + 800ab88: 009b lsls r3, r3, #2 + 800ab8a: b29b uxth r3, r3 + 800ab8c: b21a sxth r2, r3 + 800ab8e: 687b ldr r3, [r7, #4] + 800ab90: 0011 movs r1, r2 + 800ab92: 0018 movs r0, r3 + 800ab94: f7fa fcff bl 8005596 + LWIP_ASSERT("p->payload == iphdr", (p->payload == iphdr)); + icmp_dest_unreach(p, ICMP_DUR_PORT); + 800ab98: 687b ldr r3, [r7, #4] + 800ab9a: 2103 movs r1, #3 + 800ab9c: 0018 movs r0, r3 + 800ab9e: f000 fc35 bl 800b40c + } +#endif /* LWIP_ICMP */ + UDP_STATS_INC(udp.proterr); + 800aba2: 4b0a ldr r3, [pc, #40] ; (800abcc ) + 800aba4: 2288 movs r2, #136 ; 0x88 + 800aba6: 5a9b ldrh r3, [r3, r2] + 800aba8: 3301 adds r3, #1 + 800abaa: b299 uxth r1, r3 + 800abac: 4b07 ldr r3, [pc, #28] ; (800abcc ) + 800abae: 2288 movs r2, #136 ; 0x88 + 800abb0: 5299 strh r1, [r3, r2] + UDP_STATS_INC(udp.drop); + 800abb2: 4b06 ldr r3, [pc, #24] ; (800abcc ) + 800abb4: 227e movs r2, #126 ; 0x7e + 800abb6: 5a9b ldrh r3, [r3, r2] + 800abb8: 3301 adds r3, #1 + 800abba: b299 uxth r1, r3 + 800abbc: 4b03 ldr r3, [pc, #12] ; (800abcc ) + 800abbe: 227e movs r2, #126 ; 0x7e + 800abc0: 5299 strh r1, [r3, r2] + snmp_inc_udpnoports(); + pbuf_free(p); + 800abc2: 687b ldr r3, [r7, #4] + 800abc4: 0018 movs r0, r3 + 800abc6: f7fa fd6d bl 80056a4 + if (pcb != NULL) { + 800abca: e00b b.n 800abe4 + 800abcc: 20003158 .word 0x20003158 + 800abd0: 2000329c .word 0x2000329c + 800abd4: 20003290 .word 0x20003290 + 800abd8: 20003294 .word 0x20003294 + } + } else { + pbuf_free(p); + 800abdc: 687b ldr r3, [r7, #4] + 800abde: 0018 movs r0, r3 + 800abe0: f7fa fd60 bl 80056a4 + } +end: + PERF_STOP("udp_input"); +} + 800abe4: 46c0 nop ; (mov r8, r8) + 800abe6: 46bd mov sp, r7 + 800abe8: b00a add sp, #40 ; 0x28 + 800abea: bdb0 pop {r4, r5, r7, pc} + +0800abec : + * @see udp_disconnect() udp_send() + */ +err_t +udp_sendto(struct udp_pcb *pcb, struct pbuf *p, + ip_addr_t *dst_ip, u16_t dst_port) +{ + 800abec: b590 push {r4, r7, lr} + 800abee: b089 sub sp, #36 ; 0x24 + 800abf0: af02 add r7, sp, #8 + 800abf2: 60f8 str r0, [r7, #12] + 800abf4: 60b9 str r1, [r7, #8] + 800abf6: 607a str r2, [r7, #4] + 800abf8: 001a movs r2, r3 + 800abfa: 1cbb adds r3, r7, #2 + 800abfc: 801a strh r2, [r3, #0] + + /* find the outgoing network interface for this packet */ +#if LWIP_IGMP + netif = ip_route((ip_addr_ismulticast(dst_ip))?(&(pcb->multicast_ip)):(dst_ip)); +#else + netif = ip_route(dst_ip); + 800abfe: 687b ldr r3, [r7, #4] + 800ac00: 0018 movs r0, r3 + 800ac02: f000 fe21 bl 800b848 + 800ac06: 0003 movs r3, r0 + 800ac08: 617b str r3, [r7, #20] +#endif /* LWIP_IGMP */ + + /* no outgoing network interface could be found? */ + if (netif == NULL) { + 800ac0a: 697b ldr r3, [r7, #20] + 800ac0c: 2b00 cmp r3, #0 + 800ac0e: d10a bne.n 800ac26 + LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("udp_send: No route to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", + ip4_addr1_16(dst_ip), ip4_addr2_16(dst_ip), ip4_addr3_16(dst_ip), ip4_addr4_16(dst_ip))); + UDP_STATS_INC(udp.rterr); + 800ac10: 4b0c ldr r3, [pc, #48] ; (800ac44 ) + 800ac12: 2286 movs r2, #134 ; 0x86 + 800ac14: 5a9b ldrh r3, [r3, r2] + 800ac16: 3301 adds r3, #1 + 800ac18: b299 uxth r1, r3 + 800ac1a: 4b0a ldr r3, [pc, #40] ; (800ac44 ) + 800ac1c: 2286 movs r2, #134 ; 0x86 + 800ac1e: 5299 strh r1, [r3, r2] + return ERR_RTE; + 800ac20: 2304 movs r3, #4 + 800ac22: 425b negs r3, r3 + 800ac24: e00a b.n 800ac3c + } +#if LWIP_CHECKSUM_ON_COPY + return udp_sendto_if_chksum(pcb, p, dst_ip, dst_port, netif, have_chksum, chksum); +#else /* LWIP_CHECKSUM_ON_COPY */ + return udp_sendto_if(pcb, p, dst_ip, dst_port, netif); + 800ac26: 1cbb adds r3, r7, #2 + 800ac28: 881c ldrh r4, [r3, #0] + 800ac2a: 687a ldr r2, [r7, #4] + 800ac2c: 68b9 ldr r1, [r7, #8] + 800ac2e: 68f8 ldr r0, [r7, #12] + 800ac30: 697b ldr r3, [r7, #20] + 800ac32: 9300 str r3, [sp, #0] + 800ac34: 0023 movs r3, r4 + 800ac36: f000 f807 bl 800ac48 + 800ac3a: 0003 movs r3, r0 +#endif /* LWIP_CHECKSUM_ON_COPY */ +} + 800ac3c: 0018 movs r0, r3 + 800ac3e: 46bd mov sp, r7 + 800ac40: b007 add sp, #28 + 800ac42: bd90 pop {r4, r7, pc} + 800ac44: 20003158 .word 0x20003158 + +0800ac48 : + * @see udp_disconnect() udp_send() + */ +err_t +udp_sendto_if(struct udp_pcb *pcb, struct pbuf *p, + ip_addr_t *dst_ip, u16_t dst_port, struct netif *netif) +{ + 800ac48: b5f0 push {r4, r5, r6, r7, lr} + 800ac4a: b08d sub sp, #52 ; 0x34 + 800ac4c: af04 add r7, sp, #16 + 800ac4e: 60f8 str r0, [r7, #12] + 800ac50: 60b9 str r1, [r7, #8] + 800ac52: 607a str r2, [r7, #4] + 800ac54: 001a movs r2, r3 + 800ac56: 1cbb adds r3, r7, #2 + 800ac58: 801a strh r2, [r3, #0] + return ERR_VAL; + } +#endif /* IP_SOF_BROADCAST */ + + /* if the PCB is not yet bound to a port, bind it here */ + if (pcb->local_port == 0) { + 800ac5a: 68fb ldr r3, [r7, #12] + 800ac5c: 8a5b ldrh r3, [r3, #18] + 800ac5e: 2b00 cmp r3, #0 + 800ac60: d114 bne.n 800ac8c + LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, ("udp_send: not yet bound to a port, binding now\n")); + err = udp_bind(pcb, &pcb->local_ip, pcb->local_port); + 800ac62: 68f9 ldr r1, [r7, #12] + 800ac64: 68fb ldr r3, [r7, #12] + 800ac66: 8a5a ldrh r2, [r3, #18] + 800ac68: 2515 movs r5, #21 + 800ac6a: 197c adds r4, r7, r5 + 800ac6c: 68fb ldr r3, [r7, #12] + 800ac6e: 0018 movs r0, r3 + 800ac70: f000 f90a bl 800ae88 + 800ac74: 0003 movs r3, r0 + 800ac76: 7023 strb r3, [r4, #0] + if (err != ERR_OK) { + 800ac78: 197b adds r3, r7, r5 + 800ac7a: 781b ldrb r3, [r3, #0] + 800ac7c: b25b sxtb r3, r3 + 800ac7e: 2b00 cmp r3, #0 + 800ac80: d004 beq.n 800ac8c + LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("udp_send: forced port bind failed\n")); + return err; + 800ac82: 2315 movs r3, #21 + 800ac84: 18fb adds r3, r7, r3 + 800ac86: 781b ldrb r3, [r3, #0] + 800ac88: b25b sxtb r3, r3 + 800ac8a: e0f6 b.n 800ae7a + } + } + + /* not enough space to add an UDP header to first pbuf in given p chain? */ + if (pbuf_header(p, UDP_HLEN)) { + 800ac8c: 68bb ldr r3, [r7, #8] + 800ac8e: 2108 movs r1, #8 + 800ac90: 0018 movs r0, r3 + 800ac92: f7fa fc80 bl 8005596 + 800ac96: 1e03 subs r3, r0, #0 + 800ac98: d017 beq.n 800acca + /* allocate header in a separate new pbuf */ + q = pbuf_alloc(PBUF_IP, UDP_HLEN, PBUF_RAM); + 800ac9a: 2200 movs r2, #0 + 800ac9c: 2108 movs r1, #8 + 800ac9e: 2001 movs r0, #1 + 800aca0: f7fa fa74 bl 800518c + 800aca4: 0003 movs r3, r0 + 800aca6: 61bb str r3, [r7, #24] + /* new header pbuf could not be allocated? */ + if (q == NULL) { + 800aca8: 69bb ldr r3, [r7, #24] + 800acaa: 2b00 cmp r3, #0 + 800acac: d102 bne.n 800acb4 + LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("udp_send: could not allocate header\n")); + return ERR_MEM; + 800acae: 2301 movs r3, #1 + 800acb0: 425b negs r3, r3 + 800acb2: e0e2 b.n 800ae7a + } + if (p->tot_len != 0) { + 800acb4: 68bb ldr r3, [r7, #8] + 800acb6: 891b ldrh r3, [r3, #8] + 800acb8: 2b00 cmp r3, #0 + 800acba: d008 beq.n 800acce + /* chain header q in front of given pbuf p (only if p contains data) */ + pbuf_chain(q, p); + 800acbc: 68ba ldr r2, [r7, #8] + 800acbe: 69bb ldr r3, [r7, #24] + 800acc0: 0011 movs r1, r2 + 800acc2: 0018 movs r0, r3 + 800acc4: f7fa fdba bl 800583c + 800acc8: e001 b.n 800acce + LWIP_DEBUGF(UDP_DEBUG, + ("udp_send: added header pbuf %p before given pbuf %p\n", (void *)q, (void *)p)); + } else { + /* adding space for header within p succeeded */ + /* first pbuf q equals given pbuf */ + q = p; + 800acca: 68bb ldr r3, [r7, #8] + 800accc: 61bb str r3, [r7, #24] + LWIP_DEBUGF(UDP_DEBUG, ("udp_send: added header in given pbuf %p\n", (void *)p)); + } + LWIP_ASSERT("check that first pbuf can hold struct udp_hdr", + (q->len >= sizeof(struct udp_hdr))); + /* q now represents the packet to be sent */ + udphdr = (struct udp_hdr *)q->payload; + 800acce: 69bb ldr r3, [r7, #24] + 800acd0: 685b ldr r3, [r3, #4] + 800acd2: 613b str r3, [r7, #16] + udphdr->src = htons(pcb->local_port); + 800acd4: 68fb ldr r3, [r7, #12] + 800acd6: 8a5b ldrh r3, [r3, #18] + 800acd8: 0018 movs r0, r3 + 800acda: f7f9 fc9b bl 8004614 + 800acde: 0003 movs r3, r0 + 800ace0: 001a movs r2, r3 + 800ace2: 693b ldr r3, [r7, #16] + 800ace4: 21ff movs r1, #255 ; 0xff + 800ace6: 4011 ands r1, r2 + 800ace8: 000c movs r4, r1 + 800acea: 7819 ldrb r1, [r3, #0] + 800acec: 2000 movs r0, #0 + 800acee: 4001 ands r1, r0 + 800acf0: 1c08 adds r0, r1, #0 + 800acf2: 1c21 adds r1, r4, #0 + 800acf4: 4301 orrs r1, r0 + 800acf6: 7019 strb r1, [r3, #0] + 800acf8: 0a12 lsrs r2, r2, #8 + 800acfa: b290 uxth r0, r2 + 800acfc: 785a ldrb r2, [r3, #1] + 800acfe: 2100 movs r1, #0 + 800ad00: 400a ands r2, r1 + 800ad02: 1c11 adds r1, r2, #0 + 800ad04: 1c02 adds r2, r0, #0 + 800ad06: 430a orrs r2, r1 + 800ad08: 705a strb r2, [r3, #1] + udphdr->dest = htons(dst_port); + 800ad0a: 1cbb adds r3, r7, #2 + 800ad0c: 881b ldrh r3, [r3, #0] + 800ad0e: 0018 movs r0, r3 + 800ad10: f7f9 fc80 bl 8004614 + 800ad14: 0003 movs r3, r0 + 800ad16: 001a movs r2, r3 + 800ad18: 693b ldr r3, [r7, #16] + 800ad1a: 21ff movs r1, #255 ; 0xff + 800ad1c: 4011 ands r1, r2 + 800ad1e: 000c movs r4, r1 + 800ad20: 7899 ldrb r1, [r3, #2] + 800ad22: 2000 movs r0, #0 + 800ad24: 4001 ands r1, r0 + 800ad26: 1c08 adds r0, r1, #0 + 800ad28: 1c21 adds r1, r4, #0 + 800ad2a: 4301 orrs r1, r0 + 800ad2c: 7099 strb r1, [r3, #2] + 800ad2e: 0a12 lsrs r2, r2, #8 + 800ad30: b290 uxth r0, r2 + 800ad32: 78da ldrb r2, [r3, #3] + 800ad34: 2100 movs r1, #0 + 800ad36: 400a ands r2, r1 + 800ad38: 1c11 adds r1, r2, #0 + 800ad3a: 1c02 adds r2, r0, #0 + 800ad3c: 430a orrs r2, r1 + 800ad3e: 70da strb r2, [r3, #3] + /* in UDP, 0 checksum means 'no checksum' */ + udphdr->chksum = 0x0000; + 800ad40: 693b ldr r3, [r7, #16] + 800ad42: 799a ldrb r2, [r3, #6] + 800ad44: 2100 movs r1, #0 + 800ad46: 400a ands r2, r1 + 800ad48: 719a strb r2, [r3, #6] + 800ad4a: 79da ldrb r2, [r3, #7] + 800ad4c: 2100 movs r1, #0 + 800ad4e: 400a ands r2, r1 + 800ad50: 71da strb r2, [r3, #7] + } +#endif /* LWIP_IGMP */ + + + /* PCB local address is IP_ANY_ADDR? */ + if (ip_addr_isany(&pcb->local_ip)) { + 800ad52: 68fb ldr r3, [r7, #12] + 800ad54: 2b00 cmp r3, #0 + 800ad56: d003 beq.n 800ad60 + 800ad58: 68fb ldr r3, [r7, #12] + 800ad5a: 681b ldr r3, [r3, #0] + 800ad5c: 2b00 cmp r3, #0 + 800ad5e: d103 bne.n 800ad68 + /* use outgoing network interface IP address as source address */ + src_ip = &(netif->ip_addr); + 800ad60: 6bbb ldr r3, [r7, #56] ; 0x38 + 800ad62: 3304 adds r3, #4 + 800ad64: 61fb str r3, [r7, #28] + 800ad66: e014 b.n 800ad92 + } else { + /* check if UDP PCB local IP address is correct + * this could be an old address if netif->ip_addr has changed */ + if (!ip_addr_cmp(&(pcb->local_ip), &(netif->ip_addr))) { + 800ad68: 68fb ldr r3, [r7, #12] + 800ad6a: 681a ldr r2, [r3, #0] + 800ad6c: 6bbb ldr r3, [r7, #56] ; 0x38 + 800ad6e: 685b ldr r3, [r3, #4] + 800ad70: 429a cmp r2, r3 + 800ad72: d00c beq.n 800ad8e + /* local_ip doesn't match, drop the packet */ + if (q != p) { + 800ad74: 69ba ldr r2, [r7, #24] + 800ad76: 68bb ldr r3, [r7, #8] + 800ad78: 429a cmp r2, r3 + 800ad7a: d005 beq.n 800ad88 + /* free the header pbuf */ + pbuf_free(q); + 800ad7c: 69bb ldr r3, [r7, #24] + 800ad7e: 0018 movs r0, r3 + 800ad80: f7fa fc90 bl 80056a4 + q = NULL; + 800ad84: 2300 movs r3, #0 + 800ad86: 61bb str r3, [r7, #24] + /* p is still referenced by the caller, and will live on */ + } + return ERR_VAL; + 800ad88: 2306 movs r3, #6 + 800ad8a: 425b negs r3, r3 + 800ad8c: e075 b.n 800ae7a + } + /* use UDP PCB local IP address as source address */ + src_ip = &(pcb->local_ip); + 800ad8e: 68fb ldr r3, [r7, #12] + 800ad90: 61fb str r3, [r7, #28] + NETIF_SET_HWADDRHINT(netif, NULL); + } else +#endif /* LWIP_UDPLITE */ + { /* UDP */ + LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP packet length %"U16_F"\n", q->tot_len)); + udphdr->len = htons(q->tot_len); + 800ad92: 69bb ldr r3, [r7, #24] + 800ad94: 891b ldrh r3, [r3, #8] + 800ad96: 0018 movs r0, r3 + 800ad98: f7f9 fc3c bl 8004614 + 800ad9c: 0003 movs r3, r0 + 800ad9e: 001a movs r2, r3 + 800ada0: 693b ldr r3, [r7, #16] + 800ada2: 21ff movs r1, #255 ; 0xff + 800ada4: 4011 ands r1, r2 + 800ada6: 000c movs r4, r1 + 800ada8: 7919 ldrb r1, [r3, #4] + 800adaa: 2000 movs r0, #0 + 800adac: 4001 ands r1, r0 + 800adae: 1c08 adds r0, r1, #0 + 800adb0: 1c21 adds r1, r4, #0 + 800adb2: 4301 orrs r1, r0 + 800adb4: 7119 strb r1, [r3, #4] + 800adb6: 0a12 lsrs r2, r2, #8 + 800adb8: b290 uxth r0, r2 + 800adba: 795a ldrb r2, [r3, #5] + 800adbc: 2100 movs r1, #0 + 800adbe: 400a ands r2, r1 + 800adc0: 1c11 adds r1, r2, #0 + 800adc2: 1c02 adds r2, r0, #0 + 800adc4: 430a orrs r2, r1 + 800adc6: 715a strb r2, [r3, #5] + /* calculate checksum */ +#if CHECKSUM_GEN_UDP + if ((pcb->flags & UDP_FLAGS_NOCHKSUM) == 0) { + 800adc8: 68fb ldr r3, [r7, #12] + 800adca: 7c1b ldrb r3, [r3, #16] + 800adcc: 001a movs r2, r3 + 800adce: 2301 movs r3, #1 + 800add0: 4013 ands r3, r2 + 800add2: d128 bne.n 800ae26 + acc = udpchksum + (u16_t)~(chksum); + udpchksum = FOLD_U32T(acc); + } else +#endif /* LWIP_CHECKSUM_ON_COPY */ + { + udpchksum = inet_chksum_pseudo(q, src_ip, dst_ip, IP_PROTO_UDP, q->tot_len); + 800add4: 69bb ldr r3, [r7, #24] + 800add6: 891b ldrh r3, [r3, #8] + 800add8: 2516 movs r5, #22 + 800adda: 197c adds r4, r7, r5 + 800addc: 687a ldr r2, [r7, #4] + 800adde: 69f9 ldr r1, [r7, #28] + 800ade0: 69b8 ldr r0, [r7, #24] + 800ade2: 9300 str r3, [sp, #0] + 800ade4: 2311 movs r3, #17 + 800ade6: f000 fc28 bl 800b63a + 800adea: 0003 movs r3, r0 + 800adec: 8023 strh r3, [r4, #0] + } + + /* chksum zero must become 0xffff, as zero means 'no checksum' */ + if (udpchksum == 0x0000) { + 800adee: 197b adds r3, r7, r5 + 800adf0: 881b ldrh r3, [r3, #0] + 800adf2: 2b00 cmp r3, #0 + 800adf4: d104 bne.n 800ae00 + udpchksum = 0xffff; + 800adf6: 2316 movs r3, #22 + 800adf8: 18fb adds r3, r7, r3 + 800adfa: 2201 movs r2, #1 + 800adfc: 4252 negs r2, r2 + 800adfe: 801a strh r2, [r3, #0] + } + udphdr->chksum = udpchksum; + 800ae00: 693b ldr r3, [r7, #16] + 800ae02: 2216 movs r2, #22 + 800ae04: 18ba adds r2, r7, r2 + 800ae06: 7814 ldrb r4, [r2, #0] + 800ae08: 7999 ldrb r1, [r3, #6] + 800ae0a: 2000 movs r0, #0 + 800ae0c: 4001 ands r1, r0 + 800ae0e: 1c08 adds r0, r1, #0 + 800ae10: 1c21 adds r1, r4, #0 + 800ae12: 4301 orrs r1, r0 + 800ae14: 7199 strb r1, [r3, #6] + 800ae16: 7850 ldrb r0, [r2, #1] + 800ae18: 79da ldrb r2, [r3, #7] + 800ae1a: 2100 movs r1, #0 + 800ae1c: 400a ands r2, r1 + 800ae1e: 1c11 adds r1, r2, #0 + 800ae20: 1c02 adds r2, r0, #0 + 800ae22: 430a orrs r2, r1 + 800ae24: 71da strb r2, [r3, #7] +#endif /* CHECKSUM_GEN_UDP */ + LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP checksum 0x%04"X16_F"\n", udphdr->chksum)); + LWIP_DEBUGF(UDP_DEBUG, ("udp_send: ip_output_if (,,,,IP_PROTO_UDP,)\n")); + /* output to IP */ + NETIF_SET_HWADDRHINT(netif, &pcb->addr_hint); + err = ip_output_if(q, src_ip, dst_ip, pcb->ttl, pcb->tos, IP_PROTO_UDP, netif); + 800ae26: 68fb ldr r3, [r7, #12] + 800ae28: 7a9e ldrb r6, [r3, #10] + 800ae2a: 68fb ldr r3, [r7, #12] + 800ae2c: 7a5b ldrb r3, [r3, #9] + 800ae2e: 2215 movs r2, #21 + 800ae30: 18bc adds r4, r7, r2 + 800ae32: 687d ldr r5, [r7, #4] + 800ae34: 69f9 ldr r1, [r7, #28] + 800ae36: 69b8 ldr r0, [r7, #24] + 800ae38: 6bba ldr r2, [r7, #56] ; 0x38 + 800ae3a: 9202 str r2, [sp, #8] + 800ae3c: 2211 movs r2, #17 + 800ae3e: 9201 str r2, [sp, #4] + 800ae40: 9300 str r3, [sp, #0] + 800ae42: 0033 movs r3, r6 + 800ae44: 002a movs r2, r5 + 800ae46: f000 ff0d bl 800bc64 + 800ae4a: 0003 movs r3, r0 + 800ae4c: 7023 strb r3, [r4, #0] + } + /* TODO: must this be increased even if error occured? */ + snmp_inc_udpoutdatagrams(); + + /* did we chain a separate header pbuf earlier? */ + if (q != p) { + 800ae4e: 69ba ldr r2, [r7, #24] + 800ae50: 68bb ldr r3, [r7, #8] + 800ae52: 429a cmp r2, r3 + 800ae54: d005 beq.n 800ae62 + /* free the header pbuf */ + pbuf_free(q); + 800ae56: 69bb ldr r3, [r7, #24] + 800ae58: 0018 movs r0, r3 + 800ae5a: f7fa fc23 bl 80056a4 + q = NULL; + 800ae5e: 2300 movs r3, #0 + 800ae60: 61bb str r3, [r7, #24] + /* p is still referenced by the caller, and will live on */ + } + + UDP_STATS_INC(udp.xmit); + 800ae62: 4b08 ldr r3, [pc, #32] ; (800ae84 ) + 800ae64: 2278 movs r2, #120 ; 0x78 + 800ae66: 5a9b ldrh r3, [r3, r2] + 800ae68: 3301 adds r3, #1 + 800ae6a: b299 uxth r1, r3 + 800ae6c: 4b05 ldr r3, [pc, #20] ; (800ae84 ) + 800ae6e: 2278 movs r2, #120 ; 0x78 + 800ae70: 5299 strh r1, [r3, r2] + return err; + 800ae72: 2315 movs r3, #21 + 800ae74: 18fb adds r3, r7, r3 + 800ae76: 781b ldrb r3, [r3, #0] + 800ae78: b25b sxtb r3, r3 +} + 800ae7a: 0018 movs r0, r3 + 800ae7c: 46bd mov sp, r7 + 800ae7e: b009 add sp, #36 ; 0x24 + 800ae80: bdf0 pop {r4, r5, r6, r7, pc} + 800ae82: 46c0 nop ; (mov r8, r8) + 800ae84: 20003158 .word 0x20003158 + +0800ae88 : + * + * @see udp_disconnect() + */ +err_t +udp_bind(struct udp_pcb *pcb, ip_addr_t *ipaddr, u16_t port) +{ + 800ae88: b590 push {r4, r7, lr} + 800ae8a: b087 sub sp, #28 + 800ae8c: af00 add r7, sp, #0 + 800ae8e: 60f8 str r0, [r7, #12] + 800ae90: 60b9 str r1, [r7, #8] + 800ae92: 1dbb adds r3, r7, #6 + 800ae94: 801a strh r2, [r3, #0] + + LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, ("udp_bind(ipaddr = ")); + ip_addr_debug_print(UDP_DEBUG, ipaddr); + LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, (", port = %"U16_F")\n", port)); + + rebind = 0; + 800ae96: 2313 movs r3, #19 + 800ae98: 18fb adds r3, r7, r3 + 800ae9a: 2200 movs r2, #0 + 800ae9c: 701a strb r2, [r3, #0] + /* Check for double bind and rebind of the same pcb */ + for (ipcb = udp_pcbs; ipcb != NULL; ipcb = ipcb->next) { + 800ae9e: 4b2f ldr r3, [pc, #188] ; (800af5c ) + 800aea0: 681b ldr r3, [r3, #0] + 800aea2: 617b str r3, [r7, #20] + 800aea4: e028 b.n 800aef8 + /* is this UDP PCB already on active list? */ + if (pcb == ipcb) { + 800aea6: 68fa ldr r2, [r7, #12] + 800aea8: 697b ldr r3, [r7, #20] + 800aeaa: 429a cmp r2, r3 + 800aeac: d104 bne.n 800aeb8 + /* pcb may occur at most once in active list */ + LWIP_ASSERT("rebind == 0", rebind == 0); + /* pcb already in list, just rebind */ + rebind = 1; + 800aeae: 2313 movs r3, #19 + 800aeb0: 18fb adds r3, r7, r3 + 800aeb2: 2201 movs r2, #1 + 800aeb4: 701a strb r2, [r3, #0] + 800aeb6: e01c b.n 800aef2 + !ip_get_option(ipcb, SOF_REUSEADDR)) { +#else /* SO_REUSE */ + /* port matches that of PCB in list and REUSEADDR not set -> reject */ + else { +#endif /* SO_REUSE */ + if ((ipcb->local_port == port) && + 800aeb8: 697b ldr r3, [r7, #20] + 800aeba: 8a5b ldrh r3, [r3, #18] + 800aebc: 1dba adds r2, r7, #6 + 800aebe: 8812 ldrh r2, [r2, #0] + 800aec0: 429a cmp r2, r3 + 800aec2: d116 bne.n 800aef2 + /* IP address matches, or one is IP_ADDR_ANY? */ + (ip_addr_isany(&(ipcb->local_ip)) || + 800aec4: 697b ldr r3, [r7, #20] + if ((ipcb->local_port == port) && + 800aec6: 2b00 cmp r3, #0 + 800aec8: d010 beq.n 800aeec + (ip_addr_isany(&(ipcb->local_ip)) || + 800aeca: 697b ldr r3, [r7, #20] + 800aecc: 681b ldr r3, [r3, #0] + 800aece: 2b00 cmp r3, #0 + 800aed0: d00c beq.n 800aeec + 800aed2: 68bb ldr r3, [r7, #8] + 800aed4: 2b00 cmp r3, #0 + 800aed6: d009 beq.n 800aeec + ip_addr_isany(ipaddr) || + 800aed8: 68bb ldr r3, [r7, #8] + 800aeda: 681b ldr r3, [r3, #0] + 800aedc: 2b00 cmp r3, #0 + 800aede: d005 beq.n 800aeec + ip_addr_cmp(&(ipcb->local_ip), ipaddr))) { + 800aee0: 697b ldr r3, [r7, #20] + 800aee2: 681a ldr r2, [r3, #0] + 800aee4: 68bb ldr r3, [r7, #8] + 800aee6: 681b ldr r3, [r3, #0] + ip_addr_isany(ipaddr) || + 800aee8: 429a cmp r2, r3 + 800aeea: d102 bne.n 800aef2 + /* other PCB already binds to this local IP and port */ + LWIP_DEBUGF(UDP_DEBUG, + ("udp_bind: local port %"U16_F" already bound by another pcb\n", port)); + return ERR_USE; + 800aeec: 2308 movs r3, #8 + 800aeee: 425b negs r3, r3 + 800aef0: e02f b.n 800af52 + for (ipcb = udp_pcbs; ipcb != NULL; ipcb = ipcb->next) { + 800aef2: 697b ldr r3, [r7, #20] + 800aef4: 68db ldr r3, [r3, #12] + 800aef6: 617b str r3, [r7, #20] + 800aef8: 697b ldr r3, [r7, #20] + 800aefa: 2b00 cmp r3, #0 + 800aefc: d1d3 bne.n 800aea6 + } + } + } + + ip_addr_set(&pcb->local_ip, ipaddr); + 800aefe: 68bb ldr r3, [r7, #8] + 800af00: 2b00 cmp r3, #0 + 800af02: d002 beq.n 800af0a + 800af04: 68bb ldr r3, [r7, #8] + 800af06: 681a ldr r2, [r3, #0] + 800af08: e000 b.n 800af0c + 800af0a: 2200 movs r2, #0 + 800af0c: 68fb ldr r3, [r7, #12] + 800af0e: 601a str r2, [r3, #0] + + /* no port specified? */ + if (port == 0) { + 800af10: 1dbb adds r3, r7, #6 + 800af12: 881b ldrh r3, [r3, #0] + 800af14: 2b00 cmp r3, #0 + 800af16: d10b bne.n 800af30 + port = udp_new_port(); + 800af18: 1dbc adds r4, r7, #6 + 800af1a: f7ff fc8b bl 800a834 + 800af1e: 0003 movs r3, r0 + 800af20: 8023 strh r3, [r4, #0] + if (port == 0) { + 800af22: 1dbb adds r3, r7, #6 + 800af24: 881b ldrh r3, [r3, #0] + 800af26: 2b00 cmp r3, #0 + 800af28: d102 bne.n 800af30 + /* no more ports available in local range */ + LWIP_DEBUGF(UDP_DEBUG, ("udp_bind: out of free UDP ports\n")); + return ERR_USE; + 800af2a: 2308 movs r3, #8 + 800af2c: 425b negs r3, r3 + 800af2e: e010 b.n 800af52 + } + } + pcb->local_port = port; + 800af30: 68fb ldr r3, [r7, #12] + 800af32: 1dba adds r2, r7, #6 + 800af34: 8812 ldrh r2, [r2, #0] + 800af36: 825a strh r2, [r3, #18] + snmp_insert_udpidx_tree(pcb); + /* pcb not active yet? */ + if (rebind == 0) { + 800af38: 2313 movs r3, #19 + 800af3a: 18fb adds r3, r7, r3 + 800af3c: 781b ldrb r3, [r3, #0] + 800af3e: 2b00 cmp r3, #0 + 800af40: d106 bne.n 800af50 + /* place the PCB on the active list if not already there */ + pcb->next = udp_pcbs; + 800af42: 4b06 ldr r3, [pc, #24] ; (800af5c ) + 800af44: 681a ldr r2, [r3, #0] + 800af46: 68fb ldr r3, [r7, #12] + 800af48: 60da str r2, [r3, #12] + udp_pcbs = pcb; + 800af4a: 4b04 ldr r3, [pc, #16] ; (800af5c ) + 800af4c: 68fa ldr r2, [r7, #12] + 800af4e: 601a str r2, [r3, #0] + LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, + ("udp_bind: bound to %"U16_F".%"U16_F".%"U16_F".%"U16_F", port %"U16_F"\n", + ip4_addr1_16(&pcb->local_ip), ip4_addr2_16(&pcb->local_ip), + ip4_addr3_16(&pcb->local_ip), ip4_addr4_16(&pcb->local_ip), + pcb->local_port)); + return ERR_OK; + 800af50: 2300 movs r3, #0 +} + 800af52: 0018 movs r0, r3 + 800af54: 46bd mov sp, r7 + 800af56: b007 add sp, #28 + 800af58: bd90 pop {r4, r7, pc} + 800af5a: 46c0 nop ; (mov r8, r8) + 800af5c: 20003290 .word 0x20003290 + +0800af60 : + * @param recv function pointer of the callback function + * @param recv_arg additional argument to pass to the callback function + */ +void +udp_recv(struct udp_pcb *pcb, udp_recv_fn recv, void *recv_arg) +{ + 800af60: b580 push {r7, lr} + 800af62: b084 sub sp, #16 + 800af64: af00 add r7, sp, #0 + 800af66: 60f8 str r0, [r7, #12] + 800af68: 60b9 str r1, [r7, #8] + 800af6a: 607a str r2, [r7, #4] + /* remember recv() callback and user data */ + pcb->recv = recv; + 800af6c: 68fb ldr r3, [r7, #12] + 800af6e: 68ba ldr r2, [r7, #8] + 800af70: 619a str r2, [r3, #24] + pcb->recv_arg = recv_arg; + 800af72: 68fb ldr r3, [r7, #12] + 800af74: 687a ldr r2, [r7, #4] + 800af76: 61da str r2, [r3, #28] +} + 800af78: 46c0 nop ; (mov r8, r8) + 800af7a: 46bd mov sp, r7 + 800af7c: b004 add sp, #16 + 800af7e: bd80 pop {r7, pc} + +0800af80 : + * + * @see udp_new() + */ +void +udp_remove(struct udp_pcb *pcb) +{ + 800af80: b580 push {r7, lr} + 800af82: b084 sub sp, #16 + 800af84: af00 add r7, sp, #0 + 800af86: 6078 str r0, [r7, #4] + struct udp_pcb *pcb2; + + snmp_delete_udpidx_tree(pcb); + /* pcb to be removed is first in list? */ + if (udp_pcbs == pcb) { + 800af88: 4b15 ldr r3, [pc, #84] ; (800afe0 ) + 800af8a: 681b ldr r3, [r3, #0] + 800af8c: 687a ldr r2, [r7, #4] + 800af8e: 429a cmp r2, r3 + 800af90: d105 bne.n 800af9e + /* make list start at 2nd pcb */ + udp_pcbs = udp_pcbs->next; + 800af92: 4b13 ldr r3, [pc, #76] ; (800afe0 ) + 800af94: 681b ldr r3, [r3, #0] + 800af96: 68da ldr r2, [r3, #12] + 800af98: 4b11 ldr r3, [pc, #68] ; (800afe0 ) + 800af9a: 601a str r2, [r3, #0] + 800af9c: e016 b.n 800afcc + /* pcb not 1st in list */ + } else { + for (pcb2 = udp_pcbs; pcb2 != NULL; pcb2 = pcb2->next) { + 800af9e: 4b10 ldr r3, [pc, #64] ; (800afe0 ) + 800afa0: 681b ldr r3, [r3, #0] + 800afa2: 60fb str r3, [r7, #12] + 800afa4: e00f b.n 800afc6 + /* find pcb in udp_pcbs list */ + if (pcb2->next != NULL && pcb2->next == pcb) { + 800afa6: 68fb ldr r3, [r7, #12] + 800afa8: 68db ldr r3, [r3, #12] + 800afaa: 2b00 cmp r3, #0 + 800afac: d008 beq.n 800afc0 + 800afae: 68fb ldr r3, [r7, #12] + 800afb0: 68db ldr r3, [r3, #12] + 800afb2: 687a ldr r2, [r7, #4] + 800afb4: 429a cmp r2, r3 + 800afb6: d103 bne.n 800afc0 + /* remove pcb from list */ + pcb2->next = pcb->next; + 800afb8: 687b ldr r3, [r7, #4] + 800afba: 68da ldr r2, [r3, #12] + 800afbc: 68fb ldr r3, [r7, #12] + 800afbe: 60da str r2, [r3, #12] + for (pcb2 = udp_pcbs; pcb2 != NULL; pcb2 = pcb2->next) { + 800afc0: 68fb ldr r3, [r7, #12] + 800afc2: 68db ldr r3, [r3, #12] + 800afc4: 60fb str r3, [r7, #12] + 800afc6: 68fb ldr r3, [r7, #12] + 800afc8: 2b00 cmp r3, #0 + 800afca: d1ec bne.n 800afa6 + } + } + } + memp_free(MEMP_UDP_PCB, pcb); + 800afcc: 687b ldr r3, [r7, #4] + 800afce: 0019 movs r1, r3 + 800afd0: 2001 movs r0, #1 + 800afd2: f7f9 ffa5 bl 8004f20 +} + 800afd6: 46c0 nop ; (mov r8, r8) + 800afd8: 46bd mov sp, r7 + 800afda: b004 add sp, #16 + 800afdc: bd80 pop {r7, pc} + 800afde: 46c0 nop ; (mov r8, r8) + 800afe0: 20003290 .word 0x20003290 + +0800afe4 : + * + * @see udp_remove() + */ +struct udp_pcb * +udp_new(void) +{ + 800afe4: b580 push {r7, lr} + 800afe6: b082 sub sp, #8 + 800afe8: af00 add r7, sp, #0 + struct udp_pcb *pcb; + pcb = (struct udp_pcb *)memp_malloc(MEMP_UDP_PCB); + 800afea: 2001 movs r0, #1 + 800afec: f7f9 ff12 bl 8004e14 + 800aff0: 0003 movs r3, r0 + 800aff2: 607b str r3, [r7, #4] + /* could allocate UDP PCB? */ + if (pcb != NULL) { + 800aff4: 687b ldr r3, [r7, #4] + 800aff6: 2b00 cmp r3, #0 + 800aff8: d008 beq.n 800b00c + /* UDP Lite: by initializing to all zeroes, chksum_len is set to 0 + * which means checksum is generated over the whole datagram per default + * (recommended as default by RFC 3828). */ + /* initialize PCB to all zeroes */ + memset(pcb, 0, sizeof(struct udp_pcb)); + 800affa: 687b ldr r3, [r7, #4] + 800affc: 2220 movs r2, #32 + 800affe: 2100 movs r1, #0 + 800b000: 0018 movs r0, r3 + 800b002: f004 fe57 bl 800fcb4 + pcb->ttl = UDP_TTL; + 800b006: 687b ldr r3, [r7, #4] + 800b008: 22ff movs r2, #255 ; 0xff + 800b00a: 729a strb r2, [r3, #10] + } + return pcb; + 800b00c: 687b ldr r3, [r7, #4] +} + 800b00e: 0018 movs r0, r3 + 800b010: 46bd mov sp, r7 + 800b012: b002 add sp, #8 + 800b014: bd80 pop {r7, pc} + ... + +0800b018 : + * @param p the icmp echo request packet, p->payload pointing to the ip header + * @param inp the netif on which this packet was received + */ +void +icmp_input(struct pbuf *p, struct netif *inp) +{ + 800b018: b590 push {r4, r7, lr} + 800b01a: b08d sub sp, #52 ; 0x34 + 800b01c: af04 add r7, sp, #16 + 800b01e: 6078 str r0, [r7, #4] + 800b020: 6039 str r1, [r7, #0] +#endif /* LWIP_DEBUG */ + struct icmp_echo_hdr *iecho; + struct ip_hdr *iphdr; + s16_t hlen; + + ICMP_STATS_INC(icmp.recv); + 800b022: 4be1 ldr r3, [pc, #900] ; (800b3a8 ) + 800b024: 2262 movs r2, #98 ; 0x62 + 800b026: 5a9b ldrh r3, [r3, r2] + 800b028: 3301 adds r3, #1 + 800b02a: b299 uxth r1, r3 + 800b02c: 4bde ldr r3, [pc, #888] ; (800b3a8 ) + 800b02e: 2262 movs r2, #98 ; 0x62 + 800b030: 5299 strh r1, [r3, r2] + snmp_inc_icmpinmsgs(); + + + iphdr = (struct ip_hdr *)p->payload; + 800b032: 687b ldr r3, [r7, #4] + 800b034: 685b ldr r3, [r3, #4] + 800b036: 61fb str r3, [r7, #28] + hlen = IPH_HL(iphdr) * 4; + 800b038: 69fb ldr r3, [r7, #28] + 800b03a: 781b ldrb r3, [r3, #0] + 800b03c: b29b uxth r3, r3 + 800b03e: 220f movs r2, #15 + 800b040: 4013 ands r3, r2 + 800b042: b29b uxth r3, r3 + 800b044: 009b lsls r3, r3, #2 + 800b046: b29a uxth r2, r3 + 800b048: 2116 movs r1, #22 + 800b04a: 187b adds r3, r7, r1 + 800b04c: 801a strh r2, [r3, #0] + if (pbuf_header(p, -hlen) || (p->tot_len < sizeof(u16_t)*2)) { + 800b04e: 187b adds r3, r7, r1 + 800b050: 881b ldrh r3, [r3, #0] + 800b052: 425b negs r3, r3 + 800b054: b29b uxth r3, r3 + 800b056: b21a sxth r2, r3 + 800b058: 687b ldr r3, [r7, #4] + 800b05a: 0011 movs r1, r2 + 800b05c: 0018 movs r0, r3 + 800b05e: f7fa fa9a bl 8005596 + 800b062: 1e03 subs r3, r0, #0 + 800b064: d000 beq.n 800b068 + 800b066: e19c b.n 800b3a2 + 800b068: 687b ldr r3, [r7, #4] + 800b06a: 891b ldrh r3, [r3, #8] + 800b06c: 2b03 cmp r3, #3 + 800b06e: d800 bhi.n 800b072 + 800b070: e197 b.n 800b3a2 + LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: short ICMP (%"U16_F" bytes) received\n", p->tot_len)); + goto lenerr; + } + + type = *((u8_t *)p->payload); + 800b072: 687b ldr r3, [r7, #4] + 800b074: 685a ldr r2, [r3, #4] + 800b076: 2115 movs r1, #21 + 800b078: 187b adds r3, r7, r1 + 800b07a: 7812 ldrb r2, [r2, #0] + 800b07c: 701a strb r2, [r3, #0] +#ifdef LWIP_DEBUG + code = *(((u8_t *)p->payload)+1); +#endif /* LWIP_DEBUG */ + switch (type) { + 800b07e: 187b adds r3, r7, r1 + 800b080: 781b ldrb r3, [r3, #0] + 800b082: 2b00 cmp r3, #0 + 800b084: d100 bne.n 800b088 + 800b086: e184 b.n 800b392 + 800b088: 2b08 cmp r3, #8 + 800b08a: d000 beq.n 800b08e + 800b08c: e170 b.n 800b370 + (as obviously, an echo request has been sent, too). */ + break; + case ICMP_ECHO: +#if !LWIP_MULTICAST_PING || !LWIP_BROADCAST_PING + { + int accepted = 1; + 800b08e: 2301 movs r3, #1 + 800b090: 61bb str r3, [r7, #24] +#if !LWIP_MULTICAST_PING + /* multicast destination address? */ + if (ip_addr_ismulticast(¤t_iphdr_dest)) { + 800b092: 4bc6 ldr r3, [pc, #792] ; (800b3ac ) + 800b094: 681b ldr r3, [r3, #0] + 800b096: 22f0 movs r2, #240 ; 0xf0 + 800b098: 4013 ands r3, r2 + 800b09a: 2be0 cmp r3, #224 ; 0xe0 + 800b09c: d101 bne.n 800b0a2 + accepted = 0; + 800b09e: 2300 movs r3, #0 + 800b0a0: 61bb str r3, [r7, #24] + } +#endif /* LWIP_MULTICAST_PING */ +#if !LWIP_BROADCAST_PING + /* broadcast destination address? */ + if (ip_addr_isbroadcast(¤t_iphdr_dest, inp)) { + 800b0a2: 4bc2 ldr r3, [pc, #776] ; (800b3ac ) + 800b0a4: 681b ldr r3, [r3, #0] + 800b0a6: 683a ldr r2, [r7, #0] + 800b0a8: 0011 movs r1, r2 + 800b0aa: 0018 movs r0, r3 + 800b0ac: f000 ffe6 bl 800c07c + 800b0b0: 1e03 subs r3, r0, #0 + 800b0b2: d001 beq.n 800b0b8 + accepted = 0; + 800b0b4: 2300 movs r3, #0 + 800b0b6: 61bb str r3, [r7, #24] + } +#endif /* LWIP_BROADCAST_PING */ + /* broadcast or multicast destination address not acceptd? */ + if (!accepted) { + 800b0b8: 69bb ldr r3, [r7, #24] + 800b0ba: 2b00 cmp r3, #0 + 800b0bc: d10c bne.n 800b0d8 + LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: Not echoing to multicast or broadcast pings\n")); + ICMP_STATS_INC(icmp.err); + 800b0be: 4bba ldr r3, [pc, #744] ; (800b3a8 ) + 800b0c0: 2274 movs r2, #116 ; 0x74 + 800b0c2: 5a9b ldrh r3, [r3, r2] + 800b0c4: 3301 adds r3, #1 + 800b0c6: b299 uxth r1, r3 + 800b0c8: 4bb7 ldr r3, [pc, #732] ; (800b3a8 ) + 800b0ca: 2274 movs r2, #116 ; 0x74 + 800b0cc: 5299 strh r1, [r3, r2] + pbuf_free(p); + 800b0ce: 687b ldr r3, [r7, #4] + 800b0d0: 0018 movs r0, r3 + 800b0d2: f7fa fae7 bl 80056a4 + return; + 800b0d6: e193 b.n 800b400 + } + } +#endif /* !LWIP_MULTICAST_PING || !LWIP_BROADCAST_PING */ + LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: ping\n")); + if (p->tot_len < sizeof(struct icmp_echo_hdr)) { + 800b0d8: 687b ldr r3, [r7, #4] + 800b0da: 891b ldrh r3, [r3, #8] + 800b0dc: 2b07 cmp r3, #7 + 800b0de: d800 bhi.n 800b0e2 + 800b0e0: e16a b.n 800b3b8 + LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: bad ICMP echo received\n")); + goto lenerr; + } + if (inet_chksum_pbuf(p) != 0) { + 800b0e2: 687b ldr r3, [r7, #4] + 800b0e4: 0018 movs r0, r3 + 800b0e6: f000 fb58 bl 800b79a + 800b0ea: 1e03 subs r3, r0, #0 + 800b0ec: d00c beq.n 800b108 + LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: checksum failed for received ICMP echo\n")); + pbuf_free(p); + 800b0ee: 687b ldr r3, [r7, #4] + 800b0f0: 0018 movs r0, r3 + 800b0f2: f7fa fad7 bl 80056a4 + ICMP_STATS_INC(icmp.chkerr); + 800b0f6: 4bac ldr r3, [pc, #688] ; (800b3a8 ) + 800b0f8: 2268 movs r2, #104 ; 0x68 + 800b0fa: 5a9b ldrh r3, [r3, r2] + 800b0fc: 3301 adds r3, #1 + 800b0fe: b299 uxth r1, r3 + 800b100: 4ba9 ldr r3, [pc, #676] ; (800b3a8 ) + 800b102: 2268 movs r2, #104 ; 0x68 + 800b104: 5299 strh r1, [r3, r2] + snmp_inc_icmpinerrors(); + return; + 800b106: e17b b.n 800b400 + } +#if LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN + if (pbuf_header(p, (PBUF_IP_HLEN + PBUF_LINK_HLEN))) { + 800b108: 687b ldr r3, [r7, #4] + 800b10a: 2122 movs r1, #34 ; 0x22 + 800b10c: 0018 movs r0, r3 + 800b10e: f7fa fa42 bl 8005596 + 800b112: 1e03 subs r3, r0, #0 + 800b114: d039 beq.n 800b18a + /* p is not big enough to contain link headers + * allocate a new one and copy p into it + */ + struct pbuf *r; + /* switch p->payload to ip header */ + if (pbuf_header(p, hlen)) { + 800b116: 2316 movs r3, #22 + 800b118: 18fb adds r3, r7, r3 + 800b11a: 2200 movs r2, #0 + 800b11c: 5e9a ldrsh r2, [r3, r2] + 800b11e: 687b ldr r3, [r7, #4] + 800b120: 0011 movs r1, r2 + 800b122: 0018 movs r0, r3 + 800b124: f7fa fa37 bl 8005596 + 800b128: 1e03 subs r3, r0, #0 + 800b12a: d000 beq.n 800b12e + 800b12c: e152 b.n 800b3d4 + LWIP_ASSERT("icmp_input: moving p->payload to ip header failed\n", 0); + goto memerr; + } + /* allocate new packet buffer with space for link headers */ + r = pbuf_alloc(PBUF_LINK, p->tot_len, PBUF_RAM); + 800b12e: 687b ldr r3, [r7, #4] + 800b130: 891b ldrh r3, [r3, #8] + 800b132: 2200 movs r2, #0 + 800b134: 0019 movs r1, r3 + 800b136: 2002 movs r0, #2 + 800b138: f7fa f828 bl 800518c + 800b13c: 0003 movs r3, r0 + 800b13e: 613b str r3, [r7, #16] + if (r == NULL) { + 800b140: 693b ldr r3, [r7, #16] + 800b142: 2b00 cmp r3, #0 + 800b144: d100 bne.n 800b148 + 800b146: e147 b.n 800b3d8 + goto memerr; + } + LWIP_ASSERT("check that first pbuf can hold struct the ICMP header", + (r->len >= hlen + sizeof(struct icmp_echo_hdr))); + /* copy the whole packet including ip header */ + if (pbuf_copy(r, p) != ERR_OK) { + 800b148: 687a ldr r2, [r7, #4] + 800b14a: 693b ldr r3, [r7, #16] + 800b14c: 0011 movs r1, r2 + 800b14e: 0018 movs r0, r3 + 800b150: f7fa fb87 bl 8005862 + 800b154: 1e03 subs r3, r0, #0 + 800b156: d000 beq.n 800b15a + 800b158: e140 b.n 800b3dc + LWIP_ASSERT("icmp_input: copying to new pbuf failed\n", 0); + goto memerr; + } + iphdr = (struct ip_hdr *)r->payload; + 800b15a: 693b ldr r3, [r7, #16] + 800b15c: 685b ldr r3, [r3, #4] + 800b15e: 61fb str r3, [r7, #28] + /* switch r->payload back to icmp header */ + if (pbuf_header(r, -hlen)) { + 800b160: 2316 movs r3, #22 + 800b162: 18fb adds r3, r7, r3 + 800b164: 881b ldrh r3, [r3, #0] + 800b166: 425b negs r3, r3 + 800b168: b29b uxth r3, r3 + 800b16a: b21a sxth r2, r3 + 800b16c: 693b ldr r3, [r7, #16] + 800b16e: 0011 movs r1, r2 + 800b170: 0018 movs r0, r3 + 800b172: f7fa fa10 bl 8005596 + 800b176: 1e03 subs r3, r0, #0 + 800b178: d000 beq.n 800b17c + 800b17a: e131 b.n 800b3e0 + LWIP_ASSERT("icmp_input: restoring original p->payload failed\n", 0); + goto memerr; + } + /* free the original p */ + pbuf_free(p); + 800b17c: 687b ldr r3, [r7, #4] + 800b17e: 0018 movs r0, r3 + 800b180: f7fa fa90 bl 80056a4 + /* we now have an identical copy of p that has room for link headers */ + p = r; + 800b184: 693b ldr r3, [r7, #16] + 800b186: 607b str r3, [r7, #4] + 800b188: e009 b.n 800b19e + } else { + /* restore p->payload to point to icmp header */ + if (pbuf_header(p, -(s16_t)(PBUF_IP_HLEN + PBUF_LINK_HLEN))) { + 800b18a: 2322 movs r3, #34 ; 0x22 + 800b18c: 425a negs r2, r3 + 800b18e: 687b ldr r3, [r7, #4] + 800b190: 0011 movs r1, r2 + 800b192: 0018 movs r0, r3 + 800b194: f7fa f9ff bl 8005596 + 800b198: 1e03 subs r3, r0, #0 + 800b19a: d000 beq.n 800b19e + 800b19c: e122 b.n 800b3e4 + } +#endif /* LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN */ + /* At this point, all checks are OK. */ + /* We generate an answer by switching the dest and src ip addresses, + * setting the icmp type to ECHO_RESPONSE and updating the checksum. */ + iecho = (struct icmp_echo_hdr *)p->payload; + 800b19e: 687b ldr r3, [r7, #4] + 800b1a0: 685b ldr r3, [r3, #4] + 800b1a2: 60fb str r3, [r7, #12] + ip_addr_copy(iphdr->src, *ip_current_dest_addr()); + 800b1a4: 4b81 ldr r3, [pc, #516] ; (800b3ac ) + 800b1a6: 681a ldr r2, [r3, #0] + 800b1a8: 69fb ldr r3, [r7, #28] + 800b1aa: 21ff movs r1, #255 ; 0xff + 800b1ac: 4011 ands r1, r2 + 800b1ae: 000c movs r4, r1 + 800b1b0: 7b19 ldrb r1, [r3, #12] + 800b1b2: 2000 movs r0, #0 + 800b1b4: 4001 ands r1, r0 + 800b1b6: 1c08 adds r0, r1, #0 + 800b1b8: 1c21 adds r1, r4, #0 + 800b1ba: 4301 orrs r1, r0 + 800b1bc: 7319 strb r1, [r3, #12] + 800b1be: 0a11 lsrs r1, r2, #8 + 800b1c0: 20ff movs r0, #255 ; 0xff + 800b1c2: 4001 ands r1, r0 + 800b1c4: 000c movs r4, r1 + 800b1c6: 7b59 ldrb r1, [r3, #13] + 800b1c8: 2000 movs r0, #0 + 800b1ca: 4001 ands r1, r0 + 800b1cc: 1c08 adds r0, r1, #0 + 800b1ce: 1c21 adds r1, r4, #0 + 800b1d0: 4301 orrs r1, r0 + 800b1d2: 7359 strb r1, [r3, #13] + 800b1d4: 0c11 lsrs r1, r2, #16 + 800b1d6: 20ff movs r0, #255 ; 0xff + 800b1d8: 4001 ands r1, r0 + 800b1da: 000c movs r4, r1 + 800b1dc: 7b99 ldrb r1, [r3, #14] + 800b1de: 2000 movs r0, #0 + 800b1e0: 4001 ands r1, r0 + 800b1e2: 1c08 adds r0, r1, #0 + 800b1e4: 1c21 adds r1, r4, #0 + 800b1e6: 4301 orrs r1, r0 + 800b1e8: 7399 strb r1, [r3, #14] + 800b1ea: 0e10 lsrs r0, r2, #24 + 800b1ec: 7bda ldrb r2, [r3, #15] + 800b1ee: 2100 movs r1, #0 + 800b1f0: 400a ands r2, r1 + 800b1f2: 1c11 adds r1, r2, #0 + 800b1f4: 1c02 adds r2, r0, #0 + 800b1f6: 430a orrs r2, r1 + 800b1f8: 73da strb r2, [r3, #15] + ip_addr_copy(iphdr->dest, *ip_current_src_addr()); + 800b1fa: 4b6d ldr r3, [pc, #436] ; (800b3b0 ) + 800b1fc: 681a ldr r2, [r3, #0] + 800b1fe: 69fb ldr r3, [r7, #28] + 800b200: 21ff movs r1, #255 ; 0xff + 800b202: 4011 ands r1, r2 + 800b204: 000c movs r4, r1 + 800b206: 7c19 ldrb r1, [r3, #16] + 800b208: 2000 movs r0, #0 + 800b20a: 4001 ands r1, r0 + 800b20c: 1c08 adds r0, r1, #0 + 800b20e: 1c21 adds r1, r4, #0 + 800b210: 4301 orrs r1, r0 + 800b212: 7419 strb r1, [r3, #16] + 800b214: 0a11 lsrs r1, r2, #8 + 800b216: 20ff movs r0, #255 ; 0xff + 800b218: 4001 ands r1, r0 + 800b21a: 000c movs r4, r1 + 800b21c: 7c59 ldrb r1, [r3, #17] + 800b21e: 2000 movs r0, #0 + 800b220: 4001 ands r1, r0 + 800b222: 1c08 adds r0, r1, #0 + 800b224: 1c21 adds r1, r4, #0 + 800b226: 4301 orrs r1, r0 + 800b228: 7459 strb r1, [r3, #17] + 800b22a: 0c11 lsrs r1, r2, #16 + 800b22c: 20ff movs r0, #255 ; 0xff + 800b22e: 4001 ands r1, r0 + 800b230: 000c movs r4, r1 + 800b232: 7c99 ldrb r1, [r3, #18] + 800b234: 2000 movs r0, #0 + 800b236: 4001 ands r1, r0 + 800b238: 1c08 adds r0, r1, #0 + 800b23a: 1c21 adds r1, r4, #0 + 800b23c: 4301 orrs r1, r0 + 800b23e: 7499 strb r1, [r3, #18] + 800b240: 0e10 lsrs r0, r2, #24 + 800b242: 7cda ldrb r2, [r3, #19] + 800b244: 2100 movs r1, #0 + 800b246: 400a ands r2, r1 + 800b248: 1c11 adds r1, r2, #0 + 800b24a: 1c02 adds r2, r0, #0 + 800b24c: 430a orrs r2, r1 + 800b24e: 74da strb r2, [r3, #19] + ICMPH_TYPE_SET(iecho, ICMP_ER); + 800b250: 68fb ldr r3, [r7, #12] + 800b252: 2200 movs r2, #0 + 800b254: 701a strb r2, [r3, #0] +#if CHECKSUM_GEN_ICMP + /* adjust the checksum */ + if (iecho->chksum >= PP_HTONS(0xffffU - (ICMP_ECHO << 8))) { + 800b256: 68fb ldr r3, [r7, #12] + 800b258: 789a ldrb r2, [r3, #2] + 800b25a: 78db ldrb r3, [r3, #3] + 800b25c: 021b lsls r3, r3, #8 + 800b25e: 4313 orrs r3, r2 + 800b260: b29b uxth r3, r3 + 800b262: 4a54 ldr r2, [pc, #336] ; (800b3b4 ) + 800b264: 4293 cmp r3, r2 + 800b266: d91c bls.n 800b2a2 + iecho->chksum += PP_HTONS(ICMP_ECHO << 8) + 1; + 800b268: 68fb ldr r3, [r7, #12] + 800b26a: 789a ldrb r2, [r3, #2] + 800b26c: 78db ldrb r3, [r3, #3] + 800b26e: 021b lsls r3, r3, #8 + 800b270: 4313 orrs r3, r2 + 800b272: b29b uxth r3, r3 + 800b274: 3309 adds r3, #9 + 800b276: b29a uxth r2, r3 + 800b278: 68fb ldr r3, [r7, #12] + 800b27a: 21ff movs r1, #255 ; 0xff + 800b27c: 4011 ands r1, r2 + 800b27e: 000c movs r4, r1 + 800b280: 7899 ldrb r1, [r3, #2] + 800b282: 2000 movs r0, #0 + 800b284: 4001 ands r1, r0 + 800b286: 1c08 adds r0, r1, #0 + 800b288: 1c21 adds r1, r4, #0 + 800b28a: 4301 orrs r1, r0 + 800b28c: 7099 strb r1, [r3, #2] + 800b28e: 0a12 lsrs r2, r2, #8 + 800b290: b290 uxth r0, r2 + 800b292: 78da ldrb r2, [r3, #3] + 800b294: 2100 movs r1, #0 + 800b296: 400a ands r2, r1 + 800b298: 1c11 adds r1, r2, #0 + 800b29a: 1c02 adds r2, r0, #0 + 800b29c: 430a orrs r2, r1 + 800b29e: 70da strb r2, [r3, #3] + 800b2a0: e01b b.n 800b2da + } else { + iecho->chksum += PP_HTONS(ICMP_ECHO << 8); + 800b2a2: 68fb ldr r3, [r7, #12] + 800b2a4: 789a ldrb r2, [r3, #2] + 800b2a6: 78db ldrb r3, [r3, #3] + 800b2a8: 021b lsls r3, r3, #8 + 800b2aa: 4313 orrs r3, r2 + 800b2ac: b29b uxth r3, r3 + 800b2ae: 3308 adds r3, #8 + 800b2b0: b29a uxth r2, r3 + 800b2b2: 68fb ldr r3, [r7, #12] + 800b2b4: 21ff movs r1, #255 ; 0xff + 800b2b6: 4011 ands r1, r2 + 800b2b8: 000c movs r4, r1 + 800b2ba: 7899 ldrb r1, [r3, #2] + 800b2bc: 2000 movs r0, #0 + 800b2be: 4001 ands r1, r0 + 800b2c0: 1c08 adds r0, r1, #0 + 800b2c2: 1c21 adds r1, r4, #0 + 800b2c4: 4301 orrs r1, r0 + 800b2c6: 7099 strb r1, [r3, #2] + 800b2c8: 0a12 lsrs r2, r2, #8 + 800b2ca: b290 uxth r0, r2 + 800b2cc: 78da ldrb r2, [r3, #3] + 800b2ce: 2100 movs r1, #0 + 800b2d0: 400a ands r2, r1 + 800b2d2: 1c11 adds r1, r2, #0 + 800b2d4: 1c02 adds r2, r0, #0 + 800b2d6: 430a orrs r2, r1 + 800b2d8: 70da strb r2, [r3, #3] +#else /* CHECKSUM_GEN_ICMP */ + iecho->chksum = 0; +#endif /* CHECKSUM_GEN_ICMP */ + + /* Set the correct TTL and recalculate the header checksum. */ + IPH_TTL_SET(iphdr, ICMP_TTL); + 800b2da: 69fb ldr r3, [r7, #28] + 800b2dc: 22ff movs r2, #255 ; 0xff + 800b2de: 721a strb r2, [r3, #8] + IPH_CHKSUM_SET(iphdr, 0); + 800b2e0: 69fb ldr r3, [r7, #28] + 800b2e2: 7a9a ldrb r2, [r3, #10] + 800b2e4: 2100 movs r1, #0 + 800b2e6: 400a ands r2, r1 + 800b2e8: 729a strb r2, [r3, #10] + 800b2ea: 7ada ldrb r2, [r3, #11] + 800b2ec: 2100 movs r1, #0 + 800b2ee: 400a ands r2, r1 + 800b2f0: 72da strb r2, [r3, #11] +#if CHECKSUM_GEN_IP + IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, IP_HLEN)); + 800b2f2: 69fb ldr r3, [r7, #28] + 800b2f4: 2114 movs r1, #20 + 800b2f6: 0018 movs r0, r3 + 800b2f8: f000 fa3a bl 800b770 + 800b2fc: 0003 movs r3, r0 + 800b2fe: 001a movs r2, r3 + 800b300: 69fb ldr r3, [r7, #28] + 800b302: 21ff movs r1, #255 ; 0xff + 800b304: 4011 ands r1, r2 + 800b306: 000c movs r4, r1 + 800b308: 7a99 ldrb r1, [r3, #10] + 800b30a: 2000 movs r0, #0 + 800b30c: 4001 ands r1, r0 + 800b30e: 1c08 adds r0, r1, #0 + 800b310: 1c21 adds r1, r4, #0 + 800b312: 4301 orrs r1, r0 + 800b314: 7299 strb r1, [r3, #10] + 800b316: 0a12 lsrs r2, r2, #8 + 800b318: b290 uxth r0, r2 + 800b31a: 7ada ldrb r2, [r3, #11] + 800b31c: 2100 movs r1, #0 + 800b31e: 400a ands r2, r1 + 800b320: 1c11 adds r1, r2, #0 + 800b322: 1c02 adds r2, r0, #0 + 800b324: 430a orrs r2, r1 + 800b326: 72da strb r2, [r3, #11] +#endif /* CHECKSUM_GEN_IP */ + + ICMP_STATS_INC(icmp.xmit); + 800b328: 4b1f ldr r3, [pc, #124] ; (800b3a8 ) + 800b32a: 2260 movs r2, #96 ; 0x60 + 800b32c: 5a9b ldrh r3, [r3, r2] + 800b32e: 3301 adds r3, #1 + 800b330: b299 uxth r1, r3 + 800b332: 4b1d ldr r3, [pc, #116] ; (800b3a8 ) + 800b334: 2260 movs r2, #96 ; 0x60 + 800b336: 5299 strh r1, [r3, r2] + /* increase number of messages attempted to send */ + snmp_inc_icmpoutmsgs(); + /* increase number of echo replies attempted to send */ + snmp_inc_icmpoutechoreps(); + + if(pbuf_header(p, hlen)) { + 800b338: 2316 movs r3, #22 + 800b33a: 18fb adds r3, r7, r3 + 800b33c: 2200 movs r2, #0 + 800b33e: 5e9a ldrsh r2, [r3, r2] + 800b340: 687b ldr r3, [r7, #4] + 800b342: 0011 movs r1, r2 + 800b344: 0018 movs r0, r3 + 800b346: f7fa f926 bl 8005596 + 800b34a: 1e03 subs r3, r0, #0 + 800b34c: d123 bne.n 800b396 + LWIP_ASSERT("Can't move over header in packet", 0); + } else { + err_t ret; + /* send an ICMP packet, src addr is the dest addr of the curren packet */ + ret = ip_output_if(p, ip_current_dest_addr(), IP_HDRINCL, + 800b34e: 230b movs r3, #11 + 800b350: 18fc adds r4, r7, r3 + 800b352: 4916 ldr r1, [pc, #88] ; (800b3ac ) + 800b354: 6878 ldr r0, [r7, #4] + 800b356: 683b ldr r3, [r7, #0] + 800b358: 9302 str r3, [sp, #8] + 800b35a: 2301 movs r3, #1 + 800b35c: 9301 str r3, [sp, #4] + 800b35e: 2300 movs r3, #0 + 800b360: 9300 str r3, [sp, #0] + 800b362: 23ff movs r3, #255 ; 0xff + 800b364: 2200 movs r2, #0 + 800b366: f000 fc7d bl 800bc64 + 800b36a: 0003 movs r3, r0 + 800b36c: 7023 strb r3, [r4, #0] + ICMP_TTL, 0, IP_PROTO_ICMP, inp); + if (ret != ERR_OK) { + LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: ip_output_if returned an error: %c.\n", ret)); + } + } + break; + 800b36e: e012 b.n 800b396 + default: + LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: ICMP type %"S16_F" code %"S16_F" not supported.\n", + (s16_t)type, (s16_t)code)); + ICMP_STATS_INC(icmp.proterr); + 800b370: 4b0d ldr r3, [pc, #52] ; (800b3a8 ) + 800b372: 2270 movs r2, #112 ; 0x70 + 800b374: 5a9b ldrh r3, [r3, r2] + 800b376: 3301 adds r3, #1 + 800b378: b299 uxth r1, r3 + 800b37a: 4b0b ldr r3, [pc, #44] ; (800b3a8 ) + 800b37c: 2270 movs r2, #112 ; 0x70 + 800b37e: 5299 strh r1, [r3, r2] + ICMP_STATS_INC(icmp.drop); + 800b380: 4b09 ldr r3, [pc, #36] ; (800b3a8 ) + 800b382: 2266 movs r2, #102 ; 0x66 + 800b384: 5a9b ldrh r3, [r3, r2] + 800b386: 3301 adds r3, #1 + 800b388: b299 uxth r1, r3 + 800b38a: 4b07 ldr r3, [pc, #28] ; (800b3a8 ) + 800b38c: 2266 movs r2, #102 ; 0x66 + 800b38e: 5299 strh r1, [r3, r2] + 800b390: e002 b.n 800b398 + break; + 800b392: 46c0 nop ; (mov r8, r8) + 800b394: e000 b.n 800b398 + break; + 800b396: 46c0 nop ; (mov r8, r8) + } + pbuf_free(p); + 800b398: 687b ldr r3, [r7, #4] + 800b39a: 0018 movs r0, r3 + 800b39c: f7fa f982 bl 80056a4 + return; + 800b3a0: e02e b.n 800b400 +lenerr: + 800b3a2: 46c0 nop ; (mov r8, r8) + 800b3a4: e009 b.n 800b3ba + 800b3a6: 46c0 nop ; (mov r8, r8) + 800b3a8: 20003158 .word 0x20003158 + 800b3ac: 2000329c .word 0x2000329c + 800b3b0: 20003294 .word 0x20003294 + 800b3b4: 0000fff6 .word 0x0000fff6 + goto lenerr; + 800b3b8: 46c0 nop ; (mov r8, r8) + pbuf_free(p); + 800b3ba: 687b ldr r3, [r7, #4] + 800b3bc: 0018 movs r0, r3 + 800b3be: f7fa f971 bl 80056a4 + ICMP_STATS_INC(icmp.lenerr); + 800b3c2: 4b11 ldr r3, [pc, #68] ; (800b408 ) + 800b3c4: 226a movs r2, #106 ; 0x6a + 800b3c6: 5a9b ldrh r3, [r3, r2] + 800b3c8: 3301 adds r3, #1 + 800b3ca: b299 uxth r1, r3 + 800b3cc: 4b0e ldr r3, [pc, #56] ; (800b408 ) + 800b3ce: 226a movs r2, #106 ; 0x6a + 800b3d0: 5299 strh r1, [r3, r2] + snmp_inc_icmpinerrors(); + return; + 800b3d2: e015 b.n 800b400 + goto memerr; + 800b3d4: 46c0 nop ; (mov r8, r8) + 800b3d6: e006 b.n 800b3e6 + goto memerr; + 800b3d8: 46c0 nop ; (mov r8, r8) + 800b3da: e004 b.n 800b3e6 + goto memerr; + 800b3dc: 46c0 nop ; (mov r8, r8) + 800b3de: e002 b.n 800b3e6 + goto memerr; + 800b3e0: 46c0 nop ; (mov r8, r8) + 800b3e2: e000 b.n 800b3e6 + goto memerr; + 800b3e4: 46c0 nop ; (mov r8, r8) +#if LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN +memerr: + pbuf_free(p); + 800b3e6: 687b ldr r3, [r7, #4] + 800b3e8: 0018 movs r0, r3 + 800b3ea: f7fa f95b bl 80056a4 + ICMP_STATS_INC(icmp.err); + 800b3ee: 4b06 ldr r3, [pc, #24] ; (800b408 ) + 800b3f0: 2274 movs r2, #116 ; 0x74 + 800b3f2: 5a9b ldrh r3, [r3, r2] + 800b3f4: 3301 adds r3, #1 + 800b3f6: b299 uxth r1, r3 + 800b3f8: 4b03 ldr r3, [pc, #12] ; (800b408 ) + 800b3fa: 2274 movs r2, #116 ; 0x74 + 800b3fc: 5299 strh r1, [r3, r2] + snmp_inc_icmpinerrors(); + return; + 800b3fe: 46c0 nop ; (mov r8, r8) +#endif /* LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN */ +} + 800b400: 46bd mov sp, r7 + 800b402: b009 add sp, #36 ; 0x24 + 800b404: bd90 pop {r4, r7, pc} + 800b406: 46c0 nop ; (mov r8, r8) + 800b408: 20003158 .word 0x20003158 + +0800b40c : + * p->payload pointing to the IP header + * @param t type of the 'unreachable' packet + */ +void +icmp_dest_unreach(struct pbuf *p, enum icmp_dur_type t) +{ + 800b40c: b580 push {r7, lr} + 800b40e: b082 sub sp, #8 + 800b410: af00 add r7, sp, #0 + 800b412: 6078 str r0, [r7, #4] + 800b414: 000a movs r2, r1 + 800b416: 1cfb adds r3, r7, #3 + 800b418: 701a strb r2, [r3, #0] + icmp_send_response(p, ICMP_DUR, t); + 800b41a: 1cfb adds r3, r7, #3 + 800b41c: 781a ldrb r2, [r3, #0] + 800b41e: 687b ldr r3, [r7, #4] + 800b420: 2103 movs r1, #3 + 800b422: 0018 movs r0, r3 + 800b424: f000 f816 bl 800b454 +} + 800b428: 46c0 nop ; (mov r8, r8) + 800b42a: 46bd mov sp, r7 + 800b42c: b002 add sp, #8 + 800b42e: bd80 pop {r7, pc} + +0800b430 : + * p->payload pointing to the IP header + * @param t type of the 'time exceeded' packet + */ +void +icmp_time_exceeded(struct pbuf *p, enum icmp_te_type t) +{ + 800b430: b580 push {r7, lr} + 800b432: b082 sub sp, #8 + 800b434: af00 add r7, sp, #0 + 800b436: 6078 str r0, [r7, #4] + 800b438: 000a movs r2, r1 + 800b43a: 1cfb adds r3, r7, #3 + 800b43c: 701a strb r2, [r3, #0] + icmp_send_response(p, ICMP_TE, t); + 800b43e: 1cfb adds r3, r7, #3 + 800b440: 781a ldrb r2, [r3, #0] + 800b442: 687b ldr r3, [r7, #4] + 800b444: 210b movs r1, #11 + 800b446: 0018 movs r0, r3 + 800b448: f000 f804 bl 800b454 +} + 800b44c: 46c0 nop ; (mov r8, r8) + 800b44e: 46bd mov sp, r7 + 800b450: b002 add sp, #8 + 800b452: bd80 pop {r7, pc} + +0800b454 : + * @param type Type of the ICMP header + * @param code Code of the ICMP header + */ +static void +icmp_send_response(struct pbuf *p, u8_t type, u8_t code) +{ + 800b454: b590 push {r4, r7, lr} + 800b456: b089 sub sp, #36 ; 0x24 + 800b458: af02 add r7, sp, #8 + 800b45a: 6078 str r0, [r7, #4] + 800b45c: 0008 movs r0, r1 + 800b45e: 0011 movs r1, r2 + 800b460: 1cfb adds r3, r7, #3 + 800b462: 1c02 adds r2, r0, #0 + 800b464: 701a strb r2, [r3, #0] + 800b466: 1cbb adds r3, r7, #2 + 800b468: 1c0a adds r2, r1, #0 + 800b46a: 701a strb r2, [r3, #0] + /* we can use the echo header here */ + struct icmp_echo_hdr *icmphdr; + ip_addr_t iphdr_src; + + /* ICMP header + IP header + 8 bytes of data */ + q = pbuf_alloc(PBUF_IP, sizeof(struct icmp_echo_hdr) + IP_HLEN + ICMP_DEST_UNREACH_DATASIZE, + 800b46c: 2200 movs r2, #0 + 800b46e: 2124 movs r1, #36 ; 0x24 + 800b470: 2001 movs r0, #1 + 800b472: f7f9 fe8b bl 800518c + 800b476: 0003 movs r3, r0 + 800b478: 617b str r3, [r7, #20] + PBUF_RAM); + if (q == NULL) { + 800b47a: 697b ldr r3, [r7, #20] + 800b47c: 2b00 cmp r3, #0 + 800b47e: d073 beq.n 800b568 + return; + } + LWIP_ASSERT("check that first pbuf can hold icmp message", + (q->len >= (sizeof(struct icmp_echo_hdr) + IP_HLEN + ICMP_DEST_UNREACH_DATASIZE))); + + iphdr = (struct ip_hdr *)p->payload; + 800b480: 687b ldr r3, [r7, #4] + 800b482: 685b ldr r3, [r3, #4] + 800b484: 613b str r3, [r7, #16] + ip_addr_debug_print(ICMP_DEBUG, &(iphdr->src)); + LWIP_DEBUGF(ICMP_DEBUG, (" to ")); + ip_addr_debug_print(ICMP_DEBUG, &(iphdr->dest)); + LWIP_DEBUGF(ICMP_DEBUG, ("\n")); + + icmphdr = (struct icmp_echo_hdr *)q->payload; + 800b486: 697b ldr r3, [r7, #20] + 800b488: 685b ldr r3, [r3, #4] + 800b48a: 60fb str r3, [r7, #12] + icmphdr->type = type; + 800b48c: 68fb ldr r3, [r7, #12] + 800b48e: 1cfa adds r2, r7, #3 + 800b490: 7812 ldrb r2, [r2, #0] + 800b492: 701a strb r2, [r3, #0] + icmphdr->code = code; + 800b494: 68fb ldr r3, [r7, #12] + 800b496: 1cba adds r2, r7, #2 + 800b498: 7812 ldrb r2, [r2, #0] + 800b49a: 705a strb r2, [r3, #1] + icmphdr->id = 0; + 800b49c: 68fb ldr r3, [r7, #12] + 800b49e: 791a ldrb r2, [r3, #4] + 800b4a0: 2100 movs r1, #0 + 800b4a2: 400a ands r2, r1 + 800b4a4: 711a strb r2, [r3, #4] + 800b4a6: 795a ldrb r2, [r3, #5] + 800b4a8: 2100 movs r1, #0 + 800b4aa: 400a ands r2, r1 + 800b4ac: 715a strb r2, [r3, #5] + icmphdr->seqno = 0; + 800b4ae: 68fb ldr r3, [r7, #12] + 800b4b0: 799a ldrb r2, [r3, #6] + 800b4b2: 2100 movs r1, #0 + 800b4b4: 400a ands r2, r1 + 800b4b6: 719a strb r2, [r3, #6] + 800b4b8: 79da ldrb r2, [r3, #7] + 800b4ba: 2100 movs r1, #0 + 800b4bc: 400a ands r2, r1 + 800b4be: 71da strb r2, [r3, #7] + + /* copy fields from original packet */ + SMEMCPY((u8_t *)q->payload + sizeof(struct icmp_echo_hdr), (u8_t *)p->payload, + 800b4c0: 697b ldr r3, [r7, #20] + 800b4c2: 685b ldr r3, [r3, #4] + 800b4c4: 3308 adds r3, #8 + 800b4c6: 0018 movs r0, r3 + 800b4c8: 687b ldr r3, [r7, #4] + 800b4ca: 685b ldr r3, [r3, #4] + 800b4cc: 221c movs r2, #28 + 800b4ce: 0019 movs r1, r3 + 800b4d0: f004 fbe7 bl 800fca2 + IP_HLEN + ICMP_DEST_UNREACH_DATASIZE); + + /* calculate checksum */ + icmphdr->chksum = 0; + 800b4d4: 68fb ldr r3, [r7, #12] + 800b4d6: 789a ldrb r2, [r3, #2] + 800b4d8: 2100 movs r1, #0 + 800b4da: 400a ands r2, r1 + 800b4dc: 709a strb r2, [r3, #2] + 800b4de: 78da ldrb r2, [r3, #3] + 800b4e0: 2100 movs r1, #0 + 800b4e2: 400a ands r2, r1 + 800b4e4: 70da strb r2, [r3, #3] + icmphdr->chksum = inet_chksum(icmphdr, q->len); + 800b4e6: 697b ldr r3, [r7, #20] + 800b4e8: 895a ldrh r2, [r3, #10] + 800b4ea: 68fb ldr r3, [r7, #12] + 800b4ec: 0011 movs r1, r2 + 800b4ee: 0018 movs r0, r3 + 800b4f0: f000 f93e bl 800b770 + 800b4f4: 0003 movs r3, r0 + 800b4f6: 001a movs r2, r3 + 800b4f8: 68fb ldr r3, [r7, #12] + 800b4fa: 21ff movs r1, #255 ; 0xff + 800b4fc: 4011 ands r1, r2 + 800b4fe: 000c movs r4, r1 + 800b500: 7899 ldrb r1, [r3, #2] + 800b502: 2000 movs r0, #0 + 800b504: 4001 ands r1, r0 + 800b506: 1c08 adds r0, r1, #0 + 800b508: 1c21 adds r1, r4, #0 + 800b50a: 4301 orrs r1, r0 + 800b50c: 7099 strb r1, [r3, #2] + 800b50e: 0a12 lsrs r2, r2, #8 + 800b510: b290 uxth r0, r2 + 800b512: 78da ldrb r2, [r3, #3] + 800b514: 2100 movs r1, #0 + 800b516: 400a ands r2, r1 + 800b518: 1c11 adds r1, r2, #0 + 800b51a: 1c02 adds r2, r0, #0 + 800b51c: 430a orrs r2, r1 + 800b51e: 70da strb r2, [r3, #3] + ICMP_STATS_INC(icmp.xmit); + 800b520: 4b13 ldr r3, [pc, #76] ; (800b570 ) + 800b522: 2260 movs r2, #96 ; 0x60 + 800b524: 5a9b ldrh r3, [r3, r2] + 800b526: 3301 adds r3, #1 + 800b528: b299 uxth r1, r3 + 800b52a: 4b11 ldr r3, [pc, #68] ; (800b570 ) + 800b52c: 2260 movs r2, #96 ; 0x60 + 800b52e: 5299 strh r1, [r3, r2] + /* increase number of messages attempted to send */ + snmp_inc_icmpoutmsgs(); + /* increase number of destination unreachable messages attempted to send */ + snmp_inc_icmpouttimeexcds(); + ip_addr_copy(iphdr_src, iphdr->src); + 800b530: 693b ldr r3, [r7, #16] + 800b532: 7b1a ldrb r2, [r3, #12] + 800b534: 7b59 ldrb r1, [r3, #13] + 800b536: 0209 lsls r1, r1, #8 + 800b538: 430a orrs r2, r1 + 800b53a: 7b99 ldrb r1, [r3, #14] + 800b53c: 0409 lsls r1, r1, #16 + 800b53e: 430a orrs r2, r1 + 800b540: 7bdb ldrb r3, [r3, #15] + 800b542: 061b lsls r3, r3, #24 + 800b544: 4313 orrs r3, r2 + 800b546: 60bb str r3, [r7, #8] + ip_output(q, NULL, &iphdr_src, ICMP_TTL, 0, IP_PROTO_ICMP); + 800b548: 2308 movs r3, #8 + 800b54a: 18fa adds r2, r7, r3 + 800b54c: 6978 ldr r0, [r7, #20] + 800b54e: 2301 movs r3, #1 + 800b550: 9301 str r3, [sp, #4] + 800b552: 2300 movs r3, #0 + 800b554: 9300 str r3, [sp, #0] + 800b556: 23ff movs r3, #255 ; 0xff + 800b558: 2100 movs r1, #0 + 800b55a: f000 fd59 bl 800c010 + pbuf_free(q); + 800b55e: 697b ldr r3, [r7, #20] + 800b560: 0018 movs r0, r3 + 800b562: f7fa f89f bl 80056a4 + 800b566: e000 b.n 800b56a + return; + 800b568: 46c0 nop ; (mov r8, r8) +} + 800b56a: 46bd mov sp, r7 + 800b56c: b007 add sp, #28 + 800b56e: bd90 pop {r4, r7, pc} + 800b570: 20003158 .word 0x20003158 + +0800b574 : + * @return host order (!) lwip checksum (non-inverted Internet sum) + */ + +static u16_t +lwip_standard_chksum(void *dataptr, int len) +{ + 800b574: b580 push {r7, lr} + 800b576: b088 sub sp, #32 + 800b578: af00 add r7, sp, #0 + 800b57a: 6078 str r0, [r7, #4] + 800b57c: 6039 str r1, [r7, #0] + u8_t *pb = (u8_t *)dataptr; + 800b57e: 687b ldr r3, [r7, #4] + 800b580: 61fb str r3, [r7, #28] + u16_t *ps, t = 0; + 800b582: 230e movs r3, #14 + 800b584: 18fb adds r3, r7, r3 + 800b586: 2200 movs r2, #0 + 800b588: 801a strh r2, [r3, #0] + u32_t sum = 0; + 800b58a: 2300 movs r3, #0 + 800b58c: 617b str r3, [r7, #20] + int odd = ((mem_ptr_t)pb & 1); + 800b58e: 69fb ldr r3, [r7, #28] + 800b590: 2201 movs r2, #1 + 800b592: 4013 ands r3, r2 + 800b594: 613b str r3, [r7, #16] + + /* Get aligned to u16_t */ + if (odd && len > 0) { + 800b596: 693b ldr r3, [r7, #16] + 800b598: 2b00 cmp r3, #0 + 800b59a: d00d beq.n 800b5b8 + 800b59c: 683b ldr r3, [r7, #0] + 800b59e: 2b00 cmp r3, #0 + 800b5a0: dd0a ble.n 800b5b8 + ((u8_t *)&t)[1] = *pb++; + 800b5a2: 69fa ldr r2, [r7, #28] + 800b5a4: 1c53 adds r3, r2, #1 + 800b5a6: 61fb str r3, [r7, #28] + 800b5a8: 230e movs r3, #14 + 800b5aa: 18fb adds r3, r7, r3 + 800b5ac: 3301 adds r3, #1 + 800b5ae: 7812 ldrb r2, [r2, #0] + 800b5b0: 701a strb r2, [r3, #0] + len--; + 800b5b2: 683b ldr r3, [r7, #0] + 800b5b4: 3b01 subs r3, #1 + 800b5b6: 603b str r3, [r7, #0] + } + + /* Add the bulk of the data */ + ps = (u16_t *)(void *)pb; + 800b5b8: 69fb ldr r3, [r7, #28] + 800b5ba: 61bb str r3, [r7, #24] + while (len > 1) { + 800b5bc: e00a b.n 800b5d4 + sum += *ps++; + 800b5be: 69bb ldr r3, [r7, #24] + 800b5c0: 1c9a adds r2, r3, #2 + 800b5c2: 61ba str r2, [r7, #24] + 800b5c4: 881b ldrh r3, [r3, #0] + 800b5c6: 001a movs r2, r3 + 800b5c8: 697b ldr r3, [r7, #20] + 800b5ca: 189b adds r3, r3, r2 + 800b5cc: 617b str r3, [r7, #20] + len -= 2; + 800b5ce: 683b ldr r3, [r7, #0] + 800b5d0: 3b02 subs r3, #2 + 800b5d2: 603b str r3, [r7, #0] + while (len > 1) { + 800b5d4: 683b ldr r3, [r7, #0] + 800b5d6: 2b01 cmp r3, #1 + 800b5d8: dcf1 bgt.n 800b5be + } + + /* Consume left-over byte, if any */ + if (len > 0) { + 800b5da: 683b ldr r3, [r7, #0] + 800b5dc: 2b00 cmp r3, #0 + 800b5de: dd04 ble.n 800b5ea + ((u8_t *)&t)[0] = *(u8_t *)ps; + 800b5e0: 230e movs r3, #14 + 800b5e2: 18fb adds r3, r7, r3 + 800b5e4: 69ba ldr r2, [r7, #24] + 800b5e6: 7812 ldrb r2, [r2, #0] + 800b5e8: 701a strb r2, [r3, #0] + } + + /* Add end bytes */ + sum += t; + 800b5ea: 230e movs r3, #14 + 800b5ec: 18fb adds r3, r7, r3 + 800b5ee: 881b ldrh r3, [r3, #0] + 800b5f0: 001a movs r2, r3 + 800b5f2: 697b ldr r3, [r7, #20] + 800b5f4: 189b adds r3, r3, r2 + 800b5f6: 617b str r3, [r7, #20] + + /* Fold 32-bit sum to 16 bits + calling this twice is propably faster than if statements... */ + sum = FOLD_U32T(sum); + 800b5f8: 697b ldr r3, [r7, #20] + 800b5fa: 0c1a lsrs r2, r3, #16 + 800b5fc: 697b ldr r3, [r7, #20] + 800b5fe: 041b lsls r3, r3, #16 + 800b600: 0c1b lsrs r3, r3, #16 + 800b602: 18d3 adds r3, r2, r3 + 800b604: 617b str r3, [r7, #20] + sum = FOLD_U32T(sum); + 800b606: 697b ldr r3, [r7, #20] + 800b608: 0c1a lsrs r2, r3, #16 + 800b60a: 697b ldr r3, [r7, #20] + 800b60c: 041b lsls r3, r3, #16 + 800b60e: 0c1b lsrs r3, r3, #16 + 800b610: 18d3 adds r3, r2, r3 + 800b612: 617b str r3, [r7, #20] + + /* Swap if alignment was odd */ + if (odd) { + 800b614: 693b ldr r3, [r7, #16] + 800b616: 2b00 cmp r3, #0 + 800b618: d009 beq.n 800b62e + sum = SWAP_BYTES_IN_WORD(sum); + 800b61a: 697b ldr r3, [r7, #20] + 800b61c: 021b lsls r3, r3, #8 + 800b61e: 041b lsls r3, r3, #16 + 800b620: 0c1a lsrs r2, r3, #16 + 800b622: 697b ldr r3, [r7, #20] + 800b624: 0a1b lsrs r3, r3, #8 + 800b626: 21ff movs r1, #255 ; 0xff + 800b628: 400b ands r3, r1 + 800b62a: 4313 orrs r3, r2 + 800b62c: 617b str r3, [r7, #20] + } + + return (u16_t)sum; + 800b62e: 697b ldr r3, [r7, #20] + 800b630: b29b uxth r3, r3 +} + 800b632: 0018 movs r0, r3 + 800b634: 46bd mov sp, r7 + 800b636: b008 add sp, #32 + 800b638: bd80 pop {r7, pc} + +0800b63a : + */ +u16_t +inet_chksum_pseudo(struct pbuf *p, + ip_addr_t *src, ip_addr_t *dest, + u8_t proto, u16_t proto_len) +{ + 800b63a: b580 push {r7, lr} + 800b63c: b088 sub sp, #32 + 800b63e: af00 add r7, sp, #0 + 800b640: 60f8 str r0, [r7, #12] + 800b642: 60b9 str r1, [r7, #8] + 800b644: 607a str r2, [r7, #4] + 800b646: 001a movs r2, r3 + 800b648: 1cfb adds r3, r7, #3 + 800b64a: 701a strb r2, [r3, #0] + u32_t acc; + u32_t addr; + struct pbuf *q; + u8_t swapped; + + acc = 0; + 800b64c: 2300 movs r3, #0 + 800b64e: 61fb str r3, [r7, #28] + swapped = 0; + 800b650: 2317 movs r3, #23 + 800b652: 18fb adds r3, r7, r3 + 800b654: 2200 movs r2, #0 + 800b656: 701a strb r2, [r3, #0] + /* iterate through all pbuf in chain */ + for(q = p; q != NULL; q = q->next) { + 800b658: 68fb ldr r3, [r7, #12] + 800b65a: 61bb str r3, [r7, #24] + 800b65c: e02e b.n 800b6bc + LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): checksumming pbuf %p (has next %p) \n", + (void *)q, (void *)q->next)); + acc += LWIP_CHKSUM(q->payload, q->len); + 800b65e: 69bb ldr r3, [r7, #24] + 800b660: 685a ldr r2, [r3, #4] + 800b662: 69bb ldr r3, [r7, #24] + 800b664: 895b ldrh r3, [r3, #10] + 800b666: 0019 movs r1, r3 + 800b668: 0010 movs r0, r2 + 800b66a: f7ff ff83 bl 800b574 + 800b66e: 0003 movs r3, r0 + 800b670: 001a movs r2, r3 + 800b672: 69fb ldr r3, [r7, #28] + 800b674: 189b adds r3, r3, r2 + 800b676: 61fb str r3, [r7, #28] + /*LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): unwrapped lwip_chksum()=%"X32_F" \n", acc));*/ + /* just executing this next line is probably faster that the if statement needed + to check whether we really need to execute it, and does no harm */ + acc = FOLD_U32T(acc); + 800b678: 69fb ldr r3, [r7, #28] + 800b67a: 0c1a lsrs r2, r3, #16 + 800b67c: 69fb ldr r3, [r7, #28] + 800b67e: 041b lsls r3, r3, #16 + 800b680: 0c1b lsrs r3, r3, #16 + 800b682: 18d3 adds r3, r2, r3 + 800b684: 61fb str r3, [r7, #28] + if (q->len % 2 != 0) { + 800b686: 69bb ldr r3, [r7, #24] + 800b688: 895b ldrh r3, [r3, #10] + 800b68a: 2201 movs r2, #1 + 800b68c: 4013 ands r3, r2 + 800b68e: b29b uxth r3, r3 + 800b690: 2b00 cmp r3, #0 + 800b692: d010 beq.n 800b6b6 + swapped = 1 - swapped; + 800b694: 2217 movs r2, #23 + 800b696: 18bb adds r3, r7, r2 + 800b698: 18ba adds r2, r7, r2 + 800b69a: 7812 ldrb r2, [r2, #0] + 800b69c: 2101 movs r1, #1 + 800b69e: 1a8a subs r2, r1, r2 + 800b6a0: 701a strb r2, [r3, #0] + acc = SWAP_BYTES_IN_WORD(acc); + 800b6a2: 69fb ldr r3, [r7, #28] + 800b6a4: 021b lsls r3, r3, #8 + 800b6a6: 041b lsls r3, r3, #16 + 800b6a8: 0c1a lsrs r2, r3, #16 + 800b6aa: 69fb ldr r3, [r7, #28] + 800b6ac: 0a1b lsrs r3, r3, #8 + 800b6ae: 21ff movs r1, #255 ; 0xff + 800b6b0: 400b ands r3, r1 + 800b6b2: 4313 orrs r3, r2 + 800b6b4: 61fb str r3, [r7, #28] + for(q = p; q != NULL; q = q->next) { + 800b6b6: 69bb ldr r3, [r7, #24] + 800b6b8: 681b ldr r3, [r3, #0] + 800b6ba: 61bb str r3, [r7, #24] + 800b6bc: 69bb ldr r3, [r7, #24] + 800b6be: 2b00 cmp r3, #0 + 800b6c0: d1cd bne.n 800b65e + } + /*LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): wrapped lwip_chksum()=%"X32_F" \n", acc));*/ + } + + if (swapped) { + 800b6c2: 2317 movs r3, #23 + 800b6c4: 18fb adds r3, r7, r3 + 800b6c6: 781b ldrb r3, [r3, #0] + 800b6c8: 2b00 cmp r3, #0 + 800b6ca: d009 beq.n 800b6e0 + acc = SWAP_BYTES_IN_WORD(acc); + 800b6cc: 69fb ldr r3, [r7, #28] + 800b6ce: 021b lsls r3, r3, #8 + 800b6d0: 041b lsls r3, r3, #16 + 800b6d2: 0c1a lsrs r2, r3, #16 + 800b6d4: 69fb ldr r3, [r7, #28] + 800b6d6: 0a1b lsrs r3, r3, #8 + 800b6d8: 21ff movs r1, #255 ; 0xff + 800b6da: 400b ands r3, r1 + 800b6dc: 4313 orrs r3, r2 + 800b6de: 61fb str r3, [r7, #28] + } + addr = ip4_addr_get_u32(src); + 800b6e0: 68bb ldr r3, [r7, #8] + 800b6e2: 681b ldr r3, [r3, #0] + 800b6e4: 613b str r3, [r7, #16] + acc += (addr & 0xffffUL); + 800b6e6: 693b ldr r3, [r7, #16] + 800b6e8: 041b lsls r3, r3, #16 + 800b6ea: 0c1b lsrs r3, r3, #16 + 800b6ec: 69fa ldr r2, [r7, #28] + 800b6ee: 18d3 adds r3, r2, r3 + 800b6f0: 61fb str r3, [r7, #28] + acc += ((addr >> 16) & 0xffffUL); + 800b6f2: 693b ldr r3, [r7, #16] + 800b6f4: 0c1b lsrs r3, r3, #16 + 800b6f6: 69fa ldr r2, [r7, #28] + 800b6f8: 18d3 adds r3, r2, r3 + 800b6fa: 61fb str r3, [r7, #28] + addr = ip4_addr_get_u32(dest); + 800b6fc: 687b ldr r3, [r7, #4] + 800b6fe: 681b ldr r3, [r3, #0] + 800b700: 613b str r3, [r7, #16] + acc += (addr & 0xffffUL); + 800b702: 693b ldr r3, [r7, #16] + 800b704: 041b lsls r3, r3, #16 + 800b706: 0c1b lsrs r3, r3, #16 + 800b708: 69fa ldr r2, [r7, #28] + 800b70a: 18d3 adds r3, r2, r3 + 800b70c: 61fb str r3, [r7, #28] + acc += ((addr >> 16) & 0xffffUL); + 800b70e: 693b ldr r3, [r7, #16] + 800b710: 0c1b lsrs r3, r3, #16 + 800b712: 69fa ldr r2, [r7, #28] + 800b714: 18d3 adds r3, r2, r3 + 800b716: 61fb str r3, [r7, #28] + acc += (u32_t)htons((u16_t)proto); + 800b718: 1cfb adds r3, r7, #3 + 800b71a: 781b ldrb r3, [r3, #0] + 800b71c: b29b uxth r3, r3 + 800b71e: 0018 movs r0, r3 + 800b720: f7f8 ff78 bl 8004614 + 800b724: 0003 movs r3, r0 + 800b726: 001a movs r2, r3 + 800b728: 69fb ldr r3, [r7, #28] + 800b72a: 189b adds r3, r3, r2 + 800b72c: 61fb str r3, [r7, #28] + acc += (u32_t)htons(proto_len); + 800b72e: 2328 movs r3, #40 ; 0x28 + 800b730: 18fb adds r3, r7, r3 + 800b732: 881b ldrh r3, [r3, #0] + 800b734: 0018 movs r0, r3 + 800b736: f7f8 ff6d bl 8004614 + 800b73a: 0003 movs r3, r0 + 800b73c: 001a movs r2, r3 + 800b73e: 69fb ldr r3, [r7, #28] + 800b740: 189b adds r3, r3, r2 + 800b742: 61fb str r3, [r7, #28] + + /* Fold 32-bit sum to 16 bits + calling this twice is propably faster than if statements... */ + acc = FOLD_U32T(acc); + 800b744: 69fb ldr r3, [r7, #28] + 800b746: 0c1a lsrs r2, r3, #16 + 800b748: 69fb ldr r3, [r7, #28] + 800b74a: 041b lsls r3, r3, #16 + 800b74c: 0c1b lsrs r3, r3, #16 + 800b74e: 18d3 adds r3, r2, r3 + 800b750: 61fb str r3, [r7, #28] + acc = FOLD_U32T(acc); + 800b752: 69fb ldr r3, [r7, #28] + 800b754: 0c1a lsrs r2, r3, #16 + 800b756: 69fb ldr r3, [r7, #28] + 800b758: 041b lsls r3, r3, #16 + 800b75a: 0c1b lsrs r3, r3, #16 + 800b75c: 18d3 adds r3, r2, r3 + 800b75e: 61fb str r3, [r7, #28] + LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): pbuf chain lwip_chksum()=%"X32_F"\n", acc)); + return (u16_t)~(acc & 0xffffUL); + 800b760: 69fb ldr r3, [r7, #28] + 800b762: b29b uxth r3, r3 + 800b764: 43db mvns r3, r3 + 800b766: b29b uxth r3, r3 +} + 800b768: 0018 movs r0, r3 + 800b76a: 46bd mov sp, r7 + 800b76c: b008 add sp, #32 + 800b76e: bd80 pop {r7, pc} + +0800b770 : + * @return checksum (as u16_t) to be saved directly in the protocol header + */ + +u16_t +inet_chksum(void *dataptr, u16_t len) +{ + 800b770: b580 push {r7, lr} + 800b772: b082 sub sp, #8 + 800b774: af00 add r7, sp, #0 + 800b776: 6078 str r0, [r7, #4] + 800b778: 000a movs r2, r1 + 800b77a: 1cbb adds r3, r7, #2 + 800b77c: 801a strh r2, [r3, #0] + return ~LWIP_CHKSUM(dataptr, len); + 800b77e: 1cbb adds r3, r7, #2 + 800b780: 881a ldrh r2, [r3, #0] + 800b782: 687b ldr r3, [r7, #4] + 800b784: 0011 movs r1, r2 + 800b786: 0018 movs r0, r3 + 800b788: f7ff fef4 bl 800b574 + 800b78c: 0003 movs r3, r0 + 800b78e: 43db mvns r3, r3 + 800b790: b29b uxth r3, r3 +} + 800b792: 0018 movs r0, r3 + 800b794: 46bd mov sp, r7 + 800b796: b002 add sp, #8 + 800b798: bd80 pop {r7, pc} + +0800b79a : + * @param p pbuf chain over that the checksum should be calculated + * @return checksum (as u16_t) to be saved directly in the protocol header + */ +u16_t +inet_chksum_pbuf(struct pbuf *p) +{ + 800b79a: b580 push {r7, lr} + 800b79c: b086 sub sp, #24 + 800b79e: af00 add r7, sp, #0 + 800b7a0: 6078 str r0, [r7, #4] + u32_t acc; + struct pbuf *q; + u8_t swapped; + + acc = 0; + 800b7a2: 2300 movs r3, #0 + 800b7a4: 617b str r3, [r7, #20] + swapped = 0; + 800b7a6: 230f movs r3, #15 + 800b7a8: 18fb adds r3, r7, r3 + 800b7aa: 2200 movs r2, #0 + 800b7ac: 701a strb r2, [r3, #0] + for(q = p; q != NULL; q = q->next) { + 800b7ae: 687b ldr r3, [r7, #4] + 800b7b0: 613b str r3, [r7, #16] + 800b7b2: e02e b.n 800b812 + acc += LWIP_CHKSUM(q->payload, q->len); + 800b7b4: 693b ldr r3, [r7, #16] + 800b7b6: 685a ldr r2, [r3, #4] + 800b7b8: 693b ldr r3, [r7, #16] + 800b7ba: 895b ldrh r3, [r3, #10] + 800b7bc: 0019 movs r1, r3 + 800b7be: 0010 movs r0, r2 + 800b7c0: f7ff fed8 bl 800b574 + 800b7c4: 0003 movs r3, r0 + 800b7c6: 001a movs r2, r3 + 800b7c8: 697b ldr r3, [r7, #20] + 800b7ca: 189b adds r3, r3, r2 + 800b7cc: 617b str r3, [r7, #20] + acc = FOLD_U32T(acc); + 800b7ce: 697b ldr r3, [r7, #20] + 800b7d0: 0c1a lsrs r2, r3, #16 + 800b7d2: 697b ldr r3, [r7, #20] + 800b7d4: 041b lsls r3, r3, #16 + 800b7d6: 0c1b lsrs r3, r3, #16 + 800b7d8: 18d3 adds r3, r2, r3 + 800b7da: 617b str r3, [r7, #20] + if (q->len % 2 != 0) { + 800b7dc: 693b ldr r3, [r7, #16] + 800b7de: 895b ldrh r3, [r3, #10] + 800b7e0: 2201 movs r2, #1 + 800b7e2: 4013 ands r3, r2 + 800b7e4: b29b uxth r3, r3 + 800b7e6: 2b00 cmp r3, #0 + 800b7e8: d010 beq.n 800b80c + swapped = 1 - swapped; + 800b7ea: 220f movs r2, #15 + 800b7ec: 18bb adds r3, r7, r2 + 800b7ee: 18ba adds r2, r7, r2 + 800b7f0: 7812 ldrb r2, [r2, #0] + 800b7f2: 2101 movs r1, #1 + 800b7f4: 1a8a subs r2, r1, r2 + 800b7f6: 701a strb r2, [r3, #0] + acc = SWAP_BYTES_IN_WORD(acc); + 800b7f8: 697b ldr r3, [r7, #20] + 800b7fa: 021b lsls r3, r3, #8 + 800b7fc: 041b lsls r3, r3, #16 + 800b7fe: 0c1a lsrs r2, r3, #16 + 800b800: 697b ldr r3, [r7, #20] + 800b802: 0a1b lsrs r3, r3, #8 + 800b804: 21ff movs r1, #255 ; 0xff + 800b806: 400b ands r3, r1 + 800b808: 4313 orrs r3, r2 + 800b80a: 617b str r3, [r7, #20] + for(q = p; q != NULL; q = q->next) { + 800b80c: 693b ldr r3, [r7, #16] + 800b80e: 681b ldr r3, [r3, #0] + 800b810: 613b str r3, [r7, #16] + 800b812: 693b ldr r3, [r7, #16] + 800b814: 2b00 cmp r3, #0 + 800b816: d1cd bne.n 800b7b4 + } + } + + if (swapped) { + 800b818: 230f movs r3, #15 + 800b81a: 18fb adds r3, r7, r3 + 800b81c: 781b ldrb r3, [r3, #0] + 800b81e: 2b00 cmp r3, #0 + 800b820: d009 beq.n 800b836 + acc = SWAP_BYTES_IN_WORD(acc); + 800b822: 697b ldr r3, [r7, #20] + 800b824: 021b lsls r3, r3, #8 + 800b826: 041b lsls r3, r3, #16 + 800b828: 0c1a lsrs r2, r3, #16 + 800b82a: 697b ldr r3, [r7, #20] + 800b82c: 0a1b lsrs r3, r3, #8 + 800b82e: 21ff movs r1, #255 ; 0xff + 800b830: 400b ands r3, r1 + 800b832: 4313 orrs r3, r2 + 800b834: 617b str r3, [r7, #20] + } + return (u16_t)~(acc & 0xffffUL); + 800b836: 697b ldr r3, [r7, #20] + 800b838: b29b uxth r3, r3 + 800b83a: 43db mvns r3, r3 + 800b83c: b29b uxth r3, r3 +} + 800b83e: 0018 movs r0, r3 + 800b840: 46bd mov sp, r7 + 800b842: b006 add sp, #24 + 800b844: bd80 pop {r7, pc} + ... + +0800b848 : + * @param dest the destination IP address for which to find the route + * @return the netif on which to send to reach dest + */ +struct netif * +ip_route(ip_addr_t *dest) +{ + 800b848: b580 push {r7, lr} + 800b84a: b084 sub sp, #16 + 800b84c: af00 add r7, sp, #0 + 800b84e: 6078 str r0, [r7, #4] + return netif; + } +#endif + + /* iterate through netifs */ + for (netif = netif_list; netif != NULL; netif = netif->next) { + 800b850: 4b1c ldr r3, [pc, #112] ; (800b8c4 ) + 800b852: 681b ldr r3, [r3, #0] + 800b854: 60fb str r3, [r7, #12] + 800b856: e016 b.n 800b886 + /* network mask matches? */ + if (netif_is_up(netif)) { + 800b858: 68fb ldr r3, [r7, #12] + 800b85a: 2229 movs r2, #41 ; 0x29 + 800b85c: 5c9b ldrb r3, [r3, r2] + 800b85e: 1c1a adds r2, r3, #0 + 800b860: 2301 movs r3, #1 + 800b862: 4013 ands r3, r2 + 800b864: b2db uxtb r3, r3 + 800b866: 2b00 cmp r3, #0 + 800b868: d00a beq.n 800b880 + if (ip_addr_netcmp(dest, &(netif->ip_addr), &(netif->netmask))) { + 800b86a: 687b ldr r3, [r7, #4] + 800b86c: 681a ldr r2, [r3, #0] + 800b86e: 68fb ldr r3, [r7, #12] + 800b870: 685b ldr r3, [r3, #4] + 800b872: 405a eors r2, r3 + 800b874: 68fb ldr r3, [r7, #12] + 800b876: 689b ldr r3, [r3, #8] + 800b878: 4013 ands r3, r2 + 800b87a: d101 bne.n 800b880 + /* return netif on which to forward IP packet */ + return netif; + 800b87c: 68fb ldr r3, [r7, #12] + 800b87e: e01d b.n 800b8bc + for (netif = netif_list; netif != NULL; netif = netif->next) { + 800b880: 68fb ldr r3, [r7, #12] + 800b882: 681b ldr r3, [r3, #0] + 800b884: 60fb str r3, [r7, #12] + 800b886: 68fb ldr r3, [r7, #12] + 800b888: 2b00 cmp r3, #0 + 800b88a: d1e5 bne.n 800b858 + } + } + } + if ((netif_default == NULL) || (!netif_is_up(netif_default))) { + 800b88c: 4b0e ldr r3, [pc, #56] ; (800b8c8 ) + 800b88e: 681b ldr r3, [r3, #0] + 800b890: 2b00 cmp r3, #0 + 800b892: d007 beq.n 800b8a4 + 800b894: 4b0c ldr r3, [pc, #48] ; (800b8c8 ) + 800b896: 681b ldr r3, [r3, #0] + 800b898: 2229 movs r2, #41 ; 0x29 + 800b89a: 5c9b ldrb r3, [r3, r2] + 800b89c: 001a movs r2, r3 + 800b89e: 2301 movs r3, #1 + 800b8a0: 4013 ands r3, r2 + 800b8a2: d109 bne.n 800b8b8 + LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip_route: No route to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", + ip4_addr1_16(dest), ip4_addr2_16(dest), ip4_addr3_16(dest), ip4_addr4_16(dest))); + IP_STATS_INC(ip.rterr); + 800b8a4: 4b09 ldr r3, [pc, #36] ; (800b8cc ) + 800b8a6: 2256 movs r2, #86 ; 0x56 + 800b8a8: 5a9b ldrh r3, [r3, r2] + 800b8aa: 3301 adds r3, #1 + 800b8ac: b299 uxth r1, r3 + 800b8ae: 4b07 ldr r3, [pc, #28] ; (800b8cc ) + 800b8b0: 2256 movs r2, #86 ; 0x56 + 800b8b2: 5299 strh r1, [r3, r2] + snmp_inc_ipoutnoroutes(); + return NULL; + 800b8b4: 2300 movs r3, #0 + 800b8b6: e001 b.n 800b8bc + } + /* no matching netif found, use default netif */ + return netif_default; + 800b8b8: 4b03 ldr r3, [pc, #12] ; (800b8c8 ) + 800b8ba: 681b ldr r3, [r3, #0] +} + 800b8bc: 0018 movs r0, r3 + 800b8be: 46bd mov sp, r7 + 800b8c0: b004 add sp, #16 + 800b8c2: bd80 pop {r7, pc} + 800b8c4: 2000314c .word 0x2000314c + 800b8c8: 20003150 .word 0x20003150 + 800b8cc: 20003158 .word 0x20003158 + +0800b8d0 : + * @return ERR_OK if the packet was processed (could return ERR_* if it wasn't + * processed, but currently always returns ERR_OK) + */ +err_t +ip_input(struct pbuf *p, struct netif *inp) +{ + 800b8d0: b5b0 push {r4, r5, r7, lr} + 800b8d2: b088 sub sp, #32 + 800b8d4: af00 add r7, sp, #0 + 800b8d6: 6078 str r0, [r7, #4] + 800b8d8: 6039 str r1, [r7, #0] + struct ip_hdr *iphdr; + struct netif *netif; + u16_t iphdr_hlen; + u16_t iphdr_len; +#if IP_ACCEPT_LINK_LAYER_ADDRESSING + int check_ip_src=1; + 800b8da: 2301 movs r3, #1 + 800b8dc: 617b str r3, [r7, #20] +#endif /* IP_ACCEPT_LINK_LAYER_ADDRESSING */ + + IP_STATS_INC(ip.recv); + 800b8de: 4bcd ldr r3, [pc, #820] ; (800bc14 ) + 800b8e0: 224a movs r2, #74 ; 0x4a + 800b8e2: 5a9b ldrh r3, [r3, r2] + 800b8e4: 3301 adds r3, #1 + 800b8e6: b299 uxth r1, r3 + 800b8e8: 4bca ldr r3, [pc, #808] ; (800bc14 ) + 800b8ea: 224a movs r2, #74 ; 0x4a + 800b8ec: 5299 strh r1, [r3, r2] + snmp_inc_ipinreceives(); + + /* identify the IP header */ + iphdr = (struct ip_hdr *)p->payload; + 800b8ee: 687b ldr r3, [r7, #4] + 800b8f0: 685b ldr r3, [r3, #4] + 800b8f2: 61fb str r3, [r7, #28] + if (IPH_V(iphdr) != 4) { + 800b8f4: 69fb ldr r3, [r7, #28] + 800b8f6: 781b ldrb r3, [r3, #0] + 800b8f8: 091b lsrs r3, r3, #4 + 800b8fa: b2db uxtb r3, r3 + 800b8fc: 2b04 cmp r3, #4 + 800b8fe: d015 beq.n 800b92c + LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_WARNING, ("IP packet dropped due to bad version number %"U16_F"\n", IPH_V(iphdr))); + ip_debug_print(p); + pbuf_free(p); + 800b900: 687b ldr r3, [r7, #4] + 800b902: 0018 movs r0, r3 + 800b904: f7f9 fece bl 80056a4 + IP_STATS_INC(ip.err); + 800b908: 4bc2 ldr r3, [pc, #776] ; (800bc14 ) + 800b90a: 225c movs r2, #92 ; 0x5c + 800b90c: 5a9b ldrh r3, [r3, r2] + 800b90e: 3301 adds r3, #1 + 800b910: b299 uxth r1, r3 + 800b912: 4bc0 ldr r3, [pc, #768] ; (800bc14 ) + 800b914: 225c movs r2, #92 ; 0x5c + 800b916: 5299 strh r1, [r3, r2] + IP_STATS_INC(ip.drop); + 800b918: 4bbe ldr r3, [pc, #760] ; (800bc14 ) + 800b91a: 224e movs r2, #78 ; 0x4e + 800b91c: 5a9b ldrh r3, [r3, r2] + 800b91e: 3301 adds r3, #1 + 800b920: b299 uxth r1, r3 + 800b922: 4bbc ldr r3, [pc, #752] ; (800bc14 ) + 800b924: 224e movs r2, #78 ; 0x4e + 800b926: 5299 strh r1, [r3, r2] + snmp_inc_ipinhdrerrors(); + return ERR_OK; + 800b928: 2300 movs r3, #0 + 800b92a: e18f b.n 800bc4c + return ERR_OK; + } +#endif + + /* obtain IP header length in number of 32-bit words */ + iphdr_hlen = IPH_HL(iphdr); + 800b92c: 69fb ldr r3, [r7, #28] + 800b92e: 781b ldrb r3, [r3, #0] + 800b930: b29a uxth r2, r3 + 800b932: 250e movs r5, #14 + 800b934: 197b adds r3, r7, r5 + 800b936: 210f movs r1, #15 + 800b938: 400a ands r2, r1 + 800b93a: 801a strh r2, [r3, #0] + /* calculate IP header length in bytes */ + iphdr_hlen *= 4; + 800b93c: 197b adds r3, r7, r5 + 800b93e: 197a adds r2, r7, r5 + 800b940: 8812 ldrh r2, [r2, #0] + 800b942: 0092 lsls r2, r2, #2 + 800b944: 801a strh r2, [r3, #0] + /* obtain ip length in bytes */ + iphdr_len = ntohs(IPH_LEN(iphdr)); + 800b946: 69fb ldr r3, [r7, #28] + 800b948: 789a ldrb r2, [r3, #2] + 800b94a: 78db ldrb r3, [r3, #3] + 800b94c: 021b lsls r3, r3, #8 + 800b94e: 4313 orrs r3, r2 + 800b950: b29b uxth r3, r3 + 800b952: 220c movs r2, #12 + 800b954: 18bc adds r4, r7, r2 + 800b956: 0018 movs r0, r3 + 800b958: f7f8 fe72 bl 8004640 + 800b95c: 0003 movs r3, r0 + 800b95e: 8023 strh r3, [r4, #0] + + /* header length exceeds first pbuf length, or ip length exceeds total pbuf length? */ + if ((iphdr_hlen > p->len) || (iphdr_len > p->tot_len)) { + 800b960: 687b ldr r3, [r7, #4] + 800b962: 895b ldrh r3, [r3, #10] + 800b964: 197a adds r2, r7, r5 + 800b966: 8812 ldrh r2, [r2, #0] + 800b968: 429a cmp r2, r3 + 800b96a: d806 bhi.n 800b97a + 800b96c: 687b ldr r3, [r7, #4] + 800b96e: 891b ldrh r3, [r3, #8] + 800b970: 220c movs r2, #12 + 800b972: 18ba adds r2, r7, r2 + 800b974: 8812 ldrh r2, [r2, #0] + 800b976: 429a cmp r2, r3 + 800b978: d915 bls.n 800b9a6 + LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, + ("IP (len %"U16_F") is longer than pbuf (len %"U16_F"), IP packet dropped.\n", + iphdr_len, p->tot_len)); + } + /* free (drop) packet pbufs */ + pbuf_free(p); + 800b97a: 687b ldr r3, [r7, #4] + 800b97c: 0018 movs r0, r3 + 800b97e: f7f9 fe91 bl 80056a4 + IP_STATS_INC(ip.lenerr); + 800b982: 4ba4 ldr r3, [pc, #656] ; (800bc14 ) + 800b984: 2252 movs r2, #82 ; 0x52 + 800b986: 5a9b ldrh r3, [r3, r2] + 800b988: 3301 adds r3, #1 + 800b98a: b299 uxth r1, r3 + 800b98c: 4ba1 ldr r3, [pc, #644] ; (800bc14 ) + 800b98e: 2252 movs r2, #82 ; 0x52 + 800b990: 5299 strh r1, [r3, r2] + IP_STATS_INC(ip.drop); + 800b992: 4ba0 ldr r3, [pc, #640] ; (800bc14 ) + 800b994: 224e movs r2, #78 ; 0x4e + 800b996: 5a9b ldrh r3, [r3, r2] + 800b998: 3301 adds r3, #1 + 800b99a: b299 uxth r1, r3 + 800b99c: 4b9d ldr r3, [pc, #628] ; (800bc14 ) + 800b99e: 224e movs r2, #78 ; 0x4e + 800b9a0: 5299 strh r1, [r3, r2] + snmp_inc_ipindiscards(); + return ERR_OK; + 800b9a2: 2300 movs r3, #0 + 800b9a4: e152 b.n 800bc4c + } + + /* verify checksum */ +#if CHECKSUM_CHECK_IP + if (inet_chksum(iphdr, iphdr_hlen) != 0) { + 800b9a6: 230e movs r3, #14 + 800b9a8: 18fb adds r3, r7, r3 + 800b9aa: 881a ldrh r2, [r3, #0] + 800b9ac: 69fb ldr r3, [r7, #28] + 800b9ae: 0011 movs r1, r2 + 800b9b0: 0018 movs r0, r3 + 800b9b2: f7ff fedd bl 800b770 + 800b9b6: 1e03 subs r3, r0, #0 + 800b9b8: d015 beq.n 800b9e6 + + LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, + ("Checksum (0x%"X16_F") failed, IP packet dropped.\n", inet_chksum(iphdr, iphdr_hlen))); + ip_debug_print(p); + pbuf_free(p); + 800b9ba: 687b ldr r3, [r7, #4] + 800b9bc: 0018 movs r0, r3 + 800b9be: f7f9 fe71 bl 80056a4 + IP_STATS_INC(ip.chkerr); + 800b9c2: 4b94 ldr r3, [pc, #592] ; (800bc14 ) + 800b9c4: 2250 movs r2, #80 ; 0x50 + 800b9c6: 5a9b ldrh r3, [r3, r2] + 800b9c8: 3301 adds r3, #1 + 800b9ca: b299 uxth r1, r3 + 800b9cc: 4b91 ldr r3, [pc, #580] ; (800bc14 ) + 800b9ce: 2250 movs r2, #80 ; 0x50 + 800b9d0: 5299 strh r1, [r3, r2] + IP_STATS_INC(ip.drop); + 800b9d2: 4b90 ldr r3, [pc, #576] ; (800bc14 ) + 800b9d4: 224e movs r2, #78 ; 0x4e + 800b9d6: 5a9b ldrh r3, [r3, r2] + 800b9d8: 3301 adds r3, #1 + 800b9da: b299 uxth r1, r3 + 800b9dc: 4b8d ldr r3, [pc, #564] ; (800bc14 ) + 800b9de: 224e movs r2, #78 ; 0x4e + 800b9e0: 5299 strh r1, [r3, r2] + snmp_inc_ipinhdrerrors(); + return ERR_OK; + 800b9e2: 2300 movs r3, #0 + 800b9e4: e132 b.n 800bc4c + } +#endif + + /* Trim pbuf. This should have been done at the netif layer, + * but we'll do it anyway just to be sure that its done. */ + pbuf_realloc(p, iphdr_len); + 800b9e6: 230c movs r3, #12 + 800b9e8: 18fb adds r3, r7, r3 + 800b9ea: 881a ldrh r2, [r3, #0] + 800b9ec: 687b ldr r3, [r7, #4] + 800b9ee: 0011 movs r1, r2 + 800b9f0: 0018 movs r0, r3 + 800b9f2: f7f9 fd5e bl 80054b2 + + /* copy IP addresses to aligned ip_addr_t */ + ip_addr_copy(current_iphdr_dest, iphdr->dest); + 800b9f6: 69fb ldr r3, [r7, #28] + 800b9f8: 7c1a ldrb r2, [r3, #16] + 800b9fa: 7c59 ldrb r1, [r3, #17] + 800b9fc: 0209 lsls r1, r1, #8 + 800b9fe: 430a orrs r2, r1 + 800ba00: 7c99 ldrb r1, [r3, #18] + 800ba02: 0409 lsls r1, r1, #16 + 800ba04: 430a orrs r2, r1 + 800ba06: 7cdb ldrb r3, [r3, #19] + 800ba08: 061b lsls r3, r3, #24 + 800ba0a: 4313 orrs r3, r2 + 800ba0c: 001a movs r2, r3 + 800ba0e: 4b82 ldr r3, [pc, #520] ; (800bc18 ) + 800ba10: 601a str r2, [r3, #0] + ip_addr_copy(current_iphdr_src, iphdr->src); + 800ba12: 69fb ldr r3, [r7, #28] + 800ba14: 7b1a ldrb r2, [r3, #12] + 800ba16: 7b59 ldrb r1, [r3, #13] + 800ba18: 0209 lsls r1, r1, #8 + 800ba1a: 430a orrs r2, r1 + 800ba1c: 7b99 ldrb r1, [r3, #14] + 800ba1e: 0409 lsls r1, r1, #16 + 800ba20: 430a orrs r2, r1 + 800ba22: 7bdb ldrb r3, [r3, #15] + 800ba24: 061b lsls r3, r3, #24 + 800ba26: 4313 orrs r3, r2 + 800ba28: 001a movs r2, r3 + 800ba2a: 4b7c ldr r3, [pc, #496] ; (800bc1c ) + 800ba2c: 601a str r2, [r3, #0] +#endif /* LWIP_IGMP */ + { + /* start trying with inp. if that's not acceptable, start walking the + list of configured netifs. + 'first' is used as a boolean to mark whether we started walking the list */ + int first = 1; + 800ba2e: 2301 movs r3, #1 + 800ba30: 613b str r3, [r7, #16] + netif = inp; + 800ba32: 683b ldr r3, [r7, #0] + 800ba34: 61bb str r3, [r7, #24] + ip4_addr_get_u32(&iphdr->dest) & ip4_addr_get_u32(&netif->netmask), + ip4_addr_get_u32(&netif->ip_addr) & ip4_addr_get_u32(&netif->netmask), + ip4_addr_get_u32(&iphdr->dest) & ~ip4_addr_get_u32(&netif->netmask))); + + /* interface is up and configured? */ + if ((netif_is_up(netif)) && (!ip_addr_isany(&(netif->ip_addr)))) { + 800ba36: 69bb ldr r3, [r7, #24] + 800ba38: 2229 movs r2, #41 ; 0x29 + 800ba3a: 5c9b ldrb r3, [r3, r2] + 800ba3c: 1c1a adds r2, r3, #0 + 800ba3e: 2301 movs r3, #1 + 800ba40: 4013 ands r3, r2 + 800ba42: b2db uxtb r3, r3 + 800ba44: 2b00 cmp r3, #0 + 800ba46: d016 beq.n 800ba76 + 800ba48: 69bb ldr r3, [r7, #24] + 800ba4a: 3304 adds r3, #4 + 800ba4c: 2b00 cmp r3, #0 + 800ba4e: d012 beq.n 800ba76 + 800ba50: 69bb ldr r3, [r7, #24] + 800ba52: 685b ldr r3, [r3, #4] + 800ba54: 2b00 cmp r3, #0 + 800ba56: d00e beq.n 800ba76 + /* unicast to this interface address? */ + if (ip_addr_cmp(¤t_iphdr_dest, &(netif->ip_addr)) || + 800ba58: 4b6f ldr r3, [pc, #444] ; (800bc18 ) + 800ba5a: 681a ldr r2, [r3, #0] + 800ba5c: 69bb ldr r3, [r7, #24] + 800ba5e: 685b ldr r3, [r3, #4] + 800ba60: 429a cmp r2, r3 + 800ba62: d01e beq.n 800baa2 + /* or broadcast on this interface network address? */ + ip_addr_isbroadcast(¤t_iphdr_dest, netif)) { + 800ba64: 4b6c ldr r3, [pc, #432] ; (800bc18 ) + 800ba66: 681b ldr r3, [r3, #0] + 800ba68: 69ba ldr r2, [r7, #24] + 800ba6a: 0011 movs r1, r2 + 800ba6c: 0018 movs r0, r3 + 800ba6e: f000 fb05 bl 800c07c + 800ba72: 1e03 subs r3, r0, #0 + if (ip_addr_cmp(¤t_iphdr_dest, &(netif->ip_addr)) || + 800ba74: d115 bne.n 800baa2 + /* break out of for loop */ + break; + } +#endif /* LWIP_AUTOIP */ + } + if (first) { + 800ba76: 693b ldr r3, [r7, #16] + 800ba78: 2b00 cmp r3, #0 + 800ba7a: d005 beq.n 800ba88 + first = 0; + 800ba7c: 2300 movs r3, #0 + 800ba7e: 613b str r3, [r7, #16] + netif = netif_list; + 800ba80: 4b67 ldr r3, [pc, #412] ; (800bc20 ) + 800ba82: 681b ldr r3, [r3, #0] + 800ba84: 61bb str r3, [r7, #24] + 800ba86: e002 b.n 800ba8e + } else { + netif = netif->next; + 800ba88: 69bb ldr r3, [r7, #24] + 800ba8a: 681b ldr r3, [r3, #0] + 800ba8c: 61bb str r3, [r7, #24] + } + if (netif == inp) { + 800ba8e: 69ba ldr r2, [r7, #24] + 800ba90: 683b ldr r3, [r7, #0] + 800ba92: 429a cmp r2, r3 + 800ba94: d102 bne.n 800ba9c + netif = netif->next; + 800ba96: 69bb ldr r3, [r7, #24] + 800ba98: 681b ldr r3, [r3, #0] + 800ba9a: 61bb str r3, [r7, #24] + } + } while(netif != NULL); + 800ba9c: 69bb ldr r3, [r7, #24] + 800ba9e: 2b00 cmp r3, #0 + 800baa0: d1c9 bne.n 800ba36 + * If you want to accept private broadcast communication while a netif is down, + * define LWIP_IP_ACCEPT_UDP_PORT(dst_port), e.g.: + * + * #define LWIP_IP_ACCEPT_UDP_PORT(dst_port) ((dst_port) == PP_NTOHS(12345)) + */ + if (netif == NULL) { + 800baa2: 69bb ldr r3, [r7, #24] + 800baa4: 2b00 cmp r3, #0 + 800baa6: d117 bne.n 800bad8 + /* remote port is DHCP server? */ + if (IPH_PROTO(iphdr) == IP_PROTO_UDP) { + 800baa8: 69fb ldr r3, [r7, #28] + 800baaa: 7a5b ldrb r3, [r3, #9] + 800baac: 2b11 cmp r3, #17 + 800baae: d113 bne.n 800bad8 + struct udp_hdr *udphdr = (struct udp_hdr *)((u8_t *)iphdr + iphdr_hlen); + 800bab0: 230e movs r3, #14 + 800bab2: 18fb adds r3, r7, r3 + 800bab4: 881b ldrh r3, [r3, #0] + 800bab6: 69fa ldr r2, [r7, #28] + 800bab8: 18d3 adds r3, r2, r3 + 800baba: 60bb str r3, [r7, #8] + LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE, ("ip_input: UDP packet to DHCP client port %"U16_F"\n", + ntohs(udphdr->dest))); + if (IP_ACCEPT_LINK_LAYER_ADDRESSED_PORT(udphdr->dest)) { + 800babc: 68bb ldr r3, [r7, #8] + 800babe: 789a ldrb r2, [r3, #2] + 800bac0: 78db ldrb r3, [r3, #3] + 800bac2: 021b lsls r3, r3, #8 + 800bac4: 4313 orrs r3, r2 + 800bac6: b29a uxth r2, r3 + 800bac8: 2386 movs r3, #134 ; 0x86 + 800baca: 01db lsls r3, r3, #7 + 800bacc: 429a cmp r2, r3 + 800bace: d103 bne.n 800bad8 + LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE, ("ip_input: DHCP packet accepted.\n")); + netif = inp; + 800bad0: 683b ldr r3, [r7, #0] + 800bad2: 61bb str r3, [r7, #24] + check_ip_src = 0; + 800bad4: 2300 movs r3, #0 + 800bad6: 617b str r3, [r7, #20] +#endif /* IP_ACCEPT_LINK_LAYER_ADDRESSING */ + + /* broadcast or multicast packet source address? Compliant with RFC 1122: 3.2.1.3 */ +#if IP_ACCEPT_LINK_LAYER_ADDRESSING + /* DHCP servers need 0.0.0.0 to be allowed as source address (RFC 1.1.2.2: 3.2.1.3/a) */ + if (check_ip_src && !ip_addr_isany(¤t_iphdr_src)) + 800bad8: 697b ldr r3, [r7, #20] + 800bada: 2b00 cmp r3, #0 + 800badc: d020 beq.n 800bb20 + 800bade: 4b4f ldr r3, [pc, #316] ; (800bc1c ) + 800bae0: 681b ldr r3, [r3, #0] + 800bae2: 2b00 cmp r3, #0 + 800bae4: d01c beq.n 800bb20 +#endif /* IP_ACCEPT_LINK_LAYER_ADDRESSING */ + { if ((ip_addr_isbroadcast(¤t_iphdr_src, inp)) || + 800bae6: 4b4d ldr r3, [pc, #308] ; (800bc1c ) + 800bae8: 681b ldr r3, [r3, #0] + 800baea: 683a ldr r2, [r7, #0] + 800baec: 0011 movs r1, r2 + 800baee: 0018 movs r0, r3 + 800baf0: f000 fac4 bl 800c07c + 800baf4: 1e03 subs r3, r0, #0 + 800baf6: d105 bne.n 800bb04 + (ip_addr_ismulticast(¤t_iphdr_src))) { + 800baf8: 4b48 ldr r3, [pc, #288] ; (800bc1c ) + 800bafa: 681b ldr r3, [r3, #0] + 800bafc: 22f0 movs r2, #240 ; 0xf0 + 800bafe: 4013 ands r3, r2 + { if ((ip_addr_isbroadcast(¤t_iphdr_src, inp)) || + 800bb00: 2be0 cmp r3, #224 ; 0xe0 + 800bb02: d10d bne.n 800bb20 + /* packet source is not valid */ + LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, ("ip_input: packet source is not valid.\n")); + /* free (drop) packet pbufs */ + pbuf_free(p); + 800bb04: 687b ldr r3, [r7, #4] + 800bb06: 0018 movs r0, r3 + 800bb08: f7f9 fdcc bl 80056a4 + IP_STATS_INC(ip.drop); + 800bb0c: 4b41 ldr r3, [pc, #260] ; (800bc14 ) + 800bb0e: 224e movs r2, #78 ; 0x4e + 800bb10: 5a9b ldrh r3, [r3, r2] + 800bb12: 3301 adds r3, #1 + 800bb14: b299 uxth r1, r3 + 800bb16: 4b3f ldr r3, [pc, #252] ; (800bc14 ) + 800bb18: 224e movs r2, #78 ; 0x4e + 800bb1a: 5299 strh r1, [r3, r2] + snmp_inc_ipinaddrerrors(); + snmp_inc_ipindiscards(); + return ERR_OK; + 800bb1c: 2300 movs r3, #0 + 800bb1e: e095 b.n 800bc4c + } + } + + /* packet not for us? */ + if (netif == NULL) { + 800bb20: 69bb ldr r3, [r7, #24] + 800bb22: 2b00 cmp r3, #0 + 800bb24: d105 bne.n 800bb32 +#endif /* IP_FORWARD */ + { + snmp_inc_ipinaddrerrors(); + snmp_inc_ipindiscards(); + } + pbuf_free(p); + 800bb26: 687b ldr r3, [r7, #4] + 800bb28: 0018 movs r0, r3 + 800bb2a: f7f9 fdbb bl 80056a4 + return ERR_OK; + 800bb2e: 2300 movs r3, #0 + 800bb30: e08c b.n 800bc4c + } + /* packet consists of multiple fragments? */ + if ((IPH_OFFSET(iphdr) & PP_HTONS(IP_OFFMASK | IP_MF)) != 0) { + 800bb32: 69fb ldr r3, [r7, #28] + 800bb34: 799a ldrb r2, [r3, #6] + 800bb36: 79db ldrb r3, [r3, #7] + 800bb38: 021b lsls r3, r3, #8 + 800bb3a: 4313 orrs r3, r2 + 800bb3c: b29b uxth r3, r3 + 800bb3e: 001a movs r2, r3 + 800bb40: 4b38 ldr r3, [pc, #224] ; (800bc24 ) + 800bb42: 4013 ands r3, r2 + 800bb44: d00d beq.n 800bb62 +#if IP_REASSEMBLY /* packet fragment reassembly code present? */ + LWIP_DEBUGF(IP_DEBUG, ("IP packet is a fragment (id=0x%04"X16_F" tot_len=%"U16_F" len=%"U16_F" MF=%"U16_F" offset=%"U16_F"), calling ip_reass()\n", + ntohs(IPH_ID(iphdr)), p->tot_len, ntohs(IPH_LEN(iphdr)), !!(IPH_OFFSET(iphdr) & PP_HTONS(IP_MF)), (ntohs(IPH_OFFSET(iphdr)) & IP_OFFMASK)*8)); + /* reassemble the packet*/ + p = ip_reass(p); + 800bb46: 687b ldr r3, [r7, #4] + 800bb48: 0018 movs r0, r3 + 800bb4a: f000 fe51 bl 800c7f0 + 800bb4e: 0003 movs r3, r0 + 800bb50: 607b str r3, [r7, #4] + /* packet not fully reassembled yet? */ + if (p == NULL) { + 800bb52: 687b ldr r3, [r7, #4] + 800bb54: 2b00 cmp r3, #0 + 800bb56: d101 bne.n 800bb5c + return ERR_OK; + 800bb58: 2300 movs r3, #0 + 800bb5a: e077 b.n 800bc4c + } + iphdr = (struct ip_hdr *)p->payload; + 800bb5c: 687b ldr r3, [r7, #4] + 800bb5e: 685b ldr r3, [r3, #4] + 800bb60: 61fb str r3, [r7, #28] + /* send to upper layers */ + LWIP_DEBUGF(IP_DEBUG, ("ip_input: \n")); + ip_debug_print(p); + LWIP_DEBUGF(IP_DEBUG, ("ip_input: p->len %"U16_F" p->tot_len %"U16_F"\n", p->len, p->tot_len)); + + current_netif = inp; + 800bb62: 4b31 ldr r3, [pc, #196] ; (800bc28 ) + 800bb64: 683a ldr r2, [r7, #0] + 800bb66: 601a str r2, [r3, #0] + current_header = iphdr; + 800bb68: 4b30 ldr r3, [pc, #192] ; (800bc2c ) + 800bb6a: 69fa ldr r2, [r7, #28] + 800bb6c: 601a str r2, [r3, #0] + +#if LWIP_RAW + /* raw input did not eat the packet? */ + if (raw_input(p, inp) == 0) + 800bb6e: 683a ldr r2, [r7, #0] + 800bb70: 687b ldr r3, [r7, #4] + 800bb72: 0011 movs r1, r2 + 800bb74: 0018 movs r0, r3 + 800bb76: f7f9 ffa9 bl 8005acc + 800bb7a: 1e03 subs r3, r0, #0 + 800bb7c: d158 bne.n 800bc30 +#endif /* LWIP_RAW */ + { + switch (IPH_PROTO(iphdr)) { + 800bb7e: 69fb ldr r3, [r7, #28] + 800bb80: 7a5b ldrb r3, [r3, #9] + 800bb82: 2b06 cmp r3, #6 + 800bb84: d00b beq.n 800bb9e + 800bb86: 2b11 cmp r3, #17 + 800bb88: d002 beq.n 800bb90 + 800bb8a: 2b01 cmp r3, #1 + 800bb8c: d00e beq.n 800bbac + 800bb8e: e014 b.n 800bbba + case IP_PROTO_UDP: +#if LWIP_UDPLITE + case IP_PROTO_UDPLITE: +#endif /* LWIP_UDPLITE */ + snmp_inc_ipindelivers(); + udp_input(p, inp); + 800bb90: 683a ldr r2, [r7, #0] + 800bb92: 687b ldr r3, [r7, #4] + 800bb94: 0011 movs r1, r2 + 800bb96: 0018 movs r0, r3 + 800bb98: f7fe fe8a bl 800a8b0 + break; + 800bb9c: e049 b.n 800bc32 +#endif /* LWIP_UDP */ +#if LWIP_TCP + case IP_PROTO_TCP: + snmp_inc_ipindelivers(); + tcp_input(p, inp); + 800bb9e: 683a ldr r2, [r7, #0] + 800bba0: 687b ldr r3, [r7, #4] + 800bba2: 0011 movs r1, r2 + 800bba4: 0018 movs r0, r3 + 800bba6: f7fb f813 bl 8006bd0 + break; + 800bbaa: e042 b.n 800bc32 +#endif /* LWIP_TCP */ +#if LWIP_ICMP + case IP_PROTO_ICMP: + snmp_inc_ipindelivers(); + icmp_input(p, inp); + 800bbac: 683a ldr r2, [r7, #0] + 800bbae: 687b ldr r3, [r7, #4] + 800bbb0: 0011 movs r1, r2 + 800bbb2: 0018 movs r0, r3 + 800bbb4: f7ff fa30 bl 800b018 + break; + 800bbb8: e03b b.n 800bc32 + break; +#endif /* LWIP_IGMP */ + default: +#if LWIP_ICMP + /* send ICMP destination protocol unreachable unless is was a broadcast */ + if (!ip_addr_isbroadcast(¤t_iphdr_dest, inp) && + 800bbba: 4b17 ldr r3, [pc, #92] ; (800bc18 ) + 800bbbc: 681b ldr r3, [r3, #0] + 800bbbe: 683a ldr r2, [r7, #0] + 800bbc0: 0011 movs r1, r2 + 800bbc2: 0018 movs r0, r3 + 800bbc4: f000 fa5a bl 800c07c + 800bbc8: 1e03 subs r3, r0, #0 + 800bbca: d10d bne.n 800bbe8 + !ip_addr_ismulticast(¤t_iphdr_dest)) { + 800bbcc: 4b12 ldr r3, [pc, #72] ; (800bc18 ) + 800bbce: 681b ldr r3, [r3, #0] + 800bbd0: 22f0 movs r2, #240 ; 0xf0 + 800bbd2: 4013 ands r3, r2 + if (!ip_addr_isbroadcast(¤t_iphdr_dest, inp) && + 800bbd4: 2be0 cmp r3, #224 ; 0xe0 + 800bbd6: d007 beq.n 800bbe8 + p->payload = iphdr; + 800bbd8: 687b ldr r3, [r7, #4] + 800bbda: 69fa ldr r2, [r7, #28] + 800bbdc: 605a str r2, [r3, #4] + icmp_dest_unreach(p, ICMP_DUR_PROTO); + 800bbde: 687b ldr r3, [r7, #4] + 800bbe0: 2102 movs r1, #2 + 800bbe2: 0018 movs r0, r3 + 800bbe4: f7ff fc12 bl 800b40c + } +#endif /* LWIP_ICMP */ + pbuf_free(p); + 800bbe8: 687b ldr r3, [r7, #4] + 800bbea: 0018 movs r0, r3 + 800bbec: f7f9 fd5a bl 80056a4 + + LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("Unsupported transport protocol %"U16_F"\n", IPH_PROTO(iphdr))); + + IP_STATS_INC(ip.proterr); + 800bbf0: 4b08 ldr r3, [pc, #32] ; (800bc14 ) + 800bbf2: 2258 movs r2, #88 ; 0x58 + 800bbf4: 5a9b ldrh r3, [r3, r2] + 800bbf6: 3301 adds r3, #1 + 800bbf8: b299 uxth r1, r3 + 800bbfa: 4b06 ldr r3, [pc, #24] ; (800bc14 ) + 800bbfc: 2258 movs r2, #88 ; 0x58 + 800bbfe: 5299 strh r1, [r3, r2] + IP_STATS_INC(ip.drop); + 800bc00: 4b04 ldr r3, [pc, #16] ; (800bc14 ) + 800bc02: 224e movs r2, #78 ; 0x4e + 800bc04: 5a9b ldrh r3, [r3, r2] + 800bc06: 3301 adds r3, #1 + 800bc08: b299 uxth r1, r3 + 800bc0a: 4b02 ldr r3, [pc, #8] ; (800bc14 ) + 800bc0c: 224e movs r2, #78 ; 0x4e + 800bc0e: 5299 strh r1, [r3, r2] + 800bc10: e00f b.n 800bc32 + 800bc12: 46c0 nop ; (mov r8, r8) + 800bc14: 20003158 .word 0x20003158 + 800bc18: 2000329c .word 0x2000329c + 800bc1c: 20003294 .word 0x20003294 + 800bc20: 2000314c .word 0x2000314c + 800bc24: 0000ff3f .word 0x0000ff3f + 800bc28: 20003298 .word 0x20003298 + 800bc2c: 200032a0 .word 0x200032a0 + snmp_inc_ipinunknownprotos(); + } + } + 800bc30: 46c0 nop ; (mov r8, r8) + + current_netif = NULL; + 800bc32: 4b08 ldr r3, [pc, #32] ; (800bc54 ) + 800bc34: 2200 movs r2, #0 + 800bc36: 601a str r2, [r3, #0] + current_header = NULL; + 800bc38: 4b07 ldr r3, [pc, #28] ; (800bc58 ) + 800bc3a: 2200 movs r2, #0 + 800bc3c: 601a str r2, [r3, #0] + ip_addr_set_any(¤t_iphdr_src); + 800bc3e: 4b07 ldr r3, [pc, #28] ; (800bc5c ) + 800bc40: 2200 movs r2, #0 + 800bc42: 601a str r2, [r3, #0] + ip_addr_set_any(¤t_iphdr_dest); + 800bc44: 4b06 ldr r3, [pc, #24] ; (800bc60 ) + 800bc46: 2200 movs r2, #0 + 800bc48: 601a str r2, [r3, #0] + + return ERR_OK; + 800bc4a: 2300 movs r3, #0 +} + 800bc4c: 0018 movs r0, r3 + 800bc4e: 46bd mov sp, r7 + 800bc50: b008 add sp, #32 + 800bc52: bdb0 pop {r4, r5, r7, pc} + 800bc54: 20003298 .word 0x20003298 + 800bc58: 200032a0 .word 0x200032a0 + 800bc5c: 20003294 .word 0x20003294 + 800bc60: 2000329c .word 0x2000329c + +0800bc64 : + */ +err_t +ip_output_if(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest, + u8_t ttl, u8_t tos, + u8_t proto, struct netif *netif) +{ + 800bc64: b590 push {r4, r7, lr} + 800bc66: b089 sub sp, #36 ; 0x24 + 800bc68: af00 add r7, sp, #0 + 800bc6a: 60f8 str r0, [r7, #12] + 800bc6c: 60b9 str r1, [r7, #8] + 800bc6e: 607a str r2, [r7, #4] + 800bc70: 001a movs r2, r3 + 800bc72: 1cfb adds r3, r7, #3 + 800bc74: 701a strb r2, [r3, #0] +{ +#endif /* IP_OPTIONS_SEND */ + struct ip_hdr *iphdr; + ip_addr_t dest_addr; +#if CHECKSUM_GEN_IP_INLINE + u32_t chk_sum = 0; + 800bc76: 2300 movs r3, #0 + 800bc78: 61fb str r3, [r7, #28] + LWIP_ASSERT("p->ref == 1", p->ref == 1); + + snmp_inc_ipoutrequests(); + + /* Should the IP header be generated or is it already included in p? */ + if (dest != IP_HDRINCL) { + 800bc7a: 687b ldr r3, [r7, #4] + 800bc7c: 2b00 cmp r3, #0 + 800bc7e: d100 bne.n 800bc82 + 800bc80: e18b b.n 800bf9a + u16_t ip_hlen = IP_HLEN; + 800bc82: 2316 movs r3, #22 + 800bc84: 18fb adds r3, r7, r3 + 800bc86: 2214 movs r2, #20 + 800bc88: 801a strh r2, [r3, #0] + } +#endif /* CHECKSUM_GEN_IP_INLINE */ + } +#endif /* IP_OPTIONS_SEND */ + /* generate IP header */ + if (pbuf_header(p, IP_HLEN)) { + 800bc8a: 68fb ldr r3, [r7, #12] + 800bc8c: 2114 movs r1, #20 + 800bc8e: 0018 movs r0, r3 + 800bc90: f7f9 fc81 bl 8005596 + 800bc94: 1e03 subs r3, r0, #0 + 800bc96: d00a beq.n 800bcae + LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip_output: not enough room for IP header in pbuf\n")); + + IP_STATS_INC(ip.err); + 800bc98: 4bdb ldr r3, [pc, #876] ; (800c008 ) + 800bc9a: 225c movs r2, #92 ; 0x5c + 800bc9c: 5a9b ldrh r3, [r3, r2] + 800bc9e: 3301 adds r3, #1 + 800bca0: b299 uxth r1, r3 + 800bca2: 4bd9 ldr r3, [pc, #868] ; (800c008 ) + 800bca4: 225c movs r2, #92 ; 0x5c + 800bca6: 5299 strh r1, [r3, r2] + snmp_inc_ipoutdiscards(); + return ERR_BUF; + 800bca8: 2302 movs r3, #2 + 800bcaa: 425b negs r3, r3 + 800bcac: e1a8 b.n 800c000 + } + + iphdr = (struct ip_hdr *)p->payload; + 800bcae: 68fb ldr r3, [r7, #12] + 800bcb0: 685b ldr r3, [r3, #4] + 800bcb2: 61bb str r3, [r7, #24] + LWIP_ASSERT("check that first pbuf can hold struct ip_hdr", + (p->len >= sizeof(struct ip_hdr))); + + IPH_TTL_SET(iphdr, ttl); + 800bcb4: 69bb ldr r3, [r7, #24] + 800bcb6: 1cfa adds r2, r7, #3 + 800bcb8: 7812 ldrb r2, [r2, #0] + 800bcba: 721a strb r2, [r3, #8] + IPH_PROTO_SET(iphdr, proto); + 800bcbc: 69bb ldr r3, [r7, #24] + 800bcbe: 2134 movs r1, #52 ; 0x34 + 800bcc0: 187a adds r2, r7, r1 + 800bcc2: 7812 ldrb r2, [r2, #0] + 800bcc4: 725a strb r2, [r3, #9] +#if CHECKSUM_GEN_IP_INLINE + chk_sum += LWIP_MAKE_U16(proto, ttl); + 800bcc6: 187b adds r3, r7, r1 + 800bcc8: 781b ldrb r3, [r3, #0] + 800bcca: 021a lsls r2, r3, #8 + 800bccc: 1cfb adds r3, r7, #3 + 800bcce: 781b ldrb r3, [r3, #0] + 800bcd0: 4313 orrs r3, r2 + 800bcd2: 001a movs r2, r3 + 800bcd4: 69fb ldr r3, [r7, #28] + 800bcd6: 189b adds r3, r3, r2 + 800bcd8: 61fb str r3, [r7, #28] +#endif /* CHECKSUM_GEN_IP_INLINE */ + + /* dest cannot be NULL here */ + ip_addr_copy(iphdr->dest, *dest); + 800bcda: 687b ldr r3, [r7, #4] + 800bcdc: 681a ldr r2, [r3, #0] + 800bcde: 69bb ldr r3, [r7, #24] + 800bce0: 21ff movs r1, #255 ; 0xff + 800bce2: 4011 ands r1, r2 + 800bce4: 000c movs r4, r1 + 800bce6: 7c19 ldrb r1, [r3, #16] + 800bce8: 2000 movs r0, #0 + 800bcea: 4001 ands r1, r0 + 800bcec: 1c08 adds r0, r1, #0 + 800bcee: 1c21 adds r1, r4, #0 + 800bcf0: 4301 orrs r1, r0 + 800bcf2: 7419 strb r1, [r3, #16] + 800bcf4: 0a11 lsrs r1, r2, #8 + 800bcf6: 20ff movs r0, #255 ; 0xff + 800bcf8: 4001 ands r1, r0 + 800bcfa: 000c movs r4, r1 + 800bcfc: 7c59 ldrb r1, [r3, #17] + 800bcfe: 2000 movs r0, #0 + 800bd00: 4001 ands r1, r0 + 800bd02: 1c08 adds r0, r1, #0 + 800bd04: 1c21 adds r1, r4, #0 + 800bd06: 4301 orrs r1, r0 + 800bd08: 7459 strb r1, [r3, #17] + 800bd0a: 0c11 lsrs r1, r2, #16 + 800bd0c: 20ff movs r0, #255 ; 0xff + 800bd0e: 4001 ands r1, r0 + 800bd10: 000c movs r4, r1 + 800bd12: 7c99 ldrb r1, [r3, #18] + 800bd14: 2000 movs r0, #0 + 800bd16: 4001 ands r1, r0 + 800bd18: 1c08 adds r0, r1, #0 + 800bd1a: 1c21 adds r1, r4, #0 + 800bd1c: 4301 orrs r1, r0 + 800bd1e: 7499 strb r1, [r3, #18] + 800bd20: 0e10 lsrs r0, r2, #24 + 800bd22: 7cda ldrb r2, [r3, #19] + 800bd24: 2100 movs r1, #0 + 800bd26: 400a ands r2, r1 + 800bd28: 1c11 adds r1, r2, #0 + 800bd2a: 1c02 adds r2, r0, #0 + 800bd2c: 430a orrs r2, r1 + 800bd2e: 74da strb r2, [r3, #19] +#if CHECKSUM_GEN_IP_INLINE + chk_sum += ip4_addr_get_u32(&iphdr->dest) & 0xFFFF; + 800bd30: 69bb ldr r3, [r7, #24] + 800bd32: 7c1a ldrb r2, [r3, #16] + 800bd34: 7c59 ldrb r1, [r3, #17] + 800bd36: 0209 lsls r1, r1, #8 + 800bd38: 430a orrs r2, r1 + 800bd3a: 7c99 ldrb r1, [r3, #18] + 800bd3c: 0409 lsls r1, r1, #16 + 800bd3e: 430a orrs r2, r1 + 800bd40: 7cdb ldrb r3, [r3, #19] + 800bd42: 061b lsls r3, r3, #24 + 800bd44: 4313 orrs r3, r2 + 800bd46: 041b lsls r3, r3, #16 + 800bd48: 0c1b lsrs r3, r3, #16 + 800bd4a: 69fa ldr r2, [r7, #28] + 800bd4c: 18d3 adds r3, r2, r3 + 800bd4e: 61fb str r3, [r7, #28] + chk_sum += ip4_addr_get_u32(&iphdr->dest) >> 16; + 800bd50: 69bb ldr r3, [r7, #24] + 800bd52: 7c1a ldrb r2, [r3, #16] + 800bd54: 7c59 ldrb r1, [r3, #17] + 800bd56: 0209 lsls r1, r1, #8 + 800bd58: 430a orrs r2, r1 + 800bd5a: 7c99 ldrb r1, [r3, #18] + 800bd5c: 0409 lsls r1, r1, #16 + 800bd5e: 430a orrs r2, r1 + 800bd60: 7cdb ldrb r3, [r3, #19] + 800bd62: 061b lsls r3, r3, #24 + 800bd64: 4313 orrs r3, r2 + 800bd66: 0c1b lsrs r3, r3, #16 + 800bd68: 69fa ldr r2, [r7, #28] + 800bd6a: 18d3 adds r3, r2, r3 + 800bd6c: 61fb str r3, [r7, #28] +#endif /* CHECKSUM_GEN_IP_INLINE */ + + IPH_VHL_SET(iphdr, 4, ip_hlen / 4); + 800bd6e: 2316 movs r3, #22 + 800bd70: 18fb adds r3, r7, r3 + 800bd72: 881b ldrh r3, [r3, #0] + 800bd74: 089b lsrs r3, r3, #2 + 800bd76: b29b uxth r3, r3 + 800bd78: b2db uxtb r3, r3 + 800bd7a: 2240 movs r2, #64 ; 0x40 + 800bd7c: 4313 orrs r3, r2 + 800bd7e: b2da uxtb r2, r3 + 800bd80: 69bb ldr r3, [r7, #24] + 800bd82: 701a strb r2, [r3, #0] + IPH_TOS_SET(iphdr, tos); + 800bd84: 69bb ldr r3, [r7, #24] + 800bd86: 2130 movs r1, #48 ; 0x30 + 800bd88: 187a adds r2, r7, r1 + 800bd8a: 7812 ldrb r2, [r2, #0] + 800bd8c: 705a strb r2, [r3, #1] +#if CHECKSUM_GEN_IP_INLINE + chk_sum += LWIP_MAKE_U16(tos, iphdr->_v_hl); + 800bd8e: 187b adds r3, r7, r1 + 800bd90: 781b ldrb r3, [r3, #0] + 800bd92: 021b lsls r3, r3, #8 + 800bd94: 69ba ldr r2, [r7, #24] + 800bd96: 7812 ldrb r2, [r2, #0] + 800bd98: 4313 orrs r3, r2 + 800bd9a: 001a movs r2, r3 + 800bd9c: 69fb ldr r3, [r7, #28] + 800bd9e: 189b adds r3, r3, r2 + 800bda0: 61fb str r3, [r7, #28] +#endif /* CHECKSUM_GEN_IP_INLINE */ + IPH_LEN_SET(iphdr, htons(p->tot_len)); + 800bda2: 68fb ldr r3, [r7, #12] + 800bda4: 891b ldrh r3, [r3, #8] + 800bda6: 0018 movs r0, r3 + 800bda8: f7f8 fc34 bl 8004614 + 800bdac: 0003 movs r3, r0 + 800bdae: 001a movs r2, r3 + 800bdb0: 69bb ldr r3, [r7, #24] + 800bdb2: 21ff movs r1, #255 ; 0xff + 800bdb4: 4011 ands r1, r2 + 800bdb6: 000c movs r4, r1 + 800bdb8: 7899 ldrb r1, [r3, #2] + 800bdba: 2000 movs r0, #0 + 800bdbc: 4001 ands r1, r0 + 800bdbe: 1c08 adds r0, r1, #0 + 800bdc0: 1c21 adds r1, r4, #0 + 800bdc2: 4301 orrs r1, r0 + 800bdc4: 7099 strb r1, [r3, #2] + 800bdc6: 0a12 lsrs r2, r2, #8 + 800bdc8: b290 uxth r0, r2 + 800bdca: 78da ldrb r2, [r3, #3] + 800bdcc: 2100 movs r1, #0 + 800bdce: 400a ands r2, r1 + 800bdd0: 1c11 adds r1, r2, #0 + 800bdd2: 1c02 adds r2, r0, #0 + 800bdd4: 430a orrs r2, r1 + 800bdd6: 70da strb r2, [r3, #3] +#if CHECKSUM_GEN_IP_INLINE + chk_sum += iphdr->_len; + 800bdd8: 69bb ldr r3, [r7, #24] + 800bdda: 789a ldrb r2, [r3, #2] + 800bddc: 78db ldrb r3, [r3, #3] + 800bdde: 021b lsls r3, r3, #8 + 800bde0: 4313 orrs r3, r2 + 800bde2: b29b uxth r3, r3 + 800bde4: 001a movs r2, r3 + 800bde6: 69fb ldr r3, [r7, #28] + 800bde8: 189b adds r3, r3, r2 + 800bdea: 61fb str r3, [r7, #28] +#endif /* CHECKSUM_GEN_IP_INLINE */ + IPH_OFFSET_SET(iphdr, 0); + 800bdec: 69bb ldr r3, [r7, #24] + 800bdee: 799a ldrb r2, [r3, #6] + 800bdf0: 2100 movs r1, #0 + 800bdf2: 400a ands r2, r1 + 800bdf4: 719a strb r2, [r3, #6] + 800bdf6: 79da ldrb r2, [r3, #7] + 800bdf8: 2100 movs r1, #0 + 800bdfa: 400a ands r2, r1 + 800bdfc: 71da strb r2, [r3, #7] + IPH_ID_SET(iphdr, htons(ip_id)); + 800bdfe: 4b83 ldr r3, [pc, #524] ; (800c00c ) + 800be00: 881b ldrh r3, [r3, #0] + 800be02: 0018 movs r0, r3 + 800be04: f7f8 fc06 bl 8004614 + 800be08: 0003 movs r3, r0 + 800be0a: 001a movs r2, r3 + 800be0c: 69bb ldr r3, [r7, #24] + 800be0e: 21ff movs r1, #255 ; 0xff + 800be10: 4011 ands r1, r2 + 800be12: 000c movs r4, r1 + 800be14: 7919 ldrb r1, [r3, #4] + 800be16: 2000 movs r0, #0 + 800be18: 4001 ands r1, r0 + 800be1a: 1c08 adds r0, r1, #0 + 800be1c: 1c21 adds r1, r4, #0 + 800be1e: 4301 orrs r1, r0 + 800be20: 7119 strb r1, [r3, #4] + 800be22: 0a12 lsrs r2, r2, #8 + 800be24: b290 uxth r0, r2 + 800be26: 795a ldrb r2, [r3, #5] + 800be28: 2100 movs r1, #0 + 800be2a: 400a ands r2, r1 + 800be2c: 1c11 adds r1, r2, #0 + 800be2e: 1c02 adds r2, r0, #0 + 800be30: 430a orrs r2, r1 + 800be32: 715a strb r2, [r3, #5] +#if CHECKSUM_GEN_IP_INLINE + chk_sum += iphdr->_id; + 800be34: 69bb ldr r3, [r7, #24] + 800be36: 791a ldrb r2, [r3, #4] + 800be38: 795b ldrb r3, [r3, #5] + 800be3a: 021b lsls r3, r3, #8 + 800be3c: 4313 orrs r3, r2 + 800be3e: b29b uxth r3, r3 + 800be40: 001a movs r2, r3 + 800be42: 69fb ldr r3, [r7, #28] + 800be44: 189b adds r3, r3, r2 + 800be46: 61fb str r3, [r7, #28] +#endif /* CHECKSUM_GEN_IP_INLINE */ + ++ip_id; + 800be48: 4b70 ldr r3, [pc, #448] ; (800c00c ) + 800be4a: 881b ldrh r3, [r3, #0] + 800be4c: 3301 adds r3, #1 + 800be4e: b29a uxth r2, r3 + 800be50: 4b6e ldr r3, [pc, #440] ; (800c00c ) + 800be52: 801a strh r2, [r3, #0] + + if (ip_addr_isany(src)) { + 800be54: 68bb ldr r3, [r7, #8] + 800be56: 2b00 cmp r3, #0 + 800be58: d003 beq.n 800be62 + 800be5a: 68bb ldr r3, [r7, #8] + 800be5c: 681b ldr r3, [r3, #0] + 800be5e: 2b00 cmp r3, #0 + 800be60: d12b bne.n 800beba + ip_addr_copy(iphdr->src, netif->ip_addr); + 800be62: 6bbb ldr r3, [r7, #56] ; 0x38 + 800be64: 685a ldr r2, [r3, #4] + 800be66: 69bb ldr r3, [r7, #24] + 800be68: 21ff movs r1, #255 ; 0xff + 800be6a: 4011 ands r1, r2 + 800be6c: 000c movs r4, r1 + 800be6e: 7b19 ldrb r1, [r3, #12] + 800be70: 2000 movs r0, #0 + 800be72: 4001 ands r1, r0 + 800be74: 1c08 adds r0, r1, #0 + 800be76: 1c21 adds r1, r4, #0 + 800be78: 4301 orrs r1, r0 + 800be7a: 7319 strb r1, [r3, #12] + 800be7c: 0a11 lsrs r1, r2, #8 + 800be7e: 20ff movs r0, #255 ; 0xff + 800be80: 4001 ands r1, r0 + 800be82: 000c movs r4, r1 + 800be84: 7b59 ldrb r1, [r3, #13] + 800be86: 2000 movs r0, #0 + 800be88: 4001 ands r1, r0 + 800be8a: 1c08 adds r0, r1, #0 + 800be8c: 1c21 adds r1, r4, #0 + 800be8e: 4301 orrs r1, r0 + 800be90: 7359 strb r1, [r3, #13] + 800be92: 0c11 lsrs r1, r2, #16 + 800be94: 20ff movs r0, #255 ; 0xff + 800be96: 4001 ands r1, r0 + 800be98: 000c movs r4, r1 + 800be9a: 7b99 ldrb r1, [r3, #14] + 800be9c: 2000 movs r0, #0 + 800be9e: 4001 ands r1, r0 + 800bea0: 1c08 adds r0, r1, #0 + 800bea2: 1c21 adds r1, r4, #0 + 800bea4: 4301 orrs r1, r0 + 800bea6: 7399 strb r1, [r3, #14] + 800bea8: 0e10 lsrs r0, r2, #24 + 800beaa: 7bda ldrb r2, [r3, #15] + 800beac: 2100 movs r1, #0 + 800beae: 400a ands r2, r1 + 800beb0: 1c11 adds r1, r2, #0 + 800beb2: 1c02 adds r2, r0, #0 + 800beb4: 430a orrs r2, r1 + 800beb6: 73da strb r2, [r3, #15] + 800beb8: e02a b.n 800bf10 + } else { + /* src cannot be NULL here */ + ip_addr_copy(iphdr->src, *src); + 800beba: 68bb ldr r3, [r7, #8] + 800bebc: 681a ldr r2, [r3, #0] + 800bebe: 69bb ldr r3, [r7, #24] + 800bec0: 21ff movs r1, #255 ; 0xff + 800bec2: 4011 ands r1, r2 + 800bec4: 000c movs r4, r1 + 800bec6: 7b19 ldrb r1, [r3, #12] + 800bec8: 2000 movs r0, #0 + 800beca: 4001 ands r1, r0 + 800becc: 1c08 adds r0, r1, #0 + 800bece: 1c21 adds r1, r4, #0 + 800bed0: 4301 orrs r1, r0 + 800bed2: 7319 strb r1, [r3, #12] + 800bed4: 0a11 lsrs r1, r2, #8 + 800bed6: 20ff movs r0, #255 ; 0xff + 800bed8: 4001 ands r1, r0 + 800beda: 000c movs r4, r1 + 800bedc: 7b59 ldrb r1, [r3, #13] + 800bede: 2000 movs r0, #0 + 800bee0: 4001 ands r1, r0 + 800bee2: 1c08 adds r0, r1, #0 + 800bee4: 1c21 adds r1, r4, #0 + 800bee6: 4301 orrs r1, r0 + 800bee8: 7359 strb r1, [r3, #13] + 800beea: 0c11 lsrs r1, r2, #16 + 800beec: 20ff movs r0, #255 ; 0xff + 800beee: 4001 ands r1, r0 + 800bef0: 000c movs r4, r1 + 800bef2: 7b99 ldrb r1, [r3, #14] + 800bef4: 2000 movs r0, #0 + 800bef6: 4001 ands r1, r0 + 800bef8: 1c08 adds r0, r1, #0 + 800befa: 1c21 adds r1, r4, #0 + 800befc: 4301 orrs r1, r0 + 800befe: 7399 strb r1, [r3, #14] + 800bf00: 0e10 lsrs r0, r2, #24 + 800bf02: 7bda ldrb r2, [r3, #15] + 800bf04: 2100 movs r1, #0 + 800bf06: 400a ands r2, r1 + 800bf08: 1c11 adds r1, r2, #0 + 800bf0a: 1c02 adds r2, r0, #0 + 800bf0c: 430a orrs r2, r1 + 800bf0e: 73da strb r2, [r3, #15] + } + +#if CHECKSUM_GEN_IP_INLINE + chk_sum += ip4_addr_get_u32(&iphdr->src) & 0xFFFF; + 800bf10: 69bb ldr r3, [r7, #24] + 800bf12: 7b1a ldrb r2, [r3, #12] + 800bf14: 7b59 ldrb r1, [r3, #13] + 800bf16: 0209 lsls r1, r1, #8 + 800bf18: 430a orrs r2, r1 + 800bf1a: 7b99 ldrb r1, [r3, #14] + 800bf1c: 0409 lsls r1, r1, #16 + 800bf1e: 430a orrs r2, r1 + 800bf20: 7bdb ldrb r3, [r3, #15] + 800bf22: 061b lsls r3, r3, #24 + 800bf24: 4313 orrs r3, r2 + 800bf26: 041b lsls r3, r3, #16 + 800bf28: 0c1b lsrs r3, r3, #16 + 800bf2a: 69fa ldr r2, [r7, #28] + 800bf2c: 18d3 adds r3, r2, r3 + 800bf2e: 61fb str r3, [r7, #28] + chk_sum += ip4_addr_get_u32(&iphdr->src) >> 16; + 800bf30: 69bb ldr r3, [r7, #24] + 800bf32: 7b1a ldrb r2, [r3, #12] + 800bf34: 7b59 ldrb r1, [r3, #13] + 800bf36: 0209 lsls r1, r1, #8 + 800bf38: 430a orrs r2, r1 + 800bf3a: 7b99 ldrb r1, [r3, #14] + 800bf3c: 0409 lsls r1, r1, #16 + 800bf3e: 430a orrs r2, r1 + 800bf40: 7bdb ldrb r3, [r3, #15] + 800bf42: 061b lsls r3, r3, #24 + 800bf44: 4313 orrs r3, r2 + 800bf46: 0c1b lsrs r3, r3, #16 + 800bf48: 69fa ldr r2, [r7, #28] + 800bf4a: 18d3 adds r3, r2, r3 + 800bf4c: 61fb str r3, [r7, #28] + chk_sum = (chk_sum >> 16) + (chk_sum & 0xFFFF); + 800bf4e: 69fb ldr r3, [r7, #28] + 800bf50: 0c1a lsrs r2, r3, #16 + 800bf52: 69fb ldr r3, [r7, #28] + 800bf54: 041b lsls r3, r3, #16 + 800bf56: 0c1b lsrs r3, r3, #16 + 800bf58: 18d3 adds r3, r2, r3 + 800bf5a: 61fb str r3, [r7, #28] + chk_sum = (chk_sum >> 16) + chk_sum; + 800bf5c: 69fb ldr r3, [r7, #28] + 800bf5e: 0c1b lsrs r3, r3, #16 + 800bf60: 69fa ldr r2, [r7, #28] + 800bf62: 18d3 adds r3, r2, r3 + 800bf64: 61fb str r3, [r7, #28] + chk_sum = ~chk_sum; + 800bf66: 69fb ldr r3, [r7, #28] + 800bf68: 43db mvns r3, r3 + 800bf6a: 61fb str r3, [r7, #28] + iphdr->_chksum = chk_sum; /* network order */ + 800bf6c: 69fb ldr r3, [r7, #28] + 800bf6e: b29a uxth r2, r3 + 800bf70: 69bb ldr r3, [r7, #24] + 800bf72: 21ff movs r1, #255 ; 0xff + 800bf74: 4011 ands r1, r2 + 800bf76: 000c movs r4, r1 + 800bf78: 7a99 ldrb r1, [r3, #10] + 800bf7a: 2000 movs r0, #0 + 800bf7c: 4001 ands r1, r0 + 800bf7e: 1c08 adds r0, r1, #0 + 800bf80: 1c21 adds r1, r4, #0 + 800bf82: 4301 orrs r1, r0 + 800bf84: 7299 strb r1, [r3, #10] + 800bf86: 0a12 lsrs r2, r2, #8 + 800bf88: b290 uxth r0, r2 + 800bf8a: 7ada ldrb r2, [r3, #11] + 800bf8c: 2100 movs r1, #0 + 800bf8e: 400a ands r2, r1 + 800bf90: 1c11 adds r1, r2, #0 + 800bf92: 1c02 adds r2, r0, #0 + 800bf94: 430a orrs r2, r1 + 800bf96: 72da strb r2, [r3, #11] + 800bf98: e011 b.n 800bfbe + IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, ip_hlen)); +#endif +#endif /* CHECKSUM_GEN_IP_INLINE */ + } else { + /* IP header already included in p */ + iphdr = (struct ip_hdr *)p->payload; + 800bf9a: 68fb ldr r3, [r7, #12] + 800bf9c: 685b ldr r3, [r3, #4] + 800bf9e: 61bb str r3, [r7, #24] + ip_addr_copy(dest_addr, iphdr->dest); + 800bfa0: 69bb ldr r3, [r7, #24] + 800bfa2: 7c1a ldrb r2, [r3, #16] + 800bfa4: 7c59 ldrb r1, [r3, #17] + 800bfa6: 0209 lsls r1, r1, #8 + 800bfa8: 430a orrs r2, r1 + 800bfaa: 7c99 ldrb r1, [r3, #18] + 800bfac: 0409 lsls r1, r1, #16 + 800bfae: 430a orrs r2, r1 + 800bfb0: 7cdb ldrb r3, [r3, #19] + 800bfb2: 061b lsls r3, r3, #24 + 800bfb4: 4313 orrs r3, r2 + 800bfb6: 613b str r3, [r7, #16] + dest = &dest_addr; + 800bfb8: 2310 movs r3, #16 + 800bfba: 18fb adds r3, r7, r3 + 800bfbc: 607b str r3, [r7, #4] + } + + IP_STATS_INC(ip.xmit); + 800bfbe: 4b12 ldr r3, [pc, #72] ; (800c008 ) + 800bfc0: 2248 movs r2, #72 ; 0x48 + 800bfc2: 5a9b ldrh r3, [r3, r2] + 800bfc4: 3301 adds r3, #1 + 800bfc6: b299 uxth r1, r3 + 800bfc8: 4b0f ldr r3, [pc, #60] ; (800c008 ) + 800bfca: 2248 movs r2, #72 ; 0x48 + 800bfcc: 5299 strh r1, [r3, r2] + } +#endif /* LWIP_IGMP */ +#endif /* ENABLE_LOOPBACK */ +#if IP_FRAG + /* don't fragment if interface has mtu set to 0 [loopif] */ + if (netif->mtu && (p->tot_len > netif->mtu)) { + 800bfce: 6bbb ldr r3, [r7, #56] ; 0x38 + 800bfd0: 8c1b ldrh r3, [r3, #32] + 800bfd2: 2b00 cmp r3, #0 + 800bfd4: d00d beq.n 800bff2 + 800bfd6: 68fb ldr r3, [r7, #12] + 800bfd8: 891a ldrh r2, [r3, #8] + 800bfda: 6bbb ldr r3, [r7, #56] ; 0x38 + 800bfdc: 8c1b ldrh r3, [r3, #32] + 800bfde: 429a cmp r2, r3 + 800bfe0: d907 bls.n 800bff2 + return ip_frag(p, netif, dest); + 800bfe2: 687a ldr r2, [r7, #4] + 800bfe4: 6bb9 ldr r1, [r7, #56] ; 0x38 + 800bfe6: 68fb ldr r3, [r7, #12] + 800bfe8: 0018 movs r0, r3 + 800bfea: f000 fdf5 bl 800cbd8 + 800bfee: 0003 movs r3, r0 + 800bff0: e006 b.n 800c000 + } +#endif /* IP_FRAG */ + + LWIP_DEBUGF(IP_DEBUG, ("netif->output()")); + return netif->output(netif, p, dest); + 800bff2: 6bbb ldr r3, [r7, #56] ; 0x38 + 800bff4: 695b ldr r3, [r3, #20] + 800bff6: 687a ldr r2, [r7, #4] + 800bff8: 68f9 ldr r1, [r7, #12] + 800bffa: 6bb8 ldr r0, [r7, #56] ; 0x38 + 800bffc: 4798 blx r3 + 800bffe: 0003 movs r3, r0 +} + 800c000: 0018 movs r0, r3 + 800c002: 46bd mov sp, r7 + 800c004: b009 add sp, #36 ; 0x24 + 800c006: bd90 pop {r4, r7, pc} + 800c008: 20003158 .word 0x20003158 + 800c00c: 200022b4 .word 0x200022b4 + +0800c010 : + * see ip_output_if() for more return values + */ +err_t +ip_output(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest, + u8_t ttl, u8_t tos, u8_t proto) +{ + 800c010: b590 push {r4, r7, lr} + 800c012: b08b sub sp, #44 ; 0x2c + 800c014: af04 add r7, sp, #16 + 800c016: 60f8 str r0, [r7, #12] + 800c018: 60b9 str r1, [r7, #8] + 800c01a: 607a str r2, [r7, #4] + 800c01c: 001a movs r2, r3 + 800c01e: 1cfb adds r3, r7, #3 + 800c020: 701a strb r2, [r3, #0] + + /* pbufs passed to IP must have a ref-count of 1 as their payload pointer + gets altered as the packet is passed down the stack */ + LWIP_ASSERT("p->ref == 1", p->ref == 1); + + if ((netif = ip_route(dest)) == NULL) { + 800c022: 687b ldr r3, [r7, #4] + 800c024: 0018 movs r0, r3 + 800c026: f7ff fc0f bl 800b848 + 800c02a: 0003 movs r3, r0 + 800c02c: 617b str r3, [r7, #20] + 800c02e: 697b ldr r3, [r7, #20] + 800c030: 2b00 cmp r3, #0 + 800c032: d10a bne.n 800c04a + LWIP_DEBUGF(IP_DEBUG, ("ip_output: No route to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", + ip4_addr1_16(dest), ip4_addr2_16(dest), ip4_addr3_16(dest), ip4_addr4_16(dest))); + IP_STATS_INC(ip.rterr); + 800c034: 4b10 ldr r3, [pc, #64] ; (800c078 ) + 800c036: 2256 movs r2, #86 ; 0x56 + 800c038: 5a9b ldrh r3, [r3, r2] + 800c03a: 3301 adds r3, #1 + 800c03c: b299 uxth r1, r3 + 800c03e: 4b0e ldr r3, [pc, #56] ; (800c078 ) + 800c040: 2256 movs r2, #86 ; 0x56 + 800c042: 5299 strh r1, [r3, r2] + return ERR_RTE; + 800c044: 2304 movs r3, #4 + 800c046: 425b negs r3, r3 + 800c048: e012 b.n 800c070 + } + + return ip_output_if(p, src, dest, ttl, tos, proto, netif); + 800c04a: 1cfb adds r3, r7, #3 + 800c04c: 781c ldrb r4, [r3, #0] + 800c04e: 687a ldr r2, [r7, #4] + 800c050: 68b9 ldr r1, [r7, #8] + 800c052: 68f8 ldr r0, [r7, #12] + 800c054: 697b ldr r3, [r7, #20] + 800c056: 9302 str r3, [sp, #8] + 800c058: 232c movs r3, #44 ; 0x2c + 800c05a: 18fb adds r3, r7, r3 + 800c05c: 781b ldrb r3, [r3, #0] + 800c05e: 9301 str r3, [sp, #4] + 800c060: 2328 movs r3, #40 ; 0x28 + 800c062: 18fb adds r3, r7, r3 + 800c064: 781b ldrb r3, [r3, #0] + 800c066: 9300 str r3, [sp, #0] + 800c068: 0023 movs r3, r4 + 800c06a: f7ff fdfb bl 800bc64 + 800c06e: 0003 movs r3, r0 +} + 800c070: 0018 movs r0, r3 + 800c072: 46bd mov sp, r7 + 800c074: b007 add sp, #28 + 800c076: bd90 pop {r4, r7, pc} + 800c078: 20003158 .word 0x20003158 + +0800c07c : + * @param netif the network interface against which the address is checked + * @return returns non-zero if the address is a broadcast address + */ +u8_t +ip4_addr_isbroadcast(u32_t addr, const struct netif *netif) +{ + 800c07c: b580 push {r7, lr} + 800c07e: b084 sub sp, #16 + 800c080: af00 add r7, sp, #0 + 800c082: 6078 str r0, [r7, #4] + 800c084: 6039 str r1, [r7, #0] + ip_addr_t ipaddr; + ip4_addr_set_u32(&ipaddr, addr); + 800c086: 687b ldr r3, [r7, #4] + 800c088: 60fb str r3, [r7, #12] + + /* all ones (broadcast) or all zeroes (old skool broadcast) */ + if ((~addr == IPADDR_ANY) || + 800c08a: 687b ldr r3, [r7, #4] + 800c08c: 3301 adds r3, #1 + 800c08e: d002 beq.n 800c096 + 800c090: 687b ldr r3, [r7, #4] + 800c092: 2b00 cmp r3, #0 + 800c094: d101 bne.n 800c09a + (addr == IPADDR_ANY)) { + return 1; + 800c096: 2301 movs r3, #1 + 800c098: e024 b.n 800c0e4 + /* no broadcast support on this network interface? */ + } else if ((netif->flags & NETIF_FLAG_BROADCAST) == 0) { + 800c09a: 683b ldr r3, [r7, #0] + 800c09c: 2229 movs r2, #41 ; 0x29 + 800c09e: 5c9b ldrb r3, [r3, r2] + 800c0a0: 001a movs r2, r3 + 800c0a2: 2302 movs r3, #2 + 800c0a4: 4013 ands r3, r2 + 800c0a6: d101 bne.n 800c0ac + /* the given address cannot be a broadcast address + * nor can we check against any broadcast addresses */ + return 0; + 800c0a8: 2300 movs r3, #0 + 800c0aa: e01b b.n 800c0e4 + /* address matches network interface address exactly? => no broadcast */ + } else if (addr == ip4_addr_get_u32(&netif->ip_addr)) { + 800c0ac: 683b ldr r3, [r7, #0] + 800c0ae: 685b ldr r3, [r3, #4] + 800c0b0: 687a ldr r2, [r7, #4] + 800c0b2: 429a cmp r2, r3 + 800c0b4: d101 bne.n 800c0ba + return 0; + 800c0b6: 2300 movs r3, #0 + 800c0b8: e014 b.n 800c0e4 + /* on the same (sub) network... */ + } else if (ip_addr_netcmp(&ipaddr, &(netif->ip_addr), &(netif->netmask)) + 800c0ba: 68fa ldr r2, [r7, #12] + 800c0bc: 683b ldr r3, [r7, #0] + 800c0be: 685b ldr r3, [r3, #4] + 800c0c0: 405a eors r2, r3 + 800c0c2: 683b ldr r3, [r7, #0] + 800c0c4: 689b ldr r3, [r3, #8] + 800c0c6: 4013 ands r3, r2 + 800c0c8: d10b bne.n 800c0e2 + /* ...and host identifier bits are all ones? =>... */ + && ((addr & ~ip4_addr_get_u32(&netif->netmask)) == + 800c0ca: 683b ldr r3, [r7, #0] + 800c0cc: 689b ldr r3, [r3, #8] + 800c0ce: 43db mvns r3, r3 + 800c0d0: 687a ldr r2, [r7, #4] + 800c0d2: 401a ands r2, r3 + (IPADDR_BROADCAST & ~ip4_addr_get_u32(&netif->netmask)))) { + 800c0d4: 683b ldr r3, [r7, #0] + 800c0d6: 689b ldr r3, [r3, #8] + 800c0d8: 43db mvns r3, r3 + && ((addr & ~ip4_addr_get_u32(&netif->netmask)) == + 800c0da: 429a cmp r2, r3 + 800c0dc: d101 bne.n 800c0e2 + /* => network broadcast address */ + return 1; + 800c0de: 2301 movs r3, #1 + 800c0e0: e000 b.n 800c0e4 + } else { + return 0; + 800c0e2: 2300 movs r3, #0 + } +} + 800c0e4: 0018 movs r0, r3 + 800c0e6: 46bd mov sp, r7 + 800c0e8: b004 add sp, #16 + 800c0ea: bd80 pop {r7, pc} + +0800c0ec : + * + * Should be called every 1000 msec (defined by IP_TMR_INTERVAL). + */ +void +ip_reass_tmr(void) +{ + 800c0ec: b580 push {r7, lr} + 800c0ee: b084 sub sp, #16 + 800c0f0: af00 add r7, sp, #0 + struct ip_reassdata *r, *prev = NULL; + 800c0f2: 2300 movs r3, #0 + 800c0f4: 60bb str r3, [r7, #8] + + r = reassdatagrams; + 800c0f6: 4b13 ldr r3, [pc, #76] ; (800c144 ) + 800c0f8: 681b ldr r3, [r3, #0] + 800c0fa: 60fb str r3, [r7, #12] + while (r != NULL) { + 800c0fc: e01a b.n 800c134 + /* Decrement the timer. Once it reaches 0, + * clean up the incomplete fragment assembly */ + if (r->timer > 0) { + 800c0fe: 68fb ldr r3, [r7, #12] + 800c100: 7fdb ldrb r3, [r3, #31] + 800c102: 2b00 cmp r3, #0 + 800c104: d00b beq.n 800c11e + r->timer--; + 800c106: 68fb ldr r3, [r7, #12] + 800c108: 7fdb ldrb r3, [r3, #31] + 800c10a: 3b01 subs r3, #1 + 800c10c: b2da uxtb r2, r3 + 800c10e: 68fb ldr r3, [r7, #12] + 800c110: 77da strb r2, [r3, #31] + LWIP_DEBUGF(IP_REASS_DEBUG, ("ip_reass_tmr: timer dec %"U16_F"\n",(u16_t)r->timer)); + prev = r; + 800c112: 68fb ldr r3, [r7, #12] + 800c114: 60bb str r3, [r7, #8] + r = r->next; + 800c116: 68fb ldr r3, [r7, #12] + 800c118: 681b ldr r3, [r3, #0] + 800c11a: 60fb str r3, [r7, #12] + 800c11c: e00a b.n 800c134 + } else { + /* reassembly timed out */ + struct ip_reassdata *tmp; + LWIP_DEBUGF(IP_REASS_DEBUG, ("ip_reass_tmr: timer timed out\n")); + tmp = r; + 800c11e: 68fb ldr r3, [r7, #12] + 800c120: 607b str r3, [r7, #4] + /* get the next pointer before freeing */ + r = r->next; + 800c122: 68fb ldr r3, [r7, #12] + 800c124: 681b ldr r3, [r3, #0] + 800c126: 60fb str r3, [r7, #12] + /* free the helper struct and all enqueued pbufs */ + ip_reass_free_complete_datagram(tmp, prev); + 800c128: 68ba ldr r2, [r7, #8] + 800c12a: 687b ldr r3, [r7, #4] + 800c12c: 0011 movs r1, r2 + 800c12e: 0018 movs r0, r3 + 800c130: f000 f80a bl 800c148 + while (r != NULL) { + 800c134: 68fb ldr r3, [r7, #12] + 800c136: 2b00 cmp r3, #0 + 800c138: d1e1 bne.n 800c0fe + } + } +} + 800c13a: 46c0 nop ; (mov r8, r8) + 800c13c: 46bd mov sp, r7 + 800c13e: b004 add sp, #16 + 800c140: bd80 pop {r7, pc} + 800c142: 46c0 nop ; (mov r8, r8) + 800c144: 200022b8 .word 0x200022b8 + +0800c148 : + * @param prev the previous datagram in the linked list + * @return the number of pbufs freed + */ +static int +ip_reass_free_complete_datagram(struct ip_reassdata *ipr, struct ip_reassdata *prev) +{ + 800c148: b5b0 push {r4, r5, r7, lr} + 800c14a: b088 sub sp, #32 + 800c14c: af00 add r7, sp, #0 + 800c14e: 6078 str r0, [r7, #4] + 800c150: 6039 str r1, [r7, #0] + u16_t pbufs_freed = 0; + 800c152: 231e movs r3, #30 + 800c154: 18fb adds r3, r7, r3 + 800c156: 2200 movs r2, #0 + 800c158: 801a strh r2, [r3, #0] + LWIP_ASSERT("prev->next == ipr", prev->next == ipr); + } + + snmp_inc_ipreasmfails(); +#if LWIP_ICMP + iprh = (struct ip_reass_helper *)ipr->p->payload; + 800c15a: 687b ldr r3, [r7, #4] + 800c15c: 685b ldr r3, [r3, #4] + 800c15e: 685b ldr r3, [r3, #4] + 800c160: 617b str r3, [r7, #20] + if (iprh->start == 0) { + 800c162: 697b ldr r3, [r7, #20] + 800c164: 791a ldrb r2, [r3, #4] + 800c166: 795b ldrb r3, [r3, #5] + 800c168: 021b lsls r3, r3, #8 + 800c16a: 4313 orrs r3, r2 + 800c16c: b29b uxth r3, r3 + 800c16e: 2b00 cmp r3, #0 + 800c170: d132 bne.n 800c1d8 + /* The first fragment was received, send ICMP time exceeded. */ + /* First, de-queue the first pbuf from r->p. */ + p = ipr->p; + 800c172: 687b ldr r3, [r7, #4] + 800c174: 685b ldr r3, [r3, #4] + 800c176: 61bb str r3, [r7, #24] + ipr->p = iprh->next_pbuf; + 800c178: 697b ldr r3, [r7, #20] + 800c17a: 781a ldrb r2, [r3, #0] + 800c17c: 7859 ldrb r1, [r3, #1] + 800c17e: 0209 lsls r1, r1, #8 + 800c180: 430a orrs r2, r1 + 800c182: 7899 ldrb r1, [r3, #2] + 800c184: 0409 lsls r1, r1, #16 + 800c186: 430a orrs r2, r1 + 800c188: 78db ldrb r3, [r3, #3] + 800c18a: 061b lsls r3, r3, #24 + 800c18c: 4313 orrs r3, r2 + 800c18e: 001a movs r2, r3 + 800c190: 687b ldr r3, [r7, #4] + 800c192: 605a str r2, [r3, #4] + /* Then, copy the original header into it. */ + SMEMCPY(p->payload, &ipr->iphdr, IP_HLEN); + 800c194: 69bb ldr r3, [r7, #24] + 800c196: 6858 ldr r0, [r3, #4] + 800c198: 687b ldr r3, [r7, #4] + 800c19a: 3308 adds r3, #8 + 800c19c: 2214 movs r2, #20 + 800c19e: 0019 movs r1, r3 + 800c1a0: f003 fd7f bl 800fca2 + icmp_time_exceeded(p, ICMP_TE_FRAG); + 800c1a4: 69bb ldr r3, [r7, #24] + 800c1a6: 2101 movs r1, #1 + 800c1a8: 0018 movs r0, r3 + 800c1aa: f7ff f941 bl 800b430 + clen = pbuf_clen(p); + 800c1ae: 2513 movs r5, #19 + 800c1b0: 197c adds r4, r7, r5 + 800c1b2: 69bb ldr r3, [r7, #24] + 800c1b4: 0018 movs r0, r3 + 800c1b6: f7f9 fae7 bl 8005788 + 800c1ba: 0003 movs r3, r0 + 800c1bc: 7023 strb r3, [r4, #0] + LWIP_ASSERT("pbufs_freed + clen <= 0xffff", pbufs_freed + clen <= 0xffff); + pbufs_freed += clen; + 800c1be: 197b adds r3, r7, r5 + 800c1c0: 781b ldrb r3, [r3, #0] + 800c1c2: b299 uxth r1, r3 + 800c1c4: 221e movs r2, #30 + 800c1c6: 18bb adds r3, r7, r2 + 800c1c8: 18ba adds r2, r7, r2 + 800c1ca: 8812 ldrh r2, [r2, #0] + 800c1cc: 188a adds r2, r1, r2 + 800c1ce: 801a strh r2, [r3, #0] + pbuf_free(p); + 800c1d0: 69bb ldr r3, [r7, #24] + 800c1d2: 0018 movs r0, r3 + 800c1d4: f7f9 fa66 bl 80056a4 + } +#endif /* LWIP_ICMP */ + + /* First, free all received pbufs. The individual pbufs need to be released + separately as they have not yet been chained */ + p = ipr->p; + 800c1d8: 687b ldr r3, [r7, #4] + 800c1da: 685b ldr r3, [r3, #4] + 800c1dc: 61bb str r3, [r7, #24] + while (p != NULL) { + 800c1de: e026 b.n 800c22e + struct pbuf *pcur; + iprh = (struct ip_reass_helper *)p->payload; + 800c1e0: 69bb ldr r3, [r7, #24] + 800c1e2: 685b ldr r3, [r3, #4] + 800c1e4: 617b str r3, [r7, #20] + pcur = p; + 800c1e6: 69bb ldr r3, [r7, #24] + 800c1e8: 60fb str r3, [r7, #12] + /* get the next pointer before freeing */ + p = iprh->next_pbuf; + 800c1ea: 697b ldr r3, [r7, #20] + 800c1ec: 781a ldrb r2, [r3, #0] + 800c1ee: 7859 ldrb r1, [r3, #1] + 800c1f0: 0209 lsls r1, r1, #8 + 800c1f2: 430a orrs r2, r1 + 800c1f4: 7899 ldrb r1, [r3, #2] + 800c1f6: 0409 lsls r1, r1, #16 + 800c1f8: 430a orrs r2, r1 + 800c1fa: 78db ldrb r3, [r3, #3] + 800c1fc: 061b lsls r3, r3, #24 + 800c1fe: 4313 orrs r3, r2 + 800c200: 61bb str r3, [r7, #24] + clen = pbuf_clen(pcur); + 800c202: 2313 movs r3, #19 + 800c204: 18fc adds r4, r7, r3 + 800c206: 68fb ldr r3, [r7, #12] + 800c208: 0018 movs r0, r3 + 800c20a: f7f9 fabd bl 8005788 + 800c20e: 0003 movs r3, r0 + 800c210: 7023 strb r3, [r4, #0] + LWIP_ASSERT("pbufs_freed + clen <= 0xffff", pbufs_freed + clen <= 0xffff); + pbufs_freed += clen; + 800c212: 2313 movs r3, #19 + 800c214: 18fb adds r3, r7, r3 + 800c216: 781b ldrb r3, [r3, #0] + 800c218: b299 uxth r1, r3 + 800c21a: 221e movs r2, #30 + 800c21c: 18bb adds r3, r7, r2 + 800c21e: 18ba adds r2, r7, r2 + 800c220: 8812 ldrh r2, [r2, #0] + 800c222: 188a adds r2, r1, r2 + 800c224: 801a strh r2, [r3, #0] + pbuf_free(pcur); + 800c226: 68fb ldr r3, [r7, #12] + 800c228: 0018 movs r0, r3 + 800c22a: f7f9 fa3b bl 80056a4 + while (p != NULL) { + 800c22e: 69bb ldr r3, [r7, #24] + 800c230: 2b00 cmp r3, #0 + 800c232: d1d5 bne.n 800c1e0 + } + /* Then, unchain the struct ip_reassdata from the list and free it. */ + ip_reass_dequeue_datagram(ipr, prev); + 800c234: 683a ldr r2, [r7, #0] + 800c236: 687b ldr r3, [r7, #4] + 800c238: 0011 movs r1, r2 + 800c23a: 0018 movs r0, r3 + 800c23c: f000 f8ce bl 800c3dc + LWIP_ASSERT("ip_reass_pbufcount >= clen", ip_reass_pbufcount >= pbufs_freed); + ip_reass_pbufcount -= pbufs_freed; + 800c240: 4b07 ldr r3, [pc, #28] ; (800c260 ) + 800c242: 881a ldrh r2, [r3, #0] + 800c244: 211e movs r1, #30 + 800c246: 187b adds r3, r7, r1 + 800c248: 881b ldrh r3, [r3, #0] + 800c24a: 1ad3 subs r3, r2, r3 + 800c24c: b29a uxth r2, r3 + 800c24e: 4b04 ldr r3, [pc, #16] ; (800c260 ) + 800c250: 801a strh r2, [r3, #0] + + return pbufs_freed; + 800c252: 187b adds r3, r7, r1 + 800c254: 881b ldrh r3, [r3, #0] +} + 800c256: 0018 movs r0, r3 + 800c258: 46bd mov sp, r7 + 800c25a: b008 add sp, #32 + 800c25c: bdb0 pop {r4, r5, r7, pc} + 800c25e: 46c0 nop ; (mov r8, r8) + 800c260: 200022bc .word 0x200022bc + +0800c264 : + * (used for freeing other datagrams if not enough space) + * @return the number of pbufs freed + */ +static int +ip_reass_remove_oldest_datagram(struct ip_hdr *fraghdr, int pbufs_needed) +{ + 800c264: b580 push {r7, lr} + 800c266: b088 sub sp, #32 + 800c268: af00 add r7, sp, #0 + 800c26a: 6078 str r0, [r7, #4] + 800c26c: 6039 str r1, [r7, #0] + /* @todo Can't we simply remove the last datagram in the + * linked list behind reassdatagrams? + */ + struct ip_reassdata *r, *oldest, *prev; + int pbufs_freed = 0, pbufs_freed_current; + 800c26e: 2300 movs r3, #0 + 800c270: 613b str r3, [r7, #16] + int other_datagrams; + + /* Free datagrams until being allowed to enqueue 'pbufs_needed' pbufs, + * but don't free the datagram that 'fraghdr' belongs to! */ + do { + oldest = NULL; + 800c272: 2300 movs r3, #0 + 800c274: 61bb str r3, [r7, #24] + prev = NULL; + 800c276: 2300 movs r3, #0 + 800c278: 617b str r3, [r7, #20] + other_datagrams = 0; + 800c27a: 2300 movs r3, #0 + 800c27c: 60fb str r3, [r7, #12] + r = reassdatagrams; + 800c27e: 4b32 ldr r3, [pc, #200] ; (800c348 ) + 800c280: 681b ldr r3, [r3, #0] + 800c282: 61fb str r3, [r7, #28] + while (r != NULL) { + 800c284: e041 b.n 800c30a + if (!IP_ADDRESSES_AND_ID_MATCH(&r->iphdr, fraghdr)) { + 800c286: 69fb ldr r3, [r7, #28] + 800c288: 695a ldr r2, [r3, #20] + 800c28a: 687b ldr r3, [r7, #4] + 800c28c: 7b19 ldrb r1, [r3, #12] + 800c28e: 7b58 ldrb r0, [r3, #13] + 800c290: 0200 lsls r0, r0, #8 + 800c292: 4301 orrs r1, r0 + 800c294: 7b98 ldrb r0, [r3, #14] + 800c296: 0400 lsls r0, r0, #16 + 800c298: 4301 orrs r1, r0 + 800c29a: 7bdb ldrb r3, [r3, #15] + 800c29c: 061b lsls r3, r3, #24 + 800c29e: 430b orrs r3, r1 + 800c2a0: 429a cmp r2, r3 + 800c2a2: d118 bne.n 800c2d6 + 800c2a4: 69fb ldr r3, [r7, #28] + 800c2a6: 699a ldr r2, [r3, #24] + 800c2a8: 687b ldr r3, [r7, #4] + 800c2aa: 7c19 ldrb r1, [r3, #16] + 800c2ac: 7c58 ldrb r0, [r3, #17] + 800c2ae: 0200 lsls r0, r0, #8 + 800c2b0: 4301 orrs r1, r0 + 800c2b2: 7c98 ldrb r0, [r3, #18] + 800c2b4: 0400 lsls r0, r0, #16 + 800c2b6: 4301 orrs r1, r0 + 800c2b8: 7cdb ldrb r3, [r3, #19] + 800c2ba: 061b lsls r3, r3, #24 + 800c2bc: 430b orrs r3, r1 + 800c2be: 429a cmp r2, r3 + 800c2c0: d109 bne.n 800c2d6 + 800c2c2: 69fb ldr r3, [r7, #28] + 800c2c4: 899a ldrh r2, [r3, #12] + 800c2c6: 687b ldr r3, [r7, #4] + 800c2c8: 7919 ldrb r1, [r3, #4] + 800c2ca: 795b ldrb r3, [r3, #5] + 800c2cc: 021b lsls r3, r3, #8 + 800c2ce: 430b orrs r3, r1 + 800c2d0: b29b uxth r3, r3 + 800c2d2: 429a cmp r2, r3 + 800c2d4: d010 beq.n 800c2f8 + /* Not the same datagram as fraghdr */ + other_datagrams++; + 800c2d6: 68fb ldr r3, [r7, #12] + 800c2d8: 3301 adds r3, #1 + 800c2da: 60fb str r3, [r7, #12] + if (oldest == NULL) { + 800c2dc: 69bb ldr r3, [r7, #24] + 800c2de: 2b00 cmp r3, #0 + 800c2e0: d102 bne.n 800c2e8 + oldest = r; + 800c2e2: 69fb ldr r3, [r7, #28] + 800c2e4: 61bb str r3, [r7, #24] + 800c2e6: e007 b.n 800c2f8 + } else if (r->timer <= oldest->timer) { + 800c2e8: 69fb ldr r3, [r7, #28] + 800c2ea: 7fda ldrb r2, [r3, #31] + 800c2ec: 69bb ldr r3, [r7, #24] + 800c2ee: 7fdb ldrb r3, [r3, #31] + 800c2f0: 429a cmp r2, r3 + 800c2f2: d801 bhi.n 800c2f8 + /* older than the previous oldest */ + oldest = r; + 800c2f4: 69fb ldr r3, [r7, #28] + 800c2f6: 61bb str r3, [r7, #24] + } + } + if (r->next != NULL) { + 800c2f8: 69fb ldr r3, [r7, #28] + 800c2fa: 681b ldr r3, [r3, #0] + 800c2fc: 2b00 cmp r3, #0 + 800c2fe: d001 beq.n 800c304 + prev = r; + 800c300: 69fb ldr r3, [r7, #28] + 800c302: 617b str r3, [r7, #20] + } + r = r->next; + 800c304: 69fb ldr r3, [r7, #28] + 800c306: 681b ldr r3, [r3, #0] + 800c308: 61fb str r3, [r7, #28] + while (r != NULL) { + 800c30a: 69fb ldr r3, [r7, #28] + 800c30c: 2b00 cmp r3, #0 + 800c30e: d1ba bne.n 800c286 + } + if (oldest != NULL) { + 800c310: 69bb ldr r3, [r7, #24] + 800c312: 2b00 cmp r3, #0 + 800c314: d00b beq.n 800c32e + pbufs_freed_current = ip_reass_free_complete_datagram(oldest, prev); + 800c316: 697a ldr r2, [r7, #20] + 800c318: 69bb ldr r3, [r7, #24] + 800c31a: 0011 movs r1, r2 + 800c31c: 0018 movs r0, r3 + 800c31e: f7ff ff13 bl 800c148 + 800c322: 0003 movs r3, r0 + 800c324: 60bb str r3, [r7, #8] + pbufs_freed += pbufs_freed_current; + 800c326: 693a ldr r2, [r7, #16] + 800c328: 68bb ldr r3, [r7, #8] + 800c32a: 18d3 adds r3, r2, r3 + 800c32c: 613b str r3, [r7, #16] + } + } while ((pbufs_freed < pbufs_needed) && (other_datagrams > 1)); + 800c32e: 693a ldr r2, [r7, #16] + 800c330: 683b ldr r3, [r7, #0] + 800c332: 429a cmp r2, r3 + 800c334: da02 bge.n 800c33c + 800c336: 68fb ldr r3, [r7, #12] + 800c338: 2b01 cmp r3, #1 + 800c33a: dc9a bgt.n 800c272 + return pbufs_freed; + 800c33c: 693b ldr r3, [r7, #16] +} + 800c33e: 0018 movs r0, r3 + 800c340: 46bd mov sp, r7 + 800c342: b008 add sp, #32 + 800c344: bd80 pop {r7, pc} + 800c346: 46c0 nop ; (mov r8, r8) + 800c348: 200022b8 .word 0x200022b8 + +0800c34c : + * @param clen number of pbufs needed to enqueue (used for freeing other datagrams if not enough space) + * @return A pointer to the queue location into which the fragment was enqueued + */ +static struct ip_reassdata* +ip_reass_enqueue_new_datagram(struct ip_hdr *fraghdr, int clen) +{ + 800c34c: b580 push {r7, lr} + 800c34e: b084 sub sp, #16 + 800c350: af00 add r7, sp, #0 + 800c352: 6078 str r0, [r7, #4] + 800c354: 6039 str r1, [r7, #0] + struct ip_reassdata* ipr; + /* No matching previous fragment found, allocate a new reassdata struct */ + ipr = (struct ip_reassdata *)memp_malloc(MEMP_REASSDATA); + 800c356: 2005 movs r0, #5 + 800c358: f7f8 fd5c bl 8004e14 + 800c35c: 0003 movs r3, r0 + 800c35e: 60fb str r3, [r7, #12] + if (ipr == NULL) { + 800c360: 68fb ldr r3, [r7, #12] + 800c362: 2b00 cmp r3, #0 + 800c364: d119 bne.n 800c39a +#if IP_REASS_FREE_OLDEST + if (ip_reass_remove_oldest_datagram(fraghdr, clen) >= clen) { + 800c366: 683a ldr r2, [r7, #0] + 800c368: 687b ldr r3, [r7, #4] + 800c36a: 0011 movs r1, r2 + 800c36c: 0018 movs r0, r3 + 800c36e: f7ff ff79 bl 800c264 + 800c372: 0002 movs r2, r0 + 800c374: 683b ldr r3, [r7, #0] + 800c376: 4293 cmp r3, r2 + 800c378: dc04 bgt.n 800c384 + ipr = (struct ip_reassdata *)memp_malloc(MEMP_REASSDATA); + 800c37a: 2005 movs r0, #5 + 800c37c: f7f8 fd4a bl 8004e14 + 800c380: 0003 movs r3, r0 + 800c382: 60fb str r3, [r7, #12] + } + if (ipr == NULL) + 800c384: 68fb ldr r3, [r7, #12] + 800c386: 2b00 cmp r3, #0 + 800c388: d107 bne.n 800c39a +#endif /* IP_REASS_FREE_OLDEST */ + { + IPFRAG_STATS_INC(ip_frag.memerr); + 800c38a: 4b12 ldr r3, [pc, #72] ; (800c3d4 ) + 800c38c: 8f9b ldrh r3, [r3, #60] ; 0x3c + 800c38e: 3301 adds r3, #1 + 800c390: b29a uxth r2, r3 + 800c392: 4b10 ldr r3, [pc, #64] ; (800c3d4 ) + 800c394: 879a strh r2, [r3, #60] ; 0x3c + LWIP_DEBUGF(IP_REASS_DEBUG,("Failed to alloc reassdata struct\n")); + return NULL; + 800c396: 2300 movs r3, #0 + 800c398: e017 b.n 800c3ca + } + } + memset(ipr, 0, sizeof(struct ip_reassdata)); + 800c39a: 68fb ldr r3, [r7, #12] + 800c39c: 2220 movs r2, #32 + 800c39e: 2100 movs r1, #0 + 800c3a0: 0018 movs r0, r3 + 800c3a2: f003 fc87 bl 800fcb4 + ipr->timer = IP_REASS_MAXAGE; + 800c3a6: 68fb ldr r3, [r7, #12] + 800c3a8: 2203 movs r2, #3 + 800c3aa: 77da strb r2, [r3, #31] + + /* enqueue the new structure to the front of the list */ + ipr->next = reassdatagrams; + 800c3ac: 4b0a ldr r3, [pc, #40] ; (800c3d8 ) + 800c3ae: 681a ldr r2, [r3, #0] + 800c3b0: 68fb ldr r3, [r7, #12] + 800c3b2: 601a str r2, [r3, #0] + reassdatagrams = ipr; + 800c3b4: 4b08 ldr r3, [pc, #32] ; (800c3d8 ) + 800c3b6: 68fa ldr r2, [r7, #12] + 800c3b8: 601a str r2, [r3, #0] + /* copy the ip header for later tests and input */ + /* @todo: no ip options supported? */ + SMEMCPY(&(ipr->iphdr), fraghdr, IP_HLEN); + 800c3ba: 68fb ldr r3, [r7, #12] + 800c3bc: 3308 adds r3, #8 + 800c3be: 6879 ldr r1, [r7, #4] + 800c3c0: 2214 movs r2, #20 + 800c3c2: 0018 movs r0, r3 + 800c3c4: f003 fc6d bl 800fca2 + return ipr; + 800c3c8: 68fb ldr r3, [r7, #12] +} + 800c3ca: 0018 movs r0, r3 + 800c3cc: 46bd mov sp, r7 + 800c3ce: b004 add sp, #16 + 800c3d0: bd80 pop {r7, pc} + 800c3d2: 46c0 nop ; (mov r8, r8) + 800c3d4: 20003158 .word 0x20003158 + 800c3d8: 200022b8 .word 0x200022b8 + +0800c3dc : + * Dequeues a datagram from the datagram queue. Doesn't deallocate the pbufs. + * @param ipr points to the queue entry to dequeue + */ +static void +ip_reass_dequeue_datagram(struct ip_reassdata *ipr, struct ip_reassdata *prev) +{ + 800c3dc: b580 push {r7, lr} + 800c3de: b082 sub sp, #8 + 800c3e0: af00 add r7, sp, #0 + 800c3e2: 6078 str r0, [r7, #4] + 800c3e4: 6039 str r1, [r7, #0] + + /* dequeue the reass struct */ + if (reassdatagrams == ipr) { + 800c3e6: 4b0b ldr r3, [pc, #44] ; (800c414 ) + 800c3e8: 681b ldr r3, [r3, #0] + 800c3ea: 687a ldr r2, [r7, #4] + 800c3ec: 429a cmp r2, r3 + 800c3ee: d104 bne.n 800c3fa + /* it was the first in the list */ + reassdatagrams = ipr->next; + 800c3f0: 687b ldr r3, [r7, #4] + 800c3f2: 681a ldr r2, [r3, #0] + 800c3f4: 4b07 ldr r3, [pc, #28] ; (800c414 ) + 800c3f6: 601a str r2, [r3, #0] + 800c3f8: e003 b.n 800c402 + } else { + /* it wasn't the first, so it must have a valid 'prev' */ + LWIP_ASSERT("sanity check linked list", prev != NULL); + prev->next = ipr->next; + 800c3fa: 687b ldr r3, [r7, #4] + 800c3fc: 681a ldr r2, [r3, #0] + 800c3fe: 683b ldr r3, [r7, #0] + 800c400: 601a str r2, [r3, #0] + } + + /* now we can free the ip_reass struct */ + memp_free(MEMP_REASSDATA, ipr); + 800c402: 687b ldr r3, [r7, #4] + 800c404: 0019 movs r1, r3 + 800c406: 2005 movs r0, #5 + 800c408: f7f8 fd8a bl 8004f20 +} + 800c40c: 46c0 nop ; (mov r8, r8) + 800c40e: 46bd mov sp, r7 + 800c410: b002 add sp, #8 + 800c412: bd80 pop {r7, pc} + 800c414: 200022b8 .word 0x200022b8 + +0800c418 : + * @param new_p points to the pbuf for the current fragment + * @return 0 if invalid, >0 otherwise + */ +static int +ip_reass_chain_frag_into_datagram_and_validate(struct ip_reassdata *ipr, struct pbuf *new_p) +{ + 800c418: b5f0 push {r4, r5, r6, r7, lr} + 800c41a: b08b sub sp, #44 ; 0x2c + 800c41c: af00 add r7, sp, #0 + 800c41e: 6078 str r0, [r7, #4] + 800c420: 6039 str r1, [r7, #0] + struct ip_reass_helper *iprh, *iprh_tmp, *iprh_prev=NULL; + 800c422: 2300 movs r3, #0 + 800c424: 623b str r3, [r7, #32] + struct pbuf *q; + u16_t offset,len; + struct ip_hdr *fraghdr; + int valid = 1; + 800c426: 2301 movs r3, #1 + 800c428: 61bb str r3, [r7, #24] + + /* Extract length and fragment offset from current fragment */ + fraghdr = (struct ip_hdr*)new_p->payload; + 800c42a: 683b ldr r3, [r7, #0] + 800c42c: 685b ldr r3, [r3, #4] + 800c42e: 617b str r3, [r7, #20] + len = ntohs(IPH_LEN(fraghdr)) - IPH_HL(fraghdr) * 4; + 800c430: 697b ldr r3, [r7, #20] + 800c432: 789a ldrb r2, [r3, #2] + 800c434: 78db ldrb r3, [r3, #3] + 800c436: 021b lsls r3, r3, #8 + 800c438: 4313 orrs r3, r2 + 800c43a: b29b uxth r3, r3 + 800c43c: 0018 movs r0, r3 + 800c43e: f7f8 f8ff bl 8004640 + 800c442: 0003 movs r3, r0 + 800c444: 0019 movs r1, r3 + 800c446: 697b ldr r3, [r7, #20] + 800c448: 781b ldrb r3, [r3, #0] + 800c44a: b29b uxth r3, r3 + 800c44c: 220f movs r2, #15 + 800c44e: 4013 ands r3, r2 + 800c450: b29b uxth r3, r3 + 800c452: 009b lsls r3, r3, #2 + 800c454: b29a uxth r2, r3 + 800c456: 2612 movs r6, #18 + 800c458: 19bb adds r3, r7, r6 + 800c45a: 1a8a subs r2, r1, r2 + 800c45c: 801a strh r2, [r3, #0] + offset = (ntohs(IPH_OFFSET(fraghdr)) & IP_OFFMASK) * 8; + 800c45e: 697b ldr r3, [r7, #20] + 800c460: 799a ldrb r2, [r3, #6] + 800c462: 79db ldrb r3, [r3, #7] + 800c464: 021b lsls r3, r3, #8 + 800c466: 4313 orrs r3, r2 + 800c468: b29b uxth r3, r3 + 800c46a: 0018 movs r0, r3 + 800c46c: f7f8 f8e8 bl 8004640 + 800c470: 0003 movs r3, r0 + 800c472: 04db lsls r3, r3, #19 + 800c474: 0cdb lsrs r3, r3, #19 + 800c476: b29a uxth r2, r3 + 800c478: 2010 movs r0, #16 + 800c47a: 183b adds r3, r7, r0 + 800c47c: 00d2 lsls r2, r2, #3 + 800c47e: 801a strh r2, [r3, #0] + /* overwrite the fragment's ip header from the pbuf with our helper struct, + * and setup the embedded helper structure. */ + /* make sure the struct ip_reass_helper fits into the IP header */ + LWIP_ASSERT("sizeof(struct ip_reass_helper) <= IP_HLEN", + sizeof(struct ip_reass_helper) <= IP_HLEN); + iprh = (struct ip_reass_helper*)new_p->payload; + 800c480: 683b ldr r3, [r7, #0] + 800c482: 685b ldr r3, [r3, #4] + 800c484: 627b str r3, [r7, #36] ; 0x24 + iprh->next_pbuf = NULL; + 800c486: 6a7b ldr r3, [r7, #36] ; 0x24 + 800c488: 781a ldrb r2, [r3, #0] + 800c48a: 2100 movs r1, #0 + 800c48c: 400a ands r2, r1 + 800c48e: 701a strb r2, [r3, #0] + 800c490: 785a ldrb r2, [r3, #1] + 800c492: 2100 movs r1, #0 + 800c494: 400a ands r2, r1 + 800c496: 705a strb r2, [r3, #1] + 800c498: 789a ldrb r2, [r3, #2] + 800c49a: 2100 movs r1, #0 + 800c49c: 400a ands r2, r1 + 800c49e: 709a strb r2, [r3, #2] + 800c4a0: 78da ldrb r2, [r3, #3] + 800c4a2: 2100 movs r1, #0 + 800c4a4: 400a ands r2, r1 + 800c4a6: 70da strb r2, [r3, #3] + iprh->start = offset; + 800c4a8: 6a7b ldr r3, [r7, #36] ; 0x24 + 800c4aa: 0005 movs r5, r0 + 800c4ac: 183a adds r2, r7, r0 + 800c4ae: 7814 ldrb r4, [r2, #0] + 800c4b0: 7919 ldrb r1, [r3, #4] + 800c4b2: 2000 movs r0, #0 + 800c4b4: 4001 ands r1, r0 + 800c4b6: 1c08 adds r0, r1, #0 + 800c4b8: 1c21 adds r1, r4, #0 + 800c4ba: 4301 orrs r1, r0 + 800c4bc: 7119 strb r1, [r3, #4] + 800c4be: 7850 ldrb r0, [r2, #1] + 800c4c0: 795a ldrb r2, [r3, #5] + 800c4c2: 2100 movs r1, #0 + 800c4c4: 400a ands r2, r1 + 800c4c6: 1c11 adds r1, r2, #0 + 800c4c8: 1c02 adds r2, r0, #0 + 800c4ca: 430a orrs r2, r1 + 800c4cc: 715a strb r2, [r3, #5] + iprh->end = offset + len; + 800c4ce: 0028 movs r0, r5 + 800c4d0: 183a adds r2, r7, r0 + 800c4d2: 19bb adds r3, r7, r6 + 800c4d4: 8812 ldrh r2, [r2, #0] + 800c4d6: 881b ldrh r3, [r3, #0] + 800c4d8: 18d3 adds r3, r2, r3 + 800c4da: b29a uxth r2, r3 + 800c4dc: 6a7b ldr r3, [r7, #36] ; 0x24 + 800c4de: 21ff movs r1, #255 ; 0xff + 800c4e0: 4011 ands r1, r2 + 800c4e2: 000c movs r4, r1 + 800c4e4: 7999 ldrb r1, [r3, #6] + 800c4e6: 2000 movs r0, #0 + 800c4e8: 4001 ands r1, r0 + 800c4ea: 1c08 adds r0, r1, #0 + 800c4ec: 1c21 adds r1, r4, #0 + 800c4ee: 4301 orrs r1, r0 + 800c4f0: 7199 strb r1, [r3, #6] + 800c4f2: 0a12 lsrs r2, r2, #8 + 800c4f4: b290 uxth r0, r2 + 800c4f6: 79da ldrb r2, [r3, #7] + 800c4f8: 2100 movs r1, #0 + 800c4fa: 400a ands r2, r1 + 800c4fc: 1c11 adds r1, r2, #0 + 800c4fe: 1c02 adds r2, r0, #0 + 800c500: 430a orrs r2, r1 + 800c502: 71da strb r2, [r3, #7] + + /* Iterate through until we either get to the end of the list (append), + * or we find on with a larger offset (insert). */ + for (q = ipr->p; q != NULL;) { + 800c504: 687b ldr r3, [r7, #4] + 800c506: 685b ldr r3, [r3, #4] + 800c508: 61fb str r3, [r7, #28] + 800c50a: e0c3 b.n 800c694 + iprh_tmp = (struct ip_reass_helper*)q->payload; + 800c50c: 69fb ldr r3, [r7, #28] + 800c50e: 685b ldr r3, [r3, #4] + 800c510: 60fb str r3, [r7, #12] + if (iprh->start < iprh_tmp->start) { + 800c512: 6a7b ldr r3, [r7, #36] ; 0x24 + 800c514: 791a ldrb r2, [r3, #4] + 800c516: 795b ldrb r3, [r3, #5] + 800c518: 021b lsls r3, r3, #8 + 800c51a: 4313 orrs r3, r2 + 800c51c: b29a uxth r2, r3 + 800c51e: 68fb ldr r3, [r7, #12] + 800c520: 7919 ldrb r1, [r3, #4] + 800c522: 795b ldrb r3, [r3, #5] + 800c524: 021b lsls r3, r3, #8 + 800c526: 430b orrs r3, r1 + 800c528: b29b uxth r3, r3 + 800c52a: 429a cmp r2, r3 + 800c52c: d273 bcs.n 800c616 + /* the new pbuf should be inserted before this */ + iprh->next_pbuf = q; + 800c52e: 6a7b ldr r3, [r7, #36] ; 0x24 + 800c530: 221c movs r2, #28 + 800c532: 18ba adds r2, r7, r2 + 800c534: 7810 ldrb r0, [r2, #0] + 800c536: 781a ldrb r2, [r3, #0] + 800c538: 2100 movs r1, #0 + 800c53a: 400a ands r2, r1 + 800c53c: 1c11 adds r1, r2, #0 + 800c53e: 1c02 adds r2, r0, #0 + 800c540: 430a orrs r2, r1 + 800c542: 701a strb r2, [r3, #0] + 800c544: 221d movs r2, #29 + 800c546: 18ba adds r2, r7, r2 + 800c548: 7810 ldrb r0, [r2, #0] + 800c54a: 785a ldrb r2, [r3, #1] + 800c54c: 2100 movs r1, #0 + 800c54e: 400a ands r2, r1 + 800c550: 1c11 adds r1, r2, #0 + 800c552: 1c02 adds r2, r0, #0 + 800c554: 430a orrs r2, r1 + 800c556: 705a strb r2, [r3, #1] + 800c558: 221e movs r2, #30 + 800c55a: 18ba adds r2, r7, r2 + 800c55c: 7810 ldrb r0, [r2, #0] + 800c55e: 789a ldrb r2, [r3, #2] + 800c560: 2100 movs r1, #0 + 800c562: 400a ands r2, r1 + 800c564: 1c11 adds r1, r2, #0 + 800c566: 1c02 adds r2, r0, #0 + 800c568: 430a orrs r2, r1 + 800c56a: 709a strb r2, [r3, #2] + 800c56c: 221f movs r2, #31 + 800c56e: 18ba adds r2, r7, r2 + 800c570: 7810 ldrb r0, [r2, #0] + 800c572: 78da ldrb r2, [r3, #3] + 800c574: 2100 movs r1, #0 + 800c576: 400a ands r2, r1 + 800c578: 1c11 adds r1, r2, #0 + 800c57a: 1c02 adds r2, r0, #0 + 800c57c: 430a orrs r2, r1 + 800c57e: 70da strb r2, [r3, #3] + if (iprh_prev != NULL) { + 800c580: 6a3b ldr r3, [r7, #32] + 800c582: 2b00 cmp r3, #0 + 800c584: d043 beq.n 800c60e + /* not the fragment with the lowest offset */ +#if IP_REASS_CHECK_OVERLAP + if ((iprh->start < iprh_prev->end) || (iprh->end > iprh_tmp->start)) { + 800c586: 6a7b ldr r3, [r7, #36] ; 0x24 + 800c588: 791a ldrb r2, [r3, #4] + 800c58a: 795b ldrb r3, [r3, #5] + 800c58c: 021b lsls r3, r3, #8 + 800c58e: 4313 orrs r3, r2 + 800c590: b29a uxth r2, r3 + 800c592: 6a3b ldr r3, [r7, #32] + 800c594: 7999 ldrb r1, [r3, #6] + 800c596: 79db ldrb r3, [r3, #7] + 800c598: 021b lsls r3, r3, #8 + 800c59a: 430b orrs r3, r1 + 800c59c: b29b uxth r3, r3 + 800c59e: 429a cmp r2, r3 + 800c5a0: d200 bcs.n 800c5a4 + 800c5a2: e108 b.n 800c7b6 + 800c5a4: 6a7b ldr r3, [r7, #36] ; 0x24 + 800c5a6: 799a ldrb r2, [r3, #6] + 800c5a8: 79db ldrb r3, [r3, #7] + 800c5aa: 021b lsls r3, r3, #8 + 800c5ac: 4313 orrs r3, r2 + 800c5ae: b29a uxth r2, r3 + 800c5b0: 68fb ldr r3, [r7, #12] + 800c5b2: 7919 ldrb r1, [r3, #4] + 800c5b4: 795b ldrb r3, [r3, #5] + 800c5b6: 021b lsls r3, r3, #8 + 800c5b8: 430b orrs r3, r1 + 800c5ba: b29b uxth r3, r3 + 800c5bc: 429a cmp r2, r3 + 800c5be: d900 bls.n 800c5c2 + 800c5c0: e0f9 b.n 800c7b6 + /* fragment overlaps with previous or following, throw away */ + goto freepbuf; + } +#endif /* IP_REASS_CHECK_OVERLAP */ + iprh_prev->next_pbuf = new_p; + 800c5c2: 6a3b ldr r3, [r7, #32] + 800c5c4: 003a movs r2, r7 + 800c5c6: 7810 ldrb r0, [r2, #0] + 800c5c8: 781a ldrb r2, [r3, #0] + 800c5ca: 2100 movs r1, #0 + 800c5cc: 400a ands r2, r1 + 800c5ce: 1c11 adds r1, r2, #0 + 800c5d0: 1c02 adds r2, r0, #0 + 800c5d2: 430a orrs r2, r1 + 800c5d4: 701a strb r2, [r3, #0] + 800c5d6: 1c7a adds r2, r7, #1 + 800c5d8: 7810 ldrb r0, [r2, #0] + 800c5da: 785a ldrb r2, [r3, #1] + 800c5dc: 2100 movs r1, #0 + 800c5de: 400a ands r2, r1 + 800c5e0: 1c11 adds r1, r2, #0 + 800c5e2: 1c02 adds r2, r0, #0 + 800c5e4: 430a orrs r2, r1 + 800c5e6: 705a strb r2, [r3, #1] + 800c5e8: 1cba adds r2, r7, #2 + 800c5ea: 7810 ldrb r0, [r2, #0] + 800c5ec: 789a ldrb r2, [r3, #2] + 800c5ee: 2100 movs r1, #0 + 800c5f0: 400a ands r2, r1 + 800c5f2: 1c11 adds r1, r2, #0 + 800c5f4: 1c02 adds r2, r0, #0 + 800c5f6: 430a orrs r2, r1 + 800c5f8: 709a strb r2, [r3, #2] + 800c5fa: 1cfa adds r2, r7, #3 + 800c5fc: 7810 ldrb r0, [r2, #0] + 800c5fe: 78da ldrb r2, [r3, #3] + 800c600: 2100 movs r1, #0 + 800c602: 400a ands r2, r1 + 800c604: 1c11 adds r1, r2, #0 + 800c606: 1c02 adds r2, r0, #0 + 800c608: 430a orrs r2, r1 + 800c60a: 70da strb r2, [r3, #3] + } else { + /* fragment with the lowest offset */ + ipr->p = new_p; + } + break; + 800c60c: e046 b.n 800c69c + ipr->p = new_p; + 800c60e: 687b ldr r3, [r7, #4] + 800c610: 683a ldr r2, [r7, #0] + 800c612: 605a str r2, [r3, #4] + break; + 800c614: e042 b.n 800c69c + } else if(iprh->start == iprh_tmp->start) { + 800c616: 6a7b ldr r3, [r7, #36] ; 0x24 + 800c618: 791a ldrb r2, [r3, #4] + 800c61a: 795b ldrb r3, [r3, #5] + 800c61c: 021b lsls r3, r3, #8 + 800c61e: 4313 orrs r3, r2 + 800c620: b29a uxth r2, r3 + 800c622: 68fb ldr r3, [r7, #12] + 800c624: 7919 ldrb r1, [r3, #4] + 800c626: 795b ldrb r3, [r3, #5] + 800c628: 021b lsls r3, r3, #8 + 800c62a: 430b orrs r3, r1 + 800c62c: b29b uxth r3, r3 + 800c62e: 429a cmp r2, r3 + 800c630: d100 bne.n 800c634 + 800c632: e0c2 b.n 800c7ba + /* received the same datagram twice: no need to keep the datagram */ + goto freepbuf; +#if IP_REASS_CHECK_OVERLAP + } else if(iprh->start < iprh_tmp->end) { + 800c634: 6a7b ldr r3, [r7, #36] ; 0x24 + 800c636: 791a ldrb r2, [r3, #4] + 800c638: 795b ldrb r3, [r3, #5] + 800c63a: 021b lsls r3, r3, #8 + 800c63c: 4313 orrs r3, r2 + 800c63e: b29a uxth r2, r3 + 800c640: 68fb ldr r3, [r7, #12] + 800c642: 7999 ldrb r1, [r3, #6] + 800c644: 79db ldrb r3, [r3, #7] + 800c646: 021b lsls r3, r3, #8 + 800c648: 430b orrs r3, r1 + 800c64a: b29b uxth r3, r3 + 800c64c: 429a cmp r2, r3 + 800c64e: d200 bcs.n 800c652 + 800c650: e0b5 b.n 800c7be + /* overlap: no need to keep the new datagram */ + goto freepbuf; +#endif /* IP_REASS_CHECK_OVERLAP */ + } else { + /* Check if the fragments received so far have no wholes. */ + if (iprh_prev != NULL) { + 800c652: 6a3b ldr r3, [r7, #32] + 800c654: 2b00 cmp r3, #0 + 800c656: d00f beq.n 800c678 + if (iprh_prev->end != iprh_tmp->start) { + 800c658: 6a3b ldr r3, [r7, #32] + 800c65a: 799a ldrb r2, [r3, #6] + 800c65c: 79db ldrb r3, [r3, #7] + 800c65e: 021b lsls r3, r3, #8 + 800c660: 4313 orrs r3, r2 + 800c662: b29a uxth r2, r3 + 800c664: 68fb ldr r3, [r7, #12] + 800c666: 7919 ldrb r1, [r3, #4] + 800c668: 795b ldrb r3, [r3, #5] + 800c66a: 021b lsls r3, r3, #8 + 800c66c: 430b orrs r3, r1 + 800c66e: b29b uxth r3, r3 + 800c670: 429a cmp r2, r3 + 800c672: d001 beq.n 800c678 + /* There is a fragment missing between the current + * and the previous fragment */ + valid = 0; + 800c674: 2300 movs r3, #0 + 800c676: 61bb str r3, [r7, #24] + } + } + } + q = iprh_tmp->next_pbuf; + 800c678: 68fb ldr r3, [r7, #12] + 800c67a: 781a ldrb r2, [r3, #0] + 800c67c: 7859 ldrb r1, [r3, #1] + 800c67e: 0209 lsls r1, r1, #8 + 800c680: 430a orrs r2, r1 + 800c682: 7899 ldrb r1, [r3, #2] + 800c684: 0409 lsls r1, r1, #16 + 800c686: 430a orrs r2, r1 + 800c688: 78db ldrb r3, [r3, #3] + 800c68a: 061b lsls r3, r3, #24 + 800c68c: 4313 orrs r3, r2 + 800c68e: 61fb str r3, [r7, #28] + iprh_prev = iprh_tmp; + 800c690: 68fb ldr r3, [r7, #12] + 800c692: 623b str r3, [r7, #32] + for (q = ipr->p; q != NULL;) { + 800c694: 69fb ldr r3, [r7, #28] + 800c696: 2b00 cmp r3, #0 + 800c698: d000 beq.n 800c69c + 800c69a: e737 b.n 800c50c + } + + /* If q is NULL, then we made it to the end of the list. Determine what to do now */ + if (q == NULL) { + 800c69c: 69fb ldr r3, [r7, #28] + 800c69e: 2b00 cmp r3, #0 + 800c6a0: d13b bne.n 800c71a + if (iprh_prev != NULL) { + 800c6a2: 6a3b ldr r3, [r7, #32] + 800c6a4: 2b00 cmp r3, #0 + 800c6a6: d035 beq.n 800c714 + /* this is (for now), the fragment with the highest offset: + * chain it to the last fragment */ +#if IP_REASS_CHECK_OVERLAP + LWIP_ASSERT("check fragments don't overlap", iprh_prev->end <= iprh->start); +#endif /* IP_REASS_CHECK_OVERLAP */ + iprh_prev->next_pbuf = new_p; + 800c6a8: 6a3b ldr r3, [r7, #32] + 800c6aa: 003a movs r2, r7 + 800c6ac: 7810 ldrb r0, [r2, #0] + 800c6ae: 781a ldrb r2, [r3, #0] + 800c6b0: 2100 movs r1, #0 + 800c6b2: 400a ands r2, r1 + 800c6b4: 1c11 adds r1, r2, #0 + 800c6b6: 1c02 adds r2, r0, #0 + 800c6b8: 430a orrs r2, r1 + 800c6ba: 701a strb r2, [r3, #0] + 800c6bc: 1c7a adds r2, r7, #1 + 800c6be: 7810 ldrb r0, [r2, #0] + 800c6c0: 785a ldrb r2, [r3, #1] + 800c6c2: 2100 movs r1, #0 + 800c6c4: 400a ands r2, r1 + 800c6c6: 1c11 adds r1, r2, #0 + 800c6c8: 1c02 adds r2, r0, #0 + 800c6ca: 430a orrs r2, r1 + 800c6cc: 705a strb r2, [r3, #1] + 800c6ce: 1cba adds r2, r7, #2 + 800c6d0: 7810 ldrb r0, [r2, #0] + 800c6d2: 789a ldrb r2, [r3, #2] + 800c6d4: 2100 movs r1, #0 + 800c6d6: 400a ands r2, r1 + 800c6d8: 1c11 adds r1, r2, #0 + 800c6da: 1c02 adds r2, r0, #0 + 800c6dc: 430a orrs r2, r1 + 800c6de: 709a strb r2, [r3, #2] + 800c6e0: 1cfa adds r2, r7, #3 + 800c6e2: 7810 ldrb r0, [r2, #0] + 800c6e4: 78da ldrb r2, [r3, #3] + 800c6e6: 2100 movs r1, #0 + 800c6e8: 400a ands r2, r1 + 800c6ea: 1c11 adds r1, r2, #0 + 800c6ec: 1c02 adds r2, r0, #0 + 800c6ee: 430a orrs r2, r1 + 800c6f0: 70da strb r2, [r3, #3] + if (iprh_prev->end != iprh->start) { + 800c6f2: 6a3b ldr r3, [r7, #32] + 800c6f4: 799a ldrb r2, [r3, #6] + 800c6f6: 79db ldrb r3, [r3, #7] + 800c6f8: 021b lsls r3, r3, #8 + 800c6fa: 4313 orrs r3, r2 + 800c6fc: b29a uxth r2, r3 + 800c6fe: 6a7b ldr r3, [r7, #36] ; 0x24 + 800c700: 7919 ldrb r1, [r3, #4] + 800c702: 795b ldrb r3, [r3, #5] + 800c704: 021b lsls r3, r3, #8 + 800c706: 430b orrs r3, r1 + 800c708: b29b uxth r3, r3 + 800c70a: 429a cmp r2, r3 + 800c70c: d005 beq.n 800c71a + valid = 0; + 800c70e: 2300 movs r3, #0 + 800c710: 61bb str r3, [r7, #24] + 800c712: e002 b.n 800c71a +#if IP_REASS_CHECK_OVERLAP + LWIP_ASSERT("no previous fragment, this must be the first fragment!", + ipr->p == NULL); +#endif /* IP_REASS_CHECK_OVERLAP */ + /* this is the first fragment we ever received for this ip datagram */ + ipr->p = new_p; + 800c714: 687b ldr r3, [r7, #4] + 800c716: 683a ldr r2, [r7, #0] + 800c718: 605a str r2, [r3, #4] + } + } + + /* At this point, the validation part begins: */ + /* If we already received the last fragment */ + if ((ipr->flags & IP_REASS_FLAG_LASTFRAG) != 0) { + 800c71a: 687b ldr r3, [r7, #4] + 800c71c: 7f9b ldrb r3, [r3, #30] + 800c71e: 001a movs r2, r3 + 800c720: 2301 movs r3, #1 + 800c722: 4013 ands r3, r2 + 800c724: d045 beq.n 800c7b2 + /* and had no wholes so far */ + if (valid) { + 800c726: 69bb ldr r3, [r7, #24] + 800c728: 2b00 cmp r3, #0 + 800c72a: d040 beq.n 800c7ae + /* then check if the rest of the fragments is here */ + /* Check if the queue starts with the first datagram */ + if (((struct ip_reass_helper*)ipr->p->payload)->start != 0) { + 800c72c: 687b ldr r3, [r7, #4] + 800c72e: 685b ldr r3, [r3, #4] + 800c730: 685b ldr r3, [r3, #4] + 800c732: 791a ldrb r2, [r3, #4] + 800c734: 795b ldrb r3, [r3, #5] + 800c736: 021b lsls r3, r3, #8 + 800c738: 4313 orrs r3, r2 + 800c73a: b29b uxth r3, r3 + 800c73c: 2b00 cmp r3, #0 + 800c73e: d002 beq.n 800c746 + valid = 0; + 800c740: 2300 movs r3, #0 + 800c742: 61bb str r3, [r7, #24] + 800c744: e033 b.n 800c7ae + } else { + /* and check that there are no wholes after this datagram */ + iprh_prev = iprh; + 800c746: 6a7b ldr r3, [r7, #36] ; 0x24 + 800c748: 623b str r3, [r7, #32] + q = iprh->next_pbuf; + 800c74a: 6a7b ldr r3, [r7, #36] ; 0x24 + 800c74c: 781a ldrb r2, [r3, #0] + 800c74e: 7859 ldrb r1, [r3, #1] + 800c750: 0209 lsls r1, r1, #8 + 800c752: 430a orrs r2, r1 + 800c754: 7899 ldrb r1, [r3, #2] + 800c756: 0409 lsls r1, r1, #16 + 800c758: 430a orrs r2, r1 + 800c75a: 78db ldrb r3, [r3, #3] + 800c75c: 061b lsls r3, r3, #24 + 800c75e: 4313 orrs r3, r2 + 800c760: 61fb str r3, [r7, #28] + while (q != NULL) { + 800c762: e021 b.n 800c7a8 + iprh = (struct ip_reass_helper*)q->payload; + 800c764: 69fb ldr r3, [r7, #28] + 800c766: 685b ldr r3, [r3, #4] + 800c768: 627b str r3, [r7, #36] ; 0x24 + if (iprh_prev->end != iprh->start) { + 800c76a: 6a3b ldr r3, [r7, #32] + 800c76c: 799a ldrb r2, [r3, #6] + 800c76e: 79db ldrb r3, [r3, #7] + 800c770: 021b lsls r3, r3, #8 + 800c772: 4313 orrs r3, r2 + 800c774: b29a uxth r2, r3 + 800c776: 6a7b ldr r3, [r7, #36] ; 0x24 + 800c778: 7919 ldrb r1, [r3, #4] + 800c77a: 795b ldrb r3, [r3, #5] + 800c77c: 021b lsls r3, r3, #8 + 800c77e: 430b orrs r3, r1 + 800c780: b29b uxth r3, r3 + 800c782: 429a cmp r2, r3 + 800c784: d002 beq.n 800c78c + valid = 0; + 800c786: 2300 movs r3, #0 + 800c788: 61bb str r3, [r7, #24] + break; + 800c78a: e010 b.n 800c7ae + } + iprh_prev = iprh; + 800c78c: 6a7b ldr r3, [r7, #36] ; 0x24 + 800c78e: 623b str r3, [r7, #32] + q = iprh->next_pbuf; + 800c790: 6a7b ldr r3, [r7, #36] ; 0x24 + 800c792: 781a ldrb r2, [r3, #0] + 800c794: 7859 ldrb r1, [r3, #1] + 800c796: 0209 lsls r1, r1, #8 + 800c798: 430a orrs r2, r1 + 800c79a: 7899 ldrb r1, [r3, #2] + 800c79c: 0409 lsls r1, r1, #16 + 800c79e: 430a orrs r2, r1 + 800c7a0: 78db ldrb r3, [r3, #3] + 800c7a2: 061b lsls r3, r3, #24 + 800c7a4: 4313 orrs r3, r2 + 800c7a6: 61fb str r3, [r7, #28] + while (q != NULL) { + 800c7a8: 69fb ldr r3, [r7, #28] + 800c7aa: 2b00 cmp r3, #0 + 800c7ac: d1da bne.n 800c764 + } + } + /* If valid is 0 here, there are some fragments missing in the middle + * (since MF == 0 has already arrived). Such datagrams simply time out if + * no more fragments are received... */ + return valid; + 800c7ae: 69bb ldr r3, [r7, #24] + 800c7b0: e018 b.n 800c7e4 + } + /* If we come here, not all fragments were received, yet! */ + return 0; /* not yet valid! */ + 800c7b2: 2300 movs r3, #0 + 800c7b4: e016 b.n 800c7e4 +#if IP_REASS_CHECK_OVERLAP +freepbuf: + 800c7b6: 46c0 nop ; (mov r8, r8) + 800c7b8: e002 b.n 800c7c0 + goto freepbuf; + 800c7ba: 46c0 nop ; (mov r8, r8) + 800c7bc: e000 b.n 800c7c0 + goto freepbuf; + 800c7be: 46c0 nop ; (mov r8, r8) + ip_reass_pbufcount -= pbuf_clen(new_p); + 800c7c0: 683b ldr r3, [r7, #0] + 800c7c2: 0018 movs r0, r3 + 800c7c4: f7f8 ffe0 bl 8005788 + 800c7c8: 0003 movs r3, r0 + 800c7ca: 0019 movs r1, r3 + 800c7cc: 4b07 ldr r3, [pc, #28] ; (800c7ec ) + 800c7ce: 881a ldrh r2, [r3, #0] + 800c7d0: b28b uxth r3, r1 + 800c7d2: 1ad3 subs r3, r2, r3 + 800c7d4: b29a uxth r2, r3 + 800c7d6: 4b05 ldr r3, [pc, #20] ; (800c7ec ) + 800c7d8: 801a strh r2, [r3, #0] + pbuf_free(new_p); + 800c7da: 683b ldr r3, [r7, #0] + 800c7dc: 0018 movs r0, r3 + 800c7de: f7f8 ff61 bl 80056a4 + return 0; + 800c7e2: 2300 movs r3, #0 +#endif /* IP_REASS_CHECK_OVERLAP */ +} + 800c7e4: 0018 movs r0, r3 + 800c7e6: 46bd mov sp, r7 + 800c7e8: b00b add sp, #44 ; 0x2c + 800c7ea: bdf0 pop {r4, r5, r6, r7, pc} + 800c7ec: 200022bc .word 0x200022bc + +0800c7f0 : + * @param p points to a pbuf chain of the fragment + * @return NULL if reassembly is incomplete, ? otherwise + */ +struct pbuf * +ip_reass(struct pbuf *p) +{ + 800c7f0: b5b0 push {r4, r5, r7, lr} + 800c7f2: b08a sub sp, #40 ; 0x28 + 800c7f4: af00 add r7, sp, #0 + 800c7f6: 6078 str r0, [r7, #4] + struct ip_hdr *fraghdr; + struct ip_reassdata *ipr; + struct ip_reass_helper *iprh; + u16_t offset, len; + u8_t clen; + struct ip_reassdata *ipr_prev = NULL; + 800c7f8: 2300 movs r3, #0 + 800c7fa: 61fb str r3, [r7, #28] + + IPFRAG_STATS_INC(ip_frag.recv); + 800c7fc: 4bd3 ldr r3, [pc, #844] ; (800cb4c ) + 800c7fe: 8e5b ldrh r3, [r3, #50] ; 0x32 + 800c800: 3301 adds r3, #1 + 800c802: b29a uxth r2, r3 + 800c804: 4bd1 ldr r3, [pc, #836] ; (800cb4c ) + 800c806: 865a strh r2, [r3, #50] ; 0x32 + snmp_inc_ipreasmreqds(); + + fraghdr = (struct ip_hdr*)p->payload; + 800c808: 687b ldr r3, [r7, #4] + 800c80a: 685b ldr r3, [r3, #4] + 800c80c: 61bb str r3, [r7, #24] + + if ((IPH_HL(fraghdr) * 4) != IP_HLEN) { + 800c80e: 69bb ldr r3, [r7, #24] + 800c810: 781b ldrb r3, [r3, #0] + 800c812: 001a movs r2, r3 + 800c814: 230f movs r3, #15 + 800c816: 4013 ands r3, r2 + 800c818: 009b lsls r3, r3, #2 + 800c81a: 2b14 cmp r3, #20 + 800c81c: d008 beq.n 800c830 + LWIP_DEBUGF(IP_REASS_DEBUG,("ip_reass: IP options currently not supported!\n")); + IPFRAG_STATS_INC(ip_frag.err); + 800c81e: 4bcb ldr r3, [pc, #812] ; (800cb4c ) + 800c820: 2244 movs r2, #68 ; 0x44 + 800c822: 5a9b ldrh r3, [r3, r2] + 800c824: 3301 adds r3, #1 + 800c826: b299 uxth r1, r3 + 800c828: 4bc8 ldr r3, [pc, #800] ; (800cb4c ) + 800c82a: 2244 movs r2, #68 ; 0x44 + 800c82c: 5299 strh r1, [r3, r2] + goto nullreturn; + 800c82e: e193 b.n 800cb58 + } + + offset = (ntohs(IPH_OFFSET(fraghdr)) & IP_OFFMASK) * 8; + 800c830: 69bb ldr r3, [r7, #24] + 800c832: 799a ldrb r2, [r3, #6] + 800c834: 79db ldrb r3, [r3, #7] + 800c836: 021b lsls r3, r3, #8 + 800c838: 4313 orrs r3, r2 + 800c83a: b29b uxth r3, r3 + 800c83c: 0018 movs r0, r3 + 800c83e: f7f7 feff bl 8004640 + 800c842: 0003 movs r3, r0 + 800c844: 04db lsls r3, r3, #19 + 800c846: 0cdb lsrs r3, r3, #19 + 800c848: b29a uxth r2, r3 + 800c84a: 2316 movs r3, #22 + 800c84c: 18fb adds r3, r7, r3 + 800c84e: 00d2 lsls r2, r2, #3 + 800c850: 801a strh r2, [r3, #0] + len = ntohs(IPH_LEN(fraghdr)) - IPH_HL(fraghdr) * 4; + 800c852: 69bb ldr r3, [r7, #24] + 800c854: 789a ldrb r2, [r3, #2] + 800c856: 78db ldrb r3, [r3, #3] + 800c858: 021b lsls r3, r3, #8 + 800c85a: 4313 orrs r3, r2 + 800c85c: b29b uxth r3, r3 + 800c85e: 0018 movs r0, r3 + 800c860: f7f7 feee bl 8004640 + 800c864: 0003 movs r3, r0 + 800c866: 0019 movs r1, r3 + 800c868: 69bb ldr r3, [r7, #24] + 800c86a: 781b ldrb r3, [r3, #0] + 800c86c: b29b uxth r3, r3 + 800c86e: 220f movs r2, #15 + 800c870: 4013 ands r3, r2 + 800c872: b29b uxth r3, r3 + 800c874: 009b lsls r3, r3, #2 + 800c876: b29a uxth r2, r3 + 800c878: 2314 movs r3, #20 + 800c87a: 18fb adds r3, r7, r3 + 800c87c: 1a8a subs r2, r1, r2 + 800c87e: 801a strh r2, [r3, #0] + + /* Check if we are allowed to enqueue more datagrams. */ + clen = pbuf_clen(p); + 800c880: 2513 movs r5, #19 + 800c882: 197c adds r4, r7, r5 + 800c884: 687b ldr r3, [r7, #4] + 800c886: 0018 movs r0, r3 + 800c888: f7f8 ff7e bl 8005788 + 800c88c: 0003 movs r3, r0 + 800c88e: 7023 strb r3, [r4, #0] + if ((ip_reass_pbufcount + clen) > IP_REASS_MAX_PBUFS) { + 800c890: 4baf ldr r3, [pc, #700] ; (800cb50 ) + 800c892: 881b ldrh r3, [r3, #0] + 800c894: 001a movs r2, r3 + 800c896: 197b adds r3, r7, r5 + 800c898: 781b ldrb r3, [r3, #0] + 800c89a: 18d3 adds r3, r2, r3 + 800c89c: 2b0a cmp r3, #10 + 800c89e: dd19 ble.n 800c8d4 +#if IP_REASS_FREE_OLDEST + if (!ip_reass_remove_oldest_datagram(fraghdr, clen) || + 800c8a0: 2313 movs r3, #19 + 800c8a2: 18fb adds r3, r7, r3 + 800c8a4: 781a ldrb r2, [r3, #0] + 800c8a6: 69bb ldr r3, [r7, #24] + 800c8a8: 0011 movs r1, r2 + 800c8aa: 0018 movs r0, r3 + 800c8ac: f7ff fcda bl 800c264 + 800c8b0: 1e03 subs r3, r0, #0 + 800c8b2: d008 beq.n 800c8c6 + ((ip_reass_pbufcount + clen) > IP_REASS_MAX_PBUFS)) + 800c8b4: 4ba6 ldr r3, [pc, #664] ; (800cb50 ) + 800c8b6: 881b ldrh r3, [r3, #0] + 800c8b8: 001a movs r2, r3 + 800c8ba: 2313 movs r3, #19 + 800c8bc: 18fb adds r3, r7, r3 + 800c8be: 781b ldrb r3, [r3, #0] + 800c8c0: 18d3 adds r3, r2, r3 + if (!ip_reass_remove_oldest_datagram(fraghdr, clen) || + 800c8c2: 2b0a cmp r3, #10 + 800c8c4: dd06 ble.n 800c8d4 +#endif /* IP_REASS_FREE_OLDEST */ + { + /* No datagram could be freed and still too many pbufs enqueued */ + LWIP_DEBUGF(IP_REASS_DEBUG,("ip_reass: Overflow condition: pbufct=%d, clen=%d, MAX=%d\n", + ip_reass_pbufcount, clen, IP_REASS_MAX_PBUFS)); + IPFRAG_STATS_INC(ip_frag.memerr); + 800c8c6: 4ba1 ldr r3, [pc, #644] ; (800cb4c ) + 800c8c8: 8f9b ldrh r3, [r3, #60] ; 0x3c + 800c8ca: 3301 adds r3, #1 + 800c8cc: b29a uxth r2, r3 + 800c8ce: 4b9f ldr r3, [pc, #636] ; (800cb4c ) + 800c8d0: 879a strh r2, [r3, #60] ; 0x3c + /* @todo: send ICMP time exceeded here? */ + /* drop this pbuf */ + goto nullreturn; + 800c8d2: e141 b.n 800cb58 + } + } + + /* Look for the datagram the fragment belongs to in the current datagram queue, + * remembering the previous in the queue for later dequeueing. */ + for (ipr = reassdatagrams; ipr != NULL; ipr = ipr->next) { + 800c8d4: 4b9f ldr r3, [pc, #636] ; (800cb54 ) + 800c8d6: 681b ldr r3, [r3, #0] + 800c8d8: 623b str r3, [r7, #32] + 800c8da: e035 b.n 800c948 + /* Check if the incoming fragment matches the one currently present + in the reassembly buffer. If so, we proceed with copying the + fragment into the buffer. */ + if (IP_ADDRESSES_AND_ID_MATCH(&ipr->iphdr, fraghdr)) { + 800c8dc: 6a3b ldr r3, [r7, #32] + 800c8de: 695a ldr r2, [r3, #20] + 800c8e0: 69bb ldr r3, [r7, #24] + 800c8e2: 7b19 ldrb r1, [r3, #12] + 800c8e4: 7b58 ldrb r0, [r3, #13] + 800c8e6: 0200 lsls r0, r0, #8 + 800c8e8: 4301 orrs r1, r0 + 800c8ea: 7b98 ldrb r0, [r3, #14] + 800c8ec: 0400 lsls r0, r0, #16 + 800c8ee: 4301 orrs r1, r0 + 800c8f0: 7bdb ldrb r3, [r3, #15] + 800c8f2: 061b lsls r3, r3, #24 + 800c8f4: 430b orrs r3, r1 + 800c8f6: 429a cmp r2, r3 + 800c8f8: d121 bne.n 800c93e + 800c8fa: 6a3b ldr r3, [r7, #32] + 800c8fc: 699a ldr r2, [r3, #24] + 800c8fe: 69bb ldr r3, [r7, #24] + 800c900: 7c19 ldrb r1, [r3, #16] + 800c902: 7c58 ldrb r0, [r3, #17] + 800c904: 0200 lsls r0, r0, #8 + 800c906: 4301 orrs r1, r0 + 800c908: 7c98 ldrb r0, [r3, #18] + 800c90a: 0400 lsls r0, r0, #16 + 800c90c: 4301 orrs r1, r0 + 800c90e: 7cdb ldrb r3, [r3, #19] + 800c910: 061b lsls r3, r3, #24 + 800c912: 430b orrs r3, r1 + 800c914: 429a cmp r2, r3 + 800c916: d112 bne.n 800c93e + 800c918: 6a3b ldr r3, [r7, #32] + 800c91a: 899a ldrh r2, [r3, #12] + 800c91c: 69bb ldr r3, [r7, #24] + 800c91e: 7919 ldrb r1, [r3, #4] + 800c920: 795b ldrb r3, [r3, #5] + 800c922: 021b lsls r3, r3, #8 + 800c924: 430b orrs r3, r1 + 800c926: b29b uxth r3, r3 + 800c928: 429a cmp r2, r3 + 800c92a: d108 bne.n 800c93e + LWIP_DEBUGF(IP_REASS_DEBUG, ("ip_reass: matching previous fragment ID=%"X16_F"\n", + ntohs(IPH_ID(fraghdr)))); + IPFRAG_STATS_INC(ip_frag.cachehit); + 800c92c: 4b87 ldr r3, [pc, #540] ; (800cb4c ) + 800c92e: 2246 movs r2, #70 ; 0x46 + 800c930: 5a9b ldrh r3, [r3, r2] + 800c932: 3301 adds r3, #1 + 800c934: b299 uxth r1, r3 + 800c936: 4b85 ldr r3, [pc, #532] ; (800cb4c ) + 800c938: 2246 movs r2, #70 ; 0x46 + 800c93a: 5299 strh r1, [r3, r2] + break; + 800c93c: e007 b.n 800c94e + } + ipr_prev = ipr; + 800c93e: 6a3b ldr r3, [r7, #32] + 800c940: 61fb str r3, [r7, #28] + for (ipr = reassdatagrams; ipr != NULL; ipr = ipr->next) { + 800c942: 6a3b ldr r3, [r7, #32] + 800c944: 681b ldr r3, [r3, #0] + 800c946: 623b str r3, [r7, #32] + 800c948: 6a3b ldr r3, [r7, #32] + 800c94a: 2b00 cmp r3, #0 + 800c94c: d1c6 bne.n 800c8dc + } + + if (ipr == NULL) { + 800c94e: 6a3b ldr r3, [r7, #32] + 800c950: 2b00 cmp r3, #0 + 800c952: d10d bne.n 800c970 + /* Enqueue a new datagram into the datagram queue */ + ipr = ip_reass_enqueue_new_datagram(fraghdr, clen); + 800c954: 2313 movs r3, #19 + 800c956: 18fb adds r3, r7, r3 + 800c958: 781a ldrb r2, [r3, #0] + 800c95a: 69bb ldr r3, [r7, #24] + 800c95c: 0011 movs r1, r2 + 800c95e: 0018 movs r0, r3 + 800c960: f7ff fcf4 bl 800c34c + 800c964: 0003 movs r3, r0 + 800c966: 623b str r3, [r7, #32] + /* Bail if unable to enqueue */ + if(ipr == NULL) { + 800c968: 6a3b ldr r3, [r7, #32] + 800c96a: 2b00 cmp r3, #0 + 800c96c: d11d bne.n 800c9aa + goto nullreturn; + 800c96e: e0f3 b.n 800cb58 + } + } else { + if (((ntohs(IPH_OFFSET(fraghdr)) & IP_OFFMASK) == 0) && + 800c970: 69bb ldr r3, [r7, #24] + 800c972: 799a ldrb r2, [r3, #6] + 800c974: 79db ldrb r3, [r3, #7] + 800c976: 021b lsls r3, r3, #8 + 800c978: 4313 orrs r3, r2 + 800c97a: b29b uxth r3, r3 + 800c97c: 0018 movs r0, r3 + 800c97e: f7f7 fe5f bl 8004640 + 800c982: 0003 movs r3, r0 + 800c984: 04db lsls r3, r3, #19 + 800c986: 0cdb lsrs r3, r3, #19 + 800c988: d10f bne.n 800c9aa + ((ntohs(IPH_OFFSET(&ipr->iphdr)) & IP_OFFMASK) != 0)) { + 800c98a: 6a3b ldr r3, [r7, #32] + 800c98c: 89db ldrh r3, [r3, #14] + 800c98e: 0018 movs r0, r3 + 800c990: f7f7 fe56 bl 8004640 + 800c994: 0003 movs r3, r0 + 800c996: 04db lsls r3, r3, #19 + 800c998: 0cdb lsrs r3, r3, #19 + if (((ntohs(IPH_OFFSET(fraghdr)) & IP_OFFMASK) == 0) && + 800c99a: d006 beq.n 800c9aa + /* ipr->iphdr is not the header from the first fragment, but fraghdr is + * -> copy fraghdr into ipr->iphdr since we want to have the header + * of the first fragment (for ICMP time exceeded and later, for copying + * all options, if supported)*/ + SMEMCPY(&ipr->iphdr, fraghdr, IP_HLEN); + 800c99c: 6a3b ldr r3, [r7, #32] + 800c99e: 3308 adds r3, #8 + 800c9a0: 69b9 ldr r1, [r7, #24] + 800c9a2: 2214 movs r2, #20 + 800c9a4: 0018 movs r0, r3 + 800c9a6: f003 f97c bl 800fca2 + } + } + /* Track the current number of pbufs current 'in-flight', in order to limit + the number of fragments that may be enqueued at any one time */ + ip_reass_pbufcount += clen; + 800c9aa: 2313 movs r3, #19 + 800c9ac: 18fb adds r3, r7, r3 + 800c9ae: 781b ldrb r3, [r3, #0] + 800c9b0: b29a uxth r2, r3 + 800c9b2: 4b67 ldr r3, [pc, #412] ; (800cb50 ) + 800c9b4: 881b ldrh r3, [r3, #0] + 800c9b6: 18d3 adds r3, r2, r3 + 800c9b8: b29a uxth r2, r3 + 800c9ba: 4b65 ldr r3, [pc, #404] ; (800cb50 ) + 800c9bc: 801a strh r2, [r3, #0] + + /* At this point, we have either created a new entry or pointing + * to an existing one */ + + /* check for 'no more fragments', and update queue entry*/ + if ((IPH_OFFSET(fraghdr) & PP_NTOHS(IP_MF)) == 0) { + 800c9be: 69bb ldr r3, [r7, #24] + 800c9c0: 799a ldrb r2, [r3, #6] + 800c9c2: 79db ldrb r3, [r3, #7] + 800c9c4: 021b lsls r3, r3, #8 + 800c9c6: 4313 orrs r3, r2 + 800c9c8: b29b uxth r3, r3 + 800c9ca: 001a movs r2, r3 + 800c9cc: 2320 movs r3, #32 + 800c9ce: 4013 ands r3, r2 + 800c9d0: d110 bne.n 800c9f4 + ipr->flags |= IP_REASS_FLAG_LASTFRAG; + 800c9d2: 6a3b ldr r3, [r7, #32] + 800c9d4: 7f9b ldrb r3, [r3, #30] + 800c9d6: 2201 movs r2, #1 + 800c9d8: 4313 orrs r3, r2 + 800c9da: b2da uxtb r2, r3 + 800c9dc: 6a3b ldr r3, [r7, #32] + 800c9de: 779a strb r2, [r3, #30] + ipr->datagram_len = offset + len; + 800c9e0: 2316 movs r3, #22 + 800c9e2: 18fa adds r2, r7, r3 + 800c9e4: 2314 movs r3, #20 + 800c9e6: 18fb adds r3, r7, r3 + 800c9e8: 8812 ldrh r2, [r2, #0] + 800c9ea: 881b ldrh r3, [r3, #0] + 800c9ec: 18d3 adds r3, r2, r3 + 800c9ee: b29a uxth r2, r3 + 800c9f0: 6a3b ldr r3, [r7, #32] + 800c9f2: 839a strh r2, [r3, #28] + ("ip_reass: last fragment seen, total len %"S16_F"\n", + ipr->datagram_len)); + } + /* find the right place to insert this pbuf */ + /* @todo: trim pbufs if fragments are overlapping */ + if (ip_reass_chain_frag_into_datagram_and_validate(ipr, p)) { + 800c9f4: 687a ldr r2, [r7, #4] + 800c9f6: 6a3b ldr r3, [r7, #32] + 800c9f8: 0011 movs r1, r2 + 800c9fa: 0018 movs r0, r3 + 800c9fc: f7ff fd0c bl 800c418 + 800ca00: 1e03 subs r3, r0, #0 + 800ca02: d100 bne.n 800ca06 + 800ca04: e09f b.n 800cb46 + /* the totally last fragment (flag more fragments = 0) was received at least + * once AND all fragments are received */ + ipr->datagram_len += IP_HLEN; + 800ca06: 6a3b ldr r3, [r7, #32] + 800ca08: 8b9b ldrh r3, [r3, #28] + 800ca0a: 3314 adds r3, #20 + 800ca0c: b29a uxth r2, r3 + 800ca0e: 6a3b ldr r3, [r7, #32] + 800ca10: 839a strh r2, [r3, #28] + + /* save the second pbuf before copying the header over the pointer */ + r = ((struct ip_reass_helper*)ipr->p->payload)->next_pbuf; + 800ca12: 6a3b ldr r3, [r7, #32] + 800ca14: 685b ldr r3, [r3, #4] + 800ca16: 685b ldr r3, [r3, #4] + 800ca18: 781a ldrb r2, [r3, #0] + 800ca1a: 7859 ldrb r1, [r3, #1] + 800ca1c: 0209 lsls r1, r1, #8 + 800ca1e: 430a orrs r2, r1 + 800ca20: 7899 ldrb r1, [r3, #2] + 800ca22: 0409 lsls r1, r1, #16 + 800ca24: 430a orrs r2, r1 + 800ca26: 78db ldrb r3, [r3, #3] + 800ca28: 061b lsls r3, r3, #24 + 800ca2a: 4313 orrs r3, r2 + 800ca2c: 627b str r3, [r7, #36] ; 0x24 + + /* copy the original ip header back to the first pbuf */ + fraghdr = (struct ip_hdr*)(ipr->p->payload); + 800ca2e: 6a3b ldr r3, [r7, #32] + 800ca30: 685b ldr r3, [r3, #4] + 800ca32: 685b ldr r3, [r3, #4] + 800ca34: 61bb str r3, [r7, #24] + SMEMCPY(fraghdr, &ipr->iphdr, IP_HLEN); + 800ca36: 6a3b ldr r3, [r7, #32] + 800ca38: 3308 adds r3, #8 + 800ca3a: 0019 movs r1, r3 + 800ca3c: 69bb ldr r3, [r7, #24] + 800ca3e: 2214 movs r2, #20 + 800ca40: 0018 movs r0, r3 + 800ca42: f003 f92e bl 800fca2 + IPH_LEN_SET(fraghdr, htons(ipr->datagram_len)); + 800ca46: 6a3b ldr r3, [r7, #32] + 800ca48: 8b9b ldrh r3, [r3, #28] + 800ca4a: 0018 movs r0, r3 + 800ca4c: f7f7 fde2 bl 8004614 + 800ca50: 0003 movs r3, r0 + 800ca52: 001a movs r2, r3 + 800ca54: 69bb ldr r3, [r7, #24] + 800ca56: 21ff movs r1, #255 ; 0xff + 800ca58: 4011 ands r1, r2 + 800ca5a: 000c movs r4, r1 + 800ca5c: 7899 ldrb r1, [r3, #2] + 800ca5e: 2000 movs r0, #0 + 800ca60: 4001 ands r1, r0 + 800ca62: 1c08 adds r0, r1, #0 + 800ca64: 1c21 adds r1, r4, #0 + 800ca66: 4301 orrs r1, r0 + 800ca68: 7099 strb r1, [r3, #2] + 800ca6a: 0a12 lsrs r2, r2, #8 + 800ca6c: b290 uxth r0, r2 + 800ca6e: 78da ldrb r2, [r3, #3] + 800ca70: 2100 movs r1, #0 + 800ca72: 400a ands r2, r1 + 800ca74: 1c11 adds r1, r2, #0 + 800ca76: 1c02 adds r2, r0, #0 + 800ca78: 430a orrs r2, r1 + 800ca7a: 70da strb r2, [r3, #3] + IPH_OFFSET_SET(fraghdr, 0); + 800ca7c: 69bb ldr r3, [r7, #24] + 800ca7e: 799a ldrb r2, [r3, #6] + 800ca80: 2100 movs r1, #0 + 800ca82: 400a ands r2, r1 + 800ca84: 719a strb r2, [r3, #6] + 800ca86: 79da ldrb r2, [r3, #7] + 800ca88: 2100 movs r1, #0 + 800ca8a: 400a ands r2, r1 + 800ca8c: 71da strb r2, [r3, #7] + IPH_CHKSUM_SET(fraghdr, 0); + 800ca8e: 69bb ldr r3, [r7, #24] + 800ca90: 7a9a ldrb r2, [r3, #10] + 800ca92: 2100 movs r1, #0 + 800ca94: 400a ands r2, r1 + 800ca96: 729a strb r2, [r3, #10] + 800ca98: 7ada ldrb r2, [r3, #11] + 800ca9a: 2100 movs r1, #0 + 800ca9c: 400a ands r2, r1 + 800ca9e: 72da strb r2, [r3, #11] + /* @todo: do we need to set calculate the correct checksum? */ + IPH_CHKSUM_SET(fraghdr, inet_chksum(fraghdr, IP_HLEN)); + 800caa0: 69bb ldr r3, [r7, #24] + 800caa2: 2114 movs r1, #20 + 800caa4: 0018 movs r0, r3 + 800caa6: f7fe fe63 bl 800b770 + 800caaa: 0003 movs r3, r0 + 800caac: 001a movs r2, r3 + 800caae: 69bb ldr r3, [r7, #24] + 800cab0: 21ff movs r1, #255 ; 0xff + 800cab2: 4011 ands r1, r2 + 800cab4: 000c movs r4, r1 + 800cab6: 7a99 ldrb r1, [r3, #10] + 800cab8: 2000 movs r0, #0 + 800caba: 4001 ands r1, r0 + 800cabc: 1c08 adds r0, r1, #0 + 800cabe: 1c21 adds r1, r4, #0 + 800cac0: 4301 orrs r1, r0 + 800cac2: 7299 strb r1, [r3, #10] + 800cac4: 0a12 lsrs r2, r2, #8 + 800cac6: b290 uxth r0, r2 + 800cac8: 7ada ldrb r2, [r3, #11] + 800caca: 2100 movs r1, #0 + 800cacc: 400a ands r2, r1 + 800cace: 1c11 adds r1, r2, #0 + 800cad0: 1c02 adds r2, r0, #0 + 800cad2: 430a orrs r2, r1 + 800cad4: 72da strb r2, [r3, #11] + + p = ipr->p; + 800cad6: 6a3b ldr r3, [r7, #32] + 800cad8: 685b ldr r3, [r3, #4] + 800cada: 607b str r3, [r7, #4] + + /* chain together the pbufs contained within the reass_data list. */ + while(r != NULL) { + 800cadc: e01b b.n 800cb16 + iprh = (struct ip_reass_helper*)r->payload; + 800cade: 6a7b ldr r3, [r7, #36] ; 0x24 + 800cae0: 685b ldr r3, [r3, #4] + 800cae2: 60fb str r3, [r7, #12] + + /* hide the ip header for every succeding fragment */ + pbuf_header(r, -IP_HLEN); + 800cae4: 2314 movs r3, #20 + 800cae6: 425a negs r2, r3 + 800cae8: 6a7b ldr r3, [r7, #36] ; 0x24 + 800caea: 0011 movs r1, r2 + 800caec: 0018 movs r0, r3 + 800caee: f7f8 fd52 bl 8005596 + pbuf_cat(p, r); + 800caf2: 6a7a ldr r2, [r7, #36] ; 0x24 + 800caf4: 687b ldr r3, [r7, #4] + 800caf6: 0011 movs r1, r2 + 800caf8: 0018 movs r0, r3 + 800cafa: f7f8 fe72 bl 80057e2 + r = iprh->next_pbuf; + 800cafe: 68fb ldr r3, [r7, #12] + 800cb00: 781a ldrb r2, [r3, #0] + 800cb02: 7859 ldrb r1, [r3, #1] + 800cb04: 0209 lsls r1, r1, #8 + 800cb06: 430a orrs r2, r1 + 800cb08: 7899 ldrb r1, [r3, #2] + 800cb0a: 0409 lsls r1, r1, #16 + 800cb0c: 430a orrs r2, r1 + 800cb0e: 78db ldrb r3, [r3, #3] + 800cb10: 061b lsls r3, r3, #24 + 800cb12: 4313 orrs r3, r2 + 800cb14: 627b str r3, [r7, #36] ; 0x24 + while(r != NULL) { + 800cb16: 6a7b ldr r3, [r7, #36] ; 0x24 + 800cb18: 2b00 cmp r3, #0 + 800cb1a: d1e0 bne.n 800cade + } + /* release the sources allocate for the fragment queue entry */ + ip_reass_dequeue_datagram(ipr, ipr_prev); + 800cb1c: 69fa ldr r2, [r7, #28] + 800cb1e: 6a3b ldr r3, [r7, #32] + 800cb20: 0011 movs r1, r2 + 800cb22: 0018 movs r0, r3 + 800cb24: f7ff fc5a bl 800c3dc + + /* and adjust the number of pbufs currently queued for reassembly. */ + ip_reass_pbufcount -= pbuf_clen(p); + 800cb28: 687b ldr r3, [r7, #4] + 800cb2a: 0018 movs r0, r3 + 800cb2c: f7f8 fe2c bl 8005788 + 800cb30: 0003 movs r3, r0 + 800cb32: 0019 movs r1, r3 + 800cb34: 4b06 ldr r3, [pc, #24] ; (800cb50 ) + 800cb36: 881a ldrh r2, [r3, #0] + 800cb38: b28b uxth r3, r1 + 800cb3a: 1ad3 subs r3, r2, r3 + 800cb3c: b29a uxth r2, r3 + 800cb3e: 4b04 ldr r3, [pc, #16] ; (800cb50 ) + 800cb40: 801a strh r2, [r3, #0] + + /* Return the pbuf chain */ + return p; + 800cb42: 687b ldr r3, [r7, #4] + 800cb44: e013 b.n 800cb6e + } + /* the datagram is not (yet?) reassembled completely */ + LWIP_DEBUGF(IP_REASS_DEBUG,("ip_reass_pbufcount: %d out\n", ip_reass_pbufcount)); + return NULL; + 800cb46: 2300 movs r3, #0 + 800cb48: e011 b.n 800cb6e + 800cb4a: 46c0 nop ; (mov r8, r8) + 800cb4c: 20003158 .word 0x20003158 + 800cb50: 200022bc .word 0x200022bc + 800cb54: 200022b8 .word 0x200022b8 + +nullreturn: + LWIP_DEBUGF(IP_REASS_DEBUG,("ip_reass: nullreturn\n")); + IPFRAG_STATS_INC(ip_frag.drop); + 800cb58: 4b07 ldr r3, [pc, #28] ; (800cb78 ) + 800cb5a: 8edb ldrh r3, [r3, #54] ; 0x36 + 800cb5c: 3301 adds r3, #1 + 800cb5e: b29a uxth r2, r3 + 800cb60: 4b05 ldr r3, [pc, #20] ; (800cb78 ) + 800cb62: 86da strh r2, [r3, #54] ; 0x36 + pbuf_free(p); + 800cb64: 687b ldr r3, [r7, #4] + 800cb66: 0018 movs r0, r3 + 800cb68: f7f8 fd9c bl 80056a4 + return NULL; + 800cb6c: 2300 movs r3, #0 +} + 800cb6e: 0018 movs r0, r3 + 800cb70: 46bd mov sp, r7 + 800cb72: b00a add sp, #40 ; 0x28 + 800cb74: bdb0 pop {r4, r5, r7, pc} + 800cb76: 46c0 nop ; (mov r8, r8) + 800cb78: 20003158 .word 0x20003158 + +0800cb7c : + +#if !LWIP_NETIF_TX_SINGLE_PBUF +/** Allocate a new struct pbuf_custom_ref */ +static struct pbuf_custom_ref* +ip_frag_alloc_pbuf_custom_ref(void) +{ + 800cb7c: b580 push {r7, lr} + 800cb7e: af00 add r7, sp, #0 + return (struct pbuf_custom_ref*)memp_malloc(MEMP_FRAG_PBUF); + 800cb80: 2006 movs r0, #6 + 800cb82: f7f8 f947 bl 8004e14 + 800cb86: 0003 movs r3, r0 +} + 800cb88: 0018 movs r0, r3 + 800cb8a: 46bd mov sp, r7 + 800cb8c: bd80 pop {r7, pc} + +0800cb8e : + +/** Free a struct pbuf_custom_ref */ +static void +ip_frag_free_pbuf_custom_ref(struct pbuf_custom_ref* p) +{ + 800cb8e: b580 push {r7, lr} + 800cb90: b082 sub sp, #8 + 800cb92: af00 add r7, sp, #0 + 800cb94: 6078 str r0, [r7, #4] + LWIP_ASSERT("p != NULL", p != NULL); + memp_free(MEMP_FRAG_PBUF, p); + 800cb96: 687b ldr r3, [r7, #4] + 800cb98: 0019 movs r1, r3 + 800cb9a: 2006 movs r0, #6 + 800cb9c: f7f8 f9c0 bl 8004f20 +} + 800cba0: 46c0 nop ; (mov r8, r8) + 800cba2: 46bd mov sp, r7 + 800cba4: b002 add sp, #8 + 800cba6: bd80 pop {r7, pc} + +0800cba8 : + +/** Free-callback function to free a 'struct pbuf_custom_ref', called by + * pbuf_free. */ +static void +ipfrag_free_pbuf_custom(struct pbuf *p) +{ + 800cba8: b580 push {r7, lr} + 800cbaa: b084 sub sp, #16 + 800cbac: af00 add r7, sp, #0 + 800cbae: 6078 str r0, [r7, #4] + struct pbuf_custom_ref *pcr = (struct pbuf_custom_ref*)p; + 800cbb0: 687b ldr r3, [r7, #4] + 800cbb2: 60fb str r3, [r7, #12] + LWIP_ASSERT("pcr != NULL", pcr != NULL); + LWIP_ASSERT("pcr == p", (void*)pcr == (void*)p); + if (pcr->original != NULL) { + 800cbb4: 68fb ldr r3, [r7, #12] + 800cbb6: 695b ldr r3, [r3, #20] + 800cbb8: 2b00 cmp r3, #0 + 800cbba: d004 beq.n 800cbc6 + pbuf_free(pcr->original); + 800cbbc: 68fb ldr r3, [r7, #12] + 800cbbe: 695b ldr r3, [r3, #20] + 800cbc0: 0018 movs r0, r3 + 800cbc2: f7f8 fd6f bl 80056a4 + } + ip_frag_free_pbuf_custom_ref(pcr); + 800cbc6: 68fb ldr r3, [r7, #12] + 800cbc8: 0018 movs r0, r3 + 800cbca: f7ff ffe0 bl 800cb8e +} + 800cbce: 46c0 nop ; (mov r8, r8) + 800cbd0: 46bd mov sp, r7 + 800cbd2: b004 add sp, #16 + 800cbd4: bd80 pop {r7, pc} + ... + +0800cbd8 : + * + * @return ERR_OK if sent successfully, err_t otherwise + */ +err_t +ip_frag(struct pbuf *p, struct netif *netif, ip_addr_t *dest) +{ + 800cbd8: b5f0 push {r4, r5, r6, r7, lr} + 800cbda: b093 sub sp, #76 ; 0x4c + 800cbdc: af02 add r7, sp, #8 + 800cbde: 60f8 str r0, [r7, #12] + 800cbe0: 60b9 str r1, [r7, #8] + 800cbe2: 607a str r2, [r7, #4] + struct ip_hdr *original_iphdr; +#endif + struct ip_hdr *iphdr; + u16_t nfb; + u16_t left, cop; + u16_t mtu = netif->mtu; + 800cbe4: 2632 movs r6, #50 ; 0x32 + 800cbe6: 19bb adds r3, r7, r6 + 800cbe8: 68ba ldr r2, [r7, #8] + 800cbea: 8c12 ldrh r2, [r2, #32] + 800cbec: 801a strh r2, [r3, #0] + u16_t ofo, omf; + u16_t last; + u16_t poff = IP_HLEN; + 800cbee: 233a movs r3, #58 ; 0x3a + 800cbf0: 18fb adds r3, r7, r3 + 800cbf2: 2214 movs r2, #20 + 800cbf4: 801a strh r2, [r3, #0] + u16_t tmp; +#if !IP_FRAG_USES_STATIC_BUF && !LWIP_NETIF_TX_SINGLE_PBUF + u16_t newpbuflen = 0; + 800cbf6: 2336 movs r3, #54 ; 0x36 + 800cbf8: 18fb adds r3, r7, r3 + 800cbfa: 2200 movs r2, #0 + 800cbfc: 801a strh r2, [r3, #0] + + /* Copy the IP header in it */ + iphdr = (struct ip_hdr *)rambuf->payload; + SMEMCPY(iphdr, p->payload, IP_HLEN); +#else /* IP_FRAG_USES_STATIC_BUF */ + original_iphdr = (struct ip_hdr *)p->payload; + 800cbfe: 68fb ldr r3, [r7, #12] + 800cc00: 685b ldr r3, [r3, #4] + 800cc02: 62fb str r3, [r7, #44] ; 0x2c + iphdr = original_iphdr; + 800cc04: 6afb ldr r3, [r7, #44] ; 0x2c + 800cc06: 62bb str r3, [r7, #40] ; 0x28 +#endif /* IP_FRAG_USES_STATIC_BUF */ + + /* Save original offset */ + tmp = ntohs(IPH_OFFSET(iphdr)); + 800cc08: 6abb ldr r3, [r7, #40] ; 0x28 + 800cc0a: 799a ldrb r2, [r3, #6] + 800cc0c: 79db ldrb r3, [r3, #7] + 800cc0e: 021b lsls r3, r3, #8 + 800cc10: 4313 orrs r3, r2 + 800cc12: b29b uxth r3, r3 + 800cc14: 2138 movs r1, #56 ; 0x38 + 800cc16: 000d movs r5, r1 + 800cc18: 187c adds r4, r7, r1 + 800cc1a: 0018 movs r0, r3 + 800cc1c: f7f7 fd10 bl 8004640 + 800cc20: 0003 movs r3, r0 + 800cc22: 8023 strh r3, [r4, #0] + ofo = tmp & IP_OFFMASK; + 800cc24: 233c movs r3, #60 ; 0x3c + 800cc26: 18fb adds r3, r7, r3 + 800cc28: 0029 movs r1, r5 + 800cc2a: 187a adds r2, r7, r1 + 800cc2c: 8812 ldrh r2, [r2, #0] + 800cc2e: 04d2 lsls r2, r2, #19 + 800cc30: 0cd2 lsrs r2, r2, #19 + 800cc32: 801a strh r2, [r3, #0] + omf = tmp & IP_MF; + 800cc34: 2326 movs r3, #38 ; 0x26 + 800cc36: 18fb adds r3, r7, r3 + 800cc38: 187a adds r2, r7, r1 + 800cc3a: 8811 ldrh r1, [r2, #0] + 800cc3c: 2280 movs r2, #128 ; 0x80 + 800cc3e: 0192 lsls r2, r2, #6 + 800cc40: 400a ands r2, r1 + 800cc42: 801a strh r2, [r3, #0] + + left = p->tot_len - IP_HLEN; + 800cc44: 68fb ldr r3, [r7, #12] + 800cc46: 891a ldrh r2, [r3, #8] + 800cc48: 233e movs r3, #62 ; 0x3e + 800cc4a: 18fb adds r3, r7, r3 + 800cc4c: 3a14 subs r2, #20 + 800cc4e: 801a strh r2, [r3, #0] + + nfb = (mtu - IP_HLEN) / 8; + 800cc50: 19bb adds r3, r7, r6 + 800cc52: 881b ldrh r3, [r3, #0] + 800cc54: 3b14 subs r3, #20 + 800cc56: 2b00 cmp r3, #0 + 800cc58: da00 bge.n 800cc5c + 800cc5a: 3307 adds r3, #7 + 800cc5c: 10db asrs r3, r3, #3 + 800cc5e: 001a movs r2, r3 + 800cc60: 2324 movs r3, #36 ; 0x24 + 800cc62: 18fb adds r3, r7, r3 + 800cc64: 801a strh r2, [r3, #0] + + while (left) { + 800cc66: e15a b.n 800cf1e + last = (left <= mtu - IP_HLEN); + 800cc68: 233e movs r3, #62 ; 0x3e + 800cc6a: 18fb adds r3, r7, r3 + 800cc6c: 881b ldrh r3, [r3, #0] + 800cc6e: 2232 movs r2, #50 ; 0x32 + 800cc70: 18ba adds r2, r7, r2 + 800cc72: 8812 ldrh r2, [r2, #0] + 800cc74: 3a14 subs r2, #20 + 800cc76: 0fd8 lsrs r0, r3, #31 + 800cc78: 17d1 asrs r1, r2, #31 + 800cc7a: 429a cmp r2, r3 + 800cc7c: 4148 adcs r0, r1 + 800cc7e: 0003 movs r3, r0 + 800cc80: b2da uxtb r2, r3 + 800cc82: 2022 movs r0, #34 ; 0x22 + 800cc84: 183b adds r3, r7, r0 + 800cc86: 801a strh r2, [r3, #0] + + /* Set new offset and MF flag */ + tmp = omf | (IP_OFFMASK & (ofo)); + 800cc88: 233c movs r3, #60 ; 0x3c + 800cc8a: 18fb adds r3, r7, r3 + 800cc8c: 881b ldrh r3, [r3, #0] + 800cc8e: 04db lsls r3, r3, #19 + 800cc90: 0cdb lsrs r3, r3, #19 + 800cc92: b299 uxth r1, r3 + 800cc94: 2338 movs r3, #56 ; 0x38 + 800cc96: 18fb adds r3, r7, r3 + 800cc98: 2226 movs r2, #38 ; 0x26 + 800cc9a: 18ba adds r2, r7, r2 + 800cc9c: 8812 ldrh r2, [r2, #0] + 800cc9e: 430a orrs r2, r1 + 800cca0: 801a strh r2, [r3, #0] + if (!last) { + 800cca2: 183b adds r3, r7, r0 + 800cca4: 881b ldrh r3, [r3, #0] + 800cca6: 2b00 cmp r3, #0 + 800cca8: d107 bne.n 800ccba + tmp = tmp | IP_MF; + 800ccaa: 2238 movs r2, #56 ; 0x38 + 800ccac: 18bb adds r3, r7, r2 + 800ccae: 18ba adds r2, r7, r2 + 800ccb0: 8812 ldrh r2, [r2, #0] + 800ccb2: 2180 movs r1, #128 ; 0x80 + 800ccb4: 0189 lsls r1, r1, #6 + 800ccb6: 430a orrs r2, r1 + 800ccb8: 801a strh r2, [r3, #0] + } + + /* Fill this fragment */ + cop = last ? left : nfb * 8; + 800ccba: 2322 movs r3, #34 ; 0x22 + 800ccbc: 18fb adds r3, r7, r3 + 800ccbe: 881b ldrh r3, [r3, #0] + 800ccc0: 2b00 cmp r3, #0 + 800ccc2: d105 bne.n 800ccd0 + 800ccc4: 2324 movs r3, #36 ; 0x24 + 800ccc6: 18fb adds r3, r7, r3 + 800ccc8: 881b ldrh r3, [r3, #0] + 800ccca: 00db lsls r3, r3, #3 + 800cccc: b29b uxth r3, r3 + 800ccce: e002 b.n 800ccd6 + 800ccd0: 233e movs r3, #62 ; 0x3e + 800ccd2: 18fb adds r3, r7, r3 + 800ccd4: 881b ldrh r3, [r3, #0] + 800ccd6: 2220 movs r2, #32 + 800ccd8: 18ba adds r2, r7, r2 + 800ccda: 8013 strh r3, [r2, #0] + /* When not using a static buffer, create a chain of pbufs. + * The first will be a PBUF_RAM holding the link and IP header. + * The rest will be PBUF_REFs mirroring the pbuf chain to be fragged, + * but limited to the size of an mtu. + */ + rambuf = pbuf_alloc(PBUF_LINK, IP_HLEN, PBUF_RAM); + 800ccdc: 2200 movs r2, #0 + 800ccde: 2114 movs r1, #20 + 800cce0: 2002 movs r0, #2 + 800cce2: f7f8 fa53 bl 800518c + 800cce6: 0003 movs r3, r0 + 800cce8: 61fb str r3, [r7, #28] + if (rambuf == NULL) { + 800ccea: 69fb ldr r3, [r7, #28] + 800ccec: 2b00 cmp r3, #0 + 800ccee: d102 bne.n 800ccf6 + return ERR_MEM; + 800ccf0: 2301 movs r3, #1 + 800ccf2: 425b negs r3, r3 + 800ccf4: e11a b.n 800cf2c + } + LWIP_ASSERT("this needs a pbuf in one piece!", + (p->len >= (IP_HLEN))); + SMEMCPY(rambuf->payload, original_iphdr, IP_HLEN); + 800ccf6: 69fb ldr r3, [r7, #28] + 800ccf8: 685b ldr r3, [r3, #4] + 800ccfa: 6af9 ldr r1, [r7, #44] ; 0x2c + 800ccfc: 2214 movs r2, #20 + 800ccfe: 0018 movs r0, r3 + 800cd00: f002 ffcf bl 800fca2 + iphdr = (struct ip_hdr *)rambuf->payload; + 800cd04: 69fb ldr r3, [r7, #28] + 800cd06: 685b ldr r3, [r3, #4] + 800cd08: 62bb str r3, [r7, #40] ; 0x28 + + /* Can just adjust p directly for needed offset. */ + p->payload = (u8_t *)p->payload + poff; + 800cd0a: 68fb ldr r3, [r7, #12] + 800cd0c: 685a ldr r2, [r3, #4] + 800cd0e: 213a movs r1, #58 ; 0x3a + 800cd10: 187b adds r3, r7, r1 + 800cd12: 881b ldrh r3, [r3, #0] + 800cd14: 18d2 adds r2, r2, r3 + 800cd16: 68fb ldr r3, [r7, #12] + 800cd18: 605a str r2, [r3, #4] + p->len -= poff; + 800cd1a: 68fb ldr r3, [r7, #12] + 800cd1c: 895a ldrh r2, [r3, #10] + 800cd1e: 187b adds r3, r7, r1 + 800cd20: 881b ldrh r3, [r3, #0] + 800cd22: 1ad3 subs r3, r2, r3 + 800cd24: b29a uxth r2, r3 + 800cd26: 68fb ldr r3, [r7, #12] + 800cd28: 815a strh r2, [r3, #10] + + left_to_copy = cop; + 800cd2a: 2334 movs r3, #52 ; 0x34 + 800cd2c: 18fb adds r3, r7, r3 + 800cd2e: 2220 movs r2, #32 + 800cd30: 18ba adds r2, r7, r2 + 800cd32: 8812 ldrh r2, [r2, #0] + 800cd34: 801a strh r2, [r3, #0] + while (left_to_copy) { + 800cd36: e068 b.n 800ce0a + struct pbuf_custom_ref *pcr; + newpbuflen = (left_to_copy < p->len) ? left_to_copy : p->len; + 800cd38: 68fb ldr r3, [r7, #12] + 800cd3a: 8959 ldrh r1, [r3, #10] + 800cd3c: 2336 movs r3, #54 ; 0x36 + 800cd3e: 18fa adds r2, r7, r3 + 800cd40: 2334 movs r3, #52 ; 0x34 + 800cd42: 18fb adds r3, r7, r3 + 800cd44: 1c0c adds r4, r1, #0 + 800cd46: 881b ldrh r3, [r3, #0] + 800cd48: b298 uxth r0, r3 + 800cd4a: b2a1 uxth r1, r4 + 800cd4c: 4288 cmp r0, r1 + 800cd4e: d900 bls.n 800cd52 + 800cd50: 1c23 adds r3, r4, #0 + 800cd52: 8013 strh r3, [r2, #0] + /* Is this pbuf already empty? */ + if (!newpbuflen) { + 800cd54: 2336 movs r3, #54 ; 0x36 + 800cd56: 18fb adds r3, r7, r3 + 800cd58: 881b ldrh r3, [r3, #0] + 800cd5a: 2b00 cmp r3, #0 + 800cd5c: d108 bne.n 800cd70 + p = p->next; + 800cd5e: 68fb ldr r3, [r7, #12] + 800cd60: 681b ldr r3, [r3, #0] + 800cd62: 60fb str r3, [r7, #12] + 800cd64: 2234 movs r2, #52 ; 0x34 + 800cd66: 18bb adds r3, r7, r2 + 800cd68: 18ba adds r2, r7, r2 + 800cd6a: 8812 ldrh r2, [r2, #0] + 800cd6c: 801a strh r2, [r3, #0] + continue; + 800cd6e: e04c b.n 800ce0a + } + pcr = ip_frag_alloc_pbuf_custom_ref(); + 800cd70: f7ff ff04 bl 800cb7c + 800cd74: 0003 movs r3, r0 + 800cd76: 61bb str r3, [r7, #24] + if (pcr == NULL) { + 800cd78: 69bb ldr r3, [r7, #24] + 800cd7a: 2b00 cmp r3, #0 + 800cd7c: d106 bne.n 800cd8c + pbuf_free(rambuf); + 800cd7e: 69fb ldr r3, [r7, #28] + 800cd80: 0018 movs r0, r3 + 800cd82: f7f8 fc8f bl 80056a4 + return ERR_MEM; + 800cd86: 2301 movs r3, #1 + 800cd88: 425b negs r3, r3 + 800cd8a: e0cf b.n 800cf2c + } + /* Mirror this pbuf, although we might not need all of it. */ + newpbuf = pbuf_alloced_custom(PBUF_RAW, newpbuflen, PBUF_REF, &pcr->pc, p->payload, newpbuflen); + 800cd8c: 69b8 ldr r0, [r7, #24] + 800cd8e: 68fb ldr r3, [r7, #12] + 800cd90: 685b ldr r3, [r3, #4] + 800cd92: 2436 movs r4, #54 ; 0x36 + 800cd94: 193a adds r2, r7, r4 + 800cd96: 8811 ldrh r1, [r2, #0] + 800cd98: 193a adds r2, r7, r4 + 800cd9a: 8812 ldrh r2, [r2, #0] + 800cd9c: 9201 str r2, [sp, #4] + 800cd9e: 9300 str r3, [sp, #0] + 800cda0: 0003 movs r3, r0 + 800cda2: 2202 movs r2, #2 + 800cda4: 2003 movs r0, #3 + 800cda6: f7f8 fb13 bl 80053d0 + 800cdaa: 0003 movs r3, r0 + 800cdac: 617b str r3, [r7, #20] + if (newpbuf == NULL) { + 800cdae: 697b ldr r3, [r7, #20] + 800cdb0: 2b00 cmp r3, #0 + 800cdb2: d10a bne.n 800cdca + ip_frag_free_pbuf_custom_ref(pcr); + 800cdb4: 69bb ldr r3, [r7, #24] + 800cdb6: 0018 movs r0, r3 + 800cdb8: f7ff fee9 bl 800cb8e + pbuf_free(rambuf); + 800cdbc: 69fb ldr r3, [r7, #28] + 800cdbe: 0018 movs r0, r3 + 800cdc0: f7f8 fc70 bl 80056a4 + return ERR_MEM; + 800cdc4: 2301 movs r3, #1 + 800cdc6: 425b negs r3, r3 + 800cdc8: e0b0 b.n 800cf2c + } + pbuf_ref(p); + 800cdca: 68fb ldr r3, [r7, #12] + 800cdcc: 0018 movs r0, r3 + 800cdce: f7f8 fcf7 bl 80057c0 + pcr->original = p; + 800cdd2: 69bb ldr r3, [r7, #24] + 800cdd4: 68fa ldr r2, [r7, #12] + 800cdd6: 615a str r2, [r3, #20] + pcr->pc.custom_free_function = ipfrag_free_pbuf_custom; + 800cdd8: 69bb ldr r3, [r7, #24] + 800cdda: 4a56 ldr r2, [pc, #344] ; (800cf34 ) + 800cddc: 611a str r2, [r3, #16] + + /* Add it to end of rambuf's chain, but using pbuf_cat, not pbuf_chain + * so that it is removed when pbuf_dechain is later called on rambuf. + */ + pbuf_cat(rambuf, newpbuf); + 800cdde: 697a ldr r2, [r7, #20] + 800cde0: 69fb ldr r3, [r7, #28] + 800cde2: 0011 movs r1, r2 + 800cde4: 0018 movs r0, r3 + 800cde6: f7f8 fcfc bl 80057e2 + left_to_copy -= newpbuflen; + 800cdea: 2034 movs r0, #52 ; 0x34 + 800cdec: 183b adds r3, r7, r0 + 800cdee: 1839 adds r1, r7, r0 + 800cdf0: 2236 movs r2, #54 ; 0x36 + 800cdf2: 18ba adds r2, r7, r2 + 800cdf4: 8809 ldrh r1, [r1, #0] + 800cdf6: 8812 ldrh r2, [r2, #0] + 800cdf8: 1a8a subs r2, r1, r2 + 800cdfa: 801a strh r2, [r3, #0] + if (left_to_copy) { + 800cdfc: 183b adds r3, r7, r0 + 800cdfe: 881b ldrh r3, [r3, #0] + 800ce00: 2b00 cmp r3, #0 + 800ce02: d002 beq.n 800ce0a + p = p->next; + 800ce04: 68fb ldr r3, [r7, #12] + 800ce06: 681b ldr r3, [r3, #0] + 800ce08: 60fb str r3, [r7, #12] + while (left_to_copy) { + 800ce0a: 2334 movs r3, #52 ; 0x34 + 800ce0c: 18fb adds r3, r7, r3 + 800ce0e: 881b ldrh r3, [r3, #0] + 800ce10: 2b00 cmp r3, #0 + 800ce12: d191 bne.n 800cd38 + } + } + poff = newpbuflen; + 800ce14: 233a movs r3, #58 ; 0x3a + 800ce16: 18fb adds r3, r7, r3 + 800ce18: 2236 movs r2, #54 ; 0x36 + 800ce1a: 18ba adds r2, r7, r2 + 800ce1c: 8812 ldrh r2, [r2, #0] + 800ce1e: 801a strh r2, [r3, #0] +#endif /* LWIP_NETIF_TX_SINGLE_PBUF */ +#endif /* IP_FRAG_USES_STATIC_BUF */ + + /* Correct header */ + IPH_OFFSET_SET(iphdr, htons(tmp)); + 800ce20: 2338 movs r3, #56 ; 0x38 + 800ce22: 18fb adds r3, r7, r3 + 800ce24: 881b ldrh r3, [r3, #0] + 800ce26: 0018 movs r0, r3 + 800ce28: f7f7 fbf4 bl 8004614 + 800ce2c: 0003 movs r3, r0 + 800ce2e: 001a movs r2, r3 + 800ce30: 6abb ldr r3, [r7, #40] ; 0x28 + 800ce32: 21ff movs r1, #255 ; 0xff + 800ce34: 4011 ands r1, r2 + 800ce36: 000c movs r4, r1 + 800ce38: 7999 ldrb r1, [r3, #6] + 800ce3a: 2000 movs r0, #0 + 800ce3c: 4001 ands r1, r0 + 800ce3e: 1c08 adds r0, r1, #0 + 800ce40: 1c21 adds r1, r4, #0 + 800ce42: 4301 orrs r1, r0 + 800ce44: 7199 strb r1, [r3, #6] + 800ce46: 0a12 lsrs r2, r2, #8 + 800ce48: b290 uxth r0, r2 + 800ce4a: 79da ldrb r2, [r3, #7] + 800ce4c: 2100 movs r1, #0 + 800ce4e: 400a ands r2, r1 + 800ce50: 1c11 adds r1, r2, #0 + 800ce52: 1c02 adds r2, r0, #0 + 800ce54: 430a orrs r2, r1 + 800ce56: 71da strb r2, [r3, #7] + IPH_LEN_SET(iphdr, htons(cop + IP_HLEN)); + 800ce58: 2520 movs r5, #32 + 800ce5a: 197b adds r3, r7, r5 + 800ce5c: 881b ldrh r3, [r3, #0] + 800ce5e: 3314 adds r3, #20 + 800ce60: b29b uxth r3, r3 + 800ce62: 0018 movs r0, r3 + 800ce64: f7f7 fbd6 bl 8004614 + 800ce68: 0003 movs r3, r0 + 800ce6a: 001a movs r2, r3 + 800ce6c: 6abb ldr r3, [r7, #40] ; 0x28 + 800ce6e: 21ff movs r1, #255 ; 0xff + 800ce70: 4011 ands r1, r2 + 800ce72: 000c movs r4, r1 + 800ce74: 7899 ldrb r1, [r3, #2] + 800ce76: 2000 movs r0, #0 + 800ce78: 4001 ands r1, r0 + 800ce7a: 1c08 adds r0, r1, #0 + 800ce7c: 1c21 adds r1, r4, #0 + 800ce7e: 4301 orrs r1, r0 + 800ce80: 7099 strb r1, [r3, #2] + 800ce82: 0a12 lsrs r2, r2, #8 + 800ce84: b290 uxth r0, r2 + 800ce86: 78da ldrb r2, [r3, #3] + 800ce88: 2100 movs r1, #0 + 800ce8a: 400a ands r2, r1 + 800ce8c: 1c11 adds r1, r2, #0 + 800ce8e: 1c02 adds r2, r0, #0 + 800ce90: 430a orrs r2, r1 + 800ce92: 70da strb r2, [r3, #3] + IPH_CHKSUM_SET(iphdr, 0); + 800ce94: 6abb ldr r3, [r7, #40] ; 0x28 + 800ce96: 7a9a ldrb r2, [r3, #10] + 800ce98: 2100 movs r1, #0 + 800ce9a: 400a ands r2, r1 + 800ce9c: 729a strb r2, [r3, #10] + 800ce9e: 7ada ldrb r2, [r3, #11] + 800cea0: 2100 movs r1, #0 + 800cea2: 400a ands r2, r1 + 800cea4: 72da strb r2, [r3, #11] + IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, IP_HLEN)); + 800cea6: 6abb ldr r3, [r7, #40] ; 0x28 + 800cea8: 2114 movs r1, #20 + 800ceaa: 0018 movs r0, r3 + 800ceac: f7fe fc60 bl 800b770 + 800ceb0: 0003 movs r3, r0 + 800ceb2: 001a movs r2, r3 + 800ceb4: 6abb ldr r3, [r7, #40] ; 0x28 + 800ceb6: 21ff movs r1, #255 ; 0xff + 800ceb8: 4011 ands r1, r2 + 800ceba: 000c movs r4, r1 + 800cebc: 7a99 ldrb r1, [r3, #10] + 800cebe: 2000 movs r0, #0 + 800cec0: 4001 ands r1, r0 + 800cec2: 1c08 adds r0, r1, #0 + 800cec4: 1c21 adds r1, r4, #0 + 800cec6: 4301 orrs r1, r0 + 800cec8: 7299 strb r1, [r3, #10] + 800ceca: 0a12 lsrs r2, r2, #8 + 800cecc: b290 uxth r0, r2 + 800cece: 7ada ldrb r2, [r3, #11] + 800ced0: 2100 movs r1, #0 + 800ced2: 400a ands r2, r1 + 800ced4: 1c11 adds r1, r2, #0 + 800ced6: 1c02 adds r2, r0, #0 + 800ced8: 430a orrs r2, r1 + 800ceda: 72da strb r2, [r3, #11] + } +#else /* IP_FRAG_USES_STATIC_BUF */ + /* No need for separate header pbuf - we allowed room for it in rambuf + * when allocated. + */ + netif->output(netif, rambuf, dest); + 800cedc: 68bb ldr r3, [r7, #8] + 800cede: 695b ldr r3, [r3, #20] + 800cee0: 687a ldr r2, [r7, #4] + 800cee2: 69f9 ldr r1, [r7, #28] + 800cee4: 68b8 ldr r0, [r7, #8] + 800cee6: 4798 blx r3 + IPFRAG_STATS_INC(ip_frag.xmit); + 800cee8: 4b13 ldr r3, [pc, #76] ; (800cf38 ) + 800ceea: 8e1b ldrh r3, [r3, #48] ; 0x30 + 800ceec: 3301 adds r3, #1 + 800ceee: b29a uxth r2, r3 + 800cef0: 4b11 ldr r3, [pc, #68] ; (800cf38 ) + 800cef2: 861a strh r2, [r3, #48] ; 0x30 + * recreate it next time round the loop. If we're lucky the hardware + * will have already sent the packet, the free will really free, and + * there will be zero memory penalty. + */ + + pbuf_free(rambuf); + 800cef4: 69fb ldr r3, [r7, #28] + 800cef6: 0018 movs r0, r3 + 800cef8: f7f8 fbd4 bl 80056a4 +#endif /* IP_FRAG_USES_STATIC_BUF */ + left -= cop; + 800cefc: 223e movs r2, #62 ; 0x3e + 800cefe: 18bb adds r3, r7, r2 + 800cf00: 18b9 adds r1, r7, r2 + 800cf02: 197a adds r2, r7, r5 + 800cf04: 8809 ldrh r1, [r1, #0] + 800cf06: 8812 ldrh r2, [r2, #0] + 800cf08: 1a8a subs r2, r1, r2 + 800cf0a: 801a strh r2, [r3, #0] + ofo += nfb; + 800cf0c: 223c movs r2, #60 ; 0x3c + 800cf0e: 18bb adds r3, r7, r2 + 800cf10: 18b9 adds r1, r7, r2 + 800cf12: 2224 movs r2, #36 ; 0x24 + 800cf14: 18ba adds r2, r7, r2 + 800cf16: 8809 ldrh r1, [r1, #0] + 800cf18: 8812 ldrh r2, [r2, #0] + 800cf1a: 188a adds r2, r1, r2 + 800cf1c: 801a strh r2, [r3, #0] + while (left) { + 800cf1e: 233e movs r3, #62 ; 0x3e + 800cf20: 18fb adds r3, r7, r3 + 800cf22: 881b ldrh r3, [r3, #0] + 800cf24: 2b00 cmp r3, #0 + 800cf26: d000 beq.n 800cf2a + 800cf28: e69e b.n 800cc68 + } +#if IP_FRAG_USES_STATIC_BUF + pbuf_free(rambuf); +#endif /* IP_FRAG_USES_STATIC_BUF */ + snmp_inc_ipfragoks(); + return ERR_OK; + 800cf2a: 2300 movs r3, #0 +} + 800cf2c: 0018 movs r0, r3 + 800cf2e: 46bd mov sp, r7 + 800cf30: b011 add sp, #68 ; 0x44 + 800cf32: bdf0 pop {r4, r5, r6, r7, pc} + 800cf34: 0800cba9 .word 0x0800cba9 + 800cf38: 20003158 .word 0x20003158 + +0800cf3c : +#endif /* ARP_QUEUEING */ + +/** Clean up ARP table entries */ +static void +etharp_free_entry(int i) +{ + 800cf3c: b580 push {r7, lr} + 800cf3e: b082 sub sp, #8 + 800cf40: af00 add r7, sp, #0 + 800cf42: 6078 str r0, [r7, #4] + /* remove from SNMP ARP index tree */ + snmp_delete_arpidx_tree(arp_table[i].netif, &arp_table[i].ipaddr); + /* and empty packet queue */ + if (arp_table[i].q != NULL) { + 800cf44: 4914 ldr r1, [pc, #80] ; (800cf98 ) + 800cf46: 687a ldr r2, [r7, #4] + 800cf48: 0013 movs r3, r2 + 800cf4a: 009b lsls r3, r3, #2 + 800cf4c: 189b adds r3, r3, r2 + 800cf4e: 009b lsls r3, r3, #2 + 800cf50: 585b ldr r3, [r3, r1] + 800cf52: 2b00 cmp r3, #0 + 800cf54: d011 beq.n 800cf7a + /* remove all queued packets */ + LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_free_entry: freeing entry %"U16_F", packet queue %p.\n", (u16_t)i, (void *)(arp_table[i].q))); + free_etharp_q(arp_table[i].q); + 800cf56: 4910 ldr r1, [pc, #64] ; (800cf98 ) + 800cf58: 687a ldr r2, [r7, #4] + 800cf5a: 0013 movs r3, r2 + 800cf5c: 009b lsls r3, r3, #2 + 800cf5e: 189b adds r3, r3, r2 + 800cf60: 009b lsls r3, r3, #2 + 800cf62: 585b ldr r3, [r3, r1] + 800cf64: 0018 movs r0, r3 + 800cf66: f7f8 fb9d bl 80056a4 + arp_table[i].q = NULL; + 800cf6a: 490b ldr r1, [pc, #44] ; (800cf98 ) + 800cf6c: 687a ldr r2, [r7, #4] + 800cf6e: 0013 movs r3, r2 + 800cf70: 009b lsls r3, r3, #2 + 800cf72: 189b adds r3, r3, r2 + 800cf74: 009b lsls r3, r3, #2 + 800cf76: 2200 movs r2, #0 + 800cf78: 505a str r2, [r3, r1] + } + /* recycle entry for re-use */ + arp_table[i].state = ETHARP_STATE_EMPTY; + 800cf7a: 4907 ldr r1, [pc, #28] ; (800cf98 ) + 800cf7c: 687a ldr r2, [r7, #4] + 800cf7e: 0013 movs r3, r2 + 800cf80: 009b lsls r3, r3, #2 + 800cf82: 189b adds r3, r3, r2 + 800cf84: 009b lsls r3, r3, #2 + 800cf86: 18cb adds r3, r1, r3 + 800cf88: 3312 adds r3, #18 + 800cf8a: 2200 movs r2, #0 + 800cf8c: 701a strb r2, [r3, #0] + arp_table[i].ctime = 0; + arp_table[i].netif = NULL; + ip_addr_set_zero(&arp_table[i].ipaddr); + arp_table[i].ethaddr = ethzero; +#endif /* LWIP_DEBUG */ +} + 800cf8e: 46c0 nop ; (mov r8, r8) + 800cf90: 46bd mov sp, r7 + 800cf92: b002 add sp, #8 + 800cf94: bd80 pop {r7, pc} + 800cf96: 46c0 nop ; (mov r8, r8) + 800cf98: 200022c0 .word 0x200022c0 + +0800cf9c : + * This function should be called every ETHARP_TMR_INTERVAL milliseconds (5 seconds), + * in order to expire entries in the ARP table. + */ +void +etharp_tmr(void) +{ + 800cf9c: b580 push {r7, lr} + 800cf9e: b082 sub sp, #8 + 800cfa0: af00 add r7, sp, #0 + u8_t i; + + LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_timer\n")); + /* remove expired entries from the ARP table */ + for (i = 0; i < ARP_TABLE_SIZE; ++i) { + 800cfa2: 1dfb adds r3, r7, #7 + 800cfa4: 2200 movs r2, #0 + 800cfa6: 701a strb r2, [r3, #0] + 800cfa8: e06e b.n 800d088 + u8_t state = arp_table[i].state; + 800cfaa: 1dfb adds r3, r7, #7 + 800cfac: 781a ldrb r2, [r3, #0] + 800cfae: 1db9 adds r1, r7, #6 + 800cfb0: 4839 ldr r0, [pc, #228] ; (800d098 ) + 800cfb2: 0013 movs r3, r2 + 800cfb4: 009b lsls r3, r3, #2 + 800cfb6: 189b adds r3, r3, r2 + 800cfb8: 009b lsls r3, r3, #2 + 800cfba: 18c3 adds r3, r0, r3 + 800cfbc: 3312 adds r3, #18 + 800cfbe: 781b ldrb r3, [r3, #0] + 800cfc0: 700b strb r3, [r1, #0] + if (state != ETHARP_STATE_EMPTY + 800cfc2: 1dbb adds r3, r7, #6 + 800cfc4: 781b ldrb r3, [r3, #0] + 800cfc6: 2b00 cmp r3, #0 + 800cfc8: d059 beq.n 800d07e +#if ETHARP_SUPPORT_STATIC_ENTRIES + && (state != ETHARP_STATE_STATIC) + 800cfca: 1dbb adds r3, r7, #6 + 800cfcc: 781b ldrb r3, [r3, #0] + 800cfce: 2b04 cmp r3, #4 + 800cfd0: d055 beq.n 800d07e +#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */ + ) { + arp_table[i].ctime++; + 800cfd2: 1dfb adds r3, r7, #7 + 800cfd4: 781a ldrb r2, [r3, #0] + 800cfd6: 4930 ldr r1, [pc, #192] ; (800d098 ) + 800cfd8: 0013 movs r3, r2 + 800cfda: 009b lsls r3, r3, #2 + 800cfdc: 189b adds r3, r3, r2 + 800cfde: 009b lsls r3, r3, #2 + 800cfe0: 18cb adds r3, r1, r3 + 800cfe2: 3313 adds r3, #19 + 800cfe4: 781b ldrb r3, [r3, #0] + 800cfe6: 3301 adds r3, #1 + 800cfe8: b2d8 uxtb r0, r3 + 800cfea: 492b ldr r1, [pc, #172] ; (800d098 ) + 800cfec: 0013 movs r3, r2 + 800cfee: 009b lsls r3, r3, #2 + 800cff0: 189b adds r3, r3, r2 + 800cff2: 009b lsls r3, r3, #2 + 800cff4: 18cb adds r3, r1, r3 + 800cff6: 3313 adds r3, #19 + 800cff8: 1c02 adds r2, r0, #0 + 800cffa: 701a strb r2, [r3, #0] + if ((arp_table[i].ctime >= ARP_MAXAGE) || + 800cffc: 1dfb adds r3, r7, #7 + 800cffe: 781a ldrb r2, [r3, #0] + 800d000: 4925 ldr r1, [pc, #148] ; (800d098 ) + 800d002: 0013 movs r3, r2 + 800d004: 009b lsls r3, r3, #2 + 800d006: 189b adds r3, r3, r2 + 800d008: 009b lsls r3, r3, #2 + 800d00a: 18cb adds r3, r1, r3 + 800d00c: 3313 adds r3, #19 + 800d00e: 781b ldrb r3, [r3, #0] + 800d010: 2bef cmp r3, #239 ; 0xef + 800d012: d817 bhi.n 800d044 + ((arp_table[i].state == ETHARP_STATE_PENDING) && + 800d014: 1dfb adds r3, r7, #7 + 800d016: 781a ldrb r2, [r3, #0] + 800d018: 491f ldr r1, [pc, #124] ; (800d098 ) + 800d01a: 0013 movs r3, r2 + 800d01c: 009b lsls r3, r3, #2 + 800d01e: 189b adds r3, r3, r2 + 800d020: 009b lsls r3, r3, #2 + 800d022: 18cb adds r3, r1, r3 + 800d024: 3312 adds r3, #18 + 800d026: 781b ldrb r3, [r3, #0] + if ((arp_table[i].ctime >= ARP_MAXAGE) || + 800d028: 2b01 cmp r3, #1 + 800d02a: d111 bne.n 800d050 + (arp_table[i].ctime >= ARP_MAXPENDING))) { + 800d02c: 1dfb adds r3, r7, #7 + 800d02e: 781a ldrb r2, [r3, #0] + 800d030: 4919 ldr r1, [pc, #100] ; (800d098 ) + 800d032: 0013 movs r3, r2 + 800d034: 009b lsls r3, r3, #2 + 800d036: 189b adds r3, r3, r2 + 800d038: 009b lsls r3, r3, #2 + 800d03a: 18cb adds r3, r1, r3 + 800d03c: 3313 adds r3, #19 + 800d03e: 781b ldrb r3, [r3, #0] + ((arp_table[i].state == ETHARP_STATE_PENDING) && + 800d040: 2b01 cmp r3, #1 + 800d042: d905 bls.n 800d050 + /* pending or stable entry has become old! */ + LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_timer: expired %s entry %"U16_F".\n", + arp_table[i].state >= ETHARP_STATE_STABLE ? "stable" : "pending", (u16_t)i)); + /* clean up entries that have just been expired */ + etharp_free_entry(i); + 800d044: 1dfb adds r3, r7, #7 + 800d046: 781b ldrb r3, [r3, #0] + 800d048: 0018 movs r0, r3 + 800d04a: f7ff ff77 bl 800cf3c + 800d04e: e016 b.n 800d07e + } + else if (arp_table[i].state == ETHARP_STATE_STABLE_REREQUESTING) { + 800d050: 1dfb adds r3, r7, #7 + 800d052: 781a ldrb r2, [r3, #0] + 800d054: 4910 ldr r1, [pc, #64] ; (800d098 ) + 800d056: 0013 movs r3, r2 + 800d058: 009b lsls r3, r3, #2 + 800d05a: 189b adds r3, r3, r2 + 800d05c: 009b lsls r3, r3, #2 + 800d05e: 18cb adds r3, r1, r3 + 800d060: 3312 adds r3, #18 + 800d062: 781b ldrb r3, [r3, #0] + 800d064: 2b03 cmp r3, #3 + 800d066: d10a bne.n 800d07e + /* Reset state to stable, so that the next transmitted packet will + re-send an ARP request. */ + arp_table[i].state = ETHARP_STATE_STABLE; + 800d068: 1dfb adds r3, r7, #7 + 800d06a: 781a ldrb r2, [r3, #0] + 800d06c: 490a ldr r1, [pc, #40] ; (800d098 ) + 800d06e: 0013 movs r3, r2 + 800d070: 009b lsls r3, r3, #2 + 800d072: 189b adds r3, r3, r2 + 800d074: 009b lsls r3, r3, #2 + 800d076: 18cb adds r3, r1, r3 + 800d078: 3312 adds r3, #18 + 800d07a: 2202 movs r2, #2 + 800d07c: 701a strb r2, [r3, #0] + for (i = 0; i < ARP_TABLE_SIZE; ++i) { + 800d07e: 1dfb adds r3, r7, #7 + 800d080: 1dfa adds r2, r7, #7 + 800d082: 7812 ldrb r2, [r2, #0] + 800d084: 3201 adds r2, #1 + 800d086: 701a strb r2, [r3, #0] + 800d088: 1dfb adds r3, r7, #7 + 800d08a: 781b ldrb r3, [r3, #0] + 800d08c: 2b09 cmp r3, #9 + 800d08e: d98c bls.n 800cfaa + /* resend an ARP query here? */ + } +#endif /* ARP_QUEUEING */ + } + } +} + 800d090: 46c0 nop ; (mov r8, r8) + 800d092: 46bd mov sp, r7 + 800d094: b002 add sp, #8 + 800d096: bd80 pop {r7, pc} + 800d098: 200022c0 .word 0x200022c0 + +0800d09c : + * @return The ARP entry index that matched or is created, ERR_MEM if no + * entry is found or could be recycled. + */ +static s8_t +etharp_find_entry(ip_addr_t *ipaddr, u8_t flags) +{ + 800d09c: b580 push {r7, lr} + 800d09e: b086 sub sp, #24 + 800d0a0: af00 add r7, sp, #0 + 800d0a2: 6078 str r0, [r7, #4] + 800d0a4: 000a movs r2, r1 + 800d0a6: 1cfb adds r3, r7, #3 + 800d0a8: 701a strb r2, [r3, #0] + s8_t old_pending = ARP_TABLE_SIZE, old_stable = ARP_TABLE_SIZE; + 800d0aa: 2317 movs r3, #23 + 800d0ac: 18fb adds r3, r7, r3 + 800d0ae: 220a movs r2, #10 + 800d0b0: 701a strb r2, [r3, #0] + 800d0b2: 2316 movs r3, #22 + 800d0b4: 18fb adds r3, r7, r3 + 800d0b6: 220a movs r2, #10 + 800d0b8: 701a strb r2, [r3, #0] + s8_t empty = ARP_TABLE_SIZE; + 800d0ba: 2315 movs r3, #21 + 800d0bc: 18fb adds r3, r7, r3 + 800d0be: 220a movs r2, #10 + 800d0c0: 701a strb r2, [r3, #0] + u8_t i = 0, age_pending = 0, age_stable = 0; + 800d0c2: 2114 movs r1, #20 + 800d0c4: 187b adds r3, r7, r1 + 800d0c6: 2200 movs r2, #0 + 800d0c8: 701a strb r2, [r3, #0] + 800d0ca: 2313 movs r3, #19 + 800d0cc: 18fb adds r3, r7, r3 + 800d0ce: 2200 movs r2, #0 + 800d0d0: 701a strb r2, [r3, #0] + 800d0d2: 2312 movs r3, #18 + 800d0d4: 18fb adds r3, r7, r3 + 800d0d6: 2200 movs r2, #0 + 800d0d8: 701a strb r2, [r3, #0] + /* oldest entry with packets on queue */ + s8_t old_queue = ARP_TABLE_SIZE; + 800d0da: 2311 movs r3, #17 + 800d0dc: 18fb adds r3, r7, r3 + 800d0de: 220a movs r2, #10 + 800d0e0: 701a strb r2, [r3, #0] + /* its age */ + u8_t age_queue = 0; + 800d0e2: 2310 movs r3, #16 + 800d0e4: 18fb adds r3, r7, r3 + 800d0e6: 2200 movs r2, #0 + 800d0e8: 701a strb r2, [r3, #0] + * 4) remember the oldest pending entry with queued packets (if any) + * 5) search for a matching IP entry, either pending or stable + * until 5 matches, or all entries are searched for. + */ + + for (i = 0; i < ARP_TABLE_SIZE; ++i) { + 800d0ea: 187b adds r3, r7, r1 + 800d0ec: 2200 movs r2, #0 + 800d0ee: 701a strb r2, [r3, #0] + 800d0f0: e0c7 b.n 800d282 + u8_t state = arp_table[i].state; + 800d0f2: 2314 movs r3, #20 + 800d0f4: 18fb adds r3, r7, r3 + 800d0f6: 781a ldrb r2, [r3, #0] + 800d0f8: 230f movs r3, #15 + 800d0fa: 18f9 adds r1, r7, r3 + 800d0fc: 48a4 ldr r0, [pc, #656] ; (800d390 ) + 800d0fe: 0013 movs r3, r2 + 800d100: 009b lsls r3, r3, #2 + 800d102: 189b adds r3, r3, r2 + 800d104: 009b lsls r3, r3, #2 + 800d106: 18c3 adds r3, r0, r3 + 800d108: 3312 adds r3, #18 + 800d10a: 781b ldrb r3, [r3, #0] + 800d10c: 700b strb r3, [r1, #0] + /* no empty entry found yet and now we do find one? */ + if ((empty == ARP_TABLE_SIZE) && (state == ETHARP_STATE_EMPTY)) { + 800d10e: 2315 movs r3, #21 + 800d110: 18fb adds r3, r7, r3 + 800d112: 781b ldrb r3, [r3, #0] + 800d114: b25b sxtb r3, r3 + 800d116: 2b0a cmp r3, #10 + 800d118: d10b bne.n 800d132 + 800d11a: 230f movs r3, #15 + 800d11c: 18fb adds r3, r7, r3 + 800d11e: 781b ldrb r3, [r3, #0] + 800d120: 2b00 cmp r3, #0 + 800d122: d106 bne.n 800d132 + LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_find_entry: found empty entry %"U16_F"\n", (u16_t)i)); + /* remember first empty entry */ + empty = i; + 800d124: 2315 movs r3, #21 + 800d126: 18fb adds r3, r7, r3 + 800d128: 2214 movs r2, #20 + 800d12a: 18ba adds r2, r7, r2 + 800d12c: 7812 ldrb r2, [r2, #0] + 800d12e: 701a strb r2, [r3, #0] + 800d130: e0a1 b.n 800d276 + } else if (state != ETHARP_STATE_EMPTY) { + 800d132: 230f movs r3, #15 + 800d134: 18fb adds r3, r7, r3 + 800d136: 781b ldrb r3, [r3, #0] + 800d138: 2b00 cmp r3, #0 + 800d13a: d100 bne.n 800d13e + 800d13c: e09b b.n 800d276 + LWIP_ASSERT("state == ETHARP_STATE_PENDING || state >= ETHARP_STATE_STABLE", + state == ETHARP_STATE_PENDING || state >= ETHARP_STATE_STABLE); + /* if given, does IP address match IP address in ARP entry? */ + if (ipaddr && ip_addr_cmp(ipaddr, &arp_table[i].ipaddr)) { + 800d13e: 687b ldr r3, [r7, #4] + 800d140: 2b00 cmp r3, #0 + 800d142: d013 beq.n 800d16c + 800d144: 687b ldr r3, [r7, #4] + 800d146: 6819 ldr r1, [r3, #0] + 800d148: 2314 movs r3, #20 + 800d14a: 18fb adds r3, r7, r3 + 800d14c: 781a ldrb r2, [r3, #0] + 800d14e: 4890 ldr r0, [pc, #576] ; (800d390 ) + 800d150: 0013 movs r3, r2 + 800d152: 009b lsls r3, r3, #2 + 800d154: 189b adds r3, r3, r2 + 800d156: 009b lsls r3, r3, #2 + 800d158: 18c3 adds r3, r0, r3 + 800d15a: 3304 adds r3, #4 + 800d15c: 681b ldr r3, [r3, #0] + 800d15e: 4299 cmp r1, r3 + 800d160: d104 bne.n 800d16c + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: found matching entry %"U16_F"\n", (u16_t)i)); + /* found exact IP address match, simply bail out */ + return i; + 800d162: 2314 movs r3, #20 + 800d164: 18fb adds r3, r7, r3 + 800d166: 781b ldrb r3, [r3, #0] + 800d168: b25b sxtb r3, r3 + 800d16a: e10c b.n 800d386 + } + /* pending entry? */ + if (state == ETHARP_STATE_PENDING) { + 800d16c: 230f movs r3, #15 + 800d16e: 18fb adds r3, r7, r3 + 800d170: 781b ldrb r3, [r3, #0] + 800d172: 2b01 cmp r3, #1 + 800d174: d152 bne.n 800d21c + /* pending with queued packets? */ + if (arp_table[i].q != NULL) { + 800d176: 2314 movs r3, #20 + 800d178: 18fb adds r3, r7, r3 + 800d17a: 781a ldrb r2, [r3, #0] + 800d17c: 4984 ldr r1, [pc, #528] ; (800d390 ) + 800d17e: 0013 movs r3, r2 + 800d180: 009b lsls r3, r3, #2 + 800d182: 189b adds r3, r3, r2 + 800d184: 009b lsls r3, r3, #2 + 800d186: 585b ldr r3, [r3, r1] + 800d188: 2b00 cmp r3, #0 + 800d18a: d023 beq.n 800d1d4 + if (arp_table[i].ctime >= age_queue) { + 800d18c: 2314 movs r3, #20 + 800d18e: 18fb adds r3, r7, r3 + 800d190: 781a ldrb r2, [r3, #0] + 800d192: 497f ldr r1, [pc, #508] ; (800d390 ) + 800d194: 0013 movs r3, r2 + 800d196: 009b lsls r3, r3, #2 + 800d198: 189b adds r3, r3, r2 + 800d19a: 009b lsls r3, r3, #2 + 800d19c: 18cb adds r3, r1, r3 + 800d19e: 3313 adds r3, #19 + 800d1a0: 781b ldrb r3, [r3, #0] + 800d1a2: 2210 movs r2, #16 + 800d1a4: 18ba adds r2, r7, r2 + 800d1a6: 7812 ldrb r2, [r2, #0] + 800d1a8: 429a cmp r2, r3 + 800d1aa: d864 bhi.n 800d276 + old_queue = i; + 800d1ac: 2311 movs r3, #17 + 800d1ae: 18fb adds r3, r7, r3 + 800d1b0: 2114 movs r1, #20 + 800d1b2: 187a adds r2, r7, r1 + 800d1b4: 7812 ldrb r2, [r2, #0] + 800d1b6: 701a strb r2, [r3, #0] + age_queue = arp_table[i].ctime; + 800d1b8: 187b adds r3, r7, r1 + 800d1ba: 781a ldrb r2, [r3, #0] + 800d1bc: 2310 movs r3, #16 + 800d1be: 18f9 adds r1, r7, r3 + 800d1c0: 4873 ldr r0, [pc, #460] ; (800d390 ) + 800d1c2: 0013 movs r3, r2 + 800d1c4: 009b lsls r3, r3, #2 + 800d1c6: 189b adds r3, r3, r2 + 800d1c8: 009b lsls r3, r3, #2 + 800d1ca: 18c3 adds r3, r0, r3 + 800d1cc: 3313 adds r3, #19 + 800d1ce: 781b ldrb r3, [r3, #0] + 800d1d0: 700b strb r3, [r1, #0] + 800d1d2: e050 b.n 800d276 + } + } else + /* pending without queued packets? */ + { + if (arp_table[i].ctime >= age_pending) { + 800d1d4: 2314 movs r3, #20 + 800d1d6: 18fb adds r3, r7, r3 + 800d1d8: 781a ldrb r2, [r3, #0] + 800d1da: 496d ldr r1, [pc, #436] ; (800d390 ) + 800d1dc: 0013 movs r3, r2 + 800d1de: 009b lsls r3, r3, #2 + 800d1e0: 189b adds r3, r3, r2 + 800d1e2: 009b lsls r3, r3, #2 + 800d1e4: 18cb adds r3, r1, r3 + 800d1e6: 3313 adds r3, #19 + 800d1e8: 781b ldrb r3, [r3, #0] + 800d1ea: 2213 movs r2, #19 + 800d1ec: 18ba adds r2, r7, r2 + 800d1ee: 7812 ldrb r2, [r2, #0] + 800d1f0: 429a cmp r2, r3 + 800d1f2: d840 bhi.n 800d276 + old_pending = i; + 800d1f4: 2317 movs r3, #23 + 800d1f6: 18fb adds r3, r7, r3 + 800d1f8: 2114 movs r1, #20 + 800d1fa: 187a adds r2, r7, r1 + 800d1fc: 7812 ldrb r2, [r2, #0] + 800d1fe: 701a strb r2, [r3, #0] + age_pending = arp_table[i].ctime; + 800d200: 187b adds r3, r7, r1 + 800d202: 781a ldrb r2, [r3, #0] + 800d204: 2313 movs r3, #19 + 800d206: 18f9 adds r1, r7, r3 + 800d208: 4861 ldr r0, [pc, #388] ; (800d390 ) + 800d20a: 0013 movs r3, r2 + 800d20c: 009b lsls r3, r3, #2 + 800d20e: 189b adds r3, r3, r2 + 800d210: 009b lsls r3, r3, #2 + 800d212: 18c3 adds r3, r0, r3 + 800d214: 3313 adds r3, #19 + 800d216: 781b ldrb r3, [r3, #0] + 800d218: 700b strb r3, [r1, #0] + 800d21a: e02c b.n 800d276 + } + } + /* stable entry? */ + } else if (state >= ETHARP_STATE_STABLE) { + 800d21c: 230f movs r3, #15 + 800d21e: 18fb adds r3, r7, r3 + 800d220: 781b ldrb r3, [r3, #0] + 800d222: 2b01 cmp r3, #1 + 800d224: d927 bls.n 800d276 +#if ETHARP_SUPPORT_STATIC_ENTRIES + /* don't record old_stable for static entries since they never expire */ + if (state < ETHARP_STATE_STATIC) + 800d226: 230f movs r3, #15 + 800d228: 18fb adds r3, r7, r3 + 800d22a: 781b ldrb r3, [r3, #0] + 800d22c: 2b03 cmp r3, #3 + 800d22e: d822 bhi.n 800d276 +#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */ + { + /* remember entry with oldest stable entry in oldest, its age in maxtime */ + if (arp_table[i].ctime >= age_stable) { + 800d230: 2314 movs r3, #20 + 800d232: 18fb adds r3, r7, r3 + 800d234: 781a ldrb r2, [r3, #0] + 800d236: 4956 ldr r1, [pc, #344] ; (800d390 ) + 800d238: 0013 movs r3, r2 + 800d23a: 009b lsls r3, r3, #2 + 800d23c: 189b adds r3, r3, r2 + 800d23e: 009b lsls r3, r3, #2 + 800d240: 18cb adds r3, r1, r3 + 800d242: 3313 adds r3, #19 + 800d244: 781b ldrb r3, [r3, #0] + 800d246: 2212 movs r2, #18 + 800d248: 18ba adds r2, r7, r2 + 800d24a: 7812 ldrb r2, [r2, #0] + 800d24c: 429a cmp r2, r3 + 800d24e: d812 bhi.n 800d276 + old_stable = i; + 800d250: 2316 movs r3, #22 + 800d252: 18fb adds r3, r7, r3 + 800d254: 2114 movs r1, #20 + 800d256: 187a adds r2, r7, r1 + 800d258: 7812 ldrb r2, [r2, #0] + 800d25a: 701a strb r2, [r3, #0] + age_stable = arp_table[i].ctime; + 800d25c: 187b adds r3, r7, r1 + 800d25e: 781a ldrb r2, [r3, #0] + 800d260: 2312 movs r3, #18 + 800d262: 18f9 adds r1, r7, r3 + 800d264: 484a ldr r0, [pc, #296] ; (800d390 ) + 800d266: 0013 movs r3, r2 + 800d268: 009b lsls r3, r3, #2 + 800d26a: 189b adds r3, r3, r2 + 800d26c: 009b lsls r3, r3, #2 + 800d26e: 18c3 adds r3, r0, r3 + 800d270: 3313 adds r3, #19 + 800d272: 781b ldrb r3, [r3, #0] + 800d274: 700b strb r3, [r1, #0] + for (i = 0; i < ARP_TABLE_SIZE; ++i) { + 800d276: 2214 movs r2, #20 + 800d278: 18bb adds r3, r7, r2 + 800d27a: 18ba adds r2, r7, r2 + 800d27c: 7812 ldrb r2, [r2, #0] + 800d27e: 3201 adds r2, #1 + 800d280: 701a strb r2, [r3, #0] + 800d282: 2314 movs r3, #20 + 800d284: 18fb adds r3, r7, r3 + 800d286: 781b ldrb r3, [r3, #0] + 800d288: 2b09 cmp r3, #9 + 800d28a: d800 bhi.n 800d28e + 800d28c: e731 b.n 800d0f2 + } + } + /* { we have no match } => try to create a new entry */ + + /* don't create new entry, only search? */ + if (((flags & ETHARP_FLAG_FIND_ONLY) != 0) || + 800d28e: 1cfb adds r3, r7, #3 + 800d290: 781b ldrb r3, [r3, #0] + 800d292: 2202 movs r2, #2 + 800d294: 4013 ands r3, r2 + 800d296: d10a bne.n 800d2ae + 800d298: 2315 movs r3, #21 + 800d29a: 18fb adds r3, r7, r3 + 800d29c: 781b ldrb r3, [r3, #0] + 800d29e: b25b sxtb r3, r3 + 800d2a0: 2b0a cmp r3, #10 + 800d2a2: d107 bne.n 800d2b4 + /* or no empty entry found and not allowed to recycle? */ + ((empty == ARP_TABLE_SIZE) && ((flags & ETHARP_FLAG_TRY_HARD) == 0))) { + 800d2a4: 1cfb adds r3, r7, #3 + 800d2a6: 781b ldrb r3, [r3, #0] + 800d2a8: 2201 movs r2, #1 + 800d2aa: 4013 ands r3, r2 + 800d2ac: d102 bne.n 800d2b4 + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: no empty entry found and not allowed to recycle\n")); + return (s8_t)ERR_MEM; + 800d2ae: 2301 movs r3, #1 + 800d2b0: 425b negs r3, r3 + 800d2b2: e068 b.n 800d386 + * + * { ETHARP_FLAG_TRY_HARD is set at this point } + */ + + /* 1) empty entry available? */ + if (empty < ARP_TABLE_SIZE) { + 800d2b4: 2315 movs r3, #21 + 800d2b6: 18fb adds r3, r7, r3 + 800d2b8: 781b ldrb r3, [r3, #0] + 800d2ba: b25b sxtb r3, r3 + 800d2bc: 2b09 cmp r3, #9 + 800d2be: dc06 bgt.n 800d2ce + i = empty; + 800d2c0: 2314 movs r3, #20 + 800d2c2: 18fb adds r3, r7, r3 + 800d2c4: 2215 movs r2, #21 + 800d2c6: 18ba adds r2, r7, r2 + 800d2c8: 7812 ldrb r2, [r2, #0] + 800d2ca: 701a strb r2, [r3, #0] + 800d2cc: e035 b.n 800d33a + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: selecting empty entry %"U16_F"\n", (u16_t)i)); + } else { + /* 2) found recyclable stable entry? */ + if (old_stable < ARP_TABLE_SIZE) { + 800d2ce: 2316 movs r3, #22 + 800d2d0: 18fb adds r3, r7, r3 + 800d2d2: 781b ldrb r3, [r3, #0] + 800d2d4: b25b sxtb r3, r3 + 800d2d6: 2b09 cmp r3, #9 + 800d2d8: dc0c bgt.n 800d2f4 + /* recycle oldest stable*/ + i = old_stable; + 800d2da: 2114 movs r1, #20 + 800d2dc: 187b adds r3, r7, r1 + 800d2de: 2216 movs r2, #22 + 800d2e0: 18ba adds r2, r7, r2 + 800d2e2: 7812 ldrb r2, [r2, #0] + 800d2e4: 701a strb r2, [r3, #0] + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: selecting oldest stable entry %"U16_F"\n", (u16_t)i)); + /* no queued packets should exist on stable entries */ + LWIP_ASSERT("arp_table[i].q == NULL", arp_table[i].q == NULL); + 800d2e6: 187b adds r3, r7, r1 + 800d2e8: 781a ldrb r2, [r3, #0] + 800d2ea: 0013 movs r3, r2 + 800d2ec: 009b lsls r3, r3, #2 + 800d2ee: 189b adds r3, r3, r2 + 800d2f0: 009b lsls r3, r3, #2 + 800d2f2: e01c b.n 800d32e + /* 3) found recyclable pending entry without queued packets? */ + } else if (old_pending < ARP_TABLE_SIZE) { + 800d2f4: 2317 movs r3, #23 + 800d2f6: 18fb adds r3, r7, r3 + 800d2f8: 781b ldrb r3, [r3, #0] + 800d2fa: b25b sxtb r3, r3 + 800d2fc: 2b09 cmp r3, #9 + 800d2fe: dc06 bgt.n 800d30e + /* recycle oldest pending */ + i = old_pending; + 800d300: 2314 movs r3, #20 + 800d302: 18fb adds r3, r7, r3 + 800d304: 2217 movs r2, #23 + 800d306: 18ba adds r2, r7, r2 + 800d308: 7812 ldrb r2, [r2, #0] + 800d30a: 701a strb r2, [r3, #0] + 800d30c: e00f b.n 800d32e + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: selecting oldest pending entry %"U16_F" (without queue)\n", (u16_t)i)); + /* 4) found recyclable pending entry with queued packets? */ + } else if (old_queue < ARP_TABLE_SIZE) { + 800d30e: 2311 movs r3, #17 + 800d310: 18fb adds r3, r7, r3 + 800d312: 781b ldrb r3, [r3, #0] + 800d314: b25b sxtb r3, r3 + 800d316: 2b09 cmp r3, #9 + 800d318: dc06 bgt.n 800d328 + /* recycle oldest pending (queued packets are free in etharp_free_entry) */ + i = old_queue; + 800d31a: 2314 movs r3, #20 + 800d31c: 18fb adds r3, r7, r3 + 800d31e: 2211 movs r2, #17 + 800d320: 18ba adds r2, r7, r2 + 800d322: 7812 ldrb r2, [r2, #0] + 800d324: 701a strb r2, [r3, #0] + 800d326: e002 b.n 800d32e + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: selecting oldest pending entry %"U16_F", freeing packet queue %p\n", (u16_t)i, (void *)(arp_table[i].q))); + /* no empty or recyclable entries found */ + } else { + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: no empty or recyclable entries found\n")); + return (s8_t)ERR_MEM; + 800d328: 2301 movs r3, #1 + 800d32a: 425b negs r3, r3 + 800d32c: e02b b.n 800d386 + } + + /* { empty or recyclable entry found } */ + LWIP_ASSERT("i < ARP_TABLE_SIZE", i < ARP_TABLE_SIZE); + etharp_free_entry(i); + 800d32e: 2314 movs r3, #20 + 800d330: 18fb adds r3, r7, r3 + 800d332: 781b ldrb r3, [r3, #0] + 800d334: 0018 movs r0, r3 + 800d336: f7ff fe01 bl 800cf3c + } + + LWIP_ASSERT("i < ARP_TABLE_SIZE", i < ARP_TABLE_SIZE); + LWIP_ASSERT("arp_table[i].state == ETHARP_STATE_EMPTY", + 800d33a: 2314 movs r3, #20 + 800d33c: 18fb adds r3, r7, r3 + 800d33e: 781a ldrb r2, [r3, #0] + 800d340: 0013 movs r3, r2 + 800d342: 009b lsls r3, r3, #2 + 800d344: 189b adds r3, r3, r2 + 800d346: 009b lsls r3, r3, #2 + arp_table[i].state == ETHARP_STATE_EMPTY); + + /* IP address given? */ + if (ipaddr != NULL) { + 800d348: 687b ldr r3, [r7, #4] + 800d34a: 2b00 cmp r3, #0 + 800d34c: d00c beq.n 800d368 + /* set IP address */ + ip_addr_copy(arp_table[i].ipaddr, *ipaddr); + 800d34e: 2314 movs r3, #20 + 800d350: 18fb adds r3, r7, r3 + 800d352: 781a ldrb r2, [r3, #0] + 800d354: 687b ldr r3, [r7, #4] + 800d356: 6819 ldr r1, [r3, #0] + 800d358: 480d ldr r0, [pc, #52] ; (800d390 ) + 800d35a: 0013 movs r3, r2 + 800d35c: 009b lsls r3, r3, #2 + 800d35e: 189b adds r3, r3, r2 + 800d360: 009b lsls r3, r3, #2 + 800d362: 18c3 adds r3, r0, r3 + 800d364: 3304 adds r3, #4 + 800d366: 6019 str r1, [r3, #0] + } + arp_table[i].ctime = 0; + 800d368: 2014 movs r0, #20 + 800d36a: 183b adds r3, r7, r0 + 800d36c: 781a ldrb r2, [r3, #0] + 800d36e: 4908 ldr r1, [pc, #32] ; (800d390 ) + 800d370: 0013 movs r3, r2 + 800d372: 009b lsls r3, r3, #2 + 800d374: 189b adds r3, r3, r2 + 800d376: 009b lsls r3, r3, #2 + 800d378: 18cb adds r3, r1, r3 + 800d37a: 3313 adds r3, #19 + 800d37c: 2200 movs r2, #0 + 800d37e: 701a strb r2, [r3, #0] + return (err_t)i; + 800d380: 183b adds r3, r7, r0 + 800d382: 781b ldrb r3, [r3, #0] + 800d384: b25b sxtb r3, r3 +} + 800d386: 0018 movs r0, r3 + 800d388: 46bd mov sp, r7 + 800d38a: b006 add sp, #24 + 800d38c: bd80 pop {r7, pc} + 800d38e: 46c0 nop ; (mov r8, r8) + 800d390: 200022c0 .word 0x200022c0 + +0800d394 : + * @params dst the destination MAC address to be copied into the ethernet header + * @return ERR_OK if the packet was sent, any other err_t on failure + */ +static err_t +etharp_send_ip(struct netif *netif, struct pbuf *p, struct eth_addr *src, struct eth_addr *dst) +{ + 800d394: b580 push {r7, lr} + 800d396: b086 sub sp, #24 + 800d398: af00 add r7, sp, #0 + 800d39a: 60f8 str r0, [r7, #12] + 800d39c: 60b9 str r1, [r7, #8] + 800d39e: 607a str r2, [r7, #4] + 800d3a0: 603b str r3, [r7, #0] + struct eth_hdr *ethhdr = (struct eth_hdr *)p->payload; + 800d3a2: 68bb ldr r3, [r7, #8] + 800d3a4: 685b ldr r3, [r3, #4] + 800d3a6: 617b str r3, [r7, #20] + + LWIP_ASSERT("netif->hwaddr_len must be the same as ETHARP_HWADDR_LEN for etharp!", + (netif->hwaddr_len == ETHARP_HWADDR_LEN)); + ETHADDR32_COPY(ðhdr->dest, dst); + 800d3a8: 697b ldr r3, [r7, #20] + 800d3aa: 6839 ldr r1, [r7, #0] + 800d3ac: 2206 movs r2, #6 + 800d3ae: 0018 movs r0, r3 + 800d3b0: f002 fc77 bl 800fca2 + ETHADDR16_COPY(ðhdr->src, src); + 800d3b4: 697b ldr r3, [r7, #20] + 800d3b6: 3306 adds r3, #6 + 800d3b8: 6879 ldr r1, [r7, #4] + 800d3ba: 2206 movs r2, #6 + 800d3bc: 0018 movs r0, r3 + 800d3be: f002 fc70 bl 800fca2 + ethhdr->type = PP_HTONS(ETHTYPE_IP); + 800d3c2: 697b ldr r3, [r7, #20] + 800d3c4: 7b1a ldrb r2, [r3, #12] + 800d3c6: 2100 movs r1, #0 + 800d3c8: 400a ands r2, r1 + 800d3ca: 1c11 adds r1, r2, #0 + 800d3cc: 2208 movs r2, #8 + 800d3ce: 430a orrs r2, r1 + 800d3d0: 731a strb r2, [r3, #12] + 800d3d2: 7b5a ldrb r2, [r3, #13] + 800d3d4: 2100 movs r1, #0 + 800d3d6: 400a ands r2, r1 + 800d3d8: 735a strb r2, [r3, #13] + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_send_ip: sending packet %p\n", (void *)p)); + /* send the packet */ + return netif->linkoutput(netif, p); + 800d3da: 68fb ldr r3, [r7, #12] + 800d3dc: 699b ldr r3, [r3, #24] + 800d3de: 68b9 ldr r1, [r7, #8] + 800d3e0: 68fa ldr r2, [r7, #12] + 800d3e2: 0010 movs r0, r2 + 800d3e4: 4798 blx r3 + 800d3e6: 0003 movs r3, r0 +} + 800d3e8: 0018 movs r0, r3 + 800d3ea: 46bd mov sp, r7 + 800d3ec: b006 add sp, #24 + 800d3ee: bd80 pop {r7, pc} + +0800d3f0 : + * + * @see pbuf_free() + */ +static err_t +etharp_update_arp_entry(struct netif *netif, ip_addr_t *ipaddr, struct eth_addr *ethaddr, u8_t flags) +{ + 800d3f0: b5b0 push {r4, r5, r7, lr} + 800d3f2: b086 sub sp, #24 + 800d3f4: af00 add r7, sp, #0 + 800d3f6: 60f8 str r0, [r7, #12] + 800d3f8: 60b9 str r1, [r7, #8] + 800d3fa: 607a str r2, [r7, #4] + 800d3fc: 001a movs r2, r3 + 800d3fe: 1cfb adds r3, r7, #3 + 800d400: 701a strb r2, [r3, #0] + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_update_arp_entry: %"U16_F".%"U16_F".%"U16_F".%"U16_F" - %02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F"\n", + ip4_addr1_16(ipaddr), ip4_addr2_16(ipaddr), ip4_addr3_16(ipaddr), ip4_addr4_16(ipaddr), + ethaddr->addr[0], ethaddr->addr[1], ethaddr->addr[2], + ethaddr->addr[3], ethaddr->addr[4], ethaddr->addr[5])); + /* non-unicast address? */ + if (ip_addr_isany(ipaddr) || + 800d402: 68bb ldr r3, [r7, #8] + 800d404: 2b00 cmp r3, #0 + 800d406: d012 beq.n 800d42e + 800d408: 68bb ldr r3, [r7, #8] + 800d40a: 681b ldr r3, [r3, #0] + 800d40c: 2b00 cmp r3, #0 + 800d40e: d00e beq.n 800d42e + ip_addr_isbroadcast(ipaddr, netif) || + 800d410: 68bb ldr r3, [r7, #8] + 800d412: 681b ldr r3, [r3, #0] + 800d414: 68fa ldr r2, [r7, #12] + 800d416: 0011 movs r1, r2 + 800d418: 0018 movs r0, r3 + 800d41a: f7fe fe2f bl 800c07c + 800d41e: 1e03 subs r3, r0, #0 + if (ip_addr_isany(ipaddr) || + 800d420: d105 bne.n 800d42e + ip_addr_ismulticast(ipaddr)) { + 800d422: 68bb ldr r3, [r7, #8] + 800d424: 681b ldr r3, [r3, #0] + 800d426: 22f0 movs r2, #240 ; 0xf0 + 800d428: 4013 ands r3, r2 + ip_addr_isbroadcast(ipaddr, netif) || + 800d42a: 2be0 cmp r3, #224 ; 0xe0 + 800d42c: d102 bne.n 800d434 + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_update_arp_entry: will not add non-unicast IP address to ARP cache\n")); + return ERR_ARG; + 800d42e: 230e movs r3, #14 + 800d430: 425b negs r3, r3 + 800d432: e08a b.n 800d54a + } + /* find or create ARP entry */ + i = etharp_find_entry(ipaddr, flags); + 800d434: 2517 movs r5, #23 + 800d436: 197c adds r4, r7, r5 + 800d438: 1cfb adds r3, r7, #3 + 800d43a: 781a ldrb r2, [r3, #0] + 800d43c: 68bb ldr r3, [r7, #8] + 800d43e: 0011 movs r1, r2 + 800d440: 0018 movs r0, r3 + 800d442: f7ff fe2b bl 800d09c + 800d446: 0003 movs r3, r0 + 800d448: 7023 strb r3, [r4, #0] + /* bail out if no entry could be found */ + if (i < 0) { + 800d44a: 197b adds r3, r7, r5 + 800d44c: 781b ldrb r3, [r3, #0] + 800d44e: 2b7f cmp r3, #127 ; 0x7f + 800d450: d904 bls.n 800d45c + return (err_t)i; + 800d452: 2317 movs r3, #23 + 800d454: 18fb adds r3, r7, r3 + 800d456: 781b ldrb r3, [r3, #0] + 800d458: b25b sxtb r3, r3 + 800d45a: e076 b.n 800d54a + } + +#if ETHARP_SUPPORT_STATIC_ENTRIES + if (flags & ETHARP_FLAG_STATIC_ENTRY) { + 800d45c: 1cfb adds r3, r7, #3 + 800d45e: 781b ldrb r3, [r3, #0] + 800d460: 2204 movs r2, #4 + 800d462: 4013 ands r3, r2 + 800d464: d00d beq.n 800d482 + /* record static type */ + arp_table[i].state = ETHARP_STATE_STATIC; + 800d466: 2317 movs r3, #23 + 800d468: 18fb adds r3, r7, r3 + 800d46a: 2200 movs r2, #0 + 800d46c: 569a ldrsb r2, [r3, r2] + 800d46e: 4939 ldr r1, [pc, #228] ; (800d554 ) + 800d470: 0013 movs r3, r2 + 800d472: 009b lsls r3, r3, #2 + 800d474: 189b adds r3, r3, r2 + 800d476: 009b lsls r3, r3, #2 + 800d478: 18cb adds r3, r1, r3 + 800d47a: 3312 adds r3, #18 + 800d47c: 2204 movs r2, #4 + 800d47e: 701a strb r2, [r3, #0] + 800d480: e00c b.n 800d49c + } else +#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */ + { + /* mark it stable */ + arp_table[i].state = ETHARP_STATE_STABLE; + 800d482: 2317 movs r3, #23 + 800d484: 18fb adds r3, r7, r3 + 800d486: 2200 movs r2, #0 + 800d488: 569a ldrsb r2, [r3, r2] + 800d48a: 4932 ldr r1, [pc, #200] ; (800d554 ) + 800d48c: 0013 movs r3, r2 + 800d48e: 009b lsls r3, r3, #2 + 800d490: 189b adds r3, r3, r2 + 800d492: 009b lsls r3, r3, #2 + 800d494: 18cb adds r3, r1, r3 + 800d496: 3312 adds r3, #18 + 800d498: 2202 movs r2, #2 + 800d49a: 701a strb r2, [r3, #0] + } + + /* record network interface */ + arp_table[i].netif = netif; + 800d49c: 2417 movs r4, #23 + 800d49e: 193b adds r3, r7, r4 + 800d4a0: 2200 movs r2, #0 + 800d4a2: 569a ldrsb r2, [r3, r2] + 800d4a4: 492b ldr r1, [pc, #172] ; (800d554 ) + 800d4a6: 0013 movs r3, r2 + 800d4a8: 009b lsls r3, r3, #2 + 800d4aa: 189b adds r3, r3, r2 + 800d4ac: 009b lsls r3, r3, #2 + 800d4ae: 18cb adds r3, r1, r3 + 800d4b0: 3308 adds r3, #8 + 800d4b2: 68fa ldr r2, [r7, #12] + 800d4b4: 601a str r2, [r3, #0] + /* insert in SNMP ARP index tree */ + snmp_insert_arpidx_tree(netif, &arp_table[i].ipaddr); + + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_update_arp_entry: updating stable entry %"S16_F"\n", (s16_t)i)); + /* update address */ + ETHADDR32_COPY(&arp_table[i].ethaddr, ethaddr); + 800d4b6: 193b adds r3, r7, r4 + 800d4b8: 2200 movs r2, #0 + 800d4ba: 569a ldrsb r2, [r3, r2] + 800d4bc: 0013 movs r3, r2 + 800d4be: 009b lsls r3, r3, #2 + 800d4c0: 189b adds r3, r3, r2 + 800d4c2: 009b lsls r3, r3, #2 + 800d4c4: 3308 adds r3, #8 + 800d4c6: 001a movs r2, r3 + 800d4c8: 4b22 ldr r3, [pc, #136] ; (800d554 ) + 800d4ca: 18d3 adds r3, r2, r3 + 800d4cc: 3304 adds r3, #4 + 800d4ce: 6879 ldr r1, [r7, #4] + 800d4d0: 2206 movs r2, #6 + 800d4d2: 0018 movs r0, r3 + 800d4d4: f002 fbe5 bl 800fca2 + /* reset time stamp */ + arp_table[i].ctime = 0; + 800d4d8: 193b adds r3, r7, r4 + 800d4da: 2200 movs r2, #0 + 800d4dc: 569a ldrsb r2, [r3, r2] + 800d4de: 491d ldr r1, [pc, #116] ; (800d554 ) + 800d4e0: 0013 movs r3, r2 + 800d4e2: 009b lsls r3, r3, #2 + 800d4e4: 189b adds r3, r3, r2 + 800d4e6: 009b lsls r3, r3, #2 + 800d4e8: 18cb adds r3, r1, r3 + 800d4ea: 3313 adds r3, #19 + 800d4ec: 2200 movs r2, #0 + 800d4ee: 701a strb r2, [r3, #0] + /* get the packet pointer */ + p = q->p; + /* now queue entry can be freed */ + memp_free(MEMP_ARP_QUEUE, q); +#else /* ARP_QUEUEING */ + if (arp_table[i].q != NULL) { + 800d4f0: 193b adds r3, r7, r4 + 800d4f2: 2200 movs r2, #0 + 800d4f4: 569a ldrsb r2, [r3, r2] + 800d4f6: 4917 ldr r1, [pc, #92] ; (800d554 ) + 800d4f8: 0013 movs r3, r2 + 800d4fa: 009b lsls r3, r3, #2 + 800d4fc: 189b adds r3, r3, r2 + 800d4fe: 009b lsls r3, r3, #2 + 800d500: 585b ldr r3, [r3, r1] + 800d502: 2b00 cmp r3, #0 + 800d504: d020 beq.n 800d548 + struct pbuf *p = arp_table[i].q; + 800d506: 2017 movs r0, #23 + 800d508: 183b adds r3, r7, r0 + 800d50a: 2200 movs r2, #0 + 800d50c: 569a ldrsb r2, [r3, r2] + 800d50e: 4911 ldr r1, [pc, #68] ; (800d554 ) + 800d510: 0013 movs r3, r2 + 800d512: 009b lsls r3, r3, #2 + 800d514: 189b adds r3, r3, r2 + 800d516: 009b lsls r3, r3, #2 + 800d518: 585b ldr r3, [r3, r1] + 800d51a: 613b str r3, [r7, #16] + arp_table[i].q = NULL; + 800d51c: 183b adds r3, r7, r0 + 800d51e: 2200 movs r2, #0 + 800d520: 569a ldrsb r2, [r3, r2] + 800d522: 490c ldr r1, [pc, #48] ; (800d554 ) + 800d524: 0013 movs r3, r2 + 800d526: 009b lsls r3, r3, #2 + 800d528: 189b adds r3, r3, r2 + 800d52a: 009b lsls r3, r3, #2 + 800d52c: 2200 movs r2, #0 + 800d52e: 505a str r2, [r3, r1] +#endif /* ARP_QUEUEING */ + /* send the queued IP packet */ + etharp_send_ip(netif, p, (struct eth_addr*)(netif->hwaddr), ethaddr); + 800d530: 68fb ldr r3, [r7, #12] + 800d532: 3323 adds r3, #35 ; 0x23 + 800d534: 001a movs r2, r3 + 800d536: 687b ldr r3, [r7, #4] + 800d538: 6939 ldr r1, [r7, #16] + 800d53a: 68f8 ldr r0, [r7, #12] + 800d53c: f7ff ff2a bl 800d394 + /* free the queued IP packet */ + pbuf_free(p); + 800d540: 693b ldr r3, [r7, #16] + 800d542: 0018 movs r0, r3 + 800d544: f7f8 f8ae bl 80056a4 + } + return ERR_OK; + 800d548: 2300 movs r3, #0 +} + 800d54a: 0018 movs r0, r3 + 800d54c: 46bd mov sp, r7 + 800d54e: b006 add sp, #24 + 800d550: bdb0 pop {r4, r5, r7, pc} + 800d552: 46c0 nop ; (mov r8, r8) + 800d554: 200022c0 .word 0x200022c0 + +0800d558 : + * + * @see pbuf_free() + */ +static void +etharp_arp_input(struct netif *netif, struct eth_addr *ethaddr, struct pbuf *p) +{ + 800d558: b590 push {r4, r7, lr} + 800d55a: b08b sub sp, #44 ; 0x2c + 800d55c: af00 add r7, sp, #0 + 800d55e: 60f8 str r0, [r7, #12] + 800d560: 60b9 str r1, [r7, #8] + 800d562: 607a str r2, [r7, #4] + u8_t for_us; +#if LWIP_AUTOIP + const u8_t * ethdst_hwaddr; +#endif /* LWIP_AUTOIP */ + + LWIP_ERROR("netif != NULL", (netif != NULL), return;); + 800d564: 68fb ldr r3, [r7, #12] + 800d566: 2b00 cmp r3, #0 + 800d568: d100 bne.n 800d56c + 800d56a: e0f5 b.n 800d758 + + /* drop short ARP packets: we have to check for p->len instead of p->tot_len here + since a struct etharp_hdr is pointed to p->payload, so it musn't be chained! */ + if (p->len < SIZEOF_ETHARP_PACKET) { + 800d56c: 687b ldr r3, [r7, #4] + 800d56e: 895b ldrh r3, [r3, #10] + 800d570: 2b29 cmp r3, #41 ; 0x29 + 800d572: d810 bhi.n 800d596 + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, + ("etharp_arp_input: packet dropped, too short (%"S16_F"/%"S16_F")\n", p->tot_len, + (s16_t)SIZEOF_ETHARP_PACKET)); + ETHARP_STATS_INC(etharp.lenerr); + 800d574: 4b7a ldr r3, [pc, #488] ; (800d760 ) + 800d576: 8c5b ldrh r3, [r3, #34] ; 0x22 + 800d578: 3301 adds r3, #1 + 800d57a: b29a uxth r2, r3 + 800d57c: 4b78 ldr r3, [pc, #480] ; (800d760 ) + 800d57e: 845a strh r2, [r3, #34] ; 0x22 + ETHARP_STATS_INC(etharp.drop); + 800d580: 4b77 ldr r3, [pc, #476] ; (800d760 ) + 800d582: 8bdb ldrh r3, [r3, #30] + 800d584: 3301 adds r3, #1 + 800d586: b29a uxth r2, r3 + 800d588: 4b75 ldr r3, [pc, #468] ; (800d760 ) + 800d58a: 83da strh r2, [r3, #30] + pbuf_free(p); + 800d58c: 687b ldr r3, [r7, #4] + 800d58e: 0018 movs r0, r3 + 800d590: f7f8 f888 bl 80056a4 + return; + 800d594: e0e1 b.n 800d75a + } + + ethhdr = (struct eth_hdr *)p->payload; + 800d596: 687b ldr r3, [r7, #4] + 800d598: 685b ldr r3, [r3, #4] + 800d59a: 623b str r3, [r7, #32] + hdr = (struct etharp_hdr *)((u8_t*)ethhdr + SIZEOF_ETH_HDR); + 800d59c: 6a3b ldr r3, [r7, #32] + 800d59e: 330e adds r3, #14 + 800d5a0: 61fb str r3, [r7, #28] + hdr = (struct etharp_hdr *)(((u8_t*)ethhdr) + SIZEOF_ETH_HDR + SIZEOF_VLAN_HDR); + } +#endif /* ETHARP_SUPPORT_VLAN */ + + /* RFC 826 "Packet Reception": */ + if ((hdr->hwtype != PP_HTONS(HWTYPE_ETHERNET)) || + 800d5a2: 69fb ldr r3, [r7, #28] + 800d5a4: 781a ldrb r2, [r3, #0] + 800d5a6: 785b ldrb r3, [r3, #1] + 800d5a8: 021b lsls r3, r3, #8 + 800d5aa: 4313 orrs r3, r2 + 800d5ac: b29a uxth r2, r3 + 800d5ae: 2380 movs r3, #128 ; 0x80 + 800d5b0: 005b lsls r3, r3, #1 + 800d5b2: 429a cmp r2, r3 + 800d5b4: d10f bne.n 800d5d6 + (hdr->hwlen != ETHARP_HWADDR_LEN) || + 800d5b6: 69fb ldr r3, [r7, #28] + 800d5b8: 791b ldrb r3, [r3, #4] + if ((hdr->hwtype != PP_HTONS(HWTYPE_ETHERNET)) || + 800d5ba: 2b06 cmp r3, #6 + 800d5bc: d10b bne.n 800d5d6 + (hdr->protolen != sizeof(ip_addr_t)) || + 800d5be: 69fb ldr r3, [r7, #28] + 800d5c0: 795b ldrb r3, [r3, #5] + (hdr->hwlen != ETHARP_HWADDR_LEN) || + 800d5c2: 2b04 cmp r3, #4 + 800d5c4: d107 bne.n 800d5d6 + (hdr->proto != PP_HTONS(ETHTYPE_IP))) { + 800d5c6: 69fb ldr r3, [r7, #28] + 800d5c8: 789a ldrb r2, [r3, #2] + 800d5ca: 78db ldrb r3, [r3, #3] + 800d5cc: 021b lsls r3, r3, #8 + 800d5ce: 4313 orrs r3, r2 + 800d5d0: b29b uxth r3, r3 + (hdr->protolen != sizeof(ip_addr_t)) || + 800d5d2: 2b08 cmp r3, #8 + 800d5d4: d010 beq.n 800d5f8 + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, + ("etharp_arp_input: packet dropped, wrong hw type, hwlen, proto, protolen or ethernet type (%"U16_F"/%"U16_F"/%"U16_F"/%"U16_F")\n", + hdr->hwtype, hdr->hwlen, hdr->proto, hdr->protolen)); + ETHARP_STATS_INC(etharp.proterr); + 800d5d6: 4b62 ldr r3, [pc, #392] ; (800d760 ) + 800d5d8: 8d1b ldrh r3, [r3, #40] ; 0x28 + 800d5da: 3301 adds r3, #1 + 800d5dc: b29a uxth r2, r3 + 800d5de: 4b60 ldr r3, [pc, #384] ; (800d760 ) + 800d5e0: 851a strh r2, [r3, #40] ; 0x28 + ETHARP_STATS_INC(etharp.drop); + 800d5e2: 4b5f ldr r3, [pc, #380] ; (800d760 ) + 800d5e4: 8bdb ldrh r3, [r3, #30] + 800d5e6: 3301 adds r3, #1 + 800d5e8: b29a uxth r2, r3 + 800d5ea: 4b5d ldr r3, [pc, #372] ; (800d760 ) + 800d5ec: 83da strh r2, [r3, #30] + pbuf_free(p); + 800d5ee: 687b ldr r3, [r7, #4] + 800d5f0: 0018 movs r0, r3 + 800d5f2: f7f8 f857 bl 80056a4 + return; + 800d5f6: e0b0 b.n 800d75a + } + ETHARP_STATS_INC(etharp.recv); + 800d5f8: 4b59 ldr r3, [pc, #356] ; (800d760 ) + 800d5fa: 8b5b ldrh r3, [r3, #26] + 800d5fc: 3301 adds r3, #1 + 800d5fe: b29a uxth r2, r3 + 800d600: 4b57 ldr r3, [pc, #348] ; (800d760 ) + 800d602: 835a strh r2, [r3, #26] + autoip_arp_reply(netif, hdr); +#endif /* LWIP_AUTOIP */ + + /* Copy struct ip_addr2 to aligned ip_addr, to support compilers without + * structure packing (not using structure copy which breaks strict-aliasing rules). */ + IPADDR2_COPY(&sipaddr, &hdr->sipaddr); + 800d604: 69fb ldr r3, [r7, #28] + 800d606: 330e adds r3, #14 + 800d608: 0019 movs r1, r3 + 800d60a: 2318 movs r3, #24 + 800d60c: 18fb adds r3, r7, r3 + 800d60e: 2204 movs r2, #4 + 800d610: 0018 movs r0, r3 + 800d612: f002 fb46 bl 800fca2 + IPADDR2_COPY(&dipaddr, &hdr->dipaddr); + 800d616: 69fb ldr r3, [r7, #28] + 800d618: 3318 adds r3, #24 + 800d61a: 0019 movs r1, r3 + 800d61c: 2314 movs r3, #20 + 800d61e: 18fb adds r3, r7, r3 + 800d620: 2204 movs r2, #4 + 800d622: 0018 movs r0, r3 + 800d624: f002 fb3d bl 800fca2 + + /* this interface is not configured? */ + if (ip_addr_isany(&netif->ip_addr)) { + 800d628: 68fb ldr r3, [r7, #12] + 800d62a: 3304 adds r3, #4 + 800d62c: 2b00 cmp r3, #0 + 800d62e: d003 beq.n 800d638 + 800d630: 68fb ldr r3, [r7, #12] + 800d632: 685b ldr r3, [r3, #4] + 800d634: 2b00 cmp r3, #0 + 800d636: d104 bne.n 800d642 + for_us = 0; + 800d638: 2327 movs r3, #39 ; 0x27 + 800d63a: 18fb adds r3, r7, r3 + 800d63c: 2200 movs r2, #0 + 800d63e: 701a strb r2, [r3, #0] + 800d640: e009 b.n 800d656 + } else { + /* ARP packet directed to us? */ + for_us = (u8_t)ip_addr_cmp(&dipaddr, &(netif->ip_addr)); + 800d642: 697a ldr r2, [r7, #20] + 800d644: 68fb ldr r3, [r7, #12] + 800d646: 685b ldr r3, [r3, #4] + 800d648: 1ad3 subs r3, r2, r3 + 800d64a: 425a negs r2, r3 + 800d64c: 4153 adcs r3, r2 + 800d64e: b2da uxtb r2, r3 + 800d650: 2327 movs r3, #39 ; 0x27 + 800d652: 18fb adds r3, r7, r3 + 800d654: 701a strb r2, [r3, #0] + /* ARP message directed to us? + -> add IP address in ARP cache; assume requester wants to talk to us, + can result in directly sending the queued packets for this host. + ARP message not directed to us? + -> update the source IP address in the cache, if present */ + etharp_update_arp_entry(netif, &sipaddr, &(hdr->shwaddr), + 800d656: 69fb ldr r3, [r7, #28] + 800d658: 3308 adds r3, #8 + 800d65a: 001a movs r2, r3 + 800d65c: 2327 movs r3, #39 ; 0x27 + 800d65e: 18fb adds r3, r7, r3 + 800d660: 781b ldrb r3, [r3, #0] + 800d662: 2b00 cmp r3, #0 + 800d664: d001 beq.n 800d66a + 800d666: 2301 movs r3, #1 + 800d668: e000 b.n 800d66c + 800d66a: 2302 movs r3, #2 + 800d66c: 2118 movs r1, #24 + 800d66e: 1879 adds r1, r7, r1 + 800d670: 68f8 ldr r0, [r7, #12] + 800d672: f7ff febd bl 800d3f0 + for_us ? ETHARP_FLAG_TRY_HARD : ETHARP_FLAG_FIND_ONLY); + + /* now act on the message itself */ + switch (hdr->opcode) { + 800d676: 69fb ldr r3, [r7, #28] + 800d678: 799a ldrb r2, [r3, #6] + 800d67a: 79db ldrb r3, [r3, #7] + 800d67c: 021b lsls r3, r3, #8 + 800d67e: 4313 orrs r3, r2 + 800d680: b29b uxth r3, r3 + 800d682: 2280 movs r2, #128 ; 0x80 + 800d684: 0052 lsls r2, r2, #1 + 800d686: 4293 cmp r3, r2 + 800d688: d004 beq.n 800d694 + 800d68a: 2280 movs r2, #128 ; 0x80 + 800d68c: 0092 lsls r2, r2, #2 + 800d68e: 4293 cmp r3, r2 + 800d690: d05c beq.n 800d74c + 800d692: e054 b.n 800d73e + * reply. In any case, we time-stamp any existing ARP entry, + * and possiby send out an IP packet that was queued on it. */ + + LWIP_DEBUGF (ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_arp_input: incoming ARP request\n")); + /* ARP request for our address? */ + if (for_us) { + 800d694: 2327 movs r3, #39 ; 0x27 + 800d696: 18fb adds r3, r7, r3 + 800d698: 781b ldrb r3, [r3, #0] + 800d69a: 2b00 cmp r3, #0 + 800d69c: d057 beq.n 800d74e + + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_arp_input: replying to ARP request for our IP address\n")); + /* Re-use pbuf to send ARP reply. + Since we are re-using an existing pbuf, we can't call etharp_raw since + that would allocate a new pbuf. */ + hdr->opcode = htons(ARP_REPLY); + 800d69e: 2002 movs r0, #2 + 800d6a0: f7f6 ffb8 bl 8004614 + 800d6a4: 0003 movs r3, r0 + 800d6a6: 001a movs r2, r3 + 800d6a8: 69fb ldr r3, [r7, #28] + 800d6aa: 21ff movs r1, #255 ; 0xff + 800d6ac: 4011 ands r1, r2 + 800d6ae: 000c movs r4, r1 + 800d6b0: 7999 ldrb r1, [r3, #6] + 800d6b2: 2000 movs r0, #0 + 800d6b4: 4001 ands r1, r0 + 800d6b6: 1c08 adds r0, r1, #0 + 800d6b8: 1c21 adds r1, r4, #0 + 800d6ba: 4301 orrs r1, r0 + 800d6bc: 7199 strb r1, [r3, #6] + 800d6be: 0a12 lsrs r2, r2, #8 + 800d6c0: b290 uxth r0, r2 + 800d6c2: 79da ldrb r2, [r3, #7] + 800d6c4: 2100 movs r1, #0 + 800d6c6: 400a ands r2, r1 + 800d6c8: 1c11 adds r1, r2, #0 + 800d6ca: 1c02 adds r2, r0, #0 + 800d6cc: 430a orrs r2, r1 + 800d6ce: 71da strb r2, [r3, #7] + + IPADDR2_COPY(&hdr->dipaddr, &hdr->sipaddr); + 800d6d0: 69fb ldr r3, [r7, #28] + 800d6d2: 3318 adds r3, #24 + 800d6d4: 0018 movs r0, r3 + 800d6d6: 69fb ldr r3, [r7, #28] + 800d6d8: 330e adds r3, #14 + 800d6da: 2204 movs r2, #4 + 800d6dc: 0019 movs r1, r3 + 800d6de: f002 fae0 bl 800fca2 + IPADDR2_COPY(&hdr->sipaddr, &netif->ip_addr); + 800d6e2: 69fb ldr r3, [r7, #28] + 800d6e4: 330e adds r3, #14 + 800d6e6: 0018 movs r0, r3 + 800d6e8: 68fb ldr r3, [r7, #12] + 800d6ea: 3304 adds r3, #4 + 800d6ec: 2204 movs r2, #4 + 800d6ee: 0019 movs r1, r3 + 800d6f0: f002 fad7 bl 800fca2 + * 'sender IP address' MUST be sent using link-layer broadcast instead of + * link-layer unicast. (See RFC3927 Section 2.5, last paragraph) */ + ethdst_hwaddr = ip_addr_islinklocal(&netif->ip_addr) ? (u8_t*)(ethbroadcast.addr) : hdr->shwaddr.addr; +#endif /* LWIP_AUTOIP */ + + ETHADDR16_COPY(&hdr->dhwaddr, &hdr->shwaddr); + 800d6f4: 69fb ldr r3, [r7, #28] + 800d6f6: 3312 adds r3, #18 + 800d6f8: 0018 movs r0, r3 + 800d6fa: 69fb ldr r3, [r7, #28] + 800d6fc: 3308 adds r3, #8 + 800d6fe: 2206 movs r2, #6 + 800d700: 0019 movs r1, r3 + 800d702: f002 face bl 800fca2 +#if LWIP_AUTOIP + ETHADDR16_COPY(ðhdr->dest, ethdst_hwaddr); +#else /* LWIP_AUTOIP */ + ETHADDR16_COPY(ðhdr->dest, &hdr->shwaddr); + 800d706: 6a38 ldr r0, [r7, #32] + 800d708: 69fb ldr r3, [r7, #28] + 800d70a: 3308 adds r3, #8 + 800d70c: 2206 movs r2, #6 + 800d70e: 0019 movs r1, r3 + 800d710: f002 fac7 bl 800fca2 +#endif /* LWIP_AUTOIP */ + ETHADDR16_COPY(&hdr->shwaddr, ethaddr); + 800d714: 69fb ldr r3, [r7, #28] + 800d716: 3308 adds r3, #8 + 800d718: 68b9 ldr r1, [r7, #8] + 800d71a: 2206 movs r2, #6 + 800d71c: 0018 movs r0, r3 + 800d71e: f002 fac0 bl 800fca2 + ETHADDR16_COPY(ðhdr->src, ethaddr); + 800d722: 6a3b ldr r3, [r7, #32] + 800d724: 3306 adds r3, #6 + 800d726: 68b9 ldr r1, [r7, #8] + 800d728: 2206 movs r2, #6 + 800d72a: 0018 movs r0, r3 + 800d72c: f002 fab9 bl 800fca2 + + /* hwtype, hwaddr_len, proto, protolen and the type in the ethernet header + are already correct, we tested that before */ + + /* return ARP reply */ + netif->linkoutput(netif, p); + 800d730: 68fb ldr r3, [r7, #12] + 800d732: 699b ldr r3, [r3, #24] + 800d734: 6879 ldr r1, [r7, #4] + 800d736: 68fa ldr r2, [r7, #12] + 800d738: 0010 movs r0, r2 + 800d73a: 4798 blx r3 + /* request was not directed to us */ + } else { + /* { for_us == 0 and netif->ip_addr.addr != 0 } */ + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_arp_input: ARP request was not for us.\n")); + } + break; + 800d73c: e007 b.n 800d74e + dhcp_arp_reply(netif, &sipaddr); +#endif /* (LWIP_DHCP && DHCP_DOES_ARP_CHECK) */ + break; + default: + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_arp_input: ARP unknown opcode type %"S16_F"\n", htons(hdr->opcode))); + ETHARP_STATS_INC(etharp.err); + 800d73e: 4b08 ldr r3, [pc, #32] ; (800d760 ) + 800d740: 8d9b ldrh r3, [r3, #44] ; 0x2c + 800d742: 3301 adds r3, #1 + 800d744: b29a uxth r2, r3 + 800d746: 4b06 ldr r3, [pc, #24] ; (800d760 ) + 800d748: 859a strh r2, [r3, #44] ; 0x2c + break; + 800d74a: e000 b.n 800d74e + break; + 800d74c: 46c0 nop ; (mov r8, r8) + } + /* free ARP packet */ + pbuf_free(p); + 800d74e: 687b ldr r3, [r7, #4] + 800d750: 0018 movs r0, r3 + 800d752: f7f7 ffa7 bl 80056a4 + 800d756: e000 b.n 800d75a + LWIP_ERROR("netif != NULL", (netif != NULL), return;); + 800d758: 46c0 nop ; (mov r8, r8) +} + 800d75a: 46bd mov sp, r7 + 800d75c: b00b add sp, #44 ; 0x2c + 800d75e: bd90 pop {r4, r7, pc} + 800d760: 20003158 .word 0x20003158 + +0800d764 : +/** Just a small helper function that sends a pbuf to an ethernet address + * in the arp_table specified by the index 'arp_idx'. + */ +static err_t +etharp_output_to_arp_index(struct netif *netif, struct pbuf *q, u8_t arp_idx) +{ + 800d764: b590 push {r4, r7, lr} + 800d766: b085 sub sp, #20 + 800d768: af00 add r7, sp, #0 + 800d76a: 60f8 str r0, [r7, #12] + 800d76c: 60b9 str r1, [r7, #8] + 800d76e: 1dfb adds r3, r7, #7 + 800d770: 701a strb r2, [r3, #0] + LWIP_ASSERT("arp_table[arp_idx].state >= ETHARP_STATE_STABLE", + 800d772: 1dfb adds r3, r7, #7 + 800d774: 781a ldrb r2, [r3, #0] + 800d776: 0013 movs r3, r2 + 800d778: 009b lsls r3, r3, #2 + 800d77a: 189b adds r3, r3, r2 + 800d77c: 009b lsls r3, r3, #2 + arp_table[arp_idx].state >= ETHARP_STATE_STABLE); + /* if arp table entry is about to expire: re-request it, + but only if its state is ETHARP_STATE_STABLE to prevent flooding the + network with ARP requests if this address is used frequently. */ + if ((arp_table[arp_idx].state == ETHARP_STATE_STABLE) && + 800d77e: 1dfb adds r3, r7, #7 + 800d780: 781a ldrb r2, [r3, #0] + 800d782: 4924 ldr r1, [pc, #144] ; (800d814 ) + 800d784: 0013 movs r3, r2 + 800d786: 009b lsls r3, r3, #2 + 800d788: 189b adds r3, r3, r2 + 800d78a: 009b lsls r3, r3, #2 + 800d78c: 18cb adds r3, r1, r3 + 800d78e: 3312 adds r3, #18 + 800d790: 781b ldrb r3, [r3, #0] + 800d792: 2b02 cmp r3, #2 + 800d794: d126 bne.n 800d7e4 + (arp_table[arp_idx].ctime >= ARP_AGE_REREQUEST_USED)) { + 800d796: 1dfb adds r3, r7, #7 + 800d798: 781a ldrb r2, [r3, #0] + 800d79a: 491e ldr r1, [pc, #120] ; (800d814 ) + 800d79c: 0013 movs r3, r2 + 800d79e: 009b lsls r3, r3, #2 + 800d7a0: 189b adds r3, r3, r2 + 800d7a2: 009b lsls r3, r3, #2 + 800d7a4: 18cb adds r3, r1, r3 + 800d7a6: 3313 adds r3, #19 + 800d7a8: 781b ldrb r3, [r3, #0] + if ((arp_table[arp_idx].state == ETHARP_STATE_STABLE) && + 800d7aa: 2be3 cmp r3, #227 ; 0xe3 + 800d7ac: d91a bls.n 800d7e4 + if (etharp_request(netif, &arp_table[arp_idx].ipaddr) == ERR_OK) { + 800d7ae: 1dfb adds r3, r7, #7 + 800d7b0: 781a ldrb r2, [r3, #0] + 800d7b2: 0013 movs r3, r2 + 800d7b4: 009b lsls r3, r3, #2 + 800d7b6: 189b adds r3, r3, r2 + 800d7b8: 009b lsls r3, r3, #2 + 800d7ba: 4a16 ldr r2, [pc, #88] ; (800d814 ) + 800d7bc: 189b adds r3, r3, r2 + 800d7be: 1d1a adds r2, r3, #4 + 800d7c0: 68fb ldr r3, [r7, #12] + 800d7c2: 0011 movs r1, r2 + 800d7c4: 0018 movs r0, r3 + 800d7c6: f000 fb15 bl 800ddf4 + 800d7ca: 1e03 subs r3, r0, #0 + 800d7cc: d10a bne.n 800d7e4 + arp_table[arp_idx].state = ETHARP_STATE_STABLE_REREQUESTING; + 800d7ce: 1dfb adds r3, r7, #7 + 800d7d0: 781a ldrb r2, [r3, #0] + 800d7d2: 4910 ldr r1, [pc, #64] ; (800d814 ) + 800d7d4: 0013 movs r3, r2 + 800d7d6: 009b lsls r3, r3, #2 + 800d7d8: 189b adds r3, r3, r2 + 800d7da: 009b lsls r3, r3, #2 + 800d7dc: 18cb adds r3, r1, r3 + 800d7de: 3312 adds r3, #18 + 800d7e0: 2203 movs r2, #3 + 800d7e2: 701a strb r2, [r3, #0] + } + } + + return etharp_send_ip(netif, q, (struct eth_addr*)(netif->hwaddr), + 800d7e4: 68fb ldr r3, [r7, #12] + 800d7e6: 3323 adds r3, #35 ; 0x23 + 800d7e8: 001c movs r4, r3 + &arp_table[arp_idx].ethaddr); + 800d7ea: 1dfb adds r3, r7, #7 + 800d7ec: 781a ldrb r2, [r3, #0] + return etharp_send_ip(netif, q, (struct eth_addr*)(netif->hwaddr), + 800d7ee: 0013 movs r3, r2 + 800d7f0: 009b lsls r3, r3, #2 + 800d7f2: 189b adds r3, r3, r2 + 800d7f4: 009b lsls r3, r3, #2 + 800d7f6: 3308 adds r3, #8 + 800d7f8: 001a movs r2, r3 + 800d7fa: 4b06 ldr r3, [pc, #24] ; (800d814 ) + 800d7fc: 18d3 adds r3, r2, r3 + 800d7fe: 3304 adds r3, #4 + 800d800: 68b9 ldr r1, [r7, #8] + 800d802: 68f8 ldr r0, [r7, #12] + 800d804: 0022 movs r2, r4 + 800d806: f7ff fdc5 bl 800d394 + 800d80a: 0003 movs r3, r0 +} + 800d80c: 0018 movs r0, r3 + 800d80e: 46bd mov sp, r7 + 800d810: b005 add sp, #20 + 800d812: bd90 pop {r4, r7, pc} + 800d814: 200022c0 .word 0x200022c0 + +0800d818 : + * - ERR_RTE No route to destination (no gateway to external networks), + * or the return type of either etharp_query() or etharp_send_ip(). + */ +err_t +etharp_output(struct netif *netif, struct pbuf *q, ip_addr_t *ipaddr) +{ + 800d818: b580 push {r7, lr} + 800d81a: b088 sub sp, #32 + 800d81c: af00 add r7, sp, #0 + 800d81e: 60f8 str r0, [r7, #12] + 800d820: 60b9 str r1, [r7, #8] + 800d822: 607a str r2, [r7, #4] + struct eth_addr *dest; + struct eth_addr mcastaddr; + ip_addr_t *dst_addr = ipaddr; + 800d824: 687b ldr r3, [r7, #4] + 800d826: 61bb str r3, [r7, #24] + LWIP_ASSERT("netif != NULL", netif != NULL); + LWIP_ASSERT("q != NULL", q != NULL); + LWIP_ASSERT("ipaddr != NULL", ipaddr != NULL); + + /* make room for Ethernet header - should not fail */ + if (pbuf_header(q, sizeof(struct eth_hdr)) != 0) { + 800d828: 68bb ldr r3, [r7, #8] + 800d82a: 210e movs r1, #14 + 800d82c: 0018 movs r0, r3 + 800d82e: f7f7 feb2 bl 8005596 + 800d832: 1e03 subs r3, r0, #0 + 800d834: d008 beq.n 800d848 + /* bail out */ + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, + ("etharp_output: could not allocate room for header.\n")); + LINK_STATS_INC(link.lenerr); + 800d836: 4b6b ldr r3, [pc, #428] ; (800d9e4 ) + 800d838: 895b ldrh r3, [r3, #10] + 800d83a: 3301 adds r3, #1 + 800d83c: b29a uxth r2, r3 + 800d83e: 4b69 ldr r3, [pc, #420] ; (800d9e4 ) + 800d840: 815a strh r2, [r3, #10] + return ERR_BUF; + 800d842: 2302 movs r3, #2 + 800d844: 425b negs r3, r3 + 800d846: e0c9 b.n 800d9dc + + /* Determine on destination hardware address. Broadcasts and multicasts + * are special, other IP addresses are looked up in the ARP table. */ + + /* broadcast destination IP address? */ + if (ip_addr_isbroadcast(ipaddr, netif)) { + 800d848: 687b ldr r3, [r7, #4] + 800d84a: 681b ldr r3, [r3, #0] + 800d84c: 68fa ldr r2, [r7, #12] + 800d84e: 0011 movs r1, r2 + 800d850: 0018 movs r0, r3 + 800d852: f7fe fc13 bl 800c07c + 800d856: 1e03 subs r3, r0, #0 + 800d858: d002 beq.n 800d860 + /* broadcast on Ethernet also */ + dest = (struct eth_addr *)ðbroadcast; + 800d85a: 4b63 ldr r3, [pc, #396] ; (800d9e8 ) + 800d85c: 61fb str r3, [r7, #28] + 800d85e: e0b4 b.n 800d9ca + /* multicast destination IP address? */ + } else if (ip_addr_ismulticast(ipaddr)) { + 800d860: 687b ldr r3, [r7, #4] + 800d862: 681b ldr r3, [r3, #0] + 800d864: 22f0 movs r2, #240 ; 0xf0 + 800d866: 4013 ands r3, r2 + 800d868: 2be0 cmp r3, #224 ; 0xe0 + 800d86a: d11c bne.n 800d8a6 + /* Hash IP multicast address to MAC address.*/ + mcastaddr.addr[0] = LL_MULTICAST_ADDR_0; + 800d86c: 2110 movs r1, #16 + 800d86e: 187b adds r3, r7, r1 + 800d870: 2201 movs r2, #1 + 800d872: 701a strb r2, [r3, #0] + mcastaddr.addr[1] = LL_MULTICAST_ADDR_1; + 800d874: 187b adds r3, r7, r1 + 800d876: 2200 movs r2, #0 + 800d878: 705a strb r2, [r3, #1] + mcastaddr.addr[2] = LL_MULTICAST_ADDR_2; + 800d87a: 187b adds r3, r7, r1 + 800d87c: 225e movs r2, #94 ; 0x5e + 800d87e: 709a strb r2, [r3, #2] + mcastaddr.addr[3] = ip4_addr2(ipaddr) & 0x7f; + 800d880: 687b ldr r3, [r7, #4] + 800d882: 3301 adds r3, #1 + 800d884: 781b ldrb r3, [r3, #0] + 800d886: 227f movs r2, #127 ; 0x7f + 800d888: 4013 ands r3, r2 + 800d88a: b2da uxtb r2, r3 + 800d88c: 187b adds r3, r7, r1 + 800d88e: 70da strb r2, [r3, #3] + mcastaddr.addr[4] = ip4_addr3(ipaddr); + 800d890: 687b ldr r3, [r7, #4] + 800d892: 789a ldrb r2, [r3, #2] + 800d894: 187b adds r3, r7, r1 + 800d896: 711a strb r2, [r3, #4] + mcastaddr.addr[5] = ip4_addr4(ipaddr); + 800d898: 687b ldr r3, [r7, #4] + 800d89a: 78da ldrb r2, [r3, #3] + 800d89c: 187b adds r3, r7, r1 + 800d89e: 715a strb r2, [r3, #5] + /* destination Ethernet address is multicast */ + dest = &mcastaddr; + 800d8a0: 187b adds r3, r7, r1 + 800d8a2: 61fb str r3, [r7, #28] + 800d8a4: e091 b.n 800d9ca + /* unicast destination IP address? */ + } else { + s8_t i; + /* outside local network? if so, this can neither be a global broadcast nor + a subnet broadcast. */ + if (!ip_addr_netcmp(ipaddr, &(netif->ip_addr), &(netif->netmask)) && + 800d8a6: 687b ldr r3, [r7, #4] + 800d8a8: 681a ldr r2, [r3, #0] + 800d8aa: 68fb ldr r3, [r7, #12] + 800d8ac: 685b ldr r3, [r3, #4] + 800d8ae: 405a eors r2, r3 + 800d8b0: 68fb ldr r3, [r7, #12] + 800d8b2: 689b ldr r3, [r3, #8] + 800d8b4: 4013 ands r3, r2 + 800d8b6: d015 beq.n 800d8e4 + !ip_addr_islinklocal(ipaddr)) { + 800d8b8: 687b ldr r3, [r7, #4] + 800d8ba: 681b ldr r3, [r3, #0] + 800d8bc: 041b lsls r3, r3, #16 + 800d8be: 0c1b lsrs r3, r3, #16 + if (!ip_addr_netcmp(ipaddr, &(netif->ip_addr), &(netif->netmask)) && + 800d8c0: 4a4a ldr r2, [pc, #296] ; (800d9ec ) + 800d8c2: 4293 cmp r3, r2 + 800d8c4: d00e beq.n 800d8e4 + router for forwarding". */ + if (!ip_addr_islinklocal(&iphdr->src)) +#endif /* LWIP_AUTOIP */ + { + /* interface has default gateway? */ + if (!ip_addr_isany(&netif->gw)) { + 800d8c6: 68fb ldr r3, [r7, #12] + 800d8c8: 330c adds r3, #12 + 800d8ca: 2b00 cmp r3, #0 + 800d8cc: d007 beq.n 800d8de + 800d8ce: 68fb ldr r3, [r7, #12] + 800d8d0: 68db ldr r3, [r3, #12] + 800d8d2: 2b00 cmp r3, #0 + 800d8d4: d003 beq.n 800d8de + /* send to hardware address of default gateway IP address */ + dst_addr = &(netif->gw); + 800d8d6: 68fb ldr r3, [r7, #12] + 800d8d8: 330c adds r3, #12 + 800d8da: 61bb str r3, [r7, #24] + 800d8dc: e002 b.n 800d8e4 + /* no default gateway available */ + } else { + /* no route to destination error (default gateway missing) */ + return ERR_RTE; + 800d8de: 2304 movs r3, #4 + 800d8e0: 425b negs r3, r3 + 800d8e2: e07b b.n 800d9dc + if (netif->addr_hint != NULL) { + /* per-pcb cached entry was given */ + u8_t etharp_cached_entry = *(netif->addr_hint); + if (etharp_cached_entry < ARP_TABLE_SIZE) { +#endif /* LWIP_NETIF_HWADDRHINT */ + if ((arp_table[etharp_cached_entry].state >= ETHARP_STATE_STABLE) && + 800d8e4: 4b42 ldr r3, [pc, #264] ; (800d9f0 ) + 800d8e6: 781b ldrb r3, [r3, #0] + 800d8e8: 0019 movs r1, r3 + 800d8ea: 4a42 ldr r2, [pc, #264] ; (800d9f4 ) + 800d8ec: 000b movs r3, r1 + 800d8ee: 009b lsls r3, r3, #2 + 800d8f0: 185b adds r3, r3, r1 + 800d8f2: 009b lsls r3, r3, #2 + 800d8f4: 18d3 adds r3, r2, r3 + 800d8f6: 3312 adds r3, #18 + 800d8f8: 781b ldrb r3, [r3, #0] + 800d8fa: 2b01 cmp r3, #1 + 800d8fc: d91d bls.n 800d93a + (ip_addr_cmp(dst_addr, &arp_table[etharp_cached_entry].ipaddr))) { + 800d8fe: 69bb ldr r3, [r7, #24] + 800d900: 681a ldr r2, [r3, #0] + 800d902: 4b3b ldr r3, [pc, #236] ; (800d9f0 ) + 800d904: 781b ldrb r3, [r3, #0] + 800d906: 0018 movs r0, r3 + 800d908: 493a ldr r1, [pc, #232] ; (800d9f4 ) + 800d90a: 0003 movs r3, r0 + 800d90c: 009b lsls r3, r3, #2 + 800d90e: 181b adds r3, r3, r0 + 800d910: 009b lsls r3, r3, #2 + 800d912: 18cb adds r3, r1, r3 + 800d914: 3304 adds r3, #4 + 800d916: 681b ldr r3, [r3, #0] + if ((arp_table[etharp_cached_entry].state >= ETHARP_STATE_STABLE) && + 800d918: 429a cmp r2, r3 + 800d91a: d10e bne.n 800d93a + /* the per-pcb-cached entry is stable and the right one! */ + ETHARP_STATS_INC(etharp.cachehit); + 800d91c: 4b31 ldr r3, [pc, #196] ; (800d9e4 ) + 800d91e: 8ddb ldrh r3, [r3, #46] ; 0x2e + 800d920: 3301 adds r3, #1 + 800d922: b29a uxth r2, r3 + 800d924: 4b2f ldr r3, [pc, #188] ; (800d9e4 ) + 800d926: 85da strh r2, [r3, #46] ; 0x2e + return etharp_output_to_arp_index(netif, q, etharp_cached_entry); + 800d928: 4b31 ldr r3, [pc, #196] ; (800d9f0 ) + 800d92a: 781a ldrb r2, [r3, #0] + 800d92c: 68b9 ldr r1, [r7, #8] + 800d92e: 68fb ldr r3, [r7, #12] + 800d930: 0018 movs r0, r3 + 800d932: f7ff ff17 bl 800d764 + 800d936: 0003 movs r3, r0 + 800d938: e050 b.n 800d9dc + } +#endif /* LWIP_NETIF_HWADDRHINT */ + + /* find stable entry: do this here since this is a critical path for + throughput and etharp_find_entry() is kind of slow */ + for (i = 0; i < ARP_TABLE_SIZE; i++) { + 800d93a: 2317 movs r3, #23 + 800d93c: 18fb adds r3, r7, r3 + 800d93e: 2200 movs r2, #0 + 800d940: 701a strb r2, [r3, #0] + 800d942: e034 b.n 800d9ae + if ((arp_table[i].state >= ETHARP_STATE_STABLE) && + 800d944: 2317 movs r3, #23 + 800d946: 18fb adds r3, r7, r3 + 800d948: 2200 movs r2, #0 + 800d94a: 569a ldrsb r2, [r3, r2] + 800d94c: 4929 ldr r1, [pc, #164] ; (800d9f4 ) + 800d94e: 0013 movs r3, r2 + 800d950: 009b lsls r3, r3, #2 + 800d952: 189b adds r3, r3, r2 + 800d954: 009b lsls r3, r3, #2 + 800d956: 18cb adds r3, r1, r3 + 800d958: 3312 adds r3, #18 + 800d95a: 781b ldrb r3, [r3, #0] + 800d95c: 2b01 cmp r3, #1 + 800d95e: d91d bls.n 800d99c + (ip_addr_cmp(dst_addr, &arp_table[i].ipaddr))) { + 800d960: 69bb ldr r3, [r7, #24] + 800d962: 6819 ldr r1, [r3, #0] + 800d964: 2317 movs r3, #23 + 800d966: 18fb adds r3, r7, r3 + 800d968: 2200 movs r2, #0 + 800d96a: 569a ldrsb r2, [r3, r2] + 800d96c: 4821 ldr r0, [pc, #132] ; (800d9f4 ) + 800d96e: 0013 movs r3, r2 + 800d970: 009b lsls r3, r3, #2 + 800d972: 189b adds r3, r3, r2 + 800d974: 009b lsls r3, r3, #2 + 800d976: 18c3 adds r3, r0, r3 + 800d978: 3304 adds r3, #4 + 800d97a: 681b ldr r3, [r3, #0] + if ((arp_table[i].state >= ETHARP_STATE_STABLE) && + 800d97c: 4299 cmp r1, r3 + 800d97e: d10d bne.n 800d99c + /* found an existing, stable entry */ + ETHARP_SET_HINT(netif, i); + 800d980: 2117 movs r1, #23 + 800d982: 187b adds r3, r7, r1 + 800d984: 781a ldrb r2, [r3, #0] + 800d986: 4b1a ldr r3, [pc, #104] ; (800d9f0 ) + 800d988: 701a strb r2, [r3, #0] + return etharp_output_to_arp_index(netif, q, i); + 800d98a: 187b adds r3, r7, r1 + 800d98c: 781a ldrb r2, [r3, #0] + 800d98e: 68b9 ldr r1, [r7, #8] + 800d990: 68fb ldr r3, [r7, #12] + 800d992: 0018 movs r0, r3 + 800d994: f7ff fee6 bl 800d764 + 800d998: 0003 movs r3, r0 + 800d99a: e01f b.n 800d9dc + for (i = 0; i < ARP_TABLE_SIZE; i++) { + 800d99c: 2117 movs r1, #23 + 800d99e: 187b adds r3, r7, r1 + 800d9a0: 781b ldrb r3, [r3, #0] + 800d9a2: b25b sxtb r3, r3 + 800d9a4: b2db uxtb r3, r3 + 800d9a6: 3301 adds r3, #1 + 800d9a8: b2da uxtb r2, r3 + 800d9aa: 187b adds r3, r7, r1 + 800d9ac: 701a strb r2, [r3, #0] + 800d9ae: 2317 movs r3, #23 + 800d9b0: 18fb adds r3, r7, r3 + 800d9b2: 781b ldrb r3, [r3, #0] + 800d9b4: b25b sxtb r3, r3 + 800d9b6: 2b09 cmp r3, #9 + 800d9b8: ddc4 ble.n 800d944 + } + } + /* no stable entry found, use the (slower) query function: + queue on destination Ethernet address belonging to ipaddr */ + return etharp_query(netif, dst_addr, q); + 800d9ba: 68ba ldr r2, [r7, #8] + 800d9bc: 69b9 ldr r1, [r7, #24] + 800d9be: 68fb ldr r3, [r7, #12] + 800d9c0: 0018 movs r0, r3 + 800d9c2: f000 f819 bl 800d9f8 + 800d9c6: 0003 movs r3, r0 + 800d9c8: e008 b.n 800d9dc + } + + /* continuation for multicast/broadcast destinations */ + /* obtain source Ethernet address of the given interface */ + /* send packet directly on the link */ + return etharp_send_ip(netif, q, (struct eth_addr*)(netif->hwaddr), dest); + 800d9ca: 68fb ldr r3, [r7, #12] + 800d9cc: 3323 adds r3, #35 ; 0x23 + 800d9ce: 001a movs r2, r3 + 800d9d0: 69fb ldr r3, [r7, #28] + 800d9d2: 68b9 ldr r1, [r7, #8] + 800d9d4: 68f8 ldr r0, [r7, #12] + 800d9d6: f7ff fcdd bl 800d394 + 800d9da: 0003 movs r3, r0 +} + 800d9dc: 0018 movs r0, r3 + 800d9de: 46bd mov sp, r7 + 800d9e0: b008 add sp, #32 + 800d9e2: bd80 pop {r7, pc} + 800d9e4: 20003158 .word 0x20003158 + 800d9e8: 0800fdc8 .word 0x0800fdc8 + 800d9ec: 0000fea9 .word 0x0000fea9 + 800d9f0: 20002388 .word 0x20002388 + 800d9f4: 200022c0 .word 0x200022c0 + +0800d9f8 : + * - ERR_ARG Non-unicast address given, those will not appear in ARP cache. + * + */ +err_t +etharp_query(struct netif *netif, ip_addr_t *ipaddr, struct pbuf *q) +{ + 800d9f8: b5b0 push {r4, r5, r7, lr} + 800d9fa: b08a sub sp, #40 ; 0x28 + 800d9fc: af00 add r7, sp, #0 + 800d9fe: 60f8 str r0, [r7, #12] + 800da00: 60b9 str r1, [r7, #8] + 800da02: 607a str r2, [r7, #4] + struct eth_addr * srcaddr = (struct eth_addr *)netif->hwaddr; + 800da04: 68fb ldr r3, [r7, #12] + 800da06: 3323 adds r3, #35 ; 0x23 + 800da08: 61bb str r3, [r7, #24] + err_t result = ERR_MEM; + 800da0a: 2327 movs r3, #39 ; 0x27 + 800da0c: 18fb adds r3, r7, r3 + 800da0e: 22ff movs r2, #255 ; 0xff + 800da10: 701a strb r2, [r3, #0] + s8_t i; /* ARP entry index */ + + /* non-unicast address? */ + if (ip_addr_isbroadcast(ipaddr, netif) || + 800da12: 68bb ldr r3, [r7, #8] + 800da14: 681b ldr r3, [r3, #0] + 800da16: 68fa ldr r2, [r7, #12] + 800da18: 0011 movs r1, r2 + 800da1a: 0018 movs r0, r3 + 800da1c: f7fe fb2e bl 800c07c + 800da20: 1e03 subs r3, r0, #0 + 800da22: d10c bne.n 800da3e + ip_addr_ismulticast(ipaddr) || + 800da24: 68bb ldr r3, [r7, #8] + 800da26: 681b ldr r3, [r3, #0] + 800da28: 22f0 movs r2, #240 ; 0xf0 + 800da2a: 4013 ands r3, r2 + if (ip_addr_isbroadcast(ipaddr, netif) || + 800da2c: 2be0 cmp r3, #224 ; 0xe0 + 800da2e: d006 beq.n 800da3e + ip_addr_ismulticast(ipaddr) || + 800da30: 68bb ldr r3, [r7, #8] + 800da32: 2b00 cmp r3, #0 + 800da34: d003 beq.n 800da3e + ip_addr_isany(ipaddr)) { + 800da36: 68bb ldr r3, [r7, #8] + 800da38: 681b ldr r3, [r3, #0] + 800da3a: 2b00 cmp r3, #0 + 800da3c: d102 bne.n 800da44 + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: will not add non-unicast IP address to ARP cache\n")); + return ERR_ARG; + 800da3e: 230e movs r3, #14 + 800da40: 425b negs r3, r3 + 800da42: e116 b.n 800dc72 + } + + /* find entry in ARP cache, ask to create entry if queueing packet */ + i = etharp_find_entry(ipaddr, ETHARP_FLAG_TRY_HARD); + 800da44: 2517 movs r5, #23 + 800da46: 197c adds r4, r7, r5 + 800da48: 68bb ldr r3, [r7, #8] + 800da4a: 2101 movs r1, #1 + 800da4c: 0018 movs r0, r3 + 800da4e: f7ff fb25 bl 800d09c + 800da52: 0003 movs r3, r0 + 800da54: 7023 strb r3, [r4, #0] + + /* could not find or create entry? */ + if (i < 0) { + 800da56: 197b adds r3, r7, r5 + 800da58: 781b ldrb r3, [r3, #0] + 800da5a: 2b7f cmp r3, #127 ; 0x7f + 800da5c: d90d bls.n 800da7a + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: could not create ARP entry\n")); + if (q) { + 800da5e: 687b ldr r3, [r7, #4] + 800da60: 2b00 cmp r3, #0 + 800da62: d005 beq.n 800da70 + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: packet dropped\n")); + ETHARP_STATS_INC(etharp.memerr); + 800da64: 4b85 ldr r3, [pc, #532] ; (800dc7c ) + 800da66: 8c9b ldrh r3, [r3, #36] ; 0x24 + 800da68: 3301 adds r3, #1 + 800da6a: b29a uxth r2, r3 + 800da6c: 4b83 ldr r3, [pc, #524] ; (800dc7c ) + 800da6e: 849a strh r2, [r3, #36] ; 0x24 + } + return (err_t)i; + 800da70: 2317 movs r3, #23 + 800da72: 18fb adds r3, r7, r3 + 800da74: 781b ldrb r3, [r3, #0] + 800da76: b25b sxtb r3, r3 + 800da78: e0fb b.n 800dc72 + } + + /* mark a fresh entry as pending (we just sent a request) */ + if (arp_table[i].state == ETHARP_STATE_EMPTY) { + 800da7a: 2317 movs r3, #23 + 800da7c: 18fb adds r3, r7, r3 + 800da7e: 2200 movs r2, #0 + 800da80: 569a ldrsb r2, [r3, r2] + 800da82: 497f ldr r1, [pc, #508] ; (800dc80 ) + 800da84: 0013 movs r3, r2 + 800da86: 009b lsls r3, r3, #2 + 800da88: 189b adds r3, r3, r2 + 800da8a: 009b lsls r3, r3, #2 + 800da8c: 18cb adds r3, r1, r3 + 800da8e: 3312 adds r3, #18 + 800da90: 781b ldrb r3, [r3, #0] + 800da92: 2b00 cmp r3, #0 + 800da94: d10c bne.n 800dab0 + arp_table[i].state = ETHARP_STATE_PENDING; + 800da96: 2317 movs r3, #23 + 800da98: 18fb adds r3, r7, r3 + 800da9a: 2200 movs r2, #0 + 800da9c: 569a ldrsb r2, [r3, r2] + 800da9e: 4978 ldr r1, [pc, #480] ; (800dc80 ) + 800daa0: 0013 movs r3, r2 + 800daa2: 009b lsls r3, r3, #2 + 800daa4: 189b adds r3, r3, r2 + 800daa6: 009b lsls r3, r3, #2 + 800daa8: 18cb adds r3, r1, r3 + 800daaa: 3312 adds r3, #18 + 800daac: 2201 movs r2, #1 + 800daae: 701a strb r2, [r3, #0] + } + + /* { i is either a STABLE or (new or existing) PENDING entry } */ + LWIP_ASSERT("arp_table[i].state == PENDING or STABLE", + 800dab0: 2317 movs r3, #23 + 800dab2: 18fb adds r3, r7, r3 + 800dab4: 2200 movs r2, #0 + 800dab6: 569a ldrsb r2, [r3, r2] + 800dab8: 4971 ldr r1, [pc, #452] ; (800dc80 ) + 800daba: 0013 movs r3, r2 + 800dabc: 009b lsls r3, r3, #2 + 800dabe: 189b adds r3, r3, r2 + 800dac0: 009b lsls r3, r3, #2 + 800dac2: 18cb adds r3, r1, r3 + 800dac4: 3312 adds r3, #18 + 800dac6: 781b ldrb r3, [r3, #0] + 800dac8: 2b01 cmp r3, #1 + 800daca: d007 beq.n 800dadc + 800dacc: 2317 movs r3, #23 + 800dace: 18fb adds r3, r7, r3 + 800dad0: 2200 movs r2, #0 + 800dad2: 569a ldrsb r2, [r3, r2] + 800dad4: 0013 movs r3, r2 + 800dad6: 009b lsls r3, r3, #2 + 800dad8: 189b adds r3, r3, r2 + 800dada: 009b lsls r3, r3, #2 + ((arp_table[i].state == ETHARP_STATE_PENDING) || + (arp_table[i].state >= ETHARP_STATE_STABLE))); + + /* do we have a pending entry? or an implicit query request? */ + if ((arp_table[i].state == ETHARP_STATE_PENDING) || (q == NULL)) { + 800dadc: 2317 movs r3, #23 + 800dade: 18fb adds r3, r7, r3 + 800dae0: 2200 movs r2, #0 + 800dae2: 569a ldrsb r2, [r3, r2] + 800dae4: 4966 ldr r1, [pc, #408] ; (800dc80 ) + 800dae6: 0013 movs r3, r2 + 800dae8: 009b lsls r3, r3, #2 + 800daea: 189b adds r3, r3, r2 + 800daec: 009b lsls r3, r3, #2 + 800daee: 18cb adds r3, r1, r3 + 800daf0: 3312 adds r3, #18 + 800daf2: 781b ldrb r3, [r3, #0] + 800daf4: 2b01 cmp r3, #1 + 800daf6: d002 beq.n 800dafe + 800daf8: 687b ldr r3, [r7, #4] + 800dafa: 2b00 cmp r3, #0 + 800dafc: d111 bne.n 800db22 + /* try to resolve it; send out ARP request */ + result = etharp_request(netif, ipaddr); + 800dafe: 2327 movs r3, #39 ; 0x27 + 800db00: 18fc adds r4, r7, r3 + 800db02: 68ba ldr r2, [r7, #8] + 800db04: 68fb ldr r3, [r7, #12] + 800db06: 0011 movs r1, r2 + 800db08: 0018 movs r0, r3 + 800db0a: f000 f973 bl 800ddf4 + 800db0e: 0003 movs r3, r0 + 800db10: 7023 strb r3, [r4, #0] + /* ARP request couldn't be sent */ + /* We don't re-send arp request in etharp_tmr, but we still queue packets, + since this failure could be temporary, and the next packet calling + etharp_query again could lead to sending the queued packets. */ + } + if (q == NULL) { + 800db12: 687b ldr r3, [r7, #4] + 800db14: 2b00 cmp r3, #0 + 800db16: d104 bne.n 800db22 + return result; + 800db18: 2327 movs r3, #39 ; 0x27 + 800db1a: 18fb adds r3, r7, r3 + 800db1c: 781b ldrb r3, [r3, #0] + 800db1e: b25b sxtb r3, r3 + 800db20: e0a7 b.n 800dc72 + } + + /* packet given? */ + LWIP_ASSERT("q != NULL", q != NULL); + /* stable entry? */ + if (arp_table[i].state >= ETHARP_STATE_STABLE) { + 800db22: 2317 movs r3, #23 + 800db24: 18fb adds r3, r7, r3 + 800db26: 2200 movs r2, #0 + 800db28: 569a ldrsb r2, [r3, r2] + 800db2a: 4955 ldr r1, [pc, #340] ; (800dc80 ) + 800db2c: 0013 movs r3, r2 + 800db2e: 009b lsls r3, r3, #2 + 800db30: 189b adds r3, r3, r2 + 800db32: 009b lsls r3, r3, #2 + 800db34: 18cb adds r3, r1, r3 + 800db36: 3312 adds r3, #18 + 800db38: 781b ldrb r3, [r3, #0] + 800db3a: 2b01 cmp r3, #1 + 800db3c: d91a bls.n 800db74 + /* we have a valid IP->Ethernet address mapping */ + ETHARP_SET_HINT(netif, i); + 800db3e: 2117 movs r1, #23 + 800db40: 187b adds r3, r7, r1 + 800db42: 781a ldrb r2, [r3, #0] + 800db44: 4b4f ldr r3, [pc, #316] ; (800dc84 ) + 800db46: 701a strb r2, [r3, #0] + /* send the packet */ + result = etharp_send_ip(netif, q, srcaddr, &(arp_table[i].ethaddr)); + 800db48: 187b adds r3, r7, r1 + 800db4a: 2200 movs r2, #0 + 800db4c: 569a ldrsb r2, [r3, r2] + 800db4e: 0013 movs r3, r2 + 800db50: 009b lsls r3, r3, #2 + 800db52: 189b adds r3, r3, r2 + 800db54: 009b lsls r3, r3, #2 + 800db56: 3308 adds r3, #8 + 800db58: 001a movs r2, r3 + 800db5a: 4b49 ldr r3, [pc, #292] ; (800dc80 ) + 800db5c: 18d3 adds r3, r2, r3 + 800db5e: 3304 adds r3, #4 + 800db60: 2227 movs r2, #39 ; 0x27 + 800db62: 18bc adds r4, r7, r2 + 800db64: 69ba ldr r2, [r7, #24] + 800db66: 6879 ldr r1, [r7, #4] + 800db68: 68f8 ldr r0, [r7, #12] + 800db6a: f7ff fc13 bl 800d394 + 800db6e: 0003 movs r3, r0 + 800db70: 7023 strb r3, [r4, #0] + 800db72: e07a b.n 800dc6a + /* pending entry? (either just created or already pending */ + } else if (arp_table[i].state == ETHARP_STATE_PENDING) { + 800db74: 2317 movs r3, #23 + 800db76: 18fb adds r3, r7, r3 + 800db78: 2200 movs r2, #0 + 800db7a: 569a ldrsb r2, [r3, r2] + 800db7c: 4940 ldr r1, [pc, #256] ; (800dc80 ) + 800db7e: 0013 movs r3, r2 + 800db80: 009b lsls r3, r3, #2 + 800db82: 189b adds r3, r3, r2 + 800db84: 009b lsls r3, r3, #2 + 800db86: 18cb adds r3, r1, r3 + 800db88: 3312 adds r3, #18 + 800db8a: 781b ldrb r3, [r3, #0] + 800db8c: 2b01 cmp r3, #1 + 800db8e: d000 beq.n 800db92 + 800db90: e06b b.n 800dc6a + /* entry is still pending, queue the given packet 'q' */ + struct pbuf *p; + int copy_needed = 0; + 800db92: 2300 movs r3, #0 + 800db94: 61fb str r3, [r7, #28] + /* IF q includes a PBUF_REF, PBUF_POOL or PBUF_RAM, we have no choice but + * to copy the whole queue into a new PBUF_RAM (see bug #11400) + * PBUF_ROMs can be left as they are, since ROM must not get changed. */ + p = q; + 800db96: 687b ldr r3, [r7, #4] + 800db98: 623b str r3, [r7, #32] + while (p) { + 800db9a: e009 b.n 800dbb0 + LWIP_ASSERT("no packet queues allowed!", (p->len != p->tot_len) || (p->next == 0)); + if(p->type != PBUF_ROM) { + 800db9c: 6a3b ldr r3, [r7, #32] + 800db9e: 7b1b ldrb r3, [r3, #12] + 800dba0: 2b01 cmp r3, #1 + 800dba2: d002 beq.n 800dbaa + copy_needed = 1; + 800dba4: 2301 movs r3, #1 + 800dba6: 61fb str r3, [r7, #28] + break; + 800dba8: e005 b.n 800dbb6 + } + p = p->next; + 800dbaa: 6a3b ldr r3, [r7, #32] + 800dbac: 681b ldr r3, [r3, #0] + 800dbae: 623b str r3, [r7, #32] + while (p) { + 800dbb0: 6a3b ldr r3, [r7, #32] + 800dbb2: 2b00 cmp r3, #0 + 800dbb4: d1f2 bne.n 800db9c + } + if(copy_needed) { + 800dbb6: 69fb ldr r3, [r7, #28] + 800dbb8: 2b00 cmp r3, #0 + 800dbba: d01a beq.n 800dbf2 + /* copy the whole packet into new pbufs */ + p = pbuf_alloc(PBUF_RAW, p->tot_len, PBUF_RAM); + 800dbbc: 6a3b ldr r3, [r7, #32] + 800dbbe: 891b ldrh r3, [r3, #8] + 800dbc0: 2200 movs r2, #0 + 800dbc2: 0019 movs r1, r3 + 800dbc4: 2003 movs r0, #3 + 800dbc6: f7f7 fae1 bl 800518c + 800dbca: 0003 movs r3, r0 + 800dbcc: 623b str r3, [r7, #32] + if(p != NULL) { + 800dbce: 6a3b ldr r3, [r7, #32] + 800dbd0: 2b00 cmp r3, #0 + 800dbd2: d014 beq.n 800dbfe + if (pbuf_copy(p, q) != ERR_OK) { + 800dbd4: 687a ldr r2, [r7, #4] + 800dbd6: 6a3b ldr r3, [r7, #32] + 800dbd8: 0011 movs r1, r2 + 800dbda: 0018 movs r0, r3 + 800dbdc: f7f7 fe41 bl 8005862 + 800dbe0: 1e03 subs r3, r0, #0 + 800dbe2: d00c beq.n 800dbfe + pbuf_free(p); + 800dbe4: 6a3b ldr r3, [r7, #32] + 800dbe6: 0018 movs r0, r3 + 800dbe8: f7f7 fd5c bl 80056a4 + p = NULL; + 800dbec: 2300 movs r3, #0 + 800dbee: 623b str r3, [r7, #32] + 800dbf0: e005 b.n 800dbfe + } + } + } else { + /* referencing the old pbuf is enough */ + p = q; + 800dbf2: 687b ldr r3, [r7, #4] + 800dbf4: 623b str r3, [r7, #32] + pbuf_ref(p); + 800dbf6: 6a3b ldr r3, [r7, #32] + 800dbf8: 0018 movs r0, r3 + 800dbfa: f7f7 fde1 bl 80057c0 + } + /* packet could be taken over? */ + if (p != NULL) { + 800dbfe: 6a3b ldr r3, [r7, #32] + 800dc00: 2b00 cmp r3, #0 + 800dc02: d028 beq.n 800dc56 + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: could not queue a copy of PBUF_REF packet %p (out of memory)\n", (void *)q)); + result = ERR_MEM; + } +#else /* ARP_QUEUEING */ + /* always queue one packet per ARP request only, freeing a previously queued packet */ + if (arp_table[i].q != NULL) { + 800dc04: 2317 movs r3, #23 + 800dc06: 18fb adds r3, r7, r3 + 800dc08: 2200 movs r2, #0 + 800dc0a: 569a ldrsb r2, [r3, r2] + 800dc0c: 491c ldr r1, [pc, #112] ; (800dc80 ) + 800dc0e: 0013 movs r3, r2 + 800dc10: 009b lsls r3, r3, #2 + 800dc12: 189b adds r3, r3, r2 + 800dc14: 009b lsls r3, r3, #2 + 800dc16: 585b ldr r3, [r3, r1] + 800dc18: 2b00 cmp r3, #0 + 800dc1a: d00c beq.n 800dc36 + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: dropped previously queued packet %p for ARP entry %"S16_F"\n", (void *)q, (s16_t)i)); + pbuf_free(arp_table[i].q); + 800dc1c: 2317 movs r3, #23 + 800dc1e: 18fb adds r3, r7, r3 + 800dc20: 2200 movs r2, #0 + 800dc22: 569a ldrsb r2, [r3, r2] + 800dc24: 4916 ldr r1, [pc, #88] ; (800dc80 ) + 800dc26: 0013 movs r3, r2 + 800dc28: 009b lsls r3, r3, #2 + 800dc2a: 189b adds r3, r3, r2 + 800dc2c: 009b lsls r3, r3, #2 + 800dc2e: 585b ldr r3, [r3, r1] + 800dc30: 0018 movs r0, r3 + 800dc32: f7f7 fd37 bl 80056a4 + } + arp_table[i].q = p; + 800dc36: 2317 movs r3, #23 + 800dc38: 18fb adds r3, r7, r3 + 800dc3a: 2200 movs r2, #0 + 800dc3c: 569a ldrsb r2, [r3, r2] + 800dc3e: 4910 ldr r1, [pc, #64] ; (800dc80 ) + 800dc40: 0013 movs r3, r2 + 800dc42: 009b lsls r3, r3, #2 + 800dc44: 189b adds r3, r3, r2 + 800dc46: 009b lsls r3, r3, #2 + 800dc48: 6a3a ldr r2, [r7, #32] + 800dc4a: 505a str r2, [r3, r1] + result = ERR_OK; + 800dc4c: 2327 movs r3, #39 ; 0x27 + 800dc4e: 18fb adds r3, r7, r3 + 800dc50: 2200 movs r2, #0 + 800dc52: 701a strb r2, [r3, #0] + 800dc54: e009 b.n 800dc6a + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: queued packet %p on ARP entry %"S16_F"\n", (void *)q, (s16_t)i)); +#endif /* ARP_QUEUEING */ + } else { + ETHARP_STATS_INC(etharp.memerr); + 800dc56: 4b09 ldr r3, [pc, #36] ; (800dc7c ) + 800dc58: 8c9b ldrh r3, [r3, #36] ; 0x24 + 800dc5a: 3301 adds r3, #1 + 800dc5c: b29a uxth r2, r3 + 800dc5e: 4b07 ldr r3, [pc, #28] ; (800dc7c ) + 800dc60: 849a strh r2, [r3, #36] ; 0x24 + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: could not queue a copy of PBUF_REF packet %p (out of memory)\n", (void *)q)); + result = ERR_MEM; + 800dc62: 2327 movs r3, #39 ; 0x27 + 800dc64: 18fb adds r3, r7, r3 + 800dc66: 22ff movs r2, #255 ; 0xff + 800dc68: 701a strb r2, [r3, #0] + } + } + return result; + 800dc6a: 2327 movs r3, #39 ; 0x27 + 800dc6c: 18fb adds r3, r7, r3 + 800dc6e: 781b ldrb r3, [r3, #0] + 800dc70: b25b sxtb r3, r3 +} + 800dc72: 0018 movs r0, r3 + 800dc74: 46bd mov sp, r7 + 800dc76: b00a add sp, #40 ; 0x28 + 800dc78: bdb0 pop {r4, r5, r7, pc} + 800dc7a: 46c0 nop ; (mov r8, r8) + 800dc7c: 20003158 .word 0x20003158 + 800dc80: 200022c0 .word 0x200022c0 + 800dc84: 20002388 .word 0x20002388 + +0800dc88 : +etharp_raw(struct netif *netif, const struct eth_addr *ethsrc_addr, + const struct eth_addr *ethdst_addr, + const struct eth_addr *hwsrc_addr, const ip_addr_t *ipsrc_addr, + const struct eth_addr *hwdst_addr, const ip_addr_t *ipdst_addr, + const u16_t opcode) +{ + 800dc88: b5b0 push {r4, r5, r7, lr} + 800dc8a: b088 sub sp, #32 + 800dc8c: af00 add r7, sp, #0 + 800dc8e: 60f8 str r0, [r7, #12] + 800dc90: 60b9 str r1, [r7, #8] + 800dc92: 607a str r2, [r7, #4] + 800dc94: 603b str r3, [r7, #0] + struct pbuf *p; + err_t result = ERR_OK; + 800dc96: 231f movs r3, #31 + 800dc98: 18fb adds r3, r7, r3 + 800dc9a: 2200 movs r2, #0 + 800dc9c: 701a strb r2, [r3, #0] +#endif /* LWIP_AUTOIP */ + + LWIP_ASSERT("netif != NULL", netif != NULL); + + /* allocate a pbuf for the outgoing ARP request packet */ + p = pbuf_alloc(PBUF_RAW, SIZEOF_ETHARP_PACKET, PBUF_RAM); + 800dc9e: 2200 movs r2, #0 + 800dca0: 212a movs r1, #42 ; 0x2a + 800dca2: 2003 movs r0, #3 + 800dca4: f7f7 fa72 bl 800518c + 800dca8: 0003 movs r3, r0 + 800dcaa: 61bb str r3, [r7, #24] + /* could allocate a pbuf for an ARP request? */ + if (p == NULL) { + 800dcac: 69bb ldr r3, [r7, #24] + 800dcae: 2b00 cmp r3, #0 + 800dcb0: d108 bne.n 800dcc4 + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, + ("etharp_raw: could not allocate pbuf for ARP request.\n")); + ETHARP_STATS_INC(etharp.memerr); + 800dcb2: 4b4f ldr r3, [pc, #316] ; (800ddf0 ) + 800dcb4: 8c9b ldrh r3, [r3, #36] ; 0x24 + 800dcb6: 3301 adds r3, #1 + 800dcb8: b29a uxth r2, r3 + 800dcba: 4b4d ldr r3, [pc, #308] ; (800ddf0 ) + 800dcbc: 849a strh r2, [r3, #36] ; 0x24 + return ERR_MEM; + 800dcbe: 2301 movs r3, #1 + 800dcc0: 425b negs r3, r3 + 800dcc2: e090 b.n 800dde6 + } + LWIP_ASSERT("check that first pbuf can hold struct etharp_hdr", + (p->len >= SIZEOF_ETHARP_PACKET)); + + ethhdr = (struct eth_hdr *)p->payload; + 800dcc4: 69bb ldr r3, [r7, #24] + 800dcc6: 685b ldr r3, [r3, #4] + 800dcc8: 617b str r3, [r7, #20] + hdr = (struct etharp_hdr *)((u8_t*)ethhdr + SIZEOF_ETH_HDR); + 800dcca: 697b ldr r3, [r7, #20] + 800dccc: 330e adds r3, #14 + 800dcce: 613b str r3, [r7, #16] + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_raw: sending raw ARP packet.\n")); + hdr->opcode = htons(opcode); + 800dcd0: 233c movs r3, #60 ; 0x3c + 800dcd2: 18fb adds r3, r7, r3 + 800dcd4: 881b ldrh r3, [r3, #0] + 800dcd6: 0018 movs r0, r3 + 800dcd8: f7f6 fc9c bl 8004614 + 800dcdc: 0003 movs r3, r0 + 800dcde: 001a movs r2, r3 + 800dce0: 693b ldr r3, [r7, #16] + 800dce2: 21ff movs r1, #255 ; 0xff + 800dce4: 4011 ands r1, r2 + 800dce6: 000c movs r4, r1 + 800dce8: 7999 ldrb r1, [r3, #6] + 800dcea: 2000 movs r0, #0 + 800dcec: 4001 ands r1, r0 + 800dcee: 1c08 adds r0, r1, #0 + 800dcf0: 1c21 adds r1, r4, #0 + 800dcf2: 4301 orrs r1, r0 + 800dcf4: 7199 strb r1, [r3, #6] + 800dcf6: 0a12 lsrs r2, r2, #8 + 800dcf8: b290 uxth r0, r2 + 800dcfa: 79da ldrb r2, [r3, #7] + 800dcfc: 2100 movs r1, #0 + 800dcfe: 400a ands r2, r1 + 800dd00: 1c11 adds r1, r2, #0 + 800dd02: 1c02 adds r2, r0, #0 + 800dd04: 430a orrs r2, r1 + 800dd06: 71da strb r2, [r3, #7] + * 'sender IP address' MUST be sent using link-layer broadcast instead of + * link-layer unicast. (See RFC3927 Section 2.5, last paragraph) */ + ethdst_hwaddr = ip_addr_islinklocal(ipsrc_addr) ? (u8_t*)(ethbroadcast.addr) : ethdst_addr->addr; +#endif /* LWIP_AUTOIP */ + /* Write the ARP MAC-Addresses */ + ETHADDR16_COPY(&hdr->shwaddr, hwsrc_addr); + 800dd08: 693b ldr r3, [r7, #16] + 800dd0a: 3308 adds r3, #8 + 800dd0c: 6839 ldr r1, [r7, #0] + 800dd0e: 2206 movs r2, #6 + 800dd10: 0018 movs r0, r3 + 800dd12: f001 ffc6 bl 800fca2 + ETHADDR16_COPY(&hdr->dhwaddr, hwdst_addr); + 800dd16: 693b ldr r3, [r7, #16] + 800dd18: 3312 adds r3, #18 + 800dd1a: 6b79 ldr r1, [r7, #52] ; 0x34 + 800dd1c: 2206 movs r2, #6 + 800dd1e: 0018 movs r0, r3 + 800dd20: f001 ffbf bl 800fca2 + /* Write the Ethernet MAC-Addresses */ +#if LWIP_AUTOIP + ETHADDR16_COPY(ðhdr->dest, ethdst_hwaddr); +#else /* LWIP_AUTOIP */ + ETHADDR16_COPY(ðhdr->dest, ethdst_addr); + 800dd24: 697b ldr r3, [r7, #20] + 800dd26: 6879 ldr r1, [r7, #4] + 800dd28: 2206 movs r2, #6 + 800dd2a: 0018 movs r0, r3 + 800dd2c: f001 ffb9 bl 800fca2 +#endif /* LWIP_AUTOIP */ + ETHADDR16_COPY(ðhdr->src, ethsrc_addr); + 800dd30: 697b ldr r3, [r7, #20] + 800dd32: 3306 adds r3, #6 + 800dd34: 68b9 ldr r1, [r7, #8] + 800dd36: 2206 movs r2, #6 + 800dd38: 0018 movs r0, r3 + 800dd3a: f001 ffb2 bl 800fca2 + /* Copy struct ip_addr2 to aligned ip_addr, to support compilers without + * structure packing. */ + IPADDR2_COPY(&hdr->sipaddr, ipsrc_addr); + 800dd3e: 693b ldr r3, [r7, #16] + 800dd40: 330e adds r3, #14 + 800dd42: 6b39 ldr r1, [r7, #48] ; 0x30 + 800dd44: 2204 movs r2, #4 + 800dd46: 0018 movs r0, r3 + 800dd48: f001 ffab bl 800fca2 + IPADDR2_COPY(&hdr->dipaddr, ipdst_addr); + 800dd4c: 693b ldr r3, [r7, #16] + 800dd4e: 3318 adds r3, #24 + 800dd50: 6bb9 ldr r1, [r7, #56] ; 0x38 + 800dd52: 2204 movs r2, #4 + 800dd54: 0018 movs r0, r3 + 800dd56: f001 ffa4 bl 800fca2 + + hdr->hwtype = PP_HTONS(HWTYPE_ETHERNET); + 800dd5a: 693b ldr r3, [r7, #16] + 800dd5c: 781a ldrb r2, [r3, #0] + 800dd5e: 2100 movs r1, #0 + 800dd60: 400a ands r2, r1 + 800dd62: 701a strb r2, [r3, #0] + 800dd64: 785a ldrb r2, [r3, #1] + 800dd66: 2100 movs r1, #0 + 800dd68: 400a ands r2, r1 + 800dd6a: 1c11 adds r1, r2, #0 + 800dd6c: 2201 movs r2, #1 + 800dd6e: 430a orrs r2, r1 + 800dd70: 705a strb r2, [r3, #1] + hdr->proto = PP_HTONS(ETHTYPE_IP); + 800dd72: 693b ldr r3, [r7, #16] + 800dd74: 789a ldrb r2, [r3, #2] + 800dd76: 2100 movs r1, #0 + 800dd78: 400a ands r2, r1 + 800dd7a: 1c11 adds r1, r2, #0 + 800dd7c: 2208 movs r2, #8 + 800dd7e: 430a orrs r2, r1 + 800dd80: 709a strb r2, [r3, #2] + 800dd82: 78da ldrb r2, [r3, #3] + 800dd84: 2100 movs r1, #0 + 800dd86: 400a ands r2, r1 + 800dd88: 70da strb r2, [r3, #3] + /* set hwlen and protolen */ + hdr->hwlen = ETHARP_HWADDR_LEN; + 800dd8a: 693b ldr r3, [r7, #16] + 800dd8c: 2206 movs r2, #6 + 800dd8e: 711a strb r2, [r3, #4] + hdr->protolen = sizeof(ip_addr_t); + 800dd90: 693b ldr r3, [r7, #16] + 800dd92: 2204 movs r2, #4 + 800dd94: 715a strb r2, [r3, #5] + + ethhdr->type = PP_HTONS(ETHTYPE_ARP); + 800dd96: 697b ldr r3, [r7, #20] + 800dd98: 7b1a ldrb r2, [r3, #12] + 800dd9a: 2100 movs r1, #0 + 800dd9c: 400a ands r2, r1 + 800dd9e: 1c11 adds r1, r2, #0 + 800dda0: 2208 movs r2, #8 + 800dda2: 430a orrs r2, r1 + 800dda4: 731a strb r2, [r3, #12] + 800dda6: 7b5a ldrb r2, [r3, #13] + 800dda8: 2100 movs r1, #0 + 800ddaa: 400a ands r2, r1 + 800ddac: 1c11 adds r1, r2, #0 + 800ddae: 2206 movs r2, #6 + 800ddb0: 430a orrs r2, r1 + 800ddb2: 735a strb r2, [r3, #13] + /* send ARP query */ + result = netif->linkoutput(netif, p); + 800ddb4: 68fb ldr r3, [r7, #12] + 800ddb6: 699b ldr r3, [r3, #24] + 800ddb8: 251f movs r5, #31 + 800ddba: 197c adds r4, r7, r5 + 800ddbc: 69b9 ldr r1, [r7, #24] + 800ddbe: 68fa ldr r2, [r7, #12] + 800ddc0: 0010 movs r0, r2 + 800ddc2: 4798 blx r3 + 800ddc4: 0003 movs r3, r0 + 800ddc6: 7023 strb r3, [r4, #0] + ETHARP_STATS_INC(etharp.xmit); + 800ddc8: 4b09 ldr r3, [pc, #36] ; (800ddf0 ) + 800ddca: 8b1b ldrh r3, [r3, #24] + 800ddcc: 3301 adds r3, #1 + 800ddce: b29a uxth r2, r3 + 800ddd0: 4b07 ldr r3, [pc, #28] ; (800ddf0 ) + 800ddd2: 831a strh r2, [r3, #24] + /* free ARP query packet */ + pbuf_free(p); + 800ddd4: 69bb ldr r3, [r7, #24] + 800ddd6: 0018 movs r0, r3 + 800ddd8: f7f7 fc64 bl 80056a4 + p = NULL; + 800dddc: 2300 movs r3, #0 + 800ddde: 61bb str r3, [r7, #24] + /* could not allocate pbuf for ARP request */ + + return result; + 800dde0: 197b adds r3, r7, r5 + 800dde2: 781b ldrb r3, [r3, #0] + 800dde4: b25b sxtb r3, r3 +} + 800dde6: 0018 movs r0, r3 + 800dde8: 46bd mov sp, r7 + 800ddea: b008 add sp, #32 + 800ddec: bdb0 pop {r4, r5, r7, pc} + 800ddee: 46c0 nop ; (mov r8, r8) + 800ddf0: 20003158 .word 0x20003158 + +0800ddf4 : + * ERR_MEM if the ARP packet couldn't be allocated + * any other err_t on failure + */ +err_t +etharp_request(struct netif *netif, ip_addr_t *ipaddr) +{ + 800ddf4: b5b0 push {r4, r5, r7, lr} + 800ddf6: b086 sub sp, #24 + 800ddf8: af04 add r7, sp, #16 + 800ddfa: 6078 str r0, [r7, #4] + 800ddfc: 6039 str r1, [r7, #0] + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_request: sending ARP request.\n")); + return etharp_raw(netif, (struct eth_addr *)netif->hwaddr, ðbroadcast, + 800ddfe: 687b ldr r3, [r7, #4] + 800de00: 3323 adds r3, #35 ; 0x23 + 800de02: 0019 movs r1, r3 + (struct eth_addr *)netif->hwaddr, &netif->ip_addr, ðzero, + 800de04: 687b ldr r3, [r7, #4] + 800de06: 3323 adds r3, #35 ; 0x23 + 800de08: 001d movs r5, r3 + 800de0a: 687b ldr r3, [r7, #4] + 800de0c: 3304 adds r3, #4 + return etharp_raw(netif, (struct eth_addr *)netif->hwaddr, ðbroadcast, + 800de0e: 4c09 ldr r4, [pc, #36] ; (800de34 ) + 800de10: 6878 ldr r0, [r7, #4] + 800de12: 2201 movs r2, #1 + 800de14: 9203 str r2, [sp, #12] + 800de16: 683a ldr r2, [r7, #0] + 800de18: 9202 str r2, [sp, #8] + 800de1a: 4a07 ldr r2, [pc, #28] ; (800de38 ) + 800de1c: 9201 str r2, [sp, #4] + 800de1e: 9300 str r3, [sp, #0] + 800de20: 002b movs r3, r5 + 800de22: 0022 movs r2, r4 + 800de24: f7ff ff30 bl 800dc88 + 800de28: 0003 movs r3, r0 + ipaddr, ARP_REQUEST); +} + 800de2a: 0018 movs r0, r3 + 800de2c: 46bd mov sp, r7 + 800de2e: b002 add sp, #8 + 800de30: bdb0 pop {r4, r5, r7, pc} + 800de32: 46c0 nop ; (mov r8, r8) + 800de34: 0800fdc8 .word 0x0800fdc8 + 800de38: 0800fdd0 .word 0x0800fdd0 + +0800de3c : + * @param p the recevied packet, p->payload pointing to the ethernet header + * @param netif the network interface on which the packet was received + */ +err_t +ethernet_input(struct pbuf *p, struct netif *netif) +{ + 800de3c: b580 push {r7, lr} + 800de3e: b086 sub sp, #24 + 800de40: af00 add r7, sp, #0 + 800de42: 6078 str r0, [r7, #4] + 800de44: 6039 str r1, [r7, #0] + struct eth_hdr* ethhdr; + u16_t type; +#if LWIP_ARP || ETHARP_SUPPORT_VLAN + s16_t ip_hdr_offset = SIZEOF_ETH_HDR; + 800de46: 2316 movs r3, #22 + 800de48: 18fb adds r3, r7, r3 + 800de4a: 220e movs r2, #14 + 800de4c: 801a strh r2, [r3, #0] +#endif /* LWIP_ARP || ETHARP_SUPPORT_VLAN */ + + if (p->len <= SIZEOF_ETH_HDR) { + 800de4e: 687b ldr r3, [r7, #4] + 800de50: 895b ldrh r3, [r3, #10] + 800de52: 2b0e cmp r3, #14 + 800de54: d80c bhi.n 800de70 + /* a packet with only an ethernet header (or less) is not valid for us */ + ETHARP_STATS_INC(etharp.proterr); + 800de56: 4b49 ldr r3, [pc, #292] ; (800df7c ) + 800de58: 8d1b ldrh r3, [r3, #40] ; 0x28 + 800de5a: 3301 adds r3, #1 + 800de5c: b29a uxth r2, r3 + 800de5e: 4b47 ldr r3, [pc, #284] ; (800df7c ) + 800de60: 851a strh r2, [r3, #40] ; 0x28 + ETHARP_STATS_INC(etharp.drop); + 800de62: 4b46 ldr r3, [pc, #280] ; (800df7c ) + 800de64: 8bdb ldrh r3, [r3, #30] + 800de66: 3301 adds r3, #1 + 800de68: b29a uxth r2, r3 + 800de6a: 4b44 ldr r3, [pc, #272] ; (800df7c ) + 800de6c: 83da strh r2, [r3, #30] + goto free_and_return; + 800de6e: e07c b.n 800df6a + } + + /* points to packet payload, which starts with an Ethernet header */ + ethhdr = (struct eth_hdr *)p->payload; + 800de70: 687b ldr r3, [r7, #4] + 800de72: 685b ldr r3, [r3, #4] + 800de74: 613b str r3, [r7, #16] + (unsigned)ethhdr->dest.addr[3], (unsigned)ethhdr->dest.addr[4], (unsigned)ethhdr->dest.addr[5], + (unsigned)ethhdr->src.addr[0], (unsigned)ethhdr->src.addr[1], (unsigned)ethhdr->src.addr[2], + (unsigned)ethhdr->src.addr[3], (unsigned)ethhdr->src.addr[4], (unsigned)ethhdr->src.addr[5], + (unsigned)htons(ethhdr->type))); + + type = ethhdr->type; + 800de76: 230e movs r3, #14 + 800de78: 18fa adds r2, r7, r3 + 800de7a: 693b ldr r3, [r7, #16] + 800de7c: 7b19 ldrb r1, [r3, #12] + 800de7e: 7b5b ldrb r3, [r3, #13] + 800de80: 021b lsls r3, r3, #8 + 800de82: 430b orrs r3, r1 + 800de84: 8013 strh r3, [r2, #0] + +#if LWIP_ARP_FILTER_NETIF + netif = LWIP_ARP_FILTER_NETIF_FN(p, netif, htons(type)); +#endif /* LWIP_ARP_FILTER_NETIF*/ + + if (ethhdr->dest.addr[0] & 1) { + 800de86: 693b ldr r3, [r7, #16] + 800de88: 781b ldrb r3, [r3, #0] + 800de8a: 001a movs r2, r3 + 800de8c: 2301 movs r3, #1 + 800de8e: 4013 ands r3, r2 + 800de90: d022 beq.n 800ded8 + /* this might be a multicast or broadcast packet */ + if (ethhdr->dest.addr[0] == LL_MULTICAST_ADDR_0) { + 800de92: 693b ldr r3, [r7, #16] + 800de94: 781b ldrb r3, [r3, #0] + 800de96: 2b01 cmp r3, #1 + 800de98: d10f bne.n 800deba + if ((ethhdr->dest.addr[1] == LL_MULTICAST_ADDR_1) && + 800de9a: 693b ldr r3, [r7, #16] + 800de9c: 785b ldrb r3, [r3, #1] + 800de9e: 2b00 cmp r3, #0 + 800dea0: d11a bne.n 800ded8 + (ethhdr->dest.addr[2] == LL_MULTICAST_ADDR_2)) { + 800dea2: 693b ldr r3, [r7, #16] + 800dea4: 789b ldrb r3, [r3, #2] + if ((ethhdr->dest.addr[1] == LL_MULTICAST_ADDR_1) && + 800dea6: 2b5e cmp r3, #94 ; 0x5e + 800dea8: d116 bne.n 800ded8 + /* mark the pbuf as link-layer multicast */ + p->flags |= PBUF_FLAG_LLMCAST; + 800deaa: 687b ldr r3, [r7, #4] + 800deac: 7b5b ldrb r3, [r3, #13] + 800deae: 2210 movs r2, #16 + 800deb0: 4313 orrs r3, r2 + 800deb2: b2da uxtb r2, r3 + 800deb4: 687b ldr r3, [r7, #4] + 800deb6: 735a strb r2, [r3, #13] + 800deb8: e00e b.n 800ded8 + } + } else if (eth_addr_cmp(ðhdr->dest, ðbroadcast)) { + 800deba: 693b ldr r3, [r7, #16] + 800debc: 4930 ldr r1, [pc, #192] ; (800df80 ) + 800debe: 2206 movs r2, #6 + 800dec0: 0018 movs r0, r3 + 800dec2: f001 fedf bl 800fc84 + 800dec6: 1e03 subs r3, r0, #0 + 800dec8: d106 bne.n 800ded8 + /* mark the pbuf as link-layer broadcast */ + p->flags |= PBUF_FLAG_LLBCAST; + 800deca: 687b ldr r3, [r7, #4] + 800decc: 7b5b ldrb r3, [r3, #13] + 800dece: 2208 movs r2, #8 + 800ded0: 4313 orrs r3, r2 + 800ded2: b2da uxtb r2, r3 + 800ded4: 687b ldr r3, [r7, #4] + 800ded6: 735a strb r2, [r3, #13] + } + } + + switch (type) { + 800ded8: 230e movs r3, #14 + 800deda: 18fb adds r3, r7, r3 + 800dedc: 881b ldrh r3, [r3, #0] + 800dede: 2b08 cmp r3, #8 + 800dee0: d004 beq.n 800deec + 800dee2: 22c1 movs r2, #193 ; 0xc1 + 800dee4: 00d2 lsls r2, r2, #3 + 800dee6: 4293 cmp r3, r2 + 800dee8: d01b beq.n 800df22 + 800deea: e02a b.n 800df42 +#if LWIP_ARP + /* IP packet? */ + case PP_HTONS(ETHTYPE_IP): + if (!(netif->flags & NETIF_FLAG_ETHARP)) { + 800deec: 683b ldr r3, [r7, #0] + 800deee: 2229 movs r2, #41 ; 0x29 + 800def0: 5c9b ldrb r3, [r3, r2] + 800def2: 001a movs r2, r3 + 800def4: 2320 movs r3, #32 + 800def6: 4013 ands r3, r2 + 800def8: d032 beq.n 800df60 +#if ETHARP_TRUST_IP_MAC + /* update ARP table */ + etharp_ip_input(netif, p); +#endif /* ETHARP_TRUST_IP_MAC */ + /* skip Ethernet header */ + if(pbuf_header(p, -ip_hdr_offset)) { + 800defa: 2316 movs r3, #22 + 800defc: 18fb adds r3, r7, r3 + 800defe: 881b ldrh r3, [r3, #0] + 800df00: 425b negs r3, r3 + 800df02: b29b uxth r3, r3 + 800df04: b21a sxth r2, r3 + 800df06: 687b ldr r3, [r7, #4] + 800df08: 0011 movs r1, r2 + 800df0a: 0018 movs r0, r3 + 800df0c: f7f7 fb43 bl 8005596 + 800df10: 1e03 subs r3, r0, #0 + 800df12: d127 bne.n 800df64 + LWIP_ASSERT("Can't move over header in packet", 0); + goto free_and_return; + } else { + /* pass to IP layer */ + ip_input(p, netif); + 800df14: 683a ldr r2, [r7, #0] + 800df16: 687b ldr r3, [r7, #4] + 800df18: 0011 movs r1, r2 + 800df1a: 0018 movs r0, r3 + 800df1c: f7fd fcd8 bl 800b8d0 + } + break; + 800df20: e01c b.n 800df5c + + case PP_HTONS(ETHTYPE_ARP): + if (!(netif->flags & NETIF_FLAG_ETHARP)) { + 800df22: 683b ldr r3, [r7, #0] + 800df24: 2229 movs r2, #41 ; 0x29 + 800df26: 5c9b ldrb r3, [r3, r2] + 800df28: 001a movs r2, r3 + 800df2a: 2320 movs r3, #32 + 800df2c: 4013 ands r3, r2 + 800df2e: d01b beq.n 800df68 + goto free_and_return; + } + /* pass p to ARP module */ + etharp_arp_input(netif, (struct eth_addr*)(netif->hwaddr), p); + 800df30: 683b ldr r3, [r7, #0] + 800df32: 3323 adds r3, #35 ; 0x23 + 800df34: 0019 movs r1, r3 + 800df36: 687a ldr r2, [r7, #4] + 800df38: 683b ldr r3, [r7, #0] + 800df3a: 0018 movs r0, r3 + 800df3c: f7ff fb0c bl 800d558 + break; + 800df40: e00c b.n 800df5c + pppoe_data_input(netif, p); + break; +#endif /* PPPOE_SUPPORT */ + + default: + ETHARP_STATS_INC(etharp.proterr); + 800df42: 4b0e ldr r3, [pc, #56] ; (800df7c ) + 800df44: 8d1b ldrh r3, [r3, #40] ; 0x28 + 800df46: 3301 adds r3, #1 + 800df48: b29a uxth r2, r3 + 800df4a: 4b0c ldr r3, [pc, #48] ; (800df7c ) + 800df4c: 851a strh r2, [r3, #40] ; 0x28 + ETHARP_STATS_INC(etharp.drop); + 800df4e: 4b0b ldr r3, [pc, #44] ; (800df7c ) + 800df50: 8bdb ldrh r3, [r3, #30] + 800df52: 3301 adds r3, #1 + 800df54: b29a uxth r2, r3 + 800df56: 4b09 ldr r3, [pc, #36] ; (800df7c ) + 800df58: 83da strh r2, [r3, #30] + goto free_and_return; + 800df5a: e006 b.n 800df6a + } + + /* This means the pbuf is freed or consumed, + so the caller doesn't have to free it again */ + return ERR_OK; + 800df5c: 2300 movs r3, #0 + 800df5e: e009 b.n 800df74 + goto free_and_return; + 800df60: 46c0 nop ; (mov r8, r8) + 800df62: e002 b.n 800df6a + goto free_and_return; + 800df64: 46c0 nop ; (mov r8, r8) + 800df66: e000 b.n 800df6a + goto free_and_return; + 800df68: 46c0 nop ; (mov r8, r8) + +free_and_return: + pbuf_free(p); + 800df6a: 687b ldr r3, [r7, #4] + 800df6c: 0018 movs r0, r3 + 800df6e: f7f7 fb99 bl 80056a4 + return ERR_OK; + 800df72: 2300 movs r3, #0 +} + 800df74: 0018 movs r0, r3 + 800df76: 46bd mov sp, r7 + 800df78: b006 add sp, #24 + 800df7a: bd80 pop {r7, pc} + 800df7c: 20003158 .word 0x20003158 + 800df80: 0800fdc8 .word 0x0800fdc8 + +0800df84 : + entries /* entries */ +}; + +/* this function is called by usbd_ecm.c during an ISR; it must not block */ +void usb_ecm_recv_callback(const uint8_t *data, int size) +{ + 800df84: b580 push {r7, lr} + 800df86: b082 sub sp, #8 + 800df88: af00 add r7, sp, #0 + 800df8a: 6078 str r0, [r7, #4] + 800df8c: 6039 str r1, [r7, #0] + if (received_frame) + 800df8e: 4b13 ldr r3, [pc, #76] ; (800dfdc ) + 800df90: 681b ldr r3, [r3, #0] + 800df92: 2b00 cmp r3, #0 + 800df94: d11e bne.n 800dfd4 + return; + + received_frame = pbuf_alloc(PBUF_RAW, size, PBUF_POOL); + 800df96: 683b ldr r3, [r7, #0] + 800df98: b29b uxth r3, r3 + 800df9a: 2203 movs r2, #3 + 800df9c: 0019 movs r1, r3 + 800df9e: 2003 movs r0, #3 + 800dfa0: f7f7 f8f4 bl 800518c + 800dfa4: 0002 movs r2, r0 + 800dfa6: 4b0d ldr r3, [pc, #52] ; (800dfdc ) + 800dfa8: 601a str r2, [r3, #0] + if (!received_frame) + 800dfaa: 4b0c ldr r3, [pc, #48] ; (800dfdc ) + 800dfac: 681b ldr r3, [r3, #0] + 800dfae: 2b00 cmp r3, #0 + 800dfb0: d102 bne.n 800dfb8 + { + usb_ecm_recv_renew(); + 800dfb2: f001 fbb9 bl 800f728 + return; + 800dfb6: e00e b.n 800dfd6 + } + + memcpy(received_frame->payload, data, size); + 800dfb8: 4b08 ldr r3, [pc, #32] ; (800dfdc ) + 800dfba: 681b ldr r3, [r3, #0] + 800dfbc: 685b ldr r3, [r3, #4] + 800dfbe: 683a ldr r2, [r7, #0] + 800dfc0: 6879 ldr r1, [r7, #4] + 800dfc2: 0018 movs r0, r3 + 800dfc4: f001 fe6d bl 800fca2 + received_frame->len = size; + 800dfc8: 4b04 ldr r3, [pc, #16] ; (800dfdc ) + 800dfca: 681b ldr r3, [r3, #0] + 800dfcc: 683a ldr r2, [r7, #0] + 800dfce: b292 uxth r2, r2 + 800dfd0: 815a strh r2, [r3, #10] + 800dfd2: e000 b.n 800dfd6 + return; + 800dfd4: 46c0 nop ; (mov r8, r8) +} + 800dfd6: 46bd mov sp, r7 + 800dfd8: b002 add sp, #8 + 800dfda: bd80 pop {r7, pc} + 800dfdc: 200023c0 .word 0x200023c0 + +0800dfe0 : + +uint32_t sys_now() +{ + 800dfe0: b580 push {r7, lr} + 800dfe2: af00 add r7, sp, #0 + return (uint32_t)mtime(); + 800dfe4: f000 f92a bl 800e23c + 800dfe8: 0003 movs r3, r0 +} + 800dfea: 0018 movs r0, r3 + 800dfec: 46bd mov sp, r7 + 800dfee: bd80 pop {r7, pc} + +0800dff0 : + +TIMER_PROC(tcp_timer, TCP_TMR_INTERVAL, 1, NULL) +{ + 800dff0: b580 push {r7, lr} + 800dff2: b082 sub sp, #8 + 800dff4: af00 add r7, sp, #0 + 800dff6: 6078 str r0, [r7, #4] + tcp_tmr(); + 800dff8: f7f7 fddc bl 8005bb4 +} + 800dffc: 46c0 nop ; (mov r8, r8) + 800dffe: 46bd mov sp, r7 + 800e000: b002 add sp, #8 + 800e002: bd80 pop {r7, pc} + +0800e004 : + +err_t output_fn(struct netif *netif, struct pbuf *p, ip_addr_t *ipaddr) +{ + 800e004: b580 push {r7, lr} + 800e006: b084 sub sp, #16 + 800e008: af00 add r7, sp, #0 + 800e00a: 60f8 str r0, [r7, #12] + 800e00c: 60b9 str r1, [r7, #8] + 800e00e: 607a str r2, [r7, #4] + return etharp_output(netif, p, ipaddr); + 800e010: 687a ldr r2, [r7, #4] + 800e012: 68b9 ldr r1, [r7, #8] + 800e014: 68fb ldr r3, [r7, #12] + 800e016: 0018 movs r0, r3 + 800e018: f7ff fbfe bl 800d818 + 800e01c: 0003 movs r3, r0 +} + 800e01e: 0018 movs r0, r3 + 800e020: 46bd mov sp, r7 + 800e022: b004 add sp, #16 + 800e024: bd80 pop {r7, pc} + +0800e026 : + +err_t linkoutput_fn(struct netif *netif, struct pbuf *p) +{ + 800e026: b580 push {r7, lr} + 800e028: b084 sub sp, #16 + 800e02a: af00 add r7, sp, #0 + 800e02c: 6078 str r0, [r7, #4] + 800e02e: 6039 str r1, [r7, #0] + int i; + for (i = 0; i < 200; i++) + 800e030: 2300 movs r3, #0 + 800e032: 60fb str r3, [r7, #12] + 800e034: e009 b.n 800e04a + { + if (usb_ecm_can_xmit()) goto ready; + 800e036: f001 fd31 bl 800fa9c + 800e03a: 1e03 subs r3, r0, #0 + 800e03c: d10b bne.n 800e056 + msleep(1); + 800e03e: 2001 movs r0, #1 + 800e040: f000 f904 bl 800e24c + for (i = 0; i < 200; i++) + 800e044: 68fb ldr r3, [r7, #12] + 800e046: 3301 adds r3, #1 + 800e048: 60fb str r3, [r7, #12] + 800e04a: 68fb ldr r3, [r7, #12] + 800e04c: 2bc7 cmp r3, #199 ; 0xc7 + 800e04e: ddf2 ble.n 800e036 + } + return ERR_USE; + 800e050: 2308 movs r3, #8 + 800e052: 425b negs r3, r3 + 800e054: e005 b.n 800e062 + if (usb_ecm_can_xmit()) goto ready; + 800e056: 46c0 nop ; (mov r8, r8) +ready: + usb_ecm_xmit_packet(p); + 800e058: 683b ldr r3, [r7, #0] + 800e05a: 0018 movs r0, r3 + 800e05c: f001 fd30 bl 800fac0 + return ERR_OK; + 800e060: 2300 movs r3, #0 +} + 800e062: 0018 movs r0, r3 + 800e064: 46bd mov sp, r7 + 800e066: b004 add sp, #16 + 800e068: bd80 pop {r7, pc} + ... + +0800e06c : + +err_t netif_init_cb(struct netif *netif) +{ + 800e06c: b580 push {r7, lr} + 800e06e: b082 sub sp, #8 + 800e070: af00 add r7, sp, #0 + 800e072: 6078 str r0, [r7, #4] + LWIP_ASSERT("netif != NULL", (netif != NULL)); + netif->mtu = ECM_MTU; + 800e074: 687b ldr r3, [r7, #4] + 800e076: 22fa movs r2, #250 ; 0xfa + 800e078: 0052 lsls r2, r2, #1 + 800e07a: 841a strh r2, [r3, #32] + netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP | NETIF_FLAG_UP; + 800e07c: 687b ldr r3, [r7, #4] + 800e07e: 2229 movs r2, #41 ; 0x29 + 800e080: 2133 movs r1, #51 ; 0x33 + 800e082: 5499 strb r1, [r3, r2] + netif->state = NULL; + 800e084: 687b ldr r3, [r7, #4] + 800e086: 2200 movs r2, #0 + 800e088: 61da str r2, [r3, #28] + netif->name[0] = 'E'; + 800e08a: 687b ldr r3, [r7, #4] + 800e08c: 222a movs r2, #42 ; 0x2a + 800e08e: 2145 movs r1, #69 ; 0x45 + 800e090: 5499 strb r1, [r3, r2] + netif->name[1] = 'X'; + 800e092: 687b ldr r3, [r7, #4] + 800e094: 222b movs r2, #43 ; 0x2b + 800e096: 2158 movs r1, #88 ; 0x58 + 800e098: 5499 strb r1, [r3, r2] + netif->linkoutput = linkoutput_fn; + 800e09a: 687b ldr r3, [r7, #4] + 800e09c: 4a04 ldr r2, [pc, #16] ; (800e0b0 ) + 800e09e: 619a str r2, [r3, #24] + netif->output = output_fn; + 800e0a0: 687b ldr r3, [r7, #4] + 800e0a2: 4a04 ldr r2, [pc, #16] ; (800e0b4 ) + 800e0a4: 615a str r2, [r3, #20] + return ERR_OK; + 800e0a6: 2300 movs r3, #0 +} + 800e0a8: 0018 movs r0, r3 + 800e0aa: 46bd mov sp, r7 + 800e0ac: b002 add sp, #8 + 800e0ae: bd80 pop {r7, pc} + 800e0b0: 0800e027 .word 0x0800e027 + 800e0b4: 0800e005 .word 0x0800e005 + +0800e0b8 : + +#define PADDR(ptr) ((ip_addr_t *)ptr) + +static void init_lwip() +{ + 800e0b8: b590 push {r4, r7, lr} + 800e0ba: b087 sub sp, #28 + 800e0bc: af04 add r7, sp, #16 + struct netif *netif = &netif_data; + 800e0be: 4b16 ldr r3, [pc, #88] ; (800e118 ) + 800e0c0: 607b str r3, [r7, #4] + + lwip_init(); + 800e0c2: f7f6 faf3 bl 80046ac + netif->hwaddr_len = 6; + 800e0c6: 687b ldr r3, [r7, #4] + 800e0c8: 2222 movs r2, #34 ; 0x22 + 800e0ca: 2106 movs r1, #6 + 800e0cc: 5499 strb r1, [r3, r2] + memcpy(netif->hwaddr, hwaddr, 6); + 800e0ce: 687b ldr r3, [r7, #4] + 800e0d0: 3323 adds r3, #35 ; 0x23 + 800e0d2: 001a movs r2, r3 + 800e0d4: 4b11 ldr r3, [pc, #68] ; (800e11c ) + 800e0d6: 0010 movs r0, r2 + 800e0d8: 0019 movs r1, r3 + 800e0da: 2306 movs r3, #6 + 800e0dc: 001a movs r2, r3 + 800e0de: f001 fde0 bl 800fca2 + + netif = netif_add(netif, PADDR(ipaddr), PADDR(netmask), PADDR(gateway), NULL, netif_init_cb, ip_input); + 800e0e2: 4c0f ldr r4, [pc, #60] ; (800e120 ) + 800e0e4: 4a0f ldr r2, [pc, #60] ; (800e124 ) + 800e0e6: 4910 ldr r1, [pc, #64] ; (800e128 ) + 800e0e8: 6878 ldr r0, [r7, #4] + 800e0ea: 4b10 ldr r3, [pc, #64] ; (800e12c ) + 800e0ec: 9302 str r3, [sp, #8] + 800e0ee: 4b10 ldr r3, [pc, #64] ; (800e130 ) + 800e0f0: 9301 str r3, [sp, #4] + 800e0f2: 2300 movs r3, #0 + 800e0f4: 9300 str r3, [sp, #0] + 800e0f6: 0023 movs r3, r4 + 800e0f8: f7f6 ff52 bl 8004fa0 + 800e0fc: 0003 movs r3, r0 + 800e0fe: 607b str r3, [r7, #4] + netif_set_default(netif); + 800e100: 687b ldr r3, [r7, #4] + 800e102: 0018 movs r0, r3 + 800e104: f7f7 f82a bl 800515c + + stmr_add(&tcp_timer); + 800e108: 4b0a ldr r3, [pc, #40] ; (800e134 ) + 800e10a: 0018 movs r0, r3 + 800e10c: f000 f8f2 bl 800e2f4 +} + 800e110: 46c0 nop ; (mov r8, r8) + 800e112: 46bd mov sp, r7 + 800e114: b003 add sp, #12 + 800e116: bd90 pop {r4, r7, pc} + 800e118: 2000238c .word 0x2000238c + 800e11c: 20000018 .word 0x20000018 + 800e120: 200023bc .word 0x200023bc + 800e124: 20000024 .word 0x20000024 + 800e128: 20000020 .word 0x20000020 + 800e12c: 0800b8d1 .word 0x0800b8d1 + 800e130: 0800e06d .word 0x0800e06d + 800e134: 2000007c .word 0x2000007c + +0800e138 : + + +bool dns_query_proc(const char *name, ip_addr_t *addr) +{ + 800e138: b580 push {r7, lr} + 800e13a: b082 sub sp, #8 + 800e13c: af00 add r7, sp, #0 + 800e13e: 6078 str r0, [r7, #4] + 800e140: 6039 str r1, [r7, #0] + if (strcmp(name, "run.stm") == 0 || strcmp(name, "www.run.stm") == 0) + 800e142: 4a0d ldr r2, [pc, #52] ; (800e178 ) + 800e144: 687b ldr r3, [r7, #4] + 800e146: 0011 movs r1, r2 + 800e148: 0018 movs r0, r3 + 800e14a: f7f1 ffdd bl 8000108 + 800e14e: 1e03 subs r3, r0, #0 + 800e150: d007 beq.n 800e162 + 800e152: 4a0a ldr r2, [pc, #40] ; (800e17c ) + 800e154: 687b ldr r3, [r7, #4] + 800e156: 0011 movs r1, r2 + 800e158: 0018 movs r0, r3 + 800e15a: f7f1 ffd5 bl 8000108 + 800e15e: 1e03 subs r3, r0, #0 + 800e160: d105 bne.n 800e16e + { + addr->addr = *(uint32_t *)ipaddr; + 800e162: 4b07 ldr r3, [pc, #28] ; (800e180 ) + 800e164: 681a ldr r2, [r3, #0] + 800e166: 683b ldr r3, [r7, #0] + 800e168: 601a str r2, [r3, #0] + return true; + 800e16a: 2301 movs r3, #1 + 800e16c: e000 b.n 800e170 + } + return false; + 800e16e: 2300 movs r3, #0 +} + 800e170: 0018 movs r0, r3 + 800e172: 46bd mov sp, r7 + 800e174: b002 add sp, #8 + 800e176: bd80 pop {r7, pc} + 800e178: 0800fd08 .word 0x0800fd08 + 800e17c: 0800fd10 .word 0x0800fd10 + 800e180: 20000020 .word 0x20000020 + +0800e184 : + +// return res; +//} + +static void service_traffic(void) +{ + 800e184: b580 push {r7, lr} + 800e186: b082 sub sp, #8 + 800e188: af00 add r7, sp, #0 + \details Disables IRQ interrupts by setting the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __disable_irq(void) +{ + __ASM volatile ("cpsid i" : : : "memory"); + 800e18a: b672 cpsid i + struct pbuf *frame; + + /* retrieve and clear var set by usb_ecm_recv_callback() in ISR */ + __disable_irq(); + frame = received_frame; + 800e18c: 4b0d ldr r3, [pc, #52] ; (800e1c4 ) + 800e18e: 681b ldr r3, [r3, #0] + 800e190: 607b str r3, [r7, #4] + received_frame = NULL; + 800e192: 4b0c ldr r3, [pc, #48] ; (800e1c4 ) + 800e194: 2200 movs r2, #0 + 800e196: 601a str r2, [r3, #0] + __ASM volatile ("cpsie i" : : : "memory"); + 800e198: b662 cpsie i + __enable_irq(); + + if (!frame) + 800e19a: 687b ldr r3, [r7, #4] + 800e19c: 2b00 cmp r3, #0 + 800e19e: d00c beq.n 800e1ba + return; /* no packet was received */ + + /* packet was received, so handle it */ + ethernet_input(frame, &netif_data); + 800e1a0: 4a09 ldr r2, [pc, #36] ; (800e1c8 ) + 800e1a2: 687b ldr r3, [r7, #4] + 800e1a4: 0011 movs r1, r2 + 800e1a6: 0018 movs r0, r3 + 800e1a8: f7ff fe48 bl 800de3c + pbuf_free(frame); + 800e1ac: 687b ldr r3, [r7, #4] + 800e1ae: 0018 movs r0, r3 + 800e1b0: f7f7 fa78 bl 80056a4 + + /* tell usbd_ecm.c it is OK to receive another packet */ + usb_ecm_recv_renew(); + 800e1b4: f001 fab8 bl 800f728 + 800e1b8: e000 b.n 800e1bc + return; /* no packet was received */ + 800e1ba: 46c0 nop ; (mov r8, r8) +} + 800e1bc: 46bd mov sp, r7 + 800e1be: b002 add sp, #8 + 800e1c0: bd80 pop {r7, pc} + 800e1c2: 46c0 nop ; (mov r8, r8) + 800e1c4: 200023c0 .word 0x200023c0 + 800e1c8: 2000238c .word 0x2000238c + +0800e1cc : + +void ecm_main_init() +{ + 800e1cc: b580 push {r7, lr} + 800e1ce: af00 add r7, sp, #0 + time_init(); + 800e1d0: f000 f82f bl 800e232 + init_lwip(); + 800e1d4: f7ff ff70 bl 800e0b8 + + while (!netif_is_up(&netif_data)); + 800e1d8: 46c0 nop ; (mov r8, r8) + 800e1da: 4b0d ldr r3, [pc, #52] ; (800e210 ) + 800e1dc: 2229 movs r2, #41 ; 0x29 + 800e1de: 5c9b ldrb r3, [r3, r2] + 800e1e0: 001a movs r2, r3 + 800e1e2: 2301 movs r3, #1 + 800e1e4: 4013 ands r3, r2 + 800e1e6: d0f8 beq.n 800e1da + + while (dhserv_init(&dhcp_config) != ERR_OK); + 800e1e8: 46c0 nop ; (mov r8, r8) + 800e1ea: 4b0a ldr r3, [pc, #40] ; (800e214 ) + 800e1ec: 0018 movs r0, r3 + 800e1ee: f7f5 ff57 bl 80040a0 + 800e1f2: 1e03 subs r3, r0, #0 + 800e1f4: d1f9 bne.n 800e1ea + + while (dnserv_init(PADDR(ipaddr), 53, dns_query_proc) != ERR_OK); + 800e1f6: 46c0 nop ; (mov r8, r8) + 800e1f8: 4a07 ldr r2, [pc, #28] ; (800e218 ) + 800e1fa: 4b08 ldr r3, [pc, #32] ; (800e21c ) + 800e1fc: 2135 movs r1, #53 ; 0x35 + 800e1fe: 0018 movs r0, r3 + 800e200: f7f6 f9ac bl 800455c + 800e204: 1e03 subs r3, r0, #0 + 800e206: d1f7 bne.n 800e1f8 + + //http_set_cgi_handlers(cgi_uri_table, sizeof(cgi_uri_table) / sizeof(*cgi_uri_table)); + //http_set_ssi_handler(ssi_handler, ssi_tags_table, sizeof(ssi_tags_table) / sizeof(*ssi_tags_table)); + // httpd_init(); +} + 800e208: 46c0 nop ; (mov r8, r8) + 800e20a: 46bd mov sp, r7 + 800e20c: bd80 pop {r7, pc} + 800e20e: 46c0 nop ; (mov r8, r8) + 800e210: 2000238c .word 0x2000238c + 800e214: 20000064 .word 0x20000064 + 800e218: 0800e139 .word 0x0800e139 + 800e21c: 20000020 .word 0x20000020 + +0800e220 : + +void ecm_main_loop() +{ + 800e220: b580 push {r7, lr} + 800e222: af00 add r7, sp, #0 + service_traffic(); + 800e224: f7ff ffae bl 800e184 + stmr(); + 800e228: f000 f82e bl 800e288 +} + 800e22c: 46c0 nop ; (mov r8, r8) + 800e22e: 46bd mov sp, r7 + 800e230: bd80 pop {r7, pc} + +0800e232 : + +volatile uint32_t sysTimeTicks; +volatile uint32_t sysTimeDelayCounter; + +void time_init(void) +{ + 800e232: b580 push {r7, lr} + 800e234: af00 add r7, sp, #0 +// if (SysTick_Config(SystemCoreClock / 1000)) +// while (1) {} /* Capture error */ +} + 800e236: 46c0 nop ; (mov r8, r8) + 800e238: 46bd mov sp, r7 + 800e23a: bd80 pop {r7, pc} + +0800e23c : + // msAddition++; /* +1 ms */ +//} + + +uint32_t mtime(void) +{ + 800e23c: b580 push {r7, lr} + 800e23e: af00 add r7, sp, #0 + res = msAddition; + ctrl = SysTick->CTRL; + if (ctrl & SysTick_CTRL_COUNTFLAG_Msk) + goto read; + */ + return HAL_GetTick(); + 800e240: f7f2 fa40 bl 80006c4 + 800e244: 0003 movs r3, r0 +} + 800e246: 0018 movs r0, r3 + 800e248: 46bd mov sp, r7 + 800e24a: bd80 pop {r7, pc} + +0800e24c : + +void msleep(int ms) +{ + 800e24c: b580 push {r7, lr} + 800e24e: b084 sub sp, #16 + 800e250: af00 add r7, sp, #0 + 800e252: 6078 str r0, [r7, #4] + uint32_t t = mtime(); + 800e254: f7ff fff2 bl 800e23c + 800e258: 0003 movs r3, r0 + 800e25a: 60fb str r3, [r7, #12] + while (true) + { + uint32_t t1 = mtime(); + 800e25c: f7ff ffee bl 800e23c + 800e260: 0003 movs r3, r0 + 800e262: 60bb str r3, [r7, #8] + if (t1 - t >= ms) break; + 800e264: 68ba ldr r2, [r7, #8] + 800e266: 68fb ldr r3, [r7, #12] + 800e268: 1ad2 subs r2, r2, r3 + 800e26a: 687b ldr r3, [r7, #4] + 800e26c: 429a cmp r2, r3 + 800e26e: d204 bcs.n 800e27a + if (t1 < t) break; /* overflow */ + 800e270: 68ba ldr r2, [r7, #8] + 800e272: 68fb ldr r3, [r7, #12] + 800e274: 429a cmp r2, r3 + 800e276: d302 bcc.n 800e27e + { + 800e278: e7f0 b.n 800e25c + if (t1 - t >= ms) break; + 800e27a: 46c0 nop ; (mov r8, r8) + 800e27c: e000 b.n 800e280 + if (t1 < t) break; /* overflow */ + 800e27e: 46c0 nop ; (mov r8, r8) + } +} + 800e280: 46c0 nop ; (mov r8, r8) + 800e282: 46bd mov sp, r7 + 800e284: b004 add sp, #16 + 800e286: bd80 pop {r7, pc} + +0800e288 : + +static stmr_t *stmrs = NULL; + +void stmr(void) +{ + 800e288: b580 push {r7, lr} + 800e28a: b084 sub sp, #16 + 800e28c: af00 add r7, sp, #0 + stmr_t *tmr; + uint32_t time; + time = mtime(); + 800e28e: f7ff ffd5 bl 800e23c + 800e292: 0003 movs r3, r0 + 800e294: 60bb str r3, [r7, #8] + tmr = stmrs; + 800e296: 4b16 ldr r3, [pc, #88] ; (800e2f0 ) + 800e298: 681b ldr r3, [r3, #0] + 800e29a: 60fb str r3, [r7, #12] + while (tmr != NULL) + 800e29c: e021 b.n 800e2e2 + { + stmr_t *t; + uint32_t elapsed; + t = tmr; + 800e29e: 68fb ldr r3, [r7, #12] + 800e2a0: 607b str r3, [r7, #4] + tmr = tmr->next; + 800e2a2: 68fb ldr r3, [r7, #12] + 800e2a4: 695b ldr r3, [r3, #20] + 800e2a6: 60fb str r3, [r7, #12] + if ((t->flags & STMR_ACTIVE) == 0) + 800e2a8: 687b ldr r3, [r7, #4] + 800e2aa: 689b ldr r3, [r3, #8] + 800e2ac: 2201 movs r2, #1 + 800e2ae: 4013 ands r3, r2 + 800e2b0: d100 bne.n 800e2b4 + continue; + 800e2b2: e016 b.n 800e2e2 + elapsed = time; + 800e2b4: 68bb ldr r3, [r7, #8] + 800e2b6: 603b str r3, [r7, #0] + elapsed -= t->event; + 800e2b8: 687b ldr r3, [r7, #4] + 800e2ba: 685b ldr r3, [r3, #4] + 800e2bc: 683a ldr r2, [r7, #0] + 800e2be: 1ad3 subs r3, r2, r3 + 800e2c0: 603b str r3, [r7, #0] + if (elapsed < t->period) + 800e2c2: 687b ldr r3, [r7, #4] + 800e2c4: 681b ldr r3, [r3, #0] + 800e2c6: 683a ldr r2, [r7, #0] + 800e2c8: 429a cmp r2, r3 + 800e2ca: d200 bcs.n 800e2ce + continue; + 800e2cc: e009 b.n 800e2e2 + t->proc(t); + 800e2ce: 687b ldr r3, [r7, #4] + 800e2d0: 691b ldr r3, [r3, #16] + 800e2d2: 687a ldr r2, [r7, #4] + 800e2d4: 0010 movs r0, r2 + 800e2d6: 4798 blx r3 + t->event = mtime(); + 800e2d8: f7ff ffb0 bl 800e23c + 800e2dc: 0002 movs r2, r0 + 800e2de: 687b ldr r3, [r7, #4] + 800e2e0: 605a str r2, [r3, #4] + while (tmr != NULL) + 800e2e2: 68fb ldr r3, [r7, #12] + 800e2e4: 2b00 cmp r3, #0 + 800e2e6: d1da bne.n 800e29e + } +} + 800e2e8: 46c0 nop ; (mov r8, r8) + 800e2ea: 46bd mov sp, r7 + 800e2ec: b004 add sp, #16 + 800e2ee: bd80 pop {r7, pc} + 800e2f0: 200023c4 .word 0x200023c4 + +0800e2f4 : + tmr->next = stmrs; + stmrs = tmr; +} + +void stmr_add(stmr_t *tmr) +{ + 800e2f4: b580 push {r7, lr} + 800e2f6: b082 sub sp, #8 + 800e2f8: af00 add r7, sp, #0 + 800e2fa: 6078 str r0, [r7, #4] + tmr->next = stmrs; + 800e2fc: 4b05 ldr r3, [pc, #20] ; (800e314 ) + 800e2fe: 681a ldr r2, [r3, #0] + 800e300: 687b ldr r3, [r7, #4] + 800e302: 615a str r2, [r3, #20] + stmrs = tmr; + 800e304: 4b03 ldr r3, [pc, #12] ; (800e314 ) + 800e306: 687a ldr r2, [r7, #4] + 800e308: 601a str r2, [r3, #0] +} + 800e30a: 46c0 nop ; (mov r8, r8) + 800e30c: 46bd mov sp, r7 + 800e30e: b002 add sp, #8 + 800e310: bd80 pop {r7, pc} + 800e312: 46c0 nop ; (mov r8, r8) + 800e314: 200023c4 .word 0x200023c4 + +0800e318 : +/** + * Init USB device Library, add supported class and start the library + * @retval None + */ +void MX_USB_DEVICE_Init(void) +{ + 800e318: b580 push {r7, lr} + 800e31a: af00 add r7, sp, #0 + /* USER CODE BEGIN USB_DEVICE_Init_PreTreatment */ + + /* USER CODE END USB_DEVICE_Init_PreTreatment */ + + /* Init Device Library, add supported class and start the library. */ + if (USBD_Init(&hUsbDeviceFS, &VCP_Desc, 0) != USBD_OK) + 800e31c: 4913 ldr r1, [pc, #76] ; (800e36c ) + 800e31e: 4b14 ldr r3, [pc, #80] ; (800e370 ) + 800e320: 2200 movs r2, #0 + 800e322: 0018 movs r0, r3 + 800e324: f000 fa5b bl 800e7de + 800e328: 1e03 subs r3, r0, #0 + 800e32a: d001 beq.n 800e330 + { + Error_Handler(); + 800e32c: f7f2 f8f0 bl 8000510 + } + if (USBD_RegisterClass(&hUsbDeviceFS, &USBD_ECM) != USBD_OK) + 800e330: 4a10 ldr r2, [pc, #64] ; (800e374 ) + 800e332: 4b0f ldr r3, [pc, #60] ; (800e370 ) + 800e334: 0011 movs r1, r2 + 800e336: 0018 movs r0, r3 + 800e338: f000 fa82 bl 800e840 + 800e33c: 1e03 subs r3, r0, #0 + 800e33e: d001 beq.n 800e344 + { + Error_Handler(); + 800e340: f7f2 f8e6 bl 8000510 + } + if (USBD_ECM_RegisterInterface(&hUsbDeviceFS) != USBD_OK) + 800e344: 4b0a ldr r3, [pc, #40] ; (800e370 ) + 800e346: 0018 movs r0, r3 + 800e348: f001 fb6e bl 800fa28 + 800e34c: 1e03 subs r3, r0, #0 + 800e34e: d001 beq.n 800e354 + { + Error_Handler(); + 800e350: f7f2 f8de bl 8000510 + } + if (USBD_Start(&hUsbDeviceFS) != USBD_OK) + 800e354: 4b06 ldr r3, [pc, #24] ; (800e370 ) + 800e356: 0018 movs r0, r3 + 800e358: f000 fa93 bl 800e882 + 800e35c: 1e03 subs r3, r0, #0 + 800e35e: d001 beq.n 800e364 + { + Error_Handler(); + 800e360: f7f2 f8d6 bl 8000510 + } + + /* USER CODE BEGIN USB_DEVICE_Init_PostTreatment */ + + /* USER CODE END USB_DEVICE_Init_PostTreatment */ +} + 800e364: 46c0 nop ; (mov r8, r8) + 800e366: 46bd mov sp, r7 + 800e368: bd80 pop {r7, pc} + 800e36a: 46c0 nop ; (mov r8, r8) + 800e36c: 0800fe00 .word 0x0800fe00 + 800e370: 200032a4 .word 0x200032a4 + 800e374: 0800fe7c .word 0x0800fe7c + +0800e378 : + */ +#ifndef GPIO_SPEED_HIGH +#define GPIO_SPEED_HIGH GPIO_SPEED_FREQ_HIGH +#endif +void HAL_PCD_MspInit(PCD_HandleTypeDef *hpcd) +{ + 800e378: b580 push {r7, lr} + 800e37a: b08a sub sp, #40 ; 0x28 + 800e37c: af00 add r7, sp, #0 + 800e37e: 6078 str r0, [r7, #4] + GPIO_InitTypeDef GPIO_InitStruct; + + /* Enable the GPIOA clock */ + __HAL_RCC_GPIOA_CLK_ENABLE(); + 800e380: 4b1f ldr r3, [pc, #124] ; (800e400 ) + 800e382: 695a ldr r2, [r3, #20] + 800e384: 4b1e ldr r3, [pc, #120] ; (800e400 ) + 800e386: 2180 movs r1, #128 ; 0x80 + 800e388: 0289 lsls r1, r1, #10 + 800e38a: 430a orrs r2, r1 + 800e38c: 615a str r2, [r3, #20] + 800e38e: 4b1c ldr r3, [pc, #112] ; (800e400 ) + 800e390: 695a ldr r2, [r3, #20] + 800e392: 2380 movs r3, #128 ; 0x80 + 800e394: 029b lsls r3, r3, #10 + 800e396: 4013 ands r3, r2 + 800e398: 613b str r3, [r7, #16] + 800e39a: 693b ldr r3, [r7, #16] + + /* Configure USB DM and DP pins. + This is optional, and maintained only for user guidance. */ + GPIO_InitStruct.Pin = (GPIO_PIN_11 | GPIO_PIN_12); + 800e39c: 2114 movs r1, #20 + 800e39e: 187b adds r3, r7, r1 + 800e3a0: 22c0 movs r2, #192 ; 0xc0 + 800e3a2: 0152 lsls r2, r2, #5 + 800e3a4: 601a str r2, [r3, #0] + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + 800e3a6: 187b adds r3, r7, r1 + 800e3a8: 2202 movs r2, #2 + 800e3aa: 605a str r2, [r3, #4] + GPIO_InitStruct.Pull = GPIO_NOPULL; + 800e3ac: 187b adds r3, r7, r1 + 800e3ae: 2200 movs r2, #0 + 800e3b0: 609a str r2, [r3, #8] + GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; + 800e3b2: 187b adds r3, r7, r1 + 800e3b4: 2203 movs r2, #3 + 800e3b6: 60da str r2, [r3, #12] + GPIO_InitStruct.Alternate = GPIO_AF2_USB; + 800e3b8: 187b adds r3, r7, r1 + 800e3ba: 2202 movs r2, #2 + 800e3bc: 611a str r2, [r3, #16] + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + 800e3be: 187a adds r2, r7, r1 + 800e3c0: 2390 movs r3, #144 ; 0x90 + 800e3c2: 05db lsls r3, r3, #23 + 800e3c4: 0011 movs r1, r2 + 800e3c6: 0018 movs r0, r3 + 800e3c8: f7f2 fa64 bl 8000894 + + /* Enable USB FS Clock */ + __HAL_RCC_USB_CLK_ENABLE(); + 800e3cc: 4b0c ldr r3, [pc, #48] ; (800e400 ) + 800e3ce: 69da ldr r2, [r3, #28] + 800e3d0: 4b0b ldr r3, [pc, #44] ; (800e400 ) + 800e3d2: 2180 movs r1, #128 ; 0x80 + 800e3d4: 0409 lsls r1, r1, #16 + 800e3d6: 430a orrs r2, r1 + 800e3d8: 61da str r2, [r3, #28] + 800e3da: 4b09 ldr r3, [pc, #36] ; (800e400 ) + 800e3dc: 69da ldr r2, [r3, #28] + 800e3de: 2380 movs r3, #128 ; 0x80 + 800e3e0: 041b lsls r3, r3, #16 + 800e3e2: 4013 ands r3, r2 + 800e3e4: 60fb str r3, [r7, #12] + 800e3e6: 68fb ldr r3, [r7, #12] + + /* Set USB FS Interrupt priority */ + HAL_NVIC_SetPriority(USB_IRQn, 3 /* hard-coded: customize if needed */, 0); + 800e3e8: 2200 movs r2, #0 + 800e3ea: 2103 movs r1, #3 + 800e3ec: 201f movs r0, #31 + 800e3ee: f7f2 fa1f bl 8000830 + + /* Enable USB FS Interrupt */ + HAL_NVIC_EnableIRQ(USB_IRQn); + 800e3f2: 201f movs r0, #31 + 800e3f4: f7f2 fa31 bl 800085a +} + 800e3f8: 46c0 nop ; (mov r8, r8) + 800e3fa: 46bd mov sp, r7 + 800e3fc: b00a add sp, #40 ; 0x28 + 800e3fe: bd80 pop {r7, pc} + 800e400: 40021000 .word 0x40021000 + +0800e404 : + * @brief SOF callback. + * @param hpcd: PCD handle + * @retval None + */ +void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd) +{ + 800e404: b580 push {r7, lr} + 800e406: b082 sub sp, #8 + 800e408: af00 add r7, sp, #0 + 800e40a: 6078 str r0, [r7, #4] + USBD_LL_SetupStage(hpcd->pData, (uint8_t *)hpcd->Setup); + 800e40c: 687a ldr r2, [r7, #4] + 800e40e: 239c movs r3, #156 ; 0x9c + 800e410: 009b lsls r3, r3, #2 + 800e412: 58d2 ldr r2, [r2, r3] + 800e414: 687b ldr r3, [r7, #4] + 800e416: 218c movs r1, #140 ; 0x8c + 800e418: 0089 lsls r1, r1, #2 + 800e41a: 468c mov ip, r1 + 800e41c: 4463 add r3, ip + 800e41e: 0019 movs r1, r3 + 800e420: 0010 movs r0, r2 + 800e422: f000 fa79 bl 800e918 +} + 800e426: 46c0 nop ; (mov r8, r8) + 800e428: 46bd mov sp, r7 + 800e42a: b002 add sp, #8 + 800e42c: bd80 pop {r7, pc} + +0800e42e : + * @param hpcd: PCD handle + * @param epnum: Endpoint Number + * @retval None + */ +void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) +{ + 800e42e: b580 push {r7, lr} + 800e430: b082 sub sp, #8 + 800e432: af00 add r7, sp, #0 + 800e434: 6078 str r0, [r7, #4] + 800e436: 000a movs r2, r1 + 800e438: 1cfb adds r3, r7, #3 + 800e43a: 701a strb r2, [r3, #0] + USBD_LL_DataOutStage(hpcd->pData, epnum, hpcd->OUT_ep[epnum].xfer_buff); + 800e43c: 687a ldr r2, [r7, #4] + 800e43e: 239c movs r3, #156 ; 0x9c + 800e440: 009b lsls r3, r3, #2 + 800e442: 58d0 ldr r0, [r2, r3] + 800e444: 1cfb adds r3, r7, #3 + 800e446: 781a ldrb r2, [r3, #0] + 800e448: 6879 ldr r1, [r7, #4] + 800e44a: 239e movs r3, #158 ; 0x9e + 800e44c: 005b lsls r3, r3, #1 + 800e44e: 0152 lsls r2, r2, #5 + 800e450: 188a adds r2, r1, r2 + 800e452: 18d3 adds r3, r2, r3 + 800e454: 681a ldr r2, [r3, #0] + 800e456: 1cfb adds r3, r7, #3 + 800e458: 781b ldrb r3, [r3, #0] + 800e45a: 0019 movs r1, r3 + 800e45c: f000 fab8 bl 800e9d0 +} + 800e460: 46c0 nop ; (mov r8, r8) + 800e462: 46bd mov sp, r7 + 800e464: b002 add sp, #8 + 800e466: bd80 pop {r7, pc} + +0800e468 : + * @param hpcd: PCD handle + * @param epnum: Endpoint Number + * @retval None + */ +void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) +{ + 800e468: b580 push {r7, lr} + 800e46a: b082 sub sp, #8 + 800e46c: af00 add r7, sp, #0 + 800e46e: 6078 str r0, [r7, #4] + 800e470: 000a movs r2, r1 + 800e472: 1cfb adds r3, r7, #3 + 800e474: 701a strb r2, [r3, #0] + USBD_LL_DataInStage(hpcd->pData, epnum, hpcd->IN_ep[epnum].xfer_buff); + 800e476: 687a ldr r2, [r7, #4] + 800e478: 239c movs r3, #156 ; 0x9c + 800e47a: 009b lsls r3, r3, #2 + 800e47c: 58d0 ldr r0, [r2, r3] + 800e47e: 1cfb adds r3, r7, #3 + 800e480: 781b ldrb r3, [r3, #0] + 800e482: 687a ldr r2, [r7, #4] + 800e484: 015b lsls r3, r3, #5 + 800e486: 18d3 adds r3, r2, r3 + 800e488: 333c adds r3, #60 ; 0x3c + 800e48a: 681a ldr r2, [r3, #0] + 800e48c: 1cfb adds r3, r7, #3 + 800e48e: 781b ldrb r3, [r3, #0] + 800e490: 0019 movs r1, r3 + 800e492: f000 fb06 bl 800eaa2 +} + 800e496: 46c0 nop ; (mov r8, r8) + 800e498: 46bd mov sp, r7 + 800e49a: b002 add sp, #8 + 800e49c: bd80 pop {r7, pc} + +0800e49e : + * @brief SOF callback. + * @param hpcd: PCD handle + * @retval None + */ +void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd) +{ + 800e49e: b580 push {r7, lr} + 800e4a0: b082 sub sp, #8 + 800e4a2: af00 add r7, sp, #0 + 800e4a4: 6078 str r0, [r7, #4] + USBD_LL_SOF(hpcd->pData); + 800e4a6: 687a ldr r2, [r7, #4] + 800e4a8: 239c movs r3, #156 ; 0x9c + 800e4aa: 009b lsls r3, r3, #2 + 800e4ac: 58d3 ldr r3, [r2, r3] + 800e4ae: 0018 movs r0, r3 + 800e4b0: f000 fbc1 bl 800ec36 +} + 800e4b4: 46c0 nop ; (mov r8, r8) + 800e4b6: 46bd mov sp, r7 + 800e4b8: b002 add sp, #8 + 800e4ba: bd80 pop {r7, pc} + +0800e4bc : + * @brief SOF callback. + * @param hpcd: PCD handle + * @retval None + */ +void HAL_PCD_ResetCallback(PCD_HandleTypeDef *hpcd) +{ + 800e4bc: b580 push {r7, lr} + 800e4be: b082 sub sp, #8 + 800e4c0: af00 add r7, sp, #0 + 800e4c2: 6078 str r0, [r7, #4] + USBD_LL_SetSpeed(hpcd->pData, USBD_SPEED_FULL); + 800e4c4: 687a ldr r2, [r7, #4] + 800e4c6: 239c movs r3, #156 ; 0x9c + 800e4c8: 009b lsls r3, r3, #2 + 800e4ca: 58d3 ldr r3, [r2, r3] + 800e4cc: 2101 movs r1, #1 + 800e4ce: 0018 movs r0, r3 + 800e4d0: f000 fba1 bl 800ec16 + /* Reset Device */ + USBD_LL_Reset(hpcd->pData); + 800e4d4: 687a ldr r2, [r7, #4] + 800e4d6: 239c movs r3, #156 ; 0x9c + 800e4d8: 009b lsls r3, r3, #2 + 800e4da: 58d3 ldr r3, [r2, r3] + 800e4dc: 0018 movs r0, r3 + 800e4de: f000 fb67 bl 800ebb0 +} + 800e4e2: 46c0 nop ; (mov r8, r8) + 800e4e4: 46bd mov sp, r7 + 800e4e6: b002 add sp, #8 + 800e4e8: bd80 pop {r7, pc} + +0800e4ea : + * @brief SOF callback. + * @param hpcd: PCD handle + * @retval None + */ +void HAL_PCD_SuspendCallback(PCD_HandleTypeDef *hpcd) +{ + 800e4ea: b580 push {r7, lr} + 800e4ec: b082 sub sp, #8 + 800e4ee: af00 add r7, sp, #0 + 800e4f0: 6078 str r0, [r7, #4] +} + 800e4f2: 46c0 nop ; (mov r8, r8) + 800e4f4: 46bd mov sp, r7 + 800e4f6: b002 add sp, #8 + 800e4f8: bd80 pop {r7, pc} + +0800e4fa : + * @brief SOF callback. + * @param hpcd: PCD handle + * @retval None + */ +void HAL_PCD_ResumeCallback(PCD_HandleTypeDef *hpcd) +{ + 800e4fa: b580 push {r7, lr} + 800e4fc: b082 sub sp, #8 + 800e4fe: af00 add r7, sp, #0 + 800e500: 6078 str r0, [r7, #4] +} + 800e502: 46c0 nop ; (mov r8, r8) + 800e504: 46bd mov sp, r7 + 800e506: b002 add sp, #8 + 800e508: bd80 pop {r7, pc} + ... + +0800e50c : + * @brief Initializes the Low Level portion of the Device driver. + * @param pdev: Device handle + * @retval USBD Status + */ +USBD_StatusTypeDef USBD_LL_Init(USBD_HandleTypeDef *pdev) +{ + 800e50c: b580 push {r7, lr} + 800e50e: b084 sub sp, #16 + 800e510: af00 add r7, sp, #0 + 800e512: 6078 str r0, [r7, #4] + uint32_t pma_address; + + /* Set LL Driver parameters */ + hpcd.Instance = USB; + 800e514: 4b21 ldr r3, [pc, #132] ; (800e59c ) + 800e516: 4a22 ldr r2, [pc, #136] ; (800e5a0 ) + 800e518: 601a str r2, [r3, #0] + hpcd.Init.ep0_mps = 0x40; + 800e51a: 4b20 ldr r3, [pc, #128] ; (800e59c ) + 800e51c: 2240 movs r2, #64 ; 0x40 + 800e51e: 60da str r2, [r3, #12] + hpcd.Init.phy_itface = PCD_PHY_EMBEDDED; + 800e520: 4b1e ldr r3, [pc, #120] ; (800e59c ) + 800e522: 2202 movs r2, #2 + 800e524: 611a str r2, [r3, #16] + hpcd.Init.speed = PCD_SPEED_FULL; + 800e526: 4b1d ldr r3, [pc, #116] ; (800e59c ) + 800e528: 2202 movs r2, #2 + 800e52a: 609a str r2, [r3, #8] + /* Link The driver to the stack */ + hpcd.pData = pdev; + 800e52c: 4a1b ldr r2, [pc, #108] ; (800e59c ) + 800e52e: 239c movs r3, #156 ; 0x9c + 800e530: 009b lsls r3, r3, #2 + 800e532: 6879 ldr r1, [r7, #4] + 800e534: 50d1 str r1, [r2, r3] + pdev->pData = &hpcd; + 800e536: 687a ldr r2, [r7, #4] + 800e538: 2387 movs r3, #135 ; 0x87 + 800e53a: 009b lsls r3, r3, #2 + 800e53c: 4917 ldr r1, [pc, #92] ; (800e59c ) + 800e53e: 50d1 str r1, [r2, r3] + /* Initialize LL Driver */ + HAL_PCD_Init(pdev->pData); + 800e540: 687a ldr r2, [r7, #4] + 800e542: 2387 movs r3, #135 ; 0x87 + 800e544: 009b lsls r3, r3, #2 + 800e546: 58d3 ldr r3, [r2, r3] + 800e548: 0018 movs r0, r3 + 800e54a: f7f2 fb1b bl 8000b84 + /* + start address for PMA allocation: + ST's USB stack forces a BTABLE_ADDRESS at the start of PMA memory. The BTABLE occupied 8 bytes per endpoint. + we position the EP buffers starting immediately after this + */ + pma_address = 8 * MAX((sizeof(hpcd.IN_ep) / sizeof(*hpcd.IN_ep)), (sizeof(hpcd.OUT_ep) / sizeof(*hpcd.OUT_ep))); + 800e54e: 2340 movs r3, #64 ; 0x40 + 800e550: 60fb str r3, [r7, #12] + + /* PMA allocation for EP0 */ + HAL_PCDEx_PMAConfig(pdev->pData, 0x00, PCD_SNG_BUF, pma_address =+ USB_MAX_EP0_SIZE); + 800e552: 687a ldr r2, [r7, #4] + 800e554: 2387 movs r3, #135 ; 0x87 + 800e556: 009b lsls r3, r3, #2 + 800e558: 58d0 ldr r0, [r2, r3] + 800e55a: 2340 movs r3, #64 ; 0x40 + 800e55c: 60fb str r3, [r7, #12] + 800e55e: 68fb ldr r3, [r7, #12] + 800e560: 2200 movs r2, #0 + 800e562: 2100 movs r1, #0 + 800e564: f7f3 fab0 bl 8001ac8 + HAL_PCDEx_PMAConfig(pdev->pData, 0x80, PCD_SNG_BUF, pma_address =+ USB_MAX_EP0_SIZE); + 800e568: 687a ldr r2, [r7, #4] + 800e56a: 2387 movs r3, #135 ; 0x87 + 800e56c: 009b lsls r3, r3, #2 + 800e56e: 58d0 ldr r0, [r2, r3] + 800e570: 2340 movs r3, #64 ; 0x40 + 800e572: 60fb str r3, [r7, #12] + 800e574: 68fb ldr r3, [r7, #12] + 800e576: 2200 movs r2, #0 + 800e578: 2180 movs r1, #128 ; 0x80 + 800e57a: f7f3 faa5 bl 8001ac8 + + /* PMA allocation for other endpoints */ + USBD_ECM_PMAConfig(pdev->pData, &pma_address); + 800e57e: 687a ldr r2, [r7, #4] + 800e580: 2387 movs r3, #135 ; 0x87 + 800e582: 009b lsls r3, r3, #2 + 800e584: 58d3 ldr r3, [r2, r3] + 800e586: 220c movs r2, #12 + 800e588: 18ba adds r2, r7, r2 + 800e58a: 0011 movs r1, r2 + 800e58c: 0018 movs r0, r3 + 800e58e: f001 fa54 bl 800fa3a + + return USBD_OK; + 800e592: 2300 movs r3, #0 +} + 800e594: 0018 movs r0, r3 + 800e596: 46bd mov sp, r7 + 800e598: b004 add sp, #16 + 800e59a: bd80 pop {r7, pc} + 800e59c: 200034c4 .word 0x200034c4 + 800e5a0: 40005c00 .word 0x40005c00 + +0800e5a4 : + * @brief Starts the Low Level portion of the Device driver. + * @param pdev: Device handle + * @retval USBD Status + */ +USBD_StatusTypeDef USBD_LL_Start(USBD_HandleTypeDef *pdev) +{ + 800e5a4: b580 push {r7, lr} + 800e5a6: b082 sub sp, #8 + 800e5a8: af00 add r7, sp, #0 + 800e5aa: 6078 str r0, [r7, #4] + HAL_PCD_Start(pdev->pData); + 800e5ac: 687a ldr r2, [r7, #4] + 800e5ae: 2387 movs r3, #135 ; 0x87 + 800e5b0: 009b lsls r3, r3, #2 + 800e5b2: 58d3 ldr r3, [r2, r3] + 800e5b4: 0018 movs r0, r3 + 800e5b6: f7f2 fbc9 bl 8000d4c + return USBD_OK; + 800e5ba: 2300 movs r3, #0 +} + 800e5bc: 0018 movs r0, r3 + 800e5be: 46bd mov sp, r7 + 800e5c0: b002 add sp, #8 + 800e5c2: bd80 pop {r7, pc} + +0800e5c4 : + */ +USBD_StatusTypeDef USBD_LL_OpenEP(USBD_HandleTypeDef *pdev, + uint8_t ep_addr, + uint8_t ep_type, + uint16_t ep_mps) +{ + 800e5c4: b590 push {r4, r7, lr} + 800e5c6: b083 sub sp, #12 + 800e5c8: af00 add r7, sp, #0 + 800e5ca: 6078 str r0, [r7, #4] + 800e5cc: 000c movs r4, r1 + 800e5ce: 0010 movs r0, r2 + 800e5d0: 0019 movs r1, r3 + 800e5d2: 1cfb adds r3, r7, #3 + 800e5d4: 1c22 adds r2, r4, #0 + 800e5d6: 701a strb r2, [r3, #0] + 800e5d8: 1cbb adds r3, r7, #2 + 800e5da: 1c02 adds r2, r0, #0 + 800e5dc: 701a strb r2, [r3, #0] + 800e5de: 003b movs r3, r7 + 800e5e0: 1c0a adds r2, r1, #0 + 800e5e2: 801a strh r2, [r3, #0] + HAL_PCD_EP_Open(pdev->pData, + 800e5e4: 687a ldr r2, [r7, #4] + 800e5e6: 2387 movs r3, #135 ; 0x87 + 800e5e8: 009b lsls r3, r3, #2 + 800e5ea: 58d0 ldr r0, [r2, r3] + 800e5ec: 1cbb adds r3, r7, #2 + 800e5ee: 781c ldrb r4, [r3, #0] + 800e5f0: 003b movs r3, r7 + 800e5f2: 881a ldrh r2, [r3, #0] + 800e5f4: 1cfb adds r3, r7, #3 + 800e5f6: 7819 ldrb r1, [r3, #0] + 800e5f8: 0023 movs r3, r4 + 800e5fa: f7f2 fd80 bl 80010fe + ep_addr, + ep_mps, + ep_type); + + return USBD_OK; + 800e5fe: 2300 movs r3, #0 +} + 800e600: 0018 movs r0, r3 + 800e602: 46bd mov sp, r7 + 800e604: b003 add sp, #12 + 800e606: bd90 pop {r4, r7, pc} + +0800e608 : + * @param pdev: Device handle + * @param ep_addr: Endpoint Number + * @retval USBD Status + */ +USBD_StatusTypeDef USBD_LL_CloseEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr) +{ + 800e608: b580 push {r7, lr} + 800e60a: b082 sub sp, #8 + 800e60c: af00 add r7, sp, #0 + 800e60e: 6078 str r0, [r7, #4] + 800e610: 000a movs r2, r1 + 800e612: 1cfb adds r3, r7, #3 + 800e614: 701a strb r2, [r3, #0] + HAL_PCD_EP_Close(pdev->pData, ep_addr); + 800e616: 687a ldr r2, [r7, #4] + 800e618: 2387 movs r3, #135 ; 0x87 + 800e61a: 009b lsls r3, r3, #2 + 800e61c: 58d2 ldr r2, [r2, r3] + 800e61e: 1cfb adds r3, r7, #3 + 800e620: 781b ldrb r3, [r3, #0] + 800e622: 0019 movs r1, r3 + 800e624: 0010 movs r0, r2 + 800e626: f7f2 fddc bl 80011e2 + return USBD_OK; + 800e62a: 2300 movs r3, #0 +} + 800e62c: 0018 movs r0, r3 + 800e62e: 46bd mov sp, r7 + 800e630: b002 add sp, #8 + 800e632: bd80 pop {r7, pc} + +0800e634 : + * @param pdev: Device handle + * @param ep_addr: Endpoint Number + * @retval USBD Status + */ +USBD_StatusTypeDef USBD_LL_StallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr) +{ + 800e634: b580 push {r7, lr} + 800e636: b082 sub sp, #8 + 800e638: af00 add r7, sp, #0 + 800e63a: 6078 str r0, [r7, #4] + 800e63c: 000a movs r2, r1 + 800e63e: 1cfb adds r3, r7, #3 + 800e640: 701a strb r2, [r3, #0] + HAL_PCD_EP_SetStall(pdev->pData, ep_addr); + 800e642: 687a ldr r2, [r7, #4] + 800e644: 2387 movs r3, #135 ; 0x87 + 800e646: 009b lsls r3, r3, #2 + 800e648: 58d2 ldr r2, [r2, r3] + 800e64a: 1cfb adds r3, r7, #3 + 800e64c: 781b ldrb r3, [r3, #0] + 800e64e: 0019 movs r1, r3 + 800e650: 0010 movs r0, r2 + 800e652: f7f2 fea7 bl 80013a4 + return USBD_OK; + 800e656: 2300 movs r3, #0 +} + 800e658: 0018 movs r0, r3 + 800e65a: 46bd mov sp, r7 + 800e65c: b002 add sp, #8 + 800e65e: bd80 pop {r7, pc} + +0800e660 : + * @param pdev: Device handle + * @param ep_addr: Endpoint Number + * @retval USBD Status + */ +USBD_StatusTypeDef USBD_LL_ClearStallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr) +{ + 800e660: b580 push {r7, lr} + 800e662: b082 sub sp, #8 + 800e664: af00 add r7, sp, #0 + 800e666: 6078 str r0, [r7, #4] + 800e668: 000a movs r2, r1 + 800e66a: 1cfb adds r3, r7, #3 + 800e66c: 701a strb r2, [r3, #0] + HAL_PCD_EP_ClrStall(pdev->pData, ep_addr); + 800e66e: 687a ldr r2, [r7, #4] + 800e670: 2387 movs r3, #135 ; 0x87 + 800e672: 009b lsls r3, r3, #2 + 800e674: 58d2 ldr r2, [r2, r3] + 800e676: 1cfb adds r3, r7, #3 + 800e678: 781b ldrb r3, [r3, #0] + 800e67a: 0019 movs r1, r3 + 800e67c: 0010 movs r0, r2 + 800e67e: f7f2 fef7 bl 8001470 + return USBD_OK; + 800e682: 2300 movs r3, #0 +} + 800e684: 0018 movs r0, r3 + 800e686: 46bd mov sp, r7 + 800e688: b002 add sp, #8 + 800e68a: bd80 pop {r7, pc} + +0800e68c : + * @param pdev: Device handle + * @param ep_addr: Endpoint Number + * @retval Stall (1: Yes, 0: No) + */ +uint8_t USBD_LL_IsStallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr) +{ + 800e68c: b580 push {r7, lr} + 800e68e: b084 sub sp, #16 + 800e690: af00 add r7, sp, #0 + 800e692: 6078 str r0, [r7, #4] + 800e694: 000a movs r2, r1 + 800e696: 1cfb adds r3, r7, #3 + 800e698: 701a strb r2, [r3, #0] + PCD_HandleTypeDef *hpcd = pdev->pData; + 800e69a: 687a ldr r2, [r7, #4] + 800e69c: 2387 movs r3, #135 ; 0x87 + 800e69e: 009b lsls r3, r3, #2 + 800e6a0: 58d3 ldr r3, [r2, r3] + 800e6a2: 60fb str r3, [r7, #12] + + if((ep_addr & 0x80) == 0x80) + 800e6a4: 1cfb adds r3, r7, #3 + 800e6a6: 781b ldrb r3, [r3, #0] + 800e6a8: b25b sxtb r3, r3 + 800e6aa: 2b00 cmp r3, #0 + 800e6ac: da0a bge.n 800e6c4 + { + return hpcd->IN_ep[ep_addr & 0x7F].is_stall; + 800e6ae: 1cfb adds r3, r7, #3 + 800e6b0: 781b ldrb r3, [r3, #0] + 800e6b2: 227f movs r2, #127 ; 0x7f + 800e6b4: 4013 ands r3, r2 + 800e6b6: 68fa ldr r2, [r7, #12] + 800e6b8: 212a movs r1, #42 ; 0x2a + 800e6ba: 015b lsls r3, r3, #5 + 800e6bc: 18d3 adds r3, r2, r3 + 800e6be: 185b adds r3, r3, r1 + 800e6c0: 781b ldrb r3, [r3, #0] + 800e6c2: e00a b.n 800e6da + } + else + { + return hpcd->OUT_ep[ep_addr & 0x7F].is_stall; + 800e6c4: 1cfb adds r3, r7, #3 + 800e6c6: 781b ldrb r3, [r3, #0] + 800e6c8: 227f movs r2, #127 ; 0x7f + 800e6ca: 401a ands r2, r3 + 800e6cc: 68f9 ldr r1, [r7, #12] + 800e6ce: 2395 movs r3, #149 ; 0x95 + 800e6d0: 005b lsls r3, r3, #1 + 800e6d2: 0152 lsls r2, r2, #5 + 800e6d4: 188a adds r2, r1, r2 + 800e6d6: 18d3 adds r3, r2, r3 + 800e6d8: 781b ldrb r3, [r3, #0] + } +} + 800e6da: 0018 movs r0, r3 + 800e6dc: 46bd mov sp, r7 + 800e6de: b004 add sp, #16 + 800e6e0: bd80 pop {r7, pc} + +0800e6e2 : + * @param pdev: Device handle + * @param ep_addr: Endpoint Number + * @retval USBD Status + */ +USBD_StatusTypeDef USBD_LL_SetUSBAddress(USBD_HandleTypeDef *pdev, uint8_t dev_addr) +{ + 800e6e2: b580 push {r7, lr} + 800e6e4: b082 sub sp, #8 + 800e6e6: af00 add r7, sp, #0 + 800e6e8: 6078 str r0, [r7, #4] + 800e6ea: 000a movs r2, r1 + 800e6ec: 1cfb adds r3, r7, #3 + 800e6ee: 701a strb r2, [r3, #0] + HAL_PCD_SetAddress(pdev->pData, dev_addr); + 800e6f0: 687a ldr r2, [r7, #4] + 800e6f2: 2387 movs r3, #135 ; 0x87 + 800e6f4: 009b lsls r3, r3, #2 + 800e6f6: 58d2 ldr r2, [r2, r3] + 800e6f8: 1cfb adds r3, r7, #3 + 800e6fa: 781b ldrb r3, [r3, #0] + 800e6fc: 0019 movs r1, r3 + 800e6fe: 0010 movs r0, r2 + 800e700: f7f2 fcd2 bl 80010a8 + return USBD_OK; + 800e704: 2300 movs r3, #0 +} + 800e706: 0018 movs r0, r3 + 800e708: 46bd mov sp, r7 + 800e70a: b002 add sp, #8 + 800e70c: bd80 pop {r7, pc} + +0800e70e : + */ +USBD_StatusTypeDef USBD_LL_Transmit(USBD_HandleTypeDef *pdev, + uint8_t ep_addr, + uint8_t *pbuf, + uint16_t size) +{ + 800e70e: b5f0 push {r4, r5, r6, r7, lr} + 800e710: b087 sub sp, #28 + 800e712: af00 add r7, sp, #0 + 800e714: 60f8 str r0, [r7, #12] + 800e716: 0008 movs r0, r1 + 800e718: 607a str r2, [r7, #4] + 800e71a: 0019 movs r1, r3 + 800e71c: 260b movs r6, #11 + 800e71e: 19bb adds r3, r7, r6 + 800e720: 1c02 adds r2, r0, #0 + 800e722: 701a strb r2, [r3, #0] + 800e724: 2408 movs r4, #8 + 800e726: 193b adds r3, r7, r4 + 800e728: 1c0a adds r2, r1, #0 + 800e72a: 801a strh r2, [r3, #0] + HAL_StatusTypeDef outcome; + outcome = HAL_PCD_EP_Transmit(pdev->pData, ep_addr, pbuf, size); + 800e72c: 68fa ldr r2, [r7, #12] + 800e72e: 2387 movs r3, #135 ; 0x87 + 800e730: 009b lsls r3, r3, #2 + 800e732: 58d0 ldr r0, [r2, r3] + 800e734: 193b adds r3, r7, r4 + 800e736: 881d ldrh r5, [r3, #0] + 800e738: 2317 movs r3, #23 + 800e73a: 18fc adds r4, r7, r3 + 800e73c: 687a ldr r2, [r7, #4] + 800e73e: 19bb adds r3, r7, r6 + 800e740: 7819 ldrb r1, [r3, #0] + 800e742: 002b movs r3, r5 + 800e744: f7f2 fdee bl 8001324 + 800e748: 0003 movs r3, r0 + 800e74a: 7023 strb r3, [r4, #0] + return (HAL_OK == outcome) ? USBD_OK : USBD_BUSY; + 800e74c: 2317 movs r3, #23 + 800e74e: 18fb adds r3, r7, r3 + 800e750: 781b ldrb r3, [r3, #0] + 800e752: 1e5a subs r2, r3, #1 + 800e754: 4193 sbcs r3, r2 + 800e756: b2db uxtb r3, r3 +} + 800e758: 0018 movs r0, r3 + 800e75a: 46bd mov sp, r7 + 800e75c: b007 add sp, #28 + 800e75e: bdf0 pop {r4, r5, r6, r7, pc} + +0800e760 : + */ +USBD_StatusTypeDef USBD_LL_PrepareReceive(USBD_HandleTypeDef *pdev, + uint8_t ep_addr, + uint8_t *pbuf, + uint16_t size) +{ + 800e760: b5f0 push {r4, r5, r6, r7, lr} + 800e762: b087 sub sp, #28 + 800e764: af00 add r7, sp, #0 + 800e766: 60f8 str r0, [r7, #12] + 800e768: 0008 movs r0, r1 + 800e76a: 607a str r2, [r7, #4] + 800e76c: 0019 movs r1, r3 + 800e76e: 260b movs r6, #11 + 800e770: 19bb adds r3, r7, r6 + 800e772: 1c02 adds r2, r0, #0 + 800e774: 701a strb r2, [r3, #0] + 800e776: 2408 movs r4, #8 + 800e778: 193b adds r3, r7, r4 + 800e77a: 1c0a adds r2, r1, #0 + 800e77c: 801a strh r2, [r3, #0] + HAL_StatusTypeDef outcome; + outcome = HAL_PCD_EP_Receive(pdev->pData, ep_addr, pbuf, size); + 800e77e: 68fa ldr r2, [r7, #12] + 800e780: 2387 movs r3, #135 ; 0x87 + 800e782: 009b lsls r3, r3, #2 + 800e784: 58d0 ldr r0, [r2, r3] + 800e786: 193b adds r3, r7, r4 + 800e788: 881d ldrh r5, [r3, #0] + 800e78a: 2317 movs r3, #23 + 800e78c: 18fc adds r4, r7, r3 + 800e78e: 687a ldr r2, [r7, #4] + 800e790: 19bb adds r3, r7, r6 + 800e792: 7819 ldrb r1, [r3, #0] + 800e794: 002b movs r3, r5 + 800e796: f7f2 fd6f bl 8001278 + 800e79a: 0003 movs r3, r0 + 800e79c: 7023 strb r3, [r4, #0] + return (HAL_OK == outcome) ? USBD_OK : USBD_BUSY; + 800e79e: 2317 movs r3, #23 + 800e7a0: 18fb adds r3, r7, r3 + 800e7a2: 781b ldrb r3, [r3, #0] + 800e7a4: 1e5a subs r2, r3, #1 + 800e7a6: 4193 sbcs r3, r2 + 800e7a8: b2db uxtb r3, r3 +} + 800e7aa: 0018 movs r0, r3 + 800e7ac: 46bd mov sp, r7 + 800e7ae: b007 add sp, #28 + 800e7b0: bdf0 pop {r4, r5, r6, r7, pc} + +0800e7b2 : + * @param pdev: Device handle + * @param ep_addr: Endpoint Number + * @retval Recived Data Size + */ +uint32_t USBD_LL_GetRxDataSize(USBD_HandleTypeDef *pdev, uint8_t ep_addr) +{ + 800e7b2: b580 push {r7, lr} + 800e7b4: b082 sub sp, #8 + 800e7b6: af00 add r7, sp, #0 + 800e7b8: 6078 str r0, [r7, #4] + 800e7ba: 000a movs r2, r1 + 800e7bc: 1cfb adds r3, r7, #3 + 800e7be: 701a strb r2, [r3, #0] + return HAL_PCD_EP_GetRxCount(pdev->pData, ep_addr); + 800e7c0: 687a ldr r2, [r7, #4] + 800e7c2: 2387 movs r3, #135 ; 0x87 + 800e7c4: 009b lsls r3, r3, #2 + 800e7c6: 58d2 ldr r2, [r2, r3] + 800e7c8: 1cfb adds r3, r7, #3 + 800e7ca: 781b ldrb r3, [r3, #0] + 800e7cc: 0019 movs r1, r3 + 800e7ce: 0010 movs r0, r2 + 800e7d0: f7f2 fd93 bl 80012fa + 800e7d4: 0003 movs r3, r0 +} + 800e7d6: 0018 movs r0, r3 + 800e7d8: 46bd mov sp, r7 + 800e7da: b002 add sp, #8 + 800e7dc: bd80 pop {r7, pc} + +0800e7de : +* @param pdesc: Descriptor structure address +* @param id: Low level core index +* @retval None +*/ +USBD_StatusTypeDef USBD_Init(USBD_HandleTypeDef *pdev, const USBD_DescriptorsTypeDef *pdesc, uint8_t id) +{ + 800e7de: b580 push {r7, lr} + 800e7e0: b084 sub sp, #16 + 800e7e2: af00 add r7, sp, #0 + 800e7e4: 60f8 str r0, [r7, #12] + 800e7e6: 60b9 str r1, [r7, #8] + 800e7e8: 1dfb adds r3, r7, #7 + 800e7ea: 701a strb r2, [r3, #0] + /* Check whether the USB Host handle is valid */ + if(pdev == NULL) + 800e7ec: 68fb ldr r3, [r7, #12] + 800e7ee: 2b00 cmp r3, #0 + 800e7f0: d101 bne.n 800e7f6 + { + USBD_ErrLog("Invalid Device handle"); + return USBD_FAIL; + 800e7f2: 2302 movs r3, #2 + 800e7f4: e020 b.n 800e838 + } + + /* Unlink previous class*/ + if(pdev->pClass != NULL) + 800e7f6: 68fa ldr r2, [r7, #12] + 800e7f8: 2384 movs r3, #132 ; 0x84 + 800e7fa: 009b lsls r3, r3, #2 + 800e7fc: 58d3 ldr r3, [r2, r3] + 800e7fe: 2b00 cmp r3, #0 + 800e800: d004 beq.n 800e80c + { + pdev->pClass = NULL; + 800e802: 68fa ldr r2, [r7, #12] + 800e804: 2384 movs r3, #132 ; 0x84 + 800e806: 009b lsls r3, r3, #2 + 800e808: 2100 movs r1, #0 + 800e80a: 50d1 str r1, [r2, r3] + } + + /* Assign USBD Descriptors */ + if(pdesc != NULL) + 800e80c: 68bb ldr r3, [r7, #8] + 800e80e: 2b00 cmp r3, #0 + 800e810: d004 beq.n 800e81c + { + pdev->pDesc = pdesc; + 800e812: 68fa ldr r2, [r7, #12] + 800e814: 2383 movs r3, #131 ; 0x83 + 800e816: 009b lsls r3, r3, #2 + 800e818: 68b9 ldr r1, [r7, #8] + 800e81a: 50d1 str r1, [r2, r3] + } + + /* Set Device initial State */ + pdev->dev_state = USBD_STATE_DEFAULT; + 800e81c: 68fa ldr r2, [r7, #12] + 800e81e: 23fe movs r3, #254 ; 0xfe + 800e820: 005b lsls r3, r3, #1 + 800e822: 2101 movs r1, #1 + 800e824: 54d1 strb r1, [r2, r3] + pdev->id = id; + 800e826: 68fb ldr r3, [r7, #12] + 800e828: 1dfa adds r2, r7, #7 + 800e82a: 7812 ldrb r2, [r2, #0] + 800e82c: 701a strb r2, [r3, #0] + /* Initialize low level driver */ + USBD_LL_Init(pdev); + 800e82e: 68fb ldr r3, [r7, #12] + 800e830: 0018 movs r0, r3 + 800e832: f7ff fe6b bl 800e50c + + return USBD_OK; + 800e836: 2300 movs r3, #0 +} + 800e838: 0018 movs r0, r3 + 800e83a: 46bd mov sp, r7 + 800e83c: b004 add sp, #16 + 800e83e: bd80 pop {r7, pc} + +0800e840 : + * @param pDevice : Device Handle + * @param pclass: Class handle + * @retval USBD Status + */ +USBD_StatusTypeDef USBD_RegisterClass(USBD_HandleTypeDef *pdev, const USBD_ClassTypeDef *pclass) +{ + 800e840: b580 push {r7, lr} + 800e842: b084 sub sp, #16 + 800e844: af00 add r7, sp, #0 + 800e846: 6078 str r0, [r7, #4] + 800e848: 6039 str r1, [r7, #0] + USBD_StatusTypeDef status = USBD_OK; + 800e84a: 230f movs r3, #15 + 800e84c: 18fb adds r3, r7, r3 + 800e84e: 2200 movs r2, #0 + 800e850: 701a strb r2, [r3, #0] + if(pclass != 0) + 800e852: 683b ldr r3, [r7, #0] + 800e854: 2b00 cmp r3, #0 + 800e856: d009 beq.n 800e86c + { + /* link the class to the USB Device handle */ + pdev->pClass = pclass; + 800e858: 687a ldr r2, [r7, #4] + 800e85a: 2384 movs r3, #132 ; 0x84 + 800e85c: 009b lsls r3, r3, #2 + 800e85e: 6839 ldr r1, [r7, #0] + 800e860: 50d1 str r1, [r2, r3] + status = USBD_OK; + 800e862: 230f movs r3, #15 + 800e864: 18fb adds r3, r7, r3 + 800e866: 2200 movs r2, #0 + 800e868: 701a strb r2, [r3, #0] + 800e86a: e003 b.n 800e874 + } + else + { + USBD_ErrLog("Invalid Class handle"); + status = USBD_FAIL; + 800e86c: 230f movs r3, #15 + 800e86e: 18fb adds r3, r7, r3 + 800e870: 2202 movs r2, #2 + 800e872: 701a strb r2, [r3, #0] + } + + return status; + 800e874: 230f movs r3, #15 + 800e876: 18fb adds r3, r7, r3 + 800e878: 781b ldrb r3, [r3, #0] +} + 800e87a: 0018 movs r0, r3 + 800e87c: 46bd mov sp, r7 + 800e87e: b004 add sp, #16 + 800e880: bd80 pop {r7, pc} + +0800e882 : + * Start the USB Device Core. + * @param pdev: Device Handle + * @retval USBD Status + */ +USBD_StatusTypeDef USBD_Start (USBD_HandleTypeDef *pdev) +{ + 800e882: b580 push {r7, lr} + 800e884: b082 sub sp, #8 + 800e886: af00 add r7, sp, #0 + 800e888: 6078 str r0, [r7, #4] + + /* Start the low level driver */ + USBD_LL_Start(pdev); + 800e88a: 687b ldr r3, [r7, #4] + 800e88c: 0018 movs r0, r3 + 800e88e: f7ff fe89 bl 800e5a4 + + return USBD_OK; + 800e892: 2300 movs r3, #0 +} + 800e894: 0018 movs r0, r3 + 800e896: 46bd mov sp, r7 + 800e898: b002 add sp, #8 + 800e89a: bd80 pop {r7, pc} + +0800e89c : +* @param cfgidx: configuration index +* @retval status +*/ + +USBD_StatusTypeDef USBD_SetClassConfig(USBD_HandleTypeDef *pdev, uint8_t cfgidx) +{ + 800e89c: b580 push {r7, lr} + 800e89e: b084 sub sp, #16 + 800e8a0: af00 add r7, sp, #0 + 800e8a2: 6078 str r0, [r7, #4] + 800e8a4: 000a movs r2, r1 + 800e8a6: 1cfb adds r3, r7, #3 + 800e8a8: 701a strb r2, [r3, #0] + USBD_StatusTypeDef ret = USBD_FAIL; + 800e8aa: 230f movs r3, #15 + 800e8ac: 18fb adds r3, r7, r3 + 800e8ae: 2202 movs r2, #2 + 800e8b0: 701a strb r2, [r3, #0] + + if(pdev->pClass != NULL) + 800e8b2: 687a ldr r2, [r7, #4] + 800e8b4: 2384 movs r3, #132 ; 0x84 + 800e8b6: 009b lsls r3, r3, #2 + 800e8b8: 58d3 ldr r3, [r2, r3] + 800e8ba: 2b00 cmp r3, #0 + 800e8bc: d00f beq.n 800e8de + { + /* Set configuration and Start the Class*/ + if(pdev->pClass->Init(pdev, cfgidx) == 0) + 800e8be: 687a ldr r2, [r7, #4] + 800e8c0: 2384 movs r3, #132 ; 0x84 + 800e8c2: 009b lsls r3, r3, #2 + 800e8c4: 58d3 ldr r3, [r2, r3] + 800e8c6: 681b ldr r3, [r3, #0] + 800e8c8: 1cfa adds r2, r7, #3 + 800e8ca: 7811 ldrb r1, [r2, #0] + 800e8cc: 687a ldr r2, [r7, #4] + 800e8ce: 0010 movs r0, r2 + 800e8d0: 4798 blx r3 + 800e8d2: 1e03 subs r3, r0, #0 + 800e8d4: d103 bne.n 800e8de + { + ret = USBD_OK; + 800e8d6: 230f movs r3, #15 + 800e8d8: 18fb adds r3, r7, r3 + 800e8da: 2200 movs r2, #0 + 800e8dc: 701a strb r2, [r3, #0] + } + } + return ret; + 800e8de: 230f movs r3, #15 + 800e8e0: 18fb adds r3, r7, r3 + 800e8e2: 781b ldrb r3, [r3, #0] +} + 800e8e4: 0018 movs r0, r3 + 800e8e6: 46bd mov sp, r7 + 800e8e8: b004 add sp, #16 + 800e8ea: bd80 pop {r7, pc} + +0800e8ec : +* @param pdev: device instance +* @param cfgidx: configuration index +* @retval status: USBD_StatusTypeDef +*/ +USBD_StatusTypeDef USBD_ClrClassConfig(USBD_HandleTypeDef *pdev, uint8_t cfgidx) +{ + 800e8ec: b580 push {r7, lr} + 800e8ee: b082 sub sp, #8 + 800e8f0: af00 add r7, sp, #0 + 800e8f2: 6078 str r0, [r7, #4] + 800e8f4: 000a movs r2, r1 + 800e8f6: 1cfb adds r3, r7, #3 + 800e8f8: 701a strb r2, [r3, #0] + /* Clear configuration and De-initialize the Class process*/ + pdev->pClass->DeInit(pdev, cfgidx); + 800e8fa: 687a ldr r2, [r7, #4] + 800e8fc: 2384 movs r3, #132 ; 0x84 + 800e8fe: 009b lsls r3, r3, #2 + 800e900: 58d3 ldr r3, [r2, r3] + 800e902: 685b ldr r3, [r3, #4] + 800e904: 1cfa adds r2, r7, #3 + 800e906: 7811 ldrb r1, [r2, #0] + 800e908: 687a ldr r2, [r7, #4] + 800e90a: 0010 movs r0, r2 + 800e90c: 4798 blx r3 + return USBD_OK; + 800e90e: 2300 movs r3, #0 +} + 800e910: 0018 movs r0, r3 + 800e912: 46bd mov sp, r7 + 800e914: b002 add sp, #8 + 800e916: bd80 pop {r7, pc} + +0800e918 : +* Handle the setup stage +* @param pdev: device instance +* @retval status +*/ +USBD_StatusTypeDef USBD_LL_SetupStage(USBD_HandleTypeDef *pdev, uint8_t *psetup) +{ + 800e918: b580 push {r7, lr} + 800e91a: b082 sub sp, #8 + 800e91c: af00 add r7, sp, #0 + 800e91e: 6078 str r0, [r7, #4] + 800e920: 6039 str r1, [r7, #0] + + USBD_ParseSetupRequest(&pdev->request, psetup); + 800e922: 687b ldr r3, [r7, #4] + 800e924: 2281 movs r2, #129 ; 0x81 + 800e926: 0092 lsls r2, r2, #2 + 800e928: 4694 mov ip, r2 + 800e92a: 4463 add r3, ip + 800e92c: 683a ldr r2, [r7, #0] + 800e92e: 0011 movs r1, r2 + 800e930: 0018 movs r0, r3 + 800e932: f000 fd76 bl 800f422 + + pdev->ep0_state = USBD_EP0_SETUP; + 800e936: 687a ldr r2, [r7, #4] + 800e938: 23fa movs r3, #250 ; 0xfa + 800e93a: 005b lsls r3, r3, #1 + 800e93c: 2101 movs r1, #1 + 800e93e: 50d1 str r1, [r2, r3] + pdev->ep0_data_len = pdev->request.wLength; + 800e940: 687b ldr r3, [r7, #4] + 800e942: 4a22 ldr r2, [pc, #136] ; (800e9cc ) + 800e944: 5a9b ldrh r3, [r3, r2] + 800e946: 0019 movs r1, r3 + 800e948: 687a ldr r2, [r7, #4] + 800e94a: 23fc movs r3, #252 ; 0xfc + 800e94c: 005b lsls r3, r3, #1 + 800e94e: 50d1 str r1, [r2, r3] + + switch (pdev->request.bmRequest & 0x1F) + 800e950: 687a ldr r2, [r7, #4] + 800e952: 2381 movs r3, #129 ; 0x81 + 800e954: 009b lsls r3, r3, #2 + 800e956: 5cd3 ldrb r3, [r2, r3] + 800e958: 001a movs r2, r3 + 800e95a: 231f movs r3, #31 + 800e95c: 4013 ands r3, r2 + 800e95e: 2b01 cmp r3, #1 + 800e960: d00d beq.n 800e97e + 800e962: 2b02 cmp r3, #2 + 800e964: d015 beq.n 800e992 + 800e966: 2b00 cmp r3, #0 + 800e968: d11d bne.n 800e9a6 + { + case USB_REQ_RECIPIENT_DEVICE: + USBD_StdDevReq (pdev, &pdev->request); + 800e96a: 687b ldr r3, [r7, #4] + 800e96c: 2281 movs r2, #129 ; 0x81 + 800e96e: 0092 lsls r2, r2, #2 + 800e970: 189a adds r2, r3, r2 + 800e972: 687b ldr r3, [r7, #4] + 800e974: 0011 movs r1, r2 + 800e976: 0018 movs r0, r3 + 800e978: f000 f97c bl 800ec74 + break; + 800e97c: e020 b.n 800e9c0 + + case USB_REQ_RECIPIENT_INTERFACE: + USBD_StdItfReq(pdev, &pdev->request); + 800e97e: 687b ldr r3, [r7, #4] + 800e980: 2281 movs r2, #129 ; 0x81 + 800e982: 0092 lsls r2, r2, #2 + 800e984: 189a adds r2, r3, r2 + 800e986: 687b ldr r3, [r7, #4] + 800e988: 0011 movs r1, r2 + 800e98a: 0018 movs r0, r3 + 800e98c: f000 f9c6 bl 800ed1c + break; + 800e990: e016 b.n 800e9c0 + + case USB_REQ_RECIPIENT_ENDPOINT: + USBD_StdEPReq(pdev, &pdev->request); + 800e992: 687b ldr r3, [r7, #4] + 800e994: 2281 movs r2, #129 ; 0x81 + 800e996: 0092 lsls r2, r2, #2 + 800e998: 189a adds r2, r3, r2 + 800e99a: 687b ldr r3, [r7, #4] + 800e99c: 0011 movs r1, r2 + 800e99e: 0018 movs r0, r3 + 800e9a0: f000 f9fb bl 800ed9a + break; + 800e9a4: e00c b.n 800e9c0 + + default: + USBD_LL_StallEP(pdev , pdev->request.bmRequest & 0x80); + 800e9a6: 687a ldr r2, [r7, #4] + 800e9a8: 2381 movs r3, #129 ; 0x81 + 800e9aa: 009b lsls r3, r3, #2 + 800e9ac: 5cd3 ldrb r3, [r2, r3] + 800e9ae: 227f movs r2, #127 ; 0x7f + 800e9b0: 4393 bics r3, r2 + 800e9b2: b2da uxtb r2, r3 + 800e9b4: 687b ldr r3, [r7, #4] + 800e9b6: 0011 movs r1, r2 + 800e9b8: 0018 movs r0, r3 + 800e9ba: f7ff fe3b bl 800e634 + break; + 800e9be: 46c0 nop ; (mov r8, r8) + } + return USBD_OK; + 800e9c0: 2300 movs r3, #0 +} + 800e9c2: 0018 movs r0, r3 + 800e9c4: 46bd mov sp, r7 + 800e9c6: b002 add sp, #8 + 800e9c8: bd80 pop {r7, pc} + 800e9ca: 46c0 nop ; (mov r8, r8) + 800e9cc: 0000020a .word 0x0000020a + +0800e9d0 : +* @param pdev: device instance +* @param epnum: endpoint index +* @retval status +*/ +USBD_StatusTypeDef USBD_LL_DataOutStage(USBD_HandleTypeDef *pdev , uint8_t epnum, uint8_t *pdata) +{ + 800e9d0: b580 push {r7, lr} + 800e9d2: b086 sub sp, #24 + 800e9d4: af00 add r7, sp, #0 + 800e9d6: 60f8 str r0, [r7, #12] + 800e9d8: 607a str r2, [r7, #4] + 800e9da: 200b movs r0, #11 + 800e9dc: 183b adds r3, r7, r0 + 800e9de: 1c0a adds r2, r1, #0 + 800e9e0: 701a strb r2, [r3, #0] + USBD_EndpointTypeDef *pep; + + if(epnum == 0) + 800e9e2: 183b adds r3, r7, r0 + 800e9e4: 781b ldrb r3, [r3, #0] + 800e9e6: 2b00 cmp r3, #0 + 800e9e8: d13e bne.n 800ea68 + { + pep = &pdev->ep_out[0]; + 800e9ea: 68fb ldr r3, [r7, #12] + 800e9ec: 3305 adds r3, #5 + 800e9ee: 33ff adds r3, #255 ; 0xff + 800e9f0: 617b str r3, [r7, #20] + + if ( pdev->ep0_state == USBD_EP0_DATA_OUT) + 800e9f2: 68fa ldr r2, [r7, #12] + 800e9f4: 23fa movs r3, #250 ; 0xfa + 800e9f6: 005b lsls r3, r3, #1 + 800e9f8: 58d3 ldr r3, [r2, r3] + 800e9fa: 2b03 cmp r3, #3 + 800e9fc: d14c bne.n 800ea98 + { + if(pep->rem_length > pep->maxpacket) + 800e9fe: 697b ldr r3, [r7, #20] + 800ea00: 689a ldr r2, [r3, #8] + 800ea02: 697b ldr r3, [r7, #20] + 800ea04: 68db ldr r3, [r3, #12] + 800ea06: 429a cmp r2, r3 + 800ea08: d914 bls.n 800ea34 + { + pep->rem_length -= pep->maxpacket; + 800ea0a: 697b ldr r3, [r7, #20] + 800ea0c: 689a ldr r2, [r3, #8] + 800ea0e: 697b ldr r3, [r7, #20] + 800ea10: 68db ldr r3, [r3, #12] + 800ea12: 1ad2 subs r2, r2, r3 + 800ea14: 697b ldr r3, [r7, #20] + 800ea16: 609a str r2, [r3, #8] + + USBD_CtlContinueRx (pdev, + pdata, + MIN(pep->rem_length ,pep->maxpacket)); + 800ea18: 697b ldr r3, [r7, #20] + 800ea1a: 68da ldr r2, [r3, #12] + 800ea1c: 697b ldr r3, [r7, #20] + 800ea1e: 689b ldr r3, [r3, #8] + 800ea20: 429a cmp r2, r3 + 800ea22: d900 bls.n 800ea26 + 800ea24: 001a movs r2, r3 + USBD_CtlContinueRx (pdev, + 800ea26: b292 uxth r2, r2 + 800ea28: 6879 ldr r1, [r7, #4] + 800ea2a: 68fb ldr r3, [r7, #12] + 800ea2c: 0018 movs r0, r3 + 800ea2e: f001 f8ca bl 800fbc6 + 800ea32: e031 b.n 800ea98 + } + else + { + if((pdev->pClass->EP0_RxReady != NULL)&& + 800ea34: 68fa ldr r2, [r7, #12] + 800ea36: 2384 movs r3, #132 ; 0x84 + 800ea38: 009b lsls r3, r3, #2 + 800ea3a: 58d3 ldr r3, [r2, r3] + 800ea3c: 691b ldr r3, [r3, #16] + 800ea3e: 2b00 cmp r3, #0 + 800ea40: d00d beq.n 800ea5e + (pdev->dev_state == USBD_STATE_CONFIGURED)) + 800ea42: 68fa ldr r2, [r7, #12] + 800ea44: 23fe movs r3, #254 ; 0xfe + 800ea46: 005b lsls r3, r3, #1 + 800ea48: 5cd3 ldrb r3, [r2, r3] + if((pdev->pClass->EP0_RxReady != NULL)&& + 800ea4a: 2b03 cmp r3, #3 + 800ea4c: d107 bne.n 800ea5e + { + pdev->pClass->EP0_RxReady(pdev); + 800ea4e: 68fa ldr r2, [r7, #12] + 800ea50: 2384 movs r3, #132 ; 0x84 + 800ea52: 009b lsls r3, r3, #2 + 800ea54: 58d3 ldr r3, [r2, r3] + 800ea56: 691b ldr r3, [r3, #16] + 800ea58: 68fa ldr r2, [r7, #12] + 800ea5a: 0010 movs r0, r2 + 800ea5c: 4798 blx r3 + } + USBD_CtlSendStatus(pdev); + 800ea5e: 68fb ldr r3, [r7, #12] + 800ea60: 0018 movs r0, r3 + 800ea62: f001 f8c3 bl 800fbec + 800ea66: e017 b.n 800ea98 + } + } + } + else if((pdev->pClass->DataOut != NULL)&& + 800ea68: 68fa ldr r2, [r7, #12] + 800ea6a: 2384 movs r3, #132 ; 0x84 + 800ea6c: 009b lsls r3, r3, #2 + 800ea6e: 58d3 ldr r3, [r2, r3] + 800ea70: 699b ldr r3, [r3, #24] + 800ea72: 2b00 cmp r3, #0 + 800ea74: d010 beq.n 800ea98 + (pdev->dev_state == USBD_STATE_CONFIGURED)) + 800ea76: 68fa ldr r2, [r7, #12] + 800ea78: 23fe movs r3, #254 ; 0xfe + 800ea7a: 005b lsls r3, r3, #1 + 800ea7c: 5cd3 ldrb r3, [r2, r3] + else if((pdev->pClass->DataOut != NULL)&& + 800ea7e: 2b03 cmp r3, #3 + 800ea80: d10a bne.n 800ea98 + { + pdev->pClass->DataOut(pdev, epnum); + 800ea82: 68fa ldr r2, [r7, #12] + 800ea84: 2384 movs r3, #132 ; 0x84 + 800ea86: 009b lsls r3, r3, #2 + 800ea88: 58d3 ldr r3, [r2, r3] + 800ea8a: 699b ldr r3, [r3, #24] + 800ea8c: 220b movs r2, #11 + 800ea8e: 18ba adds r2, r7, r2 + 800ea90: 7811 ldrb r1, [r2, #0] + 800ea92: 68fa ldr r2, [r7, #12] + 800ea94: 0010 movs r0, r2 + 800ea96: 4798 blx r3 + } + return USBD_OK; + 800ea98: 2300 movs r3, #0 +} + 800ea9a: 0018 movs r0, r3 + 800ea9c: 46bd mov sp, r7 + 800ea9e: b006 add sp, #24 + 800eaa0: bd80 pop {r7, pc} + +0800eaa2 : +* @param pdev: device instance +* @param epnum: endpoint index +* @retval status +*/ +USBD_StatusTypeDef USBD_LL_DataInStage(USBD_HandleTypeDef *pdev ,uint8_t epnum, uint8_t *pdata) +{ + 800eaa2: b580 push {r7, lr} + 800eaa4: b086 sub sp, #24 + 800eaa6: af00 add r7, sp, #0 + 800eaa8: 60f8 str r0, [r7, #12] + 800eaaa: 607a str r2, [r7, #4] + 800eaac: 200b movs r0, #11 + 800eaae: 183b adds r3, r7, r0 + 800eab0: 1c0a adds r2, r1, #0 + 800eab2: 701a strb r2, [r3, #0] + USBD_EndpointTypeDef *pep; + + if(epnum == 0) + 800eab4: 183b adds r3, r7, r0 + 800eab6: 781b ldrb r3, [r3, #0] + 800eab8: 2b00 cmp r3, #0 + 800eaba: d15c bne.n 800eb76 + { + pep = &pdev->ep_in[0]; + 800eabc: 68fb ldr r3, [r7, #12] + 800eabe: 3314 adds r3, #20 + 800eac0: 617b str r3, [r7, #20] + + if ( pdev->ep0_state == USBD_EP0_DATA_IN) + 800eac2: 68fa ldr r2, [r7, #12] + 800eac4: 23fa movs r3, #250 ; 0xfa + 800eac6: 005b lsls r3, r3, #1 + 800eac8: 58d3 ldr r3, [r2, r3] + 800eaca: 2b02 cmp r3, #2 + 800eacc: d16b bne.n 800eba6 + { + if(pep->rem_length > pep->maxpacket) + 800eace: 697b ldr r3, [r7, #20] + 800ead0: 689a ldr r2, [r3, #8] + 800ead2: 697b ldr r3, [r7, #20] + 800ead4: 68db ldr r3, [r3, #12] + 800ead6: 429a cmp r2, r3 + 800ead8: d90f bls.n 800eafa + { + pep->rem_length -= pep->maxpacket; + 800eada: 697b ldr r3, [r7, #20] + 800eadc: 689a ldr r2, [r3, #8] + 800eade: 697b ldr r3, [r7, #20] + 800eae0: 68db ldr r3, [r3, #12] + 800eae2: 1ad2 subs r2, r2, r3 + 800eae4: 697b ldr r3, [r7, #20] + 800eae6: 609a str r2, [r3, #8] + + USBD_CtlContinueSendData (pdev, + pdata, + pep->rem_length); + 800eae8: 697b ldr r3, [r7, #20] + 800eaea: 689b ldr r3, [r3, #8] + USBD_CtlContinueSendData (pdev, + 800eaec: b29a uxth r2, r3 + 800eaee: 6879 ldr r1, [r7, #4] + 800eaf0: 68fb ldr r3, [r7, #12] + 800eaf2: 0018 movs r0, r3 + 800eaf4: f001 f854 bl 800fba0 + 800eaf8: e055 b.n 800eba6 + } + else + { /* last packet is MPS multiple, so send ZLP packet */ + if((pep->total_length % pep->maxpacket == 0) && + 800eafa: 697b ldr r3, [r7, #20] + 800eafc: 685a ldr r2, [r3, #4] + 800eafe: 697b ldr r3, [r7, #20] + 800eb00: 68db ldr r3, [r3, #12] + 800eb02: 0019 movs r1, r3 + 800eb04: 0010 movs r0, r2 + 800eb06: f7f1 fb97 bl 8000238 <__aeabi_uidivmod> + 800eb0a: 1e0b subs r3, r1, #0 + 800eb0c: d119 bne.n 800eb42 + (pep->total_length >= pep->maxpacket) && + 800eb0e: 697b ldr r3, [r7, #20] + 800eb10: 685a ldr r2, [r3, #4] + 800eb12: 697b ldr r3, [r7, #20] + 800eb14: 68db ldr r3, [r3, #12] + if((pep->total_length % pep->maxpacket == 0) && + 800eb16: 429a cmp r2, r3 + 800eb18: d313 bcc.n 800eb42 + (pep->total_length < pdev->ep0_data_len )) + 800eb1a: 697b ldr r3, [r7, #20] + 800eb1c: 685a ldr r2, [r3, #4] + 800eb1e: 68f9 ldr r1, [r7, #12] + 800eb20: 23fc movs r3, #252 ; 0xfc + 800eb22: 005b lsls r3, r3, #1 + 800eb24: 58cb ldr r3, [r1, r3] + (pep->total_length >= pep->maxpacket) && + 800eb26: 429a cmp r2, r3 + 800eb28: d20b bcs.n 800eb42 + { + + USBD_CtlContinueSendData(pdev , NULL, 0); + 800eb2a: 68fb ldr r3, [r7, #12] + 800eb2c: 2200 movs r2, #0 + 800eb2e: 2100 movs r1, #0 + 800eb30: 0018 movs r0, r3 + 800eb32: f001 f835 bl 800fba0 + pdev->ep0_data_len = 0; + 800eb36: 68fa ldr r2, [r7, #12] + 800eb38: 23fc movs r3, #252 ; 0xfc + 800eb3a: 005b lsls r3, r3, #1 + 800eb3c: 2100 movs r1, #0 + 800eb3e: 50d1 str r1, [r2, r3] + 800eb40: e031 b.n 800eba6 + } + else + { + if((pdev->pClass->EP0_TxSent != NULL)&& + 800eb42: 68fa ldr r2, [r7, #12] + 800eb44: 2384 movs r3, #132 ; 0x84 + 800eb46: 009b lsls r3, r3, #2 + 800eb48: 58d3 ldr r3, [r2, r3] + 800eb4a: 68db ldr r3, [r3, #12] + 800eb4c: 2b00 cmp r3, #0 + 800eb4e: d00d beq.n 800eb6c + (pdev->dev_state == USBD_STATE_CONFIGURED)) + 800eb50: 68fa ldr r2, [r7, #12] + 800eb52: 23fe movs r3, #254 ; 0xfe + 800eb54: 005b lsls r3, r3, #1 + 800eb56: 5cd3 ldrb r3, [r2, r3] + if((pdev->pClass->EP0_TxSent != NULL)&& + 800eb58: 2b03 cmp r3, #3 + 800eb5a: d107 bne.n 800eb6c + { + pdev->pClass->EP0_TxSent(pdev); + 800eb5c: 68fa ldr r2, [r7, #12] + 800eb5e: 2384 movs r3, #132 ; 0x84 + 800eb60: 009b lsls r3, r3, #2 + 800eb62: 58d3 ldr r3, [r2, r3] + 800eb64: 68db ldr r3, [r3, #12] + 800eb66: 68fa ldr r2, [r7, #12] + 800eb68: 0010 movs r0, r2 + 800eb6a: 4798 blx r3 + } + USBD_CtlReceiveStatus(pdev); + 800eb6c: 68fb ldr r3, [r7, #12] + 800eb6e: 0018 movs r0, r3 + 800eb70: f001 f850 bl 800fc14 + 800eb74: e017 b.n 800eba6 + } + } + } + } + else if((pdev->pClass->DataIn != NULL)&& + 800eb76: 68fa ldr r2, [r7, #12] + 800eb78: 2384 movs r3, #132 ; 0x84 + 800eb7a: 009b lsls r3, r3, #2 + 800eb7c: 58d3 ldr r3, [r2, r3] + 800eb7e: 695b ldr r3, [r3, #20] + 800eb80: 2b00 cmp r3, #0 + 800eb82: d010 beq.n 800eba6 + (pdev->dev_state == USBD_STATE_CONFIGURED)) + 800eb84: 68fa ldr r2, [r7, #12] + 800eb86: 23fe movs r3, #254 ; 0xfe + 800eb88: 005b lsls r3, r3, #1 + 800eb8a: 5cd3 ldrb r3, [r2, r3] + else if((pdev->pClass->DataIn != NULL)&& + 800eb8c: 2b03 cmp r3, #3 + 800eb8e: d10a bne.n 800eba6 + { + pdev->pClass->DataIn(pdev, epnum); + 800eb90: 68fa ldr r2, [r7, #12] + 800eb92: 2384 movs r3, #132 ; 0x84 + 800eb94: 009b lsls r3, r3, #2 + 800eb96: 58d3 ldr r3, [r2, r3] + 800eb98: 695b ldr r3, [r3, #20] + 800eb9a: 220b movs r2, #11 + 800eb9c: 18ba adds r2, r7, r2 + 800eb9e: 7811 ldrb r1, [r2, #0] + 800eba0: 68fa ldr r2, [r7, #12] + 800eba2: 0010 movs r0, r2 + 800eba4: 4798 blx r3 + } + return USBD_OK; + 800eba6: 2300 movs r3, #0 +} + 800eba8: 0018 movs r0, r3 + 800ebaa: 46bd mov sp, r7 + 800ebac: b006 add sp, #24 + 800ebae: bd80 pop {r7, pc} + +0800ebb0 : +* @param pdev: device instance +* @retval status +*/ + +USBD_StatusTypeDef USBD_LL_Reset(USBD_HandleTypeDef *pdev) +{ + 800ebb0: b580 push {r7, lr} + 800ebb2: b082 sub sp, #8 + 800ebb4: af00 add r7, sp, #0 + 800ebb6: 6078 str r0, [r7, #4] + /* Open EP0 OUT */ + USBD_LL_OpenEP(pdev, + 800ebb8: 6878 ldr r0, [r7, #4] + 800ebba: 2340 movs r3, #64 ; 0x40 + 800ebbc: 2200 movs r2, #0 + 800ebbe: 2100 movs r1, #0 + 800ebc0: f7ff fd00 bl 800e5c4 + 0x00, + USBD_EP_TYPE_CTRL, + USB_MAX_EP0_SIZE); + + pdev->ep_out[0].maxpacket = USB_MAX_EP0_SIZE; + 800ebc4: 687a ldr r2, [r7, #4] + 800ebc6: 2388 movs r3, #136 ; 0x88 + 800ebc8: 005b lsls r3, r3, #1 + 800ebca: 2140 movs r1, #64 ; 0x40 + 800ebcc: 50d1 str r1, [r2, r3] + + /* Open EP0 IN */ + USBD_LL_OpenEP(pdev, + 800ebce: 6878 ldr r0, [r7, #4] + 800ebd0: 2340 movs r3, #64 ; 0x40 + 800ebd2: 2200 movs r2, #0 + 800ebd4: 2180 movs r1, #128 ; 0x80 + 800ebd6: f7ff fcf5 bl 800e5c4 + 0x80, + USBD_EP_TYPE_CTRL, + USB_MAX_EP0_SIZE); + + pdev->ep_in[0].maxpacket = USB_MAX_EP0_SIZE; + 800ebda: 687b ldr r3, [r7, #4] + 800ebdc: 2240 movs r2, #64 ; 0x40 + 800ebde: 621a str r2, [r3, #32] + /* Upon Reset call user call back */ + pdev->dev_state = USBD_STATE_DEFAULT; + 800ebe0: 687a ldr r2, [r7, #4] + 800ebe2: 23fe movs r3, #254 ; 0xfe + 800ebe4: 005b lsls r3, r3, #1 + 800ebe6: 2101 movs r1, #1 + 800ebe8: 54d1 strb r1, [r2, r3] + + if (pdev->pClassData) + 800ebea: 687a ldr r2, [r7, #4] + 800ebec: 2385 movs r3, #133 ; 0x85 + 800ebee: 009b lsls r3, r3, #2 + 800ebf0: 58d3 ldr r3, [r2, r3] + 800ebf2: 2b00 cmp r3, #0 + 800ebf4: d00a beq.n 800ec0c + pdev->pClass->DeInit(pdev, pdev->dev_config); + 800ebf6: 687a ldr r2, [r7, #4] + 800ebf8: 2384 movs r3, #132 ; 0x84 + 800ebfa: 009b lsls r3, r3, #2 + 800ebfc: 58d3 ldr r3, [r2, r3] + 800ebfe: 685a ldr r2, [r3, #4] + 800ec00: 687b ldr r3, [r7, #4] + 800ec02: 685b ldr r3, [r3, #4] + 800ec04: b2d9 uxtb r1, r3 + 800ec06: 687b ldr r3, [r7, #4] + 800ec08: 0018 movs r0, r3 + 800ec0a: 4790 blx r2 + + + return USBD_OK; + 800ec0c: 2300 movs r3, #0 +} + 800ec0e: 0018 movs r0, r3 + 800ec10: 46bd mov sp, r7 + 800ec12: b002 add sp, #8 + 800ec14: bd80 pop {r7, pc} + +0800ec16 : +* Handle Reset event +* @param pdev: device instance +* @retval status +*/ +USBD_StatusTypeDef USBD_LL_SetSpeed(USBD_HandleTypeDef *pdev, USBD_SpeedTypeDef speed) +{ + 800ec16: b580 push {r7, lr} + 800ec18: b082 sub sp, #8 + 800ec1a: af00 add r7, sp, #0 + 800ec1c: 6078 str r0, [r7, #4] + 800ec1e: 000a movs r2, r1 + 800ec20: 1cfb adds r3, r7, #3 + 800ec22: 701a strb r2, [r3, #0] + pdev->dev_speed = speed; + 800ec24: 687b ldr r3, [r7, #4] + 800ec26: 1cfa adds r2, r7, #3 + 800ec28: 7812 ldrb r2, [r2, #0] + 800ec2a: 741a strb r2, [r3, #16] + return USBD_OK; + 800ec2c: 2300 movs r3, #0 +} + 800ec2e: 0018 movs r0, r3 + 800ec30: 46bd mov sp, r7 + 800ec32: b002 add sp, #8 + 800ec34: bd80 pop {r7, pc} + +0800ec36 : +* @param pdev: device instance +* @retval status +*/ + +USBD_StatusTypeDef USBD_LL_SOF(USBD_HandleTypeDef *pdev) +{ + 800ec36: b580 push {r7, lr} + 800ec38: b082 sub sp, #8 + 800ec3a: af00 add r7, sp, #0 + 800ec3c: 6078 str r0, [r7, #4] + if(pdev->dev_state == USBD_STATE_CONFIGURED) + 800ec3e: 687a ldr r2, [r7, #4] + 800ec40: 23fe movs r3, #254 ; 0xfe + 800ec42: 005b lsls r3, r3, #1 + 800ec44: 5cd3 ldrb r3, [r2, r3] + 800ec46: 2b03 cmp r3, #3 + 800ec48: d10e bne.n 800ec68 + { + if(pdev->pClass->SOF != NULL) + 800ec4a: 687a ldr r2, [r7, #4] + 800ec4c: 2384 movs r3, #132 ; 0x84 + 800ec4e: 009b lsls r3, r3, #2 + 800ec50: 58d3 ldr r3, [r2, r3] + 800ec52: 69db ldr r3, [r3, #28] + 800ec54: 2b00 cmp r3, #0 + 800ec56: d007 beq.n 800ec68 + { + pdev->pClass->SOF(pdev); + 800ec58: 687a ldr r2, [r7, #4] + 800ec5a: 2384 movs r3, #132 ; 0x84 + 800ec5c: 009b lsls r3, r3, #2 + 800ec5e: 58d3 ldr r3, [r2, r3] + 800ec60: 69db ldr r3, [r3, #28] + 800ec62: 687a ldr r2, [r7, #4] + 800ec64: 0010 movs r0, r2 + 800ec66: 4798 blx r3 + } + } + return USBD_OK; + 800ec68: 2300 movs r3, #0 +} + 800ec6a: 0018 movs r0, r3 + 800ec6c: 46bd mov sp, r7 + 800ec6e: b002 add sp, #8 + 800ec70: bd80 pop {r7, pc} + ... + +0800ec74 : +* @param pdev: device instance +* @param req: usb request +* @retval status +*/ +USBD_StatusTypeDef USBD_StdDevReq (USBD_HandleTypeDef *pdev , USBD_SetupReqTypedef *req) +{ + 800ec74: b580 push {r7, lr} + 800ec76: b084 sub sp, #16 + 800ec78: af00 add r7, sp, #0 + 800ec7a: 6078 str r0, [r7, #4] + 800ec7c: 6039 str r1, [r7, #0] + USBD_StatusTypeDef ret = USBD_OK; + 800ec7e: 230f movs r3, #15 + 800ec80: 18fb adds r3, r7, r3 + 800ec82: 2200 movs r2, #0 + 800ec84: 701a strb r2, [r3, #0] + + switch (req->bRequest) + 800ec86: 683b ldr r3, [r7, #0] + 800ec88: 785b ldrb r3, [r3, #1] + 800ec8a: 2b09 cmp r3, #9 + 800ec8c: d835 bhi.n 800ecfa + 800ec8e: 009a lsls r2, r3, #2 + 800ec90: 4b21 ldr r3, [pc, #132] ; (800ed18 ) + 800ec92: 18d3 adds r3, r2, r3 + 800ec94: 681b ldr r3, [r3, #0] + 800ec96: 469f mov pc, r3 + { + case USB_REQ_GET_DESCRIPTOR: + + USBD_GetDescriptor (pdev, req) ; + 800ec98: 683a ldr r2, [r7, #0] + 800ec9a: 687b ldr r3, [r7, #4] + 800ec9c: 0011 movs r1, r2 + 800ec9e: 0018 movs r0, r3 + 800eca0: f000 f97f bl 800efa2 + break; + 800eca4: e030 b.n 800ed08 + + case USB_REQ_SET_ADDRESS: + USBD_SetAddress(pdev, req); + 800eca6: 683a ldr r2, [r7, #0] + 800eca8: 687b ldr r3, [r7, #4] + 800ecaa: 0011 movs r1, r2 + 800ecac: 0018 movs r0, r3 + 800ecae: f000 fa19 bl 800f0e4 + break; + 800ecb2: e029 b.n 800ed08 + + case USB_REQ_SET_CONFIGURATION: + USBD_SetConfig (pdev , req); + 800ecb4: 683a ldr r2, [r7, #0] + 800ecb6: 687b ldr r3, [r7, #4] + 800ecb8: 0011 movs r1, r2 + 800ecba: 0018 movs r0, r3 + 800ecbc: f000 fa60 bl 800f180 + break; + 800ecc0: e022 b.n 800ed08 + + case USB_REQ_GET_CONFIGURATION: + USBD_GetConfig (pdev , req); + 800ecc2: 683a ldr r2, [r7, #0] + 800ecc4: 687b ldr r3, [r7, #4] + 800ecc6: 0011 movs r1, r2 + 800ecc8: 0018 movs r0, r3 + 800ecca: f000 faf5 bl 800f2b8 + break; + 800ecce: e01b b.n 800ed08 + + case USB_REQ_GET_STATUS: + USBD_GetStatus (pdev , req); + 800ecd0: 683a ldr r2, [r7, #0] + 800ecd2: 687b ldr r3, [r7, #4] + 800ecd4: 0011 movs r1, r2 + 800ecd6: 0018 movs r0, r3 + 800ecd8: f000 fb26 bl 800f328 + break; + 800ecdc: e014 b.n 800ed08 + + + case USB_REQ_SET_FEATURE: + USBD_SetFeature (pdev , req); + 800ecde: 683a ldr r2, [r7, #0] + 800ece0: 687b ldr r3, [r7, #4] + 800ece2: 0011 movs r1, r2 + 800ece4: 0018 movs r0, r3 + 800ece6: f000 fb4e bl 800f386 + break; + 800ecea: e00d b.n 800ed08 + + case USB_REQ_CLEAR_FEATURE: + USBD_ClrFeature (pdev , req); + 800ecec: 683a ldr r2, [r7, #0] + 800ecee: 687b ldr r3, [r7, #4] + 800ecf0: 0011 movs r1, r2 + 800ecf2: 0018 movs r0, r3 + 800ecf4: f000 fb66 bl 800f3c4 + break; + 800ecf8: e006 b.n 800ed08 + + default: + USBD_CtlError(pdev , req); + 800ecfa: 683a ldr r2, [r7, #0] + 800ecfc: 687b ldr r3, [r7, #4] + 800ecfe: 0011 movs r1, r2 + 800ed00: 0018 movs r0, r3 + 800ed02: f000 fbc9 bl 800f498 + break; + 800ed06: 46c0 nop ; (mov r8, r8) + } + + return ret; + 800ed08: 230f movs r3, #15 + 800ed0a: 18fb adds r3, r7, r3 + 800ed0c: 781b ldrb r3, [r3, #0] +} + 800ed0e: 0018 movs r0, r3 + 800ed10: 46bd mov sp, r7 + 800ed12: b004 add sp, #16 + 800ed14: bd80 pop {r7, pc} + 800ed16: 46c0 nop ; (mov r8, r8) + 800ed18: 0800fdd8 .word 0x0800fdd8 + +0800ed1c : +* @param pdev: device instance +* @param req: usb request +* @retval status +*/ +USBD_StatusTypeDef USBD_StdItfReq (USBD_HandleTypeDef *pdev , USBD_SetupReqTypedef *req) +{ + 800ed1c: b580 push {r7, lr} + 800ed1e: b084 sub sp, #16 + 800ed20: af00 add r7, sp, #0 + 800ed22: 6078 str r0, [r7, #4] + 800ed24: 6039 str r1, [r7, #0] + USBD_StatusTypeDef ret = USBD_OK; + 800ed26: 230f movs r3, #15 + 800ed28: 18fb adds r3, r7, r3 + 800ed2a: 2200 movs r2, #0 + 800ed2c: 701a strb r2, [r3, #0] + + switch (pdev->dev_state) + 800ed2e: 687a ldr r2, [r7, #4] + 800ed30: 23fe movs r3, #254 ; 0xfe + 800ed32: 005b lsls r3, r3, #1 + 800ed34: 5cd3 ldrb r3, [r2, r3] + 800ed36: 2b03 cmp r3, #3 + 800ed38: d122 bne.n 800ed80 + { + case USBD_STATE_CONFIGURED: + + if (LOBYTE(req->wIndex) <= USBD_MAX_NUM_INTERFACES) + 800ed3a: 683b ldr r3, [r7, #0] + 800ed3c: 889b ldrh r3, [r3, #4] + 800ed3e: b2db uxtb r3, r3 + 800ed40: 2b02 cmp r3, #2 + 800ed42: d816 bhi.n 800ed72 + { + pdev->pClass->Setup (pdev, req); + 800ed44: 687a ldr r2, [r7, #4] + 800ed46: 2384 movs r3, #132 ; 0x84 + 800ed48: 009b lsls r3, r3, #2 + 800ed4a: 58d3 ldr r3, [r2, r3] + 800ed4c: 689b ldr r3, [r3, #8] + 800ed4e: 6839 ldr r1, [r7, #0] + 800ed50: 687a ldr r2, [r7, #4] + 800ed52: 0010 movs r0, r2 + 800ed54: 4798 blx r3 + + if((req->wLength == 0)&& (ret == USBD_OK)) + 800ed56: 683b ldr r3, [r7, #0] + 800ed58: 88db ldrh r3, [r3, #6] + 800ed5a: 2b00 cmp r3, #0 + 800ed5c: d117 bne.n 800ed8e + 800ed5e: 230f movs r3, #15 + 800ed60: 18fb adds r3, r7, r3 + 800ed62: 781b ldrb r3, [r3, #0] + 800ed64: 2b00 cmp r3, #0 + 800ed66: d112 bne.n 800ed8e + { + USBD_CtlSendStatus(pdev); + 800ed68: 687b ldr r3, [r7, #4] + 800ed6a: 0018 movs r0, r3 + 800ed6c: f000 ff3e bl 800fbec + } + else + { + USBD_CtlError(pdev , req); + } + break; + 800ed70: e00d b.n 800ed8e + USBD_CtlError(pdev , req); + 800ed72: 683a ldr r2, [r7, #0] + 800ed74: 687b ldr r3, [r7, #4] + 800ed76: 0011 movs r1, r2 + 800ed78: 0018 movs r0, r3 + 800ed7a: f000 fb8d bl 800f498 + break; + 800ed7e: e006 b.n 800ed8e + + default: + USBD_CtlError(pdev , req); + 800ed80: 683a ldr r2, [r7, #0] + 800ed82: 687b ldr r3, [r7, #4] + 800ed84: 0011 movs r1, r2 + 800ed86: 0018 movs r0, r3 + 800ed88: f000 fb86 bl 800f498 + break; + 800ed8c: e000 b.n 800ed90 + break; + 800ed8e: 46c0 nop ; (mov r8, r8) + } + return USBD_OK; + 800ed90: 2300 movs r3, #0 +} + 800ed92: 0018 movs r0, r3 + 800ed94: 46bd mov sp, r7 + 800ed96: b004 add sp, #16 + 800ed98: bd80 pop {r7, pc} + +0800ed9a : +* @param pdev: device instance +* @param req: usb request +* @retval status +*/ +USBD_StatusTypeDef USBD_StdEPReq (USBD_HandleTypeDef *pdev , USBD_SetupReqTypedef *req) +{ + 800ed9a: b580 push {r7, lr} + 800ed9c: b084 sub sp, #16 + 800ed9e: af00 add r7, sp, #0 + 800eda0: 6078 str r0, [r7, #4] + 800eda2: 6039 str r1, [r7, #0] + + uint8_t ep_addr; + USBD_StatusTypeDef ret = USBD_OK; + 800eda4: 230f movs r3, #15 + 800eda6: 18fb adds r3, r7, r3 + 800eda8: 2200 movs r2, #0 + 800edaa: 701a strb r2, [r3, #0] + USBD_EndpointTypeDef *pep; + ep_addr = LOBYTE(req->wIndex); + 800edac: 683b ldr r3, [r7, #0] + 800edae: 889a ldrh r2, [r3, #4] + 800edb0: 230e movs r3, #14 + 800edb2: 18fb adds r3, r7, r3 + 800edb4: 701a strb r2, [r3, #0] + + switch (req->bRequest) + 800edb6: 683b ldr r3, [r7, #0] + 800edb8: 785b ldrb r3, [r3, #1] + 800edba: 2b01 cmp r3, #1 + 800edbc: d04e beq.n 800ee5c + 800edbe: 2b03 cmp r3, #3 + 800edc0: d003 beq.n 800edca + 800edc2: 2b00 cmp r3, #0 + 800edc4: d100 bne.n 800edc8 + 800edc6: e090 b.n 800eeea + break; + } + break; + + default: + break; + 800edc8: e0e4 b.n 800ef94 + switch (pdev->dev_state) + 800edca: 687a ldr r2, [r7, #4] + 800edcc: 23fe movs r3, #254 ; 0xfe + 800edce: 005b lsls r3, r3, #1 + 800edd0: 5cd3 ldrb r3, [r2, r3] + 800edd2: 2b02 cmp r3, #2 + 800edd4: d002 beq.n 800eddc + 800edd6: 2b03 cmp r3, #3 + 800edd8: d013 beq.n 800ee02 + 800edda: e036 b.n 800ee4a + if ((ep_addr != 0x00) && (ep_addr != 0x80)) + 800eddc: 230e movs r3, #14 + 800edde: 18fb adds r3, r7, r3 + 800ede0: 781b ldrb r3, [r3, #0] + 800ede2: 2b00 cmp r3, #0 + 800ede4: d038 beq.n 800ee58 + 800ede6: 230e movs r3, #14 + 800ede8: 18fb adds r3, r7, r3 + 800edea: 781b ldrb r3, [r3, #0] + 800edec: 2b80 cmp r3, #128 ; 0x80 + 800edee: d033 beq.n 800ee58 + USBD_LL_StallEP(pdev , ep_addr); + 800edf0: 230e movs r3, #14 + 800edf2: 18fb adds r3, r7, r3 + 800edf4: 781a ldrb r2, [r3, #0] + 800edf6: 687b ldr r3, [r7, #4] + 800edf8: 0011 movs r1, r2 + 800edfa: 0018 movs r0, r3 + 800edfc: f7ff fc1a bl 800e634 + break; + 800ee00: e02a b.n 800ee58 + if (req->wValue == USB_FEATURE_EP_HALT) + 800ee02: 683b ldr r3, [r7, #0] + 800ee04: 885b ldrh r3, [r3, #2] + 800ee06: 2b00 cmp r3, #0 + 800ee08: d111 bne.n 800ee2e + if ((ep_addr != 0x00) && (ep_addr != 0x80)) + 800ee0a: 230e movs r3, #14 + 800ee0c: 18fb adds r3, r7, r3 + 800ee0e: 781b ldrb r3, [r3, #0] + 800ee10: 2b00 cmp r3, #0 + 800ee12: d00c beq.n 800ee2e + 800ee14: 230e movs r3, #14 + 800ee16: 18fb adds r3, r7, r3 + 800ee18: 781b ldrb r3, [r3, #0] + 800ee1a: 2b80 cmp r3, #128 ; 0x80 + 800ee1c: d007 beq.n 800ee2e + USBD_LL_StallEP(pdev , ep_addr); + 800ee1e: 230e movs r3, #14 + 800ee20: 18fb adds r3, r7, r3 + 800ee22: 781a ldrb r2, [r3, #0] + 800ee24: 687b ldr r3, [r7, #4] + 800ee26: 0011 movs r1, r2 + 800ee28: 0018 movs r0, r3 + 800ee2a: f7ff fc03 bl 800e634 + pdev->pClass->Setup (pdev, req); + 800ee2e: 687a ldr r2, [r7, #4] + 800ee30: 2384 movs r3, #132 ; 0x84 + 800ee32: 009b lsls r3, r3, #2 + 800ee34: 58d3 ldr r3, [r2, r3] + 800ee36: 689b ldr r3, [r3, #8] + 800ee38: 6839 ldr r1, [r7, #0] + 800ee3a: 687a ldr r2, [r7, #4] + 800ee3c: 0010 movs r0, r2 + 800ee3e: 4798 blx r3 + USBD_CtlSendStatus(pdev); + 800ee40: 687b ldr r3, [r7, #4] + 800ee42: 0018 movs r0, r3 + 800ee44: f000 fed2 bl 800fbec + break; + 800ee48: e007 b.n 800ee5a + USBD_CtlError(pdev , req); + 800ee4a: 683a ldr r2, [r7, #0] + 800ee4c: 687b ldr r3, [r7, #4] + 800ee4e: 0011 movs r1, r2 + 800ee50: 0018 movs r0, r3 + 800ee52: f000 fb21 bl 800f498 + break; + 800ee56: e000 b.n 800ee5a + break; + 800ee58: 46c0 nop ; (mov r8, r8) + break; + 800ee5a: e09b b.n 800ef94 + switch (pdev->dev_state) + 800ee5c: 687a ldr r2, [r7, #4] + 800ee5e: 23fe movs r3, #254 ; 0xfe + 800ee60: 005b lsls r3, r3, #1 + 800ee62: 5cd3 ldrb r3, [r2, r3] + 800ee64: 2b02 cmp r3, #2 + 800ee66: d002 beq.n 800ee6e + 800ee68: 2b03 cmp r3, #3 + 800ee6a: d013 beq.n 800ee94 + 800ee6c: e032 b.n 800eed4 + if ((ep_addr != 0x00) && (ep_addr != 0x80)) + 800ee6e: 230e movs r3, #14 + 800ee70: 18fb adds r3, r7, r3 + 800ee72: 781b ldrb r3, [r3, #0] + 800ee74: 2b00 cmp r3, #0 + 800ee76: d034 beq.n 800eee2 + 800ee78: 230e movs r3, #14 + 800ee7a: 18fb adds r3, r7, r3 + 800ee7c: 781b ldrb r3, [r3, #0] + 800ee7e: 2b80 cmp r3, #128 ; 0x80 + 800ee80: d02f beq.n 800eee2 + USBD_LL_StallEP(pdev , ep_addr); + 800ee82: 230e movs r3, #14 + 800ee84: 18fb adds r3, r7, r3 + 800ee86: 781a ldrb r2, [r3, #0] + 800ee88: 687b ldr r3, [r7, #4] + 800ee8a: 0011 movs r1, r2 + 800ee8c: 0018 movs r0, r3 + 800ee8e: f7ff fbd1 bl 800e634 + break; + 800ee92: e026 b.n 800eee2 + if (req->wValue == USB_FEATURE_EP_HALT) + 800ee94: 683b ldr r3, [r7, #0] + 800ee96: 885b ldrh r3, [r3, #2] + 800ee98: 2b00 cmp r3, #0 + 800ee9a: d124 bne.n 800eee6 + if ((ep_addr & 0x7F) != 0x00) + 800ee9c: 230e movs r3, #14 + 800ee9e: 18fb adds r3, r7, r3 + 800eea0: 781b ldrb r3, [r3, #0] + 800eea2: 227f movs r2, #127 ; 0x7f + 800eea4: 4013 ands r3, r2 + 800eea6: d010 beq.n 800eeca + USBD_LL_ClearStallEP(pdev , ep_addr); + 800eea8: 230e movs r3, #14 + 800eeaa: 18fb adds r3, r7, r3 + 800eeac: 781a ldrb r2, [r3, #0] + 800eeae: 687b ldr r3, [r7, #4] + 800eeb0: 0011 movs r1, r2 + 800eeb2: 0018 movs r0, r3 + 800eeb4: f7ff fbd4 bl 800e660 + pdev->pClass->Setup (pdev, req); + 800eeb8: 687a ldr r2, [r7, #4] + 800eeba: 2384 movs r3, #132 ; 0x84 + 800eebc: 009b lsls r3, r3, #2 + 800eebe: 58d3 ldr r3, [r2, r3] + 800eec0: 689b ldr r3, [r3, #8] + 800eec2: 6839 ldr r1, [r7, #0] + 800eec4: 687a ldr r2, [r7, #4] + 800eec6: 0010 movs r0, r2 + 800eec8: 4798 blx r3 + USBD_CtlSendStatus(pdev); + 800eeca: 687b ldr r3, [r7, #4] + 800eecc: 0018 movs r0, r3 + 800eece: f000 fe8d bl 800fbec + break; + 800eed2: e008 b.n 800eee6 + USBD_CtlError(pdev , req); + 800eed4: 683a ldr r2, [r7, #0] + 800eed6: 687b ldr r3, [r7, #4] + 800eed8: 0011 movs r1, r2 + 800eeda: 0018 movs r0, r3 + 800eedc: f000 fadc bl 800f498 + break; + 800eee0: e002 b.n 800eee8 + break; + 800eee2: 46c0 nop ; (mov r8, r8) + 800eee4: e056 b.n 800ef94 + break; + 800eee6: 46c0 nop ; (mov r8, r8) + break; + 800eee8: e054 b.n 800ef94 + switch (pdev->dev_state) + 800eeea: 687a ldr r2, [r7, #4] + 800eeec: 23fe movs r3, #254 ; 0xfe + 800eeee: 005b lsls r3, r3, #1 + 800eef0: 5cd3 ldrb r3, [r2, r3] + 800eef2: 2b02 cmp r3, #2 + 800eef4: d002 beq.n 800eefc + 800eef6: 2b03 cmp r3, #3 + 800eef8: d00f beq.n 800ef1a + 800eefa: e042 b.n 800ef82 + if ((ep_addr & 0x7F) != 0x00) + 800eefc: 230e movs r3, #14 + 800eefe: 18fb adds r3, r7, r3 + 800ef00: 781b ldrb r3, [r3, #0] + 800ef02: 227f movs r2, #127 ; 0x7f + 800ef04: 4013 ands r3, r2 + 800ef06: d043 beq.n 800ef90 + USBD_LL_StallEP(pdev , ep_addr); + 800ef08: 230e movs r3, #14 + 800ef0a: 18fb adds r3, r7, r3 + 800ef0c: 781a ldrb r2, [r3, #0] + 800ef0e: 687b ldr r3, [r7, #4] + 800ef10: 0011 movs r1, r2 + 800ef12: 0018 movs r0, r3 + 800ef14: f7ff fb8e bl 800e634 + break; + 800ef18: e03a b.n 800ef90 + pep = ((ep_addr & 0x80) == 0x80) ? &pdev->ep_in[ep_addr & 0x7F]:\ + 800ef1a: 230e movs r3, #14 + 800ef1c: 18fb adds r3, r7, r3 + 800ef1e: 781b ldrb r3, [r3, #0] + 800ef20: b25b sxtb r3, r3 + 800ef22: 2b00 cmp r3, #0 + 800ef24: da0a bge.n 800ef3c + 800ef26: 230e movs r3, #14 + 800ef28: 18fb adds r3, r7, r3 + 800ef2a: 781b ldrb r3, [r3, #0] + 800ef2c: 227f movs r2, #127 ; 0x7f + 800ef2e: 4013 ands r3, r2 + 800ef30: 3301 adds r3, #1 + 800ef32: 011b lsls r3, r3, #4 + 800ef34: 687a ldr r2, [r7, #4] + 800ef36: 18d3 adds r3, r2, r3 + 800ef38: 3304 adds r3, #4 + 800ef3a: e009 b.n 800ef50 + &pdev->ep_out[ep_addr & 0x7F]; + 800ef3c: 230e movs r3, #14 + 800ef3e: 18fb adds r3, r7, r3 + 800ef40: 781b ldrb r3, [r3, #0] + 800ef42: 227f movs r2, #127 ; 0x7f + 800ef44: 4013 ands r3, r2 + pep = ((ep_addr & 0x80) == 0x80) ? &pdev->ep_in[ep_addr & 0x7F]:\ + 800ef46: 3310 adds r3, #16 + 800ef48: 011b lsls r3, r3, #4 + 800ef4a: 687a ldr r2, [r7, #4] + 800ef4c: 18d3 adds r3, r2, r3 + 800ef4e: 3304 adds r3, #4 + 800ef50: 60bb str r3, [r7, #8] + if(USBD_LL_IsStallEP(pdev, ep_addr)) + 800ef52: 230e movs r3, #14 + 800ef54: 18fb adds r3, r7, r3 + 800ef56: 781a ldrb r2, [r3, #0] + 800ef58: 687b ldr r3, [r7, #4] + 800ef5a: 0011 movs r1, r2 + 800ef5c: 0018 movs r0, r3 + 800ef5e: f7ff fb95 bl 800e68c + 800ef62: 1e03 subs r3, r0, #0 + 800ef64: d003 beq.n 800ef6e + pep->status = 0x0001; + 800ef66: 68bb ldr r3, [r7, #8] + 800ef68: 2201 movs r2, #1 + 800ef6a: 601a str r2, [r3, #0] + 800ef6c: e002 b.n 800ef74 + pep->status = 0x0000; + 800ef6e: 68bb ldr r3, [r7, #8] + 800ef70: 2200 movs r2, #0 + 800ef72: 601a str r2, [r3, #0] + (uint8_t *)&pep->status, + 800ef74: 68b9 ldr r1, [r7, #8] + USBD_CtlSendData (pdev, + 800ef76: 687b ldr r3, [r7, #4] + 800ef78: 2202 movs r2, #2 + 800ef7a: 0018 movs r0, r3 + 800ef7c: f000 fdf0 bl 800fb60 + break; + 800ef80: e007 b.n 800ef92 + USBD_CtlError(pdev , req); + 800ef82: 683a ldr r2, [r7, #0] + 800ef84: 687b ldr r3, [r7, #4] + 800ef86: 0011 movs r1, r2 + 800ef88: 0018 movs r0, r3 + 800ef8a: f000 fa85 bl 800f498 + break; + 800ef8e: e000 b.n 800ef92 + break; + 800ef90: 46c0 nop ; (mov r8, r8) + break; + 800ef92: 46c0 nop ; (mov r8, r8) + } + return ret; + 800ef94: 230f movs r3, #15 + 800ef96: 18fb adds r3, r7, r3 + 800ef98: 781b ldrb r3, [r3, #0] +} + 800ef9a: 0018 movs r0, r3 + 800ef9c: 46bd mov sp, r7 + 800ef9e: b004 add sp, #16 + 800efa0: bd80 pop {r7, pc} + +0800efa2 : +* @param req: usb request +* @retval status +*/ +static void USBD_GetDescriptor(USBD_HandleTypeDef *pdev , + USBD_SetupReqTypedef *req) +{ + 800efa2: b580 push {r7, lr} + 800efa4: b084 sub sp, #16 + 800efa6: af00 add r7, sp, #0 + 800efa8: 6078 str r0, [r7, #4] + 800efaa: 6039 str r1, [r7, #0] + uint16_t len; + uint8_t *pbuf; + + + switch (req->wValue >> 8) + 800efac: 683b ldr r3, [r7, #0] + 800efae: 885b ldrh r3, [r3, #2] + 800efb0: 0a1b lsrs r3, r3, #8 + 800efb2: b29b uxth r3, r3 + 800efb4: 2b02 cmp r3, #2 + 800efb6: d011 beq.n 800efdc + 800efb8: 2b03 cmp r3, #3 + 800efba: d01b beq.n 800eff4 + 800efbc: 2b01 cmp r3, #1 + 800efbe: d167 bne.n 800f090 + { + case USB_DESC_TYPE_DEVICE: + pbuf = pdev->pDesc->GetDeviceDescriptor(pdev->dev_speed, &len); + 800efc0: 687a ldr r2, [r7, #4] + 800efc2: 2383 movs r3, #131 ; 0x83 + 800efc4: 009b lsls r3, r3, #2 + 800efc6: 58d3 ldr r3, [r2, r3] + 800efc8: 681b ldr r3, [r3, #0] + 800efca: 687a ldr r2, [r7, #4] + 800efcc: 7c12 ldrb r2, [r2, #16] + 800efce: 210a movs r1, #10 + 800efd0: 1879 adds r1, r7, r1 + 800efd2: 0010 movs r0, r2 + 800efd4: 4798 blx r3 + 800efd6: 0003 movs r3, r0 + 800efd8: 60fb str r3, [r7, #12] + break; + 800efda: e060 b.n 800f09e + + case USB_DESC_TYPE_CONFIGURATION: + pbuf = (uint8_t *)pdev->pClass->GetFSConfigDescriptor(&len); + 800efdc: 687a ldr r2, [r7, #4] + 800efde: 2384 movs r3, #132 ; 0x84 + 800efe0: 009b lsls r3, r3, #2 + 800efe2: 58d3 ldr r3, [r2, r3] + 800efe4: 6a9b ldr r3, [r3, #40] ; 0x28 + 800efe6: 220a movs r2, #10 + 800efe8: 18ba adds r2, r7, r2 + 800efea: 0010 movs r0, r2 + 800efec: 4798 blx r3 + 800efee: 0003 movs r3, r0 + 800eff0: 60fb str r3, [r7, #12] + break; + 800eff2: e054 b.n 800f09e + + case USB_DESC_TYPE_STRING: + switch ((uint8_t)(req->wValue)) + 800eff4: 683b ldr r3, [r7, #0] + 800eff6: 885b ldrh r3, [r3, #2] + 800eff8: b2db uxtb r3, r3 + 800effa: 2b01 cmp r3, #1 + 800effc: d016 beq.n 800f02c + 800effe: dc02 bgt.n 800f006 + 800f000: 2b00 cmp r3, #0 + 800f002: d005 beq.n 800f010 + 800f004: e03c b.n 800f080 + 800f006: 2b02 cmp r3, #2 + 800f008: d01e beq.n 800f048 + 800f00a: 2b03 cmp r3, #3 + 800f00c: d02a beq.n 800f064 + 800f00e: e037 b.n 800f080 + { + case USBD_IDX_LANGID_STR: + pbuf = pdev->pDesc->GetLangIDStrDescriptor(pdev->dev_speed, &len); + 800f010: 687a ldr r2, [r7, #4] + 800f012: 2383 movs r3, #131 ; 0x83 + 800f014: 009b lsls r3, r3, #2 + 800f016: 58d3 ldr r3, [r2, r3] + 800f018: 685b ldr r3, [r3, #4] + 800f01a: 687a ldr r2, [r7, #4] + 800f01c: 7c12 ldrb r2, [r2, #16] + 800f01e: 210a movs r1, #10 + 800f020: 1879 adds r1, r7, r1 + 800f022: 0010 movs r0, r2 + 800f024: 4798 blx r3 + 800f026: 0003 movs r3, r0 + 800f028: 60fb str r3, [r7, #12] + break; + 800f02a: e030 b.n 800f08e + + case USBD_IDX_MFC_STR: + pbuf = pdev->pDesc->GetManufacturerStrDescriptor(pdev->dev_speed, &len); + 800f02c: 687a ldr r2, [r7, #4] + 800f02e: 2383 movs r3, #131 ; 0x83 + 800f030: 009b lsls r3, r3, #2 + 800f032: 58d3 ldr r3, [r2, r3] + 800f034: 689b ldr r3, [r3, #8] + 800f036: 687a ldr r2, [r7, #4] + 800f038: 7c12 ldrb r2, [r2, #16] + 800f03a: 210a movs r1, #10 + 800f03c: 1879 adds r1, r7, r1 + 800f03e: 0010 movs r0, r2 + 800f040: 4798 blx r3 + 800f042: 0003 movs r3, r0 + 800f044: 60fb str r3, [r7, #12] + break; + 800f046: e022 b.n 800f08e + + case USBD_IDX_PRODUCT_STR: + pbuf = pdev->pDesc->GetProductStrDescriptor(pdev->dev_speed, &len); + 800f048: 687a ldr r2, [r7, #4] + 800f04a: 2383 movs r3, #131 ; 0x83 + 800f04c: 009b lsls r3, r3, #2 + 800f04e: 58d3 ldr r3, [r2, r3] + 800f050: 68db ldr r3, [r3, #12] + 800f052: 687a ldr r2, [r7, #4] + 800f054: 7c12 ldrb r2, [r2, #16] + 800f056: 210a movs r1, #10 + 800f058: 1879 adds r1, r7, r1 + 800f05a: 0010 movs r0, r2 + 800f05c: 4798 blx r3 + 800f05e: 0003 movs r3, r0 + 800f060: 60fb str r3, [r7, #12] + break; + 800f062: e014 b.n 800f08e + + case USBD_IDX_SERIAL_STR: + pbuf = pdev->pDesc->GetSerialStrDescriptor(pdev->dev_speed, &len); + 800f064: 687a ldr r2, [r7, #4] + 800f066: 2383 movs r3, #131 ; 0x83 + 800f068: 009b lsls r3, r3, #2 + 800f06a: 58d3 ldr r3, [r2, r3] + 800f06c: 691b ldr r3, [r3, #16] + 800f06e: 687a ldr r2, [r7, #4] + 800f070: 7c12 ldrb r2, [r2, #16] + 800f072: 210a movs r1, #10 + 800f074: 1879 adds r1, r7, r1 + 800f076: 0010 movs r0, r2 + 800f078: 4798 blx r3 + 800f07a: 0003 movs r3, r0 + 800f07c: 60fb str r3, [r7, #12] + break; + 800f07e: e006 b.n 800f08e + + default: + USBD_CtlError(pdev , req); + 800f080: 683a ldr r2, [r7, #0] + 800f082: 687b ldr r3, [r7, #4] + 800f084: 0011 movs r1, r2 + 800f086: 0018 movs r0, r3 + 800f088: f000 fa06 bl 800f498 + return; + 800f08c: e027 b.n 800f0de + } + break; + 800f08e: e006 b.n 800f09e + + default: + USBD_CtlError(pdev , req); + 800f090: 683a ldr r2, [r7, #0] + 800f092: 687b ldr r3, [r7, #4] + 800f094: 0011 movs r1, r2 + 800f096: 0018 movs r0, r3 + 800f098: f000 f9fe bl 800f498 + return; + 800f09c: e01f b.n 800f0de + } + + if((len != 0)&& (req->wLength != 0)) + 800f09e: 230a movs r3, #10 + 800f0a0: 18fb adds r3, r7, r3 + 800f0a2: 881b ldrh r3, [r3, #0] + 800f0a4: 2b00 cmp r3, #0 + 800f0a6: d01a beq.n 800f0de + 800f0a8: 683b ldr r3, [r7, #0] + 800f0aa: 88db ldrh r3, [r3, #6] + 800f0ac: 2b00 cmp r3, #0 + 800f0ae: d016 beq.n 800f0de + { + + len = MIN(len , req->wLength); + 800f0b0: 683b ldr r3, [r7, #0] + 800f0b2: 88da ldrh r2, [r3, #6] + 800f0b4: 230a movs r3, #10 + 800f0b6: 18fb adds r3, r7, r3 + 800f0b8: 881b ldrh r3, [r3, #0] + 800f0ba: 1c18 adds r0, r3, #0 + 800f0bc: 1c11 adds r1, r2, #0 + 800f0be: b28a uxth r2, r1 + 800f0c0: b283 uxth r3, r0 + 800f0c2: 429a cmp r2, r3 + 800f0c4: d900 bls.n 800f0c8 + 800f0c6: 1c01 adds r1, r0, #0 + 800f0c8: b28a uxth r2, r1 + 800f0ca: 210a movs r1, #10 + 800f0cc: 187b adds r3, r7, r1 + 800f0ce: 801a strh r2, [r3, #0] + + USBD_CtlSendData (pdev, + 800f0d0: 187b adds r3, r7, r1 + 800f0d2: 881a ldrh r2, [r3, #0] + 800f0d4: 68f9 ldr r1, [r7, #12] + 800f0d6: 687b ldr r3, [r7, #4] + 800f0d8: 0018 movs r0, r3 + 800f0da: f000 fd41 bl 800fb60 + pbuf, + len); + } + +} + 800f0de: 46bd mov sp, r7 + 800f0e0: b004 add sp, #16 + 800f0e2: bd80 pop {r7, pc} + +0800f0e4 : +* @param req: usb request +* @retval status +*/ +static void USBD_SetAddress(USBD_HandleTypeDef *pdev , + USBD_SetupReqTypedef *req) +{ + 800f0e4: b590 push {r4, r7, lr} + 800f0e6: b085 sub sp, #20 + 800f0e8: af00 add r7, sp, #0 + 800f0ea: 6078 str r0, [r7, #4] + 800f0ec: 6039 str r1, [r7, #0] + uint8_t dev_addr; + + if ((req->wIndex == 0) && (req->wLength == 0)) + 800f0ee: 683b ldr r3, [r7, #0] + 800f0f0: 889b ldrh r3, [r3, #4] + 800f0f2: 2b00 cmp r3, #0 + 800f0f4: d13a bne.n 800f16c + 800f0f6: 683b ldr r3, [r7, #0] + 800f0f8: 88db ldrh r3, [r3, #6] + 800f0fa: 2b00 cmp r3, #0 + 800f0fc: d136 bne.n 800f16c + { + dev_addr = (uint8_t)(req->wValue) & 0x7F; + 800f0fe: 683b ldr r3, [r7, #0] + 800f100: 885b ldrh r3, [r3, #2] + 800f102: b2da uxtb r2, r3 + 800f104: 230f movs r3, #15 + 800f106: 18fb adds r3, r7, r3 + 800f108: 217f movs r1, #127 ; 0x7f + 800f10a: 400a ands r2, r1 + 800f10c: 701a strb r2, [r3, #0] + + if (pdev->dev_state == USBD_STATE_CONFIGURED) + 800f10e: 687a ldr r2, [r7, #4] + 800f110: 23fe movs r3, #254 ; 0xfe + 800f112: 005b lsls r3, r3, #1 + 800f114: 5cd3 ldrb r3, [r2, r3] + 800f116: 2b03 cmp r3, #3 + 800f118: d106 bne.n 800f128 + { + USBD_CtlError(pdev , req); + 800f11a: 683a ldr r2, [r7, #0] + 800f11c: 687b ldr r3, [r7, #4] + 800f11e: 0011 movs r1, r2 + 800f120: 0018 movs r0, r3 + 800f122: f000 f9b9 bl 800f498 + if (pdev->dev_state == USBD_STATE_CONFIGURED) + 800f126: e027 b.n 800f178 + } + else + { + pdev->dev_address = dev_addr; + 800f128: 687a ldr r2, [r7, #4] + 800f12a: 240f movs r4, #15 + 800f12c: 1939 adds r1, r7, r4 + 800f12e: 23ff movs r3, #255 ; 0xff + 800f130: 005b lsls r3, r3, #1 + 800f132: 7809 ldrb r1, [r1, #0] + 800f134: 54d1 strb r1, [r2, r3] + USBD_LL_SetUSBAddress(pdev, dev_addr); + 800f136: 193b adds r3, r7, r4 + 800f138: 781a ldrb r2, [r3, #0] + 800f13a: 687b ldr r3, [r7, #4] + 800f13c: 0011 movs r1, r2 + 800f13e: 0018 movs r0, r3 + 800f140: f7ff facf bl 800e6e2 + USBD_CtlSendStatus(pdev); + 800f144: 687b ldr r3, [r7, #4] + 800f146: 0018 movs r0, r3 + 800f148: f000 fd50 bl 800fbec + + if (dev_addr != 0) + 800f14c: 193b adds r3, r7, r4 + 800f14e: 781b ldrb r3, [r3, #0] + 800f150: 2b00 cmp r3, #0 + 800f152: d005 beq.n 800f160 + { + pdev->dev_state = USBD_STATE_ADDRESSED; + 800f154: 687a ldr r2, [r7, #4] + 800f156: 23fe movs r3, #254 ; 0xfe + 800f158: 005b lsls r3, r3, #1 + 800f15a: 2102 movs r1, #2 + 800f15c: 54d1 strb r1, [r2, r3] + if (pdev->dev_state == USBD_STATE_CONFIGURED) + 800f15e: e00b b.n 800f178 + } + else + { + pdev->dev_state = USBD_STATE_DEFAULT; + 800f160: 687a ldr r2, [r7, #4] + 800f162: 23fe movs r3, #254 ; 0xfe + 800f164: 005b lsls r3, r3, #1 + 800f166: 2101 movs r1, #1 + 800f168: 54d1 strb r1, [r2, r3] + if (pdev->dev_state == USBD_STATE_CONFIGURED) + 800f16a: e005 b.n 800f178 + } + } + } + else + { + USBD_CtlError(pdev , req); + 800f16c: 683a ldr r2, [r7, #0] + 800f16e: 687b ldr r3, [r7, #4] + 800f170: 0011 movs r1, r2 + 800f172: 0018 movs r0, r3 + 800f174: f000 f990 bl 800f498 + } +} + 800f178: 46c0 nop ; (mov r8, r8) + 800f17a: 46bd mov sp, r7 + 800f17c: b005 add sp, #20 + 800f17e: bd90 pop {r4, r7, pc} + +0800f180 : +* @param req: usb request +* @retval status +*/ +static void USBD_SetConfig(USBD_HandleTypeDef *pdev , + USBD_SetupReqTypedef *req) +{ + 800f180: b580 push {r7, lr} + 800f182: b082 sub sp, #8 + 800f184: af00 add r7, sp, #0 + 800f186: 6078 str r0, [r7, #4] + 800f188: 6039 str r1, [r7, #0] + + static uint8_t cfgidx; + + cfgidx = (uint8_t)(req->wValue); + 800f18a: 683b ldr r3, [r7, #0] + 800f18c: 885b ldrh r3, [r3, #2] + 800f18e: b2da uxtb r2, r3 + 800f190: 4b48 ldr r3, [pc, #288] ; (800f2b4 ) + 800f192: 701a strb r2, [r3, #0] + + if (cfgidx > USBD_MAX_NUM_CONFIGURATION ) + 800f194: 4b47 ldr r3, [pc, #284] ; (800f2b4 ) + 800f196: 781b ldrb r3, [r3, #0] + 800f198: 2b01 cmp r3, #1 + 800f19a: d906 bls.n 800f1aa + { + USBD_CtlError(pdev , req); + 800f19c: 683a ldr r2, [r7, #0] + 800f19e: 687b ldr r3, [r7, #4] + 800f1a0: 0011 movs r1, r2 + 800f1a2: 0018 movs r0, r3 + 800f1a4: f000 f978 bl 800f498 + 800f1a8: e081 b.n 800f2ae + } + else + { + switch (pdev->dev_state) + 800f1aa: 687a ldr r2, [r7, #4] + 800f1ac: 23fe movs r3, #254 ; 0xfe + 800f1ae: 005b lsls r3, r3, #1 + 800f1b0: 5cd3 ldrb r3, [r2, r3] + 800f1b2: 2b02 cmp r3, #2 + 800f1b4: d002 beq.n 800f1bc + 800f1b6: 2b03 cmp r3, #3 + 800f1b8: d029 beq.n 800f20e + 800f1ba: e071 b.n 800f2a0 + { + case USBD_STATE_ADDRESSED: + if (cfgidx) + 800f1bc: 4b3d ldr r3, [pc, #244] ; (800f2b4 ) + 800f1be: 781b ldrb r3, [r3, #0] + 800f1c0: 2b00 cmp r3, #0 + 800f1c2: d01f beq.n 800f204 + { + pdev->dev_config = cfgidx; + 800f1c4: 4b3b ldr r3, [pc, #236] ; (800f2b4 ) + 800f1c6: 781b ldrb r3, [r3, #0] + 800f1c8: 001a movs r2, r3 + 800f1ca: 687b ldr r3, [r7, #4] + 800f1cc: 605a str r2, [r3, #4] + pdev->dev_state = USBD_STATE_CONFIGURED; + 800f1ce: 687a ldr r2, [r7, #4] + 800f1d0: 23fe movs r3, #254 ; 0xfe + 800f1d2: 005b lsls r3, r3, #1 + 800f1d4: 2103 movs r1, #3 + 800f1d6: 54d1 strb r1, [r2, r3] + if(USBD_SetClassConfig(pdev , cfgidx) == USBD_FAIL) + 800f1d8: 4b36 ldr r3, [pc, #216] ; (800f2b4 ) + 800f1da: 781a ldrb r2, [r3, #0] + 800f1dc: 687b ldr r3, [r7, #4] + 800f1de: 0011 movs r1, r2 + 800f1e0: 0018 movs r0, r3 + 800f1e2: f7ff fb5b bl 800e89c + 800f1e6: 0003 movs r3, r0 + 800f1e8: 2b02 cmp r3, #2 + 800f1ea: d106 bne.n 800f1fa + { + USBD_CtlError(pdev , req); + 800f1ec: 683a ldr r2, [r7, #0] + 800f1ee: 687b ldr r3, [r7, #4] + 800f1f0: 0011 movs r1, r2 + 800f1f2: 0018 movs r0, r3 + 800f1f4: f000 f950 bl 800f498 + return; + 800f1f8: e059 b.n 800f2ae + } + USBD_CtlSendStatus(pdev); + 800f1fa: 687b ldr r3, [r7, #4] + 800f1fc: 0018 movs r0, r3 + 800f1fe: f000 fcf5 bl 800fbec + } + else + { + USBD_CtlSendStatus(pdev); + } + break; + 800f202: e054 b.n 800f2ae + USBD_CtlSendStatus(pdev); + 800f204: 687b ldr r3, [r7, #4] + 800f206: 0018 movs r0, r3 + 800f208: f000 fcf0 bl 800fbec + break; + 800f20c: e04f b.n 800f2ae + + case USBD_STATE_CONFIGURED: + if (cfgidx == 0) + 800f20e: 4b29 ldr r3, [pc, #164] ; (800f2b4 ) + 800f210: 781b ldrb r3, [r3, #0] + 800f212: 2b00 cmp r3, #0 + 800f214: d115 bne.n 800f242 + { + pdev->dev_state = USBD_STATE_ADDRESSED; + 800f216: 687a ldr r2, [r7, #4] + 800f218: 23fe movs r3, #254 ; 0xfe + 800f21a: 005b lsls r3, r3, #1 + 800f21c: 2102 movs r1, #2 + 800f21e: 54d1 strb r1, [r2, r3] + pdev->dev_config = cfgidx; + 800f220: 4b24 ldr r3, [pc, #144] ; (800f2b4 ) + 800f222: 781b ldrb r3, [r3, #0] + 800f224: 001a movs r2, r3 + 800f226: 687b ldr r3, [r7, #4] + 800f228: 605a str r2, [r3, #4] + USBD_ClrClassConfig(pdev , cfgidx); + 800f22a: 4b22 ldr r3, [pc, #136] ; (800f2b4 ) + 800f22c: 781a ldrb r2, [r3, #0] + 800f22e: 687b ldr r3, [r7, #4] + 800f230: 0011 movs r1, r2 + 800f232: 0018 movs r0, r3 + 800f234: f7ff fb5a bl 800e8ec + USBD_CtlSendStatus(pdev); + 800f238: 687b ldr r3, [r7, #4] + 800f23a: 0018 movs r0, r3 + 800f23c: f000 fcd6 bl 800fbec + } + else + { + USBD_CtlSendStatus(pdev); + } + break; + 800f240: e035 b.n 800f2ae + else if (cfgidx != pdev->dev_config) + 800f242: 4b1c ldr r3, [pc, #112] ; (800f2b4 ) + 800f244: 781b ldrb r3, [r3, #0] + 800f246: 001a movs r2, r3 + 800f248: 687b ldr r3, [r7, #4] + 800f24a: 685b ldr r3, [r3, #4] + 800f24c: 429a cmp r2, r3 + 800f24e: d022 beq.n 800f296 + USBD_ClrClassConfig(pdev , pdev->dev_config); + 800f250: 687b ldr r3, [r7, #4] + 800f252: 685b ldr r3, [r3, #4] + 800f254: b2da uxtb r2, r3 + 800f256: 687b ldr r3, [r7, #4] + 800f258: 0011 movs r1, r2 + 800f25a: 0018 movs r0, r3 + 800f25c: f7ff fb46 bl 800e8ec + pdev->dev_config = cfgidx; + 800f260: 4b14 ldr r3, [pc, #80] ; (800f2b4 ) + 800f262: 781b ldrb r3, [r3, #0] + 800f264: 001a movs r2, r3 + 800f266: 687b ldr r3, [r7, #4] + 800f268: 605a str r2, [r3, #4] + if(USBD_SetClassConfig(pdev , cfgidx) == USBD_FAIL) + 800f26a: 4b12 ldr r3, [pc, #72] ; (800f2b4 ) + 800f26c: 781a ldrb r2, [r3, #0] + 800f26e: 687b ldr r3, [r7, #4] + 800f270: 0011 movs r1, r2 + 800f272: 0018 movs r0, r3 + 800f274: f7ff fb12 bl 800e89c + 800f278: 0003 movs r3, r0 + 800f27a: 2b02 cmp r3, #2 + 800f27c: d106 bne.n 800f28c + USBD_CtlError(pdev , req); + 800f27e: 683a ldr r2, [r7, #0] + 800f280: 687b ldr r3, [r7, #4] + 800f282: 0011 movs r1, r2 + 800f284: 0018 movs r0, r3 + 800f286: f000 f907 bl 800f498 + return; + 800f28a: e010 b.n 800f2ae + USBD_CtlSendStatus(pdev); + 800f28c: 687b ldr r3, [r7, #4] + 800f28e: 0018 movs r0, r3 + 800f290: f000 fcac bl 800fbec + break; + 800f294: e00b b.n 800f2ae + USBD_CtlSendStatus(pdev); + 800f296: 687b ldr r3, [r7, #4] + 800f298: 0018 movs r0, r3 + 800f29a: f000 fca7 bl 800fbec + break; + 800f29e: e006 b.n 800f2ae + + default: + USBD_CtlError(pdev , req); + 800f2a0: 683a ldr r2, [r7, #0] + 800f2a2: 687b ldr r3, [r7, #4] + 800f2a4: 0011 movs r1, r2 + 800f2a6: 0018 movs r0, r3 + 800f2a8: f000 f8f6 bl 800f498 + break; + 800f2ac: 46c0 nop ; (mov r8, r8) + } + } +} + 800f2ae: 46bd mov sp, r7 + 800f2b0: b002 add sp, #8 + 800f2b2: bd80 pop {r7, pc} + 800f2b4: 200023c8 .word 0x200023c8 + +0800f2b8 : +* @param req: usb request +* @retval status +*/ +static void USBD_GetConfig(USBD_HandleTypeDef *pdev , + USBD_SetupReqTypedef *req) +{ + 800f2b8: b580 push {r7, lr} + 800f2ba: b082 sub sp, #8 + 800f2bc: af00 add r7, sp, #0 + 800f2be: 6078 str r0, [r7, #4] + 800f2c0: 6039 str r1, [r7, #0] + + if (req->wLength != 1) + 800f2c2: 683b ldr r3, [r7, #0] + 800f2c4: 88db ldrh r3, [r3, #6] + 800f2c6: 2b01 cmp r3, #1 + 800f2c8: d006 beq.n 800f2d8 + { + USBD_CtlError(pdev , req); + 800f2ca: 683a ldr r2, [r7, #0] + 800f2cc: 687b ldr r3, [r7, #4] + 800f2ce: 0011 movs r1, r2 + 800f2d0: 0018 movs r0, r3 + 800f2d2: f000 f8e1 bl 800f498 + default: + USBD_CtlError(pdev , req); + break; + } + } +} + 800f2d6: e023 b.n 800f320 + switch (pdev->dev_state ) + 800f2d8: 687a ldr r2, [r7, #4] + 800f2da: 23fe movs r3, #254 ; 0xfe + 800f2dc: 005b lsls r3, r3, #1 + 800f2de: 5cd3 ldrb r3, [r2, r3] + 800f2e0: 2b02 cmp r3, #2 + 800f2e2: d002 beq.n 800f2ea + 800f2e4: 2b03 cmp r3, #3 + 800f2e6: d00c beq.n 800f302 + 800f2e8: e013 b.n 800f312 + pdev->dev_default_config = 0; + 800f2ea: 687b ldr r3, [r7, #4] + 800f2ec: 2200 movs r2, #0 + 800f2ee: 609a str r2, [r3, #8] + (uint8_t *)&pdev->dev_default_config, + 800f2f0: 687b ldr r3, [r7, #4] + 800f2f2: 3308 adds r3, #8 + 800f2f4: 0019 movs r1, r3 + USBD_CtlSendData (pdev, + 800f2f6: 687b ldr r3, [r7, #4] + 800f2f8: 2201 movs r2, #1 + 800f2fa: 0018 movs r0, r3 + 800f2fc: f000 fc30 bl 800fb60 + break; + 800f300: e00e b.n 800f320 + (uint8_t *)&pdev->dev_config, + 800f302: 687b ldr r3, [r7, #4] + 800f304: 1d19 adds r1, r3, #4 + USBD_CtlSendData (pdev, + 800f306: 687b ldr r3, [r7, #4] + 800f308: 2201 movs r2, #1 + 800f30a: 0018 movs r0, r3 + 800f30c: f000 fc28 bl 800fb60 + break; + 800f310: e006 b.n 800f320 + USBD_CtlError(pdev , req); + 800f312: 683a ldr r2, [r7, #0] + 800f314: 687b ldr r3, [r7, #4] + 800f316: 0011 movs r1, r2 + 800f318: 0018 movs r0, r3 + 800f31a: f000 f8bd bl 800f498 + break; + 800f31e: 46c0 nop ; (mov r8, r8) +} + 800f320: 46c0 nop ; (mov r8, r8) + 800f322: 46bd mov sp, r7 + 800f324: b002 add sp, #8 + 800f326: bd80 pop {r7, pc} + +0800f328 : +* @param req: usb request +* @retval status +*/ +static void USBD_GetStatus(USBD_HandleTypeDef *pdev , + USBD_SetupReqTypedef *req) +{ + 800f328: b580 push {r7, lr} + 800f32a: b082 sub sp, #8 + 800f32c: af00 add r7, sp, #0 + 800f32e: 6078 str r0, [r7, #4] + 800f330: 6039 str r1, [r7, #0] + + + switch (pdev->dev_state) + 800f332: 687a ldr r2, [r7, #4] + 800f334: 23fe movs r3, #254 ; 0xfe + 800f336: 005b lsls r3, r3, #1 + 800f338: 5cd3 ldrb r3, [r2, r3] + 800f33a: 3b02 subs r3, #2 + 800f33c: 2b01 cmp r3, #1 + 800f33e: d817 bhi.n 800f370 + case USBD_STATE_CONFIGURED: + +#if ( USBD_SELF_POWERED == 1) + pdev->dev_config_status = USB_CONFIG_SELF_POWERED; +#else + pdev->dev_config_status = 0; + 800f340: 687b ldr r3, [r7, #4] + 800f342: 2200 movs r2, #0 + 800f344: 60da str r2, [r3, #12] +#endif + + if (pdev->dev_remote_wakeup) + 800f346: 687a ldr r2, [r7, #4] + 800f348: 2380 movs r3, #128 ; 0x80 + 800f34a: 009b lsls r3, r3, #2 + 800f34c: 58d3 ldr r3, [r2, r3] + 800f34e: 2b00 cmp r3, #0 + 800f350: d005 beq.n 800f35e + { + pdev->dev_config_status |= USB_CONFIG_REMOTE_WAKEUP; + 800f352: 687b ldr r3, [r7, #4] + 800f354: 68db ldr r3, [r3, #12] + 800f356: 2202 movs r2, #2 + 800f358: 431a orrs r2, r3 + 800f35a: 687b ldr r3, [r7, #4] + 800f35c: 60da str r2, [r3, #12] + } + + USBD_CtlSendData (pdev, + (uint8_t *)& pdev->dev_config_status, + 800f35e: 687b ldr r3, [r7, #4] + 800f360: 330c adds r3, #12 + 800f362: 0019 movs r1, r3 + USBD_CtlSendData (pdev, + 800f364: 687b ldr r3, [r7, #4] + 800f366: 2202 movs r2, #2 + 800f368: 0018 movs r0, r3 + 800f36a: f000 fbf9 bl 800fb60 + 2); + break; + 800f36e: e006 b.n 800f37e + + default : + USBD_CtlError(pdev , req); + 800f370: 683a ldr r2, [r7, #0] + 800f372: 687b ldr r3, [r7, #4] + 800f374: 0011 movs r1, r2 + 800f376: 0018 movs r0, r3 + 800f378: f000 f88e bl 800f498 + break; + 800f37c: 46c0 nop ; (mov r8, r8) + } +} + 800f37e: 46c0 nop ; (mov r8, r8) + 800f380: 46bd mov sp, r7 + 800f382: b002 add sp, #8 + 800f384: bd80 pop {r7, pc} + +0800f386 : +* @param req: usb request +* @retval status +*/ +static void USBD_SetFeature(USBD_HandleTypeDef *pdev , + USBD_SetupReqTypedef *req) +{ + 800f386: b580 push {r7, lr} + 800f388: b082 sub sp, #8 + 800f38a: af00 add r7, sp, #0 + 800f38c: 6078 str r0, [r7, #4] + 800f38e: 6039 str r1, [r7, #0] + + if (req->wValue == USB_FEATURE_REMOTE_WAKEUP) + 800f390: 683b ldr r3, [r7, #0] + 800f392: 885b ldrh r3, [r3, #2] + 800f394: 2b01 cmp r3, #1 + 800f396: d111 bne.n 800f3bc + { + pdev->dev_remote_wakeup = 1; + 800f398: 687a ldr r2, [r7, #4] + 800f39a: 2380 movs r3, #128 ; 0x80 + 800f39c: 009b lsls r3, r3, #2 + 800f39e: 2101 movs r1, #1 + 800f3a0: 50d1 str r1, [r2, r3] + pdev->pClass->Setup (pdev, req); + 800f3a2: 687a ldr r2, [r7, #4] + 800f3a4: 2384 movs r3, #132 ; 0x84 + 800f3a6: 009b lsls r3, r3, #2 + 800f3a8: 58d3 ldr r3, [r2, r3] + 800f3aa: 689b ldr r3, [r3, #8] + 800f3ac: 6839 ldr r1, [r7, #0] + 800f3ae: 687a ldr r2, [r7, #4] + 800f3b0: 0010 movs r0, r2 + 800f3b2: 4798 blx r3 + USBD_CtlSendStatus(pdev); + 800f3b4: 687b ldr r3, [r7, #4] + 800f3b6: 0018 movs r0, r3 + 800f3b8: f000 fc18 bl 800fbec + } + +} + 800f3bc: 46c0 nop ; (mov r8, r8) + 800f3be: 46bd mov sp, r7 + 800f3c0: b002 add sp, #8 + 800f3c2: bd80 pop {r7, pc} + +0800f3c4 : +* @param req: usb request +* @retval status +*/ +static void USBD_ClrFeature(USBD_HandleTypeDef *pdev , + USBD_SetupReqTypedef *req) +{ + 800f3c4: b580 push {r7, lr} + 800f3c6: b082 sub sp, #8 + 800f3c8: af00 add r7, sp, #0 + 800f3ca: 6078 str r0, [r7, #4] + 800f3cc: 6039 str r1, [r7, #0] + switch (pdev->dev_state) + 800f3ce: 687a ldr r2, [r7, #4] + 800f3d0: 23fe movs r3, #254 ; 0xfe + 800f3d2: 005b lsls r3, r3, #1 + 800f3d4: 5cd3 ldrb r3, [r2, r3] + 800f3d6: 3b02 subs r3, #2 + 800f3d8: 2b01 cmp r3, #1 + 800f3da: d816 bhi.n 800f40a + { + case USBD_STATE_ADDRESSED: + case USBD_STATE_CONFIGURED: + if (req->wValue == USB_FEATURE_REMOTE_WAKEUP) + 800f3dc: 683b ldr r3, [r7, #0] + 800f3de: 885b ldrh r3, [r3, #2] + 800f3e0: 2b01 cmp r3, #1 + 800f3e2: d119 bne.n 800f418 + { + pdev->dev_remote_wakeup = 0; + 800f3e4: 687a ldr r2, [r7, #4] + 800f3e6: 2380 movs r3, #128 ; 0x80 + 800f3e8: 009b lsls r3, r3, #2 + 800f3ea: 2100 movs r1, #0 + 800f3ec: 50d1 str r1, [r2, r3] + pdev->pClass->Setup (pdev, req); + 800f3ee: 687a ldr r2, [r7, #4] + 800f3f0: 2384 movs r3, #132 ; 0x84 + 800f3f2: 009b lsls r3, r3, #2 + 800f3f4: 58d3 ldr r3, [r2, r3] + 800f3f6: 689b ldr r3, [r3, #8] + 800f3f8: 6839 ldr r1, [r7, #0] + 800f3fa: 687a ldr r2, [r7, #4] + 800f3fc: 0010 movs r0, r2 + 800f3fe: 4798 blx r3 + USBD_CtlSendStatus(pdev); + 800f400: 687b ldr r3, [r7, #4] + 800f402: 0018 movs r0, r3 + 800f404: f000 fbf2 bl 800fbec + } + break; + 800f408: e006 b.n 800f418 + + default : + USBD_CtlError(pdev , req); + 800f40a: 683a ldr r2, [r7, #0] + 800f40c: 687b ldr r3, [r7, #4] + 800f40e: 0011 movs r1, r2 + 800f410: 0018 movs r0, r3 + 800f412: f000 f841 bl 800f498 + break; + 800f416: e000 b.n 800f41a + break; + 800f418: 46c0 nop ; (mov r8, r8) + } +} + 800f41a: 46c0 nop ; (mov r8, r8) + 800f41c: 46bd mov sp, r7 + 800f41e: b002 add sp, #8 + 800f420: bd80 pop {r7, pc} + +0800f422 : +* @param req: usb request +* @retval None +*/ + +void USBD_ParseSetupRequest(USBD_SetupReqTypedef *req, uint8_t *pdata) +{ + 800f422: b580 push {r7, lr} + 800f424: b082 sub sp, #8 + 800f426: af00 add r7, sp, #0 + 800f428: 6078 str r0, [r7, #4] + 800f42a: 6039 str r1, [r7, #0] + req->bmRequest = *(uint8_t *) (pdata); + 800f42c: 683b ldr r3, [r7, #0] + 800f42e: 781a ldrb r2, [r3, #0] + 800f430: 687b ldr r3, [r7, #4] + 800f432: 701a strb r2, [r3, #0] + req->bRequest = *(uint8_t *) (pdata + 1); + 800f434: 683b ldr r3, [r7, #0] + 800f436: 785a ldrb r2, [r3, #1] + 800f438: 687b ldr r3, [r7, #4] + 800f43a: 705a strb r2, [r3, #1] + req->wValue = SWAPBYTE (pdata + 2); + 800f43c: 683b ldr r3, [r7, #0] + 800f43e: 3302 adds r3, #2 + 800f440: 781b ldrb r3, [r3, #0] + 800f442: b29a uxth r2, r3 + 800f444: 683b ldr r3, [r7, #0] + 800f446: 3303 adds r3, #3 + 800f448: 781b ldrb r3, [r3, #0] + 800f44a: b29b uxth r3, r3 + 800f44c: 021b lsls r3, r3, #8 + 800f44e: b29b uxth r3, r3 + 800f450: 18d3 adds r3, r2, r3 + 800f452: b29a uxth r2, r3 + 800f454: 687b ldr r3, [r7, #4] + 800f456: 805a strh r2, [r3, #2] + req->wIndex = SWAPBYTE (pdata + 4); + 800f458: 683b ldr r3, [r7, #0] + 800f45a: 3304 adds r3, #4 + 800f45c: 781b ldrb r3, [r3, #0] + 800f45e: b29a uxth r2, r3 + 800f460: 683b ldr r3, [r7, #0] + 800f462: 3305 adds r3, #5 + 800f464: 781b ldrb r3, [r3, #0] + 800f466: b29b uxth r3, r3 + 800f468: 021b lsls r3, r3, #8 + 800f46a: b29b uxth r3, r3 + 800f46c: 18d3 adds r3, r2, r3 + 800f46e: b29a uxth r2, r3 + 800f470: 687b ldr r3, [r7, #4] + 800f472: 809a strh r2, [r3, #4] + req->wLength = SWAPBYTE (pdata + 6); + 800f474: 683b ldr r3, [r7, #0] + 800f476: 3306 adds r3, #6 + 800f478: 781b ldrb r3, [r3, #0] + 800f47a: b29a uxth r2, r3 + 800f47c: 683b ldr r3, [r7, #0] + 800f47e: 3307 adds r3, #7 + 800f480: 781b ldrb r3, [r3, #0] + 800f482: b29b uxth r3, r3 + 800f484: 021b lsls r3, r3, #8 + 800f486: b29b uxth r3, r3 + 800f488: 18d3 adds r3, r2, r3 + 800f48a: b29a uxth r2, r3 + 800f48c: 687b ldr r3, [r7, #4] + 800f48e: 80da strh r2, [r3, #6] + +} + 800f490: 46c0 nop ; (mov r8, r8) + 800f492: 46bd mov sp, r7 + 800f494: b002 add sp, #8 + 800f496: bd80 pop {r7, pc} + +0800f498 : +* @retval None +*/ + +void USBD_CtlError( USBD_HandleTypeDef *pdev , + USBD_SetupReqTypedef *req) +{ + 800f498: b580 push {r7, lr} + 800f49a: b082 sub sp, #8 + 800f49c: af00 add r7, sp, #0 + 800f49e: 6078 str r0, [r7, #4] + 800f4a0: 6039 str r1, [r7, #0] + USBD_LL_StallEP(pdev , 0x80); + 800f4a2: 687b ldr r3, [r7, #4] + 800f4a4: 2180 movs r1, #128 ; 0x80 + 800f4a6: 0018 movs r0, r3 + 800f4a8: f7ff f8c4 bl 800e634 + USBD_LL_StallEP(pdev , 0); + 800f4ac: 687b ldr r3, [r7, #4] + 800f4ae: 2100 movs r1, #0 + 800f4b0: 0018 movs r0, r3 + 800f4b2: f7ff f8bf bl 800e634 +} + 800f4b6: 46c0 nop ; (mov r8, r8) + 800f4b8: 46bd mov sp, r7 + 800f4ba: b002 add sp, #8 + 800f4bc: bd80 pop {r7, pc} + +0800f4be : + * @param unicode : Formatted string buffer (unicode) + * @param len : descriptor length + * @retval None + */ +void USBD_GetString(uint8_t *desc, uint8_t *unicode, uint16_t *len) +{ + 800f4be: b590 push {r4, r7, lr} + 800f4c0: b087 sub sp, #28 + 800f4c2: af00 add r7, sp, #0 + 800f4c4: 60f8 str r0, [r7, #12] + 800f4c6: 60b9 str r1, [r7, #8] + 800f4c8: 607a str r2, [r7, #4] + uint8_t idx = 0; + 800f4ca: 2317 movs r3, #23 + 800f4cc: 18fb adds r3, r7, r3 + 800f4ce: 2200 movs r2, #0 + 800f4d0: 701a strb r2, [r3, #0] + + if (desc != NULL) + 800f4d2: 68fb ldr r3, [r7, #12] + 800f4d4: 2b00 cmp r3, #0 + 800f4d6: d03e beq.n 800f556 + { + *len = USBD_GetLen(desc) * 2 + 2; + 800f4d8: 68fb ldr r3, [r7, #12] + 800f4da: 0018 movs r0, r3 + 800f4dc: f000 f83f bl 800f55e + 800f4e0: 0003 movs r3, r0 + 800f4e2: 3301 adds r3, #1 + 800f4e4: b29b uxth r3, r3 + 800f4e6: 18db adds r3, r3, r3 + 800f4e8: b29a uxth r2, r3 + 800f4ea: 687b ldr r3, [r7, #4] + 800f4ec: 801a strh r2, [r3, #0] + unicode[idx++] = *len; + 800f4ee: 687b ldr r3, [r7, #4] + 800f4f0: 8819 ldrh r1, [r3, #0] + 800f4f2: 2417 movs r4, #23 + 800f4f4: 193b adds r3, r7, r4 + 800f4f6: 781b ldrb r3, [r3, #0] + 800f4f8: 193a adds r2, r7, r4 + 800f4fa: 1c58 adds r0, r3, #1 + 800f4fc: 7010 strb r0, [r2, #0] + 800f4fe: 001a movs r2, r3 + 800f500: 68bb ldr r3, [r7, #8] + 800f502: 189b adds r3, r3, r2 + 800f504: b2ca uxtb r2, r1 + 800f506: 701a strb r2, [r3, #0] + unicode[idx++] = USB_DESC_TYPE_STRING; + 800f508: 193b adds r3, r7, r4 + 800f50a: 781b ldrb r3, [r3, #0] + 800f50c: 193a adds r2, r7, r4 + 800f50e: 1c59 adds r1, r3, #1 + 800f510: 7011 strb r1, [r2, #0] + 800f512: 001a movs r2, r3 + 800f514: 68bb ldr r3, [r7, #8] + 800f516: 189b adds r3, r3, r2 + 800f518: 2203 movs r2, #3 + 800f51a: 701a strb r2, [r3, #0] + + while (*desc != '\0') + 800f51c: e017 b.n 800f54e + { + unicode[idx++] = *desc++; + 800f51e: 68fb ldr r3, [r7, #12] + 800f520: 1c5a adds r2, r3, #1 + 800f522: 60fa str r2, [r7, #12] + 800f524: 2417 movs r4, #23 + 800f526: 193a adds r2, r7, r4 + 800f528: 7812 ldrb r2, [r2, #0] + 800f52a: 1939 adds r1, r7, r4 + 800f52c: 1c50 adds r0, r2, #1 + 800f52e: 7008 strb r0, [r1, #0] + 800f530: 0011 movs r1, r2 + 800f532: 68ba ldr r2, [r7, #8] + 800f534: 1852 adds r2, r2, r1 + 800f536: 781b ldrb r3, [r3, #0] + 800f538: 7013 strb r3, [r2, #0] + unicode[idx++] = 0x00; + 800f53a: 193b adds r3, r7, r4 + 800f53c: 781b ldrb r3, [r3, #0] + 800f53e: 193a adds r2, r7, r4 + 800f540: 1c59 adds r1, r3, #1 + 800f542: 7011 strb r1, [r2, #0] + 800f544: 001a movs r2, r3 + 800f546: 68bb ldr r3, [r7, #8] + 800f548: 189b adds r3, r3, r2 + 800f54a: 2200 movs r2, #0 + 800f54c: 701a strb r2, [r3, #0] + while (*desc != '\0') + 800f54e: 68fb ldr r3, [r7, #12] + 800f550: 781b ldrb r3, [r3, #0] + 800f552: 2b00 cmp r3, #0 + 800f554: d1e3 bne.n 800f51e + } + } +} + 800f556: 46c0 nop ; (mov r8, r8) + 800f558: 46bd mov sp, r7 + 800f55a: b007 add sp, #28 + 800f55c: bd90 pop {r4, r7, pc} + +0800f55e : + * return the string length + * @param buf : pointer to the ascii string buffer + * @retval string length + */ +static uint8_t USBD_GetLen(uint8_t *buf) +{ + 800f55e: b580 push {r7, lr} + 800f560: b084 sub sp, #16 + 800f562: af00 add r7, sp, #0 + 800f564: 6078 str r0, [r7, #4] + uint8_t len = 0; + 800f566: 230f movs r3, #15 + 800f568: 18fb adds r3, r7, r3 + 800f56a: 2200 movs r2, #0 + 800f56c: 701a strb r2, [r3, #0] + + while (*buf != '\0') + 800f56e: e008 b.n 800f582 + { + len++; + 800f570: 210f movs r1, #15 + 800f572: 187b adds r3, r7, r1 + 800f574: 781a ldrb r2, [r3, #0] + 800f576: 187b adds r3, r7, r1 + 800f578: 3201 adds r2, #1 + 800f57a: 701a strb r2, [r3, #0] + buf++; + 800f57c: 687b ldr r3, [r7, #4] + 800f57e: 3301 adds r3, #1 + 800f580: 607b str r3, [r7, #4] + while (*buf != '\0') + 800f582: 687b ldr r3, [r7, #4] + 800f584: 781b ldrb r3, [r3, #0] + 800f586: 2b00 cmp r3, #0 + 800f588: d1f2 bne.n 800f570 + } + + return len; + 800f58a: 230f movs r3, #15 + 800f58c: 18fb adds r3, r7, r3 + 800f58e: 781b ldrb r3, [r3, #0] +} + 800f590: 0018 movs r0, r3 + 800f592: 46bd mov sp, r7 + 800f594: b004 add sp, #16 + 800f596: bd80 pop {r7, pc} + +0800f598 : + * @param speed: Current device speed + * @param length: Pointer to data length variable + * @retval Pointer to descriptor buffer + */ +static uint8_t *USBD_VCP_DeviceDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) +{ + 800f598: b580 push {r7, lr} + 800f59a: b082 sub sp, #8 + 800f59c: af00 add r7, sp, #0 + 800f59e: 0002 movs r2, r0 + 800f5a0: 6039 str r1, [r7, #0] + 800f5a2: 1dfb adds r3, r7, #7 + 800f5a4: 701a strb r2, [r3, #0] + *length = sizeof(hUSBDDeviceDesc); + 800f5a6: 683b ldr r3, [r7, #0] + 800f5a8: 2212 movs r2, #18 + 800f5aa: 801a strh r2, [r3, #0] + return (uint8_t*)&hUSBDDeviceDesc; + 800f5ac: 4b02 ldr r3, [pc, #8] ; (800f5b8 ) +} + 800f5ae: 0018 movs r0, r3 + 800f5b0: 46bd mov sp, r7 + 800f5b2: b002 add sp, #8 + 800f5b4: bd80 pop {r7, pc} + 800f5b6: 46c0 nop ; (mov r8, r8) + 800f5b8: 0800fe14 .word 0x0800fe14 + +0800f5bc : + * @param speed: Current device speed + * @param length: Pointer to data length variable + * @retval Pointer to descriptor buffer + */ +static uint8_t *USBD_VCP_LangIDStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) +{ + 800f5bc: b580 push {r7, lr} + 800f5be: b082 sub sp, #8 + 800f5c0: af00 add r7, sp, #0 + 800f5c2: 0002 movs r2, r0 + 800f5c4: 6039 str r1, [r7, #0] + 800f5c6: 1dfb adds r3, r7, #7 + 800f5c8: 701a strb r2, [r3, #0] + *length = sizeof(USBD_LangIDDesc); + 800f5ca: 683b ldr r3, [r7, #0] + 800f5cc: 2204 movs r2, #4 + 800f5ce: 801a strh r2, [r3, #0] + return (uint8_t*)USBD_LangIDDesc; + 800f5d0: 4b02 ldr r3, [pc, #8] ; (800f5dc ) +} + 800f5d2: 0018 movs r0, r3 + 800f5d4: 46bd mov sp, r7 + 800f5d6: b002 add sp, #8 + 800f5d8: bd80 pop {r7, pc} + 800f5da: 46c0 nop ; (mov r8, r8) + 800f5dc: 0800fe78 .word 0x0800fe78 + +0800f5e0 : + * @param speed: Current device speed + * @param length: Pointer to data length variable + * @retval Pointer to descriptor buffer + */ +static uint8_t *USBD_VCP_ProductStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) +{ + 800f5e0: b580 push {r7, lr} + 800f5e2: b082 sub sp, #8 + 800f5e4: af00 add r7, sp, #0 + 800f5e6: 0002 movs r2, r0 + 800f5e8: 6039 str r1, [r7, #0] + 800f5ea: 1dfb adds r3, r7, #7 + 800f5ec: 701a strb r2, [r3, #0] + USBD_GetString((uint8_t *)USBD_PRODUCT_FS_STRING, USBD_StrDesc, length); + 800f5ee: 683a ldr r2, [r7, #0] + 800f5f0: 4904 ldr r1, [pc, #16] ; (800f604 ) + 800f5f2: 4b05 ldr r3, [pc, #20] ; (800f608 ) + 800f5f4: 0018 movs r0, r3 + 800f5f6: f7ff ff62 bl 800f4be + return USBD_StrDesc; + 800f5fa: 4b02 ldr r3, [pc, #8] ; (800f604 ) +} + 800f5fc: 0018 movs r0, r3 + 800f5fe: 46bd mov sp, r7 + 800f600: b002 add sp, #8 + 800f602: bd80 pop {r7, pc} + 800f604: 200023cc .word 0x200023cc + 800f608: 0800fd1c .word 0x0800fd1c + +0800f60c : + * @param speed: Current device speed + * @param length: Pointer to data length variable + * @retval Pointer to descriptor buffer + */ +static uint8_t *USBD_VCP_ManufacturerStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) +{ + 800f60c: b580 push {r7, lr} + 800f60e: b082 sub sp, #8 + 800f610: af00 add r7, sp, #0 + 800f612: 0002 movs r2, r0 + 800f614: 6039 str r1, [r7, #0] + 800f616: 1dfb adds r3, r7, #7 + 800f618: 701a strb r2, [r3, #0] + USBD_GetString((uint8_t *)USBD_MANUFACTURER_STRING, USBD_StrDesc, length); + 800f61a: 683a ldr r2, [r7, #0] + 800f61c: 4904 ldr r1, [pc, #16] ; (800f630 ) + 800f61e: 4b05 ldr r3, [pc, #20] ; (800f634 ) + 800f620: 0018 movs r0, r3 + 800f622: f7ff ff4c bl 800f4be + return USBD_StrDesc; + 800f626: 4b02 ldr r3, [pc, #8] ; (800f630 ) +} + 800f628: 0018 movs r0, r3 + 800f62a: 46bd mov sp, r7 + 800f62c: b002 add sp, #8 + 800f62e: bd80 pop {r7, pc} + 800f630: 200023cc .word 0x200023cc + 800f634: 0800fd20 .word 0x0800fd20 + +0800f638 : + * @param speed: Current device speed + * @param length: Pointer to data length variable + * @retval Pointer to descriptor buffer + */ +static uint8_t *USBD_VCP_SerialStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) +{ + 800f638: b580 push {r7, lr} + 800f63a: b084 sub sp, #16 + 800f63c: af00 add r7, sp, #0 + 800f63e: 0002 movs r2, r0 + 800f640: 6039 str r1, [r7, #0] + 800f642: 1dfb adds r3, r7, #7 + 800f644: 701a strb r2, [r3, #0] + + /* + for some peculiar reason, ST doesn't define the unique ID registers in the HAL include files + the DEVICE_ID registers are documented in Chapter 33 of the RM0091 Reference Manual + */ + deviceserial = *(uint32_t*)(0x1FFFF7B0); /*DEVICE_ID2*/ + 800f646: 4b0e ldr r3, [pc, #56] ; (800f680 ) + 800f648: 681b ldr r3, [r3, #0] + 800f64a: 60fb str r3, [r7, #12] + + USBD_StrDesc[0] = *length = 2 + 8*2 + 4*2; + 800f64c: 683b ldr r3, [r7, #0] + 800f64e: 221a movs r2, #26 + 800f650: 801a strh r2, [r3, #0] + 800f652: 4b0c ldr r3, [pc, #48] ; (800f684 ) + 800f654: 221a movs r2, #26 + 800f656: 701a strb r2, [r3, #0] + USBD_StrDesc[1] = USB_DESC_TYPE_STRING; + 800f658: 4b0a ldr r3, [pc, #40] ; (800f684 ) + 800f65a: 2203 movs r2, #3 + 800f65c: 705a strb r2, [r3, #1] + /* set upper bits to ensure classification as locally administered */ + IntToUnicode (0x02020000, &USBD_StrDesc[2], 4); + 800f65e: 4b0a ldr r3, [pc, #40] ; (800f688 ) + 800f660: 480a ldr r0, [pc, #40] ; (800f68c ) + 800f662: 2204 movs r2, #4 + 800f664: 0019 movs r1, r3 + 800f666: f000 f815 bl 800f694 + /* set lower 32-bits using silicon serial number */ + IntToUnicode (deviceserial, &USBD_StrDesc[10], 8); + 800f66a: 4909 ldr r1, [pc, #36] ; (800f690 ) + 800f66c: 68fb ldr r3, [r7, #12] + 800f66e: 2208 movs r2, #8 + 800f670: 0018 movs r0, r3 + 800f672: f000 f80f bl 800f694 + return USBD_StrDesc; + 800f676: 4b03 ldr r3, [pc, #12] ; (800f684 ) +} + 800f678: 0018 movs r0, r3 + 800f67a: 46bd mov sp, r7 + 800f67c: b004 add sp, #16 + 800f67e: bd80 pop {r7, pc} + 800f680: 1ffff7b0 .word 0x1ffff7b0 + 800f684: 200023cc .word 0x200023cc + 800f688: 200023ce .word 0x200023ce + 800f68c: 02020000 .word 0x02020000 + 800f690: 200023d6 .word 0x200023d6 + +0800f694 : + * @param pbuf: pointer to the buffer + * @param len: buffer length + * @retval None + */ +static void IntToUnicode (uint32_t value, uint8_t *pbuf, uint8_t len) +{ + 800f694: b580 push {r7, lr} + 800f696: b086 sub sp, #24 + 800f698: af00 add r7, sp, #0 + 800f69a: 60f8 str r0, [r7, #12] + 800f69c: 60b9 str r1, [r7, #8] + 800f69e: 1dfb adds r3, r7, #7 + 800f6a0: 701a strb r2, [r3, #0] + uint8_t idx = 0; + 800f6a2: 2117 movs r1, #23 + 800f6a4: 187b adds r3, r7, r1 + 800f6a6: 2200 movs r2, #0 + 800f6a8: 701a strb r2, [r3, #0] + + for( idx = 0 ; idx < len ; idx ++) + 800f6aa: 187b adds r3, r7, r1 + 800f6ac: 2200 movs r2, #0 + 800f6ae: 701a strb r2, [r3, #0] + 800f6b0: e02f b.n 800f712 + { + if( ((value >> 28)) < 0xA ) + 800f6b2: 68fb ldr r3, [r7, #12] + 800f6b4: 0f1b lsrs r3, r3, #28 + 800f6b6: 2b09 cmp r3, #9 + 800f6b8: d80d bhi.n 800f6d6 + { + pbuf[ 2* idx] = (value >> 28) + '0'; + 800f6ba: 68fb ldr r3, [r7, #12] + 800f6bc: 0f1b lsrs r3, r3, #28 + 800f6be: b2da uxtb r2, r3 + 800f6c0: 2317 movs r3, #23 + 800f6c2: 18fb adds r3, r7, r3 + 800f6c4: 781b ldrb r3, [r3, #0] + 800f6c6: 005b lsls r3, r3, #1 + 800f6c8: 0019 movs r1, r3 + 800f6ca: 68bb ldr r3, [r7, #8] + 800f6cc: 185b adds r3, r3, r1 + 800f6ce: 3230 adds r2, #48 ; 0x30 + 800f6d0: b2d2 uxtb r2, r2 + 800f6d2: 701a strb r2, [r3, #0] + 800f6d4: e00c b.n 800f6f0 + } + else + { + pbuf[2* idx] = (value >> 28) + 'A' - 10; + 800f6d6: 68fb ldr r3, [r7, #12] + 800f6d8: 0f1b lsrs r3, r3, #28 + 800f6da: b2da uxtb r2, r3 + 800f6dc: 2317 movs r3, #23 + 800f6de: 18fb adds r3, r7, r3 + 800f6e0: 781b ldrb r3, [r3, #0] + 800f6e2: 005b lsls r3, r3, #1 + 800f6e4: 0019 movs r1, r3 + 800f6e6: 68bb ldr r3, [r7, #8] + 800f6e8: 185b adds r3, r3, r1 + 800f6ea: 3237 adds r2, #55 ; 0x37 + 800f6ec: b2d2 uxtb r2, r2 + 800f6ee: 701a strb r2, [r3, #0] + } + + value = value << 4; + 800f6f0: 68fb ldr r3, [r7, #12] + 800f6f2: 011b lsls r3, r3, #4 + 800f6f4: 60fb str r3, [r7, #12] + + pbuf[ 2* idx + 1] = 0; + 800f6f6: 2117 movs r1, #23 + 800f6f8: 187b adds r3, r7, r1 + 800f6fa: 781b ldrb r3, [r3, #0] + 800f6fc: 005b lsls r3, r3, #1 + 800f6fe: 3301 adds r3, #1 + 800f700: 68ba ldr r2, [r7, #8] + 800f702: 18d3 adds r3, r2, r3 + 800f704: 2200 movs r2, #0 + 800f706: 701a strb r2, [r3, #0] + for( idx = 0 ; idx < len ; idx ++) + 800f708: 187b adds r3, r7, r1 + 800f70a: 781a ldrb r2, [r3, #0] + 800f70c: 187b adds r3, r7, r1 + 800f70e: 3201 adds r2, #1 + 800f710: 701a strb r2, [r3, #0] + 800f712: 2317 movs r3, #23 + 800f714: 18fa adds r2, r7, r3 + 800f716: 1dfb adds r3, r7, #7 + 800f718: 7812 ldrb r2, [r2, #0] + 800f71a: 781b ldrb r3, [r3, #0] + 800f71c: 429a cmp r2, r3 + 800f71e: d3c8 bcc.n 800f6b2 + } +} + 800f720: 46c0 nop ; (mov r8, r8) + 800f722: 46bd mov sp, r7 + 800f724: b006 add sp, #24 + 800f726: bd80 pop {r7, pc} + +0800f728 : +static int ecm_tx_remaining; +static int ecm_tx_busy; +static int copy_length; + +void usb_ecm_recv_renew(void) +{ + 800f728: b590 push {r4, r7, lr} + 800f72a: b083 sub sp, #12 + 800f72c: af00 add r7, sp, #0 + USBD_StatusTypeDef outcome; + + outcome = USBD_LL_PrepareReceive(registered_pdev, ECM_DATA_OUT_EP, ecm_rx_buffer + ecm_rx_index, ECM_DATA_OUT_SZ); + 800f72e: 4b0c ldr r3, [pc, #48] ; (800f760 ) + 800f730: 6818 ldr r0, [r3, #0] + 800f732: 4b0c ldr r3, [pc, #48] ; (800f764 ) + 800f734: 681b ldr r3, [r3, #0] + 800f736: 001a movs r2, r3 + 800f738: 4b0b ldr r3, [pc, #44] ; (800f768 ) + 800f73a: 18d2 adds r2, r2, r3 + 800f73c: 1dfc adds r4, r7, #7 + 800f73e: 2340 movs r3, #64 ; 0x40 + 800f740: 2103 movs r1, #3 + 800f742: f7ff f80d bl 800e760 + 800f746: 0003 movs r3, r0 + 800f748: 7023 strb r3, [r4, #0] + + OutboundTransferNeedsRenewal = (USBD_OK != outcome); /* set if the HAL was busy so that we know to retry it */ + 800f74a: 1dfb adds r3, r7, #7 + 800f74c: 781b ldrb r3, [r3, #0] + 800f74e: 1e5a subs r2, r3, #1 + 800f750: 4193 sbcs r3, r2 + 800f752: b2da uxtb r2, r3 + 800f754: 4b05 ldr r3, [pc, #20] ; (800f76c ) + 800f756: 701a strb r2, [r3, #0] +} + 800f758: 46c0 nop ; (mov r8, r8) + 800f75a: 46bd mov sp, r7 + 800f75c: b003 add sp, #12 + 800f75e: bd90 pop {r4, r7, pc} + 800f760: 200024cc .word 0x200024cc + 800f764: 200028d8 .word 0x200028d8 + 800f768: 200024d0 .word 0x200024d0 + 800f76c: 200028dd .word 0x200028dd + +0800f770 : + +static uint8_t USBD_ECM_Init (USBD_HandleTypeDef *pdev, uint8_t cfgidx) +{ + 800f770: b580 push {r7, lr} + 800f772: b082 sub sp, #8 + 800f774: af00 add r7, sp, #0 + 800f776: 6078 str r0, [r7, #4] + 800f778: 000a movs r2, r1 + 800f77a: 1cfb adds r3, r7, #3 + 800f77c: 701a strb r2, [r3, #0] + registered_pdev = pdev; + 800f77e: 4b14 ldr r3, [pc, #80] ; (800f7d0 ) + 800f780: 687a ldr r2, [r7, #4] + 800f782: 601a str r2, [r3, #0] + + /* Open EP IN */ + USBD_LL_OpenEP(pdev, ECM_DATA_IN_EP, USBD_EP_TYPE_BULK, ECM_DATA_IN_SZ); + 800f784: 6878 ldr r0, [r7, #4] + 800f786: 2340 movs r3, #64 ; 0x40 + 800f788: 2202 movs r2, #2 + 800f78a: 2182 movs r1, #130 ; 0x82 + 800f78c: f7fe ff1a bl 800e5c4 + + /* Open EP OUT */ + USBD_LL_OpenEP(pdev, ECM_DATA_OUT_EP, USBD_EP_TYPE_BULK, ECM_DATA_OUT_SZ); + 800f790: 6878 ldr r0, [r7, #4] + 800f792: 2340 movs r3, #64 ; 0x40 + 800f794: 2202 movs r2, #2 + 800f796: 2103 movs r1, #3 + 800f798: f7fe ff14 bl 800e5c4 + + /* Open Command IN EP */ + USBD_LL_OpenEP(pdev, ECM_NOTIFICATION_IN_EP, USBD_EP_TYPE_INTR, ECM_NOTIFICATION_IN_SZ); + 800f79c: 6878 ldr r0, [r7, #4] + 800f79e: 2340 movs r3, #64 ; 0x40 + 800f7a0: 2203 movs r2, #3 + 800f7a2: 2181 movs r1, #129 ; 0x81 + 800f7a4: f7fe ff0e bl 800e5c4 + + usb_ecm_recv_renew(); + 800f7a8: f7ff ffbe bl 800f728 + can_xmit = true; + 800f7ac: 4b09 ldr r3, [pc, #36] ; (800f7d4 ) + 800f7ae: 2201 movs r2, #1 + 800f7b0: 701a strb r2, [r3, #0] + OutboundTransferNeedsRenewal = false; + 800f7b2: 4b09 ldr r3, [pc, #36] ; (800f7d8 ) + 800f7b4: 2200 movs r2, #0 + 800f7b6: 701a strb r2, [r3, #0] + ecm_tx_busy = 0; + 800f7b8: 4b08 ldr r3, [pc, #32] ; (800f7dc ) + 800f7ba: 2200 movs r2, #0 + 800f7bc: 601a str r2, [r3, #0] + ecm_tx_remaining = 0; + 800f7be: 4b08 ldr r3, [pc, #32] ; (800f7e0 ) + 800f7c0: 2200 movs r2, #0 + 800f7c2: 601a str r2, [r3, #0] + + return USBD_OK; + 800f7c4: 2300 movs r3, #0 +} + 800f7c6: 0018 movs r0, r3 + 800f7c8: 46bd mov sp, r7 + 800f7ca: b002 add sp, #8 + 800f7cc: bd80 pop {r7, pc} + 800f7ce: 46c0 nop ; (mov r8, r8) + 800f7d0: 200024cc .word 0x200024cc + 800f7d4: 200028dc .word 0x200028dc + 800f7d8: 200028dd .word 0x200028dd + 800f7dc: 200028e8 .word 0x200028e8 + 800f7e0: 200028e4 .word 0x200028e4 + +0800f7e4 : + +static uint8_t USBD_ECM_DeInit (USBD_HandleTypeDef *pdev, uint8_t cfgidx) +{ + 800f7e4: b580 push {r7, lr} + 800f7e6: b082 sub sp, #8 + 800f7e8: af00 add r7, sp, #0 + 800f7ea: 6078 str r0, [r7, #4] + 800f7ec: 000a movs r2, r1 + 800f7ee: 1cfb adds r3, r7, #3 + 800f7f0: 701a strb r2, [r3, #0] + registered_pdev = NULL; + 800f7f2: 4b0d ldr r3, [pc, #52] ; (800f828 ) + 800f7f4: 2200 movs r2, #0 + 800f7f6: 601a str r2, [r3, #0] + + /* Close EP IN */ + USBD_LL_CloseEP(pdev, ECM_DATA_IN_EP); + 800f7f8: 687b ldr r3, [r7, #4] + 800f7fa: 2182 movs r1, #130 ; 0x82 + 800f7fc: 0018 movs r0, r3 + 800f7fe: f7fe ff03 bl 800e608 + + /* Close EP OUT */ + USBD_LL_CloseEP(pdev, ECM_DATA_OUT_EP); + 800f802: 687b ldr r3, [r7, #4] + 800f804: 2103 movs r1, #3 + 800f806: 0018 movs r0, r3 + 800f808: f7fe fefe bl 800e608 + + /* Close Command IN EP */ + USBD_LL_CloseEP(pdev, ECM_NOTIFICATION_IN_EP); + 800f80c: 687b ldr r3, [r7, #4] + 800f80e: 2181 movs r1, #129 ; 0x81 + 800f810: 0018 movs r0, r3 + 800f812: f7fe fef9 bl 800e608 + + can_xmit = false; + 800f816: 4b05 ldr r3, [pc, #20] ; (800f82c ) + 800f818: 2200 movs r2, #0 + 800f81a: 701a strb r2, [r3, #0] + + return USBD_OK; + 800f81c: 2300 movs r3, #0 +} + 800f81e: 0018 movs r0, r3 + 800f820: 46bd mov sp, r7 + 800f822: b002 add sp, #8 + 800f824: bd80 pop {r7, pc} + 800f826: 46c0 nop ; (mov r8, r8) + 800f828: 200024cc .word 0x200024cc + 800f82c: 200028dc .word 0x200028dc + +0800f830 : + +static uint8_t USBD_ECM_Setup (USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) +{ + 800f830: b580 push {r7, lr} + 800f832: b082 sub sp, #8 + 800f834: af00 add r7, sp, #0 + 800f836: 6078 str r0, [r7, #4] + 800f838: 6039 str r1, [r7, #0] + if (0x43 /* SET_ETHERNET_PACKET_FILTER */ == req->bRequest) + 800f83a: 683b ldr r3, [r7, #0] + 800f83c: 785b ldrb r3, [r3, #1] + 800f83e: 2b43 cmp r3, #67 ; 0x43 + 800f840: d109 bne.n 800f856 + { + notify.wIndex = req->wIndex; + 800f842: 683b ldr r3, [r7, #0] + 800f844: 889a ldrh r2, [r3, #4] + 800f846: 4b06 ldr r3, [pc, #24] ; (800f860 ) + 800f848: 809a strh r2, [r3, #4] + USBD_LL_Transmit(pdev, ECM_NOTIFICATION_IN_EP, (uint8_t *)¬ify, sizeof(notify)); + 800f84a: 4a05 ldr r2, [pc, #20] ; (800f860 ) + 800f84c: 6878 ldr r0, [r7, #4] + 800f84e: 2308 movs r3, #8 + 800f850: 2181 movs r1, #129 ; 0x81 + 800f852: f7fe ff5c bl 800e70e + } + + return USBD_OK; + 800f856: 2300 movs r3, #0 +} + 800f858: 0018 movs r0, r3 + 800f85a: 46bd mov sp, r7 + 800f85c: b002 add sp, #8 + 800f85e: bd80 pop {r7, pc} + 800f860: 20000094 .word 0x20000094 + +0800f864 : + +static void ecm_incoming_attempt(void) +{ + 800f864: b580 push {r7, lr} + 800f866: b082 sub sp, #8 + 800f868: af00 add r7, sp, #0 + int chunk_size; + + if (!ecm_tx_remaining || ecm_tx_busy) + 800f86a: 4b16 ldr r3, [pc, #88] ; (800f8c4 ) + 800f86c: 681b ldr r3, [r3, #0] + 800f86e: 2b00 cmp r3, #0 + 800f870: d024 beq.n 800f8bc + 800f872: 4b15 ldr r3, [pc, #84] ; (800f8c8 ) + 800f874: 681b ldr r3, [r3, #0] + 800f876: 2b00 cmp r3, #0 + 800f878: d120 bne.n 800f8bc + return; + + chunk_size = ecm_tx_remaining; + 800f87a: 4b12 ldr r3, [pc, #72] ; (800f8c4 ) + 800f87c: 681b ldr r3, [r3, #0] + 800f87e: 607b str r3, [r7, #4] + if (chunk_size > ECM_DATA_IN_SZ) + 800f880: 687b ldr r3, [r7, #4] + 800f882: 2b40 cmp r3, #64 ; 0x40 + 800f884: dd01 ble.n 800f88a + chunk_size = ECM_DATA_IN_SZ; + 800f886: 2340 movs r3, #64 ; 0x40 + 800f888: 607b str r3, [r7, #4] + + /* ST stack always returns a success code, so reading the return value is pointless */ + USBD_LL_Transmit(registered_pdev, ECM_DATA_IN_EP, ecm_tx_ptr, chunk_size); + 800f88a: 4b10 ldr r3, [pc, #64] ; (800f8cc ) + 800f88c: 6818 ldr r0, [r3, #0] + 800f88e: 4b10 ldr r3, [pc, #64] ; (800f8d0 ) + 800f890: 681a ldr r2, [r3, #0] + 800f892: 687b ldr r3, [r7, #4] + 800f894: b29b uxth r3, r3 + 800f896: 2182 movs r1, #130 ; 0x82 + 800f898: f7fe ff39 bl 800e70e + + ecm_tx_ptr += chunk_size; + 800f89c: 4b0c ldr r3, [pc, #48] ; (800f8d0 ) + 800f89e: 681a ldr r2, [r3, #0] + 800f8a0: 687b ldr r3, [r7, #4] + 800f8a2: 18d2 adds r2, r2, r3 + 800f8a4: 4b0a ldr r3, [pc, #40] ; (800f8d0 ) + 800f8a6: 601a str r2, [r3, #0] + ecm_tx_remaining -= chunk_size; + 800f8a8: 4b06 ldr r3, [pc, #24] ; (800f8c4 ) + 800f8aa: 681a ldr r2, [r3, #0] + 800f8ac: 687b ldr r3, [r7, #4] + 800f8ae: 1ad2 subs r2, r2, r3 + 800f8b0: 4b04 ldr r3, [pc, #16] ; (800f8c4 ) + 800f8b2: 601a str r2, [r3, #0] + ecm_tx_busy = 1; + 800f8b4: 4b04 ldr r3, [pc, #16] ; (800f8c8 ) + 800f8b6: 2201 movs r2, #1 + 800f8b8: 601a str r2, [r3, #0] + 800f8ba: e000 b.n 800f8be + return; + 800f8bc: 46c0 nop ; (mov r8, r8) +} + 800f8be: 46bd mov sp, r7 + 800f8c0: b002 add sp, #8 + 800f8c2: bd80 pop {r7, pc} + 800f8c4: 200028e4 .word 0x200028e4 + 800f8c8: 200028e8 .word 0x200028e8 + 800f8cc: 200024cc .word 0x200024cc + 800f8d0: 200028e0 .word 0x200028e0 + +0800f8d4 : + +static uint8_t USBD_ECM_DataIn (USBD_HandleTypeDef *pdev, uint8_t epnum) +{ + 800f8d4: b580 push {r7, lr} + 800f8d6: b082 sub sp, #8 + 800f8d8: af00 add r7, sp, #0 + 800f8da: 6078 str r0, [r7, #4] + 800f8dc: 000a movs r2, r1 + 800f8de: 1cfb adds r3, r7, #3 + 800f8e0: 701a strb r2, [r3, #0] + if (ECM_DATA_IN_EP == (epnum | 0x80)) + 800f8e2: 1cfb adds r3, r7, #3 + 800f8e4: 781b ldrb r3, [r3, #0] + 800f8e6: 2280 movs r2, #128 ; 0x80 + 800f8e8: 4252 negs r2, r2 + 800f8ea: 4313 orrs r3, r2 + 800f8ec: b2db uxtb r3, r3 + 800f8ee: 2b82 cmp r3, #130 ; 0x82 + 800f8f0: d10b bne.n 800f90a + { + ecm_tx_busy = 0; + 800f8f2: 4b08 ldr r3, [pc, #32] ; (800f914 ) + 800f8f4: 2200 movs r2, #0 + 800f8f6: 601a str r2, [r3, #0] + if (0 == ecm_tx_remaining) + 800f8f8: 4b07 ldr r3, [pc, #28] ; (800f918 ) + 800f8fa: 681b ldr r3, [r3, #0] + 800f8fc: 2b00 cmp r3, #0 + 800f8fe: d102 bne.n 800f906 + can_xmit = true; + 800f900: 4b06 ldr r3, [pc, #24] ; (800f91c ) + 800f902: 2201 movs r2, #1 + 800f904: 701a strb r2, [r3, #0] + ecm_incoming_attempt(); + 800f906: f7ff ffad bl 800f864 + } + + return USBD_OK; + 800f90a: 2300 movs r3, #0 +} + 800f90c: 0018 movs r0, r3 + 800f90e: 46bd mov sp, r7 + 800f910: b002 add sp, #8 + 800f912: bd80 pop {r7, pc} + 800f914: 200028e8 .word 0x200028e8 + 800f918: 200028e4 .word 0x200028e4 + 800f91c: 200028dc .word 0x200028dc + +0800f920 : + +static uint8_t USBD_ECM_DataOut (USBD_HandleTypeDef *pdev, uint8_t epnum) +{ + 800f920: b580 push {r7, lr} + 800f922: b084 sub sp, #16 + 800f924: af00 add r7, sp, #0 + 800f926: 6078 str r0, [r7, #4] + 800f928: 000a movs r2, r1 + 800f92a: 1cfb adds r3, r7, #3 + 800f92c: 701a strb r2, [r3, #0] + uint32_t RxLength; + + if (ECM_DATA_OUT_EP != epnum) + 800f92e: 1cfb adds r3, r7, #3 + 800f930: 781b ldrb r3, [r3, #0] + 800f932: 2b03 cmp r3, #3 + 800f934: d001 beq.n 800f93a + return USBD_OK; + 800f936: 2300 movs r3, #0 + 800f938: e021 b.n 800f97e + + /* Get the received data length */ + RxLength = USBD_LL_GetRxDataSize (pdev, epnum); + 800f93a: 1cfb adds r3, r7, #3 + 800f93c: 781a ldrb r2, [r3, #0] + 800f93e: 687b ldr r3, [r7, #4] + 800f940: 0011 movs r1, r2 + 800f942: 0018 movs r0, r3 + 800f944: f7fe ff35 bl 800e7b2 + 800f948: 0003 movs r3, r0 + 800f94a: 60fb str r3, [r7, #12] + + ecm_rx_index += RxLength; + 800f94c: 4b0e ldr r3, [pc, #56] ; (800f988 ) + 800f94e: 681b ldr r3, [r3, #0] + 800f950: 001a movs r2, r3 + 800f952: 68fb ldr r3, [r7, #12] + 800f954: 18d3 adds r3, r2, r3 + 800f956: 001a movs r2, r3 + 800f958: 4b0b ldr r3, [pc, #44] ; (800f988 ) + 800f95a: 601a str r2, [r3, #0] + + if (RxLength < ECM_DATA_OUT_SZ) + 800f95c: 68fb ldr r3, [r7, #12] + 800f95e: 2b3f cmp r3, #63 ; 0x3f + 800f960: d80a bhi.n 800f978 + { + usb_ecm_recv_callback(ecm_rx_buffer, ecm_rx_index); + 800f962: 4b09 ldr r3, [pc, #36] ; (800f988 ) + 800f964: 681a ldr r2, [r3, #0] + 800f966: 4b09 ldr r3, [pc, #36] ; (800f98c ) + 800f968: 0011 movs r1, r2 + 800f96a: 0018 movs r0, r3 + 800f96c: f7fe fb0a bl 800df84 + ecm_rx_index = 0; + 800f970: 4b05 ldr r3, [pc, #20] ; (800f988 ) + 800f972: 2200 movs r2, #0 + 800f974: 601a str r2, [r3, #0] + 800f976: e001 b.n 800f97c + } + else + { + /* Initiate next USB packet transfer */ + usb_ecm_recv_renew(); + 800f978: f7ff fed6 bl 800f728 + } + + return USBD_OK; + 800f97c: 2300 movs r3, #0 +} + 800f97e: 0018 movs r0, r3 + 800f980: 46bd mov sp, r7 + 800f982: b004 add sp, #16 + 800f984: bd80 pop {r7, pc} + 800f986: 46c0 nop ; (mov r8, r8) + 800f988: 200028d8 .word 0x200028d8 + 800f98c: 200024d0 .word 0x200024d0 + +0800f990 : + +static uint8_t USBD_ECM_SOF (USBD_HandleTypeDef *pdev) +{ + 800f990: b580 push {r7, lr} + 800f992: b082 sub sp, #8 + 800f994: af00 add r7, sp, #0 + 800f996: 6078 str r0, [r7, #4] + /* mop up for any failed USBD_LL_PrepareReceive() call */ + if (OutboundTransferNeedsRenewal) + 800f998: 4b11 ldr r3, [pc, #68] ; (800f9e0 ) + 800f99a: 781b ldrb r3, [r3, #0] + 800f99c: 2b00 cmp r3, #0 + 800f99e: d001 beq.n 800f9a4 + usb_ecm_recv_renew(); + 800f9a0: f7ff fec2 bl 800f728 + + if (ecm_tx_busy) + 800f9a4: 4b0f ldr r3, [pc, #60] ; (800f9e4 ) + 800f9a6: 681b ldr r3, [r3, #0] + 800f9a8: 2b00 cmp r3, #0 + 800f9aa: d012 beq.n 800f9d2 + { + /* ugly hack for ST stack sometimes not providing the DataOut callback */ + if (++ecm_tx_busy > 32) + 800f9ac: 4b0d ldr r3, [pc, #52] ; (800f9e4 ) + 800f9ae: 681b ldr r3, [r3, #0] + 800f9b0: 1c5a adds r2, r3, #1 + 800f9b2: 4b0c ldr r3, [pc, #48] ; (800f9e4 ) + 800f9b4: 601a str r2, [r3, #0] + 800f9b6: 4b0b ldr r3, [pc, #44] ; (800f9e4 ) + 800f9b8: 681b ldr r3, [r3, #0] + 800f9ba: 2b20 cmp r3, #32 + 800f9bc: dd09 ble.n 800f9d2 + { + ecm_tx_busy = 0; + 800f9be: 4b09 ldr r3, [pc, #36] ; (800f9e4 ) + 800f9c0: 2200 movs r2, #0 + 800f9c2: 601a str r2, [r3, #0] + if (0 == ecm_tx_remaining) + 800f9c4: 4b08 ldr r3, [pc, #32] ; (800f9e8 ) + 800f9c6: 681b ldr r3, [r3, #0] + 800f9c8: 2b00 cmp r3, #0 + 800f9ca: d102 bne.n 800f9d2 + can_xmit = true; + 800f9cc: 4b07 ldr r3, [pc, #28] ; (800f9ec ) + 800f9ce: 2201 movs r2, #1 + 800f9d0: 701a strb r2, [r3, #0] + } + } + + ecm_incoming_attempt(); + 800f9d2: f7ff ff47 bl 800f864 + + return USBD_OK; + 800f9d6: 2300 movs r3, #0 +} + 800f9d8: 0018 movs r0, r3 + 800f9da: 46bd mov sp, r7 + 800f9dc: b002 add sp, #8 + 800f9de: bd80 pop {r7, pc} + 800f9e0: 200028dd .word 0x200028dd + 800f9e4: 200028e8 .word 0x200028e8 + 800f9e8: 200028e4 .word 0x200028e4 + 800f9ec: 200028dc .word 0x200028dc + +0800f9f0 : + +static uint8_t USBD_ECM_EP0_RxReady (USBD_HandleTypeDef *pdev) +{ + 800f9f0: b580 push {r7, lr} + 800f9f2: b082 sub sp, #8 + 800f9f4: af00 add r7, sp, #0 + 800f9f6: 6078 str r0, [r7, #4] + return USBD_OK; + 800f9f8: 2300 movs r3, #0 +} + 800f9fa: 0018 movs r0, r3 + 800f9fc: 46bd mov sp, r7 + 800f9fe: b002 add sp, #8 + 800fa00: bd80 pop {r7, pc} + ... + +0800fa04 : + +static const uint8_t *USBD_ECM_GetFSCfgDesc (uint16_t *length) +{ + 800fa04: b580 push {r7, lr} + 800fa06: b082 sub sp, #8 + 800fa08: af00 add r7, sp, #0 + 800fa0a: 6078 str r0, [r7, #4] + *length = USBD_CfgFSDesc_len; + 800fa0c: 4b04 ldr r3, [pc, #16] ; (800fa20 ) + 800fa0e: 881a ldrh r2, [r3, #0] + 800fa10: 687b ldr r3, [r7, #4] + 800fa12: 801a strh r2, [r3, #0] + return USBD_CfgFSDesc_pnt; + 800fa14: 4b03 ldr r3, [pc, #12] ; (800fa24 ) + 800fa16: 681b ldr r3, [r3, #0] +} + 800fa18: 0018 movs r0, r3 + 800fa1a: 46bd mov sp, r7 + 800fa1c: b002 add sp, #8 + 800fa1e: bd80 pop {r7, pc} + 800fa20: 0800fe74 .word 0x0800fe74 + 800fa24: 0800fe70 .word 0x0800fe70 + +0800fa28 : + +uint8_t USBD_ECM_RegisterInterface(USBD_HandleTypeDef *pdev) +{ + 800fa28: b580 push {r7, lr} + 800fa2a: b082 sub sp, #8 + 800fa2c: af00 add r7, sp, #0 + 800fa2e: 6078 str r0, [r7, #4] + unsigned index; + + return USBD_OK; + 800fa30: 2300 movs r3, #0 +} + 800fa32: 0018 movs r0, r3 + 800fa34: 46bd mov sp, r7 + 800fa36: b002 add sp, #8 + 800fa38: bd80 pop {r7, pc} + +0800fa3a : + +void USBD_ECM_PMAConfig(PCD_HandleTypeDef *hpcd, uint32_t *pma_address) +{ + 800fa3a: b580 push {r7, lr} + 800fa3c: b082 sub sp, #8 + 800fa3e: af00 add r7, sp, #0 + 800fa40: 6078 str r0, [r7, #4] + 800fa42: 6039 str r1, [r7, #0] + /* allocate PMA memory for all endpoints associated with ECM */ + HAL_PCDEx_PMAConfig(hpcd, ECM_DATA_IN_EP, PCD_SNG_BUF, *pma_address); + 800fa44: 683b ldr r3, [r7, #0] + 800fa46: 681b ldr r3, [r3, #0] + 800fa48: 6878 ldr r0, [r7, #4] + 800fa4a: 2200 movs r2, #0 + 800fa4c: 2182 movs r1, #130 ; 0x82 + 800fa4e: f7f2 f83b bl 8001ac8 + *pma_address += ECM_DATA_IN_SZ; + 800fa52: 683b ldr r3, [r7, #0] + 800fa54: 681b ldr r3, [r3, #0] + 800fa56: 3340 adds r3, #64 ; 0x40 + 800fa58: 001a movs r2, r3 + 800fa5a: 683b ldr r3, [r7, #0] + 800fa5c: 601a str r2, [r3, #0] + HAL_PCDEx_PMAConfig(hpcd, ECM_DATA_OUT_EP, PCD_SNG_BUF, *pma_address); + 800fa5e: 683b ldr r3, [r7, #0] + 800fa60: 681b ldr r3, [r3, #0] + 800fa62: 6878 ldr r0, [r7, #4] + 800fa64: 2200 movs r2, #0 + 800fa66: 2103 movs r1, #3 + 800fa68: f7f2 f82e bl 8001ac8 + *pma_address += ECM_DATA_OUT_SZ; + 800fa6c: 683b ldr r3, [r7, #0] + 800fa6e: 681b ldr r3, [r3, #0] + 800fa70: 3340 adds r3, #64 ; 0x40 + 800fa72: 001a movs r2, r3 + 800fa74: 683b ldr r3, [r7, #0] + 800fa76: 601a str r2, [r3, #0] + HAL_PCDEx_PMAConfig(hpcd, ECM_NOTIFICATION_IN_EP, PCD_SNG_BUF, *pma_address); + 800fa78: 683b ldr r3, [r7, #0] + 800fa7a: 681b ldr r3, [r3, #0] + 800fa7c: 6878 ldr r0, [r7, #4] + 800fa7e: 2200 movs r2, #0 + 800fa80: 2181 movs r1, #129 ; 0x81 + 800fa82: f7f2 f821 bl 8001ac8 + *pma_address += ECM_NOTIFICATION_IN_SZ; + 800fa86: 683b ldr r3, [r7, #0] + 800fa88: 681b ldr r3, [r3, #0] + 800fa8a: 3340 adds r3, #64 ; 0x40 + 800fa8c: 001a movs r2, r3 + 800fa8e: 683b ldr r3, [r7, #0] + 800fa90: 601a str r2, [r3, #0] +} + 800fa92: 46c0 nop ; (mov r8, r8) + 800fa94: 46bd mov sp, r7 + 800fa96: b002 add sp, #8 + 800fa98: bd80 pop {r7, pc} + ... + +0800fa9c : + +bool usb_ecm_can_xmit(void) +{ + 800fa9c: b580 push {r7, lr} + 800fa9e: b082 sub sp, #8 + 800faa0: af00 add r7, sp, #0 + __ASM volatile ("cpsid i" : : : "memory"); + 800faa2: b672 cpsid i + bool outcome; + + __disable_irq(); + outcome = can_xmit; + 800faa4: 1dfb adds r3, r7, #7 + 800faa6: 4a05 ldr r2, [pc, #20] ; (800fabc ) + 800faa8: 7812 ldrb r2, [r2, #0] + 800faaa: 701a strb r2, [r3, #0] + __ASM volatile ("cpsie i" : : : "memory"); + 800faac: b662 cpsie i + __enable_irq(); + + return outcome; + 800faae: 1dfb adds r3, r7, #7 + 800fab0: 781b ldrb r3, [r3, #0] +} + 800fab2: 0018 movs r0, r3 + 800fab4: 46bd mov sp, r7 + 800fab6: b002 add sp, #8 + 800fab8: bd80 pop {r7, pc} + 800faba: 46c0 nop ; (mov r8, r8) + 800fabc: 200028dc .word 0x200028dc + +0800fac0 : + +void usb_ecm_xmit_packet(struct pbuf *p) +{ + 800fac0: b580 push {r7, lr} + 800fac2: b086 sub sp, #24 + 800fac4: af00 add r7, sp, #0 + 800fac6: 6078 str r0, [r7, #4] + struct pbuf *q; + int packet_size; + uint8_t *data; + + if (!registered_pdev || !can_xmit) + 800fac8: 4b1f ldr r3, [pc, #124] ; (800fb48 ) + 800faca: 681b ldr r3, [r3, #0] + 800facc: 2b00 cmp r3, #0 + 800face: d037 beq.n 800fb40 + 800fad0: 4b1e ldr r3, [pc, #120] ; (800fb4c ) + 800fad2: 781b ldrb r3, [r3, #0] + 800fad4: 2201 movs r2, #1 + 800fad6: 4053 eors r3, r2 + 800fad8: b2db uxtb r3, r3 + 800fada: 2b00 cmp r3, #0 + 800fadc: d130 bne.n 800fb40 + return; + + data = ecm_tx_buffer; + 800fade: 4b1c ldr r3, [pc, #112] ; (800fb50 ) + 800fae0: 60fb str r3, [r7, #12] + packet_size = 0; + 800fae2: 2300 movs r3, #0 + 800fae4: 613b str r3, [r7, #16] + for(q = p; q != NULL; q = q->next) + 800fae6: 687b ldr r3, [r7, #4] + 800fae8: 617b str r3, [r7, #20] + 800faea: e017 b.n 800fb1c + { + memcpy(data, q->payload, q->len); + 800faec: 697b ldr r3, [r7, #20] + 800faee: 6859 ldr r1, [r3, #4] + 800faf0: 697b ldr r3, [r7, #20] + 800faf2: 895b ldrh r3, [r3, #10] + 800faf4: 001a movs r2, r3 + 800faf6: 68fb ldr r3, [r7, #12] + 800faf8: 0018 movs r0, r3 + 800fafa: f000 f8d2 bl 800fca2 + data += q->len; + 800fafe: 697b ldr r3, [r7, #20] + 800fb00: 895b ldrh r3, [r3, #10] + 800fb02: 001a movs r2, r3 + 800fb04: 68fb ldr r3, [r7, #12] + 800fb06: 189b adds r3, r3, r2 + 800fb08: 60fb str r3, [r7, #12] + packet_size += q->len; + 800fb0a: 697b ldr r3, [r7, #20] + 800fb0c: 895b ldrh r3, [r3, #10] + 800fb0e: 001a movs r2, r3 + 800fb10: 693b ldr r3, [r7, #16] + 800fb12: 189b adds r3, r3, r2 + 800fb14: 613b str r3, [r7, #16] + for(q = p; q != NULL; q = q->next) + 800fb16: 697b ldr r3, [r7, #20] + 800fb18: 681b ldr r3, [r3, #0] + 800fb1a: 617b str r3, [r7, #20] + 800fb1c: 697b ldr r3, [r7, #20] + 800fb1e: 2b00 cmp r3, #0 + 800fb20: d1e4 bne.n 800faec + __ASM volatile ("cpsid i" : : : "memory"); + 800fb22: b672 cpsid i + } + + __disable_irq(); + can_xmit = false; + 800fb24: 4b09 ldr r3, [pc, #36] ; (800fb4c ) + 800fb26: 2200 movs r2, #0 + 800fb28: 701a strb r2, [r3, #0] + ecm_tx_ptr = ecm_tx_buffer; + 800fb2a: 4b0a ldr r3, [pc, #40] ; (800fb54 ) + 800fb2c: 4a08 ldr r2, [pc, #32] ; (800fb50 ) + 800fb2e: 601a str r2, [r3, #0] + ecm_tx_remaining = packet_size; + 800fb30: 4b09 ldr r3, [pc, #36] ; (800fb58 ) + 800fb32: 693a ldr r2, [r7, #16] + 800fb34: 601a str r2, [r3, #0] + copy_length = packet_size; + 800fb36: 4b09 ldr r3, [pc, #36] ; (800fb5c ) + 800fb38: 693a ldr r2, [r7, #16] + 800fb3a: 601a str r2, [r3, #0] + __ASM volatile ("cpsie i" : : : "memory"); + 800fb3c: b662 cpsie i + 800fb3e: e000 b.n 800fb42 + return; + 800fb40: 46c0 nop ; (mov r8, r8) + __enable_irq(); +} + 800fb42: 46bd mov sp, r7 + 800fb44: b006 add sp, #24 + 800fb46: bd80 pop {r7, pc} + 800fb48: 200024cc .word 0x200024cc + 800fb4c: 200028dc .word 0x200028dc + 800fb50: 200026d4 .word 0x200026d4 + 800fb54: 200028e0 .word 0x200028e0 + 800fb58: 200028e4 .word 0x200028e4 + 800fb5c: 200028ec .word 0x200028ec + +0800fb60 : +* @retval status +*/ +USBD_StatusTypeDef USBD_CtlSendData (USBD_HandleTypeDef *pdev, + uint8_t *pbuf, + uint16_t len) +{ + 800fb60: b580 push {r7, lr} + 800fb62: b084 sub sp, #16 + 800fb64: af00 add r7, sp, #0 + 800fb66: 60f8 str r0, [r7, #12] + 800fb68: 60b9 str r1, [r7, #8] + 800fb6a: 1dbb adds r3, r7, #6 + 800fb6c: 801a strh r2, [r3, #0] + /* Set EP0 State */ + pdev->ep0_state = USBD_EP0_DATA_IN; + 800fb6e: 68fa ldr r2, [r7, #12] + 800fb70: 23fa movs r3, #250 ; 0xfa + 800fb72: 005b lsls r3, r3, #1 + 800fb74: 2102 movs r1, #2 + 800fb76: 50d1 str r1, [r2, r3] + pdev->ep_in[0].total_length = len; + 800fb78: 1dbb adds r3, r7, #6 + 800fb7a: 881a ldrh r2, [r3, #0] + 800fb7c: 68fb ldr r3, [r7, #12] + 800fb7e: 619a str r2, [r3, #24] + pdev->ep_in[0].rem_length = len; + 800fb80: 1dbb adds r3, r7, #6 + 800fb82: 881a ldrh r2, [r3, #0] + 800fb84: 68fb ldr r3, [r7, #12] + 800fb86: 61da str r2, [r3, #28] + /* Start the transfer */ + USBD_LL_Transmit (pdev, 0x00, pbuf, len); + 800fb88: 1dbb adds r3, r7, #6 + 800fb8a: 881b ldrh r3, [r3, #0] + 800fb8c: 68ba ldr r2, [r7, #8] + 800fb8e: 68f8 ldr r0, [r7, #12] + 800fb90: 2100 movs r1, #0 + 800fb92: f7fe fdbc bl 800e70e + + return USBD_OK; + 800fb96: 2300 movs r3, #0 +} + 800fb98: 0018 movs r0, r3 + 800fb9a: 46bd mov sp, r7 + 800fb9c: b004 add sp, #16 + 800fb9e: bd80 pop {r7, pc} + +0800fba0 : +* @retval status +*/ +USBD_StatusTypeDef USBD_CtlContinueSendData (USBD_HandleTypeDef *pdev, + uint8_t *pbuf, + uint16_t len) +{ + 800fba0: b580 push {r7, lr} + 800fba2: b084 sub sp, #16 + 800fba4: af00 add r7, sp, #0 + 800fba6: 60f8 str r0, [r7, #12] + 800fba8: 60b9 str r1, [r7, #8] + 800fbaa: 1dbb adds r3, r7, #6 + 800fbac: 801a strh r2, [r3, #0] + /* Start the next transfer */ + USBD_LL_Transmit (pdev, 0x00, pbuf, len); + 800fbae: 1dbb adds r3, r7, #6 + 800fbb0: 881b ldrh r3, [r3, #0] + 800fbb2: 68ba ldr r2, [r7, #8] + 800fbb4: 68f8 ldr r0, [r7, #12] + 800fbb6: 2100 movs r1, #0 + 800fbb8: f7fe fda9 bl 800e70e + + return USBD_OK; + 800fbbc: 2300 movs r3, #0 +} + 800fbbe: 0018 movs r0, r3 + 800fbc0: 46bd mov sp, r7 + 800fbc2: b004 add sp, #16 + 800fbc4: bd80 pop {r7, pc} + +0800fbc6 : +* @retval status +*/ +USBD_StatusTypeDef USBD_CtlContinueRx (USBD_HandleTypeDef *pdev, + uint8_t *pbuf, + uint16_t len) +{ + 800fbc6: b580 push {r7, lr} + 800fbc8: b084 sub sp, #16 + 800fbca: af00 add r7, sp, #0 + 800fbcc: 60f8 str r0, [r7, #12] + 800fbce: 60b9 str r1, [r7, #8] + 800fbd0: 1dbb adds r3, r7, #6 + 800fbd2: 801a strh r2, [r3, #0] + + USBD_LL_PrepareReceive (pdev, + 800fbd4: 1dbb adds r3, r7, #6 + 800fbd6: 881b ldrh r3, [r3, #0] + 800fbd8: 68ba ldr r2, [r7, #8] + 800fbda: 68f8 ldr r0, [r7, #12] + 800fbdc: 2100 movs r1, #0 + 800fbde: f7fe fdbf bl 800e760 + 0, + pbuf, + len); + return USBD_OK; + 800fbe2: 2300 movs r3, #0 +} + 800fbe4: 0018 movs r0, r3 + 800fbe6: 46bd mov sp, r7 + 800fbe8: b004 add sp, #16 + 800fbea: bd80 pop {r7, pc} + +0800fbec : +* send zero lzngth packet on the ctl pipe +* @param pdev: device instance +* @retval status +*/ +USBD_StatusTypeDef USBD_CtlSendStatus (USBD_HandleTypeDef *pdev) +{ + 800fbec: b580 push {r7, lr} + 800fbee: b082 sub sp, #8 + 800fbf0: af00 add r7, sp, #0 + 800fbf2: 6078 str r0, [r7, #4] + + /* Set EP0 State */ + pdev->ep0_state = USBD_EP0_STATUS_IN; + 800fbf4: 687a ldr r2, [r7, #4] + 800fbf6: 23fa movs r3, #250 ; 0xfa + 800fbf8: 005b lsls r3, r3, #1 + 800fbfa: 2104 movs r1, #4 + 800fbfc: 50d1 str r1, [r2, r3] + + /* Start the transfer */ + USBD_LL_Transmit (pdev, 0x00, NULL, 0); + 800fbfe: 6878 ldr r0, [r7, #4] + 800fc00: 2300 movs r3, #0 + 800fc02: 2200 movs r2, #0 + 800fc04: 2100 movs r1, #0 + 800fc06: f7fe fd82 bl 800e70e + + return USBD_OK; + 800fc0a: 2300 movs r3, #0 +} + 800fc0c: 0018 movs r0, r3 + 800fc0e: 46bd mov sp, r7 + 800fc10: b002 add sp, #8 + 800fc12: bd80 pop {r7, pc} + +0800fc14 : +* receive zero lzngth packet on the ctl pipe +* @param pdev: device instance +* @retval status +*/ +USBD_StatusTypeDef USBD_CtlReceiveStatus (USBD_HandleTypeDef *pdev) +{ + 800fc14: b580 push {r7, lr} + 800fc16: b082 sub sp, #8 + 800fc18: af00 add r7, sp, #0 + 800fc1a: 6078 str r0, [r7, #4] + /* Set EP0 State */ + pdev->ep0_state = USBD_EP0_STATUS_OUT; + 800fc1c: 687a ldr r2, [r7, #4] + 800fc1e: 23fa movs r3, #250 ; 0xfa + 800fc20: 005b lsls r3, r3, #1 + 800fc22: 2105 movs r1, #5 + 800fc24: 50d1 str r1, [r2, r3] + + /* Start the transfer */ + USBD_LL_PrepareReceive ( pdev, + 800fc26: 6878 ldr r0, [r7, #4] + 800fc28: 2300 movs r3, #0 + 800fc2a: 2200 movs r2, #0 + 800fc2c: 2100 movs r1, #0 + 800fc2e: f7fe fd97 bl 800e760 + 0, + NULL, + 0); + + return USBD_OK; + 800fc32: 2300 movs r3, #0 +} + 800fc34: 0018 movs r0, r3 + 800fc36: 46bd mov sp, r7 + 800fc38: b002 add sp, #8 + 800fc3a: bd80 pop {r7, pc} + +0800fc3c <__libc_init_array>: + 800fc3c: b570 push {r4, r5, r6, lr} + 800fc3e: 2600 movs r6, #0 + 800fc40: 4d0c ldr r5, [pc, #48] ; (800fc74 <__libc_init_array+0x38>) + 800fc42: 4c0d ldr r4, [pc, #52] ; (800fc78 <__libc_init_array+0x3c>) + 800fc44: 1b64 subs r4, r4, r5 + 800fc46: 10a4 asrs r4, r4, #2 + 800fc48: 42a6 cmp r6, r4 + 800fc4a: d109 bne.n 800fc60 <__libc_init_array+0x24> + 800fc4c: 2600 movs r6, #0 + 800fc4e: f000 f839 bl 800fcc4 <_init> + 800fc52: 4d0a ldr r5, [pc, #40] ; (800fc7c <__libc_init_array+0x40>) + 800fc54: 4c0a ldr r4, [pc, #40] ; (800fc80 <__libc_init_array+0x44>) + 800fc56: 1b64 subs r4, r4, r5 + 800fc58: 10a4 asrs r4, r4, #2 + 800fc5a: 42a6 cmp r6, r4 + 800fc5c: d105 bne.n 800fc6a <__libc_init_array+0x2e> + 800fc5e: bd70 pop {r4, r5, r6, pc} + 800fc60: 00b3 lsls r3, r6, #2 + 800fc62: 58eb ldr r3, [r5, r3] + 800fc64: 4798 blx r3 + 800fc66: 3601 adds r6, #1 + 800fc68: e7ee b.n 800fc48 <__libc_init_array+0xc> + 800fc6a: 00b3 lsls r3, r6, #2 + 800fc6c: 58eb ldr r3, [r5, r3] + 800fc6e: 4798 blx r3 + 800fc70: 3601 adds r6, #1 + 800fc72: e7f2 b.n 800fc5a <__libc_init_array+0x1e> + 800fc74: 0800fea8 .word 0x0800fea8 + 800fc78: 0800fea8 .word 0x0800fea8 + 800fc7c: 0800fea8 .word 0x0800fea8 + 800fc80: 0800feac .word 0x0800feac + +0800fc84 : + 800fc84: b530 push {r4, r5, lr} + 800fc86: 2400 movs r4, #0 + 800fc88: 42a2 cmp r2, r4 + 800fc8a: d101 bne.n 800fc90 + 800fc8c: 2000 movs r0, #0 + 800fc8e: e005 b.n 800fc9c + 800fc90: 5d03 ldrb r3, [r0, r4] + 800fc92: 1c65 adds r5, r4, #1 + 800fc94: 5d0c ldrb r4, [r1, r4] + 800fc96: 42a3 cmp r3, r4 + 800fc98: d001 beq.n 800fc9e + 800fc9a: 1b18 subs r0, r3, r4 + 800fc9c: bd30 pop {r4, r5, pc} + 800fc9e: 002c movs r4, r5 + 800fca0: e7f2 b.n 800fc88 + +0800fca2 : + 800fca2: 2300 movs r3, #0 + 800fca4: b510 push {r4, lr} + 800fca6: 429a cmp r2, r3 + 800fca8: d100 bne.n 800fcac + 800fcaa: bd10 pop {r4, pc} + 800fcac: 5ccc ldrb r4, [r1, r3] + 800fcae: 54c4 strb r4, [r0, r3] + 800fcb0: 3301 adds r3, #1 + 800fcb2: e7f8 b.n 800fca6 + +0800fcb4 : + 800fcb4: 0003 movs r3, r0 + 800fcb6: 1812 adds r2, r2, r0 + 800fcb8: 4293 cmp r3, r2 + 800fcba: d100 bne.n 800fcbe + 800fcbc: 4770 bx lr + 800fcbe: 7019 strb r1, [r3, #0] + 800fcc0: 3301 adds r3, #1 + 800fcc2: e7f9 b.n 800fcb8 + +0800fcc4 <_init>: + 800fcc4: b5f8 push {r3, r4, r5, r6, r7, lr} + 800fcc6: 46c0 nop ; (mov r8, r8) + 800fcc8: bcf8 pop {r3, r4, r5, r6, r7} + 800fcca: bc08 pop {r3} + 800fccc: 469e mov lr, r3 + 800fcce: 4770 bx lr + +0800fcd0 <_fini>: + 800fcd0: b5f8 push {r3, r4, r5, r6, r7, lr} + 800fcd2: 46c0 nop ; (mov r8, r8) + 800fcd4: bcf8 pop {r3, r4, r5, r6, r7} + 800fcd6: bc08 pop {r3} + 800fcd8: 469e mov lr, r3 + 800fcda: 4770 bx lr diff --git a/test/STM32F072C8T6/Debug/stm32f072_ecm.map b/test/STM32F072C8T6/Debug/stm32f072_ecm.map new file mode 100644 index 0000000..61960a5 --- /dev/null +++ b/test/STM32F072C8T6/Debug/stm32f072_ecm.map @@ -0,0 +1,8032 @@ +Archive member included to satisfy reference by file (symbol) + +c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-errno.o) + Core/Src/syscalls.o (__errno) +c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-exit.o) + c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m/crt0.o (exit) +c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-impure.o) + c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-exit.o) (_global_impure_ptr) +c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-init.o) + c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m/crt0.o (__libc_init_array) +c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-memcmp.o) + ecm_src/dhcp-server/dhserver.o (memcmp) +c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-memcpy-stub.o) + ecm_src/dhcp-server/dhserver.o (memcpy) +c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-memset.o) + c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m/crt0.o (memset) +c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-strcmp.o) + ecm_src/src/ecm_main.o (strcmp) +c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-strlen.o) + ecm_src/dhcp-server/dhserver.o (strlen) +c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v6-m\libgcc.a(_udivsi3.o) + Core/Src/system_stm32f0xx.o (__aeabi_uidiv) +c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v6-m\libgcc.a(_divsi3.o) + ecm_src/lwip-1.4.1/src/core/tcp_in.o (__aeabi_idiv) +c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v6-m\libgcc.a(_dvmd_tls.o) + c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v6-m\libgcc.a(_udivsi3.o) (__aeabi_idiv0) + +Allocating common symbols +Common symbol size file + +current_iphdr_src 0x4 ecm_src/lwip-1.4.1/src/core/ipv4/ip.o +netif_list 0x4 ecm_src/lwip-1.4.1/src/core/netif.o +hUsbDeviceFS 0x220 ecm_src/src/usb_device.o +tcp_active_pcbs_changed + 0x1 ecm_src/lwip-1.4.1/src/core/tcp.o +tcp_active_pcbs 0x4 ecm_src/lwip-1.4.1/src/core/tcp.o +udp_pcbs 0x4 ecm_src/lwip-1.4.1/src/core/udp.o +current_netif 0x4 ecm_src/lwip-1.4.1/src/core/ipv4/ip.o +tcp_ticks 0x4 ecm_src/lwip-1.4.1/src/core/tcp.o +tcp_listen_pcbs 0x4 ecm_src/lwip-1.4.1/src/core/tcp.o +sysTimeTicks 0x4 ecm_src/src/time.o +sysTimeDelayCounter + 0x4 ecm_src/src/time.o +dhcp_data 0x204 ecm_src/dhcp-server/dhserver.o +current_iphdr_dest 0x4 ecm_src/lwip-1.4.1/src/core/ipv4/ip.o +uwTick 0x4 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o +pFlash 0x20 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o +tcp_tmp_pcb 0x4 ecm_src/lwip-1.4.1/src/core/tcp.o +tcp_input_pcb 0x4 ecm_src/lwip-1.4.1/src/core/tcp_in.o +current_header 0x4 ecm_src/lwip-1.4.1/src/core/ipv4/ip.o +tcp_bound_pcbs 0x4 ecm_src/lwip-1.4.1/src/core/tcp.o +pbuf_free_ooseq_pending + 0x1 ecm_src/lwip-1.4.1/src/core/pbuf.o +tcp_tw_pcbs 0x4 ecm_src/lwip-1.4.1/src/core/tcp.o +lwip_stats 0x116 ecm_src/lwip-1.4.1/src/core/stats.o +netif_default 0x4 ecm_src/lwip-1.4.1/src/core/netif.o +hpcd_USB_FS 0x274 ecm_src/src/usbd_conf.o +ram_heap 0x654 ecm_src/lwip-1.4.1/src/core/mem.o + +Discarded input sections + + .text 0x0000000000000000 0x0 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v6-m/crti.o + .data 0x0000000000000000 0x0 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v6-m/crti.o + .bss 0x0000000000000000 0x0 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v6-m/crti.o + .data 0x0000000000000000 0x4 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v6-m/crtbegin.o + .text 0x0000000000000000 0x78 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m/crt0.o + .data 0x0000000000000000 0x0 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m/crt0.o + .bss 0x0000000000000000 0x0 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m/crt0.o + .ARM.extab 0x0000000000000000 0x0 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m/crt0.o + .ARM.exidx 0x0000000000000000 0x8 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m/crt0.o + .ARM.attributes + 0x0000000000000000 0x1b c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m/crt0.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .text 0x0000000000000000 0x0 Core/Src/main.o + .data 0x0000000000000000 0x0 Core/Src/main.o + .bss 0x0000000000000000 0x0 Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_hal_msp.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_hal_msp.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_hal_msp.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_hal_msp.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_hal_msp.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_hal_msp.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_hal_msp.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_hal_msp.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_hal_msp.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_hal_msp.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_hal_msp.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_hal_msp.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_hal_msp.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_hal_msp.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_hal_msp.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_hal_msp.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_hal_msp.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_hal_msp.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_hal_msp.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_hal_msp.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_hal_msp.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_hal_msp.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_hal_msp.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_hal_msp.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_hal_msp.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_hal_msp.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_hal_msp.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_hal_msp.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_hal_msp.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_hal_msp.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_hal_msp.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_hal_msp.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_hal_msp.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_hal_msp.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_hal_msp.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_hal_msp.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_hal_msp.o + .text 0x0000000000000000 0x0 Core/Src/stm32f0xx_hal_msp.o + .data 0x0000000000000000 0x0 Core/Src/stm32f0xx_hal_msp.o + .bss 0x0000000000000000 0x0 Core/Src/stm32f0xx_hal_msp.o + .debug_macro 0x0000000000000000 0xa48 Core/Src/stm32f0xx_hal_msp.o + .debug_macro 0x0000000000000000 0x12d Core/Src/stm32f0xx_hal_msp.o + .debug_macro 0x0000000000000000 0x2e Core/Src/stm32f0xx_hal_msp.o + .debug_macro 0x0000000000000000 0x22 Core/Src/stm32f0xx_hal_msp.o + .debug_macro 0x0000000000000000 0x22 Core/Src/stm32f0xx_hal_msp.o + .debug_macro 0x0000000000000000 0x8e Core/Src/stm32f0xx_hal_msp.o + .debug_macro 0x0000000000000000 0x51 Core/Src/stm32f0xx_hal_msp.o + .debug_macro 0x0000000000000000 0xef Core/Src/stm32f0xx_hal_msp.o + .debug_macro 0x0000000000000000 0x6a Core/Src/stm32f0xx_hal_msp.o + .debug_macro 0x0000000000000000 0x1df Core/Src/stm32f0xx_hal_msp.o + .debug_macro 0x0000000000000000 0x1c Core/Src/stm32f0xx_hal_msp.o + .debug_macro 0x0000000000000000 0x22 Core/Src/stm32f0xx_hal_msp.o + .debug_macro 0x0000000000000000 0xb5 Core/Src/stm32f0xx_hal_msp.o + .debug_macro 0x0000000000000000 0x391 Core/Src/stm32f0xx_hal_msp.o + .debug_macro 0x0000000000000000 0xfe50 Core/Src/stm32f0xx_hal_msp.o + .debug_macro 0x0000000000000000 0x3c Core/Src/stm32f0xx_hal_msp.o + .debug_macro 0x0000000000000000 0x174 Core/Src/stm32f0xx_hal_msp.o + .debug_macro 0x0000000000000000 0x53 Core/Src/stm32f0xx_hal_msp.o + .debug_macro 0x0000000000000000 0x946 Core/Src/stm32f0xx_hal_msp.o + .debug_macro 0x0000000000000000 0x5f3 Core/Src/stm32f0xx_hal_msp.o + .debug_macro 0x0000000000000000 0x12f Core/Src/stm32f0xx_hal_msp.o + .debug_macro 0x0000000000000000 0x1a7 Core/Src/stm32f0xx_hal_msp.o + .debug_macro 0x0000000000000000 0x1a7 Core/Src/stm32f0xx_hal_msp.o + .debug_macro 0x0000000000000000 0x22c Core/Src/stm32f0xx_hal_msp.o + .debug_macro 0x0000000000000000 0x34 Core/Src/stm32f0xx_hal_msp.o + .debug_macro 0x0000000000000000 0x43 Core/Src/stm32f0xx_hal_msp.o + .debug_macro 0x0000000000000000 0x28 Core/Src/stm32f0xx_hal_msp.o + .debug_macro 0x0000000000000000 0xb0 Core/Src/stm32f0xx_hal_msp.o + .debug_macro 0x0000000000000000 0x217 Core/Src/stm32f0xx_hal_msp.o + .debug_macro 0x0000000000000000 0x22c Core/Src/stm32f0xx_hal_msp.o + .debug_macro 0x0000000000000000 0x5f Core/Src/stm32f0xx_hal_msp.o + .debug_macro 0x0000000000000000 0xa5 Core/Src/stm32f0xx_hal_msp.o + .debug_macro 0x0000000000000000 0x65 Core/Src/stm32f0xx_hal_msp.o + .debug_macro 0x0000000000000000 0x234 Core/Src/stm32f0xx_hal_msp.o + .debug_macro 0x0000000000000000 0x4c Core/Src/stm32f0xx_hal_msp.o + .debug_macro 0x0000000000000000 0x16d Core/Src/stm32f0xx_hal_msp.o + .debug_macro 0x0000000000000000 0x130 Core/Src/stm32f0xx_hal_msp.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_it.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_it.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_it.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_it.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_it.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_it.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_it.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_it.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_it.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_it.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_it.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_it.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_it.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_it.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_it.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_it.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_it.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_it.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_it.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_it.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_it.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_it.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_it.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_it.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_it.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_it.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_it.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_it.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_it.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_it.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_it.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_it.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_it.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_it.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_it.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_it.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_it.o + .text 0x0000000000000000 0x0 Core/Src/stm32f0xx_it.o + .data 0x0000000000000000 0x0 Core/Src/stm32f0xx_it.o + .bss 0x0000000000000000 0x0 Core/Src/stm32f0xx_it.o + .debug_macro 0x0000000000000000 0xa48 Core/Src/stm32f0xx_it.o + .debug_macro 0x0000000000000000 0x12d Core/Src/stm32f0xx_it.o + .debug_macro 0x0000000000000000 0x2e Core/Src/stm32f0xx_it.o + .debug_macro 0x0000000000000000 0x22 Core/Src/stm32f0xx_it.o + .debug_macro 0x0000000000000000 0x22 Core/Src/stm32f0xx_it.o + .debug_macro 0x0000000000000000 0x8e Core/Src/stm32f0xx_it.o + .debug_macro 0x0000000000000000 0x51 Core/Src/stm32f0xx_it.o + .debug_macro 0x0000000000000000 0xef Core/Src/stm32f0xx_it.o + .debug_macro 0x0000000000000000 0x6a Core/Src/stm32f0xx_it.o + .debug_macro 0x0000000000000000 0x1df Core/Src/stm32f0xx_it.o + .debug_macro 0x0000000000000000 0x1c Core/Src/stm32f0xx_it.o + .debug_macro 0x0000000000000000 0x22 Core/Src/stm32f0xx_it.o + .debug_macro 0x0000000000000000 0xb5 Core/Src/stm32f0xx_it.o + .debug_macro 0x0000000000000000 0x391 Core/Src/stm32f0xx_it.o + .debug_macro 0x0000000000000000 0xfe50 Core/Src/stm32f0xx_it.o + .debug_macro 0x0000000000000000 0x3c Core/Src/stm32f0xx_it.o + .debug_macro 0x0000000000000000 0x174 Core/Src/stm32f0xx_it.o + .debug_macro 0x0000000000000000 0x53 Core/Src/stm32f0xx_it.o + .debug_macro 0x0000000000000000 0x946 Core/Src/stm32f0xx_it.o + .debug_macro 0x0000000000000000 0x5f3 Core/Src/stm32f0xx_it.o + .debug_macro 0x0000000000000000 0x12f Core/Src/stm32f0xx_it.o + .debug_macro 0x0000000000000000 0x1a7 Core/Src/stm32f0xx_it.o + .debug_macro 0x0000000000000000 0x1a7 Core/Src/stm32f0xx_it.o + .debug_macro 0x0000000000000000 0x22c Core/Src/stm32f0xx_it.o + .debug_macro 0x0000000000000000 0x34 Core/Src/stm32f0xx_it.o + .debug_macro 0x0000000000000000 0x43 Core/Src/stm32f0xx_it.o + .debug_macro 0x0000000000000000 0x28 Core/Src/stm32f0xx_it.o + .debug_macro 0x0000000000000000 0xb0 Core/Src/stm32f0xx_it.o + .debug_macro 0x0000000000000000 0x217 Core/Src/stm32f0xx_it.o + .debug_macro 0x0000000000000000 0x22c Core/Src/stm32f0xx_it.o + .debug_macro 0x0000000000000000 0x5f Core/Src/stm32f0xx_it.o + .debug_macro 0x0000000000000000 0xa5 Core/Src/stm32f0xx_it.o + .debug_macro 0x0000000000000000 0x65 Core/Src/stm32f0xx_it.o + .debug_macro 0x0000000000000000 0x234 Core/Src/stm32f0xx_it.o + .debug_macro 0x0000000000000000 0x4c Core/Src/stm32f0xx_it.o + .debug_macro 0x0000000000000000 0x16d Core/Src/stm32f0xx_it.o + .debug_macro 0x0000000000000000 0x130 Core/Src/stm32f0xx_it.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .text 0x0000000000000000 0x0 Core/Src/syscalls.o + .data 0x0000000000000000 0x0 Core/Src/syscalls.o + .bss 0x0000000000000000 0x0 Core/Src/syscalls.o + .bss.__env 0x0000000000000000 0x4 Core/Src/syscalls.o + .data.environ 0x0000000000000000 0x4 Core/Src/syscalls.o + .text.initialise_monitor_handles + 0x0000000000000000 0xa Core/Src/syscalls.o + .text._getpid 0x0000000000000000 0xc Core/Src/syscalls.o + .text._kill 0x0000000000000000 0x20 Core/Src/syscalls.o + .text._exit 0x0000000000000000 0x18 Core/Src/syscalls.o + .text._read 0x0000000000000000 0x3a Core/Src/syscalls.o + .text._write 0x0000000000000000 0x38 Core/Src/syscalls.o + .text._close 0x0000000000000000 0x14 Core/Src/syscalls.o + .text._fstat 0x0000000000000000 0x1c Core/Src/syscalls.o + .text._isatty 0x0000000000000000 0x12 Core/Src/syscalls.o + .text._lseek 0x0000000000000000 0x16 Core/Src/syscalls.o + .text._open 0x0000000000000000 0x1c Core/Src/syscalls.o + .text._wait 0x0000000000000000 0x1e Core/Src/syscalls.o + .text._unlink 0x0000000000000000 0x1e Core/Src/syscalls.o + .text._times 0x0000000000000000 0x14 Core/Src/syscalls.o + .text._stat 0x0000000000000000 0x1c Core/Src/syscalls.o + .text._link 0x0000000000000000 0x20 Core/Src/syscalls.o + .text._fork 0x0000000000000000 0x18 Core/Src/syscalls.o + .text._execve 0x0000000000000000 0x22 Core/Src/syscalls.o + .debug_info 0x0000000000000000 0xf57 Core/Src/syscalls.o + .debug_abbrev 0x0000000000000000 0x282 Core/Src/syscalls.o + .debug_aranges + 0x0000000000000000 0xa8 Core/Src/syscalls.o + .debug_ranges 0x0000000000000000 0x98 Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x399 Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0xa48 Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x22 Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x40 Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x18 Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x94 Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x3c Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x34 Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x22 Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x57 Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0xef Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x6a Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x1df Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x174 Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x2e Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x22 Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x1c Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x22 Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0xb5 Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x391 Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0xfe50 Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x3c Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x12d Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x53 Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x946 Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x5f3 Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x12f Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x1a7 Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x1a7 Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x22c Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x34 Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x43 Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x28 Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0xb0 Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x217 Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x22c Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x5f Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0xa5 Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x65 Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x234 Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x4c Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x16d Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x130 Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x10 Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x32a Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x10 Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x52 Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x1f Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x43 Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x20 Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x1c Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x52 Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x40 Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x10 Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x40 Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0xd7 Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x1c Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x3d Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x122 Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x16 Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x35 Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x1a3 Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x16 Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x29 Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x10 Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x241 Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x1c Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x10 Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x10 Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x16 Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x145 Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x189 Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x16 Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x88 Core/Src/syscalls.o + .debug_line 0x0000000000000000 0xa52 Core/Src/syscalls.o + .debug_str 0x0000000000000000 0x75f61 Core/Src/syscalls.o + .comment 0x0000000000000000 0x7c Core/Src/syscalls.o + .debug_frame 0x0000000000000000 0x244 Core/Src/syscalls.o + .ARM.attributes + 0x0000000000000000 0x31 Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/sysmem.o + .group 0x0000000000000000 0xc Core/Src/sysmem.o + .group 0x0000000000000000 0xc Core/Src/sysmem.o + .group 0x0000000000000000 0xc Core/Src/sysmem.o + .group 0x0000000000000000 0xc Core/Src/sysmem.o + .group 0x0000000000000000 0xc Core/Src/sysmem.o + .group 0x0000000000000000 0xc Core/Src/sysmem.o + .group 0x0000000000000000 0xc Core/Src/sysmem.o + .group 0x0000000000000000 0xc Core/Src/sysmem.o + .group 0x0000000000000000 0xc Core/Src/sysmem.o + .group 0x0000000000000000 0xc Core/Src/sysmem.o + .group 0x0000000000000000 0xc Core/Src/sysmem.o + .group 0x0000000000000000 0xc Core/Src/sysmem.o + .group 0x0000000000000000 0xc Core/Src/sysmem.o + .group 0x0000000000000000 0xc Core/Src/sysmem.o + .group 0x0000000000000000 0xc Core/Src/sysmem.o + .group 0x0000000000000000 0xc Core/Src/sysmem.o + .group 0x0000000000000000 0xc Core/Src/sysmem.o + .group 0x0000000000000000 0xc Core/Src/sysmem.o + .group 0x0000000000000000 0xc Core/Src/sysmem.o + .group 0x0000000000000000 0xc Core/Src/sysmem.o + .group 0x0000000000000000 0xc Core/Src/sysmem.o + .group 0x0000000000000000 0xc Core/Src/sysmem.o + .group 0x0000000000000000 0xc Core/Src/sysmem.o + .group 0x0000000000000000 0xc Core/Src/sysmem.o + .group 0x0000000000000000 0xc Core/Src/sysmem.o + .group 0x0000000000000000 0xc Core/Src/sysmem.o + .group 0x0000000000000000 0xc Core/Src/sysmem.o + .group 0x0000000000000000 0xc Core/Src/sysmem.o + .group 0x0000000000000000 0xc Core/Src/sysmem.o + .group 0x0000000000000000 0xc Core/Src/sysmem.o + .group 0x0000000000000000 0xc Core/Src/sysmem.o + .text 0x0000000000000000 0x0 Core/Src/sysmem.o + .data 0x0000000000000000 0x0 Core/Src/sysmem.o + .bss 0x0000000000000000 0x0 Core/Src/sysmem.o + .bss.heap_end.5149 + 0x0000000000000000 0x4 Core/Src/sysmem.o + .text._sbrk 0x0000000000000000 0x58 Core/Src/sysmem.o + .debug_info 0x0000000000000000 0x91c Core/Src/sysmem.o + .debug_abbrev 0x0000000000000000 0x1bb Core/Src/sysmem.o + .debug_aranges + 0x0000000000000000 0x20 Core/Src/sysmem.o + .debug_ranges 0x0000000000000000 0x10 Core/Src/sysmem.o + .debug_macro 0x0000000000000000 0x1ae Core/Src/sysmem.o + .debug_macro 0x0000000000000000 0xa48 Core/Src/sysmem.o + .debug_macro 0x0000000000000000 0x10 Core/Src/sysmem.o + .debug_macro 0x0000000000000000 0x22 Core/Src/sysmem.o + .debug_macro 0x0000000000000000 0x40 Core/Src/sysmem.o + .debug_macro 0x0000000000000000 0x18 Core/Src/sysmem.o + .debug_macro 0x0000000000000000 0x94 Core/Src/sysmem.o + .debug_macro 0x0000000000000000 0x3c Core/Src/sysmem.o + .debug_macro 0x0000000000000000 0x34 Core/Src/sysmem.o + .debug_macro 0x0000000000000000 0x174 Core/Src/sysmem.o + .debug_macro 0x0000000000000000 0x57 Core/Src/sysmem.o + .debug_macro 0x0000000000000000 0x52 Core/Src/sysmem.o + .debug_macro 0x0000000000000000 0x1f Core/Src/sysmem.o + .debug_macro 0x0000000000000000 0x43 Core/Src/sysmem.o + .debug_macro 0x0000000000000000 0x20 Core/Src/sysmem.o + .debug_macro 0x0000000000000000 0x1a3 Core/Src/sysmem.o + .debug_macro 0x0000000000000000 0x23b Core/Src/sysmem.o + .debug_macro 0x0000000000000000 0x16 Core/Src/sysmem.o + .debug_macro 0x0000000000000000 0x35 Core/Src/sysmem.o + .debug_macro 0x0000000000000000 0x330 Core/Src/sysmem.o + .debug_macro 0x0000000000000000 0x10 Core/Src/sysmem.o + .debug_macro 0x0000000000000000 0x10 Core/Src/sysmem.o + .debug_macro 0x0000000000000000 0x6a Core/Src/sysmem.o + .debug_macro 0x0000000000000000 0x1c Core/Src/sysmem.o + .debug_macro 0x0000000000000000 0x52 Core/Src/sysmem.o + .debug_macro 0x0000000000000000 0x40 Core/Src/sysmem.o + .debug_macro 0x0000000000000000 0x10 Core/Src/sysmem.o + .debug_macro 0x0000000000000000 0x40 Core/Src/sysmem.o + .debug_macro 0x0000000000000000 0xd7 Core/Src/sysmem.o + .debug_macro 0x0000000000000000 0x1c Core/Src/sysmem.o + .debug_macro 0x0000000000000000 0x3d Core/Src/sysmem.o + .debug_macro 0x0000000000000000 0x16 Core/Src/sysmem.o + .debug_macro 0x0000000000000000 0x145 Core/Src/sysmem.o + .debug_line 0x0000000000000000 0x55e Core/Src/sysmem.o + .debug_str 0x0000000000000000 0x7a3e Core/Src/sysmem.o + .comment 0x0000000000000000 0x7c Core/Src/sysmem.o + .debug_frame 0x0000000000000000 0x30 Core/Src/sysmem.o + .ARM.attributes + 0x0000000000000000 0x31 Core/Src/sysmem.o + .group 0x0000000000000000 0xc Core/Src/system_stm32f0xx.o + .group 0x0000000000000000 0xc Core/Src/system_stm32f0xx.o + .group 0x0000000000000000 0xc Core/Src/system_stm32f0xx.o + .group 0x0000000000000000 0xc Core/Src/system_stm32f0xx.o + .group 0x0000000000000000 0xc Core/Src/system_stm32f0xx.o + .group 0x0000000000000000 0xc Core/Src/system_stm32f0xx.o + .group 0x0000000000000000 0xc Core/Src/system_stm32f0xx.o + .group 0x0000000000000000 0xc Core/Src/system_stm32f0xx.o + .group 0x0000000000000000 0xc Core/Src/system_stm32f0xx.o + .group 0x0000000000000000 0xc Core/Src/system_stm32f0xx.o + .group 0x0000000000000000 0xc Core/Src/system_stm32f0xx.o + .group 0x0000000000000000 0xc Core/Src/system_stm32f0xx.o + .group 0x0000000000000000 0xc Core/Src/system_stm32f0xx.o + .group 0x0000000000000000 0xc Core/Src/system_stm32f0xx.o + .group 0x0000000000000000 0xc Core/Src/system_stm32f0xx.o + .group 0x0000000000000000 0xc Core/Src/system_stm32f0xx.o + .group 0x0000000000000000 0xc Core/Src/system_stm32f0xx.o + .group 0x0000000000000000 0xc Core/Src/system_stm32f0xx.o + .group 0x0000000000000000 0xc Core/Src/system_stm32f0xx.o + .group 0x0000000000000000 0xc Core/Src/system_stm32f0xx.o + .group 0x0000000000000000 0xc Core/Src/system_stm32f0xx.o + .group 0x0000000000000000 0xc Core/Src/system_stm32f0xx.o + .group 0x0000000000000000 0xc Core/Src/system_stm32f0xx.o + .group 0x0000000000000000 0xc Core/Src/system_stm32f0xx.o + .group 0x0000000000000000 0xc Core/Src/system_stm32f0xx.o + .group 0x0000000000000000 0xc Core/Src/system_stm32f0xx.o + .group 0x0000000000000000 0xc Core/Src/system_stm32f0xx.o + .group 0x0000000000000000 0xc Core/Src/system_stm32f0xx.o + .group 0x0000000000000000 0xc Core/Src/system_stm32f0xx.o + .group 0x0000000000000000 0xc Core/Src/system_stm32f0xx.o + .group 0x0000000000000000 0xc Core/Src/system_stm32f0xx.o + .group 0x0000000000000000 0xc Core/Src/system_stm32f0xx.o + .group 0x0000000000000000 0xc Core/Src/system_stm32f0xx.o + .group 0x0000000000000000 0xc Core/Src/system_stm32f0xx.o + .group 0x0000000000000000 0xc Core/Src/system_stm32f0xx.o + .group 0x0000000000000000 0xc Core/Src/system_stm32f0xx.o + .group 0x0000000000000000 0xc Core/Src/system_stm32f0xx.o + .text 0x0000000000000000 0x0 Core/Src/system_stm32f0xx.o + .data 0x0000000000000000 0x0 Core/Src/system_stm32f0xx.o + .bss 0x0000000000000000 0x0 Core/Src/system_stm32f0xx.o + .rodata.APBPrescTable + 0x0000000000000000 0x8 Core/Src/system_stm32f0xx.o + .text.SystemCoreClockUpdate + 0x0000000000000000 0x100 Core/Src/system_stm32f0xx.o + .debug_macro 0x0000000000000000 0xa48 Core/Src/system_stm32f0xx.o + .debug_macro 0x0000000000000000 0x2e Core/Src/system_stm32f0xx.o + .debug_macro 0x0000000000000000 0x22 Core/Src/system_stm32f0xx.o + .debug_macro 0x0000000000000000 0x22 Core/Src/system_stm32f0xx.o + .debug_macro 0x0000000000000000 0x8e Core/Src/system_stm32f0xx.o + .debug_macro 0x0000000000000000 0x51 Core/Src/system_stm32f0xx.o + .debug_macro 0x0000000000000000 0xef Core/Src/system_stm32f0xx.o + .debug_macro 0x0000000000000000 0x6a Core/Src/system_stm32f0xx.o + .debug_macro 0x0000000000000000 0x1df Core/Src/system_stm32f0xx.o + .debug_macro 0x0000000000000000 0x1c Core/Src/system_stm32f0xx.o + .debug_macro 0x0000000000000000 0x22 Core/Src/system_stm32f0xx.o + .debug_macro 0x0000000000000000 0xb5 Core/Src/system_stm32f0xx.o + .debug_macro 0x0000000000000000 0x391 Core/Src/system_stm32f0xx.o + .debug_macro 0x0000000000000000 0xfe50 Core/Src/system_stm32f0xx.o + .debug_macro 0x0000000000000000 0x3c Core/Src/system_stm32f0xx.o + .debug_macro 0x0000000000000000 0x12d Core/Src/system_stm32f0xx.o + .debug_macro 0x0000000000000000 0x174 Core/Src/system_stm32f0xx.o + .debug_macro 0x0000000000000000 0x53 Core/Src/system_stm32f0xx.o + .debug_macro 0x0000000000000000 0x946 Core/Src/system_stm32f0xx.o + .debug_macro 0x0000000000000000 0x5f3 Core/Src/system_stm32f0xx.o + .debug_macro 0x0000000000000000 0x12f Core/Src/system_stm32f0xx.o + .debug_macro 0x0000000000000000 0x1a7 Core/Src/system_stm32f0xx.o + .debug_macro 0x0000000000000000 0x1a7 Core/Src/system_stm32f0xx.o + .debug_macro 0x0000000000000000 0x22c Core/Src/system_stm32f0xx.o + .debug_macro 0x0000000000000000 0x34 Core/Src/system_stm32f0xx.o + .debug_macro 0x0000000000000000 0x43 Core/Src/system_stm32f0xx.o + .debug_macro 0x0000000000000000 0x28 Core/Src/system_stm32f0xx.o + .debug_macro 0x0000000000000000 0xb0 Core/Src/system_stm32f0xx.o + .debug_macro 0x0000000000000000 0x217 Core/Src/system_stm32f0xx.o + .debug_macro 0x0000000000000000 0x22c Core/Src/system_stm32f0xx.o + .debug_macro 0x0000000000000000 0x5f Core/Src/system_stm32f0xx.o + .debug_macro 0x0000000000000000 0xa5 Core/Src/system_stm32f0xx.o + .debug_macro 0x0000000000000000 0x65 Core/Src/system_stm32f0xx.o + .debug_macro 0x0000000000000000 0x234 Core/Src/system_stm32f0xx.o + .debug_macro 0x0000000000000000 0x4c Core/Src/system_stm32f0xx.o + .debug_macro 0x0000000000000000 0x16d Core/Src/system_stm32f0xx.o + .debug_macro 0x0000000000000000 0x130 Core/Src/system_stm32f0xx.o + .text 0x0000000000000000 0x14 Core/Startup/startup_stm32f072c8tx.o + .data 0x0000000000000000 0x0 Core/Startup/startup_stm32f072c8tx.o + .bss 0x0000000000000000 0x0 Core/Startup/startup_stm32f072c8tx.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .text 0x0000000000000000 0x0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .data 0x0000000000000000 0x0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .bss 0x0000000000000000 0x0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .text.HAL_DeInit + 0x0000000000000000 0x40 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .text.HAL_MspInit + 0x0000000000000000 0xa Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .text.HAL_MspDeInit + 0x0000000000000000 0xa Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .text.HAL_GetTickPrio + 0x0000000000000000 0x14 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .text.HAL_SetTickFreq + 0x0000000000000000 0x6c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .text.HAL_GetTickFreq + 0x0000000000000000 0x14 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .text.HAL_Delay + 0x0000000000000000 0x44 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .text.HAL_SuspendTick + 0x0000000000000000 0x1c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .text.HAL_ResumeTick + 0x0000000000000000 0x1c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .text.HAL_GetHalVersion + 0x0000000000000000 0x10 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .text.HAL_GetREVID + 0x0000000000000000 0x14 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .text.HAL_GetDEVID + 0x0000000000000000 0x18 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .text.HAL_GetUIDw0 + 0x0000000000000000 0x14 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .text.HAL_GetUIDw1 + 0x0000000000000000 0x14 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .text.HAL_GetUIDw2 + 0x0000000000000000 0x14 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .text.HAL_DBGMCU_EnableDBGStopMode + 0x0000000000000000 0x1c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .text.HAL_DBGMCU_DisableDBGStopMode + 0x0000000000000000 0x1c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .text.HAL_DBGMCU_EnableDBGStandbyMode + 0x0000000000000000 0x1c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .text.HAL_DBGMCU_DisableDBGStandbyMode + 0x0000000000000000 0x1c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .debug_macro 0x0000000000000000 0xa48 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .debug_macro 0x0000000000000000 0x12d Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .debug_macro 0x0000000000000000 0x2e Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .debug_macro 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .debug_macro 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .debug_macro 0x0000000000000000 0x8e Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .debug_macro 0x0000000000000000 0x51 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .debug_macro 0x0000000000000000 0xef Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .debug_macro 0x0000000000000000 0x6a Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .debug_macro 0x0000000000000000 0x1df Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .debug_macro 0x0000000000000000 0x1c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .debug_macro 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .debug_macro 0x0000000000000000 0xb5 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .debug_macro 0x0000000000000000 0x391 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .debug_macro 0x0000000000000000 0xfe50 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .debug_macro 0x0000000000000000 0x3c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .debug_macro 0x0000000000000000 0x174 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .debug_macro 0x0000000000000000 0x53 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .debug_macro 0x0000000000000000 0x946 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .debug_macro 0x0000000000000000 0x5f3 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .debug_macro 0x0000000000000000 0x12f Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .debug_macro 0x0000000000000000 0x1a7 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .debug_macro 0x0000000000000000 0x1a7 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .debug_macro 0x0000000000000000 0x22c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .debug_macro 0x0000000000000000 0x34 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .debug_macro 0x0000000000000000 0x43 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .debug_macro 0x0000000000000000 0x28 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .debug_macro 0x0000000000000000 0xb0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .debug_macro 0x0000000000000000 0x217 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .debug_macro 0x0000000000000000 0x22c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .debug_macro 0x0000000000000000 0x5f Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .debug_macro 0x0000000000000000 0xa5 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .debug_macro 0x0000000000000000 0x65 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .debug_macro 0x0000000000000000 0x234 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .debug_macro 0x0000000000000000 0x4c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .debug_macro 0x0000000000000000 0x16d Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .debug_macro 0x0000000000000000 0x130 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .text 0x0000000000000000 0x0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .data 0x0000000000000000 0x0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .bss 0x0000000000000000 0x0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .text.__NVIC_DisableIRQ + 0x0000000000000000 0x40 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .text.__NVIC_GetPendingIRQ + 0x0000000000000000 0x40 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .text.__NVIC_SetPendingIRQ + 0x0000000000000000 0x38 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .text.__NVIC_ClearPendingIRQ + 0x0000000000000000 0x38 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .text.__NVIC_GetPriority + 0x0000000000000000 0x7c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .text.__NVIC_SystemReset + 0x0000000000000000 0x20 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .text.HAL_NVIC_DisableIRQ + 0x0000000000000000 0x20 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .text.HAL_NVIC_SystemReset + 0x0000000000000000 0x8 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .text.HAL_NVIC_GetPriority + 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .text.HAL_NVIC_SetPendingIRQ + 0x0000000000000000 0x20 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .text.HAL_NVIC_GetPendingIRQ + 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .text.HAL_NVIC_ClearPendingIRQ + 0x0000000000000000 0x20 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .text.HAL_SYSTICK_CLKSourceConfig + 0x0000000000000000 0x34 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .text.HAL_SYSTICK_IRQHandler + 0x0000000000000000 0xe Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .text.HAL_SYSTICK_Callback + 0x0000000000000000 0xa Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .debug_macro 0x0000000000000000 0xa48 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .debug_macro 0x0000000000000000 0x12d Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .debug_macro 0x0000000000000000 0x2e Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .debug_macro 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .debug_macro 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .debug_macro 0x0000000000000000 0x8e Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .debug_macro 0x0000000000000000 0x51 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .debug_macro 0x0000000000000000 0xef Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .debug_macro 0x0000000000000000 0x6a Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .debug_macro 0x0000000000000000 0x1df Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .debug_macro 0x0000000000000000 0x1c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .debug_macro 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .debug_macro 0x0000000000000000 0xb5 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .debug_macro 0x0000000000000000 0x391 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .debug_macro 0x0000000000000000 0xfe50 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .debug_macro 0x0000000000000000 0x3c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .debug_macro 0x0000000000000000 0x174 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .debug_macro 0x0000000000000000 0x53 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .debug_macro 0x0000000000000000 0x946 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .debug_macro 0x0000000000000000 0x5f3 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .debug_macro 0x0000000000000000 0x12f Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .debug_macro 0x0000000000000000 0x1a7 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .debug_macro 0x0000000000000000 0x1a7 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .debug_macro 0x0000000000000000 0x22c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .debug_macro 0x0000000000000000 0x34 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .debug_macro 0x0000000000000000 0x43 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .debug_macro 0x0000000000000000 0x28 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .debug_macro 0x0000000000000000 0xb0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .debug_macro 0x0000000000000000 0x217 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .debug_macro 0x0000000000000000 0x22c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .debug_macro 0x0000000000000000 0x5f Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .debug_macro 0x0000000000000000 0xa5 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .debug_macro 0x0000000000000000 0x65 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .debug_macro 0x0000000000000000 0x234 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .debug_macro 0x0000000000000000 0x4c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .debug_macro 0x0000000000000000 0x16d Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .debug_macro 0x0000000000000000 0x130 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .text 0x0000000000000000 0x0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .data 0x0000000000000000 0x0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .bss 0x0000000000000000 0x0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .text.HAL_DMA_Init + 0x0000000000000000 0x90 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .text.HAL_DMA_DeInit + 0x0000000000000000 0x92 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .text.HAL_DMA_Start + 0x0000000000000000 0x92 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .text.HAL_DMA_Start_IT + 0x0000000000000000 0xcc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .text.HAL_DMA_Abort + 0x0000000000000000 0x70 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .text.HAL_DMA_Abort_IT + 0x0000000000000000 0x8c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .text.HAL_DMA_PollForTransfer + 0x0000000000000000 0x132 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .text.HAL_DMA_IRQHandler + 0x0000000000000000 0x144 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .text.HAL_DMA_RegisterCallback + 0x0000000000000000 0xa2 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .text.HAL_DMA_UnRegisterCallback + 0x0000000000000000 0xb4 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .rodata.HAL_DMA_UnRegisterCallback + 0x0000000000000000 0x14 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .text.HAL_DMA_GetState + 0x0000000000000000 0x18 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .text.HAL_DMA_GetError + 0x0000000000000000 0x14 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .text.DMA_SetConfig + 0x0000000000000000 0x58 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .text.DMA_CalcBaseAndBitshift + 0x0000000000000000 0x38 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .debug_info 0x0000000000000000 0x7a9 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .debug_abbrev 0x0000000000000000 0x216 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .debug_aranges + 0x0000000000000000 0x88 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .debug_ranges 0x0000000000000000 0x78 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .debug_macro 0x0000000000000000 0x1b5 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .debug_macro 0x0000000000000000 0xa48 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .debug_macro 0x0000000000000000 0x12d Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .debug_macro 0x0000000000000000 0x2e Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .debug_macro 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .debug_macro 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .debug_macro 0x0000000000000000 0x8e Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .debug_macro 0x0000000000000000 0x51 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .debug_macro 0x0000000000000000 0xef Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .debug_macro 0x0000000000000000 0x6a Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .debug_macro 0x0000000000000000 0x1df Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .debug_macro 0x0000000000000000 0x1c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .debug_macro 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .debug_macro 0x0000000000000000 0xb5 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .debug_macro 0x0000000000000000 0x391 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .debug_macro 0x0000000000000000 0xfe50 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .debug_macro 0x0000000000000000 0x3c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .debug_macro 0x0000000000000000 0x174 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .debug_macro 0x0000000000000000 0x53 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .debug_macro 0x0000000000000000 0x946 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .debug_macro 0x0000000000000000 0x5f3 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .debug_macro 0x0000000000000000 0x12f Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .debug_macro 0x0000000000000000 0x1a7 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .debug_macro 0x0000000000000000 0x1a7 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .debug_macro 0x0000000000000000 0x22c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .debug_macro 0x0000000000000000 0x34 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .debug_macro 0x0000000000000000 0x43 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .debug_macro 0x0000000000000000 0x28 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .debug_macro 0x0000000000000000 0xb0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .debug_macro 0x0000000000000000 0x217 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .debug_macro 0x0000000000000000 0x22c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .debug_macro 0x0000000000000000 0x5f Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .debug_macro 0x0000000000000000 0xa5 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .debug_macro 0x0000000000000000 0x65 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .debug_macro 0x0000000000000000 0x234 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .debug_macro 0x0000000000000000 0x4c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .debug_macro 0x0000000000000000 0x16d Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .debug_macro 0x0000000000000000 0x130 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .debug_line 0x0000000000000000 0x893 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .debug_str 0x0000000000000000 0x710c0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .comment 0x0000000000000000 0x7c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .debug_frame 0x0000000000000000 0x1d0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .ARM.attributes + 0x0000000000000000 0x31 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .text 0x0000000000000000 0x0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .data 0x0000000000000000 0x0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .bss 0x0000000000000000 0x0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .text.HAL_EXTI_SetConfigLine + 0x0000000000000000 0x148 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .text.HAL_EXTI_GetConfigLine + 0x0000000000000000 0xfc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .text.HAL_EXTI_ClearConfigLine + 0x0000000000000000 0xc0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .text.HAL_EXTI_RegisterCallback + 0x0000000000000000 0x42 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .text.HAL_EXTI_GetHandle + 0x0000000000000000 0x24 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .text.HAL_EXTI_IRQHandler + 0x0000000000000000 0x48 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .text.HAL_EXTI_GetPending + 0x0000000000000000 0x3c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .text.HAL_EXTI_ClearPending + 0x0000000000000000 0x2c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .text.HAL_EXTI_GenerateSWI + 0x0000000000000000 0x2c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .debug_info 0x0000000000000000 0x5a8 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .debug_abbrev 0x0000000000000000 0x1bc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .debug_aranges + 0x0000000000000000 0x60 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .debug_ranges 0x0000000000000000 0x50 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .debug_macro 0x0000000000000000 0x1b5 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .debug_macro 0x0000000000000000 0xa48 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .debug_macro 0x0000000000000000 0x12d Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .debug_macro 0x0000000000000000 0x2e Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .debug_macro 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .debug_macro 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .debug_macro 0x0000000000000000 0x8e Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .debug_macro 0x0000000000000000 0x51 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .debug_macro 0x0000000000000000 0xef Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .debug_macro 0x0000000000000000 0x6a Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .debug_macro 0x0000000000000000 0x1df Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .debug_macro 0x0000000000000000 0x1c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .debug_macro 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .debug_macro 0x0000000000000000 0xb5 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .debug_macro 0x0000000000000000 0x391 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .debug_macro 0x0000000000000000 0xfe50 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .debug_macro 0x0000000000000000 0x3c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .debug_macro 0x0000000000000000 0x174 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .debug_macro 0x0000000000000000 0x53 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .debug_macro 0x0000000000000000 0x946 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .debug_macro 0x0000000000000000 0x5f3 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .debug_macro 0x0000000000000000 0x12f Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .debug_macro 0x0000000000000000 0x1a7 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .debug_macro 0x0000000000000000 0x1a7 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .debug_macro 0x0000000000000000 0x22c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .debug_macro 0x0000000000000000 0x34 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .debug_macro 0x0000000000000000 0x43 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .debug_macro 0x0000000000000000 0x28 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .debug_macro 0x0000000000000000 0xb0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .debug_macro 0x0000000000000000 0x217 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .debug_macro 0x0000000000000000 0x22c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .debug_macro 0x0000000000000000 0x5f Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .debug_macro 0x0000000000000000 0xa5 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .debug_macro 0x0000000000000000 0x65 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .debug_macro 0x0000000000000000 0x234 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .debug_macro 0x0000000000000000 0x4c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .debug_macro 0x0000000000000000 0x16d Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .debug_macro 0x0000000000000000 0x130 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .debug_line 0x0000000000000000 0x77c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .debug_str 0x0000000000000000 0x70e8a Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .comment 0x0000000000000000 0x7c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .debug_frame 0x0000000000000000 0x130 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .ARM.attributes + 0x0000000000000000 0x31 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .text 0x0000000000000000 0x0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .data 0x0000000000000000 0x0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .bss 0x0000000000000000 0x0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .text.HAL_FLASH_Program + 0x0000000000000000 0x12c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .text.HAL_FLASH_Program_IT + 0x0000000000000000 0xa0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .text.HAL_FLASH_IRQHandler + 0x0000000000000000 0x1d0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .text.HAL_FLASH_EndOfOperationCallback + 0x0000000000000000 0x10 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .text.HAL_FLASH_OperationErrorCallback + 0x0000000000000000 0x10 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .text.HAL_FLASH_Unlock + 0x0000000000000000 0x4c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .text.HAL_FLASH_Lock + 0x0000000000000000 0x1c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .text.HAL_FLASH_OB_Unlock + 0x0000000000000000 0x34 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .text.HAL_FLASH_OB_Lock + 0x0000000000000000 0x20 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .text.HAL_FLASH_OB_Launch + 0x0000000000000000 0x2c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .text.HAL_FLASH_GetError + 0x0000000000000000 0x14 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .text.FLASH_Program_HalfWord + 0x0000000000000000 0x38 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .text.FLASH_WaitForLastOperation + 0x0000000000000000 0x80 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .text.FLASH_SetErrorCode + 0x0000000000000000 0x60 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .debug_info 0x0000000000000000 0x57f Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .debug_abbrev 0x0000000000000000 0x22e Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .debug_aranges + 0x0000000000000000 0x88 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .debug_ranges 0x0000000000000000 0x78 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .debug_macro 0x0000000000000000 0x1b5 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .debug_macro 0x0000000000000000 0xa48 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .debug_macro 0x0000000000000000 0x12d Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .debug_macro 0x0000000000000000 0x2e Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .debug_macro 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .debug_macro 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .debug_macro 0x0000000000000000 0x8e Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .debug_macro 0x0000000000000000 0x51 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .debug_macro 0x0000000000000000 0xef Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .debug_macro 0x0000000000000000 0x6a Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .debug_macro 0x0000000000000000 0x1df Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .debug_macro 0x0000000000000000 0x1c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .debug_macro 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .debug_macro 0x0000000000000000 0xb5 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .debug_macro 0x0000000000000000 0x391 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .debug_macro 0x0000000000000000 0xfe50 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .debug_macro 0x0000000000000000 0x3c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .debug_macro 0x0000000000000000 0x174 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .debug_macro 0x0000000000000000 0x53 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .debug_macro 0x0000000000000000 0x946 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .debug_macro 0x0000000000000000 0x5f3 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .debug_macro 0x0000000000000000 0x12f Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .debug_macro 0x0000000000000000 0x1a7 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .debug_macro 0x0000000000000000 0x1a7 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .debug_macro 0x0000000000000000 0x22c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .debug_macro 0x0000000000000000 0x34 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .debug_macro 0x0000000000000000 0x43 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .debug_macro 0x0000000000000000 0x28 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .debug_macro 0x0000000000000000 0xb0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .debug_macro 0x0000000000000000 0x217 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .debug_macro 0x0000000000000000 0x22c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .debug_macro 0x0000000000000000 0x5f Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .debug_macro 0x0000000000000000 0xa5 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .debug_macro 0x0000000000000000 0x65 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .debug_macro 0x0000000000000000 0x234 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .debug_macro 0x0000000000000000 0x4c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .debug_macro 0x0000000000000000 0x16d Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .debug_macro 0x0000000000000000 0x130 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .debug_line 0x0000000000000000 0x83f Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .debug_str 0x0000000000000000 0x70fa3 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .comment 0x0000000000000000 0x7c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .debug_frame 0x0000000000000000 0x1c4 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .ARM.attributes + 0x0000000000000000 0x31 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + COMMON 0x0000000000000000 0x20 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .text 0x0000000000000000 0x0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .data 0x0000000000000000 0x0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .bss 0x0000000000000000 0x0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .text.HAL_FLASHEx_Erase + 0x0000000000000000 0xec Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .text.HAL_FLASHEx_Erase_IT + 0x0000000000000000 0x88 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .text.HAL_FLASHEx_OBErase + 0x0000000000000000 0x9c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .text.HAL_FLASHEx_OBProgram + 0x0000000000000000 0x128 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .text.HAL_FLASHEx_OBGetConfig + 0x0000000000000000 0x38 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .text.HAL_FLASHEx_OBGetUserData + 0x0000000000000000 0x40 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .text.FLASH_MassErase + 0x0000000000000000 0x30 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .text.FLASH_OB_EnableWRP + 0x0000000000000000 0x1c0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .text.FLASH_OB_DisableWRP + 0x0000000000000000 0x1bc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .text.FLASH_OB_RDP_LevelConfig + 0x0000000000000000 0xbc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .text.FLASH_OB_UserConfig + 0x0000000000000000 0x88 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .text.FLASH_OB_ProgramData + 0x0000000000000000 0x80 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .text.FLASH_OB_GetWRP + 0x0000000000000000 0x14 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .text.FLASH_OB_GetRDP + 0x0000000000000000 0x34 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .text.FLASH_OB_GetUser + 0x0000000000000000 0x1c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .text.FLASH_PageErase + 0x0000000000000000 0x3c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .debug_info 0x0000000000000000 0x7c5 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .debug_abbrev 0x0000000000000000 0x219 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .debug_aranges + 0x0000000000000000 0x98 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .debug_ranges 0x0000000000000000 0x88 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .debug_macro 0x0000000000000000 0x1c7 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .debug_macro 0x0000000000000000 0xa48 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .debug_macro 0x0000000000000000 0x12d Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .debug_macro 0x0000000000000000 0x2e Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .debug_macro 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .debug_macro 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .debug_macro 0x0000000000000000 0x8e Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .debug_macro 0x0000000000000000 0x51 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .debug_macro 0x0000000000000000 0xef Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .debug_macro 0x0000000000000000 0x6a Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .debug_macro 0x0000000000000000 0x1df Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .debug_macro 0x0000000000000000 0x1c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .debug_macro 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .debug_macro 0x0000000000000000 0xb5 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .debug_macro 0x0000000000000000 0x391 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .debug_macro 0x0000000000000000 0xfe50 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .debug_macro 0x0000000000000000 0x3c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .debug_macro 0x0000000000000000 0x174 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .debug_macro 0x0000000000000000 0x53 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .debug_macro 0x0000000000000000 0x946 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .debug_macro 0x0000000000000000 0x5f3 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .debug_macro 0x0000000000000000 0x12f Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .debug_macro 0x0000000000000000 0x1a7 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .debug_macro 0x0000000000000000 0x1a7 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .debug_macro 0x0000000000000000 0x22c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .debug_macro 0x0000000000000000 0x34 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .debug_macro 0x0000000000000000 0x43 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .debug_macro 0x0000000000000000 0x28 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .debug_macro 0x0000000000000000 0xb0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .debug_macro 0x0000000000000000 0x217 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .debug_macro 0x0000000000000000 0x22c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .debug_macro 0x0000000000000000 0x5f Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .debug_macro 0x0000000000000000 0xa5 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .debug_macro 0x0000000000000000 0x65 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .debug_macro 0x0000000000000000 0x234 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .debug_macro 0x0000000000000000 0x4c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .debug_macro 0x0000000000000000 0x16d Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .debug_macro 0x0000000000000000 0x130 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .debug_line 0x0000000000000000 0x8b9 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .debug_str 0x0000000000000000 0x71123 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .comment 0x0000000000000000 0x7c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .debug_frame 0x0000000000000000 0x220 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .ARM.attributes + 0x0000000000000000 0x31 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .text 0x0000000000000000 0x0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .data 0x0000000000000000 0x0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .bss 0x0000000000000000 0x0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .text.HAL_GPIO_DeInit + 0x0000000000000000 0x1ac Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .text.HAL_GPIO_ReadPin + 0x0000000000000000 0x3a Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .text.HAL_GPIO_WritePin + 0x0000000000000000 0x3a Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .text.HAL_GPIO_TogglePin + 0x0000000000000000 0x36 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .text.HAL_GPIO_LockPin + 0x0000000000000000 0x52 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .text.HAL_GPIO_EXTI_IRQHandler + 0x0000000000000000 0x38 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .text.HAL_GPIO_EXTI_Callback + 0x0000000000000000 0x14 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .debug_macro 0x0000000000000000 0xa48 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .debug_macro 0x0000000000000000 0x12d Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .debug_macro 0x0000000000000000 0x2e Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .debug_macro 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .debug_macro 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .debug_macro 0x0000000000000000 0x8e Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .debug_macro 0x0000000000000000 0x51 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .debug_macro 0x0000000000000000 0xef Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .debug_macro 0x0000000000000000 0x6a Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .debug_macro 0x0000000000000000 0x1df Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .debug_macro 0x0000000000000000 0x1c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .debug_macro 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .debug_macro 0x0000000000000000 0xb5 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .debug_macro 0x0000000000000000 0x391 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .debug_macro 0x0000000000000000 0xfe50 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .debug_macro 0x0000000000000000 0x3c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .debug_macro 0x0000000000000000 0x174 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .debug_macro 0x0000000000000000 0x53 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .debug_macro 0x0000000000000000 0x946 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .debug_macro 0x0000000000000000 0x5f3 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .debug_macro 0x0000000000000000 0x12f Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .debug_macro 0x0000000000000000 0x1a7 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .debug_macro 0x0000000000000000 0x1a7 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .debug_macro 0x0000000000000000 0x22c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .debug_macro 0x0000000000000000 0x34 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .debug_macro 0x0000000000000000 0x43 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .debug_macro 0x0000000000000000 0x28 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .debug_macro 0x0000000000000000 0xb0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .debug_macro 0x0000000000000000 0x217 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .debug_macro 0x0000000000000000 0x22c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .debug_macro 0x0000000000000000 0x5f Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .debug_macro 0x0000000000000000 0xa5 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .debug_macro 0x0000000000000000 0x65 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .debug_macro 0x0000000000000000 0x234 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .debug_macro 0x0000000000000000 0x4c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .debug_macro 0x0000000000000000 0x16d Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .debug_macro 0x0000000000000000 0x130 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text 0x0000000000000000 0x0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .data 0x0000000000000000 0x0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .bss 0x0000000000000000 0x0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.HAL_I2C_Init + 0x0000000000000000 0x12c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.HAL_I2C_DeInit + 0x0000000000000000 0x60 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.HAL_I2C_MspInit + 0x0000000000000000 0x10 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.HAL_I2C_MspDeInit + 0x0000000000000000 0x10 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.HAL_I2C_Master_Transmit + 0x0000000000000000 0x210 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.HAL_I2C_Master_Receive + 0x0000000000000000 0x210 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.HAL_I2C_Slave_Transmit + 0x0000000000000000 0x22c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.HAL_I2C_Slave_Receive + 0x0000000000000000 0x214 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.HAL_I2C_Master_Transmit_IT + 0x0000000000000000 0xf8 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.HAL_I2C_Master_Receive_IT + 0x0000000000000000 0xf8 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.HAL_I2C_Slave_Transmit_IT + 0x0000000000000000 0xa8 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.HAL_I2C_Slave_Receive_IT + 0x0000000000000000 0xa8 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.HAL_I2C_Master_Transmit_DMA + 0x0000000000000000 0x20c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.HAL_I2C_Master_Receive_DMA + 0x0000000000000000 0x20c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.HAL_I2C_Slave_Transmit_DMA + 0x0000000000000000 0x17c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.HAL_I2C_Slave_Receive_DMA + 0x0000000000000000 0x17c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.HAL_I2C_Mem_Write + 0x0000000000000000 0x25c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.HAL_I2C_Mem_Read + 0x0000000000000000 0x268 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.HAL_I2C_Mem_Write_IT + 0x0000000000000000 0x150 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.HAL_I2C_Mem_Read_IT + 0x0000000000000000 0x154 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.HAL_I2C_Mem_Write_DMA + 0x0000000000000000 0x21c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.HAL_I2C_Mem_Read_DMA + 0x0000000000000000 0x220 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.HAL_I2C_IsDeviceReady + 0x0000000000000000 0x234 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.HAL_I2C_Master_Seq_Transmit_IT + 0x0000000000000000 0x124 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.HAL_I2C_Master_Seq_Transmit_DMA + 0x0000000000000000 0x234 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.HAL_I2C_Master_Seq_Receive_IT + 0x0000000000000000 0x124 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.HAL_I2C_Master_Seq_Receive_DMA + 0x0000000000000000 0x234 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.HAL_I2C_Slave_Seq_Transmit_IT + 0x0000000000000000 0x158 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.HAL_I2C_Slave_Seq_Transmit_DMA + 0x0000000000000000 0x28c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.HAL_I2C_Slave_Seq_Receive_IT + 0x0000000000000000 0x15c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.HAL_I2C_Slave_Seq_Receive_DMA + 0x0000000000000000 0x28c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.HAL_I2C_EnableListen_IT + 0x0000000000000000 0x40 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.HAL_I2C_DisableListen_IT + 0x0000000000000000 0x64 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.HAL_I2C_Master_Abort_IT + 0x0000000000000000 0x88 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.HAL_I2C_EV_IRQHandler + 0x0000000000000000 0x34 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.HAL_I2C_ER_IRQHandler + 0x0000000000000000 0xc4 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.HAL_I2C_MasterTxCpltCallback + 0x0000000000000000 0x10 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.HAL_I2C_MasterRxCpltCallback + 0x0000000000000000 0x10 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.HAL_I2C_SlaveTxCpltCallback + 0x0000000000000000 0x10 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.HAL_I2C_SlaveRxCpltCallback + 0x0000000000000000 0x10 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.HAL_I2C_AddrCallback + 0x0000000000000000 0x20 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.HAL_I2C_ListenCpltCallback + 0x0000000000000000 0x10 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.HAL_I2C_MemTxCpltCallback + 0x0000000000000000 0x10 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.HAL_I2C_MemRxCpltCallback + 0x0000000000000000 0x10 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.HAL_I2C_ErrorCallback + 0x0000000000000000 0x10 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.HAL_I2C_AbortCpltCallback + 0x0000000000000000 0x10 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.HAL_I2C_GetState + 0x0000000000000000 0x18 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.HAL_I2C_GetMode + 0x0000000000000000 0x18 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.HAL_I2C_GetError + 0x0000000000000000 0x14 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.I2C_Master_ISR_IT + 0x0000000000000000 0x288 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.I2C_Slave_ISR_IT + 0x0000000000000000 0x228 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.I2C_Master_ISR_DMA + 0x0000000000000000 0x218 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.I2C_Slave_ISR_DMA + 0x0000000000000000 0x1b0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.I2C_RequestMemoryWrite + 0x0000000000000000 0xc8 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.I2C_RequestMemoryRead + 0x0000000000000000 0xc4 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.I2C_ITAddrCplt + 0x0000000000000000 0x14a Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.I2C_ITMasterSeqCplt + 0x0000000000000000 0x82 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.I2C_ITSlaveSeqCplt + 0x0000000000000000 0x82 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.I2C_ITMasterCplt + 0x0000000000000000 0x144 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.I2C_ITSlaveCplt + 0x0000000000000000 0x1c0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.I2C_ITListenCplt + 0x0000000000000000 0xac Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.I2C_ITError + 0x0000000000000000 0x1a4 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.I2C_Flush_TXDR + 0x0000000000000000 0x44 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.I2C_DMAMasterTransmitCplt + 0x0000000000000000 0xa0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.I2C_DMASlaveTransmitCplt + 0x0000000000000000 0x48 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.I2C_DMAMasterReceiveCplt + 0x0000000000000000 0xa0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.I2C_DMASlaveReceiveCplt + 0x0000000000000000 0x50 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.I2C_DMAError + 0x0000000000000000 0x32 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.I2C_DMAAbort + 0x0000000000000000 0x4c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.I2C_WaitOnFlagUntilTimeout + 0x0000000000000000 0x7e Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.I2C_WaitOnTXISFlagUntilTimeout + 0x0000000000000000 0x7e Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.I2C_WaitOnSTOPFlagUntilTimeout + 0x0000000000000000 0x78 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.I2C_WaitOnRXNEFlagUntilTimeout + 0x0000000000000000 0xd8 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.I2C_IsAcknowledgeFailed + 0x0000000000000000 0xcc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.I2C_TransferConfig + 0x0000000000000000 0x6c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.I2C_Enable_IRQ + 0x0000000000000000 0xe4 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.I2C_Disable_IRQ + 0x0000000000000000 0xd2 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.I2C_ConvertOtherXferOptions + 0x0000000000000000 0x34 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .debug_info 0x0000000000000000 0x1f43 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .debug_abbrev 0x0000000000000000 0x22a Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .debug_aranges + 0x0000000000000000 0x288 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .debug_ranges 0x0000000000000000 0x278 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .debug_macro 0x0000000000000000 0x27a Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .debug_macro 0x0000000000000000 0xa48 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .debug_macro 0x0000000000000000 0x12d Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .debug_macro 0x0000000000000000 0x2e Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .debug_macro 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .debug_macro 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .debug_macro 0x0000000000000000 0x8e Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .debug_macro 0x0000000000000000 0x51 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .debug_macro 0x0000000000000000 0xef Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .debug_macro 0x0000000000000000 0x6a Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .debug_macro 0x0000000000000000 0x1df Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .debug_macro 0x0000000000000000 0x1c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .debug_macro 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .debug_macro 0x0000000000000000 0xb5 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .debug_macro 0x0000000000000000 0x391 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .debug_macro 0x0000000000000000 0xfe50 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .debug_macro 0x0000000000000000 0x3c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .debug_macro 0x0000000000000000 0x174 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .debug_macro 0x0000000000000000 0x53 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .debug_macro 0x0000000000000000 0x946 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .debug_macro 0x0000000000000000 0x5f3 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .debug_macro 0x0000000000000000 0x12f Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .debug_macro 0x0000000000000000 0x1a7 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .debug_macro 0x0000000000000000 0x1a7 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .debug_macro 0x0000000000000000 0x22c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .debug_macro 0x0000000000000000 0x34 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .debug_macro 0x0000000000000000 0x43 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .debug_macro 0x0000000000000000 0x28 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .debug_macro 0x0000000000000000 0xb0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .debug_macro 0x0000000000000000 0x217 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .debug_macro 0x0000000000000000 0x22c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .debug_macro 0x0000000000000000 0x5f Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .debug_macro 0x0000000000000000 0xa5 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .debug_macro 0x0000000000000000 0x65 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .debug_macro 0x0000000000000000 0x234 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .debug_macro 0x0000000000000000 0x4c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .debug_macro 0x0000000000000000 0x16d Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .debug_macro 0x0000000000000000 0x130 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .debug_line 0x0000000000000000 0x1a02 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .debug_str 0x0000000000000000 0x71f47 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .comment 0x0000000000000000 0x7c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .debug_frame 0x0000000000000000 0xa00 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .ARM.attributes + 0x0000000000000000 0x31 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .text 0x0000000000000000 0x0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .data 0x0000000000000000 0x0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .bss 0x0000000000000000 0x0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .text.HAL_I2CEx_ConfigAnalogFilter + 0x0000000000000000 0x98 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .text.HAL_I2CEx_ConfigDigitalFilter + 0x0000000000000000 0x98 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .text.HAL_I2CEx_EnableWakeUp + 0x0000000000000000 0x82 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .text.HAL_I2CEx_DisableWakeUp + 0x0000000000000000 0x84 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .text.HAL_I2CEx_EnableFastModePlus + 0x0000000000000000 0x3c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .text.HAL_I2CEx_DisableFastModePlus + 0x0000000000000000 0x40 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .debug_info 0x0000000000000000 0x8c9 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .debug_abbrev 0x0000000000000000 0x1b9 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .debug_aranges + 0x0000000000000000 0x48 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .debug_ranges 0x0000000000000000 0x38 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .debug_macro 0x0000000000000000 0x1b5 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .debug_macro 0x0000000000000000 0xa48 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .debug_macro 0x0000000000000000 0x12d Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .debug_macro 0x0000000000000000 0x2e Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .debug_macro 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .debug_macro 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .debug_macro 0x0000000000000000 0x8e Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .debug_macro 0x0000000000000000 0x51 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .debug_macro 0x0000000000000000 0xef Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .debug_macro 0x0000000000000000 0x6a Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .debug_macro 0x0000000000000000 0x1df Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .debug_macro 0x0000000000000000 0x1c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .debug_macro 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .debug_macro 0x0000000000000000 0xb5 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .debug_macro 0x0000000000000000 0x391 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .debug_macro 0x0000000000000000 0xfe50 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .debug_macro 0x0000000000000000 0x3c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .debug_macro 0x0000000000000000 0x174 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .debug_macro 0x0000000000000000 0x53 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .debug_macro 0x0000000000000000 0x946 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .debug_macro 0x0000000000000000 0x5f3 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .debug_macro 0x0000000000000000 0x12f Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .debug_macro 0x0000000000000000 0x1a7 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .debug_macro 0x0000000000000000 0x1a7 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .debug_macro 0x0000000000000000 0x22c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .debug_macro 0x0000000000000000 0x34 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .debug_macro 0x0000000000000000 0x43 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .debug_macro 0x0000000000000000 0x28 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .debug_macro 0x0000000000000000 0xb0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .debug_macro 0x0000000000000000 0x217 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .debug_macro 0x0000000000000000 0x22c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .debug_macro 0x0000000000000000 0x5f Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .debug_macro 0x0000000000000000 0xa5 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .debug_macro 0x0000000000000000 0x65 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .debug_macro 0x0000000000000000 0x234 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .debug_macro 0x0000000000000000 0x4c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .debug_macro 0x0000000000000000 0x16d Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .debug_macro 0x0000000000000000 0x130 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .debug_line 0x0000000000000000 0x7c3 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .debug_str 0x0000000000000000 0x71286 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .comment 0x0000000000000000 0x7c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .debug_frame 0x0000000000000000 0xd0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .ARM.attributes + 0x0000000000000000 0x31 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .text 0x0000000000000000 0x0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .data 0x0000000000000000 0x0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .bss 0x0000000000000000 0x0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .text.HAL_PCD_DeInit + 0x0000000000000000 0x40 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .text.HAL_PCD_MspInit + 0x0000000000000000 0x10 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .text.HAL_PCD_MspDeInit + 0x0000000000000000 0x10 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .text.HAL_PCD_Stop + 0x0000000000000000 0x4a Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .text.HAL_PCD_DataOutStageCallback + 0x0000000000000000 0x16 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .text.HAL_PCD_DataInStageCallback + 0x0000000000000000 0x16 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .text.HAL_PCD_SetupStageCallback + 0x0000000000000000 0x10 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .text.HAL_PCD_SOFCallback + 0x0000000000000000 0x10 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .text.HAL_PCD_ResetCallback + 0x0000000000000000 0x10 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .text.HAL_PCD_SuspendCallback + 0x0000000000000000 0x10 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .text.HAL_PCD_ResumeCallback + 0x0000000000000000 0x10 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .text.HAL_PCD_ISOOUTIncompleteCallback + 0x0000000000000000 0x16 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .text.HAL_PCD_ISOINIncompleteCallback + 0x0000000000000000 0x16 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .text.HAL_PCD_ConnectCallback + 0x0000000000000000 0x10 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .text.HAL_PCD_DisconnectCallback + 0x0000000000000000 0x10 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .text.HAL_PCD_DevConnect + 0x0000000000000000 0x40 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .text.HAL_PCD_DevDisconnect + 0x0000000000000000 0x40 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .text.HAL_PCD_EP_Flush + 0x0000000000000000 0x18 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .text.HAL_PCD_ActivateRemoteWakeup + 0x0000000000000000 0x1c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .text.HAL_PCD_DeActivateRemoteWakeup + 0x0000000000000000 0x1c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .text.HAL_PCD_GetState + 0x0000000000000000 0x1c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .debug_macro 0x0000000000000000 0xa48 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .debug_macro 0x0000000000000000 0x12d Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .debug_macro 0x0000000000000000 0x2e Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .debug_macro 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .debug_macro 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .debug_macro 0x0000000000000000 0x8e Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .debug_macro 0x0000000000000000 0x51 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .debug_macro 0x0000000000000000 0xef Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .debug_macro 0x0000000000000000 0x6a Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .debug_macro 0x0000000000000000 0x1df Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .debug_macro 0x0000000000000000 0x1c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .debug_macro 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .debug_macro 0x0000000000000000 0xb5 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .debug_macro 0x0000000000000000 0x391 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .debug_macro 0x0000000000000000 0xfe50 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .debug_macro 0x0000000000000000 0x3c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .debug_macro 0x0000000000000000 0x174 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .debug_macro 0x0000000000000000 0x53 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .debug_macro 0x0000000000000000 0x946 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .debug_macro 0x0000000000000000 0x5f3 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .debug_macro 0x0000000000000000 0x12f Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .debug_macro 0x0000000000000000 0x1a7 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .debug_macro 0x0000000000000000 0x1a7 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .debug_macro 0x0000000000000000 0x22c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .debug_macro 0x0000000000000000 0x34 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .debug_macro 0x0000000000000000 0x43 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .debug_macro 0x0000000000000000 0x28 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .debug_macro 0x0000000000000000 0xb0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .debug_macro 0x0000000000000000 0x217 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .debug_macro 0x0000000000000000 0x22c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .debug_macro 0x0000000000000000 0x5f Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .debug_macro 0x0000000000000000 0xa5 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .debug_macro 0x0000000000000000 0x65 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .debug_macro 0x0000000000000000 0x234 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .debug_macro 0x0000000000000000 0x4c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .debug_macro 0x0000000000000000 0x16d Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .debug_macro 0x0000000000000000 0x130 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .text 0x0000000000000000 0x0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .data 0x0000000000000000 0x0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .bss 0x0000000000000000 0x0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .text.HAL_PCDEx_ActivateBCD + 0x0000000000000000 0x72 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .text.HAL_PCDEx_DeActivateBCD + 0x0000000000000000 0x36 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .text.HAL_PCDEx_BCD_VBUSDetect + 0x0000000000000000 0x12e Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .text.HAL_PCDEx_DeActivateLPM + 0x0000000000000000 0x4a Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .text.HAL_PCDEx_BCD_Callback + 0x0000000000000000 0x16 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .debug_macro 0x0000000000000000 0xa48 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .debug_macro 0x0000000000000000 0x12d Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .debug_macro 0x0000000000000000 0x2e Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .debug_macro 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .debug_macro 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .debug_macro 0x0000000000000000 0x8e Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .debug_macro 0x0000000000000000 0x51 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .debug_macro 0x0000000000000000 0xef Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .debug_macro 0x0000000000000000 0x6a Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .debug_macro 0x0000000000000000 0x1df Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .debug_macro 0x0000000000000000 0x1c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .debug_macro 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .debug_macro 0x0000000000000000 0xb5 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .debug_macro 0x0000000000000000 0x391 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .debug_macro 0x0000000000000000 0xfe50 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .debug_macro 0x0000000000000000 0x3c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .debug_macro 0x0000000000000000 0x174 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .debug_macro 0x0000000000000000 0x53 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .debug_macro 0x0000000000000000 0x946 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .debug_macro 0x0000000000000000 0x5f3 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .debug_macro 0x0000000000000000 0x12f Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .debug_macro 0x0000000000000000 0x1a7 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .debug_macro 0x0000000000000000 0x1a7 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .debug_macro 0x0000000000000000 0x22c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .debug_macro 0x0000000000000000 0x34 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .debug_macro 0x0000000000000000 0x43 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .debug_macro 0x0000000000000000 0x28 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .debug_macro 0x0000000000000000 0xb0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .debug_macro 0x0000000000000000 0x217 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .debug_macro 0x0000000000000000 0x22c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .debug_macro 0x0000000000000000 0x5f Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .debug_macro 0x0000000000000000 0xa5 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .debug_macro 0x0000000000000000 0x65 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .debug_macro 0x0000000000000000 0x234 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .debug_macro 0x0000000000000000 0x4c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .debug_macro 0x0000000000000000 0x16d Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .debug_macro 0x0000000000000000 0x130 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .text 0x0000000000000000 0x0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .data 0x0000000000000000 0x0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .bss 0x0000000000000000 0x0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .text.HAL_PWR_DeInit + 0x0000000000000000 0x2c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .text.HAL_PWR_EnableBkUpAccess + 0x0000000000000000 0x1c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .text.HAL_PWR_DisableBkUpAccess + 0x0000000000000000 0x20 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .text.HAL_PWR_EnableWakeUpPin + 0x0000000000000000 0x20 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .text.HAL_PWR_DisableWakeUpPin + 0x0000000000000000 0x24 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .text.HAL_PWR_EnterSLEEPMode + 0x0000000000000000 0x38 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .text.HAL_PWR_EnterSTOPMode + 0x0000000000000000 0x68 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .text.HAL_PWR_EnterSTANDBYMode + 0x0000000000000000 0x2c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .text.HAL_PWR_EnableSleepOnExit + 0x0000000000000000 0x1c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .text.HAL_PWR_DisableSleepOnExit + 0x0000000000000000 0x1c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .text.HAL_PWR_EnableSEVOnPend + 0x0000000000000000 0x1c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .text.HAL_PWR_DisableSEVOnPend + 0x0000000000000000 0x1c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .debug_info 0x0000000000000000 0x43a Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .debug_abbrev 0x0000000000000000 0x15f Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .debug_aranges + 0x0000000000000000 0x78 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .debug_ranges 0x0000000000000000 0x68 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .debug_macro 0x0000000000000000 0x1b5 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .debug_macro 0x0000000000000000 0xa48 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .debug_macro 0x0000000000000000 0x12d Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .debug_macro 0x0000000000000000 0x2e Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .debug_macro 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .debug_macro 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .debug_macro 0x0000000000000000 0x8e Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .debug_macro 0x0000000000000000 0x51 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .debug_macro 0x0000000000000000 0xef Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .debug_macro 0x0000000000000000 0x6a Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .debug_macro 0x0000000000000000 0x1df Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .debug_macro 0x0000000000000000 0x1c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .debug_macro 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .debug_macro 0x0000000000000000 0xb5 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .debug_macro 0x0000000000000000 0x391 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .debug_macro 0x0000000000000000 0xfe50 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .debug_macro 0x0000000000000000 0x3c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .debug_macro 0x0000000000000000 0x174 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .debug_macro 0x0000000000000000 0x53 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .debug_macro 0x0000000000000000 0x946 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .debug_macro 0x0000000000000000 0x5f3 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .debug_macro 0x0000000000000000 0x12f Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .debug_macro 0x0000000000000000 0x1a7 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .debug_macro 0x0000000000000000 0x1a7 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .debug_macro 0x0000000000000000 0x22c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .debug_macro 0x0000000000000000 0x34 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .debug_macro 0x0000000000000000 0x43 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .debug_macro 0x0000000000000000 0x28 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .debug_macro 0x0000000000000000 0xb0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .debug_macro 0x0000000000000000 0x217 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .debug_macro 0x0000000000000000 0x22c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .debug_macro 0x0000000000000000 0x5f Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .debug_macro 0x0000000000000000 0xa5 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .debug_macro 0x0000000000000000 0x65 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .debug_macro 0x0000000000000000 0x234 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .debug_macro 0x0000000000000000 0x4c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .debug_macro 0x0000000000000000 0x16d Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .debug_macro 0x0000000000000000 0x130 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .debug_line 0x0000000000000000 0x768 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .debug_str 0x0000000000000000 0x70e51 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .comment 0x0000000000000000 0x7c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .debug_frame 0x0000000000000000 0x170 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .ARM.attributes + 0x0000000000000000 0x31 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .text 0x0000000000000000 0x0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .data 0x0000000000000000 0x0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .bss 0x0000000000000000 0x0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .text.HAL_PWR_ConfigPVD + 0x0000000000000000 0xc4 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .text.HAL_PWR_EnablePVD + 0x0000000000000000 0x1c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .text.HAL_PWR_DisablePVD + 0x0000000000000000 0x1c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .text.HAL_PWR_PVD_IRQHandler + 0x0000000000000000 0x28 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .text.HAL_PWR_PVDCallback + 0x0000000000000000 0xa Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .text.HAL_PWREx_EnableVddio2Monitor + 0x0000000000000000 0x2c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .text.HAL_PWREx_DisableVddio2Monitor + 0x0000000000000000 0x34 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .text.HAL_PWREx_Vddio2Monitor_IRQHandler + 0x0000000000000000 0x24 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .text.HAL_PWREx_Vddio2MonitorCallback + 0x0000000000000000 0xa Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .debug_info 0x0000000000000000 0x2d7 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .debug_abbrev 0x0000000000000000 0x155 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .debug_aranges + 0x0000000000000000 0x60 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .debug_ranges 0x0000000000000000 0x50 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .debug_macro 0x0000000000000000 0x1cd Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .debug_macro 0x0000000000000000 0xa48 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .debug_macro 0x0000000000000000 0x12d Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .debug_macro 0x0000000000000000 0x2e Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .debug_macro 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .debug_macro 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .debug_macro 0x0000000000000000 0x8e Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .debug_macro 0x0000000000000000 0x51 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .debug_macro 0x0000000000000000 0xef Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .debug_macro 0x0000000000000000 0x6a Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .debug_macro 0x0000000000000000 0x1df Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .debug_macro 0x0000000000000000 0x1c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .debug_macro 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .debug_macro 0x0000000000000000 0xb5 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .debug_macro 0x0000000000000000 0x391 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .debug_macro 0x0000000000000000 0xfe50 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .debug_macro 0x0000000000000000 0x3c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .debug_macro 0x0000000000000000 0x174 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .debug_macro 0x0000000000000000 0x53 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .debug_macro 0x0000000000000000 0x946 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .debug_macro 0x0000000000000000 0x5f3 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .debug_macro 0x0000000000000000 0x12f Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .debug_macro 0x0000000000000000 0x1a7 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .debug_macro 0x0000000000000000 0x1a7 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .debug_macro 0x0000000000000000 0x22c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .debug_macro 0x0000000000000000 0x34 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .debug_macro 0x0000000000000000 0x43 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .debug_macro 0x0000000000000000 0x28 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .debug_macro 0x0000000000000000 0xb0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .debug_macro 0x0000000000000000 0x217 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .debug_macro 0x0000000000000000 0x22c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .debug_macro 0x0000000000000000 0x5f Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .debug_macro 0x0000000000000000 0xa5 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .debug_macro 0x0000000000000000 0x65 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .debug_macro 0x0000000000000000 0x234 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .debug_macro 0x0000000000000000 0x4c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .debug_macro 0x0000000000000000 0x16d Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .debug_macro 0x0000000000000000 0x130 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .debug_line 0x0000000000000000 0x72e Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .debug_str 0x0000000000000000 0x70e1c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .comment 0x0000000000000000 0x7c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .debug_frame 0x0000000000000000 0x110 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .ARM.attributes + 0x0000000000000000 0x31 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .text 0x0000000000000000 0x0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .data 0x0000000000000000 0x0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .bss 0x0000000000000000 0x0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .text.HAL_RCC_DeInit + 0x0000000000000000 0x10c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .text.HAL_RCC_MCOConfig + 0x0000000000000000 0x80 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .text.HAL_RCC_EnableCSS + 0x0000000000000000 0x1c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .text.HAL_RCC_DisableCSS + 0x0000000000000000 0x20 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .text.HAL_RCC_GetHCLKFreq + 0x0000000000000000 0x14 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .text.HAL_RCC_GetPCLK1Freq + 0x0000000000000000 0x2c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .text.HAL_RCC_GetOscConfig + 0x0000000000000000 0x158 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .text.HAL_RCC_GetClockConfig + 0x0000000000000000 0x54 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .text.HAL_RCC_NMI_IRQHandler + 0x0000000000000000 0x28 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .text.HAL_RCC_CSSCallback + 0x0000000000000000 0xa Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .debug_macro 0x0000000000000000 0xa48 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .debug_macro 0x0000000000000000 0x12d Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .debug_macro 0x0000000000000000 0x2e Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .debug_macro 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .debug_macro 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .debug_macro 0x0000000000000000 0x8e Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .debug_macro 0x0000000000000000 0x51 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .debug_macro 0x0000000000000000 0xef Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .debug_macro 0x0000000000000000 0x6a Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .debug_macro 0x0000000000000000 0x1df Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .debug_macro 0x0000000000000000 0x1c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .debug_macro 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .debug_macro 0x0000000000000000 0xb5 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .debug_macro 0x0000000000000000 0x391 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .debug_macro 0x0000000000000000 0xfe50 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .debug_macro 0x0000000000000000 0x3c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .debug_macro 0x0000000000000000 0x174 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .debug_macro 0x0000000000000000 0x53 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .debug_macro 0x0000000000000000 0x946 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .debug_macro 0x0000000000000000 0x5f3 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .debug_macro 0x0000000000000000 0x12f Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .debug_macro 0x0000000000000000 0x1a7 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .debug_macro 0x0000000000000000 0x1a7 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .debug_macro 0x0000000000000000 0x22c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .debug_macro 0x0000000000000000 0x34 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .debug_macro 0x0000000000000000 0x43 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .debug_macro 0x0000000000000000 0x28 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .debug_macro 0x0000000000000000 0xb0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .debug_macro 0x0000000000000000 0x217 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .debug_macro 0x0000000000000000 0x22c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .debug_macro 0x0000000000000000 0x5f Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .debug_macro 0x0000000000000000 0xa5 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .debug_macro 0x0000000000000000 0x65 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .debug_macro 0x0000000000000000 0x234 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .debug_macro 0x0000000000000000 0x4c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .debug_macro 0x0000000000000000 0x16d Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .debug_macro 0x0000000000000000 0x130 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .text 0x0000000000000000 0x0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .data 0x0000000000000000 0x0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .bss 0x0000000000000000 0x0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .text.HAL_RCCEx_GetPeriphCLKConfig + 0x0000000000000000 0x94 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .text.HAL_RCCEx_GetPeriphCLKFreq + 0x0000000000000000 0x2f0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .text.HAL_RCCEx_CRSConfig + 0x0000000000000000 0x90 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .text.HAL_RCCEx_CRSSoftwareSynchronizationGenerate + 0x0000000000000000 0x1c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .text.HAL_RCCEx_CRSGetSynchronizationInfo + 0x0000000000000000 0x4c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .text.HAL_RCCEx_CRSWaitSynchronization + 0x0000000000000000 0xf4 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .text.HAL_RCCEx_CRS_IRQHandler + 0x0000000000000000 0xcc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .text.HAL_RCCEx_CRS_SyncOkCallback + 0x0000000000000000 0xa Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .text.HAL_RCCEx_CRS_SyncWarnCallback + 0x0000000000000000 0xa Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .text.HAL_RCCEx_CRS_ExpectedSyncCallback + 0x0000000000000000 0xa Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .text.HAL_RCCEx_CRS_ErrorCallback + 0x0000000000000000 0x10 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .debug_macro 0x0000000000000000 0xa48 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .debug_macro 0x0000000000000000 0x12d Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .debug_macro 0x0000000000000000 0x2e Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .debug_macro 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .debug_macro 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .debug_macro 0x0000000000000000 0x8e Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .debug_macro 0x0000000000000000 0x51 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .debug_macro 0x0000000000000000 0xef Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .debug_macro 0x0000000000000000 0x6a Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .debug_macro 0x0000000000000000 0x1df Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .debug_macro 0x0000000000000000 0x1c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .debug_macro 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .debug_macro 0x0000000000000000 0xb5 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .debug_macro 0x0000000000000000 0x391 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .debug_macro 0x0000000000000000 0xfe50 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .debug_macro 0x0000000000000000 0x3c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .debug_macro 0x0000000000000000 0x174 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .debug_macro 0x0000000000000000 0x53 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .debug_macro 0x0000000000000000 0x946 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .debug_macro 0x0000000000000000 0x5f3 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .debug_macro 0x0000000000000000 0x12f Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .debug_macro 0x0000000000000000 0x1a7 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .debug_macro 0x0000000000000000 0x1a7 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .debug_macro 0x0000000000000000 0x22c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .debug_macro 0x0000000000000000 0x34 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .debug_macro 0x0000000000000000 0x43 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .debug_macro 0x0000000000000000 0x28 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .debug_macro 0x0000000000000000 0xb0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .debug_macro 0x0000000000000000 0x217 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .debug_macro 0x0000000000000000 0x22c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .debug_macro 0x0000000000000000 0x5f Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .debug_macro 0x0000000000000000 0xa5 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .debug_macro 0x0000000000000000 0x65 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .debug_macro 0x0000000000000000 0x234 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .debug_macro 0x0000000000000000 0x4c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .debug_macro 0x0000000000000000 0x16d Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .debug_macro 0x0000000000000000 0x130 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .text 0x0000000000000000 0x0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .data 0x0000000000000000 0x0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .bss 0x0000000000000000 0x0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .debug_info 0x0000000000000000 0x145 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .debug_abbrev 0x0000000000000000 0x92 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .debug_aranges + 0x0000000000000000 0x18 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .debug_macro 0x0000000000000000 0x1b6 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .debug_macro 0x0000000000000000 0xa48 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .debug_macro 0x0000000000000000 0x12d Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .debug_macro 0x0000000000000000 0x2e Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .debug_macro 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .debug_macro 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .debug_macro 0x0000000000000000 0x8e Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .debug_macro 0x0000000000000000 0x51 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .debug_macro 0x0000000000000000 0xef Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .debug_macro 0x0000000000000000 0x6a Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .debug_macro 0x0000000000000000 0x1df Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .debug_macro 0x0000000000000000 0x1c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .debug_macro 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .debug_macro 0x0000000000000000 0xb5 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .debug_macro 0x0000000000000000 0x391 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .debug_macro 0x0000000000000000 0xfe50 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .debug_macro 0x0000000000000000 0x3c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .debug_macro 0x0000000000000000 0x174 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .debug_macro 0x0000000000000000 0x53 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .debug_macro 0x0000000000000000 0x946 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .debug_macro 0x0000000000000000 0x5f3 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .debug_macro 0x0000000000000000 0x12f Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .debug_macro 0x0000000000000000 0x1a7 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .debug_macro 0x0000000000000000 0x1a7 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .debug_macro 0x0000000000000000 0x22c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .debug_macro 0x0000000000000000 0x34 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .debug_macro 0x0000000000000000 0x43 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .debug_macro 0x0000000000000000 0x28 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .debug_macro 0x0000000000000000 0xb0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .debug_macro 0x0000000000000000 0x217 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .debug_macro 0x0000000000000000 0x22c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .debug_macro 0x0000000000000000 0x5f Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .debug_macro 0x0000000000000000 0xa5 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .debug_macro 0x0000000000000000 0x65 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .debug_macro 0x0000000000000000 0x234 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .debug_macro 0x0000000000000000 0x4c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .debug_macro 0x0000000000000000 0x16d Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .debug_macro 0x0000000000000000 0x130 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .debug_line 0x0000000000000000 0x67a Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .debug_str 0x0000000000000000 0x70c6e Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .comment 0x0000000000000000 0x7c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .ARM.attributes + 0x0000000000000000 0x31 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .text 0x0000000000000000 0x0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .data 0x0000000000000000 0x0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .bss 0x0000000000000000 0x0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .debug_info 0x0000000000000000 0x145 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .debug_abbrev 0x0000000000000000 0x92 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .debug_aranges + 0x0000000000000000 0x18 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .debug_macro 0x0000000000000000 0x1b5 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .debug_macro 0x0000000000000000 0xa48 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .debug_macro 0x0000000000000000 0x12d Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .debug_macro 0x0000000000000000 0x2e Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .debug_macro 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .debug_macro 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .debug_macro 0x0000000000000000 0x8e Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .debug_macro 0x0000000000000000 0x51 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .debug_macro 0x0000000000000000 0xef Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .debug_macro 0x0000000000000000 0x6a Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .debug_macro 0x0000000000000000 0x1df Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .debug_macro 0x0000000000000000 0x1c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .debug_macro 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .debug_macro 0x0000000000000000 0xb5 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .debug_macro 0x0000000000000000 0x391 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .debug_macro 0x0000000000000000 0xfe50 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .debug_macro 0x0000000000000000 0x3c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .debug_macro 0x0000000000000000 0x174 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .debug_macro 0x0000000000000000 0x53 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .debug_macro 0x0000000000000000 0x946 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .debug_macro 0x0000000000000000 0x5f3 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .debug_macro 0x0000000000000000 0x12f Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .debug_macro 0x0000000000000000 0x1a7 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .debug_macro 0x0000000000000000 0x1a7 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .debug_macro 0x0000000000000000 0x22c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .debug_macro 0x0000000000000000 0x34 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .debug_macro 0x0000000000000000 0x43 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .debug_macro 0x0000000000000000 0x28 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .debug_macro 0x0000000000000000 0xb0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .debug_macro 0x0000000000000000 0x217 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .debug_macro 0x0000000000000000 0x22c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .debug_macro 0x0000000000000000 0x5f Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .debug_macro 0x0000000000000000 0xa5 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .debug_macro 0x0000000000000000 0x65 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .debug_macro 0x0000000000000000 0x234 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .debug_macro 0x0000000000000000 0x4c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .debug_macro 0x0000000000000000 0x16d Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .debug_macro 0x0000000000000000 0x130 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .debug_line 0x0000000000000000 0x67d Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .debug_str 0x0000000000000000 0x70c71 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .comment 0x0000000000000000 0x7c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .ARM.attributes + 0x0000000000000000 0x31 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .text 0x0000000000000000 0x0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .data 0x0000000000000000 0x0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .bss 0x0000000000000000 0x0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .text.USB_CoreInit + 0x0000000000000000 0x38 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .text.USB_SetCurrentMode + 0x0000000000000000 0x18 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .text.USB_SetDevSpeed + 0x0000000000000000 0x18 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .text.USB_FlushTxFifo + 0x0000000000000000 0x14 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .text.USB_FlushRxFifo + 0x0000000000000000 0x12 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .text.USB_WritePacket + 0x0000000000000000 0x20 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .text.USB_ReadPacket + 0x0000000000000000 0x18 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .text.USB_StopDevice + 0x0000000000000000 0x2a Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .text.USB_DevDisconnect + 0x0000000000000000 0x26 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .text.USB_ReadDevAllOutEpInterrupt + 0x0000000000000000 0x12 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .text.USB_ReadDevAllInEpInterrupt + 0x0000000000000000 0x12 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .text.USB_ReadDevOutEPInterrupt + 0x0000000000000000 0x18 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .text.USB_ReadDevInEPInterrupt + 0x0000000000000000 0x18 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .text.USB_ClearInterrupts + 0x0000000000000000 0x12 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .text.USB_ActivateRemoteWakeup + 0x0000000000000000 0x26 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .text.USB_DeActivateRemoteWakeup + 0x0000000000000000 0x26 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .debug_macro 0x0000000000000000 0xa48 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .debug_macro 0x0000000000000000 0x12d Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .debug_macro 0x0000000000000000 0x2e Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .debug_macro 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .debug_macro 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .debug_macro 0x0000000000000000 0x8e Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .debug_macro 0x0000000000000000 0x51 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .debug_macro 0x0000000000000000 0xef Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .debug_macro 0x0000000000000000 0x6a Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .debug_macro 0x0000000000000000 0x1df Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .debug_macro 0x0000000000000000 0x1c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .debug_macro 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .debug_macro 0x0000000000000000 0xb5 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .debug_macro 0x0000000000000000 0x391 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .debug_macro 0x0000000000000000 0xfe50 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .debug_macro 0x0000000000000000 0x3c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .debug_macro 0x0000000000000000 0x174 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .debug_macro 0x0000000000000000 0x53 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .debug_macro 0x0000000000000000 0x946 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .debug_macro 0x0000000000000000 0x5f3 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .debug_macro 0x0000000000000000 0x12f Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .debug_macro 0x0000000000000000 0x1a7 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .debug_macro 0x0000000000000000 0x1a7 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .debug_macro 0x0000000000000000 0x22c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .debug_macro 0x0000000000000000 0x34 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .debug_macro 0x0000000000000000 0x43 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .debug_macro 0x0000000000000000 0x28 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .debug_macro 0x0000000000000000 0xb0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .debug_macro 0x0000000000000000 0x217 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .debug_macro 0x0000000000000000 0x22c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .debug_macro 0x0000000000000000 0x5f Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .debug_macro 0x0000000000000000 0xa5 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .debug_macro 0x0000000000000000 0x65 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .debug_macro 0x0000000000000000 0x234 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .debug_macro 0x0000000000000000 0x4c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .debug_macro 0x0000000000000000 0x16d Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .debug_macro 0x0000000000000000 0x130 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .group 0x0000000000000000 0xc ecm_src/dhcp-server/dhserver.o + .group 0x0000000000000000 0xc ecm_src/dhcp-server/dhserver.o + .group 0x0000000000000000 0xc ecm_src/dhcp-server/dhserver.o + .group 0x0000000000000000 0xc ecm_src/dhcp-server/dhserver.o + .group 0x0000000000000000 0xc ecm_src/dhcp-server/dhserver.o + .group 0x0000000000000000 0xc ecm_src/dhcp-server/dhserver.o + .group 0x0000000000000000 0xc ecm_src/dhcp-server/dhserver.o + .group 0x0000000000000000 0xc ecm_src/dhcp-server/dhserver.o + .group 0x0000000000000000 0xc ecm_src/dhcp-server/dhserver.o + .group 0x0000000000000000 0xc ecm_src/dhcp-server/dhserver.o + .group 0x0000000000000000 0xc ecm_src/dhcp-server/dhserver.o + .group 0x0000000000000000 0xc ecm_src/dhcp-server/dhserver.o + .group 0x0000000000000000 0xc ecm_src/dhcp-server/dhserver.o + .group 0x0000000000000000 0xc ecm_src/dhcp-server/dhserver.o + .group 0x0000000000000000 0xc ecm_src/dhcp-server/dhserver.o + .group 0x0000000000000000 0xc ecm_src/dhcp-server/dhserver.o + .group 0x0000000000000000 0xc ecm_src/dhcp-server/dhserver.o + .group 0x0000000000000000 0xc ecm_src/dhcp-server/dhserver.o + .group 0x0000000000000000 0xc ecm_src/dhcp-server/dhserver.o + .group 0x0000000000000000 0xc ecm_src/dhcp-server/dhserver.o + .group 0x0000000000000000 0xc ecm_src/dhcp-server/dhserver.o + .group 0x0000000000000000 0xc ecm_src/dhcp-server/dhserver.o + .group 0x0000000000000000 0xc ecm_src/dhcp-server/dhserver.o + .group 0x0000000000000000 0xc ecm_src/dhcp-server/dhserver.o + .group 0x0000000000000000 0xc ecm_src/dhcp-server/dhserver.o + .group 0x0000000000000000 0xc ecm_src/dhcp-server/dhserver.o + .group 0x0000000000000000 0xc ecm_src/dhcp-server/dhserver.o + .group 0x0000000000000000 0xc ecm_src/dhcp-server/dhserver.o + .group 0x0000000000000000 0xc ecm_src/dhcp-server/dhserver.o + .group 0x0000000000000000 0xc ecm_src/dhcp-server/dhserver.o + .group 0x0000000000000000 0xc ecm_src/dhcp-server/dhserver.o + .group 0x0000000000000000 0xc ecm_src/dhcp-server/dhserver.o + .group 0x0000000000000000 0xc ecm_src/dhcp-server/dhserver.o + .group 0x0000000000000000 0xc ecm_src/dhcp-server/dhserver.o + .group 0x0000000000000000 0xc ecm_src/dhcp-server/dhserver.o + .group 0x0000000000000000 0xc ecm_src/dhcp-server/dhserver.o + .group 0x0000000000000000 0xc ecm_src/dhcp-server/dhserver.o + .group 0x0000000000000000 0xc ecm_src/dhcp-server/dhserver.o + .group 0x0000000000000000 0xc ecm_src/dhcp-server/dhserver.o + .group 0x0000000000000000 0xc ecm_src/dhcp-server/dhserver.o + .group 0x0000000000000000 0xc ecm_src/dhcp-server/dhserver.o + .group 0x0000000000000000 0xc ecm_src/dhcp-server/dhserver.o + .group 0x0000000000000000 0xc ecm_src/dhcp-server/dhserver.o + .group 0x0000000000000000 0xc ecm_src/dhcp-server/dhserver.o + .group 0x0000000000000000 0xc ecm_src/dhcp-server/dhserver.o + .group 0x0000000000000000 0xc ecm_src/dhcp-server/dhserver.o + .group 0x0000000000000000 0xc ecm_src/dhcp-server/dhserver.o + .group 0x0000000000000000 0xc ecm_src/dhcp-server/dhserver.o + .group 0x0000000000000000 0xc ecm_src/dhcp-server/dhserver.o + .group 0x0000000000000000 0xc ecm_src/dhcp-server/dhserver.o + .group 0x0000000000000000 0xc ecm_src/dhcp-server/dhserver.o + .text 0x0000000000000000 0x0 ecm_src/dhcp-server/dhserver.o + .data 0x0000000000000000 0x0 ecm_src/dhcp-server/dhserver.o + .bss 0x0000000000000000 0x0 ecm_src/dhcp-server/dhserver.o + .debug_macro 0x0000000000000000 0xa48 ecm_src/dhcp-server/dhserver.o + .debug_macro 0x0000000000000000 0x22 ecm_src/dhcp-server/dhserver.o + .debug_macro 0x0000000000000000 0x8e ecm_src/dhcp-server/dhserver.o + .debug_macro 0x0000000000000000 0x51 ecm_src/dhcp-server/dhserver.o + .debug_macro 0x0000000000000000 0xef ecm_src/dhcp-server/dhserver.o + .debug_macro 0x0000000000000000 0x6a ecm_src/dhcp-server/dhserver.o + .debug_macro 0x0000000000000000 0x1df ecm_src/dhcp-server/dhserver.o + .debug_macro 0x0000000000000000 0x22 ecm_src/dhcp-server/dhserver.o + .debug_macro 0x0000000000000000 0x46 ecm_src/dhcp-server/dhserver.o + .debug_macro 0x0000000000000000 0x18 ecm_src/dhcp-server/dhserver.o + .debug_macro 0x0000000000000000 0x3c ecm_src/dhcp-server/dhserver.o + .debug_macro 0x0000000000000000 0x34 ecm_src/dhcp-server/dhserver.o + .debug_macro 0x0000000000000000 0x16 ecm_src/dhcp-server/dhserver.o + .debug_macro 0x0000000000000000 0x330 ecm_src/dhcp-server/dhserver.o + .debug_macro 0x0000000000000000 0x10 ecm_src/dhcp-server/dhserver.o + .debug_macro 0x0000000000000000 0x52 ecm_src/dhcp-server/dhserver.o + .debug_macro 0x0000000000000000 0x1f ecm_src/dhcp-server/dhserver.o + .debug_macro 0x0000000000000000 0x43 ecm_src/dhcp-server/dhserver.o + .debug_macro 0x0000000000000000 0x20 ecm_src/dhcp-server/dhserver.o + .debug_macro 0x0000000000000000 0x1a3 ecm_src/dhcp-server/dhserver.o + .debug_macro 0x0000000000000000 0x10 ecm_src/dhcp-server/dhserver.o + .debug_macro 0x0000000000000000 0x1c ecm_src/dhcp-server/dhserver.o + .debug_macro 0x0000000000000000 0x52 ecm_src/dhcp-server/dhserver.o + .debug_macro 0x0000000000000000 0x40 ecm_src/dhcp-server/dhserver.o + .debug_macro 0x0000000000000000 0x10 ecm_src/dhcp-server/dhserver.o + .debug_macro 0x0000000000000000 0x40 ecm_src/dhcp-server/dhserver.o + .debug_macro 0x0000000000000000 0xd7 ecm_src/dhcp-server/dhserver.o + .debug_macro 0x0000000000000000 0x1c ecm_src/dhcp-server/dhserver.o + .debug_macro 0x0000000000000000 0x3d ecm_src/dhcp-server/dhserver.o + .debug_macro 0x0000000000000000 0x16 ecm_src/dhcp-server/dhserver.o + .debug_macro 0x0000000000000000 0x145 ecm_src/dhcp-server/dhserver.o + .debug_macro 0x0000000000000000 0x16 ecm_src/dhcp-server/dhserver.o + .debug_macro 0x0000000000000000 0x35 ecm_src/dhcp-server/dhserver.o + .debug_macro 0x0000000000000000 0x20 ecm_src/dhcp-server/dhserver.o + .debug_macro 0x0000000000000000 0x70 ecm_src/dhcp-server/dhserver.o + .debug_macro 0x0000000000000000 0x16 ecm_src/dhcp-server/dhserver.o + .debug_macro 0x0000000000000000 0x22 ecm_src/dhcp-server/dhserver.o + .debug_macro 0x0000000000000000 0x16 ecm_src/dhcp-server/dhserver.o + .debug_macro 0x0000000000000000 0x5e ecm_src/dhcp-server/dhserver.o + .debug_macro 0x0000000000000000 0x592 ecm_src/dhcp-server/dhserver.o + .debug_macro 0x0000000000000000 0x52 ecm_src/dhcp-server/dhserver.o + .debug_macro 0x0000000000000000 0x175 ecm_src/dhcp-server/dhserver.o + .debug_macro 0x0000000000000000 0x13b ecm_src/dhcp-server/dhserver.o + .group 0x0000000000000000 0xc ecm_src/dns-server/dnserver.o + .group 0x0000000000000000 0xc ecm_src/dns-server/dnserver.o + .group 0x0000000000000000 0xc ecm_src/dns-server/dnserver.o + .group 0x0000000000000000 0xc ecm_src/dns-server/dnserver.o + .group 0x0000000000000000 0xc ecm_src/dns-server/dnserver.o + .group 0x0000000000000000 0xc ecm_src/dns-server/dnserver.o + .group 0x0000000000000000 0xc ecm_src/dns-server/dnserver.o + .group 0x0000000000000000 0xc ecm_src/dns-server/dnserver.o + .group 0x0000000000000000 0xc ecm_src/dns-server/dnserver.o + .group 0x0000000000000000 0xc ecm_src/dns-server/dnserver.o + .group 0x0000000000000000 0xc ecm_src/dns-server/dnserver.o + .group 0x0000000000000000 0xc ecm_src/dns-server/dnserver.o + .group 0x0000000000000000 0xc ecm_src/dns-server/dnserver.o + .group 0x0000000000000000 0xc ecm_src/dns-server/dnserver.o + .group 0x0000000000000000 0xc ecm_src/dns-server/dnserver.o + .group 0x0000000000000000 0xc ecm_src/dns-server/dnserver.o + .group 0x0000000000000000 0xc ecm_src/dns-server/dnserver.o + .group 0x0000000000000000 0xc ecm_src/dns-server/dnserver.o + .group 0x0000000000000000 0xc ecm_src/dns-server/dnserver.o + .group 0x0000000000000000 0xc ecm_src/dns-server/dnserver.o + .group 0x0000000000000000 0xc ecm_src/dns-server/dnserver.o + .group 0x0000000000000000 0xc ecm_src/dns-server/dnserver.o + .group 0x0000000000000000 0xc ecm_src/dns-server/dnserver.o + .group 0x0000000000000000 0xc ecm_src/dns-server/dnserver.o + .group 0x0000000000000000 0xc ecm_src/dns-server/dnserver.o + .group 0x0000000000000000 0xc ecm_src/dns-server/dnserver.o + .group 0x0000000000000000 0xc ecm_src/dns-server/dnserver.o + .group 0x0000000000000000 0xc ecm_src/dns-server/dnserver.o + .group 0x0000000000000000 0xc ecm_src/dns-server/dnserver.o + .group 0x0000000000000000 0xc ecm_src/dns-server/dnserver.o + .group 0x0000000000000000 0xc ecm_src/dns-server/dnserver.o + .group 0x0000000000000000 0xc ecm_src/dns-server/dnserver.o + .group 0x0000000000000000 0xc ecm_src/dns-server/dnserver.o + .group 0x0000000000000000 0xc ecm_src/dns-server/dnserver.o + .group 0x0000000000000000 0xc ecm_src/dns-server/dnserver.o + .group 0x0000000000000000 0xc ecm_src/dns-server/dnserver.o + .group 0x0000000000000000 0xc ecm_src/dns-server/dnserver.o + .group 0x0000000000000000 0xc ecm_src/dns-server/dnserver.o + .group 0x0000000000000000 0xc ecm_src/dns-server/dnserver.o + .group 0x0000000000000000 0xc ecm_src/dns-server/dnserver.o + .group 0x0000000000000000 0xc ecm_src/dns-server/dnserver.o + .group 0x0000000000000000 0xc ecm_src/dns-server/dnserver.o + .group 0x0000000000000000 0xc ecm_src/dns-server/dnserver.o + .group 0x0000000000000000 0xc ecm_src/dns-server/dnserver.o + .group 0x0000000000000000 0xc ecm_src/dns-server/dnserver.o + .group 0x0000000000000000 0xc ecm_src/dns-server/dnserver.o + .group 0x0000000000000000 0xc ecm_src/dns-server/dnserver.o + .group 0x0000000000000000 0xc ecm_src/dns-server/dnserver.o + .group 0x0000000000000000 0xc ecm_src/dns-server/dnserver.o + .group 0x0000000000000000 0xc ecm_src/dns-server/dnserver.o + .group 0x0000000000000000 0xc ecm_src/dns-server/dnserver.o + .text 0x0000000000000000 0x0 ecm_src/dns-server/dnserver.o + .data 0x0000000000000000 0x0 ecm_src/dns-server/dnserver.o + .bss 0x0000000000000000 0x0 ecm_src/dns-server/dnserver.o + .debug_macro 0x0000000000000000 0xa48 ecm_src/dns-server/dnserver.o + .debug_macro 0x0000000000000000 0x22 ecm_src/dns-server/dnserver.o + .debug_macro 0x0000000000000000 0x8e ecm_src/dns-server/dnserver.o + .debug_macro 0x0000000000000000 0x51 ecm_src/dns-server/dnserver.o + .debug_macro 0x0000000000000000 0xef ecm_src/dns-server/dnserver.o + .debug_macro 0x0000000000000000 0x6a ecm_src/dns-server/dnserver.o + .debug_macro 0x0000000000000000 0x1df ecm_src/dns-server/dnserver.o + .debug_macro 0x0000000000000000 0x22 ecm_src/dns-server/dnserver.o + .debug_macro 0x0000000000000000 0x46 ecm_src/dns-server/dnserver.o + .debug_macro 0x0000000000000000 0x18 ecm_src/dns-server/dnserver.o + .debug_macro 0x0000000000000000 0x3c ecm_src/dns-server/dnserver.o + .debug_macro 0x0000000000000000 0x34 ecm_src/dns-server/dnserver.o + .debug_macro 0x0000000000000000 0x16 ecm_src/dns-server/dnserver.o + .debug_macro 0x0000000000000000 0x97 ecm_src/dns-server/dnserver.o + .debug_macro 0x0000000000000000 0x330 ecm_src/dns-server/dnserver.o + .debug_macro 0x0000000000000000 0xfd ecm_src/dns-server/dnserver.o + .debug_macro 0x0000000000000000 0x10 ecm_src/dns-server/dnserver.o + .debug_macro 0x0000000000000000 0x52 ecm_src/dns-server/dnserver.o + .debug_macro 0x0000000000000000 0x1f ecm_src/dns-server/dnserver.o + .debug_macro 0x0000000000000000 0x43 ecm_src/dns-server/dnserver.o + .debug_macro 0x0000000000000000 0x20 ecm_src/dns-server/dnserver.o + .debug_macro 0x0000000000000000 0x1a3 ecm_src/dns-server/dnserver.o + .debug_macro 0x0000000000000000 0x10 ecm_src/dns-server/dnserver.o + .debug_macro 0x0000000000000000 0x1c ecm_src/dns-server/dnserver.o + .debug_macro 0x0000000000000000 0x52 ecm_src/dns-server/dnserver.o + .debug_macro 0x0000000000000000 0x40 ecm_src/dns-server/dnserver.o + .debug_macro 0x0000000000000000 0x10 ecm_src/dns-server/dnserver.o + .debug_macro 0x0000000000000000 0x40 ecm_src/dns-server/dnserver.o + .debug_macro 0x0000000000000000 0xd7 ecm_src/dns-server/dnserver.o + .debug_macro 0x0000000000000000 0x1c ecm_src/dns-server/dnserver.o + .debug_macro 0x0000000000000000 0x3d ecm_src/dns-server/dnserver.o + .debug_macro 0x0000000000000000 0x16 ecm_src/dns-server/dnserver.o + .debug_macro 0x0000000000000000 0x145 ecm_src/dns-server/dnserver.o + .debug_macro 0x0000000000000000 0x16 ecm_src/dns-server/dnserver.o + .debug_macro 0x0000000000000000 0x35 ecm_src/dns-server/dnserver.o + .debug_macro 0x0000000000000000 0x20 ecm_src/dns-server/dnserver.o + .debug_macro 0x0000000000000000 0x16 ecm_src/dns-server/dnserver.o + .debug_macro 0x0000000000000000 0x22 ecm_src/dns-server/dnserver.o + .debug_macro 0x0000000000000000 0x16 ecm_src/dns-server/dnserver.o + .debug_macro 0x0000000000000000 0x70 ecm_src/dns-server/dnserver.o + .debug_macro 0x0000000000000000 0x5e ecm_src/dns-server/dnserver.o + .debug_macro 0x0000000000000000 0x592 ecm_src/dns-server/dnserver.o + .debug_macro 0x0000000000000000 0x76 ecm_src/dns-server/dnserver.o + .debug_macro 0x0000000000000000 0x55 ecm_src/dns-server/dnserver.o + .debug_macro 0x0000000000000000 0x10 ecm_src/dns-server/dnserver.o + .debug_macro 0x0000000000000000 0x56 ecm_src/dns-server/dnserver.o + .debug_macro 0x0000000000000000 0x13b ecm_src/dns-server/dnserver.o + .debug_macro 0x0000000000000000 0x37 ecm_src/dns-server/dnserver.o + .debug_macro 0x0000000000000000 0x86 ecm_src/dns-server/dnserver.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/def.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/def.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/def.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/def.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/def.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/def.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/def.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/def.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/def.o + .text 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/def.o + .data 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/def.o + .bss 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/def.o + .debug_macro 0x0000000000000000 0xa48 ecm_src/lwip-1.4.1/src/core/def.o + .debug_macro 0x0000000000000000 0x70 ecm_src/lwip-1.4.1/src/core/def.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/core/def.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/core/def.o + .debug_macro 0x0000000000000000 0x5e ecm_src/lwip-1.4.1/src/core/def.o + .debug_macro 0x0000000000000000 0x592 ecm_src/lwip-1.4.1/src/core/def.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/dhcp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/dhcp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/dhcp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/dhcp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/dhcp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/dhcp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/dhcp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/dhcp.o + .text 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/dhcp.o + .data 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/dhcp.o + .bss 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/dhcp.o + .debug_info 0x0000000000000000 0x4c ecm_src/lwip-1.4.1/src/core/dhcp.o + .debug_abbrev 0x0000000000000000 0x1e ecm_src/lwip-1.4.1/src/core/dhcp.o + .debug_aranges + 0x0000000000000000 0x18 ecm_src/lwip-1.4.1/src/core/dhcp.o + .debug_macro 0x0000000000000000 0x62 ecm_src/lwip-1.4.1/src/core/dhcp.o + .debug_macro 0x0000000000000000 0xa48 ecm_src/lwip-1.4.1/src/core/dhcp.o + .debug_macro 0x0000000000000000 0x70 ecm_src/lwip-1.4.1/src/core/dhcp.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/core/dhcp.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/dhcp.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/core/dhcp.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/core/dhcp.o + .debug_macro 0x0000000000000000 0x5e ecm_src/lwip-1.4.1/src/core/dhcp.o + .debug_macro 0x0000000000000000 0x592 ecm_src/lwip-1.4.1/src/core/dhcp.o + .debug_line 0x0000000000000000 0x13f ecm_src/lwip-1.4.1/src/core/dhcp.o + .debug_str 0x0000000000000000 0x45b0 ecm_src/lwip-1.4.1/src/core/dhcp.o + .comment 0x0000000000000000 0x7c ecm_src/lwip-1.4.1/src/core/dhcp.o + .ARM.attributes + 0x0000000000000000 0x31 ecm_src/lwip-1.4.1/src/core/dhcp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/dns.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/dns.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/dns.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/dns.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/dns.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/dns.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/dns.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/dns.o + .text 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/dns.o + .data 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/dns.o + .bss 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/dns.o + .debug_info 0x0000000000000000 0x4c ecm_src/lwip-1.4.1/src/core/dns.o + .debug_abbrev 0x0000000000000000 0x1e ecm_src/lwip-1.4.1/src/core/dns.o + .debug_aranges + 0x0000000000000000 0x18 ecm_src/lwip-1.4.1/src/core/dns.o + .debug_macro 0x0000000000000000 0x62 ecm_src/lwip-1.4.1/src/core/dns.o + .debug_macro 0x0000000000000000 0xa48 ecm_src/lwip-1.4.1/src/core/dns.o + .debug_macro 0x0000000000000000 0x70 ecm_src/lwip-1.4.1/src/core/dns.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/core/dns.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/dns.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/core/dns.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/core/dns.o + .debug_macro 0x0000000000000000 0x5e ecm_src/lwip-1.4.1/src/core/dns.o + .debug_macro 0x0000000000000000 0x592 ecm_src/lwip-1.4.1/src/core/dns.o + .debug_line 0x0000000000000000 0x13e ecm_src/lwip-1.4.1/src/core/dns.o + .debug_str 0x0000000000000000 0x45af ecm_src/lwip-1.4.1/src/core/dns.o + .comment 0x0000000000000000 0x7c ecm_src/lwip-1.4.1/src/core/dns.o + .ARM.attributes + 0x0000000000000000 0x31 ecm_src/lwip-1.4.1/src/core/dns.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/init.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/init.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/init.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/init.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/init.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/init.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/init.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/init.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/init.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/init.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/init.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/init.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/init.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/init.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/init.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/init.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/init.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/init.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/init.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/init.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/init.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/init.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/init.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/init.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/init.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/init.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/init.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/init.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/init.o + .text 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/init.o + .data 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/init.o + .bss 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/init.o + .debug_macro 0x0000000000000000 0xa48 ecm_src/lwip-1.4.1/src/core/init.o + .debug_macro 0x0000000000000000 0x70 ecm_src/lwip-1.4.1/src/core/init.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/core/init.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/init.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/core/init.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/core/init.o + .debug_macro 0x0000000000000000 0x5e ecm_src/lwip-1.4.1/src/core/init.o + .debug_macro 0x0000000000000000 0x592 ecm_src/lwip-1.4.1/src/core/init.o + .debug_macro 0x0000000000000000 0x46 ecm_src/lwip-1.4.1/src/core/init.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/core/init.o + .debug_macro 0x0000000000000000 0x76 ecm_src/lwip-1.4.1/src/core/init.o + .debug_macro 0x0000000000000000 0x4f ecm_src/lwip-1.4.1/src/core/init.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/init.o + .debug_macro 0x0000000000000000 0x58 ecm_src/lwip-1.4.1/src/core/init.o + .debug_macro 0x0000000000000000 0x175 ecm_src/lwip-1.4.1/src/core/init.o + .debug_macro 0x0000000000000000 0x56 ecm_src/lwip-1.4.1/src/core/init.o + .debug_macro 0x0000000000000000 0x13b ecm_src/lwip-1.4.1/src/core/init.o + .debug_macro 0x0000000000000000 0x3d ecm_src/lwip-1.4.1/src/core/init.o + .debug_macro 0x0000000000000000 0x64 ecm_src/lwip-1.4.1/src/core/init.o + .debug_macro 0x0000000000000000 0xac ecm_src/lwip-1.4.1/src/core/init.o + .debug_macro 0x0000000000000000 0x1be ecm_src/lwip-1.4.1/src/core/init.o + .debug_macro 0x0000000000000000 0x86 ecm_src/lwip-1.4.1/src/core/init.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/mem.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/mem.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/mem.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/mem.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/mem.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/mem.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/mem.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/mem.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/mem.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/mem.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/mem.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/mem.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/mem.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/mem.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/mem.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/mem.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/mem.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/mem.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/mem.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/mem.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/mem.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/mem.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/mem.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/mem.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/mem.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/mem.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/mem.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/mem.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/mem.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/mem.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/mem.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/mem.o + .text 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/mem.o + .data 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/mem.o + .bss 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/mem.o + .text.mem_calloc + 0x0000000000000000 0x4e ecm_src/lwip-1.4.1/src/core/mem.o + .debug_macro 0x0000000000000000 0xa48 ecm_src/lwip-1.4.1/src/core/mem.o + .debug_macro 0x0000000000000000 0x70 ecm_src/lwip-1.4.1/src/core/mem.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/core/mem.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/mem.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/core/mem.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/core/mem.o + .debug_macro 0x0000000000000000 0x5e ecm_src/lwip-1.4.1/src/core/mem.o + .debug_macro 0x0000000000000000 0x592 ecm_src/lwip-1.4.1/src/core/mem.o + .debug_macro 0x0000000000000000 0x58 ecm_src/lwip-1.4.1/src/core/mem.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/core/mem.o + .debug_macro 0x0000000000000000 0xc5 ecm_src/lwip-1.4.1/src/core/mem.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/mem.o + .debug_macro 0x0000000000000000 0x3a ecm_src/lwip-1.4.1/src/core/mem.o + .debug_macro 0x0000000000000000 0x127 ecm_src/lwip-1.4.1/src/core/mem.o + .debug_macro 0x0000000000000000 0x76 ecm_src/lwip-1.4.1/src/core/mem.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/core/mem.o + .debug_macro 0x0000000000000000 0x40 ecm_src/lwip-1.4.1/src/core/mem.o + .debug_macro 0x0000000000000000 0x18 ecm_src/lwip-1.4.1/src/core/mem.o + .debug_macro 0x0000000000000000 0x94 ecm_src/lwip-1.4.1/src/core/mem.o + .debug_macro 0x0000000000000000 0x3c ecm_src/lwip-1.4.1/src/core/mem.o + .debug_macro 0x0000000000000000 0x34 ecm_src/lwip-1.4.1/src/core/mem.o + .debug_macro 0x0000000000000000 0x174 ecm_src/lwip-1.4.1/src/core/mem.o + .debug_macro 0x0000000000000000 0x57 ecm_src/lwip-1.4.1/src/core/mem.o + .debug_macro 0x0000000000000000 0x52 ecm_src/lwip-1.4.1/src/core/mem.o + .debug_macro 0x0000000000000000 0x1f ecm_src/lwip-1.4.1/src/core/mem.o + .debug_macro 0x0000000000000000 0x43 ecm_src/lwip-1.4.1/src/core/mem.o + .debug_macro 0x0000000000000000 0x20 ecm_src/lwip-1.4.1/src/core/mem.o + .debug_macro 0x0000000000000000 0x1a3 ecm_src/lwip-1.4.1/src/core/mem.o + .debug_macro 0x0000000000000000 0x330 ecm_src/lwip-1.4.1/src/core/mem.o + .debug_macro 0x0000000000000000 0x35 ecm_src/lwip-1.4.1/src/core/mem.o + .debug_macro 0x0000000000000000 0x20 ecm_src/lwip-1.4.1/src/core/mem.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/memp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/memp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/memp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/memp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/memp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/memp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/memp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/memp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/memp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/memp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/memp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/memp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/memp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/memp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/memp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/memp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/memp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/memp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/memp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/memp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/memp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/memp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/memp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/memp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/memp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/memp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/memp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/memp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/memp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/memp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/memp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/memp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/memp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/memp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/memp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/memp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/memp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/memp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/memp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/memp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/memp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/memp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/memp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/memp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/memp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/memp.o + .text 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/memp.o + .data 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/memp.o + .bss 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/memp.o + .debug_macro 0x0000000000000000 0xa48 ecm_src/lwip-1.4.1/src/core/memp.o + .debug_macro 0x0000000000000000 0x70 ecm_src/lwip-1.4.1/src/core/memp.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/core/memp.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/memp.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/core/memp.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/core/memp.o + .debug_macro 0x0000000000000000 0x5e ecm_src/lwip-1.4.1/src/core/memp.o + .debug_macro 0x0000000000000000 0x592 ecm_src/lwip-1.4.1/src/core/memp.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/memp.o + .debug_macro 0x0000000000000000 0x3a ecm_src/lwip-1.4.1/src/core/memp.o + .debug_macro 0x0000000000000000 0x76 ecm_src/lwip-1.4.1/src/core/memp.o + .debug_macro 0x0000000000000000 0x4f ecm_src/lwip-1.4.1/src/core/memp.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/memp.o + .debug_macro 0x0000000000000000 0x58 ecm_src/lwip-1.4.1/src/core/memp.o + .debug_macro 0x0000000000000000 0x175 ecm_src/lwip-1.4.1/src/core/memp.o + .debug_macro 0x0000000000000000 0x56 ecm_src/lwip-1.4.1/src/core/memp.o + .debug_macro 0x0000000000000000 0x13b ecm_src/lwip-1.4.1/src/core/memp.o + .debug_macro 0x0000000000000000 0x37 ecm_src/lwip-1.4.1/src/core/memp.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/memp.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/core/memp.o + .debug_macro 0x0000000000000000 0x64 ecm_src/lwip-1.4.1/src/core/memp.o + .debug_macro 0x0000000000000000 0xac ecm_src/lwip-1.4.1/src/core/memp.o + .debug_macro 0x0000000000000000 0x1be ecm_src/lwip-1.4.1/src/core/memp.o + .debug_macro 0x0000000000000000 0xc5 ecm_src/lwip-1.4.1/src/core/memp.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/core/memp.o + .debug_macro 0x0000000000000000 0x86 ecm_src/lwip-1.4.1/src/core/memp.o + .debug_macro 0x0000000000000000 0x321 ecm_src/lwip-1.4.1/src/core/memp.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/core/memp.o + .debug_macro 0x0000000000000000 0x40 ecm_src/lwip-1.4.1/src/core/memp.o + .debug_macro 0x0000000000000000 0x18 ecm_src/lwip-1.4.1/src/core/memp.o + .debug_macro 0x0000000000000000 0x94 ecm_src/lwip-1.4.1/src/core/memp.o + .debug_macro 0x0000000000000000 0x3c ecm_src/lwip-1.4.1/src/core/memp.o + .debug_macro 0x0000000000000000 0x34 ecm_src/lwip-1.4.1/src/core/memp.o + .debug_macro 0x0000000000000000 0x174 ecm_src/lwip-1.4.1/src/core/memp.o + .debug_macro 0x0000000000000000 0x57 ecm_src/lwip-1.4.1/src/core/memp.o + .debug_macro 0x0000000000000000 0x52 ecm_src/lwip-1.4.1/src/core/memp.o + .debug_macro 0x0000000000000000 0x1f ecm_src/lwip-1.4.1/src/core/memp.o + .debug_macro 0x0000000000000000 0x43 ecm_src/lwip-1.4.1/src/core/memp.o + .debug_macro 0x0000000000000000 0x20 ecm_src/lwip-1.4.1/src/core/memp.o + .debug_macro 0x0000000000000000 0x1a3 ecm_src/lwip-1.4.1/src/core/memp.o + .debug_macro 0x0000000000000000 0x330 ecm_src/lwip-1.4.1/src/core/memp.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/memp.o + .debug_macro 0x0000000000000000 0x35 ecm_src/lwip-1.4.1/src/core/memp.o + .debug_macro 0x0000000000000000 0x20 ecm_src/lwip-1.4.1/src/core/memp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/netif.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/netif.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/netif.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/netif.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/netif.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/netif.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/netif.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/netif.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/netif.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/netif.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/netif.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/netif.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/netif.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/netif.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/netif.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/netif.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/netif.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/netif.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/netif.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/netif.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/netif.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/netif.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/netif.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/netif.o + .text 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/netif.o + .data 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/netif.o + .bss 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/netif.o + .text.netif_remove + 0x0000000000000000 0x90 ecm_src/lwip-1.4.1/src/core/netif.o + .text.netif_find + 0x0000000000000000 0x74 ecm_src/lwip-1.4.1/src/core/netif.o + .text.netif_set_up + 0x0000000000000000 0x5a ecm_src/lwip-1.4.1/src/core/netif.o + .text.netif_set_down + 0x0000000000000000 0x46 ecm_src/lwip-1.4.1/src/core/netif.o + .text.netif_set_link_up + 0x0000000000000000 0x5a ecm_src/lwip-1.4.1/src/core/netif.o + .text.netif_set_link_down + 0x0000000000000000 0x30 ecm_src/lwip-1.4.1/src/core/netif.o + .debug_macro 0x0000000000000000 0xa48 ecm_src/lwip-1.4.1/src/core/netif.o + .debug_macro 0x0000000000000000 0x70 ecm_src/lwip-1.4.1/src/core/netif.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/core/netif.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/netif.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/core/netif.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/core/netif.o + .debug_macro 0x0000000000000000 0x5e ecm_src/lwip-1.4.1/src/core/netif.o + .debug_macro 0x0000000000000000 0x592 ecm_src/lwip-1.4.1/src/core/netif.o + .debug_macro 0x0000000000000000 0x58 ecm_src/lwip-1.4.1/src/core/netif.o + .debug_macro 0x0000000000000000 0x17b ecm_src/lwip-1.4.1/src/core/netif.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/netif.o + .debug_macro 0x0000000000000000 0x76 ecm_src/lwip-1.4.1/src/core/netif.o + .debug_macro 0x0000000000000000 0x55 ecm_src/lwip-1.4.1/src/core/netif.o + .debug_macro 0x0000000000000000 0x56 ecm_src/lwip-1.4.1/src/core/netif.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/core/netif.o + .debug_macro 0x0000000000000000 0x13b ecm_src/lwip-1.4.1/src/core/netif.o + .debug_macro 0x0000000000000000 0x64 ecm_src/lwip-1.4.1/src/core/netif.o + .debug_macro 0x0000000000000000 0xac ecm_src/lwip-1.4.1/src/core/netif.o + .debug_macro 0x0000000000000000 0x1be ecm_src/lwip-1.4.1/src/core/netif.o + .debug_macro 0x0000000000000000 0x321 ecm_src/lwip-1.4.1/src/core/netif.o + .debug_macro 0x0000000000000000 0x86 ecm_src/lwip-1.4.1/src/core/netif.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/netif.o + .debug_macro 0x0000000000000000 0x3a ecm_src/lwip-1.4.1/src/core/netif.o + .debug_macro 0x0000000000000000 0x127 ecm_src/lwip-1.4.1/src/core/netif.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/pbuf.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/pbuf.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/pbuf.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/pbuf.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/pbuf.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/pbuf.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/pbuf.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/pbuf.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/pbuf.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/pbuf.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/pbuf.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/pbuf.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/pbuf.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/pbuf.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/pbuf.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/pbuf.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/pbuf.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/pbuf.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/pbuf.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/pbuf.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/pbuf.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/pbuf.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/pbuf.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/pbuf.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/pbuf.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/pbuf.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/pbuf.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/pbuf.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/pbuf.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/pbuf.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/pbuf.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/pbuf.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/pbuf.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/pbuf.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/pbuf.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/pbuf.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/pbuf.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/pbuf.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/pbuf.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/pbuf.o + .text 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/pbuf.o + .data 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/pbuf.o + .bss 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/pbuf.o + .text.pbuf_free_ooseq + 0x0000000000000000 0x48 ecm_src/lwip-1.4.1/src/core/pbuf.o + .text.pbuf_dechain + 0x0000000000000000 0x62 ecm_src/lwip-1.4.1/src/core/pbuf.o + .text.pbuf_take + 0x0000000000000000 0xce ecm_src/lwip-1.4.1/src/core/pbuf.o + .text.pbuf_coalesce + 0x0000000000000000 0x5e ecm_src/lwip-1.4.1/src/core/pbuf.o + .text.pbuf_get_at + 0x0000000000000000 0x76 ecm_src/lwip-1.4.1/src/core/pbuf.o + .text.pbuf_memcmp + 0x0000000000000000 0xf0 ecm_src/lwip-1.4.1/src/core/pbuf.o + .text.pbuf_memfind + 0x0000000000000000 0xa4 ecm_src/lwip-1.4.1/src/core/pbuf.o + .text.pbuf_strstr + 0x0000000000000000 0x60 ecm_src/lwip-1.4.1/src/core/pbuf.o + .debug_macro 0x0000000000000000 0xa48 ecm_src/lwip-1.4.1/src/core/pbuf.o + .debug_macro 0x0000000000000000 0x70 ecm_src/lwip-1.4.1/src/core/pbuf.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/core/pbuf.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/pbuf.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/core/pbuf.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/core/pbuf.o + .debug_macro 0x0000000000000000 0x5e ecm_src/lwip-1.4.1/src/core/pbuf.o + .debug_macro 0x0000000000000000 0x592 ecm_src/lwip-1.4.1/src/core/pbuf.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/core/pbuf.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/pbuf.o + .debug_macro 0x0000000000000000 0x3a ecm_src/lwip-1.4.1/src/core/pbuf.o + .debug_macro 0x0000000000000000 0x127 ecm_src/lwip-1.4.1/src/core/pbuf.o + .debug_macro 0x0000000000000000 0x58 ecm_src/lwip-1.4.1/src/core/pbuf.o + .debug_macro 0x0000000000000000 0x76 ecm_src/lwip-1.4.1/src/core/pbuf.o + .debug_macro 0x0000000000000000 0x4f ecm_src/lwip-1.4.1/src/core/pbuf.o + .debug_macro 0x0000000000000000 0xc5 ecm_src/lwip-1.4.1/src/core/pbuf.o + .debug_macro 0x0000000000000000 0x17b ecm_src/lwip-1.4.1/src/core/pbuf.o + .debug_macro 0x0000000000000000 0x62 ecm_src/lwip-1.4.1/src/core/pbuf.o + .debug_macro 0x0000000000000000 0x64 ecm_src/lwip-1.4.1/src/core/pbuf.o + .debug_macro 0x0000000000000000 0xac ecm_src/lwip-1.4.1/src/core/pbuf.o + .debug_macro 0x0000000000000000 0x1be ecm_src/lwip-1.4.1/src/core/pbuf.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/core/pbuf.o + .debug_macro 0x0000000000000000 0x40 ecm_src/lwip-1.4.1/src/core/pbuf.o + .debug_macro 0x0000000000000000 0x18 ecm_src/lwip-1.4.1/src/core/pbuf.o + .debug_macro 0x0000000000000000 0x94 ecm_src/lwip-1.4.1/src/core/pbuf.o + .debug_macro 0x0000000000000000 0x3c ecm_src/lwip-1.4.1/src/core/pbuf.o + .debug_macro 0x0000000000000000 0x34 ecm_src/lwip-1.4.1/src/core/pbuf.o + .debug_macro 0x0000000000000000 0x174 ecm_src/lwip-1.4.1/src/core/pbuf.o + .debug_macro 0x0000000000000000 0x57 ecm_src/lwip-1.4.1/src/core/pbuf.o + .debug_macro 0x0000000000000000 0x52 ecm_src/lwip-1.4.1/src/core/pbuf.o + .debug_macro 0x0000000000000000 0x1f ecm_src/lwip-1.4.1/src/core/pbuf.o + .debug_macro 0x0000000000000000 0x43 ecm_src/lwip-1.4.1/src/core/pbuf.o + .debug_macro 0x0000000000000000 0x20 ecm_src/lwip-1.4.1/src/core/pbuf.o + .debug_macro 0x0000000000000000 0x1a3 ecm_src/lwip-1.4.1/src/core/pbuf.o + .debug_macro 0x0000000000000000 0x330 ecm_src/lwip-1.4.1/src/core/pbuf.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/pbuf.o + .debug_macro 0x0000000000000000 0x35 ecm_src/lwip-1.4.1/src/core/pbuf.o + .debug_macro 0x0000000000000000 0x20 ecm_src/lwip-1.4.1/src/core/pbuf.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/raw.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/raw.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/raw.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/raw.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/raw.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/raw.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/raw.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/raw.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/raw.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/raw.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/raw.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/raw.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/raw.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/raw.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/raw.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/raw.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/raw.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/raw.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/raw.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/raw.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/raw.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/raw.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/raw.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/raw.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/raw.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/raw.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/raw.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/raw.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/raw.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/raw.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/raw.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/raw.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/raw.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/raw.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/raw.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/raw.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/raw.o + .text 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/raw.o + .data 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/raw.o + .bss 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/raw.o + .text.raw_bind + 0x0000000000000000 0x26 ecm_src/lwip-1.4.1/src/core/raw.o + .text.raw_connect + 0x0000000000000000 0x26 ecm_src/lwip-1.4.1/src/core/raw.o + .text.raw_recv + 0x0000000000000000 0x20 ecm_src/lwip-1.4.1/src/core/raw.o + .text.raw_sendto + 0x0000000000000000 0xf6 ecm_src/lwip-1.4.1/src/core/raw.o + .text.raw_send + 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/core/raw.o + .text.raw_remove + 0x0000000000000000 0x64 ecm_src/lwip-1.4.1/src/core/raw.o + .text.raw_new 0x0000000000000000 0x54 ecm_src/lwip-1.4.1/src/core/raw.o + .debug_macro 0x0000000000000000 0xa48 ecm_src/lwip-1.4.1/src/core/raw.o + .debug_macro 0x0000000000000000 0x70 ecm_src/lwip-1.4.1/src/core/raw.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/core/raw.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/raw.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/core/raw.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/core/raw.o + .debug_macro 0x0000000000000000 0x5e ecm_src/lwip-1.4.1/src/core/raw.o + .debug_macro 0x0000000000000000 0x592 ecm_src/lwip-1.4.1/src/core/raw.o + .debug_macro 0x0000000000000000 0x58 ecm_src/lwip-1.4.1/src/core/raw.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/raw.o + .debug_macro 0x0000000000000000 0x3a ecm_src/lwip-1.4.1/src/core/raw.o + .debug_macro 0x0000000000000000 0x17b ecm_src/lwip-1.4.1/src/core/raw.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/raw.o + .debug_macro 0x0000000000000000 0x76 ecm_src/lwip-1.4.1/src/core/raw.o + .debug_macro 0x0000000000000000 0x55 ecm_src/lwip-1.4.1/src/core/raw.o + .debug_macro 0x0000000000000000 0x56 ecm_src/lwip-1.4.1/src/core/raw.o + .debug_macro 0x0000000000000000 0x13b ecm_src/lwip-1.4.1/src/core/raw.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/core/raw.o + .debug_macro 0x0000000000000000 0x127 ecm_src/lwip-1.4.1/src/core/raw.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/core/raw.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/core/raw.o + .debug_macro 0x0000000000000000 0x40 ecm_src/lwip-1.4.1/src/core/raw.o + .debug_macro 0x0000000000000000 0x18 ecm_src/lwip-1.4.1/src/core/raw.o + .debug_macro 0x0000000000000000 0x94 ecm_src/lwip-1.4.1/src/core/raw.o + .debug_macro 0x0000000000000000 0x3c ecm_src/lwip-1.4.1/src/core/raw.o + .debug_macro 0x0000000000000000 0x34 ecm_src/lwip-1.4.1/src/core/raw.o + .debug_macro 0x0000000000000000 0x174 ecm_src/lwip-1.4.1/src/core/raw.o + .debug_macro 0x0000000000000000 0x57 ecm_src/lwip-1.4.1/src/core/raw.o + .debug_macro 0x0000000000000000 0x52 ecm_src/lwip-1.4.1/src/core/raw.o + .debug_macro 0x0000000000000000 0x1f ecm_src/lwip-1.4.1/src/core/raw.o + .debug_macro 0x0000000000000000 0x43 ecm_src/lwip-1.4.1/src/core/raw.o + .debug_macro 0x0000000000000000 0x20 ecm_src/lwip-1.4.1/src/core/raw.o + .debug_macro 0x0000000000000000 0x1a3 ecm_src/lwip-1.4.1/src/core/raw.o + .debug_macro 0x0000000000000000 0x330 ecm_src/lwip-1.4.1/src/core/raw.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/raw.o + .debug_macro 0x0000000000000000 0x35 ecm_src/lwip-1.4.1/src/core/raw.o + .debug_macro 0x0000000000000000 0x20 ecm_src/lwip-1.4.1/src/core/raw.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/stats.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/stats.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/stats.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/stats.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/stats.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/stats.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/stats.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/stats.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/stats.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/stats.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/stats.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/stats.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/stats.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/stats.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/stats.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/stats.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/stats.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/stats.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/stats.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/stats.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/stats.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/stats.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/stats.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/stats.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/stats.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/stats.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/stats.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/stats.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/stats.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/stats.o + .text 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/stats.o + .data 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/stats.o + .bss 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/stats.o + .debug_macro 0x0000000000000000 0xa48 ecm_src/lwip-1.4.1/src/core/stats.o + .debug_macro 0x0000000000000000 0x70 ecm_src/lwip-1.4.1/src/core/stats.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/core/stats.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/stats.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/core/stats.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/core/stats.o + .debug_macro 0x0000000000000000 0x5e ecm_src/lwip-1.4.1/src/core/stats.o + .debug_macro 0x0000000000000000 0x592 ecm_src/lwip-1.4.1/src/core/stats.o + .debug_macro 0x0000000000000000 0x58 ecm_src/lwip-1.4.1/src/core/stats.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/core/stats.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/stats.o + .debug_macro 0x0000000000000000 0x3a ecm_src/lwip-1.4.1/src/core/stats.o + .debug_macro 0x0000000000000000 0x127 ecm_src/lwip-1.4.1/src/core/stats.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/core/stats.o + .debug_macro 0x0000000000000000 0x40 ecm_src/lwip-1.4.1/src/core/stats.o + .debug_macro 0x0000000000000000 0x18 ecm_src/lwip-1.4.1/src/core/stats.o + .debug_macro 0x0000000000000000 0x94 ecm_src/lwip-1.4.1/src/core/stats.o + .debug_macro 0x0000000000000000 0x3c ecm_src/lwip-1.4.1/src/core/stats.o + .debug_macro 0x0000000000000000 0x34 ecm_src/lwip-1.4.1/src/core/stats.o + .debug_macro 0x0000000000000000 0x174 ecm_src/lwip-1.4.1/src/core/stats.o + .debug_macro 0x0000000000000000 0x57 ecm_src/lwip-1.4.1/src/core/stats.o + .debug_macro 0x0000000000000000 0x52 ecm_src/lwip-1.4.1/src/core/stats.o + .debug_macro 0x0000000000000000 0x1f ecm_src/lwip-1.4.1/src/core/stats.o + .debug_macro 0x0000000000000000 0x43 ecm_src/lwip-1.4.1/src/core/stats.o + .debug_macro 0x0000000000000000 0x20 ecm_src/lwip-1.4.1/src/core/stats.o + .debug_macro 0x0000000000000000 0x1a3 ecm_src/lwip-1.4.1/src/core/stats.o + .debug_macro 0x0000000000000000 0x330 ecm_src/lwip-1.4.1/src/core/stats.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/stats.o + .debug_macro 0x0000000000000000 0x35 ecm_src/lwip-1.4.1/src/core/stats.o + .debug_macro 0x0000000000000000 0x20 ecm_src/lwip-1.4.1/src/core/stats.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/sys.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/sys.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/sys.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/sys.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/sys.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/sys.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/sys.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/sys.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/sys.o + .text 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/sys.o + .data 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/sys.o + .bss 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/sys.o + .debug_info 0x0000000000000000 0x4c ecm_src/lwip-1.4.1/src/core/sys.o + .debug_abbrev 0x0000000000000000 0x1e ecm_src/lwip-1.4.1/src/core/sys.o + .debug_aranges + 0x0000000000000000 0x18 ecm_src/lwip-1.4.1/src/core/sys.o + .debug_macro 0x0000000000000000 0x6b ecm_src/lwip-1.4.1/src/core/sys.o + .debug_macro 0x0000000000000000 0xa48 ecm_src/lwip-1.4.1/src/core/sys.o + .debug_macro 0x0000000000000000 0x70 ecm_src/lwip-1.4.1/src/core/sys.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/core/sys.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/sys.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/core/sys.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/core/sys.o + .debug_macro 0x0000000000000000 0x5e ecm_src/lwip-1.4.1/src/core/sys.o + .debug_macro 0x0000000000000000 0x592 ecm_src/lwip-1.4.1/src/core/sys.o + .debug_macro 0x0000000000000000 0xc5 ecm_src/lwip-1.4.1/src/core/sys.o + .debug_line 0x0000000000000000 0x147 ecm_src/lwip-1.4.1/src/core/sys.o + .debug_str 0x0000000000000000 0x4a3a ecm_src/lwip-1.4.1/src/core/sys.o + .comment 0x0000000000000000 0x7c ecm_src/lwip-1.4.1/src/core/sys.o + .ARM.attributes + 0x0000000000000000 0x31 ecm_src/lwip-1.4.1/src/core/sys.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp.o + .text 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/tcp.o + .data 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/tcp.o + .bss 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/tcp.o + .rodata 0x0000000000000000 0x76 ecm_src/lwip-1.4.1/src/core/tcp.o + .rodata.tcp_state_str + 0x0000000000000000 0x2c ecm_src/lwip-1.4.1/src/core/tcp.o + .data.tcp_port + 0x0000000000000000 0x2 ecm_src/lwip-1.4.1/src/core/tcp.o + .rodata.tcp_pcb_lists + 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/tcp.o + .text.tcp_shutdown + 0x0000000000000000 0x92 ecm_src/lwip-1.4.1/src/core/tcp.o + .text.tcp_bind + 0x0000000000000000 0xec ecm_src/lwip-1.4.1/src/core/tcp.o + .text.tcp_accept_null + 0x0000000000000000 0x1a ecm_src/lwip-1.4.1/src/core/tcp.o + .text.tcp_listen_with_backlog + 0x0000000000000000 0x11c ecm_src/lwip-1.4.1/src/core/tcp.o + .text.tcp_new_port + 0x0000000000000000 0xa0 ecm_src/lwip-1.4.1/src/core/tcp.o + .text.tcp_connect + 0x0000000000000000 0x1dc ecm_src/lwip-1.4.1/src/core/tcp.o + .text.tcp_setprio + 0x0000000000000000 0x1e ecm_src/lwip-1.4.1/src/core/tcp.o + .text.tcp_new 0x0000000000000000 0x12 ecm_src/lwip-1.4.1/src/core/tcp.o + .text.tcp_arg 0x0000000000000000 0x18 ecm_src/lwip-1.4.1/src/core/tcp.o + .text.tcp_recv + 0x0000000000000000 0x1a ecm_src/lwip-1.4.1/src/core/tcp.o + .text.tcp_sent + 0x0000000000000000 0x18 ecm_src/lwip-1.4.1/src/core/tcp.o + .text.tcp_err 0x0000000000000000 0x1a ecm_src/lwip-1.4.1/src/core/tcp.o + .text.tcp_accept + 0x0000000000000000 0x18 ecm_src/lwip-1.4.1/src/core/tcp.o + .text.tcp_poll + 0x0000000000000000 0x28 ecm_src/lwip-1.4.1/src/core/tcp.o + .text.tcp_debug_state_str + 0x0000000000000000 0x24 ecm_src/lwip-1.4.1/src/core/tcp.o + .debug_macro 0x0000000000000000 0xa48 ecm_src/lwip-1.4.1/src/core/tcp.o + .debug_macro 0x0000000000000000 0x70 ecm_src/lwip-1.4.1/src/core/tcp.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/core/tcp.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/tcp.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/core/tcp.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/core/tcp.o + .debug_macro 0x0000000000000000 0x5e ecm_src/lwip-1.4.1/src/core/tcp.o + .debug_macro 0x0000000000000000 0x592 ecm_src/lwip-1.4.1/src/core/tcp.o + .debug_macro 0x0000000000000000 0x58 ecm_src/lwip-1.4.1/src/core/tcp.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/core/tcp.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/tcp.o + .debug_macro 0x0000000000000000 0x3a ecm_src/lwip-1.4.1/src/core/tcp.o + .debug_macro 0x0000000000000000 0x17b ecm_src/lwip-1.4.1/src/core/tcp.o + .debug_macro 0x0000000000000000 0x76 ecm_src/lwip-1.4.1/src/core/tcp.o + .debug_macro 0x0000000000000000 0x4f ecm_src/lwip-1.4.1/src/core/tcp.o + .debug_macro 0x0000000000000000 0x62 ecm_src/lwip-1.4.1/src/core/tcp.o + .debug_macro 0x0000000000000000 0x135 ecm_src/lwip-1.4.1/src/core/tcp.o + .debug_macro 0x0000000000000000 0x64 ecm_src/lwip-1.4.1/src/core/tcp.o + .debug_macro 0x0000000000000000 0xac ecm_src/lwip-1.4.1/src/core/tcp.o + .debug_macro 0x0000000000000000 0x12d ecm_src/lwip-1.4.1/src/core/tcp.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/core/tcp.o + .debug_macro 0x0000000000000000 0x40 ecm_src/lwip-1.4.1/src/core/tcp.o + .debug_macro 0x0000000000000000 0x18 ecm_src/lwip-1.4.1/src/core/tcp.o + .debug_macro 0x0000000000000000 0x94 ecm_src/lwip-1.4.1/src/core/tcp.o + .debug_macro 0x0000000000000000 0x3c ecm_src/lwip-1.4.1/src/core/tcp.o + .debug_macro 0x0000000000000000 0x34 ecm_src/lwip-1.4.1/src/core/tcp.o + .debug_macro 0x0000000000000000 0x174 ecm_src/lwip-1.4.1/src/core/tcp.o + .debug_macro 0x0000000000000000 0x57 ecm_src/lwip-1.4.1/src/core/tcp.o + .debug_macro 0x0000000000000000 0x52 ecm_src/lwip-1.4.1/src/core/tcp.o + .debug_macro 0x0000000000000000 0x1f ecm_src/lwip-1.4.1/src/core/tcp.o + .debug_macro 0x0000000000000000 0x43 ecm_src/lwip-1.4.1/src/core/tcp.o + .debug_macro 0x0000000000000000 0x20 ecm_src/lwip-1.4.1/src/core/tcp.o + .debug_macro 0x0000000000000000 0x1a3 ecm_src/lwip-1.4.1/src/core/tcp.o + .debug_macro 0x0000000000000000 0x330 ecm_src/lwip-1.4.1/src/core/tcp.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/tcp.o + .debug_macro 0x0000000000000000 0x35 ecm_src/lwip-1.4.1/src/core/tcp.o + .debug_macro 0x0000000000000000 0x20 ecm_src/lwip-1.4.1/src/core/tcp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_in.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_in.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_in.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_in.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_in.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_in.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_in.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_in.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_in.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_in.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_in.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_in.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_in.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_in.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_in.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_in.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_in.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_in.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_in.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_in.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_in.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_in.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_in.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_in.o + .text 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/tcp_in.o + .data 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/tcp_in.o + .bss 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/tcp_in.o + .debug_macro 0x0000000000000000 0xa48 ecm_src/lwip-1.4.1/src/core/tcp_in.o + .debug_macro 0x0000000000000000 0x70 ecm_src/lwip-1.4.1/src/core/tcp_in.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/core/tcp_in.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/tcp_in.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/core/tcp_in.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/core/tcp_in.o + .debug_macro 0x0000000000000000 0x5e ecm_src/lwip-1.4.1/src/core/tcp_in.o + .debug_macro 0x0000000000000000 0x592 ecm_src/lwip-1.4.1/src/core/tcp_in.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/core/tcp_in.o + .debug_macro 0x0000000000000000 0x76 ecm_src/lwip-1.4.1/src/core/tcp_in.o + .debug_macro 0x0000000000000000 0x4f ecm_src/lwip-1.4.1/src/core/tcp_in.o + .debug_macro 0x0000000000000000 0x58 ecm_src/lwip-1.4.1/src/core/tcp_in.o + .debug_macro 0x0000000000000000 0x17b ecm_src/lwip-1.4.1/src/core/tcp_in.o + .debug_macro 0x0000000000000000 0x62 ecm_src/lwip-1.4.1/src/core/tcp_in.o + .debug_macro 0x0000000000000000 0x135 ecm_src/lwip-1.4.1/src/core/tcp_in.o + .debug_macro 0x0000000000000000 0x64 ecm_src/lwip-1.4.1/src/core/tcp_in.o + .debug_macro 0x0000000000000000 0xac ecm_src/lwip-1.4.1/src/core/tcp_in.o + .debug_macro 0x0000000000000000 0x1be ecm_src/lwip-1.4.1/src/core/tcp_in.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/tcp_in.o + .debug_macro 0x0000000000000000 0x3a ecm_src/lwip-1.4.1/src/core/tcp_in.o + .debug_macro 0x0000000000000000 0x12d ecm_src/lwip-1.4.1/src/core/tcp_in.o + .debug_macro 0x0000000000000000 0x321 ecm_src/lwip-1.4.1/src/core/tcp_in.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/core/tcp_in.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_out.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_out.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_out.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_out.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_out.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_out.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_out.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_out.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_out.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_out.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_out.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_out.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_out.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_out.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_out.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_out.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_out.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_out.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_out.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_out.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_out.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_out.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_out.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_out.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_out.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_out.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_out.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_out.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_out.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_out.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_out.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_out.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_out.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_out.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_out.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_out.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_out.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_out.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_out.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_out.o + .text 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/tcp_out.o + .data 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/tcp_out.o + .bss 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/tcp_out.o + .text.tcp_pbuf_prealloc + 0x0000000000000000 0xe4 ecm_src/lwip-1.4.1/src/core/tcp_out.o + .text.tcp_write_checks + 0x0000000000000000 0xb8 ecm_src/lwip-1.4.1/src/core/tcp_out.o + .text.tcp_write + 0x0000000000000000 0x5d4 ecm_src/lwip-1.4.1/src/core/tcp_out.o + .debug_macro 0x0000000000000000 0xa48 ecm_src/lwip-1.4.1/src/core/tcp_out.o + .debug_macro 0x0000000000000000 0x70 ecm_src/lwip-1.4.1/src/core/tcp_out.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/core/tcp_out.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/tcp_out.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/core/tcp_out.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/core/tcp_out.o + .debug_macro 0x0000000000000000 0x5e ecm_src/lwip-1.4.1/src/core/tcp_out.o + .debug_macro 0x0000000000000000 0x592 ecm_src/lwip-1.4.1/src/core/tcp_out.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/core/tcp_out.o + .debug_macro 0x0000000000000000 0x76 ecm_src/lwip-1.4.1/src/core/tcp_out.o + .debug_macro 0x0000000000000000 0x4f ecm_src/lwip-1.4.1/src/core/tcp_out.o + .debug_macro 0x0000000000000000 0x58 ecm_src/lwip-1.4.1/src/core/tcp_out.o + .debug_macro 0x0000000000000000 0x17b ecm_src/lwip-1.4.1/src/core/tcp_out.o + .debug_macro 0x0000000000000000 0x62 ecm_src/lwip-1.4.1/src/core/tcp_out.o + .debug_macro 0x0000000000000000 0x135 ecm_src/lwip-1.4.1/src/core/tcp_out.o + .debug_macro 0x0000000000000000 0x64 ecm_src/lwip-1.4.1/src/core/tcp_out.o + .debug_macro 0x0000000000000000 0xac ecm_src/lwip-1.4.1/src/core/tcp_out.o + .debug_macro 0x0000000000000000 0x1be ecm_src/lwip-1.4.1/src/core/tcp_out.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/tcp_out.o + .debug_macro 0x0000000000000000 0x3a ecm_src/lwip-1.4.1/src/core/tcp_out.o + .debug_macro 0x0000000000000000 0x1c ecm_src/lwip-1.4.1/src/core/tcp_out.o + .debug_macro 0x0000000000000000 0x12d ecm_src/lwip-1.4.1/src/core/tcp_out.o + .debug_macro 0x0000000000000000 0x321 ecm_src/lwip-1.4.1/src/core/tcp_out.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/core/tcp_out.o + .debug_macro 0x0000000000000000 0x40 ecm_src/lwip-1.4.1/src/core/tcp_out.o + .debug_macro 0x0000000000000000 0x18 ecm_src/lwip-1.4.1/src/core/tcp_out.o + .debug_macro 0x0000000000000000 0x94 ecm_src/lwip-1.4.1/src/core/tcp_out.o + .debug_macro 0x0000000000000000 0x3c ecm_src/lwip-1.4.1/src/core/tcp_out.o + .debug_macro 0x0000000000000000 0x34 ecm_src/lwip-1.4.1/src/core/tcp_out.o + .debug_macro 0x0000000000000000 0x174 ecm_src/lwip-1.4.1/src/core/tcp_out.o + .debug_macro 0x0000000000000000 0x57 ecm_src/lwip-1.4.1/src/core/tcp_out.o + .debug_macro 0x0000000000000000 0x52 ecm_src/lwip-1.4.1/src/core/tcp_out.o + .debug_macro 0x0000000000000000 0x1f ecm_src/lwip-1.4.1/src/core/tcp_out.o + .debug_macro 0x0000000000000000 0x43 ecm_src/lwip-1.4.1/src/core/tcp_out.o + .debug_macro 0x0000000000000000 0x20 ecm_src/lwip-1.4.1/src/core/tcp_out.o + .debug_macro 0x0000000000000000 0x1a3 ecm_src/lwip-1.4.1/src/core/tcp_out.o + .debug_macro 0x0000000000000000 0x330 ecm_src/lwip-1.4.1/src/core/tcp_out.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/tcp_out.o + .debug_macro 0x0000000000000000 0x35 ecm_src/lwip-1.4.1/src/core/tcp_out.o + .debug_macro 0x0000000000000000 0x20 ecm_src/lwip-1.4.1/src/core/tcp_out.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/timers.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/timers.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/timers.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/timers.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/timers.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/timers.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/timers.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/timers.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/timers.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/timers.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/timers.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/timers.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/timers.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/timers.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/timers.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/timers.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/timers.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/timers.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/timers.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/timers.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/timers.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/timers.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/timers.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/timers.o + .text 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/timers.o + .data 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/timers.o + .bss 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/timers.o + .text.sys_untimeout + 0x0000000000000000 0x90 ecm_src/lwip-1.4.1/src/core/timers.o + .text.sys_check_timeouts + 0x0000000000000000 0xb0 ecm_src/lwip-1.4.1/src/core/timers.o + .text.sys_restart_timeouts + 0x0000000000000000 0x18 ecm_src/lwip-1.4.1/src/core/timers.o + .debug_macro 0x0000000000000000 0xa48 ecm_src/lwip-1.4.1/src/core/timers.o + .debug_macro 0x0000000000000000 0x70 ecm_src/lwip-1.4.1/src/core/timers.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/core/timers.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/timers.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/core/timers.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/core/timers.o + .debug_macro 0x0000000000000000 0x5e ecm_src/lwip-1.4.1/src/core/timers.o + .debug_macro 0x0000000000000000 0x592 ecm_src/lwip-1.4.1/src/core/timers.o + .debug_macro 0x0000000000000000 0x76 ecm_src/lwip-1.4.1/src/core/timers.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/core/timers.o + .debug_macro 0x0000000000000000 0x55 ecm_src/lwip-1.4.1/src/core/timers.o + .debug_macro 0x0000000000000000 0x58 ecm_src/lwip-1.4.1/src/core/timers.o + .debug_macro 0x0000000000000000 0x17b ecm_src/lwip-1.4.1/src/core/timers.o + .debug_macro 0x0000000000000000 0x62 ecm_src/lwip-1.4.1/src/core/timers.o + .debug_macro 0x0000000000000000 0x135 ecm_src/lwip-1.4.1/src/core/timers.o + .debug_macro 0x0000000000000000 0x64 ecm_src/lwip-1.4.1/src/core/timers.o + .debug_macro 0x0000000000000000 0xac ecm_src/lwip-1.4.1/src/core/timers.o + .debug_macro 0x0000000000000000 0x1be ecm_src/lwip-1.4.1/src/core/timers.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/timers.o + .debug_macro 0x0000000000000000 0x3a ecm_src/lwip-1.4.1/src/core/timers.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/timers.o + .debug_macro 0x0000000000000000 0x86 ecm_src/lwip-1.4.1/src/core/timers.o + .debug_macro 0x0000000000000000 0xc5 ecm_src/lwip-1.4.1/src/core/timers.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/udp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/udp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/udp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/udp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/udp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/udp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/udp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/udp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/udp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/udp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/udp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/udp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/udp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/udp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/udp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/udp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/udp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/udp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/udp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/udp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/udp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/udp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/udp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/udp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/udp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/udp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/udp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/udp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/udp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/udp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/udp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/udp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/udp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/udp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/udp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/udp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/udp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/udp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/udp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/udp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/udp.o + .text 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/udp.o + .data 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/udp.o + .bss 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/udp.o + .text.udp_send + 0x0000000000000000 0x24 ecm_src/lwip-1.4.1/src/core/udp.o + .text.udp_connect + 0x0000000000000000 0xa4 ecm_src/lwip-1.4.1/src/core/udp.o + .text.udp_disconnect + 0x0000000000000000 0x2a ecm_src/lwip-1.4.1/src/core/udp.o + .debug_macro 0x0000000000000000 0xa48 ecm_src/lwip-1.4.1/src/core/udp.o + .debug_macro 0x0000000000000000 0x70 ecm_src/lwip-1.4.1/src/core/udp.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/core/udp.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/udp.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/core/udp.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/core/udp.o + .debug_macro 0x0000000000000000 0x5e ecm_src/lwip-1.4.1/src/core/udp.o + .debug_macro 0x0000000000000000 0x592 ecm_src/lwip-1.4.1/src/core/udp.o + .debug_macro 0x0000000000000000 0x76 ecm_src/lwip-1.4.1/src/core/udp.o + .debug_macro 0x0000000000000000 0x4f ecm_src/lwip-1.4.1/src/core/udp.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/udp.o + .debug_macro 0x0000000000000000 0x58 ecm_src/lwip-1.4.1/src/core/udp.o + .debug_macro 0x0000000000000000 0x175 ecm_src/lwip-1.4.1/src/core/udp.o + .debug_macro 0x0000000000000000 0x56 ecm_src/lwip-1.4.1/src/core/udp.o + .debug_macro 0x0000000000000000 0x13b ecm_src/lwip-1.4.1/src/core/udp.o + .debug_macro 0x0000000000000000 0x37 ecm_src/lwip-1.4.1/src/core/udp.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/udp.o + .debug_macro 0x0000000000000000 0x3a ecm_src/lwip-1.4.1/src/core/udp.o + .debug_macro 0x0000000000000000 0x1c ecm_src/lwip-1.4.1/src/core/udp.o + .debug_macro 0x0000000000000000 0x64 ecm_src/lwip-1.4.1/src/core/udp.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/core/udp.o + .debug_macro 0x0000000000000000 0x127 ecm_src/lwip-1.4.1/src/core/udp.o + .debug_macro 0x0000000000000000 0x321 ecm_src/lwip-1.4.1/src/core/udp.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/core/udp.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/core/udp.o + .debug_macro 0x0000000000000000 0x40 ecm_src/lwip-1.4.1/src/core/udp.o + .debug_macro 0x0000000000000000 0x18 ecm_src/lwip-1.4.1/src/core/udp.o + .debug_macro 0x0000000000000000 0x94 ecm_src/lwip-1.4.1/src/core/udp.o + .debug_macro 0x0000000000000000 0x3c ecm_src/lwip-1.4.1/src/core/udp.o + .debug_macro 0x0000000000000000 0x34 ecm_src/lwip-1.4.1/src/core/udp.o + .debug_macro 0x0000000000000000 0x174 ecm_src/lwip-1.4.1/src/core/udp.o + .debug_macro 0x0000000000000000 0x57 ecm_src/lwip-1.4.1/src/core/udp.o + .debug_macro 0x0000000000000000 0x52 ecm_src/lwip-1.4.1/src/core/udp.o + .debug_macro 0x0000000000000000 0x1f ecm_src/lwip-1.4.1/src/core/udp.o + .debug_macro 0x0000000000000000 0x43 ecm_src/lwip-1.4.1/src/core/udp.o + .debug_macro 0x0000000000000000 0x20 ecm_src/lwip-1.4.1/src/core/udp.o + .debug_macro 0x0000000000000000 0x1a3 ecm_src/lwip-1.4.1/src/core/udp.o + .debug_macro 0x0000000000000000 0x330 ecm_src/lwip-1.4.1/src/core/udp.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/udp.o + .debug_macro 0x0000000000000000 0x35 ecm_src/lwip-1.4.1/src/core/udp.o + .debug_macro 0x0000000000000000 0x20 ecm_src/lwip-1.4.1/src/core/udp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/autoip.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/autoip.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/autoip.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/autoip.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/autoip.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/autoip.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/autoip.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/autoip.o + .text 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/ipv4/autoip.o + .data 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/ipv4/autoip.o + .bss 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/ipv4/autoip.o + .debug_info 0x0000000000000000 0x4c ecm_src/lwip-1.4.1/src/core/ipv4/autoip.o + .debug_abbrev 0x0000000000000000 0x1e ecm_src/lwip-1.4.1/src/core/ipv4/autoip.o + .debug_aranges + 0x0000000000000000 0x18 ecm_src/lwip-1.4.1/src/core/ipv4/autoip.o + .debug_macro 0x0000000000000000 0x62 ecm_src/lwip-1.4.1/src/core/ipv4/autoip.o + .debug_macro 0x0000000000000000 0xa48 ecm_src/lwip-1.4.1/src/core/ipv4/autoip.o + .debug_macro 0x0000000000000000 0x70 ecm_src/lwip-1.4.1/src/core/ipv4/autoip.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/core/ipv4/autoip.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/ipv4/autoip.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/core/ipv4/autoip.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/core/ipv4/autoip.o + .debug_macro 0x0000000000000000 0x5e ecm_src/lwip-1.4.1/src/core/ipv4/autoip.o + .debug_macro 0x0000000000000000 0x592 ecm_src/lwip-1.4.1/src/core/ipv4/autoip.o + .debug_line 0x0000000000000000 0x146 ecm_src/lwip-1.4.1/src/core/ipv4/autoip.o + .debug_str 0x0000000000000000 0x45b7 ecm_src/lwip-1.4.1/src/core/ipv4/autoip.o + .comment 0x0000000000000000 0x7c ecm_src/lwip-1.4.1/src/core/ipv4/autoip.o + .ARM.attributes + 0x0000000000000000 0x31 ecm_src/lwip-1.4.1/src/core/ipv4/autoip.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .text 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .data 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .bss 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .debug_macro 0x0000000000000000 0xa48 ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .debug_macro 0x0000000000000000 0x70 ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .debug_macro 0x0000000000000000 0x5e ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .debug_macro 0x0000000000000000 0x592 ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .debug_macro 0x0000000000000000 0x76 ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .debug_macro 0x0000000000000000 0x4f ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .debug_macro 0x0000000000000000 0x58 ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .debug_macro 0x0000000000000000 0x175 ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .debug_macro 0x0000000000000000 0x62 ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .debug_macro 0x0000000000000000 0x1c ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .debug_macro 0x0000000000000000 0x13b ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .debug_macro 0x0000000000000000 0x3a ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .debug_macro 0x0000000000000000 0x127 ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .debug_macro 0x0000000000000000 0x321 ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .debug_macro 0x0000000000000000 0x40 ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .debug_macro 0x0000000000000000 0x18 ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .debug_macro 0x0000000000000000 0x94 ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .debug_macro 0x0000000000000000 0x3c ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .debug_macro 0x0000000000000000 0x34 ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .debug_macro 0x0000000000000000 0x174 ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .debug_macro 0x0000000000000000 0x57 ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .debug_macro 0x0000000000000000 0x52 ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .debug_macro 0x0000000000000000 0x1f ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .debug_macro 0x0000000000000000 0x43 ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .debug_macro 0x0000000000000000 0x20 ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .debug_macro 0x0000000000000000 0x1a3 ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .debug_macro 0x0000000000000000 0x330 ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .debug_macro 0x0000000000000000 0x35 ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .debug_macro 0x0000000000000000 0x20 ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/igmp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/igmp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/igmp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/igmp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/igmp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/igmp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/igmp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/igmp.o + .text 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/ipv4/igmp.o + .data 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/ipv4/igmp.o + .bss 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/ipv4/igmp.o + .debug_info 0x0000000000000000 0x4c ecm_src/lwip-1.4.1/src/core/ipv4/igmp.o + .debug_abbrev 0x0000000000000000 0x1e ecm_src/lwip-1.4.1/src/core/ipv4/igmp.o + .debug_aranges + 0x0000000000000000 0x18 ecm_src/lwip-1.4.1/src/core/ipv4/igmp.o + .debug_macro 0x0000000000000000 0x62 ecm_src/lwip-1.4.1/src/core/ipv4/igmp.o + .debug_macro 0x0000000000000000 0xa48 ecm_src/lwip-1.4.1/src/core/ipv4/igmp.o + .debug_macro 0x0000000000000000 0x70 ecm_src/lwip-1.4.1/src/core/ipv4/igmp.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/core/ipv4/igmp.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/ipv4/igmp.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/core/ipv4/igmp.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/core/ipv4/igmp.o + .debug_macro 0x0000000000000000 0x5e ecm_src/lwip-1.4.1/src/core/ipv4/igmp.o + .debug_macro 0x0000000000000000 0x592 ecm_src/lwip-1.4.1/src/core/ipv4/igmp.o + .debug_line 0x0000000000000000 0x144 ecm_src/lwip-1.4.1/src/core/ipv4/igmp.o + .debug_str 0x0000000000000000 0x45b5 ecm_src/lwip-1.4.1/src/core/ipv4/igmp.o + .comment 0x0000000000000000 0x7c ecm_src/lwip-1.4.1/src/core/ipv4/igmp.o + .ARM.attributes + 0x0000000000000000 0x31 ecm_src/lwip-1.4.1/src/core/ipv4/igmp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/inet.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/inet.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/inet.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/inet.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/inet.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/inet.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/inet.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/inet.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/inet.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/inet.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/inet.o + .text 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/ipv4/inet.o + .data 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/ipv4/inet.o + .bss 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/ipv4/inet.o + .debug_info 0x0000000000000000 0x9d ecm_src/lwip-1.4.1/src/core/ipv4/inet.o + .debug_abbrev 0x0000000000000000 0x61 ecm_src/lwip-1.4.1/src/core/ipv4/inet.o + .debug_aranges + 0x0000000000000000 0x18 ecm_src/lwip-1.4.1/src/core/ipv4/inet.o + .debug_macro 0x0000000000000000 0x83 ecm_src/lwip-1.4.1/src/core/ipv4/inet.o + .debug_macro 0x0000000000000000 0xa48 ecm_src/lwip-1.4.1/src/core/ipv4/inet.o + .debug_macro 0x0000000000000000 0x70 ecm_src/lwip-1.4.1/src/core/ipv4/inet.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/core/ipv4/inet.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/ipv4/inet.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/core/ipv4/inet.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/core/ipv4/inet.o + .debug_macro 0x0000000000000000 0x5e ecm_src/lwip-1.4.1/src/core/ipv4/inet.o + .debug_macro 0x0000000000000000 0x592 ecm_src/lwip-1.4.1/src/core/ipv4/inet.o + .debug_macro 0x0000000000000000 0x58 ecm_src/lwip-1.4.1/src/core/ipv4/inet.o + .debug_macro 0x0000000000000000 0x17b ecm_src/lwip-1.4.1/src/core/ipv4/inet.o + .debug_macro 0x0000000000000000 0xd6 ecm_src/lwip-1.4.1/src/core/ipv4/inet.o + .debug_line 0x0000000000000000 0x1a3 ecm_src/lwip-1.4.1/src/core/ipv4/inet.o + .debug_str 0x0000000000000000 0x5952 ecm_src/lwip-1.4.1/src/core/ipv4/inet.o + .comment 0x0000000000000000 0x7c ecm_src/lwip-1.4.1/src/core/ipv4/inet.o + .ARM.attributes + 0x0000000000000000 0x31 ecm_src/lwip-1.4.1/src/core/ipv4/inet.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .text 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .data 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .bss 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .text.inet_chksum_pseudo_partial + 0x0000000000000000 0x194 ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .debug_macro 0x0000000000000000 0xa48 ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .debug_macro 0x0000000000000000 0x70 ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .debug_macro 0x0000000000000000 0x5e ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .debug_macro 0x0000000000000000 0x592 ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .debug_macro 0x0000000000000000 0x76 ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .debug_macro 0x0000000000000000 0x4f ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .debug_macro 0x0000000000000000 0x58 ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .debug_macro 0x0000000000000000 0x175 ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .debug_macro 0x0000000000000000 0x174 ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .debug_macro 0x0000000000000000 0x40 ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .debug_macro 0x0000000000000000 0x18 ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .debug_macro 0x0000000000000000 0x94 ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .debug_macro 0x0000000000000000 0x3c ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .debug_macro 0x0000000000000000 0x34 ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .debug_macro 0x0000000000000000 0x57 ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .debug_macro 0x0000000000000000 0x52 ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .debug_macro 0x0000000000000000 0x1f ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .debug_macro 0x0000000000000000 0x43 ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .debug_macro 0x0000000000000000 0x20 ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .debug_macro 0x0000000000000000 0x1a3 ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .debug_macro 0x0000000000000000 0x330 ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .debug_macro 0x0000000000000000 0x35 ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .debug_macro 0x0000000000000000 0x20 ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .text 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .data 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .bss 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .debug_macro 0x0000000000000000 0xa48 ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .debug_macro 0x0000000000000000 0x70 ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .debug_macro 0x0000000000000000 0x5e ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .debug_macro 0x0000000000000000 0x592 ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .debug_macro 0x0000000000000000 0x58 ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .debug_macro 0x0000000000000000 0x76 ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .debug_macro 0x0000000000000000 0x4f ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .debug_macro 0x0000000000000000 0x17b ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .debug_macro 0x0000000000000000 0x62 ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .debug_macro 0x0000000000000000 0x135 ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .debug_macro 0x0000000000000000 0x1c ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .debug_macro 0x0000000000000000 0x64 ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .debug_macro 0x0000000000000000 0x3d ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .debug_macro 0x0000000000000000 0x1be ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .debug_macro 0x0000000000000000 0x321 ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .debug_macro 0x0000000000000000 0x3a ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .debug_macro 0x0000000000000000 0x127 ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .debug_macro 0x0000000000000000 0x40 ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .debug_macro 0x0000000000000000 0x18 ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .debug_macro 0x0000000000000000 0x94 ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .debug_macro 0x0000000000000000 0x3c ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .debug_macro 0x0000000000000000 0x34 ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .debug_macro 0x0000000000000000 0x174 ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .debug_macro 0x0000000000000000 0x57 ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .debug_macro 0x0000000000000000 0x52 ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .debug_macro 0x0000000000000000 0x1f ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .debug_macro 0x0000000000000000 0x43 ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .debug_macro 0x0000000000000000 0x20 ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .debug_macro 0x0000000000000000 0x1a3 ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .debug_macro 0x0000000000000000 0x330 ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .debug_macro 0x0000000000000000 0x35 ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .debug_macro 0x0000000000000000 0x20 ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o + .text 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o + .data 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o + .bss 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o + .text.ip4_addr_netmask_valid + 0x0000000000000000 0x58 ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o + .text.ipaddr_addr + 0x0000000000000000 0x2a ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o + .text.ipaddr_aton + 0x0000000000000000 0x290 ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o + .rodata.ipaddr_aton + 0x0000000000000000 0x14 ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o + .text.ipaddr_ntoa + 0x0000000000000000 0x24 ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o + .text.ipaddr_ntoa_r + 0x0000000000000000 0x100 ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o + .bss.str.4349 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o + .debug_macro 0x0000000000000000 0xa48 ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o + .debug_macro 0x0000000000000000 0x70 ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o + .debug_macro 0x0000000000000000 0x5e ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o + .debug_macro 0x0000000000000000 0x592 ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o + .debug_macro 0x0000000000000000 0x58 ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o + .debug_macro 0x0000000000000000 0x175 ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o + .debug_macro 0x0000000000000000 0x76 ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o + .debug_macro 0x0000000000000000 0x55 ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o + .debug_macro 0x0000000000000000 0x56 ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .text 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .data 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .bss 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .debug_macro 0x0000000000000000 0xa48 ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .debug_macro 0x0000000000000000 0x70 ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .debug_macro 0x0000000000000000 0x5e ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .debug_macro 0x0000000000000000 0x592 ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .debug_macro 0x0000000000000000 0x76 ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .debug_macro 0x0000000000000000 0x55 ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .debug_macro 0x0000000000000000 0x58 ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .debug_macro 0x0000000000000000 0x175 ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .debug_macro 0x0000000000000000 0x56 ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .debug_macro 0x0000000000000000 0x13b ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .debug_macro 0x0000000000000000 0x1c ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .debug_macro 0x0000000000000000 0x321 ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .debug_macro 0x0000000000000000 0x3a ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .debug_macro 0x0000000000000000 0x127 ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .debug_macro 0x0000000000000000 0x64 ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .debug_macro 0x0000000000000000 0x40 ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .debug_macro 0x0000000000000000 0x18 ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .debug_macro 0x0000000000000000 0x94 ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .debug_macro 0x0000000000000000 0x3c ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .debug_macro 0x0000000000000000 0x34 ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .debug_macro 0x0000000000000000 0x174 ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .debug_macro 0x0000000000000000 0x57 ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .debug_macro 0x0000000000000000 0x52 ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .debug_macro 0x0000000000000000 0x1f ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .debug_macro 0x0000000000000000 0x43 ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .debug_macro 0x0000000000000000 0x20 ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .debug_macro 0x0000000000000000 0x1a3 ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .debug_macro 0x0000000000000000 0x330 ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .debug_macro 0x0000000000000000 0x35 ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .debug_macro 0x0000000000000000 0x20 ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/netif/etharp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/netif/etharp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/netif/etharp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/netif/etharp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/netif/etharp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/netif/etharp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/netif/etharp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/netif/etharp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/netif/etharp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/netif/etharp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/netif/etharp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/netif/etharp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/netif/etharp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/netif/etharp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/netif/etharp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/netif/etharp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/netif/etharp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/netif/etharp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/netif/etharp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/netif/etharp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/netif/etharp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/netif/etharp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/netif/etharp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/netif/etharp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/netif/etharp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/netif/etharp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/netif/etharp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/netif/etharp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/netif/etharp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/netif/etharp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/netif/etharp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/netif/etharp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/netif/etharp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/netif/etharp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/netif/etharp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/netif/etharp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/netif/etharp.o + .text 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/netif/etharp.o + .data 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/netif/etharp.o + .bss 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/netif/etharp.o + .text.etharp_add_static_entry + 0x0000000000000000 0x38 ecm_src/lwip-1.4.1/src/netif/etharp.o + .text.etharp_remove_static_entry + 0x0000000000000000 0x6c ecm_src/lwip-1.4.1/src/netif/etharp.o + .text.etharp_cleanup_netif + 0x0000000000000000 0x80 ecm_src/lwip-1.4.1/src/netif/etharp.o + .text.etharp_find_addr + 0x0000000000000000 0x94 ecm_src/lwip-1.4.1/src/netif/etharp.o + .debug_macro 0x0000000000000000 0xa48 ecm_src/lwip-1.4.1/src/netif/etharp.o + .debug_macro 0x0000000000000000 0x70 ecm_src/lwip-1.4.1/src/netif/etharp.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/netif/etharp.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/netif/etharp.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/netif/etharp.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/netif/etharp.o + .debug_macro 0x0000000000000000 0x5e ecm_src/lwip-1.4.1/src/netif/etharp.o + .debug_macro 0x0000000000000000 0x592 ecm_src/lwip-1.4.1/src/netif/etharp.o + .debug_macro 0x0000000000000000 0x58 ecm_src/lwip-1.4.1/src/netif/etharp.o + .debug_macro 0x0000000000000000 0x175 ecm_src/lwip-1.4.1/src/netif/etharp.o + .debug_macro 0x0000000000000000 0x76 ecm_src/lwip-1.4.1/src/netif/etharp.o + .debug_macro 0x0000000000000000 0x4f ecm_src/lwip-1.4.1/src/netif/etharp.o + .debug_macro 0x0000000000000000 0x62 ecm_src/lwip-1.4.1/src/netif/etharp.o + .debug_macro 0x0000000000000000 0x135 ecm_src/lwip-1.4.1/src/netif/etharp.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/netif/etharp.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/netif/etharp.o + .debug_macro 0x0000000000000000 0x3a ecm_src/lwip-1.4.1/src/netif/etharp.o + .debug_macro 0x0000000000000000 0x127 ecm_src/lwip-1.4.1/src/netif/etharp.o + .debug_macro 0x0000000000000000 0x321 ecm_src/lwip-1.4.1/src/netif/etharp.o + .debug_macro 0x0000000000000000 0x86 ecm_src/lwip-1.4.1/src/netif/etharp.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/netif/etharp.o + .debug_macro 0x0000000000000000 0x40 ecm_src/lwip-1.4.1/src/netif/etharp.o + .debug_macro 0x0000000000000000 0x18 ecm_src/lwip-1.4.1/src/netif/etharp.o + .debug_macro 0x0000000000000000 0x94 ecm_src/lwip-1.4.1/src/netif/etharp.o + .debug_macro 0x0000000000000000 0x3c ecm_src/lwip-1.4.1/src/netif/etharp.o + .debug_macro 0x0000000000000000 0x34 ecm_src/lwip-1.4.1/src/netif/etharp.o + .debug_macro 0x0000000000000000 0x174 ecm_src/lwip-1.4.1/src/netif/etharp.o + .debug_macro 0x0000000000000000 0x57 ecm_src/lwip-1.4.1/src/netif/etharp.o + .debug_macro 0x0000000000000000 0x52 ecm_src/lwip-1.4.1/src/netif/etharp.o + .debug_macro 0x0000000000000000 0x1f ecm_src/lwip-1.4.1/src/netif/etharp.o + .debug_macro 0x0000000000000000 0x43 ecm_src/lwip-1.4.1/src/netif/etharp.o + .debug_macro 0x0000000000000000 0x20 ecm_src/lwip-1.4.1/src/netif/etharp.o + .debug_macro 0x0000000000000000 0x1a3 ecm_src/lwip-1.4.1/src/netif/etharp.o + .debug_macro 0x0000000000000000 0x330 ecm_src/lwip-1.4.1/src/netif/etharp.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/netif/etharp.o + .debug_macro 0x0000000000000000 0x35 ecm_src/lwip-1.4.1/src/netif/etharp.o + .debug_macro 0x0000000000000000 0x20 ecm_src/lwip-1.4.1/src/netif/etharp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/netif/ethernetif.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/netif/ethernetif.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/netif/ethernetif.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/netif/ethernetif.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/netif/ethernetif.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/netif/ethernetif.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/netif/ethernetif.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/netif/ethernetif.o + .text 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/netif/ethernetif.o + .data 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/netif/ethernetif.o + .bss 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/netif/ethernetif.o + .debug_info 0x0000000000000000 0x4c ecm_src/lwip-1.4.1/src/netif/ethernetif.o + .debug_abbrev 0x0000000000000000 0x1e ecm_src/lwip-1.4.1/src/netif/ethernetif.o + .debug_aranges + 0x0000000000000000 0x18 ecm_src/lwip-1.4.1/src/netif/ethernetif.o + .debug_macro 0x0000000000000000 0x62 ecm_src/lwip-1.4.1/src/netif/ethernetif.o + .debug_macro 0x0000000000000000 0xa48 ecm_src/lwip-1.4.1/src/netif/ethernetif.o + .debug_macro 0x0000000000000000 0x70 ecm_src/lwip-1.4.1/src/netif/ethernetif.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/netif/ethernetif.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/netif/ethernetif.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/netif/ethernetif.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/netif/ethernetif.o + .debug_macro 0x0000000000000000 0x5e ecm_src/lwip-1.4.1/src/netif/ethernetif.o + .debug_macro 0x0000000000000000 0x592 ecm_src/lwip-1.4.1/src/netif/ethernetif.o + .debug_line 0x0000000000000000 0x146 ecm_src/lwip-1.4.1/src/netif/ethernetif.o + .debug_str 0x0000000000000000 0x45b7 ecm_src/lwip-1.4.1/src/netif/ethernetif.o + .comment 0x0000000000000000 0x7c ecm_src/lwip-1.4.1/src/netif/ethernetif.o + .ARM.attributes + 0x0000000000000000 0x31 ecm_src/lwip-1.4.1/src/netif/ethernetif.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .text 0x0000000000000000 0x0 ecm_src/src/ecm_main.o + .data 0x0000000000000000 0x0 ecm_src/src/ecm_main.o + .bss 0x0000000000000000 0x0 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0xa48 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x2e ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x22 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x22 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x8e ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x51 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0xef ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x6a ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x1df ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x1c ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x22 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0xb5 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x391 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0xfe50 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x3c ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x12d ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x174 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x53 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x946 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x5f3 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x12f ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x1a7 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x1a7 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x22c ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x34 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x43 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x28 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0xb0 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x217 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x22c ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x5f ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0xa5 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x65 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x234 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x4c ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x16d ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x130 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x46 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x18 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x3c ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x34 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x16 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x35 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x32a ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x10 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x52 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x1f ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x43 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x20 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x1a3 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x10 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x1c ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x52 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x40 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x10 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x40 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0xd7 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x1c ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x3d ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x16 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x145 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x16 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x16 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x29 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x16 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x20 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x64 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x1a6 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x22 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x70 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x16 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x22 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x16 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x5e ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x592 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x76 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x4f ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x52 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x175 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x62 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x13b ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x80 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x10 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x10 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x10 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x46 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x64 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x3d ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0xdc ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x22 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0xac ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x1be ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x10 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x10 ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/time.o + .group 0x0000000000000000 0xc ecm_src/src/time.o + .group 0x0000000000000000 0xc ecm_src/src/time.o + .group 0x0000000000000000 0xc ecm_src/src/time.o + .group 0x0000000000000000 0xc ecm_src/src/time.o + .group 0x0000000000000000 0xc ecm_src/src/time.o + .group 0x0000000000000000 0xc ecm_src/src/time.o + .group 0x0000000000000000 0xc ecm_src/src/time.o + .group 0x0000000000000000 0xc ecm_src/src/time.o + .group 0x0000000000000000 0xc ecm_src/src/time.o + .group 0x0000000000000000 0xc ecm_src/src/time.o + .group 0x0000000000000000 0xc ecm_src/src/time.o + .group 0x0000000000000000 0xc ecm_src/src/time.o + .group 0x0000000000000000 0xc ecm_src/src/time.o + .group 0x0000000000000000 0xc ecm_src/src/time.o + .group 0x0000000000000000 0xc ecm_src/src/time.o + .group 0x0000000000000000 0xc ecm_src/src/time.o + .group 0x0000000000000000 0xc ecm_src/src/time.o + .group 0x0000000000000000 0xc ecm_src/src/time.o + .group 0x0000000000000000 0xc ecm_src/src/time.o + .group 0x0000000000000000 0xc ecm_src/src/time.o + .group 0x0000000000000000 0xc ecm_src/src/time.o + .group 0x0000000000000000 0xc ecm_src/src/time.o + .group 0x0000000000000000 0xc ecm_src/src/time.o + .group 0x0000000000000000 0xc ecm_src/src/time.o + .group 0x0000000000000000 0xc ecm_src/src/time.o + .group 0x0000000000000000 0xc ecm_src/src/time.o + .group 0x0000000000000000 0xc ecm_src/src/time.o + .group 0x0000000000000000 0xc ecm_src/src/time.o + .group 0x0000000000000000 0xc ecm_src/src/time.o + .group 0x0000000000000000 0xc ecm_src/src/time.o + .group 0x0000000000000000 0xc ecm_src/src/time.o + .group 0x0000000000000000 0xc ecm_src/src/time.o + .group 0x0000000000000000 0xc ecm_src/src/time.o + .group 0x0000000000000000 0xc ecm_src/src/time.o + .group 0x0000000000000000 0xc ecm_src/src/time.o + .group 0x0000000000000000 0xc ecm_src/src/time.o + .group 0x0000000000000000 0xc ecm_src/src/time.o + .group 0x0000000000000000 0xc ecm_src/src/time.o + .text 0x0000000000000000 0x0 ecm_src/src/time.o + .data 0x0000000000000000 0x0 ecm_src/src/time.o + .bss 0x0000000000000000 0x0 ecm_src/src/time.o + .text.stmr_init + 0x0000000000000000 0x40 ecm_src/src/time.o + .text.stmr_free + 0x0000000000000000 0x68 ecm_src/src/time.o + .text.stmr_stop + 0x0000000000000000 0x1e ecm_src/src/time.o + .text.stmr_run + 0x0000000000000000 0x26 ecm_src/src/time.o + .debug_macro 0x0000000000000000 0xa48 ecm_src/src/time.o + .debug_macro 0x0000000000000000 0x22 ecm_src/src/time.o + .debug_macro 0x0000000000000000 0x22 ecm_src/src/time.o + .debug_macro 0x0000000000000000 0x8e ecm_src/src/time.o + .debug_macro 0x0000000000000000 0x51 ecm_src/src/time.o + .debug_macro 0x0000000000000000 0xef ecm_src/src/time.o + .debug_macro 0x0000000000000000 0x6a ecm_src/src/time.o + .debug_macro 0x0000000000000000 0x1df ecm_src/src/time.o + .debug_macro 0x0000000000000000 0x174 ecm_src/src/time.o + .debug_macro 0x0000000000000000 0x2e ecm_src/src/time.o + .debug_macro 0x0000000000000000 0x22 ecm_src/src/time.o + .debug_macro 0x0000000000000000 0x1c ecm_src/src/time.o + .debug_macro 0x0000000000000000 0x22 ecm_src/src/time.o + .debug_macro 0x0000000000000000 0xb5 ecm_src/src/time.o + .debug_macro 0x0000000000000000 0x391 ecm_src/src/time.o + .debug_macro 0x0000000000000000 0xfe50 ecm_src/src/time.o + .debug_macro 0x0000000000000000 0x3c ecm_src/src/time.o + .debug_macro 0x0000000000000000 0x12d ecm_src/src/time.o + .debug_macro 0x0000000000000000 0x53 ecm_src/src/time.o + .debug_macro 0x0000000000000000 0x946 ecm_src/src/time.o + .debug_macro 0x0000000000000000 0x5f3 ecm_src/src/time.o + .debug_macro 0x0000000000000000 0x12f ecm_src/src/time.o + .debug_macro 0x0000000000000000 0x1a7 ecm_src/src/time.o + .debug_macro 0x0000000000000000 0x1a7 ecm_src/src/time.o + .debug_macro 0x0000000000000000 0x22c ecm_src/src/time.o + .debug_macro 0x0000000000000000 0x34 ecm_src/src/time.o + .debug_macro 0x0000000000000000 0x43 ecm_src/src/time.o + .debug_macro 0x0000000000000000 0x28 ecm_src/src/time.o + .debug_macro 0x0000000000000000 0xb0 ecm_src/src/time.o + .debug_macro 0x0000000000000000 0x217 ecm_src/src/time.o + .debug_macro 0x0000000000000000 0x22c ecm_src/src/time.o + .debug_macro 0x0000000000000000 0x5f ecm_src/src/time.o + .debug_macro 0x0000000000000000 0xa5 ecm_src/src/time.o + .debug_macro 0x0000000000000000 0x65 ecm_src/src/time.o + .debug_macro 0x0000000000000000 0x234 ecm_src/src/time.o + .debug_macro 0x0000000000000000 0x4c ecm_src/src/time.o + .debug_macro 0x0000000000000000 0x16d ecm_src/src/time.o + .debug_macro 0x0000000000000000 0x130 ecm_src/src/time.o + .debug_macro 0x0000000000000000 0x10 ecm_src/src/time.o + COMMON 0x0000000000000000 0x8 ecm_src/src/time.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .text 0x0000000000000000 0x0 ecm_src/src/usb_device.o + .data 0x0000000000000000 0x0 ecm_src/src/usb_device.o + .bss 0x0000000000000000 0x0 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0xa48 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x2e ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x22 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x22 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x8e ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x51 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0xef ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x6a ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x1df ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x1c ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x22 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0xb5 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x391 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0xfe50 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x3c ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x12d ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x174 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x53 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x946 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x5f3 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x12f ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x1a7 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x1a7 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x22c ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x34 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x43 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x28 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0xb0 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x217 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x22c ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x5f ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0xa5 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x65 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x234 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x4c ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x16d ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x130 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x46 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x18 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x3c ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x34 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x16 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x35 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x32a ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x10 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x52 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x1f ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x43 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x20 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x1a3 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x10 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x1c ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x52 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x40 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x10 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x40 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0xd7 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x1c ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x3d ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x16 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x145 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x16 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x16 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x29 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x16 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x20 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x64 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x1a6 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x22 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x70 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x16 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x22 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x16 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x5e ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x592 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x76 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x4f ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x52 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x175 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x62 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x13b ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x80 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x10 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x10 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x10 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x46 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x64 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x3d ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0xdc ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x22 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0xac ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x1be ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x10 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x10 ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .text 0x0000000000000000 0x0 ecm_src/src/usbd_conf.o + .data 0x0000000000000000 0x0 ecm_src/src/usbd_conf.o + .bss 0x0000000000000000 0x0 ecm_src/src/usbd_conf.o + .text.HAL_PCD_MspDeInit + 0x0000000000000000 0x24 ecm_src/src/usbd_conf.o + .text.HAL_PCD_ISOOUTIncompleteCallback + 0x0000000000000000 0x2a ecm_src/src/usbd_conf.o + .text.HAL_PCD_ISOINIncompleteCallback + 0x0000000000000000 0x2a ecm_src/src/usbd_conf.o + .text.HAL_PCD_ConnectCallback + 0x0000000000000000 0x1e ecm_src/src/usbd_conf.o + .text.HAL_PCD_DisconnectCallback + 0x0000000000000000 0x1e ecm_src/src/usbd_conf.o + .text.USBD_LL_DeInit + 0x0000000000000000 0x20 ecm_src/src/usbd_conf.o + .text.USBD_LL_Stop + 0x0000000000000000 0x20 ecm_src/src/usbd_conf.o + .text.USBD_LL_FlushEP + 0x0000000000000000 0x2c ecm_src/src/usbd_conf.o + .text.USBD_LL_Delay + 0x0000000000000000 0x18 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0xa48 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x12d ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x2e ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x22 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x22 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x8e ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x51 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0xef ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x6a ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x1df ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x1c ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x22 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0xb5 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x391 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0xfe50 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x3c ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x174 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x53 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x946 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x5f3 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x12f ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x1a7 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x1a7 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x22c ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x34 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x43 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x28 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0xb0 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x217 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x22c ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x5f ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0xa5 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x65 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x234 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x4c ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x16d ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x130 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x46 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x18 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x3c ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x34 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x16 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x35 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x32a ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x10 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x52 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x1f ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x43 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x20 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x1a3 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x10 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x1c ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x52 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x40 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x10 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x40 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0xd7 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x1c ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x3d ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x16 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x145 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x16 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x16 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x29 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x16 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x20 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x64 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x22 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x70 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x16 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x22 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x16 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x5e ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x592 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x76 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x4f ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x52 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x175 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x62 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x13b ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x80 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x10 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x10 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x10 ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .text 0x0000000000000000 0x0 ecm_src/src/usbd_core.o + .data 0x0000000000000000 0x0 ecm_src/src/usbd_core.o + .bss 0x0000000000000000 0x0 ecm_src/src/usbd_core.o + .text.USBD_DeInit + 0x0000000000000000 0x42 ecm_src/src/usbd_core.o + .text.USBD_Stop + 0x0000000000000000 0x30 ecm_src/src/usbd_core.o + .text.USBD_LL_Suspend + 0x0000000000000000 0x2c ecm_src/src/usbd_core.o + .text.USBD_LL_Resume + 0x0000000000000000 0x22 ecm_src/src/usbd_core.o + .text.USBD_LL_IsoINIncomplete + 0x0000000000000000 0x18 ecm_src/src/usbd_core.o + .text.USBD_LL_IsoOUTIncomplete + 0x0000000000000000 0x18 ecm_src/src/usbd_core.o + .text.USBD_LL_DevConnected + 0x0000000000000000 0x12 ecm_src/src/usbd_core.o + .text.USBD_LL_DevDisconnected + 0x0000000000000000 0x32 ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0xa48 ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x12d ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x2e ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x22 ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x22 ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x8e ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x51 ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0xef ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x6a ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x1df ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x1c ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x22 ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0xb5 ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x391 ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0xfe50 ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x3c ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x174 ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x53 ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x946 ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x5f3 ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x12f ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x1a7 ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x1a7 ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x22c ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x34 ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x43 ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x28 ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0xb0 ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x217 ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x22c ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x5f ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0xa5 ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x65 ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x234 ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x4c ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x16d ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x130 ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x46 ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x18 ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x3c ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x34 ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x16 ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x35 ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x32a ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x10 ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x52 ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x1f ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x43 ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x20 ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x1a3 ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x10 ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x1c ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x52 ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x40 ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x10 ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x40 ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0xd7 ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x1c ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x3d ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x16 ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x145 ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x16 ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x16 ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x29 ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x16 ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x20 ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x64 ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x1ac ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .text 0x0000000000000000 0x0 ecm_src/src/usbd_ctlreq.o + .data 0x0000000000000000 0x0 ecm_src/src/usbd_ctlreq.o + .bss 0x0000000000000000 0x0 ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0xa48 ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x12d ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x2e ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x22 ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x22 ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x8e ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x51 ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0xef ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x6a ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x1df ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x1c ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x22 ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0xb5 ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x391 ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0xfe50 ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x3c ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x174 ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x53 ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x946 ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x5f3 ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x12f ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x1a7 ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x1a7 ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x22c ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x34 ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x43 ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x28 ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0xb0 ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x217 ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x22c ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x5f ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0xa5 ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x65 ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x234 ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x4c ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x16d ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x130 ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x46 ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x18 ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x3c ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x34 ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x16 ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x35 ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x32a ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x10 ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x52 ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x1f ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x43 ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x20 ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x1a3 ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x10 ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x1c ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x52 ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x40 ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x10 ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x40 ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0xd7 ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x1c ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x3d ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x16 ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x145 ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x16 ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x16 ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x29 ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x16 ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x20 ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x64 ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x1a6 ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .text 0x0000000000000000 0x0 ecm_src/src/usbd_desc.o + .data 0x0000000000000000 0x0 ecm_src/src/usbd_desc.o + .bss 0x0000000000000000 0x0 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0xa48 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x12d ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x2e ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x22 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x22 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x8e ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x51 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0xef ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x6a ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x1df ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x1c ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x22 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0xb5 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x391 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0xfe50 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x3c ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x174 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x53 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x946 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x5f3 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x12f ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x1a7 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x1a7 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x22c ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x34 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x43 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x28 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0xb0 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x217 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x22c ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x5f ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0xa5 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x65 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x234 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x4c ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x16d ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x130 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x46 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x18 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x3c ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x34 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x16 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x35 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x32a ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x10 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x52 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x1f ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x43 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x20 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x1a3 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x10 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x1c ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x52 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x40 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x10 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x40 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0xd7 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x1c ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x3d ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x16 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x145 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x16 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x16 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x29 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x16 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x20 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x64 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x1ac ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x10 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x22 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x70 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x16 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x22 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x16 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x5e ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x592 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x76 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x4f ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x52 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x175 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x62 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x13b ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x80 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x10 ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .text 0x0000000000000000 0x0 ecm_src/src/usbd_ecm.o + .data 0x0000000000000000 0x0 ecm_src/src/usbd_ecm.o + .bss 0x0000000000000000 0x0 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0xa48 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x22 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x8e ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x51 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0xef ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x6a ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x1df ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x22 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x12d ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x2e ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x22 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x1c ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x22 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0xb5 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x391 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0xfe50 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x3c ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x174 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x53 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x946 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x5f3 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x12f ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x1a7 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x1a7 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x22c ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x34 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x43 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x28 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0xb0 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x217 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x22c ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x5f ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0xa5 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x65 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x234 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x4c ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x16d ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x130 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x46 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x18 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x3c ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x34 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x16 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x35 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x32a ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x10 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x52 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x1f ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x43 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x20 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x1a3 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x10 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x1c ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x52 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x40 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x10 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x40 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0xd7 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x1c ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x3d ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x16 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x145 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x16 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x16 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x29 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x16 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x20 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x64 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x1a6 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x70 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x16 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x22 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x16 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x5e ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x592 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x76 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x4f ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x52 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x175 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x62 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x13b ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x80 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x10 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x10 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x10 ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .text 0x0000000000000000 0x0 ecm_src/src/usbd_ioreq.o + .data 0x0000000000000000 0x0 ecm_src/src/usbd_ioreq.o + .bss 0x0000000000000000 0x0 ecm_src/src/usbd_ioreq.o + .text.USBD_CtlPrepareRx + 0x0000000000000000 0x48 ecm_src/src/usbd_ioreq.o + .text.USBD_GetRxCount + 0x0000000000000000 0x28 ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0xa48 ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x12d ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x2e ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x22 ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x22 ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x8e ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x51 ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0xef ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x6a ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x1df ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x1c ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x22 ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0xb5 ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x391 ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0xfe50 ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x3c ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x174 ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x53 ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x946 ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x5f3 ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x12f ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x1a7 ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x1a7 ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x22c ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x34 ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x43 ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x28 ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0xb0 ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x217 ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x22c ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x5f ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0xa5 ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x65 ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x234 ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x4c ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x16d ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x130 ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x46 ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x18 ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x3c ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x34 ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x16 ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x35 ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x32a ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x10 ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x52 ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x1f ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x43 ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x20 ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x1a3 ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x10 ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x1c ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x52 ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x40 ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x10 ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x40 ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0xd7 ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x1c ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x3d ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x16 ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x145 ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x16 ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x16 ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x29 ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x16 ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x20 ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x64 ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x1a6 ecm_src/src/usbd_ioreq.o + .text 0x0000000000000000 0x0 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-errno.o) + .data 0x0000000000000000 0x0 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-errno.o) + .bss 0x0000000000000000 0x0 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-errno.o) + .text.__errno 0x0000000000000000 0xc c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-errno.o) + .debug_frame 0x0000000000000000 0x20 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-errno.o) + .ARM.attributes + 0x0000000000000000 0x2c c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-errno.o) + .text 0x0000000000000000 0x0 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-exit.o) + .data 0x0000000000000000 0x0 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-exit.o) + .bss 0x0000000000000000 0x0 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-exit.o) + .text.exit 0x0000000000000000 0x2c c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-exit.o) + .debug_frame 0x0000000000000000 0x28 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-exit.o) + .ARM.attributes + 0x0000000000000000 0x2c c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-exit.o) + .text 0x0000000000000000 0x0 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-impure.o) + .data 0x0000000000000000 0x0 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-impure.o) + .bss 0x0000000000000000 0x0 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-impure.o) + .data._impure_ptr + 0x0000000000000000 0x4 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-impure.o) + .data.impure_data + 0x0000000000000000 0x60 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-impure.o) + .rodata._global_impure_ptr + 0x0000000000000000 0x4 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-impure.o) + .ARM.attributes + 0x0000000000000000 0x2c c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-impure.o) + .text 0x0000000000000000 0x0 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-init.o) + .data 0x0000000000000000 0x0 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-init.o) + .bss 0x0000000000000000 0x0 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-init.o) + .text 0x0000000000000000 0x0 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-memcmp.o) + .data 0x0000000000000000 0x0 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-memcmp.o) + .bss 0x0000000000000000 0x0 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-memcmp.o) + .text 0x0000000000000000 0x0 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-memcpy-stub.o) + .data 0x0000000000000000 0x0 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-memcpy-stub.o) + .bss 0x0000000000000000 0x0 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-memcpy-stub.o) + .text 0x0000000000000000 0x0 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-memset.o) + .data 0x0000000000000000 0x0 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-memset.o) + .bss 0x0000000000000000 0x0 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-memset.o) + .data 0x0000000000000000 0x0 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-strcmp.o) + .bss 0x0000000000000000 0x0 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-strcmp.o) + .data 0x0000000000000000 0x0 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-strlen.o) + .bss 0x0000000000000000 0x0 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-strlen.o) + .data 0x0000000000000000 0x0 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v6-m\libgcc.a(_udivsi3.o) + .bss 0x0000000000000000 0x0 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v6-m\libgcc.a(_udivsi3.o) + .data 0x0000000000000000 0x0 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v6-m\libgcc.a(_divsi3.o) + .bss 0x0000000000000000 0x0 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v6-m\libgcc.a(_divsi3.o) + .data 0x0000000000000000 0x0 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v6-m\libgcc.a(_dvmd_tls.o) + .bss 0x0000000000000000 0x0 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v6-m\libgcc.a(_dvmd_tls.o) + .text 0x0000000000000000 0x0 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v6-m/crtend.o + .data 0x0000000000000000 0x0 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v6-m/crtend.o + .bss 0x0000000000000000 0x0 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v6-m/crtend.o + .eh_frame 0x0000000000000000 0x4 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v6-m/crtend.o + .ARM.attributes + 0x0000000000000000 0x2c c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v6-m/crtend.o + .text 0x0000000000000000 0x0 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v6-m/crtn.o + .data 0x0000000000000000 0x0 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v6-m/crtn.o + .bss 0x0000000000000000 0x0 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v6-m/crtn.o + +Memory Configuration + +Name Origin Length Attributes +RAM 0x0000000020000000 0x0000000000004000 xrw +FLASH 0x0000000008000000 0x0000000000010000 xr +*default* 0x0000000000000000 0xffffffffffffffff + +Linker script and memory map + +LOAD c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v6-m/crti.o +LOAD c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v6-m/crtbegin.o +LOAD c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m/crt0.o +LOAD Core/Src/main.o +LOAD Core/Src/stm32f0xx_hal_msp.o +LOAD Core/Src/stm32f0xx_it.o +LOAD Core/Src/syscalls.o +LOAD Core/Src/sysmem.o +LOAD Core/Src/system_stm32f0xx.o +LOAD Core/Startup/startup_stm32f072c8tx.o +LOAD Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o +LOAD Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o +LOAD Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o +LOAD Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o +LOAD Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o +LOAD Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o +LOAD Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o +LOAD Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o +LOAD Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o +LOAD Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o +LOAD Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o +LOAD Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o +LOAD Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o +LOAD Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o +LOAD Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o +LOAD Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o +LOAD Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o +LOAD Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o +LOAD ecm_src/dhcp-server/dhserver.o +LOAD ecm_src/dns-server/dnserver.o +LOAD ecm_src/lwip-1.4.1/src/core/def.o +LOAD ecm_src/lwip-1.4.1/src/core/dhcp.o +LOAD ecm_src/lwip-1.4.1/src/core/dns.o +LOAD ecm_src/lwip-1.4.1/src/core/init.o +LOAD ecm_src/lwip-1.4.1/src/core/mem.o +LOAD ecm_src/lwip-1.4.1/src/core/memp.o +LOAD ecm_src/lwip-1.4.1/src/core/netif.o +LOAD ecm_src/lwip-1.4.1/src/core/pbuf.o +LOAD ecm_src/lwip-1.4.1/src/core/raw.o +LOAD ecm_src/lwip-1.4.1/src/core/stats.o +LOAD ecm_src/lwip-1.4.1/src/core/sys.o +LOAD ecm_src/lwip-1.4.1/src/core/tcp.o +LOAD ecm_src/lwip-1.4.1/src/core/tcp_in.o +LOAD ecm_src/lwip-1.4.1/src/core/tcp_out.o +LOAD ecm_src/lwip-1.4.1/src/core/timers.o +LOAD ecm_src/lwip-1.4.1/src/core/udp.o +LOAD ecm_src/lwip-1.4.1/src/core/ipv4/autoip.o +LOAD ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o +LOAD ecm_src/lwip-1.4.1/src/core/ipv4/igmp.o +LOAD ecm_src/lwip-1.4.1/src/core/ipv4/inet.o +LOAD ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o +LOAD ecm_src/lwip-1.4.1/src/core/ipv4/ip.o +LOAD ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o +LOAD ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o +LOAD ecm_src/lwip-1.4.1/src/netif/etharp.o +LOAD ecm_src/lwip-1.4.1/src/netif/ethernetif.o +LOAD ecm_src/src/ecm_main.o +LOAD ecm_src/src/time.o +LOAD ecm_src/src/usb_device.o +LOAD ecm_src/src/usbd_conf.o +LOAD ecm_src/src/usbd_core.o +LOAD ecm_src/src/usbd_ctlreq.o +LOAD ecm_src/src/usbd_desc.o +LOAD ecm_src/src/usbd_ecm.o +LOAD ecm_src/src/usbd_ioreq.o +START GROUP +LOAD c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a +LOAD c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libm.a +END GROUP +START GROUP +LOAD c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v6-m\libgcc.a +LOAD c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a +END GROUP +START GROUP +LOAD c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v6-m\libgcc.a +LOAD c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a +LOAD c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libnosys.a +END GROUP +START GROUP +LOAD c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v6-m\libgcc.a +LOAD c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a +LOAD c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libnosys.a +END GROUP +LOAD c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v6-m/crtend.o +LOAD c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v6-m/crtn.o + 0x0000000020004000 _estack = (ORIGIN (RAM) + LENGTH (RAM)) + 0x0000000000000200 _Min_Heap_Size = 0x200 + 0x0000000000000400 _Min_Stack_Size = 0x400 + +.isr_vector 0x0000000008000000 0xc0 + 0x0000000008000000 . = ALIGN (0x4) + *(.isr_vector) + .isr_vector 0x0000000008000000 0xc0 Core/Startup/startup_stm32f072c8tx.o + 0x0000000008000000 g_pfnVectors + 0x00000000080000c0 . = ALIGN (0x4) + +.text 0x00000000080000c0 0xfc1c + 0x00000000080000c0 . = ALIGN (0x4) + *(.text) + .text 0x00000000080000c0 0x48 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v6-m/crtbegin.o + .text 0x0000000008000108 0x14 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-strcmp.o) + 0x0000000008000108 strcmp + .text 0x000000000800011c 0xe c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-strlen.o) + 0x000000000800011c strlen + *fill* 0x000000000800012a 0x2 + .text 0x000000000800012c 0x114 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v6-m\libgcc.a(_udivsi3.o) + 0x000000000800012c __aeabi_uidiv + 0x000000000800012c __udivsi3 + 0x0000000008000238 __aeabi_uidivmod + .text 0x0000000008000240 0x1d4 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v6-m\libgcc.a(_divsi3.o) + 0x0000000008000240 __divsi3 + 0x0000000008000240 __aeabi_idiv + 0x000000000800040c __aeabi_idivmod + .text 0x0000000008000414 0x4 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v6-m\libgcc.a(_dvmd_tls.o) + 0x0000000008000414 __aeabi_idiv0 + 0x0000000008000414 __aeabi_ldiv0 + *(.text*) + .text.main 0x0000000008000418 0x1e Core/Src/main.o + 0x0000000008000418 main + .text.SystemClock_Config + 0x0000000008000436 0xa8 Core/Src/main.o + 0x0000000008000436 SystemClock_Config + *fill* 0x00000000080004de 0x2 + .text.MX_GPIO_Init + 0x00000000080004e0 0x30 Core/Src/main.o + .text.Error_Handler + 0x0000000008000510 0xa Core/Src/main.o + 0x0000000008000510 Error_Handler + *fill* 0x000000000800051a 0x2 + .text.HAL_MspInit + 0x000000000800051c 0x48 Core/Src/stm32f0xx_hal_msp.o + 0x000000000800051c HAL_MspInit + .text.NMI_Handler + 0x0000000008000564 0xa Core/Src/stm32f0xx_it.o + 0x0000000008000564 NMI_Handler + .text.HardFault_Handler + 0x000000000800056e 0x6 Core/Src/stm32f0xx_it.o + 0x000000000800056e HardFault_Handler + .text.SVC_Handler + 0x0000000008000574 0xa Core/Src/stm32f0xx_it.o + 0x0000000008000574 SVC_Handler + .text.PendSV_Handler + 0x000000000800057e 0xa Core/Src/stm32f0xx_it.o + 0x000000000800057e PendSV_Handler + .text.SysTick_Handler + 0x0000000008000588 0xe Core/Src/stm32f0xx_it.o + 0x0000000008000588 SysTick_Handler + *fill* 0x0000000008000596 0x2 + .text.USB_IRQHandler + 0x0000000008000598 0x18 Core/Src/stm32f0xx_it.o + 0x0000000008000598 USB_IRQHandler + .text.SystemInit + 0x00000000080005b0 0xa Core/Src/system_stm32f0xx.o + 0x00000000080005b0 SystemInit + *fill* 0x00000000080005ba 0x2 + .text.Reset_Handler + 0x00000000080005bc 0x50 Core/Startup/startup_stm32f072c8tx.o + 0x00000000080005bc Reset_Handler + .text.Default_Handler + 0x000000000800060c 0x2 Core/Startup/startup_stm32f072c8tx.o + 0x000000000800060c TIM1_CC_IRQHandler + 0x000000000800060c TSC_IRQHandler + 0x000000000800060c ADC1_COMP_IRQHandler + 0x000000000800060c I2C1_IRQHandler + 0x000000000800060c RCC_CRS_IRQHandler + 0x000000000800060c SPI1_IRQHandler + 0x000000000800060c TIM6_DAC_IRQHandler + 0x000000000800060c USART3_4_IRQHandler + 0x000000000800060c EXTI2_3_IRQHandler + 0x000000000800060c I2C2_IRQHandler + 0x000000000800060c TIM17_IRQHandler + 0x000000000800060c CEC_CAN_IRQHandler + 0x000000000800060c RTC_IRQHandler + 0x000000000800060c PVD_VDDIO2_IRQHandler + 0x000000000800060c DMA1_Channel4_5_6_7_IRQHandler + 0x000000000800060c TIM16_IRQHandler + 0x000000000800060c TIM3_IRQHandler + 0x000000000800060c EXTI4_15_IRQHandler + 0x000000000800060c DMA1_Channel1_IRQHandler + 0x000000000800060c Default_Handler + 0x000000000800060c TIM14_IRQHandler + 0x000000000800060c TIM7_IRQHandler + 0x000000000800060c TIM15_IRQHandler + 0x000000000800060c EXTI0_1_IRQHandler + 0x000000000800060c SPI2_IRQHandler + 0x000000000800060c WWDG_IRQHandler + 0x000000000800060c TIM2_IRQHandler + 0x000000000800060c DMA1_Channel2_3_IRQHandler + 0x000000000800060c USART2_IRQHandler + 0x000000000800060c FLASH_IRQHandler + 0x000000000800060c USART1_IRQHandler + 0x000000000800060c TIM1_BRK_UP_TRG_COM_IRQHandler + *fill* 0x000000000800060e 0x2 + .text.HAL_Init + 0x0000000008000610 0x28 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + 0x0000000008000610 HAL_Init + .text.HAL_InitTick + 0x0000000008000638 0x68 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + 0x0000000008000638 HAL_InitTick + .text.HAL_IncTick + 0x00000000080006a0 0x24 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + 0x00000000080006a0 HAL_IncTick + .text.HAL_GetTick + 0x00000000080006c4 0x14 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + 0x00000000080006c4 HAL_GetTick + .text.__NVIC_EnableIRQ + 0x00000000080006d8 0x34 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .text.__NVIC_SetPriority + 0x000000000800070c 0xdc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .text.SysTick_Config + 0x00000000080007e8 0x48 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .text.HAL_NVIC_SetPriority + 0x0000000008000830 0x2a Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + 0x0000000008000830 HAL_NVIC_SetPriority + .text.HAL_NVIC_EnableIRQ + 0x000000000800085a 0x20 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + 0x000000000800085a HAL_NVIC_EnableIRQ + .text.HAL_SYSTICK_Config + 0x000000000800087a 0x1a Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + 0x000000000800087a HAL_SYSTICK_Config + .text.HAL_GPIO_Init + 0x0000000008000894 0x2f0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + 0x0000000008000894 HAL_GPIO_Init + .text.HAL_PCD_Init + 0x0000000008000b84 0x1c8 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + 0x0000000008000b84 HAL_PCD_Init + .text.HAL_PCD_Start + 0x0000000008000d4c 0x4a Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + 0x0000000008000d4c HAL_PCD_Start + *fill* 0x0000000008000d96 0x2 + .text.HAL_PCD_IRQHandler + 0x0000000008000d98 0x310 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + 0x0000000008000d98 HAL_PCD_IRQHandler + .text.HAL_PCD_SetAddress + 0x00000000080010a8 0x56 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + 0x00000000080010a8 HAL_PCD_SetAddress + .text.HAL_PCD_EP_Open + 0x00000000080010fe 0xe4 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + 0x00000000080010fe HAL_PCD_EP_Open + .text.HAL_PCD_EP_Close + 0x00000000080011e2 0x96 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + 0x00000000080011e2 HAL_PCD_EP_Close + .text.HAL_PCD_EP_Receive + 0x0000000008001278 0x82 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + 0x0000000008001278 HAL_PCD_EP_Receive + .text.HAL_PCD_EP_GetRxCount + 0x00000000080012fa 0x2a Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + 0x00000000080012fa HAL_PCD_EP_GetRxCount + .text.HAL_PCD_EP_Transmit + 0x0000000008001324 0x80 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + 0x0000000008001324 HAL_PCD_EP_Transmit + .text.HAL_PCD_EP_SetStall + 0x00000000080013a4 0xcc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + 0x00000000080013a4 HAL_PCD_EP_SetStall + .text.HAL_PCD_EP_ClrStall + 0x0000000008001470 0xb0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + 0x0000000008001470 HAL_PCD_EP_ClrStall + .text.PCD_EP_ISR_Handler + 0x0000000008001520 0x5a8 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .text.HAL_PCDEx_PMAConfig + 0x0000000008001ac8 0x90 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + 0x0000000008001ac8 HAL_PCDEx_PMAConfig + .text.HAL_PCDEx_ActivateLPM + 0x0000000008001b58 0x54 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + 0x0000000008001b58 HAL_PCDEx_ActivateLPM + .text.HAL_PCDEx_LPM_Callback + 0x0000000008001bac 0x16 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + 0x0000000008001bac HAL_PCDEx_LPM_Callback + *fill* 0x0000000008001bc2 0x2 + .text.HAL_RCC_OscConfig + 0x0000000008001bc4 0x70c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + 0x0000000008001bc4 HAL_RCC_OscConfig + .text.HAL_RCC_ClockConfig + 0x00000000080022d0 0x1b4 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + 0x00000000080022d0 HAL_RCC_ClockConfig + .text.HAL_RCC_GetSysClockFreq + 0x0000000008002484 0xfc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + 0x0000000008002484 HAL_RCC_GetSysClockFreq + .text.HAL_RCCEx_PeriphCLKConfig + 0x0000000008002580 0x200 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + 0x0000000008002580 HAL_RCCEx_PeriphCLKConfig + .text.USB_EnableGlobalInt + 0x0000000008002780 0x34 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + 0x0000000008002780 USB_EnableGlobalInt + .text.USB_DisableGlobalInt + 0x00000000080027b4 0x40 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + 0x00000000080027b4 USB_DisableGlobalInt + .text.USB_DevInit + 0x00000000080027f4 0x60 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + 0x00000000080027f4 USB_DevInit + .text.USB_ActivateEndpoint + 0x0000000008002854 0x5f0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + 0x0000000008002854 USB_ActivateEndpoint + .text.USB_DeactivateEndpoint + 0x0000000008002e44 0x2ec Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + 0x0000000008002e44 USB_DeactivateEndpoint + .text.USB_EPStartXfer + 0x0000000008003130 0x5a4 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + 0x0000000008003130 USB_EPStartXfer + .text.USB_EPSetStall + 0x00000000080036d4 0x84 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + 0x00000000080036d4 USB_EPSetStall + .text.USB_EPClearStall + 0x0000000008003758 0x124 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + 0x0000000008003758 USB_EPClearStall + .text.USB_SetDevAddress + 0x000000000800387c 0x28 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + 0x000000000800387c USB_SetDevAddress + .text.USB_DevConnect + 0x00000000080038a4 0x2c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + 0x00000000080038a4 USB_DevConnect + .text.USB_ReadInterrupts + 0x00000000080038d0 0x1c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + 0x00000000080038d0 USB_ReadInterrupts + .text.USB_EP0_OutStart + 0x00000000080038ec 0x14 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + 0x00000000080038ec USB_EP0_OutStart + .text.USB_WritePMA + 0x0000000008003900 0x86 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + 0x0000000008003900 USB_WritePMA + .text.USB_ReadPMA + 0x0000000008003986 0x9e Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + 0x0000000008003986 USB_ReadPMA + .text.get_ip 0x0000000008003a24 0x20 ecm_src/dhcp-server/dhserver.o + .text.set_ip 0x0000000008003a44 0x1e ecm_src/dhcp-server/dhserver.o + *fill* 0x0000000008003a62 0x2 + .text.entry_by_ip + 0x0000000008003a64 0x64 ecm_src/dhcp-server/dhserver.o + .text.entry_by_mac + 0x0000000008003ac8 0x64 ecm_src/dhcp-server/dhserver.o + .text.is_vacant + 0x0000000008003b2c 0x28 ecm_src/dhcp-server/dhserver.o + .text.vacant_address + 0x0000000008003b54 0x5c ecm_src/dhcp-server/dhserver.o + .text.free_entry + 0x0000000008003bb0 0x1c ecm_src/dhcp-server/dhserver.o + .text.find_dhcp_option + 0x0000000008003bcc 0x64 ecm_src/dhcp-server/dhserver.o + 0x0000000008003bcc find_dhcp_option + .text.fill_options + 0x0000000008003c30 0x17a ecm_src/dhcp-server/dhserver.o + 0x0000000008003c30 fill_options + *fill* 0x0000000008003daa 0x2 + .text.udp_recv_proc + 0x0000000008003dac 0x2f4 ecm_src/dhcp-server/dhserver.o + .text.dhserv_init + 0x00000000080040a0 0x88 ecm_src/dhcp-server/dhserver.o + 0x00000000080040a0 dhserv_init + .text.dhserv_free + 0x0000000008004128 0x28 ecm_src/dhcp-server/dhserver.o + 0x0000000008004128 dhserv_free + .text.get_uint16 + 0x0000000008004150 0x22 ecm_src/dns-server/dnserver.o + .text.parse_next_query + 0x0000000008004172 0x118 ecm_src/dns-server/dnserver.o + *fill* 0x000000000800428a 0x2 + .text.udp_recv_proc + 0x000000000800428c 0x2d0 ecm_src/dns-server/dnserver.o + .text.dnserv_init + 0x000000000800455c 0x90 ecm_src/dns-server/dnserver.o + 0x000000000800455c dnserv_init + .text.dnserv_free + 0x00000000080045ec 0x28 ecm_src/dns-server/dnserver.o + 0x00000000080045ec dnserv_free + .text.lwip_htons + 0x0000000008004614 0x2c ecm_src/lwip-1.4.1/src/core/def.o + 0x0000000008004614 lwip_htons + .text.lwip_ntohs + 0x0000000008004640 0x20 ecm_src/lwip-1.4.1/src/core/def.o + 0x0000000008004640 lwip_ntohs + .text.lwip_htonl + 0x0000000008004660 0x32 ecm_src/lwip-1.4.1/src/core/def.o + 0x0000000008004660 lwip_htonl + .text.lwip_ntohl + 0x0000000008004692 0x1a ecm_src/lwip-1.4.1/src/core/def.o + 0x0000000008004692 lwip_ntohl + .text.lwip_init + 0x00000000080046ac 0x26 ecm_src/lwip-1.4.1/src/core/init.o + 0x00000000080046ac lwip_init + *fill* 0x00000000080046d2 0x2 + .text.plug_holes + 0x00000000080046d4 0xbc ecm_src/lwip-1.4.1/src/core/mem.o + .text.mem_init + 0x0000000008004790 0x88 ecm_src/lwip-1.4.1/src/core/mem.o + 0x0000000008004790 mem_init + .text.mem_free + 0x0000000008004818 0x94 ecm_src/lwip-1.4.1/src/core/mem.o + 0x0000000008004818 mem_free + .text.mem_trim + 0x00000000080048ac 0x228 ecm_src/lwip-1.4.1/src/core/mem.o + 0x00000000080048ac mem_trim + .text.mem_malloc + 0x0000000008004ad4 0x218 ecm_src/lwip-1.4.1/src/core/mem.o + 0x0000000008004ad4 mem_malloc + .text.memp_init + 0x0000000008004cec 0x128 ecm_src/lwip-1.4.1/src/core/memp.o + 0x0000000008004cec memp_init + .text.memp_malloc + 0x0000000008004e14 0x10c ecm_src/lwip-1.4.1/src/core/memp.o + 0x0000000008004e14 memp_malloc + .text.memp_free + 0x0000000008004f20 0x74 ecm_src/lwip-1.4.1/src/core/memp.o + 0x0000000008004f20 memp_free + .text.netif_init + 0x0000000008004f94 0xa ecm_src/lwip-1.4.1/src/core/netif.o + 0x0000000008004f94 netif_init + *fill* 0x0000000008004f9e 0x2 + .text.netif_add + 0x0000000008004fa0 0x84 ecm_src/lwip-1.4.1/src/core/netif.o + 0x0000000008004fa0 netif_add + .text.netif_set_addr + 0x0000000008005024 0x3a ecm_src/lwip-1.4.1/src/core/netif.o + 0x0000000008005024 netif_set_addr + *fill* 0x000000000800505e 0x2 + .text.netif_set_ipaddr + 0x0000000008005060 0xb4 ecm_src/lwip-1.4.1/src/core/netif.o + 0x0000000008005060 netif_set_ipaddr + .text.netif_set_gw + 0x0000000008005114 0x24 ecm_src/lwip-1.4.1/src/core/netif.o + 0x0000000008005114 netif_set_gw + .text.netif_set_netmask + 0x0000000008005138 0x24 ecm_src/lwip-1.4.1/src/core/netif.o + 0x0000000008005138 netif_set_netmask + .text.netif_set_default + 0x000000000800515c 0x1c ecm_src/lwip-1.4.1/src/core/netif.o + 0x000000000800515c netif_set_default + .text.pbuf_pool_is_empty + 0x0000000008005178 0x14 ecm_src/lwip-1.4.1/src/core/pbuf.o + .text.pbuf_alloc + 0x000000000800518c 0x244 ecm_src/lwip-1.4.1/src/core/pbuf.o + 0x000000000800518c pbuf_alloc + .text.pbuf_alloced_custom + 0x00000000080053d0 0xe2 ecm_src/lwip-1.4.1/src/core/pbuf.o + 0x00000000080053d0 pbuf_alloced_custom + .text.pbuf_realloc + 0x00000000080054b2 0xe4 ecm_src/lwip-1.4.1/src/core/pbuf.o + 0x00000000080054b2 pbuf_realloc + .text.pbuf_header + 0x0000000008005596 0x10e ecm_src/lwip-1.4.1/src/core/pbuf.o + 0x0000000008005596 pbuf_header + .text.pbuf_free + 0x00000000080056a4 0xe4 ecm_src/lwip-1.4.1/src/core/pbuf.o + 0x00000000080056a4 pbuf_free + .text.pbuf_clen + 0x0000000008005788 0x38 ecm_src/lwip-1.4.1/src/core/pbuf.o + 0x0000000008005788 pbuf_clen + .text.pbuf_ref + 0x00000000080057c0 0x22 ecm_src/lwip-1.4.1/src/core/pbuf.o + 0x00000000080057c0 pbuf_ref + .text.pbuf_cat + 0x00000000080057e2 0x5a ecm_src/lwip-1.4.1/src/core/pbuf.o + 0x00000000080057e2 pbuf_cat + .text.pbuf_chain + 0x000000000800583c 0x26 ecm_src/lwip-1.4.1/src/core/pbuf.o + 0x000000000800583c pbuf_chain + .text.pbuf_copy + 0x0000000008005862 0x15a ecm_src/lwip-1.4.1/src/core/pbuf.o + 0x0000000008005862 pbuf_copy + .text.pbuf_copy_partial + 0x00000000080059bc 0x110 ecm_src/lwip-1.4.1/src/core/pbuf.o + 0x00000000080059bc pbuf_copy_partial + .text.raw_input + 0x0000000008005acc 0xd4 ecm_src/lwip-1.4.1/src/core/raw.o + 0x0000000008005acc raw_input + .text.stats_init + 0x0000000008005ba0 0xa ecm_src/lwip-1.4.1/src/core/stats.o + 0x0000000008005ba0 stats_init + .text.tcp_init + 0x0000000008005baa 0xa ecm_src/lwip-1.4.1/src/core/tcp.o + 0x0000000008005baa tcp_init + .text.tcp_tmr 0x0000000008005bb4 0x30 ecm_src/lwip-1.4.1/src/core/tcp.o + 0x0000000008005bb4 tcp_tmr + .text.tcp_close_shutdown + 0x0000000008005be4 0x284 ecm_src/lwip-1.4.1/src/core/tcp.o + .text.tcp_close + 0x0000000008005e68 0x32 ecm_src/lwip-1.4.1/src/core/tcp.o + 0x0000000008005e68 tcp_close + *fill* 0x0000000008005e9a 0x2 + .text.tcp_abandon + 0x0000000008005e9c 0xe0 ecm_src/lwip-1.4.1/src/core/tcp.o + 0x0000000008005e9c tcp_abandon + .text.tcp_abort + 0x0000000008005f7c 0x1a ecm_src/lwip-1.4.1/src/core/tcp.o + 0x0000000008005f7c tcp_abort + *fill* 0x0000000008005f96 0x2 + .text.tcp_update_rcv_ann_wnd + 0x0000000008005f98 0x80 ecm_src/lwip-1.4.1/src/core/tcp.o + 0x0000000008005f98 tcp_update_rcv_ann_wnd + .text.tcp_recved + 0x0000000008006018 0x68 ecm_src/lwip-1.4.1/src/core/tcp.o + 0x0000000008006018 tcp_recved + .text.tcp_slowtmr + 0x0000000008006080 0x4dc ecm_src/lwip-1.4.1/src/core/tcp.o + 0x0000000008006080 tcp_slowtmr + .text.tcp_fasttmr + 0x000000000800655c 0xa8 ecm_src/lwip-1.4.1/src/core/tcp.o + 0x000000000800655c tcp_fasttmr + .text.tcp_process_refused_data + 0x0000000008006604 0xf0 ecm_src/lwip-1.4.1/src/core/tcp.o + 0x0000000008006604 tcp_process_refused_data + .text.tcp_segs_free + 0x00000000080066f4 0x2a ecm_src/lwip-1.4.1/src/core/tcp.o + 0x00000000080066f4 tcp_segs_free + .text.tcp_seg_free + 0x000000000800671e 0x32 ecm_src/lwip-1.4.1/src/core/tcp.o + 0x000000000800671e tcp_seg_free + .text.tcp_seg_copy + 0x0000000008006750 0x3c ecm_src/lwip-1.4.1/src/core/tcp.o + 0x0000000008006750 tcp_seg_copy + .text.tcp_recv_null + 0x000000000800678c 0x50 ecm_src/lwip-1.4.1/src/core/tcp.o + 0x000000000800678c tcp_recv_null + .text.tcp_kill_prio + 0x00000000080067dc 0x94 ecm_src/lwip-1.4.1/src/core/tcp.o + .text.tcp_kill_timewait + 0x0000000008006870 0x60 ecm_src/lwip-1.4.1/src/core/tcp.o + .text.tcp_alloc + 0x00000000080068d0 0x158 ecm_src/lwip-1.4.1/src/core/tcp.o + 0x00000000080068d0 tcp_alloc + .text.tcp_pcb_purge + 0x0000000008006a28 0x82 ecm_src/lwip-1.4.1/src/core/tcp.o + 0x0000000008006a28 tcp_pcb_purge + *fill* 0x0000000008006aaa 0x2 + .text.tcp_pcb_remove + 0x0000000008006aac 0xa8 ecm_src/lwip-1.4.1/src/core/tcp.o + 0x0000000008006aac tcp_pcb_remove + .text.tcp_next_iss + 0x0000000008006b54 0x24 ecm_src/lwip-1.4.1/src/core/tcp.o + 0x0000000008006b54 tcp_next_iss + .text.tcp_eff_send_mss + 0x0000000008006b78 0x56 ecm_src/lwip-1.4.1/src/core/tcp.o + 0x0000000008006b78 tcp_eff_send_mss + *fill* 0x0000000008006bce 0x2 + .text.tcp_input + 0x0000000008006bd0 0x8b8 ecm_src/lwip-1.4.1/src/core/tcp_in.o + 0x0000000008006bd0 tcp_input + .text.tcp_listen_input + 0x0000000008007488 0x1e0 ecm_src/lwip-1.4.1/src/core/tcp_in.o + .text.tcp_timewait_input + 0x0000000008007668 0xe8 ecm_src/lwip-1.4.1/src/core/tcp_in.o + .text.tcp_process + 0x0000000008007750 0x738 ecm_src/lwip-1.4.1/src/core/tcp_in.o + .text.tcp_oos_insert_segment + 0x0000000008007e88 0x15c ecm_src/lwip-1.4.1/src/core/tcp_in.o + .text.tcp_receive + 0x0000000008007fe4 0x1154 ecm_src/lwip-1.4.1/src/core/tcp_in.o + .text.tcp_parseopt + 0x0000000008009138 0x16c ecm_src/lwip-1.4.1/src/core/tcp_in.o + .text.tcp_output_alloc_header + 0x00000000080092a4 0x21a ecm_src/lwip-1.4.1/src/core/tcp_out.o + .text.tcp_send_fin + 0x00000000080094be 0xb0 ecm_src/lwip-1.4.1/src/core/tcp_out.o + 0x00000000080094be tcp_send_fin + *fill* 0x000000000800956e 0x2 + .text.tcp_create_segment + 0x0000000008009570 0x1ec ecm_src/lwip-1.4.1/src/core/tcp_out.o + .text.tcp_enqueue_flags + 0x000000000800975c 0x1f4 ecm_src/lwip-1.4.1/src/core/tcp_out.o + 0x000000000800975c tcp_enqueue_flags + .text.tcp_send_empty_ack + 0x0000000008009950 0xc0 ecm_src/lwip-1.4.1/src/core/tcp_out.o + 0x0000000008009950 tcp_send_empty_ack + .text.tcp_output + 0x0000000008009a10 0x370 ecm_src/lwip-1.4.1/src/core/tcp_out.o + 0x0000000008009a10 tcp_output + .text.tcp_output_segment + 0x0000000008009d80 0x24c ecm_src/lwip-1.4.1/src/core/tcp_out.o + .text.tcp_rst 0x0000000008009fcc 0x248 ecm_src/lwip-1.4.1/src/core/tcp_out.o + 0x0000000008009fcc tcp_rst + .text.tcp_rexmit_rto + 0x000000000800a214 0x64 ecm_src/lwip-1.4.1/src/core/tcp_out.o + 0x000000000800a214 tcp_rexmit_rto + .text.tcp_rexmit + 0x000000000800a278 0xb8 ecm_src/lwip-1.4.1/src/core/tcp_out.o + 0x000000000800a278 tcp_rexmit + .text.tcp_rexmit_fast + 0x000000000800a330 0xaa ecm_src/lwip-1.4.1/src/core/tcp_out.o + 0x000000000800a330 tcp_rexmit_fast + *fill* 0x000000000800a3da 0x2 + .text.tcp_keepalive + 0x000000000800a3dc 0xb0 ecm_src/lwip-1.4.1/src/core/tcp_out.o + 0x000000000800a3dc tcp_keepalive + .text.tcp_zero_window_probe + 0x000000000800a48c 0x1a0 ecm_src/lwip-1.4.1/src/core/tcp_out.o + 0x000000000800a48c tcp_zero_window_probe + .text.tcpip_tcp_timer + 0x000000000800a62c 0x48 ecm_src/lwip-1.4.1/src/core/timers.o + .text.tcp_timer_needed + 0x000000000800a674 0x44 ecm_src/lwip-1.4.1/src/core/timers.o + 0x000000000800a674 tcp_timer_needed + .text.ip_reass_timer + 0x000000000800a6b8 0x28 ecm_src/lwip-1.4.1/src/core/timers.o + .text.arp_timer + 0x000000000800a6e0 0x28 ecm_src/lwip-1.4.1/src/core/timers.o + .text.sys_timeouts_init + 0x000000000800a708 0x40 ecm_src/lwip-1.4.1/src/core/timers.o + 0x000000000800a708 sys_timeouts_init + .text.sys_timeout + 0x000000000800a748 0xe0 ecm_src/lwip-1.4.1/src/core/timers.o + 0x000000000800a748 sys_timeout + .text.udp_init + 0x000000000800a828 0xa ecm_src/lwip-1.4.1/src/core/udp.o + 0x000000000800a828 udp_init + *fill* 0x000000000800a832 0x2 + .text.udp_new_port + 0x000000000800a834 0x7c ecm_src/lwip-1.4.1/src/core/udp.o + .text.udp_input + 0x000000000800a8b0 0x33c ecm_src/lwip-1.4.1/src/core/udp.o + 0x000000000800a8b0 udp_input + .text.udp_sendto + 0x000000000800abec 0x5c ecm_src/lwip-1.4.1/src/core/udp.o + 0x000000000800abec udp_sendto + .text.udp_sendto_if + 0x000000000800ac48 0x240 ecm_src/lwip-1.4.1/src/core/udp.o + 0x000000000800ac48 udp_sendto_if + .text.udp_bind + 0x000000000800ae88 0xd8 ecm_src/lwip-1.4.1/src/core/udp.o + 0x000000000800ae88 udp_bind + .text.udp_recv + 0x000000000800af60 0x20 ecm_src/lwip-1.4.1/src/core/udp.o + 0x000000000800af60 udp_recv + .text.udp_remove + 0x000000000800af80 0x64 ecm_src/lwip-1.4.1/src/core/udp.o + 0x000000000800af80 udp_remove + .text.udp_new 0x000000000800afe4 0x32 ecm_src/lwip-1.4.1/src/core/udp.o + 0x000000000800afe4 udp_new + *fill* 0x000000000800b016 0x2 + .text.icmp_input + 0x000000000800b018 0x3f4 ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + 0x000000000800b018 icmp_input + .text.icmp_dest_unreach + 0x000000000800b40c 0x24 ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + 0x000000000800b40c icmp_dest_unreach + .text.icmp_time_exceeded + 0x000000000800b430 0x24 ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + 0x000000000800b430 icmp_time_exceeded + .text.icmp_send_response + 0x000000000800b454 0x120 ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .text.lwip_standard_chksum + 0x000000000800b574 0xc6 ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .text.inet_chksum_pseudo + 0x000000000800b63a 0x136 ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + 0x000000000800b63a inet_chksum_pseudo + .text.inet_chksum + 0x000000000800b770 0x2a ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + 0x000000000800b770 inet_chksum + .text.inet_chksum_pbuf + 0x000000000800b79a 0xac ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + 0x000000000800b79a inet_chksum_pbuf + *fill* 0x000000000800b846 0x2 + .text.ip_route + 0x000000000800b848 0x88 ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + 0x000000000800b848 ip_route + .text.ip_input + 0x000000000800b8d0 0x394 ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + 0x000000000800b8d0 ip_input + .text.ip_output_if + 0x000000000800bc64 0x3ac ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + 0x000000000800bc64 ip_output_if + .text.ip_output + 0x000000000800c010 0x6c ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + 0x000000000800c010 ip_output + .text.ip4_addr_isbroadcast + 0x000000000800c07c 0x70 ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o + 0x000000000800c07c ip4_addr_isbroadcast + .text.ip_reass_tmr + 0x000000000800c0ec 0x5c ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + 0x000000000800c0ec ip_reass_tmr + .text.ip_reass_free_complete_datagram + 0x000000000800c148 0x11c ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .text.ip_reass_remove_oldest_datagram + 0x000000000800c264 0xe8 ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .text.ip_reass_enqueue_new_datagram + 0x000000000800c34c 0x90 ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .text.ip_reass_dequeue_datagram + 0x000000000800c3dc 0x3c ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .text.ip_reass_chain_frag_into_datagram_and_validate + 0x000000000800c418 0x3d8 ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .text.ip_reass + 0x000000000800c7f0 0x38c ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + 0x000000000800c7f0 ip_reass + .text.ip_frag_alloc_pbuf_custom_ref + 0x000000000800cb7c 0x12 ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .text.ip_frag_free_pbuf_custom_ref + 0x000000000800cb8e 0x1a ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .text.ipfrag_free_pbuf_custom + 0x000000000800cba8 0x2e ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + *fill* 0x000000000800cbd6 0x2 + .text.ip_frag 0x000000000800cbd8 0x364 ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + 0x000000000800cbd8 ip_frag + .text.etharp_free_entry + 0x000000000800cf3c 0x60 ecm_src/lwip-1.4.1/src/netif/etharp.o + .text.etharp_tmr + 0x000000000800cf9c 0x100 ecm_src/lwip-1.4.1/src/netif/etharp.o + 0x000000000800cf9c etharp_tmr + .text.etharp_find_entry + 0x000000000800d09c 0x2f8 ecm_src/lwip-1.4.1/src/netif/etharp.o + .text.etharp_send_ip + 0x000000000800d394 0x5c ecm_src/lwip-1.4.1/src/netif/etharp.o + .text.etharp_update_arp_entry + 0x000000000800d3f0 0x168 ecm_src/lwip-1.4.1/src/netif/etharp.o + .text.etharp_arp_input + 0x000000000800d558 0x20c ecm_src/lwip-1.4.1/src/netif/etharp.o + .text.etharp_output_to_arp_index + 0x000000000800d764 0xb4 ecm_src/lwip-1.4.1/src/netif/etharp.o + .text.etharp_output + 0x000000000800d818 0x1e0 ecm_src/lwip-1.4.1/src/netif/etharp.o + 0x000000000800d818 etharp_output + .text.etharp_query + 0x000000000800d9f8 0x290 ecm_src/lwip-1.4.1/src/netif/etharp.o + 0x000000000800d9f8 etharp_query + .text.etharp_raw + 0x000000000800dc88 0x16c ecm_src/lwip-1.4.1/src/netif/etharp.o + .text.etharp_request + 0x000000000800ddf4 0x48 ecm_src/lwip-1.4.1/src/netif/etharp.o + 0x000000000800ddf4 etharp_request + .text.ethernet_input + 0x000000000800de3c 0x148 ecm_src/lwip-1.4.1/src/netif/etharp.o + 0x000000000800de3c ethernet_input + .text.usb_ecm_recv_callback + 0x000000000800df84 0x5c ecm_src/src/ecm_main.o + 0x000000000800df84 usb_ecm_recv_callback + .text.sys_now 0x000000000800dfe0 0x10 ecm_src/src/ecm_main.o + 0x000000000800dfe0 sys_now + .text.tcp_timer_proc + 0x000000000800dff0 0x14 ecm_src/src/ecm_main.o + 0x000000000800dff0 tcp_timer_proc + .text.output_fn + 0x000000000800e004 0x22 ecm_src/src/ecm_main.o + 0x000000000800e004 output_fn + .text.linkoutput_fn + 0x000000000800e026 0x44 ecm_src/src/ecm_main.o + 0x000000000800e026 linkoutput_fn + *fill* 0x000000000800e06a 0x2 + .text.netif_init_cb + 0x000000000800e06c 0x4c ecm_src/src/ecm_main.o + 0x000000000800e06c netif_init_cb + .text.init_lwip + 0x000000000800e0b8 0x80 ecm_src/src/ecm_main.o + .text.dns_query_proc + 0x000000000800e138 0x4c ecm_src/src/ecm_main.o + 0x000000000800e138 dns_query_proc + .text.service_traffic + 0x000000000800e184 0x48 ecm_src/src/ecm_main.o + .text.ecm_main_init + 0x000000000800e1cc 0x54 ecm_src/src/ecm_main.o + 0x000000000800e1cc ecm_main_init + .text.ecm_main_loop + 0x000000000800e220 0x12 ecm_src/src/ecm_main.o + 0x000000000800e220 ecm_main_loop + .text.time_init + 0x000000000800e232 0xa ecm_src/src/time.o + 0x000000000800e232 time_init + .text.mtime 0x000000000800e23c 0x10 ecm_src/src/time.o + 0x000000000800e23c mtime + .text.msleep 0x000000000800e24c 0x3c ecm_src/src/time.o + 0x000000000800e24c msleep + .text.stmr 0x000000000800e288 0x6c ecm_src/src/time.o + 0x000000000800e288 stmr + .text.stmr_add + 0x000000000800e2f4 0x24 ecm_src/src/time.o + 0x000000000800e2f4 stmr_add + .text.MX_USB_DEVICE_Init + 0x000000000800e318 0x60 ecm_src/src/usb_device.o + 0x000000000800e318 MX_USB_DEVICE_Init + .text.HAL_PCD_MspInit + 0x000000000800e378 0x8c ecm_src/src/usbd_conf.o + 0x000000000800e378 HAL_PCD_MspInit + .text.HAL_PCD_SetupStageCallback + 0x000000000800e404 0x2a ecm_src/src/usbd_conf.o + 0x000000000800e404 HAL_PCD_SetupStageCallback + .text.HAL_PCD_DataOutStageCallback + 0x000000000800e42e 0x3a ecm_src/src/usbd_conf.o + 0x000000000800e42e HAL_PCD_DataOutStageCallback + .text.HAL_PCD_DataInStageCallback + 0x000000000800e468 0x36 ecm_src/src/usbd_conf.o + 0x000000000800e468 HAL_PCD_DataInStageCallback + .text.HAL_PCD_SOFCallback + 0x000000000800e49e 0x1e ecm_src/src/usbd_conf.o + 0x000000000800e49e HAL_PCD_SOFCallback + .text.HAL_PCD_ResetCallback + 0x000000000800e4bc 0x2e ecm_src/src/usbd_conf.o + 0x000000000800e4bc HAL_PCD_ResetCallback + .text.HAL_PCD_SuspendCallback + 0x000000000800e4ea 0x10 ecm_src/src/usbd_conf.o + 0x000000000800e4ea HAL_PCD_SuspendCallback + .text.HAL_PCD_ResumeCallback + 0x000000000800e4fa 0x10 ecm_src/src/usbd_conf.o + 0x000000000800e4fa HAL_PCD_ResumeCallback + *fill* 0x000000000800e50a 0x2 + .text.USBD_LL_Init + 0x000000000800e50c 0x98 ecm_src/src/usbd_conf.o + 0x000000000800e50c USBD_LL_Init + .text.USBD_LL_Start + 0x000000000800e5a4 0x20 ecm_src/src/usbd_conf.o + 0x000000000800e5a4 USBD_LL_Start + .text.USBD_LL_OpenEP + 0x000000000800e5c4 0x44 ecm_src/src/usbd_conf.o + 0x000000000800e5c4 USBD_LL_OpenEP + .text.USBD_LL_CloseEP + 0x000000000800e608 0x2c ecm_src/src/usbd_conf.o + 0x000000000800e608 USBD_LL_CloseEP + .text.USBD_LL_StallEP + 0x000000000800e634 0x2c ecm_src/src/usbd_conf.o + 0x000000000800e634 USBD_LL_StallEP + .text.USBD_LL_ClearStallEP + 0x000000000800e660 0x2c ecm_src/src/usbd_conf.o + 0x000000000800e660 USBD_LL_ClearStallEP + .text.USBD_LL_IsStallEP + 0x000000000800e68c 0x56 ecm_src/src/usbd_conf.o + 0x000000000800e68c USBD_LL_IsStallEP + .text.USBD_LL_SetUSBAddress + 0x000000000800e6e2 0x2c ecm_src/src/usbd_conf.o + 0x000000000800e6e2 USBD_LL_SetUSBAddress + .text.USBD_LL_Transmit + 0x000000000800e70e 0x52 ecm_src/src/usbd_conf.o + 0x000000000800e70e USBD_LL_Transmit + .text.USBD_LL_PrepareReceive + 0x000000000800e760 0x52 ecm_src/src/usbd_conf.o + 0x000000000800e760 USBD_LL_PrepareReceive + .text.USBD_LL_GetRxDataSize + 0x000000000800e7b2 0x2c ecm_src/src/usbd_conf.o + 0x000000000800e7b2 USBD_LL_GetRxDataSize + .text.USBD_Init + 0x000000000800e7de 0x62 ecm_src/src/usbd_core.o + 0x000000000800e7de USBD_Init + .text.USBD_RegisterClass + 0x000000000800e840 0x42 ecm_src/src/usbd_core.o + 0x000000000800e840 USBD_RegisterClass + .text.USBD_Start + 0x000000000800e882 0x1a ecm_src/src/usbd_core.o + 0x000000000800e882 USBD_Start + .text.USBD_SetClassConfig + 0x000000000800e89c 0x50 ecm_src/src/usbd_core.o + 0x000000000800e89c USBD_SetClassConfig + .text.USBD_ClrClassConfig + 0x000000000800e8ec 0x2c ecm_src/src/usbd_core.o + 0x000000000800e8ec USBD_ClrClassConfig + .text.USBD_LL_SetupStage + 0x000000000800e918 0xb8 ecm_src/src/usbd_core.o + 0x000000000800e918 USBD_LL_SetupStage + .text.USBD_LL_DataOutStage + 0x000000000800e9d0 0xd2 ecm_src/src/usbd_core.o + 0x000000000800e9d0 USBD_LL_DataOutStage + .text.USBD_LL_DataInStage + 0x000000000800eaa2 0x10e ecm_src/src/usbd_core.o + 0x000000000800eaa2 USBD_LL_DataInStage + .text.USBD_LL_Reset + 0x000000000800ebb0 0x66 ecm_src/src/usbd_core.o + 0x000000000800ebb0 USBD_LL_Reset + .text.USBD_LL_SetSpeed + 0x000000000800ec16 0x20 ecm_src/src/usbd_core.o + 0x000000000800ec16 USBD_LL_SetSpeed + .text.USBD_LL_SOF + 0x000000000800ec36 0x3c ecm_src/src/usbd_core.o + 0x000000000800ec36 USBD_LL_SOF + *fill* 0x000000000800ec72 0x2 + .text.USBD_StdDevReq + 0x000000000800ec74 0xa8 ecm_src/src/usbd_ctlreq.o + 0x000000000800ec74 USBD_StdDevReq + .text.USBD_StdItfReq + 0x000000000800ed1c 0x7e ecm_src/src/usbd_ctlreq.o + 0x000000000800ed1c USBD_StdItfReq + .text.USBD_StdEPReq + 0x000000000800ed9a 0x208 ecm_src/src/usbd_ctlreq.o + 0x000000000800ed9a USBD_StdEPReq + .text.USBD_GetDescriptor + 0x000000000800efa2 0x142 ecm_src/src/usbd_ctlreq.o + .text.USBD_SetAddress + 0x000000000800f0e4 0x9c ecm_src/src/usbd_ctlreq.o + .text.USBD_SetConfig + 0x000000000800f180 0x138 ecm_src/src/usbd_ctlreq.o + .text.USBD_GetConfig + 0x000000000800f2b8 0x70 ecm_src/src/usbd_ctlreq.o + .text.USBD_GetStatus + 0x000000000800f328 0x5e ecm_src/src/usbd_ctlreq.o + .text.USBD_SetFeature + 0x000000000800f386 0x3e ecm_src/src/usbd_ctlreq.o + .text.USBD_ClrFeature + 0x000000000800f3c4 0x5e ecm_src/src/usbd_ctlreq.o + .text.USBD_ParseSetupRequest + 0x000000000800f422 0x76 ecm_src/src/usbd_ctlreq.o + 0x000000000800f422 USBD_ParseSetupRequest + .text.USBD_CtlError + 0x000000000800f498 0x26 ecm_src/src/usbd_ctlreq.o + 0x000000000800f498 USBD_CtlError + .text.USBD_GetString + 0x000000000800f4be 0xa0 ecm_src/src/usbd_ctlreq.o + 0x000000000800f4be USBD_GetString + .text.USBD_GetLen + 0x000000000800f55e 0x3a ecm_src/src/usbd_ctlreq.o + .text.USBD_VCP_DeviceDescriptor + 0x000000000800f598 0x24 ecm_src/src/usbd_desc.o + .text.USBD_VCP_LangIDStrDescriptor + 0x000000000800f5bc 0x24 ecm_src/src/usbd_desc.o + .text.USBD_VCP_ProductStrDescriptor + 0x000000000800f5e0 0x2c ecm_src/src/usbd_desc.o + .text.USBD_VCP_ManufacturerStrDescriptor + 0x000000000800f60c 0x2c ecm_src/src/usbd_desc.o + .text.USBD_VCP_SerialStrDescriptor + 0x000000000800f638 0x5c ecm_src/src/usbd_desc.o + .text.IntToUnicode + 0x000000000800f694 0x94 ecm_src/src/usbd_desc.o + .text.usb_ecm_recv_renew + 0x000000000800f728 0x48 ecm_src/src/usbd_ecm.o + 0x000000000800f728 usb_ecm_recv_renew + .text.USBD_ECM_Init + 0x000000000800f770 0x74 ecm_src/src/usbd_ecm.o + .text.USBD_ECM_DeInit + 0x000000000800f7e4 0x4c ecm_src/src/usbd_ecm.o + .text.USBD_ECM_Setup + 0x000000000800f830 0x34 ecm_src/src/usbd_ecm.o + .text.ecm_incoming_attempt + 0x000000000800f864 0x70 ecm_src/src/usbd_ecm.o + .text.USBD_ECM_DataIn + 0x000000000800f8d4 0x4c ecm_src/src/usbd_ecm.o + .text.USBD_ECM_DataOut + 0x000000000800f920 0x70 ecm_src/src/usbd_ecm.o + .text.USBD_ECM_SOF + 0x000000000800f990 0x60 ecm_src/src/usbd_ecm.o + .text.USBD_ECM_EP0_RxReady + 0x000000000800f9f0 0x12 ecm_src/src/usbd_ecm.o + *fill* 0x000000000800fa02 0x2 + .text.USBD_ECM_GetFSCfgDesc + 0x000000000800fa04 0x24 ecm_src/src/usbd_ecm.o + .text.USBD_ECM_RegisterInterface + 0x000000000800fa28 0x12 ecm_src/src/usbd_ecm.o + 0x000000000800fa28 USBD_ECM_RegisterInterface + .text.USBD_ECM_PMAConfig + 0x000000000800fa3a 0x60 ecm_src/src/usbd_ecm.o + 0x000000000800fa3a USBD_ECM_PMAConfig + *fill* 0x000000000800fa9a 0x2 + .text.usb_ecm_can_xmit + 0x000000000800fa9c 0x24 ecm_src/src/usbd_ecm.o + 0x000000000800fa9c usb_ecm_can_xmit + .text.usb_ecm_xmit_packet + 0x000000000800fac0 0xa0 ecm_src/src/usbd_ecm.o + 0x000000000800fac0 usb_ecm_xmit_packet + .text.USBD_CtlSendData + 0x000000000800fb60 0x40 ecm_src/src/usbd_ioreq.o + 0x000000000800fb60 USBD_CtlSendData + .text.USBD_CtlContinueSendData + 0x000000000800fba0 0x26 ecm_src/src/usbd_ioreq.o + 0x000000000800fba0 USBD_CtlContinueSendData + .text.USBD_CtlContinueRx + 0x000000000800fbc6 0x26 ecm_src/src/usbd_ioreq.o + 0x000000000800fbc6 USBD_CtlContinueRx + .text.USBD_CtlSendStatus + 0x000000000800fbec 0x28 ecm_src/src/usbd_ioreq.o + 0x000000000800fbec USBD_CtlSendStatus + .text.USBD_CtlReceiveStatus + 0x000000000800fc14 0x28 ecm_src/src/usbd_ioreq.o + 0x000000000800fc14 USBD_CtlReceiveStatus + .text.__libc_init_array + 0x000000000800fc3c 0x48 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-init.o) + 0x000000000800fc3c __libc_init_array + .text.memcmp 0x000000000800fc84 0x1e c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-memcmp.o) + 0x000000000800fc84 memcmp + .text.memcpy 0x000000000800fca2 0x12 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-memcpy-stub.o) + 0x000000000800fca2 memcpy + .text.memset 0x000000000800fcb4 0x10 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-memset.o) + 0x000000000800fcb4 memset + *(.glue_7) + .glue_7 0x000000000800fcc4 0x0 linker stubs + *(.glue_7t) + .glue_7t 0x000000000800fcc4 0x0 linker stubs + *(.eh_frame) + .eh_frame 0x000000000800fcc4 0x0 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v6-m/crtbegin.o + *(.init) + .init 0x000000000800fcc4 0x4 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v6-m/crti.o + 0x000000000800fcc4 _init + .init 0x000000000800fcc8 0x8 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v6-m/crtn.o + *(.fini) + .fini 0x000000000800fcd0 0x4 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v6-m/crti.o + 0x000000000800fcd0 _fini + .fini 0x000000000800fcd4 0x8 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v6-m/crtn.o + 0x000000000800fcdc . = ALIGN (0x4) + 0x000000000800fcdc _etext = . + +.vfp11_veneer 0x000000000800fcdc 0x0 + .vfp11_veneer 0x000000000800fcdc 0x0 linker stubs + +.v4_bx 0x000000000800fcdc 0x0 + .v4_bx 0x000000000800fcdc 0x0 linker stubs + +.iplt 0x000000000800fcdc 0x0 + .iplt 0x000000000800fcdc 0x0 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v6-m/crtbegin.o + +.rodata 0x000000000800fcdc 0x1cc + 0x000000000800fcdc . = ALIGN (0x4) + *(.rodata) + .rodata 0x000000000800fcdc 0x20 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .rodata 0x000000000800fcfc 0x6 ecm_src/dhcp-server/dhserver.o + *fill* 0x000000000800fd02 0x2 + .rodata 0x000000000800fd04 0x18 ecm_src/src/ecm_main.o + .rodata 0x000000000800fd1c 0x9 ecm_src/src/usbd_desc.o + *(.rodata*) + *fill* 0x000000000800fd25 0x3 + .rodata.AHBPrescTable + 0x000000000800fd28 0x10 Core/Src/system_stm32f0xx.o + 0x000000000800fd28 AHBPrescTable + .rodata.memp_sizes + 0x000000000800fd38 0x14 ecm_src/lwip-1.4.1/src/core/memp.o + .rodata.memp_num + 0x000000000800fd4c 0x14 ecm_src/lwip-1.4.1/src/core/memp.o + .rodata.tcp_backoff + 0x000000000800fd60 0xd ecm_src/lwip-1.4.1/src/core/tcp.o + 0x000000000800fd60 tcp_backoff + *fill* 0x000000000800fd6d 0x3 + .rodata.tcp_persist_backoff + 0x000000000800fd70 0x7 ecm_src/lwip-1.4.1/src/core/tcp.o + 0x000000000800fd70 tcp_persist_backoff + *fill* 0x000000000800fd77 0x1 + .rodata.tcp_close_shutdown + 0x000000000800fd78 0x20 ecm_src/lwip-1.4.1/src/core/tcp.o + .rodata.tcp_process + 0x000000000800fd98 0x28 ecm_src/lwip-1.4.1/src/core/tcp_in.o + .rodata.ip_addr_any + 0x000000000800fdc0 0x4 ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o + 0x000000000800fdc0 ip_addr_any + .rodata.ip_addr_broadcast + 0x000000000800fdc4 0x4 ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o + 0x000000000800fdc4 ip_addr_broadcast + .rodata.ethbroadcast + 0x000000000800fdc8 0x6 ecm_src/lwip-1.4.1/src/netif/etharp.o + 0x000000000800fdc8 ethbroadcast + *fill* 0x000000000800fdce 0x2 + .rodata.ethzero + 0x000000000800fdd0 0x6 ecm_src/lwip-1.4.1/src/netif/etharp.o + 0x000000000800fdd0 ethzero + *fill* 0x000000000800fdd6 0x2 + .rodata.USBD_StdDevReq + 0x000000000800fdd8 0x28 ecm_src/src/usbd_ctlreq.o + .rodata.VCP_Desc + 0x000000000800fe00 0x14 ecm_src/src/usbd_desc.o + 0x000000000800fe00 VCP_Desc + .rodata.hUSBDDeviceDesc + 0x000000000800fe14 0x12 ecm_src/src/usbd_desc.o + *fill* 0x000000000800fe26 0x2 + .rodata.USBD_ECM_CfgFSDesc + 0x000000000800fe28 0x47 ecm_src/src/usbd_desc.o + *fill* 0x000000000800fe6f 0x1 + .rodata.USBD_CfgFSDesc_pnt + 0x000000000800fe70 0x4 ecm_src/src/usbd_desc.o + 0x000000000800fe70 USBD_CfgFSDesc_pnt + .rodata.USBD_CfgFSDesc_len + 0x000000000800fe74 0x2 ecm_src/src/usbd_desc.o + 0x000000000800fe74 USBD_CfgFSDesc_len + *fill* 0x000000000800fe76 0x2 + .rodata.USBD_LangIDDesc + 0x000000000800fe78 0x4 ecm_src/src/usbd_desc.o + .rodata.USBD_ECM + 0x000000000800fe7c 0x2c ecm_src/src/usbd_ecm.o + 0x000000000800fe7c USBD_ECM + 0x000000000800fea8 . = ALIGN (0x4) + +.rel.dyn 0x000000000800fea8 0x0 + .rel.iplt 0x000000000800fea8 0x0 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v6-m/crtbegin.o + +.ARM.extab 0x000000000800fea8 0x0 + 0x000000000800fea8 . = ALIGN (0x4) + *(.ARM.extab* .gnu.linkonce.armextab.*) + 0x000000000800fea8 . = ALIGN (0x4) + +.ARM 0x000000000800fea8 0x0 + 0x000000000800fea8 . = ALIGN (0x4) + 0x000000000800fea8 __exidx_start = . + *(.ARM.exidx*) + 0x000000000800fea8 __exidx_end = . + 0x000000000800fea8 . = ALIGN (0x4) + +.preinit_array 0x000000000800fea8 0x0 + 0x000000000800fea8 . = ALIGN (0x4) + 0x000000000800fea8 PROVIDE (__preinit_array_start = .) + *(.preinit_array*) + 0x000000000800fea8 PROVIDE (__preinit_array_end = .) + 0x000000000800fea8 . = ALIGN (0x4) + +.init_array 0x000000000800fea8 0x4 + 0x000000000800fea8 . = ALIGN (0x4) + 0x000000000800fea8 PROVIDE (__init_array_start = .) + *(SORT_BY_NAME(.init_array.*)) + *(.init_array*) + .init_array 0x000000000800fea8 0x4 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v6-m/crtbegin.o + 0x000000000800feac PROVIDE (__init_array_end = .) + 0x000000000800feac . = ALIGN (0x4) + +.fini_array 0x000000000800feac 0x4 + 0x000000000800feac . = ALIGN (0x4) + [!provide] PROVIDE (__fini_array_start = .) + *(SORT_BY_NAME(.fini_array.*)) + *(.fini_array*) + .fini_array 0x000000000800feac 0x4 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v6-m/crtbegin.o + [!provide] PROVIDE (__fini_array_end = .) + 0x000000000800feb0 . = ALIGN (0x4) + 0x000000000800feb0 _sidata = LOADADDR (.data) + +.data 0x0000000020000000 0x9c load address 0x000000000800feb0 + 0x0000000020000000 . = ALIGN (0x4) + 0x0000000020000000 _sdata = . + *(.data) + *(.data*) + .data.SystemCoreClock + 0x0000000020000000 0x4 Core/Src/system_stm32f0xx.o + 0x0000000020000000 SystemCoreClock + .data.uwTickPrio + 0x0000000020000004 0x4 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + 0x0000000020000004 uwTickPrio + .data.uwTickFreq + 0x0000000020000008 0x1 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + 0x0000000020000008 uwTickFreq + *fill* 0x0000000020000009 0x3 + .data.magic_cookie + 0x000000002000000c 0x4 ecm_src/dhcp-server/dhserver.o + 0x000000002000000c magic_cookie + .data.iss.5439 + 0x0000000020000010 0x4 ecm_src/lwip-1.4.1/src/core/tcp.o + .data.udp_port + 0x0000000020000014 0x2 ecm_src/lwip-1.4.1/src/core/udp.o + *fill* 0x0000000020000016 0x2 + .data.hwaddr 0x0000000020000018 0x6 ecm_src/src/ecm_main.o + *fill* 0x000000002000001e 0x2 + .data.ipaddr 0x0000000020000020 0x4 ecm_src/src/ecm_main.o + .data.netmask 0x0000000020000024 0x4 ecm_src/src/ecm_main.o + .data.entries 0x0000000020000028 0x3c ecm_src/src/ecm_main.o + .data.dhcp_config + 0x0000000020000064 0x18 ecm_src/src/ecm_main.o + .data.tcp_timer + 0x000000002000007c 0x18 ecm_src/src/ecm_main.o + .data.notify 0x0000000020000094 0x8 ecm_src/src/usbd_ecm.o + 0x000000002000009c . = ALIGN (0x4) + 0x000000002000009c _edata = . + +.igot.plt 0x000000002000009c 0x0 load address 0x000000000800ff4c + .igot.plt 0x000000002000009c 0x0 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v6-m/crtbegin.o + 0x000000002000009c . = ALIGN (0x4) + +.bss 0x000000002000009c 0x369c load address 0x000000000800ff4c + 0x000000002000009c _sbss = . + 0x000000002000009c __bss_start__ = _sbss + *(.bss) + .bss 0x000000002000009c 0x1c c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v6-m/crtbegin.o + *(.bss*) + .bss.pcb 0x00000000200000b8 0x4 ecm_src/dhcp-server/dhserver.o + .bss.config 0x00000000200000bc 0x4 ecm_src/dhcp-server/dhserver.o + .bss.pcb 0x00000000200000c0 0x4 ecm_src/dns-server/dnserver.o + .bss.query_proc + 0x00000000200000c4 0x4 ecm_src/dns-server/dnserver.o + 0x00000000200000c4 query_proc + .bss.query.5774 + 0x00000000200000c8 0x84 ecm_src/dns-server/dnserver.o + .bss.ram 0x000000002000014c 0x4 ecm_src/lwip-1.4.1/src/core/mem.o + .bss.ram_end 0x0000000020000150 0x4 ecm_src/lwip-1.4.1/src/core/mem.o + .bss.lfree 0x0000000020000154 0x4 ecm_src/lwip-1.4.1/src/core/mem.o + .bss.memp_tab 0x0000000020000158 0x28 ecm_src/lwip-1.4.1/src/core/memp.o + .bss.memp_memory + 0x0000000020000180 0x20f3 ecm_src/lwip-1.4.1/src/core/memp.o + .bss.netif_num + 0x0000000020002273 0x1 ecm_src/lwip-1.4.1/src/core/netif.o + .bss.raw_pcbs 0x0000000020002274 0x4 ecm_src/lwip-1.4.1/src/core/raw.o + .bss.tcp_timer + 0x0000000020002278 0x1 ecm_src/lwip-1.4.1/src/core/tcp.o + .bss.tcp_timer_ctr + 0x0000000020002279 0x1 ecm_src/lwip-1.4.1/src/core/tcp.o + *fill* 0x000000002000227a 0x2 + .bss.inseg 0x000000002000227c 0x10 ecm_src/lwip-1.4.1/src/core/tcp_in.o + .bss.tcphdr 0x000000002000228c 0x4 ecm_src/lwip-1.4.1/src/core/tcp_in.o + .bss.iphdr 0x0000000020002290 0x4 ecm_src/lwip-1.4.1/src/core/tcp_in.o + .bss.seqno 0x0000000020002294 0x4 ecm_src/lwip-1.4.1/src/core/tcp_in.o + .bss.ackno 0x0000000020002298 0x4 ecm_src/lwip-1.4.1/src/core/tcp_in.o + .bss.flags 0x000000002000229c 0x1 ecm_src/lwip-1.4.1/src/core/tcp_in.o + *fill* 0x000000002000229d 0x1 + .bss.tcplen 0x000000002000229e 0x2 ecm_src/lwip-1.4.1/src/core/tcp_in.o + .bss.recv_flags + 0x00000000200022a0 0x1 ecm_src/lwip-1.4.1/src/core/tcp_in.o + *fill* 0x00000000200022a1 0x3 + .bss.recv_data + 0x00000000200022a4 0x4 ecm_src/lwip-1.4.1/src/core/tcp_in.o + .bss.next_timeout + 0x00000000200022a8 0x4 ecm_src/lwip-1.4.1/src/core/timers.o + .bss.timeouts_last_time + 0x00000000200022ac 0x4 ecm_src/lwip-1.4.1/src/core/timers.o + .bss.tcpip_tcp_timer_active + 0x00000000200022b0 0x4 ecm_src/lwip-1.4.1/src/core/timers.o + .bss.ip_id 0x00000000200022b4 0x2 ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + *fill* 0x00000000200022b6 0x2 + .bss.reassdatagrams + 0x00000000200022b8 0x4 ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .bss.ip_reass_pbufcount + 0x00000000200022bc 0x2 ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + *fill* 0x00000000200022be 0x2 + .bss.arp_table + 0x00000000200022c0 0xc8 ecm_src/lwip-1.4.1/src/netif/etharp.o + .bss.etharp_cached_entry + 0x0000000020002388 0x1 ecm_src/lwip-1.4.1/src/netif/etharp.o + *fill* 0x0000000020002389 0x3 + .bss.netif_data + 0x000000002000238c 0x30 ecm_src/src/ecm_main.o + .bss.gateway 0x00000000200023bc 0x4 ecm_src/src/ecm_main.o + .bss.received_frame + 0x00000000200023c0 0x4 ecm_src/src/ecm_main.o + .bss.stmrs 0x00000000200023c4 0x4 ecm_src/src/time.o + .bss.cfgidx.7723 + 0x00000000200023c8 0x1 ecm_src/src/usbd_ctlreq.o + *fill* 0x00000000200023c9 0x3 + .bss.USBD_StrDesc + 0x00000000200023cc 0x100 ecm_src/src/usbd_desc.o + .bss.registered_pdev + 0x00000000200024cc 0x4 ecm_src/src/usbd_ecm.o + .bss.ecm_rx_buffer + 0x00000000200024d0 0x202 ecm_src/src/usbd_ecm.o + *fill* 0x00000000200026d2 0x2 + .bss.ecm_tx_buffer + 0x00000000200026d4 0x202 ecm_src/src/usbd_ecm.o + *fill* 0x00000000200028d6 0x2 + .bss.ecm_rx_index + 0x00000000200028d8 0x4 ecm_src/src/usbd_ecm.o + .bss.can_xmit 0x00000000200028dc 0x1 ecm_src/src/usbd_ecm.o + .bss.OutboundTransferNeedsRenewal + 0x00000000200028dd 0x1 ecm_src/src/usbd_ecm.o + *fill* 0x00000000200028de 0x2 + .bss.ecm_tx_ptr + 0x00000000200028e0 0x4 ecm_src/src/usbd_ecm.o + .bss.ecm_tx_remaining + 0x00000000200028e4 0x4 ecm_src/src/usbd_ecm.o + .bss.ecm_tx_busy + 0x00000000200028e8 0x4 ecm_src/src/usbd_ecm.o + .bss.copy_length + 0x00000000200028ec 0x4 ecm_src/src/usbd_ecm.o + *(COMMON) + COMMON 0x00000000200028f0 0x4 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + 0x00000000200028f0 uwTick + COMMON 0x00000000200028f4 0x204 ecm_src/dhcp-server/dhserver.o + 0x00000000200028f4 dhcp_data + COMMON 0x0000000020002af8 0x654 ecm_src/lwip-1.4.1/src/core/mem.o + 0x0000000020002af8 ram_heap + COMMON 0x000000002000314c 0x8 ecm_src/lwip-1.4.1/src/core/netif.o + 0x000000002000314c netif_list + 0x0000000020003150 netif_default + COMMON 0x0000000020003154 0x1 ecm_src/lwip-1.4.1/src/core/pbuf.o + 0x0000000020003154 pbuf_free_ooseq_pending + *fill* 0x0000000020003155 0x3 + COMMON 0x0000000020003158 0x116 ecm_src/lwip-1.4.1/src/core/stats.o + 0x0000000020003158 lwip_stats + *fill* 0x000000002000326e 0x2 + COMMON 0x0000000020003270 0x1c ecm_src/lwip-1.4.1/src/core/tcp.o + 0x0000000020003270 tcp_active_pcbs_changed + 0x0000000020003274 tcp_active_pcbs + 0x0000000020003278 tcp_ticks + 0x000000002000327c tcp_listen_pcbs + 0x0000000020003280 tcp_tmp_pcb + 0x0000000020003284 tcp_bound_pcbs + 0x0000000020003288 tcp_tw_pcbs + COMMON 0x000000002000328c 0x4 ecm_src/lwip-1.4.1/src/core/tcp_in.o + 0x000000002000328c tcp_input_pcb + COMMON 0x0000000020003290 0x4 ecm_src/lwip-1.4.1/src/core/udp.o + 0x0000000020003290 udp_pcbs + COMMON 0x0000000020003294 0x10 ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + 0x0000000020003294 current_iphdr_src + 0x0000000020003298 current_netif + 0x000000002000329c current_iphdr_dest + 0x00000000200032a0 current_header + COMMON 0x00000000200032a4 0x220 ecm_src/src/usb_device.o + 0x00000000200032a4 hUsbDeviceFS + COMMON 0x00000000200034c4 0x274 ecm_src/src/usbd_conf.o + 0x00000000200034c4 hpcd_USB_FS + 0x0000000020003738 . = ALIGN (0x4) + 0x0000000020003738 _ebss = . + 0x0000000020003738 __bss_end__ = _ebss + +._user_heap_stack + 0x0000000020003738 0x600 load address 0x000000000800ff4c + 0x0000000020003738 . = ALIGN (0x8) + 0x0000000020003738 PROVIDE (end = .) + [!provide] PROVIDE (_end = .) + 0x0000000020003938 . = (. + _Min_Heap_Size) + *fill* 0x0000000020003738 0x200 + 0x0000000020003d38 . = (. + _Min_Stack_Size) + *fill* 0x0000000020003938 0x400 + 0x0000000020003d38 . = ALIGN (0x8) + +/DISCARD/ + libc.a(*) + libm.a(*) + libgcc.a(*) + +.ARM.attributes + 0x0000000000000000 0x28 + *(.ARM.attributes) + .ARM.attributes + 0x0000000000000000 0x1e c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v6-m/crti.o + .ARM.attributes + 0x000000000000001e 0x2c c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v6-m/crtbegin.o + .ARM.attributes + 0x000000000000004a 0x31 Core/Src/main.o + .ARM.attributes + 0x000000000000007b 0x31 Core/Src/stm32f0xx_hal_msp.o + .ARM.attributes + 0x00000000000000ac 0x31 Core/Src/stm32f0xx_it.o + .ARM.attributes + 0x00000000000000dd 0x31 Core/Src/system_stm32f0xx.o + .ARM.attributes + 0x000000000000010e 0x21 Core/Startup/startup_stm32f072c8tx.o + .ARM.attributes + 0x000000000000012f 0x31 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .ARM.attributes + 0x0000000000000160 0x31 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .ARM.attributes + 0x0000000000000191 0x31 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .ARM.attributes + 0x00000000000001c2 0x31 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .ARM.attributes + 0x00000000000001f3 0x31 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .ARM.attributes + 0x0000000000000224 0x31 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .ARM.attributes + 0x0000000000000255 0x31 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .ARM.attributes + 0x0000000000000286 0x31 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .ARM.attributes + 0x00000000000002b7 0x31 ecm_src/dhcp-server/dhserver.o + .ARM.attributes + 0x00000000000002e8 0x31 ecm_src/dns-server/dnserver.o + .ARM.attributes + 0x0000000000000319 0x31 ecm_src/lwip-1.4.1/src/core/def.o + .ARM.attributes + 0x000000000000034a 0x31 ecm_src/lwip-1.4.1/src/core/init.o + .ARM.attributes + 0x000000000000037b 0x31 ecm_src/lwip-1.4.1/src/core/mem.o + .ARM.attributes + 0x00000000000003ac 0x31 ecm_src/lwip-1.4.1/src/core/memp.o + .ARM.attributes + 0x00000000000003dd 0x31 ecm_src/lwip-1.4.1/src/core/netif.o + .ARM.attributes + 0x000000000000040e 0x31 ecm_src/lwip-1.4.1/src/core/pbuf.o + .ARM.attributes + 0x000000000000043f 0x31 ecm_src/lwip-1.4.1/src/core/raw.o + .ARM.attributes + 0x0000000000000470 0x31 ecm_src/lwip-1.4.1/src/core/stats.o + .ARM.attributes + 0x00000000000004a1 0x31 ecm_src/lwip-1.4.1/src/core/tcp.o + .ARM.attributes + 0x00000000000004d2 0x31 ecm_src/lwip-1.4.1/src/core/tcp_in.o + .ARM.attributes + 0x0000000000000503 0x31 ecm_src/lwip-1.4.1/src/core/tcp_out.o + .ARM.attributes + 0x0000000000000534 0x31 ecm_src/lwip-1.4.1/src/core/timers.o + .ARM.attributes + 0x0000000000000565 0x31 ecm_src/lwip-1.4.1/src/core/udp.o + .ARM.attributes + 0x0000000000000596 0x31 ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .ARM.attributes + 0x00000000000005c7 0x31 ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .ARM.attributes + 0x00000000000005f8 0x31 ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .ARM.attributes + 0x0000000000000629 0x31 ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o + .ARM.attributes + 0x000000000000065a 0x31 ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .ARM.attributes + 0x000000000000068b 0x31 ecm_src/lwip-1.4.1/src/netif/etharp.o + .ARM.attributes + 0x00000000000006bc 0x31 ecm_src/src/ecm_main.o + .ARM.attributes + 0x00000000000006ed 0x31 ecm_src/src/time.o + .ARM.attributes + 0x000000000000071e 0x31 ecm_src/src/usb_device.o + .ARM.attributes + 0x000000000000074f 0x31 ecm_src/src/usbd_conf.o + .ARM.attributes + 0x0000000000000780 0x31 ecm_src/src/usbd_core.o + .ARM.attributes + 0x00000000000007b1 0x31 ecm_src/src/usbd_ctlreq.o + .ARM.attributes + 0x00000000000007e2 0x31 ecm_src/src/usbd_desc.o + .ARM.attributes + 0x0000000000000813 0x31 ecm_src/src/usbd_ecm.o + .ARM.attributes + 0x0000000000000844 0x31 ecm_src/src/usbd_ioreq.o + .ARM.attributes + 0x0000000000000875 0x2c c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-init.o) + .ARM.attributes + 0x00000000000008a1 0x2c c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-memcmp.o) + .ARM.attributes + 0x00000000000008cd 0x2c c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-memcpy-stub.o) + .ARM.attributes + 0x00000000000008f9 0x2c c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-memset.o) + .ARM.attributes + 0x0000000000000925 0x1c c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-strcmp.o) + .ARM.attributes + 0x0000000000000941 0x1c c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-strlen.o) + .ARM.attributes + 0x000000000000095d 0x1e c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v6-m\libgcc.a(_udivsi3.o) + .ARM.attributes + 0x000000000000097b 0x1e c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v6-m\libgcc.a(_divsi3.o) + .ARM.attributes + 0x0000000000000999 0x1e c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v6-m\libgcc.a(_dvmd_tls.o) + .ARM.attributes + 0x00000000000009b7 0x1e c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v6-m/crtn.o +OUTPUT(stm32f072_ecm.elf elf32-littlearm) + +.debug_info 0x0000000000000000 0x29068 + .debug_info 0x0000000000000000 0x1a5b Core/Src/main.o + .debug_info 0x0000000000001a5b 0x25e Core/Src/stm32f0xx_hal_msp.o + .debug_info 0x0000000000001cb9 0x667 Core/Src/stm32f0xx_it.o + .debug_info 0x0000000000002320 0x29e Core/Src/system_stm32f0xx.o + .debug_info 0x00000000000025be 0x22 Core/Startup/startup_stm32f072c8tx.o + .debug_info 0x00000000000025e0 0x6c0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .debug_info 0x0000000000002ca0 0x78c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .debug_info 0x000000000000342c 0x67a Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .debug_info 0x0000000000003aa6 0xe67 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .debug_info 0x000000000000490d 0x880 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .debug_info 0x000000000000518d 0x82d Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .debug_info 0x00000000000059ba 0x677 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .debug_info 0x0000000000006031 0x1508 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .debug_info 0x0000000000007539 0x1397 ecm_src/dhcp-server/dhserver.o + .debug_info 0x00000000000088d0 0x1119 ecm_src/dns-server/dnserver.o + .debug_info 0x00000000000099e9 0xfe ecm_src/lwip-1.4.1/src/core/def.o + .debug_info 0x0000000000009ae7 0xc11 ecm_src/lwip-1.4.1/src/core/init.o + .debug_info 0x000000000000a6f8 0xd14 ecm_src/lwip-1.4.1/src/core/mem.o + .debug_info 0x000000000000b40c 0x15e1 ecm_src/lwip-1.4.1/src/core/memp.o + .debug_info 0x000000000000c9ed 0xebb ecm_src/lwip-1.4.1/src/core/netif.o + .debug_info 0x000000000000d8a8 0x1b6d ecm_src/lwip-1.4.1/src/core/pbuf.o + .debug_info 0x000000000000f415 0x10f3 ecm_src/lwip-1.4.1/src/core/raw.o + .debug_info 0x0000000000010508 0xa86 ecm_src/lwip-1.4.1/src/core/stats.o + .debug_info 0x0000000000010f8e 0x1e9c ecm_src/lwip-1.4.1/src/core/tcp.o + .debug_info 0x0000000000012e2a 0xf0b ecm_src/lwip-1.4.1/src/core/tcp_in.o + .debug_info 0x0000000000013d35 0x1b8e ecm_src/lwip-1.4.1/src/core/tcp_out.o + .debug_info 0x00000000000158c3 0xc58 ecm_src/lwip-1.4.1/src/core/timers.o + .debug_info 0x000000000001651b 0x1355 ecm_src/lwip-1.4.1/src/core/udp.o + .debug_info 0x0000000000017870 0xfe5 ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .debug_info 0x0000000000018855 0xbdb ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .debug_info 0x0000000000019430 0x1738 ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .debug_info 0x000000000001ab68 0x565 ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o + .debug_info 0x000000000001b0cd 0x1404 ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .debug_info 0x000000000001c4d1 0x1688 ecm_src/lwip-1.4.1/src/netif/etharp.o + .debug_info 0x000000000001db59 0x1b7d ecm_src/src/ecm_main.o + .debug_info 0x000000000001f6d6 0x382 ecm_src/src/time.o + .debug_info 0x000000000001fa58 0x1797 ecm_src/src/usb_device.o + .debug_info 0x00000000000211ef 0x1e14 ecm_src/src/usbd_conf.o + .debug_info 0x0000000000023003 0x1138 ecm_src/src/usbd_core.o + .debug_info 0x000000000002413b 0x10c4 ecm_src/src/usbd_ctlreq.o + .debug_info 0x00000000000251ff 0x1640 ecm_src/src/usbd_desc.o + .debug_info 0x000000000002683f 0x1965 ecm_src/src/usbd_ecm.o + .debug_info 0x00000000000281a4 0xec4 ecm_src/src/usbd_ioreq.o + +.debug_abbrev 0x0000000000000000 0x5bb1 + .debug_abbrev 0x0000000000000000 0x235 Core/Src/main.o + .debug_abbrev 0x0000000000000235 0x109 Core/Src/stm32f0xx_hal_msp.o + .debug_abbrev 0x000000000000033e 0x155 Core/Src/stm32f0xx_it.o + .debug_abbrev 0x0000000000000493 0x12b Core/Src/system_stm32f0xx.o + .debug_abbrev 0x00000000000005be 0x12 Core/Startup/startup_stm32f072c8tx.o + .debug_abbrev 0x00000000000005d0 0x1c7 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .debug_abbrev 0x0000000000000797 0x273 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .debug_abbrev 0x0000000000000a0a 0x1c0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .debug_abbrev 0x0000000000000bca 0x27d Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .debug_abbrev 0x0000000000000e47 0x1eb Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .debug_abbrev 0x0000000000001032 0x20f Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .debug_abbrev 0x0000000000001241 0x1a7 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .debug_abbrev 0x00000000000013e8 0x239 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .debug_abbrev 0x0000000000001621 0x2d0 ecm_src/dhcp-server/dhserver.o + .debug_abbrev 0x00000000000018f1 0x26e ecm_src/dns-server/dnserver.o + .debug_abbrev 0x0000000000001b5f 0x90 ecm_src/lwip-1.4.1/src/core/def.o + .debug_abbrev 0x0000000000001bef 0x155 ecm_src/lwip-1.4.1/src/core/init.o + .debug_abbrev 0x0000000000001d44 0x284 ecm_src/lwip-1.4.1/src/core/mem.o + .debug_abbrev 0x0000000000001fc8 0x24e ecm_src/lwip-1.4.1/src/core/memp.o + .debug_abbrev 0x0000000000002216 0x272 ecm_src/lwip-1.4.1/src/core/netif.o + .debug_abbrev 0x0000000000002488 0x2e6 ecm_src/lwip-1.4.1/src/core/pbuf.o + .debug_abbrev 0x000000000000276e 0x27d ecm_src/lwip-1.4.1/src/core/raw.o + .debug_abbrev 0x00000000000029eb 0x19b ecm_src/lwip-1.4.1/src/core/stats.o + .debug_abbrev 0x0000000000002b86 0x365 ecm_src/lwip-1.4.1/src/core/tcp.o + .debug_abbrev 0x0000000000002eeb 0x23a ecm_src/lwip-1.4.1/src/core/tcp_in.o + .debug_abbrev 0x0000000000003125 0x305 ecm_src/lwip-1.4.1/src/core/tcp_out.o + .debug_abbrev 0x000000000000342a 0x225 ecm_src/lwip-1.4.1/src/core/timers.o + .debug_abbrev 0x000000000000364f 0x2c5 ecm_src/lwip-1.4.1/src/core/udp.o + .debug_abbrev 0x0000000000003914 0x26d ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .debug_abbrev 0x0000000000003b81 0x202 ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .debug_abbrev 0x0000000000003d83 0x24e ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .debug_abbrev 0x0000000000003fd1 0x193 ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o + .debug_abbrev 0x0000000000004164 0x2b6 ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .debug_abbrev 0x000000000000441a 0x2b4 ecm_src/lwip-1.4.1/src/netif/etharp.o + .debug_abbrev 0x00000000000046ce 0x2c1 ecm_src/src/ecm_main.o + .debug_abbrev 0x000000000000498f 0x188 ecm_src/src/time.o + .debug_abbrev 0x0000000000004b17 0x1d5 ecm_src/src/usb_device.o + .debug_abbrev 0x0000000000004cec 0x2bb ecm_src/src/usbd_conf.o + .debug_abbrev 0x0000000000004fa7 0x261 ecm_src/src/usbd_core.o + .debug_abbrev 0x0000000000005208 0x291 ecm_src/src/usbd_ctlreq.o + .debug_abbrev 0x0000000000005499 0x23c ecm_src/src/usbd_desc.o + .debug_abbrev 0x00000000000056d5 0x30b ecm_src/src/usbd_ecm.o + .debug_abbrev 0x00000000000059e0 0x1d1 ecm_src/src/usbd_ioreq.o + +.debug_aranges 0x0000000000000000 0x12c8 + .debug_aranges + 0x0000000000000000 0x38 Core/Src/main.o + .debug_aranges + 0x0000000000000038 0x20 Core/Src/stm32f0xx_hal_msp.o + .debug_aranges + 0x0000000000000058 0x48 Core/Src/stm32f0xx_it.o + .debug_aranges + 0x00000000000000a0 0x28 Core/Src/system_stm32f0xx.o + .debug_aranges + 0x00000000000000c8 0x28 Core/Startup/startup_stm32f072c8tx.o + .debug_aranges + 0x00000000000000f0 0xd0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .debug_aranges + 0x00000000000001c0 0xc0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .debug_aranges + 0x0000000000000280 0x58 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .debug_aranges + 0x00000000000002d8 0x120 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .debug_aranges + 0x00000000000003f8 0x58 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .debug_aranges + 0x0000000000000450 0x80 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .debug_aranges + 0x00000000000004d0 0x78 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .debug_aranges + 0x0000000000000548 0x108 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .debug_aranges + 0x0000000000000650 0x78 ecm_src/dhcp-server/dhserver.o + .debug_aranges + 0x00000000000006c8 0x40 ecm_src/dns-server/dnserver.o + .debug_aranges + 0x0000000000000708 0x38 ecm_src/lwip-1.4.1/src/core/def.o + .debug_aranges + 0x0000000000000740 0x20 ecm_src/lwip-1.4.1/src/core/init.o + .debug_aranges + 0x0000000000000760 0x48 ecm_src/lwip-1.4.1/src/core/mem.o + .debug_aranges + 0x00000000000007a8 0x30 ecm_src/lwip-1.4.1/src/core/memp.o + .debug_aranges + 0x00000000000007d8 0x80 ecm_src/lwip-1.4.1/src/core/netif.o + .debug_aranges + 0x0000000000000858 0xb8 ecm_src/lwip-1.4.1/src/core/pbuf.o + .debug_aranges + 0x0000000000000910 0x58 ecm_src/lwip-1.4.1/src/core/raw.o + .debug_aranges + 0x0000000000000968 0x20 ecm_src/lwip-1.4.1/src/core/stats.o + .debug_aranges + 0x0000000000000988 0x140 ecm_src/lwip-1.4.1/src/core/tcp.o + .debug_aranges + 0x0000000000000ac8 0x50 ecm_src/lwip-1.4.1/src/core/tcp_in.o + .debug_aranges + 0x0000000000000b18 0x98 ecm_src/lwip-1.4.1/src/core/tcp_out.o + .debug_aranges + 0x0000000000000bb0 0x60 ecm_src/lwip-1.4.1/src/core/timers.o + .debug_aranges + 0x0000000000000c10 0x78 ecm_src/lwip-1.4.1/src/core/udp.o + .debug_aranges + 0x0000000000000c88 0x38 ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .debug_aranges + 0x0000000000000cc0 0x40 ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .debug_aranges + 0x0000000000000d00 0x38 ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .debug_aranges + 0x0000000000000d38 0x48 ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o + .debug_aranges + 0x0000000000000d80 0x70 ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .debug_aranges + 0x0000000000000df0 0x98 ecm_src/lwip-1.4.1/src/netif/etharp.o + .debug_aranges + 0x0000000000000e88 0x70 ecm_src/src/ecm_main.o + .debug_aranges + 0x0000000000000ef8 0x60 ecm_src/src/time.o + .debug_aranges + 0x0000000000000f58 0x20 ecm_src/src/usb_device.o + .debug_aranges + 0x0000000000000f78 0xf8 ecm_src/src/usbd_conf.o + .debug_aranges + 0x0000000000001070 0xb0 ecm_src/src/usbd_core.o + .debug_aranges + 0x0000000000001120 0x88 ecm_src/src/usbd_ctlreq.o + .debug_aranges + 0x00000000000011a8 0x48 ecm_src/src/usbd_desc.o + .debug_aranges + 0x00000000000011f0 0x88 ecm_src/src/usbd_ecm.o + .debug_aranges + 0x0000000000001278 0x50 ecm_src/src/usbd_ioreq.o + +.debug_ranges 0x0000000000000000 0x10e0 + .debug_ranges 0x0000000000000000 0x28 Core/Src/main.o + .debug_ranges 0x0000000000000028 0x10 Core/Src/stm32f0xx_hal_msp.o + .debug_ranges 0x0000000000000038 0x38 Core/Src/stm32f0xx_it.o + .debug_ranges 0x0000000000000070 0x18 Core/Src/system_stm32f0xx.o + .debug_ranges 0x0000000000000088 0x20 Core/Startup/startup_stm32f072c8tx.o + .debug_ranges 0x00000000000000a8 0xc0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .debug_ranges 0x0000000000000168 0xb0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .debug_ranges 0x0000000000000218 0x48 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .debug_ranges 0x0000000000000260 0x110 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .debug_ranges 0x0000000000000370 0x48 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .debug_ranges 0x00000000000003b8 0x70 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .debug_ranges 0x0000000000000428 0x68 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .debug_ranges 0x0000000000000490 0xf8 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .debug_ranges 0x0000000000000588 0x68 ecm_src/dhcp-server/dhserver.o + .debug_ranges 0x00000000000005f0 0x48 ecm_src/dns-server/dnserver.o + .debug_ranges 0x0000000000000638 0x28 ecm_src/lwip-1.4.1/src/core/def.o + .debug_ranges 0x0000000000000660 0x10 ecm_src/lwip-1.4.1/src/core/init.o + .debug_ranges 0x0000000000000670 0x38 ecm_src/lwip-1.4.1/src/core/mem.o + .debug_ranges 0x00000000000006a8 0x20 ecm_src/lwip-1.4.1/src/core/memp.o + .debug_ranges 0x00000000000006c8 0x88 ecm_src/lwip-1.4.1/src/core/netif.o + .debug_ranges 0x0000000000000750 0xa8 ecm_src/lwip-1.4.1/src/core/pbuf.o + .debug_ranges 0x00000000000007f8 0x48 ecm_src/lwip-1.4.1/src/core/raw.o + .debug_ranges 0x0000000000000840 0x10 ecm_src/lwip-1.4.1/src/core/stats.o + .debug_ranges 0x0000000000000850 0x130 ecm_src/lwip-1.4.1/src/core/tcp.o + .debug_ranges 0x0000000000000980 0x40 ecm_src/lwip-1.4.1/src/core/tcp_in.o + .debug_ranges 0x00000000000009c0 0xe8 ecm_src/lwip-1.4.1/src/core/tcp_out.o + .debug_ranges 0x0000000000000aa8 0x50 ecm_src/lwip-1.4.1/src/core/timers.o + .debug_ranges 0x0000000000000af8 0x68 ecm_src/lwip-1.4.1/src/core/udp.o + .debug_ranges 0x0000000000000b60 0x40 ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .debug_ranges 0x0000000000000ba0 0x30 ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .debug_ranges 0x0000000000000bd0 0x28 ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .debug_ranges 0x0000000000000bf8 0x38 ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o + .debug_ranges 0x0000000000000c30 0x60 ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .debug_ranges 0x0000000000000c90 0x88 ecm_src/lwip-1.4.1/src/netif/etharp.o + .debug_ranges 0x0000000000000d18 0x60 ecm_src/src/ecm_main.o + .debug_ranges 0x0000000000000d78 0x68 ecm_src/src/time.o + .debug_ranges 0x0000000000000de0 0x10 ecm_src/src/usb_device.o + .debug_ranges 0x0000000000000df0 0xe8 ecm_src/src/usbd_conf.o + .debug_ranges 0x0000000000000ed8 0xa0 ecm_src/src/usbd_core.o + .debug_ranges 0x0000000000000f78 0x78 ecm_src/src/usbd_ctlreq.o + .debug_ranges 0x0000000000000ff0 0x38 ecm_src/src/usbd_desc.o + .debug_ranges 0x0000000000001028 0x78 ecm_src/src/usbd_ecm.o + .debug_ranges 0x00000000000010a0 0x40 ecm_src/src/usbd_ioreq.o + +.debug_macro 0x0000000000000000 0x1cd20 + .debug_macro 0x0000000000000000 0x53f Core/Src/main.o + .debug_macro 0x000000000000053f 0xa48 Core/Src/main.o + .debug_macro 0x0000000000000f87 0x12d Core/Src/main.o + .debug_macro 0x00000000000010b4 0x2e Core/Src/main.o + .debug_macro 0x00000000000010e2 0x22 Core/Src/main.o + .debug_macro 0x0000000000001104 0x22 Core/Src/main.o + .debug_macro 0x0000000000001126 0x8e Core/Src/main.o + .debug_macro 0x00000000000011b4 0x51 Core/Src/main.o + .debug_macro 0x0000000000001205 0xef Core/Src/main.o + .debug_macro 0x00000000000012f4 0x6a Core/Src/main.o + .debug_macro 0x000000000000135e 0x1df Core/Src/main.o + .debug_macro 0x000000000000153d 0x1c Core/Src/main.o + .debug_macro 0x0000000000001559 0x22 Core/Src/main.o + .debug_macro 0x000000000000157b 0xb5 Core/Src/main.o + .debug_macro 0x0000000000001630 0x391 Core/Src/main.o + .debug_macro 0x00000000000019c1 0xfe50 Core/Src/main.o + .debug_macro 0x0000000000011811 0x3c Core/Src/main.o + .debug_macro 0x000000000001184d 0x174 Core/Src/main.o + .debug_macro 0x00000000000119c1 0x53 Core/Src/main.o + .debug_macro 0x0000000000011a14 0x946 Core/Src/main.o + .debug_macro 0x000000000001235a 0x5f3 Core/Src/main.o + .debug_macro 0x000000000001294d 0x12f Core/Src/main.o + .debug_macro 0x0000000000012a7c 0x1a7 Core/Src/main.o + .debug_macro 0x0000000000012c23 0x1a7 Core/Src/main.o + .debug_macro 0x0000000000012dca 0x22c Core/Src/main.o + .debug_macro 0x0000000000012ff6 0x34 Core/Src/main.o + .debug_macro 0x000000000001302a 0x43 Core/Src/main.o + .debug_macro 0x000000000001306d 0x28 Core/Src/main.o + .debug_macro 0x0000000000013095 0xb0 Core/Src/main.o + .debug_macro 0x0000000000013145 0x217 Core/Src/main.o + .debug_macro 0x000000000001335c 0x22c Core/Src/main.o + .debug_macro 0x0000000000013588 0x5f Core/Src/main.o + .debug_macro 0x00000000000135e7 0xa5 Core/Src/main.o + .debug_macro 0x000000000001368c 0x65 Core/Src/main.o + .debug_macro 0x00000000000136f1 0x234 Core/Src/main.o + .debug_macro 0x0000000000013925 0x4c Core/Src/main.o + .debug_macro 0x0000000000013971 0x16d Core/Src/main.o + .debug_macro 0x0000000000013ade 0x130 Core/Src/main.o + .debug_macro 0x0000000000013c0e 0x46 Core/Src/main.o + .debug_macro 0x0000000000013c54 0x18 Core/Src/main.o + .debug_macro 0x0000000000013c6c 0x3c Core/Src/main.o + .debug_macro 0x0000000000013ca8 0x34 Core/Src/main.o + .debug_macro 0x0000000000013cdc 0x16 Core/Src/main.o + .debug_macro 0x0000000000013cf2 0x35 Core/Src/main.o + .debug_macro 0x0000000000013d27 0x32a Core/Src/main.o + .debug_macro 0x0000000000014051 0x10 Core/Src/main.o + .debug_macro 0x0000000000014061 0x52 Core/Src/main.o + .debug_macro 0x00000000000140b3 0x1f Core/Src/main.o + .debug_macro 0x00000000000140d2 0x43 Core/Src/main.o + .debug_macro 0x0000000000014115 0x20 Core/Src/main.o + .debug_macro 0x0000000000014135 0x1a3 Core/Src/main.o + .debug_macro 0x00000000000142d8 0x10 Core/Src/main.o + .debug_macro 0x00000000000142e8 0x1c Core/Src/main.o + .debug_macro 0x0000000000014304 0x52 Core/Src/main.o + .debug_macro 0x0000000000014356 0x40 Core/Src/main.o + .debug_macro 0x0000000000014396 0x10 Core/Src/main.o + .debug_macro 0x00000000000143a6 0x40 Core/Src/main.o + .debug_macro 0x00000000000143e6 0xd7 Core/Src/main.o + .debug_macro 0x00000000000144bd 0x1c Core/Src/main.o + .debug_macro 0x00000000000144d9 0x3d Core/Src/main.o + .debug_macro 0x0000000000014516 0x16 Core/Src/main.o + .debug_macro 0x000000000001452c 0x145 Core/Src/main.o + .debug_macro 0x0000000000014671 0x16 Core/Src/main.o + .debug_macro 0x0000000000014687 0x16 Core/Src/main.o + .debug_macro 0x000000000001469d 0x29 Core/Src/main.o + .debug_macro 0x00000000000146c6 0x16 Core/Src/main.o + .debug_macro 0x00000000000146dc 0x20 Core/Src/main.o + .debug_macro 0x00000000000146fc 0x64 Core/Src/main.o + .debug_macro 0x0000000000014760 0x1a6 Core/Src/main.o + .debug_macro 0x0000000000014906 0x22 Core/Src/main.o + .debug_macro 0x0000000000014928 0x70 Core/Src/main.o + .debug_macro 0x0000000000014998 0x16 Core/Src/main.o + .debug_macro 0x00000000000149ae 0x22 Core/Src/main.o + .debug_macro 0x00000000000149d0 0x16 Core/Src/main.o + .debug_macro 0x00000000000149e6 0x5e Core/Src/main.o + .debug_macro 0x0000000000014a44 0x592 Core/Src/main.o + .debug_macro 0x0000000000014fd6 0x76 Core/Src/main.o + .debug_macro 0x000000000001504c 0x4f Core/Src/main.o + .debug_macro 0x000000000001509b 0x52 Core/Src/main.o + .debug_macro 0x00000000000150ed 0x175 Core/Src/main.o + .debug_macro 0x0000000000015262 0x62 Core/Src/main.o + .debug_macro 0x00000000000152c4 0x13b Core/Src/main.o + .debug_macro 0x00000000000153ff 0x80 Core/Src/main.o + .debug_macro 0x000000000001547f 0x10 Core/Src/main.o + .debug_macro 0x000000000001548f 0x10 Core/Src/main.o + .debug_macro 0x000000000001549f 0x10 Core/Src/main.o + .debug_macro 0x00000000000154af 0x46 Core/Src/main.o + .debug_macro 0x00000000000154f5 0x64 Core/Src/main.o + .debug_macro 0x0000000000015559 0x3d Core/Src/main.o + .debug_macro 0x0000000000015596 0xdc Core/Src/main.o + .debug_macro 0x0000000000015672 0x22 Core/Src/main.o + .debug_macro 0x0000000000015694 0xac Core/Src/main.o + .debug_macro 0x0000000000015740 0x1be Core/Src/main.o + .debug_macro 0x00000000000158fe 0x10 Core/Src/main.o + .debug_macro 0x000000000001590e 0x10 Core/Src/main.o + .debug_macro 0x000000000001591e 0x1bf Core/Src/stm32f0xx_hal_msp.o + .debug_macro 0x0000000000015add 0x1c9 Core/Src/stm32f0xx_it.o + .debug_macro 0x0000000000015ca6 0x1b5 Core/Src/system_stm32f0xx.o + .debug_macro 0x0000000000015e5b 0x1d9 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .debug_macro 0x0000000000016034 0x1b5 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .debug_macro 0x00000000000161e9 0x1ed Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .debug_macro 0x00000000000163d6 0x1c1 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .debug_macro 0x0000000000016597 0x1b5 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .debug_macro 0x000000000001674c 0x1c7 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .debug_macro 0x0000000000016913 0x1c7 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .debug_macro 0x0000000000016ada 0x1b5 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .debug_macro 0x0000000000016c8f 0x2e2 ecm_src/dhcp-server/dhserver.o + .debug_macro 0x0000000000016f71 0x97 ecm_src/dhcp-server/dhserver.o + .debug_macro 0x0000000000017008 0xfd ecm_src/dhcp-server/dhserver.o + .debug_macro 0x0000000000017105 0x70 ecm_src/dhcp-server/dhserver.o + .debug_macro 0x0000000000017175 0x55 ecm_src/dhcp-server/dhserver.o + .debug_macro 0x00000000000171ca 0x10 ecm_src/dhcp-server/dhserver.o + .debug_macro 0x00000000000171da 0x56 ecm_src/dhcp-server/dhserver.o + .debug_macro 0x0000000000017230 0x37 ecm_src/dhcp-server/dhserver.o + .debug_macro 0x0000000000017267 0x86 ecm_src/dhcp-server/dhserver.o + .debug_macro 0x00000000000172ed 0x2b2 ecm_src/dns-server/dnserver.o + .debug_macro 0x000000000001759f 0x4c ecm_src/dns-server/dnserver.o + .debug_macro 0x00000000000175eb 0x17b ecm_src/dns-server/dnserver.o + .debug_macro 0x0000000000017766 0x6b ecm_src/lwip-1.4.1/src/core/def.o + .debug_macro 0x00000000000177d1 0x16 ecm_src/lwip-1.4.1/src/core/def.o + .debug_macro 0x00000000000177e7 0x10 ecm_src/lwip-1.4.1/src/core/def.o + .debug_macro 0x00000000000177f7 0x58 ecm_src/lwip-1.4.1/src/core/def.o + .debug_macro 0x000000000001784f 0x18d ecm_src/lwip-1.4.1/src/core/init.o + .debug_macro 0x00000000000179dc 0x10 ecm_src/lwip-1.4.1/src/core/init.o + .debug_macro 0x00000000000179ec 0x3a ecm_src/lwip-1.4.1/src/core/init.o + .debug_macro 0x0000000000017a26 0x127 ecm_src/lwip-1.4.1/src/core/init.o + .debug_macro 0x0000000000017b4d 0xc5 ecm_src/lwip-1.4.1/src/core/init.o + .debug_macro 0x0000000000017c12 0x10 ecm_src/lwip-1.4.1/src/core/init.o + .debug_macro 0x0000000000017c22 0x321 ecm_src/lwip-1.4.1/src/core/init.o + .debug_macro 0x0000000000017f43 0x16 ecm_src/lwip-1.4.1/src/core/init.o + .debug_macro 0x0000000000017f59 0x1db ecm_src/lwip-1.4.1/src/core/mem.o + .debug_macro 0x0000000000018134 0x10 ecm_src/lwip-1.4.1/src/core/mem.o + .debug_macro 0x0000000000018144 0x2af ecm_src/lwip-1.4.1/src/core/memp.o + .debug_macro 0x00000000000183f3 0x12d ecm_src/lwip-1.4.1/src/core/memp.o + .debug_macro 0x0000000000018520 0x10 ecm_src/lwip-1.4.1/src/core/memp.o + .debug_macro 0x0000000000018530 0x116 ecm_src/lwip-1.4.1/src/core/netif.o + .debug_macro 0x0000000000018646 0x200 ecm_src/lwip-1.4.1/src/core/pbuf.o + .debug_macro 0x0000000000018846 0x16 ecm_src/lwip-1.4.1/src/core/pbuf.o + .debug_macro 0x000000000001885c 0x135 ecm_src/lwip-1.4.1/src/core/pbuf.o + .debug_macro 0x0000000000018991 0x1c7 ecm_src/lwip-1.4.1/src/core/raw.o + .debug_macro 0x0000000000018b58 0x17c ecm_src/lwip-1.4.1/src/core/stats.o + .debug_macro 0x0000000000018cd4 0x209 ecm_src/lwip-1.4.1/src/core/tcp.o + .debug_macro 0x0000000000018edd 0x31b ecm_src/lwip-1.4.1/src/core/tcp.o + .debug_macro 0x00000000000191f8 0x1c4 ecm_src/lwip-1.4.1/src/core/tcp.o + .debug_macro 0x00000000000193bc 0x10a ecm_src/lwip-1.4.1/src/core/tcp_in.o + .debug_macro 0x00000000000194c6 0x1c ecm_src/lwip-1.4.1/src/core/tcp_in.o + .debug_macro 0x00000000000194e2 0x1fa ecm_src/lwip-1.4.1/src/core/tcp_out.o + .debug_macro 0x00000000000196dc 0x13c ecm_src/lwip-1.4.1/src/core/timers.o + .debug_macro 0x0000000000019818 0x10 ecm_src/lwip-1.4.1/src/core/timers.o + .debug_macro 0x0000000000019828 0x209 ecm_src/lwip-1.4.1/src/core/udp.o + .debug_macro 0x0000000000019a31 0x1e2 ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .debug_macro 0x0000000000019c13 0x5e ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .debug_macro 0x0000000000019c71 0x198 ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .debug_macro 0x0000000000019e09 0x16 ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .debug_macro 0x0000000000019e1f 0x242 ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .debug_macro 0x000000000001a061 0xb2 ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .debug_macro 0x000000000001a113 0xbe ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o + .debug_macro 0x000000000001a1d1 0x1f7 ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .debug_macro 0x000000000001a3c8 0x22e ecm_src/lwip-1.4.1/src/netif/etharp.o + .debug_macro 0x000000000001a5f6 0x545 ecm_src/src/ecm_main.o + .debug_macro 0x000000000001ab3b 0x1d1 ecm_src/src/time.o + .debug_macro 0x000000000001ad0c 0x53f ecm_src/src/usb_device.o + .debug_macro 0x000000000001b24b 0x492 ecm_src/src/usbd_conf.o + .debug_macro 0x000000000001b6dd 0x1ac ecm_src/src/usbd_conf.o + .debug_macro 0x000000000001b889 0x3b9 ecm_src/src/usbd_core.o + .debug_macro 0x000000000001bc42 0x3bf ecm_src/src/usbd_ctlreq.o + .debug_macro 0x000000000001c001 0x4ae ecm_src/src/usbd_desc.o + .debug_macro 0x000000000001c4af 0x16 ecm_src/src/usbd_desc.o + .debug_macro 0x000000000001c4c5 0x49c ecm_src/src/usbd_ecm.o + .debug_macro 0x000000000001c961 0x3bf ecm_src/src/usbd_ioreq.o + +.debug_line 0x0000000000000000 0x169ee + .debug_line 0x0000000000000000 0xc83 Core/Src/main.o + .debug_line 0x0000000000000c83 0x67f Core/Src/stm32f0xx_hal_msp.o + .debug_line 0x0000000000001302 0x6e5 Core/Src/stm32f0xx_it.o + .debug_line 0x00000000000019e7 0x6a2 Core/Src/system_stm32f0xx.o + .debug_line 0x0000000000002089 0x89 Core/Startup/startup_stm32f072c8tx.o + .debug_line 0x0000000000002112 0x835 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .debug_line 0x0000000000002947 0x84d Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .debug_line 0x0000000000003194 0x80f Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .debug_line 0x00000000000039a3 0xb2b Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .debug_line 0x00000000000044ce 0x746 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .debug_line 0x0000000000004c14 0x922 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .debug_line 0x0000000000005536 0x8ce Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .debug_line 0x0000000000005e04 0xb64 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .debug_line 0x0000000000006968 0x93a ecm_src/dhcp-server/dhserver.o + .debug_line 0x00000000000072a2 0x845 ecm_src/dns-server/dnserver.o + .debug_line 0x0000000000007ae7 0x195 ecm_src/lwip-1.4.1/src/core/def.o + .debug_line 0x0000000000007c7c 0x2fa ecm_src/lwip-1.4.1/src/core/init.o + .debug_line 0x0000000000007f76 0x733 ecm_src/lwip-1.4.1/src/core/mem.o + .debug_line 0x00000000000086a9 0x802 ecm_src/lwip-1.4.1/src/core/memp.o + .debug_line 0x0000000000008eab 0x43d ecm_src/lwip-1.4.1/src/core/netif.o + .debug_line 0x00000000000092e8 0xa5d ecm_src/lwip-1.4.1/src/core/pbuf.o + .debug_line 0x0000000000009d45 0x79a ecm_src/lwip-1.4.1/src/core/raw.o + .debug_line 0x000000000000a4df 0x5f4 ecm_src/lwip-1.4.1/src/core/stats.o + .debug_line 0x000000000000aad3 0xcbe ecm_src/lwip-1.4.1/src/core/tcp.o + .debug_line 0x000000000000b791 0x87e ecm_src/lwip-1.4.1/src/core/tcp_in.o + .debug_line 0x000000000000c00f 0xb26 ecm_src/lwip-1.4.1/src/core/tcp_out.o + .debug_line 0x000000000000cb35 0x3d1 ecm_src/lwip-1.4.1/src/core/timers.o + .debug_line 0x000000000000cf06 0x921 ecm_src/lwip-1.4.1/src/core/udp.o + .debug_line 0x000000000000d827 0x73c ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .debug_line 0x000000000000df63 0x70e ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .debug_line 0x000000000000e671 0x827 ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .debug_line 0x000000000000ee98 0x348 ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o + .debug_line 0x000000000000f1e0 0x8eb ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .debug_line 0x000000000000facb 0xa19 ecm_src/lwip-1.4.1/src/netif/etharp.o + .debug_line 0x00000000000104e4 0xd46 ecm_src/src/ecm_main.o + .debug_line 0x000000000001122a 0x755 ecm_src/src/time.o + .debug_line 0x000000000001197f 0xc34 ecm_src/src/usb_device.o + .debug_line 0x00000000000125b3 0xcec ecm_src/src/usbd_conf.o + .debug_line 0x000000000001329f 0xacd ecm_src/src/usbd_core.o + .debug_line 0x0000000000013d6c 0xb18 ecm_src/src/usbd_ctlreq.o + .debug_line 0x0000000000014884 0xb75 ecm_src/src/usbd_desc.o + .debug_line 0x00000000000153f9 0xc76 ecm_src/src/usbd_ecm.o + .debug_line 0x000000000001606f 0x97f ecm_src/src/usbd_ioreq.o + +.debug_str 0x0000000000000000 0x82af5 + .debug_str 0x0000000000000000 0x7bb47 Core/Src/main.o + 0x7bff0 (size before relaxing) + .debug_str 0x000000000007bb47 0x2c Core/Src/stm32f0xx_hal_msp.o + 0x70cc6 (size before relaxing) + .debug_str 0x000000000007bb73 0x3ce Core/Src/stm32f0xx_it.o + 0x7105a (size before relaxing) + .debug_str 0x000000000007bf41 0x5f Core/Src/system_stm32f0xx.o + 0x70ce8 (size before relaxing) + .debug_str 0x000000000007bfa0 0x36 Core/Startup/startup_stm32f072c8tx.o + 0x69 (size before relaxing) + .debug_str 0x000000000007bfd6 0x4f1 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + 0x71256 (size before relaxing) + .debug_str 0x000000000007c4c7 0x1e8 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + 0x7110a (size before relaxing) + .debug_str 0x000000000007c6af 0x281 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + 0x70f84 (size before relaxing) + .debug_str 0x000000000007c930 0x3c3 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + 0x713cf (size before relaxing) + .debug_str 0x000000000007ccf3 0x1c6 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + 0x711f8 (size before relaxing) + .debug_str 0x000000000007ceb9 0x254 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + 0x710fd (size before relaxing) + .debug_str 0x000000000007d10d 0x2f6 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + 0x710da (size before relaxing) + .debug_str 0x000000000007d403 0x30f Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + 0x711de (size before relaxing) + .debug_str 0x000000000007d712 0x49a ecm_src/dhcp-server/dhserver.o + 0xbbcf (size before relaxing) + .debug_str 0x000000000007dbac 0x112 ecm_src/dns-server/dnserver.o + 0xb8c7 (size before relaxing) + .debug_str 0x000000000007dcbe 0x64 ecm_src/lwip-1.4.1/src/core/def.o + 0x47cf (size before relaxing) + .debug_str 0x000000000007dd22 0x1bbe ecm_src/lwip-1.4.1/src/core/init.o + 0x9bdc (size before relaxing) + .debug_str 0x000000000007f8e0 0x2e6 ecm_src/lwip-1.4.1/src/core/mem.o + 0x90b2 (size before relaxing) + .debug_str 0x000000000007fbc6 0x1d2 ecm_src/lwip-1.4.1/src/core/memp.o + 0xd1e8 (size before relaxing) + .debug_str 0x000000000007fd98 0x152 ecm_src/lwip-1.4.1/src/core/netif.o + 0x94d3 (size before relaxing) + .debug_str 0x000000000007feea 0x333 ecm_src/lwip-1.4.1/src/core/pbuf.o + 0xc2c2 (size before relaxing) + .debug_str 0x000000000008021d 0xbf ecm_src/lwip-1.4.1/src/core/raw.o + 0xa262 (size before relaxing) + .debug_str 0x00000000000802dc 0x45 ecm_src/lwip-1.4.1/src/core/stats.o + 0x88e6 (size before relaxing) + .debug_str 0x0000000000080321 0x4a1 ecm_src/lwip-1.4.1/src/core/tcp.o + 0xcbfc (size before relaxing) + .debug_str 0x00000000000807c2 0x1f3 ecm_src/lwip-1.4.1/src/core/tcp_in.o + 0x9306 (size before relaxing) + .debug_str 0x00000000000809b5 0x280 ecm_src/lwip-1.4.1/src/core/tcp_out.o + 0xcad6 (size before relaxing) + .debug_str 0x0000000000080c35 0x154 ecm_src/lwip-1.4.1/src/core/timers.o + 0x8633 (size before relaxing) + .debug_str 0x0000000000080d89 0x218 ecm_src/lwip-1.4.1/src/core/udp.o + 0xb345 (size before relaxing) + .debug_str 0x0000000000080fa1 0x10f ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + 0xb079 (size before relaxing) + .debug_str 0x00000000000810b0 0xed ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + 0x8eb0 (size before relaxing) + .debug_str 0x000000000008119d 0x14a ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + 0xcb20 (size before relaxing) + .debug_str 0x00000000000812e7 0x1f3 ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o + 0x5b5b (size before relaxing) + .debug_str 0x00000000000814da 0x377 ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + 0xb3b4 (size before relaxing) + .debug_str 0x0000000000081851 0x49a ecm_src/lwip-1.4.1/src/netif/etharp.o + 0xb533 (size before relaxing) + .debug_str 0x0000000000081ceb 0x131 ecm_src/src/ecm_main.o + 0x7bf71 (size before relaxing) + .debug_str 0x0000000000081e1c 0x9f ecm_src/src/time.o + 0x70e1b (size before relaxing) + .debug_str 0x0000000000081ebb 0x6b ecm_src/src/usb_device.o + 0x7bdd4 (size before relaxing) + .debug_str 0x0000000000081f26 0x192 ecm_src/src/usbd_conf.o + 0x7a216 (size before relaxing) + .debug_str 0x00000000000820b8 0x186 ecm_src/src/usbd_core.o + 0x75c15 (size before relaxing) + .debug_str 0x000000000008223e 0x114 ecm_src/src/usbd_ctlreq.o + 0x75bac (size before relaxing) + .debug_str 0x0000000000082352 0x501 ecm_src/src/usbd_desc.o + 0x79e0b (size before relaxing) + .debug_str 0x0000000000082853 0x1eb ecm_src/src/usbd_ecm.o + 0x79ee0 (size before relaxing) + .debug_str 0x0000000000082a3e 0xb7 ecm_src/src/usbd_ioreq.o + 0x75b34 (size before relaxing) + +.comment 0x0000000000000000 0x7b + .comment 0x0000000000000000 0x7b Core/Src/main.o + 0x7c (size before relaxing) + .comment 0x000000000000007b 0x7c Core/Src/stm32f0xx_hal_msp.o + .comment 0x000000000000007b 0x7c Core/Src/stm32f0xx_it.o + .comment 0x000000000000007b 0x7c Core/Src/system_stm32f0xx.o + .comment 0x000000000000007b 0x7c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .comment 0x000000000000007b 0x7c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .comment 0x000000000000007b 0x7c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .comment 0x000000000000007b 0x7c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .comment 0x000000000000007b 0x7c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .comment 0x000000000000007b 0x7c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .comment 0x000000000000007b 0x7c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .comment 0x000000000000007b 0x7c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .comment 0x000000000000007b 0x7c ecm_src/dhcp-server/dhserver.o + .comment 0x000000000000007b 0x7c ecm_src/dns-server/dnserver.o + .comment 0x000000000000007b 0x7c ecm_src/lwip-1.4.1/src/core/def.o + .comment 0x000000000000007b 0x7c ecm_src/lwip-1.4.1/src/core/init.o + .comment 0x000000000000007b 0x7c ecm_src/lwip-1.4.1/src/core/mem.o + .comment 0x000000000000007b 0x7c ecm_src/lwip-1.4.1/src/core/memp.o + .comment 0x000000000000007b 0x7c ecm_src/lwip-1.4.1/src/core/netif.o + .comment 0x000000000000007b 0x7c ecm_src/lwip-1.4.1/src/core/pbuf.o + .comment 0x000000000000007b 0x7c ecm_src/lwip-1.4.1/src/core/raw.o + .comment 0x000000000000007b 0x7c ecm_src/lwip-1.4.1/src/core/stats.o + .comment 0x000000000000007b 0x7c ecm_src/lwip-1.4.1/src/core/tcp.o + .comment 0x000000000000007b 0x7c ecm_src/lwip-1.4.1/src/core/tcp_in.o + .comment 0x000000000000007b 0x7c ecm_src/lwip-1.4.1/src/core/tcp_out.o + .comment 0x000000000000007b 0x7c ecm_src/lwip-1.4.1/src/core/timers.o + .comment 0x000000000000007b 0x7c ecm_src/lwip-1.4.1/src/core/udp.o + .comment 0x000000000000007b 0x7c ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .comment 0x000000000000007b 0x7c ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .comment 0x000000000000007b 0x7c ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .comment 0x000000000000007b 0x7c ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o + .comment 0x000000000000007b 0x7c ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .comment 0x000000000000007b 0x7c ecm_src/lwip-1.4.1/src/netif/etharp.o + .comment 0x000000000000007b 0x7c ecm_src/src/ecm_main.o + .comment 0x000000000000007b 0x7c ecm_src/src/time.o + .comment 0x000000000000007b 0x7c ecm_src/src/usb_device.o + .comment 0x000000000000007b 0x7c ecm_src/src/usbd_conf.o + .comment 0x000000000000007b 0x7c ecm_src/src/usbd_core.o + .comment 0x000000000000007b 0x7c ecm_src/src/usbd_ctlreq.o + .comment 0x000000000000007b 0x7c ecm_src/src/usbd_desc.o + .comment 0x000000000000007b 0x7c ecm_src/src/usbd_ecm.o + .comment 0x000000000000007b 0x7c ecm_src/src/usbd_ioreq.o + +.debug_frame 0x0000000000000000 0x3e20 + .debug_frame 0x0000000000000000 0x88 Core/Src/main.o + .debug_frame 0x0000000000000088 0x30 Core/Src/stm32f0xx_hal_msp.o + .debug_frame 0x00000000000000b8 0xb8 Core/Src/stm32f0xx_it.o + .debug_frame 0x0000000000000170 0x4c Core/Src/system_stm32f0xx.o + .debug_frame 0x00000000000001bc 0x2a4 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .debug_frame 0x0000000000000460 0x2a0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .debug_frame 0x0000000000000700 0x110 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .debug_frame 0x0000000000000810 0x434 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .debug_frame 0x0000000000000c44 0x110 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .debug_frame 0x0000000000000d54 0x198 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .debug_frame 0x0000000000000eec 0x180 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .debug_frame 0x000000000000106c 0x3e0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .debug_frame 0x000000000000144c 0x19c ecm_src/dhcp-server/dhserver.o + .debug_frame 0x00000000000015e8 0xb0 ecm_src/dns-server/dnserver.o + .debug_frame 0x0000000000001698 0x90 ecm_src/lwip-1.4.1/src/core/def.o + .debug_frame 0x0000000000001728 0x2c ecm_src/lwip-1.4.1/src/core/init.o + .debug_frame 0x0000000000001754 0xd0 ecm_src/lwip-1.4.1/src/core/mem.o + .debug_frame 0x0000000000001824 0x70 ecm_src/lwip-1.4.1/src/core/memp.o + .debug_frame 0x0000000000001894 0x1ac ecm_src/lwip-1.4.1/src/core/netif.o + .debug_frame 0x0000000000001a40 0x2a0 ecm_src/lwip-1.4.1/src/core/pbuf.o + .debug_frame 0x0000000000001ce0 0x114 ecm_src/lwip-1.4.1/src/core/raw.o + .debug_frame 0x0000000000001df4 0x2c ecm_src/lwip-1.4.1/src/core/stats.o + .debug_frame 0x0000000000001e20 0x4b4 ecm_src/lwip-1.4.1/src/core/tcp.o + .debug_frame 0x00000000000022d4 0x104 ecm_src/lwip-1.4.1/src/core/tcp_in.o + .debug_frame 0x00000000000023d8 0x220 ecm_src/lwip-1.4.1/src/core/tcp_out.o + .debug_frame 0x00000000000025f8 0x124 ecm_src/lwip-1.4.1/src/core/timers.o + .debug_frame 0x000000000000271c 0x198 ecm_src/lwip-1.4.1/src/core/udp.o + .debug_frame 0x00000000000028b4 0x90 ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .debug_frame 0x0000000000002944 0xb0 ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .debug_frame 0x00000000000029f4 0x94 ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .debug_frame 0x0000000000002a88 0xd4 ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o + .debug_frame 0x0000000000002b5c 0x17c ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .debug_frame 0x0000000000002cd8 0x228 ecm_src/lwip-1.4.1/src/netif/etharp.o + .debug_frame 0x0000000000002f00 0x164 ecm_src/src/ecm_main.o + .debug_frame 0x0000000000003064 0x128 ecm_src/src/time.o + .debug_frame 0x000000000000318c 0x2c ecm_src/src/usb_device.o + .debug_frame 0x00000000000031b8 0x398 ecm_src/src/usbd_conf.o + .debug_frame 0x0000000000003550 0x270 ecm_src/src/usbd_core.o + .debug_frame 0x00000000000037c0 0x1d0 ecm_src/src/usbd_ctlreq.o + .debug_frame 0x0000000000003990 0xd0 ecm_src/src/usbd_desc.o + .debug_frame 0x0000000000003a60 0x1d0 ecm_src/src/usbd_ecm.o + .debug_frame 0x0000000000003c30 0xf0 ecm_src/src/usbd_ioreq.o + .debug_frame 0x0000000000003d20 0x2c c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-init.o) + .debug_frame 0x0000000000003d4c 0x2c c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-memcmp.o) + .debug_frame 0x0000000000003d78 0x28 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-memcpy-stub.o) + .debug_frame 0x0000000000003da0 0x20 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-memset.o) + .debug_frame 0x0000000000003dc0 0x20 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-strcmp.o) + .debug_frame 0x0000000000003de0 0x20 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v6-m\libgcc.a(_udivsi3.o) + .debug_frame 0x0000000000003e00 0x20 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v6-m\libgcc.a(_divsi3.o) diff --git a/test/STM32F072C8T6/Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f072xb.h b/test/STM32F072C8T6/Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f072xb.h new file mode 100644 index 0000000..f6e8fd5 --- /dev/null +++ b/test/STM32F072C8T6/Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f072xb.h @@ -0,0 +1,11293 @@ +/** + ****************************************************************************** + * @file stm32f072xb.h + * @author MCD Application Team + * @brief CMSIS Cortex-M0 Device Peripheral Access Layer Header File. + * This file contains all the peripheral register's definitions, bits + * definitions and memory mapping for STM32F0xx devices. + * + * This file contains: + * - Data structures and the address mapping for all peripherals + * - Peripheral's registers declarations and bits definition + * - Macros to access peripherals registers hardware + * + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2016 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/** @addtogroup CMSIS + * @{ + */ + +/** @addtogroup stm32f072xb + * @{ + */ + +#ifndef __STM32F072xB_H +#define __STM32F072xB_H + +#ifdef __cplusplus + extern "C" { +#endif /* __cplusplus */ + + /** @addtogroup Configuration_section_for_CMSIS + * @{ + */ +/** + * @brief Configuration of the Cortex-M0 Processor and Core Peripherals + */ +#define __CM0_REV 0 /*!< Core Revision r0p0 */ +#define __MPU_PRESENT 0 /*!< STM32F0xx do not provide MPU */ +#define __NVIC_PRIO_BITS 2 /*!< STM32F0xx uses 2 Bits for the Priority Levels */ +#define __Vendor_SysTickConfig 0 /*!< Set to 1 if different SysTick Config is used */ + +/** + * @} + */ + +/** @addtogroup Peripheral_interrupt_number_definition + * @{ + */ + +/** + * @brief STM32F0xx Interrupt Number Definition, according to the selected device + * in @ref Library_configuration_section + */ + + /*!< Interrupt Number Definition */ +typedef enum +{ +/****** Cortex-M0 Processor Exceptions Numbers **************************************************************/ + NonMaskableInt_IRQn = -14, /*!< 2 Non Maskable Interrupt */ + HardFault_IRQn = -13, /*!< 3 Cortex-M0 Hard Fault Interrupt */ + SVC_IRQn = -5, /*!< 11 Cortex-M0 SV Call Interrupt */ + PendSV_IRQn = -2, /*!< 14 Cortex-M0 Pend SV Interrupt */ + SysTick_IRQn = -1, /*!< 15 Cortex-M0 System Tick Interrupt */ + +/****** STM32F0 specific Interrupt Numbers ******************************************************************/ + WWDG_IRQn = 0, /*!< Window WatchDog Interrupt */ + PVD_VDDIO2_IRQn = 1, /*!< PVD & VDDIO2 Interrupt through EXTI Lines 16 and 31 */ + RTC_IRQn = 2, /*!< RTC Interrupt through EXTI Lines 17, 19 and 20 */ + FLASH_IRQn = 3, /*!< FLASH global Interrupt */ + RCC_CRS_IRQn = 4, /*!< RCC & CRS global Interrupt */ + EXTI0_1_IRQn = 5, /*!< EXTI Line 0 and 1 Interrupt */ + EXTI2_3_IRQn = 6, /*!< EXTI Line 2 and 3 Interrupt */ + EXTI4_15_IRQn = 7, /*!< EXTI Line 4 to 15 Interrupt */ + TSC_IRQn = 8, /*!< Touch Sensing Controller Interrupts */ + DMA1_Channel1_IRQn = 9, /*!< DMA1 Channel 1 Interrupt */ + DMA1_Channel2_3_IRQn = 10, /*!< DMA1 Channel 2 and Channel 3 Interrupt */ + DMA1_Channel4_5_6_7_IRQn = 11, /*!< DMA1 Channel 4 to Channel 7 Interrupt */ + ADC1_COMP_IRQn = 12, /*!< ADC1 and COMP interrupts (ADC interrupt combined with EXTI Lines 21 and 22 */ + TIM1_BRK_UP_TRG_COM_IRQn = 13, /*!< TIM1 Break, Update, Trigger and Commutation Interrupt */ + TIM1_CC_IRQn = 14, /*!< TIM1 Capture Compare Interrupt */ + TIM2_IRQn = 15, /*!< TIM2 global Interrupt */ + TIM3_IRQn = 16, /*!< TIM3 global Interrupt */ + TIM6_DAC_IRQn = 17, /*!< TIM6 global and DAC channel underrun error Interrupt */ + TIM7_IRQn = 18, /*!< TIM7 global Interrupt */ + TIM14_IRQn = 19, /*!< TIM14 global Interrupt */ + TIM15_IRQn = 20, /*!< TIM15 global Interrupt */ + TIM16_IRQn = 21, /*!< TIM16 global Interrupt */ + TIM17_IRQn = 22, /*!< TIM17 global Interrupt */ + I2C1_IRQn = 23, /*!< I2C1 Event Interrupt & EXTI Line23 Interrupt (I2C1 wakeup) */ + I2C2_IRQn = 24, /*!< I2C2 Event Interrupt */ + SPI1_IRQn = 25, /*!< SPI1 global Interrupt */ + SPI2_IRQn = 26, /*!< SPI2 global Interrupt */ + USART1_IRQn = 27, /*!< USART1 global Interrupt & EXTI Line25 Interrupt (USART1 wakeup) */ + USART2_IRQn = 28, /*!< USART2 global Interrupt & EXTI Line26 Interrupt (USART2 wakeup) */ + USART3_4_IRQn = 29, /*!< USART3 and USART4 global Interrupt */ + CEC_CAN_IRQn = 30, /*!< CEC and CAN global Interrupts & EXTI Line27 Interrupt */ + USB_IRQn = 31 /*!< USB global Interrupt & EXTI Line18 Interrupt */ +} IRQn_Type; + +/** + * @} + */ + +#include "core_cm0.h" /* Cortex-M0 processor and core peripherals */ +#include "system_stm32f0xx.h" /* STM32F0xx System Header */ +#include + +/** @addtogroup Peripheral_registers_structures + * @{ + */ + +/** + * @brief Analog to Digital Converter + */ + +typedef struct +{ + __IO uint32_t ISR; /*!< ADC interrupt and status register, Address offset: 0x00 */ + __IO uint32_t IER; /*!< ADC interrupt enable register, Address offset: 0x04 */ + __IO uint32_t CR; /*!< ADC control register, Address offset: 0x08 */ + __IO uint32_t CFGR1; /*!< ADC configuration register 1, Address offset: 0x0C */ + __IO uint32_t CFGR2; /*!< ADC configuration register 2, Address offset: 0x10 */ + __IO uint32_t SMPR; /*!< ADC sampling time register, Address offset: 0x14 */ + uint32_t RESERVED1; /*!< Reserved, 0x18 */ + uint32_t RESERVED2; /*!< Reserved, 0x1C */ + __IO uint32_t TR; /*!< ADC analog watchdog 1 threshold register, Address offset: 0x20 */ + uint32_t RESERVED3; /*!< Reserved, 0x24 */ + __IO uint32_t CHSELR; /*!< ADC group regular sequencer register, Address offset: 0x28 */ + uint32_t RESERVED4[5]; /*!< Reserved, 0x2C */ + __IO uint32_t DR; /*!< ADC group regular data register, Address offset: 0x40 */ +} ADC_TypeDef; + +typedef struct +{ + __IO uint32_t CCR; /*!< ADC common configuration register, Address offset: ADC1 base address + 0x308 */ +} ADC_Common_TypeDef; + +/** + * @brief Controller Area Network TxMailBox + */ +typedef struct +{ + __IO uint32_t TIR; /*!< CAN TX mailbox identifier register */ + __IO uint32_t TDTR; /*!< CAN mailbox data length control and time stamp register */ + __IO uint32_t TDLR; /*!< CAN mailbox data low register */ + __IO uint32_t TDHR; /*!< CAN mailbox data high register */ +}CAN_TxMailBox_TypeDef; + +/** + * @brief Controller Area Network FIFOMailBox + */ +typedef struct +{ + __IO uint32_t RIR; /*!< CAN receive FIFO mailbox identifier register */ + __IO uint32_t RDTR; /*!< CAN receive FIFO mailbox data length control and time stamp register */ + __IO uint32_t RDLR; /*!< CAN receive FIFO mailbox data low register */ + __IO uint32_t RDHR; /*!< CAN receive FIFO mailbox data high register */ +}CAN_FIFOMailBox_TypeDef; + +/** + * @brief Controller Area Network FilterRegister + */ +typedef struct +{ + __IO uint32_t FR1; /*!< CAN Filter bank register 1 */ + __IO uint32_t FR2; /*!< CAN Filter bank register 1 */ +}CAN_FilterRegister_TypeDef; + +/** + * @brief Controller Area Network + */ +typedef struct +{ + __IO uint32_t MCR; /*!< CAN master control register, Address offset: 0x00 */ + __IO uint32_t MSR; /*!< CAN master status register, Address offset: 0x04 */ + __IO uint32_t TSR; /*!< CAN transmit status register, Address offset: 0x08 */ + __IO uint32_t RF0R; /*!< CAN receive FIFO 0 register, Address offset: 0x0C */ + __IO uint32_t RF1R; /*!< CAN receive FIFO 1 register, Address offset: 0x10 */ + __IO uint32_t IER; /*!< CAN interrupt enable register, Address offset: 0x14 */ + __IO uint32_t ESR; /*!< CAN error status register, Address offset: 0x18 */ + __IO uint32_t BTR; /*!< CAN bit timing register, Address offset: 0x1C */ + uint32_t RESERVED0[88]; /*!< Reserved, 0x020 - 0x17F */ + CAN_TxMailBox_TypeDef sTxMailBox[3]; /*!< CAN Tx MailBox, Address offset: 0x180 - 0x1AC */ + CAN_FIFOMailBox_TypeDef sFIFOMailBox[2]; /*!< CAN FIFO MailBox, Address offset: 0x1B0 - 0x1CC */ + uint32_t RESERVED1[12]; /*!< Reserved, 0x1D0 - 0x1FF */ + __IO uint32_t FMR; /*!< CAN filter master register, Address offset: 0x200 */ + __IO uint32_t FM1R; /*!< CAN filter mode register, Address offset: 0x204 */ + uint32_t RESERVED2; /*!< Reserved, 0x208 */ + __IO uint32_t FS1R; /*!< CAN filter scale register, Address offset: 0x20C */ + uint32_t RESERVED3; /*!< Reserved, 0x210 */ + __IO uint32_t FFA1R; /*!< CAN filter FIFO assignment register, Address offset: 0x214 */ + uint32_t RESERVED4; /*!< Reserved, 0x218 */ + __IO uint32_t FA1R; /*!< CAN filter activation register, Address offset: 0x21C */ + uint32_t RESERVED5[8]; /*!< Reserved, 0x220-0x23F */ + CAN_FilterRegister_TypeDef sFilterRegister[28]; /*!< CAN Filter Register, Address offset: 0x240-0x31C */ +}CAN_TypeDef; + +/** + * @brief HDMI-CEC + */ + +typedef struct +{ + __IO uint32_t CR; /*!< CEC control register, Address offset:0x00 */ + __IO uint32_t CFGR; /*!< CEC configuration register, Address offset:0x04 */ + __IO uint32_t TXDR; /*!< CEC Tx data register , Address offset:0x08 */ + __IO uint32_t RXDR; /*!< CEC Rx Data Register, Address offset:0x0C */ + __IO uint32_t ISR; /*!< CEC Interrupt and Status Register, Address offset:0x10 */ + __IO uint32_t IER; /*!< CEC interrupt enable register, Address offset:0x14 */ +}CEC_TypeDef; + +/** + * @brief Comparator + */ + +typedef struct +{ + __IO uint16_t CSR; /*!< COMP control and status register, Address offset: 0x00 */ +} COMP_TypeDef; + +typedef struct +{ + __IO uint32_t CSR; /*!< COMP control and status register, used for bits common to several COMP instances, Address offset: 0x00 */ +} COMP_Common_TypeDef; + +/* Legacy defines */ +typedef struct +{ + __IO uint32_t CSR; /*!< Kept for legacy purpose. Use structure 'COMP_Common_TypeDef'. */ +}COMP1_2_TypeDef; + +/** + * @brief CRC calculation unit + */ + +typedef struct +{ + __IO uint32_t DR; /*!< CRC Data register, Address offset: 0x00 */ + __IO uint8_t IDR; /*!< CRC Independent data register, Address offset: 0x04 */ + uint8_t RESERVED0; /*!< Reserved, 0x05 */ + uint16_t RESERVED1; /*!< Reserved, 0x06 */ + __IO uint32_t CR; /*!< CRC Control register, Address offset: 0x08 */ + uint32_t RESERVED2; /*!< Reserved, 0x0C */ + __IO uint32_t INIT; /*!< Initial CRC value register, Address offset: 0x10 */ + __IO uint32_t POL; /*!< CRC polynomial register, Address offset: 0x14 */ +} CRC_TypeDef; + +/** + * @brief Clock Recovery System + */ +typedef struct +{ +__IO uint32_t CR; /*!< CRS ccontrol register, Address offset: 0x00 */ +__IO uint32_t CFGR; /*!< CRS configuration register, Address offset: 0x04 */ +__IO uint32_t ISR; /*!< CRS interrupt and status register, Address offset: 0x08 */ +__IO uint32_t ICR; /*!< CRS interrupt flag clear register, Address offset: 0x0C */ +}CRS_TypeDef; + +/** + * @brief Digital to Analog Converter + */ + +typedef struct +{ + __IO uint32_t CR; /*!< DAC control register, Address offset: 0x00 */ + __IO uint32_t SWTRIGR; /*!< DAC software trigger register, Address offset: 0x04 */ + __IO uint32_t DHR12R1; /*!< DAC channel1 12-bit right-aligned data holding register, Address offset: 0x08 */ + __IO uint32_t DHR12L1; /*!< DAC channel1 12-bit left aligned data holding register, Address offset: 0x0C */ + __IO uint32_t DHR8R1; /*!< DAC channel1 8-bit right aligned data holding register, Address offset: 0x10 */ + __IO uint32_t DHR12R2; /*!< DAC channel2 12-bit right aligned data holding register, Address offset: 0x14 */ + __IO uint32_t DHR12L2; /*!< DAC channel2 12-bit left aligned data holding register, Address offset: 0x18 */ + __IO uint32_t DHR8R2; /*!< DAC channel2 8-bit right-aligned data holding register, Address offset: 0x1C */ + __IO uint32_t DHR12RD; /*!< Dual DAC 12-bit right-aligned data holding register, Address offset: 0x20 */ + __IO uint32_t DHR12LD; /*!< DUAL DAC 12-bit left aligned data holding register, Address offset: 0x24 */ + __IO uint32_t DHR8RD; /*!< DUAL DAC 8-bit right aligned data holding register, Address offset: 0x28 */ + __IO uint32_t DOR1; /*!< DAC channel1 data output register, Address offset: 0x2C */ + __IO uint32_t DOR2; /*!< DAC channel2 data output register, Address offset: 0x30 */ + __IO uint32_t SR; /*!< DAC status register, Address offset: 0x34 */ +} DAC_TypeDef; + +/** + * @brief Debug MCU + */ + +typedef struct +{ + __IO uint32_t IDCODE; /*!< MCU device ID code, Address offset: 0x00 */ + __IO uint32_t CR; /*!< Debug MCU configuration register, Address offset: 0x04 */ + __IO uint32_t APB1FZ; /*!< Debug MCU APB1 freeze register, Address offset: 0x08 */ + __IO uint32_t APB2FZ; /*!< Debug MCU APB2 freeze register, Address offset: 0x0C */ +}DBGMCU_TypeDef; + +/** + * @brief DMA Controller + */ + +typedef struct +{ + __IO uint32_t CCR; /*!< DMA channel x configuration register */ + __IO uint32_t CNDTR; /*!< DMA channel x number of data register */ + __IO uint32_t CPAR; /*!< DMA channel x peripheral address register */ + __IO uint32_t CMAR; /*!< DMA channel x memory address register */ +} DMA_Channel_TypeDef; + +typedef struct +{ + __IO uint32_t ISR; /*!< DMA interrupt status register, Address offset: 0x00 */ + __IO uint32_t IFCR; /*!< DMA interrupt flag clear register, Address offset: 0x04 */ +} DMA_TypeDef; + +/** + * @brief External Interrupt/Event Controller + */ + +typedef struct +{ + __IO uint32_t IMR; /*!
© Copyright (c) 2016 STMicroelectronics. + * All rights reserved.
+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/** @addtogroup CMSIS + * @{ + */ + +/** @addtogroup stm32f0xx + * @{ + */ + +#ifndef __STM32F0xx_H +#define __STM32F0xx_H + +#ifdef __cplusplus + extern "C" { +#endif /* __cplusplus */ + +/** @addtogroup Library_configuration_section + * @{ + */ + +/** + * @brief STM32 Family + */ +#if !defined (STM32F0) +#define STM32F0 +#endif /* STM32F0 */ + +/* Uncomment the line below according to the target STM32 device used in your + application + */ + +#if !defined (STM32F030x6) && !defined (STM32F030x8) && \ + !defined (STM32F031x6) && !defined (STM32F038xx) && \ + !defined (STM32F042x6) && !defined (STM32F048xx) && !defined (STM32F070x6) && \ + !defined (STM32F051x8) && !defined (STM32F058xx) && \ + !defined (STM32F071xB) && !defined (STM32F072xB) && !defined (STM32F078xx) && !defined (STM32F070xB) && \ + !defined (STM32F091xC) && !defined (STM32F098xx) && !defined (STM32F030xC) + /* #define STM32F030x6 */ /*!< STM32F030x4, STM32F030x6 Devices (STM32F030xx microcontrollers where the Flash memory ranges between 16 and 32 Kbytes) */ + /* #define STM32F030x8 */ /*!< STM32F030x8 Devices (STM32F030xx microcontrollers where the Flash memory is 64 Kbytes) */ + /* #define STM32F031x6 */ /*!< STM32F031x4, STM32F031x6 Devices (STM32F031xx microcontrollers where the Flash memory ranges between 16 and 32 Kbytes) */ + /* #define STM32F038xx */ /*!< STM32F038xx Devices (STM32F038xx microcontrollers where the Flash memory is 32 Kbytes) */ + /* #define STM32F042x6 */ /*!< STM32F042x4, STM32F042x6 Devices (STM32F042xx microcontrollers where the Flash memory ranges between 16 and 32 Kbytes) */ + /* #define STM32F048x6 */ /*!< STM32F048xx Devices (STM32F042xx microcontrollers where the Flash memory is 32 Kbytes) */ + /* #define STM32F051x8 */ /*!< STM32F051x4, STM32F051x6, STM32F051x8 Devices (STM32F051xx microcontrollers where the Flash memory ranges between 16 and 64 Kbytes) */ + /* #define STM32F058xx */ /*!< STM32F058xx Devices (STM32F058xx microcontrollers where the Flash memory is 64 Kbytes) */ + /* #define STM32F070x6 */ /*!< STM32F070x6 Devices (STM32F070x6 microcontrollers where the Flash memory ranges between 16 and 32 Kbytes) */ + /* #define STM32F070xB */ /*!< STM32F070xB Devices (STM32F070xB microcontrollers where the Flash memory ranges between 64 and 128 Kbytes) */ + /* #define STM32F071xB */ /*!< STM32F071x8, STM32F071xB Devices (STM32F071xx microcontrollers where the Flash memory ranges between 64 and 128 Kbytes) */ + /* #define STM32F072xB */ /*!< STM32F072x8, STM32F072xB Devices (STM32F072xx microcontrollers where the Flash memory ranges between 64 and 128 Kbytes) */ + /* #define STM32F078xx */ /*!< STM32F078xx Devices (STM32F078xx microcontrollers where the Flash memory is 128 Kbytes) */ + /* #define STM32F030xC */ /*!< STM32F030xC Devices (STM32F030xC microcontrollers where the Flash memory is 256 Kbytes) */ + /* #define STM32F091xC */ /*!< STM32F091xB, STM32F091xC Devices (STM32F091xx microcontrollers where the Flash memory ranges between 128 and 256 Kbytes) */ + /* #define STM32F098xx */ /*!< STM32F098xx Devices (STM32F098xx microcontrollers where the Flash memory is 256 Kbytes) */ +#endif + +/* Tip: To avoid modifying this file each time you need to switch between these + devices, you can define the device in your toolchain compiler preprocessor. + */ +#if !defined (USE_HAL_DRIVER) +/** + * @brief Comment the line below if you will not use the peripherals drivers. + In this case, these drivers will not be included and the application code will + be based on direct access to peripherals registers + */ + /*#define USE_HAL_DRIVER */ +#endif /* USE_HAL_DRIVER */ + +/** + * @brief CMSIS Device version number V2.3.4 + */ +#define __STM32F0_DEVICE_VERSION_MAIN (0x02) /*!< [31:24] main version */ +#define __STM32F0_DEVICE_VERSION_SUB1 (0x03) /*!< [23:16] sub1 version */ +#define __STM32F0_DEVICE_VERSION_SUB2 (0x04) /*!< [15:8] sub2 version */ +#define __STM32F0_DEVICE_VERSION_RC (0x00) /*!< [7:0] release candidate */ +#define __STM32F0_DEVICE_VERSION ((__STM32F0_DEVICE_VERSION_MAIN << 24)\ + |(__STM32F0_DEVICE_VERSION_SUB1 << 16)\ + |(__STM32F0_DEVICE_VERSION_SUB2 << 8 )\ + |(__STM32F0_DEVICE_VERSION_RC)) + +/** + * @} + */ + +/** @addtogroup Device_Included + * @{ + */ + +#if defined(STM32F030x6) + #include "stm32f030x6.h" +#elif defined(STM32F030x8) + #include "stm32f030x8.h" +#elif defined(STM32F031x6) + #include "stm32f031x6.h" +#elif defined(STM32F038xx) + #include "stm32f038xx.h" +#elif defined(STM32F042x6) + #include "stm32f042x6.h" +#elif defined(STM32F048xx) + #include "stm32f048xx.h" +#elif defined(STM32F051x8) + #include "stm32f051x8.h" +#elif defined(STM32F058xx) + #include "stm32f058xx.h" +#elif defined(STM32F070x6) + #include "stm32f070x6.h" +#elif defined(STM32F070xB) + #include "stm32f070xb.h" +#elif defined(STM32F071xB) + #include "stm32f071xb.h" +#elif defined(STM32F072xB) + #include "stm32f072xb.h" +#elif defined(STM32F078xx) + #include "stm32f078xx.h" +#elif defined(STM32F091xC) + #include "stm32f091xc.h" +#elif defined(STM32F098xx) + #include "stm32f098xx.h" +#elif defined(STM32F030xC) + #include "stm32f030xc.h" +#else + #error "Please select first the target STM32F0xx device used in your application (in stm32f0xx.h file)" +#endif + +/** + * @} + */ + +/** @addtogroup Exported_types + * @{ + */ +typedef enum +{ + RESET = 0U, + SET = !RESET +} FlagStatus, ITStatus; + +typedef enum +{ + DISABLE = 0U, + ENABLE = !DISABLE +} FunctionalState; +#define IS_FUNCTIONAL_STATE(STATE) (((STATE) == DISABLE) || ((STATE) == ENABLE)) + +typedef enum +{ + SUCCESS = 0U, + ERROR = !SUCCESS +} ErrorStatus; + +/** + * @} + */ + + +/** @addtogroup Exported_macros + * @{ + */ +#define SET_BIT(REG, BIT) ((REG) |= (BIT)) + +#define CLEAR_BIT(REG, BIT) ((REG) &= ~(BIT)) + +#define READ_BIT(REG, BIT) ((REG) & (BIT)) + +#define CLEAR_REG(REG) ((REG) = (0x0)) + +#define WRITE_REG(REG, VAL) ((REG) = (VAL)) + +#define READ_REG(REG) ((REG)) + +#define MODIFY_REG(REG, CLEARMASK, SETMASK) WRITE_REG((REG), (((READ_REG(REG)) & (~(CLEARMASK))) | (SETMASK))) + + +/** + * @} + */ + +#if defined (USE_HAL_DRIVER) + #include "stm32f0xx_hal.h" +#endif /* USE_HAL_DRIVER */ + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __STM32F0xx_H */ +/** + * @} + */ + +/** + * @} + */ + + + + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/test/STM32F072C8T6/Drivers/CMSIS/Device/ST/STM32F0xx/Include/system_stm32f0xx.h b/test/STM32F072C8T6/Drivers/CMSIS/Device/ST/STM32F0xx/Include/system_stm32f0xx.h new file mode 100644 index 0000000..fafabf4 --- /dev/null +++ b/test/STM32F072C8T6/Drivers/CMSIS/Device/ST/STM32F0xx/Include/system_stm32f0xx.h @@ -0,0 +1,105 @@ +/** + ****************************************************************************** + * @file system_stm32f0xx.h + * @author MCD Application Team + * @brief CMSIS Cortex-M0 Device System Source File for STM32F0xx devices. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2016 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/** @addtogroup CMSIS + * @{ + */ + +/** @addtogroup stm32f0xx_system + * @{ + */ + +/** + * @brief Define to prevent recursive inclusion + */ +#ifndef __SYSTEM_STM32F0XX_H +#define __SYSTEM_STM32F0XX_H + +#ifdef __cplusplus + extern "C" { +#endif + +/** @addtogroup STM32F0xx_System_Includes + * @{ + */ + +/** + * @} + */ + + +/** @addtogroup STM32F0xx_System_Exported_types + * @{ + */ + /* This variable is updated in three ways: + 1) by calling CMSIS function SystemCoreClockUpdate() + 3) by calling HAL API function HAL_RCC_GetHCLKFreq() + 3) by calling HAL API function HAL_RCC_ClockConfig() + Note: If you use this function to configure the system clock; then there + is no need to call the 2 first functions listed above, since SystemCoreClock + variable is updated automatically. + */ +extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */ +extern const uint8_t AHBPrescTable[16]; /*!< AHB prescalers table values */ +extern const uint8_t APBPrescTable[8]; /*!< APB prescalers table values */ + +/** + * @} + */ + +/** @addtogroup STM32F0xx_System_Exported_Constants + * @{ + */ + +/** + * @} + */ + +/** @addtogroup STM32F0xx_System_Exported_Macros + * @{ + */ + +/** + * @} + */ + +/** @addtogroup STM32F0xx_System_Exported_Functions + * @{ + */ + +extern void SystemInit(void); +extern void SystemCoreClockUpdate(void); +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /*__SYSTEM_STM32F0XX_H */ + +/** + * @} + */ + +/** + * @} + */ +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/test/STM32F072C8T6/Drivers/CMSIS/Include/cmsis_armcc.h b/test/STM32F072C8T6/Drivers/CMSIS/Include/cmsis_armcc.h new file mode 100644 index 0000000..7d751fb --- /dev/null +++ b/test/STM32F072C8T6/Drivers/CMSIS/Include/cmsis_armcc.h @@ -0,0 +1,865 @@ +/**************************************************************************//** + * @file cmsis_armcc.h + * @brief CMSIS compiler ARMCC (Arm Compiler 5) header file + * @version V5.0.4 + * @date 10. January 2018 + ******************************************************************************/ +/* + * Copyright (c) 2009-2018 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * 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 + * + * 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 __CMSIS_ARMCC_H +#define __CMSIS_ARMCC_H + + +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 400677) + #error "Please use Arm Compiler Toolchain V4.0.677 or later!" +#endif + +/* CMSIS compiler control architecture macros */ +#if ((defined (__TARGET_ARCH_6_M ) && (__TARGET_ARCH_6_M == 1)) || \ + (defined (__TARGET_ARCH_6S_M ) && (__TARGET_ARCH_6S_M == 1)) ) + #define __ARM_ARCH_6M__ 1 +#endif + +#if (defined (__TARGET_ARCH_7_M ) && (__TARGET_ARCH_7_M == 1)) + #define __ARM_ARCH_7M__ 1 +#endif + +#if (defined (__TARGET_ARCH_7E_M) && (__TARGET_ARCH_7E_M == 1)) + #define __ARM_ARCH_7EM__ 1 +#endif + + /* __ARM_ARCH_8M_BASE__ not applicable */ + /* __ARM_ARCH_8M_MAIN__ not applicable */ + + +/* CMSIS compiler specific defines */ +#ifndef __ASM + #define __ASM __asm +#endif +#ifndef __INLINE + #define __INLINE __inline +#endif +#ifndef __STATIC_INLINE + #define __STATIC_INLINE static __inline +#endif +#ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE static __forceinline +#endif +#ifndef __NO_RETURN + #define __NO_RETURN __declspec(noreturn) +#endif +#ifndef __USED + #define __USED __attribute__((used)) +#endif +#ifndef __WEAK + #define __WEAK __attribute__((weak)) +#endif +#ifndef __PACKED + #define __PACKED __attribute__((packed)) +#endif +#ifndef __PACKED_STRUCT + #define __PACKED_STRUCT __packed struct +#endif +#ifndef __PACKED_UNION + #define __PACKED_UNION __packed union +#endif +#ifndef __UNALIGNED_UINT32 /* deprecated */ + #define __UNALIGNED_UINT32(x) (*((__packed uint32_t *)(x))) +#endif +#ifndef __UNALIGNED_UINT16_WRITE + #define __UNALIGNED_UINT16_WRITE(addr, val) ((*((__packed uint16_t *)(addr))) = (val)) +#endif +#ifndef __UNALIGNED_UINT16_READ + #define __UNALIGNED_UINT16_READ(addr) (*((const __packed uint16_t *)(addr))) +#endif +#ifndef __UNALIGNED_UINT32_WRITE + #define __UNALIGNED_UINT32_WRITE(addr, val) ((*((__packed uint32_t *)(addr))) = (val)) +#endif +#ifndef __UNALIGNED_UINT32_READ + #define __UNALIGNED_UINT32_READ(addr) (*((const __packed uint32_t *)(addr))) +#endif +#ifndef __ALIGNED + #define __ALIGNED(x) __attribute__((aligned(x))) +#endif +#ifndef __RESTRICT + #define __RESTRICT __restrict +#endif + +/* ########################### Core Function Access ########################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions + @{ + */ + +/** + \brief Enable IRQ Interrupts + \details Enables IRQ interrupts by clearing the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +/* intrinsic void __enable_irq(); */ + + +/** + \brief Disable IRQ Interrupts + \details Disables IRQ interrupts by setting the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +/* intrinsic void __disable_irq(); */ + +/** + \brief Get Control Register + \details Returns the content of the Control Register. + \return Control Register value + */ +__STATIC_INLINE uint32_t __get_CONTROL(void) +{ + register uint32_t __regControl __ASM("control"); + return(__regControl); +} + + +/** + \brief Set Control Register + \details Writes the given value to the Control Register. + \param [in] control Control Register value to set + */ +__STATIC_INLINE void __set_CONTROL(uint32_t control) +{ + register uint32_t __regControl __ASM("control"); + __regControl = control; +} + + +/** + \brief Get IPSR Register + \details Returns the content of the IPSR Register. + \return IPSR Register value + */ +__STATIC_INLINE uint32_t __get_IPSR(void) +{ + register uint32_t __regIPSR __ASM("ipsr"); + return(__regIPSR); +} + + +/** + \brief Get APSR Register + \details Returns the content of the APSR Register. + \return APSR Register value + */ +__STATIC_INLINE uint32_t __get_APSR(void) +{ + register uint32_t __regAPSR __ASM("apsr"); + return(__regAPSR); +} + + +/** + \brief Get xPSR Register + \details Returns the content of the xPSR Register. + \return xPSR Register value + */ +__STATIC_INLINE uint32_t __get_xPSR(void) +{ + register uint32_t __regXPSR __ASM("xpsr"); + return(__regXPSR); +} + + +/** + \brief Get Process Stack Pointer + \details Returns the current value of the Process Stack Pointer (PSP). + \return PSP Register value + */ +__STATIC_INLINE uint32_t __get_PSP(void) +{ + register uint32_t __regProcessStackPointer __ASM("psp"); + return(__regProcessStackPointer); +} + + +/** + \brief Set Process Stack Pointer + \details Assigns the given value to the Process Stack Pointer (PSP). + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__STATIC_INLINE void __set_PSP(uint32_t topOfProcStack) +{ + register uint32_t __regProcessStackPointer __ASM("psp"); + __regProcessStackPointer = topOfProcStack; +} + + +/** + \brief Get Main Stack Pointer + \details Returns the current value of the Main Stack Pointer (MSP). + \return MSP Register value + */ +__STATIC_INLINE uint32_t __get_MSP(void) +{ + register uint32_t __regMainStackPointer __ASM("msp"); + return(__regMainStackPointer); +} + + +/** + \brief Set Main Stack Pointer + \details Assigns the given value to the Main Stack Pointer (MSP). + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__STATIC_INLINE void __set_MSP(uint32_t topOfMainStack) +{ + register uint32_t __regMainStackPointer __ASM("msp"); + __regMainStackPointer = topOfMainStack; +} + + +/** + \brief Get Priority Mask + \details Returns the current state of the priority mask bit from the Priority Mask Register. + \return Priority Mask value + */ +__STATIC_INLINE uint32_t __get_PRIMASK(void) +{ + register uint32_t __regPriMask __ASM("primask"); + return(__regPriMask); +} + + +/** + \brief Set Priority Mask + \details Assigns the given value to the Priority Mask Register. + \param [in] priMask Priority Mask + */ +__STATIC_INLINE void __set_PRIMASK(uint32_t priMask) +{ + register uint32_t __regPriMask __ASM("primask"); + __regPriMask = (priMask); +} + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) + +/** + \brief Enable FIQ + \details Enables FIQ interrupts by clearing the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +#define __enable_fault_irq __enable_fiq + + +/** + \brief Disable FIQ + \details Disables FIQ interrupts by setting the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +#define __disable_fault_irq __disable_fiq + + +/** + \brief Get Base Priority + \details Returns the current value of the Base Priority register. + \return Base Priority register value + */ +__STATIC_INLINE uint32_t __get_BASEPRI(void) +{ + register uint32_t __regBasePri __ASM("basepri"); + return(__regBasePri); +} + + +/** + \brief Set Base Priority + \details Assigns the given value to the Base Priority register. + \param [in] basePri Base Priority value to set + */ +__STATIC_INLINE void __set_BASEPRI(uint32_t basePri) +{ + register uint32_t __regBasePri __ASM("basepri"); + __regBasePri = (basePri & 0xFFU); +} + + +/** + \brief Set Base Priority with condition + \details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled, + or the new value increases the BASEPRI priority level. + \param [in] basePri Base Priority value to set + */ +__STATIC_INLINE void __set_BASEPRI_MAX(uint32_t basePri) +{ + register uint32_t __regBasePriMax __ASM("basepri_max"); + __regBasePriMax = (basePri & 0xFFU); +} + + +/** + \brief Get Fault Mask + \details Returns the current value of the Fault Mask register. + \return Fault Mask register value + */ +__STATIC_INLINE uint32_t __get_FAULTMASK(void) +{ + register uint32_t __regFaultMask __ASM("faultmask"); + return(__regFaultMask); +} + + +/** + \brief Set Fault Mask + \details Assigns the given value to the Fault Mask register. + \param [in] faultMask Fault Mask value to set + */ +__STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask) +{ + register uint32_t __regFaultMask __ASM("faultmask"); + __regFaultMask = (faultMask & (uint32_t)1U); +} + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */ + + +/** + \brief Get FPSCR + \details Returns the current value of the Floating Point Status/Control register. + \return Floating Point Status/Control register value + */ +__STATIC_INLINE uint32_t __get_FPSCR(void) +{ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) + register uint32_t __regfpscr __ASM("fpscr"); + return(__regfpscr); +#else + return(0U); +#endif +} + + +/** + \brief Set FPSCR + \details Assigns the given value to the Floating Point Status/Control register. + \param [in] fpscr Floating Point Status/Control value to set + */ +__STATIC_INLINE void __set_FPSCR(uint32_t fpscr) +{ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) + register uint32_t __regfpscr __ASM("fpscr"); + __regfpscr = (fpscr); +#else + (void)fpscr; +#endif +} + + +/*@} end of CMSIS_Core_RegAccFunctions */ + + +/* ########################## Core Instruction Access ######################### */ +/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface + Access to dedicated instructions + @{ +*/ + +/** + \brief No Operation + \details No Operation does nothing. This instruction can be used for code alignment purposes. + */ +#define __NOP __nop + + +/** + \brief Wait For Interrupt + \details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs. + */ +#define __WFI __wfi + + +/** + \brief Wait For Event + \details Wait For Event is a hint instruction that permits the processor to enter + a low-power state until one of a number of events occurs. + */ +#define __WFE __wfe + + +/** + \brief Send Event + \details Send Event is a hint instruction. It causes an event to be signaled to the CPU. + */ +#define __SEV __sev + + +/** + \brief Instruction Synchronization Barrier + \details Instruction Synchronization Barrier flushes the pipeline in the processor, + so that all instructions following the ISB are fetched from cache or memory, + after the instruction has been completed. + */ +#define __ISB() do {\ + __schedule_barrier();\ + __isb(0xF);\ + __schedule_barrier();\ + } while (0U) + +/** + \brief Data Synchronization Barrier + \details Acts as a special kind of Data Memory Barrier. + It completes when all explicit memory accesses before this instruction complete. + */ +#define __DSB() do {\ + __schedule_barrier();\ + __dsb(0xF);\ + __schedule_barrier();\ + } while (0U) + +/** + \brief Data Memory Barrier + \details Ensures the apparent order of the explicit memory operations before + and after the instruction, without ensuring their completion. + */ +#define __DMB() do {\ + __schedule_barrier();\ + __dmb(0xF);\ + __schedule_barrier();\ + } while (0U) + + +/** + \brief Reverse byte order (32 bit) + \details Reverses the byte order in unsigned integer value. For example, 0x12345678 becomes 0x78563412. + \param [in] value Value to reverse + \return Reversed value + */ +#define __REV __rev + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order within each halfword of a word. For example, 0x12345678 becomes 0x34127856. + \param [in] value Value to reverse + \return Reversed value + */ +#ifndef __NO_EMBEDDED_ASM +__attribute__((section(".rev16_text"))) __STATIC_INLINE __ASM uint32_t __REV16(uint32_t value) +{ + rev16 r0, r0 + bx lr +} +#endif + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order in a 16-bit value and returns the signed 16-bit result. For example, 0x0080 becomes 0x8000. + \param [in] value Value to reverse + \return Reversed value + */ +#ifndef __NO_EMBEDDED_ASM +__attribute__((section(".revsh_text"))) __STATIC_INLINE __ASM int16_t __REVSH(int16_t value) +{ + revsh r0, r0 + bx lr +} +#endif + + +/** + \brief Rotate Right in unsigned value (32 bit) + \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. + \param [in] op1 Value to rotate + \param [in] op2 Number of Bits to rotate + \return Rotated value + */ +#define __ROR __ror + + +/** + \brief Breakpoint + \details Causes the processor to enter Debug state. + Debug tools can use this to investigate system state when the instruction at a particular address is reached. + \param [in] value is ignored by the processor. + If required, a debugger can use it to store additional information about the breakpoint. + */ +#define __BKPT(value) __breakpoint(value) + + +/** + \brief Reverse bit order of value + \details Reverses the bit order of the given value. + \param [in] value Value to reverse + \return Reversed value + */ +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) + #define __RBIT __rbit +#else +__attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value) +{ + uint32_t result; + uint32_t s = (4U /*sizeof(v)*/ * 8U) - 1U; /* extra shift needed at end */ + + result = value; /* r will be reversed bits of v; first get LSB of v */ + for (value >>= 1U; value != 0U; value >>= 1U) + { + result <<= 1U; + result |= value & 1U; + s--; + } + result <<= s; /* shift when v's highest bits are zero */ + return result; +} +#endif + + +/** + \brief Count leading zeros + \details Counts the number of leading zeros of a data value. + \param [in] value Value to count the leading zeros + \return number of leading zeros in value + */ +#define __CLZ __clz + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) + +/** + \brief LDR Exclusive (8 bit) + \details Executes a exclusive LDR instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __LDREXB(ptr) ((uint8_t ) __ldrex(ptr)) +#else + #define __LDREXB(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint8_t ) __ldrex(ptr)) _Pragma("pop") +#endif + + +/** + \brief LDR Exclusive (16 bit) + \details Executes a exclusive LDR instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __LDREXH(ptr) ((uint16_t) __ldrex(ptr)) +#else + #define __LDREXH(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint16_t) __ldrex(ptr)) _Pragma("pop") +#endif + + +/** + \brief LDR Exclusive (32 bit) + \details Executes a exclusive LDR instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __LDREXW(ptr) ((uint32_t ) __ldrex(ptr)) +#else + #define __LDREXW(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint32_t ) __ldrex(ptr)) _Pragma("pop") +#endif + + +/** + \brief STR Exclusive (8 bit) + \details Executes a exclusive STR instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __STREXB(value, ptr) __strex(value, ptr) +#else + #define __STREXB(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop") +#endif + + +/** + \brief STR Exclusive (16 bit) + \details Executes a exclusive STR instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __STREXH(value, ptr) __strex(value, ptr) +#else + #define __STREXH(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop") +#endif + + +/** + \brief STR Exclusive (32 bit) + \details Executes a exclusive STR instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __STREXW(value, ptr) __strex(value, ptr) +#else + #define __STREXW(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop") +#endif + + +/** + \brief Remove the exclusive lock + \details Removes the exclusive lock which is created by LDREX. + */ +#define __CLREX __clrex + + +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +#define __SSAT __ssat + + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +#define __USAT __usat + + +/** + \brief Rotate Right with Extend (32 bit) + \details Moves each bit of a bitstring right by one bit. + The carry input is shifted in at the left end of the bitstring. + \param [in] value Value to rotate + \return Rotated value + */ +#ifndef __NO_EMBEDDED_ASM +__attribute__((section(".rrx_text"))) __STATIC_INLINE __ASM uint32_t __RRX(uint32_t value) +{ + rrx r0, r0 + bx lr +} +#endif + + +/** + \brief LDRT Unprivileged (8 bit) + \details Executes a Unprivileged LDRT instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +#define __LDRBT(ptr) ((uint8_t ) __ldrt(ptr)) + + +/** + \brief LDRT Unprivileged (16 bit) + \details Executes a Unprivileged LDRT instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +#define __LDRHT(ptr) ((uint16_t) __ldrt(ptr)) + + +/** + \brief LDRT Unprivileged (32 bit) + \details Executes a Unprivileged LDRT instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +#define __LDRT(ptr) ((uint32_t ) __ldrt(ptr)) + + +/** + \brief STRT Unprivileged (8 bit) + \details Executes a Unprivileged STRT instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +#define __STRBT(value, ptr) __strt(value, ptr) + + +/** + \brief STRT Unprivileged (16 bit) + \details Executes a Unprivileged STRT instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +#define __STRHT(value, ptr) __strt(value, ptr) + + +/** + \brief STRT Unprivileged (32 bit) + \details Executes a Unprivileged STRT instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +#define __STRT(value, ptr) __strt(value, ptr) + +#else /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */ + +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +__attribute__((always_inline)) __STATIC_INLINE int32_t __SSAT(int32_t val, uint32_t sat) +{ + if ((sat >= 1U) && (sat <= 32U)) + { + const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U); + const int32_t min = -1 - max ; + if (val > max) + { + return max; + } + else if (val < min) + { + return min; + } + } + return val; +} + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __USAT(int32_t val, uint32_t sat) +{ + if (sat <= 31U) + { + const uint32_t max = ((1U << sat) - 1U); + if (val > (int32_t)max) + { + return max; + } + else if (val < 0) + { + return 0U; + } + } + return (uint32_t)val; +} + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */ + +/*@}*/ /* end of group CMSIS_Core_InstructionInterface */ + + +/* ################### Compiler specific Intrinsics ########################### */ +/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics + Access to dedicated SIMD instructions + @{ +*/ + +#if ((defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) + +#define __SADD8 __sadd8 +#define __QADD8 __qadd8 +#define __SHADD8 __shadd8 +#define __UADD8 __uadd8 +#define __UQADD8 __uqadd8 +#define __UHADD8 __uhadd8 +#define __SSUB8 __ssub8 +#define __QSUB8 __qsub8 +#define __SHSUB8 __shsub8 +#define __USUB8 __usub8 +#define __UQSUB8 __uqsub8 +#define __UHSUB8 __uhsub8 +#define __SADD16 __sadd16 +#define __QADD16 __qadd16 +#define __SHADD16 __shadd16 +#define __UADD16 __uadd16 +#define __UQADD16 __uqadd16 +#define __UHADD16 __uhadd16 +#define __SSUB16 __ssub16 +#define __QSUB16 __qsub16 +#define __SHSUB16 __shsub16 +#define __USUB16 __usub16 +#define __UQSUB16 __uqsub16 +#define __UHSUB16 __uhsub16 +#define __SASX __sasx +#define __QASX __qasx +#define __SHASX __shasx +#define __UASX __uasx +#define __UQASX __uqasx +#define __UHASX __uhasx +#define __SSAX __ssax +#define __QSAX __qsax +#define __SHSAX __shsax +#define __USAX __usax +#define __UQSAX __uqsax +#define __UHSAX __uhsax +#define __USAD8 __usad8 +#define __USADA8 __usada8 +#define __SSAT16 __ssat16 +#define __USAT16 __usat16 +#define __UXTB16 __uxtb16 +#define __UXTAB16 __uxtab16 +#define __SXTB16 __sxtb16 +#define __SXTAB16 __sxtab16 +#define __SMUAD __smuad +#define __SMUADX __smuadx +#define __SMLAD __smlad +#define __SMLADX __smladx +#define __SMLALD __smlald +#define __SMLALDX __smlaldx +#define __SMUSD __smusd +#define __SMUSDX __smusdx +#define __SMLSD __smlsd +#define __SMLSDX __smlsdx +#define __SMLSLD __smlsld +#define __SMLSLDX __smlsldx +#define __SEL __sel +#define __QADD __qadd +#define __QSUB __qsub + +#define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \ + ((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) ) + +#define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \ + ((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) ) + +#define __SMMLA(ARG1,ARG2,ARG3) ( (int32_t)((((int64_t)(ARG1) * (ARG2)) + \ + ((int64_t)(ARG3) << 32U) ) >> 32U)) + +#endif /* ((defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */ +/*@} end of group CMSIS_SIMD_intrinsics */ + + +#endif /* __CMSIS_ARMCC_H */ diff --git a/test/STM32F072C8T6/Drivers/CMSIS/Include/cmsis_armclang.h b/test/STM32F072C8T6/Drivers/CMSIS/Include/cmsis_armclang.h new file mode 100644 index 0000000..d8031b0 --- /dev/null +++ b/test/STM32F072C8T6/Drivers/CMSIS/Include/cmsis_armclang.h @@ -0,0 +1,1869 @@ +/**************************************************************************//** + * @file cmsis_armclang.h + * @brief CMSIS compiler armclang (Arm Compiler 6) header file + * @version V5.0.4 + * @date 10. January 2018 + ******************************************************************************/ +/* + * Copyright (c) 2009-2018 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * 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 + * + * 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. + */ + +/*lint -esym(9058, IRQn)*/ /* disable MISRA 2012 Rule 2.4 for IRQn */ + +#ifndef __CMSIS_ARMCLANG_H +#define __CMSIS_ARMCLANG_H + +#pragma clang system_header /* treat file as system include file */ + +#ifndef __ARM_COMPAT_H +#include /* Compatibility header for Arm Compiler 5 intrinsics */ +#endif + +/* CMSIS compiler specific defines */ +#ifndef __ASM + #define __ASM __asm +#endif +#ifndef __INLINE + #define __INLINE __inline +#endif +#ifndef __STATIC_INLINE + #define __STATIC_INLINE static __inline +#endif +#ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __attribute__((always_inline)) static __inline +#endif +#ifndef __NO_RETURN + #define __NO_RETURN __attribute__((__noreturn__)) +#endif +#ifndef __USED + #define __USED __attribute__((used)) +#endif +#ifndef __WEAK + #define __WEAK __attribute__((weak)) +#endif +#ifndef __PACKED + #define __PACKED __attribute__((packed, aligned(1))) +#endif +#ifndef __PACKED_STRUCT + #define __PACKED_STRUCT struct __attribute__((packed, aligned(1))) +#endif +#ifndef __PACKED_UNION + #define __PACKED_UNION union __attribute__((packed, aligned(1))) +#endif +#ifndef __UNALIGNED_UINT32 /* deprecated */ + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT32)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32 */ + struct __attribute__((packed)) T_UINT32 { uint32_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) +#endif +#ifndef __UNALIGNED_UINT16_WRITE + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT16_WRITE)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT16_WRITE */ + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) +#endif +#ifndef __UNALIGNED_UINT16_READ + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT16_READ)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT16_READ */ + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) +#endif +#ifndef __UNALIGNED_UINT32_WRITE + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT32_WRITE)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32_WRITE */ + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) +#endif +#ifndef __UNALIGNED_UINT32_READ + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT32_READ)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32_READ */ + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) +#endif +#ifndef __ALIGNED + #define __ALIGNED(x) __attribute__((aligned(x))) +#endif +#ifndef __RESTRICT + #define __RESTRICT __restrict +#endif + + +/* ########################### Core Function Access ########################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions + @{ + */ + +/** + \brief Enable IRQ Interrupts + \details Enables IRQ interrupts by clearing the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +/* intrinsic void __enable_irq(); see arm_compat.h */ + + +/** + \brief Disable IRQ Interrupts + \details Disables IRQ interrupts by setting the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +/* intrinsic void __disable_irq(); see arm_compat.h */ + + +/** + \brief Get Control Register + \details Returns the content of the Control Register. + \return Control Register value + */ +__STATIC_FORCEINLINE uint32_t __get_CONTROL(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, control" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Control Register (non-secure) + \details Returns the content of the non-secure Control Register when in secure mode. + \return non-secure Control Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_CONTROL_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, control_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Control Register + \details Writes the given value to the Control Register. + \param [in] control Control Register value to set + */ +__STATIC_FORCEINLINE void __set_CONTROL(uint32_t control) +{ + __ASM volatile ("MSR control, %0" : : "r" (control) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Control Register (non-secure) + \details Writes the given value to the non-secure Control Register when in secure state. + \param [in] control Control Register value to set + */ +__STATIC_FORCEINLINE void __TZ_set_CONTROL_NS(uint32_t control) +{ + __ASM volatile ("MSR control_ns, %0" : : "r" (control) : "memory"); +} +#endif + + +/** + \brief Get IPSR Register + \details Returns the content of the IPSR Register. + \return IPSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_IPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, ipsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get APSR Register + \details Returns the content of the APSR Register. + \return APSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_APSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, apsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get xPSR Register + \details Returns the content of the xPSR Register. + \return xPSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_xPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, xpsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get Process Stack Pointer + \details Returns the current value of the Process Stack Pointer (PSP). + \return PSP Register value + */ +__STATIC_FORCEINLINE uint32_t __get_PSP(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, psp" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Process Stack Pointer (non-secure) + \details Returns the current value of the non-secure Process Stack Pointer (PSP) when in secure state. + \return PSP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PSP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, psp_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Process Stack Pointer + \details Assigns the given value to the Process Stack Pointer (PSP). + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __set_PSP(uint32_t topOfProcStack) +{ + __ASM volatile ("MSR psp, %0" : : "r" (topOfProcStack) : ); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Process Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Process Stack Pointer (PSP) when in secure state. + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_PSP_NS(uint32_t topOfProcStack) +{ + __ASM volatile ("MSR psp_ns, %0" : : "r" (topOfProcStack) : ); +} +#endif + + +/** + \brief Get Main Stack Pointer + \details Returns the current value of the Main Stack Pointer (MSP). + \return MSP Register value + */ +__STATIC_FORCEINLINE uint32_t __get_MSP(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, msp" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Main Stack Pointer (non-secure) + \details Returns the current value of the non-secure Main Stack Pointer (MSP) when in secure state. + \return MSP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_MSP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, msp_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Main Stack Pointer + \details Assigns the given value to the Main Stack Pointer (MSP). + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __set_MSP(uint32_t topOfMainStack) +{ + __ASM volatile ("MSR msp, %0" : : "r" (topOfMainStack) : ); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Main Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Main Stack Pointer (MSP) when in secure state. + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_MSP_NS(uint32_t topOfMainStack) +{ + __ASM volatile ("MSR msp_ns, %0" : : "r" (topOfMainStack) : ); +} +#endif + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Stack Pointer (non-secure) + \details Returns the current value of the non-secure Stack Pointer (SP) when in secure state. + \return SP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_SP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, sp_ns" : "=r" (result) ); + return(result); +} + + +/** + \brief Set Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Stack Pointer (SP) when in secure state. + \param [in] topOfStack Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_SP_NS(uint32_t topOfStack) +{ + __ASM volatile ("MSR sp_ns, %0" : : "r" (topOfStack) : ); +} +#endif + + +/** + \brief Get Priority Mask + \details Returns the current state of the priority mask bit from the Priority Mask Register. + \return Priority Mask value + */ +__STATIC_FORCEINLINE uint32_t __get_PRIMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, primask" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Priority Mask (non-secure) + \details Returns the current state of the non-secure priority mask bit from the Priority Mask Register when in secure state. + \return Priority Mask value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PRIMASK_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, primask_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Priority Mask + \details Assigns the given value to the Priority Mask Register. + \param [in] priMask Priority Mask + */ +__STATIC_FORCEINLINE void __set_PRIMASK(uint32_t priMask) +{ + __ASM volatile ("MSR primask, %0" : : "r" (priMask) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Priority Mask (non-secure) + \details Assigns the given value to the non-secure Priority Mask Register when in secure state. + \param [in] priMask Priority Mask + */ +__STATIC_FORCEINLINE void __TZ_set_PRIMASK_NS(uint32_t priMask) +{ + __ASM volatile ("MSR primask_ns, %0" : : "r" (priMask) : "memory"); +} +#endif + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) +/** + \brief Enable FIQ + \details Enables FIQ interrupts by clearing the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +#define __enable_fault_irq __enable_fiq /* see arm_compat.h */ + + +/** + \brief Disable FIQ + \details Disables FIQ interrupts by setting the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +#define __disable_fault_irq __disable_fiq /* see arm_compat.h */ + + +/** + \brief Get Base Priority + \details Returns the current value of the Base Priority register. + \return Base Priority register value + */ +__STATIC_FORCEINLINE uint32_t __get_BASEPRI(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, basepri" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Base Priority (non-secure) + \details Returns the current value of the non-secure Base Priority register when in secure state. + \return Base Priority register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_BASEPRI_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, basepri_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Base Priority + \details Assigns the given value to the Base Priority register. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __set_BASEPRI(uint32_t basePri) +{ + __ASM volatile ("MSR basepri, %0" : : "r" (basePri) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Base Priority (non-secure) + \details Assigns the given value to the non-secure Base Priority register when in secure state. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __TZ_set_BASEPRI_NS(uint32_t basePri) +{ + __ASM volatile ("MSR basepri_ns, %0" : : "r" (basePri) : "memory"); +} +#endif + + +/** + \brief Set Base Priority with condition + \details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled, + or the new value increases the BASEPRI priority level. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __set_BASEPRI_MAX(uint32_t basePri) +{ + __ASM volatile ("MSR basepri_max, %0" : : "r" (basePri) : "memory"); +} + + +/** + \brief Get Fault Mask + \details Returns the current value of the Fault Mask register. + \return Fault Mask register value + */ +__STATIC_FORCEINLINE uint32_t __get_FAULTMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, faultmask" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Fault Mask (non-secure) + \details Returns the current value of the non-secure Fault Mask register when in secure state. + \return Fault Mask register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_FAULTMASK_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, faultmask_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Fault Mask + \details Assigns the given value to the Fault Mask register. + \param [in] faultMask Fault Mask value to set + */ +__STATIC_FORCEINLINE void __set_FAULTMASK(uint32_t faultMask) +{ + __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Fault Mask (non-secure) + \details Assigns the given value to the non-secure Fault Mask register when in secure state. + \param [in] faultMask Fault Mask value to set + */ +__STATIC_FORCEINLINE void __TZ_set_FAULTMASK_NS(uint32_t faultMask) +{ + __ASM volatile ("MSR faultmask_ns, %0" : : "r" (faultMask) : "memory"); +} +#endif + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) + +/** + \brief Get Process Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always in non-secure + mode. + + \details Returns the current value of the Process Stack Pointer Limit (PSPLIM). + \return PSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __get_PSPLIM(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, psplim" : "=r" (result) ); + return result; +#endif +} + +#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Process Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always in non-secure + mode. + + \details Returns the current value of the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. + \return PSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PSPLIM_NS(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, psplim_ns" : "=r" (result) ); + return result; +#endif +} +#endif + + +/** + \brief Set Process Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored in non-secure + mode. + + \details Assigns the given value to the Process Stack Pointer Limit (PSPLIM). + \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __set_PSPLIM(uint32_t ProcStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)ProcStackPtrLimit; +#else + __ASM volatile ("MSR psplim, %0" : : "r" (ProcStackPtrLimit)); +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Process Stack Pointer (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored in non-secure + mode. + + \details Assigns the given value to the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. + \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __TZ_set_PSPLIM_NS(uint32_t ProcStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)ProcStackPtrLimit; +#else + __ASM volatile ("MSR psplim_ns, %0\n" : : "r" (ProcStackPtrLimit)); +#endif +} +#endif + + +/** + \brief Get Main Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always. + + \details Returns the current value of the Main Stack Pointer Limit (MSPLIM). + \return MSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __get_MSPLIM(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, msplim" : "=r" (result) ); + return result; +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Main Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always. + + \details Returns the current value of the non-secure Main Stack Pointer Limit(MSPLIM) when in secure state. + \return MSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_MSPLIM_NS(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, msplim_ns" : "=r" (result) ); + return result; +#endif +} +#endif + + +/** + \brief Set Main Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored. + + \details Assigns the given value to the Main Stack Pointer Limit (MSPLIM). + \param [in] MainStackPtrLimit Main Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __set_MSPLIM(uint32_t MainStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + (void)MainStackPtrLimit; +#else + __ASM volatile ("MSR msplim, %0" : : "r" (MainStackPtrLimit)); +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Main Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored. + + \details Assigns the given value to the non-secure Main Stack Pointer Limit (MSPLIM) when in secure state. + \param [in] MainStackPtrLimit Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_MSPLIM_NS(uint32_t MainStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + (void)MainStackPtrLimit; +#else + __ASM volatile ("MSR msplim_ns, %0" : : "r" (MainStackPtrLimit)); +#endif +} +#endif + +#endif /* ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + +/** + \brief Get FPSCR + \details Returns the current value of the Floating Point Status/Control register. + \return Floating Point Status/Control register value + */ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) +#define __get_FPSCR (uint32_t)__builtin_arm_get_fpscr +#else +#define __get_FPSCR() ((uint32_t)0U) +#endif + +/** + \brief Set FPSCR + \details Assigns the given value to the Floating Point Status/Control register. + \param [in] fpscr Floating Point Status/Control value to set + */ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) +#define __set_FPSCR __builtin_arm_set_fpscr +#else +#define __set_FPSCR(x) ((void)(x)) +#endif + + +/*@} end of CMSIS_Core_RegAccFunctions */ + + +/* ########################## Core Instruction Access ######################### */ +/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface + Access to dedicated instructions + @{ +*/ + +/* Define macros for porting to both thumb1 and thumb2. + * For thumb1, use low register (r0-r7), specified by constraint "l" + * Otherwise, use general registers, specified by constraint "r" */ +#if defined (__thumb__) && !defined (__thumb2__) +#define __CMSIS_GCC_OUT_REG(r) "=l" (r) +#define __CMSIS_GCC_USE_REG(r) "l" (r) +#else +#define __CMSIS_GCC_OUT_REG(r) "=r" (r) +#define __CMSIS_GCC_USE_REG(r) "r" (r) +#endif + +/** + \brief No Operation + \details No Operation does nothing. This instruction can be used for code alignment purposes. + */ +#define __NOP __builtin_arm_nop + +/** + \brief Wait For Interrupt + \details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs. + */ +#define __WFI __builtin_arm_wfi + + +/** + \brief Wait For Event + \details Wait For Event is a hint instruction that permits the processor to enter + a low-power state until one of a number of events occurs. + */ +#define __WFE __builtin_arm_wfe + + +/** + \brief Send Event + \details Send Event is a hint instruction. It causes an event to be signaled to the CPU. + */ +#define __SEV __builtin_arm_sev + + +/** + \brief Instruction Synchronization Barrier + \details Instruction Synchronization Barrier flushes the pipeline in the processor, + so that all instructions following the ISB are fetched from cache or memory, + after the instruction has been completed. + */ +#define __ISB() __builtin_arm_isb(0xF); + +/** + \brief Data Synchronization Barrier + \details Acts as a special kind of Data Memory Barrier. + It completes when all explicit memory accesses before this instruction complete. + */ +#define __DSB() __builtin_arm_dsb(0xF); + + +/** + \brief Data Memory Barrier + \details Ensures the apparent order of the explicit memory operations before + and after the instruction, without ensuring their completion. + */ +#define __DMB() __builtin_arm_dmb(0xF); + + +/** + \brief Reverse byte order (32 bit) + \details Reverses the byte order in unsigned integer value. For example, 0x12345678 becomes 0x78563412. + \param [in] value Value to reverse + \return Reversed value + */ +#define __REV(value) __builtin_bswap32(value) + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order within each halfword of a word. For example, 0x12345678 becomes 0x34127856. + \param [in] value Value to reverse + \return Reversed value + */ +#define __REV16(value) __ROR(__REV(value), 16) + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order in a 16-bit value and returns the signed 16-bit result. For example, 0x0080 becomes 0x8000. + \param [in] value Value to reverse + \return Reversed value + */ +#define __REVSH(value) (int16_t)__builtin_bswap16(value) + + +/** + \brief Rotate Right in unsigned value (32 bit) + \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. + \param [in] op1 Value to rotate + \param [in] op2 Number of Bits to rotate + \return Rotated value + */ +__STATIC_FORCEINLINE uint32_t __ROR(uint32_t op1, uint32_t op2) +{ + op2 %= 32U; + if (op2 == 0U) + { + return op1; + } + return (op1 >> op2) | (op1 << (32U - op2)); +} + + +/** + \brief Breakpoint + \details Causes the processor to enter Debug state. + Debug tools can use this to investigate system state when the instruction at a particular address is reached. + \param [in] value is ignored by the processor. + If required, a debugger can use it to store additional information about the breakpoint. + */ +#define __BKPT(value) __ASM volatile ("bkpt "#value) + + +/** + \brief Reverse bit order of value + \details Reverses the bit order of the given value. + \param [in] value Value to reverse + \return Reversed value + */ +#define __RBIT __builtin_arm_rbit + +/** + \brief Count leading zeros + \details Counts the number of leading zeros of a data value. + \param [in] value Value to count the leading zeros + \return number of leading zeros in value + */ +#define __CLZ (uint8_t)__builtin_clz + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) +/** + \brief LDR Exclusive (8 bit) + \details Executes a exclusive LDR instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +#define __LDREXB (uint8_t)__builtin_arm_ldrex + + +/** + \brief LDR Exclusive (16 bit) + \details Executes a exclusive LDR instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +#define __LDREXH (uint16_t)__builtin_arm_ldrex + + +/** + \brief LDR Exclusive (32 bit) + \details Executes a exclusive LDR instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +#define __LDREXW (uint32_t)__builtin_arm_ldrex + + +/** + \brief STR Exclusive (8 bit) + \details Executes a exclusive STR instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STREXB (uint32_t)__builtin_arm_strex + + +/** + \brief STR Exclusive (16 bit) + \details Executes a exclusive STR instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STREXH (uint32_t)__builtin_arm_strex + + +/** + \brief STR Exclusive (32 bit) + \details Executes a exclusive STR instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STREXW (uint32_t)__builtin_arm_strex + + +/** + \brief Remove the exclusive lock + \details Removes the exclusive lock which is created by LDREX. + */ +#define __CLREX __builtin_arm_clrex + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) + +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +#define __SSAT __builtin_arm_ssat + + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +#define __USAT __builtin_arm_usat + + +/** + \brief Rotate Right with Extend (32 bit) + \details Moves each bit of a bitstring right by one bit. + The carry input is shifted in at the left end of the bitstring. + \param [in] value Value to rotate + \return Rotated value + */ +__STATIC_FORCEINLINE uint32_t __RRX(uint32_t value) +{ + uint32_t result; + + __ASM volatile ("rrx %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return(result); +} + + +/** + \brief LDRT Unprivileged (8 bit) + \details Executes a Unprivileged LDRT instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDRBT(volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldrbt %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint8_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDRT Unprivileged (16 bit) + \details Executes a Unprivileged LDRT instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDRHT(volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldrht %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint16_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDRT Unprivileged (32 bit) + \details Executes a Unprivileged LDRT instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDRT(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldrt %0, %1" : "=r" (result) : "Q" (*ptr) ); + return(result); +} + + +/** + \brief STRT Unprivileged (8 bit) + \details Executes a Unprivileged STRT instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRBT(uint8_t value, volatile uint8_t *ptr) +{ + __ASM volatile ("strbt %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief STRT Unprivileged (16 bit) + \details Executes a Unprivileged STRT instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRHT(uint16_t value, volatile uint16_t *ptr) +{ + __ASM volatile ("strht %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief STRT Unprivileged (32 bit) + \details Executes a Unprivileged STRT instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRT(uint32_t value, volatile uint32_t *ptr) +{ + __ASM volatile ("strt %1, %0" : "=Q" (*ptr) : "r" (value) ); +} + +#else /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +__STATIC_FORCEINLINE int32_t __SSAT(int32_t val, uint32_t sat) +{ + if ((sat >= 1U) && (sat <= 32U)) + { + const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U); + const int32_t min = -1 - max ; + if (val > max) + { + return max; + } + else if (val < min) + { + return min; + } + } + return val; +} + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +__STATIC_FORCEINLINE uint32_t __USAT(int32_t val, uint32_t sat) +{ + if (sat <= 31U) + { + const uint32_t max = ((1U << sat) - 1U); + if (val > (int32_t)max) + { + return max; + } + else if (val < 0) + { + return 0U; + } + } + return (uint32_t)val; +} + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) +/** + \brief Load-Acquire (8 bit) + \details Executes a LDAB instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDAB(volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldab %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint8_t) result); +} + + +/** + \brief Load-Acquire (16 bit) + \details Executes a LDAH instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDAH(volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldah %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint16_t) result); +} + + +/** + \brief Load-Acquire (32 bit) + \details Executes a LDA instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDA(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("lda %0, %1" : "=r" (result) : "Q" (*ptr) ); + return(result); +} + + +/** + \brief Store-Release (8 bit) + \details Executes a STLB instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STLB(uint8_t value, volatile uint8_t *ptr) +{ + __ASM volatile ("stlb %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief Store-Release (16 bit) + \details Executes a STLH instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STLH(uint16_t value, volatile uint16_t *ptr) +{ + __ASM volatile ("stlh %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief Store-Release (32 bit) + \details Executes a STL instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STL(uint32_t value, volatile uint32_t *ptr) +{ + __ASM volatile ("stl %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief Load-Acquire Exclusive (8 bit) + \details Executes a LDAB exclusive instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +#define __LDAEXB (uint8_t)__builtin_arm_ldaex + + +/** + \brief Load-Acquire Exclusive (16 bit) + \details Executes a LDAH exclusive instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +#define __LDAEXH (uint16_t)__builtin_arm_ldaex + + +/** + \brief Load-Acquire Exclusive (32 bit) + \details Executes a LDA exclusive instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +#define __LDAEX (uint32_t)__builtin_arm_ldaex + + +/** + \brief Store-Release Exclusive (8 bit) + \details Executes a STLB exclusive instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STLEXB (uint32_t)__builtin_arm_stlex + + +/** + \brief Store-Release Exclusive (16 bit) + \details Executes a STLH exclusive instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STLEXH (uint32_t)__builtin_arm_stlex + + +/** + \brief Store-Release Exclusive (32 bit) + \details Executes a STL exclusive instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STLEX (uint32_t)__builtin_arm_stlex + +#endif /* ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + +/*@}*/ /* end of group CMSIS_Core_InstructionInterface */ + + +/* ################### Compiler specific Intrinsics ########################### */ +/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics + Access to dedicated SIMD instructions + @{ +*/ + +#if (defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1)) + +__STATIC_FORCEINLINE uint32_t __SADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + + +__STATIC_FORCEINLINE uint32_t __SSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + + +__STATIC_FORCEINLINE uint32_t __SADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USAD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usad8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USADA8(uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("usada8 %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +#define __SSAT16(ARG1,ARG2) \ +({ \ + int32_t __RES, __ARG1 = (ARG1); \ + __ASM ("ssat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + +#define __USAT16(ARG1,ARG2) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1); \ + __ASM ("usat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + +__STATIC_FORCEINLINE uint32_t __UXTB16(uint32_t op1) +{ + uint32_t result; + + __ASM volatile ("uxtb16 %0, %1" : "=r" (result) : "r" (op1)); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UXTAB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SXTB16(uint32_t op1) +{ + uint32_t result; + + __ASM volatile ("sxtb16 %0, %1" : "=r" (result) : "r" (op1)); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SXTAB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMUAD (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smuad %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMUADX (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smuadx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLAD (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlad %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLADX (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smladx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint64_t __SMLALD (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint64_t __SMLALDX (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint32_t __SMUSD (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smusd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMUSDX (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smusdx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLSD (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlsd %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLSDX (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlsdx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint64_t __SMLSLD (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint64_t __SMLSLDX (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint32_t __SEL (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sel %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE int32_t __QADD( int32_t op1, int32_t op2) +{ + int32_t result; + + __ASM volatile ("qadd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE int32_t __QSUB( int32_t op1, int32_t op2) +{ + int32_t result; + + __ASM volatile ("qsub %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +#if 0 +#define __PKHBT(ARG1,ARG2,ARG3) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \ + __ASM ("pkhbt %0, %1, %2, lsl %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \ + __RES; \ + }) + +#define __PKHTB(ARG1,ARG2,ARG3) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \ + if (ARG3 == 0) \ + __ASM ("pkhtb %0, %1, %2" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2) ); \ + else \ + __ASM ("pkhtb %0, %1, %2, asr %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \ + __RES; \ + }) +#endif + +#define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \ + ((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) ) + +#define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \ + ((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) ) + +__STATIC_FORCEINLINE int32_t __SMMLA (int32_t op1, int32_t op2, int32_t op3) +{ + int32_t result; + + __ASM volatile ("smmla %0, %1, %2, %3" : "=r" (result): "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +#endif /* (__ARM_FEATURE_DSP == 1) */ +/*@} end of group CMSIS_SIMD_intrinsics */ + + +#endif /* __CMSIS_ARMCLANG_H */ diff --git a/test/STM32F072C8T6/Drivers/CMSIS/Include/cmsis_compiler.h b/test/STM32F072C8T6/Drivers/CMSIS/Include/cmsis_compiler.h new file mode 100644 index 0000000..79a2cac --- /dev/null +++ b/test/STM32F072C8T6/Drivers/CMSIS/Include/cmsis_compiler.h @@ -0,0 +1,266 @@ +/**************************************************************************//** + * @file cmsis_compiler.h + * @brief CMSIS compiler generic header file + * @version V5.0.4 + * @date 10. January 2018 + ******************************************************************************/ +/* + * Copyright (c) 2009-2018 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * 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 + * + * 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 __CMSIS_COMPILER_H +#define __CMSIS_COMPILER_H + +#include + +/* + * Arm Compiler 4/5 + */ +#if defined ( __CC_ARM ) + #include "cmsis_armcc.h" + + +/* + * Arm Compiler 6 (armclang) + */ +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #include "cmsis_armclang.h" + + +/* + * GNU Compiler + */ +#elif defined ( __GNUC__ ) + #include "cmsis_gcc.h" + + +/* + * IAR Compiler + */ +#elif defined ( __ICCARM__ ) + #include + + +/* + * TI Arm Compiler + */ +#elif defined ( __TI_ARM__ ) + #include + + #ifndef __ASM + #define __ASM __asm + #endif + #ifndef __INLINE + #define __INLINE inline + #endif + #ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline + #endif + #ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __STATIC_INLINE + #endif + #ifndef __NO_RETURN + #define __NO_RETURN __attribute__((noreturn)) + #endif + #ifndef __USED + #define __USED __attribute__((used)) + #endif + #ifndef __WEAK + #define __WEAK __attribute__((weak)) + #endif + #ifndef __PACKED + #define __PACKED __attribute__((packed)) + #endif + #ifndef __PACKED_STRUCT + #define __PACKED_STRUCT struct __attribute__((packed)) + #endif + #ifndef __PACKED_UNION + #define __PACKED_UNION union __attribute__((packed)) + #endif + #ifndef __UNALIGNED_UINT32 /* deprecated */ + struct __attribute__((packed)) T_UINT32 { uint32_t v; }; + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) + #endif + #ifndef __UNALIGNED_UINT16_WRITE + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void*)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT16_READ + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) + #endif + #ifndef __UNALIGNED_UINT32_WRITE + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT32_READ + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) + #endif + #ifndef __ALIGNED + #define __ALIGNED(x) __attribute__((aligned(x))) + #endif + #ifndef __RESTRICT + #warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored. + #define __RESTRICT + #endif + + +/* + * TASKING Compiler + */ +#elif defined ( __TASKING__ ) + /* + * The CMSIS functions have been implemented as intrinsics in the compiler. + * Please use "carm -?i" to get an up to date list of all intrinsics, + * Including the CMSIS ones. + */ + + #ifndef __ASM + #define __ASM __asm + #endif + #ifndef __INLINE + #define __INLINE inline + #endif + #ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline + #endif + #ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __STATIC_INLINE + #endif + #ifndef __NO_RETURN + #define __NO_RETURN __attribute__((noreturn)) + #endif + #ifndef __USED + #define __USED __attribute__((used)) + #endif + #ifndef __WEAK + #define __WEAK __attribute__((weak)) + #endif + #ifndef __PACKED + #define __PACKED __packed__ + #endif + #ifndef __PACKED_STRUCT + #define __PACKED_STRUCT struct __packed__ + #endif + #ifndef __PACKED_UNION + #define __PACKED_UNION union __packed__ + #endif + #ifndef __UNALIGNED_UINT32 /* deprecated */ + struct __packed__ T_UINT32 { uint32_t v; }; + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) + #endif + #ifndef __UNALIGNED_UINT16_WRITE + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT16_READ + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) + #endif + #ifndef __UNALIGNED_UINT32_WRITE + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT32_READ + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) + #endif + #ifndef __ALIGNED + #define __ALIGNED(x) __align(x) + #endif + #ifndef __RESTRICT + #warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored. + #define __RESTRICT + #endif + + +/* + * COSMIC Compiler + */ +#elif defined ( __CSMC__ ) + #include + + #ifndef __ASM + #define __ASM _asm + #endif + #ifndef __INLINE + #define __INLINE inline + #endif + #ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline + #endif + #ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __STATIC_INLINE + #endif + #ifndef __NO_RETURN + // NO RETURN is automatically detected hence no warning here + #define __NO_RETURN + #endif + #ifndef __USED + #warning No compiler specific solution for __USED. __USED is ignored. + #define __USED + #endif + #ifndef __WEAK + #define __WEAK __weak + #endif + #ifndef __PACKED + #define __PACKED @packed + #endif + #ifndef __PACKED_STRUCT + #define __PACKED_STRUCT @packed struct + #endif + #ifndef __PACKED_UNION + #define __PACKED_UNION @packed union + #endif + #ifndef __UNALIGNED_UINT32 /* deprecated */ + @packed struct T_UINT32 { uint32_t v; }; + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) + #endif + #ifndef __UNALIGNED_UINT16_WRITE + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT16_READ + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) + #endif + #ifndef __UNALIGNED_UINT32_WRITE + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT32_READ + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) + #endif + #ifndef __ALIGNED + #warning No compiler specific solution for __ALIGNED. __ALIGNED is ignored. + #define __ALIGNED(x) + #endif + #ifndef __RESTRICT + #warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored. + #define __RESTRICT + #endif + + +#else + #error Unknown compiler. +#endif + + +#endif /* __CMSIS_COMPILER_H */ + diff --git a/test/STM32F072C8T6/Drivers/CMSIS/Include/cmsis_gcc.h b/test/STM32F072C8T6/Drivers/CMSIS/Include/cmsis_gcc.h new file mode 100644 index 0000000..1bd41a4 --- /dev/null +++ b/test/STM32F072C8T6/Drivers/CMSIS/Include/cmsis_gcc.h @@ -0,0 +1,2085 @@ +/**************************************************************************//** + * @file cmsis_gcc.h + * @brief CMSIS compiler GCC header file + * @version V5.0.4 + * @date 09. April 2018 + ******************************************************************************/ +/* + * Copyright (c) 2009-2018 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * 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 + * + * 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 __CMSIS_GCC_H +#define __CMSIS_GCC_H + +/* ignore some GCC warnings */ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wsign-conversion" +#pragma GCC diagnostic ignored "-Wconversion" +#pragma GCC diagnostic ignored "-Wunused-parameter" + +/* Fallback for __has_builtin */ +#ifndef __has_builtin + #define __has_builtin(x) (0) +#endif + +/* CMSIS compiler specific defines */ +#ifndef __ASM + #define __ASM __asm +#endif +#ifndef __INLINE + #define __INLINE inline +#endif +#ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline +#endif +#ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __attribute__((always_inline)) static inline +#endif +#ifndef __NO_RETURN + #define __NO_RETURN __attribute__((__noreturn__)) +#endif +#ifndef __USED + #define __USED __attribute__((used)) +#endif +#ifndef __WEAK + #define __WEAK __attribute__((weak)) +#endif +#ifndef __PACKED + #define __PACKED __attribute__((packed, aligned(1))) +#endif +#ifndef __PACKED_STRUCT + #define __PACKED_STRUCT struct __attribute__((packed, aligned(1))) +#endif +#ifndef __PACKED_UNION + #define __PACKED_UNION union __attribute__((packed, aligned(1))) +#endif +#ifndef __UNALIGNED_UINT32 /* deprecated */ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + struct __attribute__((packed)) T_UINT32 { uint32_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) +#endif +#ifndef __UNALIGNED_UINT16_WRITE + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) +#endif +#ifndef __UNALIGNED_UINT16_READ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) +#endif +#ifndef __UNALIGNED_UINT32_WRITE + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) +#endif +#ifndef __UNALIGNED_UINT32_READ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) +#endif +#ifndef __ALIGNED + #define __ALIGNED(x) __attribute__((aligned(x))) +#endif +#ifndef __RESTRICT + #define __RESTRICT __restrict +#endif + + +/* ########################### Core Function Access ########################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions + @{ + */ + +/** + \brief Enable IRQ Interrupts + \details Enables IRQ interrupts by clearing the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __enable_irq(void) +{ + __ASM volatile ("cpsie i" : : : "memory"); +} + + +/** + \brief Disable IRQ Interrupts + \details Disables IRQ interrupts by setting the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __disable_irq(void) +{ + __ASM volatile ("cpsid i" : : : "memory"); +} + + +/** + \brief Get Control Register + \details Returns the content of the Control Register. + \return Control Register value + */ +__STATIC_FORCEINLINE uint32_t __get_CONTROL(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, control" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Control Register (non-secure) + \details Returns the content of the non-secure Control Register when in secure mode. + \return non-secure Control Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_CONTROL_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, control_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Control Register + \details Writes the given value to the Control Register. + \param [in] control Control Register value to set + */ +__STATIC_FORCEINLINE void __set_CONTROL(uint32_t control) +{ + __ASM volatile ("MSR control, %0" : : "r" (control) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Control Register (non-secure) + \details Writes the given value to the non-secure Control Register when in secure state. + \param [in] control Control Register value to set + */ +__STATIC_FORCEINLINE void __TZ_set_CONTROL_NS(uint32_t control) +{ + __ASM volatile ("MSR control_ns, %0" : : "r" (control) : "memory"); +} +#endif + + +/** + \brief Get IPSR Register + \details Returns the content of the IPSR Register. + \return IPSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_IPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, ipsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get APSR Register + \details Returns the content of the APSR Register. + \return APSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_APSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, apsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get xPSR Register + \details Returns the content of the xPSR Register. + \return xPSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_xPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, xpsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get Process Stack Pointer + \details Returns the current value of the Process Stack Pointer (PSP). + \return PSP Register value + */ +__STATIC_FORCEINLINE uint32_t __get_PSP(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, psp" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Process Stack Pointer (non-secure) + \details Returns the current value of the non-secure Process Stack Pointer (PSP) when in secure state. + \return PSP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PSP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, psp_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Process Stack Pointer + \details Assigns the given value to the Process Stack Pointer (PSP). + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __set_PSP(uint32_t topOfProcStack) +{ + __ASM volatile ("MSR psp, %0" : : "r" (topOfProcStack) : ); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Process Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Process Stack Pointer (PSP) when in secure state. + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_PSP_NS(uint32_t topOfProcStack) +{ + __ASM volatile ("MSR psp_ns, %0" : : "r" (topOfProcStack) : ); +} +#endif + + +/** + \brief Get Main Stack Pointer + \details Returns the current value of the Main Stack Pointer (MSP). + \return MSP Register value + */ +__STATIC_FORCEINLINE uint32_t __get_MSP(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, msp" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Main Stack Pointer (non-secure) + \details Returns the current value of the non-secure Main Stack Pointer (MSP) when in secure state. + \return MSP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_MSP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, msp_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Main Stack Pointer + \details Assigns the given value to the Main Stack Pointer (MSP). + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __set_MSP(uint32_t topOfMainStack) +{ + __ASM volatile ("MSR msp, %0" : : "r" (topOfMainStack) : ); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Main Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Main Stack Pointer (MSP) when in secure state. + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_MSP_NS(uint32_t topOfMainStack) +{ + __ASM volatile ("MSR msp_ns, %0" : : "r" (topOfMainStack) : ); +} +#endif + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Stack Pointer (non-secure) + \details Returns the current value of the non-secure Stack Pointer (SP) when in secure state. + \return SP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_SP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, sp_ns" : "=r" (result) ); + return(result); +} + + +/** + \brief Set Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Stack Pointer (SP) when in secure state. + \param [in] topOfStack Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_SP_NS(uint32_t topOfStack) +{ + __ASM volatile ("MSR sp_ns, %0" : : "r" (topOfStack) : ); +} +#endif + + +/** + \brief Get Priority Mask + \details Returns the current state of the priority mask bit from the Priority Mask Register. + \return Priority Mask value + */ +__STATIC_FORCEINLINE uint32_t __get_PRIMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, primask" : "=r" (result) :: "memory"); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Priority Mask (non-secure) + \details Returns the current state of the non-secure priority mask bit from the Priority Mask Register when in secure state. + \return Priority Mask value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PRIMASK_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, primask_ns" : "=r" (result) :: "memory"); + return(result); +} +#endif + + +/** + \brief Set Priority Mask + \details Assigns the given value to the Priority Mask Register. + \param [in] priMask Priority Mask + */ +__STATIC_FORCEINLINE void __set_PRIMASK(uint32_t priMask) +{ + __ASM volatile ("MSR primask, %0" : : "r" (priMask) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Priority Mask (non-secure) + \details Assigns the given value to the non-secure Priority Mask Register when in secure state. + \param [in] priMask Priority Mask + */ +__STATIC_FORCEINLINE void __TZ_set_PRIMASK_NS(uint32_t priMask) +{ + __ASM volatile ("MSR primask_ns, %0" : : "r" (priMask) : "memory"); +} +#endif + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) +/** + \brief Enable FIQ + \details Enables FIQ interrupts by clearing the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __enable_fault_irq(void) +{ + __ASM volatile ("cpsie f" : : : "memory"); +} + + +/** + \brief Disable FIQ + \details Disables FIQ interrupts by setting the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __disable_fault_irq(void) +{ + __ASM volatile ("cpsid f" : : : "memory"); +} + + +/** + \brief Get Base Priority + \details Returns the current value of the Base Priority register. + \return Base Priority register value + */ +__STATIC_FORCEINLINE uint32_t __get_BASEPRI(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, basepri" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Base Priority (non-secure) + \details Returns the current value of the non-secure Base Priority register when in secure state. + \return Base Priority register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_BASEPRI_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, basepri_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Base Priority + \details Assigns the given value to the Base Priority register. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __set_BASEPRI(uint32_t basePri) +{ + __ASM volatile ("MSR basepri, %0" : : "r" (basePri) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Base Priority (non-secure) + \details Assigns the given value to the non-secure Base Priority register when in secure state. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __TZ_set_BASEPRI_NS(uint32_t basePri) +{ + __ASM volatile ("MSR basepri_ns, %0" : : "r" (basePri) : "memory"); +} +#endif + + +/** + \brief Set Base Priority with condition + \details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled, + or the new value increases the BASEPRI priority level. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __set_BASEPRI_MAX(uint32_t basePri) +{ + __ASM volatile ("MSR basepri_max, %0" : : "r" (basePri) : "memory"); +} + + +/** + \brief Get Fault Mask + \details Returns the current value of the Fault Mask register. + \return Fault Mask register value + */ +__STATIC_FORCEINLINE uint32_t __get_FAULTMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, faultmask" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Fault Mask (non-secure) + \details Returns the current value of the non-secure Fault Mask register when in secure state. + \return Fault Mask register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_FAULTMASK_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, faultmask_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Fault Mask + \details Assigns the given value to the Fault Mask register. + \param [in] faultMask Fault Mask value to set + */ +__STATIC_FORCEINLINE void __set_FAULTMASK(uint32_t faultMask) +{ + __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Fault Mask (non-secure) + \details Assigns the given value to the non-secure Fault Mask register when in secure state. + \param [in] faultMask Fault Mask value to set + */ +__STATIC_FORCEINLINE void __TZ_set_FAULTMASK_NS(uint32_t faultMask) +{ + __ASM volatile ("MSR faultmask_ns, %0" : : "r" (faultMask) : "memory"); +} +#endif + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) + +/** + \brief Get Process Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always in non-secure + mode. + + \details Returns the current value of the Process Stack Pointer Limit (PSPLIM). + \return PSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __get_PSPLIM(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, psplim" : "=r" (result) ); + return result; +#endif +} + +#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Process Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always. + + \details Returns the current value of the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. + \return PSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PSPLIM_NS(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, psplim_ns" : "=r" (result) ); + return result; +#endif +} +#endif + + +/** + \brief Set Process Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored in non-secure + mode. + + \details Assigns the given value to the Process Stack Pointer Limit (PSPLIM). + \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __set_PSPLIM(uint32_t ProcStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)ProcStackPtrLimit; +#else + __ASM volatile ("MSR psplim, %0" : : "r" (ProcStackPtrLimit)); +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Process Stack Pointer (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored. + + \details Assigns the given value to the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. + \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __TZ_set_PSPLIM_NS(uint32_t ProcStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)ProcStackPtrLimit; +#else + __ASM volatile ("MSR psplim_ns, %0\n" : : "r" (ProcStackPtrLimit)); +#endif +} +#endif + + +/** + \brief Get Main Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always in non-secure + mode. + + \details Returns the current value of the Main Stack Pointer Limit (MSPLIM). + \return MSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __get_MSPLIM(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, msplim" : "=r" (result) ); + return result; +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Main Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always. + + \details Returns the current value of the non-secure Main Stack Pointer Limit(MSPLIM) when in secure state. + \return MSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_MSPLIM_NS(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, msplim_ns" : "=r" (result) ); + return result; +#endif +} +#endif + + +/** + \brief Set Main Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored in non-secure + mode. + + \details Assigns the given value to the Main Stack Pointer Limit (MSPLIM). + \param [in] MainStackPtrLimit Main Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __set_MSPLIM(uint32_t MainStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + (void)MainStackPtrLimit; +#else + __ASM volatile ("MSR msplim, %0" : : "r" (MainStackPtrLimit)); +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Main Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored. + + \details Assigns the given value to the non-secure Main Stack Pointer Limit (MSPLIM) when in secure state. + \param [in] MainStackPtrLimit Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_MSPLIM_NS(uint32_t MainStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + (void)MainStackPtrLimit; +#else + __ASM volatile ("MSR msplim_ns, %0" : : "r" (MainStackPtrLimit)); +#endif +} +#endif + +#endif /* ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + + +/** + \brief Get FPSCR + \details Returns the current value of the Floating Point Status/Control register. + \return Floating Point Status/Control register value + */ +__STATIC_FORCEINLINE uint32_t __get_FPSCR(void) +{ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) +#if __has_builtin(__builtin_arm_get_fpscr) +// Re-enable using built-in when GCC has been fixed +// || (__GNUC__ > 7) || (__GNUC__ == 7 && __GNUC_MINOR__ >= 2) + /* see https://gcc.gnu.org/ml/gcc-patches/2017-04/msg00443.html */ + return __builtin_arm_get_fpscr(); +#else + uint32_t result; + + __ASM volatile ("VMRS %0, fpscr" : "=r" (result) ); + return(result); +#endif +#else + return(0U); +#endif +} + + +/** + \brief Set FPSCR + \details Assigns the given value to the Floating Point Status/Control register. + \param [in] fpscr Floating Point Status/Control value to set + */ +__STATIC_FORCEINLINE void __set_FPSCR(uint32_t fpscr) +{ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) +#if __has_builtin(__builtin_arm_set_fpscr) +// Re-enable using built-in when GCC has been fixed +// || (__GNUC__ > 7) || (__GNUC__ == 7 && __GNUC_MINOR__ >= 2) + /* see https://gcc.gnu.org/ml/gcc-patches/2017-04/msg00443.html */ + __builtin_arm_set_fpscr(fpscr); +#else + __ASM volatile ("VMSR fpscr, %0" : : "r" (fpscr) : "vfpcc", "memory"); +#endif +#else + (void)fpscr; +#endif +} + + +/*@} end of CMSIS_Core_RegAccFunctions */ + + +/* ########################## Core Instruction Access ######################### */ +/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface + Access to dedicated instructions + @{ +*/ + +/* Define macros for porting to both thumb1 and thumb2. + * For thumb1, use low register (r0-r7), specified by constraint "l" + * Otherwise, use general registers, specified by constraint "r" */ +#if defined (__thumb__) && !defined (__thumb2__) +#define __CMSIS_GCC_OUT_REG(r) "=l" (r) +#define __CMSIS_GCC_RW_REG(r) "+l" (r) +#define __CMSIS_GCC_USE_REG(r) "l" (r) +#else +#define __CMSIS_GCC_OUT_REG(r) "=r" (r) +#define __CMSIS_GCC_RW_REG(r) "+r" (r) +#define __CMSIS_GCC_USE_REG(r) "r" (r) +#endif + +/** + \brief No Operation + \details No Operation does nothing. This instruction can be used for code alignment purposes. + */ +#define __NOP() __ASM volatile ("nop") + +/** + \brief Wait For Interrupt + \details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs. + */ +#define __WFI() __ASM volatile ("wfi") + + +/** + \brief Wait For Event + \details Wait For Event is a hint instruction that permits the processor to enter + a low-power state until one of a number of events occurs. + */ +#define __WFE() __ASM volatile ("wfe") + + +/** + \brief Send Event + \details Send Event is a hint instruction. It causes an event to be signaled to the CPU. + */ +#define __SEV() __ASM volatile ("sev") + + +/** + \brief Instruction Synchronization Barrier + \details Instruction Synchronization Barrier flushes the pipeline in the processor, + so that all instructions following the ISB are fetched from cache or memory, + after the instruction has been completed. + */ +__STATIC_FORCEINLINE void __ISB(void) +{ + __ASM volatile ("isb 0xF":::"memory"); +} + + +/** + \brief Data Synchronization Barrier + \details Acts as a special kind of Data Memory Barrier. + It completes when all explicit memory accesses before this instruction complete. + */ +__STATIC_FORCEINLINE void __DSB(void) +{ + __ASM volatile ("dsb 0xF":::"memory"); +} + + +/** + \brief Data Memory Barrier + \details Ensures the apparent order of the explicit memory operations before + and after the instruction, without ensuring their completion. + */ +__STATIC_FORCEINLINE void __DMB(void) +{ + __ASM volatile ("dmb 0xF":::"memory"); +} + + +/** + \brief Reverse byte order (32 bit) + \details Reverses the byte order in unsigned integer value. For example, 0x12345678 becomes 0x78563412. + \param [in] value Value to reverse + \return Reversed value + */ +__STATIC_FORCEINLINE uint32_t __REV(uint32_t value) +{ +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) + return __builtin_bswap32(value); +#else + uint32_t result; + + __ASM volatile ("rev %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return result; +#endif +} + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order within each halfword of a word. For example, 0x12345678 becomes 0x34127856. + \param [in] value Value to reverse + \return Reversed value + */ +__STATIC_FORCEINLINE uint32_t __REV16(uint32_t value) +{ + uint32_t result; + + __ASM volatile ("rev16 %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return result; +} + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order in a 16-bit value and returns the signed 16-bit result. For example, 0x0080 becomes 0x8000. + \param [in] value Value to reverse + \return Reversed value + */ +__STATIC_FORCEINLINE int16_t __REVSH(int16_t value) +{ +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + return (int16_t)__builtin_bswap16(value); +#else + int16_t result; + + __ASM volatile ("revsh %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return result; +#endif +} + + +/** + \brief Rotate Right in unsigned value (32 bit) + \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. + \param [in] op1 Value to rotate + \param [in] op2 Number of Bits to rotate + \return Rotated value + */ +__STATIC_FORCEINLINE uint32_t __ROR(uint32_t op1, uint32_t op2) +{ + op2 %= 32U; + if (op2 == 0U) + { + return op1; + } + return (op1 >> op2) | (op1 << (32U - op2)); +} + + +/** + \brief Breakpoint + \details Causes the processor to enter Debug state. + Debug tools can use this to investigate system state when the instruction at a particular address is reached. + \param [in] value is ignored by the processor. + If required, a debugger can use it to store additional information about the breakpoint. + */ +#define __BKPT(value) __ASM volatile ("bkpt "#value) + + +/** + \brief Reverse bit order of value + \details Reverses the bit order of the given value. + \param [in] value Value to reverse + \return Reversed value + */ +__STATIC_FORCEINLINE uint32_t __RBIT(uint32_t value) +{ + uint32_t result; + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) + __ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) ); +#else + uint32_t s = (4U /*sizeof(v)*/ * 8U) - 1U; /* extra shift needed at end */ + + result = value; /* r will be reversed bits of v; first get LSB of v */ + for (value >>= 1U; value != 0U; value >>= 1U) + { + result <<= 1U; + result |= value & 1U; + s--; + } + result <<= s; /* shift when v's highest bits are zero */ +#endif + return result; +} + + +/** + \brief Count leading zeros + \details Counts the number of leading zeros of a data value. + \param [in] value Value to count the leading zeros + \return number of leading zeros in value + */ +#define __CLZ (uint8_t)__builtin_clz + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) +/** + \brief LDR Exclusive (8 bit) + \details Executes a exclusive LDR instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDREXB(volatile uint8_t *addr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrexb %0, %1" : "=r" (result) : "Q" (*addr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) : "memory" ); +#endif + return ((uint8_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDR Exclusive (16 bit) + \details Executes a exclusive LDR instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDREXH(volatile uint16_t *addr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrexh %0, %1" : "=r" (result) : "Q" (*addr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) : "memory" ); +#endif + return ((uint16_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDR Exclusive (32 bit) + \details Executes a exclusive LDR instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDREXW(volatile uint32_t *addr) +{ + uint32_t result; + + __ASM volatile ("ldrex %0, %1" : "=r" (result) : "Q" (*addr) ); + return(result); +} + + +/** + \brief STR Exclusive (8 bit) + \details Executes a exclusive STR instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STREXB(uint8_t value, volatile uint8_t *addr) +{ + uint32_t result; + + __ASM volatile ("strexb %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) ); + return(result); +} + + +/** + \brief STR Exclusive (16 bit) + \details Executes a exclusive STR instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STREXH(uint16_t value, volatile uint16_t *addr) +{ + uint32_t result; + + __ASM volatile ("strexh %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) ); + return(result); +} + + +/** + \brief STR Exclusive (32 bit) + \details Executes a exclusive STR instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STREXW(uint32_t value, volatile uint32_t *addr) +{ + uint32_t result; + + __ASM volatile ("strex %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" (value) ); + return(result); +} + + +/** + \brief Remove the exclusive lock + \details Removes the exclusive lock which is created by LDREX. + */ +__STATIC_FORCEINLINE void __CLREX(void) +{ + __ASM volatile ("clrex" ::: "memory"); +} + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] ARG1 Value to be saturated + \param [in] ARG2 Bit position to saturate to (1..32) + \return Saturated value + */ +#define __SSAT(ARG1,ARG2) \ +__extension__ \ +({ \ + int32_t __RES, __ARG1 = (ARG1); \ + __ASM ("ssat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] ARG1 Value to be saturated + \param [in] ARG2 Bit position to saturate to (0..31) + \return Saturated value + */ +#define __USAT(ARG1,ARG2) \ + __extension__ \ +({ \ + uint32_t __RES, __ARG1 = (ARG1); \ + __ASM ("usat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + + +/** + \brief Rotate Right with Extend (32 bit) + \details Moves each bit of a bitstring right by one bit. + The carry input is shifted in at the left end of the bitstring. + \param [in] value Value to rotate + \return Rotated value + */ +__STATIC_FORCEINLINE uint32_t __RRX(uint32_t value) +{ + uint32_t result; + + __ASM volatile ("rrx %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return(result); +} + + +/** + \brief LDRT Unprivileged (8 bit) + \details Executes a Unprivileged LDRT instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDRBT(volatile uint8_t *ptr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrbt %0, %1" : "=r" (result) : "Q" (*ptr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrbt %0, [%1]" : "=r" (result) : "r" (ptr) : "memory" ); +#endif + return ((uint8_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDRT Unprivileged (16 bit) + \details Executes a Unprivileged LDRT instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDRHT(volatile uint16_t *ptr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrht %0, %1" : "=r" (result) : "Q" (*ptr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrht %0, [%1]" : "=r" (result) : "r" (ptr) : "memory" ); +#endif + return ((uint16_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDRT Unprivileged (32 bit) + \details Executes a Unprivileged LDRT instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDRT(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldrt %0, %1" : "=r" (result) : "Q" (*ptr) ); + return(result); +} + + +/** + \brief STRT Unprivileged (8 bit) + \details Executes a Unprivileged STRT instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRBT(uint8_t value, volatile uint8_t *ptr) +{ + __ASM volatile ("strbt %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief STRT Unprivileged (16 bit) + \details Executes a Unprivileged STRT instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRHT(uint16_t value, volatile uint16_t *ptr) +{ + __ASM volatile ("strht %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief STRT Unprivileged (32 bit) + \details Executes a Unprivileged STRT instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRT(uint32_t value, volatile uint32_t *ptr) +{ + __ASM volatile ("strt %1, %0" : "=Q" (*ptr) : "r" (value) ); +} + +#else /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +__STATIC_FORCEINLINE int32_t __SSAT(int32_t val, uint32_t sat) +{ + if ((sat >= 1U) && (sat <= 32U)) + { + const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U); + const int32_t min = -1 - max ; + if (val > max) + { + return max; + } + else if (val < min) + { + return min; + } + } + return val; +} + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +__STATIC_FORCEINLINE uint32_t __USAT(int32_t val, uint32_t sat) +{ + if (sat <= 31U) + { + const uint32_t max = ((1U << sat) - 1U); + if (val > (int32_t)max) + { + return max; + } + else if (val < 0) + { + return 0U; + } + } + return (uint32_t)val; +} + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) +/** + \brief Load-Acquire (8 bit) + \details Executes a LDAB instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDAB(volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldab %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint8_t) result); +} + + +/** + \brief Load-Acquire (16 bit) + \details Executes a LDAH instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDAH(volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldah %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint16_t) result); +} + + +/** + \brief Load-Acquire (32 bit) + \details Executes a LDA instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDA(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("lda %0, %1" : "=r" (result) : "Q" (*ptr) ); + return(result); +} + + +/** + \brief Store-Release (8 bit) + \details Executes a STLB instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STLB(uint8_t value, volatile uint8_t *ptr) +{ + __ASM volatile ("stlb %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief Store-Release (16 bit) + \details Executes a STLH instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STLH(uint16_t value, volatile uint16_t *ptr) +{ + __ASM volatile ("stlh %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief Store-Release (32 bit) + \details Executes a STL instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STL(uint32_t value, volatile uint32_t *ptr) +{ + __ASM volatile ("stl %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief Load-Acquire Exclusive (8 bit) + \details Executes a LDAB exclusive instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDAEXB(volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldaexb %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint8_t) result); +} + + +/** + \brief Load-Acquire Exclusive (16 bit) + \details Executes a LDAH exclusive instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDAEXH(volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldaexh %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint16_t) result); +} + + +/** + \brief Load-Acquire Exclusive (32 bit) + \details Executes a LDA exclusive instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDAEX(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldaex %0, %1" : "=r" (result) : "Q" (*ptr) ); + return(result); +} + + +/** + \brief Store-Release Exclusive (8 bit) + \details Executes a STLB exclusive instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STLEXB(uint8_t value, volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("stlexb %0, %2, %1" : "=&r" (result), "=Q" (*ptr) : "r" ((uint32_t)value) ); + return(result); +} + + +/** + \brief Store-Release Exclusive (16 bit) + \details Executes a STLH exclusive instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STLEXH(uint16_t value, volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("stlexh %0, %2, %1" : "=&r" (result), "=Q" (*ptr) : "r" ((uint32_t)value) ); + return(result); +} + + +/** + \brief Store-Release Exclusive (32 bit) + \details Executes a STL exclusive instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STLEX(uint32_t value, volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("stlex %0, %2, %1" : "=&r" (result), "=Q" (*ptr) : "r" ((uint32_t)value) ); + return(result); +} + +#endif /* ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + +/*@}*/ /* end of group CMSIS_Core_InstructionInterface */ + + +/* ################### Compiler specific Intrinsics ########################### */ +/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics + Access to dedicated SIMD instructions + @{ +*/ + +#if (defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1)) + +__STATIC_FORCEINLINE uint32_t __SADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + + +__STATIC_FORCEINLINE uint32_t __SSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + + +__STATIC_FORCEINLINE uint32_t __SADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USAD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usad8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USADA8(uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("usada8 %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +#define __SSAT16(ARG1,ARG2) \ +({ \ + int32_t __RES, __ARG1 = (ARG1); \ + __ASM ("ssat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + +#define __USAT16(ARG1,ARG2) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1); \ + __ASM ("usat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + +__STATIC_FORCEINLINE uint32_t __UXTB16(uint32_t op1) +{ + uint32_t result; + + __ASM volatile ("uxtb16 %0, %1" : "=r" (result) : "r" (op1)); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UXTAB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SXTB16(uint32_t op1) +{ + uint32_t result; + + __ASM volatile ("sxtb16 %0, %1" : "=r" (result) : "r" (op1)); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SXTAB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMUAD (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smuad %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMUADX (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smuadx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLAD (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlad %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLADX (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smladx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint64_t __SMLALD (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint64_t __SMLALDX (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint32_t __SMUSD (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smusd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMUSDX (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smusdx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLSD (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlsd %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLSDX (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlsdx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint64_t __SMLSLD (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint64_t __SMLSLDX (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint32_t __SEL (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sel %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE int32_t __QADD( int32_t op1, int32_t op2) +{ + int32_t result; + + __ASM volatile ("qadd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE int32_t __QSUB( int32_t op1, int32_t op2) +{ + int32_t result; + + __ASM volatile ("qsub %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +#if 0 +#define __PKHBT(ARG1,ARG2,ARG3) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \ + __ASM ("pkhbt %0, %1, %2, lsl %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \ + __RES; \ + }) + +#define __PKHTB(ARG1,ARG2,ARG3) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \ + if (ARG3 == 0) \ + __ASM ("pkhtb %0, %1, %2" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2) ); \ + else \ + __ASM ("pkhtb %0, %1, %2, asr %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \ + __RES; \ + }) +#endif + +#define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \ + ((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) ) + +#define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \ + ((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) ) + +__STATIC_FORCEINLINE int32_t __SMMLA (int32_t op1, int32_t op2, int32_t op3) +{ + int32_t result; + + __ASM volatile ("smmla %0, %1, %2, %3" : "=r" (result): "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +#endif /* (__ARM_FEATURE_DSP == 1) */ +/*@} end of group CMSIS_SIMD_intrinsics */ + + +#pragma GCC diagnostic pop + +#endif /* __CMSIS_GCC_H */ diff --git a/test/STM32F072C8T6/Drivers/CMSIS/Include/cmsis_iccarm.h b/test/STM32F072C8T6/Drivers/CMSIS/Include/cmsis_iccarm.h new file mode 100644 index 0000000..3c90a2c --- /dev/null +++ b/test/STM32F072C8T6/Drivers/CMSIS/Include/cmsis_iccarm.h @@ -0,0 +1,935 @@ +/**************************************************************************//** + * @file cmsis_iccarm.h + * @brief CMSIS compiler ICCARM (IAR Compiler for Arm) header file + * @version V5.0.7 + * @date 19. June 2018 + ******************************************************************************/ + +//------------------------------------------------------------------------------ +// +// Copyright (c) 2017-2018 IAR Systems +// +// 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 __CMSIS_ICCARM_H__ +#define __CMSIS_ICCARM_H__ + +#ifndef __ICCARM__ + #error This file should only be compiled by ICCARM +#endif + +#pragma system_include + +#define __IAR_FT _Pragma("inline=forced") __intrinsic + +#if (__VER__ >= 8000000) + #define __ICCARM_V8 1 +#else + #define __ICCARM_V8 0 +#endif + +#ifndef __ALIGNED + #if __ICCARM_V8 + #define __ALIGNED(x) __attribute__((aligned(x))) + #elif (__VER__ >= 7080000) + /* Needs IAR language extensions */ + #define __ALIGNED(x) __attribute__((aligned(x))) + #else + #warning No compiler specific solution for __ALIGNED.__ALIGNED is ignored. + #define __ALIGNED(x) + #endif +#endif + + +/* Define compiler macros for CPU architecture, used in CMSIS 5. + */ +#if __ARM_ARCH_6M__ || __ARM_ARCH_7M__ || __ARM_ARCH_7EM__ || __ARM_ARCH_8M_BASE__ || __ARM_ARCH_8M_MAIN__ +/* Macros already defined */ +#else + #if defined(__ARM8M_MAINLINE__) || defined(__ARM8EM_MAINLINE__) + #define __ARM_ARCH_8M_MAIN__ 1 + #elif defined(__ARM8M_BASELINE__) + #define __ARM_ARCH_8M_BASE__ 1 + #elif defined(__ARM_ARCH_PROFILE) && __ARM_ARCH_PROFILE == 'M' + #if __ARM_ARCH == 6 + #define __ARM_ARCH_6M__ 1 + #elif __ARM_ARCH == 7 + #if __ARM_FEATURE_DSP + #define __ARM_ARCH_7EM__ 1 + #else + #define __ARM_ARCH_7M__ 1 + #endif + #endif /* __ARM_ARCH */ + #endif /* __ARM_ARCH_PROFILE == 'M' */ +#endif + +/* Alternativ core deduction for older ICCARM's */ +#if !defined(__ARM_ARCH_6M__) && !defined(__ARM_ARCH_7M__) && !defined(__ARM_ARCH_7EM__) && \ + !defined(__ARM_ARCH_8M_BASE__) && !defined(__ARM_ARCH_8M_MAIN__) + #if defined(__ARM6M__) && (__CORE__ == __ARM6M__) + #define __ARM_ARCH_6M__ 1 + #elif defined(__ARM7M__) && (__CORE__ == __ARM7M__) + #define __ARM_ARCH_7M__ 1 + #elif defined(__ARM7EM__) && (__CORE__ == __ARM7EM__) + #define __ARM_ARCH_7EM__ 1 + #elif defined(__ARM8M_BASELINE__) && (__CORE == __ARM8M_BASELINE__) + #define __ARM_ARCH_8M_BASE__ 1 + #elif defined(__ARM8M_MAINLINE__) && (__CORE == __ARM8M_MAINLINE__) + #define __ARM_ARCH_8M_MAIN__ 1 + #elif defined(__ARM8EM_MAINLINE__) && (__CORE == __ARM8EM_MAINLINE__) + #define __ARM_ARCH_8M_MAIN__ 1 + #else + #error "Unknown target." + #endif +#endif + + + +#if defined(__ARM_ARCH_6M__) && __ARM_ARCH_6M__==1 + #define __IAR_M0_FAMILY 1 +#elif defined(__ARM_ARCH_8M_BASE__) && __ARM_ARCH_8M_BASE__==1 + #define __IAR_M0_FAMILY 1 +#else + #define __IAR_M0_FAMILY 0 +#endif + + +#ifndef __ASM + #define __ASM __asm +#endif + +#ifndef __INLINE + #define __INLINE inline +#endif + +#ifndef __NO_RETURN + #if __ICCARM_V8 + #define __NO_RETURN __attribute__((__noreturn__)) + #else + #define __NO_RETURN _Pragma("object_attribute=__noreturn") + #endif +#endif + +#ifndef __PACKED + #if __ICCARM_V8 + #define __PACKED __attribute__((packed, aligned(1))) + #else + /* Needs IAR language extensions */ + #define __PACKED __packed + #endif +#endif + +#ifndef __PACKED_STRUCT + #if __ICCARM_V8 + #define __PACKED_STRUCT struct __attribute__((packed, aligned(1))) + #else + /* Needs IAR language extensions */ + #define __PACKED_STRUCT __packed struct + #endif +#endif + +#ifndef __PACKED_UNION + #if __ICCARM_V8 + #define __PACKED_UNION union __attribute__((packed, aligned(1))) + #else + /* Needs IAR language extensions */ + #define __PACKED_UNION __packed union + #endif +#endif + +#ifndef __RESTRICT + #define __RESTRICT __restrict +#endif + +#ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline +#endif + +#ifndef __FORCEINLINE + #define __FORCEINLINE _Pragma("inline=forced") +#endif + +#ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __FORCEINLINE __STATIC_INLINE +#endif + +#ifndef __UNALIGNED_UINT16_READ +#pragma language=save +#pragma language=extended +__IAR_FT uint16_t __iar_uint16_read(void const *ptr) +{ + return *(__packed uint16_t*)(ptr); +} +#pragma language=restore +#define __UNALIGNED_UINT16_READ(PTR) __iar_uint16_read(PTR) +#endif + + +#ifndef __UNALIGNED_UINT16_WRITE +#pragma language=save +#pragma language=extended +__IAR_FT void __iar_uint16_write(void const *ptr, uint16_t val) +{ + *(__packed uint16_t*)(ptr) = val;; +} +#pragma language=restore +#define __UNALIGNED_UINT16_WRITE(PTR,VAL) __iar_uint16_write(PTR,VAL) +#endif + +#ifndef __UNALIGNED_UINT32_READ +#pragma language=save +#pragma language=extended +__IAR_FT uint32_t __iar_uint32_read(void const *ptr) +{ + return *(__packed uint32_t*)(ptr); +} +#pragma language=restore +#define __UNALIGNED_UINT32_READ(PTR) __iar_uint32_read(PTR) +#endif + +#ifndef __UNALIGNED_UINT32_WRITE +#pragma language=save +#pragma language=extended +__IAR_FT void __iar_uint32_write(void const *ptr, uint32_t val) +{ + *(__packed uint32_t*)(ptr) = val;; +} +#pragma language=restore +#define __UNALIGNED_UINT32_WRITE(PTR,VAL) __iar_uint32_write(PTR,VAL) +#endif + +#ifndef __UNALIGNED_UINT32 /* deprecated */ +#pragma language=save +#pragma language=extended +__packed struct __iar_u32 { uint32_t v; }; +#pragma language=restore +#define __UNALIGNED_UINT32(PTR) (((struct __iar_u32 *)(PTR))->v) +#endif + +#ifndef __USED + #if __ICCARM_V8 + #define __USED __attribute__((used)) + #else + #define __USED _Pragma("__root") + #endif +#endif + +#ifndef __WEAK + #if __ICCARM_V8 + #define __WEAK __attribute__((weak)) + #else + #define __WEAK _Pragma("__weak") + #endif +#endif + + +#ifndef __ICCARM_INTRINSICS_VERSION__ + #define __ICCARM_INTRINSICS_VERSION__ 0 +#endif + +#if __ICCARM_INTRINSICS_VERSION__ == 2 + + #if defined(__CLZ) + #undef __CLZ + #endif + #if defined(__REVSH) + #undef __REVSH + #endif + #if defined(__RBIT) + #undef __RBIT + #endif + #if defined(__SSAT) + #undef __SSAT + #endif + #if defined(__USAT) + #undef __USAT + #endif + + #include "iccarm_builtin.h" + + #define __disable_fault_irq __iar_builtin_disable_fiq + #define __disable_irq __iar_builtin_disable_interrupt + #define __enable_fault_irq __iar_builtin_enable_fiq + #define __enable_irq __iar_builtin_enable_interrupt + #define __arm_rsr __iar_builtin_rsr + #define __arm_wsr __iar_builtin_wsr + + + #define __get_APSR() (__arm_rsr("APSR")) + #define __get_BASEPRI() (__arm_rsr("BASEPRI")) + #define __get_CONTROL() (__arm_rsr("CONTROL")) + #define __get_FAULTMASK() (__arm_rsr("FAULTMASK")) + + #if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) + #define __get_FPSCR() (__arm_rsr("FPSCR")) + #define __set_FPSCR(VALUE) (__arm_wsr("FPSCR", (VALUE))) + #else + #define __get_FPSCR() ( 0 ) + #define __set_FPSCR(VALUE) ((void)VALUE) + #endif + + #define __get_IPSR() (__arm_rsr("IPSR")) + #define __get_MSP() (__arm_rsr("MSP")) + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + #define __get_MSPLIM() (0U) + #else + #define __get_MSPLIM() (__arm_rsr("MSPLIM")) + #endif + #define __get_PRIMASK() (__arm_rsr("PRIMASK")) + #define __get_PSP() (__arm_rsr("PSP")) + + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + #define __get_PSPLIM() (0U) + #else + #define __get_PSPLIM() (__arm_rsr("PSPLIM")) + #endif + + #define __get_xPSR() (__arm_rsr("xPSR")) + + #define __set_BASEPRI(VALUE) (__arm_wsr("BASEPRI", (VALUE))) + #define __set_BASEPRI_MAX(VALUE) (__arm_wsr("BASEPRI_MAX", (VALUE))) + #define __set_CONTROL(VALUE) (__arm_wsr("CONTROL", (VALUE))) + #define __set_FAULTMASK(VALUE) (__arm_wsr("FAULTMASK", (VALUE))) + #define __set_MSP(VALUE) (__arm_wsr("MSP", (VALUE))) + + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + #define __set_MSPLIM(VALUE) ((void)(VALUE)) + #else + #define __set_MSPLIM(VALUE) (__arm_wsr("MSPLIM", (VALUE))) + #endif + #define __set_PRIMASK(VALUE) (__arm_wsr("PRIMASK", (VALUE))) + #define __set_PSP(VALUE) (__arm_wsr("PSP", (VALUE))) + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + #define __set_PSPLIM(VALUE) ((void)(VALUE)) + #else + #define __set_PSPLIM(VALUE) (__arm_wsr("PSPLIM", (VALUE))) + #endif + + #define __TZ_get_CONTROL_NS() (__arm_rsr("CONTROL_NS")) + #define __TZ_set_CONTROL_NS(VALUE) (__arm_wsr("CONTROL_NS", (VALUE))) + #define __TZ_get_PSP_NS() (__arm_rsr("PSP_NS")) + #define __TZ_set_PSP_NS(VALUE) (__arm_wsr("PSP_NS", (VALUE))) + #define __TZ_get_MSP_NS() (__arm_rsr("MSP_NS")) + #define __TZ_set_MSP_NS(VALUE) (__arm_wsr("MSP_NS", (VALUE))) + #define __TZ_get_SP_NS() (__arm_rsr("SP_NS")) + #define __TZ_set_SP_NS(VALUE) (__arm_wsr("SP_NS", (VALUE))) + #define __TZ_get_PRIMASK_NS() (__arm_rsr("PRIMASK_NS")) + #define __TZ_set_PRIMASK_NS(VALUE) (__arm_wsr("PRIMASK_NS", (VALUE))) + #define __TZ_get_BASEPRI_NS() (__arm_rsr("BASEPRI_NS")) + #define __TZ_set_BASEPRI_NS(VALUE) (__arm_wsr("BASEPRI_NS", (VALUE))) + #define __TZ_get_FAULTMASK_NS() (__arm_rsr("FAULTMASK_NS")) + #define __TZ_set_FAULTMASK_NS(VALUE)(__arm_wsr("FAULTMASK_NS", (VALUE))) + + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + #define __TZ_get_PSPLIM_NS() (0U) + #define __TZ_set_PSPLIM_NS(VALUE) ((void)(VALUE)) + #else + #define __TZ_get_PSPLIM_NS() (__arm_rsr("PSPLIM_NS")) + #define __TZ_set_PSPLIM_NS(VALUE) (__arm_wsr("PSPLIM_NS", (VALUE))) + #endif + + #define __TZ_get_MSPLIM_NS() (__arm_rsr("MSPLIM_NS")) + #define __TZ_set_MSPLIM_NS(VALUE) (__arm_wsr("MSPLIM_NS", (VALUE))) + + #define __NOP __iar_builtin_no_operation + + #define __CLZ __iar_builtin_CLZ + #define __CLREX __iar_builtin_CLREX + + #define __DMB __iar_builtin_DMB + #define __DSB __iar_builtin_DSB + #define __ISB __iar_builtin_ISB + + #define __LDREXB __iar_builtin_LDREXB + #define __LDREXH __iar_builtin_LDREXH + #define __LDREXW __iar_builtin_LDREX + + #define __RBIT __iar_builtin_RBIT + #define __REV __iar_builtin_REV + #define __REV16 __iar_builtin_REV16 + + __IAR_FT int16_t __REVSH(int16_t val) + { + return (int16_t) __iar_builtin_REVSH(val); + } + + #define __ROR __iar_builtin_ROR + #define __RRX __iar_builtin_RRX + + #define __SEV __iar_builtin_SEV + + #if !__IAR_M0_FAMILY + #define __SSAT __iar_builtin_SSAT + #endif + + #define __STREXB __iar_builtin_STREXB + #define __STREXH __iar_builtin_STREXH + #define __STREXW __iar_builtin_STREX + + #if !__IAR_M0_FAMILY + #define __USAT __iar_builtin_USAT + #endif + + #define __WFE __iar_builtin_WFE + #define __WFI __iar_builtin_WFI + + #if __ARM_MEDIA__ + #define __SADD8 __iar_builtin_SADD8 + #define __QADD8 __iar_builtin_QADD8 + #define __SHADD8 __iar_builtin_SHADD8 + #define __UADD8 __iar_builtin_UADD8 + #define __UQADD8 __iar_builtin_UQADD8 + #define __UHADD8 __iar_builtin_UHADD8 + #define __SSUB8 __iar_builtin_SSUB8 + #define __QSUB8 __iar_builtin_QSUB8 + #define __SHSUB8 __iar_builtin_SHSUB8 + #define __USUB8 __iar_builtin_USUB8 + #define __UQSUB8 __iar_builtin_UQSUB8 + #define __UHSUB8 __iar_builtin_UHSUB8 + #define __SADD16 __iar_builtin_SADD16 + #define __QADD16 __iar_builtin_QADD16 + #define __SHADD16 __iar_builtin_SHADD16 + #define __UADD16 __iar_builtin_UADD16 + #define __UQADD16 __iar_builtin_UQADD16 + #define __UHADD16 __iar_builtin_UHADD16 + #define __SSUB16 __iar_builtin_SSUB16 + #define __QSUB16 __iar_builtin_QSUB16 + #define __SHSUB16 __iar_builtin_SHSUB16 + #define __USUB16 __iar_builtin_USUB16 + #define __UQSUB16 __iar_builtin_UQSUB16 + #define __UHSUB16 __iar_builtin_UHSUB16 + #define __SASX __iar_builtin_SASX + #define __QASX __iar_builtin_QASX + #define __SHASX __iar_builtin_SHASX + #define __UASX __iar_builtin_UASX + #define __UQASX __iar_builtin_UQASX + #define __UHASX __iar_builtin_UHASX + #define __SSAX __iar_builtin_SSAX + #define __QSAX __iar_builtin_QSAX + #define __SHSAX __iar_builtin_SHSAX + #define __USAX __iar_builtin_USAX + #define __UQSAX __iar_builtin_UQSAX + #define __UHSAX __iar_builtin_UHSAX + #define __USAD8 __iar_builtin_USAD8 + #define __USADA8 __iar_builtin_USADA8 + #define __SSAT16 __iar_builtin_SSAT16 + #define __USAT16 __iar_builtin_USAT16 + #define __UXTB16 __iar_builtin_UXTB16 + #define __UXTAB16 __iar_builtin_UXTAB16 + #define __SXTB16 __iar_builtin_SXTB16 + #define __SXTAB16 __iar_builtin_SXTAB16 + #define __SMUAD __iar_builtin_SMUAD + #define __SMUADX __iar_builtin_SMUADX + #define __SMMLA __iar_builtin_SMMLA + #define __SMLAD __iar_builtin_SMLAD + #define __SMLADX __iar_builtin_SMLADX + #define __SMLALD __iar_builtin_SMLALD + #define __SMLALDX __iar_builtin_SMLALDX + #define __SMUSD __iar_builtin_SMUSD + #define __SMUSDX __iar_builtin_SMUSDX + #define __SMLSD __iar_builtin_SMLSD + #define __SMLSDX __iar_builtin_SMLSDX + #define __SMLSLD __iar_builtin_SMLSLD + #define __SMLSLDX __iar_builtin_SMLSLDX + #define __SEL __iar_builtin_SEL + #define __QADD __iar_builtin_QADD + #define __QSUB __iar_builtin_QSUB + #define __PKHBT __iar_builtin_PKHBT + #define __PKHTB __iar_builtin_PKHTB + #endif + +#else /* __ICCARM_INTRINSICS_VERSION__ == 2 */ + + #if __IAR_M0_FAMILY + /* Avoid clash between intrinsics.h and arm_math.h when compiling for Cortex-M0. */ + #define __CLZ __cmsis_iar_clz_not_active + #define __SSAT __cmsis_iar_ssat_not_active + #define __USAT __cmsis_iar_usat_not_active + #define __RBIT __cmsis_iar_rbit_not_active + #define __get_APSR __cmsis_iar_get_APSR_not_active + #endif + + + #if (!((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) )) + #define __get_FPSCR __cmsis_iar_get_FPSR_not_active + #define __set_FPSCR __cmsis_iar_set_FPSR_not_active + #endif + + #ifdef __INTRINSICS_INCLUDED + #error intrinsics.h is already included previously! + #endif + + #include + + #if __IAR_M0_FAMILY + /* Avoid clash between intrinsics.h and arm_math.h when compiling for Cortex-M0. */ + #undef __CLZ + #undef __SSAT + #undef __USAT + #undef __RBIT + #undef __get_APSR + + __STATIC_INLINE uint8_t __CLZ(uint32_t data) + { + if (data == 0U) { return 32U; } + + uint32_t count = 0U; + uint32_t mask = 0x80000000U; + + while ((data & mask) == 0U) + { + count += 1U; + mask = mask >> 1U; + } + return count; + } + + __STATIC_INLINE uint32_t __RBIT(uint32_t v) + { + uint8_t sc = 31U; + uint32_t r = v; + for (v >>= 1U; v; v >>= 1U) + { + r <<= 1U; + r |= v & 1U; + sc--; + } + return (r << sc); + } + + __STATIC_INLINE uint32_t __get_APSR(void) + { + uint32_t res; + __asm("MRS %0,APSR" : "=r" (res)); + return res; + } + + #endif + + #if (!((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) )) + #undef __get_FPSCR + #undef __set_FPSCR + #define __get_FPSCR() (0) + #define __set_FPSCR(VALUE) ((void)VALUE) + #endif + + #pragma diag_suppress=Pe940 + #pragma diag_suppress=Pe177 + + #define __enable_irq __enable_interrupt + #define __disable_irq __disable_interrupt + #define __NOP __no_operation + + #define __get_xPSR __get_PSR + + #if (!defined(__ARM_ARCH_6M__) || __ARM_ARCH_6M__==0) + + __IAR_FT uint32_t __LDREXW(uint32_t volatile *ptr) + { + return __LDREX((unsigned long *)ptr); + } + + __IAR_FT uint32_t __STREXW(uint32_t value, uint32_t volatile *ptr) + { + return __STREX(value, (unsigned long *)ptr); + } + #endif + + + /* __CORTEX_M is defined in core_cm0.h, core_cm3.h and core_cm4.h. */ + #if (__CORTEX_M >= 0x03) + + __IAR_FT uint32_t __RRX(uint32_t value) + { + uint32_t result; + __ASM("RRX %0, %1" : "=r"(result) : "r" (value) : "cc"); + return(result); + } + + __IAR_FT void __set_BASEPRI_MAX(uint32_t value) + { + __asm volatile("MSR BASEPRI_MAX,%0"::"r" (value)); + } + + + #define __enable_fault_irq __enable_fiq + #define __disable_fault_irq __disable_fiq + + + #endif /* (__CORTEX_M >= 0x03) */ + + __IAR_FT uint32_t __ROR(uint32_t op1, uint32_t op2) + { + return (op1 >> op2) | (op1 << ((sizeof(op1)*8)-op2)); + } + + #if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) + + __IAR_FT uint32_t __get_MSPLIM(void) + { + uint32_t res; + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + res = 0U; + #else + __asm volatile("MRS %0,MSPLIM" : "=r" (res)); + #endif + return res; + } + + __IAR_FT void __set_MSPLIM(uint32_t value) + { + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + (void)value; + #else + __asm volatile("MSR MSPLIM,%0" :: "r" (value)); + #endif + } + + __IAR_FT uint32_t __get_PSPLIM(void) + { + uint32_t res; + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + res = 0U; + #else + __asm volatile("MRS %0,PSPLIM" : "=r" (res)); + #endif + return res; + } + + __IAR_FT void __set_PSPLIM(uint32_t value) + { + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)value; + #else + __asm volatile("MSR PSPLIM,%0" :: "r" (value)); + #endif + } + + __IAR_FT uint32_t __TZ_get_CONTROL_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,CONTROL_NS" : "=r" (res)); + return res; + } + + __IAR_FT void __TZ_set_CONTROL_NS(uint32_t value) + { + __asm volatile("MSR CONTROL_NS,%0" :: "r" (value)); + } + + __IAR_FT uint32_t __TZ_get_PSP_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,PSP_NS" : "=r" (res)); + return res; + } + + __IAR_FT void __TZ_set_PSP_NS(uint32_t value) + { + __asm volatile("MSR PSP_NS,%0" :: "r" (value)); + } + + __IAR_FT uint32_t __TZ_get_MSP_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,MSP_NS" : "=r" (res)); + return res; + } + + __IAR_FT void __TZ_set_MSP_NS(uint32_t value) + { + __asm volatile("MSR MSP_NS,%0" :: "r" (value)); + } + + __IAR_FT uint32_t __TZ_get_SP_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,SP_NS" : "=r" (res)); + return res; + } + __IAR_FT void __TZ_set_SP_NS(uint32_t value) + { + __asm volatile("MSR SP_NS,%0" :: "r" (value)); + } + + __IAR_FT uint32_t __TZ_get_PRIMASK_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,PRIMASK_NS" : "=r" (res)); + return res; + } + + __IAR_FT void __TZ_set_PRIMASK_NS(uint32_t value) + { + __asm volatile("MSR PRIMASK_NS,%0" :: "r" (value)); + } + + __IAR_FT uint32_t __TZ_get_BASEPRI_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,BASEPRI_NS" : "=r" (res)); + return res; + } + + __IAR_FT void __TZ_set_BASEPRI_NS(uint32_t value) + { + __asm volatile("MSR BASEPRI_NS,%0" :: "r" (value)); + } + + __IAR_FT uint32_t __TZ_get_FAULTMASK_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,FAULTMASK_NS" : "=r" (res)); + return res; + } + + __IAR_FT void __TZ_set_FAULTMASK_NS(uint32_t value) + { + __asm volatile("MSR FAULTMASK_NS,%0" :: "r" (value)); + } + + __IAR_FT uint32_t __TZ_get_PSPLIM_NS(void) + { + uint32_t res; + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + res = 0U; + #else + __asm volatile("MRS %0,PSPLIM_NS" : "=r" (res)); + #endif + return res; + } + + __IAR_FT void __TZ_set_PSPLIM_NS(uint32_t value) + { + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)value; + #else + __asm volatile("MSR PSPLIM_NS,%0" :: "r" (value)); + #endif + } + + __IAR_FT uint32_t __TZ_get_MSPLIM_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,MSPLIM_NS" : "=r" (res)); + return res; + } + + __IAR_FT void __TZ_set_MSPLIM_NS(uint32_t value) + { + __asm volatile("MSR MSPLIM_NS,%0" :: "r" (value)); + } + + #endif /* __ARM_ARCH_8M_MAIN__ or __ARM_ARCH_8M_BASE__ */ + +#endif /* __ICCARM_INTRINSICS_VERSION__ == 2 */ + +#define __BKPT(value) __asm volatile ("BKPT %0" : : "i"(value)) + +#if __IAR_M0_FAMILY + __STATIC_INLINE int32_t __SSAT(int32_t val, uint32_t sat) + { + if ((sat >= 1U) && (sat <= 32U)) + { + const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U); + const int32_t min = -1 - max ; + if (val > max) + { + return max; + } + else if (val < min) + { + return min; + } + } + return val; + } + + __STATIC_INLINE uint32_t __USAT(int32_t val, uint32_t sat) + { + if (sat <= 31U) + { + const uint32_t max = ((1U << sat) - 1U); + if (val > (int32_t)max) + { + return max; + } + else if (val < 0) + { + return 0U; + } + } + return (uint32_t)val; + } +#endif + +#if (__CORTEX_M >= 0x03) /* __CORTEX_M is defined in core_cm0.h, core_cm3.h and core_cm4.h. */ + + __IAR_FT uint8_t __LDRBT(volatile uint8_t *addr) + { + uint32_t res; + __ASM("LDRBT %0, [%1]" : "=r" (res) : "r" (addr) : "memory"); + return ((uint8_t)res); + } + + __IAR_FT uint16_t __LDRHT(volatile uint16_t *addr) + { + uint32_t res; + __ASM("LDRHT %0, [%1]" : "=r" (res) : "r" (addr) : "memory"); + return ((uint16_t)res); + } + + __IAR_FT uint32_t __LDRT(volatile uint32_t *addr) + { + uint32_t res; + __ASM("LDRT %0, [%1]" : "=r" (res) : "r" (addr) : "memory"); + return res; + } + + __IAR_FT void __STRBT(uint8_t value, volatile uint8_t *addr) + { + __ASM("STRBT %1, [%0]" : : "r" (addr), "r" ((uint32_t)value) : "memory"); + } + + __IAR_FT void __STRHT(uint16_t value, volatile uint16_t *addr) + { + __ASM("STRHT %1, [%0]" : : "r" (addr), "r" ((uint32_t)value) : "memory"); + } + + __IAR_FT void __STRT(uint32_t value, volatile uint32_t *addr) + { + __ASM("STRT %1, [%0]" : : "r" (addr), "r" (value) : "memory"); + } + +#endif /* (__CORTEX_M >= 0x03) */ + +#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) + + + __IAR_FT uint8_t __LDAB(volatile uint8_t *ptr) + { + uint32_t res; + __ASM volatile ("LDAB %0, [%1]" : "=r" (res) : "r" (ptr) : "memory"); + return ((uint8_t)res); + } + + __IAR_FT uint16_t __LDAH(volatile uint16_t *ptr) + { + uint32_t res; + __ASM volatile ("LDAH %0, [%1]" : "=r" (res) : "r" (ptr) : "memory"); + return ((uint16_t)res); + } + + __IAR_FT uint32_t __LDA(volatile uint32_t *ptr) + { + uint32_t res; + __ASM volatile ("LDA %0, [%1]" : "=r" (res) : "r" (ptr) : "memory"); + return res; + } + + __IAR_FT void __STLB(uint8_t value, volatile uint8_t *ptr) + { + __ASM volatile ("STLB %1, [%0]" :: "r" (ptr), "r" (value) : "memory"); + } + + __IAR_FT void __STLH(uint16_t value, volatile uint16_t *ptr) + { + __ASM volatile ("STLH %1, [%0]" :: "r" (ptr), "r" (value) : "memory"); + } + + __IAR_FT void __STL(uint32_t value, volatile uint32_t *ptr) + { + __ASM volatile ("STL %1, [%0]" :: "r" (ptr), "r" (value) : "memory"); + } + + __IAR_FT uint8_t __LDAEXB(volatile uint8_t *ptr) + { + uint32_t res; + __ASM volatile ("LDAEXB %0, [%1]" : "=r" (res) : "r" (ptr) : "memory"); + return ((uint8_t)res); + } + + __IAR_FT uint16_t __LDAEXH(volatile uint16_t *ptr) + { + uint32_t res; + __ASM volatile ("LDAEXH %0, [%1]" : "=r" (res) : "r" (ptr) : "memory"); + return ((uint16_t)res); + } + + __IAR_FT uint32_t __LDAEX(volatile uint32_t *ptr) + { + uint32_t res; + __ASM volatile ("LDAEX %0, [%1]" : "=r" (res) : "r" (ptr) : "memory"); + return res; + } + + __IAR_FT uint32_t __STLEXB(uint8_t value, volatile uint8_t *ptr) + { + uint32_t res; + __ASM volatile ("STLEXB %0, %2, [%1]" : "=r" (res) : "r" (ptr), "r" (value) : "memory"); + return res; + } + + __IAR_FT uint32_t __STLEXH(uint16_t value, volatile uint16_t *ptr) + { + uint32_t res; + __ASM volatile ("STLEXH %0, %2, [%1]" : "=r" (res) : "r" (ptr), "r" (value) : "memory"); + return res; + } + + __IAR_FT uint32_t __STLEX(uint32_t value, volatile uint32_t *ptr) + { + uint32_t res; + __ASM volatile ("STLEX %0, %2, [%1]" : "=r" (res) : "r" (ptr), "r" (value) : "memory"); + return res; + } + +#endif /* __ARM_ARCH_8M_MAIN__ or __ARM_ARCH_8M_BASE__ */ + +#undef __IAR_FT +#undef __IAR_M0_FAMILY +#undef __ICCARM_V8 + +#pragma diag_default=Pe940 +#pragma diag_default=Pe177 + +#endif /* __CMSIS_ICCARM_H__ */ diff --git a/test/STM32F072C8T6/Drivers/CMSIS/Include/cmsis_version.h b/test/STM32F072C8T6/Drivers/CMSIS/Include/cmsis_version.h new file mode 100644 index 0000000..ae3f2e3 --- /dev/null +++ b/test/STM32F072C8T6/Drivers/CMSIS/Include/cmsis_version.h @@ -0,0 +1,39 @@ +/**************************************************************************//** + * @file cmsis_version.h + * @brief CMSIS Core(M) Version definitions + * @version V5.0.2 + * @date 19. April 2017 + ******************************************************************************/ +/* + * Copyright (c) 2009-2017 ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * 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 + * + * 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. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CMSIS_VERSION_H +#define __CMSIS_VERSION_H + +/* CMSIS Version definitions */ +#define __CM_CMSIS_VERSION_MAIN ( 5U) /*!< [31:16] CMSIS Core(M) main version */ +#define __CM_CMSIS_VERSION_SUB ( 1U) /*!< [15:0] CMSIS Core(M) sub version */ +#define __CM_CMSIS_VERSION ((__CM_CMSIS_VERSION_MAIN << 16U) | \ + __CM_CMSIS_VERSION_SUB ) /*!< CMSIS Core(M) version number */ +#endif diff --git a/test/STM32F072C8T6/Drivers/CMSIS/Include/core_armv8mbl.h b/test/STM32F072C8T6/Drivers/CMSIS/Include/core_armv8mbl.h new file mode 100644 index 0000000..ec76ab2 --- /dev/null +++ b/test/STM32F072C8T6/Drivers/CMSIS/Include/core_armv8mbl.h @@ -0,0 +1,1918 @@ +/**************************************************************************//** + * @file core_armv8mbl.h + * @brief CMSIS Armv8-M Baseline Core Peripheral Access Layer Header File + * @version V5.0.7 + * @date 22. June 2018 + ******************************************************************************/ +/* + * Copyright (c) 2009-2018 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * 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 + * + * 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. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CORE_ARMV8MBL_H_GENERIC +#define __CORE_ARMV8MBL_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup Cortex_ARMv8MBL + @{ + */ + +#include "cmsis_version.h" + +/* CMSIS definitions */ +#define __ARMv8MBL_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __ARMv8MBL_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ +#define __ARMv8MBL_CMSIS_VERSION ((__ARMv8MBL_CMSIS_VERSION_MAIN << 16U) | \ + __ARMv8MBL_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ + +#define __CORTEX_M ( 2U) /*!< Cortex-M Core */ + +/** __FPU_USED indicates whether an FPU is used or not. + This core does not support an FPU at all +*/ +#define __FPU_USED 0U + +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_PCS_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TI_ARM__ ) + #if defined __TI_VFP_SUPPORT__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_ARMV8MBL_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_ARMV8MBL_H_DEPENDANT +#define __CORE_ARMV8MBL_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __ARMv8MBL_REV + #define __ARMv8MBL_REV 0x0000U + #warning "__ARMv8MBL_REV not defined in device header file; using default!" + #endif + + #ifndef __FPU_PRESENT + #define __FPU_PRESENT 0U + #warning "__FPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0U + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __SAUREGION_PRESENT + #define __SAUREGION_PRESENT 0U + #warning "__SAUREGION_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __VTOR_PRESENT + #define __VTOR_PRESENT 0U + #warning "__VTOR_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 2U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif + + #ifndef __ETM_PRESENT + #define __ETM_PRESENT 0U + #warning "__ETM_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __MTB_PRESENT + #define __MTB_PRESENT 0U + #warning "__MTB_PRESENT not defined in device header file; using default!" + #endif + +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group ARMv8MBL */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug Register + - Core MPU Register + - Core SAU Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:28; /*!< bit: 0..27 Reserved */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t _reserved1:3; /*!< bit: 25..27 Reserved */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL:1; /*!< bit: 1 Stack-pointer select */ + uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ +#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[16U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[16U]; + __IOM uint32_t ICER[16U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[16U]; + __IOM uint32_t ISPR[16U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[16U]; + __IOM uint32_t ICPR[16U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[16U]; + __IOM uint32_t IABR[16U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[16U]; + __IOM uint32_t ITNS[16U]; /*!< Offset: 0x280 (R/W) Interrupt Non-Secure State Register */ + uint32_t RESERVED5[16U]; + __IOM uint32_t IPR[124U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */ +} NVIC_Type; + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) + __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ +#else + uint32_t RESERVED0; +#endif + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + uint32_t RESERVED1; + __IOM uint32_t SHPR[2U]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_PENDNMISET_Pos 31U /*!< SCB ICSR: PENDNMISET Position */ +#define SCB_ICSR_PENDNMISET_Msk (1UL << SCB_ICSR_PENDNMISET_Pos) /*!< SCB ICSR: PENDNMISET Mask */ + +#define SCB_ICSR_NMIPENDSET_Pos SCB_ICSR_PENDNMISET_Pos /*!< SCB ICSR: NMIPENDSET Position, backward compatibility */ +#define SCB_ICSR_NMIPENDSET_Msk SCB_ICSR_PENDNMISET_Msk /*!< SCB ICSR: NMIPENDSET Mask, backward compatibility */ + +#define SCB_ICSR_PENDNMICLR_Pos 30U /*!< SCB ICSR: PENDNMICLR Position */ +#define SCB_ICSR_PENDNMICLR_Msk (1UL << SCB_ICSR_PENDNMICLR_Pos) /*!< SCB ICSR: PENDNMICLR Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_STTNS_Pos 24U /*!< SCB ICSR: STTNS Position (Security Extension) */ +#define SCB_ICSR_STTNS_Msk (1UL << SCB_ICSR_STTNS_Pos) /*!< SCB ICSR: STTNS Mask (Security Extension) */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_RETTOBASE_Pos 11U /*!< SCB ICSR: RETTOBASE Position */ +#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) +/* SCB Vector Table Offset Register Definitions */ +#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ +#endif + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_PRIS_Pos 14U /*!< SCB AIRCR: PRIS Position */ +#define SCB_AIRCR_PRIS_Msk (1UL << SCB_AIRCR_PRIS_Pos) /*!< SCB AIRCR: PRIS Mask */ + +#define SCB_AIRCR_BFHFNMINS_Pos 13U /*!< SCB AIRCR: BFHFNMINS Position */ +#define SCB_AIRCR_BFHFNMINS_Msk (1UL << SCB_AIRCR_BFHFNMINS_Pos) /*!< SCB AIRCR: BFHFNMINS Mask */ + +#define SCB_AIRCR_SYSRESETREQS_Pos 3U /*!< SCB AIRCR: SYSRESETREQS Position */ +#define SCB_AIRCR_SYSRESETREQS_Msk (1UL << SCB_AIRCR_SYSRESETREQS_Pos) /*!< SCB AIRCR: SYSRESETREQS Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEPS_Pos 3U /*!< SCB SCR: SLEEPDEEPS Position */ +#define SCB_SCR_SLEEPDEEPS_Msk (1UL << SCB_SCR_SLEEPDEEPS_Pos) /*!< SCB SCR: SLEEPDEEPS Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_BP_Pos 18U /*!< SCB CCR: BP Position */ +#define SCB_CCR_BP_Msk (1UL << SCB_CCR_BP_Pos) /*!< SCB CCR: BP Mask */ + +#define SCB_CCR_IC_Pos 17U /*!< SCB CCR: IC Position */ +#define SCB_CCR_IC_Msk (1UL << SCB_CCR_IC_Pos) /*!< SCB CCR: IC Mask */ + +#define SCB_CCR_DC_Pos 16U /*!< SCB CCR: DC Position */ +#define SCB_CCR_DC_Msk (1UL << SCB_CCR_DC_Pos) /*!< SCB CCR: DC Mask */ + +#define SCB_CCR_STKOFHFNMIGN_Pos 10U /*!< SCB CCR: STKOFHFNMIGN Position */ +#define SCB_CCR_STKOFHFNMIGN_Msk (1UL << SCB_CCR_STKOFHFNMIGN_Pos) /*!< SCB CCR: STKOFHFNMIGN Mask */ + +#define SCB_CCR_BFHFNMIGN_Pos 8U /*!< SCB CCR: BFHFNMIGN Position */ +#define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ + +#define SCB_CCR_DIV_0_TRP_Pos 4U /*!< SCB CCR: DIV_0_TRP Position */ +#define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +#define SCB_CCR_USERSETMPEND_Pos 1U /*!< SCB CCR: USERSETMPEND Position */ +#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_HARDFAULTPENDED_Pos 21U /*!< SCB SHCSR: HARDFAULTPENDED Position */ +#define SCB_SHCSR_HARDFAULTPENDED_Msk (1UL << SCB_SHCSR_HARDFAULTPENDED_Pos) /*!< SCB SHCSR: HARDFAULTPENDED Mask */ + +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +#define SCB_SHCSR_SYSTICKACT_Pos 11U /*!< SCB SHCSR: SYSTICKACT Position */ +#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ + +#define SCB_SHCSR_PENDSVACT_Pos 10U /*!< SCB SHCSR: PENDSVACT Position */ +#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ + +#define SCB_SHCSR_SVCALLACT_Pos 7U /*!< SCB SHCSR: SVCALLACT Position */ +#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ + +#define SCB_SHCSR_NMIACT_Pos 5U /*!< SCB SHCSR: NMIACT Position */ +#define SCB_SHCSR_NMIACT_Msk (1UL << SCB_SHCSR_NMIACT_Pos) /*!< SCB SHCSR: NMIACT Mask */ + +#define SCB_SHCSR_HARDFAULTACT_Pos 2U /*!< SCB SHCSR: HARDFAULTACT Position */ +#define SCB_SHCSR_HARDFAULTACT_Msk (1UL << SCB_SHCSR_HARDFAULTACT_Pos) /*!< SCB SHCSR: HARDFAULTACT Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) + \brief Type definitions for the Data Watchpoint and Trace (DWT) + @{ + */ + +/** + \brief Structure type to access the Data Watchpoint and Trace Register (DWT). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ + uint32_t RESERVED0[6U]; + __IM uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ + __IOM uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ + uint32_t RESERVED1[1U]; + __IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ + uint32_t RESERVED2[1U]; + __IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ + uint32_t RESERVED3[1U]; + __IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ + uint32_t RESERVED4[1U]; + __IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ + uint32_t RESERVED5[1U]; + __IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ + uint32_t RESERVED6[1U]; + __IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ + uint32_t RESERVED7[1U]; + __IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ + uint32_t RESERVED8[1U]; + __IOM uint32_t COMP4; /*!< Offset: 0x060 (R/W) Comparator Register 4 */ + uint32_t RESERVED9[1U]; + __IOM uint32_t FUNCTION4; /*!< Offset: 0x068 (R/W) Function Register 4 */ + uint32_t RESERVED10[1U]; + __IOM uint32_t COMP5; /*!< Offset: 0x070 (R/W) Comparator Register 5 */ + uint32_t RESERVED11[1U]; + __IOM uint32_t FUNCTION5; /*!< Offset: 0x078 (R/W) Function Register 5 */ + uint32_t RESERVED12[1U]; + __IOM uint32_t COMP6; /*!< Offset: 0x080 (R/W) Comparator Register 6 */ + uint32_t RESERVED13[1U]; + __IOM uint32_t FUNCTION6; /*!< Offset: 0x088 (R/W) Function Register 6 */ + uint32_t RESERVED14[1U]; + __IOM uint32_t COMP7; /*!< Offset: 0x090 (R/W) Comparator Register 7 */ + uint32_t RESERVED15[1U]; + __IOM uint32_t FUNCTION7; /*!< Offset: 0x098 (R/W) Function Register 7 */ + uint32_t RESERVED16[1U]; + __IOM uint32_t COMP8; /*!< Offset: 0x0A0 (R/W) Comparator Register 8 */ + uint32_t RESERVED17[1U]; + __IOM uint32_t FUNCTION8; /*!< Offset: 0x0A8 (R/W) Function Register 8 */ + uint32_t RESERVED18[1U]; + __IOM uint32_t COMP9; /*!< Offset: 0x0B0 (R/W) Comparator Register 9 */ + uint32_t RESERVED19[1U]; + __IOM uint32_t FUNCTION9; /*!< Offset: 0x0B8 (R/W) Function Register 9 */ + uint32_t RESERVED20[1U]; + __IOM uint32_t COMP10; /*!< Offset: 0x0C0 (R/W) Comparator Register 10 */ + uint32_t RESERVED21[1U]; + __IOM uint32_t FUNCTION10; /*!< Offset: 0x0C8 (R/W) Function Register 10 */ + uint32_t RESERVED22[1U]; + __IOM uint32_t COMP11; /*!< Offset: 0x0D0 (R/W) Comparator Register 11 */ + uint32_t RESERVED23[1U]; + __IOM uint32_t FUNCTION11; /*!< Offset: 0x0D8 (R/W) Function Register 11 */ + uint32_t RESERVED24[1U]; + __IOM uint32_t COMP12; /*!< Offset: 0x0E0 (R/W) Comparator Register 12 */ + uint32_t RESERVED25[1U]; + __IOM uint32_t FUNCTION12; /*!< Offset: 0x0E8 (R/W) Function Register 12 */ + uint32_t RESERVED26[1U]; + __IOM uint32_t COMP13; /*!< Offset: 0x0F0 (R/W) Comparator Register 13 */ + uint32_t RESERVED27[1U]; + __IOM uint32_t FUNCTION13; /*!< Offset: 0x0F8 (R/W) Function Register 13 */ + uint32_t RESERVED28[1U]; + __IOM uint32_t COMP14; /*!< Offset: 0x100 (R/W) Comparator Register 14 */ + uint32_t RESERVED29[1U]; + __IOM uint32_t FUNCTION14; /*!< Offset: 0x108 (R/W) Function Register 14 */ + uint32_t RESERVED30[1U]; + __IOM uint32_t COMP15; /*!< Offset: 0x110 (R/W) Comparator Register 15 */ + uint32_t RESERVED31[1U]; + __IOM uint32_t FUNCTION15; /*!< Offset: 0x118 (R/W) Function Register 15 */ +} DWT_Type; + +/* DWT Control Register Definitions */ +#define DWT_CTRL_NUMCOMP_Pos 28U /*!< DWT CTRL: NUMCOMP Position */ +#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ + +#define DWT_CTRL_NOTRCPKT_Pos 27U /*!< DWT CTRL: NOTRCPKT Position */ +#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ + +#define DWT_CTRL_NOEXTTRIG_Pos 26U /*!< DWT CTRL: NOEXTTRIG Position */ +#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ + +#define DWT_CTRL_NOCYCCNT_Pos 25U /*!< DWT CTRL: NOCYCCNT Position */ +#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ + +#define DWT_CTRL_NOPRFCNT_Pos 24U /*!< DWT CTRL: NOPRFCNT Position */ +#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ + +/* DWT Comparator Function Register Definitions */ +#define DWT_FUNCTION_ID_Pos 27U /*!< DWT FUNCTION: ID Position */ +#define DWT_FUNCTION_ID_Msk (0x1FUL << DWT_FUNCTION_ID_Pos) /*!< DWT FUNCTION: ID Mask */ + +#define DWT_FUNCTION_MATCHED_Pos 24U /*!< DWT FUNCTION: MATCHED Position */ +#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ + +#define DWT_FUNCTION_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */ +#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ + +#define DWT_FUNCTION_ACTION_Pos 4U /*!< DWT FUNCTION: ACTION Position */ +#define DWT_FUNCTION_ACTION_Msk (0x3UL << DWT_FUNCTION_ACTION_Pos) /*!< DWT FUNCTION: ACTION Mask */ + +#define DWT_FUNCTION_MATCH_Pos 0U /*!< DWT FUNCTION: MATCH Position */ +#define DWT_FUNCTION_MATCH_Msk (0xFUL /*<< DWT_FUNCTION_MATCH_Pos*/) /*!< DWT FUNCTION: MATCH Mask */ + +/*@}*/ /* end of group CMSIS_DWT */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_TPI Trace Port Interface (TPI) + \brief Type definitions for the Trace Port Interface (TPI) + @{ + */ + +/** + \brief Structure type to access the Trace Port Interface Register (TPI). + */ +typedef struct +{ + __IM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Sizes Register */ + __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Sizes Register */ + uint32_t RESERVED0[2U]; + __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ + uint32_t RESERVED1[55U]; + __IOM uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ + uint32_t RESERVED2[131U]; + __IM uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ + __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ + __IOM uint32_t PSCR; /*!< Offset: 0x308 (R/W) Periodic Synchronization Control Register */ + uint32_t RESERVED3[809U]; + __OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) Software Lock Access Register */ + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) Software Lock Status Register */ + uint32_t RESERVED4[4U]; + __IM uint32_t TYPE; /*!< Offset: 0xFC8 (R/ ) Device Identifier Register */ + __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) Device Type Register */ +} TPI_Type; + +/* TPI Asynchronous Clock Prescaler Register Definitions */ +#define TPI_ACPR_SWOSCALER_Pos 0U /*!< TPI ACPR: SWOSCALER Position */ +#define TPI_ACPR_SWOSCALER_Msk (0xFFFFUL /*<< TPI_ACPR_SWOSCALER_Pos*/) /*!< TPI ACPR: SWOSCALER Mask */ + +/* TPI Selected Pin Protocol Register Definitions */ +#define TPI_SPPR_TXMODE_Pos 0U /*!< TPI SPPR: TXMODE Position */ +#define TPI_SPPR_TXMODE_Msk (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/) /*!< TPI SPPR: TXMODE Mask */ + +/* TPI Formatter and Flush Status Register Definitions */ +#define TPI_FFSR_FtNonStop_Pos 3U /*!< TPI FFSR: FtNonStop Position */ +#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ + +#define TPI_FFSR_TCPresent_Pos 2U /*!< TPI FFSR: TCPresent Position */ +#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ + +#define TPI_FFSR_FtStopped_Pos 1U /*!< TPI FFSR: FtStopped Position */ +#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ + +#define TPI_FFSR_FlInProg_Pos 0U /*!< TPI FFSR: FlInProg Position */ +#define TPI_FFSR_FlInProg_Msk (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/) /*!< TPI FFSR: FlInProg Mask */ + +/* TPI Formatter and Flush Control Register Definitions */ +#define TPI_FFCR_TrigIn_Pos 8U /*!< TPI FFCR: TrigIn Position */ +#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ + +#define TPI_FFCR_FOnMan_Pos 6U /*!< TPI FFCR: FOnMan Position */ +#define TPI_FFCR_FOnMan_Msk (0x1UL << TPI_FFCR_FOnMan_Pos) /*!< TPI FFCR: FOnMan Mask */ + +#define TPI_FFCR_EnFCont_Pos 1U /*!< TPI FFCR: EnFCont Position */ +#define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ + +/* TPI Periodic Synchronization Control Register Definitions */ +#define TPI_PSCR_PSCount_Pos 0U /*!< TPI PSCR: PSCount Position */ +#define TPI_PSCR_PSCount_Msk (0x1FUL /*<< TPI_PSCR_PSCount_Pos*/) /*!< TPI PSCR: TPSCount Mask */ + +/* TPI Software Lock Status Register Definitions */ +#define TPI_LSR_nTT_Pos 1U /*!< TPI LSR: Not thirty-two bit. Position */ +#define TPI_LSR_nTT_Msk (0x1UL << TPI_LSR_nTT_Pos) /*!< TPI LSR: Not thirty-two bit. Mask */ + +#define TPI_LSR_SLK_Pos 1U /*!< TPI LSR: Software Lock status Position */ +#define TPI_LSR_SLK_Msk (0x1UL << TPI_LSR_SLK_Pos) /*!< TPI LSR: Software Lock status Mask */ + +#define TPI_LSR_SLI_Pos 0U /*!< TPI LSR: Software Lock implemented Position */ +#define TPI_LSR_SLI_Msk (0x1UL /*<< TPI_LSR_SLI_Pos*/) /*!< TPI LSR: Software Lock implemented Mask */ + +/* TPI DEVID Register Definitions */ +#define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */ +#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ + +#define TPI_DEVID_MANCVALID_Pos 10U /*!< TPI DEVID: MANCVALID Position */ +#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ + +#define TPI_DEVID_PTINVALID_Pos 9U /*!< TPI DEVID: PTINVALID Position */ +#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ + +#define TPI_DEVID_FIFOSZ_Pos 6U /*!< TPI DEVID: FIFO depth Position */ +#define TPI_DEVID_FIFOSZ_Msk (0x7UL << TPI_DEVID_FIFOSZ_Pos) /*!< TPI DEVID: FIFO depth Mask */ + +/* TPI DEVTYPE Register Definitions */ +#define TPI_DEVTYPE_SubType_Pos 4U /*!< TPI DEVTYPE: SubType Position */ +#define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ + +#define TPI_DEVTYPE_MajorType_Pos 0U /*!< TPI DEVTYPE: MajorType Position */ +#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ + +/*@}*/ /* end of group CMSIS_TPI */ + + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** + \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region Number Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) MPU Region Limit Address Register */ + uint32_t RESERVED0[7U]; + union { + __IOM uint32_t MAIR[2]; + struct { + __IOM uint32_t MAIR0; /*!< Offset: 0x030 (R/W) MPU Memory Attribute Indirection Register 0 */ + __IOM uint32_t MAIR1; /*!< Offset: 0x034 (R/W) MPU Memory Attribute Indirection Register 1 */ + }; + }; +} MPU_Type; + +#define MPU_TYPE_RALIASES 1U + +/* MPU Type Register Definitions */ +#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register Definitions */ +#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register Definitions */ +#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register Definitions */ +#define MPU_RBAR_BASE_Pos 5U /*!< MPU RBAR: BASE Position */ +#define MPU_RBAR_BASE_Msk (0x7FFFFFFUL << MPU_RBAR_BASE_Pos) /*!< MPU RBAR: BASE Mask */ + +#define MPU_RBAR_SH_Pos 3U /*!< MPU RBAR: SH Position */ +#define MPU_RBAR_SH_Msk (0x3UL << MPU_RBAR_SH_Pos) /*!< MPU RBAR: SH Mask */ + +#define MPU_RBAR_AP_Pos 1U /*!< MPU RBAR: AP Position */ +#define MPU_RBAR_AP_Msk (0x3UL << MPU_RBAR_AP_Pos) /*!< MPU RBAR: AP Mask */ + +#define MPU_RBAR_XN_Pos 0U /*!< MPU RBAR: XN Position */ +#define MPU_RBAR_XN_Msk (01UL /*<< MPU_RBAR_XN_Pos*/) /*!< MPU RBAR: XN Mask */ + +/* MPU Region Limit Address Register Definitions */ +#define MPU_RLAR_LIMIT_Pos 5U /*!< MPU RLAR: LIMIT Position */ +#define MPU_RLAR_LIMIT_Msk (0x7FFFFFFUL << MPU_RLAR_LIMIT_Pos) /*!< MPU RLAR: LIMIT Mask */ + +#define MPU_RLAR_AttrIndx_Pos 1U /*!< MPU RLAR: AttrIndx Position */ +#define MPU_RLAR_AttrIndx_Msk (0x7UL << MPU_RLAR_AttrIndx_Pos) /*!< MPU RLAR: AttrIndx Mask */ + +#define MPU_RLAR_EN_Pos 0U /*!< MPU RLAR: EN Position */ +#define MPU_RLAR_EN_Msk (1UL /*<< MPU_RLAR_EN_Pos*/) /*!< MPU RLAR: EN Mask */ + +/* MPU Memory Attribute Indirection Register 0 Definitions */ +#define MPU_MAIR0_Attr3_Pos 24U /*!< MPU MAIR0: Attr3 Position */ +#define MPU_MAIR0_Attr3_Msk (0xFFUL << MPU_MAIR0_Attr3_Pos) /*!< MPU MAIR0: Attr3 Mask */ + +#define MPU_MAIR0_Attr2_Pos 16U /*!< MPU MAIR0: Attr2 Position */ +#define MPU_MAIR0_Attr2_Msk (0xFFUL << MPU_MAIR0_Attr2_Pos) /*!< MPU MAIR0: Attr2 Mask */ + +#define MPU_MAIR0_Attr1_Pos 8U /*!< MPU MAIR0: Attr1 Position */ +#define MPU_MAIR0_Attr1_Msk (0xFFUL << MPU_MAIR0_Attr1_Pos) /*!< MPU MAIR0: Attr1 Mask */ + +#define MPU_MAIR0_Attr0_Pos 0U /*!< MPU MAIR0: Attr0 Position */ +#define MPU_MAIR0_Attr0_Msk (0xFFUL /*<< MPU_MAIR0_Attr0_Pos*/) /*!< MPU MAIR0: Attr0 Mask */ + +/* MPU Memory Attribute Indirection Register 1 Definitions */ +#define MPU_MAIR1_Attr7_Pos 24U /*!< MPU MAIR1: Attr7 Position */ +#define MPU_MAIR1_Attr7_Msk (0xFFUL << MPU_MAIR1_Attr7_Pos) /*!< MPU MAIR1: Attr7 Mask */ + +#define MPU_MAIR1_Attr6_Pos 16U /*!< MPU MAIR1: Attr6 Position */ +#define MPU_MAIR1_Attr6_Msk (0xFFUL << MPU_MAIR1_Attr6_Pos) /*!< MPU MAIR1: Attr6 Mask */ + +#define MPU_MAIR1_Attr5_Pos 8U /*!< MPU MAIR1: Attr5 Position */ +#define MPU_MAIR1_Attr5_Msk (0xFFUL << MPU_MAIR1_Attr5_Pos) /*!< MPU MAIR1: Attr5 Mask */ + +#define MPU_MAIR1_Attr4_Pos 0U /*!< MPU MAIR1: Attr4 Position */ +#define MPU_MAIR1_Attr4_Msk (0xFFUL /*<< MPU_MAIR1_Attr4_Pos*/) /*!< MPU MAIR1: Attr4 Mask */ + +/*@} end of group CMSIS_MPU */ +#endif + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SAU Security Attribution Unit (SAU) + \brief Type definitions for the Security Attribution Unit (SAU) + @{ + */ + +/** + \brief Structure type to access the Security Attribution Unit (SAU). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SAU Control Register */ + __IM uint32_t TYPE; /*!< Offset: 0x004 (R/ ) SAU Type Register */ +#if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) SAU Region Number Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) SAU Region Base Address Register */ + __IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) SAU Region Limit Address Register */ +#endif +} SAU_Type; + +/* SAU Control Register Definitions */ +#define SAU_CTRL_ALLNS_Pos 1U /*!< SAU CTRL: ALLNS Position */ +#define SAU_CTRL_ALLNS_Msk (1UL << SAU_CTRL_ALLNS_Pos) /*!< SAU CTRL: ALLNS Mask */ + +#define SAU_CTRL_ENABLE_Pos 0U /*!< SAU CTRL: ENABLE Position */ +#define SAU_CTRL_ENABLE_Msk (1UL /*<< SAU_CTRL_ENABLE_Pos*/) /*!< SAU CTRL: ENABLE Mask */ + +/* SAU Type Register Definitions */ +#define SAU_TYPE_SREGION_Pos 0U /*!< SAU TYPE: SREGION Position */ +#define SAU_TYPE_SREGION_Msk (0xFFUL /*<< SAU_TYPE_SREGION_Pos*/) /*!< SAU TYPE: SREGION Mask */ + +#if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) +/* SAU Region Number Register Definitions */ +#define SAU_RNR_REGION_Pos 0U /*!< SAU RNR: REGION Position */ +#define SAU_RNR_REGION_Msk (0xFFUL /*<< SAU_RNR_REGION_Pos*/) /*!< SAU RNR: REGION Mask */ + +/* SAU Region Base Address Register Definitions */ +#define SAU_RBAR_BADDR_Pos 5U /*!< SAU RBAR: BADDR Position */ +#define SAU_RBAR_BADDR_Msk (0x7FFFFFFUL << SAU_RBAR_BADDR_Pos) /*!< SAU RBAR: BADDR Mask */ + +/* SAU Region Limit Address Register Definitions */ +#define SAU_RLAR_LADDR_Pos 5U /*!< SAU RLAR: LADDR Position */ +#define SAU_RLAR_LADDR_Msk (0x7FFFFFFUL << SAU_RLAR_LADDR_Pos) /*!< SAU RLAR: LADDR Mask */ + +#define SAU_RLAR_NSC_Pos 1U /*!< SAU RLAR: NSC Position */ +#define SAU_RLAR_NSC_Msk (1UL << SAU_RLAR_NSC_Pos) /*!< SAU RLAR: NSC Mask */ + +#define SAU_RLAR_ENABLE_Pos 0U /*!< SAU RLAR: ENABLE Position */ +#define SAU_RLAR_ENABLE_Msk (1UL /*<< SAU_RLAR_ENABLE_Pos*/) /*!< SAU RLAR: ENABLE Mask */ + +#endif /* defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) */ + +/*@} end of group CMSIS_SAU */ +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Type definitions for the Core Debug Registers + @{ + */ + +/** + \brief Structure type to access the Core Debug Register (CoreDebug). + */ +typedef struct +{ + __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ + uint32_t RESERVED4[1U]; + __IOM uint32_t DAUTHCTRL; /*!< Offset: 0x014 (R/W) Debug Authentication Control Register */ + __IOM uint32_t DSCSR; /*!< Offset: 0x018 (R/W) Debug Security Control and Status Register */ +} CoreDebug_Type; + +/* Debug Halting Control and Status Register Definitions */ +#define CoreDebug_DHCSR_DBGKEY_Pos 16U /*!< CoreDebug DHCSR: DBGKEY Position */ +#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */ + +#define CoreDebug_DHCSR_S_RESTART_ST_Pos 26U /*!< CoreDebug DHCSR: S_RESTART_ST Position */ +#define CoreDebug_DHCSR_S_RESTART_ST_Msk (1UL << CoreDebug_DHCSR_S_RESTART_ST_Pos) /*!< CoreDebug DHCSR: S_RESTART_ST Mask */ + +#define CoreDebug_DHCSR_S_RESET_ST_Pos 25U /*!< CoreDebug DHCSR: S_RESET_ST Position */ +#define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< CoreDebug DHCSR: S_RESET_ST Mask */ + +#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24U /*!< CoreDebug DHCSR: S_RETIRE_ST Position */ +#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */ + +#define CoreDebug_DHCSR_S_LOCKUP_Pos 19U /*!< CoreDebug DHCSR: S_LOCKUP Position */ +#define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< CoreDebug DHCSR: S_LOCKUP Mask */ + +#define CoreDebug_DHCSR_S_SLEEP_Pos 18U /*!< CoreDebug DHCSR: S_SLEEP Position */ +#define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< CoreDebug DHCSR: S_SLEEP Mask */ + +#define CoreDebug_DHCSR_S_HALT_Pos 17U /*!< CoreDebug DHCSR: S_HALT Position */ +#define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< CoreDebug DHCSR: S_HALT Mask */ + +#define CoreDebug_DHCSR_S_REGRDY_Pos 16U /*!< CoreDebug DHCSR: S_REGRDY Position */ +#define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< CoreDebug DHCSR: S_REGRDY Mask */ + +#define CoreDebug_DHCSR_C_MASKINTS_Pos 3U /*!< CoreDebug DHCSR: C_MASKINTS Position */ +#define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< CoreDebug DHCSR: C_MASKINTS Mask */ + +#define CoreDebug_DHCSR_C_STEP_Pos 2U /*!< CoreDebug DHCSR: C_STEP Position */ +#define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< CoreDebug DHCSR: C_STEP Mask */ + +#define CoreDebug_DHCSR_C_HALT_Pos 1U /*!< CoreDebug DHCSR: C_HALT Position */ +#define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< CoreDebug DHCSR: C_HALT Mask */ + +#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0U /*!< CoreDebug DHCSR: C_DEBUGEN Position */ +#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */ + +/* Debug Core Register Selector Register Definitions */ +#define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< CoreDebug DCRSR: REGWnR Position */ +#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ + +#define CoreDebug_DCRSR_REGSEL_Pos 0U /*!< CoreDebug DCRSR: REGSEL Position */ +#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/) /*!< CoreDebug DCRSR: REGSEL Mask */ + +/* Debug Exception and Monitor Control Register */ +#define CoreDebug_DEMCR_DWTENA_Pos 24U /*!< CoreDebug DEMCR: DWTENA Position */ +#define CoreDebug_DEMCR_DWTENA_Msk (1UL << CoreDebug_DEMCR_DWTENA_Pos) /*!< CoreDebug DEMCR: DWTENA Mask */ + +#define CoreDebug_DEMCR_VC_HARDERR_Pos 10U /*!< CoreDebug DEMCR: VC_HARDERR Position */ +#define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< CoreDebug DEMCR: VC_HARDERR Mask */ + +#define CoreDebug_DEMCR_VC_CORERESET_Pos 0U /*!< CoreDebug DEMCR: VC_CORERESET Position */ +#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/) /*!< CoreDebug DEMCR: VC_CORERESET Mask */ + +/* Debug Authentication Control Register Definitions */ +#define CoreDebug_DAUTHCTRL_INTSPNIDEN_Pos 3U /*!< CoreDebug DAUTHCTRL: INTSPNIDEN, Position */ +#define CoreDebug_DAUTHCTRL_INTSPNIDEN_Msk (1UL << CoreDebug_DAUTHCTRL_INTSPNIDEN_Pos) /*!< CoreDebug DAUTHCTRL: INTSPNIDEN, Mask */ + +#define CoreDebug_DAUTHCTRL_SPNIDENSEL_Pos 2U /*!< CoreDebug DAUTHCTRL: SPNIDENSEL Position */ +#define CoreDebug_DAUTHCTRL_SPNIDENSEL_Msk (1UL << CoreDebug_DAUTHCTRL_SPNIDENSEL_Pos) /*!< CoreDebug DAUTHCTRL: SPNIDENSEL Mask */ + +#define CoreDebug_DAUTHCTRL_INTSPIDEN_Pos 1U /*!< CoreDebug DAUTHCTRL: INTSPIDEN Position */ +#define CoreDebug_DAUTHCTRL_INTSPIDEN_Msk (1UL << CoreDebug_DAUTHCTRL_INTSPIDEN_Pos) /*!< CoreDebug DAUTHCTRL: INTSPIDEN Mask */ + +#define CoreDebug_DAUTHCTRL_SPIDENSEL_Pos 0U /*!< CoreDebug DAUTHCTRL: SPIDENSEL Position */ +#define CoreDebug_DAUTHCTRL_SPIDENSEL_Msk (1UL /*<< CoreDebug_DAUTHCTRL_SPIDENSEL_Pos*/) /*!< CoreDebug DAUTHCTRL: SPIDENSEL Mask */ + +/* Debug Security Control and Status Register Definitions */ +#define CoreDebug_DSCSR_CDS_Pos 16U /*!< CoreDebug DSCSR: CDS Position */ +#define CoreDebug_DSCSR_CDS_Msk (1UL << CoreDebug_DSCSR_CDS_Pos) /*!< CoreDebug DSCSR: CDS Mask */ + +#define CoreDebug_DSCSR_SBRSEL_Pos 1U /*!< CoreDebug DSCSR: SBRSEL Position */ +#define CoreDebug_DSCSR_SBRSEL_Msk (1UL << CoreDebug_DSCSR_SBRSEL_Pos) /*!< CoreDebug DSCSR: SBRSEL Mask */ + +#define CoreDebug_DSCSR_SBRSELEN_Pos 0U /*!< CoreDebug DSCSR: SBRSELEN Position */ +#define CoreDebug_DSCSR_SBRSELEN_Msk (1UL /*<< CoreDebug_DSCSR_SBRSELEN_Pos*/) /*!< CoreDebug DSCSR: SBRSELEN Mask */ + +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param[in] field Name of the register bit field. + \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param[in] field Name of the register bit field. + \param[in] value Value of register. This parameter is interpreted as an uint32_t type. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) + +/*@} end of group CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Core Hardware */ + #define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ + #define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ + #define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ + #define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */ + #define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ + #define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ + #define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + + + #define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ + #define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ + #define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ + #define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ + #define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ + #define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE ) /*!< Core Debug configuration struct */ + + #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ + #endif + + #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + #define SAU_BASE (SCS_BASE + 0x0DD0UL) /*!< Security Attribution Unit */ + #define SAU ((SAU_Type *) SAU_BASE ) /*!< Security Attribution Unit */ + #endif + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + #define SCS_BASE_NS (0xE002E000UL) /*!< System Control Space Base Address (non-secure address space) */ + #define CoreDebug_BASE_NS (0xE002EDF0UL) /*!< Core Debug Base Address (non-secure address space) */ + #define SysTick_BASE_NS (SCS_BASE_NS + 0x0010UL) /*!< SysTick Base Address (non-secure address space) */ + #define NVIC_BASE_NS (SCS_BASE_NS + 0x0100UL) /*!< NVIC Base Address (non-secure address space) */ + #define SCB_BASE_NS (SCS_BASE_NS + 0x0D00UL) /*!< System Control Block Base Address (non-secure address space) */ + + #define SCB_NS ((SCB_Type *) SCB_BASE_NS ) /*!< SCB configuration struct (non-secure address space) */ + #define SysTick_NS ((SysTick_Type *) SysTick_BASE_NS ) /*!< SysTick configuration struct (non-secure address space) */ + #define NVIC_NS ((NVIC_Type *) NVIC_BASE_NS ) /*!< NVIC configuration struct (non-secure address space) */ + #define CoreDebug_NS ((CoreDebug_Type *) CoreDebug_BASE_NS) /*!< Core Debug configuration struct (non-secure address space) */ + + #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE_NS (SCS_BASE_NS + 0x0D90UL) /*!< Memory Protection Unit (non-secure address space) */ + #define MPU_NS ((MPU_Type *) MPU_BASE_NS ) /*!< Memory Protection Unit (non-secure address space) */ + #endif + +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping + #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping + #define NVIC_EnableIRQ __NVIC_EnableIRQ + #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ + #define NVIC_DisableIRQ __NVIC_DisableIRQ + #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ + #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ + #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ + #define NVIC_GetActive __NVIC_GetActive + #define NVIC_SetPriority __NVIC_SetPriority + #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset +#endif /* CMSIS_NVIC_VIRTUAL */ + +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetVector __NVIC_SetVector + #define NVIC_GetVector __NVIC_GetVector +#endif /* (CMSIS_VECTAB_VIRTUAL) */ + +#define NVIC_USER_IRQ_OFFSET 16 + + +/* Special LR values for Secure/Non-Secure call handling and exception handling */ + +/* Function Return Payload (from ARMv8-M Architecture Reference Manual) LR value on entry from Secure BLXNS */ +#define FNC_RETURN (0xFEFFFFFFUL) /* bit [0] ignored when processing a branch */ + +/* The following EXC_RETURN mask values are used to evaluate the LR on exception entry */ +#define EXC_RETURN_PREFIX (0xFF000000UL) /* bits [31:24] set to indicate an EXC_RETURN value */ +#define EXC_RETURN_S (0x00000040UL) /* bit [6] stack used to push registers: 0=Non-secure 1=Secure */ +#define EXC_RETURN_DCRS (0x00000020UL) /* bit [5] stacking rules for called registers: 0=skipped 1=saved */ +#define EXC_RETURN_FTYPE (0x00000010UL) /* bit [4] allocate stack for floating-point context: 0=done 1=skipped */ +#define EXC_RETURN_MODE (0x00000008UL) /* bit [3] processor mode for return: 0=Handler mode 1=Thread mode */ +#define EXC_RETURN_SPSEL (0x00000002UL) /* bit [1] stack pointer used to restore context: 0=MSP 1=PSP */ +#define EXC_RETURN_ES (0x00000001UL) /* bit [0] security state exception was taken to: 0=Non-secure 1=Secure */ + +/* Integrity Signature (from ARMv8-M Architecture Reference Manual) for exception context stacking */ +#if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) /* Value for processors with floating-point extension: */ +#define EXC_INTEGRITY_SIGNATURE (0xFEFA125AUL) /* bit [0] SFTC must match LR bit[4] EXC_RETURN_FTYPE */ +#else +#define EXC_INTEGRITY_SIGNATURE (0xFEFA125BUL) /* Value for processors without floating-point extension */ +#endif + + +/* Interrupt Priorities are WORD accessible only under Armv6-M */ +/* The following MACROS handle generation of the register offset and byte masks */ +#define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL) +#define _SHP_IDX(IRQn) ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >> 2UL) ) +#define _IP_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 2UL) ) + +#define __NVIC_SetPriorityGrouping(X) (void)(X) +#define __NVIC_GetPriorityGrouping() (0U) + +/** + \brief Enable Interrupt + \details Enables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Interrupt Enable status + \details Returns a device specific interrupt enable status from the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt + \details Disables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __DSB(); + __ISB(); + } +} + + +/** + \brief Get Pending Interrupt + \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt + \details Reads the active register in the NVIC and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetActive(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Get Interrupt Target State + \details Reads the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + \return 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_GetTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Target State + \details Sets the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_SetTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] |= ((uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL))); + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Clear Interrupt Target State + \details Clears the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_ClearTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] &= ~((uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL))); + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + + +/** + \brief Set Interrupt Priority + \details Sets the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every processor exception. + */ +__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->IPR[_IP_IDX(IRQn)] = ((uint32_t)(NVIC->IPR[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } + else + { + SCB->SHPR[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHPR[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IPR[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return((uint32_t)(((SCB->SHPR[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief Encode Priority + \details Encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + return ( + ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | + ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) + ); +} + + +/** + \brief Decode Priority + \details Decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. + \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); + *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); +} + + +/** + \brief Set Interrupt Vector + \details Sets an interrupt vector in SRAM based interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + VTOR must been relocated to SRAM before. + If VTOR is not present address 0 must be mapped to SRAM. + \param [in] IRQn Interrupt number + \param [in] vector Address of interrupt handler function + */ +__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) +{ +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) + uint32_t *vectors = (uint32_t *)SCB->VTOR; +#else + uint32_t *vectors = (uint32_t *)0x0U; +#endif + vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; +} + + +/** + \brief Get Interrupt Vector + \details Reads an interrupt vector from interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Address of interrupt handler function + */ +__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) +{ +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) + uint32_t *vectors = (uint32_t *)SCB->VTOR; +#else + uint32_t *vectors = (uint32_t *)0x0U; +#endif + return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET]; +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + SCB_AIRCR_SYSRESETREQ_Msk); + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Enable Interrupt (non-secure) + \details Enables a device specific interrupt in the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_EnableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Interrupt Enable status (non-secure) + \details Returns a device specific interrupt enable status from the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetEnableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt (non-secure) + \details Disables a device specific interrupt in the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_DisableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Pending Interrupt (non-secure) + \details Reads the NVIC pending register in the non-secure NVIC when in secure state and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt (non-secure) + \details Sets the pending bit of a device specific interrupt in the non-secure NVIC pending register when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_SetPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt (non-secure) + \details Clears the pending bit of a device specific interrupt in the non-secure NVIC pending register when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_ClearPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt (non-secure) + \details Reads the active register in non-secure NVIC when in secure state and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetActive_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Priority (non-secure) + \details Sets the priority of a non-secure device specific interrupt or a non-secure processor exception when in secure state. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every non-secure processor exception. + */ +__STATIC_INLINE void TZ_NVIC_SetPriority_NS(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->IPR[_IP_IDX(IRQn)] = ((uint32_t)(NVIC_NS->IPR[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } + else + { + SCB_NS->SHPR[_SHP_IDX(IRQn)] = ((uint32_t)(SCB_NS->SHPR[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } +} + + +/** + \brief Get Interrupt Priority (non-secure) + \details Reads the priority of a non-secure device specific interrupt or a non-secure processor exception when in secure state. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetPriority_NS(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->IPR[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return((uint32_t)(((SCB_NS->SHPR[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } +} +#endif /* defined (__ARM_FEATURE_CMSE) &&(__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_NVICFunctions */ + +/* ########################## MPU functions #################################### */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + +#include "mpu_armv8.h" + +#endif + +/* ########################## FPU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_FpuFunctions FPU Functions + \brief Function that provides FPU type. + @{ + */ + +/** + \brief get FPU type + \details returns the FPU type + \returns + - \b 0: No FPU + - \b 1: Single precision FPU + - \b 2: Double + Single precision FPU + */ +__STATIC_INLINE uint32_t SCB_GetFPUType(void) +{ + return 0U; /* No FPU */ +} + + +/*@} end of CMSIS_Core_FpuFunctions */ + + + +/* ########################## SAU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SAUFunctions SAU Functions + \brief Functions that configure the SAU. + @{ + */ + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + +/** + \brief Enable SAU + \details Enables the Security Attribution Unit (SAU). + */ +__STATIC_INLINE void TZ_SAU_Enable(void) +{ + SAU->CTRL |= (SAU_CTRL_ENABLE_Msk); +} + + + +/** + \brief Disable SAU + \details Disables the Security Attribution Unit (SAU). + */ +__STATIC_INLINE void TZ_SAU_Disable(void) +{ + SAU->CTRL &= ~(SAU_CTRL_ENABLE_Msk); +} + +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_SAUFunctions */ + + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief System Tick Configuration (non-secure) + \details Initializes the non-secure System Timer and its interrupt when in secure state, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function TZ_SysTick_Config_NS is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + + */ +__STATIC_INLINE uint32_t TZ_SysTick_Config_NS(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick_NS->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + TZ_NVIC_SetPriority_NS (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick_NS->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick_NS->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_ARMV8MBL_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/test/STM32F072C8T6/Drivers/CMSIS/Include/core_armv8mml.h b/test/STM32F072C8T6/Drivers/CMSIS/Include/core_armv8mml.h new file mode 100644 index 0000000..2d0f106 --- /dev/null +++ b/test/STM32F072C8T6/Drivers/CMSIS/Include/core_armv8mml.h @@ -0,0 +1,2927 @@ +/**************************************************************************//** + * @file core_armv8mml.h + * @brief CMSIS Armv8-M Mainline Core Peripheral Access Layer Header File + * @version V5.0.7 + * @date 06. July 2018 + ******************************************************************************/ +/* + * Copyright (c) 2009-2018 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * 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 + * + * 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. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CORE_ARMV8MML_H_GENERIC +#define __CORE_ARMV8MML_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup Cortex_ARMv8MML + @{ + */ + +#include "cmsis_version.h" + +/* CMSIS Armv8MML definitions */ +#define __ARMv8MML_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __ARMv8MML_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ +#define __ARMv8MML_CMSIS_VERSION ((__ARMv8MML_CMSIS_VERSION_MAIN << 16U) | \ + __ARMv8MML_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ + +#define __CORTEX_M (81U) /*!< Cortex-M Core */ + +/** __FPU_USED indicates whether an FPU is used or not. + For this, __FPU_PRESENT has to be checked prior to making use of FPU specific registers and functions. +*/ +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + + #if defined(__ARM_FEATURE_DSP) + #if defined(__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_USED 0U + #endif + +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_PCS_VFP + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + + #if defined(__ARM_FEATURE_DSP) + #if defined(__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_USED 0U + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + + #if defined(__ARM_FEATURE_DSP) + #if defined(__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_USED 0U + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + + #if defined(__ARM_FEATURE_DSP) + #if defined(__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_USED 0U + #endif + +#elif defined ( __TI_ARM__ ) + #if defined __TI_VFP_SUPPORT__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_ARMV8MML_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_ARMV8MML_H_DEPENDANT +#define __CORE_ARMV8MML_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __ARMv8MML_REV + #define __ARMv8MML_REV 0x0000U + #warning "__ARMv8MML_REV not defined in device header file; using default!" + #endif + + #ifndef __FPU_PRESENT + #define __FPU_PRESENT 0U + #warning "__FPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0U + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __SAUREGION_PRESENT + #define __SAUREGION_PRESENT 0U + #warning "__SAUREGION_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __DSP_PRESENT + #define __DSP_PRESENT 0U + #warning "__DSP_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 3U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group ARMv8MML */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug Register + - Core MPU Register + - Core SAU Register + - Core FPU Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:16; /*!< bit: 0..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:7; /*!< bit: 20..26 Reserved */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + +#define APSR_Q_Pos 27U /*!< APSR: Q Position */ +#define APSR_Q_Msk (1UL << APSR_Q_Pos) /*!< APSR: Q Mask */ + +#define APSR_GE_Pos 16U /*!< APSR: GE Position */ +#define APSR_GE_Msk (0xFUL << APSR_GE_Pos) /*!< APSR: GE Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:7; /*!< bit: 9..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:4; /*!< bit: 20..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t IT:2; /*!< bit: 25..26 saved IT state (read 0) */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_Q_Pos 27U /*!< xPSR: Q Position */ +#define xPSR_Q_Msk (1UL << xPSR_Q_Pos) /*!< xPSR: Q Mask */ + +#define xPSR_IT_Pos 25U /*!< xPSR: IT Position */ +#define xPSR_IT_Msk (3UL << xPSR_IT_Pos) /*!< xPSR: IT Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_GE_Pos 16U /*!< xPSR: GE Position */ +#define xPSR_GE_Msk (0xFUL << xPSR_GE_Pos) /*!< xPSR: GE Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL:1; /*!< bit: 1 Stack-pointer select */ + uint32_t FPCA:1; /*!< bit: 2 Floating-point context active */ + uint32_t SFPA:1; /*!< bit: 3 Secure floating-point active */ + uint32_t _reserved1:28; /*!< bit: 4..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_SFPA_Pos 3U /*!< CONTROL: SFPA Position */ +#define CONTROL_SFPA_Msk (1UL << CONTROL_SFPA_Pos) /*!< CONTROL: SFPA Mask */ + +#define CONTROL_FPCA_Pos 2U /*!< CONTROL: FPCA Position */ +#define CONTROL_FPCA_Msk (1UL << CONTROL_FPCA_Pos) /*!< CONTROL: FPCA Mask */ + +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ +#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[16U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[16U]; + __IOM uint32_t ICER[16U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[16U]; + __IOM uint32_t ISPR[16U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[16U]; + __IOM uint32_t ICPR[16U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[16U]; + __IOM uint32_t IABR[16U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[16U]; + __IOM uint32_t ITNS[16U]; /*!< Offset: 0x280 (R/W) Interrupt Non-Secure State Register */ + uint32_t RESERVED5[16U]; + __IOM uint8_t IPR[496U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ + uint32_t RESERVED6[580U]; + __OM uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ +} NVIC_Type; + +/* Software Triggered Interrupt Register Definitions */ +#define NVIC_STIR_INTID_Pos 0U /*!< STIR: INTLINESNUM Position */ +#define NVIC_STIR_INTID_Msk (0x1FFUL /*<< NVIC_STIR_INTID_Pos*/) /*!< STIR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + __IOM uint8_t SHPR[12U]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ + __IOM uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ + __IOM uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ + __IOM uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ + __IOM uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ + __IOM uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ + __IOM uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ + __IM uint32_t ID_PFR[2U]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ + __IM uint32_t ID_DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ + __IM uint32_t ID_ADR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ + __IM uint32_t ID_MMFR[4U]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ + __IM uint32_t ID_ISAR[6U]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ + __IM uint32_t CLIDR; /*!< Offset: 0x078 (R/ ) Cache Level ID register */ + __IM uint32_t CTR; /*!< Offset: 0x07C (R/ ) Cache Type register */ + __IM uint32_t CCSIDR; /*!< Offset: 0x080 (R/ ) Cache Size ID Register */ + __IOM uint32_t CSSELR; /*!< Offset: 0x084 (R/W) Cache Size Selection Register */ + __IOM uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ + __IOM uint32_t NSACR; /*!< Offset: 0x08C (R/W) Non-Secure Access Control Register */ + uint32_t RESERVED3[92U]; + __OM uint32_t STIR; /*!< Offset: 0x200 ( /W) Software Triggered Interrupt Register */ + uint32_t RESERVED4[15U]; + __IM uint32_t MVFR0; /*!< Offset: 0x240 (R/ ) Media and VFP Feature Register 0 */ + __IM uint32_t MVFR1; /*!< Offset: 0x244 (R/ ) Media and VFP Feature Register 1 */ + __IM uint32_t MVFR2; /*!< Offset: 0x248 (R/ ) Media and VFP Feature Register 2 */ + uint32_t RESERVED5[1U]; + __OM uint32_t ICIALLU; /*!< Offset: 0x250 ( /W) I-Cache Invalidate All to PoU */ + uint32_t RESERVED6[1U]; + __OM uint32_t ICIMVAU; /*!< Offset: 0x258 ( /W) I-Cache Invalidate by MVA to PoU */ + __OM uint32_t DCIMVAC; /*!< Offset: 0x25C ( /W) D-Cache Invalidate by MVA to PoC */ + __OM uint32_t DCISW; /*!< Offset: 0x260 ( /W) D-Cache Invalidate by Set-way */ + __OM uint32_t DCCMVAU; /*!< Offset: 0x264 ( /W) D-Cache Clean by MVA to PoU */ + __OM uint32_t DCCMVAC; /*!< Offset: 0x268 ( /W) D-Cache Clean by MVA to PoC */ + __OM uint32_t DCCSW; /*!< Offset: 0x26C ( /W) D-Cache Clean by Set-way */ + __OM uint32_t DCCIMVAC; /*!< Offset: 0x270 ( /W) D-Cache Clean and Invalidate by MVA to PoC */ + __OM uint32_t DCCISW; /*!< Offset: 0x274 ( /W) D-Cache Clean and Invalidate by Set-way */ + uint32_t RESERVED7[6U]; + __IOM uint32_t ITCMCR; /*!< Offset: 0x290 (R/W) Instruction Tightly-Coupled Memory Control Register */ + __IOM uint32_t DTCMCR; /*!< Offset: 0x294 (R/W) Data Tightly-Coupled Memory Control Registers */ + __IOM uint32_t AHBPCR; /*!< Offset: 0x298 (R/W) AHBP Control Register */ + __IOM uint32_t CACR; /*!< Offset: 0x29C (R/W) L1 Cache Control Register */ + __IOM uint32_t AHBSCR; /*!< Offset: 0x2A0 (R/W) AHB Slave Control Register */ + uint32_t RESERVED8[1U]; + __IOM uint32_t ABFSR; /*!< Offset: 0x2A8 (R/W) Auxiliary Bus Fault Status Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_PENDNMISET_Pos 31U /*!< SCB ICSR: PENDNMISET Position */ +#define SCB_ICSR_PENDNMISET_Msk (1UL << SCB_ICSR_PENDNMISET_Pos) /*!< SCB ICSR: PENDNMISET Mask */ + +#define SCB_ICSR_NMIPENDSET_Pos SCB_ICSR_PENDNMISET_Pos /*!< SCB ICSR: NMIPENDSET Position, backward compatibility */ +#define SCB_ICSR_NMIPENDSET_Msk SCB_ICSR_PENDNMISET_Msk /*!< SCB ICSR: NMIPENDSET Mask, backward compatibility */ + +#define SCB_ICSR_PENDNMICLR_Pos 30U /*!< SCB ICSR: PENDNMICLR Position */ +#define SCB_ICSR_PENDNMICLR_Msk (1UL << SCB_ICSR_PENDNMICLR_Pos) /*!< SCB ICSR: PENDNMICLR Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_STTNS_Pos 24U /*!< SCB ICSR: STTNS Position (Security Extension) */ +#define SCB_ICSR_STTNS_Msk (1UL << SCB_ICSR_STTNS_Pos) /*!< SCB ICSR: STTNS Mask (Security Extension) */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_RETTOBASE_Pos 11U /*!< SCB ICSR: RETTOBASE Position */ +#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Vector Table Offset Register Definitions */ +#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_PRIS_Pos 14U /*!< SCB AIRCR: PRIS Position */ +#define SCB_AIRCR_PRIS_Msk (1UL << SCB_AIRCR_PRIS_Pos) /*!< SCB AIRCR: PRIS Mask */ + +#define SCB_AIRCR_BFHFNMINS_Pos 13U /*!< SCB AIRCR: BFHFNMINS Position */ +#define SCB_AIRCR_BFHFNMINS_Msk (1UL << SCB_AIRCR_BFHFNMINS_Pos) /*!< SCB AIRCR: BFHFNMINS Mask */ + +#define SCB_AIRCR_PRIGROUP_Pos 8U /*!< SCB AIRCR: PRIGROUP Position */ +#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ + +#define SCB_AIRCR_SYSRESETREQS_Pos 3U /*!< SCB AIRCR: SYSRESETREQS Position */ +#define SCB_AIRCR_SYSRESETREQS_Msk (1UL << SCB_AIRCR_SYSRESETREQS_Pos) /*!< SCB AIRCR: SYSRESETREQS Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEPS_Pos 3U /*!< SCB SCR: SLEEPDEEPS Position */ +#define SCB_SCR_SLEEPDEEPS_Msk (1UL << SCB_SCR_SLEEPDEEPS_Pos) /*!< SCB SCR: SLEEPDEEPS Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_BP_Pos 18U /*!< SCB CCR: BP Position */ +#define SCB_CCR_BP_Msk (1UL << SCB_CCR_BP_Pos) /*!< SCB CCR: BP Mask */ + +#define SCB_CCR_IC_Pos 17U /*!< SCB CCR: IC Position */ +#define SCB_CCR_IC_Msk (1UL << SCB_CCR_IC_Pos) /*!< SCB CCR: IC Mask */ + +#define SCB_CCR_DC_Pos 16U /*!< SCB CCR: DC Position */ +#define SCB_CCR_DC_Msk (1UL << SCB_CCR_DC_Pos) /*!< SCB CCR: DC Mask */ + +#define SCB_CCR_STKOFHFNMIGN_Pos 10U /*!< SCB CCR: STKOFHFNMIGN Position */ +#define SCB_CCR_STKOFHFNMIGN_Msk (1UL << SCB_CCR_STKOFHFNMIGN_Pos) /*!< SCB CCR: STKOFHFNMIGN Mask */ + +#define SCB_CCR_BFHFNMIGN_Pos 8U /*!< SCB CCR: BFHFNMIGN Position */ +#define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ + +#define SCB_CCR_DIV_0_TRP_Pos 4U /*!< SCB CCR: DIV_0_TRP Position */ +#define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +#define SCB_CCR_USERSETMPEND_Pos 1U /*!< SCB CCR: USERSETMPEND Position */ +#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_HARDFAULTPENDED_Pos 21U /*!< SCB SHCSR: HARDFAULTPENDED Position */ +#define SCB_SHCSR_HARDFAULTPENDED_Msk (1UL << SCB_SHCSR_HARDFAULTPENDED_Pos) /*!< SCB SHCSR: HARDFAULTPENDED Mask */ + +#define SCB_SHCSR_SECUREFAULTPENDED_Pos 20U /*!< SCB SHCSR: SECUREFAULTPENDED Position */ +#define SCB_SHCSR_SECUREFAULTPENDED_Msk (1UL << SCB_SHCSR_SECUREFAULTPENDED_Pos) /*!< SCB SHCSR: SECUREFAULTPENDED Mask */ + +#define SCB_SHCSR_SECUREFAULTENA_Pos 19U /*!< SCB SHCSR: SECUREFAULTENA Position */ +#define SCB_SHCSR_SECUREFAULTENA_Msk (1UL << SCB_SHCSR_SECUREFAULTENA_Pos) /*!< SCB SHCSR: SECUREFAULTENA Mask */ + +#define SCB_SHCSR_USGFAULTENA_Pos 18U /*!< SCB SHCSR: USGFAULTENA Position */ +#define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */ + +#define SCB_SHCSR_BUSFAULTENA_Pos 17U /*!< SCB SHCSR: BUSFAULTENA Position */ +#define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */ + +#define SCB_SHCSR_MEMFAULTENA_Pos 16U /*!< SCB SHCSR: MEMFAULTENA Position */ +#define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */ + +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +#define SCB_SHCSR_BUSFAULTPENDED_Pos 14U /*!< SCB SHCSR: BUSFAULTPENDED Position */ +#define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */ + +#define SCB_SHCSR_MEMFAULTPENDED_Pos 13U /*!< SCB SHCSR: MEMFAULTPENDED Position */ +#define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */ + +#define SCB_SHCSR_USGFAULTPENDED_Pos 12U /*!< SCB SHCSR: USGFAULTPENDED Position */ +#define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */ + +#define SCB_SHCSR_SYSTICKACT_Pos 11U /*!< SCB SHCSR: SYSTICKACT Position */ +#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ + +#define SCB_SHCSR_PENDSVACT_Pos 10U /*!< SCB SHCSR: PENDSVACT Position */ +#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ + +#define SCB_SHCSR_MONITORACT_Pos 8U /*!< SCB SHCSR: MONITORACT Position */ +#define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */ + +#define SCB_SHCSR_SVCALLACT_Pos 7U /*!< SCB SHCSR: SVCALLACT Position */ +#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ + +#define SCB_SHCSR_NMIACT_Pos 5U /*!< SCB SHCSR: NMIACT Position */ +#define SCB_SHCSR_NMIACT_Msk (1UL << SCB_SHCSR_NMIACT_Pos) /*!< SCB SHCSR: NMIACT Mask */ + +#define SCB_SHCSR_SECUREFAULTACT_Pos 4U /*!< SCB SHCSR: SECUREFAULTACT Position */ +#define SCB_SHCSR_SECUREFAULTACT_Msk (1UL << SCB_SHCSR_SECUREFAULTACT_Pos) /*!< SCB SHCSR: SECUREFAULTACT Mask */ + +#define SCB_SHCSR_USGFAULTACT_Pos 3U /*!< SCB SHCSR: USGFAULTACT Position */ +#define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */ + +#define SCB_SHCSR_HARDFAULTACT_Pos 2U /*!< SCB SHCSR: HARDFAULTACT Position */ +#define SCB_SHCSR_HARDFAULTACT_Msk (1UL << SCB_SHCSR_HARDFAULTACT_Pos) /*!< SCB SHCSR: HARDFAULTACT Mask */ + +#define SCB_SHCSR_BUSFAULTACT_Pos 1U /*!< SCB SHCSR: BUSFAULTACT Position */ +#define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */ + +#define SCB_SHCSR_MEMFAULTACT_Pos 0U /*!< SCB SHCSR: MEMFAULTACT Position */ +#define SCB_SHCSR_MEMFAULTACT_Msk (1UL /*<< SCB_SHCSR_MEMFAULTACT_Pos*/) /*!< SCB SHCSR: MEMFAULTACT Mask */ + +/* SCB Configurable Fault Status Register Definitions */ +#define SCB_CFSR_USGFAULTSR_Pos 16U /*!< SCB CFSR: Usage Fault Status Register Position */ +#define SCB_CFSR_USGFAULTSR_Msk (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */ + +#define SCB_CFSR_BUSFAULTSR_Pos 8U /*!< SCB CFSR: Bus Fault Status Register Position */ +#define SCB_CFSR_BUSFAULTSR_Msk (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */ + +#define SCB_CFSR_MEMFAULTSR_Pos 0U /*!< SCB CFSR: Memory Manage Fault Status Register Position */ +#define SCB_CFSR_MEMFAULTSR_Msk (0xFFUL /*<< SCB_CFSR_MEMFAULTSR_Pos*/) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */ + +/* MemManage Fault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_MMARVALID_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 7U) /*!< SCB CFSR (MMFSR): MMARVALID Position */ +#define SCB_CFSR_MMARVALID_Msk (1UL << SCB_CFSR_MMARVALID_Pos) /*!< SCB CFSR (MMFSR): MMARVALID Mask */ + +#define SCB_CFSR_MLSPERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 5U) /*!< SCB CFSR (MMFSR): MLSPERR Position */ +#define SCB_CFSR_MLSPERR_Msk (1UL << SCB_CFSR_MLSPERR_Pos) /*!< SCB CFSR (MMFSR): MLSPERR Mask */ + +#define SCB_CFSR_MSTKERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 4U) /*!< SCB CFSR (MMFSR): MSTKERR Position */ +#define SCB_CFSR_MSTKERR_Msk (1UL << SCB_CFSR_MSTKERR_Pos) /*!< SCB CFSR (MMFSR): MSTKERR Mask */ + +#define SCB_CFSR_MUNSTKERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 3U) /*!< SCB CFSR (MMFSR): MUNSTKERR Position */ +#define SCB_CFSR_MUNSTKERR_Msk (1UL << SCB_CFSR_MUNSTKERR_Pos) /*!< SCB CFSR (MMFSR): MUNSTKERR Mask */ + +#define SCB_CFSR_DACCVIOL_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 1U) /*!< SCB CFSR (MMFSR): DACCVIOL Position */ +#define SCB_CFSR_DACCVIOL_Msk (1UL << SCB_CFSR_DACCVIOL_Pos) /*!< SCB CFSR (MMFSR): DACCVIOL Mask */ + +#define SCB_CFSR_IACCVIOL_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 0U) /*!< SCB CFSR (MMFSR): IACCVIOL Position */ +#define SCB_CFSR_IACCVIOL_Msk (1UL /*<< SCB_CFSR_IACCVIOL_Pos*/) /*!< SCB CFSR (MMFSR): IACCVIOL Mask */ + +/* BusFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_BFARVALID_Pos (SCB_CFSR_BUSFAULTSR_Pos + 7U) /*!< SCB CFSR (BFSR): BFARVALID Position */ +#define SCB_CFSR_BFARVALID_Msk (1UL << SCB_CFSR_BFARVALID_Pos) /*!< SCB CFSR (BFSR): BFARVALID Mask */ + +#define SCB_CFSR_LSPERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 5U) /*!< SCB CFSR (BFSR): LSPERR Position */ +#define SCB_CFSR_LSPERR_Msk (1UL << SCB_CFSR_LSPERR_Pos) /*!< SCB CFSR (BFSR): LSPERR Mask */ + +#define SCB_CFSR_STKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 4U) /*!< SCB CFSR (BFSR): STKERR Position */ +#define SCB_CFSR_STKERR_Msk (1UL << SCB_CFSR_STKERR_Pos) /*!< SCB CFSR (BFSR): STKERR Mask */ + +#define SCB_CFSR_UNSTKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 3U) /*!< SCB CFSR (BFSR): UNSTKERR Position */ +#define SCB_CFSR_UNSTKERR_Msk (1UL << SCB_CFSR_UNSTKERR_Pos) /*!< SCB CFSR (BFSR): UNSTKERR Mask */ + +#define SCB_CFSR_IMPRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 2U) /*!< SCB CFSR (BFSR): IMPRECISERR Position */ +#define SCB_CFSR_IMPRECISERR_Msk (1UL << SCB_CFSR_IMPRECISERR_Pos) /*!< SCB CFSR (BFSR): IMPRECISERR Mask */ + +#define SCB_CFSR_PRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 1U) /*!< SCB CFSR (BFSR): PRECISERR Position */ +#define SCB_CFSR_PRECISERR_Msk (1UL << SCB_CFSR_PRECISERR_Pos) /*!< SCB CFSR (BFSR): PRECISERR Mask */ + +#define SCB_CFSR_IBUSERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 0U) /*!< SCB CFSR (BFSR): IBUSERR Position */ +#define SCB_CFSR_IBUSERR_Msk (1UL << SCB_CFSR_IBUSERR_Pos) /*!< SCB CFSR (BFSR): IBUSERR Mask */ + +/* UsageFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_DIVBYZERO_Pos (SCB_CFSR_USGFAULTSR_Pos + 9U) /*!< SCB CFSR (UFSR): DIVBYZERO Position */ +#define SCB_CFSR_DIVBYZERO_Msk (1UL << SCB_CFSR_DIVBYZERO_Pos) /*!< SCB CFSR (UFSR): DIVBYZERO Mask */ + +#define SCB_CFSR_UNALIGNED_Pos (SCB_CFSR_USGFAULTSR_Pos + 8U) /*!< SCB CFSR (UFSR): UNALIGNED Position */ +#define SCB_CFSR_UNALIGNED_Msk (1UL << SCB_CFSR_UNALIGNED_Pos) /*!< SCB CFSR (UFSR): UNALIGNED Mask */ + +#define SCB_CFSR_STKOF_Pos (SCB_CFSR_USGFAULTSR_Pos + 4U) /*!< SCB CFSR (UFSR): STKOF Position */ +#define SCB_CFSR_STKOF_Msk (1UL << SCB_CFSR_STKOF_Pos) /*!< SCB CFSR (UFSR): STKOF Mask */ + +#define SCB_CFSR_NOCP_Pos (SCB_CFSR_USGFAULTSR_Pos + 3U) /*!< SCB CFSR (UFSR): NOCP Position */ +#define SCB_CFSR_NOCP_Msk (1UL << SCB_CFSR_NOCP_Pos) /*!< SCB CFSR (UFSR): NOCP Mask */ + +#define SCB_CFSR_INVPC_Pos (SCB_CFSR_USGFAULTSR_Pos + 2U) /*!< SCB CFSR (UFSR): INVPC Position */ +#define SCB_CFSR_INVPC_Msk (1UL << SCB_CFSR_INVPC_Pos) /*!< SCB CFSR (UFSR): INVPC Mask */ + +#define SCB_CFSR_INVSTATE_Pos (SCB_CFSR_USGFAULTSR_Pos + 1U) /*!< SCB CFSR (UFSR): INVSTATE Position */ +#define SCB_CFSR_INVSTATE_Msk (1UL << SCB_CFSR_INVSTATE_Pos) /*!< SCB CFSR (UFSR): INVSTATE Mask */ + +#define SCB_CFSR_UNDEFINSTR_Pos (SCB_CFSR_USGFAULTSR_Pos + 0U) /*!< SCB CFSR (UFSR): UNDEFINSTR Position */ +#define SCB_CFSR_UNDEFINSTR_Msk (1UL << SCB_CFSR_UNDEFINSTR_Pos) /*!< SCB CFSR (UFSR): UNDEFINSTR Mask */ + +/* SCB Hard Fault Status Register Definitions */ +#define SCB_HFSR_DEBUGEVT_Pos 31U /*!< SCB HFSR: DEBUGEVT Position */ +#define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ + +#define SCB_HFSR_FORCED_Pos 30U /*!< SCB HFSR: FORCED Position */ +#define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */ + +#define SCB_HFSR_VECTTBL_Pos 1U /*!< SCB HFSR: VECTTBL Position */ +#define SCB_HFSR_VECTTBL_Msk (1UL << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */ + +/* SCB Debug Fault Status Register Definitions */ +#define SCB_DFSR_EXTERNAL_Pos 4U /*!< SCB DFSR: EXTERNAL Position */ +#define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */ + +#define SCB_DFSR_VCATCH_Pos 3U /*!< SCB DFSR: VCATCH Position */ +#define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */ + +#define SCB_DFSR_DWTTRAP_Pos 2U /*!< SCB DFSR: DWTTRAP Position */ +#define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */ + +#define SCB_DFSR_BKPT_Pos 1U /*!< SCB DFSR: BKPT Position */ +#define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */ + +#define SCB_DFSR_HALTED_Pos 0U /*!< SCB DFSR: HALTED Position */ +#define SCB_DFSR_HALTED_Msk (1UL /*<< SCB_DFSR_HALTED_Pos*/) /*!< SCB DFSR: HALTED Mask */ + +/* SCB Non-Secure Access Control Register Definitions */ +#define SCB_NSACR_CP11_Pos 11U /*!< SCB NSACR: CP11 Position */ +#define SCB_NSACR_CP11_Msk (1UL << SCB_NSACR_CP11_Pos) /*!< SCB NSACR: CP11 Mask */ + +#define SCB_NSACR_CP10_Pos 10U /*!< SCB NSACR: CP10 Position */ +#define SCB_NSACR_CP10_Msk (1UL << SCB_NSACR_CP10_Pos) /*!< SCB NSACR: CP10 Mask */ + +#define SCB_NSACR_CPn_Pos 0U /*!< SCB NSACR: CPn Position */ +#define SCB_NSACR_CPn_Msk (1UL /*<< SCB_NSACR_CPn_Pos*/) /*!< SCB NSACR: CPn Mask */ + +/* SCB Cache Level ID Register Definitions */ +#define SCB_CLIDR_LOUU_Pos 27U /*!< SCB CLIDR: LoUU Position */ +#define SCB_CLIDR_LOUU_Msk (7UL << SCB_CLIDR_LOUU_Pos) /*!< SCB CLIDR: LoUU Mask */ + +#define SCB_CLIDR_LOC_Pos 24U /*!< SCB CLIDR: LoC Position */ +#define SCB_CLIDR_LOC_Msk (7UL << SCB_CLIDR_LOC_Pos) /*!< SCB CLIDR: LoC Mask */ + +/* SCB Cache Type Register Definitions */ +#define SCB_CTR_FORMAT_Pos 29U /*!< SCB CTR: Format Position */ +#define SCB_CTR_FORMAT_Msk (7UL << SCB_CTR_FORMAT_Pos) /*!< SCB CTR: Format Mask */ + +#define SCB_CTR_CWG_Pos 24U /*!< SCB CTR: CWG Position */ +#define SCB_CTR_CWG_Msk (0xFUL << SCB_CTR_CWG_Pos) /*!< SCB CTR: CWG Mask */ + +#define SCB_CTR_ERG_Pos 20U /*!< SCB CTR: ERG Position */ +#define SCB_CTR_ERG_Msk (0xFUL << SCB_CTR_ERG_Pos) /*!< SCB CTR: ERG Mask */ + +#define SCB_CTR_DMINLINE_Pos 16U /*!< SCB CTR: DminLine Position */ +#define SCB_CTR_DMINLINE_Msk (0xFUL << SCB_CTR_DMINLINE_Pos) /*!< SCB CTR: DminLine Mask */ + +#define SCB_CTR_IMINLINE_Pos 0U /*!< SCB CTR: ImInLine Position */ +#define SCB_CTR_IMINLINE_Msk (0xFUL /*<< SCB_CTR_IMINLINE_Pos*/) /*!< SCB CTR: ImInLine Mask */ + +/* SCB Cache Size ID Register Definitions */ +#define SCB_CCSIDR_WT_Pos 31U /*!< SCB CCSIDR: WT Position */ +#define SCB_CCSIDR_WT_Msk (1UL << SCB_CCSIDR_WT_Pos) /*!< SCB CCSIDR: WT Mask */ + +#define SCB_CCSIDR_WB_Pos 30U /*!< SCB CCSIDR: WB Position */ +#define SCB_CCSIDR_WB_Msk (1UL << SCB_CCSIDR_WB_Pos) /*!< SCB CCSIDR: WB Mask */ + +#define SCB_CCSIDR_RA_Pos 29U /*!< SCB CCSIDR: RA Position */ +#define SCB_CCSIDR_RA_Msk (1UL << SCB_CCSIDR_RA_Pos) /*!< SCB CCSIDR: RA Mask */ + +#define SCB_CCSIDR_WA_Pos 28U /*!< SCB CCSIDR: WA Position */ +#define SCB_CCSIDR_WA_Msk (1UL << SCB_CCSIDR_WA_Pos) /*!< SCB CCSIDR: WA Mask */ + +#define SCB_CCSIDR_NUMSETS_Pos 13U /*!< SCB CCSIDR: NumSets Position */ +#define SCB_CCSIDR_NUMSETS_Msk (0x7FFFUL << SCB_CCSIDR_NUMSETS_Pos) /*!< SCB CCSIDR: NumSets Mask */ + +#define SCB_CCSIDR_ASSOCIATIVITY_Pos 3U /*!< SCB CCSIDR: Associativity Position */ +#define SCB_CCSIDR_ASSOCIATIVITY_Msk (0x3FFUL << SCB_CCSIDR_ASSOCIATIVITY_Pos) /*!< SCB CCSIDR: Associativity Mask */ + +#define SCB_CCSIDR_LINESIZE_Pos 0U /*!< SCB CCSIDR: LineSize Position */ +#define SCB_CCSIDR_LINESIZE_Msk (7UL /*<< SCB_CCSIDR_LINESIZE_Pos*/) /*!< SCB CCSIDR: LineSize Mask */ + +/* SCB Cache Size Selection Register Definitions */ +#define SCB_CSSELR_LEVEL_Pos 1U /*!< SCB CSSELR: Level Position */ +#define SCB_CSSELR_LEVEL_Msk (7UL << SCB_CSSELR_LEVEL_Pos) /*!< SCB CSSELR: Level Mask */ + +#define SCB_CSSELR_IND_Pos 0U /*!< SCB CSSELR: InD Position */ +#define SCB_CSSELR_IND_Msk (1UL /*<< SCB_CSSELR_IND_Pos*/) /*!< SCB CSSELR: InD Mask */ + +/* SCB Software Triggered Interrupt Register Definitions */ +#define SCB_STIR_INTID_Pos 0U /*!< SCB STIR: INTID Position */ +#define SCB_STIR_INTID_Msk (0x1FFUL /*<< SCB_STIR_INTID_Pos*/) /*!< SCB STIR: INTID Mask */ + +/* SCB D-Cache Invalidate by Set-way Register Definitions */ +#define SCB_DCISW_WAY_Pos 30U /*!< SCB DCISW: Way Position */ +#define SCB_DCISW_WAY_Msk (3UL << SCB_DCISW_WAY_Pos) /*!< SCB DCISW: Way Mask */ + +#define SCB_DCISW_SET_Pos 5U /*!< SCB DCISW: Set Position */ +#define SCB_DCISW_SET_Msk (0x1FFUL << SCB_DCISW_SET_Pos) /*!< SCB DCISW: Set Mask */ + +/* SCB D-Cache Clean by Set-way Register Definitions */ +#define SCB_DCCSW_WAY_Pos 30U /*!< SCB DCCSW: Way Position */ +#define SCB_DCCSW_WAY_Msk (3UL << SCB_DCCSW_WAY_Pos) /*!< SCB DCCSW: Way Mask */ + +#define SCB_DCCSW_SET_Pos 5U /*!< SCB DCCSW: Set Position */ +#define SCB_DCCSW_SET_Msk (0x1FFUL << SCB_DCCSW_SET_Pos) /*!< SCB DCCSW: Set Mask */ + +/* SCB D-Cache Clean and Invalidate by Set-way Register Definitions */ +#define SCB_DCCISW_WAY_Pos 30U /*!< SCB DCCISW: Way Position */ +#define SCB_DCCISW_WAY_Msk (3UL << SCB_DCCISW_WAY_Pos) /*!< SCB DCCISW: Way Mask */ + +#define SCB_DCCISW_SET_Pos 5U /*!< SCB DCCISW: Set Position */ +#define SCB_DCCISW_SET_Msk (0x1FFUL << SCB_DCCISW_SET_Pos) /*!< SCB DCCISW: Set Mask */ + +/* Instruction Tightly-Coupled Memory Control Register Definitions */ +#define SCB_ITCMCR_SZ_Pos 3U /*!< SCB ITCMCR: SZ Position */ +#define SCB_ITCMCR_SZ_Msk (0xFUL << SCB_ITCMCR_SZ_Pos) /*!< SCB ITCMCR: SZ Mask */ + +#define SCB_ITCMCR_RETEN_Pos 2U /*!< SCB ITCMCR: RETEN Position */ +#define SCB_ITCMCR_RETEN_Msk (1UL << SCB_ITCMCR_RETEN_Pos) /*!< SCB ITCMCR: RETEN Mask */ + +#define SCB_ITCMCR_RMW_Pos 1U /*!< SCB ITCMCR: RMW Position */ +#define SCB_ITCMCR_RMW_Msk (1UL << SCB_ITCMCR_RMW_Pos) /*!< SCB ITCMCR: RMW Mask */ + +#define SCB_ITCMCR_EN_Pos 0U /*!< SCB ITCMCR: EN Position */ +#define SCB_ITCMCR_EN_Msk (1UL /*<< SCB_ITCMCR_EN_Pos*/) /*!< SCB ITCMCR: EN Mask */ + +/* Data Tightly-Coupled Memory Control Register Definitions */ +#define SCB_DTCMCR_SZ_Pos 3U /*!< SCB DTCMCR: SZ Position */ +#define SCB_DTCMCR_SZ_Msk (0xFUL << SCB_DTCMCR_SZ_Pos) /*!< SCB DTCMCR: SZ Mask */ + +#define SCB_DTCMCR_RETEN_Pos 2U /*!< SCB DTCMCR: RETEN Position */ +#define SCB_DTCMCR_RETEN_Msk (1UL << SCB_DTCMCR_RETEN_Pos) /*!< SCB DTCMCR: RETEN Mask */ + +#define SCB_DTCMCR_RMW_Pos 1U /*!< SCB DTCMCR: RMW Position */ +#define SCB_DTCMCR_RMW_Msk (1UL << SCB_DTCMCR_RMW_Pos) /*!< SCB DTCMCR: RMW Mask */ + +#define SCB_DTCMCR_EN_Pos 0U /*!< SCB DTCMCR: EN Position */ +#define SCB_DTCMCR_EN_Msk (1UL /*<< SCB_DTCMCR_EN_Pos*/) /*!< SCB DTCMCR: EN Mask */ + +/* AHBP Control Register Definitions */ +#define SCB_AHBPCR_SZ_Pos 1U /*!< SCB AHBPCR: SZ Position */ +#define SCB_AHBPCR_SZ_Msk (7UL << SCB_AHBPCR_SZ_Pos) /*!< SCB AHBPCR: SZ Mask */ + +#define SCB_AHBPCR_EN_Pos 0U /*!< SCB AHBPCR: EN Position */ +#define SCB_AHBPCR_EN_Msk (1UL /*<< SCB_AHBPCR_EN_Pos*/) /*!< SCB AHBPCR: EN Mask */ + +/* L1 Cache Control Register Definitions */ +#define SCB_CACR_FORCEWT_Pos 2U /*!< SCB CACR: FORCEWT Position */ +#define SCB_CACR_FORCEWT_Msk (1UL << SCB_CACR_FORCEWT_Pos) /*!< SCB CACR: FORCEWT Mask */ + +#define SCB_CACR_ECCEN_Pos 1U /*!< SCB CACR: ECCEN Position */ +#define SCB_CACR_ECCEN_Msk (1UL << SCB_CACR_ECCEN_Pos) /*!< SCB CACR: ECCEN Mask */ + +#define SCB_CACR_SIWT_Pos 0U /*!< SCB CACR: SIWT Position */ +#define SCB_CACR_SIWT_Msk (1UL /*<< SCB_CACR_SIWT_Pos*/) /*!< SCB CACR: SIWT Mask */ + +/* AHBS Control Register Definitions */ +#define SCB_AHBSCR_INITCOUNT_Pos 11U /*!< SCB AHBSCR: INITCOUNT Position */ +#define SCB_AHBSCR_INITCOUNT_Msk (0x1FUL << SCB_AHBPCR_INITCOUNT_Pos) /*!< SCB AHBSCR: INITCOUNT Mask */ + +#define SCB_AHBSCR_TPRI_Pos 2U /*!< SCB AHBSCR: TPRI Position */ +#define SCB_AHBSCR_TPRI_Msk (0x1FFUL << SCB_AHBPCR_TPRI_Pos) /*!< SCB AHBSCR: TPRI Mask */ + +#define SCB_AHBSCR_CTL_Pos 0U /*!< SCB AHBSCR: CTL Position*/ +#define SCB_AHBSCR_CTL_Msk (3UL /*<< SCB_AHBPCR_CTL_Pos*/) /*!< SCB AHBSCR: CTL Mask */ + +/* Auxiliary Bus Fault Status Register Definitions */ +#define SCB_ABFSR_AXIMTYPE_Pos 8U /*!< SCB ABFSR: AXIMTYPE Position*/ +#define SCB_ABFSR_AXIMTYPE_Msk (3UL << SCB_ABFSR_AXIMTYPE_Pos) /*!< SCB ABFSR: AXIMTYPE Mask */ + +#define SCB_ABFSR_EPPB_Pos 4U /*!< SCB ABFSR: EPPB Position*/ +#define SCB_ABFSR_EPPB_Msk (1UL << SCB_ABFSR_EPPB_Pos) /*!< SCB ABFSR: EPPB Mask */ + +#define SCB_ABFSR_AXIM_Pos 3U /*!< SCB ABFSR: AXIM Position*/ +#define SCB_ABFSR_AXIM_Msk (1UL << SCB_ABFSR_AXIM_Pos) /*!< SCB ABFSR: AXIM Mask */ + +#define SCB_ABFSR_AHBP_Pos 2U /*!< SCB ABFSR: AHBP Position*/ +#define SCB_ABFSR_AHBP_Msk (1UL << SCB_ABFSR_AHBP_Pos) /*!< SCB ABFSR: AHBP Mask */ + +#define SCB_ABFSR_DTCM_Pos 1U /*!< SCB ABFSR: DTCM Position*/ +#define SCB_ABFSR_DTCM_Msk (1UL << SCB_ABFSR_DTCM_Pos) /*!< SCB ABFSR: DTCM Mask */ + +#define SCB_ABFSR_ITCM_Pos 0U /*!< SCB ABFSR: ITCM Position*/ +#define SCB_ABFSR_ITCM_Msk (1UL /*<< SCB_ABFSR_ITCM_Pos*/) /*!< SCB ABFSR: ITCM Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) + \brief Type definitions for the System Control and ID Register not in the SCB + @{ + */ + +/** + \brief Structure type to access the System Control and ID Register not in the SCB. + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IM uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ + __IOM uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ + __IOM uint32_t CPPWR; /*!< Offset: 0x00C (R/W) Coprocessor Power Control Register */ +} SCnSCB_Type; + +/* Interrupt Controller Type Register Definitions */ +#define SCnSCB_ICTR_INTLINESNUM_Pos 0U /*!< ICTR: INTLINESNUM Position */ +#define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL /*<< SCnSCB_ICTR_INTLINESNUM_Pos*/) /*!< ICTR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_SCnotSCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_ITM Instrumentation Trace Macrocell (ITM) + \brief Type definitions for the Instrumentation Trace Macrocell (ITM) + @{ + */ + +/** + \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM). + */ +typedef struct +{ + __OM union + { + __OM uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ + __OM uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ + __OM uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ + } PORT [32U]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ + uint32_t RESERVED0[864U]; + __IOM uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ + uint32_t RESERVED1[15U]; + __IOM uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ + uint32_t RESERVED2[15U]; + __IOM uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ + uint32_t RESERVED3[29U]; + __OM uint32_t IWR; /*!< Offset: 0xEF8 ( /W) ITM Integration Write Register */ + __IM uint32_t IRR; /*!< Offset: 0xEFC (R/ ) ITM Integration Read Register */ + __IOM uint32_t IMCR; /*!< Offset: 0xF00 (R/W) ITM Integration Mode Control Register */ + uint32_t RESERVED4[43U]; + __OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */ + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */ + uint32_t RESERVED5[1U]; + __IM uint32_t DEVARCH; /*!< Offset: 0xFBC (R/ ) ITM Device Architecture Register */ + uint32_t RESERVED6[4U]; + __IM uint32_t PID4; /*!< Offset: 0xFD0 (R/ ) ITM Peripheral Identification Register #4 */ + __IM uint32_t PID5; /*!< Offset: 0xFD4 (R/ ) ITM Peripheral Identification Register #5 */ + __IM uint32_t PID6; /*!< Offset: 0xFD8 (R/ ) ITM Peripheral Identification Register #6 */ + __IM uint32_t PID7; /*!< Offset: 0xFDC (R/ ) ITM Peripheral Identification Register #7 */ + __IM uint32_t PID0; /*!< Offset: 0xFE0 (R/ ) ITM Peripheral Identification Register #0 */ + __IM uint32_t PID1; /*!< Offset: 0xFE4 (R/ ) ITM Peripheral Identification Register #1 */ + __IM uint32_t PID2; /*!< Offset: 0xFE8 (R/ ) ITM Peripheral Identification Register #2 */ + __IM uint32_t PID3; /*!< Offset: 0xFEC (R/ ) ITM Peripheral Identification Register #3 */ + __IM uint32_t CID0; /*!< Offset: 0xFF0 (R/ ) ITM Component Identification Register #0 */ + __IM uint32_t CID1; /*!< Offset: 0xFF4 (R/ ) ITM Component Identification Register #1 */ + __IM uint32_t CID2; /*!< Offset: 0xFF8 (R/ ) ITM Component Identification Register #2 */ + __IM uint32_t CID3; /*!< Offset: 0xFFC (R/ ) ITM Component Identification Register #3 */ +} ITM_Type; + +/* ITM Stimulus Port Register Definitions */ +#define ITM_STIM_DISABLED_Pos 1U /*!< ITM STIM: DISABLED Position */ +#define ITM_STIM_DISABLED_Msk (0x1UL << ITM_STIM_DISABLED_Pos) /*!< ITM STIM: DISABLED Mask */ + +#define ITM_STIM_FIFOREADY_Pos 0U /*!< ITM STIM: FIFOREADY Position */ +#define ITM_STIM_FIFOREADY_Msk (0x1UL /*<< ITM_STIM_FIFOREADY_Pos*/) /*!< ITM STIM: FIFOREADY Mask */ + +/* ITM Trace Privilege Register Definitions */ +#define ITM_TPR_PRIVMASK_Pos 0U /*!< ITM TPR: PRIVMASK Position */ +#define ITM_TPR_PRIVMASK_Msk (0xFUL /*<< ITM_TPR_PRIVMASK_Pos*/) /*!< ITM TPR: PRIVMASK Mask */ + +/* ITM Trace Control Register Definitions */ +#define ITM_TCR_BUSY_Pos 23U /*!< ITM TCR: BUSY Position */ +#define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */ + +#define ITM_TCR_TRACEBUSID_Pos 16U /*!< ITM TCR: ATBID Position */ +#define ITM_TCR_TRACEBUSID_Msk (0x7FUL << ITM_TCR_TRACEBUSID_Pos) /*!< ITM TCR: ATBID Mask */ + +#define ITM_TCR_GTSFREQ_Pos 10U /*!< ITM TCR: Global timestamp frequency Position */ +#define ITM_TCR_GTSFREQ_Msk (3UL << ITM_TCR_GTSFREQ_Pos) /*!< ITM TCR: Global timestamp frequency Mask */ + +#define ITM_TCR_TSPRESCALE_Pos 8U /*!< ITM TCR: TSPRESCALE Position */ +#define ITM_TCR_TSPRESCALE_Msk (3UL << ITM_TCR_TSPRESCALE_Pos) /*!< ITM TCR: TSPRESCALE Mask */ + +#define ITM_TCR_STALLENA_Pos 5U /*!< ITM TCR: STALLENA Position */ +#define ITM_TCR_STALLENA_Msk (1UL << ITM_TCR_STALLENA_Pos) /*!< ITM TCR: STALLENA Mask */ + +#define ITM_TCR_SWOENA_Pos 4U /*!< ITM TCR: SWOENA Position */ +#define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */ + +#define ITM_TCR_DWTENA_Pos 3U /*!< ITM TCR: DWTENA Position */ +#define ITM_TCR_DWTENA_Msk (1UL << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */ + +#define ITM_TCR_SYNCENA_Pos 2U /*!< ITM TCR: SYNCENA Position */ +#define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */ + +#define ITM_TCR_TSENA_Pos 1U /*!< ITM TCR: TSENA Position */ +#define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */ + +#define ITM_TCR_ITMENA_Pos 0U /*!< ITM TCR: ITM Enable bit Position */ +#define ITM_TCR_ITMENA_Msk (1UL /*<< ITM_TCR_ITMENA_Pos*/) /*!< ITM TCR: ITM Enable bit Mask */ + +/* ITM Integration Write Register Definitions */ +#define ITM_IWR_ATVALIDM_Pos 0U /*!< ITM IWR: ATVALIDM Position */ +#define ITM_IWR_ATVALIDM_Msk (1UL /*<< ITM_IWR_ATVALIDM_Pos*/) /*!< ITM IWR: ATVALIDM Mask */ + +/* ITM Integration Read Register Definitions */ +#define ITM_IRR_ATREADYM_Pos 0U /*!< ITM IRR: ATREADYM Position */ +#define ITM_IRR_ATREADYM_Msk (1UL /*<< ITM_IRR_ATREADYM_Pos*/) /*!< ITM IRR: ATREADYM Mask */ + +/* ITM Integration Mode Control Register Definitions */ +#define ITM_IMCR_INTEGRATION_Pos 0U /*!< ITM IMCR: INTEGRATION Position */ +#define ITM_IMCR_INTEGRATION_Msk (1UL /*<< ITM_IMCR_INTEGRATION_Pos*/) /*!< ITM IMCR: INTEGRATION Mask */ + +/* ITM Lock Status Register Definitions */ +#define ITM_LSR_ByteAcc_Pos 2U /*!< ITM LSR: ByteAcc Position */ +#define ITM_LSR_ByteAcc_Msk (1UL << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */ + +#define ITM_LSR_Access_Pos 1U /*!< ITM LSR: Access Position */ +#define ITM_LSR_Access_Msk (1UL << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */ + +#define ITM_LSR_Present_Pos 0U /*!< ITM LSR: Present Position */ +#define ITM_LSR_Present_Msk (1UL /*<< ITM_LSR_Present_Pos*/) /*!< ITM LSR: Present Mask */ + +/*@}*/ /* end of group CMSIS_ITM */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) + \brief Type definitions for the Data Watchpoint and Trace (DWT) + @{ + */ + +/** + \brief Structure type to access the Data Watchpoint and Trace Register (DWT). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ + __IOM uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */ + __IOM uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */ + __IOM uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */ + __IOM uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */ + __IOM uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */ + __IOM uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */ + __IM uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ + __IOM uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ + uint32_t RESERVED1[1U]; + __IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ + uint32_t RESERVED2[1U]; + __IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ + uint32_t RESERVED3[1U]; + __IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ + uint32_t RESERVED4[1U]; + __IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ + uint32_t RESERVED5[1U]; + __IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ + uint32_t RESERVED6[1U]; + __IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ + uint32_t RESERVED7[1U]; + __IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ + uint32_t RESERVED8[1U]; + __IOM uint32_t COMP4; /*!< Offset: 0x060 (R/W) Comparator Register 4 */ + uint32_t RESERVED9[1U]; + __IOM uint32_t FUNCTION4; /*!< Offset: 0x068 (R/W) Function Register 4 */ + uint32_t RESERVED10[1U]; + __IOM uint32_t COMP5; /*!< Offset: 0x070 (R/W) Comparator Register 5 */ + uint32_t RESERVED11[1U]; + __IOM uint32_t FUNCTION5; /*!< Offset: 0x078 (R/W) Function Register 5 */ + uint32_t RESERVED12[1U]; + __IOM uint32_t COMP6; /*!< Offset: 0x080 (R/W) Comparator Register 6 */ + uint32_t RESERVED13[1U]; + __IOM uint32_t FUNCTION6; /*!< Offset: 0x088 (R/W) Function Register 6 */ + uint32_t RESERVED14[1U]; + __IOM uint32_t COMP7; /*!< Offset: 0x090 (R/W) Comparator Register 7 */ + uint32_t RESERVED15[1U]; + __IOM uint32_t FUNCTION7; /*!< Offset: 0x098 (R/W) Function Register 7 */ + uint32_t RESERVED16[1U]; + __IOM uint32_t COMP8; /*!< Offset: 0x0A0 (R/W) Comparator Register 8 */ + uint32_t RESERVED17[1U]; + __IOM uint32_t FUNCTION8; /*!< Offset: 0x0A8 (R/W) Function Register 8 */ + uint32_t RESERVED18[1U]; + __IOM uint32_t COMP9; /*!< Offset: 0x0B0 (R/W) Comparator Register 9 */ + uint32_t RESERVED19[1U]; + __IOM uint32_t FUNCTION9; /*!< Offset: 0x0B8 (R/W) Function Register 9 */ + uint32_t RESERVED20[1U]; + __IOM uint32_t COMP10; /*!< Offset: 0x0C0 (R/W) Comparator Register 10 */ + uint32_t RESERVED21[1U]; + __IOM uint32_t FUNCTION10; /*!< Offset: 0x0C8 (R/W) Function Register 10 */ + uint32_t RESERVED22[1U]; + __IOM uint32_t COMP11; /*!< Offset: 0x0D0 (R/W) Comparator Register 11 */ + uint32_t RESERVED23[1U]; + __IOM uint32_t FUNCTION11; /*!< Offset: 0x0D8 (R/W) Function Register 11 */ + uint32_t RESERVED24[1U]; + __IOM uint32_t COMP12; /*!< Offset: 0x0E0 (R/W) Comparator Register 12 */ + uint32_t RESERVED25[1U]; + __IOM uint32_t FUNCTION12; /*!< Offset: 0x0E8 (R/W) Function Register 12 */ + uint32_t RESERVED26[1U]; + __IOM uint32_t COMP13; /*!< Offset: 0x0F0 (R/W) Comparator Register 13 */ + uint32_t RESERVED27[1U]; + __IOM uint32_t FUNCTION13; /*!< Offset: 0x0F8 (R/W) Function Register 13 */ + uint32_t RESERVED28[1U]; + __IOM uint32_t COMP14; /*!< Offset: 0x100 (R/W) Comparator Register 14 */ + uint32_t RESERVED29[1U]; + __IOM uint32_t FUNCTION14; /*!< Offset: 0x108 (R/W) Function Register 14 */ + uint32_t RESERVED30[1U]; + __IOM uint32_t COMP15; /*!< Offset: 0x110 (R/W) Comparator Register 15 */ + uint32_t RESERVED31[1U]; + __IOM uint32_t FUNCTION15; /*!< Offset: 0x118 (R/W) Function Register 15 */ + uint32_t RESERVED32[934U]; + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R ) Lock Status Register */ + uint32_t RESERVED33[1U]; + __IM uint32_t DEVARCH; /*!< Offset: 0xFBC (R/ ) Device Architecture Register */ +} DWT_Type; + +/* DWT Control Register Definitions */ +#define DWT_CTRL_NUMCOMP_Pos 28U /*!< DWT CTRL: NUMCOMP Position */ +#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ + +#define DWT_CTRL_NOTRCPKT_Pos 27U /*!< DWT CTRL: NOTRCPKT Position */ +#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ + +#define DWT_CTRL_NOEXTTRIG_Pos 26U /*!< DWT CTRL: NOEXTTRIG Position */ +#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ + +#define DWT_CTRL_NOCYCCNT_Pos 25U /*!< DWT CTRL: NOCYCCNT Position */ +#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ + +#define DWT_CTRL_NOPRFCNT_Pos 24U /*!< DWT CTRL: NOPRFCNT Position */ +#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ + +#define DWT_CTRL_CYCDISS_Pos 23U /*!< DWT CTRL: CYCDISS Position */ +#define DWT_CTRL_CYCDISS_Msk (0x1UL << DWT_CTRL_CYCDISS_Pos) /*!< DWT CTRL: CYCDISS Mask */ + +#define DWT_CTRL_CYCEVTENA_Pos 22U /*!< DWT CTRL: CYCEVTENA Position */ +#define DWT_CTRL_CYCEVTENA_Msk (0x1UL << DWT_CTRL_CYCEVTENA_Pos) /*!< DWT CTRL: CYCEVTENA Mask */ + +#define DWT_CTRL_FOLDEVTENA_Pos 21U /*!< DWT CTRL: FOLDEVTENA Position */ +#define DWT_CTRL_FOLDEVTENA_Msk (0x1UL << DWT_CTRL_FOLDEVTENA_Pos) /*!< DWT CTRL: FOLDEVTENA Mask */ + +#define DWT_CTRL_LSUEVTENA_Pos 20U /*!< DWT CTRL: LSUEVTENA Position */ +#define DWT_CTRL_LSUEVTENA_Msk (0x1UL << DWT_CTRL_LSUEVTENA_Pos) /*!< DWT CTRL: LSUEVTENA Mask */ + +#define DWT_CTRL_SLEEPEVTENA_Pos 19U /*!< DWT CTRL: SLEEPEVTENA Position */ +#define DWT_CTRL_SLEEPEVTENA_Msk (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos) /*!< DWT CTRL: SLEEPEVTENA Mask */ + +#define DWT_CTRL_EXCEVTENA_Pos 18U /*!< DWT CTRL: EXCEVTENA Position */ +#define DWT_CTRL_EXCEVTENA_Msk (0x1UL << DWT_CTRL_EXCEVTENA_Pos) /*!< DWT CTRL: EXCEVTENA Mask */ + +#define DWT_CTRL_CPIEVTENA_Pos 17U /*!< DWT CTRL: CPIEVTENA Position */ +#define DWT_CTRL_CPIEVTENA_Msk (0x1UL << DWT_CTRL_CPIEVTENA_Pos) /*!< DWT CTRL: CPIEVTENA Mask */ + +#define DWT_CTRL_EXCTRCENA_Pos 16U /*!< DWT CTRL: EXCTRCENA Position */ +#define DWT_CTRL_EXCTRCENA_Msk (0x1UL << DWT_CTRL_EXCTRCENA_Pos) /*!< DWT CTRL: EXCTRCENA Mask */ + +#define DWT_CTRL_PCSAMPLENA_Pos 12U /*!< DWT CTRL: PCSAMPLENA Position */ +#define DWT_CTRL_PCSAMPLENA_Msk (0x1UL << DWT_CTRL_PCSAMPLENA_Pos) /*!< DWT CTRL: PCSAMPLENA Mask */ + +#define DWT_CTRL_SYNCTAP_Pos 10U /*!< DWT CTRL: SYNCTAP Position */ +#define DWT_CTRL_SYNCTAP_Msk (0x3UL << DWT_CTRL_SYNCTAP_Pos) /*!< DWT CTRL: SYNCTAP Mask */ + +#define DWT_CTRL_CYCTAP_Pos 9U /*!< DWT CTRL: CYCTAP Position */ +#define DWT_CTRL_CYCTAP_Msk (0x1UL << DWT_CTRL_CYCTAP_Pos) /*!< DWT CTRL: CYCTAP Mask */ + +#define DWT_CTRL_POSTINIT_Pos 5U /*!< DWT CTRL: POSTINIT Position */ +#define DWT_CTRL_POSTINIT_Msk (0xFUL << DWT_CTRL_POSTINIT_Pos) /*!< DWT CTRL: POSTINIT Mask */ + +#define DWT_CTRL_POSTPRESET_Pos 1U /*!< DWT CTRL: POSTPRESET Position */ +#define DWT_CTRL_POSTPRESET_Msk (0xFUL << DWT_CTRL_POSTPRESET_Pos) /*!< DWT CTRL: POSTPRESET Mask */ + +#define DWT_CTRL_CYCCNTENA_Pos 0U /*!< DWT CTRL: CYCCNTENA Position */ +#define DWT_CTRL_CYCCNTENA_Msk (0x1UL /*<< DWT_CTRL_CYCCNTENA_Pos*/) /*!< DWT CTRL: CYCCNTENA Mask */ + +/* DWT CPI Count Register Definitions */ +#define DWT_CPICNT_CPICNT_Pos 0U /*!< DWT CPICNT: CPICNT Position */ +#define DWT_CPICNT_CPICNT_Msk (0xFFUL /*<< DWT_CPICNT_CPICNT_Pos*/) /*!< DWT CPICNT: CPICNT Mask */ + +/* DWT Exception Overhead Count Register Definitions */ +#define DWT_EXCCNT_EXCCNT_Pos 0U /*!< DWT EXCCNT: EXCCNT Position */ +#define DWT_EXCCNT_EXCCNT_Msk (0xFFUL /*<< DWT_EXCCNT_EXCCNT_Pos*/) /*!< DWT EXCCNT: EXCCNT Mask */ + +/* DWT Sleep Count Register Definitions */ +#define DWT_SLEEPCNT_SLEEPCNT_Pos 0U /*!< DWT SLEEPCNT: SLEEPCNT Position */ +#define DWT_SLEEPCNT_SLEEPCNT_Msk (0xFFUL /*<< DWT_SLEEPCNT_SLEEPCNT_Pos*/) /*!< DWT SLEEPCNT: SLEEPCNT Mask */ + +/* DWT LSU Count Register Definitions */ +#define DWT_LSUCNT_LSUCNT_Pos 0U /*!< DWT LSUCNT: LSUCNT Position */ +#define DWT_LSUCNT_LSUCNT_Msk (0xFFUL /*<< DWT_LSUCNT_LSUCNT_Pos*/) /*!< DWT LSUCNT: LSUCNT Mask */ + +/* DWT Folded-instruction Count Register Definitions */ +#define DWT_FOLDCNT_FOLDCNT_Pos 0U /*!< DWT FOLDCNT: FOLDCNT Position */ +#define DWT_FOLDCNT_FOLDCNT_Msk (0xFFUL /*<< DWT_FOLDCNT_FOLDCNT_Pos*/) /*!< DWT FOLDCNT: FOLDCNT Mask */ + +/* DWT Comparator Function Register Definitions */ +#define DWT_FUNCTION_ID_Pos 27U /*!< DWT FUNCTION: ID Position */ +#define DWT_FUNCTION_ID_Msk (0x1FUL << DWT_FUNCTION_ID_Pos) /*!< DWT FUNCTION: ID Mask */ + +#define DWT_FUNCTION_MATCHED_Pos 24U /*!< DWT FUNCTION: MATCHED Position */ +#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ + +#define DWT_FUNCTION_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */ +#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ + +#define DWT_FUNCTION_ACTION_Pos 4U /*!< DWT FUNCTION: ACTION Position */ +#define DWT_FUNCTION_ACTION_Msk (0x1UL << DWT_FUNCTION_ACTION_Pos) /*!< DWT FUNCTION: ACTION Mask */ + +#define DWT_FUNCTION_MATCH_Pos 0U /*!< DWT FUNCTION: MATCH Position */ +#define DWT_FUNCTION_MATCH_Msk (0xFUL /*<< DWT_FUNCTION_MATCH_Pos*/) /*!< DWT FUNCTION: MATCH Mask */ + +/*@}*/ /* end of group CMSIS_DWT */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_TPI Trace Port Interface (TPI) + \brief Type definitions for the Trace Port Interface (TPI) + @{ + */ + +/** + \brief Structure type to access the Trace Port Interface Register (TPI). + */ +typedef struct +{ + __IM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Sizes Register */ + __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Sizes Register */ + uint32_t RESERVED0[2U]; + __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ + uint32_t RESERVED1[55U]; + __IOM uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ + uint32_t RESERVED2[131U]; + __IM uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ + __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ + __IOM uint32_t PSCR; /*!< Offset: 0x308 (R/W) Periodic Synchronization Control Register */ + uint32_t RESERVED3[809U]; + __OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) Software Lock Access Register */ + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) Software Lock Status Register */ + uint32_t RESERVED4[4U]; + __IM uint32_t TYPE; /*!< Offset: 0xFC8 (R/ ) Device Identifier Register */ + __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) Device Type Register */ +} TPI_Type; + +/* TPI Asynchronous Clock Prescaler Register Definitions */ +#define TPI_ACPR_SWOSCALER_Pos 0U /*!< TPI ACPR: SWOSCALER Position */ +#define TPI_ACPR_SWOSCALER_Msk (0xFFFFUL /*<< TPI_ACPR_SWOSCALER_Pos*/) /*!< TPI ACPR: SWOSCALER Mask */ + +/* TPI Selected Pin Protocol Register Definitions */ +#define TPI_SPPR_TXMODE_Pos 0U /*!< TPI SPPR: TXMODE Position */ +#define TPI_SPPR_TXMODE_Msk (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/) /*!< TPI SPPR: TXMODE Mask */ + +/* TPI Formatter and Flush Status Register Definitions */ +#define TPI_FFSR_FtNonStop_Pos 3U /*!< TPI FFSR: FtNonStop Position */ +#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ + +#define TPI_FFSR_TCPresent_Pos 2U /*!< TPI FFSR: TCPresent Position */ +#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ + +#define TPI_FFSR_FtStopped_Pos 1U /*!< TPI FFSR: FtStopped Position */ +#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ + +#define TPI_FFSR_FlInProg_Pos 0U /*!< TPI FFSR: FlInProg Position */ +#define TPI_FFSR_FlInProg_Msk (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/) /*!< TPI FFSR: FlInProg Mask */ + +/* TPI Formatter and Flush Control Register Definitions */ +#define TPI_FFCR_TrigIn_Pos 8U /*!< TPI FFCR: TrigIn Position */ +#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ + +#define TPI_FFCR_FOnMan_Pos 6U /*!< TPI FFCR: FOnMan Position */ +#define TPI_FFCR_FOnMan_Msk (0x1UL << TPI_FFCR_FOnMan_Pos) /*!< TPI FFCR: FOnMan Mask */ + +#define TPI_FFCR_EnFCont_Pos 1U /*!< TPI FFCR: EnFCont Position */ +#define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ + +/* TPI Periodic Synchronization Control Register Definitions */ +#define TPI_PSCR_PSCount_Pos 0U /*!< TPI PSCR: PSCount Position */ +#define TPI_PSCR_PSCount_Msk (0x1FUL /*<< TPI_PSCR_PSCount_Pos*/) /*!< TPI PSCR: TPSCount Mask */ + +/* TPI Software Lock Status Register Definitions */ +#define TPI_LSR_nTT_Pos 1U /*!< TPI LSR: Not thirty-two bit. Position */ +#define TPI_LSR_nTT_Msk (0x1UL << TPI_LSR_nTT_Pos) /*!< TPI LSR: Not thirty-two bit. Mask */ + +#define TPI_LSR_SLK_Pos 1U /*!< TPI LSR: Software Lock status Position */ +#define TPI_LSR_SLK_Msk (0x1UL << TPI_LSR_SLK_Pos) /*!< TPI LSR: Software Lock status Mask */ + +#define TPI_LSR_SLI_Pos 0U /*!< TPI LSR: Software Lock implemented Position */ +#define TPI_LSR_SLI_Msk (0x1UL /*<< TPI_LSR_SLI_Pos*/) /*!< TPI LSR: Software Lock implemented Mask */ + +/* TPI DEVID Register Definitions */ +#define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */ +#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ + +#define TPI_DEVID_MANCVALID_Pos 10U /*!< TPI DEVID: MANCVALID Position */ +#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ + +#define TPI_DEVID_PTINVALID_Pos 9U /*!< TPI DEVID: PTINVALID Position */ +#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ + +#define TPI_DEVID_FIFOSZ_Pos 6U /*!< TPI DEVID: FIFO depth Position */ +#define TPI_DEVID_FIFOSZ_Msk (0x7UL << TPI_DEVID_FIFOSZ_Pos) /*!< TPI DEVID: FIFO depth Mask */ + +/* TPI DEVTYPE Register Definitions */ +#define TPI_DEVTYPE_SubType_Pos 4U /*!< TPI DEVTYPE: SubType Position */ +#define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ + +#define TPI_DEVTYPE_MajorType_Pos 0U /*!< TPI DEVTYPE: MajorType Position */ +#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ + +/*@}*/ /* end of group CMSIS_TPI */ + + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** + \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region Number Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) MPU Region Limit Address Register */ + __IOM uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Region Base Address Register Alias 1 */ + __IOM uint32_t RLAR_A1; /*!< Offset: 0x018 (R/W) MPU Region Limit Address Register Alias 1 */ + __IOM uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Region Base Address Register Alias 2 */ + __IOM uint32_t RLAR_A2; /*!< Offset: 0x020 (R/W) MPU Region Limit Address Register Alias 2 */ + __IOM uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Region Base Address Register Alias 3 */ + __IOM uint32_t RLAR_A3; /*!< Offset: 0x028 (R/W) MPU Region Limit Address Register Alias 3 */ + uint32_t RESERVED0[1]; + union { + __IOM uint32_t MAIR[2]; + struct { + __IOM uint32_t MAIR0; /*!< Offset: 0x030 (R/W) MPU Memory Attribute Indirection Register 0 */ + __IOM uint32_t MAIR1; /*!< Offset: 0x034 (R/W) MPU Memory Attribute Indirection Register 1 */ + }; + }; +} MPU_Type; + +#define MPU_TYPE_RALIASES 4U + +/* MPU Type Register Definitions */ +#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register Definitions */ +#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register Definitions */ +#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register Definitions */ +#define MPU_RBAR_BASE_Pos 5U /*!< MPU RBAR: BASE Position */ +#define MPU_RBAR_BASE_Msk (0x7FFFFFFUL << MPU_RBAR_BASE_Pos) /*!< MPU RBAR: BASE Mask */ + +#define MPU_RBAR_SH_Pos 3U /*!< MPU RBAR: SH Position */ +#define MPU_RBAR_SH_Msk (0x3UL << MPU_RBAR_SH_Pos) /*!< MPU RBAR: SH Mask */ + +#define MPU_RBAR_AP_Pos 1U /*!< MPU RBAR: AP Position */ +#define MPU_RBAR_AP_Msk (0x3UL << MPU_RBAR_AP_Pos) /*!< MPU RBAR: AP Mask */ + +#define MPU_RBAR_XN_Pos 0U /*!< MPU RBAR: XN Position */ +#define MPU_RBAR_XN_Msk (01UL /*<< MPU_RBAR_XN_Pos*/) /*!< MPU RBAR: XN Mask */ + +/* MPU Region Limit Address Register Definitions */ +#define MPU_RLAR_LIMIT_Pos 5U /*!< MPU RLAR: LIMIT Position */ +#define MPU_RLAR_LIMIT_Msk (0x7FFFFFFUL << MPU_RLAR_LIMIT_Pos) /*!< MPU RLAR: LIMIT Mask */ + +#define MPU_RLAR_AttrIndx_Pos 1U /*!< MPU RLAR: AttrIndx Position */ +#define MPU_RLAR_AttrIndx_Msk (0x7UL << MPU_RLAR_AttrIndx_Pos) /*!< MPU RLAR: AttrIndx Mask */ + +#define MPU_RLAR_EN_Pos 0U /*!< MPU RLAR: Region enable bit Position */ +#define MPU_RLAR_EN_Msk (1UL /*<< MPU_RLAR_EN_Pos*/) /*!< MPU RLAR: Region enable bit Disable Mask */ + +/* MPU Memory Attribute Indirection Register 0 Definitions */ +#define MPU_MAIR0_Attr3_Pos 24U /*!< MPU MAIR0: Attr3 Position */ +#define MPU_MAIR0_Attr3_Msk (0xFFUL << MPU_MAIR0_Attr3_Pos) /*!< MPU MAIR0: Attr3 Mask */ + +#define MPU_MAIR0_Attr2_Pos 16U /*!< MPU MAIR0: Attr2 Position */ +#define MPU_MAIR0_Attr2_Msk (0xFFUL << MPU_MAIR0_Attr2_Pos) /*!< MPU MAIR0: Attr2 Mask */ + +#define MPU_MAIR0_Attr1_Pos 8U /*!< MPU MAIR0: Attr1 Position */ +#define MPU_MAIR0_Attr1_Msk (0xFFUL << MPU_MAIR0_Attr1_Pos) /*!< MPU MAIR0: Attr1 Mask */ + +#define MPU_MAIR0_Attr0_Pos 0U /*!< MPU MAIR0: Attr0 Position */ +#define MPU_MAIR0_Attr0_Msk (0xFFUL /*<< MPU_MAIR0_Attr0_Pos*/) /*!< MPU MAIR0: Attr0 Mask */ + +/* MPU Memory Attribute Indirection Register 1 Definitions */ +#define MPU_MAIR1_Attr7_Pos 24U /*!< MPU MAIR1: Attr7 Position */ +#define MPU_MAIR1_Attr7_Msk (0xFFUL << MPU_MAIR1_Attr7_Pos) /*!< MPU MAIR1: Attr7 Mask */ + +#define MPU_MAIR1_Attr6_Pos 16U /*!< MPU MAIR1: Attr6 Position */ +#define MPU_MAIR1_Attr6_Msk (0xFFUL << MPU_MAIR1_Attr6_Pos) /*!< MPU MAIR1: Attr6 Mask */ + +#define MPU_MAIR1_Attr5_Pos 8U /*!< MPU MAIR1: Attr5 Position */ +#define MPU_MAIR1_Attr5_Msk (0xFFUL << MPU_MAIR1_Attr5_Pos) /*!< MPU MAIR1: Attr5 Mask */ + +#define MPU_MAIR1_Attr4_Pos 0U /*!< MPU MAIR1: Attr4 Position */ +#define MPU_MAIR1_Attr4_Msk (0xFFUL /*<< MPU_MAIR1_Attr4_Pos*/) /*!< MPU MAIR1: Attr4 Mask */ + +/*@} end of group CMSIS_MPU */ +#endif + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SAU Security Attribution Unit (SAU) + \brief Type definitions for the Security Attribution Unit (SAU) + @{ + */ + +/** + \brief Structure type to access the Security Attribution Unit (SAU). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SAU Control Register */ + __IM uint32_t TYPE; /*!< Offset: 0x004 (R/ ) SAU Type Register */ +#if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) SAU Region Number Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) SAU Region Base Address Register */ + __IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) SAU Region Limit Address Register */ +#else + uint32_t RESERVED0[3]; +#endif + __IOM uint32_t SFSR; /*!< Offset: 0x014 (R/W) Secure Fault Status Register */ + __IOM uint32_t SFAR; /*!< Offset: 0x018 (R/W) Secure Fault Address Register */ +} SAU_Type; + +/* SAU Control Register Definitions */ +#define SAU_CTRL_ALLNS_Pos 1U /*!< SAU CTRL: ALLNS Position */ +#define SAU_CTRL_ALLNS_Msk (1UL << SAU_CTRL_ALLNS_Pos) /*!< SAU CTRL: ALLNS Mask */ + +#define SAU_CTRL_ENABLE_Pos 0U /*!< SAU CTRL: ENABLE Position */ +#define SAU_CTRL_ENABLE_Msk (1UL /*<< SAU_CTRL_ENABLE_Pos*/) /*!< SAU CTRL: ENABLE Mask */ + +/* SAU Type Register Definitions */ +#define SAU_TYPE_SREGION_Pos 0U /*!< SAU TYPE: SREGION Position */ +#define SAU_TYPE_SREGION_Msk (0xFFUL /*<< SAU_TYPE_SREGION_Pos*/) /*!< SAU TYPE: SREGION Mask */ + +#if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) +/* SAU Region Number Register Definitions */ +#define SAU_RNR_REGION_Pos 0U /*!< SAU RNR: REGION Position */ +#define SAU_RNR_REGION_Msk (0xFFUL /*<< SAU_RNR_REGION_Pos*/) /*!< SAU RNR: REGION Mask */ + +/* SAU Region Base Address Register Definitions */ +#define SAU_RBAR_BADDR_Pos 5U /*!< SAU RBAR: BADDR Position */ +#define SAU_RBAR_BADDR_Msk (0x7FFFFFFUL << SAU_RBAR_BADDR_Pos) /*!< SAU RBAR: BADDR Mask */ + +/* SAU Region Limit Address Register Definitions */ +#define SAU_RLAR_LADDR_Pos 5U /*!< SAU RLAR: LADDR Position */ +#define SAU_RLAR_LADDR_Msk (0x7FFFFFFUL << SAU_RLAR_LADDR_Pos) /*!< SAU RLAR: LADDR Mask */ + +#define SAU_RLAR_NSC_Pos 1U /*!< SAU RLAR: NSC Position */ +#define SAU_RLAR_NSC_Msk (1UL << SAU_RLAR_NSC_Pos) /*!< SAU RLAR: NSC Mask */ + +#define SAU_RLAR_ENABLE_Pos 0U /*!< SAU RLAR: ENABLE Position */ +#define SAU_RLAR_ENABLE_Msk (1UL /*<< SAU_RLAR_ENABLE_Pos*/) /*!< SAU RLAR: ENABLE Mask */ + +#endif /* defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) */ + +/* Secure Fault Status Register Definitions */ +#define SAU_SFSR_LSERR_Pos 7U /*!< SAU SFSR: LSERR Position */ +#define SAU_SFSR_LSERR_Msk (1UL << SAU_SFSR_LSERR_Pos) /*!< SAU SFSR: LSERR Mask */ + +#define SAU_SFSR_SFARVALID_Pos 6U /*!< SAU SFSR: SFARVALID Position */ +#define SAU_SFSR_SFARVALID_Msk (1UL << SAU_SFSR_SFARVALID_Pos) /*!< SAU SFSR: SFARVALID Mask */ + +#define SAU_SFSR_LSPERR_Pos 5U /*!< SAU SFSR: LSPERR Position */ +#define SAU_SFSR_LSPERR_Msk (1UL << SAU_SFSR_LSPERR_Pos) /*!< SAU SFSR: LSPERR Mask */ + +#define SAU_SFSR_INVTRAN_Pos 4U /*!< SAU SFSR: INVTRAN Position */ +#define SAU_SFSR_INVTRAN_Msk (1UL << SAU_SFSR_INVTRAN_Pos) /*!< SAU SFSR: INVTRAN Mask */ + +#define SAU_SFSR_AUVIOL_Pos 3U /*!< SAU SFSR: AUVIOL Position */ +#define SAU_SFSR_AUVIOL_Msk (1UL << SAU_SFSR_AUVIOL_Pos) /*!< SAU SFSR: AUVIOL Mask */ + +#define SAU_SFSR_INVER_Pos 2U /*!< SAU SFSR: INVER Position */ +#define SAU_SFSR_INVER_Msk (1UL << SAU_SFSR_INVER_Pos) /*!< SAU SFSR: INVER Mask */ + +#define SAU_SFSR_INVIS_Pos 1U /*!< SAU SFSR: INVIS Position */ +#define SAU_SFSR_INVIS_Msk (1UL << SAU_SFSR_INVIS_Pos) /*!< SAU SFSR: INVIS Mask */ + +#define SAU_SFSR_INVEP_Pos 0U /*!< SAU SFSR: INVEP Position */ +#define SAU_SFSR_INVEP_Msk (1UL /*<< SAU_SFSR_INVEP_Pos*/) /*!< SAU SFSR: INVEP Mask */ + +/*@} end of group CMSIS_SAU */ +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_FPU Floating Point Unit (FPU) + \brief Type definitions for the Floating Point Unit (FPU) + @{ + */ + +/** + \brief Structure type to access the Floating Point Unit (FPU). + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IOM uint32_t FPCCR; /*!< Offset: 0x004 (R/W) Floating-Point Context Control Register */ + __IOM uint32_t FPCAR; /*!< Offset: 0x008 (R/W) Floating-Point Context Address Register */ + __IOM uint32_t FPDSCR; /*!< Offset: 0x00C (R/W) Floating-Point Default Status Control Register */ + __IM uint32_t MVFR0; /*!< Offset: 0x010 (R/ ) Media and FP Feature Register 0 */ + __IM uint32_t MVFR1; /*!< Offset: 0x014 (R/ ) Media and FP Feature Register 1 */ +} FPU_Type; + +/* Floating-Point Context Control Register Definitions */ +#define FPU_FPCCR_ASPEN_Pos 31U /*!< FPCCR: ASPEN bit Position */ +#define FPU_FPCCR_ASPEN_Msk (1UL << FPU_FPCCR_ASPEN_Pos) /*!< FPCCR: ASPEN bit Mask */ + +#define FPU_FPCCR_LSPEN_Pos 30U /*!< FPCCR: LSPEN Position */ +#define FPU_FPCCR_LSPEN_Msk (1UL << FPU_FPCCR_LSPEN_Pos) /*!< FPCCR: LSPEN bit Mask */ + +#define FPU_FPCCR_LSPENS_Pos 29U /*!< FPCCR: LSPENS Position */ +#define FPU_FPCCR_LSPENS_Msk (1UL << FPU_FPCCR_LSPENS_Pos) /*!< FPCCR: LSPENS bit Mask */ + +#define FPU_FPCCR_CLRONRET_Pos 28U /*!< FPCCR: CLRONRET Position */ +#define FPU_FPCCR_CLRONRET_Msk (1UL << FPU_FPCCR_CLRONRET_Pos) /*!< FPCCR: CLRONRET bit Mask */ + +#define FPU_FPCCR_CLRONRETS_Pos 27U /*!< FPCCR: CLRONRETS Position */ +#define FPU_FPCCR_CLRONRETS_Msk (1UL << FPU_FPCCR_CLRONRETS_Pos) /*!< FPCCR: CLRONRETS bit Mask */ + +#define FPU_FPCCR_TS_Pos 26U /*!< FPCCR: TS Position */ +#define FPU_FPCCR_TS_Msk (1UL << FPU_FPCCR_TS_Pos) /*!< FPCCR: TS bit Mask */ + +#define FPU_FPCCR_UFRDY_Pos 10U /*!< FPCCR: UFRDY Position */ +#define FPU_FPCCR_UFRDY_Msk (1UL << FPU_FPCCR_UFRDY_Pos) /*!< FPCCR: UFRDY bit Mask */ + +#define FPU_FPCCR_SPLIMVIOL_Pos 9U /*!< FPCCR: SPLIMVIOL Position */ +#define FPU_FPCCR_SPLIMVIOL_Msk (1UL << FPU_FPCCR_SPLIMVIOL_Pos) /*!< FPCCR: SPLIMVIOL bit Mask */ + +#define FPU_FPCCR_MONRDY_Pos 8U /*!< FPCCR: MONRDY Position */ +#define FPU_FPCCR_MONRDY_Msk (1UL << FPU_FPCCR_MONRDY_Pos) /*!< FPCCR: MONRDY bit Mask */ + +#define FPU_FPCCR_SFRDY_Pos 7U /*!< FPCCR: SFRDY Position */ +#define FPU_FPCCR_SFRDY_Msk (1UL << FPU_FPCCR_SFRDY_Pos) /*!< FPCCR: SFRDY bit Mask */ + +#define FPU_FPCCR_BFRDY_Pos 6U /*!< FPCCR: BFRDY Position */ +#define FPU_FPCCR_BFRDY_Msk (1UL << FPU_FPCCR_BFRDY_Pos) /*!< FPCCR: BFRDY bit Mask */ + +#define FPU_FPCCR_MMRDY_Pos 5U /*!< FPCCR: MMRDY Position */ +#define FPU_FPCCR_MMRDY_Msk (1UL << FPU_FPCCR_MMRDY_Pos) /*!< FPCCR: MMRDY bit Mask */ + +#define FPU_FPCCR_HFRDY_Pos 4U /*!< FPCCR: HFRDY Position */ +#define FPU_FPCCR_HFRDY_Msk (1UL << FPU_FPCCR_HFRDY_Pos) /*!< FPCCR: HFRDY bit Mask */ + +#define FPU_FPCCR_THREAD_Pos 3U /*!< FPCCR: processor mode bit Position */ +#define FPU_FPCCR_THREAD_Msk (1UL << FPU_FPCCR_THREAD_Pos) /*!< FPCCR: processor mode active bit Mask */ + +#define FPU_FPCCR_S_Pos 2U /*!< FPCCR: Security status of the FP context bit Position */ +#define FPU_FPCCR_S_Msk (1UL << FPU_FPCCR_S_Pos) /*!< FPCCR: Security status of the FP context bit Mask */ + +#define FPU_FPCCR_USER_Pos 1U /*!< FPCCR: privilege level bit Position */ +#define FPU_FPCCR_USER_Msk (1UL << FPU_FPCCR_USER_Pos) /*!< FPCCR: privilege level bit Mask */ + +#define FPU_FPCCR_LSPACT_Pos 0U /*!< FPCCR: Lazy state preservation active bit Position */ +#define FPU_FPCCR_LSPACT_Msk (1UL /*<< FPU_FPCCR_LSPACT_Pos*/) /*!< FPCCR: Lazy state preservation active bit Mask */ + +/* Floating-Point Context Address Register Definitions */ +#define FPU_FPCAR_ADDRESS_Pos 3U /*!< FPCAR: ADDRESS bit Position */ +#define FPU_FPCAR_ADDRESS_Msk (0x1FFFFFFFUL << FPU_FPCAR_ADDRESS_Pos) /*!< FPCAR: ADDRESS bit Mask */ + +/* Floating-Point Default Status Control Register Definitions */ +#define FPU_FPDSCR_AHP_Pos 26U /*!< FPDSCR: AHP bit Position */ +#define FPU_FPDSCR_AHP_Msk (1UL << FPU_FPDSCR_AHP_Pos) /*!< FPDSCR: AHP bit Mask */ + +#define FPU_FPDSCR_DN_Pos 25U /*!< FPDSCR: DN bit Position */ +#define FPU_FPDSCR_DN_Msk (1UL << FPU_FPDSCR_DN_Pos) /*!< FPDSCR: DN bit Mask */ + +#define FPU_FPDSCR_FZ_Pos 24U /*!< FPDSCR: FZ bit Position */ +#define FPU_FPDSCR_FZ_Msk (1UL << FPU_FPDSCR_FZ_Pos) /*!< FPDSCR: FZ bit Mask */ + +#define FPU_FPDSCR_RMode_Pos 22U /*!< FPDSCR: RMode bit Position */ +#define FPU_FPDSCR_RMode_Msk (3UL << FPU_FPDSCR_RMode_Pos) /*!< FPDSCR: RMode bit Mask */ + +/* Media and FP Feature Register 0 Definitions */ +#define FPU_MVFR0_FP_rounding_modes_Pos 28U /*!< MVFR0: FP rounding modes bits Position */ +#define FPU_MVFR0_FP_rounding_modes_Msk (0xFUL << FPU_MVFR0_FP_rounding_modes_Pos) /*!< MVFR0: FP rounding modes bits Mask */ + +#define FPU_MVFR0_Short_vectors_Pos 24U /*!< MVFR0: Short vectors bits Position */ +#define FPU_MVFR0_Short_vectors_Msk (0xFUL << FPU_MVFR0_Short_vectors_Pos) /*!< MVFR0: Short vectors bits Mask */ + +#define FPU_MVFR0_Square_root_Pos 20U /*!< MVFR0: Square root bits Position */ +#define FPU_MVFR0_Square_root_Msk (0xFUL << FPU_MVFR0_Square_root_Pos) /*!< MVFR0: Square root bits Mask */ + +#define FPU_MVFR0_Divide_Pos 16U /*!< MVFR0: Divide bits Position */ +#define FPU_MVFR0_Divide_Msk (0xFUL << FPU_MVFR0_Divide_Pos) /*!< MVFR0: Divide bits Mask */ + +#define FPU_MVFR0_FP_excep_trapping_Pos 12U /*!< MVFR0: FP exception trapping bits Position */ +#define FPU_MVFR0_FP_excep_trapping_Msk (0xFUL << FPU_MVFR0_FP_excep_trapping_Pos) /*!< MVFR0: FP exception trapping bits Mask */ + +#define FPU_MVFR0_Double_precision_Pos 8U /*!< MVFR0: Double-precision bits Position */ +#define FPU_MVFR0_Double_precision_Msk (0xFUL << FPU_MVFR0_Double_precision_Pos) /*!< MVFR0: Double-precision bits Mask */ + +#define FPU_MVFR0_Single_precision_Pos 4U /*!< MVFR0: Single-precision bits Position */ +#define FPU_MVFR0_Single_precision_Msk (0xFUL << FPU_MVFR0_Single_precision_Pos) /*!< MVFR0: Single-precision bits Mask */ + +#define FPU_MVFR0_A_SIMD_registers_Pos 0U /*!< MVFR0: A_SIMD registers bits Position */ +#define FPU_MVFR0_A_SIMD_registers_Msk (0xFUL /*<< FPU_MVFR0_A_SIMD_registers_Pos*/) /*!< MVFR0: A_SIMD registers bits Mask */ + +/* Media and FP Feature Register 1 Definitions */ +#define FPU_MVFR1_FP_fused_MAC_Pos 28U /*!< MVFR1: FP fused MAC bits Position */ +#define FPU_MVFR1_FP_fused_MAC_Msk (0xFUL << FPU_MVFR1_FP_fused_MAC_Pos) /*!< MVFR1: FP fused MAC bits Mask */ + +#define FPU_MVFR1_FP_HPFP_Pos 24U /*!< MVFR1: FP HPFP bits Position */ +#define FPU_MVFR1_FP_HPFP_Msk (0xFUL << FPU_MVFR1_FP_HPFP_Pos) /*!< MVFR1: FP HPFP bits Mask */ + +#define FPU_MVFR1_D_NaN_mode_Pos 4U /*!< MVFR1: D_NaN mode bits Position */ +#define FPU_MVFR1_D_NaN_mode_Msk (0xFUL << FPU_MVFR1_D_NaN_mode_Pos) /*!< MVFR1: D_NaN mode bits Mask */ + +#define FPU_MVFR1_FtZ_mode_Pos 0U /*!< MVFR1: FtZ mode bits Position */ +#define FPU_MVFR1_FtZ_mode_Msk (0xFUL /*<< FPU_MVFR1_FtZ_mode_Pos*/) /*!< MVFR1: FtZ mode bits Mask */ + +/*@} end of group CMSIS_FPU */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Type definitions for the Core Debug Registers + @{ + */ + +/** + \brief Structure type to access the Core Debug Register (CoreDebug). + */ +typedef struct +{ + __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ + uint32_t RESERVED4[1U]; + __IOM uint32_t DAUTHCTRL; /*!< Offset: 0x014 (R/W) Debug Authentication Control Register */ + __IOM uint32_t DSCSR; /*!< Offset: 0x018 (R/W) Debug Security Control and Status Register */ +} CoreDebug_Type; + +/* Debug Halting Control and Status Register Definitions */ +#define CoreDebug_DHCSR_DBGKEY_Pos 16U /*!< CoreDebug DHCSR: DBGKEY Position */ +#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */ + +#define CoreDebug_DHCSR_S_RESTART_ST_Pos 26U /*!< CoreDebug DHCSR: S_RESTART_ST Position */ +#define CoreDebug_DHCSR_S_RESTART_ST_Msk (1UL << CoreDebug_DHCSR_S_RESTART_ST_Pos) /*!< CoreDebug DHCSR: S_RESTART_ST Mask */ + +#define CoreDebug_DHCSR_S_RESET_ST_Pos 25U /*!< CoreDebug DHCSR: S_RESET_ST Position */ +#define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< CoreDebug DHCSR: S_RESET_ST Mask */ + +#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24U /*!< CoreDebug DHCSR: S_RETIRE_ST Position */ +#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */ + +#define CoreDebug_DHCSR_S_LOCKUP_Pos 19U /*!< CoreDebug DHCSR: S_LOCKUP Position */ +#define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< CoreDebug DHCSR: S_LOCKUP Mask */ + +#define CoreDebug_DHCSR_S_SLEEP_Pos 18U /*!< CoreDebug DHCSR: S_SLEEP Position */ +#define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< CoreDebug DHCSR: S_SLEEP Mask */ + +#define CoreDebug_DHCSR_S_HALT_Pos 17U /*!< CoreDebug DHCSR: S_HALT Position */ +#define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< CoreDebug DHCSR: S_HALT Mask */ + +#define CoreDebug_DHCSR_S_REGRDY_Pos 16U /*!< CoreDebug DHCSR: S_REGRDY Position */ +#define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< CoreDebug DHCSR: S_REGRDY Mask */ + +#define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5U /*!< CoreDebug DHCSR: C_SNAPSTALL Position */ +#define CoreDebug_DHCSR_C_SNAPSTALL_Msk (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos) /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */ + +#define CoreDebug_DHCSR_C_MASKINTS_Pos 3U /*!< CoreDebug DHCSR: C_MASKINTS Position */ +#define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< CoreDebug DHCSR: C_MASKINTS Mask */ + +#define CoreDebug_DHCSR_C_STEP_Pos 2U /*!< CoreDebug DHCSR: C_STEP Position */ +#define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< CoreDebug DHCSR: C_STEP Mask */ + +#define CoreDebug_DHCSR_C_HALT_Pos 1U /*!< CoreDebug DHCSR: C_HALT Position */ +#define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< CoreDebug DHCSR: C_HALT Mask */ + +#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0U /*!< CoreDebug DHCSR: C_DEBUGEN Position */ +#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */ + +/* Debug Core Register Selector Register Definitions */ +#define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< CoreDebug DCRSR: REGWnR Position */ +#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ + +#define CoreDebug_DCRSR_REGSEL_Pos 0U /*!< CoreDebug DCRSR: REGSEL Position */ +#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/) /*!< CoreDebug DCRSR: REGSEL Mask */ + +/* Debug Exception and Monitor Control Register Definitions */ +#define CoreDebug_DEMCR_TRCENA_Pos 24U /*!< CoreDebug DEMCR: TRCENA Position */ +#define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< CoreDebug DEMCR: TRCENA Mask */ + +#define CoreDebug_DEMCR_MON_REQ_Pos 19U /*!< CoreDebug DEMCR: MON_REQ Position */ +#define CoreDebug_DEMCR_MON_REQ_Msk (1UL << CoreDebug_DEMCR_MON_REQ_Pos) /*!< CoreDebug DEMCR: MON_REQ Mask */ + +#define CoreDebug_DEMCR_MON_STEP_Pos 18U /*!< CoreDebug DEMCR: MON_STEP Position */ +#define CoreDebug_DEMCR_MON_STEP_Msk (1UL << CoreDebug_DEMCR_MON_STEP_Pos) /*!< CoreDebug DEMCR: MON_STEP Mask */ + +#define CoreDebug_DEMCR_MON_PEND_Pos 17U /*!< CoreDebug DEMCR: MON_PEND Position */ +#define CoreDebug_DEMCR_MON_PEND_Msk (1UL << CoreDebug_DEMCR_MON_PEND_Pos) /*!< CoreDebug DEMCR: MON_PEND Mask */ + +#define CoreDebug_DEMCR_MON_EN_Pos 16U /*!< CoreDebug DEMCR: MON_EN Position */ +#define CoreDebug_DEMCR_MON_EN_Msk (1UL << CoreDebug_DEMCR_MON_EN_Pos) /*!< CoreDebug DEMCR: MON_EN Mask */ + +#define CoreDebug_DEMCR_VC_HARDERR_Pos 10U /*!< CoreDebug DEMCR: VC_HARDERR Position */ +#define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< CoreDebug DEMCR: VC_HARDERR Mask */ + +#define CoreDebug_DEMCR_VC_INTERR_Pos 9U /*!< CoreDebug DEMCR: VC_INTERR Position */ +#define CoreDebug_DEMCR_VC_INTERR_Msk (1UL << CoreDebug_DEMCR_VC_INTERR_Pos) /*!< CoreDebug DEMCR: VC_INTERR Mask */ + +#define CoreDebug_DEMCR_VC_BUSERR_Pos 8U /*!< CoreDebug DEMCR: VC_BUSERR Position */ +#define CoreDebug_DEMCR_VC_BUSERR_Msk (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos) /*!< CoreDebug DEMCR: VC_BUSERR Mask */ + +#define CoreDebug_DEMCR_VC_STATERR_Pos 7U /*!< CoreDebug DEMCR: VC_STATERR Position */ +#define CoreDebug_DEMCR_VC_STATERR_Msk (1UL << CoreDebug_DEMCR_VC_STATERR_Pos) /*!< CoreDebug DEMCR: VC_STATERR Mask */ + +#define CoreDebug_DEMCR_VC_CHKERR_Pos 6U /*!< CoreDebug DEMCR: VC_CHKERR Position */ +#define CoreDebug_DEMCR_VC_CHKERR_Msk (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos) /*!< CoreDebug DEMCR: VC_CHKERR Mask */ + +#define CoreDebug_DEMCR_VC_NOCPERR_Pos 5U /*!< CoreDebug DEMCR: VC_NOCPERR Position */ +#define CoreDebug_DEMCR_VC_NOCPERR_Msk (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos) /*!< CoreDebug DEMCR: VC_NOCPERR Mask */ + +#define CoreDebug_DEMCR_VC_MMERR_Pos 4U /*!< CoreDebug DEMCR: VC_MMERR Position */ +#define CoreDebug_DEMCR_VC_MMERR_Msk (1UL << CoreDebug_DEMCR_VC_MMERR_Pos) /*!< CoreDebug DEMCR: VC_MMERR Mask */ + +#define CoreDebug_DEMCR_VC_CORERESET_Pos 0U /*!< CoreDebug DEMCR: VC_CORERESET Position */ +#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/) /*!< CoreDebug DEMCR: VC_CORERESET Mask */ + +/* Debug Authentication Control Register Definitions */ +#define CoreDebug_DAUTHCTRL_INTSPNIDEN_Pos 3U /*!< CoreDebug DAUTHCTRL: INTSPNIDEN, Position */ +#define CoreDebug_DAUTHCTRL_INTSPNIDEN_Msk (1UL << CoreDebug_DAUTHCTRL_INTSPNIDEN_Pos) /*!< CoreDebug DAUTHCTRL: INTSPNIDEN, Mask */ + +#define CoreDebug_DAUTHCTRL_SPNIDENSEL_Pos 2U /*!< CoreDebug DAUTHCTRL: SPNIDENSEL Position */ +#define CoreDebug_DAUTHCTRL_SPNIDENSEL_Msk (1UL << CoreDebug_DAUTHCTRL_SPNIDENSEL_Pos) /*!< CoreDebug DAUTHCTRL: SPNIDENSEL Mask */ + +#define CoreDebug_DAUTHCTRL_INTSPIDEN_Pos 1U /*!< CoreDebug DAUTHCTRL: INTSPIDEN Position */ +#define CoreDebug_DAUTHCTRL_INTSPIDEN_Msk (1UL << CoreDebug_DAUTHCTRL_INTSPIDEN_Pos) /*!< CoreDebug DAUTHCTRL: INTSPIDEN Mask */ + +#define CoreDebug_DAUTHCTRL_SPIDENSEL_Pos 0U /*!< CoreDebug DAUTHCTRL: SPIDENSEL Position */ +#define CoreDebug_DAUTHCTRL_SPIDENSEL_Msk (1UL /*<< CoreDebug_DAUTHCTRL_SPIDENSEL_Pos*/) /*!< CoreDebug DAUTHCTRL: SPIDENSEL Mask */ + +/* Debug Security Control and Status Register Definitions */ +#define CoreDebug_DSCSR_CDS_Pos 16U /*!< CoreDebug DSCSR: CDS Position */ +#define CoreDebug_DSCSR_CDS_Msk (1UL << CoreDebug_DSCSR_CDS_Pos) /*!< CoreDebug DSCSR: CDS Mask */ + +#define CoreDebug_DSCSR_SBRSEL_Pos 1U /*!< CoreDebug DSCSR: SBRSEL Position */ +#define CoreDebug_DSCSR_SBRSEL_Msk (1UL << CoreDebug_DSCSR_SBRSEL_Pos) /*!< CoreDebug DSCSR: SBRSEL Mask */ + +#define CoreDebug_DSCSR_SBRSELEN_Pos 0U /*!< CoreDebug DSCSR: SBRSELEN Position */ +#define CoreDebug_DSCSR_SBRSELEN_Msk (1UL /*<< CoreDebug_DSCSR_SBRSELEN_Pos*/) /*!< CoreDebug DSCSR: SBRSELEN Mask */ + +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param[in] field Name of the register bit field. + \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param[in] field Name of the register bit field. + \param[in] value Value of register. This parameter is interpreted as an uint32_t type. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) + +/*@} end of group CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Core Hardware */ + #define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ + #define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ + #define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ + #define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ + #define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */ + #define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ + #define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ + #define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + + #define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ + #define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ + #define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ + #define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ + #define ITM ((ITM_Type *) ITM_BASE ) /*!< ITM configuration struct */ + #define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ + #define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ + #define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE ) /*!< Core Debug configuration struct */ + + #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ + #endif + + #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + #define SAU_BASE (SCS_BASE + 0x0DD0UL) /*!< Security Attribution Unit */ + #define SAU ((SAU_Type *) SAU_BASE ) /*!< Security Attribution Unit */ + #endif + + #define FPU_BASE (SCS_BASE + 0x0F30UL) /*!< Floating Point Unit */ + #define FPU ((FPU_Type *) FPU_BASE ) /*!< Floating Point Unit */ + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + #define SCS_BASE_NS (0xE002E000UL) /*!< System Control Space Base Address (non-secure address space) */ + #define CoreDebug_BASE_NS (0xE002EDF0UL) /*!< Core Debug Base Address (non-secure address space) */ + #define SysTick_BASE_NS (SCS_BASE_NS + 0x0010UL) /*!< SysTick Base Address (non-secure address space) */ + #define NVIC_BASE_NS (SCS_BASE_NS + 0x0100UL) /*!< NVIC Base Address (non-secure address space) */ + #define SCB_BASE_NS (SCS_BASE_NS + 0x0D00UL) /*!< System Control Block Base Address (non-secure address space) */ + + #define SCnSCB_NS ((SCnSCB_Type *) SCS_BASE_NS ) /*!< System control Register not in SCB(non-secure address space) */ + #define SCB_NS ((SCB_Type *) SCB_BASE_NS ) /*!< SCB configuration struct (non-secure address space) */ + #define SysTick_NS ((SysTick_Type *) SysTick_BASE_NS ) /*!< SysTick configuration struct (non-secure address space) */ + #define NVIC_NS ((NVIC_Type *) NVIC_BASE_NS ) /*!< NVIC configuration struct (non-secure address space) */ + #define CoreDebug_NS ((CoreDebug_Type *) CoreDebug_BASE_NS) /*!< Core Debug configuration struct (non-secure address space) */ + + #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE_NS (SCS_BASE_NS + 0x0D90UL) /*!< Memory Protection Unit (non-secure address space) */ + #define MPU_NS ((MPU_Type *) MPU_BASE_NS ) /*!< Memory Protection Unit (non-secure address space) */ + #endif + + #define FPU_BASE_NS (SCS_BASE_NS + 0x0F30UL) /*!< Floating Point Unit (non-secure address space) */ + #define FPU_NS ((FPU_Type *) FPU_BASE_NS ) /*!< Floating Point Unit (non-secure address space) */ + +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Debug Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping + #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping + #define NVIC_EnableIRQ __NVIC_EnableIRQ + #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ + #define NVIC_DisableIRQ __NVIC_DisableIRQ + #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ + #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ + #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ + #define NVIC_GetActive __NVIC_GetActive + #define NVIC_SetPriority __NVIC_SetPriority + #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset +#endif /* CMSIS_NVIC_VIRTUAL */ + +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetVector __NVIC_SetVector + #define NVIC_GetVector __NVIC_GetVector +#endif /* (CMSIS_VECTAB_VIRTUAL) */ + +#define NVIC_USER_IRQ_OFFSET 16 + + +/* Special LR values for Secure/Non-Secure call handling and exception handling */ + +/* Function Return Payload (from ARMv8-M Architecture Reference Manual) LR value on entry from Secure BLXNS */ +#define FNC_RETURN (0xFEFFFFFFUL) /* bit [0] ignored when processing a branch */ + +/* The following EXC_RETURN mask values are used to evaluate the LR on exception entry */ +#define EXC_RETURN_PREFIX (0xFF000000UL) /* bits [31:24] set to indicate an EXC_RETURN value */ +#define EXC_RETURN_S (0x00000040UL) /* bit [6] stack used to push registers: 0=Non-secure 1=Secure */ +#define EXC_RETURN_DCRS (0x00000020UL) /* bit [5] stacking rules for called registers: 0=skipped 1=saved */ +#define EXC_RETURN_FTYPE (0x00000010UL) /* bit [4] allocate stack for floating-point context: 0=done 1=skipped */ +#define EXC_RETURN_MODE (0x00000008UL) /* bit [3] processor mode for return: 0=Handler mode 1=Thread mode */ +#define EXC_RETURN_SPSEL (0x00000002UL) /* bit [1] stack pointer used to restore context: 0=MSP 1=PSP */ +#define EXC_RETURN_ES (0x00000001UL) /* bit [0] security state exception was taken to: 0=Non-secure 1=Secure */ + +/* Integrity Signature (from ARMv8-M Architecture Reference Manual) for exception context stacking */ +#if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) /* Value for processors with floating-point extension: */ +#define EXC_INTEGRITY_SIGNATURE (0xFEFA125AUL) /* bit [0] SFTC must match LR bit[4] EXC_RETURN_FTYPE */ +#else +#define EXC_INTEGRITY_SIGNATURE (0xFEFA125BUL) /* Value for processors without floating-point extension */ +#endif + + +/** + \brief Set Priority Grouping + \details Sets the priority grouping field using the required unlock sequence. + The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. + Only values from 0..7 are used. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Priority grouping field. + */ +__STATIC_INLINE void __NVIC_SetPriorityGrouping(uint32_t PriorityGroup) +{ + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + + reg_value = SCB->AIRCR; /* read old register configuration */ + reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << 8U) ); /* Insert write key and priorty group */ + SCB->AIRCR = reg_value; +} + + +/** + \brief Get Priority Grouping + \details Reads the priority grouping field from the NVIC Interrupt Controller. + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t __NVIC_GetPriorityGrouping(void) +{ + return ((uint32_t)((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); +} + + +/** + \brief Enable Interrupt + \details Enables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Interrupt Enable status + \details Returns a device specific interrupt enable status from the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt + \details Disables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __DSB(); + __ISB(); + } +} + + +/** + \brief Get Pending Interrupt + \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt + \details Reads the active register in the NVIC and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetActive(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Get Interrupt Target State + \details Reads the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + \return 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_GetTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Target State + \details Sets the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_SetTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] |= ((uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL))); + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Clear Interrupt Target State + \details Clears the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_ClearTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] &= ~((uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL))); + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + + +/** + \brief Set Interrupt Priority + \details Sets the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every processor exception. + */ +__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->IPR[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } + else + { + SCB->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return(((uint32_t)NVIC->IPR[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return(((uint32_t)SCB->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief Encode Priority + \details Encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + return ( + ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | + ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) + ); +} + + +/** + \brief Decode Priority + \details Decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. + \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); + *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); +} + + +/** + \brief Set Interrupt Vector + \details Sets an interrupt vector in SRAM based interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + VTOR must been relocated to SRAM before. + \param [in] IRQn Interrupt number + \param [in] vector Address of interrupt handler function + */ +__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; +} + + +/** + \brief Get Interrupt Vector + \details Reads an interrupt vector from interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Address of interrupt handler function + */ +__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET]; +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + SCB_AIRCR_SYSRESETREQ_Msk ); /* Keep priority group unchanged */ + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Set Priority Grouping (non-secure) + \details Sets the non-secure priority grouping field when in secure state using the required unlock sequence. + The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. + Only values from 0..7 are used. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Priority grouping field. + */ +__STATIC_INLINE void TZ_NVIC_SetPriorityGrouping_NS(uint32_t PriorityGroup) +{ + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + + reg_value = SCB_NS->AIRCR; /* read old register configuration */ + reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << 8U) ); /* Insert write key and priorty group */ + SCB_NS->AIRCR = reg_value; +} + + +/** + \brief Get Priority Grouping (non-secure) + \details Reads the priority grouping field from the non-secure NVIC when in secure state. + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetPriorityGrouping_NS(void) +{ + return ((uint32_t)((SCB_NS->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); +} + + +/** + \brief Enable Interrupt (non-secure) + \details Enables a device specific interrupt in the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_EnableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Interrupt Enable status (non-secure) + \details Returns a device specific interrupt enable status from the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetEnableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt (non-secure) + \details Disables a device specific interrupt in the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_DisableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Pending Interrupt (non-secure) + \details Reads the NVIC pending register in the non-secure NVIC when in secure state and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt (non-secure) + \details Sets the pending bit of a device specific interrupt in the non-secure NVIC pending register when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_SetPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt (non-secure) + \details Clears the pending bit of a device specific interrupt in the non-secure NVIC pending register when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_ClearPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt (non-secure) + \details Reads the active register in non-secure NVIC when in secure state and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetActive_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Priority (non-secure) + \details Sets the priority of a non-secure device specific interrupt or a non-secure processor exception when in secure state. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every non-secure processor exception. + */ +__STATIC_INLINE void TZ_NVIC_SetPriority_NS(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->IPR[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } + else + { + SCB_NS->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } +} + + +/** + \brief Get Interrupt Priority (non-secure) + \details Reads the priority of a non-secure device specific interrupt or a non-secure processor exception when in secure state. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetPriority_NS(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return(((uint32_t)NVIC_NS->IPR[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return(((uint32_t)SCB_NS->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); + } +} +#endif /* defined (__ARM_FEATURE_CMSE) &&(__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_NVICFunctions */ + +/* ########################## MPU functions #################################### */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + +#include "mpu_armv8.h" + +#endif + +/* ########################## FPU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_FpuFunctions FPU Functions + \brief Function that provides FPU type. + @{ + */ + +/** + \brief get FPU type + \details returns the FPU type + \returns + - \b 0: No FPU + - \b 1: Single precision FPU + - \b 2: Double + Single precision FPU + */ +__STATIC_INLINE uint32_t SCB_GetFPUType(void) +{ + uint32_t mvfr0; + + mvfr0 = FPU->MVFR0; + if ((mvfr0 & (FPU_MVFR0_Single_precision_Msk | FPU_MVFR0_Double_precision_Msk)) == 0x220U) + { + return 2U; /* Double + Single precision FPU */ + } + else if ((mvfr0 & (FPU_MVFR0_Single_precision_Msk | FPU_MVFR0_Double_precision_Msk)) == 0x020U) + { + return 1U; /* Single precision FPU */ + } + else + { + return 0U; /* No FPU */ + } +} + + +/*@} end of CMSIS_Core_FpuFunctions */ + + + +/* ########################## SAU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SAUFunctions SAU Functions + \brief Functions that configure the SAU. + @{ + */ + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + +/** + \brief Enable SAU + \details Enables the Security Attribution Unit (SAU). + */ +__STATIC_INLINE void TZ_SAU_Enable(void) +{ + SAU->CTRL |= (SAU_CTRL_ENABLE_Msk); +} + + + +/** + \brief Disable SAU + \details Disables the Security Attribution Unit (SAU). + */ +__STATIC_INLINE void TZ_SAU_Disable(void) +{ + SAU->CTRL &= ~(SAU_CTRL_ENABLE_Msk); +} + +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_SAUFunctions */ + + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief System Tick Configuration (non-secure) + \details Initializes the non-secure System Timer and its interrupt when in secure state, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function TZ_SysTick_Config_NS is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + + */ +__STATIC_INLINE uint32_t TZ_SysTick_Config_NS(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick_NS->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + TZ_NVIC_SetPriority_NS (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick_NS->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick_NS->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + +/* ##################################### Debug In/Output function ########################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_core_DebugFunctions ITM Functions + \brief Functions that access the ITM debug interface. + @{ + */ + +extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */ +#define ITM_RXBUFFER_EMPTY ((int32_t)0x5AA55AA5U) /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */ + + +/** + \brief ITM Send Character + \details Transmits a character via the ITM channel 0, and + \li Just returns when no debugger is connected that has booked the output. + \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted. + \param [in] ch Character to transmit. + \returns Character to transmit. + */ +__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch) +{ + if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) && /* ITM enabled */ + ((ITM->TER & 1UL ) != 0UL) ) /* ITM Port #0 enabled */ + { + while (ITM->PORT[0U].u32 == 0UL) + { + __NOP(); + } + ITM->PORT[0U].u8 = (uint8_t)ch; + } + return (ch); +} + + +/** + \brief ITM Receive Character + \details Inputs a character via the external variable \ref ITM_RxBuffer. + \return Received character. + \return -1 No character pending. + */ +__STATIC_INLINE int32_t ITM_ReceiveChar (void) +{ + int32_t ch = -1; /* no character available */ + + if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) + { + ch = ITM_RxBuffer; + ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */ + } + + return (ch); +} + + +/** + \brief ITM Check Character + \details Checks whether a character is pending for reading in the variable \ref ITM_RxBuffer. + \return 0 No character available. + \return 1 Character available. + */ +__STATIC_INLINE int32_t ITM_CheckChar (void) +{ + + if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) + { + return (0); /* no character available */ + } + else + { + return (1); /* character available */ + } +} + +/*@} end of CMSIS_core_DebugFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_ARMV8MML_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/test/STM32F072C8T6/Drivers/CMSIS/Include/core_cm0.h b/test/STM32F072C8T6/Drivers/CMSIS/Include/core_cm0.h new file mode 100644 index 0000000..6f82227 --- /dev/null +++ b/test/STM32F072C8T6/Drivers/CMSIS/Include/core_cm0.h @@ -0,0 +1,949 @@ +/**************************************************************************//** + * @file core_cm0.h + * @brief CMSIS Cortex-M0 Core Peripheral Access Layer Header File + * @version V5.0.5 + * @date 28. May 2018 + ******************************************************************************/ +/* + * Copyright (c) 2009-2018 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * 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 + * + * 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. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CORE_CM0_H_GENERIC +#define __CORE_CM0_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup Cortex_M0 + @{ + */ + +#include "cmsis_version.h" + +/* CMSIS CM0 definitions */ +#define __CM0_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __CM0_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ +#define __CM0_CMSIS_VERSION ((__CM0_CMSIS_VERSION_MAIN << 16U) | \ + __CM0_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ + +#define __CORTEX_M (0U) /*!< Cortex-M Core */ + +/** __FPU_USED indicates whether an FPU is used or not. + This core does not support an FPU at all +*/ +#define __FPU_USED 0U + +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_PCS_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TI_ARM__ ) + #if defined __TI_VFP_SUPPORT__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM0_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM0_H_DEPENDANT +#define __CORE_CM0_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM0_REV + #define __CM0_REV 0x0000U + #warning "__CM0_REV not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 2U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group Cortex_M0 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:28; /*!< bit: 0..27 Reserved */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t _reserved1:3; /*!< bit: 25..27 Reserved */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t _reserved0:1; /*!< bit: 0 Reserved */ + uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ + uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[1U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[31U]; + __IOM uint32_t ICER[1U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[31U]; + __IOM uint32_t ISPR[1U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[31U]; + __IOM uint32_t ICPR[1U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[31U]; + uint32_t RESERVED4[64U]; + __IOM uint32_t IP[8U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */ +} NVIC_Type; + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + uint32_t RESERVED0; + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + uint32_t RESERVED1; + __IOM uint32_t SHP[2U]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */ +#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */ +#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Cortex-M0 Core Debug Registers (DCB registers, SHCSR, and DFSR) are only accessible over DAP and not via processor. + Therefore they are not covered by the Cortex-M0 header file. + @{ + */ +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param[in] field Name of the register bit field. + \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param[in] field Name of the register bit field. + \param[in] value Value of register. This parameter is interpreted as an uint32_t type. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) + +/*@} end of group CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Core Hardware */ +#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ +#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ +#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ +#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + +#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ +#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ +#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ + + +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping + #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping + #define NVIC_EnableIRQ __NVIC_EnableIRQ + #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ + #define NVIC_DisableIRQ __NVIC_DisableIRQ + #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ + #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ + #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ +/*#define NVIC_GetActive __NVIC_GetActive not available for Cortex-M0 */ + #define NVIC_SetPriority __NVIC_SetPriority + #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset +#endif /* CMSIS_NVIC_VIRTUAL */ + +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetVector __NVIC_SetVector + #define NVIC_GetVector __NVIC_GetVector +#endif /* (CMSIS_VECTAB_VIRTUAL) */ + +#define NVIC_USER_IRQ_OFFSET 16 + + +/* The following EXC_RETURN values are saved the LR on exception entry */ +#define EXC_RETURN_HANDLER (0xFFFFFFF1UL) /* return to Handler mode, uses MSP after return */ +#define EXC_RETURN_THREAD_MSP (0xFFFFFFF9UL) /* return to Thread mode, uses MSP after return */ +#define EXC_RETURN_THREAD_PSP (0xFFFFFFFDUL) /* return to Thread mode, uses PSP after return */ + + +/* Interrupt Priorities are WORD accessible only under Armv6-M */ +/* The following MACROS handle generation of the register offset and byte masks */ +#define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL) +#define _SHP_IDX(IRQn) ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >> 2UL) ) +#define _IP_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 2UL) ) + +#define __NVIC_SetPriorityGrouping(X) (void)(X) +#define __NVIC_GetPriorityGrouping() (0U) + +/** + \brief Enable Interrupt + \details Enables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISER[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Interrupt Enable status + \details Returns a device specific interrupt enable status from the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISER[0U] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt + \details Disables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICER[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __DSB(); + __ISB(); + } +} + + +/** + \brief Get Pending Interrupt + \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISPR[0U] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISPR[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICPR[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Set Interrupt Priority + \details Sets the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every processor exception. + */ +__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->IP[_IP_IDX(IRQn)] = ((uint32_t)(NVIC->IP[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } + else + { + SCB->SHP[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief Encode Priority + \details Encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + return ( + ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | + ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) + ); +} + + +/** + \brief Decode Priority + \details Decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. + \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); + *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); +} + + + +/** + \brief Set Interrupt Vector + \details Sets an interrupt vector in SRAM based interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + Address 0 must be mapped to SRAM. + \param [in] IRQn Interrupt number + \param [in] vector Address of interrupt handler function + */ +__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) +{ + uint32_t *vectors = (uint32_t *)0x0U; + vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; +} + + +/** + \brief Get Interrupt Vector + \details Reads an interrupt vector from interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Address of interrupt handler function + */ +__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) +{ + uint32_t *vectors = (uint32_t *)0x0U; + return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET]; +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + SCB_AIRCR_SYSRESETREQ_Msk); + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +/*@} end of CMSIS_Core_NVICFunctions */ + + +/* ########################## FPU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_FpuFunctions FPU Functions + \brief Function that provides FPU type. + @{ + */ + +/** + \brief get FPU type + \details returns the FPU type + \returns + - \b 0: No FPU + - \b 1: Single precision FPU + - \b 2: Double + Single precision FPU + */ +__STATIC_INLINE uint32_t SCB_GetFPUType(void) +{ + return 0U; /* No FPU */ +} + + +/*@} end of CMSIS_Core_FpuFunctions */ + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM0_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/test/STM32F072C8T6/Drivers/CMSIS/Include/core_cm0plus.h b/test/STM32F072C8T6/Drivers/CMSIS/Include/core_cm0plus.h new file mode 100644 index 0000000..b9377e8 --- /dev/null +++ b/test/STM32F072C8T6/Drivers/CMSIS/Include/core_cm0plus.h @@ -0,0 +1,1083 @@ +/**************************************************************************//** + * @file core_cm0plus.h + * @brief CMSIS Cortex-M0+ Core Peripheral Access Layer Header File + * @version V5.0.6 + * @date 28. May 2018 + ******************************************************************************/ +/* + * Copyright (c) 2009-2018 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * 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 + * + * 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. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CORE_CM0PLUS_H_GENERIC +#define __CORE_CM0PLUS_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup Cortex-M0+ + @{ + */ + +#include "cmsis_version.h" + +/* CMSIS CM0+ definitions */ +#define __CM0PLUS_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __CM0PLUS_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ +#define __CM0PLUS_CMSIS_VERSION ((__CM0PLUS_CMSIS_VERSION_MAIN << 16U) | \ + __CM0PLUS_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ + +#define __CORTEX_M (0U) /*!< Cortex-M Core */ + +/** __FPU_USED indicates whether an FPU is used or not. + This core does not support an FPU at all +*/ +#define __FPU_USED 0U + +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_PCS_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TI_ARM__ ) + #if defined __TI_VFP_SUPPORT__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM0PLUS_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM0PLUS_H_DEPENDANT +#define __CORE_CM0PLUS_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM0PLUS_REV + #define __CM0PLUS_REV 0x0000U + #warning "__CM0PLUS_REV not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0U + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __VTOR_PRESENT + #define __VTOR_PRESENT 0U + #warning "__VTOR_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 2U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group Cortex-M0+ */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core MPU Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:28; /*!< bit: 0..27 Reserved */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t _reserved1:3; /*!< bit: 25..27 Reserved */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ + uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ +#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[1U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[31U]; + __IOM uint32_t ICER[1U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[31U]; + __IOM uint32_t ISPR[1U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[31U]; + __IOM uint32_t ICPR[1U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[31U]; + uint32_t RESERVED4[64U]; + __IOM uint32_t IP[8U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */ +} NVIC_Type; + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) + __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ +#else + uint32_t RESERVED0; +#endif + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + uint32_t RESERVED1; + __IOM uint32_t SHP[2U]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */ +#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) +/* SCB Interrupt Control State Register Definitions */ +#define SCB_VTOR_TBLOFF_Pos 8U /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0xFFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ +#endif + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */ +#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** + \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IOM uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */ +} MPU_Type; + +#define MPU_TYPE_RALIASES 1U + +/* MPU Type Register Definitions */ +#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register Definitions */ +#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register Definitions */ +#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register Definitions */ +#define MPU_RBAR_ADDR_Pos 8U /*!< MPU RBAR: ADDR Position */ +#define MPU_RBAR_ADDR_Msk (0xFFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ + +#define MPU_RBAR_VALID_Pos 4U /*!< MPU RBAR: VALID Position */ +#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */ + +#define MPU_RBAR_REGION_Pos 0U /*!< MPU RBAR: REGION Position */ +#define MPU_RBAR_REGION_Msk (0xFUL /*<< MPU_RBAR_REGION_Pos*/) /*!< MPU RBAR: REGION Mask */ + +/* MPU Region Attribute and Size Register Definitions */ +#define MPU_RASR_ATTRS_Pos 16U /*!< MPU RASR: MPU Region Attribute field Position */ +#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */ + +#define MPU_RASR_XN_Pos 28U /*!< MPU RASR: ATTRS.XN Position */ +#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */ + +#define MPU_RASR_AP_Pos 24U /*!< MPU RASR: ATTRS.AP Position */ +#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */ + +#define MPU_RASR_TEX_Pos 19U /*!< MPU RASR: ATTRS.TEX Position */ +#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */ + +#define MPU_RASR_S_Pos 18U /*!< MPU RASR: ATTRS.S Position */ +#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */ + +#define MPU_RASR_C_Pos 17U /*!< MPU RASR: ATTRS.C Position */ +#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */ + +#define MPU_RASR_B_Pos 16U /*!< MPU RASR: ATTRS.B Position */ +#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */ + +#define MPU_RASR_SRD_Pos 8U /*!< MPU RASR: Sub-Region Disable Position */ +#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */ + +#define MPU_RASR_SIZE_Pos 1U /*!< MPU RASR: Region Size Field Position */ +#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */ + +#define MPU_RASR_ENABLE_Pos 0U /*!< MPU RASR: Region enable bit Position */ +#define MPU_RASR_ENABLE_Msk (1UL /*<< MPU_RASR_ENABLE_Pos*/) /*!< MPU RASR: Region enable bit Disable Mask */ + +/*@} end of group CMSIS_MPU */ +#endif + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Cortex-M0+ Core Debug Registers (DCB registers, SHCSR, and DFSR) are only accessible over DAP and not via processor. + Therefore they are not covered by the Cortex-M0+ header file. + @{ + */ +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param[in] field Name of the register bit field. + \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param[in] field Name of the register bit field. + \param[in] value Value of register. This parameter is interpreted as an uint32_t type. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) + +/*@} end of group CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Core Hardware */ +#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ +#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ +#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ +#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + +#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ +#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ +#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ +#endif + +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping + #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping + #define NVIC_EnableIRQ __NVIC_EnableIRQ + #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ + #define NVIC_DisableIRQ __NVIC_DisableIRQ + #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ + #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ + #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ +/*#define NVIC_GetActive __NVIC_GetActive not available for Cortex-M0+ */ + #define NVIC_SetPriority __NVIC_SetPriority + #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset +#endif /* CMSIS_NVIC_VIRTUAL */ + +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetVector __NVIC_SetVector + #define NVIC_GetVector __NVIC_GetVector +#endif /* (CMSIS_VECTAB_VIRTUAL) */ + +#define NVIC_USER_IRQ_OFFSET 16 + + +/* The following EXC_RETURN values are saved the LR on exception entry */ +#define EXC_RETURN_HANDLER (0xFFFFFFF1UL) /* return to Handler mode, uses MSP after return */ +#define EXC_RETURN_THREAD_MSP (0xFFFFFFF9UL) /* return to Thread mode, uses MSP after return */ +#define EXC_RETURN_THREAD_PSP (0xFFFFFFFDUL) /* return to Thread mode, uses PSP after return */ + + +/* Interrupt Priorities are WORD accessible only under Armv6-M */ +/* The following MACROS handle generation of the register offset and byte masks */ +#define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL) +#define _SHP_IDX(IRQn) ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >> 2UL) ) +#define _IP_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 2UL) ) + +#define __NVIC_SetPriorityGrouping(X) (void)(X) +#define __NVIC_GetPriorityGrouping() (0U) + +/** + \brief Enable Interrupt + \details Enables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISER[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Interrupt Enable status + \details Returns a device specific interrupt enable status from the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISER[0U] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt + \details Disables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICER[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __DSB(); + __ISB(); + } +} + + +/** + \brief Get Pending Interrupt + \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISPR[0U] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISPR[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICPR[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Set Interrupt Priority + \details Sets the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every processor exception. + */ +__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->IP[_IP_IDX(IRQn)] = ((uint32_t)(NVIC->IP[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } + else + { + SCB->SHP[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief Encode Priority + \details Encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + return ( + ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | + ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) + ); +} + + +/** + \brief Decode Priority + \details Decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. + \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); + *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); +} + + +/** + \brief Set Interrupt Vector + \details Sets an interrupt vector in SRAM based interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + VTOR must been relocated to SRAM before. + If VTOR is not present address 0 must be mapped to SRAM. + \param [in] IRQn Interrupt number + \param [in] vector Address of interrupt handler function + */ +__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) +{ +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) + uint32_t *vectors = (uint32_t *)SCB->VTOR; +#else + uint32_t *vectors = (uint32_t *)0x0U; +#endif + vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; +} + + +/** + \brief Get Interrupt Vector + \details Reads an interrupt vector from interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Address of interrupt handler function + */ +__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) +{ +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) + uint32_t *vectors = (uint32_t *)SCB->VTOR; +#else + uint32_t *vectors = (uint32_t *)0x0U; +#endif + return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET]; + +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + SCB_AIRCR_SYSRESETREQ_Msk); + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +/*@} end of CMSIS_Core_NVICFunctions */ + +/* ########################## MPU functions #################################### */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + +#include "mpu_armv7.h" + +#endif + +/* ########################## FPU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_FpuFunctions FPU Functions + \brief Function that provides FPU type. + @{ + */ + +/** + \brief get FPU type + \details returns the FPU type + \returns + - \b 0: No FPU + - \b 1: Single precision FPU + - \b 2: Double + Single precision FPU + */ +__STATIC_INLINE uint32_t SCB_GetFPUType(void) +{ + return 0U; /* No FPU */ +} + + +/*@} end of CMSIS_Core_FpuFunctions */ + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM0PLUS_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/test/STM32F072C8T6/Drivers/CMSIS/Include/core_cm1.h b/test/STM32F072C8T6/Drivers/CMSIS/Include/core_cm1.h new file mode 100644 index 0000000..fd1c407 --- /dev/null +++ b/test/STM32F072C8T6/Drivers/CMSIS/Include/core_cm1.h @@ -0,0 +1,976 @@ +/**************************************************************************//** + * @file core_cm1.h + * @brief CMSIS Cortex-M1 Core Peripheral Access Layer Header File + * @version V1.0.0 + * @date 23. July 2018 + ******************************************************************************/ +/* + * Copyright (c) 2009-2018 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * 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 + * + * 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. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CORE_CM1_H_GENERIC +#define __CORE_CM1_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup Cortex_M1 + @{ + */ + +#include "cmsis_version.h" + +/* CMSIS CM1 definitions */ +#define __CM1_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __CM1_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ +#define __CM1_CMSIS_VERSION ((__CM1_CMSIS_VERSION_MAIN << 16U) | \ + __CM1_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ + +#define __CORTEX_M (1U) /*!< Cortex-M Core */ + +/** __FPU_USED indicates whether an FPU is used or not. + This core does not support an FPU at all +*/ +#define __FPU_USED 0U + +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_PCS_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TI_ARM__ ) + #if defined __TI_VFP_SUPPORT__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM1_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM1_H_DEPENDANT +#define __CORE_CM1_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM1_REV + #define __CM1_REV 0x0100U + #warning "__CM1_REV not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 2U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group Cortex_M1 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:28; /*!< bit: 0..27 Reserved */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t _reserved1:3; /*!< bit: 25..27 Reserved */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t _reserved0:1; /*!< bit: 0 Reserved */ + uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ + uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[1U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[31U]; + __IOM uint32_t ICER[1U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[31U]; + __IOM uint32_t ISPR[1U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[31U]; + __IOM uint32_t ICPR[1U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[31U]; + uint32_t RESERVED4[64U]; + __IOM uint32_t IP[8U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */ +} NVIC_Type; + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + uint32_t RESERVED0; + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + uint32_t RESERVED1; + __IOM uint32_t SHP[2U]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */ +#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */ +#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) + \brief Type definitions for the System Control and ID Register not in the SCB + @{ + */ + +/** + \brief Structure type to access the System Control and ID Register not in the SCB. + */ +typedef struct +{ + uint32_t RESERVED0[2U]; + __IOM uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ +} SCnSCB_Type; + +/* Auxiliary Control Register Definitions */ +#define SCnSCB_ACTLR_ITCMUAEN_Pos 4U /*!< ACTLR: Instruction TCM Upper Alias Enable Position */ +#define SCnSCB_ACTLR_ITCMUAEN_Msk (1UL << SCnSCB_ACTLR_ITCMUAEN_Pos) /*!< ACTLR: Instruction TCM Upper Alias Enable Mask */ + +#define SCnSCB_ACTLR_ITCMLAEN_Pos 3U /*!< ACTLR: Instruction TCM Lower Alias Enable Position */ +#define SCnSCB_ACTLR_ITCMLAEN_Msk (1UL << SCnSCB_ACTLR_ITCMLAEN_Pos) /*!< ACTLR: Instruction TCM Lower Alias Enable Mask */ + +/*@} end of group CMSIS_SCnotSCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Cortex-M1 Core Debug Registers (DCB registers, SHCSR, and DFSR) are only accessible over DAP and not via processor. + Therefore they are not covered by the Cortex-M1 header file. + @{ + */ +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param[in] field Name of the register bit field. + \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param[in] field Name of the register bit field. + \param[in] value Value of register. This parameter is interpreted as an uint32_t type. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) + +/*@} end of group CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Core Hardware */ +#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ +#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ +#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ +#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + +#define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ +#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ +#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ +#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ + + +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping + #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping + #define NVIC_EnableIRQ __NVIC_EnableIRQ + #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ + #define NVIC_DisableIRQ __NVIC_DisableIRQ + #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ + #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ + #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ +/*#define NVIC_GetActive __NVIC_GetActive not available for Cortex-M1 */ + #define NVIC_SetPriority __NVIC_SetPriority + #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset +#endif /* CMSIS_NVIC_VIRTUAL */ + +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetVector __NVIC_SetVector + #define NVIC_GetVector __NVIC_GetVector +#endif /* (CMSIS_VECTAB_VIRTUAL) */ + +#define NVIC_USER_IRQ_OFFSET 16 + + +/* The following EXC_RETURN values are saved the LR on exception entry */ +#define EXC_RETURN_HANDLER (0xFFFFFFF1UL) /* return to Handler mode, uses MSP after return */ +#define EXC_RETURN_THREAD_MSP (0xFFFFFFF9UL) /* return to Thread mode, uses MSP after return */ +#define EXC_RETURN_THREAD_PSP (0xFFFFFFFDUL) /* return to Thread mode, uses PSP after return */ + + +/* Interrupt Priorities are WORD accessible only under Armv6-M */ +/* The following MACROS handle generation of the register offset and byte masks */ +#define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL) +#define _SHP_IDX(IRQn) ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >> 2UL) ) +#define _IP_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 2UL) ) + +#define __NVIC_SetPriorityGrouping(X) (void)(X) +#define __NVIC_GetPriorityGrouping() (0U) + +/** + \brief Enable Interrupt + \details Enables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISER[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Interrupt Enable status + \details Returns a device specific interrupt enable status from the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISER[0U] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt + \details Disables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICER[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __DSB(); + __ISB(); + } +} + + +/** + \brief Get Pending Interrupt + \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISPR[0U] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISPR[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICPR[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Set Interrupt Priority + \details Sets the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every processor exception. + */ +__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->IP[_IP_IDX(IRQn)] = ((uint32_t)(NVIC->IP[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } + else + { + SCB->SHP[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief Encode Priority + \details Encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + return ( + ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | + ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) + ); +} + + +/** + \brief Decode Priority + \details Decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. + \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); + *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); +} + + + +/** + \brief Set Interrupt Vector + \details Sets an interrupt vector in SRAM based interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + Address 0 must be mapped to SRAM. + \param [in] IRQn Interrupt number + \param [in] vector Address of interrupt handler function + */ +__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) +{ + uint32_t *vectors = (uint32_t *)0x0U; + vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; +} + + +/** + \brief Get Interrupt Vector + \details Reads an interrupt vector from interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Address of interrupt handler function + */ +__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) +{ + uint32_t *vectors = (uint32_t *)0x0U; + return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET]; +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + SCB_AIRCR_SYSRESETREQ_Msk); + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +/*@} end of CMSIS_Core_NVICFunctions */ + + +/* ########################## FPU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_FpuFunctions FPU Functions + \brief Function that provides FPU type. + @{ + */ + +/** + \brief get FPU type + \details returns the FPU type + \returns + - \b 0: No FPU + - \b 1: Single precision FPU + - \b 2: Double + Single precision FPU + */ +__STATIC_INLINE uint32_t SCB_GetFPUType(void) +{ + return 0U; /* No FPU */ +} + + +/*@} end of CMSIS_Core_FpuFunctions */ + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM1_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/test/STM32F072C8T6/Drivers/CMSIS/Include/core_cm23.h b/test/STM32F072C8T6/Drivers/CMSIS/Include/core_cm23.h new file mode 100644 index 0000000..8202a8d --- /dev/null +++ b/test/STM32F072C8T6/Drivers/CMSIS/Include/core_cm23.h @@ -0,0 +1,1993 @@ +/**************************************************************************//** + * @file core_cm23.h + * @brief CMSIS Cortex-M23 Core Peripheral Access Layer Header File + * @version V5.0.7 + * @date 22. June 2018 + ******************************************************************************/ +/* + * Copyright (c) 2009-2018 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * 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 + * + * 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. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CORE_CM23_H_GENERIC +#define __CORE_CM23_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup Cortex_M23 + @{ + */ + +#include "cmsis_version.h" + +/* CMSIS definitions */ +#define __CM23_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __CM23_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ +#define __CM23_CMSIS_VERSION ((__CM23_CMSIS_VERSION_MAIN << 16U) | \ + __CM23_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ + +#define __CORTEX_M (23U) /*!< Cortex-M Core */ + +/** __FPU_USED indicates whether an FPU is used or not. + This core does not support an FPU at all +*/ +#define __FPU_USED 0U + +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_PCS_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TI_ARM__ ) + #if defined __TI_VFP_SUPPORT__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM23_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM23_H_DEPENDANT +#define __CORE_CM23_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM23_REV + #define __CM23_REV 0x0000U + #warning "__CM23_REV not defined in device header file; using default!" + #endif + + #ifndef __FPU_PRESENT + #define __FPU_PRESENT 0U + #warning "__FPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0U + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __SAUREGION_PRESENT + #define __SAUREGION_PRESENT 0U + #warning "__SAUREGION_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __VTOR_PRESENT + #define __VTOR_PRESENT 0U + #warning "__VTOR_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 2U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif + + #ifndef __ETM_PRESENT + #define __ETM_PRESENT 0U + #warning "__ETM_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __MTB_PRESENT + #define __MTB_PRESENT 0U + #warning "__MTB_PRESENT not defined in device header file; using default!" + #endif + +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group Cortex_M23 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug Register + - Core MPU Register + - Core SAU Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:28; /*!< bit: 0..27 Reserved */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t _reserved1:3; /*!< bit: 25..27 Reserved */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL:1; /*!< bit: 1 Stack-pointer select */ + uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ +#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[16U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[16U]; + __IOM uint32_t ICER[16U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[16U]; + __IOM uint32_t ISPR[16U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[16U]; + __IOM uint32_t ICPR[16U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[16U]; + __IOM uint32_t IABR[16U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[16U]; + __IOM uint32_t ITNS[16U]; /*!< Offset: 0x280 (R/W) Interrupt Non-Secure State Register */ + uint32_t RESERVED5[16U]; + __IOM uint32_t IPR[124U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */ +} NVIC_Type; + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) + __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ +#else + uint32_t RESERVED0; +#endif + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + uint32_t RESERVED1; + __IOM uint32_t SHPR[2U]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_PENDNMISET_Pos 31U /*!< SCB ICSR: PENDNMISET Position */ +#define SCB_ICSR_PENDNMISET_Msk (1UL << SCB_ICSR_PENDNMISET_Pos) /*!< SCB ICSR: PENDNMISET Mask */ + +#define SCB_ICSR_NMIPENDSET_Pos SCB_ICSR_PENDNMISET_Pos /*!< SCB ICSR: NMIPENDSET Position, backward compatibility */ +#define SCB_ICSR_NMIPENDSET_Msk SCB_ICSR_PENDNMISET_Msk /*!< SCB ICSR: NMIPENDSET Mask, backward compatibility */ + +#define SCB_ICSR_PENDNMICLR_Pos 30U /*!< SCB ICSR: PENDNMICLR Position */ +#define SCB_ICSR_PENDNMICLR_Msk (1UL << SCB_ICSR_PENDNMICLR_Pos) /*!< SCB ICSR: PENDNMICLR Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_STTNS_Pos 24U /*!< SCB ICSR: STTNS Position (Security Extension) */ +#define SCB_ICSR_STTNS_Msk (1UL << SCB_ICSR_STTNS_Pos) /*!< SCB ICSR: STTNS Mask (Security Extension) */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_RETTOBASE_Pos 11U /*!< SCB ICSR: RETTOBASE Position */ +#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) +/* SCB Vector Table Offset Register Definitions */ +#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ +#endif + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_PRIS_Pos 14U /*!< SCB AIRCR: PRIS Position */ +#define SCB_AIRCR_PRIS_Msk (1UL << SCB_AIRCR_PRIS_Pos) /*!< SCB AIRCR: PRIS Mask */ + +#define SCB_AIRCR_BFHFNMINS_Pos 13U /*!< SCB AIRCR: BFHFNMINS Position */ +#define SCB_AIRCR_BFHFNMINS_Msk (1UL << SCB_AIRCR_BFHFNMINS_Pos) /*!< SCB AIRCR: BFHFNMINS Mask */ + +#define SCB_AIRCR_SYSRESETREQS_Pos 3U /*!< SCB AIRCR: SYSRESETREQS Position */ +#define SCB_AIRCR_SYSRESETREQS_Msk (1UL << SCB_AIRCR_SYSRESETREQS_Pos) /*!< SCB AIRCR: SYSRESETREQS Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEPS_Pos 3U /*!< SCB SCR: SLEEPDEEPS Position */ +#define SCB_SCR_SLEEPDEEPS_Msk (1UL << SCB_SCR_SLEEPDEEPS_Pos) /*!< SCB SCR: SLEEPDEEPS Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_BP_Pos 18U /*!< SCB CCR: BP Position */ +#define SCB_CCR_BP_Msk (1UL << SCB_CCR_BP_Pos) /*!< SCB CCR: BP Mask */ + +#define SCB_CCR_IC_Pos 17U /*!< SCB CCR: IC Position */ +#define SCB_CCR_IC_Msk (1UL << SCB_CCR_IC_Pos) /*!< SCB CCR: IC Mask */ + +#define SCB_CCR_DC_Pos 16U /*!< SCB CCR: DC Position */ +#define SCB_CCR_DC_Msk (1UL << SCB_CCR_DC_Pos) /*!< SCB CCR: DC Mask */ + +#define SCB_CCR_STKOFHFNMIGN_Pos 10U /*!< SCB CCR: STKOFHFNMIGN Position */ +#define SCB_CCR_STKOFHFNMIGN_Msk (1UL << SCB_CCR_STKOFHFNMIGN_Pos) /*!< SCB CCR: STKOFHFNMIGN Mask */ + +#define SCB_CCR_BFHFNMIGN_Pos 8U /*!< SCB CCR: BFHFNMIGN Position */ +#define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ + +#define SCB_CCR_DIV_0_TRP_Pos 4U /*!< SCB CCR: DIV_0_TRP Position */ +#define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +#define SCB_CCR_USERSETMPEND_Pos 1U /*!< SCB CCR: USERSETMPEND Position */ +#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_HARDFAULTPENDED_Pos 21U /*!< SCB SHCSR: HARDFAULTPENDED Position */ +#define SCB_SHCSR_HARDFAULTPENDED_Msk (1UL << SCB_SHCSR_HARDFAULTPENDED_Pos) /*!< SCB SHCSR: HARDFAULTPENDED Mask */ + +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +#define SCB_SHCSR_SYSTICKACT_Pos 11U /*!< SCB SHCSR: SYSTICKACT Position */ +#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ + +#define SCB_SHCSR_PENDSVACT_Pos 10U /*!< SCB SHCSR: PENDSVACT Position */ +#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ + +#define SCB_SHCSR_SVCALLACT_Pos 7U /*!< SCB SHCSR: SVCALLACT Position */ +#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ + +#define SCB_SHCSR_NMIACT_Pos 5U /*!< SCB SHCSR: NMIACT Position */ +#define SCB_SHCSR_NMIACT_Msk (1UL << SCB_SHCSR_NMIACT_Pos) /*!< SCB SHCSR: NMIACT Mask */ + +#define SCB_SHCSR_HARDFAULTACT_Pos 2U /*!< SCB SHCSR: HARDFAULTACT Position */ +#define SCB_SHCSR_HARDFAULTACT_Msk (1UL << SCB_SHCSR_HARDFAULTACT_Pos) /*!< SCB SHCSR: HARDFAULTACT Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) + \brief Type definitions for the Data Watchpoint and Trace (DWT) + @{ + */ + +/** + \brief Structure type to access the Data Watchpoint and Trace Register (DWT). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ + uint32_t RESERVED0[6U]; + __IM uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ + __IOM uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ + uint32_t RESERVED1[1U]; + __IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ + uint32_t RESERVED2[1U]; + __IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ + uint32_t RESERVED3[1U]; + __IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ + uint32_t RESERVED4[1U]; + __IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ + uint32_t RESERVED5[1U]; + __IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ + uint32_t RESERVED6[1U]; + __IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ + uint32_t RESERVED7[1U]; + __IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ + uint32_t RESERVED8[1U]; + __IOM uint32_t COMP4; /*!< Offset: 0x060 (R/W) Comparator Register 4 */ + uint32_t RESERVED9[1U]; + __IOM uint32_t FUNCTION4; /*!< Offset: 0x068 (R/W) Function Register 4 */ + uint32_t RESERVED10[1U]; + __IOM uint32_t COMP5; /*!< Offset: 0x070 (R/W) Comparator Register 5 */ + uint32_t RESERVED11[1U]; + __IOM uint32_t FUNCTION5; /*!< Offset: 0x078 (R/W) Function Register 5 */ + uint32_t RESERVED12[1U]; + __IOM uint32_t COMP6; /*!< Offset: 0x080 (R/W) Comparator Register 6 */ + uint32_t RESERVED13[1U]; + __IOM uint32_t FUNCTION6; /*!< Offset: 0x088 (R/W) Function Register 6 */ + uint32_t RESERVED14[1U]; + __IOM uint32_t COMP7; /*!< Offset: 0x090 (R/W) Comparator Register 7 */ + uint32_t RESERVED15[1U]; + __IOM uint32_t FUNCTION7; /*!< Offset: 0x098 (R/W) Function Register 7 */ + uint32_t RESERVED16[1U]; + __IOM uint32_t COMP8; /*!< Offset: 0x0A0 (R/W) Comparator Register 8 */ + uint32_t RESERVED17[1U]; + __IOM uint32_t FUNCTION8; /*!< Offset: 0x0A8 (R/W) Function Register 8 */ + uint32_t RESERVED18[1U]; + __IOM uint32_t COMP9; /*!< Offset: 0x0B0 (R/W) Comparator Register 9 */ + uint32_t RESERVED19[1U]; + __IOM uint32_t FUNCTION9; /*!< Offset: 0x0B8 (R/W) Function Register 9 */ + uint32_t RESERVED20[1U]; + __IOM uint32_t COMP10; /*!< Offset: 0x0C0 (R/W) Comparator Register 10 */ + uint32_t RESERVED21[1U]; + __IOM uint32_t FUNCTION10; /*!< Offset: 0x0C8 (R/W) Function Register 10 */ + uint32_t RESERVED22[1U]; + __IOM uint32_t COMP11; /*!< Offset: 0x0D0 (R/W) Comparator Register 11 */ + uint32_t RESERVED23[1U]; + __IOM uint32_t FUNCTION11; /*!< Offset: 0x0D8 (R/W) Function Register 11 */ + uint32_t RESERVED24[1U]; + __IOM uint32_t COMP12; /*!< Offset: 0x0E0 (R/W) Comparator Register 12 */ + uint32_t RESERVED25[1U]; + __IOM uint32_t FUNCTION12; /*!< Offset: 0x0E8 (R/W) Function Register 12 */ + uint32_t RESERVED26[1U]; + __IOM uint32_t COMP13; /*!< Offset: 0x0F0 (R/W) Comparator Register 13 */ + uint32_t RESERVED27[1U]; + __IOM uint32_t FUNCTION13; /*!< Offset: 0x0F8 (R/W) Function Register 13 */ + uint32_t RESERVED28[1U]; + __IOM uint32_t COMP14; /*!< Offset: 0x100 (R/W) Comparator Register 14 */ + uint32_t RESERVED29[1U]; + __IOM uint32_t FUNCTION14; /*!< Offset: 0x108 (R/W) Function Register 14 */ + uint32_t RESERVED30[1U]; + __IOM uint32_t COMP15; /*!< Offset: 0x110 (R/W) Comparator Register 15 */ + uint32_t RESERVED31[1U]; + __IOM uint32_t FUNCTION15; /*!< Offset: 0x118 (R/W) Function Register 15 */ +} DWT_Type; + +/* DWT Control Register Definitions */ +#define DWT_CTRL_NUMCOMP_Pos 28U /*!< DWT CTRL: NUMCOMP Position */ +#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ + +#define DWT_CTRL_NOTRCPKT_Pos 27U /*!< DWT CTRL: NOTRCPKT Position */ +#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ + +#define DWT_CTRL_NOEXTTRIG_Pos 26U /*!< DWT CTRL: NOEXTTRIG Position */ +#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ + +#define DWT_CTRL_NOCYCCNT_Pos 25U /*!< DWT CTRL: NOCYCCNT Position */ +#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ + +#define DWT_CTRL_NOPRFCNT_Pos 24U /*!< DWT CTRL: NOPRFCNT Position */ +#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ + +/* DWT Comparator Function Register Definitions */ +#define DWT_FUNCTION_ID_Pos 27U /*!< DWT FUNCTION: ID Position */ +#define DWT_FUNCTION_ID_Msk (0x1FUL << DWT_FUNCTION_ID_Pos) /*!< DWT FUNCTION: ID Mask */ + +#define DWT_FUNCTION_MATCHED_Pos 24U /*!< DWT FUNCTION: MATCHED Position */ +#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ + +#define DWT_FUNCTION_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */ +#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ + +#define DWT_FUNCTION_ACTION_Pos 4U /*!< DWT FUNCTION: ACTION Position */ +#define DWT_FUNCTION_ACTION_Msk (0x3UL << DWT_FUNCTION_ACTION_Pos) /*!< DWT FUNCTION: ACTION Mask */ + +#define DWT_FUNCTION_MATCH_Pos 0U /*!< DWT FUNCTION: MATCH Position */ +#define DWT_FUNCTION_MATCH_Msk (0xFUL /*<< DWT_FUNCTION_MATCH_Pos*/) /*!< DWT FUNCTION: MATCH Mask */ + +/*@}*/ /* end of group CMSIS_DWT */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_TPI Trace Port Interface (TPI) + \brief Type definitions for the Trace Port Interface (TPI) + @{ + */ + +/** + \brief Structure type to access the Trace Port Interface Register (TPI). + */ +typedef struct +{ + __IM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ + __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ + uint32_t RESERVED0[2U]; + __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ + uint32_t RESERVED1[55U]; + __IOM uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ + uint32_t RESERVED2[131U]; + __IM uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ + __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ + __IOM uint32_t PSCR; /*!< Offset: 0x308 (R/W) Periodic Synchronization Control Register */ + uint32_t RESERVED3[759U]; + __IM uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER Register */ + __IM uint32_t ITFTTD0; /*!< Offset: 0xEEC (R/ ) Integration Test FIFO Test Data 0 Register */ + __IOM uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/W) Integration Test ATB Control Register 2 */ + uint32_t RESERVED4[1U]; + __IM uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) Integration Test ATB Control Register 0 */ + __IM uint32_t ITFTTD1; /*!< Offset: 0xEFC (R/ ) Integration Test FIFO Test Data 1 Register */ + __IOM uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */ + uint32_t RESERVED5[39U]; + __IOM uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */ + __IOM uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */ + uint32_t RESERVED7[8U]; + __IM uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) Device Configuration Register */ + __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) Device Type Identifier Register */ +} TPI_Type; + +/* TPI Asynchronous Clock Prescaler Register Definitions */ +#define TPI_ACPR_PRESCALER_Pos 0U /*!< TPI ACPR: PRESCALER Position */ +#define TPI_ACPR_PRESCALER_Msk (0x1FFFUL /*<< TPI_ACPR_PRESCALER_Pos*/) /*!< TPI ACPR: PRESCALER Mask */ + +/* TPI Selected Pin Protocol Register Definitions */ +#define TPI_SPPR_TXMODE_Pos 0U /*!< TPI SPPR: TXMODE Position */ +#define TPI_SPPR_TXMODE_Msk (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/) /*!< TPI SPPR: TXMODE Mask */ + +/* TPI Formatter and Flush Status Register Definitions */ +#define TPI_FFSR_FtNonStop_Pos 3U /*!< TPI FFSR: FtNonStop Position */ +#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ + +#define TPI_FFSR_TCPresent_Pos 2U /*!< TPI FFSR: TCPresent Position */ +#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ + +#define TPI_FFSR_FtStopped_Pos 1U /*!< TPI FFSR: FtStopped Position */ +#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ + +#define TPI_FFSR_FlInProg_Pos 0U /*!< TPI FFSR: FlInProg Position */ +#define TPI_FFSR_FlInProg_Msk (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/) /*!< TPI FFSR: FlInProg Mask */ + +/* TPI Formatter and Flush Control Register Definitions */ +#define TPI_FFCR_TrigIn_Pos 8U /*!< TPI FFCR: TrigIn Position */ +#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ + +#define TPI_FFCR_FOnMan_Pos 6U /*!< TPI FFCR: FOnMan Position */ +#define TPI_FFCR_FOnMan_Msk (0x1UL << TPI_FFCR_FOnMan_Pos) /*!< TPI FFCR: FOnMan Mask */ + +#define TPI_FFCR_EnFCont_Pos 1U /*!< TPI FFCR: EnFCont Position */ +#define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ + +/* TPI TRIGGER Register Definitions */ +#define TPI_TRIGGER_TRIGGER_Pos 0U /*!< TPI TRIGGER: TRIGGER Position */ +#define TPI_TRIGGER_TRIGGER_Msk (0x1UL /*<< TPI_TRIGGER_TRIGGER_Pos*/) /*!< TPI TRIGGER: TRIGGER Mask */ + +/* TPI Integration Test FIFO Test Data 0 Register Definitions */ +#define TPI_ITFTTD0_ATB_IF2_ATVALID_Pos 29U /*!< TPI ITFTTD0: ATB Interface 2 ATVALIDPosition */ +#define TPI_ITFTTD0_ATB_IF2_ATVALID_Msk (0x3UL << TPI_ITFTTD0_ATB_IF2_ATVALID_Pos) /*!< TPI ITFTTD0: ATB Interface 2 ATVALID Mask */ + +#define TPI_ITFTTD0_ATB_IF2_bytecount_Pos 27U /*!< TPI ITFTTD0: ATB Interface 2 byte count Position */ +#define TPI_ITFTTD0_ATB_IF2_bytecount_Msk (0x3UL << TPI_ITFTTD0_ATB_IF2_bytecount_Pos) /*!< TPI ITFTTD0: ATB Interface 2 byte count Mask */ + +#define TPI_ITFTTD0_ATB_IF1_ATVALID_Pos 26U /*!< TPI ITFTTD0: ATB Interface 1 ATVALID Position */ +#define TPI_ITFTTD0_ATB_IF1_ATVALID_Msk (0x3UL << TPI_ITFTTD0_ATB_IF1_ATVALID_Pos) /*!< TPI ITFTTD0: ATB Interface 1 ATVALID Mask */ + +#define TPI_ITFTTD0_ATB_IF1_bytecount_Pos 24U /*!< TPI ITFTTD0: ATB Interface 1 byte count Position */ +#define TPI_ITFTTD0_ATB_IF1_bytecount_Msk (0x3UL << TPI_ITFTTD0_ATB_IF1_bytecount_Pos) /*!< TPI ITFTTD0: ATB Interface 1 byte countt Mask */ + +#define TPI_ITFTTD0_ATB_IF1_data2_Pos 16U /*!< TPI ITFTTD0: ATB Interface 1 data2 Position */ +#define TPI_ITFTTD0_ATB_IF1_data2_Msk (0xFFUL << TPI_ITFTTD0_ATB_IF1_data1_Pos) /*!< TPI ITFTTD0: ATB Interface 1 data2 Mask */ + +#define TPI_ITFTTD0_ATB_IF1_data1_Pos 8U /*!< TPI ITFTTD0: ATB Interface 1 data1 Position */ +#define TPI_ITFTTD0_ATB_IF1_data1_Msk (0xFFUL << TPI_ITFTTD0_ATB_IF1_data1_Pos) /*!< TPI ITFTTD0: ATB Interface 1 data1 Mask */ + +#define TPI_ITFTTD0_ATB_IF1_data0_Pos 0U /*!< TPI ITFTTD0: ATB Interface 1 data0 Position */ +#define TPI_ITFTTD0_ATB_IF1_data0_Msk (0xFFUL /*<< TPI_ITFTTD0_ATB_IF1_data0_Pos*/) /*!< TPI ITFTTD0: ATB Interface 1 data0 Mask */ + +/* TPI Integration Test ATB Control Register 2 Register Definitions */ +#define TPI_ITATBCTR2_AFVALID2S_Pos 1U /*!< TPI ITATBCTR2: AFVALID2S Position */ +#define TPI_ITATBCTR2_AFVALID2S_Msk (0x1UL << TPI_ITATBCTR2_AFVALID2S_Pos) /*!< TPI ITATBCTR2: AFVALID2SS Mask */ + +#define TPI_ITATBCTR2_AFVALID1S_Pos 1U /*!< TPI ITATBCTR2: AFVALID1S Position */ +#define TPI_ITATBCTR2_AFVALID1S_Msk (0x1UL << TPI_ITATBCTR2_AFVALID1S_Pos) /*!< TPI ITATBCTR2: AFVALID1SS Mask */ + +#define TPI_ITATBCTR2_ATREADY2S_Pos 0U /*!< TPI ITATBCTR2: ATREADY2S Position */ +#define TPI_ITATBCTR2_ATREADY2S_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY2S_Pos*/) /*!< TPI ITATBCTR2: ATREADY2S Mask */ + +#define TPI_ITATBCTR2_ATREADY1S_Pos 0U /*!< TPI ITATBCTR2: ATREADY1S Position */ +#define TPI_ITATBCTR2_ATREADY1S_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY1S_Pos*/) /*!< TPI ITATBCTR2: ATREADY1S Mask */ + +/* TPI Integration Test FIFO Test Data 1 Register Definitions */ +#define TPI_ITFTTD1_ATB_IF2_ATVALID_Pos 29U /*!< TPI ITFTTD1: ATB Interface 2 ATVALID Position */ +#define TPI_ITFTTD1_ATB_IF2_ATVALID_Msk (0x3UL << TPI_ITFTTD1_ATB_IF2_ATVALID_Pos) /*!< TPI ITFTTD1: ATB Interface 2 ATVALID Mask */ + +#define TPI_ITFTTD1_ATB_IF2_bytecount_Pos 27U /*!< TPI ITFTTD1: ATB Interface 2 byte count Position */ +#define TPI_ITFTTD1_ATB_IF2_bytecount_Msk (0x3UL << TPI_ITFTTD1_ATB_IF2_bytecount_Pos) /*!< TPI ITFTTD1: ATB Interface 2 byte count Mask */ + +#define TPI_ITFTTD1_ATB_IF1_ATVALID_Pos 26U /*!< TPI ITFTTD1: ATB Interface 1 ATVALID Position */ +#define TPI_ITFTTD1_ATB_IF1_ATVALID_Msk (0x3UL << TPI_ITFTTD1_ATB_IF1_ATVALID_Pos) /*!< TPI ITFTTD1: ATB Interface 1 ATVALID Mask */ + +#define TPI_ITFTTD1_ATB_IF1_bytecount_Pos 24U /*!< TPI ITFTTD1: ATB Interface 1 byte count Position */ +#define TPI_ITFTTD1_ATB_IF1_bytecount_Msk (0x3UL << TPI_ITFTTD1_ATB_IF1_bytecount_Pos) /*!< TPI ITFTTD1: ATB Interface 1 byte countt Mask */ + +#define TPI_ITFTTD1_ATB_IF2_data2_Pos 16U /*!< TPI ITFTTD1: ATB Interface 2 data2 Position */ +#define TPI_ITFTTD1_ATB_IF2_data2_Msk (0xFFUL << TPI_ITFTTD1_ATB_IF2_data1_Pos) /*!< TPI ITFTTD1: ATB Interface 2 data2 Mask */ + +#define TPI_ITFTTD1_ATB_IF2_data1_Pos 8U /*!< TPI ITFTTD1: ATB Interface 2 data1 Position */ +#define TPI_ITFTTD1_ATB_IF2_data1_Msk (0xFFUL << TPI_ITFTTD1_ATB_IF2_data1_Pos) /*!< TPI ITFTTD1: ATB Interface 2 data1 Mask */ + +#define TPI_ITFTTD1_ATB_IF2_data0_Pos 0U /*!< TPI ITFTTD1: ATB Interface 2 data0 Position */ +#define TPI_ITFTTD1_ATB_IF2_data0_Msk (0xFFUL /*<< TPI_ITFTTD1_ATB_IF2_data0_Pos*/) /*!< TPI ITFTTD1: ATB Interface 2 data0 Mask */ + +/* TPI Integration Test ATB Control Register 0 Definitions */ +#define TPI_ITATBCTR0_AFVALID2S_Pos 1U /*!< TPI ITATBCTR0: AFVALID2S Position */ +#define TPI_ITATBCTR0_AFVALID2S_Msk (0x1UL << TPI_ITATBCTR0_AFVALID2S_Pos) /*!< TPI ITATBCTR0: AFVALID2SS Mask */ + +#define TPI_ITATBCTR0_AFVALID1S_Pos 1U /*!< TPI ITATBCTR0: AFVALID1S Position */ +#define TPI_ITATBCTR0_AFVALID1S_Msk (0x1UL << TPI_ITATBCTR0_AFVALID1S_Pos) /*!< TPI ITATBCTR0: AFVALID1SS Mask */ + +#define TPI_ITATBCTR0_ATREADY2S_Pos 0U /*!< TPI ITATBCTR0: ATREADY2S Position */ +#define TPI_ITATBCTR0_ATREADY2S_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY2S_Pos*/) /*!< TPI ITATBCTR0: ATREADY2S Mask */ + +#define TPI_ITATBCTR0_ATREADY1S_Pos 0U /*!< TPI ITATBCTR0: ATREADY1S Position */ +#define TPI_ITATBCTR0_ATREADY1S_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY1S_Pos*/) /*!< TPI ITATBCTR0: ATREADY1S Mask */ + +/* TPI Integration Mode Control Register Definitions */ +#define TPI_ITCTRL_Mode_Pos 0U /*!< TPI ITCTRL: Mode Position */ +#define TPI_ITCTRL_Mode_Msk (0x3UL /*<< TPI_ITCTRL_Mode_Pos*/) /*!< TPI ITCTRL: Mode Mask */ + +/* TPI DEVID Register Definitions */ +#define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */ +#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ + +#define TPI_DEVID_MANCVALID_Pos 10U /*!< TPI DEVID: MANCVALID Position */ +#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ + +#define TPI_DEVID_PTINVALID_Pos 9U /*!< TPI DEVID: PTINVALID Position */ +#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ + +#define TPI_DEVID_FIFOSZ_Pos 6U /*!< TPI DEVID: FIFOSZ Position */ +#define TPI_DEVID_FIFOSZ_Msk (0x7UL << TPI_DEVID_FIFOSZ_Pos) /*!< TPI DEVID: FIFOSZ Mask */ + +#define TPI_DEVID_NrTraceInput_Pos 0U /*!< TPI DEVID: NrTraceInput Position */ +#define TPI_DEVID_NrTraceInput_Msk (0x3FUL /*<< TPI_DEVID_NrTraceInput_Pos*/) /*!< TPI DEVID: NrTraceInput Mask */ + +/* TPI DEVTYPE Register Definitions */ +#define TPI_DEVTYPE_SubType_Pos 4U /*!< TPI DEVTYPE: SubType Position */ +#define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ + +#define TPI_DEVTYPE_MajorType_Pos 0U /*!< TPI DEVTYPE: MajorType Position */ +#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ + +/*@}*/ /* end of group CMSIS_TPI */ + + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** + \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region Number Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) MPU Region Limit Address Register */ + uint32_t RESERVED0[7U]; + union { + __IOM uint32_t MAIR[2]; + struct { + __IOM uint32_t MAIR0; /*!< Offset: 0x030 (R/W) MPU Memory Attribute Indirection Register 0 */ + __IOM uint32_t MAIR1; /*!< Offset: 0x034 (R/W) MPU Memory Attribute Indirection Register 1 */ + }; + }; +} MPU_Type; + +#define MPU_TYPE_RALIASES 1U + +/* MPU Type Register Definitions */ +#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register Definitions */ +#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register Definitions */ +#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register Definitions */ +#define MPU_RBAR_BASE_Pos 5U /*!< MPU RBAR: BASE Position */ +#define MPU_RBAR_BASE_Msk (0x7FFFFFFUL << MPU_RBAR_BASE_Pos) /*!< MPU RBAR: BASE Mask */ + +#define MPU_RBAR_SH_Pos 3U /*!< MPU RBAR: SH Position */ +#define MPU_RBAR_SH_Msk (0x3UL << MPU_RBAR_SH_Pos) /*!< MPU RBAR: SH Mask */ + +#define MPU_RBAR_AP_Pos 1U /*!< MPU RBAR: AP Position */ +#define MPU_RBAR_AP_Msk (0x3UL << MPU_RBAR_AP_Pos) /*!< MPU RBAR: AP Mask */ + +#define MPU_RBAR_XN_Pos 0U /*!< MPU RBAR: XN Position */ +#define MPU_RBAR_XN_Msk (01UL /*<< MPU_RBAR_XN_Pos*/) /*!< MPU RBAR: XN Mask */ + +/* MPU Region Limit Address Register Definitions */ +#define MPU_RLAR_LIMIT_Pos 5U /*!< MPU RLAR: LIMIT Position */ +#define MPU_RLAR_LIMIT_Msk (0x7FFFFFFUL << MPU_RLAR_LIMIT_Pos) /*!< MPU RLAR: LIMIT Mask */ + +#define MPU_RLAR_AttrIndx_Pos 1U /*!< MPU RLAR: AttrIndx Position */ +#define MPU_RLAR_AttrIndx_Msk (0x7UL << MPU_RLAR_AttrIndx_Pos) /*!< MPU RLAR: AttrIndx Mask */ + +#define MPU_RLAR_EN_Pos 0U /*!< MPU RLAR: EN Position */ +#define MPU_RLAR_EN_Msk (1UL /*<< MPU_RLAR_EN_Pos*/) /*!< MPU RLAR: EN Mask */ + +/* MPU Memory Attribute Indirection Register 0 Definitions */ +#define MPU_MAIR0_Attr3_Pos 24U /*!< MPU MAIR0: Attr3 Position */ +#define MPU_MAIR0_Attr3_Msk (0xFFUL << MPU_MAIR0_Attr3_Pos) /*!< MPU MAIR0: Attr3 Mask */ + +#define MPU_MAIR0_Attr2_Pos 16U /*!< MPU MAIR0: Attr2 Position */ +#define MPU_MAIR0_Attr2_Msk (0xFFUL << MPU_MAIR0_Attr2_Pos) /*!< MPU MAIR0: Attr2 Mask */ + +#define MPU_MAIR0_Attr1_Pos 8U /*!< MPU MAIR0: Attr1 Position */ +#define MPU_MAIR0_Attr1_Msk (0xFFUL << MPU_MAIR0_Attr1_Pos) /*!< MPU MAIR0: Attr1 Mask */ + +#define MPU_MAIR0_Attr0_Pos 0U /*!< MPU MAIR0: Attr0 Position */ +#define MPU_MAIR0_Attr0_Msk (0xFFUL /*<< MPU_MAIR0_Attr0_Pos*/) /*!< MPU MAIR0: Attr0 Mask */ + +/* MPU Memory Attribute Indirection Register 1 Definitions */ +#define MPU_MAIR1_Attr7_Pos 24U /*!< MPU MAIR1: Attr7 Position */ +#define MPU_MAIR1_Attr7_Msk (0xFFUL << MPU_MAIR1_Attr7_Pos) /*!< MPU MAIR1: Attr7 Mask */ + +#define MPU_MAIR1_Attr6_Pos 16U /*!< MPU MAIR1: Attr6 Position */ +#define MPU_MAIR1_Attr6_Msk (0xFFUL << MPU_MAIR1_Attr6_Pos) /*!< MPU MAIR1: Attr6 Mask */ + +#define MPU_MAIR1_Attr5_Pos 8U /*!< MPU MAIR1: Attr5 Position */ +#define MPU_MAIR1_Attr5_Msk (0xFFUL << MPU_MAIR1_Attr5_Pos) /*!< MPU MAIR1: Attr5 Mask */ + +#define MPU_MAIR1_Attr4_Pos 0U /*!< MPU MAIR1: Attr4 Position */ +#define MPU_MAIR1_Attr4_Msk (0xFFUL /*<< MPU_MAIR1_Attr4_Pos*/) /*!< MPU MAIR1: Attr4 Mask */ + +/*@} end of group CMSIS_MPU */ +#endif + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SAU Security Attribution Unit (SAU) + \brief Type definitions for the Security Attribution Unit (SAU) + @{ + */ + +/** + \brief Structure type to access the Security Attribution Unit (SAU). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SAU Control Register */ + __IM uint32_t TYPE; /*!< Offset: 0x004 (R/ ) SAU Type Register */ +#if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) SAU Region Number Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) SAU Region Base Address Register */ + __IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) SAU Region Limit Address Register */ +#endif +} SAU_Type; + +/* SAU Control Register Definitions */ +#define SAU_CTRL_ALLNS_Pos 1U /*!< SAU CTRL: ALLNS Position */ +#define SAU_CTRL_ALLNS_Msk (1UL << SAU_CTRL_ALLNS_Pos) /*!< SAU CTRL: ALLNS Mask */ + +#define SAU_CTRL_ENABLE_Pos 0U /*!< SAU CTRL: ENABLE Position */ +#define SAU_CTRL_ENABLE_Msk (1UL /*<< SAU_CTRL_ENABLE_Pos*/) /*!< SAU CTRL: ENABLE Mask */ + +/* SAU Type Register Definitions */ +#define SAU_TYPE_SREGION_Pos 0U /*!< SAU TYPE: SREGION Position */ +#define SAU_TYPE_SREGION_Msk (0xFFUL /*<< SAU_TYPE_SREGION_Pos*/) /*!< SAU TYPE: SREGION Mask */ + +#if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) +/* SAU Region Number Register Definitions */ +#define SAU_RNR_REGION_Pos 0U /*!< SAU RNR: REGION Position */ +#define SAU_RNR_REGION_Msk (0xFFUL /*<< SAU_RNR_REGION_Pos*/) /*!< SAU RNR: REGION Mask */ + +/* SAU Region Base Address Register Definitions */ +#define SAU_RBAR_BADDR_Pos 5U /*!< SAU RBAR: BADDR Position */ +#define SAU_RBAR_BADDR_Msk (0x7FFFFFFUL << SAU_RBAR_BADDR_Pos) /*!< SAU RBAR: BADDR Mask */ + +/* SAU Region Limit Address Register Definitions */ +#define SAU_RLAR_LADDR_Pos 5U /*!< SAU RLAR: LADDR Position */ +#define SAU_RLAR_LADDR_Msk (0x7FFFFFFUL << SAU_RLAR_LADDR_Pos) /*!< SAU RLAR: LADDR Mask */ + +#define SAU_RLAR_NSC_Pos 1U /*!< SAU RLAR: NSC Position */ +#define SAU_RLAR_NSC_Msk (1UL << SAU_RLAR_NSC_Pos) /*!< SAU RLAR: NSC Mask */ + +#define SAU_RLAR_ENABLE_Pos 0U /*!< SAU RLAR: ENABLE Position */ +#define SAU_RLAR_ENABLE_Msk (1UL /*<< SAU_RLAR_ENABLE_Pos*/) /*!< SAU RLAR: ENABLE Mask */ + +#endif /* defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) */ + +/*@} end of group CMSIS_SAU */ +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Type definitions for the Core Debug Registers + @{ + */ + +/** + \brief Structure type to access the Core Debug Register (CoreDebug). + */ +typedef struct +{ + __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ + uint32_t RESERVED4[1U]; + __IOM uint32_t DAUTHCTRL; /*!< Offset: 0x014 (R/W) Debug Authentication Control Register */ + __IOM uint32_t DSCSR; /*!< Offset: 0x018 (R/W) Debug Security Control and Status Register */ +} CoreDebug_Type; + +/* Debug Halting Control and Status Register Definitions */ +#define CoreDebug_DHCSR_DBGKEY_Pos 16U /*!< CoreDebug DHCSR: DBGKEY Position */ +#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */ + +#define CoreDebug_DHCSR_S_RESTART_ST_Pos 26U /*!< CoreDebug DHCSR: S_RESTART_ST Position */ +#define CoreDebug_DHCSR_S_RESTART_ST_Msk (1UL << CoreDebug_DHCSR_S_RESTART_ST_Pos) /*!< CoreDebug DHCSR: S_RESTART_ST Mask */ + +#define CoreDebug_DHCSR_S_RESET_ST_Pos 25U /*!< CoreDebug DHCSR: S_RESET_ST Position */ +#define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< CoreDebug DHCSR: S_RESET_ST Mask */ + +#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24U /*!< CoreDebug DHCSR: S_RETIRE_ST Position */ +#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */ + +#define CoreDebug_DHCSR_S_LOCKUP_Pos 19U /*!< CoreDebug DHCSR: S_LOCKUP Position */ +#define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< CoreDebug DHCSR: S_LOCKUP Mask */ + +#define CoreDebug_DHCSR_S_SLEEP_Pos 18U /*!< CoreDebug DHCSR: S_SLEEP Position */ +#define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< CoreDebug DHCSR: S_SLEEP Mask */ + +#define CoreDebug_DHCSR_S_HALT_Pos 17U /*!< CoreDebug DHCSR: S_HALT Position */ +#define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< CoreDebug DHCSR: S_HALT Mask */ + +#define CoreDebug_DHCSR_S_REGRDY_Pos 16U /*!< CoreDebug DHCSR: S_REGRDY Position */ +#define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< CoreDebug DHCSR: S_REGRDY Mask */ + +#define CoreDebug_DHCSR_C_MASKINTS_Pos 3U /*!< CoreDebug DHCSR: C_MASKINTS Position */ +#define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< CoreDebug DHCSR: C_MASKINTS Mask */ + +#define CoreDebug_DHCSR_C_STEP_Pos 2U /*!< CoreDebug DHCSR: C_STEP Position */ +#define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< CoreDebug DHCSR: C_STEP Mask */ + +#define CoreDebug_DHCSR_C_HALT_Pos 1U /*!< CoreDebug DHCSR: C_HALT Position */ +#define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< CoreDebug DHCSR: C_HALT Mask */ + +#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0U /*!< CoreDebug DHCSR: C_DEBUGEN Position */ +#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */ + +/* Debug Core Register Selector Register Definitions */ +#define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< CoreDebug DCRSR: REGWnR Position */ +#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ + +#define CoreDebug_DCRSR_REGSEL_Pos 0U /*!< CoreDebug DCRSR: REGSEL Position */ +#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/) /*!< CoreDebug DCRSR: REGSEL Mask */ + +/* Debug Exception and Monitor Control Register */ +#define CoreDebug_DEMCR_DWTENA_Pos 24U /*!< CoreDebug DEMCR: DWTENA Position */ +#define CoreDebug_DEMCR_DWTENA_Msk (1UL << CoreDebug_DEMCR_DWTENA_Pos) /*!< CoreDebug DEMCR: DWTENA Mask */ + +#define CoreDebug_DEMCR_VC_HARDERR_Pos 10U /*!< CoreDebug DEMCR: VC_HARDERR Position */ +#define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< CoreDebug DEMCR: VC_HARDERR Mask */ + +#define CoreDebug_DEMCR_VC_CORERESET_Pos 0U /*!< CoreDebug DEMCR: VC_CORERESET Position */ +#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/) /*!< CoreDebug DEMCR: VC_CORERESET Mask */ + +/* Debug Authentication Control Register Definitions */ +#define CoreDebug_DAUTHCTRL_INTSPNIDEN_Pos 3U /*!< CoreDebug DAUTHCTRL: INTSPNIDEN, Position */ +#define CoreDebug_DAUTHCTRL_INTSPNIDEN_Msk (1UL << CoreDebug_DAUTHCTRL_INTSPNIDEN_Pos) /*!< CoreDebug DAUTHCTRL: INTSPNIDEN, Mask */ + +#define CoreDebug_DAUTHCTRL_SPNIDENSEL_Pos 2U /*!< CoreDebug DAUTHCTRL: SPNIDENSEL Position */ +#define CoreDebug_DAUTHCTRL_SPNIDENSEL_Msk (1UL << CoreDebug_DAUTHCTRL_SPNIDENSEL_Pos) /*!< CoreDebug DAUTHCTRL: SPNIDENSEL Mask */ + +#define CoreDebug_DAUTHCTRL_INTSPIDEN_Pos 1U /*!< CoreDebug DAUTHCTRL: INTSPIDEN Position */ +#define CoreDebug_DAUTHCTRL_INTSPIDEN_Msk (1UL << CoreDebug_DAUTHCTRL_INTSPIDEN_Pos) /*!< CoreDebug DAUTHCTRL: INTSPIDEN Mask */ + +#define CoreDebug_DAUTHCTRL_SPIDENSEL_Pos 0U /*!< CoreDebug DAUTHCTRL: SPIDENSEL Position */ +#define CoreDebug_DAUTHCTRL_SPIDENSEL_Msk (1UL /*<< CoreDebug_DAUTHCTRL_SPIDENSEL_Pos*/) /*!< CoreDebug DAUTHCTRL: SPIDENSEL Mask */ + +/* Debug Security Control and Status Register Definitions */ +#define CoreDebug_DSCSR_CDS_Pos 16U /*!< CoreDebug DSCSR: CDS Position */ +#define CoreDebug_DSCSR_CDS_Msk (1UL << CoreDebug_DSCSR_CDS_Pos) /*!< CoreDebug DSCSR: CDS Mask */ + +#define CoreDebug_DSCSR_SBRSEL_Pos 1U /*!< CoreDebug DSCSR: SBRSEL Position */ +#define CoreDebug_DSCSR_SBRSEL_Msk (1UL << CoreDebug_DSCSR_SBRSEL_Pos) /*!< CoreDebug DSCSR: SBRSEL Mask */ + +#define CoreDebug_DSCSR_SBRSELEN_Pos 0U /*!< CoreDebug DSCSR: SBRSELEN Position */ +#define CoreDebug_DSCSR_SBRSELEN_Msk (1UL /*<< CoreDebug_DSCSR_SBRSELEN_Pos*/) /*!< CoreDebug DSCSR: SBRSELEN Mask */ + +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param[in] field Name of the register bit field. + \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param[in] field Name of the register bit field. + \param[in] value Value of register. This parameter is interpreted as an uint32_t type. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) + +/*@} end of group CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Core Hardware */ + #define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ + #define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ + #define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ + #define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */ + #define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ + #define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ + #define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + + + #define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ + #define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ + #define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ + #define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ + #define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ + #define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE ) /*!< Core Debug configuration struct */ + + #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ + #endif + + #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + #define SAU_BASE (SCS_BASE + 0x0DD0UL) /*!< Security Attribution Unit */ + #define SAU ((SAU_Type *) SAU_BASE ) /*!< Security Attribution Unit */ + #endif + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + #define SCS_BASE_NS (0xE002E000UL) /*!< System Control Space Base Address (non-secure address space) */ + #define CoreDebug_BASE_NS (0xE002EDF0UL) /*!< Core Debug Base Address (non-secure address space) */ + #define SysTick_BASE_NS (SCS_BASE_NS + 0x0010UL) /*!< SysTick Base Address (non-secure address space) */ + #define NVIC_BASE_NS (SCS_BASE_NS + 0x0100UL) /*!< NVIC Base Address (non-secure address space) */ + #define SCB_BASE_NS (SCS_BASE_NS + 0x0D00UL) /*!< System Control Block Base Address (non-secure address space) */ + + #define SCB_NS ((SCB_Type *) SCB_BASE_NS ) /*!< SCB configuration struct (non-secure address space) */ + #define SysTick_NS ((SysTick_Type *) SysTick_BASE_NS ) /*!< SysTick configuration struct (non-secure address space) */ + #define NVIC_NS ((NVIC_Type *) NVIC_BASE_NS ) /*!< NVIC configuration struct (non-secure address space) */ + #define CoreDebug_NS ((CoreDebug_Type *) CoreDebug_BASE_NS) /*!< Core Debug configuration struct (non-secure address space) */ + + #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE_NS (SCS_BASE_NS + 0x0D90UL) /*!< Memory Protection Unit (non-secure address space) */ + #define MPU_NS ((MPU_Type *) MPU_BASE_NS ) /*!< Memory Protection Unit (non-secure address space) */ + #endif + +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else +/*#define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping not available for Cortex-M23 */ +/*#define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping not available for Cortex-M23 */ + #define NVIC_EnableIRQ __NVIC_EnableIRQ + #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ + #define NVIC_DisableIRQ __NVIC_DisableIRQ + #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ + #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ + #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ + #define NVIC_GetActive __NVIC_GetActive + #define NVIC_SetPriority __NVIC_SetPriority + #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset +#endif /* CMSIS_NVIC_VIRTUAL */ + +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetVector __NVIC_SetVector + #define NVIC_GetVector __NVIC_GetVector +#endif /* (CMSIS_VECTAB_VIRTUAL) */ + +#define NVIC_USER_IRQ_OFFSET 16 + + +/* Special LR values for Secure/Non-Secure call handling and exception handling */ + +/* Function Return Payload (from ARMv8-M Architecture Reference Manual) LR value on entry from Secure BLXNS */ +#define FNC_RETURN (0xFEFFFFFFUL) /* bit [0] ignored when processing a branch */ + +/* The following EXC_RETURN mask values are used to evaluate the LR on exception entry */ +#define EXC_RETURN_PREFIX (0xFF000000UL) /* bits [31:24] set to indicate an EXC_RETURN value */ +#define EXC_RETURN_S (0x00000040UL) /* bit [6] stack used to push registers: 0=Non-secure 1=Secure */ +#define EXC_RETURN_DCRS (0x00000020UL) /* bit [5] stacking rules for called registers: 0=skipped 1=saved */ +#define EXC_RETURN_FTYPE (0x00000010UL) /* bit [4] allocate stack for floating-point context: 0=done 1=skipped */ +#define EXC_RETURN_MODE (0x00000008UL) /* bit [3] processor mode for return: 0=Handler mode 1=Thread mode */ +#define EXC_RETURN_SPSEL (0x00000002UL) /* bit [1] stack pointer used to restore context: 0=MSP 1=PSP */ +#define EXC_RETURN_ES (0x00000001UL) /* bit [0] security state exception was taken to: 0=Non-secure 1=Secure */ + +/* Integrity Signature (from ARMv8-M Architecture Reference Manual) for exception context stacking */ +#if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) /* Value for processors with floating-point extension: */ +#define EXC_INTEGRITY_SIGNATURE (0xFEFA125AUL) /* bit [0] SFTC must match LR bit[4] EXC_RETURN_FTYPE */ +#else +#define EXC_INTEGRITY_SIGNATURE (0xFEFA125BUL) /* Value for processors without floating-point extension */ +#endif + + +/* Interrupt Priorities are WORD accessible only under Armv6-M */ +/* The following MACROS handle generation of the register offset and byte masks */ +#define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL) +#define _SHP_IDX(IRQn) ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >> 2UL) ) +#define _IP_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 2UL) ) + +#define __NVIC_SetPriorityGrouping(X) (void)(X) +#define __NVIC_GetPriorityGrouping() (0U) + +/** + \brief Enable Interrupt + \details Enables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Interrupt Enable status + \details Returns a device specific interrupt enable status from the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt + \details Disables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __DSB(); + __ISB(); + } +} + + +/** + \brief Get Pending Interrupt + \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt + \details Reads the active register in the NVIC and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetActive(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Get Interrupt Target State + \details Reads the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + \return 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_GetTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Target State + \details Sets the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_SetTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] |= ((uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL))); + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Clear Interrupt Target State + \details Clears the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_ClearTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] &= ~((uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL))); + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + + +/** + \brief Set Interrupt Priority + \details Sets the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every processor exception. + */ +__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->IPR[_IP_IDX(IRQn)] = ((uint32_t)(NVIC->IPR[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } + else + { + SCB->SHPR[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHPR[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IPR[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return((uint32_t)(((SCB->SHPR[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief Encode Priority + \details Encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + return ( + ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | + ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) + ); +} + + +/** + \brief Decode Priority + \details Decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. + \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); + *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); +} + + +/** + \brief Set Interrupt Vector + \details Sets an interrupt vector in SRAM based interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + VTOR must been relocated to SRAM before. + If VTOR is not present address 0 must be mapped to SRAM. + \param [in] IRQn Interrupt number + \param [in] vector Address of interrupt handler function + */ +__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) +{ +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) + uint32_t *vectors = (uint32_t *)SCB->VTOR; +#else + uint32_t *vectors = (uint32_t *)0x0U; +#endif + vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; +} + + +/** + \brief Get Interrupt Vector + \details Reads an interrupt vector from interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Address of interrupt handler function + */ +__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) +{ +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) + uint32_t *vectors = (uint32_t *)SCB->VTOR; +#else + uint32_t *vectors = (uint32_t *)0x0U; +#endif + return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET]; +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + SCB_AIRCR_SYSRESETREQ_Msk); + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Enable Interrupt (non-secure) + \details Enables a device specific interrupt in the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_EnableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Interrupt Enable status (non-secure) + \details Returns a device specific interrupt enable status from the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetEnableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt (non-secure) + \details Disables a device specific interrupt in the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_DisableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Pending Interrupt (non-secure) + \details Reads the NVIC pending register in the non-secure NVIC when in secure state and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt (non-secure) + \details Sets the pending bit of a device specific interrupt in the non-secure NVIC pending register when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_SetPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt (non-secure) + \details Clears the pending bit of a device specific interrupt in the non-secure NVIC pending register when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_ClearPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt (non-secure) + \details Reads the active register in non-secure NVIC when in secure state and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetActive_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Priority (non-secure) + \details Sets the priority of a non-secure device specific interrupt or a non-secure processor exception when in secure state. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every non-secure processor exception. + */ +__STATIC_INLINE void TZ_NVIC_SetPriority_NS(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->IPR[_IP_IDX(IRQn)] = ((uint32_t)(NVIC_NS->IPR[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } + else + { + SCB_NS->SHPR[_SHP_IDX(IRQn)] = ((uint32_t)(SCB_NS->SHPR[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } +} + + +/** + \brief Get Interrupt Priority (non-secure) + \details Reads the priority of a non-secure device specific interrupt or a non-secure processor exception when in secure state. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetPriority_NS(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->IPR[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return((uint32_t)(((SCB_NS->SHPR[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } +} +#endif /* defined (__ARM_FEATURE_CMSE) &&(__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_NVICFunctions */ + +/* ########################## MPU functions #################################### */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + +#include "mpu_armv8.h" + +#endif + +/* ########################## FPU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_FpuFunctions FPU Functions + \brief Function that provides FPU type. + @{ + */ + +/** + \brief get FPU type + \details returns the FPU type + \returns + - \b 0: No FPU + - \b 1: Single precision FPU + - \b 2: Double + Single precision FPU + */ +__STATIC_INLINE uint32_t SCB_GetFPUType(void) +{ + return 0U; /* No FPU */ +} + + +/*@} end of CMSIS_Core_FpuFunctions */ + + + +/* ########################## SAU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SAUFunctions SAU Functions + \brief Functions that configure the SAU. + @{ + */ + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + +/** + \brief Enable SAU + \details Enables the Security Attribution Unit (SAU). + */ +__STATIC_INLINE void TZ_SAU_Enable(void) +{ + SAU->CTRL |= (SAU_CTRL_ENABLE_Msk); +} + + + +/** + \brief Disable SAU + \details Disables the Security Attribution Unit (SAU). + */ +__STATIC_INLINE void TZ_SAU_Disable(void) +{ + SAU->CTRL &= ~(SAU_CTRL_ENABLE_Msk); +} + +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_SAUFunctions */ + + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief System Tick Configuration (non-secure) + \details Initializes the non-secure System Timer and its interrupt when in secure state, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function TZ_SysTick_Config_NS is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + + */ +__STATIC_INLINE uint32_t TZ_SysTick_Config_NS(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick_NS->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + TZ_NVIC_SetPriority_NS (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick_NS->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick_NS->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM23_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/test/STM32F072C8T6/Drivers/CMSIS/Include/core_cm3.h b/test/STM32F072C8T6/Drivers/CMSIS/Include/core_cm3.h new file mode 100644 index 0000000..b0dfbd3 --- /dev/null +++ b/test/STM32F072C8T6/Drivers/CMSIS/Include/core_cm3.h @@ -0,0 +1,1941 @@ +/**************************************************************************//** + * @file core_cm3.h + * @brief CMSIS Cortex-M3 Core Peripheral Access Layer Header File + * @version V5.0.8 + * @date 04. June 2018 + ******************************************************************************/ +/* + * Copyright (c) 2009-2018 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * 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 + * + * 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. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CORE_CM3_H_GENERIC +#define __CORE_CM3_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup Cortex_M3 + @{ + */ + +#include "cmsis_version.h" + +/* CMSIS CM3 definitions */ +#define __CM3_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __CM3_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ +#define __CM3_CMSIS_VERSION ((__CM3_CMSIS_VERSION_MAIN << 16U) | \ + __CM3_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ + +#define __CORTEX_M (3U) /*!< Cortex-M Core */ + +/** __FPU_USED indicates whether an FPU is used or not. + This core does not support an FPU at all +*/ +#define __FPU_USED 0U + +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_PCS_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TI_ARM__ ) + #if defined __TI_VFP_SUPPORT__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM3_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM3_H_DEPENDANT +#define __CORE_CM3_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM3_REV + #define __CM3_REV 0x0200U + #warning "__CM3_REV not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0U + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 3U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group Cortex_M3 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug Register + - Core MPU Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:27; /*!< bit: 0..26 Reserved */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + +#define APSR_Q_Pos 27U /*!< APSR: Q Position */ +#define APSR_Q_Msk (1UL << APSR_Q_Pos) /*!< APSR: Q Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:1; /*!< bit: 9 Reserved */ + uint32_t ICI_IT_1:6; /*!< bit: 10..15 ICI/IT part 1 */ + uint32_t _reserved1:8; /*!< bit: 16..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit */ + uint32_t ICI_IT_2:2; /*!< bit: 25..26 ICI/IT part 2 */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_Q_Pos 27U /*!< xPSR: Q Position */ +#define xPSR_Q_Msk (1UL << xPSR_Q_Pos) /*!< xPSR: Q Mask */ + +#define xPSR_ICI_IT_2_Pos 25U /*!< xPSR: ICI/IT part 2 Position */ +#define xPSR_ICI_IT_2_Msk (3UL << xPSR_ICI_IT_2_Pos) /*!< xPSR: ICI/IT part 2 Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_ICI_IT_1_Pos 10U /*!< xPSR: ICI/IT part 1 Position */ +#define xPSR_ICI_IT_1_Msk (0x3FUL << xPSR_ICI_IT_1_Pos) /*!< xPSR: ICI/IT part 1 Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ + uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ +#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[8U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[24U]; + __IOM uint32_t ICER[8U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[24U]; + __IOM uint32_t ISPR[8U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[24U]; + __IOM uint32_t ICPR[8U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[24U]; + __IOM uint32_t IABR[8U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[56U]; + __IOM uint8_t IP[240U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ + uint32_t RESERVED5[644U]; + __OM uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ +} NVIC_Type; + +/* Software Triggered Interrupt Register Definitions */ +#define NVIC_STIR_INTID_Pos 0U /*!< STIR: INTLINESNUM Position */ +#define NVIC_STIR_INTID_Msk (0x1FFUL /*<< NVIC_STIR_INTID_Pos*/) /*!< STIR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + __IOM uint8_t SHP[12U]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ + __IOM uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ + __IOM uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ + __IOM uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ + __IOM uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ + __IOM uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ + __IOM uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ + __IM uint32_t PFR[2U]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ + __IM uint32_t DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ + __IM uint32_t ADR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ + __IM uint32_t MMFR[4U]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ + __IM uint32_t ISAR[5U]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ + uint32_t RESERVED0[5U]; + __IOM uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */ +#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_RETTOBASE_Pos 11U /*!< SCB ICSR: RETTOBASE Position */ +#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Vector Table Offset Register Definitions */ +#if defined (__CM3_REV) && (__CM3_REV < 0x0201U) /* core r2p1 */ +#define SCB_VTOR_TBLBASE_Pos 29U /*!< SCB VTOR: TBLBASE Position */ +#define SCB_VTOR_TBLBASE_Msk (1UL << SCB_VTOR_TBLBASE_Pos) /*!< SCB VTOR: TBLBASE Mask */ + +#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x3FFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ +#else +#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ +#endif + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_PRIGROUP_Pos 8U /*!< SCB AIRCR: PRIGROUP Position */ +#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +#define SCB_AIRCR_VECTRESET_Pos 0U /*!< SCB AIRCR: VECTRESET Position */ +#define SCB_AIRCR_VECTRESET_Msk (1UL /*<< SCB_AIRCR_VECTRESET_Pos*/) /*!< SCB AIRCR: VECTRESET Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */ +#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ + +#define SCB_CCR_BFHFNMIGN_Pos 8U /*!< SCB CCR: BFHFNMIGN Position */ +#define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ + +#define SCB_CCR_DIV_0_TRP_Pos 4U /*!< SCB CCR: DIV_0_TRP Position */ +#define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +#define SCB_CCR_USERSETMPEND_Pos 1U /*!< SCB CCR: USERSETMPEND Position */ +#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ + +#define SCB_CCR_NONBASETHRDENA_Pos 0U /*!< SCB CCR: NONBASETHRDENA Position */ +#define SCB_CCR_NONBASETHRDENA_Msk (1UL /*<< SCB_CCR_NONBASETHRDENA_Pos*/) /*!< SCB CCR: NONBASETHRDENA Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_USGFAULTENA_Pos 18U /*!< SCB SHCSR: USGFAULTENA Position */ +#define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */ + +#define SCB_SHCSR_BUSFAULTENA_Pos 17U /*!< SCB SHCSR: BUSFAULTENA Position */ +#define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */ + +#define SCB_SHCSR_MEMFAULTENA_Pos 16U /*!< SCB SHCSR: MEMFAULTENA Position */ +#define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */ + +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +#define SCB_SHCSR_BUSFAULTPENDED_Pos 14U /*!< SCB SHCSR: BUSFAULTPENDED Position */ +#define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */ + +#define SCB_SHCSR_MEMFAULTPENDED_Pos 13U /*!< SCB SHCSR: MEMFAULTPENDED Position */ +#define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */ + +#define SCB_SHCSR_USGFAULTPENDED_Pos 12U /*!< SCB SHCSR: USGFAULTPENDED Position */ +#define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */ + +#define SCB_SHCSR_SYSTICKACT_Pos 11U /*!< SCB SHCSR: SYSTICKACT Position */ +#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ + +#define SCB_SHCSR_PENDSVACT_Pos 10U /*!< SCB SHCSR: PENDSVACT Position */ +#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ + +#define SCB_SHCSR_MONITORACT_Pos 8U /*!< SCB SHCSR: MONITORACT Position */ +#define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */ + +#define SCB_SHCSR_SVCALLACT_Pos 7U /*!< SCB SHCSR: SVCALLACT Position */ +#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ + +#define SCB_SHCSR_USGFAULTACT_Pos 3U /*!< SCB SHCSR: USGFAULTACT Position */ +#define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */ + +#define SCB_SHCSR_BUSFAULTACT_Pos 1U /*!< SCB SHCSR: BUSFAULTACT Position */ +#define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */ + +#define SCB_SHCSR_MEMFAULTACT_Pos 0U /*!< SCB SHCSR: MEMFAULTACT Position */ +#define SCB_SHCSR_MEMFAULTACT_Msk (1UL /*<< SCB_SHCSR_MEMFAULTACT_Pos*/) /*!< SCB SHCSR: MEMFAULTACT Mask */ + +/* SCB Configurable Fault Status Register Definitions */ +#define SCB_CFSR_USGFAULTSR_Pos 16U /*!< SCB CFSR: Usage Fault Status Register Position */ +#define SCB_CFSR_USGFAULTSR_Msk (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */ + +#define SCB_CFSR_BUSFAULTSR_Pos 8U /*!< SCB CFSR: Bus Fault Status Register Position */ +#define SCB_CFSR_BUSFAULTSR_Msk (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */ + +#define SCB_CFSR_MEMFAULTSR_Pos 0U /*!< SCB CFSR: Memory Manage Fault Status Register Position */ +#define SCB_CFSR_MEMFAULTSR_Msk (0xFFUL /*<< SCB_CFSR_MEMFAULTSR_Pos*/) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */ + +/* MemManage Fault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_MMARVALID_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 7U) /*!< SCB CFSR (MMFSR): MMARVALID Position */ +#define SCB_CFSR_MMARVALID_Msk (1UL << SCB_CFSR_MMARVALID_Pos) /*!< SCB CFSR (MMFSR): MMARVALID Mask */ + +#define SCB_CFSR_MSTKERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 4U) /*!< SCB CFSR (MMFSR): MSTKERR Position */ +#define SCB_CFSR_MSTKERR_Msk (1UL << SCB_CFSR_MSTKERR_Pos) /*!< SCB CFSR (MMFSR): MSTKERR Mask */ + +#define SCB_CFSR_MUNSTKERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 3U) /*!< SCB CFSR (MMFSR): MUNSTKERR Position */ +#define SCB_CFSR_MUNSTKERR_Msk (1UL << SCB_CFSR_MUNSTKERR_Pos) /*!< SCB CFSR (MMFSR): MUNSTKERR Mask */ + +#define SCB_CFSR_DACCVIOL_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 1U) /*!< SCB CFSR (MMFSR): DACCVIOL Position */ +#define SCB_CFSR_DACCVIOL_Msk (1UL << SCB_CFSR_DACCVIOL_Pos) /*!< SCB CFSR (MMFSR): DACCVIOL Mask */ + +#define SCB_CFSR_IACCVIOL_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 0U) /*!< SCB CFSR (MMFSR): IACCVIOL Position */ +#define SCB_CFSR_IACCVIOL_Msk (1UL /*<< SCB_CFSR_IACCVIOL_Pos*/) /*!< SCB CFSR (MMFSR): IACCVIOL Mask */ + +/* BusFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_BFARVALID_Pos (SCB_CFSR_BUSFAULTSR_Pos + 7U) /*!< SCB CFSR (BFSR): BFARVALID Position */ +#define SCB_CFSR_BFARVALID_Msk (1UL << SCB_CFSR_BFARVALID_Pos) /*!< SCB CFSR (BFSR): BFARVALID Mask */ + +#define SCB_CFSR_STKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 4U) /*!< SCB CFSR (BFSR): STKERR Position */ +#define SCB_CFSR_STKERR_Msk (1UL << SCB_CFSR_STKERR_Pos) /*!< SCB CFSR (BFSR): STKERR Mask */ + +#define SCB_CFSR_UNSTKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 3U) /*!< SCB CFSR (BFSR): UNSTKERR Position */ +#define SCB_CFSR_UNSTKERR_Msk (1UL << SCB_CFSR_UNSTKERR_Pos) /*!< SCB CFSR (BFSR): UNSTKERR Mask */ + +#define SCB_CFSR_IMPRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 2U) /*!< SCB CFSR (BFSR): IMPRECISERR Position */ +#define SCB_CFSR_IMPRECISERR_Msk (1UL << SCB_CFSR_IMPRECISERR_Pos) /*!< SCB CFSR (BFSR): IMPRECISERR Mask */ + +#define SCB_CFSR_PRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 1U) /*!< SCB CFSR (BFSR): PRECISERR Position */ +#define SCB_CFSR_PRECISERR_Msk (1UL << SCB_CFSR_PRECISERR_Pos) /*!< SCB CFSR (BFSR): PRECISERR Mask */ + +#define SCB_CFSR_IBUSERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 0U) /*!< SCB CFSR (BFSR): IBUSERR Position */ +#define SCB_CFSR_IBUSERR_Msk (1UL << SCB_CFSR_IBUSERR_Pos) /*!< SCB CFSR (BFSR): IBUSERR Mask */ + +/* UsageFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_DIVBYZERO_Pos (SCB_CFSR_USGFAULTSR_Pos + 9U) /*!< SCB CFSR (UFSR): DIVBYZERO Position */ +#define SCB_CFSR_DIVBYZERO_Msk (1UL << SCB_CFSR_DIVBYZERO_Pos) /*!< SCB CFSR (UFSR): DIVBYZERO Mask */ + +#define SCB_CFSR_UNALIGNED_Pos (SCB_CFSR_USGFAULTSR_Pos + 8U) /*!< SCB CFSR (UFSR): UNALIGNED Position */ +#define SCB_CFSR_UNALIGNED_Msk (1UL << SCB_CFSR_UNALIGNED_Pos) /*!< SCB CFSR (UFSR): UNALIGNED Mask */ + +#define SCB_CFSR_NOCP_Pos (SCB_CFSR_USGFAULTSR_Pos + 3U) /*!< SCB CFSR (UFSR): NOCP Position */ +#define SCB_CFSR_NOCP_Msk (1UL << SCB_CFSR_NOCP_Pos) /*!< SCB CFSR (UFSR): NOCP Mask */ + +#define SCB_CFSR_INVPC_Pos (SCB_CFSR_USGFAULTSR_Pos + 2U) /*!< SCB CFSR (UFSR): INVPC Position */ +#define SCB_CFSR_INVPC_Msk (1UL << SCB_CFSR_INVPC_Pos) /*!< SCB CFSR (UFSR): INVPC Mask */ + +#define SCB_CFSR_INVSTATE_Pos (SCB_CFSR_USGFAULTSR_Pos + 1U) /*!< SCB CFSR (UFSR): INVSTATE Position */ +#define SCB_CFSR_INVSTATE_Msk (1UL << SCB_CFSR_INVSTATE_Pos) /*!< SCB CFSR (UFSR): INVSTATE Mask */ + +#define SCB_CFSR_UNDEFINSTR_Pos (SCB_CFSR_USGFAULTSR_Pos + 0U) /*!< SCB CFSR (UFSR): UNDEFINSTR Position */ +#define SCB_CFSR_UNDEFINSTR_Msk (1UL << SCB_CFSR_UNDEFINSTR_Pos) /*!< SCB CFSR (UFSR): UNDEFINSTR Mask */ + +/* SCB Hard Fault Status Register Definitions */ +#define SCB_HFSR_DEBUGEVT_Pos 31U /*!< SCB HFSR: DEBUGEVT Position */ +#define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ + +#define SCB_HFSR_FORCED_Pos 30U /*!< SCB HFSR: FORCED Position */ +#define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */ + +#define SCB_HFSR_VECTTBL_Pos 1U /*!< SCB HFSR: VECTTBL Position */ +#define SCB_HFSR_VECTTBL_Msk (1UL << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */ + +/* SCB Debug Fault Status Register Definitions */ +#define SCB_DFSR_EXTERNAL_Pos 4U /*!< SCB DFSR: EXTERNAL Position */ +#define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */ + +#define SCB_DFSR_VCATCH_Pos 3U /*!< SCB DFSR: VCATCH Position */ +#define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */ + +#define SCB_DFSR_DWTTRAP_Pos 2U /*!< SCB DFSR: DWTTRAP Position */ +#define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */ + +#define SCB_DFSR_BKPT_Pos 1U /*!< SCB DFSR: BKPT Position */ +#define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */ + +#define SCB_DFSR_HALTED_Pos 0U /*!< SCB DFSR: HALTED Position */ +#define SCB_DFSR_HALTED_Msk (1UL /*<< SCB_DFSR_HALTED_Pos*/) /*!< SCB DFSR: HALTED Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) + \brief Type definitions for the System Control and ID Register not in the SCB + @{ + */ + +/** + \brief Structure type to access the System Control and ID Register not in the SCB. + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IM uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ +#if defined (__CM3_REV) && (__CM3_REV >= 0x200U) + __IOM uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ +#else + uint32_t RESERVED1[1U]; +#endif +} SCnSCB_Type; + +/* Interrupt Controller Type Register Definitions */ +#define SCnSCB_ICTR_INTLINESNUM_Pos 0U /*!< ICTR: INTLINESNUM Position */ +#define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL /*<< SCnSCB_ICTR_INTLINESNUM_Pos*/) /*!< ICTR: INTLINESNUM Mask */ + +/* Auxiliary Control Register Definitions */ + +#define SCnSCB_ACTLR_DISFOLD_Pos 2U /*!< ACTLR: DISFOLD Position */ +#define SCnSCB_ACTLR_DISFOLD_Msk (1UL << SCnSCB_ACTLR_DISFOLD_Pos) /*!< ACTLR: DISFOLD Mask */ + +#define SCnSCB_ACTLR_DISDEFWBUF_Pos 1U /*!< ACTLR: DISDEFWBUF Position */ +#define SCnSCB_ACTLR_DISDEFWBUF_Msk (1UL << SCnSCB_ACTLR_DISDEFWBUF_Pos) /*!< ACTLR: DISDEFWBUF Mask */ + +#define SCnSCB_ACTLR_DISMCYCINT_Pos 0U /*!< ACTLR: DISMCYCINT Position */ +#define SCnSCB_ACTLR_DISMCYCINT_Msk (1UL /*<< SCnSCB_ACTLR_DISMCYCINT_Pos*/) /*!< ACTLR: DISMCYCINT Mask */ + +/*@} end of group CMSIS_SCnotSCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_ITM Instrumentation Trace Macrocell (ITM) + \brief Type definitions for the Instrumentation Trace Macrocell (ITM) + @{ + */ + +/** + \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM). + */ +typedef struct +{ + __OM union + { + __OM uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ + __OM uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ + __OM uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ + } PORT [32U]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ + uint32_t RESERVED0[864U]; + __IOM uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ + uint32_t RESERVED1[15U]; + __IOM uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ + uint32_t RESERVED2[15U]; + __IOM uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ + uint32_t RESERVED3[29U]; + __OM uint32_t IWR; /*!< Offset: 0xEF8 ( /W) ITM Integration Write Register */ + __IM uint32_t IRR; /*!< Offset: 0xEFC (R/ ) ITM Integration Read Register */ + __IOM uint32_t IMCR; /*!< Offset: 0xF00 (R/W) ITM Integration Mode Control Register */ + uint32_t RESERVED4[43U]; + __OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */ + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */ + uint32_t RESERVED5[6U]; + __IM uint32_t PID4; /*!< Offset: 0xFD0 (R/ ) ITM Peripheral Identification Register #4 */ + __IM uint32_t PID5; /*!< Offset: 0xFD4 (R/ ) ITM Peripheral Identification Register #5 */ + __IM uint32_t PID6; /*!< Offset: 0xFD8 (R/ ) ITM Peripheral Identification Register #6 */ + __IM uint32_t PID7; /*!< Offset: 0xFDC (R/ ) ITM Peripheral Identification Register #7 */ + __IM uint32_t PID0; /*!< Offset: 0xFE0 (R/ ) ITM Peripheral Identification Register #0 */ + __IM uint32_t PID1; /*!< Offset: 0xFE4 (R/ ) ITM Peripheral Identification Register #1 */ + __IM uint32_t PID2; /*!< Offset: 0xFE8 (R/ ) ITM Peripheral Identification Register #2 */ + __IM uint32_t PID3; /*!< Offset: 0xFEC (R/ ) ITM Peripheral Identification Register #3 */ + __IM uint32_t CID0; /*!< Offset: 0xFF0 (R/ ) ITM Component Identification Register #0 */ + __IM uint32_t CID1; /*!< Offset: 0xFF4 (R/ ) ITM Component Identification Register #1 */ + __IM uint32_t CID2; /*!< Offset: 0xFF8 (R/ ) ITM Component Identification Register #2 */ + __IM uint32_t CID3; /*!< Offset: 0xFFC (R/ ) ITM Component Identification Register #3 */ +} ITM_Type; + +/* ITM Trace Privilege Register Definitions */ +#define ITM_TPR_PRIVMASK_Pos 0U /*!< ITM TPR: PRIVMASK Position */ +#define ITM_TPR_PRIVMASK_Msk (0xFFFFFFFFUL /*<< ITM_TPR_PRIVMASK_Pos*/) /*!< ITM TPR: PRIVMASK Mask */ + +/* ITM Trace Control Register Definitions */ +#define ITM_TCR_BUSY_Pos 23U /*!< ITM TCR: BUSY Position */ +#define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */ + +#define ITM_TCR_TraceBusID_Pos 16U /*!< ITM TCR: ATBID Position */ +#define ITM_TCR_TraceBusID_Msk (0x7FUL << ITM_TCR_TraceBusID_Pos) /*!< ITM TCR: ATBID Mask */ + +#define ITM_TCR_GTSFREQ_Pos 10U /*!< ITM TCR: Global timestamp frequency Position */ +#define ITM_TCR_GTSFREQ_Msk (3UL << ITM_TCR_GTSFREQ_Pos) /*!< ITM TCR: Global timestamp frequency Mask */ + +#define ITM_TCR_TSPrescale_Pos 8U /*!< ITM TCR: TSPrescale Position */ +#define ITM_TCR_TSPrescale_Msk (3UL << ITM_TCR_TSPrescale_Pos) /*!< ITM TCR: TSPrescale Mask */ + +#define ITM_TCR_SWOENA_Pos 4U /*!< ITM TCR: SWOENA Position */ +#define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */ + +#define ITM_TCR_DWTENA_Pos 3U /*!< ITM TCR: DWTENA Position */ +#define ITM_TCR_DWTENA_Msk (1UL << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */ + +#define ITM_TCR_SYNCENA_Pos 2U /*!< ITM TCR: SYNCENA Position */ +#define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */ + +#define ITM_TCR_TSENA_Pos 1U /*!< ITM TCR: TSENA Position */ +#define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */ + +#define ITM_TCR_ITMENA_Pos 0U /*!< ITM TCR: ITM Enable bit Position */ +#define ITM_TCR_ITMENA_Msk (1UL /*<< ITM_TCR_ITMENA_Pos*/) /*!< ITM TCR: ITM Enable bit Mask */ + +/* ITM Integration Write Register Definitions */ +#define ITM_IWR_ATVALIDM_Pos 0U /*!< ITM IWR: ATVALIDM Position */ +#define ITM_IWR_ATVALIDM_Msk (1UL /*<< ITM_IWR_ATVALIDM_Pos*/) /*!< ITM IWR: ATVALIDM Mask */ + +/* ITM Integration Read Register Definitions */ +#define ITM_IRR_ATREADYM_Pos 0U /*!< ITM IRR: ATREADYM Position */ +#define ITM_IRR_ATREADYM_Msk (1UL /*<< ITM_IRR_ATREADYM_Pos*/) /*!< ITM IRR: ATREADYM Mask */ + +/* ITM Integration Mode Control Register Definitions */ +#define ITM_IMCR_INTEGRATION_Pos 0U /*!< ITM IMCR: INTEGRATION Position */ +#define ITM_IMCR_INTEGRATION_Msk (1UL /*<< ITM_IMCR_INTEGRATION_Pos*/) /*!< ITM IMCR: INTEGRATION Mask */ + +/* ITM Lock Status Register Definitions */ +#define ITM_LSR_ByteAcc_Pos 2U /*!< ITM LSR: ByteAcc Position */ +#define ITM_LSR_ByteAcc_Msk (1UL << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */ + +#define ITM_LSR_Access_Pos 1U /*!< ITM LSR: Access Position */ +#define ITM_LSR_Access_Msk (1UL << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */ + +#define ITM_LSR_Present_Pos 0U /*!< ITM LSR: Present Position */ +#define ITM_LSR_Present_Msk (1UL /*<< ITM_LSR_Present_Pos*/) /*!< ITM LSR: Present Mask */ + +/*@}*/ /* end of group CMSIS_ITM */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) + \brief Type definitions for the Data Watchpoint and Trace (DWT) + @{ + */ + +/** + \brief Structure type to access the Data Watchpoint and Trace Register (DWT). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ + __IOM uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */ + __IOM uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */ + __IOM uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */ + __IOM uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */ + __IOM uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */ + __IOM uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */ + __IM uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ + __IOM uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ + __IOM uint32_t MASK0; /*!< Offset: 0x024 (R/W) Mask Register 0 */ + __IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ + uint32_t RESERVED0[1U]; + __IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ + __IOM uint32_t MASK1; /*!< Offset: 0x034 (R/W) Mask Register 1 */ + __IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ + uint32_t RESERVED1[1U]; + __IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ + __IOM uint32_t MASK2; /*!< Offset: 0x044 (R/W) Mask Register 2 */ + __IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ + uint32_t RESERVED2[1U]; + __IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ + __IOM uint32_t MASK3; /*!< Offset: 0x054 (R/W) Mask Register 3 */ + __IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ +} DWT_Type; + +/* DWT Control Register Definitions */ +#define DWT_CTRL_NUMCOMP_Pos 28U /*!< DWT CTRL: NUMCOMP Position */ +#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ + +#define DWT_CTRL_NOTRCPKT_Pos 27U /*!< DWT CTRL: NOTRCPKT Position */ +#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ + +#define DWT_CTRL_NOEXTTRIG_Pos 26U /*!< DWT CTRL: NOEXTTRIG Position */ +#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ + +#define DWT_CTRL_NOCYCCNT_Pos 25U /*!< DWT CTRL: NOCYCCNT Position */ +#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ + +#define DWT_CTRL_NOPRFCNT_Pos 24U /*!< DWT CTRL: NOPRFCNT Position */ +#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ + +#define DWT_CTRL_CYCEVTENA_Pos 22U /*!< DWT CTRL: CYCEVTENA Position */ +#define DWT_CTRL_CYCEVTENA_Msk (0x1UL << DWT_CTRL_CYCEVTENA_Pos) /*!< DWT CTRL: CYCEVTENA Mask */ + +#define DWT_CTRL_FOLDEVTENA_Pos 21U /*!< DWT CTRL: FOLDEVTENA Position */ +#define DWT_CTRL_FOLDEVTENA_Msk (0x1UL << DWT_CTRL_FOLDEVTENA_Pos) /*!< DWT CTRL: FOLDEVTENA Mask */ + +#define DWT_CTRL_LSUEVTENA_Pos 20U /*!< DWT CTRL: LSUEVTENA Position */ +#define DWT_CTRL_LSUEVTENA_Msk (0x1UL << DWT_CTRL_LSUEVTENA_Pos) /*!< DWT CTRL: LSUEVTENA Mask */ + +#define DWT_CTRL_SLEEPEVTENA_Pos 19U /*!< DWT CTRL: SLEEPEVTENA Position */ +#define DWT_CTRL_SLEEPEVTENA_Msk (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos) /*!< DWT CTRL: SLEEPEVTENA Mask */ + +#define DWT_CTRL_EXCEVTENA_Pos 18U /*!< DWT CTRL: EXCEVTENA Position */ +#define DWT_CTRL_EXCEVTENA_Msk (0x1UL << DWT_CTRL_EXCEVTENA_Pos) /*!< DWT CTRL: EXCEVTENA Mask */ + +#define DWT_CTRL_CPIEVTENA_Pos 17U /*!< DWT CTRL: CPIEVTENA Position */ +#define DWT_CTRL_CPIEVTENA_Msk (0x1UL << DWT_CTRL_CPIEVTENA_Pos) /*!< DWT CTRL: CPIEVTENA Mask */ + +#define DWT_CTRL_EXCTRCENA_Pos 16U /*!< DWT CTRL: EXCTRCENA Position */ +#define DWT_CTRL_EXCTRCENA_Msk (0x1UL << DWT_CTRL_EXCTRCENA_Pos) /*!< DWT CTRL: EXCTRCENA Mask */ + +#define DWT_CTRL_PCSAMPLENA_Pos 12U /*!< DWT CTRL: PCSAMPLENA Position */ +#define DWT_CTRL_PCSAMPLENA_Msk (0x1UL << DWT_CTRL_PCSAMPLENA_Pos) /*!< DWT CTRL: PCSAMPLENA Mask */ + +#define DWT_CTRL_SYNCTAP_Pos 10U /*!< DWT CTRL: SYNCTAP Position */ +#define DWT_CTRL_SYNCTAP_Msk (0x3UL << DWT_CTRL_SYNCTAP_Pos) /*!< DWT CTRL: SYNCTAP Mask */ + +#define DWT_CTRL_CYCTAP_Pos 9U /*!< DWT CTRL: CYCTAP Position */ +#define DWT_CTRL_CYCTAP_Msk (0x1UL << DWT_CTRL_CYCTAP_Pos) /*!< DWT CTRL: CYCTAP Mask */ + +#define DWT_CTRL_POSTINIT_Pos 5U /*!< DWT CTRL: POSTINIT Position */ +#define DWT_CTRL_POSTINIT_Msk (0xFUL << DWT_CTRL_POSTINIT_Pos) /*!< DWT CTRL: POSTINIT Mask */ + +#define DWT_CTRL_POSTPRESET_Pos 1U /*!< DWT CTRL: POSTPRESET Position */ +#define DWT_CTRL_POSTPRESET_Msk (0xFUL << DWT_CTRL_POSTPRESET_Pos) /*!< DWT CTRL: POSTPRESET Mask */ + +#define DWT_CTRL_CYCCNTENA_Pos 0U /*!< DWT CTRL: CYCCNTENA Position */ +#define DWT_CTRL_CYCCNTENA_Msk (0x1UL /*<< DWT_CTRL_CYCCNTENA_Pos*/) /*!< DWT CTRL: CYCCNTENA Mask */ + +/* DWT CPI Count Register Definitions */ +#define DWT_CPICNT_CPICNT_Pos 0U /*!< DWT CPICNT: CPICNT Position */ +#define DWT_CPICNT_CPICNT_Msk (0xFFUL /*<< DWT_CPICNT_CPICNT_Pos*/) /*!< DWT CPICNT: CPICNT Mask */ + +/* DWT Exception Overhead Count Register Definitions */ +#define DWT_EXCCNT_EXCCNT_Pos 0U /*!< DWT EXCCNT: EXCCNT Position */ +#define DWT_EXCCNT_EXCCNT_Msk (0xFFUL /*<< DWT_EXCCNT_EXCCNT_Pos*/) /*!< DWT EXCCNT: EXCCNT Mask */ + +/* DWT Sleep Count Register Definitions */ +#define DWT_SLEEPCNT_SLEEPCNT_Pos 0U /*!< DWT SLEEPCNT: SLEEPCNT Position */ +#define DWT_SLEEPCNT_SLEEPCNT_Msk (0xFFUL /*<< DWT_SLEEPCNT_SLEEPCNT_Pos*/) /*!< DWT SLEEPCNT: SLEEPCNT Mask */ + +/* DWT LSU Count Register Definitions */ +#define DWT_LSUCNT_LSUCNT_Pos 0U /*!< DWT LSUCNT: LSUCNT Position */ +#define DWT_LSUCNT_LSUCNT_Msk (0xFFUL /*<< DWT_LSUCNT_LSUCNT_Pos*/) /*!< DWT LSUCNT: LSUCNT Mask */ + +/* DWT Folded-instruction Count Register Definitions */ +#define DWT_FOLDCNT_FOLDCNT_Pos 0U /*!< DWT FOLDCNT: FOLDCNT Position */ +#define DWT_FOLDCNT_FOLDCNT_Msk (0xFFUL /*<< DWT_FOLDCNT_FOLDCNT_Pos*/) /*!< DWT FOLDCNT: FOLDCNT Mask */ + +/* DWT Comparator Mask Register Definitions */ +#define DWT_MASK_MASK_Pos 0U /*!< DWT MASK: MASK Position */ +#define DWT_MASK_MASK_Msk (0x1FUL /*<< DWT_MASK_MASK_Pos*/) /*!< DWT MASK: MASK Mask */ + +/* DWT Comparator Function Register Definitions */ +#define DWT_FUNCTION_MATCHED_Pos 24U /*!< DWT FUNCTION: MATCHED Position */ +#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ + +#define DWT_FUNCTION_DATAVADDR1_Pos 16U /*!< DWT FUNCTION: DATAVADDR1 Position */ +#define DWT_FUNCTION_DATAVADDR1_Msk (0xFUL << DWT_FUNCTION_DATAVADDR1_Pos) /*!< DWT FUNCTION: DATAVADDR1 Mask */ + +#define DWT_FUNCTION_DATAVADDR0_Pos 12U /*!< DWT FUNCTION: DATAVADDR0 Position */ +#define DWT_FUNCTION_DATAVADDR0_Msk (0xFUL << DWT_FUNCTION_DATAVADDR0_Pos) /*!< DWT FUNCTION: DATAVADDR0 Mask */ + +#define DWT_FUNCTION_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */ +#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ + +#define DWT_FUNCTION_LNK1ENA_Pos 9U /*!< DWT FUNCTION: LNK1ENA Position */ +#define DWT_FUNCTION_LNK1ENA_Msk (0x1UL << DWT_FUNCTION_LNK1ENA_Pos) /*!< DWT FUNCTION: LNK1ENA Mask */ + +#define DWT_FUNCTION_DATAVMATCH_Pos 8U /*!< DWT FUNCTION: DATAVMATCH Position */ +#define DWT_FUNCTION_DATAVMATCH_Msk (0x1UL << DWT_FUNCTION_DATAVMATCH_Pos) /*!< DWT FUNCTION: DATAVMATCH Mask */ + +#define DWT_FUNCTION_CYCMATCH_Pos 7U /*!< DWT FUNCTION: CYCMATCH Position */ +#define DWT_FUNCTION_CYCMATCH_Msk (0x1UL << DWT_FUNCTION_CYCMATCH_Pos) /*!< DWT FUNCTION: CYCMATCH Mask */ + +#define DWT_FUNCTION_EMITRANGE_Pos 5U /*!< DWT FUNCTION: EMITRANGE Position */ +#define DWT_FUNCTION_EMITRANGE_Msk (0x1UL << DWT_FUNCTION_EMITRANGE_Pos) /*!< DWT FUNCTION: EMITRANGE Mask */ + +#define DWT_FUNCTION_FUNCTION_Pos 0U /*!< DWT FUNCTION: FUNCTION Position */ +#define DWT_FUNCTION_FUNCTION_Msk (0xFUL /*<< DWT_FUNCTION_FUNCTION_Pos*/) /*!< DWT FUNCTION: FUNCTION Mask */ + +/*@}*/ /* end of group CMSIS_DWT */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_TPI Trace Port Interface (TPI) + \brief Type definitions for the Trace Port Interface (TPI) + @{ + */ + +/** + \brief Structure type to access the Trace Port Interface Register (TPI). + */ +typedef struct +{ + __IM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ + __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ + uint32_t RESERVED0[2U]; + __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ + uint32_t RESERVED1[55U]; + __IOM uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ + uint32_t RESERVED2[131U]; + __IM uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ + __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ + __IM uint32_t FSCR; /*!< Offset: 0x308 (R/ ) Formatter Synchronization Counter Register */ + uint32_t RESERVED3[759U]; + __IM uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER Register */ + __IM uint32_t FIFO0; /*!< Offset: 0xEEC (R/ ) Integration ETM Data */ + __IM uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/ ) ITATBCTR2 */ + uint32_t RESERVED4[1U]; + __IM uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) ITATBCTR0 */ + __IM uint32_t FIFO1; /*!< Offset: 0xEFC (R/ ) Integration ITM Data */ + __IOM uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */ + uint32_t RESERVED5[39U]; + __IOM uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */ + __IOM uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */ + uint32_t RESERVED7[8U]; + __IM uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) TPIU_DEVID */ + __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) TPIU_DEVTYPE */ +} TPI_Type; + +/* TPI Asynchronous Clock Prescaler Register Definitions */ +#define TPI_ACPR_PRESCALER_Pos 0U /*!< TPI ACPR: PRESCALER Position */ +#define TPI_ACPR_PRESCALER_Msk (0x1FFFUL /*<< TPI_ACPR_PRESCALER_Pos*/) /*!< TPI ACPR: PRESCALER Mask */ + +/* TPI Selected Pin Protocol Register Definitions */ +#define TPI_SPPR_TXMODE_Pos 0U /*!< TPI SPPR: TXMODE Position */ +#define TPI_SPPR_TXMODE_Msk (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/) /*!< TPI SPPR: TXMODE Mask */ + +/* TPI Formatter and Flush Status Register Definitions */ +#define TPI_FFSR_FtNonStop_Pos 3U /*!< TPI FFSR: FtNonStop Position */ +#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ + +#define TPI_FFSR_TCPresent_Pos 2U /*!< TPI FFSR: TCPresent Position */ +#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ + +#define TPI_FFSR_FtStopped_Pos 1U /*!< TPI FFSR: FtStopped Position */ +#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ + +#define TPI_FFSR_FlInProg_Pos 0U /*!< TPI FFSR: FlInProg Position */ +#define TPI_FFSR_FlInProg_Msk (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/) /*!< TPI FFSR: FlInProg Mask */ + +/* TPI Formatter and Flush Control Register Definitions */ +#define TPI_FFCR_TrigIn_Pos 8U /*!< TPI FFCR: TrigIn Position */ +#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ + +#define TPI_FFCR_EnFCont_Pos 1U /*!< TPI FFCR: EnFCont Position */ +#define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ + +/* TPI TRIGGER Register Definitions */ +#define TPI_TRIGGER_TRIGGER_Pos 0U /*!< TPI TRIGGER: TRIGGER Position */ +#define TPI_TRIGGER_TRIGGER_Msk (0x1UL /*<< TPI_TRIGGER_TRIGGER_Pos*/) /*!< TPI TRIGGER: TRIGGER Mask */ + +/* TPI Integration ETM Data Register Definitions (FIFO0) */ +#define TPI_FIFO0_ITM_ATVALID_Pos 29U /*!< TPI FIFO0: ITM_ATVALID Position */ +#define TPI_FIFO0_ITM_ATVALID_Msk (0x3UL << TPI_FIFO0_ITM_ATVALID_Pos) /*!< TPI FIFO0: ITM_ATVALID Mask */ + +#define TPI_FIFO0_ITM_bytecount_Pos 27U /*!< TPI FIFO0: ITM_bytecount Position */ +#define TPI_FIFO0_ITM_bytecount_Msk (0x3UL << TPI_FIFO0_ITM_bytecount_Pos) /*!< TPI FIFO0: ITM_bytecount Mask */ + +#define TPI_FIFO0_ETM_ATVALID_Pos 26U /*!< TPI FIFO0: ETM_ATVALID Position */ +#define TPI_FIFO0_ETM_ATVALID_Msk (0x3UL << TPI_FIFO0_ETM_ATVALID_Pos) /*!< TPI FIFO0: ETM_ATVALID Mask */ + +#define TPI_FIFO0_ETM_bytecount_Pos 24U /*!< TPI FIFO0: ETM_bytecount Position */ +#define TPI_FIFO0_ETM_bytecount_Msk (0x3UL << TPI_FIFO0_ETM_bytecount_Pos) /*!< TPI FIFO0: ETM_bytecount Mask */ + +#define TPI_FIFO0_ETM2_Pos 16U /*!< TPI FIFO0: ETM2 Position */ +#define TPI_FIFO0_ETM2_Msk (0xFFUL << TPI_FIFO0_ETM2_Pos) /*!< TPI FIFO0: ETM2 Mask */ + +#define TPI_FIFO0_ETM1_Pos 8U /*!< TPI FIFO0: ETM1 Position */ +#define TPI_FIFO0_ETM1_Msk (0xFFUL << TPI_FIFO0_ETM1_Pos) /*!< TPI FIFO0: ETM1 Mask */ + +#define TPI_FIFO0_ETM0_Pos 0U /*!< TPI FIFO0: ETM0 Position */ +#define TPI_FIFO0_ETM0_Msk (0xFFUL /*<< TPI_FIFO0_ETM0_Pos*/) /*!< TPI FIFO0: ETM0 Mask */ + +/* TPI ITATBCTR2 Register Definitions */ +#define TPI_ITATBCTR2_ATREADY2_Pos 0U /*!< TPI ITATBCTR2: ATREADY2 Position */ +#define TPI_ITATBCTR2_ATREADY2_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY2_Pos*/) /*!< TPI ITATBCTR2: ATREADY2 Mask */ + +#define TPI_ITATBCTR2_ATREADY1_Pos 0U /*!< TPI ITATBCTR2: ATREADY1 Position */ +#define TPI_ITATBCTR2_ATREADY1_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY1_Pos*/) /*!< TPI ITATBCTR2: ATREADY1 Mask */ + +/* TPI Integration ITM Data Register Definitions (FIFO1) */ +#define TPI_FIFO1_ITM_ATVALID_Pos 29U /*!< TPI FIFO1: ITM_ATVALID Position */ +#define TPI_FIFO1_ITM_ATVALID_Msk (0x3UL << TPI_FIFO1_ITM_ATVALID_Pos) /*!< TPI FIFO1: ITM_ATVALID Mask */ + +#define TPI_FIFO1_ITM_bytecount_Pos 27U /*!< TPI FIFO1: ITM_bytecount Position */ +#define TPI_FIFO1_ITM_bytecount_Msk (0x3UL << TPI_FIFO1_ITM_bytecount_Pos) /*!< TPI FIFO1: ITM_bytecount Mask */ + +#define TPI_FIFO1_ETM_ATVALID_Pos 26U /*!< TPI FIFO1: ETM_ATVALID Position */ +#define TPI_FIFO1_ETM_ATVALID_Msk (0x3UL << TPI_FIFO1_ETM_ATVALID_Pos) /*!< TPI FIFO1: ETM_ATVALID Mask */ + +#define TPI_FIFO1_ETM_bytecount_Pos 24U /*!< TPI FIFO1: ETM_bytecount Position */ +#define TPI_FIFO1_ETM_bytecount_Msk (0x3UL << TPI_FIFO1_ETM_bytecount_Pos) /*!< TPI FIFO1: ETM_bytecount Mask */ + +#define TPI_FIFO1_ITM2_Pos 16U /*!< TPI FIFO1: ITM2 Position */ +#define TPI_FIFO1_ITM2_Msk (0xFFUL << TPI_FIFO1_ITM2_Pos) /*!< TPI FIFO1: ITM2 Mask */ + +#define TPI_FIFO1_ITM1_Pos 8U /*!< TPI FIFO1: ITM1 Position */ +#define TPI_FIFO1_ITM1_Msk (0xFFUL << TPI_FIFO1_ITM1_Pos) /*!< TPI FIFO1: ITM1 Mask */ + +#define TPI_FIFO1_ITM0_Pos 0U /*!< TPI FIFO1: ITM0 Position */ +#define TPI_FIFO1_ITM0_Msk (0xFFUL /*<< TPI_FIFO1_ITM0_Pos*/) /*!< TPI FIFO1: ITM0 Mask */ + +/* TPI ITATBCTR0 Register Definitions */ +#define TPI_ITATBCTR0_ATREADY2_Pos 0U /*!< TPI ITATBCTR0: ATREADY2 Position */ +#define TPI_ITATBCTR0_ATREADY2_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY2_Pos*/) /*!< TPI ITATBCTR0: ATREADY2 Mask */ + +#define TPI_ITATBCTR0_ATREADY1_Pos 0U /*!< TPI ITATBCTR0: ATREADY1 Position */ +#define TPI_ITATBCTR0_ATREADY1_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY1_Pos*/) /*!< TPI ITATBCTR0: ATREADY1 Mask */ + +/* TPI Integration Mode Control Register Definitions */ +#define TPI_ITCTRL_Mode_Pos 0U /*!< TPI ITCTRL: Mode Position */ +#define TPI_ITCTRL_Mode_Msk (0x3UL /*<< TPI_ITCTRL_Mode_Pos*/) /*!< TPI ITCTRL: Mode Mask */ + +/* TPI DEVID Register Definitions */ +#define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */ +#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ + +#define TPI_DEVID_MANCVALID_Pos 10U /*!< TPI DEVID: MANCVALID Position */ +#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ + +#define TPI_DEVID_PTINVALID_Pos 9U /*!< TPI DEVID: PTINVALID Position */ +#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ + +#define TPI_DEVID_MinBufSz_Pos 6U /*!< TPI DEVID: MinBufSz Position */ +#define TPI_DEVID_MinBufSz_Msk (0x7UL << TPI_DEVID_MinBufSz_Pos) /*!< TPI DEVID: MinBufSz Mask */ + +#define TPI_DEVID_AsynClkIn_Pos 5U /*!< TPI DEVID: AsynClkIn Position */ +#define TPI_DEVID_AsynClkIn_Msk (0x1UL << TPI_DEVID_AsynClkIn_Pos) /*!< TPI DEVID: AsynClkIn Mask */ + +#define TPI_DEVID_NrTraceInput_Pos 0U /*!< TPI DEVID: NrTraceInput Position */ +#define TPI_DEVID_NrTraceInput_Msk (0x1FUL /*<< TPI_DEVID_NrTraceInput_Pos*/) /*!< TPI DEVID: NrTraceInput Mask */ + +/* TPI DEVTYPE Register Definitions */ +#define TPI_DEVTYPE_SubType_Pos 4U /*!< TPI DEVTYPE: SubType Position */ +#define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ + +#define TPI_DEVTYPE_MajorType_Pos 0U /*!< TPI DEVTYPE: MajorType Position */ +#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ + +/*@}*/ /* end of group CMSIS_TPI */ + + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** + \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IOM uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */ + __IOM uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Alias 1 Region Base Address Register */ + __IOM uint32_t RASR_A1; /*!< Offset: 0x018 (R/W) MPU Alias 1 Region Attribute and Size Register */ + __IOM uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Alias 2 Region Base Address Register */ + __IOM uint32_t RASR_A2; /*!< Offset: 0x020 (R/W) MPU Alias 2 Region Attribute and Size Register */ + __IOM uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Alias 3 Region Base Address Register */ + __IOM uint32_t RASR_A3; /*!< Offset: 0x028 (R/W) MPU Alias 3 Region Attribute and Size Register */ +} MPU_Type; + +#define MPU_TYPE_RALIASES 4U + +/* MPU Type Register Definitions */ +#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register Definitions */ +#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register Definitions */ +#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register Definitions */ +#define MPU_RBAR_ADDR_Pos 5U /*!< MPU RBAR: ADDR Position */ +#define MPU_RBAR_ADDR_Msk (0x7FFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ + +#define MPU_RBAR_VALID_Pos 4U /*!< MPU RBAR: VALID Position */ +#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */ + +#define MPU_RBAR_REGION_Pos 0U /*!< MPU RBAR: REGION Position */ +#define MPU_RBAR_REGION_Msk (0xFUL /*<< MPU_RBAR_REGION_Pos*/) /*!< MPU RBAR: REGION Mask */ + +/* MPU Region Attribute and Size Register Definitions */ +#define MPU_RASR_ATTRS_Pos 16U /*!< MPU RASR: MPU Region Attribute field Position */ +#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */ + +#define MPU_RASR_XN_Pos 28U /*!< MPU RASR: ATTRS.XN Position */ +#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */ + +#define MPU_RASR_AP_Pos 24U /*!< MPU RASR: ATTRS.AP Position */ +#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */ + +#define MPU_RASR_TEX_Pos 19U /*!< MPU RASR: ATTRS.TEX Position */ +#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */ + +#define MPU_RASR_S_Pos 18U /*!< MPU RASR: ATTRS.S Position */ +#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */ + +#define MPU_RASR_C_Pos 17U /*!< MPU RASR: ATTRS.C Position */ +#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */ + +#define MPU_RASR_B_Pos 16U /*!< MPU RASR: ATTRS.B Position */ +#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */ + +#define MPU_RASR_SRD_Pos 8U /*!< MPU RASR: Sub-Region Disable Position */ +#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */ + +#define MPU_RASR_SIZE_Pos 1U /*!< MPU RASR: Region Size Field Position */ +#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */ + +#define MPU_RASR_ENABLE_Pos 0U /*!< MPU RASR: Region enable bit Position */ +#define MPU_RASR_ENABLE_Msk (1UL /*<< MPU_RASR_ENABLE_Pos*/) /*!< MPU RASR: Region enable bit Disable Mask */ + +/*@} end of group CMSIS_MPU */ +#endif + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Type definitions for the Core Debug Registers + @{ + */ + +/** + \brief Structure type to access the Core Debug Register (CoreDebug). + */ +typedef struct +{ + __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ +} CoreDebug_Type; + +/* Debug Halting Control and Status Register Definitions */ +#define CoreDebug_DHCSR_DBGKEY_Pos 16U /*!< CoreDebug DHCSR: DBGKEY Position */ +#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */ + +#define CoreDebug_DHCSR_S_RESET_ST_Pos 25U /*!< CoreDebug DHCSR: S_RESET_ST Position */ +#define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< CoreDebug DHCSR: S_RESET_ST Mask */ + +#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24U /*!< CoreDebug DHCSR: S_RETIRE_ST Position */ +#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */ + +#define CoreDebug_DHCSR_S_LOCKUP_Pos 19U /*!< CoreDebug DHCSR: S_LOCKUP Position */ +#define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< CoreDebug DHCSR: S_LOCKUP Mask */ + +#define CoreDebug_DHCSR_S_SLEEP_Pos 18U /*!< CoreDebug DHCSR: S_SLEEP Position */ +#define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< CoreDebug DHCSR: S_SLEEP Mask */ + +#define CoreDebug_DHCSR_S_HALT_Pos 17U /*!< CoreDebug DHCSR: S_HALT Position */ +#define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< CoreDebug DHCSR: S_HALT Mask */ + +#define CoreDebug_DHCSR_S_REGRDY_Pos 16U /*!< CoreDebug DHCSR: S_REGRDY Position */ +#define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< CoreDebug DHCSR: S_REGRDY Mask */ + +#define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5U /*!< CoreDebug DHCSR: C_SNAPSTALL Position */ +#define CoreDebug_DHCSR_C_SNAPSTALL_Msk (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos) /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */ + +#define CoreDebug_DHCSR_C_MASKINTS_Pos 3U /*!< CoreDebug DHCSR: C_MASKINTS Position */ +#define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< CoreDebug DHCSR: C_MASKINTS Mask */ + +#define CoreDebug_DHCSR_C_STEP_Pos 2U /*!< CoreDebug DHCSR: C_STEP Position */ +#define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< CoreDebug DHCSR: C_STEP Mask */ + +#define CoreDebug_DHCSR_C_HALT_Pos 1U /*!< CoreDebug DHCSR: C_HALT Position */ +#define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< CoreDebug DHCSR: C_HALT Mask */ + +#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0U /*!< CoreDebug DHCSR: C_DEBUGEN Position */ +#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */ + +/* Debug Core Register Selector Register Definitions */ +#define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< CoreDebug DCRSR: REGWnR Position */ +#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ + +#define CoreDebug_DCRSR_REGSEL_Pos 0U /*!< CoreDebug DCRSR: REGSEL Position */ +#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/) /*!< CoreDebug DCRSR: REGSEL Mask */ + +/* Debug Exception and Monitor Control Register Definitions */ +#define CoreDebug_DEMCR_TRCENA_Pos 24U /*!< CoreDebug DEMCR: TRCENA Position */ +#define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< CoreDebug DEMCR: TRCENA Mask */ + +#define CoreDebug_DEMCR_MON_REQ_Pos 19U /*!< CoreDebug DEMCR: MON_REQ Position */ +#define CoreDebug_DEMCR_MON_REQ_Msk (1UL << CoreDebug_DEMCR_MON_REQ_Pos) /*!< CoreDebug DEMCR: MON_REQ Mask */ + +#define CoreDebug_DEMCR_MON_STEP_Pos 18U /*!< CoreDebug DEMCR: MON_STEP Position */ +#define CoreDebug_DEMCR_MON_STEP_Msk (1UL << CoreDebug_DEMCR_MON_STEP_Pos) /*!< CoreDebug DEMCR: MON_STEP Mask */ + +#define CoreDebug_DEMCR_MON_PEND_Pos 17U /*!< CoreDebug DEMCR: MON_PEND Position */ +#define CoreDebug_DEMCR_MON_PEND_Msk (1UL << CoreDebug_DEMCR_MON_PEND_Pos) /*!< CoreDebug DEMCR: MON_PEND Mask */ + +#define CoreDebug_DEMCR_MON_EN_Pos 16U /*!< CoreDebug DEMCR: MON_EN Position */ +#define CoreDebug_DEMCR_MON_EN_Msk (1UL << CoreDebug_DEMCR_MON_EN_Pos) /*!< CoreDebug DEMCR: MON_EN Mask */ + +#define CoreDebug_DEMCR_VC_HARDERR_Pos 10U /*!< CoreDebug DEMCR: VC_HARDERR Position */ +#define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< CoreDebug DEMCR: VC_HARDERR Mask */ + +#define CoreDebug_DEMCR_VC_INTERR_Pos 9U /*!< CoreDebug DEMCR: VC_INTERR Position */ +#define CoreDebug_DEMCR_VC_INTERR_Msk (1UL << CoreDebug_DEMCR_VC_INTERR_Pos) /*!< CoreDebug DEMCR: VC_INTERR Mask */ + +#define CoreDebug_DEMCR_VC_BUSERR_Pos 8U /*!< CoreDebug DEMCR: VC_BUSERR Position */ +#define CoreDebug_DEMCR_VC_BUSERR_Msk (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos) /*!< CoreDebug DEMCR: VC_BUSERR Mask */ + +#define CoreDebug_DEMCR_VC_STATERR_Pos 7U /*!< CoreDebug DEMCR: VC_STATERR Position */ +#define CoreDebug_DEMCR_VC_STATERR_Msk (1UL << CoreDebug_DEMCR_VC_STATERR_Pos) /*!< CoreDebug DEMCR: VC_STATERR Mask */ + +#define CoreDebug_DEMCR_VC_CHKERR_Pos 6U /*!< CoreDebug DEMCR: VC_CHKERR Position */ +#define CoreDebug_DEMCR_VC_CHKERR_Msk (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos) /*!< CoreDebug DEMCR: VC_CHKERR Mask */ + +#define CoreDebug_DEMCR_VC_NOCPERR_Pos 5U /*!< CoreDebug DEMCR: VC_NOCPERR Position */ +#define CoreDebug_DEMCR_VC_NOCPERR_Msk (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos) /*!< CoreDebug DEMCR: VC_NOCPERR Mask */ + +#define CoreDebug_DEMCR_VC_MMERR_Pos 4U /*!< CoreDebug DEMCR: VC_MMERR Position */ +#define CoreDebug_DEMCR_VC_MMERR_Msk (1UL << CoreDebug_DEMCR_VC_MMERR_Pos) /*!< CoreDebug DEMCR: VC_MMERR Mask */ + +#define CoreDebug_DEMCR_VC_CORERESET_Pos 0U /*!< CoreDebug DEMCR: VC_CORERESET Position */ +#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/) /*!< CoreDebug DEMCR: VC_CORERESET Mask */ + +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param[in] field Name of the register bit field. + \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param[in] field Name of the register bit field. + \param[in] value Value of register. This parameter is interpreted as an uint32_t type. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) + +/*@} end of group CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Core Hardware */ +#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ +#define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ +#define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ +#define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ +#define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */ +#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ +#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ +#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + +#define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ +#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ +#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ +#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ +#define ITM ((ITM_Type *) ITM_BASE ) /*!< ITM configuration struct */ +#define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ +#define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ +#define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE) /*!< Core Debug configuration struct */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ +#endif + +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Debug Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping + #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping + #define NVIC_EnableIRQ __NVIC_EnableIRQ + #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ + #define NVIC_DisableIRQ __NVIC_DisableIRQ + #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ + #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ + #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ + #define NVIC_GetActive __NVIC_GetActive + #define NVIC_SetPriority __NVIC_SetPriority + #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset +#endif /* CMSIS_NVIC_VIRTUAL */ + +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetVector __NVIC_SetVector + #define NVIC_GetVector __NVIC_GetVector +#endif /* (CMSIS_VECTAB_VIRTUAL) */ + +#define NVIC_USER_IRQ_OFFSET 16 + + +/* The following EXC_RETURN values are saved the LR on exception entry */ +#define EXC_RETURN_HANDLER (0xFFFFFFF1UL) /* return to Handler mode, uses MSP after return */ +#define EXC_RETURN_THREAD_MSP (0xFFFFFFF9UL) /* return to Thread mode, uses MSP after return */ +#define EXC_RETURN_THREAD_PSP (0xFFFFFFFDUL) /* return to Thread mode, uses PSP after return */ + + +/** + \brief Set Priority Grouping + \details Sets the priority grouping field using the required unlock sequence. + The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. + Only values from 0..7 are used. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Priority grouping field. + */ +__STATIC_INLINE void __NVIC_SetPriorityGrouping(uint32_t PriorityGroup) +{ + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + + reg_value = SCB->AIRCR; /* read old register configuration */ + reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << SCB_AIRCR_PRIGROUP_Pos) ); /* Insert write key and priority group */ + SCB->AIRCR = reg_value; +} + + +/** + \brief Get Priority Grouping + \details Reads the priority grouping field from the NVIC Interrupt Controller. + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t __NVIC_GetPriorityGrouping(void) +{ + return ((uint32_t)((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); +} + + +/** + \brief Enable Interrupt + \details Enables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Interrupt Enable status + \details Returns a device specific interrupt enable status from the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt + \details Disables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __DSB(); + __ISB(); + } +} + + +/** + \brief Get Pending Interrupt + \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt + \details Reads the active register in the NVIC and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetActive(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Priority + \details Sets the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every processor exception. + */ +__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->IP[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } + else + { + SCB->SHP[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return(((uint32_t)NVIC->IP[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return(((uint32_t)SCB->SHP[(((uint32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief Encode Priority + \details Encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + return ( + ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | + ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) + ); +} + + +/** + \brief Decode Priority + \details Decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. + \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); + *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); +} + + +/** + \brief Set Interrupt Vector + \details Sets an interrupt vector in SRAM based interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + VTOR must been relocated to SRAM before. + \param [in] IRQn Interrupt number + \param [in] vector Address of interrupt handler function + */ +__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; +} + + +/** + \brief Get Interrupt Vector + \details Reads an interrupt vector from interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Address of interrupt handler function + */ +__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET]; +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + SCB_AIRCR_SYSRESETREQ_Msk ); /* Keep priority group unchanged */ + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +/*@} end of CMSIS_Core_NVICFunctions */ + +/* ########################## MPU functions #################################### */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + +#include "mpu_armv7.h" + +#endif + +/* ########################## FPU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_FpuFunctions FPU Functions + \brief Function that provides FPU type. + @{ + */ + +/** + \brief get FPU type + \details returns the FPU type + \returns + - \b 0: No FPU + - \b 1: Single precision FPU + - \b 2: Double + Single precision FPU + */ +__STATIC_INLINE uint32_t SCB_GetFPUType(void) +{ + return 0U; /* No FPU */ +} + + +/*@} end of CMSIS_Core_FpuFunctions */ + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + +/* ##################################### Debug In/Output function ########################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_core_DebugFunctions ITM Functions + \brief Functions that access the ITM debug interface. + @{ + */ + +extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */ +#define ITM_RXBUFFER_EMPTY ((int32_t)0x5AA55AA5U) /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */ + + +/** + \brief ITM Send Character + \details Transmits a character via the ITM channel 0, and + \li Just returns when no debugger is connected that has booked the output. + \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted. + \param [in] ch Character to transmit. + \returns Character to transmit. + */ +__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch) +{ + if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) && /* ITM enabled */ + ((ITM->TER & 1UL ) != 0UL) ) /* ITM Port #0 enabled */ + { + while (ITM->PORT[0U].u32 == 0UL) + { + __NOP(); + } + ITM->PORT[0U].u8 = (uint8_t)ch; + } + return (ch); +} + + +/** + \brief ITM Receive Character + \details Inputs a character via the external variable \ref ITM_RxBuffer. + \return Received character. + \return -1 No character pending. + */ +__STATIC_INLINE int32_t ITM_ReceiveChar (void) +{ + int32_t ch = -1; /* no character available */ + + if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) + { + ch = ITM_RxBuffer; + ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */ + } + + return (ch); +} + + +/** + \brief ITM Check Character + \details Checks whether a character is pending for reading in the variable \ref ITM_RxBuffer. + \return 0 No character available. + \return 1 Character available. + */ +__STATIC_INLINE int32_t ITM_CheckChar (void) +{ + + if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) + { + return (0); /* no character available */ + } + else + { + return (1); /* character available */ + } +} + +/*@} end of CMSIS_core_DebugFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM3_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/test/STM32F072C8T6/Drivers/CMSIS/Include/core_cm33.h b/test/STM32F072C8T6/Drivers/CMSIS/Include/core_cm33.h new file mode 100644 index 0000000..02f82e2 --- /dev/null +++ b/test/STM32F072C8T6/Drivers/CMSIS/Include/core_cm33.h @@ -0,0 +1,3002 @@ +/**************************************************************************//** + * @file core_cm33.h + * @brief CMSIS Cortex-M33 Core Peripheral Access Layer Header File + * @version V5.0.9 + * @date 06. July 2018 + ******************************************************************************/ +/* + * Copyright (c) 2009-2018 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * 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 + * + * 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. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CORE_CM33_H_GENERIC +#define __CORE_CM33_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup Cortex_M33 + @{ + */ + +#include "cmsis_version.h" + +/* CMSIS CM33 definitions */ +#define __CM33_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __CM33_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ +#define __CM33_CMSIS_VERSION ((__CM33_CMSIS_VERSION_MAIN << 16U) | \ + __CM33_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ + +#define __CORTEX_M (33U) /*!< Cortex-M Core */ + +/** __FPU_USED indicates whether an FPU is used or not. + For this, __FPU_PRESENT has to be checked prior to making use of FPU specific registers and functions. +*/ +#if defined ( __CC_ARM ) + #if defined (__TARGET_FPU_VFP) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + + #if defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1U) + #if defined (__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_USED 0U + #endif + +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined (__ARM_PCS_VFP) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + + #if defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1U) + #if defined (__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_USED 0U + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + + #if defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1U) + #if defined (__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_USED 0U + #endif + +#elif defined ( __ICCARM__ ) + #if defined (__ARMVFP__) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + + #if defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1U) + #if defined (__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_USED 0U + #endif + +#elif defined ( __TI_ARM__ ) + #if defined (__TI_VFP_SUPPORT__) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __TASKING__ ) + #if defined (__FPU_VFP__) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM33_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM33_H_DEPENDANT +#define __CORE_CM33_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM33_REV + #define __CM33_REV 0x0000U + #warning "__CM33_REV not defined in device header file; using default!" + #endif + + #ifndef __FPU_PRESENT + #define __FPU_PRESENT 0U + #warning "__FPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0U + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __SAUREGION_PRESENT + #define __SAUREGION_PRESENT 0U + #warning "__SAUREGION_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __DSP_PRESENT + #define __DSP_PRESENT 0U + #warning "__DSP_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 3U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group Cortex_M33 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug Register + - Core MPU Register + - Core SAU Register + - Core FPU Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:16; /*!< bit: 0..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:7; /*!< bit: 20..26 Reserved */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + +#define APSR_Q_Pos 27U /*!< APSR: Q Position */ +#define APSR_Q_Msk (1UL << APSR_Q_Pos) /*!< APSR: Q Mask */ + +#define APSR_GE_Pos 16U /*!< APSR: GE Position */ +#define APSR_GE_Msk (0xFUL << APSR_GE_Pos) /*!< APSR: GE Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:7; /*!< bit: 9..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:4; /*!< bit: 20..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t IT:2; /*!< bit: 25..26 saved IT state (read 0) */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_Q_Pos 27U /*!< xPSR: Q Position */ +#define xPSR_Q_Msk (1UL << xPSR_Q_Pos) /*!< xPSR: Q Mask */ + +#define xPSR_IT_Pos 25U /*!< xPSR: IT Position */ +#define xPSR_IT_Msk (3UL << xPSR_IT_Pos) /*!< xPSR: IT Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_GE_Pos 16U /*!< xPSR: GE Position */ +#define xPSR_GE_Msk (0xFUL << xPSR_GE_Pos) /*!< xPSR: GE Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL:1; /*!< bit: 1 Stack-pointer select */ + uint32_t FPCA:1; /*!< bit: 2 Floating-point context active */ + uint32_t SFPA:1; /*!< bit: 3 Secure floating-point active */ + uint32_t _reserved1:28; /*!< bit: 4..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_SFPA_Pos 3U /*!< CONTROL: SFPA Position */ +#define CONTROL_SFPA_Msk (1UL << CONTROL_SFPA_Pos) /*!< CONTROL: SFPA Mask */ + +#define CONTROL_FPCA_Pos 2U /*!< CONTROL: FPCA Position */ +#define CONTROL_FPCA_Msk (1UL << CONTROL_FPCA_Pos) /*!< CONTROL: FPCA Mask */ + +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ +#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[16U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[16U]; + __IOM uint32_t ICER[16U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[16U]; + __IOM uint32_t ISPR[16U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[16U]; + __IOM uint32_t ICPR[16U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[16U]; + __IOM uint32_t IABR[16U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[16U]; + __IOM uint32_t ITNS[16U]; /*!< Offset: 0x280 (R/W) Interrupt Non-Secure State Register */ + uint32_t RESERVED5[16U]; + __IOM uint8_t IPR[496U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ + uint32_t RESERVED6[580U]; + __OM uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ +} NVIC_Type; + +/* Software Triggered Interrupt Register Definitions */ +#define NVIC_STIR_INTID_Pos 0U /*!< STIR: INTLINESNUM Position */ +#define NVIC_STIR_INTID_Msk (0x1FFUL /*<< NVIC_STIR_INTID_Pos*/) /*!< STIR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + __IOM uint8_t SHPR[12U]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ + __IOM uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ + __IOM uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ + __IOM uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ + __IOM uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ + __IOM uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ + __IOM uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ + __IM uint32_t ID_PFR[2U]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ + __IM uint32_t ID_DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ + __IM uint32_t ID_ADR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ + __IM uint32_t ID_MMFR[4U]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ + __IM uint32_t ID_ISAR[6U]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ + __IM uint32_t CLIDR; /*!< Offset: 0x078 (R/ ) Cache Level ID register */ + __IM uint32_t CTR; /*!< Offset: 0x07C (R/ ) Cache Type register */ + __IM uint32_t CCSIDR; /*!< Offset: 0x080 (R/ ) Cache Size ID Register */ + __IOM uint32_t CSSELR; /*!< Offset: 0x084 (R/W) Cache Size Selection Register */ + __IOM uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ + __IOM uint32_t NSACR; /*!< Offset: 0x08C (R/W) Non-Secure Access Control Register */ + uint32_t RESERVED3[92U]; + __OM uint32_t STIR; /*!< Offset: 0x200 ( /W) Software Triggered Interrupt Register */ + uint32_t RESERVED4[15U]; + __IM uint32_t MVFR0; /*!< Offset: 0x240 (R/ ) Media and VFP Feature Register 0 */ + __IM uint32_t MVFR1; /*!< Offset: 0x244 (R/ ) Media and VFP Feature Register 1 */ + __IM uint32_t MVFR2; /*!< Offset: 0x248 (R/ ) Media and VFP Feature Register 2 */ + uint32_t RESERVED5[1U]; + __OM uint32_t ICIALLU; /*!< Offset: 0x250 ( /W) I-Cache Invalidate All to PoU */ + uint32_t RESERVED6[1U]; + __OM uint32_t ICIMVAU; /*!< Offset: 0x258 ( /W) I-Cache Invalidate by MVA to PoU */ + __OM uint32_t DCIMVAC; /*!< Offset: 0x25C ( /W) D-Cache Invalidate by MVA to PoC */ + __OM uint32_t DCISW; /*!< Offset: 0x260 ( /W) D-Cache Invalidate by Set-way */ + __OM uint32_t DCCMVAU; /*!< Offset: 0x264 ( /W) D-Cache Clean by MVA to PoU */ + __OM uint32_t DCCMVAC; /*!< Offset: 0x268 ( /W) D-Cache Clean by MVA to PoC */ + __OM uint32_t DCCSW; /*!< Offset: 0x26C ( /W) D-Cache Clean by Set-way */ + __OM uint32_t DCCIMVAC; /*!< Offset: 0x270 ( /W) D-Cache Clean and Invalidate by MVA to PoC */ + __OM uint32_t DCCISW; /*!< Offset: 0x274 ( /W) D-Cache Clean and Invalidate by Set-way */ + uint32_t RESERVED7[6U]; + __IOM uint32_t ITCMCR; /*!< Offset: 0x290 (R/W) Instruction Tightly-Coupled Memory Control Register */ + __IOM uint32_t DTCMCR; /*!< Offset: 0x294 (R/W) Data Tightly-Coupled Memory Control Registers */ + __IOM uint32_t AHBPCR; /*!< Offset: 0x298 (R/W) AHBP Control Register */ + __IOM uint32_t CACR; /*!< Offset: 0x29C (R/W) L1 Cache Control Register */ + __IOM uint32_t AHBSCR; /*!< Offset: 0x2A0 (R/W) AHB Slave Control Register */ + uint32_t RESERVED8[1U]; + __IOM uint32_t ABFSR; /*!< Offset: 0x2A8 (R/W) Auxiliary Bus Fault Status Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_PENDNMISET_Pos 31U /*!< SCB ICSR: PENDNMISET Position */ +#define SCB_ICSR_PENDNMISET_Msk (1UL << SCB_ICSR_PENDNMISET_Pos) /*!< SCB ICSR: PENDNMISET Mask */ + +#define SCB_ICSR_NMIPENDSET_Pos SCB_ICSR_PENDNMISET_Pos /*!< SCB ICSR: NMIPENDSET Position, backward compatibility */ +#define SCB_ICSR_NMIPENDSET_Msk SCB_ICSR_PENDNMISET_Msk /*!< SCB ICSR: NMIPENDSET Mask, backward compatibility */ + +#define SCB_ICSR_PENDNMICLR_Pos 30U /*!< SCB ICSR: PENDNMICLR Position */ +#define SCB_ICSR_PENDNMICLR_Msk (1UL << SCB_ICSR_PENDNMICLR_Pos) /*!< SCB ICSR: PENDNMICLR Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_STTNS_Pos 24U /*!< SCB ICSR: STTNS Position (Security Extension) */ +#define SCB_ICSR_STTNS_Msk (1UL << SCB_ICSR_STTNS_Pos) /*!< SCB ICSR: STTNS Mask (Security Extension) */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_RETTOBASE_Pos 11U /*!< SCB ICSR: RETTOBASE Position */ +#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Vector Table Offset Register Definitions */ +#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_PRIS_Pos 14U /*!< SCB AIRCR: PRIS Position */ +#define SCB_AIRCR_PRIS_Msk (1UL << SCB_AIRCR_PRIS_Pos) /*!< SCB AIRCR: PRIS Mask */ + +#define SCB_AIRCR_BFHFNMINS_Pos 13U /*!< SCB AIRCR: BFHFNMINS Position */ +#define SCB_AIRCR_BFHFNMINS_Msk (1UL << SCB_AIRCR_BFHFNMINS_Pos) /*!< SCB AIRCR: BFHFNMINS Mask */ + +#define SCB_AIRCR_PRIGROUP_Pos 8U /*!< SCB AIRCR: PRIGROUP Position */ +#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ + +#define SCB_AIRCR_SYSRESETREQS_Pos 3U /*!< SCB AIRCR: SYSRESETREQS Position */ +#define SCB_AIRCR_SYSRESETREQS_Msk (1UL << SCB_AIRCR_SYSRESETREQS_Pos) /*!< SCB AIRCR: SYSRESETREQS Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEPS_Pos 3U /*!< SCB SCR: SLEEPDEEPS Position */ +#define SCB_SCR_SLEEPDEEPS_Msk (1UL << SCB_SCR_SLEEPDEEPS_Pos) /*!< SCB SCR: SLEEPDEEPS Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_BP_Pos 18U /*!< SCB CCR: BP Position */ +#define SCB_CCR_BP_Msk (1UL << SCB_CCR_BP_Pos) /*!< SCB CCR: BP Mask */ + +#define SCB_CCR_IC_Pos 17U /*!< SCB CCR: IC Position */ +#define SCB_CCR_IC_Msk (1UL << SCB_CCR_IC_Pos) /*!< SCB CCR: IC Mask */ + +#define SCB_CCR_DC_Pos 16U /*!< SCB CCR: DC Position */ +#define SCB_CCR_DC_Msk (1UL << SCB_CCR_DC_Pos) /*!< SCB CCR: DC Mask */ + +#define SCB_CCR_STKOFHFNMIGN_Pos 10U /*!< SCB CCR: STKOFHFNMIGN Position */ +#define SCB_CCR_STKOFHFNMIGN_Msk (1UL << SCB_CCR_STKOFHFNMIGN_Pos) /*!< SCB CCR: STKOFHFNMIGN Mask */ + +#define SCB_CCR_BFHFNMIGN_Pos 8U /*!< SCB CCR: BFHFNMIGN Position */ +#define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ + +#define SCB_CCR_DIV_0_TRP_Pos 4U /*!< SCB CCR: DIV_0_TRP Position */ +#define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +#define SCB_CCR_USERSETMPEND_Pos 1U /*!< SCB CCR: USERSETMPEND Position */ +#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_HARDFAULTPENDED_Pos 21U /*!< SCB SHCSR: HARDFAULTPENDED Position */ +#define SCB_SHCSR_HARDFAULTPENDED_Msk (1UL << SCB_SHCSR_HARDFAULTPENDED_Pos) /*!< SCB SHCSR: HARDFAULTPENDED Mask */ + +#define SCB_SHCSR_SECUREFAULTPENDED_Pos 20U /*!< SCB SHCSR: SECUREFAULTPENDED Position */ +#define SCB_SHCSR_SECUREFAULTPENDED_Msk (1UL << SCB_SHCSR_SECUREFAULTPENDED_Pos) /*!< SCB SHCSR: SECUREFAULTPENDED Mask */ + +#define SCB_SHCSR_SECUREFAULTENA_Pos 19U /*!< SCB SHCSR: SECUREFAULTENA Position */ +#define SCB_SHCSR_SECUREFAULTENA_Msk (1UL << SCB_SHCSR_SECUREFAULTENA_Pos) /*!< SCB SHCSR: SECUREFAULTENA Mask */ + +#define SCB_SHCSR_USGFAULTENA_Pos 18U /*!< SCB SHCSR: USGFAULTENA Position */ +#define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */ + +#define SCB_SHCSR_BUSFAULTENA_Pos 17U /*!< SCB SHCSR: BUSFAULTENA Position */ +#define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */ + +#define SCB_SHCSR_MEMFAULTENA_Pos 16U /*!< SCB SHCSR: MEMFAULTENA Position */ +#define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */ + +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +#define SCB_SHCSR_BUSFAULTPENDED_Pos 14U /*!< SCB SHCSR: BUSFAULTPENDED Position */ +#define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */ + +#define SCB_SHCSR_MEMFAULTPENDED_Pos 13U /*!< SCB SHCSR: MEMFAULTPENDED Position */ +#define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */ + +#define SCB_SHCSR_USGFAULTPENDED_Pos 12U /*!< SCB SHCSR: USGFAULTPENDED Position */ +#define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */ + +#define SCB_SHCSR_SYSTICKACT_Pos 11U /*!< SCB SHCSR: SYSTICKACT Position */ +#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ + +#define SCB_SHCSR_PENDSVACT_Pos 10U /*!< SCB SHCSR: PENDSVACT Position */ +#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ + +#define SCB_SHCSR_MONITORACT_Pos 8U /*!< SCB SHCSR: MONITORACT Position */ +#define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */ + +#define SCB_SHCSR_SVCALLACT_Pos 7U /*!< SCB SHCSR: SVCALLACT Position */ +#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ + +#define SCB_SHCSR_NMIACT_Pos 5U /*!< SCB SHCSR: NMIACT Position */ +#define SCB_SHCSR_NMIACT_Msk (1UL << SCB_SHCSR_NMIACT_Pos) /*!< SCB SHCSR: NMIACT Mask */ + +#define SCB_SHCSR_SECUREFAULTACT_Pos 4U /*!< SCB SHCSR: SECUREFAULTACT Position */ +#define SCB_SHCSR_SECUREFAULTACT_Msk (1UL << SCB_SHCSR_SECUREFAULTACT_Pos) /*!< SCB SHCSR: SECUREFAULTACT Mask */ + +#define SCB_SHCSR_USGFAULTACT_Pos 3U /*!< SCB SHCSR: USGFAULTACT Position */ +#define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */ + +#define SCB_SHCSR_HARDFAULTACT_Pos 2U /*!< SCB SHCSR: HARDFAULTACT Position */ +#define SCB_SHCSR_HARDFAULTACT_Msk (1UL << SCB_SHCSR_HARDFAULTACT_Pos) /*!< SCB SHCSR: HARDFAULTACT Mask */ + +#define SCB_SHCSR_BUSFAULTACT_Pos 1U /*!< SCB SHCSR: BUSFAULTACT Position */ +#define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */ + +#define SCB_SHCSR_MEMFAULTACT_Pos 0U /*!< SCB SHCSR: MEMFAULTACT Position */ +#define SCB_SHCSR_MEMFAULTACT_Msk (1UL /*<< SCB_SHCSR_MEMFAULTACT_Pos*/) /*!< SCB SHCSR: MEMFAULTACT Mask */ + +/* SCB Configurable Fault Status Register Definitions */ +#define SCB_CFSR_USGFAULTSR_Pos 16U /*!< SCB CFSR: Usage Fault Status Register Position */ +#define SCB_CFSR_USGFAULTSR_Msk (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */ + +#define SCB_CFSR_BUSFAULTSR_Pos 8U /*!< SCB CFSR: Bus Fault Status Register Position */ +#define SCB_CFSR_BUSFAULTSR_Msk (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */ + +#define SCB_CFSR_MEMFAULTSR_Pos 0U /*!< SCB CFSR: Memory Manage Fault Status Register Position */ +#define SCB_CFSR_MEMFAULTSR_Msk (0xFFUL /*<< SCB_CFSR_MEMFAULTSR_Pos*/) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */ + +/* MemManage Fault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_MMARVALID_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 7U) /*!< SCB CFSR (MMFSR): MMARVALID Position */ +#define SCB_CFSR_MMARVALID_Msk (1UL << SCB_CFSR_MMARVALID_Pos) /*!< SCB CFSR (MMFSR): MMARVALID Mask */ + +#define SCB_CFSR_MLSPERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 5U) /*!< SCB CFSR (MMFSR): MLSPERR Position */ +#define SCB_CFSR_MLSPERR_Msk (1UL << SCB_CFSR_MLSPERR_Pos) /*!< SCB CFSR (MMFSR): MLSPERR Mask */ + +#define SCB_CFSR_MSTKERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 4U) /*!< SCB CFSR (MMFSR): MSTKERR Position */ +#define SCB_CFSR_MSTKERR_Msk (1UL << SCB_CFSR_MSTKERR_Pos) /*!< SCB CFSR (MMFSR): MSTKERR Mask */ + +#define SCB_CFSR_MUNSTKERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 3U) /*!< SCB CFSR (MMFSR): MUNSTKERR Position */ +#define SCB_CFSR_MUNSTKERR_Msk (1UL << SCB_CFSR_MUNSTKERR_Pos) /*!< SCB CFSR (MMFSR): MUNSTKERR Mask */ + +#define SCB_CFSR_DACCVIOL_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 1U) /*!< SCB CFSR (MMFSR): DACCVIOL Position */ +#define SCB_CFSR_DACCVIOL_Msk (1UL << SCB_CFSR_DACCVIOL_Pos) /*!< SCB CFSR (MMFSR): DACCVIOL Mask */ + +#define SCB_CFSR_IACCVIOL_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 0U) /*!< SCB CFSR (MMFSR): IACCVIOL Position */ +#define SCB_CFSR_IACCVIOL_Msk (1UL /*<< SCB_CFSR_IACCVIOL_Pos*/) /*!< SCB CFSR (MMFSR): IACCVIOL Mask */ + +/* BusFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_BFARVALID_Pos (SCB_CFSR_BUSFAULTSR_Pos + 7U) /*!< SCB CFSR (BFSR): BFARVALID Position */ +#define SCB_CFSR_BFARVALID_Msk (1UL << SCB_CFSR_BFARVALID_Pos) /*!< SCB CFSR (BFSR): BFARVALID Mask */ + +#define SCB_CFSR_LSPERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 5U) /*!< SCB CFSR (BFSR): LSPERR Position */ +#define SCB_CFSR_LSPERR_Msk (1UL << SCB_CFSR_LSPERR_Pos) /*!< SCB CFSR (BFSR): LSPERR Mask */ + +#define SCB_CFSR_STKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 4U) /*!< SCB CFSR (BFSR): STKERR Position */ +#define SCB_CFSR_STKERR_Msk (1UL << SCB_CFSR_STKERR_Pos) /*!< SCB CFSR (BFSR): STKERR Mask */ + +#define SCB_CFSR_UNSTKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 3U) /*!< SCB CFSR (BFSR): UNSTKERR Position */ +#define SCB_CFSR_UNSTKERR_Msk (1UL << SCB_CFSR_UNSTKERR_Pos) /*!< SCB CFSR (BFSR): UNSTKERR Mask */ + +#define SCB_CFSR_IMPRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 2U) /*!< SCB CFSR (BFSR): IMPRECISERR Position */ +#define SCB_CFSR_IMPRECISERR_Msk (1UL << SCB_CFSR_IMPRECISERR_Pos) /*!< SCB CFSR (BFSR): IMPRECISERR Mask */ + +#define SCB_CFSR_PRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 1U) /*!< SCB CFSR (BFSR): PRECISERR Position */ +#define SCB_CFSR_PRECISERR_Msk (1UL << SCB_CFSR_PRECISERR_Pos) /*!< SCB CFSR (BFSR): PRECISERR Mask */ + +#define SCB_CFSR_IBUSERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 0U) /*!< SCB CFSR (BFSR): IBUSERR Position */ +#define SCB_CFSR_IBUSERR_Msk (1UL << SCB_CFSR_IBUSERR_Pos) /*!< SCB CFSR (BFSR): IBUSERR Mask */ + +/* UsageFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_DIVBYZERO_Pos (SCB_CFSR_USGFAULTSR_Pos + 9U) /*!< SCB CFSR (UFSR): DIVBYZERO Position */ +#define SCB_CFSR_DIVBYZERO_Msk (1UL << SCB_CFSR_DIVBYZERO_Pos) /*!< SCB CFSR (UFSR): DIVBYZERO Mask */ + +#define SCB_CFSR_UNALIGNED_Pos (SCB_CFSR_USGFAULTSR_Pos + 8U) /*!< SCB CFSR (UFSR): UNALIGNED Position */ +#define SCB_CFSR_UNALIGNED_Msk (1UL << SCB_CFSR_UNALIGNED_Pos) /*!< SCB CFSR (UFSR): UNALIGNED Mask */ + +#define SCB_CFSR_STKOF_Pos (SCB_CFSR_USGFAULTSR_Pos + 4U) /*!< SCB CFSR (UFSR): STKOF Position */ +#define SCB_CFSR_STKOF_Msk (1UL << SCB_CFSR_STKOF_Pos) /*!< SCB CFSR (UFSR): STKOF Mask */ + +#define SCB_CFSR_NOCP_Pos (SCB_CFSR_USGFAULTSR_Pos + 3U) /*!< SCB CFSR (UFSR): NOCP Position */ +#define SCB_CFSR_NOCP_Msk (1UL << SCB_CFSR_NOCP_Pos) /*!< SCB CFSR (UFSR): NOCP Mask */ + +#define SCB_CFSR_INVPC_Pos (SCB_CFSR_USGFAULTSR_Pos + 2U) /*!< SCB CFSR (UFSR): INVPC Position */ +#define SCB_CFSR_INVPC_Msk (1UL << SCB_CFSR_INVPC_Pos) /*!< SCB CFSR (UFSR): INVPC Mask */ + +#define SCB_CFSR_INVSTATE_Pos (SCB_CFSR_USGFAULTSR_Pos + 1U) /*!< SCB CFSR (UFSR): INVSTATE Position */ +#define SCB_CFSR_INVSTATE_Msk (1UL << SCB_CFSR_INVSTATE_Pos) /*!< SCB CFSR (UFSR): INVSTATE Mask */ + +#define SCB_CFSR_UNDEFINSTR_Pos (SCB_CFSR_USGFAULTSR_Pos + 0U) /*!< SCB CFSR (UFSR): UNDEFINSTR Position */ +#define SCB_CFSR_UNDEFINSTR_Msk (1UL << SCB_CFSR_UNDEFINSTR_Pos) /*!< SCB CFSR (UFSR): UNDEFINSTR Mask */ + +/* SCB Hard Fault Status Register Definitions */ +#define SCB_HFSR_DEBUGEVT_Pos 31U /*!< SCB HFSR: DEBUGEVT Position */ +#define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ + +#define SCB_HFSR_FORCED_Pos 30U /*!< SCB HFSR: FORCED Position */ +#define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */ + +#define SCB_HFSR_VECTTBL_Pos 1U /*!< SCB HFSR: VECTTBL Position */ +#define SCB_HFSR_VECTTBL_Msk (1UL << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */ + +/* SCB Debug Fault Status Register Definitions */ +#define SCB_DFSR_EXTERNAL_Pos 4U /*!< SCB DFSR: EXTERNAL Position */ +#define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */ + +#define SCB_DFSR_VCATCH_Pos 3U /*!< SCB DFSR: VCATCH Position */ +#define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */ + +#define SCB_DFSR_DWTTRAP_Pos 2U /*!< SCB DFSR: DWTTRAP Position */ +#define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */ + +#define SCB_DFSR_BKPT_Pos 1U /*!< SCB DFSR: BKPT Position */ +#define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */ + +#define SCB_DFSR_HALTED_Pos 0U /*!< SCB DFSR: HALTED Position */ +#define SCB_DFSR_HALTED_Msk (1UL /*<< SCB_DFSR_HALTED_Pos*/) /*!< SCB DFSR: HALTED Mask */ + +/* SCB Non-Secure Access Control Register Definitions */ +#define SCB_NSACR_CP11_Pos 11U /*!< SCB NSACR: CP11 Position */ +#define SCB_NSACR_CP11_Msk (1UL << SCB_NSACR_CP11_Pos) /*!< SCB NSACR: CP11 Mask */ + +#define SCB_NSACR_CP10_Pos 10U /*!< SCB NSACR: CP10 Position */ +#define SCB_NSACR_CP10_Msk (1UL << SCB_NSACR_CP10_Pos) /*!< SCB NSACR: CP10 Mask */ + +#define SCB_NSACR_CPn_Pos 0U /*!< SCB NSACR: CPn Position */ +#define SCB_NSACR_CPn_Msk (1UL /*<< SCB_NSACR_CPn_Pos*/) /*!< SCB NSACR: CPn Mask */ + +/* SCB Cache Level ID Register Definitions */ +#define SCB_CLIDR_LOUU_Pos 27U /*!< SCB CLIDR: LoUU Position */ +#define SCB_CLIDR_LOUU_Msk (7UL << SCB_CLIDR_LOUU_Pos) /*!< SCB CLIDR: LoUU Mask */ + +#define SCB_CLIDR_LOC_Pos 24U /*!< SCB CLIDR: LoC Position */ +#define SCB_CLIDR_LOC_Msk (7UL << SCB_CLIDR_LOC_Pos) /*!< SCB CLIDR: LoC Mask */ + +/* SCB Cache Type Register Definitions */ +#define SCB_CTR_FORMAT_Pos 29U /*!< SCB CTR: Format Position */ +#define SCB_CTR_FORMAT_Msk (7UL << SCB_CTR_FORMAT_Pos) /*!< SCB CTR: Format Mask */ + +#define SCB_CTR_CWG_Pos 24U /*!< SCB CTR: CWG Position */ +#define SCB_CTR_CWG_Msk (0xFUL << SCB_CTR_CWG_Pos) /*!< SCB CTR: CWG Mask */ + +#define SCB_CTR_ERG_Pos 20U /*!< SCB CTR: ERG Position */ +#define SCB_CTR_ERG_Msk (0xFUL << SCB_CTR_ERG_Pos) /*!< SCB CTR: ERG Mask */ + +#define SCB_CTR_DMINLINE_Pos 16U /*!< SCB CTR: DminLine Position */ +#define SCB_CTR_DMINLINE_Msk (0xFUL << SCB_CTR_DMINLINE_Pos) /*!< SCB CTR: DminLine Mask */ + +#define SCB_CTR_IMINLINE_Pos 0U /*!< SCB CTR: ImInLine Position */ +#define SCB_CTR_IMINLINE_Msk (0xFUL /*<< SCB_CTR_IMINLINE_Pos*/) /*!< SCB CTR: ImInLine Mask */ + +/* SCB Cache Size ID Register Definitions */ +#define SCB_CCSIDR_WT_Pos 31U /*!< SCB CCSIDR: WT Position */ +#define SCB_CCSIDR_WT_Msk (1UL << SCB_CCSIDR_WT_Pos) /*!< SCB CCSIDR: WT Mask */ + +#define SCB_CCSIDR_WB_Pos 30U /*!< SCB CCSIDR: WB Position */ +#define SCB_CCSIDR_WB_Msk (1UL << SCB_CCSIDR_WB_Pos) /*!< SCB CCSIDR: WB Mask */ + +#define SCB_CCSIDR_RA_Pos 29U /*!< SCB CCSIDR: RA Position */ +#define SCB_CCSIDR_RA_Msk (1UL << SCB_CCSIDR_RA_Pos) /*!< SCB CCSIDR: RA Mask */ + +#define SCB_CCSIDR_WA_Pos 28U /*!< SCB CCSIDR: WA Position */ +#define SCB_CCSIDR_WA_Msk (1UL << SCB_CCSIDR_WA_Pos) /*!< SCB CCSIDR: WA Mask */ + +#define SCB_CCSIDR_NUMSETS_Pos 13U /*!< SCB CCSIDR: NumSets Position */ +#define SCB_CCSIDR_NUMSETS_Msk (0x7FFFUL << SCB_CCSIDR_NUMSETS_Pos) /*!< SCB CCSIDR: NumSets Mask */ + +#define SCB_CCSIDR_ASSOCIATIVITY_Pos 3U /*!< SCB CCSIDR: Associativity Position */ +#define SCB_CCSIDR_ASSOCIATIVITY_Msk (0x3FFUL << SCB_CCSIDR_ASSOCIATIVITY_Pos) /*!< SCB CCSIDR: Associativity Mask */ + +#define SCB_CCSIDR_LINESIZE_Pos 0U /*!< SCB CCSIDR: LineSize Position */ +#define SCB_CCSIDR_LINESIZE_Msk (7UL /*<< SCB_CCSIDR_LINESIZE_Pos*/) /*!< SCB CCSIDR: LineSize Mask */ + +/* SCB Cache Size Selection Register Definitions */ +#define SCB_CSSELR_LEVEL_Pos 1U /*!< SCB CSSELR: Level Position */ +#define SCB_CSSELR_LEVEL_Msk (7UL << SCB_CSSELR_LEVEL_Pos) /*!< SCB CSSELR: Level Mask */ + +#define SCB_CSSELR_IND_Pos 0U /*!< SCB CSSELR: InD Position */ +#define SCB_CSSELR_IND_Msk (1UL /*<< SCB_CSSELR_IND_Pos*/) /*!< SCB CSSELR: InD Mask */ + +/* SCB Software Triggered Interrupt Register Definitions */ +#define SCB_STIR_INTID_Pos 0U /*!< SCB STIR: INTID Position */ +#define SCB_STIR_INTID_Msk (0x1FFUL /*<< SCB_STIR_INTID_Pos*/) /*!< SCB STIR: INTID Mask */ + +/* SCB D-Cache Invalidate by Set-way Register Definitions */ +#define SCB_DCISW_WAY_Pos 30U /*!< SCB DCISW: Way Position */ +#define SCB_DCISW_WAY_Msk (3UL << SCB_DCISW_WAY_Pos) /*!< SCB DCISW: Way Mask */ + +#define SCB_DCISW_SET_Pos 5U /*!< SCB DCISW: Set Position */ +#define SCB_DCISW_SET_Msk (0x1FFUL << SCB_DCISW_SET_Pos) /*!< SCB DCISW: Set Mask */ + +/* SCB D-Cache Clean by Set-way Register Definitions */ +#define SCB_DCCSW_WAY_Pos 30U /*!< SCB DCCSW: Way Position */ +#define SCB_DCCSW_WAY_Msk (3UL << SCB_DCCSW_WAY_Pos) /*!< SCB DCCSW: Way Mask */ + +#define SCB_DCCSW_SET_Pos 5U /*!< SCB DCCSW: Set Position */ +#define SCB_DCCSW_SET_Msk (0x1FFUL << SCB_DCCSW_SET_Pos) /*!< SCB DCCSW: Set Mask */ + +/* SCB D-Cache Clean and Invalidate by Set-way Register Definitions */ +#define SCB_DCCISW_WAY_Pos 30U /*!< SCB DCCISW: Way Position */ +#define SCB_DCCISW_WAY_Msk (3UL << SCB_DCCISW_WAY_Pos) /*!< SCB DCCISW: Way Mask */ + +#define SCB_DCCISW_SET_Pos 5U /*!< SCB DCCISW: Set Position */ +#define SCB_DCCISW_SET_Msk (0x1FFUL << SCB_DCCISW_SET_Pos) /*!< SCB DCCISW: Set Mask */ + +/* Instruction Tightly-Coupled Memory Control Register Definitions */ +#define SCB_ITCMCR_SZ_Pos 3U /*!< SCB ITCMCR: SZ Position */ +#define SCB_ITCMCR_SZ_Msk (0xFUL << SCB_ITCMCR_SZ_Pos) /*!< SCB ITCMCR: SZ Mask */ + +#define SCB_ITCMCR_RETEN_Pos 2U /*!< SCB ITCMCR: RETEN Position */ +#define SCB_ITCMCR_RETEN_Msk (1UL << SCB_ITCMCR_RETEN_Pos) /*!< SCB ITCMCR: RETEN Mask */ + +#define SCB_ITCMCR_RMW_Pos 1U /*!< SCB ITCMCR: RMW Position */ +#define SCB_ITCMCR_RMW_Msk (1UL << SCB_ITCMCR_RMW_Pos) /*!< SCB ITCMCR: RMW Mask */ + +#define SCB_ITCMCR_EN_Pos 0U /*!< SCB ITCMCR: EN Position */ +#define SCB_ITCMCR_EN_Msk (1UL /*<< SCB_ITCMCR_EN_Pos*/) /*!< SCB ITCMCR: EN Mask */ + +/* Data Tightly-Coupled Memory Control Register Definitions */ +#define SCB_DTCMCR_SZ_Pos 3U /*!< SCB DTCMCR: SZ Position */ +#define SCB_DTCMCR_SZ_Msk (0xFUL << SCB_DTCMCR_SZ_Pos) /*!< SCB DTCMCR: SZ Mask */ + +#define SCB_DTCMCR_RETEN_Pos 2U /*!< SCB DTCMCR: RETEN Position */ +#define SCB_DTCMCR_RETEN_Msk (1UL << SCB_DTCMCR_RETEN_Pos) /*!< SCB DTCMCR: RETEN Mask */ + +#define SCB_DTCMCR_RMW_Pos 1U /*!< SCB DTCMCR: RMW Position */ +#define SCB_DTCMCR_RMW_Msk (1UL << SCB_DTCMCR_RMW_Pos) /*!< SCB DTCMCR: RMW Mask */ + +#define SCB_DTCMCR_EN_Pos 0U /*!< SCB DTCMCR: EN Position */ +#define SCB_DTCMCR_EN_Msk (1UL /*<< SCB_DTCMCR_EN_Pos*/) /*!< SCB DTCMCR: EN Mask */ + +/* AHBP Control Register Definitions */ +#define SCB_AHBPCR_SZ_Pos 1U /*!< SCB AHBPCR: SZ Position */ +#define SCB_AHBPCR_SZ_Msk (7UL << SCB_AHBPCR_SZ_Pos) /*!< SCB AHBPCR: SZ Mask */ + +#define SCB_AHBPCR_EN_Pos 0U /*!< SCB AHBPCR: EN Position */ +#define SCB_AHBPCR_EN_Msk (1UL /*<< SCB_AHBPCR_EN_Pos*/) /*!< SCB AHBPCR: EN Mask */ + +/* L1 Cache Control Register Definitions */ +#define SCB_CACR_FORCEWT_Pos 2U /*!< SCB CACR: FORCEWT Position */ +#define SCB_CACR_FORCEWT_Msk (1UL << SCB_CACR_FORCEWT_Pos) /*!< SCB CACR: FORCEWT Mask */ + +#define SCB_CACR_ECCEN_Pos 1U /*!< SCB CACR: ECCEN Position */ +#define SCB_CACR_ECCEN_Msk (1UL << SCB_CACR_ECCEN_Pos) /*!< SCB CACR: ECCEN Mask */ + +#define SCB_CACR_SIWT_Pos 0U /*!< SCB CACR: SIWT Position */ +#define SCB_CACR_SIWT_Msk (1UL /*<< SCB_CACR_SIWT_Pos*/) /*!< SCB CACR: SIWT Mask */ + +/* AHBS Control Register Definitions */ +#define SCB_AHBSCR_INITCOUNT_Pos 11U /*!< SCB AHBSCR: INITCOUNT Position */ +#define SCB_AHBSCR_INITCOUNT_Msk (0x1FUL << SCB_AHBPCR_INITCOUNT_Pos) /*!< SCB AHBSCR: INITCOUNT Mask */ + +#define SCB_AHBSCR_TPRI_Pos 2U /*!< SCB AHBSCR: TPRI Position */ +#define SCB_AHBSCR_TPRI_Msk (0x1FFUL << SCB_AHBPCR_TPRI_Pos) /*!< SCB AHBSCR: TPRI Mask */ + +#define SCB_AHBSCR_CTL_Pos 0U /*!< SCB AHBSCR: CTL Position*/ +#define SCB_AHBSCR_CTL_Msk (3UL /*<< SCB_AHBPCR_CTL_Pos*/) /*!< SCB AHBSCR: CTL Mask */ + +/* Auxiliary Bus Fault Status Register Definitions */ +#define SCB_ABFSR_AXIMTYPE_Pos 8U /*!< SCB ABFSR: AXIMTYPE Position*/ +#define SCB_ABFSR_AXIMTYPE_Msk (3UL << SCB_ABFSR_AXIMTYPE_Pos) /*!< SCB ABFSR: AXIMTYPE Mask */ + +#define SCB_ABFSR_EPPB_Pos 4U /*!< SCB ABFSR: EPPB Position*/ +#define SCB_ABFSR_EPPB_Msk (1UL << SCB_ABFSR_EPPB_Pos) /*!< SCB ABFSR: EPPB Mask */ + +#define SCB_ABFSR_AXIM_Pos 3U /*!< SCB ABFSR: AXIM Position*/ +#define SCB_ABFSR_AXIM_Msk (1UL << SCB_ABFSR_AXIM_Pos) /*!< SCB ABFSR: AXIM Mask */ + +#define SCB_ABFSR_AHBP_Pos 2U /*!< SCB ABFSR: AHBP Position*/ +#define SCB_ABFSR_AHBP_Msk (1UL << SCB_ABFSR_AHBP_Pos) /*!< SCB ABFSR: AHBP Mask */ + +#define SCB_ABFSR_DTCM_Pos 1U /*!< SCB ABFSR: DTCM Position*/ +#define SCB_ABFSR_DTCM_Msk (1UL << SCB_ABFSR_DTCM_Pos) /*!< SCB ABFSR: DTCM Mask */ + +#define SCB_ABFSR_ITCM_Pos 0U /*!< SCB ABFSR: ITCM Position*/ +#define SCB_ABFSR_ITCM_Msk (1UL /*<< SCB_ABFSR_ITCM_Pos*/) /*!< SCB ABFSR: ITCM Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) + \brief Type definitions for the System Control and ID Register not in the SCB + @{ + */ + +/** + \brief Structure type to access the System Control and ID Register not in the SCB. + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IM uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ + __IOM uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ + __IOM uint32_t CPPWR; /*!< Offset: 0x00C (R/W) Coprocessor Power Control Register */ +} SCnSCB_Type; + +/* Interrupt Controller Type Register Definitions */ +#define SCnSCB_ICTR_INTLINESNUM_Pos 0U /*!< ICTR: INTLINESNUM Position */ +#define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL /*<< SCnSCB_ICTR_INTLINESNUM_Pos*/) /*!< ICTR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_SCnotSCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_ITM Instrumentation Trace Macrocell (ITM) + \brief Type definitions for the Instrumentation Trace Macrocell (ITM) + @{ + */ + +/** + \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM). + */ +typedef struct +{ + __OM union + { + __OM uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ + __OM uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ + __OM uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ + } PORT [32U]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ + uint32_t RESERVED0[864U]; + __IOM uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ + uint32_t RESERVED1[15U]; + __IOM uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ + uint32_t RESERVED2[15U]; + __IOM uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ + uint32_t RESERVED3[29U]; + __OM uint32_t IWR; /*!< Offset: 0xEF8 ( /W) ITM Integration Write Register */ + __IM uint32_t IRR; /*!< Offset: 0xEFC (R/ ) ITM Integration Read Register */ + __IOM uint32_t IMCR; /*!< Offset: 0xF00 (R/W) ITM Integration Mode Control Register */ + uint32_t RESERVED4[43U]; + __OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */ + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */ + uint32_t RESERVED5[1U]; + __IM uint32_t DEVARCH; /*!< Offset: 0xFBC (R/ ) ITM Device Architecture Register */ + uint32_t RESERVED6[4U]; + __IM uint32_t PID4; /*!< Offset: 0xFD0 (R/ ) ITM Peripheral Identification Register #4 */ + __IM uint32_t PID5; /*!< Offset: 0xFD4 (R/ ) ITM Peripheral Identification Register #5 */ + __IM uint32_t PID6; /*!< Offset: 0xFD8 (R/ ) ITM Peripheral Identification Register #6 */ + __IM uint32_t PID7; /*!< Offset: 0xFDC (R/ ) ITM Peripheral Identification Register #7 */ + __IM uint32_t PID0; /*!< Offset: 0xFE0 (R/ ) ITM Peripheral Identification Register #0 */ + __IM uint32_t PID1; /*!< Offset: 0xFE4 (R/ ) ITM Peripheral Identification Register #1 */ + __IM uint32_t PID2; /*!< Offset: 0xFE8 (R/ ) ITM Peripheral Identification Register #2 */ + __IM uint32_t PID3; /*!< Offset: 0xFEC (R/ ) ITM Peripheral Identification Register #3 */ + __IM uint32_t CID0; /*!< Offset: 0xFF0 (R/ ) ITM Component Identification Register #0 */ + __IM uint32_t CID1; /*!< Offset: 0xFF4 (R/ ) ITM Component Identification Register #1 */ + __IM uint32_t CID2; /*!< Offset: 0xFF8 (R/ ) ITM Component Identification Register #2 */ + __IM uint32_t CID3; /*!< Offset: 0xFFC (R/ ) ITM Component Identification Register #3 */ +} ITM_Type; + +/* ITM Stimulus Port Register Definitions */ +#define ITM_STIM_DISABLED_Pos 1U /*!< ITM STIM: DISABLED Position */ +#define ITM_STIM_DISABLED_Msk (0x1UL << ITM_STIM_DISABLED_Pos) /*!< ITM STIM: DISABLED Mask */ + +#define ITM_STIM_FIFOREADY_Pos 0U /*!< ITM STIM: FIFOREADY Position */ +#define ITM_STIM_FIFOREADY_Msk (0x1UL /*<< ITM_STIM_FIFOREADY_Pos*/) /*!< ITM STIM: FIFOREADY Mask */ + +/* ITM Trace Privilege Register Definitions */ +#define ITM_TPR_PRIVMASK_Pos 0U /*!< ITM TPR: PRIVMASK Position */ +#define ITM_TPR_PRIVMASK_Msk (0xFFFFFFFFUL /*<< ITM_TPR_PRIVMASK_Pos*/) /*!< ITM TPR: PRIVMASK Mask */ + +/* ITM Trace Control Register Definitions */ +#define ITM_TCR_BUSY_Pos 23U /*!< ITM TCR: BUSY Position */ +#define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */ + +#define ITM_TCR_TRACEBUSID_Pos 16U /*!< ITM TCR: ATBID Position */ +#define ITM_TCR_TRACEBUSID_Msk (0x7FUL << ITM_TCR_TRACEBUSID_Pos) /*!< ITM TCR: ATBID Mask */ + +#define ITM_TCR_GTSFREQ_Pos 10U /*!< ITM TCR: Global timestamp frequency Position */ +#define ITM_TCR_GTSFREQ_Msk (3UL << ITM_TCR_GTSFREQ_Pos) /*!< ITM TCR: Global timestamp frequency Mask */ + +#define ITM_TCR_TSPRESCALE_Pos 8U /*!< ITM TCR: TSPRESCALE Position */ +#define ITM_TCR_TSPRESCALE_Msk (3UL << ITM_TCR_TSPRESCALE_Pos) /*!< ITM TCR: TSPRESCALE Mask */ + +#define ITM_TCR_STALLENA_Pos 5U /*!< ITM TCR: STALLENA Position */ +#define ITM_TCR_STALLENA_Msk (1UL << ITM_TCR_STALLENA_Pos) /*!< ITM TCR: STALLENA Mask */ + +#define ITM_TCR_SWOENA_Pos 4U /*!< ITM TCR: SWOENA Position */ +#define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */ + +#define ITM_TCR_DWTENA_Pos 3U /*!< ITM TCR: DWTENA Position */ +#define ITM_TCR_DWTENA_Msk (1UL << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */ + +#define ITM_TCR_SYNCENA_Pos 2U /*!< ITM TCR: SYNCENA Position */ +#define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */ + +#define ITM_TCR_TSENA_Pos 1U /*!< ITM TCR: TSENA Position */ +#define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */ + +#define ITM_TCR_ITMENA_Pos 0U /*!< ITM TCR: ITM Enable bit Position */ +#define ITM_TCR_ITMENA_Msk (1UL /*<< ITM_TCR_ITMENA_Pos*/) /*!< ITM TCR: ITM Enable bit Mask */ + +/* ITM Integration Write Register Definitions */ +#define ITM_IWR_ATVALIDM_Pos 0U /*!< ITM IWR: ATVALIDM Position */ +#define ITM_IWR_ATVALIDM_Msk (1UL /*<< ITM_IWR_ATVALIDM_Pos*/) /*!< ITM IWR: ATVALIDM Mask */ + +/* ITM Integration Read Register Definitions */ +#define ITM_IRR_ATREADYM_Pos 0U /*!< ITM IRR: ATREADYM Position */ +#define ITM_IRR_ATREADYM_Msk (1UL /*<< ITM_IRR_ATREADYM_Pos*/) /*!< ITM IRR: ATREADYM Mask */ + +/* ITM Integration Mode Control Register Definitions */ +#define ITM_IMCR_INTEGRATION_Pos 0U /*!< ITM IMCR: INTEGRATION Position */ +#define ITM_IMCR_INTEGRATION_Msk (1UL /*<< ITM_IMCR_INTEGRATION_Pos*/) /*!< ITM IMCR: INTEGRATION Mask */ + +/* ITM Lock Status Register Definitions */ +#define ITM_LSR_ByteAcc_Pos 2U /*!< ITM LSR: ByteAcc Position */ +#define ITM_LSR_ByteAcc_Msk (1UL << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */ + +#define ITM_LSR_Access_Pos 1U /*!< ITM LSR: Access Position */ +#define ITM_LSR_Access_Msk (1UL << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */ + +#define ITM_LSR_Present_Pos 0U /*!< ITM LSR: Present Position */ +#define ITM_LSR_Present_Msk (1UL /*<< ITM_LSR_Present_Pos*/) /*!< ITM LSR: Present Mask */ + +/*@}*/ /* end of group CMSIS_ITM */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) + \brief Type definitions for the Data Watchpoint and Trace (DWT) + @{ + */ + +/** + \brief Structure type to access the Data Watchpoint and Trace Register (DWT). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ + __IOM uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */ + __IOM uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */ + __IOM uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */ + __IOM uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */ + __IOM uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */ + __IOM uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */ + __IM uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ + __IOM uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ + uint32_t RESERVED1[1U]; + __IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ + uint32_t RESERVED2[1U]; + __IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ + uint32_t RESERVED3[1U]; + __IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ + uint32_t RESERVED4[1U]; + __IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ + uint32_t RESERVED5[1U]; + __IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ + uint32_t RESERVED6[1U]; + __IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ + uint32_t RESERVED7[1U]; + __IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ + uint32_t RESERVED8[1U]; + __IOM uint32_t COMP4; /*!< Offset: 0x060 (R/W) Comparator Register 4 */ + uint32_t RESERVED9[1U]; + __IOM uint32_t FUNCTION4; /*!< Offset: 0x068 (R/W) Function Register 4 */ + uint32_t RESERVED10[1U]; + __IOM uint32_t COMP5; /*!< Offset: 0x070 (R/W) Comparator Register 5 */ + uint32_t RESERVED11[1U]; + __IOM uint32_t FUNCTION5; /*!< Offset: 0x078 (R/W) Function Register 5 */ + uint32_t RESERVED12[1U]; + __IOM uint32_t COMP6; /*!< Offset: 0x080 (R/W) Comparator Register 6 */ + uint32_t RESERVED13[1U]; + __IOM uint32_t FUNCTION6; /*!< Offset: 0x088 (R/W) Function Register 6 */ + uint32_t RESERVED14[1U]; + __IOM uint32_t COMP7; /*!< Offset: 0x090 (R/W) Comparator Register 7 */ + uint32_t RESERVED15[1U]; + __IOM uint32_t FUNCTION7; /*!< Offset: 0x098 (R/W) Function Register 7 */ + uint32_t RESERVED16[1U]; + __IOM uint32_t COMP8; /*!< Offset: 0x0A0 (R/W) Comparator Register 8 */ + uint32_t RESERVED17[1U]; + __IOM uint32_t FUNCTION8; /*!< Offset: 0x0A8 (R/W) Function Register 8 */ + uint32_t RESERVED18[1U]; + __IOM uint32_t COMP9; /*!< Offset: 0x0B0 (R/W) Comparator Register 9 */ + uint32_t RESERVED19[1U]; + __IOM uint32_t FUNCTION9; /*!< Offset: 0x0B8 (R/W) Function Register 9 */ + uint32_t RESERVED20[1U]; + __IOM uint32_t COMP10; /*!< Offset: 0x0C0 (R/W) Comparator Register 10 */ + uint32_t RESERVED21[1U]; + __IOM uint32_t FUNCTION10; /*!< Offset: 0x0C8 (R/W) Function Register 10 */ + uint32_t RESERVED22[1U]; + __IOM uint32_t COMP11; /*!< Offset: 0x0D0 (R/W) Comparator Register 11 */ + uint32_t RESERVED23[1U]; + __IOM uint32_t FUNCTION11; /*!< Offset: 0x0D8 (R/W) Function Register 11 */ + uint32_t RESERVED24[1U]; + __IOM uint32_t COMP12; /*!< Offset: 0x0E0 (R/W) Comparator Register 12 */ + uint32_t RESERVED25[1U]; + __IOM uint32_t FUNCTION12; /*!< Offset: 0x0E8 (R/W) Function Register 12 */ + uint32_t RESERVED26[1U]; + __IOM uint32_t COMP13; /*!< Offset: 0x0F0 (R/W) Comparator Register 13 */ + uint32_t RESERVED27[1U]; + __IOM uint32_t FUNCTION13; /*!< Offset: 0x0F8 (R/W) Function Register 13 */ + uint32_t RESERVED28[1U]; + __IOM uint32_t COMP14; /*!< Offset: 0x100 (R/W) Comparator Register 14 */ + uint32_t RESERVED29[1U]; + __IOM uint32_t FUNCTION14; /*!< Offset: 0x108 (R/W) Function Register 14 */ + uint32_t RESERVED30[1U]; + __IOM uint32_t COMP15; /*!< Offset: 0x110 (R/W) Comparator Register 15 */ + uint32_t RESERVED31[1U]; + __IOM uint32_t FUNCTION15; /*!< Offset: 0x118 (R/W) Function Register 15 */ + uint32_t RESERVED32[934U]; + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R ) Lock Status Register */ + uint32_t RESERVED33[1U]; + __IM uint32_t DEVARCH; /*!< Offset: 0xFBC (R/ ) Device Architecture Register */ +} DWT_Type; + +/* DWT Control Register Definitions */ +#define DWT_CTRL_NUMCOMP_Pos 28U /*!< DWT CTRL: NUMCOMP Position */ +#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ + +#define DWT_CTRL_NOTRCPKT_Pos 27U /*!< DWT CTRL: NOTRCPKT Position */ +#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ + +#define DWT_CTRL_NOEXTTRIG_Pos 26U /*!< DWT CTRL: NOEXTTRIG Position */ +#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ + +#define DWT_CTRL_NOCYCCNT_Pos 25U /*!< DWT CTRL: NOCYCCNT Position */ +#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ + +#define DWT_CTRL_NOPRFCNT_Pos 24U /*!< DWT CTRL: NOPRFCNT Position */ +#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ + +#define DWT_CTRL_CYCDISS_Pos 23U /*!< DWT CTRL: CYCDISS Position */ +#define DWT_CTRL_CYCDISS_Msk (0x1UL << DWT_CTRL_CYCDISS_Pos) /*!< DWT CTRL: CYCDISS Mask */ + +#define DWT_CTRL_CYCEVTENA_Pos 22U /*!< DWT CTRL: CYCEVTENA Position */ +#define DWT_CTRL_CYCEVTENA_Msk (0x1UL << DWT_CTRL_CYCEVTENA_Pos) /*!< DWT CTRL: CYCEVTENA Mask */ + +#define DWT_CTRL_FOLDEVTENA_Pos 21U /*!< DWT CTRL: FOLDEVTENA Position */ +#define DWT_CTRL_FOLDEVTENA_Msk (0x1UL << DWT_CTRL_FOLDEVTENA_Pos) /*!< DWT CTRL: FOLDEVTENA Mask */ + +#define DWT_CTRL_LSUEVTENA_Pos 20U /*!< DWT CTRL: LSUEVTENA Position */ +#define DWT_CTRL_LSUEVTENA_Msk (0x1UL << DWT_CTRL_LSUEVTENA_Pos) /*!< DWT CTRL: LSUEVTENA Mask */ + +#define DWT_CTRL_SLEEPEVTENA_Pos 19U /*!< DWT CTRL: SLEEPEVTENA Position */ +#define DWT_CTRL_SLEEPEVTENA_Msk (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos) /*!< DWT CTRL: SLEEPEVTENA Mask */ + +#define DWT_CTRL_EXCEVTENA_Pos 18U /*!< DWT CTRL: EXCEVTENA Position */ +#define DWT_CTRL_EXCEVTENA_Msk (0x1UL << DWT_CTRL_EXCEVTENA_Pos) /*!< DWT CTRL: EXCEVTENA Mask */ + +#define DWT_CTRL_CPIEVTENA_Pos 17U /*!< DWT CTRL: CPIEVTENA Position */ +#define DWT_CTRL_CPIEVTENA_Msk (0x1UL << DWT_CTRL_CPIEVTENA_Pos) /*!< DWT CTRL: CPIEVTENA Mask */ + +#define DWT_CTRL_EXCTRCENA_Pos 16U /*!< DWT CTRL: EXCTRCENA Position */ +#define DWT_CTRL_EXCTRCENA_Msk (0x1UL << DWT_CTRL_EXCTRCENA_Pos) /*!< DWT CTRL: EXCTRCENA Mask */ + +#define DWT_CTRL_PCSAMPLENA_Pos 12U /*!< DWT CTRL: PCSAMPLENA Position */ +#define DWT_CTRL_PCSAMPLENA_Msk (0x1UL << DWT_CTRL_PCSAMPLENA_Pos) /*!< DWT CTRL: PCSAMPLENA Mask */ + +#define DWT_CTRL_SYNCTAP_Pos 10U /*!< DWT CTRL: SYNCTAP Position */ +#define DWT_CTRL_SYNCTAP_Msk (0x3UL << DWT_CTRL_SYNCTAP_Pos) /*!< DWT CTRL: SYNCTAP Mask */ + +#define DWT_CTRL_CYCTAP_Pos 9U /*!< DWT CTRL: CYCTAP Position */ +#define DWT_CTRL_CYCTAP_Msk (0x1UL << DWT_CTRL_CYCTAP_Pos) /*!< DWT CTRL: CYCTAP Mask */ + +#define DWT_CTRL_POSTINIT_Pos 5U /*!< DWT CTRL: POSTINIT Position */ +#define DWT_CTRL_POSTINIT_Msk (0xFUL << DWT_CTRL_POSTINIT_Pos) /*!< DWT CTRL: POSTINIT Mask */ + +#define DWT_CTRL_POSTPRESET_Pos 1U /*!< DWT CTRL: POSTPRESET Position */ +#define DWT_CTRL_POSTPRESET_Msk (0xFUL << DWT_CTRL_POSTPRESET_Pos) /*!< DWT CTRL: POSTPRESET Mask */ + +#define DWT_CTRL_CYCCNTENA_Pos 0U /*!< DWT CTRL: CYCCNTENA Position */ +#define DWT_CTRL_CYCCNTENA_Msk (0x1UL /*<< DWT_CTRL_CYCCNTENA_Pos*/) /*!< DWT CTRL: CYCCNTENA Mask */ + +/* DWT CPI Count Register Definitions */ +#define DWT_CPICNT_CPICNT_Pos 0U /*!< DWT CPICNT: CPICNT Position */ +#define DWT_CPICNT_CPICNT_Msk (0xFFUL /*<< DWT_CPICNT_CPICNT_Pos*/) /*!< DWT CPICNT: CPICNT Mask */ + +/* DWT Exception Overhead Count Register Definitions */ +#define DWT_EXCCNT_EXCCNT_Pos 0U /*!< DWT EXCCNT: EXCCNT Position */ +#define DWT_EXCCNT_EXCCNT_Msk (0xFFUL /*<< DWT_EXCCNT_EXCCNT_Pos*/) /*!< DWT EXCCNT: EXCCNT Mask */ + +/* DWT Sleep Count Register Definitions */ +#define DWT_SLEEPCNT_SLEEPCNT_Pos 0U /*!< DWT SLEEPCNT: SLEEPCNT Position */ +#define DWT_SLEEPCNT_SLEEPCNT_Msk (0xFFUL /*<< DWT_SLEEPCNT_SLEEPCNT_Pos*/) /*!< DWT SLEEPCNT: SLEEPCNT Mask */ + +/* DWT LSU Count Register Definitions */ +#define DWT_LSUCNT_LSUCNT_Pos 0U /*!< DWT LSUCNT: LSUCNT Position */ +#define DWT_LSUCNT_LSUCNT_Msk (0xFFUL /*<< DWT_LSUCNT_LSUCNT_Pos*/) /*!< DWT LSUCNT: LSUCNT Mask */ + +/* DWT Folded-instruction Count Register Definitions */ +#define DWT_FOLDCNT_FOLDCNT_Pos 0U /*!< DWT FOLDCNT: FOLDCNT Position */ +#define DWT_FOLDCNT_FOLDCNT_Msk (0xFFUL /*<< DWT_FOLDCNT_FOLDCNT_Pos*/) /*!< DWT FOLDCNT: FOLDCNT Mask */ + +/* DWT Comparator Function Register Definitions */ +#define DWT_FUNCTION_ID_Pos 27U /*!< DWT FUNCTION: ID Position */ +#define DWT_FUNCTION_ID_Msk (0x1FUL << DWT_FUNCTION_ID_Pos) /*!< DWT FUNCTION: ID Mask */ + +#define DWT_FUNCTION_MATCHED_Pos 24U /*!< DWT FUNCTION: MATCHED Position */ +#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ + +#define DWT_FUNCTION_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */ +#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ + +#define DWT_FUNCTION_ACTION_Pos 4U /*!< DWT FUNCTION: ACTION Position */ +#define DWT_FUNCTION_ACTION_Msk (0x1UL << DWT_FUNCTION_ACTION_Pos) /*!< DWT FUNCTION: ACTION Mask */ + +#define DWT_FUNCTION_MATCH_Pos 0U /*!< DWT FUNCTION: MATCH Position */ +#define DWT_FUNCTION_MATCH_Msk (0xFUL /*<< DWT_FUNCTION_MATCH_Pos*/) /*!< DWT FUNCTION: MATCH Mask */ + +/*@}*/ /* end of group CMSIS_DWT */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_TPI Trace Port Interface (TPI) + \brief Type definitions for the Trace Port Interface (TPI) + @{ + */ + +/** + \brief Structure type to access the Trace Port Interface Register (TPI). + */ +typedef struct +{ + __IM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ + __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ + uint32_t RESERVED0[2U]; + __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ + uint32_t RESERVED1[55U]; + __IOM uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ + uint32_t RESERVED2[131U]; + __IM uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ + __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ + __IOM uint32_t PSCR; /*!< Offset: 0x308 (R/W) Periodic Synchronization Control Register */ + uint32_t RESERVED3[759U]; + __IM uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER Register */ + __IM uint32_t ITFTTD0; /*!< Offset: 0xEEC (R/ ) Integration Test FIFO Test Data 0 Register */ + __IOM uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/W) Integration Test ATB Control Register 2 */ + uint32_t RESERVED4[1U]; + __IM uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) Integration Test ATB Control Register 0 */ + __IM uint32_t ITFTTD1; /*!< Offset: 0xEFC (R/ ) Integration Test FIFO Test Data 1 Register */ + __IOM uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */ + uint32_t RESERVED5[39U]; + __IOM uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */ + __IOM uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */ + uint32_t RESERVED7[8U]; + __IM uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) Device Configuration Register */ + __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) Device Type Identifier Register */ +} TPI_Type; + +/* TPI Asynchronous Clock Prescaler Register Definitions */ +#define TPI_ACPR_PRESCALER_Pos 0U /*!< TPI ACPR: PRESCALER Position */ +#define TPI_ACPR_PRESCALER_Msk (0x1FFFUL /*<< TPI_ACPR_PRESCALER_Pos*/) /*!< TPI ACPR: PRESCALER Mask */ + +/* TPI Selected Pin Protocol Register Definitions */ +#define TPI_SPPR_TXMODE_Pos 0U /*!< TPI SPPR: TXMODE Position */ +#define TPI_SPPR_TXMODE_Msk (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/) /*!< TPI SPPR: TXMODE Mask */ + +/* TPI Formatter and Flush Status Register Definitions */ +#define TPI_FFSR_FtNonStop_Pos 3U /*!< TPI FFSR: FtNonStop Position */ +#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ + +#define TPI_FFSR_TCPresent_Pos 2U /*!< TPI FFSR: TCPresent Position */ +#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ + +#define TPI_FFSR_FtStopped_Pos 1U /*!< TPI FFSR: FtStopped Position */ +#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ + +#define TPI_FFSR_FlInProg_Pos 0U /*!< TPI FFSR: FlInProg Position */ +#define TPI_FFSR_FlInProg_Msk (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/) /*!< TPI FFSR: FlInProg Mask */ + +/* TPI Formatter and Flush Control Register Definitions */ +#define TPI_FFCR_TrigIn_Pos 8U /*!< TPI FFCR: TrigIn Position */ +#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ + +#define TPI_FFCR_FOnMan_Pos 6U /*!< TPI FFCR: FOnMan Position */ +#define TPI_FFCR_FOnMan_Msk (0x1UL << TPI_FFCR_FOnMan_Pos) /*!< TPI FFCR: FOnMan Mask */ + +#define TPI_FFCR_EnFCont_Pos 1U /*!< TPI FFCR: EnFCont Position */ +#define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ + +/* TPI TRIGGER Register Definitions */ +#define TPI_TRIGGER_TRIGGER_Pos 0U /*!< TPI TRIGGER: TRIGGER Position */ +#define TPI_TRIGGER_TRIGGER_Msk (0x1UL /*<< TPI_TRIGGER_TRIGGER_Pos*/) /*!< TPI TRIGGER: TRIGGER Mask */ + +/* TPI Integration Test FIFO Test Data 0 Register Definitions */ +#define TPI_ITFTTD0_ATB_IF2_ATVALID_Pos 29U /*!< TPI ITFTTD0: ATB Interface 2 ATVALIDPosition */ +#define TPI_ITFTTD0_ATB_IF2_ATVALID_Msk (0x3UL << TPI_ITFTTD0_ATB_IF2_ATVALID_Pos) /*!< TPI ITFTTD0: ATB Interface 2 ATVALID Mask */ + +#define TPI_ITFTTD0_ATB_IF2_bytecount_Pos 27U /*!< TPI ITFTTD0: ATB Interface 2 byte count Position */ +#define TPI_ITFTTD0_ATB_IF2_bytecount_Msk (0x3UL << TPI_ITFTTD0_ATB_IF2_bytecount_Pos) /*!< TPI ITFTTD0: ATB Interface 2 byte count Mask */ + +#define TPI_ITFTTD0_ATB_IF1_ATVALID_Pos 26U /*!< TPI ITFTTD0: ATB Interface 1 ATVALID Position */ +#define TPI_ITFTTD0_ATB_IF1_ATVALID_Msk (0x3UL << TPI_ITFTTD0_ATB_IF1_ATVALID_Pos) /*!< TPI ITFTTD0: ATB Interface 1 ATVALID Mask */ + +#define TPI_ITFTTD0_ATB_IF1_bytecount_Pos 24U /*!< TPI ITFTTD0: ATB Interface 1 byte count Position */ +#define TPI_ITFTTD0_ATB_IF1_bytecount_Msk (0x3UL << TPI_ITFTTD0_ATB_IF1_bytecount_Pos) /*!< TPI ITFTTD0: ATB Interface 1 byte countt Mask */ + +#define TPI_ITFTTD0_ATB_IF1_data2_Pos 16U /*!< TPI ITFTTD0: ATB Interface 1 data2 Position */ +#define TPI_ITFTTD0_ATB_IF1_data2_Msk (0xFFUL << TPI_ITFTTD0_ATB_IF1_data1_Pos) /*!< TPI ITFTTD0: ATB Interface 1 data2 Mask */ + +#define TPI_ITFTTD0_ATB_IF1_data1_Pos 8U /*!< TPI ITFTTD0: ATB Interface 1 data1 Position */ +#define TPI_ITFTTD0_ATB_IF1_data1_Msk (0xFFUL << TPI_ITFTTD0_ATB_IF1_data1_Pos) /*!< TPI ITFTTD0: ATB Interface 1 data1 Mask */ + +#define TPI_ITFTTD0_ATB_IF1_data0_Pos 0U /*!< TPI ITFTTD0: ATB Interface 1 data0 Position */ +#define TPI_ITFTTD0_ATB_IF1_data0_Msk (0xFFUL /*<< TPI_ITFTTD0_ATB_IF1_data0_Pos*/) /*!< TPI ITFTTD0: ATB Interface 1 data0 Mask */ + +/* TPI Integration Test ATB Control Register 2 Register Definitions */ +#define TPI_ITATBCTR2_AFVALID2S_Pos 1U /*!< TPI ITATBCTR2: AFVALID2S Position */ +#define TPI_ITATBCTR2_AFVALID2S_Msk (0x1UL << TPI_ITATBCTR2_AFVALID2S_Pos) /*!< TPI ITATBCTR2: AFVALID2SS Mask */ + +#define TPI_ITATBCTR2_AFVALID1S_Pos 1U /*!< TPI ITATBCTR2: AFVALID1S Position */ +#define TPI_ITATBCTR2_AFVALID1S_Msk (0x1UL << TPI_ITATBCTR2_AFVALID1S_Pos) /*!< TPI ITATBCTR2: AFVALID1SS Mask */ + +#define TPI_ITATBCTR2_ATREADY2S_Pos 0U /*!< TPI ITATBCTR2: ATREADY2S Position */ +#define TPI_ITATBCTR2_ATREADY2S_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY2S_Pos*/) /*!< TPI ITATBCTR2: ATREADY2S Mask */ + +#define TPI_ITATBCTR2_ATREADY1S_Pos 0U /*!< TPI ITATBCTR2: ATREADY1S Position */ +#define TPI_ITATBCTR2_ATREADY1S_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY1S_Pos*/) /*!< TPI ITATBCTR2: ATREADY1S Mask */ + +/* TPI Integration Test FIFO Test Data 1 Register Definitions */ +#define TPI_ITFTTD1_ATB_IF2_ATVALID_Pos 29U /*!< TPI ITFTTD1: ATB Interface 2 ATVALID Position */ +#define TPI_ITFTTD1_ATB_IF2_ATVALID_Msk (0x3UL << TPI_ITFTTD1_ATB_IF2_ATVALID_Pos) /*!< TPI ITFTTD1: ATB Interface 2 ATVALID Mask */ + +#define TPI_ITFTTD1_ATB_IF2_bytecount_Pos 27U /*!< TPI ITFTTD1: ATB Interface 2 byte count Position */ +#define TPI_ITFTTD1_ATB_IF2_bytecount_Msk (0x3UL << TPI_ITFTTD1_ATB_IF2_bytecount_Pos) /*!< TPI ITFTTD1: ATB Interface 2 byte count Mask */ + +#define TPI_ITFTTD1_ATB_IF1_ATVALID_Pos 26U /*!< TPI ITFTTD1: ATB Interface 1 ATVALID Position */ +#define TPI_ITFTTD1_ATB_IF1_ATVALID_Msk (0x3UL << TPI_ITFTTD1_ATB_IF1_ATVALID_Pos) /*!< TPI ITFTTD1: ATB Interface 1 ATVALID Mask */ + +#define TPI_ITFTTD1_ATB_IF1_bytecount_Pos 24U /*!< TPI ITFTTD1: ATB Interface 1 byte count Position */ +#define TPI_ITFTTD1_ATB_IF1_bytecount_Msk (0x3UL << TPI_ITFTTD1_ATB_IF1_bytecount_Pos) /*!< TPI ITFTTD1: ATB Interface 1 byte countt Mask */ + +#define TPI_ITFTTD1_ATB_IF2_data2_Pos 16U /*!< TPI ITFTTD1: ATB Interface 2 data2 Position */ +#define TPI_ITFTTD1_ATB_IF2_data2_Msk (0xFFUL << TPI_ITFTTD1_ATB_IF2_data1_Pos) /*!< TPI ITFTTD1: ATB Interface 2 data2 Mask */ + +#define TPI_ITFTTD1_ATB_IF2_data1_Pos 8U /*!< TPI ITFTTD1: ATB Interface 2 data1 Position */ +#define TPI_ITFTTD1_ATB_IF2_data1_Msk (0xFFUL << TPI_ITFTTD1_ATB_IF2_data1_Pos) /*!< TPI ITFTTD1: ATB Interface 2 data1 Mask */ + +#define TPI_ITFTTD1_ATB_IF2_data0_Pos 0U /*!< TPI ITFTTD1: ATB Interface 2 data0 Position */ +#define TPI_ITFTTD1_ATB_IF2_data0_Msk (0xFFUL /*<< TPI_ITFTTD1_ATB_IF2_data0_Pos*/) /*!< TPI ITFTTD1: ATB Interface 2 data0 Mask */ + +/* TPI Integration Test ATB Control Register 0 Definitions */ +#define TPI_ITATBCTR0_AFVALID2S_Pos 1U /*!< TPI ITATBCTR0: AFVALID2S Position */ +#define TPI_ITATBCTR0_AFVALID2S_Msk (0x1UL << TPI_ITATBCTR0_AFVALID2S_Pos) /*!< TPI ITATBCTR0: AFVALID2SS Mask */ + +#define TPI_ITATBCTR0_AFVALID1S_Pos 1U /*!< TPI ITATBCTR0: AFVALID1S Position */ +#define TPI_ITATBCTR0_AFVALID1S_Msk (0x1UL << TPI_ITATBCTR0_AFVALID1S_Pos) /*!< TPI ITATBCTR0: AFVALID1SS Mask */ + +#define TPI_ITATBCTR0_ATREADY2S_Pos 0U /*!< TPI ITATBCTR0: ATREADY2S Position */ +#define TPI_ITATBCTR0_ATREADY2S_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY2S_Pos*/) /*!< TPI ITATBCTR0: ATREADY2S Mask */ + +#define TPI_ITATBCTR0_ATREADY1S_Pos 0U /*!< TPI ITATBCTR0: ATREADY1S Position */ +#define TPI_ITATBCTR0_ATREADY1S_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY1S_Pos*/) /*!< TPI ITATBCTR0: ATREADY1S Mask */ + +/* TPI Integration Mode Control Register Definitions */ +#define TPI_ITCTRL_Mode_Pos 0U /*!< TPI ITCTRL: Mode Position */ +#define TPI_ITCTRL_Mode_Msk (0x3UL /*<< TPI_ITCTRL_Mode_Pos*/) /*!< TPI ITCTRL: Mode Mask */ + +/* TPI DEVID Register Definitions */ +#define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */ +#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ + +#define TPI_DEVID_MANCVALID_Pos 10U /*!< TPI DEVID: MANCVALID Position */ +#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ + +#define TPI_DEVID_PTINVALID_Pos 9U /*!< TPI DEVID: PTINVALID Position */ +#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ + +#define TPI_DEVID_FIFOSZ_Pos 6U /*!< TPI DEVID: FIFOSZ Position */ +#define TPI_DEVID_FIFOSZ_Msk (0x7UL << TPI_DEVID_FIFOSZ_Pos) /*!< TPI DEVID: FIFOSZ Mask */ + +#define TPI_DEVID_NrTraceInput_Pos 0U /*!< TPI DEVID: NrTraceInput Position */ +#define TPI_DEVID_NrTraceInput_Msk (0x3FUL /*<< TPI_DEVID_NrTraceInput_Pos*/) /*!< TPI DEVID: NrTraceInput Mask */ + +/* TPI DEVTYPE Register Definitions */ +#define TPI_DEVTYPE_SubType_Pos 4U /*!< TPI DEVTYPE: SubType Position */ +#define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ + +#define TPI_DEVTYPE_MajorType_Pos 0U /*!< TPI DEVTYPE: MajorType Position */ +#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ + +/*@}*/ /* end of group CMSIS_TPI */ + + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** + \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region Number Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) MPU Region Limit Address Register */ + __IOM uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Region Base Address Register Alias 1 */ + __IOM uint32_t RLAR_A1; /*!< Offset: 0x018 (R/W) MPU Region Limit Address Register Alias 1 */ + __IOM uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Region Base Address Register Alias 2 */ + __IOM uint32_t RLAR_A2; /*!< Offset: 0x020 (R/W) MPU Region Limit Address Register Alias 2 */ + __IOM uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Region Base Address Register Alias 3 */ + __IOM uint32_t RLAR_A3; /*!< Offset: 0x028 (R/W) MPU Region Limit Address Register Alias 3 */ + uint32_t RESERVED0[1]; + union { + __IOM uint32_t MAIR[2]; + struct { + __IOM uint32_t MAIR0; /*!< Offset: 0x030 (R/W) MPU Memory Attribute Indirection Register 0 */ + __IOM uint32_t MAIR1; /*!< Offset: 0x034 (R/W) MPU Memory Attribute Indirection Register 1 */ + }; + }; +} MPU_Type; + +#define MPU_TYPE_RALIASES 4U + +/* MPU Type Register Definitions */ +#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register Definitions */ +#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register Definitions */ +#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register Definitions */ +#define MPU_RBAR_BASE_Pos 5U /*!< MPU RBAR: BASE Position */ +#define MPU_RBAR_BASE_Msk (0x7FFFFFFUL << MPU_RBAR_BASE_Pos) /*!< MPU RBAR: BASE Mask */ + +#define MPU_RBAR_SH_Pos 3U /*!< MPU RBAR: SH Position */ +#define MPU_RBAR_SH_Msk (0x3UL << MPU_RBAR_SH_Pos) /*!< MPU RBAR: SH Mask */ + +#define MPU_RBAR_AP_Pos 1U /*!< MPU RBAR: AP Position */ +#define MPU_RBAR_AP_Msk (0x3UL << MPU_RBAR_AP_Pos) /*!< MPU RBAR: AP Mask */ + +#define MPU_RBAR_XN_Pos 0U /*!< MPU RBAR: XN Position */ +#define MPU_RBAR_XN_Msk (01UL /*<< MPU_RBAR_XN_Pos*/) /*!< MPU RBAR: XN Mask */ + +/* MPU Region Limit Address Register Definitions */ +#define MPU_RLAR_LIMIT_Pos 5U /*!< MPU RLAR: LIMIT Position */ +#define MPU_RLAR_LIMIT_Msk (0x7FFFFFFUL << MPU_RLAR_LIMIT_Pos) /*!< MPU RLAR: LIMIT Mask */ + +#define MPU_RLAR_AttrIndx_Pos 1U /*!< MPU RLAR: AttrIndx Position */ +#define MPU_RLAR_AttrIndx_Msk (0x7UL << MPU_RLAR_AttrIndx_Pos) /*!< MPU RLAR: AttrIndx Mask */ + +#define MPU_RLAR_EN_Pos 0U /*!< MPU RLAR: Region enable bit Position */ +#define MPU_RLAR_EN_Msk (1UL /*<< MPU_RLAR_EN_Pos*/) /*!< MPU RLAR: Region enable bit Disable Mask */ + +/* MPU Memory Attribute Indirection Register 0 Definitions */ +#define MPU_MAIR0_Attr3_Pos 24U /*!< MPU MAIR0: Attr3 Position */ +#define MPU_MAIR0_Attr3_Msk (0xFFUL << MPU_MAIR0_Attr3_Pos) /*!< MPU MAIR0: Attr3 Mask */ + +#define MPU_MAIR0_Attr2_Pos 16U /*!< MPU MAIR0: Attr2 Position */ +#define MPU_MAIR0_Attr2_Msk (0xFFUL << MPU_MAIR0_Attr2_Pos) /*!< MPU MAIR0: Attr2 Mask */ + +#define MPU_MAIR0_Attr1_Pos 8U /*!< MPU MAIR0: Attr1 Position */ +#define MPU_MAIR0_Attr1_Msk (0xFFUL << MPU_MAIR0_Attr1_Pos) /*!< MPU MAIR0: Attr1 Mask */ + +#define MPU_MAIR0_Attr0_Pos 0U /*!< MPU MAIR0: Attr0 Position */ +#define MPU_MAIR0_Attr0_Msk (0xFFUL /*<< MPU_MAIR0_Attr0_Pos*/) /*!< MPU MAIR0: Attr0 Mask */ + +/* MPU Memory Attribute Indirection Register 1 Definitions */ +#define MPU_MAIR1_Attr7_Pos 24U /*!< MPU MAIR1: Attr7 Position */ +#define MPU_MAIR1_Attr7_Msk (0xFFUL << MPU_MAIR1_Attr7_Pos) /*!< MPU MAIR1: Attr7 Mask */ + +#define MPU_MAIR1_Attr6_Pos 16U /*!< MPU MAIR1: Attr6 Position */ +#define MPU_MAIR1_Attr6_Msk (0xFFUL << MPU_MAIR1_Attr6_Pos) /*!< MPU MAIR1: Attr6 Mask */ + +#define MPU_MAIR1_Attr5_Pos 8U /*!< MPU MAIR1: Attr5 Position */ +#define MPU_MAIR1_Attr5_Msk (0xFFUL << MPU_MAIR1_Attr5_Pos) /*!< MPU MAIR1: Attr5 Mask */ + +#define MPU_MAIR1_Attr4_Pos 0U /*!< MPU MAIR1: Attr4 Position */ +#define MPU_MAIR1_Attr4_Msk (0xFFUL /*<< MPU_MAIR1_Attr4_Pos*/) /*!< MPU MAIR1: Attr4 Mask */ + +/*@} end of group CMSIS_MPU */ +#endif + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SAU Security Attribution Unit (SAU) + \brief Type definitions for the Security Attribution Unit (SAU) + @{ + */ + +/** + \brief Structure type to access the Security Attribution Unit (SAU). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SAU Control Register */ + __IM uint32_t TYPE; /*!< Offset: 0x004 (R/ ) SAU Type Register */ +#if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) SAU Region Number Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) SAU Region Base Address Register */ + __IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) SAU Region Limit Address Register */ +#else + uint32_t RESERVED0[3]; +#endif + __IOM uint32_t SFSR; /*!< Offset: 0x014 (R/W) Secure Fault Status Register */ + __IOM uint32_t SFAR; /*!< Offset: 0x018 (R/W) Secure Fault Address Register */ +} SAU_Type; + +/* SAU Control Register Definitions */ +#define SAU_CTRL_ALLNS_Pos 1U /*!< SAU CTRL: ALLNS Position */ +#define SAU_CTRL_ALLNS_Msk (1UL << SAU_CTRL_ALLNS_Pos) /*!< SAU CTRL: ALLNS Mask */ + +#define SAU_CTRL_ENABLE_Pos 0U /*!< SAU CTRL: ENABLE Position */ +#define SAU_CTRL_ENABLE_Msk (1UL /*<< SAU_CTRL_ENABLE_Pos*/) /*!< SAU CTRL: ENABLE Mask */ + +/* SAU Type Register Definitions */ +#define SAU_TYPE_SREGION_Pos 0U /*!< SAU TYPE: SREGION Position */ +#define SAU_TYPE_SREGION_Msk (0xFFUL /*<< SAU_TYPE_SREGION_Pos*/) /*!< SAU TYPE: SREGION Mask */ + +#if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) +/* SAU Region Number Register Definitions */ +#define SAU_RNR_REGION_Pos 0U /*!< SAU RNR: REGION Position */ +#define SAU_RNR_REGION_Msk (0xFFUL /*<< SAU_RNR_REGION_Pos*/) /*!< SAU RNR: REGION Mask */ + +/* SAU Region Base Address Register Definitions */ +#define SAU_RBAR_BADDR_Pos 5U /*!< SAU RBAR: BADDR Position */ +#define SAU_RBAR_BADDR_Msk (0x7FFFFFFUL << SAU_RBAR_BADDR_Pos) /*!< SAU RBAR: BADDR Mask */ + +/* SAU Region Limit Address Register Definitions */ +#define SAU_RLAR_LADDR_Pos 5U /*!< SAU RLAR: LADDR Position */ +#define SAU_RLAR_LADDR_Msk (0x7FFFFFFUL << SAU_RLAR_LADDR_Pos) /*!< SAU RLAR: LADDR Mask */ + +#define SAU_RLAR_NSC_Pos 1U /*!< SAU RLAR: NSC Position */ +#define SAU_RLAR_NSC_Msk (1UL << SAU_RLAR_NSC_Pos) /*!< SAU RLAR: NSC Mask */ + +#define SAU_RLAR_ENABLE_Pos 0U /*!< SAU RLAR: ENABLE Position */ +#define SAU_RLAR_ENABLE_Msk (1UL /*<< SAU_RLAR_ENABLE_Pos*/) /*!< SAU RLAR: ENABLE Mask */ + +#endif /* defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) */ + +/* Secure Fault Status Register Definitions */ +#define SAU_SFSR_LSERR_Pos 7U /*!< SAU SFSR: LSERR Position */ +#define SAU_SFSR_LSERR_Msk (1UL << SAU_SFSR_LSERR_Pos) /*!< SAU SFSR: LSERR Mask */ + +#define SAU_SFSR_SFARVALID_Pos 6U /*!< SAU SFSR: SFARVALID Position */ +#define SAU_SFSR_SFARVALID_Msk (1UL << SAU_SFSR_SFARVALID_Pos) /*!< SAU SFSR: SFARVALID Mask */ + +#define SAU_SFSR_LSPERR_Pos 5U /*!< SAU SFSR: LSPERR Position */ +#define SAU_SFSR_LSPERR_Msk (1UL << SAU_SFSR_LSPERR_Pos) /*!< SAU SFSR: LSPERR Mask */ + +#define SAU_SFSR_INVTRAN_Pos 4U /*!< SAU SFSR: INVTRAN Position */ +#define SAU_SFSR_INVTRAN_Msk (1UL << SAU_SFSR_INVTRAN_Pos) /*!< SAU SFSR: INVTRAN Mask */ + +#define SAU_SFSR_AUVIOL_Pos 3U /*!< SAU SFSR: AUVIOL Position */ +#define SAU_SFSR_AUVIOL_Msk (1UL << SAU_SFSR_AUVIOL_Pos) /*!< SAU SFSR: AUVIOL Mask */ + +#define SAU_SFSR_INVER_Pos 2U /*!< SAU SFSR: INVER Position */ +#define SAU_SFSR_INVER_Msk (1UL << SAU_SFSR_INVER_Pos) /*!< SAU SFSR: INVER Mask */ + +#define SAU_SFSR_INVIS_Pos 1U /*!< SAU SFSR: INVIS Position */ +#define SAU_SFSR_INVIS_Msk (1UL << SAU_SFSR_INVIS_Pos) /*!< SAU SFSR: INVIS Mask */ + +#define SAU_SFSR_INVEP_Pos 0U /*!< SAU SFSR: INVEP Position */ +#define SAU_SFSR_INVEP_Msk (1UL /*<< SAU_SFSR_INVEP_Pos*/) /*!< SAU SFSR: INVEP Mask */ + +/*@} end of group CMSIS_SAU */ +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_FPU Floating Point Unit (FPU) + \brief Type definitions for the Floating Point Unit (FPU) + @{ + */ + +/** + \brief Structure type to access the Floating Point Unit (FPU). + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IOM uint32_t FPCCR; /*!< Offset: 0x004 (R/W) Floating-Point Context Control Register */ + __IOM uint32_t FPCAR; /*!< Offset: 0x008 (R/W) Floating-Point Context Address Register */ + __IOM uint32_t FPDSCR; /*!< Offset: 0x00C (R/W) Floating-Point Default Status Control Register */ + __IM uint32_t MVFR0; /*!< Offset: 0x010 (R/ ) Media and FP Feature Register 0 */ + __IM uint32_t MVFR1; /*!< Offset: 0x014 (R/ ) Media and FP Feature Register 1 */ +} FPU_Type; + +/* Floating-Point Context Control Register Definitions */ +#define FPU_FPCCR_ASPEN_Pos 31U /*!< FPCCR: ASPEN bit Position */ +#define FPU_FPCCR_ASPEN_Msk (1UL << FPU_FPCCR_ASPEN_Pos) /*!< FPCCR: ASPEN bit Mask */ + +#define FPU_FPCCR_LSPEN_Pos 30U /*!< FPCCR: LSPEN Position */ +#define FPU_FPCCR_LSPEN_Msk (1UL << FPU_FPCCR_LSPEN_Pos) /*!< FPCCR: LSPEN bit Mask */ + +#define FPU_FPCCR_LSPENS_Pos 29U /*!< FPCCR: LSPENS Position */ +#define FPU_FPCCR_LSPENS_Msk (1UL << FPU_FPCCR_LSPENS_Pos) /*!< FPCCR: LSPENS bit Mask */ + +#define FPU_FPCCR_CLRONRET_Pos 28U /*!< FPCCR: CLRONRET Position */ +#define FPU_FPCCR_CLRONRET_Msk (1UL << FPU_FPCCR_CLRONRET_Pos) /*!< FPCCR: CLRONRET bit Mask */ + +#define FPU_FPCCR_CLRONRETS_Pos 27U /*!< FPCCR: CLRONRETS Position */ +#define FPU_FPCCR_CLRONRETS_Msk (1UL << FPU_FPCCR_CLRONRETS_Pos) /*!< FPCCR: CLRONRETS bit Mask */ + +#define FPU_FPCCR_TS_Pos 26U /*!< FPCCR: TS Position */ +#define FPU_FPCCR_TS_Msk (1UL << FPU_FPCCR_TS_Pos) /*!< FPCCR: TS bit Mask */ + +#define FPU_FPCCR_UFRDY_Pos 10U /*!< FPCCR: UFRDY Position */ +#define FPU_FPCCR_UFRDY_Msk (1UL << FPU_FPCCR_UFRDY_Pos) /*!< FPCCR: UFRDY bit Mask */ + +#define FPU_FPCCR_SPLIMVIOL_Pos 9U /*!< FPCCR: SPLIMVIOL Position */ +#define FPU_FPCCR_SPLIMVIOL_Msk (1UL << FPU_FPCCR_SPLIMVIOL_Pos) /*!< FPCCR: SPLIMVIOL bit Mask */ + +#define FPU_FPCCR_MONRDY_Pos 8U /*!< FPCCR: MONRDY Position */ +#define FPU_FPCCR_MONRDY_Msk (1UL << FPU_FPCCR_MONRDY_Pos) /*!< FPCCR: MONRDY bit Mask */ + +#define FPU_FPCCR_SFRDY_Pos 7U /*!< FPCCR: SFRDY Position */ +#define FPU_FPCCR_SFRDY_Msk (1UL << FPU_FPCCR_SFRDY_Pos) /*!< FPCCR: SFRDY bit Mask */ + +#define FPU_FPCCR_BFRDY_Pos 6U /*!< FPCCR: BFRDY Position */ +#define FPU_FPCCR_BFRDY_Msk (1UL << FPU_FPCCR_BFRDY_Pos) /*!< FPCCR: BFRDY bit Mask */ + +#define FPU_FPCCR_MMRDY_Pos 5U /*!< FPCCR: MMRDY Position */ +#define FPU_FPCCR_MMRDY_Msk (1UL << FPU_FPCCR_MMRDY_Pos) /*!< FPCCR: MMRDY bit Mask */ + +#define FPU_FPCCR_HFRDY_Pos 4U /*!< FPCCR: HFRDY Position */ +#define FPU_FPCCR_HFRDY_Msk (1UL << FPU_FPCCR_HFRDY_Pos) /*!< FPCCR: HFRDY bit Mask */ + +#define FPU_FPCCR_THREAD_Pos 3U /*!< FPCCR: processor mode bit Position */ +#define FPU_FPCCR_THREAD_Msk (1UL << FPU_FPCCR_THREAD_Pos) /*!< FPCCR: processor mode active bit Mask */ + +#define FPU_FPCCR_S_Pos 2U /*!< FPCCR: Security status of the FP context bit Position */ +#define FPU_FPCCR_S_Msk (1UL << FPU_FPCCR_S_Pos) /*!< FPCCR: Security status of the FP context bit Mask */ + +#define FPU_FPCCR_USER_Pos 1U /*!< FPCCR: privilege level bit Position */ +#define FPU_FPCCR_USER_Msk (1UL << FPU_FPCCR_USER_Pos) /*!< FPCCR: privilege level bit Mask */ + +#define FPU_FPCCR_LSPACT_Pos 0U /*!< FPCCR: Lazy state preservation active bit Position */ +#define FPU_FPCCR_LSPACT_Msk (1UL /*<< FPU_FPCCR_LSPACT_Pos*/) /*!< FPCCR: Lazy state preservation active bit Mask */ + +/* Floating-Point Context Address Register Definitions */ +#define FPU_FPCAR_ADDRESS_Pos 3U /*!< FPCAR: ADDRESS bit Position */ +#define FPU_FPCAR_ADDRESS_Msk (0x1FFFFFFFUL << FPU_FPCAR_ADDRESS_Pos) /*!< FPCAR: ADDRESS bit Mask */ + +/* Floating-Point Default Status Control Register Definitions */ +#define FPU_FPDSCR_AHP_Pos 26U /*!< FPDSCR: AHP bit Position */ +#define FPU_FPDSCR_AHP_Msk (1UL << FPU_FPDSCR_AHP_Pos) /*!< FPDSCR: AHP bit Mask */ + +#define FPU_FPDSCR_DN_Pos 25U /*!< FPDSCR: DN bit Position */ +#define FPU_FPDSCR_DN_Msk (1UL << FPU_FPDSCR_DN_Pos) /*!< FPDSCR: DN bit Mask */ + +#define FPU_FPDSCR_FZ_Pos 24U /*!< FPDSCR: FZ bit Position */ +#define FPU_FPDSCR_FZ_Msk (1UL << FPU_FPDSCR_FZ_Pos) /*!< FPDSCR: FZ bit Mask */ + +#define FPU_FPDSCR_RMode_Pos 22U /*!< FPDSCR: RMode bit Position */ +#define FPU_FPDSCR_RMode_Msk (3UL << FPU_FPDSCR_RMode_Pos) /*!< FPDSCR: RMode bit Mask */ + +/* Media and FP Feature Register 0 Definitions */ +#define FPU_MVFR0_FP_rounding_modes_Pos 28U /*!< MVFR0: FP rounding modes bits Position */ +#define FPU_MVFR0_FP_rounding_modes_Msk (0xFUL << FPU_MVFR0_FP_rounding_modes_Pos) /*!< MVFR0: FP rounding modes bits Mask */ + +#define FPU_MVFR0_Short_vectors_Pos 24U /*!< MVFR0: Short vectors bits Position */ +#define FPU_MVFR0_Short_vectors_Msk (0xFUL << FPU_MVFR0_Short_vectors_Pos) /*!< MVFR0: Short vectors bits Mask */ + +#define FPU_MVFR0_Square_root_Pos 20U /*!< MVFR0: Square root bits Position */ +#define FPU_MVFR0_Square_root_Msk (0xFUL << FPU_MVFR0_Square_root_Pos) /*!< MVFR0: Square root bits Mask */ + +#define FPU_MVFR0_Divide_Pos 16U /*!< MVFR0: Divide bits Position */ +#define FPU_MVFR0_Divide_Msk (0xFUL << FPU_MVFR0_Divide_Pos) /*!< MVFR0: Divide bits Mask */ + +#define FPU_MVFR0_FP_excep_trapping_Pos 12U /*!< MVFR0: FP exception trapping bits Position */ +#define FPU_MVFR0_FP_excep_trapping_Msk (0xFUL << FPU_MVFR0_FP_excep_trapping_Pos) /*!< MVFR0: FP exception trapping bits Mask */ + +#define FPU_MVFR0_Double_precision_Pos 8U /*!< MVFR0: Double-precision bits Position */ +#define FPU_MVFR0_Double_precision_Msk (0xFUL << FPU_MVFR0_Double_precision_Pos) /*!< MVFR0: Double-precision bits Mask */ + +#define FPU_MVFR0_Single_precision_Pos 4U /*!< MVFR0: Single-precision bits Position */ +#define FPU_MVFR0_Single_precision_Msk (0xFUL << FPU_MVFR0_Single_precision_Pos) /*!< MVFR0: Single-precision bits Mask */ + +#define FPU_MVFR0_A_SIMD_registers_Pos 0U /*!< MVFR0: A_SIMD registers bits Position */ +#define FPU_MVFR0_A_SIMD_registers_Msk (0xFUL /*<< FPU_MVFR0_A_SIMD_registers_Pos*/) /*!< MVFR0: A_SIMD registers bits Mask */ + +/* Media and FP Feature Register 1 Definitions */ +#define FPU_MVFR1_FP_fused_MAC_Pos 28U /*!< MVFR1: FP fused MAC bits Position */ +#define FPU_MVFR1_FP_fused_MAC_Msk (0xFUL << FPU_MVFR1_FP_fused_MAC_Pos) /*!< MVFR1: FP fused MAC bits Mask */ + +#define FPU_MVFR1_FP_HPFP_Pos 24U /*!< MVFR1: FP HPFP bits Position */ +#define FPU_MVFR1_FP_HPFP_Msk (0xFUL << FPU_MVFR1_FP_HPFP_Pos) /*!< MVFR1: FP HPFP bits Mask */ + +#define FPU_MVFR1_D_NaN_mode_Pos 4U /*!< MVFR1: D_NaN mode bits Position */ +#define FPU_MVFR1_D_NaN_mode_Msk (0xFUL << FPU_MVFR1_D_NaN_mode_Pos) /*!< MVFR1: D_NaN mode bits Mask */ + +#define FPU_MVFR1_FtZ_mode_Pos 0U /*!< MVFR1: FtZ mode bits Position */ +#define FPU_MVFR1_FtZ_mode_Msk (0xFUL /*<< FPU_MVFR1_FtZ_mode_Pos*/) /*!< MVFR1: FtZ mode bits Mask */ + +/*@} end of group CMSIS_FPU */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Type definitions for the Core Debug Registers + @{ + */ + +/** + \brief Structure type to access the Core Debug Register (CoreDebug). + */ +typedef struct +{ + __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ + uint32_t RESERVED4[1U]; + __IOM uint32_t DAUTHCTRL; /*!< Offset: 0x014 (R/W) Debug Authentication Control Register */ + __IOM uint32_t DSCSR; /*!< Offset: 0x018 (R/W) Debug Security Control and Status Register */ +} CoreDebug_Type; + +/* Debug Halting Control and Status Register Definitions */ +#define CoreDebug_DHCSR_DBGKEY_Pos 16U /*!< CoreDebug DHCSR: DBGKEY Position */ +#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */ + +#define CoreDebug_DHCSR_S_RESTART_ST_Pos 26U /*!< CoreDebug DHCSR: S_RESTART_ST Position */ +#define CoreDebug_DHCSR_S_RESTART_ST_Msk (1UL << CoreDebug_DHCSR_S_RESTART_ST_Pos) /*!< CoreDebug DHCSR: S_RESTART_ST Mask */ + +#define CoreDebug_DHCSR_S_RESET_ST_Pos 25U /*!< CoreDebug DHCSR: S_RESET_ST Position */ +#define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< CoreDebug DHCSR: S_RESET_ST Mask */ + +#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24U /*!< CoreDebug DHCSR: S_RETIRE_ST Position */ +#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */ + +#define CoreDebug_DHCSR_S_LOCKUP_Pos 19U /*!< CoreDebug DHCSR: S_LOCKUP Position */ +#define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< CoreDebug DHCSR: S_LOCKUP Mask */ + +#define CoreDebug_DHCSR_S_SLEEP_Pos 18U /*!< CoreDebug DHCSR: S_SLEEP Position */ +#define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< CoreDebug DHCSR: S_SLEEP Mask */ + +#define CoreDebug_DHCSR_S_HALT_Pos 17U /*!< CoreDebug DHCSR: S_HALT Position */ +#define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< CoreDebug DHCSR: S_HALT Mask */ + +#define CoreDebug_DHCSR_S_REGRDY_Pos 16U /*!< CoreDebug DHCSR: S_REGRDY Position */ +#define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< CoreDebug DHCSR: S_REGRDY Mask */ + +#define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5U /*!< CoreDebug DHCSR: C_SNAPSTALL Position */ +#define CoreDebug_DHCSR_C_SNAPSTALL_Msk (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos) /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */ + +#define CoreDebug_DHCSR_C_MASKINTS_Pos 3U /*!< CoreDebug DHCSR: C_MASKINTS Position */ +#define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< CoreDebug DHCSR: C_MASKINTS Mask */ + +#define CoreDebug_DHCSR_C_STEP_Pos 2U /*!< CoreDebug DHCSR: C_STEP Position */ +#define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< CoreDebug DHCSR: C_STEP Mask */ + +#define CoreDebug_DHCSR_C_HALT_Pos 1U /*!< CoreDebug DHCSR: C_HALT Position */ +#define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< CoreDebug DHCSR: C_HALT Mask */ + +#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0U /*!< CoreDebug DHCSR: C_DEBUGEN Position */ +#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */ + +/* Debug Core Register Selector Register Definitions */ +#define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< CoreDebug DCRSR: REGWnR Position */ +#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ + +#define CoreDebug_DCRSR_REGSEL_Pos 0U /*!< CoreDebug DCRSR: REGSEL Position */ +#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/) /*!< CoreDebug DCRSR: REGSEL Mask */ + +/* Debug Exception and Monitor Control Register Definitions */ +#define CoreDebug_DEMCR_TRCENA_Pos 24U /*!< CoreDebug DEMCR: TRCENA Position */ +#define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< CoreDebug DEMCR: TRCENA Mask */ + +#define CoreDebug_DEMCR_MON_REQ_Pos 19U /*!< CoreDebug DEMCR: MON_REQ Position */ +#define CoreDebug_DEMCR_MON_REQ_Msk (1UL << CoreDebug_DEMCR_MON_REQ_Pos) /*!< CoreDebug DEMCR: MON_REQ Mask */ + +#define CoreDebug_DEMCR_MON_STEP_Pos 18U /*!< CoreDebug DEMCR: MON_STEP Position */ +#define CoreDebug_DEMCR_MON_STEP_Msk (1UL << CoreDebug_DEMCR_MON_STEP_Pos) /*!< CoreDebug DEMCR: MON_STEP Mask */ + +#define CoreDebug_DEMCR_MON_PEND_Pos 17U /*!< CoreDebug DEMCR: MON_PEND Position */ +#define CoreDebug_DEMCR_MON_PEND_Msk (1UL << CoreDebug_DEMCR_MON_PEND_Pos) /*!< CoreDebug DEMCR: MON_PEND Mask */ + +#define CoreDebug_DEMCR_MON_EN_Pos 16U /*!< CoreDebug DEMCR: MON_EN Position */ +#define CoreDebug_DEMCR_MON_EN_Msk (1UL << CoreDebug_DEMCR_MON_EN_Pos) /*!< CoreDebug DEMCR: MON_EN Mask */ + +#define CoreDebug_DEMCR_VC_HARDERR_Pos 10U /*!< CoreDebug DEMCR: VC_HARDERR Position */ +#define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< CoreDebug DEMCR: VC_HARDERR Mask */ + +#define CoreDebug_DEMCR_VC_INTERR_Pos 9U /*!< CoreDebug DEMCR: VC_INTERR Position */ +#define CoreDebug_DEMCR_VC_INTERR_Msk (1UL << CoreDebug_DEMCR_VC_INTERR_Pos) /*!< CoreDebug DEMCR: VC_INTERR Mask */ + +#define CoreDebug_DEMCR_VC_BUSERR_Pos 8U /*!< CoreDebug DEMCR: VC_BUSERR Position */ +#define CoreDebug_DEMCR_VC_BUSERR_Msk (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos) /*!< CoreDebug DEMCR: VC_BUSERR Mask */ + +#define CoreDebug_DEMCR_VC_STATERR_Pos 7U /*!< CoreDebug DEMCR: VC_STATERR Position */ +#define CoreDebug_DEMCR_VC_STATERR_Msk (1UL << CoreDebug_DEMCR_VC_STATERR_Pos) /*!< CoreDebug DEMCR: VC_STATERR Mask */ + +#define CoreDebug_DEMCR_VC_CHKERR_Pos 6U /*!< CoreDebug DEMCR: VC_CHKERR Position */ +#define CoreDebug_DEMCR_VC_CHKERR_Msk (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos) /*!< CoreDebug DEMCR: VC_CHKERR Mask */ + +#define CoreDebug_DEMCR_VC_NOCPERR_Pos 5U /*!< CoreDebug DEMCR: VC_NOCPERR Position */ +#define CoreDebug_DEMCR_VC_NOCPERR_Msk (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos) /*!< CoreDebug DEMCR: VC_NOCPERR Mask */ + +#define CoreDebug_DEMCR_VC_MMERR_Pos 4U /*!< CoreDebug DEMCR: VC_MMERR Position */ +#define CoreDebug_DEMCR_VC_MMERR_Msk (1UL << CoreDebug_DEMCR_VC_MMERR_Pos) /*!< CoreDebug DEMCR: VC_MMERR Mask */ + +#define CoreDebug_DEMCR_VC_CORERESET_Pos 0U /*!< CoreDebug DEMCR: VC_CORERESET Position */ +#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/) /*!< CoreDebug DEMCR: VC_CORERESET Mask */ + +/* Debug Authentication Control Register Definitions */ +#define CoreDebug_DAUTHCTRL_INTSPNIDEN_Pos 3U /*!< CoreDebug DAUTHCTRL: INTSPNIDEN, Position */ +#define CoreDebug_DAUTHCTRL_INTSPNIDEN_Msk (1UL << CoreDebug_DAUTHCTRL_INTSPNIDEN_Pos) /*!< CoreDebug DAUTHCTRL: INTSPNIDEN, Mask */ + +#define CoreDebug_DAUTHCTRL_SPNIDENSEL_Pos 2U /*!< CoreDebug DAUTHCTRL: SPNIDENSEL Position */ +#define CoreDebug_DAUTHCTRL_SPNIDENSEL_Msk (1UL << CoreDebug_DAUTHCTRL_SPNIDENSEL_Pos) /*!< CoreDebug DAUTHCTRL: SPNIDENSEL Mask */ + +#define CoreDebug_DAUTHCTRL_INTSPIDEN_Pos 1U /*!< CoreDebug DAUTHCTRL: INTSPIDEN Position */ +#define CoreDebug_DAUTHCTRL_INTSPIDEN_Msk (1UL << CoreDebug_DAUTHCTRL_INTSPIDEN_Pos) /*!< CoreDebug DAUTHCTRL: INTSPIDEN Mask */ + +#define CoreDebug_DAUTHCTRL_SPIDENSEL_Pos 0U /*!< CoreDebug DAUTHCTRL: SPIDENSEL Position */ +#define CoreDebug_DAUTHCTRL_SPIDENSEL_Msk (1UL /*<< CoreDebug_DAUTHCTRL_SPIDENSEL_Pos*/) /*!< CoreDebug DAUTHCTRL: SPIDENSEL Mask */ + +/* Debug Security Control and Status Register Definitions */ +#define CoreDebug_DSCSR_CDS_Pos 16U /*!< CoreDebug DSCSR: CDS Position */ +#define CoreDebug_DSCSR_CDS_Msk (1UL << CoreDebug_DSCSR_CDS_Pos) /*!< CoreDebug DSCSR: CDS Mask */ + +#define CoreDebug_DSCSR_SBRSEL_Pos 1U /*!< CoreDebug DSCSR: SBRSEL Position */ +#define CoreDebug_DSCSR_SBRSEL_Msk (1UL << CoreDebug_DSCSR_SBRSEL_Pos) /*!< CoreDebug DSCSR: SBRSEL Mask */ + +#define CoreDebug_DSCSR_SBRSELEN_Pos 0U /*!< CoreDebug DSCSR: SBRSELEN Position */ +#define CoreDebug_DSCSR_SBRSELEN_Msk (1UL /*<< CoreDebug_DSCSR_SBRSELEN_Pos*/) /*!< CoreDebug DSCSR: SBRSELEN Mask */ + +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param[in] field Name of the register bit field. + \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param[in] field Name of the register bit field. + \param[in] value Value of register. This parameter is interpreted as an uint32_t type. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) + +/*@} end of group CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Core Hardware */ + #define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ + #define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ + #define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ + #define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ + #define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */ + #define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ + #define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ + #define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + + #define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ + #define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ + #define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ + #define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ + #define ITM ((ITM_Type *) ITM_BASE ) /*!< ITM configuration struct */ + #define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ + #define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ + #define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE ) /*!< Core Debug configuration struct */ + + #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ + #endif + + #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + #define SAU_BASE (SCS_BASE + 0x0DD0UL) /*!< Security Attribution Unit */ + #define SAU ((SAU_Type *) SAU_BASE ) /*!< Security Attribution Unit */ + #endif + + #define FPU_BASE (SCS_BASE + 0x0F30UL) /*!< Floating Point Unit */ + #define FPU ((FPU_Type *) FPU_BASE ) /*!< Floating Point Unit */ + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + #define SCS_BASE_NS (0xE002E000UL) /*!< System Control Space Base Address (non-secure address space) */ + #define CoreDebug_BASE_NS (0xE002EDF0UL) /*!< Core Debug Base Address (non-secure address space) */ + #define SysTick_BASE_NS (SCS_BASE_NS + 0x0010UL) /*!< SysTick Base Address (non-secure address space) */ + #define NVIC_BASE_NS (SCS_BASE_NS + 0x0100UL) /*!< NVIC Base Address (non-secure address space) */ + #define SCB_BASE_NS (SCS_BASE_NS + 0x0D00UL) /*!< System Control Block Base Address (non-secure address space) */ + + #define SCnSCB_NS ((SCnSCB_Type *) SCS_BASE_NS ) /*!< System control Register not in SCB(non-secure address space) */ + #define SCB_NS ((SCB_Type *) SCB_BASE_NS ) /*!< SCB configuration struct (non-secure address space) */ + #define SysTick_NS ((SysTick_Type *) SysTick_BASE_NS ) /*!< SysTick configuration struct (non-secure address space) */ + #define NVIC_NS ((NVIC_Type *) NVIC_BASE_NS ) /*!< NVIC configuration struct (non-secure address space) */ + #define CoreDebug_NS ((CoreDebug_Type *) CoreDebug_BASE_NS) /*!< Core Debug configuration struct (non-secure address space) */ + + #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE_NS (SCS_BASE_NS + 0x0D90UL) /*!< Memory Protection Unit (non-secure address space) */ + #define MPU_NS ((MPU_Type *) MPU_BASE_NS ) /*!< Memory Protection Unit (non-secure address space) */ + #endif + + #define FPU_BASE_NS (SCS_BASE_NS + 0x0F30UL) /*!< Floating Point Unit (non-secure address space) */ + #define FPU_NS ((FPU_Type *) FPU_BASE_NS ) /*!< Floating Point Unit (non-secure address space) */ + +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Debug Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping + #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping + #define NVIC_EnableIRQ __NVIC_EnableIRQ + #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ + #define NVIC_DisableIRQ __NVIC_DisableIRQ + #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ + #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ + #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ + #define NVIC_GetActive __NVIC_GetActive + #define NVIC_SetPriority __NVIC_SetPriority + #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset +#endif /* CMSIS_NVIC_VIRTUAL */ + +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetVector __NVIC_SetVector + #define NVIC_GetVector __NVIC_GetVector +#endif /* (CMSIS_VECTAB_VIRTUAL) */ + +#define NVIC_USER_IRQ_OFFSET 16 + + +/* Special LR values for Secure/Non-Secure call handling and exception handling */ + +/* Function Return Payload (from ARMv8-M Architecture Reference Manual) LR value on entry from Secure BLXNS */ +#define FNC_RETURN (0xFEFFFFFFUL) /* bit [0] ignored when processing a branch */ + +/* The following EXC_RETURN mask values are used to evaluate the LR on exception entry */ +#define EXC_RETURN_PREFIX (0xFF000000UL) /* bits [31:24] set to indicate an EXC_RETURN value */ +#define EXC_RETURN_S (0x00000040UL) /* bit [6] stack used to push registers: 0=Non-secure 1=Secure */ +#define EXC_RETURN_DCRS (0x00000020UL) /* bit [5] stacking rules for called registers: 0=skipped 1=saved */ +#define EXC_RETURN_FTYPE (0x00000010UL) /* bit [4] allocate stack for floating-point context: 0=done 1=skipped */ +#define EXC_RETURN_MODE (0x00000008UL) /* bit [3] processor mode for return: 0=Handler mode 1=Thread mode */ +#define EXC_RETURN_SPSEL (0x00000002UL) /* bit [1] stack pointer used to restore context: 0=MSP 1=PSP */ +#define EXC_RETURN_ES (0x00000001UL) /* bit [0] security state exception was taken to: 0=Non-secure 1=Secure */ + +/* Integrity Signature (from ARMv8-M Architecture Reference Manual) for exception context stacking */ +#if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) /* Value for processors with floating-point extension: */ +#define EXC_INTEGRITY_SIGNATURE (0xFEFA125AUL) /* bit [0] SFTC must match LR bit[4] EXC_RETURN_FTYPE */ +#else +#define EXC_INTEGRITY_SIGNATURE (0xFEFA125BUL) /* Value for processors without floating-point extension */ +#endif + + +/** + \brief Set Priority Grouping + \details Sets the priority grouping field using the required unlock sequence. + The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. + Only values from 0..7 are used. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Priority grouping field. + */ +__STATIC_INLINE void __NVIC_SetPriorityGrouping(uint32_t PriorityGroup) +{ + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + + reg_value = SCB->AIRCR; /* read old register configuration */ + reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << 8U) ); /* Insert write key and priority group */ + SCB->AIRCR = reg_value; +} + + +/** + \brief Get Priority Grouping + \details Reads the priority grouping field from the NVIC Interrupt Controller. + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t __NVIC_GetPriorityGrouping(void) +{ + return ((uint32_t)((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); +} + + +/** + \brief Enable Interrupt + \details Enables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Interrupt Enable status + \details Returns a device specific interrupt enable status from the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt + \details Disables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __DSB(); + __ISB(); + } +} + + +/** + \brief Get Pending Interrupt + \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt + \details Reads the active register in the NVIC and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetActive(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Get Interrupt Target State + \details Reads the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + \return 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_GetTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Target State + \details Sets the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_SetTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] |= ((uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL))); + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Clear Interrupt Target State + \details Clears the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_ClearTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] &= ~((uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL))); + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + + +/** + \brief Set Interrupt Priority + \details Sets the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every processor exception. + */ +__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->IPR[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } + else + { + SCB->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return(((uint32_t)NVIC->IPR[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return(((uint32_t)SCB->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief Encode Priority + \details Encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + return ( + ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | + ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) + ); +} + + +/** + \brief Decode Priority + \details Decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. + \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); + *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); +} + + +/** + \brief Set Interrupt Vector + \details Sets an interrupt vector in SRAM based interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + VTOR must been relocated to SRAM before. + \param [in] IRQn Interrupt number + \param [in] vector Address of interrupt handler function + */ +__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; +} + + +/** + \brief Get Interrupt Vector + \details Reads an interrupt vector from interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Address of interrupt handler function + */ +__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET]; +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + SCB_AIRCR_SYSRESETREQ_Msk ); /* Keep priority group unchanged */ + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Set Priority Grouping (non-secure) + \details Sets the non-secure priority grouping field when in secure state using the required unlock sequence. + The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. + Only values from 0..7 are used. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Priority grouping field. + */ +__STATIC_INLINE void TZ_NVIC_SetPriorityGrouping_NS(uint32_t PriorityGroup) +{ + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + + reg_value = SCB_NS->AIRCR; /* read old register configuration */ + reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << SCB_AIRCR_PRIGROUP_Pos) ); /* Insert write key and priority group */ + SCB_NS->AIRCR = reg_value; +} + + +/** + \brief Get Priority Grouping (non-secure) + \details Reads the priority grouping field from the non-secure NVIC when in secure state. + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetPriorityGrouping_NS(void) +{ + return ((uint32_t)((SCB_NS->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); +} + + +/** + \brief Enable Interrupt (non-secure) + \details Enables a device specific interrupt in the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_EnableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Interrupt Enable status (non-secure) + \details Returns a device specific interrupt enable status from the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetEnableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt (non-secure) + \details Disables a device specific interrupt in the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_DisableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Pending Interrupt (non-secure) + \details Reads the NVIC pending register in the non-secure NVIC when in secure state and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt (non-secure) + \details Sets the pending bit of a device specific interrupt in the non-secure NVIC pending register when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_SetPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt (non-secure) + \details Clears the pending bit of a device specific interrupt in the non-secure NVIC pending register when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_ClearPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt (non-secure) + \details Reads the active register in non-secure NVIC when in secure state and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetActive_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Priority (non-secure) + \details Sets the priority of a non-secure device specific interrupt or a non-secure processor exception when in secure state. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every non-secure processor exception. + */ +__STATIC_INLINE void TZ_NVIC_SetPriority_NS(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->IPR[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } + else + { + SCB_NS->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } +} + + +/** + \brief Get Interrupt Priority (non-secure) + \details Reads the priority of a non-secure device specific interrupt or a non-secure processor exception when in secure state. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetPriority_NS(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return(((uint32_t)NVIC_NS->IPR[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return(((uint32_t)SCB_NS->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); + } +} +#endif /* defined (__ARM_FEATURE_CMSE) &&(__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_NVICFunctions */ + +/* ########################## MPU functions #################################### */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + +#include "mpu_armv8.h" + +#endif + +/* ########################## FPU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_FpuFunctions FPU Functions + \brief Function that provides FPU type. + @{ + */ + +/** + \brief get FPU type + \details returns the FPU type + \returns + - \b 0: No FPU + - \b 1: Single precision FPU + - \b 2: Double + Single precision FPU + */ +__STATIC_INLINE uint32_t SCB_GetFPUType(void) +{ + uint32_t mvfr0; + + mvfr0 = FPU->MVFR0; + if ((mvfr0 & (FPU_MVFR0_Single_precision_Msk | FPU_MVFR0_Double_precision_Msk)) == 0x220U) + { + return 2U; /* Double + Single precision FPU */ + } + else if ((mvfr0 & (FPU_MVFR0_Single_precision_Msk | FPU_MVFR0_Double_precision_Msk)) == 0x020U) + { + return 1U; /* Single precision FPU */ + } + else + { + return 0U; /* No FPU */ + } +} + + +/*@} end of CMSIS_Core_FpuFunctions */ + + + +/* ########################## SAU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SAUFunctions SAU Functions + \brief Functions that configure the SAU. + @{ + */ + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + +/** + \brief Enable SAU + \details Enables the Security Attribution Unit (SAU). + */ +__STATIC_INLINE void TZ_SAU_Enable(void) +{ + SAU->CTRL |= (SAU_CTRL_ENABLE_Msk); +} + + + +/** + \brief Disable SAU + \details Disables the Security Attribution Unit (SAU). + */ +__STATIC_INLINE void TZ_SAU_Disable(void) +{ + SAU->CTRL &= ~(SAU_CTRL_ENABLE_Msk); +} + +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_SAUFunctions */ + + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief System Tick Configuration (non-secure) + \details Initializes the non-secure System Timer and its interrupt when in secure state, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function TZ_SysTick_Config_NS is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + + */ +__STATIC_INLINE uint32_t TZ_SysTick_Config_NS(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick_NS->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + TZ_NVIC_SetPriority_NS (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick_NS->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick_NS->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + +/* ##################################### Debug In/Output function ########################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_core_DebugFunctions ITM Functions + \brief Functions that access the ITM debug interface. + @{ + */ + +extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */ +#define ITM_RXBUFFER_EMPTY ((int32_t)0x5AA55AA5U) /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */ + + +/** + \brief ITM Send Character + \details Transmits a character via the ITM channel 0, and + \li Just returns when no debugger is connected that has booked the output. + \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted. + \param [in] ch Character to transmit. + \returns Character to transmit. + */ +__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch) +{ + if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) && /* ITM enabled */ + ((ITM->TER & 1UL ) != 0UL) ) /* ITM Port #0 enabled */ + { + while (ITM->PORT[0U].u32 == 0UL) + { + __NOP(); + } + ITM->PORT[0U].u8 = (uint8_t)ch; + } + return (ch); +} + + +/** + \brief ITM Receive Character + \details Inputs a character via the external variable \ref ITM_RxBuffer. + \return Received character. + \return -1 No character pending. + */ +__STATIC_INLINE int32_t ITM_ReceiveChar (void) +{ + int32_t ch = -1; /* no character available */ + + if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) + { + ch = ITM_RxBuffer; + ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */ + } + + return (ch); +} + + +/** + \brief ITM Check Character + \details Checks whether a character is pending for reading in the variable \ref ITM_RxBuffer. + \return 0 No character available. + \return 1 Character available. + */ +__STATIC_INLINE int32_t ITM_CheckChar (void) +{ + + if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) + { + return (0); /* no character available */ + } + else + { + return (1); /* character available */ + } +} + +/*@} end of CMSIS_core_DebugFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM33_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/test/STM32F072C8T6/Drivers/CMSIS/Include/core_cm4.h b/test/STM32F072C8T6/Drivers/CMSIS/Include/core_cm4.h new file mode 100644 index 0000000..308b868 --- /dev/null +++ b/test/STM32F072C8T6/Drivers/CMSIS/Include/core_cm4.h @@ -0,0 +1,2129 @@ +/**************************************************************************//** + * @file core_cm4.h + * @brief CMSIS Cortex-M4 Core Peripheral Access Layer Header File + * @version V5.0.8 + * @date 04. June 2018 + ******************************************************************************/ +/* + * Copyright (c) 2009-2018 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * 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 + * + * 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. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CORE_CM4_H_GENERIC +#define __CORE_CM4_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup Cortex_M4 + @{ + */ + +#include "cmsis_version.h" + +/* CMSIS CM4 definitions */ +#define __CM4_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __CM4_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ +#define __CM4_CMSIS_VERSION ((__CM4_CMSIS_VERSION_MAIN << 16U) | \ + __CM4_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ + +#define __CORTEX_M (4U) /*!< Cortex-M Core */ + +/** __FPU_USED indicates whether an FPU is used or not. + For this, __FPU_PRESENT has to be checked prior to making use of FPU specific registers and functions. +*/ +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_PCS_VFP + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __TI_ARM__ ) + #if defined __TI_VFP_SUPPORT__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM4_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM4_H_DEPENDANT +#define __CORE_CM4_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM4_REV + #define __CM4_REV 0x0000U + #warning "__CM4_REV not defined in device header file; using default!" + #endif + + #ifndef __FPU_PRESENT + #define __FPU_PRESENT 0U + #warning "__FPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0U + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 3U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group Cortex_M4 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug Register + - Core MPU Register + - Core FPU Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:16; /*!< bit: 0..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:7; /*!< bit: 20..26 Reserved */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + +#define APSR_Q_Pos 27U /*!< APSR: Q Position */ +#define APSR_Q_Msk (1UL << APSR_Q_Pos) /*!< APSR: Q Mask */ + +#define APSR_GE_Pos 16U /*!< APSR: GE Position */ +#define APSR_GE_Msk (0xFUL << APSR_GE_Pos) /*!< APSR: GE Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:1; /*!< bit: 9 Reserved */ + uint32_t ICI_IT_1:6; /*!< bit: 10..15 ICI/IT part 1 */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:4; /*!< bit: 20..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit */ + uint32_t ICI_IT_2:2; /*!< bit: 25..26 ICI/IT part 2 */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_Q_Pos 27U /*!< xPSR: Q Position */ +#define xPSR_Q_Msk (1UL << xPSR_Q_Pos) /*!< xPSR: Q Mask */ + +#define xPSR_ICI_IT_2_Pos 25U /*!< xPSR: ICI/IT part 2 Position */ +#define xPSR_ICI_IT_2_Msk (3UL << xPSR_ICI_IT_2_Pos) /*!< xPSR: ICI/IT part 2 Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_GE_Pos 16U /*!< xPSR: GE Position */ +#define xPSR_GE_Msk (0xFUL << xPSR_GE_Pos) /*!< xPSR: GE Mask */ + +#define xPSR_ICI_IT_1_Pos 10U /*!< xPSR: ICI/IT part 1 Position */ +#define xPSR_ICI_IT_1_Msk (0x3FUL << xPSR_ICI_IT_1_Pos) /*!< xPSR: ICI/IT part 1 Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ + uint32_t FPCA:1; /*!< bit: 2 FP extension active flag */ + uint32_t _reserved0:29; /*!< bit: 3..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_FPCA_Pos 2U /*!< CONTROL: FPCA Position */ +#define CONTROL_FPCA_Msk (1UL << CONTROL_FPCA_Pos) /*!< CONTROL: FPCA Mask */ + +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ +#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[8U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[24U]; + __IOM uint32_t ICER[8U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[24U]; + __IOM uint32_t ISPR[8U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[24U]; + __IOM uint32_t ICPR[8U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[24U]; + __IOM uint32_t IABR[8U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[56U]; + __IOM uint8_t IP[240U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ + uint32_t RESERVED5[644U]; + __OM uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ +} NVIC_Type; + +/* Software Triggered Interrupt Register Definitions */ +#define NVIC_STIR_INTID_Pos 0U /*!< STIR: INTLINESNUM Position */ +#define NVIC_STIR_INTID_Msk (0x1FFUL /*<< NVIC_STIR_INTID_Pos*/) /*!< STIR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + __IOM uint8_t SHP[12U]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ + __IOM uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ + __IOM uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ + __IOM uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ + __IOM uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ + __IOM uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ + __IOM uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ + __IM uint32_t PFR[2U]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ + __IM uint32_t DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ + __IM uint32_t ADR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ + __IM uint32_t MMFR[4U]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ + __IM uint32_t ISAR[5U]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ + uint32_t RESERVED0[5U]; + __IOM uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */ +#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_RETTOBASE_Pos 11U /*!< SCB ICSR: RETTOBASE Position */ +#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Vector Table Offset Register Definitions */ +#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_PRIGROUP_Pos 8U /*!< SCB AIRCR: PRIGROUP Position */ +#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +#define SCB_AIRCR_VECTRESET_Pos 0U /*!< SCB AIRCR: VECTRESET Position */ +#define SCB_AIRCR_VECTRESET_Msk (1UL /*<< SCB_AIRCR_VECTRESET_Pos*/) /*!< SCB AIRCR: VECTRESET Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */ +#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ + +#define SCB_CCR_BFHFNMIGN_Pos 8U /*!< SCB CCR: BFHFNMIGN Position */ +#define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ + +#define SCB_CCR_DIV_0_TRP_Pos 4U /*!< SCB CCR: DIV_0_TRP Position */ +#define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +#define SCB_CCR_USERSETMPEND_Pos 1U /*!< SCB CCR: USERSETMPEND Position */ +#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ + +#define SCB_CCR_NONBASETHRDENA_Pos 0U /*!< SCB CCR: NONBASETHRDENA Position */ +#define SCB_CCR_NONBASETHRDENA_Msk (1UL /*<< SCB_CCR_NONBASETHRDENA_Pos*/) /*!< SCB CCR: NONBASETHRDENA Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_USGFAULTENA_Pos 18U /*!< SCB SHCSR: USGFAULTENA Position */ +#define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */ + +#define SCB_SHCSR_BUSFAULTENA_Pos 17U /*!< SCB SHCSR: BUSFAULTENA Position */ +#define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */ + +#define SCB_SHCSR_MEMFAULTENA_Pos 16U /*!< SCB SHCSR: MEMFAULTENA Position */ +#define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */ + +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +#define SCB_SHCSR_BUSFAULTPENDED_Pos 14U /*!< SCB SHCSR: BUSFAULTPENDED Position */ +#define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */ + +#define SCB_SHCSR_MEMFAULTPENDED_Pos 13U /*!< SCB SHCSR: MEMFAULTPENDED Position */ +#define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */ + +#define SCB_SHCSR_USGFAULTPENDED_Pos 12U /*!< SCB SHCSR: USGFAULTPENDED Position */ +#define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */ + +#define SCB_SHCSR_SYSTICKACT_Pos 11U /*!< SCB SHCSR: SYSTICKACT Position */ +#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ + +#define SCB_SHCSR_PENDSVACT_Pos 10U /*!< SCB SHCSR: PENDSVACT Position */ +#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ + +#define SCB_SHCSR_MONITORACT_Pos 8U /*!< SCB SHCSR: MONITORACT Position */ +#define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */ + +#define SCB_SHCSR_SVCALLACT_Pos 7U /*!< SCB SHCSR: SVCALLACT Position */ +#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ + +#define SCB_SHCSR_USGFAULTACT_Pos 3U /*!< SCB SHCSR: USGFAULTACT Position */ +#define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */ + +#define SCB_SHCSR_BUSFAULTACT_Pos 1U /*!< SCB SHCSR: BUSFAULTACT Position */ +#define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */ + +#define SCB_SHCSR_MEMFAULTACT_Pos 0U /*!< SCB SHCSR: MEMFAULTACT Position */ +#define SCB_SHCSR_MEMFAULTACT_Msk (1UL /*<< SCB_SHCSR_MEMFAULTACT_Pos*/) /*!< SCB SHCSR: MEMFAULTACT Mask */ + +/* SCB Configurable Fault Status Register Definitions */ +#define SCB_CFSR_USGFAULTSR_Pos 16U /*!< SCB CFSR: Usage Fault Status Register Position */ +#define SCB_CFSR_USGFAULTSR_Msk (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */ + +#define SCB_CFSR_BUSFAULTSR_Pos 8U /*!< SCB CFSR: Bus Fault Status Register Position */ +#define SCB_CFSR_BUSFAULTSR_Msk (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */ + +#define SCB_CFSR_MEMFAULTSR_Pos 0U /*!< SCB CFSR: Memory Manage Fault Status Register Position */ +#define SCB_CFSR_MEMFAULTSR_Msk (0xFFUL /*<< SCB_CFSR_MEMFAULTSR_Pos*/) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */ + +/* MemManage Fault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_MMARVALID_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 7U) /*!< SCB CFSR (MMFSR): MMARVALID Position */ +#define SCB_CFSR_MMARVALID_Msk (1UL << SCB_CFSR_MMARVALID_Pos) /*!< SCB CFSR (MMFSR): MMARVALID Mask */ + +#define SCB_CFSR_MLSPERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 5U) /*!< SCB CFSR (MMFSR): MLSPERR Position */ +#define SCB_CFSR_MLSPERR_Msk (1UL << SCB_CFSR_MLSPERR_Pos) /*!< SCB CFSR (MMFSR): MLSPERR Mask */ + +#define SCB_CFSR_MSTKERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 4U) /*!< SCB CFSR (MMFSR): MSTKERR Position */ +#define SCB_CFSR_MSTKERR_Msk (1UL << SCB_CFSR_MSTKERR_Pos) /*!< SCB CFSR (MMFSR): MSTKERR Mask */ + +#define SCB_CFSR_MUNSTKERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 3U) /*!< SCB CFSR (MMFSR): MUNSTKERR Position */ +#define SCB_CFSR_MUNSTKERR_Msk (1UL << SCB_CFSR_MUNSTKERR_Pos) /*!< SCB CFSR (MMFSR): MUNSTKERR Mask */ + +#define SCB_CFSR_DACCVIOL_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 1U) /*!< SCB CFSR (MMFSR): DACCVIOL Position */ +#define SCB_CFSR_DACCVIOL_Msk (1UL << SCB_CFSR_DACCVIOL_Pos) /*!< SCB CFSR (MMFSR): DACCVIOL Mask */ + +#define SCB_CFSR_IACCVIOL_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 0U) /*!< SCB CFSR (MMFSR): IACCVIOL Position */ +#define SCB_CFSR_IACCVIOL_Msk (1UL /*<< SCB_CFSR_IACCVIOL_Pos*/) /*!< SCB CFSR (MMFSR): IACCVIOL Mask */ + +/* BusFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_BFARVALID_Pos (SCB_CFSR_BUSFAULTSR_Pos + 7U) /*!< SCB CFSR (BFSR): BFARVALID Position */ +#define SCB_CFSR_BFARVALID_Msk (1UL << SCB_CFSR_BFARVALID_Pos) /*!< SCB CFSR (BFSR): BFARVALID Mask */ + +#define SCB_CFSR_LSPERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 5U) /*!< SCB CFSR (BFSR): LSPERR Position */ +#define SCB_CFSR_LSPERR_Msk (1UL << SCB_CFSR_LSPERR_Pos) /*!< SCB CFSR (BFSR): LSPERR Mask */ + +#define SCB_CFSR_STKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 4U) /*!< SCB CFSR (BFSR): STKERR Position */ +#define SCB_CFSR_STKERR_Msk (1UL << SCB_CFSR_STKERR_Pos) /*!< SCB CFSR (BFSR): STKERR Mask */ + +#define SCB_CFSR_UNSTKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 3U) /*!< SCB CFSR (BFSR): UNSTKERR Position */ +#define SCB_CFSR_UNSTKERR_Msk (1UL << SCB_CFSR_UNSTKERR_Pos) /*!< SCB CFSR (BFSR): UNSTKERR Mask */ + +#define SCB_CFSR_IMPRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 2U) /*!< SCB CFSR (BFSR): IMPRECISERR Position */ +#define SCB_CFSR_IMPRECISERR_Msk (1UL << SCB_CFSR_IMPRECISERR_Pos) /*!< SCB CFSR (BFSR): IMPRECISERR Mask */ + +#define SCB_CFSR_PRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 1U) /*!< SCB CFSR (BFSR): PRECISERR Position */ +#define SCB_CFSR_PRECISERR_Msk (1UL << SCB_CFSR_PRECISERR_Pos) /*!< SCB CFSR (BFSR): PRECISERR Mask */ + +#define SCB_CFSR_IBUSERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 0U) /*!< SCB CFSR (BFSR): IBUSERR Position */ +#define SCB_CFSR_IBUSERR_Msk (1UL << SCB_CFSR_IBUSERR_Pos) /*!< SCB CFSR (BFSR): IBUSERR Mask */ + +/* UsageFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_DIVBYZERO_Pos (SCB_CFSR_USGFAULTSR_Pos + 9U) /*!< SCB CFSR (UFSR): DIVBYZERO Position */ +#define SCB_CFSR_DIVBYZERO_Msk (1UL << SCB_CFSR_DIVBYZERO_Pos) /*!< SCB CFSR (UFSR): DIVBYZERO Mask */ + +#define SCB_CFSR_UNALIGNED_Pos (SCB_CFSR_USGFAULTSR_Pos + 8U) /*!< SCB CFSR (UFSR): UNALIGNED Position */ +#define SCB_CFSR_UNALIGNED_Msk (1UL << SCB_CFSR_UNALIGNED_Pos) /*!< SCB CFSR (UFSR): UNALIGNED Mask */ + +#define SCB_CFSR_NOCP_Pos (SCB_CFSR_USGFAULTSR_Pos + 3U) /*!< SCB CFSR (UFSR): NOCP Position */ +#define SCB_CFSR_NOCP_Msk (1UL << SCB_CFSR_NOCP_Pos) /*!< SCB CFSR (UFSR): NOCP Mask */ + +#define SCB_CFSR_INVPC_Pos (SCB_CFSR_USGFAULTSR_Pos + 2U) /*!< SCB CFSR (UFSR): INVPC Position */ +#define SCB_CFSR_INVPC_Msk (1UL << SCB_CFSR_INVPC_Pos) /*!< SCB CFSR (UFSR): INVPC Mask */ + +#define SCB_CFSR_INVSTATE_Pos (SCB_CFSR_USGFAULTSR_Pos + 1U) /*!< SCB CFSR (UFSR): INVSTATE Position */ +#define SCB_CFSR_INVSTATE_Msk (1UL << SCB_CFSR_INVSTATE_Pos) /*!< SCB CFSR (UFSR): INVSTATE Mask */ + +#define SCB_CFSR_UNDEFINSTR_Pos (SCB_CFSR_USGFAULTSR_Pos + 0U) /*!< SCB CFSR (UFSR): UNDEFINSTR Position */ +#define SCB_CFSR_UNDEFINSTR_Msk (1UL << SCB_CFSR_UNDEFINSTR_Pos) /*!< SCB CFSR (UFSR): UNDEFINSTR Mask */ + +/* SCB Hard Fault Status Register Definitions */ +#define SCB_HFSR_DEBUGEVT_Pos 31U /*!< SCB HFSR: DEBUGEVT Position */ +#define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ + +#define SCB_HFSR_FORCED_Pos 30U /*!< SCB HFSR: FORCED Position */ +#define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */ + +#define SCB_HFSR_VECTTBL_Pos 1U /*!< SCB HFSR: VECTTBL Position */ +#define SCB_HFSR_VECTTBL_Msk (1UL << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */ + +/* SCB Debug Fault Status Register Definitions */ +#define SCB_DFSR_EXTERNAL_Pos 4U /*!< SCB DFSR: EXTERNAL Position */ +#define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */ + +#define SCB_DFSR_VCATCH_Pos 3U /*!< SCB DFSR: VCATCH Position */ +#define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */ + +#define SCB_DFSR_DWTTRAP_Pos 2U /*!< SCB DFSR: DWTTRAP Position */ +#define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */ + +#define SCB_DFSR_BKPT_Pos 1U /*!< SCB DFSR: BKPT Position */ +#define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */ + +#define SCB_DFSR_HALTED_Pos 0U /*!< SCB DFSR: HALTED Position */ +#define SCB_DFSR_HALTED_Msk (1UL /*<< SCB_DFSR_HALTED_Pos*/) /*!< SCB DFSR: HALTED Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) + \brief Type definitions for the System Control and ID Register not in the SCB + @{ + */ + +/** + \brief Structure type to access the System Control and ID Register not in the SCB. + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IM uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ + __IOM uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ +} SCnSCB_Type; + +/* Interrupt Controller Type Register Definitions */ +#define SCnSCB_ICTR_INTLINESNUM_Pos 0U /*!< ICTR: INTLINESNUM Position */ +#define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL /*<< SCnSCB_ICTR_INTLINESNUM_Pos*/) /*!< ICTR: INTLINESNUM Mask */ + +/* Auxiliary Control Register Definitions */ +#define SCnSCB_ACTLR_DISOOFP_Pos 9U /*!< ACTLR: DISOOFP Position */ +#define SCnSCB_ACTLR_DISOOFP_Msk (1UL << SCnSCB_ACTLR_DISOOFP_Pos) /*!< ACTLR: DISOOFP Mask */ + +#define SCnSCB_ACTLR_DISFPCA_Pos 8U /*!< ACTLR: DISFPCA Position */ +#define SCnSCB_ACTLR_DISFPCA_Msk (1UL << SCnSCB_ACTLR_DISFPCA_Pos) /*!< ACTLR: DISFPCA Mask */ + +#define SCnSCB_ACTLR_DISFOLD_Pos 2U /*!< ACTLR: DISFOLD Position */ +#define SCnSCB_ACTLR_DISFOLD_Msk (1UL << SCnSCB_ACTLR_DISFOLD_Pos) /*!< ACTLR: DISFOLD Mask */ + +#define SCnSCB_ACTLR_DISDEFWBUF_Pos 1U /*!< ACTLR: DISDEFWBUF Position */ +#define SCnSCB_ACTLR_DISDEFWBUF_Msk (1UL << SCnSCB_ACTLR_DISDEFWBUF_Pos) /*!< ACTLR: DISDEFWBUF Mask */ + +#define SCnSCB_ACTLR_DISMCYCINT_Pos 0U /*!< ACTLR: DISMCYCINT Position */ +#define SCnSCB_ACTLR_DISMCYCINT_Msk (1UL /*<< SCnSCB_ACTLR_DISMCYCINT_Pos*/) /*!< ACTLR: DISMCYCINT Mask */ + +/*@} end of group CMSIS_SCnotSCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_ITM Instrumentation Trace Macrocell (ITM) + \brief Type definitions for the Instrumentation Trace Macrocell (ITM) + @{ + */ + +/** + \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM). + */ +typedef struct +{ + __OM union + { + __OM uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ + __OM uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ + __OM uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ + } PORT [32U]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ + uint32_t RESERVED0[864U]; + __IOM uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ + uint32_t RESERVED1[15U]; + __IOM uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ + uint32_t RESERVED2[15U]; + __IOM uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ + uint32_t RESERVED3[29U]; + __OM uint32_t IWR; /*!< Offset: 0xEF8 ( /W) ITM Integration Write Register */ + __IM uint32_t IRR; /*!< Offset: 0xEFC (R/ ) ITM Integration Read Register */ + __IOM uint32_t IMCR; /*!< Offset: 0xF00 (R/W) ITM Integration Mode Control Register */ + uint32_t RESERVED4[43U]; + __OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */ + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */ + uint32_t RESERVED5[6U]; + __IM uint32_t PID4; /*!< Offset: 0xFD0 (R/ ) ITM Peripheral Identification Register #4 */ + __IM uint32_t PID5; /*!< Offset: 0xFD4 (R/ ) ITM Peripheral Identification Register #5 */ + __IM uint32_t PID6; /*!< Offset: 0xFD8 (R/ ) ITM Peripheral Identification Register #6 */ + __IM uint32_t PID7; /*!< Offset: 0xFDC (R/ ) ITM Peripheral Identification Register #7 */ + __IM uint32_t PID0; /*!< Offset: 0xFE0 (R/ ) ITM Peripheral Identification Register #0 */ + __IM uint32_t PID1; /*!< Offset: 0xFE4 (R/ ) ITM Peripheral Identification Register #1 */ + __IM uint32_t PID2; /*!< Offset: 0xFE8 (R/ ) ITM Peripheral Identification Register #2 */ + __IM uint32_t PID3; /*!< Offset: 0xFEC (R/ ) ITM Peripheral Identification Register #3 */ + __IM uint32_t CID0; /*!< Offset: 0xFF0 (R/ ) ITM Component Identification Register #0 */ + __IM uint32_t CID1; /*!< Offset: 0xFF4 (R/ ) ITM Component Identification Register #1 */ + __IM uint32_t CID2; /*!< Offset: 0xFF8 (R/ ) ITM Component Identification Register #2 */ + __IM uint32_t CID3; /*!< Offset: 0xFFC (R/ ) ITM Component Identification Register #3 */ +} ITM_Type; + +/* ITM Trace Privilege Register Definitions */ +#define ITM_TPR_PRIVMASK_Pos 0U /*!< ITM TPR: PRIVMASK Position */ +#define ITM_TPR_PRIVMASK_Msk (0xFFFFFFFFUL /*<< ITM_TPR_PRIVMASK_Pos*/) /*!< ITM TPR: PRIVMASK Mask */ + +/* ITM Trace Control Register Definitions */ +#define ITM_TCR_BUSY_Pos 23U /*!< ITM TCR: BUSY Position */ +#define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */ + +#define ITM_TCR_TraceBusID_Pos 16U /*!< ITM TCR: ATBID Position */ +#define ITM_TCR_TraceBusID_Msk (0x7FUL << ITM_TCR_TraceBusID_Pos) /*!< ITM TCR: ATBID Mask */ + +#define ITM_TCR_GTSFREQ_Pos 10U /*!< ITM TCR: Global timestamp frequency Position */ +#define ITM_TCR_GTSFREQ_Msk (3UL << ITM_TCR_GTSFREQ_Pos) /*!< ITM TCR: Global timestamp frequency Mask */ + +#define ITM_TCR_TSPrescale_Pos 8U /*!< ITM TCR: TSPrescale Position */ +#define ITM_TCR_TSPrescale_Msk (3UL << ITM_TCR_TSPrescale_Pos) /*!< ITM TCR: TSPrescale Mask */ + +#define ITM_TCR_SWOENA_Pos 4U /*!< ITM TCR: SWOENA Position */ +#define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */ + +#define ITM_TCR_DWTENA_Pos 3U /*!< ITM TCR: DWTENA Position */ +#define ITM_TCR_DWTENA_Msk (1UL << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */ + +#define ITM_TCR_SYNCENA_Pos 2U /*!< ITM TCR: SYNCENA Position */ +#define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */ + +#define ITM_TCR_TSENA_Pos 1U /*!< ITM TCR: TSENA Position */ +#define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */ + +#define ITM_TCR_ITMENA_Pos 0U /*!< ITM TCR: ITM Enable bit Position */ +#define ITM_TCR_ITMENA_Msk (1UL /*<< ITM_TCR_ITMENA_Pos*/) /*!< ITM TCR: ITM Enable bit Mask */ + +/* ITM Integration Write Register Definitions */ +#define ITM_IWR_ATVALIDM_Pos 0U /*!< ITM IWR: ATVALIDM Position */ +#define ITM_IWR_ATVALIDM_Msk (1UL /*<< ITM_IWR_ATVALIDM_Pos*/) /*!< ITM IWR: ATVALIDM Mask */ + +/* ITM Integration Read Register Definitions */ +#define ITM_IRR_ATREADYM_Pos 0U /*!< ITM IRR: ATREADYM Position */ +#define ITM_IRR_ATREADYM_Msk (1UL /*<< ITM_IRR_ATREADYM_Pos*/) /*!< ITM IRR: ATREADYM Mask */ + +/* ITM Integration Mode Control Register Definitions */ +#define ITM_IMCR_INTEGRATION_Pos 0U /*!< ITM IMCR: INTEGRATION Position */ +#define ITM_IMCR_INTEGRATION_Msk (1UL /*<< ITM_IMCR_INTEGRATION_Pos*/) /*!< ITM IMCR: INTEGRATION Mask */ + +/* ITM Lock Status Register Definitions */ +#define ITM_LSR_ByteAcc_Pos 2U /*!< ITM LSR: ByteAcc Position */ +#define ITM_LSR_ByteAcc_Msk (1UL << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */ + +#define ITM_LSR_Access_Pos 1U /*!< ITM LSR: Access Position */ +#define ITM_LSR_Access_Msk (1UL << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */ + +#define ITM_LSR_Present_Pos 0U /*!< ITM LSR: Present Position */ +#define ITM_LSR_Present_Msk (1UL /*<< ITM_LSR_Present_Pos*/) /*!< ITM LSR: Present Mask */ + +/*@}*/ /* end of group CMSIS_ITM */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) + \brief Type definitions for the Data Watchpoint and Trace (DWT) + @{ + */ + +/** + \brief Structure type to access the Data Watchpoint and Trace Register (DWT). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ + __IOM uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */ + __IOM uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */ + __IOM uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */ + __IOM uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */ + __IOM uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */ + __IOM uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */ + __IM uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ + __IOM uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ + __IOM uint32_t MASK0; /*!< Offset: 0x024 (R/W) Mask Register 0 */ + __IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ + uint32_t RESERVED0[1U]; + __IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ + __IOM uint32_t MASK1; /*!< Offset: 0x034 (R/W) Mask Register 1 */ + __IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ + uint32_t RESERVED1[1U]; + __IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ + __IOM uint32_t MASK2; /*!< Offset: 0x044 (R/W) Mask Register 2 */ + __IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ + uint32_t RESERVED2[1U]; + __IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ + __IOM uint32_t MASK3; /*!< Offset: 0x054 (R/W) Mask Register 3 */ + __IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ +} DWT_Type; + +/* DWT Control Register Definitions */ +#define DWT_CTRL_NUMCOMP_Pos 28U /*!< DWT CTRL: NUMCOMP Position */ +#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ + +#define DWT_CTRL_NOTRCPKT_Pos 27U /*!< DWT CTRL: NOTRCPKT Position */ +#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ + +#define DWT_CTRL_NOEXTTRIG_Pos 26U /*!< DWT CTRL: NOEXTTRIG Position */ +#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ + +#define DWT_CTRL_NOCYCCNT_Pos 25U /*!< DWT CTRL: NOCYCCNT Position */ +#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ + +#define DWT_CTRL_NOPRFCNT_Pos 24U /*!< DWT CTRL: NOPRFCNT Position */ +#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ + +#define DWT_CTRL_CYCEVTENA_Pos 22U /*!< DWT CTRL: CYCEVTENA Position */ +#define DWT_CTRL_CYCEVTENA_Msk (0x1UL << DWT_CTRL_CYCEVTENA_Pos) /*!< DWT CTRL: CYCEVTENA Mask */ + +#define DWT_CTRL_FOLDEVTENA_Pos 21U /*!< DWT CTRL: FOLDEVTENA Position */ +#define DWT_CTRL_FOLDEVTENA_Msk (0x1UL << DWT_CTRL_FOLDEVTENA_Pos) /*!< DWT CTRL: FOLDEVTENA Mask */ + +#define DWT_CTRL_LSUEVTENA_Pos 20U /*!< DWT CTRL: LSUEVTENA Position */ +#define DWT_CTRL_LSUEVTENA_Msk (0x1UL << DWT_CTRL_LSUEVTENA_Pos) /*!< DWT CTRL: LSUEVTENA Mask */ + +#define DWT_CTRL_SLEEPEVTENA_Pos 19U /*!< DWT CTRL: SLEEPEVTENA Position */ +#define DWT_CTRL_SLEEPEVTENA_Msk (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos) /*!< DWT CTRL: SLEEPEVTENA Mask */ + +#define DWT_CTRL_EXCEVTENA_Pos 18U /*!< DWT CTRL: EXCEVTENA Position */ +#define DWT_CTRL_EXCEVTENA_Msk (0x1UL << DWT_CTRL_EXCEVTENA_Pos) /*!< DWT CTRL: EXCEVTENA Mask */ + +#define DWT_CTRL_CPIEVTENA_Pos 17U /*!< DWT CTRL: CPIEVTENA Position */ +#define DWT_CTRL_CPIEVTENA_Msk (0x1UL << DWT_CTRL_CPIEVTENA_Pos) /*!< DWT CTRL: CPIEVTENA Mask */ + +#define DWT_CTRL_EXCTRCENA_Pos 16U /*!< DWT CTRL: EXCTRCENA Position */ +#define DWT_CTRL_EXCTRCENA_Msk (0x1UL << DWT_CTRL_EXCTRCENA_Pos) /*!< DWT CTRL: EXCTRCENA Mask */ + +#define DWT_CTRL_PCSAMPLENA_Pos 12U /*!< DWT CTRL: PCSAMPLENA Position */ +#define DWT_CTRL_PCSAMPLENA_Msk (0x1UL << DWT_CTRL_PCSAMPLENA_Pos) /*!< DWT CTRL: PCSAMPLENA Mask */ + +#define DWT_CTRL_SYNCTAP_Pos 10U /*!< DWT CTRL: SYNCTAP Position */ +#define DWT_CTRL_SYNCTAP_Msk (0x3UL << DWT_CTRL_SYNCTAP_Pos) /*!< DWT CTRL: SYNCTAP Mask */ + +#define DWT_CTRL_CYCTAP_Pos 9U /*!< DWT CTRL: CYCTAP Position */ +#define DWT_CTRL_CYCTAP_Msk (0x1UL << DWT_CTRL_CYCTAP_Pos) /*!< DWT CTRL: CYCTAP Mask */ + +#define DWT_CTRL_POSTINIT_Pos 5U /*!< DWT CTRL: POSTINIT Position */ +#define DWT_CTRL_POSTINIT_Msk (0xFUL << DWT_CTRL_POSTINIT_Pos) /*!< DWT CTRL: POSTINIT Mask */ + +#define DWT_CTRL_POSTPRESET_Pos 1U /*!< DWT CTRL: POSTPRESET Position */ +#define DWT_CTRL_POSTPRESET_Msk (0xFUL << DWT_CTRL_POSTPRESET_Pos) /*!< DWT CTRL: POSTPRESET Mask */ + +#define DWT_CTRL_CYCCNTENA_Pos 0U /*!< DWT CTRL: CYCCNTENA Position */ +#define DWT_CTRL_CYCCNTENA_Msk (0x1UL /*<< DWT_CTRL_CYCCNTENA_Pos*/) /*!< DWT CTRL: CYCCNTENA Mask */ + +/* DWT CPI Count Register Definitions */ +#define DWT_CPICNT_CPICNT_Pos 0U /*!< DWT CPICNT: CPICNT Position */ +#define DWT_CPICNT_CPICNT_Msk (0xFFUL /*<< DWT_CPICNT_CPICNT_Pos*/) /*!< DWT CPICNT: CPICNT Mask */ + +/* DWT Exception Overhead Count Register Definitions */ +#define DWT_EXCCNT_EXCCNT_Pos 0U /*!< DWT EXCCNT: EXCCNT Position */ +#define DWT_EXCCNT_EXCCNT_Msk (0xFFUL /*<< DWT_EXCCNT_EXCCNT_Pos*/) /*!< DWT EXCCNT: EXCCNT Mask */ + +/* DWT Sleep Count Register Definitions */ +#define DWT_SLEEPCNT_SLEEPCNT_Pos 0U /*!< DWT SLEEPCNT: SLEEPCNT Position */ +#define DWT_SLEEPCNT_SLEEPCNT_Msk (0xFFUL /*<< DWT_SLEEPCNT_SLEEPCNT_Pos*/) /*!< DWT SLEEPCNT: SLEEPCNT Mask */ + +/* DWT LSU Count Register Definitions */ +#define DWT_LSUCNT_LSUCNT_Pos 0U /*!< DWT LSUCNT: LSUCNT Position */ +#define DWT_LSUCNT_LSUCNT_Msk (0xFFUL /*<< DWT_LSUCNT_LSUCNT_Pos*/) /*!< DWT LSUCNT: LSUCNT Mask */ + +/* DWT Folded-instruction Count Register Definitions */ +#define DWT_FOLDCNT_FOLDCNT_Pos 0U /*!< DWT FOLDCNT: FOLDCNT Position */ +#define DWT_FOLDCNT_FOLDCNT_Msk (0xFFUL /*<< DWT_FOLDCNT_FOLDCNT_Pos*/) /*!< DWT FOLDCNT: FOLDCNT Mask */ + +/* DWT Comparator Mask Register Definitions */ +#define DWT_MASK_MASK_Pos 0U /*!< DWT MASK: MASK Position */ +#define DWT_MASK_MASK_Msk (0x1FUL /*<< DWT_MASK_MASK_Pos*/) /*!< DWT MASK: MASK Mask */ + +/* DWT Comparator Function Register Definitions */ +#define DWT_FUNCTION_MATCHED_Pos 24U /*!< DWT FUNCTION: MATCHED Position */ +#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ + +#define DWT_FUNCTION_DATAVADDR1_Pos 16U /*!< DWT FUNCTION: DATAVADDR1 Position */ +#define DWT_FUNCTION_DATAVADDR1_Msk (0xFUL << DWT_FUNCTION_DATAVADDR1_Pos) /*!< DWT FUNCTION: DATAVADDR1 Mask */ + +#define DWT_FUNCTION_DATAVADDR0_Pos 12U /*!< DWT FUNCTION: DATAVADDR0 Position */ +#define DWT_FUNCTION_DATAVADDR0_Msk (0xFUL << DWT_FUNCTION_DATAVADDR0_Pos) /*!< DWT FUNCTION: DATAVADDR0 Mask */ + +#define DWT_FUNCTION_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */ +#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ + +#define DWT_FUNCTION_LNK1ENA_Pos 9U /*!< DWT FUNCTION: LNK1ENA Position */ +#define DWT_FUNCTION_LNK1ENA_Msk (0x1UL << DWT_FUNCTION_LNK1ENA_Pos) /*!< DWT FUNCTION: LNK1ENA Mask */ + +#define DWT_FUNCTION_DATAVMATCH_Pos 8U /*!< DWT FUNCTION: DATAVMATCH Position */ +#define DWT_FUNCTION_DATAVMATCH_Msk (0x1UL << DWT_FUNCTION_DATAVMATCH_Pos) /*!< DWT FUNCTION: DATAVMATCH Mask */ + +#define DWT_FUNCTION_CYCMATCH_Pos 7U /*!< DWT FUNCTION: CYCMATCH Position */ +#define DWT_FUNCTION_CYCMATCH_Msk (0x1UL << DWT_FUNCTION_CYCMATCH_Pos) /*!< DWT FUNCTION: CYCMATCH Mask */ + +#define DWT_FUNCTION_EMITRANGE_Pos 5U /*!< DWT FUNCTION: EMITRANGE Position */ +#define DWT_FUNCTION_EMITRANGE_Msk (0x1UL << DWT_FUNCTION_EMITRANGE_Pos) /*!< DWT FUNCTION: EMITRANGE Mask */ + +#define DWT_FUNCTION_FUNCTION_Pos 0U /*!< DWT FUNCTION: FUNCTION Position */ +#define DWT_FUNCTION_FUNCTION_Msk (0xFUL /*<< DWT_FUNCTION_FUNCTION_Pos*/) /*!< DWT FUNCTION: FUNCTION Mask */ + +/*@}*/ /* end of group CMSIS_DWT */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_TPI Trace Port Interface (TPI) + \brief Type definitions for the Trace Port Interface (TPI) + @{ + */ + +/** + \brief Structure type to access the Trace Port Interface Register (TPI). + */ +typedef struct +{ + __IM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ + __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ + uint32_t RESERVED0[2U]; + __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ + uint32_t RESERVED1[55U]; + __IOM uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ + uint32_t RESERVED2[131U]; + __IM uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ + __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ + __IM uint32_t FSCR; /*!< Offset: 0x308 (R/ ) Formatter Synchronization Counter Register */ + uint32_t RESERVED3[759U]; + __IM uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER Register */ + __IM uint32_t FIFO0; /*!< Offset: 0xEEC (R/ ) Integration ETM Data */ + __IM uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/ ) ITATBCTR2 */ + uint32_t RESERVED4[1U]; + __IM uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) ITATBCTR0 */ + __IM uint32_t FIFO1; /*!< Offset: 0xEFC (R/ ) Integration ITM Data */ + __IOM uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */ + uint32_t RESERVED5[39U]; + __IOM uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */ + __IOM uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */ + uint32_t RESERVED7[8U]; + __IM uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) TPIU_DEVID */ + __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) TPIU_DEVTYPE */ +} TPI_Type; + +/* TPI Asynchronous Clock Prescaler Register Definitions */ +#define TPI_ACPR_PRESCALER_Pos 0U /*!< TPI ACPR: PRESCALER Position */ +#define TPI_ACPR_PRESCALER_Msk (0x1FFFUL /*<< TPI_ACPR_PRESCALER_Pos*/) /*!< TPI ACPR: PRESCALER Mask */ + +/* TPI Selected Pin Protocol Register Definitions */ +#define TPI_SPPR_TXMODE_Pos 0U /*!< TPI SPPR: TXMODE Position */ +#define TPI_SPPR_TXMODE_Msk (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/) /*!< TPI SPPR: TXMODE Mask */ + +/* TPI Formatter and Flush Status Register Definitions */ +#define TPI_FFSR_FtNonStop_Pos 3U /*!< TPI FFSR: FtNonStop Position */ +#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ + +#define TPI_FFSR_TCPresent_Pos 2U /*!< TPI FFSR: TCPresent Position */ +#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ + +#define TPI_FFSR_FtStopped_Pos 1U /*!< TPI FFSR: FtStopped Position */ +#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ + +#define TPI_FFSR_FlInProg_Pos 0U /*!< TPI FFSR: FlInProg Position */ +#define TPI_FFSR_FlInProg_Msk (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/) /*!< TPI FFSR: FlInProg Mask */ + +/* TPI Formatter and Flush Control Register Definitions */ +#define TPI_FFCR_TrigIn_Pos 8U /*!< TPI FFCR: TrigIn Position */ +#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ + +#define TPI_FFCR_EnFCont_Pos 1U /*!< TPI FFCR: EnFCont Position */ +#define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ + +/* TPI TRIGGER Register Definitions */ +#define TPI_TRIGGER_TRIGGER_Pos 0U /*!< TPI TRIGGER: TRIGGER Position */ +#define TPI_TRIGGER_TRIGGER_Msk (0x1UL /*<< TPI_TRIGGER_TRIGGER_Pos*/) /*!< TPI TRIGGER: TRIGGER Mask */ + +/* TPI Integration ETM Data Register Definitions (FIFO0) */ +#define TPI_FIFO0_ITM_ATVALID_Pos 29U /*!< TPI FIFO0: ITM_ATVALID Position */ +#define TPI_FIFO0_ITM_ATVALID_Msk (0x3UL << TPI_FIFO0_ITM_ATVALID_Pos) /*!< TPI FIFO0: ITM_ATVALID Mask */ + +#define TPI_FIFO0_ITM_bytecount_Pos 27U /*!< TPI FIFO0: ITM_bytecount Position */ +#define TPI_FIFO0_ITM_bytecount_Msk (0x3UL << TPI_FIFO0_ITM_bytecount_Pos) /*!< TPI FIFO0: ITM_bytecount Mask */ + +#define TPI_FIFO0_ETM_ATVALID_Pos 26U /*!< TPI FIFO0: ETM_ATVALID Position */ +#define TPI_FIFO0_ETM_ATVALID_Msk (0x3UL << TPI_FIFO0_ETM_ATVALID_Pos) /*!< TPI FIFO0: ETM_ATVALID Mask */ + +#define TPI_FIFO0_ETM_bytecount_Pos 24U /*!< TPI FIFO0: ETM_bytecount Position */ +#define TPI_FIFO0_ETM_bytecount_Msk (0x3UL << TPI_FIFO0_ETM_bytecount_Pos) /*!< TPI FIFO0: ETM_bytecount Mask */ + +#define TPI_FIFO0_ETM2_Pos 16U /*!< TPI FIFO0: ETM2 Position */ +#define TPI_FIFO0_ETM2_Msk (0xFFUL << TPI_FIFO0_ETM2_Pos) /*!< TPI FIFO0: ETM2 Mask */ + +#define TPI_FIFO0_ETM1_Pos 8U /*!< TPI FIFO0: ETM1 Position */ +#define TPI_FIFO0_ETM1_Msk (0xFFUL << TPI_FIFO0_ETM1_Pos) /*!< TPI FIFO0: ETM1 Mask */ + +#define TPI_FIFO0_ETM0_Pos 0U /*!< TPI FIFO0: ETM0 Position */ +#define TPI_FIFO0_ETM0_Msk (0xFFUL /*<< TPI_FIFO0_ETM0_Pos*/) /*!< TPI FIFO0: ETM0 Mask */ + +/* TPI ITATBCTR2 Register Definitions */ +#define TPI_ITATBCTR2_ATREADY2_Pos 0U /*!< TPI ITATBCTR2: ATREADY2 Position */ +#define TPI_ITATBCTR2_ATREADY2_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY2_Pos*/) /*!< TPI ITATBCTR2: ATREADY2 Mask */ + +#define TPI_ITATBCTR2_ATREADY1_Pos 0U /*!< TPI ITATBCTR2: ATREADY1 Position */ +#define TPI_ITATBCTR2_ATREADY1_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY1_Pos*/) /*!< TPI ITATBCTR2: ATREADY1 Mask */ + +/* TPI Integration ITM Data Register Definitions (FIFO1) */ +#define TPI_FIFO1_ITM_ATVALID_Pos 29U /*!< TPI FIFO1: ITM_ATVALID Position */ +#define TPI_FIFO1_ITM_ATVALID_Msk (0x3UL << TPI_FIFO1_ITM_ATVALID_Pos) /*!< TPI FIFO1: ITM_ATVALID Mask */ + +#define TPI_FIFO1_ITM_bytecount_Pos 27U /*!< TPI FIFO1: ITM_bytecount Position */ +#define TPI_FIFO1_ITM_bytecount_Msk (0x3UL << TPI_FIFO1_ITM_bytecount_Pos) /*!< TPI FIFO1: ITM_bytecount Mask */ + +#define TPI_FIFO1_ETM_ATVALID_Pos 26U /*!< TPI FIFO1: ETM_ATVALID Position */ +#define TPI_FIFO1_ETM_ATVALID_Msk (0x3UL << TPI_FIFO1_ETM_ATVALID_Pos) /*!< TPI FIFO1: ETM_ATVALID Mask */ + +#define TPI_FIFO1_ETM_bytecount_Pos 24U /*!< TPI FIFO1: ETM_bytecount Position */ +#define TPI_FIFO1_ETM_bytecount_Msk (0x3UL << TPI_FIFO1_ETM_bytecount_Pos) /*!< TPI FIFO1: ETM_bytecount Mask */ + +#define TPI_FIFO1_ITM2_Pos 16U /*!< TPI FIFO1: ITM2 Position */ +#define TPI_FIFO1_ITM2_Msk (0xFFUL << TPI_FIFO1_ITM2_Pos) /*!< TPI FIFO1: ITM2 Mask */ + +#define TPI_FIFO1_ITM1_Pos 8U /*!< TPI FIFO1: ITM1 Position */ +#define TPI_FIFO1_ITM1_Msk (0xFFUL << TPI_FIFO1_ITM1_Pos) /*!< TPI FIFO1: ITM1 Mask */ + +#define TPI_FIFO1_ITM0_Pos 0U /*!< TPI FIFO1: ITM0 Position */ +#define TPI_FIFO1_ITM0_Msk (0xFFUL /*<< TPI_FIFO1_ITM0_Pos*/) /*!< TPI FIFO1: ITM0 Mask */ + +/* TPI ITATBCTR0 Register Definitions */ +#define TPI_ITATBCTR0_ATREADY2_Pos 0U /*!< TPI ITATBCTR0: ATREADY2 Position */ +#define TPI_ITATBCTR0_ATREADY2_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY2_Pos*/) /*!< TPI ITATBCTR0: ATREADY2 Mask */ + +#define TPI_ITATBCTR0_ATREADY1_Pos 0U /*!< TPI ITATBCTR0: ATREADY1 Position */ +#define TPI_ITATBCTR0_ATREADY1_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY1_Pos*/) /*!< TPI ITATBCTR0: ATREADY1 Mask */ + +/* TPI Integration Mode Control Register Definitions */ +#define TPI_ITCTRL_Mode_Pos 0U /*!< TPI ITCTRL: Mode Position */ +#define TPI_ITCTRL_Mode_Msk (0x3UL /*<< TPI_ITCTRL_Mode_Pos*/) /*!< TPI ITCTRL: Mode Mask */ + +/* TPI DEVID Register Definitions */ +#define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */ +#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ + +#define TPI_DEVID_MANCVALID_Pos 10U /*!< TPI DEVID: MANCVALID Position */ +#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ + +#define TPI_DEVID_PTINVALID_Pos 9U /*!< TPI DEVID: PTINVALID Position */ +#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ + +#define TPI_DEVID_MinBufSz_Pos 6U /*!< TPI DEVID: MinBufSz Position */ +#define TPI_DEVID_MinBufSz_Msk (0x7UL << TPI_DEVID_MinBufSz_Pos) /*!< TPI DEVID: MinBufSz Mask */ + +#define TPI_DEVID_AsynClkIn_Pos 5U /*!< TPI DEVID: AsynClkIn Position */ +#define TPI_DEVID_AsynClkIn_Msk (0x1UL << TPI_DEVID_AsynClkIn_Pos) /*!< TPI DEVID: AsynClkIn Mask */ + +#define TPI_DEVID_NrTraceInput_Pos 0U /*!< TPI DEVID: NrTraceInput Position */ +#define TPI_DEVID_NrTraceInput_Msk (0x1FUL /*<< TPI_DEVID_NrTraceInput_Pos*/) /*!< TPI DEVID: NrTraceInput Mask */ + +/* TPI DEVTYPE Register Definitions */ +#define TPI_DEVTYPE_SubType_Pos 4U /*!< TPI DEVTYPE: SubType Position */ +#define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ + +#define TPI_DEVTYPE_MajorType_Pos 0U /*!< TPI DEVTYPE: MajorType Position */ +#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ + +/*@}*/ /* end of group CMSIS_TPI */ + + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** + \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IOM uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */ + __IOM uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Alias 1 Region Base Address Register */ + __IOM uint32_t RASR_A1; /*!< Offset: 0x018 (R/W) MPU Alias 1 Region Attribute and Size Register */ + __IOM uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Alias 2 Region Base Address Register */ + __IOM uint32_t RASR_A2; /*!< Offset: 0x020 (R/W) MPU Alias 2 Region Attribute and Size Register */ + __IOM uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Alias 3 Region Base Address Register */ + __IOM uint32_t RASR_A3; /*!< Offset: 0x028 (R/W) MPU Alias 3 Region Attribute and Size Register */ +} MPU_Type; + +#define MPU_TYPE_RALIASES 4U + +/* MPU Type Register Definitions */ +#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register Definitions */ +#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register Definitions */ +#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register Definitions */ +#define MPU_RBAR_ADDR_Pos 5U /*!< MPU RBAR: ADDR Position */ +#define MPU_RBAR_ADDR_Msk (0x7FFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ + +#define MPU_RBAR_VALID_Pos 4U /*!< MPU RBAR: VALID Position */ +#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */ + +#define MPU_RBAR_REGION_Pos 0U /*!< MPU RBAR: REGION Position */ +#define MPU_RBAR_REGION_Msk (0xFUL /*<< MPU_RBAR_REGION_Pos*/) /*!< MPU RBAR: REGION Mask */ + +/* MPU Region Attribute and Size Register Definitions */ +#define MPU_RASR_ATTRS_Pos 16U /*!< MPU RASR: MPU Region Attribute field Position */ +#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */ + +#define MPU_RASR_XN_Pos 28U /*!< MPU RASR: ATTRS.XN Position */ +#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */ + +#define MPU_RASR_AP_Pos 24U /*!< MPU RASR: ATTRS.AP Position */ +#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */ + +#define MPU_RASR_TEX_Pos 19U /*!< MPU RASR: ATTRS.TEX Position */ +#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */ + +#define MPU_RASR_S_Pos 18U /*!< MPU RASR: ATTRS.S Position */ +#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */ + +#define MPU_RASR_C_Pos 17U /*!< MPU RASR: ATTRS.C Position */ +#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */ + +#define MPU_RASR_B_Pos 16U /*!< MPU RASR: ATTRS.B Position */ +#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */ + +#define MPU_RASR_SRD_Pos 8U /*!< MPU RASR: Sub-Region Disable Position */ +#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */ + +#define MPU_RASR_SIZE_Pos 1U /*!< MPU RASR: Region Size Field Position */ +#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */ + +#define MPU_RASR_ENABLE_Pos 0U /*!< MPU RASR: Region enable bit Position */ +#define MPU_RASR_ENABLE_Msk (1UL /*<< MPU_RASR_ENABLE_Pos*/) /*!< MPU RASR: Region enable bit Disable Mask */ + +/*@} end of group CMSIS_MPU */ +#endif /* defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_FPU Floating Point Unit (FPU) + \brief Type definitions for the Floating Point Unit (FPU) + @{ + */ + +/** + \brief Structure type to access the Floating Point Unit (FPU). + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IOM uint32_t FPCCR; /*!< Offset: 0x004 (R/W) Floating-Point Context Control Register */ + __IOM uint32_t FPCAR; /*!< Offset: 0x008 (R/W) Floating-Point Context Address Register */ + __IOM uint32_t FPDSCR; /*!< Offset: 0x00C (R/W) Floating-Point Default Status Control Register */ + __IM uint32_t MVFR0; /*!< Offset: 0x010 (R/ ) Media and FP Feature Register 0 */ + __IM uint32_t MVFR1; /*!< Offset: 0x014 (R/ ) Media and FP Feature Register 1 */ +} FPU_Type; + +/* Floating-Point Context Control Register Definitions */ +#define FPU_FPCCR_ASPEN_Pos 31U /*!< FPCCR: ASPEN bit Position */ +#define FPU_FPCCR_ASPEN_Msk (1UL << FPU_FPCCR_ASPEN_Pos) /*!< FPCCR: ASPEN bit Mask */ + +#define FPU_FPCCR_LSPEN_Pos 30U /*!< FPCCR: LSPEN Position */ +#define FPU_FPCCR_LSPEN_Msk (1UL << FPU_FPCCR_LSPEN_Pos) /*!< FPCCR: LSPEN bit Mask */ + +#define FPU_FPCCR_MONRDY_Pos 8U /*!< FPCCR: MONRDY Position */ +#define FPU_FPCCR_MONRDY_Msk (1UL << FPU_FPCCR_MONRDY_Pos) /*!< FPCCR: MONRDY bit Mask */ + +#define FPU_FPCCR_BFRDY_Pos 6U /*!< FPCCR: BFRDY Position */ +#define FPU_FPCCR_BFRDY_Msk (1UL << FPU_FPCCR_BFRDY_Pos) /*!< FPCCR: BFRDY bit Mask */ + +#define FPU_FPCCR_MMRDY_Pos 5U /*!< FPCCR: MMRDY Position */ +#define FPU_FPCCR_MMRDY_Msk (1UL << FPU_FPCCR_MMRDY_Pos) /*!< FPCCR: MMRDY bit Mask */ + +#define FPU_FPCCR_HFRDY_Pos 4U /*!< FPCCR: HFRDY Position */ +#define FPU_FPCCR_HFRDY_Msk (1UL << FPU_FPCCR_HFRDY_Pos) /*!< FPCCR: HFRDY bit Mask */ + +#define FPU_FPCCR_THREAD_Pos 3U /*!< FPCCR: processor mode bit Position */ +#define FPU_FPCCR_THREAD_Msk (1UL << FPU_FPCCR_THREAD_Pos) /*!< FPCCR: processor mode active bit Mask */ + +#define FPU_FPCCR_USER_Pos 1U /*!< FPCCR: privilege level bit Position */ +#define FPU_FPCCR_USER_Msk (1UL << FPU_FPCCR_USER_Pos) /*!< FPCCR: privilege level bit Mask */ + +#define FPU_FPCCR_LSPACT_Pos 0U /*!< FPCCR: Lazy state preservation active bit Position */ +#define FPU_FPCCR_LSPACT_Msk (1UL /*<< FPU_FPCCR_LSPACT_Pos*/) /*!< FPCCR: Lazy state preservation active bit Mask */ + +/* Floating-Point Context Address Register Definitions */ +#define FPU_FPCAR_ADDRESS_Pos 3U /*!< FPCAR: ADDRESS bit Position */ +#define FPU_FPCAR_ADDRESS_Msk (0x1FFFFFFFUL << FPU_FPCAR_ADDRESS_Pos) /*!< FPCAR: ADDRESS bit Mask */ + +/* Floating-Point Default Status Control Register Definitions */ +#define FPU_FPDSCR_AHP_Pos 26U /*!< FPDSCR: AHP bit Position */ +#define FPU_FPDSCR_AHP_Msk (1UL << FPU_FPDSCR_AHP_Pos) /*!< FPDSCR: AHP bit Mask */ + +#define FPU_FPDSCR_DN_Pos 25U /*!< FPDSCR: DN bit Position */ +#define FPU_FPDSCR_DN_Msk (1UL << FPU_FPDSCR_DN_Pos) /*!< FPDSCR: DN bit Mask */ + +#define FPU_FPDSCR_FZ_Pos 24U /*!< FPDSCR: FZ bit Position */ +#define FPU_FPDSCR_FZ_Msk (1UL << FPU_FPDSCR_FZ_Pos) /*!< FPDSCR: FZ bit Mask */ + +#define FPU_FPDSCR_RMode_Pos 22U /*!< FPDSCR: RMode bit Position */ +#define FPU_FPDSCR_RMode_Msk (3UL << FPU_FPDSCR_RMode_Pos) /*!< FPDSCR: RMode bit Mask */ + +/* Media and FP Feature Register 0 Definitions */ +#define FPU_MVFR0_FP_rounding_modes_Pos 28U /*!< MVFR0: FP rounding modes bits Position */ +#define FPU_MVFR0_FP_rounding_modes_Msk (0xFUL << FPU_MVFR0_FP_rounding_modes_Pos) /*!< MVFR0: FP rounding modes bits Mask */ + +#define FPU_MVFR0_Short_vectors_Pos 24U /*!< MVFR0: Short vectors bits Position */ +#define FPU_MVFR0_Short_vectors_Msk (0xFUL << FPU_MVFR0_Short_vectors_Pos) /*!< MVFR0: Short vectors bits Mask */ + +#define FPU_MVFR0_Square_root_Pos 20U /*!< MVFR0: Square root bits Position */ +#define FPU_MVFR0_Square_root_Msk (0xFUL << FPU_MVFR0_Square_root_Pos) /*!< MVFR0: Square root bits Mask */ + +#define FPU_MVFR0_Divide_Pos 16U /*!< MVFR0: Divide bits Position */ +#define FPU_MVFR0_Divide_Msk (0xFUL << FPU_MVFR0_Divide_Pos) /*!< MVFR0: Divide bits Mask */ + +#define FPU_MVFR0_FP_excep_trapping_Pos 12U /*!< MVFR0: FP exception trapping bits Position */ +#define FPU_MVFR0_FP_excep_trapping_Msk (0xFUL << FPU_MVFR0_FP_excep_trapping_Pos) /*!< MVFR0: FP exception trapping bits Mask */ + +#define FPU_MVFR0_Double_precision_Pos 8U /*!< MVFR0: Double-precision bits Position */ +#define FPU_MVFR0_Double_precision_Msk (0xFUL << FPU_MVFR0_Double_precision_Pos) /*!< MVFR0: Double-precision bits Mask */ + +#define FPU_MVFR0_Single_precision_Pos 4U /*!< MVFR0: Single-precision bits Position */ +#define FPU_MVFR0_Single_precision_Msk (0xFUL << FPU_MVFR0_Single_precision_Pos) /*!< MVFR0: Single-precision bits Mask */ + +#define FPU_MVFR0_A_SIMD_registers_Pos 0U /*!< MVFR0: A_SIMD registers bits Position */ +#define FPU_MVFR0_A_SIMD_registers_Msk (0xFUL /*<< FPU_MVFR0_A_SIMD_registers_Pos*/) /*!< MVFR0: A_SIMD registers bits Mask */ + +/* Media and FP Feature Register 1 Definitions */ +#define FPU_MVFR1_FP_fused_MAC_Pos 28U /*!< MVFR1: FP fused MAC bits Position */ +#define FPU_MVFR1_FP_fused_MAC_Msk (0xFUL << FPU_MVFR1_FP_fused_MAC_Pos) /*!< MVFR1: FP fused MAC bits Mask */ + +#define FPU_MVFR1_FP_HPFP_Pos 24U /*!< MVFR1: FP HPFP bits Position */ +#define FPU_MVFR1_FP_HPFP_Msk (0xFUL << FPU_MVFR1_FP_HPFP_Pos) /*!< MVFR1: FP HPFP bits Mask */ + +#define FPU_MVFR1_D_NaN_mode_Pos 4U /*!< MVFR1: D_NaN mode bits Position */ +#define FPU_MVFR1_D_NaN_mode_Msk (0xFUL << FPU_MVFR1_D_NaN_mode_Pos) /*!< MVFR1: D_NaN mode bits Mask */ + +#define FPU_MVFR1_FtZ_mode_Pos 0U /*!< MVFR1: FtZ mode bits Position */ +#define FPU_MVFR1_FtZ_mode_Msk (0xFUL /*<< FPU_MVFR1_FtZ_mode_Pos*/) /*!< MVFR1: FtZ mode bits Mask */ + +/*@} end of group CMSIS_FPU */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Type definitions for the Core Debug Registers + @{ + */ + +/** + \brief Structure type to access the Core Debug Register (CoreDebug). + */ +typedef struct +{ + __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ +} CoreDebug_Type; + +/* Debug Halting Control and Status Register Definitions */ +#define CoreDebug_DHCSR_DBGKEY_Pos 16U /*!< CoreDebug DHCSR: DBGKEY Position */ +#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */ + +#define CoreDebug_DHCSR_S_RESET_ST_Pos 25U /*!< CoreDebug DHCSR: S_RESET_ST Position */ +#define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< CoreDebug DHCSR: S_RESET_ST Mask */ + +#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24U /*!< CoreDebug DHCSR: S_RETIRE_ST Position */ +#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */ + +#define CoreDebug_DHCSR_S_LOCKUP_Pos 19U /*!< CoreDebug DHCSR: S_LOCKUP Position */ +#define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< CoreDebug DHCSR: S_LOCKUP Mask */ + +#define CoreDebug_DHCSR_S_SLEEP_Pos 18U /*!< CoreDebug DHCSR: S_SLEEP Position */ +#define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< CoreDebug DHCSR: S_SLEEP Mask */ + +#define CoreDebug_DHCSR_S_HALT_Pos 17U /*!< CoreDebug DHCSR: S_HALT Position */ +#define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< CoreDebug DHCSR: S_HALT Mask */ + +#define CoreDebug_DHCSR_S_REGRDY_Pos 16U /*!< CoreDebug DHCSR: S_REGRDY Position */ +#define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< CoreDebug DHCSR: S_REGRDY Mask */ + +#define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5U /*!< CoreDebug DHCSR: C_SNAPSTALL Position */ +#define CoreDebug_DHCSR_C_SNAPSTALL_Msk (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos) /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */ + +#define CoreDebug_DHCSR_C_MASKINTS_Pos 3U /*!< CoreDebug DHCSR: C_MASKINTS Position */ +#define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< CoreDebug DHCSR: C_MASKINTS Mask */ + +#define CoreDebug_DHCSR_C_STEP_Pos 2U /*!< CoreDebug DHCSR: C_STEP Position */ +#define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< CoreDebug DHCSR: C_STEP Mask */ + +#define CoreDebug_DHCSR_C_HALT_Pos 1U /*!< CoreDebug DHCSR: C_HALT Position */ +#define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< CoreDebug DHCSR: C_HALT Mask */ + +#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0U /*!< CoreDebug DHCSR: C_DEBUGEN Position */ +#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */ + +/* Debug Core Register Selector Register Definitions */ +#define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< CoreDebug DCRSR: REGWnR Position */ +#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ + +#define CoreDebug_DCRSR_REGSEL_Pos 0U /*!< CoreDebug DCRSR: REGSEL Position */ +#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/) /*!< CoreDebug DCRSR: REGSEL Mask */ + +/* Debug Exception and Monitor Control Register Definitions */ +#define CoreDebug_DEMCR_TRCENA_Pos 24U /*!< CoreDebug DEMCR: TRCENA Position */ +#define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< CoreDebug DEMCR: TRCENA Mask */ + +#define CoreDebug_DEMCR_MON_REQ_Pos 19U /*!< CoreDebug DEMCR: MON_REQ Position */ +#define CoreDebug_DEMCR_MON_REQ_Msk (1UL << CoreDebug_DEMCR_MON_REQ_Pos) /*!< CoreDebug DEMCR: MON_REQ Mask */ + +#define CoreDebug_DEMCR_MON_STEP_Pos 18U /*!< CoreDebug DEMCR: MON_STEP Position */ +#define CoreDebug_DEMCR_MON_STEP_Msk (1UL << CoreDebug_DEMCR_MON_STEP_Pos) /*!< CoreDebug DEMCR: MON_STEP Mask */ + +#define CoreDebug_DEMCR_MON_PEND_Pos 17U /*!< CoreDebug DEMCR: MON_PEND Position */ +#define CoreDebug_DEMCR_MON_PEND_Msk (1UL << CoreDebug_DEMCR_MON_PEND_Pos) /*!< CoreDebug DEMCR: MON_PEND Mask */ + +#define CoreDebug_DEMCR_MON_EN_Pos 16U /*!< CoreDebug DEMCR: MON_EN Position */ +#define CoreDebug_DEMCR_MON_EN_Msk (1UL << CoreDebug_DEMCR_MON_EN_Pos) /*!< CoreDebug DEMCR: MON_EN Mask */ + +#define CoreDebug_DEMCR_VC_HARDERR_Pos 10U /*!< CoreDebug DEMCR: VC_HARDERR Position */ +#define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< CoreDebug DEMCR: VC_HARDERR Mask */ + +#define CoreDebug_DEMCR_VC_INTERR_Pos 9U /*!< CoreDebug DEMCR: VC_INTERR Position */ +#define CoreDebug_DEMCR_VC_INTERR_Msk (1UL << CoreDebug_DEMCR_VC_INTERR_Pos) /*!< CoreDebug DEMCR: VC_INTERR Mask */ + +#define CoreDebug_DEMCR_VC_BUSERR_Pos 8U /*!< CoreDebug DEMCR: VC_BUSERR Position */ +#define CoreDebug_DEMCR_VC_BUSERR_Msk (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos) /*!< CoreDebug DEMCR: VC_BUSERR Mask */ + +#define CoreDebug_DEMCR_VC_STATERR_Pos 7U /*!< CoreDebug DEMCR: VC_STATERR Position */ +#define CoreDebug_DEMCR_VC_STATERR_Msk (1UL << CoreDebug_DEMCR_VC_STATERR_Pos) /*!< CoreDebug DEMCR: VC_STATERR Mask */ + +#define CoreDebug_DEMCR_VC_CHKERR_Pos 6U /*!< CoreDebug DEMCR: VC_CHKERR Position */ +#define CoreDebug_DEMCR_VC_CHKERR_Msk (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos) /*!< CoreDebug DEMCR: VC_CHKERR Mask */ + +#define CoreDebug_DEMCR_VC_NOCPERR_Pos 5U /*!< CoreDebug DEMCR: VC_NOCPERR Position */ +#define CoreDebug_DEMCR_VC_NOCPERR_Msk (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos) /*!< CoreDebug DEMCR: VC_NOCPERR Mask */ + +#define CoreDebug_DEMCR_VC_MMERR_Pos 4U /*!< CoreDebug DEMCR: VC_MMERR Position */ +#define CoreDebug_DEMCR_VC_MMERR_Msk (1UL << CoreDebug_DEMCR_VC_MMERR_Pos) /*!< CoreDebug DEMCR: VC_MMERR Mask */ + +#define CoreDebug_DEMCR_VC_CORERESET_Pos 0U /*!< CoreDebug DEMCR: VC_CORERESET Position */ +#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/) /*!< CoreDebug DEMCR: VC_CORERESET Mask */ + +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param[in] field Name of the register bit field. + \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param[in] field Name of the register bit field. + \param[in] value Value of register. This parameter is interpreted as an uint32_t type. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) + +/*@} end of group CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Core Hardware */ +#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ +#define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ +#define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ +#define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ +#define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */ +#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ +#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ +#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + +#define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ +#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ +#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ +#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ +#define ITM ((ITM_Type *) ITM_BASE ) /*!< ITM configuration struct */ +#define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ +#define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ +#define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE) /*!< Core Debug configuration struct */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ +#endif + +#define FPU_BASE (SCS_BASE + 0x0F30UL) /*!< Floating Point Unit */ +#define FPU ((FPU_Type *) FPU_BASE ) /*!< Floating Point Unit */ + +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Debug Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping + #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping + #define NVIC_EnableIRQ __NVIC_EnableIRQ + #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ + #define NVIC_DisableIRQ __NVIC_DisableIRQ + #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ + #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ + #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ + #define NVIC_GetActive __NVIC_GetActive + #define NVIC_SetPriority __NVIC_SetPriority + #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset +#endif /* CMSIS_NVIC_VIRTUAL */ + +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetVector __NVIC_SetVector + #define NVIC_GetVector __NVIC_GetVector +#endif /* (CMSIS_VECTAB_VIRTUAL) */ + +#define NVIC_USER_IRQ_OFFSET 16 + + +/* The following EXC_RETURN values are saved the LR on exception entry */ +#define EXC_RETURN_HANDLER (0xFFFFFFF1UL) /* return to Handler mode, uses MSP after return */ +#define EXC_RETURN_THREAD_MSP (0xFFFFFFF9UL) /* return to Thread mode, uses MSP after return */ +#define EXC_RETURN_THREAD_PSP (0xFFFFFFFDUL) /* return to Thread mode, uses PSP after return */ +#define EXC_RETURN_HANDLER_FPU (0xFFFFFFE1UL) /* return to Handler mode, uses MSP after return, restore floating-point state */ +#define EXC_RETURN_THREAD_MSP_FPU (0xFFFFFFE9UL) /* return to Thread mode, uses MSP after return, restore floating-point state */ +#define EXC_RETURN_THREAD_PSP_FPU (0xFFFFFFEDUL) /* return to Thread mode, uses PSP after return, restore floating-point state */ + + +/** + \brief Set Priority Grouping + \details Sets the priority grouping field using the required unlock sequence. + The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. + Only values from 0..7 are used. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Priority grouping field. + */ +__STATIC_INLINE void __NVIC_SetPriorityGrouping(uint32_t PriorityGroup) +{ + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + + reg_value = SCB->AIRCR; /* read old register configuration */ + reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << SCB_AIRCR_PRIGROUP_Pos) ); /* Insert write key and priority group */ + SCB->AIRCR = reg_value; +} + + +/** + \brief Get Priority Grouping + \details Reads the priority grouping field from the NVIC Interrupt Controller. + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t __NVIC_GetPriorityGrouping(void) +{ + return ((uint32_t)((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); +} + + +/** + \brief Enable Interrupt + \details Enables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Interrupt Enable status + \details Returns a device specific interrupt enable status from the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt + \details Disables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __DSB(); + __ISB(); + } +} + + +/** + \brief Get Pending Interrupt + \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt + \details Reads the active register in the NVIC and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetActive(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Priority + \details Sets the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every processor exception. + */ +__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->IP[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } + else + { + SCB->SHP[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return(((uint32_t)NVIC->IP[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return(((uint32_t)SCB->SHP[(((uint32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief Encode Priority + \details Encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + return ( + ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | + ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) + ); +} + + +/** + \brief Decode Priority + \details Decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. + \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); + *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); +} + + +/** + \brief Set Interrupt Vector + \details Sets an interrupt vector in SRAM based interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + VTOR must been relocated to SRAM before. + \param [in] IRQn Interrupt number + \param [in] vector Address of interrupt handler function + */ +__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; +} + + +/** + \brief Get Interrupt Vector + \details Reads an interrupt vector from interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Address of interrupt handler function + */ +__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET]; +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + SCB_AIRCR_SYSRESETREQ_Msk ); /* Keep priority group unchanged */ + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +/*@} end of CMSIS_Core_NVICFunctions */ + +/* ########################## MPU functions #################################### */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + +#include "mpu_armv7.h" + +#endif + + +/* ########################## FPU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_FpuFunctions FPU Functions + \brief Function that provides FPU type. + @{ + */ + +/** + \brief get FPU type + \details returns the FPU type + \returns + - \b 0: No FPU + - \b 1: Single precision FPU + - \b 2: Double + Single precision FPU + */ +__STATIC_INLINE uint32_t SCB_GetFPUType(void) +{ + uint32_t mvfr0; + + mvfr0 = FPU->MVFR0; + if ((mvfr0 & (FPU_MVFR0_Single_precision_Msk | FPU_MVFR0_Double_precision_Msk)) == 0x020U) + { + return 1U; /* Single precision FPU */ + } + else + { + return 0U; /* No FPU */ + } +} + + +/*@} end of CMSIS_Core_FpuFunctions */ + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + +/* ##################################### Debug In/Output function ########################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_core_DebugFunctions ITM Functions + \brief Functions that access the ITM debug interface. + @{ + */ + +extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */ +#define ITM_RXBUFFER_EMPTY ((int32_t)0x5AA55AA5U) /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */ + + +/** + \brief ITM Send Character + \details Transmits a character via the ITM channel 0, and + \li Just returns when no debugger is connected that has booked the output. + \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted. + \param [in] ch Character to transmit. + \returns Character to transmit. + */ +__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch) +{ + if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) && /* ITM enabled */ + ((ITM->TER & 1UL ) != 0UL) ) /* ITM Port #0 enabled */ + { + while (ITM->PORT[0U].u32 == 0UL) + { + __NOP(); + } + ITM->PORT[0U].u8 = (uint8_t)ch; + } + return (ch); +} + + +/** + \brief ITM Receive Character + \details Inputs a character via the external variable \ref ITM_RxBuffer. + \return Received character. + \return -1 No character pending. + */ +__STATIC_INLINE int32_t ITM_ReceiveChar (void) +{ + int32_t ch = -1; /* no character available */ + + if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) + { + ch = ITM_RxBuffer; + ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */ + } + + return (ch); +} + + +/** + \brief ITM Check Character + \details Checks whether a character is pending for reading in the variable \ref ITM_RxBuffer. + \return 0 No character available. + \return 1 Character available. + */ +__STATIC_INLINE int32_t ITM_CheckChar (void) +{ + + if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) + { + return (0); /* no character available */ + } + else + { + return (1); /* character available */ + } +} + +/*@} end of CMSIS_core_DebugFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM4_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/test/STM32F072C8T6/Drivers/CMSIS/Include/core_cm7.h b/test/STM32F072C8T6/Drivers/CMSIS/Include/core_cm7.h new file mode 100644 index 0000000..ada6c2a --- /dev/null +++ b/test/STM32F072C8T6/Drivers/CMSIS/Include/core_cm7.h @@ -0,0 +1,2671 @@ +/**************************************************************************//** + * @file core_cm7.h + * @brief CMSIS Cortex-M7 Core Peripheral Access Layer Header File + * @version V5.0.8 + * @date 04. June 2018 + ******************************************************************************/ +/* + * Copyright (c) 2009-2018 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * 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 + * + * 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. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CORE_CM7_H_GENERIC +#define __CORE_CM7_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup Cortex_M7 + @{ + */ + +#include "cmsis_version.h" + +/* CMSIS CM7 definitions */ +#define __CM7_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __CM7_CMSIS_VERSION_SUB ( __CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ +#define __CM7_CMSIS_VERSION ((__CM7_CMSIS_VERSION_MAIN << 16U) | \ + __CM7_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ + +#define __CORTEX_M (7U) /*!< Cortex-M Core */ + +/** __FPU_USED indicates whether an FPU is used or not. + For this, __FPU_PRESENT has to be checked prior to making use of FPU specific registers and functions. +*/ +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_PCS_VFP + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __TI_ARM__ ) + #if defined __TI_VFP_SUPPORT__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM7_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM7_H_DEPENDANT +#define __CORE_CM7_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM7_REV + #define __CM7_REV 0x0000U + #warning "__CM7_REV not defined in device header file; using default!" + #endif + + #ifndef __FPU_PRESENT + #define __FPU_PRESENT 0U + #warning "__FPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0U + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __ICACHE_PRESENT + #define __ICACHE_PRESENT 0U + #warning "__ICACHE_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __DCACHE_PRESENT + #define __DCACHE_PRESENT 0U + #warning "__DCACHE_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __DTCM_PRESENT + #define __DTCM_PRESENT 0U + #warning "__DTCM_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 3U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group Cortex_M7 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug Register + - Core MPU Register + - Core FPU Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:16; /*!< bit: 0..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:7; /*!< bit: 20..26 Reserved */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + +#define APSR_Q_Pos 27U /*!< APSR: Q Position */ +#define APSR_Q_Msk (1UL << APSR_Q_Pos) /*!< APSR: Q Mask */ + +#define APSR_GE_Pos 16U /*!< APSR: GE Position */ +#define APSR_GE_Msk (0xFUL << APSR_GE_Pos) /*!< APSR: GE Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:1; /*!< bit: 9 Reserved */ + uint32_t ICI_IT_1:6; /*!< bit: 10..15 ICI/IT part 1 */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:4; /*!< bit: 20..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit */ + uint32_t ICI_IT_2:2; /*!< bit: 25..26 ICI/IT part 2 */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_Q_Pos 27U /*!< xPSR: Q Position */ +#define xPSR_Q_Msk (1UL << xPSR_Q_Pos) /*!< xPSR: Q Mask */ + +#define xPSR_ICI_IT_2_Pos 25U /*!< xPSR: ICI/IT part 2 Position */ +#define xPSR_ICI_IT_2_Msk (3UL << xPSR_ICI_IT_2_Pos) /*!< xPSR: ICI/IT part 2 Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_GE_Pos 16U /*!< xPSR: GE Position */ +#define xPSR_GE_Msk (0xFUL << xPSR_GE_Pos) /*!< xPSR: GE Mask */ + +#define xPSR_ICI_IT_1_Pos 10U /*!< xPSR: ICI/IT part 1 Position */ +#define xPSR_ICI_IT_1_Msk (0x3FUL << xPSR_ICI_IT_1_Pos) /*!< xPSR: ICI/IT part 1 Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ + uint32_t FPCA:1; /*!< bit: 2 FP extension active flag */ + uint32_t _reserved0:29; /*!< bit: 3..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_FPCA_Pos 2U /*!< CONTROL: FPCA Position */ +#define CONTROL_FPCA_Msk (1UL << CONTROL_FPCA_Pos) /*!< CONTROL: FPCA Mask */ + +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ +#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[8U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[24U]; + __IOM uint32_t ICER[8U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[24U]; + __IOM uint32_t ISPR[8U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[24U]; + __IOM uint32_t ICPR[8U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[24U]; + __IOM uint32_t IABR[8U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[56U]; + __IOM uint8_t IP[240U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ + uint32_t RESERVED5[644U]; + __OM uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ +} NVIC_Type; + +/* Software Triggered Interrupt Register Definitions */ +#define NVIC_STIR_INTID_Pos 0U /*!< STIR: INTLINESNUM Position */ +#define NVIC_STIR_INTID_Msk (0x1FFUL /*<< NVIC_STIR_INTID_Pos*/) /*!< STIR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + __IOM uint8_t SHPR[12U]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ + __IOM uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ + __IOM uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ + __IOM uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ + __IOM uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ + __IOM uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ + __IOM uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ + __IM uint32_t ID_PFR[2U]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ + __IM uint32_t ID_DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ + __IM uint32_t ID_AFR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ + __IM uint32_t ID_MFR[4U]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ + __IM uint32_t ID_ISAR[5U]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ + uint32_t RESERVED0[1U]; + __IM uint32_t CLIDR; /*!< Offset: 0x078 (R/ ) Cache Level ID register */ + __IM uint32_t CTR; /*!< Offset: 0x07C (R/ ) Cache Type register */ + __IM uint32_t CCSIDR; /*!< Offset: 0x080 (R/ ) Cache Size ID Register */ + __IOM uint32_t CSSELR; /*!< Offset: 0x084 (R/W) Cache Size Selection Register */ + __IOM uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ + uint32_t RESERVED3[93U]; + __OM uint32_t STIR; /*!< Offset: 0x200 ( /W) Software Triggered Interrupt Register */ + uint32_t RESERVED4[15U]; + __IM uint32_t MVFR0; /*!< Offset: 0x240 (R/ ) Media and VFP Feature Register 0 */ + __IM uint32_t MVFR1; /*!< Offset: 0x244 (R/ ) Media and VFP Feature Register 1 */ + __IM uint32_t MVFR2; /*!< Offset: 0x248 (R/ ) Media and VFP Feature Register 2 */ + uint32_t RESERVED5[1U]; + __OM uint32_t ICIALLU; /*!< Offset: 0x250 ( /W) I-Cache Invalidate All to PoU */ + uint32_t RESERVED6[1U]; + __OM uint32_t ICIMVAU; /*!< Offset: 0x258 ( /W) I-Cache Invalidate by MVA to PoU */ + __OM uint32_t DCIMVAC; /*!< Offset: 0x25C ( /W) D-Cache Invalidate by MVA to PoC */ + __OM uint32_t DCISW; /*!< Offset: 0x260 ( /W) D-Cache Invalidate by Set-way */ + __OM uint32_t DCCMVAU; /*!< Offset: 0x264 ( /W) D-Cache Clean by MVA to PoU */ + __OM uint32_t DCCMVAC; /*!< Offset: 0x268 ( /W) D-Cache Clean by MVA to PoC */ + __OM uint32_t DCCSW; /*!< Offset: 0x26C ( /W) D-Cache Clean by Set-way */ + __OM uint32_t DCCIMVAC; /*!< Offset: 0x270 ( /W) D-Cache Clean and Invalidate by MVA to PoC */ + __OM uint32_t DCCISW; /*!< Offset: 0x274 ( /W) D-Cache Clean and Invalidate by Set-way */ + uint32_t RESERVED7[6U]; + __IOM uint32_t ITCMCR; /*!< Offset: 0x290 (R/W) Instruction Tightly-Coupled Memory Control Register */ + __IOM uint32_t DTCMCR; /*!< Offset: 0x294 (R/W) Data Tightly-Coupled Memory Control Registers */ + __IOM uint32_t AHBPCR; /*!< Offset: 0x298 (R/W) AHBP Control Register */ + __IOM uint32_t CACR; /*!< Offset: 0x29C (R/W) L1 Cache Control Register */ + __IOM uint32_t AHBSCR; /*!< Offset: 0x2A0 (R/W) AHB Slave Control Register */ + uint32_t RESERVED8[1U]; + __IOM uint32_t ABFSR; /*!< Offset: 0x2A8 (R/W) Auxiliary Bus Fault Status Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */ +#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_RETTOBASE_Pos 11U /*!< SCB ICSR: RETTOBASE Position */ +#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Vector Table Offset Register Definitions */ +#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_PRIGROUP_Pos 8U /*!< SCB AIRCR: PRIGROUP Position */ +#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +#define SCB_AIRCR_VECTRESET_Pos 0U /*!< SCB AIRCR: VECTRESET Position */ +#define SCB_AIRCR_VECTRESET_Msk (1UL /*<< SCB_AIRCR_VECTRESET_Pos*/) /*!< SCB AIRCR: VECTRESET Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_BP_Pos 18U /*!< SCB CCR: Branch prediction enable bit Position */ +#define SCB_CCR_BP_Msk (1UL << SCB_CCR_BP_Pos) /*!< SCB CCR: Branch prediction enable bit Mask */ + +#define SCB_CCR_IC_Pos 17U /*!< SCB CCR: Instruction cache enable bit Position */ +#define SCB_CCR_IC_Msk (1UL << SCB_CCR_IC_Pos) /*!< SCB CCR: Instruction cache enable bit Mask */ + +#define SCB_CCR_DC_Pos 16U /*!< SCB CCR: Cache enable bit Position */ +#define SCB_CCR_DC_Msk (1UL << SCB_CCR_DC_Pos) /*!< SCB CCR: Cache enable bit Mask */ + +#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */ +#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ + +#define SCB_CCR_BFHFNMIGN_Pos 8U /*!< SCB CCR: BFHFNMIGN Position */ +#define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ + +#define SCB_CCR_DIV_0_TRP_Pos 4U /*!< SCB CCR: DIV_0_TRP Position */ +#define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +#define SCB_CCR_USERSETMPEND_Pos 1U /*!< SCB CCR: USERSETMPEND Position */ +#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ + +#define SCB_CCR_NONBASETHRDENA_Pos 0U /*!< SCB CCR: NONBASETHRDENA Position */ +#define SCB_CCR_NONBASETHRDENA_Msk (1UL /*<< SCB_CCR_NONBASETHRDENA_Pos*/) /*!< SCB CCR: NONBASETHRDENA Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_USGFAULTENA_Pos 18U /*!< SCB SHCSR: USGFAULTENA Position */ +#define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */ + +#define SCB_SHCSR_BUSFAULTENA_Pos 17U /*!< SCB SHCSR: BUSFAULTENA Position */ +#define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */ + +#define SCB_SHCSR_MEMFAULTENA_Pos 16U /*!< SCB SHCSR: MEMFAULTENA Position */ +#define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */ + +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +#define SCB_SHCSR_BUSFAULTPENDED_Pos 14U /*!< SCB SHCSR: BUSFAULTPENDED Position */ +#define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */ + +#define SCB_SHCSR_MEMFAULTPENDED_Pos 13U /*!< SCB SHCSR: MEMFAULTPENDED Position */ +#define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */ + +#define SCB_SHCSR_USGFAULTPENDED_Pos 12U /*!< SCB SHCSR: USGFAULTPENDED Position */ +#define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */ + +#define SCB_SHCSR_SYSTICKACT_Pos 11U /*!< SCB SHCSR: SYSTICKACT Position */ +#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ + +#define SCB_SHCSR_PENDSVACT_Pos 10U /*!< SCB SHCSR: PENDSVACT Position */ +#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ + +#define SCB_SHCSR_MONITORACT_Pos 8U /*!< SCB SHCSR: MONITORACT Position */ +#define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */ + +#define SCB_SHCSR_SVCALLACT_Pos 7U /*!< SCB SHCSR: SVCALLACT Position */ +#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ + +#define SCB_SHCSR_USGFAULTACT_Pos 3U /*!< SCB SHCSR: USGFAULTACT Position */ +#define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */ + +#define SCB_SHCSR_BUSFAULTACT_Pos 1U /*!< SCB SHCSR: BUSFAULTACT Position */ +#define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */ + +#define SCB_SHCSR_MEMFAULTACT_Pos 0U /*!< SCB SHCSR: MEMFAULTACT Position */ +#define SCB_SHCSR_MEMFAULTACT_Msk (1UL /*<< SCB_SHCSR_MEMFAULTACT_Pos*/) /*!< SCB SHCSR: MEMFAULTACT Mask */ + +/* SCB Configurable Fault Status Register Definitions */ +#define SCB_CFSR_USGFAULTSR_Pos 16U /*!< SCB CFSR: Usage Fault Status Register Position */ +#define SCB_CFSR_USGFAULTSR_Msk (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */ + +#define SCB_CFSR_BUSFAULTSR_Pos 8U /*!< SCB CFSR: Bus Fault Status Register Position */ +#define SCB_CFSR_BUSFAULTSR_Msk (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */ + +#define SCB_CFSR_MEMFAULTSR_Pos 0U /*!< SCB CFSR: Memory Manage Fault Status Register Position */ +#define SCB_CFSR_MEMFAULTSR_Msk (0xFFUL /*<< SCB_CFSR_MEMFAULTSR_Pos*/) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */ + +/* MemManage Fault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_MMARVALID_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 7U) /*!< SCB CFSR (MMFSR): MMARVALID Position */ +#define SCB_CFSR_MMARVALID_Msk (1UL << SCB_CFSR_MMARVALID_Pos) /*!< SCB CFSR (MMFSR): MMARVALID Mask */ + +#define SCB_CFSR_MLSPERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 5U) /*!< SCB CFSR (MMFSR): MLSPERR Position */ +#define SCB_CFSR_MLSPERR_Msk (1UL << SCB_CFSR_MLSPERR_Pos) /*!< SCB CFSR (MMFSR): MLSPERR Mask */ + +#define SCB_CFSR_MSTKERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 4U) /*!< SCB CFSR (MMFSR): MSTKERR Position */ +#define SCB_CFSR_MSTKERR_Msk (1UL << SCB_CFSR_MSTKERR_Pos) /*!< SCB CFSR (MMFSR): MSTKERR Mask */ + +#define SCB_CFSR_MUNSTKERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 3U) /*!< SCB CFSR (MMFSR): MUNSTKERR Position */ +#define SCB_CFSR_MUNSTKERR_Msk (1UL << SCB_CFSR_MUNSTKERR_Pos) /*!< SCB CFSR (MMFSR): MUNSTKERR Mask */ + +#define SCB_CFSR_DACCVIOL_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 1U) /*!< SCB CFSR (MMFSR): DACCVIOL Position */ +#define SCB_CFSR_DACCVIOL_Msk (1UL << SCB_CFSR_DACCVIOL_Pos) /*!< SCB CFSR (MMFSR): DACCVIOL Mask */ + +#define SCB_CFSR_IACCVIOL_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 0U) /*!< SCB CFSR (MMFSR): IACCVIOL Position */ +#define SCB_CFSR_IACCVIOL_Msk (1UL /*<< SCB_CFSR_IACCVIOL_Pos*/) /*!< SCB CFSR (MMFSR): IACCVIOL Mask */ + +/* BusFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_BFARVALID_Pos (SCB_CFSR_BUSFAULTSR_Pos + 7U) /*!< SCB CFSR (BFSR): BFARVALID Position */ +#define SCB_CFSR_BFARVALID_Msk (1UL << SCB_CFSR_BFARVALID_Pos) /*!< SCB CFSR (BFSR): BFARVALID Mask */ + +#define SCB_CFSR_LSPERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 5U) /*!< SCB CFSR (BFSR): LSPERR Position */ +#define SCB_CFSR_LSPERR_Msk (1UL << SCB_CFSR_LSPERR_Pos) /*!< SCB CFSR (BFSR): LSPERR Mask */ + +#define SCB_CFSR_STKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 4U) /*!< SCB CFSR (BFSR): STKERR Position */ +#define SCB_CFSR_STKERR_Msk (1UL << SCB_CFSR_STKERR_Pos) /*!< SCB CFSR (BFSR): STKERR Mask */ + +#define SCB_CFSR_UNSTKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 3U) /*!< SCB CFSR (BFSR): UNSTKERR Position */ +#define SCB_CFSR_UNSTKERR_Msk (1UL << SCB_CFSR_UNSTKERR_Pos) /*!< SCB CFSR (BFSR): UNSTKERR Mask */ + +#define SCB_CFSR_IMPRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 2U) /*!< SCB CFSR (BFSR): IMPRECISERR Position */ +#define SCB_CFSR_IMPRECISERR_Msk (1UL << SCB_CFSR_IMPRECISERR_Pos) /*!< SCB CFSR (BFSR): IMPRECISERR Mask */ + +#define SCB_CFSR_PRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 1U) /*!< SCB CFSR (BFSR): PRECISERR Position */ +#define SCB_CFSR_PRECISERR_Msk (1UL << SCB_CFSR_PRECISERR_Pos) /*!< SCB CFSR (BFSR): PRECISERR Mask */ + +#define SCB_CFSR_IBUSERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 0U) /*!< SCB CFSR (BFSR): IBUSERR Position */ +#define SCB_CFSR_IBUSERR_Msk (1UL << SCB_CFSR_IBUSERR_Pos) /*!< SCB CFSR (BFSR): IBUSERR Mask */ + +/* UsageFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_DIVBYZERO_Pos (SCB_CFSR_USGFAULTSR_Pos + 9U) /*!< SCB CFSR (UFSR): DIVBYZERO Position */ +#define SCB_CFSR_DIVBYZERO_Msk (1UL << SCB_CFSR_DIVBYZERO_Pos) /*!< SCB CFSR (UFSR): DIVBYZERO Mask */ + +#define SCB_CFSR_UNALIGNED_Pos (SCB_CFSR_USGFAULTSR_Pos + 8U) /*!< SCB CFSR (UFSR): UNALIGNED Position */ +#define SCB_CFSR_UNALIGNED_Msk (1UL << SCB_CFSR_UNALIGNED_Pos) /*!< SCB CFSR (UFSR): UNALIGNED Mask */ + +#define SCB_CFSR_NOCP_Pos (SCB_CFSR_USGFAULTSR_Pos + 3U) /*!< SCB CFSR (UFSR): NOCP Position */ +#define SCB_CFSR_NOCP_Msk (1UL << SCB_CFSR_NOCP_Pos) /*!< SCB CFSR (UFSR): NOCP Mask */ + +#define SCB_CFSR_INVPC_Pos (SCB_CFSR_USGFAULTSR_Pos + 2U) /*!< SCB CFSR (UFSR): INVPC Position */ +#define SCB_CFSR_INVPC_Msk (1UL << SCB_CFSR_INVPC_Pos) /*!< SCB CFSR (UFSR): INVPC Mask */ + +#define SCB_CFSR_INVSTATE_Pos (SCB_CFSR_USGFAULTSR_Pos + 1U) /*!< SCB CFSR (UFSR): INVSTATE Position */ +#define SCB_CFSR_INVSTATE_Msk (1UL << SCB_CFSR_INVSTATE_Pos) /*!< SCB CFSR (UFSR): INVSTATE Mask */ + +#define SCB_CFSR_UNDEFINSTR_Pos (SCB_CFSR_USGFAULTSR_Pos + 0U) /*!< SCB CFSR (UFSR): UNDEFINSTR Position */ +#define SCB_CFSR_UNDEFINSTR_Msk (1UL << SCB_CFSR_UNDEFINSTR_Pos) /*!< SCB CFSR (UFSR): UNDEFINSTR Mask */ + +/* SCB Hard Fault Status Register Definitions */ +#define SCB_HFSR_DEBUGEVT_Pos 31U /*!< SCB HFSR: DEBUGEVT Position */ +#define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ + +#define SCB_HFSR_FORCED_Pos 30U /*!< SCB HFSR: FORCED Position */ +#define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */ + +#define SCB_HFSR_VECTTBL_Pos 1U /*!< SCB HFSR: VECTTBL Position */ +#define SCB_HFSR_VECTTBL_Msk (1UL << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */ + +/* SCB Debug Fault Status Register Definitions */ +#define SCB_DFSR_EXTERNAL_Pos 4U /*!< SCB DFSR: EXTERNAL Position */ +#define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */ + +#define SCB_DFSR_VCATCH_Pos 3U /*!< SCB DFSR: VCATCH Position */ +#define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */ + +#define SCB_DFSR_DWTTRAP_Pos 2U /*!< SCB DFSR: DWTTRAP Position */ +#define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */ + +#define SCB_DFSR_BKPT_Pos 1U /*!< SCB DFSR: BKPT Position */ +#define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */ + +#define SCB_DFSR_HALTED_Pos 0U /*!< SCB DFSR: HALTED Position */ +#define SCB_DFSR_HALTED_Msk (1UL /*<< SCB_DFSR_HALTED_Pos*/) /*!< SCB DFSR: HALTED Mask */ + +/* SCB Cache Level ID Register Definitions */ +#define SCB_CLIDR_LOUU_Pos 27U /*!< SCB CLIDR: LoUU Position */ +#define SCB_CLIDR_LOUU_Msk (7UL << SCB_CLIDR_LOUU_Pos) /*!< SCB CLIDR: LoUU Mask */ + +#define SCB_CLIDR_LOC_Pos 24U /*!< SCB CLIDR: LoC Position */ +#define SCB_CLIDR_LOC_Msk (7UL << SCB_CLIDR_LOC_Pos) /*!< SCB CLIDR: LoC Mask */ + +/* SCB Cache Type Register Definitions */ +#define SCB_CTR_FORMAT_Pos 29U /*!< SCB CTR: Format Position */ +#define SCB_CTR_FORMAT_Msk (7UL << SCB_CTR_FORMAT_Pos) /*!< SCB CTR: Format Mask */ + +#define SCB_CTR_CWG_Pos 24U /*!< SCB CTR: CWG Position */ +#define SCB_CTR_CWG_Msk (0xFUL << SCB_CTR_CWG_Pos) /*!< SCB CTR: CWG Mask */ + +#define SCB_CTR_ERG_Pos 20U /*!< SCB CTR: ERG Position */ +#define SCB_CTR_ERG_Msk (0xFUL << SCB_CTR_ERG_Pos) /*!< SCB CTR: ERG Mask */ + +#define SCB_CTR_DMINLINE_Pos 16U /*!< SCB CTR: DminLine Position */ +#define SCB_CTR_DMINLINE_Msk (0xFUL << SCB_CTR_DMINLINE_Pos) /*!< SCB CTR: DminLine Mask */ + +#define SCB_CTR_IMINLINE_Pos 0U /*!< SCB CTR: ImInLine Position */ +#define SCB_CTR_IMINLINE_Msk (0xFUL /*<< SCB_CTR_IMINLINE_Pos*/) /*!< SCB CTR: ImInLine Mask */ + +/* SCB Cache Size ID Register Definitions */ +#define SCB_CCSIDR_WT_Pos 31U /*!< SCB CCSIDR: WT Position */ +#define SCB_CCSIDR_WT_Msk (1UL << SCB_CCSIDR_WT_Pos) /*!< SCB CCSIDR: WT Mask */ + +#define SCB_CCSIDR_WB_Pos 30U /*!< SCB CCSIDR: WB Position */ +#define SCB_CCSIDR_WB_Msk (1UL << SCB_CCSIDR_WB_Pos) /*!< SCB CCSIDR: WB Mask */ + +#define SCB_CCSIDR_RA_Pos 29U /*!< SCB CCSIDR: RA Position */ +#define SCB_CCSIDR_RA_Msk (1UL << SCB_CCSIDR_RA_Pos) /*!< SCB CCSIDR: RA Mask */ + +#define SCB_CCSIDR_WA_Pos 28U /*!< SCB CCSIDR: WA Position */ +#define SCB_CCSIDR_WA_Msk (1UL << SCB_CCSIDR_WA_Pos) /*!< SCB CCSIDR: WA Mask */ + +#define SCB_CCSIDR_NUMSETS_Pos 13U /*!< SCB CCSIDR: NumSets Position */ +#define SCB_CCSIDR_NUMSETS_Msk (0x7FFFUL << SCB_CCSIDR_NUMSETS_Pos) /*!< SCB CCSIDR: NumSets Mask */ + +#define SCB_CCSIDR_ASSOCIATIVITY_Pos 3U /*!< SCB CCSIDR: Associativity Position */ +#define SCB_CCSIDR_ASSOCIATIVITY_Msk (0x3FFUL << SCB_CCSIDR_ASSOCIATIVITY_Pos) /*!< SCB CCSIDR: Associativity Mask */ + +#define SCB_CCSIDR_LINESIZE_Pos 0U /*!< SCB CCSIDR: LineSize Position */ +#define SCB_CCSIDR_LINESIZE_Msk (7UL /*<< SCB_CCSIDR_LINESIZE_Pos*/) /*!< SCB CCSIDR: LineSize Mask */ + +/* SCB Cache Size Selection Register Definitions */ +#define SCB_CSSELR_LEVEL_Pos 1U /*!< SCB CSSELR: Level Position */ +#define SCB_CSSELR_LEVEL_Msk (7UL << SCB_CSSELR_LEVEL_Pos) /*!< SCB CSSELR: Level Mask */ + +#define SCB_CSSELR_IND_Pos 0U /*!< SCB CSSELR: InD Position */ +#define SCB_CSSELR_IND_Msk (1UL /*<< SCB_CSSELR_IND_Pos*/) /*!< SCB CSSELR: InD Mask */ + +/* SCB Software Triggered Interrupt Register Definitions */ +#define SCB_STIR_INTID_Pos 0U /*!< SCB STIR: INTID Position */ +#define SCB_STIR_INTID_Msk (0x1FFUL /*<< SCB_STIR_INTID_Pos*/) /*!< SCB STIR: INTID Mask */ + +/* SCB D-Cache Invalidate by Set-way Register Definitions */ +#define SCB_DCISW_WAY_Pos 30U /*!< SCB DCISW: Way Position */ +#define SCB_DCISW_WAY_Msk (3UL << SCB_DCISW_WAY_Pos) /*!< SCB DCISW: Way Mask */ + +#define SCB_DCISW_SET_Pos 5U /*!< SCB DCISW: Set Position */ +#define SCB_DCISW_SET_Msk (0x1FFUL << SCB_DCISW_SET_Pos) /*!< SCB DCISW: Set Mask */ + +/* SCB D-Cache Clean by Set-way Register Definitions */ +#define SCB_DCCSW_WAY_Pos 30U /*!< SCB DCCSW: Way Position */ +#define SCB_DCCSW_WAY_Msk (3UL << SCB_DCCSW_WAY_Pos) /*!< SCB DCCSW: Way Mask */ + +#define SCB_DCCSW_SET_Pos 5U /*!< SCB DCCSW: Set Position */ +#define SCB_DCCSW_SET_Msk (0x1FFUL << SCB_DCCSW_SET_Pos) /*!< SCB DCCSW: Set Mask */ + +/* SCB D-Cache Clean and Invalidate by Set-way Register Definitions */ +#define SCB_DCCISW_WAY_Pos 30U /*!< SCB DCCISW: Way Position */ +#define SCB_DCCISW_WAY_Msk (3UL << SCB_DCCISW_WAY_Pos) /*!< SCB DCCISW: Way Mask */ + +#define SCB_DCCISW_SET_Pos 5U /*!< SCB DCCISW: Set Position */ +#define SCB_DCCISW_SET_Msk (0x1FFUL << SCB_DCCISW_SET_Pos) /*!< SCB DCCISW: Set Mask */ + +/* Instruction Tightly-Coupled Memory Control Register Definitions */ +#define SCB_ITCMCR_SZ_Pos 3U /*!< SCB ITCMCR: SZ Position */ +#define SCB_ITCMCR_SZ_Msk (0xFUL << SCB_ITCMCR_SZ_Pos) /*!< SCB ITCMCR: SZ Mask */ + +#define SCB_ITCMCR_RETEN_Pos 2U /*!< SCB ITCMCR: RETEN Position */ +#define SCB_ITCMCR_RETEN_Msk (1UL << SCB_ITCMCR_RETEN_Pos) /*!< SCB ITCMCR: RETEN Mask */ + +#define SCB_ITCMCR_RMW_Pos 1U /*!< SCB ITCMCR: RMW Position */ +#define SCB_ITCMCR_RMW_Msk (1UL << SCB_ITCMCR_RMW_Pos) /*!< SCB ITCMCR: RMW Mask */ + +#define SCB_ITCMCR_EN_Pos 0U /*!< SCB ITCMCR: EN Position */ +#define SCB_ITCMCR_EN_Msk (1UL /*<< SCB_ITCMCR_EN_Pos*/) /*!< SCB ITCMCR: EN Mask */ + +/* Data Tightly-Coupled Memory Control Register Definitions */ +#define SCB_DTCMCR_SZ_Pos 3U /*!< SCB DTCMCR: SZ Position */ +#define SCB_DTCMCR_SZ_Msk (0xFUL << SCB_DTCMCR_SZ_Pos) /*!< SCB DTCMCR: SZ Mask */ + +#define SCB_DTCMCR_RETEN_Pos 2U /*!< SCB DTCMCR: RETEN Position */ +#define SCB_DTCMCR_RETEN_Msk (1UL << SCB_DTCMCR_RETEN_Pos) /*!< SCB DTCMCR: RETEN Mask */ + +#define SCB_DTCMCR_RMW_Pos 1U /*!< SCB DTCMCR: RMW Position */ +#define SCB_DTCMCR_RMW_Msk (1UL << SCB_DTCMCR_RMW_Pos) /*!< SCB DTCMCR: RMW Mask */ + +#define SCB_DTCMCR_EN_Pos 0U /*!< SCB DTCMCR: EN Position */ +#define SCB_DTCMCR_EN_Msk (1UL /*<< SCB_DTCMCR_EN_Pos*/) /*!< SCB DTCMCR: EN Mask */ + +/* AHBP Control Register Definitions */ +#define SCB_AHBPCR_SZ_Pos 1U /*!< SCB AHBPCR: SZ Position */ +#define SCB_AHBPCR_SZ_Msk (7UL << SCB_AHBPCR_SZ_Pos) /*!< SCB AHBPCR: SZ Mask */ + +#define SCB_AHBPCR_EN_Pos 0U /*!< SCB AHBPCR: EN Position */ +#define SCB_AHBPCR_EN_Msk (1UL /*<< SCB_AHBPCR_EN_Pos*/) /*!< SCB AHBPCR: EN Mask */ + +/* L1 Cache Control Register Definitions */ +#define SCB_CACR_FORCEWT_Pos 2U /*!< SCB CACR: FORCEWT Position */ +#define SCB_CACR_FORCEWT_Msk (1UL << SCB_CACR_FORCEWT_Pos) /*!< SCB CACR: FORCEWT Mask */ + +#define SCB_CACR_ECCEN_Pos 1U /*!< SCB CACR: ECCEN Position */ +#define SCB_CACR_ECCEN_Msk (1UL << SCB_CACR_ECCEN_Pos) /*!< SCB CACR: ECCEN Mask */ + +#define SCB_CACR_SIWT_Pos 0U /*!< SCB CACR: SIWT Position */ +#define SCB_CACR_SIWT_Msk (1UL /*<< SCB_CACR_SIWT_Pos*/) /*!< SCB CACR: SIWT Mask */ + +/* AHBS Control Register Definitions */ +#define SCB_AHBSCR_INITCOUNT_Pos 11U /*!< SCB AHBSCR: INITCOUNT Position */ +#define SCB_AHBSCR_INITCOUNT_Msk (0x1FUL << SCB_AHBPCR_INITCOUNT_Pos) /*!< SCB AHBSCR: INITCOUNT Mask */ + +#define SCB_AHBSCR_TPRI_Pos 2U /*!< SCB AHBSCR: TPRI Position */ +#define SCB_AHBSCR_TPRI_Msk (0x1FFUL << SCB_AHBPCR_TPRI_Pos) /*!< SCB AHBSCR: TPRI Mask */ + +#define SCB_AHBSCR_CTL_Pos 0U /*!< SCB AHBSCR: CTL Position*/ +#define SCB_AHBSCR_CTL_Msk (3UL /*<< SCB_AHBPCR_CTL_Pos*/) /*!< SCB AHBSCR: CTL Mask */ + +/* Auxiliary Bus Fault Status Register Definitions */ +#define SCB_ABFSR_AXIMTYPE_Pos 8U /*!< SCB ABFSR: AXIMTYPE Position*/ +#define SCB_ABFSR_AXIMTYPE_Msk (3UL << SCB_ABFSR_AXIMTYPE_Pos) /*!< SCB ABFSR: AXIMTYPE Mask */ + +#define SCB_ABFSR_EPPB_Pos 4U /*!< SCB ABFSR: EPPB Position*/ +#define SCB_ABFSR_EPPB_Msk (1UL << SCB_ABFSR_EPPB_Pos) /*!< SCB ABFSR: EPPB Mask */ + +#define SCB_ABFSR_AXIM_Pos 3U /*!< SCB ABFSR: AXIM Position*/ +#define SCB_ABFSR_AXIM_Msk (1UL << SCB_ABFSR_AXIM_Pos) /*!< SCB ABFSR: AXIM Mask */ + +#define SCB_ABFSR_AHBP_Pos 2U /*!< SCB ABFSR: AHBP Position*/ +#define SCB_ABFSR_AHBP_Msk (1UL << SCB_ABFSR_AHBP_Pos) /*!< SCB ABFSR: AHBP Mask */ + +#define SCB_ABFSR_DTCM_Pos 1U /*!< SCB ABFSR: DTCM Position*/ +#define SCB_ABFSR_DTCM_Msk (1UL << SCB_ABFSR_DTCM_Pos) /*!< SCB ABFSR: DTCM Mask */ + +#define SCB_ABFSR_ITCM_Pos 0U /*!< SCB ABFSR: ITCM Position*/ +#define SCB_ABFSR_ITCM_Msk (1UL /*<< SCB_ABFSR_ITCM_Pos*/) /*!< SCB ABFSR: ITCM Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) + \brief Type definitions for the System Control and ID Register not in the SCB + @{ + */ + +/** + \brief Structure type to access the System Control and ID Register not in the SCB. + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IM uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ + __IOM uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ +} SCnSCB_Type; + +/* Interrupt Controller Type Register Definitions */ +#define SCnSCB_ICTR_INTLINESNUM_Pos 0U /*!< ICTR: INTLINESNUM Position */ +#define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL /*<< SCnSCB_ICTR_INTLINESNUM_Pos*/) /*!< ICTR: INTLINESNUM Mask */ + +/* Auxiliary Control Register Definitions */ +#define SCnSCB_ACTLR_DISITMATBFLUSH_Pos 12U /*!< ACTLR: DISITMATBFLUSH Position */ +#define SCnSCB_ACTLR_DISITMATBFLUSH_Msk (1UL << SCnSCB_ACTLR_DISITMATBFLUSH_Pos) /*!< ACTLR: DISITMATBFLUSH Mask */ + +#define SCnSCB_ACTLR_DISRAMODE_Pos 11U /*!< ACTLR: DISRAMODE Position */ +#define SCnSCB_ACTLR_DISRAMODE_Msk (1UL << SCnSCB_ACTLR_DISRAMODE_Pos) /*!< ACTLR: DISRAMODE Mask */ + +#define SCnSCB_ACTLR_FPEXCODIS_Pos 10U /*!< ACTLR: FPEXCODIS Position */ +#define SCnSCB_ACTLR_FPEXCODIS_Msk (1UL << SCnSCB_ACTLR_FPEXCODIS_Pos) /*!< ACTLR: FPEXCODIS Mask */ + +#define SCnSCB_ACTLR_DISFOLD_Pos 2U /*!< ACTLR: DISFOLD Position */ +#define SCnSCB_ACTLR_DISFOLD_Msk (1UL << SCnSCB_ACTLR_DISFOLD_Pos) /*!< ACTLR: DISFOLD Mask */ + +#define SCnSCB_ACTLR_DISMCYCINT_Pos 0U /*!< ACTLR: DISMCYCINT Position */ +#define SCnSCB_ACTLR_DISMCYCINT_Msk (1UL /*<< SCnSCB_ACTLR_DISMCYCINT_Pos*/) /*!< ACTLR: DISMCYCINT Mask */ + +/*@} end of group CMSIS_SCnotSCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_ITM Instrumentation Trace Macrocell (ITM) + \brief Type definitions for the Instrumentation Trace Macrocell (ITM) + @{ + */ + +/** + \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM). + */ +typedef struct +{ + __OM union + { + __OM uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ + __OM uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ + __OM uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ + } PORT [32U]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ + uint32_t RESERVED0[864U]; + __IOM uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ + uint32_t RESERVED1[15U]; + __IOM uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ + uint32_t RESERVED2[15U]; + __IOM uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ + uint32_t RESERVED3[29U]; + __OM uint32_t IWR; /*!< Offset: 0xEF8 ( /W) ITM Integration Write Register */ + __IM uint32_t IRR; /*!< Offset: 0xEFC (R/ ) ITM Integration Read Register */ + __IOM uint32_t IMCR; /*!< Offset: 0xF00 (R/W) ITM Integration Mode Control Register */ + uint32_t RESERVED4[43U]; + __OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */ + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */ + uint32_t RESERVED5[6U]; + __IM uint32_t PID4; /*!< Offset: 0xFD0 (R/ ) ITM Peripheral Identification Register #4 */ + __IM uint32_t PID5; /*!< Offset: 0xFD4 (R/ ) ITM Peripheral Identification Register #5 */ + __IM uint32_t PID6; /*!< Offset: 0xFD8 (R/ ) ITM Peripheral Identification Register #6 */ + __IM uint32_t PID7; /*!< Offset: 0xFDC (R/ ) ITM Peripheral Identification Register #7 */ + __IM uint32_t PID0; /*!< Offset: 0xFE0 (R/ ) ITM Peripheral Identification Register #0 */ + __IM uint32_t PID1; /*!< Offset: 0xFE4 (R/ ) ITM Peripheral Identification Register #1 */ + __IM uint32_t PID2; /*!< Offset: 0xFE8 (R/ ) ITM Peripheral Identification Register #2 */ + __IM uint32_t PID3; /*!< Offset: 0xFEC (R/ ) ITM Peripheral Identification Register #3 */ + __IM uint32_t CID0; /*!< Offset: 0xFF0 (R/ ) ITM Component Identification Register #0 */ + __IM uint32_t CID1; /*!< Offset: 0xFF4 (R/ ) ITM Component Identification Register #1 */ + __IM uint32_t CID2; /*!< Offset: 0xFF8 (R/ ) ITM Component Identification Register #2 */ + __IM uint32_t CID3; /*!< Offset: 0xFFC (R/ ) ITM Component Identification Register #3 */ +} ITM_Type; + +/* ITM Trace Privilege Register Definitions */ +#define ITM_TPR_PRIVMASK_Pos 0U /*!< ITM TPR: PRIVMASK Position */ +#define ITM_TPR_PRIVMASK_Msk (0xFFFFFFFFUL /*<< ITM_TPR_PRIVMASK_Pos*/) /*!< ITM TPR: PRIVMASK Mask */ + +/* ITM Trace Control Register Definitions */ +#define ITM_TCR_BUSY_Pos 23U /*!< ITM TCR: BUSY Position */ +#define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */ + +#define ITM_TCR_TraceBusID_Pos 16U /*!< ITM TCR: ATBID Position */ +#define ITM_TCR_TraceBusID_Msk (0x7FUL << ITM_TCR_TraceBusID_Pos) /*!< ITM TCR: ATBID Mask */ + +#define ITM_TCR_GTSFREQ_Pos 10U /*!< ITM TCR: Global timestamp frequency Position */ +#define ITM_TCR_GTSFREQ_Msk (3UL << ITM_TCR_GTSFREQ_Pos) /*!< ITM TCR: Global timestamp frequency Mask */ + +#define ITM_TCR_TSPrescale_Pos 8U /*!< ITM TCR: TSPrescale Position */ +#define ITM_TCR_TSPrescale_Msk (3UL << ITM_TCR_TSPrescale_Pos) /*!< ITM TCR: TSPrescale Mask */ + +#define ITM_TCR_SWOENA_Pos 4U /*!< ITM TCR: SWOENA Position */ +#define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */ + +#define ITM_TCR_DWTENA_Pos 3U /*!< ITM TCR: DWTENA Position */ +#define ITM_TCR_DWTENA_Msk (1UL << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */ + +#define ITM_TCR_SYNCENA_Pos 2U /*!< ITM TCR: SYNCENA Position */ +#define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */ + +#define ITM_TCR_TSENA_Pos 1U /*!< ITM TCR: TSENA Position */ +#define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */ + +#define ITM_TCR_ITMENA_Pos 0U /*!< ITM TCR: ITM Enable bit Position */ +#define ITM_TCR_ITMENA_Msk (1UL /*<< ITM_TCR_ITMENA_Pos*/) /*!< ITM TCR: ITM Enable bit Mask */ + +/* ITM Integration Write Register Definitions */ +#define ITM_IWR_ATVALIDM_Pos 0U /*!< ITM IWR: ATVALIDM Position */ +#define ITM_IWR_ATVALIDM_Msk (1UL /*<< ITM_IWR_ATVALIDM_Pos*/) /*!< ITM IWR: ATVALIDM Mask */ + +/* ITM Integration Read Register Definitions */ +#define ITM_IRR_ATREADYM_Pos 0U /*!< ITM IRR: ATREADYM Position */ +#define ITM_IRR_ATREADYM_Msk (1UL /*<< ITM_IRR_ATREADYM_Pos*/) /*!< ITM IRR: ATREADYM Mask */ + +/* ITM Integration Mode Control Register Definitions */ +#define ITM_IMCR_INTEGRATION_Pos 0U /*!< ITM IMCR: INTEGRATION Position */ +#define ITM_IMCR_INTEGRATION_Msk (1UL /*<< ITM_IMCR_INTEGRATION_Pos*/) /*!< ITM IMCR: INTEGRATION Mask */ + +/* ITM Lock Status Register Definitions */ +#define ITM_LSR_ByteAcc_Pos 2U /*!< ITM LSR: ByteAcc Position */ +#define ITM_LSR_ByteAcc_Msk (1UL << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */ + +#define ITM_LSR_Access_Pos 1U /*!< ITM LSR: Access Position */ +#define ITM_LSR_Access_Msk (1UL << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */ + +#define ITM_LSR_Present_Pos 0U /*!< ITM LSR: Present Position */ +#define ITM_LSR_Present_Msk (1UL /*<< ITM_LSR_Present_Pos*/) /*!< ITM LSR: Present Mask */ + +/*@}*/ /* end of group CMSIS_ITM */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) + \brief Type definitions for the Data Watchpoint and Trace (DWT) + @{ + */ + +/** + \brief Structure type to access the Data Watchpoint and Trace Register (DWT). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ + __IOM uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */ + __IOM uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */ + __IOM uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */ + __IOM uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */ + __IOM uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */ + __IOM uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */ + __IM uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ + __IOM uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ + __IOM uint32_t MASK0; /*!< Offset: 0x024 (R/W) Mask Register 0 */ + __IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ + uint32_t RESERVED0[1U]; + __IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ + __IOM uint32_t MASK1; /*!< Offset: 0x034 (R/W) Mask Register 1 */ + __IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ + uint32_t RESERVED1[1U]; + __IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ + __IOM uint32_t MASK2; /*!< Offset: 0x044 (R/W) Mask Register 2 */ + __IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ + uint32_t RESERVED2[1U]; + __IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ + __IOM uint32_t MASK3; /*!< Offset: 0x054 (R/W) Mask Register 3 */ + __IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ + uint32_t RESERVED3[981U]; + __OM uint32_t LAR; /*!< Offset: 0xFB0 ( W) Lock Access Register */ + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R ) Lock Status Register */ +} DWT_Type; + +/* DWT Control Register Definitions */ +#define DWT_CTRL_NUMCOMP_Pos 28U /*!< DWT CTRL: NUMCOMP Position */ +#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ + +#define DWT_CTRL_NOTRCPKT_Pos 27U /*!< DWT CTRL: NOTRCPKT Position */ +#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ + +#define DWT_CTRL_NOEXTTRIG_Pos 26U /*!< DWT CTRL: NOEXTTRIG Position */ +#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ + +#define DWT_CTRL_NOCYCCNT_Pos 25U /*!< DWT CTRL: NOCYCCNT Position */ +#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ + +#define DWT_CTRL_NOPRFCNT_Pos 24U /*!< DWT CTRL: NOPRFCNT Position */ +#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ + +#define DWT_CTRL_CYCEVTENA_Pos 22U /*!< DWT CTRL: CYCEVTENA Position */ +#define DWT_CTRL_CYCEVTENA_Msk (0x1UL << DWT_CTRL_CYCEVTENA_Pos) /*!< DWT CTRL: CYCEVTENA Mask */ + +#define DWT_CTRL_FOLDEVTENA_Pos 21U /*!< DWT CTRL: FOLDEVTENA Position */ +#define DWT_CTRL_FOLDEVTENA_Msk (0x1UL << DWT_CTRL_FOLDEVTENA_Pos) /*!< DWT CTRL: FOLDEVTENA Mask */ + +#define DWT_CTRL_LSUEVTENA_Pos 20U /*!< DWT CTRL: LSUEVTENA Position */ +#define DWT_CTRL_LSUEVTENA_Msk (0x1UL << DWT_CTRL_LSUEVTENA_Pos) /*!< DWT CTRL: LSUEVTENA Mask */ + +#define DWT_CTRL_SLEEPEVTENA_Pos 19U /*!< DWT CTRL: SLEEPEVTENA Position */ +#define DWT_CTRL_SLEEPEVTENA_Msk (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos) /*!< DWT CTRL: SLEEPEVTENA Mask */ + +#define DWT_CTRL_EXCEVTENA_Pos 18U /*!< DWT CTRL: EXCEVTENA Position */ +#define DWT_CTRL_EXCEVTENA_Msk (0x1UL << DWT_CTRL_EXCEVTENA_Pos) /*!< DWT CTRL: EXCEVTENA Mask */ + +#define DWT_CTRL_CPIEVTENA_Pos 17U /*!< DWT CTRL: CPIEVTENA Position */ +#define DWT_CTRL_CPIEVTENA_Msk (0x1UL << DWT_CTRL_CPIEVTENA_Pos) /*!< DWT CTRL: CPIEVTENA Mask */ + +#define DWT_CTRL_EXCTRCENA_Pos 16U /*!< DWT CTRL: EXCTRCENA Position */ +#define DWT_CTRL_EXCTRCENA_Msk (0x1UL << DWT_CTRL_EXCTRCENA_Pos) /*!< DWT CTRL: EXCTRCENA Mask */ + +#define DWT_CTRL_PCSAMPLENA_Pos 12U /*!< DWT CTRL: PCSAMPLENA Position */ +#define DWT_CTRL_PCSAMPLENA_Msk (0x1UL << DWT_CTRL_PCSAMPLENA_Pos) /*!< DWT CTRL: PCSAMPLENA Mask */ + +#define DWT_CTRL_SYNCTAP_Pos 10U /*!< DWT CTRL: SYNCTAP Position */ +#define DWT_CTRL_SYNCTAP_Msk (0x3UL << DWT_CTRL_SYNCTAP_Pos) /*!< DWT CTRL: SYNCTAP Mask */ + +#define DWT_CTRL_CYCTAP_Pos 9U /*!< DWT CTRL: CYCTAP Position */ +#define DWT_CTRL_CYCTAP_Msk (0x1UL << DWT_CTRL_CYCTAP_Pos) /*!< DWT CTRL: CYCTAP Mask */ + +#define DWT_CTRL_POSTINIT_Pos 5U /*!< DWT CTRL: POSTINIT Position */ +#define DWT_CTRL_POSTINIT_Msk (0xFUL << DWT_CTRL_POSTINIT_Pos) /*!< DWT CTRL: POSTINIT Mask */ + +#define DWT_CTRL_POSTPRESET_Pos 1U /*!< DWT CTRL: POSTPRESET Position */ +#define DWT_CTRL_POSTPRESET_Msk (0xFUL << DWT_CTRL_POSTPRESET_Pos) /*!< DWT CTRL: POSTPRESET Mask */ + +#define DWT_CTRL_CYCCNTENA_Pos 0U /*!< DWT CTRL: CYCCNTENA Position */ +#define DWT_CTRL_CYCCNTENA_Msk (0x1UL /*<< DWT_CTRL_CYCCNTENA_Pos*/) /*!< DWT CTRL: CYCCNTENA Mask */ + +/* DWT CPI Count Register Definitions */ +#define DWT_CPICNT_CPICNT_Pos 0U /*!< DWT CPICNT: CPICNT Position */ +#define DWT_CPICNT_CPICNT_Msk (0xFFUL /*<< DWT_CPICNT_CPICNT_Pos*/) /*!< DWT CPICNT: CPICNT Mask */ + +/* DWT Exception Overhead Count Register Definitions */ +#define DWT_EXCCNT_EXCCNT_Pos 0U /*!< DWT EXCCNT: EXCCNT Position */ +#define DWT_EXCCNT_EXCCNT_Msk (0xFFUL /*<< DWT_EXCCNT_EXCCNT_Pos*/) /*!< DWT EXCCNT: EXCCNT Mask */ + +/* DWT Sleep Count Register Definitions */ +#define DWT_SLEEPCNT_SLEEPCNT_Pos 0U /*!< DWT SLEEPCNT: SLEEPCNT Position */ +#define DWT_SLEEPCNT_SLEEPCNT_Msk (0xFFUL /*<< DWT_SLEEPCNT_SLEEPCNT_Pos*/) /*!< DWT SLEEPCNT: SLEEPCNT Mask */ + +/* DWT LSU Count Register Definitions */ +#define DWT_LSUCNT_LSUCNT_Pos 0U /*!< DWT LSUCNT: LSUCNT Position */ +#define DWT_LSUCNT_LSUCNT_Msk (0xFFUL /*<< DWT_LSUCNT_LSUCNT_Pos*/) /*!< DWT LSUCNT: LSUCNT Mask */ + +/* DWT Folded-instruction Count Register Definitions */ +#define DWT_FOLDCNT_FOLDCNT_Pos 0U /*!< DWT FOLDCNT: FOLDCNT Position */ +#define DWT_FOLDCNT_FOLDCNT_Msk (0xFFUL /*<< DWT_FOLDCNT_FOLDCNT_Pos*/) /*!< DWT FOLDCNT: FOLDCNT Mask */ + +/* DWT Comparator Mask Register Definitions */ +#define DWT_MASK_MASK_Pos 0U /*!< DWT MASK: MASK Position */ +#define DWT_MASK_MASK_Msk (0x1FUL /*<< DWT_MASK_MASK_Pos*/) /*!< DWT MASK: MASK Mask */ + +/* DWT Comparator Function Register Definitions */ +#define DWT_FUNCTION_MATCHED_Pos 24U /*!< DWT FUNCTION: MATCHED Position */ +#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ + +#define DWT_FUNCTION_DATAVADDR1_Pos 16U /*!< DWT FUNCTION: DATAVADDR1 Position */ +#define DWT_FUNCTION_DATAVADDR1_Msk (0xFUL << DWT_FUNCTION_DATAVADDR1_Pos) /*!< DWT FUNCTION: DATAVADDR1 Mask */ + +#define DWT_FUNCTION_DATAVADDR0_Pos 12U /*!< DWT FUNCTION: DATAVADDR0 Position */ +#define DWT_FUNCTION_DATAVADDR0_Msk (0xFUL << DWT_FUNCTION_DATAVADDR0_Pos) /*!< DWT FUNCTION: DATAVADDR0 Mask */ + +#define DWT_FUNCTION_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */ +#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ + +#define DWT_FUNCTION_LNK1ENA_Pos 9U /*!< DWT FUNCTION: LNK1ENA Position */ +#define DWT_FUNCTION_LNK1ENA_Msk (0x1UL << DWT_FUNCTION_LNK1ENA_Pos) /*!< DWT FUNCTION: LNK1ENA Mask */ + +#define DWT_FUNCTION_DATAVMATCH_Pos 8U /*!< DWT FUNCTION: DATAVMATCH Position */ +#define DWT_FUNCTION_DATAVMATCH_Msk (0x1UL << DWT_FUNCTION_DATAVMATCH_Pos) /*!< DWT FUNCTION: DATAVMATCH Mask */ + +#define DWT_FUNCTION_CYCMATCH_Pos 7U /*!< DWT FUNCTION: CYCMATCH Position */ +#define DWT_FUNCTION_CYCMATCH_Msk (0x1UL << DWT_FUNCTION_CYCMATCH_Pos) /*!< DWT FUNCTION: CYCMATCH Mask */ + +#define DWT_FUNCTION_EMITRANGE_Pos 5U /*!< DWT FUNCTION: EMITRANGE Position */ +#define DWT_FUNCTION_EMITRANGE_Msk (0x1UL << DWT_FUNCTION_EMITRANGE_Pos) /*!< DWT FUNCTION: EMITRANGE Mask */ + +#define DWT_FUNCTION_FUNCTION_Pos 0U /*!< DWT FUNCTION: FUNCTION Position */ +#define DWT_FUNCTION_FUNCTION_Msk (0xFUL /*<< DWT_FUNCTION_FUNCTION_Pos*/) /*!< DWT FUNCTION: FUNCTION Mask */ + +/*@}*/ /* end of group CMSIS_DWT */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_TPI Trace Port Interface (TPI) + \brief Type definitions for the Trace Port Interface (TPI) + @{ + */ + +/** + \brief Structure type to access the Trace Port Interface Register (TPI). + */ +typedef struct +{ + __IM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ + __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ + uint32_t RESERVED0[2U]; + __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ + uint32_t RESERVED1[55U]; + __IOM uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ + uint32_t RESERVED2[131U]; + __IM uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ + __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ + __IM uint32_t FSCR; /*!< Offset: 0x308 (R/ ) Formatter Synchronization Counter Register */ + uint32_t RESERVED3[759U]; + __IM uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER Register */ + __IM uint32_t FIFO0; /*!< Offset: 0xEEC (R/ ) Integration ETM Data */ + __IM uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/ ) ITATBCTR2 */ + uint32_t RESERVED4[1U]; + __IM uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) ITATBCTR0 */ + __IM uint32_t FIFO1; /*!< Offset: 0xEFC (R/ ) Integration ITM Data */ + __IOM uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */ + uint32_t RESERVED5[39U]; + __IOM uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */ + __IOM uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */ + uint32_t RESERVED7[8U]; + __IM uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) TPIU_DEVID */ + __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) TPIU_DEVTYPE */ +} TPI_Type; + +/* TPI Asynchronous Clock Prescaler Register Definitions */ +#define TPI_ACPR_PRESCALER_Pos 0U /*!< TPI ACPR: PRESCALER Position */ +#define TPI_ACPR_PRESCALER_Msk (0x1FFFUL /*<< TPI_ACPR_PRESCALER_Pos*/) /*!< TPI ACPR: PRESCALER Mask */ + +/* TPI Selected Pin Protocol Register Definitions */ +#define TPI_SPPR_TXMODE_Pos 0U /*!< TPI SPPR: TXMODE Position */ +#define TPI_SPPR_TXMODE_Msk (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/) /*!< TPI SPPR: TXMODE Mask */ + +/* TPI Formatter and Flush Status Register Definitions */ +#define TPI_FFSR_FtNonStop_Pos 3U /*!< TPI FFSR: FtNonStop Position */ +#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ + +#define TPI_FFSR_TCPresent_Pos 2U /*!< TPI FFSR: TCPresent Position */ +#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ + +#define TPI_FFSR_FtStopped_Pos 1U /*!< TPI FFSR: FtStopped Position */ +#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ + +#define TPI_FFSR_FlInProg_Pos 0U /*!< TPI FFSR: FlInProg Position */ +#define TPI_FFSR_FlInProg_Msk (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/) /*!< TPI FFSR: FlInProg Mask */ + +/* TPI Formatter and Flush Control Register Definitions */ +#define TPI_FFCR_TrigIn_Pos 8U /*!< TPI FFCR: TrigIn Position */ +#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ + +#define TPI_FFCR_EnFCont_Pos 1U /*!< TPI FFCR: EnFCont Position */ +#define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ + +/* TPI TRIGGER Register Definitions */ +#define TPI_TRIGGER_TRIGGER_Pos 0U /*!< TPI TRIGGER: TRIGGER Position */ +#define TPI_TRIGGER_TRIGGER_Msk (0x1UL /*<< TPI_TRIGGER_TRIGGER_Pos*/) /*!< TPI TRIGGER: TRIGGER Mask */ + +/* TPI Integration ETM Data Register Definitions (FIFO0) */ +#define TPI_FIFO0_ITM_ATVALID_Pos 29U /*!< TPI FIFO0: ITM_ATVALID Position */ +#define TPI_FIFO0_ITM_ATVALID_Msk (0x3UL << TPI_FIFO0_ITM_ATVALID_Pos) /*!< TPI FIFO0: ITM_ATVALID Mask */ + +#define TPI_FIFO0_ITM_bytecount_Pos 27U /*!< TPI FIFO0: ITM_bytecount Position */ +#define TPI_FIFO0_ITM_bytecount_Msk (0x3UL << TPI_FIFO0_ITM_bytecount_Pos) /*!< TPI FIFO0: ITM_bytecount Mask */ + +#define TPI_FIFO0_ETM_ATVALID_Pos 26U /*!< TPI FIFO0: ETM_ATVALID Position */ +#define TPI_FIFO0_ETM_ATVALID_Msk (0x3UL << TPI_FIFO0_ETM_ATVALID_Pos) /*!< TPI FIFO0: ETM_ATVALID Mask */ + +#define TPI_FIFO0_ETM_bytecount_Pos 24U /*!< TPI FIFO0: ETM_bytecount Position */ +#define TPI_FIFO0_ETM_bytecount_Msk (0x3UL << TPI_FIFO0_ETM_bytecount_Pos) /*!< TPI FIFO0: ETM_bytecount Mask */ + +#define TPI_FIFO0_ETM2_Pos 16U /*!< TPI FIFO0: ETM2 Position */ +#define TPI_FIFO0_ETM2_Msk (0xFFUL << TPI_FIFO0_ETM2_Pos) /*!< TPI FIFO0: ETM2 Mask */ + +#define TPI_FIFO0_ETM1_Pos 8U /*!< TPI FIFO0: ETM1 Position */ +#define TPI_FIFO0_ETM1_Msk (0xFFUL << TPI_FIFO0_ETM1_Pos) /*!< TPI FIFO0: ETM1 Mask */ + +#define TPI_FIFO0_ETM0_Pos 0U /*!< TPI FIFO0: ETM0 Position */ +#define TPI_FIFO0_ETM0_Msk (0xFFUL /*<< TPI_FIFO0_ETM0_Pos*/) /*!< TPI FIFO0: ETM0 Mask */ + +/* TPI ITATBCTR2 Register Definitions */ +#define TPI_ITATBCTR2_ATREADY2_Pos 0U /*!< TPI ITATBCTR2: ATREADY2 Position */ +#define TPI_ITATBCTR2_ATREADY2_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY2_Pos*/) /*!< TPI ITATBCTR2: ATREADY2 Mask */ + +#define TPI_ITATBCTR2_ATREADY1_Pos 0U /*!< TPI ITATBCTR2: ATREADY1 Position */ +#define TPI_ITATBCTR2_ATREADY1_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY1_Pos*/) /*!< TPI ITATBCTR2: ATREADY1 Mask */ + +/* TPI Integration ITM Data Register Definitions (FIFO1) */ +#define TPI_FIFO1_ITM_ATVALID_Pos 29U /*!< TPI FIFO1: ITM_ATVALID Position */ +#define TPI_FIFO1_ITM_ATVALID_Msk (0x3UL << TPI_FIFO1_ITM_ATVALID_Pos) /*!< TPI FIFO1: ITM_ATVALID Mask */ + +#define TPI_FIFO1_ITM_bytecount_Pos 27U /*!< TPI FIFO1: ITM_bytecount Position */ +#define TPI_FIFO1_ITM_bytecount_Msk (0x3UL << TPI_FIFO1_ITM_bytecount_Pos) /*!< TPI FIFO1: ITM_bytecount Mask */ + +#define TPI_FIFO1_ETM_ATVALID_Pos 26U /*!< TPI FIFO1: ETM_ATVALID Position */ +#define TPI_FIFO1_ETM_ATVALID_Msk (0x3UL << TPI_FIFO1_ETM_ATVALID_Pos) /*!< TPI FIFO1: ETM_ATVALID Mask */ + +#define TPI_FIFO1_ETM_bytecount_Pos 24U /*!< TPI FIFO1: ETM_bytecount Position */ +#define TPI_FIFO1_ETM_bytecount_Msk (0x3UL << TPI_FIFO1_ETM_bytecount_Pos) /*!< TPI FIFO1: ETM_bytecount Mask */ + +#define TPI_FIFO1_ITM2_Pos 16U /*!< TPI FIFO1: ITM2 Position */ +#define TPI_FIFO1_ITM2_Msk (0xFFUL << TPI_FIFO1_ITM2_Pos) /*!< TPI FIFO1: ITM2 Mask */ + +#define TPI_FIFO1_ITM1_Pos 8U /*!< TPI FIFO1: ITM1 Position */ +#define TPI_FIFO1_ITM1_Msk (0xFFUL << TPI_FIFO1_ITM1_Pos) /*!< TPI FIFO1: ITM1 Mask */ + +#define TPI_FIFO1_ITM0_Pos 0U /*!< TPI FIFO1: ITM0 Position */ +#define TPI_FIFO1_ITM0_Msk (0xFFUL /*<< TPI_FIFO1_ITM0_Pos*/) /*!< TPI FIFO1: ITM0 Mask */ + +/* TPI ITATBCTR0 Register Definitions */ +#define TPI_ITATBCTR0_ATREADY2_Pos 0U /*!< TPI ITATBCTR0: ATREADY2 Position */ +#define TPI_ITATBCTR0_ATREADY2_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY2_Pos*/) /*!< TPI ITATBCTR0: ATREADY2 Mask */ + +#define TPI_ITATBCTR0_ATREADY1_Pos 0U /*!< TPI ITATBCTR0: ATREADY1 Position */ +#define TPI_ITATBCTR0_ATREADY1_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY1_Pos*/) /*!< TPI ITATBCTR0: ATREADY1 Mask */ + +/* TPI Integration Mode Control Register Definitions */ +#define TPI_ITCTRL_Mode_Pos 0U /*!< TPI ITCTRL: Mode Position */ +#define TPI_ITCTRL_Mode_Msk (0x3UL /*<< TPI_ITCTRL_Mode_Pos*/) /*!< TPI ITCTRL: Mode Mask */ + +/* TPI DEVID Register Definitions */ +#define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */ +#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ + +#define TPI_DEVID_MANCVALID_Pos 10U /*!< TPI DEVID: MANCVALID Position */ +#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ + +#define TPI_DEVID_PTINVALID_Pos 9U /*!< TPI DEVID: PTINVALID Position */ +#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ + +#define TPI_DEVID_MinBufSz_Pos 6U /*!< TPI DEVID: MinBufSz Position */ +#define TPI_DEVID_MinBufSz_Msk (0x7UL << TPI_DEVID_MinBufSz_Pos) /*!< TPI DEVID: MinBufSz Mask */ + +#define TPI_DEVID_AsynClkIn_Pos 5U /*!< TPI DEVID: AsynClkIn Position */ +#define TPI_DEVID_AsynClkIn_Msk (0x1UL << TPI_DEVID_AsynClkIn_Pos) /*!< TPI DEVID: AsynClkIn Mask */ + +#define TPI_DEVID_NrTraceInput_Pos 0U /*!< TPI DEVID: NrTraceInput Position */ +#define TPI_DEVID_NrTraceInput_Msk (0x1FUL /*<< TPI_DEVID_NrTraceInput_Pos*/) /*!< TPI DEVID: NrTraceInput Mask */ + +/* TPI DEVTYPE Register Definitions */ +#define TPI_DEVTYPE_SubType_Pos 4U /*!< TPI DEVTYPE: SubType Position */ +#define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ + +#define TPI_DEVTYPE_MajorType_Pos 0U /*!< TPI DEVTYPE: MajorType Position */ +#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ + +/*@}*/ /* end of group CMSIS_TPI */ + + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** + \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IOM uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */ + __IOM uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Alias 1 Region Base Address Register */ + __IOM uint32_t RASR_A1; /*!< Offset: 0x018 (R/W) MPU Alias 1 Region Attribute and Size Register */ + __IOM uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Alias 2 Region Base Address Register */ + __IOM uint32_t RASR_A2; /*!< Offset: 0x020 (R/W) MPU Alias 2 Region Attribute and Size Register */ + __IOM uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Alias 3 Region Base Address Register */ + __IOM uint32_t RASR_A3; /*!< Offset: 0x028 (R/W) MPU Alias 3 Region Attribute and Size Register */ +} MPU_Type; + +#define MPU_TYPE_RALIASES 4U + +/* MPU Type Register Definitions */ +#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register Definitions */ +#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register Definitions */ +#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register Definitions */ +#define MPU_RBAR_ADDR_Pos 5U /*!< MPU RBAR: ADDR Position */ +#define MPU_RBAR_ADDR_Msk (0x7FFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ + +#define MPU_RBAR_VALID_Pos 4U /*!< MPU RBAR: VALID Position */ +#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */ + +#define MPU_RBAR_REGION_Pos 0U /*!< MPU RBAR: REGION Position */ +#define MPU_RBAR_REGION_Msk (0xFUL /*<< MPU_RBAR_REGION_Pos*/) /*!< MPU RBAR: REGION Mask */ + +/* MPU Region Attribute and Size Register Definitions */ +#define MPU_RASR_ATTRS_Pos 16U /*!< MPU RASR: MPU Region Attribute field Position */ +#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */ + +#define MPU_RASR_XN_Pos 28U /*!< MPU RASR: ATTRS.XN Position */ +#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */ + +#define MPU_RASR_AP_Pos 24U /*!< MPU RASR: ATTRS.AP Position */ +#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */ + +#define MPU_RASR_TEX_Pos 19U /*!< MPU RASR: ATTRS.TEX Position */ +#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */ + +#define MPU_RASR_S_Pos 18U /*!< MPU RASR: ATTRS.S Position */ +#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */ + +#define MPU_RASR_C_Pos 17U /*!< MPU RASR: ATTRS.C Position */ +#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */ + +#define MPU_RASR_B_Pos 16U /*!< MPU RASR: ATTRS.B Position */ +#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */ + +#define MPU_RASR_SRD_Pos 8U /*!< MPU RASR: Sub-Region Disable Position */ +#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */ + +#define MPU_RASR_SIZE_Pos 1U /*!< MPU RASR: Region Size Field Position */ +#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */ + +#define MPU_RASR_ENABLE_Pos 0U /*!< MPU RASR: Region enable bit Position */ +#define MPU_RASR_ENABLE_Msk (1UL /*<< MPU_RASR_ENABLE_Pos*/) /*!< MPU RASR: Region enable bit Disable Mask */ + +/*@} end of group CMSIS_MPU */ +#endif /* defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_FPU Floating Point Unit (FPU) + \brief Type definitions for the Floating Point Unit (FPU) + @{ + */ + +/** + \brief Structure type to access the Floating Point Unit (FPU). + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IOM uint32_t FPCCR; /*!< Offset: 0x004 (R/W) Floating-Point Context Control Register */ + __IOM uint32_t FPCAR; /*!< Offset: 0x008 (R/W) Floating-Point Context Address Register */ + __IOM uint32_t FPDSCR; /*!< Offset: 0x00C (R/W) Floating-Point Default Status Control Register */ + __IM uint32_t MVFR0; /*!< Offset: 0x010 (R/ ) Media and FP Feature Register 0 */ + __IM uint32_t MVFR1; /*!< Offset: 0x014 (R/ ) Media and FP Feature Register 1 */ + __IM uint32_t MVFR2; /*!< Offset: 0x018 (R/ ) Media and FP Feature Register 2 */ +} FPU_Type; + +/* Floating-Point Context Control Register Definitions */ +#define FPU_FPCCR_ASPEN_Pos 31U /*!< FPCCR: ASPEN bit Position */ +#define FPU_FPCCR_ASPEN_Msk (1UL << FPU_FPCCR_ASPEN_Pos) /*!< FPCCR: ASPEN bit Mask */ + +#define FPU_FPCCR_LSPEN_Pos 30U /*!< FPCCR: LSPEN Position */ +#define FPU_FPCCR_LSPEN_Msk (1UL << FPU_FPCCR_LSPEN_Pos) /*!< FPCCR: LSPEN bit Mask */ + +#define FPU_FPCCR_MONRDY_Pos 8U /*!< FPCCR: MONRDY Position */ +#define FPU_FPCCR_MONRDY_Msk (1UL << FPU_FPCCR_MONRDY_Pos) /*!< FPCCR: MONRDY bit Mask */ + +#define FPU_FPCCR_BFRDY_Pos 6U /*!< FPCCR: BFRDY Position */ +#define FPU_FPCCR_BFRDY_Msk (1UL << FPU_FPCCR_BFRDY_Pos) /*!< FPCCR: BFRDY bit Mask */ + +#define FPU_FPCCR_MMRDY_Pos 5U /*!< FPCCR: MMRDY Position */ +#define FPU_FPCCR_MMRDY_Msk (1UL << FPU_FPCCR_MMRDY_Pos) /*!< FPCCR: MMRDY bit Mask */ + +#define FPU_FPCCR_HFRDY_Pos 4U /*!< FPCCR: HFRDY Position */ +#define FPU_FPCCR_HFRDY_Msk (1UL << FPU_FPCCR_HFRDY_Pos) /*!< FPCCR: HFRDY bit Mask */ + +#define FPU_FPCCR_THREAD_Pos 3U /*!< FPCCR: processor mode bit Position */ +#define FPU_FPCCR_THREAD_Msk (1UL << FPU_FPCCR_THREAD_Pos) /*!< FPCCR: processor mode active bit Mask */ + +#define FPU_FPCCR_USER_Pos 1U /*!< FPCCR: privilege level bit Position */ +#define FPU_FPCCR_USER_Msk (1UL << FPU_FPCCR_USER_Pos) /*!< FPCCR: privilege level bit Mask */ + +#define FPU_FPCCR_LSPACT_Pos 0U /*!< FPCCR: Lazy state preservation active bit Position */ +#define FPU_FPCCR_LSPACT_Msk (1UL /*<< FPU_FPCCR_LSPACT_Pos*/) /*!< FPCCR: Lazy state preservation active bit Mask */ + +/* Floating-Point Context Address Register Definitions */ +#define FPU_FPCAR_ADDRESS_Pos 3U /*!< FPCAR: ADDRESS bit Position */ +#define FPU_FPCAR_ADDRESS_Msk (0x1FFFFFFFUL << FPU_FPCAR_ADDRESS_Pos) /*!< FPCAR: ADDRESS bit Mask */ + +/* Floating-Point Default Status Control Register Definitions */ +#define FPU_FPDSCR_AHP_Pos 26U /*!< FPDSCR: AHP bit Position */ +#define FPU_FPDSCR_AHP_Msk (1UL << FPU_FPDSCR_AHP_Pos) /*!< FPDSCR: AHP bit Mask */ + +#define FPU_FPDSCR_DN_Pos 25U /*!< FPDSCR: DN bit Position */ +#define FPU_FPDSCR_DN_Msk (1UL << FPU_FPDSCR_DN_Pos) /*!< FPDSCR: DN bit Mask */ + +#define FPU_FPDSCR_FZ_Pos 24U /*!< FPDSCR: FZ bit Position */ +#define FPU_FPDSCR_FZ_Msk (1UL << FPU_FPDSCR_FZ_Pos) /*!< FPDSCR: FZ bit Mask */ + +#define FPU_FPDSCR_RMode_Pos 22U /*!< FPDSCR: RMode bit Position */ +#define FPU_FPDSCR_RMode_Msk (3UL << FPU_FPDSCR_RMode_Pos) /*!< FPDSCR: RMode bit Mask */ + +/* Media and FP Feature Register 0 Definitions */ +#define FPU_MVFR0_FP_rounding_modes_Pos 28U /*!< MVFR0: FP rounding modes bits Position */ +#define FPU_MVFR0_FP_rounding_modes_Msk (0xFUL << FPU_MVFR0_FP_rounding_modes_Pos) /*!< MVFR0: FP rounding modes bits Mask */ + +#define FPU_MVFR0_Short_vectors_Pos 24U /*!< MVFR0: Short vectors bits Position */ +#define FPU_MVFR0_Short_vectors_Msk (0xFUL << FPU_MVFR0_Short_vectors_Pos) /*!< MVFR0: Short vectors bits Mask */ + +#define FPU_MVFR0_Square_root_Pos 20U /*!< MVFR0: Square root bits Position */ +#define FPU_MVFR0_Square_root_Msk (0xFUL << FPU_MVFR0_Square_root_Pos) /*!< MVFR0: Square root bits Mask */ + +#define FPU_MVFR0_Divide_Pos 16U /*!< MVFR0: Divide bits Position */ +#define FPU_MVFR0_Divide_Msk (0xFUL << FPU_MVFR0_Divide_Pos) /*!< MVFR0: Divide bits Mask */ + +#define FPU_MVFR0_FP_excep_trapping_Pos 12U /*!< MVFR0: FP exception trapping bits Position */ +#define FPU_MVFR0_FP_excep_trapping_Msk (0xFUL << FPU_MVFR0_FP_excep_trapping_Pos) /*!< MVFR0: FP exception trapping bits Mask */ + +#define FPU_MVFR0_Double_precision_Pos 8U /*!< MVFR0: Double-precision bits Position */ +#define FPU_MVFR0_Double_precision_Msk (0xFUL << FPU_MVFR0_Double_precision_Pos) /*!< MVFR0: Double-precision bits Mask */ + +#define FPU_MVFR0_Single_precision_Pos 4U /*!< MVFR0: Single-precision bits Position */ +#define FPU_MVFR0_Single_precision_Msk (0xFUL << FPU_MVFR0_Single_precision_Pos) /*!< MVFR0: Single-precision bits Mask */ + +#define FPU_MVFR0_A_SIMD_registers_Pos 0U /*!< MVFR0: A_SIMD registers bits Position */ +#define FPU_MVFR0_A_SIMD_registers_Msk (0xFUL /*<< FPU_MVFR0_A_SIMD_registers_Pos*/) /*!< MVFR0: A_SIMD registers bits Mask */ + +/* Media and FP Feature Register 1 Definitions */ +#define FPU_MVFR1_FP_fused_MAC_Pos 28U /*!< MVFR1: FP fused MAC bits Position */ +#define FPU_MVFR1_FP_fused_MAC_Msk (0xFUL << FPU_MVFR1_FP_fused_MAC_Pos) /*!< MVFR1: FP fused MAC bits Mask */ + +#define FPU_MVFR1_FP_HPFP_Pos 24U /*!< MVFR1: FP HPFP bits Position */ +#define FPU_MVFR1_FP_HPFP_Msk (0xFUL << FPU_MVFR1_FP_HPFP_Pos) /*!< MVFR1: FP HPFP bits Mask */ + +#define FPU_MVFR1_D_NaN_mode_Pos 4U /*!< MVFR1: D_NaN mode bits Position */ +#define FPU_MVFR1_D_NaN_mode_Msk (0xFUL << FPU_MVFR1_D_NaN_mode_Pos) /*!< MVFR1: D_NaN mode bits Mask */ + +#define FPU_MVFR1_FtZ_mode_Pos 0U /*!< MVFR1: FtZ mode bits Position */ +#define FPU_MVFR1_FtZ_mode_Msk (0xFUL /*<< FPU_MVFR1_FtZ_mode_Pos*/) /*!< MVFR1: FtZ mode bits Mask */ + +/* Media and FP Feature Register 2 Definitions */ + +/*@} end of group CMSIS_FPU */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Type definitions for the Core Debug Registers + @{ + */ + +/** + \brief Structure type to access the Core Debug Register (CoreDebug). + */ +typedef struct +{ + __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ +} CoreDebug_Type; + +/* Debug Halting Control and Status Register Definitions */ +#define CoreDebug_DHCSR_DBGKEY_Pos 16U /*!< CoreDebug DHCSR: DBGKEY Position */ +#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */ + +#define CoreDebug_DHCSR_S_RESET_ST_Pos 25U /*!< CoreDebug DHCSR: S_RESET_ST Position */ +#define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< CoreDebug DHCSR: S_RESET_ST Mask */ + +#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24U /*!< CoreDebug DHCSR: S_RETIRE_ST Position */ +#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */ + +#define CoreDebug_DHCSR_S_LOCKUP_Pos 19U /*!< CoreDebug DHCSR: S_LOCKUP Position */ +#define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< CoreDebug DHCSR: S_LOCKUP Mask */ + +#define CoreDebug_DHCSR_S_SLEEP_Pos 18U /*!< CoreDebug DHCSR: S_SLEEP Position */ +#define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< CoreDebug DHCSR: S_SLEEP Mask */ + +#define CoreDebug_DHCSR_S_HALT_Pos 17U /*!< CoreDebug DHCSR: S_HALT Position */ +#define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< CoreDebug DHCSR: S_HALT Mask */ + +#define CoreDebug_DHCSR_S_REGRDY_Pos 16U /*!< CoreDebug DHCSR: S_REGRDY Position */ +#define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< CoreDebug DHCSR: S_REGRDY Mask */ + +#define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5U /*!< CoreDebug DHCSR: C_SNAPSTALL Position */ +#define CoreDebug_DHCSR_C_SNAPSTALL_Msk (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos) /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */ + +#define CoreDebug_DHCSR_C_MASKINTS_Pos 3U /*!< CoreDebug DHCSR: C_MASKINTS Position */ +#define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< CoreDebug DHCSR: C_MASKINTS Mask */ + +#define CoreDebug_DHCSR_C_STEP_Pos 2U /*!< CoreDebug DHCSR: C_STEP Position */ +#define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< CoreDebug DHCSR: C_STEP Mask */ + +#define CoreDebug_DHCSR_C_HALT_Pos 1U /*!< CoreDebug DHCSR: C_HALT Position */ +#define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< CoreDebug DHCSR: C_HALT Mask */ + +#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0U /*!< CoreDebug DHCSR: C_DEBUGEN Position */ +#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */ + +/* Debug Core Register Selector Register Definitions */ +#define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< CoreDebug DCRSR: REGWnR Position */ +#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ + +#define CoreDebug_DCRSR_REGSEL_Pos 0U /*!< CoreDebug DCRSR: REGSEL Position */ +#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/) /*!< CoreDebug DCRSR: REGSEL Mask */ + +/* Debug Exception and Monitor Control Register Definitions */ +#define CoreDebug_DEMCR_TRCENA_Pos 24U /*!< CoreDebug DEMCR: TRCENA Position */ +#define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< CoreDebug DEMCR: TRCENA Mask */ + +#define CoreDebug_DEMCR_MON_REQ_Pos 19U /*!< CoreDebug DEMCR: MON_REQ Position */ +#define CoreDebug_DEMCR_MON_REQ_Msk (1UL << CoreDebug_DEMCR_MON_REQ_Pos) /*!< CoreDebug DEMCR: MON_REQ Mask */ + +#define CoreDebug_DEMCR_MON_STEP_Pos 18U /*!< CoreDebug DEMCR: MON_STEP Position */ +#define CoreDebug_DEMCR_MON_STEP_Msk (1UL << CoreDebug_DEMCR_MON_STEP_Pos) /*!< CoreDebug DEMCR: MON_STEP Mask */ + +#define CoreDebug_DEMCR_MON_PEND_Pos 17U /*!< CoreDebug DEMCR: MON_PEND Position */ +#define CoreDebug_DEMCR_MON_PEND_Msk (1UL << CoreDebug_DEMCR_MON_PEND_Pos) /*!< CoreDebug DEMCR: MON_PEND Mask */ + +#define CoreDebug_DEMCR_MON_EN_Pos 16U /*!< CoreDebug DEMCR: MON_EN Position */ +#define CoreDebug_DEMCR_MON_EN_Msk (1UL << CoreDebug_DEMCR_MON_EN_Pos) /*!< CoreDebug DEMCR: MON_EN Mask */ + +#define CoreDebug_DEMCR_VC_HARDERR_Pos 10U /*!< CoreDebug DEMCR: VC_HARDERR Position */ +#define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< CoreDebug DEMCR: VC_HARDERR Mask */ + +#define CoreDebug_DEMCR_VC_INTERR_Pos 9U /*!< CoreDebug DEMCR: VC_INTERR Position */ +#define CoreDebug_DEMCR_VC_INTERR_Msk (1UL << CoreDebug_DEMCR_VC_INTERR_Pos) /*!< CoreDebug DEMCR: VC_INTERR Mask */ + +#define CoreDebug_DEMCR_VC_BUSERR_Pos 8U /*!< CoreDebug DEMCR: VC_BUSERR Position */ +#define CoreDebug_DEMCR_VC_BUSERR_Msk (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos) /*!< CoreDebug DEMCR: VC_BUSERR Mask */ + +#define CoreDebug_DEMCR_VC_STATERR_Pos 7U /*!< CoreDebug DEMCR: VC_STATERR Position */ +#define CoreDebug_DEMCR_VC_STATERR_Msk (1UL << CoreDebug_DEMCR_VC_STATERR_Pos) /*!< CoreDebug DEMCR: VC_STATERR Mask */ + +#define CoreDebug_DEMCR_VC_CHKERR_Pos 6U /*!< CoreDebug DEMCR: VC_CHKERR Position */ +#define CoreDebug_DEMCR_VC_CHKERR_Msk (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos) /*!< CoreDebug DEMCR: VC_CHKERR Mask */ + +#define CoreDebug_DEMCR_VC_NOCPERR_Pos 5U /*!< CoreDebug DEMCR: VC_NOCPERR Position */ +#define CoreDebug_DEMCR_VC_NOCPERR_Msk (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos) /*!< CoreDebug DEMCR: VC_NOCPERR Mask */ + +#define CoreDebug_DEMCR_VC_MMERR_Pos 4U /*!< CoreDebug DEMCR: VC_MMERR Position */ +#define CoreDebug_DEMCR_VC_MMERR_Msk (1UL << CoreDebug_DEMCR_VC_MMERR_Pos) /*!< CoreDebug DEMCR: VC_MMERR Mask */ + +#define CoreDebug_DEMCR_VC_CORERESET_Pos 0U /*!< CoreDebug DEMCR: VC_CORERESET Position */ +#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/) /*!< CoreDebug DEMCR: VC_CORERESET Mask */ + +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param[in] field Name of the register bit field. + \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param[in] field Name of the register bit field. + \param[in] value Value of register. This parameter is interpreted as an uint32_t type. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) + +/*@} end of group CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Core Hardware */ +#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ +#define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ +#define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ +#define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ +#define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */ +#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ +#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ +#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + +#define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ +#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ +#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ +#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ +#define ITM ((ITM_Type *) ITM_BASE ) /*!< ITM configuration struct */ +#define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ +#define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ +#define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE) /*!< Core Debug configuration struct */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ +#endif + +#define FPU_BASE (SCS_BASE + 0x0F30UL) /*!< Floating Point Unit */ +#define FPU ((FPU_Type *) FPU_BASE ) /*!< Floating Point Unit */ + +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Debug Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping + #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping + #define NVIC_EnableIRQ __NVIC_EnableIRQ + #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ + #define NVIC_DisableIRQ __NVIC_DisableIRQ + #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ + #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ + #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ + #define NVIC_GetActive __NVIC_GetActive + #define NVIC_SetPriority __NVIC_SetPriority + #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset +#endif /* CMSIS_NVIC_VIRTUAL */ + +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetVector __NVIC_SetVector + #define NVIC_GetVector __NVIC_GetVector +#endif /* (CMSIS_VECTAB_VIRTUAL) */ + +#define NVIC_USER_IRQ_OFFSET 16 + + +/* The following EXC_RETURN values are saved the LR on exception entry */ +#define EXC_RETURN_HANDLER (0xFFFFFFF1UL) /* return to Handler mode, uses MSP after return */ +#define EXC_RETURN_THREAD_MSP (0xFFFFFFF9UL) /* return to Thread mode, uses MSP after return */ +#define EXC_RETURN_THREAD_PSP (0xFFFFFFFDUL) /* return to Thread mode, uses PSP after return */ +#define EXC_RETURN_HANDLER_FPU (0xFFFFFFE1UL) /* return to Handler mode, uses MSP after return, restore floating-point state */ +#define EXC_RETURN_THREAD_MSP_FPU (0xFFFFFFE9UL) /* return to Thread mode, uses MSP after return, restore floating-point state */ +#define EXC_RETURN_THREAD_PSP_FPU (0xFFFFFFEDUL) /* return to Thread mode, uses PSP after return, restore floating-point state */ + + +/** + \brief Set Priority Grouping + \details Sets the priority grouping field using the required unlock sequence. + The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. + Only values from 0..7 are used. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Priority grouping field. + */ +__STATIC_INLINE void __NVIC_SetPriorityGrouping(uint32_t PriorityGroup) +{ + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + + reg_value = SCB->AIRCR; /* read old register configuration */ + reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << SCB_AIRCR_PRIGROUP_Pos) ); /* Insert write key and priority group */ + SCB->AIRCR = reg_value; +} + + +/** + \brief Get Priority Grouping + \details Reads the priority grouping field from the NVIC Interrupt Controller. + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t __NVIC_GetPriorityGrouping(void) +{ + return ((uint32_t)((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); +} + + +/** + \brief Enable Interrupt + \details Enables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Interrupt Enable status + \details Returns a device specific interrupt enable status from the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt + \details Disables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __DSB(); + __ISB(); + } +} + + +/** + \brief Get Pending Interrupt + \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt + \details Reads the active register in the NVIC and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetActive(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Priority + \details Sets the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every processor exception. + */ +__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->IP[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } + else + { + SCB->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return(((uint32_t)NVIC->IP[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return(((uint32_t)SCB->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief Encode Priority + \details Encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + return ( + ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | + ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) + ); +} + + +/** + \brief Decode Priority + \details Decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. + \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); + *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); +} + + +/** + \brief Set Interrupt Vector + \details Sets an interrupt vector in SRAM based interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + VTOR must been relocated to SRAM before. + \param [in] IRQn Interrupt number + \param [in] vector Address of interrupt handler function + */ +__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; +} + + +/** + \brief Get Interrupt Vector + \details Reads an interrupt vector from interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Address of interrupt handler function + */ +__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET]; +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + SCB_AIRCR_SYSRESETREQ_Msk ); /* Keep priority group unchanged */ + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +/*@} end of CMSIS_Core_NVICFunctions */ + +/* ########################## MPU functions #################################### */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + +#include "mpu_armv7.h" + +#endif + +/* ########################## FPU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_FpuFunctions FPU Functions + \brief Function that provides FPU type. + @{ + */ + +/** + \brief get FPU type + \details returns the FPU type + \returns + - \b 0: No FPU + - \b 1: Single precision FPU + - \b 2: Double + Single precision FPU + */ +__STATIC_INLINE uint32_t SCB_GetFPUType(void) +{ + uint32_t mvfr0; + + mvfr0 = SCB->MVFR0; + if ((mvfr0 & (FPU_MVFR0_Single_precision_Msk | FPU_MVFR0_Double_precision_Msk)) == 0x220U) + { + return 2U; /* Double + Single precision FPU */ + } + else if ((mvfr0 & (FPU_MVFR0_Single_precision_Msk | FPU_MVFR0_Double_precision_Msk)) == 0x020U) + { + return 1U; /* Single precision FPU */ + } + else + { + return 0U; /* No FPU */ + } +} + + +/*@} end of CMSIS_Core_FpuFunctions */ + + + +/* ########################## Cache functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_CacheFunctions Cache Functions + \brief Functions that configure Instruction and Data cache. + @{ + */ + +/* Cache Size ID Register Macros */ +#define CCSIDR_WAYS(x) (((x) & SCB_CCSIDR_ASSOCIATIVITY_Msk) >> SCB_CCSIDR_ASSOCIATIVITY_Pos) +#define CCSIDR_SETS(x) (((x) & SCB_CCSIDR_NUMSETS_Msk ) >> SCB_CCSIDR_NUMSETS_Pos ) + + +/** + \brief Enable I-Cache + \details Turns on I-Cache + */ +__STATIC_INLINE void SCB_EnableICache (void) +{ + #if defined (__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U) + __DSB(); + __ISB(); + SCB->ICIALLU = 0UL; /* invalidate I-Cache */ + __DSB(); + __ISB(); + SCB->CCR |= (uint32_t)SCB_CCR_IC_Msk; /* enable I-Cache */ + __DSB(); + __ISB(); + #endif +} + + +/** + \brief Disable I-Cache + \details Turns off I-Cache + */ +__STATIC_INLINE void SCB_DisableICache (void) +{ + #if defined (__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U) + __DSB(); + __ISB(); + SCB->CCR &= ~(uint32_t)SCB_CCR_IC_Msk; /* disable I-Cache */ + SCB->ICIALLU = 0UL; /* invalidate I-Cache */ + __DSB(); + __ISB(); + #endif +} + + +/** + \brief Invalidate I-Cache + \details Invalidates I-Cache + */ +__STATIC_INLINE void SCB_InvalidateICache (void) +{ + #if defined (__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U) + __DSB(); + __ISB(); + SCB->ICIALLU = 0UL; + __DSB(); + __ISB(); + #endif +} + + +/** + \brief Enable D-Cache + \details Turns on D-Cache + */ +__STATIC_INLINE void SCB_EnableDCache (void) +{ + #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + uint32_t ccsidr; + uint32_t sets; + uint32_t ways; + + SCB->CSSELR = 0U; /*(0U << 1U) | 0U;*/ /* Level 1 data cache */ + __DSB(); + + ccsidr = SCB->CCSIDR; + + /* invalidate D-Cache */ + sets = (uint32_t)(CCSIDR_SETS(ccsidr)); + do { + ways = (uint32_t)(CCSIDR_WAYS(ccsidr)); + do { + SCB->DCISW = (((sets << SCB_DCISW_SET_Pos) & SCB_DCISW_SET_Msk) | + ((ways << SCB_DCISW_WAY_Pos) & SCB_DCISW_WAY_Msk) ); + #if defined ( __CC_ARM ) + __schedule_barrier(); + #endif + } while (ways-- != 0U); + } while(sets-- != 0U); + __DSB(); + + SCB->CCR |= (uint32_t)SCB_CCR_DC_Msk; /* enable D-Cache */ + + __DSB(); + __ISB(); + #endif +} + + +/** + \brief Disable D-Cache + \details Turns off D-Cache + */ +__STATIC_INLINE void SCB_DisableDCache (void) +{ + #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + uint32_t ccsidr; + uint32_t sets; + uint32_t ways; + + SCB->CSSELR = 0U; /*(0U << 1U) | 0U;*/ /* Level 1 data cache */ + __DSB(); + + SCB->CCR &= ~(uint32_t)SCB_CCR_DC_Msk; /* disable D-Cache */ + __DSB(); + + ccsidr = SCB->CCSIDR; + + /* clean & invalidate D-Cache */ + sets = (uint32_t)(CCSIDR_SETS(ccsidr)); + do { + ways = (uint32_t)(CCSIDR_WAYS(ccsidr)); + do { + SCB->DCCISW = (((sets << SCB_DCCISW_SET_Pos) & SCB_DCCISW_SET_Msk) | + ((ways << SCB_DCCISW_WAY_Pos) & SCB_DCCISW_WAY_Msk) ); + #if defined ( __CC_ARM ) + __schedule_barrier(); + #endif + } while (ways-- != 0U); + } while(sets-- != 0U); + + __DSB(); + __ISB(); + #endif +} + + +/** + \brief Invalidate D-Cache + \details Invalidates D-Cache + */ +__STATIC_INLINE void SCB_InvalidateDCache (void) +{ + #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + uint32_t ccsidr; + uint32_t sets; + uint32_t ways; + + SCB->CSSELR = 0U; /*(0U << 1U) | 0U;*/ /* Level 1 data cache */ + __DSB(); + + ccsidr = SCB->CCSIDR; + + /* invalidate D-Cache */ + sets = (uint32_t)(CCSIDR_SETS(ccsidr)); + do { + ways = (uint32_t)(CCSIDR_WAYS(ccsidr)); + do { + SCB->DCISW = (((sets << SCB_DCISW_SET_Pos) & SCB_DCISW_SET_Msk) | + ((ways << SCB_DCISW_WAY_Pos) & SCB_DCISW_WAY_Msk) ); + #if defined ( __CC_ARM ) + __schedule_barrier(); + #endif + } while (ways-- != 0U); + } while(sets-- != 0U); + + __DSB(); + __ISB(); + #endif +} + + +/** + \brief Clean D-Cache + \details Cleans D-Cache + */ +__STATIC_INLINE void SCB_CleanDCache (void) +{ + #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + uint32_t ccsidr; + uint32_t sets; + uint32_t ways; + + SCB->CSSELR = 0U; /*(0U << 1U) | 0U;*/ /* Level 1 data cache */ + __DSB(); + + ccsidr = SCB->CCSIDR; + + /* clean D-Cache */ + sets = (uint32_t)(CCSIDR_SETS(ccsidr)); + do { + ways = (uint32_t)(CCSIDR_WAYS(ccsidr)); + do { + SCB->DCCSW = (((sets << SCB_DCCSW_SET_Pos) & SCB_DCCSW_SET_Msk) | + ((ways << SCB_DCCSW_WAY_Pos) & SCB_DCCSW_WAY_Msk) ); + #if defined ( __CC_ARM ) + __schedule_barrier(); + #endif + } while (ways-- != 0U); + } while(sets-- != 0U); + + __DSB(); + __ISB(); + #endif +} + + +/** + \brief Clean & Invalidate D-Cache + \details Cleans and Invalidates D-Cache + */ +__STATIC_INLINE void SCB_CleanInvalidateDCache (void) +{ + #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + uint32_t ccsidr; + uint32_t sets; + uint32_t ways; + + SCB->CSSELR = 0U; /*(0U << 1U) | 0U;*/ /* Level 1 data cache */ + __DSB(); + + ccsidr = SCB->CCSIDR; + + /* clean & invalidate D-Cache */ + sets = (uint32_t)(CCSIDR_SETS(ccsidr)); + do { + ways = (uint32_t)(CCSIDR_WAYS(ccsidr)); + do { + SCB->DCCISW = (((sets << SCB_DCCISW_SET_Pos) & SCB_DCCISW_SET_Msk) | + ((ways << SCB_DCCISW_WAY_Pos) & SCB_DCCISW_WAY_Msk) ); + #if defined ( __CC_ARM ) + __schedule_barrier(); + #endif + } while (ways-- != 0U); + } while(sets-- != 0U); + + __DSB(); + __ISB(); + #endif +} + + +/** + \brief D-Cache Invalidate by address + \details Invalidates D-Cache for the given address + \param[in] addr address (aligned to 32-byte boundary) + \param[in] dsize size of memory block (in number of bytes) +*/ +__STATIC_INLINE void SCB_InvalidateDCache_by_Addr (uint32_t *addr, int32_t dsize) +{ + #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + int32_t op_size = dsize; + uint32_t op_addr = (uint32_t)addr; + int32_t linesize = 32; /* in Cortex-M7 size of cache line is fixed to 8 words (32 bytes) */ + + __DSB(); + + while (op_size > 0) { + SCB->DCIMVAC = op_addr; + op_addr += (uint32_t)linesize; + op_size -= linesize; + } + + __DSB(); + __ISB(); + #endif +} + + +/** + \brief D-Cache Clean by address + \details Cleans D-Cache for the given address + \param[in] addr address (aligned to 32-byte boundary) + \param[in] dsize size of memory block (in number of bytes) +*/ +__STATIC_INLINE void SCB_CleanDCache_by_Addr (uint32_t *addr, int32_t dsize) +{ + #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + int32_t op_size = dsize; + uint32_t op_addr = (uint32_t) addr; + int32_t linesize = 32; /* in Cortex-M7 size of cache line is fixed to 8 words (32 bytes) */ + + __DSB(); + + while (op_size > 0) { + SCB->DCCMVAC = op_addr; + op_addr += (uint32_t)linesize; + op_size -= linesize; + } + + __DSB(); + __ISB(); + #endif +} + + +/** + \brief D-Cache Clean and Invalidate by address + \details Cleans and invalidates D_Cache for the given address + \param[in] addr address (aligned to 32-byte boundary) + \param[in] dsize size of memory block (in number of bytes) +*/ +__STATIC_INLINE void SCB_CleanInvalidateDCache_by_Addr (uint32_t *addr, int32_t dsize) +{ + #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + int32_t op_size = dsize; + uint32_t op_addr = (uint32_t) addr; + int32_t linesize = 32; /* in Cortex-M7 size of cache line is fixed to 8 words (32 bytes) */ + + __DSB(); + + while (op_size > 0) { + SCB->DCCIMVAC = op_addr; + op_addr += (uint32_t)linesize; + op_size -= linesize; + } + + __DSB(); + __ISB(); + #endif +} + + +/*@} end of CMSIS_Core_CacheFunctions */ + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + +/* ##################################### Debug In/Output function ########################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_core_DebugFunctions ITM Functions + \brief Functions that access the ITM debug interface. + @{ + */ + +extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */ +#define ITM_RXBUFFER_EMPTY ((int32_t)0x5AA55AA5U) /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */ + + +/** + \brief ITM Send Character + \details Transmits a character via the ITM channel 0, and + \li Just returns when no debugger is connected that has booked the output. + \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted. + \param [in] ch Character to transmit. + \returns Character to transmit. + */ +__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch) +{ + if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) && /* ITM enabled */ + ((ITM->TER & 1UL ) != 0UL) ) /* ITM Port #0 enabled */ + { + while (ITM->PORT[0U].u32 == 0UL) + { + __NOP(); + } + ITM->PORT[0U].u8 = (uint8_t)ch; + } + return (ch); +} + + +/** + \brief ITM Receive Character + \details Inputs a character via the external variable \ref ITM_RxBuffer. + \return Received character. + \return -1 No character pending. + */ +__STATIC_INLINE int32_t ITM_ReceiveChar (void) +{ + int32_t ch = -1; /* no character available */ + + if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) + { + ch = ITM_RxBuffer; + ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */ + } + + return (ch); +} + + +/** + \brief ITM Check Character + \details Checks whether a character is pending for reading in the variable \ref ITM_RxBuffer. + \return 0 No character available. + \return 1 Character available. + */ +__STATIC_INLINE int32_t ITM_CheckChar (void) +{ + + if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) + { + return (0); /* no character available */ + } + else + { + return (1); /* character available */ + } +} + +/*@} end of CMSIS_core_DebugFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM7_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/test/STM32F072C8T6/Drivers/CMSIS/Include/core_sc000.h b/test/STM32F072C8T6/Drivers/CMSIS/Include/core_sc000.h new file mode 100644 index 0000000..9086c64 --- /dev/null +++ b/test/STM32F072C8T6/Drivers/CMSIS/Include/core_sc000.h @@ -0,0 +1,1022 @@ +/**************************************************************************//** + * @file core_sc000.h + * @brief CMSIS SC000 Core Peripheral Access Layer Header File + * @version V5.0.5 + * @date 28. May 2018 + ******************************************************************************/ +/* + * Copyright (c) 2009-2018 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * 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 + * + * 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. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CORE_SC000_H_GENERIC +#define __CORE_SC000_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup SC000 + @{ + */ + +#include "cmsis_version.h" + +/* CMSIS SC000 definitions */ +#define __SC000_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __SC000_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ +#define __SC000_CMSIS_VERSION ((__SC000_CMSIS_VERSION_MAIN << 16U) | \ + __SC000_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ + +#define __CORTEX_SC (000U) /*!< Cortex secure core */ + +/** __FPU_USED indicates whether an FPU is used or not. + This core does not support an FPU at all +*/ +#define __FPU_USED 0U + +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_PCS_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TI_ARM__ ) + #if defined __TI_VFP_SUPPORT__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_SC000_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_SC000_H_DEPENDANT +#define __CORE_SC000_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __SC000_REV + #define __SC000_REV 0x0000U + #warning "__SC000_REV not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0U + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 2U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group SC000 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core MPU Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:28; /*!< bit: 0..27 Reserved */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t _reserved1:3; /*!< bit: 25..27 Reserved */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t _reserved0:1; /*!< bit: 0 Reserved */ + uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ + uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[1U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[31U]; + __IOM uint32_t ICER[1U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[31U]; + __IOM uint32_t ISPR[1U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[31U]; + __IOM uint32_t ICPR[1U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[31U]; + uint32_t RESERVED4[64U]; + __IOM uint32_t IP[8U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */ +} NVIC_Type; + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + uint32_t RESERVED0[1U]; + __IOM uint32_t SHP[2U]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ + uint32_t RESERVED1[154U]; + __IOM uint32_t SFCR; /*!< Offset: 0x290 (R/W) Security Features Control Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */ +#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */ +#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) + \brief Type definitions for the System Control and ID Register not in the SCB + @{ + */ + +/** + \brief Structure type to access the System Control and ID Register not in the SCB. + */ +typedef struct +{ + uint32_t RESERVED0[2U]; + __IOM uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ +} SCnSCB_Type; + +/* Auxiliary Control Register Definitions */ +#define SCnSCB_ACTLR_DISMCYCINT_Pos 0U /*!< ACTLR: DISMCYCINT Position */ +#define SCnSCB_ACTLR_DISMCYCINT_Msk (1UL /*<< SCnSCB_ACTLR_DISMCYCINT_Pos*/) /*!< ACTLR: DISMCYCINT Mask */ + +/*@} end of group CMSIS_SCnotSCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** + \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IOM uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */ +} MPU_Type; + +/* MPU Type Register Definitions */ +#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register Definitions */ +#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register Definitions */ +#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register Definitions */ +#define MPU_RBAR_ADDR_Pos 8U /*!< MPU RBAR: ADDR Position */ +#define MPU_RBAR_ADDR_Msk (0xFFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ + +#define MPU_RBAR_VALID_Pos 4U /*!< MPU RBAR: VALID Position */ +#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */ + +#define MPU_RBAR_REGION_Pos 0U /*!< MPU RBAR: REGION Position */ +#define MPU_RBAR_REGION_Msk (0xFUL /*<< MPU_RBAR_REGION_Pos*/) /*!< MPU RBAR: REGION Mask */ + +/* MPU Region Attribute and Size Register Definitions */ +#define MPU_RASR_ATTRS_Pos 16U /*!< MPU RASR: MPU Region Attribute field Position */ +#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */ + +#define MPU_RASR_XN_Pos 28U /*!< MPU RASR: ATTRS.XN Position */ +#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */ + +#define MPU_RASR_AP_Pos 24U /*!< MPU RASR: ATTRS.AP Position */ +#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */ + +#define MPU_RASR_TEX_Pos 19U /*!< MPU RASR: ATTRS.TEX Position */ +#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */ + +#define MPU_RASR_S_Pos 18U /*!< MPU RASR: ATTRS.S Position */ +#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */ + +#define MPU_RASR_C_Pos 17U /*!< MPU RASR: ATTRS.C Position */ +#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */ + +#define MPU_RASR_B_Pos 16U /*!< MPU RASR: ATTRS.B Position */ +#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */ + +#define MPU_RASR_SRD_Pos 8U /*!< MPU RASR: Sub-Region Disable Position */ +#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */ + +#define MPU_RASR_SIZE_Pos 1U /*!< MPU RASR: Region Size Field Position */ +#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */ + +#define MPU_RASR_ENABLE_Pos 0U /*!< MPU RASR: Region enable bit Position */ +#define MPU_RASR_ENABLE_Msk (1UL /*<< MPU_RASR_ENABLE_Pos*/) /*!< MPU RASR: Region enable bit Disable Mask */ + +/*@} end of group CMSIS_MPU */ +#endif + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief SC000 Core Debug Registers (DCB registers, SHCSR, and DFSR) are only accessible over DAP and not via processor. + Therefore they are not covered by the SC000 header file. + @{ + */ +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param[in] field Name of the register bit field. + \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param[in] field Name of the register bit field. + \param[in] value Value of register. This parameter is interpreted as an uint32_t type. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) + +/*@} end of group CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Core Hardware */ +#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ +#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ +#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ +#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + +#define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ +#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ +#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ +#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ +#endif + +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else +/*#define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping not available for SC000 */ +/*#define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping not available for SC000 */ + #define NVIC_EnableIRQ __NVIC_EnableIRQ + #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ + #define NVIC_DisableIRQ __NVIC_DisableIRQ + #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ + #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ + #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ +/*#define NVIC_GetActive __NVIC_GetActive not available for SC000 */ + #define NVIC_SetPriority __NVIC_SetPriority + #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset +#endif /* CMSIS_NVIC_VIRTUAL */ + +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetVector __NVIC_SetVector + #define NVIC_GetVector __NVIC_GetVector +#endif /* (CMSIS_VECTAB_VIRTUAL) */ + +#define NVIC_USER_IRQ_OFFSET 16 + + +/* The following EXC_RETURN values are saved the LR on exception entry */ +#define EXC_RETURN_HANDLER (0xFFFFFFF1UL) /* return to Handler mode, uses MSP after return */ +#define EXC_RETURN_THREAD_MSP (0xFFFFFFF9UL) /* return to Thread mode, uses MSP after return */ +#define EXC_RETURN_THREAD_PSP (0xFFFFFFFDUL) /* return to Thread mode, uses PSP after return */ + + +/* Interrupt Priorities are WORD accessible only under Armv6-M */ +/* The following MACROS handle generation of the register offset and byte masks */ +#define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL) +#define _SHP_IDX(IRQn) ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >> 2UL) ) +#define _IP_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 2UL) ) + + +/** + \brief Enable Interrupt + \details Enables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISER[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Interrupt Enable status + \details Returns a device specific interrupt enable status from the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISER[0U] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt + \details Disables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICER[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __DSB(); + __ISB(); + } +} + + +/** + \brief Get Pending Interrupt + \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISPR[0U] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISPR[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICPR[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Set Interrupt Priority + \details Sets the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every processor exception. + */ +__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->IP[_IP_IDX(IRQn)] = ((uint32_t)(NVIC->IP[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } + else + { + SCB->SHP[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief Set Interrupt Vector + \details Sets an interrupt vector in SRAM based interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + VTOR must been relocated to SRAM before. + \param [in] IRQn Interrupt number + \param [in] vector Address of interrupt handler function + */ +__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; +} + + +/** + \brief Get Interrupt Vector + \details Reads an interrupt vector from interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Address of interrupt handler function + */ +__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET]; +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + SCB_AIRCR_SYSRESETREQ_Msk); + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +/*@} end of CMSIS_Core_NVICFunctions */ + + +/* ########################## FPU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_FpuFunctions FPU Functions + \brief Function that provides FPU type. + @{ + */ + +/** + \brief get FPU type + \details returns the FPU type + \returns + - \b 0: No FPU + - \b 1: Single precision FPU + - \b 2: Double + Single precision FPU + */ +__STATIC_INLINE uint32_t SCB_GetFPUType(void) +{ + return 0U; /* No FPU */ +} + + +/*@} end of CMSIS_Core_FpuFunctions */ + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_SC000_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/test/STM32F072C8T6/Drivers/CMSIS/Include/core_sc300.h b/test/STM32F072C8T6/Drivers/CMSIS/Include/core_sc300.h new file mode 100644 index 0000000..665822d --- /dev/null +++ b/test/STM32F072C8T6/Drivers/CMSIS/Include/core_sc300.h @@ -0,0 +1,1915 @@ +/**************************************************************************//** + * @file core_sc300.h + * @brief CMSIS SC300 Core Peripheral Access Layer Header File + * @version V5.0.6 + * @date 04. June 2018 + ******************************************************************************/ +/* + * Copyright (c) 2009-2018 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * 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 + * + * 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. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CORE_SC300_H_GENERIC +#define __CORE_SC300_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup SC3000 + @{ + */ + +#include "cmsis_version.h" + +/* CMSIS SC300 definitions */ +#define __SC300_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __SC300_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ +#define __SC300_CMSIS_VERSION ((__SC300_CMSIS_VERSION_MAIN << 16U) | \ + __SC300_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ + +#define __CORTEX_SC (300U) /*!< Cortex secure core */ + +/** __FPU_USED indicates whether an FPU is used or not. + This core does not support an FPU at all +*/ +#define __FPU_USED 0U + +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_PCS_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TI_ARM__ ) + #if defined __TI_VFP_SUPPORT__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_SC300_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_SC300_H_DEPENDANT +#define __CORE_SC300_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __SC300_REV + #define __SC300_REV 0x0000U + #warning "__SC300_REV not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0U + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 3U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group SC300 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug Register + - Core MPU Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:27; /*!< bit: 0..26 Reserved */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + +#define APSR_Q_Pos 27U /*!< APSR: Q Position */ +#define APSR_Q_Msk (1UL << APSR_Q_Pos) /*!< APSR: Q Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:1; /*!< bit: 9 Reserved */ + uint32_t ICI_IT_1:6; /*!< bit: 10..15 ICI/IT part 1 */ + uint32_t _reserved1:8; /*!< bit: 16..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit */ + uint32_t ICI_IT_2:2; /*!< bit: 25..26 ICI/IT part 2 */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_Q_Pos 27U /*!< xPSR: Q Position */ +#define xPSR_Q_Msk (1UL << xPSR_Q_Pos) /*!< xPSR: Q Mask */ + +#define xPSR_ICI_IT_2_Pos 25U /*!< xPSR: ICI/IT part 2 Position */ +#define xPSR_ICI_IT_2_Msk (3UL << xPSR_ICI_IT_2_Pos) /*!< xPSR: ICI/IT part 2 Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_ICI_IT_1_Pos 10U /*!< xPSR: ICI/IT part 1 Position */ +#define xPSR_ICI_IT_1_Msk (0x3FUL << xPSR_ICI_IT_1_Pos) /*!< xPSR: ICI/IT part 1 Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ + uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ +#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[8U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[24U]; + __IOM uint32_t ICER[8U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[24U]; + __IOM uint32_t ISPR[8U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[24U]; + __IOM uint32_t ICPR[8U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[24U]; + __IOM uint32_t IABR[8U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[56U]; + __IOM uint8_t IP[240U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ + uint32_t RESERVED5[644U]; + __OM uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ +} NVIC_Type; + +/* Software Triggered Interrupt Register Definitions */ +#define NVIC_STIR_INTID_Pos 0U /*!< STIR: INTLINESNUM Position */ +#define NVIC_STIR_INTID_Msk (0x1FFUL /*<< NVIC_STIR_INTID_Pos*/) /*!< STIR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + __IOM uint8_t SHP[12U]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ + __IOM uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ + __IOM uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ + __IOM uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ + __IOM uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ + __IOM uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ + __IOM uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ + __IM uint32_t PFR[2U]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ + __IM uint32_t DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ + __IM uint32_t ADR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ + __IM uint32_t MMFR[4U]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ + __IM uint32_t ISAR[5U]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ + uint32_t RESERVED0[5U]; + __IOM uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ + uint32_t RESERVED1[129U]; + __IOM uint32_t SFCR; /*!< Offset: 0x290 (R/W) Security Features Control Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */ +#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_RETTOBASE_Pos 11U /*!< SCB ICSR: RETTOBASE Position */ +#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Vector Table Offset Register Definitions */ +#define SCB_VTOR_TBLBASE_Pos 29U /*!< SCB VTOR: TBLBASE Position */ +#define SCB_VTOR_TBLBASE_Msk (1UL << SCB_VTOR_TBLBASE_Pos) /*!< SCB VTOR: TBLBASE Mask */ + +#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x3FFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_PRIGROUP_Pos 8U /*!< SCB AIRCR: PRIGROUP Position */ +#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +#define SCB_AIRCR_VECTRESET_Pos 0U /*!< SCB AIRCR: VECTRESET Position */ +#define SCB_AIRCR_VECTRESET_Msk (1UL /*<< SCB_AIRCR_VECTRESET_Pos*/) /*!< SCB AIRCR: VECTRESET Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */ +#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ + +#define SCB_CCR_BFHFNMIGN_Pos 8U /*!< SCB CCR: BFHFNMIGN Position */ +#define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ + +#define SCB_CCR_DIV_0_TRP_Pos 4U /*!< SCB CCR: DIV_0_TRP Position */ +#define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +#define SCB_CCR_USERSETMPEND_Pos 1U /*!< SCB CCR: USERSETMPEND Position */ +#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ + +#define SCB_CCR_NONBASETHRDENA_Pos 0U /*!< SCB CCR: NONBASETHRDENA Position */ +#define SCB_CCR_NONBASETHRDENA_Msk (1UL /*<< SCB_CCR_NONBASETHRDENA_Pos*/) /*!< SCB CCR: NONBASETHRDENA Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_USGFAULTENA_Pos 18U /*!< SCB SHCSR: USGFAULTENA Position */ +#define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */ + +#define SCB_SHCSR_BUSFAULTENA_Pos 17U /*!< SCB SHCSR: BUSFAULTENA Position */ +#define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */ + +#define SCB_SHCSR_MEMFAULTENA_Pos 16U /*!< SCB SHCSR: MEMFAULTENA Position */ +#define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */ + +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +#define SCB_SHCSR_BUSFAULTPENDED_Pos 14U /*!< SCB SHCSR: BUSFAULTPENDED Position */ +#define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */ + +#define SCB_SHCSR_MEMFAULTPENDED_Pos 13U /*!< SCB SHCSR: MEMFAULTPENDED Position */ +#define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */ + +#define SCB_SHCSR_USGFAULTPENDED_Pos 12U /*!< SCB SHCSR: USGFAULTPENDED Position */ +#define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */ + +#define SCB_SHCSR_SYSTICKACT_Pos 11U /*!< SCB SHCSR: SYSTICKACT Position */ +#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ + +#define SCB_SHCSR_PENDSVACT_Pos 10U /*!< SCB SHCSR: PENDSVACT Position */ +#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ + +#define SCB_SHCSR_MONITORACT_Pos 8U /*!< SCB SHCSR: MONITORACT Position */ +#define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */ + +#define SCB_SHCSR_SVCALLACT_Pos 7U /*!< SCB SHCSR: SVCALLACT Position */ +#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ + +#define SCB_SHCSR_USGFAULTACT_Pos 3U /*!< SCB SHCSR: USGFAULTACT Position */ +#define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */ + +#define SCB_SHCSR_BUSFAULTACT_Pos 1U /*!< SCB SHCSR: BUSFAULTACT Position */ +#define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */ + +#define SCB_SHCSR_MEMFAULTACT_Pos 0U /*!< SCB SHCSR: MEMFAULTACT Position */ +#define SCB_SHCSR_MEMFAULTACT_Msk (1UL /*<< SCB_SHCSR_MEMFAULTACT_Pos*/) /*!< SCB SHCSR: MEMFAULTACT Mask */ + +/* SCB Configurable Fault Status Register Definitions */ +#define SCB_CFSR_USGFAULTSR_Pos 16U /*!< SCB CFSR: Usage Fault Status Register Position */ +#define SCB_CFSR_USGFAULTSR_Msk (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */ + +#define SCB_CFSR_BUSFAULTSR_Pos 8U /*!< SCB CFSR: Bus Fault Status Register Position */ +#define SCB_CFSR_BUSFAULTSR_Msk (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */ + +#define SCB_CFSR_MEMFAULTSR_Pos 0U /*!< SCB CFSR: Memory Manage Fault Status Register Position */ +#define SCB_CFSR_MEMFAULTSR_Msk (0xFFUL /*<< SCB_CFSR_MEMFAULTSR_Pos*/) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */ + +/* MemManage Fault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_MMARVALID_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 7U) /*!< SCB CFSR (MMFSR): MMARVALID Position */ +#define SCB_CFSR_MMARVALID_Msk (1UL << SCB_CFSR_MMARVALID_Pos) /*!< SCB CFSR (MMFSR): MMARVALID Mask */ + +#define SCB_CFSR_MSTKERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 4U) /*!< SCB CFSR (MMFSR): MSTKERR Position */ +#define SCB_CFSR_MSTKERR_Msk (1UL << SCB_CFSR_MSTKERR_Pos) /*!< SCB CFSR (MMFSR): MSTKERR Mask */ + +#define SCB_CFSR_MUNSTKERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 3U) /*!< SCB CFSR (MMFSR): MUNSTKERR Position */ +#define SCB_CFSR_MUNSTKERR_Msk (1UL << SCB_CFSR_MUNSTKERR_Pos) /*!< SCB CFSR (MMFSR): MUNSTKERR Mask */ + +#define SCB_CFSR_DACCVIOL_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 1U) /*!< SCB CFSR (MMFSR): DACCVIOL Position */ +#define SCB_CFSR_DACCVIOL_Msk (1UL << SCB_CFSR_DACCVIOL_Pos) /*!< SCB CFSR (MMFSR): DACCVIOL Mask */ + +#define SCB_CFSR_IACCVIOL_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 0U) /*!< SCB CFSR (MMFSR): IACCVIOL Position */ +#define SCB_CFSR_IACCVIOL_Msk (1UL /*<< SCB_CFSR_IACCVIOL_Pos*/) /*!< SCB CFSR (MMFSR): IACCVIOL Mask */ + +/* BusFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_BFARVALID_Pos (SCB_CFSR_BUSFAULTSR_Pos + 7U) /*!< SCB CFSR (BFSR): BFARVALID Position */ +#define SCB_CFSR_BFARVALID_Msk (1UL << SCB_CFSR_BFARVALID_Pos) /*!< SCB CFSR (BFSR): BFARVALID Mask */ + +#define SCB_CFSR_STKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 4U) /*!< SCB CFSR (BFSR): STKERR Position */ +#define SCB_CFSR_STKERR_Msk (1UL << SCB_CFSR_STKERR_Pos) /*!< SCB CFSR (BFSR): STKERR Mask */ + +#define SCB_CFSR_UNSTKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 3U) /*!< SCB CFSR (BFSR): UNSTKERR Position */ +#define SCB_CFSR_UNSTKERR_Msk (1UL << SCB_CFSR_UNSTKERR_Pos) /*!< SCB CFSR (BFSR): UNSTKERR Mask */ + +#define SCB_CFSR_IMPRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 2U) /*!< SCB CFSR (BFSR): IMPRECISERR Position */ +#define SCB_CFSR_IMPRECISERR_Msk (1UL << SCB_CFSR_IMPRECISERR_Pos) /*!< SCB CFSR (BFSR): IMPRECISERR Mask */ + +#define SCB_CFSR_PRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 1U) /*!< SCB CFSR (BFSR): PRECISERR Position */ +#define SCB_CFSR_PRECISERR_Msk (1UL << SCB_CFSR_PRECISERR_Pos) /*!< SCB CFSR (BFSR): PRECISERR Mask */ + +#define SCB_CFSR_IBUSERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 0U) /*!< SCB CFSR (BFSR): IBUSERR Position */ +#define SCB_CFSR_IBUSERR_Msk (1UL << SCB_CFSR_IBUSERR_Pos) /*!< SCB CFSR (BFSR): IBUSERR Mask */ + +/* UsageFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_DIVBYZERO_Pos (SCB_CFSR_USGFAULTSR_Pos + 9U) /*!< SCB CFSR (UFSR): DIVBYZERO Position */ +#define SCB_CFSR_DIVBYZERO_Msk (1UL << SCB_CFSR_DIVBYZERO_Pos) /*!< SCB CFSR (UFSR): DIVBYZERO Mask */ + +#define SCB_CFSR_UNALIGNED_Pos (SCB_CFSR_USGFAULTSR_Pos + 8U) /*!< SCB CFSR (UFSR): UNALIGNED Position */ +#define SCB_CFSR_UNALIGNED_Msk (1UL << SCB_CFSR_UNALIGNED_Pos) /*!< SCB CFSR (UFSR): UNALIGNED Mask */ + +#define SCB_CFSR_NOCP_Pos (SCB_CFSR_USGFAULTSR_Pos + 3U) /*!< SCB CFSR (UFSR): NOCP Position */ +#define SCB_CFSR_NOCP_Msk (1UL << SCB_CFSR_NOCP_Pos) /*!< SCB CFSR (UFSR): NOCP Mask */ + +#define SCB_CFSR_INVPC_Pos (SCB_CFSR_USGFAULTSR_Pos + 2U) /*!< SCB CFSR (UFSR): INVPC Position */ +#define SCB_CFSR_INVPC_Msk (1UL << SCB_CFSR_INVPC_Pos) /*!< SCB CFSR (UFSR): INVPC Mask */ + +#define SCB_CFSR_INVSTATE_Pos (SCB_CFSR_USGFAULTSR_Pos + 1U) /*!< SCB CFSR (UFSR): INVSTATE Position */ +#define SCB_CFSR_INVSTATE_Msk (1UL << SCB_CFSR_INVSTATE_Pos) /*!< SCB CFSR (UFSR): INVSTATE Mask */ + +#define SCB_CFSR_UNDEFINSTR_Pos (SCB_CFSR_USGFAULTSR_Pos + 0U) /*!< SCB CFSR (UFSR): UNDEFINSTR Position */ +#define SCB_CFSR_UNDEFINSTR_Msk (1UL << SCB_CFSR_UNDEFINSTR_Pos) /*!< SCB CFSR (UFSR): UNDEFINSTR Mask */ + +/* SCB Hard Fault Status Register Definitions */ +#define SCB_HFSR_DEBUGEVT_Pos 31U /*!< SCB HFSR: DEBUGEVT Position */ +#define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ + +#define SCB_HFSR_FORCED_Pos 30U /*!< SCB HFSR: FORCED Position */ +#define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */ + +#define SCB_HFSR_VECTTBL_Pos 1U /*!< SCB HFSR: VECTTBL Position */ +#define SCB_HFSR_VECTTBL_Msk (1UL << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */ + +/* SCB Debug Fault Status Register Definitions */ +#define SCB_DFSR_EXTERNAL_Pos 4U /*!< SCB DFSR: EXTERNAL Position */ +#define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */ + +#define SCB_DFSR_VCATCH_Pos 3U /*!< SCB DFSR: VCATCH Position */ +#define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */ + +#define SCB_DFSR_DWTTRAP_Pos 2U /*!< SCB DFSR: DWTTRAP Position */ +#define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */ + +#define SCB_DFSR_BKPT_Pos 1U /*!< SCB DFSR: BKPT Position */ +#define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */ + +#define SCB_DFSR_HALTED_Pos 0U /*!< SCB DFSR: HALTED Position */ +#define SCB_DFSR_HALTED_Msk (1UL /*<< SCB_DFSR_HALTED_Pos*/) /*!< SCB DFSR: HALTED Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) + \brief Type definitions for the System Control and ID Register not in the SCB + @{ + */ + +/** + \brief Structure type to access the System Control and ID Register not in the SCB. + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IM uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ + uint32_t RESERVED1[1U]; +} SCnSCB_Type; + +/* Interrupt Controller Type Register Definitions */ +#define SCnSCB_ICTR_INTLINESNUM_Pos 0U /*!< ICTR: INTLINESNUM Position */ +#define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL /*<< SCnSCB_ICTR_INTLINESNUM_Pos*/) /*!< ICTR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_SCnotSCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_ITM Instrumentation Trace Macrocell (ITM) + \brief Type definitions for the Instrumentation Trace Macrocell (ITM) + @{ + */ + +/** + \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM). + */ +typedef struct +{ + __OM union + { + __OM uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ + __OM uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ + __OM uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ + } PORT [32U]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ + uint32_t RESERVED0[864U]; + __IOM uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ + uint32_t RESERVED1[15U]; + __IOM uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ + uint32_t RESERVED2[15U]; + __IOM uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ + uint32_t RESERVED3[29U]; + __OM uint32_t IWR; /*!< Offset: 0xEF8 ( /W) ITM Integration Write Register */ + __IM uint32_t IRR; /*!< Offset: 0xEFC (R/ ) ITM Integration Read Register */ + __IOM uint32_t IMCR; /*!< Offset: 0xF00 (R/W) ITM Integration Mode Control Register */ + uint32_t RESERVED4[43U]; + __OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */ + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */ + uint32_t RESERVED5[6U]; + __IM uint32_t PID4; /*!< Offset: 0xFD0 (R/ ) ITM Peripheral Identification Register #4 */ + __IM uint32_t PID5; /*!< Offset: 0xFD4 (R/ ) ITM Peripheral Identification Register #5 */ + __IM uint32_t PID6; /*!< Offset: 0xFD8 (R/ ) ITM Peripheral Identification Register #6 */ + __IM uint32_t PID7; /*!< Offset: 0xFDC (R/ ) ITM Peripheral Identification Register #7 */ + __IM uint32_t PID0; /*!< Offset: 0xFE0 (R/ ) ITM Peripheral Identification Register #0 */ + __IM uint32_t PID1; /*!< Offset: 0xFE4 (R/ ) ITM Peripheral Identification Register #1 */ + __IM uint32_t PID2; /*!< Offset: 0xFE8 (R/ ) ITM Peripheral Identification Register #2 */ + __IM uint32_t PID3; /*!< Offset: 0xFEC (R/ ) ITM Peripheral Identification Register #3 */ + __IM uint32_t CID0; /*!< Offset: 0xFF0 (R/ ) ITM Component Identification Register #0 */ + __IM uint32_t CID1; /*!< Offset: 0xFF4 (R/ ) ITM Component Identification Register #1 */ + __IM uint32_t CID2; /*!< Offset: 0xFF8 (R/ ) ITM Component Identification Register #2 */ + __IM uint32_t CID3; /*!< Offset: 0xFFC (R/ ) ITM Component Identification Register #3 */ +} ITM_Type; + +/* ITM Trace Privilege Register Definitions */ +#define ITM_TPR_PRIVMASK_Pos 0U /*!< ITM TPR: PRIVMASK Position */ +#define ITM_TPR_PRIVMASK_Msk (0xFUL /*<< ITM_TPR_PRIVMASK_Pos*/) /*!< ITM TPR: PRIVMASK Mask */ + +/* ITM Trace Control Register Definitions */ +#define ITM_TCR_BUSY_Pos 23U /*!< ITM TCR: BUSY Position */ +#define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */ + +#define ITM_TCR_TraceBusID_Pos 16U /*!< ITM TCR: ATBID Position */ +#define ITM_TCR_TraceBusID_Msk (0x7FUL << ITM_TCR_TraceBusID_Pos) /*!< ITM TCR: ATBID Mask */ + +#define ITM_TCR_GTSFREQ_Pos 10U /*!< ITM TCR: Global timestamp frequency Position */ +#define ITM_TCR_GTSFREQ_Msk (3UL << ITM_TCR_GTSFREQ_Pos) /*!< ITM TCR: Global timestamp frequency Mask */ + +#define ITM_TCR_TSPrescale_Pos 8U /*!< ITM TCR: TSPrescale Position */ +#define ITM_TCR_TSPrescale_Msk (3UL << ITM_TCR_TSPrescale_Pos) /*!< ITM TCR: TSPrescale Mask */ + +#define ITM_TCR_SWOENA_Pos 4U /*!< ITM TCR: SWOENA Position */ +#define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */ + +#define ITM_TCR_DWTENA_Pos 3U /*!< ITM TCR: DWTENA Position */ +#define ITM_TCR_DWTENA_Msk (1UL << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */ + +#define ITM_TCR_SYNCENA_Pos 2U /*!< ITM TCR: SYNCENA Position */ +#define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */ + +#define ITM_TCR_TSENA_Pos 1U /*!< ITM TCR: TSENA Position */ +#define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */ + +#define ITM_TCR_ITMENA_Pos 0U /*!< ITM TCR: ITM Enable bit Position */ +#define ITM_TCR_ITMENA_Msk (1UL /*<< ITM_TCR_ITMENA_Pos*/) /*!< ITM TCR: ITM Enable bit Mask */ + +/* ITM Integration Write Register Definitions */ +#define ITM_IWR_ATVALIDM_Pos 0U /*!< ITM IWR: ATVALIDM Position */ +#define ITM_IWR_ATVALIDM_Msk (1UL /*<< ITM_IWR_ATVALIDM_Pos*/) /*!< ITM IWR: ATVALIDM Mask */ + +/* ITM Integration Read Register Definitions */ +#define ITM_IRR_ATREADYM_Pos 0U /*!< ITM IRR: ATREADYM Position */ +#define ITM_IRR_ATREADYM_Msk (1UL /*<< ITM_IRR_ATREADYM_Pos*/) /*!< ITM IRR: ATREADYM Mask */ + +/* ITM Integration Mode Control Register Definitions */ +#define ITM_IMCR_INTEGRATION_Pos 0U /*!< ITM IMCR: INTEGRATION Position */ +#define ITM_IMCR_INTEGRATION_Msk (1UL /*<< ITM_IMCR_INTEGRATION_Pos*/) /*!< ITM IMCR: INTEGRATION Mask */ + +/* ITM Lock Status Register Definitions */ +#define ITM_LSR_ByteAcc_Pos 2U /*!< ITM LSR: ByteAcc Position */ +#define ITM_LSR_ByteAcc_Msk (1UL << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */ + +#define ITM_LSR_Access_Pos 1U /*!< ITM LSR: Access Position */ +#define ITM_LSR_Access_Msk (1UL << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */ + +#define ITM_LSR_Present_Pos 0U /*!< ITM LSR: Present Position */ +#define ITM_LSR_Present_Msk (1UL /*<< ITM_LSR_Present_Pos*/) /*!< ITM LSR: Present Mask */ + +/*@}*/ /* end of group CMSIS_ITM */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) + \brief Type definitions for the Data Watchpoint and Trace (DWT) + @{ + */ + +/** + \brief Structure type to access the Data Watchpoint and Trace Register (DWT). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ + __IOM uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */ + __IOM uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */ + __IOM uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */ + __IOM uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */ + __IOM uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */ + __IOM uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */ + __IM uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ + __IOM uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ + __IOM uint32_t MASK0; /*!< Offset: 0x024 (R/W) Mask Register 0 */ + __IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ + uint32_t RESERVED0[1U]; + __IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ + __IOM uint32_t MASK1; /*!< Offset: 0x034 (R/W) Mask Register 1 */ + __IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ + uint32_t RESERVED1[1U]; + __IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ + __IOM uint32_t MASK2; /*!< Offset: 0x044 (R/W) Mask Register 2 */ + __IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ + uint32_t RESERVED2[1U]; + __IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ + __IOM uint32_t MASK3; /*!< Offset: 0x054 (R/W) Mask Register 3 */ + __IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ +} DWT_Type; + +/* DWT Control Register Definitions */ +#define DWT_CTRL_NUMCOMP_Pos 28U /*!< DWT CTRL: NUMCOMP Position */ +#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ + +#define DWT_CTRL_NOTRCPKT_Pos 27U /*!< DWT CTRL: NOTRCPKT Position */ +#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ + +#define DWT_CTRL_NOEXTTRIG_Pos 26U /*!< DWT CTRL: NOEXTTRIG Position */ +#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ + +#define DWT_CTRL_NOCYCCNT_Pos 25U /*!< DWT CTRL: NOCYCCNT Position */ +#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ + +#define DWT_CTRL_NOPRFCNT_Pos 24U /*!< DWT CTRL: NOPRFCNT Position */ +#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ + +#define DWT_CTRL_CYCEVTENA_Pos 22U /*!< DWT CTRL: CYCEVTENA Position */ +#define DWT_CTRL_CYCEVTENA_Msk (0x1UL << DWT_CTRL_CYCEVTENA_Pos) /*!< DWT CTRL: CYCEVTENA Mask */ + +#define DWT_CTRL_FOLDEVTENA_Pos 21U /*!< DWT CTRL: FOLDEVTENA Position */ +#define DWT_CTRL_FOLDEVTENA_Msk (0x1UL << DWT_CTRL_FOLDEVTENA_Pos) /*!< DWT CTRL: FOLDEVTENA Mask */ + +#define DWT_CTRL_LSUEVTENA_Pos 20U /*!< DWT CTRL: LSUEVTENA Position */ +#define DWT_CTRL_LSUEVTENA_Msk (0x1UL << DWT_CTRL_LSUEVTENA_Pos) /*!< DWT CTRL: LSUEVTENA Mask */ + +#define DWT_CTRL_SLEEPEVTENA_Pos 19U /*!< DWT CTRL: SLEEPEVTENA Position */ +#define DWT_CTRL_SLEEPEVTENA_Msk (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos) /*!< DWT CTRL: SLEEPEVTENA Mask */ + +#define DWT_CTRL_EXCEVTENA_Pos 18U /*!< DWT CTRL: EXCEVTENA Position */ +#define DWT_CTRL_EXCEVTENA_Msk (0x1UL << DWT_CTRL_EXCEVTENA_Pos) /*!< DWT CTRL: EXCEVTENA Mask */ + +#define DWT_CTRL_CPIEVTENA_Pos 17U /*!< DWT CTRL: CPIEVTENA Position */ +#define DWT_CTRL_CPIEVTENA_Msk (0x1UL << DWT_CTRL_CPIEVTENA_Pos) /*!< DWT CTRL: CPIEVTENA Mask */ + +#define DWT_CTRL_EXCTRCENA_Pos 16U /*!< DWT CTRL: EXCTRCENA Position */ +#define DWT_CTRL_EXCTRCENA_Msk (0x1UL << DWT_CTRL_EXCTRCENA_Pos) /*!< DWT CTRL: EXCTRCENA Mask */ + +#define DWT_CTRL_PCSAMPLENA_Pos 12U /*!< DWT CTRL: PCSAMPLENA Position */ +#define DWT_CTRL_PCSAMPLENA_Msk (0x1UL << DWT_CTRL_PCSAMPLENA_Pos) /*!< DWT CTRL: PCSAMPLENA Mask */ + +#define DWT_CTRL_SYNCTAP_Pos 10U /*!< DWT CTRL: SYNCTAP Position */ +#define DWT_CTRL_SYNCTAP_Msk (0x3UL << DWT_CTRL_SYNCTAP_Pos) /*!< DWT CTRL: SYNCTAP Mask */ + +#define DWT_CTRL_CYCTAP_Pos 9U /*!< DWT CTRL: CYCTAP Position */ +#define DWT_CTRL_CYCTAP_Msk (0x1UL << DWT_CTRL_CYCTAP_Pos) /*!< DWT CTRL: CYCTAP Mask */ + +#define DWT_CTRL_POSTINIT_Pos 5U /*!< DWT CTRL: POSTINIT Position */ +#define DWT_CTRL_POSTINIT_Msk (0xFUL << DWT_CTRL_POSTINIT_Pos) /*!< DWT CTRL: POSTINIT Mask */ + +#define DWT_CTRL_POSTPRESET_Pos 1U /*!< DWT CTRL: POSTPRESET Position */ +#define DWT_CTRL_POSTPRESET_Msk (0xFUL << DWT_CTRL_POSTPRESET_Pos) /*!< DWT CTRL: POSTPRESET Mask */ + +#define DWT_CTRL_CYCCNTENA_Pos 0U /*!< DWT CTRL: CYCCNTENA Position */ +#define DWT_CTRL_CYCCNTENA_Msk (0x1UL /*<< DWT_CTRL_CYCCNTENA_Pos*/) /*!< DWT CTRL: CYCCNTENA Mask */ + +/* DWT CPI Count Register Definitions */ +#define DWT_CPICNT_CPICNT_Pos 0U /*!< DWT CPICNT: CPICNT Position */ +#define DWT_CPICNT_CPICNT_Msk (0xFFUL /*<< DWT_CPICNT_CPICNT_Pos*/) /*!< DWT CPICNT: CPICNT Mask */ + +/* DWT Exception Overhead Count Register Definitions */ +#define DWT_EXCCNT_EXCCNT_Pos 0U /*!< DWT EXCCNT: EXCCNT Position */ +#define DWT_EXCCNT_EXCCNT_Msk (0xFFUL /*<< DWT_EXCCNT_EXCCNT_Pos*/) /*!< DWT EXCCNT: EXCCNT Mask */ + +/* DWT Sleep Count Register Definitions */ +#define DWT_SLEEPCNT_SLEEPCNT_Pos 0U /*!< DWT SLEEPCNT: SLEEPCNT Position */ +#define DWT_SLEEPCNT_SLEEPCNT_Msk (0xFFUL /*<< DWT_SLEEPCNT_SLEEPCNT_Pos*/) /*!< DWT SLEEPCNT: SLEEPCNT Mask */ + +/* DWT LSU Count Register Definitions */ +#define DWT_LSUCNT_LSUCNT_Pos 0U /*!< DWT LSUCNT: LSUCNT Position */ +#define DWT_LSUCNT_LSUCNT_Msk (0xFFUL /*<< DWT_LSUCNT_LSUCNT_Pos*/) /*!< DWT LSUCNT: LSUCNT Mask */ + +/* DWT Folded-instruction Count Register Definitions */ +#define DWT_FOLDCNT_FOLDCNT_Pos 0U /*!< DWT FOLDCNT: FOLDCNT Position */ +#define DWT_FOLDCNT_FOLDCNT_Msk (0xFFUL /*<< DWT_FOLDCNT_FOLDCNT_Pos*/) /*!< DWT FOLDCNT: FOLDCNT Mask */ + +/* DWT Comparator Mask Register Definitions */ +#define DWT_MASK_MASK_Pos 0U /*!< DWT MASK: MASK Position */ +#define DWT_MASK_MASK_Msk (0x1FUL /*<< DWT_MASK_MASK_Pos*/) /*!< DWT MASK: MASK Mask */ + +/* DWT Comparator Function Register Definitions */ +#define DWT_FUNCTION_MATCHED_Pos 24U /*!< DWT FUNCTION: MATCHED Position */ +#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ + +#define DWT_FUNCTION_DATAVADDR1_Pos 16U /*!< DWT FUNCTION: DATAVADDR1 Position */ +#define DWT_FUNCTION_DATAVADDR1_Msk (0xFUL << DWT_FUNCTION_DATAVADDR1_Pos) /*!< DWT FUNCTION: DATAVADDR1 Mask */ + +#define DWT_FUNCTION_DATAVADDR0_Pos 12U /*!< DWT FUNCTION: DATAVADDR0 Position */ +#define DWT_FUNCTION_DATAVADDR0_Msk (0xFUL << DWT_FUNCTION_DATAVADDR0_Pos) /*!< DWT FUNCTION: DATAVADDR0 Mask */ + +#define DWT_FUNCTION_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */ +#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ + +#define DWT_FUNCTION_LNK1ENA_Pos 9U /*!< DWT FUNCTION: LNK1ENA Position */ +#define DWT_FUNCTION_LNK1ENA_Msk (0x1UL << DWT_FUNCTION_LNK1ENA_Pos) /*!< DWT FUNCTION: LNK1ENA Mask */ + +#define DWT_FUNCTION_DATAVMATCH_Pos 8U /*!< DWT FUNCTION: DATAVMATCH Position */ +#define DWT_FUNCTION_DATAVMATCH_Msk (0x1UL << DWT_FUNCTION_DATAVMATCH_Pos) /*!< DWT FUNCTION: DATAVMATCH Mask */ + +#define DWT_FUNCTION_CYCMATCH_Pos 7U /*!< DWT FUNCTION: CYCMATCH Position */ +#define DWT_FUNCTION_CYCMATCH_Msk (0x1UL << DWT_FUNCTION_CYCMATCH_Pos) /*!< DWT FUNCTION: CYCMATCH Mask */ + +#define DWT_FUNCTION_EMITRANGE_Pos 5U /*!< DWT FUNCTION: EMITRANGE Position */ +#define DWT_FUNCTION_EMITRANGE_Msk (0x1UL << DWT_FUNCTION_EMITRANGE_Pos) /*!< DWT FUNCTION: EMITRANGE Mask */ + +#define DWT_FUNCTION_FUNCTION_Pos 0U /*!< DWT FUNCTION: FUNCTION Position */ +#define DWT_FUNCTION_FUNCTION_Msk (0xFUL /*<< DWT_FUNCTION_FUNCTION_Pos*/) /*!< DWT FUNCTION: FUNCTION Mask */ + +/*@}*/ /* end of group CMSIS_DWT */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_TPI Trace Port Interface (TPI) + \brief Type definitions for the Trace Port Interface (TPI) + @{ + */ + +/** + \brief Structure type to access the Trace Port Interface Register (TPI). + */ +typedef struct +{ + __IM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ + __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ + uint32_t RESERVED0[2U]; + __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ + uint32_t RESERVED1[55U]; + __IOM uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ + uint32_t RESERVED2[131U]; + __IM uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ + __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ + __IM uint32_t FSCR; /*!< Offset: 0x308 (R/ ) Formatter Synchronization Counter Register */ + uint32_t RESERVED3[759U]; + __IM uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER Register */ + __IM uint32_t FIFO0; /*!< Offset: 0xEEC (R/ ) Integration ETM Data */ + __IM uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/ ) ITATBCTR2 */ + uint32_t RESERVED4[1U]; + __IM uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) ITATBCTR0 */ + __IM uint32_t FIFO1; /*!< Offset: 0xEFC (R/ ) Integration ITM Data */ + __IOM uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */ + uint32_t RESERVED5[39U]; + __IOM uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */ + __IOM uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */ + uint32_t RESERVED7[8U]; + __IM uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) TPIU_DEVID */ + __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) TPIU_DEVTYPE */ +} TPI_Type; + +/* TPI Asynchronous Clock Prescaler Register Definitions */ +#define TPI_ACPR_PRESCALER_Pos 0U /*!< TPI ACPR: PRESCALER Position */ +#define TPI_ACPR_PRESCALER_Msk (0x1FFFUL /*<< TPI_ACPR_PRESCALER_Pos*/) /*!< TPI ACPR: PRESCALER Mask */ + +/* TPI Selected Pin Protocol Register Definitions */ +#define TPI_SPPR_TXMODE_Pos 0U /*!< TPI SPPR: TXMODE Position */ +#define TPI_SPPR_TXMODE_Msk (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/) /*!< TPI SPPR: TXMODE Mask */ + +/* TPI Formatter and Flush Status Register Definitions */ +#define TPI_FFSR_FtNonStop_Pos 3U /*!< TPI FFSR: FtNonStop Position */ +#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ + +#define TPI_FFSR_TCPresent_Pos 2U /*!< TPI FFSR: TCPresent Position */ +#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ + +#define TPI_FFSR_FtStopped_Pos 1U /*!< TPI FFSR: FtStopped Position */ +#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ + +#define TPI_FFSR_FlInProg_Pos 0U /*!< TPI FFSR: FlInProg Position */ +#define TPI_FFSR_FlInProg_Msk (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/) /*!< TPI FFSR: FlInProg Mask */ + +/* TPI Formatter and Flush Control Register Definitions */ +#define TPI_FFCR_TrigIn_Pos 8U /*!< TPI FFCR: TrigIn Position */ +#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ + +#define TPI_FFCR_EnFCont_Pos 1U /*!< TPI FFCR: EnFCont Position */ +#define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ + +/* TPI TRIGGER Register Definitions */ +#define TPI_TRIGGER_TRIGGER_Pos 0U /*!< TPI TRIGGER: TRIGGER Position */ +#define TPI_TRIGGER_TRIGGER_Msk (0x1UL /*<< TPI_TRIGGER_TRIGGER_Pos*/) /*!< TPI TRIGGER: TRIGGER Mask */ + +/* TPI Integration ETM Data Register Definitions (FIFO0) */ +#define TPI_FIFO0_ITM_ATVALID_Pos 29U /*!< TPI FIFO0: ITM_ATVALID Position */ +#define TPI_FIFO0_ITM_ATVALID_Msk (0x3UL << TPI_FIFO0_ITM_ATVALID_Pos) /*!< TPI FIFO0: ITM_ATVALID Mask */ + +#define TPI_FIFO0_ITM_bytecount_Pos 27U /*!< TPI FIFO0: ITM_bytecount Position */ +#define TPI_FIFO0_ITM_bytecount_Msk (0x3UL << TPI_FIFO0_ITM_bytecount_Pos) /*!< TPI FIFO0: ITM_bytecount Mask */ + +#define TPI_FIFO0_ETM_ATVALID_Pos 26U /*!< TPI FIFO0: ETM_ATVALID Position */ +#define TPI_FIFO0_ETM_ATVALID_Msk (0x3UL << TPI_FIFO0_ETM_ATVALID_Pos) /*!< TPI FIFO0: ETM_ATVALID Mask */ + +#define TPI_FIFO0_ETM_bytecount_Pos 24U /*!< TPI FIFO0: ETM_bytecount Position */ +#define TPI_FIFO0_ETM_bytecount_Msk (0x3UL << TPI_FIFO0_ETM_bytecount_Pos) /*!< TPI FIFO0: ETM_bytecount Mask */ + +#define TPI_FIFO0_ETM2_Pos 16U /*!< TPI FIFO0: ETM2 Position */ +#define TPI_FIFO0_ETM2_Msk (0xFFUL << TPI_FIFO0_ETM2_Pos) /*!< TPI FIFO0: ETM2 Mask */ + +#define TPI_FIFO0_ETM1_Pos 8U /*!< TPI FIFO0: ETM1 Position */ +#define TPI_FIFO0_ETM1_Msk (0xFFUL << TPI_FIFO0_ETM1_Pos) /*!< TPI FIFO0: ETM1 Mask */ + +#define TPI_FIFO0_ETM0_Pos 0U /*!< TPI FIFO0: ETM0 Position */ +#define TPI_FIFO0_ETM0_Msk (0xFFUL /*<< TPI_FIFO0_ETM0_Pos*/) /*!< TPI FIFO0: ETM0 Mask */ + +/* TPI ITATBCTR2 Register Definitions */ +#define TPI_ITATBCTR2_ATREADY2_Pos 0U /*!< TPI ITATBCTR2: ATREADY2 Position */ +#define TPI_ITATBCTR2_ATREADY2_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY2_Pos*/) /*!< TPI ITATBCTR2: ATREADY2 Mask */ + +#define TPI_ITATBCTR2_ATREADY1_Pos 0U /*!< TPI ITATBCTR2: ATREADY1 Position */ +#define TPI_ITATBCTR2_ATREADY1_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY1_Pos*/) /*!< TPI ITATBCTR2: ATREADY1 Mask */ + +/* TPI Integration ITM Data Register Definitions (FIFO1) */ +#define TPI_FIFO1_ITM_ATVALID_Pos 29U /*!< TPI FIFO1: ITM_ATVALID Position */ +#define TPI_FIFO1_ITM_ATVALID_Msk (0x3UL << TPI_FIFO1_ITM_ATVALID_Pos) /*!< TPI FIFO1: ITM_ATVALID Mask */ + +#define TPI_FIFO1_ITM_bytecount_Pos 27U /*!< TPI FIFO1: ITM_bytecount Position */ +#define TPI_FIFO1_ITM_bytecount_Msk (0x3UL << TPI_FIFO1_ITM_bytecount_Pos) /*!< TPI FIFO1: ITM_bytecount Mask */ + +#define TPI_FIFO1_ETM_ATVALID_Pos 26U /*!< TPI FIFO1: ETM_ATVALID Position */ +#define TPI_FIFO1_ETM_ATVALID_Msk (0x3UL << TPI_FIFO1_ETM_ATVALID_Pos) /*!< TPI FIFO1: ETM_ATVALID Mask */ + +#define TPI_FIFO1_ETM_bytecount_Pos 24U /*!< TPI FIFO1: ETM_bytecount Position */ +#define TPI_FIFO1_ETM_bytecount_Msk (0x3UL << TPI_FIFO1_ETM_bytecount_Pos) /*!< TPI FIFO1: ETM_bytecount Mask */ + +#define TPI_FIFO1_ITM2_Pos 16U /*!< TPI FIFO1: ITM2 Position */ +#define TPI_FIFO1_ITM2_Msk (0xFFUL << TPI_FIFO1_ITM2_Pos) /*!< TPI FIFO1: ITM2 Mask */ + +#define TPI_FIFO1_ITM1_Pos 8U /*!< TPI FIFO1: ITM1 Position */ +#define TPI_FIFO1_ITM1_Msk (0xFFUL << TPI_FIFO1_ITM1_Pos) /*!< TPI FIFO1: ITM1 Mask */ + +#define TPI_FIFO1_ITM0_Pos 0U /*!< TPI FIFO1: ITM0 Position */ +#define TPI_FIFO1_ITM0_Msk (0xFFUL /*<< TPI_FIFO1_ITM0_Pos*/) /*!< TPI FIFO1: ITM0 Mask */ + +/* TPI ITATBCTR0 Register Definitions */ +#define TPI_ITATBCTR0_ATREADY2_Pos 0U /*!< TPI ITATBCTR0: ATREADY2 Position */ +#define TPI_ITATBCTR0_ATREADY2_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY2_Pos*/) /*!< TPI ITATBCTR0: ATREADY2 Mask */ + +#define TPI_ITATBCTR0_ATREADY1_Pos 0U /*!< TPI ITATBCTR0: ATREADY1 Position */ +#define TPI_ITATBCTR0_ATREADY1_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY1_Pos*/) /*!< TPI ITATBCTR0: ATREADY1 Mask */ + +/* TPI Integration Mode Control Register Definitions */ +#define TPI_ITCTRL_Mode_Pos 0U /*!< TPI ITCTRL: Mode Position */ +#define TPI_ITCTRL_Mode_Msk (0x3UL /*<< TPI_ITCTRL_Mode_Pos*/) /*!< TPI ITCTRL: Mode Mask */ + +/* TPI DEVID Register Definitions */ +#define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */ +#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ + +#define TPI_DEVID_MANCVALID_Pos 10U /*!< TPI DEVID: MANCVALID Position */ +#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ + +#define TPI_DEVID_PTINVALID_Pos 9U /*!< TPI DEVID: PTINVALID Position */ +#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ + +#define TPI_DEVID_MinBufSz_Pos 6U /*!< TPI DEVID: MinBufSz Position */ +#define TPI_DEVID_MinBufSz_Msk (0x7UL << TPI_DEVID_MinBufSz_Pos) /*!< TPI DEVID: MinBufSz Mask */ + +#define TPI_DEVID_AsynClkIn_Pos 5U /*!< TPI DEVID: AsynClkIn Position */ +#define TPI_DEVID_AsynClkIn_Msk (0x1UL << TPI_DEVID_AsynClkIn_Pos) /*!< TPI DEVID: AsynClkIn Mask */ + +#define TPI_DEVID_NrTraceInput_Pos 0U /*!< TPI DEVID: NrTraceInput Position */ +#define TPI_DEVID_NrTraceInput_Msk (0x1FUL /*<< TPI_DEVID_NrTraceInput_Pos*/) /*!< TPI DEVID: NrTraceInput Mask */ + +/* TPI DEVTYPE Register Definitions */ +#define TPI_DEVTYPE_SubType_Pos 4U /*!< TPI DEVTYPE: SubType Position */ +#define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ + +#define TPI_DEVTYPE_MajorType_Pos 0U /*!< TPI DEVTYPE: MajorType Position */ +#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ + +/*@}*/ /* end of group CMSIS_TPI */ + + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** + \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IOM uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */ + __IOM uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Alias 1 Region Base Address Register */ + __IOM uint32_t RASR_A1; /*!< Offset: 0x018 (R/W) MPU Alias 1 Region Attribute and Size Register */ + __IOM uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Alias 2 Region Base Address Register */ + __IOM uint32_t RASR_A2; /*!< Offset: 0x020 (R/W) MPU Alias 2 Region Attribute and Size Register */ + __IOM uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Alias 3 Region Base Address Register */ + __IOM uint32_t RASR_A3; /*!< Offset: 0x028 (R/W) MPU Alias 3 Region Attribute and Size Register */ +} MPU_Type; + +/* MPU Type Register Definitions */ +#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register Definitions */ +#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register Definitions */ +#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register Definitions */ +#define MPU_RBAR_ADDR_Pos 5U /*!< MPU RBAR: ADDR Position */ +#define MPU_RBAR_ADDR_Msk (0x7FFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ + +#define MPU_RBAR_VALID_Pos 4U /*!< MPU RBAR: VALID Position */ +#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */ + +#define MPU_RBAR_REGION_Pos 0U /*!< MPU RBAR: REGION Position */ +#define MPU_RBAR_REGION_Msk (0xFUL /*<< MPU_RBAR_REGION_Pos*/) /*!< MPU RBAR: REGION Mask */ + +/* MPU Region Attribute and Size Register Definitions */ +#define MPU_RASR_ATTRS_Pos 16U /*!< MPU RASR: MPU Region Attribute field Position */ +#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */ + +#define MPU_RASR_XN_Pos 28U /*!< MPU RASR: ATTRS.XN Position */ +#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */ + +#define MPU_RASR_AP_Pos 24U /*!< MPU RASR: ATTRS.AP Position */ +#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */ + +#define MPU_RASR_TEX_Pos 19U /*!< MPU RASR: ATTRS.TEX Position */ +#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */ + +#define MPU_RASR_S_Pos 18U /*!< MPU RASR: ATTRS.S Position */ +#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */ + +#define MPU_RASR_C_Pos 17U /*!< MPU RASR: ATTRS.C Position */ +#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */ + +#define MPU_RASR_B_Pos 16U /*!< MPU RASR: ATTRS.B Position */ +#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */ + +#define MPU_RASR_SRD_Pos 8U /*!< MPU RASR: Sub-Region Disable Position */ +#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */ + +#define MPU_RASR_SIZE_Pos 1U /*!< MPU RASR: Region Size Field Position */ +#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */ + +#define MPU_RASR_ENABLE_Pos 0U /*!< MPU RASR: Region enable bit Position */ +#define MPU_RASR_ENABLE_Msk (1UL /*<< MPU_RASR_ENABLE_Pos*/) /*!< MPU RASR: Region enable bit Disable Mask */ + +/*@} end of group CMSIS_MPU */ +#endif + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Type definitions for the Core Debug Registers + @{ + */ + +/** + \brief Structure type to access the Core Debug Register (CoreDebug). + */ +typedef struct +{ + __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ +} CoreDebug_Type; + +/* Debug Halting Control and Status Register Definitions */ +#define CoreDebug_DHCSR_DBGKEY_Pos 16U /*!< CoreDebug DHCSR: DBGKEY Position */ +#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */ + +#define CoreDebug_DHCSR_S_RESET_ST_Pos 25U /*!< CoreDebug DHCSR: S_RESET_ST Position */ +#define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< CoreDebug DHCSR: S_RESET_ST Mask */ + +#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24U /*!< CoreDebug DHCSR: S_RETIRE_ST Position */ +#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */ + +#define CoreDebug_DHCSR_S_LOCKUP_Pos 19U /*!< CoreDebug DHCSR: S_LOCKUP Position */ +#define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< CoreDebug DHCSR: S_LOCKUP Mask */ + +#define CoreDebug_DHCSR_S_SLEEP_Pos 18U /*!< CoreDebug DHCSR: S_SLEEP Position */ +#define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< CoreDebug DHCSR: S_SLEEP Mask */ + +#define CoreDebug_DHCSR_S_HALT_Pos 17U /*!< CoreDebug DHCSR: S_HALT Position */ +#define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< CoreDebug DHCSR: S_HALT Mask */ + +#define CoreDebug_DHCSR_S_REGRDY_Pos 16U /*!< CoreDebug DHCSR: S_REGRDY Position */ +#define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< CoreDebug DHCSR: S_REGRDY Mask */ + +#define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5U /*!< CoreDebug DHCSR: C_SNAPSTALL Position */ +#define CoreDebug_DHCSR_C_SNAPSTALL_Msk (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos) /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */ + +#define CoreDebug_DHCSR_C_MASKINTS_Pos 3U /*!< CoreDebug DHCSR: C_MASKINTS Position */ +#define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< CoreDebug DHCSR: C_MASKINTS Mask */ + +#define CoreDebug_DHCSR_C_STEP_Pos 2U /*!< CoreDebug DHCSR: C_STEP Position */ +#define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< CoreDebug DHCSR: C_STEP Mask */ + +#define CoreDebug_DHCSR_C_HALT_Pos 1U /*!< CoreDebug DHCSR: C_HALT Position */ +#define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< CoreDebug DHCSR: C_HALT Mask */ + +#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0U /*!< CoreDebug DHCSR: C_DEBUGEN Position */ +#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */ + +/* Debug Core Register Selector Register Definitions */ +#define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< CoreDebug DCRSR: REGWnR Position */ +#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ + +#define CoreDebug_DCRSR_REGSEL_Pos 0U /*!< CoreDebug DCRSR: REGSEL Position */ +#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/) /*!< CoreDebug DCRSR: REGSEL Mask */ + +/* Debug Exception and Monitor Control Register Definitions */ +#define CoreDebug_DEMCR_TRCENA_Pos 24U /*!< CoreDebug DEMCR: TRCENA Position */ +#define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< CoreDebug DEMCR: TRCENA Mask */ + +#define CoreDebug_DEMCR_MON_REQ_Pos 19U /*!< CoreDebug DEMCR: MON_REQ Position */ +#define CoreDebug_DEMCR_MON_REQ_Msk (1UL << CoreDebug_DEMCR_MON_REQ_Pos) /*!< CoreDebug DEMCR: MON_REQ Mask */ + +#define CoreDebug_DEMCR_MON_STEP_Pos 18U /*!< CoreDebug DEMCR: MON_STEP Position */ +#define CoreDebug_DEMCR_MON_STEP_Msk (1UL << CoreDebug_DEMCR_MON_STEP_Pos) /*!< CoreDebug DEMCR: MON_STEP Mask */ + +#define CoreDebug_DEMCR_MON_PEND_Pos 17U /*!< CoreDebug DEMCR: MON_PEND Position */ +#define CoreDebug_DEMCR_MON_PEND_Msk (1UL << CoreDebug_DEMCR_MON_PEND_Pos) /*!< CoreDebug DEMCR: MON_PEND Mask */ + +#define CoreDebug_DEMCR_MON_EN_Pos 16U /*!< CoreDebug DEMCR: MON_EN Position */ +#define CoreDebug_DEMCR_MON_EN_Msk (1UL << CoreDebug_DEMCR_MON_EN_Pos) /*!< CoreDebug DEMCR: MON_EN Mask */ + +#define CoreDebug_DEMCR_VC_HARDERR_Pos 10U /*!< CoreDebug DEMCR: VC_HARDERR Position */ +#define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< CoreDebug DEMCR: VC_HARDERR Mask */ + +#define CoreDebug_DEMCR_VC_INTERR_Pos 9U /*!< CoreDebug DEMCR: VC_INTERR Position */ +#define CoreDebug_DEMCR_VC_INTERR_Msk (1UL << CoreDebug_DEMCR_VC_INTERR_Pos) /*!< CoreDebug DEMCR: VC_INTERR Mask */ + +#define CoreDebug_DEMCR_VC_BUSERR_Pos 8U /*!< CoreDebug DEMCR: VC_BUSERR Position */ +#define CoreDebug_DEMCR_VC_BUSERR_Msk (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos) /*!< CoreDebug DEMCR: VC_BUSERR Mask */ + +#define CoreDebug_DEMCR_VC_STATERR_Pos 7U /*!< CoreDebug DEMCR: VC_STATERR Position */ +#define CoreDebug_DEMCR_VC_STATERR_Msk (1UL << CoreDebug_DEMCR_VC_STATERR_Pos) /*!< CoreDebug DEMCR: VC_STATERR Mask */ + +#define CoreDebug_DEMCR_VC_CHKERR_Pos 6U /*!< CoreDebug DEMCR: VC_CHKERR Position */ +#define CoreDebug_DEMCR_VC_CHKERR_Msk (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos) /*!< CoreDebug DEMCR: VC_CHKERR Mask */ + +#define CoreDebug_DEMCR_VC_NOCPERR_Pos 5U /*!< CoreDebug DEMCR: VC_NOCPERR Position */ +#define CoreDebug_DEMCR_VC_NOCPERR_Msk (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos) /*!< CoreDebug DEMCR: VC_NOCPERR Mask */ + +#define CoreDebug_DEMCR_VC_MMERR_Pos 4U /*!< CoreDebug DEMCR: VC_MMERR Position */ +#define CoreDebug_DEMCR_VC_MMERR_Msk (1UL << CoreDebug_DEMCR_VC_MMERR_Pos) /*!< CoreDebug DEMCR: VC_MMERR Mask */ + +#define CoreDebug_DEMCR_VC_CORERESET_Pos 0U /*!< CoreDebug DEMCR: VC_CORERESET Position */ +#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/) /*!< CoreDebug DEMCR: VC_CORERESET Mask */ + +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param[in] field Name of the register bit field. + \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param[in] field Name of the register bit field. + \param[in] value Value of register. This parameter is interpreted as an uint32_t type. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) + +/*@} end of group CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Core Hardware */ +#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ +#define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ +#define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ +#define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ +#define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */ +#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ +#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ +#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + +#define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ +#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ +#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ +#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ +#define ITM ((ITM_Type *) ITM_BASE ) /*!< ITM configuration struct */ +#define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ +#define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ +#define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE) /*!< Core Debug configuration struct */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ +#endif + +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Debug Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping + #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping + #define NVIC_EnableIRQ __NVIC_EnableIRQ + #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ + #define NVIC_DisableIRQ __NVIC_DisableIRQ + #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ + #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ + #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ + #define NVIC_GetActive __NVIC_GetActive + #define NVIC_SetPriority __NVIC_SetPriority + #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset +#endif /* CMSIS_NVIC_VIRTUAL */ + +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetVector __NVIC_SetVector + #define NVIC_GetVector __NVIC_GetVector +#endif /* (CMSIS_VECTAB_VIRTUAL) */ + +#define NVIC_USER_IRQ_OFFSET 16 + + +/* The following EXC_RETURN values are saved the LR on exception entry */ +#define EXC_RETURN_HANDLER (0xFFFFFFF1UL) /* return to Handler mode, uses MSP after return */ +#define EXC_RETURN_THREAD_MSP (0xFFFFFFF9UL) /* return to Thread mode, uses MSP after return */ +#define EXC_RETURN_THREAD_PSP (0xFFFFFFFDUL) /* return to Thread mode, uses PSP after return */ + + + +/** + \brief Set Priority Grouping + \details Sets the priority grouping field using the required unlock sequence. + The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. + Only values from 0..7 are used. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Priority grouping field. + */ +__STATIC_INLINE void __NVIC_SetPriorityGrouping(uint32_t PriorityGroup) +{ + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + + reg_value = SCB->AIRCR; /* read old register configuration */ + reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << 8U) ); /* Insert write key and priorty group */ + SCB->AIRCR = reg_value; +} + + +/** + \brief Get Priority Grouping + \details Reads the priority grouping field from the NVIC Interrupt Controller. + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t __NVIC_GetPriorityGrouping(void) +{ + return ((uint32_t)((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); +} + + +/** + \brief Enable Interrupt + \details Enables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Interrupt Enable status + \details Returns a device specific interrupt enable status from the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt + \details Disables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __DSB(); + __ISB(); + } +} + + +/** + \brief Get Pending Interrupt + \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt + \details Reads the active register in the NVIC and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetActive(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Priority + \details Sets the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every processor exception. + */ +__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->IP[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } + else + { + SCB->SHP[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return(((uint32_t)NVIC->IP[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return(((uint32_t)SCB->SHP[(((uint32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief Encode Priority + \details Encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + return ( + ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | + ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) + ); +} + + +/** + \brief Decode Priority + \details Decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. + \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); + *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); +} + + +/** + \brief Set Interrupt Vector + \details Sets an interrupt vector in SRAM based interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + VTOR must been relocated to SRAM before. + \param [in] IRQn Interrupt number + \param [in] vector Address of interrupt handler function + */ +__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; +} + + +/** + \brief Get Interrupt Vector + \details Reads an interrupt vector from interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Address of interrupt handler function + */ +__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET]; +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + SCB_AIRCR_SYSRESETREQ_Msk ); /* Keep priority group unchanged */ + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +/*@} end of CMSIS_Core_NVICFunctions */ + + +/* ########################## FPU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_FpuFunctions FPU Functions + \brief Function that provides FPU type. + @{ + */ + +/** + \brief get FPU type + \details returns the FPU type + \returns + - \b 0: No FPU + - \b 1: Single precision FPU + - \b 2: Double + Single precision FPU + */ +__STATIC_INLINE uint32_t SCB_GetFPUType(void) +{ + return 0U; /* No FPU */ +} + + +/*@} end of CMSIS_Core_FpuFunctions */ + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + +/* ##################################### Debug In/Output function ########################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_core_DebugFunctions ITM Functions + \brief Functions that access the ITM debug interface. + @{ + */ + +extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */ +#define ITM_RXBUFFER_EMPTY ((int32_t)0x5AA55AA5U) /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */ + + +/** + \brief ITM Send Character + \details Transmits a character via the ITM channel 0, and + \li Just returns when no debugger is connected that has booked the output. + \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted. + \param [in] ch Character to transmit. + \returns Character to transmit. + */ +__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch) +{ + if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) && /* ITM enabled */ + ((ITM->TER & 1UL ) != 0UL) ) /* ITM Port #0 enabled */ + { + while (ITM->PORT[0U].u32 == 0UL) + { + __NOP(); + } + ITM->PORT[0U].u8 = (uint8_t)ch; + } + return (ch); +} + + +/** + \brief ITM Receive Character + \details Inputs a character via the external variable \ref ITM_RxBuffer. + \return Received character. + \return -1 No character pending. + */ +__STATIC_INLINE int32_t ITM_ReceiveChar (void) +{ + int32_t ch = -1; /* no character available */ + + if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) + { + ch = ITM_RxBuffer; + ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */ + } + + return (ch); +} + + +/** + \brief ITM Check Character + \details Checks whether a character is pending for reading in the variable \ref ITM_RxBuffer. + \return 0 No character available. + \return 1 Character available. + */ +__STATIC_INLINE int32_t ITM_CheckChar (void) +{ + + if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) + { + return (0); /* no character available */ + } + else + { + return (1); /* character available */ + } +} + +/*@} end of CMSIS_core_DebugFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_SC300_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/test/STM32F072C8T6/Drivers/CMSIS/Include/mpu_armv7.h b/test/STM32F072C8T6/Drivers/CMSIS/Include/mpu_armv7.h new file mode 100644 index 0000000..7d4b600 --- /dev/null +++ b/test/STM32F072C8T6/Drivers/CMSIS/Include/mpu_armv7.h @@ -0,0 +1,270 @@ +/****************************************************************************** + * @file mpu_armv7.h + * @brief CMSIS MPU API for Armv7-M MPU + * @version V5.0.4 + * @date 10. January 2018 + ******************************************************************************/ +/* + * Copyright (c) 2017-2018 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * 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 + * + * 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. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef ARM_MPU_ARMV7_H +#define ARM_MPU_ARMV7_H + +#define ARM_MPU_REGION_SIZE_32B ((uint8_t)0x04U) ///!< MPU Region Size 32 Bytes +#define ARM_MPU_REGION_SIZE_64B ((uint8_t)0x05U) ///!< MPU Region Size 64 Bytes +#define ARM_MPU_REGION_SIZE_128B ((uint8_t)0x06U) ///!< MPU Region Size 128 Bytes +#define ARM_MPU_REGION_SIZE_256B ((uint8_t)0x07U) ///!< MPU Region Size 256 Bytes +#define ARM_MPU_REGION_SIZE_512B ((uint8_t)0x08U) ///!< MPU Region Size 512 Bytes +#define ARM_MPU_REGION_SIZE_1KB ((uint8_t)0x09U) ///!< MPU Region Size 1 KByte +#define ARM_MPU_REGION_SIZE_2KB ((uint8_t)0x0AU) ///!< MPU Region Size 2 KBytes +#define ARM_MPU_REGION_SIZE_4KB ((uint8_t)0x0BU) ///!< MPU Region Size 4 KBytes +#define ARM_MPU_REGION_SIZE_8KB ((uint8_t)0x0CU) ///!< MPU Region Size 8 KBytes +#define ARM_MPU_REGION_SIZE_16KB ((uint8_t)0x0DU) ///!< MPU Region Size 16 KBytes +#define ARM_MPU_REGION_SIZE_32KB ((uint8_t)0x0EU) ///!< MPU Region Size 32 KBytes +#define ARM_MPU_REGION_SIZE_64KB ((uint8_t)0x0FU) ///!< MPU Region Size 64 KBytes +#define ARM_MPU_REGION_SIZE_128KB ((uint8_t)0x10U) ///!< MPU Region Size 128 KBytes +#define ARM_MPU_REGION_SIZE_256KB ((uint8_t)0x11U) ///!< MPU Region Size 256 KBytes +#define ARM_MPU_REGION_SIZE_512KB ((uint8_t)0x12U) ///!< MPU Region Size 512 KBytes +#define ARM_MPU_REGION_SIZE_1MB ((uint8_t)0x13U) ///!< MPU Region Size 1 MByte +#define ARM_MPU_REGION_SIZE_2MB ((uint8_t)0x14U) ///!< MPU Region Size 2 MBytes +#define ARM_MPU_REGION_SIZE_4MB ((uint8_t)0x15U) ///!< MPU Region Size 4 MBytes +#define ARM_MPU_REGION_SIZE_8MB ((uint8_t)0x16U) ///!< MPU Region Size 8 MBytes +#define ARM_MPU_REGION_SIZE_16MB ((uint8_t)0x17U) ///!< MPU Region Size 16 MBytes +#define ARM_MPU_REGION_SIZE_32MB ((uint8_t)0x18U) ///!< MPU Region Size 32 MBytes +#define ARM_MPU_REGION_SIZE_64MB ((uint8_t)0x19U) ///!< MPU Region Size 64 MBytes +#define ARM_MPU_REGION_SIZE_128MB ((uint8_t)0x1AU) ///!< MPU Region Size 128 MBytes +#define ARM_MPU_REGION_SIZE_256MB ((uint8_t)0x1BU) ///!< MPU Region Size 256 MBytes +#define ARM_MPU_REGION_SIZE_512MB ((uint8_t)0x1CU) ///!< MPU Region Size 512 MBytes +#define ARM_MPU_REGION_SIZE_1GB ((uint8_t)0x1DU) ///!< MPU Region Size 1 GByte +#define ARM_MPU_REGION_SIZE_2GB ((uint8_t)0x1EU) ///!< MPU Region Size 2 GBytes +#define ARM_MPU_REGION_SIZE_4GB ((uint8_t)0x1FU) ///!< MPU Region Size 4 GBytes + +#define ARM_MPU_AP_NONE 0U ///!< MPU Access Permission no access +#define ARM_MPU_AP_PRIV 1U ///!< MPU Access Permission privileged access only +#define ARM_MPU_AP_URO 2U ///!< MPU Access Permission unprivileged access read-only +#define ARM_MPU_AP_FULL 3U ///!< MPU Access Permission full access +#define ARM_MPU_AP_PRO 5U ///!< MPU Access Permission privileged access read-only +#define ARM_MPU_AP_RO 6U ///!< MPU Access Permission read-only access + +/** MPU Region Base Address Register Value +* +* \param Region The region to be configured, number 0 to 15. +* \param BaseAddress The base address for the region. +*/ +#define ARM_MPU_RBAR(Region, BaseAddress) \ + (((BaseAddress) & MPU_RBAR_ADDR_Msk) | \ + ((Region) & MPU_RBAR_REGION_Msk) | \ + (MPU_RBAR_VALID_Msk)) + +/** +* MPU Memory Access Attributes +* +* \param TypeExtField Type extension field, allows you to configure memory access type, for example strongly ordered, peripheral. +* \param IsShareable Region is shareable between multiple bus masters. +* \param IsCacheable Region is cacheable, i.e. its value may be kept in cache. +* \param IsBufferable Region is bufferable, i.e. using write-back caching. Cacheable but non-bufferable regions use write-through policy. +*/ +#define ARM_MPU_ACCESS_(TypeExtField, IsShareable, IsCacheable, IsBufferable) \ + ((((TypeExtField ) << MPU_RASR_TEX_Pos) & MPU_RASR_TEX_Msk) | \ + (((IsShareable ) << MPU_RASR_S_Pos) & MPU_RASR_S_Msk) | \ + (((IsCacheable ) << MPU_RASR_C_Pos) & MPU_RASR_C_Msk) | \ + (((IsBufferable ) << MPU_RASR_B_Pos) & MPU_RASR_B_Msk)) + +/** +* MPU Region Attribute and Size Register Value +* +* \param DisableExec Instruction access disable bit, 1= disable instruction fetches. +* \param AccessPermission Data access permissions, allows you to configure read/write access for User and Privileged mode. +* \param AccessAttributes Memory access attribution, see \ref ARM_MPU_ACCESS_. +* \param SubRegionDisable Sub-region disable field. +* \param Size Region size of the region to be configured, for example 4K, 8K. +*/ +#define ARM_MPU_RASR_EX(DisableExec, AccessPermission, AccessAttributes, SubRegionDisable, Size) \ + ((((DisableExec ) << MPU_RASR_XN_Pos) & MPU_RASR_XN_Msk) | \ + (((AccessPermission) << MPU_RASR_AP_Pos) & MPU_RASR_AP_Msk) | \ + (((AccessAttributes) ) & (MPU_RASR_TEX_Msk | MPU_RASR_S_Msk | MPU_RASR_C_Msk | MPU_RASR_B_Msk))) + +/** +* MPU Region Attribute and Size Register Value +* +* \param DisableExec Instruction access disable bit, 1= disable instruction fetches. +* \param AccessPermission Data access permissions, allows you to configure read/write access for User and Privileged mode. +* \param TypeExtField Type extension field, allows you to configure memory access type, for example strongly ordered, peripheral. +* \param IsShareable Region is shareable between multiple bus masters. +* \param IsCacheable Region is cacheable, i.e. its value may be kept in cache. +* \param IsBufferable Region is bufferable, i.e. using write-back caching. Cacheable but non-bufferable regions use write-through policy. +* \param SubRegionDisable Sub-region disable field. +* \param Size Region size of the region to be configured, for example 4K, 8K. +*/ +#define ARM_MPU_RASR(DisableExec, AccessPermission, TypeExtField, IsShareable, IsCacheable, IsBufferable, SubRegionDisable, Size) \ + ARM_MPU_RASR_EX(DisableExec, AccessPermission, ARM_MPU_ACCESS_(TypeExtField, IsShareable, IsCacheable, IsBufferable), SubRegionDisable, Size) + +/** +* MPU Memory Access Attribute for strongly ordered memory. +* - TEX: 000b +* - Shareable +* - Non-cacheable +* - Non-bufferable +*/ +#define ARM_MPU_ACCESS_ORDERED ARM_MPU_ACCESS_(0U, 1U, 0U, 0U) + +/** +* MPU Memory Access Attribute for device memory. +* - TEX: 000b (if non-shareable) or 010b (if shareable) +* - Shareable or non-shareable +* - Non-cacheable +* - Bufferable (if shareable) or non-bufferable (if non-shareable) +* +* \param IsShareable Configures the device memory as shareable or non-shareable. +*/ +#define ARM_MPU_ACCESS_DEVICE(IsShareable) ((IsShareable) ? ARM_MPU_ACCESS_(0U, 1U, 0U, 1U) : ARM_MPU_ACCESS_(2U, 0U, 0U, 0U)) + +/** +* MPU Memory Access Attribute for normal memory. +* - TEX: 1BBb (reflecting outer cacheability rules) +* - Shareable or non-shareable +* - Cacheable or non-cacheable (reflecting inner cacheability rules) +* - Bufferable or non-bufferable (reflecting inner cacheability rules) +* +* \param OuterCp Configures the outer cache policy. +* \param InnerCp Configures the inner cache policy. +* \param IsShareable Configures the memory as shareable or non-shareable. +*/ +#define ARM_MPU_ACCESS_NORMAL(OuterCp, InnerCp, IsShareable) ARM_MPU_ACCESS_((4U | (OuterCp)), IsShareable, ((InnerCp) & 2U), ((InnerCp) & 1U)) + +/** +* MPU Memory Access Attribute non-cacheable policy. +*/ +#define ARM_MPU_CACHEP_NOCACHE 0U + +/** +* MPU Memory Access Attribute write-back, write and read allocate policy. +*/ +#define ARM_MPU_CACHEP_WB_WRA 1U + +/** +* MPU Memory Access Attribute write-through, no write allocate policy. +*/ +#define ARM_MPU_CACHEP_WT_NWA 2U + +/** +* MPU Memory Access Attribute write-back, no write allocate policy. +*/ +#define ARM_MPU_CACHEP_WB_NWA 3U + + +/** +* Struct for a single MPU Region +*/ +typedef struct { + uint32_t RBAR; //!< The region base address register value (RBAR) + uint32_t RASR; //!< The region attribute and size register value (RASR) \ref MPU_RASR +} ARM_MPU_Region_t; + +/** Enable the MPU. +* \param MPU_Control Default access permissions for unconfigured regions. +*/ +__STATIC_INLINE void ARM_MPU_Enable(uint32_t MPU_Control) +{ + __DSB(); + __ISB(); + MPU->CTRL = MPU_Control | MPU_CTRL_ENABLE_Msk; +#ifdef SCB_SHCSR_MEMFAULTENA_Msk + SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; +#endif +} + +/** Disable the MPU. +*/ +__STATIC_INLINE void ARM_MPU_Disable(void) +{ + __DSB(); + __ISB(); +#ifdef SCB_SHCSR_MEMFAULTENA_Msk + SCB->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk; +#endif + MPU->CTRL &= ~MPU_CTRL_ENABLE_Msk; +} + +/** Clear and disable the given MPU region. +* \param rnr Region number to be cleared. +*/ +__STATIC_INLINE void ARM_MPU_ClrRegion(uint32_t rnr) +{ + MPU->RNR = rnr; + MPU->RASR = 0U; +} + +/** Configure an MPU region. +* \param rbar Value for RBAR register. +* \param rsar Value for RSAR register. +*/ +__STATIC_INLINE void ARM_MPU_SetRegion(uint32_t rbar, uint32_t rasr) +{ + MPU->RBAR = rbar; + MPU->RASR = rasr; +} + +/** Configure the given MPU region. +* \param rnr Region number to be configured. +* \param rbar Value for RBAR register. +* \param rsar Value for RSAR register. +*/ +__STATIC_INLINE void ARM_MPU_SetRegionEx(uint32_t rnr, uint32_t rbar, uint32_t rasr) +{ + MPU->RNR = rnr; + MPU->RBAR = rbar; + MPU->RASR = rasr; +} + +/** Memcopy with strictly ordered memory access, e.g. for register targets. +* \param dst Destination data is copied to. +* \param src Source data is copied from. +* \param len Amount of data words to be copied. +*/ +__STATIC_INLINE void orderedCpy(volatile uint32_t* dst, const uint32_t* __RESTRICT src, uint32_t len) +{ + uint32_t i; + for (i = 0U; i < len; ++i) + { + dst[i] = src[i]; + } +} + +/** Load the given number of MPU regions from a table. +* \param table Pointer to the MPU configuration table. +* \param cnt Amount of regions to be configured. +*/ +__STATIC_INLINE void ARM_MPU_Load(ARM_MPU_Region_t const* table, uint32_t cnt) +{ + const uint32_t rowWordSize = sizeof(ARM_MPU_Region_t)/4U; + while (cnt > MPU_TYPE_RALIASES) { + orderedCpy(&(MPU->RBAR), &(table->RBAR), MPU_TYPE_RALIASES*rowWordSize); + table += MPU_TYPE_RALIASES; + cnt -= MPU_TYPE_RALIASES; + } + orderedCpy(&(MPU->RBAR), &(table->RBAR), cnt*rowWordSize); +} + +#endif diff --git a/test/STM32F072C8T6/Drivers/CMSIS/Include/mpu_armv8.h b/test/STM32F072C8T6/Drivers/CMSIS/Include/mpu_armv8.h new file mode 100644 index 0000000..99ee9f9 --- /dev/null +++ b/test/STM32F072C8T6/Drivers/CMSIS/Include/mpu_armv8.h @@ -0,0 +1,333 @@ +/****************************************************************************** + * @file mpu_armv8.h + * @brief CMSIS MPU API for Armv8-M MPU + * @version V5.0.4 + * @date 10. January 2018 + ******************************************************************************/ +/* + * Copyright (c) 2017-2018 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * 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 + * + * 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. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef ARM_MPU_ARMV8_H +#define ARM_MPU_ARMV8_H + +/** \brief Attribute for device memory (outer only) */ +#define ARM_MPU_ATTR_DEVICE ( 0U ) + +/** \brief Attribute for non-cacheable, normal memory */ +#define ARM_MPU_ATTR_NON_CACHEABLE ( 4U ) + +/** \brief Attribute for normal memory (outer and inner) +* \param NT Non-Transient: Set to 1 for non-transient data. +* \param WB Write-Back: Set to 1 to use write-back update policy. +* \param RA Read Allocation: Set to 1 to use cache allocation on read miss. +* \param WA Write Allocation: Set to 1 to use cache allocation on write miss. +*/ +#define ARM_MPU_ATTR_MEMORY_(NT, WB, RA, WA) \ + (((NT & 1U) << 3U) | ((WB & 1U) << 2U) | ((RA & 1U) << 1U) | (WA & 1U)) + +/** \brief Device memory type non Gathering, non Re-ordering, non Early Write Acknowledgement */ +#define ARM_MPU_ATTR_DEVICE_nGnRnE (0U) + +/** \brief Device memory type non Gathering, non Re-ordering, Early Write Acknowledgement */ +#define ARM_MPU_ATTR_DEVICE_nGnRE (1U) + +/** \brief Device memory type non Gathering, Re-ordering, Early Write Acknowledgement */ +#define ARM_MPU_ATTR_DEVICE_nGRE (2U) + +/** \brief Device memory type Gathering, Re-ordering, Early Write Acknowledgement */ +#define ARM_MPU_ATTR_DEVICE_GRE (3U) + +/** \brief Memory Attribute +* \param O Outer memory attributes +* \param I O == ARM_MPU_ATTR_DEVICE: Device memory attributes, else: Inner memory attributes +*/ +#define ARM_MPU_ATTR(O, I) (((O & 0xFU) << 4U) | (((O & 0xFU) != 0U) ? (I & 0xFU) : ((I & 0x3U) << 2U))) + +/** \brief Normal memory non-shareable */ +#define ARM_MPU_SH_NON (0U) + +/** \brief Normal memory outer shareable */ +#define ARM_MPU_SH_OUTER (2U) + +/** \brief Normal memory inner shareable */ +#define ARM_MPU_SH_INNER (3U) + +/** \brief Memory access permissions +* \param RO Read-Only: Set to 1 for read-only memory. +* \param NP Non-Privileged: Set to 1 for non-privileged memory. +*/ +#define ARM_MPU_AP_(RO, NP) (((RO & 1U) << 1U) | (NP & 1U)) + +/** \brief Region Base Address Register value +* \param BASE The base address bits [31:5] of a memory region. The value is zero extended. Effective address gets 32 byte aligned. +* \param SH Defines the Shareability domain for this memory region. +* \param RO Read-Only: Set to 1 for a read-only memory region. +* \param NP Non-Privileged: Set to 1 for a non-privileged memory region. +* \oaram XN eXecute Never: Set to 1 for a non-executable memory region. +*/ +#define ARM_MPU_RBAR(BASE, SH, RO, NP, XN) \ + ((BASE & MPU_RBAR_BASE_Msk) | \ + ((SH << MPU_RBAR_SH_Pos) & MPU_RBAR_SH_Msk) | \ + ((ARM_MPU_AP_(RO, NP) << MPU_RBAR_AP_Pos) & MPU_RBAR_AP_Msk) | \ + ((XN << MPU_RBAR_XN_Pos) & MPU_RBAR_XN_Msk)) + +/** \brief Region Limit Address Register value +* \param LIMIT The limit address bits [31:5] for this memory region. The value is one extended. +* \param IDX The attribute index to be associated with this memory region. +*/ +#define ARM_MPU_RLAR(LIMIT, IDX) \ + ((LIMIT & MPU_RLAR_LIMIT_Msk) | \ + ((IDX << MPU_RLAR_AttrIndx_Pos) & MPU_RLAR_AttrIndx_Msk) | \ + (MPU_RLAR_EN_Msk)) + +/** +* Struct for a single MPU Region +*/ +typedef struct { + uint32_t RBAR; /*!< Region Base Address Register value */ + uint32_t RLAR; /*!< Region Limit Address Register value */ +} ARM_MPU_Region_t; + +/** Enable the MPU. +* \param MPU_Control Default access permissions for unconfigured regions. +*/ +__STATIC_INLINE void ARM_MPU_Enable(uint32_t MPU_Control) +{ + __DSB(); + __ISB(); + MPU->CTRL = MPU_Control | MPU_CTRL_ENABLE_Msk; +#ifdef SCB_SHCSR_MEMFAULTENA_Msk + SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; +#endif +} + +/** Disable the MPU. +*/ +__STATIC_INLINE void ARM_MPU_Disable(void) +{ + __DSB(); + __ISB(); +#ifdef SCB_SHCSR_MEMFAULTENA_Msk + SCB->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk; +#endif + MPU->CTRL &= ~MPU_CTRL_ENABLE_Msk; +} + +#ifdef MPU_NS +/** Enable the Non-secure MPU. +* \param MPU_Control Default access permissions for unconfigured regions. +*/ +__STATIC_INLINE void ARM_MPU_Enable_NS(uint32_t MPU_Control) +{ + __DSB(); + __ISB(); + MPU_NS->CTRL = MPU_Control | MPU_CTRL_ENABLE_Msk; +#ifdef SCB_SHCSR_MEMFAULTENA_Msk + SCB_NS->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; +#endif +} + +/** Disable the Non-secure MPU. +*/ +__STATIC_INLINE void ARM_MPU_Disable_NS(void) +{ + __DSB(); + __ISB(); +#ifdef SCB_SHCSR_MEMFAULTENA_Msk + SCB_NS->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk; +#endif + MPU_NS->CTRL &= ~MPU_CTRL_ENABLE_Msk; +} +#endif + +/** Set the memory attribute encoding to the given MPU. +* \param mpu Pointer to the MPU to be configured. +* \param idx The attribute index to be set [0-7] +* \param attr The attribute value to be set. +*/ +__STATIC_INLINE void ARM_MPU_SetMemAttrEx(MPU_Type* mpu, uint8_t idx, uint8_t attr) +{ + const uint8_t reg = idx / 4U; + const uint32_t pos = ((idx % 4U) * 8U); + const uint32_t mask = 0xFFU << pos; + + if (reg >= (sizeof(mpu->MAIR) / sizeof(mpu->MAIR[0]))) { + return; // invalid index + } + + mpu->MAIR[reg] = ((mpu->MAIR[reg] & ~mask) | ((attr << pos) & mask)); +} + +/** Set the memory attribute encoding. +* \param idx The attribute index to be set [0-7] +* \param attr The attribute value to be set. +*/ +__STATIC_INLINE void ARM_MPU_SetMemAttr(uint8_t idx, uint8_t attr) +{ + ARM_MPU_SetMemAttrEx(MPU, idx, attr); +} + +#ifdef MPU_NS +/** Set the memory attribute encoding to the Non-secure MPU. +* \param idx The attribute index to be set [0-7] +* \param attr The attribute value to be set. +*/ +__STATIC_INLINE void ARM_MPU_SetMemAttr_NS(uint8_t idx, uint8_t attr) +{ + ARM_MPU_SetMemAttrEx(MPU_NS, idx, attr); +} +#endif + +/** Clear and disable the given MPU region of the given MPU. +* \param mpu Pointer to MPU to be used. +* \param rnr Region number to be cleared. +*/ +__STATIC_INLINE void ARM_MPU_ClrRegionEx(MPU_Type* mpu, uint32_t rnr) +{ + mpu->RNR = rnr; + mpu->RLAR = 0U; +} + +/** Clear and disable the given MPU region. +* \param rnr Region number to be cleared. +*/ +__STATIC_INLINE void ARM_MPU_ClrRegion(uint32_t rnr) +{ + ARM_MPU_ClrRegionEx(MPU, rnr); +} + +#ifdef MPU_NS +/** Clear and disable the given Non-secure MPU region. +* \param rnr Region number to be cleared. +*/ +__STATIC_INLINE void ARM_MPU_ClrRegion_NS(uint32_t rnr) +{ + ARM_MPU_ClrRegionEx(MPU_NS, rnr); +} +#endif + +/** Configure the given MPU region of the given MPU. +* \param mpu Pointer to MPU to be used. +* \param rnr Region number to be configured. +* \param rbar Value for RBAR register. +* \param rlar Value for RLAR register. +*/ +__STATIC_INLINE void ARM_MPU_SetRegionEx(MPU_Type* mpu, uint32_t rnr, uint32_t rbar, uint32_t rlar) +{ + mpu->RNR = rnr; + mpu->RBAR = rbar; + mpu->RLAR = rlar; +} + +/** Configure the given MPU region. +* \param rnr Region number to be configured. +* \param rbar Value for RBAR register. +* \param rlar Value for RLAR register. +*/ +__STATIC_INLINE void ARM_MPU_SetRegion(uint32_t rnr, uint32_t rbar, uint32_t rlar) +{ + ARM_MPU_SetRegionEx(MPU, rnr, rbar, rlar); +} + +#ifdef MPU_NS +/** Configure the given Non-secure MPU region. +* \param rnr Region number to be configured. +* \param rbar Value for RBAR register. +* \param rlar Value for RLAR register. +*/ +__STATIC_INLINE void ARM_MPU_SetRegion_NS(uint32_t rnr, uint32_t rbar, uint32_t rlar) +{ + ARM_MPU_SetRegionEx(MPU_NS, rnr, rbar, rlar); +} +#endif + +/** Memcopy with strictly ordered memory access, e.g. for register targets. +* \param dst Destination data is copied to. +* \param src Source data is copied from. +* \param len Amount of data words to be copied. +*/ +__STATIC_INLINE void orderedCpy(volatile uint32_t* dst, const uint32_t* __RESTRICT src, uint32_t len) +{ + uint32_t i; + for (i = 0U; i < len; ++i) + { + dst[i] = src[i]; + } +} + +/** Load the given number of MPU regions from a table to the given MPU. +* \param mpu Pointer to the MPU registers to be used. +* \param rnr First region number to be configured. +* \param table Pointer to the MPU configuration table. +* \param cnt Amount of regions to be configured. +*/ +__STATIC_INLINE void ARM_MPU_LoadEx(MPU_Type* mpu, uint32_t rnr, ARM_MPU_Region_t const* table, uint32_t cnt) +{ + const uint32_t rowWordSize = sizeof(ARM_MPU_Region_t)/4U; + if (cnt == 1U) { + mpu->RNR = rnr; + orderedCpy(&(mpu->RBAR), &(table->RBAR), rowWordSize); + } else { + uint32_t rnrBase = rnr & ~(MPU_TYPE_RALIASES-1U); + uint32_t rnrOffset = rnr % MPU_TYPE_RALIASES; + + mpu->RNR = rnrBase; + while ((rnrOffset + cnt) > MPU_TYPE_RALIASES) { + uint32_t c = MPU_TYPE_RALIASES - rnrOffset; + orderedCpy(&(mpu->RBAR)+(rnrOffset*2U), &(table->RBAR), c*rowWordSize); + table += c; + cnt -= c; + rnrOffset = 0U; + rnrBase += MPU_TYPE_RALIASES; + mpu->RNR = rnrBase; + } + + orderedCpy(&(mpu->RBAR)+(rnrOffset*2U), &(table->RBAR), cnt*rowWordSize); + } +} + +/** Load the given number of MPU regions from a table. +* \param rnr First region number to be configured. +* \param table Pointer to the MPU configuration table. +* \param cnt Amount of regions to be configured. +*/ +__STATIC_INLINE void ARM_MPU_Load(uint32_t rnr, ARM_MPU_Region_t const* table, uint32_t cnt) +{ + ARM_MPU_LoadEx(MPU, rnr, table, cnt); +} + +#ifdef MPU_NS +/** Load the given number of MPU regions from a table to the Non-secure MPU. +* \param rnr First region number to be configured. +* \param table Pointer to the MPU configuration table. +* \param cnt Amount of regions to be configured. +*/ +__STATIC_INLINE void ARM_MPU_Load_NS(uint32_t rnr, ARM_MPU_Region_t const* table, uint32_t cnt) +{ + ARM_MPU_LoadEx(MPU_NS, rnr, table, cnt); +} +#endif + +#endif + diff --git a/test/STM32F072C8T6/Drivers/CMSIS/Include/tz_context.h b/test/STM32F072C8T6/Drivers/CMSIS/Include/tz_context.h new file mode 100644 index 0000000..d4c1474 --- /dev/null +++ b/test/STM32F072C8T6/Drivers/CMSIS/Include/tz_context.h @@ -0,0 +1,70 @@ +/****************************************************************************** + * @file tz_context.h + * @brief Context Management for Armv8-M TrustZone + * @version V1.0.1 + * @date 10. January 2018 + ******************************************************************************/ +/* + * Copyright (c) 2017-2018 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * 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 + * + * 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. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef TZ_CONTEXT_H +#define TZ_CONTEXT_H + +#include + +#ifndef TZ_MODULEID_T +#define TZ_MODULEID_T +/// \details Data type that identifies secure software modules called by a process. +typedef uint32_t TZ_ModuleId_t; +#endif + +/// \details TZ Memory ID identifies an allocated memory slot. +typedef uint32_t TZ_MemoryId_t; + +/// Initialize secure context memory system +/// \return execution status (1: success, 0: error) +uint32_t TZ_InitContextSystem_S (void); + +/// Allocate context memory for calling secure software modules in TrustZone +/// \param[in] module identifies software modules called from non-secure mode +/// \return value != 0 id TrustZone memory slot identifier +/// \return value 0 no memory available or internal error +TZ_MemoryId_t TZ_AllocModuleContext_S (TZ_ModuleId_t module); + +/// Free context memory that was previously allocated with \ref TZ_AllocModuleContext_S +/// \param[in] id TrustZone memory slot identifier +/// \return execution status (1: success, 0: error) +uint32_t TZ_FreeModuleContext_S (TZ_MemoryId_t id); + +/// Load secure context (called on RTOS thread context switch) +/// \param[in] id TrustZone memory slot identifier +/// \return execution status (1: success, 0: error) +uint32_t TZ_LoadContext_S (TZ_MemoryId_t id); + +/// Store secure context (called on RTOS thread context switch) +/// \param[in] id TrustZone memory slot identifier +/// \return execution status (1: success, 0: error) +uint32_t TZ_StoreContext_S (TZ_MemoryId_t id); + +#endif // TZ_CONTEXT_H diff --git a/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Inc/Legacy/stm32_hal_legacy.h b/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Inc/Legacy/stm32_hal_legacy.h new file mode 100644 index 0000000..2c80bc5 --- /dev/null +++ b/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Inc/Legacy/stm32_hal_legacy.h @@ -0,0 +1,3649 @@ +/** + ****************************************************************************** + * @file stm32_hal_legacy.h + * @author MCD Application Team + * @brief This file contains aliases definition for the STM32Cube HAL constants + * macros and functions maintained for legacy purpose. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2019 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32_HAL_LEGACY +#define STM32_HAL_LEGACY + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup HAL_AES_Aliased_Defines HAL CRYP Aliased Defines maintained for legacy purpose + * @{ + */ +#define AES_FLAG_RDERR CRYP_FLAG_RDERR +#define AES_FLAG_WRERR CRYP_FLAG_WRERR +#define AES_CLEARFLAG_CCF CRYP_CLEARFLAG_CCF +#define AES_CLEARFLAG_RDERR CRYP_CLEARFLAG_RDERR +#define AES_CLEARFLAG_WRERR CRYP_CLEARFLAG_WRERR + +/** + * @} + */ + +/** @defgroup HAL_ADC_Aliased_Defines HAL ADC Aliased Defines maintained for legacy purpose + * @{ + */ +#define ADC_RESOLUTION12b ADC_RESOLUTION_12B +#define ADC_RESOLUTION10b ADC_RESOLUTION_10B +#define ADC_RESOLUTION8b ADC_RESOLUTION_8B +#define ADC_RESOLUTION6b ADC_RESOLUTION_6B +#define OVR_DATA_OVERWRITTEN ADC_OVR_DATA_OVERWRITTEN +#define OVR_DATA_PRESERVED ADC_OVR_DATA_PRESERVED +#define EOC_SINGLE_CONV ADC_EOC_SINGLE_CONV +#define EOC_SEQ_CONV ADC_EOC_SEQ_CONV +#define EOC_SINGLE_SEQ_CONV ADC_EOC_SINGLE_SEQ_CONV +#define REGULAR_GROUP ADC_REGULAR_GROUP +#define INJECTED_GROUP ADC_INJECTED_GROUP +#define REGULAR_INJECTED_GROUP ADC_REGULAR_INJECTED_GROUP +#define AWD_EVENT ADC_AWD_EVENT +#define AWD1_EVENT ADC_AWD1_EVENT +#define AWD2_EVENT ADC_AWD2_EVENT +#define AWD3_EVENT ADC_AWD3_EVENT +#define OVR_EVENT ADC_OVR_EVENT +#define JQOVF_EVENT ADC_JQOVF_EVENT +#define ALL_CHANNELS ADC_ALL_CHANNELS +#define REGULAR_CHANNELS ADC_REGULAR_CHANNELS +#define INJECTED_CHANNELS ADC_INJECTED_CHANNELS +#define SYSCFG_FLAG_SENSOR_ADC ADC_FLAG_SENSOR +#define SYSCFG_FLAG_VREF_ADC ADC_FLAG_VREFINT +#define ADC_CLOCKPRESCALER_PCLK_DIV1 ADC_CLOCK_SYNC_PCLK_DIV1 +#define ADC_CLOCKPRESCALER_PCLK_DIV2 ADC_CLOCK_SYNC_PCLK_DIV2 +#define ADC_CLOCKPRESCALER_PCLK_DIV4 ADC_CLOCK_SYNC_PCLK_DIV4 +#define ADC_CLOCKPRESCALER_PCLK_DIV6 ADC_CLOCK_SYNC_PCLK_DIV6 +#define ADC_CLOCKPRESCALER_PCLK_DIV8 ADC_CLOCK_SYNC_PCLK_DIV8 +#define ADC_EXTERNALTRIG0_T6_TRGO ADC_EXTERNALTRIGCONV_T6_TRGO +#define ADC_EXTERNALTRIG1_T21_CC2 ADC_EXTERNALTRIGCONV_T21_CC2 +#define ADC_EXTERNALTRIG2_T2_TRGO ADC_EXTERNALTRIGCONV_T2_TRGO +#define ADC_EXTERNALTRIG3_T2_CC4 ADC_EXTERNALTRIGCONV_T2_CC4 +#define ADC_EXTERNALTRIG4_T22_TRGO ADC_EXTERNALTRIGCONV_T22_TRGO +#define ADC_EXTERNALTRIG7_EXT_IT11 ADC_EXTERNALTRIGCONV_EXT_IT11 +#define ADC_CLOCK_ASYNC ADC_CLOCK_ASYNC_DIV1 +#define ADC_EXTERNALTRIG_EDGE_NONE ADC_EXTERNALTRIGCONVEDGE_NONE +#define ADC_EXTERNALTRIG_EDGE_RISING ADC_EXTERNALTRIGCONVEDGE_RISING +#define ADC_EXTERNALTRIG_EDGE_FALLING ADC_EXTERNALTRIGCONVEDGE_FALLING +#define ADC_EXTERNALTRIG_EDGE_RISINGFALLING ADC_EXTERNALTRIGCONVEDGE_RISINGFALLING +#define ADC_SAMPLETIME_2CYCLE_5 ADC_SAMPLETIME_2CYCLES_5 + +#define HAL_ADC_STATE_BUSY_REG HAL_ADC_STATE_REG_BUSY +#define HAL_ADC_STATE_BUSY_INJ HAL_ADC_STATE_INJ_BUSY +#define HAL_ADC_STATE_EOC_REG HAL_ADC_STATE_REG_EOC +#define HAL_ADC_STATE_EOC_INJ HAL_ADC_STATE_INJ_EOC +#define HAL_ADC_STATE_ERROR HAL_ADC_STATE_ERROR_INTERNAL +#define HAL_ADC_STATE_BUSY HAL_ADC_STATE_BUSY_INTERNAL +#define HAL_ADC_STATE_AWD HAL_ADC_STATE_AWD1 + +#if defined(STM32H7) +#define ADC_CHANNEL_VBAT_DIV4 ADC_CHANNEL_VBAT +#endif /* STM32H7 */ +/** + * @} + */ + +/** @defgroup HAL_CEC_Aliased_Defines HAL CEC Aliased Defines maintained for legacy purpose + * @{ + */ + +#define __HAL_CEC_GET_IT __HAL_CEC_GET_FLAG + +/** + * @} + */ + +/** @defgroup HAL_COMP_Aliased_Defines HAL COMP Aliased Defines maintained for legacy purpose + * @{ + */ +#define COMP_WINDOWMODE_DISABLED COMP_WINDOWMODE_DISABLE +#define COMP_WINDOWMODE_ENABLED COMP_WINDOWMODE_ENABLE +#define COMP_EXTI_LINE_COMP1_EVENT COMP_EXTI_LINE_COMP1 +#define COMP_EXTI_LINE_COMP2_EVENT COMP_EXTI_LINE_COMP2 +#define COMP_EXTI_LINE_COMP3_EVENT COMP_EXTI_LINE_COMP3 +#define COMP_EXTI_LINE_COMP4_EVENT COMP_EXTI_LINE_COMP4 +#define COMP_EXTI_LINE_COMP5_EVENT COMP_EXTI_LINE_COMP5 +#define COMP_EXTI_LINE_COMP6_EVENT COMP_EXTI_LINE_COMP6 +#define COMP_EXTI_LINE_COMP7_EVENT COMP_EXTI_LINE_COMP7 +#if defined(STM32L0) +#define COMP_LPTIMCONNECTION_ENABLED ((uint32_t)0x00000003U) /*!< COMPX output generic naming: connected to LPTIM input 1 for COMP1, LPTIM input 2 for COMP2 */ +#endif +#define COMP_OUTPUT_COMP6TIM2OCREFCLR COMP_OUTPUT_COMP6_TIM2OCREFCLR +#if defined(STM32F373xC) || defined(STM32F378xx) +#define COMP_OUTPUT_TIM3IC1 COMP_OUTPUT_COMP1_TIM3IC1 +#define COMP_OUTPUT_TIM3OCREFCLR COMP_OUTPUT_COMP1_TIM3OCREFCLR +#endif /* STM32F373xC || STM32F378xx */ + +#if defined(STM32L0) || defined(STM32L4) +#define COMP_WINDOWMODE_ENABLE COMP_WINDOWMODE_COMP1_INPUT_PLUS_COMMON + +#define COMP_NONINVERTINGINPUT_IO1 COMP_INPUT_PLUS_IO1 +#define COMP_NONINVERTINGINPUT_IO2 COMP_INPUT_PLUS_IO2 +#define COMP_NONINVERTINGINPUT_IO3 COMP_INPUT_PLUS_IO3 +#define COMP_NONINVERTINGINPUT_IO4 COMP_INPUT_PLUS_IO4 +#define COMP_NONINVERTINGINPUT_IO5 COMP_INPUT_PLUS_IO5 +#define COMP_NONINVERTINGINPUT_IO6 COMP_INPUT_PLUS_IO6 + +#define COMP_INVERTINGINPUT_1_4VREFINT COMP_INPUT_MINUS_1_4VREFINT +#define COMP_INVERTINGINPUT_1_2VREFINT COMP_INPUT_MINUS_1_2VREFINT +#define COMP_INVERTINGINPUT_3_4VREFINT COMP_INPUT_MINUS_3_4VREFINT +#define COMP_INVERTINGINPUT_VREFINT COMP_INPUT_MINUS_VREFINT +#define COMP_INVERTINGINPUT_DAC1_CH1 COMP_INPUT_MINUS_DAC1_CH1 +#define COMP_INVERTINGINPUT_DAC1_CH2 COMP_INPUT_MINUS_DAC1_CH2 +#define COMP_INVERTINGINPUT_DAC1 COMP_INPUT_MINUS_DAC1_CH1 +#define COMP_INVERTINGINPUT_DAC2 COMP_INPUT_MINUS_DAC1_CH2 +#define COMP_INVERTINGINPUT_IO1 COMP_INPUT_MINUS_IO1 +#if defined(STM32L0) +/* Issue fixed on STM32L0 COMP driver: only 2 dedicated IO (IO1 and IO2), */ +/* IO2 was wrongly assigned to IO shared with DAC and IO3 was corresponding */ +/* to the second dedicated IO (only for COMP2). */ +#define COMP_INVERTINGINPUT_IO2 COMP_INPUT_MINUS_DAC1_CH2 +#define COMP_INVERTINGINPUT_IO3 COMP_INPUT_MINUS_IO2 +#else +#define COMP_INVERTINGINPUT_IO2 COMP_INPUT_MINUS_IO2 +#define COMP_INVERTINGINPUT_IO3 COMP_INPUT_MINUS_IO3 +#endif +#define COMP_INVERTINGINPUT_IO4 COMP_INPUT_MINUS_IO4 +#define COMP_INVERTINGINPUT_IO5 COMP_INPUT_MINUS_IO5 + +#define COMP_OUTPUTLEVEL_LOW COMP_OUTPUT_LEVEL_LOW +#define COMP_OUTPUTLEVEL_HIGH COMP_OUTPUT_LEVEL_HIGH + +/* Note: Literal "COMP_FLAG_LOCK" kept for legacy purpose. */ +/* To check COMP lock state, use macro "__HAL_COMP_IS_LOCKED()". */ +#if defined(COMP_CSR_LOCK) +#define COMP_FLAG_LOCK COMP_CSR_LOCK +#elif defined(COMP_CSR_COMP1LOCK) +#define COMP_FLAG_LOCK COMP_CSR_COMP1LOCK +#elif defined(COMP_CSR_COMPxLOCK) +#define COMP_FLAG_LOCK COMP_CSR_COMPxLOCK +#endif + +#if defined(STM32L4) +#define COMP_BLANKINGSRCE_TIM1OC5 COMP_BLANKINGSRC_TIM1_OC5_COMP1 +#define COMP_BLANKINGSRCE_TIM2OC3 COMP_BLANKINGSRC_TIM2_OC3_COMP1 +#define COMP_BLANKINGSRCE_TIM3OC3 COMP_BLANKINGSRC_TIM3_OC3_COMP1 +#define COMP_BLANKINGSRCE_TIM3OC4 COMP_BLANKINGSRC_TIM3_OC4_COMP2 +#define COMP_BLANKINGSRCE_TIM8OC5 COMP_BLANKINGSRC_TIM8_OC5_COMP2 +#define COMP_BLANKINGSRCE_TIM15OC1 COMP_BLANKINGSRC_TIM15_OC1_COMP2 +#define COMP_BLANKINGSRCE_NONE COMP_BLANKINGSRC_NONE +#endif + +#if defined(STM32L0) +#define COMP_MODE_HIGHSPEED COMP_POWERMODE_MEDIUMSPEED +#define COMP_MODE_LOWSPEED COMP_POWERMODE_ULTRALOWPOWER +#else +#define COMP_MODE_HIGHSPEED COMP_POWERMODE_HIGHSPEED +#define COMP_MODE_MEDIUMSPEED COMP_POWERMODE_MEDIUMSPEED +#define COMP_MODE_LOWPOWER COMP_POWERMODE_LOWPOWER +#define COMP_MODE_ULTRALOWPOWER COMP_POWERMODE_ULTRALOWPOWER +#endif + +#endif +/** + * @} + */ + +/** @defgroup HAL_CORTEX_Aliased_Defines HAL CORTEX Aliased Defines maintained for legacy purpose + * @{ + */ +#define __HAL_CORTEX_SYSTICKCLK_CONFIG HAL_SYSTICK_CLKSourceConfig +/** + * @} + */ + +/** @defgroup HAL_CRC_Aliased_Defines HAL CRC Aliased Defines maintained for legacy purpose + * @{ + */ + +#define CRC_OUTPUTDATA_INVERSION_DISABLED CRC_OUTPUTDATA_INVERSION_DISABLE +#define CRC_OUTPUTDATA_INVERSION_ENABLED CRC_OUTPUTDATA_INVERSION_ENABLE + +/** + * @} + */ + +/** @defgroup HAL_DAC_Aliased_Defines HAL DAC Aliased Defines maintained for legacy purpose + * @{ + */ + +#define DAC1_CHANNEL_1 DAC_CHANNEL_1 +#define DAC1_CHANNEL_2 DAC_CHANNEL_2 +#define DAC2_CHANNEL_1 DAC_CHANNEL_1 +#define DAC_WAVE_NONE 0x00000000U +#define DAC_WAVE_NOISE DAC_CR_WAVE1_0 +#define DAC_WAVE_TRIANGLE DAC_CR_WAVE1_1 +#define DAC_WAVEGENERATION_NONE DAC_WAVE_NONE +#define DAC_WAVEGENERATION_NOISE DAC_WAVE_NOISE +#define DAC_WAVEGENERATION_TRIANGLE DAC_WAVE_TRIANGLE + +#if defined(STM32G4) +#define DAC_CHIPCONNECT_DISABLE (DAC_CHIPCONNECT_EXTERNAL | DAC_CHIPCONNECT_BOTH) +#define DAC_CHIPCONNECT_ENABLE (DAC_CHIPCONNECT_INTERNAL | DAC_CHIPCONNECT_BOTH) +#endif + +#if defined(STM32L1) || defined(STM32L4) || defined(STM32G0) +#define HAL_DAC_MSP_INIT_CB_ID HAL_DAC_MSPINIT_CB_ID +#define HAL_DAC_MSP_DEINIT_CB_ID HAL_DAC_MSPDEINIT_CB_ID +#endif + +/** + * @} + */ + +/** @defgroup HAL_DMA_Aliased_Defines HAL DMA Aliased Defines maintained for legacy purpose + * @{ + */ +#define HAL_REMAPDMA_ADC_DMA_CH2 DMA_REMAP_ADC_DMA_CH2 +#define HAL_REMAPDMA_USART1_TX_DMA_CH4 DMA_REMAP_USART1_TX_DMA_CH4 +#define HAL_REMAPDMA_USART1_RX_DMA_CH5 DMA_REMAP_USART1_RX_DMA_CH5 +#define HAL_REMAPDMA_TIM16_DMA_CH4 DMA_REMAP_TIM16_DMA_CH4 +#define HAL_REMAPDMA_TIM17_DMA_CH2 DMA_REMAP_TIM17_DMA_CH2 +#define HAL_REMAPDMA_USART3_DMA_CH32 DMA_REMAP_USART3_DMA_CH32 +#define HAL_REMAPDMA_TIM16_DMA_CH6 DMA_REMAP_TIM16_DMA_CH6 +#define HAL_REMAPDMA_TIM17_DMA_CH7 DMA_REMAP_TIM17_DMA_CH7 +#define HAL_REMAPDMA_SPI2_DMA_CH67 DMA_REMAP_SPI2_DMA_CH67 +#define HAL_REMAPDMA_USART2_DMA_CH67 DMA_REMAP_USART2_DMA_CH67 +#define HAL_REMAPDMA_I2C1_DMA_CH76 DMA_REMAP_I2C1_DMA_CH76 +#define HAL_REMAPDMA_TIM1_DMA_CH6 DMA_REMAP_TIM1_DMA_CH6 +#define HAL_REMAPDMA_TIM2_DMA_CH7 DMA_REMAP_TIM2_DMA_CH7 +#define HAL_REMAPDMA_TIM3_DMA_CH6 DMA_REMAP_TIM3_DMA_CH6 + +#define IS_HAL_REMAPDMA IS_DMA_REMAP +#define __HAL_REMAPDMA_CHANNEL_ENABLE __HAL_DMA_REMAP_CHANNEL_ENABLE +#define __HAL_REMAPDMA_CHANNEL_DISABLE __HAL_DMA_REMAP_CHANNEL_DISABLE + +#if defined(STM32L4) + +#define HAL_DMAMUX1_REQUEST_GEN_EXTI0 HAL_DMAMUX1_REQ_GEN_EXTI0 +#define HAL_DMAMUX1_REQUEST_GEN_EXTI1 HAL_DMAMUX1_REQ_GEN_EXTI1 +#define HAL_DMAMUX1_REQUEST_GEN_EXTI2 HAL_DMAMUX1_REQ_GEN_EXTI2 +#define HAL_DMAMUX1_REQUEST_GEN_EXTI3 HAL_DMAMUX1_REQ_GEN_EXTI3 +#define HAL_DMAMUX1_REQUEST_GEN_EXTI4 HAL_DMAMUX1_REQ_GEN_EXTI4 +#define HAL_DMAMUX1_REQUEST_GEN_EXTI5 HAL_DMAMUX1_REQ_GEN_EXTI5 +#define HAL_DMAMUX1_REQUEST_GEN_EXTI6 HAL_DMAMUX1_REQ_GEN_EXTI6 +#define HAL_DMAMUX1_REQUEST_GEN_EXTI7 HAL_DMAMUX1_REQ_GEN_EXTI7 +#define HAL_DMAMUX1_REQUEST_GEN_EXTI8 HAL_DMAMUX1_REQ_GEN_EXTI8 +#define HAL_DMAMUX1_REQUEST_GEN_EXTI9 HAL_DMAMUX1_REQ_GEN_EXTI9 +#define HAL_DMAMUX1_REQUEST_GEN_EXTI10 HAL_DMAMUX1_REQ_GEN_EXTI10 +#define HAL_DMAMUX1_REQUEST_GEN_EXTI11 HAL_DMAMUX1_REQ_GEN_EXTI11 +#define HAL_DMAMUX1_REQUEST_GEN_EXTI12 HAL_DMAMUX1_REQ_GEN_EXTI12 +#define HAL_DMAMUX1_REQUEST_GEN_EXTI13 HAL_DMAMUX1_REQ_GEN_EXTI13 +#define HAL_DMAMUX1_REQUEST_GEN_EXTI14 HAL_DMAMUX1_REQ_GEN_EXTI14 +#define HAL_DMAMUX1_REQUEST_GEN_EXTI15 HAL_DMAMUX1_REQ_GEN_EXTI15 +#define HAL_DMAMUX1_REQUEST_GEN_DMAMUX1_CH0_EVT HAL_DMAMUX1_REQ_GEN_DMAMUX1_CH0_EVT +#define HAL_DMAMUX1_REQUEST_GEN_DMAMUX1_CH1_EVT HAL_DMAMUX1_REQ_GEN_DMAMUX1_CH1_EVT +#define HAL_DMAMUX1_REQUEST_GEN_DMAMUX1_CH2_EVT HAL_DMAMUX1_REQ_GEN_DMAMUX1_CH2_EVT +#define HAL_DMAMUX1_REQUEST_GEN_DMAMUX1_CH3_EVT HAL_DMAMUX1_REQ_GEN_DMAMUX1_CH3_EVT +#define HAL_DMAMUX1_REQUEST_GEN_LPTIM1_OUT HAL_DMAMUX1_REQ_GEN_LPTIM1_OUT +#define HAL_DMAMUX1_REQUEST_GEN_LPTIM2_OUT HAL_DMAMUX1_REQ_GEN_LPTIM2_OUT +#define HAL_DMAMUX1_REQUEST_GEN_DSI_TE HAL_DMAMUX1_REQ_GEN_DSI_TE +#define HAL_DMAMUX1_REQUEST_GEN_DSI_EOT HAL_DMAMUX1_REQ_GEN_DSI_EOT +#define HAL_DMAMUX1_REQUEST_GEN_DMA2D_EOT HAL_DMAMUX1_REQ_GEN_DMA2D_EOT +#define HAL_DMAMUX1_REQUEST_GEN_LTDC_IT HAL_DMAMUX1_REQ_GEN_LTDC_IT + +#define HAL_DMAMUX_REQUEST_GEN_NO_EVENT HAL_DMAMUX_REQ_GEN_NO_EVENT +#define HAL_DMAMUX_REQUEST_GEN_RISING HAL_DMAMUX_REQ_GEN_RISING +#define HAL_DMAMUX_REQUEST_GEN_FALLING HAL_DMAMUX_REQ_GEN_FALLING +#define HAL_DMAMUX_REQUEST_GEN_RISING_FALLING HAL_DMAMUX_REQ_GEN_RISING_FALLING + +#endif /* STM32L4 */ + +#if defined(STM32H7) + +#define DMA_REQUEST_DAC1 DMA_REQUEST_DAC1_CH1 +#define DMA_REQUEST_DAC2 DMA_REQUEST_DAC1_CH2 + +#define BDMA_REQUEST_LP_UART1_RX BDMA_REQUEST_LPUART1_RX +#define BDMA_REQUEST_LP_UART1_TX BDMA_REQUEST_LPUART1_TX + +#define HAL_DMAMUX1_REQUEST_GEN_DMAMUX1_CH0_EVT HAL_DMAMUX1_REQ_GEN_DMAMUX1_CH0_EVT +#define HAL_DMAMUX1_REQUEST_GEN_DMAMUX1_CH1_EVT HAL_DMAMUX1_REQ_GEN_DMAMUX1_CH1_EVT +#define HAL_DMAMUX1_REQUEST_GEN_DMAMUX1_CH2_EVT HAL_DMAMUX1_REQ_GEN_DMAMUX1_CH2_EVT +#define HAL_DMAMUX1_REQUEST_GEN_LPTIM1_OUT HAL_DMAMUX1_REQ_GEN_LPTIM1_OUT +#define HAL_DMAMUX1_REQUEST_GEN_LPTIM2_OUT HAL_DMAMUX1_REQ_GEN_LPTIM2_OUT +#define HAL_DMAMUX1_REQUEST_GEN_LPTIM3_OUT HAL_DMAMUX1_REQ_GEN_LPTIM3_OUT +#define HAL_DMAMUX1_REQUEST_GEN_EXTI0 HAL_DMAMUX1_REQ_GEN_EXTI0 +#define HAL_DMAMUX1_REQUEST_GEN_TIM12_TRGO HAL_DMAMUX1_REQ_GEN_TIM12_TRGO + +#define HAL_DMAMUX2_REQUEST_GEN_DMAMUX2_CH0_EVT HAL_DMAMUX2_REQ_GEN_DMAMUX2_CH0_EVT +#define HAL_DMAMUX2_REQUEST_GEN_DMAMUX2_CH1_EVT HAL_DMAMUX2_REQ_GEN_DMAMUX2_CH1_EVT +#define HAL_DMAMUX2_REQUEST_GEN_DMAMUX2_CH2_EVT HAL_DMAMUX2_REQ_GEN_DMAMUX2_CH2_EVT +#define HAL_DMAMUX2_REQUEST_GEN_DMAMUX2_CH3_EVT HAL_DMAMUX2_REQ_GEN_DMAMUX2_CH3_EVT +#define HAL_DMAMUX2_REQUEST_GEN_DMAMUX2_CH4_EVT HAL_DMAMUX2_REQ_GEN_DMAMUX2_CH4_EVT +#define HAL_DMAMUX2_REQUEST_GEN_DMAMUX2_CH5_EVT HAL_DMAMUX2_REQ_GEN_DMAMUX2_CH5_EVT +#define HAL_DMAMUX2_REQUEST_GEN_DMAMUX2_CH6_EVT HAL_DMAMUX2_REQ_GEN_DMAMUX2_CH6_EVT +#define HAL_DMAMUX2_REQUEST_GEN_LPUART1_RX_WKUP HAL_DMAMUX2_REQ_GEN_LPUART1_RX_WKUP +#define HAL_DMAMUX2_REQUEST_GEN_LPUART1_TX_WKUP HAL_DMAMUX2_REQ_GEN_LPUART1_TX_WKUP +#define HAL_DMAMUX2_REQUEST_GEN_LPTIM2_WKUP HAL_DMAMUX2_REQ_GEN_LPTIM2_WKUP +#define HAL_DMAMUX2_REQUEST_GEN_LPTIM2_OUT HAL_DMAMUX2_REQ_GEN_LPTIM2_OUT +#define HAL_DMAMUX2_REQUEST_GEN_LPTIM3_WKUP HAL_DMAMUX2_REQ_GEN_LPTIM3_WKUP +#define HAL_DMAMUX2_REQUEST_GEN_LPTIM3_OUT HAL_DMAMUX2_REQ_GEN_LPTIM3_OUT +#define HAL_DMAMUX2_REQUEST_GEN_LPTIM4_WKUP HAL_DMAMUX2_REQ_GEN_LPTIM4_WKUP +#define HAL_DMAMUX2_REQUEST_GEN_LPTIM5_WKUP HAL_DMAMUX2_REQ_GEN_LPTIM5_WKUP +#define HAL_DMAMUX2_REQUEST_GEN_I2C4_WKUP HAL_DMAMUX2_REQ_GEN_I2C4_WKUP +#define HAL_DMAMUX2_REQUEST_GEN_SPI6_WKUP HAL_DMAMUX2_REQ_GEN_SPI6_WKUP +#define HAL_DMAMUX2_REQUEST_GEN_COMP1_OUT HAL_DMAMUX2_REQ_GEN_COMP1_OUT +#define HAL_DMAMUX2_REQUEST_GEN_COMP2_OUT HAL_DMAMUX2_REQ_GEN_COMP2_OUT +#define HAL_DMAMUX2_REQUEST_GEN_RTC_WKUP HAL_DMAMUX2_REQ_GEN_RTC_WKUP +#define HAL_DMAMUX2_REQUEST_GEN_EXTI0 HAL_DMAMUX2_REQ_GEN_EXTI0 +#define HAL_DMAMUX2_REQUEST_GEN_EXTI2 HAL_DMAMUX2_REQ_GEN_EXTI2 +#define HAL_DMAMUX2_REQUEST_GEN_I2C4_IT_EVT HAL_DMAMUX2_REQ_GEN_I2C4_IT_EVT +#define HAL_DMAMUX2_REQUEST_GEN_SPI6_IT HAL_DMAMUX2_REQ_GEN_SPI6_IT +#define HAL_DMAMUX2_REQUEST_GEN_LPUART1_TX_IT HAL_DMAMUX2_REQ_GEN_LPUART1_TX_IT +#define HAL_DMAMUX2_REQUEST_GEN_LPUART1_RX_IT HAL_DMAMUX2_REQ_GEN_LPUART1_RX_IT +#define HAL_DMAMUX2_REQUEST_GEN_ADC3_IT HAL_DMAMUX2_REQ_GEN_ADC3_IT +#define HAL_DMAMUX2_REQUEST_GEN_ADC3_AWD1_OUT HAL_DMAMUX2_REQ_GEN_ADC3_AWD1_OUT +#define HAL_DMAMUX2_REQUEST_GEN_BDMA_CH0_IT HAL_DMAMUX2_REQ_GEN_BDMA_CH0_IT +#define HAL_DMAMUX2_REQUEST_GEN_BDMA_CH1_IT HAL_DMAMUX2_REQ_GEN_BDMA_CH1_IT + +#define HAL_DMAMUX_REQUEST_GEN_NO_EVENT HAL_DMAMUX_REQ_GEN_NO_EVENT +#define HAL_DMAMUX_REQUEST_GEN_RISING HAL_DMAMUX_REQ_GEN_RISING +#define HAL_DMAMUX_REQUEST_GEN_FALLING HAL_DMAMUX_REQ_GEN_FALLING +#define HAL_DMAMUX_REQUEST_GEN_RISING_FALLING HAL_DMAMUX_REQ_GEN_RISING_FALLING + +#define DFSDM_FILTER_EXT_TRIG_LPTIM1 DFSDM_FILTER_EXT_TRIG_LPTIM1_OUT +#define DFSDM_FILTER_EXT_TRIG_LPTIM2 DFSDM_FILTER_EXT_TRIG_LPTIM2_OUT +#define DFSDM_FILTER_EXT_TRIG_LPTIM3 DFSDM_FILTER_EXT_TRIG_LPTIM3_OUT + +#endif /* STM32H7 */ + +/** + * @} + */ + +/** @defgroup HAL_FLASH_Aliased_Defines HAL FLASH Aliased Defines maintained for legacy purpose + * @{ + */ + +#define TYPEPROGRAM_BYTE FLASH_TYPEPROGRAM_BYTE +#define TYPEPROGRAM_HALFWORD FLASH_TYPEPROGRAM_HALFWORD +#define TYPEPROGRAM_WORD FLASH_TYPEPROGRAM_WORD +#define TYPEPROGRAM_DOUBLEWORD FLASH_TYPEPROGRAM_DOUBLEWORD +#define TYPEERASE_SECTORS FLASH_TYPEERASE_SECTORS +#define TYPEERASE_PAGES FLASH_TYPEERASE_PAGES +#define TYPEERASE_PAGEERASE FLASH_TYPEERASE_PAGES +#define TYPEERASE_MASSERASE FLASH_TYPEERASE_MASSERASE +#define WRPSTATE_DISABLE OB_WRPSTATE_DISABLE +#define WRPSTATE_ENABLE OB_WRPSTATE_ENABLE +#define HAL_FLASH_TIMEOUT_VALUE FLASH_TIMEOUT_VALUE +#define OBEX_PCROP OPTIONBYTE_PCROP +#define OBEX_BOOTCONFIG OPTIONBYTE_BOOTCONFIG +#define PCROPSTATE_DISABLE OB_PCROP_STATE_DISABLE +#define PCROPSTATE_ENABLE OB_PCROP_STATE_ENABLE +#define TYPEERASEDATA_BYTE FLASH_TYPEERASEDATA_BYTE +#define TYPEERASEDATA_HALFWORD FLASH_TYPEERASEDATA_HALFWORD +#define TYPEERASEDATA_WORD FLASH_TYPEERASEDATA_WORD +#define TYPEPROGRAMDATA_BYTE FLASH_TYPEPROGRAMDATA_BYTE +#define TYPEPROGRAMDATA_HALFWORD FLASH_TYPEPROGRAMDATA_HALFWORD +#define TYPEPROGRAMDATA_WORD FLASH_TYPEPROGRAMDATA_WORD +#define TYPEPROGRAMDATA_FASTBYTE FLASH_TYPEPROGRAMDATA_FASTBYTE +#define TYPEPROGRAMDATA_FASTHALFWORD FLASH_TYPEPROGRAMDATA_FASTHALFWORD +#define TYPEPROGRAMDATA_FASTWORD FLASH_TYPEPROGRAMDATA_FASTWORD +#define PAGESIZE FLASH_PAGE_SIZE +#define TYPEPROGRAM_FASTBYTE FLASH_TYPEPROGRAM_BYTE +#define TYPEPROGRAM_FASTHALFWORD FLASH_TYPEPROGRAM_HALFWORD +#define TYPEPROGRAM_FASTWORD FLASH_TYPEPROGRAM_WORD +#define VOLTAGE_RANGE_1 FLASH_VOLTAGE_RANGE_1 +#define VOLTAGE_RANGE_2 FLASH_VOLTAGE_RANGE_2 +#define VOLTAGE_RANGE_3 FLASH_VOLTAGE_RANGE_3 +#define VOLTAGE_RANGE_4 FLASH_VOLTAGE_RANGE_4 +#define TYPEPROGRAM_FAST FLASH_TYPEPROGRAM_FAST +#define TYPEPROGRAM_FAST_AND_LAST FLASH_TYPEPROGRAM_FAST_AND_LAST +#define WRPAREA_BANK1_AREAA OB_WRPAREA_BANK1_AREAA +#define WRPAREA_BANK1_AREAB OB_WRPAREA_BANK1_AREAB +#define WRPAREA_BANK2_AREAA OB_WRPAREA_BANK2_AREAA +#define WRPAREA_BANK2_AREAB OB_WRPAREA_BANK2_AREAB +#define IWDG_STDBY_FREEZE OB_IWDG_STDBY_FREEZE +#define IWDG_STDBY_ACTIVE OB_IWDG_STDBY_RUN +#define IWDG_STOP_FREEZE OB_IWDG_STOP_FREEZE +#define IWDG_STOP_ACTIVE OB_IWDG_STOP_RUN +#define FLASH_ERROR_NONE HAL_FLASH_ERROR_NONE +#define FLASH_ERROR_RD HAL_FLASH_ERROR_RD +#define FLASH_ERROR_PG HAL_FLASH_ERROR_PROG +#define FLASH_ERROR_PGP HAL_FLASH_ERROR_PGS +#define FLASH_ERROR_WRP HAL_FLASH_ERROR_WRP +#define FLASH_ERROR_OPTV HAL_FLASH_ERROR_OPTV +#define FLASH_ERROR_OPTVUSR HAL_FLASH_ERROR_OPTVUSR +#define FLASH_ERROR_PROG HAL_FLASH_ERROR_PROG +#define FLASH_ERROR_OP HAL_FLASH_ERROR_OPERATION +#define FLASH_ERROR_PGA HAL_FLASH_ERROR_PGA +#define FLASH_ERROR_SIZE HAL_FLASH_ERROR_SIZE +#define FLASH_ERROR_SIZ HAL_FLASH_ERROR_SIZE +#define FLASH_ERROR_PGS HAL_FLASH_ERROR_PGS +#define FLASH_ERROR_MIS HAL_FLASH_ERROR_MIS +#define FLASH_ERROR_FAST HAL_FLASH_ERROR_FAST +#define FLASH_ERROR_FWWERR HAL_FLASH_ERROR_FWWERR +#define FLASH_ERROR_NOTZERO HAL_FLASH_ERROR_NOTZERO +#define FLASH_ERROR_OPERATION HAL_FLASH_ERROR_OPERATION +#define FLASH_ERROR_ERS HAL_FLASH_ERROR_ERS +#define OB_WDG_SW OB_IWDG_SW +#define OB_WDG_HW OB_IWDG_HW +#define OB_SDADC12_VDD_MONITOR_SET OB_SDACD_VDD_MONITOR_SET +#define OB_SDADC12_VDD_MONITOR_RESET OB_SDACD_VDD_MONITOR_RESET +#define OB_RAM_PARITY_CHECK_SET OB_SRAM_PARITY_SET +#define OB_RAM_PARITY_CHECK_RESET OB_SRAM_PARITY_RESET +#define IS_OB_SDADC12_VDD_MONITOR IS_OB_SDACD_VDD_MONITOR +#define OB_RDP_LEVEL0 OB_RDP_LEVEL_0 +#define OB_RDP_LEVEL1 OB_RDP_LEVEL_1 +#define OB_RDP_LEVEL2 OB_RDP_LEVEL_2 +#if defined(STM32G0) +#define OB_BOOT_LOCK_DISABLE OB_BOOT_ENTRY_FORCED_NONE +#define OB_BOOT_LOCK_ENABLE OB_BOOT_ENTRY_FORCED_FLASH +#else +#define OB_BOOT_ENTRY_FORCED_NONE OB_BOOT_LOCK_DISABLE +#define OB_BOOT_ENTRY_FORCED_FLASH OB_BOOT_LOCK_ENABLE +#endif +#if defined(STM32H7) +#define FLASH_FLAG_SNECCE_BANK1RR FLASH_FLAG_SNECCERR_BANK1 +#define FLASH_FLAG_DBECCE_BANK1RR FLASH_FLAG_DBECCERR_BANK1 +#define FLASH_FLAG_STRBER_BANK1R FLASH_FLAG_STRBERR_BANK1 +#define FLASH_FLAG_SNECCE_BANK2RR FLASH_FLAG_SNECCERR_BANK2 +#define FLASH_FLAG_DBECCE_BANK2RR FLASH_FLAG_DBECCERR_BANK2 +#define FLASH_FLAG_STRBER_BANK2R FLASH_FLAG_STRBERR_BANK2 +#define FLASH_FLAG_WDW FLASH_FLAG_WBNE +#define OB_WRP_SECTOR_All OB_WRP_SECTOR_ALL +#endif /* STM32H7 */ + +/** + * @} + */ + +/** @defgroup HAL_JPEG_Aliased_Macros HAL JPEG Aliased Macros maintained for legacy purpose + * @{ + */ + +#if defined(STM32H7) +#define __HAL_RCC_JPEG_CLK_ENABLE __HAL_RCC_JPGDECEN_CLK_ENABLE +#define __HAL_RCC_JPEG_CLK_DISABLE __HAL_RCC_JPGDECEN_CLK_DISABLE +#define __HAL_RCC_JPEG_FORCE_RESET __HAL_RCC_JPGDECRST_FORCE_RESET +#define __HAL_RCC_JPEG_RELEASE_RESET __HAL_RCC_JPGDECRST_RELEASE_RESET +#define __HAL_RCC_JPEG_CLK_SLEEP_ENABLE __HAL_RCC_JPGDEC_CLK_SLEEP_ENABLE +#define __HAL_RCC_JPEG_CLK_SLEEP_DISABLE __HAL_RCC_JPGDEC_CLK_SLEEP_DISABLE +#endif /* STM32H7 */ + +/** + * @} + */ + +/** @defgroup HAL_SYSCFG_Aliased_Defines HAL SYSCFG Aliased Defines maintained for legacy purpose + * @{ + */ + +#define HAL_SYSCFG_FASTMODEPLUS_I2C_PA9 I2C_FASTMODEPLUS_PA9 +#define HAL_SYSCFG_FASTMODEPLUS_I2C_PA10 I2C_FASTMODEPLUS_PA10 +#define HAL_SYSCFG_FASTMODEPLUS_I2C_PB6 I2C_FASTMODEPLUS_PB6 +#define HAL_SYSCFG_FASTMODEPLUS_I2C_PB7 I2C_FASTMODEPLUS_PB7 +#define HAL_SYSCFG_FASTMODEPLUS_I2C_PB8 I2C_FASTMODEPLUS_PB8 +#define HAL_SYSCFG_FASTMODEPLUS_I2C_PB9 I2C_FASTMODEPLUS_PB9 +#define HAL_SYSCFG_FASTMODEPLUS_I2C1 I2C_FASTMODEPLUS_I2C1 +#define HAL_SYSCFG_FASTMODEPLUS_I2C2 I2C_FASTMODEPLUS_I2C2 +#define HAL_SYSCFG_FASTMODEPLUS_I2C3 I2C_FASTMODEPLUS_I2C3 +#if defined(STM32G4) + +#define HAL_SYSCFG_EnableIOAnalogSwitchBooster HAL_SYSCFG_EnableIOSwitchBooster +#define HAL_SYSCFG_DisableIOAnalogSwitchBooster HAL_SYSCFG_DisableIOSwitchBooster +#define HAL_SYSCFG_EnableIOAnalogSwitchVDD HAL_SYSCFG_EnableIOSwitchVDD +#define HAL_SYSCFG_DisableIOAnalogSwitchVDD HAL_SYSCFG_DisableIOSwitchVDD +#endif /* STM32G4 */ +/** + * @} + */ + + +/** @defgroup LL_FMC_Aliased_Defines LL FMC Aliased Defines maintained for compatibility purpose + * @{ + */ +#if defined(STM32L4) || defined(STM32F7) || defined(STM32H7) || defined(STM32G4) +#define FMC_NAND_PCC_WAIT_FEATURE_DISABLE FMC_NAND_WAIT_FEATURE_DISABLE +#define FMC_NAND_PCC_WAIT_FEATURE_ENABLE FMC_NAND_WAIT_FEATURE_ENABLE +#define FMC_NAND_PCC_MEM_BUS_WIDTH_8 FMC_NAND_MEM_BUS_WIDTH_8 +#define FMC_NAND_PCC_MEM_BUS_WIDTH_16 FMC_NAND_MEM_BUS_WIDTH_16 +#elif defined(STM32F1) || defined(STM32F2) || defined(STM32F3) || defined(STM32F4) +#define FMC_NAND_WAIT_FEATURE_DISABLE FMC_NAND_PCC_WAIT_FEATURE_DISABLE +#define FMC_NAND_WAIT_FEATURE_ENABLE FMC_NAND_PCC_WAIT_FEATURE_ENABLE +#define FMC_NAND_MEM_BUS_WIDTH_8 FMC_NAND_PCC_MEM_BUS_WIDTH_8 +#define FMC_NAND_MEM_BUS_WIDTH_16 FMC_NAND_PCC_MEM_BUS_WIDTH_16 +#endif +/** + * @} + */ + +/** @defgroup LL_FSMC_Aliased_Defines LL FSMC Aliased Defines maintained for legacy purpose + * @{ + */ + +#define FSMC_NORSRAM_TYPEDEF FSMC_NORSRAM_TypeDef +#define FSMC_NORSRAM_EXTENDED_TYPEDEF FSMC_NORSRAM_EXTENDED_TypeDef +/** + * @} + */ + +/** @defgroup HAL_GPIO_Aliased_Macros HAL GPIO Aliased Macros maintained for legacy purpose + * @{ + */ +#define GET_GPIO_SOURCE GPIO_GET_INDEX +#define GET_GPIO_INDEX GPIO_GET_INDEX + +#if defined(STM32F4) +#define GPIO_AF12_SDMMC GPIO_AF12_SDIO +#define GPIO_AF12_SDMMC1 GPIO_AF12_SDIO +#endif + +#if defined(STM32F7) +#define GPIO_AF12_SDIO GPIO_AF12_SDMMC1 +#define GPIO_AF12_SDMMC GPIO_AF12_SDMMC1 +#endif + +#if defined(STM32L4) +#define GPIO_AF12_SDIO GPIO_AF12_SDMMC1 +#define GPIO_AF12_SDMMC GPIO_AF12_SDMMC1 +#endif + +#if defined(STM32H7) +#define GPIO_AF7_SDIO1 GPIO_AF7_SDMMC1 +#define GPIO_AF8_SDIO1 GPIO_AF8_SDMMC1 +#define GPIO_AF12_SDIO1 GPIO_AF12_SDMMC1 +#define GPIO_AF9_SDIO2 GPIO_AF9_SDMMC2 +#define GPIO_AF10_SDIO2 GPIO_AF10_SDMMC2 +#define GPIO_AF11_SDIO2 GPIO_AF11_SDMMC2 +#endif + +#define GPIO_AF0_LPTIM GPIO_AF0_LPTIM1 +#define GPIO_AF1_LPTIM GPIO_AF1_LPTIM1 +#define GPIO_AF2_LPTIM GPIO_AF2_LPTIM1 + +#if defined(STM32L0) || defined(STM32L4) || defined(STM32F4) || defined(STM32F2) || defined(STM32F7) || defined(STM32G4) || defined(STM32H7) +#define GPIO_SPEED_LOW GPIO_SPEED_FREQ_LOW +#define GPIO_SPEED_MEDIUM GPIO_SPEED_FREQ_MEDIUM +#define GPIO_SPEED_FAST GPIO_SPEED_FREQ_HIGH +#define GPIO_SPEED_HIGH GPIO_SPEED_FREQ_VERY_HIGH +#endif /* STM32L0 || STM32L4 || STM32F4 || STM32F2 || STM32F7 || STM32G4 || STM32H7*/ + +#if defined(STM32L1) + #define GPIO_SPEED_VERY_LOW GPIO_SPEED_FREQ_LOW + #define GPIO_SPEED_LOW GPIO_SPEED_FREQ_MEDIUM + #define GPIO_SPEED_MEDIUM GPIO_SPEED_FREQ_HIGH + #define GPIO_SPEED_HIGH GPIO_SPEED_FREQ_VERY_HIGH +#endif /* STM32L1 */ + +#if defined(STM32F0) || defined(STM32F3) || defined(STM32F1) + #define GPIO_SPEED_LOW GPIO_SPEED_FREQ_LOW + #define GPIO_SPEED_MEDIUM GPIO_SPEED_FREQ_MEDIUM + #define GPIO_SPEED_HIGH GPIO_SPEED_FREQ_HIGH +#endif /* STM32F0 || STM32F3 || STM32F1 */ + +#define GPIO_AF6_DFSDM GPIO_AF6_DFSDM1 +/** + * @} + */ + +/** @defgroup HAL_HRTIM_Aliased_Macros HAL HRTIM Aliased Macros maintained for legacy purpose + * @{ + */ +#define HRTIM_TIMDELAYEDPROTECTION_DISABLED HRTIM_TIMER_A_B_C_DELAYEDPROTECTION_DISABLED +#define HRTIM_TIMDELAYEDPROTECTION_DELAYEDOUT1_EEV68 HRTIM_TIMER_A_B_C_DELAYEDPROTECTION_DELAYEDOUT1_EEV6 +#define HRTIM_TIMDELAYEDPROTECTION_DELAYEDOUT2_EEV68 HRTIM_TIMER_A_B_C_DELAYEDPROTECTION_DELAYEDOUT2_EEV6 +#define HRTIM_TIMDELAYEDPROTECTION_DELAYEDBOTH_EEV68 HRTIM_TIMER_A_B_C_DELAYEDPROTECTION_DELAYEDBOTH_EEV6 +#define HRTIM_TIMDELAYEDPROTECTION_BALANCED_EEV68 HRTIM_TIMER_A_B_C_DELAYEDPROTECTION_BALANCED_EEV6 +#define HRTIM_TIMDELAYEDPROTECTION_DELAYEDOUT1_DEEV79 HRTIM_TIMER_A_B_C_DELAYEDPROTECTION_DELAYEDOUT1_DEEV7 +#define HRTIM_TIMDELAYEDPROTECTION_DELAYEDOUT2_DEEV79 HRTIM_TIMER_A_B_C_DELAYEDPROTECTION_DELAYEDOUT2_DEEV7 +#define HRTIM_TIMDELAYEDPROTECTION_DELAYEDBOTH_EEV79 HRTIM_TIMER_A_B_C_DELAYEDPROTECTION_DELAYEDBOTH_EEV7 +#define HRTIM_TIMDELAYEDPROTECTION_BALANCED_EEV79 HRTIM_TIMER_A_B_C_DELAYEDPROTECTION_BALANCED_EEV7 + +#define __HAL_HRTIM_SetCounter __HAL_HRTIM_SETCOUNTER +#define __HAL_HRTIM_GetCounter __HAL_HRTIM_GETCOUNTER +#define __HAL_HRTIM_SetPeriod __HAL_HRTIM_SETPERIOD +#define __HAL_HRTIM_GetPeriod __HAL_HRTIM_GETPERIOD +#define __HAL_HRTIM_SetClockPrescaler __HAL_HRTIM_SETCLOCKPRESCALER +#define __HAL_HRTIM_GetClockPrescaler __HAL_HRTIM_GETCLOCKPRESCALER +#define __HAL_HRTIM_SetCompare __HAL_HRTIM_SETCOMPARE +#define __HAL_HRTIM_GetCompare __HAL_HRTIM_GETCOMPARE + +#if defined(STM32G4) +#define HAL_HRTIM_ExternalEventCounterConfig HAL_HRTIM_ExtEventCounterConfig +#define HAL_HRTIM_ExternalEventCounterEnable HAL_HRTIM_ExtEventCounterEnable +#define HAL_HRTIM_ExternalEventCounterDisable HAL_HRTIM_ExtEventCounterDisable +#define HAL_HRTIM_ExternalEventCounterReset HAL_HRTIM_ExtEventCounterReset +#endif /* STM32G4 */ + +#if defined(STM32H7) +#define HRTIM_OUTPUTSET_TIMAEV1_TIMBCMP1 HRTIM_OUTPUTSET_TIMEV_1 +#define HRTIM_OUTPUTSET_TIMAEV2_TIMBCMP2 HRTIM_OUTPUTSET_TIMEV_2 +#define HRTIM_OUTPUTSET_TIMAEV3_TIMCCMP2 HRTIM_OUTPUTSET_TIMEV_3 +#define HRTIM_OUTPUTSET_TIMAEV4_TIMCCMP3 HRTIM_OUTPUTSET_TIMEV_4 +#define HRTIM_OUTPUTSET_TIMAEV5_TIMDCMP1 HRTIM_OUTPUTSET_TIMEV_5 +#define HRTIM_OUTPUTSET_TIMAEV6_TIMDCMP2 HRTIM_OUTPUTSET_TIMEV_6 +#define HRTIM_OUTPUTSET_TIMAEV7_TIMECMP3 HRTIM_OUTPUTSET_TIMEV_7 +#define HRTIM_OUTPUTSET_TIMAEV8_TIMECMP4 HRTIM_OUTPUTSET_TIMEV_8 +#define HRTIM_OUTPUTSET_TIMAEV9_TIMFCMP4 HRTIM_OUTPUTSET_TIMEV_9 +#define HRTIM_OUTPUTSET_TIMBEV1_TIMACMP1 HRTIM_OUTPUTSET_TIMEV_1 +#define HRTIM_OUTPUTSET_TIMBEV2_TIMACMP2 HRTIM_OUTPUTSET_TIMEV_2 +#define HRTIM_OUTPUTSET_TIMBEV3_TIMCCMP3 HRTIM_OUTPUTSET_TIMEV_3 +#define HRTIM_OUTPUTSET_TIMBEV4_TIMCCMP4 HRTIM_OUTPUTSET_TIMEV_4 +#define HRTIM_OUTPUTSET_TIMBEV5_TIMDCMP3 HRTIM_OUTPUTSET_TIMEV_5 +#define HRTIM_OUTPUTSET_TIMBEV6_TIMDCMP4 HRTIM_OUTPUTSET_TIMEV_6 +#define HRTIM_OUTPUTSET_TIMBEV7_TIMECMP1 HRTIM_OUTPUTSET_TIMEV_7 +#define HRTIM_OUTPUTSET_TIMBEV8_TIMECMP2 HRTIM_OUTPUTSET_TIMEV_8 +#define HRTIM_OUTPUTSET_TIMBEV9_TIMFCMP3 HRTIM_OUTPUTSET_TIMEV_9 +#define HRTIM_OUTPUTSET_TIMCEV1_TIMACMP1 HRTIM_OUTPUTSET_TIMEV_1 +#define HRTIM_OUTPUTSET_TIMCEV2_TIMACMP2 HRTIM_OUTPUTSET_TIMEV_2 +#define HRTIM_OUTPUTSET_TIMCEV3_TIMBCMP2 HRTIM_OUTPUTSET_TIMEV_3 +#define HRTIM_OUTPUTSET_TIMCEV4_TIMBCMP3 HRTIM_OUTPUTSET_TIMEV_4 +#define HRTIM_OUTPUTSET_TIMCEV5_TIMDCMP2 HRTIM_OUTPUTSET_TIMEV_5 +#define HRTIM_OUTPUTSET_TIMCEV6_TIMDCMP4 HRTIM_OUTPUTSET_TIMEV_6 +#define HRTIM_OUTPUTSET_TIMCEV7_TIMECMP3 HRTIM_OUTPUTSET_TIMEV_7 +#define HRTIM_OUTPUTSET_TIMCEV8_TIMECMP4 HRTIM_OUTPUTSET_TIMEV_8 +#define HRTIM_OUTPUTSET_TIMCEV9_TIMFCMP2 HRTIM_OUTPUTSET_TIMEV_9 +#define HRTIM_OUTPUTSET_TIMDEV1_TIMACMP1 HRTIM_OUTPUTSET_TIMEV_1 +#define HRTIM_OUTPUTSET_TIMDEV2_TIMACMP4 HRTIM_OUTPUTSET_TIMEV_2 +#define HRTIM_OUTPUTSET_TIMDEV3_TIMBCMP2 HRTIM_OUTPUTSET_TIMEV_3 +#define HRTIM_OUTPUTSET_TIMDEV4_TIMBCMP4 HRTIM_OUTPUTSET_TIMEV_4 +#define HRTIM_OUTPUTSET_TIMDEV5_TIMCCMP4 HRTIM_OUTPUTSET_TIMEV_5 +#define HRTIM_OUTPUTSET_TIMDEV6_TIMECMP1 HRTIM_OUTPUTSET_TIMEV_6 +#define HRTIM_OUTPUTSET_TIMDEV7_TIMECMP4 HRTIM_OUTPUTSET_TIMEV_7 +#define HRTIM_OUTPUTSET_TIMDEV8_TIMFCMP1 HRTIM_OUTPUTSET_TIMEV_8 +#define HRTIM_OUTPUTSET_TIMDEV9_TIMFCMP3 HRTIM_OUTPUTSET_TIMEV_9 +#define HRTIM_OUTPUTSET_TIMEEV1_TIMACMP4 HRTIM_OUTPUTSET_TIMEV_1 +#define HRTIM_OUTPUTSET_TIMEEV2_TIMBCMP3 HRTIM_OUTPUTSET_TIMEV_2 +#define HRTIM_OUTPUTSET_TIMEEV3_TIMBCMP4 HRTIM_OUTPUTSET_TIMEV_3 +#define HRTIM_OUTPUTSET_TIMEEV4_TIMCCMP1 HRTIM_OUTPUTSET_TIMEV_4 +#define HRTIM_OUTPUTSET_TIMEEV5_TIMDCMP2 HRTIM_OUTPUTSET_TIMEV_5 +#define HRTIM_OUTPUTSET_TIMEEV6_TIMDCMP1 HRTIM_OUTPUTSET_TIMEV_6 +#define HRTIM_OUTPUTSET_TIMEEV7_TIMDCMP2 HRTIM_OUTPUTSET_TIMEV_7 +#define HRTIM_OUTPUTSET_TIMEEV8_TIMFCMP3 HRTIM_OUTPUTSET_TIMEV_8 +#define HRTIM_OUTPUTSET_TIMEEV9_TIMFCMP4 HRTIM_OUTPUTSET_TIMEV_9 +#define HRTIM_OUTPUTSET_TIMFEV1_TIMACMP3 HRTIM_OUTPUTSET_TIMEV_1 +#define HRTIM_OUTPUTSET_TIMFEV2_TIMBCMP1 HRTIM_OUTPUTSET_TIMEV_2 +#define HRTIM_OUTPUTSET_TIMFEV3_TIMBCMP4 HRTIM_OUTPUTSET_TIMEV_3 +#define HRTIM_OUTPUTSET_TIMFEV4_TIMCCMP1 HRTIM_OUTPUTSET_TIMEV_4 +#define HRTIM_OUTPUTSET_TIMFEV5_TIMCCMP4 HRTIM_OUTPUTSET_TIMEV_5 +#define HRTIM_OUTPUTSET_TIMFEV6_TIMDCMP3 HRTIM_OUTPUTSET_TIMEV_6 +#define HRTIM_OUTPUTSET_TIMFEV7_TIMDCMP4 HRTIM_OUTPUTSET_TIMEV_7 +#define HRTIM_OUTPUTSET_TIMFEV8_TIMECMP2 HRTIM_OUTPUTSET_TIMEV_8 +#define HRTIM_OUTPUTSET_TIMFEV9_TIMECMP3 HRTIM_OUTPUTSET_TIMEV_9 + +#define HRTIM_OUTPUTRESET_TIMAEV1_TIMBCMP1 HRTIM_OUTPUTSET_TIMEV_1 +#define HRTIM_OUTPUTRESET_TIMAEV2_TIMBCMP2 HRTIM_OUTPUTSET_TIMEV_2 +#define HRTIM_OUTPUTRESET_TIMAEV3_TIMCCMP2 HRTIM_OUTPUTSET_TIMEV_3 +#define HRTIM_OUTPUTRESET_TIMAEV4_TIMCCMP3 HRTIM_OUTPUTSET_TIMEV_4 +#define HRTIM_OUTPUTRESET_TIMAEV5_TIMDCMP1 HRTIM_OUTPUTSET_TIMEV_5 +#define HRTIM_OUTPUTRESET_TIMAEV6_TIMDCMP2 HRTIM_OUTPUTSET_TIMEV_6 +#define HRTIM_OUTPUTRESET_TIMAEV7_TIMECMP3 HRTIM_OUTPUTSET_TIMEV_7 +#define HRTIM_OUTPUTRESET_TIMAEV8_TIMECMP4 HRTIM_OUTPUTSET_TIMEV_8 +#define HRTIM_OUTPUTRESET_TIMAEV9_TIMFCMP4 HRTIM_OUTPUTSET_TIMEV_9 +#define HRTIM_OUTPUTRESET_TIMBEV1_TIMACMP1 HRTIM_OUTPUTSET_TIMEV_1 +#define HRTIM_OUTPUTRESET_TIMBEV2_TIMACMP2 HRTIM_OUTPUTSET_TIMEV_2 +#define HRTIM_OUTPUTRESET_TIMBEV3_TIMCCMP3 HRTIM_OUTPUTSET_TIMEV_3 +#define HRTIM_OUTPUTRESET_TIMBEV4_TIMCCMP4 HRTIM_OUTPUTSET_TIMEV_4 +#define HRTIM_OUTPUTRESET_TIMBEV5_TIMDCMP3 HRTIM_OUTPUTSET_TIMEV_5 +#define HRTIM_OUTPUTRESET_TIMBEV6_TIMDCMP4 HRTIM_OUTPUTSET_TIMEV_6 +#define HRTIM_OUTPUTRESET_TIMBEV7_TIMECMP1 HRTIM_OUTPUTSET_TIMEV_7 +#define HRTIM_OUTPUTRESET_TIMBEV8_TIMECMP2 HRTIM_OUTPUTSET_TIMEV_8 +#define HRTIM_OUTPUTRESET_TIMBEV9_TIMFCMP3 HRTIM_OUTPUTSET_TIMEV_9 +#define HRTIM_OUTPUTRESET_TIMCEV1_TIMACMP1 HRTIM_OUTPUTSET_TIMEV_1 +#define HRTIM_OUTPUTRESET_TIMCEV2_TIMACMP2 HRTIM_OUTPUTSET_TIMEV_2 +#define HRTIM_OUTPUTRESET_TIMCEV3_TIMBCMP2 HRTIM_OUTPUTSET_TIMEV_3 +#define HRTIM_OUTPUTRESET_TIMCEV4_TIMBCMP3 HRTIM_OUTPUTSET_TIMEV_4 +#define HRTIM_OUTPUTRESET_TIMCEV5_TIMDCMP2 HRTIM_OUTPUTSET_TIMEV_5 +#define HRTIM_OUTPUTRESET_TIMCEV6_TIMDCMP4 HRTIM_OUTPUTSET_TIMEV_6 +#define HRTIM_OUTPUTRESET_TIMCEV7_TIMECMP3 HRTIM_OUTPUTSET_TIMEV_7 +#define HRTIM_OUTPUTRESET_TIMCEV8_TIMECMP4 HRTIM_OUTPUTSET_TIMEV_8 +#define HRTIM_OUTPUTRESET_TIMCEV9_TIMFCMP2 HRTIM_OUTPUTSET_TIMEV_9 +#define HRTIM_OUTPUTRESET_TIMDEV1_TIMACMP1 HRTIM_OUTPUTSET_TIMEV_1 +#define HRTIM_OUTPUTRESET_TIMDEV2_TIMACMP4 HRTIM_OUTPUTSET_TIMEV_2 +#define HRTIM_OUTPUTRESET_TIMDEV3_TIMBCMP2 HRTIM_OUTPUTSET_TIMEV_3 +#define HRTIM_OUTPUTRESET_TIMDEV4_TIMBCMP4 HRTIM_OUTPUTSET_TIMEV_4 +#define HRTIM_OUTPUTRESET_TIMDEV5_TIMCCMP4 HRTIM_OUTPUTSET_TIMEV_5 +#define HRTIM_OUTPUTRESET_TIMDEV6_TIMECMP1 HRTIM_OUTPUTSET_TIMEV_6 +#define HRTIM_OUTPUTRESET_TIMDEV7_TIMECMP4 HRTIM_OUTPUTSET_TIMEV_7 +#define HRTIM_OUTPUTRESET_TIMDEV8_TIMFCMP1 HRTIM_OUTPUTSET_TIMEV_8 +#define HRTIM_OUTPUTRESET_TIMDEV9_TIMFCMP3 HRTIM_OUTPUTSET_TIMEV_9 +#define HRTIM_OUTPUTRESET_TIMEEV1_TIMACMP4 HRTIM_OUTPUTSET_TIMEV_1 +#define HRTIM_OUTPUTRESET_TIMEEV2_TIMBCMP3 HRTIM_OUTPUTSET_TIMEV_2 +#define HRTIM_OUTPUTRESET_TIMEEV3_TIMBCMP4 HRTIM_OUTPUTSET_TIMEV_3 +#define HRTIM_OUTPUTRESET_TIMEEV4_TIMCCMP1 HRTIM_OUTPUTSET_TIMEV_4 +#define HRTIM_OUTPUTRESET_TIMEEV5_TIMDCMP2 HRTIM_OUTPUTSET_TIMEV_5 +#define HRTIM_OUTPUTRESET_TIMEEV6_TIMDCMP1 HRTIM_OUTPUTSET_TIMEV_6 +#define HRTIM_OUTPUTRESET_TIMEEV7_TIMDCMP2 HRTIM_OUTPUTSET_TIMEV_7 +#define HRTIM_OUTPUTRESET_TIMEEV8_TIMFCMP3 HRTIM_OUTPUTSET_TIMEV_8 +#define HRTIM_OUTPUTRESET_TIMEEV9_TIMFCMP4 HRTIM_OUTPUTSET_TIMEV_9 +#define HRTIM_OUTPUTRESET_TIMFEV1_TIMACMP3 HRTIM_OUTPUTSET_TIMEV_1 +#define HRTIM_OUTPUTRESET_TIMFEV2_TIMBCMP1 HRTIM_OUTPUTSET_TIMEV_2 +#define HRTIM_OUTPUTRESET_TIMFEV3_TIMBCMP4 HRTIM_OUTPUTSET_TIMEV_3 +#define HRTIM_OUTPUTRESET_TIMFEV4_TIMCCMP1 HRTIM_OUTPUTSET_TIMEV_4 +#define HRTIM_OUTPUTRESET_TIMFEV5_TIMCCMP4 HRTIM_OUTPUTSET_TIMEV_5 +#define HRTIM_OUTPUTRESET_TIMFEV6_TIMDCMP3 HRTIM_OUTPUTSET_TIMEV_6 +#define HRTIM_OUTPUTRESET_TIMFEV7_TIMDCMP4 HRTIM_OUTPUTSET_TIMEV_7 +#define HRTIM_OUTPUTRESET_TIMFEV8_TIMECMP2 HRTIM_OUTPUTSET_TIMEV_8 +#define HRTIM_OUTPUTRESET_TIMFEV9_TIMECMP3 HRTIM_OUTPUTSET_TIMEV_9 +#endif /* STM32H7 */ +/** + * @} + */ + +/** @defgroup HAL_I2C_Aliased_Defines HAL I2C Aliased Defines maintained for legacy purpose + * @{ + */ +#define I2C_DUALADDRESS_DISABLED I2C_DUALADDRESS_DISABLE +#define I2C_DUALADDRESS_ENABLED I2C_DUALADDRESS_ENABLE +#define I2C_GENERALCALL_DISABLED I2C_GENERALCALL_DISABLE +#define I2C_GENERALCALL_ENABLED I2C_GENERALCALL_ENABLE +#define I2C_NOSTRETCH_DISABLED I2C_NOSTRETCH_DISABLE +#define I2C_NOSTRETCH_ENABLED I2C_NOSTRETCH_ENABLE +#define I2C_ANALOGFILTER_ENABLED I2C_ANALOGFILTER_ENABLE +#define I2C_ANALOGFILTER_DISABLED I2C_ANALOGFILTER_DISABLE +#if defined(STM32F0) || defined(STM32F1) || defined(STM32F3) || defined(STM32G0) || defined(STM32L4) || defined(STM32L1) || defined(STM32F7) +#define HAL_I2C_STATE_MEM_BUSY_TX HAL_I2C_STATE_BUSY_TX +#define HAL_I2C_STATE_MEM_BUSY_RX HAL_I2C_STATE_BUSY_RX +#define HAL_I2C_STATE_MASTER_BUSY_TX HAL_I2C_STATE_BUSY_TX +#define HAL_I2C_STATE_MASTER_BUSY_RX HAL_I2C_STATE_BUSY_RX +#define HAL_I2C_STATE_SLAVE_BUSY_TX HAL_I2C_STATE_BUSY_TX +#define HAL_I2C_STATE_SLAVE_BUSY_RX HAL_I2C_STATE_BUSY_RX +#endif +/** + * @} + */ + +/** @defgroup HAL_IRDA_Aliased_Defines HAL IRDA Aliased Defines maintained for legacy purpose + * @{ + */ +#define IRDA_ONE_BIT_SAMPLE_DISABLED IRDA_ONE_BIT_SAMPLE_DISABLE +#define IRDA_ONE_BIT_SAMPLE_ENABLED IRDA_ONE_BIT_SAMPLE_ENABLE + +/** + * @} + */ + +/** @defgroup HAL_IWDG_Aliased_Defines HAL IWDG Aliased Defines maintained for legacy purpose + * @{ + */ +#define KR_KEY_RELOAD IWDG_KEY_RELOAD +#define KR_KEY_ENABLE IWDG_KEY_ENABLE +#define KR_KEY_EWA IWDG_KEY_WRITE_ACCESS_ENABLE +#define KR_KEY_DWA IWDG_KEY_WRITE_ACCESS_DISABLE +/** + * @} + */ + +/** @defgroup HAL_LPTIM_Aliased_Defines HAL LPTIM Aliased Defines maintained for legacy purpose + * @{ + */ + +#define LPTIM_CLOCKSAMPLETIME_DIRECTTRANSISTION LPTIM_CLOCKSAMPLETIME_DIRECTTRANSITION +#define LPTIM_CLOCKSAMPLETIME_2TRANSISTIONS LPTIM_CLOCKSAMPLETIME_2TRANSITIONS +#define LPTIM_CLOCKSAMPLETIME_4TRANSISTIONS LPTIM_CLOCKSAMPLETIME_4TRANSITIONS +#define LPTIM_CLOCKSAMPLETIME_8TRANSISTIONS LPTIM_CLOCKSAMPLETIME_8TRANSITIONS + +#define LPTIM_CLOCKPOLARITY_RISINGEDGE LPTIM_CLOCKPOLARITY_RISING +#define LPTIM_CLOCKPOLARITY_FALLINGEDGE LPTIM_CLOCKPOLARITY_FALLING +#define LPTIM_CLOCKPOLARITY_BOTHEDGES LPTIM_CLOCKPOLARITY_RISING_FALLING + +#define LPTIM_TRIGSAMPLETIME_DIRECTTRANSISTION LPTIM_TRIGSAMPLETIME_DIRECTTRANSITION +#define LPTIM_TRIGSAMPLETIME_2TRANSISTIONS LPTIM_TRIGSAMPLETIME_2TRANSITIONS +#define LPTIM_TRIGSAMPLETIME_4TRANSISTIONS LPTIM_TRIGSAMPLETIME_4TRANSITIONS +#define LPTIM_TRIGSAMPLETIME_8TRANSISTIONS LPTIM_TRIGSAMPLETIME_8TRANSITIONS + +/* The following 3 definition have also been present in a temporary version of lptim.h */ +/* They need to be renamed also to the right name, just in case */ +#define LPTIM_TRIGSAMPLETIME_2TRANSITION LPTIM_TRIGSAMPLETIME_2TRANSITIONS +#define LPTIM_TRIGSAMPLETIME_4TRANSITION LPTIM_TRIGSAMPLETIME_4TRANSITIONS +#define LPTIM_TRIGSAMPLETIME_8TRANSITION LPTIM_TRIGSAMPLETIME_8TRANSITIONS + +/** + * @} + */ + +/** @defgroup HAL_NAND_Aliased_Defines HAL NAND Aliased Defines maintained for legacy purpose + * @{ + */ +#define HAL_NAND_Read_Page HAL_NAND_Read_Page_8b +#define HAL_NAND_Write_Page HAL_NAND_Write_Page_8b +#define HAL_NAND_Read_SpareArea HAL_NAND_Read_SpareArea_8b +#define HAL_NAND_Write_SpareArea HAL_NAND_Write_SpareArea_8b + +#define NAND_AddressTypedef NAND_AddressTypeDef + +#define __ARRAY_ADDRESS ARRAY_ADDRESS +#define __ADDR_1st_CYCLE ADDR_1ST_CYCLE +#define __ADDR_2nd_CYCLE ADDR_2ND_CYCLE +#define __ADDR_3rd_CYCLE ADDR_3RD_CYCLE +#define __ADDR_4th_CYCLE ADDR_4TH_CYCLE +/** + * @} + */ + +/** @defgroup HAL_NOR_Aliased_Defines HAL NOR Aliased Defines maintained for legacy purpose + * @{ + */ +#define NOR_StatusTypedef HAL_NOR_StatusTypeDef +#define NOR_SUCCESS HAL_NOR_STATUS_SUCCESS +#define NOR_ONGOING HAL_NOR_STATUS_ONGOING +#define NOR_ERROR HAL_NOR_STATUS_ERROR +#define NOR_TIMEOUT HAL_NOR_STATUS_TIMEOUT + +#define __NOR_WRITE NOR_WRITE +#define __NOR_ADDR_SHIFT NOR_ADDR_SHIFT +/** + * @} + */ + +/** @defgroup HAL_OPAMP_Aliased_Defines HAL OPAMP Aliased Defines maintained for legacy purpose + * @{ + */ + +#define OPAMP_NONINVERTINGINPUT_VP0 OPAMP_NONINVERTINGINPUT_IO0 +#define OPAMP_NONINVERTINGINPUT_VP1 OPAMP_NONINVERTINGINPUT_IO1 +#define OPAMP_NONINVERTINGINPUT_VP2 OPAMP_NONINVERTINGINPUT_IO2 +#define OPAMP_NONINVERTINGINPUT_VP3 OPAMP_NONINVERTINGINPUT_IO3 + +#define OPAMP_SEC_NONINVERTINGINPUT_VP0 OPAMP_SEC_NONINVERTINGINPUT_IO0 +#define OPAMP_SEC_NONINVERTINGINPUT_VP1 OPAMP_SEC_NONINVERTINGINPUT_IO1 +#define OPAMP_SEC_NONINVERTINGINPUT_VP2 OPAMP_SEC_NONINVERTINGINPUT_IO2 +#define OPAMP_SEC_NONINVERTINGINPUT_VP3 OPAMP_SEC_NONINVERTINGINPUT_IO3 + +#define OPAMP_INVERTINGINPUT_VM0 OPAMP_INVERTINGINPUT_IO0 +#define OPAMP_INVERTINGINPUT_VM1 OPAMP_INVERTINGINPUT_IO1 + +#define IOPAMP_INVERTINGINPUT_VM0 OPAMP_INVERTINGINPUT_IO0 +#define IOPAMP_INVERTINGINPUT_VM1 OPAMP_INVERTINGINPUT_IO1 + +#define OPAMP_SEC_INVERTINGINPUT_VM0 OPAMP_SEC_INVERTINGINPUT_IO0 +#define OPAMP_SEC_INVERTINGINPUT_VM1 OPAMP_SEC_INVERTINGINPUT_IO1 + +#define OPAMP_INVERTINGINPUT_VINM OPAMP_SEC_INVERTINGINPUT_IO1 + +#define OPAMP_PGACONNECT_NO OPAMP_PGA_CONNECT_INVERTINGINPUT_NO +#define OPAMP_PGACONNECT_VM0 OPAMP_PGA_CONNECT_INVERTINGINPUT_IO0 +#define OPAMP_PGACONNECT_VM1 OPAMP_PGA_CONNECT_INVERTINGINPUT_IO1 + +#if defined(STM32L1) || defined(STM32L4) +#define HAL_OPAMP_MSP_INIT_CB_ID HAL_OPAMP_MSPINIT_CB_ID +#define HAL_OPAMP_MSP_DEINIT_CB_ID HAL_OPAMP_MSPDEINIT_CB_ID +#endif + + +/** + * @} + */ + +/** @defgroup HAL_I2S_Aliased_Defines HAL I2S Aliased Defines maintained for legacy purpose + * @{ + */ +#define I2S_STANDARD_PHILLIPS I2S_STANDARD_PHILIPS + +#if defined(STM32H7) + #define I2S_IT_TXE I2S_IT_TXP + #define I2S_IT_RXNE I2S_IT_RXP + + #define I2S_FLAG_TXE I2S_FLAG_TXP + #define I2S_FLAG_RXNE I2S_FLAG_RXP +#endif + +#if defined(STM32F7) + #define I2S_CLOCK_SYSCLK I2S_CLOCK_PLL +#endif +/** + * @} + */ + +/** @defgroup HAL_PCCARD_Aliased_Defines HAL PCCARD Aliased Defines maintained for legacy purpose + * @{ + */ + +/* Compact Flash-ATA registers description */ +#define CF_DATA ATA_DATA +#define CF_SECTOR_COUNT ATA_SECTOR_COUNT +#define CF_SECTOR_NUMBER ATA_SECTOR_NUMBER +#define CF_CYLINDER_LOW ATA_CYLINDER_LOW +#define CF_CYLINDER_HIGH ATA_CYLINDER_HIGH +#define CF_CARD_HEAD ATA_CARD_HEAD +#define CF_STATUS_CMD ATA_STATUS_CMD +#define CF_STATUS_CMD_ALTERNATE ATA_STATUS_CMD_ALTERNATE +#define CF_COMMON_DATA_AREA ATA_COMMON_DATA_AREA + +/* Compact Flash-ATA commands */ +#define CF_READ_SECTOR_CMD ATA_READ_SECTOR_CMD +#define CF_WRITE_SECTOR_CMD ATA_WRITE_SECTOR_CMD +#define CF_ERASE_SECTOR_CMD ATA_ERASE_SECTOR_CMD +#define CF_IDENTIFY_CMD ATA_IDENTIFY_CMD + +#define PCCARD_StatusTypedef HAL_PCCARD_StatusTypeDef +#define PCCARD_SUCCESS HAL_PCCARD_STATUS_SUCCESS +#define PCCARD_ONGOING HAL_PCCARD_STATUS_ONGOING +#define PCCARD_ERROR HAL_PCCARD_STATUS_ERROR +#define PCCARD_TIMEOUT HAL_PCCARD_STATUS_TIMEOUT +/** + * @} + */ + +/** @defgroup HAL_RTC_Aliased_Defines HAL RTC Aliased Defines maintained for legacy purpose + * @{ + */ + +#define FORMAT_BIN RTC_FORMAT_BIN +#define FORMAT_BCD RTC_FORMAT_BCD + +#define RTC_ALARMSUBSECONDMASK_None RTC_ALARMSUBSECONDMASK_NONE +#define RTC_TAMPERERASEBACKUP_DISABLED RTC_TAMPER_ERASE_BACKUP_DISABLE +#define RTC_TAMPERMASK_FLAG_DISABLED RTC_TAMPERMASK_FLAG_DISABLE +#define RTC_TAMPERMASK_FLAG_ENABLED RTC_TAMPERMASK_FLAG_ENABLE + +#define RTC_MASKTAMPERFLAG_DISABLED RTC_TAMPERMASK_FLAG_DISABLE +#define RTC_MASKTAMPERFLAG_ENABLED RTC_TAMPERMASK_FLAG_ENABLE +#define RTC_TAMPERERASEBACKUP_ENABLED RTC_TAMPER_ERASE_BACKUP_ENABLE +#define RTC_TAMPER1_2_INTERRUPT RTC_ALL_TAMPER_INTERRUPT +#define RTC_TAMPER1_2_3_INTERRUPT RTC_ALL_TAMPER_INTERRUPT + +#define RTC_TIMESTAMPPIN_PC13 RTC_TIMESTAMPPIN_DEFAULT +#define RTC_TIMESTAMPPIN_PA0 RTC_TIMESTAMPPIN_POS1 +#define RTC_TIMESTAMPPIN_PI8 RTC_TIMESTAMPPIN_POS1 +#define RTC_TIMESTAMPPIN_PC1 RTC_TIMESTAMPPIN_POS2 + +#define RTC_OUTPUT_REMAP_PC13 RTC_OUTPUT_REMAP_NONE +#define RTC_OUTPUT_REMAP_PB14 RTC_OUTPUT_REMAP_POS1 +#define RTC_OUTPUT_REMAP_PB2 RTC_OUTPUT_REMAP_POS1 + +#define RTC_TAMPERPIN_PC13 RTC_TAMPERPIN_DEFAULT +#define RTC_TAMPERPIN_PA0 RTC_TAMPERPIN_POS1 +#define RTC_TAMPERPIN_PI8 RTC_TAMPERPIN_POS1 + +/** + * @} + */ + + +/** @defgroup HAL_SMARTCARD_Aliased_Defines HAL SMARTCARD Aliased Defines maintained for legacy purpose + * @{ + */ +#define SMARTCARD_NACK_ENABLED SMARTCARD_NACK_ENABLE +#define SMARTCARD_NACK_DISABLED SMARTCARD_NACK_DISABLE + +#define SMARTCARD_ONEBIT_SAMPLING_DISABLED SMARTCARD_ONE_BIT_SAMPLE_DISABLE +#define SMARTCARD_ONEBIT_SAMPLING_ENABLED SMARTCARD_ONE_BIT_SAMPLE_ENABLE +#define SMARTCARD_ONEBIT_SAMPLING_DISABLE SMARTCARD_ONE_BIT_SAMPLE_DISABLE +#define SMARTCARD_ONEBIT_SAMPLING_ENABLE SMARTCARD_ONE_BIT_SAMPLE_ENABLE + +#define SMARTCARD_TIMEOUT_DISABLED SMARTCARD_TIMEOUT_DISABLE +#define SMARTCARD_TIMEOUT_ENABLED SMARTCARD_TIMEOUT_ENABLE + +#define SMARTCARD_LASTBIT_DISABLED SMARTCARD_LASTBIT_DISABLE +#define SMARTCARD_LASTBIT_ENABLED SMARTCARD_LASTBIT_ENABLE +/** + * @} + */ + + +/** @defgroup HAL_SMBUS_Aliased_Defines HAL SMBUS Aliased Defines maintained for legacy purpose + * @{ + */ +#define SMBUS_DUALADDRESS_DISABLED SMBUS_DUALADDRESS_DISABLE +#define SMBUS_DUALADDRESS_ENABLED SMBUS_DUALADDRESS_ENABLE +#define SMBUS_GENERALCALL_DISABLED SMBUS_GENERALCALL_DISABLE +#define SMBUS_GENERALCALL_ENABLED SMBUS_GENERALCALL_ENABLE +#define SMBUS_NOSTRETCH_DISABLED SMBUS_NOSTRETCH_DISABLE +#define SMBUS_NOSTRETCH_ENABLED SMBUS_NOSTRETCH_ENABLE +#define SMBUS_ANALOGFILTER_ENABLED SMBUS_ANALOGFILTER_ENABLE +#define SMBUS_ANALOGFILTER_DISABLED SMBUS_ANALOGFILTER_DISABLE +#define SMBUS_PEC_DISABLED SMBUS_PEC_DISABLE +#define SMBUS_PEC_ENABLED SMBUS_PEC_ENABLE +#define HAL_SMBUS_STATE_SLAVE_LISTEN HAL_SMBUS_STATE_LISTEN +/** + * @} + */ + +/** @defgroup HAL_SPI_Aliased_Defines HAL SPI Aliased Defines maintained for legacy purpose + * @{ + */ +#define SPI_TIMODE_DISABLED SPI_TIMODE_DISABLE +#define SPI_TIMODE_ENABLED SPI_TIMODE_ENABLE + +#define SPI_CRCCALCULATION_DISABLED SPI_CRCCALCULATION_DISABLE +#define SPI_CRCCALCULATION_ENABLED SPI_CRCCALCULATION_ENABLE + +#define SPI_NSS_PULSE_DISABLED SPI_NSS_PULSE_DISABLE +#define SPI_NSS_PULSE_ENABLED SPI_NSS_PULSE_ENABLE + +#if defined(STM32H7) + + #define SPI_FLAG_TXE SPI_FLAG_TXP + #define SPI_FLAG_RXNE SPI_FLAG_RXP + + #define SPI_IT_TXE SPI_IT_TXP + #define SPI_IT_RXNE SPI_IT_RXP + + #define SPI_FRLVL_EMPTY SPI_RX_FIFO_0PACKET + #define SPI_FRLVL_QUARTER_FULL SPI_RX_FIFO_1PACKET + #define SPI_FRLVL_HALF_FULL SPI_RX_FIFO_2PACKET + #define SPI_FRLVL_FULL SPI_RX_FIFO_3PACKET + +#endif /* STM32H7 */ + +/** + * @} + */ + +/** @defgroup HAL_TIM_Aliased_Defines HAL TIM Aliased Defines maintained for legacy purpose + * @{ + */ +#define CCER_CCxE_MASK TIM_CCER_CCxE_MASK +#define CCER_CCxNE_MASK TIM_CCER_CCxNE_MASK + +#define TIM_DMABase_CR1 TIM_DMABASE_CR1 +#define TIM_DMABase_CR2 TIM_DMABASE_CR2 +#define TIM_DMABase_SMCR TIM_DMABASE_SMCR +#define TIM_DMABase_DIER TIM_DMABASE_DIER +#define TIM_DMABase_SR TIM_DMABASE_SR +#define TIM_DMABase_EGR TIM_DMABASE_EGR +#define TIM_DMABase_CCMR1 TIM_DMABASE_CCMR1 +#define TIM_DMABase_CCMR2 TIM_DMABASE_CCMR2 +#define TIM_DMABase_CCER TIM_DMABASE_CCER +#define TIM_DMABase_CNT TIM_DMABASE_CNT +#define TIM_DMABase_PSC TIM_DMABASE_PSC +#define TIM_DMABase_ARR TIM_DMABASE_ARR +#define TIM_DMABase_RCR TIM_DMABASE_RCR +#define TIM_DMABase_CCR1 TIM_DMABASE_CCR1 +#define TIM_DMABase_CCR2 TIM_DMABASE_CCR2 +#define TIM_DMABase_CCR3 TIM_DMABASE_CCR3 +#define TIM_DMABase_CCR4 TIM_DMABASE_CCR4 +#define TIM_DMABase_BDTR TIM_DMABASE_BDTR +#define TIM_DMABase_DCR TIM_DMABASE_DCR +#define TIM_DMABase_DMAR TIM_DMABASE_DMAR +#define TIM_DMABase_OR1 TIM_DMABASE_OR1 +#define TIM_DMABase_CCMR3 TIM_DMABASE_CCMR3 +#define TIM_DMABase_CCR5 TIM_DMABASE_CCR5 +#define TIM_DMABase_CCR6 TIM_DMABASE_CCR6 +#define TIM_DMABase_OR2 TIM_DMABASE_OR2 +#define TIM_DMABase_OR3 TIM_DMABASE_OR3 +#define TIM_DMABase_OR TIM_DMABASE_OR + +#define TIM_EventSource_Update TIM_EVENTSOURCE_UPDATE +#define TIM_EventSource_CC1 TIM_EVENTSOURCE_CC1 +#define TIM_EventSource_CC2 TIM_EVENTSOURCE_CC2 +#define TIM_EventSource_CC3 TIM_EVENTSOURCE_CC3 +#define TIM_EventSource_CC4 TIM_EVENTSOURCE_CC4 +#define TIM_EventSource_COM TIM_EVENTSOURCE_COM +#define TIM_EventSource_Trigger TIM_EVENTSOURCE_TRIGGER +#define TIM_EventSource_Break TIM_EVENTSOURCE_BREAK +#define TIM_EventSource_Break2 TIM_EVENTSOURCE_BREAK2 + +#define TIM_DMABurstLength_1Transfer TIM_DMABURSTLENGTH_1TRANSFER +#define TIM_DMABurstLength_2Transfers TIM_DMABURSTLENGTH_2TRANSFERS +#define TIM_DMABurstLength_3Transfers TIM_DMABURSTLENGTH_3TRANSFERS +#define TIM_DMABurstLength_4Transfers TIM_DMABURSTLENGTH_4TRANSFERS +#define TIM_DMABurstLength_5Transfers TIM_DMABURSTLENGTH_5TRANSFERS +#define TIM_DMABurstLength_6Transfers TIM_DMABURSTLENGTH_6TRANSFERS +#define TIM_DMABurstLength_7Transfers TIM_DMABURSTLENGTH_7TRANSFERS +#define TIM_DMABurstLength_8Transfers TIM_DMABURSTLENGTH_8TRANSFERS +#define TIM_DMABurstLength_9Transfers TIM_DMABURSTLENGTH_9TRANSFERS +#define TIM_DMABurstLength_10Transfers TIM_DMABURSTLENGTH_10TRANSFERS +#define TIM_DMABurstLength_11Transfers TIM_DMABURSTLENGTH_11TRANSFERS +#define TIM_DMABurstLength_12Transfers TIM_DMABURSTLENGTH_12TRANSFERS +#define TIM_DMABurstLength_13Transfers TIM_DMABURSTLENGTH_13TRANSFERS +#define TIM_DMABurstLength_14Transfers TIM_DMABURSTLENGTH_14TRANSFERS +#define TIM_DMABurstLength_15Transfers TIM_DMABURSTLENGTH_15TRANSFERS +#define TIM_DMABurstLength_16Transfers TIM_DMABURSTLENGTH_16TRANSFERS +#define TIM_DMABurstLength_17Transfers TIM_DMABURSTLENGTH_17TRANSFERS +#define TIM_DMABurstLength_18Transfers TIM_DMABURSTLENGTH_18TRANSFERS + +#if defined(STM32L0) +#define TIM22_TI1_GPIO1 TIM22_TI1_GPIO +#define TIM22_TI1_GPIO2 TIM22_TI1_GPIO +#endif + +#if defined(STM32F3) +#define IS_TIM_HALL_INTERFACE_INSTANCE IS_TIM_HALL_SENSOR_INTERFACE_INSTANCE +#endif + +#if defined(STM32H7) +#define TIM_TIM1_ETR_COMP1_OUT TIM_TIM1_ETR_COMP1 +#define TIM_TIM1_ETR_COMP2_OUT TIM_TIM1_ETR_COMP2 +#define TIM_TIM8_ETR_COMP1_OUT TIM_TIM8_ETR_COMP1 +#define TIM_TIM8_ETR_COMP2_OUT TIM_TIM8_ETR_COMP2 +#define TIM_TIM2_ETR_COMP1_OUT TIM_TIM2_ETR_COMP1 +#define TIM_TIM2_ETR_COMP2_OUT TIM_TIM2_ETR_COMP2 +#define TIM_TIM3_ETR_COMP1_OUT TIM_TIM3_ETR_COMP1 +#define TIM_TIM1_TI1_COMP1_OUT TIM_TIM1_TI1_COMP1 +#define TIM_TIM8_TI1_COMP2_OUT TIM_TIM8_TI1_COMP2 +#define TIM_TIM2_TI4_COMP1_OUT TIM_TIM2_TI4_COMP1 +#define TIM_TIM2_TI4_COMP2_OUT TIM_TIM2_TI4_COMP2 +#define TIM_TIM2_TI4_COMP1COMP2_OUT TIM_TIM2_TI4_COMP1_COMP2 +#define TIM_TIM3_TI1_COMP1_OUT TIM_TIM3_TI1_COMP1 +#define TIM_TIM3_TI1_COMP2_OUT TIM_TIM3_TI1_COMP2 +#define TIM_TIM3_TI1_COMP1COMP2_OUT TIM_TIM3_TI1_COMP1_COMP2 +#endif + +/** + * @} + */ + +/** @defgroup HAL_TSC_Aliased_Defines HAL TSC Aliased Defines maintained for legacy purpose + * @{ + */ +#define TSC_SYNC_POL_FALL TSC_SYNC_POLARITY_FALLING +#define TSC_SYNC_POL_RISE_HIGH TSC_SYNC_POLARITY_RISING +/** + * @} + */ + +/** @defgroup HAL_UART_Aliased_Defines HAL UART Aliased Defines maintained for legacy purpose + * @{ + */ +#define UART_ONEBIT_SAMPLING_DISABLED UART_ONE_BIT_SAMPLE_DISABLE +#define UART_ONEBIT_SAMPLING_ENABLED UART_ONE_BIT_SAMPLE_ENABLE +#define UART_ONE_BIT_SAMPLE_DISABLED UART_ONE_BIT_SAMPLE_DISABLE +#define UART_ONE_BIT_SAMPLE_ENABLED UART_ONE_BIT_SAMPLE_ENABLE + +#define __HAL_UART_ONEBIT_ENABLE __HAL_UART_ONE_BIT_SAMPLE_ENABLE +#define __HAL_UART_ONEBIT_DISABLE __HAL_UART_ONE_BIT_SAMPLE_DISABLE + +#define __DIV_SAMPLING16 UART_DIV_SAMPLING16 +#define __DIVMANT_SAMPLING16 UART_DIVMANT_SAMPLING16 +#define __DIVFRAQ_SAMPLING16 UART_DIVFRAQ_SAMPLING16 +#define __UART_BRR_SAMPLING16 UART_BRR_SAMPLING16 + +#define __DIV_SAMPLING8 UART_DIV_SAMPLING8 +#define __DIVMANT_SAMPLING8 UART_DIVMANT_SAMPLING8 +#define __DIVFRAQ_SAMPLING8 UART_DIVFRAQ_SAMPLING8 +#define __UART_BRR_SAMPLING8 UART_BRR_SAMPLING8 + +#define __DIV_LPUART UART_DIV_LPUART + +#define UART_WAKEUPMETHODE_IDLELINE UART_WAKEUPMETHOD_IDLELINE +#define UART_WAKEUPMETHODE_ADDRESSMARK UART_WAKEUPMETHOD_ADDRESSMARK + +/** + * @} + */ + + +/** @defgroup HAL_USART_Aliased_Defines HAL USART Aliased Defines maintained for legacy purpose + * @{ + */ + +#define USART_CLOCK_DISABLED USART_CLOCK_DISABLE +#define USART_CLOCK_ENABLED USART_CLOCK_ENABLE + +#define USARTNACK_ENABLED USART_NACK_ENABLE +#define USARTNACK_DISABLED USART_NACK_DISABLE +/** + * @} + */ + +/** @defgroup HAL_WWDG_Aliased_Defines HAL WWDG Aliased Defines maintained for legacy purpose + * @{ + */ +#define CFR_BASE WWDG_CFR_BASE + +/** + * @} + */ + +/** @defgroup HAL_CAN_Aliased_Defines HAL CAN Aliased Defines maintained for legacy purpose + * @{ + */ +#define CAN_FilterFIFO0 CAN_FILTER_FIFO0 +#define CAN_FilterFIFO1 CAN_FILTER_FIFO1 +#define CAN_IT_RQCP0 CAN_IT_TME +#define CAN_IT_RQCP1 CAN_IT_TME +#define CAN_IT_RQCP2 CAN_IT_TME +#define INAK_TIMEOUT CAN_TIMEOUT_VALUE +#define SLAK_TIMEOUT CAN_TIMEOUT_VALUE +#define CAN_TXSTATUS_FAILED ((uint8_t)0x00U) +#define CAN_TXSTATUS_OK ((uint8_t)0x01U) +#define CAN_TXSTATUS_PENDING ((uint8_t)0x02U) + +/** + * @} + */ + +/** @defgroup HAL_ETH_Aliased_Defines HAL ETH Aliased Defines maintained for legacy purpose + * @{ + */ + +#define VLAN_TAG ETH_VLAN_TAG +#define MIN_ETH_PAYLOAD ETH_MIN_ETH_PAYLOAD +#define MAX_ETH_PAYLOAD ETH_MAX_ETH_PAYLOAD +#define JUMBO_FRAME_PAYLOAD ETH_JUMBO_FRAME_PAYLOAD +#define MACMIIAR_CR_MASK ETH_MACMIIAR_CR_MASK +#define MACCR_CLEAR_MASK ETH_MACCR_CLEAR_MASK +#define MACFCR_CLEAR_MASK ETH_MACFCR_CLEAR_MASK +#define DMAOMR_CLEAR_MASK ETH_DMAOMR_CLEAR_MASK + +#define ETH_MMCCR 0x00000100U +#define ETH_MMCRIR 0x00000104U +#define ETH_MMCTIR 0x00000108U +#define ETH_MMCRIMR 0x0000010CU +#define ETH_MMCTIMR 0x00000110U +#define ETH_MMCTGFSCCR 0x0000014CU +#define ETH_MMCTGFMSCCR 0x00000150U +#define ETH_MMCTGFCR 0x00000168U +#define ETH_MMCRFCECR 0x00000194U +#define ETH_MMCRFAECR 0x00000198U +#define ETH_MMCRGUFCR 0x000001C4U + +#define ETH_MAC_TXFIFO_FULL 0x02000000U /* Tx FIFO full */ +#define ETH_MAC_TXFIFONOT_EMPTY 0x01000000U /* Tx FIFO not empty */ +#define ETH_MAC_TXFIFO_WRITE_ACTIVE 0x00400000U /* Tx FIFO write active */ +#define ETH_MAC_TXFIFO_IDLE 0x00000000U /* Tx FIFO read status: Idle */ +#define ETH_MAC_TXFIFO_READ 0x00100000U /* Tx FIFO read status: Read (transferring data to the MAC transmitter) */ +#define ETH_MAC_TXFIFO_WAITING 0x00200000U /* Tx FIFO read status: Waiting for TxStatus from MAC transmitter */ +#define ETH_MAC_TXFIFO_WRITING 0x00300000U /* Tx FIFO read status: Writing the received TxStatus or flushing the TxFIFO */ +#define ETH_MAC_TRANSMISSION_PAUSE 0x00080000U /* MAC transmitter in pause */ +#define ETH_MAC_TRANSMITFRAMECONTROLLER_IDLE 0x00000000U /* MAC transmit frame controller: Idle */ +#define ETH_MAC_TRANSMITFRAMECONTROLLER_WAITING 0x00020000U /* MAC transmit frame controller: Waiting for Status of previous frame or IFG/backoff period to be over */ +#define ETH_MAC_TRANSMITFRAMECONTROLLER_GENRATING_PCF 0x00040000U /* MAC transmit frame controller: Generating and transmitting a Pause control frame (in full duplex mode) */ +#define ETH_MAC_TRANSMITFRAMECONTROLLER_TRANSFERRING 0x00060000U /* MAC transmit frame controller: Transferring input frame for transmission */ +#define ETH_MAC_MII_TRANSMIT_ACTIVE 0x00010000U /* MAC MII transmit engine active */ +#define ETH_MAC_RXFIFO_EMPTY 0x00000000U /* Rx FIFO fill level: empty */ +#define ETH_MAC_RXFIFO_BELOW_THRESHOLD 0x00000100U /* Rx FIFO fill level: fill-level below flow-control de-activate threshold */ +#define ETH_MAC_RXFIFO_ABOVE_THRESHOLD 0x00000200U /* Rx FIFO fill level: fill-level above flow-control activate threshold */ +#define ETH_MAC_RXFIFO_FULL 0x00000300U /* Rx FIFO fill level: full */ +#if defined(STM32F1) +#else +#define ETH_MAC_READCONTROLLER_IDLE 0x00000000U /* Rx FIFO read controller IDLE state */ +#define ETH_MAC_READCONTROLLER_READING_DATA 0x00000020U /* Rx FIFO read controller Reading frame data */ +#define ETH_MAC_READCONTROLLER_READING_STATUS 0x00000040U /* Rx FIFO read controller Reading frame status (or time-stamp) */ +#endif +#define ETH_MAC_READCONTROLLER_FLUSHING 0x00000060U /* Rx FIFO read controller Flushing the frame data and status */ +#define ETH_MAC_RXFIFO_WRITE_ACTIVE 0x00000010U /* Rx FIFO write controller active */ +#define ETH_MAC_SMALL_FIFO_NOTACTIVE 0x00000000U /* MAC small FIFO read / write controllers not active */ +#define ETH_MAC_SMALL_FIFO_READ_ACTIVE 0x00000002U /* MAC small FIFO read controller active */ +#define ETH_MAC_SMALL_FIFO_WRITE_ACTIVE 0x00000004U /* MAC small FIFO write controller active */ +#define ETH_MAC_SMALL_FIFO_RW_ACTIVE 0x00000006U /* MAC small FIFO read / write controllers active */ +#define ETH_MAC_MII_RECEIVE_PROTOCOL_ACTIVE 0x00000001U /* MAC MII receive protocol engine active */ + +/** + * @} + */ + +/** @defgroup HAL_DCMI_Aliased_Defines HAL DCMI Aliased Defines maintained for legacy purpose + * @{ + */ +#define HAL_DCMI_ERROR_OVF HAL_DCMI_ERROR_OVR +#define DCMI_IT_OVF DCMI_IT_OVR +#define DCMI_FLAG_OVFRI DCMI_FLAG_OVRRI +#define DCMI_FLAG_OVFMI DCMI_FLAG_OVRMI + +#define HAL_DCMI_ConfigCROP HAL_DCMI_ConfigCrop +#define HAL_DCMI_EnableCROP HAL_DCMI_EnableCrop +#define HAL_DCMI_DisableCROP HAL_DCMI_DisableCrop + +/** + * @} + */ + +#if defined(STM32L4) || defined(STM32F7) || defined(STM32F427xx) || defined(STM32F437xx) \ + || defined(STM32F429xx) || defined(STM32F439xx) || defined(STM32F469xx) || defined(STM32F479xx) \ + || defined(STM32H7) +/** @defgroup HAL_DMA2D_Aliased_Defines HAL DMA2D Aliased Defines maintained for legacy purpose + * @{ + */ +#define DMA2D_ARGB8888 DMA2D_OUTPUT_ARGB8888 +#define DMA2D_RGB888 DMA2D_OUTPUT_RGB888 +#define DMA2D_RGB565 DMA2D_OUTPUT_RGB565 +#define DMA2D_ARGB1555 DMA2D_OUTPUT_ARGB1555 +#define DMA2D_ARGB4444 DMA2D_OUTPUT_ARGB4444 + +#define CM_ARGB8888 DMA2D_INPUT_ARGB8888 +#define CM_RGB888 DMA2D_INPUT_RGB888 +#define CM_RGB565 DMA2D_INPUT_RGB565 +#define CM_ARGB1555 DMA2D_INPUT_ARGB1555 +#define CM_ARGB4444 DMA2D_INPUT_ARGB4444 +#define CM_L8 DMA2D_INPUT_L8 +#define CM_AL44 DMA2D_INPUT_AL44 +#define CM_AL88 DMA2D_INPUT_AL88 +#define CM_L4 DMA2D_INPUT_L4 +#define CM_A8 DMA2D_INPUT_A8 +#define CM_A4 DMA2D_INPUT_A4 +/** + * @} + */ +#endif /* STM32L4 || STM32F7 || STM32F4 || STM32H7 */ + +/** @defgroup HAL_PPP_Aliased_Defines HAL PPP Aliased Defines maintained for legacy purpose + * @{ + */ + +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ + +/** @defgroup HAL_CRYP_Aliased_Functions HAL CRYP Aliased Functions maintained for legacy purpose + * @{ + */ +#define HAL_CRYP_ComputationCpltCallback HAL_CRYPEx_ComputationCpltCallback +/** + * @} + */ + +/** @defgroup HAL_HASH_Aliased_Functions HAL HASH Aliased Functions maintained for legacy purpose + * @{ + */ +#define HAL_HASH_STATETypeDef HAL_HASH_StateTypeDef +#define HAL_HASHPhaseTypeDef HAL_HASH_PhaseTypeDef +#define HAL_HMAC_MD5_Finish HAL_HASH_MD5_Finish +#define HAL_HMAC_SHA1_Finish HAL_HASH_SHA1_Finish +#define HAL_HMAC_SHA224_Finish HAL_HASH_SHA224_Finish +#define HAL_HMAC_SHA256_Finish HAL_HASH_SHA256_Finish + +/*HASH Algorithm Selection*/ + +#define HASH_AlgoSelection_SHA1 HASH_ALGOSELECTION_SHA1 +#define HASH_AlgoSelection_SHA224 HASH_ALGOSELECTION_SHA224 +#define HASH_AlgoSelection_SHA256 HASH_ALGOSELECTION_SHA256 +#define HASH_AlgoSelection_MD5 HASH_ALGOSELECTION_MD5 + +#define HASH_AlgoMode_HASH HASH_ALGOMODE_HASH +#define HASH_AlgoMode_HMAC HASH_ALGOMODE_HMAC + +#define HASH_HMACKeyType_ShortKey HASH_HMAC_KEYTYPE_SHORTKEY +#define HASH_HMACKeyType_LongKey HASH_HMAC_KEYTYPE_LONGKEY +/** + * @} + */ + +/** @defgroup HAL_Aliased_Functions HAL Generic Aliased Functions maintained for legacy purpose + * @{ + */ +#define HAL_EnableDBGSleepMode HAL_DBGMCU_EnableDBGSleepMode +#define HAL_DisableDBGSleepMode HAL_DBGMCU_DisableDBGSleepMode +#define HAL_EnableDBGStopMode HAL_DBGMCU_EnableDBGStopMode +#define HAL_DisableDBGStopMode HAL_DBGMCU_DisableDBGStopMode +#define HAL_EnableDBGStandbyMode HAL_DBGMCU_EnableDBGStandbyMode +#define HAL_DisableDBGStandbyMode HAL_DBGMCU_DisableDBGStandbyMode +#define HAL_DBG_LowPowerConfig(Periph, cmd) (((cmd)==ENABLE)? HAL_DBGMCU_DBG_EnableLowPowerConfig(Periph) : HAL_DBGMCU_DBG_DisableLowPowerConfig(Periph)) +#define HAL_VREFINT_OutputSelect HAL_SYSCFG_VREFINT_OutputSelect +#define HAL_Lock_Cmd(cmd) (((cmd)==ENABLE) ? HAL_SYSCFG_Enable_Lock_VREFINT() : HAL_SYSCFG_Disable_Lock_VREFINT()) +#if defined(STM32L0) +#else +#define HAL_VREFINT_Cmd(cmd) (((cmd)==ENABLE)? HAL_SYSCFG_EnableVREFINT() : HAL_SYSCFG_DisableVREFINT()) +#endif +#define HAL_ADC_EnableBuffer_Cmd(cmd) (((cmd)==ENABLE) ? HAL_ADCEx_EnableVREFINT() : HAL_ADCEx_DisableVREFINT()) +#define HAL_ADC_EnableBufferSensor_Cmd(cmd) (((cmd)==ENABLE) ? HAL_ADCEx_EnableVREFINTTempSensor() : HAL_ADCEx_DisableVREFINTTempSensor()) +/** + * @} + */ + +/** @defgroup HAL_FLASH_Aliased_Functions HAL FLASH Aliased Functions maintained for legacy purpose + * @{ + */ +#define FLASH_HalfPageProgram HAL_FLASHEx_HalfPageProgram +#define FLASH_EnableRunPowerDown HAL_FLASHEx_EnableRunPowerDown +#define FLASH_DisableRunPowerDown HAL_FLASHEx_DisableRunPowerDown +#define HAL_DATA_EEPROMEx_Unlock HAL_FLASHEx_DATAEEPROM_Unlock +#define HAL_DATA_EEPROMEx_Lock HAL_FLASHEx_DATAEEPROM_Lock +#define HAL_DATA_EEPROMEx_Erase HAL_FLASHEx_DATAEEPROM_Erase +#define HAL_DATA_EEPROMEx_Program HAL_FLASHEx_DATAEEPROM_Program + + /** + * @} + */ + +/** @defgroup HAL_I2C_Aliased_Functions HAL I2C Aliased Functions maintained for legacy purpose + * @{ + */ +#define HAL_I2CEx_AnalogFilter_Config HAL_I2CEx_ConfigAnalogFilter +#define HAL_I2CEx_DigitalFilter_Config HAL_I2CEx_ConfigDigitalFilter +#define HAL_FMPI2CEx_AnalogFilter_Config HAL_FMPI2CEx_ConfigAnalogFilter +#define HAL_FMPI2CEx_DigitalFilter_Config HAL_FMPI2CEx_ConfigDigitalFilter + +#define HAL_I2CFastModePlusConfig(SYSCFG_I2CFastModePlus, cmd) (((cmd)==ENABLE)? HAL_I2CEx_EnableFastModePlus(SYSCFG_I2CFastModePlus): HAL_I2CEx_DisableFastModePlus(SYSCFG_I2CFastModePlus)) + +#if defined(STM32H7) || defined(STM32WB) || defined(STM32G0) || defined(STM32F0) || defined(STM32F1) || defined(STM32F2) || defined(STM32F3) || defined(STM32F4) || defined(STM32F7) || defined(STM32L0) || defined(STM32L4) || defined(STM32L5) || defined(STM32G4) +#define HAL_I2C_Master_Sequential_Transmit_IT HAL_I2C_Master_Seq_Transmit_IT +#define HAL_I2C_Master_Sequential_Receive_IT HAL_I2C_Master_Seq_Receive_IT +#define HAL_I2C_Slave_Sequential_Transmit_IT HAL_I2C_Slave_Seq_Transmit_IT +#define HAL_I2C_Slave_Sequential_Receive_IT HAL_I2C_Slave_Seq_Receive_IT +#endif /* STM32H7 || STM32WB || STM32G0 || STM32F0 || STM32F1 || STM32F2 || STM32F3 || STM32F4 || STM32F7 || STM32L0 || STM32L4 || STM32L5 || STM32G4 */ +#if defined(STM32H7) || defined(STM32WB) || defined(STM32G0) || defined(STM32F4) || defined(STM32F7) || defined(STM32L0) || defined(STM32L4) || defined(STM32L5) || defined(STM32G4) +#define HAL_I2C_Master_Sequential_Transmit_DMA HAL_I2C_Master_Seq_Transmit_DMA +#define HAL_I2C_Master_Sequential_Receive_DMA HAL_I2C_Master_Seq_Receive_DMA +#define HAL_I2C_Slave_Sequential_Transmit_DMA HAL_I2C_Slave_Seq_Transmit_DMA +#define HAL_I2C_Slave_Sequential_Receive_DMA HAL_I2C_Slave_Seq_Receive_DMA +#endif /* STM32H7 || STM32WB || STM32G0 || STM32F4 || STM32F7 || STM32L0 || STM32L4 || STM32L5 || STM32G4 */ + +#if defined(STM32F4) +#define HAL_FMPI2C_Master_Sequential_Transmit_IT HAL_FMPI2C_Master_Seq_Transmit_IT +#define HAL_FMPI2C_Master_Sequential_Receive_IT HAL_FMPI2C_Master_Seq_Receive_IT +#define HAL_FMPI2C_Slave_Sequential_Transmit_IT HAL_FMPI2C_Slave_Seq_Transmit_IT +#define HAL_FMPI2C_Slave_Sequential_Receive_IT HAL_FMPI2C_Slave_Seq_Receive_IT +#define HAL_FMPI2C_Master_Sequential_Transmit_DMA HAL_FMPI2C_Master_Seq_Transmit_DMA +#define HAL_FMPI2C_Master_Sequential_Receive_DMA HAL_FMPI2C_Master_Seq_Receive_DMA +#define HAL_FMPI2C_Slave_Sequential_Transmit_DMA HAL_FMPI2C_Slave_Seq_Transmit_DMA +#define HAL_FMPI2C_Slave_Sequential_Receive_DMA HAL_FMPI2C_Slave_Seq_Receive_DMA +#endif /* STM32F4 */ + /** + * @} + */ + +/** @defgroup HAL_PWR_Aliased HAL PWR Aliased maintained for legacy purpose + * @{ + */ +#define HAL_PWR_PVDConfig HAL_PWR_ConfigPVD +#define HAL_PWR_DisableBkUpReg HAL_PWREx_DisableBkUpReg +#define HAL_PWR_DisableFlashPowerDown HAL_PWREx_DisableFlashPowerDown +#define HAL_PWR_DisableVddio2Monitor HAL_PWREx_DisableVddio2Monitor +#define HAL_PWR_EnableBkUpReg HAL_PWREx_EnableBkUpReg +#define HAL_PWR_EnableFlashPowerDown HAL_PWREx_EnableFlashPowerDown +#define HAL_PWR_EnableVddio2Monitor HAL_PWREx_EnableVddio2Monitor +#define HAL_PWR_PVD_PVM_IRQHandler HAL_PWREx_PVD_PVM_IRQHandler +#define HAL_PWR_PVDLevelConfig HAL_PWR_ConfigPVD +#define HAL_PWR_Vddio2Monitor_IRQHandler HAL_PWREx_Vddio2Monitor_IRQHandler +#define HAL_PWR_Vddio2MonitorCallback HAL_PWREx_Vddio2MonitorCallback +#define HAL_PWREx_ActivateOverDrive HAL_PWREx_EnableOverDrive +#define HAL_PWREx_DeactivateOverDrive HAL_PWREx_DisableOverDrive +#define HAL_PWREx_DisableSDADCAnalog HAL_PWREx_DisableSDADC +#define HAL_PWREx_EnableSDADCAnalog HAL_PWREx_EnableSDADC +#define HAL_PWREx_PVMConfig HAL_PWREx_ConfigPVM + +#define PWR_MODE_NORMAL PWR_PVD_MODE_NORMAL +#define PWR_MODE_IT_RISING PWR_PVD_MODE_IT_RISING +#define PWR_MODE_IT_FALLING PWR_PVD_MODE_IT_FALLING +#define PWR_MODE_IT_RISING_FALLING PWR_PVD_MODE_IT_RISING_FALLING +#define PWR_MODE_EVENT_RISING PWR_PVD_MODE_EVENT_RISING +#define PWR_MODE_EVENT_FALLING PWR_PVD_MODE_EVENT_FALLING +#define PWR_MODE_EVENT_RISING_FALLING PWR_PVD_MODE_EVENT_RISING_FALLING + +#define CR_OFFSET_BB PWR_CR_OFFSET_BB +#define CSR_OFFSET_BB PWR_CSR_OFFSET_BB +#define PMODE_BIT_NUMBER VOS_BIT_NUMBER +#define CR_PMODE_BB CR_VOS_BB + +#define DBP_BitNumber DBP_BIT_NUMBER +#define PVDE_BitNumber PVDE_BIT_NUMBER +#define PMODE_BitNumber PMODE_BIT_NUMBER +#define EWUP_BitNumber EWUP_BIT_NUMBER +#define FPDS_BitNumber FPDS_BIT_NUMBER +#define ODEN_BitNumber ODEN_BIT_NUMBER +#define ODSWEN_BitNumber ODSWEN_BIT_NUMBER +#define MRLVDS_BitNumber MRLVDS_BIT_NUMBER +#define LPLVDS_BitNumber LPLVDS_BIT_NUMBER +#define BRE_BitNumber BRE_BIT_NUMBER + +#define PWR_MODE_EVT PWR_PVD_MODE_NORMAL + + /** + * @} + */ + +/** @defgroup HAL_SMBUS_Aliased_Functions HAL SMBUS Aliased Functions maintained for legacy purpose + * @{ + */ +#define HAL_SMBUS_Slave_Listen_IT HAL_SMBUS_EnableListen_IT +#define HAL_SMBUS_SlaveAddrCallback HAL_SMBUS_AddrCallback +#define HAL_SMBUS_SlaveListenCpltCallback HAL_SMBUS_ListenCpltCallback +/** + * @} + */ + +/** @defgroup HAL_SPI_Aliased_Functions HAL SPI Aliased Functions maintained for legacy purpose + * @{ + */ +#define HAL_SPI_FlushRxFifo HAL_SPIEx_FlushRxFifo +/** + * @} + */ + +/** @defgroup HAL_TIM_Aliased_Functions HAL TIM Aliased Functions maintained for legacy purpose + * @{ + */ +#define HAL_TIM_DMADelayPulseCplt TIM_DMADelayPulseCplt +#define HAL_TIM_DMAError TIM_DMAError +#define HAL_TIM_DMACaptureCplt TIM_DMACaptureCplt +#define HAL_TIMEx_DMACommutationCplt TIMEx_DMACommutationCplt +#if defined(STM32H7) || defined(STM32G0) || defined(STM32F0) || defined(STM32F1) || defined(STM32F2) || defined(STM32F3) || defined(STM32F4) || defined(STM32F7) || defined(STM32L0) || defined(STM32L4) +#define HAL_TIM_SlaveConfigSynchronization HAL_TIM_SlaveConfigSynchro +#define HAL_TIM_SlaveConfigSynchronization_IT HAL_TIM_SlaveConfigSynchro_IT +#define HAL_TIMEx_CommutationCallback HAL_TIMEx_CommutCallback +#define HAL_TIMEx_ConfigCommutationEvent HAL_TIMEx_ConfigCommutEvent +#define HAL_TIMEx_ConfigCommutationEvent_IT HAL_TIMEx_ConfigCommutEvent_IT +#define HAL_TIMEx_ConfigCommutationEvent_DMA HAL_TIMEx_ConfigCommutEvent_DMA +#endif /* STM32H7 || STM32G0 || STM32F0 || STM32F1 || STM32F2 || STM32F3 || STM32F4 || STM32F7 || STM32L0 */ +/** + * @} + */ + +/** @defgroup HAL_UART_Aliased_Functions HAL UART Aliased Functions maintained for legacy purpose + * @{ + */ +#define HAL_UART_WakeupCallback HAL_UARTEx_WakeupCallback +/** + * @} + */ + +/** @defgroup HAL_LTDC_Aliased_Functions HAL LTDC Aliased Functions maintained for legacy purpose + * @{ + */ +#define HAL_LTDC_LineEvenCallback HAL_LTDC_LineEventCallback +#define HAL_LTDC_Relaod HAL_LTDC_Reload +#define HAL_LTDC_StructInitFromVideoConfig HAL_LTDCEx_StructInitFromVideoConfig +#define HAL_LTDC_StructInitFromAdaptedCommandConfig HAL_LTDCEx_StructInitFromAdaptedCommandConfig +/** + * @} + */ + + +/** @defgroup HAL_PPP_Aliased_Functions HAL PPP Aliased Functions maintained for legacy purpose + * @{ + */ + +/** + * @} + */ + +/* Exported macros ------------------------------------------------------------*/ + +/** @defgroup HAL_AES_Aliased_Macros HAL CRYP Aliased Macros maintained for legacy purpose + * @{ + */ +#define AES_IT_CC CRYP_IT_CC +#define AES_IT_ERR CRYP_IT_ERR +#define AES_FLAG_CCF CRYP_FLAG_CCF +/** + * @} + */ + +/** @defgroup HAL_Aliased_Macros HAL Generic Aliased Macros maintained for legacy purpose + * @{ + */ +#define __HAL_GET_BOOT_MODE __HAL_SYSCFG_GET_BOOT_MODE +#define __HAL_REMAPMEMORY_FLASH __HAL_SYSCFG_REMAPMEMORY_FLASH +#define __HAL_REMAPMEMORY_SYSTEMFLASH __HAL_SYSCFG_REMAPMEMORY_SYSTEMFLASH +#define __HAL_REMAPMEMORY_SRAM __HAL_SYSCFG_REMAPMEMORY_SRAM +#define __HAL_REMAPMEMORY_FMC __HAL_SYSCFG_REMAPMEMORY_FMC +#define __HAL_REMAPMEMORY_FMC_SDRAM __HAL_SYSCFG_REMAPMEMORY_FMC_SDRAM +#define __HAL_REMAPMEMORY_FSMC __HAL_SYSCFG_REMAPMEMORY_FSMC +#define __HAL_REMAPMEMORY_QUADSPI __HAL_SYSCFG_REMAPMEMORY_QUADSPI +#define __HAL_FMC_BANK __HAL_SYSCFG_FMC_BANK +#define __HAL_GET_FLAG __HAL_SYSCFG_GET_FLAG +#define __HAL_CLEAR_FLAG __HAL_SYSCFG_CLEAR_FLAG +#define __HAL_VREFINT_OUT_ENABLE __HAL_SYSCFG_VREFINT_OUT_ENABLE +#define __HAL_VREFINT_OUT_DISABLE __HAL_SYSCFG_VREFINT_OUT_DISABLE +#define __HAL_SYSCFG_SRAM2_WRP_ENABLE __HAL_SYSCFG_SRAM2_WRP_0_31_ENABLE + +#define SYSCFG_FLAG_VREF_READY SYSCFG_FLAG_VREFINT_READY +#define SYSCFG_FLAG_RC48 RCC_FLAG_HSI48 +#define IS_SYSCFG_FASTMODEPLUS_CONFIG IS_I2C_FASTMODEPLUS +#define UFB_MODE_BitNumber UFB_MODE_BIT_NUMBER +#define CMP_PD_BitNumber CMP_PD_BIT_NUMBER + +/** + * @} + */ + + +/** @defgroup HAL_ADC_Aliased_Macros HAL ADC Aliased Macros maintained for legacy purpose + * @{ + */ +#define __ADC_ENABLE __HAL_ADC_ENABLE +#define __ADC_DISABLE __HAL_ADC_DISABLE +#define __HAL_ADC_ENABLING_CONDITIONS ADC_ENABLING_CONDITIONS +#define __HAL_ADC_DISABLING_CONDITIONS ADC_DISABLING_CONDITIONS +#define __HAL_ADC_IS_ENABLED ADC_IS_ENABLE +#define __ADC_IS_ENABLED ADC_IS_ENABLE +#define __HAL_ADC_IS_SOFTWARE_START_REGULAR ADC_IS_SOFTWARE_START_REGULAR +#define __HAL_ADC_IS_SOFTWARE_START_INJECTED ADC_IS_SOFTWARE_START_INJECTED +#define __HAL_ADC_IS_CONVERSION_ONGOING_REGULAR_INJECTED ADC_IS_CONVERSION_ONGOING_REGULAR_INJECTED +#define __HAL_ADC_IS_CONVERSION_ONGOING_REGULAR ADC_IS_CONVERSION_ONGOING_REGULAR +#define __HAL_ADC_IS_CONVERSION_ONGOING_INJECTED ADC_IS_CONVERSION_ONGOING_INJECTED +#define __HAL_ADC_IS_CONVERSION_ONGOING ADC_IS_CONVERSION_ONGOING +#define __HAL_ADC_CLEAR_ERRORCODE ADC_CLEAR_ERRORCODE + +#define __HAL_ADC_GET_RESOLUTION ADC_GET_RESOLUTION +#define __HAL_ADC_JSQR_RK ADC_JSQR_RK +#define __HAL_ADC_CFGR_AWD1CH ADC_CFGR_AWD1CH_SHIFT +#define __HAL_ADC_CFGR_AWD23CR ADC_CFGR_AWD23CR +#define __HAL_ADC_CFGR_INJECT_AUTO_CONVERSION ADC_CFGR_INJECT_AUTO_CONVERSION +#define __HAL_ADC_CFGR_INJECT_CONTEXT_QUEUE ADC_CFGR_INJECT_CONTEXT_QUEUE +#define __HAL_ADC_CFGR_INJECT_DISCCONTINUOUS ADC_CFGR_INJECT_DISCCONTINUOUS +#define __HAL_ADC_CFGR_REG_DISCCONTINUOUS ADC_CFGR_REG_DISCCONTINUOUS +#define __HAL_ADC_CFGR_DISCONTINUOUS_NUM ADC_CFGR_DISCONTINUOUS_NUM +#define __HAL_ADC_CFGR_AUTOWAIT ADC_CFGR_AUTOWAIT +#define __HAL_ADC_CFGR_CONTINUOUS ADC_CFGR_CONTINUOUS +#define __HAL_ADC_CFGR_OVERRUN ADC_CFGR_OVERRUN +#define __HAL_ADC_CFGR_DMACONTREQ ADC_CFGR_DMACONTREQ +#define __HAL_ADC_CFGR_EXTSEL ADC_CFGR_EXTSEL_SET +#define __HAL_ADC_JSQR_JEXTSEL ADC_JSQR_JEXTSEL_SET +#define __HAL_ADC_OFR_CHANNEL ADC_OFR_CHANNEL +#define __HAL_ADC_DIFSEL_CHANNEL ADC_DIFSEL_CHANNEL +#define __HAL_ADC_CALFACT_DIFF_SET ADC_CALFACT_DIFF_SET +#define __HAL_ADC_CALFACT_DIFF_GET ADC_CALFACT_DIFF_GET +#define __HAL_ADC_TRX_HIGHTHRESHOLD ADC_TRX_HIGHTHRESHOLD + +#define __HAL_ADC_OFFSET_SHIFT_RESOLUTION ADC_OFFSET_SHIFT_RESOLUTION +#define __HAL_ADC_AWD1THRESHOLD_SHIFT_RESOLUTION ADC_AWD1THRESHOLD_SHIFT_RESOLUTION +#define __HAL_ADC_AWD23THRESHOLD_SHIFT_RESOLUTION ADC_AWD23THRESHOLD_SHIFT_RESOLUTION +#define __HAL_ADC_COMMON_REGISTER ADC_COMMON_REGISTER +#define __HAL_ADC_COMMON_CCR_MULTI ADC_COMMON_CCR_MULTI +#define __HAL_ADC_MULTIMODE_IS_ENABLED ADC_MULTIMODE_IS_ENABLE +#define __ADC_MULTIMODE_IS_ENABLED ADC_MULTIMODE_IS_ENABLE +#define __HAL_ADC_NONMULTIMODE_OR_MULTIMODEMASTER ADC_NONMULTIMODE_OR_MULTIMODEMASTER +#define __HAL_ADC_COMMON_ADC_OTHER ADC_COMMON_ADC_OTHER +#define __HAL_ADC_MULTI_SLAVE ADC_MULTI_SLAVE + +#define __HAL_ADC_SQR1_L ADC_SQR1_L_SHIFT +#define __HAL_ADC_JSQR_JL ADC_JSQR_JL_SHIFT +#define __HAL_ADC_JSQR_RK_JL ADC_JSQR_RK_JL +#define __HAL_ADC_CR1_DISCONTINUOUS_NUM ADC_CR1_DISCONTINUOUS_NUM +#define __HAL_ADC_CR1_SCAN ADC_CR1_SCAN_SET +#define __HAL_ADC_CONVCYCLES_MAX_RANGE ADC_CONVCYCLES_MAX_RANGE +#define __HAL_ADC_CLOCK_PRESCALER_RANGE ADC_CLOCK_PRESCALER_RANGE +#define __HAL_ADC_GET_CLOCK_PRESCALER ADC_GET_CLOCK_PRESCALER + +#define __HAL_ADC_SQR1 ADC_SQR1 +#define __HAL_ADC_SMPR1 ADC_SMPR1 +#define __HAL_ADC_SMPR2 ADC_SMPR2 +#define __HAL_ADC_SQR3_RK ADC_SQR3_RK +#define __HAL_ADC_SQR2_RK ADC_SQR2_RK +#define __HAL_ADC_SQR1_RK ADC_SQR1_RK +#define __HAL_ADC_CR2_CONTINUOUS ADC_CR2_CONTINUOUS +#define __HAL_ADC_CR1_DISCONTINUOUS ADC_CR1_DISCONTINUOUS +#define __HAL_ADC_CR1_SCANCONV ADC_CR1_SCANCONV +#define __HAL_ADC_CR2_EOCSelection ADC_CR2_EOCSelection +#define __HAL_ADC_CR2_DMAContReq ADC_CR2_DMAContReq +#define __HAL_ADC_JSQR ADC_JSQR + +#define __HAL_ADC_CHSELR_CHANNEL ADC_CHSELR_CHANNEL +#define __HAL_ADC_CFGR1_REG_DISCCONTINUOUS ADC_CFGR1_REG_DISCCONTINUOUS +#define __HAL_ADC_CFGR1_AUTOOFF ADC_CFGR1_AUTOOFF +#define __HAL_ADC_CFGR1_AUTOWAIT ADC_CFGR1_AUTOWAIT +#define __HAL_ADC_CFGR1_CONTINUOUS ADC_CFGR1_CONTINUOUS +#define __HAL_ADC_CFGR1_OVERRUN ADC_CFGR1_OVERRUN +#define __HAL_ADC_CFGR1_SCANDIR ADC_CFGR1_SCANDIR +#define __HAL_ADC_CFGR1_DMACONTREQ ADC_CFGR1_DMACONTREQ + +/** + * @} + */ + +/** @defgroup HAL_DAC_Aliased_Macros HAL DAC Aliased Macros maintained for legacy purpose + * @{ + */ +#define __HAL_DHR12R1_ALIGNEMENT DAC_DHR12R1_ALIGNMENT +#define __HAL_DHR12R2_ALIGNEMENT DAC_DHR12R2_ALIGNMENT +#define __HAL_DHR12RD_ALIGNEMENT DAC_DHR12RD_ALIGNMENT +#define IS_DAC_GENERATE_WAVE IS_DAC_WAVE + +/** + * @} + */ + +/** @defgroup HAL_DBGMCU_Aliased_Macros HAL DBGMCU Aliased Macros maintained for legacy purpose + * @{ + */ +#define __HAL_FREEZE_TIM1_DBGMCU __HAL_DBGMCU_FREEZE_TIM1 +#define __HAL_UNFREEZE_TIM1_DBGMCU __HAL_DBGMCU_UNFREEZE_TIM1 +#define __HAL_FREEZE_TIM2_DBGMCU __HAL_DBGMCU_FREEZE_TIM2 +#define __HAL_UNFREEZE_TIM2_DBGMCU __HAL_DBGMCU_UNFREEZE_TIM2 +#define __HAL_FREEZE_TIM3_DBGMCU __HAL_DBGMCU_FREEZE_TIM3 +#define __HAL_UNFREEZE_TIM3_DBGMCU __HAL_DBGMCU_UNFREEZE_TIM3 +#define __HAL_FREEZE_TIM4_DBGMCU __HAL_DBGMCU_FREEZE_TIM4 +#define __HAL_UNFREEZE_TIM4_DBGMCU __HAL_DBGMCU_UNFREEZE_TIM4 +#define __HAL_FREEZE_TIM5_DBGMCU __HAL_DBGMCU_FREEZE_TIM5 +#define __HAL_UNFREEZE_TIM5_DBGMCU __HAL_DBGMCU_UNFREEZE_TIM5 +#define __HAL_FREEZE_TIM6_DBGMCU __HAL_DBGMCU_FREEZE_TIM6 +#define __HAL_UNFREEZE_TIM6_DBGMCU __HAL_DBGMCU_UNFREEZE_TIM6 +#define __HAL_FREEZE_TIM7_DBGMCU __HAL_DBGMCU_FREEZE_TIM7 +#define __HAL_UNFREEZE_TIM7_DBGMCU __HAL_DBGMCU_UNFREEZE_TIM7 +#define __HAL_FREEZE_TIM8_DBGMCU __HAL_DBGMCU_FREEZE_TIM8 +#define __HAL_UNFREEZE_TIM8_DBGMCU __HAL_DBGMCU_UNFREEZE_TIM8 + +#define __HAL_FREEZE_TIM9_DBGMCU __HAL_DBGMCU_FREEZE_TIM9 +#define __HAL_UNFREEZE_TIM9_DBGMCU __HAL_DBGMCU_UNFREEZE_TIM9 +#define __HAL_FREEZE_TIM10_DBGMCU __HAL_DBGMCU_FREEZE_TIM10 +#define __HAL_UNFREEZE_TIM10_DBGMCU __HAL_DBGMCU_UNFREEZE_TIM10 +#define __HAL_FREEZE_TIM11_DBGMCU __HAL_DBGMCU_FREEZE_TIM11 +#define __HAL_UNFREEZE_TIM11_DBGMCU __HAL_DBGMCU_UNFREEZE_TIM11 +#define __HAL_FREEZE_TIM12_DBGMCU __HAL_DBGMCU_FREEZE_TIM12 +#define __HAL_UNFREEZE_TIM12_DBGMCU __HAL_DBGMCU_UNFREEZE_TIM12 +#define __HAL_FREEZE_TIM13_DBGMCU __HAL_DBGMCU_FREEZE_TIM13 +#define __HAL_UNFREEZE_TIM13_DBGMCU __HAL_DBGMCU_UNFREEZE_TIM13 +#define __HAL_FREEZE_TIM14_DBGMCU __HAL_DBGMCU_FREEZE_TIM14 +#define __HAL_UNFREEZE_TIM14_DBGMCU __HAL_DBGMCU_UNFREEZE_TIM14 +#define __HAL_FREEZE_CAN2_DBGMCU __HAL_DBGMCU_FREEZE_CAN2 +#define __HAL_UNFREEZE_CAN2_DBGMCU __HAL_DBGMCU_UNFREEZE_CAN2 + + +#define __HAL_FREEZE_TIM15_DBGMCU __HAL_DBGMCU_FREEZE_TIM15 +#define __HAL_UNFREEZE_TIM15_DBGMCU __HAL_DBGMCU_UNFREEZE_TIM15 +#define __HAL_FREEZE_TIM16_DBGMCU __HAL_DBGMCU_FREEZE_TIM16 +#define __HAL_UNFREEZE_TIM16_DBGMCU __HAL_DBGMCU_UNFREEZE_TIM16 +#define __HAL_FREEZE_TIM17_DBGMCU __HAL_DBGMCU_FREEZE_TIM17 +#define __HAL_UNFREEZE_TIM17_DBGMCU __HAL_DBGMCU_UNFREEZE_TIM17 +#define __HAL_FREEZE_RTC_DBGMCU __HAL_DBGMCU_FREEZE_RTC +#define __HAL_UNFREEZE_RTC_DBGMCU __HAL_DBGMCU_UNFREEZE_RTC +#if defined(STM32H7) + #define __HAL_FREEZE_WWDG_DBGMCU __HAL_DBGMCU_FREEZE_WWDG1 + #define __HAL_UNFREEZE_WWDG_DBGMCU __HAL_DBGMCU_UnFreeze_WWDG1 + #define __HAL_FREEZE_IWDG_DBGMCU __HAL_DBGMCU_FREEZE_IWDG1 + #define __HAL_UNFREEZE_IWDG_DBGMCU __HAL_DBGMCU_UnFreeze_IWDG1 +#else + #define __HAL_FREEZE_WWDG_DBGMCU __HAL_DBGMCU_FREEZE_WWDG + #define __HAL_UNFREEZE_WWDG_DBGMCU __HAL_DBGMCU_UNFREEZE_WWDG + #define __HAL_FREEZE_IWDG_DBGMCU __HAL_DBGMCU_FREEZE_IWDG + #define __HAL_UNFREEZE_IWDG_DBGMCU __HAL_DBGMCU_UNFREEZE_IWDG +#endif /* STM32H7 */ +#define __HAL_FREEZE_I2C1_TIMEOUT_DBGMCU __HAL_DBGMCU_FREEZE_I2C1_TIMEOUT +#define __HAL_UNFREEZE_I2C1_TIMEOUT_DBGMCU __HAL_DBGMCU_UNFREEZE_I2C1_TIMEOUT +#define __HAL_FREEZE_I2C2_TIMEOUT_DBGMCU __HAL_DBGMCU_FREEZE_I2C2_TIMEOUT +#define __HAL_UNFREEZE_I2C2_TIMEOUT_DBGMCU __HAL_DBGMCU_UNFREEZE_I2C2_TIMEOUT +#define __HAL_FREEZE_I2C3_TIMEOUT_DBGMCU __HAL_DBGMCU_FREEZE_I2C3_TIMEOUT +#define __HAL_UNFREEZE_I2C3_TIMEOUT_DBGMCU __HAL_DBGMCU_UNFREEZE_I2C3_TIMEOUT +#define __HAL_FREEZE_CAN1_DBGMCU __HAL_DBGMCU_FREEZE_CAN1 +#define __HAL_UNFREEZE_CAN1_DBGMCU __HAL_DBGMCU_UNFREEZE_CAN1 +#define __HAL_FREEZE_LPTIM1_DBGMCU __HAL_DBGMCU_FREEZE_LPTIM1 +#define __HAL_UNFREEZE_LPTIM1_DBGMCU __HAL_DBGMCU_UNFREEZE_LPTIM1 +#define __HAL_FREEZE_LPTIM2_DBGMCU __HAL_DBGMCU_FREEZE_LPTIM2 +#define __HAL_UNFREEZE_LPTIM2_DBGMCU __HAL_DBGMCU_UNFREEZE_LPTIM2 + +/** + * @} + */ + +/** @defgroup HAL_COMP_Aliased_Macros HAL COMP Aliased Macros maintained for legacy purpose + * @{ + */ +#if defined(STM32F3) +#define COMP_START __HAL_COMP_ENABLE +#define COMP_STOP __HAL_COMP_DISABLE +#define COMP_LOCK __HAL_COMP_LOCK + +#if defined(STM32F301x8) || defined(STM32F302x8) || defined(STM32F318xx) || defined(STM32F303x8) || defined(STM32F334x8) || defined(STM32F328xx) +#define __HAL_COMP_EXTI_RISING_IT_ENABLE(__EXTILINE__) (((__EXTILINE__) == COMP_EXTI_LINE_COMP2) ? __HAL_COMP_COMP2_EXTI_ENABLE_RISING_EDGE() : \ + ((__EXTILINE__) == COMP_EXTI_LINE_COMP4) ? __HAL_COMP_COMP4_EXTI_ENABLE_RISING_EDGE() : \ + __HAL_COMP_COMP6_EXTI_ENABLE_RISING_EDGE()) +#define __HAL_COMP_EXTI_RISING_IT_DISABLE(__EXTILINE__) (((__EXTILINE__) == COMP_EXTI_LINE_COMP2) ? __HAL_COMP_COMP2_EXTI_DISABLE_RISING_EDGE() : \ + ((__EXTILINE__) == COMP_EXTI_LINE_COMP4) ? __HAL_COMP_COMP4_EXTI_DISABLE_RISING_EDGE() : \ + __HAL_COMP_COMP6_EXTI_DISABLE_RISING_EDGE()) +#define __HAL_COMP_EXTI_FALLING_IT_ENABLE(__EXTILINE__) (((__EXTILINE__) == COMP_EXTI_LINE_COMP2) ? __HAL_COMP_COMP2_EXTI_ENABLE_FALLING_EDGE() : \ + ((__EXTILINE__) == COMP_EXTI_LINE_COMP4) ? __HAL_COMP_COMP4_EXTI_ENABLE_FALLING_EDGE() : \ + __HAL_COMP_COMP6_EXTI_ENABLE_FALLING_EDGE()) +#define __HAL_COMP_EXTI_FALLING_IT_DISABLE(__EXTILINE__) (((__EXTILINE__) == COMP_EXTI_LINE_COMP2) ? __HAL_COMP_COMP2_EXTI_DISABLE_FALLING_EDGE() : \ + ((__EXTILINE__) == COMP_EXTI_LINE_COMP4) ? __HAL_COMP_COMP4_EXTI_DISABLE_FALLING_EDGE() : \ + __HAL_COMP_COMP6_EXTI_DISABLE_FALLING_EDGE()) +#define __HAL_COMP_EXTI_ENABLE_IT(__EXTILINE__) (((__EXTILINE__) == COMP_EXTI_LINE_COMP2) ? __HAL_COMP_COMP2_EXTI_ENABLE_IT() : \ + ((__EXTILINE__) == COMP_EXTI_LINE_COMP4) ? __HAL_COMP_COMP4_EXTI_ENABLE_IT() : \ + __HAL_COMP_COMP6_EXTI_ENABLE_IT()) +#define __HAL_COMP_EXTI_DISABLE_IT(__EXTILINE__) (((__EXTILINE__) == COMP_EXTI_LINE_COMP2) ? __HAL_COMP_COMP2_EXTI_DISABLE_IT() : \ + ((__EXTILINE__) == COMP_EXTI_LINE_COMP4) ? __HAL_COMP_COMP4_EXTI_DISABLE_IT() : \ + __HAL_COMP_COMP6_EXTI_DISABLE_IT()) +#define __HAL_COMP_EXTI_GET_FLAG(__FLAG__) (((__FLAG__) == COMP_EXTI_LINE_COMP2) ? __HAL_COMP_COMP2_EXTI_GET_FLAG() : \ + ((__FLAG__) == COMP_EXTI_LINE_COMP4) ? __HAL_COMP_COMP4_EXTI_GET_FLAG() : \ + __HAL_COMP_COMP6_EXTI_GET_FLAG()) +#define __HAL_COMP_EXTI_CLEAR_FLAG(__FLAG__) (((__FLAG__) == COMP_EXTI_LINE_COMP2) ? __HAL_COMP_COMP2_EXTI_CLEAR_FLAG() : \ + ((__FLAG__) == COMP_EXTI_LINE_COMP4) ? __HAL_COMP_COMP4_EXTI_CLEAR_FLAG() : \ + __HAL_COMP_COMP6_EXTI_CLEAR_FLAG()) +# endif +# if defined(STM32F302xE) || defined(STM32F302xC) +#define __HAL_COMP_EXTI_RISING_IT_ENABLE(__EXTILINE__) (((__EXTILINE__) == COMP_EXTI_LINE_COMP1) ? __HAL_COMP_COMP1_EXTI_ENABLE_RISING_EDGE() : \ + ((__EXTILINE__) == COMP_EXTI_LINE_COMP2) ? __HAL_COMP_COMP2_EXTI_ENABLE_RISING_EDGE() : \ + ((__EXTILINE__) == COMP_EXTI_LINE_COMP4) ? __HAL_COMP_COMP4_EXTI_ENABLE_RISING_EDGE() : \ + __HAL_COMP_COMP6_EXTI_ENABLE_RISING_EDGE()) +#define __HAL_COMP_EXTI_RISING_IT_DISABLE(__EXTILINE__) (((__EXTILINE__) == COMP_EXTI_LINE_COMP1) ? __HAL_COMP_COMP1_EXTI_DISABLE_RISING_EDGE() : \ + ((__EXTILINE__) == COMP_EXTI_LINE_COMP2) ? __HAL_COMP_COMP2_EXTI_DISABLE_RISING_EDGE() : \ + ((__EXTILINE__) == COMP_EXTI_LINE_COMP4) ? __HAL_COMP_COMP4_EXTI_DISABLE_RISING_EDGE() : \ + __HAL_COMP_COMP6_EXTI_DISABLE_RISING_EDGE()) +#define __HAL_COMP_EXTI_FALLING_IT_ENABLE(__EXTILINE__) (((__EXTILINE__) == COMP_EXTI_LINE_COMP1) ? __HAL_COMP_COMP1_EXTI_ENABLE_FALLING_EDGE() : \ + ((__EXTILINE__) == COMP_EXTI_LINE_COMP2) ? __HAL_COMP_COMP2_EXTI_ENABLE_FALLING_EDGE() : \ + ((__EXTILINE__) == COMP_EXTI_LINE_COMP4) ? __HAL_COMP_COMP4_EXTI_ENABLE_FALLING_EDGE() : \ + __HAL_COMP_COMP6_EXTI_ENABLE_FALLING_EDGE()) +#define __HAL_COMP_EXTI_FALLING_IT_DISABLE(__EXTILINE__) (((__EXTILINE__) == COMP_EXTI_LINE_COMP1) ? __HAL_COMP_COMP1_EXTI_DISABLE_FALLING_EDGE() : \ + ((__EXTILINE__) == COMP_EXTI_LINE_COMP2) ? __HAL_COMP_COMP2_EXTI_DISABLE_FALLING_EDGE() : \ + ((__EXTILINE__) == COMP_EXTI_LINE_COMP4) ? __HAL_COMP_COMP4_EXTI_DISABLE_FALLING_EDGE() : \ + __HAL_COMP_COMP6_EXTI_DISABLE_FALLING_EDGE()) +#define __HAL_COMP_EXTI_ENABLE_IT(__EXTILINE__) (((__EXTILINE__) == COMP_EXTI_LINE_COMP1) ? __HAL_COMP_COMP1_EXTI_ENABLE_IT() : \ + ((__EXTILINE__) == COMP_EXTI_LINE_COMP2) ? __HAL_COMP_COMP2_EXTI_ENABLE_IT() : \ + ((__EXTILINE__) == COMP_EXTI_LINE_COMP4) ? __HAL_COMP_COMP4_EXTI_ENABLE_IT() : \ + __HAL_COMP_COMP6_EXTI_ENABLE_IT()) +#define __HAL_COMP_EXTI_DISABLE_IT(__EXTILINE__) (((__EXTILINE__) == COMP_EXTI_LINE_COMP1) ? __HAL_COMP_COMP1_EXTI_DISABLE_IT() : \ + ((__EXTILINE__) == COMP_EXTI_LINE_COMP2) ? __HAL_COMP_COMP2_EXTI_DISABLE_IT() : \ + ((__EXTILINE__) == COMP_EXTI_LINE_COMP4) ? __HAL_COMP_COMP4_EXTI_DISABLE_IT() : \ + __HAL_COMP_COMP6_EXTI_DISABLE_IT()) +#define __HAL_COMP_EXTI_GET_FLAG(__FLAG__) (((__FLAG__) == COMP_EXTI_LINE_COMP1) ? __HAL_COMP_COMP1_EXTI_GET_FLAG() : \ + ((__FLAG__) == COMP_EXTI_LINE_COMP2) ? __HAL_COMP_COMP2_EXTI_GET_FLAG() : \ + ((__FLAG__) == COMP_EXTI_LINE_COMP4) ? __HAL_COMP_COMP4_EXTI_GET_FLAG() : \ + __HAL_COMP_COMP6_EXTI_GET_FLAG()) +#define __HAL_COMP_EXTI_CLEAR_FLAG(__FLAG__) (((__FLAG__) == COMP_EXTI_LINE_COMP1) ? __HAL_COMP_COMP1_EXTI_CLEAR_FLAG() : \ + ((__FLAG__) == COMP_EXTI_LINE_COMP2) ? __HAL_COMP_COMP2_EXTI_CLEAR_FLAG() : \ + ((__FLAG__) == COMP_EXTI_LINE_COMP4) ? __HAL_COMP_COMP4_EXTI_CLEAR_FLAG() : \ + __HAL_COMP_COMP6_EXTI_CLEAR_FLAG()) +# endif +# if defined(STM32F303xE) || defined(STM32F398xx) || defined(STM32F303xC) || defined(STM32F358xx) +#define __HAL_COMP_EXTI_RISING_IT_ENABLE(__EXTILINE__) (((__EXTILINE__) == COMP_EXTI_LINE_COMP1) ? __HAL_COMP_COMP1_EXTI_ENABLE_RISING_EDGE() : \ + ((__EXTILINE__) == COMP_EXTI_LINE_COMP2) ? __HAL_COMP_COMP2_EXTI_ENABLE_RISING_EDGE() : \ + ((__EXTILINE__) == COMP_EXTI_LINE_COMP3) ? __HAL_COMP_COMP3_EXTI_ENABLE_RISING_EDGE() : \ + ((__EXTILINE__) == COMP_EXTI_LINE_COMP4) ? __HAL_COMP_COMP4_EXTI_ENABLE_RISING_EDGE() : \ + ((__EXTILINE__) == COMP_EXTI_LINE_COMP5) ? __HAL_COMP_COMP5_EXTI_ENABLE_RISING_EDGE() : \ + ((__EXTILINE__) == COMP_EXTI_LINE_COMP6) ? __HAL_COMP_COMP6_EXTI_ENABLE_RISING_EDGE() : \ + __HAL_COMP_COMP7_EXTI_ENABLE_RISING_EDGE()) +#define __HAL_COMP_EXTI_RISING_IT_DISABLE(__EXTILINE__) (((__EXTILINE__) == COMP_EXTI_LINE_COMP1) ? __HAL_COMP_COMP1_EXTI_DISABLE_RISING_EDGE() : \ + ((__EXTILINE__) == COMP_EXTI_LINE_COMP2) ? __HAL_COMP_COMP2_EXTI_DISABLE_RISING_EDGE() : \ + ((__EXTILINE__) == COMP_EXTI_LINE_COMP3) ? __HAL_COMP_COMP3_EXTI_DISABLE_RISING_EDGE() : \ + ((__EXTILINE__) == COMP_EXTI_LINE_COMP4) ? __HAL_COMP_COMP4_EXTI_DISABLE_RISING_EDGE() : \ + ((__EXTILINE__) == COMP_EXTI_LINE_COMP5) ? __HAL_COMP_COMP5_EXTI_DISABLE_RISING_EDGE() : \ + ((__EXTILINE__) == COMP_EXTI_LINE_COMP6) ? __HAL_COMP_COMP6_EXTI_DISABLE_RISING_EDGE() : \ + __HAL_COMP_COMP7_EXTI_DISABLE_RISING_EDGE()) +#define __HAL_COMP_EXTI_FALLING_IT_ENABLE(__EXTILINE__) (((__EXTILINE__) == COMP_EXTI_LINE_COMP1) ? __HAL_COMP_COMP1_EXTI_ENABLE_FALLING_EDGE() : \ + ((__EXTILINE__) == COMP_EXTI_LINE_COMP2) ? __HAL_COMP_COMP2_EXTI_ENABLE_FALLING_EDGE() : \ + ((__EXTILINE__) == COMP_EXTI_LINE_COMP3) ? __HAL_COMP_COMP3_EXTI_ENABLE_FALLING_EDGE() : \ + ((__EXTILINE__) == COMP_EXTI_LINE_COMP4) ? __HAL_COMP_COMP4_EXTI_ENABLE_FALLING_EDGE() : \ + ((__EXTILINE__) == COMP_EXTI_LINE_COMP5) ? __HAL_COMP_COMP5_EXTI_ENABLE_FALLING_EDGE() : \ + ((__EXTILINE__) == COMP_EXTI_LINE_COMP6) ? __HAL_COMP_COMP6_EXTI_ENABLE_FALLING_EDGE() : \ + __HAL_COMP_COMP7_EXTI_ENABLE_FALLING_EDGE()) +#define __HAL_COMP_EXTI_FALLING_IT_DISABLE(__EXTILINE__) (((__EXTILINE__) == COMP_EXTI_LINE_COMP1) ? __HAL_COMP_COMP1_EXTI_DISABLE_FALLING_EDGE() : \ + ((__EXTILINE__) == COMP_EXTI_LINE_COMP2) ? __HAL_COMP_COMP2_EXTI_DISABLE_FALLING_EDGE() : \ + ((__EXTILINE__) == COMP_EXTI_LINE_COMP3) ? __HAL_COMP_COMP3_EXTI_DISABLE_FALLING_EDGE() : \ + ((__EXTILINE__) == COMP_EXTI_LINE_COMP4) ? __HAL_COMP_COMP4_EXTI_DISABLE_FALLING_EDGE() : \ + ((__EXTILINE__) == COMP_EXTI_LINE_COMP5) ? __HAL_COMP_COMP5_EXTI_DISABLE_FALLING_EDGE() : \ + ((__EXTILINE__) == COMP_EXTI_LINE_COMP6) ? __HAL_COMP_COMP6_EXTI_DISABLE_FALLING_EDGE() : \ + __HAL_COMP_COMP7_EXTI_DISABLE_FALLING_EDGE()) +#define __HAL_COMP_EXTI_ENABLE_IT(__EXTILINE__) (((__EXTILINE__) == COMP_EXTI_LINE_COMP1) ? __HAL_COMP_COMP1_EXTI_ENABLE_IT() : \ + ((__EXTILINE__) == COMP_EXTI_LINE_COMP2) ? __HAL_COMP_COMP2_EXTI_ENABLE_IT() : \ + ((__EXTILINE__) == COMP_EXTI_LINE_COMP3) ? __HAL_COMP_COMP3_EXTI_ENABLE_IT() : \ + ((__EXTILINE__) == COMP_EXTI_LINE_COMP4) ? __HAL_COMP_COMP4_EXTI_ENABLE_IT() : \ + ((__EXTILINE__) == COMP_EXTI_LINE_COMP5) ? __HAL_COMP_COMP5_EXTI_ENABLE_IT() : \ + ((__EXTILINE__) == COMP_EXTI_LINE_COMP6) ? __HAL_COMP_COMP6_EXTI_ENABLE_IT() : \ + __HAL_COMP_COMP7_EXTI_ENABLE_IT()) +#define __HAL_COMP_EXTI_DISABLE_IT(__EXTILINE__) (((__EXTILINE__) == COMP_EXTI_LINE_COMP1) ? __HAL_COMP_COMP1_EXTI_DISABLE_IT() : \ + ((__EXTILINE__) == COMP_EXTI_LINE_COMP2) ? __HAL_COMP_COMP2_EXTI_DISABLE_IT() : \ + ((__EXTILINE__) == COMP_EXTI_LINE_COMP3) ? __HAL_COMP_COMP3_EXTI_DISABLE_IT() : \ + ((__EXTILINE__) == COMP_EXTI_LINE_COMP4) ? __HAL_COMP_COMP4_EXTI_DISABLE_IT() : \ + ((__EXTILINE__) == COMP_EXTI_LINE_COMP5) ? __HAL_COMP_COMP5_EXTI_DISABLE_IT() : \ + ((__EXTILINE__) == COMP_EXTI_LINE_COMP6) ? __HAL_COMP_COMP6_EXTI_DISABLE_IT() : \ + __HAL_COMP_COMP7_EXTI_DISABLE_IT()) +#define __HAL_COMP_EXTI_GET_FLAG(__FLAG__) (((__FLAG__) == COMP_EXTI_LINE_COMP1) ? __HAL_COMP_COMP1_EXTI_GET_FLAG() : \ + ((__FLAG__) == COMP_EXTI_LINE_COMP2) ? __HAL_COMP_COMP2_EXTI_GET_FLAG() : \ + ((__FLAG__) == COMP_EXTI_LINE_COMP3) ? __HAL_COMP_COMP3_EXTI_GET_FLAG() : \ + ((__FLAG__) == COMP_EXTI_LINE_COMP4) ? __HAL_COMP_COMP4_EXTI_GET_FLAG() : \ + ((__FLAG__) == COMP_EXTI_LINE_COMP5) ? __HAL_COMP_COMP5_EXTI_GET_FLAG() : \ + ((__FLAG__) == COMP_EXTI_LINE_COMP6) ? __HAL_COMP_COMP6_EXTI_GET_FLAG() : \ + __HAL_COMP_COMP7_EXTI_GET_FLAG()) +#define __HAL_COMP_EXTI_CLEAR_FLAG(__FLAG__) (((__FLAG__) == COMP_EXTI_LINE_COMP1) ? __HAL_COMP_COMP1_EXTI_CLEAR_FLAG() : \ + ((__FLAG__) == COMP_EXTI_LINE_COMP2) ? __HAL_COMP_COMP2_EXTI_CLEAR_FLAG() : \ + ((__FLAG__) == COMP_EXTI_LINE_COMP3) ? __HAL_COMP_COMP3_EXTI_CLEAR_FLAG() : \ + ((__FLAG__) == COMP_EXTI_LINE_COMP4) ? __HAL_COMP_COMP4_EXTI_CLEAR_FLAG() : \ + ((__FLAG__) == COMP_EXTI_LINE_COMP5) ? __HAL_COMP_COMP5_EXTI_CLEAR_FLAG() : \ + ((__FLAG__) == COMP_EXTI_LINE_COMP6) ? __HAL_COMP_COMP6_EXTI_CLEAR_FLAG() : \ + __HAL_COMP_COMP7_EXTI_CLEAR_FLAG()) +# endif +# if defined(STM32F373xC) ||defined(STM32F378xx) +#define __HAL_COMP_EXTI_RISING_IT_ENABLE(__EXTILINE__) (((__EXTILINE__) == COMP_EXTI_LINE_COMP1) ? __HAL_COMP_COMP1_EXTI_ENABLE_RISING_EDGE() : \ + __HAL_COMP_COMP2_EXTI_ENABLE_RISING_EDGE()) +#define __HAL_COMP_EXTI_RISING_IT_DISABLE(__EXTILINE__) (((__EXTILINE__) == COMP_EXTI_LINE_COMP1) ? __HAL_COMP_COMP1_EXTI_DISABLE_RISING_EDGE() : \ + __HAL_COMP_COMP2_EXTI_DISABLE_RISING_EDGE()) +#define __HAL_COMP_EXTI_FALLING_IT_ENABLE(__EXTILINE__) (((__EXTILINE__) == COMP_EXTI_LINE_COMP1) ? __HAL_COMP_COMP1_EXTI_ENABLE_FALLING_EDGE() : \ + __HAL_COMP_COMP2_EXTI_ENABLE_FALLING_EDGE()) +#define __HAL_COMP_EXTI_FALLING_IT_DISABLE(__EXTILINE__) (((__EXTILINE__) == COMP_EXTI_LINE_COMP1) ? __HAL_COMP_COMP1_EXTI_DISABLE_FALLING_EDGE() : \ + __HAL_COMP_COMP2_EXTI_DISABLE_FALLING_EDGE()) +#define __HAL_COMP_EXTI_ENABLE_IT(__EXTILINE__) (((__EXTILINE__) == COMP_EXTI_LINE_COMP1) ? __HAL_COMP_COMP1_EXTI_ENABLE_IT() : \ + __HAL_COMP_COMP2_EXTI_ENABLE_IT()) +#define __HAL_COMP_EXTI_DISABLE_IT(__EXTILINE__) (((__EXTILINE__) == COMP_EXTI_LINE_COMP1) ? __HAL_COMP_COMP1_EXTI_DISABLE_IT() : \ + __HAL_COMP_COMP2_EXTI_DISABLE_IT()) +#define __HAL_COMP_EXTI_GET_FLAG(__FLAG__) (((__FLAG__) == COMP_EXTI_LINE_COMP1) ? __HAL_COMP_COMP1_EXTI_GET_FLAG() : \ + __HAL_COMP_COMP2_EXTI_GET_FLAG()) +#define __HAL_COMP_EXTI_CLEAR_FLAG(__FLAG__) (((__FLAG__) == COMP_EXTI_LINE_COMP1) ? __HAL_COMP_COMP1_EXTI_CLEAR_FLAG() : \ + __HAL_COMP_COMP2_EXTI_CLEAR_FLAG()) +# endif +#else +#define __HAL_COMP_EXTI_RISING_IT_ENABLE(__EXTILINE__) (((__EXTILINE__) == COMP_EXTI_LINE_COMP1) ? __HAL_COMP_COMP1_EXTI_ENABLE_RISING_EDGE() : \ + __HAL_COMP_COMP2_EXTI_ENABLE_RISING_EDGE()) +#define __HAL_COMP_EXTI_RISING_IT_DISABLE(__EXTILINE__) (((__EXTILINE__) == COMP_EXTI_LINE_COMP1) ? __HAL_COMP_COMP1_EXTI_DISABLE_RISING_EDGE() : \ + __HAL_COMP_COMP2_EXTI_DISABLE_RISING_EDGE()) +#define __HAL_COMP_EXTI_FALLING_IT_ENABLE(__EXTILINE__) (((__EXTILINE__) == COMP_EXTI_LINE_COMP1) ? __HAL_COMP_COMP1_EXTI_ENABLE_FALLING_EDGE() : \ + __HAL_COMP_COMP2_EXTI_ENABLE_FALLING_EDGE()) +#define __HAL_COMP_EXTI_FALLING_IT_DISABLE(__EXTILINE__) (((__EXTILINE__) == COMP_EXTI_LINE_COMP1) ? __HAL_COMP_COMP1_EXTI_DISABLE_FALLING_EDGE() : \ + __HAL_COMP_COMP2_EXTI_DISABLE_FALLING_EDGE()) +#define __HAL_COMP_EXTI_ENABLE_IT(__EXTILINE__) (((__EXTILINE__) == COMP_EXTI_LINE_COMP1) ? __HAL_COMP_COMP1_EXTI_ENABLE_IT() : \ + __HAL_COMP_COMP2_EXTI_ENABLE_IT()) +#define __HAL_COMP_EXTI_DISABLE_IT(__EXTILINE__) (((__EXTILINE__) == COMP_EXTI_LINE_COMP1) ? __HAL_COMP_COMP1_EXTI_DISABLE_IT() : \ + __HAL_COMP_COMP2_EXTI_DISABLE_IT()) +#define __HAL_COMP_EXTI_GET_FLAG(__FLAG__) (((__FLAG__) == COMP_EXTI_LINE_COMP1) ? __HAL_COMP_COMP1_EXTI_GET_FLAG() : \ + __HAL_COMP_COMP2_EXTI_GET_FLAG()) +#define __HAL_COMP_EXTI_CLEAR_FLAG(__FLAG__) (((__FLAG__) == COMP_EXTI_LINE_COMP1) ? __HAL_COMP_COMP1_EXTI_CLEAR_FLAG() : \ + __HAL_COMP_COMP2_EXTI_CLEAR_FLAG()) +#endif + +#define __HAL_COMP_GET_EXTI_LINE COMP_GET_EXTI_LINE + +#if defined(STM32L0) || defined(STM32L4) +/* Note: On these STM32 families, the only argument of this macro */ +/* is COMP_FLAG_LOCK. */ +/* This macro is replaced by __HAL_COMP_IS_LOCKED with only HAL handle */ +/* argument. */ +#define __HAL_COMP_GET_FLAG(__HANDLE__, __FLAG__) (__HAL_COMP_IS_LOCKED(__HANDLE__)) +#endif +/** + * @} + */ + +#if defined(STM32L0) || defined(STM32L4) +/** @defgroup HAL_COMP_Aliased_Functions HAL COMP Aliased Functions maintained for legacy purpose + * @{ + */ +#define HAL_COMP_Start_IT HAL_COMP_Start /* Function considered as legacy as EXTI event or IT configuration is done into HAL_COMP_Init() */ +#define HAL_COMP_Stop_IT HAL_COMP_Stop /* Function considered as legacy as EXTI event or IT configuration is done into HAL_COMP_Init() */ +/** + * @} + */ +#endif + +/** @defgroup HAL_DAC_Aliased_Macros HAL DAC Aliased Macros maintained for legacy purpose + * @{ + */ + +#define IS_DAC_WAVE(WAVE) (((WAVE) == DAC_WAVE_NONE) || \ + ((WAVE) == DAC_WAVE_NOISE)|| \ + ((WAVE) == DAC_WAVE_TRIANGLE)) + +/** + * @} + */ + +/** @defgroup HAL_FLASH_Aliased_Macros HAL FLASH Aliased Macros maintained for legacy purpose + * @{ + */ + +#define IS_WRPAREA IS_OB_WRPAREA +#define IS_TYPEPROGRAM IS_FLASH_TYPEPROGRAM +#define IS_TYPEPROGRAMFLASH IS_FLASH_TYPEPROGRAM +#define IS_TYPEERASE IS_FLASH_TYPEERASE +#define IS_NBSECTORS IS_FLASH_NBSECTORS +#define IS_OB_WDG_SOURCE IS_OB_IWDG_SOURCE + +/** + * @} + */ + +/** @defgroup HAL_I2C_Aliased_Macros HAL I2C Aliased Macros maintained for legacy purpose + * @{ + */ + +#define __HAL_I2C_RESET_CR2 I2C_RESET_CR2 +#define __HAL_I2C_GENERATE_START I2C_GENERATE_START +#if defined(STM32F1) +#define __HAL_I2C_FREQ_RANGE I2C_FREQRANGE +#else +#define __HAL_I2C_FREQ_RANGE I2C_FREQ_RANGE +#endif /* STM32F1 */ +#define __HAL_I2C_RISE_TIME I2C_RISE_TIME +#define __HAL_I2C_SPEED_STANDARD I2C_SPEED_STANDARD +#define __HAL_I2C_SPEED_FAST I2C_SPEED_FAST +#define __HAL_I2C_SPEED I2C_SPEED +#define __HAL_I2C_7BIT_ADD_WRITE I2C_7BIT_ADD_WRITE +#define __HAL_I2C_7BIT_ADD_READ I2C_7BIT_ADD_READ +#define __HAL_I2C_10BIT_ADDRESS I2C_10BIT_ADDRESS +#define __HAL_I2C_10BIT_HEADER_WRITE I2C_10BIT_HEADER_WRITE +#define __HAL_I2C_10BIT_HEADER_READ I2C_10BIT_HEADER_READ +#define __HAL_I2C_MEM_ADD_MSB I2C_MEM_ADD_MSB +#define __HAL_I2C_MEM_ADD_LSB I2C_MEM_ADD_LSB +#define __HAL_I2C_FREQRANGE I2C_FREQRANGE +/** + * @} + */ + +/** @defgroup HAL_I2S_Aliased_Macros HAL I2S Aliased Macros maintained for legacy purpose + * @{ + */ + +#define IS_I2S_INSTANCE IS_I2S_ALL_INSTANCE +#define IS_I2S_INSTANCE_EXT IS_I2S_ALL_INSTANCE_EXT + +#if defined(STM32H7) + #define __HAL_I2S_CLEAR_FREFLAG __HAL_I2S_CLEAR_TIFREFLAG +#endif + +/** + * @} + */ + +/** @defgroup HAL_IRDA_Aliased_Macros HAL IRDA Aliased Macros maintained for legacy purpose + * @{ + */ + +#define __IRDA_DISABLE __HAL_IRDA_DISABLE +#define __IRDA_ENABLE __HAL_IRDA_ENABLE + +#define __HAL_IRDA_GETCLOCKSOURCE IRDA_GETCLOCKSOURCE +#define __HAL_IRDA_MASK_COMPUTATION IRDA_MASK_COMPUTATION +#define __IRDA_GETCLOCKSOURCE IRDA_GETCLOCKSOURCE +#define __IRDA_MASK_COMPUTATION IRDA_MASK_COMPUTATION + +#define IS_IRDA_ONEBIT_SAMPLE IS_IRDA_ONE_BIT_SAMPLE + + +/** + * @} + */ + + +/** @defgroup HAL_IWDG_Aliased_Macros HAL IWDG Aliased Macros maintained for legacy purpose + * @{ + */ +#define __HAL_IWDG_ENABLE_WRITE_ACCESS IWDG_ENABLE_WRITE_ACCESS +#define __HAL_IWDG_DISABLE_WRITE_ACCESS IWDG_DISABLE_WRITE_ACCESS +/** + * @} + */ + + +/** @defgroup HAL_LPTIM_Aliased_Macros HAL LPTIM Aliased Macros maintained for legacy purpose + * @{ + */ + +#define __HAL_LPTIM_ENABLE_INTERRUPT __HAL_LPTIM_ENABLE_IT +#define __HAL_LPTIM_DISABLE_INTERRUPT __HAL_LPTIM_DISABLE_IT +#define __HAL_LPTIM_GET_ITSTATUS __HAL_LPTIM_GET_IT_SOURCE + +/** + * @} + */ + + +/** @defgroup HAL_OPAMP_Aliased_Macros HAL OPAMP Aliased Macros maintained for legacy purpose + * @{ + */ +#define __OPAMP_CSR_OPAXPD OPAMP_CSR_OPAXPD +#define __OPAMP_CSR_S3SELX OPAMP_CSR_S3SELX +#define __OPAMP_CSR_S4SELX OPAMP_CSR_S4SELX +#define __OPAMP_CSR_S5SELX OPAMP_CSR_S5SELX +#define __OPAMP_CSR_S6SELX OPAMP_CSR_S6SELX +#define __OPAMP_CSR_OPAXCAL_L OPAMP_CSR_OPAXCAL_L +#define __OPAMP_CSR_OPAXCAL_H OPAMP_CSR_OPAXCAL_H +#define __OPAMP_CSR_OPAXLPM OPAMP_CSR_OPAXLPM +#define __OPAMP_CSR_ALL_SWITCHES OPAMP_CSR_ALL_SWITCHES +#define __OPAMP_CSR_ANAWSELX OPAMP_CSR_ANAWSELX +#define __OPAMP_CSR_OPAXCALOUT OPAMP_CSR_OPAXCALOUT +#define __OPAMP_OFFSET_TRIM_BITSPOSITION OPAMP_OFFSET_TRIM_BITSPOSITION +#define __OPAMP_OFFSET_TRIM_SET OPAMP_OFFSET_TRIM_SET + +/** + * @} + */ + + +/** @defgroup HAL_PWR_Aliased_Macros HAL PWR Aliased Macros maintained for legacy purpose + * @{ + */ +#define __HAL_PVD_EVENT_DISABLE __HAL_PWR_PVD_EXTI_DISABLE_EVENT +#define __HAL_PVD_EVENT_ENABLE __HAL_PWR_PVD_EXTI_ENABLE_EVENT +#define __HAL_PVD_EXTI_FALLINGTRIGGER_DISABLE __HAL_PWR_PVD_EXTI_DISABLE_FALLING_EDGE +#define __HAL_PVD_EXTI_FALLINGTRIGGER_ENABLE __HAL_PWR_PVD_EXTI_ENABLE_FALLING_EDGE +#define __HAL_PVD_EXTI_RISINGTRIGGER_DISABLE __HAL_PWR_PVD_EXTI_DISABLE_RISING_EDGE +#define __HAL_PVD_EXTI_RISINGTRIGGER_ENABLE __HAL_PWR_PVD_EXTI_ENABLE_RISING_EDGE +#define __HAL_PVM_EVENT_DISABLE __HAL_PWR_PVM_EVENT_DISABLE +#define __HAL_PVM_EVENT_ENABLE __HAL_PWR_PVM_EVENT_ENABLE +#define __HAL_PVM_EXTI_FALLINGTRIGGER_DISABLE __HAL_PWR_PVM_EXTI_FALLINGTRIGGER_DISABLE +#define __HAL_PVM_EXTI_FALLINGTRIGGER_ENABLE __HAL_PWR_PVM_EXTI_FALLINGTRIGGER_ENABLE +#define __HAL_PVM_EXTI_RISINGTRIGGER_DISABLE __HAL_PWR_PVM_EXTI_RISINGTRIGGER_DISABLE +#define __HAL_PVM_EXTI_RISINGTRIGGER_ENABLE __HAL_PWR_PVM_EXTI_RISINGTRIGGER_ENABLE +#define __HAL_PWR_INTERNALWAKEUP_DISABLE HAL_PWREx_DisableInternalWakeUpLine +#define __HAL_PWR_INTERNALWAKEUP_ENABLE HAL_PWREx_EnableInternalWakeUpLine +#define __HAL_PWR_PULL_UP_DOWN_CONFIG_DISABLE HAL_PWREx_DisablePullUpPullDownConfig +#define __HAL_PWR_PULL_UP_DOWN_CONFIG_ENABLE HAL_PWREx_EnablePullUpPullDownConfig +#define __HAL_PWR_PVD_EXTI_CLEAR_EGDE_TRIGGER() do { __HAL_PWR_PVD_EXTI_DISABLE_RISING_EDGE();__HAL_PWR_PVD_EXTI_DISABLE_FALLING_EDGE(); } while(0) +#define __HAL_PWR_PVD_EXTI_EVENT_DISABLE __HAL_PWR_PVD_EXTI_DISABLE_EVENT +#define __HAL_PWR_PVD_EXTI_EVENT_ENABLE __HAL_PWR_PVD_EXTI_ENABLE_EVENT +#define __HAL_PWR_PVD_EXTI_FALLINGTRIGGER_DISABLE __HAL_PWR_PVD_EXTI_DISABLE_FALLING_EDGE +#define __HAL_PWR_PVD_EXTI_FALLINGTRIGGER_ENABLE __HAL_PWR_PVD_EXTI_ENABLE_FALLING_EDGE +#define __HAL_PWR_PVD_EXTI_RISINGTRIGGER_DISABLE __HAL_PWR_PVD_EXTI_DISABLE_RISING_EDGE +#define __HAL_PWR_PVD_EXTI_RISINGTRIGGER_ENABLE __HAL_PWR_PVD_EXTI_ENABLE_RISING_EDGE +#define __HAL_PWR_PVD_EXTI_SET_FALLING_EGDE_TRIGGER __HAL_PWR_PVD_EXTI_ENABLE_FALLING_EDGE +#define __HAL_PWR_PVD_EXTI_SET_RISING_EDGE_TRIGGER __HAL_PWR_PVD_EXTI_ENABLE_RISING_EDGE +#define __HAL_PWR_PVM_DISABLE() do { HAL_PWREx_DisablePVM1();HAL_PWREx_DisablePVM2();HAL_PWREx_DisablePVM3();HAL_PWREx_DisablePVM4(); } while(0) +#define __HAL_PWR_PVM_ENABLE() do { HAL_PWREx_EnablePVM1();HAL_PWREx_EnablePVM2();HAL_PWREx_EnablePVM3();HAL_PWREx_EnablePVM4(); } while(0) +#define __HAL_PWR_SRAM2CONTENT_PRESERVE_DISABLE HAL_PWREx_DisableSRAM2ContentRetention +#define __HAL_PWR_SRAM2CONTENT_PRESERVE_ENABLE HAL_PWREx_EnableSRAM2ContentRetention +#define __HAL_PWR_VDDIO2_DISABLE HAL_PWREx_DisableVddIO2 +#define __HAL_PWR_VDDIO2_ENABLE HAL_PWREx_EnableVddIO2 +#define __HAL_PWR_VDDIO2_EXTI_CLEAR_EGDE_TRIGGER __HAL_PWR_VDDIO2_EXTI_DISABLE_FALLING_EDGE +#define __HAL_PWR_VDDIO2_EXTI_SET_FALLING_EGDE_TRIGGER __HAL_PWR_VDDIO2_EXTI_ENABLE_FALLING_EDGE +#define __HAL_PWR_VDDUSB_DISABLE HAL_PWREx_DisableVddUSB +#define __HAL_PWR_VDDUSB_ENABLE HAL_PWREx_EnableVddUSB + +#if defined (STM32F4) +#define __HAL_PVD_EXTI_ENABLE_IT(PWR_EXTI_LINE_PVD) __HAL_PWR_PVD_EXTI_ENABLE_IT() +#define __HAL_PVD_EXTI_DISABLE_IT(PWR_EXTI_LINE_PVD) __HAL_PWR_PVD_EXTI_DISABLE_IT() +#define __HAL_PVD_EXTI_GET_FLAG(PWR_EXTI_LINE_PVD) __HAL_PWR_PVD_EXTI_GET_FLAG() +#define __HAL_PVD_EXTI_CLEAR_FLAG(PWR_EXTI_LINE_PVD) __HAL_PWR_PVD_EXTI_CLEAR_FLAG() +#define __HAL_PVD_EXTI_GENERATE_SWIT(PWR_EXTI_LINE_PVD) __HAL_PWR_PVD_EXTI_GENERATE_SWIT() +#else +#define __HAL_PVD_EXTI_CLEAR_FLAG __HAL_PWR_PVD_EXTI_CLEAR_FLAG +#define __HAL_PVD_EXTI_DISABLE_IT __HAL_PWR_PVD_EXTI_DISABLE_IT +#define __HAL_PVD_EXTI_ENABLE_IT __HAL_PWR_PVD_EXTI_ENABLE_IT +#define __HAL_PVD_EXTI_GENERATE_SWIT __HAL_PWR_PVD_EXTI_GENERATE_SWIT +#define __HAL_PVD_EXTI_GET_FLAG __HAL_PWR_PVD_EXTI_GET_FLAG +#endif /* STM32F4 */ +/** + * @} + */ + + +/** @defgroup HAL_RCC_Aliased HAL RCC Aliased maintained for legacy purpose + * @{ + */ + +#define RCC_StopWakeUpClock_MSI RCC_STOP_WAKEUPCLOCK_MSI +#define RCC_StopWakeUpClock_HSI RCC_STOP_WAKEUPCLOCK_HSI + +#define HAL_RCC_CCSCallback HAL_RCC_CSSCallback +#define HAL_RC48_EnableBuffer_Cmd(cmd) (((cmd)==ENABLE) ? HAL_RCCEx_EnableHSI48_VREFINT() : HAL_RCCEx_DisableHSI48_VREFINT()) + +#define __ADC_CLK_DISABLE __HAL_RCC_ADC_CLK_DISABLE +#define __ADC_CLK_ENABLE __HAL_RCC_ADC_CLK_ENABLE +#define __ADC_CLK_SLEEP_DISABLE __HAL_RCC_ADC_CLK_SLEEP_DISABLE +#define __ADC_CLK_SLEEP_ENABLE __HAL_RCC_ADC_CLK_SLEEP_ENABLE +#define __ADC_FORCE_RESET __HAL_RCC_ADC_FORCE_RESET +#define __ADC_RELEASE_RESET __HAL_RCC_ADC_RELEASE_RESET +#define __ADC1_CLK_DISABLE __HAL_RCC_ADC1_CLK_DISABLE +#define __ADC1_CLK_ENABLE __HAL_RCC_ADC1_CLK_ENABLE +#define __ADC1_FORCE_RESET __HAL_RCC_ADC1_FORCE_RESET +#define __ADC1_RELEASE_RESET __HAL_RCC_ADC1_RELEASE_RESET +#define __ADC1_CLK_SLEEP_ENABLE __HAL_RCC_ADC1_CLK_SLEEP_ENABLE +#define __ADC1_CLK_SLEEP_DISABLE __HAL_RCC_ADC1_CLK_SLEEP_DISABLE +#define __ADC2_CLK_DISABLE __HAL_RCC_ADC2_CLK_DISABLE +#define __ADC2_CLK_ENABLE __HAL_RCC_ADC2_CLK_ENABLE +#define __ADC2_FORCE_RESET __HAL_RCC_ADC2_FORCE_RESET +#define __ADC2_RELEASE_RESET __HAL_RCC_ADC2_RELEASE_RESET +#define __ADC3_CLK_DISABLE __HAL_RCC_ADC3_CLK_DISABLE +#define __ADC3_CLK_ENABLE __HAL_RCC_ADC3_CLK_ENABLE +#define __ADC3_FORCE_RESET __HAL_RCC_ADC3_FORCE_RESET +#define __ADC3_RELEASE_RESET __HAL_RCC_ADC3_RELEASE_RESET +#define __AES_CLK_DISABLE __HAL_RCC_AES_CLK_DISABLE +#define __AES_CLK_ENABLE __HAL_RCC_AES_CLK_ENABLE +#define __AES_CLK_SLEEP_DISABLE __HAL_RCC_AES_CLK_SLEEP_DISABLE +#define __AES_CLK_SLEEP_ENABLE __HAL_RCC_AES_CLK_SLEEP_ENABLE +#define __AES_FORCE_RESET __HAL_RCC_AES_FORCE_RESET +#define __AES_RELEASE_RESET __HAL_RCC_AES_RELEASE_RESET +#define __CRYP_CLK_SLEEP_ENABLE __HAL_RCC_CRYP_CLK_SLEEP_ENABLE +#define __CRYP_CLK_SLEEP_DISABLE __HAL_RCC_CRYP_CLK_SLEEP_DISABLE +#define __CRYP_CLK_ENABLE __HAL_RCC_CRYP_CLK_ENABLE +#define __CRYP_CLK_DISABLE __HAL_RCC_CRYP_CLK_DISABLE +#define __CRYP_FORCE_RESET __HAL_RCC_CRYP_FORCE_RESET +#define __CRYP_RELEASE_RESET __HAL_RCC_CRYP_RELEASE_RESET +#define __AFIO_CLK_DISABLE __HAL_RCC_AFIO_CLK_DISABLE +#define __AFIO_CLK_ENABLE __HAL_RCC_AFIO_CLK_ENABLE +#define __AFIO_FORCE_RESET __HAL_RCC_AFIO_FORCE_RESET +#define __AFIO_RELEASE_RESET __HAL_RCC_AFIO_RELEASE_RESET +#define __AHB_FORCE_RESET __HAL_RCC_AHB_FORCE_RESET +#define __AHB_RELEASE_RESET __HAL_RCC_AHB_RELEASE_RESET +#define __AHB1_FORCE_RESET __HAL_RCC_AHB1_FORCE_RESET +#define __AHB1_RELEASE_RESET __HAL_RCC_AHB1_RELEASE_RESET +#define __AHB2_FORCE_RESET __HAL_RCC_AHB2_FORCE_RESET +#define __AHB2_RELEASE_RESET __HAL_RCC_AHB2_RELEASE_RESET +#define __AHB3_FORCE_RESET __HAL_RCC_AHB3_FORCE_RESET +#define __AHB3_RELEASE_RESET __HAL_RCC_AHB3_RELEASE_RESET +#define __APB1_FORCE_RESET __HAL_RCC_APB1_FORCE_RESET +#define __APB1_RELEASE_RESET __HAL_RCC_APB1_RELEASE_RESET +#define __APB2_FORCE_RESET __HAL_RCC_APB2_FORCE_RESET +#define __APB2_RELEASE_RESET __HAL_RCC_APB2_RELEASE_RESET +#define __BKP_CLK_DISABLE __HAL_RCC_BKP_CLK_DISABLE +#define __BKP_CLK_ENABLE __HAL_RCC_BKP_CLK_ENABLE +#define __BKP_FORCE_RESET __HAL_RCC_BKP_FORCE_RESET +#define __BKP_RELEASE_RESET __HAL_RCC_BKP_RELEASE_RESET +#define __CAN1_CLK_DISABLE __HAL_RCC_CAN1_CLK_DISABLE +#define __CAN1_CLK_ENABLE __HAL_RCC_CAN1_CLK_ENABLE +#define __CAN1_CLK_SLEEP_DISABLE __HAL_RCC_CAN1_CLK_SLEEP_DISABLE +#define __CAN1_CLK_SLEEP_ENABLE __HAL_RCC_CAN1_CLK_SLEEP_ENABLE +#define __CAN1_FORCE_RESET __HAL_RCC_CAN1_FORCE_RESET +#define __CAN1_RELEASE_RESET __HAL_RCC_CAN1_RELEASE_RESET +#define __CAN_CLK_DISABLE __HAL_RCC_CAN1_CLK_DISABLE +#define __CAN_CLK_ENABLE __HAL_RCC_CAN1_CLK_ENABLE +#define __CAN_FORCE_RESET __HAL_RCC_CAN1_FORCE_RESET +#define __CAN_RELEASE_RESET __HAL_RCC_CAN1_RELEASE_RESET +#define __CAN2_CLK_DISABLE __HAL_RCC_CAN2_CLK_DISABLE +#define __CAN2_CLK_ENABLE __HAL_RCC_CAN2_CLK_ENABLE +#define __CAN2_FORCE_RESET __HAL_RCC_CAN2_FORCE_RESET +#define __CAN2_RELEASE_RESET __HAL_RCC_CAN2_RELEASE_RESET +#define __CEC_CLK_DISABLE __HAL_RCC_CEC_CLK_DISABLE +#define __CEC_CLK_ENABLE __HAL_RCC_CEC_CLK_ENABLE +#define __COMP_CLK_DISABLE __HAL_RCC_COMP_CLK_DISABLE +#define __COMP_CLK_ENABLE __HAL_RCC_COMP_CLK_ENABLE +#define __COMP_FORCE_RESET __HAL_RCC_COMP_FORCE_RESET +#define __COMP_RELEASE_RESET __HAL_RCC_COMP_RELEASE_RESET +#define __COMP_CLK_SLEEP_ENABLE __HAL_RCC_COMP_CLK_SLEEP_ENABLE +#define __COMP_CLK_SLEEP_DISABLE __HAL_RCC_COMP_CLK_SLEEP_DISABLE +#define __CEC_FORCE_RESET __HAL_RCC_CEC_FORCE_RESET +#define __CEC_RELEASE_RESET __HAL_RCC_CEC_RELEASE_RESET +#define __CRC_CLK_DISABLE __HAL_RCC_CRC_CLK_DISABLE +#define __CRC_CLK_ENABLE __HAL_RCC_CRC_CLK_ENABLE +#define __CRC_CLK_SLEEP_DISABLE __HAL_RCC_CRC_CLK_SLEEP_DISABLE +#define __CRC_CLK_SLEEP_ENABLE __HAL_RCC_CRC_CLK_SLEEP_ENABLE +#define __CRC_FORCE_RESET __HAL_RCC_CRC_FORCE_RESET +#define __CRC_RELEASE_RESET __HAL_RCC_CRC_RELEASE_RESET +#define __DAC_CLK_DISABLE __HAL_RCC_DAC_CLK_DISABLE +#define __DAC_CLK_ENABLE __HAL_RCC_DAC_CLK_ENABLE +#define __DAC_FORCE_RESET __HAL_RCC_DAC_FORCE_RESET +#define __DAC_RELEASE_RESET __HAL_RCC_DAC_RELEASE_RESET +#define __DAC1_CLK_DISABLE __HAL_RCC_DAC1_CLK_DISABLE +#define __DAC1_CLK_ENABLE __HAL_RCC_DAC1_CLK_ENABLE +#define __DAC1_CLK_SLEEP_DISABLE __HAL_RCC_DAC1_CLK_SLEEP_DISABLE +#define __DAC1_CLK_SLEEP_ENABLE __HAL_RCC_DAC1_CLK_SLEEP_ENABLE +#define __DAC1_FORCE_RESET __HAL_RCC_DAC1_FORCE_RESET +#define __DAC1_RELEASE_RESET __HAL_RCC_DAC1_RELEASE_RESET +#define __DBGMCU_CLK_ENABLE __HAL_RCC_DBGMCU_CLK_ENABLE +#define __DBGMCU_CLK_DISABLE __HAL_RCC_DBGMCU_CLK_DISABLE +#define __DBGMCU_FORCE_RESET __HAL_RCC_DBGMCU_FORCE_RESET +#define __DBGMCU_RELEASE_RESET __HAL_RCC_DBGMCU_RELEASE_RESET +#define __DFSDM_CLK_DISABLE __HAL_RCC_DFSDM_CLK_DISABLE +#define __DFSDM_CLK_ENABLE __HAL_RCC_DFSDM_CLK_ENABLE +#define __DFSDM_CLK_SLEEP_DISABLE __HAL_RCC_DFSDM_CLK_SLEEP_DISABLE +#define __DFSDM_CLK_SLEEP_ENABLE __HAL_RCC_DFSDM_CLK_SLEEP_ENABLE +#define __DFSDM_FORCE_RESET __HAL_RCC_DFSDM_FORCE_RESET +#define __DFSDM_RELEASE_RESET __HAL_RCC_DFSDM_RELEASE_RESET +#define __DMA1_CLK_DISABLE __HAL_RCC_DMA1_CLK_DISABLE +#define __DMA1_CLK_ENABLE __HAL_RCC_DMA1_CLK_ENABLE +#define __DMA1_CLK_SLEEP_DISABLE __HAL_RCC_DMA1_CLK_SLEEP_DISABLE +#define __DMA1_CLK_SLEEP_ENABLE __HAL_RCC_DMA1_CLK_SLEEP_ENABLE +#define __DMA1_FORCE_RESET __HAL_RCC_DMA1_FORCE_RESET +#define __DMA1_RELEASE_RESET __HAL_RCC_DMA1_RELEASE_RESET +#define __DMA2_CLK_DISABLE __HAL_RCC_DMA2_CLK_DISABLE +#define __DMA2_CLK_ENABLE __HAL_RCC_DMA2_CLK_ENABLE +#define __DMA2_CLK_SLEEP_DISABLE __HAL_RCC_DMA2_CLK_SLEEP_DISABLE +#define __DMA2_CLK_SLEEP_ENABLE __HAL_RCC_DMA2_CLK_SLEEP_ENABLE +#define __DMA2_FORCE_RESET __HAL_RCC_DMA2_FORCE_RESET +#define __DMA2_RELEASE_RESET __HAL_RCC_DMA2_RELEASE_RESET +#define __ETHMAC_CLK_DISABLE __HAL_RCC_ETHMAC_CLK_DISABLE +#define __ETHMAC_CLK_ENABLE __HAL_RCC_ETHMAC_CLK_ENABLE +#define __ETHMAC_FORCE_RESET __HAL_RCC_ETHMAC_FORCE_RESET +#define __ETHMAC_RELEASE_RESET __HAL_RCC_ETHMAC_RELEASE_RESET +#define __ETHMACRX_CLK_DISABLE __HAL_RCC_ETHMACRX_CLK_DISABLE +#define __ETHMACRX_CLK_ENABLE __HAL_RCC_ETHMACRX_CLK_ENABLE +#define __ETHMACTX_CLK_DISABLE __HAL_RCC_ETHMACTX_CLK_DISABLE +#define __ETHMACTX_CLK_ENABLE __HAL_RCC_ETHMACTX_CLK_ENABLE +#define __FIREWALL_CLK_DISABLE __HAL_RCC_FIREWALL_CLK_DISABLE +#define __FIREWALL_CLK_ENABLE __HAL_RCC_FIREWALL_CLK_ENABLE +#define __FLASH_CLK_DISABLE __HAL_RCC_FLASH_CLK_DISABLE +#define __FLASH_CLK_ENABLE __HAL_RCC_FLASH_CLK_ENABLE +#define __FLASH_CLK_SLEEP_DISABLE __HAL_RCC_FLASH_CLK_SLEEP_DISABLE +#define __FLASH_CLK_SLEEP_ENABLE __HAL_RCC_FLASH_CLK_SLEEP_ENABLE +#define __FLASH_FORCE_RESET __HAL_RCC_FLASH_FORCE_RESET +#define __FLASH_RELEASE_RESET __HAL_RCC_FLASH_RELEASE_RESET +#define __FLITF_CLK_DISABLE __HAL_RCC_FLITF_CLK_DISABLE +#define __FLITF_CLK_ENABLE __HAL_RCC_FLITF_CLK_ENABLE +#define __FLITF_FORCE_RESET __HAL_RCC_FLITF_FORCE_RESET +#define __FLITF_RELEASE_RESET __HAL_RCC_FLITF_RELEASE_RESET +#define __FLITF_CLK_SLEEP_ENABLE __HAL_RCC_FLITF_CLK_SLEEP_ENABLE +#define __FLITF_CLK_SLEEP_DISABLE __HAL_RCC_FLITF_CLK_SLEEP_DISABLE +#define __FMC_CLK_DISABLE __HAL_RCC_FMC_CLK_DISABLE +#define __FMC_CLK_ENABLE __HAL_RCC_FMC_CLK_ENABLE +#define __FMC_CLK_SLEEP_DISABLE __HAL_RCC_FMC_CLK_SLEEP_DISABLE +#define __FMC_CLK_SLEEP_ENABLE __HAL_RCC_FMC_CLK_SLEEP_ENABLE +#define __FMC_FORCE_RESET __HAL_RCC_FMC_FORCE_RESET +#define __FMC_RELEASE_RESET __HAL_RCC_FMC_RELEASE_RESET +#define __FSMC_CLK_DISABLE __HAL_RCC_FSMC_CLK_DISABLE +#define __FSMC_CLK_ENABLE __HAL_RCC_FSMC_CLK_ENABLE +#define __GPIOA_CLK_DISABLE __HAL_RCC_GPIOA_CLK_DISABLE +#define __GPIOA_CLK_ENABLE __HAL_RCC_GPIOA_CLK_ENABLE +#define __GPIOA_CLK_SLEEP_DISABLE __HAL_RCC_GPIOA_CLK_SLEEP_DISABLE +#define __GPIOA_CLK_SLEEP_ENABLE __HAL_RCC_GPIOA_CLK_SLEEP_ENABLE +#define __GPIOA_FORCE_RESET __HAL_RCC_GPIOA_FORCE_RESET +#define __GPIOA_RELEASE_RESET __HAL_RCC_GPIOA_RELEASE_RESET +#define __GPIOB_CLK_DISABLE __HAL_RCC_GPIOB_CLK_DISABLE +#define __GPIOB_CLK_ENABLE __HAL_RCC_GPIOB_CLK_ENABLE +#define __GPIOB_CLK_SLEEP_DISABLE __HAL_RCC_GPIOB_CLK_SLEEP_DISABLE +#define __GPIOB_CLK_SLEEP_ENABLE __HAL_RCC_GPIOB_CLK_SLEEP_ENABLE +#define __GPIOB_FORCE_RESET __HAL_RCC_GPIOB_FORCE_RESET +#define __GPIOB_RELEASE_RESET __HAL_RCC_GPIOB_RELEASE_RESET +#define __GPIOC_CLK_DISABLE __HAL_RCC_GPIOC_CLK_DISABLE +#define __GPIOC_CLK_ENABLE __HAL_RCC_GPIOC_CLK_ENABLE +#define __GPIOC_CLK_SLEEP_DISABLE __HAL_RCC_GPIOC_CLK_SLEEP_DISABLE +#define __GPIOC_CLK_SLEEP_ENABLE __HAL_RCC_GPIOC_CLK_SLEEP_ENABLE +#define __GPIOC_FORCE_RESET __HAL_RCC_GPIOC_FORCE_RESET +#define __GPIOC_RELEASE_RESET __HAL_RCC_GPIOC_RELEASE_RESET +#define __GPIOD_CLK_DISABLE __HAL_RCC_GPIOD_CLK_DISABLE +#define __GPIOD_CLK_ENABLE __HAL_RCC_GPIOD_CLK_ENABLE +#define __GPIOD_CLK_SLEEP_DISABLE __HAL_RCC_GPIOD_CLK_SLEEP_DISABLE +#define __GPIOD_CLK_SLEEP_ENABLE __HAL_RCC_GPIOD_CLK_SLEEP_ENABLE +#define __GPIOD_FORCE_RESET __HAL_RCC_GPIOD_FORCE_RESET +#define __GPIOD_RELEASE_RESET __HAL_RCC_GPIOD_RELEASE_RESET +#define __GPIOE_CLK_DISABLE __HAL_RCC_GPIOE_CLK_DISABLE +#define __GPIOE_CLK_ENABLE __HAL_RCC_GPIOE_CLK_ENABLE +#define __GPIOE_CLK_SLEEP_DISABLE __HAL_RCC_GPIOE_CLK_SLEEP_DISABLE +#define __GPIOE_CLK_SLEEP_ENABLE __HAL_RCC_GPIOE_CLK_SLEEP_ENABLE +#define __GPIOE_FORCE_RESET __HAL_RCC_GPIOE_FORCE_RESET +#define __GPIOE_RELEASE_RESET __HAL_RCC_GPIOE_RELEASE_RESET +#define __GPIOF_CLK_DISABLE __HAL_RCC_GPIOF_CLK_DISABLE +#define __GPIOF_CLK_ENABLE __HAL_RCC_GPIOF_CLK_ENABLE +#define __GPIOF_CLK_SLEEP_DISABLE __HAL_RCC_GPIOF_CLK_SLEEP_DISABLE +#define __GPIOF_CLK_SLEEP_ENABLE __HAL_RCC_GPIOF_CLK_SLEEP_ENABLE +#define __GPIOF_FORCE_RESET __HAL_RCC_GPIOF_FORCE_RESET +#define __GPIOF_RELEASE_RESET __HAL_RCC_GPIOF_RELEASE_RESET +#define __GPIOG_CLK_DISABLE __HAL_RCC_GPIOG_CLK_DISABLE +#define __GPIOG_CLK_ENABLE __HAL_RCC_GPIOG_CLK_ENABLE +#define __GPIOG_CLK_SLEEP_DISABLE __HAL_RCC_GPIOG_CLK_SLEEP_DISABLE +#define __GPIOG_CLK_SLEEP_ENABLE __HAL_RCC_GPIOG_CLK_SLEEP_ENABLE +#define __GPIOG_FORCE_RESET __HAL_RCC_GPIOG_FORCE_RESET +#define __GPIOG_RELEASE_RESET __HAL_RCC_GPIOG_RELEASE_RESET +#define __GPIOH_CLK_DISABLE __HAL_RCC_GPIOH_CLK_DISABLE +#define __GPIOH_CLK_ENABLE __HAL_RCC_GPIOH_CLK_ENABLE +#define __GPIOH_CLK_SLEEP_DISABLE __HAL_RCC_GPIOH_CLK_SLEEP_DISABLE +#define __GPIOH_CLK_SLEEP_ENABLE __HAL_RCC_GPIOH_CLK_SLEEP_ENABLE +#define __GPIOH_FORCE_RESET __HAL_RCC_GPIOH_FORCE_RESET +#define __GPIOH_RELEASE_RESET __HAL_RCC_GPIOH_RELEASE_RESET +#define __I2C1_CLK_DISABLE __HAL_RCC_I2C1_CLK_DISABLE +#define __I2C1_CLK_ENABLE __HAL_RCC_I2C1_CLK_ENABLE +#define __I2C1_CLK_SLEEP_DISABLE __HAL_RCC_I2C1_CLK_SLEEP_DISABLE +#define __I2C1_CLK_SLEEP_ENABLE __HAL_RCC_I2C1_CLK_SLEEP_ENABLE +#define __I2C1_FORCE_RESET __HAL_RCC_I2C1_FORCE_RESET +#define __I2C1_RELEASE_RESET __HAL_RCC_I2C1_RELEASE_RESET +#define __I2C2_CLK_DISABLE __HAL_RCC_I2C2_CLK_DISABLE +#define __I2C2_CLK_ENABLE __HAL_RCC_I2C2_CLK_ENABLE +#define __I2C2_CLK_SLEEP_DISABLE __HAL_RCC_I2C2_CLK_SLEEP_DISABLE +#define __I2C2_CLK_SLEEP_ENABLE __HAL_RCC_I2C2_CLK_SLEEP_ENABLE +#define __I2C2_FORCE_RESET __HAL_RCC_I2C2_FORCE_RESET +#define __I2C2_RELEASE_RESET __HAL_RCC_I2C2_RELEASE_RESET +#define __I2C3_CLK_DISABLE __HAL_RCC_I2C3_CLK_DISABLE +#define __I2C3_CLK_ENABLE __HAL_RCC_I2C3_CLK_ENABLE +#define __I2C3_CLK_SLEEP_DISABLE __HAL_RCC_I2C3_CLK_SLEEP_DISABLE +#define __I2C3_CLK_SLEEP_ENABLE __HAL_RCC_I2C3_CLK_SLEEP_ENABLE +#define __I2C3_FORCE_RESET __HAL_RCC_I2C3_FORCE_RESET +#define __I2C3_RELEASE_RESET __HAL_RCC_I2C3_RELEASE_RESET +#define __LCD_CLK_DISABLE __HAL_RCC_LCD_CLK_DISABLE +#define __LCD_CLK_ENABLE __HAL_RCC_LCD_CLK_ENABLE +#define __LCD_CLK_SLEEP_DISABLE __HAL_RCC_LCD_CLK_SLEEP_DISABLE +#define __LCD_CLK_SLEEP_ENABLE __HAL_RCC_LCD_CLK_SLEEP_ENABLE +#define __LCD_FORCE_RESET __HAL_RCC_LCD_FORCE_RESET +#define __LCD_RELEASE_RESET __HAL_RCC_LCD_RELEASE_RESET +#define __LPTIM1_CLK_DISABLE __HAL_RCC_LPTIM1_CLK_DISABLE +#define __LPTIM1_CLK_ENABLE __HAL_RCC_LPTIM1_CLK_ENABLE +#define __LPTIM1_CLK_SLEEP_DISABLE __HAL_RCC_LPTIM1_CLK_SLEEP_DISABLE +#define __LPTIM1_CLK_SLEEP_ENABLE __HAL_RCC_LPTIM1_CLK_SLEEP_ENABLE +#define __LPTIM1_FORCE_RESET __HAL_RCC_LPTIM1_FORCE_RESET +#define __LPTIM1_RELEASE_RESET __HAL_RCC_LPTIM1_RELEASE_RESET +#define __LPTIM2_CLK_DISABLE __HAL_RCC_LPTIM2_CLK_DISABLE +#define __LPTIM2_CLK_ENABLE __HAL_RCC_LPTIM2_CLK_ENABLE +#define __LPTIM2_CLK_SLEEP_DISABLE __HAL_RCC_LPTIM2_CLK_SLEEP_DISABLE +#define __LPTIM2_CLK_SLEEP_ENABLE __HAL_RCC_LPTIM2_CLK_SLEEP_ENABLE +#define __LPTIM2_FORCE_RESET __HAL_RCC_LPTIM2_FORCE_RESET +#define __LPTIM2_RELEASE_RESET __HAL_RCC_LPTIM2_RELEASE_RESET +#define __LPUART1_CLK_DISABLE __HAL_RCC_LPUART1_CLK_DISABLE +#define __LPUART1_CLK_ENABLE __HAL_RCC_LPUART1_CLK_ENABLE +#define __LPUART1_CLK_SLEEP_DISABLE __HAL_RCC_LPUART1_CLK_SLEEP_DISABLE +#define __LPUART1_CLK_SLEEP_ENABLE __HAL_RCC_LPUART1_CLK_SLEEP_ENABLE +#define __LPUART1_FORCE_RESET __HAL_RCC_LPUART1_FORCE_RESET +#define __LPUART1_RELEASE_RESET __HAL_RCC_LPUART1_RELEASE_RESET +#define __OPAMP_CLK_DISABLE __HAL_RCC_OPAMP_CLK_DISABLE +#define __OPAMP_CLK_ENABLE __HAL_RCC_OPAMP_CLK_ENABLE +#define __OPAMP_CLK_SLEEP_DISABLE __HAL_RCC_OPAMP_CLK_SLEEP_DISABLE +#define __OPAMP_CLK_SLEEP_ENABLE __HAL_RCC_OPAMP_CLK_SLEEP_ENABLE +#define __OPAMP_FORCE_RESET __HAL_RCC_OPAMP_FORCE_RESET +#define __OPAMP_RELEASE_RESET __HAL_RCC_OPAMP_RELEASE_RESET +#define __OTGFS_CLK_DISABLE __HAL_RCC_OTGFS_CLK_DISABLE +#define __OTGFS_CLK_ENABLE __HAL_RCC_OTGFS_CLK_ENABLE +#define __OTGFS_CLK_SLEEP_DISABLE __HAL_RCC_OTGFS_CLK_SLEEP_DISABLE +#define __OTGFS_CLK_SLEEP_ENABLE __HAL_RCC_OTGFS_CLK_SLEEP_ENABLE +#define __OTGFS_FORCE_RESET __HAL_RCC_OTGFS_FORCE_RESET +#define __OTGFS_RELEASE_RESET __HAL_RCC_OTGFS_RELEASE_RESET +#define __PWR_CLK_DISABLE __HAL_RCC_PWR_CLK_DISABLE +#define __PWR_CLK_ENABLE __HAL_RCC_PWR_CLK_ENABLE +#define __PWR_CLK_SLEEP_DISABLE __HAL_RCC_PWR_CLK_SLEEP_DISABLE +#define __PWR_CLK_SLEEP_ENABLE __HAL_RCC_PWR_CLK_SLEEP_ENABLE +#define __PWR_FORCE_RESET __HAL_RCC_PWR_FORCE_RESET +#define __PWR_RELEASE_RESET __HAL_RCC_PWR_RELEASE_RESET +#define __QSPI_CLK_DISABLE __HAL_RCC_QSPI_CLK_DISABLE +#define __QSPI_CLK_ENABLE __HAL_RCC_QSPI_CLK_ENABLE +#define __QSPI_CLK_SLEEP_DISABLE __HAL_RCC_QSPI_CLK_SLEEP_DISABLE +#define __QSPI_CLK_SLEEP_ENABLE __HAL_RCC_QSPI_CLK_SLEEP_ENABLE +#define __QSPI_FORCE_RESET __HAL_RCC_QSPI_FORCE_RESET +#define __QSPI_RELEASE_RESET __HAL_RCC_QSPI_RELEASE_RESET + +#if defined(STM32WB) +#define __HAL_RCC_QSPI_CLK_DISABLE __HAL_RCC_QUADSPI_CLK_DISABLE +#define __HAL_RCC_QSPI_CLK_ENABLE __HAL_RCC_QUADSPI_CLK_ENABLE +#define __HAL_RCC_QSPI_CLK_SLEEP_DISABLE __HAL_RCC_QUADSPI_CLK_SLEEP_DISABLE +#define __HAL_RCC_QSPI_CLK_SLEEP_ENABLE __HAL_RCC_QUADSPI_CLK_SLEEP_ENABLE +#define __HAL_RCC_QSPI_FORCE_RESET __HAL_RCC_QUADSPI_FORCE_RESET +#define __HAL_RCC_QSPI_RELEASE_RESET __HAL_RCC_QUADSPI_RELEASE_RESET +#define __HAL_RCC_QSPI_IS_CLK_ENABLED __HAL_RCC_QUADSPI_IS_CLK_ENABLED +#define __HAL_RCC_QSPI_IS_CLK_DISABLED __HAL_RCC_QUADSPI_IS_CLK_DISABLED +#define __HAL_RCC_QSPI_IS_CLK_SLEEP_ENABLED __HAL_RCC_QUADSPI_IS_CLK_SLEEP_ENABLED +#define __HAL_RCC_QSPI_IS_CLK_SLEEP_DISABLED __HAL_RCC_QUADSPI_IS_CLK_SLEEP_DISABLED +#define QSPI_IRQHandler QUADSPI_IRQHandler +#endif /* __HAL_RCC_QUADSPI_CLK_ENABLE */ + +#define __RNG_CLK_DISABLE __HAL_RCC_RNG_CLK_DISABLE +#define __RNG_CLK_ENABLE __HAL_RCC_RNG_CLK_ENABLE +#define __RNG_CLK_SLEEP_DISABLE __HAL_RCC_RNG_CLK_SLEEP_DISABLE +#define __RNG_CLK_SLEEP_ENABLE __HAL_RCC_RNG_CLK_SLEEP_ENABLE +#define __RNG_FORCE_RESET __HAL_RCC_RNG_FORCE_RESET +#define __RNG_RELEASE_RESET __HAL_RCC_RNG_RELEASE_RESET +#define __SAI1_CLK_DISABLE __HAL_RCC_SAI1_CLK_DISABLE +#define __SAI1_CLK_ENABLE __HAL_RCC_SAI1_CLK_ENABLE +#define __SAI1_CLK_SLEEP_DISABLE __HAL_RCC_SAI1_CLK_SLEEP_DISABLE +#define __SAI1_CLK_SLEEP_ENABLE __HAL_RCC_SAI1_CLK_SLEEP_ENABLE +#define __SAI1_FORCE_RESET __HAL_RCC_SAI1_FORCE_RESET +#define __SAI1_RELEASE_RESET __HAL_RCC_SAI1_RELEASE_RESET +#define __SAI2_CLK_DISABLE __HAL_RCC_SAI2_CLK_DISABLE +#define __SAI2_CLK_ENABLE __HAL_RCC_SAI2_CLK_ENABLE +#define __SAI2_CLK_SLEEP_DISABLE __HAL_RCC_SAI2_CLK_SLEEP_DISABLE +#define __SAI2_CLK_SLEEP_ENABLE __HAL_RCC_SAI2_CLK_SLEEP_ENABLE +#define __SAI2_FORCE_RESET __HAL_RCC_SAI2_FORCE_RESET +#define __SAI2_RELEASE_RESET __HAL_RCC_SAI2_RELEASE_RESET +#define __SDIO_CLK_DISABLE __HAL_RCC_SDIO_CLK_DISABLE +#define __SDIO_CLK_ENABLE __HAL_RCC_SDIO_CLK_ENABLE +#define __SDMMC_CLK_DISABLE __HAL_RCC_SDMMC_CLK_DISABLE +#define __SDMMC_CLK_ENABLE __HAL_RCC_SDMMC_CLK_ENABLE +#define __SDMMC_CLK_SLEEP_DISABLE __HAL_RCC_SDMMC_CLK_SLEEP_DISABLE +#define __SDMMC_CLK_SLEEP_ENABLE __HAL_RCC_SDMMC_CLK_SLEEP_ENABLE +#define __SDMMC_FORCE_RESET __HAL_RCC_SDMMC_FORCE_RESET +#define __SDMMC_RELEASE_RESET __HAL_RCC_SDMMC_RELEASE_RESET +#define __SPI1_CLK_DISABLE __HAL_RCC_SPI1_CLK_DISABLE +#define __SPI1_CLK_ENABLE __HAL_RCC_SPI1_CLK_ENABLE +#define __SPI1_CLK_SLEEP_DISABLE __HAL_RCC_SPI1_CLK_SLEEP_DISABLE +#define __SPI1_CLK_SLEEP_ENABLE __HAL_RCC_SPI1_CLK_SLEEP_ENABLE +#define __SPI1_FORCE_RESET __HAL_RCC_SPI1_FORCE_RESET +#define __SPI1_RELEASE_RESET __HAL_RCC_SPI1_RELEASE_RESET +#define __SPI2_CLK_DISABLE __HAL_RCC_SPI2_CLK_DISABLE +#define __SPI2_CLK_ENABLE __HAL_RCC_SPI2_CLK_ENABLE +#define __SPI2_CLK_SLEEP_DISABLE __HAL_RCC_SPI2_CLK_SLEEP_DISABLE +#define __SPI2_CLK_SLEEP_ENABLE __HAL_RCC_SPI2_CLK_SLEEP_ENABLE +#define __SPI2_FORCE_RESET __HAL_RCC_SPI2_FORCE_RESET +#define __SPI2_RELEASE_RESET __HAL_RCC_SPI2_RELEASE_RESET +#define __SPI3_CLK_DISABLE __HAL_RCC_SPI3_CLK_DISABLE +#define __SPI3_CLK_ENABLE __HAL_RCC_SPI3_CLK_ENABLE +#define __SPI3_CLK_SLEEP_DISABLE __HAL_RCC_SPI3_CLK_SLEEP_DISABLE +#define __SPI3_CLK_SLEEP_ENABLE __HAL_RCC_SPI3_CLK_SLEEP_ENABLE +#define __SPI3_FORCE_RESET __HAL_RCC_SPI3_FORCE_RESET +#define __SPI3_RELEASE_RESET __HAL_RCC_SPI3_RELEASE_RESET +#define __SRAM_CLK_DISABLE __HAL_RCC_SRAM_CLK_DISABLE +#define __SRAM_CLK_ENABLE __HAL_RCC_SRAM_CLK_ENABLE +#define __SRAM1_CLK_SLEEP_DISABLE __HAL_RCC_SRAM1_CLK_SLEEP_DISABLE +#define __SRAM1_CLK_SLEEP_ENABLE __HAL_RCC_SRAM1_CLK_SLEEP_ENABLE +#define __SRAM2_CLK_SLEEP_DISABLE __HAL_RCC_SRAM2_CLK_SLEEP_DISABLE +#define __SRAM2_CLK_SLEEP_ENABLE __HAL_RCC_SRAM2_CLK_SLEEP_ENABLE +#define __SWPMI1_CLK_DISABLE __HAL_RCC_SWPMI1_CLK_DISABLE +#define __SWPMI1_CLK_ENABLE __HAL_RCC_SWPMI1_CLK_ENABLE +#define __SWPMI1_CLK_SLEEP_DISABLE __HAL_RCC_SWPMI1_CLK_SLEEP_DISABLE +#define __SWPMI1_CLK_SLEEP_ENABLE __HAL_RCC_SWPMI1_CLK_SLEEP_ENABLE +#define __SWPMI1_FORCE_RESET __HAL_RCC_SWPMI1_FORCE_RESET +#define __SWPMI1_RELEASE_RESET __HAL_RCC_SWPMI1_RELEASE_RESET +#define __SYSCFG_CLK_DISABLE __HAL_RCC_SYSCFG_CLK_DISABLE +#define __SYSCFG_CLK_ENABLE __HAL_RCC_SYSCFG_CLK_ENABLE +#define __SYSCFG_CLK_SLEEP_DISABLE __HAL_RCC_SYSCFG_CLK_SLEEP_DISABLE +#define __SYSCFG_CLK_SLEEP_ENABLE __HAL_RCC_SYSCFG_CLK_SLEEP_ENABLE +#define __SYSCFG_FORCE_RESET __HAL_RCC_SYSCFG_FORCE_RESET +#define __SYSCFG_RELEASE_RESET __HAL_RCC_SYSCFG_RELEASE_RESET +#define __TIM1_CLK_DISABLE __HAL_RCC_TIM1_CLK_DISABLE +#define __TIM1_CLK_ENABLE __HAL_RCC_TIM1_CLK_ENABLE +#define __TIM1_CLK_SLEEP_DISABLE __HAL_RCC_TIM1_CLK_SLEEP_DISABLE +#define __TIM1_CLK_SLEEP_ENABLE __HAL_RCC_TIM1_CLK_SLEEP_ENABLE +#define __TIM1_FORCE_RESET __HAL_RCC_TIM1_FORCE_RESET +#define __TIM1_RELEASE_RESET __HAL_RCC_TIM1_RELEASE_RESET +#define __TIM10_CLK_DISABLE __HAL_RCC_TIM10_CLK_DISABLE +#define __TIM10_CLK_ENABLE __HAL_RCC_TIM10_CLK_ENABLE +#define __TIM10_FORCE_RESET __HAL_RCC_TIM10_FORCE_RESET +#define __TIM10_RELEASE_RESET __HAL_RCC_TIM10_RELEASE_RESET +#define __TIM11_CLK_DISABLE __HAL_RCC_TIM11_CLK_DISABLE +#define __TIM11_CLK_ENABLE __HAL_RCC_TIM11_CLK_ENABLE +#define __TIM11_FORCE_RESET __HAL_RCC_TIM11_FORCE_RESET +#define __TIM11_RELEASE_RESET __HAL_RCC_TIM11_RELEASE_RESET +#define __TIM12_CLK_DISABLE __HAL_RCC_TIM12_CLK_DISABLE +#define __TIM12_CLK_ENABLE __HAL_RCC_TIM12_CLK_ENABLE +#define __TIM12_FORCE_RESET __HAL_RCC_TIM12_FORCE_RESET +#define __TIM12_RELEASE_RESET __HAL_RCC_TIM12_RELEASE_RESET +#define __TIM13_CLK_DISABLE __HAL_RCC_TIM13_CLK_DISABLE +#define __TIM13_CLK_ENABLE __HAL_RCC_TIM13_CLK_ENABLE +#define __TIM13_FORCE_RESET __HAL_RCC_TIM13_FORCE_RESET +#define __TIM13_RELEASE_RESET __HAL_RCC_TIM13_RELEASE_RESET +#define __TIM14_CLK_DISABLE __HAL_RCC_TIM14_CLK_DISABLE +#define __TIM14_CLK_ENABLE __HAL_RCC_TIM14_CLK_ENABLE +#define __TIM14_FORCE_RESET __HAL_RCC_TIM14_FORCE_RESET +#define __TIM14_RELEASE_RESET __HAL_RCC_TIM14_RELEASE_RESET +#define __TIM15_CLK_DISABLE __HAL_RCC_TIM15_CLK_DISABLE +#define __TIM15_CLK_ENABLE __HAL_RCC_TIM15_CLK_ENABLE +#define __TIM15_CLK_SLEEP_DISABLE __HAL_RCC_TIM15_CLK_SLEEP_DISABLE +#define __TIM15_CLK_SLEEP_ENABLE __HAL_RCC_TIM15_CLK_SLEEP_ENABLE +#define __TIM15_FORCE_RESET __HAL_RCC_TIM15_FORCE_RESET +#define __TIM15_RELEASE_RESET __HAL_RCC_TIM15_RELEASE_RESET +#define __TIM16_CLK_DISABLE __HAL_RCC_TIM16_CLK_DISABLE +#define __TIM16_CLK_ENABLE __HAL_RCC_TIM16_CLK_ENABLE +#define __TIM16_CLK_SLEEP_DISABLE __HAL_RCC_TIM16_CLK_SLEEP_DISABLE +#define __TIM16_CLK_SLEEP_ENABLE __HAL_RCC_TIM16_CLK_SLEEP_ENABLE +#define __TIM16_FORCE_RESET __HAL_RCC_TIM16_FORCE_RESET +#define __TIM16_RELEASE_RESET __HAL_RCC_TIM16_RELEASE_RESET +#define __TIM17_CLK_DISABLE __HAL_RCC_TIM17_CLK_DISABLE +#define __TIM17_CLK_ENABLE __HAL_RCC_TIM17_CLK_ENABLE +#define __TIM17_CLK_SLEEP_DISABLE __HAL_RCC_TIM17_CLK_SLEEP_DISABLE +#define __TIM17_CLK_SLEEP_ENABLE __HAL_RCC_TIM17_CLK_SLEEP_ENABLE +#define __TIM17_FORCE_RESET __HAL_RCC_TIM17_FORCE_RESET +#define __TIM17_RELEASE_RESET __HAL_RCC_TIM17_RELEASE_RESET +#define __TIM2_CLK_DISABLE __HAL_RCC_TIM2_CLK_DISABLE +#define __TIM2_CLK_ENABLE __HAL_RCC_TIM2_CLK_ENABLE +#define __TIM2_CLK_SLEEP_DISABLE __HAL_RCC_TIM2_CLK_SLEEP_DISABLE +#define __TIM2_CLK_SLEEP_ENABLE __HAL_RCC_TIM2_CLK_SLEEP_ENABLE +#define __TIM2_FORCE_RESET __HAL_RCC_TIM2_FORCE_RESET +#define __TIM2_RELEASE_RESET __HAL_RCC_TIM2_RELEASE_RESET +#define __TIM3_CLK_DISABLE __HAL_RCC_TIM3_CLK_DISABLE +#define __TIM3_CLK_ENABLE __HAL_RCC_TIM3_CLK_ENABLE +#define __TIM3_CLK_SLEEP_DISABLE __HAL_RCC_TIM3_CLK_SLEEP_DISABLE +#define __TIM3_CLK_SLEEP_ENABLE __HAL_RCC_TIM3_CLK_SLEEP_ENABLE +#define __TIM3_FORCE_RESET __HAL_RCC_TIM3_FORCE_RESET +#define __TIM3_RELEASE_RESET __HAL_RCC_TIM3_RELEASE_RESET +#define __TIM4_CLK_DISABLE __HAL_RCC_TIM4_CLK_DISABLE +#define __TIM4_CLK_ENABLE __HAL_RCC_TIM4_CLK_ENABLE +#define __TIM4_CLK_SLEEP_DISABLE __HAL_RCC_TIM4_CLK_SLEEP_DISABLE +#define __TIM4_CLK_SLEEP_ENABLE __HAL_RCC_TIM4_CLK_SLEEP_ENABLE +#define __TIM4_FORCE_RESET __HAL_RCC_TIM4_FORCE_RESET +#define __TIM4_RELEASE_RESET __HAL_RCC_TIM4_RELEASE_RESET +#define __TIM5_CLK_DISABLE __HAL_RCC_TIM5_CLK_DISABLE +#define __TIM5_CLK_ENABLE __HAL_RCC_TIM5_CLK_ENABLE +#define __TIM5_CLK_SLEEP_DISABLE __HAL_RCC_TIM5_CLK_SLEEP_DISABLE +#define __TIM5_CLK_SLEEP_ENABLE __HAL_RCC_TIM5_CLK_SLEEP_ENABLE +#define __TIM5_FORCE_RESET __HAL_RCC_TIM5_FORCE_RESET +#define __TIM5_RELEASE_RESET __HAL_RCC_TIM5_RELEASE_RESET +#define __TIM6_CLK_DISABLE __HAL_RCC_TIM6_CLK_DISABLE +#define __TIM6_CLK_ENABLE __HAL_RCC_TIM6_CLK_ENABLE +#define __TIM6_CLK_SLEEP_DISABLE __HAL_RCC_TIM6_CLK_SLEEP_DISABLE +#define __TIM6_CLK_SLEEP_ENABLE __HAL_RCC_TIM6_CLK_SLEEP_ENABLE +#define __TIM6_FORCE_RESET __HAL_RCC_TIM6_FORCE_RESET +#define __TIM6_RELEASE_RESET __HAL_RCC_TIM6_RELEASE_RESET +#define __TIM7_CLK_DISABLE __HAL_RCC_TIM7_CLK_DISABLE +#define __TIM7_CLK_ENABLE __HAL_RCC_TIM7_CLK_ENABLE +#define __TIM7_CLK_SLEEP_DISABLE __HAL_RCC_TIM7_CLK_SLEEP_DISABLE +#define __TIM7_CLK_SLEEP_ENABLE __HAL_RCC_TIM7_CLK_SLEEP_ENABLE +#define __TIM7_FORCE_RESET __HAL_RCC_TIM7_FORCE_RESET +#define __TIM7_RELEASE_RESET __HAL_RCC_TIM7_RELEASE_RESET +#define __TIM8_CLK_DISABLE __HAL_RCC_TIM8_CLK_DISABLE +#define __TIM8_CLK_ENABLE __HAL_RCC_TIM8_CLK_ENABLE +#define __TIM8_CLK_SLEEP_DISABLE __HAL_RCC_TIM8_CLK_SLEEP_DISABLE +#define __TIM8_CLK_SLEEP_ENABLE __HAL_RCC_TIM8_CLK_SLEEP_ENABLE +#define __TIM8_FORCE_RESET __HAL_RCC_TIM8_FORCE_RESET +#define __TIM8_RELEASE_RESET __HAL_RCC_TIM8_RELEASE_RESET +#define __TIM9_CLK_DISABLE __HAL_RCC_TIM9_CLK_DISABLE +#define __TIM9_CLK_ENABLE __HAL_RCC_TIM9_CLK_ENABLE +#define __TIM9_FORCE_RESET __HAL_RCC_TIM9_FORCE_RESET +#define __TIM9_RELEASE_RESET __HAL_RCC_TIM9_RELEASE_RESET +#define __TSC_CLK_DISABLE __HAL_RCC_TSC_CLK_DISABLE +#define __TSC_CLK_ENABLE __HAL_RCC_TSC_CLK_ENABLE +#define __TSC_CLK_SLEEP_DISABLE __HAL_RCC_TSC_CLK_SLEEP_DISABLE +#define __TSC_CLK_SLEEP_ENABLE __HAL_RCC_TSC_CLK_SLEEP_ENABLE +#define __TSC_FORCE_RESET __HAL_RCC_TSC_FORCE_RESET +#define __TSC_RELEASE_RESET __HAL_RCC_TSC_RELEASE_RESET +#define __UART4_CLK_DISABLE __HAL_RCC_UART4_CLK_DISABLE +#define __UART4_CLK_ENABLE __HAL_RCC_UART4_CLK_ENABLE +#define __UART4_CLK_SLEEP_DISABLE __HAL_RCC_UART4_CLK_SLEEP_DISABLE +#define __UART4_CLK_SLEEP_ENABLE __HAL_RCC_UART4_CLK_SLEEP_ENABLE +#define __UART4_FORCE_RESET __HAL_RCC_UART4_FORCE_RESET +#define __UART4_RELEASE_RESET __HAL_RCC_UART4_RELEASE_RESET +#define __UART5_CLK_DISABLE __HAL_RCC_UART5_CLK_DISABLE +#define __UART5_CLK_ENABLE __HAL_RCC_UART5_CLK_ENABLE +#define __UART5_CLK_SLEEP_DISABLE __HAL_RCC_UART5_CLK_SLEEP_DISABLE +#define __UART5_CLK_SLEEP_ENABLE __HAL_RCC_UART5_CLK_SLEEP_ENABLE +#define __UART5_FORCE_RESET __HAL_RCC_UART5_FORCE_RESET +#define __UART5_RELEASE_RESET __HAL_RCC_UART5_RELEASE_RESET +#define __USART1_CLK_DISABLE __HAL_RCC_USART1_CLK_DISABLE +#define __USART1_CLK_ENABLE __HAL_RCC_USART1_CLK_ENABLE +#define __USART1_CLK_SLEEP_DISABLE __HAL_RCC_USART1_CLK_SLEEP_DISABLE +#define __USART1_CLK_SLEEP_ENABLE __HAL_RCC_USART1_CLK_SLEEP_ENABLE +#define __USART1_FORCE_RESET __HAL_RCC_USART1_FORCE_RESET +#define __USART1_RELEASE_RESET __HAL_RCC_USART1_RELEASE_RESET +#define __USART2_CLK_DISABLE __HAL_RCC_USART2_CLK_DISABLE +#define __USART2_CLK_ENABLE __HAL_RCC_USART2_CLK_ENABLE +#define __USART2_CLK_SLEEP_DISABLE __HAL_RCC_USART2_CLK_SLEEP_DISABLE +#define __USART2_CLK_SLEEP_ENABLE __HAL_RCC_USART2_CLK_SLEEP_ENABLE +#define __USART2_FORCE_RESET __HAL_RCC_USART2_FORCE_RESET +#define __USART2_RELEASE_RESET __HAL_RCC_USART2_RELEASE_RESET +#define __USART3_CLK_DISABLE __HAL_RCC_USART3_CLK_DISABLE +#define __USART3_CLK_ENABLE __HAL_RCC_USART3_CLK_ENABLE +#define __USART3_CLK_SLEEP_DISABLE __HAL_RCC_USART3_CLK_SLEEP_DISABLE +#define __USART3_CLK_SLEEP_ENABLE __HAL_RCC_USART3_CLK_SLEEP_ENABLE +#define __USART3_FORCE_RESET __HAL_RCC_USART3_FORCE_RESET +#define __USART3_RELEASE_RESET __HAL_RCC_USART3_RELEASE_RESET +#define __USART4_CLK_DISABLE __HAL_RCC_UART4_CLK_DISABLE +#define __USART4_CLK_ENABLE __HAL_RCC_UART4_CLK_ENABLE +#define __USART4_CLK_SLEEP_ENABLE __HAL_RCC_UART4_CLK_SLEEP_ENABLE +#define __USART4_CLK_SLEEP_DISABLE __HAL_RCC_UART4_CLK_SLEEP_DISABLE +#define __USART4_FORCE_RESET __HAL_RCC_UART4_FORCE_RESET +#define __USART4_RELEASE_RESET __HAL_RCC_UART4_RELEASE_RESET +#define __USART5_CLK_DISABLE __HAL_RCC_UART5_CLK_DISABLE +#define __USART5_CLK_ENABLE __HAL_RCC_UART5_CLK_ENABLE +#define __USART5_CLK_SLEEP_ENABLE __HAL_RCC_UART5_CLK_SLEEP_ENABLE +#define __USART5_CLK_SLEEP_DISABLE __HAL_RCC_UART5_CLK_SLEEP_DISABLE +#define __USART5_FORCE_RESET __HAL_RCC_UART5_FORCE_RESET +#define __USART5_RELEASE_RESET __HAL_RCC_UART5_RELEASE_RESET +#define __USART7_CLK_DISABLE __HAL_RCC_UART7_CLK_DISABLE +#define __USART7_CLK_ENABLE __HAL_RCC_UART7_CLK_ENABLE +#define __USART7_FORCE_RESET __HAL_RCC_UART7_FORCE_RESET +#define __USART7_RELEASE_RESET __HAL_RCC_UART7_RELEASE_RESET +#define __USART8_CLK_DISABLE __HAL_RCC_UART8_CLK_DISABLE +#define __USART8_CLK_ENABLE __HAL_RCC_UART8_CLK_ENABLE +#define __USART8_FORCE_RESET __HAL_RCC_UART8_FORCE_RESET +#define __USART8_RELEASE_RESET __HAL_RCC_UART8_RELEASE_RESET +#define __USB_CLK_DISABLE __HAL_RCC_USB_CLK_DISABLE +#define __USB_CLK_ENABLE __HAL_RCC_USB_CLK_ENABLE +#define __USB_FORCE_RESET __HAL_RCC_USB_FORCE_RESET +#define __USB_CLK_SLEEP_ENABLE __HAL_RCC_USB_CLK_SLEEP_ENABLE +#define __USB_CLK_SLEEP_DISABLE __HAL_RCC_USB_CLK_SLEEP_DISABLE +#define __USB_OTG_FS_CLK_DISABLE __HAL_RCC_USB_OTG_FS_CLK_DISABLE +#define __USB_OTG_FS_CLK_ENABLE __HAL_RCC_USB_OTG_FS_CLK_ENABLE +#define __USB_RELEASE_RESET __HAL_RCC_USB_RELEASE_RESET + +#if defined(STM32H7) +#define __HAL_RCC_WWDG_CLK_DISABLE __HAL_RCC_WWDG1_CLK_DISABLE +#define __HAL_RCC_WWDG_CLK_ENABLE __HAL_RCC_WWDG1_CLK_ENABLE +#define __HAL_RCC_WWDG_CLK_SLEEP_DISABLE __HAL_RCC_WWDG1_CLK_SLEEP_DISABLE +#define __HAL_RCC_WWDG_CLK_SLEEP_ENABLE __HAL_RCC_WWDG1_CLK_SLEEP_ENABLE + +#define __HAL_RCC_WWDG_FORCE_RESET ((void)0U) /* Not available on the STM32H7*/ +#define __HAL_RCC_WWDG_RELEASE_RESET ((void)0U) /* Not available on the STM32H7*/ + + +#define __HAL_RCC_WWDG_IS_CLK_ENABLED __HAL_RCC_WWDG1_IS_CLK_ENABLED +#define __HAL_RCC_WWDG_IS_CLK_DISABLED __HAL_RCC_WWDG1_IS_CLK_DISABLED +#endif + +#define __WWDG_CLK_DISABLE __HAL_RCC_WWDG_CLK_DISABLE +#define __WWDG_CLK_ENABLE __HAL_RCC_WWDG_CLK_ENABLE +#define __WWDG_CLK_SLEEP_DISABLE __HAL_RCC_WWDG_CLK_SLEEP_DISABLE +#define __WWDG_CLK_SLEEP_ENABLE __HAL_RCC_WWDG_CLK_SLEEP_ENABLE +#define __WWDG_FORCE_RESET __HAL_RCC_WWDG_FORCE_RESET +#define __WWDG_RELEASE_RESET __HAL_RCC_WWDG_RELEASE_RESET + +#define __TIM21_CLK_ENABLE __HAL_RCC_TIM21_CLK_ENABLE +#define __TIM21_CLK_DISABLE __HAL_RCC_TIM21_CLK_DISABLE +#define __TIM21_FORCE_RESET __HAL_RCC_TIM21_FORCE_RESET +#define __TIM21_RELEASE_RESET __HAL_RCC_TIM21_RELEASE_RESET +#define __TIM21_CLK_SLEEP_ENABLE __HAL_RCC_TIM21_CLK_SLEEP_ENABLE +#define __TIM21_CLK_SLEEP_DISABLE __HAL_RCC_TIM21_CLK_SLEEP_DISABLE +#define __TIM22_CLK_ENABLE __HAL_RCC_TIM22_CLK_ENABLE +#define __TIM22_CLK_DISABLE __HAL_RCC_TIM22_CLK_DISABLE +#define __TIM22_FORCE_RESET __HAL_RCC_TIM22_FORCE_RESET +#define __TIM22_RELEASE_RESET __HAL_RCC_TIM22_RELEASE_RESET +#define __TIM22_CLK_SLEEP_ENABLE __HAL_RCC_TIM22_CLK_SLEEP_ENABLE +#define __TIM22_CLK_SLEEP_DISABLE __HAL_RCC_TIM22_CLK_SLEEP_DISABLE +#define __CRS_CLK_DISABLE __HAL_RCC_CRS_CLK_DISABLE +#define __CRS_CLK_ENABLE __HAL_RCC_CRS_CLK_ENABLE +#define __CRS_CLK_SLEEP_DISABLE __HAL_RCC_CRS_CLK_SLEEP_DISABLE +#define __CRS_CLK_SLEEP_ENABLE __HAL_RCC_CRS_CLK_SLEEP_ENABLE +#define __CRS_FORCE_RESET __HAL_RCC_CRS_FORCE_RESET +#define __CRS_RELEASE_RESET __HAL_RCC_CRS_RELEASE_RESET +#define __RCC_BACKUPRESET_FORCE __HAL_RCC_BACKUPRESET_FORCE +#define __RCC_BACKUPRESET_RELEASE __HAL_RCC_BACKUPRESET_RELEASE + +#define __USB_OTG_FS_FORCE_RESET __HAL_RCC_USB_OTG_FS_FORCE_RESET +#define __USB_OTG_FS_RELEASE_RESET __HAL_RCC_USB_OTG_FS_RELEASE_RESET +#define __USB_OTG_FS_CLK_SLEEP_ENABLE __HAL_RCC_USB_OTG_FS_CLK_SLEEP_ENABLE +#define __USB_OTG_FS_CLK_SLEEP_DISABLE __HAL_RCC_USB_OTG_FS_CLK_SLEEP_DISABLE +#define __USB_OTG_HS_CLK_DISABLE __HAL_RCC_USB_OTG_HS_CLK_DISABLE +#define __USB_OTG_HS_CLK_ENABLE __HAL_RCC_USB_OTG_HS_CLK_ENABLE +#define __USB_OTG_HS_ULPI_CLK_ENABLE __HAL_RCC_USB_OTG_HS_ULPI_CLK_ENABLE +#define __USB_OTG_HS_ULPI_CLK_DISABLE __HAL_RCC_USB_OTG_HS_ULPI_CLK_DISABLE +#define __TIM9_CLK_SLEEP_ENABLE __HAL_RCC_TIM9_CLK_SLEEP_ENABLE +#define __TIM9_CLK_SLEEP_DISABLE __HAL_RCC_TIM9_CLK_SLEEP_DISABLE +#define __TIM10_CLK_SLEEP_ENABLE __HAL_RCC_TIM10_CLK_SLEEP_ENABLE +#define __TIM10_CLK_SLEEP_DISABLE __HAL_RCC_TIM10_CLK_SLEEP_DISABLE +#define __TIM11_CLK_SLEEP_ENABLE __HAL_RCC_TIM11_CLK_SLEEP_ENABLE +#define __TIM11_CLK_SLEEP_DISABLE __HAL_RCC_TIM11_CLK_SLEEP_DISABLE +#define __ETHMACPTP_CLK_SLEEP_ENABLE __HAL_RCC_ETHMACPTP_CLK_SLEEP_ENABLE +#define __ETHMACPTP_CLK_SLEEP_DISABLE __HAL_RCC_ETHMACPTP_CLK_SLEEP_DISABLE +#define __ETHMACPTP_CLK_ENABLE __HAL_RCC_ETHMACPTP_CLK_ENABLE +#define __ETHMACPTP_CLK_DISABLE __HAL_RCC_ETHMACPTP_CLK_DISABLE +#define __HASH_CLK_ENABLE __HAL_RCC_HASH_CLK_ENABLE +#define __HASH_FORCE_RESET __HAL_RCC_HASH_FORCE_RESET +#define __HASH_RELEASE_RESET __HAL_RCC_HASH_RELEASE_RESET +#define __HASH_CLK_SLEEP_ENABLE __HAL_RCC_HASH_CLK_SLEEP_ENABLE +#define __HASH_CLK_SLEEP_DISABLE __HAL_RCC_HASH_CLK_SLEEP_DISABLE +#define __HASH_CLK_DISABLE __HAL_RCC_HASH_CLK_DISABLE +#define __SPI5_CLK_ENABLE __HAL_RCC_SPI5_CLK_ENABLE +#define __SPI5_CLK_DISABLE __HAL_RCC_SPI5_CLK_DISABLE +#define __SPI5_FORCE_RESET __HAL_RCC_SPI5_FORCE_RESET +#define __SPI5_RELEASE_RESET __HAL_RCC_SPI5_RELEASE_RESET +#define __SPI5_CLK_SLEEP_ENABLE __HAL_RCC_SPI5_CLK_SLEEP_ENABLE +#define __SPI5_CLK_SLEEP_DISABLE __HAL_RCC_SPI5_CLK_SLEEP_DISABLE +#define __SPI6_CLK_ENABLE __HAL_RCC_SPI6_CLK_ENABLE +#define __SPI6_CLK_DISABLE __HAL_RCC_SPI6_CLK_DISABLE +#define __SPI6_FORCE_RESET __HAL_RCC_SPI6_FORCE_RESET +#define __SPI6_RELEASE_RESET __HAL_RCC_SPI6_RELEASE_RESET +#define __SPI6_CLK_SLEEP_ENABLE __HAL_RCC_SPI6_CLK_SLEEP_ENABLE +#define __SPI6_CLK_SLEEP_DISABLE __HAL_RCC_SPI6_CLK_SLEEP_DISABLE +#define __LTDC_CLK_ENABLE __HAL_RCC_LTDC_CLK_ENABLE +#define __LTDC_CLK_DISABLE __HAL_RCC_LTDC_CLK_DISABLE +#define __LTDC_FORCE_RESET __HAL_RCC_LTDC_FORCE_RESET +#define __LTDC_RELEASE_RESET __HAL_RCC_LTDC_RELEASE_RESET +#define __LTDC_CLK_SLEEP_ENABLE __HAL_RCC_LTDC_CLK_SLEEP_ENABLE +#define __ETHMAC_CLK_SLEEP_ENABLE __HAL_RCC_ETHMAC_CLK_SLEEP_ENABLE +#define __ETHMAC_CLK_SLEEP_DISABLE __HAL_RCC_ETHMAC_CLK_SLEEP_DISABLE +#define __ETHMACTX_CLK_SLEEP_ENABLE __HAL_RCC_ETHMACTX_CLK_SLEEP_ENABLE +#define __ETHMACTX_CLK_SLEEP_DISABLE __HAL_RCC_ETHMACTX_CLK_SLEEP_DISABLE +#define __ETHMACRX_CLK_SLEEP_ENABLE __HAL_RCC_ETHMACRX_CLK_SLEEP_ENABLE +#define __ETHMACRX_CLK_SLEEP_DISABLE __HAL_RCC_ETHMACRX_CLK_SLEEP_DISABLE +#define __TIM12_CLK_SLEEP_ENABLE __HAL_RCC_TIM12_CLK_SLEEP_ENABLE +#define __TIM12_CLK_SLEEP_DISABLE __HAL_RCC_TIM12_CLK_SLEEP_DISABLE +#define __TIM13_CLK_SLEEP_ENABLE __HAL_RCC_TIM13_CLK_SLEEP_ENABLE +#define __TIM13_CLK_SLEEP_DISABLE __HAL_RCC_TIM13_CLK_SLEEP_DISABLE +#define __TIM14_CLK_SLEEP_ENABLE __HAL_RCC_TIM14_CLK_SLEEP_ENABLE +#define __TIM14_CLK_SLEEP_DISABLE __HAL_RCC_TIM14_CLK_SLEEP_DISABLE +#define __BKPSRAM_CLK_ENABLE __HAL_RCC_BKPSRAM_CLK_ENABLE +#define __BKPSRAM_CLK_DISABLE __HAL_RCC_BKPSRAM_CLK_DISABLE +#define __BKPSRAM_CLK_SLEEP_ENABLE __HAL_RCC_BKPSRAM_CLK_SLEEP_ENABLE +#define __BKPSRAM_CLK_SLEEP_DISABLE __HAL_RCC_BKPSRAM_CLK_SLEEP_DISABLE +#define __CCMDATARAMEN_CLK_ENABLE __HAL_RCC_CCMDATARAMEN_CLK_ENABLE +#define __CCMDATARAMEN_CLK_DISABLE __HAL_RCC_CCMDATARAMEN_CLK_DISABLE +#define __USART6_CLK_ENABLE __HAL_RCC_USART6_CLK_ENABLE +#define __USART6_CLK_DISABLE __HAL_RCC_USART6_CLK_DISABLE +#define __USART6_FORCE_RESET __HAL_RCC_USART6_FORCE_RESET +#define __USART6_RELEASE_RESET __HAL_RCC_USART6_RELEASE_RESET +#define __USART6_CLK_SLEEP_ENABLE __HAL_RCC_USART6_CLK_SLEEP_ENABLE +#define __USART6_CLK_SLEEP_DISABLE __HAL_RCC_USART6_CLK_SLEEP_DISABLE +#define __SPI4_CLK_ENABLE __HAL_RCC_SPI4_CLK_ENABLE +#define __SPI4_CLK_DISABLE __HAL_RCC_SPI4_CLK_DISABLE +#define __SPI4_FORCE_RESET __HAL_RCC_SPI4_FORCE_RESET +#define __SPI4_RELEASE_RESET __HAL_RCC_SPI4_RELEASE_RESET +#define __SPI4_CLK_SLEEP_ENABLE __HAL_RCC_SPI4_CLK_SLEEP_ENABLE +#define __SPI4_CLK_SLEEP_DISABLE __HAL_RCC_SPI4_CLK_SLEEP_DISABLE +#define __GPIOI_CLK_ENABLE __HAL_RCC_GPIOI_CLK_ENABLE +#define __GPIOI_CLK_DISABLE __HAL_RCC_GPIOI_CLK_DISABLE +#define __GPIOI_FORCE_RESET __HAL_RCC_GPIOI_FORCE_RESET +#define __GPIOI_RELEASE_RESET __HAL_RCC_GPIOI_RELEASE_RESET +#define __GPIOI_CLK_SLEEP_ENABLE __HAL_RCC_GPIOI_CLK_SLEEP_ENABLE +#define __GPIOI_CLK_SLEEP_DISABLE __HAL_RCC_GPIOI_CLK_SLEEP_DISABLE +#define __GPIOJ_CLK_ENABLE __HAL_RCC_GPIOJ_CLK_ENABLE +#define __GPIOJ_CLK_DISABLE __HAL_RCC_GPIOJ_CLK_DISABLE +#define __GPIOJ_FORCE_RESET __HAL_RCC_GPIOJ_FORCE_RESET +#define __GPIOJ_RELEASE_RESET __HAL_RCC_GPIOJ_RELEASE_RESET +#define __GPIOJ_CLK_SLEEP_ENABLE __HAL_RCC_GPIOJ_CLK_SLEEP_ENABLE +#define __GPIOJ_CLK_SLEEP_DISABLE __HAL_RCC_GPIOJ_CLK_SLEEP_DISABLE +#define __GPIOK_CLK_ENABLE __HAL_RCC_GPIOK_CLK_ENABLE +#define __GPIOK_CLK_DISABLE __HAL_RCC_GPIOK_CLK_DISABLE +#define __GPIOK_RELEASE_RESET __HAL_RCC_GPIOK_RELEASE_RESET +#define __GPIOK_CLK_SLEEP_ENABLE __HAL_RCC_GPIOK_CLK_SLEEP_ENABLE +#define __GPIOK_CLK_SLEEP_DISABLE __HAL_RCC_GPIOK_CLK_SLEEP_DISABLE +#define __ETH_CLK_ENABLE __HAL_RCC_ETH_CLK_ENABLE +#define __ETH_CLK_DISABLE __HAL_RCC_ETH_CLK_DISABLE +#define __DCMI_CLK_ENABLE __HAL_RCC_DCMI_CLK_ENABLE +#define __DCMI_CLK_DISABLE __HAL_RCC_DCMI_CLK_DISABLE +#define __DCMI_FORCE_RESET __HAL_RCC_DCMI_FORCE_RESET +#define __DCMI_RELEASE_RESET __HAL_RCC_DCMI_RELEASE_RESET +#define __DCMI_CLK_SLEEP_ENABLE __HAL_RCC_DCMI_CLK_SLEEP_ENABLE +#define __DCMI_CLK_SLEEP_DISABLE __HAL_RCC_DCMI_CLK_SLEEP_DISABLE +#define __UART7_CLK_ENABLE __HAL_RCC_UART7_CLK_ENABLE +#define __UART7_CLK_DISABLE __HAL_RCC_UART7_CLK_DISABLE +#define __UART7_RELEASE_RESET __HAL_RCC_UART7_RELEASE_RESET +#define __UART7_FORCE_RESET __HAL_RCC_UART7_FORCE_RESET +#define __UART7_CLK_SLEEP_ENABLE __HAL_RCC_UART7_CLK_SLEEP_ENABLE +#define __UART7_CLK_SLEEP_DISABLE __HAL_RCC_UART7_CLK_SLEEP_DISABLE +#define __UART8_CLK_ENABLE __HAL_RCC_UART8_CLK_ENABLE +#define __UART8_CLK_DISABLE __HAL_RCC_UART8_CLK_DISABLE +#define __UART8_FORCE_RESET __HAL_RCC_UART8_FORCE_RESET +#define __UART8_RELEASE_RESET __HAL_RCC_UART8_RELEASE_RESET +#define __UART8_CLK_SLEEP_ENABLE __HAL_RCC_UART8_CLK_SLEEP_ENABLE +#define __UART8_CLK_SLEEP_DISABLE __HAL_RCC_UART8_CLK_SLEEP_DISABLE +#define __OTGHS_CLK_SLEEP_ENABLE __HAL_RCC_USB_OTG_HS_CLK_SLEEP_ENABLE +#define __OTGHS_CLK_SLEEP_DISABLE __HAL_RCC_USB_OTG_HS_CLK_SLEEP_DISABLE +#define __OTGHS_FORCE_RESET __HAL_RCC_USB_OTG_HS_FORCE_RESET +#define __OTGHS_RELEASE_RESET __HAL_RCC_USB_OTG_HS_RELEASE_RESET +#define __OTGHSULPI_CLK_SLEEP_ENABLE __HAL_RCC_USB_OTG_HS_ULPI_CLK_SLEEP_ENABLE +#define __OTGHSULPI_CLK_SLEEP_DISABLE __HAL_RCC_USB_OTG_HS_ULPI_CLK_SLEEP_DISABLE +#define __HAL_RCC_OTGHS_CLK_SLEEP_ENABLE __HAL_RCC_USB_OTG_HS_CLK_SLEEP_ENABLE +#define __HAL_RCC_OTGHS_CLK_SLEEP_DISABLE __HAL_RCC_USB_OTG_HS_CLK_SLEEP_DISABLE +#define __HAL_RCC_OTGHS_IS_CLK_SLEEP_ENABLED __HAL_RCC_USB_OTG_HS_IS_CLK_SLEEP_ENABLED +#define __HAL_RCC_OTGHS_IS_CLK_SLEEP_DISABLED __HAL_RCC_USB_OTG_HS_IS_CLK_SLEEP_DISABLED +#define __HAL_RCC_OTGHS_FORCE_RESET __HAL_RCC_USB_OTG_HS_FORCE_RESET +#define __HAL_RCC_OTGHS_RELEASE_RESET __HAL_RCC_USB_OTG_HS_RELEASE_RESET +#define __HAL_RCC_OTGHSULPI_CLK_SLEEP_ENABLE __HAL_RCC_USB_OTG_HS_ULPI_CLK_SLEEP_ENABLE +#define __HAL_RCC_OTGHSULPI_CLK_SLEEP_DISABLE __HAL_RCC_USB_OTG_HS_ULPI_CLK_SLEEP_DISABLE +#define __HAL_RCC_OTGHSULPI_IS_CLK_SLEEP_ENABLED __HAL_RCC_USB_OTG_HS_ULPI_IS_CLK_SLEEP_ENABLED +#define __HAL_RCC_OTGHSULPI_IS_CLK_SLEEP_DISABLED __HAL_RCC_USB_OTG_HS_ULPI_IS_CLK_SLEEP_DISABLED +#define __SRAM3_CLK_SLEEP_ENABLE __HAL_RCC_SRAM3_CLK_SLEEP_ENABLE +#define __CAN2_CLK_SLEEP_ENABLE __HAL_RCC_CAN2_CLK_SLEEP_ENABLE +#define __CAN2_CLK_SLEEP_DISABLE __HAL_RCC_CAN2_CLK_SLEEP_DISABLE +#define __DAC_CLK_SLEEP_ENABLE __HAL_RCC_DAC_CLK_SLEEP_ENABLE +#define __DAC_CLK_SLEEP_DISABLE __HAL_RCC_DAC_CLK_SLEEP_DISABLE +#define __ADC2_CLK_SLEEP_ENABLE __HAL_RCC_ADC2_CLK_SLEEP_ENABLE +#define __ADC2_CLK_SLEEP_DISABLE __HAL_RCC_ADC2_CLK_SLEEP_DISABLE +#define __ADC3_CLK_SLEEP_ENABLE __HAL_RCC_ADC3_CLK_SLEEP_ENABLE +#define __ADC3_CLK_SLEEP_DISABLE __HAL_RCC_ADC3_CLK_SLEEP_DISABLE +#define __FSMC_FORCE_RESET __HAL_RCC_FSMC_FORCE_RESET +#define __FSMC_RELEASE_RESET __HAL_RCC_FSMC_RELEASE_RESET +#define __FSMC_CLK_SLEEP_ENABLE __HAL_RCC_FSMC_CLK_SLEEP_ENABLE +#define __FSMC_CLK_SLEEP_DISABLE __HAL_RCC_FSMC_CLK_SLEEP_DISABLE +#define __SDIO_FORCE_RESET __HAL_RCC_SDIO_FORCE_RESET +#define __SDIO_RELEASE_RESET __HAL_RCC_SDIO_RELEASE_RESET +#define __SDIO_CLK_SLEEP_DISABLE __HAL_RCC_SDIO_CLK_SLEEP_DISABLE +#define __SDIO_CLK_SLEEP_ENABLE __HAL_RCC_SDIO_CLK_SLEEP_ENABLE +#define __DMA2D_CLK_ENABLE __HAL_RCC_DMA2D_CLK_ENABLE +#define __DMA2D_CLK_DISABLE __HAL_RCC_DMA2D_CLK_DISABLE +#define __DMA2D_FORCE_RESET __HAL_RCC_DMA2D_FORCE_RESET +#define __DMA2D_RELEASE_RESET __HAL_RCC_DMA2D_RELEASE_RESET +#define __DMA2D_CLK_SLEEP_ENABLE __HAL_RCC_DMA2D_CLK_SLEEP_ENABLE +#define __DMA2D_CLK_SLEEP_DISABLE __HAL_RCC_DMA2D_CLK_SLEEP_DISABLE + +/* alias define maintained for legacy */ +#define __HAL_RCC_OTGFS_FORCE_RESET __HAL_RCC_USB_OTG_FS_FORCE_RESET +#define __HAL_RCC_OTGFS_RELEASE_RESET __HAL_RCC_USB_OTG_FS_RELEASE_RESET + +#define __ADC12_CLK_ENABLE __HAL_RCC_ADC12_CLK_ENABLE +#define __ADC12_CLK_DISABLE __HAL_RCC_ADC12_CLK_DISABLE +#define __ADC34_CLK_ENABLE __HAL_RCC_ADC34_CLK_ENABLE +#define __ADC34_CLK_DISABLE __HAL_RCC_ADC34_CLK_DISABLE +#define __DAC2_CLK_ENABLE __HAL_RCC_DAC2_CLK_ENABLE +#define __DAC2_CLK_DISABLE __HAL_RCC_DAC2_CLK_DISABLE +#define __TIM18_CLK_ENABLE __HAL_RCC_TIM18_CLK_ENABLE +#define __TIM18_CLK_DISABLE __HAL_RCC_TIM18_CLK_DISABLE +#define __TIM19_CLK_ENABLE __HAL_RCC_TIM19_CLK_ENABLE +#define __TIM19_CLK_DISABLE __HAL_RCC_TIM19_CLK_DISABLE +#define __TIM20_CLK_ENABLE __HAL_RCC_TIM20_CLK_ENABLE +#define __TIM20_CLK_DISABLE __HAL_RCC_TIM20_CLK_DISABLE +#define __HRTIM1_CLK_ENABLE __HAL_RCC_HRTIM1_CLK_ENABLE +#define __HRTIM1_CLK_DISABLE __HAL_RCC_HRTIM1_CLK_DISABLE +#define __SDADC1_CLK_ENABLE __HAL_RCC_SDADC1_CLK_ENABLE +#define __SDADC2_CLK_ENABLE __HAL_RCC_SDADC2_CLK_ENABLE +#define __SDADC3_CLK_ENABLE __HAL_RCC_SDADC3_CLK_ENABLE +#define __SDADC1_CLK_DISABLE __HAL_RCC_SDADC1_CLK_DISABLE +#define __SDADC2_CLK_DISABLE __HAL_RCC_SDADC2_CLK_DISABLE +#define __SDADC3_CLK_DISABLE __HAL_RCC_SDADC3_CLK_DISABLE + +#define __ADC12_FORCE_RESET __HAL_RCC_ADC12_FORCE_RESET +#define __ADC12_RELEASE_RESET __HAL_RCC_ADC12_RELEASE_RESET +#define __ADC34_FORCE_RESET __HAL_RCC_ADC34_FORCE_RESET +#define __ADC34_RELEASE_RESET __HAL_RCC_ADC34_RELEASE_RESET +#define __DAC2_FORCE_RESET __HAL_RCC_DAC2_FORCE_RESET +#define __DAC2_RELEASE_RESET __HAL_RCC_DAC2_RELEASE_RESET +#define __TIM18_FORCE_RESET __HAL_RCC_TIM18_FORCE_RESET +#define __TIM18_RELEASE_RESET __HAL_RCC_TIM18_RELEASE_RESET +#define __TIM19_FORCE_RESET __HAL_RCC_TIM19_FORCE_RESET +#define __TIM19_RELEASE_RESET __HAL_RCC_TIM19_RELEASE_RESET +#define __TIM20_FORCE_RESET __HAL_RCC_TIM20_FORCE_RESET +#define __TIM20_RELEASE_RESET __HAL_RCC_TIM20_RELEASE_RESET +#define __HRTIM1_FORCE_RESET __HAL_RCC_HRTIM1_FORCE_RESET +#define __HRTIM1_RELEASE_RESET __HAL_RCC_HRTIM1_RELEASE_RESET +#define __SDADC1_FORCE_RESET __HAL_RCC_SDADC1_FORCE_RESET +#define __SDADC2_FORCE_RESET __HAL_RCC_SDADC2_FORCE_RESET +#define __SDADC3_FORCE_RESET __HAL_RCC_SDADC3_FORCE_RESET +#define __SDADC1_RELEASE_RESET __HAL_RCC_SDADC1_RELEASE_RESET +#define __SDADC2_RELEASE_RESET __HAL_RCC_SDADC2_RELEASE_RESET +#define __SDADC3_RELEASE_RESET __HAL_RCC_SDADC3_RELEASE_RESET + +#define __ADC1_IS_CLK_ENABLED __HAL_RCC_ADC1_IS_CLK_ENABLED +#define __ADC1_IS_CLK_DISABLED __HAL_RCC_ADC1_IS_CLK_DISABLED +#define __ADC12_IS_CLK_ENABLED __HAL_RCC_ADC12_IS_CLK_ENABLED +#define __ADC12_IS_CLK_DISABLED __HAL_RCC_ADC12_IS_CLK_DISABLED +#define __ADC34_IS_CLK_ENABLED __HAL_RCC_ADC34_IS_CLK_ENABLED +#define __ADC34_IS_CLK_DISABLED __HAL_RCC_ADC34_IS_CLK_DISABLED +#define __CEC_IS_CLK_ENABLED __HAL_RCC_CEC_IS_CLK_ENABLED +#define __CEC_IS_CLK_DISABLED __HAL_RCC_CEC_IS_CLK_DISABLED +#define __CRC_IS_CLK_ENABLED __HAL_RCC_CRC_IS_CLK_ENABLED +#define __CRC_IS_CLK_DISABLED __HAL_RCC_CRC_IS_CLK_DISABLED +#define __DAC1_IS_CLK_ENABLED __HAL_RCC_DAC1_IS_CLK_ENABLED +#define __DAC1_IS_CLK_DISABLED __HAL_RCC_DAC1_IS_CLK_DISABLED +#define __DAC2_IS_CLK_ENABLED __HAL_RCC_DAC2_IS_CLK_ENABLED +#define __DAC2_IS_CLK_DISABLED __HAL_RCC_DAC2_IS_CLK_DISABLED +#define __DMA1_IS_CLK_ENABLED __HAL_RCC_DMA1_IS_CLK_ENABLED +#define __DMA1_IS_CLK_DISABLED __HAL_RCC_DMA1_IS_CLK_DISABLED +#define __DMA2_IS_CLK_ENABLED __HAL_RCC_DMA2_IS_CLK_ENABLED +#define __DMA2_IS_CLK_DISABLED __HAL_RCC_DMA2_IS_CLK_DISABLED +#define __FLITF_IS_CLK_ENABLED __HAL_RCC_FLITF_IS_CLK_ENABLED +#define __FLITF_IS_CLK_DISABLED __HAL_RCC_FLITF_IS_CLK_DISABLED +#define __FMC_IS_CLK_ENABLED __HAL_RCC_FMC_IS_CLK_ENABLED +#define __FMC_IS_CLK_DISABLED __HAL_RCC_FMC_IS_CLK_DISABLED +#define __GPIOA_IS_CLK_ENABLED __HAL_RCC_GPIOA_IS_CLK_ENABLED +#define __GPIOA_IS_CLK_DISABLED __HAL_RCC_GPIOA_IS_CLK_DISABLED +#define __GPIOB_IS_CLK_ENABLED __HAL_RCC_GPIOB_IS_CLK_ENABLED +#define __GPIOB_IS_CLK_DISABLED __HAL_RCC_GPIOB_IS_CLK_DISABLED +#define __GPIOC_IS_CLK_ENABLED __HAL_RCC_GPIOC_IS_CLK_ENABLED +#define __GPIOC_IS_CLK_DISABLED __HAL_RCC_GPIOC_IS_CLK_DISABLED +#define __GPIOD_IS_CLK_ENABLED __HAL_RCC_GPIOD_IS_CLK_ENABLED +#define __GPIOD_IS_CLK_DISABLED __HAL_RCC_GPIOD_IS_CLK_DISABLED +#define __GPIOE_IS_CLK_ENABLED __HAL_RCC_GPIOE_IS_CLK_ENABLED +#define __GPIOE_IS_CLK_DISABLED __HAL_RCC_GPIOE_IS_CLK_DISABLED +#define __GPIOF_IS_CLK_ENABLED __HAL_RCC_GPIOF_IS_CLK_ENABLED +#define __GPIOF_IS_CLK_DISABLED __HAL_RCC_GPIOF_IS_CLK_DISABLED +#define __GPIOG_IS_CLK_ENABLED __HAL_RCC_GPIOG_IS_CLK_ENABLED +#define __GPIOG_IS_CLK_DISABLED __HAL_RCC_GPIOG_IS_CLK_DISABLED +#define __GPIOH_IS_CLK_ENABLED __HAL_RCC_GPIOH_IS_CLK_ENABLED +#define __GPIOH_IS_CLK_DISABLED __HAL_RCC_GPIOH_IS_CLK_DISABLED +#define __HRTIM1_IS_CLK_ENABLED __HAL_RCC_HRTIM1_IS_CLK_ENABLED +#define __HRTIM1_IS_CLK_DISABLED __HAL_RCC_HRTIM1_IS_CLK_DISABLED +#define __I2C1_IS_CLK_ENABLED __HAL_RCC_I2C1_IS_CLK_ENABLED +#define __I2C1_IS_CLK_DISABLED __HAL_RCC_I2C1_IS_CLK_DISABLED +#define __I2C2_IS_CLK_ENABLED __HAL_RCC_I2C2_IS_CLK_ENABLED +#define __I2C2_IS_CLK_DISABLED __HAL_RCC_I2C2_IS_CLK_DISABLED +#define __I2C3_IS_CLK_ENABLED __HAL_RCC_I2C3_IS_CLK_ENABLED +#define __I2C3_IS_CLK_DISABLED __HAL_RCC_I2C3_IS_CLK_DISABLED +#define __PWR_IS_CLK_ENABLED __HAL_RCC_PWR_IS_CLK_ENABLED +#define __PWR_IS_CLK_DISABLED __HAL_RCC_PWR_IS_CLK_DISABLED +#define __SYSCFG_IS_CLK_ENABLED __HAL_RCC_SYSCFG_IS_CLK_ENABLED +#define __SYSCFG_IS_CLK_DISABLED __HAL_RCC_SYSCFG_IS_CLK_DISABLED +#define __SPI1_IS_CLK_ENABLED __HAL_RCC_SPI1_IS_CLK_ENABLED +#define __SPI1_IS_CLK_DISABLED __HAL_RCC_SPI1_IS_CLK_DISABLED +#define __SPI2_IS_CLK_ENABLED __HAL_RCC_SPI2_IS_CLK_ENABLED +#define __SPI2_IS_CLK_DISABLED __HAL_RCC_SPI2_IS_CLK_DISABLED +#define __SPI3_IS_CLK_ENABLED __HAL_RCC_SPI3_IS_CLK_ENABLED +#define __SPI3_IS_CLK_DISABLED __HAL_RCC_SPI3_IS_CLK_DISABLED +#define __SPI4_IS_CLK_ENABLED __HAL_RCC_SPI4_IS_CLK_ENABLED +#define __SPI4_IS_CLK_DISABLED __HAL_RCC_SPI4_IS_CLK_DISABLED +#define __SDADC1_IS_CLK_ENABLED __HAL_RCC_SDADC1_IS_CLK_ENABLED +#define __SDADC1_IS_CLK_DISABLED __HAL_RCC_SDADC1_IS_CLK_DISABLED +#define __SDADC2_IS_CLK_ENABLED __HAL_RCC_SDADC2_IS_CLK_ENABLED +#define __SDADC2_IS_CLK_DISABLED __HAL_RCC_SDADC2_IS_CLK_DISABLED +#define __SDADC3_IS_CLK_ENABLED __HAL_RCC_SDADC3_IS_CLK_ENABLED +#define __SDADC3_IS_CLK_DISABLED __HAL_RCC_SDADC3_IS_CLK_DISABLED +#define __SRAM_IS_CLK_ENABLED __HAL_RCC_SRAM_IS_CLK_ENABLED +#define __SRAM_IS_CLK_DISABLED __HAL_RCC_SRAM_IS_CLK_DISABLED +#define __TIM1_IS_CLK_ENABLED __HAL_RCC_TIM1_IS_CLK_ENABLED +#define __TIM1_IS_CLK_DISABLED __HAL_RCC_TIM1_IS_CLK_DISABLED +#define __TIM2_IS_CLK_ENABLED __HAL_RCC_TIM2_IS_CLK_ENABLED +#define __TIM2_IS_CLK_DISABLED __HAL_RCC_TIM2_IS_CLK_DISABLED +#define __TIM3_IS_CLK_ENABLED __HAL_RCC_TIM3_IS_CLK_ENABLED +#define __TIM3_IS_CLK_DISABLED __HAL_RCC_TIM3_IS_CLK_DISABLED +#define __TIM4_IS_CLK_ENABLED __HAL_RCC_TIM4_IS_CLK_ENABLED +#define __TIM4_IS_CLK_DISABLED __HAL_RCC_TIM4_IS_CLK_DISABLED +#define __TIM5_IS_CLK_ENABLED __HAL_RCC_TIM5_IS_CLK_ENABLED +#define __TIM5_IS_CLK_DISABLED __HAL_RCC_TIM5_IS_CLK_DISABLED +#define __TIM6_IS_CLK_ENABLED __HAL_RCC_TIM6_IS_CLK_ENABLED +#define __TIM6_IS_CLK_DISABLED __HAL_RCC_TIM6_IS_CLK_DISABLED +#define __TIM7_IS_CLK_ENABLED __HAL_RCC_TIM7_IS_CLK_ENABLED +#define __TIM7_IS_CLK_DISABLED __HAL_RCC_TIM7_IS_CLK_DISABLED +#define __TIM8_IS_CLK_ENABLED __HAL_RCC_TIM8_IS_CLK_ENABLED +#define __TIM8_IS_CLK_DISABLED __HAL_RCC_TIM8_IS_CLK_DISABLED +#define __TIM12_IS_CLK_ENABLED __HAL_RCC_TIM12_IS_CLK_ENABLED +#define __TIM12_IS_CLK_DISABLED __HAL_RCC_TIM12_IS_CLK_DISABLED +#define __TIM13_IS_CLK_ENABLED __HAL_RCC_TIM13_IS_CLK_ENABLED +#define __TIM13_IS_CLK_DISABLED __HAL_RCC_TIM13_IS_CLK_DISABLED +#define __TIM14_IS_CLK_ENABLED __HAL_RCC_TIM14_IS_CLK_ENABLED +#define __TIM14_IS_CLK_DISABLED __HAL_RCC_TIM14_IS_CLK_DISABLED +#define __TIM15_IS_CLK_ENABLED __HAL_RCC_TIM15_IS_CLK_ENABLED +#define __TIM15_IS_CLK_DISABLED __HAL_RCC_TIM15_IS_CLK_DISABLED +#define __TIM16_IS_CLK_ENABLED __HAL_RCC_TIM16_IS_CLK_ENABLED +#define __TIM16_IS_CLK_DISABLED __HAL_RCC_TIM16_IS_CLK_DISABLED +#define __TIM17_IS_CLK_ENABLED __HAL_RCC_TIM17_IS_CLK_ENABLED +#define __TIM17_IS_CLK_DISABLED __HAL_RCC_TIM17_IS_CLK_DISABLED +#define __TIM18_IS_CLK_ENABLED __HAL_RCC_TIM18_IS_CLK_ENABLED +#define __TIM18_IS_CLK_DISABLED __HAL_RCC_TIM18_IS_CLK_DISABLED +#define __TIM19_IS_CLK_ENABLED __HAL_RCC_TIM19_IS_CLK_ENABLED +#define __TIM19_IS_CLK_DISABLED __HAL_RCC_TIM19_IS_CLK_DISABLED +#define __TIM20_IS_CLK_ENABLED __HAL_RCC_TIM20_IS_CLK_ENABLED +#define __TIM20_IS_CLK_DISABLED __HAL_RCC_TIM20_IS_CLK_DISABLED +#define __TSC_IS_CLK_ENABLED __HAL_RCC_TSC_IS_CLK_ENABLED +#define __TSC_IS_CLK_DISABLED __HAL_RCC_TSC_IS_CLK_DISABLED +#define __UART4_IS_CLK_ENABLED __HAL_RCC_UART4_IS_CLK_ENABLED +#define __UART4_IS_CLK_DISABLED __HAL_RCC_UART4_IS_CLK_DISABLED +#define __UART5_IS_CLK_ENABLED __HAL_RCC_UART5_IS_CLK_ENABLED +#define __UART5_IS_CLK_DISABLED __HAL_RCC_UART5_IS_CLK_DISABLED +#define __USART1_IS_CLK_ENABLED __HAL_RCC_USART1_IS_CLK_ENABLED +#define __USART1_IS_CLK_DISABLED __HAL_RCC_USART1_IS_CLK_DISABLED +#define __USART2_IS_CLK_ENABLED __HAL_RCC_USART2_IS_CLK_ENABLED +#define __USART2_IS_CLK_DISABLED __HAL_RCC_USART2_IS_CLK_DISABLED +#define __USART3_IS_CLK_ENABLED __HAL_RCC_USART3_IS_CLK_ENABLED +#define __USART3_IS_CLK_DISABLED __HAL_RCC_USART3_IS_CLK_DISABLED +#define __USB_IS_CLK_ENABLED __HAL_RCC_USB_IS_CLK_ENABLED +#define __USB_IS_CLK_DISABLED __HAL_RCC_USB_IS_CLK_DISABLED +#define __WWDG_IS_CLK_ENABLED __HAL_RCC_WWDG_IS_CLK_ENABLED +#define __WWDG_IS_CLK_DISABLED __HAL_RCC_WWDG_IS_CLK_DISABLED + +#if defined(STM32L1) +#define __HAL_RCC_CRYP_CLK_DISABLE __HAL_RCC_AES_CLK_DISABLE +#define __HAL_RCC_CRYP_CLK_ENABLE __HAL_RCC_AES_CLK_ENABLE +#define __HAL_RCC_CRYP_CLK_SLEEP_DISABLE __HAL_RCC_AES_CLK_SLEEP_DISABLE +#define __HAL_RCC_CRYP_CLK_SLEEP_ENABLE __HAL_RCC_AES_CLK_SLEEP_ENABLE +#define __HAL_RCC_CRYP_FORCE_RESET __HAL_RCC_AES_FORCE_RESET +#define __HAL_RCC_CRYP_RELEASE_RESET __HAL_RCC_AES_RELEASE_RESET +#endif /* STM32L1 */ + +#if defined(STM32F4) +#define __HAL_RCC_SDMMC1_FORCE_RESET __HAL_RCC_SDIO_FORCE_RESET +#define __HAL_RCC_SDMMC1_RELEASE_RESET __HAL_RCC_SDIO_RELEASE_RESET +#define __HAL_RCC_SDMMC1_CLK_SLEEP_ENABLE __HAL_RCC_SDIO_CLK_SLEEP_ENABLE +#define __HAL_RCC_SDMMC1_CLK_SLEEP_DISABLE __HAL_RCC_SDIO_CLK_SLEEP_DISABLE +#define __HAL_RCC_SDMMC1_CLK_ENABLE __HAL_RCC_SDIO_CLK_ENABLE +#define __HAL_RCC_SDMMC1_CLK_DISABLE __HAL_RCC_SDIO_CLK_DISABLE +#define __HAL_RCC_SDMMC1_IS_CLK_ENABLED __HAL_RCC_SDIO_IS_CLK_ENABLED +#define __HAL_RCC_SDMMC1_IS_CLK_DISABLED __HAL_RCC_SDIO_IS_CLK_DISABLED +#define Sdmmc1ClockSelection SdioClockSelection +#define RCC_PERIPHCLK_SDMMC1 RCC_PERIPHCLK_SDIO +#define RCC_SDMMC1CLKSOURCE_CLK48 RCC_SDIOCLKSOURCE_CK48 +#define RCC_SDMMC1CLKSOURCE_SYSCLK RCC_SDIOCLKSOURCE_SYSCLK +#define __HAL_RCC_SDMMC1_CONFIG __HAL_RCC_SDIO_CONFIG +#define __HAL_RCC_GET_SDMMC1_SOURCE __HAL_RCC_GET_SDIO_SOURCE +#endif + +#if defined(STM32F7) || defined(STM32L4) +#define __HAL_RCC_SDIO_FORCE_RESET __HAL_RCC_SDMMC1_FORCE_RESET +#define __HAL_RCC_SDIO_RELEASE_RESET __HAL_RCC_SDMMC1_RELEASE_RESET +#define __HAL_RCC_SDIO_CLK_SLEEP_ENABLE __HAL_RCC_SDMMC1_CLK_SLEEP_ENABLE +#define __HAL_RCC_SDIO_CLK_SLEEP_DISABLE __HAL_RCC_SDMMC1_CLK_SLEEP_DISABLE +#define __HAL_RCC_SDIO_CLK_ENABLE __HAL_RCC_SDMMC1_CLK_ENABLE +#define __HAL_RCC_SDIO_CLK_DISABLE __HAL_RCC_SDMMC1_CLK_DISABLE +#define __HAL_RCC_SDIO_IS_CLK_ENABLED __HAL_RCC_SDMMC1_IS_CLK_ENABLED +#define __HAL_RCC_SDIO_IS_CLK_DISABLED __HAL_RCC_SDMMC1_IS_CLK_DISABLED +#define SdioClockSelection Sdmmc1ClockSelection +#define RCC_PERIPHCLK_SDIO RCC_PERIPHCLK_SDMMC1 +#define __HAL_RCC_SDIO_CONFIG __HAL_RCC_SDMMC1_CONFIG +#define __HAL_RCC_GET_SDIO_SOURCE __HAL_RCC_GET_SDMMC1_SOURCE +#endif + +#if defined(STM32F7) +#define RCC_SDIOCLKSOURCE_CLK48 RCC_SDMMC1CLKSOURCE_CLK48 +#define RCC_SDIOCLKSOURCE_SYSCLK RCC_SDMMC1CLKSOURCE_SYSCLK +#endif + +#if defined(STM32H7) +#define __HAL_RCC_USB_OTG_HS_CLK_ENABLE() __HAL_RCC_USB1_OTG_HS_CLK_ENABLE() +#define __HAL_RCC_USB_OTG_HS_ULPI_CLK_ENABLE() __HAL_RCC_USB1_OTG_HS_ULPI_CLK_ENABLE() +#define __HAL_RCC_USB_OTG_HS_CLK_DISABLE() __HAL_RCC_USB1_OTG_HS_CLK_DISABLE() +#define __HAL_RCC_USB_OTG_HS_ULPI_CLK_DISABLE() __HAL_RCC_USB1_OTG_HS_ULPI_CLK_DISABLE() +#define __HAL_RCC_USB_OTG_HS_FORCE_RESET() __HAL_RCC_USB1_OTG_HS_FORCE_RESET() +#define __HAL_RCC_USB_OTG_HS_RELEASE_RESET() __HAL_RCC_USB1_OTG_HS_RELEASE_RESET() +#define __HAL_RCC_USB_OTG_HS_CLK_SLEEP_ENABLE() __HAL_RCC_USB1_OTG_HS_CLK_SLEEP_ENABLE() +#define __HAL_RCC_USB_OTG_HS_ULPI_CLK_SLEEP_ENABLE() __HAL_RCC_USB1_OTG_HS_ULPI_CLK_SLEEP_ENABLE() +#define __HAL_RCC_USB_OTG_HS_CLK_SLEEP_DISABLE() __HAL_RCC_USB1_OTG_HS_CLK_SLEEP_DISABLE() +#define __HAL_RCC_USB_OTG_HS_ULPI_CLK_SLEEP_DISABLE() __HAL_RCC_USB1_OTG_HS_ULPI_CLK_SLEEP_DISABLE() + +#define __HAL_RCC_USB_OTG_FS_CLK_ENABLE() __HAL_RCC_USB2_OTG_FS_CLK_ENABLE() +#define __HAL_RCC_USB_OTG_FS_ULPI_CLK_ENABLE() __HAL_RCC_USB2_OTG_FS_ULPI_CLK_ENABLE() +#define __HAL_RCC_USB_OTG_FS_CLK_DISABLE() __HAL_RCC_USB2_OTG_FS_CLK_DISABLE() +#define __HAL_RCC_USB_OTG_FS_ULPI_CLK_DISABLE() __HAL_RCC_USB2_OTG_FS_ULPI_CLK_DISABLE() +#define __HAL_RCC_USB_OTG_FS_FORCE_RESET() __HAL_RCC_USB2_OTG_FS_FORCE_RESET() +#define __HAL_RCC_USB_OTG_FS_RELEASE_RESET() __HAL_RCC_USB2_OTG_FS_RELEASE_RESET() +#define __HAL_RCC_USB_OTG_FS_CLK_SLEEP_ENABLE() __HAL_RCC_USB2_OTG_FS_CLK_SLEEP_ENABLE() +#define __HAL_RCC_USB_OTG_FS_ULPI_CLK_SLEEP_ENABLE() __HAL_RCC_USB2_OTG_FS_ULPI_CLK_SLEEP_ENABLE() +#define __HAL_RCC_USB_OTG_FS_CLK_SLEEP_DISABLE() __HAL_RCC_USB2_OTG_FS_CLK_SLEEP_DISABLE() +#define __HAL_RCC_USB_OTG_FS_ULPI_CLK_SLEEP_DISABLE() __HAL_RCC_USB2_OTG_FS_ULPI_CLK_SLEEP_DISABLE() +#endif + +#define __HAL_RCC_I2SCLK __HAL_RCC_I2S_CONFIG +#define __HAL_RCC_I2SCLK_CONFIG __HAL_RCC_I2S_CONFIG + +#define __RCC_PLLSRC RCC_GET_PLL_OSCSOURCE + +#define IS_RCC_MSIRANGE IS_RCC_MSI_CLOCK_RANGE +#define IS_RCC_RTCCLK_SOURCE IS_RCC_RTCCLKSOURCE +#define IS_RCC_SYSCLK_DIV IS_RCC_HCLK +#define IS_RCC_HCLK_DIV IS_RCC_PCLK +#define IS_RCC_PERIPHCLK IS_RCC_PERIPHCLOCK + +#define RCC_IT_HSI14 RCC_IT_HSI14RDY + +#define RCC_IT_CSSLSE RCC_IT_LSECSS +#define RCC_IT_CSSHSE RCC_IT_CSS + +#define RCC_PLLMUL_3 RCC_PLL_MUL3 +#define RCC_PLLMUL_4 RCC_PLL_MUL4 +#define RCC_PLLMUL_6 RCC_PLL_MUL6 +#define RCC_PLLMUL_8 RCC_PLL_MUL8 +#define RCC_PLLMUL_12 RCC_PLL_MUL12 +#define RCC_PLLMUL_16 RCC_PLL_MUL16 +#define RCC_PLLMUL_24 RCC_PLL_MUL24 +#define RCC_PLLMUL_32 RCC_PLL_MUL32 +#define RCC_PLLMUL_48 RCC_PLL_MUL48 + +#define RCC_PLLDIV_2 RCC_PLL_DIV2 +#define RCC_PLLDIV_3 RCC_PLL_DIV3 +#define RCC_PLLDIV_4 RCC_PLL_DIV4 + +#define IS_RCC_MCOSOURCE IS_RCC_MCO1SOURCE +#define __HAL_RCC_MCO_CONFIG __HAL_RCC_MCO1_CONFIG +#define RCC_MCO_NODIV RCC_MCODIV_1 +#define RCC_MCO_DIV1 RCC_MCODIV_1 +#define RCC_MCO_DIV2 RCC_MCODIV_2 +#define RCC_MCO_DIV4 RCC_MCODIV_4 +#define RCC_MCO_DIV8 RCC_MCODIV_8 +#define RCC_MCO_DIV16 RCC_MCODIV_16 +#define RCC_MCO_DIV32 RCC_MCODIV_32 +#define RCC_MCO_DIV64 RCC_MCODIV_64 +#define RCC_MCO_DIV128 RCC_MCODIV_128 +#define RCC_MCOSOURCE_NONE RCC_MCO1SOURCE_NOCLOCK +#define RCC_MCOSOURCE_LSI RCC_MCO1SOURCE_LSI +#define RCC_MCOSOURCE_LSE RCC_MCO1SOURCE_LSE +#define RCC_MCOSOURCE_SYSCLK RCC_MCO1SOURCE_SYSCLK +#define RCC_MCOSOURCE_HSI RCC_MCO1SOURCE_HSI +#define RCC_MCOSOURCE_HSI14 RCC_MCO1SOURCE_HSI14 +#define RCC_MCOSOURCE_HSI48 RCC_MCO1SOURCE_HSI48 +#define RCC_MCOSOURCE_HSE RCC_MCO1SOURCE_HSE +#define RCC_MCOSOURCE_PLLCLK_DIV1 RCC_MCO1SOURCE_PLLCLK +#define RCC_MCOSOURCE_PLLCLK_NODIV RCC_MCO1SOURCE_PLLCLK +#define RCC_MCOSOURCE_PLLCLK_DIV2 RCC_MCO1SOURCE_PLLCLK_DIV2 + +#if defined(STM32L4) +#define RCC_RTCCLKSOURCE_NO_CLK RCC_RTCCLKSOURCE_NONE +#elif defined(STM32WB) || defined(STM32G0) || defined(STM32G4) +#else +#define RCC_RTCCLKSOURCE_NONE RCC_RTCCLKSOURCE_NO_CLK +#endif + +#define RCC_USBCLK_PLLSAI1 RCC_USBCLKSOURCE_PLLSAI1 +#define RCC_USBCLK_PLL RCC_USBCLKSOURCE_PLL +#define RCC_USBCLK_MSI RCC_USBCLKSOURCE_MSI +#define RCC_USBCLKSOURCE_PLLCLK RCC_USBCLKSOURCE_PLL +#define RCC_USBPLLCLK_DIV1 RCC_USBCLKSOURCE_PLL +#define RCC_USBPLLCLK_DIV1_5 RCC_USBCLKSOURCE_PLL_DIV1_5 +#define RCC_USBPLLCLK_DIV2 RCC_USBCLKSOURCE_PLL_DIV2 +#define RCC_USBPLLCLK_DIV3 RCC_USBCLKSOURCE_PLL_DIV3 + +#define HSION_BitNumber RCC_HSION_BIT_NUMBER +#define HSION_BITNUMBER RCC_HSION_BIT_NUMBER +#define HSEON_BitNumber RCC_HSEON_BIT_NUMBER +#define HSEON_BITNUMBER RCC_HSEON_BIT_NUMBER +#define MSION_BITNUMBER RCC_MSION_BIT_NUMBER +#define CSSON_BitNumber RCC_CSSON_BIT_NUMBER +#define CSSON_BITNUMBER RCC_CSSON_BIT_NUMBER +#define PLLON_BitNumber RCC_PLLON_BIT_NUMBER +#define PLLON_BITNUMBER RCC_PLLON_BIT_NUMBER +#define PLLI2SON_BitNumber RCC_PLLI2SON_BIT_NUMBER +#define I2SSRC_BitNumber RCC_I2SSRC_BIT_NUMBER +#define RTCEN_BitNumber RCC_RTCEN_BIT_NUMBER +#define RTCEN_BITNUMBER RCC_RTCEN_BIT_NUMBER +#define BDRST_BitNumber RCC_BDRST_BIT_NUMBER +#define BDRST_BITNUMBER RCC_BDRST_BIT_NUMBER +#define RTCRST_BITNUMBER RCC_RTCRST_BIT_NUMBER +#define LSION_BitNumber RCC_LSION_BIT_NUMBER +#define LSION_BITNUMBER RCC_LSION_BIT_NUMBER +#define LSEON_BitNumber RCC_LSEON_BIT_NUMBER +#define LSEON_BITNUMBER RCC_LSEON_BIT_NUMBER +#define LSEBYP_BITNUMBER RCC_LSEBYP_BIT_NUMBER +#define PLLSAION_BitNumber RCC_PLLSAION_BIT_NUMBER +#define TIMPRE_BitNumber RCC_TIMPRE_BIT_NUMBER +#define RMVF_BitNumber RCC_RMVF_BIT_NUMBER +#define RMVF_BITNUMBER RCC_RMVF_BIT_NUMBER +#define RCC_CR2_HSI14TRIM_BitNumber RCC_HSI14TRIM_BIT_NUMBER +#define CR_BYTE2_ADDRESS RCC_CR_BYTE2_ADDRESS +#define CIR_BYTE1_ADDRESS RCC_CIR_BYTE1_ADDRESS +#define CIR_BYTE2_ADDRESS RCC_CIR_BYTE2_ADDRESS +#define BDCR_BYTE0_ADDRESS RCC_BDCR_BYTE0_ADDRESS +#define DBP_TIMEOUT_VALUE RCC_DBP_TIMEOUT_VALUE +#define LSE_TIMEOUT_VALUE RCC_LSE_TIMEOUT_VALUE + +#define CR_HSION_BB RCC_CR_HSION_BB +#define CR_CSSON_BB RCC_CR_CSSON_BB +#define CR_PLLON_BB RCC_CR_PLLON_BB +#define CR_PLLI2SON_BB RCC_CR_PLLI2SON_BB +#define CR_MSION_BB RCC_CR_MSION_BB +#define CSR_LSION_BB RCC_CSR_LSION_BB +#define CSR_LSEON_BB RCC_CSR_LSEON_BB +#define CSR_LSEBYP_BB RCC_CSR_LSEBYP_BB +#define CSR_RTCEN_BB RCC_CSR_RTCEN_BB +#define CSR_RTCRST_BB RCC_CSR_RTCRST_BB +#define CFGR_I2SSRC_BB RCC_CFGR_I2SSRC_BB +#define BDCR_RTCEN_BB RCC_BDCR_RTCEN_BB +#define BDCR_BDRST_BB RCC_BDCR_BDRST_BB +#define CR_HSEON_BB RCC_CR_HSEON_BB +#define CSR_RMVF_BB RCC_CSR_RMVF_BB +#define CR_PLLSAION_BB RCC_CR_PLLSAION_BB +#define DCKCFGR_TIMPRE_BB RCC_DCKCFGR_TIMPRE_BB + +#define __HAL_RCC_CRS_ENABLE_FREQ_ERROR_COUNTER __HAL_RCC_CRS_FREQ_ERROR_COUNTER_ENABLE +#define __HAL_RCC_CRS_DISABLE_FREQ_ERROR_COUNTER __HAL_RCC_CRS_FREQ_ERROR_COUNTER_DISABLE +#define __HAL_RCC_CRS_ENABLE_AUTOMATIC_CALIB __HAL_RCC_CRS_AUTOMATIC_CALIB_ENABLE +#define __HAL_RCC_CRS_DISABLE_AUTOMATIC_CALIB __HAL_RCC_CRS_AUTOMATIC_CALIB_DISABLE +#define __HAL_RCC_CRS_CALCULATE_RELOADVALUE __HAL_RCC_CRS_RELOADVALUE_CALCULATE + +#define __HAL_RCC_GET_IT_SOURCE __HAL_RCC_GET_IT + +#define RCC_CRS_SYNCWARM RCC_CRS_SYNCWARN +#define RCC_CRS_TRIMOV RCC_CRS_TRIMOVF + +#define RCC_PERIPHCLK_CK48 RCC_PERIPHCLK_CLK48 +#define RCC_CK48CLKSOURCE_PLLQ RCC_CLK48CLKSOURCE_PLLQ +#define RCC_CK48CLKSOURCE_PLLSAIP RCC_CLK48CLKSOURCE_PLLSAIP +#define RCC_CK48CLKSOURCE_PLLI2SQ RCC_CLK48CLKSOURCE_PLLI2SQ +#define IS_RCC_CK48CLKSOURCE IS_RCC_CLK48CLKSOURCE +#define RCC_SDIOCLKSOURCE_CK48 RCC_SDIOCLKSOURCE_CLK48 + +#define __HAL_RCC_DFSDM_CLK_ENABLE __HAL_RCC_DFSDM1_CLK_ENABLE +#define __HAL_RCC_DFSDM_CLK_DISABLE __HAL_RCC_DFSDM1_CLK_DISABLE +#define __HAL_RCC_DFSDM_IS_CLK_ENABLED __HAL_RCC_DFSDM1_IS_CLK_ENABLED +#define __HAL_RCC_DFSDM_IS_CLK_DISABLED __HAL_RCC_DFSDM1_IS_CLK_DISABLED +#define __HAL_RCC_DFSDM_FORCE_RESET __HAL_RCC_DFSDM1_FORCE_RESET +#define __HAL_RCC_DFSDM_RELEASE_RESET __HAL_RCC_DFSDM1_RELEASE_RESET +#define __HAL_RCC_DFSDM_CLK_SLEEP_ENABLE __HAL_RCC_DFSDM1_CLK_SLEEP_ENABLE +#define __HAL_RCC_DFSDM_CLK_SLEEP_DISABLE __HAL_RCC_DFSDM1_CLK_SLEEP_DISABLE +#define __HAL_RCC_DFSDM_IS_CLK_SLEEP_ENABLED __HAL_RCC_DFSDM1_IS_CLK_SLEEP_ENABLED +#define __HAL_RCC_DFSDM_IS_CLK_SLEEP_DISABLED __HAL_RCC_DFSDM1_IS_CLK_SLEEP_DISABLED +#define DfsdmClockSelection Dfsdm1ClockSelection +#define RCC_PERIPHCLK_DFSDM RCC_PERIPHCLK_DFSDM1 +#define RCC_DFSDMCLKSOURCE_PCLK RCC_DFSDM1CLKSOURCE_PCLK2 +#define RCC_DFSDMCLKSOURCE_SYSCLK RCC_DFSDM1CLKSOURCE_SYSCLK +#define __HAL_RCC_DFSDM_CONFIG __HAL_RCC_DFSDM1_CONFIG +#define __HAL_RCC_GET_DFSDM_SOURCE __HAL_RCC_GET_DFSDM1_SOURCE +#define RCC_DFSDM1CLKSOURCE_PCLK RCC_DFSDM1CLKSOURCE_PCLK2 +#define RCC_SWPMI1CLKSOURCE_PCLK RCC_SWPMI1CLKSOURCE_PCLK1 +#define RCC_LPTIM1CLKSOURCE_PCLK RCC_LPTIM1CLKSOURCE_PCLK1 +#define RCC_LPTIM2CLKSOURCE_PCLK RCC_LPTIM2CLKSOURCE_PCLK1 + +#define RCC_DFSDM1AUDIOCLKSOURCE_I2SAPB1 RCC_DFSDM1AUDIOCLKSOURCE_I2S1 +#define RCC_DFSDM1AUDIOCLKSOURCE_I2SAPB2 RCC_DFSDM1AUDIOCLKSOURCE_I2S2 +#define RCC_DFSDM2AUDIOCLKSOURCE_I2SAPB1 RCC_DFSDM2AUDIOCLKSOURCE_I2S1 +#define RCC_DFSDM2AUDIOCLKSOURCE_I2SAPB2 RCC_DFSDM2AUDIOCLKSOURCE_I2S2 +#define RCC_DFSDM1CLKSOURCE_APB2 RCC_DFSDM1CLKSOURCE_PCLK2 +#define RCC_DFSDM2CLKSOURCE_APB2 RCC_DFSDM2CLKSOURCE_PCLK2 +#define RCC_FMPI2C1CLKSOURCE_APB RCC_FMPI2C1CLKSOURCE_PCLK1 + +/** + * @} + */ + +/** @defgroup HAL_RNG_Aliased_Macros HAL RNG Aliased Macros maintained for legacy purpose + * @{ + */ +#define HAL_RNG_ReadyCallback(__HANDLE__) HAL_RNG_ReadyDataCallback((__HANDLE__), uint32_t random32bit) + +/** + * @} + */ + +/** @defgroup HAL_RTC_Aliased_Macros HAL RTC Aliased Macros maintained for legacy purpose + * @{ + */ +#if defined (STM32G0) || defined (STM32L412xx) || defined (STM32L422xx) || defined (STM32G4) +#else +#define __HAL_RTC_CLEAR_FLAG __HAL_RTC_EXTI_CLEAR_FLAG +#endif +#define __HAL_RTC_DISABLE_IT __HAL_RTC_EXTI_DISABLE_IT +#define __HAL_RTC_ENABLE_IT __HAL_RTC_EXTI_ENABLE_IT + +#if defined (STM32F1) +#define __HAL_RTC_EXTI_CLEAR_FLAG(RTC_EXTI_LINE_ALARM_EVENT) __HAL_RTC_ALARM_EXTI_CLEAR_FLAG() + +#define __HAL_RTC_EXTI_ENABLE_IT(RTC_EXTI_LINE_ALARM_EVENT) __HAL_RTC_ALARM_EXTI_ENABLE_IT() + +#define __HAL_RTC_EXTI_DISABLE_IT(RTC_EXTI_LINE_ALARM_EVENT) __HAL_RTC_ALARM_EXTI_DISABLE_IT() + +#define __HAL_RTC_EXTI_GET_FLAG(RTC_EXTI_LINE_ALARM_EVENT) __HAL_RTC_ALARM_EXTI_GET_FLAG() + +#define __HAL_RTC_EXTI_GENERATE_SWIT(RTC_EXTI_LINE_ALARM_EVENT) __HAL_RTC_ALARM_EXTI_GENERATE_SWIT() +#else +#define __HAL_RTC_EXTI_CLEAR_FLAG(__EXTI_LINE__) (((__EXTI_LINE__) == RTC_EXTI_LINE_ALARM_EVENT) ? __HAL_RTC_ALARM_EXTI_CLEAR_FLAG() : \ + (((__EXTI_LINE__) == RTC_EXTI_LINE_WAKEUPTIMER_EVENT) ? __HAL_RTC_WAKEUPTIMER_EXTI_CLEAR_FLAG() : \ + __HAL_RTC_TAMPER_TIMESTAMP_EXTI_CLEAR_FLAG())) +#define __HAL_RTC_EXTI_ENABLE_IT(__EXTI_LINE__) (((__EXTI_LINE__) == RTC_EXTI_LINE_ALARM_EVENT) ? __HAL_RTC_ALARM_EXTI_ENABLE_IT() : \ + (((__EXTI_LINE__) == RTC_EXTI_LINE_WAKEUPTIMER_EVENT) ? __HAL_RTC_WAKEUPTIMER_EXTI_ENABLE_IT() : \ + __HAL_RTC_TAMPER_TIMESTAMP_EXTI_ENABLE_IT())) +#define __HAL_RTC_EXTI_DISABLE_IT(__EXTI_LINE__) (((__EXTI_LINE__) == RTC_EXTI_LINE_ALARM_EVENT) ? __HAL_RTC_ALARM_EXTI_DISABLE_IT() : \ + (((__EXTI_LINE__) == RTC_EXTI_LINE_WAKEUPTIMER_EVENT) ? __HAL_RTC_WAKEUPTIMER_EXTI_DISABLE_IT() : \ + __HAL_RTC_TAMPER_TIMESTAMP_EXTI_DISABLE_IT())) +#define __HAL_RTC_EXTI_GET_FLAG(__EXTI_LINE__) (((__EXTI_LINE__) == RTC_EXTI_LINE_ALARM_EVENT) ? __HAL_RTC_ALARM_EXTI_GET_FLAG() : \ + (((__EXTI_LINE__) == RTC_EXTI_LINE_WAKEUPTIMER_EVENT) ? __HAL_RTC_WAKEUPTIMER_EXTI_GET_FLAG() : \ + __HAL_RTC_TAMPER_TIMESTAMP_EXTI_GET_FLAG())) +#define __HAL_RTC_EXTI_GENERATE_SWIT(__EXTI_LINE__) (((__EXTI_LINE__) == RTC_EXTI_LINE_ALARM_EVENT) ? __HAL_RTC_ALARM_EXTI_GENERATE_SWIT() : \ + (((__EXTI_LINE__) == RTC_EXTI_LINE_WAKEUPTIMER_EVENT) ? __HAL_RTC_WAKEUPTIMER_EXTI_GENERATE_SWIT() : \ + __HAL_RTC_TAMPER_TIMESTAMP_EXTI_GENERATE_SWIT())) +#endif /* STM32F1 */ + +#define IS_ALARM IS_RTC_ALARM +#define IS_ALARM_MASK IS_RTC_ALARM_MASK +#define IS_TAMPER IS_RTC_TAMPER +#define IS_TAMPER_ERASE_MODE IS_RTC_TAMPER_ERASE_MODE +#define IS_TAMPER_FILTER IS_RTC_TAMPER_FILTER +#define IS_TAMPER_INTERRUPT IS_RTC_TAMPER_INTERRUPT +#define IS_TAMPER_MASKFLAG_STATE IS_RTC_TAMPER_MASKFLAG_STATE +#define IS_TAMPER_PRECHARGE_DURATION IS_RTC_TAMPER_PRECHARGE_DURATION +#define IS_TAMPER_PULLUP_STATE IS_RTC_TAMPER_PULLUP_STATE +#define IS_TAMPER_SAMPLING_FREQ IS_RTC_TAMPER_SAMPLING_FREQ +#define IS_TAMPER_TIMESTAMPONTAMPER_DETECTION IS_RTC_TAMPER_TIMESTAMPONTAMPER_DETECTION +#define IS_TAMPER_TRIGGER IS_RTC_TAMPER_TRIGGER +#define IS_WAKEUP_CLOCK IS_RTC_WAKEUP_CLOCK +#define IS_WAKEUP_COUNTER IS_RTC_WAKEUP_COUNTER + +#define __RTC_WRITEPROTECTION_ENABLE __HAL_RTC_WRITEPROTECTION_ENABLE +#define __RTC_WRITEPROTECTION_DISABLE __HAL_RTC_WRITEPROTECTION_DISABLE + +/** + * @} + */ + +/** @defgroup HAL_SD_Aliased_Macros HAL SD Aliased Macros maintained for legacy purpose + * @{ + */ + +#define SD_OCR_CID_CSD_OVERWRIETE SD_OCR_CID_CSD_OVERWRITE +#define SD_CMD_SD_APP_STAUS SD_CMD_SD_APP_STATUS + +#if defined(STM32F4) || defined(STM32F2) +#define SD_SDMMC_DISABLED SD_SDIO_DISABLED +#define SD_SDMMC_FUNCTION_BUSY SD_SDIO_FUNCTION_BUSY +#define SD_SDMMC_FUNCTION_FAILED SD_SDIO_FUNCTION_FAILED +#define SD_SDMMC_UNKNOWN_FUNCTION SD_SDIO_UNKNOWN_FUNCTION +#define SD_CMD_SDMMC_SEN_OP_COND SD_CMD_SDIO_SEN_OP_COND +#define SD_CMD_SDMMC_RW_DIRECT SD_CMD_SDIO_RW_DIRECT +#define SD_CMD_SDMMC_RW_EXTENDED SD_CMD_SDIO_RW_EXTENDED +#define __HAL_SD_SDMMC_ENABLE __HAL_SD_SDIO_ENABLE +#define __HAL_SD_SDMMC_DISABLE __HAL_SD_SDIO_DISABLE +#define __HAL_SD_SDMMC_DMA_ENABLE __HAL_SD_SDIO_DMA_ENABLE +#define __HAL_SD_SDMMC_DMA_DISABLE __HAL_SD_SDIO_DMA_DISABL +#define __HAL_SD_SDMMC_ENABLE_IT __HAL_SD_SDIO_ENABLE_IT +#define __HAL_SD_SDMMC_DISABLE_IT __HAL_SD_SDIO_DISABLE_IT +#define __HAL_SD_SDMMC_GET_FLAG __HAL_SD_SDIO_GET_FLAG +#define __HAL_SD_SDMMC_CLEAR_FLAG __HAL_SD_SDIO_CLEAR_FLAG +#define __HAL_SD_SDMMC_GET_IT __HAL_SD_SDIO_GET_IT +#define __HAL_SD_SDMMC_CLEAR_IT __HAL_SD_SDIO_CLEAR_IT +#define SDMMC_STATIC_FLAGS SDIO_STATIC_FLAGS +#define SDMMC_CMD0TIMEOUT SDIO_CMD0TIMEOUT +#define SD_SDMMC_SEND_IF_COND SD_SDIO_SEND_IF_COND +/* alias CMSIS */ +#define SDMMC1_IRQn SDIO_IRQn +#define SDMMC1_IRQHandler SDIO_IRQHandler +#endif + +#if defined(STM32F7) || defined(STM32L4) +#define SD_SDIO_DISABLED SD_SDMMC_DISABLED +#define SD_SDIO_FUNCTION_BUSY SD_SDMMC_FUNCTION_BUSY +#define SD_SDIO_FUNCTION_FAILED SD_SDMMC_FUNCTION_FAILED +#define SD_SDIO_UNKNOWN_FUNCTION SD_SDMMC_UNKNOWN_FUNCTION +#define SD_CMD_SDIO_SEN_OP_COND SD_CMD_SDMMC_SEN_OP_COND +#define SD_CMD_SDIO_RW_DIRECT SD_CMD_SDMMC_RW_DIRECT +#define SD_CMD_SDIO_RW_EXTENDED SD_CMD_SDMMC_RW_EXTENDED +#define __HAL_SD_SDIO_ENABLE __HAL_SD_SDMMC_ENABLE +#define __HAL_SD_SDIO_DISABLE __HAL_SD_SDMMC_DISABLE +#define __HAL_SD_SDIO_DMA_ENABLE __HAL_SD_SDMMC_DMA_ENABLE +#define __HAL_SD_SDIO_DMA_DISABL __HAL_SD_SDMMC_DMA_DISABLE +#define __HAL_SD_SDIO_ENABLE_IT __HAL_SD_SDMMC_ENABLE_IT +#define __HAL_SD_SDIO_DISABLE_IT __HAL_SD_SDMMC_DISABLE_IT +#define __HAL_SD_SDIO_GET_FLAG __HAL_SD_SDMMC_GET_FLAG +#define __HAL_SD_SDIO_CLEAR_FLAG __HAL_SD_SDMMC_CLEAR_FLAG +#define __HAL_SD_SDIO_GET_IT __HAL_SD_SDMMC_GET_IT +#define __HAL_SD_SDIO_CLEAR_IT __HAL_SD_SDMMC_CLEAR_IT +#define SDIO_STATIC_FLAGS SDMMC_STATIC_FLAGS +#define SDIO_CMD0TIMEOUT SDMMC_CMD0TIMEOUT +#define SD_SDIO_SEND_IF_COND SD_SDMMC_SEND_IF_COND +/* alias CMSIS for compatibilities */ +#define SDIO_IRQn SDMMC1_IRQn +#define SDIO_IRQHandler SDMMC1_IRQHandler +#endif + +#if defined(STM32F7) || defined(STM32F4) || defined(STM32F2) || defined(STM32L4) || defined(STM32H7) +#define HAL_SD_CardCIDTypedef HAL_SD_CardCIDTypeDef +#define HAL_SD_CardCSDTypedef HAL_SD_CardCSDTypeDef +#define HAL_SD_CardStatusTypedef HAL_SD_CardStatusTypeDef +#define HAL_SD_CardStateTypedef HAL_SD_CardStateTypeDef +#endif + +#if defined(STM32H7) +#define HAL_MMCEx_Read_DMADoubleBuffer0CpltCallback HAL_MMCEx_Read_DMADoubleBuf0CpltCallback +#define HAL_MMCEx_Read_DMADoubleBuffer1CpltCallback HAL_MMCEx_Read_DMADoubleBuf1CpltCallback +#define HAL_MMCEx_Write_DMADoubleBuffer0CpltCallback HAL_MMCEx_Write_DMADoubleBuf0CpltCallback +#define HAL_MMCEx_Write_DMADoubleBuffer1CpltCallback HAL_MMCEx_Write_DMADoubleBuf1CpltCallback +#define HAL_SDEx_Read_DMADoubleBuffer0CpltCallback HAL_SDEx_Read_DMADoubleBuf0CpltCallback +#define HAL_SDEx_Read_DMADoubleBuffer1CpltCallback HAL_SDEx_Read_DMADoubleBuf1CpltCallback +#define HAL_SDEx_Write_DMADoubleBuffer0CpltCallback HAL_SDEx_Write_DMADoubleBuf0CpltCallback +#define HAL_SDEx_Write_DMADoubleBuffer1CpltCallback HAL_SDEx_Write_DMADoubleBuf1CpltCallback +#define HAL_SD_DriveTransciver_1_8V_Callback HAL_SD_DriveTransceiver_1_8V_Callback +#endif +/** + * @} + */ + +/** @defgroup HAL_SMARTCARD_Aliased_Macros HAL SMARTCARD Aliased Macros maintained for legacy purpose + * @{ + */ + +#define __SMARTCARD_ENABLE_IT __HAL_SMARTCARD_ENABLE_IT +#define __SMARTCARD_DISABLE_IT __HAL_SMARTCARD_DISABLE_IT +#define __SMARTCARD_ENABLE __HAL_SMARTCARD_ENABLE +#define __SMARTCARD_DISABLE __HAL_SMARTCARD_DISABLE +#define __SMARTCARD_DMA_REQUEST_ENABLE __HAL_SMARTCARD_DMA_REQUEST_ENABLE +#define __SMARTCARD_DMA_REQUEST_DISABLE __HAL_SMARTCARD_DMA_REQUEST_DISABLE + +#define __HAL_SMARTCARD_GETCLOCKSOURCE SMARTCARD_GETCLOCKSOURCE +#define __SMARTCARD_GETCLOCKSOURCE SMARTCARD_GETCLOCKSOURCE + +#define IS_SMARTCARD_ONEBIT_SAMPLING IS_SMARTCARD_ONE_BIT_SAMPLE + +/** + * @} + */ + +/** @defgroup HAL_SMBUS_Aliased_Macros HAL SMBUS Aliased Macros maintained for legacy purpose + * @{ + */ +#define __HAL_SMBUS_RESET_CR1 SMBUS_RESET_CR1 +#define __HAL_SMBUS_RESET_CR2 SMBUS_RESET_CR2 +#define __HAL_SMBUS_GENERATE_START SMBUS_GENERATE_START +#define __HAL_SMBUS_GET_ADDR_MATCH SMBUS_GET_ADDR_MATCH +#define __HAL_SMBUS_GET_DIR SMBUS_GET_DIR +#define __HAL_SMBUS_GET_STOP_MODE SMBUS_GET_STOP_MODE +#define __HAL_SMBUS_GET_PEC_MODE SMBUS_GET_PEC_MODE +#define __HAL_SMBUS_GET_ALERT_ENABLED SMBUS_GET_ALERT_ENABLED +/** + * @} + */ + +/** @defgroup HAL_SPI_Aliased_Macros HAL SPI Aliased Macros maintained for legacy purpose + * @{ + */ + +#define __HAL_SPI_1LINE_TX SPI_1LINE_TX +#define __HAL_SPI_1LINE_RX SPI_1LINE_RX +#define __HAL_SPI_RESET_CRC SPI_RESET_CRC + +/** + * @} + */ + +/** @defgroup HAL_UART_Aliased_Macros HAL UART Aliased Macros maintained for legacy purpose + * @{ + */ + +#define __HAL_UART_GETCLOCKSOURCE UART_GETCLOCKSOURCE +#define __HAL_UART_MASK_COMPUTATION UART_MASK_COMPUTATION +#define __UART_GETCLOCKSOURCE UART_GETCLOCKSOURCE +#define __UART_MASK_COMPUTATION UART_MASK_COMPUTATION + +#define IS_UART_WAKEUPMETHODE IS_UART_WAKEUPMETHOD + +#define IS_UART_ONEBIT_SAMPLE IS_UART_ONE_BIT_SAMPLE +#define IS_UART_ONEBIT_SAMPLING IS_UART_ONE_BIT_SAMPLE + +/** + * @} + */ + + +/** @defgroup HAL_USART_Aliased_Macros HAL USART Aliased Macros maintained for legacy purpose + * @{ + */ + +#define __USART_ENABLE_IT __HAL_USART_ENABLE_IT +#define __USART_DISABLE_IT __HAL_USART_DISABLE_IT +#define __USART_ENABLE __HAL_USART_ENABLE +#define __USART_DISABLE __HAL_USART_DISABLE + +#define __HAL_USART_GETCLOCKSOURCE USART_GETCLOCKSOURCE +#define __USART_GETCLOCKSOURCE USART_GETCLOCKSOURCE + +/** + * @} + */ + +/** @defgroup HAL_USB_Aliased_Macros HAL USB Aliased Macros maintained for legacy purpose + * @{ + */ +#define USB_EXTI_LINE_WAKEUP USB_WAKEUP_EXTI_LINE + +#define USB_FS_EXTI_TRIGGER_RISING_EDGE USB_OTG_FS_WAKEUP_EXTI_RISING_EDGE +#define USB_FS_EXTI_TRIGGER_FALLING_EDGE USB_OTG_FS_WAKEUP_EXTI_FALLING_EDGE +#define USB_FS_EXTI_TRIGGER_BOTH_EDGE USB_OTG_FS_WAKEUP_EXTI_RISING_FALLING_EDGE +#define USB_FS_EXTI_LINE_WAKEUP USB_OTG_FS_WAKEUP_EXTI_LINE + +#define USB_HS_EXTI_TRIGGER_RISING_EDGE USB_OTG_HS_WAKEUP_EXTI_RISING_EDGE +#define USB_HS_EXTI_TRIGGER_FALLING_EDGE USB_OTG_HS_WAKEUP_EXTI_FALLING_EDGE +#define USB_HS_EXTI_TRIGGER_BOTH_EDGE USB_OTG_HS_WAKEUP_EXTI_RISING_FALLING_EDGE +#define USB_HS_EXTI_LINE_WAKEUP USB_OTG_HS_WAKEUP_EXTI_LINE + +#define __HAL_USB_EXTI_ENABLE_IT __HAL_USB_WAKEUP_EXTI_ENABLE_IT +#define __HAL_USB_EXTI_DISABLE_IT __HAL_USB_WAKEUP_EXTI_DISABLE_IT +#define __HAL_USB_EXTI_GET_FLAG __HAL_USB_WAKEUP_EXTI_GET_FLAG +#define __HAL_USB_EXTI_CLEAR_FLAG __HAL_USB_WAKEUP_EXTI_CLEAR_FLAG +#define __HAL_USB_EXTI_SET_RISING_EDGE_TRIGGER __HAL_USB_WAKEUP_EXTI_ENABLE_RISING_EDGE +#define __HAL_USB_EXTI_SET_FALLING_EDGE_TRIGGER __HAL_USB_WAKEUP_EXTI_ENABLE_FALLING_EDGE +#define __HAL_USB_EXTI_SET_FALLINGRISING_TRIGGER __HAL_USB_WAKEUP_EXTI_ENABLE_RISING_FALLING_EDGE + +#define __HAL_USB_FS_EXTI_ENABLE_IT __HAL_USB_OTG_FS_WAKEUP_EXTI_ENABLE_IT +#define __HAL_USB_FS_EXTI_DISABLE_IT __HAL_USB_OTG_FS_WAKEUP_EXTI_DISABLE_IT +#define __HAL_USB_FS_EXTI_GET_FLAG __HAL_USB_OTG_FS_WAKEUP_EXTI_GET_FLAG +#define __HAL_USB_FS_EXTI_CLEAR_FLAG __HAL_USB_OTG_FS_WAKEUP_EXTI_CLEAR_FLAG +#define __HAL_USB_FS_EXTI_SET_RISING_EGDE_TRIGGER __HAL_USB_OTG_FS_WAKEUP_EXTI_ENABLE_RISING_EDGE +#define __HAL_USB_FS_EXTI_SET_FALLING_EGDE_TRIGGER __HAL_USB_OTG_FS_WAKEUP_EXTI_ENABLE_FALLING_EDGE +#define __HAL_USB_FS_EXTI_SET_FALLINGRISING_TRIGGER __HAL_USB_OTG_FS_WAKEUP_EXTI_ENABLE_RISING_FALLING_EDGE +#define __HAL_USB_FS_EXTI_GENERATE_SWIT __HAL_USB_OTG_FS_WAKEUP_EXTI_GENERATE_SWIT + +#define __HAL_USB_HS_EXTI_ENABLE_IT __HAL_USB_OTG_HS_WAKEUP_EXTI_ENABLE_IT +#define __HAL_USB_HS_EXTI_DISABLE_IT __HAL_USB_OTG_HS_WAKEUP_EXTI_DISABLE_IT +#define __HAL_USB_HS_EXTI_GET_FLAG __HAL_USB_OTG_HS_WAKEUP_EXTI_GET_FLAG +#define __HAL_USB_HS_EXTI_CLEAR_FLAG __HAL_USB_OTG_HS_WAKEUP_EXTI_CLEAR_FLAG +#define __HAL_USB_HS_EXTI_SET_RISING_EGDE_TRIGGER __HAL_USB_OTG_HS_WAKEUP_EXTI_ENABLE_RISING_EDGE +#define __HAL_USB_HS_EXTI_SET_FALLING_EGDE_TRIGGER __HAL_USB_OTG_HS_WAKEUP_EXTI_ENABLE_FALLING_EDGE +#define __HAL_USB_HS_EXTI_SET_FALLINGRISING_TRIGGER __HAL_USB_OTG_HS_WAKEUP_EXTI_ENABLE_RISING_FALLING_EDGE +#define __HAL_USB_HS_EXTI_GENERATE_SWIT __HAL_USB_OTG_HS_WAKEUP_EXTI_GENERATE_SWIT + +#define HAL_PCD_ActiveRemoteWakeup HAL_PCD_ActivateRemoteWakeup +#define HAL_PCD_DeActiveRemoteWakeup HAL_PCD_DeActivateRemoteWakeup + +#define HAL_PCD_SetTxFiFo HAL_PCDEx_SetTxFiFo +#define HAL_PCD_SetRxFiFo HAL_PCDEx_SetRxFiFo +/** + * @} + */ + +/** @defgroup HAL_TIM_Aliased_Macros HAL TIM Aliased Macros maintained for legacy purpose + * @{ + */ +#define __HAL_TIM_SetICPrescalerValue TIM_SET_ICPRESCALERVALUE +#define __HAL_TIM_ResetICPrescalerValue TIM_RESET_ICPRESCALERVALUE + +#define TIM_GET_ITSTATUS __HAL_TIM_GET_IT_SOURCE +#define TIM_GET_CLEAR_IT __HAL_TIM_CLEAR_IT + +#define __HAL_TIM_GET_ITSTATUS __HAL_TIM_GET_IT_SOURCE + +#define __HAL_TIM_DIRECTION_STATUS __HAL_TIM_IS_TIM_COUNTING_DOWN +#define __HAL_TIM_PRESCALER __HAL_TIM_SET_PRESCALER +#define __HAL_TIM_SetCounter __HAL_TIM_SET_COUNTER +#define __HAL_TIM_GetCounter __HAL_TIM_GET_COUNTER +#define __HAL_TIM_SetAutoreload __HAL_TIM_SET_AUTORELOAD +#define __HAL_TIM_GetAutoreload __HAL_TIM_GET_AUTORELOAD +#define __HAL_TIM_SetClockDivision __HAL_TIM_SET_CLOCKDIVISION +#define __HAL_TIM_GetClockDivision __HAL_TIM_GET_CLOCKDIVISION +#define __HAL_TIM_SetICPrescaler __HAL_TIM_SET_ICPRESCALER +#define __HAL_TIM_GetICPrescaler __HAL_TIM_GET_ICPRESCALER +#define __HAL_TIM_SetCompare __HAL_TIM_SET_COMPARE +#define __HAL_TIM_GetCompare __HAL_TIM_GET_COMPARE + +#define TIM_BREAKINPUTSOURCE_DFSDM TIM_BREAKINPUTSOURCE_DFSDM1 +/** + * @} + */ + +/** @defgroup HAL_ETH_Aliased_Macros HAL ETH Aliased Macros maintained for legacy purpose + * @{ + */ + +#define __HAL_ETH_EXTI_ENABLE_IT __HAL_ETH_WAKEUP_EXTI_ENABLE_IT +#define __HAL_ETH_EXTI_DISABLE_IT __HAL_ETH_WAKEUP_EXTI_DISABLE_IT +#define __HAL_ETH_EXTI_GET_FLAG __HAL_ETH_WAKEUP_EXTI_GET_FLAG +#define __HAL_ETH_EXTI_CLEAR_FLAG __HAL_ETH_WAKEUP_EXTI_CLEAR_FLAG +#define __HAL_ETH_EXTI_SET_RISING_EGDE_TRIGGER __HAL_ETH_WAKEUP_EXTI_ENABLE_RISING_EDGE_TRIGGER +#define __HAL_ETH_EXTI_SET_FALLING_EGDE_TRIGGER __HAL_ETH_WAKEUP_EXTI_ENABLE_FALLING_EDGE_TRIGGER +#define __HAL_ETH_EXTI_SET_FALLINGRISING_TRIGGER __HAL_ETH_WAKEUP_EXTI_ENABLE_FALLINGRISING_TRIGGER + +#define ETH_PROMISCIOUSMODE_ENABLE ETH_PROMISCUOUS_MODE_ENABLE +#define ETH_PROMISCIOUSMODE_DISABLE ETH_PROMISCUOUS_MODE_DISABLE +#define IS_ETH_PROMISCIOUS_MODE IS_ETH_PROMISCUOUS_MODE +/** + * @} + */ + +/** @defgroup HAL_LTDC_Aliased_Macros HAL LTDC Aliased Macros maintained for legacy purpose + * @{ + */ +#define __HAL_LTDC_LAYER LTDC_LAYER +#define __HAL_LTDC_RELOAD_CONFIG __HAL_LTDC_RELOAD_IMMEDIATE_CONFIG +/** + * @} + */ + +/** @defgroup HAL_SAI_Aliased_Macros HAL SAI Aliased Macros maintained for legacy purpose + * @{ + */ +#define SAI_OUTPUTDRIVE_DISABLED SAI_OUTPUTDRIVE_DISABLE +#define SAI_OUTPUTDRIVE_ENABLED SAI_OUTPUTDRIVE_ENABLE +#define SAI_MASTERDIVIDER_ENABLED SAI_MASTERDIVIDER_ENABLE +#define SAI_MASTERDIVIDER_DISABLED SAI_MASTERDIVIDER_DISABLE +#define SAI_STREOMODE SAI_STEREOMODE +#define SAI_FIFOStatus_Empty SAI_FIFOSTATUS_EMPTY +#define SAI_FIFOStatus_Less1QuarterFull SAI_FIFOSTATUS_LESS1QUARTERFULL +#define SAI_FIFOStatus_1QuarterFull SAI_FIFOSTATUS_1QUARTERFULL +#define SAI_FIFOStatus_HalfFull SAI_FIFOSTATUS_HALFFULL +#define SAI_FIFOStatus_3QuartersFull SAI_FIFOSTATUS_3QUARTERFULL +#define SAI_FIFOStatus_Full SAI_FIFOSTATUS_FULL +#define IS_SAI_BLOCK_MONO_STREO_MODE IS_SAI_BLOCK_MONO_STEREO_MODE +#define SAI_SYNCHRONOUS_EXT SAI_SYNCHRONOUS_EXT_SAI1 +#define SAI_SYNCEXT_IN_ENABLE SAI_SYNCEXT_OUTBLOCKA_ENABLE +/** + * @} + */ + +/** @defgroup HAL_SPDIFRX_Aliased_Macros HAL SPDIFRX Aliased Macros maintained for legacy purpose + * @{ + */ +#if defined(STM32H7) +#define HAL_SPDIFRX_ReceiveControlFlow HAL_SPDIFRX_ReceiveCtrlFlow +#define HAL_SPDIFRX_ReceiveControlFlow_IT HAL_SPDIFRX_ReceiveCtrlFlow_IT +#define HAL_SPDIFRX_ReceiveControlFlow_DMA HAL_SPDIFRX_ReceiveCtrlFlow_DMA +#endif +/** + * @} + */ + +/** @defgroup HAL_HRTIM_Aliased_Functions HAL HRTIM Aliased Functions maintained for legacy purpose + * @{ + */ +#if defined (STM32H7) || defined (STM32G4) || defined (STM32F3) +#define HAL_HRTIM_WaveformCounterStart_IT HAL_HRTIM_WaveformCountStart_IT +#define HAL_HRTIM_WaveformCounterStart_DMA HAL_HRTIM_WaveformCountStart_DMA +#define HAL_HRTIM_WaveformCounterStart HAL_HRTIM_WaveformCountStart +#define HAL_HRTIM_WaveformCounterStop_IT HAL_HRTIM_WaveformCountStop_IT +#define HAL_HRTIM_WaveformCounterStop_DMA HAL_HRTIM_WaveformCountStop_DMA +#define HAL_HRTIM_WaveformCounterStop HAL_HRTIM_WaveformCountStop +#endif +/** + * @} + */ + +/** @defgroup HAL_QSPI_Aliased_Macros HAL QSPI Aliased Macros maintained for legacy purpose + * @{ + */ +#if defined (STM32L4) +#define HAL_QPSI_TIMEOUT_DEFAULT_VALUE HAL_QSPI_TIMEOUT_DEFAULT_VALUE +#endif +/** + * @} + */ + +/** @defgroup HAL_PPP_Aliased_Macros HAL PPP Aliased Macros maintained for legacy purpose + * @{ + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32_HAL_LEGACY */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ + diff --git a/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal.h b/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal.h new file mode 100644 index 0000000..a100055 --- /dev/null +++ b/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal.h @@ -0,0 +1,585 @@ +/** + ****************************************************************************** + * @file stm32f0xx_hal.h + * @author MCD Application Team + * @brief This file contains all the functions prototypes for the HAL + * module driver. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2016 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F0xx_HAL_H +#define __STM32F0xx_HAL_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f0xx_hal_conf.h" + +/** @addtogroup STM32F0xx_HAL_Driver + * @{ + */ + +/** @addtogroup HAL + * @{ + */ + +/* Private macros ------------------------------------------------------------*/ +/** @addtogroup HAL_Private_Macros + * @{ + */ +#if defined(STM32F091xC) || defined(STM32F098xx) || defined(STM32F042x6) || defined(STM32F048xx) || \ + defined(STM32F030x6) || defined(STM32F031x6) || defined(STM32F038xx) || defined(STM32F070x6) || \ + defined(STM32F070xB) || defined(STM32F030x6) +#define IS_SYSCFG_FASTMODEPLUS(__PIN__) ((((__PIN__) & SYSCFG_FASTMODEPLUS_PA9) == SYSCFG_FASTMODEPLUS_PA9) || \ + (((__PIN__) & SYSCFG_FASTMODEPLUS_PA10) == SYSCFG_FASTMODEPLUS_PA10) || \ + (((__PIN__) & SYSCFG_FASTMODEPLUS_PB6) == SYSCFG_FASTMODEPLUS_PB6) || \ + (((__PIN__) & SYSCFG_FASTMODEPLUS_PB7) == SYSCFG_FASTMODEPLUS_PB7) || \ + (((__PIN__) & SYSCFG_FASTMODEPLUS_PB8) == SYSCFG_FASTMODEPLUS_PB8) || \ + (((__PIN__) & SYSCFG_FASTMODEPLUS_PB9) == SYSCFG_FASTMODEPLUS_PB9)) +#else +#define IS_SYSCFG_FASTMODEPLUS(__PIN__) ((((__PIN__) & SYSCFG_FASTMODEPLUS_PB6) == SYSCFG_FASTMODEPLUS_PB6) || \ + (((__PIN__) & SYSCFG_FASTMODEPLUS_PB7) == SYSCFG_FASTMODEPLUS_PB7) || \ + (((__PIN__) & SYSCFG_FASTMODEPLUS_PB8) == SYSCFG_FASTMODEPLUS_PB8) || \ + (((__PIN__) & SYSCFG_FASTMODEPLUS_PB9) == SYSCFG_FASTMODEPLUS_PB9)) +#endif +#if defined(SYSCFG_CFGR1_PA11_PA12_RMP) +#define IS_HAL_REMAP_PIN(RMP) ((RMP) == HAL_REMAP_PA11_PA12) +#endif /* SYSCFG_CFGR1_PA11_PA12_RMP */ +#if defined(STM32F091xC) || defined(STM32F098xx) +#define IS_HAL_SYSCFG_IRDA_ENV_SEL(SEL) (((SEL) == HAL_SYSCFG_IRDA_ENV_SEL_TIM16) || \ + ((SEL) == HAL_SYSCFG_IRDA_ENV_SEL_USART1) || \ + ((SEL) == HAL_SYSCFG_IRDA_ENV_SEL_USART4)) +#endif /* STM32F091xC || STM32F098xx */ +/** + * @} + */ + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ +/** @defgroup HAL_Exported_Constants HAL Exported Constants + * @{ + */ + +/** @defgroup HAL_TICK_FREQ Tick Frequency + * @{ + */ +typedef enum +{ + HAL_TICK_FREQ_10HZ = 100U, + HAL_TICK_FREQ_100HZ = 10U, + HAL_TICK_FREQ_1KHZ = 1U, + HAL_TICK_FREQ_DEFAULT = HAL_TICK_FREQ_1KHZ +} HAL_TickFreqTypeDef; + +/** + * @} + */ + +#if defined(SYSCFG_CFGR1_PA11_PA12_RMP) +/** @defgroup HAL_Pin_remapping HAL Pin remapping + * @{ + */ +#define HAL_REMAP_PA11_PA12 (SYSCFG_CFGR1_PA11_PA12_RMP) /*!< PA11 and PA12 remapping bit for small packages (28 and 20 pins). + 0: No remap (pin pair PA9/10 mapped on the pins) + 1: Remap (pin pair PA11/12 mapped instead of PA9/10) */ + +/** + * @} + */ +#endif /* SYSCFG_CFGR1_PA11_PA12_RMP */ + +#if defined(STM32F091xC) || defined(STM32F098xx) +/** @defgroup HAL_IRDA_ENV_SEL HAL IRDA Enveloppe Selection + * @note Applicable on STM32F09x + * @{ + */ +#define HAL_SYSCFG_IRDA_ENV_SEL_TIM16 (SYSCFG_CFGR1_IRDA_ENV_SEL_0 & SYSCFG_CFGR1_IRDA_ENV_SEL_1) /* 00: Timer16 is selected as IRDA Modulation enveloppe source */ +#define HAL_SYSCFG_IRDA_ENV_SEL_USART1 (SYSCFG_CFGR1_IRDA_ENV_SEL_0) /* 01: USART1 is selected as IRDA Modulation enveloppe source */ +#define HAL_SYSCFG_IRDA_ENV_SEL_USART4 (SYSCFG_CFGR1_IRDA_ENV_SEL_1) /* 10: USART4 is selected as IRDA Modulation enveloppe source */ + +/** + * @} + */ +#endif /* STM32F091xC || STM32F098xx */ + + +/** @defgroup SYSCFG_FastModePlus_GPIO Fast-mode Plus on GPIO + * @{ + */ + +/** @brief Fast-mode Plus driving capability on a specific GPIO + */ +#if defined(STM32F091xC) || defined(STM32F098xx) || defined(STM32F042x6) || defined(STM32F048xx) || \ + defined(STM32F030x6) || defined(STM32F031x6) || defined(STM32F038xx) || defined(STM32F070x6) || \ + defined(STM32F070xB) || defined(STM32F030x6) +#define SYSCFG_FASTMODEPLUS_PA9 SYSCFG_CFGR1_I2C_FMP_PA9 /*!< Enable Fast-mode Plus on PA9 */ +#define SYSCFG_FASTMODEPLUS_PA10 SYSCFG_CFGR1_I2C_FMP_PA10 /*!< Enable Fast-mode Plus on PA10 */ +#endif +#define SYSCFG_FASTMODEPLUS_PB6 SYSCFG_CFGR1_I2C_FMP_PB6 /*!< Enable Fast-mode Plus on PB6 */ +#define SYSCFG_FASTMODEPLUS_PB7 SYSCFG_CFGR1_I2C_FMP_PB7 /*!< Enable Fast-mode Plus on PB7 */ +#define SYSCFG_FASTMODEPLUS_PB8 SYSCFG_CFGR1_I2C_FMP_PB8 /*!< Enable Fast-mode Plus on PB8 */ +#define SYSCFG_FASTMODEPLUS_PB9 SYSCFG_CFGR1_I2C_FMP_PB9 /*!< Enable Fast-mode Plus on PB9 */ + +/** + * @} + */ + + +#if defined(STM32F091xC) || defined (STM32F098xx) +/** @defgroup HAL_ISR_Wrapper HAL ISR Wrapper + * @brief ISR Wrapper + * @note applicable on STM32F09x + * @{ + */ +#define HAL_SYSCFG_ITLINE0 ( 0x00000000U) /*!< Internal define for macro handling */ +#define HAL_SYSCFG_ITLINE1 ( 0x00000001U) /*!< Internal define for macro handling */ +#define HAL_SYSCFG_ITLINE2 ( 0x00000002U) /*!< Internal define for macro handling */ +#define HAL_SYSCFG_ITLINE3 ( 0x00000003U) /*!< Internal define for macro handling */ +#define HAL_SYSCFG_ITLINE4 ( 0x00000004U) /*!< Internal define for macro handling */ +#define HAL_SYSCFG_ITLINE5 ( 0x00000005U) /*!< Internal define for macro handling */ +#define HAL_SYSCFG_ITLINE6 ( 0x00000006U) /*!< Internal define for macro handling */ +#define HAL_SYSCFG_ITLINE7 ( 0x00000007U) /*!< Internal define for macro handling */ +#define HAL_SYSCFG_ITLINE8 ( 0x00000008U) /*!< Internal define for macro handling */ +#define HAL_SYSCFG_ITLINE9 ( 0x00000009U) /*!< Internal define for macro handling */ +#define HAL_SYSCFG_ITLINE10 ( 0x0000000AU) /*!< Internal define for macro handling */ +#define HAL_SYSCFG_ITLINE11 ( 0x0000000BU) /*!< Internal define for macro handling */ +#define HAL_SYSCFG_ITLINE12 ( 0x0000000CU) /*!< Internal define for macro handling */ +#define HAL_SYSCFG_ITLINE13 ( 0x0000000DU) /*!< Internal define for macro handling */ +#define HAL_SYSCFG_ITLINE14 ( 0x0000000EU) /*!< Internal define for macro handling */ +#define HAL_SYSCFG_ITLINE15 ( 0x0000000FU) /*!< Internal define for macro handling */ +#define HAL_SYSCFG_ITLINE16 ( 0x00000010U) /*!< Internal define for macro handling */ +#define HAL_SYSCFG_ITLINE17 ( 0x00000011U) /*!< Internal define for macro handling */ +#define HAL_SYSCFG_ITLINE18 ( 0x00000012U) /*!< Internal define for macro handling */ +#define HAL_SYSCFG_ITLINE19 ( 0x00000013U) /*!< Internal define for macro handling */ +#define HAL_SYSCFG_ITLINE20 ( 0x00000014U) /*!< Internal define for macro handling */ +#define HAL_SYSCFG_ITLINE21 ( 0x00000015U) /*!< Internal define for macro handling */ +#define HAL_SYSCFG_ITLINE22 ( 0x00000016U) /*!< Internal define for macro handling */ +#define HAL_SYSCFG_ITLINE23 ( 0x00000017U) /*!< Internal define for macro handling */ +#define HAL_SYSCFG_ITLINE24 ( 0x00000018U) /*!< Internal define for macro handling */ +#define HAL_SYSCFG_ITLINE25 ( 0x00000019U) /*!< Internal define for macro handling */ +#define HAL_SYSCFG_ITLINE26 ( 0x0000001AU) /*!< Internal define for macro handling */ +#define HAL_SYSCFG_ITLINE27 ( 0x0000001BU) /*!< Internal define for macro handling */ +#define HAL_SYSCFG_ITLINE28 ( 0x0000001CU) /*!< Internal define for macro handling */ +#define HAL_SYSCFG_ITLINE29 ( 0x0000001DU) /*!< Internal define for macro handling */ +#define HAL_SYSCFG_ITLINE30 ( 0x0000001EU) /*!< Internal define for macro handling */ +#define HAL_SYSCFG_ITLINE31 ( 0x0000001FU) /*!< Internal define for macro handling */ + +#define HAL_ITLINE_EWDG ((uint32_t) ((HAL_SYSCFG_ITLINE0 << 0x18U) | SYSCFG_ITLINE0_SR_EWDG)) /*!< EWDG has expired .... */ +#if defined(STM32F091xC) +#define HAL_ITLINE_PVDOUT ((uint32_t) ((HAL_SYSCFG_ITLINE1 << 0x18U) | SYSCFG_ITLINE1_SR_PVDOUT)) /*!< Power voltage detection Interrupt .... */ +#endif +#define HAL_ITLINE_VDDIO2 ((uint32_t) ((HAL_SYSCFG_ITLINE1 << 0x18U) | SYSCFG_ITLINE1_SR_VDDIO2)) /*!< VDDIO2 Interrupt .... */ +#define HAL_ITLINE_RTC_WAKEUP ((uint32_t) ((HAL_SYSCFG_ITLINE2 << 0x18U) | SYSCFG_ITLINE2_SR_RTC_WAKEUP)) /*!< RTC WAKEUP -> exti[20] Interrupt */ +#define HAL_ITLINE_RTC_TSTAMP ((uint32_t) ((HAL_SYSCFG_ITLINE2 << 0x18U) | SYSCFG_ITLINE2_SR_RTC_TSTAMP)) /*!< RTC Time Stamp -> exti[19] interrupt */ +#define HAL_ITLINE_RTC_ALRA ((uint32_t) ((HAL_SYSCFG_ITLINE2 << 0x18U) | SYSCFG_ITLINE2_SR_RTC_ALRA)) /*!< RTC Alarm -> exti[17] interrupt .... */ +#define HAL_ITLINE_FLASH_ITF ((uint32_t) ((HAL_SYSCFG_ITLINE3 << 0x18U) | SYSCFG_ITLINE3_SR_FLASH_ITF)) /*!< Flash ITF Interrupt */ +#define HAL_ITLINE_CRS ((uint32_t) ((HAL_SYSCFG_ITLINE4 << 0x18U) | SYSCFG_ITLINE4_SR_CRS)) /*!< CRS Interrupt */ +#define HAL_ITLINE_CLK_CTRL ((uint32_t) ((HAL_SYSCFG_ITLINE4 << 0x18U) | SYSCFG_ITLINE4_SR_CLK_CTRL)) /*!< CLK Control Interrupt */ +#define HAL_ITLINE_EXTI0 ((uint32_t) ((HAL_SYSCFG_ITLINE5 << 0x18U) | SYSCFG_ITLINE5_SR_EXTI0)) /*!< External Interrupt 0 */ +#define HAL_ITLINE_EXTI1 ((uint32_t) ((HAL_SYSCFG_ITLINE5 << 0x18U) | SYSCFG_ITLINE5_SR_EXTI1)) /*!< External Interrupt 1 */ +#define HAL_ITLINE_EXTI2 ((uint32_t) ((HAL_SYSCFG_ITLINE6 << 0x18U) | SYSCFG_ITLINE6_SR_EXTI2)) /*!< External Interrupt 2 */ +#define HAL_ITLINE_EXTI3 ((uint32_t) ((HAL_SYSCFG_ITLINE6 << 0x18U) | SYSCFG_ITLINE6_SR_EXTI3)) /*!< External Interrupt 3 */ +#define HAL_ITLINE_EXTI4 ((uint32_t) ((HAL_SYSCFG_ITLINE7 << 0x18U) | SYSCFG_ITLINE7_SR_EXTI4)) /*!< EXTI4 Interrupt */ +#define HAL_ITLINE_EXTI5 ((uint32_t) ((HAL_SYSCFG_ITLINE7 << 0x18U) | SYSCFG_ITLINE7_SR_EXTI5)) /*!< EXTI5 Interrupt */ +#define HAL_ITLINE_EXTI6 ((uint32_t) ((HAL_SYSCFG_ITLINE7 << 0x18U) | SYSCFG_ITLINE7_SR_EXTI6)) /*!< EXTI6 Interrupt */ +#define HAL_ITLINE_EXTI7 ((uint32_t) ((HAL_SYSCFG_ITLINE7 << 0x18U) | SYSCFG_ITLINE7_SR_EXTI7)) /*!< EXTI7 Interrupt */ +#define HAL_ITLINE_EXTI8 ((uint32_t) ((HAL_SYSCFG_ITLINE7 << 0x18U) | SYSCFG_ITLINE7_SR_EXTI8)) /*!< EXTI8 Interrupt */ +#define HAL_ITLINE_EXTI9 ((uint32_t) ((HAL_SYSCFG_ITLINE7 << 0x18U) | SYSCFG_ITLINE7_SR_EXTI9)) /*!< EXTI9 Interrupt */ +#define HAL_ITLINE_EXTI10 ((uint32_t) ((HAL_SYSCFG_ITLINE7 << 0x18U) | SYSCFG_ITLINE7_SR_EXTI10)) /*!< EXTI10 Interrupt */ +#define HAL_ITLINE_EXTI11 ((uint32_t) ((HAL_SYSCFG_ITLINE7 << 0x18U) | SYSCFG_ITLINE7_SR_EXTI11)) /*!< EXTI11 Interrupt */ +#define HAL_ITLINE_EXTI12 ((uint32_t) ((HAL_SYSCFG_ITLINE7 << 0x18U) | SYSCFG_ITLINE7_SR_EXTI12)) /*!< EXTI12 Interrupt */ +#define HAL_ITLINE_EXTI13 ((uint32_t) ((HAL_SYSCFG_ITLINE7 << 0x18U) | SYSCFG_ITLINE7_SR_EXTI13)) /*!< EXTI13 Interrupt */ +#define HAL_ITLINE_EXTI14 ((uint32_t) ((HAL_SYSCFG_ITLINE7 << 0x18U) | SYSCFG_ITLINE7_SR_EXTI14)) /*!< EXTI14 Interrupt */ +#define HAL_ITLINE_EXTI15 ((uint32_t) ((HAL_SYSCFG_ITLINE7 << 0x18U) | SYSCFG_ITLINE7_SR_EXTI15)) /*!< EXTI15 Interrupt */ +#define HAL_ITLINE_TSC_EOA ((uint32_t) ((HAL_SYSCFG_ITLINE8 << 0x18U) | SYSCFG_ITLINE8_SR_TSC_EOA)) /*!< Touch control EOA Interrupt */ +#define HAL_ITLINE_TSC_MCE ((uint32_t) ((HAL_SYSCFG_ITLINE8 << 0x18U) | SYSCFG_ITLINE8_SR_TSC_MCE)) /*!< Touch control MCE Interrupt */ +#define HAL_ITLINE_DMA1_CH1 ((uint32_t) ((HAL_SYSCFG_ITLINE9 << 0x18U) | SYSCFG_ITLINE9_SR_DMA1_CH1)) /*!< DMA1 Channel 1 Interrupt */ +#define HAL_ITLINE_DMA1_CH2 ((uint32_t) ((HAL_SYSCFG_ITLINE10 << 0x18U) | SYSCFG_ITLINE10_SR_DMA1_CH2)) /*!< DMA1 Channel 2 Interrupt */ +#define HAL_ITLINE_DMA1_CH3 ((uint32_t) ((HAL_SYSCFG_ITLINE10 << 0x18U) | SYSCFG_ITLINE10_SR_DMA1_CH3)) /*!< DMA1 Channel 3 Interrupt */ +#define HAL_ITLINE_DMA2_CH1 ((uint32_t) ((HAL_SYSCFG_ITLINE10 << 0x18U) | SYSCFG_ITLINE10_SR_DMA2_CH1)) /*!< DMA2 Channel 1 Interrupt */ +#define HAL_ITLINE_DMA2_CH2 ((uint32_t) ((HAL_SYSCFG_ITLINE10 << 0x18U) | SYSCFG_ITLINE10_SR_DMA2_CH2)) /*!< DMA2 Channel 2 Interrupt */ +#define HAL_ITLINE_DMA1_CH4 ((uint32_t) ((HAL_SYSCFG_ITLINE11 << 0x18U) | SYSCFG_ITLINE11_SR_DMA1_CH4)) /*!< DMA1 Channel 4 Interrupt */ +#define HAL_ITLINE_DMA1_CH5 ((uint32_t) ((HAL_SYSCFG_ITLINE11 << 0x18U) | SYSCFG_ITLINE11_SR_DMA1_CH5)) /*!< DMA1 Channel 5 Interrupt */ +#define HAL_ITLINE_DMA1_CH6 ((uint32_t) ((HAL_SYSCFG_ITLINE11 << 0x18U) | SYSCFG_ITLINE11_SR_DMA1_CH6)) /*!< DMA1 Channel 6 Interrupt */ +#define HAL_ITLINE_DMA1_CH7 ((uint32_t) ((HAL_SYSCFG_ITLINE11 << 0x18U) | SYSCFG_ITLINE11_SR_DMA1_CH7)) /*!< DMA1 Channel 7 Interrupt */ +#define HAL_ITLINE_DMA2_CH3 ((uint32_t) ((HAL_SYSCFG_ITLINE11 << 0x18U) | SYSCFG_ITLINE11_SR_DMA2_CH3)) /*!< DMA2 Channel 3 Interrupt */ +#define HAL_ITLINE_DMA2_CH4 ((uint32_t) ((HAL_SYSCFG_ITLINE11 << 0x18U) | SYSCFG_ITLINE11_SR_DMA2_CH4)) /*!< DMA2 Channel 4 Interrupt */ +#define HAL_ITLINE_DMA2_CH5 ((uint32_t) ((HAL_SYSCFG_ITLINE11 << 0x18U) | SYSCFG_ITLINE11_SR_DMA2_CH5)) /*!< DMA2 Channel 5 Interrupt */ +#define HAL_ITLINE_ADC ((uint32_t) ((HAL_SYSCFG_ITLINE12 << 0x18U) | SYSCFG_ITLINE12_SR_ADC)) /*!< ADC Interrupt */ +#define HAL_ITLINE_COMP1 ((uint32_t) ((HAL_SYSCFG_ITLINE12 << 0x18U) | SYSCFG_ITLINE12_SR_COMP1)) /*!< COMP1 Interrupt -> exti[21] */ +#define HAL_ITLINE_COMP2 ((uint32_t) ((HAL_SYSCFG_ITLINE12 << 0x18U) | SYSCFG_ITLINE12_SR_COMP2)) /*!< COMP2 Interrupt -> exti[21] */ +#define HAL_ITLINE_TIM1_BRK ((uint32_t) ((HAL_SYSCFG_ITLINE13 << 0x18U) | SYSCFG_ITLINE13_SR_TIM1_BRK)) /*!< TIM1 BRK Interrupt */ +#define HAL_ITLINE_TIM1_UPD ((uint32_t) ((HAL_SYSCFG_ITLINE13 << 0x18U) | SYSCFG_ITLINE13_SR_TIM1_UPD)) /*!< TIM1 UPD Interrupt */ +#define HAL_ITLINE_TIM1_TRG ((uint32_t) ((HAL_SYSCFG_ITLINE13 << 0x18U) | SYSCFG_ITLINE13_SR_TIM1_TRG)) /*!< TIM1 TRG Interrupt */ +#define HAL_ITLINE_TIM1_CCU ((uint32_t) ((HAL_SYSCFG_ITLINE13 << 0x18U) | SYSCFG_ITLINE13_SR_TIM1_CCU)) /*!< TIM1 CCU Interrupt */ +#define HAL_ITLINE_TIM1_CC ((uint32_t) ((HAL_SYSCFG_ITLINE14 << 0x18U) | SYSCFG_ITLINE14_SR_TIM1_CC)) /*!< TIM1 CC Interrupt */ +#define HAL_ITLINE_TIM2 ((uint32_t) ((HAL_SYSCFG_ITLINE15 << 0x18U) | SYSCFG_ITLINE15_SR_TIM2_GLB)) /*!< TIM2 Interrupt */ +#define HAL_ITLINE_TIM3 ((uint32_t) ((HAL_SYSCFG_ITLINE16 << 0x18U) | SYSCFG_ITLINE16_SR_TIM3_GLB)) /*!< TIM3 Interrupt */ +#define HAL_ITLINE_DAC ((uint32_t) ((HAL_SYSCFG_ITLINE17 << 0x18U) | SYSCFG_ITLINE17_SR_DAC)) /*!< DAC Interrupt */ +#define HAL_ITLINE_TIM6 ((uint32_t) ((HAL_SYSCFG_ITLINE17 << 0x18U) | SYSCFG_ITLINE17_SR_TIM6_GLB)) /*!< TIM6 Interrupt */ +#define HAL_ITLINE_TIM7 ((uint32_t) ((HAL_SYSCFG_ITLINE18 << 0x18U) | SYSCFG_ITLINE18_SR_TIM7_GLB)) /*!< TIM7 Interrupt */ +#define HAL_ITLINE_TIM14 ((uint32_t) ((HAL_SYSCFG_ITLINE19 << 0x18U) | SYSCFG_ITLINE19_SR_TIM14_GLB)) /*!< TIM14 Interrupt */ +#define HAL_ITLINE_TIM15 ((uint32_t) ((HAL_SYSCFG_ITLINE20 << 0x18U) | SYSCFG_ITLINE20_SR_TIM15_GLB)) /*!< TIM15 Interrupt */ +#define HAL_ITLINE_TIM16 ((uint32_t) ((HAL_SYSCFG_ITLINE21 << 0x18U) | SYSCFG_ITLINE21_SR_TIM16_GLB)) /*!< TIM16 Interrupt */ +#define HAL_ITLINE_TIM17 ((uint32_t) ((HAL_SYSCFG_ITLINE22 << 0x18U) | SYSCFG_ITLINE22_SR_TIM17_GLB)) /*!< TIM17 Interrupt */ +#define HAL_ITLINE_I2C1 ((uint32_t) ((HAL_SYSCFG_ITLINE23 << 0x18U) | SYSCFG_ITLINE23_SR_I2C1_GLB)) /*!< I2C1 Interrupt -> exti[23] */ +#define HAL_ITLINE_I2C2 ((uint32_t) ((HAL_SYSCFG_ITLINE24 << 0x18U) | SYSCFG_ITLINE24_SR_I2C2_GLB)) /*!< I2C2 Interrupt */ +#define HAL_ITLINE_SPI1 ((uint32_t) ((HAL_SYSCFG_ITLINE25 << 0x18U) | SYSCFG_ITLINE25_SR_SPI1)) /*!< I2C1 Interrupt -> exti[23] */ +#define HAL_ITLINE_SPI2 ((uint32_t) ((HAL_SYSCFG_ITLINE26 << 0x18U) | SYSCFG_ITLINE26_SR_SPI2)) /*!< SPI1 Interrupt */ +#define HAL_ITLINE_USART1 ((uint32_t) ((HAL_SYSCFG_ITLINE27 << 0x18U) | SYSCFG_ITLINE27_SR_USART1_GLB)) /*!< USART1 GLB Interrupt -> exti[25] */ +#define HAL_ITLINE_USART2 ((uint32_t) ((HAL_SYSCFG_ITLINE28 << 0x18U) | SYSCFG_ITLINE28_SR_USART2_GLB)) /*!< USART2 GLB Interrupt -> exti[26] */ +#define HAL_ITLINE_USART3 ((uint32_t) ((HAL_SYSCFG_ITLINE29 << 0x18U) | SYSCFG_ITLINE29_SR_USART3_GLB)) /*!< USART3 Interrupt .... */ +#define HAL_ITLINE_USART4 ((uint32_t) ((HAL_SYSCFG_ITLINE29 << 0x18U) | SYSCFG_ITLINE29_SR_USART4_GLB)) /*!< USART4 Interrupt .... */ +#define HAL_ITLINE_USART5 ((uint32_t) ((HAL_SYSCFG_ITLINE29 << 0x18U) | SYSCFG_ITLINE29_SR_USART5_GLB)) /*!< USART5 Interrupt .... */ +#define HAL_ITLINE_USART6 ((uint32_t) ((HAL_SYSCFG_ITLINE29 << 0x18U) | SYSCFG_ITLINE29_SR_USART6_GLB)) /*!< USART6 Interrupt .... */ +#define HAL_ITLINE_USART7 ((uint32_t) ((HAL_SYSCFG_ITLINE29 << 0x18U) | SYSCFG_ITLINE29_SR_USART7_GLB)) /*!< USART7 Interrupt .... */ +#define HAL_ITLINE_USART8 ((uint32_t) ((HAL_SYSCFG_ITLINE29 << 0x18U) | SYSCFG_ITLINE29_SR_USART8_GLB)) /*!< USART8 Interrupt .... */ +#define HAL_ITLINE_CAN ((uint32_t) ((HAL_SYSCFG_ITLINE30 << 0x18U) | SYSCFG_ITLINE30_SR_CAN)) /*!< CAN Interrupt */ +#define HAL_ITLINE_CEC ((uint32_t) ((HAL_SYSCFG_ITLINE30 << 0x18U) | SYSCFG_ITLINE30_SR_CEC)) /*!< CEC Interrupt -> exti[27] */ +/** + * @} + */ +#endif /* STM32F091xC || STM32F098xx */ + +/** + * @} + */ + +/* Exported macros -----------------------------------------------------------*/ +/** @defgroup HAL_Exported_Macros HAL Exported Macros + * @{ + */ + +/** @defgroup HAL_Freeze_Unfreeze_Peripherals HAL Freeze Unfreeze Peripherals + * @brief Freeze/Unfreeze Peripherals in Debug mode + * @{ + */ + +#if defined(DBGMCU_APB1_FZ_DBG_CAN_STOP) +#define __HAL_FREEZE_CAN_DBGMCU() (DBGMCU->APB1FZ |= (DBGMCU_APB1_FZ_DBG_CAN_STOP)) +#define __HAL_UNFREEZE_CAN_DBGMCU() (DBGMCU->APB1FZ &= ~(DBGMCU_APB1_FZ_DBG_CAN_STOP)) +#endif /* DBGMCU_APB1_FZ_DBG_CAN_STOP */ + +#if defined(DBGMCU_APB1_FZ_DBG_RTC_STOP) +#define __HAL_DBGMCU_FREEZE_RTC() (DBGMCU->APB1FZ |= (DBGMCU_APB1_FZ_DBG_RTC_STOP)) +#define __HAL_DBGMCU_UNFREEZE_RTC() (DBGMCU->APB1FZ &= ~(DBGMCU_APB1_FZ_DBG_RTC_STOP)) +#endif /* DBGMCU_APB1_FZ_DBG_RTC_STOP */ + +#if defined(DBGMCU_APB1_FZ_DBG_I2C1_SMBUS_TIMEOUT) +#define __HAL_DBGMCU_FREEZE_I2C1_TIMEOUT() (DBGMCU->APB1FZ |= (DBGMCU_APB1_FZ_DBG_I2C1_SMBUS_TIMEOUT)) +#define __HAL_DBGMCU_UNFREEZE_I2C1_TIMEOUT() (DBGMCU->APB1FZ &= ~(DBGMCU_APB1_FZ_DBG_I2C1_SMBUS_TIMEOUT)) +#endif /* DBGMCU_APB1_FZ_DBG_I2C1_SMBUS_TIMEOUT */ + +#if defined(DBGMCU_APB1_FZ_DBG_IWDG_STOP) +#define __HAL_DBGMCU_FREEZE_IWDG() (DBGMCU->APB1FZ |= (DBGMCU_APB1_FZ_DBG_IWDG_STOP)) +#define __HAL_DBGMCU_UNFREEZE_IWDG() (DBGMCU->APB1FZ &= ~(DBGMCU_APB1_FZ_DBG_IWDG_STOP)) +#endif /* DBGMCU_APB1_FZ_DBG_IWDG_STOP */ + +#if defined(DBGMCU_APB1_FZ_DBG_WWDG_STOP) +#define __HAL_DBGMCU_FREEZE_WWDG() (DBGMCU->APB1FZ |= (DBGMCU_APB1_FZ_DBG_WWDG_STOP)) +#define __HAL_DBGMCU_UNFREEZE_WWDG() (DBGMCU->APB1FZ &= ~(DBGMCU_APB1_FZ_DBG_WWDG_STOP)) +#endif /* DBGMCU_APB1_FZ_DBG_WWDG_STOP */ + +#if defined(DBGMCU_APB1_FZ_DBG_TIM2_STOP) +#define __HAL_DBGMCU_FREEZE_TIM2() (DBGMCU->APB1FZ |= (DBGMCU_APB1_FZ_DBG_TIM2_STOP)) +#define __HAL_DBGMCU_UNFREEZE_TIM2() (DBGMCU->APB1FZ &= ~(DBGMCU_APB1_FZ_DBG_TIM2_STOP)) +#endif /* DBGMCU_APB1_FZ_DBG_TIM2_STOP */ + +#if defined(DBGMCU_APB1_FZ_DBG_TIM3_STOP) +#define __HAL_DBGMCU_FREEZE_TIM3() (DBGMCU->APB1FZ |= (DBGMCU_APB1_FZ_DBG_TIM3_STOP)) +#define __HAL_DBGMCU_UNFREEZE_TIM3() (DBGMCU->APB1FZ &= ~(DBGMCU_APB1_FZ_DBG_TIM3_STOP)) +#endif /* DBGMCU_APB1_FZ_DBG_TIM3_STOP */ + +#if defined(DBGMCU_APB1_FZ_DBG_TIM6_STOP) +#define __HAL_DBGMCU_FREEZE_TIM6() (DBGMCU->APB1FZ |= (DBGMCU_APB1_FZ_DBG_TIM6_STOP)) +#define __HAL_DBGMCU_UNFREEZE_TIM6() (DBGMCU->APB1FZ &= ~(DBGMCU_APB1_FZ_DBG_TIM6_STOP)) +#endif /* DBGMCU_APB1_FZ_DBG_TIM6_STOP */ + +#if defined(DBGMCU_APB1_FZ_DBG_TIM7_STOP) +#define __HAL_DBGMCU_FREEZE_TIM7() (DBGMCU->APB1FZ |= (DBGMCU_APB1_FZ_DBG_TIM7_STOP)) +#define __HAL_DBGMCU_UNFREEZE_TIM7() (DBGMCU->APB1FZ &= ~(DBGMCU_APB1_FZ_DBG_TIM7_STOP)) +#endif /* DBGMCU_APB1_FZ_DBG_TIM7_STOP */ + +#if defined(DBGMCU_APB1_FZ_DBG_TIM14_STOP) +#define __HAL_DBGMCU_FREEZE_TIM14() (DBGMCU->APB1FZ |= (DBGMCU_APB1_FZ_DBG_TIM14_STOP)) +#define __HAL_DBGMCU_UNFREEZE_TIM14() (DBGMCU->APB1FZ &= ~(DBGMCU_APB1_FZ_DBG_TIM14_STOP)) +#endif /* DBGMCU_APB1_FZ_DBG_TIM14_STOP */ + +#if defined(DBGMCU_APB2_FZ_DBG_TIM1_STOP) +#define __HAL_DBGMCU_FREEZE_TIM1() (DBGMCU->APB2FZ |= (DBGMCU_APB2_FZ_DBG_TIM1_STOP)) +#define __HAL_DBGMCU_UNFREEZE_TIM1() (DBGMCU->APB2FZ &= ~(DBGMCU_APB2_FZ_DBG_TIM1_STOP)) +#endif /* DBGMCU_APB2_FZ_DBG_TIM1_STOP */ + +#if defined(DBGMCU_APB2_FZ_DBG_TIM15_STOP) +#define __HAL_DBGMCU_FREEZE_TIM15() (DBGMCU->APB2FZ |= (DBGMCU_APB2_FZ_DBG_TIM15_STOP)) +#define __HAL_DBGMCU_UNFREEZE_TIM15() (DBGMCU->APB2FZ &= ~(DBGMCU_APB2_FZ_DBG_TIM15_STOP)) +#endif /* DBGMCU_APB2_FZ_DBG_TIM15_STOP */ + +#if defined(DBGMCU_APB2_FZ_DBG_TIM16_STOP) +#define __HAL_DBGMCU_FREEZE_TIM16() (DBGMCU->APB2FZ |= (DBGMCU_APB2_FZ_DBG_TIM16_STOP)) +#define __HAL_DBGMCU_UNFREEZE_TIM16() (DBGMCU->APB2FZ &= ~(DBGMCU_APB2_FZ_DBG_TIM16_STOP)) +#endif /* DBGMCU_APB2_FZ_DBG_TIM16_STOP */ + +#if defined(DBGMCU_APB2_FZ_DBG_TIM17_STOP) +#define __HAL_DBGMCU_FREEZE_TIM17() (DBGMCU->APB2FZ |= (DBGMCU_APB2_FZ_DBG_TIM17_STOP)) +#define __HAL_DBGMCU_UNFREEZE_TIM17() (DBGMCU->APB2FZ &= ~(DBGMCU_APB2_FZ_DBG_TIM17_STOP)) +#endif /* DBGMCU_APB2_FZ_DBG_TIM17_STOP */ + +/** + * @} + */ + +/** @defgroup Memory_Mapping_Selection Memory Mapping Selection + * @{ + */ +#if defined(SYSCFG_CFGR1_MEM_MODE) +/** @brief Main Flash memory mapped at 0x00000000 + */ +#define __HAL_SYSCFG_REMAPMEMORY_FLASH() (SYSCFG->CFGR1 &= ~(SYSCFG_CFGR1_MEM_MODE)) +#endif /* SYSCFG_CFGR1_MEM_MODE */ + +#if defined(SYSCFG_CFGR1_MEM_MODE_0) +/** @brief System Flash memory mapped at 0x00000000 + */ +#define __HAL_SYSCFG_REMAPMEMORY_SYSTEMFLASH() do {SYSCFG->CFGR1 &= ~(SYSCFG_CFGR1_MEM_MODE); \ + SYSCFG->CFGR1 |= SYSCFG_CFGR1_MEM_MODE_0; \ + }while(0) +#endif /* SYSCFG_CFGR1_MEM_MODE_0 */ + +#if defined(SYSCFG_CFGR1_MEM_MODE_0) && defined(SYSCFG_CFGR1_MEM_MODE_1) +/** @brief Embedded SRAM mapped at 0x00000000 + */ +#define __HAL_SYSCFG_REMAPMEMORY_SRAM() do {SYSCFG->CFGR1 &= ~(SYSCFG_CFGR1_MEM_MODE); \ + SYSCFG->CFGR1 |= (SYSCFG_CFGR1_MEM_MODE_0 | SYSCFG_CFGR1_MEM_MODE_1); \ + }while(0) +#endif /* SYSCFG_CFGR1_MEM_MODE_0 && SYSCFG_CFGR1_MEM_MODE_1 */ +/** + * @} + */ + + +#if defined(SYSCFG_CFGR1_PA11_PA12_RMP) +/** @defgroup HAL_Pin_remap HAL Pin remap + * @brief Pin remapping enable/disable macros + * @param __PIN_REMAP__ This parameter can be a value of @ref HAL_Pin_remapping + * @{ + */ +#define __HAL_REMAP_PIN_ENABLE(__PIN_REMAP__) do {assert_param(IS_HAL_REMAP_PIN((__PIN_REMAP__))); \ + SYSCFG->CFGR1 |= (__PIN_REMAP__); \ + }while(0) +#define __HAL_REMAP_PIN_DISABLE(__PIN_REMAP__) do {assert_param(IS_HAL_REMAP_PIN((__PIN_REMAP__))); \ + SYSCFG->CFGR1 &= ~(__PIN_REMAP__); \ + }while(0) +/** + * @} + */ +#endif /* SYSCFG_CFGR1_PA11_PA12_RMP */ + +/** @brief Fast-mode Plus driving capability enable/disable macros + * @param __FASTMODEPLUS__ This parameter can be a value of @ref SYSCFG_FastModePlus_GPIO values. + * That you can find above these macros. + */ +#define __HAL_SYSCFG_FASTMODEPLUS_ENABLE(__FASTMODEPLUS__) do {assert_param(IS_SYSCFG_FASTMODEPLUS((__FASTMODEPLUS__)));\ + SET_BIT(SYSCFG->CFGR1, (__FASTMODEPLUS__));\ + }while(0) + +#define __HAL_SYSCFG_FASTMODEPLUS_DISABLE(__FASTMODEPLUS__) do {assert_param(IS_SYSCFG_FASTMODEPLUS((__FASTMODEPLUS__)));\ + CLEAR_BIT(SYSCFG->CFGR1, (__FASTMODEPLUS__));\ + }while(0) +#if defined(SYSCFG_CFGR2_LOCKUP_LOCK) +/** @defgroup Cortex_Lockup_Enable Cortex Lockup Enable + * @{ + */ +/** @brief SYSCFG Break Lockup lock + * Enables and locks the connection of Cortex-M0 LOCKUP (Hardfault) output to TIM1/15/16/17 Break input + * @note The selected configuration is locked and can be unlocked by system reset + */ +#define __HAL_SYSCFG_BREAK_LOCKUP_LOCK() do {SYSCFG->CFGR2 &= ~(SYSCFG_CFGR2_LOCKUP_LOCK); \ + SYSCFG->CFGR2 |= SYSCFG_CFGR2_LOCKUP_LOCK; \ + }while(0) +/** + * @} + */ +#endif /* SYSCFG_CFGR2_LOCKUP_LOCK */ + +#if defined(SYSCFG_CFGR2_PVD_LOCK) +/** @defgroup PVD_Lock_Enable PVD Lock + * @{ + */ +/** @brief SYSCFG Break PVD lock + * Enables and locks the PVD connection with Timer1/8/15/16/17 Break Input, , as well as the PVDE and PLS[2:0] in the PWR_CR register + * @note The selected configuration is locked and can be unlocked by system reset + */ +#define __HAL_SYSCFG_BREAK_PVD_LOCK() do {SYSCFG->CFGR2 &= ~(SYSCFG_CFGR2_PVD_LOCK); \ + SYSCFG->CFGR2 |= SYSCFG_CFGR2_PVD_LOCK; \ + }while(0) +/** + * @} + */ +#endif /* SYSCFG_CFGR2_PVD_LOCK */ + +#if defined(SYSCFG_CFGR2_SRAM_PARITY_LOCK) +/** @defgroup SRAM_Parity_Lock SRAM Parity Lock + * @{ + */ +/** @brief SYSCFG Break SRAM PARITY lock + * Enables and locks the SRAM_PARITY error signal with Break Input of TIMER1/8/15/16/17 + * @note The selected configuration is locked and can be unlocked by system reset + */ +#define __HAL_SYSCFG_BREAK_SRAMPARITY_LOCK() do {SYSCFG->CFGR2 &= ~(SYSCFG_CFGR2_SRAM_PARITY_LOCK); \ + SYSCFG->CFGR2 |= SYSCFG_CFGR2_SRAM_PARITY_LOCK; \ + }while(0) +/** + * @} + */ +#endif /* SYSCFG_CFGR2_SRAM_PARITY_LOCK */ + +#if defined(SYSCFG_CFGR2_SRAM_PEF) +/** @defgroup HAL_SYSCFG_Parity_check_on_RAM HAL SYSCFG Parity check on RAM + * @brief Parity check on RAM disable macro + * @note Disabling the parity check on RAM locks the configuration bit. + * To re-enable the parity check on RAM perform a system reset. + * @{ + */ +#define __HAL_SYSCFG_RAM_PARITYCHECK_DISABLE() (SYSCFG->CFGR2 |= SYSCFG_CFGR2_SRAM_PEF) +/** + * @} + */ +#endif /* SYSCFG_CFGR2_SRAM_PEF */ + + +#if defined(STM32F091xC) || defined (STM32F098xx) +/** @defgroup HAL_ISR_wrapper_check HAL ISR wrapper check + * @brief ISR wrapper check + * @note This feature is applicable on STM32F09x + * @note Allow to determine interrupt source per line. + * @{ + */ +#define __HAL_GET_PENDING_IT(__SOURCE__) (SYSCFG->IT_LINE_SR[((__SOURCE__) >> 0x18U)] & ((__SOURCE__) & 0x00FFFFFF)) +/** + * @} + */ +#endif /* (STM32F091xC) || defined (STM32F098xx)*/ + +#if defined(STM32F091xC) || defined (STM32F098xx) +/** @defgroup HAL_SYSCFG_IRDA_modulation_envelope_selection HAL SYSCFG IRDA modulation envelope selection + * @brief selection of the modulation envelope signal macro, using bits [7:6] of SYS_CTRL(CFGR1) register + * @note This feature is applicable on STM32F09x + * @param __SOURCE__ This parameter can be a value of @ref HAL_IRDA_ENV_SEL + * @{ + */ +#define __HAL_SYSCFG_IRDA_ENV_SELECTION(__SOURCE__) do {assert_param(IS_HAL_SYSCFG_IRDA_ENV_SEL((__SOURCE__))); \ + SYSCFG->CFGR1 &= ~(SYSCFG_CFGR1_IRDA_ENV_SEL); \ + SYSCFG->CFGR1 |= (__SOURCE__); \ + }while(0) + +#define __HAL_SYSCFG_GET_IRDA_ENV_SELECTION() ((SYSCFG->CFGR1) & 0x000000C0) +/** + * @} + */ +#endif /* (STM32F091xC) || defined (STM32F098xx)*/ + +/** + * @} + */ + +/** @defgroup HAL_Private_Macros HAL Private Macros + * @{ + */ +#define IS_TICKFREQ(FREQ) (((FREQ) == HAL_TICK_FREQ_10HZ) || \ + ((FREQ) == HAL_TICK_FREQ_100HZ) || \ + ((FREQ) == HAL_TICK_FREQ_1KHZ)) +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ + +/** @addtogroup HAL_Exported_Functions + * @{ + */ + +/** @addtogroup HAL_Exported_Functions_Group1 + * @{ + */ +/* Initialization and de-initialization functions ******************************/ +HAL_StatusTypeDef HAL_Init(void); +HAL_StatusTypeDef HAL_DeInit(void); +void HAL_MspInit(void); +void HAL_MspDeInit(void); +HAL_StatusTypeDef HAL_InitTick (uint32_t TickPriority); +/** + * @} + */ + +/* Exported variables ---------------------------------------------------------*/ +/** @addtogroup HAL_Exported_Variables + * @{ + */ +extern __IO uint32_t uwTick; +extern uint32_t uwTickPrio; +extern HAL_TickFreqTypeDef uwTickFreq; +/** + * @} + */ + +/** @addtogroup HAL_Exported_Functions_Group2 + * @{ + */ + +/* Peripheral Control functions ************************************************/ +void HAL_IncTick(void); +void HAL_Delay(uint32_t Delay); +uint32_t HAL_GetTick(void); +uint32_t HAL_GetTickPrio(void); +HAL_StatusTypeDef HAL_SetTickFreq(HAL_TickFreqTypeDef Freq); +HAL_TickFreqTypeDef HAL_GetTickFreq(void); +void HAL_SuspendTick(void); +void HAL_ResumeTick(void); +uint32_t HAL_GetHalVersion(void); +uint32_t HAL_GetREVID(void); +uint32_t HAL_GetDEVID(void); +uint32_t HAL_GetUIDw0(void); +uint32_t HAL_GetUIDw1(void); +uint32_t HAL_GetUIDw2(void); +void HAL_DBGMCU_EnableDBGStopMode(void); +void HAL_DBGMCU_DisableDBGStopMode(void); +void HAL_DBGMCU_EnableDBGStandbyMode(void); +void HAL_DBGMCU_DisableDBGStandbyMode(void); +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F0xx_HAL_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_cortex.h b/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_cortex.h new file mode 100644 index 0000000..e471200 --- /dev/null +++ b/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_cortex.h @@ -0,0 +1,133 @@ +/** + ****************************************************************************** + * @file stm32f0xx_hal_cortex.h + * @author MCD Application Team + * @brief Header file of CORTEX HAL module. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2016 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F0xx_HAL_CORTEX_H +#define __STM32F0xx_HAL_CORTEX_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f0xx_hal_def.h" + +/** @addtogroup STM32F0xx_HAL_Driver + * @{ + */ + +/** @addtogroup CORTEX CORTEX + * @{ + */ +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup CORTEX_Exported_Constants CORTEX Exported Constants + * @{ + */ + +/** @defgroup CORTEX_SysTick_clock_source CORTEX SysTick clock source + * @{ + */ +#define SYSTICK_CLKSOURCE_HCLK_DIV8 (0x00000000U) +#define SYSTICK_CLKSOURCE_HCLK (0x00000004U) + +/** + * @} + */ + +/** + * @} + */ + +/* Exported Macros -----------------------------------------------------------*/ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup CORTEX_Exported_Functions CORTEX Exported Functions + * @{ + */ +/** @addtogroup CORTEX_Exported_Functions_Group1 Initialization and de-initialization functions + * @brief Initialization and Configuration functions + * @{ + */ +/* Initialization and de-initialization functions *******************************/ +void HAL_NVIC_SetPriority(IRQn_Type IRQn,uint32_t PreemptPriority, uint32_t SubPriority); +void HAL_NVIC_EnableIRQ(IRQn_Type IRQn); +void HAL_NVIC_DisableIRQ(IRQn_Type IRQn); +void HAL_NVIC_SystemReset(void); +uint32_t HAL_SYSTICK_Config(uint32_t TicksNumb); +/** + * @} + */ + +/** @addtogroup CORTEX_Exported_Functions_Group2 Peripheral Control functions + * @brief Cortex control functions + * @{ + */ + +/* Peripheral Control functions *************************************************/ +uint32_t HAL_NVIC_GetPriority(IRQn_Type IRQn); +uint32_t HAL_NVIC_GetPendingIRQ(IRQn_Type IRQn); +void HAL_NVIC_SetPendingIRQ(IRQn_Type IRQn); +void HAL_NVIC_ClearPendingIRQ(IRQn_Type IRQn); +void HAL_SYSTICK_CLKSourceConfig(uint32_t CLKSource); +void HAL_SYSTICK_IRQHandler(void); +void HAL_SYSTICK_Callback(void); +/** + * @} + */ + +/** + * @} + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/* Private macros ------------------------------------------------------------*/ +/** @defgroup CORTEX_Private_Macros CORTEX Private Macros + * @{ + */ +#define IS_NVIC_PREEMPTION_PRIORITY(PRIORITY) ((PRIORITY) < 0x4) + +#define IS_NVIC_DEVICE_IRQ(IRQ) ((IRQ) >= 0x00) + +#define IS_SYSTICK_CLK_SOURCE(SOURCE) (((SOURCE) == SYSTICK_CLKSOURCE_HCLK) || \ + ((SOURCE) == SYSTICK_CLKSOURCE_HCLK_DIV8)) +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F0xx_HAL_CORTEX_H */ + + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ + diff --git a/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_def.h b/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_def.h new file mode 100644 index 0000000..1d2c9f8 --- /dev/null +++ b/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_def.h @@ -0,0 +1,166 @@ +/** + ****************************************************************************** + * @file stm32f0xx_hal_def.h + * @author MCD Application Team + * @brief This file contains HAL common defines, enumeration, macros and + * structures definitions. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2016 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F0xx_HAL_DEF +#define __STM32F0xx_HAL_DEF + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f0xx.h" +#if defined(USE_HAL_LEGACY) + #include "Legacy/stm32_hal_legacy.h" +#endif +#include + +/* Exported types ------------------------------------------------------------*/ + +/** + * @brief HAL Status structures definition + */ +typedef enum +{ + HAL_OK = 0x00U, + HAL_ERROR = 0x01U, + HAL_BUSY = 0x02U, + HAL_TIMEOUT = 0x03U +} HAL_StatusTypeDef; + +/** + * @brief HAL Lock structures definition + */ +typedef enum +{ + HAL_UNLOCKED = 0x00U, + HAL_LOCKED = 0x01U +} HAL_LockTypeDef; + +/* Exported macro ------------------------------------------------------------*/ + +#define HAL_MAX_DELAY 0xFFFFFFFFU + +#define HAL_IS_BIT_SET(REG, BIT) (((REG) & (BIT)) == (BIT)) +#define HAL_IS_BIT_CLR(REG, BIT) (((REG) & (BIT)) == 0U) + +#define __HAL_LINKDMA(__HANDLE__, __PPP_DMA_FIELD_, __DMA_HANDLE_) \ + do{ \ + (__HANDLE__)->__PPP_DMA_FIELD_ = &(__DMA_HANDLE_); \ + (__DMA_HANDLE_).Parent = (__HANDLE__); \ + } while(0) + +#define UNUSED(X) (void)X /* To avoid gcc/g++ warnings */ + +/** @brief Reset the Handle's State field. + * @param __HANDLE__ specifies the Peripheral Handle. + * @note This macro can be used for the following purpose: + * - When the Handle is declared as local variable; before passing it as parameter + * to HAL_PPP_Init() for the first time, it is mandatory to use this macro + * to set to 0 the Handle's "State" field. + * Otherwise, "State" field may have any random value and the first time the function + * HAL_PPP_Init() is called, the low level hardware initialization will be missed + * (i.e. HAL_PPP_MspInit() will not be executed). + * - When there is a need to reconfigure the low level hardware: instead of calling + * HAL_PPP_DeInit() then HAL_PPP_Init(), user can make a call to this macro then HAL_PPP_Init(). + * In this later function, when the Handle's "State" field is set to 0, it will execute the function + * HAL_PPP_MspInit() which will reconfigure the low level hardware. + * @retval None + */ +#define __HAL_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = 0) + +#if (USE_RTOS == 1) + #error " USE_RTOS should be 0 in the current HAL release " +#else + #define __HAL_LOCK(__HANDLE__) \ + do{ \ + if((__HANDLE__)->Lock == HAL_LOCKED) \ + { \ + return HAL_BUSY; \ + } \ + else \ + { \ + (__HANDLE__)->Lock = HAL_LOCKED; \ + } \ + }while (0) + + #define __HAL_UNLOCK(__HANDLE__) \ + do{ \ + (__HANDLE__)->Lock = HAL_UNLOCKED; \ + }while (0) +#endif /* USE_RTOS */ + +#if defined ( __GNUC__ ) + #ifndef __weak + #define __weak __attribute__((weak)) + #endif /* __weak */ + #ifndef __packed + #define __packed __attribute__((__packed__)) + #endif /* __packed */ +#endif /* __GNUC__ */ + + +/* Macro to get variable aligned on 4-bytes, for __ICCARM__ the directive "#pragma data_alignment=4" must be used instead */ +#if defined (__GNUC__) /* GNU Compiler */ + #ifndef __ALIGN_END + #define __ALIGN_END __attribute__ ((aligned (4))) + #endif /* __ALIGN_END */ + #ifndef __ALIGN_BEGIN + #define __ALIGN_BEGIN + #endif /* __ALIGN_BEGIN */ +#else + #ifndef __ALIGN_END + #define __ALIGN_END + #endif /* __ALIGN_END */ + #ifndef __ALIGN_BEGIN + #if defined (__CC_ARM) /* ARM Compiler */ + #define __ALIGN_BEGIN __align(4) + #elif defined (__ICCARM__) /* IAR Compiler */ + #define __ALIGN_BEGIN + #endif /* __CC_ARM */ + #endif /* __ALIGN_BEGIN */ +#endif /* __GNUC__ */ + +/** + * @brief __NOINLINE definition + */ +#if defined ( __CC_ARM ) || defined ( __GNUC__ ) +/* ARM & GNUCompiler + ---------------- +*/ +#define __NOINLINE __attribute__ ( (noinline) ) + +#elif defined ( __ICCARM__ ) +/* ICCARM Compiler + --------------- +*/ +#define __NOINLINE _Pragma("optimize = no_inline") + +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* ___STM32F0xx_HAL_DEF */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ + diff --git a/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma.h b/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma.h new file mode 100644 index 0000000..db71942 --- /dev/null +++ b/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma.h @@ -0,0 +1,563 @@ +/** + ****************************************************************************** + * @file stm32f0xx_hal_dma.h + * @author MCD Application Team + * @brief Header file of DMA HAL module. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2016 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F0xx_HAL_DMA_H +#define __STM32F0xx_HAL_DMA_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f0xx_hal_def.h" + +/** @addtogroup STM32F0xx_HAL_Driver + * @{ + */ + +/** @addtogroup DMA + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ + +/** @defgroup DMA_Exported_Types DMA Exported Types + * @{ + */ + +/** + * @brief DMA Configuration Structure definition + */ +typedef struct +{ + uint32_t Direction; /*!< Specifies if the data will be transferred from memory to peripheral, + from memory to memory or from peripheral to memory. + This parameter can be a value of @ref DMA_Data_transfer_direction */ + + uint32_t PeriphInc; /*!< Specifies whether the Peripheral address register should be incremented or not. + This parameter can be a value of @ref DMA_Peripheral_incremented_mode */ + + uint32_t MemInc; /*!< Specifies whether the memory address register should be incremented or not. + This parameter can be a value of @ref DMA_Memory_incremented_mode */ + + uint32_t PeriphDataAlignment; /*!< Specifies the Peripheral data width. + This parameter can be a value of @ref DMA_Peripheral_data_size */ + + uint32_t MemDataAlignment; /*!< Specifies the Memory data width. + This parameter can be a value of @ref DMA_Memory_data_size */ + + uint32_t Mode; /*!< Specifies the operation mode of the DMAy Channelx. + This parameter can be a value of @ref DMA_mode + @note The circular buffer mode cannot be used if the memory-to-memory + data transfer is configured on the selected Channel */ + + uint32_t Priority; /*!< Specifies the software priority for the DMAy Channelx. + This parameter can be a value of @ref DMA_Priority_level */ +} DMA_InitTypeDef; + +/** + * @brief HAL DMA State structures definition + */ +typedef enum +{ + HAL_DMA_STATE_RESET = 0x00U, /*!< DMA not yet initialized or disabled */ + HAL_DMA_STATE_READY = 0x01U, /*!< DMA initialized and ready for use */ + HAL_DMA_STATE_BUSY = 0x02U, /*!< DMA process is ongoing */ + HAL_DMA_STATE_TIMEOUT = 0x03U /*!< DMA timeout state */ +}HAL_DMA_StateTypeDef; + +/** + * @brief HAL DMA Error Code structure definition + */ +typedef enum +{ + HAL_DMA_FULL_TRANSFER = 0x00U, /*!< Full transfer */ + HAL_DMA_HALF_TRANSFER = 0x01U /*!< Half Transfer */ +}HAL_DMA_LevelCompleteTypeDef; + +/** + * @brief HAL DMA Callback ID structure definition + */ +typedef enum +{ + HAL_DMA_XFER_CPLT_CB_ID = 0x00U, /*!< Full transfer */ + HAL_DMA_XFER_HALFCPLT_CB_ID = 0x01U, /*!< Half transfer */ + HAL_DMA_XFER_ERROR_CB_ID = 0x02U, /*!< Error */ + HAL_DMA_XFER_ABORT_CB_ID = 0x03U, /*!< Abort */ + HAL_DMA_XFER_ALL_CB_ID = 0x04U /*!< All */ + +}HAL_DMA_CallbackIDTypeDef; + +/** + * @brief DMA handle Structure definition + */ +typedef struct __DMA_HandleTypeDef +{ + DMA_Channel_TypeDef *Instance; /*!< Register base address */ + + DMA_InitTypeDef Init; /*!< DMA communication parameters */ + + HAL_LockTypeDef Lock; /*!< DMA locking object */ + + __IO HAL_DMA_StateTypeDef State; /*!< DMA transfer state */ + + void *Parent; /*!< Parent object state */ + + void (* XferCpltCallback)( struct __DMA_HandleTypeDef * hdma); /*!< DMA transfer complete callback */ + + void (* XferHalfCpltCallback)( struct __DMA_HandleTypeDef * hdma); /*!< DMA Half transfer complete callback */ + + void (* XferErrorCallback)( struct __DMA_HandleTypeDef * hdma); /*!< DMA transfer error callback */ + + void (* XferAbortCallback)( struct __DMA_HandleTypeDef * hdma); /*!< DMA transfer abort callback */ + + __IO uint32_t ErrorCode; /*!< DMA Error code */ + + DMA_TypeDef *DmaBaseAddress; /*!< DMA Channel Base Address */ + + uint32_t ChannelIndex; /*!< DMA Channel Index */ +} DMA_HandleTypeDef; + +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup DMA_Exported_Constants DMA Exported Constants + * @{ + */ + +/** @defgroup DMA_Error_Code DMA Error Code + * @{ + */ +#define HAL_DMA_ERROR_NONE (0x00000000U) /*!< No error */ +#define HAL_DMA_ERROR_TE (0x00000001U) /*!< Transfer error */ +#define HAL_DMA_ERROR_NO_XFER (0x00000004U) /*!< no ongoin transfer */ +#define HAL_DMA_ERROR_TIMEOUT (0x00000020U) /*!< Timeout error */ +#define HAL_DMA_ERROR_NOT_SUPPORTED (0x00000100U) /*!< Not supported mode */ +/** + * @} + */ + +/** @defgroup DMA_Data_transfer_direction DMA Data transfer direction + * @{ + */ +#define DMA_PERIPH_TO_MEMORY (0x00000000U) /*!< Peripheral to memory direction */ +#define DMA_MEMORY_TO_PERIPH ((uint32_t)DMA_CCR_DIR) /*!< Memory to peripheral direction */ +#define DMA_MEMORY_TO_MEMORY ((uint32_t)(DMA_CCR_MEM2MEM)) /*!< Memory to memory direction */ + +/** + * @} + */ + +/** @defgroup DMA_Peripheral_incremented_mode DMA Peripheral incremented mode + * @{ + */ +#define DMA_PINC_ENABLE ((uint32_t)DMA_CCR_PINC) /*!< Peripheral increment mode Enable */ +#define DMA_PINC_DISABLE (0x00000000U) /*!< Peripheral increment mode Disable */ +/** + * @} + */ + +/** @defgroup DMA_Memory_incremented_mode DMA Memory incremented mode + * @{ + */ +#define DMA_MINC_ENABLE ((uint32_t)DMA_CCR_MINC) /*!< Memory increment mode Enable */ +#define DMA_MINC_DISABLE (0x00000000U) /*!< Memory increment mode Disable */ +/** + * @} + */ + +/** @defgroup DMA_Peripheral_data_size DMA Peripheral data size + * @{ + */ +#define DMA_PDATAALIGN_BYTE (0x00000000U) /*!< Peripheral data alignment : Byte */ +#define DMA_PDATAALIGN_HALFWORD ((uint32_t)DMA_CCR_PSIZE_0) /*!< Peripheral data alignment : HalfWord */ +#define DMA_PDATAALIGN_WORD ((uint32_t)DMA_CCR_PSIZE_1) /*!< Peripheral data alignment : Word */ +/** + * @} + */ + +/** @defgroup DMA_Memory_data_size DMA Memory data size + * @{ + */ +#define DMA_MDATAALIGN_BYTE (0x00000000U) /*!< Memory data alignment : Byte */ +#define DMA_MDATAALIGN_HALFWORD ((uint32_t)DMA_CCR_MSIZE_0) /*!< Memory data alignment : HalfWord */ +#define DMA_MDATAALIGN_WORD ((uint32_t)DMA_CCR_MSIZE_1) /*!< Memory data alignment : Word */ +/** + * @} + */ + +/** @defgroup DMA_mode DMA mode + * @{ + */ +#define DMA_NORMAL (0x00000000U) /*!< Normal Mode */ +#define DMA_CIRCULAR ((uint32_t)DMA_CCR_CIRC) /*!< Circular Mode */ +/** + * @} + */ + +/** @defgroup DMA_Priority_level DMA Priority level + * @{ + */ +#define DMA_PRIORITY_LOW (0x00000000U) /*!< Priority level : Low */ +#define DMA_PRIORITY_MEDIUM ((uint32_t)DMA_CCR_PL_0) /*!< Priority level : Medium */ +#define DMA_PRIORITY_HIGH ((uint32_t)DMA_CCR_PL_1) /*!< Priority level : High */ +#define DMA_PRIORITY_VERY_HIGH ((uint32_t)DMA_CCR_PL) /*!< Priority level : Very_High */ +/** + * @} + */ + + +/** @defgroup DMA_interrupt_enable_definitions DMA interrupt enable definitions + * @{ + */ +#define DMA_IT_TC ((uint32_t)DMA_CCR_TCIE) +#define DMA_IT_HT ((uint32_t)DMA_CCR_HTIE) +#define DMA_IT_TE ((uint32_t)DMA_CCR_TEIE) +/** + * @} + */ + +/** @defgroup DMA_flag_definitions DMA flag definitions + * @{ + */ + +#define DMA_FLAG_GL1 (0x00000001U) /*!< Channel 1 global interrupt flag */ +#define DMA_FLAG_TC1 (0x00000002U) /*!< Channel 1 transfer complete flag */ +#define DMA_FLAG_HT1 (0x00000004U) /*!< Channel 1 half transfer flag */ +#define DMA_FLAG_TE1 (0x00000008U) /*!< Channel 1 transfer error flag */ +#define DMA_FLAG_GL2 (0x00000010U) /*!< Channel 2 global interrupt flag */ +#define DMA_FLAG_TC2 (0x00000020U) /*!< Channel 2 transfer complete flag */ +#define DMA_FLAG_HT2 (0x00000040U) /*!< Channel 2 half transfer flag */ +#define DMA_FLAG_TE2 (0x00000080U) /*!< Channel 2 transfer error flag */ +#define DMA_FLAG_GL3 (0x00000100U) /*!< Channel 3 global interrupt flag */ +#define DMA_FLAG_TC3 (0x00000200U) /*!< Channel 3 transfer complete flag */ +#define DMA_FLAG_HT3 (0x00000400U) /*!< Channel 3 half transfer flag */ +#define DMA_FLAG_TE3 (0x00000800U) /*!< Channel 3 transfer error flag */ +#define DMA_FLAG_GL4 (0x00001000U) /*!< Channel 4 global interrupt flag */ +#define DMA_FLAG_TC4 (0x00002000U) /*!< Channel 4 transfer complete flag */ +#define DMA_FLAG_HT4 (0x00004000U) /*!< Channel 4 half transfer flag */ +#define DMA_FLAG_TE4 (0x00008000U) /*!< Channel 4 transfer error flag */ +#define DMA_FLAG_GL5 (0x00010000U) /*!< Channel 5 global interrupt flag */ +#define DMA_FLAG_TC5 (0x00020000U) /*!< Channel 5 transfer complete flag */ +#define DMA_FLAG_HT5 (0x00040000U) /*!< Channel 5 half transfer flag */ +#define DMA_FLAG_TE5 (0x00080000U) /*!< Channel 5 transfer error flag */ +#define DMA_FLAG_GL6 (0x00100000U) /*!< Channel 6 global interrupt flag */ +#define DMA_FLAG_TC6 (0x00200000U) /*!< Channel 6 transfer complete flag */ +#define DMA_FLAG_HT6 (0x00400000U) /*!< Channel 6 half transfer flag */ +#define DMA_FLAG_TE6 (0x00800000U) /*!< Channel 6 transfer error flag */ +#define DMA_FLAG_GL7 (0x01000000U) /*!< Channel 7 global interrupt flag */ +#define DMA_FLAG_TC7 (0x02000000U) /*!< Channel 7 transfer complete flag */ +#define DMA_FLAG_HT7 (0x04000000U) /*!< Channel 7 half transfer flag */ +#define DMA_FLAG_TE7 (0x08000000U) /*!< Channel 7 transfer error flag */ + +/** + * @} + */ + +#if defined(SYSCFG_CFGR1_DMA_RMP) +/** @defgroup HAL_DMA_remapping HAL DMA remapping + * Elements values convention: 0xYYYYYYYY + * - YYYYYYYY : Position in the SYSCFG register CFGR1 + * @{ + */ +#define DMA_REMAP_ADC_DMA_CH2 ((uint32_t)SYSCFG_CFGR1_ADC_DMA_RMP) /*!< ADC DMA remap + 0: No remap (ADC DMA requests mapped on DMA channel 1 + 1: Remap (ADC DMA requests mapped on DMA channel 2 */ +#define DMA_REMAP_USART1_TX_DMA_CH4 ((uint32_t)SYSCFG_CFGR1_USART1TX_DMA_RMP) /*!< USART1 TX DMA remap + 0: No remap (USART1_TX DMA request mapped on DMA channel 2 + 1: Remap (USART1_TX DMA request mapped on DMA channel 4 */ +#define DMA_REMAP_USART1_RX_DMA_CH5 ((uint32_t)SYSCFG_CFGR1_USART1RX_DMA_RMP) /*!< USART1 RX DMA remap + 0: No remap (USART1_RX DMA request mapped on DMA channel 3 + 1: Remap (USART1_RX DMA request mapped on DMA channel 5 */ +#define DMA_REMAP_TIM16_DMA_CH4 ((uint32_t)SYSCFG_CFGR1_TIM16_DMA_RMP) /*!< TIM16 DMA request remap + 0: No remap (TIM16_CH1 and TIM16_UP DMA requests mapped on DMA channel 3) + 1: Remap (TIM16_CH1 and TIM16_UP DMA requests mapped on DMA channel 4) */ +#define DMA_REMAP_TIM17_DMA_CH2 ((uint32_t)SYSCFG_CFGR1_TIM17_DMA_RMP) /*!< TIM17 DMA request remap + 0: No remap (TIM17_CH1 and TIM17_UP DMA requests mapped on DMA channel 1 + 1: Remap (TIM17_CH1 and TIM17_UP DMA requests mapped on DMA channel 2) */ +#if defined (STM32F070xB) +#define DMA_REMAP_USART3_DMA_CH32 ((uint32_t)SYSCFG_CFGR1_USART3_DMA_RMP) /*!< USART3 DMA request remapping bit. Available on STM32F070xB devices only. + 0: Disabled, need to remap before use + 1: Remap (USART3_RX and USART3_TX DMA requests mapped on DMA channel 3 and 2 respectively) */ + +#endif + +#if defined (STM32F071xB) || defined (STM32F072xB) || defined (STM32F078xx) +#define DMA_REMAP_TIM16_DMA_CH6 ((uint32_t)SYSCFG_CFGR1_TIM16_DMA_RMP2) /*!< TIM16 alternate DMA request remapping bit. Available on STM32F07x devices only + 0: No alternate remap (TIM16 DMA requestsmapped according to TIM16_DMA_RMP bit) + 1: Alternate remap (TIM16_CH1 and TIM16_UP DMA requests mapped on DMA channel 6) */ +#define DMA_REMAP_TIM17_DMA_CH7 ((uint32_t)SYSCFG_CFGR1_TIM17_DMA_RMP2) /*!< TIM17 alternate DMA request remapping bit. Available on STM32F07x devices only + 0: No alternate remap (TIM17 DMA requestsmapped according to TIM17_DMA_RMP bit) + 1: Alternate remap (TIM17_CH1 and TIM17_UP DMA requests mapped on DMA channel 7) */ +#define DMA_REMAP_SPI2_DMA_CH67 ((uint32_t)SYSCFG_CFGR1_SPI2_DMA_RMP) /*!< SPI2 DMA request remapping bit. Available on STM32F07x devices only. + 0: No remap (SPI2_RX and SPI2_TX DMA requests mapped on DMA channel 4 and 5 respectively) + 1: Remap (SPI2_RX and SPI2_TX DMA requests mapped on DMA channel 6 and 7 respectively) */ +#define DMA_REMAP_USART2_DMA_CH67 ((uint32_t)SYSCFG_CFGR1_USART2_DMA_RMP) /*!< USART2 DMA request remapping bit. Available on STM32F07x devices only. + 0: No remap (USART2_RX and USART2_TX DMA requests mapped on DMA channel 5 and 4 respectively) + 1: 1: Remap (USART2_RX and USART2_TX DMA requests mapped on DMA channel 6 and 7 respectively) */ +#define DMA_REMAP_USART3_DMA_CH32 ((uint32_t)SYSCFG_CFGR1_USART3_DMA_RMP) /*!< USART3 DMA request remapping bit. Available on STM32F07x devices only. + 0: No remap (USART3_RX and USART3_TX DMA requests mapped on DMA channel 6 and 7 respectively) + 1: Remap (USART3_RX and USART3_TX DMA requests mapped on DMA channel 3 and 2 respectively) */ +#define DMA_REMAP_I2C1_DMA_CH76 ((uint32_t)SYSCFG_CFGR1_I2C1_DMA_RMP) /*!< I2C1 DMA request remapping bit. Available on STM32F07x devices only. + 0: No remap (I2C1_RX and I2C1_TX DMA requests mapped on DMA channel 3 and 2 respectively) + 1: Remap (I2C1_RX and I2C1_TX DMA requests mapped on DMA channel 7 and 6 respectively) */ +#define DMA_REMAP_TIM1_DMA_CH6 ((uint32_t)SYSCFG_CFGR1_TIM1_DMA_RMP) /*!< TIM1 DMA request remapping bit. Available on STM32F07x devices only. + 0: No remap (TIM1_CH1, TIM1_CH2 and TIM1_CH3 DMA requests mapped on DMA channel 2, 3 and 4 respectively) + 1: Remap (TIM1_CH1, TIM1_CH2 and TIM1_CH3 DMA requests mapped on DMA channel 6 */ +#define DMA_REMAP_TIM2_DMA_CH7 ((uint32_t)SYSCFG_CFGR1_TIM2_DMA_RMP) /*!< TIM2 DMA request remapping bit. Available on STM32F07x devices only. + 0: No remap (TIM2_CH2 and TIM2_CH4 DMA requests mapped on DMA channel 3 and 4 respectively) + 1: Remap (TIM2_CH2 and TIM2_CH4 DMA requests mapped on DMA channel 7 */ +#define DMA_REMAP_TIM3_DMA_CH6 ((uint32_t)SYSCFG_CFGR1_TIM3_DMA_RMP) /*!< TIM3 DMA request remapping bit. Available on STM32F07x devices only. + 0: No remap (TIM3_CH1 and TIM3_TRIG DMA requests mapped on DMA channel 4) + 1: Remap (TIM3_CH1 and TIM3_TRIG DMA requests mapped on DMA channel 6) */ +#endif + +/** + * @} + */ + +#endif /* SYSCFG_CFGR1_DMA_RMP */ +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup DMA_Exported_Macros DMA Exported Macros + * @{ + */ + +/** @brief Reset DMA handle state + * @param __HANDLE__ DMA handle. + * @retval None + */ +#define __HAL_DMA_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_DMA_STATE_RESET) + +/** + * @brief Enable the specified DMA Channel. + * @param __HANDLE__ DMA handle + * @retval None + */ +#define __HAL_DMA_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->CCR |= DMA_CCR_EN) + +/** + * @brief Disable the specified DMA Channel. + * @param __HANDLE__ DMA handle + * @retval None + */ +#define __HAL_DMA_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->CCR &= ~DMA_CCR_EN) + + +/* Interrupt & Flag management */ + +/** + * @brief Enables the specified DMA Channel interrupts. + * @param __HANDLE__ DMA handle + * @param __INTERRUPT__ specifies the DMA interrupt sources to be enabled or disabled. + * This parameter can be any combination of the following values: + * @arg DMA_IT_TC: Transfer complete interrupt mask + * @arg DMA_IT_HT: Half transfer complete interrupt mask + * @arg DMA_IT_TE: Transfer error interrupt mask + * @retval None + */ +#define __HAL_DMA_ENABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->CCR |= (__INTERRUPT__)) + +/** + * @brief Disables the specified DMA Channel interrupts. + * @param __HANDLE__ DMA handle + * @param __INTERRUPT__ specifies the DMA interrupt sources to be enabled or disabled. + * This parameter can be any combination of the following values: + * @arg DMA_IT_TC: Transfer complete interrupt mask + * @arg DMA_IT_HT: Half transfer complete interrupt mask + * @arg DMA_IT_TE: Transfer error interrupt mask + * @retval None + */ +#define __HAL_DMA_DISABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->CCR &= ~(__INTERRUPT__)) + +/** + * @brief Checks whether the specified DMA Channel interrupt is enabled or disabled. + * @param __HANDLE__ DMA handle + * @param __INTERRUPT__ specifies the DMA interrupt source to check. + * This parameter can be one of the following values: + * @arg DMA_IT_TC: Transfer complete interrupt mask + * @arg DMA_IT_HT: Half transfer complete interrupt mask + * @arg DMA_IT_TE: Transfer error interrupt mask + * @retval The state of DMA_IT (SET or RESET). + */ +#define __HAL_DMA_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) (((__HANDLE__)->Instance->CCR & (__INTERRUPT__))) + +/** + * @brief Returns the number of remaining data units in the current DMAy Channelx transfer. + * @param __HANDLE__ DMA handle + * + * @retval The number of remaining data units in the current DMA Channel transfer. + */ +#define __HAL_DMA_GET_COUNTER(__HANDLE__) ((__HANDLE__)->Instance->CNDTR) + +#if defined(SYSCFG_CFGR1_DMA_RMP) +/** @brief DMA remapping enable/disable macros + * @param __DMA_REMAP__ This parameter can be a value of @ref HAL_DMA_remapping + */ +#define __HAL_DMA_REMAP_CHANNEL_ENABLE(__DMA_REMAP__) do {assert_param(IS_DMA_REMAP((__DMA_REMAP__))); \ + SYSCFG->CFGR1 |= (__DMA_REMAP__); \ + }while(0) +#define __HAL_DMA_REMAP_CHANNEL_DISABLE(__DMA_REMAP__) do {assert_param(IS_DMA_REMAP((__DMA_REMAP__))); \ + SYSCFG->CFGR1 &= ~(__DMA_REMAP__); \ + }while(0) +#endif /* SYSCFG_CFGR1_DMA_RMP */ + +/** + * @} + */ + +/* Include DMA HAL Extension module */ +#include "stm32f0xx_hal_dma_ex.h" + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup DMA_Exported_Functions + * @{ + */ + +/** @addtogroup DMA_Exported_Functions_Group1 + * @{ + */ +/* Initialization and de-initialization functions *****************************/ +HAL_StatusTypeDef HAL_DMA_Init(DMA_HandleTypeDef *hdma); +HAL_StatusTypeDef HAL_DMA_DeInit (DMA_HandleTypeDef *hdma); +/** + * @} + */ + +/** @addtogroup DMA_Exported_Functions_Group2 + * @{ + */ +/* Input and Output operation functions *****************************************************/ +HAL_StatusTypeDef HAL_DMA_Start (DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength); +HAL_StatusTypeDef HAL_DMA_Start_IT(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength); +HAL_StatusTypeDef HAL_DMA_Abort(DMA_HandleTypeDef *hdma); +HAL_StatusTypeDef HAL_DMA_Abort_IT(DMA_HandleTypeDef *hdma); +HAL_StatusTypeDef HAL_DMA_PollForTransfer(DMA_HandleTypeDef *hdma, uint32_t CompleteLevel, uint32_t Timeout); +void HAL_DMA_IRQHandler(DMA_HandleTypeDef *hdma); +HAL_StatusTypeDef HAL_DMA_RegisterCallback(DMA_HandleTypeDef *hdma, HAL_DMA_CallbackIDTypeDef CallbackID, void (* pCallback)( DMA_HandleTypeDef * _hdma)); +HAL_StatusTypeDef HAL_DMA_UnRegisterCallback(DMA_HandleTypeDef *hdma, HAL_DMA_CallbackIDTypeDef CallbackID); + +/** + * @} + */ + +/** @addtogroup DMA_Exported_Functions_Group3 + * @{ + */ +/* Peripheral State and Error functions ***************************************/ +HAL_DMA_StateTypeDef HAL_DMA_GetState(DMA_HandleTypeDef *hdma); +uint32_t HAL_DMA_GetError(DMA_HandleTypeDef *hdma); +/** + * @} + */ + +/** + * @} + */ + +/** @addtogroup DMA_Private_Macros + * @{ + */ +#define IS_DMA_DIRECTION(DIRECTION) (((DIRECTION) == DMA_PERIPH_TO_MEMORY ) || \ + ((DIRECTION) == DMA_MEMORY_TO_PERIPH) || \ + ((DIRECTION) == DMA_MEMORY_TO_MEMORY)) +#define IS_DMA_PERIPHERAL_INC_STATE(STATE) (((STATE) == DMA_PINC_ENABLE) || \ + ((STATE) == DMA_PINC_DISABLE)) + +#define IS_DMA_MEMORY_INC_STATE(STATE) (((STATE) == DMA_MINC_ENABLE) || \ + ((STATE) == DMA_MINC_DISABLE)) + +#define IS_DMA_PERIPHERAL_DATA_SIZE(SIZE) (((SIZE) == DMA_PDATAALIGN_BYTE) || \ + ((SIZE) == DMA_PDATAALIGN_HALFWORD) || \ + ((SIZE) == DMA_PDATAALIGN_WORD)) + +#define IS_DMA_MEMORY_DATA_SIZE(SIZE) (((SIZE) == DMA_MDATAALIGN_BYTE) || \ + ((SIZE) == DMA_MDATAALIGN_HALFWORD) || \ + ((SIZE) == DMA_MDATAALIGN_WORD )) + +#define IS_DMA_MODE(MODE) (((MODE) == DMA_NORMAL ) || \ + ((MODE) == DMA_CIRCULAR)) +#define IS_DMA_PRIORITY(PRIORITY) (((PRIORITY) == DMA_PRIORITY_LOW ) || \ + ((PRIORITY) == DMA_PRIORITY_MEDIUM) || \ + ((PRIORITY) == DMA_PRIORITY_HIGH) || \ + ((PRIORITY) == DMA_PRIORITY_VERY_HIGH)) +#define IS_DMA_BUFFER_SIZE(SIZE) (((SIZE) >= 0x1U) && ((SIZE) < 0x10000U)) + +#if defined(SYSCFG_CFGR1_DMA_RMP) + +#if defined (STM32F071xB) || defined (STM32F072xB) || defined (STM32F078xx) +#define IS_DMA_REMAP(RMP) (((RMP) == DMA_REMAP_ADC_DMA_CH2) || \ + ((RMP) == DMA_REMAP_USART1_TX_DMA_CH4) || \ + ((RMP) == DMA_REMAP_USART1_RX_DMA_CH5) || \ + ((RMP) == DMA_REMAP_TIM16_DMA_CH4) || \ + ((RMP) == DMA_REMAP_TIM17_DMA_CH2) || \ + ((RMP) == DMA_REMAP_TIM16_DMA_CH6) || \ + ((RMP) == DMA_REMAP_TIM17_DMA_CH7) || \ + ((RMP) == DMA_REMAP_SPI2_DMA_CH67) || \ + ((RMP) == DMA_REMAP_USART2_DMA_CH67) || \ + ((RMP) == DMA_REMAP_USART3_DMA_CH32) || \ + ((RMP) == DMA_REMAP_I2C1_DMA_CH76) || \ + ((RMP) == DMA_REMAP_TIM1_DMA_CH6) || \ + ((RMP) == DMA_REMAP_TIM2_DMA_CH7) || \ + ((RMP) == DMA_REMAP_TIM3_DMA_CH6)) +#elif defined (STM32F070xB) +#define IS_DMA_REMAP(RMP) (((RMP) == DMA_REMAP_USART3_DMA_CH32) || \ + ((RMP) == DMA_REMAP_ADC_DMA_CH2) || \ + ((RMP) == DMA_REMAP_USART1_TX_DMA_CH4) || \ + ((RMP) == DMA_REMAP_USART1_RX_DMA_CH5) || \ + ((RMP) == DMA_REMAP_TIM16_DMA_CH4) || \ + ((RMP) == DMA_REMAP_TIM17_DMA_CH2)) +#else +#define IS_DMA_REMAP(RMP) (((RMP) == DMA_REMAP_ADC_DMA_CH2) || \ + ((RMP) == DMA_REMAP_USART1_TX_DMA_CH4) || \ + ((RMP) == DMA_REMAP_USART1_RX_DMA_CH5) || \ + ((RMP) == DMA_REMAP_TIM16_DMA_CH4) || \ + ((RMP) == DMA_REMAP_TIM17_DMA_CH2)) +#endif + +#endif /* SYSCFG_CFGR1_DMA_RMP */ + + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F0xx_HAL_DMA_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ + diff --git a/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma_ex.h b/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma_ex.h new file mode 100644 index 0000000..185f833 --- /dev/null +++ b/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma_ex.h @@ -0,0 +1,811 @@ +/** + ****************************************************************************** + * @file stm32f0xx_hal_dma_ex.h + * @author MCD Application Team + * @brief Header file of DMA HAL Extension module. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2016 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F0xx_HAL_DMA_EX_H +#define __STM32F0xx_HAL_DMA_EX_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f0xx_hal_def.h" + +/** @addtogroup STM32F0xx_HAL_Driver + * @{ + */ + +/** @defgroup DMAEx DMAEx + * @brief DMA HAL module driver + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ +#if defined(STM32F091xC) || defined(STM32F098xx) || defined(STM32F030xC) +/** @defgroup DMAEx_Exported_Constants DMAEx Exported Constants + * @{ + */ +#define DMA1_CHANNEL1_RMP 0x00000000 /*!< Internal define for remaping on STM32F09x/30xC */ +#define DMA1_CHANNEL2_RMP 0x10000000 /*!< Internal define for remaping on STM32F09x/30xC */ +#define DMA1_CHANNEL3_RMP 0x20000000 /*!< Internal define for remaping on STM32F09x/30xC */ +#define DMA1_CHANNEL4_RMP 0x30000000 /*!< Internal define for remaping on STM32F09x/30xC */ +#define DMA1_CHANNEL5_RMP 0x40000000 /*!< Internal define for remaping on STM32F09x/30xC */ +#if !defined(STM32F030xC) +#define DMA1_CHANNEL6_RMP 0x50000000 /*!< Internal define for remaping on STM32F09x/30xC */ +#define DMA1_CHANNEL7_RMP 0x60000000 /*!< Internal define for remaping on STM32F09x/30xC */ +#define DMA2_CHANNEL1_RMP 0x00000000 /*!< Internal define for remaping on STM32F09x/30xC */ +#define DMA2_CHANNEL2_RMP 0x10000000 /*!< Internal define for remaping on STM32F09x/30xC */ +#define DMA2_CHANNEL3_RMP 0x20000000 /*!< Internal define for remaping on STM32F09x/30xC */ +#define DMA2_CHANNEL4_RMP 0x30000000 /*!< Internal define for remaping on STM32F09x/30xC */ +#define DMA2_CHANNEL5_RMP 0x40000000 /*!< Internal define for remaping on STM32F09x/30xC */ +#endif /* !defined(STM32F030xC) */ + +/****************** DMA1 remap bit field definition********************/ +/* DMA1 - Channel 1 */ +#define HAL_DMA1_CH1_DEFAULT (uint32_t) (DMA1_CHANNEL1_RMP | DMA1_CSELR_DEFAULT) /*!< Default remap position for DMA1 */ +#define HAL_DMA1_CH1_ADC (uint32_t) (DMA1_CHANNEL1_RMP | DMA1_CSELR_CH1_ADC) /*!< Remap ADC on DMA1 Channel 1*/ +#define HAL_DMA1_CH1_TIM17_CH1 (uint32_t) (DMA1_CHANNEL1_RMP | DMA1_CSELR_CH1_TIM17_CH1) /*!< Remap TIM17 channel 1 on DMA1 channel 1 */ +#define HAL_DMA1_CH1_TIM17_UP (uint32_t) (DMA1_CHANNEL1_RMP | DMA1_CSELR_CH1_TIM17_UP) /*!< Remap TIM17 up on DMA1 channel 1 */ +#define HAL_DMA1_CH1_USART1_RX (uint32_t) (DMA1_CHANNEL1_RMP | DMA1_CSELR_CH1_USART1_RX) /*!< Remap USART1 Rx on DMA1 channel 1 */ +#define HAL_DMA1_CH1_USART2_RX (uint32_t) (DMA1_CHANNEL1_RMP | DMA1_CSELR_CH1_USART2_RX) /*!< Remap USART2 Rx on DMA1 channel 1 */ +#define HAL_DMA1_CH1_USART3_RX (uint32_t) (DMA1_CHANNEL1_RMP | DMA1_CSELR_CH1_USART3_RX) /*!< Remap USART3 Rx on DMA1 channel 1 */ +#define HAL_DMA1_CH1_USART4_RX (uint32_t) (DMA1_CHANNEL1_RMP | DMA1_CSELR_CH1_USART4_RX) /*!< Remap USART4 Rx on DMA1 channel 1 */ +#define HAL_DMA1_CH1_USART5_RX (uint32_t) (DMA1_CHANNEL1_RMP | DMA1_CSELR_CH1_USART5_RX) /*!< Remap USART5 Rx on DMA1 channel 1 */ +#define HAL_DMA1_CH1_USART6_RX (uint32_t) (DMA1_CHANNEL1_RMP | DMA1_CSELR_CH1_USART6_RX) /*!< Remap USART6 Rx on DMA1 channel 1 */ +#if !defined(STM32F030xC) +#define HAL_DMA1_CH1_USART7_RX (uint32_t) (DMA1_CHANNEL1_RMP | DMA1_CSELR_CH1_USART7_RX) /*!< Remap USART7 Rx on DMA1 channel 1 */ +#define HAL_DMA1_CH1_USART8_RX (uint32_t) (DMA1_CHANNEL1_RMP | DMA1_CSELR_CH1_USART8_RX) /*!< Remap USART8 Rx on DMA1 channel 1 */ +#endif /* !defined(STM32F030xC) */ + +/* DMA1 - Channel 2 */ +#define HAL_DMA1_CH2_DEFAULT (uint32_t) (DMA1_CHANNEL2_RMP | DMA1_CSELR_DEFAULT) /*!< Default remap position for DMA1 */ +#define HAL_DMA1_CH2_ADC (uint32_t) (DMA1_CHANNEL2_RMP | DMA1_CSELR_CH2_ADC) /*!< Remap ADC on DMA1 channel 2 */ +#define HAL_DMA1_CH2_I2C1_TX (uint32_t) (DMA1_CHANNEL2_RMP | DMA1_CSELR_CH2_I2C1_TX) /*!< Remap I2C1 Tx on DMA1 channel 2 */ +#define HAL_DMA1_CH2_SPI1_RX (uint32_t) (DMA1_CHANNEL2_RMP | DMA1_CSELR_CH2_SPI1_RX) /*!< Remap SPI1 Rx on DMA1 channel 2 */ +#define HAL_DMA1_CH2_TIM1_CH1 (uint32_t) (DMA1_CHANNEL2_RMP | DMA1_CSELR_CH2_TIM1_CH1) /*!< Remap TIM1 channel 1 on DMA1 channel 2 */ +#define HAL_DMA1_CH2_TIM17_CH1 (uint32_t) (DMA1_CHANNEL2_RMP | DMA1_CSELR_CH2_TIM17_CH1) /*!< Remap TIM17 channel 1 on DMA1 channel 2 */ +#define HAL_DMA1_CH2_TIM17_UP (uint32_t) (DMA1_CHANNEL2_RMP | DMA1_CSELR_CH2_TIM17_UP) /*!< Remap TIM17 up on DMA1 channel 2 */ +#define HAL_DMA1_CH2_USART1_TX (uint32_t) (DMA1_CHANNEL2_RMP | DMA1_CSELR_CH2_USART1_TX) /*!< Remap USART1 Tx on DMA1 channel 2 */ +#define HAL_DMA1_CH2_USART2_TX (uint32_t) (DMA1_CHANNEL2_RMP | DMA1_CSELR_CH2_USART2_TX) /*!< Remap USART2 Tx on DMA1 channel 2 */ +#define HAL_DMA1_CH2_USART3_TX (uint32_t) (DMA1_CHANNEL2_RMP | DMA1_CSELR_CH2_USART3_TX) /*!< Remap USART3 Tx on DMA1 channel 2 */ +#define HAL_DMA1_CH2_USART4_TX (uint32_t) (DMA1_CHANNEL2_RMP | DMA1_CSELR_CH2_USART4_TX) /*!< Remap USART4 Tx on DMA1 channel 2 */ +#define HAL_DMA1_CH2_USART5_TX (uint32_t) (DMA1_CHANNEL2_RMP | DMA1_CSELR_CH2_USART5_TX) /*!< Remap USART5 Tx on DMA1 channel 2 */ +#define HAL_DMA1_CH2_USART6_TX (uint32_t) (DMA1_CHANNEL2_RMP | DMA1_CSELR_CH2_USART6_TX) /*!< Remap USART6 Tx on DMA1 channel 2 */ +#if !defined(STM32F030xC) +#define HAL_DMA1_CH2_USART7_TX (uint32_t) (DMA1_CHANNEL2_RMP | DMA1_CSELR_CH2_USART7_TX) /*!< Remap USART7 Tx on DMA1 channel 2 */ +#define HAL_DMA1_CH2_USART8_TX (uint32_t) (DMA1_CHANNEL2_RMP | DMA1_CSELR_CH2_USART8_TX) /*!< Remap USART8 Tx on DMA1 channel 2 */ +#endif /* !defined(STM32F030xC) */ + +/* DMA1 - Channel 3 */ +#define HAL_DMA1_CH3_DEFAULT (uint32_t) (DMA1_CHANNEL3_RMP | DMA1_CSELR_DEFAULT) /*!< Default remap position for DMA1 */ +#define HAL_DMA1_CH3_TIM6_UP (uint32_t) (DMA1_CHANNEL3_RMP | DMA1_CSELR_CH3_TIM6_UP) /*!< Remap TIM6 up on DMA1 channel 3 */ +#if !defined(STM32F030xC) +#define HAL_DMA1_CH3_DAC_CH1 (uint32_t) (DMA1_CHANNEL3_RMP | DMA1_CSELR_CH3_DAC_CH1) /*!< Remap DAC Channel 1on DMA1 channel 3 */ +#endif /* !defined(STM32F030xC) */ +#define HAL_DMA1_CH3_I2C1_RX (uint32_t) (DMA1_CHANNEL3_RMP | DMA1_CSELR_CH3_I2C1_RX) /*!< Remap I2C1 Rx on DMA1 channel 3 */ +#define HAL_DMA1_CH3_SPI1_TX (uint32_t) (DMA1_CHANNEL3_RMP | DMA1_CSELR_CH3_SPI1_TX) /*!< Remap SPI1 Tx on DMA1 channel 3 */ +#define HAL_DMA1_CH3_TIM1_CH2 (uint32_t) (DMA1_CHANNEL3_RMP | DMA1_CSELR_CH3_TIM1_CH2) /*!< Remap TIM1 channel 2 on DMA1 channel 3 */ +#if !defined(STM32F030xC) +#define HAL_DMA1_CH3_TIM2_CH2 (uint32_t) (DMA1_CHANNEL3_RMP | DMA1_CSELR_CH3_TIM2_CH2) /*!< Remap TIM2 channel 2 on DMA1 channel 3 */ +#endif /* !defined(STM32F030xC) */ +#define HAL_DMA1_CH3_TIM16_CH1 (uint32_t) (DMA1_CHANNEL3_RMP | DMA1_CSELR_CH3_TIM16_CH1) /*!< Remap TIM16 channel 1 on DMA1 channel 3 */ +#define HAL_DMA1_CH3_TIM16_UP (uint32_t) (DMA1_CHANNEL3_RMP | DMA1_CSELR_CH3_TIM16_UP) /*!< Remap TIM16 up on DMA1 channel 3 */ +#define HAL_DMA1_CH3_USART1_RX (uint32_t) (DMA1_CHANNEL3_RMP | DMA1_CSELR_CH3_USART1_RX) /*!< Remap USART1 Rx on DMA1 channel 3 */ +#define HAL_DMA1_CH3_USART2_RX (uint32_t) (DMA1_CHANNEL3_RMP | DMA1_CSELR_CH3_USART2_RX) /*!< Remap USART2 Rx on DMA1 channel 3 */ +#define HAL_DMA1_CH3_USART3_RX (uint32_t) (DMA1_CHANNEL3_RMP | DMA1_CSELR_CH3_USART3_RX) /*!< Remap USART3 Rx on DMA1 channel 3 */ +#define HAL_DMA1_CH3_USART4_RX (uint32_t) (DMA1_CHANNEL3_RMP | DMA1_CSELR_CH3_USART4_RX) /*!< Remap USART4 Rx on DMA1 channel 3 */ +#define HAL_DMA1_CH3_USART5_RX (uint32_t) (DMA1_CHANNEL3_RMP | DMA1_CSELR_CH3_USART5_RX) /*!< Remap USART5 Rx on DMA1 channel 3 */ +#define HAL_DMA1_CH3_USART6_RX (uint32_t) (DMA1_CHANNEL3_RMP | DMA1_CSELR_CH3_USART6_RX) /*!< Remap USART6 Rx on DMA1 channel 3 */ +#if !defined(STM32F030xC) +#define HAL_DMA1_CH3_USART7_RX (uint32_t) (DMA1_CHANNEL3_RMP | DMA1_CSELR_CH3_USART7_RX) /*!< Remap USART7 Rx on DMA1 channel 3 */ +#define HAL_DMA1_CH3_USART8_RX (uint32_t) (DMA1_CHANNEL3_RMP | DMA1_CSELR_CH3_USART8_RX) /*!< Remap USART8 Rx on DMA1 channel 3 */ +#endif /* !defined(STM32F030xC) */ + +/* DMA1 - Channel 4 */ +#define HAL_DMA1_CH4_DEFAULT (uint32_t) (DMA1_CHANNEL4_RMP | DMA1_CSELR_DEFAULT) /*!< Default remap position for DMA1 */ +#define HAL_DMA1_CH4_TIM7_UP (uint32_t) (DMA1_CHANNEL4_RMP | DMA1_CSELR_CH4_TIM7_UP) /*!< Remap TIM7 up on DMA1 channel 4 */ +#if !defined(STM32F030xC) +#define HAL_DMA1_CH4_DAC_CH2 (uint32_t) (DMA1_CHANNEL4_RMP | DMA1_CSELR_CH4_DAC_CH2) /*!< Remap DAC Channel 2 on DMA1 channel 4 */ +#endif /* !defined(STM32F030xC) */ +#define HAL_DMA1_CH4_I2C2_TX (uint32_t) (DMA1_CHANNEL4_RMP | DMA1_CSELR_CH4_I2C2_TX) /*!< Remap I2C2 Tx on DMA1 channel 4 */ +#define HAL_DMA1_CH4_SPI2_RX (uint32_t) (DMA1_CHANNEL4_RMP | DMA1_CSELR_CH4_SPI2_RX) /*!< Remap SPI2 Rx on DMA1 channel 4 */ +#if !defined(STM32F030xC) +#define HAL_DMA1_CH4_TIM2_CH4 (uint32_t) (DMA1_CHANNEL4_RMP | DMA1_CSELR_CH4_TIM2_CH4) /*!< Remap TIM2 channel 4 on DMA1 channel 4 */ +#endif /* !defined(STM32F030xC) */ +#define HAL_DMA1_CH4_TIM3_CH1 (uint32_t) (DMA1_CHANNEL4_RMP | DMA1_CSELR_CH4_TIM3_CH1) /*!< Remap TIM3 channel 1 on DMA1 channel 4 */ +#define HAL_DMA1_CH4_TIM3_TRIG (uint32_t) (DMA1_CHANNEL4_RMP | DMA1_CSELR_CH4_TIM3_TRIG) /*!< Remap TIM3 Trig on DMA1 channel 4 */ +#define HAL_DMA1_CH4_TIM16_CH1 (uint32_t) (DMA1_CHANNEL4_RMP | DMA1_CSELR_CH4_TIM16_CH1) /*!< Remap TIM16 channel 1 on DMA1 channel 4 */ +#define HAL_DMA1_CH4_TIM16_UP (uint32_t) (DMA1_CHANNEL4_RMP | DMA1_CSELR_CH4_TIM16_UP) /*!< Remap TIM16 up on DMA1 channel 4 */ +#define HAL_DMA1_CH4_USART1_TX (uint32_t) (DMA1_CHANNEL4_RMP | DMA1_CSELR_CH4_USART1_TX) /*!< Remap USART1 Tx on DMA1 channel 4 */ +#define HAL_DMA1_CH4_USART2_TX (uint32_t) (DMA1_CHANNEL4_RMP | DMA1_CSELR_CH4_USART2_TX) /*!< Remap USART2 Tx on DMA1 channel 4 */ +#define HAL_DMA1_CH4_USART3_TX (uint32_t) (DMA1_CHANNEL4_RMP | DMA1_CSELR_CH4_USART3_TX) /*!< Remap USART3 Tx on DMA1 channel 4 */ +#define HAL_DMA1_CH4_USART4_TX (uint32_t) (DMA1_CHANNEL4_RMP | DMA1_CSELR_CH4_USART4_TX) /*!< Remap USART4 Tx on DMA1 channel 4 */ +#define HAL_DMA1_CH4_USART5_TX (uint32_t) (DMA1_CHANNEL4_RMP | DMA1_CSELR_CH4_USART5_TX) /*!< Remap USART5 Tx on DMA1 channel 4 */ +#define HAL_DMA1_CH4_USART6_TX (uint32_t) (DMA1_CHANNEL4_RMP | DMA1_CSELR_CH4_USART6_TX) /*!< Remap USART6 Tx on DMA1 channel 4 */ +#if !defined(STM32F030xC) +#define HAL_DMA1_CH4_USART7_TX (uint32_t) (DMA1_CHANNEL4_RMP | DMA1_CSELR_CH4_USART7_TX) /*!< Remap USART7 Tx on DMA1 channel 4 */ +#define HAL_DMA1_CH4_USART8_TX (uint32_t) (DMA1_CHANNEL4_RMP | DMA1_CSELR_CH4_USART8_TX) /*!< Remap USART8 Tx on DMA1 channel 4 */ +#endif /* !defined(STM32F030xC) */ + +/* DMA1 - Channel 5 */ +#define HAL_DMA1_CH5_DEFAULT (uint32_t) (DMA1_CHANNEL5_RMP | DMA1_CSELR_DEFAULT) /*!< Default remap position for DMA1 */ +#define HAL_DMA1_CH5_I2C2_RX (uint32_t) (DMA1_CHANNEL5_RMP | DMA1_CSELR_CH5_I2C2_RX) /*!< Remap I2C2 Rx on DMA1 channel 5 */ +#define HAL_DMA1_CH5_SPI2_TX (uint32_t) (DMA1_CHANNEL5_RMP | DMA1_CSELR_CH5_SPI2_TX) /*!< Remap SPI1 Tx on DMA1 channel 5 */ +#define HAL_DMA1_CH5_TIM1_CH3 (uint32_t) (DMA1_CHANNEL5_RMP | DMA1_CSELR_CH5_TIM1_CH3) /*!< Remap TIM1 channel 3 on DMA1 channel 5 */ +#define HAL_DMA1_CH5_USART1_RX (uint32_t) (DMA1_CHANNEL5_RMP | DMA1_CSELR_CH5_USART1_RX) /*!< Remap USART1 Rx on DMA1 channel 5 */ +#define HAL_DMA1_CH5_USART2_RX (uint32_t) (DMA1_CHANNEL5_RMP | DMA1_CSELR_CH5_USART2_RX) /*!< Remap USART2 Rx on DMA1 channel 5 */ +#define HAL_DMA1_CH5_USART3_RX (uint32_t) (DMA1_CHANNEL5_RMP | DMA1_CSELR_CH5_USART3_RX) /*!< Remap USART3 Rx on DMA1 channel 5 */ +#define HAL_DMA1_CH5_USART4_RX (uint32_t) (DMA1_CHANNEL5_RMP | DMA1_CSELR_CH5_USART4_RX) /*!< Remap USART4 Rx on DMA1 channel 5 */ +#define HAL_DMA1_CH5_USART5_RX (uint32_t) (DMA1_CHANNEL5_RMP | DMA1_CSELR_CH5_USART5_RX) /*!< Remap USART5 Rx on DMA1 channel 5 */ +#define HAL_DMA1_CH5_USART6_RX (uint32_t) (DMA1_CHANNEL5_RMP | DMA1_CSELR_CH5_USART6_RX) /*!< Remap USART6 Rx on DMA1 channel 5 */ +#if !defined(STM32F030xC) +#define HAL_DMA1_CH5_USART7_RX (uint32_t) (DMA1_CHANNEL5_RMP | DMA1_CSELR_CH5_USART7_RX) /*!< Remap USART7 Rx on DMA1 channel 5 */ +#define HAL_DMA1_CH5_USART8_RX (uint32_t) (DMA1_CHANNEL5_RMP | DMA1_CSELR_CH5_USART8_RX) /*!< Remap USART8 Rx on DMA1 channel 5 */ +#endif /* !defined(STM32F030xC) */ + +#if !defined(STM32F030xC) +/* DMA1 - Channel 6 */ +#define HAL_DMA1_CH6_DEFAULT (uint32_t) (DMA1_CHANNEL6_RMP | DMA1_CSELR_DEFAULT) /*!< Default remap position for DMA1 */ +#define HAL_DMA1_CH6_I2C1_TX (uint32_t) (DMA1_CHANNEL6_RMP | DMA1_CSELR_CH6_I2C1_TX) /*!< Remap I2C1 Tx on DMA1 channel 6 */ +#define HAL_DMA1_CH6_SPI2_RX (uint32_t) (DMA1_CHANNEL6_RMP | DMA1_CSELR_CH6_SPI2_RX) /*!< Remap SPI2 Rx on DMA1 channel 6 */ +#define HAL_DMA1_CH6_TIM1_CH1 (uint32_t) (DMA1_CHANNEL6_RMP | DMA1_CSELR_CH6_TIM1_CH1) /*!< Remap TIM1 channel 1 on DMA1 channel 6 */ +#define HAL_DMA1_CH6_TIM1_CH2 (uint32_t) (DMA1_CHANNEL6_RMP | DMA1_CSELR_CH6_TIM1_CH2) /*!< Remap TIM1 channel 2 on DMA1 channel 6 */ +#define HAL_DMA1_CH6_TIM1_CH3 (uint32_t) (DMA1_CHANNEL6_RMP | DMA1_CSELR_CH6_TIM1_CH3) /*!< Remap TIM1 channel 3 on DMA1 channel 6 */ +#define HAL_DMA1_CH6_TIM3_CH1 (uint32_t) (DMA1_CHANNEL6_RMP | DMA1_CSELR_CH6_TIM3_CH1) /*!< Remap TIM3 channel 1 on DMA1 channel 6 */ +#define HAL_DMA1_CH6_TIM3_TRIG (uint32_t) (DMA1_CHANNEL6_RMP | DMA1_CSELR_CH6_TIM3_TRIG) /*!< Remap TIM3 Trig on DMA1 channel 6 */ +#define HAL_DMA1_CH6_TIM16_CH1 (uint32_t) (DMA1_CHANNEL6_RMP | DMA1_CSELR_CH6_TIM16_CH1) /*!< Remap TIM16 channel 1 on DMA1 channel 6 */ +#define HAL_DMA1_CH6_TIM16_UP (uint32_t) (DMA1_CHANNEL6_RMP | DMA1_CSELR_CH6_TIM16_UP) /*!< Remap TIM16 up on DMA1 channel 6 */ +#define HAL_DMA1_CH6_USART1_RX (uint32_t) (DMA1_CHANNEL6_RMP | DMA1_CSELR_CH6_USART1_RX) /*!< Remap USART1 Rx on DMA1 channel 6 */ +#define HAL_DMA1_CH6_USART2_RX (uint32_t) (DMA1_CHANNEL6_RMP | DMA1_CSELR_CH6_USART2_RX) /*!< Remap USART2 Rx on DMA1 channel 6 */ +#define HAL_DMA1_CH6_USART3_RX (uint32_t) (DMA1_CHANNEL6_RMP | DMA1_CSELR_CH6_USART3_RX) /*!< Remap USART3 Rx on DMA1 channel 6 */ +#define HAL_DMA1_CH6_USART4_RX (uint32_t) (DMA1_CHANNEL6_RMP | DMA1_CSELR_CH6_USART4_RX) /*!< Remap USART4 Rx on DMA1 channel 6 */ +#define HAL_DMA1_CH6_USART5_RX (uint32_t) (DMA1_CHANNEL6_RMP | DMA1_CSELR_CH6_USART5_RX) /*!< Remap USART5 Rx on DMA1 channel 6 */ +#define HAL_DMA1_CH6_USART6_RX (uint32_t) (DMA1_CHANNEL6_RMP | DMA1_CSELR_CH6_USART6_RX) /*!< Remap USART6 Rx on DMA1 channel 6 */ +#define HAL_DMA1_CH6_USART7_RX (uint32_t) (DMA1_CHANNEL6_RMP | DMA1_CSELR_CH6_USART7_RX) /*!< Remap USART7 Rx on DMA1 channel 6 */ +#define HAL_DMA1_CH6_USART8_RX (uint32_t) (DMA1_CHANNEL6_RMP | DMA1_CSELR_CH6_USART8_RX) /*!< Remap USART8 Rx on DMA1 channel 6 */ +/* DMA1 - Channel 7 */ +#define HAL_DMA1_CH7_DEFAULT (uint32_t) (DMA1_CHANNEL7_RMP | DMA1_CSELR_DEFAULT) /*!< Default remap position for DMA1 */ +#define HAL_DMA1_CH7_I2C1_RX (uint32_t) (DMA1_CHANNEL7_RMP | DMA1_CSELR_CH7_I2C1_RX) /*!< Remap I2C1 Rx on DMA1 channel 7 */ +#define HAL_DMA1_CH7_SPI2_TX (uint32_t) (DMA1_CHANNEL7_RMP | DMA1_CSELR_CH7_SPI2_TX) /*!< Remap SPI2 Tx on DMA1 channel 7 */ +#define HAL_DMA1_CH7_TIM2_CH2 (uint32_t) (DMA1_CHANNEL7_RMP | DMA1_CSELR_CH7_TIM2_CH2) /*!< Remap TIM2 channel 2 on DMA1 channel 7 */ +#define HAL_DMA1_CH7_TIM2_CH4 (uint32_t) (DMA1_CHANNEL7_RMP | DMA1_CSELR_CH7_TIM2_CH4) /*!< Remap TIM2 channel 4 on DMA1 channel 7 */ +#define HAL_DMA1_CH7_TIM17_CH1 (uint32_t) (DMA1_CHANNEL7_RMP | DMA1_CSELR_CH7_TIM17_CH1) /*!< Remap TIM17 channel 1 on DMA1 channel 7 */ +#define HAL_DMA1_CH7_TIM17_UP (uint32_t) (DMA1_CHANNEL7_RMP | DMA1_CSELR_CH7_TIM17_UP) /*!< Remap TIM17 up on DMA1 channel 7 */ +#define HAL_DMA1_CH7_USART1_TX (uint32_t) (DMA1_CHANNEL7_RMP | DMA1_CSELR_CH7_USART1_TX) /*!< Remap USART1 Tx on DMA1 channel 7 */ +#define HAL_DMA1_CH7_USART2_TX (uint32_t) (DMA1_CHANNEL7_RMP | DMA1_CSELR_CH7_USART2_TX) /*!< Remap USART2 Tx on DMA1 channel 7 */ +#define HAL_DMA1_CH7_USART3_TX (uint32_t) (DMA1_CHANNEL7_RMP | DMA1_CSELR_CH7_USART3_TX) /*!< Remap USART3 Tx on DMA1 channel 7 */ +#define HAL_DMA1_CH7_USART4_TX (uint32_t) (DMA1_CHANNEL7_RMP | DMA1_CSELR_CH7_USART4_TX) /*!< Remap USART4 Tx on DMA1 channel 7 */ +#define HAL_DMA1_CH7_USART5_TX (uint32_t) (DMA1_CHANNEL7_RMP | DMA1_CSELR_CH7_USART5_TX) /*!< Remap USART5 Tx on DMA1 channel 7 */ +#define HAL_DMA1_CH7_USART6_TX (uint32_t) (DMA1_CHANNEL7_RMP | DMA1_CSELR_CH7_USART6_TX) /*!< Remap USART6 Tx on DMA1 channel 7 */ +#define HAL_DMA1_CH7_USART7_TX (uint32_t) (DMA1_CHANNEL7_RMP | DMA1_CSELR_CH7_USART7_TX) /*!< Remap USART7 Tx on DMA1 channel 7 */ +#define HAL_DMA1_CH7_USART8_TX (uint32_t) (DMA1_CHANNEL7_RMP | DMA1_CSELR_CH7_USART8_TX) /*!< Remap USART8 Tx on DMA1 channel 7 */ + +/****************** DMA2 remap bit field definition********************/ +/* DMA2 - Channel 1 */ +#define HAL_DMA2_CH1_DEFAULT (uint32_t) (DMA2_CHANNEL1_RMP | DMA2_CSELR_DEFAULT) /*!< Default remap position for DMA2 */ +#define HAL_DMA2_CH1_I2C2_TX (uint32_t) (DMA2_CHANNEL1_RMP | DMA2_CSELR_CH1_I2C2_TX) /*!< Remap I2C2 TX on DMA2 channel 1 */ +#define HAL_DMA2_CH1_USART1_TX (uint32_t) (DMA2_CHANNEL1_RMP | DMA2_CSELR_CH1_USART1_TX) /*!< Remap USART1 Tx on DMA2 channel 1 */ +#define HAL_DMA2_CH1_USART2_TX (uint32_t) (DMA2_CHANNEL1_RMP | DMA2_CSELR_CH1_USART2_TX) /*!< Remap USART2 Tx on DMA2 channel 1 */ +#define HAL_DMA2_CH1_USART3_TX (uint32_t) (DMA2_CHANNEL1_RMP | DMA2_CSELR_CH1_USART3_TX) /*!< Remap USART3 Tx on DMA2 channel 1 */ +#define HAL_DMA2_CH1_USART4_TX (uint32_t) (DMA2_CHANNEL1_RMP | DMA2_CSELR_CH1_USART4_TX) /*!< Remap USART4 Tx on DMA2 channel 1 */ +#define HAL_DMA2_CH1_USART5_TX (uint32_t) (DMA2_CHANNEL1_RMP | DMA2_CSELR_CH1_USART5_TX) /*!< Remap USART5 Tx on DMA2 channel 1 */ +#define HAL_DMA2_CH1_USART6_TX (uint32_t) (DMA2_CHANNEL1_RMP | DMA2_CSELR_CH1_USART6_TX) /*!< Remap USART6 Tx on DMA2 channel 1 */ +#define HAL_DMA2_CH1_USART7_TX (uint32_t) (DMA2_CHANNEL1_RMP | DMA2_CSELR_CH1_USART7_TX) /*!< Remap USART7 Tx on DMA2 channel 1 */ +#define HAL_DMA2_CH1_USART8_TX (uint32_t) (DMA2_CHANNEL1_RMP | DMA2_CSELR_CH1_USART8_TX) /*!< Remap USART8 Tx on DMA2 channel 1 */ +/* DMA2 - Channel 2 */ +#define HAL_DMA2_CH2_DEFAULT (uint32_t) (DMA2_CHANNEL2_RMP | DMA2_CSELR_DEFAULT) /*!< Default remap position for DMA2 */ +#define HAL_DMA2_CH2_I2C2_RX (uint32_t) (DMA2_CHANNEL2_RMP | DMA2_CSELR_CH2_I2C2_RX) /*!< Remap I2C2 Rx on DMA2 channel 2 */ +#define HAL_DMA2_CH2_USART1_RX (uint32_t) (DMA2_CHANNEL2_RMP | DMA2_CSELR_CH2_USART1_RX) /*!< Remap USART1 Rx on DMA2 channel 2 */ +#define HAL_DMA2_CH2_USART2_RX (uint32_t) (DMA2_CHANNEL2_RMP | DMA2_CSELR_CH2_USART2_RX) /*!< Remap USART2 Rx on DMA2 channel 2 */ +#define HAL_DMA2_CH2_USART3_RX (uint32_t) (DMA2_CHANNEL2_RMP | DMA2_CSELR_CH2_USART3_RX) /*!< Remap USART3 Rx on DMA2 channel 2 */ +#define HAL_DMA2_CH2_USART4_RX (uint32_t) (DMA2_CHANNEL2_RMP | DMA2_CSELR_CH2_USART4_RX) /*!< Remap USART4 Rx on DMA2 channel 2 */ +#define HAL_DMA2_CH2_USART5_RX (uint32_t) (DMA2_CHANNEL2_RMP | DMA2_CSELR_CH2_USART5_RX) /*!< Remap USART5 Rx on DMA2 channel 2 */ +#define HAL_DMA2_CH2_USART6_RX (uint32_t) (DMA2_CHANNEL2_RMP | DMA2_CSELR_CH2_USART6_RX) /*!< Remap USART6 Rx on DMA2 channel 2 */ +#define HAL_DMA2_CH2_USART7_RX (uint32_t) (DMA2_CHANNEL2_RMP | DMA2_CSELR_CH2_USART7_RX) /*!< Remap USART7 Rx on DMA2 channel 2 */ +#define HAL_DMA2_CH2_USART8_RX (uint32_t) (DMA2_CHANNEL2_RMP | DMA2_CSELR_CH2_USART8_RX) /*!< Remap USART8 Rx on DMA2 channel 2 */ +/* DMA2 - Channel 3 */ +#define HAL_DMA2_CH3_DEFAULT (uint32_t) (DMA2_CHANNEL3_RMP | DMA2_CSELR_DEFAULT) /*!< Default remap position for DMA2 */ +#define HAL_DMA2_CH3_TIM6_UP (uint32_t) (DMA2_CHANNEL3_RMP | DMA2_CSELR_CH3_TIM6_UP) /*!< Remap TIM6 up on DMA2 channel 3 */ +#define HAL_DMA2_CH3_DAC_CH1 (uint32_t) (DMA2_CHANNEL3_RMP | DMA2_CSELR_CH3_DAC_CH1) /*!< Remap DAC channel 1 on DMA2 channel 3 */ +#define HAL_DMA2_CH3_SPI1_RX (uint32_t) (DMA2_CHANNEL3_RMP | DMA2_CSELR_CH3_SPI1_RX) /*!< Remap SPI1 Rx on DMA2 channel 3 */ +#define HAL_DMA2_CH3_USART1_RX (uint32_t) (DMA2_CHANNEL3_RMP | DMA2_CSELR_CH3_USART1_RX) /*!< Remap USART1 Rx on DMA2 channel 3 */ +#define HAL_DMA2_CH3_USART2_RX (uint32_t) (DMA2_CHANNEL3_RMP | DMA2_CSELR_CH3_USART2_RX) /*!< Remap USART2 Rx on DMA2 channel 3 */ +#define HAL_DMA2_CH3_USART3_RX (uint32_t) (DMA2_CHANNEL3_RMP | DMA2_CSELR_CH3_USART3_RX) /*!< Remap USART3 Rx on DMA2 channel 3 */ +#define HAL_DMA2_CH3_USART4_RX (uint32_t) (DMA2_CHANNEL3_RMP | DMA2_CSELR_CH3_USART4_RX) /*!< Remap USART4 Rx on DMA2 channel 3 */ +#define HAL_DMA2_CH3_USART5_RX (uint32_t) (DMA2_CHANNEL3_RMP | DMA2_CSELR_CH3_USART5_RX) /*!< Remap USART5 Rx on DMA2 channel 3 */ +#define HAL_DMA2_CH3_USART6_RX (uint32_t) (DMA2_CHANNEL3_RMP | DMA2_CSELR_CH3_USART6_RX) /*!< Remap USART6 Rx on DMA2 channel 3 */ +#define HAL_DMA2_CH3_USART7_RX (uint32_t) (DMA2_CHANNEL3_RMP | DMA2_CSELR_CH3_USART7_RX) /*!< Remap USART7 Rx on DMA2 channel 3 */ +#define HAL_DMA2_CH3_USART8_RX (uint32_t) (DMA2_CHANNEL3_RMP | DMA2_CSELR_CH3_USART8_RX) /*!< Remap USART8 Rx on DMA2 channel 3 */ +/* DMA2 - Channel 4 */ +#define HAL_DMA2_CH4_DEFAULT (uint32_t) (DMA2_CHANNEL4_RMP | DMA2_CSELR_DEFAULT) /*!< Default remap position for DMA2 */ +#define HAL_DMA2_CH4_TIM7_UP (uint32_t) (DMA2_CHANNEL4_RMP | DMA2_CSELR_CH4_TIM7_UP) /*!< Remap TIM7 up on DMA2 channel 4 */ +#define HAL_DMA2_CH4_DAC_CH2 (uint32_t) (DMA2_CHANNEL4_RMP | DMA2_CSELR_CH4_DAC_CH2) /*!< Remap DAC channel 2 on DMA2 channel 4 */ +#define HAL_DMA2_CH4_SPI1_TX (uint32_t) (DMA2_CHANNEL4_RMP | DMA2_CSELR_CH4_SPI1_TX) /*!< Remap SPI1 Tx on DMA2 channel 4 */ +#define HAL_DMA2_CH4_USART1_TX (uint32_t) (DMA2_CHANNEL4_RMP | DMA2_CSELR_CH4_USART1_TX) /*!< Remap USART1 Tx on DMA2 channel 4 */ +#define HAL_DMA2_CH4_USART2_TX (uint32_t) (DMA2_CHANNEL4_RMP | DMA2_CSELR_CH4_USART2_TX) /*!< Remap USART2 Tx on DMA2 channel 4 */ +#define HAL_DMA2_CH4_USART3_TX (uint32_t) (DMA2_CHANNEL4_RMP | DMA2_CSELR_CH4_USART3_TX) /*!< Remap USART3 Tx on DMA2 channel 4 */ +#define HAL_DMA2_CH4_USART4_TX (uint32_t) (DMA2_CHANNEL4_RMP | DMA2_CSELR_CH4_USART4_TX) /*!< Remap USART4 Tx on DMA2 channel 4 */ +#define HAL_DMA2_CH4_USART5_TX (uint32_t) (DMA2_CHANNEL4_RMP | DMA2_CSELR_CH4_USART5_TX) /*!< Remap USART5 Tx on DMA2 channel 4 */ +#define HAL_DMA2_CH4_USART6_TX (uint32_t) (DMA2_CHANNEL4_RMP | DMA2_CSELR_CH4_USART6_TX) /*!< Remap USART6 Tx on DMA2 channel 4 */ +#define HAL_DMA2_CH4_USART7_TX (uint32_t) (DMA2_CHANNEL4_RMP | DMA2_CSELR_CH4_USART7_TX) /*!< Remap USART7 Tx on DMA2 channel 4 */ +#define HAL_DMA2_CH4_USART8_TX (uint32_t) (DMA2_CHANNEL4_RMP | DMA2_CSELR_CH4_USART8_TX) /*!< Remap USART8 Tx on DMA2 channel 4 */ +/* DMA2 - Channel 5 */ +#define HAL_DMA2_CH5_DEFAULT (uint32_t) (DMA2_CHANNEL5_RMP | DMA2_CSELR_DEFAULT) /*!< Default remap position for DMA2 */ +#define HAL_DMA2_CH5_ADC (uint32_t) (DMA2_CHANNEL5_RMP | DMA2_CSELR_CH5_ADC) /*!< Remap ADC on DMA2 channel 5 */ +#define HAL_DMA2_CH5_USART1_TX (uint32_t) (DMA2_CHANNEL5_RMP | DMA2_CSELR_CH5_USART1_TX) /*!< Remap USART1 Tx on DMA2 channel 5 */ +#define HAL_DMA2_CH5_USART2_TX (uint32_t) (DMA2_CHANNEL5_RMP | DMA2_CSELR_CH5_USART2_TX) /*!< Remap USART2 Tx on DMA2 channel 5 */ +#define HAL_DMA2_CH5_USART3_TX (uint32_t) (DMA2_CHANNEL5_RMP | DMA2_CSELR_CH5_USART3_TX) /*!< Remap USART3 Tx on DMA2 channel 5 */ +#define HAL_DMA2_CH5_USART4_TX (uint32_t) (DMA2_CHANNEL5_RMP | DMA2_CSELR_CH5_USART4_TX) /*!< Remap USART4 Tx on DMA2 channel 5 */ +#define HAL_DMA2_CH5_USART5_TX (uint32_t) (DMA2_CHANNEL5_RMP | DMA2_CSELR_CH5_USART5_TX) /*!< Remap USART5 Tx on DMA2 channel 5 */ +#define HAL_DMA2_CH5_USART6_TX (uint32_t) (DMA2_CHANNEL5_RMP | DMA2_CSELR_CH5_USART6_TX) /*!< Remap USART6 Tx on DMA2 channel 5 */ +#define HAL_DMA2_CH5_USART7_TX (uint32_t) (DMA2_CHANNEL5_RMP | DMA2_CSELR_CH5_USART7_TX) /*!< Remap USART7 Tx on DMA2 channel 5 */ +#define HAL_DMA2_CH5_USART8_TX (uint32_t) (DMA2_CHANNEL5_RMP | DMA2_CSELR_CH5_USART8_TX) /*!< Remap USART8 Tx on DMA2 channel 5 */ +#endif /* !defined(STM32F030xC) */ + +#if defined(STM32F091xC) || defined(STM32F098xx) +#define IS_HAL_DMA1_REMAP(REQUEST) (((REQUEST) == HAL_DMA1_CH1_DEFAULT) ||\ + ((REQUEST) == HAL_DMA1_CH1_ADC) ||\ + ((REQUEST) == HAL_DMA1_CH1_TIM17_CH1) ||\ + ((REQUEST) == HAL_DMA1_CH1_TIM17_UP) ||\ + ((REQUEST) == HAL_DMA1_CH1_USART1_RX) ||\ + ((REQUEST) == HAL_DMA1_CH1_USART2_RX) ||\ + ((REQUEST) == HAL_DMA1_CH1_USART3_RX) ||\ + ((REQUEST) == HAL_DMA1_CH1_USART4_RX) ||\ + ((REQUEST) == HAL_DMA1_CH1_USART5_RX) ||\ + ((REQUEST) == HAL_DMA1_CH1_USART6_RX) ||\ + ((REQUEST) == HAL_DMA1_CH1_USART7_RX) ||\ + ((REQUEST) == HAL_DMA1_CH1_USART8_RX) ||\ + ((REQUEST) == HAL_DMA1_CH2_DEFAULT) ||\ + ((REQUEST) == HAL_DMA1_CH2_ADC) ||\ + ((REQUEST) == HAL_DMA1_CH2_I2C1_TX) ||\ + ((REQUEST) == HAL_DMA1_CH2_SPI1_RX) ||\ + ((REQUEST) == HAL_DMA1_CH2_TIM1_CH1) ||\ + ((REQUEST) == HAL_DMA1_CH2_I2C1_TX) ||\ + ((REQUEST) == HAL_DMA1_CH2_TIM17_CH1) ||\ + ((REQUEST) == HAL_DMA1_CH2_TIM17_UP) ||\ + ((REQUEST) == HAL_DMA1_CH2_USART1_TX) ||\ + ((REQUEST) == HAL_DMA1_CH2_USART2_TX) ||\ + ((REQUEST) == HAL_DMA1_CH2_USART3_TX) ||\ + ((REQUEST) == HAL_DMA1_CH2_USART4_TX) ||\ + ((REQUEST) == HAL_DMA1_CH2_USART5_TX) ||\ + ((REQUEST) == HAL_DMA1_CH2_USART6_TX) ||\ + ((REQUEST) == HAL_DMA1_CH2_USART7_TX) ||\ + ((REQUEST) == HAL_DMA1_CH2_USART8_TX) ||\ + ((REQUEST) == HAL_DMA1_CH3_DEFAULT) ||\ + ((REQUEST) == HAL_DMA1_CH3_TIM6_UP) ||\ + ((REQUEST) == HAL_DMA1_CH3_DAC_CH1) ||\ + ((REQUEST) == HAL_DMA1_CH3_I2C1_RX) ||\ + ((REQUEST) == HAL_DMA1_CH3_SPI1_TX) ||\ + ((REQUEST) == HAL_DMA1_CH3_TIM1_CH2) ||\ + ((REQUEST) == HAL_DMA1_CH3_TIM2_CH2) ||\ + ((REQUEST) == HAL_DMA1_CH3_TIM16_CH1) ||\ + ((REQUEST) == HAL_DMA1_CH3_TIM16_UP) ||\ + ((REQUEST) == HAL_DMA1_CH3_USART1_RX) ||\ + ((REQUEST) == HAL_DMA1_CH3_USART2_RX) ||\ + ((REQUEST) == HAL_DMA1_CH3_USART3_RX) ||\ + ((REQUEST) == HAL_DMA1_CH3_USART4_RX) ||\ + ((REQUEST) == HAL_DMA1_CH3_USART5_RX) ||\ + ((REQUEST) == HAL_DMA1_CH3_USART6_RX) ||\ + ((REQUEST) == HAL_DMA1_CH3_USART7_RX) ||\ + ((REQUEST) == HAL_DMA1_CH3_USART8_RX) ||\ + ((REQUEST) == HAL_DMA1_CH4_DEFAULT) ||\ + ((REQUEST) == HAL_DMA1_CH4_TIM7_UP) ||\ + ((REQUEST) == HAL_DMA1_CH4_DAC_CH2) ||\ + ((REQUEST) == HAL_DMA1_CH4_I2C2_TX) ||\ + ((REQUEST) == HAL_DMA1_CH4_SPI2_RX) ||\ + ((REQUEST) == HAL_DMA1_CH4_TIM2_CH4) ||\ + ((REQUEST) == HAL_DMA1_CH4_TIM3_CH1) ||\ + ((REQUEST) == HAL_DMA1_CH4_TIM3_TRIG) ||\ + ((REQUEST) == HAL_DMA1_CH4_TIM16_CH1) ||\ + ((REQUEST) == HAL_DMA1_CH4_TIM16_UP) ||\ + ((REQUEST) == HAL_DMA1_CH4_USART1_TX) ||\ + ((REQUEST) == HAL_DMA1_CH4_USART2_TX) ||\ + ((REQUEST) == HAL_DMA1_CH4_USART3_TX) ||\ + ((REQUEST) == HAL_DMA1_CH4_USART4_TX) ||\ + ((REQUEST) == HAL_DMA1_CH4_USART5_TX) ||\ + ((REQUEST) == HAL_DMA1_CH4_USART6_TX) ||\ + ((REQUEST) == HAL_DMA1_CH4_USART7_TX) ||\ + ((REQUEST) == HAL_DMA1_CH4_USART8_TX) ||\ + ((REQUEST) == HAL_DMA1_CH5_DEFAULT) ||\ + ((REQUEST) == HAL_DMA1_CH5_I2C2_RX) ||\ + ((REQUEST) == HAL_DMA1_CH5_SPI2_TX) ||\ + ((REQUEST) == HAL_DMA1_CH5_TIM1_CH3) ||\ + ((REQUEST) == HAL_DMA1_CH5_USART1_RX) ||\ + ((REQUEST) == HAL_DMA1_CH5_USART2_RX) ||\ + ((REQUEST) == HAL_DMA1_CH5_USART3_RX) ||\ + ((REQUEST) == HAL_DMA1_CH5_USART4_RX) ||\ + ((REQUEST) == HAL_DMA1_CH5_USART5_RX) ||\ + ((REQUEST) == HAL_DMA1_CH5_USART6_RX) ||\ + ((REQUEST) == HAL_DMA1_CH5_USART7_RX) ||\ + ((REQUEST) == HAL_DMA1_CH5_USART8_RX) ||\ + ((REQUEST) == HAL_DMA1_CH6_DEFAULT) ||\ + ((REQUEST) == HAL_DMA1_CH6_I2C1_TX) ||\ + ((REQUEST) == HAL_DMA1_CH6_SPI2_RX) ||\ + ((REQUEST) == HAL_DMA1_CH6_TIM1_CH1) ||\ + ((REQUEST) == HAL_DMA1_CH6_TIM1_CH2) ||\ + ((REQUEST) == HAL_DMA1_CH6_TIM1_CH3) ||\ + ((REQUEST) == HAL_DMA1_CH6_TIM3_CH1) ||\ + ((REQUEST) == HAL_DMA1_CH6_TIM3_TRIG) ||\ + ((REQUEST) == HAL_DMA1_CH6_TIM16_CH1) ||\ + ((REQUEST) == HAL_DMA1_CH6_TIM16_UP) ||\ + ((REQUEST) == HAL_DMA1_CH6_USART1_RX) ||\ + ((REQUEST) == HAL_DMA1_CH6_USART2_RX) ||\ + ((REQUEST) == HAL_DMA1_CH6_USART3_RX) ||\ + ((REQUEST) == HAL_DMA1_CH6_USART4_RX) ||\ + ((REQUEST) == HAL_DMA1_CH6_USART5_RX) ||\ + ((REQUEST) == HAL_DMA1_CH6_USART6_RX) ||\ + ((REQUEST) == HAL_DMA1_CH6_USART7_RX) ||\ + ((REQUEST) == HAL_DMA1_CH6_USART8_RX) ||\ + ((REQUEST) == HAL_DMA1_CH7_DEFAULT) ||\ + ((REQUEST) == HAL_DMA1_CH7_I2C1_RX) ||\ + ((REQUEST) == HAL_DMA1_CH7_SPI2_TX) ||\ + ((REQUEST) == HAL_DMA1_CH7_TIM2_CH2) ||\ + ((REQUEST) == HAL_DMA1_CH7_TIM2_CH4) ||\ + ((REQUEST) == HAL_DMA1_CH7_TIM17_CH1) ||\ + ((REQUEST) == HAL_DMA1_CH7_TIM17_UP) ||\ + ((REQUEST) == HAL_DMA1_CH7_USART1_TX) ||\ + ((REQUEST) == HAL_DMA1_CH7_USART2_TX) ||\ + ((REQUEST) == HAL_DMA1_CH7_USART3_TX) ||\ + ((REQUEST) == HAL_DMA1_CH7_USART4_TX) ||\ + ((REQUEST) == HAL_DMA1_CH7_USART5_TX) ||\ + ((REQUEST) == HAL_DMA1_CH7_USART6_TX) ||\ + ((REQUEST) == HAL_DMA1_CH7_USART7_TX) ||\ + ((REQUEST) == HAL_DMA1_CH7_USART8_TX)) + +#define IS_HAL_DMA2_REMAP(REQUEST) (((REQUEST) == HAL_DMA2_CH1_DEFAULT) ||\ + ((REQUEST) == HAL_DMA2_CH1_I2C2_TX) ||\ + ((REQUEST) == HAL_DMA2_CH1_USART1_TX) ||\ + ((REQUEST) == HAL_DMA2_CH1_USART2_TX) ||\ + ((REQUEST) == HAL_DMA2_CH1_USART3_TX) ||\ + ((REQUEST) == HAL_DMA2_CH1_USART4_TX) ||\ + ((REQUEST) == HAL_DMA2_CH1_USART5_TX) ||\ + ((REQUEST) == HAL_DMA2_CH1_USART6_TX) ||\ + ((REQUEST) == HAL_DMA2_CH1_USART7_TX) ||\ + ((REQUEST) == HAL_DMA2_CH1_USART8_TX) ||\ + ((REQUEST) == HAL_DMA2_CH2_DEFAULT) ||\ + ((REQUEST) == HAL_DMA2_CH2_I2C2_RX) ||\ + ((REQUEST) == HAL_DMA2_CH2_USART1_RX) ||\ + ((REQUEST) == HAL_DMA2_CH2_USART2_RX) ||\ + ((REQUEST) == HAL_DMA2_CH2_USART3_RX) ||\ + ((REQUEST) == HAL_DMA2_CH2_USART4_RX) ||\ + ((REQUEST) == HAL_DMA2_CH2_USART5_RX) ||\ + ((REQUEST) == HAL_DMA2_CH2_USART6_RX) ||\ + ((REQUEST) == HAL_DMA2_CH2_USART7_RX) ||\ + ((REQUEST) == HAL_DMA2_CH2_USART8_RX) ||\ + ((REQUEST) == HAL_DMA2_CH3_DEFAULT) ||\ + ((REQUEST) == HAL_DMA2_CH3_TIM6_UP) ||\ + ((REQUEST) == HAL_DMA2_CH3_DAC_CH1) ||\ + ((REQUEST) == HAL_DMA2_CH3_SPI1_RX) ||\ + ((REQUEST) == HAL_DMA2_CH3_USART1_RX) ||\ + ((REQUEST) == HAL_DMA2_CH3_USART2_RX) ||\ + ((REQUEST) == HAL_DMA2_CH3_USART3_RX) ||\ + ((REQUEST) == HAL_DMA2_CH3_USART4_RX) ||\ + ((REQUEST) == HAL_DMA2_CH3_USART5_RX) ||\ + ((REQUEST) == HAL_DMA2_CH3_USART6_RX) ||\ + ((REQUEST) == HAL_DMA2_CH3_USART7_RX) ||\ + ((REQUEST) == HAL_DMA2_CH3_USART8_RX) ||\ + ((REQUEST) == HAL_DMA2_CH4_DEFAULT) ||\ + ((REQUEST) == HAL_DMA2_CH4_TIM7_UP) ||\ + ((REQUEST) == HAL_DMA2_CH4_DAC_CH2) ||\ + ((REQUEST) == HAL_DMA2_CH4_SPI1_TX) ||\ + ((REQUEST) == HAL_DMA2_CH4_USART1_TX) ||\ + ((REQUEST) == HAL_DMA2_CH4_USART2_TX) ||\ + ((REQUEST) == HAL_DMA2_CH4_USART3_TX) ||\ + ((REQUEST) == HAL_DMA2_CH4_USART4_TX) ||\ + ((REQUEST) == HAL_DMA2_CH4_USART5_TX) ||\ + ((REQUEST) == HAL_DMA2_CH4_USART6_TX) ||\ + ((REQUEST) == HAL_DMA2_CH4_USART7_TX) ||\ + ((REQUEST) == HAL_DMA2_CH4_USART8_TX) ||\ + ((REQUEST) == HAL_DMA2_CH5_DEFAULT) ||\ + ((REQUEST) == HAL_DMA2_CH5_ADC) ||\ + ((REQUEST) == HAL_DMA2_CH5_USART1_TX) ||\ + ((REQUEST) == HAL_DMA2_CH5_USART2_TX) ||\ + ((REQUEST) == HAL_DMA2_CH5_USART3_TX) ||\ + ((REQUEST) == HAL_DMA2_CH5_USART4_TX) ||\ + ((REQUEST) == HAL_DMA2_CH5_USART5_TX) ||\ + ((REQUEST) == HAL_DMA2_CH5_USART6_TX) ||\ + ((REQUEST) == HAL_DMA2_CH5_USART7_TX) ||\ + ((REQUEST) == HAL_DMA2_CH5_USART8_TX )) +#endif /* STM32F091xC || STM32F098xx */ + +#if defined(STM32F030xC) +#define IS_HAL_DMA1_REMAP(REQUEST) (((REQUEST) == HAL_DMA1_CH1_DEFAULT) ||\ + ((REQUEST) == HAL_DMA1_CH1_ADC) ||\ + ((REQUEST) == HAL_DMA1_CH1_TIM17_CH1) ||\ + ((REQUEST) == HAL_DMA1_CH1_TIM17_UP) ||\ + ((REQUEST) == HAL_DMA1_CH1_USART1_RX) ||\ + ((REQUEST) == HAL_DMA1_CH1_USART2_RX) ||\ + ((REQUEST) == HAL_DMA1_CH1_USART3_RX) ||\ + ((REQUEST) == HAL_DMA1_CH1_USART4_RX) ||\ + ((REQUEST) == HAL_DMA1_CH1_USART5_RX) ||\ + ((REQUEST) == HAL_DMA1_CH1_USART6_RX) ||\ + ((REQUEST) == HAL_DMA1_CH2_DEFAULT) ||\ + ((REQUEST) == HAL_DMA1_CH2_ADC) ||\ + ((REQUEST) == HAL_DMA1_CH2_I2C1_TX) ||\ + ((REQUEST) == HAL_DMA1_CH2_SPI1_RX) ||\ + ((REQUEST) == HAL_DMA1_CH2_TIM1_CH1) ||\ + ((REQUEST) == HAL_DMA1_CH2_I2C1_TX) ||\ + ((REQUEST) == HAL_DMA1_CH2_TIM17_CH1) ||\ + ((REQUEST) == HAL_DMA1_CH2_TIM17_UP) ||\ + ((REQUEST) == HAL_DMA1_CH2_USART1_TX) ||\ + ((REQUEST) == HAL_DMA1_CH2_USART2_TX) ||\ + ((REQUEST) == HAL_DMA1_CH2_USART3_TX) ||\ + ((REQUEST) == HAL_DMA1_CH2_USART4_TX) ||\ + ((REQUEST) == HAL_DMA1_CH2_USART5_TX) ||\ + ((REQUEST) == HAL_DMA1_CH2_USART6_TX) ||\ + ((REQUEST) == HAL_DMA1_CH3_DEFAULT) ||\ + ((REQUEST) == HAL_DMA1_CH3_TIM6_UP) ||\ + ((REQUEST) == HAL_DMA1_CH3_I2C1_RX) ||\ + ((REQUEST) == HAL_DMA1_CH3_SPI1_TX) ||\ + ((REQUEST) == HAL_DMA1_CH3_TIM1_CH2) ||\ + ((REQUEST) == HAL_DMA1_CH3_TIM16_CH1) ||\ + ((REQUEST) == HAL_DMA1_CH3_TIM16_UP) ||\ + ((REQUEST) == HAL_DMA1_CH3_USART1_RX) ||\ + ((REQUEST) == HAL_DMA1_CH3_USART2_RX) ||\ + ((REQUEST) == HAL_DMA1_CH3_USART3_RX) ||\ + ((REQUEST) == HAL_DMA1_CH3_USART4_RX) ||\ + ((REQUEST) == HAL_DMA1_CH3_USART5_RX) ||\ + ((REQUEST) == HAL_DMA1_CH3_USART6_RX) ||\ + ((REQUEST) == HAL_DMA1_CH4_DEFAULT) ||\ + ((REQUEST) == HAL_DMA1_CH4_TIM7_UP) ||\ + ((REQUEST) == HAL_DMA1_CH4_I2C2_TX) ||\ + ((REQUEST) == HAL_DMA1_CH4_SPI2_RX) ||\ + ((REQUEST) == HAL_DMA1_CH4_TIM3_CH1) ||\ + ((REQUEST) == HAL_DMA1_CH4_TIM3_TRIG) ||\ + ((REQUEST) == HAL_DMA1_CH4_TIM16_CH1) ||\ + ((REQUEST) == HAL_DMA1_CH4_TIM16_UP) ||\ + ((REQUEST) == HAL_DMA1_CH4_USART1_TX) ||\ + ((REQUEST) == HAL_DMA1_CH4_USART2_TX) ||\ + ((REQUEST) == HAL_DMA1_CH4_USART3_TX) ||\ + ((REQUEST) == HAL_DMA1_CH4_USART4_TX) ||\ + ((REQUEST) == HAL_DMA1_CH4_USART5_TX) ||\ + ((REQUEST) == HAL_DMA1_CH4_USART6_TX) ||\ + ((REQUEST) == HAL_DMA1_CH5_DEFAULT) ||\ + ((REQUEST) == HAL_DMA1_CH5_I2C2_RX) ||\ + ((REQUEST) == HAL_DMA1_CH5_SPI2_TX) ||\ + ((REQUEST) == HAL_DMA1_CH5_TIM1_CH3) ||\ + ((REQUEST) == HAL_DMA1_CH5_USART1_RX) ||\ + ((REQUEST) == HAL_DMA1_CH5_USART2_RX) ||\ + ((REQUEST) == HAL_DMA1_CH5_USART3_RX) ||\ + ((REQUEST) == HAL_DMA1_CH5_USART4_RX) ||\ + ((REQUEST) == HAL_DMA1_CH5_USART5_RX) ||\ + ((REQUEST) == HAL_DMA1_CH5_USART6_RX)) +#endif /* STM32F030xC */ + +/** + * @} + */ +#endif /* STM32F091xC || STM32F098xx || STM32F030xC */ + +/* Exported macros -----------------------------------------------------------*/ + +/** @defgroup DMAEx_Exported_Macros DMAEx Exported Macros + * @{ + */ +/* Interrupt & Flag management */ + +#if defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F078xx) +/** + * @brief Returns the current DMA Channel transfer complete flag. + * @param __HANDLE__ DMA handle + * @retval The specified transfer complete flag index. + */ +#define __HAL_DMA_GET_TC_FLAG_INDEX(__HANDLE__) \ +(((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel1))? DMA_FLAG_TC1 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel2))? DMA_FLAG_TC2 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel3))? DMA_FLAG_TC3 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel4))? DMA_FLAG_TC4 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel5))? DMA_FLAG_TC5 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel6))? DMA_FLAG_TC6 :\ + DMA_FLAG_TC7) + +/** + * @brief Returns the current DMA Channel half transfer complete flag. + * @param __HANDLE__ DMA handle + * @retval The specified half transfer complete flag index. + */ +#define __HAL_DMA_GET_HT_FLAG_INDEX(__HANDLE__)\ +(((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel1))? DMA_FLAG_HT1 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel2))? DMA_FLAG_HT2 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel3))? DMA_FLAG_HT3 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel4))? DMA_FLAG_HT4 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel5))? DMA_FLAG_HT5 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel6))? DMA_FLAG_HT6 :\ + DMA_FLAG_HT7) + +/** + * @brief Returns the current DMA Channel transfer error flag. + * @param __HANDLE__ DMA handle + * @retval The specified transfer error flag index. + */ +#define __HAL_DMA_GET_TE_FLAG_INDEX(__HANDLE__)\ +(((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel1))? DMA_FLAG_TE1 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel2))? DMA_FLAG_TE2 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel3))? DMA_FLAG_TE3 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel4))? DMA_FLAG_TE4 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel5))? DMA_FLAG_TE5 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel6))? DMA_FLAG_TE6 :\ + DMA_FLAG_TE7) + +/** + * @brief Return the current DMA Channel Global interrupt flag. + * @param __HANDLE__ DMA handle + * @retval The specified transfer error flag index. + */ +#define __HAL_DMA_GET_GI_FLAG_INDEX(__HANDLE__)\ +(((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel1))? DMA_FLAG_GL1 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel2))? DMA_FLAG_GL2 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel3))? DMA_FLAG_GL3 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel4))? DMA_FLAG_GL4 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel5))? DMA_FLAG_GL5 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel6))? DMA_FLAG_GL6 :\ + DMA_FLAG_GL7) + +/** + * @brief Get the DMA Channel pending flags. + * @param __HANDLE__ DMA handle + * @param __FLAG__ Get the specified flag. + * This parameter can be any combination of the following values: + * @arg DMA_FLAG_TCx: Transfer complete flag + * @arg DMA_FLAG_HTx: Half transfer complete flag + * @arg DMA_FLAG_TEx: Transfer error flag + * Where x can be 1_7 to select the DMA Channel flag. + * @retval The state of FLAG (SET or RESET). + */ + +#define __HAL_DMA_GET_FLAG(__HANDLE__, __FLAG__) (DMA1->ISR & (__FLAG__)) + +/** + * @brief Clears the DMA Channel pending flags. + * @param __HANDLE__ DMA handle + * @param __FLAG__ specifies the flag to clear. + * This parameter can be any combination of the following values: + * @arg DMA_FLAG_TCx: Transfer complete flag + * @arg DMA_FLAG_HTx: Half transfer complete flag + * @arg DMA_FLAG_TEx: Transfer error flag + * Where x can be 1_7 to select the DMA Channel flag. + * @retval None + */ +#define __HAL_DMA_CLEAR_FLAG(__HANDLE__, __FLAG__) (DMA1->IFCR = (__FLAG__)) + +#elif defined(STM32F091xC) || defined(STM32F098xx) +/** + * @brief Returns the current DMA Channel transfer complete flag. + * @param __HANDLE__ DMA handle + * @retval The specified transfer complete flag index. + */ +#define __HAL_DMA_GET_TC_FLAG_INDEX(__HANDLE__) \ +(((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel1))? DMA_FLAG_TC1 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel2))? DMA_FLAG_TC2 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel3))? DMA_FLAG_TC3 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel4))? DMA_FLAG_TC4 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel5))? DMA_FLAG_TC5 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel6))? DMA_FLAG_TC6 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel7))? DMA_FLAG_TC7 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA2_Channel1))? DMA_FLAG_TC1 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA2_Channel2))? DMA_FLAG_TC2 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA2_Channel3))? DMA_FLAG_TC3 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA2_Channel4))? DMA_FLAG_TC4 :\ + DMA_FLAG_TC5) + +/** + * @brief Returns the current DMA Channel half transfer complete flag. + * @param __HANDLE__ DMA handle + * @retval The specified half transfer complete flag index. + */ +#define __HAL_DMA_GET_HT_FLAG_INDEX(__HANDLE__)\ +(((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel1))? DMA_FLAG_HT1 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel2))? DMA_FLAG_HT2 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel3))? DMA_FLAG_HT3 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel4))? DMA_FLAG_HT4 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel5))? DMA_FLAG_HT5 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel6))? DMA_FLAG_HT6 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel7))? DMA_FLAG_HT7 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA2_Channel1))? DMA_FLAG_HT1 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA2_Channel2))? DMA_FLAG_HT2 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA2_Channel3))? DMA_FLAG_HT3 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA2_Channel4))? DMA_FLAG_HT4 :\ + DMA_FLAG_HT5) + +/** + * @brief Returns the current DMA Channel transfer error flag. + * @param __HANDLE__ DMA handle + * @retval The specified transfer error flag index. + */ +#define __HAL_DMA_GET_TE_FLAG_INDEX(__HANDLE__)\ +(((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel1))? DMA_FLAG_TE1 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel2))? DMA_FLAG_TE2 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel3))? DMA_FLAG_TE3 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel4))? DMA_FLAG_TE4 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel5))? DMA_FLAG_TE5 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel6))? DMA_FLAG_TE6 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel7))? DMA_FLAG_TE7 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA2_Channel1))? DMA_FLAG_TE1 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA2_Channel2))? DMA_FLAG_TE2 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA2_Channel3))? DMA_FLAG_TE3 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA2_Channel4))? DMA_FLAG_TE4 :\ + DMA_FLAG_TE5) + +/** + * @brief Return the current DMA Channel Global interrupt flag. + * @param __HANDLE__ DMA handle + * @retval The specified transfer error flag index. + */ +#define __HAL_DMA_GET_GI_FLAG_INDEX(__HANDLE__)\ +(((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel1))? DMA_FLAG_GL1 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel2))? DMA_FLAG_GL2 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel3))? DMA_FLAG_GL3 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel4))? DMA_FLAG_GL4 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel5))? DMA_FLAG_GL5 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel6))? DMA_FLAG_GL6 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel7))? DMA_FLAG_GL7 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA2_Channel1))? DMA_FLAG_GL1 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA2_Channel2))? DMA_FLAG_GL2 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA2_Channel3))? DMA_FLAG_GL3 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA2_Channel4))? DMA_FLAG_GL4 :\ + DMA_FLAG_GL5) + +/** + * @brief Get the DMA Channel pending flags. + * @param __HANDLE__ DMA handle + * @param __FLAG__ Get the specified flag. + * This parameter can be any combination of the following values: + * @arg DMA_FLAG_TCx: Transfer complete flag + * @arg DMA_FLAG_HTx: Half transfer complete flag + * @arg DMA_FLAG_TEx: Transfer error flag + * Where x can be 0_4, 1_5, 2_6 or 3_7 to select the DMA Channel flag. + * @retval The state of FLAG (SET or RESET). + */ + +#define __HAL_DMA_GET_FLAG(__HANDLE__, __FLAG__)\ +(((uint32_t)((__HANDLE__)->Instance) > (uint32_t)DMA1_Channel7)? (DMA2->ISR & (__FLAG__)) :\ + (DMA1->ISR & (__FLAG__))) + +/** + * @brief Clears the DMA Channel pending flags. + * @param __HANDLE__ DMA handle + * @param __FLAG__ specifies the flag to clear. + * This parameter can be any combination of the following values: + * @arg DMA_FLAG_TCx: Transfer complete flag + * @arg DMA_FLAG_HTx: Half transfer complete flag + * @arg DMA_FLAG_TEx: Transfer error flag + * Where x can be 0_4, 1_5, 2_6 or 3_7 to select the DMA Channel flag. + * @retval None + */ +#define __HAL_DMA_CLEAR_FLAG(__HANDLE__, __FLAG__) \ +(((uint32_t)((__HANDLE__)->Instance) > (uint32_t)DMA1_Channel7)? (DMA2->IFCR = (__FLAG__)) :\ + (DMA1->IFCR = (__FLAG__))) + +#else /* STM32F030x8_STM32F030xC_STM32F031x6_STM32F038xx_STM32F051x8_STM32F058xx_STM32F070x6_STM32F070xB Product devices */ +/** + * @brief Returns the current DMA Channel transfer complete flag. + * @param __HANDLE__ DMA handle + * @retval The specified transfer complete flag index. + */ +#define __HAL_DMA_GET_TC_FLAG_INDEX(__HANDLE__) \ +(((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel1))? DMA_FLAG_TC1 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel2))? DMA_FLAG_TC2 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel3))? DMA_FLAG_TC3 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel4))? DMA_FLAG_TC4 :\ + DMA_FLAG_TC5) + +/** + * @brief Returns the current DMA Channel half transfer complete flag. + * @param __HANDLE__ DMA handle + * @retval The specified half transfer complete flag index. + */ +#define __HAL_DMA_GET_HT_FLAG_INDEX(__HANDLE__)\ +(((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel1))? DMA_FLAG_HT1 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel2))? DMA_FLAG_HT2 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel3))? DMA_FLAG_HT3 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel4))? DMA_FLAG_HT4 :\ + DMA_FLAG_HT5) + +/** + * @brief Returns the current DMA Channel transfer error flag. + * @param __HANDLE__ DMA handle + * @retval The specified transfer error flag index. + */ +#define __HAL_DMA_GET_TE_FLAG_INDEX(__HANDLE__)\ +(((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel1))? DMA_FLAG_TE1 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel2))? DMA_FLAG_TE2 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel3))? DMA_FLAG_TE3 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel4))? DMA_FLAG_TE4 :\ + DMA_FLAG_TE5) + +/** + * @brief Return the current DMA Channel Global interrupt flag. + * @param __HANDLE__ DMA handle + * @retval The specified transfer error flag index. + */ +#define __HAL_DMA_GET_GI_FLAG_INDEX(__HANDLE__)\ +(((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel1))? DMA_FLAG_GL1 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel2))? DMA_FLAG_GL2 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel3))? DMA_FLAG_GL3 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Channel4))? DMA_FLAG_GL4 :\ + DMA_FLAG_GL5) + +/** + * @brief Get the DMA Channel pending flags. + * @param __HANDLE__ DMA handle + * @param __FLAG__ Get the specified flag. + * This parameter can be any combination of the following values: + * @arg DMA_FLAG_TCx: Transfer complete flag + * @arg DMA_FLAG_HTx: Half transfer complete flag + * @arg DMA_FLAG_TEx: Transfer error flag + * Where x can be 1_5 to select the DMA Channel flag. + * @retval The state of FLAG (SET or RESET). + */ + +#define __HAL_DMA_GET_FLAG(__HANDLE__, __FLAG__) (DMA1->ISR & (__FLAG__)) + +/** + * @brief Clears the DMA Channel pending flags. + * @param __HANDLE__ DMA handle + * @param __FLAG__ specifies the flag to clear. + * This parameter can be any combination of the following values: + * @arg DMA_FLAG_TCx: Transfer complete flag + * @arg DMA_FLAG_HTx: Half transfer complete flag + * @arg DMA_FLAG_TEx: Transfer error flag + * Where x can be 1_5 to select the DMA Channel flag. + * @retval None + */ +#define __HAL_DMA_CLEAR_FLAG(__HANDLE__, __FLAG__) (DMA1->IFCR = (__FLAG__)) + +#endif + + +#if defined(STM32F091xC) || defined(STM32F098xx) || defined(STM32F030xC) +#define __HAL_DMA1_REMAP(__REQUEST__) \ + do { assert_param(IS_HAL_DMA1_REMAP(__REQUEST__)); \ + DMA1->CSELR &= ~(0x0FU << (uint32_t)(((__REQUEST__) >> 28U) * 4U)); \ + DMA1->CSELR |= (uint32_t)((__REQUEST__) & 0x0FFFFFFFU); \ + }while(0) + +#if defined(STM32F091xC) || defined(STM32F098xx) +#define __HAL_DMA2_REMAP(__REQUEST__) \ + do { assert_param(IS_HAL_DMA2_REMAP(__REQUEST__)); \ + DMA2->CSELR &= ~(0x0FU << (uint32_t)(((__REQUEST__) >> 28U) * 4U)); \ + DMA2->CSELR |= (uint32_t)((__REQUEST__) & 0x0FFFFFFFU); \ + }while(0) +#endif /* STM32F091xC || STM32F098xx */ + +#endif /* STM32F091xC || STM32F098xx || STM32F030xC */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F0xx_HAL_DMA_EX_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_exti.h b/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_exti.h new file mode 100644 index 0000000..6bfdc0a --- /dev/null +++ b/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_exti.h @@ -0,0 +1,375 @@ +/** + ****************************************************************************** + * @file stm32f0xx_hal_exti.h + * @author MCD Application Team + * @brief Header file of EXTI HAL module. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2019 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32F0xx_HAL_EXTI_H +#define STM32F0xx_HAL_EXTI_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f0xx_hal_def.h" + +/** @addtogroup STM32F0xx_HAL_Driver + * @{ + */ + +/** @defgroup EXTI EXTI + * @brief EXTI HAL module driver + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ + +/** @defgroup EXTI_Exported_Types EXTI Exported Types + * @{ + */ + +/** + * @brief HAL EXTI common Callback ID enumeration definition + */ +typedef enum +{ + HAL_EXTI_COMMON_CB_ID = 0x00U +} EXTI_CallbackIDTypeDef; + +/** + * @brief EXTI Handle structure definition + */ +typedef struct +{ + uint32_t Line; /*!< Exti line number */ + void (* PendingCallback)(void); /*!< Exti pending callback */ +} EXTI_HandleTypeDef; + +/** + * @brief EXTI Configuration structure definition + */ +typedef struct +{ + uint32_t Line; /*!< The Exti line to be configured. This parameter + can be a value of @ref EXTI_Line */ + uint32_t Mode; /*!< The Exit Mode to be configured for a core. + This parameter can be a combination of @ref EXTI_Mode */ + uint32_t Trigger; /*!< The Exti Trigger to be configured. This parameter + can be a value of @ref EXTI_Trigger */ + uint32_t GPIOSel; /*!< The Exti GPIO multiplexer selection to be configured. + This parameter is only possible for line 0 to 15. It + can be a value of @ref EXTI_GPIOSel */ +} EXTI_ConfigTypeDef; + +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup EXTI_Exported_Constants EXTI Exported Constants + * @{ + */ + +/** @defgroup EXTI_Line EXTI Line + * @{ + */ +#define EXTI_LINE_0 (EXTI_GPIO | 0x00u) /*!< External interrupt line 0 */ +#define EXTI_LINE_1 (EXTI_GPIO | 0x01u) /*!< External interrupt line 1 */ +#define EXTI_LINE_2 (EXTI_GPIO | 0x02u) /*!< External interrupt line 2 */ +#define EXTI_LINE_3 (EXTI_GPIO | 0x03u) /*!< External interrupt line 3 */ +#define EXTI_LINE_4 (EXTI_GPIO | 0x04u) /*!< External interrupt line 4 */ +#define EXTI_LINE_5 (EXTI_GPIO | 0x05u) /*!< External interrupt line 5 */ +#define EXTI_LINE_6 (EXTI_GPIO | 0x06u) /*!< External interrupt line 6 */ +#define EXTI_LINE_7 (EXTI_GPIO | 0x07u) /*!< External interrupt line 7 */ +#define EXTI_LINE_8 (EXTI_GPIO | 0x08u) /*!< External interrupt line 8 */ +#define EXTI_LINE_9 (EXTI_GPIO | 0x09u) /*!< External interrupt line 9 */ +#define EXTI_LINE_10 (EXTI_GPIO | 0x0Au) /*!< External interrupt line 10 */ +#define EXTI_LINE_11 (EXTI_GPIO | 0x0Bu) /*!< External interrupt line 11 */ +#define EXTI_LINE_12 (EXTI_GPIO | 0x0Cu) /*!< External interrupt line 12 */ +#define EXTI_LINE_13 (EXTI_GPIO | 0x0Du) /*!< External interrupt line 13 */ +#define EXTI_LINE_14 (EXTI_GPIO | 0x0Eu) /*!< External interrupt line 14 */ +#define EXTI_LINE_15 (EXTI_GPIO | 0x0Fu) /*!< External interrupt line 15 */ + +#if defined (EXTI_IMR_MR16) +#define EXTI_LINE_16 (EXTI_CONFIG | 0x10u) /*!< External interrupt line 16 Connected to the PVD Output */ +#else +#define EXTI_LINE_16 (EXTI_RESERVED | 0x10u) +#endif /* EXTI_IMR_MR16 */ + +#define EXTI_LINE_17 (EXTI_CONFIG | 0x11u) /*!< External interrupt line 17 Connected to the RTC Alarm event */ + +#if defined (EXTI_IMR_MR18) +#define EXTI_LINE_18 (EXTI_CONFIG | 0x12u) /*!< External interrupt line 18 Connected to the USB OTG FS Wakeup from suspend event */ +#else +#define EXTI_LINE_18 (EXTI_RESERVED | 0x12u) +#endif /* EXTI_IMR_MR18 */ + +#define EXTI_LINE_19 (EXTI_CONFIG | 0x13u) /*!< External interrupt line 19 Connected to the Ethernet Wakeup event */ + +#if defined (EXTI_IMR_MR20) +#define EXTI_LINE_20 (EXTI_CONFIG | 0x14u) /*!< External interrupt line 20 Connected to the USB OTG HS (configured in FS) Wakeup event */ +#else +#define EXTI_LINE_20 (EXTI_RESERVED | 0x14u) +#endif /* EXTI_IMR_MR20 */ + +#if defined (EXTI_IMR_MR21) +#define EXTI_LINE_21 (EXTI_CONFIG | 0x15u) /*!< External interrupt line 21 Connected to the Comparator 1 output */ +#else +#define EXTI_LINE_21 (EXTI_RESERVED | 0x15u) +#endif /* EXTI_IMR_MR21 */ + +#if defined (EXTI_IMR_MR22) +#define EXTI_LINE_22 (EXTI_CONFIG | 0x16u) /*!< External interrupt line 22 Connected to the Comparator 2 output */ +#else +#define EXTI_LINE_22 (EXTI_RESERVED | 0x16u) +#endif /* EXTI_IMR_MR22 */ + +#if defined (EXTI_IMR_MR23) +#define EXTI_LINE_23 (EXTI_DIRECT | 0x17u) /*!< External interrupt line 23 Connected to the internal I2C1 wakeup event */ +#else +#define EXTI_LINE_23 (EXTI_RESERVED | 0x17u) +#endif /* EXTI_IMR_MR23 */ + +#define EXTI_LINE_24 (EXTI_RESERVED | 0x18u) + +#if defined (EXTI_IMR_MR25) +#define EXTI_LINE_25 (EXTI_CONFIG | 0x19u) /*!< External interrupt line 25 Connected to the internal USART1 wakeup event */ +#else +#define EXTI_LINE_25 (EXTI_RESERVED | 0x19u) +#endif /* EXTI_IMR_MR25 */ + +#if defined (EXTI_IMR_MR26) +#define EXTI_LINE_26 (EXTI_CONFIG | 0x1Au) /*!< External interrupt line 26 Connected to the internal USART2 wakeup event */ +#else +#define EXTI_LINE_26 (EXTI_RESERVED | 0x1Au) +#endif /* EXTI_IMR_MR26 */ + +#if defined (EXTI_IMR_MR27) +#define EXTI_LINE_27 (EXTI_CONFIG | 0x1Bu) /*!< External interrupt line 27 Connected to the internal CEC wakeup event */ +#else +#define EXTI_LINE_27 (EXTI_RESERVED | 0x1Bu) +#endif /* EXTI_IMR_MR27 */ + +#if defined (EXTI_IMR_MR28) +#define EXTI_LINE_28 (EXTI_CONFIG | 0x1Cu) /*!< External interrupt line 28 Connected to the internal USART3 wakeup event */ +#else +#define EXTI_LINE_28 (EXTI_RESERVED | 0x1Cu) +#endif /* EXTI_IMR_MR28 */ + +#define EXTI_LINE_29 (EXTI_RESERVED | 0x1Du) +#define EXTI_LINE_30 (EXTI_RESERVED | 0x1Eu) + +#if defined (EXTI_IMR_MR31) +#define EXTI_LINE_31 (EXTI_CONFIG | 0x1Fu) /*!< External interrupt line 31 Connected to the VDDIO2 supply comparator output */ +#else +#define EXTI_LINE_31 (EXTI_RESERVED | 0x1Fu) +#endif /* EXTI_IMR_MR31 */ + +/** + * @} + */ + +/** @defgroup EXTI_Mode EXTI Mode + * @{ + */ +#define EXTI_MODE_NONE 0x00000000u +#define EXTI_MODE_INTERRUPT 0x00000001u +#define EXTI_MODE_EVENT 0x00000002u +/** + * @} + */ + +/** @defgroup EXTI_Trigger EXTI Trigger + * @{ + */ +#define EXTI_TRIGGER_NONE 0x00000000u +#define EXTI_TRIGGER_RISING 0x00000001u +#define EXTI_TRIGGER_FALLING 0x00000002u +#define EXTI_TRIGGER_RISING_FALLING (EXTI_TRIGGER_RISING | EXTI_TRIGGER_FALLING) +/** + * @} + */ + +/** @defgroup EXTI_GPIOSel EXTI GPIOSel + * @brief + * @{ + */ +#define EXTI_GPIOA 0x00000000u +#define EXTI_GPIOB 0x00000001u +#define EXTI_GPIOC 0x00000002u +#if defined (GPIOD) +#define EXTI_GPIOD 0x00000003u +#endif /* GPIOD */ +#if defined (GPIOE) +#define EXTI_GPIOE 0x00000004u +#endif /* GPIOE */ +#define EXTI_GPIOF 0x00000005u +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup EXTI_Exported_Macros EXTI Exported Macros + * @{ + */ + +/** + * @} + */ + +/* Private constants --------------------------------------------------------*/ +/** @defgroup EXTI_Private_Constants EXTI Private Constants + * @{ + */ +/** + * @brief EXTI Line property definition + */ +#define EXTI_PROPERTY_SHIFT 24u +#define EXTI_DIRECT (0x01uL << EXTI_PROPERTY_SHIFT) +#define EXTI_CONFIG (0x02uL << EXTI_PROPERTY_SHIFT) +#define EXTI_GPIO ((0x04uL << EXTI_PROPERTY_SHIFT) | EXTI_CONFIG) +#define EXTI_RESERVED (0x08uL << EXTI_PROPERTY_SHIFT) +#define EXTI_PROPERTY_MASK (EXTI_DIRECT | EXTI_CONFIG | EXTI_GPIO) + +/** + * @brief EXTI bit usage + */ +#define EXTI_PIN_MASK 0x0000001Fu + +/** + * @brief EXTI Mask for interrupt & event mode + */ +#define EXTI_MODE_MASK (EXTI_MODE_EVENT | EXTI_MODE_INTERRUPT) + +/** + * @brief EXTI Mask for trigger possibilities + */ +#define EXTI_TRIGGER_MASK (EXTI_TRIGGER_RISING | EXTI_TRIGGER_FALLING) + +/** + * @brief EXTI Line number + */ +#define EXTI_LINE_NB 32uL + +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup EXTI_Private_Macros EXTI Private Macros + * @{ + */ +#define IS_EXTI_LINE(__LINE__) ((((__LINE__) & ~(EXTI_PROPERTY_MASK | EXTI_PIN_MASK)) == 0x00u) && \ + ((((__LINE__) & EXTI_PROPERTY_MASK) == EXTI_DIRECT) || \ + (((__LINE__) & EXTI_PROPERTY_MASK) == EXTI_CONFIG) || \ + (((__LINE__) & EXTI_PROPERTY_MASK) == EXTI_GPIO)) && \ + (((__LINE__) & EXTI_PIN_MASK) < EXTI_LINE_NB)) + +#define IS_EXTI_MODE(__LINE__) ((((__LINE__) & EXTI_MODE_MASK) != 0x00u) && \ + (((__LINE__) & ~EXTI_MODE_MASK) == 0x00u)) + +#define IS_EXTI_TRIGGER(__LINE__) (((__LINE__) & ~EXTI_TRIGGER_MASK) == 0x00u) + +#define IS_EXTI_PENDING_EDGE(__LINE__) ((__LINE__) == EXTI_TRIGGER_RISING_FALLING) + +#define IS_EXTI_CONFIG_LINE(__LINE__) (((__LINE__) & EXTI_CONFIG) != 0x00u) + +#if defined (GPIOE) +#define IS_EXTI_GPIO_PORT(__PORT__) (((__PORT__) == EXTI_GPIOA) || \ + ((__PORT__) == EXTI_GPIOB) || \ + ((__PORT__) == EXTI_GPIOC) || \ + ((__PORT__) == EXTI_GPIOD) || \ + ((__PORT__) == EXTI_GPIOE) || \ + ((__PORT__) == EXTI_GPIOF)) +#elif defined (GPIOD) +#define IS_EXTI_GPIO_PORT(__PORT__) (((__PORT__) == EXTI_GPIOA) || \ + ((__PORT__) == EXTI_GPIOB) || \ + ((__PORT__) == EXTI_GPIOC) || \ + ((__PORT__) == EXTI_GPIOD) || \ + ((__PORT__) == EXTI_GPIOF)) +#else +#define IS_EXTI_GPIO_PORT(__PORT__) (((__PORT__) == EXTI_GPIOA) || \ + ((__PORT__) == EXTI_GPIOB) || \ + ((__PORT__) == EXTI_GPIOC) || \ + ((__PORT__) == EXTI_GPIOF)) +#endif /* GPIOE */ + +#define IS_EXTI_GPIO_PIN(__PIN__) ((__PIN__) < 16u) + +/** + * @} + */ + + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup EXTI_Exported_Functions EXTI Exported Functions + * @brief EXTI Exported Functions + * @{ + */ + +/** @defgroup EXTI_Exported_Functions_Group1 Configuration functions + * @brief Configuration functions + * @{ + */ +/* Configuration functions ****************************************************/ +HAL_StatusTypeDef HAL_EXTI_SetConfigLine(EXTI_HandleTypeDef *hexti, EXTI_ConfigTypeDef *pExtiConfig); +HAL_StatusTypeDef HAL_EXTI_GetConfigLine(EXTI_HandleTypeDef *hexti, EXTI_ConfigTypeDef *pExtiConfig); +HAL_StatusTypeDef HAL_EXTI_ClearConfigLine(EXTI_HandleTypeDef *hexti); +HAL_StatusTypeDef HAL_EXTI_RegisterCallback(EXTI_HandleTypeDef *hexti, EXTI_CallbackIDTypeDef CallbackID, void (*pPendingCbfn)(void)); +HAL_StatusTypeDef HAL_EXTI_GetHandle(EXTI_HandleTypeDef *hexti, uint32_t ExtiLine); +/** + * @} + */ + +/** @defgroup EXTI_Exported_Functions_Group2 IO operation functions + * @brief IO operation functions + * @{ + */ +/* IO operation functions *****************************************************/ +void HAL_EXTI_IRQHandler(EXTI_HandleTypeDef *hexti); +uint32_t HAL_EXTI_GetPending(EXTI_HandleTypeDef *hexti, uint32_t Edge); +void HAL_EXTI_ClearPending(EXTI_HandleTypeDef *hexti, uint32_t Edge); +void HAL_EXTI_GenerateSWI(EXTI_HandleTypeDef *hexti); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32F0xx_HAL_EXTI_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash.h b/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash.h new file mode 100644 index 0000000..ecce5da --- /dev/null +++ b/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash.h @@ -0,0 +1,353 @@ +/** + ****************************************************************************** + * @file stm32f0xx_hal_flash.h + * @author MCD Application Team + * @brief Header file of Flash HAL module. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2016 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F0xx_HAL_FLASH_H +#define __STM32F0xx_HAL_FLASH_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f0xx_hal_def.h" + +/** @addtogroup STM32F0xx_HAL_Driver + * @{ + */ + +/** @addtogroup FLASH + * @{ + */ + +/** @addtogroup FLASH_Private_Constants + * @{ + */ +#define FLASH_TIMEOUT_VALUE (50000U) /* 50 s */ +/** + * @} + */ + +/** @addtogroup FLASH_Private_Macros + * @{ + */ + +#define IS_FLASH_TYPEPROGRAM(VALUE) (((VALUE) == FLASH_TYPEPROGRAM_HALFWORD) || \ + ((VALUE) == FLASH_TYPEPROGRAM_WORD) || \ + ((VALUE) == FLASH_TYPEPROGRAM_DOUBLEWORD)) + +#define IS_FLASH_LATENCY(__LATENCY__) (((__LATENCY__) == FLASH_LATENCY_0) || \ + ((__LATENCY__) == FLASH_LATENCY_1)) + +/** + * @} + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup FLASH_Exported_Types FLASH Exported Types + * @{ + */ + +/** + * @brief FLASH Procedure structure definition + */ +typedef enum +{ + FLASH_PROC_NONE = 0U, + FLASH_PROC_PAGEERASE = 1U, + FLASH_PROC_MASSERASE = 2U, + FLASH_PROC_PROGRAMHALFWORD = 3U, + FLASH_PROC_PROGRAMWORD = 4U, + FLASH_PROC_PROGRAMDOUBLEWORD = 5U +} FLASH_ProcedureTypeDef; + +/** + * @brief FLASH handle Structure definition + */ +typedef struct +{ + __IO FLASH_ProcedureTypeDef ProcedureOnGoing; /*!< Internal variable to indicate which procedure is ongoing or not in IT context */ + + __IO uint32_t DataRemaining; /*!< Internal variable to save the remaining pages to erase or half-word to program in IT context */ + + __IO uint32_t Address; /*!< Internal variable to save address selected for program or erase */ + + __IO uint64_t Data; /*!< Internal variable to save data to be programmed */ + + HAL_LockTypeDef Lock; /*!< FLASH locking object */ + + __IO uint32_t ErrorCode; /*!< FLASH error code + This parameter can be a value of @ref FLASH_Error_Codes */ +} FLASH_ProcessTypeDef; + +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup FLASH_Exported_Constants FLASH Exported Constants + * @{ + */ + +/** @defgroup FLASH_Error_Codes FLASH Error Codes + * @{ + */ + +#define HAL_FLASH_ERROR_NONE 0x00U /*!< No error */ +#define HAL_FLASH_ERROR_PROG 0x01U /*!< Programming error */ +#define HAL_FLASH_ERROR_WRP 0x02U /*!< Write protection error */ + +/** + * @} + */ + +/** @defgroup FLASH_Type_Program FLASH Type Program + * @{ + */ +#define FLASH_TYPEPROGRAM_HALFWORD (0x01U) /*!ACR = (FLASH->ACR&(~FLASH_ACR_LATENCY)) | (__LATENCY__)) + + +/** + * @brief Get the FLASH Latency. + * @retval FLASH Latency + * The value of this parameter depend on device used within the same series + */ +#define __HAL_FLASH_GET_LATENCY() (READ_BIT((FLASH->ACR), FLASH_ACR_LATENCY)) + +/** + * @} + */ + +/** @defgroup FLASH_Prefetch FLASH Prefetch + * @brief macros to handle FLASH Prefetch buffer + * @{ + */ +/** + * @brief Enable the FLASH prefetch buffer. + * @retval None + */ +#define __HAL_FLASH_PREFETCH_BUFFER_ENABLE() (FLASH->ACR |= FLASH_ACR_PRFTBE) + +/** + * @brief Disable the FLASH prefetch buffer. + * @retval None + */ +#define __HAL_FLASH_PREFETCH_BUFFER_DISABLE() (FLASH->ACR &= (~FLASH_ACR_PRFTBE)) + +/** + * @} + */ + +/** @defgroup FLASH_Interrupt FLASH Interrupts + * @brief macros to handle FLASH interrupts + * @{ + */ + +/** + * @brief Enable the specified FLASH interrupt. + * @param __INTERRUPT__ FLASH interrupt + * This parameter can be any combination of the following values: + * @arg @ref FLASH_IT_EOP End of FLASH Operation Interrupt + * @arg @ref FLASH_IT_ERR Error Interrupt + * @retval none + */ +#define __HAL_FLASH_ENABLE_IT(__INTERRUPT__) SET_BIT((FLASH->CR), (__INTERRUPT__)) + +/** + * @brief Disable the specified FLASH interrupt. + * @param __INTERRUPT__ FLASH interrupt + * This parameter can be any combination of the following values: + * @arg @ref FLASH_IT_EOP End of FLASH Operation Interrupt + * @arg @ref FLASH_IT_ERR Error Interrupt + * @retval none + */ +#define __HAL_FLASH_DISABLE_IT(__INTERRUPT__) CLEAR_BIT((FLASH->CR), (uint32_t)(__INTERRUPT__)) + +/** + * @brief Get the specified FLASH flag status. + * @param __FLAG__ specifies the FLASH flag to check. + * This parameter can be one of the following values: + * @arg @ref FLASH_FLAG_BSY FLASH Busy flag + * @arg @ref FLASH_FLAG_EOP FLASH End of Operation flag + * @arg @ref FLASH_FLAG_WRPERR FLASH Write protected error flag + * @arg @ref FLASH_FLAG_PGERR FLASH Programming error flag + * @retval The new state of __FLAG__ (SET or RESET). + */ +#define __HAL_FLASH_GET_FLAG(__FLAG__) (((FLASH->SR) & (__FLAG__)) == (__FLAG__)) + +/** + * @brief Clear the specified FLASH flag. + * @param __FLAG__ specifies the FLASH flags to clear. + * This parameter can be any combination of the following values: + * @arg @ref FLASH_FLAG_EOP FLASH End of Operation flag + * @arg @ref FLASH_FLAG_WRPERR FLASH Write protected error flag + * @arg @ref FLASH_FLAG_PGERR FLASH Programming error flag + * @retval none + */ +#define __HAL_FLASH_CLEAR_FLAG(__FLAG__) ((FLASH->SR) = (__FLAG__)) + +/** + * @} + */ + +/** + * @} + */ + +/* Include FLASH HAL Extended module */ +#include "stm32f0xx_hal_flash_ex.h" + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup FLASH_Exported_Functions + * @{ + */ + +/** @addtogroup FLASH_Exported_Functions_Group1 + * @{ + */ +/* IO operation functions *****************************************************/ +HAL_StatusTypeDef HAL_FLASH_Program(uint32_t TypeProgram, uint32_t Address, uint64_t Data); +HAL_StatusTypeDef HAL_FLASH_Program_IT(uint32_t TypeProgram, uint32_t Address, uint64_t Data); + +/* FLASH IRQ handler function */ +void HAL_FLASH_IRQHandler(void); +/* Callbacks in non blocking modes */ +void HAL_FLASH_EndOfOperationCallback(uint32_t ReturnValue); +void HAL_FLASH_OperationErrorCallback(uint32_t ReturnValue); + +/** + * @} + */ + +/** @addtogroup FLASH_Exported_Functions_Group2 + * @{ + */ +/* Peripheral Control functions ***********************************************/ +HAL_StatusTypeDef HAL_FLASH_Unlock(void); +HAL_StatusTypeDef HAL_FLASH_Lock(void); +HAL_StatusTypeDef HAL_FLASH_OB_Unlock(void); +HAL_StatusTypeDef HAL_FLASH_OB_Lock(void); +HAL_StatusTypeDef HAL_FLASH_OB_Launch(void); + +/** + * @} + */ + +/** @addtogroup FLASH_Exported_Functions_Group3 + * @{ + */ +/* Peripheral State and Error functions ***************************************/ +uint32_t HAL_FLASH_GetError(void); + +/** + * @} + */ + +/** + * @} + */ + +/* Private function -------------------------------------------------*/ +/** @addtogroup FLASH_Private_Functions + * @{ + */ +HAL_StatusTypeDef FLASH_WaitForLastOperation(uint32_t Timeout); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F0xx_HAL_FLASH_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ + diff --git a/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash_ex.h b/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash_ex.h new file mode 100644 index 0000000..a4c79d8 --- /dev/null +++ b/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash_ex.h @@ -0,0 +1,448 @@ +/** + ****************************************************************************** + * @file stm32f0xx_hal_flash_ex.h + * @author MCD Application Team + * @brief Header file of Flash HAL Extended module. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2016 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F0xx_HAL_FLASH_EX_H +#define __STM32F0xx_HAL_FLASH_EX_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f0xx_hal_def.h" + +/** @addtogroup STM32F0xx_HAL_Driver + * @{ + */ + +/** @addtogroup FLASHEx + * @{ + */ + +/** @addtogroup FLASHEx_Private_Macros + * @{ + */ +#define IS_FLASH_TYPEERASE(VALUE) (((VALUE) == FLASH_TYPEERASE_PAGES) || \ + ((VALUE) == FLASH_TYPEERASE_MASSERASE)) + +#define IS_OPTIONBYTE(VALUE) ((VALUE) <= (OPTIONBYTE_WRP | OPTIONBYTE_RDP | OPTIONBYTE_USER | OPTIONBYTE_DATA)) + +#define IS_WRPSTATE(VALUE) (((VALUE) == OB_WRPSTATE_DISABLE) || \ + ((VALUE) == OB_WRPSTATE_ENABLE)) + +#define IS_OB_DATA_ADDRESS(ADDRESS) (((ADDRESS) == OB_DATA_ADDRESS_DATA0) || ((ADDRESS) == OB_DATA_ADDRESS_DATA1)) + +#define IS_OB_RDP_LEVEL(LEVEL) (((LEVEL) == OB_RDP_LEVEL_0) ||\ + ((LEVEL) == OB_RDP_LEVEL_1))/*||\ + ((LEVEL) == OB_RDP_LEVEL_2))*/ + +#define IS_OB_IWDG_SOURCE(SOURCE) (((SOURCE) == OB_IWDG_SW) || ((SOURCE) == OB_IWDG_HW)) + +#define IS_OB_STOP_SOURCE(SOURCE) (((SOURCE) == OB_STOP_NO_RST) || ((SOURCE) == OB_STOP_RST)) + +#define IS_OB_STDBY_SOURCE(SOURCE) (((SOURCE) == OB_STDBY_NO_RST) || ((SOURCE) == OB_STDBY_RST)) + +#define IS_OB_BOOT1(BOOT1) (((BOOT1) == OB_BOOT1_RESET) || ((BOOT1) == OB_BOOT1_SET)) + +#define IS_OB_VDDA_ANALOG(ANALOG) (((ANALOG) == OB_VDDA_ANALOG_ON) || ((ANALOG) == OB_VDDA_ANALOG_OFF)) + +#define IS_OB_SRAM_PARITY(PARITY) (((PARITY) == OB_SRAM_PARITY_SET) || ((PARITY) == OB_SRAM_PARITY_RESET)) + +#if defined(FLASH_OBR_BOOT_SEL) +#define IS_OB_BOOT_SEL(BOOT_SEL) (((BOOT_SEL) == OB_BOOT_SEL_RESET) || ((BOOT_SEL) == OB_BOOT_SEL_SET)) +#define IS_OB_BOOT0(BOOT0) (((BOOT0) == OB_BOOT0_RESET) || ((BOOT0) == OB_BOOT0_SET)) +#endif /* FLASH_OBR_BOOT_SEL */ + + +#define IS_OB_WRP(PAGE) (((PAGE) != 0x0000000U)) + +#define IS_FLASH_NB_PAGES(ADDRESS,NBPAGES) ((ADDRESS)+((NBPAGES)*FLASH_PAGE_SIZE)-1 <= FLASH_BANK1_END) + +#define IS_FLASH_PROGRAM_ADDRESS(ADDRESS) (((ADDRESS) >= FLASH_BASE) && ((ADDRESS) <= FLASH_BANK1_END)) + +/** + * @} + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup FLASHEx_Exported_Types FLASHEx Exported Types + * @{ + */ +/** + * @brief FLASH Erase structure definition + */ +typedef struct +{ + uint32_t TypeErase; /*!< TypeErase: Mass erase or page erase. + This parameter can be a value of @ref FLASHEx_Type_Erase */ + + uint32_t PageAddress; /*!< PageAdress: Initial FLASH page address to erase when mass erase is disabled + This parameter must be a number between Min_Data = FLASH_BASE and Max_Data = FLASH_BANK1_END */ + + uint32_t NbPages; /*!< NbPages: Number of pagess to be erased. + This parameter must be a value between Min_Data = 1 and Max_Data = (max number of pages - value of initial page)*/ + +} FLASH_EraseInitTypeDef; + +/** + * @brief FLASH Options bytes program structure definition + */ +typedef struct +{ + uint32_t OptionType; /*!< OptionType: Option byte to be configured. + This parameter can be a value of @ref FLASHEx_OB_Type */ + + uint32_t WRPState; /*!< WRPState: Write protection activation or deactivation. + This parameter can be a value of @ref FLASHEx_OB_WRP_State */ + + uint32_t WRPPage; /*!< WRPPage: specifies the page(s) to be write protected + This parameter can be a value of @ref FLASHEx_OB_Write_Protection */ + + uint8_t RDPLevel; /*!< RDPLevel: Set the read protection level.. + This parameter can be a value of @ref FLASHEx_OB_Read_Protection */ + + uint8_t USERConfig; /*!< USERConfig: Program the FLASH User Option Byte: + IWDG / STOP / STDBY / BOOT1 / VDDA_ANALOG / SRAM_PARITY + This parameter can be a combination of @ref FLASHEx_OB_IWatchdog, @ref FLASHEx_OB_nRST_STOP, + @ref FLASHEx_OB_nRST_STDBY, @ref FLASHEx_OB_BOOT1, @ref FLASHEx_OB_VDDA_Analog_Monitoring and + @ref FLASHEx_OB_RAM_Parity_Check_Enable */ + + uint32_t DATAAddress; /*!< DATAAddress: Address of the option byte DATA to be programmed + This parameter can be a value of @ref FLASHEx_OB_Data_Address */ + + uint8_t DATAData; /*!< DATAData: Data to be stored in the option byte DATA + This parameter must be a number between Min_Data = 0x00 and Max_Data = 0xFF */ +} FLASH_OBProgramInitTypeDef; +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup FLASHEx_Exported_Constants FLASHEx Exported Constants + * @{ + */ + +/** @defgroup FLASHEx_Page_Size FLASHEx Page Size + * @{ + */ +#if defined(STM32F030x6) || defined(STM32F030x8) || defined(STM32F031x6) || defined(STM32F038xx) \ + || defined(STM32F051x8) || defined(STM32F042x6) || defined(STM32F048xx) || defined(STM32F058xx) || defined(STM32F070x6) +#define FLASH_PAGE_SIZE 0x400U +#endif /* STM32F030x6 || STM32F030x8 || STM32F031x6 || STM32F051x8 || STM32F042x6 || STM32F048xx || STM32F058xx || STM32F070x6 */ + +#if defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F078xx) || defined(STM32F070xB) \ + || defined(STM32F091xC) || defined(STM32F098xx) || defined(STM32F030xC) +#define FLASH_PAGE_SIZE 0x800U +#endif /* STM32F071xB || STM32F072xB || STM32F078xx || STM32F091xC || STM32F098xx || STM32F030xC */ +/** + * @} + */ + +/** @defgroup FLASHEx_Type_Erase FLASH Type Erase + * @{ + */ +#define FLASH_TYPEERASE_PAGES (0x00U) /*!
© Copyright (c) 2016 STMicroelectronics. + * All rights reserved.
+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F0xx_HAL_GPIO_H +#define __STM32F0xx_HAL_GPIO_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f0xx_hal_def.h" + +/** @addtogroup STM32F0xx_HAL_Driver + * @{ + */ + +/** @addtogroup GPIO + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ + +/** @defgroup GPIO_Exported_Types GPIO Exported Types + * @{ + */ +/** + * @brief GPIO Init structure definition + */ +typedef struct +{ + uint32_t Pin; /*!< Specifies the GPIO pins to be configured. + This parameter can be any value of @ref GPIO_pins */ + + uint32_t Mode; /*!< Specifies the operating mode for the selected pins. + This parameter can be a value of @ref GPIO_mode */ + + uint32_t Pull; /*!< Specifies the Pull-up or Pull-Down activation for the selected pins. + This parameter can be a value of @ref GPIO_pull */ + + uint32_t Speed; /*!< Specifies the speed for the selected pins. + This parameter can be a value of @ref GPIO_speed */ + + uint32_t Alternate; /*!< Peripheral to be connected to the selected pins + This parameter can be a value of @ref GPIOEx_Alternate_function_selection */ +}GPIO_InitTypeDef; + +/** + * @brief GPIO Bit SET and Bit RESET enumeration + */ +typedef enum +{ + GPIO_PIN_RESET = 0U, + GPIO_PIN_SET +}GPIO_PinState; +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup GPIO_Exported_Constants GPIO Exported Constants + * @{ + */ +/** @defgroup GPIO_pins GPIO pins + * @{ + */ +#define GPIO_PIN_0 ((uint16_t)0x0001U) /* Pin 0 selected */ +#define GPIO_PIN_1 ((uint16_t)0x0002U) /* Pin 1 selected */ +#define GPIO_PIN_2 ((uint16_t)0x0004U) /* Pin 2 selected */ +#define GPIO_PIN_3 ((uint16_t)0x0008U) /* Pin 3 selected */ +#define GPIO_PIN_4 ((uint16_t)0x0010U) /* Pin 4 selected */ +#define GPIO_PIN_5 ((uint16_t)0x0020U) /* Pin 5 selected */ +#define GPIO_PIN_6 ((uint16_t)0x0040U) /* Pin 6 selected */ +#define GPIO_PIN_7 ((uint16_t)0x0080U) /* Pin 7 selected */ +#define GPIO_PIN_8 ((uint16_t)0x0100U) /* Pin 8 selected */ +#define GPIO_PIN_9 ((uint16_t)0x0200U) /* Pin 9 selected */ +#define GPIO_PIN_10 ((uint16_t)0x0400U) /* Pin 10 selected */ +#define GPIO_PIN_11 ((uint16_t)0x0800U) /* Pin 11 selected */ +#define GPIO_PIN_12 ((uint16_t)0x1000U) /* Pin 12 selected */ +#define GPIO_PIN_13 ((uint16_t)0x2000U) /* Pin 13 selected */ +#define GPIO_PIN_14 ((uint16_t)0x4000U) /* Pin 14 selected */ +#define GPIO_PIN_15 ((uint16_t)0x8000U) /* Pin 15 selected */ +#define GPIO_PIN_All ((uint16_t)0xFFFFU) /* All pins selected */ + +#define GPIO_PIN_MASK (0x0000FFFFU) /* PIN mask for assert test */ +/** + * @} + */ + +/** @defgroup GPIO_mode GPIO mode + * @brief GPIO Configuration Mode + * Elements values convention: 0xX0yz00YZ + * - X : GPIO mode or EXTI Mode + * - y : External IT or Event trigger detection + * - z : IO configuration on External IT or Event + * - Y : Output type (Push Pull or Open Drain) + * - Z : IO Direction mode (Input, Output, Alternate or Analog) + * @{ + */ +#define GPIO_MODE_INPUT (0x00000000U) /*!< Input Floating Mode */ +#define GPIO_MODE_OUTPUT_PP (0x00000001U) /*!< Output Push Pull Mode */ +#define GPIO_MODE_OUTPUT_OD (0x00000011U) /*!< Output Open Drain Mode */ +#define GPIO_MODE_AF_PP (0x00000002U) /*!< Alternate Function Push Pull Mode */ +#define GPIO_MODE_AF_OD (0x00000012U) /*!< Alternate Function Open Drain Mode */ +#define GPIO_MODE_ANALOG (0x00000003U) /*!< Analog Mode */ +#define GPIO_MODE_IT_RISING (0x10110000U) /*!< External Interrupt Mode with Rising edge trigger detection */ +#define GPIO_MODE_IT_FALLING (0x10210000U) /*!< External Interrupt Mode with Falling edge trigger detection */ +#define GPIO_MODE_IT_RISING_FALLING (0x10310000U) /*!< External Interrupt Mode with Rising/Falling edge trigger detection */ +#define GPIO_MODE_EVT_RISING (0x10120000U) /*!< External Event Mode with Rising edge trigger detection */ +#define GPIO_MODE_EVT_FALLING (0x10220000U) /*!< External Event Mode with Falling edge trigger detection */ +#define GPIO_MODE_EVT_RISING_FALLING (0x10320000U) /*!< External Event Mode with Rising/Falling edge trigger detection */ +/** + * @} + */ + +/** @defgroup GPIO_speed GPIO speed + * @brief GPIO Output Maximum frequency + * @{ + */ +#define GPIO_SPEED_FREQ_LOW (0x00000000U) /*!< range up to 2 MHz, please refer to the product datasheet */ +#define GPIO_SPEED_FREQ_MEDIUM (0x00000001U) /*!< range 4 MHz to 10 MHz, please refer to the product datasheet */ +#define GPIO_SPEED_FREQ_HIGH (0x00000003U) /*!< range 10 MHz to 50 MHz, please refer to the product datasheet */ +/** + * @} + */ + + /** @defgroup GPIO_pull GPIO pull + * @brief GPIO Pull-Up or Pull-Down Activation + * @{ + */ +#define GPIO_NOPULL (0x00000000U) /*!< No Pull-up or Pull-down activation */ +#define GPIO_PULLUP (0x00000001U) /*!< Pull-up activation */ +#define GPIO_PULLDOWN (0x00000002U) /*!< Pull-down activation */ +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup GPIO_Exported_Macros GPIO Exported Macros + * @{ + */ + +/** + * @brief Check whether the specified EXTI line flag is set or not. + * @param __EXTI_LINE__ specifies the EXTI line flag to check. + * This parameter can be GPIO_PIN_x where x can be(0..15) + * @retval The new state of __EXTI_LINE__ (SET or RESET). + */ +#define __HAL_GPIO_EXTI_GET_FLAG(__EXTI_LINE__) (EXTI->PR & (__EXTI_LINE__)) + +/** + * @brief Clear the EXTI's line pending flags. + * @param __EXTI_LINE__ specifies the EXTI lines flags to clear. + * This parameter can be any combination of GPIO_PIN_x where x can be (0..15) + * @retval None + */ +#define __HAL_GPIO_EXTI_CLEAR_FLAG(__EXTI_LINE__) (EXTI->PR = (__EXTI_LINE__)) + +/** + * @brief Check whether the specified EXTI line is asserted or not. + * @param __EXTI_LINE__ specifies the EXTI line to check. + * This parameter can be GPIO_PIN_x where x can be(0..15) + * @retval The new state of __EXTI_LINE__ (SET or RESET). + */ +#define __HAL_GPIO_EXTI_GET_IT(__EXTI_LINE__) (EXTI->PR & (__EXTI_LINE__)) + +/** + * @brief Clear the EXTI's line pending bits. + * @param __EXTI_LINE__ specifies the EXTI lines to clear. + * This parameter can be any combination of GPIO_PIN_x where x can be (0..15) + * @retval None + */ +#define __HAL_GPIO_EXTI_CLEAR_IT(__EXTI_LINE__) (EXTI->PR = (__EXTI_LINE__)) + +/** + * @brief Generate a Software interrupt on selected EXTI line. + * @param __EXTI_LINE__ specifies the EXTI line to check. + * This parameter can be GPIO_PIN_x where x can be(0..15) + * @retval None + */ +#define __HAL_GPIO_EXTI_GENERATE_SWIT(__EXTI_LINE__) (EXTI->SWIER |= (__EXTI_LINE__)) + +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @addtogroup GPIO_Private_Macros GPIO Private Macros + * @{ + */ +#define IS_GPIO_PIN_ACTION(ACTION) (((ACTION) == GPIO_PIN_RESET) || ((ACTION) == GPIO_PIN_SET)) + +#define IS_GPIO_PIN(__PIN__) (((((uint32_t)__PIN__) & GPIO_PIN_MASK) != 0x00U) &&\ + ((((uint32_t)__PIN__) & ~GPIO_PIN_MASK) == 0x00U)) + +#define IS_GPIO_MODE(__MODE__) (((__MODE__) == GPIO_MODE_INPUT) ||\ + ((__MODE__) == GPIO_MODE_OUTPUT_PP) ||\ + ((__MODE__) == GPIO_MODE_OUTPUT_OD) ||\ + ((__MODE__) == GPIO_MODE_AF_PP) ||\ + ((__MODE__) == GPIO_MODE_AF_OD) ||\ + ((__MODE__) == GPIO_MODE_IT_RISING) ||\ + ((__MODE__) == GPIO_MODE_IT_FALLING) ||\ + ((__MODE__) == GPIO_MODE_IT_RISING_FALLING) ||\ + ((__MODE__) == GPIO_MODE_EVT_RISING) ||\ + ((__MODE__) == GPIO_MODE_EVT_FALLING) ||\ + ((__MODE__) == GPIO_MODE_EVT_RISING_FALLING) ||\ + ((__MODE__) == GPIO_MODE_ANALOG)) + +#define IS_GPIO_SPEED(__SPEED__) (((__SPEED__) == GPIO_SPEED_FREQ_LOW) ||\ + ((__SPEED__) == GPIO_SPEED_FREQ_MEDIUM) ||\ + ((__SPEED__) == GPIO_SPEED_FREQ_HIGH)) + +#define IS_GPIO_PULL(__PULL__) (((__PULL__) == GPIO_NOPULL) ||\ + ((__PULL__) == GPIO_PULLUP) || \ + ((__PULL__) == GPIO_PULLDOWN)) +/** + * @} + */ + +/* Include GPIO HAL Extended module */ +#include "stm32f0xx_hal_gpio_ex.h" + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup GPIO_Exported_Functions GPIO Exported Functions + * @{ + */ + +/** @addtogroup GPIO_Exported_Functions_Group1 Initialization/de-initialization functions + * @brief Initialization and Configuration functions + * @{ + */ + +/* Initialization and de-initialization functions *****************************/ +void HAL_GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *GPIO_Init); +void HAL_GPIO_DeInit(GPIO_TypeDef *GPIOx, uint32_t GPIO_Pin); + +/** + * @} + */ + +/** @addtogroup GPIO_Exported_Functions_Group2 IO operation functions + * @{ + */ + +/* IO operation functions *****************************************************/ +GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); +void HAL_GPIO_WritePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState); +void HAL_GPIO_TogglePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); +HAL_StatusTypeDef HAL_GPIO_LockPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); +void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin); +void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F0xx_HAL_GPIO_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio_ex.h b/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio_ex.h new file mode 100644 index 0000000..33b27e3 --- /dev/null +++ b/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio_ex.h @@ -0,0 +1,800 @@ +/** + ****************************************************************************** + * @file stm32f0xx_hal_gpio_ex.h + * @author MCD Application Team + * @brief Header file of GPIO HAL Extension module. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2016 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F0xx_HAL_GPIO_EX_H +#define __STM32F0xx_HAL_GPIO_EX_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f0xx_hal_def.h" + +/** @addtogroup STM32F0xx_HAL_Driver + * @{ + */ + +/** @defgroup GPIOEx GPIOEx + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ +/** @defgroup GPIOEx_Exported_Constants GPIOEx Exported Constants + * @{ + */ + +/** @defgroup GPIOEx_Alternate_function_selection GPIOEx Alternate function selection + * @{ + */ + +#if defined (STM32F030x6) +/*------------------------- STM32F030x6---------------------------*/ +/* AF 0 */ +#define GPIO_AF0_EVENTOUT ((uint8_t)0x00U) /*!< AF0: EVENTOUT Alternate Function mapping */ +#define GPIO_AF0_MCO ((uint8_t)0x00U) /*!< AF0: MCO Alternate Function mapping */ +#define GPIO_AF0_SPI1 ((uint8_t)0x00U) /*!< AF0: SPI1 Alternate Function mapping */ +#define GPIO_AF0_TIM17 ((uint8_t)0x00U) /*!< AF0: TIM17 Alternate Function mapping */ +#define GPIO_AF0_SWDIO ((uint8_t)0x00U) /*!< AF0: SWDIO Alternate Function mapping */ +#define GPIO_AF0_SWCLK ((uint8_t)0x00U) /*!< AF0: SWCLK Alternate Function mapping */ +#define GPIO_AF0_TIM14 ((uint8_t)0x00U) /*!< AF0: TIM14 Alternate Function mapping */ +#define GPIO_AF0_USART1 ((uint8_t)0x00U) /*!< AF0: USART1 Alternate Function mapping */ +#define GPIO_AF0_IR ((uint8_t)0x00U) /*!< AF0: IR Alternate Function mapping */ +#define GPIO_AF0_TIM3 ((uint8_t)0x00U) /*!< AF0: TIM3 Alternate Function mapping */ + +/* AF 1 */ +#define GPIO_AF1_TIM3 ((uint8_t)0x01U) /*!< AF1: TIM3 Alternate Function mapping */ +#define GPIO_AF1_USART1 ((uint8_t)0x01U) /*!< AF1: USART1 Alternate Function mapping */ +#define GPIO_AF1_EVENTOUT ((uint8_t)0x01U) /*!< AF1: EVENTOUT Alternate Function mapping */ +#define GPIO_AF1_I2C1 ((uint8_t)0x01U) /*!< AF1: I2C1 Alternate Function mapping */ +#define GPIO_AF1_IR ((uint8_t)0x01U) /*!< AF1: IR Alternate Function mapping */ + +/* AF 2 */ +#define GPIO_AF2_TIM1 ((uint8_t)0x02U) /*!< AF2: TIM1 Alternate Function mapping */ +#define GPIO_AF2_TIM16 ((uint8_t)0x02U) /*!< AF2: TIM16 Alternate Function mapping */ +#define GPIO_AF2_TIM17 ((uint8_t)0x02U) /*!< AF2: TIM17 Alternate Function mapping */ +#define GPIO_AF2_EVENTOUT ((uint8_t)0x02U) /*!< AF2: EVENTOUT Alternate Function mapping */ + +/* AF 3 */ +#define GPIO_AF3_EVENTOUT ((uint8_t)0x03U) /*!< AF3: EVENTOUT Alternate Function mapping */ +#define GPIO_AF3_I2C1 ((uint8_t)0x03U) /*!< AF3: I2C1 Alternate Function mapping */ + +/* AF 4 */ +#define GPIO_AF4_TIM14 ((uint8_t)0x04U) /*!< AF4: TIM14 Alternate Function mapping */ +#define GPIO_AF4_I2C1 ((uint8_t)0x04U) /*!< AF4: I2C1 Alternate Function mapping */ + +/* AF 5 */ +#define GPIO_AF5_TIM16 ((uint8_t)0x05U) /*!< AF5: TIM16 Alternate Function mapping */ +#define GPIO_AF5_TIM17 ((uint8_t)0x05U) /*!< AF5: TIM17 Alternate Function mapping */ + +/* AF 6 */ +#define GPIO_AF6_EVENTOUT ((uint8_t)0x06U) /*!< AF6: EVENTOUT Alternate Function mapping */ + +#define IS_GPIO_AF(AF) ((AF) <= (uint8_t)0x06U) + +#endif /* STM32F030x6 */ + +/*---------------------------------- STM32F030x8 -------------------------------------------*/ +#if defined (STM32F030x8) +/* AF 0 */ +#define GPIO_AF0_EVENTOUT ((uint8_t)0x00U) /*!< AF0: EVENTOUT Alternate Function mapping */ +#define GPIO_AF0_MCO ((uint8_t)0x00U) /*!< AF0: MCO Alternate Function mapping */ +#define GPIO_AF0_SPI1 ((uint8_t)0x00U) /*!< AF0: SPI1 Alternate Function mapping */ +#define GPIO_AF0_SPI2 ((uint8_t)0x00U) /*!< AF0: SPI2 Alternate Function mapping */ +#define GPIO_AF0_TIM15 ((uint8_t)0x00U) /*!< AF0: TIM15 Alternate Function mapping */ +#define GPIO_AF0_TIM17 ((uint8_t)0x00U) /*!< AF0: TIM17 Alternate Function mapping */ +#define GPIO_AF0_SWDIO ((uint8_t)0x00U) /*!< AF0: SWDIO Alternate Function mapping */ +#define GPIO_AF0_SWCLK ((uint8_t)0x00U) /*!< AF0: SWCLK Alternate Function mapping */ +#define GPIO_AF0_TIM14 ((uint8_t)0x00U) /*!< AF0: TIM14 Alternate Function mapping */ +#define GPIO_AF0_USART1 ((uint8_t)0x00U) /*!< AF0: USART1 Alternate Function mapping */ +#define GPIO_AF0_IR ((uint8_t)0x00U) /*!< AF0: IR Alternate Function mapping */ +#define GPIO_AF0_TIM3 ((uint8_t)0x00U) /*!< AF0: TIM3 Alternate Function mapping */ + +/* AF 1 */ +#define GPIO_AF1_TIM3 ((uint8_t)0x01U) /*!< AF1: TIM3 Alternate Function mapping */ +#define GPIO_AF1_TIM15 ((uint8_t)0x01U) /*!< AF1: TIM15 Alternate Function mapping */ +#define GPIO_AF1_USART1 ((uint8_t)0x01U) /*!< AF1: USART1 Alternate Function mapping */ +#define GPIO_AF1_USART2 ((uint8_t)0x01U) /*!< AF1: USART2 Alternate Function mapping */ +#define GPIO_AF1_EVENTOUT ((uint8_t)0x01U) /*!< AF1: EVENTOUT Alternate Function mapping */ +#define GPIO_AF1_I2C1 ((uint8_t)0x01U) /*!< AF1: I2C1 Alternate Function mapping */ +#define GPIO_AF1_I2C2 ((uint8_t)0x01U) /*!< AF1: I2C2 Alternate Function mapping */ +#define GPIO_AF1_IR ((uint8_t)0x01U) /*!< AF1: IR Alternate Function mapping */ + +/* AF 2 */ +#define GPIO_AF2_TIM1 ((uint8_t)0x02U) /*!< AF2: TIM1 Alternate Function mapping */ +#define GPIO_AF2_TIM16 ((uint8_t)0x02U) /*!< AF2: TIM16 Alternate Function mapping */ +#define GPIO_AF2_TIM17 ((uint8_t)0x02U) /*!< AF2: TIM17 Alternate Function mapping */ +#define GPIO_AF2_EVENTOUT ((uint8_t)0x02U) /*!< AF2: EVENTOUT Alternate Function mapping */ + +/* AF 3 */ +#define GPIO_AF3_EVENTOUT ((uint8_t)0x03U) /*!< AF3: EVENTOUT Alternate Function mapping */ +#define GPIO_AF3_I2C1 ((uint8_t)0x03U) /*!< AF3: I2C1 Alternate Function mapping */ +#define GPIO_AF3_TIM15 ((uint8_t)0x03U) /*!< AF3: TIM15 Alternate Function mapping */ + +/* AF 4 */ +#define GPIO_AF4_TIM14 ((uint8_t)0x04U) /*!< AF4: TIM14 Alternate Function mapping */ + +/* AF 5 */ +#define GPIO_AF5_TIM16 ((uint8_t)0x05U) /*!< AF5: TIM16 Alternate Function mapping */ +#define GPIO_AF5_TIM17 ((uint8_t)0x05U) /*!< AF5: TIM17 Alternate Function mapping */ + +/* AF 6 */ +#define GPIO_AF6_EVENTOUT ((uint8_t)0x06U) /*!< AF6: EVENTOUT Alternate Function mapping */ + +#define IS_GPIO_AF(AF) ((AF) <= (uint8_t)0x06U) + +#endif /* STM32F030x8 */ + +#if defined (STM32F031x6) || defined (STM32F038xx) +/*--------------------------- STM32F031x6/STM32F038xx ---------------------------*/ +/* AF 0 */ +#define GPIO_AF0_EVENTOUT ((uint8_t)0x00U) /*!< AF0: EVENTOUT Alternate Function mapping */ +#define GPIO_AF0_MCO ((uint8_t)0x00U) /*!< AF0: MCO Alternate Function mapping */ +#define GPIO_AF0_SPI1 ((uint8_t)0x00U) /*!< AF0: SPI1/I2S1 Alternate Function mapping */ +#define GPIO_AF0_TIM17 ((uint8_t)0x00U) /*!< AF0: TIM17 Alternate Function mapping */ +#define GPIO_AF0_SWDAT ((uint8_t)0x00U) /*!< AF0: SWDAT Alternate Function mapping */ +#define GPIO_AF0_SWCLK ((uint8_t)0x00U) /*!< AF0: SWCLK Alternate Function mapping */ +#define GPIO_AF0_TIM14 ((uint8_t)0x00U) /*!< AF0: TIM14 Alternate Function mapping */ +#define GPIO_AF0_USART1 ((uint8_t)0x00U) /*!< AF0: USART1 Alternate Function mapping */ +#define GPIO_AF0_IR ((uint8_t)0x00U) /*!< AF0: IR Alternate Function mapping */ + +/* AF 1 */ +#define GPIO_AF1_TIM3 ((uint8_t)0x01U) /*!< AF1: TIM3 Alternate Function mapping */ +#define GPIO_AF1_USART1 ((uint8_t)0x01U) /*!< AF1: USART1 Alternate Function mapping */ +#define GPIO_AF1_IR ((uint8_t)0x01U) /*!< AF1: IR Alternate Function mapping */ +#define GPIO_AF1_EVENTOUT ((uint8_t)0x01U) /*!< AF1: EVENTOUT Alternate Function mapping */ +#define GPIO_AF1_I2C1 ((uint8_t)0x01U) /*!< AF1: I2C1 Alternate Function mapping */ + +/* AF 2 */ +#define GPIO_AF2_TIM1 ((uint8_t)0x02U) /*!< AF2: TIM1 Alternate Function mapping */ +#define GPIO_AF2_TIM2 ((uint8_t)0x02U) /*!< AF2: TIM2 Alternate Function mapping */ +#define GPIO_AF2_TIM16 ((uint8_t)0x02U) /*!< AF2: TIM16 Alternate Function mapping */ +#define GPIO_AF2_TIM17 ((uint8_t)0x02U) /*!< AF2: TIM17 Alternate Function mapping */ +#define GPIO_AF2_EVENTOUT ((uint8_t)0x02U) /*!< AF2: EVENTOUT Alternate Function mapping */ + +/* AF 3 */ +#define GPIO_AF3_EVENTOUT ((uint8_t)0x03U) /*!< AF3: EVENTOUT Alternate Function mapping */ +#define GPIO_AF3_I2C1 ((uint8_t)0x03U) /*!< AF3: I2C1 Alternate Function mapping */ + +/* AF 4 */ +#define GPIO_AF4_TIM14 ((uint8_t)0x04U) /*!< AF4: TIM14 Alternate Function mapping */ +#define GPIO_AF4_I2C1 ((uint8_t)0x04U) /*!< AF4: I2C1 Alternate Function mapping */ + +/* AF 5 */ +#define GPIO_AF5_TIM16 ((uint8_t)0x05U) /*!< AF5: TIM16 Alternate Function mapping */ +#define GPIO_AF5_TIM17 ((uint8_t)0x05U) /*!< AF5: TIM17 Alternate Function mapping */ + +/* AF 6 */ +#define GPIO_AF6_EVENTOUT ((uint8_t)0x06U) /*!< AF6: EVENTOUT Alternate Function mapping */ + +#define IS_GPIO_AF(AF) ((AF) <= (uint8_t)0x06U) + +#endif /* STM32F031x6 || STM32F038xx */ + +#if defined (STM32F051x8) || defined (STM32F058xx) +/*--------------------------- STM32F051x8/STM32F058xx---------------------------*/ +/* AF 0 */ +#define GPIO_AF0_EVENTOUT ((uint8_t)0x00U) /*!< AF0: EVENTOUT Alternate Function mapping */ +#define GPIO_AF0_MCO ((uint8_t)0x00U) /*!< AF0: MCO Alternate Function mapping */ +#define GPIO_AF0_SPI1 ((uint8_t)0x00U) /*!< AF0: SPI1/I2S1 Alternate Function mapping */ +#define GPIO_AF0_SPI2 ((uint8_t)0x00U) /*!< AF0: SPI2 Alternate Function mapping */ +#define GPIO_AF0_TIM15 ((uint8_t)0x00U) /*!< AF0: TIM15 Alternate Function mapping */ +#define GPIO_AF0_TIM17 ((uint8_t)0x00U) /*!< AF0: TIM17 Alternate Function mapping */ +#define GPIO_AF0_SWDIO ((uint8_t)0x00U) /*!< AF0: SWDIO Alternate Function mapping */ +#define GPIO_AF0_SWCLK ((uint8_t)0x00U) /*!< AF0: SWCLK Alternate Function mapping */ +#define GPIO_AF0_TIM14 ((uint8_t)0x00U) /*!< AF0: TIM14 Alternate Function mapping */ +#define GPIO_AF0_USART1 ((uint8_t)0x00U) /*!< AF0: USART1 Alternate Function mapping */ +#define GPIO_AF0_IR ((uint8_t)0x00U) /*!< AF0: IR Alternate Function mapping */ +#define GPIO_AF0_CEC ((uint8_t)0x00U) /*!< AF0: CEC Alternate Function mapping */ + +/* AF 1 */ +#define GPIO_AF1_TIM3 ((uint8_t)0x01U) /*!< AF1: TIM3 Alternate Function mapping */ +#define GPIO_AF1_TIM15 ((uint8_t)0x01U) /*!< AF1: TIM15 Alternate Function mapping */ +#define GPIO_AF1_USART1 ((uint8_t)0x01U) /*!< AF1: USART1 Alternate Function mapping */ +#define GPIO_AF1_USART2 ((uint8_t)0x01U) /*!< AF1: USART2 Alternate Function mapping */ +#define GPIO_AF1_EVENTOUT ((uint8_t)0x01U) /*!< AF1: EVENTOUT Alternate Function mapping */ +#define GPIO_AF1_I2C1 ((uint8_t)0x01U) /*!< AF1: I2C1 Alternate Function mapping */ +#define GPIO_AF1_I2C2 ((uint8_t)0x01U) /*!< AF1: I2C2 Alternate Function mapping */ +#define GPIO_AF1_IR ((uint8_t)0x01U) /*!< AF1: IR Alternate Function mapping */ +#define GPIO_AF1_CEC ((uint8_t)0x01U) /*!< AF1: CEC Alternate Function mapping */ + +/* AF 2 */ +#define GPIO_AF2_TIM1 ((uint8_t)0x02U) /*!< AF2: TIM1 Alternate Function mapping */ +#define GPIO_AF2_TIM2 ((uint8_t)0x02U) /*!< AF2: TIM2 Alternate Function mapping */ +#define GPIO_AF2_TIM16 ((uint8_t)0x02U) /*!< AF2: TIM16 Alternate Function mapping */ +#define GPIO_AF2_TIM17 ((uint8_t)0x02U) /*!< AF2: TIM17 Alternate Function mapping */ +#define GPIO_AF2_EVENTOUT ((uint8_t)0x02U) /*!< AF2: EVENTOUT Alternate Function mapping */ + +/* AF 3 */ +#define GPIO_AF3_EVENTOUT ((uint8_t)0x03U) /*!< AF3: EVENTOUT Alternate Function mapping */ +#define GPIO_AF3_I2C1 ((uint8_t)0x03U) /*!< AF3: I2C1 Alternate Function mapping */ +#define GPIO_AF3_TIM15 ((uint8_t)0x03U) /*!< AF3: TIM15 Alternate Function mapping */ +#define GPIO_AF3_TSC ((uint8_t)0x03U) /*!< AF3: TSC Alternate Function mapping */ + +/* AF 4 */ +#define GPIO_AF4_TIM14 ((uint8_t)0x04U) /*!< AF4: TIM14 Alternate Function mapping */ + +/* AF 5 */ +#define GPIO_AF5_TIM16 ((uint8_t)0x05U) /*!< AF5: TIM16 Alternate Function mapping */ +#define GPIO_AF5_TIM17 ((uint8_t)0x05U) /*!< AF5: TIM17 Alternate Function mapping */ + +/* AF 6 */ +#define GPIO_AF6_EVENTOUT ((uint8_t)0x06U) /*!< AF6: EVENTOUT Alternate Function mapping */ + +/* AF 7 */ +#define GPIO_AF7_COMP1 ((uint8_t)0x07U) /*!< AF7: COMP1 Alternate Function mapping */ +#define GPIO_AF7_COMP2 ((uint8_t)0x07U) /*!< AF7: COMP2 Alternate Function mapping */ + +#define IS_GPIO_AF(AF) ((AF) <= (uint8_t)0x07U) + +#endif /* STM32F051x8/STM32F058xx */ + +#if defined (STM32F071xB) +/*--------------------------- STM32F071xB ---------------------------*/ +/* AF 0 */ +#define GPIO_AF0_EVENTOUT ((uint8_t)0x00U) /*!< AF0: AEVENTOUT Alternate Function mapping */ +#define GPIO_AF0_SWDIO ((uint8_t)0x00U) /*!< AF0: SWDIO Alternate Function mapping */ +#define GPIO_AF0_SWCLK ((uint8_t)0x00U) /*!< AF0: SWCLK Alternate Function mapping */ +#define GPIO_AF0_MCO ((uint8_t)0x00U) /*!< AF0: MCO Alternate Function mapping */ +#define GPIO_AF0_CEC ((uint8_t)0x00U) /*!< AF0: CEC Alternate Function mapping */ +#define GPIO_AF0_CRS ((uint8_t)0x00U) /*!< AF0: CRS Alternate Function mapping */ +#define GPIO_AF0_IR ((uint8_t)0x00U) /*!< AF0: IR Alternate Function mapping */ +#define GPIO_AF0_SPI1 ((uint8_t)0x00U) /*!< AF0: SPI1/I2S1 Alternate Function mapping */ +#define GPIO_AF0_SPI2 ((uint8_t)0x00U) /*!< AF0: SPI2/I2S2 Alternate Function mapping */ +#define GPIO_AF0_TIM1 ((uint8_t)0x00U) /*!< AF0: TIM1 Alternate Function mapping */ +#define GPIO_AF0_TIM3 ((uint8_t)0x00U) /*!< AF0: TIM3 Alternate Function mapping */ +#define GPIO_AF0_TIM14 ((uint8_t)0x00U) /*!< AF0: TIM14 Alternate Function mapping */ +#define GPIO_AF0_TIM15 ((uint8_t)0x00U) /*!< AF0: TIM15 Alternate Function mapping */ +#define GPIO_AF0_TIM16 ((uint8_t)0x00U) /*!< AF0: TIM16 Alternate Function mapping */ +#define GPIO_AF0_TIM17 ((uint8_t)0x00U) /*!< AF0: TIM17 Alternate Function mapping */ +#define GPIO_AF0_TSC ((uint8_t)0x00U) /*!< AF0: TSC Alternate Function mapping */ +#define GPIO_AF0_USART1 ((uint8_t)0x00U) /*!< AF0: USART1 Alternate Function mapping */ +#define GPIO_AF0_USART2 ((uint8_t)0x00U) /*!< AF0: USART2 Alternate Function mapping */ +#define GPIO_AF0_USART3 ((uint8_t)0x00U) /*!< AF0: USART3 Alternate Function mapping */ +#define GPIO_AF0_USART4 ((uint8_t)0x00U) /*!< AF0: USART4 Alternate Function mapping */ + +/* AF 1 */ +#define GPIO_AF1_TIM3 ((uint8_t)0x01U) /*!< AF1: TIM3 Alternate Function mapping */ +#define GPIO_AF1_TIM15 ((uint8_t)0x01U) /*!< AF1: TIM15 Alternate Function mapping */ +#define GPIO_AF1_USART1 ((uint8_t)0x01U) /*!< AF1: USART1 Alternate Function mapping */ +#define GPIO_AF1_USART2 ((uint8_t)0x01U) /*!< AF1: USART2 Alternate Function mapping */ +#define GPIO_AF1_USART3 ((uint8_t)0x01U) /*!< AF1: USART3 Alternate Function mapping */ +#define GPIO_AF1_IR ((uint8_t)0x01U) /*!< AF1: IR Alternate Function mapping */ +#define GPIO_AF1_CEC ((uint8_t)0x01U) /*!< AF1: CEC Alternate Function mapping */ +#define GPIO_AF1_EVENTOUT ((uint8_t)0x01U) /*!< AF1: EVENTOUT Alternate Function mapping */ +#define GPIO_AF1_I2C1 ((uint8_t)0x01U) /*!< AF1: I2C1 Alternate Function mapping */ +#define GPIO_AF1_I2C2 ((uint8_t)0x01U) /*!< AF1: I2C2 Alternate Function mapping */ +#define GPIO_AF1_TSC ((uint8_t)0x01U) /*!< AF1: TSC Alternate Function mapping */ +#define GPIO_AF1_SPI1 ((uint8_t)0x01U) /*!< AF1: SPI1 Alternate Function mapping */ +#define GPIO_AF1_SPI2 ((uint8_t)0x01U) /*!< AF1: SPI2 Alternate Function mapping */ + +/* AF 2 */ +#define GPIO_AF2_TIM1 ((uint8_t)0x02U) /*!< AF2: TIM1 Alternate Function mapping */ +#define GPIO_AF2_TIM2 ((uint8_t)0x02U) /*!< AF2: TIM2 Alternate Function mapping */ +#define GPIO_AF2_TIM16 ((uint8_t)0x02U) /*!< AF2: TIM16 Alternate Function mapping */ +#define GPIO_AF2_TIM17 ((uint8_t)0x02U) /*!< AF2: TIM17 Alternate Function mapping */ +#define GPIO_AF2_EVENTOUT ((uint8_t)0x02U) /*!< AF2: EVENTOUT Alternate Function mapping */ + +/* AF 3 */ +#define GPIO_AF3_EVENTOUT ((uint8_t)0x03U) /*!< AF3: EVENTOUT Alternate Function mapping */ +#define GPIO_AF3_TSC ((uint8_t)0x03U) /*!< AF3: TSC Alternate Function mapping */ +#define GPIO_AF3_TIM15 ((uint8_t)0x03U) /*!< AF3: TIM15 Alternate Function mapping */ +#define GPIO_AF3_I2C1 ((uint8_t)0x03U) /*!< AF3: I2C1 Alternate Function mapping */ + +/* AF 4 */ +#define GPIO_AF4_TIM14 ((uint8_t)0x04U) /*!< AF4: TIM14 Alternate Function mapping */ +#define GPIO_AF4_USART4 ((uint8_t)0x04U) /*!< AF4: USART4 Alternate Function mapping */ +#define GPIO_AF4_USART3 ((uint8_t)0x04U) /*!< AF4: USART3 Alternate Function mapping */ +#define GPIO_AF4_CRS ((uint8_t)0x04U) /*!< AF4: CRS Alternate Function mapping */ + +/* AF 5 */ +#define GPIO_AF5_TIM15 ((uint8_t)0x05U) /*!< AF5: TIM15 Alternate Function mapping */ +#define GPIO_AF5_TIM16 ((uint8_t)0x05U) /*!< AF5: TIM16 Alternate Function mapping */ +#define GPIO_AF5_TIM17 ((uint8_t)0x05U) /*!< AF5: TIM17 Alternate Function mapping */ +#define GPIO_AF5_SPI2 ((uint8_t)0x05U) /*!< AF5: SPI2 Alternate Function mapping */ +#define GPIO_AF5_I2C2 ((uint8_t)0x05U) /*!< AF5: I2C2 Alternate Function mapping */ + +/* AF 6 */ +#define GPIO_AF6_EVENTOUT ((uint8_t)0x06U) /*!< AF6: EVENTOUT Alternate Function mapping */ + +/* AF 7 */ +#define GPIO_AF7_COMP1 ((uint8_t)0x07U) /*!< AF7: COMP1 Alternate Function mapping */ +#define GPIO_AF7_COMP2 ((uint8_t)0x07U) /*!< AF7: COMP2 Alternate Function mapping */ + +#define IS_GPIO_AF(AF) ((AF) <= (uint8_t)0x07U) + +#endif /* STM32F071xB */ + + +#if defined(STM32F091xC) || defined(STM32F098xx) +/*--------------------------- STM32F091xC || STM32F098xx ------------------------------*/ +/* AF 0 */ +#define GPIO_AF0_EVENTOUT ((uint8_t)0x00U) /*!< AF0: EVENTOUT Alternate Function mapping */ +#define GPIO_AF0_SWDIO ((uint8_t)0x00U) /*!< AF0: SWDIO Alternate Function mapping */ +#define GPIO_AF0_SWCLK ((uint8_t)0x00U) /*!< AF0: SWCLK Alternate Function mapping */ +#define GPIO_AF0_MCO ((uint8_t)0x00U) /*!< AF0: MCO Alternate Function mapping */ +#define GPIO_AF0_CEC ((uint8_t)0x00U) /*!< AF0: CEC Alternate Function mapping */ +#define GPIO_AF0_CRS ((uint8_t)0x00U) /*!< AF0: CRS Alternate Function mapping */ +#define GPIO_AF0_IR ((uint8_t)0x00U) /*!< AF0: IR Alternate Function mapping */ +#define GPIO_AF0_SPI1 ((uint8_t)0x00U) /*!< AF0: SPI1/I2S1 Alternate Function mapping */ +#define GPIO_AF0_SPI2 ((uint8_t)0x00U) /*!< AF0: SPI2/I2S2 Alternate Function mapping */ +#define GPIO_AF0_TIM1 ((uint8_t)0x00U) /*!< AF0: TIM1 Alternate Function mapping */ +#define GPIO_AF0_TIM3 ((uint8_t)0x00U) /*!< AF0: TIM3 Alternate Function mapping */ +#define GPIO_AF0_TIM14 ((uint8_t)0x00U) /*!< AF0: TIM14 Alternate Function mapping */ +#define GPIO_AF0_TIM15 ((uint8_t)0x00U) /*!< AF0: TIM15 Alternate Function mapping */ +#define GPIO_AF0_TIM16 ((uint8_t)0x00U) /*!< AF0: TIM16 Alternate Function mapping */ +#define GPIO_AF0_TIM17 ((uint8_t)0x00U) /*!< AF0: TIM17 Alternate Function mapping */ +#define GPIO_AF0_TSC ((uint8_t)0x00U) /*!< AF0: TSC Alternate Function mapping */ +#define GPIO_AF0_USART1 ((uint8_t)0x00U) /*!< AF0: USART1 Alternate Function mapping */ +#define GPIO_AF0_USART2 ((uint8_t)0x00U) /*!< AF0: USART2 Alternate Function mapping */ +#define GPIO_AF0_USART3 ((uint8_t)0x00U) /*!< AF0: USART3 Alternate Function mapping */ +#define GPIO_AF0_USART4 ((uint8_t)0x00U) /*!< AF0: USART4 Alternate Function mapping */ +#define GPIO_AF0_USART8 ((uint8_t)0x00U) /*!< AF0: USART8 Alternate Function mapping */ +#define GPIO_AF0_CAN ((uint8_t)0x00U) /*!< AF0: CAN Alternate Function mapping */ + +/* AF 1 */ +#define GPIO_AF1_TIM3 ((uint8_t)0x01U) /*!< AF1: TIM3 Alternate Function mapping */ +#define GPIO_AF1_TIM15 ((uint8_t)0x01U) /*!< AF1: TIM15 Alternate Function mapping */ +#define GPIO_AF1_USART1 ((uint8_t)0x01U) /*!< AF1: USART1 Alternate Function mapping */ +#define GPIO_AF1_USART2 ((uint8_t)0x01U) /*!< AF1: USART2 Alternate Function mapping */ +#define GPIO_AF1_USART3 ((uint8_t)0x01U) /*!< AF1: USART3 Alternate Function mapping */ +#define GPIO_AF1_USART4 ((uint8_t)0x01U) /*!< AF1: USART4 Alternate Function mapping */ +#define GPIO_AF1_USART5 ((uint8_t)0x01U) /*!< AF1: USART5 Alternate Function mapping */ +#define GPIO_AF1_USART6 ((uint8_t)0x01U) /*!< AF1: USART6 Alternate Function mapping */ +#define GPIO_AF1_USART7 ((uint8_t)0x01U) /*!< AF1: USART7 Alternate Function mapping */ +#define GPIO_AF1_USART8 ((uint8_t)0x01U) /*!< AF1: USART8 Alternate Function mapping */ +#define GPIO_AF1_IR ((uint8_t)0x01U) /*!< AF1: IR Alternate Function mapping */ +#define GPIO_AF1_CEC ((uint8_t)0x01U) /*!< AF1: CEC Alternate Function mapping */ +#define GPIO_AF1_EVENTOUT ((uint8_t)0x01U) /*!< AF1: EVENTOUT Alternate Function mapping */ +#define GPIO_AF1_I2C1 ((uint8_t)0x01U) /*!< AF1: I2C1 Alternate Function mapping */ +#define GPIO_AF1_I2C2 ((uint8_t)0x01U) /*!< AF1: I2C2 Alternate Function mapping */ +#define GPIO_AF1_TSC ((uint8_t)0x01U) /*!< AF1: TSC Alternate Function mapping */ +#define GPIO_AF1_SPI1 ((uint8_t)0x01U) /*!< AF1: SPI1 Alternate Function mapping */ +#define GPIO_AF1_SPI2 ((uint8_t)0x01U) /*!< AF1: SPI2 Alternate Function mapping */ + +/* AF 2 */ +#define GPIO_AF2_TIM1 ((uint8_t)0x02U) /*!< AF2: TIM1 Alternate Function mapping */ +#define GPIO_AF2_TIM2 ((uint8_t)0x02U) /*!< AF2: TIM2 Alternate Function mapping */ +#define GPIO_AF2_TIM16 ((uint8_t)0x02U) /*!< AF2: TIM16 Alternate Function mapping */ +#define GPIO_AF2_TIM17 ((uint8_t)0x02U) /*!< AF2: TIM17 Alternate Function mapping */ +#define GPIO_AF2_EVENTOUT ((uint8_t)0x02U) /*!< AF2: EVENTOUT Alternate Function mapping */ +#define GPIO_AF2_USART5 ((uint8_t)0x02U) /*!< AF2: USART5 Alternate Function mapping */ +#define GPIO_AF2_USART6 ((uint8_t)0x02U) /*!< AF2: USART6 Alternate Function mapping */ +#define GPIO_AF2_USART7 ((uint8_t)0x02U) /*!< AF2: USART7 Alternate Function mapping */ +#define GPIO_AF2_USART8 ((uint8_t)0x02U) /*!< AF2: USART8 Alternate Function mapping */ + +/* AF 3 */ +#define GPIO_AF3_EVENTOUT ((uint8_t)0x03U) /*!< AF3: EVENTOUT Alternate Function mapping */ +#define GPIO_AF3_TSC ((uint8_t)0x03U) /*!< AF3: TSC Alternate Function mapping */ +#define GPIO_AF3_TIM15 ((uint8_t)0x03U) /*!< AF3: TIM15 Alternate Function mapping */ +#define GPIO_AF3_I2C1 ((uint8_t)0x03U) /*!< AF3: I2C1 Alternate Function mapping */ + +/* AF 4 */ +#define GPIO_AF4_TIM14 ((uint8_t)0x04U) /*!< AF4: TIM14 Alternate Function mapping */ +#define GPIO_AF4_USART4 ((uint8_t)0x04U) /*!< AF4: USART4 Alternate Function mapping */ +#define GPIO_AF4_USART3 ((uint8_t)0x04U) /*!< AF4: USART3 Alternate Function mapping */ +#define GPIO_AF4_CRS ((uint8_t)0x04U) /*!< AF4: CRS Alternate Function mapping */ +#define GPIO_AF4_CAN ((uint8_t)0x04U) /*!< AF4: CAN Alternate Function mapping */ +#define GPIO_AF4_I2C1 ((uint8_t)0x04U) /*!< AF4: I2C1 Alternate Function mapping */ +#define GPIO_AF4_USART5 ((uint8_t)0x04U) /*!< AF4: USART5 Alternate Function mapping */ + +/* AF 5 */ +#define GPIO_AF5_TIM15 ((uint8_t)0x05U) /*!< AF5: TIM15 Alternate Function mapping */ +#define GPIO_AF5_TIM16 ((uint8_t)0x05U) /*!< AF5: TIM16 Alternate Function mapping */ +#define GPIO_AF5_TIM17 ((uint8_t)0x05U) /*!< AF5: TIM17 Alternate Function mapping */ +#define GPIO_AF5_SPI2 ((uint8_t)0x05U) /*!< AF5: SPI2 Alternate Function mapping */ +#define GPIO_AF5_I2C2 ((uint8_t)0x05U) /*!< AF5: I2C2 Alternate Function mapping */ +#define GPIO_AF5_MCO ((uint8_t)0x05U) /*!< AF5: MCO Alternate Function mapping */ +#define GPIO_AF5_USART6 ((uint8_t)0x05U) /*!< AF5: USART6 Alternate Function mapping */ + +/* AF 6 */ +#define GPIO_AF6_EVENTOUT ((uint8_t)0x06U) /*!< AF6: EVENTOUT Alternate Function mapping */ + +/* AF 7 */ +#define GPIO_AF7_COMP1 ((uint8_t)0x07U) /*!< AF7: COMP1 Alternate Function mapping */ +#define GPIO_AF7_COMP2 ((uint8_t)0x07U) /*!< AF7: COMP2 Alternate Function mapping */ + +#define IS_GPIO_AF(AF) ((AF) <= (uint8_t)0x07U) + +#endif /* STM32F091xC || STM32F098xx */ + +#if defined(STM32F030xC) +/*--------------------------- STM32F030xC ----------------------------------------------------*/ +/* AF 0 */ +#define GPIO_AF0_EVENTOUT ((uint8_t)0x00U) /*!< AF0: EVENTOUT Alternate Function mapping */ +#define GPIO_AF0_SWDIO ((uint8_t)0x00U) /*!< AF0: SWDIO Alternate Function mapping */ +#define GPIO_AF0_SWCLK ((uint8_t)0x00U) /*!< AF0: SWCLK Alternate Function mapping */ +#define GPIO_AF0_MCO ((uint8_t)0x00U) /*!< AF0: MCO Alternate Function mapping */ +#define GPIO_AF0_IR ((uint8_t)0x00U) /*!< AF0: IR Alternate Function mapping */ +#define GPIO_AF0_SPI1 ((uint8_t)0x00U) /*!< AF0: SPI1 Alternate Function mapping */ +#define GPIO_AF0_SPI2 ((uint8_t)0x00U) /*!< AF0: SPI2 Alternate Function mapping */ +#define GPIO_AF0_TIM3 ((uint8_t)0x00U) /*!< AF0: TIM3 Alternate Function mapping */ +#define GPIO_AF0_TIM14 ((uint8_t)0x00U) /*!< AF0: TIM14 Alternate Function mapping */ +#define GPIO_AF0_TIM15 ((uint8_t)0x00U) /*!< AF0: TIM15 Alternate Function mapping */ +#define GPIO_AF0_TIM17 ((uint8_t)0x00U) /*!< AF0: TIM17 Alternate Function mapping */ +#define GPIO_AF0_USART1 ((uint8_t)0x00U) /*!< AF0: USART1 Alternate Function mapping */ +#define GPIO_AF0_USART4 ((uint8_t)0x00U) /*!< AF0: USART4 Alternate Function mapping */ + +/* AF 1 */ +#define GPIO_AF1_TIM3 ((uint8_t)0x01U) /*!< AF1: TIM3 Alternate Function mapping */ +#define GPIO_AF1_TIM15 ((uint8_t)0x01U) /*!< AF1: TIM15 Alternate Function mapping */ +#define GPIO_AF1_USART1 ((uint8_t)0x01U) /*!< AF1: USART1 Alternate Function mapping */ +#define GPIO_AF1_USART2 ((uint8_t)0x01U) /*!< AF1: USART2 Alternate Function mapping */ +#define GPIO_AF1_USART3 ((uint8_t)0x01U) /*!< AF1: USART3 Alternate Function mapping */ +#define GPIO_AF1_IR ((uint8_t)0x01U) /*!< AF1: IR Alternate Function mapping */ +#define GPIO_AF1_EVENTOUT ((uint8_t)0x01U) /*!< AF1: EVENTOUT Alternate Function mapping */ +#define GPIO_AF1_I2C1 ((uint8_t)0x01U) /*!< AF1: I2C1 Alternate Function mapping */ +#define GPIO_AF1_I2C2 ((uint8_t)0x01U) /*!< AF1: I2C2 Alternate Function mapping */ +#define GPIO_AF1_SPI2 ((uint8_t)0x01U) /*!< AF1: SPI2 Alternate Function mapping */ + +/* AF 2 */ +#define GPIO_AF2_TIM1 ((uint8_t)0x02U) /*!< AF2: TIM1 Alternate Function mapping */ +#define GPIO_AF2_TIM16 ((uint8_t)0x02U) /*!< AF2: TIM16 Alternate Function mapping */ +#define GPIO_AF2_TIM17 ((uint8_t)0x02U) /*!< AF2: TIM17 Alternate Function mapping */ +#define GPIO_AF2_EVENTOUT ((uint8_t)0x02U) /*!< AF2: EVENTOUT Alternate Function mapping */ +#define GPIO_AF2_USART5 ((uint8_t)0x02U) /*!< AF2: USART5 Alternate Function mapping */ +#define GPIO_AF2_USART6 ((uint8_t)0x02U) /*!< AF2: USART6 Alternate Function mapping */ + +/* AF 3 */ +#define GPIO_AF3_EVENTOUT ((uint8_t)0x03U) /*!< AF3: EVENTOUT Alternate Function mapping */ +#define GPIO_AF3_TIM15 ((uint8_t)0x03U) /*!< AF3: TIM15 Alternate Function mapping */ +#define GPIO_AF3_I2C1 ((uint8_t)0x03U) /*!< AF3: I2C1 Alternate Function mapping */ + +/* AF 4 */ +#define GPIO_AF4_TIM14 ((uint8_t)0x04U) /*!< AF4: TIM14 Alternate Function mapping */ +#define GPIO_AF4_USART4 ((uint8_t)0x04U) /*!< AF4: USART4 Alternate Function mapping */ +#define GPIO_AF4_USART3 ((uint8_t)0x04U) /*!< AF4: USART3 Alternate Function mapping */ +#define GPIO_AF4_I2C1 ((uint8_t)0x04U) /*!< AF4: I2C1 Alternate Function mapping */ +#define GPIO_AF4_USART5 ((uint8_t)0x04U) /*!< AF4: USART5 Alternate Function mapping */ + +/* AF 5 */ +#define GPIO_AF5_TIM15 ((uint8_t)0x05U) /*!< AF5: TIM15 Alternate Function mapping */ +#define GPIO_AF5_TIM16 ((uint8_t)0x05U) /*!< AF5: TIM16 Alternate Function mapping */ +#define GPIO_AF5_TIM17 ((uint8_t)0x05U) /*!< AF5: TIM17 Alternate Function mapping */ +#define GPIO_AF5_SPI2 ((uint8_t)0x05U) /*!< AF5: SPI2 Alternate Function mapping */ +#define GPIO_AF5_I2C2 ((uint8_t)0x05U) /*!< AF5: I2C2 Alternate Function mapping */ +#define GPIO_AF5_MCO ((uint8_t)0x05U) /*!< AF5: MCO Alternate Function mapping */ +#define GPIO_AF5_USART6 ((uint8_t)0x05U) /*!< AF5: USART6 Alternate Function mapping */ + +/* AF 6 */ +#define GPIO_AF6_EVENTOUT ((uint8_t)0x06U) /*!< AF6: EVENTOUT Alternate Function mapping */ + +#define IS_GPIO_AF(AF) ((AF) <= (uint8_t)0x06U) + +#endif /* STM32F030xC */ + +#if defined (STM32F072xB) || defined (STM32F078xx) +/*--------------------------- STM32F072xB/STM32F078xx ---------------------------*/ +/* AF 0 */ +#define GPIO_AF0_EVENTOUT ((uint8_t)0x00U) /*!< AF0: EVENTOUT Alternate Function mapping */ +#define GPIO_AF0_SWDIO ((uint8_t)0x00U) /*!< AF0: SWDIO Alternate Function mapping */ +#define GPIO_AF0_SWCLK ((uint8_t)0x00U) /*!< AF0: SWCLK Alternate Function mapping */ +#define GPIO_AF0_MCO ((uint8_t)0x00U) /*!< AF0: MCO Alternate Function mapping */ +#define GPIO_AF0_CEC ((uint8_t)0x00U) /*!< AF0: CEC Alternate Function mapping */ +#define GPIO_AF0_CRS ((uint8_t)0x00U) /*!< AF0: CRS Alternate Function mapping */ +#define GPIO_AF0_IR ((uint8_t)0x00U) /*!< AF0: IR Alternate Function mapping */ +#define GPIO_AF0_SPI1 ((uint8_t)0x00U) /*!< AF0: SPI1/I2S1 Alternate Function mapping */ +#define GPIO_AF0_SPI2 ((uint8_t)0x00U) /*!< AF0: SPI2/I2S2 Alternate Function mapping */ +#define GPIO_AF0_TIM1 ((uint8_t)0x00U) /*!< AF0: TIM1 Alternate Function mapping */ +#define GPIO_AF0_TIM3 ((uint8_t)0x00U) /*!< AF0: TIM3 Alternate Function mapping */ +#define GPIO_AF0_TIM14 ((uint8_t)0x00U) /*!< AF0: TIM14 Alternate Function mapping */ +#define GPIO_AF0_TIM15 ((uint8_t)0x00U) /*!< AF0: TIM15 Alternate Function mapping */ +#define GPIO_AF0_TIM16 ((uint8_t)0x00U) /*!< AF0: TIM16 Alternate Function mapping */ +#define GPIO_AF0_TIM17 ((uint8_t)0x00U) /*!< AF0: TIM17 Alternate Function mapping */ +#define GPIO_AF0_TSC ((uint8_t)0x00U) /*!< AF0: TSC Alternate Function mapping */ +#define GPIO_AF0_USART1 ((uint8_t)0x00U) /*!< AF0: USART1 Alternate Function mapping */ +#define GPIO_AF0_USART2 ((uint8_t)0x00U) /*!< AF0: USART2 Alternate Function mapping */ +#define GPIO_AF0_USART3 ((uint8_t)0x00U) /*!< AF0: USART2 Alternate Function mapping */ +#define GPIO_AF0_USART4 ((uint8_t)0x00U) /*!< AF0: USART4 Alternate Function mapping */ +#define GPIO_AF0_CAN ((uint8_t)0x00U) /*!< AF0: CAN Alternate Function mapping */ + +/* AF 1 */ +#define GPIO_AF1_TIM3 ((uint8_t)0x01U) /*!< AF1: TIM3 Alternate Function mapping */ +#define GPIO_AF1_TIM15 ((uint8_t)0x01U) /*!< AF1: TIM15 Alternate Function mapping */ +#define GPIO_AF1_USART1 ((uint8_t)0x01U) /*!< AF1: USART1 Alternate Function mapping */ +#define GPIO_AF1_USART2 ((uint8_t)0x01U) /*!< AF1: USART2 Alternate Function mapping */ +#define GPIO_AF1_USART3 ((uint8_t)0x01U) /*!< AF1: USART3 Alternate Function mapping */ +#define GPIO_AF1_IR ((uint8_t)0x01U) /*!< AF1: IR Alternate Function mapping */ +#define GPIO_AF1_CEC ((uint8_t)0x01U) /*!< AF1: CEC Alternate Function mapping */ +#define GPIO_AF1_EVENTOUT ((uint8_t)0x01U) /*!< AF1: EVENTOUT Alternate Function mapping */ +#define GPIO_AF1_I2C1 ((uint8_t)0x01U) /*!< AF1: I2C1 Alternate Function mapping */ +#define GPIO_AF1_I2C2 ((uint8_t)0x01U) /*!< AF1: I2C1 Alternate Function mapping */ +#define GPIO_AF1_TSC ((uint8_t)0x01U) /*!< AF1: I2C1 Alternate Function mapping */ +#define GPIO_AF1_SPI1 ((uint8_t)0x01U) /*!< AF1: SPI1 Alternate Function mapping */ +#define GPIO_AF1_SPI2 ((uint8_t)0x01U) /*!< AF1: SPI2 Alternate Function mapping */ + +/* AF 2 */ +#define GPIO_AF2_TIM1 ((uint8_t)0x02U) /*!< AF2: TIM1 Alternate Function mapping */ +#define GPIO_AF2_TIM2 ((uint8_t)0x02U) /*!< AF2: TIM2 Alternate Function mapping */ +#define GPIO_AF2_TIM16 ((uint8_t)0x02U) /*!< AF2: TIM16 Alternate Function mapping */ +#define GPIO_AF2_TIM17 ((uint8_t)0x02U) /*!< AF2: TIM17 Alternate Function mapping */ +#define GPIO_AF2_EVENTOUT ((uint8_t)0x02U) /*!< AF2: EVENTOUT Alternate Function mapping */ +#define GPIO_AF2_USB ((uint8_t)0x02U) /*!< AF2: USB Alternate Function mapping */ + +/* AF 3 */ +#define GPIO_AF3_EVENTOUT ((uint8_t)0x03U) /*!< AF3: EVENTOUT Alternate Function mapping */ +#define GPIO_AF3_TSC ((uint8_t)0x03U) /*!< AF3: TSC Alternate Function mapping */ +#define GPIO_AF3_TIM15 ((uint8_t)0x03U) /*!< AF3: TIM15 Alternate Function mapping */ +#define GPIO_AF3_I2C1 ((uint8_t)0x03U) /*!< AF3: I2C1 Alternate Function mapping */ + +/* AF 4 */ +#define GPIO_AF4_TIM14 ((uint8_t)0x04U) /*!< AF4: TIM14 Alternate Function mapping */ +#define GPIO_AF4_USART4 ((uint8_t)0x04U) /*!< AF4: USART4 Alternate Function mapping */ +#define GPIO_AF4_USART3 ((uint8_t)0x04U) /*!< AF4: USART3 Alternate Function mapping */ +#define GPIO_AF4_CRS ((uint8_t)0x04U) /*!< AF4: CRS Alternate Function mapping */ +#define GPIO_AF4_CAN ((uint8_t)0x04U) /*!< AF4: CAN Alternate Function mapping */ + +/* AF 5 */ +#define GPIO_AF5_TIM15 ((uint8_t)0x05U) /*!< AF5: TIM15 Alternate Function mapping */ +#define GPIO_AF5_TIM16 ((uint8_t)0x05U) /*!< AF5: TIM16 Alternate Function mapping */ +#define GPIO_AF5_TIM17 ((uint8_t)0x05U) /*!< AF5: TIM17 Alternate Function mapping */ +#define GPIO_AF5_SPI2 ((uint8_t)0x05U) /*!< AF5: SPI2 Alternate Function mapping */ +#define GPIO_AF5_I2C2 ((uint8_t)0x05U) /*!< AF5: I2C2 Alternate Function mapping */ + +/* AF 6 */ +#define GPIO_AF6_EVENTOUT ((uint8_t)0x06U) /*!< AF6: EVENTOUT Alternate Function mapping */ + +/* AF 7 */ +#define GPIO_AF7_COMP1 ((uint8_t)0x07U) /*!< AF7: COMP1 Alternate Function mapping */ +#define GPIO_AF7_COMP2 ((uint8_t)0x07U) /*!< AF7: COMP2 Alternate Function mapping */ + +#define IS_GPIO_AF(AF) ((AF) <= (uint8_t)0x07U) + +#endif /* STM32F072xB || STM32F078xx */ + +#if defined (STM32F070xB) +/*---------------------------------- STM32F070xB ---------------------------------------------*/ +/* AF 0 */ +#define GPIO_AF0_EVENTOUT ((uint8_t)0x00U) /*!< AF0: EVENTOUT Alternate Function mapping */ +#define GPIO_AF0_SWDIO ((uint8_t)0x00U) /*!< AF0: SWDIO Alternate Function mapping */ +#define GPIO_AF0_SWCLK ((uint8_t)0x00U) /*!< AF0: SWCLK Alternate Function mapping */ +#define GPIO_AF0_MCO ((uint8_t)0x00U) /*!< AF0: MCO Alternate Function mapping */ +#define GPIO_AF0_IR ((uint8_t)0x00U) /*!< AF0: IR Alternate Function mapping */ +#define GPIO_AF0_SPI1 ((uint8_t)0x00U) /*!< AF0: SPI1 Alternate Function mapping */ +#define GPIO_AF0_SPI2 ((uint8_t)0x00U) /*!< AF0: SPI2 Alternate Function mapping */ +#define GPIO_AF0_TIM3 ((uint8_t)0x00U) /*!< AF0: TIM3 Alternate Function mapping */ +#define GPIO_AF0_TIM14 ((uint8_t)0x00U) /*!< AF0: TIM14 Alternate Function mapping */ +#define GPIO_AF0_TIM15 ((uint8_t)0x00U) /*!< AF0: TIM15 Alternate Function mapping */ +#define GPIO_AF0_TIM17 ((uint8_t)0x00U) /*!< AF0: TIM17 Alternate Function mapping */ +#define GPIO_AF0_USART1 ((uint8_t)0x00U) /*!< AF0: USART1 Alternate Function mapping */ +#define GPIO_AF0_USART4 ((uint8_t)0x00U) /*!< AF0: USART4 Alternate Function mapping */ + +/* AF 1 */ +#define GPIO_AF1_TIM3 ((uint8_t)0x01U) /*!< AF1: TIM3 Alternate Function mapping */ +#define GPIO_AF1_TIM15 ((uint8_t)0x01U) /*!< AF1: TIM15 Alternate Function mapping */ +#define GPIO_AF1_USART1 ((uint8_t)0x01U) /*!< AF1: USART1 Alternate Function mapping */ +#define GPIO_AF1_USART2 ((uint8_t)0x01U) /*!< AF1: USART2 Alternate Function mapping */ +#define GPIO_AF1_USART3 ((uint8_t)0x01U) /*!< AF1: USART4 Alternate Function mapping */ +#define GPIO_AF1_IR ((uint8_t)0x01U) /*!< AF1: IR Alternate Function mapping */ +#define GPIO_AF1_EVENTOUT ((uint8_t)0x01U) /*!< AF1: EVENTOUT Alternate Function mapping */ +#define GPIO_AF1_I2C1 ((uint8_t)0x01U) /*!< AF1: I2C1 Alternate Function mapping */ +#define GPIO_AF1_I2C2 ((uint8_t)0x01U) /*!< AF1: I2C1 Alternate Function mapping */ +#define GPIO_AF1_SPI2 ((uint8_t)0x01U) /*!< AF1: SPI2 Alternate Function mapping */ + +/* AF 2 */ +#define GPIO_AF2_TIM1 ((uint8_t)0x02U) /*!< AF2: TIM1 Alternate Function mapping */ +#define GPIO_AF2_TIM16 ((uint8_t)0x02U) /*!< AF2: TIM16 Alternate Function mapping */ +#define GPIO_AF2_TIM17 ((uint8_t)0x02U) /*!< AF2: TIM17 Alternate Function mapping */ +#define GPIO_AF2_EVENTOUT ((uint8_t)0x02U) /*!< AF2: EVENTOUT Alternate Function mapping */ +#define GPIO_AF2_USB ((uint8_t)0x02U) /*!< AF2: USB Alternate Function mapping */ + +/* AF 3 */ +#define GPIO_AF3_EVENTOUT ((uint8_t)0x03U) /*!< AF3: EVENTOUT Alternate Function mapping */ +#define GPIO_AF3_I2C1 ((uint8_t)0x03U) /*!< AF3: I2C1 Alternate Function mapping */ +#define GPIO_AF3_TIM15 ((uint8_t)0x03U) /*!< AF3: TIM15 Alternate Function mapping */ + +/* AF 4 */ +#define GPIO_AF4_TIM14 ((uint8_t)0x04U) /*!< AF4: TIM14 Alternate Function mapping */ +#define GPIO_AF4_USART4 ((uint8_t)0x04U) /*!< AF4: USART4 Alternate Function mapping */ +#define GPIO_AF4_USART3 ((uint8_t)0x04U) /*!< AF4: USART3 Alternate Function mapping */ + +/* AF 5 */ +#define GPIO_AF5_TIM15 ((uint8_t)0x05U) /*!< AF5: TIM15 Alternate Function mapping */ +#define GPIO_AF5_TIM16 ((uint8_t)0x05U) /*!< AF5: TIM16 Alternate Function mapping */ +#define GPIO_AF5_TIM17 ((uint8_t)0x05U) /*!< AF5: TIM17 Alternate Function mapping */ +#define GPIO_AF5_SPI2 ((uint8_t)0x05U) /*!< AF5: SPI2 Alternate Function mapping */ +#define GPIO_AF5_I2C2 ((uint8_t)0x05U) /*!< AF5: I2C2 Alternate Function mapping */ + +/* AF 6 */ +#define GPIO_AF6_EVENTOUT ((uint8_t)0x06U) /*!< AF6: EVENTOUT Alternate Function mapping */ + +#define IS_GPIO_AF(AF) ((AF) <= (uint8_t)0x06U) + +#endif /* STM32F070xB */ + +#if defined (STM32F042x6) || defined (STM32F048xx) +/*--------------------------- STM32F042x6/STM32F048xx ---------------------------*/ +/* AF 0 */ +#define GPIO_AF0_EVENTOUT ((uint8_t)0x00U) /*!< AF0: EVENTOUT Alternate Function mapping */ +#define GPIO_AF0_CEC ((uint8_t)0x00U) /*!< AF0: CEC Alternate Function mapping */ +#define GPIO_AF0_CRS ((uint8_t)0x00U) /*!< AF0: CRS Alternate Function mapping */ +#define GPIO_AF0_IR ((uint8_t)0x00U) /*!< AF0: IR Alternate Function mapping */ +#define GPIO_AF0_MCO ((uint8_t)0x00U) /*!< AF0: MCO Alternate Function mapping */ +#define GPIO_AF0_SPI1 ((uint8_t)0x00U) /*!< AF0: SPI1/I2S1 Alternate Function mapping */ +#define GPIO_AF0_SPI2 ((uint8_t)0x00U) /*!< AF0: SPI2/I2S2 Alternate Function mapping */ +#define GPIO_AF0_SWDIO ((uint8_t)0x00U) /*!< AF0: SWDIO Alternate Function mapping */ +#define GPIO_AF0_SWCLK ((uint8_t)0x00U) /*!< AF0: SWCLK Alternate Function mapping */ +#define GPIO_AF0_TIM14 ((uint8_t)0x00U) /*!< AF0: TIM14 Alternate Function mapping */ +#define GPIO_AF0_TIM17 ((uint8_t)0x00U) /*!< AF0: TIM17 Alternate Function mapping */ +#define GPIO_AF0_USART1 ((uint8_t)0x00U) /*!< AF0: USART1 Alternate Function mapping */ + +/* AF 1 */ +#define GPIO_AF1_CEC ((uint8_t)0x01U) /*!< AF1: CEC Alternate Function mapping */ +#define GPIO_AF1_EVENTOUT ((uint8_t)0x01U) /*!< AF1: EVENTOUT Alternate Function mapping */ +#define GPIO_AF1_I2C1 ((uint8_t)0x01U) /*!< AF1: I2C1 Alternate Function mapping */ +#define GPIO_AF1_IR ((uint8_t)0x01U) /*!< AF1: IR Alternate Function mapping */ +#define GPIO_AF1_USART1 ((uint8_t)0x01U) /*!< AF1: USART1 Alternate Function mapping */ +#define GPIO_AF1_USART2 ((uint8_t)0x01U) /*!< AF1: USART2 Alternate Function mapping */ +#define GPIO_AF1_TIM3 ((uint8_t)0x01U) /*!< AF1: TIM3 Alternate Function mapping */ + +/* AF 2 */ +#define GPIO_AF2_EVENTOUT ((uint8_t)0x02U) /*!< AF2: EVENTOUT Alternate Function mapping */ +#define GPIO_AF2_TIM1 ((uint8_t)0x02U) /*!< AF2: TIM1 Alternate Function mapping */ +#define GPIO_AF2_TIM2 ((uint8_t)0x02U) /*!< AF2: TIM2 Alternate Function mapping */ +#define GPIO_AF2_TIM16 ((uint8_t)0x02U) /*!< AF2: TIM16 Alternate Function mapping */ +#define GPIO_AF2_TIM17 ((uint8_t)0x02U) /*!< AF2: TIM17 Alternate Function mapping */ +#define GPIO_AF2_USB ((uint8_t)0x02U) /*!< AF2: USB Alternate Function mapping */ + +/* AF 3 */ +#define GPIO_AF3_EVENTOUT ((uint8_t)0x03U) /*!< AF3: EVENTOUT Alternate Function mapping */ +#define GPIO_AF3_I2C1 ((uint8_t)0x03U) /*!< AF3: I2C1 Alternate Function mapping */ +#define GPIO_AF3_TSC ((uint8_t)0x03U) /*!< AF3: TSC Alternate Function mapping */ + +/* AF 4 */ +#define GPIO_AF4_TIM14 ((uint8_t)0x04U) /*!< AF4: TIM14 Alternate Function mapping */ +#define GPIO_AF4_CAN ((uint8_t)0x04U) /*!< AF4: CAN Alternate Function mapping */ +#define GPIO_AF4_CRS ((uint8_t)0x04U) /*!< AF4: CRS Alternate Function mapping */ +#define GPIO_AF4_I2C1 ((uint8_t)0x04U) /*!< AF4: I2C1 Alternate Function mapping */ + +/* AF 5 */ +#define GPIO_AF5_MCO ((uint8_t)0x05U) /*!< AF5: MCO Alternate Function mapping */ +#define GPIO_AF5_I2C1 ((uint8_t)0x05U) /*!< AF5: I2C1 Alternate Function mapping */ +#define GPIO_AF5_I2C2 ((uint8_t)0x05U) /*!< AF5: I2C2 Alternate Function mapping */ +#define GPIO_AF5_SPI2 ((uint8_t)0x05U) /*!< AF5: SPI2 Alternate Function mapping */ +#define GPIO_AF5_TIM16 ((uint8_t)0x05U) /*!< AF5: TIM16 Alternate Function mapping */ +#define GPIO_AF5_TIM17 ((uint8_t)0x05U) /*!< AF5: TIM17 Alternate Function mapping */ +#define GPIO_AF5_USB ((uint8_t)0x05U) /*!< AF5: USB Alternate Function mapping */ + +/* AF 6 */ +#define GPIO_AF6_EVENTOUT ((uint8_t)0x06U) /*!< AF6: EVENTOUT Alternate Function mapping */ + +#define IS_GPIO_AF(AF) ((AF) <= (uint8_t)0x06U) + +#endif /* STM32F042x6 || STM32F048xx */ + +#if defined (STM32F070x6) +/*--------------------------------------- STM32F070x6 ----------------------------------------*/ +/* AF 0 */ +#define GPIO_AF0_EVENTOUT ((uint8_t)0x00U) /*!< AF0: EVENTOUT Alternate Function mapping */ +#define GPIO_AF0_IR ((uint8_t)0x00U) /*!< AF0: IR Alternate Function mapping */ +#define GPIO_AF0_MCO ((uint8_t)0x00U) /*!< AF0: MCO Alternate Function mapping */ +#define GPIO_AF0_SPI1 ((uint8_t)0x00U) /*!< AF0: SPI1 Alternate Function mapping */ +#define GPIO_AF0_SWDIO ((uint8_t)0x00U) /*!< AF0: SWDIO Alternate Function mapping */ +#define GPIO_AF0_SWCLK ((uint8_t)0x00U) /*!< AF0: SWCLK Alternate Function mapping */ +#define GPIO_AF0_TIM14 ((uint8_t)0x00U) /*!< AF0: TIM14 Alternate Function mapping */ +#define GPIO_AF0_TIM17 ((uint8_t)0x00U) /*!< AF0: TIM17 Alternate Function mapping */ +#define GPIO_AF0_USART1 ((uint8_t)0x00U) /*!< AF0: USART1 Alternate Function mapping */ + +/* AF 1 */ +#define GPIO_AF1_EVENTOUT ((uint8_t)0x01U) /*!< AF1: EVENTOUT Alternate Function mapping */ +#define GPIO_AF1_I2C1 ((uint8_t)0x01U) /*!< AF1: I2C1 Alternate Function mapping */ +#define GPIO_AF1_IR ((uint8_t)0x01U) /*!< AF1: IR Alternate Function mapping */ +#define GPIO_AF1_USART1 ((uint8_t)0x01U) /*!< AF1: USART1 Alternate Function mapping */ +#define GPIO_AF1_USART2 ((uint8_t)0x01U) /*!< AF1: USART2 Alternate Function mapping */ +#define GPIO_AF1_TIM3 ((uint8_t)0x01U) /*!< AF1: TIM3 Alternate Function mapping */ + +/* AF 2 */ +#define GPIO_AF2_EVENTOUT ((uint8_t)0x02U) /*!< AF2: EVENTOUT Alternate Function mapping */ +#define GPIO_AF2_TIM1 ((uint8_t)0x02U) /*!< AF2: TIM1 Alternate Function mapping */ +#define GPIO_AF2_TIM16 ((uint8_t)0x02U) /*!< AF2: TIM16 Alternate Function mapping */ +#define GPIO_AF2_TIM17 ((uint8_t)0x02U) /*!< AF2: TIM17 Alternate Function mapping */ +#define GPIO_AF2_USB ((uint8_t)0x02U) /*!< AF2: USB Alternate Function mapping */ + +/* AF 3 */ +#define GPIO_AF3_EVENTOUT ((uint8_t)0x03U) /*!< AF3: EVENTOUT Alternate Function mapping */ +#define GPIO_AF3_I2C1 ((uint8_t)0x03U) /*!< AF3: I2C1 Alternate Function mapping */ + +/* AF 4 */ +#define GPIO_AF4_TIM14 ((uint8_t)0x04U) /*!< AF4: TIM14 Alternate Function mapping */ +#define GPIO_AF4_I2C1 ((uint8_t)0x04U) /*!< AF4: I2C1 Alternate Function mapping */ + +/* AF 5 */ +#define GPIO_AF5_MCO ((uint8_t)0x05U) /*!< AF5: MCO Alternate Function mapping */ +#define GPIO_AF5_I2C1 ((uint8_t)0x05U) /*!< AF5: I2C1 Alternate Function mapping */ +#define GPIO_AF5_TIM16 ((uint8_t)0x05U) /*!< AF5: TIM16 Alternate Function mapping */ +#define GPIO_AF5_TIM17 ((uint8_t)0x05U) /*!< AF5: TIM17 Alternate Function mapping */ +#define GPIO_AF5_USB ((uint8_t)0x05U) /*!< AF5: USB Alternate Function mapping */ + +/* AF 6 */ +#define GPIO_AF6_EVENTOUT ((uint8_t)0x06U) /*!< AF6: EVENTOUT Alternate Function mapping */ + +#define IS_GPIO_AF(AF) ((AF) <= (uint8_t)0x06U) + +#endif /* STM32F070x6 */ +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup GPIOEx_Exported_Macros GPIOEx Exported Macros + * @{ + */ + +/** @defgroup GPIOEx_Get_Port_Index GPIOEx_Get Port Index +* @{ + */ +#if defined(GPIOD) && defined(GPIOE) +#define GPIO_GET_INDEX(__GPIOx__) (((__GPIOx__) == (GPIOA))? 0U :\ + ((__GPIOx__) == (GPIOB))? 1U :\ + ((__GPIOx__) == (GPIOC))? 2U :\ + ((__GPIOx__) == (GPIOD))? 3U :\ + ((__GPIOx__) == (GPIOE))? 4U : 5U) +#endif + +#if defined(GPIOD) && !defined(GPIOE) +#define GPIO_GET_INDEX(__GPIOx__) (((__GPIOx__) == (GPIOA))? 0U :\ + ((__GPIOx__) == (GPIOB))? 1U :\ + ((__GPIOx__) == (GPIOC))? 2U :\ + ((__GPIOx__) == (GPIOD))? 3U : 5U) +#endif + +#if !defined(GPIOD) && defined(GPIOE) +#define GPIO_GET_INDEX(__GPIOx__) (((__GPIOx__) == (GPIOA))? 0U :\ + ((__GPIOx__) == (GPIOB))? 1U :\ + ((__GPIOx__) == (GPIOC))? 2U :\ + ((__GPIOx__) == (GPIOE))? 4U : 5U) +#endif + +#if !defined(GPIOD) && !defined(GPIOE) +#define GPIO_GET_INDEX(__GPIOx__) (((__GPIOx__) == (GPIOA))? 0U :\ + ((__GPIOx__) == (GPIOB))? 1U :\ + ((__GPIOx__) == (GPIOC))? 2U : 5U) +#endif + +/** + * @} + */ + +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F0xx_HAL_GPIO_EX_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ + diff --git a/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c.h b/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c.h new file mode 100644 index 0000000..d61df7e --- /dev/null +++ b/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c.h @@ -0,0 +1,782 @@ +/** + ****************************************************************************** + * @file stm32f0xx_hal_i2c.h + * @author MCD Application Team + * @brief Header file of I2C HAL module. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2016 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32F0xx_HAL_I2C_H +#define STM32F0xx_HAL_I2C_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f0xx_hal_def.h" + +/** @addtogroup STM32F0xx_HAL_Driver + * @{ + */ + +/** @addtogroup I2C + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup I2C_Exported_Types I2C Exported Types + * @{ + */ + +/** @defgroup I2C_Configuration_Structure_definition I2C Configuration Structure definition + * @brief I2C Configuration Structure definition + * @{ + */ +typedef struct +{ + uint32_t Timing; /*!< Specifies the I2C_TIMINGR_register value. + This parameter calculated by referring to I2C initialization + section in Reference manual */ + + uint32_t OwnAddress1; /*!< Specifies the first device own address. + This parameter can be a 7-bit or 10-bit address. */ + + uint32_t AddressingMode; /*!< Specifies if 7-bit or 10-bit addressing mode is selected. + This parameter can be a value of @ref I2C_ADDRESSING_MODE */ + + uint32_t DualAddressMode; /*!< Specifies if dual addressing mode is selected. + This parameter can be a value of @ref I2C_DUAL_ADDRESSING_MODE */ + + uint32_t OwnAddress2; /*!< Specifies the second device own address if dual addressing mode is selected + This parameter can be a 7-bit address. */ + + uint32_t OwnAddress2Masks; /*!< Specifies the acknowledge mask address second device own address if dual addressing mode is selected + This parameter can be a value of @ref I2C_OWN_ADDRESS2_MASKS */ + + uint32_t GeneralCallMode; /*!< Specifies if general call mode is selected. + This parameter can be a value of @ref I2C_GENERAL_CALL_ADDRESSING_MODE */ + + uint32_t NoStretchMode; /*!< Specifies if nostretch mode is selected. + This parameter can be a value of @ref I2C_NOSTRETCH_MODE */ + +} I2C_InitTypeDef; + +/** + * @} + */ + +/** @defgroup HAL_state_structure_definition HAL state structure definition + * @brief HAL State structure definition + * @note HAL I2C State value coding follow below described bitmap :\n + * b7-b6 Error information\n + * 00 : No Error\n + * 01 : Abort (Abort user request on going)\n + * 10 : Timeout\n + * 11 : Error\n + * b5 Peripheral initialization status\n + * 0 : Reset (peripheral not initialized)\n + * 1 : Init done (peripheral initialized and ready to use. HAL I2C Init function called)\n + * b4 (not used)\n + * x : Should be set to 0\n + * b3\n + * 0 : Ready or Busy (No Listen mode ongoing)\n + * 1 : Listen (peripheral in Address Listen Mode)\n + * b2 Intrinsic process state\n + * 0 : Ready\n + * 1 : Busy (peripheral busy with some configuration or internal operations)\n + * b1 Rx state\n + * 0 : Ready (no Rx operation ongoing)\n + * 1 : Busy (Rx operation ongoing)\n + * b0 Tx state\n + * 0 : Ready (no Tx operation ongoing)\n + * 1 : Busy (Tx operation ongoing) + * @{ + */ +typedef enum +{ + HAL_I2C_STATE_RESET = 0x00U, /*!< Peripheral is not yet Initialized */ + HAL_I2C_STATE_READY = 0x20U, /*!< Peripheral Initialized and ready for use */ + HAL_I2C_STATE_BUSY = 0x24U, /*!< An internal process is ongoing */ + HAL_I2C_STATE_BUSY_TX = 0x21U, /*!< Data Transmission process is ongoing */ + HAL_I2C_STATE_BUSY_RX = 0x22U, /*!< Data Reception process is ongoing */ + HAL_I2C_STATE_LISTEN = 0x28U, /*!< Address Listen Mode is ongoing */ + HAL_I2C_STATE_BUSY_TX_LISTEN = 0x29U, /*!< Address Listen Mode and Data Transmission + process is ongoing */ + HAL_I2C_STATE_BUSY_RX_LISTEN = 0x2AU, /*!< Address Listen Mode and Data Reception + process is ongoing */ + HAL_I2C_STATE_ABORT = 0x60U, /*!< Abort user request ongoing */ + HAL_I2C_STATE_TIMEOUT = 0xA0U, /*!< Timeout state */ + HAL_I2C_STATE_ERROR = 0xE0U /*!< Error */ + +} HAL_I2C_StateTypeDef; + +/** + * @} + */ + +/** @defgroup HAL_mode_structure_definition HAL mode structure definition + * @brief HAL Mode structure definition + * @note HAL I2C Mode value coding follow below described bitmap :\n + * b7 (not used)\n + * x : Should be set to 0\n + * b6\n + * 0 : None\n + * 1 : Memory (HAL I2C communication is in Memory Mode)\n + * b5\n + * 0 : None\n + * 1 : Slave (HAL I2C communication is in Slave Mode)\n + * b4\n + * 0 : None\n + * 1 : Master (HAL I2C communication is in Master Mode)\n + * b3-b2-b1-b0 (not used)\n + * xxxx : Should be set to 0000 + * @{ + */ +typedef enum +{ + HAL_I2C_MODE_NONE = 0x00U, /*!< No I2C communication on going */ + HAL_I2C_MODE_MASTER = 0x10U, /*!< I2C communication is in Master Mode */ + HAL_I2C_MODE_SLAVE = 0x20U, /*!< I2C communication is in Slave Mode */ + HAL_I2C_MODE_MEM = 0x40U /*!< I2C communication is in Memory Mode */ + +} HAL_I2C_ModeTypeDef; + +/** + * @} + */ + +/** @defgroup I2C_Error_Code_definition I2C Error Code definition + * @brief I2C Error Code definition + * @{ + */ +#define HAL_I2C_ERROR_NONE (0x00000000U) /*!< No error */ +#define HAL_I2C_ERROR_BERR (0x00000001U) /*!< BERR error */ +#define HAL_I2C_ERROR_ARLO (0x00000002U) /*!< ARLO error */ +#define HAL_I2C_ERROR_AF (0x00000004U) /*!< ACKF error */ +#define HAL_I2C_ERROR_OVR (0x00000008U) /*!< OVR error */ +#define HAL_I2C_ERROR_DMA (0x00000010U) /*!< DMA transfer error */ +#define HAL_I2C_ERROR_TIMEOUT (0x00000020U) /*!< Timeout error */ +#define HAL_I2C_ERROR_SIZE (0x00000040U) /*!< Size Management error */ +#define HAL_I2C_ERROR_DMA_PARAM (0x00000080U) /*!< DMA Parameter Error */ +#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1) +#define HAL_I2C_ERROR_INVALID_CALLBACK (0x00000100U) /*!< Invalid Callback error */ +#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */ +#define HAL_I2C_ERROR_INVALID_PARAM (0x00000200U) /*!< Invalid Parameters error */ +/** + * @} + */ + +/** @defgroup I2C_handle_Structure_definition I2C handle Structure definition + * @brief I2C handle Structure definition + * @{ + */ +typedef struct __I2C_HandleTypeDef +{ + I2C_TypeDef *Instance; /*!< I2C registers base address */ + + I2C_InitTypeDef Init; /*!< I2C communication parameters */ + + uint8_t *pBuffPtr; /*!< Pointer to I2C transfer buffer */ + + uint16_t XferSize; /*!< I2C transfer size */ + + __IO uint16_t XferCount; /*!< I2C transfer counter */ + + __IO uint32_t XferOptions; /*!< I2C sequantial transfer options, this parameter can + be a value of @ref I2C_XFEROPTIONS */ + + __IO uint32_t PreviousState; /*!< I2C communication Previous state */ + + HAL_StatusTypeDef(*XferISR)(struct __I2C_HandleTypeDef *hi2c, uint32_t ITFlags, uint32_t ITSources); /*!< I2C transfer IRQ handler function pointer */ + + DMA_HandleTypeDef *hdmatx; /*!< I2C Tx DMA handle parameters */ + + DMA_HandleTypeDef *hdmarx; /*!< I2C Rx DMA handle parameters */ + + HAL_LockTypeDef Lock; /*!< I2C locking object */ + + __IO HAL_I2C_StateTypeDef State; /*!< I2C communication state */ + + __IO HAL_I2C_ModeTypeDef Mode; /*!< I2C communication mode */ + + __IO uint32_t ErrorCode; /*!< I2C Error code */ + + __IO uint32_t AddrEventCount; /*!< I2C Address Event counter */ + +#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1) + void (* MasterTxCpltCallback)(struct __I2C_HandleTypeDef *hi2c); /*!< I2C Master Tx Transfer completed callback */ + void (* MasterRxCpltCallback)(struct __I2C_HandleTypeDef *hi2c); /*!< I2C Master Rx Transfer completed callback */ + void (* SlaveTxCpltCallback)(struct __I2C_HandleTypeDef *hi2c); /*!< I2C Slave Tx Transfer completed callback */ + void (* SlaveRxCpltCallback)(struct __I2C_HandleTypeDef *hi2c); /*!< I2C Slave Rx Transfer completed callback */ + void (* ListenCpltCallback)(struct __I2C_HandleTypeDef *hi2c); /*!< I2C Listen Complete callback */ + void (* MemTxCpltCallback)(struct __I2C_HandleTypeDef *hi2c); /*!< I2C Memory Tx Transfer completed callback */ + void (* MemRxCpltCallback)(struct __I2C_HandleTypeDef *hi2c); /*!< I2C Memory Rx Transfer completed callback */ + void (* ErrorCallback)(struct __I2C_HandleTypeDef *hi2c); /*!< I2C Error callback */ + void (* AbortCpltCallback)(struct __I2C_HandleTypeDef *hi2c); /*!< I2C Abort callback */ + + void (* AddrCallback)(struct __I2C_HandleTypeDef *hi2c, uint8_t TransferDirection, uint16_t AddrMatchCode); /*!< I2C Slave Address Match callback */ + + void (* MspInitCallback)(struct __I2C_HandleTypeDef *hi2c); /*!< I2C Msp Init callback */ + void (* MspDeInitCallback)(struct __I2C_HandleTypeDef *hi2c); /*!< I2C Msp DeInit callback */ + +#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */ +} I2C_HandleTypeDef; + +#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1) +/** + * @brief HAL I2C Callback ID enumeration definition + */ +typedef enum +{ + HAL_I2C_MASTER_TX_COMPLETE_CB_ID = 0x00U, /*!< I2C Master Tx Transfer completed callback ID */ + HAL_I2C_MASTER_RX_COMPLETE_CB_ID = 0x01U, /*!< I2C Master Rx Transfer completed callback ID */ + HAL_I2C_SLAVE_TX_COMPLETE_CB_ID = 0x02U, /*!< I2C Slave Tx Transfer completed callback ID */ + HAL_I2C_SLAVE_RX_COMPLETE_CB_ID = 0x03U, /*!< I2C Slave Rx Transfer completed callback ID */ + HAL_I2C_LISTEN_COMPLETE_CB_ID = 0x04U, /*!< I2C Listen Complete callback ID */ + HAL_I2C_MEM_TX_COMPLETE_CB_ID = 0x05U, /*!< I2C Memory Tx Transfer callback ID */ + HAL_I2C_MEM_RX_COMPLETE_CB_ID = 0x06U, /*!< I2C Memory Rx Transfer completed callback ID */ + HAL_I2C_ERROR_CB_ID = 0x07U, /*!< I2C Error callback ID */ + HAL_I2C_ABORT_CB_ID = 0x08U, /*!< I2C Abort callback ID */ + + HAL_I2C_MSPINIT_CB_ID = 0x09U, /*!< I2C Msp Init callback ID */ + HAL_I2C_MSPDEINIT_CB_ID = 0x0AU /*!< I2C Msp DeInit callback ID */ + +} HAL_I2C_CallbackIDTypeDef; + +/** + * @brief HAL I2C Callback pointer definition + */ +typedef void (*pI2C_CallbackTypeDef)(I2C_HandleTypeDef *hi2c); /*!< pointer to an I2C callback function */ +typedef void (*pI2C_AddrCallbackTypeDef)(I2C_HandleTypeDef *hi2c, uint8_t TransferDirection, uint16_t AddrMatchCode); /*!< pointer to an I2C Address Match callback function */ + +#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */ +/** + * @} + */ + +/** + * @} + */ +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup I2C_Exported_Constants I2C Exported Constants + * @{ + */ + +/** @defgroup I2C_XFEROPTIONS I2C Sequential Transfer Options + * @{ + */ +#define I2C_FIRST_FRAME ((uint32_t)I2C_SOFTEND_MODE) +#define I2C_FIRST_AND_NEXT_FRAME ((uint32_t)(I2C_RELOAD_MODE | I2C_SOFTEND_MODE)) +#define I2C_NEXT_FRAME ((uint32_t)(I2C_RELOAD_MODE | I2C_SOFTEND_MODE)) +#define I2C_FIRST_AND_LAST_FRAME ((uint32_t)I2C_AUTOEND_MODE) +#define I2C_LAST_FRAME ((uint32_t)I2C_AUTOEND_MODE) +#define I2C_LAST_FRAME_NO_STOP ((uint32_t)I2C_SOFTEND_MODE) + +/* List of XferOptions in usage of : + * 1- Restart condition in all use cases (direction change or not) + */ +#define I2C_OTHER_FRAME (0x000000AAU) +#define I2C_OTHER_AND_LAST_FRAME (0x0000AA00U) +/** + * @} + */ + +/** @defgroup I2C_ADDRESSING_MODE I2C Addressing Mode + * @{ + */ +#define I2C_ADDRESSINGMODE_7BIT (0x00000001U) +#define I2C_ADDRESSINGMODE_10BIT (0x00000002U) +/** + * @} + */ + +/** @defgroup I2C_DUAL_ADDRESSING_MODE I2C Dual Addressing Mode + * @{ + */ +#define I2C_DUALADDRESS_DISABLE (0x00000000U) +#define I2C_DUALADDRESS_ENABLE I2C_OAR2_OA2EN +/** + * @} + */ + +/** @defgroup I2C_OWN_ADDRESS2_MASKS I2C Own Address2 Masks + * @{ + */ +#define I2C_OA2_NOMASK ((uint8_t)0x00U) +#define I2C_OA2_MASK01 ((uint8_t)0x01U) +#define I2C_OA2_MASK02 ((uint8_t)0x02U) +#define I2C_OA2_MASK03 ((uint8_t)0x03U) +#define I2C_OA2_MASK04 ((uint8_t)0x04U) +#define I2C_OA2_MASK05 ((uint8_t)0x05U) +#define I2C_OA2_MASK06 ((uint8_t)0x06U) +#define I2C_OA2_MASK07 ((uint8_t)0x07U) +/** + * @} + */ + +/** @defgroup I2C_GENERAL_CALL_ADDRESSING_MODE I2C General Call Addressing Mode + * @{ + */ +#define I2C_GENERALCALL_DISABLE (0x00000000U) +#define I2C_GENERALCALL_ENABLE I2C_CR1_GCEN +/** + * @} + */ + +/** @defgroup I2C_NOSTRETCH_MODE I2C No-Stretch Mode + * @{ + */ +#define I2C_NOSTRETCH_DISABLE (0x00000000U) +#define I2C_NOSTRETCH_ENABLE I2C_CR1_NOSTRETCH +/** + * @} + */ + +/** @defgroup I2C_MEMORY_ADDRESS_SIZE I2C Memory Address Size + * @{ + */ +#define I2C_MEMADD_SIZE_8BIT (0x00000001U) +#define I2C_MEMADD_SIZE_16BIT (0x00000002U) +/** + * @} + */ + +/** @defgroup I2C_XFERDIRECTION I2C Transfer Direction Master Point of View + * @{ + */ +#define I2C_DIRECTION_TRANSMIT (0x00000000U) +#define I2C_DIRECTION_RECEIVE (0x00000001U) +/** + * @} + */ + +/** @defgroup I2C_RELOAD_END_MODE I2C Reload End Mode + * @{ + */ +#define I2C_RELOAD_MODE I2C_CR2_RELOAD +#define I2C_AUTOEND_MODE I2C_CR2_AUTOEND +#define I2C_SOFTEND_MODE (0x00000000U) +/** + * @} + */ + +/** @defgroup I2C_START_STOP_MODE I2C Start or Stop Mode + * @{ + */ +#define I2C_NO_STARTSTOP (0x00000000U) +#define I2C_GENERATE_STOP (uint32_t)(0x80000000U | I2C_CR2_STOP) +#define I2C_GENERATE_START_READ (uint32_t)(0x80000000U | I2C_CR2_START | I2C_CR2_RD_WRN) +#define I2C_GENERATE_START_WRITE (uint32_t)(0x80000000U | I2C_CR2_START) +/** + * @} + */ + +/** @defgroup I2C_Interrupt_configuration_definition I2C Interrupt configuration definition + * @brief I2C Interrupt definition + * Elements values convention: 0xXXXXXXXX + * - XXXXXXXX : Interrupt control mask + * @{ + */ +#define I2C_IT_ERRI I2C_CR1_ERRIE +#define I2C_IT_TCI I2C_CR1_TCIE +#define I2C_IT_STOPI I2C_CR1_STOPIE +#define I2C_IT_NACKI I2C_CR1_NACKIE +#define I2C_IT_ADDRI I2C_CR1_ADDRIE +#define I2C_IT_RXI I2C_CR1_RXIE +#define I2C_IT_TXI I2C_CR1_TXIE +/** + * @} + */ + +/** @defgroup I2C_Flag_definition I2C Flag definition + * @{ + */ +#define I2C_FLAG_TXE I2C_ISR_TXE +#define I2C_FLAG_TXIS I2C_ISR_TXIS +#define I2C_FLAG_RXNE I2C_ISR_RXNE +#define I2C_FLAG_ADDR I2C_ISR_ADDR +#define I2C_FLAG_AF I2C_ISR_NACKF +#define I2C_FLAG_STOPF I2C_ISR_STOPF +#define I2C_FLAG_TC I2C_ISR_TC +#define I2C_FLAG_TCR I2C_ISR_TCR +#define I2C_FLAG_BERR I2C_ISR_BERR +#define I2C_FLAG_ARLO I2C_ISR_ARLO +#define I2C_FLAG_OVR I2C_ISR_OVR +#define I2C_FLAG_PECERR I2C_ISR_PECERR +#define I2C_FLAG_TIMEOUT I2C_ISR_TIMEOUT +#define I2C_FLAG_ALERT I2C_ISR_ALERT +#define I2C_FLAG_BUSY I2C_ISR_BUSY +#define I2C_FLAG_DIR I2C_ISR_DIR +/** + * @} + */ + +/** + * @} + */ + +/* Exported macros -----------------------------------------------------------*/ + +/** @defgroup I2C_Exported_Macros I2C Exported Macros + * @{ + */ + +/** @brief Reset I2C handle state. + * @param __HANDLE__ specifies the I2C Handle. + * @retval None + */ +#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1) +#define __HAL_I2C_RESET_HANDLE_STATE(__HANDLE__) do{ \ + (__HANDLE__)->State = HAL_I2C_STATE_RESET; \ + (__HANDLE__)->MspInitCallback = NULL; \ + (__HANDLE__)->MspDeInitCallback = NULL; \ + } while(0) +#else +#define __HAL_I2C_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_I2C_STATE_RESET) +#endif + +/** @brief Enable the specified I2C interrupt. + * @param __HANDLE__ specifies the I2C Handle. + * @param __INTERRUPT__ specifies the interrupt source to enable. + * This parameter can be one of the following values: + * @arg @ref I2C_IT_ERRI Errors interrupt enable + * @arg @ref I2C_IT_TCI Transfer complete interrupt enable + * @arg @ref I2C_IT_STOPI STOP detection interrupt enable + * @arg @ref I2C_IT_NACKI NACK received interrupt enable + * @arg @ref I2C_IT_ADDRI Address match interrupt enable + * @arg @ref I2C_IT_RXI RX interrupt enable + * @arg @ref I2C_IT_TXI TX interrupt enable + * + * @retval None + */ +#define __HAL_I2C_ENABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->CR1 |= (__INTERRUPT__)) + +/** @brief Disable the specified I2C interrupt. + * @param __HANDLE__ specifies the I2C Handle. + * @param __INTERRUPT__ specifies the interrupt source to disable. + * This parameter can be one of the following values: + * @arg @ref I2C_IT_ERRI Errors interrupt enable + * @arg @ref I2C_IT_TCI Transfer complete interrupt enable + * @arg @ref I2C_IT_STOPI STOP detection interrupt enable + * @arg @ref I2C_IT_NACKI NACK received interrupt enable + * @arg @ref I2C_IT_ADDRI Address match interrupt enable + * @arg @ref I2C_IT_RXI RX interrupt enable + * @arg @ref I2C_IT_TXI TX interrupt enable + * + * @retval None + */ +#define __HAL_I2C_DISABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->CR1 &= (~(__INTERRUPT__))) + +/** @brief Check whether the specified I2C interrupt source is enabled or not. + * @param __HANDLE__ specifies the I2C Handle. + * @param __INTERRUPT__ specifies the I2C interrupt source to check. + * This parameter can be one of the following values: + * @arg @ref I2C_IT_ERRI Errors interrupt enable + * @arg @ref I2C_IT_TCI Transfer complete interrupt enable + * @arg @ref I2C_IT_STOPI STOP detection interrupt enable + * @arg @ref I2C_IT_NACKI NACK received interrupt enable + * @arg @ref I2C_IT_ADDRI Address match interrupt enable + * @arg @ref I2C_IT_RXI RX interrupt enable + * @arg @ref I2C_IT_TXI TX interrupt enable + * + * @retval The new state of __INTERRUPT__ (SET or RESET). + */ +#define __HAL_I2C_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) ((((__HANDLE__)->Instance->CR1 & (__INTERRUPT__)) == (__INTERRUPT__)) ? SET : RESET) + +/** @brief Check whether the specified I2C flag is set or not. + * @param __HANDLE__ specifies the I2C Handle. + * @param __FLAG__ specifies the flag to check. + * This parameter can be one of the following values: + * @arg @ref I2C_FLAG_TXE Transmit data register empty + * @arg @ref I2C_FLAG_TXIS Transmit interrupt status + * @arg @ref I2C_FLAG_RXNE Receive data register not empty + * @arg @ref I2C_FLAG_ADDR Address matched (slave mode) + * @arg @ref I2C_FLAG_AF Acknowledge failure received flag + * @arg @ref I2C_FLAG_STOPF STOP detection flag + * @arg @ref I2C_FLAG_TC Transfer complete (master mode) + * @arg @ref I2C_FLAG_TCR Transfer complete reload + * @arg @ref I2C_FLAG_BERR Bus error + * @arg @ref I2C_FLAG_ARLO Arbitration lost + * @arg @ref I2C_FLAG_OVR Overrun/Underrun + * @arg @ref I2C_FLAG_PECERR PEC error in reception + * @arg @ref I2C_FLAG_TIMEOUT Timeout or Tlow detection flag + * @arg @ref I2C_FLAG_ALERT SMBus alert + * @arg @ref I2C_FLAG_BUSY Bus busy + * @arg @ref I2C_FLAG_DIR Transfer direction (slave mode) + * + * @retval The new state of __FLAG__ (SET or RESET). + */ +#define I2C_FLAG_MASK (0x0001FFFFU) +#define __HAL_I2C_GET_FLAG(__HANDLE__, __FLAG__) (((((__HANDLE__)->Instance->ISR) & (__FLAG__)) == (__FLAG__)) ? SET : RESET) + +/** @brief Clear the I2C pending flags which are cleared by writing 1 in a specific bit. + * @param __HANDLE__ specifies the I2C Handle. + * @param __FLAG__ specifies the flag to clear. + * This parameter can be any combination of the following values: + * @arg @ref I2C_FLAG_TXE Transmit data register empty + * @arg @ref I2C_FLAG_ADDR Address matched (slave mode) + * @arg @ref I2C_FLAG_AF Acknowledge failure received flag + * @arg @ref I2C_FLAG_STOPF STOP detection flag + * @arg @ref I2C_FLAG_BERR Bus error + * @arg @ref I2C_FLAG_ARLO Arbitration lost + * @arg @ref I2C_FLAG_OVR Overrun/Underrun + * @arg @ref I2C_FLAG_PECERR PEC error in reception + * @arg @ref I2C_FLAG_TIMEOUT Timeout or Tlow detection flag + * @arg @ref I2C_FLAG_ALERT SMBus alert + * + * @retval None + */ +#define __HAL_I2C_CLEAR_FLAG(__HANDLE__, __FLAG__) (((__FLAG__) == I2C_FLAG_TXE) ? ((__HANDLE__)->Instance->ISR |= (__FLAG__)) \ + : ((__HANDLE__)->Instance->ICR = (__FLAG__))) + +/** @brief Enable the specified I2C peripheral. + * @param __HANDLE__ specifies the I2C Handle. + * @retval None + */ +#define __HAL_I2C_ENABLE(__HANDLE__) (SET_BIT((__HANDLE__)->Instance->CR1, I2C_CR1_PE)) + +/** @brief Disable the specified I2C peripheral. + * @param __HANDLE__ specifies the I2C Handle. + * @retval None + */ +#define __HAL_I2C_DISABLE(__HANDLE__) (CLEAR_BIT((__HANDLE__)->Instance->CR1, I2C_CR1_PE)) + +/** @brief Generate a Non-Acknowledge I2C peripheral in Slave mode. + * @param __HANDLE__ specifies the I2C Handle. + * @retval None + */ +#define __HAL_I2C_GENERATE_NACK(__HANDLE__) (SET_BIT((__HANDLE__)->Instance->CR2, I2C_CR2_NACK)) +/** + * @} + */ + +/* Include I2C HAL Extended module */ +#include "stm32f0xx_hal_i2c_ex.h" + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup I2C_Exported_Functions + * @{ + */ + +/** @addtogroup I2C_Exported_Functions_Group1 Initialization and de-initialization functions + * @{ + */ +/* Initialization and de-initialization functions******************************/ +HAL_StatusTypeDef HAL_I2C_Init(I2C_HandleTypeDef *hi2c); +HAL_StatusTypeDef HAL_I2C_DeInit(I2C_HandleTypeDef *hi2c); +void HAL_I2C_MspInit(I2C_HandleTypeDef *hi2c); +void HAL_I2C_MspDeInit(I2C_HandleTypeDef *hi2c); + +/* Callbacks Register/UnRegister functions ***********************************/ +#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1) +HAL_StatusTypeDef HAL_I2C_RegisterCallback(I2C_HandleTypeDef *hi2c, HAL_I2C_CallbackIDTypeDef CallbackID, pI2C_CallbackTypeDef pCallback); +HAL_StatusTypeDef HAL_I2C_UnRegisterCallback(I2C_HandleTypeDef *hi2c, HAL_I2C_CallbackIDTypeDef CallbackID); + +HAL_StatusTypeDef HAL_I2C_RegisterAddrCallback(I2C_HandleTypeDef *hi2c, pI2C_AddrCallbackTypeDef pCallback); +HAL_StatusTypeDef HAL_I2C_UnRegisterAddrCallback(I2C_HandleTypeDef *hi2c); +#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */ +/** + * @} + */ + +/** @addtogroup I2C_Exported_Functions_Group2 Input and Output operation functions + * @{ + */ +/* IO operation functions ****************************************************/ +/******* Blocking mode: Polling */ +HAL_StatusTypeDef HAL_I2C_Master_Transmit(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout); +HAL_StatusTypeDef HAL_I2C_Master_Receive(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout); +HAL_StatusTypeDef HAL_I2C_Slave_Transmit(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t Timeout); +HAL_StatusTypeDef HAL_I2C_Slave_Receive(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t Timeout); +HAL_StatusTypeDef HAL_I2C_Mem_Write(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout); +HAL_StatusTypeDef HAL_I2C_Mem_Read(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout); +HAL_StatusTypeDef HAL_I2C_IsDeviceReady(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint32_t Trials, uint32_t Timeout); + +/******* Non-Blocking mode: Interrupt */ +HAL_StatusTypeDef HAL_I2C_Master_Transmit_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size); +HAL_StatusTypeDef HAL_I2C_Master_Receive_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size); +HAL_StatusTypeDef HAL_I2C_Slave_Transmit_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size); +HAL_StatusTypeDef HAL_I2C_Slave_Receive_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size); +HAL_StatusTypeDef HAL_I2C_Mem_Write_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size); +HAL_StatusTypeDef HAL_I2C_Mem_Read_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size); + +HAL_StatusTypeDef HAL_I2C_Master_Seq_Transmit_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t XferOptions); +HAL_StatusTypeDef HAL_I2C_Master_Seq_Receive_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t XferOptions); +HAL_StatusTypeDef HAL_I2C_Slave_Seq_Transmit_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t XferOptions); +HAL_StatusTypeDef HAL_I2C_Slave_Seq_Receive_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t XferOptions); +HAL_StatusTypeDef HAL_I2C_EnableListen_IT(I2C_HandleTypeDef *hi2c); +HAL_StatusTypeDef HAL_I2C_DisableListen_IT(I2C_HandleTypeDef *hi2c); +HAL_StatusTypeDef HAL_I2C_Master_Abort_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress); + +/******* Non-Blocking mode: DMA */ +HAL_StatusTypeDef HAL_I2C_Master_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size); +HAL_StatusTypeDef HAL_I2C_Master_Receive_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size); +HAL_StatusTypeDef HAL_I2C_Slave_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size); +HAL_StatusTypeDef HAL_I2C_Slave_Receive_DMA(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size); +HAL_StatusTypeDef HAL_I2C_Mem_Write_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size); +HAL_StatusTypeDef HAL_I2C_Mem_Read_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size); + +HAL_StatusTypeDef HAL_I2C_Master_Seq_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t XferOptions); +HAL_StatusTypeDef HAL_I2C_Master_Seq_Receive_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t XferOptions); +HAL_StatusTypeDef HAL_I2C_Slave_Seq_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t XferOptions); +HAL_StatusTypeDef HAL_I2C_Slave_Seq_Receive_DMA(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t XferOptions); +/** + * @} + */ + +/** @addtogroup I2C_IRQ_Handler_and_Callbacks IRQ Handler and Callbacks + * @{ + */ +/******* I2C IRQHandler and Callbacks used in non blocking modes (Interrupt and DMA) */ +void HAL_I2C_EV_IRQHandler(I2C_HandleTypeDef *hi2c); +void HAL_I2C_ER_IRQHandler(I2C_HandleTypeDef *hi2c); +void HAL_I2C_MasterTxCpltCallback(I2C_HandleTypeDef *hi2c); +void HAL_I2C_MasterRxCpltCallback(I2C_HandleTypeDef *hi2c); +void HAL_I2C_SlaveTxCpltCallback(I2C_HandleTypeDef *hi2c); +void HAL_I2C_SlaveRxCpltCallback(I2C_HandleTypeDef *hi2c); +void HAL_I2C_AddrCallback(I2C_HandleTypeDef *hi2c, uint8_t TransferDirection, uint16_t AddrMatchCode); +void HAL_I2C_ListenCpltCallback(I2C_HandleTypeDef *hi2c); +void HAL_I2C_MemTxCpltCallback(I2C_HandleTypeDef *hi2c); +void HAL_I2C_MemRxCpltCallback(I2C_HandleTypeDef *hi2c); +void HAL_I2C_ErrorCallback(I2C_HandleTypeDef *hi2c); +void HAL_I2C_AbortCpltCallback(I2C_HandleTypeDef *hi2c); +/** + * @} + */ + +/** @addtogroup I2C_Exported_Functions_Group3 Peripheral State, Mode and Error functions + * @{ + */ +/* Peripheral State, Mode and Error functions *********************************/ +HAL_I2C_StateTypeDef HAL_I2C_GetState(I2C_HandleTypeDef *hi2c); +HAL_I2C_ModeTypeDef HAL_I2C_GetMode(I2C_HandleTypeDef *hi2c); +uint32_t HAL_I2C_GetError(I2C_HandleTypeDef *hi2c); + +/** + * @} + */ + +/** + * @} + */ + +/* Private constants ---------------------------------------------------------*/ +/** @defgroup I2C_Private_Constants I2C Private Constants + * @{ + */ + +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup I2C_Private_Macro I2C Private Macros + * @{ + */ + +#define IS_I2C_ADDRESSING_MODE(MODE) (((MODE) == I2C_ADDRESSINGMODE_7BIT) || \ + ((MODE) == I2C_ADDRESSINGMODE_10BIT)) + +#define IS_I2C_DUAL_ADDRESS(ADDRESS) (((ADDRESS) == I2C_DUALADDRESS_DISABLE) || \ + ((ADDRESS) == I2C_DUALADDRESS_ENABLE)) + +#define IS_I2C_OWN_ADDRESS2_MASK(MASK) (((MASK) == I2C_OA2_NOMASK) || \ + ((MASK) == I2C_OA2_MASK01) || \ + ((MASK) == I2C_OA2_MASK02) || \ + ((MASK) == I2C_OA2_MASK03) || \ + ((MASK) == I2C_OA2_MASK04) || \ + ((MASK) == I2C_OA2_MASK05) || \ + ((MASK) == I2C_OA2_MASK06) || \ + ((MASK) == I2C_OA2_MASK07)) + +#define IS_I2C_GENERAL_CALL(CALL) (((CALL) == I2C_GENERALCALL_DISABLE) || \ + ((CALL) == I2C_GENERALCALL_ENABLE)) + +#define IS_I2C_NO_STRETCH(STRETCH) (((STRETCH) == I2C_NOSTRETCH_DISABLE) || \ + ((STRETCH) == I2C_NOSTRETCH_ENABLE)) + +#define IS_I2C_MEMADD_SIZE(SIZE) (((SIZE) == I2C_MEMADD_SIZE_8BIT) || \ + ((SIZE) == I2C_MEMADD_SIZE_16BIT)) + +#define IS_TRANSFER_MODE(MODE) (((MODE) == I2C_RELOAD_MODE) || \ + ((MODE) == I2C_AUTOEND_MODE) || \ + ((MODE) == I2C_SOFTEND_MODE)) + +#define IS_TRANSFER_REQUEST(REQUEST) (((REQUEST) == I2C_GENERATE_STOP) || \ + ((REQUEST) == I2C_GENERATE_START_READ) || \ + ((REQUEST) == I2C_GENERATE_START_WRITE) || \ + ((REQUEST) == I2C_NO_STARTSTOP)) + +#define IS_I2C_TRANSFER_OPTIONS_REQUEST(REQUEST) (((REQUEST) == I2C_FIRST_FRAME) || \ + ((REQUEST) == I2C_FIRST_AND_NEXT_FRAME) || \ + ((REQUEST) == I2C_NEXT_FRAME) || \ + ((REQUEST) == I2C_FIRST_AND_LAST_FRAME) || \ + ((REQUEST) == I2C_LAST_FRAME) || \ + ((REQUEST) == I2C_LAST_FRAME_NO_STOP) || \ + IS_I2C_TRANSFER_OTHER_OPTIONS_REQUEST(REQUEST)) + +#define IS_I2C_TRANSFER_OTHER_OPTIONS_REQUEST(REQUEST) (((REQUEST) == I2C_OTHER_FRAME) || \ + ((REQUEST) == I2C_OTHER_AND_LAST_FRAME)) + +#define I2C_RESET_CR2(__HANDLE__) ((__HANDLE__)->Instance->CR2 &= (uint32_t)~((uint32_t)(I2C_CR2_SADD | I2C_CR2_HEAD10R | I2C_CR2_NBYTES | I2C_CR2_RELOAD | I2C_CR2_RD_WRN))) + +#define I2C_GET_ADDR_MATCH(__HANDLE__) ((uint16_t)(((__HANDLE__)->Instance->ISR & I2C_ISR_ADDCODE) >> 16U)) +#define I2C_GET_DIR(__HANDLE__) ((uint8_t)(((__HANDLE__)->Instance->ISR & I2C_ISR_DIR) >> 16U)) +#define I2C_GET_STOP_MODE(__HANDLE__) ((__HANDLE__)->Instance->CR2 & I2C_CR2_AUTOEND) +#define I2C_GET_OWN_ADDRESS1(__HANDLE__) ((uint16_t)((__HANDLE__)->Instance->OAR1 & I2C_OAR1_OA1)) +#define I2C_GET_OWN_ADDRESS2(__HANDLE__) ((uint16_t)((__HANDLE__)->Instance->OAR2 & I2C_OAR2_OA2)) + +#define IS_I2C_OWN_ADDRESS1(ADDRESS1) ((ADDRESS1) <= 0x000003FFU) +#define IS_I2C_OWN_ADDRESS2(ADDRESS2) ((ADDRESS2) <= (uint16_t)0x00FFU) + +#define I2C_MEM_ADD_MSB(__ADDRESS__) ((uint8_t)((uint16_t)(((uint16_t)((__ADDRESS__) & (uint16_t)(0xFF00U))) >> 8U))) +#define I2C_MEM_ADD_LSB(__ADDRESS__) ((uint8_t)((uint16_t)((__ADDRESS__) & (uint16_t)(0x00FFU)))) + +#define I2C_GENERATE_START(__ADDMODE__,__ADDRESS__) (((__ADDMODE__) == I2C_ADDRESSINGMODE_7BIT) ? (uint32_t)((((uint32_t)(__ADDRESS__) & (I2C_CR2_SADD)) | (I2C_CR2_START) | (I2C_CR2_AUTOEND)) & (~I2C_CR2_RD_WRN)) : \ + (uint32_t)((((uint32_t)(__ADDRESS__) & (I2C_CR2_SADD)) | (I2C_CR2_ADD10) | (I2C_CR2_START)) & (~I2C_CR2_RD_WRN))) + +#define I2C_CHECK_FLAG(__ISR__, __FLAG__) ((((__ISR__) & ((__FLAG__) & I2C_FLAG_MASK)) == ((__FLAG__) & I2C_FLAG_MASK)) ? SET : RESET) +#define I2C_CHECK_IT_SOURCE(__CR1__, __IT__) ((((__CR1__) & (__IT__)) == (__IT__)) ? SET : RESET) +/** + * @} + */ + +/* Private Functions ---------------------------------------------------------*/ +/** @defgroup I2C_Private_Functions I2C Private Functions + * @{ + */ +/* Private functions are defined in stm32f0xx_hal_i2c.c file */ +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + + +#endif /* STM32F0xx_HAL_I2C_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c_ex.h b/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c_ex.h new file mode 100644 index 0000000..ca388e0 --- /dev/null +++ b/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c_ex.h @@ -0,0 +1,172 @@ +/** + ****************************************************************************** + * @file stm32f0xx_hal_i2c_ex.h + * @author MCD Application Team + * @brief Header file of I2C HAL Extended module. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2016 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32F0xx_HAL_I2C_EX_H +#define STM32F0xx_HAL_I2C_EX_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f0xx_hal_def.h" + +/** @addtogroup STM32F0xx_HAL_Driver + * @{ + */ + +/** @addtogroup I2CEx + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup I2CEx_Exported_Constants I2C Extended Exported Constants + * @{ + */ + +/** @defgroup I2CEx_Analog_Filter I2C Extended Analog Filter + * @{ + */ +#define I2C_ANALOGFILTER_ENABLE 0x00000000U +#define I2C_ANALOGFILTER_DISABLE I2C_CR1_ANFOFF +/** + * @} + */ + +/** @defgroup I2CEx_FastModePlus I2C Extended Fast Mode Plus + * @{ + */ +#define I2C_FMP_NOT_SUPPORTED 0xAAAA0000U /*!< Fast Mode Plus not supported */ +#if defined(SYSCFG_CFGR1_I2C_FMP_PA9) +#define I2C_FASTMODEPLUS_PA9 SYSCFG_CFGR1_I2C_FMP_PA9 /*!< Enable Fast Mode Plus on PA9 */ +#define I2C_FASTMODEPLUS_PA10 SYSCFG_CFGR1_I2C_FMP_PA10 /*!< Enable Fast Mode Plus on PA10 */ +#else +#define I2C_FASTMODEPLUS_PA9 (uint32_t)(0x00000001U | I2C_FMP_NOT_SUPPORTED) /*!< Fast Mode Plus PA9 not supported */ +#define I2C_FASTMODEPLUS_PA10 (uint32_t)(0x00000002U | I2C_FMP_NOT_SUPPORTED) /*!< Fast Mode Plus PA10 not supported */ +#endif +#define I2C_FASTMODEPLUS_PB6 SYSCFG_CFGR1_I2C_FMP_PB6 /*!< Enable Fast Mode Plus on PB6 */ +#define I2C_FASTMODEPLUS_PB7 SYSCFG_CFGR1_I2C_FMP_PB7 /*!< Enable Fast Mode Plus on PB7 */ +#define I2C_FASTMODEPLUS_PB8 SYSCFG_CFGR1_I2C_FMP_PB8 /*!< Enable Fast Mode Plus on PB8 */ +#define I2C_FASTMODEPLUS_PB9 SYSCFG_CFGR1_I2C_FMP_PB9 /*!< Enable Fast Mode Plus on PB9 */ +#if defined(SYSCFG_CFGR1_I2C_FMP_I2C1) +#define I2C_FASTMODEPLUS_I2C1 SYSCFG_CFGR1_I2C_FMP_I2C1 /*!< Enable Fast Mode Plus on I2C1 pins */ +#else +#define I2C_FASTMODEPLUS_I2C1 (uint32_t)(0x00000100U | I2C_FMP_NOT_SUPPORTED) /*!< Fast Mode Plus I2C1 not supported */ +#endif +#if defined(SYSCFG_CFGR1_I2C_FMP_I2C2) +#define I2C_FASTMODEPLUS_I2C2 SYSCFG_CFGR1_I2C_FMP_I2C2 /*!< Enable Fast Mode Plus on I2C2 pins */ +#else +#define I2C_FASTMODEPLUS_I2C2 (uint32_t)(0x00000200U | I2C_FMP_NOT_SUPPORTED) /*!< Fast Mode Plus I2C2 not supported */ +#endif +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ + +/** @addtogroup I2CEx_Exported_Functions I2C Extended Exported Functions + * @{ + */ + +/** @addtogroup I2CEx_Exported_Functions_Group1 Extended features functions + * @brief Extended features functions + * @{ + */ + +/* Peripheral Control functions ************************************************/ +HAL_StatusTypeDef HAL_I2CEx_ConfigAnalogFilter(I2C_HandleTypeDef *hi2c, uint32_t AnalogFilter); +HAL_StatusTypeDef HAL_I2CEx_ConfigDigitalFilter(I2C_HandleTypeDef *hi2c, uint32_t DigitalFilter); +#if defined(I2C_CR1_WUPEN) +HAL_StatusTypeDef HAL_I2CEx_EnableWakeUp(I2C_HandleTypeDef *hi2c); +HAL_StatusTypeDef HAL_I2CEx_DisableWakeUp(I2C_HandleTypeDef *hi2c); +#endif +void HAL_I2CEx_EnableFastModePlus(uint32_t ConfigFastModePlus); +void HAL_I2CEx_DisableFastModePlus(uint32_t ConfigFastModePlus); + +/* Private constants ---------------------------------------------------------*/ +/** @defgroup I2CEx_Private_Constants I2C Extended Private Constants + * @{ + */ + +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup I2CEx_Private_Macro I2C Extended Private Macros + * @{ + */ +#define IS_I2C_ANALOG_FILTER(FILTER) (((FILTER) == I2C_ANALOGFILTER_ENABLE) || \ + ((FILTER) == I2C_ANALOGFILTER_DISABLE)) + +#define IS_I2C_DIGITAL_FILTER(FILTER) ((FILTER) <= 0x0000000FU) + +#define IS_I2C_FASTMODEPLUS(__CONFIG__) ((((__CONFIG__) & I2C_FMP_NOT_SUPPORTED) != I2C_FMP_NOT_SUPPORTED) && \ + ((((__CONFIG__) & (I2C_FASTMODEPLUS_PA9)) == I2C_FASTMODEPLUS_PA9) || \ + (((__CONFIG__) & (I2C_FASTMODEPLUS_PA10)) == I2C_FASTMODEPLUS_PA10) || \ + (((__CONFIG__) & (I2C_FASTMODEPLUS_PB6)) == I2C_FASTMODEPLUS_PB6) || \ + (((__CONFIG__) & (I2C_FASTMODEPLUS_PB7)) == I2C_FASTMODEPLUS_PB7) || \ + (((__CONFIG__) & (I2C_FASTMODEPLUS_PB8)) == I2C_FASTMODEPLUS_PB8) || \ + (((__CONFIG__) & (I2C_FASTMODEPLUS_PB9)) == I2C_FASTMODEPLUS_PB9) || \ + (((__CONFIG__) & (I2C_FASTMODEPLUS_I2C1)) == I2C_FASTMODEPLUS_I2C1) || \ + (((__CONFIG__) & (I2C_FASTMODEPLUS_I2C2)) == I2C_FASTMODEPLUS_I2C2))) +/** + * @} + */ + +/* Private Functions ---------------------------------------------------------*/ +/** @defgroup I2CEx_Private_Functions I2C Extended Private Functions + * @{ + */ +/* Private functions are defined in stm32f0xx_hal_i2c_ex.c file */ +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32F0xx_HAL_I2C_EX_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd.h b/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd.h new file mode 100644 index 0000000..00b7047 --- /dev/null +++ b/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd.h @@ -0,0 +1,945 @@ +/** + ****************************************************************************** + * @file stm32f0xx_hal_pcd.h + * @author MCD Application Team + * @brief Header file of PCD HAL module. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2016 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32F0xx_HAL_PCD_H +#define STM32F0xx_HAL_PCD_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f0xx_ll_usb.h" + +#if defined (USB) + +/** @addtogroup STM32F0xx_HAL_Driver + * @{ + */ + +/** @addtogroup PCD + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup PCD_Exported_Types PCD Exported Types + * @{ + */ + +/** + * @brief PCD State structure definition + */ +typedef enum +{ + HAL_PCD_STATE_RESET = 0x00, + HAL_PCD_STATE_READY = 0x01, + HAL_PCD_STATE_ERROR = 0x02, + HAL_PCD_STATE_BUSY = 0x03, + HAL_PCD_STATE_TIMEOUT = 0x04 +} PCD_StateTypeDef; + +/* Device LPM suspend state */ +typedef enum +{ + LPM_L0 = 0x00, /* on */ + LPM_L1 = 0x01, /* LPM L1 sleep */ + LPM_L2 = 0x02, /* suspend */ + LPM_L3 = 0x03, /* off */ +} PCD_LPM_StateTypeDef; + +typedef enum +{ + PCD_LPM_L0_ACTIVE = 0x00, /* on */ + PCD_LPM_L1_ACTIVE = 0x01, /* LPM L1 sleep */ +} PCD_LPM_MsgTypeDef; + +typedef enum +{ + PCD_BCD_ERROR = 0xFF, + PCD_BCD_CONTACT_DETECTION = 0xFE, + PCD_BCD_STD_DOWNSTREAM_PORT = 0xFD, + PCD_BCD_CHARGING_DOWNSTREAM_PORT = 0xFC, + PCD_BCD_DEDICATED_CHARGING_PORT = 0xFB, + PCD_BCD_DISCOVERY_COMPLETED = 0x00, + +} PCD_BCD_MsgTypeDef; + + + + + +typedef USB_TypeDef PCD_TypeDef; +typedef USB_CfgTypeDef PCD_InitTypeDef; +typedef USB_EPTypeDef PCD_EPTypeDef; + + +/** + * @brief PCD Handle Structure definition + */ +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) +typedef struct __PCD_HandleTypeDef +#else +typedef struct +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ +{ + PCD_TypeDef *Instance; /*!< Register base address */ + PCD_InitTypeDef Init; /*!< PCD required parameters */ + __IO uint8_t USB_Address; /*!< USB Address */ + PCD_EPTypeDef IN_ep[8]; /*!< IN endpoint parameters */ + PCD_EPTypeDef OUT_ep[8]; /*!< OUT endpoint parameters */ + HAL_LockTypeDef Lock; /*!< PCD peripheral status */ + __IO PCD_StateTypeDef State; /*!< PCD communication state */ + __IO uint32_t ErrorCode; /*!< PCD Error code */ + uint32_t Setup[12]; /*!< Setup packet buffer */ + PCD_LPM_StateTypeDef LPM_State; /*!< LPM State */ + uint32_t BESL; + + + uint32_t lpm_active; /*!< Enable or disable the Link Power Management . + This parameter can be set to ENABLE or DISABLE */ + + uint32_t battery_charging_active; /*!< Enable or disable Battery charging. + This parameter can be set to ENABLE or DISABLE */ + void *pData; /*!< Pointer to upper stack Handler */ + +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) + void (* SOFCallback)(struct __PCD_HandleTypeDef *hpcd); /*!< USB OTG PCD SOF callback */ + void (* SetupStageCallback)(struct __PCD_HandleTypeDef *hpcd); /*!< USB OTG PCD Setup Stage callback */ + void (* ResetCallback)(struct __PCD_HandleTypeDef *hpcd); /*!< USB OTG PCD Reset callback */ + void (* SuspendCallback)(struct __PCD_HandleTypeDef *hpcd); /*!< USB OTG PCD Suspend callback */ + void (* ResumeCallback)(struct __PCD_HandleTypeDef *hpcd); /*!< USB OTG PCD Resume callback */ + void (* ConnectCallback)(struct __PCD_HandleTypeDef *hpcd); /*!< USB OTG PCD Connect callback */ + void (* DisconnectCallback)(struct __PCD_HandleTypeDef *hpcd); /*!< USB OTG PCD Disconnect callback */ + + void (* DataOutStageCallback)(struct __PCD_HandleTypeDef *hpcd, uint8_t epnum); /*!< USB OTG PCD Data OUT Stage callback */ + void (* DataInStageCallback)(struct __PCD_HandleTypeDef *hpcd, uint8_t epnum); /*!< USB OTG PCD Data IN Stage callback */ + void (* ISOOUTIncompleteCallback)(struct __PCD_HandleTypeDef *hpcd, uint8_t epnum); /*!< USB OTG PCD ISO OUT Incomplete callback */ + void (* ISOINIncompleteCallback)(struct __PCD_HandleTypeDef *hpcd, uint8_t epnum); /*!< USB OTG PCD ISO IN Incomplete callback */ + void (* BCDCallback)(struct __PCD_HandleTypeDef *hpcd, PCD_BCD_MsgTypeDef msg); /*!< USB OTG PCD BCD callback */ + void (* LPMCallback)(struct __PCD_HandleTypeDef *hpcd, PCD_LPM_MsgTypeDef msg); /*!< USB OTG PCD LPM callback */ + + void (* MspInitCallback)(struct __PCD_HandleTypeDef *hpcd); /*!< USB OTG PCD Msp Init callback */ + void (* MspDeInitCallback)(struct __PCD_HandleTypeDef *hpcd); /*!< USB OTG PCD Msp DeInit callback */ +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ +} PCD_HandleTypeDef; + +/** + * @} + */ + +/* Include PCD HAL Extended module */ +#include "stm32f0xx_hal_pcd_ex.h" + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup PCD_Exported_Constants PCD Exported Constants + * @{ + */ + +/** @defgroup PCD_Speed PCD Speed + * @{ + */ +#define PCD_SPEED_FULL USBD_FS_SPEED +/** + * @} + */ + +/** @defgroup PCD_PHY_Module PCD PHY Module + * @{ + */ +#define PCD_PHY_ULPI 1U +#define PCD_PHY_EMBEDDED 2U +#define PCD_PHY_UTMI 3U +/** + * @} + */ + +/** @defgroup PCD_Error_Code_definition PCD Error Code definition + * @brief PCD Error Code definition + * @{ + */ +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) +#define HAL_PCD_ERROR_INVALID_CALLBACK (0x00000010U) /*!< Invalid Callback error */ +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ + +/** + * @} + */ + +/** + * @} + */ + +/* Exported macros -----------------------------------------------------------*/ +/** @defgroup PCD_Exported_Macros PCD Exported Macros + * @brief macros to handle interrupts and specific clock configurations + * @{ + */ + + +#define __HAL_PCD_ENABLE(__HANDLE__) (void)USB_EnableGlobalInt ((__HANDLE__)->Instance) +#define __HAL_PCD_DISABLE(__HANDLE__) (void)USB_DisableGlobalInt ((__HANDLE__)->Instance) +#define __HAL_PCD_GET_FLAG(__HANDLE__, __INTERRUPT__) ((USB_ReadInterrupts((__HANDLE__)->Instance) & (__INTERRUPT__)) == (__INTERRUPT__)) +#define __HAL_PCD_CLEAR_FLAG(__HANDLE__, __INTERRUPT__) (((__HANDLE__)->Instance->ISTR) &= ~(__INTERRUPT__)) + +#define __HAL_USB_WAKEUP_EXTI_ENABLE_IT() EXTI->IMR |= USB_WAKEUP_EXTI_LINE +#define __HAL_USB_WAKEUP_EXTI_DISABLE_IT() EXTI->IMR &= ~(USB_WAKEUP_EXTI_LINE) + + +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup PCD_Exported_Functions PCD Exported Functions + * @{ + */ + +/* Initialization/de-initialization functions ********************************/ +/** @addtogroup PCD_Exported_Functions_Group1 Initialization and de-initialization functions + * @{ + */ +HAL_StatusTypeDef HAL_PCD_Init(PCD_HandleTypeDef *hpcd); +HAL_StatusTypeDef HAL_PCD_DeInit(PCD_HandleTypeDef *hpcd); +void HAL_PCD_MspInit(PCD_HandleTypeDef *hpcd); +void HAL_PCD_MspDeInit(PCD_HandleTypeDef *hpcd); + +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) +/** @defgroup HAL_PCD_Callback_ID_enumeration_definition HAL USB OTG PCD Callback ID enumeration definition + * @brief HAL USB OTG PCD Callback ID enumeration definition + * @{ + */ +typedef enum +{ + HAL_PCD_SOF_CB_ID = 0x01, /*!< USB PCD SOF callback ID */ + HAL_PCD_SETUPSTAGE_CB_ID = 0x02, /*!< USB PCD Setup Stage callback ID */ + HAL_PCD_RESET_CB_ID = 0x03, /*!< USB PCD Reset callback ID */ + HAL_PCD_SUSPEND_CB_ID = 0x04, /*!< USB PCD Suspend callback ID */ + HAL_PCD_RESUME_CB_ID = 0x05, /*!< USB PCD Resume callback ID */ + HAL_PCD_CONNECT_CB_ID = 0x06, /*!< USB PCD Connect callback ID */ + HAL_PCD_DISCONNECT_CB_ID = 0x07, /*!< USB PCD Disconnect callback ID */ + + HAL_PCD_MSPINIT_CB_ID = 0x08, /*!< USB PCD MspInit callback ID */ + HAL_PCD_MSPDEINIT_CB_ID = 0x09 /*!< USB PCD MspDeInit callback ID */ + +} HAL_PCD_CallbackIDTypeDef; +/** + * @} + */ + +/** @defgroup HAL_PCD_Callback_pointer_definition HAL USB OTG PCD Callback pointer definition + * @brief HAL USB OTG PCD Callback pointer definition + * @{ + */ + +typedef void (*pPCD_CallbackTypeDef)(PCD_HandleTypeDef *hpcd); /*!< pointer to a common USB OTG PCD callback function */ +typedef void (*pPCD_DataOutStageCallbackTypeDef)(PCD_HandleTypeDef *hpcd, uint8_t epnum); /*!< pointer to USB OTG PCD Data OUT Stage callback */ +typedef void (*pPCD_DataInStageCallbackTypeDef)(PCD_HandleTypeDef *hpcd, uint8_t epnum); /*!< pointer to USB OTG PCD Data IN Stage callback */ +typedef void (*pPCD_IsoOutIncpltCallbackTypeDef)(PCD_HandleTypeDef *hpcd, uint8_t epnum); /*!< pointer to USB OTG PCD ISO OUT Incomplete callback */ +typedef void (*pPCD_IsoInIncpltCallbackTypeDef)(PCD_HandleTypeDef *hpcd, uint8_t epnum); /*!< pointer to USB OTG PCD ISO IN Incomplete callback */ +typedef void (*pPCD_LpmCallbackTypeDef)(PCD_HandleTypeDef *hpcd, PCD_LPM_MsgTypeDef msg); /*!< pointer to USB OTG PCD LPM callback */ +typedef void (*pPCD_BcdCallbackTypeDef)(PCD_HandleTypeDef *hpcd, PCD_BCD_MsgTypeDef msg); /*!< pointer to USB OTG PCD BCD callback */ + +/** + * @} + */ + +HAL_StatusTypeDef HAL_PCD_RegisterCallback(PCD_HandleTypeDef *hpcd, HAL_PCD_CallbackIDTypeDef CallbackID, pPCD_CallbackTypeDef pCallback); +HAL_StatusTypeDef HAL_PCD_UnRegisterCallback(PCD_HandleTypeDef *hpcd, HAL_PCD_CallbackIDTypeDef CallbackID); + +HAL_StatusTypeDef HAL_PCD_RegisterDataOutStageCallback(PCD_HandleTypeDef *hpcd, pPCD_DataOutStageCallbackTypeDef pCallback); +HAL_StatusTypeDef HAL_PCD_UnRegisterDataOutStageCallback(PCD_HandleTypeDef *hpcd); + +HAL_StatusTypeDef HAL_PCD_RegisterDataInStageCallback(PCD_HandleTypeDef *hpcd, pPCD_DataInStageCallbackTypeDef pCallback); +HAL_StatusTypeDef HAL_PCD_UnRegisterDataInStageCallback(PCD_HandleTypeDef *hpcd); + +HAL_StatusTypeDef HAL_PCD_RegisterIsoOutIncpltCallback(PCD_HandleTypeDef *hpcd, pPCD_IsoOutIncpltCallbackTypeDef pCallback); +HAL_StatusTypeDef HAL_PCD_UnRegisterIsoOutIncpltCallback(PCD_HandleTypeDef *hpcd); + +HAL_StatusTypeDef HAL_PCD_RegisterIsoInIncpltCallback(PCD_HandleTypeDef *hpcd, pPCD_IsoInIncpltCallbackTypeDef pCallback); +HAL_StatusTypeDef HAL_PCD_UnRegisterIsoInIncpltCallback(PCD_HandleTypeDef *hpcd); + +HAL_StatusTypeDef HAL_PCD_RegisterBcdCallback(PCD_HandleTypeDef *hpcd, pPCD_BcdCallbackTypeDef pCallback); +HAL_StatusTypeDef HAL_PCD_UnRegisterBcdCallback(PCD_HandleTypeDef *hpcd); + +HAL_StatusTypeDef HAL_PCD_RegisterLpmCallback(PCD_HandleTypeDef *hpcd, pPCD_LpmCallbackTypeDef pCallback); +HAL_StatusTypeDef HAL_PCD_UnRegisterLpmCallback(PCD_HandleTypeDef *hpcd); +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ +/** + * @} + */ + +/* I/O operation functions ***************************************************/ +/* Non-Blocking mode: Interrupt */ +/** @addtogroup PCD_Exported_Functions_Group2 Input and Output operation functions + * @{ + */ +HAL_StatusTypeDef HAL_PCD_Start(PCD_HandleTypeDef *hpcd); +HAL_StatusTypeDef HAL_PCD_Stop(PCD_HandleTypeDef *hpcd); +void HAL_PCD_IRQHandler(PCD_HandleTypeDef *hpcd); + +void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd); +void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd); +void HAL_PCD_ResetCallback(PCD_HandleTypeDef *hpcd); +void HAL_PCD_SuspendCallback(PCD_HandleTypeDef *hpcd); +void HAL_PCD_ResumeCallback(PCD_HandleTypeDef *hpcd); +void HAL_PCD_ConnectCallback(PCD_HandleTypeDef *hpcd); +void HAL_PCD_DisconnectCallback(PCD_HandleTypeDef *hpcd); + +void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum); +void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum); +void HAL_PCD_ISOOUTIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum); +void HAL_PCD_ISOINIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum); +/** + * @} + */ + +/* Peripheral Control functions **********************************************/ +/** @addtogroup PCD_Exported_Functions_Group3 Peripheral Control functions + * @{ + */ +HAL_StatusTypeDef HAL_PCD_DevConnect(PCD_HandleTypeDef *hpcd); +HAL_StatusTypeDef HAL_PCD_DevDisconnect(PCD_HandleTypeDef *hpcd); +HAL_StatusTypeDef HAL_PCD_SetAddress(PCD_HandleTypeDef *hpcd, uint8_t address); +HAL_StatusTypeDef HAL_PCD_EP_Open(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint16_t ep_mps, uint8_t ep_type); +HAL_StatusTypeDef HAL_PCD_EP_Close(PCD_HandleTypeDef *hpcd, uint8_t ep_addr); +HAL_StatusTypeDef HAL_PCD_EP_Receive(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len); +HAL_StatusTypeDef HAL_PCD_EP_Transmit(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len); +uint32_t HAL_PCD_EP_GetRxCount(PCD_HandleTypeDef *hpcd, uint8_t ep_addr); +HAL_StatusTypeDef HAL_PCD_EP_SetStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr); +HAL_StatusTypeDef HAL_PCD_EP_ClrStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr); +HAL_StatusTypeDef HAL_PCD_EP_Flush(PCD_HandleTypeDef *hpcd, uint8_t ep_addr); +HAL_StatusTypeDef HAL_PCD_ActivateRemoteWakeup(PCD_HandleTypeDef *hpcd); +HAL_StatusTypeDef HAL_PCD_DeActivateRemoteWakeup(PCD_HandleTypeDef *hpcd); +/** + * @} + */ + +/* Peripheral State functions ************************************************/ +/** @addtogroup PCD_Exported_Functions_Group4 Peripheral State functions + * @{ + */ +PCD_StateTypeDef HAL_PCD_GetState(PCD_HandleTypeDef *hpcd); +/** + * @} + */ + +/** + * @} + */ + +/* Private constants ---------------------------------------------------------*/ +/** @defgroup PCD_Private_Constants PCD Private Constants + * @{ + */ +/** @defgroup USB_EXTI_Line_Interrupt USB EXTI line interrupt + * @{ + */ + + +#define USB_WAKEUP_EXTI_LINE (0x1U << 18) /*!< USB FS EXTI Line WakeUp Interrupt */ + + +/** + * @} + */ + +/** @defgroup PCD_EP0_MPS PCD EP0 MPS + * @{ + */ +#define PCD_EP0MPS_64 DEP0CTL_MPS_64 +#define PCD_EP0MPS_32 DEP0CTL_MPS_32 +#define PCD_EP0MPS_16 DEP0CTL_MPS_16 +#define PCD_EP0MPS_08 DEP0CTL_MPS_8 +/** + * @} + */ + +/** @defgroup PCD_ENDP PCD ENDP + * @{ + */ +#define PCD_ENDP0 0U +#define PCD_ENDP1 1U +#define PCD_ENDP2 2U +#define PCD_ENDP3 3U +#define PCD_ENDP4 4U +#define PCD_ENDP5 5U +#define PCD_ENDP6 6U +#define PCD_ENDP7 7U +/** + * @} + */ + +/** @defgroup PCD_ENDP_Kind PCD Endpoint Kind + * @{ + */ +#define PCD_SNG_BUF 0U +#define PCD_DBL_BUF 1U +/** + * @} + */ + +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup PCD_Private_Macros PCD Private Macros + * @{ + */ + +/******************** Bit definition for USB_COUNTn_RX register *************/ +#define USB_CNTRX_NBLK_MSK (0x1FU << 10) +#define USB_CNTRX_BLSIZE (0x1U << 15) + +/* SetENDPOINT */ +#define PCD_SET_ENDPOINT(USBx, bEpNum, wRegValue) (*(__IO uint16_t *)(&(USBx)->EP0R + ((bEpNum) * 2U)) = (uint16_t)(wRegValue)) + +/* GetENDPOINT */ +#define PCD_GET_ENDPOINT(USBx, bEpNum) (*(__IO uint16_t *)(&(USBx)->EP0R + ((bEpNum) * 2U))) + +/* ENDPOINT transfer */ +#define USB_EP0StartXfer USB_EPStartXfer + +/** + * @brief sets the type in the endpoint register(bits EP_TYPE[1:0]) + * @param USBx USB peripheral instance register address. + * @param bEpNum Endpoint Number. + * @param wType Endpoint Type. + * @retval None + */ +#define PCD_SET_EPTYPE(USBx, bEpNum, wType) (PCD_SET_ENDPOINT((USBx), (bEpNum), \ + ((PCD_GET_ENDPOINT((USBx), (bEpNum)) & USB_EP_T_MASK) | (wType) | USB_EP_CTR_TX | USB_EP_CTR_RX))) + +/** + * @brief gets the type in the endpoint register(bits EP_TYPE[1:0]) + * @param USBx USB peripheral instance register address. + * @param bEpNum Endpoint Number. + * @retval Endpoint Type + */ +#define PCD_GET_EPTYPE(USBx, bEpNum) (PCD_GET_ENDPOINT((USBx), (bEpNum)) & USB_EP_T_FIELD) + +/** + * @brief free buffer used from the application realizing it to the line + * toggles bit SW_BUF in the double buffered endpoint register + * @param USBx USB device. + * @param bEpNum, bDir + * @retval None + */ +#define PCD_FreeUserBuffer(USBx, bEpNum, bDir) do { \ + if ((bDir) == 0U) \ + { \ + /* OUT double buffered endpoint */ \ + PCD_TX_DTOG((USBx), (bEpNum)); \ + } \ + else if ((bDir) == 1U) \ + { \ + /* IN double buffered endpoint */ \ + PCD_RX_DTOG((USBx), (bEpNum)); \ + } \ +} while(0) + +/** + * @brief sets the status for tx transfer (bits STAT_TX[1:0]). + * @param USBx USB peripheral instance register address. + * @param bEpNum Endpoint Number. + * @param wState new state + * @retval None + */ +#define PCD_SET_EP_TX_STATUS(USBx, bEpNum, wState) do { \ + register uint16_t _wRegVal; \ + \ + _wRegVal = PCD_GET_ENDPOINT((USBx), (bEpNum)) & USB_EPTX_DTOGMASK; \ + /* toggle first bit ? */ \ + if ((USB_EPTX_DTOG1 & (wState))!= 0U) \ + { \ + _wRegVal ^= USB_EPTX_DTOG1; \ + } \ + /* toggle second bit ? */ \ + if ((USB_EPTX_DTOG2 & (wState))!= 0U) \ + { \ + _wRegVal ^= USB_EPTX_DTOG2; \ + } \ + PCD_SET_ENDPOINT((USBx), (bEpNum), (_wRegVal | USB_EP_CTR_RX | USB_EP_CTR_TX)); \ + } while(0) /* PCD_SET_EP_TX_STATUS */ + +/** + * @brief sets the status for rx transfer (bits STAT_TX[1:0]) + * @param USBx USB peripheral instance register address. + * @param bEpNum Endpoint Number. + * @param wState new state + * @retval None + */ +#define PCD_SET_EP_RX_STATUS(USBx, bEpNum,wState) do { \ + register uint16_t _wRegVal; \ + \ + _wRegVal = PCD_GET_ENDPOINT((USBx), (bEpNum)) & USB_EPRX_DTOGMASK; \ + /* toggle first bit ? */ \ + if ((USB_EPRX_DTOG1 & (wState))!= 0U) \ + { \ + _wRegVal ^= USB_EPRX_DTOG1; \ + } \ + /* toggle second bit ? */ \ + if ((USB_EPRX_DTOG2 & (wState))!= 0U) \ + { \ + _wRegVal ^= USB_EPRX_DTOG2; \ + } \ + PCD_SET_ENDPOINT((USBx), (bEpNum), (_wRegVal | USB_EP_CTR_RX | USB_EP_CTR_TX)); \ + } while(0) /* PCD_SET_EP_RX_STATUS */ + +/** + * @brief sets the status for rx & tx (bits STAT_TX[1:0] & STAT_RX[1:0]) + * @param USBx USB peripheral instance register address. + * @param bEpNum Endpoint Number. + * @param wStaterx new state. + * @param wStatetx new state. + * @retval None + */ +#define PCD_SET_EP_TXRX_STATUS(USBx, bEpNum, wStaterx, wStatetx) do { \ + register uint16_t _wRegVal; \ + \ + _wRegVal = PCD_GET_ENDPOINT((USBx), (bEpNum)) & (USB_EPRX_DTOGMASK | USB_EPTX_STAT); \ + /* toggle first bit ? */ \ + if ((USB_EPRX_DTOG1 & (wStaterx))!= 0U) \ + { \ + _wRegVal ^= USB_EPRX_DTOG1; \ + } \ + /* toggle second bit ? */ \ + if ((USB_EPRX_DTOG2 & (wStaterx))!= 0U) \ + { \ + _wRegVal ^= USB_EPRX_DTOG2; \ + } \ + /* toggle first bit ? */ \ + if ((USB_EPTX_DTOG1 & (wStatetx))!= 0U) \ + { \ + _wRegVal ^= USB_EPTX_DTOG1; \ + } \ + /* toggle second bit ? */ \ + if ((USB_EPTX_DTOG2 & (wStatetx))!= 0U) \ + { \ + _wRegVal ^= USB_EPTX_DTOG2; \ + } \ + \ + PCD_SET_ENDPOINT((USBx), (bEpNum), (_wRegVal | USB_EP_CTR_RX | USB_EP_CTR_TX)); \ + } while(0) /* PCD_SET_EP_TXRX_STATUS */ + +/** + * @brief gets the status for tx/rx transfer (bits STAT_TX[1:0] + * /STAT_RX[1:0]) + * @param USBx USB peripheral instance register address. + * @param bEpNum Endpoint Number. + * @retval status + */ +#define PCD_GET_EP_TX_STATUS(USBx, bEpNum) ((uint16_t)PCD_GET_ENDPOINT((USBx), (bEpNum)) & USB_EPTX_STAT) +#define PCD_GET_EP_RX_STATUS(USBx, bEpNum) ((uint16_t)PCD_GET_ENDPOINT((USBx), (bEpNum)) & USB_EPRX_STAT) + +/** + * @brief sets directly the VALID tx/rx-status into the endpoint register + * @param USBx USB peripheral instance register address. + * @param bEpNum Endpoint Number. + * @retval None + */ +#define PCD_SET_EP_TX_VALID(USBx, bEpNum) (PCD_SET_EP_TX_STATUS((USBx), (bEpNum), USB_EP_TX_VALID)) +#define PCD_SET_EP_RX_VALID(USBx, bEpNum) (PCD_SET_EP_RX_STATUS((USBx), (bEpNum), USB_EP_RX_VALID)) + +/** + * @brief checks stall condition in an endpoint. + * @param USBx USB peripheral instance register address. + * @param bEpNum Endpoint Number. + * @retval TRUE = endpoint in stall condition. + */ +#define PCD_GET_EP_TX_STALL_STATUS(USBx, bEpNum) (PCD_GET_EP_TX_STATUS((USBx), (bEpNum)) \ + == USB_EP_TX_STALL) +#define PCD_GET_EP_RX_STALL_STATUS(USBx, bEpNum) (PCD_GET_EP_RX_STATUS((USBx), (bEpNum)) \ + == USB_EP_RX_STALL) + +/** + * @brief set & clear EP_KIND bit. + * @param USBx USB peripheral instance register address. + * @param bEpNum Endpoint Number. + * @retval None + */ +#define PCD_SET_EP_KIND(USBx, bEpNum) do { \ + register uint16_t _wRegVal; \ + \ + _wRegVal = PCD_GET_ENDPOINT((USBx), (bEpNum)) & USB_EPREG_MASK; \ + \ + PCD_SET_ENDPOINT((USBx), (bEpNum), (_wRegVal | USB_EP_CTR_RX | USB_EP_CTR_TX | USB_EP_KIND)); \ + } while(0) /* PCD_SET_EP_KIND */ + +#define PCD_CLEAR_EP_KIND(USBx, bEpNum) do { \ + register uint16_t _wRegVal; \ + \ + _wRegVal = PCD_GET_ENDPOINT((USBx), (bEpNum)) & USB_EPKIND_MASK; \ + \ + PCD_SET_ENDPOINT((USBx), (bEpNum), (_wRegVal | USB_EP_CTR_RX | USB_EP_CTR_TX)); \ + } while(0) /* PCD_CLEAR_EP_KIND */ + +/** + * @brief Sets/clears directly STATUS_OUT bit in the endpoint register. + * @param USBx USB peripheral instance register address. + * @param bEpNum Endpoint Number. + * @retval None + */ +#define PCD_SET_OUT_STATUS(USBx, bEpNum) PCD_SET_EP_KIND((USBx), (bEpNum)) +#define PCD_CLEAR_OUT_STATUS(USBx, bEpNum) PCD_CLEAR_EP_KIND((USBx), (bEpNum)) + +/** + * @brief Sets/clears directly EP_KIND bit in the endpoint register. + * @param USBx USB peripheral instance register address. + * @param bEpNum Endpoint Number. + * @retval None + */ +#define PCD_SET_EP_DBUF(USBx, bEpNum) PCD_SET_EP_KIND((USBx), (bEpNum)) +#define PCD_CLEAR_EP_DBUF(USBx, bEpNum) PCD_CLEAR_EP_KIND((USBx), (bEpNum)) + +/** + * @brief Clears bit CTR_RX / CTR_TX in the endpoint register. + * @param USBx USB peripheral instance register address. + * @param bEpNum Endpoint Number. + * @retval None + */ +#define PCD_CLEAR_RX_EP_CTR(USBx, bEpNum) do { \ + register uint16_t _wRegVal; \ + \ + _wRegVal = PCD_GET_ENDPOINT((USBx), (bEpNum)) & (0x7FFFU & USB_EPREG_MASK); \ + \ + PCD_SET_ENDPOINT((USBx), (bEpNum), (_wRegVal | USB_EP_CTR_TX)); \ + } while(0) /* PCD_CLEAR_RX_EP_CTR */ + +#define PCD_CLEAR_TX_EP_CTR(USBx, bEpNum) do { \ + register uint16_t _wRegVal; \ + \ + _wRegVal = PCD_GET_ENDPOINT((USBx), (bEpNum)) & (0xFF7FU & USB_EPREG_MASK); \ + \ + PCD_SET_ENDPOINT((USBx), (bEpNum), (_wRegVal | USB_EP_CTR_RX)); \ + } while(0) /* PCD_CLEAR_TX_EP_CTR */ + +/** + * @brief Toggles DTOG_RX / DTOG_TX bit in the endpoint register. + * @param USBx USB peripheral instance register address. + * @param bEpNum Endpoint Number. + * @retval None + */ +#define PCD_RX_DTOG(USBx, bEpNum) do { \ + register uint16_t _wEPVal; \ + \ + _wEPVal = PCD_GET_ENDPOINT((USBx), (bEpNum)) & USB_EPREG_MASK; \ + \ + PCD_SET_ENDPOINT((USBx), (bEpNum), (_wEPVal | USB_EP_CTR_RX | USB_EP_CTR_TX | USB_EP_DTOG_RX)); \ + } while(0) /* PCD_RX_DTOG */ + +#define PCD_TX_DTOG(USBx, bEpNum) do { \ + register uint16_t _wEPVal; \ + \ + _wEPVal = PCD_GET_ENDPOINT((USBx), (bEpNum)) & USB_EPREG_MASK; \ + \ + PCD_SET_ENDPOINT((USBx), (bEpNum), (_wEPVal | USB_EP_CTR_RX | USB_EP_CTR_TX | USB_EP_DTOG_TX)); \ + } while(0) /* PCD_TX_DTOG */ +/** + * @brief Clears DTOG_RX / DTOG_TX bit in the endpoint register. + * @param USBx USB peripheral instance register address. + * @param bEpNum Endpoint Number. + * @retval None + */ +#define PCD_CLEAR_RX_DTOG(USBx, bEpNum) do { \ + register uint16_t _wRegVal; \ + \ + _wRegVal = PCD_GET_ENDPOINT((USBx), (bEpNum)); \ + \ + if ((_wRegVal & USB_EP_DTOG_RX) != 0U)\ + { \ + PCD_RX_DTOG((USBx), (bEpNum)); \ + } \ + } while(0) /* PCD_CLEAR_RX_DTOG */ + +#define PCD_CLEAR_TX_DTOG(USBx, bEpNum) do { \ + register uint16_t _wRegVal; \ + \ + _wRegVal = PCD_GET_ENDPOINT((USBx), (bEpNum)); \ + \ + if ((_wRegVal & USB_EP_DTOG_TX) != 0U)\ + { \ + PCD_TX_DTOG((USBx), (bEpNum)); \ + } \ + } while(0) /* PCD_CLEAR_TX_DTOG */ + +/** + * @brief Sets address in an endpoint register. + * @param USBx USB peripheral instance register address. + * @param bEpNum Endpoint Number. + * @param bAddr Address. + * @retval None + */ +#define PCD_SET_EP_ADDRESS(USBx, bEpNum, bAddr) do { \ + register uint16_t _wRegVal; \ + \ + _wRegVal = (PCD_GET_ENDPOINT((USBx), (bEpNum)) & USB_EPREG_MASK) | (bAddr); \ + \ + PCD_SET_ENDPOINT((USBx), (bEpNum), (_wRegVal | USB_EP_CTR_RX | USB_EP_CTR_TX)); \ + } while(0) /* PCD_SET_EP_ADDRESS */ + +/** + * @brief Gets address in an endpoint register. + * @param USBx USB peripheral instance register address. + * @param bEpNum Endpoint Number. + * @retval None + */ +#define PCD_GET_EP_ADDRESS(USBx, bEpNum) ((uint8_t)(PCD_GET_ENDPOINT((USBx), (bEpNum)) & USB_EPADDR_FIELD)) + +#define PCD_EP_TX_CNT(USBx, bEpNum) ((uint16_t *)((((uint32_t)(USBx)->BTABLE + ((uint32_t)(bEpNum) * 8U) + 2U) * PMA_ACCESS) + ((uint32_t)(USBx) + 0x400U))) +#define PCD_EP_RX_CNT(USBx, bEpNum) ((uint16_t *)((((uint32_t)(USBx)->BTABLE + ((uint32_t)(bEpNum) * 8U) + 6U) * PMA_ACCESS) + ((uint32_t)(USBx) + 0x400U))) + +/** + * @brief sets address of the tx/rx buffer. + * @param USBx USB peripheral instance register address. + * @param bEpNum Endpoint Number. + * @param wAddr address to be set (must be word aligned). + * @retval None + */ +#define PCD_SET_EP_TX_ADDRESS(USBx, bEpNum, wAddr) do { \ + register uint16_t *_wRegVal; \ + register uint32_t _wRegBase = (uint32_t)USBx; \ + \ + _wRegBase += (uint32_t)(USBx)->BTABLE; \ + _wRegVal = (uint16_t *)(_wRegBase + 0x400U + (((uint32_t)(bEpNum) * 8U) * PMA_ACCESS)); \ + *_wRegVal = ((wAddr) >> 1) << 1; \ +} while(0) /* PCD_SET_EP_TX_ADDRESS */ + +#define PCD_SET_EP_RX_ADDRESS(USBx, bEpNum, wAddr) do { \ + register uint16_t *_wRegVal; \ + register uint32_t _wRegBase = (uint32_t)USBx; \ + \ + _wRegBase += (uint32_t)(USBx)->BTABLE; \ + _wRegVal = (uint16_t *)(_wRegBase + 0x400U + ((((uint32_t)(bEpNum) * 8U) + 4U) * PMA_ACCESS)); \ + *_wRegVal = ((wAddr) >> 1) << 1; \ +} while(0) /* PCD_SET_EP_RX_ADDRESS */ + +/** + * @brief Gets address of the tx/rx buffer. + * @param USBx USB peripheral instance register address. + * @param bEpNum Endpoint Number. + * @retval address of the buffer. + */ +#define PCD_GET_EP_TX_ADDRESS(USBx, bEpNum) ((uint16_t)*PCD_EP_TX_ADDRESS((USBx), (bEpNum))) +#define PCD_GET_EP_RX_ADDRESS(USBx, bEpNum) ((uint16_t)*PCD_EP_RX_ADDRESS((USBx), (bEpNum))) + +/** + * @brief Sets counter of rx buffer with no. of blocks. + * @param pdwReg Register pointer + * @param wCount Counter. + * @param wNBlocks no. of Blocks. + * @retval None + */ +#define PCD_CALC_BLK32(pdwReg, wCount, wNBlocks) do { \ + (wNBlocks) = (wCount) >> 5; \ + if (((wCount) & 0x1fU) == 0U) \ + { \ + (wNBlocks)--; \ + } \ + *(pdwReg) = (uint16_t)(((wNBlocks) << 10) | USB_CNTRX_BLSIZE); \ + } while(0) /* PCD_CALC_BLK32 */ + +#define PCD_CALC_BLK2(pdwReg, wCount, wNBlocks) do { \ + (wNBlocks) = (wCount) >> 1; \ + if (((wCount) & 0x1U) != 0U) \ + { \ + (wNBlocks)++; \ + } \ + *(pdwReg) = (uint16_t)((wNBlocks) << 10); \ + } while(0) /* PCD_CALC_BLK2 */ + +#define PCD_SET_EP_CNT_RX_REG(pdwReg, wCount) do { \ + uint32_t wNBlocks; \ + if ((wCount) == 0U) \ + { \ + *(pdwReg) &= (uint16_t)~USB_CNTRX_NBLK_MSK; \ + *(pdwReg) |= USB_CNTRX_BLSIZE; \ + } \ + else if((wCount) <= 62U) \ + { \ + PCD_CALC_BLK2((pdwReg), (wCount), wNBlocks); \ + } \ + else \ + { \ + PCD_CALC_BLK32((pdwReg),(wCount), wNBlocks); \ + } \ + } while(0) /* PCD_SET_EP_CNT_RX_REG */ + +#define PCD_SET_EP_RX_DBUF0_CNT(USBx, bEpNum, wCount) do { \ + register uint32_t _wRegBase = (uint32_t)(USBx); \ + uint16_t *pdwReg; \ + \ + _wRegBase += (uint32_t)(USBx)->BTABLE; \ + pdwReg = (uint16_t *)(_wRegBase + 0x400U + ((((uint32_t)(bEpNum) * 8U) + 2U) * PMA_ACCESS)); \ + PCD_SET_EP_CNT_RX_REG(pdwReg, (wCount)); \ + } while(0) + +/** + * @brief sets counter for the tx/rx buffer. + * @param USBx USB peripheral instance register address. + * @param bEpNum Endpoint Number. + * @param wCount Counter value. + * @retval None + */ +#define PCD_SET_EP_TX_CNT(USBx, bEpNum, wCount) do { \ + register uint32_t _wRegBase = (uint32_t)(USBx); \ + uint16_t *_wRegVal; \ + \ + _wRegBase += (uint32_t)(USBx)->BTABLE; \ + _wRegVal = (uint16_t *)(_wRegBase + 0x400U + ((((uint32_t)(bEpNum) * 8U) + 2U) * PMA_ACCESS)); \ + *_wRegVal = (uint16_t)(wCount); \ +} while(0) + +#define PCD_SET_EP_RX_CNT(USBx, bEpNum, wCount) do { \ + register uint32_t _wRegBase = (uint32_t)(USBx); \ + uint16_t *_wRegVal; \ + \ + _wRegBase += (uint32_t)(USBx)->BTABLE; \ + _wRegVal = (uint16_t *)(_wRegBase + 0x400U + ((((uint32_t)(bEpNum) * 8U) + 6U) * PMA_ACCESS)); \ + PCD_SET_EP_CNT_RX_REG(_wRegVal, (wCount)); \ +} while(0) + +/** + * @brief gets counter of the tx buffer. + * @param USBx USB peripheral instance register address. + * @param bEpNum Endpoint Number. + * @retval Counter value + */ +#define PCD_GET_EP_TX_CNT(USBx, bEpNum) ((uint32_t)(*PCD_EP_TX_CNT((USBx), (bEpNum))) & 0x3ffU) +#define PCD_GET_EP_RX_CNT(USBx, bEpNum) ((uint32_t)(*PCD_EP_RX_CNT((USBx), (bEpNum))) & 0x3ffU) + +/** + * @brief Sets buffer 0/1 address in a double buffer endpoint. + * @param USBx USB peripheral instance register address. + * @param bEpNum Endpoint Number. + * @param wBuf0Addr buffer 0 address. + * @retval Counter value + */ +#define PCD_SET_EP_DBUF0_ADDR(USBx, bEpNum, wBuf0Addr) do { \ + PCD_SET_EP_TX_ADDRESS((USBx), (bEpNum), (wBuf0Addr)); \ + } while(0) /* PCD_SET_EP_DBUF0_ADDR */ +#define PCD_SET_EP_DBUF1_ADDR(USBx, bEpNum, wBuf1Addr) do { \ + PCD_SET_EP_RX_ADDRESS((USBx), (bEpNum), (wBuf1Addr)); \ + } while(0) /* PCD_SET_EP_DBUF1_ADDR */ + +/** + * @brief Sets addresses in a double buffer endpoint. + * @param USBx USB peripheral instance register address. + * @param bEpNum Endpoint Number. + * @param wBuf0Addr: buffer 0 address. + * @param wBuf1Addr = buffer 1 address. + * @retval None + */ +#define PCD_SET_EP_DBUF_ADDR(USBx, bEpNum, wBuf0Addr, wBuf1Addr) do { \ + PCD_SET_EP_DBUF0_ADDR((USBx), (bEpNum), (wBuf0Addr)); \ + PCD_SET_EP_DBUF1_ADDR((USBx), (bEpNum), (wBuf1Addr)); \ + } while(0) /* PCD_SET_EP_DBUF_ADDR */ + +/** + * @brief Gets buffer 0/1 address of a double buffer endpoint. + * @param USBx USB peripheral instance register address. + * @param bEpNum Endpoint Number. + * @retval None + */ +#define PCD_GET_EP_DBUF0_ADDR(USBx, bEpNum) (PCD_GET_EP_TX_ADDRESS((USBx), (bEpNum))) +#define PCD_GET_EP_DBUF1_ADDR(USBx, bEpNum) (PCD_GET_EP_RX_ADDRESS((USBx), (bEpNum))) + +/** + * @brief Gets buffer 0/1 address of a double buffer endpoint. + * @param USBx USB peripheral instance register address. + * @param bEpNum Endpoint Number. + * @param bDir endpoint dir EP_DBUF_OUT = OUT + * EP_DBUF_IN = IN + * @param wCount: Counter value + * @retval None + */ +#define PCD_SET_EP_DBUF0_CNT(USBx, bEpNum, bDir, wCount) do { \ + if ((bDir) == 0U) \ + /* OUT endpoint */ \ + { \ + PCD_SET_EP_RX_DBUF0_CNT((USBx), (bEpNum), (wCount)); \ + } \ + else \ + { \ + if ((bDir) == 1U) \ + { \ + /* IN endpoint */ \ + PCD_SET_EP_TX_CNT((USBx), (bEpNum), (wCount)); \ + } \ + } \ + } while(0) /* SetEPDblBuf0Count*/ + +#define PCD_SET_EP_DBUF1_CNT(USBx, bEpNum, bDir, wCount) do { \ + register uint32_t _wBase = (uint32_t)(USBx); \ + uint16_t *_wEPRegVal; \ + \ + if ((bDir) == 0U) \ + { \ + /* OUT endpoint */ \ + PCD_SET_EP_RX_CNT((USBx), (bEpNum), (wCount)); \ + } \ + else \ + { \ + if ((bDir) == 1U) \ + { \ + /* IN endpoint */ \ + _wBase += (uint32_t)(USBx)->BTABLE; \ + _wEPRegVal = (uint16_t *)(_wBase + 0x400U + ((((uint32_t)(bEpNum) * 8U) + 6U) * PMA_ACCESS)); \ + *_wEPRegVal = (uint16_t)(wCount); \ + } \ + } \ + } while(0) /* SetEPDblBuf1Count */ + +#define PCD_SET_EP_DBUF_CNT(USBx, bEpNum, bDir, wCount) do { \ + PCD_SET_EP_DBUF0_CNT((USBx), (bEpNum), (bDir), (wCount)); \ + PCD_SET_EP_DBUF1_CNT((USBx), (bEpNum), (bDir), (wCount)); \ + } while(0) /* PCD_SET_EP_DBUF_CNT */ + +/** + * @brief Gets buffer 0/1 rx/tx counter for double buffering. + * @param USBx USB peripheral instance register address. + * @param bEpNum Endpoint Number. + * @retval None + */ +#define PCD_GET_EP_DBUF0_CNT(USBx, bEpNum) (PCD_GET_EP_TX_CNT((USBx), (bEpNum))) +#define PCD_GET_EP_DBUF1_CNT(USBx, bEpNum) (PCD_GET_EP_RX_CNT((USBx), (bEpNum))) + + + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ +#endif /* defined (USB) */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32F0xx_HAL_PCD_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd_ex.h b/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd_ex.h new file mode 100644 index 0000000..af65766 --- /dev/null +++ b/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pcd_ex.h @@ -0,0 +1,93 @@ +/** + ****************************************************************************** + * @file stm32f0xx_hal_pcd_ex.h + * @author MCD Application Team + * @brief Header file of PCD HAL Extension module. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2016 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32F0xx_HAL_PCD_EX_H +#define STM32F0xx_HAL_PCD_EX_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f0xx_hal_def.h" + +#if defined (USB) +/** @addtogroup STM32F0xx_HAL_Driver + * @{ + */ + +/** @addtogroup PCDEx + * @{ + */ +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ +/* Exported macros -----------------------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup PCDEx_Exported_Functions PCDEx Exported Functions + * @{ + */ +/** @addtogroup PCDEx_Exported_Functions_Group1 Peripheral Control functions + * @{ + */ + + + +HAL_StatusTypeDef HAL_PCDEx_PMAConfig(PCD_HandleTypeDef *hpcd, + uint16_t ep_addr, + uint16_t ep_kind, + uint32_t pmaadress); + + +HAL_StatusTypeDef HAL_PCDEx_ActivateLPM(PCD_HandleTypeDef *hpcd); +HAL_StatusTypeDef HAL_PCDEx_DeActivateLPM(PCD_HandleTypeDef *hpcd); + + +HAL_StatusTypeDef HAL_PCDEx_ActivateBCD(PCD_HandleTypeDef *hpcd); +HAL_StatusTypeDef HAL_PCDEx_DeActivateBCD(PCD_HandleTypeDef *hpcd); +void HAL_PCDEx_BCD_VBUSDetect(PCD_HandleTypeDef *hpcd); + +void HAL_PCDEx_LPM_Callback(PCD_HandleTypeDef *hpcd, PCD_LPM_MsgTypeDef msg); +void HAL_PCDEx_BCD_Callback(PCD_HandleTypeDef *hpcd, PCD_BCD_MsgTypeDef msg); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ +#endif /* defined (USB) */ + +#ifdef __cplusplus +} +#endif + + +#endif /* STM32F0xx_HAL_PCD_EX_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr.h b/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr.h new file mode 100644 index 0000000..e716606 --- /dev/null +++ b/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr.h @@ -0,0 +1,189 @@ +/** + ****************************************************************************** + * @file stm32f0xx_hal_pwr.h + * @author MCD Application Team + * @brief Header file of PWR HAL module. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2016 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F0xx_HAL_PWR_H +#define __STM32F0xx_HAL_PWR_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f0xx_hal_def.h" + +/** @addtogroup STM32F0xx_HAL_Driver + * @{ + */ + +/** @addtogroup PWR PWR + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup PWR_Exported_Constants PWR Exported Constants + * @{ + */ + +/** @defgroup PWR_Regulator_state_in_STOP_mode PWR Regulator state in STOP mode + * @{ + */ +#define PWR_MAINREGULATOR_ON (0x00000000U) +#define PWR_LOWPOWERREGULATOR_ON PWR_CR_LPDS + +#define IS_PWR_REGULATOR(REGULATOR) (((REGULATOR) == PWR_MAINREGULATOR_ON) || \ + ((REGULATOR) == PWR_LOWPOWERREGULATOR_ON)) +/** + * @} + */ + +/** @defgroup PWR_SLEEP_mode_entry PWR SLEEP mode entry + * @{ + */ +#define PWR_SLEEPENTRY_WFI ((uint8_t)0x01U) +#define PWR_SLEEPENTRY_WFE ((uint8_t)0x02U) +#define IS_PWR_SLEEP_ENTRY(ENTRY) (((ENTRY) == PWR_SLEEPENTRY_WFI) || ((ENTRY) == PWR_SLEEPENTRY_WFE)) +/** + * @} + */ + +/** @defgroup PWR_STOP_mode_entry PWR STOP mode entry + * @{ + */ +#define PWR_STOPENTRY_WFI ((uint8_t)0x01U) +#define PWR_STOPENTRY_WFE ((uint8_t)0x02U) +#define IS_PWR_STOP_ENTRY(ENTRY) (((ENTRY) == PWR_STOPENTRY_WFI) || ((ENTRY) == PWR_STOPENTRY_WFE)) +/** + * @} + */ + + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup PWR_Exported_Macro PWR Exported Macro + * @{ + */ + +/** @brief Check PWR flag is set or not. + * @param __FLAG__ specifies the flag to check. + * This parameter can be one of the following values: + * @arg PWR_FLAG_WU: Wake Up flag. This flag indicates that a wakeup event + * was received from the WKUP pin or from the RTC alarm (Alarm A), + * RTC Tamper event, RTC TimeStamp event or RTC Wakeup. + * An additional wakeup event is detected if the WKUP pin is enabled + * (by setting the EWUP bit) when the WKUP pin level is already high. + * @arg PWR_FLAG_SB: StandBy flag. This flag indicates that the system was + * resumed from StandBy mode. + * @arg PWR_FLAG_PVDO: PVD Output. This flag is valid only if PVD is enabled + * by the HAL_PWR_EnablePVD() function. The PVD is stopped by Standby mode + * For this reason, this bit is equal to 0 after Standby or reset + * until the PVDE bit is set. + * Warning: this Flag is not available on STM32F030x8 products + * @arg PWR_FLAG_VREFINTRDY: This flag indicates that the internal reference + * voltage VREFINT is ready. + * Warning: this Flag is not available on STM32F030x8 products + * @retval The new state of __FLAG__ (TRUE or FALSE). + */ +#define __HAL_PWR_GET_FLAG(__FLAG__) ((PWR->CSR & (__FLAG__)) == (__FLAG__)) + +/** @brief Clear the PWR's pending flags. + * @param __FLAG__ specifies the flag to clear. + * This parameter can be one of the following values: + * @arg PWR_FLAG_WU: Wake Up flag + * @arg PWR_FLAG_SB: StandBy flag + */ +#define __HAL_PWR_CLEAR_FLAG(__FLAG__) (PWR->CR |= (__FLAG__) << 2U) + + +/** + * @} + */ + +/* Include PWR HAL Extension module */ +#include "stm32f0xx_hal_pwr_ex.h" + +/* Exported functions --------------------------------------------------------*/ + +/** @addtogroup PWR_Exported_Functions PWR Exported Functions + * @{ + */ + +/** @addtogroup PWR_Exported_Functions_Group1 Initialization and de-initialization functions + * @{ + */ + +/* Initialization and de-initialization functions *****************************/ +void HAL_PWR_DeInit(void); + +/** + * @} + */ + +/** @addtogroup PWR_Exported_Functions_Group2 Peripheral Control functions + * @{ + */ + +/* Peripheral Control functions **********************************************/ +void HAL_PWR_EnableBkUpAccess(void); +void HAL_PWR_DisableBkUpAccess(void); + +/* WakeUp pins configuration functions ****************************************/ +void HAL_PWR_EnableWakeUpPin(uint32_t WakeUpPinx); +void HAL_PWR_DisableWakeUpPin(uint32_t WakeUpPinx); + +/* Low Power modes configuration functions ************************************/ +void HAL_PWR_EnterSTOPMode(uint32_t Regulator, uint8_t STOPEntry); +void HAL_PWR_EnterSLEEPMode(uint32_t Regulator, uint8_t SLEEPEntry); +void HAL_PWR_EnterSTANDBYMode(void); + +void HAL_PWR_EnableSleepOnExit(void); +void HAL_PWR_DisableSleepOnExit(void); +void HAL_PWR_EnableSEVOnPend(void); +void HAL_PWR_DisableSEVOnPend(void); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + + +#endif /* __STM32F0xx_HAL_PWR_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ + diff --git a/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr_ex.h b/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr_ex.h new file mode 100644 index 0000000..a9ed6eb --- /dev/null +++ b/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr_ex.h @@ -0,0 +1,459 @@ +/** + ****************************************************************************** + * @file stm32f0xx_hal_pwr_ex.h + * @author MCD Application Team + * @brief Header file of PWR HAL Extension module. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2016 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F0xx_HAL_PWR_EX_H +#define __STM32F0xx_HAL_PWR_EX_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f0xx_hal_def.h" + +/** @addtogroup STM32F0xx_HAL_Driver + * @{ + */ + +/** @addtogroup PWREx + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ + +/** @defgroup PWREx_Exported_Types PWREx Exported Types + * @{ + */ + +#if defined (STM32F031x6) || defined (STM32F042x6) || defined (STM32F051x8) || \ + defined (STM32F071xB) || defined (STM32F072xB) || \ + defined (STM32F091xC) + +/** + * @brief PWR PVD configuration structure definition + */ +typedef struct +{ + uint32_t PVDLevel; /*!< PVDLevel: Specifies the PVD detection level + This parameter can be a value of @ref PWREx_PVD_detection_level */ + + uint32_t Mode; /*!< Mode: Specifies the operating mode for the selected pins. + This parameter can be a value of @ref PWREx_PVD_Mode */ +}PWR_PVDTypeDef; + +#endif /* defined (STM32F031x6) || defined (STM32F042x6) || defined (STM32F051x8) || */ + /* defined (STM32F071xB) || defined (STM32F072xB) || */ + /* defined (STM32F091xC) */ +/** + * @} + */ +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup PWREx_Exported_Constants PWREx Exported Constants + * @{ + */ + + +/** @defgroup PWREx_WakeUp_Pins PWREx Wakeup Pins + * @{ + */ +#if defined (STM32F071xB) || defined (STM32F072xB) || defined (STM32F078xx) || \ + defined (STM32F091xC) || defined (STM32F098xx) +#define PWR_WAKEUP_PIN1 ((uint32_t)PWR_CSR_EWUP1) +#define PWR_WAKEUP_PIN2 ((uint32_t)PWR_CSR_EWUP2) +#define PWR_WAKEUP_PIN3 ((uint32_t)PWR_CSR_EWUP3) +#define PWR_WAKEUP_PIN4 ((uint32_t)PWR_CSR_EWUP4) +#define PWR_WAKEUP_PIN5 ((uint32_t)PWR_CSR_EWUP5) +#define PWR_WAKEUP_PIN6 ((uint32_t)PWR_CSR_EWUP6) +#define PWR_WAKEUP_PIN7 ((uint32_t)PWR_CSR_EWUP7) +#define PWR_WAKEUP_PIN8 ((uint32_t)PWR_CSR_EWUP8) + +#define IS_PWR_WAKEUP_PIN(PIN) (((PIN) == PWR_WAKEUP_PIN1) || \ + ((PIN) == PWR_WAKEUP_PIN2) || \ + ((PIN) == PWR_WAKEUP_PIN3) || \ + ((PIN) == PWR_WAKEUP_PIN4) || \ + ((PIN) == PWR_WAKEUP_PIN5) || \ + ((PIN) == PWR_WAKEUP_PIN6) || \ + ((PIN) == PWR_WAKEUP_PIN7) || \ + ((PIN) == PWR_WAKEUP_PIN8)) + +#elif defined(STM32F030xC) || defined (STM32F070xB) +#define PWR_WAKEUP_PIN1 ((uint32_t)PWR_CSR_EWUP1) +#define PWR_WAKEUP_PIN2 ((uint32_t)PWR_CSR_EWUP2) +#define PWR_WAKEUP_PIN4 ((uint32_t)PWR_CSR_EWUP4) +#define PWR_WAKEUP_PIN5 ((uint32_t)PWR_CSR_EWUP5) +#define PWR_WAKEUP_PIN6 ((uint32_t)PWR_CSR_EWUP6) +#define PWR_WAKEUP_PIN7 ((uint32_t)PWR_CSR_EWUP7) + +#define IS_PWR_WAKEUP_PIN(PIN) (((PIN) == PWR_WAKEUP_PIN1) || \ + ((PIN) == PWR_WAKEUP_PIN2) || \ + ((PIN) == PWR_WAKEUP_PIN4) || \ + ((PIN) == PWR_WAKEUP_PIN5) || \ + ((PIN) == PWR_WAKEUP_PIN6) || \ + ((PIN) == PWR_WAKEUP_PIN7)) + +#elif defined(STM32F042x6) || defined (STM32F048xx) +#define PWR_WAKEUP_PIN1 ((uint32_t)PWR_CSR_EWUP1) +#define PWR_WAKEUP_PIN2 ((uint32_t)PWR_CSR_EWUP2) +#define PWR_WAKEUP_PIN4 ((uint32_t)PWR_CSR_EWUP4) +#define PWR_WAKEUP_PIN6 ((uint32_t)PWR_CSR_EWUP6) +#define PWR_WAKEUP_PIN7 ((uint32_t)PWR_CSR_EWUP7) + +#define IS_PWR_WAKEUP_PIN(PIN) (((PIN) == PWR_WAKEUP_PIN1) || \ + ((PIN) == PWR_WAKEUP_PIN2) || \ + ((PIN) == PWR_WAKEUP_PIN4) || \ + ((PIN) == PWR_WAKEUP_PIN6) || \ + ((PIN) == PWR_WAKEUP_PIN7)) + +#else +#define PWR_WAKEUP_PIN1 ((uint32_t)PWR_CSR_EWUP1) +#define PWR_WAKEUP_PIN2 ((uint32_t)PWR_CSR_EWUP2) + + +#define IS_PWR_WAKEUP_PIN(PIN) (((PIN) == PWR_WAKEUP_PIN1) || \ + ((PIN) == PWR_WAKEUP_PIN2)) + +#endif + +/** + * @} + */ + +/** @defgroup PWREx_EXTI_Line PWREx EXTI Line + * @{ + */ +#if defined (STM32F031x6) || defined (STM32F042x6) || defined (STM32F051x8) || \ + defined (STM32F071xB) || defined (STM32F072xB) || \ + defined (STM32F091xC) + +#define PWR_EXTI_LINE_PVD ((uint32_t)EXTI_IMR_MR16) /*!< External interrupt line 16 Connected to the PVD EXTI Line */ + +#endif /* defined (STM32F031x6) || defined (STM32F042x6) || defined (STM32F051x8) || */ + /* defined (STM32F071xB) || defined (STM32F072xB) || */ + /* defined (STM32F091xC) */ + +#if defined (STM32F042x6) || defined (STM32F048xx) || \ + defined (STM32F071xB) || defined (STM32F072xB) || defined (STM32F078xx) || \ + defined (STM32F091xC) || defined (STM32F098xx) + +#define PWR_EXTI_LINE_VDDIO2 ((uint32_t)EXTI_IMR_MR31) /*!< External interrupt line 31 Connected to the Vddio2 Monitor EXTI Line */ + +#endif /* defined (STM32F042x6) || defined (STM32F048xx) ||\ + defined (STM32F071xB) || defined (STM32F072xB) || defined (STM32F078xx) || \ + defined (STM32F091xC) || defined (STM32F098xx) ||*/ +/** + * @} + */ + +#if defined (STM32F031x6) || defined (STM32F042x6) || defined (STM32F051x8) || \ + defined (STM32F071xB) || defined (STM32F072xB) || \ + defined (STM32F091xC) +/** @defgroup PWREx_PVD_detection_level PWREx PVD detection level + * @{ + */ +#define PWR_PVDLEVEL_0 PWR_CR_PLS_LEV0 +#define PWR_PVDLEVEL_1 PWR_CR_PLS_LEV1 +#define PWR_PVDLEVEL_2 PWR_CR_PLS_LEV2 +#define PWR_PVDLEVEL_3 PWR_CR_PLS_LEV3 +#define PWR_PVDLEVEL_4 PWR_CR_PLS_LEV4 +#define PWR_PVDLEVEL_5 PWR_CR_PLS_LEV5 +#define PWR_PVDLEVEL_6 PWR_CR_PLS_LEV6 +#define PWR_PVDLEVEL_7 PWR_CR_PLS_LEV7 +#define IS_PWR_PVD_LEVEL(LEVEL) (((LEVEL) == PWR_PVDLEVEL_0) || ((LEVEL) == PWR_PVDLEVEL_1)|| \ + ((LEVEL) == PWR_PVDLEVEL_2) || ((LEVEL) == PWR_PVDLEVEL_3)|| \ + ((LEVEL) == PWR_PVDLEVEL_4) || ((LEVEL) == PWR_PVDLEVEL_5)|| \ + ((LEVEL) == PWR_PVDLEVEL_6) || ((LEVEL) == PWR_PVDLEVEL_7)) +/** + * @} + */ + +/** @defgroup PWREx_PVD_Mode PWREx PVD Mode + * @{ + */ +#define PWR_PVD_MODE_NORMAL (0x00000000U) /*!< basic mode is used */ +#define PWR_PVD_MODE_IT_RISING (0x00010001U) /*!< External Interrupt Mode with Rising edge trigger detection */ +#define PWR_PVD_MODE_IT_FALLING (0x00010002U) /*!< External Interrupt Mode with Falling edge trigger detection */ +#define PWR_PVD_MODE_IT_RISING_FALLING (0x00010003U) /*!< External Interrupt Mode with Rising/Falling edge trigger detection */ +#define PWR_PVD_MODE_EVENT_RISING (0x00020001U) /*!< Event Mode with Rising edge trigger detection */ +#define PWR_PVD_MODE_EVENT_FALLING (0x00020002U) /*!< Event Mode with Falling edge trigger detection */ +#define PWR_PVD_MODE_EVENT_RISING_FALLING (0x00020003U) /*!< Event Mode with Rising/Falling edge trigger detection */ + +#define IS_PWR_PVD_MODE(MODE) (((MODE) == PWR_PVD_MODE_IT_RISING)|| ((MODE) == PWR_PVD_MODE_IT_FALLING) || \ + ((MODE) == PWR_PVD_MODE_IT_RISING_FALLING) || ((MODE) == PWR_PVD_MODE_EVENT_RISING) || \ + ((MODE) == PWR_PVD_MODE_EVENT_FALLING) || ((MODE) == PWR_PVD_MODE_EVENT_RISING_FALLING) || \ + ((MODE) == PWR_PVD_MODE_NORMAL)) +/** + * @} + */ +#endif /* defined (STM32F031x6) || defined (STM32F042x6) || defined (STM32F051x8) || */ + /* defined (STM32F071xB) || defined (STM32F072xB) || */ + /* defined (STM32F091xC) */ + +/** @defgroup PWREx_Flag PWREx Flag + * @{ + */ +#if defined (STM32F031x6) || defined (STM32F042x6) || defined (STM32F051x8) || \ + defined (STM32F071xB) || defined (STM32F072xB) || \ + defined (STM32F091xC) + +#define PWR_FLAG_WU PWR_CSR_WUF +#define PWR_FLAG_SB PWR_CSR_SBF +#define PWR_FLAG_PVDO PWR_CSR_PVDO +#define PWR_FLAG_VREFINTRDY PWR_CSR_VREFINTRDYF +#elif defined (STM32F070x6) || defined (STM32F070xB) || defined (STM32F030xC) +#define PWR_FLAG_WU PWR_CSR_WUF +#define PWR_FLAG_SB PWR_CSR_SBF +#define PWR_FLAG_VREFINTRDY PWR_CSR_VREFINTRDYF +#else +#define PWR_FLAG_WU PWR_CSR_WUF +#define PWR_FLAG_SB PWR_CSR_SBF + +#endif /* defined (STM32F031x6) || defined (STM32F042x6) || defined (STM32F051x8) || */ + /* defined (STM32F071xB) || defined (STM32F072xB) || */ + /* defined (STM32F091xC) */ +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup PWREx_Exported_Macros PWREx Exported Macros + * @{ + */ +#if defined (STM32F031x6) || defined (STM32F042x6) || defined (STM32F051x8) || \ + defined (STM32F071xB) || defined (STM32F072xB) || \ + defined (STM32F091xC) +/** + * @brief Enable interrupt on PVD Exti Line 16. + * @retval None. + */ +#define __HAL_PWR_PVD_EXTI_ENABLE_IT() (EXTI->IMR |= (PWR_EXTI_LINE_PVD)) + +/** + * @brief Disable interrupt on PVD Exti Line 16. + * @retval None. + */ +#define __HAL_PWR_PVD_EXTI_DISABLE_IT() (EXTI->IMR &= ~(PWR_EXTI_LINE_PVD)) + +/** + * @brief Enable event on PVD Exti Line 16. + * @retval None. + */ +#define __HAL_PWR_PVD_EXTI_ENABLE_EVENT() (EXTI->EMR |= (PWR_EXTI_LINE_PVD)) + +/** + * @brief Disable event on PVD Exti Line 16. + * @retval None. + */ +#define __HAL_PWR_PVD_EXTI_DISABLE_EVENT() (EXTI->EMR &= ~(PWR_EXTI_LINE_PVD)) + +/** + * @brief Disable the PVD Extended Interrupt Rising Trigger. + * @retval None. + */ +#define __HAL_PWR_PVD_EXTI_DISABLE_RISING_EDGE() CLEAR_BIT(EXTI->RTSR, PWR_EXTI_LINE_PVD) + +/** + * @brief Disable the PVD Extended Interrupt Falling Trigger. + * @retval None. + */ +#define __HAL_PWR_PVD_EXTI_DISABLE_FALLING_EDGE() CLEAR_BIT(EXTI->FTSR, PWR_EXTI_LINE_PVD) + +/** + * @brief Disable the PVD Extended Interrupt Rising & Falling Trigger. + * @retval None + */ +#define __HAL_PWR_PVD_EXTI_DISABLE_RISING_FALLING_EDGE() __HAL_PWR_PVD_EXTI_DISABLE_RISING_EDGE();__HAL_PWR_PVD_EXTI_DISABLE_FALLING_EDGE(); + + +/** + * @brief PVD EXTI line configuration: set falling edge trigger. + * @retval None. + */ +#define __HAL_PWR_PVD_EXTI_ENABLE_FALLING_EDGE() EXTI->FTSR |= (PWR_EXTI_LINE_PVD) + +/** + * @brief PVD EXTI line configuration: set rising edge trigger. + * @retval None. + */ +#define __HAL_PWR_PVD_EXTI_ENABLE_RISING_EDGE() EXTI->RTSR |= (PWR_EXTI_LINE_PVD) + +/** + * @brief Enable the PVD Extended Interrupt Rising & Falling Trigger. + * @retval None + */ +#define __HAL_PWR_PVD_EXTI_ENABLE_RISING_FALLING_EDGE() __HAL_PWR_PVD_EXTI_ENABLE_RISING_EDGE();__HAL_PWR_PVD_EXTI_ENABLE_FALLING_EDGE(); + +/** + * @brief Check whether the specified PVD EXTI interrupt flag is set or not. + * @retval EXTI PVD Line Status. + */ +#define __HAL_PWR_PVD_EXTI_GET_FLAG() (EXTI->PR & (PWR_EXTI_LINE_PVD)) + +/** + * @brief Clear the PVD EXTI flag. + * @retval None. + */ +#define __HAL_PWR_PVD_EXTI_CLEAR_FLAG() (EXTI->PR = (PWR_EXTI_LINE_PVD)) + +/** + * @brief Generate a Software interrupt on selected EXTI line. + * @retval None. + */ +#define __HAL_PWR_PVD_EXTI_GENERATE_SWIT() (EXTI->SWIER |= (PWR_EXTI_LINE_PVD)) + +#endif /* defined (STM32F031x6) || defined (STM32F042x6) || defined (STM32F051x8) || */ + /* defined (STM32F071xB) || defined (STM32F072xB) || */ + /* defined (STM32F091xC) */ + + +#if defined (STM32F042x6) || defined (STM32F048xx) || \ + defined (STM32F071xB) || defined (STM32F072xB) || defined (STM32F078xx) || \ + defined (STM32F091xC) || defined (STM32F098xx) +/** + * @brief Enable interrupt on Vddio2 Monitor Exti Line 31. + * @retval None. + */ +#define __HAL_PWR_VDDIO2_EXTI_ENABLE_IT() (EXTI->IMR |= (PWR_EXTI_LINE_VDDIO2)) + +/** + * @brief Disable interrupt on Vddio2 Monitor Exti Line 31. + * @retval None. + */ +#define __HAL_PWR_VDDIO2_EXTI_DISABLE_IT() (EXTI->IMR &= ~(PWR_EXTI_LINE_VDDIO2)) + +/** + * @brief Vddio2 Monitor EXTI line configuration: clear falling edge and rising edge trigger. + * @retval None. + */ +#define __HAL_PWR_VDDIO2_EXTI_DISABLE_FALLING_EDGE() \ + do{ \ + EXTI->FTSR &= ~(PWR_EXTI_LINE_VDDIO2); \ + EXTI->RTSR &= ~(PWR_EXTI_LINE_VDDIO2); \ + } while(0) + +/** + * @brief Vddio2 Monitor EXTI line configuration: set falling edge trigger. + * @retval None. + */ +#define __HAL_PWR_VDDIO2_EXTI_ENABLE_FALLING_EDGE() EXTI->FTSR |= (PWR_EXTI_LINE_VDDIO2) + +/** + * @brief Check whether the specified VDDIO2 monitor EXTI interrupt flag is set or not. + * @retval EXTI VDDIO2 Monitor Line Status. + */ +#define __HAL_PWR_VDDIO2_EXTI_GET_FLAG() (EXTI->PR & (PWR_EXTI_LINE_VDDIO2)) + +/** + * @brief Clear the VDDIO2 Monitor EXTI flag. + * @retval None. + */ +#define __HAL_PWR_VDDIO2_EXTI_CLEAR_FLAG() (EXTI->PR = (PWR_EXTI_LINE_VDDIO2)) + +/** + * @brief Generate a Software interrupt on selected EXTI line. + * @retval None. + */ +#define __HAL_PWR_VDDIO2_EXTI_GENERATE_SWIT() (EXTI->SWIER |= (PWR_EXTI_LINE_VDDIO2)) + + +#endif /* defined (STM32F042x6) || defined (STM32F048xx) ||\ + defined (STM32F071xB) || defined (STM32F072xB) || defined (STM32F078xx) || \ + defined (STM32F091xC) || defined (STM32F098xx) */ + +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ + +/** @addtogroup PWREx_Exported_Functions PWREx Exported Functions + * @{ + */ + +/** @addtogroup PWREx_Exported_Functions_Group1 + * @{ + */ +/* I/O operation functions ***************************************************/ +#if defined (STM32F031x6) || defined (STM32F042x6) || defined (STM32F051x8) || \ + defined (STM32F071xB) || defined (STM32F072xB) || \ + defined (STM32F091xC) +void HAL_PWR_PVD_IRQHandler(void); +void HAL_PWR_PVDCallback(void); +#endif /* defined (STM32F031x6) || defined (STM32F042x6) || defined (STM32F051x8) || */ + /* defined (STM32F071xB) || defined (STM32F072xB) || */ + /* defined (STM32F091xC) */ + +#if defined (STM32F042x6) || defined (STM32F048xx) || \ + defined (STM32F071xB) || defined (STM32F072xB) || defined (STM32F078xx) || \ + defined (STM32F091xC) || defined (STM32F098xx) +void HAL_PWREx_Vddio2Monitor_IRQHandler(void); +void HAL_PWREx_Vddio2MonitorCallback(void); +#endif /* defined (STM32F042x6) || defined (STM32F048xx) || \ + defined (STM32F071xB) || defined (STM32F072xB) || defined (STM32F078xx) || \ + defined (STM32F091xC) || defined (STM32F098xx) */ + +/* Peripheral Control functions **********************************************/ +#if defined (STM32F031x6) || defined (STM32F042x6) || defined (STM32F051x8) || \ + defined (STM32F071xB) || defined (STM32F072xB) || \ + defined (STM32F091xC) +void HAL_PWR_ConfigPVD(PWR_PVDTypeDef *sConfigPVD); +void HAL_PWR_EnablePVD(void); +void HAL_PWR_DisablePVD(void); +#endif /* defined (STM32F031x6) || defined (STM32F042x6) || defined (STM32F051x8) || */ + /* defined (STM32F071xB) || defined (STM32F072xB) || */ + /* defined (STM32F091xC) */ + +#if defined (STM32F042x6) || defined (STM32F048xx) || \ + defined (STM32F071xB) || defined (STM32F072xB) || defined (STM32F078xx) || \ + defined (STM32F091xC) || defined (STM32F098xx) +void HAL_PWREx_EnableVddio2Monitor(void); +void HAL_PWREx_DisableVddio2Monitor(void); +#endif /* defined (STM32F042x6) || defined (STM32F048xx) || \ + defined (STM32F071xB) || defined (STM32F072xB) || defined (STM32F078xx) || \ + defined (STM32F091xC) || defined (STM32F098xx) */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F0xx_HAL_PWR_EX_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ + diff --git a/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc.h b/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc.h new file mode 100644 index 0000000..4239c51 --- /dev/null +++ b/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc.h @@ -0,0 +1,1686 @@ +/** + ****************************************************************************** + * @file stm32f0xx_hal_rcc.h + * @author MCD Application Team + * @brief Header file of RCC HAL module. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2016 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F0xx_HAL_RCC_H +#define __STM32F0xx_HAL_RCC_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f0xx_hal_def.h" + +/** @addtogroup STM32F0xx_HAL_Driver + * @{ + */ + +/** @addtogroup RCC + * @{ + */ + +/** @addtogroup RCC_Private_Constants + * @{ + */ + +/** @defgroup RCC_Timeout RCC Timeout + * @{ + */ + +/* Disable Backup domain write protection state change timeout */ +#define RCC_DBP_TIMEOUT_VALUE (100U) /* 100 ms */ +/* LSE state change timeout */ +#define RCC_LSE_TIMEOUT_VALUE LSE_STARTUP_TIMEOUT +#define CLOCKSWITCH_TIMEOUT_VALUE (5000U) /* 5 s */ +#define HSE_TIMEOUT_VALUE HSE_STARTUP_TIMEOUT +#define HSI_TIMEOUT_VALUE (2U) /* 2 ms (minimum Tick + 1U) */ +#define LSI_TIMEOUT_VALUE (2U) /* 2 ms (minimum Tick + 1U) */ +#define PLL_TIMEOUT_VALUE (2U) /* 2 ms (minimum Tick + 1U) */ +#define HSI14_TIMEOUT_VALUE (2U) /* 2 ms (minimum Tick + 1U) */ +#if defined(RCC_HSI48_SUPPORT) +#define HSI48_TIMEOUT_VALUE (2U) /* 2 ms (minimum Tick + 1U) */ +#endif /* RCC_HSI48_SUPPORT */ +/** + * @} + */ + +/** @defgroup RCC_Register_Offset Register offsets + * @{ + */ +#define RCC_OFFSET (RCC_BASE - PERIPH_BASE) +#define RCC_CR_OFFSET 0x00 +#define RCC_CFGR_OFFSET 0x04 +#define RCC_CIR_OFFSET 0x08 +#define RCC_BDCR_OFFSET 0x20 +#define RCC_CSR_OFFSET 0x24 + +/** + * @} + */ + + +/* CR register byte 2 (Bits[23:16]) base address */ +#define RCC_CR_BYTE2_ADDRESS ((uint32_t)(RCC_BASE + RCC_CR_OFFSET + 0x02U)) + +/* CIR register byte 1 (Bits[15:8]) base address */ +#define RCC_CIR_BYTE1_ADDRESS ((uint32_t)(RCC_BASE + RCC_CIR_OFFSET + 0x01U)) + +/* CIR register byte 2 (Bits[23:16]) base address */ +#define RCC_CIR_BYTE2_ADDRESS ((uint32_t)(RCC_BASE + RCC_CIR_OFFSET + 0x02U)) + +/* Defines used for Flags */ +#define CR_REG_INDEX ((uint8_t)1U) +#define CR2_REG_INDEX ((uint8_t)2U) +#define BDCR_REG_INDEX ((uint8_t)3U) +#define CSR_REG_INDEX ((uint8_t)4U) + +/* Bits position in in the CFGR register */ +#define RCC_CFGR_PLLMUL_BITNUMBER 18U +#define RCC_CFGR_HPRE_BITNUMBER 4U +#define RCC_CFGR_PPRE_BITNUMBER 8U +/* Flags in the CFGR2 register */ +#define RCC_CFGR2_PREDIV_BITNUMBER 0 +/* Flags in the CR register */ +#define RCC_CR_HSIRDY_BitNumber 1 +#define RCC_CR_HSERDY_BitNumber 17 +#define RCC_CR_PLLRDY_BitNumber 25 +/* Flags in the CR2 register */ +#define RCC_CR2_HSI14RDY_BitNumber 1 +#define RCC_CR2_HSI48RDY_BitNumber 16 +/* Flags in the BDCR register */ +#define RCC_BDCR_LSERDY_BitNumber 1 +/* Flags in the CSR register */ +#define RCC_CSR_LSIRDY_BitNumber 1 +#define RCC_CSR_V18PWRRSTF_BitNumber 23 +#define RCC_CSR_RMVF_BitNumber 24 +#define RCC_CSR_OBLRSTF_BitNumber 25 +#define RCC_CSR_PINRSTF_BitNumber 26 +#define RCC_CSR_PORRSTF_BitNumber 27 +#define RCC_CSR_SFTRSTF_BitNumber 28 +#define RCC_CSR_IWDGRSTF_BitNumber 29 +#define RCC_CSR_WWDGRSTF_BitNumber 30 +#define RCC_CSR_LPWRRSTF_BitNumber 31 +/* Flags in the HSITRIM register */ +#define RCC_CR_HSITRIM_BitNumber 3 +#define RCC_HSI14TRIM_BIT_NUMBER 3 +#define RCC_FLAG_MASK ((uint8_t)0x1FU) + +/** + * @} + */ + +/** @addtogroup RCC_Private_Macros + * @{ + */ +#define IS_RCC_HSE(__HSE__) (((__HSE__) == RCC_HSE_OFF) || ((__HSE__) == RCC_HSE_ON) || \ + ((__HSE__) == RCC_HSE_BYPASS)) +#define IS_RCC_LSE(__LSE__) (((__LSE__) == RCC_LSE_OFF) || ((__LSE__) == RCC_LSE_ON) || \ + ((__LSE__) == RCC_LSE_BYPASS)) +#define IS_RCC_HSI(__HSI__) (((__HSI__) == RCC_HSI_OFF) || ((__HSI__) == RCC_HSI_ON)) +#define IS_RCC_HSI14(__HSI14__) (((__HSI14__) == RCC_HSI14_OFF) || ((__HSI14__) == RCC_HSI14_ON) || ((__HSI14__) == RCC_HSI14_ADC_CONTROL)) +#define IS_RCC_CALIBRATION_VALUE(__VALUE__) ((__VALUE__) <= 0x1FU) +#define IS_RCC_LSI(__LSI__) (((__LSI__) == RCC_LSI_OFF) || ((__LSI__) == RCC_LSI_ON)) +#define IS_RCC_PLL(__PLL__) (((__PLL__) == RCC_PLL_NONE) || ((__PLL__) == RCC_PLL_OFF) || \ + ((__PLL__) == RCC_PLL_ON)) +#define IS_RCC_PREDIV(__PREDIV__) (((__PREDIV__) == RCC_PREDIV_DIV1) || ((__PREDIV__) == RCC_PREDIV_DIV2) || \ + ((__PREDIV__) == RCC_PREDIV_DIV3) || ((__PREDIV__) == RCC_PREDIV_DIV4) || \ + ((__PREDIV__) == RCC_PREDIV_DIV5) || ((__PREDIV__) == RCC_PREDIV_DIV6) || \ + ((__PREDIV__) == RCC_PREDIV_DIV7) || ((__PREDIV__) == RCC_PREDIV_DIV8) || \ + ((__PREDIV__) == RCC_PREDIV_DIV9) || ((__PREDIV__) == RCC_PREDIV_DIV10) || \ + ((__PREDIV__) == RCC_PREDIV_DIV11) || ((__PREDIV__) == RCC_PREDIV_DIV12) || \ + ((__PREDIV__) == RCC_PREDIV_DIV13) || ((__PREDIV__) == RCC_PREDIV_DIV14) || \ + ((__PREDIV__) == RCC_PREDIV_DIV15) || ((__PREDIV__) == RCC_PREDIV_DIV16)) + +#define IS_RCC_PLL_MUL(__MUL__) (((__MUL__) == RCC_PLL_MUL2) || ((__MUL__) == RCC_PLL_MUL3) || \ + ((__MUL__) == RCC_PLL_MUL4) || ((__MUL__) == RCC_PLL_MUL5) || \ + ((__MUL__) == RCC_PLL_MUL6) || ((__MUL__) == RCC_PLL_MUL7) || \ + ((__MUL__) == RCC_PLL_MUL8) || ((__MUL__) == RCC_PLL_MUL9) || \ + ((__MUL__) == RCC_PLL_MUL10) || ((__MUL__) == RCC_PLL_MUL11) || \ + ((__MUL__) == RCC_PLL_MUL12) || ((__MUL__) == RCC_PLL_MUL13) || \ + ((__MUL__) == RCC_PLL_MUL14) || ((__MUL__) == RCC_PLL_MUL15) || \ + ((__MUL__) == RCC_PLL_MUL16)) +#define IS_RCC_CLOCKTYPE(__CLK__) ((((__CLK__) & RCC_CLOCKTYPE_SYSCLK) == RCC_CLOCKTYPE_SYSCLK) || \ + (((__CLK__) & RCC_CLOCKTYPE_HCLK) == RCC_CLOCKTYPE_HCLK) || \ + (((__CLK__) & RCC_CLOCKTYPE_PCLK1) == RCC_CLOCKTYPE_PCLK1)) +#define IS_RCC_HCLK(__HCLK__) (((__HCLK__) == RCC_SYSCLK_DIV1) || ((__HCLK__) == RCC_SYSCLK_DIV2) || \ + ((__HCLK__) == RCC_SYSCLK_DIV4) || ((__HCLK__) == RCC_SYSCLK_DIV8) || \ + ((__HCLK__) == RCC_SYSCLK_DIV16) || ((__HCLK__) == RCC_SYSCLK_DIV64) || \ + ((__HCLK__) == RCC_SYSCLK_DIV128) || ((__HCLK__) == RCC_SYSCLK_DIV256) || \ + ((__HCLK__) == RCC_SYSCLK_DIV512)) +#define IS_RCC_PCLK(__PCLK__) (((__PCLK__) == RCC_HCLK_DIV1) || ((__PCLK__) == RCC_HCLK_DIV2) || \ + ((__PCLK__) == RCC_HCLK_DIV4) || ((__PCLK__) == RCC_HCLK_DIV8) || \ + ((__PCLK__) == RCC_HCLK_DIV16)) +#define IS_RCC_MCO(__MCO__) ((__MCO__) == RCC_MCO) +#define IS_RCC_RTCCLKSOURCE(__SOURCE__) (((__SOURCE__) == RCC_RTCCLKSOURCE_NO_CLK) || \ + ((__SOURCE__) == RCC_RTCCLKSOURCE_LSE) || \ + ((__SOURCE__) == RCC_RTCCLKSOURCE_LSI) || \ + ((__SOURCE__) == RCC_RTCCLKSOURCE_HSE_DIV32)) +#define IS_RCC_USART1CLKSOURCE(__SOURCE__) (((__SOURCE__) == RCC_USART1CLKSOURCE_PCLK1) || \ + ((__SOURCE__) == RCC_USART1CLKSOURCE_SYSCLK) || \ + ((__SOURCE__) == RCC_USART1CLKSOURCE_LSE) || \ + ((__SOURCE__) == RCC_USART1CLKSOURCE_HSI)) +#define IS_RCC_I2C1CLKSOURCE(__SOURCE__) (((__SOURCE__) == RCC_I2C1CLKSOURCE_HSI) || \ + ((__SOURCE__) == RCC_I2C1CLKSOURCE_SYSCLK)) + +/** + * @} + */ + +/* Exported types ------------------------------------------------------------*/ + +/** @defgroup RCC_Exported_Types RCC Exported Types + * @{ + */ + +/** + * @brief RCC PLL configuration structure definition + */ +typedef struct +{ + uint32_t PLLState; /*!< PLLState: The new state of the PLL. + This parameter can be a value of @ref RCC_PLL_Config */ + + uint32_t PLLSource; /*!< PLLSource: PLL entry clock source. + This parameter must be a value of @ref RCC_PLL_Clock_Source */ + + uint32_t PLLMUL; /*!< PLLMUL: Multiplication factor for PLL VCO input clock + This parameter must be a value of @ref RCC_PLL_Multiplication_Factor*/ + + uint32_t PREDIV; /*!< PREDIV: Predivision factor for PLL VCO input clock + This parameter must be a value of @ref RCC_PLL_Prediv_Factor */ + +} RCC_PLLInitTypeDef; + +/** + * @brief RCC Internal/External Oscillator (HSE, HSI, LSE and LSI) configuration structure definition + */ +typedef struct +{ + uint32_t OscillatorType; /*!< The oscillators to be configured. + This parameter can be a value of @ref RCC_Oscillator_Type */ + + uint32_t HSEState; /*!< The new state of the HSE. + This parameter can be a value of @ref RCC_HSE_Config */ + + uint32_t LSEState; /*!< The new state of the LSE. + This parameter can be a value of @ref RCC_LSE_Config */ + + uint32_t HSIState; /*!< The new state of the HSI. + This parameter can be a value of @ref RCC_HSI_Config */ + + uint32_t HSICalibrationValue; /*!< The HSI calibration trimming value (default is RCC_HSICALIBRATION_DEFAULT). + This parameter must be a number between Min_Data = 0x00 and Max_Data = 0x1FU */ + + uint32_t HSI14State; /*!< The new state of the HSI14. + This parameter can be a value of @ref RCC_HSI14_Config */ + + uint32_t HSI14CalibrationValue; /*!< The HSI14 calibration trimming value (default is RCC_HSI14CALIBRATION_DEFAULT). + This parameter must be a number between Min_Data = 0x00 and Max_Data = 0x1FU */ + + uint32_t LSIState; /*!< The new state of the LSI. + This parameter can be a value of @ref RCC_LSI_Config */ + +#if defined(RCC_HSI48_SUPPORT) + uint32_t HSI48State; /*!< The new state of the HSI48. + This parameter can be a value of @ref RCC_HSI48_Config */ + +#endif /* RCC_HSI48_SUPPORT */ + RCC_PLLInitTypeDef PLL; /*!< PLL structure parameters */ + +} RCC_OscInitTypeDef; + +/** + * @brief RCC System, AHB and APB busses clock configuration structure definition + */ +typedef struct +{ + uint32_t ClockType; /*!< The clock to be configured. + This parameter can be a value of @ref RCC_System_Clock_Type */ + + uint32_t SYSCLKSource; /*!< The clock source (SYSCLKS) used as system clock. + This parameter can be a value of @ref RCC_System_Clock_Source */ + + uint32_t AHBCLKDivider; /*!< The AHB clock (HCLK) divider. This clock is derived from the system clock (SYSCLK). + This parameter can be a value of @ref RCC_AHB_Clock_Source */ + + uint32_t APB1CLKDivider; /*!< The APB1 clock (PCLK1) divider. This clock is derived from the AHB clock (HCLK). + This parameter can be a value of @ref RCC_APB1_Clock_Source */ + +} RCC_ClkInitTypeDef; + +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup RCC_Exported_Constants RCC Exported Constants + * @{ + */ + +/** @defgroup RCC_PLL_Clock_Source PLL Clock Source + * @{ + */ + +#define RCC_PLLSOURCE_HSE RCC_CFGR_PLLSRC_HSE_PREDIV /*!< HSE clock selected as PLL entry clock source */ + +/** + * @} + */ + +/** @defgroup RCC_Oscillator_Type Oscillator Type + * @{ + */ +#define RCC_OSCILLATORTYPE_NONE (0x00000000U) +#define RCC_OSCILLATORTYPE_HSE (0x00000001U) +#define RCC_OSCILLATORTYPE_HSI (0x00000002U) +#define RCC_OSCILLATORTYPE_LSE (0x00000004U) +#define RCC_OSCILLATORTYPE_LSI (0x00000008U) +#define RCC_OSCILLATORTYPE_HSI14 (0x00000010U) +#if defined(RCC_HSI48_SUPPORT) +#define RCC_OSCILLATORTYPE_HSI48 (0x00000020U) +#endif /* RCC_HSI48_SUPPORT */ +/** + * @} + */ + +/** @defgroup RCC_HSE_Config HSE Config + * @{ + */ +#define RCC_HSE_OFF (0x00000000U) /*!< HSE clock deactivation */ +#define RCC_HSE_ON (0x00000001U) /*!< HSE clock activation */ +#define RCC_HSE_BYPASS (0x00000005U) /*!< External clock source for HSE clock */ +/** + * @} + */ + +/** @defgroup RCC_LSE_Config LSE Config + * @{ + */ +#define RCC_LSE_OFF (0x00000000U) /*!< LSE clock deactivation */ +#define RCC_LSE_ON (0x00000001U) /*!< LSE clock activation */ +#define RCC_LSE_BYPASS (0x00000005U) /*!< External clock source for LSE clock */ + +/** + * @} + */ + +/** @defgroup RCC_HSI_Config HSI Config + * @{ + */ +#define RCC_HSI_OFF (0x00000000U) /*!< HSI clock deactivation */ +#define RCC_HSI_ON RCC_CR_HSION /*!< HSI clock activation */ + +#define RCC_HSICALIBRATION_DEFAULT (0x10U) /* Default HSI calibration trimming value */ + +/** + * @} + */ + +/** @defgroup RCC_HSI14_Config RCC HSI14 Config + * @{ + */ +#define RCC_HSI14_OFF (0x00000000U) +#define RCC_HSI14_ON RCC_CR2_HSI14ON +#define RCC_HSI14_ADC_CONTROL (~RCC_CR2_HSI14DIS) + +#define RCC_HSI14CALIBRATION_DEFAULT (0x10U) /* Default HSI14 calibration trimming value */ +/** + * @} + */ + +/** @defgroup RCC_LSI_Config LSI Config + * @{ + */ +#define RCC_LSI_OFF (0x00000000U) /*!< LSI clock deactivation */ +#define RCC_LSI_ON RCC_CSR_LSION /*!< LSI clock activation */ + +/** + * @} + */ + +#if defined(RCC_HSI48_SUPPORT) +/** @defgroup RCC_HSI48_Config HSI48 Config + * @{ + */ +#define RCC_HSI48_OFF ((uint8_t)0x00U) +#define RCC_HSI48_ON ((uint8_t)0x01U) + +/** + * @} + */ +#endif /* RCC_HSI48_SUPPORT */ + +/** @defgroup RCC_PLL_Config PLL Config + * @{ + */ +#define RCC_PLL_NONE (0x00000000U) /*!< PLL is not configured */ +#define RCC_PLL_OFF (0x00000001U) /*!< PLL deactivation */ +#define RCC_PLL_ON (0x00000002U) /*!< PLL activation */ + +/** + * @} + */ + +/** @defgroup RCC_System_Clock_Type System Clock Type + * @{ + */ +#define RCC_CLOCKTYPE_SYSCLK (0x00000001U) /*!< SYSCLK to configure */ +#define RCC_CLOCKTYPE_HCLK (0x00000002U) /*!< HCLK to configure */ +#define RCC_CLOCKTYPE_PCLK1 (0x00000004U) /*!< PCLK1 to configure */ + +/** + * @} + */ + +/** @defgroup RCC_System_Clock_Source System Clock Source + * @{ + */ +#define RCC_SYSCLKSOURCE_HSI RCC_CFGR_SW_HSI /*!< HSI selected as system clock */ +#define RCC_SYSCLKSOURCE_HSE RCC_CFGR_SW_HSE /*!< HSE selected as system clock */ +#define RCC_SYSCLKSOURCE_PLLCLK RCC_CFGR_SW_PLL /*!< PLL selected as system clock */ + +/** + * @} + */ + +/** @defgroup RCC_System_Clock_Source_Status System Clock Source Status + * @{ + */ +#define RCC_SYSCLKSOURCE_STATUS_HSI RCC_CFGR_SWS_HSI /*!< HSI used as system clock */ +#define RCC_SYSCLKSOURCE_STATUS_HSE RCC_CFGR_SWS_HSE /*!< HSE used as system clock */ +#define RCC_SYSCLKSOURCE_STATUS_PLLCLK RCC_CFGR_SWS_PLL /*!< PLL used as system clock */ + +/** + * @} + */ + +/** @defgroup RCC_AHB_Clock_Source AHB Clock Source + * @{ + */ +#define RCC_SYSCLK_DIV1 RCC_CFGR_HPRE_DIV1 /*!< SYSCLK not divided */ +#define RCC_SYSCLK_DIV2 RCC_CFGR_HPRE_DIV2 /*!< SYSCLK divided by 2 */ +#define RCC_SYSCLK_DIV4 RCC_CFGR_HPRE_DIV4 /*!< SYSCLK divided by 4 */ +#define RCC_SYSCLK_DIV8 RCC_CFGR_HPRE_DIV8 /*!< SYSCLK divided by 8 */ +#define RCC_SYSCLK_DIV16 RCC_CFGR_HPRE_DIV16 /*!< SYSCLK divided by 16 */ +#define RCC_SYSCLK_DIV64 RCC_CFGR_HPRE_DIV64 /*!< SYSCLK divided by 64 */ +#define RCC_SYSCLK_DIV128 RCC_CFGR_HPRE_DIV128 /*!< SYSCLK divided by 128 */ +#define RCC_SYSCLK_DIV256 RCC_CFGR_HPRE_DIV256 /*!< SYSCLK divided by 256 */ +#define RCC_SYSCLK_DIV512 RCC_CFGR_HPRE_DIV512 /*!< SYSCLK divided by 512 */ + +/** + * @} + */ + +/** @defgroup RCC_APB1_Clock_Source RCC APB1 Clock Source + * @{ + */ +#define RCC_HCLK_DIV1 RCC_CFGR_PPRE_DIV1 /*!< HCLK not divided */ +#define RCC_HCLK_DIV2 RCC_CFGR_PPRE_DIV2 /*!< HCLK divided by 2 */ +#define RCC_HCLK_DIV4 RCC_CFGR_PPRE_DIV4 /*!< HCLK divided by 4 */ +#define RCC_HCLK_DIV8 RCC_CFGR_PPRE_DIV8 /*!< HCLK divided by 8 */ +#define RCC_HCLK_DIV16 RCC_CFGR_PPRE_DIV16 /*!< HCLK divided by 16 */ + +/** + * @} + */ + +/** @defgroup RCC_RTC_Clock_Source RTC Clock Source + * @{ + */ +#define RCC_RTCCLKSOURCE_NO_CLK (0x00000000U) /*!< No clock */ +#define RCC_RTCCLKSOURCE_LSE RCC_BDCR_RTCSEL_LSE /*!< LSE oscillator clock used as RTC clock */ +#define RCC_RTCCLKSOURCE_LSI RCC_BDCR_RTCSEL_LSI /*!< LSI oscillator clock used as RTC clock */ +#define RCC_RTCCLKSOURCE_HSE_DIV32 RCC_BDCR_RTCSEL_HSE /*!< HSE oscillator clock divided by 32 used as RTC clock */ +/** + * @} + */ + +/** @defgroup RCC_PLL_Multiplication_Factor RCC PLL Multiplication Factor + * @{ + */ +#define RCC_PLL_MUL2 RCC_CFGR_PLLMUL2 +#define RCC_PLL_MUL3 RCC_CFGR_PLLMUL3 +#define RCC_PLL_MUL4 RCC_CFGR_PLLMUL4 +#define RCC_PLL_MUL5 RCC_CFGR_PLLMUL5 +#define RCC_PLL_MUL6 RCC_CFGR_PLLMUL6 +#define RCC_PLL_MUL7 RCC_CFGR_PLLMUL7 +#define RCC_PLL_MUL8 RCC_CFGR_PLLMUL8 +#define RCC_PLL_MUL9 RCC_CFGR_PLLMUL9 +#define RCC_PLL_MUL10 RCC_CFGR_PLLMUL10 +#define RCC_PLL_MUL11 RCC_CFGR_PLLMUL11 +#define RCC_PLL_MUL12 RCC_CFGR_PLLMUL12 +#define RCC_PLL_MUL13 RCC_CFGR_PLLMUL13 +#define RCC_PLL_MUL14 RCC_CFGR_PLLMUL14 +#define RCC_PLL_MUL15 RCC_CFGR_PLLMUL15 +#define RCC_PLL_MUL16 RCC_CFGR_PLLMUL16 + +/** + * @} + */ + +/** @defgroup RCC_PLL_Prediv_Factor RCC PLL Prediv Factor + * @{ + */ + +#define RCC_PREDIV_DIV1 RCC_CFGR2_PREDIV_DIV1 +#define RCC_PREDIV_DIV2 RCC_CFGR2_PREDIV_DIV2 +#define RCC_PREDIV_DIV3 RCC_CFGR2_PREDIV_DIV3 +#define RCC_PREDIV_DIV4 RCC_CFGR2_PREDIV_DIV4 +#define RCC_PREDIV_DIV5 RCC_CFGR2_PREDIV_DIV5 +#define RCC_PREDIV_DIV6 RCC_CFGR2_PREDIV_DIV6 +#define RCC_PREDIV_DIV7 RCC_CFGR2_PREDIV_DIV7 +#define RCC_PREDIV_DIV8 RCC_CFGR2_PREDIV_DIV8 +#define RCC_PREDIV_DIV9 RCC_CFGR2_PREDIV_DIV9 +#define RCC_PREDIV_DIV10 RCC_CFGR2_PREDIV_DIV10 +#define RCC_PREDIV_DIV11 RCC_CFGR2_PREDIV_DIV11 +#define RCC_PREDIV_DIV12 RCC_CFGR2_PREDIV_DIV12 +#define RCC_PREDIV_DIV13 RCC_CFGR2_PREDIV_DIV13 +#define RCC_PREDIV_DIV14 RCC_CFGR2_PREDIV_DIV14 +#define RCC_PREDIV_DIV15 RCC_CFGR2_PREDIV_DIV15 +#define RCC_PREDIV_DIV16 RCC_CFGR2_PREDIV_DIV16 + +/** + * @} + */ + + +/** @defgroup RCC_USART1_Clock_Source RCC USART1 Clock Source + * @{ + */ +#define RCC_USART1CLKSOURCE_PCLK1 RCC_CFGR3_USART1SW_PCLK +#define RCC_USART1CLKSOURCE_SYSCLK RCC_CFGR3_USART1SW_SYSCLK +#define RCC_USART1CLKSOURCE_LSE RCC_CFGR3_USART1SW_LSE +#define RCC_USART1CLKSOURCE_HSI RCC_CFGR3_USART1SW_HSI + +/** + * @} + */ + +/** @defgroup RCC_I2C1_Clock_Source RCC I2C1 Clock Source + * @{ + */ +#define RCC_I2C1CLKSOURCE_HSI RCC_CFGR3_I2C1SW_HSI +#define RCC_I2C1CLKSOURCE_SYSCLK RCC_CFGR3_I2C1SW_SYSCLK + +/** + * @} + */ +/** @defgroup RCC_MCO_Index MCO Index + * @{ + */ +#define RCC_MCO1 (0x00000000U) +#define RCC_MCO RCC_MCO1 /*!< MCO1 to be compliant with other families with 2 MCOs*/ + +/** + * @} + */ + +/** @defgroup RCC_MCO_Clock_Source RCC MCO Clock Source + * @{ + */ +#define RCC_MCO1SOURCE_NOCLOCK RCC_CFGR_MCO_NOCLOCK +#define RCC_MCO1SOURCE_LSI RCC_CFGR_MCO_LSI +#define RCC_MCO1SOURCE_LSE RCC_CFGR_MCO_LSE +#define RCC_MCO1SOURCE_SYSCLK RCC_CFGR_MCO_SYSCLK +#define RCC_MCO1SOURCE_HSI RCC_CFGR_MCO_HSI +#define RCC_MCO1SOURCE_HSE RCC_CFGR_MCO_HSE +#define RCC_MCO1SOURCE_PLLCLK_DIV2 RCC_CFGR_MCO_PLL +#define RCC_MCO1SOURCE_HSI14 RCC_CFGR_MCO_HSI14 + +/** + * @} + */ + +/** @defgroup RCC_Interrupt Interrupts + * @{ + */ +#define RCC_IT_LSIRDY ((uint8_t)RCC_CIR_LSIRDYF) /*!< LSI Ready Interrupt flag */ +#define RCC_IT_LSERDY ((uint8_t)RCC_CIR_LSERDYF) /*!< LSE Ready Interrupt flag */ +#define RCC_IT_HSIRDY ((uint8_t)RCC_CIR_HSIRDYF) /*!< HSI Ready Interrupt flag */ +#define RCC_IT_HSERDY ((uint8_t)RCC_CIR_HSERDYF) /*!< HSE Ready Interrupt flag */ +#define RCC_IT_PLLRDY ((uint8_t)RCC_CIR_PLLRDYF) /*!< PLL Ready Interrupt flag */ +#define RCC_IT_HSI14RDY ((uint8_t)RCC_CIR_HSI14RDYF) /*!< HSI14 Ready Interrupt flag */ +#if defined(RCC_CIR_HSI48RDYF) +#define RCC_IT_HSI48RDY ((uint8_t)RCC_CIR_HSI48RDYF) /*!< HSI48 Ready Interrupt flag */ +#endif +#define RCC_IT_CSS ((uint8_t)RCC_CIR_CSSF) /*!< Clock Security System Interrupt flag */ +/** + * @} + */ + +/** @defgroup RCC_Flag Flags + * Elements values convention: XXXYYYYYb + * - YYYYY : Flag position in the register + * - XXX : Register index + * - 001: CR register + * - 010: CR2 register + * - 011: BDCR register + * - 0100: CSR register + * @{ + */ +/* Flags in the CR register */ +#define RCC_FLAG_HSIRDY ((uint8_t)((CR_REG_INDEX << 5U) | RCC_CR_HSIRDY_BitNumber)) +#define RCC_FLAG_HSERDY ((uint8_t)((CR_REG_INDEX << 5U) | RCC_CR_HSERDY_BitNumber)) +#define RCC_FLAG_PLLRDY ((uint8_t)((CR_REG_INDEX << 5U) | RCC_CR_PLLRDY_BitNumber)) +/* Flags in the CR2 register */ +#define RCC_FLAG_HSI14RDY ((uint8_t)((CR2_REG_INDEX << 5U) | RCC_CR2_HSI14RDY_BitNumber)) + +/* Flags in the CSR register */ +#define RCC_FLAG_LSIRDY ((uint8_t)((CSR_REG_INDEX << 5U) | RCC_CSR_LSIRDY_BitNumber)) +#if defined(RCC_CSR_V18PWRRSTF) +#define RCC_FLAG_V18PWRRST ((uint8_t)((CSR_REG_INDEX << 5U) | RCC_CSR_V18PWRRSTF_BitNumber)) +#endif +#define RCC_FLAG_OBLRST ((uint8_t)((CSR_REG_INDEX << 5U) | RCC_CSR_OBLRSTF_BitNumber)) +#define RCC_FLAG_PINRST ((uint8_t)((CSR_REG_INDEX << 5U) | RCC_CSR_PINRSTF_BitNumber)) /*!< PIN reset flag */ +#define RCC_FLAG_PORRST ((uint8_t)((CSR_REG_INDEX << 5U) | RCC_CSR_PORRSTF_BitNumber)) /*!< POR/PDR reset flag */ +#define RCC_FLAG_SFTRST ((uint8_t)((CSR_REG_INDEX << 5U) | RCC_CSR_SFTRSTF_BitNumber)) /*!< Software Reset flag */ +#define RCC_FLAG_IWDGRST ((uint8_t)((CSR_REG_INDEX << 5U) | RCC_CSR_IWDGRSTF_BitNumber)) /*!< Independent Watchdog reset flag */ +#define RCC_FLAG_WWDGRST ((uint8_t)((CSR_REG_INDEX << 5U) | RCC_CSR_WWDGRSTF_BitNumber)) /*!< Window watchdog reset flag */ +#define RCC_FLAG_LPWRRST ((uint8_t)((CSR_REG_INDEX << 5U) | RCC_CSR_LPWRRSTF_BitNumber)) /*!< Low-Power reset flag */ + +/* Flags in the BDCR register */ +#define RCC_FLAG_LSERDY ((uint8_t)((BDCR_REG_INDEX << 5U) | RCC_BDCR_LSERDY_BitNumber)) /*!< External Low Speed oscillator Ready */ + +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ + +/** @defgroup RCC_Exported_Macros RCC Exported Macros + * @{ + */ + +/** @defgroup RCC_AHB_Clock_Enable_Disable RCC AHB Clock Enable Disable + * @brief Enable or disable the AHB peripheral clock. + * @note After reset, the peripheral clock (used for registers read/write access) + * is disabled and the application software has to enable this clock before + * using it. + * @{ + */ +#define __HAL_RCC_GPIOA_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHBENR, RCC_AHBENR_GPIOAEN);\ + /* Delay after an RCC peripheral clock enabling */\ + tmpreg = READ_BIT(RCC->AHBENR, RCC_AHBENR_GPIOAEN);\ + UNUSED(tmpreg); \ + } while(0U) +#define __HAL_RCC_GPIOB_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHBENR, RCC_AHBENR_GPIOBEN);\ + /* Delay after an RCC peripheral clock enabling */\ + tmpreg = READ_BIT(RCC->AHBENR, RCC_AHBENR_GPIOBEN);\ + UNUSED(tmpreg); \ + } while(0U) +#define __HAL_RCC_GPIOC_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHBENR, RCC_AHBENR_GPIOCEN);\ + /* Delay after an RCC peripheral clock enabling */\ + tmpreg = READ_BIT(RCC->AHBENR, RCC_AHBENR_GPIOCEN);\ + UNUSED(tmpreg); \ + } while(0U) +#define __HAL_RCC_GPIOF_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHBENR, RCC_AHBENR_GPIOFEN);\ + /* Delay after an RCC peripheral clock enabling */\ + tmpreg = READ_BIT(RCC->AHBENR, RCC_AHBENR_GPIOFEN);\ + UNUSED(tmpreg); \ + } while(0U) +#define __HAL_RCC_CRC_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHBENR, RCC_AHBENR_CRCEN);\ + /* Delay after an RCC peripheral clock enabling */\ + tmpreg = READ_BIT(RCC->AHBENR, RCC_AHBENR_CRCEN);\ + UNUSED(tmpreg); \ + } while(0U) +#define __HAL_RCC_DMA1_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHBENR, RCC_AHBENR_DMA1EN);\ + /* Delay after an RCC peripheral clock enabling */\ + tmpreg = READ_BIT(RCC->AHBENR, RCC_AHBENR_DMA1EN);\ + UNUSED(tmpreg); \ + } while(0U) +#define __HAL_RCC_SRAM_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHBENR, RCC_AHBENR_SRAMEN);\ + /* Delay after an RCC peripheral clock enabling */\ + tmpreg = READ_BIT(RCC->AHBENR, RCC_AHBENR_SRAMEN);\ + UNUSED(tmpreg); \ + } while(0U) +#define __HAL_RCC_FLITF_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHBENR, RCC_AHBENR_FLITFEN);\ + /* Delay after an RCC peripheral clock enabling */\ + tmpreg = READ_BIT(RCC->AHBENR, RCC_AHBENR_FLITFEN);\ + UNUSED(tmpreg); \ + } while(0U) + +#define __HAL_RCC_GPIOA_CLK_DISABLE() (RCC->AHBENR &= ~(RCC_AHBENR_GPIOAEN)) +#define __HAL_RCC_GPIOB_CLK_DISABLE() (RCC->AHBENR &= ~(RCC_AHBENR_GPIOBEN)) +#define __HAL_RCC_GPIOC_CLK_DISABLE() (RCC->AHBENR &= ~(RCC_AHBENR_GPIOCEN)) +#define __HAL_RCC_GPIOF_CLK_DISABLE() (RCC->AHBENR &= ~(RCC_AHBENR_GPIOFEN)) +#define __HAL_RCC_CRC_CLK_DISABLE() (RCC->AHBENR &= ~(RCC_AHBENR_CRCEN)) +#define __HAL_RCC_DMA1_CLK_DISABLE() (RCC->AHBENR &= ~(RCC_AHBENR_DMA1EN)) +#define __HAL_RCC_SRAM_CLK_DISABLE() (RCC->AHBENR &= ~(RCC_AHBENR_SRAMEN)) +#define __HAL_RCC_FLITF_CLK_DISABLE() (RCC->AHBENR &= ~(RCC_AHBENR_FLITFEN)) +/** + * @} + */ + +/** @defgroup RCC_AHB_Peripheral_Clock_Enable_Disable_Status AHB Peripheral Clock Enable Disable Status + * @brief Get the enable or disable status of the AHB peripheral clock. + * @note After reset, the peripheral clock (used for registers read/write access) + * is disabled and the application software has to enable this clock before + * using it. + * @{ + */ +#define __HAL_RCC_GPIOA_IS_CLK_ENABLED() ((RCC->AHBENR & (RCC_AHBENR_GPIOAEN)) != RESET) +#define __HAL_RCC_GPIOB_IS_CLK_ENABLED() ((RCC->AHBENR & (RCC_AHBENR_GPIOBEN)) != RESET) +#define __HAL_RCC_GPIOC_IS_CLK_ENABLED() ((RCC->AHBENR & (RCC_AHBENR_GPIOCEN)) != RESET) +#define __HAL_RCC_GPIOF_IS_CLK_ENABLED() ((RCC->AHBENR & (RCC_AHBENR_GPIOFEN)) != RESET) +#define __HAL_RCC_CRC_IS_CLK_ENABLED() ((RCC->AHBENR & (RCC_AHBENR_CRCEN)) != RESET) +#define __HAL_RCC_DMA1_IS_CLK_ENABLED() ((RCC->AHBENR & (RCC_AHBENR_DMA1EN)) != RESET) +#define __HAL_RCC_SRAM_IS_CLK_ENABLED() ((RCC->AHBENR & (RCC_AHBENR_SRAMEN)) != RESET) +#define __HAL_RCC_FLITF_IS_CLK_ENABLED() ((RCC->AHBENR & (RCC_AHBENR_FLITFEN)) != RESET) +#define __HAL_RCC_GPIOA_IS_CLK_DISABLED() ((RCC->AHBENR & (RCC_AHBENR_GPIOAEN)) == RESET) +#define __HAL_RCC_GPIOB_IS_CLK_DISABLED() ((RCC->AHBENR & (RCC_AHBENR_GPIOBEN)) == RESET) +#define __HAL_RCC_GPIOC_IS_CLK_DISABLED() ((RCC->AHBENR & (RCC_AHBENR_GPIOCEN)) == RESET) +#define __HAL_RCC_GPIOF_IS_CLK_DISABLED() ((RCC->AHBENR & (RCC_AHBENR_GPIOFEN)) == RESET) +#define __HAL_RCC_CRC_IS_CLK_DISABLED() ((RCC->AHBENR & (RCC_AHBENR_CRCEN)) == RESET) +#define __HAL_RCC_DMA1_IS_CLK_DISABLED() ((RCC->AHBENR & (RCC_AHBENR_DMA1EN)) == RESET) +#define __HAL_RCC_SRAM_IS_CLK_DISABLED() ((RCC->AHBENR & (RCC_AHBENR_SRAMEN)) == RESET) +#define __HAL_RCC_FLITF_IS_CLK_DISABLED() ((RCC->AHBENR & (RCC_AHBENR_FLITFEN)) == RESET) +/** + * @} + */ + +/** @defgroup RCC_APB1_Clock_Enable_Disable RCC APB1 Clock Enable Disable + * @brief Enable or disable the Low Speed APB (APB1) peripheral clock. + * @note After reset, the peripheral clock (used for registers read/write access) + * is disabled and the application software has to enable this clock before + * using it. + * @{ + */ +#define __HAL_RCC_TIM3_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR, RCC_APB1ENR_TIM3EN);\ + /* Delay after an RCC peripheral clock enabling */\ + tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_TIM3EN);\ + UNUSED(tmpreg); \ + } while(0U) +#define __HAL_RCC_TIM14_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR, RCC_APB1ENR_TIM14EN);\ + /* Delay after an RCC peripheral clock enabling */\ + tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_TIM14EN);\ + UNUSED(tmpreg); \ + } while(0U) +#define __HAL_RCC_WWDG_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR, RCC_APB1ENR_WWDGEN);\ + /* Delay after an RCC peripheral clock enabling */\ + tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_WWDGEN);\ + UNUSED(tmpreg); \ + } while(0U) +#define __HAL_RCC_I2C1_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR, RCC_APB1ENR_I2C1EN);\ + /* Delay after an RCC peripheral clock enabling */\ + tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_I2C1EN);\ + UNUSED(tmpreg); \ + } while(0U) +#define __HAL_RCC_PWR_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR, RCC_APB1ENR_PWREN);\ + /* Delay after an RCC peripheral clock enabling */\ + tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_PWREN);\ + UNUSED(tmpreg); \ + } while(0U) + +#define __HAL_RCC_TIM3_CLK_DISABLE() (RCC->APB1ENR &= ~(RCC_APB1ENR_TIM3EN)) +#define __HAL_RCC_TIM14_CLK_DISABLE() (RCC->APB1ENR &= ~(RCC_APB1ENR_TIM14EN)) +#define __HAL_RCC_WWDG_CLK_DISABLE() (RCC->APB1ENR &= ~(RCC_APB1ENR_WWDGEN)) +#define __HAL_RCC_I2C1_CLK_DISABLE() (RCC->APB1ENR &= ~(RCC_APB1ENR_I2C1EN)) +#define __HAL_RCC_PWR_CLK_DISABLE() (RCC->APB1ENR &= ~(RCC_APB1ENR_PWREN)) +/** + * @} + */ + +/** @defgroup RCC_APB1_Peripheral_Clock_Enable_Disable_Status APB1 Peripheral Clock Enable Disable Status + * @brief Get the enable or disable status of the APB1 peripheral clock. + * @note After reset, the peripheral clock (used for registers read/write access) + * is disabled and the application software has to enable this clock before + * using it. + * @{ + */ +#define __HAL_RCC_TIM3_IS_CLK_ENABLED() ((RCC->APB1ENR & (RCC_APB1ENR_TIM3EN)) != RESET) +#define __HAL_RCC_TIM14_IS_CLK_ENABLED() ((RCC->APB1ENR & (RCC_APB1ENR_TIM14EN)) != RESET) +#define __HAL_RCC_WWDG_IS_CLK_ENABLED() ((RCC->APB1ENR & (RCC_APB1ENR_WWDGEN)) != RESET) +#define __HAL_RCC_I2C1_IS_CLK_ENABLED() ((RCC->APB1ENR & (RCC_APB1ENR_I2C1EN)) != RESET) +#define __HAL_RCC_PWR_IS_CLK_ENABLED() ((RCC->APB1ENR & (RCC_APB1ENR_PWREN)) != RESET) +#define __HAL_RCC_TIM3_IS_CLK_DISABLED() ((RCC->APB1ENR & (RCC_APB1ENR_TIM3EN)) == RESET) +#define __HAL_RCC_TIM14_IS_CLK_DISABLED() ((RCC->APB1ENR & (RCC_APB1ENR_TIM14EN)) == RESET) +#define __HAL_RCC_WWDG_IS_CLK_DISABLED() ((RCC->APB1ENR & (RCC_APB1ENR_WWDGEN)) == RESET) +#define __HAL_RCC_I2C1_IS_CLK_DISABLED() ((RCC->APB1ENR & (RCC_APB1ENR_I2C1EN)) == RESET) +#define __HAL_RCC_PWR_IS_CLK_DISABLED() ((RCC->APB1ENR & (RCC_APB1ENR_PWREN)) == RESET) +/** + * @} + */ + + +/** @defgroup RCC_APB2_Clock_Enable_Disable RCC APB2 Clock Enable Disable + * @brief Enable or disable the High Speed APB (APB2) peripheral clock. + * @note After reset, the peripheral clock (used for registers read/write access) + * is disabled and the application software has to enable this clock before + * using it. + * @{ + */ +#define __HAL_RCC_SYSCFG_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB2ENR, RCC_APB2ENR_SYSCFGEN);\ + /* Delay after an RCC peripheral clock enabling */\ + tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_SYSCFGEN);\ + UNUSED(tmpreg); \ + } while(0U) +#define __HAL_RCC_ADC1_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB2ENR, RCC_APB2ENR_ADC1EN);\ + /* Delay after an RCC peripheral clock enabling */\ + tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_ADC1EN);\ + UNUSED(tmpreg); \ + } while(0U) +#define __HAL_RCC_TIM1_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB2ENR, RCC_APB2ENR_TIM1EN);\ + /* Delay after an RCC peripheral clock enabling */\ + tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_TIM1EN);\ + UNUSED(tmpreg); \ + } while(0U) +#define __HAL_RCC_SPI1_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB2ENR, RCC_APB2ENR_SPI1EN);\ + /* Delay after an RCC peripheral clock enabling */\ + tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_SPI1EN);\ + UNUSED(tmpreg); \ + } while(0U) +#define __HAL_RCC_TIM16_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB2ENR, RCC_APB2ENR_TIM16EN);\ + /* Delay after an RCC peripheral clock enabling */\ + tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_TIM16EN);\ + UNUSED(tmpreg); \ + } while(0U) +#define __HAL_RCC_TIM17_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB2ENR, RCC_APB2ENR_TIM17EN);\ + /* Delay after an RCC peripheral clock enabling */\ + tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_TIM17EN);\ + UNUSED(tmpreg); \ + } while(0U) +#define __HAL_RCC_USART1_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB2ENR, RCC_APB2ENR_USART1EN);\ + /* Delay after an RCC peripheral clock enabling */\ + tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_USART1EN);\ + UNUSED(tmpreg); \ + } while(0U) +#define __HAL_RCC_DBGMCU_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB2ENR, RCC_APB2ENR_DBGMCUEN);\ + /* Delay after an RCC peripheral clock enabling */\ + tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_DBGMCUEN);\ + UNUSED(tmpreg); \ + } while(0U) + +#define __HAL_RCC_SYSCFG_CLK_DISABLE() (RCC->APB2ENR &= ~(RCC_APB2ENR_SYSCFGEN)) +#define __HAL_RCC_ADC1_CLK_DISABLE() (RCC->APB2ENR &= ~(RCC_APB2ENR_ADC1EN)) +#define __HAL_RCC_TIM1_CLK_DISABLE() (RCC->APB2ENR &= ~(RCC_APB2ENR_TIM1EN)) +#define __HAL_RCC_SPI1_CLK_DISABLE() (RCC->APB2ENR &= ~(RCC_APB2ENR_SPI1EN)) +#define __HAL_RCC_TIM16_CLK_DISABLE() (RCC->APB2ENR &= ~(RCC_APB2ENR_TIM16EN)) +#define __HAL_RCC_TIM17_CLK_DISABLE() (RCC->APB2ENR &= ~(RCC_APB2ENR_TIM17EN)) +#define __HAL_RCC_USART1_CLK_DISABLE() (RCC->APB2ENR &= ~(RCC_APB2ENR_USART1EN)) +#define __HAL_RCC_DBGMCU_CLK_DISABLE() (RCC->APB2ENR &= ~(RCC_APB2ENR_DBGMCUEN)) +/** + * @} + */ + +/** @defgroup RCC_APB2_Peripheral_Clock_Enable_Disable_Status APB2 Peripheral Clock Enable Disable Status + * @brief Get the enable or disable status of the APB2 peripheral clock. + * @note After reset, the peripheral clock (used for registers read/write access) + * is disabled and the application software has to enable this clock before + * using it. + * @{ + */ +#define __HAL_RCC_SYSCFG_IS_CLK_ENABLED() ((RCC->APB2ENR & (RCC_APB2ENR_SYSCFGEN)) != RESET) +#define __HAL_RCC_ADC1_IS_CLK_ENABLED() ((RCC->APB2ENR & (RCC_APB2ENR_ADC1EN)) != RESET) +#define __HAL_RCC_TIM1_IS_CLK_ENABLED() ((RCC->APB2ENR & (RCC_APB2ENR_TIM1EN)) != RESET) +#define __HAL_RCC_SPI1_IS_CLK_ENABLED() ((RCC->APB2ENR & (RCC_APB2ENR_SPI1EN)) != RESET) +#define __HAL_RCC_TIM16_IS_CLK_ENABLED() ((RCC->APB2ENR & (RCC_APB2ENR_TIM16EN)) != RESET) +#define __HAL_RCC_TIM17_IS_CLK_ENABLED() ((RCC->APB2ENR & (RCC_APB2ENR_TIM17EN)) != RESET) +#define __HAL_RCC_USART1_IS_CLK_ENABLED() ((RCC->APB2ENR & (RCC_APB2ENR_USART1EN)) != RESET) +#define __HAL_RCC_DBGMCU_IS_CLK_ENABLED() ((RCC->APB2ENR & (RCC_APB2ENR_DBGMCUEN)) != RESET) +#define __HAL_RCC_SYSCFG_IS_CLK_DISABLED() ((RCC->APB2ENR & (RCC_APB2ENR_SYSCFGEN)) == RESET) +#define __HAL_RCC_ADC1_IS_CLK_DISABLED() ((RCC->APB2ENR & (RCC_APB2ENR_ADC1EN)) == RESET) +#define __HAL_RCC_TIM1_IS_CLK_DISABLED() ((RCC->APB2ENR & (RCC_APB2ENR_TIM1EN)) == RESET) +#define __HAL_RCC_SPI1_IS_CLK_DISABLED() ((RCC->APB2ENR & (RCC_APB2ENR_SPI1EN)) == RESET) +#define __HAL_RCC_TIM16_IS_CLK_DISABLED() ((RCC->APB2ENR & (RCC_APB2ENR_TIM16EN)) == RESET) +#define __HAL_RCC_TIM17_IS_CLK_DISABLED() ((RCC->APB2ENR & (RCC_APB2ENR_TIM17EN)) == RESET) +#define __HAL_RCC_USART1_IS_CLK_DISABLED() ((RCC->APB2ENR & (RCC_APB2ENR_USART1EN)) == RESET) +#define __HAL_RCC_DBGMCU_IS_CLK_DISABLED() ((RCC->APB2ENR & (RCC_APB2ENR_DBGMCUEN)) == RESET) +/** + * @} + */ + +/** @defgroup RCC_AHB_Force_Release_Reset RCC AHB Force Release Reset + * @brief Force or release AHB peripheral reset. + * @{ + */ +#define __HAL_RCC_AHB_FORCE_RESET() (RCC->AHBRSTR = 0xFFFFFFFFU) +#define __HAL_RCC_GPIOA_FORCE_RESET() (RCC->AHBRSTR |= (RCC_AHBRSTR_GPIOARST)) +#define __HAL_RCC_GPIOB_FORCE_RESET() (RCC->AHBRSTR |= (RCC_AHBRSTR_GPIOBRST)) +#define __HAL_RCC_GPIOC_FORCE_RESET() (RCC->AHBRSTR |= (RCC_AHBRSTR_GPIOCRST)) +#define __HAL_RCC_GPIOF_FORCE_RESET() (RCC->AHBRSTR |= (RCC_AHBRSTR_GPIOFRST)) + +#define __HAL_RCC_AHB_RELEASE_RESET() (RCC->AHBRSTR = 0x00000000U) +#define __HAL_RCC_GPIOA_RELEASE_RESET() (RCC->AHBRSTR &= ~(RCC_AHBRSTR_GPIOARST)) +#define __HAL_RCC_GPIOB_RELEASE_RESET() (RCC->AHBRSTR &= ~(RCC_AHBRSTR_GPIOBRST)) +#define __HAL_RCC_GPIOC_RELEASE_RESET() (RCC->AHBRSTR &= ~(RCC_AHBRSTR_GPIOCRST)) +#define __HAL_RCC_GPIOF_RELEASE_RESET() (RCC->AHBRSTR &= ~(RCC_AHBRSTR_GPIOFRST)) +/** + * @} + */ + +/** @defgroup RCC_APB1_Force_Release_Reset RCC APB1 Force Release Reset + * @brief Force or release APB1 peripheral reset. + * @{ + */ +#define __HAL_RCC_APB1_FORCE_RESET() (RCC->APB1RSTR = 0xFFFFFFFFU) +#define __HAL_RCC_TIM3_FORCE_RESET() (RCC->APB1RSTR |= (RCC_APB1RSTR_TIM3RST)) +#define __HAL_RCC_TIM14_FORCE_RESET() (RCC->APB1RSTR |= (RCC_APB1RSTR_TIM14RST)) +#define __HAL_RCC_WWDG_FORCE_RESET() (RCC->APB1RSTR |= (RCC_APB1RSTR_WWDGRST)) +#define __HAL_RCC_I2C1_FORCE_RESET() (RCC->APB1RSTR |= (RCC_APB1RSTR_I2C1RST)) +#define __HAL_RCC_PWR_FORCE_RESET() (RCC->APB1RSTR |= (RCC_APB1RSTR_PWRRST)) + +#define __HAL_RCC_APB1_RELEASE_RESET() (RCC->APB1RSTR = 0x00000000U) +#define __HAL_RCC_TIM3_RELEASE_RESET() (RCC->APB1RSTR &= ~(RCC_APB1RSTR_TIM3RST)) +#define __HAL_RCC_TIM14_RELEASE_RESET() (RCC->APB1RSTR &= ~(RCC_APB1RSTR_TIM14RST)) +#define __HAL_RCC_WWDG_RELEASE_RESET() (RCC->APB1RSTR &= ~(RCC_APB1RSTR_WWDGRST)) +#define __HAL_RCC_I2C1_RELEASE_RESET() (RCC->APB1RSTR &= ~(RCC_APB1RSTR_I2C1RST)) +#define __HAL_RCC_PWR_RELEASE_RESET() (RCC->APB1RSTR &= ~(RCC_APB1RSTR_PWRRST)) +/** + * @} + */ + +/** @defgroup RCC_APB2_Force_Release_Reset RCC APB2 Force Release Reset + * @brief Force or release APB2 peripheral reset. + * @{ + */ +#define __HAL_RCC_APB2_FORCE_RESET() (RCC->APB2RSTR = 0xFFFFFFFFU) +#define __HAL_RCC_SYSCFG_FORCE_RESET() (RCC->APB2RSTR |= (RCC_APB2RSTR_SYSCFGRST)) +#define __HAL_RCC_ADC1_FORCE_RESET() (RCC->APB2RSTR |= (RCC_APB2RSTR_ADC1RST)) +#define __HAL_RCC_TIM1_FORCE_RESET() (RCC->APB2RSTR |= (RCC_APB2RSTR_TIM1RST)) +#define __HAL_RCC_SPI1_FORCE_RESET() (RCC->APB2RSTR |= (RCC_APB2RSTR_SPI1RST)) +#define __HAL_RCC_USART1_FORCE_RESET() (RCC->APB2RSTR |= (RCC_APB2RSTR_USART1RST)) +#define __HAL_RCC_TIM16_FORCE_RESET() (RCC->APB2RSTR |= (RCC_APB2RSTR_TIM16RST)) +#define __HAL_RCC_TIM17_FORCE_RESET() (RCC->APB2RSTR |= (RCC_APB2RSTR_TIM17RST)) +#define __HAL_RCC_DBGMCU_FORCE_RESET() (RCC->APB2RSTR |= (RCC_APB2RSTR_DBGMCURST)) + +#define __HAL_RCC_APB2_RELEASE_RESET() (RCC->APB2RSTR = 0x00000000U) +#define __HAL_RCC_SYSCFG_RELEASE_RESET() (RCC->APB2RSTR &= ~(RCC_APB2RSTR_SYSCFGRST)) +#define __HAL_RCC_ADC1_RELEASE_RESET() (RCC->APB2RSTR &= ~(RCC_APB2RSTR_ADC1RST)) +#define __HAL_RCC_TIM1_RELEASE_RESET() (RCC->APB2RSTR &= ~(RCC_APB2RSTR_TIM1RST)) +#define __HAL_RCC_SPI1_RELEASE_RESET() (RCC->APB2RSTR &= ~(RCC_APB2RSTR_SPI1RST)) +#define __HAL_RCC_USART1_RELEASE_RESET() (RCC->APB2RSTR &= ~(RCC_APB2RSTR_USART1RST)) +#define __HAL_RCC_TIM16_RELEASE_RESET() (RCC->APB2RSTR &= ~(RCC_APB2RSTR_TIM16RST)) +#define __HAL_RCC_TIM17_RELEASE_RESET() (RCC->APB2RSTR &= ~(RCC_APB2RSTR_TIM17RST)) +#define __HAL_RCC_DBGMCU_RELEASE_RESET() (RCC->APB2RSTR &= ~(RCC_APB2RSTR_DBGMCURST)) +/** + * @} + */ +/** @defgroup RCC_HSI_Configuration HSI Configuration + * @{ + */ + +/** @brief Macros to enable or disable the Internal High Speed oscillator (HSI). + * @note The HSI is stopped by hardware when entering STOP and STANDBY modes. + * @note HSI can not be stopped if it is used as system clock source. In this case, + * you have to select another source of the system clock then stop the HSI. + * @note After enabling the HSI, the application software should wait on HSIRDY + * flag to be set indicating that HSI clock is stable and can be used as + * system clock source. + * @note When the HSI is stopped, HSIRDY flag goes low after 6 HSI oscillator + * clock cycles. + */ +#define __HAL_RCC_HSI_ENABLE() SET_BIT(RCC->CR, RCC_CR_HSION) +#define __HAL_RCC_HSI_DISABLE() CLEAR_BIT(RCC->CR, RCC_CR_HSION) + +/** @brief Macro to adjust the Internal High Speed oscillator (HSI) calibration value. + * @note The calibration is used to compensate for the variations in voltage + * and temperature that influence the frequency of the internal HSI RC. + * @param _HSICALIBRATIONVALUE_ specifies the calibration trimming value. + * (default is RCC_HSICALIBRATION_DEFAULT). + * This parameter must be a number between 0 and 0x1F. + */ +#define __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(_HSICALIBRATIONVALUE_) \ + MODIFY_REG(RCC->CR, RCC_CR_HSITRIM, (uint32_t)(_HSICALIBRATIONVALUE_) << RCC_CR_HSITRIM_BitNumber) + +/** + * @} + */ + +/** @defgroup RCC_LSI_Configuration LSI Configuration + * @{ + */ + +/** @brief Macro to enable the Internal Low Speed oscillator (LSI). + * @note After enabling the LSI, the application software should wait on + * LSIRDY flag to be set indicating that LSI clock is stable and can + * be used to clock the IWDG and/or the RTC. + */ +#define __HAL_RCC_LSI_ENABLE() SET_BIT(RCC->CSR, RCC_CSR_LSION) + +/** @brief Macro to disable the Internal Low Speed oscillator (LSI). + * @note LSI can not be disabled if the IWDG is running. + * @note When the LSI is stopped, LSIRDY flag goes low after 6 LSI oscillator + * clock cycles. + */ +#define __HAL_RCC_LSI_DISABLE() CLEAR_BIT(RCC->CSR, RCC_CSR_LSION) + +/** + * @} + */ + +/** @defgroup RCC_HSE_Configuration HSE Configuration + * @{ + */ + +/** + * @brief Macro to configure the External High Speed oscillator (HSE). + * @note Transition HSE Bypass to HSE On and HSE On to HSE Bypass are not + * supported by this macro. User should request a transition to HSE Off + * first and then HSE On or HSE Bypass. + * @note After enabling the HSE (RCC_HSE_ON or RCC_HSE_Bypass), the application + * software should wait on HSERDY flag to be set indicating that HSE clock + * is stable and can be used to clock the PLL and/or system clock. + * @note HSE state can not be changed if it is used directly or through the + * PLL as system clock. In this case, you have to select another source + * of the system clock then change the HSE state (ex. disable it). + * @note The HSE is stopped by hardware when entering STOP and STANDBY modes. + * @note This function reset the CSSON bit, so if the clock security system(CSS) + * was previously enabled you have to enable it again after calling this + * function. + * @param __STATE__ specifies the new state of the HSE. + * This parameter can be one of the following values: + * @arg @ref RCC_HSE_OFF turn OFF the HSE oscillator, HSERDY flag goes low after + * 6 HSE oscillator clock cycles. + * @arg @ref RCC_HSE_ON turn ON the HSE oscillator + * @arg @ref RCC_HSE_BYPASS HSE oscillator bypassed with external clock + */ +#define __HAL_RCC_HSE_CONFIG(__STATE__) \ + do{ \ + if ((__STATE__) == RCC_HSE_ON) \ + { \ + SET_BIT(RCC->CR, RCC_CR_HSEON); \ + } \ + else if ((__STATE__) == RCC_HSE_OFF) \ + { \ + CLEAR_BIT(RCC->CR, RCC_CR_HSEON); \ + CLEAR_BIT(RCC->CR, RCC_CR_HSEBYP); \ + } \ + else if ((__STATE__) == RCC_HSE_BYPASS) \ + { \ + SET_BIT(RCC->CR, RCC_CR_HSEBYP); \ + SET_BIT(RCC->CR, RCC_CR_HSEON); \ + } \ + else \ + { \ + CLEAR_BIT(RCC->CR, RCC_CR_HSEON); \ + CLEAR_BIT(RCC->CR, RCC_CR_HSEBYP); \ + } \ + }while(0U) + +/** + * @brief Macro to configure the External High Speed oscillator (HSE) Predivision factor for PLL. + * @note Predivision factor can not be changed if PLL is used as system clock + * In this case, you have to select another source of the system clock, disable the PLL and + * then change the HSE predivision factor. + * @param __HSE_PREDIV_VALUE__ specifies the division value applied to HSE. + * This parameter must be a number between RCC_HSE_PREDIV_DIV1 and RCC_HSE_PREDIV_DIV16. + */ +#define __HAL_RCC_HSE_PREDIV_CONFIG(__HSE_PREDIV_VALUE__) \ + MODIFY_REG(RCC->CFGR2, RCC_CFGR2_PREDIV, (uint32_t)(__HSE_PREDIV_VALUE__)) + +/** + * @} + */ + +/** @defgroup RCC_LSE_Configuration LSE Configuration + * @{ + */ + +/** + * @brief Macro to configure the External Low Speed oscillator (LSE). + * @note Transitions LSE Bypass to LSE On and LSE On to LSE Bypass are not supported by this macro. + * @note As the LSE is in the Backup domain and write access is denied to + * this domain after reset, you have to enable write access using + * @ref HAL_PWR_EnableBkUpAccess() function before to configure the LSE + * (to be done once after reset). + * @note After enabling the LSE (RCC_LSE_ON or RCC_LSE_BYPASS), the application + * software should wait on LSERDY flag to be set indicating that LSE clock + * is stable and can be used to clock the RTC. + * @param __STATE__ specifies the new state of the LSE. + * This parameter can be one of the following values: + * @arg @ref RCC_LSE_OFF turn OFF the LSE oscillator, LSERDY flag goes low after + * 6 LSE oscillator clock cycles. + * @arg @ref RCC_LSE_ON turn ON the LSE oscillator. + * @arg @ref RCC_LSE_BYPASS LSE oscillator bypassed with external clock. + */ +#define __HAL_RCC_LSE_CONFIG(__STATE__) \ + do{ \ + if ((__STATE__) == RCC_LSE_ON) \ + { \ + SET_BIT(RCC->BDCR, RCC_BDCR_LSEON); \ + } \ + else if ((__STATE__) == RCC_LSE_OFF) \ + { \ + CLEAR_BIT(RCC->BDCR, RCC_BDCR_LSEON); \ + CLEAR_BIT(RCC->BDCR, RCC_BDCR_LSEBYP); \ + } \ + else if ((__STATE__) == RCC_LSE_BYPASS) \ + { \ + SET_BIT(RCC->BDCR, RCC_BDCR_LSEBYP); \ + SET_BIT(RCC->BDCR, RCC_BDCR_LSEON); \ + } \ + else \ + { \ + CLEAR_BIT(RCC->BDCR, RCC_BDCR_LSEON); \ + CLEAR_BIT(RCC->BDCR, RCC_BDCR_LSEBYP); \ + } \ + }while(0U) + +/** + * @} + */ + +/** @defgroup RCC_HSI14_Configuration RCC_HSI14_Configuration + * @{ + */ + +/** @brief Macro to enable the Internal 14Mhz High Speed oscillator (HSI14). + * @note After enabling the HSI14 with @ref __HAL_RCC_HSI14_ENABLE(), the application software + * should wait on HSI14RDY flag to be set indicating that HSI clock is stable and can be + * used as system clock source. This is not necessary if @ref HAL_RCC_OscConfig() is used. + * clock cycles. + */ +#define __HAL_RCC_HSI14_ENABLE() SET_BIT(RCC->CR2, RCC_CR2_HSI14ON) + +/** @brief Macro to disable the Internal 14Mhz High Speed oscillator (HSI14). + * @note The HSI14 is stopped by hardware when entering STOP and STANDBY modes. + * @note HSI14 can not be stopped if it is used as system clock source. In this case, + * you have to select another source of the system clock then stop the HSI14. + * @note When the HSI14 is stopped, HSI14RDY flag goes low after 6 HSI14 oscillator + * clock cycles. + */ +#define __HAL_RCC_HSI14_DISABLE() CLEAR_BIT(RCC->CR2, RCC_CR2_HSI14ON) + +/** @brief Macro to enable the Internal 14Mhz High Speed oscillator (HSI14) used by ADC. + */ +#define __HAL_RCC_HSI14ADC_ENABLE() CLEAR_BIT(RCC->CR2, RCC_CR2_HSI14DIS) + +/** @brief Macro to disable the Internal 14Mhz High Speed oscillator (HSI14) used by ADC. + */ +#define __HAL_RCC_HSI14ADC_DISABLE() SET_BIT(RCC->CR2, RCC_CR2_HSI14DIS) + +/** @brief Macro to adjust the Internal 14Mhz High Speed oscillator (HSI) calibration value. + * @note The calibration is used to compensate for the variations in voltage + * and temperature that influence the frequency of the internal HSI14 RC. + * @param __HSI14CALIBRATIONVALUE__ specifies the calibration trimming value + * (default is RCC_HSI14CALIBRATION_DEFAULT). + * This parameter must be a number between 0 and 0x1F. + */ +#define __HAL_RCC_HSI14_CALIBRATIONVALUE_ADJUST(__HSI14CALIBRATIONVALUE__) \ + MODIFY_REG(RCC->CR2, RCC_CR2_HSI14TRIM, (uint32_t)(__HSI14CALIBRATIONVALUE__) << RCC_HSI14TRIM_BIT_NUMBER) +/** + * @} + */ + +/** @defgroup RCC_USARTx_Clock_Config RCC USARTx Clock Config + * @{ + */ + +/** @brief Macro to configure the USART1 clock (USART1CLK). + * @param __USART1CLKSOURCE__ specifies the USART1 clock source. + * This parameter can be one of the following values: + * @arg @ref RCC_USART1CLKSOURCE_PCLK1 PCLK1 selected as USART1 clock + * @arg @ref RCC_USART1CLKSOURCE_HSI HSI selected as USART1 clock + * @arg @ref RCC_USART1CLKSOURCE_SYSCLK System Clock selected as USART1 clock + * @arg @ref RCC_USART1CLKSOURCE_LSE LSE selected as USART1 clock + */ +#define __HAL_RCC_USART1_CONFIG(__USART1CLKSOURCE__) \ + MODIFY_REG(RCC->CFGR3, RCC_CFGR3_USART1SW, (uint32_t)(__USART1CLKSOURCE__)) + +/** @brief Macro to get the USART1 clock source. + * @retval The clock source can be one of the following values: + * @arg @ref RCC_USART1CLKSOURCE_PCLK1 PCLK1 selected as USART1 clock + * @arg @ref RCC_USART1CLKSOURCE_HSI HSI selected as USART1 clock + * @arg @ref RCC_USART1CLKSOURCE_SYSCLK System Clock selected as USART1 clock + * @arg @ref RCC_USART1CLKSOURCE_LSE LSE selected as USART1 clock + */ +#define __HAL_RCC_GET_USART1_SOURCE() ((uint32_t)(READ_BIT(RCC->CFGR3, RCC_CFGR3_USART1SW))) + +/** + * @} + */ + +/** @defgroup RCC_I2Cx_Clock_Config RCC I2Cx Clock Config + * @{ + */ + +/** @brief Macro to configure the I2C1 clock (I2C1CLK). + * @param __I2C1CLKSOURCE__ specifies the I2C1 clock source. + * This parameter can be one of the following values: + * @arg @ref RCC_I2C1CLKSOURCE_HSI HSI selected as I2C1 clock + * @arg @ref RCC_I2C1CLKSOURCE_SYSCLK System Clock selected as I2C1 clock + */ +#define __HAL_RCC_I2C1_CONFIG(__I2C1CLKSOURCE__) \ + MODIFY_REG(RCC->CFGR3, RCC_CFGR3_I2C1SW, (uint32_t)(__I2C1CLKSOURCE__)) + +/** @brief Macro to get the I2C1 clock source. + * @retval The clock source can be one of the following values: + * @arg @ref RCC_I2C1CLKSOURCE_HSI HSI selected as I2C1 clock + * @arg @ref RCC_I2C1CLKSOURCE_SYSCLK System Clock selected as I2C1 clock + */ +#define __HAL_RCC_GET_I2C1_SOURCE() ((uint32_t)(READ_BIT(RCC->CFGR3, RCC_CFGR3_I2C1SW))) +/** + * @} + */ + +/** @defgroup RCC_PLL_Configuration PLL Configuration + * @{ + */ + +/** @brief Macro to enable the main PLL. + * @note After enabling the main PLL, the application software should wait on + * PLLRDY flag to be set indicating that PLL clock is stable and can + * be used as system clock source. + * @note The main PLL is disabled by hardware when entering STOP and STANDBY modes. + */ +#define __HAL_RCC_PLL_ENABLE() SET_BIT(RCC->CR, RCC_CR_PLLON) + +/** @brief Macro to disable the main PLL. + * @note The main PLL can not be disabled if it is used as system clock source + */ +#define __HAL_RCC_PLL_DISABLE() CLEAR_BIT(RCC->CR, RCC_CR_PLLON) + +/** @brief Macro to configure the PLL clock source, multiplication and division factors. + * @note This function must be used only when the main PLL is disabled. + * + * @param __RCC_PLLSOURCE__ specifies the PLL entry clock source. + * This parameter can be one of the following values: + * @arg @ref RCC_PLLSOURCE_HSI HSI oscillator clock selected as PLL clock entry + * @arg @ref RCC_PLLSOURCE_HSE HSE oscillator clock selected as PLL clock entry + * @param __PLLMUL__ specifies the multiplication factor for PLL VCO output clock + * This parameter can be one of the following values: + * This parameter must be a number between RCC_PLL_MUL2 and RCC_PLL_MUL16. + * @param __PREDIV__ specifies the predivider factor for PLL VCO input clock + * This parameter must be a number between RCC_PREDIV_DIV1 and RCC_PREDIV_DIV16. + * + */ +#define __HAL_RCC_PLL_CONFIG(__RCC_PLLSOURCE__ , __PREDIV__, __PLLMUL__) \ + do { \ + MODIFY_REG(RCC->CFGR2, RCC_CFGR2_PREDIV, (__PREDIV__)); \ + MODIFY_REG(RCC->CFGR, RCC_CFGR_PLLMUL | RCC_CFGR_PLLSRC, (uint32_t)((__PLLMUL__)|(__RCC_PLLSOURCE__))); \ + } while(0U) + + +/** @brief Get oscillator clock selected as PLL input clock + * @retval The clock source used for PLL entry. The returned value can be one + * of the following: + * @arg @ref RCC_PLLSOURCE_HSE HSE oscillator clock selected as PLL input clock + */ +#define __HAL_RCC_GET_PLL_OSCSOURCE() ((uint32_t)(READ_BIT(RCC->CFGR, RCC_CFGR_PLLSRC))) + +/** + * @} + */ + +/** @defgroup RCC_Get_Clock_source Get Clock source + * @{ + */ + +/** + * @brief Macro to configure the system clock source. + * @param __SYSCLKSOURCE__ specifies the system clock source. + * This parameter can be one of the following values: + * @arg @ref RCC_SYSCLKSOURCE_HSI HSI oscillator is used as system clock source. + * @arg @ref RCC_SYSCLKSOURCE_HSE HSE oscillator is used as system clock source. + * @arg @ref RCC_SYSCLKSOURCE_PLLCLK PLL output is used as system clock source. + */ +#define __HAL_RCC_SYSCLK_CONFIG(__SYSCLKSOURCE__) \ + MODIFY_REG(RCC->CFGR, RCC_CFGR_SW, (__SYSCLKSOURCE__)) + +/** @brief Macro to get the clock source used as system clock. + * @retval The clock source used as system clock. The returned value can be one + * of the following: + * @arg @ref RCC_SYSCLKSOURCE_STATUS_HSI HSI used as system clock + * @arg @ref RCC_SYSCLKSOURCE_STATUS_HSE HSE used as system clock + * @arg @ref RCC_SYSCLKSOURCE_STATUS_PLLCLK PLL used as system clock + */ +#define __HAL_RCC_GET_SYSCLK_SOURCE() ((uint32_t)(RCC->CFGR & RCC_CFGR_SWS)) + +/** + * @} + */ + +/** @defgroup RCCEx_MCOx_Clock_Config RCC Extended MCOx Clock Config + * @{ + */ + +#if defined(RCC_CFGR_MCOPRE) +/** @brief Macro to configure the MCO clock. + * @param __MCOCLKSOURCE__ specifies the MCO clock source. + * This parameter can be one of the following values: + * @arg @ref RCC_MCO1SOURCE_NOCLOCK No clock selected as MCO clock + * @arg @ref RCC_MCO1SOURCE_SYSCLK System Clock selected as MCO clock + * @arg @ref RCC_MCO1SOURCE_HSI HSI oscillator clock selected as MCO clock + * @arg @ref RCC_MCO1SOURCE_HSE HSE selected as MCO clock + * @arg @ref RCC_MCO1SOURCE_LSI LSI selected as MCO clock + * @arg @ref RCC_MCO1SOURCE_LSE LSE selected as MCO clock + * @arg @ref RCC_MCO1SOURCE_HSI14 HSI14 selected as MCO clock + @if STM32F042x6 + * @arg @ref RCC_MCO1SOURCE_HSI48 HSI48 selected as MCO clock + * @arg @ref RCC_MCO1SOURCE_PLLCLK PLLCLK selected as MCO clock + @elseif STM32F048xx + * @arg @ref RCC_MCO1SOURCE_HSI48 HSI48 selected as MCO clock + * @arg @ref RCC_MCO1SOURCE_PLLCLK PLLCLK selected as MCO clock + @elseif STM32F071xB + * @arg @ref RCC_MCO1SOURCE_HSI48 HSI48 selected as MCO clock + * @arg @ref RCC_MCO1SOURCE_PLLCLK PLLCLK selected as MCO clock + @elseif STM32F072xB + * @arg @ref RCC_MCO1SOURCE_HSI48 HSI48 selected as MCO clock + * @arg @ref RCC_MCO1SOURCE_PLLCLK PLLCLK selected as MCO clock + @elseif STM32F078xx + * @arg @ref RCC_MCO1SOURCE_HSI48 HSI48 selected as MCO clock + * @arg @ref RCC_MCO1SOURCE_PLLCLK PLLCLK selected as MCO clock + @elseif STM32F091xC + * @arg @ref RCC_MCO1SOURCE_HSI48 HSI48 selected as MCO clock + * @arg @ref RCC_MCO1SOURCE_PLLCLK PLLCLK selected as MCO clock + @elseif STM32F098xx + * @arg @ref RCC_MCO1SOURCE_HSI48 HSI48 selected as MCO clock + * @arg @ref RCC_MCO1SOURCE_PLLCLK PLLCLK selected as MCO clock + @elseif STM32F030x6 + * @arg @ref RCC_MCO1SOURCE_PLLCLK PLLCLK selected as MCO clock + @elseif STM32F030xC + * @arg @ref RCC_MCO1SOURCE_PLLCLK PLLCLK selected as MCO clock + @elseif STM32F031x6 + * @arg @ref RCC_MCO1SOURCE_PLLCLK PLLCLK selected as MCO clock + @elseif STM32F038xx + * @arg @ref RCC_MCO1SOURCE_PLLCLK PLLCLK selected as MCO clock + @elseif STM32F070x6 + * @arg @ref RCC_MCO1SOURCE_PLLCLK PLLCLK selected as MCO clock + @elseif STM32F070xB + * @arg @ref RCC_MCO1SOURCE_PLLCLK PLLCLK selected as MCO clock + @endif + * @arg @ref RCC_MCO1SOURCE_PLLCLK_DIV2 PLLCLK Divided by 2 selected as MCO clock + * @param __MCODIV__ specifies the MCO clock prescaler. + * This parameter can be one of the following values: + * @arg @ref RCC_MCODIV_1 MCO clock source is divided by 1 + * @arg @ref RCC_MCODIV_2 MCO clock source is divided by 2 + * @arg @ref RCC_MCODIV_4 MCO clock source is divided by 4 + * @arg @ref RCC_MCODIV_8 MCO clock source is divided by 8 + * @arg @ref RCC_MCODIV_16 MCO clock source is divided by 16 + * @arg @ref RCC_MCODIV_32 MCO clock source is divided by 32 + * @arg @ref RCC_MCODIV_64 MCO clock source is divided by 64 + * @arg @ref RCC_MCODIV_128 MCO clock source is divided by 128 + */ +#else +/** @brief Macro to configure the MCO clock. + * @param __MCOCLKSOURCE__ specifies the MCO clock source. + * This parameter can be one of the following values: + * @arg @ref RCC_MCO1SOURCE_NOCLOCK No clock selected as MCO clock + * @arg @ref RCC_MCO1SOURCE_SYSCLK System Clock selected as MCO clock + * @arg @ref RCC_MCO1SOURCE_HSI HSI selected as MCO clock + * @arg @ref RCC_MCO1SOURCE_HSE HSE selected as MCO clock + * @arg @ref RCC_MCO1SOURCE_LSI LSI selected as MCO clock + * @arg @ref RCC_MCO1SOURCE_LSE LSE selected as MCO clock + * @arg @ref RCC_MCO1SOURCE_HSI14 HSI14 selected as MCO clock + * @arg @ref RCC_MCO1SOURCE_PLLCLK_DIV2 PLLCLK Divided by 2 selected as MCO clock + * @param __MCODIV__ specifies the MCO clock prescaler. + * This parameter can be one of the following values: + * @arg @ref RCC_MCODIV_1 No division applied on MCO clock source + */ +#endif +#if defined(RCC_CFGR_MCOPRE) +#define __HAL_RCC_MCO1_CONFIG(__MCOCLKSOURCE__, __MCODIV__) \ + MODIFY_REG(RCC->CFGR, (RCC_CFGR_MCO | RCC_CFGR_MCOPRE), ((__MCOCLKSOURCE__) | (__MCODIV__))) +#else + +#define __HAL_RCC_MCO1_CONFIG(__MCOCLKSOURCE__, __MCODIV__) \ + MODIFY_REG(RCC->CFGR, RCC_CFGR_MCO, (__MCOCLKSOURCE__)) + +#endif + +/** + * @} + */ + + /** @defgroup RCC_RTC_Clock_Configuration RCC RTC Clock Configuration + * @{ + */ + +/** @brief Macro to configure the RTC clock (RTCCLK). + * @note As the RTC clock configuration bits are in the Backup domain and write + * access is denied to this domain after reset, you have to enable write + * access using the Power Backup Access macro before to configure + * the RTC clock source (to be done once after reset). + * @note Once the RTC clock is configured it cannot be changed unless the + * Backup domain is reset using @ref __HAL_RCC_BACKUPRESET_FORCE() macro, or by + * a Power On Reset (POR). + * + * @param __RTC_CLKSOURCE__ specifies the RTC clock source. + * This parameter can be one of the following values: + * @arg @ref RCC_RTCCLKSOURCE_NO_CLK No clock selected as RTC clock + * @arg @ref RCC_RTCCLKSOURCE_LSE LSE selected as RTC clock + * @arg @ref RCC_RTCCLKSOURCE_LSI LSI selected as RTC clock + * @arg @ref RCC_RTCCLKSOURCE_HSE_DIV32 HSE clock divided by 32 + * @note If the LSE or LSI is used as RTC clock source, the RTC continues to + * work in STOP and STANDBY modes, and can be used as wakeup source. + * However, when the LSI clock and HSE clock divided by 32 is used as RTC clock source, + * the RTC cannot be used in STOP and STANDBY modes. + * @note The system must always be configured so as to get a PCLK frequency greater than or + * equal to the RTCCLK frequency for a proper operation of the RTC. + */ +#define __HAL_RCC_RTC_CONFIG(__RTC_CLKSOURCE__) MODIFY_REG(RCC->BDCR, RCC_BDCR_RTCSEL, (__RTC_CLKSOURCE__)) + +/** @brief Macro to get the RTC clock source. + * @retval The clock source can be one of the following values: + * @arg @ref RCC_RTCCLKSOURCE_NO_CLK No clock selected as RTC clock + * @arg @ref RCC_RTCCLKSOURCE_LSE LSE selected as RTC clock + * @arg @ref RCC_RTCCLKSOURCE_LSI LSI selected as RTC clock + * @arg @ref RCC_RTCCLKSOURCE_HSE_DIV32 HSE clock divided by 32 + */ +#define __HAL_RCC_GET_RTC_SOURCE() (READ_BIT(RCC->BDCR, RCC_BDCR_RTCSEL)) + +/** @brief Macro to enable the the RTC clock. + * @note These macros must be used only after the RTC clock source was selected. + */ +#define __HAL_RCC_RTC_ENABLE() SET_BIT(RCC->BDCR, RCC_BDCR_RTCEN) + +/** @brief Macro to disable the the RTC clock. + * @note These macros must be used only after the RTC clock source was selected. + */ +#define __HAL_RCC_RTC_DISABLE() CLEAR_BIT(RCC->BDCR, RCC_BDCR_RTCEN) + +/** @brief Macro to force the Backup domain reset. + * @note This function resets the RTC peripheral (including the backup registers) + * and the RTC clock source selection in RCC_BDCR register. + */ +#define __HAL_RCC_BACKUPRESET_FORCE() SET_BIT(RCC->BDCR, RCC_BDCR_BDRST) + +/** @brief Macros to release the Backup domain reset. + */ +#define __HAL_RCC_BACKUPRESET_RELEASE() CLEAR_BIT(RCC->BDCR, RCC_BDCR_BDRST) + +/** + * @} + */ + +/** @defgroup RCC_Flags_Interrupts_Management Flags Interrupts Management + * @brief macros to manage the specified RCC Flags and interrupts. + * @{ + */ + +/** @brief Enable RCC interrupt. + * @param __INTERRUPT__ specifies the RCC interrupt sources to be enabled. + * This parameter can be any combination of the following values: + * @arg @ref RCC_IT_LSIRDY LSI ready interrupt + * @arg @ref RCC_IT_LSERDY LSE ready interrupt + * @arg @ref RCC_IT_HSIRDY HSI ready interrupt + * @arg @ref RCC_IT_HSERDY HSE ready interrupt + * @arg @ref RCC_IT_PLLRDY main PLL ready interrupt + * @arg @ref RCC_IT_HSI14RDY HSI14 ready interrupt + @if STM32F042x6 + * @arg @ref RCC_IT_HSI48RDY HSI48 ready interrupt + @elseif STM32F048xx + * @arg @ref RCC_IT_HSI48RDY HSI48 ready interrupt + @elseif STM32F071xB + * @arg @ref RCC_IT_HSI48RDY HSI48 ready interrupt + @elseif STM32F072xB + * @arg @ref RCC_IT_HSI48RDY HSI48 ready interrupt + @elseif STM32F078xx + * @arg @ref RCC_IT_HSI48RDY HSI48 ready interrupt + @elseif STM32F091xC + * @arg @ref RCC_IT_HSI48RDY HSI48 ready interrupt + @elseif STM32F098xx + * @arg @ref RCC_IT_HSI48RDY HSI48 ready interrupt + @endif + */ +#define __HAL_RCC_ENABLE_IT(__INTERRUPT__) (*(__IO uint8_t *) RCC_CIR_BYTE1_ADDRESS |= (__INTERRUPT__)) + +/** @brief Disable RCC interrupt. + * @param __INTERRUPT__ specifies the RCC interrupt sources to be disabled. + * This parameter can be any combination of the following values: + * @arg @ref RCC_IT_LSIRDY LSI ready interrupt + * @arg @ref RCC_IT_LSERDY LSE ready interrupt + * @arg @ref RCC_IT_HSIRDY HSI ready interrupt + * @arg @ref RCC_IT_HSERDY HSE ready interrupt + * @arg @ref RCC_IT_PLLRDY main PLL ready interrupt + * @arg @ref RCC_IT_HSI14RDY HSI14 ready interrupt + @if STM32F042x6 + * @arg @ref RCC_IT_HSI48RDY HSI48 ready interrupt + @elseif STM32F048xx + * @arg @ref RCC_IT_HSI48RDY HSI48 ready interrupt + @elseif STM32F071xB + * @arg @ref RCC_IT_HSI48RDY HSI48 ready interrupt + @elseif STM32F072xB + * @arg @ref RCC_IT_HSI48RDY HSI48 ready interrupt + @elseif STM32F078xx + * @arg @ref RCC_IT_HSI48RDY HSI48 ready interrupt + @elseif STM32F091xC + * @arg @ref RCC_IT_HSI48RDY HSI48 ready interrupt + @elseif STM32F098xx + * @arg @ref RCC_IT_HSI48RDY HSI48 ready interrupt + @endif + */ +#define __HAL_RCC_DISABLE_IT(__INTERRUPT__) (*(__IO uint8_t *) RCC_CIR_BYTE1_ADDRESS &= (uint8_t)(~(__INTERRUPT__))) + +/** @brief Clear the RCC's interrupt pending bits. + * @param __INTERRUPT__ specifies the interrupt pending bit to clear. + * This parameter can be any combination of the following values: + * @arg @ref RCC_IT_LSIRDY LSI ready interrupt. + * @arg @ref RCC_IT_LSERDY LSE ready interrupt. + * @arg @ref RCC_IT_HSIRDY HSI ready interrupt. + * @arg @ref RCC_IT_HSERDY HSE ready interrupt. + * @arg @ref RCC_IT_PLLRDY Main PLL ready interrupt. + * @arg @ref RCC_IT_CSS Clock Security System interrupt + * @arg @ref RCC_IT_HSI14RDY HSI14 ready interrupt + @if STM32F042x6 + * @arg @ref RCC_IT_HSI48RDY HSI48 ready interrupt + @elseif STM32F048xx + * @arg @ref RCC_IT_HSI48RDY HSI48 ready interrupt + @elseif STM32F071xB + * @arg @ref RCC_IT_HSI48RDY HSI48 ready interrupt + @elseif STM32F072xB + * @arg @ref RCC_IT_HSI48RDY HSI48 ready interrupt + @elseif STM32F078xx + * @arg @ref RCC_IT_HSI48RDY HSI48 ready interrupt + @elseif STM32F091xC + * @arg @ref RCC_IT_HSI48RDY HSI48 ready interrupt + @elseif STM32F098xx + * @arg @ref RCC_IT_HSI48RDY HSI48 ready interrupt + @endif + */ +#define __HAL_RCC_CLEAR_IT(__INTERRUPT__) (*(__IO uint8_t *) RCC_CIR_BYTE2_ADDRESS = (__INTERRUPT__)) + +/** @brief Check the RCC's interrupt has occurred or not. + * @param __INTERRUPT__ specifies the RCC interrupt source to check. + * This parameter can be one of the following values: + * @arg @ref RCC_IT_LSIRDY LSI ready interrupt. + * @arg @ref RCC_IT_LSERDY LSE ready interrupt. + * @arg @ref RCC_IT_HSIRDY HSI ready interrupt. + * @arg @ref RCC_IT_HSERDY HSE ready interrupt. + * @arg @ref RCC_IT_PLLRDY Main PLL ready interrupt. + * @arg @ref RCC_IT_CSS Clock Security System interrupt + * @arg @ref RCC_IT_HSI14RDY HSI14 ready interrupt enable + @if STM32F042x6 + * @arg @ref RCC_IT_HSI48RDY HSI48 ready interrupt + @elseif STM32F048xx + * @arg @ref RCC_IT_HSI48RDY HSI48 ready interrupt + @elseif STM32F071xB + * @arg @ref RCC_IT_HSI48RDY HSI48 ready interrupt + @elseif STM32F072xB + * @arg @ref RCC_IT_HSI48RDY HSI48 ready interrupt + @elseif STM32F078xx + * @arg @ref RCC_IT_HSI48RDY HSI48 ready interrupt + @elseif STM32F091xC + * @arg @ref RCC_IT_HSI48RDY HSI48 ready interrupt + @elseif STM32F098xx + * @arg @ref RCC_IT_HSI48RDY HSI48 ready interrupt + @endif + * @retval The new state of __INTERRUPT__ (TRUE or FALSE). + */ +#define __HAL_RCC_GET_IT(__INTERRUPT__) ((RCC->CIR & (__INTERRUPT__)) == (__INTERRUPT__)) + +/** @brief Set RMVF bit to clear the reset flags. + * The reset flags are RCC_FLAG_PINRST, RCC_FLAG_PORRST, RCC_FLAG_SFTRST, + * RCC_FLAG_OBLRST, RCC_FLAG_IWDGRST, RCC_FLAG_WWDGRST, RCC_FLAG_LPWRRST + */ +#define __HAL_RCC_CLEAR_RESET_FLAGS() (RCC->CSR |= RCC_CSR_RMVF) + +/** @brief Check RCC flag is set or not. + * @param __FLAG__ specifies the flag to check. + * This parameter can be one of the following values: + * @arg @ref RCC_FLAG_HSIRDY HSI oscillator clock ready. + * @arg @ref RCC_FLAG_HSERDY HSE oscillator clock ready. + * @arg @ref RCC_FLAG_PLLRDY Main PLL clock ready. + * @arg @ref RCC_FLAG_HSI14RDY HSI14 oscillator clock ready + @if STM32F038xx + * @arg @ref RCC_FLAG_V18PWRRST Reset flag of the 1.8 V domain + @elseif STM32F042x6 + * @arg @ref RCC_FLAG_HSI48RDY HSI48 oscillator clock ready + @elseif STM32F048xx + * @arg @ref RCC_FLAG_HSI48RDY HSI48 oscillator clock ready + * @arg @ref RCC_FLAG_V18PWRRST Reset flag of the 1.8 V domain + @elseif STM32F058xx + * @arg @ref RCC_FLAG_V18PWRRST Reset flag of the 1.8 V domain + @elseif STM32F071xB + * @arg @ref RCC_FLAG_HSI48RDY HSI48 oscillator clock ready + @elseif STM32F072xB + * @arg @ref RCC_FLAG_HSI48RDY HSI48 oscillator clock ready + @elseif STM32F078xx + * @arg @ref RCC_FLAG_HSI48RDY HSI48 oscillator clock ready + * @arg @ref RCC_FLAG_V18PWRRST Reset flag of the 1.8 V domain + @elseif STM32F091xC + * @arg @ref RCC_FLAG_HSI48RDY HSI48 oscillator clock ready + @elseif STM32F098xx + * @arg @ref RCC_FLAG_HSI48RDY HSI48 oscillator clock ready + * @arg @ref RCC_FLAG_V18PWRRST Reset flag of the 1.8 V domain + @endif + * @arg @ref RCC_FLAG_LSERDY LSE oscillator clock ready. + * @arg @ref RCC_FLAG_LSIRDY LSI oscillator clock ready. + * @arg @ref RCC_FLAG_OBLRST Option Byte Load reset + * @arg @ref RCC_FLAG_PINRST Pin reset. + * @arg @ref RCC_FLAG_PORRST POR/PDR reset. + * @arg @ref RCC_FLAG_SFTRST Software reset. + * @arg @ref RCC_FLAG_IWDGRST Independent Watchdog reset. + * @arg @ref RCC_FLAG_WWDGRST Window Watchdog reset. + * @arg @ref RCC_FLAG_LPWRRST Low Power reset. + * @retval The new state of __FLAG__ (TRUE or FALSE). + */ +#define __HAL_RCC_GET_FLAG(__FLAG__) (((((__FLAG__) >> 5U) == CR_REG_INDEX)? RCC->CR : \ + (((__FLAG__) >> 5U) == CR2_REG_INDEX)? RCC->CR2 : \ + (((__FLAG__) >> 5U) == BDCR_REG_INDEX) ? RCC->BDCR : \ + RCC->CSR) & (1U << ((__FLAG__) & RCC_FLAG_MASK))) + +/** + * @} + */ + +/** + * @} + */ + +/* Include RCC HAL Extension module */ +#include "stm32f0xx_hal_rcc_ex.h" + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup RCC_Exported_Functions + * @{ + */ + +/** @addtogroup RCC_Exported_Functions_Group1 + * @{ + */ + +/* Initialization and de-initialization functions ******************************/ +HAL_StatusTypeDef HAL_RCC_DeInit(void); +HAL_StatusTypeDef HAL_RCC_OscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct); +HAL_StatusTypeDef HAL_RCC_ClockConfig(RCC_ClkInitTypeDef *RCC_ClkInitStruct, uint32_t FLatency); + +/** + * @} + */ + +/** @addtogroup RCC_Exported_Functions_Group2 + * @{ + */ + +/* Peripheral Control functions ************************************************/ +void HAL_RCC_MCOConfig(uint32_t RCC_MCOx, uint32_t RCC_MCOSource, uint32_t RCC_MCODiv); +void HAL_RCC_EnableCSS(void); +/* CSS NMI IRQ handler */ +void HAL_RCC_NMI_IRQHandler(void); +/* User Callbacks in non blocking mode (IT mode) */ +void HAL_RCC_CSSCallback(void); +void HAL_RCC_DisableCSS(void); +uint32_t HAL_RCC_GetSysClockFreq(void); +uint32_t HAL_RCC_GetHCLKFreq(void); +uint32_t HAL_RCC_GetPCLK1Freq(void); +void HAL_RCC_GetOscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct); +void HAL_RCC_GetClockConfig(RCC_ClkInitTypeDef *RCC_ClkInitStruct, uint32_t *pFLatency); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F0xx_HAL_RCC_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ + diff --git a/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc_ex.h b/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc_ex.h new file mode 100644 index 0000000..0062222 --- /dev/null +++ b/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc_ex.h @@ -0,0 +1,2085 @@ +/** + ****************************************************************************** + * @file stm32f0xx_hal_rcc_ex.h + * @author MCD Application Team + * @brief Header file of RCC HAL Extension module. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2016 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F0xx_HAL_RCC_EX_H +#define __STM32F0xx_HAL_RCC_EX_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f0xx_hal_def.h" + +/** @addtogroup STM32F0xx_HAL_Driver + * @{ + */ + +/** @addtogroup RCC + * @{ + */ + +/** @addtogroup RCC_Private_Macros + * @{ + */ +#if defined(RCC_HSI48_SUPPORT) +#define IS_RCC_OSCILLATORTYPE(OSCILLATOR) (((OSCILLATOR) == RCC_OSCILLATORTYPE_NONE) || \ + (((OSCILLATOR) & RCC_OSCILLATORTYPE_HSE) == RCC_OSCILLATORTYPE_HSE) || \ + (((OSCILLATOR) & RCC_OSCILLATORTYPE_HSI) == RCC_OSCILLATORTYPE_HSI) || \ + (((OSCILLATOR) & RCC_OSCILLATORTYPE_LSI) == RCC_OSCILLATORTYPE_LSI) || \ + (((OSCILLATOR) & RCC_OSCILLATORTYPE_LSE) == RCC_OSCILLATORTYPE_LSE) || \ + (((OSCILLATOR) & RCC_OSCILLATORTYPE_HSI14) == RCC_OSCILLATORTYPE_HSI14) || \ + (((OSCILLATOR) & RCC_OSCILLATORTYPE_HSI48) == RCC_OSCILLATORTYPE_HSI48)) + +#define IS_RCC_SYSCLKSOURCE(SOURCE) (((SOURCE) == RCC_SYSCLKSOURCE_HSI) || \ + ((SOURCE) == RCC_SYSCLKSOURCE_HSE) || \ + ((SOURCE) == RCC_SYSCLKSOURCE_PLLCLK) || \ + ((SOURCE) == RCC_SYSCLKSOURCE_HSI48)) + +#define IS_RCC_SYSCLKSOURCE_STATUS(SOURCE) (((SOURCE) == RCC_SYSCLKSOURCE_STATUS_HSI) || \ + ((SOURCE) == RCC_SYSCLKSOURCE_STATUS_HSE) || \ + ((SOURCE) == RCC_SYSCLKSOURCE_STATUS_PLLCLK) || \ + ((SOURCE) == RCC_SYSCLKSOURCE_STATUS_HSI48)) + +#define IS_RCC_PLLSOURCE(SOURCE) (((SOURCE) == RCC_PLLSOURCE_HSI) || \ + ((SOURCE) == RCC_PLLSOURCE_HSI48) || \ + ((SOURCE) == RCC_PLLSOURCE_HSE)) + +#define IS_RCC_HSI48(HSI48) (((HSI48) == RCC_HSI48_OFF) || ((HSI48) == RCC_HSI48_ON)) + +#else + +#define IS_RCC_OSCILLATORTYPE(OSCILLATOR) (((OSCILLATOR) == RCC_OSCILLATORTYPE_NONE) || \ + (((OSCILLATOR) & RCC_OSCILLATORTYPE_HSE) == RCC_OSCILLATORTYPE_HSE) || \ + (((OSCILLATOR) & RCC_OSCILLATORTYPE_HSI) == RCC_OSCILLATORTYPE_HSI) || \ + (((OSCILLATOR) & RCC_OSCILLATORTYPE_LSI) == RCC_OSCILLATORTYPE_LSI) || \ + (((OSCILLATOR) & RCC_OSCILLATORTYPE_LSE) == RCC_OSCILLATORTYPE_LSE) || \ + (((OSCILLATOR) & RCC_OSCILLATORTYPE_HSI14) == RCC_OSCILLATORTYPE_HSI14)) +#define IS_RCC_SYSCLKSOURCE(SOURCE) (((SOURCE) == RCC_SYSCLKSOURCE_HSI) || \ + ((SOURCE) == RCC_SYSCLKSOURCE_HSE) || \ + ((SOURCE) == RCC_SYSCLKSOURCE_PLLCLK)) + +#define IS_RCC_SYSCLKSOURCE_STATUS(SOURCE) (((SOURCE) == RCC_SYSCLKSOURCE_STATUS_HSI) || \ + ((SOURCE) == RCC_SYSCLKSOURCE_STATUS_HSE) || \ + ((SOURCE) == RCC_SYSCLKSOURCE_STATUS_PLLCLK)) +#define IS_RCC_PLLSOURCE(SOURCE) (((SOURCE) == RCC_PLLSOURCE_HSI) || \ + ((SOURCE) == RCC_PLLSOURCE_HSE)) + +#endif /* RCC_HSI48_SUPPORT */ + +#if defined(RCC_CFGR_PLLNODIV) && !defined(RCC_CFGR_MCO_HSI48) + +#define IS_RCC_MCO1SOURCE(SOURCE) (((SOURCE) == RCC_MCO1SOURCE_NOCLOCK) || \ + ((SOURCE) == RCC_MCO1SOURCE_LSI) || \ + ((SOURCE) == RCC_MCO1SOURCE_LSE) || \ + ((SOURCE) == RCC_MCO1SOURCE_SYSCLK) || \ + ((SOURCE) == RCC_MCO1SOURCE_HSI) || \ + ((SOURCE) == RCC_MCO1SOURCE_HSE) || \ + ((SOURCE) == RCC_MCO1SOURCE_PLLCLK) || \ + ((SOURCE) == RCC_MCO1SOURCE_PLLCLK_DIV2) || \ + ((SOURCE) == RCC_MCO1SOURCE_HSI14)) + +#elif defined(RCC_CFGR_PLLNODIV) && defined(RCC_CFGR_MCO_HSI48) + +#define IS_RCC_MCO1SOURCE(SOURCE) (((SOURCE) == RCC_MCO1SOURCE_NOCLOCK) || \ + ((SOURCE) == RCC_MCO1SOURCE_LSI) || \ + ((SOURCE) == RCC_MCO1SOURCE_LSE) || \ + ((SOURCE) == RCC_MCO1SOURCE_SYSCLK) || \ + ((SOURCE) == RCC_MCO1SOURCE_HSI) || \ + ((SOURCE) == RCC_MCO1SOURCE_HSE) || \ + ((SOURCE) == RCC_MCO1SOURCE_PLLCLK) || \ + ((SOURCE) == RCC_MCO1SOURCE_PLLCLK_DIV2) || \ + ((SOURCE) == RCC_MCO1SOURCE_HSI14) || \ + ((SOURCE) == RCC_MCO1SOURCE_HSI48)) + +#elif !defined(RCC_CFGR_PLLNODIV) && !defined(RCC_CFGR_MCO_HSI48) + +#define IS_RCC_MCO1SOURCE(SOURCE) (((SOURCE) == RCC_MCO1SOURCE_NOCLOCK) || \ + ((SOURCE) == RCC_MCO1SOURCE_LSI) || \ + ((SOURCE) == RCC_MCO1SOURCE_LSE) || \ + ((SOURCE) == RCC_MCO1SOURCE_SYSCLK) || \ + ((SOURCE) == RCC_MCO1SOURCE_HSI) || \ + ((SOURCE) == RCC_MCO1SOURCE_HSE) || \ + ((SOURCE) == RCC_MCO1SOURCE_PLLCLK_DIV2) || \ + ((SOURCE) == RCC_MCO1SOURCE_HSI14)) + +#endif /* RCC_CFGR_PLLNODIV && !RCC_CFGR_MCO_HSI48 */ + +/** + * @} + */ + +/** @addtogroup RCC_Exported_Constants + * @{ + */ +#if defined(RCC_HSI48_SUPPORT) + +/** @addtogroup RCC_PLL_Clock_Source + * @{ + */ +#define RCC_PLLSOURCE_HSI RCC_CFGR_PLLSRC_HSI_PREDIV +#define RCC_PLLSOURCE_HSI48 RCC_CFGR_PLLSRC_HSI48_PREDIV + +/** + * @} + */ + +/** @addtogroup RCC_Interrupt + * @{ + */ +#define RCC_IT_HSI48 RCC_CIR_HSI48RDYF /*!< HSI48 Ready Interrupt flag */ +/** + * @} + */ + +/** @addtogroup RCC_Flag + * @{ + */ +#define RCC_FLAG_HSI48RDY ((uint8_t)((CR2_REG_INDEX << 5U) | RCC_CR2_HSI48RDY_BitNumber)) +/** + * @} + */ + +/** @addtogroup RCC_System_Clock_Source + * @{ + */ +#define RCC_SYSCLKSOURCE_HSI48 RCC_CFGR_SW_HSI48 +/** + * @} + */ + +/** @addtogroup RCC_System_Clock_Source_Status + * @{ + */ +#define RCC_SYSCLKSOURCE_STATUS_HSI48 RCC_CFGR_SWS_HSI48 +/** + * @} + */ + +#else +/** @addtogroup RCC_PLL_Clock_Source + * @{ + */ + +#if defined(STM32F070xB) || defined(STM32F070x6) || defined(STM32F030xC) +#define RCC_PLLSOURCE_HSI RCC_CFGR_PLLSRC_HSI_PREDIV +#else +#define RCC_PLLSOURCE_HSI RCC_CFGR_PLLSRC_HSI_DIV2 +#endif + +/** + * @} + */ + +#endif /* RCC_HSI48_SUPPORT */ + +/** @addtogroup RCC_MCO_Clock_Source + * @{ + */ + +#if defined(RCC_CFGR_PLLNODIV) + +#define RCC_MCO1SOURCE_PLLCLK (RCC_CFGR_MCO_PLL | RCC_CFGR_PLLNODIV) + +#endif /* RCC_CFGR_PLLNODIV */ + +#if defined(RCC_CFGR_MCO_HSI48) + +#define RCC_MCO1SOURCE_HSI48 RCC_CFGR_MCO_HSI48 + +#endif /* SRCC_CFGR_MCO_HSI48 */ +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** @addtogroup RCCEx + * @{ + */ + +/* Private Constants -------------------------------------------------------------*/ +#if defined(CRS) +/** @addtogroup RCCEx_Private_Constants + * @{ + */ + +/* CRS IT Error Mask */ +#define RCC_CRS_IT_ERROR_MASK ((uint32_t)(RCC_CRS_IT_TRIMOVF | RCC_CRS_IT_SYNCERR | RCC_CRS_IT_SYNCMISS)) + +/* CRS Flag Error Mask */ +#define RCC_CRS_FLAG_ERROR_MASK ((uint32_t)(RCC_CRS_FLAG_TRIMOVF | RCC_CRS_FLAG_SYNCERR | RCC_CRS_FLAG_SYNCMISS)) + +/** + * @} + */ +#endif /* CRS */ + +/* Private macro -------------------------------------------------------------*/ +/** @defgroup RCCEx_Private_Macros RCCEx Private Macros + * @{ + */ +#if defined(STM32F030x6) || defined(STM32F030x8) || defined(STM32F031x6) || defined(STM32F038xx)\ + || defined(STM32F030xC) + +#define IS_RCC_PERIPHCLOCK(SELECTION) ((SELECTION) <= (RCC_PERIPHCLK_USART1 | RCC_PERIPHCLK_I2C1 | \ + RCC_PERIPHCLK_RTC)) +#endif /* STM32F030x6 || STM32F030x8 || STM32F031x6 || STM32F038xx || + STM32F030xC */ + +#if defined(STM32F070x6) || defined(STM32F070xB) + +#define IS_RCC_PERIPHCLOCK(SELECTION) ((SELECTION) <= (RCC_PERIPHCLK_USART1 | RCC_PERIPHCLK_I2C1 | \ + RCC_PERIPHCLK_RTC | RCC_PERIPHCLK_USB)) +#endif /* STM32F070x6 || STM32F070xB */ + +#if defined(STM32F042x6) || defined(STM32F048xx) + +#define IS_RCC_PERIPHCLOCK(SELECTION) ((SELECTION) <= (RCC_PERIPHCLK_USART1 | RCC_PERIPHCLK_I2C1 | \ + RCC_PERIPHCLK_CEC | RCC_PERIPHCLK_RTC | \ + RCC_PERIPHCLK_USB)) +#endif /* STM32F042x6 || STM32F048xx */ + +#if defined(STM32F051x8) || defined(STM32F058xx) + +#define IS_RCC_PERIPHCLOCK(SELECTION) ((SELECTION) <= (RCC_PERIPHCLK_USART1 | RCC_PERIPHCLK_I2C1 | \ + RCC_PERIPHCLK_CEC | RCC_PERIPHCLK_RTC)) +#endif /* STM32F051x8 || STM32F058xx */ + +#if defined(STM32F071xB) + +#define IS_RCC_PERIPHCLOCK(SELECTION) ((SELECTION) <= (RCC_PERIPHCLK_USART1 | RCC_PERIPHCLK_USART2 | \ + RCC_PERIPHCLK_I2C1 | RCC_PERIPHCLK_CEC | \ + RCC_PERIPHCLK_RTC)) +#endif /* STM32F071xB */ + +#if defined(STM32F072xB) || defined(STM32F078xx) + +#define IS_RCC_PERIPHCLOCK(SELECTION) ((SELECTION) <= (RCC_PERIPHCLK_USART1 | RCC_PERIPHCLK_USART2 | \ + RCC_PERIPHCLK_I2C1 | RCC_PERIPHCLK_CEC | \ + RCC_PERIPHCLK_RTC | RCC_PERIPHCLK_USB)) +#endif /* STM32F072xB || STM32F078xx */ + +#if defined(STM32F091xC) || defined(STM32F098xx) + +#define IS_RCC_PERIPHCLOCK(SELECTION) ((SELECTION) <= (RCC_PERIPHCLK_USART1 | RCC_PERIPHCLK_USART2 | \ + RCC_PERIPHCLK_I2C1 | RCC_PERIPHCLK_CEC | \ + RCC_PERIPHCLK_RTC | RCC_PERIPHCLK_USART3 )) +#endif /* STM32F091xC || STM32F098xx */ + +#if defined(STM32F042x6) || defined(STM32F048xx) || defined(STM32F072xB) || defined(STM32F078xx) + +#define IS_RCC_USBCLKSOURCE(SOURCE) (((SOURCE) == RCC_USBCLKSOURCE_HSI48) || \ + ((SOURCE) == RCC_USBCLKSOURCE_PLL)) + +#endif /* STM32F042x6 || STM32F048xx || STM32F072xB || STM32F078xx */ + +#if defined(STM32F070x6) || defined(STM32F070xB) + +#define IS_RCC_USBCLKSOURCE(SOURCE) (((SOURCE) == RCC_USBCLKSOURCE_NONE) || \ + ((SOURCE) == RCC_USBCLKSOURCE_PLL)) + +#endif /* STM32F070x6 || STM32F070xB */ + +#if defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F078xx)\ + || defined(STM32F091xC) || defined(STM32F098xx) + +#define IS_RCC_USART2CLKSOURCE(SOURCE) (((SOURCE) == RCC_USART2CLKSOURCE_PCLK1) || \ + ((SOURCE) == RCC_USART2CLKSOURCE_SYSCLK) || \ + ((SOURCE) == RCC_USART2CLKSOURCE_LSE) || \ + ((SOURCE) == RCC_USART2CLKSOURCE_HSI)) + +#endif /* STM32F071xB || STM32F072xB || STM32F078xx || */ + /* STM32F091xC || STM32F098xx */ + +#if defined(STM32F091xC) || defined(STM32F098xx) + +#define IS_RCC_USART3CLKSOURCE(SOURCE) (((SOURCE) == RCC_USART3CLKSOURCE_PCLK1) || \ + ((SOURCE) == RCC_USART3CLKSOURCE_SYSCLK) || \ + ((SOURCE) == RCC_USART3CLKSOURCE_LSE) || \ + ((SOURCE) == RCC_USART3CLKSOURCE_HSI)) +#endif /* STM32F091xC || STM32F098xx */ + + +#if defined(STM32F042x6) || defined(STM32F048xx)\ + || defined(STM32F051x8) || defined(STM32F058xx)\ + || defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F078xx)\ + || defined(STM32F091xC) || defined(STM32F098xx) + +#define IS_RCC_CECCLKSOURCE(SOURCE) (((SOURCE) == RCC_CECCLKSOURCE_HSI) || \ + ((SOURCE) == RCC_CECCLKSOURCE_LSE)) +#endif /* STM32F042x6 || STM32F048xx || */ + /* STM32F051x8 || STM32F058xx || */ + /* STM32F071xB || STM32F072xB || STM32F078xx || */ + /* STM32F091xC || STM32F098xx */ + +#if defined(RCC_CFGR_MCOPRE) + +#define IS_RCC_MCODIV(DIV) (((DIV) == RCC_MCODIV_1) || ((DIV) == RCC_MCODIV_2) || \ + ((DIV) == RCC_MCODIV_4) || ((DIV) == RCC_MCODIV_8) || \ + ((DIV) == RCC_MCODIV_16) || ((DIV) == RCC_MCODIV_32) || \ + ((DIV) == RCC_MCODIV_64) || ((DIV) == RCC_MCODIV_128)) +#else + +#define IS_RCC_MCODIV(DIV) (((DIV) == RCC_MCODIV_1)) + +#endif /* RCC_CFGR_MCOPRE */ + +#define IS_RCC_LSE_DRIVE(__DRIVE__) (((__DRIVE__) == RCC_LSEDRIVE_LOW) || \ + ((__DRIVE__) == RCC_LSEDRIVE_MEDIUMLOW) || \ + ((__DRIVE__) == RCC_LSEDRIVE_MEDIUMHIGH) || \ + ((__DRIVE__) == RCC_LSEDRIVE_HIGH)) + +#if defined(CRS) + +#define IS_RCC_CRS_SYNC_SOURCE(_SOURCE_) (((_SOURCE_) == RCC_CRS_SYNC_SOURCE_GPIO) || \ + ((_SOURCE_) == RCC_CRS_SYNC_SOURCE_LSE) || \ + ((_SOURCE_) == RCC_CRS_SYNC_SOURCE_USB)) +#define IS_RCC_CRS_SYNC_DIV(_DIV_) (((_DIV_) == RCC_CRS_SYNC_DIV1) || ((_DIV_) == RCC_CRS_SYNC_DIV2) || \ + ((_DIV_) == RCC_CRS_SYNC_DIV4) || ((_DIV_) == RCC_CRS_SYNC_DIV8) || \ + ((_DIV_) == RCC_CRS_SYNC_DIV16) || ((_DIV_) == RCC_CRS_SYNC_DIV32) || \ + ((_DIV_) == RCC_CRS_SYNC_DIV64) || ((_DIV_) == RCC_CRS_SYNC_DIV128)) +#define IS_RCC_CRS_SYNC_POLARITY(_POLARITY_) (((_POLARITY_) == RCC_CRS_SYNC_POLARITY_RISING) || \ + ((_POLARITY_) == RCC_CRS_SYNC_POLARITY_FALLING)) +#define IS_RCC_CRS_RELOADVALUE(_VALUE_) (((_VALUE_) <= 0xFFFFU)) +#define IS_RCC_CRS_ERRORLIMIT(_VALUE_) (((_VALUE_) <= 0xFFU)) +#define IS_RCC_CRS_HSI48CALIBRATION(_VALUE_) (((_VALUE_) <= 0x3FU)) +#define IS_RCC_CRS_FREQERRORDIR(_DIR_) (((_DIR_) == RCC_CRS_FREQERRORDIR_UP) || \ + ((_DIR_) == RCC_CRS_FREQERRORDIR_DOWN)) +#endif /* CRS */ +/** + * @} + */ + +/* Exported types ------------------------------------------------------------*/ + +/** @defgroup RCCEx_Exported_Types RCCEx Exported Types + * @{ + */ + +/** + * @brief RCC extended clocks structure definition + */ +#if defined(STM32F030x6) || defined(STM32F030x8) || defined(STM32F031x6) || defined(STM32F038xx)\ + || defined(STM32F030xC) +typedef struct +{ + uint32_t PeriphClockSelection; /*!< The Extended Clock to be configured. + This parameter can be a value of @ref RCCEx_Periph_Clock_Selection */ + + uint32_t RTCClockSelection; /*!< Specifies RTC Clock Prescalers Selection + This parameter can be a value of @ref RCC_RTC_Clock_Source */ + + uint32_t Usart1ClockSelection; /*!< USART1 clock source + This parameter can be a value of @ref RCC_USART1_Clock_Source */ + + uint32_t I2c1ClockSelection; /*!< I2C1 clock source + This parameter can be a value of @ref RCC_I2C1_Clock_Source */ + +}RCC_PeriphCLKInitTypeDef; +#endif /* STM32F030x6 || STM32F030x8 || STM32F031x6 || STM32F038xx || + STM32F030xC */ + +#if defined(STM32F070x6) || defined(STM32F070xB) +typedef struct +{ + uint32_t PeriphClockSelection; /*!< The Extended Clock to be configured. + This parameter can be a value of @ref RCCEx_Periph_Clock_Selection */ + + uint32_t RTCClockSelection; /*!< Specifies RTC Clock Prescalers Selection + This parameter can be a value of @ref RCC_RTC_Clock_Source */ + + uint32_t Usart1ClockSelection; /*!< USART1 clock source + This parameter can be a value of @ref RCC_USART1_Clock_Source */ + + uint32_t I2c1ClockSelection; /*!< I2C1 clock source + This parameter can be a value of @ref RCC_I2C1_Clock_Source */ + + uint32_t UsbClockSelection; /*!< USB clock source + This parameter can be a value of @ref RCCEx_USB_Clock_Source */ + +}RCC_PeriphCLKInitTypeDef; +#endif /* STM32F070x6 || STM32F070xB */ + +#if defined(STM32F042x6) || defined(STM32F048xx) +typedef struct +{ + uint32_t PeriphClockSelection; /*!< The Extended Clock to be configured. + This parameter can be a value of @ref RCCEx_Periph_Clock_Selection */ + + uint32_t RTCClockSelection; /*!< Specifies RTC Clock Prescalers Selection + This parameter can be a value of @ref RCC_RTC_Clock_Source */ + + uint32_t Usart1ClockSelection; /*!< USART1 clock source + This parameter can be a value of @ref RCC_USART1_Clock_Source */ + + uint32_t I2c1ClockSelection; /*!< I2C1 clock source + This parameter can be a value of @ref RCC_I2C1_Clock_Source */ + + uint32_t CecClockSelection; /*!< HDMI CEC clock source + This parameter can be a value of @ref RCCEx_CEC_Clock_Source */ + + uint32_t UsbClockSelection; /*!< USB clock source + This parameter can be a value of @ref RCCEx_USB_Clock_Source */ + +}RCC_PeriphCLKInitTypeDef; +#endif /* STM32F042x6 || STM32F048xx */ + +#if defined(STM32F051x8) || defined(STM32F058xx) +typedef struct +{ + uint32_t PeriphClockSelection; /*!< The Extended Clock to be configured. + This parameter can be a value of @ref RCCEx_Periph_Clock_Selection */ + + uint32_t RTCClockSelection; /*!< Specifies RTC Clock Prescalers Selection + This parameter can be a value of @ref RCC_RTC_Clock_Source */ + + uint32_t Usart1ClockSelection; /*!< USART1 clock source + This parameter can be a value of @ref RCC_USART1_Clock_Source */ + + uint32_t I2c1ClockSelection; /*!< I2C1 clock source + This parameter can be a value of @ref RCC_I2C1_Clock_Source */ + + uint32_t CecClockSelection; /*!< HDMI CEC clock source + This parameter can be a value of @ref RCCEx_CEC_Clock_Source */ + +}RCC_PeriphCLKInitTypeDef; +#endif /* STM32F051x8 || STM32F058xx */ + +#if defined(STM32F071xB) +typedef struct +{ + uint32_t PeriphClockSelection; /*!< The Extended Clock to be configured. + This parameter can be a value of @ref RCCEx_Periph_Clock_Selection */ + + uint32_t RTCClockSelection; /*!< Specifies RTC Clock Prescalers Selection + This parameter can be a value of @ref RCC_RTC_Clock_Source */ + + uint32_t Usart1ClockSelection; /*!< USART1 clock source + This parameter can be a value of @ref RCC_USART1_Clock_Source */ + + uint32_t Usart2ClockSelection; /*!< USART2 clock source + This parameter can be a value of @ref RCCEx_USART2_Clock_Source */ + + uint32_t I2c1ClockSelection; /*!< I2C1 clock source + This parameter can be a value of @ref RCC_I2C1_Clock_Source */ + + uint32_t CecClockSelection; /*!< HDMI CEC clock source + This parameter can be a value of @ref RCCEx_CEC_Clock_Source */ + +}RCC_PeriphCLKInitTypeDef; +#endif /* STM32F071xB */ + +#if defined(STM32F072xB) || defined(STM32F078xx) +typedef struct +{ + uint32_t PeriphClockSelection; /*!< The Extended Clock to be configured. + This parameter can be a value of @ref RCCEx_Periph_Clock_Selection */ + + uint32_t RTCClockSelection; /*!< Specifies RTC Clock Prescalers Selection + This parameter can be a value of @ref RCC_RTC_Clock_Source */ + + uint32_t Usart1ClockSelection; /*!< USART1 clock source + This parameter can be a value of @ref RCC_USART1_Clock_Source */ + + uint32_t Usart2ClockSelection; /*!< USART2 clock source + This parameter can be a value of @ref RCCEx_USART2_Clock_Source */ + + uint32_t I2c1ClockSelection; /*!< I2C1 clock source + This parameter can be a value of @ref RCC_I2C1_Clock_Source */ + + uint32_t CecClockSelection; /*!< HDMI CEC clock source + This parameter can be a value of @ref RCCEx_CEC_Clock_Source */ + + uint32_t UsbClockSelection; /*!< USB clock source + This parameter can be a value of @ref RCCEx_USB_Clock_Source */ + +}RCC_PeriphCLKInitTypeDef; +#endif /* STM32F072xB || STM32F078xx */ + + +#if defined(STM32F091xC) || defined(STM32F098xx) +typedef struct +{ + uint32_t PeriphClockSelection; /*!< The Extended Clock to be configured. + This parameter can be a value of @ref RCCEx_Periph_Clock_Selection */ + + uint32_t RTCClockSelection; /*!< Specifies RTC Clock Prescalers Selection + This parameter can be a value of @ref RCC_RTC_Clock_Source */ + + uint32_t Usart1ClockSelection; /*!< USART1 clock source + This parameter can be a value of @ref RCC_USART1_Clock_Source */ + + uint32_t Usart2ClockSelection; /*!< USART2 clock source + This parameter can be a value of @ref RCCEx_USART2_Clock_Source */ + + uint32_t Usart3ClockSelection; /*!< USART3 clock source + This parameter can be a value of @ref RCCEx_USART3_Clock_Source */ + + uint32_t I2c1ClockSelection; /*!< I2C1 clock source + This parameter can be a value of @ref RCC_I2C1_Clock_Source */ + + uint32_t CecClockSelection; /*!< HDMI CEC clock source + This parameter can be a value of @ref RCCEx_CEC_Clock_Source */ + +}RCC_PeriphCLKInitTypeDef; +#endif /* STM32F091xC || STM32F098xx */ + +#if defined(CRS) + +/** + * @brief RCC_CRS Init structure definition + */ +typedef struct +{ + uint32_t Prescaler; /*!< Specifies the division factor of the SYNC signal. + This parameter can be a value of @ref RCCEx_CRS_SynchroDivider */ + + uint32_t Source; /*!< Specifies the SYNC signal source. + This parameter can be a value of @ref RCCEx_CRS_SynchroSource */ + + uint32_t Polarity; /*!< Specifies the input polarity for the SYNC signal source. + This parameter can be a value of @ref RCCEx_CRS_SynchroPolarity */ + + uint32_t ReloadValue; /*!< Specifies the value to be loaded in the frequency error counter with each SYNC event. + It can be calculated in using macro @ref __HAL_RCC_CRS_RELOADVALUE_CALCULATE(__FTARGET__, __FSYNC__) + This parameter must be a number between 0 and 0xFFFF or a value of @ref RCCEx_CRS_ReloadValueDefault .*/ + + uint32_t ErrorLimitValue; /*!< Specifies the value to be used to evaluate the captured frequency error value. + This parameter must be a number between 0 and 0xFF or a value of @ref RCCEx_CRS_ErrorLimitDefault */ + + uint32_t HSI48CalibrationValue; /*!< Specifies a user-programmable trimming value to the HSI48 oscillator. + This parameter must be a number between 0 and 0x3F or a value of @ref RCCEx_CRS_HSI48CalibrationDefault */ + +}RCC_CRSInitTypeDef; + +/** + * @brief RCC_CRS Synchronization structure definition + */ +typedef struct +{ + uint32_t ReloadValue; /*!< Specifies the value loaded in the Counter reload value. + This parameter must be a number between 0 and 0xFFFFU */ + + uint32_t HSI48CalibrationValue; /*!< Specifies value loaded in HSI48 oscillator smooth trimming. + This parameter must be a number between 0 and 0x3FU */ + + uint32_t FreqErrorCapture; /*!< Specifies the value loaded in the .FECAP, the frequency error counter + value latched in the time of the last SYNC event. + This parameter must be a number between 0 and 0xFFFFU */ + + uint32_t FreqErrorDirection; /*!< Specifies the value loaded in the .FEDIR, the counting direction of the + frequency error counter latched in the time of the last SYNC event. + It shows whether the actual frequency is below or above the target. + This parameter must be a value of @ref RCCEx_CRS_FreqErrorDirection*/ + +}RCC_CRSSynchroInfoTypeDef; + +#endif /* CRS */ + +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup RCCEx_Exported_Constants RCCEx Exported Constants + * @{ + */ + +/** @defgroup RCCEx_Periph_Clock_Selection RCCEx Periph Clock Selection + * @{ + */ +#if defined(STM32F030x6) || defined(STM32F030x8) || defined(STM32F031x6) || defined(STM32F038xx)\ + || defined(STM32F030xC) +#define RCC_PERIPHCLK_USART1 (0x00000001U) +#define RCC_PERIPHCLK_I2C1 (0x00000020U) +#define RCC_PERIPHCLK_RTC (0x00010000U) + +#endif /* STM32F030x6 || STM32F030x8 || STM32F031x6 || STM32F038xx || + STM32F030xC */ + +#if defined(STM32F070x6) || defined(STM32F070xB) +#define RCC_PERIPHCLK_USART1 (0x00000001U) +#define RCC_PERIPHCLK_I2C1 (0x00000020U) +#define RCC_PERIPHCLK_RTC (0x00010000U) +#define RCC_PERIPHCLK_USB (0x00020000U) + +#endif /* STM32F070x6 || STM32F070xB */ + +#if defined(STM32F042x6) || defined(STM32F048xx) +#define RCC_PERIPHCLK_USART1 (0x00000001U) +#define RCC_PERIPHCLK_I2C1 (0x00000020U) +#define RCC_PERIPHCLK_CEC (0x00000400U) +#define RCC_PERIPHCLK_RTC (0x00010000U) +#define RCC_PERIPHCLK_USB (0x00020000U) + +#endif /* STM32F042x6 || STM32F048xx */ + +#if defined(STM32F051x8) || defined(STM32F058xx) +#define RCC_PERIPHCLK_USART1 (0x00000001U) +#define RCC_PERIPHCLK_I2C1 (0x00000020U) +#define RCC_PERIPHCLK_CEC (0x00000400U) +#define RCC_PERIPHCLK_RTC (0x00010000U) + +#endif /* STM32F051x8 || STM32F058xx */ + +#if defined(STM32F071xB) +#define RCC_PERIPHCLK_USART1 (0x00000001U) +#define RCC_PERIPHCLK_USART2 (0x00000002U) +#define RCC_PERIPHCLK_I2C1 (0x00000020U) +#define RCC_PERIPHCLK_CEC (0x00000400U) +#define RCC_PERIPHCLK_RTC (0x00010000U) + +#endif /* STM32F071xB */ + +#if defined(STM32F072xB) || defined(STM32F078xx) +#define RCC_PERIPHCLK_USART1 (0x00000001U) +#define RCC_PERIPHCLK_USART2 (0x00000002U) +#define RCC_PERIPHCLK_I2C1 (0x00000020U) +#define RCC_PERIPHCLK_CEC (0x00000400U) +#define RCC_PERIPHCLK_RTC (0x00010000U) +#define RCC_PERIPHCLK_USB (0x00020000U) + +#endif /* STM32F072xB || STM32F078xx */ + +#if defined(STM32F091xC) || defined(STM32F098xx) +#define RCC_PERIPHCLK_USART1 (0x00000001U) +#define RCC_PERIPHCLK_USART2 (0x00000002U) +#define RCC_PERIPHCLK_I2C1 (0x00000020U) +#define RCC_PERIPHCLK_CEC (0x00000400U) +#define RCC_PERIPHCLK_RTC (0x00010000U) +#define RCC_PERIPHCLK_USART3 (0x00040000U) + +#endif /* STM32F091xC || STM32F098xx */ + +/** + * @} + */ + +#if defined(STM32F042x6) || defined(STM32F048xx) || defined(STM32F072xB) || defined(STM32F078xx) + +/** @defgroup RCCEx_USB_Clock_Source RCCEx USB Clock Source + * @{ + */ +#define RCC_USBCLKSOURCE_HSI48 RCC_CFGR3_USBSW_HSI48 /*!< HSI48 clock selected as USB clock source */ +#define RCC_USBCLKSOURCE_PLL RCC_CFGR3_USBSW_PLLCLK /*!< PLL clock (PLLCLK) selected as USB clock */ + +/** + * @} + */ + +#endif /* STM32F042x6 || STM32F048xx || STM32F072xB || STM32F078xx */ + +#if defined(STM32F070x6) || defined(STM32F070xB) + +/** @defgroup RCCEx_USB_Clock_Source RCCEx USB Clock Source + * @{ + */ +#define RCC_USBCLKSOURCE_NONE (0x00000000U) /*!< USB clock disabled */ +#define RCC_USBCLKSOURCE_PLL RCC_CFGR3_USBSW_PLLCLK /*!< PLL clock (PLLCLK) selected as USB clock */ + +/** + * @} + */ + +#endif /* STM32F070x6 || STM32F070xB */ + +#if defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F078xx)\ + || defined(STM32F091xC) || defined(STM32F098xx) + +/** @defgroup RCCEx_USART2_Clock_Source RCCEx USART2 Clock Source + * @{ + */ +#define RCC_USART2CLKSOURCE_PCLK1 RCC_CFGR3_USART2SW_PCLK +#define RCC_USART2CLKSOURCE_SYSCLK RCC_CFGR3_USART2SW_SYSCLK +#define RCC_USART2CLKSOURCE_LSE RCC_CFGR3_USART2SW_LSE +#define RCC_USART2CLKSOURCE_HSI RCC_CFGR3_USART2SW_HSI + +/** + * @} + */ + +#endif /* STM32F071xB || STM32F072xB || STM32F078xx || */ + /* STM32F091xC || STM32F098xx */ + +#if defined(STM32F091xC) || defined(STM32F098xx) + +/** @defgroup RCCEx_USART3_Clock_Source RCCEx USART3 Clock Source + * @{ + */ +#define RCC_USART3CLKSOURCE_PCLK1 RCC_CFGR3_USART3SW_PCLK +#define RCC_USART3CLKSOURCE_SYSCLK RCC_CFGR3_USART3SW_SYSCLK +#define RCC_USART3CLKSOURCE_LSE RCC_CFGR3_USART3SW_LSE +#define RCC_USART3CLKSOURCE_HSI RCC_CFGR3_USART3SW_HSI + +/** + * @} + */ + +#endif /* STM32F091xC || STM32F098xx */ + + +#if defined(STM32F042x6) || defined(STM32F048xx)\ + || defined(STM32F051x8) || defined(STM32F058xx)\ + || defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F078xx)\ + || defined(STM32F091xC) || defined(STM32F098xx) + +/** @defgroup RCCEx_CEC_Clock_Source RCCEx CEC Clock Source + * @{ + */ +#define RCC_CECCLKSOURCE_HSI RCC_CFGR3_CECSW_HSI_DIV244 +#define RCC_CECCLKSOURCE_LSE RCC_CFGR3_CECSW_LSE + +/** + * @} + */ + +#endif /* STM32F042x6 || STM32F048xx || */ + /* STM32F051x8 || STM32F058xx || */ + /* STM32F071xB || STM32F072xB || STM32F078xx || */ + /* STM32F091xC || STM32F098xx */ + +/** @defgroup RCCEx_MCOx_Clock_Prescaler RCCEx MCOx Clock Prescaler + * @{ + */ + +#if defined(RCC_CFGR_MCOPRE) + +#define RCC_MCODIV_1 (0x00000000U) +#define RCC_MCODIV_2 (0x10000000U) +#define RCC_MCODIV_4 (0x20000000U) +#define RCC_MCODIV_8 (0x30000000U) +#define RCC_MCODIV_16 (0x40000000U) +#define RCC_MCODIV_32 (0x50000000U) +#define RCC_MCODIV_64 (0x60000000U) +#define RCC_MCODIV_128 (0x70000000U) + +#else + +#define RCC_MCODIV_1 (0x00000000U) + +#endif /* RCC_CFGR_MCOPRE */ + +/** + * @} + */ + +/** @defgroup RCCEx_LSEDrive_Configuration RCC LSE Drive Configuration + * @{ + */ + +#define RCC_LSEDRIVE_LOW (0x00000000U) /*!< Xtal mode lower driving capability */ +#define RCC_LSEDRIVE_MEDIUMLOW RCC_BDCR_LSEDRV_1 /*!< Xtal mode medium low driving capability */ +#define RCC_LSEDRIVE_MEDIUMHIGH RCC_BDCR_LSEDRV_0 /*!< Xtal mode medium high driving capability */ +#define RCC_LSEDRIVE_HIGH RCC_BDCR_LSEDRV /*!< Xtal mode higher driving capability */ + +/** + * @} + */ + +#if defined(CRS) + +/** @defgroup RCCEx_CRS_Status RCCEx CRS Status + * @{ + */ +#define RCC_CRS_NONE (0x00000000U) +#define RCC_CRS_TIMEOUT (0x00000001U) +#define RCC_CRS_SYNCOK (0x00000002U) +#define RCC_CRS_SYNCWARN (0x00000004U) +#define RCC_CRS_SYNCERR (0x00000008U) +#define RCC_CRS_SYNCMISS (0x00000010U) +#define RCC_CRS_TRIMOVF (0x00000020U) + +/** + * @} + */ + +/** @defgroup RCCEx_CRS_SynchroSource RCCEx CRS Synchronization Source + * @{ + */ +#define RCC_CRS_SYNC_SOURCE_GPIO (0x00000000U) /*!< Synchro Signal source GPIO */ +#define RCC_CRS_SYNC_SOURCE_LSE CRS_CFGR_SYNCSRC_0 /*!< Synchro Signal source LSE */ +#define RCC_CRS_SYNC_SOURCE_USB CRS_CFGR_SYNCSRC_1 /*!< Synchro Signal source USB SOF (default)*/ +/** + * @} + */ + +/** @defgroup RCCEx_CRS_SynchroDivider RCCEx CRS Synchronization Divider + * @{ + */ +#define RCC_CRS_SYNC_DIV1 (0x00000000U) /*!< Synchro Signal not divided (default) */ +#define RCC_CRS_SYNC_DIV2 CRS_CFGR_SYNCDIV_0 /*!< Synchro Signal divided by 2 */ +#define RCC_CRS_SYNC_DIV4 CRS_CFGR_SYNCDIV_1 /*!< Synchro Signal divided by 4 */ +#define RCC_CRS_SYNC_DIV8 (CRS_CFGR_SYNCDIV_1 | CRS_CFGR_SYNCDIV_0) /*!< Synchro Signal divided by 8 */ +#define RCC_CRS_SYNC_DIV16 CRS_CFGR_SYNCDIV_2 /*!< Synchro Signal divided by 16 */ +#define RCC_CRS_SYNC_DIV32 (CRS_CFGR_SYNCDIV_2 | CRS_CFGR_SYNCDIV_0) /*!< Synchro Signal divided by 32 */ +#define RCC_CRS_SYNC_DIV64 (CRS_CFGR_SYNCDIV_2 | CRS_CFGR_SYNCDIV_1) /*!< Synchro Signal divided by 64 */ +#define RCC_CRS_SYNC_DIV128 CRS_CFGR_SYNCDIV /*!< Synchro Signal divided by 128 */ +/** + * @} + */ + +/** @defgroup RCCEx_CRS_SynchroPolarity RCCEx CRS Synchronization Polarity + * @{ + */ +#define RCC_CRS_SYNC_POLARITY_RISING (0x00000000U) /*!< Synchro Active on rising edge (default) */ +#define RCC_CRS_SYNC_POLARITY_FALLING CRS_CFGR_SYNCPOL /*!< Synchro Active on falling edge */ +/** + * @} + */ + +/** @defgroup RCCEx_CRS_ReloadValueDefault RCCEx CRS Default Reload Value + * @{ + */ +#define RCC_CRS_RELOADVALUE_DEFAULT (0x0000BB7FU) /*!< The reset value of the RELOAD field corresponds + to a target frequency of 48 MHz and a synchronization signal frequency of 1 kHz (SOF signal from USB). */ +/** + * @} + */ + +/** @defgroup RCCEx_CRS_ErrorLimitDefault RCCEx CRS Default Error Limit Value + * @{ + */ +#define RCC_CRS_ERRORLIMIT_DEFAULT (0x00000022U) /*!< Default Frequency error limit */ +/** + * @} + */ + +/** @defgroup RCCEx_CRS_HSI48CalibrationDefault RCCEx CRS Default HSI48 Calibration vakye + * @{ + */ +#define RCC_CRS_HSI48CALIBRATION_DEFAULT (0x00000020U) /*!< The default value is 32, which corresponds to the middle of the trimming interval. + The trimming step is around 67 kHz between two consecutive TRIM steps. A higher TRIM value + corresponds to a higher output frequency */ +/** + * @} + */ + +/** @defgroup RCCEx_CRS_FreqErrorDirection RCCEx CRS Frequency Error Direction + * @{ + */ +#define RCC_CRS_FREQERRORDIR_UP (0x00000000U) /*!< Upcounting direction, the actual frequency is above the target */ +#define RCC_CRS_FREQERRORDIR_DOWN ((uint32_t)CRS_ISR_FEDIR) /*!< Downcounting direction, the actual frequency is below the target */ +/** + * @} + */ + +/** @defgroup RCCEx_CRS_Interrupt_Sources RCCEx CRS Interrupt Sources + * @{ + */ +#define RCC_CRS_IT_SYNCOK CRS_CR_SYNCOKIE /*!< SYNC event OK */ +#define RCC_CRS_IT_SYNCWARN CRS_CR_SYNCWARNIE /*!< SYNC warning */ +#define RCC_CRS_IT_ERR CRS_CR_ERRIE /*!< Error */ +#define RCC_CRS_IT_ESYNC CRS_CR_ESYNCIE /*!< Expected SYNC */ +#define RCC_CRS_IT_SYNCERR CRS_CR_ERRIE /*!< SYNC error */ +#define RCC_CRS_IT_SYNCMISS CRS_CR_ERRIE /*!< SYNC missed */ +#define RCC_CRS_IT_TRIMOVF CRS_CR_ERRIE /*!< Trimming overflow or underflow */ + +/** + * @} + */ + +/** @defgroup RCCEx_CRS_Flags RCCEx CRS Flags + * @{ + */ +#define RCC_CRS_FLAG_SYNCOK CRS_ISR_SYNCOKF /*!< SYNC event OK flag */ +#define RCC_CRS_FLAG_SYNCWARN CRS_ISR_SYNCWARNF /*!< SYNC warning flag */ +#define RCC_CRS_FLAG_ERR CRS_ISR_ERRF /*!< Error flag */ +#define RCC_CRS_FLAG_ESYNC CRS_ISR_ESYNCF /*!< Expected SYNC flag */ +#define RCC_CRS_FLAG_SYNCERR CRS_ISR_SYNCERR /*!< SYNC error */ +#define RCC_CRS_FLAG_SYNCMISS CRS_ISR_SYNCMISS /*!< SYNC missed*/ +#define RCC_CRS_FLAG_TRIMOVF CRS_ISR_TRIMOVF /*!< Trimming overflow or underflow */ + +/** + * @} + */ + +#endif /* CRS */ + +/** + * @} + */ + +/* Exported macros ------------------------------------------------------------*/ +/** @defgroup RCCEx_Exported_Macros RCCEx Exported Macros + * @{ + */ + +/** @defgroup RCCEx_Peripheral_Clock_Enable_Disable RCCEx_Peripheral_Clock_Enable_Disable + * @brief Enables or disables the AHB1 peripheral clock. + * @note After reset, the peripheral clock (used for registers read/write access) + * is disabled and the application software has to enable this clock before + * using it. + * @{ + */ +#if defined(GPIOD) + +#define __HAL_RCC_GPIOD_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHBENR, RCC_AHBENR_GPIODEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->AHBENR, RCC_AHBENR_GPIODEN);\ + UNUSED(tmpreg); \ + } while(0U) + +#define __HAL_RCC_GPIOD_CLK_DISABLE() (RCC->AHBENR &= ~(RCC_AHBENR_GPIODEN)) + +#endif /* GPIOD */ + +#if defined(GPIOE) + +#define __HAL_RCC_GPIOE_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHBENR, RCC_AHBENR_GPIOEEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->AHBENR, RCC_AHBENR_GPIOEEN);\ + UNUSED(tmpreg); \ + } while(0U) + +#define __HAL_RCC_GPIOE_CLK_DISABLE() (RCC->AHBENR &= ~(RCC_AHBENR_GPIOEEN)) + +#endif /* GPIOE */ + +#if defined(STM32F042x6) || defined(STM32F048xx)\ + || defined(STM32F051x8) || defined(STM32F058xx)\ + || defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F078xx)\ + || defined(STM32F091xC) || defined(STM32F098xx) + +#define __HAL_RCC_TSC_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHBENR, RCC_AHBENR_TSCEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->AHBENR, RCC_AHBENR_TSCEN);\ + UNUSED(tmpreg); \ + } while(0U) + +#define __HAL_RCC_TSC_CLK_DISABLE() (RCC->AHBENR &= ~(RCC_AHBENR_TSCEN)) + +#endif /* STM32F042x6 || STM32F048xx || */ + /* STM32F051x8 || STM32F058xx || */ + /* STM32F071xB || STM32F072xB || STM32F078xx || */ + /* STM32F091xC || STM32F098xx */ + +#if defined(STM32F091xC) || defined(STM32F098xx) + +#define __HAL_RCC_DMA2_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHBENR, RCC_AHBENR_DMA2EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->AHBENR, RCC_AHBENR_DMA2EN);\ + UNUSED(tmpreg); \ + } while(0U) + +#define __HAL_RCC_DMA2_CLK_DISABLE() (RCC->AHBENR &= ~(RCC_AHBENR_DMA2EN)) + +#endif /* STM32F091xC || STM32F098xx */ + +/** @brief Enable or disable the Low Speed APB (APB1) peripheral clock. + * @note After reset, the peripheral clock (used for registers read/write access) + * is disabled and the application software has to enable this clock before + * using it. + */ +#if defined(STM32F030x8)\ + || defined(STM32F042x6) || defined(STM32F048xx) || defined(STM32F070x6)\ + || defined(STM32F051x8) || defined(STM32F058xx)\ + || defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F078xx) || defined(STM32F070xB)\ + || defined(STM32F091xC) || defined(STM32F098xx) || defined(STM32F030xC) + +#define __HAL_RCC_USART2_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR, RCC_APB1ENR_USART2EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_USART2EN);\ + UNUSED(tmpreg); \ + } while(0U) + +#define __HAL_RCC_USART2_CLK_DISABLE() (RCC->APB1ENR &= ~(RCC_APB1ENR_USART2EN)) + +#endif /* STM32F030x8 || STM32F042x6 || STM32F048xx || */ + /* STM32F051x8 || STM32F058xx || STM32F070x6 || */ + /* STM32F071xB || STM32F072xB || STM32F078xx || STM32F070xB || */ + /* STM32F091xC || STM32F098xx || STM32F030xC */ + +#if defined(STM32F030x8)\ + || defined(STM32F042x6) || defined(STM32F048xx)\ + || defined(STM32F051x8) || defined(STM32F058xx)\ + || defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F078xx) || defined(STM32F070xB)\ + || defined(STM32F091xC) || defined(STM32F098xx) || defined(STM32F030xC) + +#define __HAL_RCC_SPI2_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR, RCC_APB1ENR_SPI2EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_SPI2EN);\ + UNUSED(tmpreg); \ + } while(0U) + +#define __HAL_RCC_SPI2_CLK_DISABLE() (RCC->APB1ENR &= ~(RCC_APB1ENR_SPI2EN)) + +#endif /* STM32F030x8 || STM32F042x6 || STM32F048xx || */ + /* STM32F051x8 || STM32F058xx || */ + /* STM32F071xB || STM32F072xB || STM32F078xx || STM32F070xB || */ + /* STM32F091xC || STM32F098xx || STM32F030xC */ + +#if defined(STM32F031x6) || defined(STM32F038xx)\ + || defined(STM32F042x6) || defined(STM32F048xx)\ + || defined(STM32F051x8) || defined(STM32F058xx)\ + || defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F078xx)\ + || defined(STM32F091xC) || defined(STM32F098xx) + +#define __HAL_RCC_TIM2_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR, RCC_APB1ENR_TIM2EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_TIM2EN);\ + UNUSED(tmpreg); \ + } while(0U) + +#define __HAL_RCC_TIM2_CLK_DISABLE() (RCC->APB1ENR &= ~(RCC_APB1ENR_TIM2EN)) + +#endif /* STM32F031x6 || STM32F038xx || */ + /* STM32F042x6 || STM32F048xx || */ + /* STM32F051x8 || STM32F058xx || */ + /* STM32F071xB || STM32F072xB || STM32F078xx || */ + /* STM32F091xC || STM32F098xx */ + +#if defined(STM32F030x8) \ + || defined(STM32F051x8) || defined(STM32F058xx)\ + || defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F078xx) || defined(STM32F070xB)\ + || defined(STM32F091xC) || defined(STM32F098xx) || defined(STM32F030xC) + +#define __HAL_RCC_TIM6_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR, RCC_APB1ENR_TIM6EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_TIM6EN);\ + UNUSED(tmpreg); \ + } while(0U) +#define __HAL_RCC_I2C2_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR, RCC_APB1ENR_I2C2EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_I2C2EN);\ + UNUSED(tmpreg); \ + } while(0U) + +#define __HAL_RCC_TIM6_CLK_DISABLE() (RCC->APB1ENR &= ~(RCC_APB1ENR_TIM6EN)) +#define __HAL_RCC_I2C2_CLK_DISABLE() (RCC->APB1ENR &= ~(RCC_APB1ENR_I2C2EN)) + +#endif /* STM32F030x8 || */ + /* STM32F051x8 || STM32F058xx || */ + /* STM32F071xB || STM32F072xB || STM32F078xx || STM32F070xB || */ + /* STM32F091xC || STM32F098xx || STM32F030xC */ + +#if defined(STM32F051x8) || defined(STM32F058xx)\ + || defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F078xx)\ + || defined(STM32F091xC) || defined(STM32F098xx) + +#define __HAL_RCC_DAC1_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR, RCC_APB1ENR_DACEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_DACEN);\ + UNUSED(tmpreg); \ + } while(0U) + +#define __HAL_RCC_DAC1_CLK_DISABLE() (RCC->APB1ENR &= ~(RCC_APB1ENR_DACEN)) + +#endif /* STM32F051x8 || STM32F058xx || */ + /* STM32F071xB || STM32F072xB || STM32F078xx || */ + /* STM32F091xC || STM32F098xx */ + +#if defined(STM32F042x6) || defined(STM32F048xx)\ + || defined(STM32F051x8) || defined(STM32F058xx)\ + || defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F078xx)\ + || defined(STM32F091xC) || defined(STM32F098xx) + +#define __HAL_RCC_CEC_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR, RCC_APB1ENR_CECEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_CECEN);\ + UNUSED(tmpreg); \ + } while(0U) + +#define __HAL_RCC_CEC_CLK_DISABLE() (RCC->APB1ENR &= ~(RCC_APB1ENR_CECEN)) + +#endif /* STM32F042x6 || STM32F048xx || */ + /* STM32F051x8 || STM32F058xx || */ + /* STM32F071xB || STM32F072xB || STM32F078xx || */ + /* STM32F091xC || STM32F098xx */ + +#if defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F078xx) || defined(STM32F070xB)\ + || defined(STM32F091xC) || defined(STM32F098xx) || defined(STM32F030xC) + +#define __HAL_RCC_TIM7_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR, RCC_APB1ENR_TIM7EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_TIM7EN);\ + UNUSED(tmpreg); \ + } while(0U) +#define __HAL_RCC_USART3_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR, RCC_APB1ENR_USART3EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_USART3EN);\ + UNUSED(tmpreg); \ + } while(0U) +#define __HAL_RCC_USART4_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR, RCC_APB1ENR_USART4EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_USART4EN);\ + UNUSED(tmpreg); \ + } while(0U) + +#define __HAL_RCC_TIM7_CLK_DISABLE() (RCC->APB1ENR &= ~(RCC_APB1ENR_TIM7EN)) +#define __HAL_RCC_USART3_CLK_DISABLE() (RCC->APB1ENR &= ~(RCC_APB1ENR_USART3EN)) +#define __HAL_RCC_USART4_CLK_DISABLE() (RCC->APB1ENR &= ~(RCC_APB1ENR_USART4EN)) + +#endif /* STM32F071xB || STM32F072xB || STM32F078xx || STM32F070xB || */ + /* STM32F091xC || STM32F098xx || STM32F030xC */ + +#if defined(STM32F042x6) || defined(STM32F048xx) || defined(STM32F070x6)\ + || defined(STM32F072xB) || defined(STM32F078xx) || defined(STM32F070xB) + +#define __HAL_RCC_USB_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR, RCC_APB1ENR_USBEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_USBEN);\ + UNUSED(tmpreg); \ + } while(0U) + +#define __HAL_RCC_USB_CLK_DISABLE() (RCC->APB1ENR &= ~(RCC_APB1ENR_USBEN)) + +#endif /* STM32F042x6 || STM32F048xx || STM32F070x6 || */ + /* STM32F072xB || STM32F078xx || STM32F070xB */ + +#if defined(STM32F042x6) || defined(STM32F048xx) || defined(STM32F072xB)\ + || defined(STM32F091xC) || defined(STM32F098xx) + +#define __HAL_RCC_CAN1_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR, RCC_APB1ENR_CANEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_CANEN);\ + UNUSED(tmpreg); \ + } while(0U) +#define __HAL_RCC_CAN1_CLK_DISABLE() (RCC->APB1ENR &= ~(RCC_APB1ENR_CANEN)) + +#endif /* STM32F042x6 || STM32F048xx || STM32F072xB || */ + /* STM32F091xC || STM32F098xx */ + +#if defined(CRS) + +#define __HAL_RCC_CRS_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR, RCC_APB1ENR_CRSEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_CRSEN);\ + UNUSED(tmpreg); \ + } while(0U) + +#define __HAL_RCC_CRS_CLK_DISABLE() (RCC->APB1ENR &= ~(RCC_APB1ENR_CRSEN)) + +#endif /* CRS */ + +#if defined(STM32F091xC) || defined(STM32F098xx) || defined(STM32F030xC) + +#define __HAL_RCC_USART5_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR, RCC_APB1ENR_USART5EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_USART5EN);\ + UNUSED(tmpreg); \ + } while(0U) + +#define __HAL_RCC_USART5_CLK_DISABLE() (RCC->APB1ENR &= ~(RCC_APB1ENR_USART5EN)) + +#endif /* STM32F091xC || STM32F098xx || STM32F030xC */ + +/** @brief Enable or disable the High Speed APB (APB2) peripheral clock. + * @note After reset, the peripheral clock (used for registers read/write access) + * is disabled and the application software has to enable this clock before + * using it. + */ +#if defined(STM32F030x8) || defined(STM32F042x6) || defined(STM32F048xx) || defined(STM32F070x6)\ + || defined(STM32F051x8) || defined(STM32F058xx)\ + || defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F078xx) || defined(STM32F070xB)\ + || defined(STM32F091xC) || defined(STM32F098xx) || defined(STM32F030xC) + +#define __HAL_RCC_TIM15_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB2ENR, RCC_APB2ENR_TIM15EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_TIM15EN);\ + UNUSED(tmpreg); \ + } while(0U) + +#define __HAL_RCC_TIM15_CLK_DISABLE() (RCC->APB2ENR &= ~(RCC_APB2ENR_TIM15EN)) + +#endif /* STM32F030x8 || STM32F042x6 || STM32F048xx || STM32F070x6 || */ + /* STM32F051x8 || STM32F058xx || */ + /* STM32F071xB || STM32F072xB || STM32F078xx || STM32F070xB || */ + /* STM32F091xC || STM32F098xx || STM32F030xC */ + +#if defined(STM32F091xC) || defined(STM32F098xx) || defined(STM32F030xC) + +#define __HAL_RCC_USART6_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB2ENR, RCC_APB2ENR_USART6EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_USART6EN);\ + UNUSED(tmpreg); \ + } while(0U) + +#define __HAL_RCC_USART6_CLK_DISABLE() (RCC->APB2ENR &= ~(RCC_APB2ENR_USART6EN)) + +#endif /* STM32F091xC || STM32F098xx || STM32F030xC */ + +#if defined(STM32F091xC) || defined(STM32F098xx) + +#define __HAL_RCC_USART7_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB2ENR, RCC_APB2ENR_USART7EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_USART7EN);\ + UNUSED(tmpreg); \ + } while(0U) +#define __HAL_RCC_USART8_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB2ENR, RCC_APB2ENR_USART8EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_USART8EN);\ + UNUSED(tmpreg); \ + } while(0U) + +#define __HAL_RCC_USART7_CLK_DISABLE() (RCC->APB2ENR &= ~(RCC_APB2ENR_USART7EN)) +#define __HAL_RCC_USART8_CLK_DISABLE() (RCC->APB2ENR &= ~(RCC_APB2ENR_USART8EN)) + +#endif /* STM32F091xC || STM32F098xx */ + +/** + * @} + */ + + +/** @defgroup RCCEx_Force_Release_Peripheral_Reset RCCEx Force Release Peripheral Reset + * @brief Forces or releases peripheral reset. + * @{ + */ + +/** @brief Force or release AHB peripheral reset. + */ +#if defined(GPIOD) + +#define __HAL_RCC_GPIOD_FORCE_RESET() (RCC->AHBRSTR |= (RCC_AHBRSTR_GPIODRST)) + +#define __HAL_RCC_GPIOD_RELEASE_RESET() (RCC->AHBRSTR &= ~(RCC_AHBRSTR_GPIODRST)) + +#endif /* GPIOD */ + +#if defined(GPIOE) + +#define __HAL_RCC_GPIOE_FORCE_RESET() (RCC->AHBRSTR |= (RCC_AHBRSTR_GPIOERST)) + +#define __HAL_RCC_GPIOE_RELEASE_RESET() (RCC->AHBRSTR &= ~(RCC_AHBRSTR_GPIOERST)) + +#endif /* GPIOE */ + +#if defined(STM32F042x6) || defined(STM32F048xx)\ + || defined(STM32F051x8) || defined(STM32F058xx)\ + || defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F078xx)\ + || defined(STM32F091xC) || defined(STM32F098xx) + +#define __HAL_RCC_TSC_FORCE_RESET() (RCC->AHBRSTR |= (RCC_AHBRSTR_TSCRST)) + +#define __HAL_RCC_TSC_RELEASE_RESET() (RCC->AHBRSTR &= ~(RCC_AHBRSTR_TSCRST)) + +#endif /* STM32F042x6 || STM32F048xx || */ + /* STM32F051x8 || STM32F058xx || */ + /* STM32F071xB || STM32F072xB || STM32F078xx || */ + /* STM32F091xC || STM32F098xx */ + +/** @brief Force or release APB1 peripheral reset. + */ +#if defined(STM32F030x8) \ + || defined(STM32F042x6) || defined(STM32F048xx) || defined(STM32F070x6)\ + || defined(STM32F051x8) || defined(STM32F058xx)\ + || defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F078xx) || defined(STM32F070xB)\ + || defined(STM32F091xC) || defined(STM32F098xx) || defined(STM32F030xC) + +#define __HAL_RCC_USART2_FORCE_RESET() (RCC->APB1RSTR |= (RCC_APB1RSTR_USART2RST)) +#define __HAL_RCC_SPI2_FORCE_RESET() (RCC->APB1RSTR |= (RCC_APB1RSTR_SPI2RST)) + +#define __HAL_RCC_USART2_RELEASE_RESET() (RCC->APB1RSTR &= ~(RCC_APB1RSTR_USART2RST)) +#define __HAL_RCC_SPI2_RELEASE_RESET() (RCC->APB1RSTR &= ~(RCC_APB1RSTR_SPI2RST)) + +#endif /* STM32F030x8 || STM32F042x6 || STM32F048xx || STM32F070x6 || */ + /* STM32F051x8 || STM32F058xx || */ + /* STM32F071xB || STM32F072xB || STM32F078xx || STM32F070xB || */ + /* STM32F091xC || STM32F098xx || STM32F030xC */ + +#if defined(STM32F031x6) || defined(STM32F038xx)\ + || defined(STM32F042x6) || defined(STM32F048xx)\ + || defined(STM32F051x8) || defined(STM32F058xx)\ + || defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F078xx)\ + || defined(STM32F091xC) || defined(STM32F098xx) + +#define __HAL_RCC_TIM2_FORCE_RESET() (RCC->APB1RSTR |= (RCC_APB1RSTR_TIM2RST)) + +#define __HAL_RCC_TIM2_RELEASE_RESET() (RCC->APB1RSTR &= ~(RCC_APB1RSTR_TIM2RST)) + +#endif /* STM32F031x6 || STM32F038xx || */ + /* STM32F042x6 || STM32F048xx || */ + /* STM32F051x8 || STM32F058xx || */ + /* STM32F071xB || STM32F072xB || STM32F078xx || */ + /* STM32F091xC || STM32F098xx */ + +#if defined(STM32F030x8) \ + || defined(STM32F051x8) || defined(STM32F058xx)\ + || defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F078xx) || defined(STM32F070xB)\ + || defined(STM32F091xC) || defined(STM32F098xx) || defined(STM32F030xC) + +#define __HAL_RCC_TIM6_FORCE_RESET() (RCC->APB1RSTR |= (RCC_APB1RSTR_TIM6RST)) +#define __HAL_RCC_I2C2_FORCE_RESET() (RCC->APB1RSTR |= (RCC_APB1RSTR_I2C2RST)) + +#define __HAL_RCC_TIM6_RELEASE_RESET() (RCC->APB1RSTR &= ~(RCC_APB1RSTR_TIM6RST)) +#define __HAL_RCC_I2C2_RELEASE_RESET() (RCC->APB1RSTR &= ~(RCC_APB1RSTR_I2C2RST)) + +#endif /* STM32F030x8 || */ + /* STM32F051x8 || STM32F058xx || */ + /* STM32F071xB || STM32F072xB || STM32F078xx || STM32F070xB || */ + /* STM32F091xC || STM32F098xx || STM32F030xC */ + +#if defined(STM32F051x8) || defined(STM32F058xx)\ + || defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F078xx)\ + || defined(STM32F091xC) || defined(STM32F098xx) + +#define __HAL_RCC_DAC1_FORCE_RESET() (RCC->APB1RSTR |= (RCC_APB1RSTR_DACRST)) + +#define __HAL_RCC_DAC1_RELEASE_RESET() (RCC->APB1RSTR &= ~(RCC_APB1RSTR_DACRST)) + +#endif /* STM32F051x8 || STM32F058xx || */ + /* STM32F071xB || STM32F072xB || STM32F078xx || */ + /* STM32F091xC || STM32F098xx */ + +#if defined(STM32F042x6) || defined(STM32F048xx)\ + || defined(STM32F051x8) || defined(STM32F058xx)\ + || defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F078xx)\ + || defined(STM32F091xC) || defined(STM32F098xx) + +#define __HAL_RCC_CEC_FORCE_RESET() (RCC->APB1RSTR |= (RCC_APB1RSTR_CECRST)) + +#define __HAL_RCC_CEC_RELEASE_RESET() (RCC->APB1RSTR &= ~(RCC_APB1RSTR_CECRST)) + +#endif /* STM32F042x6 || STM32F048xx || */ + /* STM32F051x8 || STM32F058xx || */ + /* STM32F071xB || STM32F072xB || STM32F078xx || */ + /* STM32F091xC || STM32F098xx */ + +#if defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F078xx) || defined(STM32F070xB)\ + || defined(STM32F091xC) || defined(STM32F098xx) || defined(STM32F030xC) + +#define __HAL_RCC_TIM7_FORCE_RESET() (RCC->APB1RSTR |= (RCC_APB1RSTR_TIM7RST)) +#define __HAL_RCC_USART3_FORCE_RESET() (RCC->APB1RSTR |= (RCC_APB1RSTR_USART3RST)) +#define __HAL_RCC_USART4_FORCE_RESET() (RCC->APB1RSTR |= (RCC_APB1RSTR_USART4RST)) + +#define __HAL_RCC_TIM7_RELEASE_RESET() (RCC->APB1RSTR &= ~(RCC_APB1RSTR_TIM7RST)) +#define __HAL_RCC_USART3_RELEASE_RESET() (RCC->APB1RSTR &= ~(RCC_APB1RSTR_USART3RST)) +#define __HAL_RCC_USART4_RELEASE_RESET() (RCC->APB1RSTR &= ~(RCC_APB1RSTR_USART4RST)) + +#endif /* STM32F071xB || STM32F072xB || STM32F078xx || STM32F070xB || */ + /* STM32F091xC || STM32F098xx || STM32F030xC */ + +#if defined(STM32F042x6) || defined(STM32F048xx) || defined(STM32F070x6)\ + || defined(STM32F072xB) || defined(STM32F078xx) || defined(STM32F070xB) + +#define __HAL_RCC_USB_FORCE_RESET() (RCC->APB1RSTR |= (RCC_APB1RSTR_USBRST)) + +#define __HAL_RCC_USB_RELEASE_RESET() (RCC->APB1RSTR &= ~(RCC_APB1RSTR_USBRST)) + +#endif /* STM32F042x6 || STM32F048xx || STM32F070x6 || */ + /* STM32F072xB || STM32F078xx || STM32F070xB */ + +#if defined(STM32F042x6) || defined(STM32F048xx) || defined(STM32F072xB)\ + || defined(STM32F091xC) || defined(STM32F098xx) + +#define __HAL_RCC_CAN1_FORCE_RESET() (RCC->APB1RSTR |= (RCC_APB1RSTR_CANRST)) + +#define __HAL_RCC_CAN1_RELEASE_RESET() (RCC->APB1RSTR &= ~(RCC_APB1RSTR_CANRST)) + +#endif /* STM32F042x6 || STM32F048xx || STM32F072xB || */ + /* STM32F091xC || STM32F098xx */ + +#if defined(CRS) + +#define __HAL_RCC_CRS_FORCE_RESET() (RCC->APB1RSTR |= (RCC_APB1RSTR_CRSRST)) + +#define __HAL_RCC_CRS_RELEASE_RESET() (RCC->APB1RSTR &= ~(RCC_APB1RSTR_CRSRST)) + +#endif /* CRS */ + +#if defined(STM32F091xC) || defined(STM32F098xx) || defined(STM32F030xC) + +#define __HAL_RCC_USART5_FORCE_RESET() (RCC->APB1RSTR |= (RCC_APB1RSTR_USART5RST)) + +#define __HAL_RCC_USART5_RELEASE_RESET() (RCC->APB1RSTR &= ~(RCC_APB1RSTR_USART5RST)) + +#endif /* STM32F091xC || STM32F098xx || STM32F030xC */ + + +/** @brief Force or release APB2 peripheral reset. + */ +#if defined(STM32F030x8) || defined(STM32F042x6) || defined(STM32F048xx) || defined(STM32F070x6)\ + || defined(STM32F051x8) || defined(STM32F058xx)\ + || defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F078xx) || defined(STM32F070xB)\ + || defined(STM32F091xC) || defined(STM32F098xx) || defined(STM32F030xC) + +#define __HAL_RCC_TIM15_FORCE_RESET() (RCC->APB2RSTR |= (RCC_APB2RSTR_TIM15RST)) + +#define __HAL_RCC_TIM15_RELEASE_RESET() (RCC->APB2RSTR &= ~(RCC_APB2RSTR_TIM15RST)) + +#endif /* STM32F030x8 || STM32F042x6 || STM32F048xx || STM32F070x6 || */ + /* STM32F051x8 || STM32F058xx || */ + /* STM32F071xB || STM32F072xB || STM32F078xx || STM32F070xB || */ + /* STM32F091xC || STM32F098xx || STM32F030xC */ + +#if defined(STM32F091xC) || defined(STM32F098xx) || defined(STM32F030xC) + +#define __HAL_RCC_USART6_FORCE_RESET() (RCC->APB2RSTR |= (RCC_APB2RSTR_USART6RST)) + +#define __HAL_RCC_USART6_RELEASE_RESET() (RCC->APB2RSTR &= ~(RCC_APB2RSTR_USART6RST)) + +#endif /* STM32F091xC || STM32F098xx || STM32F030xC */ + +#if defined(STM32F091xC) || defined(STM32F098xx) + +#define __HAL_RCC_USART7_FORCE_RESET() (RCC->APB2RSTR |= (RCC_APB2RSTR_USART7RST)) +#define __HAL_RCC_USART8_FORCE_RESET() (RCC->APB2RSTR |= (RCC_APB2RSTR_USART8RST)) + +#define __HAL_RCC_USART7_RELEASE_RESET() (RCC->APB2RSTR &= ~(RCC_APB2RSTR_USART7RST)) +#define __HAL_RCC_USART8_RELEASE_RESET() (RCC->APB2RSTR &= ~(RCC_APB2RSTR_USART8RST)) + +#endif /* STM32F091xC || STM32F098xx */ + +/** + * @} + */ + +/** @defgroup RCCEx_Peripheral_Clock_Enable_Disable_Status Peripheral Clock Enable Disable Status + * @brief Get the enable or disable status of peripheral clock. + * @note After reset, the peripheral clock (used for registers read/write access) + * is disabled and the application software has to enable this clock before + * using it. + * @{ + */ +/** @brief AHB Peripheral Clock Enable Disable Status + */ +#if defined(GPIOD) + +#define __HAL_RCC_GPIOD_IS_CLK_ENABLED() ((RCC->AHBENR & (RCC_AHBENR_GPIODEN)) != RESET) +#define __HAL_RCC_GPIOD_IS_CLK_DISABLED() ((RCC->AHBENR & (RCC_AHBENR_GPIODEN)) == RESET) + +#endif /* GPIOD */ + +#if defined(GPIOE) + +#define __HAL_RCC_GPIOE_IS_CLK_ENABLED() ((RCC->AHBENR & (RCC_AHBENR_GPIOEEN)) != RESET) +#define __HAL_RCC_GPIOE_IS_CLK_DISABLED() ((RCC->AHBENR & (RCC_AHBENR_GPIOEEN)) == RESET) + +#endif /* GPIOE */ + +#if defined(STM32F042x6) || defined(STM32F048xx)\ + || defined(STM32F051x8) || defined(STM32F058xx)\ + || defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F078xx)\ + || defined(STM32F091xC) || defined(STM32F098xx) + +#define __HAL_RCC_TSC_IS_CLK_ENABLED() ((RCC->AHBENR & (RCC_AHBENR_TSCEN)) != RESET) +#define __HAL_RCC_TSC_IS_CLK_DISABLED() ((RCC->AHBENR & (RCC_AHBENR_TSCEN)) == RESET) + +#endif /* STM32F042x6 || STM32F048xx || */ + /* STM32F051x8 || STM32F058xx || */ + /* STM32F071xB || STM32F072xB || STM32F078xx || */ + /* STM32F091xC || STM32F098xx */ + +#if defined(STM32F091xC) || defined(STM32F098xx) + +#define __HAL_RCC_DMA2_IS_CLK_ENABLED() ((RCC->AHBENR & (RCC_AHBENR_DMA2EN)) != RESET) +#define __HAL_RCC_DMA2_IS_CLK_DISABLED() ((RCC->AHBENR & (RCC_AHBENR_DMA2EN)) == RESET) + +#endif /* STM32F091xC || STM32F098xx */ + +/** @brief APB1 Peripheral Clock Enable Disable Status + */ +#if defined(STM32F030x8)\ + || defined(STM32F042x6) || defined(STM32F048xx) || defined(STM32F070x6)\ + || defined(STM32F051x8) || defined(STM32F058xx)\ + || defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F078xx) || defined(STM32F070xB)\ + || defined(STM32F091xC) || defined(STM32F098xx) || defined(STM32F030xC) + +#define __HAL_RCC_USART2_IS_CLK_ENABLED() ((RCC->APB1ENR & (RCC_APB1ENR_USART2EN)) != RESET) +#define __HAL_RCC_USART2_IS_CLK_DISABLED() ((RCC->APB1ENR & (RCC_APB1ENR_USART2EN)) == RESET) + +#endif /* STM32F030x8 || STM32F042x6 || STM32F048xx || */ + /* STM32F051x8 || STM32F058xx || STM32F070x6 || */ + /* STM32F071xB || STM32F072xB || STM32F078xx || STM32F070xB || */ + /* STM32F091xC || STM32F098xx || STM32F030xC */ + +#if defined(STM32F030x8)\ + || defined(STM32F042x6) || defined(STM32F048xx)\ + || defined(STM32F051x8) || defined(STM32F058xx)\ + || defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F078xx) || defined(STM32F070xB)\ + || defined(STM32F091xC) || defined(STM32F098xx) || defined(STM32F030xC) + +#define __HAL_RCC_SPI2_IS_CLK_ENABLED() ((RCC->APB1ENR & (RCC_APB1ENR_SPI2EN)) != RESET) +#define __HAL_RCC_SPI2_IS_CLK_DISABLED() ((RCC->APB1ENR & (RCC_APB1ENR_SPI2EN)) == RESET) + +#endif /* STM32F030x8 || STM32F042x6 || STM32F048xx || */ + /* STM32F051x8 || STM32F058xx || */ + /* STM32F071xB || STM32F072xB || STM32F078xx || STM32F070xB || */ + /* STM32F091xC || STM32F098xx || STM32F030xC */ + +#if defined(STM32F031x6) || defined(STM32F038xx)\ + || defined(STM32F042x6) || defined(STM32F048xx)\ + || defined(STM32F051x8) || defined(STM32F058xx)\ + || defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F078xx)\ + || defined(STM32F091xC) || defined(STM32F098xx) + +#define __HAL_RCC_TIM2_IS_CLK_ENABLED() ((RCC->APB1ENR & (RCC_APB1ENR_TIM2EN)) != RESET) +#define __HAL_RCC_TIM2_IS_CLK_DISABLED() ((RCC->APB1ENR & (RCC_APB1ENR_TIM2EN)) == RESET) + +#endif /* STM32F031x6 || STM32F038xx || */ + /* STM32F042x6 || STM32F048xx || */ + /* STM32F051x8 || STM32F058xx || */ + /* STM32F071xB || STM32F072xB || STM32F078xx || */ + /* STM32F091xC || STM32F098xx */ + +#if defined(STM32F030x8) \ + || defined(STM32F051x8) || defined(STM32F058xx)\ + || defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F078xx) || defined(STM32F070xB)\ + || defined(STM32F091xC) || defined(STM32F098xx) || defined(STM32F030xC) + +#define __HAL_RCC_TIM6_IS_CLK_ENABLED() ((RCC->APB1ENR & (RCC_APB1ENR_TIM6EN)) != RESET) +#define __HAL_RCC_I2C2_IS_CLK_ENABLED() ((RCC->APB1ENR & (RCC_APB1ENR_I2C2EN)) != RESET) +#define __HAL_RCC_TIM6_IS_CLK_DISABLED() ((RCC->APB1ENR & (RCC_APB1ENR_TIM6EN)) == RESET) +#define __HAL_RCC_I2C2_IS_CLK_DISABLED() ((RCC->APB1ENR & (RCC_APB1ENR_I2C2EN)) == RESET) + +#endif /* STM32F030x8 || */ + /* STM32F051x8 || STM32F058xx || */ + /* STM32F071xB || STM32F072xB || STM32F078xx || STM32F070xB || */ + /* STM32F091xC || STM32F098xx || STM32F030xC */ + +#if defined(STM32F051x8) || defined(STM32F058xx)\ + || defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F078xx)\ + || defined(STM32F091xC) || defined(STM32F098xx) + +#define __HAL_RCC_DAC1_IS_CLK_ENABLED() ((RCC->APB1ENR & (RCC_APB1ENR_DAC1EN)) != RESET) +#define __HAL_RCC_DAC1_IS_CLK_DISABLED() ((RCC->APB1ENR & (RCC_APB1ENR_DAC1EN)) == RESET) + +#endif /* STM32F051x8 || STM32F058xx || */ + /* STM32F071xB || STM32F072xB || STM32F078xx || */ + /* STM32F091xC || STM32F098xx */ + +#if defined(STM32F042x6) || defined(STM32F048xx)\ + || defined(STM32F051x8) || defined(STM32F058xx)\ + || defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F078xx)\ + || defined(STM32F091xC) || defined(STM32F098xx) + +#define __HAL_RCC_CEC_IS_CLK_ENABLED() ((RCC->APB1ENR & (RCC_APB1ENR_CECEN)) != RESET) +#define __HAL_RCC_CEC_IS_CLK_DISABLED() ((RCC->APB1ENR & (RCC_APB1ENR_CECEN)) == RESET) + +#endif /* STM32F042x6 || STM32F048xx || */ + /* STM32F051x8 || STM32F058xx || */ + /* STM32F071xB || STM32F072xB || STM32F078xx || */ + /* STM32F091xC || STM32F098xx */ + +#if defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F078xx) || defined(STM32F070xB)\ + || defined(STM32F091xC) || defined(STM32F098xx) || defined(STM32F030xC) + +#define __HAL_RCC_TIM7_IS_CLK_ENABLED() ((RCC->APB1ENR & (RCC_APB1ENR_TIM7EN)) != RESET) +#define __HAL_RCC_USART3_IS_CLK_ENABLED() ((RCC->APB1ENR & (RCC_APB1ENR_USART3EN)) != RESET) +#define __HAL_RCC_USART4_IS_CLK_ENABLED() ((RCC->APB1ENR & (RCC_APB1ENR_USART4EN)) != RESET) +#define __HAL_RCC_TIM7_IS_CLK_DISABLED() ((RCC->APB1ENR & (RCC_APB1ENR_TIM7EN)) == RESET) +#define __HAL_RCC_USART3_IS_CLK_DISABLED() ((RCC->APB1ENR & (RCC_APB1ENR_USART3EN)) == RESET) +#define __HAL_RCC_USART4_IS_CLK_DISABLED() ((RCC->APB1ENR & (RCC_APB1ENR_USART4EN)) == RESET) + +#endif /* STM32F071xB || STM32F072xB || STM32F078xx || STM32F070xB || */ + /* STM32F091xC || STM32F098xx || STM32F030xC */ + +#if defined(STM32F042x6) || defined(STM32F048xx) || defined(STM32F070x6)\ + || defined(STM32F072xB) || defined(STM32F078xx) || defined(STM32F070xB) + +#define __HAL_RCC_USB_IS_CLK_ENABLED() ((RCC->APB1ENR & (RCC_APB1ENR_USBEN)) != RESET) +#define __HAL_RCC_USB_IS_CLK_DISABLED() ((RCC->APB1ENR & (RCC_APB1ENR_USBEN)) == RESET) + +#endif /* STM32F042x6 || STM32F048xx || STM32F070x6 || */ + /* STM32F072xB || STM32F078xx || STM32F070xB */ + +#if defined(STM32F042x6) || defined(STM32F048xx) || defined(STM32F072xB)\ + || defined(STM32F091xC) || defined(STM32F098xx) + +#define __HAL_RCC_CAN1_IS_CLK_ENABLED() ((RCC->APB1ENR & (RCC_APB1ENR_CAN1EN)) != RESET) +#define __HAL_RCC_CAN1_IS_CLK_DISABLED() ((RCC->APB1ENR & (RCC_APB1ENR_CAN1EN)) == RESET) + +#endif /* STM32F042x6 || STM32F048xx || STM32F072xB || */ + /* STM32F091xC || STM32F098xx */ + +#if defined(CRS) + +#define __HAL_RCC_CRS_IS_CLK_ENABLED() ((RCC->APB1ENR & (RCC_APB1ENR_CRSEN)) != RESET) +#define __HAL_RCC_CRS_IS_CLK_DISABLED() ((RCC->APB1ENR & (RCC_APB1ENR_CRSEN)) == RESET) + +#endif /* CRS */ + +#if defined(STM32F091xC) || defined(STM32F098xx) || defined(STM32F030xC) + +#define __HAL_RCC_USART5_IS_CLK_ENABLED() ((RCC->APB1ENR & (RCC_APB1ENR_USART5EN)) != RESET) +#define __HAL_RCC_USART5_IS_CLK_DISABLED() ((RCC->APB1ENR & (RCC_APB1ENR_USART5EN)) == RESET) + +#endif /* STM32F091xC || STM32F098xx || STM32F030xC */ + +/** @brief APB1 Peripheral Clock Enable Disable Status + */ +#if defined(STM32F030x8) || defined(STM32F042x6) || defined(STM32F048xx) || defined(STM32F070x6)\ + || defined(STM32F051x8) || defined(STM32F058xx)\ + || defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F078xx) || defined(STM32F070xB)\ + || defined(STM32F091xC) || defined(STM32F098xx) || defined(STM32F030xC) + +#define __HAL_RCC_TIM15_IS_CLK_ENABLED() ((RCC->APB2ENR & (RCC_APB2ENR_TIM15EN)) != RESET) +#define __HAL_RCC_TIM15_IS_CLK_DISABLED() ((RCC->APB2ENR & (RCC_APB2ENR_TIM15EN)) == RESET) + +#endif /* STM32F030x8 || STM32F042x6 || STM32F048xx || STM32F070x6 || */ + /* STM32F051x8 || STM32F058xx || */ + /* STM32F071xB || STM32F072xB || STM32F078xx || STM32F070xB || */ + /* STM32F091xC || STM32F098xx || STM32F030xC */ + +#if defined(STM32F091xC) || defined(STM32F098xx) || defined(STM32F030xC) + +#define __HAL_RCC_USART6_IS_CLK_ENABLED() ((RCC->APB2ENR & (RCC_APB2ENR_USART6EN)) != RESET) +#define __HAL_RCC_USART6_IS_CLK_DISABLED() ((RCC->APB2ENR & (RCC_APB2ENR_USART6EN)) == RESET) + +#endif /* STM32F091xC || STM32F098xx || STM32F030xC */ + +#if defined(STM32F091xC) || defined(STM32F098xx) + +#define __HAL_RCC_USART7_IS_CLK_ENABLED() ((RCC->APB2ENR & (RCC_APB2ENR_USART7EN)) != RESET) +#define __HAL_RCC_USART8_IS_CLK_ENABLED() ((RCC->APB2ENR & (RCC_APB2ENR_USART8EN)) != RESET) +#define __HAL_RCC_USART7_IS_CLK_DISABLED() ((RCC->APB2ENR & (RCC_APB2ENR_USART7EN)) == RESET) +#define __HAL_RCC_USART8_IS_CLK_DISABLED() ((RCC->APB2ENR & (RCC_APB2ENR_USART8EN)) == RESET) + +#endif /* STM32F091xC || STM32F098xx */ +/** + * @} + */ + + +/** @defgroup RCCEx_HSI48_Enable_Disable RCCEx HSI48 Enable Disable + * @brief Macros to enable or disable the Internal 48Mhz High Speed oscillator (HSI48). + * @note The HSI48 is stopped by hardware when entering STOP and STANDBY modes. + * @note HSI48 can not be stopped if it is used as system clock source. In this case, + * you have to select another source of the system clock then stop the HSI14. + * @note After enabling the HSI48 with __HAL_RCC_HSI48_ENABLE(), the application software + * should wait on HSI48RDY flag to be set indicating that HSI48 clock is stable and can be + * used as system clock source. This is not necessary if HAL_RCC_OscConfig() is used. + * @note When the HSI48 is stopped, HSI48RDY flag goes low after 6 HSI48 oscillator + * clock cycles. + * @{ + */ +#if defined(RCC_HSI48_SUPPORT) + +#define __HAL_RCC_HSI48_ENABLE() SET_BIT(RCC->CR2, RCC_CR2_HSI48ON) +#define __HAL_RCC_HSI48_DISABLE() CLEAR_BIT(RCC->CR2, RCC_CR2_HSI48ON) + +/** @brief Macro to get the Internal 48Mhz High Speed oscillator (HSI48) state. + * @retval The clock source can be one of the following values: + * @arg @ref RCC_HSI48_ON HSI48 enabled + * @arg @ref RCC_HSI48_OFF HSI48 disabled + */ +#define __HAL_RCC_GET_HSI48_STATE() \ + (((uint32_t)(READ_BIT(RCC->CR2, RCC_CR2_HSI48ON)) != RESET) ? RCC_HSI48_ON : RCC_HSI48_OFF) + +#endif /* RCC_HSI48_SUPPORT */ + +/** + * @} + */ + +/** @defgroup RCCEx_Peripheral_Clock_Source_Config RCCEx Peripheral Clock Source Config + * @{ + */ +#if defined(STM32F042x6) || defined(STM32F048xx)\ + || defined(STM32F072xB) || defined(STM32F078xx)\ + || defined(STM32F070x6) || defined(STM32F070xB) + +/** @brief Macro to configure the USB clock (USBCLK). + * @param __USBCLKSOURCE__ specifies the USB clock source. + * This parameter can be one of the following values: +@if STM32F070xB +@elseif STM32F070x6 +@else + * @arg @ref RCC_USBCLKSOURCE_HSI48 HSI48 selected as USB clock +@endif + * @arg @ref RCC_USBCLKSOURCE_PLL PLL Clock selected as USB clock + */ +#define __HAL_RCC_USB_CONFIG(__USBCLKSOURCE__) \ + MODIFY_REG(RCC->CFGR3, RCC_CFGR3_USBSW, (uint32_t)(__USBCLKSOURCE__)) + +/** @brief Macro to get the USB clock source. + * @retval The clock source can be one of the following values: +@if STM32F070xB +@elseif STM32F070x6 +@else + * @arg @ref RCC_USBCLKSOURCE_HSI48 HSI48 selected as USB clock +@endif + * @arg @ref RCC_USBCLKSOURCE_PLL PLL Clock selected as USB clock + */ +#define __HAL_RCC_GET_USB_SOURCE() ((uint32_t)(READ_BIT(RCC->CFGR3, RCC_CFGR3_USBSW))) + +#endif /* STM32F042x6 || STM32F048xx || */ + /* STM32F072xB || STM32F078xx || */ + /* STM32F070x6 || STM32F070xB */ + +#if defined(STM32F042x6) || defined(STM32F048xx)\ + || defined(STM32F051x8) || defined(STM32F058xx)\ + || defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F078xx)\ + || defined(STM32F091xC) || defined(STM32F098xx) + +/** @brief Macro to configure the CEC clock. + * @param __CECCLKSOURCE__ specifies the CEC clock source. + * This parameter can be one of the following values: + * @arg @ref RCC_CECCLKSOURCE_HSI HSI selected as CEC clock + * @arg @ref RCC_CECCLKSOURCE_LSE LSE selected as CEC clock + */ +#define __HAL_RCC_CEC_CONFIG(__CECCLKSOURCE__) \ + MODIFY_REG(RCC->CFGR3, RCC_CFGR3_CECSW, (uint32_t)(__CECCLKSOURCE__)) + +/** @brief Macro to get the HDMI CEC clock source. + * @retval The clock source can be one of the following values: + * @arg @ref RCC_CECCLKSOURCE_HSI HSI selected as CEC clock + * @arg @ref RCC_CECCLKSOURCE_LSE LSE selected as CEC clock + */ +#define __HAL_RCC_GET_CEC_SOURCE() ((uint32_t)(READ_BIT(RCC->CFGR3, RCC_CFGR3_CECSW))) + +#endif /* STM32F042x6 || STM32F048xx || */ + /* STM32F051x8 || STM32F058xx || */ + /* STM32F071xB || STM32F072xB || STM32F078xx || */ + /* STM32F091xC || defined(STM32F098xx) */ + +#if defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F078xx)\ + || defined(STM32F091xC) || defined(STM32F098xx) +/** @brief Macro to configure the USART2 clock (USART2CLK). + * @param __USART2CLKSOURCE__ specifies the USART2 clock source. + * This parameter can be one of the following values: + * @arg @ref RCC_USART2CLKSOURCE_PCLK1 PCLK1 selected as USART2 clock + * @arg @ref RCC_USART2CLKSOURCE_HSI HSI selected as USART2 clock + * @arg @ref RCC_USART2CLKSOURCE_SYSCLK System Clock selected as USART2 clock + * @arg @ref RCC_USART2CLKSOURCE_LSE LSE selected as USART2 clock + */ +#define __HAL_RCC_USART2_CONFIG(__USART2CLKSOURCE__) \ + MODIFY_REG(RCC->CFGR3, RCC_CFGR3_USART2SW, (uint32_t)(__USART2CLKSOURCE__)) + +/** @brief Macro to get the USART2 clock source. + * @retval The clock source can be one of the following values: + * @arg @ref RCC_USART2CLKSOURCE_PCLK1 PCLK1 selected as USART2 clock + * @arg @ref RCC_USART2CLKSOURCE_HSI HSI selected as USART2 clock + * @arg @ref RCC_USART2CLKSOURCE_SYSCLK System Clock selected as USART2 clock + * @arg @ref RCC_USART2CLKSOURCE_LSE LSE selected as USART2 clock + */ +#define __HAL_RCC_GET_USART2_SOURCE() ((uint32_t)(READ_BIT(RCC->CFGR3, RCC_CFGR3_USART2SW))) +#endif /* STM32F071xB || STM32F072xB || STM32F078xx || STM32F091xC || STM32F098xx*/ + +#if defined(STM32F091xC) || defined(STM32F098xx) +/** @brief Macro to configure the USART3 clock (USART3CLK). + * @param __USART3CLKSOURCE__ specifies the USART3 clock source. + * This parameter can be one of the following values: + * @arg @ref RCC_USART3CLKSOURCE_PCLK1 PCLK1 selected as USART3 clock + * @arg @ref RCC_USART3CLKSOURCE_HSI HSI selected as USART3 clock + * @arg @ref RCC_USART3CLKSOURCE_SYSCLK System Clock selected as USART3 clock + * @arg @ref RCC_USART3CLKSOURCE_LSE LSE selected as USART3 clock + */ +#define __HAL_RCC_USART3_CONFIG(__USART3CLKSOURCE__) \ + MODIFY_REG(RCC->CFGR3, RCC_CFGR3_USART3SW, (uint32_t)(__USART3CLKSOURCE__)) + +/** @brief Macro to get the USART3 clock source. + * @retval The clock source can be one of the following values: + * @arg @ref RCC_USART3CLKSOURCE_PCLK1 PCLK1 selected as USART3 clock + * @arg @ref RCC_USART3CLKSOURCE_HSI HSI selected as USART3 clock + * @arg @ref RCC_USART3CLKSOURCE_SYSCLK System Clock selected as USART3 clock + * @arg @ref RCC_USART3CLKSOURCE_LSE LSE selected as USART3 clock + */ +#define __HAL_RCC_GET_USART3_SOURCE() ((uint32_t)(READ_BIT(RCC->CFGR3, RCC_CFGR3_USART3SW))) + +#endif /* STM32F091xC || STM32F098xx */ +/** + * @} + */ + +/** @defgroup RCCEx_LSE_Configuration LSE Drive Configuration + * @{ + */ + +/** + * @brief Macro to configure the External Low Speed oscillator (LSE) drive capability. + * @param __RCC_LSEDRIVE__ specifies the new state of the LSE drive capability. + * This parameter can be one of the following values: + * @arg @ref RCC_LSEDRIVE_LOW LSE oscillator low drive capability. + * @arg @ref RCC_LSEDRIVE_MEDIUMLOW LSE oscillator medium low drive capability. + * @arg @ref RCC_LSEDRIVE_MEDIUMHIGH LSE oscillator medium high drive capability. + * @arg @ref RCC_LSEDRIVE_HIGH LSE oscillator high drive capability. + * @retval None + */ +#define __HAL_RCC_LSEDRIVE_CONFIG(__RCC_LSEDRIVE__) (MODIFY_REG(RCC->BDCR,\ + RCC_BDCR_LSEDRV, (uint32_t)(__RCC_LSEDRIVE__) )) + +/** + * @} + */ + +#if defined(CRS) + +/** @defgroup RCCEx_IT_And_Flag RCCEx IT and Flag + * @{ + */ +/* Interrupt & Flag management */ + +/** + * @brief Enable the specified CRS interrupts. + * @param __INTERRUPT__ specifies the CRS interrupt sources to be enabled. + * This parameter can be any combination of the following values: + * @arg @ref RCC_CRS_IT_SYNCOK SYNC event OK interrupt + * @arg @ref RCC_CRS_IT_SYNCWARN SYNC warning interrupt + * @arg @ref RCC_CRS_IT_ERR Synchronization or trimming error interrupt + * @arg @ref RCC_CRS_IT_ESYNC Expected SYNC interrupt + * @retval None + */ +#define __HAL_RCC_CRS_ENABLE_IT(__INTERRUPT__) SET_BIT(CRS->CR, (__INTERRUPT__)) + +/** + * @brief Disable the specified CRS interrupts. + * @param __INTERRUPT__ specifies the CRS interrupt sources to be disabled. + * This parameter can be any combination of the following values: + * @arg @ref RCC_CRS_IT_SYNCOK SYNC event OK interrupt + * @arg @ref RCC_CRS_IT_SYNCWARN SYNC warning interrupt + * @arg @ref RCC_CRS_IT_ERR Synchronization or trimming error interrupt + * @arg @ref RCC_CRS_IT_ESYNC Expected SYNC interrupt + * @retval None + */ +#define __HAL_RCC_CRS_DISABLE_IT(__INTERRUPT__) CLEAR_BIT(CRS->CR, (__INTERRUPT__)) + +/** @brief Check whether the CRS interrupt has occurred or not. + * @param __INTERRUPT__ specifies the CRS interrupt source to check. + * This parameter can be one of the following values: + * @arg @ref RCC_CRS_IT_SYNCOK SYNC event OK interrupt + * @arg @ref RCC_CRS_IT_SYNCWARN SYNC warning interrupt + * @arg @ref RCC_CRS_IT_ERR Synchronization or trimming error interrupt + * @arg @ref RCC_CRS_IT_ESYNC Expected SYNC interrupt + * @retval The new state of __INTERRUPT__ (SET or RESET). + */ +#define __HAL_RCC_CRS_GET_IT_SOURCE(__INTERRUPT__) ((READ_BIT(CRS->CR, (__INTERRUPT__)) != RESET) ? SET : RESET) + +/** @brief Clear the CRS interrupt pending bits + * @param __INTERRUPT__ specifies the interrupt pending bit to clear. + * This parameter can be any combination of the following values: + * @arg @ref RCC_CRS_IT_SYNCOK SYNC event OK interrupt + * @arg @ref RCC_CRS_IT_SYNCWARN SYNC warning interrupt + * @arg @ref RCC_CRS_IT_ERR Synchronization or trimming error interrupt + * @arg @ref RCC_CRS_IT_ESYNC Expected SYNC interrupt + * @arg @ref RCC_CRS_IT_TRIMOVF Trimming overflow or underflow interrupt + * @arg @ref RCC_CRS_IT_SYNCERR SYNC error interrupt + * @arg @ref RCC_CRS_IT_SYNCMISS SYNC missed interrupt + */ +#define __HAL_RCC_CRS_CLEAR_IT(__INTERRUPT__) do { \ + if(((__INTERRUPT__) & RCC_CRS_IT_ERROR_MASK) != RESET) \ + { \ + WRITE_REG(CRS->ICR, CRS_ICR_ERRC | ((__INTERRUPT__) & ~RCC_CRS_IT_ERROR_MASK)); \ + } \ + else \ + { \ + WRITE_REG(CRS->ICR, (__INTERRUPT__)); \ + } \ + } while(0U) + +/** + * @brief Check whether the specified CRS flag is set or not. + * @param __FLAG__ specifies the flag to check. + * This parameter can be one of the following values: + * @arg @ref RCC_CRS_FLAG_SYNCOK SYNC event OK + * @arg @ref RCC_CRS_FLAG_SYNCWARN SYNC warning + * @arg @ref RCC_CRS_FLAG_ERR Error + * @arg @ref RCC_CRS_FLAG_ESYNC Expected SYNC + * @arg @ref RCC_CRS_FLAG_TRIMOVF Trimming overflow or underflow + * @arg @ref RCC_CRS_FLAG_SYNCERR SYNC error + * @arg @ref RCC_CRS_FLAG_SYNCMISS SYNC missed + * @retval The new state of _FLAG_ (TRUE or FALSE). + */ +#define __HAL_RCC_CRS_GET_FLAG(__FLAG__) (READ_BIT(CRS->ISR, (__FLAG__)) == (__FLAG__)) + +/** + * @brief Clear the CRS specified FLAG. + * @param __FLAG__ specifies the flag to clear. + * This parameter can be one of the following values: + * @arg @ref RCC_CRS_FLAG_SYNCOK SYNC event OK + * @arg @ref RCC_CRS_FLAG_SYNCWARN SYNC warning + * @arg @ref RCC_CRS_FLAG_ERR Error + * @arg @ref RCC_CRS_FLAG_ESYNC Expected SYNC + * @arg @ref RCC_CRS_FLAG_TRIMOVF Trimming overflow or underflow + * @arg @ref RCC_CRS_FLAG_SYNCERR SYNC error + * @arg @ref RCC_CRS_FLAG_SYNCMISS SYNC missed + * @note RCC_CRS_FLAG_ERR clears RCC_CRS_FLAG_TRIMOVF, RCC_CRS_FLAG_SYNCERR, RCC_CRS_FLAG_SYNCMISS and consequently RCC_CRS_FLAG_ERR + * @retval None + */ +#define __HAL_RCC_CRS_CLEAR_FLAG(__FLAG__) do { \ + if(((__FLAG__) & RCC_CRS_FLAG_ERROR_MASK) != RESET) \ + { \ + WRITE_REG(CRS->ICR, CRS_ICR_ERRC | ((__FLAG__) & ~RCC_CRS_FLAG_ERROR_MASK)); \ + } \ + else \ + { \ + WRITE_REG(CRS->ICR, (__FLAG__)); \ + } \ + } while(0U) + +/** + * @} + */ + +/** @defgroup RCCEx_CRS_Extended_Features RCCEx CRS Extended Features + * @{ + */ +/** + * @brief Enable the oscillator clock for frequency error counter. + * @note when the CEN bit is set the CRS_CFGR register becomes write-protected. + * @retval None + */ +#define __HAL_RCC_CRS_FREQ_ERROR_COUNTER_ENABLE() SET_BIT(CRS->CR, CRS_CR_CEN) + +/** + * @brief Disable the oscillator clock for frequency error counter. + * @retval None + */ +#define __HAL_RCC_CRS_FREQ_ERROR_COUNTER_DISABLE() CLEAR_BIT(CRS->CR, CRS_CR_CEN) + +/** + * @brief Enable the automatic hardware adjustement of TRIM bits. + * @note When the AUTOTRIMEN bit is set the CRS_CFGR register becomes write-protected. + * @retval None + */ +#define __HAL_RCC_CRS_AUTOMATIC_CALIB_ENABLE() SET_BIT(CRS->CR, CRS_CR_AUTOTRIMEN) + +/** + * @brief Disable the automatic hardware adjustement of TRIM bits. + * @retval None + */ +#define __HAL_RCC_CRS_AUTOMATIC_CALIB_DISABLE() CLEAR_BIT(CRS->CR, CRS_CR_AUTOTRIMEN) + +/** + * @brief Macro to calculate reload value to be set in CRS register according to target and sync frequencies + * @note The RELOAD value should be selected according to the ratio between the target frequency and the frequency + * of the synchronization source after prescaling. It is then decreased by one in order to + * reach the expected synchronization on the zero value. The formula is the following: + * RELOAD = (fTARGET / fSYNC) -1 + * @param __FTARGET__ Target frequency (value in Hz) + * @param __FSYNC__ Synchronization signal frequency (value in Hz) + * @retval None + */ +#define __HAL_RCC_CRS_RELOADVALUE_CALCULATE(__FTARGET__, __FSYNC__) (((__FTARGET__) / (__FSYNC__)) - 1U) + +/** + * @} + */ + +#endif /* CRS */ + +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup RCCEx_Exported_Functions + * @{ + */ + +/** @addtogroup RCCEx_Exported_Functions_Group1 + * @{ + */ + +HAL_StatusTypeDef HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit); +void HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit); +uint32_t HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk); + +/** + * @} + */ + +#if defined(CRS) + +/** @addtogroup RCCEx_Exported_Functions_Group3 + * @{ + */ + +void HAL_RCCEx_CRSConfig(RCC_CRSInitTypeDef *pInit); +void HAL_RCCEx_CRSSoftwareSynchronizationGenerate(void); +void HAL_RCCEx_CRSGetSynchronizationInfo(RCC_CRSSynchroInfoTypeDef *pSynchroInfo); +uint32_t HAL_RCCEx_CRSWaitSynchronization(uint32_t Timeout); +void HAL_RCCEx_CRS_IRQHandler(void); +void HAL_RCCEx_CRS_SyncOkCallback(void); +void HAL_RCCEx_CRS_SyncWarnCallback(void); +void HAL_RCCEx_CRS_ExpectedSyncCallback(void); +void HAL_RCCEx_CRS_ErrorCallback(uint32_t Error); + +/** + * @} + */ + +#endif /* CRS */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F0xx_HAL_RCC_EX_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_tim.h b/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_tim.h new file mode 100644 index 0000000..69cc007 --- /dev/null +++ b/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_tim.h @@ -0,0 +1,2040 @@ +/** + ****************************************************************************** + * @file stm32f0xx_hal_tim.h + * @author MCD Application Team + * @brief Header file of TIM HAL module. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2016 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32F0xx_HAL_TIM_H +#define STM32F0xx_HAL_TIM_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f0xx_hal_def.h" + +/** @addtogroup STM32F0xx_HAL_Driver + * @{ + */ + +/** @addtogroup TIM + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup TIM_Exported_Types TIM Exported Types + * @{ + */ + +/** + * @brief TIM Time base Configuration Structure definition + */ +typedef struct +{ + uint32_t Prescaler; /*!< Specifies the prescaler value used to divide the TIM clock. + This parameter can be a number between Min_Data = 0x0000 and Max_Data = 0xFFFF */ + + uint32_t CounterMode; /*!< Specifies the counter mode. + This parameter can be a value of @ref TIM_Counter_Mode */ + + uint32_t Period; /*!< Specifies the period value to be loaded into the active + Auto-Reload Register at the next update event. + This parameter can be a number between Min_Data = 0x0000 and Max_Data = 0xFFFF. */ + + uint32_t ClockDivision; /*!< Specifies the clock division. + This parameter can be a value of @ref TIM_ClockDivision */ + + uint32_t RepetitionCounter; /*!< Specifies the repetition counter value. Each time the RCR downcounter + reaches zero, an update event is generated and counting restarts + from the RCR value (N). + This means in PWM mode that (N+1) corresponds to: + - the number of PWM periods in edge-aligned mode + - the number of half PWM period in center-aligned mode + GP timers: this parameter must be a number between Min_Data = 0x00 and Max_Data = 0xFF. + Advanced timers: this parameter must be a number between Min_Data = 0x0000 and Max_Data = 0xFFFF. */ + + uint32_t AutoReloadPreload; /*!< Specifies the auto-reload preload. + This parameter can be a value of @ref TIM_AutoReloadPreload */ +} TIM_Base_InitTypeDef; + +/** + * @brief TIM Output Compare Configuration Structure definition + */ +typedef struct +{ + uint32_t OCMode; /*!< Specifies the TIM mode. + This parameter can be a value of @ref TIM_Output_Compare_and_PWM_modes */ + + uint32_t Pulse; /*!< Specifies the pulse value to be loaded into the Capture Compare Register. + This parameter can be a number between Min_Data = 0x0000 and Max_Data = 0xFFFF */ + + uint32_t OCPolarity; /*!< Specifies the output polarity. + This parameter can be a value of @ref TIM_Output_Compare_Polarity */ + + uint32_t OCNPolarity; /*!< Specifies the complementary output polarity. + This parameter can be a value of @ref TIM_Output_Compare_N_Polarity + @note This parameter is valid only for timer instances supporting break feature. */ + + uint32_t OCFastMode; /*!< Specifies the Fast mode state. + This parameter can be a value of @ref TIM_Output_Fast_State + @note This parameter is valid only in PWM1 and PWM2 mode. */ + + + uint32_t OCIdleState; /*!< Specifies the TIM Output Compare pin state during Idle state. + This parameter can be a value of @ref TIM_Output_Compare_Idle_State + @note This parameter is valid only for timer instances supporting break feature. */ + + uint32_t OCNIdleState; /*!< Specifies the TIM Output Compare pin state during Idle state. + This parameter can be a value of @ref TIM_Output_Compare_N_Idle_State + @note This parameter is valid only for timer instances supporting break feature. */ +} TIM_OC_InitTypeDef; + +/** + * @brief TIM One Pulse Mode Configuration Structure definition + */ +typedef struct +{ + uint32_t OCMode; /*!< Specifies the TIM mode. + This parameter can be a value of @ref TIM_Output_Compare_and_PWM_modes */ + + uint32_t Pulse; /*!< Specifies the pulse value to be loaded into the Capture Compare Register. + This parameter can be a number between Min_Data = 0x0000 and Max_Data = 0xFFFF */ + + uint32_t OCPolarity; /*!< Specifies the output polarity. + This parameter can be a value of @ref TIM_Output_Compare_Polarity */ + + uint32_t OCNPolarity; /*!< Specifies the complementary output polarity. + This parameter can be a value of @ref TIM_Output_Compare_N_Polarity + @note This parameter is valid only for timer instances supporting break feature. */ + + uint32_t OCIdleState; /*!< Specifies the TIM Output Compare pin state during Idle state. + This parameter can be a value of @ref TIM_Output_Compare_Idle_State + @note This parameter is valid only for timer instances supporting break feature. */ + + uint32_t OCNIdleState; /*!< Specifies the TIM Output Compare pin state during Idle state. + This parameter can be a value of @ref TIM_Output_Compare_N_Idle_State + @note This parameter is valid only for timer instances supporting break feature. */ + + uint32_t ICPolarity; /*!< Specifies the active edge of the input signal. + This parameter can be a value of @ref TIM_Input_Capture_Polarity */ + + uint32_t ICSelection; /*!< Specifies the input. + This parameter can be a value of @ref TIM_Input_Capture_Selection */ + + uint32_t ICFilter; /*!< Specifies the input capture filter. + This parameter can be a number between Min_Data = 0x0 and Max_Data = 0xF */ +} TIM_OnePulse_InitTypeDef; + +/** + * @brief TIM Input Capture Configuration Structure definition + */ +typedef struct +{ + uint32_t ICPolarity; /*!< Specifies the active edge of the input signal. + This parameter can be a value of @ref TIM_Input_Capture_Polarity */ + + uint32_t ICSelection; /*!< Specifies the input. + This parameter can be a value of @ref TIM_Input_Capture_Selection */ + + uint32_t ICPrescaler; /*!< Specifies the Input Capture Prescaler. + This parameter can be a value of @ref TIM_Input_Capture_Prescaler */ + + uint32_t ICFilter; /*!< Specifies the input capture filter. + This parameter can be a number between Min_Data = 0x0 and Max_Data = 0xF */ +} TIM_IC_InitTypeDef; + +/** + * @brief TIM Encoder Configuration Structure definition + */ +typedef struct +{ + uint32_t EncoderMode; /*!< Specifies the active edge of the input signal. + This parameter can be a value of @ref TIM_Encoder_Mode */ + + uint32_t IC1Polarity; /*!< Specifies the active edge of the input signal. + This parameter can be a value of @ref TIM_Encoder_Input_Polarity */ + + uint32_t IC1Selection; /*!< Specifies the input. + This parameter can be a value of @ref TIM_Input_Capture_Selection */ + + uint32_t IC1Prescaler; /*!< Specifies the Input Capture Prescaler. + This parameter can be a value of @ref TIM_Input_Capture_Prescaler */ + + uint32_t IC1Filter; /*!< Specifies the input capture filter. + This parameter can be a number between Min_Data = 0x0 and Max_Data = 0xF */ + + uint32_t IC2Polarity; /*!< Specifies the active edge of the input signal. + This parameter can be a value of @ref TIM_Encoder_Input_Polarity */ + + uint32_t IC2Selection; /*!< Specifies the input. + This parameter can be a value of @ref TIM_Input_Capture_Selection */ + + uint32_t IC2Prescaler; /*!< Specifies the Input Capture Prescaler. + This parameter can be a value of @ref TIM_Input_Capture_Prescaler */ + + uint32_t IC2Filter; /*!< Specifies the input capture filter. + This parameter can be a number between Min_Data = 0x0 and Max_Data = 0xF */ +} TIM_Encoder_InitTypeDef; + +/** + * @brief Clock Configuration Handle Structure definition + */ +typedef struct +{ + uint32_t ClockSource; /*!< TIM clock sources + This parameter can be a value of @ref TIM_Clock_Source */ + uint32_t ClockPolarity; /*!< TIM clock polarity + This parameter can be a value of @ref TIM_Clock_Polarity */ + uint32_t ClockPrescaler; /*!< TIM clock prescaler + This parameter can be a value of @ref TIM_Clock_Prescaler */ + uint32_t ClockFilter; /*!< TIM clock filter + This parameter can be a number between Min_Data = 0x0 and Max_Data = 0xF */ +} TIM_ClockConfigTypeDef; + +/** + * @brief TIM Clear Input Configuration Handle Structure definition + */ +typedef struct +{ + uint32_t ClearInputState; /*!< TIM clear Input state + This parameter can be ENABLE or DISABLE */ + uint32_t ClearInputSource; /*!< TIM clear Input sources + This parameter can be a value of @ref TIM_ClearInput_Source */ + uint32_t ClearInputPolarity; /*!< TIM Clear Input polarity + This parameter can be a value of @ref TIM_ClearInput_Polarity */ + uint32_t ClearInputPrescaler; /*!< TIM Clear Input prescaler + This parameter must be 0: When OCRef clear feature is used with ETR source, ETR prescaler must be off */ + uint32_t ClearInputFilter; /*!< TIM Clear Input filter + This parameter can be a number between Min_Data = 0x0 and Max_Data = 0xF */ +} TIM_ClearInputConfigTypeDef; + +/** + * @brief TIM Master configuration Structure definition + */ +typedef struct +{ + uint32_t MasterOutputTrigger; /*!< Trigger output (TRGO) selection + This parameter can be a value of @ref TIM_Master_Mode_Selection */ + uint32_t MasterSlaveMode; /*!< Master/slave mode selection + This parameter can be a value of @ref TIM_Master_Slave_Mode + @note When the Master/slave mode is enabled, the effect of + an event on the trigger input (TRGI) is delayed to allow a + perfect synchronization between the current timer and its + slaves (through TRGO). It is not mandatory in case of timer + synchronization mode. */ +} TIM_MasterConfigTypeDef; + +/** + * @brief TIM Slave configuration Structure definition + */ +typedef struct +{ + uint32_t SlaveMode; /*!< Slave mode selection + This parameter can be a value of @ref TIM_Slave_Mode */ + uint32_t InputTrigger; /*!< Input Trigger source + This parameter can be a value of @ref TIM_Trigger_Selection */ + uint32_t TriggerPolarity; /*!< Input Trigger polarity + This parameter can be a value of @ref TIM_Trigger_Polarity */ + uint32_t TriggerPrescaler; /*!< Input trigger prescaler + This parameter can be a value of @ref TIM_Trigger_Prescaler */ + uint32_t TriggerFilter; /*!< Input trigger filter + This parameter can be a number between Min_Data = 0x0 and Max_Data = 0xF */ + +} TIM_SlaveConfigTypeDef; + +/** + * @brief TIM Break input(s) and Dead time configuration Structure definition + * @note 2 break inputs can be configured (BKIN and BKIN2) with configurable + * filter and polarity. + */ +typedef struct +{ + uint32_t OffStateRunMode; /*!< TIM off state in run mode + This parameter can be a value of @ref TIM_OSSR_Off_State_Selection_for_Run_mode_state */ + uint32_t OffStateIDLEMode; /*!< TIM off state in IDLE mode + This parameter can be a value of @ref TIM_OSSI_Off_State_Selection_for_Idle_mode_state */ + uint32_t LockLevel; /*!< TIM Lock level + This parameter can be a value of @ref TIM_Lock_level */ + uint32_t DeadTime; /*!< TIM dead Time + This parameter can be a number between Min_Data = 0x00 and Max_Data = 0xFF */ + uint32_t BreakState; /*!< TIM Break State + This parameter can be a value of @ref TIM_Break_Input_enable_disable */ + uint32_t BreakPolarity; /*!< TIM Break input polarity + This parameter can be a value of @ref TIM_Break_Polarity */ + uint32_t BreakFilter; /*!< Specifies the break input filter. + This parameter can be a number between Min_Data = 0x0 and Max_Data = 0xF */ + uint32_t AutomaticOutput; /*!< TIM Automatic Output Enable state + This parameter can be a value of @ref TIM_AOE_Bit_Set_Reset */ +} TIM_BreakDeadTimeConfigTypeDef; + +/** + * @brief HAL State structures definition + */ +typedef enum +{ + HAL_TIM_STATE_RESET = 0x00U, /*!< Peripheral not yet initialized or disabled */ + HAL_TIM_STATE_READY = 0x01U, /*!< Peripheral Initialized and ready for use */ + HAL_TIM_STATE_BUSY = 0x02U, /*!< An internal process is ongoing */ + HAL_TIM_STATE_TIMEOUT = 0x03U, /*!< Timeout state */ + HAL_TIM_STATE_ERROR = 0x04U /*!< Reception process is ongoing */ +} HAL_TIM_StateTypeDef; + +/** + * @brief HAL Active channel structures definition + */ +typedef enum +{ + HAL_TIM_ACTIVE_CHANNEL_1 = 0x01U, /*!< The active channel is 1 */ + HAL_TIM_ACTIVE_CHANNEL_2 = 0x02U, /*!< The active channel is 2 */ + HAL_TIM_ACTIVE_CHANNEL_3 = 0x04U, /*!< The active channel is 3 */ + HAL_TIM_ACTIVE_CHANNEL_4 = 0x08U, /*!< The active channel is 4 */ + HAL_TIM_ACTIVE_CHANNEL_CLEARED = 0x00U /*!< All active channels cleared */ +} HAL_TIM_ActiveChannel; + +/** + * @brief TIM Time Base Handle Structure definition + */ +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) +typedef struct __TIM_HandleTypeDef +#else +typedef struct +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ +{ + TIM_TypeDef *Instance; /*!< Register base address */ + TIM_Base_InitTypeDef Init; /*!< TIM Time Base required parameters */ + HAL_TIM_ActiveChannel Channel; /*!< Active channel */ + DMA_HandleTypeDef *hdma[7]; /*!< DMA Handlers array + This array is accessed by a @ref DMA_Handle_index */ + HAL_LockTypeDef Lock; /*!< Locking object */ + __IO HAL_TIM_StateTypeDef State; /*!< TIM operation state */ + +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + void (* Base_MspInitCallback)(struct __TIM_HandleTypeDef *htim); /*!< TIM Base Msp Init Callback */ + void (* Base_MspDeInitCallback)(struct __TIM_HandleTypeDef *htim); /*!< TIM Base Msp DeInit Callback */ + void (* IC_MspInitCallback)(struct __TIM_HandleTypeDef *htim); /*!< TIM IC Msp Init Callback */ + void (* IC_MspDeInitCallback)(struct __TIM_HandleTypeDef *htim); /*!< TIM IC Msp DeInit Callback */ + void (* OC_MspInitCallback)(struct __TIM_HandleTypeDef *htim); /*!< TIM OC Msp Init Callback */ + void (* OC_MspDeInitCallback)(struct __TIM_HandleTypeDef *htim); /*!< TIM OC Msp DeInit Callback */ + void (* PWM_MspInitCallback)(struct __TIM_HandleTypeDef *htim); /*!< TIM PWM Msp Init Callback */ + void (* PWM_MspDeInitCallback)(struct __TIM_HandleTypeDef *htim); /*!< TIM PWM Msp DeInit Callback */ + void (* OnePulse_MspInitCallback)(struct __TIM_HandleTypeDef *htim); /*!< TIM One Pulse Msp Init Callback */ + void (* OnePulse_MspDeInitCallback)(struct __TIM_HandleTypeDef *htim); /*!< TIM One Pulse Msp DeInit Callback */ + void (* Encoder_MspInitCallback)(struct __TIM_HandleTypeDef *htim); /*!< TIM Encoder Msp Init Callback */ + void (* Encoder_MspDeInitCallback)(struct __TIM_HandleTypeDef *htim); /*!< TIM Encoder Msp DeInit Callback */ + void (* HallSensor_MspInitCallback)(struct __TIM_HandleTypeDef *htim); /*!< TIM Hall Sensor Msp Init Callback */ + void (* HallSensor_MspDeInitCallback)(struct __TIM_HandleTypeDef *htim); /*!< TIM Hall Sensor Msp DeInit Callback */ + void (* PeriodElapsedCallback)(struct __TIM_HandleTypeDef *htim); /*!< TIM Period Elapsed Callback */ + void (* PeriodElapsedHalfCpltCallback)(struct __TIM_HandleTypeDef *htim); /*!< TIM Period Elapsed half complete Callback */ + void (* TriggerCallback)(struct __TIM_HandleTypeDef *htim); /*!< TIM Trigger Callback */ + void (* TriggerHalfCpltCallback)(struct __TIM_HandleTypeDef *htim); /*!< TIM Trigger half complete Callback */ + void (* IC_CaptureCallback)(struct __TIM_HandleTypeDef *htim); /*!< TIM Input Capture Callback */ + void (* IC_CaptureHalfCpltCallback)(struct __TIM_HandleTypeDef *htim); /*!< TIM Input Capture half complete Callback */ + void (* OC_DelayElapsedCallback)(struct __TIM_HandleTypeDef *htim); /*!< TIM Output Compare Delay Elapsed Callback */ + void (* PWM_PulseFinishedCallback)(struct __TIM_HandleTypeDef *htim); /*!< TIM PWM Pulse Finished Callback */ + void (* PWM_PulseFinishedHalfCpltCallback)(struct __TIM_HandleTypeDef *htim); /*!< TIM PWM Pulse Finished half complete Callback */ + void (* ErrorCallback)(struct __TIM_HandleTypeDef *htim); /*!< TIM Error Callback */ + void (* CommutationCallback)(struct __TIM_HandleTypeDef *htim); /*!< TIM Commutation Callback */ + void (* CommutationHalfCpltCallback)(struct __TIM_HandleTypeDef *htim); /*!< TIM Commutation half complete Callback */ + void (* BreakCallback)(struct __TIM_HandleTypeDef *htim); /*!< TIM Break Callback */ +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ +} TIM_HandleTypeDef; + +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) +/** + * @brief HAL TIM Callback ID enumeration definition + */ +typedef enum +{ + HAL_TIM_BASE_MSPINIT_CB_ID = 0x00U /*!< TIM Base MspInit Callback ID */ + ,HAL_TIM_BASE_MSPDEINIT_CB_ID = 0x01U /*!< TIM Base MspDeInit Callback ID */ + ,HAL_TIM_IC_MSPINIT_CB_ID = 0x02U /*!< TIM IC MspInit Callback ID */ + ,HAL_TIM_IC_MSPDEINIT_CB_ID = 0x03U /*!< TIM IC MspDeInit Callback ID */ + ,HAL_TIM_OC_MSPINIT_CB_ID = 0x04U /*!< TIM OC MspInit Callback ID */ + ,HAL_TIM_OC_MSPDEINIT_CB_ID = 0x05U /*!< TIM OC MspDeInit Callback ID */ + ,HAL_TIM_PWM_MSPINIT_CB_ID = 0x06U /*!< TIM PWM MspInit Callback ID */ + ,HAL_TIM_PWM_MSPDEINIT_CB_ID = 0x07U /*!< TIM PWM MspDeInit Callback ID */ + ,HAL_TIM_ONE_PULSE_MSPINIT_CB_ID = 0x08U /*!< TIM One Pulse MspInit Callback ID */ + ,HAL_TIM_ONE_PULSE_MSPDEINIT_CB_ID = 0x09U /*!< TIM One Pulse MspDeInit Callback ID */ + ,HAL_TIM_ENCODER_MSPINIT_CB_ID = 0x0AU /*!< TIM Encoder MspInit Callback ID */ + ,HAL_TIM_ENCODER_MSPDEINIT_CB_ID = 0x0BU /*!< TIM Encoder MspDeInit Callback ID */ + ,HAL_TIM_HALL_SENSOR_MSPINIT_CB_ID = 0x0CU /*!< TIM Hall Sensor MspDeInit Callback ID */ + ,HAL_TIM_HALL_SENSOR_MSPDEINIT_CB_ID = 0x0DU /*!< TIM Hall Sensor MspDeInit Callback ID */ + ,HAL_TIM_PERIOD_ELAPSED_CB_ID = 0x0EU /*!< TIM Period Elapsed Callback ID */ + ,HAL_TIM_PERIOD_ELAPSED_HALF_CB_ID = 0x0FU /*!< TIM Period Elapsed half complete Callback ID */ + ,HAL_TIM_TRIGGER_CB_ID = 0x10U /*!< TIM Trigger Callback ID */ + ,HAL_TIM_TRIGGER_HALF_CB_ID = 0x11U /*!< TIM Trigger half complete Callback ID */ + + ,HAL_TIM_IC_CAPTURE_CB_ID = 0x12U /*!< TIM Input Capture Callback ID */ + ,HAL_TIM_IC_CAPTURE_HALF_CB_ID = 0x13U /*!< TIM Input Capture half complete Callback ID */ + ,HAL_TIM_OC_DELAY_ELAPSED_CB_ID = 0x14U /*!< TIM Output Compare Delay Elapsed Callback ID */ + ,HAL_TIM_PWM_PULSE_FINISHED_CB_ID = 0x15U /*!< TIM PWM Pulse Finished Callback ID */ + ,HAL_TIM_PWM_PULSE_FINISHED_HALF_CB_ID = 0x16U /*!< TIM PWM Pulse Finished half complete Callback ID */ + ,HAL_TIM_ERROR_CB_ID = 0x17U /*!< TIM Error Callback ID */ + ,HAL_TIM_COMMUTATION_CB_ID = 0x18U /*!< TIM Commutation Callback ID */ + ,HAL_TIM_COMMUTATION_HALF_CB_ID = 0x19U /*!< TIM Commutation half complete Callback ID */ + ,HAL_TIM_BREAK_CB_ID = 0x1AU /*!< TIM Break Callback ID */ +} HAL_TIM_CallbackIDTypeDef; + +/** + * @brief HAL TIM Callback pointer definition + */ +typedef void (*pTIM_CallbackTypeDef)(TIM_HandleTypeDef *htim); /*!< pointer to the TIM callback function */ + +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + +/** + * @} + */ +/* End of exported types -----------------------------------------------------*/ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup TIM_Exported_Constants TIM Exported Constants + * @{ + */ + +/** @defgroup TIM_ClearInput_Source TIM Clear Input Source + * @{ + */ +#define TIM_CLEARINPUTSOURCE_NONE 0x00000000U /*!< OCREF_CLR is disabled */ +#define TIM_CLEARINPUTSOURCE_ETR 0x00000001U /*!< OCREF_CLR is connected to ETRF input */ +#define TIM_CLEARINPUTSOURCE_OCREFCLR 0x00000002U /*!< OCREF_CLR is connected to OCREF_CLR_INT */ +/** + * @} + */ + +/** @defgroup TIM_DMA_Base_address TIM DMA Base Address + * @{ + */ +#define TIM_DMABASE_CR1 0x00000000U +#define TIM_DMABASE_CR2 0x00000001U +#define TIM_DMABASE_SMCR 0x00000002U +#define TIM_DMABASE_DIER 0x00000003U +#define TIM_DMABASE_SR 0x00000004U +#define TIM_DMABASE_EGR 0x00000005U +#define TIM_DMABASE_CCMR1 0x00000006U +#define TIM_DMABASE_CCMR2 0x00000007U +#define TIM_DMABASE_CCER 0x00000008U +#define TIM_DMABASE_CNT 0x00000009U +#define TIM_DMABASE_PSC 0x0000000AU +#define TIM_DMABASE_ARR 0x0000000BU +#define TIM_DMABASE_RCR 0x0000000CU +#define TIM_DMABASE_CCR1 0x0000000DU +#define TIM_DMABASE_CCR2 0x0000000EU +#define TIM_DMABASE_CCR3 0x0000000FU +#define TIM_DMABASE_CCR4 0x00000010U +#define TIM_DMABASE_BDTR 0x00000011U +#define TIM_DMABASE_DCR 0x00000012U +#define TIM_DMABASE_DMAR 0x00000013U +/** + * @} + */ + +/** @defgroup TIM_Event_Source TIM Event Source + * @{ + */ +#define TIM_EVENTSOURCE_UPDATE TIM_EGR_UG /*!< Reinitialize the counter and generates an update of the registers */ +#define TIM_EVENTSOURCE_CC1 TIM_EGR_CC1G /*!< A capture/compare event is generated on channel 1 */ +#define TIM_EVENTSOURCE_CC2 TIM_EGR_CC2G /*!< A capture/compare event is generated on channel 2 */ +#define TIM_EVENTSOURCE_CC3 TIM_EGR_CC3G /*!< A capture/compare event is generated on channel 3 */ +#define TIM_EVENTSOURCE_CC4 TIM_EGR_CC4G /*!< A capture/compare event is generated on channel 4 */ +#define TIM_EVENTSOURCE_COM TIM_EGR_COMG /*!< A commutation event is generated */ +#define TIM_EVENTSOURCE_TRIGGER TIM_EGR_TG /*!< A trigger event is generated */ +#define TIM_EVENTSOURCE_BREAK TIM_EGR_BG /*!< A break event is generated */ +/** + * @} + */ + +/** @defgroup TIM_Input_Channel_Polarity TIM Input Channel polarity + * @{ + */ +#define TIM_INPUTCHANNELPOLARITY_RISING 0x00000000U /*!< Polarity for TIx source */ +#define TIM_INPUTCHANNELPOLARITY_FALLING TIM_CCER_CC1P /*!< Polarity for TIx source */ +#define TIM_INPUTCHANNELPOLARITY_BOTHEDGE (TIM_CCER_CC1P | TIM_CCER_CC1NP) /*!< Polarity for TIx source */ +/** + * @} + */ + +/** @defgroup TIM_ETR_Polarity TIM ETR Polarity + * @{ + */ +#define TIM_ETRPOLARITY_INVERTED TIM_SMCR_ETP /*!< Polarity for ETR source */ +#define TIM_ETRPOLARITY_NONINVERTED 0x00000000U /*!< Polarity for ETR source */ +/** + * @} + */ + +/** @defgroup TIM_ETR_Prescaler TIM ETR Prescaler + * @{ + */ +#define TIM_ETRPRESCALER_DIV1 0x00000000U /*!< No prescaler is used */ +#define TIM_ETRPRESCALER_DIV2 TIM_SMCR_ETPS_0 /*!< ETR input source is divided by 2 */ +#define TIM_ETRPRESCALER_DIV4 TIM_SMCR_ETPS_1 /*!< ETR input source is divided by 4 */ +#define TIM_ETRPRESCALER_DIV8 TIM_SMCR_ETPS /*!< ETR input source is divided by 8 */ +/** + * @} + */ + +/** @defgroup TIM_Counter_Mode TIM Counter Mode + * @{ + */ +#define TIM_COUNTERMODE_UP 0x00000000U /*!< Counter used as up-counter */ +#define TIM_COUNTERMODE_DOWN TIM_CR1_DIR /*!< Counter used as down-counter */ +#define TIM_COUNTERMODE_CENTERALIGNED1 TIM_CR1_CMS_0 /*!< Center-aligned mode 1 */ +#define TIM_COUNTERMODE_CENTERALIGNED2 TIM_CR1_CMS_1 /*!< Center-aligned mode 2 */ +#define TIM_COUNTERMODE_CENTERALIGNED3 TIM_CR1_CMS /*!< Center-aligned mode 3 */ +/** + * @} + */ + +/** @defgroup TIM_ClockDivision TIM Clock Division + * @{ + */ +#define TIM_CLOCKDIVISION_DIV1 0x00000000U /*!< Clock division: tDTS=tCK_INT */ +#define TIM_CLOCKDIVISION_DIV2 TIM_CR1_CKD_0 /*!< Clock division: tDTS=2*tCK_INT */ +#define TIM_CLOCKDIVISION_DIV4 TIM_CR1_CKD_1 /*!< Clock division: tDTS=4*tCK_INT */ +/** + * @} + */ + +/** @defgroup TIM_Output_Compare_State TIM Output Compare State + * @{ + */ +#define TIM_OUTPUTSTATE_DISABLE 0x00000000U /*!< Capture/Compare 1 output disabled */ +#define TIM_OUTPUTSTATE_ENABLE TIM_CCER_CC1E /*!< Capture/Compare 1 output enabled */ +/** + * @} + */ + +/** @defgroup TIM_AutoReloadPreload TIM Auto-Reload Preload + * @{ + */ +#define TIM_AUTORELOAD_PRELOAD_DISABLE 0x00000000U /*!< TIMx_ARR register is not buffered */ +#define TIM_AUTORELOAD_PRELOAD_ENABLE TIM_CR1_ARPE /*!< TIMx_ARR register is buffered */ + +/** + * @} + */ + +/** @defgroup TIM_Output_Fast_State TIM Output Fast State + * @{ + */ +#define TIM_OCFAST_DISABLE 0x00000000U /*!< Output Compare fast disable */ +#define TIM_OCFAST_ENABLE TIM_CCMR1_OC1FE /*!< Output Compare fast enable */ +/** + * @} + */ + +/** @defgroup TIM_Output_Compare_N_State TIM Complementary Output Compare State + * @{ + */ +#define TIM_OUTPUTNSTATE_DISABLE 0x00000000U /*!< OCxN is disabled */ +#define TIM_OUTPUTNSTATE_ENABLE TIM_CCER_CC1NE /*!< OCxN is enabled */ +/** + * @} + */ + +/** @defgroup TIM_Output_Compare_Polarity TIM Output Compare Polarity + * @{ + */ +#define TIM_OCPOLARITY_HIGH 0x00000000U /*!< Capture/Compare output polarity */ +#define TIM_OCPOLARITY_LOW TIM_CCER_CC1P /*!< Capture/Compare output polarity */ +/** + * @} + */ + +/** @defgroup TIM_Output_Compare_N_Polarity TIM Complementary Output Compare Polarity + * @{ + */ +#define TIM_OCNPOLARITY_HIGH 0x00000000U /*!< Capture/Compare complementary output polarity */ +#define TIM_OCNPOLARITY_LOW TIM_CCER_CC1NP /*!< Capture/Compare complementary output polarity */ +/** + * @} + */ + +/** @defgroup TIM_Output_Compare_Idle_State TIM Output Compare Idle State + * @{ + */ +#define TIM_OCIDLESTATE_SET TIM_CR2_OIS1 /*!< Output Idle state: OCx=1 when MOE=0 */ +#define TIM_OCIDLESTATE_RESET 0x00000000U /*!< Output Idle state: OCx=0 when MOE=0 */ +/** + * @} + */ + +/** @defgroup TIM_Output_Compare_N_Idle_State TIM Complementary Output Compare Idle State + * @{ + */ +#define TIM_OCNIDLESTATE_SET TIM_CR2_OIS1N /*!< Complementary output Idle state: OCxN=1 when MOE=0 */ +#define TIM_OCNIDLESTATE_RESET 0x00000000U /*!< Complementary output Idle state: OCxN=0 when MOE=0 */ +/** + * @} + */ + +/** @defgroup TIM_Input_Capture_Polarity TIM Input Capture Polarity + * @{ + */ +#define TIM_ICPOLARITY_RISING TIM_INPUTCHANNELPOLARITY_RISING /*!< Capture triggered by rising edge on timer input */ +#define TIM_ICPOLARITY_FALLING TIM_INPUTCHANNELPOLARITY_FALLING /*!< Capture triggered by falling edge on timer input */ +#define TIM_ICPOLARITY_BOTHEDGE TIM_INPUTCHANNELPOLARITY_BOTHEDGE /*!< Capture triggered by both rising and falling edges on timer input*/ +/** + * @} + */ + +/** @defgroup TIM_Encoder_Input_Polarity TIM Encoder Input Polarity + * @{ + */ +#define TIM_ENCODERINPUTPOLARITY_RISING TIM_INPUTCHANNELPOLARITY_RISING /*!< Encoder input with rising edge polarity */ +#define TIM_ENCODERINPUTPOLARITY_FALLING TIM_INPUTCHANNELPOLARITY_FALLING /*!< Encoder input with falling edge polarity */ +/** + * @} + */ + +/** @defgroup TIM_Input_Capture_Selection TIM Input Capture Selection + * @{ + */ +#define TIM_ICSELECTION_DIRECTTI TIM_CCMR1_CC1S_0 /*!< TIM Input 1, 2, 3 or 4 is selected to be + connected to IC1, IC2, IC3 or IC4, respectively */ +#define TIM_ICSELECTION_INDIRECTTI TIM_CCMR1_CC1S_1 /*!< TIM Input 1, 2, 3 or 4 is selected to be + connected to IC2, IC1, IC4 or IC3, respectively */ +#define TIM_ICSELECTION_TRC TIM_CCMR1_CC1S /*!< TIM Input 1, 2, 3 or 4 is selected to be connected to TRC */ +/** + * @} + */ + +/** @defgroup TIM_Input_Capture_Prescaler TIM Input Capture Prescaler + * @{ + */ +#define TIM_ICPSC_DIV1 0x00000000U /*!< Capture performed each time an edge is detected on the capture input */ +#define TIM_ICPSC_DIV2 TIM_CCMR1_IC1PSC_0 /*!< Capture performed once every 2 events */ +#define TIM_ICPSC_DIV4 TIM_CCMR1_IC1PSC_1 /*!< Capture performed once every 4 events */ +#define TIM_ICPSC_DIV8 TIM_CCMR1_IC1PSC /*!< Capture performed once every 8 events */ +/** + * @} + */ + +/** @defgroup TIM_One_Pulse_Mode TIM One Pulse Mode + * @{ + */ +#define TIM_OPMODE_SINGLE TIM_CR1_OPM /*!< Counter stops counting at the next update event */ +#define TIM_OPMODE_REPETITIVE 0x00000000U /*!< Counter is not stopped at update event */ +/** + * @} + */ + +/** @defgroup TIM_Encoder_Mode TIM Encoder Mode + * @{ + */ +#define TIM_ENCODERMODE_TI1 TIM_SMCR_SMS_0 /*!< Quadrature encoder mode 1, x2 mode, counts up/down on TI1FP1 edge depending on TI2FP2 level */ +#define TIM_ENCODERMODE_TI2 TIM_SMCR_SMS_1 /*!< Quadrature encoder mode 2, x2 mode, counts up/down on TI2FP2 edge depending on TI1FP1 level. */ +#define TIM_ENCODERMODE_TI12 (TIM_SMCR_SMS_1 | TIM_SMCR_SMS_0) /*!< Quadrature encoder mode 3, x4 mode, counts up/down on both TI1FP1 and TI2FP2 edges depending on the level of the other input. */ +/** + * @} + */ + +/** @defgroup TIM_Interrupt_definition TIM interrupt Definition + * @{ + */ +#define TIM_IT_UPDATE TIM_DIER_UIE /*!< Update interrupt */ +#define TIM_IT_CC1 TIM_DIER_CC1IE /*!< Capture/Compare 1 interrupt */ +#define TIM_IT_CC2 TIM_DIER_CC2IE /*!< Capture/Compare 2 interrupt */ +#define TIM_IT_CC3 TIM_DIER_CC3IE /*!< Capture/Compare 3 interrupt */ +#define TIM_IT_CC4 TIM_DIER_CC4IE /*!< Capture/Compare 4 interrupt */ +#define TIM_IT_COM TIM_DIER_COMIE /*!< Commutation interrupt */ +#define TIM_IT_TRIGGER TIM_DIER_TIE /*!< Trigger interrupt */ +#define TIM_IT_BREAK TIM_DIER_BIE /*!< Break interrupt */ +/** + * @} + */ + +/** @defgroup TIM_Commutation_Source TIM Commutation Source + * @{ + */ +#define TIM_COMMUTATION_TRGI TIM_CR2_CCUS /*!< When Capture/compare control bits are preloaded, they are updated by setting the COMG bit or when an rising edge occurs on trigger input */ +#define TIM_COMMUTATION_SOFTWARE 0x00000000U /*!< When Capture/compare control bits are preloaded, they are updated by setting the COMG bit */ +/** + * @} + */ + +/** @defgroup TIM_DMA_sources TIM DMA Sources + * @{ + */ +#define TIM_DMA_UPDATE TIM_DIER_UDE /*!< DMA request is triggered by the update event */ +#define TIM_DMA_CC1 TIM_DIER_CC1DE /*!< DMA request is triggered by the capture/compare macth 1 event */ +#define TIM_DMA_CC2 TIM_DIER_CC2DE /*!< DMA request is triggered by the capture/compare macth 2 event event */ +#define TIM_DMA_CC3 TIM_DIER_CC3DE /*!< DMA request is triggered by the capture/compare macth 3 event event */ +#define TIM_DMA_CC4 TIM_DIER_CC4DE /*!< DMA request is triggered by the capture/compare macth 4 event event */ +#define TIM_DMA_COM TIM_DIER_COMDE /*!< DMA request is triggered by the commutation event */ +#define TIM_DMA_TRIGGER TIM_DIER_TDE /*!< DMA request is triggered by the trigger event */ +/** + * @} + */ + +/** @defgroup TIM_Flag_definition TIM Flag Definition + * @{ + */ +#define TIM_FLAG_UPDATE TIM_SR_UIF /*!< Update interrupt flag */ +#define TIM_FLAG_CC1 TIM_SR_CC1IF /*!< Capture/Compare 1 interrupt flag */ +#define TIM_FLAG_CC2 TIM_SR_CC2IF /*!< Capture/Compare 2 interrupt flag */ +#define TIM_FLAG_CC3 TIM_SR_CC3IF /*!< Capture/Compare 3 interrupt flag */ +#define TIM_FLAG_CC4 TIM_SR_CC4IF /*!< Capture/Compare 4 interrupt flag */ +#define TIM_FLAG_COM TIM_SR_COMIF /*!< Commutation interrupt flag */ +#define TIM_FLAG_TRIGGER TIM_SR_TIF /*!< Trigger interrupt flag */ +#define TIM_FLAG_BREAK TIM_SR_BIF /*!< Break interrupt flag */ +#define TIM_FLAG_CC1OF TIM_SR_CC1OF /*!< Capture 1 overcapture flag */ +#define TIM_FLAG_CC2OF TIM_SR_CC2OF /*!< Capture 2 overcapture flag */ +#define TIM_FLAG_CC3OF TIM_SR_CC3OF /*!< Capture 3 overcapture flag */ +#define TIM_FLAG_CC4OF TIM_SR_CC4OF /*!< Capture 4 overcapture flag */ +/** + * @} + */ + +/** @defgroup TIM_Channel TIM Channel + * @{ + */ +#define TIM_CHANNEL_1 0x00000000U /*!< Capture/compare channel 1 identifier */ +#define TIM_CHANNEL_2 0x00000004U /*!< Capture/compare channel 2 identifier */ +#define TIM_CHANNEL_3 0x00000008U /*!< Capture/compare channel 3 identifier */ +#define TIM_CHANNEL_4 0x0000000CU /*!< Capture/compare channel 4 identifier */ +#define TIM_CHANNEL_ALL 0x0000003CU /*!< Global Capture/compare channel identifier */ +/** + * @} + */ + +/** @defgroup TIM_Clock_Source TIM Clock Source + * @{ + */ +#define TIM_CLOCKSOURCE_ETRMODE2 TIM_SMCR_ETPS_1 /*!< External clock source mode 2 */ +#define TIM_CLOCKSOURCE_INTERNAL TIM_SMCR_ETPS_0 /*!< Internal clock source */ +#define TIM_CLOCKSOURCE_ITR0 TIM_TS_ITR0 /*!< External clock source mode 1 (ITR0) */ +#define TIM_CLOCKSOURCE_ITR1 TIM_TS_ITR1 /*!< External clock source mode 1 (ITR1) */ +#define TIM_CLOCKSOURCE_ITR2 TIM_TS_ITR2 /*!< External clock source mode 1 (ITR2) */ +#define TIM_CLOCKSOURCE_ITR3 TIM_TS_ITR3 /*!< External clock source mode 1 (ITR3) */ +#define TIM_CLOCKSOURCE_TI1ED TIM_TS_TI1F_ED /*!< External clock source mode 1 (TTI1FP1 + edge detect.) */ +#define TIM_CLOCKSOURCE_TI1 TIM_TS_TI1FP1 /*!< External clock source mode 1 (TTI1FP1) */ +#define TIM_CLOCKSOURCE_TI2 TIM_TS_TI2FP2 /*!< External clock source mode 1 (TTI2FP2) */ +#define TIM_CLOCKSOURCE_ETRMODE1 TIM_TS_ETRF /*!< External clock source mode 1 (ETRF) */ +/** + * @} + */ + +/** @defgroup TIM_Clock_Polarity TIM Clock Polarity + * @{ + */ +#define TIM_CLOCKPOLARITY_INVERTED TIM_ETRPOLARITY_INVERTED /*!< Polarity for ETRx clock sources */ +#define TIM_CLOCKPOLARITY_NONINVERTED TIM_ETRPOLARITY_NONINVERTED /*!< Polarity for ETRx clock sources */ +#define TIM_CLOCKPOLARITY_RISING TIM_INPUTCHANNELPOLARITY_RISING /*!< Polarity for TIx clock sources */ +#define TIM_CLOCKPOLARITY_FALLING TIM_INPUTCHANNELPOLARITY_FALLING /*!< Polarity for TIx clock sources */ +#define TIM_CLOCKPOLARITY_BOTHEDGE TIM_INPUTCHANNELPOLARITY_BOTHEDGE /*!< Polarity for TIx clock sources */ +/** + * @} + */ + +/** @defgroup TIM_Clock_Prescaler TIM Clock Prescaler + * @{ + */ +#define TIM_CLOCKPRESCALER_DIV1 TIM_ETRPRESCALER_DIV1 /*!< No prescaler is used */ +#define TIM_CLOCKPRESCALER_DIV2 TIM_ETRPRESCALER_DIV2 /*!< Prescaler for External ETR Clock: Capture performed once every 2 events. */ +#define TIM_CLOCKPRESCALER_DIV4 TIM_ETRPRESCALER_DIV4 /*!< Prescaler for External ETR Clock: Capture performed once every 4 events. */ +#define TIM_CLOCKPRESCALER_DIV8 TIM_ETRPRESCALER_DIV8 /*!< Prescaler for External ETR Clock: Capture performed once every 8 events. */ +/** + * @} + */ + +/** @defgroup TIM_ClearInput_Polarity TIM Clear Input Polarity + * @{ + */ +#define TIM_CLEARINPUTPOLARITY_INVERTED TIM_ETRPOLARITY_INVERTED /*!< Polarity for ETRx pin */ +#define TIM_CLEARINPUTPOLARITY_NONINVERTED TIM_ETRPOLARITY_NONINVERTED /*!< Polarity for ETRx pin */ +/** + * @} + */ + +/** @defgroup TIM_ClearInput_Prescaler TIM Clear Input Prescaler + * @{ + */ +#define TIM_CLEARINPUTPRESCALER_DIV1 TIM_ETRPRESCALER_DIV1 /*!< No prescaler is used */ +#define TIM_CLEARINPUTPRESCALER_DIV2 TIM_ETRPRESCALER_DIV2 /*!< Prescaler for External ETR pin: Capture performed once every 2 events. */ +#define TIM_CLEARINPUTPRESCALER_DIV4 TIM_ETRPRESCALER_DIV4 /*!< Prescaler for External ETR pin: Capture performed once every 4 events. */ +#define TIM_CLEARINPUTPRESCALER_DIV8 TIM_ETRPRESCALER_DIV8 /*!< Prescaler for External ETR pin: Capture performed once every 8 events. */ +/** + * @} + */ + +/** @defgroup TIM_OSSR_Off_State_Selection_for_Run_mode_state TIM OSSR OffState Selection for Run mode state + * @{ + */ +#define TIM_OSSR_ENABLE TIM_BDTR_OSSR /*!< When inactive, OC/OCN outputs are enabled (still controlled by the timer) */ +#define TIM_OSSR_DISABLE 0x00000000U /*!< When inactive, OC/OCN outputs are disabled (not controlled any longer by the timer) */ +/** + * @} + */ + +/** @defgroup TIM_OSSI_Off_State_Selection_for_Idle_mode_state TIM OSSI OffState Selection for Idle mode state + * @{ + */ +#define TIM_OSSI_ENABLE TIM_BDTR_OSSI /*!< When inactive, OC/OCN outputs are enabled (still controlled by the timer) */ +#define TIM_OSSI_DISABLE 0x00000000U /*!< When inactive, OC/OCN outputs are disabled (not controlled any longer by the timer) */ +/** + * @} + */ +/** @defgroup TIM_Lock_level TIM Lock level + * @{ + */ +#define TIM_LOCKLEVEL_OFF 0x00000000U /*!< LOCK OFF */ +#define TIM_LOCKLEVEL_1 TIM_BDTR_LOCK_0 /*!< LOCK Level 1 */ +#define TIM_LOCKLEVEL_2 TIM_BDTR_LOCK_1 /*!< LOCK Level 2 */ +#define TIM_LOCKLEVEL_3 TIM_BDTR_LOCK /*!< LOCK Level 3 */ +/** + * @} + */ + +/** @defgroup TIM_Break_Input_enable_disable TIM Break Input Enable + * @{ + */ +#define TIM_BREAK_ENABLE TIM_BDTR_BKE /*!< Break input BRK is enabled */ +#define TIM_BREAK_DISABLE 0x00000000U /*!< Break input BRK is disabled */ +/** + * @} + */ + +/** @defgroup TIM_Break_Polarity TIM Break Input Polarity + * @{ + */ +#define TIM_BREAKPOLARITY_LOW 0x00000000U /*!< Break input BRK is active low */ +#define TIM_BREAKPOLARITY_HIGH TIM_BDTR_BKP /*!< Break input BRK is active high */ +/** + * @} + */ + +/** @defgroup TIM_AOE_Bit_Set_Reset TIM Automatic Output Enable + * @{ + */ +#define TIM_AUTOMATICOUTPUT_DISABLE 0x00000000U /*!< MOE can be set only by software */ +#define TIM_AUTOMATICOUTPUT_ENABLE TIM_BDTR_AOE /*!< MOE can be set by software or automatically at the next update event + (if none of the break inputs BRK and BRK2 is active) */ +/** + * @} + */ + +/** @defgroup TIM_Master_Mode_Selection TIM Master Mode Selection + * @{ + */ +#define TIM_TRGO_RESET 0x00000000U /*!< TIMx_EGR.UG bit is used as trigger output (TRGO) */ +#define TIM_TRGO_ENABLE TIM_CR2_MMS_0 /*!< TIMx_CR1.CEN bit is used as trigger output (TRGO) */ +#define TIM_TRGO_UPDATE TIM_CR2_MMS_1 /*!< Update event is used as trigger output (TRGO) */ +#define TIM_TRGO_OC1 (TIM_CR2_MMS_1 | TIM_CR2_MMS_0) /*!< Capture or a compare match 1 is used as trigger output (TRGO) */ +#define TIM_TRGO_OC1REF TIM_CR2_MMS_2 /*!< OC1REF signal is used as trigger output (TRGO) */ +#define TIM_TRGO_OC2REF (TIM_CR2_MMS_2 | TIM_CR2_MMS_0) /*!< OC2REF signal is used as trigger output(TRGO) */ +#define TIM_TRGO_OC3REF (TIM_CR2_MMS_2 | TIM_CR2_MMS_1) /*!< OC3REF signal is used as trigger output(TRGO) */ +#define TIM_TRGO_OC4REF (TIM_CR2_MMS_2 | TIM_CR2_MMS_1 | TIM_CR2_MMS_0) /*!< OC4REF signal is used as trigger output(TRGO) */ +/** + * @} + */ + +/** @defgroup TIM_Master_Slave_Mode TIM Master/Slave Mode + * @{ + */ +#define TIM_MASTERSLAVEMODE_ENABLE TIM_SMCR_MSM /*!< No action */ +#define TIM_MASTERSLAVEMODE_DISABLE 0x00000000U /*!< Master/slave mode is selected */ +/** + * @} + */ + +/** @defgroup TIM_Slave_Mode TIM Slave mode + * @{ + */ +#define TIM_SLAVEMODE_DISABLE 0x00000000U /*!< Slave mode disabled */ +#define TIM_SLAVEMODE_RESET TIM_SMCR_SMS_2 /*!< Reset Mode */ +#define TIM_SLAVEMODE_GATED (TIM_SMCR_SMS_2 | TIM_SMCR_SMS_0) /*!< Gated Mode */ +#define TIM_SLAVEMODE_TRIGGER (TIM_SMCR_SMS_2 | TIM_SMCR_SMS_1) /*!< Trigger Mode */ +#define TIM_SLAVEMODE_EXTERNAL1 (TIM_SMCR_SMS_2 | TIM_SMCR_SMS_1 | TIM_SMCR_SMS_0) /*!< External Clock Mode 1 */ +/** + * @} + */ + +/** @defgroup TIM_Output_Compare_and_PWM_modes TIM Output Compare and PWM Modes + * @{ + */ +#define TIM_OCMODE_TIMING 0x00000000U /*!< Frozen */ +#define TIM_OCMODE_ACTIVE TIM_CCMR1_OC1M_0 /*!< Set channel to active level on match */ +#define TIM_OCMODE_INACTIVE TIM_CCMR1_OC1M_1 /*!< Set channel to inactive level on match */ +#define TIM_OCMODE_TOGGLE (TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_0) /*!< Toggle */ +#define TIM_OCMODE_PWM1 (TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_1) /*!< PWM mode 1 */ +#define TIM_OCMODE_PWM2 (TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_0) /*!< PWM mode 2 */ +#define TIM_OCMODE_FORCED_ACTIVE (TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_0) /*!< Force active level */ +#define TIM_OCMODE_FORCED_INACTIVE TIM_CCMR1_OC1M_2 /*!< Force inactive level */ +/** + * @} + */ + +/** @defgroup TIM_Trigger_Selection TIM Trigger Selection + * @{ + */ +#define TIM_TS_ITR0 0x00000000U /*!< Internal Trigger 0 (ITR0) */ +#define TIM_TS_ITR1 TIM_SMCR_TS_0 /*!< Internal Trigger 1 (ITR1) */ +#define TIM_TS_ITR2 TIM_SMCR_TS_1 /*!< Internal Trigger 2 (ITR2) */ +#define TIM_TS_ITR3 (TIM_SMCR_TS_0 | TIM_SMCR_TS_1) /*!< Internal Trigger 3 (ITR3) */ +#define TIM_TS_TI1F_ED TIM_SMCR_TS_2 /*!< TI1 Edge Detector (TI1F_ED) */ +#define TIM_TS_TI1FP1 (TIM_SMCR_TS_0 | TIM_SMCR_TS_2) /*!< Filtered Timer Input 1 (TI1FP1) */ +#define TIM_TS_TI2FP2 (TIM_SMCR_TS_1 | TIM_SMCR_TS_2) /*!< Filtered Timer Input 2 (TI2FP2) */ +#define TIM_TS_ETRF (TIM_SMCR_TS_0 | TIM_SMCR_TS_1 | TIM_SMCR_TS_2) /*!< Filtered External Trigger input (ETRF) */ +#define TIM_TS_NONE 0x0000FFFFU /*!< No trigger selected */ +/** + * @} + */ + +/** @defgroup TIM_Trigger_Polarity TIM Trigger Polarity + * @{ + */ +#define TIM_TRIGGERPOLARITY_INVERTED TIM_ETRPOLARITY_INVERTED /*!< Polarity for ETRx trigger sources */ +#define TIM_TRIGGERPOLARITY_NONINVERTED TIM_ETRPOLARITY_NONINVERTED /*!< Polarity for ETRx trigger sources */ +#define TIM_TRIGGERPOLARITY_RISING TIM_INPUTCHANNELPOLARITY_RISING /*!< Polarity for TIxFPx or TI1_ED trigger sources */ +#define TIM_TRIGGERPOLARITY_FALLING TIM_INPUTCHANNELPOLARITY_FALLING /*!< Polarity for TIxFPx or TI1_ED trigger sources */ +#define TIM_TRIGGERPOLARITY_BOTHEDGE TIM_INPUTCHANNELPOLARITY_BOTHEDGE /*!< Polarity for TIxFPx or TI1_ED trigger sources */ +/** + * @} + */ + +/** @defgroup TIM_Trigger_Prescaler TIM Trigger Prescaler + * @{ + */ +#define TIM_TRIGGERPRESCALER_DIV1 TIM_ETRPRESCALER_DIV1 /*!< No prescaler is used */ +#define TIM_TRIGGERPRESCALER_DIV2 TIM_ETRPRESCALER_DIV2 /*!< Prescaler for External ETR Trigger: Capture performed once every 2 events. */ +#define TIM_TRIGGERPRESCALER_DIV4 TIM_ETRPRESCALER_DIV4 /*!< Prescaler for External ETR Trigger: Capture performed once every 4 events. */ +#define TIM_TRIGGERPRESCALER_DIV8 TIM_ETRPRESCALER_DIV8 /*!< Prescaler for External ETR Trigger: Capture performed once every 8 events. */ +/** + * @} + */ + +/** @defgroup TIM_TI1_Selection TIM TI1 Input Selection + * @{ + */ +#define TIM_TI1SELECTION_CH1 0x00000000U /*!< The TIMx_CH1 pin is connected to TI1 input */ +#define TIM_TI1SELECTION_XORCOMBINATION TIM_CR2_TI1S /*!< The TIMx_CH1, CH2 and CH3 pins are connected to the TI1 input (XOR combination) */ +/** + * @} + */ + +/** @defgroup TIM_DMA_Burst_Length TIM DMA Burst Length + * @{ + */ +#define TIM_DMABURSTLENGTH_1TRANSFER 0x00000000U /*!< The transfer is done to 1 register starting trom TIMx_CR1 + TIMx_DCR.DBA */ +#define TIM_DMABURSTLENGTH_2TRANSFERS 0x00000100U /*!< The transfer is done to 2 registers starting trom TIMx_CR1 + TIMx_DCR.DBA */ +#define TIM_DMABURSTLENGTH_3TRANSFERS 0x00000200U /*!< The transfer is done to 3 registers starting trom TIMx_CR1 + TIMx_DCR.DBA */ +#define TIM_DMABURSTLENGTH_4TRANSFERS 0x00000300U /*!< The transfer is done to 4 registers starting trom TIMx_CR1 + TIMx_DCR.DBA */ +#define TIM_DMABURSTLENGTH_5TRANSFERS 0x00000400U /*!< The transfer is done to 5 registers starting trom TIMx_CR1 + TIMx_DCR.DBA */ +#define TIM_DMABURSTLENGTH_6TRANSFERS 0x00000500U /*!< The transfer is done to 6 registers starting trom TIMx_CR1 + TIMx_DCR.DBA */ +#define TIM_DMABURSTLENGTH_7TRANSFERS 0x00000600U /*!< The transfer is done to 7 registers starting trom TIMx_CR1 + TIMx_DCR.DBA */ +#define TIM_DMABURSTLENGTH_8TRANSFERS 0x00000700U /*!< The transfer is done to 8 registers starting trom TIMx_CR1 + TIMx_DCR.DBA */ +#define TIM_DMABURSTLENGTH_9TRANSFERS 0x00000800U /*!< The transfer is done to 9 registers starting trom TIMx_CR1 + TIMx_DCR.DBA */ +#define TIM_DMABURSTLENGTH_10TRANSFERS 0x00000900U /*!< The transfer is done to 10 registers starting trom TIMx_CR1 + TIMx_DCR.DBA */ +#define TIM_DMABURSTLENGTH_11TRANSFERS 0x00000A00U /*!< The transfer is done to 11 registers starting trom TIMx_CR1 + TIMx_DCR.DBA */ +#define TIM_DMABURSTLENGTH_12TRANSFERS 0x00000B00U /*!< The transfer is done to 12 registers starting trom TIMx_CR1 + TIMx_DCR.DBA */ +#define TIM_DMABURSTLENGTH_13TRANSFERS 0x00000C00U /*!< The transfer is done to 13 registers starting trom TIMx_CR1 + TIMx_DCR.DBA */ +#define TIM_DMABURSTLENGTH_14TRANSFERS 0x00000D00U /*!< The transfer is done to 14 registers starting trom TIMx_CR1 + TIMx_DCR.DBA */ +#define TIM_DMABURSTLENGTH_15TRANSFERS 0x00000E00U /*!< The transfer is done to 15 registers starting trom TIMx_CR1 + TIMx_DCR.DBA */ +#define TIM_DMABURSTLENGTH_16TRANSFERS 0x00000F00U /*!< The transfer is done to 16 registers starting trom TIMx_CR1 + TIMx_DCR.DBA */ +#define TIM_DMABURSTLENGTH_17TRANSFERS 0x00001000U /*!< The transfer is done to 17 registers starting trom TIMx_CR1 + TIMx_DCR.DBA */ +#define TIM_DMABURSTLENGTH_18TRANSFERS 0x00001100U /*!< The transfer is done to 18 registers starting trom TIMx_CR1 + TIMx_DCR.DBA */ +/** + * @} + */ + +/** @defgroup DMA_Handle_index TIM DMA Handle Index + * @{ + */ +#define TIM_DMA_ID_UPDATE ((uint16_t) 0x0000) /*!< Index of the DMA handle used for Update DMA requests */ +#define TIM_DMA_ID_CC1 ((uint16_t) 0x0001) /*!< Index of the DMA handle used for Capture/Compare 1 DMA requests */ +#define TIM_DMA_ID_CC2 ((uint16_t) 0x0002) /*!< Index of the DMA handle used for Capture/Compare 2 DMA requests */ +#define TIM_DMA_ID_CC3 ((uint16_t) 0x0003) /*!< Index of the DMA handle used for Capture/Compare 3 DMA requests */ +#define TIM_DMA_ID_CC4 ((uint16_t) 0x0004) /*!< Index of the DMA handle used for Capture/Compare 4 DMA requests */ +#define TIM_DMA_ID_COMMUTATION ((uint16_t) 0x0005) /*!< Index of the DMA handle used for Commutation DMA requests */ +#define TIM_DMA_ID_TRIGGER ((uint16_t) 0x0006) /*!< Index of the DMA handle used for Trigger DMA requests */ +/** + * @} + */ + +/** @defgroup Channel_CC_State TIM Capture/Compare Channel State + * @{ + */ +#define TIM_CCx_ENABLE 0x00000001U /*!< Input or output channel is enabled */ +#define TIM_CCx_DISABLE 0x00000000U /*!< Input or output channel is disabled */ +#define TIM_CCxN_ENABLE 0x00000004U /*!< Complementary output channel is enabled */ +#define TIM_CCxN_DISABLE 0x00000000U /*!< Complementary output channel is enabled */ +/** + * @} + */ + +/** + * @} + */ +/* End of exported constants -------------------------------------------------*/ + +/* Exported macros -----------------------------------------------------------*/ +/** @defgroup TIM_Exported_Macros TIM Exported Macros + * @{ + */ + +/** @brief Reset TIM handle state. + * @param __HANDLE__ TIM handle. + * @retval None + */ +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) +#define __HAL_TIM_RESET_HANDLE_STATE(__HANDLE__) do { \ + (__HANDLE__)->State = HAL_TIM_STATE_RESET; \ + (__HANDLE__)->Base_MspInitCallback = NULL; \ + (__HANDLE__)->Base_MspDeInitCallback = NULL; \ + (__HANDLE__)->IC_MspInitCallback = NULL; \ + (__HANDLE__)->IC_MspDeInitCallback = NULL; \ + (__HANDLE__)->OC_MspInitCallback = NULL; \ + (__HANDLE__)->OC_MspDeInitCallback = NULL; \ + (__HANDLE__)->PWM_MspInitCallback = NULL; \ + (__HANDLE__)->PWM_MspDeInitCallback = NULL; \ + (__HANDLE__)->OnePulse_MspInitCallback = NULL; \ + (__HANDLE__)->OnePulse_MspDeInitCallback = NULL; \ + (__HANDLE__)->Encoder_MspInitCallback = NULL; \ + (__HANDLE__)->Encoder_MspDeInitCallback = NULL; \ + (__HANDLE__)->HallSensor_MspInitCallback = NULL; \ + (__HANDLE__)->HallSensor_MspDeInitCallback = NULL; \ + } while(0) +#else +#define __HAL_TIM_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_TIM_STATE_RESET) +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + +/** + * @brief Enable the TIM peripheral. + * @param __HANDLE__ TIM handle + * @retval None + */ +#define __HAL_TIM_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->CR1|=(TIM_CR1_CEN)) + +/** + * @brief Enable the TIM main Output. + * @param __HANDLE__ TIM handle + * @retval None + */ +#define __HAL_TIM_MOE_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->BDTR|=(TIM_BDTR_MOE)) + +/** + * @brief Disable the TIM peripheral. + * @param __HANDLE__ TIM handle + * @retval None + */ +#define __HAL_TIM_DISABLE(__HANDLE__) \ + do { \ + if (((__HANDLE__)->Instance->CCER & TIM_CCER_CCxE_MASK) == 0UL) \ + { \ + if(((__HANDLE__)->Instance->CCER & TIM_CCER_CCxNE_MASK) == 0UL) \ + { \ + (__HANDLE__)->Instance->CR1 &= ~(TIM_CR1_CEN); \ + } \ + } \ + } while(0) + +/** + * @brief Disable the TIM main Output. + * @param __HANDLE__ TIM handle + * @retval None + * @note The Main Output Enable of a timer instance is disabled only if all the CCx and CCxN channels have been disabled + */ +#define __HAL_TIM_MOE_DISABLE(__HANDLE__) \ + do { \ + if (((__HANDLE__)->Instance->CCER & TIM_CCER_CCxE_MASK) == 0UL) \ + { \ + if(((__HANDLE__)->Instance->CCER & TIM_CCER_CCxNE_MASK) == 0UL) \ + { \ + (__HANDLE__)->Instance->BDTR &= ~(TIM_BDTR_MOE); \ + } \ + } \ + } while(0) + +/** + * @brief Disable the TIM main Output. + * @param __HANDLE__ TIM handle + * @retval None + * @note The Main Output Enable of a timer instance is disabled unconditionally + */ +#define __HAL_TIM_MOE_DISABLE_UNCONDITIONALLY(__HANDLE__) (__HANDLE__)->Instance->BDTR &= ~(TIM_BDTR_MOE) + +/** @brief Enable the specified TIM interrupt. + * @param __HANDLE__ specifies the TIM Handle. + * @param __INTERRUPT__ specifies the TIM interrupt source to enable. + * This parameter can be one of the following values: + * @arg TIM_IT_UPDATE: Update interrupt + * @arg TIM_IT_CC1: Capture/Compare 1 interrupt + * @arg TIM_IT_CC2: Capture/Compare 2 interrupt + * @arg TIM_IT_CC3: Capture/Compare 3 interrupt + * @arg TIM_IT_CC4: Capture/Compare 4 interrupt + * @arg TIM_IT_COM: Commutation interrupt + * @arg TIM_IT_TRIGGER: Trigger interrupt + * @arg TIM_IT_BREAK: Break interrupt + * @retval None + */ +#define __HAL_TIM_ENABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->DIER |= (__INTERRUPT__)) + +/** @brief Disable the specified TIM interrupt. + * @param __HANDLE__ specifies the TIM Handle. + * @param __INTERRUPT__ specifies the TIM interrupt source to disable. + * This parameter can be one of the following values: + * @arg TIM_IT_UPDATE: Update interrupt + * @arg TIM_IT_CC1: Capture/Compare 1 interrupt + * @arg TIM_IT_CC2: Capture/Compare 2 interrupt + * @arg TIM_IT_CC3: Capture/Compare 3 interrupt + * @arg TIM_IT_CC4: Capture/Compare 4 interrupt + * @arg TIM_IT_COM: Commutation interrupt + * @arg TIM_IT_TRIGGER: Trigger interrupt + * @arg TIM_IT_BREAK: Break interrupt + * @retval None + */ +#define __HAL_TIM_DISABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->DIER &= ~(__INTERRUPT__)) + +/** @brief Enable the specified DMA request. + * @param __HANDLE__ specifies the TIM Handle. + * @param __DMA__ specifies the TIM DMA request to enable. + * This parameter can be one of the following values: + * @arg TIM_DMA_UPDATE: Update DMA request + * @arg TIM_DMA_CC1: Capture/Compare 1 DMA request + * @arg TIM_DMA_CC2: Capture/Compare 2 DMA request + * @arg TIM_DMA_CC3: Capture/Compare 3 DMA request + * @arg TIM_DMA_CC4: Capture/Compare 4 DMA request + * @arg TIM_DMA_COM: Commutation DMA request + * @arg TIM_DMA_TRIGGER: Trigger DMA request + * @retval None + */ +#define __HAL_TIM_ENABLE_DMA(__HANDLE__, __DMA__) ((__HANDLE__)->Instance->DIER |= (__DMA__)) + +/** @brief Disable the specified DMA request. + * @param __HANDLE__ specifies the TIM Handle. + * @param __DMA__ specifies the TIM DMA request to disable. + * This parameter can be one of the following values: + * @arg TIM_DMA_UPDATE: Update DMA request + * @arg TIM_DMA_CC1: Capture/Compare 1 DMA request + * @arg TIM_DMA_CC2: Capture/Compare 2 DMA request + * @arg TIM_DMA_CC3: Capture/Compare 3 DMA request + * @arg TIM_DMA_CC4: Capture/Compare 4 DMA request + * @arg TIM_DMA_COM: Commutation DMA request + * @arg TIM_DMA_TRIGGER: Trigger DMA request + * @retval None + */ +#define __HAL_TIM_DISABLE_DMA(__HANDLE__, __DMA__) ((__HANDLE__)->Instance->DIER &= ~(__DMA__)) + +/** @brief Check whether the specified TIM interrupt flag is set or not. + * @param __HANDLE__ specifies the TIM Handle. + * @param __FLAG__ specifies the TIM interrupt flag to check. + * This parameter can be one of the following values: + * @arg TIM_FLAG_UPDATE: Update interrupt flag + * @arg TIM_FLAG_CC1: Capture/Compare 1 interrupt flag + * @arg TIM_FLAG_CC2: Capture/Compare 2 interrupt flag + * @arg TIM_FLAG_CC3: Capture/Compare 3 interrupt flag + * @arg TIM_FLAG_CC4: Capture/Compare 4 interrupt flag + * @arg TIM_FLAG_COM: Commutation interrupt flag + * @arg TIM_FLAG_TRIGGER: Trigger interrupt flag + * @arg TIM_FLAG_BREAK: Break interrupt flag + * @arg TIM_FLAG_CC1OF: Capture/Compare 1 overcapture flag + * @arg TIM_FLAG_CC2OF: Capture/Compare 2 overcapture flag + * @arg TIM_FLAG_CC3OF: Capture/Compare 3 overcapture flag + * @arg TIM_FLAG_CC4OF: Capture/Compare 4 overcapture flag + * @retval The new state of __FLAG__ (TRUE or FALSE). + */ +#define __HAL_TIM_GET_FLAG(__HANDLE__, __FLAG__) (((__HANDLE__)->Instance->SR &(__FLAG__)) == (__FLAG__)) + +/** @brief Clear the specified TIM interrupt flag. + * @param __HANDLE__ specifies the TIM Handle. + * @param __FLAG__ specifies the TIM interrupt flag to clear. + * This parameter can be one of the following values: + * @arg TIM_FLAG_UPDATE: Update interrupt flag + * @arg TIM_FLAG_CC1: Capture/Compare 1 interrupt flag + * @arg TIM_FLAG_CC2: Capture/Compare 2 interrupt flag + * @arg TIM_FLAG_CC3: Capture/Compare 3 interrupt flag + * @arg TIM_FLAG_CC4: Capture/Compare 4 interrupt flag + * @arg TIM_FLAG_COM: Commutation interrupt flag + * @arg TIM_FLAG_TRIGGER: Trigger interrupt flag + * @arg TIM_FLAG_BREAK: Break interrupt flag + * @arg TIM_FLAG_CC1OF: Capture/Compare 1 overcapture flag + * @arg TIM_FLAG_CC2OF: Capture/Compare 2 overcapture flag + * @arg TIM_FLAG_CC3OF: Capture/Compare 3 overcapture flag + * @arg TIM_FLAG_CC4OF: Capture/Compare 4 overcapture flag + * @retval The new state of __FLAG__ (TRUE or FALSE). + */ +#define __HAL_TIM_CLEAR_FLAG(__HANDLE__, __FLAG__) ((__HANDLE__)->Instance->SR = ~(__FLAG__)) + +/** + * @brief Check whether the specified TIM interrupt source is enabled or not. + * @param __HANDLE__ TIM handle + * @param __INTERRUPT__ specifies the TIM interrupt source to check. + * This parameter can be one of the following values: + * @arg TIM_IT_UPDATE: Update interrupt + * @arg TIM_IT_CC1: Capture/Compare 1 interrupt + * @arg TIM_IT_CC2: Capture/Compare 2 interrupt + * @arg TIM_IT_CC3: Capture/Compare 3 interrupt + * @arg TIM_IT_CC4: Capture/Compare 4 interrupt + * @arg TIM_IT_COM: Commutation interrupt + * @arg TIM_IT_TRIGGER: Trigger interrupt + * @arg TIM_IT_BREAK: Break interrupt + * @retval The state of TIM_IT (SET or RESET). + */ +#define __HAL_TIM_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) ((((__HANDLE__)->Instance->DIER & (__INTERRUPT__)) \ + == (__INTERRUPT__)) ? SET : RESET) + +/** @brief Clear the TIM interrupt pending bits. + * @param __HANDLE__ TIM handle + * @param __INTERRUPT__ specifies the interrupt pending bit to clear. + * This parameter can be one of the following values: + * @arg TIM_IT_UPDATE: Update interrupt + * @arg TIM_IT_CC1: Capture/Compare 1 interrupt + * @arg TIM_IT_CC2: Capture/Compare 2 interrupt + * @arg TIM_IT_CC3: Capture/Compare 3 interrupt + * @arg TIM_IT_CC4: Capture/Compare 4 interrupt + * @arg TIM_IT_COM: Commutation interrupt + * @arg TIM_IT_TRIGGER: Trigger interrupt + * @arg TIM_IT_BREAK: Break interrupt + * @retval None + */ +#define __HAL_TIM_CLEAR_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->SR = ~(__INTERRUPT__)) + +/** + * @brief Indicates whether or not the TIM Counter is used as downcounter. + * @param __HANDLE__ TIM handle. + * @retval False (Counter used as upcounter) or True (Counter used as downcounter) + * @note This macro is particularly useful to get the counting mode when the timer operates in Center-aligned mode or Encoder +mode. + */ +#define __HAL_TIM_IS_TIM_COUNTING_DOWN(__HANDLE__) (((__HANDLE__)->Instance->CR1 &(TIM_CR1_DIR)) == (TIM_CR1_DIR)) + +/** + * @brief Set the TIM Prescaler on runtime. + * @param __HANDLE__ TIM handle. + * @param __PRESC__ specifies the Prescaler new value. + * @retval None + */ +#define __HAL_TIM_SET_PRESCALER(__HANDLE__, __PRESC__) ((__HANDLE__)->Instance->PSC = (__PRESC__)) + +/** + * @brief Set the TIM Counter Register value on runtime. + * @param __HANDLE__ TIM handle. + * @param __COUNTER__ specifies the Counter register new value. + * @retval None + */ +#define __HAL_TIM_SET_COUNTER(__HANDLE__, __COUNTER__) ((__HANDLE__)->Instance->CNT = (__COUNTER__)) + +/** + * @brief Get the TIM Counter Register value on runtime. + * @param __HANDLE__ TIM handle. + * @retval 16-bit or 32-bit value of the timer counter register (TIMx_CNT) + */ +#define __HAL_TIM_GET_COUNTER(__HANDLE__) ((__HANDLE__)->Instance->CNT) + +/** + * @brief Set the TIM Autoreload Register value on runtime without calling another time any Init function. + * @param __HANDLE__ TIM handle. + * @param __AUTORELOAD__ specifies the Counter register new value. + * @retval None + */ +#define __HAL_TIM_SET_AUTORELOAD(__HANDLE__, __AUTORELOAD__) \ + do{ \ + (__HANDLE__)->Instance->ARR = (__AUTORELOAD__); \ + (__HANDLE__)->Init.Period = (__AUTORELOAD__); \ + } while(0) + +/** + * @brief Get the TIM Autoreload Register value on runtime. + * @param __HANDLE__ TIM handle. + * @retval 16-bit or 32-bit value of the timer auto-reload register(TIMx_ARR) + */ +#define __HAL_TIM_GET_AUTORELOAD(__HANDLE__) ((__HANDLE__)->Instance->ARR) + +/** + * @brief Set the TIM Clock Division value on runtime without calling another time any Init function. + * @param __HANDLE__ TIM handle. + * @param __CKD__ specifies the clock division value. + * This parameter can be one of the following value: + * @arg TIM_CLOCKDIVISION_DIV1: tDTS=tCK_INT + * @arg TIM_CLOCKDIVISION_DIV2: tDTS=2*tCK_INT + * @arg TIM_CLOCKDIVISION_DIV4: tDTS=4*tCK_INT + * @retval None + */ +#define __HAL_TIM_SET_CLOCKDIVISION(__HANDLE__, __CKD__) \ + do{ \ + (__HANDLE__)->Instance->CR1 &= (~TIM_CR1_CKD); \ + (__HANDLE__)->Instance->CR1 |= (__CKD__); \ + (__HANDLE__)->Init.ClockDivision = (__CKD__); \ + } while(0) + +/** + * @brief Get the TIM Clock Division value on runtime. + * @param __HANDLE__ TIM handle. + * @retval The clock division can be one of the following values: + * @arg TIM_CLOCKDIVISION_DIV1: tDTS=tCK_INT + * @arg TIM_CLOCKDIVISION_DIV2: tDTS=2*tCK_INT + * @arg TIM_CLOCKDIVISION_DIV4: tDTS=4*tCK_INT + */ +#define __HAL_TIM_GET_CLOCKDIVISION(__HANDLE__) ((__HANDLE__)->Instance->CR1 & TIM_CR1_CKD) + +/** + * @brief Set the TIM Input Capture prescaler on runtime without calling another time HAL_TIM_IC_ConfigChannel() function. + * @param __HANDLE__ TIM handle. + * @param __CHANNEL__ TIM Channels to be configured. + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @param __ICPSC__ specifies the Input Capture4 prescaler new value. + * This parameter can be one of the following values: + * @arg TIM_ICPSC_DIV1: no prescaler + * @arg TIM_ICPSC_DIV2: capture is done once every 2 events + * @arg TIM_ICPSC_DIV4: capture is done once every 4 events + * @arg TIM_ICPSC_DIV8: capture is done once every 8 events + * @retval None + */ +#define __HAL_TIM_SET_ICPRESCALER(__HANDLE__, __CHANNEL__, __ICPSC__) \ + do{ \ + TIM_RESET_ICPRESCALERVALUE((__HANDLE__), (__CHANNEL__)); \ + TIM_SET_ICPRESCALERVALUE((__HANDLE__), (__CHANNEL__), (__ICPSC__)); \ + } while(0) + +/** + * @brief Get the TIM Input Capture prescaler on runtime. + * @param __HANDLE__ TIM handle. + * @param __CHANNEL__ TIM Channels to be configured. + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: get input capture 1 prescaler value + * @arg TIM_CHANNEL_2: get input capture 2 prescaler value + * @arg TIM_CHANNEL_3: get input capture 3 prescaler value + * @arg TIM_CHANNEL_4: get input capture 4 prescaler value + * @retval The input capture prescaler can be one of the following values: + * @arg TIM_ICPSC_DIV1: no prescaler + * @arg TIM_ICPSC_DIV2: capture is done once every 2 events + * @arg TIM_ICPSC_DIV4: capture is done once every 4 events + * @arg TIM_ICPSC_DIV8: capture is done once every 8 events + */ +#define __HAL_TIM_GET_ICPRESCALER(__HANDLE__, __CHANNEL__) \ + (((__CHANNEL__) == TIM_CHANNEL_1) ? ((__HANDLE__)->Instance->CCMR1 & TIM_CCMR1_IC1PSC) :\ + ((__CHANNEL__) == TIM_CHANNEL_2) ? (((__HANDLE__)->Instance->CCMR1 & TIM_CCMR1_IC2PSC) >> 8U) :\ + ((__CHANNEL__) == TIM_CHANNEL_3) ? ((__HANDLE__)->Instance->CCMR2 & TIM_CCMR2_IC3PSC) :\ + (((__HANDLE__)->Instance->CCMR2 & TIM_CCMR2_IC4PSC)) >> 8U) + +/** + * @brief Set the TIM Capture Compare Register value on runtime without calling another time ConfigChannel function. + * @param __HANDLE__ TIM handle. + * @param __CHANNEL__ TIM Channels to be configured. + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @param __COMPARE__ specifies the Capture Compare register new value. + * @retval None + */ +#define __HAL_TIM_SET_COMPARE(__HANDLE__, __CHANNEL__, __COMPARE__) \ + (((__CHANNEL__) == TIM_CHANNEL_1) ? ((__HANDLE__)->Instance->CCR1 = (__COMPARE__)) :\ + ((__CHANNEL__) == TIM_CHANNEL_2) ? ((__HANDLE__)->Instance->CCR2 = (__COMPARE__)) :\ + ((__CHANNEL__) == TIM_CHANNEL_3) ? ((__HANDLE__)->Instance->CCR3 = (__COMPARE__)) :\ + ((__HANDLE__)->Instance->CCR4 = (__COMPARE__))) + +/** + * @brief Get the TIM Capture Compare Register value on runtime. + * @param __HANDLE__ TIM handle. + * @param __CHANNEL__ TIM Channel associated with the capture compare register + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: get capture/compare 1 register value + * @arg TIM_CHANNEL_2: get capture/compare 2 register value + * @arg TIM_CHANNEL_3: get capture/compare 3 register value + * @arg TIM_CHANNEL_4: get capture/compare 4 register value + * @retval 16-bit or 32-bit value of the capture/compare register (TIMx_CCRy) + */ +#define __HAL_TIM_GET_COMPARE(__HANDLE__, __CHANNEL__) \ + (((__CHANNEL__) == TIM_CHANNEL_1) ? ((__HANDLE__)->Instance->CCR1) :\ + ((__CHANNEL__) == TIM_CHANNEL_2) ? ((__HANDLE__)->Instance->CCR2) :\ + ((__CHANNEL__) == TIM_CHANNEL_3) ? ((__HANDLE__)->Instance->CCR3) :\ + ((__HANDLE__)->Instance->CCR4)) + +/** + * @brief Set the TIM Output compare preload. + * @param __HANDLE__ TIM handle. + * @param __CHANNEL__ TIM Channels to be configured. + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @retval None + */ +#define __HAL_TIM_ENABLE_OCxPRELOAD(__HANDLE__, __CHANNEL__) \ + (((__CHANNEL__) == TIM_CHANNEL_1) ? ((__HANDLE__)->Instance->CCMR1 |= TIM_CCMR1_OC1PE) :\ + ((__CHANNEL__) == TIM_CHANNEL_2) ? ((__HANDLE__)->Instance->CCMR1 |= TIM_CCMR1_OC2PE) :\ + ((__CHANNEL__) == TIM_CHANNEL_3) ? ((__HANDLE__)->Instance->CCMR2 |= TIM_CCMR2_OC3PE) :\ + ((__HANDLE__)->Instance->CCMR2 |= TIM_CCMR2_OC4PE)) + +/** + * @brief Reset the TIM Output compare preload. + * @param __HANDLE__ TIM handle. + * @param __CHANNEL__ TIM Channels to be configured. + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @retval None + */ +#define __HAL_TIM_DISABLE_OCxPRELOAD(__HANDLE__, __CHANNEL__) \ + (((__CHANNEL__) == TIM_CHANNEL_1) ? ((__HANDLE__)->Instance->CCMR1 &= ~TIM_CCMR1_OC1PE) :\ + ((__CHANNEL__) == TIM_CHANNEL_2) ? ((__HANDLE__)->Instance->CCMR1 &= ~TIM_CCMR1_OC2PE) :\ + ((__CHANNEL__) == TIM_CHANNEL_3) ? ((__HANDLE__)->Instance->CCMR2 &= ~TIM_CCMR2_OC3PE) :\ + ((__HANDLE__)->Instance->CCMR2 &= ~TIM_CCMR2_OC4PE)) + +/** + * @brief Enable fast mode for a given channel. + * @param __HANDLE__ TIM handle. + * @param __CHANNEL__ TIM Channels to be configured. + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @note When fast mode is enabled an active edge on the trigger input acts + * like a compare match on CCx output. Delay to sample the trigger + * input and to activate CCx output is reduced to 3 clock cycles. + * @note Fast mode acts only if the channel is configured in PWM1 or PWM2 mode. + * @retval None + */ +#define __HAL_TIM_ENABLE_OCxFAST(__HANDLE__, __CHANNEL__) \ + (((__CHANNEL__) == TIM_CHANNEL_1) ? ((__HANDLE__)->Instance->CCMR1 |= TIM_CCMR1_OC1FE) :\ + ((__CHANNEL__) == TIM_CHANNEL_2) ? ((__HANDLE__)->Instance->CCMR1 |= TIM_CCMR1_OC2FE) :\ + ((__CHANNEL__) == TIM_CHANNEL_3) ? ((__HANDLE__)->Instance->CCMR2 |= TIM_CCMR2_OC3FE) :\ + ((__HANDLE__)->Instance->CCMR2 |= TIM_CCMR2_OC4FE)) + +/** + * @brief Disable fast mode for a given channel. + * @param __HANDLE__ TIM handle. + * @param __CHANNEL__ TIM Channels to be configured. + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @note When fast mode is disabled CCx output behaves normally depending + * on counter and CCRx values even when the trigger is ON. The minimum + * delay to activate CCx output when an active edge occurs on the + * trigger input is 5 clock cycles. + * @retval None + */ +#define __HAL_TIM_DISABLE_OCxFAST(__HANDLE__, __CHANNEL__) \ + (((__CHANNEL__) == TIM_CHANNEL_1) ? ((__HANDLE__)->Instance->CCMR1 &= ~TIM_CCMR1_OC1FE) :\ + ((__CHANNEL__) == TIM_CHANNEL_2) ? ((__HANDLE__)->Instance->CCMR1 &= ~TIM_CCMR1_OC2FE) :\ + ((__CHANNEL__) == TIM_CHANNEL_3) ? ((__HANDLE__)->Instance->CCMR2 &= ~TIM_CCMR2_OC3FE) :\ + ((__HANDLE__)->Instance->CCMR2 &= ~TIM_CCMR2_OC4FE)) + +/** + * @brief Set the Update Request Source (URS) bit of the TIMx_CR1 register. + * @param __HANDLE__ TIM handle. + * @note When the URS bit of the TIMx_CR1 register is set, only counter + * overflow/underflow generates an update interrupt or DMA request (if + * enabled) + * @retval None + */ +#define __HAL_TIM_URS_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->CR1|= TIM_CR1_URS) + +/** + * @brief Reset the Update Request Source (URS) bit of the TIMx_CR1 register. + * @param __HANDLE__ TIM handle. + * @note When the URS bit of the TIMx_CR1 register is reset, any of the + * following events generate an update interrupt or DMA request (if + * enabled): + * _ Counter overflow underflow + * _ Setting the UG bit + * _ Update generation through the slave mode controller + * @retval None + */ +#define __HAL_TIM_URS_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->CR1&=~TIM_CR1_URS) + +/** + * @brief Set the TIM Capture x input polarity on runtime. + * @param __HANDLE__ TIM handle. + * @param __CHANNEL__ TIM Channels to be configured. + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @param __POLARITY__ Polarity for TIx source + * @arg TIM_INPUTCHANNELPOLARITY_RISING: Rising Edge + * @arg TIM_INPUTCHANNELPOLARITY_FALLING: Falling Edge + * @arg TIM_INPUTCHANNELPOLARITY_BOTHEDGE: Rising and Falling Edge + * @retval None + */ +#define __HAL_TIM_SET_CAPTUREPOLARITY(__HANDLE__, __CHANNEL__, __POLARITY__) \ + do{ \ + TIM_RESET_CAPTUREPOLARITY((__HANDLE__), (__CHANNEL__)); \ + TIM_SET_CAPTUREPOLARITY((__HANDLE__), (__CHANNEL__), (__POLARITY__)); \ + }while(0) + +/** + * @} + */ +/* End of exported macros ----------------------------------------------------*/ + +/* Private constants ---------------------------------------------------------*/ +/** @defgroup TIM_Private_Constants TIM Private Constants + * @{ + */ +/* The counter of a timer instance is disabled only if all the CCx and CCxN + channels have been disabled */ +#define TIM_CCER_CCxE_MASK ((uint32_t)(TIM_CCER_CC1E | TIM_CCER_CC2E | TIM_CCER_CC3E | TIM_CCER_CC4E)) +#define TIM_CCER_CCxNE_MASK ((uint32_t)(TIM_CCER_CC1NE | TIM_CCER_CC2NE | TIM_CCER_CC3NE)) +/** + * @} + */ +/* End of private constants --------------------------------------------------*/ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup TIM_Private_Macros TIM Private Macros + * @{ + */ +#define IS_TIM_CLEARINPUT_SOURCE(__MODE__) (((__MODE__) == TIM_CLEARINPUTSOURCE_NONE) || \ + ((__MODE__) == TIM_CLEARINPUTSOURCE_ETR) || \ + ((__MODE__) == TIM_CLEARINPUTSOURCE_OCREFCLR)) + +#define IS_TIM_DMA_BASE(__BASE__) (((__BASE__) == TIM_DMABASE_CR1) || \ + ((__BASE__) == TIM_DMABASE_CR2) || \ + ((__BASE__) == TIM_DMABASE_SMCR) || \ + ((__BASE__) == TIM_DMABASE_DIER) || \ + ((__BASE__) == TIM_DMABASE_SR) || \ + ((__BASE__) == TIM_DMABASE_EGR) || \ + ((__BASE__) == TIM_DMABASE_CCMR1) || \ + ((__BASE__) == TIM_DMABASE_CCMR2) || \ + ((__BASE__) == TIM_DMABASE_CCER) || \ + ((__BASE__) == TIM_DMABASE_CNT) || \ + ((__BASE__) == TIM_DMABASE_PSC) || \ + ((__BASE__) == TIM_DMABASE_ARR) || \ + ((__BASE__) == TIM_DMABASE_RCR) || \ + ((__BASE__) == TIM_DMABASE_CCR1) || \ + ((__BASE__) == TIM_DMABASE_CCR2) || \ + ((__BASE__) == TIM_DMABASE_CCR3) || \ + ((__BASE__) == TIM_DMABASE_CCR4) || \ + ((__BASE__) == TIM_DMABASE_BDTR)) + +#define IS_TIM_EVENT_SOURCE(__SOURCE__) ((((__SOURCE__) & 0xFFFFFF00U) == 0x00000000U) && ((__SOURCE__) != 0x00000000U)) + +#define IS_TIM_COUNTER_MODE(__MODE__) (((__MODE__) == TIM_COUNTERMODE_UP) || \ + ((__MODE__) == TIM_COUNTERMODE_DOWN) || \ + ((__MODE__) == TIM_COUNTERMODE_CENTERALIGNED1) || \ + ((__MODE__) == TIM_COUNTERMODE_CENTERALIGNED2) || \ + ((__MODE__) == TIM_COUNTERMODE_CENTERALIGNED3)) + +#define IS_TIM_CLOCKDIVISION_DIV(__DIV__) (((__DIV__) == TIM_CLOCKDIVISION_DIV1) || \ + ((__DIV__) == TIM_CLOCKDIVISION_DIV2) || \ + ((__DIV__) == TIM_CLOCKDIVISION_DIV4)) + +#define IS_TIM_AUTORELOAD_PRELOAD(PRELOAD) (((PRELOAD) == TIM_AUTORELOAD_PRELOAD_DISABLE) || \ + ((PRELOAD) == TIM_AUTORELOAD_PRELOAD_ENABLE)) + +#define IS_TIM_FAST_STATE(__STATE__) (((__STATE__) == TIM_OCFAST_DISABLE) || \ + ((__STATE__) == TIM_OCFAST_ENABLE)) + +#define IS_TIM_OC_POLARITY(__POLARITY__) (((__POLARITY__) == TIM_OCPOLARITY_HIGH) || \ + ((__POLARITY__) == TIM_OCPOLARITY_LOW)) + +#define IS_TIM_OCN_POLARITY(__POLARITY__) (((__POLARITY__) == TIM_OCNPOLARITY_HIGH) || \ + ((__POLARITY__) == TIM_OCNPOLARITY_LOW)) + +#define IS_TIM_OCIDLE_STATE(__STATE__) (((__STATE__) == TIM_OCIDLESTATE_SET) || \ + ((__STATE__) == TIM_OCIDLESTATE_RESET)) + +#define IS_TIM_OCNIDLE_STATE(__STATE__) (((__STATE__) == TIM_OCNIDLESTATE_SET) || \ + ((__STATE__) == TIM_OCNIDLESTATE_RESET)) + +#define IS_TIM_ENCODERINPUT_POLARITY(__POLARITY__) (((__POLARITY__) == TIM_ENCODERINPUTPOLARITY_RISING) || \ + ((__POLARITY__) == TIM_ENCODERINPUTPOLARITY_FALLING)) + +#define IS_TIM_IC_POLARITY(__POLARITY__) (((__POLARITY__) == TIM_ICPOLARITY_RISING) || \ + ((__POLARITY__) == TIM_ICPOLARITY_FALLING) || \ + ((__POLARITY__) == TIM_ICPOLARITY_BOTHEDGE)) + +#define IS_TIM_IC_SELECTION(__SELECTION__) (((__SELECTION__) == TIM_ICSELECTION_DIRECTTI) || \ + ((__SELECTION__) == TIM_ICSELECTION_INDIRECTTI) || \ + ((__SELECTION__) == TIM_ICSELECTION_TRC)) + +#define IS_TIM_IC_PRESCALER(__PRESCALER__) (((__PRESCALER__) == TIM_ICPSC_DIV1) || \ + ((__PRESCALER__) == TIM_ICPSC_DIV2) || \ + ((__PRESCALER__) == TIM_ICPSC_DIV4) || \ + ((__PRESCALER__) == TIM_ICPSC_DIV8)) + +#define IS_TIM_OPM_MODE(__MODE__) (((__MODE__) == TIM_OPMODE_SINGLE) || \ + ((__MODE__) == TIM_OPMODE_REPETITIVE)) + +#define IS_TIM_ENCODER_MODE(__MODE__) (((__MODE__) == TIM_ENCODERMODE_TI1) || \ + ((__MODE__) == TIM_ENCODERMODE_TI2) || \ + ((__MODE__) == TIM_ENCODERMODE_TI12)) + +#define IS_TIM_DMA_SOURCE(__SOURCE__) ((((__SOURCE__) & 0xFFFF80FFU) == 0x00000000U) && ((__SOURCE__) != 0x00000000U)) + +#define IS_TIM_CHANNELS(__CHANNEL__) (((__CHANNEL__) == TIM_CHANNEL_1) || \ + ((__CHANNEL__) == TIM_CHANNEL_2) || \ + ((__CHANNEL__) == TIM_CHANNEL_3) || \ + ((__CHANNEL__) == TIM_CHANNEL_4) || \ + ((__CHANNEL__) == TIM_CHANNEL_ALL)) + +#define IS_TIM_OPM_CHANNELS(__CHANNEL__) (((__CHANNEL__) == TIM_CHANNEL_1) || \ + ((__CHANNEL__) == TIM_CHANNEL_2)) + +#define IS_TIM_COMPLEMENTARY_CHANNELS(__CHANNEL__) (((__CHANNEL__) == TIM_CHANNEL_1) || \ + ((__CHANNEL__) == TIM_CHANNEL_2) || \ + ((__CHANNEL__) == TIM_CHANNEL_3)) + +#define IS_TIM_CLOCKSOURCE(__CLOCK__) (((__CLOCK__) == TIM_CLOCKSOURCE_INTERNAL) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ETRMODE2) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR0) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR1) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR2) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR3) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_TI1ED) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_TI1) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_TI2) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ETRMODE1)) + +#define IS_TIM_CLOCKPOLARITY(__POLARITY__) (((__POLARITY__) == TIM_CLOCKPOLARITY_INVERTED) || \ + ((__POLARITY__) == TIM_CLOCKPOLARITY_NONINVERTED) || \ + ((__POLARITY__) == TIM_CLOCKPOLARITY_RISING) || \ + ((__POLARITY__) == TIM_CLOCKPOLARITY_FALLING) || \ + ((__POLARITY__) == TIM_CLOCKPOLARITY_BOTHEDGE)) + +#define IS_TIM_CLOCKPRESCALER(__PRESCALER__) (((__PRESCALER__) == TIM_CLOCKPRESCALER_DIV1) || \ + ((__PRESCALER__) == TIM_CLOCKPRESCALER_DIV2) || \ + ((__PRESCALER__) == TIM_CLOCKPRESCALER_DIV4) || \ + ((__PRESCALER__) == TIM_CLOCKPRESCALER_DIV8)) + +#define IS_TIM_CLOCKFILTER(__ICFILTER__) ((__ICFILTER__) <= 0xFU) + +#define IS_TIM_CLEARINPUT_POLARITY(__POLARITY__) (((__POLARITY__) == TIM_CLEARINPUTPOLARITY_INVERTED) || \ + ((__POLARITY__) == TIM_CLEARINPUTPOLARITY_NONINVERTED)) + +#define IS_TIM_CLEARINPUT_PRESCALER(__PRESCALER__) (((__PRESCALER__) == TIM_CLEARINPUTPRESCALER_DIV1) || \ + ((__PRESCALER__) == TIM_CLEARINPUTPRESCALER_DIV2) || \ + ((__PRESCALER__) == TIM_CLEARINPUTPRESCALER_DIV4) || \ + ((__PRESCALER__) == TIM_CLEARINPUTPRESCALER_DIV8)) + +#define IS_TIM_CLEARINPUT_FILTER(__ICFILTER__) ((__ICFILTER__) <= 0xFU) + +#define IS_TIM_OSSR_STATE(__STATE__) (((__STATE__) == TIM_OSSR_ENABLE) || \ + ((__STATE__) == TIM_OSSR_DISABLE)) + +#define IS_TIM_OSSI_STATE(__STATE__) (((__STATE__) == TIM_OSSI_ENABLE) || \ + ((__STATE__) == TIM_OSSI_DISABLE)) + +#define IS_TIM_LOCK_LEVEL(__LEVEL__) (((__LEVEL__) == TIM_LOCKLEVEL_OFF) || \ + ((__LEVEL__) == TIM_LOCKLEVEL_1) || \ + ((__LEVEL__) == TIM_LOCKLEVEL_2) || \ + ((__LEVEL__) == TIM_LOCKLEVEL_3)) + +#define IS_TIM_BREAK_FILTER(__BRKFILTER__) ((__BRKFILTER__) <= 0xFUL) + + +#define IS_TIM_BREAK_STATE(__STATE__) (((__STATE__) == TIM_BREAK_ENABLE) || \ + ((__STATE__) == TIM_BREAK_DISABLE)) + +#define IS_TIM_BREAK_POLARITY(__POLARITY__) (((__POLARITY__) == TIM_BREAKPOLARITY_LOW) || \ + ((__POLARITY__) == TIM_BREAKPOLARITY_HIGH)) + +#define IS_TIM_AUTOMATIC_OUTPUT_STATE(__STATE__) (((__STATE__) == TIM_AUTOMATICOUTPUT_ENABLE) || \ + ((__STATE__) == TIM_AUTOMATICOUTPUT_DISABLE)) + +#define IS_TIM_TRGO_SOURCE(__SOURCE__) (((__SOURCE__) == TIM_TRGO_RESET) || \ + ((__SOURCE__) == TIM_TRGO_ENABLE) || \ + ((__SOURCE__) == TIM_TRGO_UPDATE) || \ + ((__SOURCE__) == TIM_TRGO_OC1) || \ + ((__SOURCE__) == TIM_TRGO_OC1REF) || \ + ((__SOURCE__) == TIM_TRGO_OC2REF) || \ + ((__SOURCE__) == TIM_TRGO_OC3REF) || \ + ((__SOURCE__) == TIM_TRGO_OC4REF)) + +#define IS_TIM_MSM_STATE(__STATE__) (((__STATE__) == TIM_MASTERSLAVEMODE_ENABLE) || \ + ((__STATE__) == TIM_MASTERSLAVEMODE_DISABLE)) + +#define IS_TIM_SLAVE_MODE(__MODE__) (((__MODE__) == TIM_SLAVEMODE_DISABLE) || \ + ((__MODE__) == TIM_SLAVEMODE_RESET) || \ + ((__MODE__) == TIM_SLAVEMODE_GATED) || \ + ((__MODE__) == TIM_SLAVEMODE_TRIGGER) || \ + ((__MODE__) == TIM_SLAVEMODE_EXTERNAL1)) + +#define IS_TIM_PWM_MODE(__MODE__) (((__MODE__) == TIM_OCMODE_PWM1) || \ + ((__MODE__) == TIM_OCMODE_PWM2)) + +#define IS_TIM_OC_MODE(__MODE__) (((__MODE__) == TIM_OCMODE_TIMING) || \ + ((__MODE__) == TIM_OCMODE_ACTIVE) || \ + ((__MODE__) == TIM_OCMODE_INACTIVE) || \ + ((__MODE__) == TIM_OCMODE_TOGGLE) || \ + ((__MODE__) == TIM_OCMODE_FORCED_ACTIVE) || \ + ((__MODE__) == TIM_OCMODE_FORCED_INACTIVE)) + +#define IS_TIM_TRIGGER_SELECTION(__SELECTION__) (((__SELECTION__) == TIM_TS_ITR0) || \ + ((__SELECTION__) == TIM_TS_ITR1) || \ + ((__SELECTION__) == TIM_TS_ITR2) || \ + ((__SELECTION__) == TIM_TS_ITR3) || \ + ((__SELECTION__) == TIM_TS_TI1F_ED) || \ + ((__SELECTION__) == TIM_TS_TI1FP1) || \ + ((__SELECTION__) == TIM_TS_TI2FP2) || \ + ((__SELECTION__) == TIM_TS_ETRF)) + +#define IS_TIM_INTERNAL_TRIGGEREVENT_SELECTION(__SELECTION__) (((__SELECTION__) == TIM_TS_ITR0) || \ + ((__SELECTION__) == TIM_TS_ITR1) || \ + ((__SELECTION__) == TIM_TS_ITR2) || \ + ((__SELECTION__) == TIM_TS_ITR3) || \ + ((__SELECTION__) == TIM_TS_NONE)) + +#define IS_TIM_TRIGGERPOLARITY(__POLARITY__) (((__POLARITY__) == TIM_TRIGGERPOLARITY_INVERTED ) || \ + ((__POLARITY__) == TIM_TRIGGERPOLARITY_NONINVERTED) || \ + ((__POLARITY__) == TIM_TRIGGERPOLARITY_RISING ) || \ + ((__POLARITY__) == TIM_TRIGGERPOLARITY_FALLING ) || \ + ((__POLARITY__) == TIM_TRIGGERPOLARITY_BOTHEDGE )) + +#define IS_TIM_TRIGGERPRESCALER(__PRESCALER__) (((__PRESCALER__) == TIM_TRIGGERPRESCALER_DIV1) || \ + ((__PRESCALER__) == TIM_TRIGGERPRESCALER_DIV2) || \ + ((__PRESCALER__) == TIM_TRIGGERPRESCALER_DIV4) || \ + ((__PRESCALER__) == TIM_TRIGGERPRESCALER_DIV8)) + +#define IS_TIM_TRIGGERFILTER(__ICFILTER__) ((__ICFILTER__) <= 0xFU) + +#define IS_TIM_TI1SELECTION(__TI1SELECTION__) (((__TI1SELECTION__) == TIM_TI1SELECTION_CH1) || \ + ((__TI1SELECTION__) == TIM_TI1SELECTION_XORCOMBINATION)) + +#define IS_TIM_DMA_LENGTH(__LENGTH__) (((__LENGTH__) == TIM_DMABURSTLENGTH_1TRANSFER) || \ + ((__LENGTH__) == TIM_DMABURSTLENGTH_2TRANSFERS) || \ + ((__LENGTH__) == TIM_DMABURSTLENGTH_3TRANSFERS) || \ + ((__LENGTH__) == TIM_DMABURSTLENGTH_4TRANSFERS) || \ + ((__LENGTH__) == TIM_DMABURSTLENGTH_5TRANSFERS) || \ + ((__LENGTH__) == TIM_DMABURSTLENGTH_6TRANSFERS) || \ + ((__LENGTH__) == TIM_DMABURSTLENGTH_7TRANSFERS) || \ + ((__LENGTH__) == TIM_DMABURSTLENGTH_8TRANSFERS) || \ + ((__LENGTH__) == TIM_DMABURSTLENGTH_9TRANSFERS) || \ + ((__LENGTH__) == TIM_DMABURSTLENGTH_10TRANSFERS) || \ + ((__LENGTH__) == TIM_DMABURSTLENGTH_11TRANSFERS) || \ + ((__LENGTH__) == TIM_DMABURSTLENGTH_12TRANSFERS) || \ + ((__LENGTH__) == TIM_DMABURSTLENGTH_13TRANSFERS) || \ + ((__LENGTH__) == TIM_DMABURSTLENGTH_14TRANSFERS) || \ + ((__LENGTH__) == TIM_DMABURSTLENGTH_15TRANSFERS) || \ + ((__LENGTH__) == TIM_DMABURSTLENGTH_16TRANSFERS) || \ + ((__LENGTH__) == TIM_DMABURSTLENGTH_17TRANSFERS) || \ + ((__LENGTH__) == TIM_DMABURSTLENGTH_18TRANSFERS)) + +#define IS_TIM_DMA_DATA_LENGTH(LENGTH) (((LENGTH) >= 0x1U) && ((LENGTH) < 0x10000U)) + +#define IS_TIM_IC_FILTER(__ICFILTER__) ((__ICFILTER__) <= 0xFU) + +#define IS_TIM_DEADTIME(__DEADTIME__) ((__DEADTIME__) <= 0xFFU) + +#define IS_TIM_SLAVEMODE_TRIGGER_ENABLED(__TRIGGER__) ((__TRIGGER__) == TIM_SLAVEMODE_TRIGGER) + +#define TIM_SET_ICPRESCALERVALUE(__HANDLE__, __CHANNEL__, __ICPSC__) \ + (((__CHANNEL__) == TIM_CHANNEL_1) ? ((__HANDLE__)->Instance->CCMR1 |= (__ICPSC__)) :\ + ((__CHANNEL__) == TIM_CHANNEL_2) ? ((__HANDLE__)->Instance->CCMR1 |= ((__ICPSC__) << 8U)) :\ + ((__CHANNEL__) == TIM_CHANNEL_3) ? ((__HANDLE__)->Instance->CCMR2 |= (__ICPSC__)) :\ + ((__HANDLE__)->Instance->CCMR2 |= ((__ICPSC__) << 8U))) + +#define TIM_RESET_ICPRESCALERVALUE(__HANDLE__, __CHANNEL__) \ + (((__CHANNEL__) == TIM_CHANNEL_1) ? ((__HANDLE__)->Instance->CCMR1 &= ~TIM_CCMR1_IC1PSC) :\ + ((__CHANNEL__) == TIM_CHANNEL_2) ? ((__HANDLE__)->Instance->CCMR1 &= ~TIM_CCMR1_IC2PSC) :\ + ((__CHANNEL__) == TIM_CHANNEL_3) ? ((__HANDLE__)->Instance->CCMR2 &= ~TIM_CCMR2_IC3PSC) :\ + ((__HANDLE__)->Instance->CCMR2 &= ~TIM_CCMR2_IC4PSC)) + +#define TIM_SET_CAPTUREPOLARITY(__HANDLE__, __CHANNEL__, __POLARITY__) \ + (((__CHANNEL__) == TIM_CHANNEL_1) ? ((__HANDLE__)->Instance->CCER |= (__POLARITY__)) :\ + ((__CHANNEL__) == TIM_CHANNEL_2) ? ((__HANDLE__)->Instance->CCER |= ((__POLARITY__) << 4U)) :\ + ((__CHANNEL__) == TIM_CHANNEL_3) ? ((__HANDLE__)->Instance->CCER |= ((__POLARITY__) << 8U)) :\ + ((__HANDLE__)->Instance->CCER |= (((__POLARITY__) << 12U)))) + +#define TIM_RESET_CAPTUREPOLARITY(__HANDLE__, __CHANNEL__) \ + (((__CHANNEL__) == TIM_CHANNEL_1) ? ((__HANDLE__)->Instance->CCER &= ~(TIM_CCER_CC1P | TIM_CCER_CC1NP)) :\ + ((__CHANNEL__) == TIM_CHANNEL_2) ? ((__HANDLE__)->Instance->CCER &= ~(TIM_CCER_CC2P | TIM_CCER_CC2NP)) :\ + ((__CHANNEL__) == TIM_CHANNEL_3) ? ((__HANDLE__)->Instance->CCER &= ~(TIM_CCER_CC3P | TIM_CCER_CC3NP)) :\ + ((__HANDLE__)->Instance->CCER &= ~(TIM_CCER_CC4P | TIM_CCER_CC4NP))) + +/** + * @} + */ +/* End of private macros -----------------------------------------------------*/ + +/* Include TIM HAL Extended module */ +#include "stm32f0xx_hal_tim_ex.h" + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup TIM_Exported_Functions TIM Exported Functions + * @{ + */ + +/** @addtogroup TIM_Exported_Functions_Group1 TIM Time Base functions + * @brief Time Base functions + * @{ + */ +/* Time Base functions ********************************************************/ +HAL_StatusTypeDef HAL_TIM_Base_Init(TIM_HandleTypeDef *htim); +HAL_StatusTypeDef HAL_TIM_Base_DeInit(TIM_HandleTypeDef *htim); +void HAL_TIM_Base_MspInit(TIM_HandleTypeDef *htim); +void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef *htim); +/* Blocking mode: Polling */ +HAL_StatusTypeDef HAL_TIM_Base_Start(TIM_HandleTypeDef *htim); +HAL_StatusTypeDef HAL_TIM_Base_Stop(TIM_HandleTypeDef *htim); +/* Non-Blocking mode: Interrupt */ +HAL_StatusTypeDef HAL_TIM_Base_Start_IT(TIM_HandleTypeDef *htim); +HAL_StatusTypeDef HAL_TIM_Base_Stop_IT(TIM_HandleTypeDef *htim); +/* Non-Blocking mode: DMA */ +HAL_StatusTypeDef HAL_TIM_Base_Start_DMA(TIM_HandleTypeDef *htim, uint32_t *pData, uint16_t Length); +HAL_StatusTypeDef HAL_TIM_Base_Stop_DMA(TIM_HandleTypeDef *htim); +/** + * @} + */ + +/** @addtogroup TIM_Exported_Functions_Group2 TIM Output Compare functions + * @brief TIM Output Compare functions + * @{ + */ +/* Timer Output Compare functions *********************************************/ +HAL_StatusTypeDef HAL_TIM_OC_Init(TIM_HandleTypeDef *htim); +HAL_StatusTypeDef HAL_TIM_OC_DeInit(TIM_HandleTypeDef *htim); +void HAL_TIM_OC_MspInit(TIM_HandleTypeDef *htim); +void HAL_TIM_OC_MspDeInit(TIM_HandleTypeDef *htim); +/* Blocking mode: Polling */ +HAL_StatusTypeDef HAL_TIM_OC_Start(TIM_HandleTypeDef *htim, uint32_t Channel); +HAL_StatusTypeDef HAL_TIM_OC_Stop(TIM_HandleTypeDef *htim, uint32_t Channel); +/* Non-Blocking mode: Interrupt */ +HAL_StatusTypeDef HAL_TIM_OC_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel); +HAL_StatusTypeDef HAL_TIM_OC_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channel); +/* Non-Blocking mode: DMA */ +HAL_StatusTypeDef HAL_TIM_OC_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Channel, uint32_t *pData, uint16_t Length); +HAL_StatusTypeDef HAL_TIM_OC_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Channel); +/** + * @} + */ + +/** @addtogroup TIM_Exported_Functions_Group3 TIM PWM functions + * @brief TIM PWM functions + * @{ + */ +/* Timer PWM functions ********************************************************/ +HAL_StatusTypeDef HAL_TIM_PWM_Init(TIM_HandleTypeDef *htim); +HAL_StatusTypeDef HAL_TIM_PWM_DeInit(TIM_HandleTypeDef *htim); +void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef *htim); +void HAL_TIM_PWM_MspDeInit(TIM_HandleTypeDef *htim); +/* Blocking mode: Polling */ +HAL_StatusTypeDef HAL_TIM_PWM_Start(TIM_HandleTypeDef *htim, uint32_t Channel); +HAL_StatusTypeDef HAL_TIM_PWM_Stop(TIM_HandleTypeDef *htim, uint32_t Channel); +/* Non-Blocking mode: Interrupt */ +HAL_StatusTypeDef HAL_TIM_PWM_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel); +HAL_StatusTypeDef HAL_TIM_PWM_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channel); +/* Non-Blocking mode: DMA */ +HAL_StatusTypeDef HAL_TIM_PWM_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Channel, uint32_t *pData, uint16_t Length); +HAL_StatusTypeDef HAL_TIM_PWM_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Channel); +/** + * @} + */ + +/** @addtogroup TIM_Exported_Functions_Group4 TIM Input Capture functions + * @brief TIM Input Capture functions + * @{ + */ +/* Timer Input Capture functions **********************************************/ +HAL_StatusTypeDef HAL_TIM_IC_Init(TIM_HandleTypeDef *htim); +HAL_StatusTypeDef HAL_TIM_IC_DeInit(TIM_HandleTypeDef *htim); +void HAL_TIM_IC_MspInit(TIM_HandleTypeDef *htim); +void HAL_TIM_IC_MspDeInit(TIM_HandleTypeDef *htim); +/* Blocking mode: Polling */ +HAL_StatusTypeDef HAL_TIM_IC_Start(TIM_HandleTypeDef *htim, uint32_t Channel); +HAL_StatusTypeDef HAL_TIM_IC_Stop(TIM_HandleTypeDef *htim, uint32_t Channel); +/* Non-Blocking mode: Interrupt */ +HAL_StatusTypeDef HAL_TIM_IC_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel); +HAL_StatusTypeDef HAL_TIM_IC_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channel); +/* Non-Blocking mode: DMA */ +HAL_StatusTypeDef HAL_TIM_IC_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Channel, uint32_t *pData, uint16_t Length); +HAL_StatusTypeDef HAL_TIM_IC_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Channel); +/** + * @} + */ + +/** @addtogroup TIM_Exported_Functions_Group5 TIM One Pulse functions + * @brief TIM One Pulse functions + * @{ + */ +/* Timer One Pulse functions **************************************************/ +HAL_StatusTypeDef HAL_TIM_OnePulse_Init(TIM_HandleTypeDef *htim, uint32_t OnePulseMode); +HAL_StatusTypeDef HAL_TIM_OnePulse_DeInit(TIM_HandleTypeDef *htim); +void HAL_TIM_OnePulse_MspInit(TIM_HandleTypeDef *htim); +void HAL_TIM_OnePulse_MspDeInit(TIM_HandleTypeDef *htim); +/* Blocking mode: Polling */ +HAL_StatusTypeDef HAL_TIM_OnePulse_Start(TIM_HandleTypeDef *htim, uint32_t OutputChannel); +HAL_StatusTypeDef HAL_TIM_OnePulse_Stop(TIM_HandleTypeDef *htim, uint32_t OutputChannel); +/* Non-Blocking mode: Interrupt */ +HAL_StatusTypeDef HAL_TIM_OnePulse_Start_IT(TIM_HandleTypeDef *htim, uint32_t OutputChannel); +HAL_StatusTypeDef HAL_TIM_OnePulse_Stop_IT(TIM_HandleTypeDef *htim, uint32_t OutputChannel); +/** + * @} + */ + +/** @addtogroup TIM_Exported_Functions_Group6 TIM Encoder functions + * @brief TIM Encoder functions + * @{ + */ +/* Timer Encoder functions ****************************************************/ +HAL_StatusTypeDef HAL_TIM_Encoder_Init(TIM_HandleTypeDef *htim, TIM_Encoder_InitTypeDef *sConfig); +HAL_StatusTypeDef HAL_TIM_Encoder_DeInit(TIM_HandleTypeDef *htim); +void HAL_TIM_Encoder_MspInit(TIM_HandleTypeDef *htim); +void HAL_TIM_Encoder_MspDeInit(TIM_HandleTypeDef *htim); +/* Blocking mode: Polling */ +HAL_StatusTypeDef HAL_TIM_Encoder_Start(TIM_HandleTypeDef *htim, uint32_t Channel); +HAL_StatusTypeDef HAL_TIM_Encoder_Stop(TIM_HandleTypeDef *htim, uint32_t Channel); +/* Non-Blocking mode: Interrupt */ +HAL_StatusTypeDef HAL_TIM_Encoder_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel); +HAL_StatusTypeDef HAL_TIM_Encoder_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channel); +/* Non-Blocking mode: DMA */ +HAL_StatusTypeDef HAL_TIM_Encoder_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Channel, uint32_t *pData1, + uint32_t *pData2, uint16_t Length); +HAL_StatusTypeDef HAL_TIM_Encoder_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Channel); +/** + * @} + */ + +/** @addtogroup TIM_Exported_Functions_Group7 TIM IRQ handler management + * @brief IRQ handler management + * @{ + */ +/* Interrupt Handler functions ***********************************************/ +void HAL_TIM_IRQHandler(TIM_HandleTypeDef *htim); +/** + * @} + */ + +/** @defgroup TIM_Exported_Functions_Group8 TIM Peripheral Control functions + * @brief Peripheral Control functions + * @{ + */ +/* Control functions *********************************************************/ +HAL_StatusTypeDef HAL_TIM_OC_ConfigChannel(TIM_HandleTypeDef *htim, TIM_OC_InitTypeDef *sConfig, uint32_t Channel); +HAL_StatusTypeDef HAL_TIM_PWM_ConfigChannel(TIM_HandleTypeDef *htim, TIM_OC_InitTypeDef *sConfig, uint32_t Channel); +HAL_StatusTypeDef HAL_TIM_IC_ConfigChannel(TIM_HandleTypeDef *htim, TIM_IC_InitTypeDef *sConfig, uint32_t Channel); +HAL_StatusTypeDef HAL_TIM_OnePulse_ConfigChannel(TIM_HandleTypeDef *htim, TIM_OnePulse_InitTypeDef *sConfig, + uint32_t OutputChannel, uint32_t InputChannel); +HAL_StatusTypeDef HAL_TIM_ConfigOCrefClear(TIM_HandleTypeDef *htim, TIM_ClearInputConfigTypeDef *sClearInputConfig, + uint32_t Channel); +HAL_StatusTypeDef HAL_TIM_ConfigClockSource(TIM_HandleTypeDef *htim, TIM_ClockConfigTypeDef *sClockSourceConfig); +HAL_StatusTypeDef HAL_TIM_ConfigTI1Input(TIM_HandleTypeDef *htim, uint32_t TI1_Selection); +HAL_StatusTypeDef HAL_TIM_SlaveConfigSynchro(TIM_HandleTypeDef *htim, TIM_SlaveConfigTypeDef *sSlaveConfig); +HAL_StatusTypeDef HAL_TIM_SlaveConfigSynchro_IT(TIM_HandleTypeDef *htim, TIM_SlaveConfigTypeDef *sSlaveConfig); +HAL_StatusTypeDef HAL_TIM_DMABurst_WriteStart(TIM_HandleTypeDef *htim, uint32_t BurstBaseAddress, + uint32_t BurstRequestSrc, uint32_t *BurstBuffer, uint32_t BurstLength); +HAL_StatusTypeDef HAL_TIM_DMABurst_MultiWriteStart(TIM_HandleTypeDef *htim, uint32_t BurstBaseAddress, + uint32_t BurstRequestSrc, uint32_t *BurstBuffer, uint32_t BurstLength, + uint32_t DataLength); +HAL_StatusTypeDef HAL_TIM_DMABurst_WriteStop(TIM_HandleTypeDef *htim, uint32_t BurstRequestSrc); +HAL_StatusTypeDef HAL_TIM_DMABurst_ReadStart(TIM_HandleTypeDef *htim, uint32_t BurstBaseAddress, + uint32_t BurstRequestSrc, uint32_t *BurstBuffer, uint32_t BurstLength); +HAL_StatusTypeDef HAL_TIM_DMABurst_MultiReadStart(TIM_HandleTypeDef *htim, uint32_t BurstBaseAddress, + uint32_t BurstRequestSrc, uint32_t *BurstBuffer, uint32_t BurstLength, + uint32_t DataLength); +HAL_StatusTypeDef HAL_TIM_DMABurst_ReadStop(TIM_HandleTypeDef *htim, uint32_t BurstRequestSrc); +HAL_StatusTypeDef HAL_TIM_GenerateEvent(TIM_HandleTypeDef *htim, uint32_t EventSource); +uint32_t HAL_TIM_ReadCapturedValue(TIM_HandleTypeDef *htim, uint32_t Channel); +/** + * @} + */ + +/** @defgroup TIM_Exported_Functions_Group9 TIM Callbacks functions + * @brief TIM Callbacks functions + * @{ + */ +/* Callback in non blocking modes (Interrupt and DMA) *************************/ +void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim); +void HAL_TIM_PeriodElapsedHalfCpltCallback(TIM_HandleTypeDef *htim); +void HAL_TIM_OC_DelayElapsedCallback(TIM_HandleTypeDef *htim); +void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim); +void HAL_TIM_IC_CaptureHalfCpltCallback(TIM_HandleTypeDef *htim); +void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim); +void HAL_TIM_PWM_PulseFinishedHalfCpltCallback(TIM_HandleTypeDef *htim); +void HAL_TIM_TriggerCallback(TIM_HandleTypeDef *htim); +void HAL_TIM_TriggerHalfCpltCallback(TIM_HandleTypeDef *htim); +void HAL_TIM_ErrorCallback(TIM_HandleTypeDef *htim); + +/* Callbacks Register/UnRegister functions ***********************************/ +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) +HAL_StatusTypeDef HAL_TIM_RegisterCallback(TIM_HandleTypeDef *htim, HAL_TIM_CallbackIDTypeDef CallbackID, + pTIM_CallbackTypeDef pCallback); +HAL_StatusTypeDef HAL_TIM_UnRegisterCallback(TIM_HandleTypeDef *htim, HAL_TIM_CallbackIDTypeDef CallbackID); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + +/** + * @} + */ + +/** @defgroup TIM_Exported_Functions_Group10 TIM Peripheral State functions + * @brief Peripheral State functions + * @{ + */ +/* Peripheral State functions ************************************************/ +HAL_TIM_StateTypeDef HAL_TIM_Base_GetState(TIM_HandleTypeDef *htim); +HAL_TIM_StateTypeDef HAL_TIM_OC_GetState(TIM_HandleTypeDef *htim); +HAL_TIM_StateTypeDef HAL_TIM_PWM_GetState(TIM_HandleTypeDef *htim); +HAL_TIM_StateTypeDef HAL_TIM_IC_GetState(TIM_HandleTypeDef *htim); +HAL_TIM_StateTypeDef HAL_TIM_OnePulse_GetState(TIM_HandleTypeDef *htim); +HAL_TIM_StateTypeDef HAL_TIM_Encoder_GetState(TIM_HandleTypeDef *htim); +/** + * @} + */ + +/** + * @} + */ +/* End of exported functions -------------------------------------------------*/ + +/* Private functions----------------------------------------------------------*/ +/** @defgroup TIM_Private_Functions TIM Private Functions + * @{ + */ +void TIM_Base_SetConfig(TIM_TypeDef *TIMx, TIM_Base_InitTypeDef *Structure); +void TIM_TI1_SetConfig(TIM_TypeDef *TIMx, uint32_t TIM_ICPolarity, uint32_t TIM_ICSelection, uint32_t TIM_ICFilter); +void TIM_OC2_SetConfig(TIM_TypeDef *TIMx, TIM_OC_InitTypeDef *OC_Config); +void TIM_ETR_SetConfig(TIM_TypeDef *TIMx, uint32_t TIM_ExtTRGPrescaler, + uint32_t TIM_ExtTRGPolarity, uint32_t ExtTRGFilter); + +void TIM_DMADelayPulseCplt(DMA_HandleTypeDef *hdma); +void TIM_DMADelayPulseHalfCplt(DMA_HandleTypeDef *hdma); +void TIM_DMAError(DMA_HandleTypeDef *hdma); +void TIM_DMACaptureCplt(DMA_HandleTypeDef *hdma); +void TIM_DMACaptureHalfCplt(DMA_HandleTypeDef *hdma); +void TIM_CCxChannelCmd(TIM_TypeDef *TIMx, uint32_t Channel, uint32_t ChannelState); + +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) +void TIM_ResetCallback(TIM_HandleTypeDef *htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + +/** + * @} + */ +/* End of private functions --------------------------------------------------*/ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32F0xx_HAL_TIM_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_tim_ex.h b/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_tim_ex.h new file mode 100644 index 0000000..0c39c2e --- /dev/null +++ b/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_tim_ex.h @@ -0,0 +1,267 @@ +/** + ****************************************************************************** + * @file stm32f0xx_hal_tim_ex.h + * @author MCD Application Team + * @brief Header file of TIM HAL Extended module. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2016 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32F0xx_HAL_TIM_EX_H +#define STM32F0xx_HAL_TIM_EX_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f0xx_hal_def.h" + +/** @addtogroup STM32F0xx_HAL_Driver + * @{ + */ + +/** @addtogroup TIMEx + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup TIMEx_Exported_Types TIM Extended Exported Types + * @{ + */ + +/** + * @brief TIM Hall sensor Configuration Structure definition + */ + +typedef struct +{ + uint32_t IC1Polarity; /*!< Specifies the active edge of the input signal. + This parameter can be a value of @ref TIM_Input_Capture_Polarity */ + + uint32_t IC1Prescaler; /*!< Specifies the Input Capture Prescaler. + This parameter can be a value of @ref TIM_Input_Capture_Prescaler */ + + uint32_t IC1Filter; /*!< Specifies the input capture filter. + This parameter can be a number between Min_Data = 0x0 and Max_Data = 0xF */ + + uint32_t Commutation_Delay; /*!< Specifies the pulse value to be loaded into the Capture Compare Register. + This parameter can be a number between Min_Data = 0x0000 and Max_Data = 0xFFFF */ +} TIM_HallSensor_InitTypeDef; +/** + * @} + */ +/* End of exported types -----------------------------------------------------*/ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup TIMEx_Exported_Constants TIM Extended Exported Constants + * @{ + */ + +/** @defgroup TIMEx_Remap TIM Extended Remapping + * @{ + */ +#define TIM_TIM14_GPIO (0x00000000U) /*!< TIM14 TI1 is connected to GPIO */ +#define TIM_TIM14_RTC (0x00000001U) /*!< TIM14 TI1 is connected to RTC_clock */ +#define TIM_TIM14_HSE (0x00000002U) /*!< TIM14 TI1 is connected to HSE/32U */ +#define TIM_TIM14_MCO (0x00000003U) /*!< TIM14 TI1 is connected to MCO */ +/** + * @} + */ + +/** + * @} + */ +/* End of exported constants -------------------------------------------------*/ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup TIMEx_Exported_Macros TIM Extended Exported Macros + * @{ + */ + +/** + * @} + */ +/* End of exported macro -----------------------------------------------------*/ + +/* Private macro -------------------------------------------------------------*/ +/** @defgroup TIMEx_Private_Macros TIM Extended Private Macros + * @{ + */ +#define IS_TIM_REMAP(__INSTANCE__, __REMAP__) \ + (((__INSTANCE__) == TIM14) && (((__REMAP__) & 0xFFFFFFFCU) == 0x00000000U)) + +/** + * @} + */ +/* End of private macro ------------------------------------------------------*/ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup TIMEx_Exported_Functions TIM Extended Exported Functions + * @{ + */ + +/** @addtogroup TIMEx_Exported_Functions_Group1 Extended Timer Hall Sensor functions + * @brief Timer Hall Sensor functions + * @{ + */ +/* Timer Hall Sensor functions **********************************************/ +HAL_StatusTypeDef HAL_TIMEx_HallSensor_Init(TIM_HandleTypeDef *htim, TIM_HallSensor_InitTypeDef *sConfig); +HAL_StatusTypeDef HAL_TIMEx_HallSensor_DeInit(TIM_HandleTypeDef *htim); + +void HAL_TIMEx_HallSensor_MspInit(TIM_HandleTypeDef *htim); +void HAL_TIMEx_HallSensor_MspDeInit(TIM_HandleTypeDef *htim); + +/* Blocking mode: Polling */ +HAL_StatusTypeDef HAL_TIMEx_HallSensor_Start(TIM_HandleTypeDef *htim); +HAL_StatusTypeDef HAL_TIMEx_HallSensor_Stop(TIM_HandleTypeDef *htim); +/* Non-Blocking mode: Interrupt */ +HAL_StatusTypeDef HAL_TIMEx_HallSensor_Start_IT(TIM_HandleTypeDef *htim); +HAL_StatusTypeDef HAL_TIMEx_HallSensor_Stop_IT(TIM_HandleTypeDef *htim); +/* Non-Blocking mode: DMA */ +HAL_StatusTypeDef HAL_TIMEx_HallSensor_Start_DMA(TIM_HandleTypeDef *htim, uint32_t *pData, uint16_t Length); +HAL_StatusTypeDef HAL_TIMEx_HallSensor_Stop_DMA(TIM_HandleTypeDef *htim); +/** + * @} + */ + +/** @addtogroup TIMEx_Exported_Functions_Group2 Extended Timer Complementary Output Compare functions + * @brief Timer Complementary Output Compare functions + * @{ + */ +/* Timer Complementary Output Compare functions *****************************/ +/* Blocking mode: Polling */ +HAL_StatusTypeDef HAL_TIMEx_OCN_Start(TIM_HandleTypeDef *htim, uint32_t Channel); +HAL_StatusTypeDef HAL_TIMEx_OCN_Stop(TIM_HandleTypeDef *htim, uint32_t Channel); + +/* Non-Blocking mode: Interrupt */ +HAL_StatusTypeDef HAL_TIMEx_OCN_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel); +HAL_StatusTypeDef HAL_TIMEx_OCN_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channel); + +/* Non-Blocking mode: DMA */ +HAL_StatusTypeDef HAL_TIMEx_OCN_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Channel, uint32_t *pData, uint16_t Length); +HAL_StatusTypeDef HAL_TIMEx_OCN_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Channel); +/** + * @} + */ + +/** @addtogroup TIMEx_Exported_Functions_Group3 Extended Timer Complementary PWM functions + * @brief Timer Complementary PWM functions + * @{ + */ +/* Timer Complementary PWM functions ****************************************/ +/* Blocking mode: Polling */ +HAL_StatusTypeDef HAL_TIMEx_PWMN_Start(TIM_HandleTypeDef *htim, uint32_t Channel); +HAL_StatusTypeDef HAL_TIMEx_PWMN_Stop(TIM_HandleTypeDef *htim, uint32_t Channel); + +/* Non-Blocking mode: Interrupt */ +HAL_StatusTypeDef HAL_TIMEx_PWMN_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel); +HAL_StatusTypeDef HAL_TIMEx_PWMN_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channel); +/* Non-Blocking mode: DMA */ +HAL_StatusTypeDef HAL_TIMEx_PWMN_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Channel, uint32_t *pData, uint16_t Length); +HAL_StatusTypeDef HAL_TIMEx_PWMN_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Channel); +/** + * @} + */ + +/** @addtogroup TIMEx_Exported_Functions_Group4 Extended Timer Complementary One Pulse functions + * @brief Timer Complementary One Pulse functions + * @{ + */ +/* Timer Complementary One Pulse functions **********************************/ +/* Blocking mode: Polling */ +HAL_StatusTypeDef HAL_TIMEx_OnePulseN_Start(TIM_HandleTypeDef *htim, uint32_t OutputChannel); +HAL_StatusTypeDef HAL_TIMEx_OnePulseN_Stop(TIM_HandleTypeDef *htim, uint32_t OutputChannel); + +/* Non-Blocking mode: Interrupt */ +HAL_StatusTypeDef HAL_TIMEx_OnePulseN_Start_IT(TIM_HandleTypeDef *htim, uint32_t OutputChannel); +HAL_StatusTypeDef HAL_TIMEx_OnePulseN_Stop_IT(TIM_HandleTypeDef *htim, uint32_t OutputChannel); +/** + * @} + */ + +/** @addtogroup TIMEx_Exported_Functions_Group5 Extended Peripheral Control functions + * @brief Peripheral Control functions + * @{ + */ +/* Extended Control functions ************************************************/ +HAL_StatusTypeDef HAL_TIMEx_ConfigCommutEvent(TIM_HandleTypeDef *htim, uint32_t InputTrigger, + uint32_t CommutationSource); +HAL_StatusTypeDef HAL_TIMEx_ConfigCommutEvent_IT(TIM_HandleTypeDef *htim, uint32_t InputTrigger, + uint32_t CommutationSource); +HAL_StatusTypeDef HAL_TIMEx_ConfigCommutEvent_DMA(TIM_HandleTypeDef *htim, uint32_t InputTrigger, + uint32_t CommutationSource); +HAL_StatusTypeDef HAL_TIMEx_MasterConfigSynchronization(TIM_HandleTypeDef *htim, + TIM_MasterConfigTypeDef *sMasterConfig); +HAL_StatusTypeDef HAL_TIMEx_ConfigBreakDeadTime(TIM_HandleTypeDef *htim, + TIM_BreakDeadTimeConfigTypeDef *sBreakDeadTimeConfig); +HAL_StatusTypeDef HAL_TIMEx_RemapConfig(TIM_HandleTypeDef *htim, uint32_t Remap); +/** + * @} + */ + +/** @addtogroup TIMEx_Exported_Functions_Group6 Extended Callbacks functions + * @brief Extended Callbacks functions + * @{ + */ +/* Extended Callback **********************************************************/ +void HAL_TIMEx_CommutCallback(TIM_HandleTypeDef *htim); +void HAL_TIMEx_CommutHalfCpltCallback(TIM_HandleTypeDef *htim); +void HAL_TIMEx_BreakCallback(TIM_HandleTypeDef *htim); +/** + * @} + */ + +/** @addtogroup TIMEx_Exported_Functions_Group7 Extended Peripheral State functions + * @brief Extended Peripheral State functions + * @{ + */ +/* Extended Peripheral State functions ***************************************/ +HAL_TIM_StateTypeDef HAL_TIMEx_HallSensor_GetState(TIM_HandleTypeDef *htim); +/** + * @} + */ + +/** + * @} + */ +/* End of exported functions -------------------------------------------------*/ + +/* Private functions----------------------------------------------------------*/ +/** @addtogroup TIMEx_Private_Functions TIMEx Private Functions + * @{ + */ +void TIMEx_DMACommutationCplt(DMA_HandleTypeDef *hdma); +void TIMEx_DMACommutationHalfCplt(DMA_HandleTypeDef *hdma); +/** + * @} + */ +/* End of private functions --------------------------------------------------*/ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + + +#endif /* STM32F0xx_HAL_TIM_EX_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_usb.h b/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_usb.h new file mode 100644 index 0000000..4197cb6 --- /dev/null +++ b/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_usb.h @@ -0,0 +1,237 @@ +/** + ****************************************************************************** + * @file stm32f0xx_ll_usb.h + * @author MCD Application Team + * @brief Header file of USB Low Layer HAL module. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2016 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32F0xx_LL_USB_H +#define STM32F0xx_LL_USB_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f0xx_hal_def.h" + +#if defined (USB) +/** @addtogroup STM32F0xx_HAL_Driver + * @{ + */ + +/** @addtogroup USB_LL + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ + +/** + * @brief USB Mode definition + */ + + + +typedef enum +{ + USB_DEVICE_MODE = 0 +} USB_ModeTypeDef; + +/** + * @brief USB Initialization Structure definition + */ +typedef struct +{ + uint32_t dev_endpoints; /*!< Device Endpoints number. + This parameter depends on the used USB core. + This parameter must be a number between Min_Data = 1 and Max_Data = 15 */ + + uint32_t speed; /*!< USB Core speed. + This parameter can be any value of @ref USB_Core_Speed */ + + uint32_t ep0_mps; /*!< Set the Endpoint 0 Max Packet size. */ + + uint32_t phy_itface; /*!< Select the used PHY interface. + This parameter can be any value of @ref USB_Core_PHY */ + + uint32_t Sof_enable; /*!< Enable or disable the output of the SOF signal. */ + + uint32_t low_power_enable; /*!< Enable or disable Low Power mode */ + + uint32_t lpm_enable; /*!< Enable or disable Battery charging. */ + + uint32_t battery_charging_enable; /*!< Enable or disable Battery charging. */ +} USB_CfgTypeDef; + +typedef struct +{ + uint8_t num; /*!< Endpoint number + This parameter must be a number between Min_Data = 1 and Max_Data = 15 */ + + uint8_t is_in; /*!< Endpoint direction + This parameter must be a number between Min_Data = 0 and Max_Data = 1 */ + + uint8_t is_stall; /*!< Endpoint stall condition + This parameter must be a number between Min_Data = 0 and Max_Data = 1 */ + + uint8_t type; /*!< Endpoint type + This parameter can be any value of @ref USB_EP_Type */ + + uint8_t data_pid_start; /*!< Initial data PID + This parameter must be a number between Min_Data = 0 and Max_Data = 1 */ + + uint16_t pmaadress; /*!< PMA Address + This parameter can be any value between Min_addr = 0 and Max_addr = 1K */ + + uint16_t pmaaddr0; /*!< PMA Address0 + This parameter can be any value between Min_addr = 0 and Max_addr = 1K */ + + uint16_t pmaaddr1; /*!< PMA Address1 + This parameter can be any value between Min_addr = 0 and Max_addr = 1K */ + + uint8_t doublebuffer; /*!< Double buffer enable + This parameter can be 0 or 1 */ + + uint16_t tx_fifo_num; /*!< This parameter is not required by USB Device FS peripheral, it is used + only by USB OTG FS peripheral + This parameter is added to ensure compatibility across USB peripherals */ + + uint32_t maxpacket; /*!< Endpoint Max packet size + This parameter must be a number between Min_Data = 0 and Max_Data = 64KB */ + + uint8_t *xfer_buff; /*!< Pointer to transfer buffer */ + + uint32_t xfer_len; /*!< Current transfer length */ + + uint32_t xfer_count; /*!< Partial transfer length in case of multi packet transfer */ + +} USB_EPTypeDef; + + +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup PCD_Exported_Constants PCD Exported Constants + * @{ + */ + + +/** @defgroup USB_LL_EP0_MPS USB Low Layer EP0 MPS + * @{ + */ +#define DEP0CTL_MPS_64 0U +#define DEP0CTL_MPS_32 1U +#define DEP0CTL_MPS_16 2U +#define DEP0CTL_MPS_8 3U +/** + * @} + */ + +/** @defgroup USB_LL_EP_Type USB Low Layer EP Type + * @{ + */ +#define EP_TYPE_CTRL 0U +#define EP_TYPE_ISOC 1U +#define EP_TYPE_BULK 2U +#define EP_TYPE_INTR 3U +#define EP_TYPE_MSK 3U +/** + * @} + */ + +/** @defgroup USB_LL Device Speed + * @{ + */ +#define USBD_FS_SPEED 2U +/** + * @} + */ + +#define BTABLE_ADDRESS 0x000U +#define PMA_ACCESS 1U + +#define EP_ADDR_MSK 0x7U +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup USB_LL_Exported_Functions USB Low Layer Exported Functions + * @{ + */ + + +HAL_StatusTypeDef USB_CoreInit(USB_TypeDef *USBx, USB_CfgTypeDef cfg); +HAL_StatusTypeDef USB_DevInit(USB_TypeDef *USBx, USB_CfgTypeDef cfg); +HAL_StatusTypeDef USB_EnableGlobalInt(USB_TypeDef *USBx); +HAL_StatusTypeDef USB_DisableGlobalInt(USB_TypeDef *USBx); +HAL_StatusTypeDef USB_SetCurrentMode(USB_TypeDef *USBx, USB_ModeTypeDef mode); +HAL_StatusTypeDef USB_SetDevSpeed(USB_TypeDef *USBx, uint8_t speed); +HAL_StatusTypeDef USB_FlushRxFifo(USB_TypeDef *USBx); +HAL_StatusTypeDef USB_FlushTxFifo(USB_TypeDef *USBx, uint32_t num); +HAL_StatusTypeDef USB_ActivateEndpoint(USB_TypeDef *USBx, USB_EPTypeDef *ep); +HAL_StatusTypeDef USB_DeactivateEndpoint(USB_TypeDef *USBx, USB_EPTypeDef *ep); +HAL_StatusTypeDef USB_EPStartXfer(USB_TypeDef *USBx, USB_EPTypeDef *ep); +HAL_StatusTypeDef USB_WritePacket(USB_TypeDef *USBx, uint8_t *src, uint8_t ch_ep_num, uint16_t len); +void *USB_ReadPacket(USB_TypeDef *USBx, uint8_t *dest, uint16_t len); +HAL_StatusTypeDef USB_EPSetStall(USB_TypeDef *USBx, USB_EPTypeDef *ep); +HAL_StatusTypeDef USB_EPClearStall(USB_TypeDef *USBx, USB_EPTypeDef *ep); +HAL_StatusTypeDef USB_SetDevAddress(USB_TypeDef *USBx, uint8_t address); +HAL_StatusTypeDef USB_DevConnect(USB_TypeDef *USBx); +HAL_StatusTypeDef USB_DevDisconnect(USB_TypeDef *USBx); +HAL_StatusTypeDef USB_StopDevice(USB_TypeDef *USBx); +HAL_StatusTypeDef USB_EP0_OutStart(USB_TypeDef *USBx, uint8_t *psetup); +uint32_t USB_ReadInterrupts(USB_TypeDef *USBx); +uint32_t USB_ReadDevAllOutEpInterrupt(USB_TypeDef *USBx); +uint32_t USB_ReadDevOutEPInterrupt(USB_TypeDef *USBx, uint8_t epnum); +uint32_t USB_ReadDevAllInEpInterrupt(USB_TypeDef *USBx); +uint32_t USB_ReadDevInEPInterrupt(USB_TypeDef *USBx, uint8_t epnum); +void USB_ClearInterrupts(USB_TypeDef *USBx, uint32_t interrupt); + +HAL_StatusTypeDef USB_ActivateRemoteWakeup(USB_TypeDef *USBx); +HAL_StatusTypeDef USB_DeActivateRemoteWakeup(USB_TypeDef *USBx); +void USB_WritePMA(USB_TypeDef *USBx, uint8_t *pbUsrBuf, uint16_t wPMABufAddr, uint16_t wNBytes); +void USB_ReadPMA(USB_TypeDef *USBx, uint8_t *pbUsrBuf, uint16_t wPMABufAddr, uint16_t wNBytes); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ +#endif /* defined (USB) */ + +#ifdef __cplusplus +} +#endif + + +#endif /* STM32F0xx_LL_USB_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.c b/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.c new file mode 100644 index 0000000..5651040 --- /dev/null +++ b/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.c @@ -0,0 +1,514 @@ +/** + ****************************************************************************** + * @file stm32f0xx_hal.c + * @author MCD Application Team + * @brief HAL module driver. + * This is the common part of the HAL initialization + * + @verbatim + ============================================================================== + ##### How to use this driver ##### + ============================================================================== + [..] + The common HAL driver contains a set of generic and common APIs that can be + used by the PPP peripheral drivers and the user to start using the HAL. + [..] + The HAL contains two APIs categories: + (+) HAL Initialization and de-initialization functions + (+) HAL Control functions + + @endverbatim + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2016 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f0xx_hal.h" + +/** @addtogroup STM32F0xx_HAL_Driver + * @{ + */ + +/** @defgroup HAL HAL + * @brief HAL module driver. + * @{ + */ + +#ifdef HAL_MODULE_ENABLED + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/** @defgroup HAL_Private_Constants HAL Private Constants + * @{ + */ +/** + * @brief STM32F0xx HAL Driver version number V1.7.3 + */ +#define __STM32F0xx_HAL_VERSION_MAIN (0x01U) /*!< [31:24] main version */ +#define __STM32F0xx_HAL_VERSION_SUB1 (0x07U) /*!< [23:16] sub1 version */ +#define __STM32F0xx_HAL_VERSION_SUB2 (0x03U) /*!< [15:8] sub2 version */ +#define __STM32F0xx_HAL_VERSION_RC (0x00U) /*!< [7:0] release candidate */ +#define __STM32F0xx_HAL_VERSION ((__STM32F0xx_HAL_VERSION_MAIN << 24U)\ + |(__STM32F0xx_HAL_VERSION_SUB1 << 16U)\ + |(__STM32F0xx_HAL_VERSION_SUB2 << 8U )\ + |(__STM32F0xx_HAL_VERSION_RC)) + +#define IDCODE_DEVID_MASK (0x00000FFFU) +/** + * @} + */ + +/* Private macro -------------------------------------------------------------*/ +/** @defgroup HAL_Private_Macros HAL Private Macros + * @{ + */ +/** + * @} + */ + +/* Exported variables ---------------------------------------------------------*/ +/** @defgroup HAL_Private_Variables HAL Exported Variables + * @{ + */ +__IO uint32_t uwTick; +uint32_t uwTickPrio = (1UL << __NVIC_PRIO_BITS); /* Invalid PRIO */ +HAL_TickFreqTypeDef uwTickFreq = HAL_TICK_FREQ_DEFAULT; /* 1KHz */ +/** + * @} + */ +/* Private function prototypes -----------------------------------------------*/ +/* Exported functions ---------------------------------------------------------*/ + +/** @defgroup HAL_Exported_Functions HAL Exported Functions + * @{ + */ + +/** @defgroup HAL_Exported_Functions_Group1 Initialization and de-initialization Functions + * @brief Initialization and de-initialization functions + * +@verbatim + =============================================================================== + ##### Initialization and de-initialization functions ##### + =============================================================================== + [..] This section provides functions allowing to: + (+) Initializes the Flash interface, the NVIC allocation and initial clock + configuration. It initializes the systick also when timeout is needed + and the backup domain when enabled. + (+) de-Initializes common part of the HAL. + (+) Configure The time base source to have 1ms time base with a dedicated + Tick interrupt priority. + (++) SysTick timer is used by default as source of time base, but user + can eventually implement his proper time base source (a general purpose + timer for example or other time source), keeping in mind that Time base + duration should be kept 1ms since PPP_TIMEOUT_VALUEs are defined and + handled in milliseconds basis. + (++) Time base configuration function (HAL_InitTick ()) is called automatically + at the beginning of the program after reset by HAL_Init() or at any time + when clock is configured, by HAL_RCC_ClockConfig(). + (++) Source of time base is configured to generate interrupts at regular + time intervals. Care must be taken if HAL_Delay() is called from a + peripheral ISR process, the Tick interrupt line must have higher priority + (numerically lower) than the peripheral interrupt. Otherwise the caller + ISR process will be blocked. + (++) functions affecting time base configurations are declared as __Weak + to make override possible in case of other implementations in user file. + +@endverbatim + * @{ + */ + +/** + * @brief This function configures the Flash prefetch, + * Configures time base source, NVIC and Low level hardware + * @note This function is called at the beginning of program after reset and before + * the clock configuration + * @note The time base configuration is based on HSI clock when exiting from Reset. + * Once done, time base tick start incrementing. + * In the default implementation,Systick is used as source of time base. + * The tick variable is incremented each 1ms in its ISR. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_Init(void) +{ + /* Configure Flash prefetch */ +#if (PREFETCH_ENABLE != 0) + __HAL_FLASH_PREFETCH_BUFFER_ENABLE(); +#endif /* PREFETCH_ENABLE */ + + /* Use systick as time base source and configure 1ms tick (default clock after Reset is HSI) */ + + HAL_InitTick(TICK_INT_PRIORITY); + + /* Init the low level hardware */ + HAL_MspInit(); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief This function de-Initialize common part of the HAL and stops the SysTick + * of time base. + * @note This function is optional. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DeInit(void) +{ + /* Reset of all peripherals */ + __HAL_RCC_APB1_FORCE_RESET(); + __HAL_RCC_APB1_RELEASE_RESET(); + + __HAL_RCC_APB2_FORCE_RESET(); + __HAL_RCC_APB2_RELEASE_RESET(); + + __HAL_RCC_AHB_FORCE_RESET(); + __HAL_RCC_AHB_RELEASE_RESET(); + + /* De-Init the low level hardware */ + HAL_MspDeInit(); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Initialize the MSP. + * @retval None + */ +__weak void HAL_MspInit(void) +{ + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_MspInit could be implemented in the user file + */ +} + +/** + * @brief DeInitializes the MSP. + * @retval None + */ +__weak void HAL_MspDeInit(void) +{ + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_MspDeInit could be implemented in the user file + */ +} + +/** + * @brief This function configures the source of the time base. + * The time source is configured to have 1ms time base with a dedicated + * Tick interrupt priority. + * @note This function is called automatically at the beginning of program after + * reset by HAL_Init() or at any time when clock is reconfigured by HAL_RCC_ClockConfig(). + * @note In the default implementation, SysTick timer is the source of time base. + * It is used to generate interrupts at regular time intervals. + * Care must be taken if HAL_Delay() is called from a peripheral ISR process, + * The SysTick interrupt must have higher priority (numerically lower) + * than the peripheral interrupt. Otherwise the caller ISR process will be blocked. + * The function is declared as __Weak to be overwritten in case of other + * implementation in user file. + * @param TickPriority Tick interrupt priority. + * @retval HAL status + */ +__weak HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority) +{ + /*Configure the SysTick to have interrupt in 1ms time basis*/ + if (HAL_SYSTICK_Config(SystemCoreClock / (1000U / uwTickFreq)) > 0U) + { + return HAL_ERROR; + } + + /* Configure the SysTick IRQ priority */ + if (TickPriority < (1UL << __NVIC_PRIO_BITS)) + { + HAL_NVIC_SetPriority(SysTick_IRQn, TickPriority, 0U); + uwTickPrio = TickPriority; + } + else + { + return HAL_ERROR; + } + + /* Return function status */ + return HAL_OK; +} + +/** + * @} + */ + +/** @defgroup HAL_Exported_Functions_Group2 HAL Control functions + * @brief HAL Control functions + * +@verbatim + =============================================================================== + ##### HAL Control functions ##### + =============================================================================== + [..] This section provides functions allowing to: + (+) Provide a tick value in millisecond + (+) Provide a blocking delay in millisecond + (+) Suspend the time base source interrupt + (+) Resume the time base source interrupt + (+) Get the HAL API driver version + (+) Get the device identifier + (+) Get the device revision identifier + (+) Enable/Disable Debug module during Sleep mode + (+) Enable/Disable Debug module during STOP mode + (+) Enable/Disable Debug module during STANDBY mode + +@endverbatim + * @{ + */ + +/** + * @brief This function is called to increment a global variable "uwTick" + * used as application time base. + * @note In the default implementation, this variable is incremented each 1ms + * in SysTick ISR. + * @note This function is declared as __weak to be overwritten in case of other + * implementations in user file. + * @retval None + */ +__weak void HAL_IncTick(void) +{ + uwTick += uwTickFreq; +} + +/** + * @brief Provides a tick value in millisecond. + * @note This function is declared as __weak to be overwritten in case of other + * implementations in user file. + * @retval tick value + */ +__weak uint32_t HAL_GetTick(void) +{ + return uwTick; +} + +/** + * @brief This function returns a tick priority. + * @retval tick priority + */ +uint32_t HAL_GetTickPrio(void) +{ + return uwTickPrio; +} + +/** + * @brief Set new tick Freq. + * @retval status + */ +HAL_StatusTypeDef HAL_SetTickFreq(HAL_TickFreqTypeDef Freq) +{ + HAL_StatusTypeDef status = HAL_OK; + HAL_TickFreqTypeDef prevTickFreq; + + assert_param(IS_TICKFREQ(Freq)); + + if (uwTickFreq != Freq) + { + /* Back up uwTickFreq frequency */ + prevTickFreq = uwTickFreq; + + /* Update uwTickFreq global variable used by HAL_InitTick() */ + uwTickFreq = Freq; + + /* Apply the new tick Freq */ + status = HAL_InitTick(uwTickPrio); + + if (status != HAL_OK) + { + /* Restore previous tick frequency */ + uwTickFreq = prevTickFreq; + } + } + + return status; +} + +/** + * @brief return tick frequency. + * @retval tick period in Hz + */ +HAL_TickFreqTypeDef HAL_GetTickFreq(void) +{ + return uwTickFreq; +} + +/** + * @brief This function provides accurate delay (in milliseconds) based + * on variable incremented. + * @note In the default implementation , SysTick timer is the source of time base. + * It is used to generate interrupts at regular time intervals where uwTick + * is incremented. + * @note ThiS function is declared as __weak to be overwritten in case of other + * implementations in user file. + * @param Delay specifies the delay time length, in milliseconds. + * @retval None + */ +__weak void HAL_Delay(uint32_t Delay) +{ + uint32_t tickstart = HAL_GetTick(); + uint32_t wait = Delay; + + /* Add a freq to guarantee minimum wait */ + if (wait < HAL_MAX_DELAY) + { + wait += (uint32_t)(uwTickFreq); + } + + while((HAL_GetTick() - tickstart) < wait) + { + } +} + +/** + * @brief Suspend Tick increment. + * @note In the default implementation , SysTick timer is the source of time base. It is + * used to generate interrupts at regular time intervals. Once HAL_SuspendTick() + * is called, the the SysTick interrupt will be disabled and so Tick increment + * is suspended. + * @note This function is declared as __weak to be overwritten in case of other + * implementations in user file. + * @retval None + */ +__weak void HAL_SuspendTick(void) + +{ + /* Disable SysTick Interrupt */ + CLEAR_BIT(SysTick->CTRL,SysTick_CTRL_TICKINT_Msk); +} + +/** + * @brief Resume Tick increment. + * @note In the default implementation , SysTick timer is the source of time base. It is + * used to generate interrupts at regular time intervals. Once HAL_ResumeTick() + * is called, the the SysTick interrupt will be enabled and so Tick increment + * is resumed. + * @note This function is declared as __weak to be overwritten in case of other + * implementations in user file. + * @retval None + */ +__weak void HAL_ResumeTick(void) +{ + /* Enable SysTick Interrupt */ + SET_BIT(SysTick->CTRL,SysTick_CTRL_TICKINT_Msk); +} + +/** + * @brief This method returns the HAL revision + * @retval version 0xXYZR (8bits for each decimal, R for RC) + */ +uint32_t HAL_GetHalVersion(void) +{ + return __STM32F0xx_HAL_VERSION; +} + +/** + * @brief Returns the device revision identifier. + * @retval Device revision identifier + */ +uint32_t HAL_GetREVID(void) +{ + return((DBGMCU->IDCODE) >> 16U); +} + +/** + * @brief Returns the device identifier. + * @retval Device identifier + */ +uint32_t HAL_GetDEVID(void) +{ + return((DBGMCU->IDCODE) & IDCODE_DEVID_MASK); +} + +/** + * @brief Returns first word of the unique device identifier (UID based on 96 bits) + * @retval Device identifier + */ +uint32_t HAL_GetUIDw0(void) +{ + return(READ_REG(*((uint32_t *)UID_BASE))); +} + +/** + * @brief Returns second word of the unique device identifier (UID based on 96 bits) + * @retval Device identifier + */ +uint32_t HAL_GetUIDw1(void) +{ + return(READ_REG(*((uint32_t *)(UID_BASE + 4U)))); +} + +/** + * @brief Returns third word of the unique device identifier (UID based on 96 bits) + * @retval Device identifier + */ +uint32_t HAL_GetUIDw2(void) +{ + return(READ_REG(*((uint32_t *)(UID_BASE + 8U)))); +} + +/** + * @brief Enable the Debug Module during STOP mode + * @retval None + */ +void HAL_DBGMCU_EnableDBGStopMode(void) +{ + SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_STOP); +} + +/** + * @brief Disable the Debug Module during STOP mode + * @retval None + */ +void HAL_DBGMCU_DisableDBGStopMode(void) +{ + CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_STOP); +} + +/** + * @brief Enable the Debug Module during STANDBY mode + * @retval None + */ +void HAL_DBGMCU_EnableDBGStandbyMode(void) +{ + SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_STANDBY); +} + +/** + * @brief Disable the Debug Module during STANDBY mode + * @retval None + */ +void HAL_DBGMCU_DisableDBGStandbyMode(void) +{ + CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_STANDBY); +} + +/** + * @} + */ + +/** + * @} + */ + +#endif /* HAL_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.c b/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.c new file mode 100644 index 0000000..cbe3f5b --- /dev/null +++ b/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.c @@ -0,0 +1,341 @@ +/** + ****************************************************************************** + * @file stm32f0xx_hal_cortex.c + * @author MCD Application Team + * @brief CORTEX HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the CORTEX: + * + Initialization and de-initialization functions + * + Peripheral Control functions + * + * @verbatim + ============================================================================== + ##### How to use this driver ##### + ============================================================================== + + [..] + *** How to configure Interrupts using CORTEX HAL driver *** + =========================================================== + [..] + This section provides functions allowing to configure the NVIC interrupts (IRQ). + The Cortex-M0 exceptions are managed by CMSIS functions. + (#) Enable and Configure the priority of the selected IRQ Channels. + The priority can be 0..3. + + -@- Lower priority values gives higher priority. + -@- Priority Order: + (#@) Lowest priority. + (#@) Lowest hardware priority (IRQn position). + + (#) Configure the priority of the selected IRQ Channels using HAL_NVIC_SetPriority() + + (#) Enable the selected IRQ Channels using HAL_NVIC_EnableIRQ() + + -@- Negative value of IRQn_Type are not allowed. + + + [..] + *** How to configure Systick using CORTEX HAL driver *** + ======================================================== + [..] + Setup SysTick Timer for time base. + + (+) The HAL_SYSTICK_Config()function calls the SysTick_Config() function which + is a CMSIS function that: + (++) Configures the SysTick Reload register with value passed as function parameter. + (++) Configures the SysTick IRQ priority to the lowest value (0x03). + (++) Resets the SysTick Counter register. + (++) Configures the SysTick Counter clock source to be Core Clock Source (HCLK). + (++) Enables the SysTick Interrupt. + (++) Starts the SysTick Counter. + + (+) You can change the SysTick Clock source to be HCLK_Div8 by calling the macro + HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK_DIV8) just after the + HAL_SYSTICK_Config() function call. The HAL_SYSTICK_CLKSourceConfig() macro is defined + inside the stm32f0xx_hal_cortex.h file. + + (+) You can change the SysTick IRQ priority by calling the + HAL_NVIC_SetPriority(SysTick_IRQn,...) function just after the HAL_SYSTICK_Config() function + call. The HAL_NVIC_SetPriority() call the NVIC_SetPriority() function which is a CMSIS function. + + (+) To adjust the SysTick time base, use the following formula: + + Reload Value = SysTick Counter Clock (Hz) x Desired Time base (s) + (++) Reload Value is the parameter to be passed for HAL_SYSTICK_Config() function + (++) Reload Value should not exceed 0xFFFFFF + + @endverbatim + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2016 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f0xx_hal.h" + +/** @addtogroup STM32F0xx_HAL_Driver + * @{ + */ + +/** @defgroup CORTEX CORTEX + * @brief CORTEX CORTEX HAL module driver + * @{ + */ + +#ifdef HAL_CORTEX_MODULE_ENABLED + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Exported functions ---------------------------------------------------------*/ + +/** @defgroup CORTEX_Exported_Functions CORTEX Exported Functions + * @{ + */ + + +/** @defgroup CORTEX_Exported_Functions_Group1 Initialization and de-initialization functions + * @brief Initialization and Configuration functions + * +@verbatim + ============================================================================== + ##### Initialization and de-initialization functions ##### + ============================================================================== + [..] + This section provides the CORTEX HAL driver functions allowing to configure Interrupts + Systick functionalities + +@endverbatim + * @{ + */ + +/** + * @brief Sets the priority of an interrupt. + * @param IRQn External interrupt number . + * This parameter can be an enumerator of IRQn_Type enumeration + * (For the complete STM32 Devices IRQ Channels list, please refer to stm32f0xx.h file) + * @param PreemptPriority The preemption priority for the IRQn channel. + * This parameter can be a value between 0 and 3. + * A lower priority value indicates a higher priority + * @param SubPriority the subpriority level for the IRQ channel. + * with stm32f0xx devices, this parameter is a dummy value and it is ignored, because + * no subpriority supported in Cortex M0 based products. + * @retval None + */ +void HAL_NVIC_SetPriority(IRQn_Type IRQn, uint32_t PreemptPriority, uint32_t SubPriority) +{ + /* Check the parameters */ + assert_param(IS_NVIC_PREEMPTION_PRIORITY(PreemptPriority)); + NVIC_SetPriority(IRQn,PreemptPriority); +} + +/** + * @brief Enables a device specific interrupt in the NVIC interrupt controller. + * @note To configure interrupts priority correctly, the NVIC_PriorityGroupConfig() + * function should be called before. + * @param IRQn External interrupt number. + * This parameter can be an enumerator of IRQn_Type enumeration + * (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32f0xxxx.h)) + * @retval None + */ +void HAL_NVIC_EnableIRQ(IRQn_Type IRQn) +{ + /* Check the parameters */ + assert_param(IS_NVIC_DEVICE_IRQ(IRQn)); + + /* Enable interrupt */ + NVIC_EnableIRQ(IRQn); +} + +/** + * @brief Disables a device specific interrupt in the NVIC interrupt controller. + * @param IRQn External interrupt number. + * This parameter can be an enumerator of IRQn_Type enumeration + * (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32f0xxxx.h)) + * @retval None + */ +void HAL_NVIC_DisableIRQ(IRQn_Type IRQn) +{ + /* Check the parameters */ + assert_param(IS_NVIC_DEVICE_IRQ(IRQn)); + + /* Disable interrupt */ + NVIC_DisableIRQ(IRQn); +} + +/** + * @brief Initiates a system reset request to reset the MCU. + * @retval None + */ +void HAL_NVIC_SystemReset(void) +{ + /* System Reset */ + NVIC_SystemReset(); +} + +/** + * @brief Initializes the System Timer and its interrupt, and starts the System Tick Timer. + * Counter is in free running mode to generate periodic interrupts. + * @param TicksNumb Specifies the ticks Number of ticks between two interrupts. + * @retval status: - 0 Function succeeded. + * - 1 Function failed. + */ +uint32_t HAL_SYSTICK_Config(uint32_t TicksNumb) +{ + return SysTick_Config(TicksNumb); +} +/** + * @} + */ + +/** @defgroup CORTEX_Exported_Functions_Group2 Peripheral Control functions + * @brief Cortex control functions + * +@verbatim + ============================================================================== + ##### Peripheral Control functions ##### + ============================================================================== + [..] + This subsection provides a set of functions allowing to control the CORTEX + (NVIC, SYSTICK) functionalities. + + +@endverbatim + * @{ + */ + + +/** + * @brief Gets the priority of an interrupt. + * @param IRQn External interrupt number. + * This parameter can be an enumerator of IRQn_Type enumeration + * (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32f0xxxx.h)) + * @retval None + */ +uint32_t HAL_NVIC_GetPriority(IRQn_Type IRQn) +{ + /* Get priority for Cortex-M system or device specific interrupts */ + return NVIC_GetPriority(IRQn); +} + +/** + * @brief Sets Pending bit of an external interrupt. + * @param IRQn External interrupt number + * This parameter can be an enumerator of IRQn_Type enumeration + * (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32f0xxxx.h)) + * @retval None + */ +void HAL_NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + /* Check the parameters */ + assert_param(IS_NVIC_DEVICE_IRQ(IRQn)); + + /* Set interrupt pending */ + NVIC_SetPendingIRQ(IRQn); +} + +/** + * @brief Gets Pending Interrupt (reads the pending register in the NVIC + * and returns the pending bit for the specified interrupt). + * @param IRQn External interrupt number. + * This parameter can be an enumerator of IRQn_Type enumeration + * (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32f0xxxx.h)) + * @retval status: - 0 Interrupt status is not pending. + * - 1 Interrupt status is pending. + */ +uint32_t HAL_NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + /* Check the parameters */ + assert_param(IS_NVIC_DEVICE_IRQ(IRQn)); + + /* Return 1 if pending else 0 */ + return NVIC_GetPendingIRQ(IRQn); +} + +/** + * @brief Clears the pending bit of an external interrupt. + * @param IRQn External interrupt number. + * This parameter can be an enumerator of IRQn_Type enumeration + * (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32f0xxxx.h)) + * @retval None + */ +void HAL_NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + /* Check the parameters */ + assert_param(IS_NVIC_DEVICE_IRQ(IRQn)); + + /* Clear pending interrupt */ + NVIC_ClearPendingIRQ(IRQn); +} + +/** + * @brief Configures the SysTick clock source. + * @param CLKSource specifies the SysTick clock source. + * This parameter can be one of the following values: + * @arg SYSTICK_CLKSOURCE_HCLK_DIV8: AHB clock divided by 8 selected as SysTick clock source. + * @arg SYSTICK_CLKSOURCE_HCLK: AHB clock selected as SysTick clock source. + * @retval None + */ +void HAL_SYSTICK_CLKSourceConfig(uint32_t CLKSource) +{ + /* Check the parameters */ + assert_param(IS_SYSTICK_CLK_SOURCE(CLKSource)); + if (CLKSource == SYSTICK_CLKSOURCE_HCLK) + { + SysTick->CTRL |= SYSTICK_CLKSOURCE_HCLK; + } + else + { + SysTick->CTRL &= ~SYSTICK_CLKSOURCE_HCLK; + } +} + +/** + * @brief This function handles SYSTICK interrupt request. + * @retval None + */ +void HAL_SYSTICK_IRQHandler(void) +{ + HAL_SYSTICK_Callback(); +} + +/** + * @brief SYSTICK callback. + * @retval None + */ +__weak void HAL_SYSTICK_Callback(void) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_SYSTICK_Callback could be implemented in the user file + */ +} + +/** + * @} + */ + +/** + * @} + */ + +#endif /* HAL_CORTEX_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.c b/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.c new file mode 100644 index 0000000..b7f91a4 --- /dev/null +++ b/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.c @@ -0,0 +1,901 @@ +/** + ****************************************************************************** + * @file stm32f0xx_hal_dma.c + * @author MCD Application Team + * @brief DMA HAL module driver. + * + * This file provides firmware functions to manage the following + * functionalities of the Direct Memory Access (DMA) peripheral: + * + Initialization and de-initialization functions + * + IO operation functions + * + Peripheral State and errors functions + @verbatim + ============================================================================== + ##### How to use this driver ##### + ============================================================================== + [..] + (#) Enable and configure the peripheral to be connected to the DMA Channel + (except for internal SRAM / FLASH memories: no initialization is + necessary). Please refer to Reference manual for connection between peripherals + and DMA requests . + + (#) For a given Channel, program the required configuration through the following parameters: + Transfer Direction, Source and Destination data formats, + Circular or Normal mode, Channel Priority level, Source and Destination Increment mode, + using HAL_DMA_Init() function. + + (#) Use HAL_DMA_GetState() function to return the DMA state and HAL_DMA_GetError() in case of error + detection. + + (#) Use HAL_DMA_Abort() function to abort the current transfer + + -@- In Memory-to-Memory transfer mode, Circular mode is not allowed. + *** Polling mode IO operation *** + ================================= + [..] + (+) Use HAL_DMA_Start() to start DMA transfer after the configuration of Source + address and destination address and the Length of data to be transferred + (+) Use HAL_DMA_PollForTransfer() to poll for the end of current transfer, in this + case a fixed Timeout can be configured by User depending from his application. + + *** Interrupt mode IO operation *** + =================================== + [..] + (+) Configure the DMA interrupt priority using HAL_NVIC_SetPriority() + (+) Enable the DMA IRQ handler using HAL_NVIC_EnableIRQ() + (+) Use HAL_DMA_Start_IT() to start DMA transfer after the configuration of + Source address and destination address and the Length of data to be transferred. + In this case the DMA interrupt is configured + (+) Use HAL_DMA_Channel_IRQHandler() called under DMA_IRQHandler() Interrupt subroutine + (+) At the end of data transfer HAL_DMA_IRQHandler() function is executed and user can + add his own function by customization of function pointer XferCpltCallback and + XferErrorCallback (i.e a member of DMA handle structure). + + *** DMA HAL driver macros list *** + ============================================= + [..] + Below the list of most used macros in DMA HAL driver. + + [..] + (@) You can refer to the DMA HAL driver header file for more useful macros + + @endverbatim + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2016 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f0xx_hal.h" + +/** @addtogroup STM32F0xx_HAL_Driver + * @{ + */ + + +/** @defgroup DMA DMA + * @brief DMA HAL module driver + * @{ + */ + +#ifdef HAL_DMA_MODULE_ENABLED + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/** @defgroup DMA_Private_Functions DMA Private Functions + * @{ + */ +static void DMA_SetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength); +static void DMA_CalcBaseAndBitshift(DMA_HandleTypeDef *hdma); +/** + * @} + */ + +/* Exported functions ---------------------------------------------------------*/ + +/** @defgroup DMA_Exported_Functions DMA Exported Functions + * @{ + */ + +/** @defgroup DMA_Exported_Functions_Group1 Initialization and de-initialization functions + * @brief Initialization and de-initialization functions + * +@verbatim + =============================================================================== + ##### Initialization and de-initialization functions ##### + =============================================================================== + [..] + This section provides functions allowing to initialize the DMA Channel source + and destination addresses, incrementation and data sizes, transfer direction, + circular/normal mode selection, memory-to-memory mode selection and Channel priority value. + [..] + The HAL_DMA_Init() function follows the DMA configuration procedures as described in + reference manual. + +@endverbatim + * @{ + */ + +/** + * @brief Initialize the DMA according to the specified + * parameters in the DMA_InitTypeDef and initialize the associated handle. + * @param hdma Pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA Channel. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DMA_Init(DMA_HandleTypeDef *hdma) +{ + uint32_t tmp = 0U; + + /* Check the DMA handle allocation */ + if(NULL == hdma) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_DMA_ALL_INSTANCE(hdma->Instance)); + assert_param(IS_DMA_DIRECTION(hdma->Init.Direction)); + assert_param(IS_DMA_PERIPHERAL_INC_STATE(hdma->Init.PeriphInc)); + assert_param(IS_DMA_MEMORY_INC_STATE(hdma->Init.MemInc)); + assert_param(IS_DMA_PERIPHERAL_DATA_SIZE(hdma->Init.PeriphDataAlignment)); + assert_param(IS_DMA_MEMORY_DATA_SIZE(hdma->Init.MemDataAlignment)); + assert_param(IS_DMA_MODE(hdma->Init.Mode)); + assert_param(IS_DMA_PRIORITY(hdma->Init.Priority)); + + /* Change DMA peripheral state */ + hdma->State = HAL_DMA_STATE_BUSY; + + /* Get the CR register value */ + tmp = hdma->Instance->CCR; + + /* Clear PL, MSIZE, PSIZE, MINC, PINC, CIRC, DIR bits */ + tmp &= ((uint32_t)~(DMA_CCR_PL | DMA_CCR_MSIZE | DMA_CCR_PSIZE | \ + DMA_CCR_MINC | DMA_CCR_PINC | DMA_CCR_CIRC | \ + DMA_CCR_DIR)); + + /* Prepare the DMA Channel configuration */ + tmp |= hdma->Init.Direction | + hdma->Init.PeriphInc | hdma->Init.MemInc | + hdma->Init.PeriphDataAlignment | hdma->Init.MemDataAlignment | + hdma->Init.Mode | hdma->Init.Priority; + + /* Write to DMA Channel CR register */ + hdma->Instance->CCR = tmp; + + /* Initialize DmaBaseAddress and ChannelIndex parameters used + by HAL_DMA_IRQHandler() and HAL_DMA_PollForTransfer() */ + DMA_CalcBaseAndBitshift(hdma); + + /* Initialise the error code */ + hdma->ErrorCode = HAL_DMA_ERROR_NONE; + + /* Initialize the DMA state*/ + hdma->State = HAL_DMA_STATE_READY; + + /* Allocate lock resource and initialize it */ + hdma->Lock = HAL_UNLOCKED; + + return HAL_OK; +} + +/** + * @brief DeInitialize the DMA peripheral + * @param hdma pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA Channel. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DMA_DeInit(DMA_HandleTypeDef *hdma) +{ + /* Check the DMA handle allocation */ + if(NULL == hdma) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_DMA_ALL_INSTANCE(hdma->Instance)); + + /* Disable the selected DMA Channelx */ + hdma->Instance->CCR &= ~DMA_CCR_EN; + + /* Reset DMA Channel control register */ + hdma->Instance->CCR = 0U; + + /* Reset DMA Channel Number of Data to Transfer register */ + hdma->Instance->CNDTR = 0U; + + /* Reset DMA Channel peripheral address register */ + hdma->Instance->CPAR = 0U; + + /* Reset DMA Channel memory address register */ + hdma->Instance->CMAR = 0U; + +/* Get DMA Base Address */ + DMA_CalcBaseAndBitshift(hdma); + + /* Clear all flags */ + hdma->DmaBaseAddress->IFCR = DMA_FLAG_GL1 << hdma->ChannelIndex; + + /* Clean callbacks */ + hdma->XferCpltCallback = NULL; + hdma->XferHalfCpltCallback = NULL; + hdma->XferErrorCallback = NULL; + hdma->XferAbortCallback = NULL; + + /* Reset the error code */ + hdma->ErrorCode = HAL_DMA_ERROR_NONE; + + /* Reset the DMA state */ + hdma->State = HAL_DMA_STATE_RESET; + + /* Release Lock */ + __HAL_UNLOCK(hdma); + + return HAL_OK; +} + +/** + * @} + */ + +/** @defgroup DMA_Exported_Functions_Group2 Input and Output operation functions + * @brief I/O operation functions + * +@verbatim + =============================================================================== + ##### IO operation functions ##### + =============================================================================== + [..] This section provides functions allowing to: + (+) Configure the source, destination address and data length and Start DMA transfer + (+) Configure the source, destination address and data length and + Start DMA transfer with interrupt + (+) Abort DMA transfer + (+) Poll for transfer complete + (+) Handle DMA interrupt request + +@endverbatim + * @{ + */ + +/** + * @brief Start the DMA Transfer. + * @param hdma pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA Channel. + * @param SrcAddress The source memory Buffer address + * @param DstAddress The destination memory Buffer address + * @param DataLength The length of data to be transferred from source to destination + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DMA_Start(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check the parameters */ + assert_param(IS_DMA_BUFFER_SIZE(DataLength)); + + /* Process locked */ + __HAL_LOCK(hdma); + + if(HAL_DMA_STATE_READY == hdma->State) + { + /* Change DMA peripheral state */ + hdma->State = HAL_DMA_STATE_BUSY; + + hdma->ErrorCode = HAL_DMA_ERROR_NONE; + + /* Disable the peripheral */ + hdma->Instance->CCR &= ~DMA_CCR_EN; + + /* Configure the source, destination address and the data length */ + DMA_SetConfig(hdma, SrcAddress, DstAddress, DataLength); + + /* Enable the Peripheral */ + hdma->Instance->CCR |= DMA_CCR_EN; + } + else + { + /* Process Unlocked */ + __HAL_UNLOCK(hdma); + + /* Remain BUSY */ + status = HAL_BUSY; + } + + return status; +} + +/** + * @brief Start the DMA Transfer with interrupt enabled. + * @param hdma pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA Channel. + * @param SrcAddress The source memory Buffer address + * @param DstAddress The destination memory Buffer address + * @param DataLength The length of data to be transferred from source to destination + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DMA_Start_IT(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check the parameters */ + assert_param(IS_DMA_BUFFER_SIZE(DataLength)); + + /* Process locked */ + __HAL_LOCK(hdma); + + if(HAL_DMA_STATE_READY == hdma->State) + { + /* Change DMA peripheral state */ + hdma->State = HAL_DMA_STATE_BUSY; + + hdma->ErrorCode = HAL_DMA_ERROR_NONE; + + /* Disable the peripheral */ + hdma->Instance->CCR &= ~DMA_CCR_EN; + + /* Configure the source, destination address and the data length */ + DMA_SetConfig(hdma, SrcAddress, DstAddress, DataLength); + + /* Enable the transfer complete, & transfer error interrupts */ + /* Half transfer interrupt is optional: enable it only if associated callback is available */ + if(NULL != hdma->XferHalfCpltCallback ) + { + hdma->Instance->CCR |= (DMA_IT_TC | DMA_IT_HT | DMA_IT_TE); + } + else + { + hdma->Instance->CCR |= (DMA_IT_TC | DMA_IT_TE); + hdma->Instance->CCR &= ~DMA_IT_HT; + } + + /* Enable the Peripheral */ + hdma->Instance->CCR |= DMA_CCR_EN; + } + else + { + /* Process Unlocked */ + __HAL_UNLOCK(hdma); + + /* Remain BUSY */ + status = HAL_BUSY; + } + + return status; +} + +/** + * @brief Abort the DMA Transfer. + * @param hdma pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA Channel. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DMA_Abort(DMA_HandleTypeDef *hdma) +{ + if(hdma->State != HAL_DMA_STATE_BUSY) + { + /* no transfer ongoing */ + hdma->ErrorCode = HAL_DMA_ERROR_NO_XFER; + + /* Process Unlocked */ + __HAL_UNLOCK(hdma); + + return HAL_ERROR; + } + else + { + /* Disable DMA IT */ + hdma->Instance->CCR &= ~(DMA_IT_TC | DMA_IT_HT | DMA_IT_TE); + + /* Disable the channel */ + hdma->Instance->CCR &= ~DMA_CCR_EN; + + /* Clear all flags */ + hdma->DmaBaseAddress->IFCR = (DMA_FLAG_GL1 << hdma->ChannelIndex); + } + /* Change the DMA state*/ + hdma->State = HAL_DMA_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hdma); + + return HAL_OK; +} + +/** + * @brief Abort the DMA Transfer in Interrupt mode. + * @param hdma pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA Stream. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DMA_Abort_IT(DMA_HandleTypeDef *hdma) +{ + HAL_StatusTypeDef status = HAL_OK; + + if(HAL_DMA_STATE_BUSY != hdma->State) + { + /* no transfer ongoing */ + hdma->ErrorCode = HAL_DMA_ERROR_NO_XFER; + + status = HAL_ERROR; + } + else + { + + /* Disable DMA IT */ + hdma->Instance->CCR &= ~(DMA_IT_TC | DMA_IT_HT | DMA_IT_TE); + + /* Disable the channel */ + hdma->Instance->CCR &= ~DMA_CCR_EN; + + /* Clear all flags */ + hdma->DmaBaseAddress->IFCR = DMA_FLAG_GL1 << hdma->ChannelIndex; + + /* Change the DMA state */ + hdma->State = HAL_DMA_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hdma); + + /* Call User Abort callback */ + if(hdma->XferAbortCallback != NULL) + { + hdma->XferAbortCallback(hdma); + } + } + return status; +} + +/** + * @brief Polling for transfer complete. + * @param hdma pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA Channel. + * @param CompleteLevel Specifies the DMA level complete. + * @param Timeout Timeout duration. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DMA_PollForTransfer(DMA_HandleTypeDef *hdma, uint32_t CompleteLevel, uint32_t Timeout) +{ + uint32_t temp; + uint32_t tickstart = 0U; + + if(HAL_DMA_STATE_BUSY != hdma->State) + { + /* no transfer ongoing */ + hdma->ErrorCode = HAL_DMA_ERROR_NO_XFER; + __HAL_UNLOCK(hdma); + return HAL_ERROR; + } + + /* Polling mode not supported in circular mode */ + if (RESET != (hdma->Instance->CCR & DMA_CCR_CIRC)) + { + hdma->ErrorCode = HAL_DMA_ERROR_NOT_SUPPORTED; + return HAL_ERROR; + } + + /* Get the level transfer complete flag */ + if(HAL_DMA_FULL_TRANSFER == CompleteLevel) + { + /* Transfer Complete flag */ + temp = DMA_FLAG_TC1 << hdma->ChannelIndex; + } + else + { + /* Half Transfer Complete flag */ + temp = DMA_FLAG_HT1 << hdma->ChannelIndex; + } + + /* Get tick */ + tickstart = HAL_GetTick(); + + while(RESET == (hdma->DmaBaseAddress->ISR & temp)) + { + if(RESET != (hdma->DmaBaseAddress->ISR & (DMA_FLAG_TE1 << hdma->ChannelIndex))) + { + /* When a DMA transfer error occurs */ + /* A hardware clear of its EN bits is performed */ + /* Clear all flags */ + hdma->DmaBaseAddress->IFCR = DMA_FLAG_GL1 << hdma->ChannelIndex; + + /* Update error code */ + hdma->ErrorCode = HAL_DMA_ERROR_TE; + + /* Change the DMA state */ + hdma->State= HAL_DMA_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hdma); + + return HAL_ERROR; + } + /* Check for the Timeout */ + if(Timeout != HAL_MAX_DELAY) + { + if((Timeout == 0U) || ((HAL_GetTick() - tickstart) > Timeout)) + { + /* Update error code */ + hdma->ErrorCode = HAL_DMA_ERROR_TIMEOUT; + + /* Change the DMA state */ + hdma->State = HAL_DMA_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hdma); + + return HAL_ERROR; + } + } + } + + if(HAL_DMA_FULL_TRANSFER == CompleteLevel) + { + /* Clear the transfer complete flag */ + hdma->DmaBaseAddress->IFCR = DMA_FLAG_TC1 << hdma->ChannelIndex; + + /* The selected Channelx EN bit is cleared (DMA is disabled and + all transfers are complete) */ + hdma->State = HAL_DMA_STATE_READY; + } + else + { + /* Clear the half transfer complete flag */ + hdma->DmaBaseAddress->IFCR = DMA_FLAG_HT1 << hdma->ChannelIndex; + } + + /* Process unlocked */ + __HAL_UNLOCK(hdma); + + return HAL_OK; +} + +/** + * @brief Handle DMA interrupt request. + * @param hdma pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA Channel. + * @retval None + */ +void HAL_DMA_IRQHandler(DMA_HandleTypeDef *hdma) +{ + uint32_t flag_it = hdma->DmaBaseAddress->ISR; + uint32_t source_it = hdma->Instance->CCR; + + /* Half Transfer Complete Interrupt management ******************************/ + if ((RESET != (flag_it & (DMA_FLAG_HT1 << hdma->ChannelIndex))) && (RESET != (source_it & DMA_IT_HT))) + { + /* Disable the half transfer interrupt if the DMA mode is not CIRCULAR */ + if((hdma->Instance->CCR & DMA_CCR_CIRC) == 0U) + { + /* Disable the half transfer interrupt */ + hdma->Instance->CCR &= ~DMA_IT_HT; + } + + /* Clear the half transfer complete flag */ + hdma->DmaBaseAddress->IFCR = DMA_FLAG_HT1 << hdma->ChannelIndex; + + /* DMA peripheral state is not updated in Half Transfer */ + /* State is updated only in Transfer Complete case */ + + if(hdma->XferHalfCpltCallback != NULL) + { + /* Half transfer callback */ + hdma->XferHalfCpltCallback(hdma); + } + } + + /* Transfer Complete Interrupt management ***********************************/ + else if ((RESET != (flag_it & (DMA_FLAG_TC1 << hdma->ChannelIndex))) && (RESET != (source_it & DMA_IT_TC))) + { + if((hdma->Instance->CCR & DMA_CCR_CIRC) == 0U) + { + /* Disable the transfer complete & transfer error interrupts */ + /* if the DMA mode is not CIRCULAR */ + hdma->Instance->CCR &= ~(DMA_IT_TC | DMA_IT_TE); + + /* Change the DMA state */ + hdma->State = HAL_DMA_STATE_READY; + } + + /* Clear the transfer complete flag */ + hdma->DmaBaseAddress->IFCR = DMA_FLAG_TC1 << hdma->ChannelIndex; + + /* Process Unlocked */ + __HAL_UNLOCK(hdma); + + if(hdma->XferCpltCallback != NULL) + { + /* Transfer complete callback */ + hdma->XferCpltCallback(hdma); + } + } + + /* Transfer Error Interrupt management ***************************************/ + else if (( RESET != (flag_it & (DMA_FLAG_TE1 << hdma->ChannelIndex))) && (RESET != (source_it & DMA_IT_TE))) + { + /* When a DMA transfer error occurs */ + /* A hardware clear of its EN bits is performed */ + /* Then, disable all DMA interrupts */ + hdma->Instance->CCR &= ~(DMA_IT_TC | DMA_IT_HT | DMA_IT_TE); + + /* Clear all flags */ + hdma->DmaBaseAddress->IFCR = DMA_FLAG_GL1 << hdma->ChannelIndex; + + /* Update error code */ + hdma->ErrorCode = HAL_DMA_ERROR_TE; + + /* Change the DMA state */ + hdma->State = HAL_DMA_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hdma); + + if(hdma->XferErrorCallback != NULL) + { + /* Transfer error callback */ + hdma->XferErrorCallback(hdma); + } + } +} + +/** + * @brief Register callbacks + * @param hdma pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA Stream. + * @param CallbackID User Callback identifer + * a HAL_DMA_CallbackIDTypeDef ENUM as parameter. + * @param pCallback pointer to private callback function which has pointer to + * a DMA_HandleTypeDef structure as parameter. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DMA_RegisterCallback(DMA_HandleTypeDef *hdma, HAL_DMA_CallbackIDTypeDef CallbackID, void (* pCallback)( DMA_HandleTypeDef * _hdma)) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Process locked */ + __HAL_LOCK(hdma); + + if(HAL_DMA_STATE_READY == hdma->State) + { + switch (CallbackID) + { + case HAL_DMA_XFER_CPLT_CB_ID: + hdma->XferCpltCallback = pCallback; + break; + + case HAL_DMA_XFER_HALFCPLT_CB_ID: + hdma->XferHalfCpltCallback = pCallback; + break; + + case HAL_DMA_XFER_ERROR_CB_ID: + hdma->XferErrorCallback = pCallback; + break; + + case HAL_DMA_XFER_ABORT_CB_ID: + hdma->XferAbortCallback = pCallback; + break; + + default: + status = HAL_ERROR; + break; + } + } + else + { + status = HAL_ERROR; + } + + /* Release Lock */ + __HAL_UNLOCK(hdma); + + return status; +} + +/** + * @brief UnRegister callbacks + * @param hdma pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA Stream. + * @param CallbackID User Callback identifer + * a HAL_DMA_CallbackIDTypeDef ENUM as parameter. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DMA_UnRegisterCallback(DMA_HandleTypeDef *hdma, HAL_DMA_CallbackIDTypeDef CallbackID) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Process locked */ + __HAL_LOCK(hdma); + + if(HAL_DMA_STATE_READY == hdma->State) + { + switch (CallbackID) + { + case HAL_DMA_XFER_CPLT_CB_ID: + hdma->XferCpltCallback = NULL; + break; + + case HAL_DMA_XFER_HALFCPLT_CB_ID: + hdma->XferHalfCpltCallback = NULL; + break; + + case HAL_DMA_XFER_ERROR_CB_ID: + hdma->XferErrorCallback = NULL; + break; + + case HAL_DMA_XFER_ABORT_CB_ID: + hdma->XferAbortCallback = NULL; + break; + + case HAL_DMA_XFER_ALL_CB_ID: + hdma->XferCpltCallback = NULL; + hdma->XferHalfCpltCallback = NULL; + hdma->XferErrorCallback = NULL; + hdma->XferAbortCallback = NULL; + break; + + default: + status = HAL_ERROR; + break; + } + } + else + { + status = HAL_ERROR; + } + + /* Release Lock */ + __HAL_UNLOCK(hdma); + + return status; +} + +/** + * @} + */ + +/** @defgroup DMA_Exported_Functions_Group3 Peripheral State functions + * @brief Peripheral State functions + * +@verbatim + =============================================================================== + ##### State and Errors functions ##### + =============================================================================== + [..] + This subsection provides functions allowing to + (+) Check the DMA state + (+) Get error code + +@endverbatim + * @{ + */ + +/** + * @brief Returns the DMA state. + * @param hdma pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA Channel. + * @retval HAL state + */ +HAL_DMA_StateTypeDef HAL_DMA_GetState(DMA_HandleTypeDef *hdma) +{ + return hdma->State; +} + +/** + * @brief Return the DMA error code + * @param hdma pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA Channel. + * @retval DMA Error Code + */ +uint32_t HAL_DMA_GetError(DMA_HandleTypeDef *hdma) +{ + return hdma->ErrorCode; +} + +/** + * @} + */ + +/** + * @} + */ + +/** @addtogroup DMA_Private_Functions + * @{ + */ + +/** + * @brief Set the DMA Transfer parameters. + * @param hdma pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA Channel. + * @param SrcAddress The source memory Buffer address + * @param DstAddress The destination memory Buffer address + * @param DataLength The length of data to be transferred from source to destination + * @retval HAL status + */ +static void DMA_SetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength) +{ + /* Clear all flags */ + hdma->DmaBaseAddress->IFCR = (DMA_FLAG_GL1 << hdma->ChannelIndex); + + /* Configure DMA Channel data length */ + hdma->Instance->CNDTR = DataLength; + + /* Memory to Peripheral */ + if((hdma->Init.Direction) == DMA_MEMORY_TO_PERIPH) + { + /* Configure DMA Channel destination address */ + hdma->Instance->CPAR = DstAddress; + + /* Configure DMA Channel source address */ + hdma->Instance->CMAR = SrcAddress; + } + /* Peripheral to Memory */ + else + { + /* Configure DMA Channel source address */ + hdma->Instance->CPAR = SrcAddress; + + /* Configure DMA Channel destination address */ + hdma->Instance->CMAR = DstAddress; + } +} + +/** + * @brief set the DMA base address and channel index depending on DMA instance + * @param hdma pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA Stream. + * @retval None + */ +static void DMA_CalcBaseAndBitshift(DMA_HandleTypeDef *hdma) +{ +#if defined (DMA2) + /* calculation of the channel index */ + if ((uint32_t)(hdma->Instance) < (uint32_t)(DMA2_Channel1)) + { + /* DMA1 */ + hdma->ChannelIndex = (((uint32_t)hdma->Instance - (uint32_t)DMA1_Channel1) / ((uint32_t)DMA1_Channel2 - (uint32_t)DMA1_Channel1)) << 2U; + hdma->DmaBaseAddress = DMA1; + } + else + { + /* DMA2 */ + hdma->ChannelIndex = (((uint32_t)hdma->Instance - (uint32_t)DMA2_Channel1) / ((uint32_t)DMA2_Channel2 - (uint32_t)DMA2_Channel1)) << 2U; + hdma->DmaBaseAddress = DMA2; + } +#else + /* calculation of the channel index */ + /* DMA1 */ + hdma->ChannelIndex = (((uint32_t)hdma->Instance - (uint32_t)DMA1_Channel1) / ((uint32_t)DMA1_Channel2 - (uint32_t)DMA1_Channel1)) << 2U; + hdma->DmaBaseAddress = DMA1; +#endif +} + +/** + * @} + */ + +/** + * @} + */ +#endif /* HAL_DMA_MODULE_ENABLED */ + +/** + * @} + */ + + /** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.c b/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.c new file mode 100644 index 0000000..1adb8f7 --- /dev/null +++ b/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.c @@ -0,0 +1,559 @@ +/** + ****************************************************************************** + * @file stm32f0xx_hal_exti.c + * @author MCD Application Team + * @brief EXTI HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the Extended Interrupts and events controller (EXTI) peripheral: + * + Initialization and de-initialization functions + * + IO operation functions + * + @verbatim + ============================================================================== + ##### EXTI Peripheral features ##### + ============================================================================== + [..] + (+) Each Exti line can be configured within this driver. + + (+) Exti line can be configured in 3 different modes + (++) Interrupt + (++) Event + (++) Both of them + + (+) Configurable Exti lines can be configured with 3 different triggers + (++) Rising + (++) Falling + (++) Both of them + + (+) When set in interrupt mode, configurable Exti lines have two different + interrupts pending registers which allow to distinguish which transition + occurs: + (++) Rising edge pending interrupt + (++) Falling + + (+) Exti lines 0 to 15 are linked to gpio pin number 0 to 15. Gpio port can + be selected through multiplexer. + + ##### How to use this driver ##### + ============================================================================== + [..] + + (#) Configure the EXTI line using HAL_EXTI_SetConfigLine(). + (++) Choose the interrupt line number by setting "Line" member from + EXTI_ConfigTypeDef structure. + (++) Configure the interrupt and/or event mode using "Mode" member from + EXTI_ConfigTypeDef structure. + (++) For configurable lines, configure rising and/or falling trigger + "Trigger" member from EXTI_ConfigTypeDef structure. + (++) For Exti lines linked to gpio, choose gpio port using "GPIOSel" + member from GPIO_InitTypeDef structure. + + (#) Get current Exti configuration of a dedicated line using + HAL_EXTI_GetConfigLine(). + (++) Provide exiting handle as parameter. + (++) Provide pointer on EXTI_ConfigTypeDef structure as second parameter. + + (#) Clear Exti configuration of a dedicated line using HAL_EXTI_GetConfigLine(). + (++) Provide exiting handle as parameter. + + (#) Register callback to treat Exti interrupts using HAL_EXTI_RegisterCallback(). + (++) Provide exiting handle as first parameter. + (++) Provide which callback will be registered using one value from + EXTI_CallbackIDTypeDef. + (++) Provide callback function pointer. + + (#) Get interrupt pending bit using HAL_EXTI_GetPending(). + + (#) Clear interrupt pending bit using HAL_EXTI_GetPending(). + + (#) Generate software interrupt using HAL_EXTI_GenerateSWI(). + + @endverbatim + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2019 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f0xx_hal.h" + +/** @addtogroup STM32F0xx_HAL_Driver + * @{ + */ + +/** @addtogroup EXTI + * @{ + */ +/** MISRA C:2012 deviation rule has been granted for following rule: + * Rule-18.1_b - Medium: Array `EXTICR' 1st subscript interval [0,7] may be out + * of bounds [0,3] in following API : + * HAL_EXTI_SetConfigLine + * HAL_EXTI_GetConfigLine + * HAL_EXTI_ClearConfigLine + */ + +#ifdef HAL_EXTI_MODULE_ENABLED + +/* Private typedef -----------------------------------------------------------*/ +/* Private defines -----------------------------------------------------------*/ +/** @defgroup EXTI_Private_Constants EXTI Private Constants + * @{ + */ + +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ + +/** @addtogroup EXTI_Exported_Functions + * @{ + */ + +/** @addtogroup EXTI_Exported_Functions_Group1 + * @brief Configuration functions + * +@verbatim + =============================================================================== + ##### Configuration functions ##### + =============================================================================== + +@endverbatim + * @{ + */ + +/** + * @brief Set configuration of a dedicated Exti line. + * @param hexti Exti handle. + * @param pExtiConfig Pointer on EXTI configuration to be set. + * @retval HAL Status. + */ +HAL_StatusTypeDef HAL_EXTI_SetConfigLine(EXTI_HandleTypeDef *hexti, EXTI_ConfigTypeDef *pExtiConfig) +{ + uint32_t regval; + uint32_t linepos; + uint32_t maskline; + + /* Check null pointer */ + if ((hexti == NULL) || (pExtiConfig == NULL)) + { + return HAL_ERROR; + } + + /* Check parameters */ + assert_param(IS_EXTI_LINE(pExtiConfig->Line)); + assert_param(IS_EXTI_MODE(pExtiConfig->Mode)); + + /* Assign line number to handle */ + hexti->Line = pExtiConfig->Line; + + /* Compute line mask */ + linepos = (pExtiConfig->Line & EXTI_PIN_MASK); + maskline = (1uL << linepos); + + /* Configure triggers for configurable lines */ + if ((pExtiConfig->Line & EXTI_CONFIG) != 0x00u) + { + assert_param(IS_EXTI_TRIGGER(pExtiConfig->Trigger)); + + /* Configure rising trigger */ + /* Mask or set line */ + if ((pExtiConfig->Trigger & EXTI_TRIGGER_RISING) != 0x00u) + { + EXTI->RTSR |= maskline; + } + else + { + EXTI->RTSR &= ~maskline; + } + + /* Configure falling trigger */ + /* Mask or set line */ + if ((pExtiConfig->Trigger & EXTI_TRIGGER_FALLING) != 0x00u) + { + EXTI->FTSR |= maskline; + } + else + { + EXTI->FTSR &= ~maskline; + } + + + /* Configure gpio port selection in case of gpio exti line */ + if ((pExtiConfig->Line & EXTI_GPIO) == EXTI_GPIO) + { + assert_param(IS_EXTI_GPIO_PORT(pExtiConfig->GPIOSel)); + assert_param(IS_EXTI_GPIO_PIN(linepos)); + + regval = SYSCFG->EXTICR[linepos >> 2u]; + regval &= ~(SYSCFG_EXTICR1_EXTI0 << (SYSCFG_EXTICR1_EXTI1_Pos * (linepos & 0x03u))); + regval |= (pExtiConfig->GPIOSel << (SYSCFG_EXTICR1_EXTI1_Pos * (linepos & 0x03u))); + SYSCFG->EXTICR[linepos >> 2u] = regval; + } + } + + /* Configure interrupt mode : read current mode */ + /* Mask or set line */ + if ((pExtiConfig->Mode & EXTI_MODE_INTERRUPT) != 0x00u) + { + EXTI->IMR |= maskline; + } + else + { + EXTI->IMR &= ~maskline; + } + + /* Configure event mode : read current mode */ + /* Mask or set line */ + if ((pExtiConfig->Mode & EXTI_MODE_EVENT) != 0x00u) + { + EXTI->EMR |= maskline; + } + else + { + EXTI->EMR &= ~maskline; + } + + return HAL_OK; +} + +/** + * @brief Get configuration of a dedicated Exti line. + * @param hexti Exti handle. + * @param pExtiConfig Pointer on structure to store Exti configuration. + * @retval HAL Status. + */ +HAL_StatusTypeDef HAL_EXTI_GetConfigLine(EXTI_HandleTypeDef *hexti, EXTI_ConfigTypeDef *pExtiConfig) +{ + uint32_t regval; + uint32_t linepos; + uint32_t maskline; + + /* Check null pointer */ + if ((hexti == NULL) || (pExtiConfig == NULL)) + { + return HAL_ERROR; + } + + /* Check the parameter */ + assert_param(IS_EXTI_LINE(hexti->Line)); + + /* Store handle line number to configuration structure */ + pExtiConfig->Line = hexti->Line; + + /* Compute line mask */ + linepos = (pExtiConfig->Line & EXTI_PIN_MASK); + maskline = (1uL << linepos); + + /* 1] Get core mode : interrupt */ + + /* Check if selected line is enable */ + if ((EXTI->IMR & maskline) != 0x00u) + { + pExtiConfig->Mode = EXTI_MODE_INTERRUPT; + } + else + { + pExtiConfig->Mode = EXTI_MODE_NONE; + } + + /* Get event mode */ + /* Check if selected line is enable */ + if ((EXTI->EMR & maskline) != 0x00u) + { + pExtiConfig->Mode |= EXTI_MODE_EVENT; + } + + /* 2] Get trigger for configurable lines : rising */ + if ((pExtiConfig->Line & EXTI_CONFIG) != 0x00u) + { + /* Check if configuration of selected line is enable */ + if ((EXTI->RTSR & maskline) != 0x00u) + { + pExtiConfig->Trigger = EXTI_TRIGGER_RISING; + } + else + { + pExtiConfig->Trigger = EXTI_TRIGGER_NONE; + } + + /* Get falling configuration */ + /* Check if configuration of selected line is enable */ + if ((EXTI->FTSR & maskline) != 0x00u) + { + pExtiConfig->Trigger |= EXTI_TRIGGER_FALLING; + } + + /* Get Gpio port selection for gpio lines */ + if ((pExtiConfig->Line & EXTI_GPIO) == EXTI_GPIO) + { + assert_param(IS_EXTI_GPIO_PIN(linepos)); + + regval = SYSCFG->EXTICR[linepos >> 2u]; + pExtiConfig->GPIOSel = ((regval << (SYSCFG_EXTICR1_EXTI1_Pos * (3uL - (linepos & 0x03u)))) >> 24); + } + else + { + pExtiConfig->GPIOSel = 0x00u; + } + } + else + { + /* No Trigger selected */ + pExtiConfig->Trigger = EXTI_TRIGGER_NONE; + pExtiConfig->GPIOSel = 0x00u; + } + + return HAL_OK; +} + +/** + * @brief Clear whole configuration of a dedicated Exti line. + * @param hexti Exti handle. + * @retval HAL Status. + */ +HAL_StatusTypeDef HAL_EXTI_ClearConfigLine(EXTI_HandleTypeDef *hexti) +{ + uint32_t regval; + uint32_t linepos; + uint32_t maskline; + + /* Check null pointer */ + if (hexti == NULL) + { + return HAL_ERROR; + } + + /* Check the parameter */ + assert_param(IS_EXTI_LINE(hexti->Line)); + + /* compute line mask */ + linepos = (hexti->Line & EXTI_PIN_MASK); + maskline = (1uL << linepos); + + /* 1] Clear interrupt mode */ + EXTI->IMR = (EXTI->IMR & ~maskline); + + /* 2] Clear event mode */ + EXTI->EMR = (EXTI->EMR & ~maskline); + + /* 3] Clear triggers in case of configurable lines */ + if ((hexti->Line & EXTI_CONFIG) != 0x00u) + { + EXTI->RTSR = (EXTI->RTSR & ~maskline); + EXTI->FTSR = (EXTI->FTSR & ~maskline); + + /* Get Gpio port selection for gpio lines */ + if ((hexti->Line & EXTI_GPIO) == EXTI_GPIO) + { + assert_param(IS_EXTI_GPIO_PIN(linepos)); + + regval = SYSCFG->EXTICR[linepos >> 2u]; + regval &= ~(SYSCFG_EXTICR1_EXTI0 << (SYSCFG_EXTICR1_EXTI1_Pos * (linepos & 0x03u))); + SYSCFG->EXTICR[linepos >> 2u] = regval; + } + } + + return HAL_OK; +} + +/** + * @brief Register callback for a dedicated Exti line. + * @param hexti Exti handle. + * @param CallbackID User callback identifier. + * This parameter can be one of @arg @ref EXTI_CallbackIDTypeDef values. + * @param pPendingCbfn function pointer to be stored as callback. + * @retval HAL Status. + */ +HAL_StatusTypeDef HAL_EXTI_RegisterCallback(EXTI_HandleTypeDef *hexti, EXTI_CallbackIDTypeDef CallbackID, void (*pPendingCbfn)(void)) +{ + HAL_StatusTypeDef status = HAL_OK; + + switch (CallbackID) + { + case HAL_EXTI_COMMON_CB_ID: + hexti->PendingCallback = pPendingCbfn; + break; + + default: + status = HAL_ERROR; + break; + } + + return status; +} + +/** + * @brief Store line number as handle private field. + * @param hexti Exti handle. + * @param ExtiLine Exti line number. + * This parameter can be from 0 to @ref EXTI_LINE_NB. + * @retval HAL Status. + */ +HAL_StatusTypeDef HAL_EXTI_GetHandle(EXTI_HandleTypeDef *hexti, uint32_t ExtiLine) +{ + /* Check the parameters */ + assert_param(IS_EXTI_LINE(ExtiLine)); + + /* Check null pointer */ + if (hexti == NULL) + { + return HAL_ERROR; + } + else + { + /* Store line number as handle private field */ + hexti->Line = ExtiLine; + + return HAL_OK; + } +} + +/** + * @} + */ + +/** @addtogroup EXTI_Exported_Functions_Group2 + * @brief EXTI IO functions. + * +@verbatim + =============================================================================== + ##### IO operation functions ##### + =============================================================================== + +@endverbatim + * @{ + */ + +/** + * @brief Handle EXTI interrupt request. + * @param hexti Exti handle. + * @retval none. + */ +void HAL_EXTI_IRQHandler(EXTI_HandleTypeDef *hexti) +{ + uint32_t regval; + uint32_t maskline; + + /* Compute line mask */ + maskline = (1uL << (hexti->Line & EXTI_PIN_MASK)); + + /* Get pending bit */ + regval = (EXTI->PR & maskline); + if (regval != 0x00u) + { + /* Clear pending bit */ + EXTI->PR = maskline; + + /* Call callback */ + if (hexti->PendingCallback != NULL) + { + hexti->PendingCallback(); + } + } +} + +/** + * @brief Get interrupt pending bit of a dedicated line. + * @param hexti Exti handle. + * @param Edge Specify which pending edge as to be checked. + * This parameter can be one of the following values: + * @arg @ref EXTI_TRIGGER_RISING_FALLING + * This parameter is kept for compatibility with other series. + * @retval 1 if interrupt is pending else 0. + */ +uint32_t HAL_EXTI_GetPending(EXTI_HandleTypeDef *hexti, uint32_t Edge) +{ + uint32_t regval; + uint32_t linepos; + uint32_t maskline; + + /* Check parameters */ + assert_param(IS_EXTI_LINE(hexti->Line)); + assert_param(IS_EXTI_CONFIG_LINE(hexti->Line)); + assert_param(IS_EXTI_PENDING_EDGE(Edge)); + + /* Compute line mask */ + linepos = (hexti->Line & EXTI_PIN_MASK); + maskline = (1uL << linepos); + + /* return 1 if bit is set else 0 */ + regval = ((EXTI->PR & maskline) >> linepos); + return regval; +} + +/** + * @brief Clear interrupt pending bit of a dedicated line. + * @param hexti Exti handle. + * @param Edge Specify which pending edge as to be clear. + * This parameter can be one of the following values: + * @arg @ref EXTI_TRIGGER_RISING_FALLING + * This parameter is kept for compatibility with other series. + * @retval None. + */ +void HAL_EXTI_ClearPending(EXTI_HandleTypeDef *hexti, uint32_t Edge) +{ + uint32_t maskline; + + /* Check parameters */ + assert_param(IS_EXTI_LINE(hexti->Line)); + assert_param(IS_EXTI_CONFIG_LINE(hexti->Line)); + assert_param(IS_EXTI_PENDING_EDGE(Edge)); + + /* Compute line mask */ + maskline = (1uL << (hexti->Line & EXTI_PIN_MASK)); + + /* Clear Pending bit */ + EXTI->PR = maskline; +} + +/** + * @brief Generate a software interrupt for a dedicated line. + * @param hexti Exti handle. + * @retval None. + */ +void HAL_EXTI_GenerateSWI(EXTI_HandleTypeDef *hexti) +{ + uint32_t maskline; + + /* Check parameters */ + assert_param(IS_EXTI_LINE(hexti->Line)); + assert_param(IS_EXTI_CONFIG_LINE(hexti->Line)); + + /* Compute line mask */ + maskline = (1uL << (hexti->Line & EXTI_PIN_MASK)); + + /* Generate Software interrupt */ + EXTI->SWIER = maskline; +} + +/** + * @} + */ + +/** + * @} + */ + +#endif /* HAL_EXTI_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.c b/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.c new file mode 100644 index 0000000..94ad6e9 --- /dev/null +++ b/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.c @@ -0,0 +1,694 @@ +/** + ****************************************************************************** + * @file stm32f0xx_hal_flash.c + * @author MCD Application Team + * @brief FLASH HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the internal FLASH memory: + * + Program operations functions + * + Memory Control functions + * + Peripheral State functions + * + @verbatim + ============================================================================== + ##### FLASH peripheral features ##### + ============================================================================== + [..] The Flash memory interface manages CPU AHB I-Code and D-Code accesses + to the Flash memory. It implements the erase and program Flash memory operations + and the read and write protection mechanisms. + + [..] The Flash memory interface accelerates code execution with a system of instruction + prefetch. + + [..] The FLASH main features are: + (+) Flash memory read operations + (+) Flash memory program/erase operations + (+) Read / write protections + (+) Prefetch on I-Code + (+) Option Bytes programming + + + ##### How to use this driver ##### + ============================================================================== + [..] + This driver provides functions and macros to configure and program the FLASH + memory of all STM32F0xx devices. + + (#) FLASH Memory I/O Programming functions: this group includes all needed + functions to erase and program the main memory: + (++) Lock and Unlock the FLASH interface + (++) Erase function: Erase page, erase all pages + (++) Program functions: half word, word and doubleword + (#) FLASH Option Bytes Programming functions: this group includes all needed + functions to manage the Option Bytes: + (++) Lock and Unlock the Option Bytes + (++) Set/Reset the write protection + (++) Set the Read protection Level + (++) Program the user Option Bytes + (++) Launch the Option Bytes loader + (++) Erase Option Bytes + (++) Program the data Option Bytes + (++) Get the Write protection. + (++) Get the user option bytes. + + (#) Interrupts and flags management functions : this group + includes all needed functions to: + (++) Handle FLASH interrupts + (++) Wait for last FLASH operation according to its status + (++) Get error flag status + + [..] In addition to these function, this driver includes a set of macros allowing + to handle the following operations: + + (+) Set/Get the latency + (+) Enable/Disable the prefetch buffer + (+) Enable/Disable the FLASH interrupts + (+) Monitor the FLASH flags status + + @endverbatim + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2016 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f0xx_hal.h" + +/** @addtogroup STM32F0xx_HAL_Driver + * @{ + */ + +#ifdef HAL_FLASH_MODULE_ENABLED + +/** @defgroup FLASH FLASH + * @brief FLASH HAL module driver + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/** @defgroup FLASH_Private_Constants FLASH Private Constants + * @{ + */ +/** + * @} + */ + +/* Private macro ---------------------------- ---------------------------------*/ +/** @defgroup FLASH_Private_Macros FLASH Private Macros + * @{ + */ + +/** + * @} + */ + +/* Private variables ---------------------------------------------------------*/ +/** @defgroup FLASH_Private_Variables FLASH Private Variables + * @{ + */ +/* Variables used for Erase pages under interruption*/ +FLASH_ProcessTypeDef pFlash; +/** + * @} + */ + +/* Private function prototypes -----------------------------------------------*/ +/** @defgroup FLASH_Private_Functions FLASH Private Functions + * @{ + */ +static void FLASH_Program_HalfWord(uint32_t Address, uint16_t Data); +static void FLASH_SetErrorCode(void); +extern void FLASH_PageErase(uint32_t PageAddress); +/** + * @} + */ + +/* Exported functions ---------------------------------------------------------*/ +/** @defgroup FLASH_Exported_Functions FLASH Exported Functions + * @{ + */ + +/** @defgroup FLASH_Exported_Functions_Group1 Programming operation functions + * @brief Programming operation functions + * +@verbatim +@endverbatim + * @{ + */ + +/** + * @brief Program halfword, word or double word at a specified address + * @note The function HAL_FLASH_Unlock() should be called before to unlock the FLASH interface + * The function HAL_FLASH_Lock() should be called after to lock the FLASH interface + * + * @note If an erase and a program operations are requested simultaneously, + * the erase operation is performed before the program one. + * + * @note FLASH should be previously erased before new programming (only exception to this + * is when 0x0000 is programmed) + * + * @param TypeProgram Indicate the way to program at a specified address. + * This parameter can be a value of @ref FLASH_Type_Program + * @param Address Specifie the address to be programmed. + * @param Data Specifie the data to be programmed + * + * @retval HAL_StatusTypeDef HAL Status + */ +HAL_StatusTypeDef HAL_FLASH_Program(uint32_t TypeProgram, uint32_t Address, uint64_t Data) +{ + HAL_StatusTypeDef status = HAL_ERROR; + uint8_t index = 0U; + uint8_t nbiterations = 0U; + + /* Process Locked */ + __HAL_LOCK(&pFlash); + + /* Check the parameters */ + assert_param(IS_FLASH_TYPEPROGRAM(TypeProgram)); + assert_param(IS_FLASH_PROGRAM_ADDRESS(Address)); + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE); + + if(status == HAL_OK) + { + if(TypeProgram == FLASH_TYPEPROGRAM_HALFWORD) + { + /* Program halfword (16-bit) at a specified address. */ + nbiterations = 1U; + } + else if(TypeProgram == FLASH_TYPEPROGRAM_WORD) + { + /* Program word (32-bit = 2*16-bit) at a specified address. */ + nbiterations = 2U; + } + else + { + /* Program double word (64-bit = 4*16-bit) at a specified address. */ + nbiterations = 4U; + } + + for (index = 0U; index < nbiterations; index++) + { + FLASH_Program_HalfWord((Address + (2U*index)), (uint16_t)(Data >> (16U*index))); + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE); + + /* If the program operation is completed, disable the PG Bit */ + CLEAR_BIT(FLASH->CR, FLASH_CR_PG); + /* In case of error, stop programming procedure */ + if (status != HAL_OK) + { + break; + } + } + } + + /* Process Unlocked */ + __HAL_UNLOCK(&pFlash); + + return status; +} + +/** + * @brief Program halfword, word or double word at a specified address with interrupt enabled. + * @note The function HAL_FLASH_Unlock() should be called before to unlock the FLASH interface + * The function HAL_FLASH_Lock() should be called after to lock the FLASH interface + * + * @note If an erase and a program operations are requested simultaneously, + * the erase operation is performed before the program one. + * + * @param TypeProgram Indicate the way to program at a specified address. + * This parameter can be a value of @ref FLASH_Type_Program + * @param Address Specifie the address to be programmed. + * @param Data Specifie the data to be programmed + * + * @retval HAL_StatusTypeDef HAL Status + */ +HAL_StatusTypeDef HAL_FLASH_Program_IT(uint32_t TypeProgram, uint32_t Address, uint64_t Data) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Process Locked */ + __HAL_LOCK(&pFlash); + + /* Check the parameters */ + assert_param(IS_FLASH_TYPEPROGRAM(TypeProgram)); + assert_param(IS_FLASH_PROGRAM_ADDRESS(Address)); + + /* Enable End of FLASH Operation and Error source interrupts */ + __HAL_FLASH_ENABLE_IT(FLASH_IT_EOP | FLASH_IT_ERR); + + pFlash.Address = Address; + pFlash.Data = Data; + + if(TypeProgram == FLASH_TYPEPROGRAM_HALFWORD) + { + pFlash.ProcedureOnGoing = FLASH_PROC_PROGRAMHALFWORD; + /* Program halfword (16-bit) at a specified address. */ + pFlash.DataRemaining = 1U; + } + else if(TypeProgram == FLASH_TYPEPROGRAM_WORD) + { + pFlash.ProcedureOnGoing = FLASH_PROC_PROGRAMWORD; + /* Program word (32-bit : 2*16-bit) at a specified address. */ + pFlash.DataRemaining = 2U; + } + else + { + pFlash.ProcedureOnGoing = FLASH_PROC_PROGRAMDOUBLEWORD; + /* Program double word (64-bit : 4*16-bit) at a specified address. */ + pFlash.DataRemaining = 4U; + } + + /* Program halfword (16-bit) at a specified address. */ + FLASH_Program_HalfWord(Address, (uint16_t)Data); + + return status; +} + +/** + * @brief This function handles FLASH interrupt request. + * @retval None + */ +void HAL_FLASH_IRQHandler(void) +{ + uint32_t addresstmp = 0U; + + /* Check FLASH operation error flags */ + if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR) ||__HAL_FLASH_GET_FLAG(FLASH_FLAG_PGERR)) + { + /* Return the faulty address */ + addresstmp = pFlash.Address; + /* Reset address */ + pFlash.Address = 0xFFFFFFFFU; + + /* Save the Error code */ + FLASH_SetErrorCode(); + + /* FLASH error interrupt user callback */ + HAL_FLASH_OperationErrorCallback(addresstmp); + + /* Stop the procedure ongoing */ + pFlash.ProcedureOnGoing = FLASH_PROC_NONE; + } + + /* Check FLASH End of Operation flag */ + if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP)) + { + /* Clear FLASH End of Operation pending bit */ + __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP); + + /* Process can continue only if no error detected */ + if(pFlash.ProcedureOnGoing != FLASH_PROC_NONE) + { + if(pFlash.ProcedureOnGoing == FLASH_PROC_PAGEERASE) + { + /* Nb of pages to erased can be decreased */ + pFlash.DataRemaining--; + + /* Check if there are still pages to erase */ + if(pFlash.DataRemaining != 0U) + { + addresstmp = pFlash.Address; + /*Indicate user which sector has been erased */ + HAL_FLASH_EndOfOperationCallback(addresstmp); + + /*Increment sector number*/ + addresstmp = pFlash.Address + FLASH_PAGE_SIZE; + pFlash.Address = addresstmp; + + /* If the erase operation is completed, disable the PER Bit */ + CLEAR_BIT(FLASH->CR, FLASH_CR_PER); + + FLASH_PageErase(addresstmp); + } + else + { + /* No more pages to Erase, user callback can be called. */ + /* Reset Sector and stop Erase pages procedure */ + pFlash.Address = addresstmp = 0xFFFFFFFFU; + pFlash.ProcedureOnGoing = FLASH_PROC_NONE; + /* FLASH EOP interrupt user callback */ + HAL_FLASH_EndOfOperationCallback(addresstmp); + } + } + else if(pFlash.ProcedureOnGoing == FLASH_PROC_MASSERASE) + { + /* Operation is completed, disable the MER Bit */ + CLEAR_BIT(FLASH->CR, FLASH_CR_MER); + + /* MassErase ended. Return the selected bank */ + /* FLASH EOP interrupt user callback */ + HAL_FLASH_EndOfOperationCallback(0); + + /* Stop Mass Erase procedure*/ + pFlash.ProcedureOnGoing = FLASH_PROC_NONE; + } + else + { + /* Nb of 16-bit data to program can be decreased */ + pFlash.DataRemaining--; + + /* Check if there are still 16-bit data to program */ + if(pFlash.DataRemaining != 0U) + { + /* Increment address to 16-bit */ + pFlash.Address += 2; + addresstmp = pFlash.Address; + + /* Shift to have next 16-bit data */ + pFlash.Data = (pFlash.Data >> 16U); + + /* Operation is completed, disable the PG Bit */ + CLEAR_BIT(FLASH->CR, FLASH_CR_PG); + + /*Program halfword (16-bit) at a specified address.*/ + FLASH_Program_HalfWord(addresstmp, (uint16_t)pFlash.Data); + } + else + { + /* Program ended. Return the selected address */ + /* FLASH EOP interrupt user callback */ + if (pFlash.ProcedureOnGoing == FLASH_PROC_PROGRAMHALFWORD) + { + HAL_FLASH_EndOfOperationCallback(pFlash.Address); + } + else if (pFlash.ProcedureOnGoing == FLASH_PROC_PROGRAMWORD) + { + HAL_FLASH_EndOfOperationCallback(pFlash.Address - 2U); + } + else + { + HAL_FLASH_EndOfOperationCallback(pFlash.Address - 6U); + } + + /* Reset Address and stop Program procedure */ + pFlash.Address = 0xFFFFFFFFU; + pFlash.ProcedureOnGoing = FLASH_PROC_NONE; + } + } + } + } + + + if(pFlash.ProcedureOnGoing == FLASH_PROC_NONE) + { + /* Operation is completed, disable the PG, PER and MER Bits */ + CLEAR_BIT(FLASH->CR, (FLASH_CR_PG | FLASH_CR_PER | FLASH_CR_MER)); + + /* Disable End of FLASH Operation and Error source interrupts */ + __HAL_FLASH_DISABLE_IT(FLASH_IT_EOP | FLASH_IT_ERR); + + /* Process Unlocked */ + __HAL_UNLOCK(&pFlash); + } +} + +/** + * @brief FLASH end of operation interrupt callback + * @param ReturnValue The value saved in this parameter depends on the ongoing procedure + * - Mass Erase: No return value expected + * - Pages Erase: Address of the page which has been erased + * (if 0xFFFFFFFF, it means that all the selected pages have been erased) + * - Program: Address which was selected for data program + * @retval none + */ +__weak void HAL_FLASH_EndOfOperationCallback(uint32_t ReturnValue) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(ReturnValue); + + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_FLASH_EndOfOperationCallback could be implemented in the user file + */ +} + +/** + * @brief FLASH operation error interrupt callback + * @param ReturnValue The value saved in this parameter depends on the ongoing procedure + * - Mass Erase: No return value expected + * - Pages Erase: Address of the page which returned an error + * - Program: Address which was selected for data program + * @retval none + */ +__weak void HAL_FLASH_OperationErrorCallback(uint32_t ReturnValue) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(ReturnValue); + + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_FLASH_OperationErrorCallback could be implemented in the user file + */ +} + +/** + * @} + */ + +/** @defgroup FLASH_Exported_Functions_Group2 Peripheral Control functions + * @brief management functions + * +@verbatim + =============================================================================== + ##### Peripheral Control functions ##### + =============================================================================== + [..] + This subsection provides a set of functions allowing to control the FLASH + memory operations. + +@endverbatim + * @{ + */ + +/** + * @brief Unlock the FLASH control register access + * @retval HAL Status + */ +HAL_StatusTypeDef HAL_FLASH_Unlock(void) +{ + HAL_StatusTypeDef status = HAL_OK; + + if(READ_BIT(FLASH->CR, FLASH_CR_LOCK) != RESET) + { + /* Authorize the FLASH Registers access */ + WRITE_REG(FLASH->KEYR, FLASH_KEY1); + WRITE_REG(FLASH->KEYR, FLASH_KEY2); + + /* Verify Flash is unlocked */ + if(READ_BIT(FLASH->CR, FLASH_CR_LOCK) != RESET) + { + status = HAL_ERROR; + } + } + + return status; +} + +/** + * @brief Locks the FLASH control register access + * @retval HAL Status + */ +HAL_StatusTypeDef HAL_FLASH_Lock(void) +{ + /* Set the LOCK Bit to lock the FLASH Registers access */ + SET_BIT(FLASH->CR, FLASH_CR_LOCK); + + return HAL_OK; +} + +/** + * @brief Unlock the FLASH Option Control Registers access. + * @retval HAL Status + */ +HAL_StatusTypeDef HAL_FLASH_OB_Unlock(void) +{ + if (HAL_IS_BIT_CLR(FLASH->CR, FLASH_CR_OPTWRE)) + { + /* Authorizes the Option Byte register programming */ + WRITE_REG(FLASH->OPTKEYR, FLASH_OPTKEY1); + WRITE_REG(FLASH->OPTKEYR, FLASH_OPTKEY2); + } + else + { + return HAL_ERROR; + } + + return HAL_OK; +} + +/** + * @brief Lock the FLASH Option Control Registers access. + * @retval HAL Status + */ +HAL_StatusTypeDef HAL_FLASH_OB_Lock(void) +{ + /* Clear the OPTWRE Bit to lock the FLASH Option Byte Registers access */ + CLEAR_BIT(FLASH->CR, FLASH_CR_OPTWRE); + + return HAL_OK; +} + +/** + * @brief Launch the option byte loading. + * @note This function will reset automatically the MCU. + * @retval HAL Status + */ +HAL_StatusTypeDef HAL_FLASH_OB_Launch(void) +{ + /* Set the OBL_Launch bit to launch the option byte loading */ + SET_BIT(FLASH->CR, FLASH_CR_OBL_LAUNCH); + + /* Wait for last operation to be completed */ + return(FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE)); +} + +/** + * @} + */ + +/** @defgroup FLASH_Exported_Functions_Group3 Peripheral errors functions + * @brief Peripheral errors functions + * +@verbatim + =============================================================================== + ##### Peripheral Errors functions ##### + =============================================================================== + [..] + This subsection permit to get in run-time errors of the FLASH peripheral. + +@endverbatim + * @{ + */ + +/** + * @brief Get the specific FLASH error flag. + * @retval FLASH_ErrorCode The returned value can be: + * @ref FLASH_Error_Codes + */ +uint32_t HAL_FLASH_GetError(void) +{ + return pFlash.ErrorCode; +} + +/** + * @} + */ + +/** + * @} + */ + +/** @addtogroup FLASH_Private_Functions + * @{ + */ + +/** + * @brief Program a half-word (16-bit) at a specified address. + * @param Address specify the address to be programmed. + * @param Data specify the data to be programmed. + * @retval None + */ +static void FLASH_Program_HalfWord(uint32_t Address, uint16_t Data) +{ + /* Clean the error context */ + pFlash.ErrorCode = HAL_FLASH_ERROR_NONE; + + /* Proceed to program the new data */ + SET_BIT(FLASH->CR, FLASH_CR_PG); + + /* Write data in the address */ + *(__IO uint16_t*)Address = Data; +} + +/** + * @brief Wait for a FLASH operation to complete. + * @param Timeout maximum flash operation timeout + * @retval HAL Status + */ +HAL_StatusTypeDef FLASH_WaitForLastOperation(uint32_t Timeout) +{ + /* Wait for the FLASH operation to complete by polling on BUSY flag to be reset. + Even if the FLASH operation fails, the BUSY flag will be reset and an error + flag will be set */ + + uint32_t tickstart = HAL_GetTick(); + + while(__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY)) + { + if (Timeout != HAL_MAX_DELAY) + { + if((Timeout == 0U) || ((HAL_GetTick()-tickstart) > Timeout)) + { + return HAL_TIMEOUT; + } + } + } + + /* Check FLASH End of Operation flag */ + if (__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP)) + { + /* Clear FLASH End of Operation pending bit */ + __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP); + } + + if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR) || + __HAL_FLASH_GET_FLAG(FLASH_FLAG_PGERR)) + { + /*Save the error code*/ + FLASH_SetErrorCode(); + return HAL_ERROR; + } + + /* There is no error flag set */ + return HAL_OK; +} + + +/** + * @brief Set the specific FLASH error flag. + * @retval None + */ +static void FLASH_SetErrorCode(void) +{ + uint32_t flags = 0U; + + if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR)) + { + pFlash.ErrorCode |= HAL_FLASH_ERROR_WRP; + flags |= FLASH_FLAG_WRPERR; + } + if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_PGERR)) + { + pFlash.ErrorCode |= HAL_FLASH_ERROR_PROG; + flags |= FLASH_FLAG_PGERR; + } + /* Clear FLASH error pending bits */ + __HAL_FLASH_CLEAR_FLAG(flags); +} +/** + * @} + */ + +/** + * @} + */ + +#endif /* HAL_FLASH_MODULE_ENABLED */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.c b/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.c new file mode 100644 index 0000000..c86705f --- /dev/null +++ b/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.c @@ -0,0 +1,984 @@ +/** + ****************************************************************************** + * @file stm32f0xx_hal_flash_ex.c + * @author MCD Application Team + * @brief Extended FLASH HAL module driver. + * + * This file provides firmware functions to manage the following + * functionalities of the FLASH peripheral: + * + Extended Initialization/de-initialization functions + * + Extended I/O operation functions + * + Extended Peripheral Control functions + * + @verbatim + ============================================================================== + ##### Flash peripheral extended features ##### + ============================================================================== + + ##### How to use this driver ##### + ============================================================================== + [..] This driver provides functions to configure and program the FLASH memory + of all STM32F0xxx devices. It includes + + (++) Set/Reset the write protection + (++) Program the user Option Bytes + (++) Get the Read protection Level + + @endverbatim + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2016 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f0xx_hal.h" + +/** @addtogroup STM32F0xx_HAL_Driver + * @{ + */ +#ifdef HAL_FLASH_MODULE_ENABLED + +/** @addtogroup FLASH + * @{ + */ +/** @addtogroup FLASH_Private_Variables + * @{ + */ +/* Variables used for Erase pages under interruption*/ +extern FLASH_ProcessTypeDef pFlash; +/** + * @} + */ + +/** + * @} + */ + +/** @defgroup FLASHEx FLASHEx + * @brief FLASH HAL Extension module driver + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/** @defgroup FLASHEx_Private_Constants FLASHEx Private Constants + * @{ + */ +#define FLASH_POSITION_IWDGSW_BIT 8U +#define FLASH_POSITION_OB_USERDATA0_BIT 16U +#define FLASH_POSITION_OB_USERDATA1_BIT 24U +/** + * @} + */ + +/* Private macro -------------------------------------------------------------*/ +/** @defgroup FLASHEx_Private_Macros FLASHEx Private Macros + * @{ + */ +/** + * @} + */ + +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/** @defgroup FLASHEx_Private_Functions FLASHEx Private Functions + * @{ + */ +/* Erase operations */ +static void FLASH_MassErase(void); +void FLASH_PageErase(uint32_t PageAddress); + +/* Option bytes control */ +static HAL_StatusTypeDef FLASH_OB_EnableWRP(uint32_t WriteProtectPage); +static HAL_StatusTypeDef FLASH_OB_DisableWRP(uint32_t WriteProtectPage); +static HAL_StatusTypeDef FLASH_OB_RDP_LevelConfig(uint8_t ReadProtectLevel); +static HAL_StatusTypeDef FLASH_OB_UserConfig(uint8_t UserConfig); +static HAL_StatusTypeDef FLASH_OB_ProgramData(uint32_t Address, uint8_t Data); +static uint32_t FLASH_OB_GetWRP(void); +static uint32_t FLASH_OB_GetRDP(void); +static uint8_t FLASH_OB_GetUser(void); + +/** + * @} + */ + +/* Exported functions ---------------------------------------------------------*/ +/** @defgroup FLASHEx_Exported_Functions FLASHEx Exported Functions + * @{ + */ + +/** @defgroup FLASHEx_Exported_Functions_Group1 FLASHEx Memory Erasing functions + * @brief FLASH Memory Erasing functions + * +@verbatim + ============================================================================== + ##### FLASH Erasing Programming functions ##### + ============================================================================== + + [..] The FLASH Memory Erasing functions, includes the following functions: + (+) @ref HAL_FLASHEx_Erase: return only when erase has been done + (+) @ref HAL_FLASHEx_Erase_IT: end of erase is done when @ref HAL_FLASH_EndOfOperationCallback + is called with parameter 0xFFFFFFFF + + [..] Any operation of erase should follow these steps: + (#) Call the @ref HAL_FLASH_Unlock() function to enable the flash control register and + program memory access. + (#) Call the desired function to erase page. + (#) Call the @ref HAL_FLASH_Lock() to disable the flash program memory access + (recommended to protect the FLASH memory against possible unwanted operation). + +@endverbatim + * @{ + */ + + +/** + * @brief Perform a mass erase or erase the specified FLASH memory pages + * @note To correctly run this function, the @ref HAL_FLASH_Unlock() function + * must be called before. + * Call the @ref HAL_FLASH_Lock() to disable the flash memory access + * (recommended to protect the FLASH memory against possible unwanted operation) + * @param[in] pEraseInit pointer to an FLASH_EraseInitTypeDef structure that + * contains the configuration information for the erasing. + * + * @param[out] PageError pointer to variable that + * contains the configuration information on faulty page in case of error + * (0xFFFFFFFF means that all the pages have been correctly erased) + * + * @retval HAL_StatusTypeDef HAL Status + */ +HAL_StatusTypeDef HAL_FLASHEx_Erase(FLASH_EraseInitTypeDef *pEraseInit, uint32_t *PageError) +{ + HAL_StatusTypeDef status = HAL_ERROR; + uint32_t address = 0U; + + /* Process Locked */ + __HAL_LOCK(&pFlash); + + /* Check the parameters */ + assert_param(IS_FLASH_TYPEERASE(pEraseInit->TypeErase)); + + if (pEraseInit->TypeErase == FLASH_TYPEERASE_MASSERASE) + { + /* Mass Erase requested for Bank1 */ + /* Wait for last operation to be completed */ + if (FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE) == HAL_OK) + { + /*Mass erase to be done*/ + FLASH_MassErase(); + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE); + + /* If the erase operation is completed, disable the MER Bit */ + CLEAR_BIT(FLASH->CR, FLASH_CR_MER); + } + } + else + { + /* Page Erase is requested */ + /* Check the parameters */ + assert_param(IS_FLASH_PROGRAM_ADDRESS(pEraseInit->PageAddress)); + assert_param(IS_FLASH_NB_PAGES(pEraseInit->PageAddress, pEraseInit->NbPages)); + + /* Page Erase requested on address located on bank1 */ + /* Wait for last operation to be completed */ + if (FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE) == HAL_OK) + { + /*Initialization of PageError variable*/ + *PageError = 0xFFFFFFFFU; + + /* Erase page by page to be done*/ + for(address = pEraseInit->PageAddress; + address < ((pEraseInit->NbPages * FLASH_PAGE_SIZE) + pEraseInit->PageAddress); + address += FLASH_PAGE_SIZE) + { + FLASH_PageErase(address); + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE); + + /* If the erase operation is completed, disable the PER Bit */ + CLEAR_BIT(FLASH->CR, FLASH_CR_PER); + + if (status != HAL_OK) + { + /* In case of error, stop erase procedure and return the faulty address */ + *PageError = address; + break; + } + } + } + } + + /* Process Unlocked */ + __HAL_UNLOCK(&pFlash); + + return status; +} + +/** + * @brief Perform a mass erase or erase the specified FLASH memory pages with interrupt enabled + * @note To correctly run this function, the @ref HAL_FLASH_Unlock() function + * must be called before. + * Call the @ref HAL_FLASH_Lock() to disable the flash memory access + * (recommended to protect the FLASH memory against possible unwanted operation) + * @param pEraseInit pointer to an FLASH_EraseInitTypeDef structure that + * contains the configuration information for the erasing. + * + * @retval HAL_StatusTypeDef HAL Status + */ +HAL_StatusTypeDef HAL_FLASHEx_Erase_IT(FLASH_EraseInitTypeDef *pEraseInit) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Process Locked */ + __HAL_LOCK(&pFlash); + + /* If procedure already ongoing, reject the next one */ + if (pFlash.ProcedureOnGoing != FLASH_PROC_NONE) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_FLASH_TYPEERASE(pEraseInit->TypeErase)); + + /* Enable End of FLASH Operation and Error source interrupts */ + __HAL_FLASH_ENABLE_IT(FLASH_IT_EOP | FLASH_IT_ERR); + + if (pEraseInit->TypeErase == FLASH_TYPEERASE_MASSERASE) + { + /*Mass erase to be done*/ + pFlash.ProcedureOnGoing = FLASH_PROC_MASSERASE; + FLASH_MassErase(); + } + else + { + /* Erase by page to be done*/ + + /* Check the parameters */ + assert_param(IS_FLASH_PROGRAM_ADDRESS(pEraseInit->PageAddress)); + assert_param(IS_FLASH_NB_PAGES(pEraseInit->PageAddress, pEraseInit->NbPages)); + + pFlash.ProcedureOnGoing = FLASH_PROC_PAGEERASE; + pFlash.DataRemaining = pEraseInit->NbPages; + pFlash.Address = pEraseInit->PageAddress; + + /*Erase 1st page and wait for IT*/ + FLASH_PageErase(pEraseInit->PageAddress); + } + + return status; +} + +/** + * @} + */ + +/** @defgroup FLASHEx_Exported_Functions_Group2 Option Bytes Programming functions + * @brief Option Bytes Programming functions + * +@verbatim + ============================================================================== + ##### Option Bytes Programming functions ##### + ============================================================================== + [..] + This subsection provides a set of functions allowing to control the FLASH + option bytes operations. + +@endverbatim + * @{ + */ + +/** + * @brief Erases the FLASH option bytes. + * @note This functions erases all option bytes except the Read protection (RDP). + * The function @ref HAL_FLASH_Unlock() should be called before to unlock the FLASH interface + * The function @ref HAL_FLASH_OB_Unlock() should be called before to unlock the options bytes + * The function @ref HAL_FLASH_OB_Launch() should be called after to force the reload of the options bytes + * (system reset will occur) + * @retval HAL status + */ + +HAL_StatusTypeDef HAL_FLASHEx_OBErase(void) +{ + uint8_t rdptmp = OB_RDP_LEVEL_0; + HAL_StatusTypeDef status = HAL_ERROR; + + /* Get the actual read protection Option Byte value */ + rdptmp = FLASH_OB_GetRDP(); + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE); + + if(status == HAL_OK) + { + /* Clean the error context */ + pFlash.ErrorCode = HAL_FLASH_ERROR_NONE; + + /* If the previous operation is completed, proceed to erase the option bytes */ + SET_BIT(FLASH->CR, FLASH_CR_OPTER); + SET_BIT(FLASH->CR, FLASH_CR_STRT); + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE); + + /* If the erase operation is completed, disable the OPTER Bit */ + CLEAR_BIT(FLASH->CR, FLASH_CR_OPTER); + + if(status == HAL_OK) + { + /* Restore the last read protection Option Byte value */ + status = FLASH_OB_RDP_LevelConfig(rdptmp); + } + } + + /* Return the erase status */ + return status; +} + +/** + * @brief Program option bytes + * @note The function @ref HAL_FLASH_Unlock() should be called before to unlock the FLASH interface + * The function @ref HAL_FLASH_OB_Unlock() should be called before to unlock the options bytes + * The function @ref HAL_FLASH_OB_Launch() should be called after to force the reload of the options bytes + * (system reset will occur) + * + * @param pOBInit pointer to an FLASH_OBInitStruct structure that + * contains the configuration information for the programming. + * + * @retval HAL_StatusTypeDef HAL Status + */ +HAL_StatusTypeDef HAL_FLASHEx_OBProgram(FLASH_OBProgramInitTypeDef *pOBInit) +{ + HAL_StatusTypeDef status = HAL_ERROR; + + /* Process Locked */ + __HAL_LOCK(&pFlash); + + /* Check the parameters */ + assert_param(IS_OPTIONBYTE(pOBInit->OptionType)); + + /* Write protection configuration */ + if((pOBInit->OptionType & OPTIONBYTE_WRP) == OPTIONBYTE_WRP) + { + assert_param(IS_WRPSTATE(pOBInit->WRPState)); + if (pOBInit->WRPState == OB_WRPSTATE_ENABLE) + { + /* Enable of Write protection on the selected page */ + status = FLASH_OB_EnableWRP(pOBInit->WRPPage); + } + else + { + /* Disable of Write protection on the selected page */ + status = FLASH_OB_DisableWRP(pOBInit->WRPPage); + } + if (status != HAL_OK) + { + /* Process Unlocked */ + __HAL_UNLOCK(&pFlash); + return status; + } + } + + /* Read protection configuration */ + if((pOBInit->OptionType & OPTIONBYTE_RDP) == OPTIONBYTE_RDP) + { + status = FLASH_OB_RDP_LevelConfig(pOBInit->RDPLevel); + if (status != HAL_OK) + { + /* Process Unlocked */ + __HAL_UNLOCK(&pFlash); + return status; + } + } + + /* USER configuration */ + if((pOBInit->OptionType & OPTIONBYTE_USER) == OPTIONBYTE_USER) + { + status = FLASH_OB_UserConfig(pOBInit->USERConfig); + if (status != HAL_OK) + { + /* Process Unlocked */ + __HAL_UNLOCK(&pFlash); + return status; + } + } + + /* DATA configuration*/ + if((pOBInit->OptionType & OPTIONBYTE_DATA) == OPTIONBYTE_DATA) + { + status = FLASH_OB_ProgramData(pOBInit->DATAAddress, pOBInit->DATAData); + if (status != HAL_OK) + { + /* Process Unlocked */ + __HAL_UNLOCK(&pFlash); + return status; + } + } + + /* Process Unlocked */ + __HAL_UNLOCK(&pFlash); + + return status; +} + +/** + * @brief Get the Option byte configuration + * @param pOBInit pointer to an FLASH_OBInitStruct structure that + * contains the configuration information for the programming. + * + * @retval None + */ +void HAL_FLASHEx_OBGetConfig(FLASH_OBProgramInitTypeDef *pOBInit) +{ + pOBInit->OptionType = OPTIONBYTE_WRP | OPTIONBYTE_RDP | OPTIONBYTE_USER; + + /*Get WRP*/ + pOBInit->WRPPage = FLASH_OB_GetWRP(); + + /*Get RDP Level*/ + pOBInit->RDPLevel = FLASH_OB_GetRDP(); + + /*Get USER*/ + pOBInit->USERConfig = FLASH_OB_GetUser(); +} + +/** + * @brief Get the Option byte user data + * @param DATAAdress Address of the option byte DATA + * This parameter can be one of the following values: + * @arg @ref OB_DATA_ADDRESS_DATA0 + * @arg @ref OB_DATA_ADDRESS_DATA1 + * @retval Value programmed in USER data + */ +uint32_t HAL_FLASHEx_OBGetUserData(uint32_t DATAAdress) +{ + uint32_t value = 0U; + + if (DATAAdress == OB_DATA_ADDRESS_DATA0) + { + /* Get value programmed in OB USER Data0 */ + value = READ_BIT(FLASH->OBR, FLASH_OBR_DATA0) >> FLASH_POSITION_OB_USERDATA0_BIT; + } + else + { + /* Get value programmed in OB USER Data1 */ + value = READ_BIT(FLASH->OBR, FLASH_OBR_DATA1) >> FLASH_POSITION_OB_USERDATA1_BIT; + } + + return value; +} + +/** + * @} + */ + +/** + * @} + */ + +/** @addtogroup FLASHEx_Private_Functions + * @{ + */ + +/** + * @brief Full erase of FLASH memory Bank + * + * @retval None + */ +static void FLASH_MassErase(void) +{ + /* Clean the error context */ + pFlash.ErrorCode = HAL_FLASH_ERROR_NONE; + + /* Only bank1 will be erased*/ + SET_BIT(FLASH->CR, FLASH_CR_MER); + SET_BIT(FLASH->CR, FLASH_CR_STRT); +} + +/** + * @brief Enable the write protection of the desired pages + * @note An option byte erase is done automatically in this function. + * @note When the memory read protection level is selected (RDP level = 1), + * it is not possible to program or erase the flash page i if + * debug features are connected or boot code is executed in RAM, even if nWRPi = 1 + * + * @param WriteProtectPage specifies the page(s) to be write protected. + * The value of this parameter depend on device used within the same series + * @retval HAL status + */ +static HAL_StatusTypeDef FLASH_OB_EnableWRP(uint32_t WriteProtectPage) +{ + HAL_StatusTypeDef status = HAL_OK; + uint16_t WRP0_Data = 0xFFFFU; +#if defined(OB_WRP1_WRP1) + uint16_t WRP1_Data = 0xFFFFU; +#endif /* OB_WRP1_WRP1 */ +#if defined(OB_WRP2_WRP2) + uint16_t WRP2_Data = 0xFFFFU; +#endif /* OB_WRP2_WRP2 */ +#if defined(OB_WRP3_WRP3) + uint16_t WRP3_Data = 0xFFFFU; +#endif /* OB_WRP3_WRP3 */ + + /* Check the parameters */ + assert_param(IS_OB_WRP(WriteProtectPage)); + + /* Get current write protected pages and the new pages to be protected ******/ + WriteProtectPage = (uint32_t)(~((~FLASH_OB_GetWRP()) | WriteProtectPage)); + +#if defined(OB_WRP_PAGES0TO15MASK) + WRP0_Data = (uint16_t)(WriteProtectPage & OB_WRP_PAGES0TO15MASK); +#elif defined(OB_WRP_PAGES0TO31MASK) + WRP0_Data = (uint16_t)(WriteProtectPage & OB_WRP_PAGES0TO31MASK); +#endif /* OB_WRP_PAGES0TO31MASK */ + +#if defined(OB_WRP_PAGES16TO31MASK) + WRP1_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES16TO31MASK) >> 8U); +#elif defined(OB_WRP_PAGES32TO63MASK) + WRP1_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES32TO63MASK) >> 8U); +#endif /* OB_WRP_PAGES32TO63MASK */ + +#if defined(OB_WRP_PAGES32TO47MASK) + WRP2_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES32TO47MASK) >> 16U); +#endif /* OB_WRP_PAGES32TO47MASK */ + +#if defined(OB_WRP_PAGES48TO63MASK) + WRP3_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES48TO63MASK) >> 24U); +#elif defined(OB_WRP_PAGES48TO127MASK) + WRP3_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES48TO127MASK) >> 24U); +#endif /* OB_WRP_PAGES48TO63MASK */ + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE); + + if(status == HAL_OK) + { + /* Clean the error context */ + pFlash.ErrorCode = HAL_FLASH_ERROR_NONE; + + /* To be able to write again option byte, need to perform a option byte erase */ + status = HAL_FLASHEx_OBErase(); + if (status == HAL_OK) + { + /* Enable write protection */ + SET_BIT(FLASH->CR, FLASH_CR_OPTPG); + +#if defined(OB_WRP0_WRP0) + if(WRP0_Data != 0xFFU) + { + OB->WRP0 &= WRP0_Data; + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE); + } +#endif /* OB_WRP0_WRP0 */ + +#if defined(OB_WRP1_WRP1) + if((status == HAL_OK) && (WRP1_Data != 0xFFU)) + { + OB->WRP1 &= WRP1_Data; + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE); + } +#endif /* OB_WRP1_WRP1 */ + +#if defined(OB_WRP2_WRP2) + if((status == HAL_OK) && (WRP2_Data != 0xFFU)) + { + OB->WRP2 &= WRP2_Data; + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE); + } +#endif /* OB_WRP2_WRP2 */ + +#if defined(OB_WRP3_WRP3) + if((status == HAL_OK) && (WRP3_Data != 0xFFU)) + { + OB->WRP3 &= WRP3_Data; + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE); + } +#endif /* OB_WRP3_WRP3 */ + + /* if the program operation is completed, disable the OPTPG Bit */ + CLEAR_BIT(FLASH->CR, FLASH_CR_OPTPG); + } + } + + return status; +} + +/** + * @brief Disable the write protection of the desired pages + * @note An option byte erase is done automatically in this function. + * @note When the memory read protection level is selected (RDP level = 1), + * it is not possible to program or erase the flash page i if + * debug features are connected or boot code is executed in RAM, even if nWRPi = 1 + * + * @param WriteProtectPage specifies the page(s) to be write unprotected. + * The value of this parameter depend on device used within the same series + * @retval HAL status + */ +static HAL_StatusTypeDef FLASH_OB_DisableWRP(uint32_t WriteProtectPage) +{ + HAL_StatusTypeDef status = HAL_OK; + uint16_t WRP0_Data = 0xFFFFU; +#if defined(OB_WRP1_WRP1) + uint16_t WRP1_Data = 0xFFFFU; +#endif /* OB_WRP1_WRP1 */ +#if defined(OB_WRP2_WRP2) + uint16_t WRP2_Data = 0xFFFFU; +#endif /* OB_WRP2_WRP2 */ +#if defined(OB_WRP3_WRP3) + uint16_t WRP3_Data = 0xFFFFU; +#endif /* OB_WRP3_WRP3 */ + + /* Check the parameters */ + assert_param(IS_OB_WRP(WriteProtectPage)); + + /* Get current write protected pages and the new pages to be unprotected ******/ + WriteProtectPage = (FLASH_OB_GetWRP() | WriteProtectPage); + +#if defined(OB_WRP_PAGES0TO15MASK) + WRP0_Data = (uint16_t)(WriteProtectPage & OB_WRP_PAGES0TO15MASK); +#elif defined(OB_WRP_PAGES0TO31MASK) + WRP0_Data = (uint16_t)(WriteProtectPage & OB_WRP_PAGES0TO31MASK); +#endif /* OB_WRP_PAGES0TO31MASK */ + +#if defined(OB_WRP_PAGES16TO31MASK) + WRP1_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES16TO31MASK) >> 8U); +#elif defined(OB_WRP_PAGES32TO63MASK) + WRP1_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES32TO63MASK) >> 8U); +#endif /* OB_WRP_PAGES32TO63MASK */ + +#if defined(OB_WRP_PAGES32TO47MASK) + WRP2_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES32TO47MASK) >> 16U); +#endif /* OB_WRP_PAGES32TO47MASK */ + +#if defined(OB_WRP_PAGES48TO63MASK) + WRP3_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES48TO63MASK) >> 24U); +#elif defined(OB_WRP_PAGES48TO127MASK) + WRP3_Data = (uint16_t)((WriteProtectPage & OB_WRP_PAGES48TO127MASK) >> 24U); +#endif /* OB_WRP_PAGES48TO63MASK */ + + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE); + + if(status == HAL_OK) + { + /* Clean the error context */ + pFlash.ErrorCode = HAL_FLASH_ERROR_NONE; + + /* To be able to write again option byte, need to perform a option byte erase */ + status = HAL_FLASHEx_OBErase(); + if (status == HAL_OK) + { + SET_BIT(FLASH->CR, FLASH_CR_OPTPG); + +#if defined(OB_WRP0_WRP0) + if(WRP0_Data != 0xFFU) + { + OB->WRP0 |= WRP0_Data; + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE); + } +#endif /* OB_WRP0_WRP0 */ + +#if defined(OB_WRP1_WRP1) + if((status == HAL_OK) && (WRP1_Data != 0xFFU)) + { + OB->WRP1 |= WRP1_Data; + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE); + } +#endif /* OB_WRP1_WRP1 */ + +#if defined(OB_WRP2_WRP2) + if((status == HAL_OK) && (WRP2_Data != 0xFFU)) + { + OB->WRP2 |= WRP2_Data; + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE); + } +#endif /* OB_WRP2_WRP2 */ + +#if defined(OB_WRP3_WRP3) + if((status == HAL_OK) && (WRP3_Data != 0xFFU)) + { + OB->WRP3 |= WRP3_Data; + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE); + } +#endif /* OB_WRP3_WRP3 */ + + /* if the program operation is completed, disable the OPTPG Bit */ + CLEAR_BIT(FLASH->CR, FLASH_CR_OPTPG); + } + } + return status; +} + +/** + * @brief Set the read protection level. + * @param ReadProtectLevel specifies the read protection level. + * This parameter can be one of the following values: + * @arg @ref OB_RDP_LEVEL_0 No protection + * @arg @ref OB_RDP_LEVEL_1 Read protection of the memory + * @arg @ref OB_RDP_LEVEL_2 Full chip protection + * @note Warning: When enabling OB_RDP level 2 it's no more possible to go back to level 1 or 0 + * @retval HAL status + */ +static HAL_StatusTypeDef FLASH_OB_RDP_LevelConfig(uint8_t ReadProtectLevel) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check the parameters */ + assert_param(IS_OB_RDP_LEVEL(ReadProtectLevel)); + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE); + + if(status == HAL_OK) + { + /* Clean the error context */ + pFlash.ErrorCode = HAL_FLASH_ERROR_NONE; + + /* If the previous operation is completed, proceed to erase the option bytes */ + SET_BIT(FLASH->CR, FLASH_CR_OPTER); + SET_BIT(FLASH->CR, FLASH_CR_STRT); + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE); + + /* If the erase operation is completed, disable the OPTER Bit */ + CLEAR_BIT(FLASH->CR, FLASH_CR_OPTER); + + if(status == HAL_OK) + { + /* Enable the Option Bytes Programming operation */ + SET_BIT(FLASH->CR, FLASH_CR_OPTPG); + + WRITE_REG(OB->RDP, ReadProtectLevel); + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE); + + /* if the program operation is completed, disable the OPTPG Bit */ + CLEAR_BIT(FLASH->CR, FLASH_CR_OPTPG); + } + } + + return status; +} + +/** + * @brief Program the FLASH User Option Byte. + * @note Programming of the OB should be performed only after an erase (otherwise PGERR occurs) + * @param UserConfig The FLASH User Option Bytes values: IWDG_SW(Bit0), RST_STOP(Bit1), RST_STDBY(Bit2), nBOOT1(Bit4), + * VDDA_Analog_Monitoring(Bit5) and SRAM_Parity_Enable(Bit6). + * For few devices, following option bytes are available: nBOOT0(Bit3) & BOOT_SEL(Bit7). + * @retval HAL status + */ +static HAL_StatusTypeDef FLASH_OB_UserConfig(uint8_t UserConfig) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check the parameters */ + assert_param(IS_OB_IWDG_SOURCE((UserConfig&OB_IWDG_SW))); + assert_param(IS_OB_STOP_SOURCE((UserConfig&OB_STOP_NO_RST))); + assert_param(IS_OB_STDBY_SOURCE((UserConfig&OB_STDBY_NO_RST))); + assert_param(IS_OB_BOOT1((UserConfig&OB_BOOT1_SET))); + assert_param(IS_OB_VDDA_ANALOG((UserConfig&OB_VDDA_ANALOG_ON))); + assert_param(IS_OB_SRAM_PARITY((UserConfig&OB_SRAM_PARITY_RESET))); +#if defined(FLASH_OBR_BOOT_SEL) + assert_param(IS_OB_BOOT_SEL((UserConfig&OB_BOOT_SEL_SET))); + assert_param(IS_OB_BOOT0((UserConfig&OB_BOOT0_SET))); +#endif /* FLASH_OBR_BOOT_SEL */ + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE); + + if(status == HAL_OK) + { + /* Clean the error context */ + pFlash.ErrorCode = HAL_FLASH_ERROR_NONE; + + /* Enable the Option Bytes Programming operation */ + SET_BIT(FLASH->CR, FLASH_CR_OPTPG); + +#if defined(FLASH_OBR_BOOT_SEL) + OB->USER = UserConfig; +#else + OB->USER = (UserConfig | 0x88U); +#endif + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE); + + /* if the program operation is completed, disable the OPTPG Bit */ + CLEAR_BIT(FLASH->CR, FLASH_CR_OPTPG); + } + + return status; +} + +/** + * @brief Programs a half word at a specified Option Byte Data address. + * @note The function @ref HAL_FLASH_Unlock() should be called before to unlock the FLASH interface + * The function @ref HAL_FLASH_OB_Unlock() should be called before to unlock the options bytes + * The function @ref HAL_FLASH_OB_Launch() should be called after to force the reload of the options bytes + * (system reset will occur) + * Programming of the OB should be performed only after an erase (otherwise PGERR occurs) + * @param Address specifies the address to be programmed. + * This parameter can be 0x1FFFF804 or 0x1FFFF806. + * @param Data specifies the data to be programmed. + * @retval HAL status + */ +static HAL_StatusTypeDef FLASH_OB_ProgramData(uint32_t Address, uint8_t Data) +{ + HAL_StatusTypeDef status = HAL_ERROR; + + /* Check the parameters */ + assert_param(IS_OB_DATA_ADDRESS(Address)); + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE); + + if(status == HAL_OK) + { + /* Clean the error context */ + pFlash.ErrorCode = HAL_FLASH_ERROR_NONE; + + /* Enables the Option Bytes Programming operation */ + SET_BIT(FLASH->CR, FLASH_CR_OPTPG); + *(__IO uint16_t*)Address = Data; + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE); + + /* If the program operation is completed, disable the OPTPG Bit */ + CLEAR_BIT(FLASH->CR, FLASH_CR_OPTPG); + } + /* Return the Option Byte Data Program Status */ + return status; +} + +/** + * @brief Return the FLASH Write Protection Option Bytes value. + * @retval The FLASH Write Protection Option Bytes value + */ +static uint32_t FLASH_OB_GetWRP(void) +{ + /* Return the FLASH write protection Register value */ + return (uint32_t)(READ_REG(FLASH->WRPR)); +} + +/** + * @brief Returns the FLASH Read Protection level. + * @retval FLASH RDP level + * This parameter can be one of the following values: + * @arg @ref OB_RDP_LEVEL_0 No protection + * @arg @ref OB_RDP_LEVEL_1 Read protection of the memory + * @arg @ref OB_RDP_LEVEL_2 Full chip protection + */ +static uint32_t FLASH_OB_GetRDP(void) +{ + uint32_t tmp_reg; + + /* Read RDP level bits */ + tmp_reg = READ_BIT(FLASH->OBR, (FLASH_OBR_RDPRT1 | FLASH_OBR_RDPRT2)); + + if (tmp_reg == 0U) + { + return OB_RDP_LEVEL_0; + } + else if ((tmp_reg & FLASH_OBR_RDPRT2) == FLASH_OBR_RDPRT2) + { + return OB_RDP_LEVEL_2; + } + else + { + return OB_RDP_LEVEL_1; + } +} + +/** + * @brief Return the FLASH User Option Byte value. + * @retval The FLASH User Option Bytes values: IWDG_SW(Bit0), RST_STOP(Bit1), RST_STDBY(Bit2), nBOOT1(Bit4), + * VDDA_Analog_Monitoring(Bit5) and SRAM_Parity_Enable(Bit6). + * For few devices, following option bytes are available: nBOOT0(Bit3) & BOOT_SEL(Bit7). + */ +static uint8_t FLASH_OB_GetUser(void) +{ + /* Return the User Option Byte */ + return (uint8_t)((READ_REG(FLASH->OBR) & FLASH_OBR_USER) >> FLASH_POSITION_IWDGSW_BIT); +} + +/** + * @} + */ + +/** + * @} + */ + +/** @addtogroup FLASH + * @{ + */ + +/** @addtogroup FLASH_Private_Functions + * @{ + */ + +/** + * @brief Erase the specified FLASH memory page + * @param PageAddress FLASH page to erase + * The value of this parameter depend on device used within the same series + * + * @retval None + */ +void FLASH_PageErase(uint32_t PageAddress) +{ + /* Clean the error context */ + pFlash.ErrorCode = HAL_FLASH_ERROR_NONE; + + /* Proceed to erase the page */ + SET_BIT(FLASH->CR, FLASH_CR_PER); + WRITE_REG(FLASH->AR, PageAddress); + SET_BIT(FLASH->CR, FLASH_CR_STRT); +} + +/** + * @} + */ + +/** + * @} + */ + +#endif /* HAL_FLASH_MODULE_ENABLED */ +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.c b/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.c new file mode 100644 index 0000000..6faa77a --- /dev/null +++ b/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.c @@ -0,0 +1,543 @@ +/** + ****************************************************************************** + * @file stm32f0xx_hal_gpio.c + * @author MCD Application Team + * @brief GPIO HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the General Purpose Input/Output (GPIO) peripheral: + * + Initialization and de-initialization functions + * + IO operation functions + * + @verbatim + ============================================================================== + ##### GPIO Peripheral features ##### + ============================================================================== + [..] + (+) Each port bit of the general-purpose I/O (GPIO) ports can be individually + configured by software in several modes: + (++) Input mode + (++) Analog mode + (++) Output mode + (++) Alternate function mode + (++) External interrupt/event lines + + (+) During and just after reset, the alternate functions and external interrupt + lines are not active and the I/O ports are configured in input floating mode. + + (+) All GPIO pins have weak internal pull-up and pull-down resistors, which can be + activated or not. + + (+) In Output or Alternate mode, each IO can be configured on open-drain or push-pull + type and the IO speed can be selected depending on the VDD value. + + (+) The microcontroller IO pins are connected to onboard peripherals/modules through a + multiplexer that allows only one peripheral alternate function (AF) connected + to an IO pin at a time. In this way, there can be no conflict between peripherals + sharing the same IO pin. + + (+) All ports have external interrupt/event capability. To use external interrupt + lines, the port must be configured in input mode. All available GPIO pins are + connected to the 16 external interrupt/event lines from EXTI0 to EXTI15. + + (+) The external interrupt/event controller consists of up to 28 edge detectors + (16 lines are connected to GPIO) for generating event/interrupt requests (each + input line can be independently configured to select the type (interrupt or event) + and the corresponding trigger event (rising or falling or both). Each line can + also be masked independently. + + ##### How to use this driver ##### + ============================================================================== + [..] + (#) Enable the GPIO AHB clock using the following function : __HAL_RCC_GPIOx_CLK_ENABLE(). + + (#) Configure the GPIO pin(s) using HAL_GPIO_Init(). + (++) Configure the IO mode using "Mode" member from GPIO_InitTypeDef structure + (++) Activate Pull-up, Pull-down resistor using "Pull" member from GPIO_InitTypeDef + structure. + (++) In case of Output or alternate function mode selection: the speed is + configured through "Speed" member from GPIO_InitTypeDef structure. + (++) In alternate mode is selection, the alternate function connected to the IO + is configured through "Alternate" member from GPIO_InitTypeDef structure. + (++) Analog mode is required when a pin is to be used as ADC channel + or DAC output. + (++) In case of external interrupt/event selection the "Mode" member from + GPIO_InitTypeDef structure select the type (interrupt or event) and + the corresponding trigger event (rising or falling or both). + + (#) In case of external interrupt/event mode selection, configure NVIC IRQ priority + mapped to the EXTI line using HAL_NVIC_SetPriority() and enable it using + HAL_NVIC_EnableIRQ(). + + (#) HAL_GPIO_DeInit allows to set register values to their reset value. It's also + recommended to use it to unconfigure pin which was used as an external interrupt + or in event mode. That's the only way to reset corresponding bit in EXTI & SYSCFG + registers. + + (#) To get the level of a pin configured in input mode use HAL_GPIO_ReadPin(). + + (#) To set/reset the level of a pin configured in output mode use + HAL_GPIO_WritePin()/HAL_GPIO_TogglePin(). + + (#) To lock pin configuration until next reset use HAL_GPIO_LockPin(). + + (#) During and just after reset, the alternate functions are not + active and the GPIO pins are configured in input floating mode (except JTAG + pins). + + (#) The LSE oscillator pins OSC32_IN and OSC32_OUT can be used as general purpose + (PC14 and PC15, respectively) when the LSE oscillator is off. The LSE has + priority over the GPIO function. + + (#) The HSE oscillator pins OSC_IN/OSC_OUT can be used as + general purpose PF0 and PF1, respectively, when the HSE oscillator is off. + The HSE has priority over the GPIO function. + + @endverbatim + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2016 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f0xx_hal.h" + +/** @addtogroup STM32F0xx_HAL_Driver + * @{ + */ + +/** @defgroup GPIO GPIO + * @brief GPIO HAL module driver + * @{ + */ + +/** MISRA C:2012 deviation rule has been granted for following rules: + * Rule-18.1_d - Medium: Array pointer `GPIOx' is accessed with index [..,..] + * which may be out of array bounds [..,UNKNOWN] in following APIs: + * HAL_GPIO_Init + * HAL_GPIO_DeInit + */ + +#ifdef HAL_GPIO_MODULE_ENABLED + +/* Private typedef -----------------------------------------------------------*/ +/* Private defines -----------------------------------------------------------*/ +/** @defgroup GPIO_Private_Defines GPIO Private Defines + * @{ + */ +#define GPIO_MODE (0x00000003U) +#define EXTI_MODE (0x10000000U) +#define GPIO_MODE_IT (0x00010000U) +#define GPIO_MODE_EVT (0x00020000U) +#define RISING_EDGE (0x00100000U) +#define FALLING_EDGE (0x00200000U) +#define GPIO_OUTPUT_TYPE (0x00000010U) + +#define GPIO_NUMBER (16U) +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ + +/** @defgroup GPIO_Exported_Functions GPIO Exported Functions + * @{ + */ + +/** @defgroup GPIO_Exported_Functions_Group1 Initialization/de-initialization functions + * @brief Initialization and Configuration functions + * +@verbatim + =============================================================================== + ##### Initialization and de-initialization functions ##### + =============================================================================== + +@endverbatim + * @{ + */ + +/** + * @brief Initialize the GPIOx peripheral according to the specified parameters in the GPIO_Init. + * @param GPIOx where x can be (A..F) to select the GPIO peripheral for STM32F0 family + * @param GPIO_Init pointer to a GPIO_InitTypeDef structure that contains + * the configuration information for the specified GPIO peripheral. + * @retval None + */ +void HAL_GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *GPIO_Init) +{ + uint32_t position = 0x00u; + uint32_t iocurrent; + uint32_t temp; + + /* Check the parameters */ + assert_param(IS_GPIO_ALL_INSTANCE(GPIOx)); + assert_param(IS_GPIO_PIN(GPIO_Init->Pin)); + assert_param(IS_GPIO_MODE(GPIO_Init->Mode)); + assert_param(IS_GPIO_PULL(GPIO_Init->Pull)); + + /* Configure the port pins */ + while (((GPIO_Init->Pin) >> position) != 0x00u) + { + /* Get current io position */ + iocurrent = (GPIO_Init->Pin) & (1uL << position); + + if (iocurrent != 0x00u) + { + /*--------------------- GPIO Mode Configuration ------------------------*/ + /* In case of Alternate function mode selection */ + if((GPIO_Init->Mode == GPIO_MODE_AF_PP) || (GPIO_Init->Mode == GPIO_MODE_AF_OD)) + { + /* Check the Alternate function parameters */ + assert_param(IS_GPIO_AF_INSTANCE(GPIOx)); + assert_param(IS_GPIO_AF(GPIO_Init->Alternate)); + + /* Configure Alternate function mapped with the current IO */ + temp = GPIOx->AFR[position >> 3u]; + temp &= ~(0xFu << ((position & 0x07u) * 4u)); + temp |= ((GPIO_Init->Alternate) << ((position & 0x07u) * 4u)); + GPIOx->AFR[position >> 3u] = temp; + } + + /* Configure IO Direction mode (Input, Output, Alternate or Analog) */ + temp = GPIOx->MODER; + temp &= ~(GPIO_MODER_MODER0 << (position * 2u)); + temp |= ((GPIO_Init->Mode & GPIO_MODE) << (position * 2u)); + GPIOx->MODER = temp; + + /* In case of Output or Alternate function mode selection */ + if((GPIO_Init->Mode == GPIO_MODE_OUTPUT_PP) || (GPIO_Init->Mode == GPIO_MODE_AF_PP) || + (GPIO_Init->Mode == GPIO_MODE_OUTPUT_OD) || (GPIO_Init->Mode == GPIO_MODE_AF_OD)) + { + /* Check the Speed parameter */ + assert_param(IS_GPIO_SPEED(GPIO_Init->Speed)); + /* Configure the IO Speed */ + temp = GPIOx->OSPEEDR; + temp &= ~(GPIO_OSPEEDER_OSPEEDR0 << (position * 2u)); + temp |= (GPIO_Init->Speed << (position * 2u)); + GPIOx->OSPEEDR = temp; + + /* Configure the IO Output Type */ + temp = GPIOx->OTYPER; + temp &= ~(GPIO_OTYPER_OT_0 << position) ; + temp |= (((GPIO_Init->Mode & GPIO_OUTPUT_TYPE) >> 4u) << position); + GPIOx->OTYPER = temp; + } + + /* Activate the Pull-up or Pull down resistor for the current IO */ + temp = GPIOx->PUPDR; + temp &= ~(GPIO_PUPDR_PUPDR0 << (position * 2u)); + temp |= ((GPIO_Init->Pull) << (position * 2u)); + GPIOx->PUPDR = temp; + + /*--------------------- EXTI Mode Configuration ------------------------*/ + /* Configure the External Interrupt or event for the current IO */ + if((GPIO_Init->Mode & EXTI_MODE) == EXTI_MODE) + { + /* Enable SYSCFG Clock */ + __HAL_RCC_SYSCFG_CLK_ENABLE(); + + temp = SYSCFG->EXTICR[position >> 2u]; + temp &= ~(0x0FuL << (4u * (position & 0x03u))); + temp |= (GPIO_GET_INDEX(GPIOx) << (4u * (position & 0x03u))); + SYSCFG->EXTICR[position >> 2u] = temp; + + /* Clear EXTI line configuration */ + temp = EXTI->IMR; + temp &= ~(iocurrent); + if((GPIO_Init->Mode & GPIO_MODE_IT) == GPIO_MODE_IT) + { + temp |= iocurrent; + } + EXTI->IMR = temp; + + temp = EXTI->EMR; + temp &= ~(iocurrent); + if((GPIO_Init->Mode & GPIO_MODE_EVT) == GPIO_MODE_EVT) + { + temp |= iocurrent; + } + EXTI->EMR = temp; + + /* Clear Rising Falling edge configuration */ + temp = EXTI->RTSR; + temp &= ~(iocurrent); + if((GPIO_Init->Mode & RISING_EDGE) == RISING_EDGE) + { + temp |= iocurrent; + } + EXTI->RTSR = temp; + + temp = EXTI->FTSR; + temp &= ~(iocurrent); + if((GPIO_Init->Mode & FALLING_EDGE) == FALLING_EDGE) + { + temp |= iocurrent; + } + EXTI->FTSR = temp; + } + } + + position++; + } +} + +/** + * @brief De-initialize the GPIOx peripheral registers to their default reset values. + * @param GPIOx where x can be (A..F) to select the GPIO peripheral for STM32F0 family + * @param GPIO_Pin specifies the port bit to be written. + * This parameter can be one of GPIO_PIN_x where x can be (0..15). + * @retval None + */ +void HAL_GPIO_DeInit(GPIO_TypeDef *GPIOx, uint32_t GPIO_Pin) +{ + uint32_t position = 0x00u; + uint32_t iocurrent; + uint32_t tmp; + + /* Check the parameters */ + assert_param(IS_GPIO_ALL_INSTANCE(GPIOx)); + assert_param(IS_GPIO_PIN(GPIO_Pin)); + + /* Configure the port pins */ + while ((GPIO_Pin >> position) != 0x00u) + { + /* Get current io position */ + iocurrent = (GPIO_Pin) & (1uL << position); + + if (iocurrent != 0x00u) + { + /*------------------------- EXTI Mode Configuration --------------------*/ + /* Clear the External Interrupt or Event for the current IO */ + + tmp = SYSCFG->EXTICR[position >> 2u]; + tmp &= (0x0FuL << (4u * (position & 0x03u))); + if (tmp == (GPIO_GET_INDEX(GPIOx) << (4u * (position & 0x03u)))) + { + /* Clear EXTI line configuration */ + EXTI->IMR &= ~((uint32_t)iocurrent); + EXTI->EMR &= ~((uint32_t)iocurrent); + + /* Clear Rising Falling edge configuration */ + EXTI->RTSR &= ~((uint32_t)iocurrent); + EXTI->FTSR &= ~((uint32_t)iocurrent); + + /* Configure the External Interrupt or event for the current IO */ + tmp = 0x0FuL << (4u * (position & 0x03u)); + SYSCFG->EXTICR[position >> 2u] &= ~tmp; + } + + /*------------------------- GPIO Mode Configuration --------------------*/ + /* Configure IO Direction in Input Floating Mode */ + GPIOx->MODER &= ~(GPIO_MODER_MODER0 << (position * 2u)); + + /* Configure the default Alternate Function in current IO */ + GPIOx->AFR[position >> 3u] &= ~(0xFu << ((uint32_t)(position & 0x07u) * 4u)) ; + + /* Configure the default value for IO Speed */ + GPIOx->OSPEEDR &= ~(GPIO_OSPEEDER_OSPEEDR0 << (position * 2u)); + + /* Configure the default value IO Output Type */ + GPIOx->OTYPER &= ~(GPIO_OTYPER_OT_0 << position) ; + + /* Deactivate the Pull-up and Pull-down resistor for the current IO */ + GPIOx->PUPDR &= ~(GPIO_PUPDR_PUPDR0 << (position * 2U)); + } + + position++; + } +} + +/** + * @} + */ + +/** @defgroup GPIO_Exported_Functions_Group2 IO operation functions + * @brief GPIO Read, Write, Toggle, Lock and EXTI management functions. + * +@verbatim + =============================================================================== + ##### IO operation functions ##### + =============================================================================== + +@endverbatim + * @{ + */ + +/** + * @brief Read the specified input port pin. + * @param GPIOx where x can be (A..F) to select the GPIO peripheral for STM32F0 family + * @param GPIO_Pin specifies the port bit to read. + * This parameter can be GPIO_PIN_x where x can be (0..15). + * @retval The input port pin value. + */ +GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) +{ + GPIO_PinState bitstatus; + + /* Check the parameters */ + assert_param(IS_GPIO_PIN(GPIO_Pin)); + + if ((GPIOx->IDR & GPIO_Pin) != (uint32_t)GPIO_PIN_RESET) + { + bitstatus = GPIO_PIN_SET; + } + else + { + bitstatus = GPIO_PIN_RESET; + } + return bitstatus; + } + +/** + * @brief Set or clear the selected data port bit. + * @note This function uses GPIOx_BSRR and GPIOx_BRR registers to allow atomic read/modify + * accesses. In this way, there is no risk of an IRQ occurring between + * the read and the modify access. + * + * @param GPIOx where x can be (A..H) to select the GPIO peripheral for STM32F0 family + * @param GPIO_Pin specifies the port bit to be written. + * This parameter can be one of GPIO_PIN_x where x can be (0..15). + * @param PinState specifies the value to be written to the selected bit. + * This parameter can be one of the GPIO_PinState enum values: + * @arg GPIO_PIN_RESET: to clear the port pin + * @arg GPIO_PIN_SET: to set the port pin + * @retval None + */ +void HAL_GPIO_WritePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState) +{ + /* Check the parameters */ + assert_param(IS_GPIO_PIN(GPIO_Pin)); + assert_param(IS_GPIO_PIN_ACTION(PinState)); + + if (PinState != GPIO_PIN_RESET) + { + GPIOx->BSRR = (uint32_t)GPIO_Pin; + } + else + { + GPIOx->BRR = (uint32_t)GPIO_Pin; + } +} + +/** + * @brief Toggle the specified GPIO pin. + * @param GPIOx where x can be (A..F) to select the GPIO peripheral for STM32F0 family + * @param GPIO_Pin specifies the pin to be toggled. + * @retval None + */ +void HAL_GPIO_TogglePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) +{ + /* Check the parameters */ + assert_param(IS_GPIO_PIN(GPIO_Pin)); + + if ((GPIOx->ODR & GPIO_Pin) != 0X00u) + { + GPIOx->BSRR = (uint32_t)GPIO_Pin << GPIO_NUMBER; + } + else + { + GPIOx->BSRR = (uint32_t)GPIO_Pin; + } +} + +/** +* @brief Locks GPIO Pins configuration registers. +* @note The locked registers are GPIOx_MODER, GPIOx_OTYPER, GPIOx_OSPEEDR, +* GPIOx_PUPDR, GPIOx_AFRL and GPIOx_AFRH. +* @note The configuration of the locked GPIO pins can no longer be modified +* until the next reset. + * @param GPIOx where x can be (A..F) to select the GPIO peripheral for STM32F0 family + * @param GPIO_Pin specifies the port bits to be locked. +* This parameter can be any combination of GPIO_Pin_x where x can be (0..15). +* @retval None +*/ +HAL_StatusTypeDef HAL_GPIO_LockPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) +{ + __IO uint32_t tmp = GPIO_LCKR_LCKK; + + /* Check the parameters */ + assert_param(IS_GPIO_LOCK_INSTANCE(GPIOx)); + assert_param(IS_GPIO_PIN(GPIO_Pin)); + + /* Apply lock key write sequence */ + SET_BIT(tmp, GPIO_Pin); + /* Set LCKx bit(s): LCKK='1' + LCK[15-0] */ + GPIOx->LCKR = tmp; + /* Reset LCKx bit(s): LCKK='0' + LCK[15-0] */ + GPIOx->LCKR = GPIO_Pin; + /* Set LCKx bit(s): LCKK='1' + LCK[15-0] */ + GPIOx->LCKR = tmp; + /* Read LCKK register. This read is mandatory to complete key lock sequence */ + tmp = GPIOx->LCKR; + + /* read again in order to confirm lock is active */ + if((GPIOx->LCKR & GPIO_LCKR_LCKK) != 0x00u) + { + return HAL_OK; + } + else + { + return HAL_ERROR; + } +} + +/** + * @brief Handle EXTI interrupt request. + * @param GPIO_Pin Specifies the port pin connected to corresponding EXTI line. + * @retval None + */ +void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin) +{ + /* EXTI line interrupt detected */ + if(__HAL_GPIO_EXTI_GET_IT(GPIO_Pin) != 0x00u) + { + __HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin); + HAL_GPIO_EXTI_Callback(GPIO_Pin); + } +} + +/** + * @brief EXTI line detection callback. + * @param GPIO_Pin Specifies the port pin connected to corresponding EXTI line. + * @retval None + */ +__weak void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(GPIO_Pin); + + /* NOTE: This function should not be modified, when the callback is needed, + the HAL_GPIO_EXTI_Callback could be implemented in the user file + */ +} + +/** + * @} + */ + + +/** + * @} + */ + +#endif /* HAL_GPIO_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.c b/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.c new file mode 100644 index 0000000..7c2bf82 --- /dev/null +++ b/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.c @@ -0,0 +1,6501 @@ +/** + ****************************************************************************** + * @file stm32f0xx_hal_i2c.c + * @author MCD Application Team + * @brief I2C HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the Inter Integrated Circuit (I2C) peripheral: + * + Initialization and de-initialization functions + * + IO operation functions + * + Peripheral State and Errors functions + * + @verbatim + ============================================================================== + ##### How to use this driver ##### + ============================================================================== + [..] + The I2C HAL driver can be used as follows: + + (#) Declare a I2C_HandleTypeDef handle structure, for example: + I2C_HandleTypeDef hi2c; + + (#)Initialize the I2C low level resources by implementing the @ref HAL_I2C_MspInit() API: + (##) Enable the I2Cx interface clock + (##) I2C pins configuration + (+++) Enable the clock for the I2C GPIOs + (+++) Configure I2C pins as alternate function open-drain + (##) NVIC configuration if you need to use interrupt process + (+++) Configure the I2Cx interrupt priority + (+++) Enable the NVIC I2C IRQ Channel + (##) DMA Configuration if you need to use DMA process + (+++) Declare a DMA_HandleTypeDef handle structure for the transmit or receive channel + (+++) Enable the DMAx interface clock using + (+++) Configure the DMA handle parameters + (+++) Configure the DMA Tx or Rx channel + (+++) Associate the initialized DMA handle to the hi2c DMA Tx or Rx handle + (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on + the DMA Tx or Rx channel + + (#) Configure the Communication Clock Timing, Own Address1, Master Addressing mode, Dual Addressing mode, + Own Address2, Own Address2 Mask, General call and Nostretch mode in the hi2c Init structure. + + (#) Initialize the I2C registers by calling the @ref HAL_I2C_Init(), configures also the low level Hardware + (GPIO, CLOCK, NVIC...etc) by calling the customized @ref HAL_I2C_MspInit(&hi2c) API. + + (#) To check if target device is ready for communication, use the function @ref HAL_I2C_IsDeviceReady() + + (#) For I2C IO and IO MEM operations, three operation modes are available within this driver : + + *** Polling mode IO operation *** + ================================= + [..] + (+) Transmit in master mode an amount of data in blocking mode using @ref HAL_I2C_Master_Transmit() + (+) Receive in master mode an amount of data in blocking mode using @ref HAL_I2C_Master_Receive() + (+) Transmit in slave mode an amount of data in blocking mode using @ref HAL_I2C_Slave_Transmit() + (+) Receive in slave mode an amount of data in blocking mode using @ref HAL_I2C_Slave_Receive() + + *** Polling mode IO MEM operation *** + ===================================== + [..] + (+) Write an amount of data in blocking mode to a specific memory address using @ref HAL_I2C_Mem_Write() + (+) Read an amount of data in blocking mode from a specific memory address using @ref HAL_I2C_Mem_Read() + + + *** Interrupt mode IO operation *** + =================================== + [..] + (+) Transmit in master mode an amount of data in non-blocking mode using @ref HAL_I2C_Master_Transmit_IT() + (+) At transmission end of transfer, @ref HAL_I2C_MasterTxCpltCallback() is executed and user can + add his own code by customization of function pointer @ref HAL_I2C_MasterTxCpltCallback() + (+) Receive in master mode an amount of data in non-blocking mode using @ref HAL_I2C_Master_Receive_IT() + (+) At reception end of transfer, @ref HAL_I2C_MasterRxCpltCallback() is executed and user can + add his own code by customization of function pointer @ref HAL_I2C_MasterRxCpltCallback() + (+) Transmit in slave mode an amount of data in non-blocking mode using @ref HAL_I2C_Slave_Transmit_IT() + (+) At transmission end of transfer, @ref HAL_I2C_SlaveTxCpltCallback() is executed and user can + add his own code by customization of function pointer @ref HAL_I2C_SlaveTxCpltCallback() + (+) Receive in slave mode an amount of data in non-blocking mode using @ref HAL_I2C_Slave_Receive_IT() + (+) At reception end of transfer, @ref HAL_I2C_SlaveRxCpltCallback() is executed and user can + add his own code by customization of function pointer @ref HAL_I2C_SlaveRxCpltCallback() + (+) In case of transfer Error, @ref HAL_I2C_ErrorCallback() function is executed and user can + add his own code by customization of function pointer @ref HAL_I2C_ErrorCallback() + (+) Abort a master I2C process communication with Interrupt using @ref HAL_I2C_Master_Abort_IT() + (+) End of abort process, @ref HAL_I2C_AbortCpltCallback() is executed and user can + add his own code by customization of function pointer @ref HAL_I2C_AbortCpltCallback() + (+) Discard a slave I2C process communication using @ref __HAL_I2C_GENERATE_NACK() macro. + This action will inform Master to generate a Stop condition to discard the communication. + + + *** Interrupt mode or DMA mode IO sequential operation *** + ========================================================== + [..] + (@) These interfaces allow to manage a sequential transfer with a repeated start condition + when a direction change during transfer + [..] + (+) A specific option field manage the different steps of a sequential transfer + (+) Option field values are defined through @ref I2C_XFEROPTIONS and are listed below: + (++) I2C_FIRST_AND_LAST_FRAME: No sequential usage, functionnal is same as associated interfaces in no sequential mode + (++) I2C_FIRST_FRAME: Sequential usage, this option allow to manage a sequence with start condition, address + and data to transfer without a final stop condition + (++) I2C_FIRST_AND_NEXT_FRAME: Sequential usage (Master only), this option allow to manage a sequence with start condition, address + and data to transfer without a final stop condition, an then permit a call the same master sequential interface + several times (like @ref HAL_I2C_Master_Seq_Transmit_IT() then @ref HAL_I2C_Master_Seq_Transmit_IT() + or @ref HAL_I2C_Master_Seq_Transmit_DMA() then @ref HAL_I2C_Master_Seq_Transmit_DMA()) + (++) I2C_NEXT_FRAME: Sequential usage, this option allow to manage a sequence with a restart condition, address + and with new data to transfer if the direction change or manage only the new data to transfer + if no direction change and without a final stop condition in both cases + (++) I2C_LAST_FRAME: Sequential usage, this option allow to manage a sequance with a restart condition, address + and with new data to transfer if the direction change or manage only the new data to transfer + if no direction change and with a final stop condition in both cases + (++) I2C_LAST_FRAME_NO_STOP: Sequential usage (Master only), this option allow to manage a restart condition after several call of the same master sequential + interface several times (link with option I2C_FIRST_AND_NEXT_FRAME). + Usage can, transfer several bytes one by one using HAL_I2C_Master_Seq_Transmit_IT(option I2C_FIRST_AND_NEXT_FRAME then I2C_NEXT_FRAME) + or HAL_I2C_Master_Seq_Receive_IT(option I2C_FIRST_AND_NEXT_FRAME then I2C_NEXT_FRAME) + or HAL_I2C_Master_Seq_Transmit_DMA(option I2C_FIRST_AND_NEXT_FRAME then I2C_NEXT_FRAME) + or HAL_I2C_Master_Seq_Receive_DMA(option I2C_FIRST_AND_NEXT_FRAME then I2C_NEXT_FRAME). + Then usage of this option I2C_LAST_FRAME_NO_STOP at the last Transmit or Receive sequence permit to call the oposite interface Receive or Transmit + without stopping the communication and so generate a restart condition. + (++) I2C_OTHER_FRAME: Sequential usage (Master only), this option allow to manage a restart condition after each call of the same master sequential + interface. + Usage can, transfer several bytes one by one with a restart with slave address between each bytes using HAL_I2C_Master_Seq_Transmit_IT(option I2C_FIRST_FRAME then I2C_OTHER_FRAME) + or HAL_I2C_Master_Seq_Receive_IT(option I2C_FIRST_FRAME then I2C_OTHER_FRAME) + or HAL_I2C_Master_Seq_Transmit_DMA(option I2C_FIRST_FRAME then I2C_OTHER_FRAME) + or HAL_I2C_Master_Seq_Receive_DMA(option I2C_FIRST_FRAME then I2C_OTHER_FRAME). + Then usage of this option I2C_OTHER_AND_LAST_FRAME at the last frame to help automatic generation of STOP condition. + + (+) Differents sequential I2C interfaces are listed below: + (++) Sequential transmit in master I2C mode an amount of data in non-blocking mode using @ref HAL_I2C_Master_Seq_Transmit_IT() + or using @ref HAL_I2C_Master_Seq_Transmit_DMA() + (+++) At transmission end of current frame transfer, @ref HAL_I2C_MasterTxCpltCallback() is executed and user can + add his own code by customization of function pointer @ref HAL_I2C_MasterTxCpltCallback() + (++) Sequential receive in master I2C mode an amount of data in non-blocking mode using @ref HAL_I2C_Master_Seq_Receive_IT() + or using @ref HAL_I2C_Master_Seq_Receive_DMA() + (+++) At reception end of current frame transfer, @ref HAL_I2C_MasterRxCpltCallback() is executed and user can + add his own code by customization of function pointer @ref HAL_I2C_MasterRxCpltCallback() + (++) Abort a master IT or DMA I2C process communication with Interrupt using @ref HAL_I2C_Master_Abort_IT() + (+++) End of abort process, @ref HAL_I2C_AbortCpltCallback() is executed and user can + add his own code by customization of function pointer @ref HAL_I2C_AbortCpltCallback() + (++) Enable/disable the Address listen mode in slave I2C mode using @ref HAL_I2C_EnableListen_IT() @ref HAL_I2C_DisableListen_IT() + (+++) When address slave I2C match, @ref HAL_I2C_AddrCallback() is executed and user can + add his own code to check the Address Match Code and the transmission direction request by master (Write/Read). + (+++) At Listen mode end @ref HAL_I2C_ListenCpltCallback() is executed and user can + add his own code by customization of function pointer @ref HAL_I2C_ListenCpltCallback() + (++) Sequential transmit in slave I2C mode an amount of data in non-blocking mode using @ref HAL_I2C_Slave_Seq_Transmit_IT() + or using @ref HAL_I2C_Slave_Seq_Transmit_DMA() + (+++) At transmission end of current frame transfer, @ref HAL_I2C_SlaveTxCpltCallback() is executed and user can + add his own code by customization of function pointer @ref HAL_I2C_SlaveTxCpltCallback() + (++) Sequential receive in slave I2C mode an amount of data in non-blocking mode using @ref HAL_I2C_Slave_Seq_Receive_IT() + or using @ref HAL_I2C_Slave_Seq_Receive_DMA() + (+++) At reception end of current frame transfer, @ref HAL_I2C_SlaveRxCpltCallback() is executed and user can + add his own code by customization of function pointer @ref HAL_I2C_SlaveRxCpltCallback() + (++) In case of transfer Error, @ref HAL_I2C_ErrorCallback() function is executed and user can + add his own code by customization of function pointer @ref HAL_I2C_ErrorCallback() + (++) Discard a slave I2C process communication using @ref __HAL_I2C_GENERATE_NACK() macro. + This action will inform Master to generate a Stop condition to discard the communication. + + *** Interrupt mode IO MEM operation *** + ======================================= + [..] + (+) Write an amount of data in non-blocking mode with Interrupt to a specific memory address using + @ref HAL_I2C_Mem_Write_IT() + (+) At Memory end of write transfer, @ref HAL_I2C_MemTxCpltCallback() is executed and user can + add his own code by customization of function pointer @ref HAL_I2C_MemTxCpltCallback() + (+) Read an amount of data in non-blocking mode with Interrupt from a specific memory address using + @ref HAL_I2C_Mem_Read_IT() + (+) At Memory end of read transfer, @ref HAL_I2C_MemRxCpltCallback() is executed and user can + add his own code by customization of function pointer @ref HAL_I2C_MemRxCpltCallback() + (+) In case of transfer Error, @ref HAL_I2C_ErrorCallback() function is executed and user can + add his own code by customization of function pointer @ref HAL_I2C_ErrorCallback() + + *** DMA mode IO operation *** + ============================== + [..] + (+) Transmit in master mode an amount of data in non-blocking mode (DMA) using + @ref HAL_I2C_Master_Transmit_DMA() + (+) At transmission end of transfer, @ref HAL_I2C_MasterTxCpltCallback() is executed and user can + add his own code by customization of function pointer @ref HAL_I2C_MasterTxCpltCallback() + (+) Receive in master mode an amount of data in non-blocking mode (DMA) using + @ref HAL_I2C_Master_Receive_DMA() + (+) At reception end of transfer, @ref HAL_I2C_MasterRxCpltCallback() is executed and user can + add his own code by customization of function pointer @ref HAL_I2C_MasterRxCpltCallback() + (+) Transmit in slave mode an amount of data in non-blocking mode (DMA) using + @ref HAL_I2C_Slave_Transmit_DMA() + (+) At transmission end of transfer, @ref HAL_I2C_SlaveTxCpltCallback() is executed and user can + add his own code by customization of function pointer @ref HAL_I2C_SlaveTxCpltCallback() + (+) Receive in slave mode an amount of data in non-blocking mode (DMA) using + @ref HAL_I2C_Slave_Receive_DMA() + (+) At reception end of transfer, @ref HAL_I2C_SlaveRxCpltCallback() is executed and user can + add his own code by customization of function pointer @ref HAL_I2C_SlaveRxCpltCallback() + (+) In case of transfer Error, @ref HAL_I2C_ErrorCallback() function is executed and user can + add his own code by customization of function pointer @ref HAL_I2C_ErrorCallback() + (+) Abort a master I2C process communication with Interrupt using @ref HAL_I2C_Master_Abort_IT() + (+) End of abort process, @ref HAL_I2C_AbortCpltCallback() is executed and user can + add his own code by customization of function pointer @ref HAL_I2C_AbortCpltCallback() + (+) Discard a slave I2C process communication using @ref __HAL_I2C_GENERATE_NACK() macro. + This action will inform Master to generate a Stop condition to discard the communication. + + *** DMA mode IO MEM operation *** + ================================= + [..] + (+) Write an amount of data in non-blocking mode with DMA to a specific memory address using + @ref HAL_I2C_Mem_Write_DMA() + (+) At Memory end of write transfer, @ref HAL_I2C_MemTxCpltCallback() is executed and user can + add his own code by customization of function pointer @ref HAL_I2C_MemTxCpltCallback() + (+) Read an amount of data in non-blocking mode with DMA from a specific memory address using + @ref HAL_I2C_Mem_Read_DMA() + (+) At Memory end of read transfer, @ref HAL_I2C_MemRxCpltCallback() is executed and user can + add his own code by customization of function pointer @ref HAL_I2C_MemRxCpltCallback() + (+) In case of transfer Error, @ref HAL_I2C_ErrorCallback() function is executed and user can + add his own code by customization of function pointer @ref HAL_I2C_ErrorCallback() + + + *** I2C HAL driver macros list *** + ================================== + [..] + Below the list of most used macros in I2C HAL driver. + + (+) @ref __HAL_I2C_ENABLE: Enable the I2C peripheral + (+) @ref __HAL_I2C_DISABLE: Disable the I2C peripheral + (+) @ref __HAL_I2C_GENERATE_NACK: Generate a Non-Acknowledge I2C peripheral in Slave mode + (+) @ref __HAL_I2C_GET_FLAG: Check whether the specified I2C flag is set or not + (+) @ref __HAL_I2C_CLEAR_FLAG: Clear the specified I2C pending flag + (+) @ref __HAL_I2C_ENABLE_IT: Enable the specified I2C interrupt + (+) @ref __HAL_I2C_DISABLE_IT: Disable the specified I2C interrupt + + *** Callback registration *** + ============================================= + [..] + The compilation flag USE_HAL_I2C_REGISTER_CALLBACKS when set to 1 + allows the user to configure dynamically the driver callbacks. + Use Functions @ref HAL_I2C_RegisterCallback() or @ref HAL_I2C_RegisterAddrCallback() + to register an interrupt callback. + [..] + Function @ref HAL_I2C_RegisterCallback() allows to register following callbacks: + (+) MasterTxCpltCallback : callback for Master transmission end of transfer. + (+) MasterRxCpltCallback : callback for Master reception end of transfer. + (+) SlaveTxCpltCallback : callback for Slave transmission end of transfer. + (+) SlaveRxCpltCallback : callback for Slave reception end of transfer. + (+) ListenCpltCallback : callback for end of listen mode. + (+) MemTxCpltCallback : callback for Memory transmission end of transfer. + (+) MemRxCpltCallback : callback for Memory reception end of transfer. + (+) ErrorCallback : callback for error detection. + (+) AbortCpltCallback : callback for abort completion process. + (+) MspInitCallback : callback for Msp Init. + (+) MspDeInitCallback : callback for Msp DeInit. + This function takes as parameters the HAL peripheral handle, the Callback ID + and a pointer to the user callback function. + [..] + For specific callback AddrCallback use dedicated register callbacks : @ref HAL_I2C_RegisterAddrCallback(). + [..] + Use function @ref HAL_I2C_UnRegisterCallback to reset a callback to the default + weak function. + @ref HAL_I2C_UnRegisterCallback takes as parameters the HAL peripheral handle, + and the Callback ID. + This function allows to reset following callbacks: + (+) MasterTxCpltCallback : callback for Master transmission end of transfer. + (+) MasterRxCpltCallback : callback for Master reception end of transfer. + (+) SlaveTxCpltCallback : callback for Slave transmission end of transfer. + (+) SlaveRxCpltCallback : callback for Slave reception end of transfer. + (+) ListenCpltCallback : callback for end of listen mode. + (+) MemTxCpltCallback : callback for Memory transmission end of transfer. + (+) MemRxCpltCallback : callback for Memory reception end of transfer. + (+) ErrorCallback : callback for error detection. + (+) AbortCpltCallback : callback for abort completion process. + (+) MspInitCallback : callback for Msp Init. + (+) MspDeInitCallback : callback for Msp DeInit. + [..] + For callback AddrCallback use dedicated register callbacks : @ref HAL_I2C_UnRegisterAddrCallback(). + [..] + By default, after the @ref HAL_I2C_Init() and when the state is @ref HAL_I2C_STATE_RESET + all callbacks are set to the corresponding weak functions: + examples @ref HAL_I2C_MasterTxCpltCallback(), @ref HAL_I2C_MasterRxCpltCallback(). + Exception done for MspInit and MspDeInit functions that are + reset to the legacy weak functions in the @ref HAL_I2C_Init()/ @ref HAL_I2C_DeInit() only when + these callbacks are null (not registered beforehand). + If MspInit or MspDeInit are not null, the @ref HAL_I2C_Init()/ @ref HAL_I2C_DeInit() + keep and use the user MspInit/MspDeInit callbacks (registered beforehand) whatever the state. + [..] + Callbacks can be registered/unregistered in @ref HAL_I2C_STATE_READY state only. + Exception done MspInit/MspDeInit functions that can be registered/unregistered + in @ref HAL_I2C_STATE_READY or @ref HAL_I2C_STATE_RESET state, + thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit. + Then, the user first registers the MspInit/MspDeInit user callbacks + using @ref HAL_I2C_RegisterCallback() before calling @ref HAL_I2C_DeInit() + or @ref HAL_I2C_Init() function. + [..] + When the compilation flag USE_HAL_I2C_REGISTER_CALLBACKS is set to 0 or + not defined, the callback registration feature is not available and all callbacks + are set to the corresponding weak functions. + + [..] + (@) You can refer to the I2C HAL driver header file for more useful macros + + @endverbatim + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2016 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f0xx_hal.h" + +/** @addtogroup STM32F0xx_HAL_Driver + * @{ + */ + +/** @defgroup I2C I2C + * @brief I2C HAL module driver + * @{ + */ + +#ifdef HAL_I2C_MODULE_ENABLED + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ + +/** @defgroup I2C_Private_Define I2C Private Define + * @{ + */ +#define TIMING_CLEAR_MASK (0xF0FFFFFFU) /*!< I2C TIMING clear register Mask */ +#define I2C_TIMEOUT_ADDR (10000U) /*!< 10 s */ +#define I2C_TIMEOUT_BUSY (25U) /*!< 25 ms */ +#define I2C_TIMEOUT_DIR (25U) /*!< 25 ms */ +#define I2C_TIMEOUT_RXNE (25U) /*!< 25 ms */ +#define I2C_TIMEOUT_STOPF (25U) /*!< 25 ms */ +#define I2C_TIMEOUT_TC (25U) /*!< 25 ms */ +#define I2C_TIMEOUT_TCR (25U) /*!< 25 ms */ +#define I2C_TIMEOUT_TXIS (25U) /*!< 25 ms */ +#define I2C_TIMEOUT_FLAG (25U) /*!< 25 ms */ + +#define MAX_NBYTE_SIZE 255U +#define SlaveAddr_SHIFT 7U +#define SlaveAddr_MSK 0x06U + +/* Private define for @ref PreviousState usage */ +#define I2C_STATE_MSK ((uint32_t)((uint32_t)((uint32_t)HAL_I2C_STATE_BUSY_TX | (uint32_t)HAL_I2C_STATE_BUSY_RX) & (uint32_t)(~((uint32_t)HAL_I2C_STATE_READY)))) /*!< Mask State define, keep only RX and TX bits */ +#define I2C_STATE_NONE ((uint32_t)(HAL_I2C_MODE_NONE)) /*!< Default Value */ +#define I2C_STATE_MASTER_BUSY_TX ((uint32_t)(((uint32_t)HAL_I2C_STATE_BUSY_TX & I2C_STATE_MSK) | (uint32_t)HAL_I2C_MODE_MASTER)) /*!< Master Busy TX, combinaison of State LSB and Mode enum */ +#define I2C_STATE_MASTER_BUSY_RX ((uint32_t)(((uint32_t)HAL_I2C_STATE_BUSY_RX & I2C_STATE_MSK) | (uint32_t)HAL_I2C_MODE_MASTER)) /*!< Master Busy RX, combinaison of State LSB and Mode enum */ +#define I2C_STATE_SLAVE_BUSY_TX ((uint32_t)(((uint32_t)HAL_I2C_STATE_BUSY_TX & I2C_STATE_MSK) | (uint32_t)HAL_I2C_MODE_SLAVE)) /*!< Slave Busy TX, combinaison of State LSB and Mode enum */ +#define I2C_STATE_SLAVE_BUSY_RX ((uint32_t)(((uint32_t)HAL_I2C_STATE_BUSY_RX & I2C_STATE_MSK) | (uint32_t)HAL_I2C_MODE_SLAVE)) /*!< Slave Busy RX, combinaison of State LSB and Mode enum */ +#define I2C_STATE_MEM_BUSY_TX ((uint32_t)(((uint32_t)HAL_I2C_STATE_BUSY_TX & I2C_STATE_MSK) | (uint32_t)HAL_I2C_MODE_MEM)) /*!< Memory Busy TX, combinaison of State LSB and Mode enum */ +#define I2C_STATE_MEM_BUSY_RX ((uint32_t)(((uint32_t)HAL_I2C_STATE_BUSY_RX & I2C_STATE_MSK) | (uint32_t)HAL_I2C_MODE_MEM)) /*!< Memory Busy RX, combinaison of State LSB and Mode enum */ + + +/* Private define to centralize the enable/disable of Interrupts */ +#define I2C_XFER_TX_IT (0x00000001U) +#define I2C_XFER_RX_IT (0x00000002U) +#define I2C_XFER_LISTEN_IT (0x00000004U) + +#define I2C_XFER_ERROR_IT (0x00000011U) +#define I2C_XFER_CPLT_IT (0x00000012U) +#define I2C_XFER_RELOAD_IT (0x00000012U) + +/* Private define Sequential Transfer Options default/reset value */ +#define I2C_NO_OPTION_FRAME (0xFFFF0000U) +/** + * @} + */ + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ + +/** @defgroup I2C_Private_Functions I2C Private Functions + * @{ + */ +/* Private functions to handle DMA transfer */ +static void I2C_DMAMasterTransmitCplt(DMA_HandleTypeDef *hdma); +static void I2C_DMAMasterReceiveCplt(DMA_HandleTypeDef *hdma); +static void I2C_DMASlaveTransmitCplt(DMA_HandleTypeDef *hdma); +static void I2C_DMASlaveReceiveCplt(DMA_HandleTypeDef *hdma); +static void I2C_DMAError(DMA_HandleTypeDef *hdma); +static void I2C_DMAAbort(DMA_HandleTypeDef *hdma); + +/* Private functions to handle IT transfer */ +static void I2C_ITAddrCplt(I2C_HandleTypeDef *hi2c, uint32_t ITFlags); +static void I2C_ITMasterSeqCplt(I2C_HandleTypeDef *hi2c); +static void I2C_ITSlaveSeqCplt(I2C_HandleTypeDef *hi2c); +static void I2C_ITMasterCplt(I2C_HandleTypeDef *hi2c, uint32_t ITFlags); +static void I2C_ITSlaveCplt(I2C_HandleTypeDef *hi2c, uint32_t ITFlags); +static void I2C_ITListenCplt(I2C_HandleTypeDef *hi2c, uint32_t ITFlags); +static void I2C_ITError(I2C_HandleTypeDef *hi2c, uint32_t ErrorCode); + +/* Private functions to handle IT transfer */ +static HAL_StatusTypeDef I2C_RequestMemoryWrite(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint32_t Timeout, uint32_t Tickstart); +static HAL_StatusTypeDef I2C_RequestMemoryRead(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint32_t Timeout, uint32_t Tickstart); + +/* Private functions for I2C transfer IRQ handler */ +static HAL_StatusTypeDef I2C_Master_ISR_IT(struct __I2C_HandleTypeDef *hi2c, uint32_t ITFlags, uint32_t ITSources); +static HAL_StatusTypeDef I2C_Slave_ISR_IT(struct __I2C_HandleTypeDef *hi2c, uint32_t ITFlags, uint32_t ITSources); +static HAL_StatusTypeDef I2C_Master_ISR_DMA(struct __I2C_HandleTypeDef *hi2c, uint32_t ITFlags, uint32_t ITSources); +static HAL_StatusTypeDef I2C_Slave_ISR_DMA(struct __I2C_HandleTypeDef *hi2c, uint32_t ITFlags, uint32_t ITSources); + +/* Private functions to handle flags during polling transfer */ +static HAL_StatusTypeDef I2C_WaitOnFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Flag, FlagStatus Status, uint32_t Timeout, uint32_t Tickstart); +static HAL_StatusTypeDef I2C_WaitOnTXISFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Timeout, uint32_t Tickstart); +static HAL_StatusTypeDef I2C_WaitOnRXNEFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Timeout, uint32_t Tickstart); +static HAL_StatusTypeDef I2C_WaitOnSTOPFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Timeout, uint32_t Tickstart); +static HAL_StatusTypeDef I2C_IsAcknowledgeFailed(I2C_HandleTypeDef *hi2c, uint32_t Timeout, uint32_t Tickstart); + +/* Private functions to centralize the enable/disable of Interrupts */ +static void I2C_Enable_IRQ(I2C_HandleTypeDef *hi2c, uint16_t InterruptRequest); +static void I2C_Disable_IRQ(I2C_HandleTypeDef *hi2c, uint16_t InterruptRequest); + +/* Private function to flush TXDR register */ +static void I2C_Flush_TXDR(I2C_HandleTypeDef *hi2c); + +/* Private function to handle start, restart or stop a transfer */ +static void I2C_TransferConfig(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t Size, uint32_t Mode, uint32_t Request); + +/* Private function to Convert Specific options */ +static void I2C_ConvertOtherXferOptions(I2C_HandleTypeDef *hi2c); +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ + +/** @defgroup I2C_Exported_Functions I2C Exported Functions + * @{ + */ + +/** @defgroup I2C_Exported_Functions_Group1 Initialization and de-initialization functions + * @brief Initialization and Configuration functions + * +@verbatim + =============================================================================== + ##### Initialization and de-initialization functions ##### + =============================================================================== + [..] This subsection provides a set of functions allowing to initialize and + deinitialize the I2Cx peripheral: + + (+) User must Implement HAL_I2C_MspInit() function in which he configures + all related peripherals resources (CLOCK, GPIO, DMA, IT and NVIC ). + + (+) Call the function HAL_I2C_Init() to configure the selected device with + the selected configuration: + (++) Clock Timing + (++) Own Address 1 + (++) Addressing mode (Master, Slave) + (++) Dual Addressing mode + (++) Own Address 2 + (++) Own Address 2 Mask + (++) General call mode + (++) Nostretch mode + + (+) Call the function HAL_I2C_DeInit() to restore the default configuration + of the selected I2Cx peripheral. + +@endverbatim + * @{ + */ + +/** + * @brief Initializes the I2C according to the specified parameters + * in the I2C_InitTypeDef and initialize the associated handle. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Init(I2C_HandleTypeDef *hi2c) +{ + /* Check the I2C handle allocation */ + if (hi2c == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_I2C_ALL_INSTANCE(hi2c->Instance)); + assert_param(IS_I2C_OWN_ADDRESS1(hi2c->Init.OwnAddress1)); + assert_param(IS_I2C_ADDRESSING_MODE(hi2c->Init.AddressingMode)); + assert_param(IS_I2C_DUAL_ADDRESS(hi2c->Init.DualAddressMode)); + assert_param(IS_I2C_OWN_ADDRESS2(hi2c->Init.OwnAddress2)); + assert_param(IS_I2C_OWN_ADDRESS2_MASK(hi2c->Init.OwnAddress2Masks)); + assert_param(IS_I2C_GENERAL_CALL(hi2c->Init.GeneralCallMode)); + assert_param(IS_I2C_NO_STRETCH(hi2c->Init.NoStretchMode)); + + if (hi2c->State == HAL_I2C_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + hi2c->Lock = HAL_UNLOCKED; + +#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1) + /* Init the I2C Callback settings */ + hi2c->MasterTxCpltCallback = HAL_I2C_MasterTxCpltCallback; /* Legacy weak MasterTxCpltCallback */ + hi2c->MasterRxCpltCallback = HAL_I2C_MasterRxCpltCallback; /* Legacy weak MasterRxCpltCallback */ + hi2c->SlaveTxCpltCallback = HAL_I2C_SlaveTxCpltCallback; /* Legacy weak SlaveTxCpltCallback */ + hi2c->SlaveRxCpltCallback = HAL_I2C_SlaveRxCpltCallback; /* Legacy weak SlaveRxCpltCallback */ + hi2c->ListenCpltCallback = HAL_I2C_ListenCpltCallback; /* Legacy weak ListenCpltCallback */ + hi2c->MemTxCpltCallback = HAL_I2C_MemTxCpltCallback; /* Legacy weak MemTxCpltCallback */ + hi2c->MemRxCpltCallback = HAL_I2C_MemRxCpltCallback; /* Legacy weak MemRxCpltCallback */ + hi2c->ErrorCallback = HAL_I2C_ErrorCallback; /* Legacy weak ErrorCallback */ + hi2c->AbortCpltCallback = HAL_I2C_AbortCpltCallback; /* Legacy weak AbortCpltCallback */ + hi2c->AddrCallback = HAL_I2C_AddrCallback; /* Legacy weak AddrCallback */ + + if (hi2c->MspInitCallback == NULL) + { + hi2c->MspInitCallback = HAL_I2C_MspInit; /* Legacy weak MspInit */ + } + + /* Init the low level hardware : GPIO, CLOCK, CORTEX...etc */ + hi2c->MspInitCallback(hi2c); +#else + /* Init the low level hardware : GPIO, CLOCK, CORTEX...etc */ + HAL_I2C_MspInit(hi2c); +#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */ + } + + hi2c->State = HAL_I2C_STATE_BUSY; + + /* Disable the selected I2C peripheral */ + __HAL_I2C_DISABLE(hi2c); + + /*---------------------------- I2Cx TIMINGR Configuration ------------------*/ + /* Configure I2Cx: Frequency range */ + hi2c->Instance->TIMINGR = hi2c->Init.Timing & TIMING_CLEAR_MASK; + + /*---------------------------- I2Cx OAR1 Configuration ---------------------*/ + /* Disable Own Address1 before set the Own Address1 configuration */ + hi2c->Instance->OAR1 &= ~I2C_OAR1_OA1EN; + + /* Configure I2Cx: Own Address1 and ack own address1 mode */ + if (hi2c->Init.AddressingMode == I2C_ADDRESSINGMODE_7BIT) + { + hi2c->Instance->OAR1 = (I2C_OAR1_OA1EN | hi2c->Init.OwnAddress1); + } + else /* I2C_ADDRESSINGMODE_10BIT */ + { + hi2c->Instance->OAR1 = (I2C_OAR1_OA1EN | I2C_OAR1_OA1MODE | hi2c->Init.OwnAddress1); + } + + /*---------------------------- I2Cx CR2 Configuration ----------------------*/ + /* Configure I2Cx: Addressing Master mode */ + if (hi2c->Init.AddressingMode == I2C_ADDRESSINGMODE_10BIT) + { + hi2c->Instance->CR2 = (I2C_CR2_ADD10); + } + /* Enable the AUTOEND by default, and enable NACK (should be disable only during Slave process */ + hi2c->Instance->CR2 |= (I2C_CR2_AUTOEND | I2C_CR2_NACK); + + /*---------------------------- I2Cx OAR2 Configuration ---------------------*/ + /* Disable Own Address2 before set the Own Address2 configuration */ + hi2c->Instance->OAR2 &= ~I2C_DUALADDRESS_ENABLE; + + /* Configure I2Cx: Dual mode and Own Address2 */ + hi2c->Instance->OAR2 = (hi2c->Init.DualAddressMode | hi2c->Init.OwnAddress2 | (hi2c->Init.OwnAddress2Masks << 8)); + + /*---------------------------- I2Cx CR1 Configuration ----------------------*/ + /* Configure I2Cx: Generalcall and NoStretch mode */ + hi2c->Instance->CR1 = (hi2c->Init.GeneralCallMode | hi2c->Init.NoStretchMode); + + /* Enable the selected I2C peripheral */ + __HAL_I2C_ENABLE(hi2c); + + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + hi2c->State = HAL_I2C_STATE_READY; + hi2c->PreviousState = I2C_STATE_NONE; + hi2c->Mode = HAL_I2C_MODE_NONE; + + return HAL_OK; +} + +/** + * @brief DeInitialize the I2C peripheral. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_DeInit(I2C_HandleTypeDef *hi2c) +{ + /* Check the I2C handle allocation */ + if (hi2c == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_I2C_ALL_INSTANCE(hi2c->Instance)); + + hi2c->State = HAL_I2C_STATE_BUSY; + + /* Disable the I2C Peripheral Clock */ + __HAL_I2C_DISABLE(hi2c); + +#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1) + if (hi2c->MspDeInitCallback == NULL) + { + hi2c->MspDeInitCallback = HAL_I2C_MspDeInit; /* Legacy weak MspDeInit */ + } + + /* DeInit the low level hardware: GPIO, CLOCK, NVIC */ + hi2c->MspDeInitCallback(hi2c); +#else + /* DeInit the low level hardware: GPIO, CLOCK, NVIC */ + HAL_I2C_MspDeInit(hi2c); +#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */ + + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + hi2c->State = HAL_I2C_STATE_RESET; + hi2c->PreviousState = I2C_STATE_NONE; + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Release Lock */ + __HAL_UNLOCK(hi2c); + + return HAL_OK; +} + +/** + * @brief Initialize the I2C MSP. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @retval None + */ +__weak void HAL_I2C_MspInit(I2C_HandleTypeDef *hi2c) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hi2c); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_I2C_MspInit could be implemented in the user file + */ +} + +/** + * @brief DeInitialize the I2C MSP. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @retval None + */ +__weak void HAL_I2C_MspDeInit(I2C_HandleTypeDef *hi2c) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hi2c); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_I2C_MspDeInit could be implemented in the user file + */ +} + +#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1) +/** + * @brief Register a User I2C Callback + * To be used instead of the weak predefined callback + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param CallbackID ID of the callback to be registered + * This parameter can be one of the following values: + * @arg @ref HAL_I2C_MASTER_TX_COMPLETE_CB_ID Master Tx Transfer completed callback ID + * @arg @ref HAL_I2C_MASTER_RX_COMPLETE_CB_ID Master Rx Transfer completed callback ID + * @arg @ref HAL_I2C_SLAVE_TX_COMPLETE_CB_ID Slave Tx Transfer completed callback ID + * @arg @ref HAL_I2C_SLAVE_RX_COMPLETE_CB_ID Slave Rx Transfer completed callback ID + * @arg @ref HAL_I2C_LISTEN_COMPLETE_CB_ID Listen Complete callback ID + * @arg @ref HAL_I2C_MEM_TX_COMPLETE_CB_ID Memory Tx Transfer callback ID + * @arg @ref HAL_I2C_MEM_RX_COMPLETE_CB_ID Memory Rx Transfer completed callback ID + * @arg @ref HAL_I2C_ERROR_CB_ID Error callback ID + * @arg @ref HAL_I2C_ABORT_CB_ID Abort callback ID + * @arg @ref HAL_I2C_MSPINIT_CB_ID MspInit callback ID + * @arg @ref HAL_I2C_MSPDEINIT_CB_ID MspDeInit callback ID + * @param pCallback pointer to the Callback function + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_RegisterCallback(I2C_HandleTypeDef *hi2c, HAL_I2C_CallbackIDTypeDef CallbackID, pI2C_CallbackTypeDef pCallback) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (pCallback == NULL) + { + /* Update the error code */ + hi2c->ErrorCode |= HAL_I2C_ERROR_INVALID_CALLBACK; + + return HAL_ERROR; + } + /* Process locked */ + __HAL_LOCK(hi2c); + + if (HAL_I2C_STATE_READY == hi2c->State) + { + switch (CallbackID) + { + case HAL_I2C_MASTER_TX_COMPLETE_CB_ID : + hi2c->MasterTxCpltCallback = pCallback; + break; + + case HAL_I2C_MASTER_RX_COMPLETE_CB_ID : + hi2c->MasterRxCpltCallback = pCallback; + break; + + case HAL_I2C_SLAVE_TX_COMPLETE_CB_ID : + hi2c->SlaveTxCpltCallback = pCallback; + break; + + case HAL_I2C_SLAVE_RX_COMPLETE_CB_ID : + hi2c->SlaveRxCpltCallback = pCallback; + break; + + case HAL_I2C_LISTEN_COMPLETE_CB_ID : + hi2c->ListenCpltCallback = pCallback; + break; + + case HAL_I2C_MEM_TX_COMPLETE_CB_ID : + hi2c->MemTxCpltCallback = pCallback; + break; + + case HAL_I2C_MEM_RX_COMPLETE_CB_ID : + hi2c->MemRxCpltCallback = pCallback; + break; + + case HAL_I2C_ERROR_CB_ID : + hi2c->ErrorCallback = pCallback; + break; + + case HAL_I2C_ABORT_CB_ID : + hi2c->AbortCpltCallback = pCallback; + break; + + case HAL_I2C_MSPINIT_CB_ID : + hi2c->MspInitCallback = pCallback; + break; + + case HAL_I2C_MSPDEINIT_CB_ID : + hi2c->MspDeInitCallback = pCallback; + break; + + default : + /* Update the error code */ + hi2c->ErrorCode |= HAL_I2C_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else if (HAL_I2C_STATE_RESET == hi2c->State) + { + switch (CallbackID) + { + case HAL_I2C_MSPINIT_CB_ID : + hi2c->MspInitCallback = pCallback; + break; + + case HAL_I2C_MSPDEINIT_CB_ID : + hi2c->MspDeInitCallback = pCallback; + break; + + default : + /* Update the error code */ + hi2c->ErrorCode |= HAL_I2C_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else + { + /* Update the error code */ + hi2c->ErrorCode |= HAL_I2C_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + } + + /* Release Lock */ + __HAL_UNLOCK(hi2c); + return status; +} + +/** + * @brief Unregister an I2C Callback + * I2C callback is redirected to the weak predefined callback + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param CallbackID ID of the callback to be unregistered + * This parameter can be one of the following values: + * This parameter can be one of the following values: + * @arg @ref HAL_I2C_MASTER_TX_COMPLETE_CB_ID Master Tx Transfer completed callback ID + * @arg @ref HAL_I2C_MASTER_RX_COMPLETE_CB_ID Master Rx Transfer completed callback ID + * @arg @ref HAL_I2C_SLAVE_TX_COMPLETE_CB_ID Slave Tx Transfer completed callback ID + * @arg @ref HAL_I2C_SLAVE_RX_COMPLETE_CB_ID Slave Rx Transfer completed callback ID + * @arg @ref HAL_I2C_LISTEN_COMPLETE_CB_ID Listen Complete callback ID + * @arg @ref HAL_I2C_MEM_TX_COMPLETE_CB_ID Memory Tx Transfer callback ID + * @arg @ref HAL_I2C_MEM_RX_COMPLETE_CB_ID Memory Rx Transfer completed callback ID + * @arg @ref HAL_I2C_ERROR_CB_ID Error callback ID + * @arg @ref HAL_I2C_ABORT_CB_ID Abort callback ID + * @arg @ref HAL_I2C_MSPINIT_CB_ID MspInit callback ID + * @arg @ref HAL_I2C_MSPDEINIT_CB_ID MspDeInit callback ID + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_UnRegisterCallback(I2C_HandleTypeDef *hi2c, HAL_I2C_CallbackIDTypeDef CallbackID) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Process locked */ + __HAL_LOCK(hi2c); + + if (HAL_I2C_STATE_READY == hi2c->State) + { + switch (CallbackID) + { + case HAL_I2C_MASTER_TX_COMPLETE_CB_ID : + hi2c->MasterTxCpltCallback = HAL_I2C_MasterTxCpltCallback; /* Legacy weak MasterTxCpltCallback */ + break; + + case HAL_I2C_MASTER_RX_COMPLETE_CB_ID : + hi2c->MasterRxCpltCallback = HAL_I2C_MasterRxCpltCallback; /* Legacy weak MasterRxCpltCallback */ + break; + + case HAL_I2C_SLAVE_TX_COMPLETE_CB_ID : + hi2c->SlaveTxCpltCallback = HAL_I2C_SlaveTxCpltCallback; /* Legacy weak SlaveTxCpltCallback */ + break; + + case HAL_I2C_SLAVE_RX_COMPLETE_CB_ID : + hi2c->SlaveRxCpltCallback = HAL_I2C_SlaveRxCpltCallback; /* Legacy weak SlaveRxCpltCallback */ + break; + + case HAL_I2C_LISTEN_COMPLETE_CB_ID : + hi2c->ListenCpltCallback = HAL_I2C_ListenCpltCallback; /* Legacy weak ListenCpltCallback */ + break; + + case HAL_I2C_MEM_TX_COMPLETE_CB_ID : + hi2c->MemTxCpltCallback = HAL_I2C_MemTxCpltCallback; /* Legacy weak MemTxCpltCallback */ + break; + + case HAL_I2C_MEM_RX_COMPLETE_CB_ID : + hi2c->MemRxCpltCallback = HAL_I2C_MemRxCpltCallback; /* Legacy weak MemRxCpltCallback */ + break; + + case HAL_I2C_ERROR_CB_ID : + hi2c->ErrorCallback = HAL_I2C_ErrorCallback; /* Legacy weak ErrorCallback */ + break; + + case HAL_I2C_ABORT_CB_ID : + hi2c->AbortCpltCallback = HAL_I2C_AbortCpltCallback; /* Legacy weak AbortCpltCallback */ + break; + + case HAL_I2C_MSPINIT_CB_ID : + hi2c->MspInitCallback = HAL_I2C_MspInit; /* Legacy weak MspInit */ + break; + + case HAL_I2C_MSPDEINIT_CB_ID : + hi2c->MspDeInitCallback = HAL_I2C_MspDeInit; /* Legacy weak MspDeInit */ + break; + + default : + /* Update the error code */ + hi2c->ErrorCode |= HAL_I2C_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else if (HAL_I2C_STATE_RESET == hi2c->State) + { + switch (CallbackID) + { + case HAL_I2C_MSPINIT_CB_ID : + hi2c->MspInitCallback = HAL_I2C_MspInit; /* Legacy weak MspInit */ + break; + + case HAL_I2C_MSPDEINIT_CB_ID : + hi2c->MspDeInitCallback = HAL_I2C_MspDeInit; /* Legacy weak MspDeInit */ + break; + + default : + /* Update the error code */ + hi2c->ErrorCode |= HAL_I2C_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else + { + /* Update the error code */ + hi2c->ErrorCode |= HAL_I2C_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + } + + /* Release Lock */ + __HAL_UNLOCK(hi2c); + return status; +} + +/** + * @brief Register the Slave Address Match I2C Callback + * To be used instead of the weak HAL_I2C_AddrCallback() predefined callback + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param pCallback pointer to the Address Match Callback function + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_RegisterAddrCallback(I2C_HandleTypeDef *hi2c, pI2C_AddrCallbackTypeDef pCallback) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (pCallback == NULL) + { + /* Update the error code */ + hi2c->ErrorCode |= HAL_I2C_ERROR_INVALID_CALLBACK; + + return HAL_ERROR; + } + /* Process locked */ + __HAL_LOCK(hi2c); + + if (HAL_I2C_STATE_READY == hi2c->State) + { + hi2c->AddrCallback = pCallback; + } + else + { + /* Update the error code */ + hi2c->ErrorCode |= HAL_I2C_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + } + + /* Release Lock */ + __HAL_UNLOCK(hi2c); + return status; +} + +/** + * @brief UnRegister the Slave Address Match I2C Callback + * Info Ready I2C Callback is redirected to the weak HAL_I2C_AddrCallback() predefined callback + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_UnRegisterAddrCallback(I2C_HandleTypeDef *hi2c) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Process locked */ + __HAL_LOCK(hi2c); + + if (HAL_I2C_STATE_READY == hi2c->State) + { + hi2c->AddrCallback = HAL_I2C_AddrCallback; /* Legacy weak AddrCallback */ + } + else + { + /* Update the error code */ + hi2c->ErrorCode |= HAL_I2C_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + } + + /* Release Lock */ + __HAL_UNLOCK(hi2c); + return status; +} + +#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */ + +/** + * @} + */ + +/** @defgroup I2C_Exported_Functions_Group2 Input and Output operation functions + * @brief Data transfers functions + * +@verbatim + =============================================================================== + ##### IO operation functions ##### + =============================================================================== + [..] + This subsection provides a set of functions allowing to manage the I2C data + transfers. + + (#) There are two modes of transfer: + (++) Blocking mode : The communication is performed in the polling mode. + The status of all data processing is returned by the same function + after finishing transfer. + (++) No-Blocking mode : The communication is performed using Interrupts + or DMA. These functions return the status of the transfer startup. + The end of the data processing will be indicated through the + dedicated I2C IRQ when using Interrupt mode or the DMA IRQ when + using DMA mode. + + (#) Blocking mode functions are : + (++) HAL_I2C_Master_Transmit() + (++) HAL_I2C_Master_Receive() + (++) HAL_I2C_Slave_Transmit() + (++) HAL_I2C_Slave_Receive() + (++) HAL_I2C_Mem_Write() + (++) HAL_I2C_Mem_Read() + (++) HAL_I2C_IsDeviceReady() + + (#) No-Blocking mode functions with Interrupt are : + (++) HAL_I2C_Master_Transmit_IT() + (++) HAL_I2C_Master_Receive_IT() + (++) HAL_I2C_Slave_Transmit_IT() + (++) HAL_I2C_Slave_Receive_IT() + (++) HAL_I2C_Mem_Write_IT() + (++) HAL_I2C_Mem_Read_IT() + (++) HAL_I2C_Master_Seq_Transmit_IT() + (++) HAL_I2C_Master_Seq_Receive_IT() + (++) HAL_I2C_Slave_Seq_Transmit_IT() + (++) HAL_I2C_Slave_Seq_Receive_IT() + (++) HAL_I2C_EnableListen_IT() + (++) HAL_I2C_DisableListen_IT() + (++) HAL_I2C_Master_Abort_IT() + + (#) No-Blocking mode functions with DMA are : + (++) HAL_I2C_Master_Transmit_DMA() + (++) HAL_I2C_Master_Receive_DMA() + (++) HAL_I2C_Slave_Transmit_DMA() + (++) HAL_I2C_Slave_Receive_DMA() + (++) HAL_I2C_Mem_Write_DMA() + (++) HAL_I2C_Mem_Read_DMA() + (++) HAL_I2C_Master_Seq_Transmit_DMA() + (++) HAL_I2C_Master_Seq_Receive_DMA() + (++) HAL_I2C_Slave_Seq_Transmit_DMA() + (++) HAL_I2C_Slave_Seq_Receive_DMA() + + (#) A set of Transfer Complete Callbacks are provided in non Blocking mode: + (++) HAL_I2C_MasterTxCpltCallback() + (++) HAL_I2C_MasterRxCpltCallback() + (++) HAL_I2C_SlaveTxCpltCallback() + (++) HAL_I2C_SlaveRxCpltCallback() + (++) HAL_I2C_MemTxCpltCallback() + (++) HAL_I2C_MemRxCpltCallback() + (++) HAL_I2C_AddrCallback() + (++) HAL_I2C_ListenCpltCallback() + (++) HAL_I2C_ErrorCallback() + (++) HAL_I2C_AbortCpltCallback() + +@endverbatim + * @{ + */ + +/** + * @brief Transmits in master mode an amount of data in blocking mode. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param DevAddress Target device address: The device 7 bits address value + * in datasheet must be shifted to the left before calling the interface + * @param pData Pointer to data buffer + * @param Size Amount of data to be sent + * @param Timeout Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Master_Transmit(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout) +{ + uint32_t tickstart; + + if (hi2c->State == HAL_I2C_STATE_READY) + { + /* Process Locked */ + __HAL_LOCK(hi2c); + + /* Init tickstart for timeout management*/ + tickstart = HAL_GetTick(); + + if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY, tickstart) != HAL_OK) + { + return HAL_ERROR; + } + + hi2c->State = HAL_I2C_STATE_BUSY_TX; + hi2c->Mode = HAL_I2C_MODE_MASTER; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + /* Prepare transfer parameters */ + hi2c->pBuffPtr = pData; + hi2c->XferCount = Size; + hi2c->XferISR = NULL; + + /* Send Slave Address */ + /* Set NBYTES to write and reload if hi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */ + if (hi2c->XferCount > MAX_NBYTE_SIZE) + { + hi2c->XferSize = MAX_NBYTE_SIZE; + I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_RELOAD_MODE, I2C_GENERATE_START_WRITE); + } + else + { + hi2c->XferSize = hi2c->XferCount; + I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_AUTOEND_MODE, I2C_GENERATE_START_WRITE); + } + + while (hi2c->XferCount > 0U) + { + /* Wait until TXIS flag is set */ + if (I2C_WaitOnTXISFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) + { + return HAL_ERROR; + } + /* Write data to TXDR */ + hi2c->Instance->TXDR = *hi2c->pBuffPtr; + + /* Increment Buffer pointer */ + hi2c->pBuffPtr++; + + hi2c->XferCount--; + hi2c->XferSize--; + + if ((hi2c->XferCount != 0U) && (hi2c->XferSize == 0U)) + { + /* Wait until TCR flag is set */ + if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_TCR, RESET, Timeout, tickstart) != HAL_OK) + { + return HAL_ERROR; + } + + if (hi2c->XferCount > MAX_NBYTE_SIZE) + { + hi2c->XferSize = MAX_NBYTE_SIZE; + I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_RELOAD_MODE, I2C_NO_STARTSTOP); + } + else + { + hi2c->XferSize = hi2c->XferCount; + I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_AUTOEND_MODE, I2C_NO_STARTSTOP); + } + } + } + + /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */ + /* Wait until STOPF flag is set */ + if (I2C_WaitOnSTOPFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) + { + return HAL_ERROR; + } + + /* Clear STOP Flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF); + + /* Clear Configuration Register 2 */ + I2C_RESET_CR2(hi2c); + + hi2c->State = HAL_I2C_STATE_READY; + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Receives in master mode an amount of data in blocking mode. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param DevAddress Target device address: The device 7 bits address value + * in datasheet must be shifted to the left before calling the interface + * @param pData Pointer to data buffer + * @param Size Amount of data to be sent + * @param Timeout Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Master_Receive(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout) +{ + uint32_t tickstart; + + if (hi2c->State == HAL_I2C_STATE_READY) + { + /* Process Locked */ + __HAL_LOCK(hi2c); + + /* Init tickstart for timeout management*/ + tickstart = HAL_GetTick(); + + if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY, tickstart) != HAL_OK) + { + return HAL_ERROR; + } + + hi2c->State = HAL_I2C_STATE_BUSY_RX; + hi2c->Mode = HAL_I2C_MODE_MASTER; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + /* Prepare transfer parameters */ + hi2c->pBuffPtr = pData; + hi2c->XferCount = Size; + hi2c->XferISR = NULL; + + /* Send Slave Address */ + /* Set NBYTES to write and reload if hi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */ + if (hi2c->XferCount > MAX_NBYTE_SIZE) + { + hi2c->XferSize = MAX_NBYTE_SIZE; + I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_RELOAD_MODE, I2C_GENERATE_START_READ); + } + else + { + hi2c->XferSize = hi2c->XferCount; + I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_AUTOEND_MODE, I2C_GENERATE_START_READ); + } + + while (hi2c->XferCount > 0U) + { + /* Wait until RXNE flag is set */ + if (I2C_WaitOnRXNEFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) + { + return HAL_ERROR; + } + + /* Read data from RXDR */ + *hi2c->pBuffPtr = (uint8_t)hi2c->Instance->RXDR; + + /* Increment Buffer pointer */ + hi2c->pBuffPtr++; + + hi2c->XferSize--; + hi2c->XferCount--; + + if ((hi2c->XferCount != 0U) && (hi2c->XferSize == 0U)) + { + /* Wait until TCR flag is set */ + if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_TCR, RESET, Timeout, tickstart) != HAL_OK) + { + return HAL_ERROR; + } + + if (hi2c->XferCount > MAX_NBYTE_SIZE) + { + hi2c->XferSize = MAX_NBYTE_SIZE; + I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_RELOAD_MODE, I2C_NO_STARTSTOP); + } + else + { + hi2c->XferSize = hi2c->XferCount; + I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_AUTOEND_MODE, I2C_NO_STARTSTOP); + } + } + } + + /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */ + /* Wait until STOPF flag is set */ + if (I2C_WaitOnSTOPFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) + { + return HAL_ERROR; + } + + /* Clear STOP Flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF); + + /* Clear Configuration Register 2 */ + I2C_RESET_CR2(hi2c); + + hi2c->State = HAL_I2C_STATE_READY; + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Transmits in slave mode an amount of data in blocking mode. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param pData Pointer to data buffer + * @param Size Amount of data to be sent + * @param Timeout Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Slave_Transmit(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t Timeout) +{ + uint32_t tickstart; + + if (hi2c->State == HAL_I2C_STATE_READY) + { + if ((pData == NULL) || (Size == 0U)) + { + hi2c->ErrorCode = HAL_I2C_ERROR_INVALID_PARAM; + return HAL_ERROR; + } + /* Process Locked */ + __HAL_LOCK(hi2c); + + /* Init tickstart for timeout management*/ + tickstart = HAL_GetTick(); + + hi2c->State = HAL_I2C_STATE_BUSY_TX; + hi2c->Mode = HAL_I2C_MODE_SLAVE; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + /* Prepare transfer parameters */ + hi2c->pBuffPtr = pData; + hi2c->XferCount = Size; + hi2c->XferISR = NULL; + + /* Enable Address Acknowledge */ + hi2c->Instance->CR2 &= ~I2C_CR2_NACK; + + /* Wait until ADDR flag is set */ + if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, RESET, Timeout, tickstart) != HAL_OK) + { + /* Disable Address Acknowledge */ + hi2c->Instance->CR2 |= I2C_CR2_NACK; + return HAL_ERROR; + } + + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_ADDR); + + /* If 10bit addressing mode is selected */ + if (hi2c->Init.AddressingMode == I2C_ADDRESSINGMODE_10BIT) + { + /* Wait until ADDR flag is set */ + if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, RESET, Timeout, tickstart) != HAL_OK) + { + /* Disable Address Acknowledge */ + hi2c->Instance->CR2 |= I2C_CR2_NACK; + return HAL_ERROR; + } + + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_ADDR); + } + + /* Wait until DIR flag is set Transmitter mode */ + if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_DIR, RESET, Timeout, tickstart) != HAL_OK) + { + /* Disable Address Acknowledge */ + hi2c->Instance->CR2 |= I2C_CR2_NACK; + return HAL_ERROR; + } + + while (hi2c->XferCount > 0U) + { + /* Wait until TXIS flag is set */ + if (I2C_WaitOnTXISFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) + { + /* Disable Address Acknowledge */ + hi2c->Instance->CR2 |= I2C_CR2_NACK; + return HAL_ERROR; + } + + /* Write data to TXDR */ + hi2c->Instance->TXDR = *hi2c->pBuffPtr; + + /* Increment Buffer pointer */ + hi2c->pBuffPtr++; + + hi2c->XferCount--; + } + + /* Wait until STOP flag is set */ + if (I2C_WaitOnSTOPFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) + { + /* Disable Address Acknowledge */ + hi2c->Instance->CR2 |= I2C_CR2_NACK; + + if (hi2c->ErrorCode == HAL_I2C_ERROR_AF) + { + /* Normal use case for Transmitter mode */ + /* A NACK is generated to confirm the end of transfer */ + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + } + else + { + return HAL_ERROR; + } + } + + /* Clear STOP flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF); + + /* Wait until BUSY flag is reset */ + if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, Timeout, tickstart) != HAL_OK) + { + /* Disable Address Acknowledge */ + hi2c->Instance->CR2 |= I2C_CR2_NACK; + return HAL_ERROR; + } + + /* Disable Address Acknowledge */ + hi2c->Instance->CR2 |= I2C_CR2_NACK; + + hi2c->State = HAL_I2C_STATE_READY; + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Receive in slave mode an amount of data in blocking mode + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param pData Pointer to data buffer + * @param Size Amount of data to be sent + * @param Timeout Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Slave_Receive(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t Timeout) +{ + uint32_t tickstart; + + if (hi2c->State == HAL_I2C_STATE_READY) + { + if ((pData == NULL) || (Size == 0U)) + { + hi2c->ErrorCode = HAL_I2C_ERROR_INVALID_PARAM; + return HAL_ERROR; + } + /* Process Locked */ + __HAL_LOCK(hi2c); + + /* Init tickstart for timeout management*/ + tickstart = HAL_GetTick(); + + hi2c->State = HAL_I2C_STATE_BUSY_RX; + hi2c->Mode = HAL_I2C_MODE_SLAVE; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + /* Prepare transfer parameters */ + hi2c->pBuffPtr = pData; + hi2c->XferCount = Size; + hi2c->XferISR = NULL; + + /* Enable Address Acknowledge */ + hi2c->Instance->CR2 &= ~I2C_CR2_NACK; + + /* Wait until ADDR flag is set */ + if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, RESET, Timeout, tickstart) != HAL_OK) + { + /* Disable Address Acknowledge */ + hi2c->Instance->CR2 |= I2C_CR2_NACK; + return HAL_ERROR; + } + + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_ADDR); + + /* Wait until DIR flag is reset Receiver mode */ + if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_DIR, SET, Timeout, tickstart) != HAL_OK) + { + /* Disable Address Acknowledge */ + hi2c->Instance->CR2 |= I2C_CR2_NACK; + return HAL_ERROR; + } + + while (hi2c->XferCount > 0U) + { + /* Wait until RXNE flag is set */ + if (I2C_WaitOnRXNEFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) + { + /* Disable Address Acknowledge */ + hi2c->Instance->CR2 |= I2C_CR2_NACK; + + /* Store Last receive data if any */ + if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_RXNE) == SET) + { + /* Read data from RXDR */ + *hi2c->pBuffPtr = (uint8_t)hi2c->Instance->RXDR; + + /* Increment Buffer pointer */ + hi2c->pBuffPtr++; + + hi2c->XferCount--; + } + + return HAL_ERROR; + } + + /* Read data from RXDR */ + *hi2c->pBuffPtr = (uint8_t)hi2c->Instance->RXDR; + + /* Increment Buffer pointer */ + hi2c->pBuffPtr++; + + hi2c->XferCount--; + } + + /* Wait until STOP flag is set */ + if (I2C_WaitOnSTOPFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) + { + /* Disable Address Acknowledge */ + hi2c->Instance->CR2 |= I2C_CR2_NACK; + return HAL_ERROR; + } + + /* Clear STOP flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF); + + /* Wait until BUSY flag is reset */ + if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, Timeout, tickstart) != HAL_OK) + { + /* Disable Address Acknowledge */ + hi2c->Instance->CR2 |= I2C_CR2_NACK; + return HAL_ERROR; + } + + /* Disable Address Acknowledge */ + hi2c->Instance->CR2 |= I2C_CR2_NACK; + + hi2c->State = HAL_I2C_STATE_READY; + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Transmit in master mode an amount of data in non-blocking mode with Interrupt + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param DevAddress Target device address: The device 7 bits address value + * in datasheet must be shifted to the left before calling the interface + * @param pData Pointer to data buffer + * @param Size Amount of data to be sent + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Master_Transmit_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size) +{ + uint32_t xfermode; + + if (hi2c->State == HAL_I2C_STATE_READY) + { + if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) == SET) + { + return HAL_BUSY; + } + + /* Process Locked */ + __HAL_LOCK(hi2c); + + hi2c->State = HAL_I2C_STATE_BUSY_TX; + hi2c->Mode = HAL_I2C_MODE_MASTER; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + /* Prepare transfer parameters */ + hi2c->pBuffPtr = pData; + hi2c->XferCount = Size; + hi2c->XferOptions = I2C_NO_OPTION_FRAME; + hi2c->XferISR = I2C_Master_ISR_IT; + + if (hi2c->XferCount > MAX_NBYTE_SIZE) + { + hi2c->XferSize = MAX_NBYTE_SIZE; + xfermode = I2C_RELOAD_MODE; + } + else + { + hi2c->XferSize = hi2c->XferCount; + xfermode = I2C_AUTOEND_MODE; + } + + /* Send Slave Address */ + /* Set NBYTES to write and reload if hi2c->XferCount > MAX_NBYTE_SIZE */ + I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, xfermode, I2C_GENERATE_START_WRITE); + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Note : The I2C interrupts must be enabled after unlocking current process + to avoid the risk of I2C interrupt handle execution before current + process unlock */ + + /* Enable ERR, TC, STOP, NACK, TXI interrupt */ + /* possible to enable all of these */ + /* I2C_IT_ERRI | I2C_IT_TCI| I2C_IT_STOPI| I2C_IT_NACKI | I2C_IT_ADDRI | I2C_IT_RXI | I2C_IT_TXI */ + I2C_Enable_IRQ(hi2c, I2C_XFER_TX_IT); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Receive in master mode an amount of data in non-blocking mode with Interrupt + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param DevAddress Target device address: The device 7 bits address value + * in datasheet must be shifted to the left before calling the interface + * @param pData Pointer to data buffer + * @param Size Amount of data to be sent + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Master_Receive_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size) +{ + uint32_t xfermode; + + if (hi2c->State == HAL_I2C_STATE_READY) + { + if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) == SET) + { + return HAL_BUSY; + } + + /* Process Locked */ + __HAL_LOCK(hi2c); + + hi2c->State = HAL_I2C_STATE_BUSY_RX; + hi2c->Mode = HAL_I2C_MODE_MASTER; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + /* Prepare transfer parameters */ + hi2c->pBuffPtr = pData; + hi2c->XferCount = Size; + hi2c->XferOptions = I2C_NO_OPTION_FRAME; + hi2c->XferISR = I2C_Master_ISR_IT; + + if (hi2c->XferCount > MAX_NBYTE_SIZE) + { + hi2c->XferSize = MAX_NBYTE_SIZE; + xfermode = I2C_RELOAD_MODE; + } + else + { + hi2c->XferSize = hi2c->XferCount; + xfermode = I2C_AUTOEND_MODE; + } + + /* Send Slave Address */ + /* Set NBYTES to write and reload if hi2c->XferCount > MAX_NBYTE_SIZE */ + I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, xfermode, I2C_GENERATE_START_READ); + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Note : The I2C interrupts must be enabled after unlocking current process + to avoid the risk of I2C interrupt handle execution before current + process unlock */ + + /* Enable ERR, TC, STOP, NACK, RXI interrupt */ + /* possible to enable all of these */ + /* I2C_IT_ERRI | I2C_IT_TCI| I2C_IT_STOPI| I2C_IT_NACKI | I2C_IT_ADDRI | I2C_IT_RXI | I2C_IT_TXI */ + I2C_Enable_IRQ(hi2c, I2C_XFER_RX_IT); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Transmit in slave mode an amount of data in non-blocking mode with Interrupt + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param pData Pointer to data buffer + * @param Size Amount of data to be sent + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Slave_Transmit_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size) +{ + if (hi2c->State == HAL_I2C_STATE_READY) + { + /* Process Locked */ + __HAL_LOCK(hi2c); + + hi2c->State = HAL_I2C_STATE_BUSY_TX; + hi2c->Mode = HAL_I2C_MODE_SLAVE; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + /* Enable Address Acknowledge */ + hi2c->Instance->CR2 &= ~I2C_CR2_NACK; + + /* Prepare transfer parameters */ + hi2c->pBuffPtr = pData; + hi2c->XferCount = Size; + hi2c->XferSize = hi2c->XferCount; + hi2c->XferOptions = I2C_NO_OPTION_FRAME; + hi2c->XferISR = I2C_Slave_ISR_IT; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Note : The I2C interrupts must be enabled after unlocking current process + to avoid the risk of I2C interrupt handle execution before current + process unlock */ + + /* Enable ERR, TC, STOP, NACK, TXI interrupt */ + /* possible to enable all of these */ + /* I2C_IT_ERRI | I2C_IT_TCI| I2C_IT_STOPI| I2C_IT_NACKI | I2C_IT_ADDRI | I2C_IT_RXI | I2C_IT_TXI */ + I2C_Enable_IRQ(hi2c, I2C_XFER_TX_IT | I2C_XFER_LISTEN_IT); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Receive in slave mode an amount of data in non-blocking mode with Interrupt + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param pData Pointer to data buffer + * @param Size Amount of data to be sent + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Slave_Receive_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size) +{ + if (hi2c->State == HAL_I2C_STATE_READY) + { + /* Process Locked */ + __HAL_LOCK(hi2c); + + hi2c->State = HAL_I2C_STATE_BUSY_RX; + hi2c->Mode = HAL_I2C_MODE_SLAVE; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + /* Enable Address Acknowledge */ + hi2c->Instance->CR2 &= ~I2C_CR2_NACK; + + /* Prepare transfer parameters */ + hi2c->pBuffPtr = pData; + hi2c->XferCount = Size; + hi2c->XferSize = hi2c->XferCount; + hi2c->XferOptions = I2C_NO_OPTION_FRAME; + hi2c->XferISR = I2C_Slave_ISR_IT; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Note : The I2C interrupts must be enabled after unlocking current process + to avoid the risk of I2C interrupt handle execution before current + process unlock */ + + /* Enable ERR, TC, STOP, NACK, RXI interrupt */ + /* possible to enable all of these */ + /* I2C_IT_ERRI | I2C_IT_TCI| I2C_IT_STOPI| I2C_IT_NACKI | I2C_IT_ADDRI | I2C_IT_RXI | I2C_IT_TXI */ + I2C_Enable_IRQ(hi2c, I2C_XFER_RX_IT | I2C_XFER_LISTEN_IT); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Transmit in master mode an amount of data in non-blocking mode with DMA + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param DevAddress Target device address: The device 7 bits address value + * in datasheet must be shifted to the left before calling the interface + * @param pData Pointer to data buffer + * @param Size Amount of data to be sent + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Master_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size) +{ + uint32_t xfermode; + HAL_StatusTypeDef dmaxferstatus; + + if (hi2c->State == HAL_I2C_STATE_READY) + { + if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) == SET) + { + return HAL_BUSY; + } + + /* Process Locked */ + __HAL_LOCK(hi2c); + + hi2c->State = HAL_I2C_STATE_BUSY_TX; + hi2c->Mode = HAL_I2C_MODE_MASTER; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + /* Prepare transfer parameters */ + hi2c->pBuffPtr = pData; + hi2c->XferCount = Size; + hi2c->XferOptions = I2C_NO_OPTION_FRAME; + hi2c->XferISR = I2C_Master_ISR_DMA; + + if (hi2c->XferCount > MAX_NBYTE_SIZE) + { + hi2c->XferSize = MAX_NBYTE_SIZE; + xfermode = I2C_RELOAD_MODE; + } + else + { + hi2c->XferSize = hi2c->XferCount; + xfermode = I2C_AUTOEND_MODE; + } + + if (hi2c->XferSize > 0U) + { + if (hi2c->hdmatx != NULL) + { + /* Set the I2C DMA transfer complete callback */ + hi2c->hdmatx->XferCpltCallback = I2C_DMAMasterTransmitCplt; + + /* Set the DMA error callback */ + hi2c->hdmatx->XferErrorCallback = I2C_DMAError; + + /* Set the unused DMA callbacks to NULL */ + hi2c->hdmatx->XferHalfCpltCallback = NULL; + hi2c->hdmatx->XferAbortCallback = NULL; + + /* Enable the DMA channel */ + dmaxferstatus = HAL_DMA_Start_IT(hi2c->hdmatx, (uint32_t)pData, (uint32_t)&hi2c->Instance->TXDR, hi2c->XferSize); + } + else + { + /* Update I2C state */ + hi2c->State = HAL_I2C_STATE_READY; + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Update I2C error code */ + hi2c->ErrorCode |= HAL_I2C_ERROR_DMA_PARAM; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_ERROR; + } + + if (dmaxferstatus == HAL_OK) + { + /* Send Slave Address */ + /* Set NBYTES to write and reload if hi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */ + I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, xfermode, I2C_GENERATE_START_WRITE); + + /* Update XferCount value */ + hi2c->XferCount -= hi2c->XferSize; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Note : The I2C interrupts must be enabled after unlocking current process + to avoid the risk of I2C interrupt handle execution before current + process unlock */ + /* Enable ERR and NACK interrupts */ + I2C_Enable_IRQ(hi2c, I2C_XFER_ERROR_IT); + + /* Enable DMA Request */ + hi2c->Instance->CR1 |= I2C_CR1_TXDMAEN; + } + else + { + /* Update I2C state */ + hi2c->State = HAL_I2C_STATE_READY; + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Update I2C error code */ + hi2c->ErrorCode |= HAL_I2C_ERROR_DMA; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_ERROR; + } + } + else + { + /* Update Transfer ISR function pointer */ + hi2c->XferISR = I2C_Master_ISR_IT; + + /* Send Slave Address */ + /* Set NBYTES to write and generate START condition */ + I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_AUTOEND_MODE, I2C_GENERATE_START_WRITE); + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Note : The I2C interrupts must be enabled after unlocking current process + to avoid the risk of I2C interrupt handle execution before current + process unlock */ + /* Enable ERR, TC, STOP, NACK, TXI interrupt */ + /* possible to enable all of these */ + /* I2C_IT_ERRI | I2C_IT_TCI| I2C_IT_STOPI| I2C_IT_NACKI | I2C_IT_ADDRI | I2C_IT_RXI | I2C_IT_TXI */ + I2C_Enable_IRQ(hi2c, I2C_XFER_TX_IT); + } + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Receive in master mode an amount of data in non-blocking mode with DMA + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param DevAddress Target device address: The device 7 bits address value + * in datasheet must be shifted to the left before calling the interface + * @param pData Pointer to data buffer + * @param Size Amount of data to be sent + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Master_Receive_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size) +{ + uint32_t xfermode; + HAL_StatusTypeDef dmaxferstatus; + + if (hi2c->State == HAL_I2C_STATE_READY) + { + if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) == SET) + { + return HAL_BUSY; + } + + /* Process Locked */ + __HAL_LOCK(hi2c); + + hi2c->State = HAL_I2C_STATE_BUSY_RX; + hi2c->Mode = HAL_I2C_MODE_MASTER; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + /* Prepare transfer parameters */ + hi2c->pBuffPtr = pData; + hi2c->XferCount = Size; + hi2c->XferOptions = I2C_NO_OPTION_FRAME; + hi2c->XferISR = I2C_Master_ISR_DMA; + + if (hi2c->XferCount > MAX_NBYTE_SIZE) + { + hi2c->XferSize = MAX_NBYTE_SIZE; + xfermode = I2C_RELOAD_MODE; + } + else + { + hi2c->XferSize = hi2c->XferCount; + xfermode = I2C_AUTOEND_MODE; + } + + if (hi2c->XferSize > 0U) + { + if (hi2c->hdmarx != NULL) + { + /* Set the I2C DMA transfer complete callback */ + hi2c->hdmarx->XferCpltCallback = I2C_DMAMasterReceiveCplt; + + /* Set the DMA error callback */ + hi2c->hdmarx->XferErrorCallback = I2C_DMAError; + + /* Set the unused DMA callbacks to NULL */ + hi2c->hdmarx->XferHalfCpltCallback = NULL; + hi2c->hdmarx->XferAbortCallback = NULL; + + /* Enable the DMA channel */ + dmaxferstatus = HAL_DMA_Start_IT(hi2c->hdmarx, (uint32_t)&hi2c->Instance->RXDR, (uint32_t)pData, hi2c->XferSize); + } + else + { + /* Update I2C state */ + hi2c->State = HAL_I2C_STATE_READY; + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Update I2C error code */ + hi2c->ErrorCode |= HAL_I2C_ERROR_DMA_PARAM; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_ERROR; + } + + if (dmaxferstatus == HAL_OK) + { + /* Send Slave Address */ + /* Set NBYTES to read and reload if hi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */ + I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, xfermode, I2C_GENERATE_START_READ); + + /* Update XferCount value */ + hi2c->XferCount -= hi2c->XferSize; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Note : The I2C interrupts must be enabled after unlocking current process + to avoid the risk of I2C interrupt handle execution before current + process unlock */ + /* Enable ERR and NACK interrupts */ + I2C_Enable_IRQ(hi2c, I2C_XFER_ERROR_IT); + + /* Enable DMA Request */ + hi2c->Instance->CR1 |= I2C_CR1_RXDMAEN; + } + else + { + /* Update I2C state */ + hi2c->State = HAL_I2C_STATE_READY; + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Update I2C error code */ + hi2c->ErrorCode |= HAL_I2C_ERROR_DMA; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_ERROR; + } + } + else + { + /* Update Transfer ISR function pointer */ + hi2c->XferISR = I2C_Master_ISR_IT; + + /* Send Slave Address */ + /* Set NBYTES to read and generate START condition */ + I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_AUTOEND_MODE, I2C_GENERATE_START_READ); + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Note : The I2C interrupts must be enabled after unlocking current process + to avoid the risk of I2C interrupt handle execution before current + process unlock */ + /* Enable ERR, TC, STOP, NACK, TXI interrupt */ + /* possible to enable all of these */ + /* I2C_IT_ERRI | I2C_IT_TCI| I2C_IT_STOPI| I2C_IT_NACKI | I2C_IT_ADDRI | I2C_IT_RXI | I2C_IT_TXI */ + I2C_Enable_IRQ(hi2c, I2C_XFER_TX_IT); + } + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Transmit in slave mode an amount of data in non-blocking mode with DMA + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param pData Pointer to data buffer + * @param Size Amount of data to be sent + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Slave_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size) +{ + HAL_StatusTypeDef dmaxferstatus; + + if (hi2c->State == HAL_I2C_STATE_READY) + { + if ((pData == NULL) || (Size == 0U)) + { + hi2c->ErrorCode = HAL_I2C_ERROR_INVALID_PARAM; + return HAL_ERROR; + } + /* Process Locked */ + __HAL_LOCK(hi2c); + + hi2c->State = HAL_I2C_STATE_BUSY_TX; + hi2c->Mode = HAL_I2C_MODE_SLAVE; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + /* Prepare transfer parameters */ + hi2c->pBuffPtr = pData; + hi2c->XferCount = Size; + hi2c->XferSize = hi2c->XferCount; + hi2c->XferOptions = I2C_NO_OPTION_FRAME; + hi2c->XferISR = I2C_Slave_ISR_DMA; + + if (hi2c->hdmatx != NULL) + { + /* Set the I2C DMA transfer complete callback */ + hi2c->hdmatx->XferCpltCallback = I2C_DMASlaveTransmitCplt; + + /* Set the DMA error callback */ + hi2c->hdmatx->XferErrorCallback = I2C_DMAError; + + /* Set the unused DMA callbacks to NULL */ + hi2c->hdmatx->XferHalfCpltCallback = NULL; + hi2c->hdmatx->XferAbortCallback = NULL; + + /* Enable the DMA channel */ + dmaxferstatus = HAL_DMA_Start_IT(hi2c->hdmatx, (uint32_t)pData, (uint32_t)&hi2c->Instance->TXDR, hi2c->XferSize); + } + else + { + /* Update I2C state */ + hi2c->State = HAL_I2C_STATE_LISTEN; + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Update I2C error code */ + hi2c->ErrorCode |= HAL_I2C_ERROR_DMA_PARAM; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_ERROR; + } + + if (dmaxferstatus == HAL_OK) + { + /* Enable Address Acknowledge */ + hi2c->Instance->CR2 &= ~I2C_CR2_NACK; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Note : The I2C interrupts must be enabled after unlocking current process + to avoid the risk of I2C interrupt handle execution before current + process unlock */ + /* Enable ERR, STOP, NACK, ADDR interrupts */ + I2C_Enable_IRQ(hi2c, I2C_XFER_LISTEN_IT); + + /* Enable DMA Request */ + hi2c->Instance->CR1 |= I2C_CR1_TXDMAEN; + } + else + { + /* Update I2C state */ + hi2c->State = HAL_I2C_STATE_LISTEN; + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Update I2C error code */ + hi2c->ErrorCode |= HAL_I2C_ERROR_DMA; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_ERROR; + } + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Receive in slave mode an amount of data in non-blocking mode with DMA + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param pData Pointer to data buffer + * @param Size Amount of data to be sent + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Slave_Receive_DMA(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size) +{ + HAL_StatusTypeDef dmaxferstatus; + + if (hi2c->State == HAL_I2C_STATE_READY) + { + if ((pData == NULL) || (Size == 0U)) + { + hi2c->ErrorCode = HAL_I2C_ERROR_INVALID_PARAM; + return HAL_ERROR; + } + /* Process Locked */ + __HAL_LOCK(hi2c); + + hi2c->State = HAL_I2C_STATE_BUSY_RX; + hi2c->Mode = HAL_I2C_MODE_SLAVE; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + /* Prepare transfer parameters */ + hi2c->pBuffPtr = pData; + hi2c->XferCount = Size; + hi2c->XferSize = hi2c->XferCount; + hi2c->XferOptions = I2C_NO_OPTION_FRAME; + hi2c->XferISR = I2C_Slave_ISR_DMA; + + if (hi2c->hdmarx != NULL) + { + /* Set the I2C DMA transfer complete callback */ + hi2c->hdmarx->XferCpltCallback = I2C_DMASlaveReceiveCplt; + + /* Set the DMA error callback */ + hi2c->hdmarx->XferErrorCallback = I2C_DMAError; + + /* Set the unused DMA callbacks to NULL */ + hi2c->hdmarx->XferHalfCpltCallback = NULL; + hi2c->hdmarx->XferAbortCallback = NULL; + + /* Enable the DMA channel */ + dmaxferstatus = HAL_DMA_Start_IT(hi2c->hdmarx, (uint32_t)&hi2c->Instance->RXDR, (uint32_t)pData, hi2c->XferSize); + } + else + { + /* Update I2C state */ + hi2c->State = HAL_I2C_STATE_LISTEN; + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Update I2C error code */ + hi2c->ErrorCode |= HAL_I2C_ERROR_DMA_PARAM; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_ERROR; + } + + if (dmaxferstatus == HAL_OK) + { + /* Enable Address Acknowledge */ + hi2c->Instance->CR2 &= ~I2C_CR2_NACK; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Note : The I2C interrupts must be enabled after unlocking current process + to avoid the risk of I2C interrupt handle execution before current + process unlock */ + /* Enable ERR, STOP, NACK, ADDR interrupts */ + I2C_Enable_IRQ(hi2c, I2C_XFER_LISTEN_IT); + + /* Enable DMA Request */ + hi2c->Instance->CR1 |= I2C_CR1_RXDMAEN; + } + else + { + /* Update I2C state */ + hi2c->State = HAL_I2C_STATE_LISTEN; + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Update I2C error code */ + hi2c->ErrorCode |= HAL_I2C_ERROR_DMA; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_ERROR; + } + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} +/** + * @brief Write an amount of data in blocking mode to a specific memory address + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param DevAddress Target device address: The device 7 bits address value + * in datasheet must be shifted to the left before calling the interface + * @param MemAddress Internal memory address + * @param MemAddSize Size of internal memory address + * @param pData Pointer to data buffer + * @param Size Amount of data to be sent + * @param Timeout Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Mem_Write(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout) +{ + uint32_t tickstart; + + /* Check the parameters */ + assert_param(IS_I2C_MEMADD_SIZE(MemAddSize)); + + if (hi2c->State == HAL_I2C_STATE_READY) + { + if ((pData == NULL) || (Size == 0U)) + { + hi2c->ErrorCode = HAL_I2C_ERROR_INVALID_PARAM; + return HAL_ERROR; + } + + /* Process Locked */ + __HAL_LOCK(hi2c); + + /* Init tickstart for timeout management*/ + tickstart = HAL_GetTick(); + + if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY, tickstart) != HAL_OK) + { + return HAL_ERROR; + } + + hi2c->State = HAL_I2C_STATE_BUSY_TX; + hi2c->Mode = HAL_I2C_MODE_MEM; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + /* Prepare transfer parameters */ + hi2c->pBuffPtr = pData; + hi2c->XferCount = Size; + hi2c->XferISR = NULL; + + /* Send Slave Address and Memory Address */ + if (I2C_RequestMemoryWrite(hi2c, DevAddress, MemAddress, MemAddSize, Timeout, tickstart) != HAL_OK) + { + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + return HAL_ERROR; + } + + /* Set NBYTES to write and reload if hi2c->XferCount > MAX_NBYTE_SIZE */ + if (hi2c->XferCount > MAX_NBYTE_SIZE) + { + hi2c->XferSize = MAX_NBYTE_SIZE; + I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_RELOAD_MODE, I2C_NO_STARTSTOP); + } + else + { + hi2c->XferSize = hi2c->XferCount; + I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_AUTOEND_MODE, I2C_NO_STARTSTOP); + } + + do + { + /* Wait until TXIS flag is set */ + if (I2C_WaitOnTXISFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) + { + return HAL_ERROR; + } + + /* Write data to TXDR */ + hi2c->Instance->TXDR = *hi2c->pBuffPtr; + + /* Increment Buffer pointer */ + hi2c->pBuffPtr++; + + hi2c->XferCount--; + hi2c->XferSize--; + + if ((hi2c->XferCount != 0U) && (hi2c->XferSize == 0U)) + { + /* Wait until TCR flag is set */ + if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_TCR, RESET, Timeout, tickstart) != HAL_OK) + { + return HAL_ERROR; + } + + if (hi2c->XferCount > MAX_NBYTE_SIZE) + { + hi2c->XferSize = MAX_NBYTE_SIZE; + I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_RELOAD_MODE, I2C_NO_STARTSTOP); + } + else + { + hi2c->XferSize = hi2c->XferCount; + I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_AUTOEND_MODE, I2C_NO_STARTSTOP); + } + } + + } + while (hi2c->XferCount > 0U); + + /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */ + /* Wait until STOPF flag is reset */ + if (I2C_WaitOnSTOPFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) + { + return HAL_ERROR; + } + + /* Clear STOP Flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF); + + /* Clear Configuration Register 2 */ + I2C_RESET_CR2(hi2c); + + hi2c->State = HAL_I2C_STATE_READY; + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Read an amount of data in blocking mode from a specific memory address + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param DevAddress Target device address: The device 7 bits address value + * in datasheet must be shifted to the left before calling the interface + * @param MemAddress Internal memory address + * @param MemAddSize Size of internal memory address + * @param pData Pointer to data buffer + * @param Size Amount of data to be sent + * @param Timeout Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Mem_Read(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout) +{ + uint32_t tickstart; + + /* Check the parameters */ + assert_param(IS_I2C_MEMADD_SIZE(MemAddSize)); + + if (hi2c->State == HAL_I2C_STATE_READY) + { + if ((pData == NULL) || (Size == 0U)) + { + hi2c->ErrorCode = HAL_I2C_ERROR_INVALID_PARAM; + return HAL_ERROR; + } + + /* Process Locked */ + __HAL_LOCK(hi2c); + + /* Init tickstart for timeout management*/ + tickstart = HAL_GetTick(); + + if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY, tickstart) != HAL_OK) + { + return HAL_ERROR; + } + + hi2c->State = HAL_I2C_STATE_BUSY_RX; + hi2c->Mode = HAL_I2C_MODE_MEM; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + /* Prepare transfer parameters */ + hi2c->pBuffPtr = pData; + hi2c->XferCount = Size; + hi2c->XferISR = NULL; + + /* Send Slave Address and Memory Address */ + if (I2C_RequestMemoryRead(hi2c, DevAddress, MemAddress, MemAddSize, Timeout, tickstart) != HAL_OK) + { + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + return HAL_ERROR; + } + + /* Send Slave Address */ + /* Set NBYTES to write and reload if hi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */ + if (hi2c->XferCount > MAX_NBYTE_SIZE) + { + hi2c->XferSize = MAX_NBYTE_SIZE; + I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_RELOAD_MODE, I2C_GENERATE_START_READ); + } + else + { + hi2c->XferSize = hi2c->XferCount; + I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_AUTOEND_MODE, I2C_GENERATE_START_READ); + } + + do + { + /* Wait until RXNE flag is set */ + if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_RXNE, RESET, Timeout, tickstart) != HAL_OK) + { + return HAL_ERROR; + } + + /* Read data from RXDR */ + *hi2c->pBuffPtr = (uint8_t)hi2c->Instance->RXDR; + + /* Increment Buffer pointer */ + hi2c->pBuffPtr++; + + hi2c->XferSize--; + hi2c->XferCount--; + + if ((hi2c->XferCount != 0U) && (hi2c->XferSize == 0U)) + { + /* Wait until TCR flag is set */ + if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_TCR, RESET, Timeout, tickstart) != HAL_OK) + { + return HAL_ERROR; + } + + if (hi2c->XferCount > MAX_NBYTE_SIZE) + { + hi2c->XferSize = MAX_NBYTE_SIZE; + I2C_TransferConfig(hi2c, DevAddress, (uint8_t) hi2c->XferSize, I2C_RELOAD_MODE, I2C_NO_STARTSTOP); + } + else + { + hi2c->XferSize = hi2c->XferCount; + I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_AUTOEND_MODE, I2C_NO_STARTSTOP); + } + } + } + while (hi2c->XferCount > 0U); + + /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */ + /* Wait until STOPF flag is reset */ + if (I2C_WaitOnSTOPFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) + { + return HAL_ERROR; + } + + /* Clear STOP Flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF); + + /* Clear Configuration Register 2 */ + I2C_RESET_CR2(hi2c); + + hi2c->State = HAL_I2C_STATE_READY; + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} +/** + * @brief Write an amount of data in non-blocking mode with Interrupt to a specific memory address + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param DevAddress Target device address: The device 7 bits address value + * in datasheet must be shifted to the left before calling the interface + * @param MemAddress Internal memory address + * @param MemAddSize Size of internal memory address + * @param pData Pointer to data buffer + * @param Size Amount of data to be sent + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Mem_Write_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size) +{ + uint32_t tickstart; + uint32_t xfermode; + + /* Check the parameters */ + assert_param(IS_I2C_MEMADD_SIZE(MemAddSize)); + + if (hi2c->State == HAL_I2C_STATE_READY) + { + if ((pData == NULL) || (Size == 0U)) + { + hi2c->ErrorCode = HAL_I2C_ERROR_INVALID_PARAM; + return HAL_ERROR; + } + + if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) == SET) + { + return HAL_BUSY; + } + + /* Process Locked */ + __HAL_LOCK(hi2c); + + /* Init tickstart for timeout management*/ + tickstart = HAL_GetTick(); + + hi2c->State = HAL_I2C_STATE_BUSY_TX; + hi2c->Mode = HAL_I2C_MODE_MEM; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + /* Prepare transfer parameters */ + hi2c->pBuffPtr = pData; + hi2c->XferCount = Size; + hi2c->XferOptions = I2C_NO_OPTION_FRAME; + hi2c->XferISR = I2C_Master_ISR_IT; + + if (hi2c->XferCount > MAX_NBYTE_SIZE) + { + hi2c->XferSize = MAX_NBYTE_SIZE; + xfermode = I2C_RELOAD_MODE; + } + else + { + hi2c->XferSize = hi2c->XferCount; + xfermode = I2C_AUTOEND_MODE; + } + + /* Send Slave Address and Memory Address */ + if (I2C_RequestMemoryWrite(hi2c, DevAddress, MemAddress, MemAddSize, I2C_TIMEOUT_FLAG, tickstart) != HAL_OK) + { + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + return HAL_ERROR; + } + + /* Set NBYTES to write and reload if hi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */ + I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, xfermode, I2C_NO_STARTSTOP); + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Note : The I2C interrupts must be enabled after unlocking current process + to avoid the risk of I2C interrupt handle execution before current + process unlock */ + + /* Enable ERR, TC, STOP, NACK, TXI interrupt */ + /* possible to enable all of these */ + /* I2C_IT_ERRI | I2C_IT_TCI| I2C_IT_STOPI| I2C_IT_NACKI | I2C_IT_ADDRI | I2C_IT_RXI | I2C_IT_TXI */ + I2C_Enable_IRQ(hi2c, I2C_XFER_TX_IT); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Read an amount of data in non-blocking mode with Interrupt from a specific memory address + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param DevAddress Target device address: The device 7 bits address value + * in datasheet must be shifted to the left before calling the interface + * @param MemAddress Internal memory address + * @param MemAddSize Size of internal memory address + * @param pData Pointer to data buffer + * @param Size Amount of data to be sent + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Mem_Read_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size) +{ + uint32_t tickstart; + uint32_t xfermode; + + /* Check the parameters */ + assert_param(IS_I2C_MEMADD_SIZE(MemAddSize)); + + if (hi2c->State == HAL_I2C_STATE_READY) + { + if ((pData == NULL) || (Size == 0U)) + { + hi2c->ErrorCode = HAL_I2C_ERROR_INVALID_PARAM; + return HAL_ERROR; + } + + if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) == SET) + { + return HAL_BUSY; + } + + /* Process Locked */ + __HAL_LOCK(hi2c); + + /* Init tickstart for timeout management*/ + tickstart = HAL_GetTick(); + + hi2c->State = HAL_I2C_STATE_BUSY_RX; + hi2c->Mode = HAL_I2C_MODE_MEM; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + /* Prepare transfer parameters */ + hi2c->pBuffPtr = pData; + hi2c->XferCount = Size; + hi2c->XferOptions = I2C_NO_OPTION_FRAME; + hi2c->XferISR = I2C_Master_ISR_IT; + + if (hi2c->XferCount > MAX_NBYTE_SIZE) + { + hi2c->XferSize = MAX_NBYTE_SIZE; + xfermode = I2C_RELOAD_MODE; + } + else + { + hi2c->XferSize = hi2c->XferCount; + xfermode = I2C_AUTOEND_MODE; + } + + /* Send Slave Address and Memory Address */ + if (I2C_RequestMemoryRead(hi2c, DevAddress, MemAddress, MemAddSize, I2C_TIMEOUT_FLAG, tickstart) != HAL_OK) + { + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + return HAL_ERROR; + } + + /* Set NBYTES to write and reload if hi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */ + I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, xfermode, I2C_GENERATE_START_READ); + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Note : The I2C interrupts must be enabled after unlocking current process + to avoid the risk of I2C interrupt handle execution before current + process unlock */ + + /* Enable ERR, TC, STOP, NACK, RXI interrupt */ + /* possible to enable all of these */ + /* I2C_IT_ERRI | I2C_IT_TCI| I2C_IT_STOPI| I2C_IT_NACKI | I2C_IT_ADDRI | I2C_IT_RXI | I2C_IT_TXI */ + I2C_Enable_IRQ(hi2c, I2C_XFER_RX_IT); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} +/** + * @brief Write an amount of data in non-blocking mode with DMA to a specific memory address + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param DevAddress Target device address: The device 7 bits address value + * in datasheet must be shifted to the left before calling the interface + * @param MemAddress Internal memory address + * @param MemAddSize Size of internal memory address + * @param pData Pointer to data buffer + * @param Size Amount of data to be sent + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Mem_Write_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size) +{ + uint32_t tickstart; + uint32_t xfermode; + HAL_StatusTypeDef dmaxferstatus; + + /* Check the parameters */ + assert_param(IS_I2C_MEMADD_SIZE(MemAddSize)); + + if (hi2c->State == HAL_I2C_STATE_READY) + { + if ((pData == NULL) || (Size == 0U)) + { + hi2c->ErrorCode = HAL_I2C_ERROR_INVALID_PARAM; + return HAL_ERROR; + } + + if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) == SET) + { + return HAL_BUSY; + } + + /* Process Locked */ + __HAL_LOCK(hi2c); + + /* Init tickstart for timeout management*/ + tickstart = HAL_GetTick(); + + hi2c->State = HAL_I2C_STATE_BUSY_TX; + hi2c->Mode = HAL_I2C_MODE_MEM; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + /* Prepare transfer parameters */ + hi2c->pBuffPtr = pData; + hi2c->XferCount = Size; + hi2c->XferOptions = I2C_NO_OPTION_FRAME; + hi2c->XferISR = I2C_Master_ISR_DMA; + + if (hi2c->XferCount > MAX_NBYTE_SIZE) + { + hi2c->XferSize = MAX_NBYTE_SIZE; + xfermode = I2C_RELOAD_MODE; + } + else + { + hi2c->XferSize = hi2c->XferCount; + xfermode = I2C_AUTOEND_MODE; + } + + /* Send Slave Address and Memory Address */ + if (I2C_RequestMemoryWrite(hi2c, DevAddress, MemAddress, MemAddSize, I2C_TIMEOUT_FLAG, tickstart) != HAL_OK) + { + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + return HAL_ERROR; + } + + + if (hi2c->hdmatx != NULL) + { + /* Set the I2C DMA transfer complete callback */ + hi2c->hdmatx->XferCpltCallback = I2C_DMAMasterTransmitCplt; + + /* Set the DMA error callback */ + hi2c->hdmatx->XferErrorCallback = I2C_DMAError; + + /* Set the unused DMA callbacks to NULL */ + hi2c->hdmatx->XferHalfCpltCallback = NULL; + hi2c->hdmatx->XferAbortCallback = NULL; + + /* Enable the DMA channel */ + dmaxferstatus = HAL_DMA_Start_IT(hi2c->hdmatx, (uint32_t)pData, (uint32_t)&hi2c->Instance->TXDR, hi2c->XferSize); + } + else + { + /* Update I2C state */ + hi2c->State = HAL_I2C_STATE_READY; + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Update I2C error code */ + hi2c->ErrorCode |= HAL_I2C_ERROR_DMA_PARAM; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_ERROR; + } + + if (dmaxferstatus == HAL_OK) + { + /* Send Slave Address */ + /* Set NBYTES to write and reload if hi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */ + I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, xfermode, I2C_NO_STARTSTOP); + + /* Update XferCount value */ + hi2c->XferCount -= hi2c->XferSize; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Note : The I2C interrupts must be enabled after unlocking current process + to avoid the risk of I2C interrupt handle execution before current + process unlock */ + /* Enable ERR and NACK interrupts */ + I2C_Enable_IRQ(hi2c, I2C_XFER_ERROR_IT); + + /* Enable DMA Request */ + hi2c->Instance->CR1 |= I2C_CR1_TXDMAEN; + } + else + { + /* Update I2C state */ + hi2c->State = HAL_I2C_STATE_READY; + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Update I2C error code */ + hi2c->ErrorCode |= HAL_I2C_ERROR_DMA; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_ERROR; + } + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Reads an amount of data in non-blocking mode with DMA from a specific memory address. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param DevAddress Target device address: The device 7 bits address value + * in datasheet must be shifted to the left before calling the interface + * @param MemAddress Internal memory address + * @param MemAddSize Size of internal memory address + * @param pData Pointer to data buffer + * @param Size Amount of data to be read + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Mem_Read_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size) +{ + uint32_t tickstart; + uint32_t xfermode; + HAL_StatusTypeDef dmaxferstatus; + + /* Check the parameters */ + assert_param(IS_I2C_MEMADD_SIZE(MemAddSize)); + + if (hi2c->State == HAL_I2C_STATE_READY) + { + if ((pData == NULL) || (Size == 0U)) + { + hi2c->ErrorCode = HAL_I2C_ERROR_INVALID_PARAM; + return HAL_ERROR; + } + + if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) == SET) + { + return HAL_BUSY; + } + + /* Process Locked */ + __HAL_LOCK(hi2c); + + /* Init tickstart for timeout management*/ + tickstart = HAL_GetTick(); + + hi2c->State = HAL_I2C_STATE_BUSY_RX; + hi2c->Mode = HAL_I2C_MODE_MEM; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + /* Prepare transfer parameters */ + hi2c->pBuffPtr = pData; + hi2c->XferCount = Size; + hi2c->XferOptions = I2C_NO_OPTION_FRAME; + hi2c->XferISR = I2C_Master_ISR_DMA; + + if (hi2c->XferCount > MAX_NBYTE_SIZE) + { + hi2c->XferSize = MAX_NBYTE_SIZE; + xfermode = I2C_RELOAD_MODE; + } + else + { + hi2c->XferSize = hi2c->XferCount; + xfermode = I2C_AUTOEND_MODE; + } + + /* Send Slave Address and Memory Address */ + if (I2C_RequestMemoryRead(hi2c, DevAddress, MemAddress, MemAddSize, I2C_TIMEOUT_FLAG, tickstart) != HAL_OK) + { + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + return HAL_ERROR; + } + + if (hi2c->hdmarx != NULL) + { + /* Set the I2C DMA transfer complete callback */ + hi2c->hdmarx->XferCpltCallback = I2C_DMAMasterReceiveCplt; + + /* Set the DMA error callback */ + hi2c->hdmarx->XferErrorCallback = I2C_DMAError; + + /* Set the unused DMA callbacks to NULL */ + hi2c->hdmarx->XferHalfCpltCallback = NULL; + hi2c->hdmarx->XferAbortCallback = NULL; + + /* Enable the DMA channel */ + dmaxferstatus = HAL_DMA_Start_IT(hi2c->hdmarx, (uint32_t)&hi2c->Instance->RXDR, (uint32_t)pData, hi2c->XferSize); + } + else + { + /* Update I2C state */ + hi2c->State = HAL_I2C_STATE_READY; + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Update I2C error code */ + hi2c->ErrorCode |= HAL_I2C_ERROR_DMA_PARAM; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_ERROR; + } + + if (dmaxferstatus == HAL_OK) + { + /* Set NBYTES to write and reload if hi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */ + I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, xfermode, I2C_GENERATE_START_READ); + + /* Update XferCount value */ + hi2c->XferCount -= hi2c->XferSize; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Note : The I2C interrupts must be enabled after unlocking current process + to avoid the risk of I2C interrupt handle execution before current + process unlock */ + /* Enable ERR and NACK interrupts */ + I2C_Enable_IRQ(hi2c, I2C_XFER_ERROR_IT); + + /* Enable DMA Request */ + hi2c->Instance->CR1 |= I2C_CR1_RXDMAEN; + } + else + { + /* Update I2C state */ + hi2c->State = HAL_I2C_STATE_READY; + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Update I2C error code */ + hi2c->ErrorCode |= HAL_I2C_ERROR_DMA; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_ERROR; + } + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Checks if target device is ready for communication. + * @note This function is used with Memory devices + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param DevAddress Target device address: The device 7 bits address value + * in datasheet must be shifted to the left before calling the interface + * @param Trials Number of trials + * @param Timeout Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_IsDeviceReady(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint32_t Trials, uint32_t Timeout) +{ + uint32_t tickstart; + + __IO uint32_t I2C_Trials = 0UL; + + FlagStatus tmp1; + FlagStatus tmp2; + + if (hi2c->State == HAL_I2C_STATE_READY) + { + if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) == SET) + { + return HAL_BUSY; + } + + /* Process Locked */ + __HAL_LOCK(hi2c); + + hi2c->State = HAL_I2C_STATE_BUSY; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + do + { + /* Generate Start */ + hi2c->Instance->CR2 = I2C_GENERATE_START(hi2c->Init.AddressingMode, DevAddress); + + /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */ + /* Wait until STOPF flag is set or a NACK flag is set*/ + tickstart = HAL_GetTick(); + + tmp1 = __HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_STOPF); + tmp2 = __HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_AF); + + while ((tmp1 == RESET) && (tmp2 == RESET)) + { + if (Timeout != HAL_MAX_DELAY) + { + if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U)) + { + /* Update I2C state */ + hi2c->State = HAL_I2C_STATE_READY; + + /* Update I2C error code */ + hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_ERROR; + } + } + + tmp1 = __HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_STOPF); + tmp2 = __HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_AF); + } + + /* Check if the NACKF flag has not been set */ + if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_AF) == RESET) + { + /* Wait until STOPF flag is reset */ + if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_STOPF, RESET, Timeout, tickstart) != HAL_OK) + { + return HAL_ERROR; + } + + /* Clear STOP Flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF); + + /* Device is ready */ + hi2c->State = HAL_I2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_OK; + } + else + { + /* Wait until STOPF flag is reset */ + if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_STOPF, RESET, Timeout, tickstart) != HAL_OK) + { + return HAL_ERROR; + } + + /* Clear NACK Flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF); + + /* Clear STOP Flag, auto generated with autoend*/ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF); + } + + /* Check if the maximum allowed number of trials has been reached */ + if (I2C_Trials == Trials) + { + /* Generate Stop */ + hi2c->Instance->CR2 |= I2C_CR2_STOP; + + /* Wait until STOPF flag is reset */ + if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_STOPF, RESET, Timeout, tickstart) != HAL_OK) + { + return HAL_ERROR; + } + + /* Clear STOP Flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF); + } + + /* Increment Trials */ + I2C_Trials++; + } + while (I2C_Trials < Trials); + + /* Update I2C state */ + hi2c->State = HAL_I2C_STATE_READY; + + /* Update I2C error code */ + hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_ERROR; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Sequential transmit in master I2C mode an amount of data in non-blocking mode with Interrupt. + * @note This interface allow to manage repeated start condition when a direction change during transfer + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param DevAddress Target device address: The device 7 bits address value + * in datasheet must be shifted to the left before calling the interface + * @param pData Pointer to data buffer + * @param Size Amount of data to be sent + * @param XferOptions Options of Transfer, value of @ref I2C_XFEROPTIONS + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Master_Seq_Transmit_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t XferOptions) +{ + uint32_t xfermode; + uint32_t xferrequest = I2C_GENERATE_START_WRITE; + + /* Check the parameters */ + assert_param(IS_I2C_TRANSFER_OPTIONS_REQUEST(XferOptions)); + + if (hi2c->State == HAL_I2C_STATE_READY) + { + /* Process Locked */ + __HAL_LOCK(hi2c); + + hi2c->State = HAL_I2C_STATE_BUSY_TX; + hi2c->Mode = HAL_I2C_MODE_MASTER; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + /* Prepare transfer parameters */ + hi2c->pBuffPtr = pData; + hi2c->XferCount = Size; + hi2c->XferOptions = XferOptions; + hi2c->XferISR = I2C_Master_ISR_IT; + + /* If hi2c->XferCount > MAX_NBYTE_SIZE, use reload mode */ + if (hi2c->XferCount > MAX_NBYTE_SIZE) + { + hi2c->XferSize = MAX_NBYTE_SIZE; + xfermode = I2C_RELOAD_MODE; + } + else + { + hi2c->XferSize = hi2c->XferCount; + xfermode = hi2c->XferOptions; + } + + /* If transfer direction not change and there is no request to start another frame, do not generate Restart Condition */ + /* Mean Previous state is same as current state */ + if ((hi2c->PreviousState == I2C_STATE_MASTER_BUSY_TX) && (IS_I2C_TRANSFER_OTHER_OPTIONS_REQUEST(XferOptions) == 0)) + { + xferrequest = I2C_NO_STARTSTOP; + } + else + { + /* Convert OTHER_xxx XferOptions if any */ + I2C_ConvertOtherXferOptions(hi2c); + + /* Update xfermode accordingly if no reload is necessary */ + if (hi2c->XferCount < MAX_NBYTE_SIZE) + { + xfermode = hi2c->XferOptions; + } + } + + /* Send Slave Address and set NBYTES to write */ + I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, xfermode, xferrequest); + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Note : The I2C interrupts must be enabled after unlocking current process + to avoid the risk of I2C interrupt handle execution before current + process unlock */ + I2C_Enable_IRQ(hi2c, I2C_XFER_TX_IT); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Sequential transmit in master I2C mode an amount of data in non-blocking mode with DMA. + * @note This interface allow to manage repeated start condition when a direction change during transfer + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param DevAddress Target device address: The device 7 bits address value + * in datasheet must be shifted to the left before calling the interface + * @param pData Pointer to data buffer + * @param Size Amount of data to be sent + * @param XferOptions Options of Transfer, value of @ref I2C_XFEROPTIONS + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Master_Seq_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t XferOptions) +{ + uint32_t xfermode; + uint32_t xferrequest = I2C_GENERATE_START_WRITE; + HAL_StatusTypeDef dmaxferstatus; + + /* Check the parameters */ + assert_param(IS_I2C_TRANSFER_OPTIONS_REQUEST(XferOptions)); + + if (hi2c->State == HAL_I2C_STATE_READY) + { + /* Process Locked */ + __HAL_LOCK(hi2c); + + hi2c->State = HAL_I2C_STATE_BUSY_TX; + hi2c->Mode = HAL_I2C_MODE_MASTER; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + /* Prepare transfer parameters */ + hi2c->pBuffPtr = pData; + hi2c->XferCount = Size; + hi2c->XferOptions = XferOptions; + hi2c->XferISR = I2C_Master_ISR_DMA; + + /* If hi2c->XferCount > MAX_NBYTE_SIZE, use reload mode */ + if (hi2c->XferCount > MAX_NBYTE_SIZE) + { + hi2c->XferSize = MAX_NBYTE_SIZE; + xfermode = I2C_RELOAD_MODE; + } + else + { + hi2c->XferSize = hi2c->XferCount; + xfermode = hi2c->XferOptions; + } + + /* If transfer direction not change and there is no request to start another frame, do not generate Restart Condition */ + /* Mean Previous state is same as current state */ + if ((hi2c->PreviousState == I2C_STATE_MASTER_BUSY_TX) && (IS_I2C_TRANSFER_OTHER_OPTIONS_REQUEST(XferOptions) == 0)) + { + xferrequest = I2C_NO_STARTSTOP; + } + else + { + /* Convert OTHER_xxx XferOptions if any */ + I2C_ConvertOtherXferOptions(hi2c); + + /* Update xfermode accordingly if no reload is necessary */ + if (hi2c->XferCount < MAX_NBYTE_SIZE) + { + xfermode = hi2c->XferOptions; + } + } + + if (hi2c->XferSize > 0U) + { + if (hi2c->hdmatx != NULL) + { + /* Set the I2C DMA transfer complete callback */ + hi2c->hdmatx->XferCpltCallback = I2C_DMAMasterTransmitCplt; + + /* Set the DMA error callback */ + hi2c->hdmatx->XferErrorCallback = I2C_DMAError; + + /* Set the unused DMA callbacks to NULL */ + hi2c->hdmatx->XferHalfCpltCallback = NULL; + hi2c->hdmatx->XferAbortCallback = NULL; + + /* Enable the DMA channel */ + dmaxferstatus = HAL_DMA_Start_IT(hi2c->hdmatx, (uint32_t)pData, (uint32_t)&hi2c->Instance->TXDR, hi2c->XferSize); + } + else + { + /* Update I2C state */ + hi2c->State = HAL_I2C_STATE_READY; + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Update I2C error code */ + hi2c->ErrorCode |= HAL_I2C_ERROR_DMA_PARAM; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_ERROR; + } + + if (dmaxferstatus == HAL_OK) + { + /* Send Slave Address and set NBYTES to write */ + I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, xfermode, xferrequest); + + /* Update XferCount value */ + hi2c->XferCount -= hi2c->XferSize; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Note : The I2C interrupts must be enabled after unlocking current process + to avoid the risk of I2C interrupt handle execution before current + process unlock */ + /* Enable ERR and NACK interrupts */ + I2C_Enable_IRQ(hi2c, I2C_XFER_ERROR_IT); + + /* Enable DMA Request */ + hi2c->Instance->CR1 |= I2C_CR1_TXDMAEN; + } + else + { + /* Update I2C state */ + hi2c->State = HAL_I2C_STATE_READY; + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Update I2C error code */ + hi2c->ErrorCode |= HAL_I2C_ERROR_DMA; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_ERROR; + } + } + else + { + /* Update Transfer ISR function pointer */ + hi2c->XferISR = I2C_Master_ISR_IT; + + /* Send Slave Address */ + /* Set NBYTES to write and generate START condition */ + I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_AUTOEND_MODE, I2C_GENERATE_START_WRITE); + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Note : The I2C interrupts must be enabled after unlocking current process + to avoid the risk of I2C interrupt handle execution before current + process unlock */ + /* Enable ERR, TC, STOP, NACK, TXI interrupt */ + /* possible to enable all of these */ + /* I2C_IT_ERRI | I2C_IT_TCI| I2C_IT_STOPI| I2C_IT_NACKI | I2C_IT_ADDRI | I2C_IT_RXI | I2C_IT_TXI */ + I2C_Enable_IRQ(hi2c, I2C_XFER_TX_IT); + } + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Sequential receive in master I2C mode an amount of data in non-blocking mode with Interrupt + * @note This interface allow to manage repeated start condition when a direction change during transfer + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param DevAddress Target device address: The device 7 bits address value + * in datasheet must be shifted to the left before calling the interface + * @param pData Pointer to data buffer + * @param Size Amount of data to be sent + * @param XferOptions Options of Transfer, value of @ref I2C_XFEROPTIONS + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Master_Seq_Receive_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t XferOptions) +{ + uint32_t xfermode; + uint32_t xferrequest = I2C_GENERATE_START_READ; + + /* Check the parameters */ + assert_param(IS_I2C_TRANSFER_OPTIONS_REQUEST(XferOptions)); + + if (hi2c->State == HAL_I2C_STATE_READY) + { + /* Process Locked */ + __HAL_LOCK(hi2c); + + hi2c->State = HAL_I2C_STATE_BUSY_RX; + hi2c->Mode = HAL_I2C_MODE_MASTER; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + /* Prepare transfer parameters */ + hi2c->pBuffPtr = pData; + hi2c->XferCount = Size; + hi2c->XferOptions = XferOptions; + hi2c->XferISR = I2C_Master_ISR_IT; + + /* If hi2c->XferCount > MAX_NBYTE_SIZE, use reload mode */ + if (hi2c->XferCount > MAX_NBYTE_SIZE) + { + hi2c->XferSize = MAX_NBYTE_SIZE; + xfermode = I2C_RELOAD_MODE; + } + else + { + hi2c->XferSize = hi2c->XferCount; + xfermode = hi2c->XferOptions; + } + + /* If transfer direction not change and there is no request to start another frame, do not generate Restart Condition */ + /* Mean Previous state is same as current state */ + if ((hi2c->PreviousState == I2C_STATE_MASTER_BUSY_RX) && (IS_I2C_TRANSFER_OTHER_OPTIONS_REQUEST(XferOptions) == 0)) + { + xferrequest = I2C_NO_STARTSTOP; + } + else + { + /* Convert OTHER_xxx XferOptions if any */ + I2C_ConvertOtherXferOptions(hi2c); + + /* Update xfermode accordingly if no reload is necessary */ + if (hi2c->XferCount < MAX_NBYTE_SIZE) + { + xfermode = hi2c->XferOptions; + } + } + + /* Send Slave Address and set NBYTES to read */ + I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, xfermode, xferrequest); + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Note : The I2C interrupts must be enabled after unlocking current process + to avoid the risk of I2C interrupt handle execution before current + process unlock */ + I2C_Enable_IRQ(hi2c, I2C_XFER_RX_IT); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Sequential receive in master I2C mode an amount of data in non-blocking mode with DMA + * @note This interface allow to manage repeated start condition when a direction change during transfer + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param DevAddress Target device address: The device 7 bits address value + * in datasheet must be shifted to the left before calling the interface + * @param pData Pointer to data buffer + * @param Size Amount of data to be sent + * @param XferOptions Options of Transfer, value of @ref I2C_XFEROPTIONS + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Master_Seq_Receive_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t XferOptions) +{ + uint32_t xfermode; + uint32_t xferrequest = I2C_GENERATE_START_READ; + HAL_StatusTypeDef dmaxferstatus; + + /* Check the parameters */ + assert_param(IS_I2C_TRANSFER_OPTIONS_REQUEST(XferOptions)); + + if (hi2c->State == HAL_I2C_STATE_READY) + { + /* Process Locked */ + __HAL_LOCK(hi2c); + + hi2c->State = HAL_I2C_STATE_BUSY_RX; + hi2c->Mode = HAL_I2C_MODE_MASTER; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + /* Prepare transfer parameters */ + hi2c->pBuffPtr = pData; + hi2c->XferCount = Size; + hi2c->XferOptions = XferOptions; + hi2c->XferISR = I2C_Master_ISR_DMA; + + /* If hi2c->XferCount > MAX_NBYTE_SIZE, use reload mode */ + if (hi2c->XferCount > MAX_NBYTE_SIZE) + { + hi2c->XferSize = MAX_NBYTE_SIZE; + xfermode = I2C_RELOAD_MODE; + } + else + { + hi2c->XferSize = hi2c->XferCount; + xfermode = hi2c->XferOptions; + } + + /* If transfer direction not change and there is no request to start another frame, do not generate Restart Condition */ + /* Mean Previous state is same as current state */ + if ((hi2c->PreviousState == I2C_STATE_MASTER_BUSY_RX) && (IS_I2C_TRANSFER_OTHER_OPTIONS_REQUEST(XferOptions) == 0)) + { + xferrequest = I2C_NO_STARTSTOP; + } + else + { + /* Convert OTHER_xxx XferOptions if any */ + I2C_ConvertOtherXferOptions(hi2c); + + /* Update xfermode accordingly if no reload is necessary */ + if (hi2c->XferCount < MAX_NBYTE_SIZE) + { + xfermode = hi2c->XferOptions; + } + } + + if (hi2c->XferSize > 0U) + { + if (hi2c->hdmarx != NULL) + { + /* Set the I2C DMA transfer complete callback */ + hi2c->hdmarx->XferCpltCallback = I2C_DMAMasterReceiveCplt; + + /* Set the DMA error callback */ + hi2c->hdmarx->XferErrorCallback = I2C_DMAError; + + /* Set the unused DMA callbacks to NULL */ + hi2c->hdmarx->XferHalfCpltCallback = NULL; + hi2c->hdmarx->XferAbortCallback = NULL; + + /* Enable the DMA channel */ + dmaxferstatus = HAL_DMA_Start_IT(hi2c->hdmarx, (uint32_t)&hi2c->Instance->RXDR, (uint32_t)pData, hi2c->XferSize); + } + else + { + /* Update I2C state */ + hi2c->State = HAL_I2C_STATE_READY; + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Update I2C error code */ + hi2c->ErrorCode |= HAL_I2C_ERROR_DMA_PARAM; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_ERROR; + } + + if (dmaxferstatus == HAL_OK) + { + /* Send Slave Address and set NBYTES to read */ + I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, xfermode, xferrequest); + + /* Update XferCount value */ + hi2c->XferCount -= hi2c->XferSize; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Note : The I2C interrupts must be enabled after unlocking current process + to avoid the risk of I2C interrupt handle execution before current + process unlock */ + /* Enable ERR and NACK interrupts */ + I2C_Enable_IRQ(hi2c, I2C_XFER_ERROR_IT); + + /* Enable DMA Request */ + hi2c->Instance->CR1 |= I2C_CR1_RXDMAEN; + } + else + { + /* Update I2C state */ + hi2c->State = HAL_I2C_STATE_READY; + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Update I2C error code */ + hi2c->ErrorCode |= HAL_I2C_ERROR_DMA; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_ERROR; + } + } + else + { + /* Update Transfer ISR function pointer */ + hi2c->XferISR = I2C_Master_ISR_IT; + + /* Send Slave Address */ + /* Set NBYTES to read and generate START condition */ + I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_AUTOEND_MODE, I2C_GENERATE_START_READ); + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Note : The I2C interrupts must be enabled after unlocking current process + to avoid the risk of I2C interrupt handle execution before current + process unlock */ + /* Enable ERR, TC, STOP, NACK, TXI interrupt */ + /* possible to enable all of these */ + /* I2C_IT_ERRI | I2C_IT_TCI| I2C_IT_STOPI| I2C_IT_NACKI | I2C_IT_ADDRI | I2C_IT_RXI | I2C_IT_TXI */ + I2C_Enable_IRQ(hi2c, I2C_XFER_TX_IT); + } + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Sequential transmit in slave/device I2C mode an amount of data in non-blocking mode with Interrupt + * @note This interface allow to manage repeated start condition when a direction change during transfer + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param pData Pointer to data buffer + * @param Size Amount of data to be sent + * @param XferOptions Options of Transfer, value of @ref I2C_XFEROPTIONS + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Slave_Seq_Transmit_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t XferOptions) +{ + /* Check the parameters */ + assert_param(IS_I2C_TRANSFER_OPTIONS_REQUEST(XferOptions)); + + if (((uint32_t)hi2c->State & (uint32_t)HAL_I2C_STATE_LISTEN) == (uint32_t)HAL_I2C_STATE_LISTEN) + { + if ((pData == NULL) || (Size == 0U)) + { + hi2c->ErrorCode = HAL_I2C_ERROR_INVALID_PARAM; + return HAL_ERROR; + } + + /* Disable Interrupts, to prevent preemption during treatment in case of multicall */ + I2C_Disable_IRQ(hi2c, I2C_XFER_LISTEN_IT | I2C_XFER_TX_IT); + + /* Process Locked */ + __HAL_LOCK(hi2c); + + /* I2C cannot manage full duplex exchange so disable previous IT enabled if any */ + /* and then toggle the HAL slave RX state to TX state */ + if (hi2c->State == HAL_I2C_STATE_BUSY_RX_LISTEN) + { + /* Disable associated Interrupts */ + I2C_Disable_IRQ(hi2c, I2C_XFER_RX_IT); + + /* Abort DMA Xfer if any */ + if ((hi2c->Instance->CR1 & I2C_CR1_RXDMAEN) == I2C_CR1_RXDMAEN) + { + hi2c->Instance->CR1 &= ~I2C_CR1_RXDMAEN; + + if (hi2c->hdmarx != NULL) + { + /* Set the I2C DMA Abort callback : + will lead to call HAL_I2C_ErrorCallback() at end of DMA abort procedure */ + hi2c->hdmarx->XferAbortCallback = I2C_DMAAbort; + + /* Abort DMA RX */ + if (HAL_DMA_Abort_IT(hi2c->hdmarx) != HAL_OK) + { + /* Call Directly XferAbortCallback function in case of error */ + hi2c->hdmarx->XferAbortCallback(hi2c->hdmarx); + } + } + } + } + + hi2c->State = HAL_I2C_STATE_BUSY_TX_LISTEN; + hi2c->Mode = HAL_I2C_MODE_SLAVE; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + /* Enable Address Acknowledge */ + hi2c->Instance->CR2 &= ~I2C_CR2_NACK; + + /* Prepare transfer parameters */ + hi2c->pBuffPtr = pData; + hi2c->XferCount = Size; + hi2c->XferSize = hi2c->XferCount; + hi2c->XferOptions = XferOptions; + hi2c->XferISR = I2C_Slave_ISR_IT; + + if (I2C_GET_DIR(hi2c) == I2C_DIRECTION_RECEIVE) + { + /* Clear ADDR flag after prepare the transfer parameters */ + /* This action will generate an acknowledge to the Master */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_ADDR); + } + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Note : The I2C interrupts must be enabled after unlocking current process + to avoid the risk of I2C interrupt handle execution before current + process unlock */ + /* REnable ADDR interrupt */ + I2C_Enable_IRQ(hi2c, I2C_XFER_TX_IT | I2C_XFER_LISTEN_IT); + + return HAL_OK; + } + else + { + return HAL_ERROR; + } +} + +/** + * @brief Sequential transmit in slave/device I2C mode an amount of data in non-blocking mode with DMA + * @note This interface allow to manage repeated start condition when a direction change during transfer + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param pData Pointer to data buffer + * @param Size Amount of data to be sent + * @param XferOptions Options of Transfer, value of @ref I2C_XFEROPTIONS + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Slave_Seq_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t XferOptions) +{ + HAL_StatusTypeDef dmaxferstatus; + + /* Check the parameters */ + assert_param(IS_I2C_TRANSFER_OPTIONS_REQUEST(XferOptions)); + + if (((uint32_t)hi2c->State & (uint32_t)HAL_I2C_STATE_LISTEN) == (uint32_t)HAL_I2C_STATE_LISTEN) + { + if ((pData == NULL) || (Size == 0U)) + { + hi2c->ErrorCode = HAL_I2C_ERROR_INVALID_PARAM; + return HAL_ERROR; + } + + /* Process Locked */ + __HAL_LOCK(hi2c); + + /* Disable Interrupts, to prevent preemption during treatment in case of multicall */ + I2C_Disable_IRQ(hi2c, I2C_XFER_LISTEN_IT | I2C_XFER_TX_IT); + + /* I2C cannot manage full duplex exchange so disable previous IT enabled if any */ + /* and then toggle the HAL slave RX state to TX state */ + if (hi2c->State == HAL_I2C_STATE_BUSY_RX_LISTEN) + { + /* Disable associated Interrupts */ + I2C_Disable_IRQ(hi2c, I2C_XFER_RX_IT); + + if ((hi2c->Instance->CR1 & I2C_CR1_RXDMAEN) == I2C_CR1_RXDMAEN) + { + /* Abort DMA Xfer if any */ + if (hi2c->hdmarx != NULL) + { + hi2c->Instance->CR1 &= ~I2C_CR1_RXDMAEN; + + /* Set the I2C DMA Abort callback : + will lead to call HAL_I2C_ErrorCallback() at end of DMA abort procedure */ + hi2c->hdmarx->XferAbortCallback = I2C_DMAAbort; + + /* Abort DMA RX */ + if (HAL_DMA_Abort_IT(hi2c->hdmarx) != HAL_OK) + { + /* Call Directly XferAbortCallback function in case of error */ + hi2c->hdmarx->XferAbortCallback(hi2c->hdmarx); + } + } + } + } + else if (hi2c->State == HAL_I2C_STATE_BUSY_TX_LISTEN) + { + if ((hi2c->Instance->CR1 & I2C_CR1_TXDMAEN) == I2C_CR1_TXDMAEN) + { + hi2c->Instance->CR1 &= ~I2C_CR1_TXDMAEN; + + /* Abort DMA Xfer if any */ + if (hi2c->hdmatx != NULL) + { + /* Set the I2C DMA Abort callback : + will lead to call HAL_I2C_ErrorCallback() at end of DMA abort procedure */ + hi2c->hdmatx->XferAbortCallback = I2C_DMAAbort; + + /* Abort DMA TX */ + if (HAL_DMA_Abort_IT(hi2c->hdmatx) != HAL_OK) + { + /* Call Directly XferAbortCallback function in case of error */ + hi2c->hdmatx->XferAbortCallback(hi2c->hdmatx); + } + } + } + } + else + { + /* Nothing to do */ + } + + hi2c->State = HAL_I2C_STATE_BUSY_TX_LISTEN; + hi2c->Mode = HAL_I2C_MODE_SLAVE; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + /* Enable Address Acknowledge */ + hi2c->Instance->CR2 &= ~I2C_CR2_NACK; + + /* Prepare transfer parameters */ + hi2c->pBuffPtr = pData; + hi2c->XferCount = Size; + hi2c->XferSize = hi2c->XferCount; + hi2c->XferOptions = XferOptions; + hi2c->XferISR = I2C_Slave_ISR_DMA; + + if (hi2c->hdmatx != NULL) + { + /* Set the I2C DMA transfer complete callback */ + hi2c->hdmatx->XferCpltCallback = I2C_DMASlaveTransmitCplt; + + /* Set the DMA error callback */ + hi2c->hdmatx->XferErrorCallback = I2C_DMAError; + + /* Set the unused DMA callbacks to NULL */ + hi2c->hdmatx->XferHalfCpltCallback = NULL; + hi2c->hdmatx->XferAbortCallback = NULL; + + /* Enable the DMA channel */ + dmaxferstatus = HAL_DMA_Start_IT(hi2c->hdmatx, (uint32_t)pData, (uint32_t)&hi2c->Instance->TXDR, hi2c->XferSize); + } + else + { + /* Update I2C state */ + hi2c->State = HAL_I2C_STATE_LISTEN; + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Update I2C error code */ + hi2c->ErrorCode |= HAL_I2C_ERROR_DMA_PARAM; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_ERROR; + } + + if (dmaxferstatus == HAL_OK) + { + /* Update XferCount value */ + hi2c->XferCount -= hi2c->XferSize; + + /* Reset XferSize */ + hi2c->XferSize = 0; + } + else + { + /* Update I2C state */ + hi2c->State = HAL_I2C_STATE_LISTEN; + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Update I2C error code */ + hi2c->ErrorCode |= HAL_I2C_ERROR_DMA; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_ERROR; + } + + if (I2C_GET_DIR(hi2c) == I2C_DIRECTION_RECEIVE) + { + /* Clear ADDR flag after prepare the transfer parameters */ + /* This action will generate an acknowledge to the Master */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_ADDR); + } + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Note : The I2C interrupts must be enabled after unlocking current process + to avoid the risk of I2C interrupt handle execution before current + process unlock */ + /* Enable ERR, STOP, NACK, ADDR interrupts */ + I2C_Enable_IRQ(hi2c, I2C_XFER_LISTEN_IT); + + /* Enable DMA Request */ + hi2c->Instance->CR1 |= I2C_CR1_TXDMAEN; + + return HAL_OK; + } + else + { + return HAL_ERROR; + } +} + +/** + * @brief Sequential receive in slave/device I2C mode an amount of data in non-blocking mode with Interrupt + * @note This interface allow to manage repeated start condition when a direction change during transfer + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param pData Pointer to data buffer + * @param Size Amount of data to be sent + * @param XferOptions Options of Transfer, value of @ref I2C_XFEROPTIONS + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Slave_Seq_Receive_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t XferOptions) +{ + /* Check the parameters */ + assert_param(IS_I2C_TRANSFER_OPTIONS_REQUEST(XferOptions)); + + if (((uint32_t)hi2c->State & (uint32_t)HAL_I2C_STATE_LISTEN) == (uint32_t)HAL_I2C_STATE_LISTEN) + { + if ((pData == NULL) || (Size == 0U)) + { + hi2c->ErrorCode = HAL_I2C_ERROR_INVALID_PARAM; + return HAL_ERROR; + } + + /* Disable Interrupts, to prevent preemption during treatment in case of multicall */ + I2C_Disable_IRQ(hi2c, I2C_XFER_LISTEN_IT | I2C_XFER_RX_IT); + + /* Process Locked */ + __HAL_LOCK(hi2c); + + /* I2C cannot manage full duplex exchange so disable previous IT enabled if any */ + /* and then toggle the HAL slave TX state to RX state */ + if (hi2c->State == HAL_I2C_STATE_BUSY_TX_LISTEN) + { + /* Disable associated Interrupts */ + I2C_Disable_IRQ(hi2c, I2C_XFER_TX_IT); + + if ((hi2c->Instance->CR1 & I2C_CR1_TXDMAEN) == I2C_CR1_TXDMAEN) + { + hi2c->Instance->CR1 &= ~I2C_CR1_TXDMAEN; + + /* Abort DMA Xfer if any */ + if (hi2c->hdmatx != NULL) + { + /* Set the I2C DMA Abort callback : + will lead to call HAL_I2C_ErrorCallback() at end of DMA abort procedure */ + hi2c->hdmatx->XferAbortCallback = I2C_DMAAbort; + + /* Abort DMA TX */ + if (HAL_DMA_Abort_IT(hi2c->hdmatx) != HAL_OK) + { + /* Call Directly XferAbortCallback function in case of error */ + hi2c->hdmatx->XferAbortCallback(hi2c->hdmatx); + } + } + } + } + + hi2c->State = HAL_I2C_STATE_BUSY_RX_LISTEN; + hi2c->Mode = HAL_I2C_MODE_SLAVE; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + /* Enable Address Acknowledge */ + hi2c->Instance->CR2 &= ~I2C_CR2_NACK; + + /* Prepare transfer parameters */ + hi2c->pBuffPtr = pData; + hi2c->XferCount = Size; + hi2c->XferSize = hi2c->XferCount; + hi2c->XferOptions = XferOptions; + hi2c->XferISR = I2C_Slave_ISR_IT; + + if (I2C_GET_DIR(hi2c) == I2C_DIRECTION_TRANSMIT) + { + /* Clear ADDR flag after prepare the transfer parameters */ + /* This action will generate an acknowledge to the Master */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_ADDR); + } + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Note : The I2C interrupts must be enabled after unlocking current process + to avoid the risk of I2C interrupt handle execution before current + process unlock */ + /* REnable ADDR interrupt */ + I2C_Enable_IRQ(hi2c, I2C_XFER_RX_IT | I2C_XFER_LISTEN_IT); + + return HAL_OK; + } + else + { + return HAL_ERROR; + } +} + +/** + * @brief Sequential receive in slave/device I2C mode an amount of data in non-blocking mode with DMA + * @note This interface allow to manage repeated start condition when a direction change during transfer + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param pData Pointer to data buffer + * @param Size Amount of data to be sent + * @param XferOptions Options of Transfer, value of @ref I2C_XFEROPTIONS + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Slave_Seq_Receive_DMA(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t XferOptions) +{ + HAL_StatusTypeDef dmaxferstatus; + + /* Check the parameters */ + assert_param(IS_I2C_TRANSFER_OPTIONS_REQUEST(XferOptions)); + + if (((uint32_t)hi2c->State & (uint32_t)HAL_I2C_STATE_LISTEN) == (uint32_t)HAL_I2C_STATE_LISTEN) + { + if ((pData == NULL) || (Size == 0U)) + { + hi2c->ErrorCode = HAL_I2C_ERROR_INVALID_PARAM; + return HAL_ERROR; + } + + /* Disable Interrupts, to prevent preemption during treatment in case of multicall */ + I2C_Disable_IRQ(hi2c, I2C_XFER_LISTEN_IT | I2C_XFER_RX_IT); + + /* Process Locked */ + __HAL_LOCK(hi2c); + + /* I2C cannot manage full duplex exchange so disable previous IT enabled if any */ + /* and then toggle the HAL slave TX state to RX state */ + if (hi2c->State == HAL_I2C_STATE_BUSY_TX_LISTEN) + { + /* Disable associated Interrupts */ + I2C_Disable_IRQ(hi2c, I2C_XFER_TX_IT); + + if ((hi2c->Instance->CR1 & I2C_CR1_TXDMAEN) == I2C_CR1_TXDMAEN) + { + /* Abort DMA Xfer if any */ + if (hi2c->hdmatx != NULL) + { + hi2c->Instance->CR1 &= ~I2C_CR1_TXDMAEN; + + /* Set the I2C DMA Abort callback : + will lead to call HAL_I2C_ErrorCallback() at end of DMA abort procedure */ + hi2c->hdmatx->XferAbortCallback = I2C_DMAAbort; + + /* Abort DMA TX */ + if (HAL_DMA_Abort_IT(hi2c->hdmatx) != HAL_OK) + { + /* Call Directly XferAbortCallback function in case of error */ + hi2c->hdmatx->XferAbortCallback(hi2c->hdmatx); + } + } + } + } + else if (hi2c->State == HAL_I2C_STATE_BUSY_RX_LISTEN) + { + if ((hi2c->Instance->CR1 & I2C_CR1_RXDMAEN) == I2C_CR1_RXDMAEN) + { + hi2c->Instance->CR1 &= ~I2C_CR1_RXDMAEN; + + /* Abort DMA Xfer if any */ + if (hi2c->hdmarx != NULL) + { + /* Set the I2C DMA Abort callback : + will lead to call HAL_I2C_ErrorCallback() at end of DMA abort procedure */ + hi2c->hdmarx->XferAbortCallback = I2C_DMAAbort; + + /* Abort DMA RX */ + if (HAL_DMA_Abort_IT(hi2c->hdmarx) != HAL_OK) + { + /* Call Directly XferAbortCallback function in case of error */ + hi2c->hdmarx->XferAbortCallback(hi2c->hdmarx); + } + } + } + } + else + { + /* Nothing to do */ + } + + hi2c->State = HAL_I2C_STATE_BUSY_RX_LISTEN; + hi2c->Mode = HAL_I2C_MODE_SLAVE; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + /* Enable Address Acknowledge */ + hi2c->Instance->CR2 &= ~I2C_CR2_NACK; + + /* Prepare transfer parameters */ + hi2c->pBuffPtr = pData; + hi2c->XferCount = Size; + hi2c->XferSize = hi2c->XferCount; + hi2c->XferOptions = XferOptions; + hi2c->XferISR = I2C_Slave_ISR_DMA; + + if (hi2c->hdmarx != NULL) + { + /* Set the I2C DMA transfer complete callback */ + hi2c->hdmarx->XferCpltCallback = I2C_DMASlaveReceiveCplt; + + /* Set the DMA error callback */ + hi2c->hdmarx->XferErrorCallback = I2C_DMAError; + + /* Set the unused DMA callbacks to NULL */ + hi2c->hdmarx->XferHalfCpltCallback = NULL; + hi2c->hdmarx->XferAbortCallback = NULL; + + /* Enable the DMA channel */ + dmaxferstatus = HAL_DMA_Start_IT(hi2c->hdmarx, (uint32_t)&hi2c->Instance->RXDR, (uint32_t)pData, hi2c->XferSize); + } + else + { + /* Update I2C state */ + hi2c->State = HAL_I2C_STATE_LISTEN; + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Update I2C error code */ + hi2c->ErrorCode |= HAL_I2C_ERROR_DMA_PARAM; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_ERROR; + } + + if (dmaxferstatus == HAL_OK) + { + /* Update XferCount value */ + hi2c->XferCount -= hi2c->XferSize; + + /* Reset XferSize */ + hi2c->XferSize = 0; + } + else + { + /* Update I2C state */ + hi2c->State = HAL_I2C_STATE_LISTEN; + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Update I2C error code */ + hi2c->ErrorCode |= HAL_I2C_ERROR_DMA; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_ERROR; + } + + if (I2C_GET_DIR(hi2c) == I2C_DIRECTION_TRANSMIT) + { + /* Clear ADDR flag after prepare the transfer parameters */ + /* This action will generate an acknowledge to the Master */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_ADDR); + } + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Note : The I2C interrupts must be enabled after unlocking current process + to avoid the risk of I2C interrupt handle execution before current + process unlock */ + /* REnable ADDR interrupt */ + I2C_Enable_IRQ(hi2c, I2C_XFER_RX_IT | I2C_XFER_LISTEN_IT); + + /* Enable DMA Request */ + hi2c->Instance->CR1 |= I2C_CR1_RXDMAEN; + + return HAL_OK; + } + else + { + return HAL_ERROR; + } +} + +/** + * @brief Enable the Address listen mode with Interrupt. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_EnableListen_IT(I2C_HandleTypeDef *hi2c) +{ + if (hi2c->State == HAL_I2C_STATE_READY) + { + hi2c->State = HAL_I2C_STATE_LISTEN; + hi2c->XferISR = I2C_Slave_ISR_IT; + + /* Enable the Address Match interrupt */ + I2C_Enable_IRQ(hi2c, I2C_XFER_LISTEN_IT); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Disable the Address listen mode with Interrupt. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_DisableListen_IT(I2C_HandleTypeDef *hi2c) +{ + /* Declaration of tmp to prevent undefined behavior of volatile usage */ + uint32_t tmp; + + /* Disable Address listen mode only if a transfer is not ongoing */ + if (hi2c->State == HAL_I2C_STATE_LISTEN) + { + tmp = (uint32_t)(hi2c->State) & I2C_STATE_MSK; + hi2c->PreviousState = tmp | (uint32_t)(hi2c->Mode); + hi2c->State = HAL_I2C_STATE_READY; + hi2c->Mode = HAL_I2C_MODE_NONE; + hi2c->XferISR = NULL; + + /* Disable the Address Match interrupt */ + I2C_Disable_IRQ(hi2c, I2C_XFER_LISTEN_IT); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Abort a master I2C IT or DMA process communication with Interrupt. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param DevAddress Target device address: The device 7 bits address value + * in datasheet must be shifted to the left before calling the interface + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Master_Abort_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress) +{ + if (hi2c->Mode == HAL_I2C_MODE_MASTER) + { + /* Process Locked */ + __HAL_LOCK(hi2c); + + /* Disable Interrupts */ + I2C_Disable_IRQ(hi2c, I2C_XFER_RX_IT); + I2C_Disable_IRQ(hi2c, I2C_XFER_TX_IT); + + /* Set State at HAL_I2C_STATE_ABORT */ + hi2c->State = HAL_I2C_STATE_ABORT; + + /* Set NBYTES to 1 to generate a dummy read on I2C peripheral */ + /* Set AUTOEND mode, this will generate a NACK then STOP condition to abort the current transfer */ + I2C_TransferConfig(hi2c, DevAddress, 1, I2C_AUTOEND_MODE, I2C_GENERATE_STOP); + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Note : The I2C interrupts must be enabled after unlocking current process + to avoid the risk of I2C interrupt handle execution before current + process unlock */ + I2C_Enable_IRQ(hi2c, I2C_XFER_CPLT_IT); + + return HAL_OK; + } + else + { + /* Wrong usage of abort function */ + /* This function should be used only in case of abort monitored by master device */ + return HAL_ERROR; + } +} + +/** + * @} + */ + +/** @defgroup I2C_IRQ_Handler_and_Callbacks IRQ Handler and Callbacks + * @{ + */ + +/** + * @brief This function handles I2C event interrupt request. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @retval None + */ +void HAL_I2C_EV_IRQHandler(I2C_HandleTypeDef *hi2c) +{ + /* Get current IT Flags and IT sources value */ + uint32_t itflags = READ_REG(hi2c->Instance->ISR); + uint32_t itsources = READ_REG(hi2c->Instance->CR1); + + /* I2C events treatment -------------------------------------*/ + if (hi2c->XferISR != NULL) + { + hi2c->XferISR(hi2c, itflags, itsources); + } +} + +/** + * @brief This function handles I2C error interrupt request. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @retval None + */ +void HAL_I2C_ER_IRQHandler(I2C_HandleTypeDef *hi2c) +{ + uint32_t itflags = READ_REG(hi2c->Instance->ISR); + uint32_t itsources = READ_REG(hi2c->Instance->CR1); + uint32_t tmperror; + + /* I2C Bus error interrupt occurred ------------------------------------*/ + if ((I2C_CHECK_FLAG(itflags, I2C_FLAG_BERR) != RESET) && (I2C_CHECK_IT_SOURCE(itsources, I2C_IT_ERRI) != RESET)) + { + hi2c->ErrorCode |= HAL_I2C_ERROR_BERR; + + /* Clear BERR flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_BERR); + } + + /* I2C Over-Run/Under-Run interrupt occurred ----------------------------------------*/ + if ((I2C_CHECK_FLAG(itflags, I2C_FLAG_OVR) != RESET) && (I2C_CHECK_IT_SOURCE(itsources, I2C_IT_ERRI) != RESET)) + { + hi2c->ErrorCode |= HAL_I2C_ERROR_OVR; + + /* Clear OVR flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_OVR); + } + + /* I2C Arbitration Loss error interrupt occurred -------------------------------------*/ + if ((I2C_CHECK_FLAG(itflags, I2C_FLAG_ARLO) != RESET) && (I2C_CHECK_IT_SOURCE(itsources, I2C_IT_ERRI) != RESET)) + { + hi2c->ErrorCode |= HAL_I2C_ERROR_ARLO; + + /* Clear ARLO flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_ARLO); + } + + /* Store current volatile hi2c->ErrorCode, misra rule */ + tmperror = hi2c->ErrorCode; + + /* Call the Error Callback in case of Error detected */ + if ((tmperror & (HAL_I2C_ERROR_BERR | HAL_I2C_ERROR_OVR | HAL_I2C_ERROR_ARLO)) != HAL_I2C_ERROR_NONE) + { + I2C_ITError(hi2c, tmperror); + } +} + +/** + * @brief Master Tx Transfer completed callback. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @retval None + */ +__weak void HAL_I2C_MasterTxCpltCallback(I2C_HandleTypeDef *hi2c) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hi2c); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_I2C_MasterTxCpltCallback could be implemented in the user file + */ +} + +/** + * @brief Master Rx Transfer completed callback. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @retval None + */ +__weak void HAL_I2C_MasterRxCpltCallback(I2C_HandleTypeDef *hi2c) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hi2c); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_I2C_MasterRxCpltCallback could be implemented in the user file + */ +} + +/** @brief Slave Tx Transfer completed callback. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @retval None + */ +__weak void HAL_I2C_SlaveTxCpltCallback(I2C_HandleTypeDef *hi2c) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hi2c); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_I2C_SlaveTxCpltCallback could be implemented in the user file + */ +} + +/** + * @brief Slave Rx Transfer completed callback. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @retval None + */ +__weak void HAL_I2C_SlaveRxCpltCallback(I2C_HandleTypeDef *hi2c) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hi2c); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_I2C_SlaveRxCpltCallback could be implemented in the user file + */ +} + +/** + * @brief Slave Address Match callback. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param TransferDirection Master request Transfer Direction (Write/Read), value of @ref I2C_XFERDIRECTION + * @param AddrMatchCode Address Match Code + * @retval None + */ +__weak void HAL_I2C_AddrCallback(I2C_HandleTypeDef *hi2c, uint8_t TransferDirection, uint16_t AddrMatchCode) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hi2c); + UNUSED(TransferDirection); + UNUSED(AddrMatchCode); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_I2C_AddrCallback() could be implemented in the user file + */ +} + +/** + * @brief Listen Complete callback. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @retval None + */ +__weak void HAL_I2C_ListenCpltCallback(I2C_HandleTypeDef *hi2c) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hi2c); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_I2C_ListenCpltCallback() could be implemented in the user file + */ +} + +/** + * @brief Memory Tx Transfer completed callback. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @retval None + */ +__weak void HAL_I2C_MemTxCpltCallback(I2C_HandleTypeDef *hi2c) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hi2c); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_I2C_MemTxCpltCallback could be implemented in the user file + */ +} + +/** + * @brief Memory Rx Transfer completed callback. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @retval None + */ +__weak void HAL_I2C_MemRxCpltCallback(I2C_HandleTypeDef *hi2c) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hi2c); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_I2C_MemRxCpltCallback could be implemented in the user file + */ +} + +/** + * @brief I2C error callback. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @retval None + */ +__weak void HAL_I2C_ErrorCallback(I2C_HandleTypeDef *hi2c) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hi2c); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_I2C_ErrorCallback could be implemented in the user file + */ +} + +/** + * @brief I2C abort callback. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @retval None + */ +__weak void HAL_I2C_AbortCpltCallback(I2C_HandleTypeDef *hi2c) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hi2c); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_I2C_AbortCpltCallback could be implemented in the user file + */ +} + +/** + * @} + */ + +/** @defgroup I2C_Exported_Functions_Group3 Peripheral State, Mode and Error functions + * @brief Peripheral State, Mode and Error functions + * +@verbatim + =============================================================================== + ##### Peripheral State, Mode and Error functions ##### + =============================================================================== + [..] + This subsection permit to get in run-time the status of the peripheral + and the data flow. + +@endverbatim + * @{ + */ + +/** + * @brief Return the I2C handle state. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @retval HAL state + */ +HAL_I2C_StateTypeDef HAL_I2C_GetState(I2C_HandleTypeDef *hi2c) +{ + /* Return I2C handle state */ + return hi2c->State; +} + +/** + * @brief Returns the I2C Master, Slave, Memory or no mode. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @retval HAL mode + */ +HAL_I2C_ModeTypeDef HAL_I2C_GetMode(I2C_HandleTypeDef *hi2c) +{ + return hi2c->Mode; +} + +/** +* @brief Return the I2C error code. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. +* @retval I2C Error Code +*/ +uint32_t HAL_I2C_GetError(I2C_HandleTypeDef *hi2c) +{ + return hi2c->ErrorCode; +} + +/** + * @} + */ + +/** + * @} + */ + +/** @addtogroup I2C_Private_Functions + * @{ + */ + +/** + * @brief Interrupt Sub-Routine which handle the Interrupt Flags Master Mode with Interrupt. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param ITFlags Interrupt flags to handle. + * @param ITSources Interrupt sources enabled. + * @retval HAL status + */ +static HAL_StatusTypeDef I2C_Master_ISR_IT(struct __I2C_HandleTypeDef *hi2c, uint32_t ITFlags, uint32_t ITSources) +{ + uint16_t devaddress; + uint32_t tmpITFlags = ITFlags; + + /* Process Locked */ + __HAL_LOCK(hi2c); + + if ((I2C_CHECK_FLAG(tmpITFlags, I2C_FLAG_AF) != RESET) && (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_NACKI) != RESET)) + { + /* Clear NACK Flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF); + + /* Set corresponding Error Code */ + /* No need to generate STOP, it is automatically done */ + /* Error callback will be send during stop flag treatment */ + hi2c->ErrorCode |= HAL_I2C_ERROR_AF; + + /* Flush TX register */ + I2C_Flush_TXDR(hi2c); + } + else if ((I2C_CHECK_FLAG(tmpITFlags, I2C_FLAG_RXNE) != RESET) && (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_RXI) != RESET)) + { + /* Remove RXNE flag on temporary variable as read done */ + tmpITFlags &= ~I2C_FLAG_RXNE; + + /* Read data from RXDR */ + *hi2c->pBuffPtr = (uint8_t)hi2c->Instance->RXDR; + + /* Increment Buffer pointer */ + hi2c->pBuffPtr++; + + hi2c->XferSize--; + hi2c->XferCount--; + } + else if ((I2C_CHECK_FLAG(tmpITFlags, I2C_FLAG_TXIS) != RESET) && (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_TXI) != RESET)) + { + /* Write data to TXDR */ + hi2c->Instance->TXDR = *hi2c->pBuffPtr; + + /* Increment Buffer pointer */ + hi2c->pBuffPtr++; + + hi2c->XferSize--; + hi2c->XferCount--; + } + else if ((I2C_CHECK_FLAG(tmpITFlags, I2C_FLAG_TCR) != RESET) && (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_TCI) != RESET)) + { + if ((hi2c->XferCount != 0U) && (hi2c->XferSize == 0U)) + { + devaddress = (uint16_t)(hi2c->Instance->CR2 & I2C_CR2_SADD); + + if (hi2c->XferCount > MAX_NBYTE_SIZE) + { + hi2c->XferSize = MAX_NBYTE_SIZE; + I2C_TransferConfig(hi2c, devaddress, (uint8_t)hi2c->XferSize, I2C_RELOAD_MODE, I2C_NO_STARTSTOP); + } + else + { + hi2c->XferSize = hi2c->XferCount; + if (hi2c->XferOptions != I2C_NO_OPTION_FRAME) + { + I2C_TransferConfig(hi2c, devaddress, (uint8_t)hi2c->XferSize, hi2c->XferOptions, I2C_NO_STARTSTOP); + } + else + { + I2C_TransferConfig(hi2c, devaddress, (uint8_t)hi2c->XferSize, I2C_AUTOEND_MODE, I2C_NO_STARTSTOP); + } + } + } + else + { + /* Call TxCpltCallback() if no stop mode is set */ + if (I2C_GET_STOP_MODE(hi2c) != I2C_AUTOEND_MODE) + { + /* Call I2C Master Sequential complete process */ + I2C_ITMasterSeqCplt(hi2c); + } + else + { + /* Wrong size Status regarding TCR flag event */ + /* Call the corresponding callback to inform upper layer of End of Transfer */ + I2C_ITError(hi2c, HAL_I2C_ERROR_SIZE); + } + } + } + else if ((I2C_CHECK_FLAG(tmpITFlags, I2C_FLAG_TC) != RESET) && (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_TCI) != RESET)) + { + if (hi2c->XferCount == 0U) + { + if (I2C_GET_STOP_MODE(hi2c) != I2C_AUTOEND_MODE) + { + /* Generate a stop condition in case of no transfer option */ + if (hi2c->XferOptions == I2C_NO_OPTION_FRAME) + { + /* Generate Stop */ + hi2c->Instance->CR2 |= I2C_CR2_STOP; + } + else + { + /* Call I2C Master Sequential complete process */ + I2C_ITMasterSeqCplt(hi2c); + } + } + } + else + { + /* Wrong size Status regarding TC flag event */ + /* Call the corresponding callback to inform upper layer of End of Transfer */ + I2C_ITError(hi2c, HAL_I2C_ERROR_SIZE); + } + } + else + { + /* Nothing to do */ + } + + if ((I2C_CHECK_FLAG(tmpITFlags, I2C_FLAG_STOPF) != RESET) && (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_STOPI) != RESET)) + { + /* Call I2C Master complete process */ + I2C_ITMasterCplt(hi2c, tmpITFlags); + } + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_OK; +} + +/** + * @brief Interrupt Sub-Routine which handle the Interrupt Flags Slave Mode with Interrupt. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param ITFlags Interrupt flags to handle. + * @param ITSources Interrupt sources enabled. + * @retval HAL status + */ +static HAL_StatusTypeDef I2C_Slave_ISR_IT(struct __I2C_HandleTypeDef *hi2c, uint32_t ITFlags, uint32_t ITSources) +{ + uint32_t tmpoptions = hi2c->XferOptions; + uint32_t tmpITFlags = ITFlags; + + /* Process locked */ + __HAL_LOCK(hi2c); + + /* Check if STOPF is set */ + if ((I2C_CHECK_FLAG(tmpITFlags, I2C_FLAG_STOPF) != RESET) && (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_STOPI) != RESET)) + { + /* Call I2C Slave complete process */ + I2C_ITSlaveCplt(hi2c, tmpITFlags); + } + + if ((I2C_CHECK_FLAG(tmpITFlags, I2C_FLAG_AF) != RESET) && (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_NACKI) != RESET)) + { + /* Check that I2C transfer finished */ + /* if yes, normal use case, a NACK is sent by the MASTER when Transfer is finished */ + /* Mean XferCount == 0*/ + /* So clear Flag NACKF only */ + if (hi2c->XferCount == 0U) + { + if ((hi2c->State == HAL_I2C_STATE_LISTEN) && (tmpoptions == I2C_FIRST_AND_LAST_FRAME)) /* Same action must be done for (tmpoptions == I2C_LAST_FRAME) which removed for Warning[Pa134]: left and right operands are identical */ + { + /* Call I2C Listen complete process */ + I2C_ITListenCplt(hi2c, tmpITFlags); + } + else if ((hi2c->State == HAL_I2C_STATE_BUSY_TX_LISTEN) && (tmpoptions != I2C_NO_OPTION_FRAME)) + { + /* Clear NACK Flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF); + + /* Flush TX register */ + I2C_Flush_TXDR(hi2c); + + /* Last Byte is Transmitted */ + /* Call I2C Slave Sequential complete process */ + I2C_ITSlaveSeqCplt(hi2c); + } + else + { + /* Clear NACK Flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF); + } + } + else + { + /* if no, error use case, a Non-Acknowledge of last Data is generated by the MASTER*/ + /* Clear NACK Flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF); + + /* Set ErrorCode corresponding to a Non-Acknowledge */ + hi2c->ErrorCode |= HAL_I2C_ERROR_AF; + + if ((tmpoptions == I2C_FIRST_FRAME) || (tmpoptions == I2C_NEXT_FRAME)) + { + /* Call the corresponding callback to inform upper layer of End of Transfer */ + I2C_ITError(hi2c, hi2c->ErrorCode); + } + } + } + else if ((I2C_CHECK_FLAG(tmpITFlags, I2C_FLAG_RXNE) != RESET) && (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_RXI) != RESET)) + { + if (hi2c->XferCount > 0U) + { + /* Read data from RXDR */ + *hi2c->pBuffPtr = (uint8_t)hi2c->Instance->RXDR; + + /* Increment Buffer pointer */ + hi2c->pBuffPtr++; + + hi2c->XferSize--; + hi2c->XferCount--; + } + + if ((hi2c->XferCount == 0U) && \ + (tmpoptions != I2C_NO_OPTION_FRAME)) + { + /* Call I2C Slave Sequential complete process */ + I2C_ITSlaveSeqCplt(hi2c); + } + } + else if ((I2C_CHECK_FLAG(tmpITFlags, I2C_FLAG_ADDR) != RESET) && (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_ADDRI) != RESET)) + { + I2C_ITAddrCplt(hi2c, tmpITFlags); + } + else if ((I2C_CHECK_FLAG(tmpITFlags, I2C_FLAG_TXIS) != RESET) && (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_TXI) != RESET)) + { + /* Write data to TXDR only if XferCount not reach "0" */ + /* A TXIS flag can be set, during STOP treatment */ + /* Check if all Datas have already been sent */ + /* If it is the case, this last write in TXDR is not sent, correspond to a dummy TXIS event */ + if (hi2c->XferCount > 0U) + { + /* Write data to TXDR */ + hi2c->Instance->TXDR = *hi2c->pBuffPtr; + + /* Increment Buffer pointer */ + hi2c->pBuffPtr++; + + hi2c->XferCount--; + hi2c->XferSize--; + } + else + { + if ((tmpoptions == I2C_NEXT_FRAME) || (tmpoptions == I2C_FIRST_FRAME)) + { + /* Last Byte is Transmitted */ + /* Call I2C Slave Sequential complete process */ + I2C_ITSlaveSeqCplt(hi2c); + } + } + } + else + { + /* Nothing to do */ + } + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_OK; +} + +/** + * @brief Interrupt Sub-Routine which handle the Interrupt Flags Master Mode with DMA. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param ITFlags Interrupt flags to handle. + * @param ITSources Interrupt sources enabled. + * @retval HAL status + */ +static HAL_StatusTypeDef I2C_Master_ISR_DMA(struct __I2C_HandleTypeDef *hi2c, uint32_t ITFlags, uint32_t ITSources) +{ + uint16_t devaddress; + uint32_t xfermode; + + /* Process Locked */ + __HAL_LOCK(hi2c); + + if ((I2C_CHECK_FLAG(ITFlags, I2C_FLAG_AF) != RESET) && (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_NACKI) != RESET)) + { + /* Clear NACK Flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF); + + /* Set corresponding Error Code */ + hi2c->ErrorCode |= HAL_I2C_ERROR_AF; + + /* No need to generate STOP, it is automatically done */ + /* But enable STOP interrupt, to treat it */ + /* Error callback will be send during stop flag treatment */ + I2C_Enable_IRQ(hi2c, I2C_XFER_CPLT_IT); + + /* Flush TX register */ + I2C_Flush_TXDR(hi2c); + } + else if ((I2C_CHECK_FLAG(ITFlags, I2C_FLAG_TCR) != RESET) && (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_TCI) != RESET)) + { + /* Disable TC interrupt */ + __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_TCI); + + if (hi2c->XferCount != 0U) + { + /* Recover Slave address */ + devaddress = (uint16_t)(hi2c->Instance->CR2 & I2C_CR2_SADD); + + /* Prepare the new XferSize to transfer */ + if (hi2c->XferCount > MAX_NBYTE_SIZE) + { + hi2c->XferSize = MAX_NBYTE_SIZE; + xfermode = I2C_RELOAD_MODE; + } + else + { + hi2c->XferSize = hi2c->XferCount; + if (hi2c->XferOptions != I2C_NO_OPTION_FRAME) + { + xfermode = hi2c->XferOptions; + } + else + { + xfermode = I2C_AUTOEND_MODE; + } + } + + /* Set the new XferSize in Nbytes register */ + I2C_TransferConfig(hi2c, devaddress, (uint8_t)hi2c->XferSize, xfermode, I2C_NO_STARTSTOP); + + /* Update XferCount value */ + hi2c->XferCount -= hi2c->XferSize; + + /* Enable DMA Request */ + if (hi2c->State == HAL_I2C_STATE_BUSY_RX) + { + hi2c->Instance->CR1 |= I2C_CR1_RXDMAEN; + } + else + { + hi2c->Instance->CR1 |= I2C_CR1_TXDMAEN; + } + } + else + { + /* Call TxCpltCallback() if no stop mode is set */ + if (I2C_GET_STOP_MODE(hi2c) != I2C_AUTOEND_MODE) + { + /* Call I2C Master Sequential complete process */ + I2C_ITMasterSeqCplt(hi2c); + } + else + { + /* Wrong size Status regarding TCR flag event */ + /* Call the corresponding callback to inform upper layer of End of Transfer */ + I2C_ITError(hi2c, HAL_I2C_ERROR_SIZE); + } + } + } + else if ((I2C_CHECK_FLAG(ITFlags, I2C_FLAG_TC) != RESET) && (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_TCI) != RESET)) + { + if (hi2c->XferCount == 0U) + { + if (I2C_GET_STOP_MODE(hi2c) != I2C_AUTOEND_MODE) + { + /* Generate a stop condition in case of no transfer option */ + if (hi2c->XferOptions == I2C_NO_OPTION_FRAME) + { + /* Generate Stop */ + hi2c->Instance->CR2 |= I2C_CR2_STOP; + } + else + { + /* Call I2C Master Sequential complete process */ + I2C_ITMasterSeqCplt(hi2c); + } + } + } + else + { + /* Wrong size Status regarding TC flag event */ + /* Call the corresponding callback to inform upper layer of End of Transfer */ + I2C_ITError(hi2c, HAL_I2C_ERROR_SIZE); + } + } + else if ((I2C_CHECK_FLAG(ITFlags, I2C_FLAG_STOPF) != RESET) && (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_STOPI) != RESET)) + { + /* Call I2C Master complete process */ + I2C_ITMasterCplt(hi2c, ITFlags); + } + else + { + /* Nothing to do */ + } + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_OK; +} + +/** + * @brief Interrupt Sub-Routine which handle the Interrupt Flags Slave Mode with DMA. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param ITFlags Interrupt flags to handle. + * @param ITSources Interrupt sources enabled. + * @retval HAL status + */ +static HAL_StatusTypeDef I2C_Slave_ISR_DMA(struct __I2C_HandleTypeDef *hi2c, uint32_t ITFlags, uint32_t ITSources) +{ + uint32_t tmpoptions = hi2c->XferOptions; + uint32_t treatdmanack = 0U; + + /* Process locked */ + __HAL_LOCK(hi2c); + + /* Check if STOPF is set */ + if ((I2C_CHECK_FLAG(ITFlags, I2C_FLAG_STOPF) != RESET) && (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_STOPI) != RESET)) + { + /* Call I2C Slave complete process */ + I2C_ITSlaveCplt(hi2c, ITFlags); + } + + if ((I2C_CHECK_FLAG(ITFlags, I2C_FLAG_AF) != RESET) && (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_NACKI) != RESET)) + { + /* Check that I2C transfer finished */ + /* if yes, normal use case, a NACK is sent by the MASTER when Transfer is finished */ + /* Mean XferCount == 0 */ + /* So clear Flag NACKF only */ + if ((I2C_CHECK_IT_SOURCE(ITSources, I2C_CR1_TXDMAEN) != RESET) || + (I2C_CHECK_IT_SOURCE(ITSources, I2C_CR1_RXDMAEN) != RESET)) + { + /* Split check of hdmarx, for MISRA compliance */ + if (hi2c->hdmarx != NULL) + { + if (I2C_CHECK_IT_SOURCE(ITSources, I2C_CR1_RXDMAEN) != RESET) + { + if (__HAL_DMA_GET_COUNTER(hi2c->hdmarx) == 0U) + { + treatdmanack = 1U; + } + } + } + + /* Split check of hdmatx, for MISRA compliance */ + if (hi2c->hdmatx != NULL) + { + if (I2C_CHECK_IT_SOURCE(ITSources, I2C_CR1_TXDMAEN) != RESET) + { + if (__HAL_DMA_GET_COUNTER(hi2c->hdmatx) == 0U) + { + treatdmanack = 1U; + } + } + } + + if (treatdmanack == 1U) + { + if ((hi2c->State == HAL_I2C_STATE_LISTEN) && (tmpoptions == I2C_FIRST_AND_LAST_FRAME)) /* Same action must be done for (tmpoptions == I2C_LAST_FRAME) which removed for Warning[Pa134]: left and right operands are identical */ + { + /* Call I2C Listen complete process */ + I2C_ITListenCplt(hi2c, ITFlags); + } + else if ((hi2c->State == HAL_I2C_STATE_BUSY_TX_LISTEN) && (tmpoptions != I2C_NO_OPTION_FRAME)) + { + /* Clear NACK Flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF); + + /* Flush TX register */ + I2C_Flush_TXDR(hi2c); + + /* Last Byte is Transmitted */ + /* Call I2C Slave Sequential complete process */ + I2C_ITSlaveSeqCplt(hi2c); + } + else + { + /* Clear NACK Flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF); + } + } + else + { + /* if no, error use case, a Non-Acknowledge of last Data is generated by the MASTER*/ + /* Clear NACK Flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF); + + /* Set ErrorCode corresponding to a Non-Acknowledge */ + hi2c->ErrorCode |= HAL_I2C_ERROR_AF; + + if ((tmpoptions == I2C_FIRST_FRAME) || (tmpoptions == I2C_NEXT_FRAME)) + { + /* Call the corresponding callback to inform upper layer of End of Transfer */ + I2C_ITError(hi2c, hi2c->ErrorCode); + } + } + } + else + { + /* Only Clear NACK Flag, no DMA treatment is pending */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF); + } + } + else if ((I2C_CHECK_FLAG(ITFlags, I2C_FLAG_ADDR) != RESET) && (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_ADDRI) != RESET)) + { + I2C_ITAddrCplt(hi2c, ITFlags); + } + else + { + /* Nothing to do */ + } + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_OK; +} + +/** + * @brief Master sends target device address followed by internal memory address for write request. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param DevAddress Target device address: The device 7 bits address value + * in datasheet must be shifted to the left before calling the interface + * @param MemAddress Internal memory address + * @param MemAddSize Size of internal memory address + * @param Timeout Timeout duration + * @param Tickstart Tick start value + * @retval HAL status + */ +static HAL_StatusTypeDef I2C_RequestMemoryWrite(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint32_t Timeout, uint32_t Tickstart) +{ + I2C_TransferConfig(hi2c, DevAddress, (uint8_t)MemAddSize, I2C_RELOAD_MODE, I2C_GENERATE_START_WRITE); + + /* Wait until TXIS flag is set */ + if (I2C_WaitOnTXISFlagUntilTimeout(hi2c, Timeout, Tickstart) != HAL_OK) + { + return HAL_ERROR; + } + + /* If Memory address size is 8Bit */ + if (MemAddSize == I2C_MEMADD_SIZE_8BIT) + { + /* Send Memory Address */ + hi2c->Instance->TXDR = I2C_MEM_ADD_LSB(MemAddress); + } + /* If Memory address size is 16Bit */ + else + { + /* Send MSB of Memory Address */ + hi2c->Instance->TXDR = I2C_MEM_ADD_MSB(MemAddress); + + /* Wait until TXIS flag is set */ + if (I2C_WaitOnTXISFlagUntilTimeout(hi2c, Timeout, Tickstart) != HAL_OK) + { + return HAL_ERROR; + } + + /* Send LSB of Memory Address */ + hi2c->Instance->TXDR = I2C_MEM_ADD_LSB(MemAddress); + } + + /* Wait until TCR flag is set */ + if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_TCR, RESET, Timeout, Tickstart) != HAL_OK) + { + return HAL_ERROR; + } + + return HAL_OK; +} + +/** + * @brief Master sends target device address followed by internal memory address for read request. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param DevAddress Target device address: The device 7 bits address value + * in datasheet must be shifted to the left before calling the interface + * @param MemAddress Internal memory address + * @param MemAddSize Size of internal memory address + * @param Timeout Timeout duration + * @param Tickstart Tick start value + * @retval HAL status + */ +static HAL_StatusTypeDef I2C_RequestMemoryRead(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint32_t Timeout, uint32_t Tickstart) +{ + I2C_TransferConfig(hi2c, DevAddress, (uint8_t)MemAddSize, I2C_SOFTEND_MODE, I2C_GENERATE_START_WRITE); + + /* Wait until TXIS flag is set */ + if (I2C_WaitOnTXISFlagUntilTimeout(hi2c, Timeout, Tickstart) != HAL_OK) + { + return HAL_ERROR; + } + + /* If Memory address size is 8Bit */ + if (MemAddSize == I2C_MEMADD_SIZE_8BIT) + { + /* Send Memory Address */ + hi2c->Instance->TXDR = I2C_MEM_ADD_LSB(MemAddress); + } + /* If Memory address size is 16Bit */ + else + { + /* Send MSB of Memory Address */ + hi2c->Instance->TXDR = I2C_MEM_ADD_MSB(MemAddress); + + /* Wait until TXIS flag is set */ + if (I2C_WaitOnTXISFlagUntilTimeout(hi2c, Timeout, Tickstart) != HAL_OK) + { + return HAL_ERROR; + } + + /* Send LSB of Memory Address */ + hi2c->Instance->TXDR = I2C_MEM_ADD_LSB(MemAddress); + } + + /* Wait until TC flag is set */ + if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_TC, RESET, Timeout, Tickstart) != HAL_OK) + { + return HAL_ERROR; + } + + return HAL_OK; +} + +/** + * @brief I2C Address complete process callback. + * @param hi2c I2C handle. + * @param ITFlags Interrupt flags to handle. + * @retval None + */ +static void I2C_ITAddrCplt(I2C_HandleTypeDef *hi2c, uint32_t ITFlags) +{ + uint8_t transferdirection; + uint16_t slaveaddrcode; + uint16_t ownadd1code; + uint16_t ownadd2code; + + /* Prevent unused argument(s) compilation warning */ + UNUSED(ITFlags); + + /* In case of Listen state, need to inform upper layer of address match code event */ + if (((uint32_t)hi2c->State & (uint32_t)HAL_I2C_STATE_LISTEN) == (uint32_t)HAL_I2C_STATE_LISTEN) + { + transferdirection = I2C_GET_DIR(hi2c); + slaveaddrcode = I2C_GET_ADDR_MATCH(hi2c); + ownadd1code = I2C_GET_OWN_ADDRESS1(hi2c); + ownadd2code = I2C_GET_OWN_ADDRESS2(hi2c); + + /* If 10bits addressing mode is selected */ + if (hi2c->Init.AddressingMode == I2C_ADDRESSINGMODE_10BIT) + { + if ((slaveaddrcode & SlaveAddr_MSK) == ((ownadd1code >> SlaveAddr_SHIFT) & SlaveAddr_MSK)) + { + slaveaddrcode = ownadd1code; + hi2c->AddrEventCount++; + if (hi2c->AddrEventCount == 2U) + { + /* Reset Address Event counter */ + hi2c->AddrEventCount = 0U; + + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_ADDR); + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Call Slave Addr callback */ +#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1) + hi2c->AddrCallback(hi2c, transferdirection, slaveaddrcode); +#else + HAL_I2C_AddrCallback(hi2c, transferdirection, slaveaddrcode); +#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */ + } + } + else + { + slaveaddrcode = ownadd2code; + + /* Disable ADDR Interrupts */ + I2C_Disable_IRQ(hi2c, I2C_XFER_LISTEN_IT); + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Call Slave Addr callback */ +#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1) + hi2c->AddrCallback(hi2c, transferdirection, slaveaddrcode); +#else + HAL_I2C_AddrCallback(hi2c, transferdirection, slaveaddrcode); +#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */ + } + } + /* else 7 bits addressing mode is selected */ + else + { + /* Disable ADDR Interrupts */ + I2C_Disable_IRQ(hi2c, I2C_XFER_LISTEN_IT); + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Call Slave Addr callback */ +#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1) + hi2c->AddrCallback(hi2c, transferdirection, slaveaddrcode); +#else + HAL_I2C_AddrCallback(hi2c, transferdirection, slaveaddrcode); +#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */ + } + } + /* Else clear address flag only */ + else + { + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_ADDR); + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + } +} + +/** + * @brief I2C Master sequential complete process. + * @param hi2c I2C handle. + * @retval None + */ +static void I2C_ITMasterSeqCplt(I2C_HandleTypeDef *hi2c) +{ + /* Reset I2C handle mode */ + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* No Generate Stop, to permit restart mode */ + /* The stop will be done at the end of transfer, when I2C_AUTOEND_MODE enable */ + if (hi2c->State == HAL_I2C_STATE_BUSY_TX) + { + hi2c->State = HAL_I2C_STATE_READY; + hi2c->PreviousState = I2C_STATE_MASTER_BUSY_TX; + hi2c->XferISR = NULL; + + /* Disable Interrupts */ + I2C_Disable_IRQ(hi2c, I2C_XFER_TX_IT); + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Call the corresponding callback to inform upper layer of End of Transfer */ +#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1) + hi2c->MasterTxCpltCallback(hi2c); +#else + HAL_I2C_MasterTxCpltCallback(hi2c); +#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */ + } + /* hi2c->State == HAL_I2C_STATE_BUSY_RX */ + else + { + hi2c->State = HAL_I2C_STATE_READY; + hi2c->PreviousState = I2C_STATE_MASTER_BUSY_RX; + hi2c->XferISR = NULL; + + /* Disable Interrupts */ + I2C_Disable_IRQ(hi2c, I2C_XFER_RX_IT); + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Call the corresponding callback to inform upper layer of End of Transfer */ +#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1) + hi2c->MasterRxCpltCallback(hi2c); +#else + HAL_I2C_MasterRxCpltCallback(hi2c); +#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */ + } +} + +/** + * @brief I2C Slave sequential complete process. + * @param hi2c I2C handle. + * @retval None + */ +static void I2C_ITSlaveSeqCplt(I2C_HandleTypeDef *hi2c) +{ + /* Reset I2C handle mode */ + hi2c->Mode = HAL_I2C_MODE_NONE; + + if (hi2c->State == HAL_I2C_STATE_BUSY_TX_LISTEN) + { + /* Remove HAL_I2C_STATE_SLAVE_BUSY_TX, keep only HAL_I2C_STATE_LISTEN */ + hi2c->State = HAL_I2C_STATE_LISTEN; + hi2c->PreviousState = I2C_STATE_SLAVE_BUSY_TX; + + /* Disable Interrupts */ + I2C_Disable_IRQ(hi2c, I2C_XFER_TX_IT); + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Call the corresponding callback to inform upper layer of End of Transfer */ +#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1) + hi2c->SlaveTxCpltCallback(hi2c); +#else + HAL_I2C_SlaveTxCpltCallback(hi2c); +#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */ + } + + else if (hi2c->State == HAL_I2C_STATE_BUSY_RX_LISTEN) + { + /* Remove HAL_I2C_STATE_SLAVE_BUSY_RX, keep only HAL_I2C_STATE_LISTEN */ + hi2c->State = HAL_I2C_STATE_LISTEN; + hi2c->PreviousState = I2C_STATE_SLAVE_BUSY_RX; + + /* Disable Interrupts */ + I2C_Disable_IRQ(hi2c, I2C_XFER_RX_IT); + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Call the corresponding callback to inform upper layer of End of Transfer */ +#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1) + hi2c->SlaveRxCpltCallback(hi2c); +#else + HAL_I2C_SlaveRxCpltCallback(hi2c); +#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */ + } + else + { + /* Nothing to do */ + } +} + +/** + * @brief I2C Master complete process. + * @param hi2c I2C handle. + * @param ITFlags Interrupt flags to handle. + * @retval None + */ +static void I2C_ITMasterCplt(I2C_HandleTypeDef *hi2c, uint32_t ITFlags) +{ + uint32_t tmperror; + + /* Clear STOP Flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF); + + /* Clear Configuration Register 2 */ + I2C_RESET_CR2(hi2c); + + /* Reset handle parameters */ + hi2c->PreviousState = I2C_STATE_NONE; + hi2c->XferISR = NULL; + hi2c->XferOptions = I2C_NO_OPTION_FRAME; + + if (I2C_CHECK_FLAG(ITFlags, I2C_FLAG_AF) != RESET) + { + /* Clear NACK Flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF); + + /* Set acknowledge error code */ + hi2c->ErrorCode |= HAL_I2C_ERROR_AF; + } + + /* Flush TX register */ + I2C_Flush_TXDR(hi2c); + + /* Disable Interrupts */ + I2C_Disable_IRQ(hi2c, I2C_XFER_TX_IT | I2C_XFER_RX_IT); + + /* Store current volatile hi2c->ErrorCode, misra rule */ + tmperror = hi2c->ErrorCode; + + /* Call the corresponding callback to inform upper layer of End of Transfer */ + if ((hi2c->State == HAL_I2C_STATE_ABORT) || (tmperror != HAL_I2C_ERROR_NONE)) + { + /* Call the corresponding callback to inform upper layer of End of Transfer */ + I2C_ITError(hi2c, hi2c->ErrorCode); + } + /* hi2c->State == HAL_I2C_STATE_BUSY_TX */ + else if (hi2c->State == HAL_I2C_STATE_BUSY_TX) + { + hi2c->State = HAL_I2C_STATE_READY; + + if (hi2c->Mode == HAL_I2C_MODE_MEM) + { + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Call the corresponding callback to inform upper layer of End of Transfer */ +#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1) + hi2c->MemTxCpltCallback(hi2c); +#else + HAL_I2C_MemTxCpltCallback(hi2c); +#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */ + } + else + { + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Call the corresponding callback to inform upper layer of End of Transfer */ +#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1) + hi2c->MasterTxCpltCallback(hi2c); +#else + HAL_I2C_MasterTxCpltCallback(hi2c); +#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */ + } + } + /* hi2c->State == HAL_I2C_STATE_BUSY_RX */ + else if (hi2c->State == HAL_I2C_STATE_BUSY_RX) + { + hi2c->State = HAL_I2C_STATE_READY; + + if (hi2c->Mode == HAL_I2C_MODE_MEM) + { + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Call the corresponding callback to inform upper layer of End of Transfer */ +#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1) + hi2c->MemRxCpltCallback(hi2c); +#else + HAL_I2C_MemRxCpltCallback(hi2c); +#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */ + } + else + { + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Call the corresponding callback to inform upper layer of End of Transfer */ +#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1) + hi2c->MasterRxCpltCallback(hi2c); +#else + HAL_I2C_MasterRxCpltCallback(hi2c); +#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */ + } + } + else + { + /* Nothing to do */ + } +} + +/** + * @brief I2C Slave complete process. + * @param hi2c I2C handle. + * @param ITFlags Interrupt flags to handle. + * @retval None + */ +static void I2C_ITSlaveCplt(I2C_HandleTypeDef *hi2c, uint32_t ITFlags) +{ + uint32_t tmpcr1value = READ_REG(hi2c->Instance->CR1); + uint32_t tmpITFlags = ITFlags; + + /* Clear STOP Flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF); + + /* Disable all interrupts */ + I2C_Disable_IRQ(hi2c, I2C_XFER_LISTEN_IT | I2C_XFER_TX_IT | I2C_XFER_RX_IT); + + /* Disable Address Acknowledge */ + hi2c->Instance->CR2 |= I2C_CR2_NACK; + + /* Clear Configuration Register 2 */ + I2C_RESET_CR2(hi2c); + + /* Flush TX register */ + I2C_Flush_TXDR(hi2c); + + /* If a DMA is ongoing, Update handle size context */ + if (I2C_CHECK_IT_SOURCE(tmpcr1value, I2C_CR1_TXDMAEN) != RESET) + { + if (hi2c->hdmatx != NULL) + { + hi2c->XferCount = (uint16_t)__HAL_DMA_GET_COUNTER(hi2c->hdmatx); + } + } + else if (I2C_CHECK_IT_SOURCE(tmpcr1value, I2C_CR1_RXDMAEN) != RESET) + { + if (hi2c->hdmarx != NULL) + { + hi2c->XferCount = (uint16_t)__HAL_DMA_GET_COUNTER(hi2c->hdmarx); + } + } + else + { + /* Do nothing */ + } + + /* Store Last receive data if any */ + if (I2C_CHECK_FLAG(tmpITFlags, I2C_FLAG_RXNE) != RESET) + { + /* Remove RXNE flag on temporary variable as read done */ + tmpITFlags &= ~I2C_FLAG_RXNE; + + /* Read data from RXDR */ + *hi2c->pBuffPtr = (uint8_t)hi2c->Instance->RXDR; + + /* Increment Buffer pointer */ + hi2c->pBuffPtr++; + + if ((hi2c->XferSize > 0U)) + { + hi2c->XferSize--; + hi2c->XferCount--; + } + } + + /* All data are not transferred, so set error code accordingly */ + if (hi2c->XferCount != 0U) + { + /* Set ErrorCode corresponding to a Non-Acknowledge */ + hi2c->ErrorCode |= HAL_I2C_ERROR_AF; + } + + hi2c->PreviousState = I2C_STATE_NONE; + hi2c->Mode = HAL_I2C_MODE_NONE; + hi2c->XferISR = NULL; + + if (hi2c->ErrorCode != HAL_I2C_ERROR_NONE) + { + /* Call the corresponding callback to inform upper layer of End of Transfer */ + I2C_ITError(hi2c, hi2c->ErrorCode); + + /* Call the Listen Complete callback, to inform upper layer of the end of Listen usecase */ + if (hi2c->State == HAL_I2C_STATE_LISTEN) + { + /* Call I2C Listen complete process */ + I2C_ITListenCplt(hi2c, tmpITFlags); + } + } + else if (hi2c->XferOptions != I2C_NO_OPTION_FRAME) + { + /* Call the Sequential Complete callback, to inform upper layer of the end of Tranfer */ + I2C_ITSlaveSeqCplt(hi2c); + + hi2c->XferOptions = I2C_NO_OPTION_FRAME; + hi2c->State = HAL_I2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Call the Listen Complete callback, to inform upper layer of the end of Listen usecase */ +#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1) + hi2c->ListenCpltCallback(hi2c); +#else + HAL_I2C_ListenCpltCallback(hi2c); +#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */ + } + /* Call the corresponding callback to inform upper layer of End of Transfer */ + else if (hi2c->State == HAL_I2C_STATE_BUSY_RX) + { + hi2c->State = HAL_I2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Call the corresponding callback to inform upper layer of End of Transfer */ +#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1) + hi2c->SlaveRxCpltCallback(hi2c); +#else + HAL_I2C_SlaveRxCpltCallback(hi2c); +#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */ + } + else + { + hi2c->State = HAL_I2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Call the corresponding callback to inform upper layer of End of Transfer */ +#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1) + hi2c->SlaveTxCpltCallback(hi2c); +#else + HAL_I2C_SlaveTxCpltCallback(hi2c); +#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */ + } +} + +/** + * @brief I2C Listen complete process. + * @param hi2c I2C handle. + * @param ITFlags Interrupt flags to handle. + * @retval None + */ +static void I2C_ITListenCplt(I2C_HandleTypeDef *hi2c, uint32_t ITFlags) +{ + /* Reset handle parameters */ + hi2c->XferOptions = I2C_NO_OPTION_FRAME; + hi2c->PreviousState = I2C_STATE_NONE; + hi2c->State = HAL_I2C_STATE_READY; + hi2c->Mode = HAL_I2C_MODE_NONE; + hi2c->XferISR = NULL; + + /* Store Last receive data if any */ + if (I2C_CHECK_FLAG(ITFlags, I2C_FLAG_RXNE) != RESET) + { + /* Read data from RXDR */ + *hi2c->pBuffPtr = (uint8_t)hi2c->Instance->RXDR; + + /* Increment Buffer pointer */ + hi2c->pBuffPtr++; + + if ((hi2c->XferSize > 0U)) + { + hi2c->XferSize--; + hi2c->XferCount--; + + /* Set ErrorCode corresponding to a Non-Acknowledge */ + hi2c->ErrorCode |= HAL_I2C_ERROR_AF; + } + } + + /* Disable all Interrupts*/ + I2C_Disable_IRQ(hi2c, I2C_XFER_LISTEN_IT | I2C_XFER_RX_IT | I2C_XFER_TX_IT); + + /* Clear NACK Flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF); + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Call the Listen Complete callback, to inform upper layer of the end of Listen usecase */ +#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1) + hi2c->ListenCpltCallback(hi2c); +#else + HAL_I2C_ListenCpltCallback(hi2c); +#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */ +} + +/** + * @brief I2C interrupts error process. + * @param hi2c I2C handle. + * @param ErrorCode Error code to handle. + * @retval None + */ +static void I2C_ITError(I2C_HandleTypeDef *hi2c, uint32_t ErrorCode) +{ + HAL_I2C_StateTypeDef tmpstate = hi2c->State; + + /* Reset handle parameters */ + hi2c->Mode = HAL_I2C_MODE_NONE; + hi2c->XferOptions = I2C_NO_OPTION_FRAME; + hi2c->XferCount = 0U; + + /* Set new error code */ + hi2c->ErrorCode |= ErrorCode; + + /* Disable Interrupts */ + if ((tmpstate == HAL_I2C_STATE_LISTEN) || + (tmpstate == HAL_I2C_STATE_BUSY_TX_LISTEN) || + (tmpstate == HAL_I2C_STATE_BUSY_RX_LISTEN)) + { + /* Disable all interrupts, except interrupts related to LISTEN state */ + I2C_Disable_IRQ(hi2c, I2C_XFER_RX_IT | I2C_XFER_TX_IT); + + /* keep HAL_I2C_STATE_LISTEN if set */ + hi2c->State = HAL_I2C_STATE_LISTEN; + hi2c->PreviousState = I2C_STATE_NONE; + hi2c->XferISR = I2C_Slave_ISR_IT; + } + else + { + /* Disable all interrupts */ + I2C_Disable_IRQ(hi2c, I2C_XFER_LISTEN_IT | I2C_XFER_RX_IT | I2C_XFER_TX_IT); + + /* If state is an abort treatment on goind, don't change state */ + /* This change will be do later */ + if (hi2c->State != HAL_I2C_STATE_ABORT) + { + /* Set HAL_I2C_STATE_READY */ + hi2c->State = HAL_I2C_STATE_READY; + } + hi2c->PreviousState = I2C_STATE_NONE; + hi2c->XferISR = NULL; + } + + /* Abort DMA TX transfer if any */ + if ((hi2c->Instance->CR1 & I2C_CR1_TXDMAEN) == I2C_CR1_TXDMAEN) + { + hi2c->Instance->CR1 &= ~I2C_CR1_TXDMAEN; + + if (hi2c->hdmatx != NULL) + { + /* Set the I2C DMA Abort callback : + will lead to call HAL_I2C_ErrorCallback() at end of DMA abort procedure */ + hi2c->hdmatx->XferAbortCallback = I2C_DMAAbort; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Abort DMA TX */ + if (HAL_DMA_Abort_IT(hi2c->hdmatx) != HAL_OK) + { + /* Call Directly XferAbortCallback function in case of error */ + hi2c->hdmatx->XferAbortCallback(hi2c->hdmatx); + } + } + } + /* Abort DMA RX transfer if any */ + else if ((hi2c->Instance->CR1 & I2C_CR1_RXDMAEN) == I2C_CR1_RXDMAEN) + { + hi2c->Instance->CR1 &= ~I2C_CR1_RXDMAEN; + + if (hi2c->hdmarx != NULL) + { + /* Set the I2C DMA Abort callback : + will lead to call HAL_I2C_ErrorCallback() at end of DMA abort procedure */ + hi2c->hdmarx->XferAbortCallback = I2C_DMAAbort; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Abort DMA RX */ + if (HAL_DMA_Abort_IT(hi2c->hdmarx) != HAL_OK) + { + /* Call Directly hi2c->hdmarx->XferAbortCallback function in case of error */ + hi2c->hdmarx->XferAbortCallback(hi2c->hdmarx); + } + } + } + else if (hi2c->State == HAL_I2C_STATE_ABORT) + { + hi2c->State = HAL_I2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Call the corresponding callback to inform upper layer of End of Transfer */ +#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1) + hi2c->AbortCpltCallback(hi2c); +#else + HAL_I2C_AbortCpltCallback(hi2c); +#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */ + } + else + { + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Call the corresponding callback to inform upper layer of End of Transfer */ +#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1) + hi2c->ErrorCallback(hi2c); +#else + HAL_I2C_ErrorCallback(hi2c); +#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */ + } +} + +/** + * @brief I2C Tx data register flush process. + * @param hi2c I2C handle. + * @retval None + */ +static void I2C_Flush_TXDR(I2C_HandleTypeDef *hi2c) +{ + /* If a pending TXIS flag is set */ + /* Write a dummy data in TXDR to clear it */ + if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_TXIS) != RESET) + { + hi2c->Instance->TXDR = 0x00U; + } + + /* Flush TX register if not empty */ + if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_TXE) == RESET) + { + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_TXE); + } +} + +/** + * @brief DMA I2C master transmit process complete callback. + * @param hdma DMA handle + * @retval None + */ +static void I2C_DMAMasterTransmitCplt(DMA_HandleTypeDef *hdma) +{ + I2C_HandleTypeDef *hi2c = (I2C_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent); /* Derogation MISRAC2012-Rule-11.5 */ + + /* Disable DMA Request */ + hi2c->Instance->CR1 &= ~I2C_CR1_TXDMAEN; + + /* If last transfer, enable STOP interrupt */ + if (hi2c->XferCount == 0U) + { + /* Enable STOP interrupt */ + I2C_Enable_IRQ(hi2c, I2C_XFER_CPLT_IT); + } + /* else prepare a new DMA transfer and enable TCReload interrupt */ + else + { + /* Update Buffer pointer */ + hi2c->pBuffPtr += hi2c->XferSize; + + /* Set the XferSize to transfer */ + if (hi2c->XferCount > MAX_NBYTE_SIZE) + { + hi2c->XferSize = MAX_NBYTE_SIZE; + } + else + { + hi2c->XferSize = hi2c->XferCount; + } + + /* Enable the DMA channel */ + if (HAL_DMA_Start_IT(hi2c->hdmatx, (uint32_t)hi2c->pBuffPtr, (uint32_t)&hi2c->Instance->TXDR, hi2c->XferSize) != HAL_OK) + { + /* Call the corresponding callback to inform upper layer of End of Transfer */ + I2C_ITError(hi2c, HAL_I2C_ERROR_DMA); + } + else + { + /* Enable TC interrupts */ + I2C_Enable_IRQ(hi2c, I2C_XFER_RELOAD_IT); + } + } +} + +/** + * @brief DMA I2C slave transmit process complete callback. + * @param hdma DMA handle + * @retval None + */ +static void I2C_DMASlaveTransmitCplt(DMA_HandleTypeDef *hdma) +{ + I2C_HandleTypeDef *hi2c = (I2C_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent); /* Derogation MISRAC2012-Rule-11.5 */ + uint32_t tmpoptions = hi2c->XferOptions; + + if ((tmpoptions == I2C_NEXT_FRAME) || (tmpoptions == I2C_FIRST_FRAME)) + { + /* Disable DMA Request */ + hi2c->Instance->CR1 &= ~I2C_CR1_TXDMAEN; + + /* Last Byte is Transmitted */ + /* Call I2C Slave Sequential complete process */ + I2C_ITSlaveSeqCplt(hi2c); + } + else + { + /* No specific action, Master fully manage the generation of STOP condition */ + /* Mean that this generation can arrive at any time, at the end or during DMA process */ + /* So STOP condition should be manage through Interrupt treatment */ + } +} + +/** + * @brief DMA I2C master receive process complete callback. + * @param hdma DMA handle + * @retval None + */ +static void I2C_DMAMasterReceiveCplt(DMA_HandleTypeDef *hdma) +{ + I2C_HandleTypeDef *hi2c = (I2C_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent); /* Derogation MISRAC2012-Rule-11.5 */ + + /* Disable DMA Request */ + hi2c->Instance->CR1 &= ~I2C_CR1_RXDMAEN; + + /* If last transfer, enable STOP interrupt */ + if (hi2c->XferCount == 0U) + { + /* Enable STOP interrupt */ + I2C_Enable_IRQ(hi2c, I2C_XFER_CPLT_IT); + } + /* else prepare a new DMA transfer and enable TCReload interrupt */ + else + { + /* Update Buffer pointer */ + hi2c->pBuffPtr += hi2c->XferSize; + + /* Set the XferSize to transfer */ + if (hi2c->XferCount > MAX_NBYTE_SIZE) + { + hi2c->XferSize = MAX_NBYTE_SIZE; + } + else + { + hi2c->XferSize = hi2c->XferCount; + } + + /* Enable the DMA channel */ + if (HAL_DMA_Start_IT(hi2c->hdmarx, (uint32_t)&hi2c->Instance->RXDR, (uint32_t)hi2c->pBuffPtr, hi2c->XferSize) != HAL_OK) + { + /* Call the corresponding callback to inform upper layer of End of Transfer */ + I2C_ITError(hi2c, HAL_I2C_ERROR_DMA); + } + else + { + /* Enable TC interrupts */ + I2C_Enable_IRQ(hi2c, I2C_XFER_RELOAD_IT); + } + } +} + +/** + * @brief DMA I2C slave receive process complete callback. + * @param hdma DMA handle + * @retval None + */ +static void I2C_DMASlaveReceiveCplt(DMA_HandleTypeDef *hdma) +{ + I2C_HandleTypeDef *hi2c = (I2C_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent); /* Derogation MISRAC2012-Rule-11.5 */ + uint32_t tmpoptions = hi2c->XferOptions; + + if ((__HAL_DMA_GET_COUNTER(hi2c->hdmarx) == 0U) && \ + (tmpoptions != I2C_NO_OPTION_FRAME)) + { + /* Disable DMA Request */ + hi2c->Instance->CR1 &= ~I2C_CR1_RXDMAEN; + + /* Call I2C Slave Sequential complete process */ + I2C_ITSlaveSeqCplt(hi2c); + } + else + { + /* No specific action, Master fully manage the generation of STOP condition */ + /* Mean that this generation can arrive at any time, at the end or during DMA process */ + /* So STOP condition should be manage through Interrupt treatment */ + } +} + +/** + * @brief DMA I2C communication error callback. + * @param hdma DMA handle + * @retval None + */ +static void I2C_DMAError(DMA_HandleTypeDef *hdma) +{ + I2C_HandleTypeDef *hi2c = (I2C_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent); /* Derogation MISRAC2012-Rule-11.5 */ + + /* Disable Acknowledge */ + hi2c->Instance->CR2 |= I2C_CR2_NACK; + + /* Call the corresponding callback to inform upper layer of End of Transfer */ + I2C_ITError(hi2c, HAL_I2C_ERROR_DMA); +} + +/** + * @brief DMA I2C communication abort callback + * (To be called at end of DMA Abort procedure). + * @param hdma DMA handle. + * @retval None + */ +static void I2C_DMAAbort(DMA_HandleTypeDef *hdma) +{ + I2C_HandleTypeDef *hi2c = (I2C_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent); /* Derogation MISRAC2012-Rule-11.5 */ + + /* Reset AbortCpltCallback */ + hi2c->hdmatx->XferAbortCallback = NULL; + hi2c->hdmarx->XferAbortCallback = NULL; + + /* Check if come from abort from user */ + if (hi2c->State == HAL_I2C_STATE_ABORT) + { + hi2c->State = HAL_I2C_STATE_READY; + + /* Call the corresponding callback to inform upper layer of End of Transfer */ +#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1) + hi2c->AbortCpltCallback(hi2c); +#else + HAL_I2C_AbortCpltCallback(hi2c); +#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */ + } + else + { + /* Call the corresponding callback to inform upper layer of End of Transfer */ +#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1) + hi2c->ErrorCallback(hi2c); +#else + HAL_I2C_ErrorCallback(hi2c); +#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */ + } +} + +/** + * @brief This function handles I2C Communication Timeout. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param Flag Specifies the I2C flag to check. + * @param Status The new Flag status (SET or RESET). + * @param Timeout Timeout duration + * @param Tickstart Tick start value + * @retval HAL status + */ +static HAL_StatusTypeDef I2C_WaitOnFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Flag, FlagStatus Status, uint32_t Timeout, uint32_t Tickstart) +{ + while (__HAL_I2C_GET_FLAG(hi2c, Flag) == Status) + { + /* Check for the Timeout */ + if (Timeout != HAL_MAX_DELAY) + { + if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U)) + { + hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT; + hi2c->State = HAL_I2C_STATE_READY; + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + return HAL_ERROR; + } + } + } + return HAL_OK; +} + +/** + * @brief This function handles I2C Communication Timeout for specific usage of TXIS flag. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param Timeout Timeout duration + * @param Tickstart Tick start value + * @retval HAL status + */ +static HAL_StatusTypeDef I2C_WaitOnTXISFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Timeout, uint32_t Tickstart) +{ + while (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_TXIS) == RESET) + { + /* Check if a NACK is detected */ + if (I2C_IsAcknowledgeFailed(hi2c, Timeout, Tickstart) != HAL_OK) + { + return HAL_ERROR; + } + + /* Check for the Timeout */ + if (Timeout != HAL_MAX_DELAY) + { + if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U)) + { + hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT; + hi2c->State = HAL_I2C_STATE_READY; + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_ERROR; + } + } + } + return HAL_OK; +} + +/** + * @brief This function handles I2C Communication Timeout for specific usage of STOP flag. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param Timeout Timeout duration + * @param Tickstart Tick start value + * @retval HAL status + */ +static HAL_StatusTypeDef I2C_WaitOnSTOPFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Timeout, uint32_t Tickstart) +{ + while (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_STOPF) == RESET) + { + /* Check if a NACK is detected */ + if (I2C_IsAcknowledgeFailed(hi2c, Timeout, Tickstart) != HAL_OK) + { + return HAL_ERROR; + } + + /* Check for the Timeout */ + if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U)) + { + hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT; + hi2c->State = HAL_I2C_STATE_READY; + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_ERROR; + } + } + return HAL_OK; +} + +/** + * @brief This function handles I2C Communication Timeout for specific usage of RXNE flag. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param Timeout Timeout duration + * @param Tickstart Tick start value + * @retval HAL status + */ +static HAL_StatusTypeDef I2C_WaitOnRXNEFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Timeout, uint32_t Tickstart) +{ + while (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_RXNE) == RESET) + { + /* Check if a NACK is detected */ + if (I2C_IsAcknowledgeFailed(hi2c, Timeout, Tickstart) != HAL_OK) + { + return HAL_ERROR; + } + + /* Check if a STOPF is detected */ + if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_STOPF) == SET) + { + /* Check if an RXNE is pending */ + /* Store Last receive data if any */ + if ((__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_RXNE) == SET) && (hi2c->XferSize > 0U)) + { + /* Return HAL_OK */ + /* The Reading of data from RXDR will be done in caller function */ + return HAL_OK; + } + else + { + /* Clear STOP Flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF); + + /* Clear Configuration Register 2 */ + I2C_RESET_CR2(hi2c); + + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + hi2c->State = HAL_I2C_STATE_READY; + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_ERROR; + } + } + + /* Check for the Timeout */ + if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U)) + { + hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT; + hi2c->State = HAL_I2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_ERROR; + } + } + return HAL_OK; +} + +/** + * @brief This function handles Acknowledge failed detection during an I2C Communication. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param Timeout Timeout duration + * @param Tickstart Tick start value + * @retval HAL status + */ +static HAL_StatusTypeDef I2C_IsAcknowledgeFailed(I2C_HandleTypeDef *hi2c, uint32_t Timeout, uint32_t Tickstart) +{ + if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_AF) == SET) + { + /* Wait until STOP Flag is reset */ + /* AutoEnd should be initiate after AF */ + while (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_STOPF) == RESET) + { + /* Check for the Timeout */ + if (Timeout != HAL_MAX_DELAY) + { + if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U)) + { + hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT; + hi2c->State = HAL_I2C_STATE_READY; + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_ERROR; + } + } + } + + /* Clear NACKF Flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF); + + /* Clear STOP Flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF); + + /* Flush TX register */ + I2C_Flush_TXDR(hi2c); + + /* Clear Configuration Register 2 */ + I2C_RESET_CR2(hi2c); + + hi2c->ErrorCode |= HAL_I2C_ERROR_AF; + hi2c->State = HAL_I2C_STATE_READY; + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_ERROR; + } + return HAL_OK; +} + +/** + * @brief Handles I2Cx communication when starting transfer or during transfer (TC or TCR flag are set). + * @param hi2c I2C handle. + * @param DevAddress Specifies the slave address to be programmed. + * @param Size Specifies the number of bytes to be programmed. + * This parameter must be a value between 0 and 255. + * @param Mode New state of the I2C START condition generation. + * This parameter can be one of the following values: + * @arg @ref I2C_RELOAD_MODE Enable Reload mode . + * @arg @ref I2C_AUTOEND_MODE Enable Automatic end mode. + * @arg @ref I2C_SOFTEND_MODE Enable Software end mode. + * @param Request New state of the I2C START condition generation. + * This parameter can be one of the following values: + * @arg @ref I2C_NO_STARTSTOP Don't Generate stop and start condition. + * @arg @ref I2C_GENERATE_STOP Generate stop condition (Size should be set to 0). + * @arg @ref I2C_GENERATE_START_READ Generate Restart for read request. + * @arg @ref I2C_GENERATE_START_WRITE Generate Restart for write request. + * @retval None + */ +static void I2C_TransferConfig(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t Size, uint32_t Mode, uint32_t Request) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_INSTANCE(hi2c->Instance)); + assert_param(IS_TRANSFER_MODE(Mode)); + assert_param(IS_TRANSFER_REQUEST(Request)); + + /* update CR2 register */ + MODIFY_REG(hi2c->Instance->CR2, ((I2C_CR2_SADD | I2C_CR2_NBYTES | I2C_CR2_RELOAD | I2C_CR2_AUTOEND | (I2C_CR2_RD_WRN & (uint32_t)(Request >> (31U - I2C_CR2_RD_WRN_Pos))) | I2C_CR2_START | I2C_CR2_STOP)), \ + (uint32_t)(((uint32_t)DevAddress & I2C_CR2_SADD) | (((uint32_t)Size << I2C_CR2_NBYTES_Pos) & I2C_CR2_NBYTES) | (uint32_t)Mode | (uint32_t)Request)); +} + +/** + * @brief Manage the enabling of Interrupts. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param InterruptRequest Value of @ref I2C_Interrupt_configuration_definition. + * @retval None + */ +static void I2C_Enable_IRQ(I2C_HandleTypeDef *hi2c, uint16_t InterruptRequest) +{ + uint32_t tmpisr = 0U; + + if ((hi2c->XferISR == I2C_Master_ISR_DMA) || \ + (hi2c->XferISR == I2C_Slave_ISR_DMA)) + { + if ((InterruptRequest & I2C_XFER_LISTEN_IT) == I2C_XFER_LISTEN_IT) + { + /* Enable ERR, STOP, NACK and ADDR interrupts */ + tmpisr |= I2C_IT_ADDRI | I2C_IT_STOPI | I2C_IT_NACKI | I2C_IT_ERRI; + } + + if ((InterruptRequest & I2C_XFER_ERROR_IT) == I2C_XFER_ERROR_IT) + { + /* Enable ERR and NACK interrupts */ + tmpisr |= I2C_IT_ERRI | I2C_IT_NACKI; + } + + if ((InterruptRequest & I2C_XFER_CPLT_IT) == I2C_XFER_CPLT_IT) + { + /* Enable STOP interrupts */ + tmpisr |= I2C_IT_STOPI; + } + + if ((InterruptRequest & I2C_XFER_RELOAD_IT) == I2C_XFER_RELOAD_IT) + { + /* Enable TC interrupts */ + tmpisr |= I2C_IT_TCI; + } + } + else + { + if ((InterruptRequest & I2C_XFER_LISTEN_IT) == I2C_XFER_LISTEN_IT) + { + /* Enable ERR, STOP, NACK, and ADDR interrupts */ + tmpisr |= I2C_IT_ADDRI | I2C_IT_STOPI | I2C_IT_NACKI | I2C_IT_ERRI; + } + + if ((InterruptRequest & I2C_XFER_TX_IT) == I2C_XFER_TX_IT) + { + /* Enable ERR, TC, STOP, NACK and RXI interrupts */ + tmpisr |= I2C_IT_ERRI | I2C_IT_TCI | I2C_IT_STOPI | I2C_IT_NACKI | I2C_IT_TXI; + } + + if ((InterruptRequest & I2C_XFER_RX_IT) == I2C_XFER_RX_IT) + { + /* Enable ERR, TC, STOP, NACK and TXI interrupts */ + tmpisr |= I2C_IT_ERRI | I2C_IT_TCI | I2C_IT_STOPI | I2C_IT_NACKI | I2C_IT_RXI; + } + + else if ((InterruptRequest & I2C_XFER_CPLT_IT) == I2C_XFER_CPLT_IT) + { + /* Enable STOP interrupts */ + tmpisr |= I2C_IT_STOPI; + } + } + + /* Enable interrupts only at the end */ + /* to avoid the risk of I2C interrupt handle execution before */ + /* all interrupts requested done */ + __HAL_I2C_ENABLE_IT(hi2c, tmpisr); +} + +/** + * @brief Manage the disabling of Interrupts. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param InterruptRequest Value of @ref I2C_Interrupt_configuration_definition. + * @retval None + */ +static void I2C_Disable_IRQ(I2C_HandleTypeDef *hi2c, uint16_t InterruptRequest) +{ + uint32_t tmpisr = 0U; + + if ((InterruptRequest & I2C_XFER_TX_IT) == I2C_XFER_TX_IT) + { + /* Disable TC and TXI interrupts */ + tmpisr |= I2C_IT_TCI | I2C_IT_TXI; + + if (((uint32_t)hi2c->State & (uint32_t)HAL_I2C_STATE_LISTEN) != (uint32_t)HAL_I2C_STATE_LISTEN) + { + /* Disable NACK and STOP interrupts */ + tmpisr |= I2C_IT_STOPI | I2C_IT_NACKI | I2C_IT_ERRI; + } + } + + if ((InterruptRequest & I2C_XFER_RX_IT) == I2C_XFER_RX_IT) + { + /* Disable TC and RXI interrupts */ + tmpisr |= I2C_IT_TCI | I2C_IT_RXI; + + if (((uint32_t)hi2c->State & (uint32_t)HAL_I2C_STATE_LISTEN) != (uint32_t)HAL_I2C_STATE_LISTEN) + { + /* Disable NACK and STOP interrupts */ + tmpisr |= I2C_IT_STOPI | I2C_IT_NACKI | I2C_IT_ERRI; + } + } + + if ((InterruptRequest & I2C_XFER_LISTEN_IT) == I2C_XFER_LISTEN_IT) + { + /* Disable ADDR, NACK and STOP interrupts */ + tmpisr |= I2C_IT_ADDRI | I2C_IT_STOPI | I2C_IT_NACKI | I2C_IT_ERRI; + } + + if ((InterruptRequest & I2C_XFER_ERROR_IT) == I2C_XFER_ERROR_IT) + { + /* Enable ERR and NACK interrupts */ + tmpisr |= I2C_IT_ERRI | I2C_IT_NACKI; + } + + if ((InterruptRequest & I2C_XFER_CPLT_IT) == I2C_XFER_CPLT_IT) + { + /* Enable STOP interrupts */ + tmpisr |= I2C_IT_STOPI; + } + + if ((InterruptRequest & I2C_XFER_RELOAD_IT) == I2C_XFER_RELOAD_IT) + { + /* Enable TC interrupts */ + tmpisr |= I2C_IT_TCI; + } + + /* Disable interrupts only at the end */ + /* to avoid a breaking situation like at "t" time */ + /* all disable interrupts request are not done */ + __HAL_I2C_DISABLE_IT(hi2c, tmpisr); +} + +/** + * @brief Convert I2Cx OTHER_xxx XferOptions to functionnal XferOptions. + * @param hi2c I2C handle. + * @retval None + */ +static void I2C_ConvertOtherXferOptions(I2C_HandleTypeDef *hi2c) +{ + /* if user set XferOptions to I2C_OTHER_FRAME */ + /* it request implicitly to generate a restart condition */ + /* set XferOptions to I2C_FIRST_FRAME */ + if (hi2c->XferOptions == I2C_OTHER_FRAME) + { + hi2c->XferOptions = I2C_FIRST_FRAME; + } + /* else if user set XferOptions to I2C_OTHER_AND_LAST_FRAME */ + /* it request implicitly to generate a restart condition */ + /* then generate a stop condition at the end of transfer */ + /* set XferOptions to I2C_FIRST_AND_LAST_FRAME */ + else if (hi2c->XferOptions == I2C_OTHER_AND_LAST_FRAME) + { + hi2c->XferOptions = I2C_FIRST_AND_LAST_FRAME; + } + else + { + /* Nothing to do */ + } +} + +/** + * @} + */ + +#endif /* HAL_I2C_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.c b/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.c new file mode 100644 index 0000000..9dd3af2 --- /dev/null +++ b/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.c @@ -0,0 +1,333 @@ +/** + ****************************************************************************** + * @file stm32f0xx_hal_i2c_ex.c + * @author MCD Application Team + * @brief I2C Extended HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of I2C Extended peripheral: + * + Extended features functions + * + @verbatim + ============================================================================== + ##### I2C peripheral Extended features ##### + ============================================================================== + + [..] Comparing to other previous devices, the I2C interface for STM32F0xx + devices contains the following additional features + + (+) Possibility to disable or enable Analog Noise Filter + (+) Use of a configured Digital Noise Filter + (+) Disable or enable wakeup from Stop mode(s) + (+) Disable or enable Fast Mode Plus + + ##### How to use this driver ##### + ============================================================================== + [..] This driver provides functions to configure Noise Filter and Wake Up Feature + (#) Configure I2C Analog noise filter using the function HAL_I2CEx_ConfigAnalogFilter() + (#) Configure I2C Digital noise filter using the function HAL_I2CEx_ConfigDigitalFilter() + (#) Configure the enable or disable of I2C Wake Up Mode using the functions : + (++) HAL_I2CEx_EnableWakeUp() + (++) HAL_I2CEx_DisableWakeUp() + (#) Configure the enable or disable of fast mode plus driving capability using the functions : + (++) HAL_I2CEx_EnableFastModePlus() + (++) HAL_I2CEx_DisableFastModePlus() + @endverbatim + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2016 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f0xx_hal.h" + +/** @addtogroup STM32F0xx_HAL_Driver + * @{ + */ + +/** @defgroup I2CEx I2CEx + * @brief I2C Extended HAL module driver + * @{ + */ + +#ifdef HAL_I2C_MODULE_ENABLED + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + +/** @defgroup I2CEx_Exported_Functions I2C Extended Exported Functions + * @{ + */ + +/** @defgroup I2CEx_Exported_Functions_Group1 Extended features functions + * @brief Extended features functions + * +@verbatim + =============================================================================== + ##### Extended features functions ##### + =============================================================================== + [..] This section provides functions allowing to: + (+) Configure Noise Filters + (+) Configure Wake Up Feature + (+) Configure Fast Mode Plus + +@endverbatim + * @{ + */ + +/** + * @brief Configure I2C Analog noise filter. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2Cx peripheral. + * @param AnalogFilter New state of the Analog filter. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2CEx_ConfigAnalogFilter(I2C_HandleTypeDef *hi2c, uint32_t AnalogFilter) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_INSTANCE(hi2c->Instance)); + assert_param(IS_I2C_ANALOG_FILTER(AnalogFilter)); + + if (hi2c->State == HAL_I2C_STATE_READY) + { + /* Process Locked */ + __HAL_LOCK(hi2c); + + hi2c->State = HAL_I2C_STATE_BUSY; + + /* Disable the selected I2C peripheral */ + __HAL_I2C_DISABLE(hi2c); + + /* Reset I2Cx ANOFF bit */ + hi2c->Instance->CR1 &= ~(I2C_CR1_ANFOFF); + + /* Set analog filter bit*/ + hi2c->Instance->CR1 |= AnalogFilter; + + __HAL_I2C_ENABLE(hi2c); + + hi2c->State = HAL_I2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Configure I2C Digital noise filter. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2Cx peripheral. + * @param DigitalFilter Coefficient of digital noise filter between Min_Data=0x00 and Max_Data=0x0F. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2CEx_ConfigDigitalFilter(I2C_HandleTypeDef *hi2c, uint32_t DigitalFilter) +{ + uint32_t tmpreg; + + /* Check the parameters */ + assert_param(IS_I2C_ALL_INSTANCE(hi2c->Instance)); + assert_param(IS_I2C_DIGITAL_FILTER(DigitalFilter)); + + if (hi2c->State == HAL_I2C_STATE_READY) + { + /* Process Locked */ + __HAL_LOCK(hi2c); + + hi2c->State = HAL_I2C_STATE_BUSY; + + /* Disable the selected I2C peripheral */ + __HAL_I2C_DISABLE(hi2c); + + /* Get the old register value */ + tmpreg = hi2c->Instance->CR1; + + /* Reset I2Cx DNF bits [11:8] */ + tmpreg &= ~(I2C_CR1_DNF); + + /* Set I2Cx DNF coefficient */ + tmpreg |= DigitalFilter << 8U; + + /* Store the new register value */ + hi2c->Instance->CR1 = tmpreg; + + __HAL_I2C_ENABLE(hi2c); + + hi2c->State = HAL_I2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} +#if defined(I2C_CR1_WUPEN) + +/** + * @brief Enable I2C wakeup from Stop mode(s). + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2Cx peripheral. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2CEx_EnableWakeUp(I2C_HandleTypeDef *hi2c) +{ + /* Check the parameters */ + assert_param(IS_I2C_WAKEUP_FROMSTOP_INSTANCE(hi2c->Instance)); + + if (hi2c->State == HAL_I2C_STATE_READY) + { + /* Process Locked */ + __HAL_LOCK(hi2c); + + hi2c->State = HAL_I2C_STATE_BUSY; + + /* Disable the selected I2C peripheral */ + __HAL_I2C_DISABLE(hi2c); + + /* Enable wakeup from stop mode */ + hi2c->Instance->CR1 |= I2C_CR1_WUPEN; + + __HAL_I2C_ENABLE(hi2c); + + hi2c->State = HAL_I2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Disable I2C wakeup from Stop mode(s). + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2Cx peripheral. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2CEx_DisableWakeUp(I2C_HandleTypeDef *hi2c) +{ + /* Check the parameters */ + assert_param(IS_I2C_WAKEUP_FROMSTOP_INSTANCE(hi2c->Instance)); + + if (hi2c->State == HAL_I2C_STATE_READY) + { + /* Process Locked */ + __HAL_LOCK(hi2c); + + hi2c->State = HAL_I2C_STATE_BUSY; + + /* Disable the selected I2C peripheral */ + __HAL_I2C_DISABLE(hi2c); + + /* Enable wakeup from stop mode */ + hi2c->Instance->CR1 &= ~(I2C_CR1_WUPEN); + + __HAL_I2C_ENABLE(hi2c); + + hi2c->State = HAL_I2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} +#endif + +/** + * @brief Enable the I2C fast mode plus driving capability. + * @param ConfigFastModePlus Selects the pin. + * This parameter can be one of the @ref I2CEx_FastModePlus values + * @note For I2C1, fast mode plus driving capability can be enabled on all selected + * I2C1 pins using I2C_FASTMODEPLUS_I2C1 parameter or independently + * on each one of the following pins PB6, PB7, PB8 and PB9. + * @note For remaining I2C1 pins (PA14, PA15...) fast mode plus driving capability + * can be enabled only by using I2C_FASTMODEPLUS_I2C1 parameter. + * @note For all I2C2 pins fast mode plus driving capability can be enabled + * only by using I2C_FASTMODEPLUS_I2C2 parameter. + * @retval None + */ +void HAL_I2CEx_EnableFastModePlus(uint32_t ConfigFastModePlus) +{ + /* Check the parameter */ + assert_param(IS_I2C_FASTMODEPLUS(ConfigFastModePlus)); + + /* Enable SYSCFG clock */ + __HAL_RCC_SYSCFG_CLK_ENABLE(); + + /* Enable fast mode plus driving capability for selected pin */ + SET_BIT(SYSCFG->CFGR1, (uint32_t)ConfigFastModePlus); +} + +/** + * @brief Disable the I2C fast mode plus driving capability. + * @param ConfigFastModePlus Selects the pin. + * This parameter can be one of the @ref I2CEx_FastModePlus values + * @note For I2C1, fast mode plus driving capability can be disabled on all selected + * I2C1 pins using I2C_FASTMODEPLUS_I2C1 parameter or independently + * on each one of the following pins PB6, PB7, PB8 and PB9. + * @note For remaining I2C1 pins (PA14, PA15...) fast mode plus driving capability + * can be disabled only by using I2C_FASTMODEPLUS_I2C1 parameter. + * @note For all I2C2 pins fast mode plus driving capability can be disabled + * only by using I2C_FASTMODEPLUS_I2C2 parameter. + * @retval None + */ +void HAL_I2CEx_DisableFastModePlus(uint32_t ConfigFastModePlus) +{ + /* Check the parameter */ + assert_param(IS_I2C_FASTMODEPLUS(ConfigFastModePlus)); + + /* Enable SYSCFG clock */ + __HAL_RCC_SYSCFG_CLK_ENABLE(); + + /* Disable fast mode plus driving capability for selected pin */ + CLEAR_BIT(SYSCFG->CFGR1, (uint32_t)ConfigFastModePlus); +} + +/** + * @} + */ + +/** + * @} + */ + +#endif /* HAL_I2C_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.c b/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.c new file mode 100644 index 0000000..f94a7b5 --- /dev/null +++ b/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.c @@ -0,0 +1,1869 @@ +/** + ****************************************************************************** + * @file stm32f0xx_hal_pcd.c + * @author MCD Application Team + * @brief PCD HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the USB Peripheral Controller: + * + Initialization and de-initialization functions + * + IO operation functions + * + Peripheral Control functions + * + Peripheral State functions + * + @verbatim + ============================================================================== + ##### How to use this driver ##### + ============================================================================== + [..] + The PCD HAL driver can be used as follows: + + (#) Declare a PCD_HandleTypeDef handle structure, for example: + PCD_HandleTypeDef hpcd; + + (#) Fill parameters of Init structure in HCD handle + + (#) Call HAL_PCD_Init() API to initialize the PCD peripheral (Core, Device core, ...) + + (#) Initialize the PCD low level resources through the HAL_PCD_MspInit() API: + (##) Enable the PCD/USB Low Level interface clock using + (+++) __HAL_RCC_USB_CLK_ENABLE(); For USB Device only FS peripheral + + (##) Initialize the related GPIO clocks + (##) Configure PCD pin-out + (##) Configure PCD NVIC interrupt + + (#)Associate the Upper USB device stack to the HAL PCD Driver: + (##) hpcd.pData = pdev; + + (#)Enable PCD transmission and reception: + (##) HAL_PCD_Start(); + + @endverbatim + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2016 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f0xx_hal.h" + +/** @addtogroup STM32F0xx_HAL_Driver + * @{ + */ + +/** @defgroup PCD PCD + * @brief PCD HAL module driver + * @{ + */ + +#ifdef HAL_PCD_MODULE_ENABLED + +#if defined (USB) + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/* Private macros ------------------------------------------------------------*/ +/** @defgroup PCD_Private_Macros PCD Private Macros + * @{ + */ +#define PCD_MIN(a, b) (((a) < (b)) ? (a) : (b)) +#define PCD_MAX(a, b) (((a) > (b)) ? (a) : (b)) +/** + * @} + */ + +/* Private functions prototypes ----------------------------------------------*/ +/** @defgroup PCD_Private_Functions PCD Private Functions + * @{ + */ + +static HAL_StatusTypeDef PCD_EP_ISR_Handler(PCD_HandleTypeDef *hpcd); + +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup PCD_Exported_Functions PCD Exported Functions + * @{ + */ + +/** @defgroup PCD_Exported_Functions_Group1 Initialization and de-initialization functions + * @brief Initialization and Configuration functions + * +@verbatim + =============================================================================== + ##### Initialization and de-initialization functions ##### + =============================================================================== + [..] This section provides functions allowing to: + +@endverbatim + * @{ + */ + +/** + * @brief Initializes the PCD according to the specified + * parameters in the PCD_InitTypeDef and initialize the associated handle. + * @param hpcd PCD handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_Init(PCD_HandleTypeDef *hpcd) +{ + uint8_t i; + + /* Check the PCD handle allocation */ + if (hpcd == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_PCD_ALL_INSTANCE(hpcd->Instance)); + + if (hpcd->State == HAL_PCD_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + hpcd->Lock = HAL_UNLOCKED; + +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) + hpcd->SOFCallback = HAL_PCD_SOFCallback; + hpcd->SetupStageCallback = HAL_PCD_SetupStageCallback; + hpcd->ResetCallback = HAL_PCD_ResetCallback; + hpcd->SuspendCallback = HAL_PCD_SuspendCallback; + hpcd->ResumeCallback = HAL_PCD_ResumeCallback; + hpcd->ConnectCallback = HAL_PCD_ConnectCallback; + hpcd->DisconnectCallback = HAL_PCD_DisconnectCallback; + hpcd->DataOutStageCallback = HAL_PCD_DataOutStageCallback; + hpcd->DataInStageCallback = HAL_PCD_DataInStageCallback; + hpcd->ISOOUTIncompleteCallback = HAL_PCD_ISOOUTIncompleteCallback; + hpcd->ISOINIncompleteCallback = HAL_PCD_ISOINIncompleteCallback; + hpcd->LPMCallback = HAL_PCDEx_LPM_Callback; + hpcd->BCDCallback = HAL_PCDEx_BCD_Callback; + + if (hpcd->MspInitCallback == NULL) + { + hpcd->MspInitCallback = HAL_PCD_MspInit; + } + + /* Init the low level hardware */ + hpcd->MspInitCallback(hpcd); +#else + /* Init the low level hardware : GPIO, CLOCK, NVIC... */ + HAL_PCD_MspInit(hpcd); +#endif /* (USE_HAL_PCD_REGISTER_CALLBACKS) */ + } + + hpcd->State = HAL_PCD_STATE_BUSY; + + /* Disable the Interrupts */ + __HAL_PCD_DISABLE(hpcd); + + /* Init endpoints structures */ + for (i = 0U; i < hpcd->Init.dev_endpoints; i++) + { + /* Init ep structure */ + hpcd->IN_ep[i].is_in = 1U; + hpcd->IN_ep[i].num = i; + hpcd->IN_ep[i].tx_fifo_num = i; + /* Control until ep is activated */ + hpcd->IN_ep[i].type = EP_TYPE_CTRL; + hpcd->IN_ep[i].maxpacket = 0U; + hpcd->IN_ep[i].xfer_buff = 0U; + hpcd->IN_ep[i].xfer_len = 0U; + } + + for (i = 0U; i < hpcd->Init.dev_endpoints; i++) + { + hpcd->OUT_ep[i].is_in = 0U; + hpcd->OUT_ep[i].num = i; + /* Control until ep is activated */ + hpcd->OUT_ep[i].type = EP_TYPE_CTRL; + hpcd->OUT_ep[i].maxpacket = 0U; + hpcd->OUT_ep[i].xfer_buff = 0U; + hpcd->OUT_ep[i].xfer_len = 0U; + } + + /* Init Device */ + (void)USB_DevInit(hpcd->Instance, hpcd->Init); + + hpcd->USB_Address = 0U; + hpcd->State = HAL_PCD_STATE_READY; + + /* Activate LPM */ + if (hpcd->Init.lpm_enable == 1U) + { + (void)HAL_PCDEx_ActivateLPM(hpcd); + } + + return HAL_OK; +} + +/** + * @brief DeInitializes the PCD peripheral. + * @param hpcd PCD handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_DeInit(PCD_HandleTypeDef *hpcd) +{ + /* Check the PCD handle allocation */ + if (hpcd == NULL) + { + return HAL_ERROR; + } + + hpcd->State = HAL_PCD_STATE_BUSY; + + /* Stop Device */ + (void)HAL_PCD_Stop(hpcd); + +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) + if (hpcd->MspDeInitCallback == NULL) + { + hpcd->MspDeInitCallback = HAL_PCD_MspDeInit; /* Legacy weak MspDeInit */ + } + + /* DeInit the low level hardware */ + hpcd->MspDeInitCallback(hpcd); +#else + /* DeInit the low level hardware: CLOCK, NVIC.*/ + HAL_PCD_MspDeInit(hpcd); +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ + + hpcd->State = HAL_PCD_STATE_RESET; + + return HAL_OK; +} + +/** + * @brief Initializes the PCD MSP. + * @param hpcd PCD handle + * @retval None + */ +__weak void HAL_PCD_MspInit(PCD_HandleTypeDef *hpcd) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hpcd); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_PCD_MspInit could be implemented in the user file + */ +} + +/** + * @brief DeInitializes PCD MSP. + * @param hpcd PCD handle + * @retval None + */ +__weak void HAL_PCD_MspDeInit(PCD_HandleTypeDef *hpcd) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hpcd); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_PCD_MspDeInit could be implemented in the user file + */ +} + +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) +/** + * @brief Register a User USB PCD Callback + * To be used instead of the weak predefined callback + * @param hpcd USB PCD handle + * @param CallbackID ID of the callback to be registered + * This parameter can be one of the following values: + * @arg @ref HAL_PCD_SOF_CB_ID USB PCD SOF callback ID + * @arg @ref HAL_PCD_SETUPSTAGE_CB_ID USB PCD Setup callback ID + * @arg @ref HAL_PCD_RESET_CB_ID USB PCD Reset callback ID + * @arg @ref HAL_PCD_SUSPEND_CB_ID USB PCD Suspend callback ID + * @arg @ref HAL_PCD_RESUME_CB_ID USB PCD Resume callback ID + * @arg @ref HAL_PCD_CONNECT_CB_ID USB PCD Connect callback ID + * @arg @ref HAL_PCD_DISCONNECT_CB_ID OTG PCD Disconnect callback ID + * @arg @ref HAL_PCD_MSPINIT_CB_ID MspDeInit callback ID + * @arg @ref HAL_PCD_MSPDEINIT_CB_ID MspDeInit callback ID + * @param pCallback pointer to the Callback function + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_RegisterCallback(PCD_HandleTypeDef *hpcd, HAL_PCD_CallbackIDTypeDef CallbackID, pPCD_CallbackTypeDef pCallback) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (pCallback == NULL) + { + /* Update the error code */ + hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; + return HAL_ERROR; + } + /* Process locked */ + __HAL_LOCK(hpcd); + + if (hpcd->State == HAL_PCD_STATE_READY) + { + switch (CallbackID) + { + case HAL_PCD_SOF_CB_ID : + hpcd->SOFCallback = pCallback; + break; + + case HAL_PCD_SETUPSTAGE_CB_ID : + hpcd->SetupStageCallback = pCallback; + break; + + case HAL_PCD_RESET_CB_ID : + hpcd->ResetCallback = pCallback; + break; + + case HAL_PCD_SUSPEND_CB_ID : + hpcd->SuspendCallback = pCallback; + break; + + case HAL_PCD_RESUME_CB_ID : + hpcd->ResumeCallback = pCallback; + break; + + case HAL_PCD_CONNECT_CB_ID : + hpcd->ConnectCallback = pCallback; + break; + + case HAL_PCD_DISCONNECT_CB_ID : + hpcd->DisconnectCallback = pCallback; + break; + + case HAL_PCD_MSPINIT_CB_ID : + hpcd->MspInitCallback = pCallback; + break; + + case HAL_PCD_MSPDEINIT_CB_ID : + hpcd->MspDeInitCallback = pCallback; + break; + + default : + /* Update the error code */ + hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else if (hpcd->State == HAL_PCD_STATE_RESET) + { + switch (CallbackID) + { + case HAL_PCD_MSPINIT_CB_ID : + hpcd->MspInitCallback = pCallback; + break; + + case HAL_PCD_MSPDEINIT_CB_ID : + hpcd->MspDeInitCallback = pCallback; + break; + + default : + /* Update the error code */ + hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else + { + /* Update the error code */ + hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; + /* Return error status */ + status = HAL_ERROR; + } + + /* Release Lock */ + __HAL_UNLOCK(hpcd); + return status; +} + +/** + * @brief Unregister an USB PCD Callback + * USB PCD callabck is redirected to the weak predefined callback + * @param hpcd USB PCD handle + * @param CallbackID ID of the callback to be unregistered + * This parameter can be one of the following values: + * @arg @ref HAL_PCD_SOF_CB_ID USB PCD SOF callback ID + * @arg @ref HAL_PCD_SETUPSTAGE_CB_ID USB PCD Setup callback ID + * @arg @ref HAL_PCD_RESET_CB_ID USB PCD Reset callback ID + * @arg @ref HAL_PCD_SUSPEND_CB_ID USB PCD Suspend callback ID + * @arg @ref HAL_PCD_RESUME_CB_ID USB PCD Resume callback ID + * @arg @ref HAL_PCD_CONNECT_CB_ID USB PCD Connect callback ID + * @arg @ref HAL_PCD_DISCONNECT_CB_ID OTG PCD Disconnect callback ID + * @arg @ref HAL_PCD_MSPINIT_CB_ID MspDeInit callback ID + * @arg @ref HAL_PCD_MSPDEINIT_CB_ID MspDeInit callback ID + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_UnRegisterCallback(PCD_HandleTypeDef *hpcd, HAL_PCD_CallbackIDTypeDef CallbackID) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Process locked */ + __HAL_LOCK(hpcd); + + /* Setup Legacy weak Callbacks */ + if (hpcd->State == HAL_PCD_STATE_READY) + { + switch (CallbackID) + { + case HAL_PCD_SOF_CB_ID : + hpcd->SOFCallback = HAL_PCD_SOFCallback; + break; + + case HAL_PCD_SETUPSTAGE_CB_ID : + hpcd->SetupStageCallback = HAL_PCD_SetupStageCallback; + break; + + case HAL_PCD_RESET_CB_ID : + hpcd->ResetCallback = HAL_PCD_ResetCallback; + break; + + case HAL_PCD_SUSPEND_CB_ID : + hpcd->SuspendCallback = HAL_PCD_SuspendCallback; + break; + + case HAL_PCD_RESUME_CB_ID : + hpcd->ResumeCallback = HAL_PCD_ResumeCallback; + break; + + case HAL_PCD_CONNECT_CB_ID : + hpcd->ConnectCallback = HAL_PCD_ConnectCallback; + break; + + case HAL_PCD_DISCONNECT_CB_ID : + hpcd->DisconnectCallback = HAL_PCD_DisconnectCallback; + break; + + case HAL_PCD_MSPINIT_CB_ID : + hpcd->MspInitCallback = HAL_PCD_MspInit; + break; + + case HAL_PCD_MSPDEINIT_CB_ID : + hpcd->MspDeInitCallback = HAL_PCD_MspDeInit; + break; + + default : + /* Update the error code */ + hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else if (hpcd->State == HAL_PCD_STATE_RESET) + { + switch (CallbackID) + { + case HAL_PCD_MSPINIT_CB_ID : + hpcd->MspInitCallback = HAL_PCD_MspInit; + break; + + case HAL_PCD_MSPDEINIT_CB_ID : + hpcd->MspDeInitCallback = HAL_PCD_MspDeInit; + break; + + default : + /* Update the error code */ + hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else + { + /* Update the error code */ + hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + } + + /* Release Lock */ + __HAL_UNLOCK(hpcd); + return status; +} + +/** + * @brief Register USB PCD Data OUT Stage Callback + * To be used instead of the weak HAL_PCD_DataOutStageCallback() predefined callback + * @param hpcd PCD handle + * @param pCallback pointer to the USB PCD Data OUT Stage Callback function + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_RegisterDataOutStageCallback(PCD_HandleTypeDef *hpcd, pPCD_DataOutStageCallbackTypeDef pCallback) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (pCallback == NULL) + { + /* Update the error code */ + hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; + + return HAL_ERROR; + } + + /* Process locked */ + __HAL_LOCK(hpcd); + + if (hpcd->State == HAL_PCD_STATE_READY) + { + hpcd->DataOutStageCallback = pCallback; + } + else + { + /* Update the error code */ + hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + } + + /* Release Lock */ + __HAL_UNLOCK(hpcd); + + return status; +} + +/** + * @brief UnRegister the USB PCD Data OUT Stage Callback + * USB PCD Data OUT Stage Callback is redirected to the weak HAL_PCD_DataOutStageCallback() predefined callback + * @param hpcd PCD handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_UnRegisterDataOutStageCallback(PCD_HandleTypeDef *hpcd) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Process locked */ + __HAL_LOCK(hpcd); + + if (hpcd->State == HAL_PCD_STATE_READY) + { + hpcd->DataOutStageCallback = HAL_PCD_DataOutStageCallback; /* Legacy weak DataOutStageCallback */ + } + else + { + /* Update the error code */ + hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + } + + /* Release Lock */ + __HAL_UNLOCK(hpcd); + + return status; +} + +/** + * @brief Register USB PCD Data IN Stage Callback + * To be used instead of the weak HAL_PCD_DataInStageCallback() predefined callback + * @param hpcd PCD handle + * @param pCallback pointer to the USB PCD Data IN Stage Callback function + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_RegisterDataInStageCallback(PCD_HandleTypeDef *hpcd, pPCD_DataInStageCallbackTypeDef pCallback) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (pCallback == NULL) + { + /* Update the error code */ + hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; + + return HAL_ERROR; + } + + /* Process locked */ + __HAL_LOCK(hpcd); + + if (hpcd->State == HAL_PCD_STATE_READY) + { + hpcd->DataInStageCallback = pCallback; + } + else + { + /* Update the error code */ + hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + } + + /* Release Lock */ + __HAL_UNLOCK(hpcd); + + return status; +} + +/** + * @brief UnRegister the USB PCD Data IN Stage Callback + * USB PCD Data OUT Stage Callback is redirected to the weak HAL_PCD_DataInStageCallback() predefined callback + * @param hpcd PCD handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_UnRegisterDataInStageCallback(PCD_HandleTypeDef *hpcd) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Process locked */ + __HAL_LOCK(hpcd); + + if (hpcd->State == HAL_PCD_STATE_READY) + { + hpcd->DataInStageCallback = HAL_PCD_DataInStageCallback; /* Legacy weak DataInStageCallback */ + } + else + { + /* Update the error code */ + hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + } + + /* Release Lock */ + __HAL_UNLOCK(hpcd); + + return status; +} + +/** + * @brief Register USB PCD Iso OUT incomplete Callback + * To be used instead of the weak HAL_PCD_ISOOUTIncompleteCallback() predefined callback + * @param hpcd PCD handle + * @param pCallback pointer to the USB PCD Iso OUT incomplete Callback function + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_RegisterIsoOutIncpltCallback(PCD_HandleTypeDef *hpcd, pPCD_IsoOutIncpltCallbackTypeDef pCallback) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (pCallback == NULL) + { + /* Update the error code */ + hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; + + return HAL_ERROR; + } + + /* Process locked */ + __HAL_LOCK(hpcd); + + if (hpcd->State == HAL_PCD_STATE_READY) + { + hpcd->ISOOUTIncompleteCallback = pCallback; + } + else + { + /* Update the error code */ + hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + } + + /* Release Lock */ + __HAL_UNLOCK(hpcd); + + return status; +} + +/** + * @brief UnRegister the USB PCD Iso OUT incomplete Callback + * USB PCD Iso OUT incomplete Callback is redirected to the weak HAL_PCD_ISOOUTIncompleteCallback() predefined callback + * @param hpcd PCD handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_UnRegisterIsoOutIncpltCallback(PCD_HandleTypeDef *hpcd) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Process locked */ + __HAL_LOCK(hpcd); + + if (hpcd->State == HAL_PCD_STATE_READY) + { + hpcd->ISOOUTIncompleteCallback = HAL_PCD_ISOOUTIncompleteCallback; /* Legacy weak ISOOUTIncompleteCallback */ + } + else + { + /* Update the error code */ + hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + } + + /* Release Lock */ + __HAL_UNLOCK(hpcd); + + return status; +} + +/** + * @brief Register USB PCD Iso IN incomplete Callback + * To be used instead of the weak HAL_PCD_ISOINIncompleteCallback() predefined callback + * @param hpcd PCD handle + * @param pCallback pointer to the USB PCD Iso IN incomplete Callback function + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_RegisterIsoInIncpltCallback(PCD_HandleTypeDef *hpcd, pPCD_IsoInIncpltCallbackTypeDef pCallback) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (pCallback == NULL) + { + /* Update the error code */ + hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; + + return HAL_ERROR; + } + + /* Process locked */ + __HAL_LOCK(hpcd); + + if (hpcd->State == HAL_PCD_STATE_READY) + { + hpcd->ISOINIncompleteCallback = pCallback; + } + else + { + /* Update the error code */ + hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + } + + /* Release Lock */ + __HAL_UNLOCK(hpcd); + + return status; +} + +/** + * @brief UnRegister the USB PCD Iso IN incomplete Callback + * USB PCD Iso IN incomplete Callback is redirected to the weak HAL_PCD_ISOINIncompleteCallback() predefined callback + * @param hpcd PCD handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_UnRegisterIsoInIncpltCallback(PCD_HandleTypeDef *hpcd) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Process locked */ + __HAL_LOCK(hpcd); + + if (hpcd->State == HAL_PCD_STATE_READY) + { + hpcd->ISOINIncompleteCallback = HAL_PCD_ISOINIncompleteCallback; /* Legacy weak ISOINIncompleteCallback */ + } + else + { + /* Update the error code */ + hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + } + + /* Release Lock */ + __HAL_UNLOCK(hpcd); + + return status; +} + +/** + * @brief Register USB PCD BCD Callback + * To be used instead of the weak HAL_PCDEx_BCD_Callback() predefined callback + * @param hpcd PCD handle + * @param pCallback pointer to the USB PCD BCD Callback function + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_RegisterBcdCallback(PCD_HandleTypeDef *hpcd, pPCD_BcdCallbackTypeDef pCallback) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (pCallback == NULL) + { + /* Update the error code */ + hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; + + return HAL_ERROR; + } + + /* Process locked */ + __HAL_LOCK(hpcd); + + if (hpcd->State == HAL_PCD_STATE_READY) + { + hpcd->BCDCallback = pCallback; + } + else + { + /* Update the error code */ + hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + } + + /* Release Lock */ + __HAL_UNLOCK(hpcd); + + return status; +} + +/** + * @brief UnRegister the USB PCD BCD Callback + * USB BCD Callback is redirected to the weak HAL_PCDEx_BCD_Callback() predefined callback + * @param hpcd PCD handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_UnRegisterBcdCallback(PCD_HandleTypeDef *hpcd) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Process locked */ + __HAL_LOCK(hpcd); + + if (hpcd->State == HAL_PCD_STATE_READY) + { + hpcd->BCDCallback = HAL_PCDEx_BCD_Callback; /* Legacy weak HAL_PCDEx_BCD_Callback */ + } + else + { + /* Update the error code */ + hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + } + + /* Release Lock */ + __HAL_UNLOCK(hpcd); + + return status; +} + +/** + * @brief Register USB PCD LPM Callback + * To be used instead of the weak HAL_PCDEx_LPM_Callback() predefined callback + * @param hpcd PCD handle + * @param pCallback pointer to the USB PCD LPM Callback function + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_RegisterLpmCallback(PCD_HandleTypeDef *hpcd, pPCD_LpmCallbackTypeDef pCallback) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (pCallback == NULL) + { + /* Update the error code */ + hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; + + return HAL_ERROR; + } + + /* Process locked */ + __HAL_LOCK(hpcd); + + if (hpcd->State == HAL_PCD_STATE_READY) + { + hpcd->LPMCallback = pCallback; + } + else + { + /* Update the error code */ + hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + } + + /* Release Lock */ + __HAL_UNLOCK(hpcd); + + return status; +} + +/** + * @brief UnRegister the USB PCD LPM Callback + * USB LPM Callback is redirected to the weak HAL_PCDEx_LPM_Callback() predefined callback + * @param hpcd PCD handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_UnRegisterLpmCallback(PCD_HandleTypeDef *hpcd) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Process locked */ + __HAL_LOCK(hpcd); + + if (hpcd->State == HAL_PCD_STATE_READY) + { + hpcd->LPMCallback = HAL_PCDEx_LPM_Callback; /* Legacy weak HAL_PCDEx_LPM_Callback */ + } + else + { + /* Update the error code */ + hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + } + + /* Release Lock */ + __HAL_UNLOCK(hpcd); + + return status; +} +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ + +/** + * @} + */ + +/** @defgroup PCD_Exported_Functions_Group2 Input and Output operation functions + * @brief Data transfers functions + * +@verbatim + =============================================================================== + ##### IO operation functions ##### + =============================================================================== + [..] + This subsection provides a set of functions allowing to manage the PCD data + transfers. + +@endverbatim + * @{ + */ + +/** + * @brief Start the USB device + * @param hpcd PCD handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_Start(PCD_HandleTypeDef *hpcd) +{ + __HAL_LOCK(hpcd); + (void)USB_DevConnect(hpcd->Instance); + __HAL_PCD_ENABLE(hpcd); + __HAL_UNLOCK(hpcd); + return HAL_OK; +} + +/** + * @brief Stop the USB device. + * @param hpcd PCD handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_Stop(PCD_HandleTypeDef *hpcd) +{ + __HAL_LOCK(hpcd); + __HAL_PCD_DISABLE(hpcd); + + (void)USB_StopDevice(hpcd->Instance); + + __HAL_UNLOCK(hpcd); + + return HAL_OK; +} + + +/** + * @brief This function handles PCD interrupt request. + * @param hpcd PCD handle + * @retval HAL status + */ +void HAL_PCD_IRQHandler(PCD_HandleTypeDef *hpcd) +{ + if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_CTR)) + { + /* servicing of the endpoint correct transfer interrupt */ + /* clear of the CTR flag into the sub */ + (void)PCD_EP_ISR_Handler(hpcd); + } + + if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_RESET)) + { + __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_RESET); + +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) + hpcd->ResetCallback(hpcd); +#else + HAL_PCD_ResetCallback(hpcd); +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ + + (void)HAL_PCD_SetAddress(hpcd, 0U); + } + + if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_PMAOVR)) + { + __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_PMAOVR); + } + + if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_ERR)) + { + __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_ERR); + } + + if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_WKUP)) + { + hpcd->Instance->CNTR &= (uint16_t) ~(USB_CNTR_LPMODE); + hpcd->Instance->CNTR &= (uint16_t) ~(USB_CNTR_FSUSP); + + if (hpcd->LPM_State == LPM_L1) + { + hpcd->LPM_State = LPM_L0; +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) + hpcd->LPMCallback(hpcd, PCD_LPM_L0_ACTIVE); +#else + HAL_PCDEx_LPM_Callback(hpcd, PCD_LPM_L0_ACTIVE); +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ + } + +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) + hpcd->ResumeCallback(hpcd); +#else + HAL_PCD_ResumeCallback(hpcd); +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ + + __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_WKUP); + } + + if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_SUSP)) + { + /* Force low-power mode in the macrocell */ + hpcd->Instance->CNTR |= USB_CNTR_FSUSP; + + /* clear of the ISTR bit must be done after setting of CNTR_FSUSP */ + __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_SUSP); + + hpcd->Instance->CNTR |= USB_CNTR_LPMODE; + + if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_WKUP) == 0U) + { +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) + hpcd->SuspendCallback(hpcd); +#else + HAL_PCD_SuspendCallback(hpcd); +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ + } + } + + /* Handle LPM Interrupt */ + if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_L1REQ)) + { + __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_L1REQ); + if (hpcd->LPM_State == LPM_L0) + { + /* Force suspend and low-power mode before going to L1 state*/ + hpcd->Instance->CNTR |= USB_CNTR_LPMODE; + hpcd->Instance->CNTR |= USB_CNTR_FSUSP; + + hpcd->LPM_State = LPM_L1; + hpcd->BESL = ((uint32_t)hpcd->Instance->LPMCSR & USB_LPMCSR_BESL) >> 2; +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) + hpcd->LPMCallback(hpcd, PCD_LPM_L1_ACTIVE); +#else + HAL_PCDEx_LPM_Callback(hpcd, PCD_LPM_L1_ACTIVE); +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ + } + else + { +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) + hpcd->SuspendCallback(hpcd); +#else + HAL_PCD_SuspendCallback(hpcd); +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ + } + } + + if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_SOF)) + { + __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_SOF); + +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) + hpcd->SOFCallback(hpcd); +#else + HAL_PCD_SOFCallback(hpcd); +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ + } + + if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_ESOF)) + { + /* clear ESOF flag in ISTR */ + __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_ESOF); + } +} + + +/** + * @brief Data OUT stage callback. + * @param hpcd PCD handle + * @param epnum endpoint number + * @retval None + */ +__weak void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hpcd); + UNUSED(epnum); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_PCD_DataOutStageCallback could be implemented in the user file + */ +} + +/** + * @brief Data IN stage callback + * @param hpcd PCD handle + * @param epnum endpoint number + * @retval None + */ +__weak void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hpcd); + UNUSED(epnum); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_PCD_DataInStageCallback could be implemented in the user file + */ +} +/** + * @brief Setup stage callback + * @param hpcd PCD handle + * @retval None + */ +__weak void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hpcd); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_PCD_SetupStageCallback could be implemented in the user file + */ +} + +/** + * @brief USB Start Of Frame callback. + * @param hpcd PCD handle + * @retval None + */ +__weak void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hpcd); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_PCD_SOFCallback could be implemented in the user file + */ +} + +/** + * @brief USB Reset callback. + * @param hpcd PCD handle + * @retval None + */ +__weak void HAL_PCD_ResetCallback(PCD_HandleTypeDef *hpcd) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hpcd); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_PCD_ResetCallback could be implemented in the user file + */ +} + +/** + * @brief Suspend event callback. + * @param hpcd PCD handle + * @retval None + */ +__weak void HAL_PCD_SuspendCallback(PCD_HandleTypeDef *hpcd) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hpcd); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_PCD_SuspendCallback could be implemented in the user file + */ +} + +/** + * @brief Resume event callback. + * @param hpcd PCD handle + * @retval None + */ +__weak void HAL_PCD_ResumeCallback(PCD_HandleTypeDef *hpcd) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hpcd); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_PCD_ResumeCallback could be implemented in the user file + */ +} + +/** + * @brief Incomplete ISO OUT callback. + * @param hpcd PCD handle + * @param epnum endpoint number + * @retval None + */ +__weak void HAL_PCD_ISOOUTIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hpcd); + UNUSED(epnum); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_PCD_ISOOUTIncompleteCallback could be implemented in the user file + */ +} + +/** + * @brief Incomplete ISO IN callback. + * @param hpcd PCD handle + * @param epnum endpoint number + * @retval None + */ +__weak void HAL_PCD_ISOINIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hpcd); + UNUSED(epnum); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_PCD_ISOINIncompleteCallback could be implemented in the user file + */ +} + +/** + * @brief Connection event callback. + * @param hpcd PCD handle + * @retval None + */ +__weak void HAL_PCD_ConnectCallback(PCD_HandleTypeDef *hpcd) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hpcd); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_PCD_ConnectCallback could be implemented in the user file + */ +} + +/** + * @brief Disconnection event callback. + * @param hpcd PCD handle + * @retval None + */ +__weak void HAL_PCD_DisconnectCallback(PCD_HandleTypeDef *hpcd) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hpcd); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_PCD_DisconnectCallback could be implemented in the user file + */ +} + +/** + * @} + */ + +/** @defgroup PCD_Exported_Functions_Group3 Peripheral Control functions + * @brief management functions + * +@verbatim + =============================================================================== + ##### Peripheral Control functions ##### + =============================================================================== + [..] + This subsection provides a set of functions allowing to control the PCD data + transfers. + +@endverbatim + * @{ + */ + +/** + * @brief Connect the USB device + * @param hpcd PCD handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_DevConnect(PCD_HandleTypeDef *hpcd) +{ + __HAL_LOCK(hpcd); + (void)USB_DevConnect(hpcd->Instance); + __HAL_UNLOCK(hpcd); + return HAL_OK; +} + +/** + * @brief Disconnect the USB device. + * @param hpcd PCD handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_DevDisconnect(PCD_HandleTypeDef *hpcd) +{ + __HAL_LOCK(hpcd); + (void)USB_DevDisconnect(hpcd->Instance); + __HAL_UNLOCK(hpcd); + return HAL_OK; +} + +/** + * @brief Set the USB Device address. + * @param hpcd PCD handle + * @param address new device address + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_SetAddress(PCD_HandleTypeDef *hpcd, uint8_t address) +{ + __HAL_LOCK(hpcd); + hpcd->USB_Address = address; + (void)USB_SetDevAddress(hpcd->Instance, address); + __HAL_UNLOCK(hpcd); + return HAL_OK; +} +/** + * @brief Open and configure an endpoint. + * @param hpcd PCD handle + * @param ep_addr endpoint address + * @param ep_mps endpoint max packet size + * @param ep_type endpoint type + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_EP_Open(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint16_t ep_mps, uint8_t ep_type) +{ + HAL_StatusTypeDef ret = HAL_OK; + PCD_EPTypeDef *ep; + + if ((ep_addr & 0x80U) == 0x80U) + { + ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK]; + ep->is_in = 1U; + } + else + { + ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK]; + ep->is_in = 0U; + } + + ep->num = ep_addr & EP_ADDR_MSK; + ep->maxpacket = ep_mps; + ep->type = ep_type; + + if (ep->is_in != 0U) + { + /* Assign a Tx FIFO */ + ep->tx_fifo_num = ep->num; + } + /* Set initial data PID. */ + if (ep_type == EP_TYPE_BULK) + { + ep->data_pid_start = 0U; + } + + __HAL_LOCK(hpcd); + (void)USB_ActivateEndpoint(hpcd->Instance, ep); + __HAL_UNLOCK(hpcd); + + return ret; +} + +/** + * @brief Deactivate an endpoint. + * @param hpcd PCD handle + * @param ep_addr endpoint address + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_EP_Close(PCD_HandleTypeDef *hpcd, uint8_t ep_addr) +{ + PCD_EPTypeDef *ep; + + if ((ep_addr & 0x80U) == 0x80U) + { + ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK]; + ep->is_in = 1U; + } + else + { + ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK]; + ep->is_in = 0U; + } + ep->num = ep_addr & EP_ADDR_MSK; + + __HAL_LOCK(hpcd); + (void)USB_DeactivateEndpoint(hpcd->Instance, ep); + __HAL_UNLOCK(hpcd); + return HAL_OK; +} + + +/** + * @brief Receive an amount of data. + * @param hpcd PCD handle + * @param ep_addr endpoint address + * @param pBuf pointer to the reception buffer + * @param len amount of data to be received + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_EP_Receive(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len) +{ + PCD_EPTypeDef *ep; + + ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK]; + + /*setup and start the Xfer */ + ep->xfer_buff = pBuf; + ep->xfer_len = len; + ep->xfer_count = 0U; + ep->is_in = 0U; + ep->num = ep_addr & EP_ADDR_MSK; + + if ((ep_addr & EP_ADDR_MSK) == 0U) + { + (void)USB_EP0StartXfer(hpcd->Instance, ep); + } + else + { + (void)USB_EPStartXfer(hpcd->Instance, ep); + } + + return HAL_OK; +} + +/** + * @brief Get Received Data Size + * @param hpcd PCD handle + * @param ep_addr endpoint address + * @retval Data Size + */ +uint32_t HAL_PCD_EP_GetRxCount(PCD_HandleTypeDef *hpcd, uint8_t ep_addr) +{ + return hpcd->OUT_ep[ep_addr & EP_ADDR_MSK].xfer_count; +} +/** + * @brief Send an amount of data + * @param hpcd PCD handle + * @param ep_addr endpoint address + * @param pBuf pointer to the transmission buffer + * @param len amount of data to be sent + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_EP_Transmit(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len) +{ + PCD_EPTypeDef *ep; + + ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK]; + + /*setup and start the Xfer */ + ep->xfer_buff = pBuf; + ep->xfer_len = len; + ep->xfer_count = 0U; + ep->is_in = 1U; + ep->num = ep_addr & EP_ADDR_MSK; + + if ((ep_addr & EP_ADDR_MSK) == 0U) + { + (void)USB_EP0StartXfer(hpcd->Instance, ep); + } + else + { + (void)USB_EPStartXfer(hpcd->Instance, ep); + } + + return HAL_OK; +} + +/** + * @brief Set a STALL condition over an endpoint + * @param hpcd PCD handle + * @param ep_addr endpoint address + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_EP_SetStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr) +{ + PCD_EPTypeDef *ep; + + if (((uint32_t)ep_addr & EP_ADDR_MSK) > hpcd->Init.dev_endpoints) + { + return HAL_ERROR; + } + + if ((0x80U & ep_addr) == 0x80U) + { + ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK]; + ep->is_in = 1U; + } + else + { + ep = &hpcd->OUT_ep[ep_addr]; + ep->is_in = 0U; + } + + ep->is_stall = 1U; + ep->num = ep_addr & EP_ADDR_MSK; + + __HAL_LOCK(hpcd); + + (void)USB_EPSetStall(hpcd->Instance, ep); + if ((ep_addr & EP_ADDR_MSK) == 0U) + { + (void)USB_EP0_OutStart(hpcd->Instance, (uint8_t *)hpcd->Setup); + } + __HAL_UNLOCK(hpcd); + + return HAL_OK; +} + +/** + * @brief Clear a STALL condition over in an endpoint + * @param hpcd PCD handle + * @param ep_addr endpoint address + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_EP_ClrStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr) +{ + PCD_EPTypeDef *ep; + + if (((uint32_t)ep_addr & 0x0FU) > hpcd->Init.dev_endpoints) + { + return HAL_ERROR; + } + + if ((0x80U & ep_addr) == 0x80U) + { + ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK]; + ep->is_in = 1U; + } + else + { + ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK]; + ep->is_in = 0U; + } + + ep->is_stall = 0U; + ep->num = ep_addr & EP_ADDR_MSK; + + __HAL_LOCK(hpcd); + (void)USB_EPClearStall(hpcd->Instance, ep); + __HAL_UNLOCK(hpcd); + + return HAL_OK; +} + +/** + * @brief Flush an endpoint + * @param hpcd PCD handle + * @param ep_addr endpoint address + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_EP_Flush(PCD_HandleTypeDef *hpcd, uint8_t ep_addr) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hpcd); + UNUSED(ep_addr); + + return HAL_OK; +} + +/** + * @brief Activate remote wakeup signalling + * @param hpcd PCD handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_ActivateRemoteWakeup(PCD_HandleTypeDef *hpcd) +{ + return (USB_ActivateRemoteWakeup(hpcd->Instance)); +} + +/** + * @brief De-activate remote wakeup signalling. + * @param hpcd PCD handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_DeActivateRemoteWakeup(PCD_HandleTypeDef *hpcd) +{ + return (USB_DeActivateRemoteWakeup(hpcd->Instance)); +} + +/** + * @} + */ + +/** @defgroup PCD_Exported_Functions_Group4 Peripheral State functions + * @brief Peripheral State functions + * +@verbatim + =============================================================================== + ##### Peripheral State functions ##### + =============================================================================== + [..] + This subsection permits to get in run-time the status of the peripheral + and the data flow. + +@endverbatim + * @{ + */ + +/** + * @brief Return the PCD handle state. + * @param hpcd PCD handle + * @retval HAL state + */ +PCD_StateTypeDef HAL_PCD_GetState(PCD_HandleTypeDef *hpcd) +{ + return hpcd->State; +} + +/** + * @} + */ + +/** + * @} + */ + +/* Private functions ---------------------------------------------------------*/ +/** @addtogroup PCD_Private_Functions + * @{ + */ + + +/** + * @brief This function handles PCD Endpoint interrupt request. + * @param hpcd PCD handle + * @retval HAL status + */ +static HAL_StatusTypeDef PCD_EP_ISR_Handler(PCD_HandleTypeDef *hpcd) +{ + PCD_EPTypeDef *ep; + uint16_t count; + uint16_t wIstr; + uint16_t wEPVal; + uint8_t epindex; + + /* stay in loop while pending interrupts */ + while ((hpcd->Instance->ISTR & USB_ISTR_CTR) != 0U) + { + wIstr = hpcd->Instance->ISTR; + /* extract highest priority endpoint number */ + epindex = (uint8_t)(wIstr & USB_ISTR_EP_ID); + + if (epindex == 0U) + { + /* Decode and service control endpoint interrupt */ + + /* DIR bit = origin of the interrupt */ + if ((wIstr & USB_ISTR_DIR) == 0U) + { + /* DIR = 0 */ + + /* DIR = 0 => IN int */ + /* DIR = 0 implies that (EP_CTR_TX = 1) always */ + PCD_CLEAR_TX_EP_CTR(hpcd->Instance, PCD_ENDP0); + ep = &hpcd->IN_ep[0]; + + ep->xfer_count = PCD_GET_EP_TX_CNT(hpcd->Instance, ep->num); + ep->xfer_buff += ep->xfer_count; + + /* TX COMPLETE */ +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) + hpcd->DataInStageCallback(hpcd, 0U); +#else + HAL_PCD_DataInStageCallback(hpcd, 0U); +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ + + if ((hpcd->USB_Address > 0U) && (ep->xfer_len == 0U)) + { + hpcd->Instance->DADDR = ((uint16_t)hpcd->USB_Address | USB_DADDR_EF); + hpcd->USB_Address = 0U; + } + } + else + { + /* DIR = 1 */ + + /* DIR = 1 & CTR_RX => SETUP or OUT int */ + /* DIR = 1 & (CTR_TX | CTR_RX) => 2 int pending */ + ep = &hpcd->OUT_ep[0]; + wEPVal = PCD_GET_ENDPOINT(hpcd->Instance, PCD_ENDP0); + + if ((wEPVal & USB_EP_SETUP) != 0U) + { + /* Get SETUP Packet*/ + ep->xfer_count = PCD_GET_EP_RX_CNT(hpcd->Instance, ep->num); + + USB_ReadPMA(hpcd->Instance, (uint8_t *)hpcd->Setup, + ep->pmaadress, (uint16_t)ep->xfer_count); + + /* SETUP bit kept frozen while CTR_RX = 1*/ + PCD_CLEAR_RX_EP_CTR(hpcd->Instance, PCD_ENDP0); + + /* Process SETUP Packet*/ +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) + hpcd->SetupStageCallback(hpcd); +#else + HAL_PCD_SetupStageCallback(hpcd); +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ + } + + else if ((wEPVal & USB_EP_CTR_RX) != 0U) + { + PCD_CLEAR_RX_EP_CTR(hpcd->Instance, PCD_ENDP0); + + /* Get Control Data OUT Packet*/ + ep->xfer_count = PCD_GET_EP_RX_CNT(hpcd->Instance, ep->num); + + if ((ep->xfer_count != 0U) && (ep->xfer_buff != 0U)) + { + USB_ReadPMA(hpcd->Instance, ep->xfer_buff, + ep->pmaadress, (uint16_t)ep->xfer_count); + + ep->xfer_buff += ep->xfer_count; + + /* Process Control Data OUT Packet*/ +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) + hpcd->DataOutStageCallback(hpcd, 0U); +#else + HAL_PCD_DataOutStageCallback(hpcd, 0U); +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ + } + + PCD_SET_EP_RX_CNT(hpcd->Instance, PCD_ENDP0, ep->maxpacket); + PCD_SET_EP_RX_STATUS(hpcd->Instance, PCD_ENDP0, USB_EP_RX_VALID); + } + } + } + else + { + /* Decode and service non control endpoints interrupt */ + + /* process related endpoint register */ + wEPVal = PCD_GET_ENDPOINT(hpcd->Instance, epindex); + if ((wEPVal & USB_EP_CTR_RX) != 0U) + { + /* clear int flag */ + PCD_CLEAR_RX_EP_CTR(hpcd->Instance, epindex); + ep = &hpcd->OUT_ep[epindex]; + + /* OUT double Buffering*/ + if (ep->doublebuffer == 0U) + { + count = (uint16_t)PCD_GET_EP_RX_CNT(hpcd->Instance, ep->num); + if (count != 0U) + { + USB_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaadress, count); + } + } + else + { + if ((PCD_GET_ENDPOINT(hpcd->Instance, ep->num) & USB_EP_DTOG_RX) != 0U) + { + /*read from endpoint BUF0Addr buffer*/ + count = (uint16_t)PCD_GET_EP_DBUF0_CNT(hpcd->Instance, ep->num); + if (count != 0U) + { + USB_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaaddr0, count); + } + } + else + { + /*read from endpoint BUF1Addr buffer*/ + count = (uint16_t)PCD_GET_EP_DBUF1_CNT(hpcd->Instance, ep->num); + if (count != 0U) + { + USB_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaaddr1, count); + } + } + /* free EP OUT Buffer */ + PCD_FreeUserBuffer(hpcd->Instance, ep->num, 0U); + } + /*multi-packet on the NON control OUT endpoint*/ + ep->xfer_count += count; + ep->xfer_buff += count; + + if ((ep->xfer_len == 0U) || (count < ep->maxpacket)) + { + /* RX COMPLETE */ +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) + hpcd->DataOutStageCallback(hpcd, ep->num); +#else + HAL_PCD_DataOutStageCallback(hpcd, ep->num); +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ + } + else + { + (void)HAL_PCD_EP_Receive(hpcd, ep->num, ep->xfer_buff, ep->xfer_len); + } + + } /* if((wEPVal & EP_CTR_RX) */ + + if ((wEPVal & USB_EP_CTR_TX) != 0U) + { + ep = &hpcd->IN_ep[epindex]; + + /* clear int flag */ + PCD_CLEAR_TX_EP_CTR(hpcd->Instance, epindex); + + /*multi-packet on the NON control IN endpoint*/ + ep->xfer_count = PCD_GET_EP_TX_CNT(hpcd->Instance, ep->num); + ep->xfer_buff += ep->xfer_count; + + /* Zero Length Packet? */ + if (ep->xfer_len == 0U) + { + /* TX COMPLETE */ +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) + hpcd->DataInStageCallback(hpcd, ep->num); +#else + HAL_PCD_DataInStageCallback(hpcd, ep->num); +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ + } + else + { + (void)HAL_PCD_EP_Transmit(hpcd, ep->num, ep->xfer_buff, ep->xfer_len); + } + } + } + } + return HAL_OK; +} + + +/** + * @} + */ +#endif /* defined (USB) */ +#endif /* HAL_PCD_MODULE_ENABLED */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.c b/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.c new file mode 100644 index 0000000..26dd51f --- /dev/null +++ b/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.c @@ -0,0 +1,338 @@ +/** + ****************************************************************************** + * @file stm32f0xx_hal_pcd_ex.c + * @author MCD Application Team + * @brief PCD Extended HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the USB Peripheral Controller: + * + Extended features functions + * + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2016 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f0xx_hal.h" + +/** @addtogroup STM32F0xx_HAL_Driver + * @{ + */ + +/** @defgroup PCDEx PCDEx + * @brief PCD Extended HAL module driver + * @{ + */ + +#ifdef HAL_PCD_MODULE_ENABLED + +#if defined (USB) +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/* Private macros ------------------------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ + +/** @defgroup PCDEx_Exported_Functions PCDEx Exported Functions + * @{ + */ + +/** @defgroup PCDEx_Exported_Functions_Group1 Peripheral Control functions + * @brief PCDEx control functions + * +@verbatim + =============================================================================== + ##### Extended features functions ##### + =============================================================================== + [..] This section provides functions allowing to: + (+) Update FIFO configuration + +@endverbatim + * @{ + */ + +/** + * @brief Configure PMA for EP + * @param hpcd Device instance + * @param ep_addr endpoint address + * @param ep_kind endpoint Kind + * USB_SNG_BUF: Single Buffer used + * USB_DBL_BUF: Double Buffer used + * @param pmaadress: EP address in The PMA: In case of single buffer endpoint + * this parameter is 16-bit value providing the address + * in PMA allocated to endpoint. + * In case of double buffer endpoint this parameter + * is a 32-bit value providing the endpoint buffer 0 address + * in the LSB part of 32-bit value and endpoint buffer 1 address + * in the MSB part of 32-bit value. + * @retval HAL status + */ + +HAL_StatusTypeDef HAL_PCDEx_PMAConfig(PCD_HandleTypeDef *hpcd, + uint16_t ep_addr, + uint16_t ep_kind, + uint32_t pmaadress) +{ + PCD_EPTypeDef *ep; + + /* initialize ep structure*/ + if ((0x80U & ep_addr) == 0x80U) + { + ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK]; + } + else + { + ep = &hpcd->OUT_ep[ep_addr]; + } + + /* Here we check if the endpoint is single or double Buffer*/ + if (ep_kind == PCD_SNG_BUF) + { + /* Single Buffer */ + ep->doublebuffer = 0U; + /* Configure the PMA */ + ep->pmaadress = (uint16_t)pmaadress; + } + else /* USB_DBL_BUF */ + { + /* Double Buffer Endpoint */ + ep->doublebuffer = 1U; + /* Configure the PMA */ + ep->pmaaddr0 = (uint16_t)(pmaadress & 0xFFFFU); + ep->pmaaddr1 = (uint16_t)((pmaadress & 0xFFFF0000U) >> 16); + } + + return HAL_OK; +} + +/** + * @brief Activate BatteryCharging feature. + * @param hpcd PCD handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCDEx_ActivateBCD(PCD_HandleTypeDef *hpcd) +{ + USB_TypeDef *USBx = hpcd->Instance; + hpcd->battery_charging_active = 1U; + + /* Enable BCD feature */ + USBx->BCDR |= USB_BCDR_BCDEN; + + /* Enable DCD : Data Contact Detect */ + USBx->BCDR &= ~(USB_BCDR_PDEN); + USBx->BCDR &= ~(USB_BCDR_SDEN); + USBx->BCDR |= USB_BCDR_DCDEN; + + return HAL_OK; +} + +/** + * @brief Deactivate BatteryCharging feature. + * @param hpcd PCD handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCDEx_DeActivateBCD(PCD_HandleTypeDef *hpcd) +{ + USB_TypeDef *USBx = hpcd->Instance; + hpcd->battery_charging_active = 0U; + + /* Disable BCD feature */ + USBx->BCDR &= ~(USB_BCDR_BCDEN); + + return HAL_OK; +} + +/** + * @brief Handle BatteryCharging Process. + * @param hpcd PCD handle + * @retval HAL status + */ +void HAL_PCDEx_BCD_VBUSDetect(PCD_HandleTypeDef *hpcd) +{ + USB_TypeDef *USBx = hpcd->Instance; + uint32_t tickstart = HAL_GetTick(); + + /* Wait Detect flag or a timeout is happen*/ + while ((USBx->BCDR & USB_BCDR_DCDET) == 0U) + { + /* Check for the Timeout */ + if ((HAL_GetTick() - tickstart) > 1000U) + { +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) + hpcd->BCDCallback(hpcd, PCD_BCD_ERROR); +#else + HAL_PCDEx_BCD_Callback(hpcd, PCD_BCD_ERROR); +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ + + return; + } + } + + HAL_Delay(200U); + + /* Data Pin Contact ? Check Detect flag */ + if ((USBx->BCDR & USB_BCDR_DCDET) == USB_BCDR_DCDET) + { +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) + hpcd->BCDCallback(hpcd, PCD_BCD_CONTACT_DETECTION); +#else + HAL_PCDEx_BCD_Callback(hpcd, PCD_BCD_CONTACT_DETECTION); +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ + } + /* Primary detection: checks if connected to Standard Downstream Port + (without charging capability) */ + USBx->BCDR &= ~(USB_BCDR_DCDEN); + HAL_Delay(50U); + USBx->BCDR |= (USB_BCDR_PDEN); + HAL_Delay(50U); + + /* If Charger detect ? */ + if ((USBx->BCDR & USB_BCDR_PDET) == USB_BCDR_PDET) + { + /* Start secondary detection to check connection to Charging Downstream + Port or Dedicated Charging Port */ + USBx->BCDR &= ~(USB_BCDR_PDEN); + HAL_Delay(50U); + USBx->BCDR |= (USB_BCDR_SDEN); + HAL_Delay(50U); + + /* If CDP ? */ + if ((USBx->BCDR & USB_BCDR_SDET) == USB_BCDR_SDET) + { + /* Dedicated Downstream Port DCP */ +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) + hpcd->BCDCallback(hpcd, PCD_BCD_DEDICATED_CHARGING_PORT); +#else + HAL_PCDEx_BCD_Callback(hpcd, PCD_BCD_DEDICATED_CHARGING_PORT); +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ + } + else + { + /* Charging Downstream Port CDP */ +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) + hpcd->BCDCallback(hpcd, PCD_BCD_CHARGING_DOWNSTREAM_PORT); +#else + HAL_PCDEx_BCD_Callback(hpcd, PCD_BCD_CHARGING_DOWNSTREAM_PORT); +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ + } + } + else /* NO */ + { + /* Standard Downstream Port */ +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) + hpcd->BCDCallback(hpcd, PCD_BCD_STD_DOWNSTREAM_PORT); +#else + HAL_PCDEx_BCD_Callback(hpcd, PCD_BCD_STD_DOWNSTREAM_PORT); +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ + } + + /* Battery Charging capability discovery finished Start Enumeration */ + (void)HAL_PCDEx_DeActivateBCD(hpcd); +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) + hpcd->BCDCallback(hpcd, PCD_BCD_DISCOVERY_COMPLETED); +#else + HAL_PCDEx_BCD_Callback(hpcd, PCD_BCD_DISCOVERY_COMPLETED); +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ +} + + +/** + * @brief Activate LPM feature. + * @param hpcd PCD handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCDEx_ActivateLPM(PCD_HandleTypeDef *hpcd) +{ + + USB_TypeDef *USBx = hpcd->Instance; + hpcd->lpm_active = 1U; + hpcd->LPM_State = LPM_L0; + + USBx->LPMCSR |= USB_LPMCSR_LMPEN; + USBx->LPMCSR |= USB_LPMCSR_LPMACK; + + return HAL_OK; +} + +/** + * @brief Deactivate LPM feature. + * @param hpcd PCD handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCDEx_DeActivateLPM(PCD_HandleTypeDef *hpcd) +{ + USB_TypeDef *USBx = hpcd->Instance; + + hpcd->lpm_active = 0U; + + USBx->LPMCSR &= ~(USB_LPMCSR_LMPEN); + USBx->LPMCSR &= ~(USB_LPMCSR_LPMACK); + + return HAL_OK; +} + + + +/** + * @brief Send LPM message to user layer callback. + * @param hpcd PCD handle + * @param msg LPM message + * @retval HAL status + */ +__weak void HAL_PCDEx_LPM_Callback(PCD_HandleTypeDef *hpcd, PCD_LPM_MsgTypeDef msg) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hpcd); + UNUSED(msg); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_PCDEx_LPM_Callback could be implemented in the user file + */ +} + +/** + * @brief Send BatteryCharging message to user layer callback. + * @param hpcd PCD handle + * @param msg LPM message + * @retval HAL status + */ +__weak void HAL_PCDEx_BCD_Callback(PCD_HandleTypeDef *hpcd, PCD_BCD_MsgTypeDef msg) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hpcd); + UNUSED(msg); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_PCDEx_BCD_Callback could be implemented in the user file + */ +} + +/** + * @} + */ + +/** + * @} + */ +#endif /* defined (USB) */ +#endif /* HAL_PCD_MODULE_ENABLED */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.c b/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.c new file mode 100644 index 0000000..558d869 --- /dev/null +++ b/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.c @@ -0,0 +1,454 @@ +/** + ****************************************************************************** + * @file stm32f0xx_hal_pwr.c + * @author MCD Application Team + * @brief PWR HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the Power Controller (PWR) peripheral: + * + Initialization/de-initialization function + * + Peripheral Control function + * + @verbatim + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2016 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f0xx_hal.h" + +/** @addtogroup STM32F0xx_HAL_Driver + * @{ + */ + +/** @defgroup PWR PWR + * @brief PWR HAL module driver + * @{ + */ + +#ifdef HAL_PWR_MODULE_ENABLED + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + +/** @defgroup PWR_Exported_Functions PWR Exported Functions + * @{ + */ + +/** @defgroup PWR_Exported_Functions_Group1 Initialization and de-initialization functions + * @brief Initialization and de-initialization functions + * +@verbatim + =============================================================================== + ##### Initialization and de-initialization functions ##### + =============================================================================== + [..] + After reset, the backup domain (RTC registers, RTC backup data + registers) is protected against possible unwanted + write accesses. + To enable access to the RTC Domain and RTC registers, proceed as follows: + (+) Enable the Power Controller (PWR) APB1 interface clock using the + __HAL_RCC_PWR_CLK_ENABLE() macro. + (+) Enable access to RTC domain using the HAL_PWR_EnableBkUpAccess() function. + +@endverbatim + * @{ + */ + +/** + * @brief Deinitializes the PWR peripheral registers to their default reset values. + * @retval None + */ +void HAL_PWR_DeInit(void) +{ + __HAL_RCC_PWR_FORCE_RESET(); + __HAL_RCC_PWR_RELEASE_RESET(); +} + +/** + * @brief Enables access to the backup domain (RTC registers, RTC + * backup data registers when present). + * @note If the HSE divided by 32 is used as the RTC clock, the + * Backup Domain Access should be kept enabled. + * @retval None + */ +void HAL_PWR_EnableBkUpAccess(void) +{ + PWR->CR |= (uint32_t)PWR_CR_DBP; +} + +/** + * @brief Disables access to the backup domain (RTC registers, RTC + * backup data registers when present). + * @note If the HSE divided by 32 is used as the RTC clock, the + * Backup Domain Access should be kept enabled. + * @retval None + */ +void HAL_PWR_DisableBkUpAccess(void) +{ + PWR->CR &= ~((uint32_t)PWR_CR_DBP); +} + +/** + * @} + */ + +/** @defgroup PWR_Exported_Functions_Group2 Peripheral Control functions + * @brief Low Power modes configuration functions + * +@verbatim + + =============================================================================== + ##### Peripheral Control functions ##### + =============================================================================== + + *** WakeUp pin configuration *** + ================================ + [..] + (+) WakeUp pin is used to wakeup the system from Standby mode. This pin is + forced in input pull down configuration and is active on rising edges. + (+) There are two WakeUp pins, and up to eight Wakeup pins on STM32F07x & STM32F09x devices. + (++)WakeUp Pin 1 on PA.00. + (++)WakeUp Pin 2 on PC.13. + (++)WakeUp Pin 3 on PE.06.(STM32F07x/STM32F09x) + (++)WakeUp Pin 4 on PA.02.(STM32F07x/STM32F09x) + (++)WakeUp Pin 5 on PC.05.(STM32F07x/STM32F09x) + (++)WakeUp Pin 6 on PB.05.(STM32F07x/STM32F09x) + (++)WakeUp Pin 7 on PB.15.(STM32F07x/STM32F09x) + (++)WakeUp Pin 8 on PF.02.(STM32F07x/STM32F09x) + + *** Low Power modes configuration *** + ===================================== + [..] + The devices feature 3 low-power modes: + (+) Sleep mode: Cortex-M0 core stopped, peripherals kept running. + (+) Stop mode: all clocks are stopped, regulator running, regulator + in low power mode + (+) Standby mode: 1.2V domain powered off (mode not available on STM32F0x8 devices). + + *** Sleep mode *** + ================== + [..] + (+) Entry: + The Sleep mode is entered by using the HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFx) + functions with + (++) PWR_SLEEPENTRY_WFI: enter SLEEP mode with WFI instruction + (++) PWR_SLEEPENTRY_WFE: enter SLEEP mode with WFE instruction + + (+) Exit: + (++) Any peripheral interrupt acknowledged by the nested vectored interrupt + controller (NVIC) can wake up the device from Sleep mode. + + *** Stop mode *** + ================= + [..] + In Stop mode, all clocks in the 1.8V domain are stopped, the PLL, the HSI, + and the HSE RC oscillators are disabled. Internal SRAM and register contents + are preserved. + The voltage regulator can be configured either in normal or low-power mode. + To minimize the consumption. + + (+) Entry: + The Stop mode is entered using the HAL_PWR_EnterSTOPMode(PWR_MAINREGULATOR_ON, PWR_STOPENTRY_WFI ) + function with: + (++) Main regulator ON. + (++) Low Power regulator ON. + (++) PWR_STOPENTRY_WFI: enter STOP mode with WFI instruction + (++) PWR_STOPENTRY_WFE: enter STOP mode with WFE instruction + (+) Exit: + (++) Any EXTI Line (Internal or External) configured in Interrupt/Event mode. + (++) Some specific communication peripherals (CEC, USART, I2C) interrupts, + when programmed in wakeup mode (the peripheral must be + programmed in wakeup mode and the corresponding interrupt vector + must be enabled in the NVIC) + + *** Standby mode *** + ==================== + [..] + The Standby mode allows to achieve the lowest power consumption. It is based + on the Cortex-M0 deep sleep mode, with the voltage regulator disabled. + The 1.8V domain is consequently powered off. The PLL, the HSI oscillator and + the HSE oscillator are also switched off. SRAM and register contents are lost + except for the RTC registers, RTC backup registers and Standby circuitry. + The voltage regulator is OFF. + + (+) Entry: + (++) The Standby mode is entered using the HAL_PWR_EnterSTANDBYMode() function. + (+) Exit: + (++) WKUP pin rising edge, RTC alarm (Alarm A), RTC wakeup, + tamper event, time-stamp event, external reset in NRST pin, IWDG reset. + + *** Auto-wakeup (AWU) from low-power mode *** + ============================================= + [..] + The MCU can be woken up from low-power mode by an RTC Alarm event, an RTC + Wakeup event, a tamper event, a time-stamp event, or a comparator event, + without depending on an external interrupt (Auto-wakeup mode). + + (+) RTC auto-wakeup (AWU) from the Stop and Standby modes + + (++) To wake up from the Stop mode with an RTC alarm event, it is necessary to + configure the RTC to generate the RTC alarm using the HAL_RTC_SetAlarm_IT() function. + + (++) To wake up from the Stop mode with an RTC Tamper or time stamp event, it + is necessary to configure the RTC to detect the tamper or time stamp event using the + HAL_RTC_SetTimeStamp_IT() or HAL_RTC_SetTamper_IT() functions. + + (++) To wake up from the Stop mode with an RTC WakeUp event, it is necessary to + configure the RTC to generate the RTC WakeUp event using the HAL_RTC_SetWakeUpTimer_IT() function. + + (+) Comparator auto-wakeup (AWU) from the Stop mode + + (++) To wake up from the Stop mode with a comparator wakeup event, it is necessary to: + (+++) Configure the EXTI Line associated with the comparator (example EXTI Line 22 for comparator 2) + to be sensitive to to the selected edges (falling, rising or falling + and rising) (Interrupt or Event modes) using the EXTI_Init() function. + (+++) Configure the comparator to generate the event. +@endverbatim + * @{ + */ + +/** + * @brief Enables the WakeUp PINx functionality. + * @param WakeUpPinx Specifies the Power Wake-Up pin to enable. + * This parameter can be value of : + * @ref PWREx_WakeUp_Pins + * @retval None + */ +void HAL_PWR_EnableWakeUpPin(uint32_t WakeUpPinx) +{ + /* Check the parameters */ + assert_param(IS_PWR_WAKEUP_PIN(WakeUpPinx)); + /* Enable the EWUPx pin */ + SET_BIT(PWR->CSR, WakeUpPinx); +} + +/** + * @brief Disables the WakeUp PINx functionality. + * @param WakeUpPinx Specifies the Power Wake-Up pin to disable. + * This parameter can be values of : + * @ref PWREx_WakeUp_Pins + * @retval None + */ +void HAL_PWR_DisableWakeUpPin(uint32_t WakeUpPinx) +{ + /* Check the parameters */ + assert_param(IS_PWR_WAKEUP_PIN(WakeUpPinx)); + /* Disable the EWUPx pin */ + CLEAR_BIT(PWR->CSR, WakeUpPinx); +} + +/** + * @brief Enters Sleep mode. + * @note In Sleep mode, all I/O pins keep the same state as in Run mode. + * @param Regulator Specifies the regulator state in SLEEP mode. + * On STM32F0 devices, this parameter is a dummy value and it is ignored + * as regulator can't be modified in this mode. Parameter is kept for platform + * compatibility. + * @param SLEEPEntry Specifies if SLEEP mode is entered with WFI or WFE instruction. + * When WFI entry is used, tick interrupt have to be disabled if not desired as + * the interrupt wake up source. + * This parameter can be one of the following values: + * @arg PWR_SLEEPENTRY_WFI: enter SLEEP mode with WFI instruction + * @arg PWR_SLEEPENTRY_WFE: enter SLEEP mode with WFE instruction + * @retval None + */ +void HAL_PWR_EnterSLEEPMode(uint32_t Regulator, uint8_t SLEEPEntry) +{ + /* Check the parameters */ + assert_param(IS_PWR_REGULATOR(Regulator)); + assert_param(IS_PWR_SLEEP_ENTRY(SLEEPEntry)); + + /* Clear SLEEPDEEP bit of Cortex System Control Register */ + SCB->SCR &= (uint32_t)~((uint32_t)SCB_SCR_SLEEPDEEP_Msk); + + /* Select SLEEP mode entry -------------------------------------------------*/ + if(SLEEPEntry == PWR_SLEEPENTRY_WFI) + { + /* Request Wait For Interrupt */ + __WFI(); + } + else + { + /* Request Wait For Event */ + __SEV(); + __WFE(); + __WFE(); + } +} + +/** + * @brief Enters STOP mode. + * @note In Stop mode, all I/O pins keep the same state as in Run mode. + * @note When exiting Stop mode by issuing an interrupt or a wakeup event, + * the HSI RC oscillator is selected as system clock. + * @note When the voltage regulator operates in low power mode, an additional + * startup delay is incurred when waking up from Stop mode. + * By keeping the internal regulator ON during Stop mode, the consumption + * is higher although the startup time is reduced. + * @param Regulator Specifies the regulator state in STOP mode. + * This parameter can be one of the following values: + * @arg PWR_MAINREGULATOR_ON: STOP mode with regulator ON + * @arg PWR_LOWPOWERREGULATOR_ON: STOP mode with low power regulator ON + * @param STOPEntry specifies if STOP mode in entered with WFI or WFE instruction. + * This parameter can be one of the following values: + * @arg PWR_STOPENTRY_WFI:Enter STOP mode with WFI instruction + * @arg PWR_STOPENTRY_WFE: Enter STOP mode with WFE instruction + * @retval None + */ +void HAL_PWR_EnterSTOPMode(uint32_t Regulator, uint8_t STOPEntry) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_PWR_REGULATOR(Regulator)); + assert_param(IS_PWR_STOP_ENTRY(STOPEntry)); + + /* Select the regulator state in STOP mode ---------------------------------*/ + tmpreg = PWR->CR; + + /* Clear PDDS and LPDS bits */ + tmpreg &= (uint32_t)~(PWR_CR_PDDS | PWR_CR_LPDS); + + /* Set LPDS bit according to Regulator value */ + tmpreg |= Regulator; + + /* Store the new value */ + PWR->CR = tmpreg; + + /* Set SLEEPDEEP bit of Cortex System Control Register */ + SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; + + /* Select STOP mode entry --------------------------------------------------*/ + if(STOPEntry == PWR_STOPENTRY_WFI) + { + /* Request Wait For Interrupt */ + __WFI(); + } + else + { + /* Request Wait For Event */ + __SEV(); + __WFE(); + __WFE(); + } + + /* Reset SLEEPDEEP bit of Cortex System Control Register */ + SCB->SCR &= (uint32_t)~((uint32_t)SCB_SCR_SLEEPDEEP_Msk); +} + +/** + * @brief Enters STANDBY mode. + * @note In Standby mode, all I/O pins are high impedance except for: + * - Reset pad (still available) + * - RTC alternate function pins if configured for tamper, time-stamp, RTC + * Alarm out, or RTC clock calibration out. + * - WKUP pins if enabled. + * STM32F0x8 devices, the Stop mode is available, but it is + * aningless to distinguish between voltage regulator in Low power + * mode and voltage regulator in Run mode because the regulator + * not used and the core is supplied directly from an external source. + * Consequently, the Standby mode is not available on those devices. + * @retval None + */ +void HAL_PWR_EnterSTANDBYMode(void) +{ + /* Select STANDBY mode */ + PWR->CR |= (uint32_t)PWR_CR_PDDS; + + /* Set SLEEPDEEP bit of Cortex System Control Register */ + SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; + + /* This option is used to ensure that store operations are completed */ +#if defined ( __CC_ARM) + __force_stores(); +#endif + /* Request Wait For Interrupt */ + __WFI(); +} + +/** + * @brief Indicates Sleep-On-Exit when returning from Handler mode to Thread mode. + * @note Set SLEEPONEXIT bit of SCR register. When this bit is set, the processor + * re-enters SLEEP mode when an interruption handling is over. + * Setting this bit is useful when the processor is expected to run only on + * interruptions handling. + * @retval None + */ +void HAL_PWR_EnableSleepOnExit(void) +{ + /* Set SLEEPONEXIT bit of Cortex System Control Register */ + SET_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPONEXIT_Msk)); +} + + +/** + * @brief Disables Sleep-On-Exit feature when returning from Handler mode to Thread mode. + * @note Clears SLEEPONEXIT bit of SCR register. When this bit is set, the processor + * re-enters SLEEP mode when an interruption handling is over. + * @retval None + */ +void HAL_PWR_DisableSleepOnExit(void) +{ + /* Clear SLEEPONEXIT bit of Cortex System Control Register */ + CLEAR_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPONEXIT_Msk)); +} + + + +/** + * @brief Enables CORTEX M4 SEVONPEND bit. + * @note Sets SEVONPEND bit of SCR register. When this bit is set, this causes + * WFE to wake up when an interrupt moves from inactive to pended. + * @retval None + */ +void HAL_PWR_EnableSEVOnPend(void) +{ + /* Set SEVONPEND bit of Cortex System Control Register */ + SET_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SEVONPEND_Msk)); +} + + +/** + * @brief Disables CORTEX M4 SEVONPEND bit. + * @note Clears SEVONPEND bit of SCR register. When this bit is set, this causes + * WFE to wake up when an interrupt moves from inactive to pended. + * @retval None + */ +void HAL_PWR_DisableSEVOnPend(void) +{ + /* Clear SEVONPEND bit of Cortex System Control Register */ + CLEAR_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SEVONPEND_Msk)); +} + +/** + * @} + */ + +/** + * @} + */ + +#endif /* HAL_PWR_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.c b/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.c new file mode 100644 index 0000000..c14370b --- /dev/null +++ b/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.c @@ -0,0 +1,274 @@ +/** + ****************************************************************************** + * @file stm32f0xx_hal_pwr_ex.c + * @author MCD Application Team + * @brief Extended PWR HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the Power Controller (PWR) peripheral: + * + Extended Initialization and de-initialization functions + * + Extended Peripheral Control functions + * + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2016 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f0xx_hal.h" + +/** @addtogroup STM32F0xx_HAL_Driver + * @{ + */ + +/** @defgroup PWREx PWREx + * @brief PWREx HAL module driver + * @{ + */ + +#ifdef HAL_PWR_MODULE_ENABLED + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/** @defgroup PWREx_Private_Constants PWREx Private Constants + * @{ + */ +#define PVD_MODE_IT (0x00010000U) +#define PVD_MODE_EVT (0x00020000U) +#define PVD_RISING_EDGE (0x00000001U) +#define PVD_FALLING_EDGE (0x00000002U) +/** + * @} + */ + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Exported functions ---------------------------------------------------------*/ + +/** @defgroup PWREx_Exported_Functions PWREx Exported Functions + * @{ + */ + +/** @defgroup PWREx_Exported_Functions_Group1 Peripheral Extended Control Functions + * @brief Extended Peripheral Control functions + * +@verbatim + + =============================================================================== + ##### Peripheral extended control functions ##### + =============================================================================== + + *** PVD configuration *** + ========================= + [..] + (+) The PVD is used to monitor the VDD power supply by comparing it to a + threshold selected by the PVD Level (PLS[2:0] bits in the PWR_CR). + (+) A PVDO flag is available to indicate if VDD/VDDA is higher or lower + than the PVD threshold. This event is internally connected to the EXTI + line16 and can generate an interrupt if enabled. This is done through + HAL_PWR_ConfigPVD(), HAL_PWR_EnablePVD() functions. + (+) The PVD is stopped in Standby mode. + -@- PVD is not available on STM32F030x4/x6/x8 + + *** VDDIO2 Monitor Configuration *** + ==================================== + [..] + (+) VDDIO2 monitor is used to monitor the VDDIO2 power supply by comparing it + to VREFInt Voltage + (+) This monitor is internally connected to the EXTI line31 + and can generate an interrupt if enabled. This is done through + HAL_PWREx_EnableVddio2Monitor() function. + -@- VDDIO2 is available on STM32F07x/09x/04x + +@endverbatim + * @{ + */ + +#if defined (STM32F031x6) || defined (STM32F051x8) || \ + defined (STM32F071xB) || defined (STM32F091xC) || \ + defined (STM32F042x6) || defined (STM32F072xB) +/** + * @brief Configures the voltage threshold detected by the Power Voltage Detector(PVD). + * @param sConfigPVD pointer to an PWR_PVDTypeDef structure that contains the configuration + * information for the PVD. + * @note Refer to the electrical characteristics of your device datasheet for + * more details about the voltage threshold corresponding to each + * detection level. + * @retval None + */ +void HAL_PWR_ConfigPVD(PWR_PVDTypeDef *sConfigPVD) +{ + /* Check the parameters */ + assert_param(IS_PWR_PVD_LEVEL(sConfigPVD->PVDLevel)); + assert_param(IS_PWR_PVD_MODE(sConfigPVD->Mode)); + + /* Set PLS[7:5] bits according to PVDLevel value */ + MODIFY_REG(PWR->CR, PWR_CR_PLS, sConfigPVD->PVDLevel); + + /* Clear any previous config. Keep it clear if no event or IT mode is selected */ + __HAL_PWR_PVD_EXTI_DISABLE_EVENT(); + __HAL_PWR_PVD_EXTI_DISABLE_IT(); + __HAL_PWR_PVD_EXTI_DISABLE_RISING_EDGE();__HAL_PWR_PVD_EXTI_DISABLE_FALLING_EDGE(); + + /* Configure interrupt mode */ + if((sConfigPVD->Mode & PVD_MODE_IT) == PVD_MODE_IT) + { + __HAL_PWR_PVD_EXTI_ENABLE_IT(); + } + + /* Configure event mode */ + if((sConfigPVD->Mode & PVD_MODE_EVT) == PVD_MODE_EVT) + { + __HAL_PWR_PVD_EXTI_ENABLE_EVENT(); + } + + /* Configure the edge */ + if((sConfigPVD->Mode & PVD_RISING_EDGE) == PVD_RISING_EDGE) + { + __HAL_PWR_PVD_EXTI_ENABLE_RISING_EDGE(); + } + + if((sConfigPVD->Mode & PVD_FALLING_EDGE) == PVD_FALLING_EDGE) + { + __HAL_PWR_PVD_EXTI_ENABLE_FALLING_EDGE(); + } +} + +/** + * @brief Enables the Power Voltage Detector(PVD). + * @retval None + */ +void HAL_PWR_EnablePVD(void) +{ + PWR->CR |= (uint32_t)PWR_CR_PVDE; +} + +/** + * @brief Disables the Power Voltage Detector(PVD). + * @retval None + */ +void HAL_PWR_DisablePVD(void) +{ + PWR->CR &= ~((uint32_t)PWR_CR_PVDE); +} + +/** + * @brief This function handles the PWR PVD interrupt request. + * @note This API should be called under the PVD_IRQHandler() or PVD_VDDIO2_IRQHandler(). + * @retval None + */ +void HAL_PWR_PVD_IRQHandler(void) +{ + /* Check PWR exti flag */ + if(__HAL_PWR_PVD_EXTI_GET_FLAG() != RESET) + { + /* PWR PVD interrupt user callback */ + HAL_PWR_PVDCallback(); + + /* Clear PWR Exti pending bit */ + __HAL_PWR_PVD_EXTI_CLEAR_FLAG(); + } +} + +/** + * @brief PWR PVD interrupt callback + * @retval None + */ +__weak void HAL_PWR_PVDCallback(void) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_PWR_PVDCallback could be implemented in the user file + */ +} + +#endif /* defined (STM32F031x6) || defined (STM32F051x8) || */ + /* defined (STM32F071xB) || defined (STM32F091xC) || */ + /* defined (STM32F042x6) || defined (STM32F072xB) */ + +#if defined (STM32F042x6) || defined (STM32F048xx) || \ + defined (STM32F071xB) || defined (STM32F072xB) || defined (STM32F078xx) || \ + defined (STM32F091xC) || defined (STM32F098xx) +/** + * @brief Enable VDDIO2 monitor: enable Exti 31 and falling edge detection. + * @note If Exti 31 is enable correlty and VDDIO2 voltage goes below Vrefint, + an interrupt is generated Irq line 1. + NVIS has to be enable by user. + * @retval None + */ +void HAL_PWREx_EnableVddio2Monitor(void) +{ + __HAL_PWR_VDDIO2_EXTI_ENABLE_IT(); + __HAL_PWR_VDDIO2_EXTI_ENABLE_FALLING_EDGE(); +} + +/** + * @brief Disable the Vddio2 Monitor. + * @retval None + */ +void HAL_PWREx_DisableVddio2Monitor(void) +{ + __HAL_PWR_VDDIO2_EXTI_DISABLE_IT(); + __HAL_PWR_VDDIO2_EXTI_DISABLE_FALLING_EDGE(); + +} + +/** + * @brief This function handles the PWR Vddio2 monitor interrupt request. + * @note This API should be called under the VDDIO2_IRQHandler() PVD_VDDIO2_IRQHandler(). + * @retval None + */ +void HAL_PWREx_Vddio2Monitor_IRQHandler(void) +{ + /* Check PWR exti flag */ + if(__HAL_PWR_VDDIO2_EXTI_GET_FLAG() != RESET) + { + /* PWR Vddio2 monitor interrupt user callback */ + HAL_PWREx_Vddio2MonitorCallback(); + + /* Clear PWR Exti pending bit */ + __HAL_PWR_VDDIO2_EXTI_CLEAR_FLAG(); + } +} + +/** + * @brief PWR Vddio2 Monitor interrupt callback + * @retval None + */ +__weak void HAL_PWREx_Vddio2MonitorCallback(void) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_PWREx_Vddio2MonitorCallback could be implemented in the user file + */ +} + +#endif /* defined (STM32F042x6) || defined (STM32F048xx) || \ + defined (STM32F071xB) || defined (STM32F072xB) || defined (STM32F078xx) || \ + defined (STM32F091xC) || defined (STM32F098xx) */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* HAL_PWR_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.c b/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.c new file mode 100644 index 0000000..3dd009c --- /dev/null +++ b/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.c @@ -0,0 +1,1365 @@ +/** + ****************************************************************************** + * @file stm32f0xx_hal_rcc.c + * @author MCD Application Team + * @brief RCC HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the Reset and Clock Control (RCC) peripheral: + * + Initialization and de-initialization functions + * + Peripheral Control functions + * + @verbatim + ============================================================================== + ##### RCC specific features ##### + ============================================================================== + [..] + After reset the device is running from Internal High Speed oscillator + (HSI 8MHz) with Flash 0 wait state, Flash prefetch buffer is enabled, + and all peripherals are off except internal SRAM, Flash and JTAG. + (+) There is no prescaler on High speed (AHB) and Low speed (APB) buses; + all peripherals mapped on these buses are running at HSI speed. + (+) The clock for all peripherals is switched off, except the SRAM and FLASH. + (+) All GPIOs are in input floating state, except the JTAG pins which + are assigned to be used for debug purpose. + [..] Once the device started from reset, the user application has to: + (+) Configure the clock source to be used to drive the System clock + (if the application needs higher frequency/performance) + (+) Configure the System clock frequency and Flash settings + (+) Configure the AHB and APB buses prescalers + (+) Enable the clock for the peripheral(s) to be used + (+) Configure the clock source(s) for peripherals whose clocks are not + derived from the System clock (RTC, ADC, I2C, USART, TIM, USB FS, etc..) + + ##### RCC Limitations ##### + ============================================================================== + [..] + A delay between an RCC peripheral clock enable and the effective peripheral + enabling should be taken into account in order to manage the peripheral read/write + from/to registers. + (+) This delay depends on the peripheral mapping. + (++) AHB & APB peripherals, 1 dummy read is necessary + + [..] + Workarounds: + (#) For AHB & APB peripherals, a dummy read to the peripheral register has been + inserted in each __HAL_RCC_PPP_CLK_ENABLE() macro. + + @endverbatim + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2016 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f0xx_hal.h" + +/** @addtogroup STM32F0xx_HAL_Driver + * @{ + */ + +/** @defgroup RCC RCC +* @brief RCC HAL module driver + * @{ + */ + +#ifdef HAL_RCC_MODULE_ENABLED + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/** @defgroup RCC_Private_Constants RCC Private Constants + * @{ + */ +/** + * @} + */ +/* Private macro -------------------------------------------------------------*/ +/** @defgroup RCC_Private_Macros RCC Private Macros + * @{ + */ + +#define MCO1_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE() +#define MCO1_GPIO_PORT GPIOA +#define MCO1_PIN GPIO_PIN_8 + +/** + * @} + */ + +/* Private variables ---------------------------------------------------------*/ +/** @defgroup RCC_Private_Variables RCC Private Variables + * @{ + */ +/** + * @} + */ + +/* Private function prototypes -----------------------------------------------*/ +/* Exported functions ---------------------------------------------------------*/ + +/** @defgroup RCC_Exported_Functions RCC Exported Functions + * @{ + */ + +/** @defgroup RCC_Exported_Functions_Group1 Initialization and de-initialization functions + * @brief Initialization and Configuration functions + * + @verbatim + =============================================================================== + ##### Initialization and de-initialization functions ##### + =============================================================================== + [..] + This section provides functions allowing to configure the internal/external oscillators + (HSE, HSI, HSI14, HSI48, LSE, LSI, PLL, CSS and MCO) and the System buses clocks (SYSCLK, + AHB and APB1). + + [..] Internal/external clock and PLL configuration + (#) HSI (high-speed internal), 8 MHz factory-trimmed RC used directly or through + the PLL as System clock source. + The HSI clock can be used also to clock the USART and I2C peripherals. + + (#) HSI14 (high-speed internal), 14 MHz factory-trimmed RC used directly to clock + the ADC peripheral. + + (#) LSI (low-speed internal), ~40 KHz low consumption RC used as IWDG and/or RTC + clock source. + + (#) HSE (high-speed external), 4 to 32 MHz crystal oscillator used directly or + through the PLL as System clock source. Can be used also as RTC clock source. + + (#) LSE (low-speed external), 32 KHz oscillator used as RTC clock source. + + (#) PLL (clocked by HSI, HSI48 or HSE), featuring different output clocks: + (++) The first output is used to generate the high speed system clock (up to 48 MHz) + (++) The second output is used to generate the clock for the USB FS (48 MHz) + (++) The third output may be used to generate the clock for the TIM, I2C and USART + peripherals (up to 48 MHz) + + (#) CSS (Clock security system), once enable using the macro __HAL_RCC_CSS_ENABLE() + and if a HSE clock failure occurs(HSE used directly or through PLL as System + clock source), the System clocks automatically switched to HSI and an interrupt + is generated if enabled. The interrupt is linked to the Cortex-M0 NMI + (Non-Maskable Interrupt) exception vector. + + (#) MCO (microcontroller clock output), used to output SYSCLK, HSI, HSE, LSI, LSE or PLL + clock (divided by 2) output on pin (such as PA8 pin). + + [..] System, AHB and APB buses clocks configuration + (#) Several clock sources can be used to drive the System clock (SYSCLK): HSI, + HSE and PLL. + The AHB clock (HCLK) is derived from System clock through configurable + prescaler and used to clock the CPU, memory and peripherals mapped + on AHB bus (DMA, GPIO...). APB1 (PCLK1) clock is derived + from AHB clock through configurable prescalers and used to clock + the peripherals mapped on these buses. You can use + "@ref HAL_RCC_GetSysClockFreq()" function to retrieve the frequencies of these clocks. + + (#) All the peripheral clocks are derived from the System clock (SYSCLK) except: + (++) The FLASH program/erase clock which is always HSI 8MHz clock. + (++) The USB 48 MHz clock which is derived from the PLL VCO clock. + (++) The USART clock which can be derived as well from HSI 8MHz, LSI or LSE. + (++) The I2C clock which can be derived as well from HSI 8MHz clock. + (++) The ADC clock which is derived from PLL output. + (++) The RTC clock which is derived from the LSE, LSI or 1 MHz HSE_RTC + (HSE divided by a programmable prescaler). The System clock (SYSCLK) + frequency must be higher or equal to the RTC clock frequency. + (++) IWDG clock which is always the LSI clock. + + (#) For the STM32F0xx devices, the maximum frequency of the SYSCLK, HCLK and PCLK1 is 48 MHz, + Depending on the SYSCLK frequency, the flash latency should be adapted accordingly. + + (#) After reset, the System clock source is the HSI (8 MHz) with 0 WS and + prefetch is disabled. + @endverbatim + * @{ + */ + +/* + Additional consideration on the SYSCLK based on Latency settings: + +-----------------------------------------------+ + | Latency | SYSCLK clock frequency (MHz) | + |---------------|-------------------------------| + |0WS(1CPU cycle)| 0 < SYSCLK <= 24 | + |---------------|-------------------------------| + |1WS(2CPU cycle)| 24 < SYSCLK <= 48 | + +-----------------------------------------------+ + */ + +/** + * @brief Resets the RCC clock configuration to the default reset state. + * @note The default reset state of the clock configuration is given below: + * - HSI ON and used as system clock source + * - HSE and PLL OFF + * - AHB, APB1 prescaler set to 1. + * - CSS and MCO1 OFF + * - All interrupts disabled + * - All interrupt and reset flags cleared + * @note This function does not modify the configuration of the + * - Peripheral clocks + * - LSI, LSE and RTC clocks + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RCC_DeInit(void) +{ + uint32_t tickstart; + + /* Get Start Tick*/ + tickstart = HAL_GetTick(); + + /* Set HSION bit, HSITRIM[4:0] bits to the reset value*/ + SET_BIT(RCC->CR, RCC_CR_HSION | RCC_CR_HSITRIM_4); + + /* Wait till HSI is ready */ + while (READ_BIT(RCC->CR, RCC_CR_HSIRDY) == RESET) + { + if ((HAL_GetTick() - tickstart) > HSI_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + + /* Reset SW[1:0], HPRE[3:0], PPRE[2:0] and MCOSEL[2:0] bits */ + CLEAR_BIT(RCC->CFGR, RCC_CFGR_SW | RCC_CFGR_HPRE | RCC_CFGR_PPRE | RCC_CFGR_MCO); + + /* Wait till HSI as SYSCLK status is enabled */ + while (READ_BIT(RCC->CFGR, RCC_CFGR_SWS) != RESET) + { + if ((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + + /* Update the SystemCoreClock global variable for HSI as system clock source */ + SystemCoreClock = HSI_VALUE; + + /* Adapt Systick interrupt period */ + if (HAL_InitTick(uwTickPrio) != HAL_OK) + { + return HAL_ERROR; + } + + /* Reset HSEON, CSSON, PLLON bits */ + CLEAR_BIT(RCC->CR, RCC_CR_PLLON | RCC_CR_CSSON | RCC_CR_HSEON); + + /* Reset HSEBYP bit */ + CLEAR_BIT(RCC->CR, RCC_CR_HSEBYP); + + /* Get start tick */ + tickstart = HAL_GetTick(); + + /* Wait till PLLRDY is cleared */ + while(READ_BIT(RCC->CR, RCC_CR_PLLRDY) != RESET) + { + if((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + + /* Reset CFGR register */ + CLEAR_REG(RCC->CFGR); + + /* Reset CFGR2 register */ + CLEAR_REG(RCC->CFGR2); + + /* Reset CFGR3 register */ + CLEAR_REG(RCC->CFGR3); + + /* Disable all interrupts */ + CLEAR_REG(RCC->CIR); + + /* Clear all reset flags */ + __HAL_RCC_CLEAR_RESET_FLAGS(); + + return HAL_OK; +} + +/** + * @brief Initializes the RCC Oscillators according to the specified parameters in the + * RCC_OscInitTypeDef. + * @param RCC_OscInitStruct pointer to an RCC_OscInitTypeDef structure that + * contains the configuration information for the RCC Oscillators. + * @note The PLL is not disabled when used as system clock. + * @note Transitions LSE Bypass to LSE On and LSE On to LSE Bypass are not + * supported by this macro. User should request a transition to LSE Off + * first and then LSE On or LSE Bypass. + * @note Transition HSE Bypass to HSE On and HSE On to HSE Bypass are not + * supported by this macro. User should request a transition to HSE Off + * first and then HSE On or HSE Bypass. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RCC_OscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct) +{ + uint32_t tickstart; + uint32_t pll_config; + uint32_t pll_config2; + + /* Check Null pointer */ + if(RCC_OscInitStruct == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_RCC_OSCILLATORTYPE(RCC_OscInitStruct->OscillatorType)); + + /*------------------------------- HSE Configuration ------------------------*/ + if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSE) == RCC_OSCILLATORTYPE_HSE) + { + /* Check the parameters */ + assert_param(IS_RCC_HSE(RCC_OscInitStruct->HSEState)); + + /* When the HSE is used as system clock or clock source for PLL in these cases it is not allowed to be disabled */ + if((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_HSE) + || ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && (__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_HSE))) + { + if((__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) != RESET) && (RCC_OscInitStruct->HSEState == RCC_HSE_OFF)) + { + return HAL_ERROR; + } + } + else + { + /* Set the new HSE configuration ---------------------------------------*/ + __HAL_RCC_HSE_CONFIG(RCC_OscInitStruct->HSEState); + + + /* Check the HSE State */ + if(RCC_OscInitStruct->HSEState != RCC_HSE_OFF) + { + /* Get Start Tick */ + tickstart = HAL_GetTick(); + + /* Wait till HSE is ready */ + while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) == RESET) + { + if((HAL_GetTick() - tickstart ) > HSE_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + } + else + { + /* Get Start Tick */ + tickstart = HAL_GetTick(); + + /* Wait till HSE is disabled */ + while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) != RESET) + { + if((HAL_GetTick() - tickstart ) > HSE_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + } + } + } + /*----------------------------- HSI Configuration --------------------------*/ + if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSI) == RCC_OSCILLATORTYPE_HSI) + { + /* Check the parameters */ + assert_param(IS_RCC_HSI(RCC_OscInitStruct->HSIState)); + assert_param(IS_RCC_CALIBRATION_VALUE(RCC_OscInitStruct->HSICalibrationValue)); + + /* Check if HSI is used as system clock or as PLL source when PLL is selected as system clock */ + if((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_HSI) + || ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && (__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_HSI))) + { + /* When HSI is used as system clock it will not disabled */ + if((__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) != RESET) && (RCC_OscInitStruct->HSIState != RCC_HSI_ON)) + { + return HAL_ERROR; + } + /* Otherwise, just the calibration is allowed */ + else + { + /* Adjusts the Internal High Speed oscillator (HSI) calibration value.*/ + __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->HSICalibrationValue); + } + } + else + { + /* Check the HSI State */ + if(RCC_OscInitStruct->HSIState != RCC_HSI_OFF) + { + /* Enable the Internal High Speed oscillator (HSI). */ + __HAL_RCC_HSI_ENABLE(); + + /* Get Start Tick */ + tickstart = HAL_GetTick(); + + /* Wait till HSI is ready */ + while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) == RESET) + { + if((HAL_GetTick() - tickstart ) > HSI_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + + /* Adjusts the Internal High Speed oscillator (HSI) calibration value.*/ + __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->HSICalibrationValue); + } + else + { + /* Disable the Internal High Speed oscillator (HSI). */ + __HAL_RCC_HSI_DISABLE(); + + /* Get Start Tick */ + tickstart = HAL_GetTick(); + + /* Wait till HSI is disabled */ + while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) != RESET) + { + if((HAL_GetTick() - tickstart ) > HSI_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + } + } + } + /*------------------------------ LSI Configuration -------------------------*/ + if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSI) == RCC_OSCILLATORTYPE_LSI) + { + /* Check the parameters */ + assert_param(IS_RCC_LSI(RCC_OscInitStruct->LSIState)); + + /* Check the LSI State */ + if(RCC_OscInitStruct->LSIState != RCC_LSI_OFF) + { + /* Enable the Internal Low Speed oscillator (LSI). */ + __HAL_RCC_LSI_ENABLE(); + + /* Get Start Tick */ + tickstart = HAL_GetTick(); + + /* Wait till LSI is ready */ + while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSIRDY) == RESET) + { + if((HAL_GetTick() - tickstart ) > LSI_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + } + else + { + /* Disable the Internal Low Speed oscillator (LSI). */ + __HAL_RCC_LSI_DISABLE(); + + /* Get Start Tick */ + tickstart = HAL_GetTick(); + + /* Wait till LSI is disabled */ + while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSIRDY) != RESET) + { + if((HAL_GetTick() - tickstart ) > LSI_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + } + } + /*------------------------------ LSE Configuration -------------------------*/ + if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSE) == RCC_OSCILLATORTYPE_LSE) + { + FlagStatus pwrclkchanged = RESET; + + /* Check the parameters */ + assert_param(IS_RCC_LSE(RCC_OscInitStruct->LSEState)); + + /* Update LSE configuration in Backup Domain control register */ + /* Requires to enable write access to Backup Domain of necessary */ + if(__HAL_RCC_PWR_IS_CLK_DISABLED()) + { + __HAL_RCC_PWR_CLK_ENABLE(); + pwrclkchanged = SET; + } + + if(HAL_IS_BIT_CLR(PWR->CR, PWR_CR_DBP)) + { + /* Enable write access to Backup domain */ + SET_BIT(PWR->CR, PWR_CR_DBP); + + /* Wait for Backup domain Write protection disable */ + tickstart = HAL_GetTick(); + + while(HAL_IS_BIT_CLR(PWR->CR, PWR_CR_DBP)) + { + if((HAL_GetTick() - tickstart) > RCC_DBP_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + } + + /* Set the new LSE configuration -----------------------------------------*/ + __HAL_RCC_LSE_CONFIG(RCC_OscInitStruct->LSEState); + /* Check the LSE State */ + if(RCC_OscInitStruct->LSEState != RCC_LSE_OFF) + { + /* Get Start Tick */ + tickstart = HAL_GetTick(); + + /* Wait till LSE is ready */ + while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET) + { + if((HAL_GetTick() - tickstart ) > RCC_LSE_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + } + else + { + /* Get Start Tick */ + tickstart = HAL_GetTick(); + + /* Wait till LSE is disabled */ + while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) != RESET) + { + if((HAL_GetTick() - tickstart ) > RCC_LSE_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + } + + /* Require to disable power clock if necessary */ + if(pwrclkchanged == SET) + { + __HAL_RCC_PWR_CLK_DISABLE(); + } + } + + /*----------------------------- HSI14 Configuration --------------------------*/ + if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSI14) == RCC_OSCILLATORTYPE_HSI14) + { + /* Check the parameters */ + assert_param(IS_RCC_HSI14(RCC_OscInitStruct->HSI14State)); + assert_param(IS_RCC_CALIBRATION_VALUE(RCC_OscInitStruct->HSI14CalibrationValue)); + + /* Check the HSI14 State */ + if(RCC_OscInitStruct->HSI14State == RCC_HSI14_ON) + { + /* Disable ADC control of the Internal High Speed oscillator HSI14 */ + __HAL_RCC_HSI14ADC_DISABLE(); + + /* Enable the Internal High Speed oscillator (HSI). */ + __HAL_RCC_HSI14_ENABLE(); + + /* Get Start Tick */ + tickstart = HAL_GetTick(); + + /* Wait till HSI is ready */ + while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSI14RDY) == RESET) + { + if((HAL_GetTick() - tickstart) > HSI14_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + + /* Adjusts the Internal High Speed oscillator 14Mhz (HSI14) calibration value. */ + __HAL_RCC_HSI14_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->HSI14CalibrationValue); + } + else if(RCC_OscInitStruct->HSI14State == RCC_HSI14_ADC_CONTROL) + { + /* Enable ADC control of the Internal High Speed oscillator HSI14 */ + __HAL_RCC_HSI14ADC_ENABLE(); + + /* Adjusts the Internal High Speed oscillator 14Mhz (HSI14) calibration value. */ + __HAL_RCC_HSI14_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->HSI14CalibrationValue); + } + else + { + /* Disable ADC control of the Internal High Speed oscillator HSI14 */ + __HAL_RCC_HSI14ADC_DISABLE(); + + /* Disable the Internal High Speed oscillator (HSI). */ + __HAL_RCC_HSI14_DISABLE(); + + /* Get Start Tick */ + tickstart = HAL_GetTick(); + + /* Wait till HSI is ready */ + while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSI14RDY) != RESET) + { + if((HAL_GetTick() - tickstart) > HSI14_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + } + } + +#if defined(RCC_HSI48_SUPPORT) + /*----------------------------- HSI48 Configuration --------------------------*/ + if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSI48) == RCC_OSCILLATORTYPE_HSI48) + { + /* Check the parameters */ + assert_param(IS_RCC_HSI48(RCC_OscInitStruct->HSI48State)); + + /* When the HSI48 is used as system clock it is not allowed to be disabled */ + if((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_HSI48) || + ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && (__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_HSI48))) + { + if((__HAL_RCC_GET_FLAG(RCC_FLAG_HSI48RDY) != RESET) && (RCC_OscInitStruct->HSI48State != RCC_HSI48_ON)) + { + return HAL_ERROR; + } + } + else + { + /* Check the HSI48 State */ + if(RCC_OscInitStruct->HSI48State != RCC_HSI48_OFF) + { + /* Enable the Internal High Speed oscillator (HSI48). */ + __HAL_RCC_HSI48_ENABLE(); + + /* Get Start Tick */ + tickstart = HAL_GetTick(); + + /* Wait till HSI48 is ready */ + while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSI48RDY) == RESET) + { + if((HAL_GetTick() - tickstart) > HSI48_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + } + else + { + /* Disable the Internal High Speed oscillator (HSI48). */ + __HAL_RCC_HSI48_DISABLE(); + + /* Get Start Tick */ + tickstart = HAL_GetTick(); + + /* Wait till HSI48 is ready */ + while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSI48RDY) != RESET) + { + if((HAL_GetTick() - tickstart) > HSI48_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + } + } + } +#endif /* RCC_HSI48_SUPPORT */ + + /*-------------------------------- PLL Configuration -----------------------*/ + /* Check the parameters */ + assert_param(IS_RCC_PLL(RCC_OscInitStruct->PLL.PLLState)); + if ((RCC_OscInitStruct->PLL.PLLState) != RCC_PLL_NONE) + { + /* Check if the PLL is used as system clock or not */ + if(__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_SYSCLKSOURCE_STATUS_PLLCLK) + { + if((RCC_OscInitStruct->PLL.PLLState) == RCC_PLL_ON) + { + /* Check the parameters */ + assert_param(IS_RCC_PLLSOURCE(RCC_OscInitStruct->PLL.PLLSource)); + assert_param(IS_RCC_PLL_MUL(RCC_OscInitStruct->PLL.PLLMUL)); + assert_param(IS_RCC_PREDIV(RCC_OscInitStruct->PLL.PREDIV)); + + /* Disable the main PLL. */ + __HAL_RCC_PLL_DISABLE(); + + /* Get Start Tick */ + tickstart = HAL_GetTick(); + + /* Wait till PLL is disabled */ + while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) != RESET) + { + if((HAL_GetTick() - tickstart ) > PLL_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + + /* Configure the main PLL clock source, predivider and multiplication factor. */ + __HAL_RCC_PLL_CONFIG(RCC_OscInitStruct->PLL.PLLSource, + RCC_OscInitStruct->PLL.PREDIV, + RCC_OscInitStruct->PLL.PLLMUL); + /* Enable the main PLL. */ + __HAL_RCC_PLL_ENABLE(); + + /* Get Start Tick */ + tickstart = HAL_GetTick(); + + /* Wait till PLL is ready */ + while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) == RESET) + { + if((HAL_GetTick() - tickstart ) > PLL_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + } + else + { + /* Disable the main PLL. */ + __HAL_RCC_PLL_DISABLE(); + + /* Get Start Tick */ + tickstart = HAL_GetTick(); + + /* Wait till PLL is disabled */ + while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) != RESET) + { + if((HAL_GetTick() - tickstart ) > PLL_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + } + } + else + { + /* Check if there is a request to disable the PLL used as System clock source */ + if((RCC_OscInitStruct->PLL.PLLState) == RCC_PLL_OFF) + { + return HAL_ERROR; + } + else + { + /* Do not return HAL_ERROR if request repeats the current configuration */ + pll_config = RCC->CFGR; + pll_config2 = RCC->CFGR2; + if((READ_BIT(pll_config, RCC_CFGR_PLLSRC) != RCC_OscInitStruct->PLL.PLLSource) || + (READ_BIT(pll_config2, RCC_CFGR2_PREDIV) != RCC_OscInitStruct->PLL.PREDIV) || + (READ_BIT(pll_config, RCC_CFGR_PLLMUL) != RCC_OscInitStruct->PLL.PLLMUL)) + { + return HAL_ERROR; + } + } + } + } + + return HAL_OK; +} + +/** + * @brief Initializes the CPU, AHB and APB buses clocks according to the specified + * parameters in the RCC_ClkInitStruct. + * @param RCC_ClkInitStruct pointer to an RCC_OscInitTypeDef structure that + * contains the configuration information for the RCC peripheral. + * @param FLatency FLASH Latency + * The value of this parameter depend on device used within the same series + * @note The SystemCoreClock CMSIS variable is used to store System Clock Frequency + * and updated by @ref HAL_RCC_GetHCLKFreq() function called within this function + * + * @note The HSI is used (enabled by hardware) as system clock source after + * start-up from Reset, wake-up from STOP and STANDBY mode, or in case + * of failure of the HSE used directly or indirectly as system clock + * (if the Clock Security System CSS is enabled). + * + * @note A switch from one clock source to another occurs only if the target + * clock source is ready (clock stable after start-up delay or PLL locked). + * If a clock source which is not yet ready is selected, the switch will + * occur when the clock source will be ready. + * You can use @ref HAL_RCC_GetClockConfig() function to know which clock is + * currently used as system clock source. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RCC_ClockConfig(RCC_ClkInitTypeDef *RCC_ClkInitStruct, uint32_t FLatency) +{ + uint32_t tickstart; + + /* Check Null pointer */ + if(RCC_ClkInitStruct == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_RCC_CLOCKTYPE(RCC_ClkInitStruct->ClockType)); + assert_param(IS_FLASH_LATENCY(FLatency)); + + /* To correctly read data from FLASH memory, the number of wait states (LATENCY) + must be correctly programmed according to the frequency of the CPU clock + (HCLK) of the device. */ + + /* Increasing the number of wait states because of higher CPU frequency */ + if(FLatency > __HAL_FLASH_GET_LATENCY()) + { + /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */ + __HAL_FLASH_SET_LATENCY(FLatency); + + /* Check that the new number of wait states is taken into account to access the Flash + memory by reading the FLASH_ACR register */ + if(__HAL_FLASH_GET_LATENCY() != FLatency) + { + return HAL_ERROR; + } + } + + /*-------------------------- HCLK Configuration --------------------------*/ + if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_HCLK) == RCC_CLOCKTYPE_HCLK) + { + /* Set the highest APB divider in order to ensure that we do not go through + a non-spec phase whatever we decrease or increase HCLK. */ + if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK1) == RCC_CLOCKTYPE_PCLK1) + { + MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE, RCC_HCLK_DIV16); + } + + /* Set the new HCLK clock divider */ + assert_param(IS_RCC_HCLK(RCC_ClkInitStruct->AHBCLKDivider)); + MODIFY_REG(RCC->CFGR, RCC_CFGR_HPRE, RCC_ClkInitStruct->AHBCLKDivider); + } + + /*------------------------- SYSCLK Configuration ---------------------------*/ + if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_SYSCLK) == RCC_CLOCKTYPE_SYSCLK) + { + assert_param(IS_RCC_SYSCLKSOURCE(RCC_ClkInitStruct->SYSCLKSource)); + + /* HSE is selected as System Clock Source */ + if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_HSE) + { + /* Check the HSE ready flag */ + if(__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) == RESET) + { + return HAL_ERROR; + } + } + /* PLL is selected as System Clock Source */ + else if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_PLLCLK) + { + /* Check the PLL ready flag */ + if(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) == RESET) + { + return HAL_ERROR; + } + } +#if defined(RCC_CFGR_SWS_HSI48) + /* HSI48 is selected as System Clock Source */ + else if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_HSI48) + { + /* Check the HSI48 ready flag */ + if(__HAL_RCC_GET_FLAG(RCC_FLAG_HSI48RDY) == RESET) + { + return HAL_ERROR; + } + } +#endif /* RCC_CFGR_SWS_HSI48 */ + /* HSI is selected as System Clock Source */ + else + { + /* Check the HSI ready flag */ + if(__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) == RESET) + { + return HAL_ERROR; + } + } + __HAL_RCC_SYSCLK_CONFIG(RCC_ClkInitStruct->SYSCLKSource); + + /* Get Start Tick */ + tickstart = HAL_GetTick(); + + while (__HAL_RCC_GET_SYSCLK_SOURCE() != (RCC_ClkInitStruct->SYSCLKSource << RCC_CFGR_SWS_Pos)) + { + if((HAL_GetTick() - tickstart ) > CLOCKSWITCH_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + } + + /* Decreasing the number of wait states because of lower CPU frequency */ + if(FLatency < __HAL_FLASH_GET_LATENCY()) + { + /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */ + __HAL_FLASH_SET_LATENCY(FLatency); + + /* Check that the new number of wait states is taken into account to access the Flash + memory by reading the FLASH_ACR register */ + if(__HAL_FLASH_GET_LATENCY() != FLatency) + { + return HAL_ERROR; + } + } + + /*-------------------------- PCLK1 Configuration ---------------------------*/ + if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK1) == RCC_CLOCKTYPE_PCLK1) + { + assert_param(IS_RCC_PCLK(RCC_ClkInitStruct->APB1CLKDivider)); + MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE, RCC_ClkInitStruct->APB1CLKDivider); + } + + /* Update the SystemCoreClock global variable */ + SystemCoreClock = HAL_RCC_GetSysClockFreq() >> AHBPrescTable[(RCC->CFGR & RCC_CFGR_HPRE)>> RCC_CFGR_HPRE_BITNUMBER]; + + /* Configure the source of time base considering new system clocks settings*/ + HAL_InitTick (TICK_INT_PRIORITY); + + return HAL_OK; +} + +/** + * @} + */ + +/** @defgroup RCC_Exported_Functions_Group2 Peripheral Control functions + * @brief RCC clocks control functions + * + @verbatim + =============================================================================== + ##### Peripheral Control functions ##### + =============================================================================== + [..] + This subsection provides a set of functions allowing to control the RCC Clocks + frequencies. + + @endverbatim + * @{ + */ + +#if defined(RCC_CFGR_MCOPRE) +/** + * @brief Selects the clock source to output on MCO pin. + * @note MCO pin should be configured in alternate function mode. + * @param RCC_MCOx specifies the output direction for the clock source. + * This parameter can be one of the following values: + * @arg @ref RCC_MCO1 Clock source to output on MCO1 pin(PA8). + * @param RCC_MCOSource specifies the clock source to output. + * This parameter can be one of the following values: + * @arg @ref RCC_MCO1SOURCE_NOCLOCK No clock selected + * @arg @ref RCC_MCO1SOURCE_SYSCLK System Clock selected as MCO clock + * @arg @ref RCC_MCO1SOURCE_HSI HSI selected as MCO clock + * @arg @ref RCC_MCO1SOURCE_HSE HSE selected as MCO clock + * @arg @ref RCC_MCO1SOURCE_LSI LSI selected as MCO clock + * @arg @ref RCC_MCO1SOURCE_LSE LSE selected as MCO clock + * @arg @ref RCC_MCO1SOURCE_HSI14 HSI14 selected as MCO clock + @if STM32F042x6 + * @arg @ref RCC_MCO1SOURCE_HSI48 HSI48 selected as MCO clock + * @arg @ref RCC_MCO1SOURCE_PLLCLK PLLCLK selected as MCO clock + @elseif STM32F048xx + * @arg @ref RCC_MCO1SOURCE_HSI48 HSI48 selected as MCO clock + * @arg @ref RCC_MCO1SOURCE_PLLCLK PLLCLK selected as MCO clock + @elseif STM32F071xB + * @arg @ref RCC_MCO1SOURCE_HSI48 HSI48 selected as MCO clock + * @arg @ref RCC_MCO1SOURCE_PLLCLK PLLCLK selected as MCO clock + @elseif STM32F072xB + * @arg @ref RCC_MCO1SOURCE_HSI48 HSI48 selected as MCO clock + * @arg @ref RCC_MCO1SOURCE_PLLCLK PLLCLK selected as MCO clock + @elseif STM32F078xx + * @arg @ref RCC_MCO1SOURCE_HSI48 HSI48 selected as MCO clock + * @arg @ref RCC_MCO1SOURCE_PLLCLK PLLCLK selected as MCO clock + @elseif STM32F091xC + * @arg @ref RCC_MCO1SOURCE_HSI48 HSI48 selected as MCO clock + * @arg @ref RCC_MCO1SOURCE_PLLCLK PLLCLK selected as MCO clock + @elseif STM32F098xx + * @arg @ref RCC_MCO1SOURCE_HSI48 HSI48 selected as MCO clock + * @arg @ref RCC_MCO1SOURCE_PLLCLK PLLCLK selected as MCO clock + @elif STM32F030x6 + * @arg @ref RCC_MCO1SOURCE_PLLCLK PLLCLK selected as MCO clock + @elif STM32F030xC + * @arg @ref RCC_MCO1SOURCE_PLLCLK PLLCLK selected as MCO clock + @elif STM32F031x6 + * @arg @ref RCC_MCO1SOURCE_PLLCLK PLLCLK selected as MCO clock + @elif STM32F038xx + * @arg @ref RCC_MCO1SOURCE_PLLCLK PLLCLK selected as MCO clock + @elif STM32F070x6 + * @arg @ref RCC_MCO1SOURCE_PLLCLK PLLCLK selected as MCO clock + @elif STM32F070xB + * @arg @ref RCC_MCO1SOURCE_PLLCLK PLLCLK selected as MCO clock + @endif + * @arg @ref RCC_MCO1SOURCE_PLLCLK_DIV2 PLLCLK Divided by 2 selected as MCO clock + * @param RCC_MCODiv specifies the MCO DIV. + * This parameter can be one of the following values: + * @arg @ref RCC_MCODIV_1 no division applied to MCO clock + * @arg @ref RCC_MCODIV_2 division by 2 applied to MCO clock + * @arg @ref RCC_MCODIV_4 division by 4 applied to MCO clock + * @arg @ref RCC_MCODIV_8 division by 8 applied to MCO clock + * @arg @ref RCC_MCODIV_16 division by 16 applied to MCO clock + * @arg @ref RCC_MCODIV_32 division by 32 applied to MCO clock + * @arg @ref RCC_MCODIV_64 division by 64 applied to MCO clock + * @arg @ref RCC_MCODIV_128 division by 128 applied to MCO clock + * @retval None + */ +#else +/** + * @brief Selects the clock source to output on MCO pin. + * @note MCO pin should be configured in alternate function mode. + * @param RCC_MCOx specifies the output direction for the clock source. + * This parameter can be one of the following values: + * @arg @ref RCC_MCO1 Clock source to output on MCO1 pin(PA8). + * @param RCC_MCOSource specifies the clock source to output. + * This parameter can be one of the following values: + * @arg @ref RCC_MCO1SOURCE_NOCLOCK No clock selected as MCO clock + * @arg @ref RCC_MCO1SOURCE_SYSCLK System clock selected as MCO clock + * @arg @ref RCC_MCO1SOURCE_HSI HSI selected as MCO clock + * @arg @ref RCC_MCO1SOURCE_HSE HSE selected as MCO clock + * @arg @ref RCC_MCO1SOURCE_LSI LSI selected as MCO clock + * @arg @ref RCC_MCO1SOURCE_LSE LSE selected as MCO clock + * @arg @ref RCC_MCO1SOURCE_HSI14 HSI14 selected as MCO clock + * @arg @ref RCC_MCO1SOURCE_PLLCLK_DIV2 PLLCLK Divided by 2 selected as MCO clock + * @param RCC_MCODiv specifies the MCO DIV. + * This parameter can be one of the following values: + * @arg @ref RCC_MCODIV_1 no division applied to MCO clock + * @retval None + */ +#endif +void HAL_RCC_MCOConfig(uint32_t RCC_MCOx, uint32_t RCC_MCOSource, uint32_t RCC_MCODiv) +{ + GPIO_InitTypeDef gpio; + + /* Check the parameters */ + assert_param(IS_RCC_MCO(RCC_MCOx)); + assert_param(IS_RCC_MCODIV(RCC_MCODiv)); + assert_param(IS_RCC_MCO1SOURCE(RCC_MCOSource)); + + /* Configure the MCO1 pin in alternate function mode */ + gpio.Mode = GPIO_MODE_AF_PP; + gpio.Speed = GPIO_SPEED_FREQ_HIGH; + gpio.Pull = GPIO_NOPULL; + gpio.Pin = MCO1_PIN; + gpio.Alternate = GPIO_AF0_MCO; + + /* MCO1 Clock Enable */ + MCO1_CLK_ENABLE(); + + HAL_GPIO_Init(MCO1_GPIO_PORT, &gpio); + + /* Configure the MCO clock source */ + __HAL_RCC_MCO1_CONFIG(RCC_MCOSource, RCC_MCODiv); +} + +/** + * @brief Enables the Clock Security System. + * @note If a failure is detected on the HSE oscillator clock, this oscillator + * is automatically disabled and an interrupt is generated to inform the + * software about the failure (Clock Security System Interrupt, CSSI), + * allowing the MCU to perform rescue operations. The CSSI is linked to + * the Cortex-M0 NMI (Non-Maskable Interrupt) exception vector. + * @retval None + */ +void HAL_RCC_EnableCSS(void) +{ + SET_BIT(RCC->CR, RCC_CR_CSSON) ; +} + +/** + * @brief Disables the Clock Security System. + * @retval None + */ +void HAL_RCC_DisableCSS(void) +{ + CLEAR_BIT(RCC->CR, RCC_CR_CSSON) ; +} + +/** + * @brief Returns the SYSCLK frequency + * @note The system frequency computed by this function is not the real + * frequency in the chip. It is calculated based on the predefined + * constant and the selected clock source: + * @note If SYSCLK source is HSI, function returns values based on HSI_VALUE(*) + * @note If SYSCLK source is HSE, function returns a value based on HSE_VALUE + * divided by PREDIV factor(**) + * @note If SYSCLK source is PLL, function returns a value based on HSE_VALUE + * divided by PREDIV factor(**) or depending on STM32F0xxxx devices either a value based + * on HSI_VALUE divided by 2 or HSI_VALUE divided by PREDIV factor(*) multiplied by the + * PLL factor. + * @note (*) HSI_VALUE is a constant defined in stm32f0xx_hal_conf.h file (default value + * 8 MHz) but the real value may vary depending on the variations + * in voltage and temperature. + * @note (**) HSE_VALUE is a constant defined in stm32f0xx_hal_conf.h file (default value + * 8 MHz), user has to ensure that HSE_VALUE is same as the real + * frequency of the crystal used. Otherwise, this function may + * have wrong result. + * + * @note The result of this function could be not correct when using fractional + * value for HSE crystal. + * + * @note This function can be used by the user application to compute the + * baud-rate for the communication peripherals or configure other parameters. + * + * @note Each time SYSCLK changes, this function must be called to update the + * right SYSCLK value. Otherwise, any configuration based on this function will be incorrect. + * + * @retval SYSCLK frequency + */ +uint32_t HAL_RCC_GetSysClockFreq(void) +{ + const uint8_t aPLLMULFactorTable[16] = { 2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, + 10U, 11U, 12U, 13U, 14U, 15U, 16U, 16U}; + const uint8_t aPredivFactorTable[16] = { 1U, 2U, 3U, 4U, 5U, 6U, 7U, 8U, + 9U,10U, 11U, 12U, 13U, 14U, 15U, 16U}; + + uint32_t tmpreg = 0U, prediv = 0U, pllclk = 0U, pllmul = 0U; + uint32_t sysclockfreq = 0U; + + tmpreg = RCC->CFGR; + + /* Get SYSCLK source -------------------------------------------------------*/ + switch (tmpreg & RCC_CFGR_SWS) + { + case RCC_SYSCLKSOURCE_STATUS_HSE: /* HSE used as system clock */ + { + sysclockfreq = HSE_VALUE; + break; + } + case RCC_SYSCLKSOURCE_STATUS_PLLCLK: /* PLL used as system clock */ + { + pllmul = aPLLMULFactorTable[(uint32_t)(tmpreg & RCC_CFGR_PLLMUL) >> RCC_CFGR_PLLMUL_BITNUMBER]; + prediv = aPredivFactorTable[(uint32_t)(RCC->CFGR2 & RCC_CFGR2_PREDIV) >> RCC_CFGR2_PREDIV_BITNUMBER]; + if ((tmpreg & RCC_CFGR_PLLSRC) == RCC_PLLSOURCE_HSE) + { + /* HSE used as PLL clock source : PLLCLK = HSE/PREDIV * PLLMUL */ + pllclk = (uint32_t)((uint64_t) HSE_VALUE / (uint64_t) (prediv)) * ((uint64_t) pllmul); + } +#if defined(RCC_CFGR_PLLSRC_HSI48_PREDIV) + else if ((tmpreg & RCC_CFGR_PLLSRC) == RCC_PLLSOURCE_HSI48) + { + /* HSI48 used as PLL clock source : PLLCLK = HSI48/PREDIV * PLLMUL */ + pllclk = (uint32_t)((uint64_t) HSI48_VALUE / (uint64_t) (prediv)) * ((uint64_t) pllmul); + } +#endif /* RCC_CFGR_PLLSRC_HSI48_PREDIV */ + else + { +#if (defined(STM32F042x6) || defined(STM32F048xx) || defined(STM32F070x6) || defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F078xx) || defined(STM32F070xB) || defined(STM32F091xC) || defined(STM32F098xx) || defined(STM32F030xC)) + /* HSI used as PLL clock source : PLLCLK = HSI/PREDIV * PLLMUL */ + pllclk = (uint32_t)((uint64_t) HSI_VALUE / (uint64_t) (prediv)) * ((uint64_t) pllmul); +#else + /* HSI used as PLL clock source : PLLCLK = HSI/2 * PLLMUL */ + pllclk = (uint32_t)((uint64_t) (HSI_VALUE >> 1U) * ((uint64_t) pllmul)); +#endif + } + sysclockfreq = pllclk; + break; + } +#if defined(RCC_CFGR_SWS_HSI48) + case RCC_SYSCLKSOURCE_STATUS_HSI48: /* HSI48 used as system clock source */ + { + sysclockfreq = HSI48_VALUE; + break; + } +#endif /* RCC_CFGR_SWS_HSI48 */ + case RCC_SYSCLKSOURCE_STATUS_HSI: /* HSI used as system clock source */ + default: /* HSI used as system clock */ + { + sysclockfreq = HSI_VALUE; + break; + } + } + return sysclockfreq; +} + +/** + * @brief Returns the HCLK frequency + * @note Each time HCLK changes, this function must be called to update the + * right HCLK value. Otherwise, any configuration based on this function will be incorrect. + * + * @note The SystemCoreClock CMSIS variable is used to store System Clock Frequency + * and updated within this function + * @retval HCLK frequency + */ +uint32_t HAL_RCC_GetHCLKFreq(void) +{ + return SystemCoreClock; +} + +/** + * @brief Returns the PCLK1 frequency + * @note Each time PCLK1 changes, this function must be called to update the + * right PCLK1 value. Otherwise, any configuration based on this function will be incorrect. + * @retval PCLK1 frequency + */ +uint32_t HAL_RCC_GetPCLK1Freq(void) +{ + /* Get HCLK source and Compute PCLK1 frequency ---------------------------*/ + return (HAL_RCC_GetHCLKFreq() >> APBPrescTable[(RCC->CFGR & RCC_CFGR_PPRE) >> RCC_CFGR_PPRE_BITNUMBER]); +} + +/** + * @brief Configures the RCC_OscInitStruct according to the internal + * RCC configuration registers. + * @param RCC_OscInitStruct pointer to an RCC_OscInitTypeDef structure that + * will be configured. + * @retval None + */ +void HAL_RCC_GetOscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct) +{ + /* Check the parameters */ + assert_param(RCC_OscInitStruct != NULL); + + /* Set all possible values for the Oscillator type parameter ---------------*/ + RCC_OscInitStruct->OscillatorType = RCC_OSCILLATORTYPE_HSE | RCC_OSCILLATORTYPE_HSI \ + | RCC_OSCILLATORTYPE_LSE | RCC_OSCILLATORTYPE_LSI | RCC_OSCILLATORTYPE_HSI14; +#if defined(RCC_HSI48_SUPPORT) + RCC_OscInitStruct->OscillatorType |= RCC_OSCILLATORTYPE_HSI48; +#endif /* RCC_HSI48_SUPPORT */ + + + /* Get the HSE configuration -----------------------------------------------*/ + if((RCC->CR &RCC_CR_HSEBYP) == RCC_CR_HSEBYP) + { + RCC_OscInitStruct->HSEState = RCC_HSE_BYPASS; + } + else if((RCC->CR &RCC_CR_HSEON) == RCC_CR_HSEON) + { + RCC_OscInitStruct->HSEState = RCC_HSE_ON; + } + else + { + RCC_OscInitStruct->HSEState = RCC_HSE_OFF; + } + + /* Get the HSI configuration -----------------------------------------------*/ + if((RCC->CR &RCC_CR_HSION) == RCC_CR_HSION) + { + RCC_OscInitStruct->HSIState = RCC_HSI_ON; + } + else + { + RCC_OscInitStruct->HSIState = RCC_HSI_OFF; + } + + RCC_OscInitStruct->HSICalibrationValue = (uint32_t)((RCC->CR &RCC_CR_HSITRIM) >> RCC_CR_HSITRIM_BitNumber); + + /* Get the LSE configuration -----------------------------------------------*/ + if((RCC->BDCR &RCC_BDCR_LSEBYP) == RCC_BDCR_LSEBYP) + { + RCC_OscInitStruct->LSEState = RCC_LSE_BYPASS; + } + else if((RCC->BDCR &RCC_BDCR_LSEON) == RCC_BDCR_LSEON) + { + RCC_OscInitStruct->LSEState = RCC_LSE_ON; + } + else + { + RCC_OscInitStruct->LSEState = RCC_LSE_OFF; + } + + /* Get the LSI configuration -----------------------------------------------*/ + if((RCC->CSR &RCC_CSR_LSION) == RCC_CSR_LSION) + { + RCC_OscInitStruct->LSIState = RCC_LSI_ON; + } + else + { + RCC_OscInitStruct->LSIState = RCC_LSI_OFF; + } + + /* Get the HSI14 configuration -----------------------------------------------*/ + if((RCC->CR2 & RCC_CR2_HSI14ON) == RCC_CR2_HSI14ON) + { + RCC_OscInitStruct->HSI14State = RCC_HSI_ON; + } + else + { + RCC_OscInitStruct->HSI14State = RCC_HSI_OFF; + } + + RCC_OscInitStruct->HSI14CalibrationValue = (uint32_t)((RCC->CR2 & RCC_CR2_HSI14TRIM) >> RCC_HSI14TRIM_BIT_NUMBER); + +#if defined(RCC_HSI48_SUPPORT) + /* Get the HSI48 configuration if any-----------------------------------------*/ + RCC_OscInitStruct->HSI48State = __HAL_RCC_GET_HSI48_STATE(); +#endif /* RCC_HSI48_SUPPORT */ + + /* Get the PLL configuration -----------------------------------------------*/ + if((RCC->CR &RCC_CR_PLLON) == RCC_CR_PLLON) + { + RCC_OscInitStruct->PLL.PLLState = RCC_PLL_ON; + } + else + { + RCC_OscInitStruct->PLL.PLLState = RCC_PLL_OFF; + } + RCC_OscInitStruct->PLL.PLLSource = (uint32_t)(RCC->CFGR & RCC_CFGR_PLLSRC); + RCC_OscInitStruct->PLL.PLLMUL = (uint32_t)(RCC->CFGR & RCC_CFGR_PLLMUL); + RCC_OscInitStruct->PLL.PREDIV = (uint32_t)(RCC->CFGR2 & RCC_CFGR2_PREDIV); +} + +/** + * @brief Get the RCC_ClkInitStruct according to the internal + * RCC configuration registers. + * @param RCC_ClkInitStruct pointer to an RCC_ClkInitTypeDef structure that + * contains the current clock configuration. + * @param pFLatency Pointer on the Flash Latency. + * @retval None + */ +void HAL_RCC_GetClockConfig(RCC_ClkInitTypeDef *RCC_ClkInitStruct, uint32_t *pFLatency) +{ + /* Check the parameters */ + assert_param(RCC_ClkInitStruct != NULL); + assert_param(pFLatency != NULL); + + /* Set all possible values for the Clock type parameter --------------------*/ + RCC_ClkInitStruct->ClockType = RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1; + + /* Get the SYSCLK configuration --------------------------------------------*/ + RCC_ClkInitStruct->SYSCLKSource = (uint32_t)(RCC->CFGR & RCC_CFGR_SW); + + /* Get the HCLK configuration ----------------------------------------------*/ + RCC_ClkInitStruct->AHBCLKDivider = (uint32_t)(RCC->CFGR & RCC_CFGR_HPRE); + + /* Get the APB1 configuration ----------------------------------------------*/ + RCC_ClkInitStruct->APB1CLKDivider = (uint32_t)(RCC->CFGR & RCC_CFGR_PPRE); + /* Get the Flash Wait State (Latency) configuration ------------------------*/ + *pFLatency = __HAL_FLASH_GET_LATENCY(); +} + +/** + * @brief This function handles the RCC CSS interrupt request. + * @note This API should be called under the NMI_Handler(). + * @retval None + */ +void HAL_RCC_NMI_IRQHandler(void) +{ + /* Check RCC CSSF flag */ + if(__HAL_RCC_GET_IT(RCC_IT_CSS)) + { + /* RCC Clock Security System interrupt user callback */ + HAL_RCC_CSSCallback(); + + /* Clear RCC CSS pending bit */ + __HAL_RCC_CLEAR_IT(RCC_IT_CSS); + } +} + +/** + * @brief RCC Clock Security System interrupt callback + * @retval none + */ +__weak void HAL_RCC_CSSCallback(void) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_RCC_CSSCallback could be implemented in the user file + */ +} + +/** + * @} + */ + +/** + * @} + */ + +#endif /* HAL_RCC_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.c b/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.c new file mode 100644 index 0000000..386e9ae --- /dev/null +++ b/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.c @@ -0,0 +1,964 @@ +/** + ****************************************************************************** + * @file stm32f0xx_hal_rcc_ex.c + * @author MCD Application Team + * @brief Extended RCC HAL module driver. + * This file provides firmware functions to manage the following + * functionalities RCC extension peripheral: + * + Extended Peripheral Control functions + * + Extended Clock Recovery System Control functions + * + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2016 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f0xx_hal.h" + +/** @addtogroup STM32F0xx_HAL_Driver + * @{ + */ + +#ifdef HAL_RCC_MODULE_ENABLED + +/** @defgroup RCCEx RCCEx + * @brief RCC Extension HAL module driver. + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +#if defined(CRS) +/** @defgroup RCCEx_Private_Constants RCCEx Private Constants + * @{ + */ +/* Bit position in register */ +#define CRS_CFGR_FELIM_BITNUMBER 16 +#define CRS_CR_TRIM_BITNUMBER 8 +#define CRS_ISR_FECAP_BITNUMBER 16 +/** + * @} + */ +#endif /* CRS */ + +/* Private macro -------------------------------------------------------------*/ +/** @defgroup RCCEx_Private_Macros RCCEx Private Macros + * @{ + */ +/** + * @} + */ + +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + +/** @defgroup RCCEx_Exported_Functions RCCEx Exported Functions + * @{ + */ + +/** @defgroup RCCEx_Exported_Functions_Group1 Extended Peripheral Control functions + * @brief Extended Peripheral Control functions + * +@verbatim + =============================================================================== + ##### Extended Peripheral Control functions ##### + =============================================================================== + [..] + This subsection provides a set of functions allowing to control the RCC Clocks + frequencies. + [..] + (@) Important note: Care must be taken when HAL_RCCEx_PeriphCLKConfig() is used to + select the RTC clock source; in this case the Backup domain will be reset in + order to modify the RTC Clock source, as consequence RTC registers (including + the backup registers) are set to their reset values. + +@endverbatim + * @{ + */ + +/** + * @brief Initializes the RCC extended peripherals clocks according to the specified + * parameters in the RCC_PeriphCLKInitTypeDef. + * @param PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that + * contains the configuration information for the Extended Peripherals clocks + * (USART, RTC, I2C, CEC and USB). + * + * @note Care must be taken when @ref HAL_RCCEx_PeriphCLKConfig() is used to select + * the RTC clock source; in this case the Backup domain will be reset in + * order to modify the RTC Clock source, as consequence RTC registers (including + * the backup registers) and RCC_BDCR register are set to their reset values. + * + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit) +{ + uint32_t tickstart = 0U; + uint32_t temp_reg = 0U; + + /* Check the parameters */ + assert_param(IS_RCC_PERIPHCLOCK(PeriphClkInit->PeriphClockSelection)); + + /*---------------------------- RTC configuration -------------------------------*/ + if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_RTC) == (RCC_PERIPHCLK_RTC)) + { + /* check for RTC Parameters used to output RTCCLK */ + assert_param(IS_RCC_RTCCLKSOURCE(PeriphClkInit->RTCClockSelection)); + + FlagStatus pwrclkchanged = RESET; + + /* As soon as function is called to change RTC clock source, activation of the + power domain is done. */ + /* Requires to enable write access to Backup Domain of necessary */ + if(__HAL_RCC_PWR_IS_CLK_DISABLED()) + { + __HAL_RCC_PWR_CLK_ENABLE(); + pwrclkchanged = SET; + } + + if(HAL_IS_BIT_CLR(PWR->CR, PWR_CR_DBP)) + { + /* Enable write access to Backup domain */ + SET_BIT(PWR->CR, PWR_CR_DBP); + + /* Wait for Backup domain Write protection disable */ + tickstart = HAL_GetTick(); + + while(HAL_IS_BIT_CLR(PWR->CR, PWR_CR_DBP)) + { + if((HAL_GetTick() - tickstart) > RCC_DBP_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + } + + /* Reset the Backup domain only if the RTC Clock source selection is modified from reset value */ + temp_reg = (RCC->BDCR & RCC_BDCR_RTCSEL); + if((temp_reg != 0x00000000U) && (temp_reg != (PeriphClkInit->RTCClockSelection & RCC_BDCR_RTCSEL))) + { + /* Store the content of BDCR register before the reset of Backup Domain */ + temp_reg = (RCC->BDCR & ~(RCC_BDCR_RTCSEL)); + /* RTC Clock selection can be changed only if the Backup Domain is reset */ + __HAL_RCC_BACKUPRESET_FORCE(); + __HAL_RCC_BACKUPRESET_RELEASE(); + /* Restore the Content of BDCR register */ + RCC->BDCR = temp_reg; + + /* Wait for LSERDY if LSE was enabled */ + if (HAL_IS_BIT_SET(temp_reg, RCC_BDCR_LSEON)) + { + /* Get Start Tick */ + tickstart = HAL_GetTick(); + + /* Wait till LSE is ready */ + while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET) + { + if((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + } + } + __HAL_RCC_RTC_CONFIG(PeriphClkInit->RTCClockSelection); + + /* Require to disable power clock if necessary */ + if(pwrclkchanged == SET) + { + __HAL_RCC_PWR_CLK_DISABLE(); + } + } + + /*------------------------------- USART1 Configuration ------------------------*/ + if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USART1) == RCC_PERIPHCLK_USART1) + { + /* Check the parameters */ + assert_param(IS_RCC_USART1CLKSOURCE(PeriphClkInit->Usart1ClockSelection)); + + /* Configure the USART1 clock source */ + __HAL_RCC_USART1_CONFIG(PeriphClkInit->Usart1ClockSelection); + } + +#if defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F078xx)\ + || defined(STM32F091xC) || defined(STM32F098xx) + /*----------------------------- USART2 Configuration --------------------------*/ + if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USART2) == RCC_PERIPHCLK_USART2) + { + /* Check the parameters */ + assert_param(IS_RCC_USART2CLKSOURCE(PeriphClkInit->Usart2ClockSelection)); + + /* Configure the USART2 clock source */ + __HAL_RCC_USART2_CONFIG(PeriphClkInit->Usart2ClockSelection); + } +#endif /* STM32F071xB || STM32F072xB || STM32F078xx || */ + /* STM32F091xC || STM32F098xx */ + +#if defined(STM32F091xC) || defined(STM32F098xx) + /*----------------------------- USART3 Configuration --------------------------*/ + if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USART3) == RCC_PERIPHCLK_USART3) + { + /* Check the parameters */ + assert_param(IS_RCC_USART3CLKSOURCE(PeriphClkInit->Usart3ClockSelection)); + + /* Configure the USART3 clock source */ + __HAL_RCC_USART3_CONFIG(PeriphClkInit->Usart3ClockSelection); + } +#endif /* STM32F091xC || STM32F098xx */ + + /*------------------------------ I2C1 Configuration ------------------------*/ + if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2C1) == RCC_PERIPHCLK_I2C1) + { + /* Check the parameters */ + assert_param(IS_RCC_I2C1CLKSOURCE(PeriphClkInit->I2c1ClockSelection)); + + /* Configure the I2C1 clock source */ + __HAL_RCC_I2C1_CONFIG(PeriphClkInit->I2c1ClockSelection); + } + +#if defined(STM32F042x6) || defined(STM32F048xx) || defined(STM32F072xB) || defined(STM32F078xx) || defined(STM32F070xB) || defined(STM32F070x6) + /*------------------------------ USB Configuration ------------------------*/ + if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USB) == RCC_PERIPHCLK_USB) + { + /* Check the parameters */ + assert_param(IS_RCC_USBCLKSOURCE(PeriphClkInit->UsbClockSelection)); + + /* Configure the USB clock source */ + __HAL_RCC_USB_CONFIG(PeriphClkInit->UsbClockSelection); + } +#endif /* STM32F042x6 || STM32F048xx || STM32F072xB || STM32F078xx || STM32F070xB || STM32F070x6 */ + +#if defined(STM32F042x6) || defined(STM32F048xx)\ + || defined(STM32F051x8) || defined(STM32F058xx)\ + || defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F078xx)\ + || defined(STM32F091xC) || defined(STM32F098xx) + /*------------------------------ CEC clock Configuration -------------------*/ + if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_CEC) == RCC_PERIPHCLK_CEC) + { + /* Check the parameters */ + assert_param(IS_RCC_CECCLKSOURCE(PeriphClkInit->CecClockSelection)); + + /* Configure the CEC clock source */ + __HAL_RCC_CEC_CONFIG(PeriphClkInit->CecClockSelection); + } +#endif /* STM32F042x6 || STM32F048xx || */ + /* STM32F051x8 || STM32F058xx || */ + /* STM32F071xB || STM32F072xB || STM32F078xx || */ + /* STM32F091xC || STM32F098xx */ + + return HAL_OK; +} + +/** + * @brief Get the RCC_ClkInitStruct according to the internal + * RCC configuration registers. + * @param PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that + * returns the configuration information for the Extended Peripherals clocks + * (USART, RTC, I2C, CEC and USB). + * @retval None + */ +void HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit) +{ + /* Set all possible values for the extended clock type parameter------------*/ + /* Common part first */ + PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_USART1 | RCC_PERIPHCLK_I2C1 | RCC_PERIPHCLK_RTC; + /* Get the RTC configuration --------------------------------------------*/ + PeriphClkInit->RTCClockSelection = __HAL_RCC_GET_RTC_SOURCE(); + /* Get the USART1 clock configuration --------------------------------------------*/ + PeriphClkInit->Usart1ClockSelection = __HAL_RCC_GET_USART1_SOURCE(); + /* Get the I2C1 clock source -----------------------------------------------*/ + PeriphClkInit->I2c1ClockSelection = __HAL_RCC_GET_I2C1_SOURCE(); + +#if defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F078xx)\ + || defined(STM32F091xC) || defined(STM32F098xx) + PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_USART2; + /* Get the USART2 clock source ---------------------------------------------*/ + PeriphClkInit->Usart2ClockSelection = __HAL_RCC_GET_USART2_SOURCE(); +#endif /* STM32F071xB || STM32F072xB || STM32F078xx || */ + /* STM32F091xC || STM32F098xx */ + +#if defined(STM32F091xC) || defined(STM32F098xx) + PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_USART3; + /* Get the USART3 clock source ---------------------------------------------*/ + PeriphClkInit->Usart3ClockSelection = __HAL_RCC_GET_USART3_SOURCE(); +#endif /* STM32F091xC || STM32F098xx */ + +#if defined(STM32F042x6) || defined(STM32F048xx) || defined(STM32F072xB) || defined(STM32F078xx) || defined(STM32F070xB) || defined(STM32F070x6) + PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_USB; + /* Get the USB clock source ---------------------------------------------*/ + PeriphClkInit->UsbClockSelection = __HAL_RCC_GET_USB_SOURCE(); +#endif /* STM32F042x6 || STM32F048xx || STM32F072xB || STM32F078xx || STM32F070xB || STM32F070x6 */ + +#if defined(STM32F042x6) || defined(STM32F048xx)\ + || defined(STM32F051x8) || defined(STM32F058xx)\ + || defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F078xx)\ + || defined(STM32F091xC) || defined(STM32F098xx) + PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_CEC; + /* Get the CEC clock source ------------------------------------------------*/ + PeriphClkInit->CecClockSelection = __HAL_RCC_GET_CEC_SOURCE(); +#endif /* STM32F042x6 || STM32F048xx || */ + /* STM32F051x8 || STM32F058xx || */ + /* STM32F071xB || STM32F072xB || STM32F078xx || */ + /* STM32F091xC || STM32F098xx */ + +} + +/** + * @brief Returns the peripheral clock frequency + * @note Returns 0 if peripheral clock is unknown + * @param PeriphClk Peripheral clock identifier + * This parameter can be one of the following values: + * @arg @ref RCC_PERIPHCLK_RTC RTC peripheral clock + * @arg @ref RCC_PERIPHCLK_USART1 USART1 peripheral clock + * @arg @ref RCC_PERIPHCLK_I2C1 I2C1 peripheral clock + @if STM32F042x6 + * @arg @ref RCC_PERIPHCLK_USB USB peripheral clock + * @arg @ref RCC_PERIPHCLK_CEC CEC peripheral clock + @endif + @if STM32F048xx + * @arg @ref RCC_PERIPHCLK_USB USB peripheral clock + * @arg @ref RCC_PERIPHCLK_CEC CEC peripheral clock + @endif + @if STM32F051x8 + * @arg @ref RCC_PERIPHCLK_CEC CEC peripheral clock + @endif + @if STM32F058xx + * @arg @ref RCC_PERIPHCLK_CEC CEC peripheral clock + @endif + @if STM32F070x6 + * @arg @ref RCC_PERIPHCLK_USB USB peripheral clock + @endif + @if STM32F070xB + * @arg @ref RCC_PERIPHCLK_USB USB peripheral clock + @endif + @if STM32F071xB + * @arg @ref RCC_PERIPHCLK_USART2 USART2 peripheral clock + * @arg @ref RCC_PERIPHCLK_CEC CEC peripheral clock + @endif + @if STM32F072xB + * @arg @ref RCC_PERIPHCLK_USART2 USART2 peripheral clock + * @arg @ref RCC_PERIPHCLK_USB USB peripheral clock + * @arg @ref RCC_PERIPHCLK_CEC CEC peripheral clock + @endif + @if STM32F078xx + * @arg @ref RCC_PERIPHCLK_USART2 USART2 peripheral clock + * @arg @ref RCC_PERIPHCLK_USB USB peripheral clock + * @arg @ref RCC_PERIPHCLK_CEC CEC peripheral clock + @endif + @if STM32F091xC + * @arg @ref RCC_PERIPHCLK_USART2 USART2 peripheral clock + * @arg @ref RCC_PERIPHCLK_USART3 USART2 peripheral clock + * @arg @ref RCC_PERIPHCLK_CEC CEC peripheral clock + @endif + @if STM32F098xx + * @arg @ref RCC_PERIPHCLK_USART2 USART2 peripheral clock + * @arg @ref RCC_PERIPHCLK_USART3 USART2 peripheral clock + * @arg @ref RCC_PERIPHCLK_CEC CEC peripheral clock + @endif + * @retval Frequency in Hz (0: means that no available frequency for the peripheral) + */ +uint32_t HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk) +{ + /* frequency == 0 : means that no available frequency for the peripheral */ + uint32_t frequency = 0U; + + uint32_t srcclk = 0U; +#if defined(USB) + uint32_t pllmull = 0U, pllsource = 0U, predivfactor = 0U; +#endif /* USB */ + + /* Check the parameters */ + assert_param(IS_RCC_PERIPHCLOCK(PeriphClk)); + + switch (PeriphClk) + { + case RCC_PERIPHCLK_RTC: + { + /* Get the current RTC source */ + srcclk = __HAL_RCC_GET_RTC_SOURCE(); + + /* Check if LSE is ready and if RTC clock selection is LSE */ + if ((srcclk == RCC_RTCCLKSOURCE_LSE) && (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY))) + { + frequency = LSE_VALUE; + } + /* Check if LSI is ready and if RTC clock selection is LSI */ + else if ((srcclk == RCC_RTCCLKSOURCE_LSI) && (HAL_IS_BIT_SET(RCC->CSR, RCC_CSR_LSIRDY))) + { + frequency = LSI_VALUE; + } + /* Check if HSE is ready and if RTC clock selection is HSI_DIV32*/ + else if ((srcclk == RCC_RTCCLKSOURCE_HSE_DIV32) && (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSERDY))) + { + frequency = HSE_VALUE / 32U; + } + break; + } + case RCC_PERIPHCLK_USART1: + { + /* Get the current USART1 source */ + srcclk = __HAL_RCC_GET_USART1_SOURCE(); + + /* Check if USART1 clock selection is PCLK1 */ + if (srcclk == RCC_USART1CLKSOURCE_PCLK1) + { + frequency = HAL_RCC_GetPCLK1Freq(); + } + /* Check if HSI is ready and if USART1 clock selection is HSI */ + else if ((srcclk == RCC_USART1CLKSOURCE_HSI) && (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY))) + { + frequency = HSI_VALUE; + } + /* Check if USART1 clock selection is SYSCLK */ + else if (srcclk == RCC_USART1CLKSOURCE_SYSCLK) + { + frequency = HAL_RCC_GetSysClockFreq(); + } + /* Check if LSE is ready and if USART1 clock selection is LSE */ + else if ((srcclk == RCC_USART1CLKSOURCE_LSE) && (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY))) + { + frequency = LSE_VALUE; + } + break; + } +#if defined(RCC_CFGR3_USART2SW) + case RCC_PERIPHCLK_USART2: + { + /* Get the current USART2 source */ + srcclk = __HAL_RCC_GET_USART2_SOURCE(); + + /* Check if USART2 clock selection is PCLK1 */ + if (srcclk == RCC_USART2CLKSOURCE_PCLK1) + { + frequency = HAL_RCC_GetPCLK1Freq(); + } + /* Check if HSI is ready and if USART2 clock selection is HSI */ + else if ((srcclk == RCC_USART2CLKSOURCE_HSI) && (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY))) + { + frequency = HSI_VALUE; + } + /* Check if USART2 clock selection is SYSCLK */ + else if (srcclk == RCC_USART2CLKSOURCE_SYSCLK) + { + frequency = HAL_RCC_GetSysClockFreq(); + } + /* Check if LSE is ready and if USART2 clock selection is LSE */ + else if ((srcclk == RCC_USART2CLKSOURCE_LSE) && (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY))) + { + frequency = LSE_VALUE; + } + break; + } +#endif /* RCC_CFGR3_USART2SW */ +#if defined(RCC_CFGR3_USART3SW) + case RCC_PERIPHCLK_USART3: + { + /* Get the current USART3 source */ + srcclk = __HAL_RCC_GET_USART3_SOURCE(); + + /* Check if USART3 clock selection is PCLK1 */ + if (srcclk == RCC_USART3CLKSOURCE_PCLK1) + { + frequency = HAL_RCC_GetPCLK1Freq(); + } + /* Check if HSI is ready and if USART3 clock selection is HSI */ + else if ((srcclk == RCC_USART3CLKSOURCE_HSI) && (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY))) + { + frequency = HSI_VALUE; + } + /* Check if USART3 clock selection is SYSCLK */ + else if (srcclk == RCC_USART3CLKSOURCE_SYSCLK) + { + frequency = HAL_RCC_GetSysClockFreq(); + } + /* Check if LSE is ready and if USART3 clock selection is LSE */ + else if ((srcclk == RCC_USART3CLKSOURCE_LSE) && (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY))) + { + frequency = LSE_VALUE; + } + break; + } +#endif /* RCC_CFGR3_USART3SW */ + case RCC_PERIPHCLK_I2C1: + { + /* Get the current I2C1 source */ + srcclk = __HAL_RCC_GET_I2C1_SOURCE(); + + /* Check if HSI is ready and if I2C1 clock selection is HSI */ + if ((srcclk == RCC_I2C1CLKSOURCE_HSI) && (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY))) + { + frequency = HSI_VALUE; + } + /* Check if I2C1 clock selection is SYSCLK */ + else if (srcclk == RCC_I2C1CLKSOURCE_SYSCLK) + { + frequency = HAL_RCC_GetSysClockFreq(); + } + break; + } +#if defined(USB) + case RCC_PERIPHCLK_USB: + { + /* Get the current USB source */ + srcclk = __HAL_RCC_GET_USB_SOURCE(); + + /* Check if PLL is ready and if USB clock selection is PLL */ + if ((srcclk == RCC_USBCLKSOURCE_PLL) && (HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLLRDY))) + { + /* Get PLL clock source and multiplication factor ----------------------*/ + pllmull = RCC->CFGR & RCC_CFGR_PLLMUL; + pllsource = RCC->CFGR & RCC_CFGR_PLLSRC; + pllmull = (pllmull >> RCC_CFGR_PLLMUL_BITNUMBER) + 2U; + predivfactor = (RCC->CFGR2 & RCC_CFGR2_PREDIV) + 1U; + + if (pllsource == RCC_CFGR_PLLSRC_HSE_PREDIV) + { + /* HSE used as PLL clock source : frequency = HSE/PREDIV * PLLMUL */ + frequency = (HSE_VALUE/predivfactor) * pllmull; + } +#if defined(RCC_CR2_HSI48ON) + else if (pllsource == RCC_CFGR_PLLSRC_HSI48_PREDIV) + { + /* HSI48 used as PLL clock source : frequency = HSI48/PREDIV * PLLMUL */ + frequency = (HSI48_VALUE / predivfactor) * pllmull; + } +#endif /* RCC_CR2_HSI48ON */ + else + { +#if defined(STM32F042x6) || defined(STM32F048xx) || defined(STM32F078xx) || defined(STM32F072xB) || defined(STM32F070xB) + /* HSI used as PLL clock source : frequency = HSI/PREDIV * PLLMUL */ + frequency = (HSI_VALUE / predivfactor) * pllmull; +#else + /* HSI used as PLL clock source : frequency = HSI/2U * PLLMUL */ + frequency = (HSI_VALUE >> 1U) * pllmull; +#endif /* STM32F042x6 || STM32F048xx || STM32F072xB || STM32F078xx || STM32F070xB */ + } + } +#if defined(RCC_CR2_HSI48ON) + /* Check if HSI48 is ready and if USB clock selection is HSI48 */ + else if ((srcclk == RCC_USBCLKSOURCE_HSI48) && (HAL_IS_BIT_SET(RCC->CR2, RCC_CR2_HSI48RDY))) + { + frequency = HSI48_VALUE; + } +#endif /* RCC_CR2_HSI48ON */ + break; + } +#endif /* USB */ +#if defined(CEC) + case RCC_PERIPHCLK_CEC: + { + /* Get the current CEC source */ + srcclk = __HAL_RCC_GET_CEC_SOURCE(); + + /* Check if HSI is ready and if CEC clock selection is HSI */ + if ((srcclk == RCC_CECCLKSOURCE_HSI) && (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY))) + { + frequency = HSI_VALUE; + } + /* Check if LSE is ready and if CEC clock selection is LSE */ + else if ((srcclk == RCC_CECCLKSOURCE_LSE) && (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY))) + { + frequency = LSE_VALUE; + } + break; + } +#endif /* CEC */ + default: + { + break; + } + } + return(frequency); +} + +/** + * @} + */ + +#if defined(CRS) + +/** @defgroup RCCEx_Exported_Functions_Group3 Extended Clock Recovery System Control functions + * @brief Extended Clock Recovery System Control functions + * +@verbatim + =============================================================================== + ##### Extended Clock Recovery System Control functions ##### + =============================================================================== + [..] + For devices with Clock Recovery System feature (CRS), RCC Extention HAL driver can be used as follows: + + (#) In System clock config, HSI48 needs to be enabled + + (#) Enable CRS clock in IP MSP init which will use CRS functions + + (#) Call CRS functions as follows: + (##) Prepare synchronization configuration necessary for HSI48 calibration + (+++) Default values can be set for frequency Error Measurement (reload and error limit) + and also HSI48 oscillator smooth trimming. + (+++) Macro @ref __HAL_RCC_CRS_RELOADVALUE_CALCULATE can be also used to calculate + directly reload value with target and synchronization frequencies values + (##) Call function @ref HAL_RCCEx_CRSConfig which + (+++) Reset CRS registers to their default values. + (+++) Configure CRS registers with synchronization configuration + (+++) Enable automatic calibration and frequency error counter feature + Note: When using USB LPM (Link Power Management) and the device is in Sleep mode, the + periodic USB SOF will not be generated by the host. No SYNC signal will therefore be + provided to the CRS to calibrate the HSI48 on the run. To guarantee the required clock + precision after waking up from Sleep mode, the LSE or reference clock on the GPIOs + should be used as SYNC signal. + + (##) A polling function is provided to wait for complete synchronization + (+++) Call function @ref HAL_RCCEx_CRSWaitSynchronization() + (+++) According to CRS status, user can decide to adjust again the calibration or continue + application if synchronization is OK + + (#) User can retrieve information related to synchronization in calling function + @ref HAL_RCCEx_CRSGetSynchronizationInfo() + + (#) Regarding synchronization status and synchronization information, user can try a new calibration + in changing synchronization configuration and call again HAL_RCCEx_CRSConfig. + Note: When the SYNC event is detected during the downcounting phase (before reaching the zero value), + it means that the actual frequency is lower than the target (and so, that the TRIM value should be + incremented), while when it is detected during the upcounting phase it means that the actual frequency + is higher (and that the TRIM value should be decremented). + + (#) In interrupt mode, user can resort to the available macros (__HAL_RCC_CRS_XXX_IT). Interrupts will go + through CRS Handler (RCC_IRQn/RCC_IRQHandler) + (++) Call function @ref HAL_RCCEx_CRSConfig() + (++) Enable RCC_IRQn (thanks to NVIC functions) + (++) Enable CRS interrupt (@ref __HAL_RCC_CRS_ENABLE_IT) + (++) Implement CRS status management in the following user callbacks called from + HAL_RCCEx_CRS_IRQHandler(): + (+++) @ref HAL_RCCEx_CRS_SyncOkCallback() + (+++) @ref HAL_RCCEx_CRS_SyncWarnCallback() + (+++) @ref HAL_RCCEx_CRS_ExpectedSyncCallback() + (+++) @ref HAL_RCCEx_CRS_ErrorCallback() + + (#) To force a SYNC EVENT, user can use the function @ref HAL_RCCEx_CRSSoftwareSynchronizationGenerate(). + This function can be called before calling @ref HAL_RCCEx_CRSConfig (for instance in Systick handler) + +@endverbatim + * @{ + */ + +/** + * @brief Start automatic synchronization for polling mode + * @param pInit Pointer on RCC_CRSInitTypeDef structure + * @retval None + */ +void HAL_RCCEx_CRSConfig(RCC_CRSInitTypeDef *pInit) +{ + uint32_t value = 0U; + + /* Check the parameters */ + assert_param(IS_RCC_CRS_SYNC_DIV(pInit->Prescaler)); + assert_param(IS_RCC_CRS_SYNC_SOURCE(pInit->Source)); + assert_param(IS_RCC_CRS_SYNC_POLARITY(pInit->Polarity)); + assert_param(IS_RCC_CRS_RELOADVALUE(pInit->ReloadValue)); + assert_param(IS_RCC_CRS_ERRORLIMIT(pInit->ErrorLimitValue)); + assert_param(IS_RCC_CRS_HSI48CALIBRATION(pInit->HSI48CalibrationValue)); + + /* CONFIGURATION */ + + /* Before configuration, reset CRS registers to their default values*/ + __HAL_RCC_CRS_FORCE_RESET(); + __HAL_RCC_CRS_RELEASE_RESET(); + + /* Set the SYNCDIV[2:0] bits according to Prescaler value */ + /* Set the SYNCSRC[1:0] bits according to Source value */ + /* Set the SYNCSPOL bit according to Polarity value */ + value = (pInit->Prescaler | pInit->Source | pInit->Polarity); + /* Set the RELOAD[15:0] bits according to ReloadValue value */ + value |= pInit->ReloadValue; + /* Set the FELIM[7:0] bits according to ErrorLimitValue value */ + value |= (pInit->ErrorLimitValue << CRS_CFGR_FELIM_BITNUMBER); + WRITE_REG(CRS->CFGR, value); + + /* Adjust HSI48 oscillator smooth trimming */ + /* Set the TRIM[5:0] bits according to RCC_CRS_HSI48CalibrationValue value */ + MODIFY_REG(CRS->CR, CRS_CR_TRIM, (pInit->HSI48CalibrationValue << CRS_CR_TRIM_BITNUMBER)); + + /* START AUTOMATIC SYNCHRONIZATION*/ + + /* Enable Automatic trimming & Frequency error counter */ + SET_BIT(CRS->CR, CRS_CR_AUTOTRIMEN | CRS_CR_CEN); +} + +/** + * @brief Generate the software synchronization event + * @retval None + */ +void HAL_RCCEx_CRSSoftwareSynchronizationGenerate(void) +{ + SET_BIT(CRS->CR, CRS_CR_SWSYNC); +} + +/** + * @brief Return synchronization info + * @param pSynchroInfo Pointer on RCC_CRSSynchroInfoTypeDef structure + * @retval None + */ +void HAL_RCCEx_CRSGetSynchronizationInfo(RCC_CRSSynchroInfoTypeDef *pSynchroInfo) +{ + /* Check the parameter */ + assert_param(pSynchroInfo != NULL); + + /* Get the reload value */ + pSynchroInfo->ReloadValue = (uint32_t)(READ_BIT(CRS->CFGR, CRS_CFGR_RELOAD)); + + /* Get HSI48 oscillator smooth trimming */ + pSynchroInfo->HSI48CalibrationValue = (uint32_t)(READ_BIT(CRS->CR, CRS_CR_TRIM) >> CRS_CR_TRIM_BITNUMBER); + + /* Get Frequency error capture */ + pSynchroInfo->FreqErrorCapture = (uint32_t)(READ_BIT(CRS->ISR, CRS_ISR_FECAP) >> CRS_ISR_FECAP_BITNUMBER); + + /* Get Frequency error direction */ + pSynchroInfo->FreqErrorDirection = (uint32_t)(READ_BIT(CRS->ISR, CRS_ISR_FEDIR)); +} + +/** +* @brief Wait for CRS Synchronization status. +* @param Timeout Duration of the timeout +* @note Timeout is based on the maximum time to receive a SYNC event based on synchronization +* frequency. +* @note If Timeout set to HAL_MAX_DELAY, HAL_TIMEOUT will be never returned. +* @retval Combination of Synchronization status +* This parameter can be a combination of the following values: +* @arg @ref RCC_CRS_TIMEOUT +* @arg @ref RCC_CRS_SYNCOK +* @arg @ref RCC_CRS_SYNCWARN +* @arg @ref RCC_CRS_SYNCERR +* @arg @ref RCC_CRS_SYNCMISS +* @arg @ref RCC_CRS_TRIMOVF +*/ +uint32_t HAL_RCCEx_CRSWaitSynchronization(uint32_t Timeout) +{ + uint32_t crsstatus = RCC_CRS_NONE; + uint32_t tickstart = 0U; + + /* Get timeout */ + tickstart = HAL_GetTick(); + + /* Wait for CRS flag or timeout detection */ + do + { + if(Timeout != HAL_MAX_DELAY) + { + if((Timeout == 0U) || ((HAL_GetTick() - tickstart) > Timeout)) + { + crsstatus = RCC_CRS_TIMEOUT; + } + } + /* Check CRS SYNCOK flag */ + if(__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_SYNCOK)) + { + /* CRS SYNC event OK */ + crsstatus |= RCC_CRS_SYNCOK; + + /* Clear CRS SYNC event OK bit */ + __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_SYNCOK); + } + + /* Check CRS SYNCWARN flag */ + if(__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_SYNCWARN)) + { + /* CRS SYNC warning */ + crsstatus |= RCC_CRS_SYNCWARN; + + /* Clear CRS SYNCWARN bit */ + __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_SYNCWARN); + } + + /* Check CRS TRIM overflow flag */ + if(__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_TRIMOVF)) + { + /* CRS SYNC Error */ + crsstatus |= RCC_CRS_TRIMOVF; + + /* Clear CRS Error bit */ + __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_TRIMOVF); + } + + /* Check CRS Error flag */ + if(__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_SYNCERR)) + { + /* CRS SYNC Error */ + crsstatus |= RCC_CRS_SYNCERR; + + /* Clear CRS Error bit */ + __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_SYNCERR); + } + + /* Check CRS SYNC Missed flag */ + if(__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_SYNCMISS)) + { + /* CRS SYNC Missed */ + crsstatus |= RCC_CRS_SYNCMISS; + + /* Clear CRS SYNC Missed bit */ + __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_SYNCMISS); + } + + /* Check CRS Expected SYNC flag */ + if(__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_ESYNC)) + { + /* frequency error counter reached a zero value */ + __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_ESYNC); + } + } while(RCC_CRS_NONE == crsstatus); + + return crsstatus; +} + +/** + * @brief Handle the Clock Recovery System interrupt request. + * @retval None + */ +void HAL_RCCEx_CRS_IRQHandler(void) +{ + uint32_t crserror = RCC_CRS_NONE; + /* Get current IT flags and IT sources values */ + uint32_t itflags = READ_REG(CRS->ISR); + uint32_t itsources = READ_REG(CRS->CR); + + /* Check CRS SYNCOK flag */ + if(((itflags & RCC_CRS_FLAG_SYNCOK) != RESET) && ((itsources & RCC_CRS_IT_SYNCOK) != RESET)) + { + /* Clear CRS SYNC event OK flag */ + WRITE_REG(CRS->ICR, CRS_ICR_SYNCOKC); + + /* user callback */ + HAL_RCCEx_CRS_SyncOkCallback(); + } + /* Check CRS SYNCWARN flag */ + else if(((itflags & RCC_CRS_FLAG_SYNCWARN) != RESET) && ((itsources & RCC_CRS_IT_SYNCWARN) != RESET)) + { + /* Clear CRS SYNCWARN flag */ + WRITE_REG(CRS->ICR, CRS_ICR_SYNCWARNC); + + /* user callback */ + HAL_RCCEx_CRS_SyncWarnCallback(); + } + /* Check CRS Expected SYNC flag */ + else if(((itflags & RCC_CRS_FLAG_ESYNC) != RESET) && ((itsources & RCC_CRS_IT_ESYNC) != RESET)) + { + /* frequency error counter reached a zero value */ + WRITE_REG(CRS->ICR, CRS_ICR_ESYNCC); + + /* user callback */ + HAL_RCCEx_CRS_ExpectedSyncCallback(); + } + /* Check CRS Error flags */ + else + { + if(((itflags & RCC_CRS_FLAG_ERR) != RESET) && ((itsources & RCC_CRS_IT_ERR) != RESET)) + { + if((itflags & RCC_CRS_FLAG_SYNCERR) != RESET) + { + crserror |= RCC_CRS_SYNCERR; + } + if((itflags & RCC_CRS_FLAG_SYNCMISS) != RESET) + { + crserror |= RCC_CRS_SYNCMISS; + } + if((itflags & RCC_CRS_FLAG_TRIMOVF) != RESET) + { + crserror |= RCC_CRS_TRIMOVF; + } + + /* Clear CRS Error flags */ + WRITE_REG(CRS->ICR, CRS_ICR_ERRC); + + /* user error callback */ + HAL_RCCEx_CRS_ErrorCallback(crserror); + } + } +} + +/** + * @brief RCCEx Clock Recovery System SYNCOK interrupt callback. + * @retval none + */ +__weak void HAL_RCCEx_CRS_SyncOkCallback(void) +{ + /* NOTE : This function should not be modified, when the callback is needed, + the @ref HAL_RCCEx_CRS_SyncOkCallback should be implemented in the user file + */ +} + +/** + * @brief RCCEx Clock Recovery System SYNCWARN interrupt callback. + * @retval none + */ +__weak void HAL_RCCEx_CRS_SyncWarnCallback(void) +{ + /* NOTE : This function should not be modified, when the callback is needed, + the @ref HAL_RCCEx_CRS_SyncWarnCallback should be implemented in the user file + */ +} + +/** + * @brief RCCEx Clock Recovery System Expected SYNC interrupt callback. + * @retval none + */ +__weak void HAL_RCCEx_CRS_ExpectedSyncCallback(void) +{ + /* NOTE : This function should not be modified, when the callback is needed, + the @ref HAL_RCCEx_CRS_ExpectedSyncCallback should be implemented in the user file + */ +} + +/** + * @brief RCCEx Clock Recovery System Error interrupt callback. + * @param Error Combination of Error status. + * This parameter can be a combination of the following values: + * @arg @ref RCC_CRS_SYNCERR + * @arg @ref RCC_CRS_SYNCMISS + * @arg @ref RCC_CRS_TRIMOVF + * @retval none + */ +__weak void HAL_RCCEx_CRS_ErrorCallback(uint32_t Error) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(Error); + + /* NOTE : This function should not be modified, when the callback is needed, + the @ref HAL_RCCEx_CRS_ErrorCallback should be implemented in the user file + */ +} + +/** + * @} + */ + +#endif /* CRS */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* HAL_RCC_MODULE_ENABLED */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.c b/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.c new file mode 100644 index 0000000..24648d1 --- /dev/null +++ b/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.c @@ -0,0 +1,6767 @@ +/** + ****************************************************************************** + * @file stm32f0xx_hal_tim.c + * @author MCD Application Team + * @brief TIM HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the Timer (TIM) peripheral: + * + TIM Time Base Initialization + * + TIM Time Base Start + * + TIM Time Base Start Interruption + * + TIM Time Base Start DMA + * + TIM Output Compare/PWM Initialization + * + TIM Output Compare/PWM Channel Configuration + * + TIM Output Compare/PWM Start + * + TIM Output Compare/PWM Start Interruption + * + TIM Output Compare/PWM Start DMA + * + TIM Input Capture Initialization + * + TIM Input Capture Channel Configuration + * + TIM Input Capture Start + * + TIM Input Capture Start Interruption + * + TIM Input Capture Start DMA + * + TIM One Pulse Initialization + * + TIM One Pulse Channel Configuration + * + TIM One Pulse Start + * + TIM Encoder Interface Initialization + * + TIM Encoder Interface Start + * + TIM Encoder Interface Start Interruption + * + TIM Encoder Interface Start DMA + * + Commutation Event configuration with Interruption and DMA + * + TIM OCRef clear configuration + * + TIM External Clock configuration + @verbatim + ============================================================================== + ##### TIMER Generic features ##### + ============================================================================== + [..] The Timer features include: + (#) 16-bit up, down, up/down auto-reload counter. + (#) 16-bit programmable prescaler allowing dividing (also on the fly) the + counter clock frequency either by any factor between 1 and 65536. + (#) Up to 4 independent channels for: + (++) Input Capture + (++) Output Compare + (++) PWM generation (Edge and Center-aligned Mode) + (++) One-pulse mode output + (#) Synchronization circuit to control the timer with external signals and to interconnect + several timers together. + (#) Supports incremental encoder for positioning purposes + + ##### How to use this driver ##### + ============================================================================== + [..] + (#) Initialize the TIM low level resources by implementing the following functions + depending on the selected feature: + (++) Time Base : HAL_TIM_Base_MspInit() + (++) Input Capture : HAL_TIM_IC_MspInit() + (++) Output Compare : HAL_TIM_OC_MspInit() + (++) PWM generation : HAL_TIM_PWM_MspInit() + (++) One-pulse mode output : HAL_TIM_OnePulse_MspInit() + (++) Encoder mode output : HAL_TIM_Encoder_MspInit() + + (#) Initialize the TIM low level resources : + (##) Enable the TIM interface clock using __HAL_RCC_TIMx_CLK_ENABLE(); + (##) TIM pins configuration + (+++) Enable the clock for the TIM GPIOs using the following function: + __HAL_RCC_GPIOx_CLK_ENABLE(); + (+++) Configure these TIM pins in Alternate function mode using HAL_GPIO_Init(); + + (#) The external Clock can be configured, if needed (the default clock is the + internal clock from the APBx), using the following function: + HAL_TIM_ConfigClockSource, the clock configuration should be done before + any start function. + + (#) Configure the TIM in the desired functioning mode using one of the + Initialization function of this driver: + (++) HAL_TIM_Base_Init: to use the Timer to generate a simple time base + (++) HAL_TIM_OC_Init and HAL_TIM_OC_ConfigChannel: to use the Timer to generate an + Output Compare signal. + (++) HAL_TIM_PWM_Init and HAL_TIM_PWM_ConfigChannel: to use the Timer to generate a + PWM signal. + (++) HAL_TIM_IC_Init and HAL_TIM_IC_ConfigChannel: to use the Timer to measure an + external signal. + (++) HAL_TIM_OnePulse_Init and HAL_TIM_OnePulse_ConfigChannel: to use the Timer + in One Pulse Mode. + (++) HAL_TIM_Encoder_Init: to use the Timer Encoder Interface. + + (#) Activate the TIM peripheral using one of the start functions depending from the feature used: + (++) Time Base : HAL_TIM_Base_Start(), HAL_TIM_Base_Start_DMA(), HAL_TIM_Base_Start_IT() + (++) Input Capture : HAL_TIM_IC_Start(), HAL_TIM_IC_Start_DMA(), HAL_TIM_IC_Start_IT() + (++) Output Compare : HAL_TIM_OC_Start(), HAL_TIM_OC_Start_DMA(), HAL_TIM_OC_Start_IT() + (++) PWM generation : HAL_TIM_PWM_Start(), HAL_TIM_PWM_Start_DMA(), HAL_TIM_PWM_Start_IT() + (++) One-pulse mode output : HAL_TIM_OnePulse_Start(), HAL_TIM_OnePulse_Start_IT() + (++) Encoder mode output : HAL_TIM_Encoder_Start(), HAL_TIM_Encoder_Start_DMA(), HAL_TIM_Encoder_Start_IT(). + + (#) The DMA Burst is managed with the two following functions: + HAL_TIM_DMABurst_WriteStart() + HAL_TIM_DMABurst_ReadStart() + + *** Callback registration *** + ============================================= + + [..] + The compilation define USE_HAL_TIM_REGISTER_CALLBACKS when set to 1 + allows the user to configure dynamically the driver callbacks. + + [..] + Use Function @ref HAL_TIM_RegisterCallback() to register a callback. + @ref HAL_TIM_RegisterCallback() takes as parameters the HAL peripheral handle, + the Callback ID and a pointer to the user callback function. + + [..] + Use function @ref HAL_TIM_UnRegisterCallback() to reset a callback to the default + weak function. + @ref HAL_TIM_UnRegisterCallback takes as parameters the HAL peripheral handle, + and the Callback ID. + + [..] + These functions allow to register/unregister following callbacks: + (+) Base_MspInitCallback : TIM Base Msp Init Callback. + (+) Base_MspDeInitCallback : TIM Base Msp DeInit Callback. + (+) IC_MspInitCallback : TIM IC Msp Init Callback. + (+) IC_MspDeInitCallback : TIM IC Msp DeInit Callback. + (+) OC_MspInitCallback : TIM OC Msp Init Callback. + (+) OC_MspDeInitCallback : TIM OC Msp DeInit Callback. + (+) PWM_MspInitCallback : TIM PWM Msp Init Callback. + (+) PWM_MspDeInitCallback : TIM PWM Msp DeInit Callback. + (+) OnePulse_MspInitCallback : TIM One Pulse Msp Init Callback. + (+) OnePulse_MspDeInitCallback : TIM One Pulse Msp DeInit Callback. + (+) Encoder_MspInitCallback : TIM Encoder Msp Init Callback. + (+) Encoder_MspDeInitCallback : TIM Encoder Msp DeInit Callback. + (+) HallSensor_MspInitCallback : TIM Hall Sensor Msp Init Callback. + (+) HallSensor_MspDeInitCallback : TIM Hall Sensor Msp DeInit Callback. + (+) PeriodElapsedCallback : TIM Period Elapsed Callback. + (+) PeriodElapsedHalfCpltCallback : TIM Period Elapsed half complete Callback. + (+) TriggerCallback : TIM Trigger Callback. + (+) TriggerHalfCpltCallback : TIM Trigger half complete Callback. + (+) IC_CaptureCallback : TIM Input Capture Callback. + (+) IC_CaptureHalfCpltCallback : TIM Input Capture half complete Callback. + (+) OC_DelayElapsedCallback : TIM Output Compare Delay Elapsed Callback. + (+) PWM_PulseFinishedCallback : TIM PWM Pulse Finished Callback. + (+) PWM_PulseFinishedHalfCpltCallback : TIM PWM Pulse Finished half complete Callback. + (+) ErrorCallback : TIM Error Callback. + (+) CommutationCallback : TIM Commutation Callback. + (+) CommutationHalfCpltCallback : TIM Commutation half complete Callback. + (+) BreakCallback : TIM Break Callback. + + [..] +By default, after the Init and when the state is HAL_TIM_STATE_RESET +all interrupt callbacks are set to the corresponding weak functions: + examples @ref HAL_TIM_TriggerCallback(), @ref HAL_TIM_ErrorCallback(). + + [..] + Exception done for MspInit and MspDeInit functions that are reset to the legacy weak + functionalities in the Init / DeInit only when these callbacks are null + (not registered beforehand). If not, MspInit or MspDeInit are not null, the Init / DeInit + keep and use the user MspInit / MspDeInit callbacks(registered beforehand) + + [..] + Callbacks can be registered / unregistered in HAL_TIM_STATE_READY state only. + Exception done MspInit / MspDeInit that can be registered / unregistered + in HAL_TIM_STATE_READY or HAL_TIM_STATE_RESET state, + thus registered(user) MspInit / DeInit callbacks can be used during the Init / DeInit. + In that case first register the MspInit/MspDeInit user callbacks + using @ref HAL_TIM_RegisterCallback() before calling DeInit or Init function. + + [..] + When The compilation define USE_HAL_TIM_REGISTER_CALLBACKS is set to 0 or + not defined, the callback registration feature is not available and all callbacks + are set to the corresponding weak functions. + + @endverbatim + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2016 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f0xx_hal.h" + +/** @addtogroup STM32F0xx_HAL_Driver + * @{ + */ + +/** @defgroup TIM TIM + * @brief TIM HAL module driver + * @{ + */ + +#ifdef HAL_TIM_MODULE_ENABLED + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/** @addtogroup TIM_Private_Functions + * @{ + */ +static void TIM_OC1_SetConfig(TIM_TypeDef *TIMx, TIM_OC_InitTypeDef *OC_Config); +static void TIM_OC3_SetConfig(TIM_TypeDef *TIMx, TIM_OC_InitTypeDef *OC_Config); +static void TIM_OC4_SetConfig(TIM_TypeDef *TIMx, TIM_OC_InitTypeDef *OC_Config); +static void TIM_TI1_ConfigInputStage(TIM_TypeDef *TIMx, uint32_t TIM_ICPolarity, uint32_t TIM_ICFilter); +static void TIM_TI2_SetConfig(TIM_TypeDef *TIMx, uint32_t TIM_ICPolarity, uint32_t TIM_ICSelection, + uint32_t TIM_ICFilter); +static void TIM_TI2_ConfigInputStage(TIM_TypeDef *TIMx, uint32_t TIM_ICPolarity, uint32_t TIM_ICFilter); +static void TIM_TI3_SetConfig(TIM_TypeDef *TIMx, uint32_t TIM_ICPolarity, uint32_t TIM_ICSelection, + uint32_t TIM_ICFilter); +static void TIM_TI4_SetConfig(TIM_TypeDef *TIMx, uint32_t TIM_ICPolarity, uint32_t TIM_ICSelection, + uint32_t TIM_ICFilter); +static void TIM_ITRx_SetConfig(TIM_TypeDef *TIMx, uint32_t InputTriggerSource); +static void TIM_DMAPeriodElapsedCplt(DMA_HandleTypeDef *hdma); +static void TIM_DMAPeriodElapsedHalfCplt(DMA_HandleTypeDef *hdma); +static void TIM_DMATriggerCplt(DMA_HandleTypeDef *hdma); +static void TIM_DMATriggerHalfCplt(DMA_HandleTypeDef *hdma); +static HAL_StatusTypeDef TIM_SlaveTimer_SetConfig(TIM_HandleTypeDef *htim, + TIM_SlaveConfigTypeDef *sSlaveConfig); +/** + * @} + */ +/* Exported functions --------------------------------------------------------*/ + +/** @defgroup TIM_Exported_Functions TIM Exported Functions + * @{ + */ + +/** @defgroup TIM_Exported_Functions_Group1 TIM Time Base functions + * @brief Time Base functions + * +@verbatim + ============================================================================== + ##### Time Base functions ##### + ============================================================================== + [..] + This section provides functions allowing to: + (+) Initialize and configure the TIM base. + (+) De-initialize the TIM base. + (+) Start the Time Base. + (+) Stop the Time Base. + (+) Start the Time Base and enable interrupt. + (+) Stop the Time Base and disable interrupt. + (+) Start the Time Base and enable DMA transfer. + (+) Stop the Time Base and disable DMA transfer. + +@endverbatim + * @{ + */ +/** + * @brief Initializes the TIM Time base Unit according to the specified + * parameters in the TIM_HandleTypeDef and initialize the associated handle. + * @note Switching from Center Aligned counter mode to Edge counter mode (or reverse) + * requires a timer reset to avoid unexpected direction + * due to DIR bit readonly in center aligned mode. + * Ex: call @ref HAL_TIM_Base_DeInit() before HAL_TIM_Base_Init() + * @param htim TIM Base handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_Base_Init(TIM_HandleTypeDef *htim) +{ + /* Check the TIM handle allocation */ + if (htim == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_TIM_INSTANCE(htim->Instance)); + assert_param(IS_TIM_COUNTER_MODE(htim->Init.CounterMode)); + assert_param(IS_TIM_CLOCKDIVISION_DIV(htim->Init.ClockDivision)); + assert_param(IS_TIM_AUTORELOAD_PRELOAD(htim->Init.AutoReloadPreload)); + + if (htim->State == HAL_TIM_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + htim->Lock = HAL_UNLOCKED; + +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + /* Reset interrupt callbacks to legacy weak callbacks */ + TIM_ResetCallback(htim); + + if (htim->Base_MspInitCallback == NULL) + { + htim->Base_MspInitCallback = HAL_TIM_Base_MspInit; + } + /* Init the low level hardware : GPIO, CLOCK, NVIC */ + htim->Base_MspInitCallback(htim); +#else + /* Init the low level hardware : GPIO, CLOCK, NVIC */ + HAL_TIM_Base_MspInit(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + } + + /* Set the TIM state */ + htim->State = HAL_TIM_STATE_BUSY; + + /* Set the Time Base configuration */ + TIM_Base_SetConfig(htim->Instance, &htim->Init); + + /* Initialize the TIM state*/ + htim->State = HAL_TIM_STATE_READY; + + return HAL_OK; +} + +/** + * @brief DeInitializes the TIM Base peripheral + * @param htim TIM Base handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_Base_DeInit(TIM_HandleTypeDef *htim) +{ + /* Check the parameters */ + assert_param(IS_TIM_INSTANCE(htim->Instance)); + + htim->State = HAL_TIM_STATE_BUSY; + + /* Disable the TIM Peripheral Clock */ + __HAL_TIM_DISABLE(htim); + +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + if (htim->Base_MspDeInitCallback == NULL) + { + htim->Base_MspDeInitCallback = HAL_TIM_Base_MspDeInit; + } + /* DeInit the low level hardware */ + htim->Base_MspDeInitCallback(htim); +#else + /* DeInit the low level hardware: GPIO, CLOCK, NVIC */ + HAL_TIM_Base_MspDeInit(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + + /* Change TIM state */ + htim->State = HAL_TIM_STATE_RESET; + + /* Release Lock */ + __HAL_UNLOCK(htim); + + return HAL_OK; +} + +/** + * @brief Initializes the TIM Base MSP. + * @param htim TIM Base handle + * @retval None + */ +__weak void HAL_TIM_Base_MspInit(TIM_HandleTypeDef *htim) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(htim); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_TIM_Base_MspInit could be implemented in the user file + */ +} + +/** + * @brief DeInitializes TIM Base MSP. + * @param htim TIM Base handle + * @retval None + */ +__weak void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef *htim) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(htim); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_TIM_Base_MspDeInit could be implemented in the user file + */ +} + + +/** + * @brief Starts the TIM Base generation. + * @param htim TIM Base handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_Base_Start(TIM_HandleTypeDef *htim) +{ + uint32_t tmpsmcr; + + /* Check the parameters */ + assert_param(IS_TIM_INSTANCE(htim->Instance)); + + /* Set the TIM state */ + htim->State = HAL_TIM_STATE_BUSY; + + /* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */ + tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS; + if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr)) + { + __HAL_TIM_ENABLE(htim); + } + + /* Change the TIM state*/ + htim->State = HAL_TIM_STATE_READY; + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stops the TIM Base generation. + * @param htim TIM Base handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_Base_Stop(TIM_HandleTypeDef *htim) +{ + /* Check the parameters */ + assert_param(IS_TIM_INSTANCE(htim->Instance)); + + /* Set the TIM state */ + htim->State = HAL_TIM_STATE_BUSY; + + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Change the TIM state*/ + htim->State = HAL_TIM_STATE_READY; + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Starts the TIM Base generation in interrupt mode. + * @param htim TIM Base handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_Base_Start_IT(TIM_HandleTypeDef *htim) +{ + uint32_t tmpsmcr; + + /* Check the parameters */ + assert_param(IS_TIM_INSTANCE(htim->Instance)); + + /* Enable the TIM Update interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_UPDATE); + + /* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */ + tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS; + if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr)) + { + __HAL_TIM_ENABLE(htim); + } + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stops the TIM Base generation in interrupt mode. + * @param htim TIM Base handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_Base_Stop_IT(TIM_HandleTypeDef *htim) +{ + /* Check the parameters */ + assert_param(IS_TIM_INSTANCE(htim->Instance)); + /* Disable the TIM Update interrupt */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_UPDATE); + + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Starts the TIM Base generation in DMA mode. + * @param htim TIM Base handle + * @param pData The source Buffer address. + * @param Length The length of data to be transferred from memory to peripheral. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_Base_Start_DMA(TIM_HandleTypeDef *htim, uint32_t *pData, uint16_t Length) +{ + uint32_t tmpsmcr; + + /* Check the parameters */ + assert_param(IS_TIM_DMA_INSTANCE(htim->Instance)); + + if (htim->State == HAL_TIM_STATE_BUSY) + { + return HAL_BUSY; + } + else if (htim->State == HAL_TIM_STATE_READY) + { + if ((pData == NULL) && (Length > 0U)) + { + return HAL_ERROR; + } + else + { + htim->State = HAL_TIM_STATE_BUSY; + } + } + else + { + /* nothing to do */ + } + + /* Set the DMA Period elapsed callbacks */ + htim->hdma[TIM_DMA_ID_UPDATE]->XferCpltCallback = TIM_DMAPeriodElapsedCplt; + htim->hdma[TIM_DMA_ID_UPDATE]->XferHalfCpltCallback = TIM_DMAPeriodElapsedHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_UPDATE]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA channel */ + if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_UPDATE], (uint32_t)pData, (uint32_t)&htim->Instance->ARR, Length) != HAL_OK) + { + return HAL_ERROR; + } + + /* Enable the TIM Update DMA request */ + __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_UPDATE); + + /* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */ + tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS; + if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr)) + { + __HAL_TIM_ENABLE(htim); + } + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stops the TIM Base generation in DMA mode. + * @param htim TIM Base handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_Base_Stop_DMA(TIM_HandleTypeDef *htim) +{ + /* Check the parameters */ + assert_param(IS_TIM_DMA_INSTANCE(htim->Instance)); + + /* Disable the TIM Update DMA request */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_UPDATE); + + (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_UPDATE]); + + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Change the htim state */ + htim->State = HAL_TIM_STATE_READY; + + /* Return function status */ + return HAL_OK; +} + +/** + * @} + */ + +/** @defgroup TIM_Exported_Functions_Group2 TIM Output Compare functions + * @brief TIM Output Compare functions + * +@verbatim + ============================================================================== + ##### TIM Output Compare functions ##### + ============================================================================== + [..] + This section provides functions allowing to: + (+) Initialize and configure the TIM Output Compare. + (+) De-initialize the TIM Output Compare. + (+) Start the TIM Output Compare. + (+) Stop the TIM Output Compare. + (+) Start the TIM Output Compare and enable interrupt. + (+) Stop the TIM Output Compare and disable interrupt. + (+) Start the TIM Output Compare and enable DMA transfer. + (+) Stop the TIM Output Compare and disable DMA transfer. + +@endverbatim + * @{ + */ +/** + * @brief Initializes the TIM Output Compare according to the specified + * parameters in the TIM_HandleTypeDef and initializes the associated handle. + * @note Switching from Center Aligned counter mode to Edge counter mode (or reverse) + * requires a timer reset to avoid unexpected direction + * due to DIR bit readonly in center aligned mode. + * Ex: call @ref HAL_TIM_OC_DeInit() before HAL_TIM_OC_Init() + * @param htim TIM Output Compare handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_OC_Init(TIM_HandleTypeDef *htim) +{ + /* Check the TIM handle allocation */ + if (htim == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_TIM_INSTANCE(htim->Instance)); + assert_param(IS_TIM_COUNTER_MODE(htim->Init.CounterMode)); + assert_param(IS_TIM_CLOCKDIVISION_DIV(htim->Init.ClockDivision)); + assert_param(IS_TIM_AUTORELOAD_PRELOAD(htim->Init.AutoReloadPreload)); + + if (htim->State == HAL_TIM_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + htim->Lock = HAL_UNLOCKED; + +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + /* Reset interrupt callbacks to legacy weak callbacks */ + TIM_ResetCallback(htim); + + if (htim->OC_MspInitCallback == NULL) + { + htim->OC_MspInitCallback = HAL_TIM_OC_MspInit; + } + /* Init the low level hardware : GPIO, CLOCK, NVIC */ + htim->OC_MspInitCallback(htim); +#else + /* Init the low level hardware : GPIO, CLOCK, NVIC and DMA */ + HAL_TIM_OC_MspInit(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + } + + /* Set the TIM state */ + htim->State = HAL_TIM_STATE_BUSY; + + /* Init the base time for the Output Compare */ + TIM_Base_SetConfig(htim->Instance, &htim->Init); + + /* Initialize the TIM state*/ + htim->State = HAL_TIM_STATE_READY; + + return HAL_OK; +} + +/** + * @brief DeInitializes the TIM peripheral + * @param htim TIM Output Compare handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_OC_DeInit(TIM_HandleTypeDef *htim) +{ + /* Check the parameters */ + assert_param(IS_TIM_INSTANCE(htim->Instance)); + + htim->State = HAL_TIM_STATE_BUSY; + + /* Disable the TIM Peripheral Clock */ + __HAL_TIM_DISABLE(htim); + +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + if (htim->OC_MspDeInitCallback == NULL) + { + htim->OC_MspDeInitCallback = HAL_TIM_OC_MspDeInit; + } + /* DeInit the low level hardware */ + htim->OC_MspDeInitCallback(htim); +#else + /* DeInit the low level hardware: GPIO, CLOCK, NVIC and DMA */ + HAL_TIM_OC_MspDeInit(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + + /* Change TIM state */ + htim->State = HAL_TIM_STATE_RESET; + + /* Release Lock */ + __HAL_UNLOCK(htim); + + return HAL_OK; +} + +/** + * @brief Initializes the TIM Output Compare MSP. + * @param htim TIM Output Compare handle + * @retval None + */ +__weak void HAL_TIM_OC_MspInit(TIM_HandleTypeDef *htim) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(htim); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_TIM_OC_MspInit could be implemented in the user file + */ +} + +/** + * @brief DeInitializes TIM Output Compare MSP. + * @param htim TIM Output Compare handle + * @retval None + */ +__weak void HAL_TIM_OC_MspDeInit(TIM_HandleTypeDef *htim) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(htim); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_TIM_OC_MspDeInit could be implemented in the user file + */ +} + +/** + * @brief Starts the TIM Output Compare signal generation. + * @param htim TIM Output Compare handle + * @param Channel TIM Channel to be enabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_OC_Start(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + uint32_t tmpsmcr; + + /* Check the parameters */ + assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel)); + + /* Enable the Output compare channel */ + TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_ENABLE); + + if (IS_TIM_BREAK_INSTANCE(htim->Instance) != RESET) + { + /* Enable the main output */ + __HAL_TIM_MOE_ENABLE(htim); + } + + /* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */ + tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS; + if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr)) + { + __HAL_TIM_ENABLE(htim); + } + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stops the TIM Output Compare signal generation. + * @param htim TIM Output Compare handle + * @param Channel TIM Channel to be disabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_OC_Stop(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + /* Check the parameters */ + assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel)); + + /* Disable the Output compare channel */ + TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_DISABLE); + + if (IS_TIM_BREAK_INSTANCE(htim->Instance) != RESET) + { + /* Disable the Main Output */ + __HAL_TIM_MOE_DISABLE(htim); + } + + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Starts the TIM Output Compare signal generation in interrupt mode. + * @param htim TIM Output Compare handle + * @param Channel TIM Channel to be enabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_OC_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + uint32_t tmpsmcr; + + /* Check the parameters */ + assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel)); + + switch (Channel) + { + case TIM_CHANNEL_1: + { + /* Enable the TIM Capture/Compare 1 interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC1); + break; + } + + case TIM_CHANNEL_2: + { + /* Enable the TIM Capture/Compare 2 interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC2); + break; + } + + case TIM_CHANNEL_3: + { + /* Enable the TIM Capture/Compare 3 interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC3); + break; + } + + case TIM_CHANNEL_4: + { + /* Enable the TIM Capture/Compare 4 interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC4); + break; + } + + default: + break; + } + + /* Enable the Output compare channel */ + TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_ENABLE); + + if (IS_TIM_BREAK_INSTANCE(htim->Instance) != RESET) + { + /* Enable the main output */ + __HAL_TIM_MOE_ENABLE(htim); + } + + /* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */ + tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS; + if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr)) + { + __HAL_TIM_ENABLE(htim); + } + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stops the TIM Output Compare signal generation in interrupt mode. + * @param htim TIM Output Compare handle + * @param Channel TIM Channel to be disabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_OC_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + /* Check the parameters */ + assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel)); + + switch (Channel) + { + case TIM_CHANNEL_1: + { + /* Disable the TIM Capture/Compare 1 interrupt */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC1); + break; + } + + case TIM_CHANNEL_2: + { + /* Disable the TIM Capture/Compare 2 interrupt */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC2); + break; + } + + case TIM_CHANNEL_3: + { + /* Disable the TIM Capture/Compare 3 interrupt */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC3); + break; + } + + case TIM_CHANNEL_4: + { + /* Disable the TIM Capture/Compare 4 interrupt */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC4); + break; + } + + default: + break; + } + + /* Disable the Output compare channel */ + TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_DISABLE); + + if (IS_TIM_BREAK_INSTANCE(htim->Instance) != RESET) + { + /* Disable the Main Output */ + __HAL_TIM_MOE_DISABLE(htim); + } + + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Starts the TIM Output Compare signal generation in DMA mode. + * @param htim TIM Output Compare handle + * @param Channel TIM Channel to be enabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @param pData The source Buffer address. + * @param Length The length of data to be transferred from memory to TIM peripheral + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_OC_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Channel, uint32_t *pData, uint16_t Length) +{ + uint32_t tmpsmcr; + + /* Check the parameters */ + assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel)); + + if (htim->State == HAL_TIM_STATE_BUSY) + { + return HAL_BUSY; + } + else if (htim->State == HAL_TIM_STATE_READY) + { + if ((pData == NULL) && (Length > 0U)) + { + return HAL_ERROR; + } + else + { + htim->State = HAL_TIM_STATE_BUSY; + } + } + else + { + /* nothing to do */ + } + + switch (Channel) + { + case TIM_CHANNEL_1: + { + /* Set the DMA compare callbacks */ + htim->hdma[TIM_DMA_ID_CC1]->XferCpltCallback = TIM_DMADelayPulseCplt; + htim->hdma[TIM_DMA_ID_CC1]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC1]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA channel */ + if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC1], (uint32_t)pData, (uint32_t)&htim->Instance->CCR1, Length) != HAL_OK) + { + return HAL_ERROR; + } + + /* Enable the TIM Capture/Compare 1 DMA request */ + __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC1); + break; + } + + case TIM_CHANNEL_2: + { + /* Set the DMA compare callbacks */ + htim->hdma[TIM_DMA_ID_CC2]->XferCpltCallback = TIM_DMADelayPulseCplt; + htim->hdma[TIM_DMA_ID_CC2]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC2]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA channel */ + if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC2], (uint32_t)pData, (uint32_t)&htim->Instance->CCR2, Length) != HAL_OK) + { + return HAL_ERROR; + } + + /* Enable the TIM Capture/Compare 2 DMA request */ + __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC2); + break; + } + + case TIM_CHANNEL_3: + { + /* Set the DMA compare callbacks */ + htim->hdma[TIM_DMA_ID_CC3]->XferCpltCallback = TIM_DMADelayPulseCplt; + htim->hdma[TIM_DMA_ID_CC3]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC3]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA channel */ + if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC3], (uint32_t)pData, (uint32_t)&htim->Instance->CCR3, Length) != HAL_OK) + { + return HAL_ERROR; + } + /* Enable the TIM Capture/Compare 3 DMA request */ + __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC3); + break; + } + + case TIM_CHANNEL_4: + { + /* Set the DMA compare callbacks */ + htim->hdma[TIM_DMA_ID_CC4]->XferCpltCallback = TIM_DMADelayPulseCplt; + htim->hdma[TIM_DMA_ID_CC4]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC4]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA channel */ + if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC4], (uint32_t)pData, (uint32_t)&htim->Instance->CCR4, Length) != HAL_OK) + { + return HAL_ERROR; + } + /* Enable the TIM Capture/Compare 4 DMA request */ + __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC4); + break; + } + + default: + break; + } + + /* Enable the Output compare channel */ + TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_ENABLE); + + if (IS_TIM_BREAK_INSTANCE(htim->Instance) != RESET) + { + /* Enable the main output */ + __HAL_TIM_MOE_ENABLE(htim); + } + + /* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */ + tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS; + if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr)) + { + __HAL_TIM_ENABLE(htim); + } + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stops the TIM Output Compare signal generation in DMA mode. + * @param htim TIM Output Compare handle + * @param Channel TIM Channel to be disabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_OC_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + /* Check the parameters */ + assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel)); + + switch (Channel) + { + case TIM_CHANNEL_1: + { + /* Disable the TIM Capture/Compare 1 DMA request */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC1); + (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC1]); + break; + } + + case TIM_CHANNEL_2: + { + /* Disable the TIM Capture/Compare 2 DMA request */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC2); + (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC2]); + break; + } + + case TIM_CHANNEL_3: + { + /* Disable the TIM Capture/Compare 3 DMA request */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC3); + (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC3]); + break; + } + + case TIM_CHANNEL_4: + { + /* Disable the TIM Capture/Compare 4 interrupt */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC4); + (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC4]); + break; + } + + default: + break; + } + + /* Disable the Output compare channel */ + TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_DISABLE); + + if (IS_TIM_BREAK_INSTANCE(htim->Instance) != RESET) + { + /* Disable the Main Output */ + __HAL_TIM_MOE_DISABLE(htim); + } + + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Change the htim state */ + htim->State = HAL_TIM_STATE_READY; + + /* Return function status */ + return HAL_OK; +} + +/** + * @} + */ + +/** @defgroup TIM_Exported_Functions_Group3 TIM PWM functions + * @brief TIM PWM functions + * +@verbatim + ============================================================================== + ##### TIM PWM functions ##### + ============================================================================== + [..] + This section provides functions allowing to: + (+) Initialize and configure the TIM PWM. + (+) De-initialize the TIM PWM. + (+) Start the TIM PWM. + (+) Stop the TIM PWM. + (+) Start the TIM PWM and enable interrupt. + (+) Stop the TIM PWM and disable interrupt. + (+) Start the TIM PWM and enable DMA transfer. + (+) Stop the TIM PWM and disable DMA transfer. + +@endverbatim + * @{ + */ +/** + * @brief Initializes the TIM PWM Time Base according to the specified + * parameters in the TIM_HandleTypeDef and initializes the associated handle. + * @note Switching from Center Aligned counter mode to Edge counter mode (or reverse) + * requires a timer reset to avoid unexpected direction + * due to DIR bit readonly in center aligned mode. + * Ex: call @ref HAL_TIM_PWM_DeInit() before HAL_TIM_PWM_Init() + * @param htim TIM PWM handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_PWM_Init(TIM_HandleTypeDef *htim) +{ + /* Check the TIM handle allocation */ + if (htim == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_TIM_INSTANCE(htim->Instance)); + assert_param(IS_TIM_COUNTER_MODE(htim->Init.CounterMode)); + assert_param(IS_TIM_CLOCKDIVISION_DIV(htim->Init.ClockDivision)); + assert_param(IS_TIM_AUTORELOAD_PRELOAD(htim->Init.AutoReloadPreload)); + + if (htim->State == HAL_TIM_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + htim->Lock = HAL_UNLOCKED; + +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + /* Reset interrupt callbacks to legacy weak callbacks */ + TIM_ResetCallback(htim); + + if (htim->PWM_MspInitCallback == NULL) + { + htim->PWM_MspInitCallback = HAL_TIM_PWM_MspInit; + } + /* Init the low level hardware : GPIO, CLOCK, NVIC */ + htim->PWM_MspInitCallback(htim); +#else + /* Init the low level hardware : GPIO, CLOCK, NVIC and DMA */ + HAL_TIM_PWM_MspInit(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + } + + /* Set the TIM state */ + htim->State = HAL_TIM_STATE_BUSY; + + /* Init the base time for the PWM */ + TIM_Base_SetConfig(htim->Instance, &htim->Init); + + /* Initialize the TIM state*/ + htim->State = HAL_TIM_STATE_READY; + + return HAL_OK; +} + +/** + * @brief DeInitializes the TIM peripheral + * @param htim TIM PWM handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_PWM_DeInit(TIM_HandleTypeDef *htim) +{ + /* Check the parameters */ + assert_param(IS_TIM_INSTANCE(htim->Instance)); + + htim->State = HAL_TIM_STATE_BUSY; + + /* Disable the TIM Peripheral Clock */ + __HAL_TIM_DISABLE(htim); + +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + if (htim->PWM_MspDeInitCallback == NULL) + { + htim->PWM_MspDeInitCallback = HAL_TIM_PWM_MspDeInit; + } + /* DeInit the low level hardware */ + htim->PWM_MspDeInitCallback(htim); +#else + /* DeInit the low level hardware: GPIO, CLOCK, NVIC and DMA */ + HAL_TIM_PWM_MspDeInit(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + + /* Change TIM state */ + htim->State = HAL_TIM_STATE_RESET; + + /* Release Lock */ + __HAL_UNLOCK(htim); + + return HAL_OK; +} + +/** + * @brief Initializes the TIM PWM MSP. + * @param htim TIM PWM handle + * @retval None + */ +__weak void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef *htim) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(htim); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_TIM_PWM_MspInit could be implemented in the user file + */ +} + +/** + * @brief DeInitializes TIM PWM MSP. + * @param htim TIM PWM handle + * @retval None + */ +__weak void HAL_TIM_PWM_MspDeInit(TIM_HandleTypeDef *htim) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(htim); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_TIM_PWM_MspDeInit could be implemented in the user file + */ +} + +/** + * @brief Starts the PWM signal generation. + * @param htim TIM handle + * @param Channel TIM Channels to be enabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_PWM_Start(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + uint32_t tmpsmcr; + + /* Check the parameters */ + assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel)); + + /* Enable the Capture compare channel */ + TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_ENABLE); + + if (IS_TIM_BREAK_INSTANCE(htim->Instance) != RESET) + { + /* Enable the main output */ + __HAL_TIM_MOE_ENABLE(htim); + } + + /* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */ + tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS; + if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr)) + { + __HAL_TIM_ENABLE(htim); + } + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stops the PWM signal generation. + * @param htim TIM PWM handle + * @param Channel TIM Channels to be disabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_PWM_Stop(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + /* Check the parameters */ + assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel)); + + /* Disable the Capture compare channel */ + TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_DISABLE); + + if (IS_TIM_BREAK_INSTANCE(htim->Instance) != RESET) + { + /* Disable the Main Output */ + __HAL_TIM_MOE_DISABLE(htim); + } + + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Change the htim state */ + htim->State = HAL_TIM_STATE_READY; + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Starts the PWM signal generation in interrupt mode. + * @param htim TIM PWM handle + * @param Channel TIM Channel to be enabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_PWM_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + uint32_t tmpsmcr; + /* Check the parameters */ + assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel)); + + switch (Channel) + { + case TIM_CHANNEL_1: + { + /* Enable the TIM Capture/Compare 1 interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC1); + break; + } + + case TIM_CHANNEL_2: + { + /* Enable the TIM Capture/Compare 2 interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC2); + break; + } + + case TIM_CHANNEL_3: + { + /* Enable the TIM Capture/Compare 3 interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC3); + break; + } + + case TIM_CHANNEL_4: + { + /* Enable the TIM Capture/Compare 4 interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC4); + break; + } + + default: + break; + } + + /* Enable the Capture compare channel */ + TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_ENABLE); + + if (IS_TIM_BREAK_INSTANCE(htim->Instance) != RESET) + { + /* Enable the main output */ + __HAL_TIM_MOE_ENABLE(htim); + } + + /* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */ + tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS; + if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr)) + { + __HAL_TIM_ENABLE(htim); + } + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stops the PWM signal generation in interrupt mode. + * @param htim TIM PWM handle + * @param Channel TIM Channels to be disabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_PWM_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + /* Check the parameters */ + assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel)); + + switch (Channel) + { + case TIM_CHANNEL_1: + { + /* Disable the TIM Capture/Compare 1 interrupt */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC1); + break; + } + + case TIM_CHANNEL_2: + { + /* Disable the TIM Capture/Compare 2 interrupt */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC2); + break; + } + + case TIM_CHANNEL_3: + { + /* Disable the TIM Capture/Compare 3 interrupt */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC3); + break; + } + + case TIM_CHANNEL_4: + { + /* Disable the TIM Capture/Compare 4 interrupt */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC4); + break; + } + + default: + break; + } + + /* Disable the Capture compare channel */ + TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_DISABLE); + + if (IS_TIM_BREAK_INSTANCE(htim->Instance) != RESET) + { + /* Disable the Main Output */ + __HAL_TIM_MOE_DISABLE(htim); + } + + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Starts the TIM PWM signal generation in DMA mode. + * @param htim TIM PWM handle + * @param Channel TIM Channels to be enabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @param pData The source Buffer address. + * @param Length The length of data to be transferred from memory to TIM peripheral + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_PWM_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Channel, uint32_t *pData, uint16_t Length) +{ + uint32_t tmpsmcr; + + /* Check the parameters */ + assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel)); + + if (htim->State == HAL_TIM_STATE_BUSY) + { + return HAL_BUSY; + } + else if (htim->State == HAL_TIM_STATE_READY) + { + if ((pData == NULL) && (Length > 0U)) + { + return HAL_ERROR; + } + else + { + htim->State = HAL_TIM_STATE_BUSY; + } + } + else + { + /* nothing to do */ + } + + switch (Channel) + { + case TIM_CHANNEL_1: + { + /* Set the DMA compare callbacks */ + htim->hdma[TIM_DMA_ID_CC1]->XferCpltCallback = TIM_DMADelayPulseCplt; + htim->hdma[TIM_DMA_ID_CC1]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC1]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA channel */ + if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC1], (uint32_t)pData, (uint32_t)&htim->Instance->CCR1, Length) != HAL_OK) + { + return HAL_ERROR; + } + + /* Enable the TIM Capture/Compare 1 DMA request */ + __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC1); + break; + } + + case TIM_CHANNEL_2: + { + /* Set the DMA compare callbacks */ + htim->hdma[TIM_DMA_ID_CC2]->XferCpltCallback = TIM_DMADelayPulseCplt; + htim->hdma[TIM_DMA_ID_CC2]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC2]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA channel */ + if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC2], (uint32_t)pData, (uint32_t)&htim->Instance->CCR2, Length) != HAL_OK) + { + return HAL_ERROR; + } + /* Enable the TIM Capture/Compare 2 DMA request */ + __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC2); + break; + } + + case TIM_CHANNEL_3: + { + /* Set the DMA compare callbacks */ + htim->hdma[TIM_DMA_ID_CC3]->XferCpltCallback = TIM_DMADelayPulseCplt; + htim->hdma[TIM_DMA_ID_CC3]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC3]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA channel */ + if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC3], (uint32_t)pData, (uint32_t)&htim->Instance->CCR3, Length) != HAL_OK) + { + return HAL_ERROR; + } + /* Enable the TIM Output Capture/Compare 3 request */ + __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC3); + break; + } + + case TIM_CHANNEL_4: + { + /* Set the DMA compare callbacks */ + htim->hdma[TIM_DMA_ID_CC4]->XferCpltCallback = TIM_DMADelayPulseCplt; + htim->hdma[TIM_DMA_ID_CC4]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC4]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA channel */ + if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC4], (uint32_t)pData, (uint32_t)&htim->Instance->CCR4, Length) != HAL_OK) + { + return HAL_ERROR; + } + /* Enable the TIM Capture/Compare 4 DMA request */ + __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC4); + break; + } + + default: + break; + } + + /* Enable the Capture compare channel */ + TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_ENABLE); + + if (IS_TIM_BREAK_INSTANCE(htim->Instance) != RESET) + { + /* Enable the main output */ + __HAL_TIM_MOE_ENABLE(htim); + } + + /* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */ + tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS; + if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr)) + { + __HAL_TIM_ENABLE(htim); + } + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stops the TIM PWM signal generation in DMA mode. + * @param htim TIM PWM handle + * @param Channel TIM Channels to be disabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_PWM_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + /* Check the parameters */ + assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel)); + + switch (Channel) + { + case TIM_CHANNEL_1: + { + /* Disable the TIM Capture/Compare 1 DMA request */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC1); + (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC1]); + break; + } + + case TIM_CHANNEL_2: + { + /* Disable the TIM Capture/Compare 2 DMA request */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC2); + (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC2]); + break; + } + + case TIM_CHANNEL_3: + { + /* Disable the TIM Capture/Compare 3 DMA request */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC3); + (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC3]); + break; + } + + case TIM_CHANNEL_4: + { + /* Disable the TIM Capture/Compare 4 interrupt */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC4); + (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC4]); + break; + } + + default: + break; + } + + /* Disable the Capture compare channel */ + TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_DISABLE); + + if (IS_TIM_BREAK_INSTANCE(htim->Instance) != RESET) + { + /* Disable the Main Output */ + __HAL_TIM_MOE_DISABLE(htim); + } + + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Change the htim state */ + htim->State = HAL_TIM_STATE_READY; + + /* Return function status */ + return HAL_OK; +} + +/** + * @} + */ + +/** @defgroup TIM_Exported_Functions_Group4 TIM Input Capture functions + * @brief TIM Input Capture functions + * +@verbatim + ============================================================================== + ##### TIM Input Capture functions ##### + ============================================================================== + [..] + This section provides functions allowing to: + (+) Initialize and configure the TIM Input Capture. + (+) De-initialize the TIM Input Capture. + (+) Start the TIM Input Capture. + (+) Stop the TIM Input Capture. + (+) Start the TIM Input Capture and enable interrupt. + (+) Stop the TIM Input Capture and disable interrupt. + (+) Start the TIM Input Capture and enable DMA transfer. + (+) Stop the TIM Input Capture and disable DMA transfer. + +@endverbatim + * @{ + */ +/** + * @brief Initializes the TIM Input Capture Time base according to the specified + * parameters in the TIM_HandleTypeDef and initializes the associated handle. + * @note Switching from Center Aligned counter mode to Edge counter mode (or reverse) + * requires a timer reset to avoid unexpected direction + * due to DIR bit readonly in center aligned mode. + * Ex: call @ref HAL_TIM_IC_DeInit() before HAL_TIM_IC_Init() + * @param htim TIM Input Capture handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_IC_Init(TIM_HandleTypeDef *htim) +{ + /* Check the TIM handle allocation */ + if (htim == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_TIM_INSTANCE(htim->Instance)); + assert_param(IS_TIM_COUNTER_MODE(htim->Init.CounterMode)); + assert_param(IS_TIM_CLOCKDIVISION_DIV(htim->Init.ClockDivision)); + assert_param(IS_TIM_AUTORELOAD_PRELOAD(htim->Init.AutoReloadPreload)); + + if (htim->State == HAL_TIM_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + htim->Lock = HAL_UNLOCKED; + +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + /* Reset interrupt callbacks to legacy weak callbacks */ + TIM_ResetCallback(htim); + + if (htim->IC_MspInitCallback == NULL) + { + htim->IC_MspInitCallback = HAL_TIM_IC_MspInit; + } + /* Init the low level hardware : GPIO, CLOCK, NVIC */ + htim->IC_MspInitCallback(htim); +#else + /* Init the low level hardware : GPIO, CLOCK, NVIC and DMA */ + HAL_TIM_IC_MspInit(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + } + + /* Set the TIM state */ + htim->State = HAL_TIM_STATE_BUSY; + + /* Init the base time for the input capture */ + TIM_Base_SetConfig(htim->Instance, &htim->Init); + + /* Initialize the TIM state*/ + htim->State = HAL_TIM_STATE_READY; + + return HAL_OK; +} + +/** + * @brief DeInitializes the TIM peripheral + * @param htim TIM Input Capture handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_IC_DeInit(TIM_HandleTypeDef *htim) +{ + /* Check the parameters */ + assert_param(IS_TIM_INSTANCE(htim->Instance)); + + htim->State = HAL_TIM_STATE_BUSY; + + /* Disable the TIM Peripheral Clock */ + __HAL_TIM_DISABLE(htim); + +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + if (htim->IC_MspDeInitCallback == NULL) + { + htim->IC_MspDeInitCallback = HAL_TIM_IC_MspDeInit; + } + /* DeInit the low level hardware */ + htim->IC_MspDeInitCallback(htim); +#else + /* DeInit the low level hardware: GPIO, CLOCK, NVIC and DMA */ + HAL_TIM_IC_MspDeInit(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + + /* Change TIM state */ + htim->State = HAL_TIM_STATE_RESET; + + /* Release Lock */ + __HAL_UNLOCK(htim); + + return HAL_OK; +} + +/** + * @brief Initializes the TIM Input Capture MSP. + * @param htim TIM Input Capture handle + * @retval None + */ +__weak void HAL_TIM_IC_MspInit(TIM_HandleTypeDef *htim) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(htim); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_TIM_IC_MspInit could be implemented in the user file + */ +} + +/** + * @brief DeInitializes TIM Input Capture MSP. + * @param htim TIM handle + * @retval None + */ +__weak void HAL_TIM_IC_MspDeInit(TIM_HandleTypeDef *htim) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(htim); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_TIM_IC_MspDeInit could be implemented in the user file + */ +} + +/** + * @brief Starts the TIM Input Capture measurement. + * @param htim TIM Input Capture handle + * @param Channel TIM Channels to be enabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_IC_Start(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + uint32_t tmpsmcr; + + /* Check the parameters */ + assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel)); + + /* Enable the Input Capture channel */ + TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_ENABLE); + + /* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */ + tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS; + if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr)) + { + __HAL_TIM_ENABLE(htim); + } + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stops the TIM Input Capture measurement. + * @param htim TIM Input Capture handle + * @param Channel TIM Channels to be disabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_IC_Stop(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + /* Check the parameters */ + assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel)); + + /* Disable the Input Capture channel */ + TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_DISABLE); + + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Starts the TIM Input Capture measurement in interrupt mode. + * @param htim TIM Input Capture handle + * @param Channel TIM Channels to be enabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_IC_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + uint32_t tmpsmcr; + + /* Check the parameters */ + assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel)); + + switch (Channel) + { + case TIM_CHANNEL_1: + { + /* Enable the TIM Capture/Compare 1 interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC1); + break; + } + + case TIM_CHANNEL_2: + { + /* Enable the TIM Capture/Compare 2 interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC2); + break; + } + + case TIM_CHANNEL_3: + { + /* Enable the TIM Capture/Compare 3 interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC3); + break; + } + + case TIM_CHANNEL_4: + { + /* Enable the TIM Capture/Compare 4 interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC4); + break; + } + + default: + break; + } + /* Enable the Input Capture channel */ + TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_ENABLE); + + /* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */ + tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS; + if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr)) + { + __HAL_TIM_ENABLE(htim); + } + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stops the TIM Input Capture measurement in interrupt mode. + * @param htim TIM Input Capture handle + * @param Channel TIM Channels to be disabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_IC_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + /* Check the parameters */ + assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel)); + + switch (Channel) + { + case TIM_CHANNEL_1: + { + /* Disable the TIM Capture/Compare 1 interrupt */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC1); + break; + } + + case TIM_CHANNEL_2: + { + /* Disable the TIM Capture/Compare 2 interrupt */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC2); + break; + } + + case TIM_CHANNEL_3: + { + /* Disable the TIM Capture/Compare 3 interrupt */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC3); + break; + } + + case TIM_CHANNEL_4: + { + /* Disable the TIM Capture/Compare 4 interrupt */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC4); + break; + } + + default: + break; + } + + /* Disable the Input Capture channel */ + TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_DISABLE); + + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Starts the TIM Input Capture measurement in DMA mode. + * @param htim TIM Input Capture handle + * @param Channel TIM Channels to be enabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @param pData The destination Buffer address. + * @param Length The length of data to be transferred from TIM peripheral to memory. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_IC_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Channel, uint32_t *pData, uint16_t Length) +{ + uint32_t tmpsmcr; + + /* Check the parameters */ + assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel)); + assert_param(IS_TIM_DMA_CC_INSTANCE(htim->Instance)); + + if (htim->State == HAL_TIM_STATE_BUSY) + { + return HAL_BUSY; + } + else if (htim->State == HAL_TIM_STATE_READY) + { + if ((pData == NULL) && (Length > 0U)) + { + return HAL_ERROR; + } + else + { + htim->State = HAL_TIM_STATE_BUSY; + } + } + else + { + /* nothing to do */ + } + + switch (Channel) + { + case TIM_CHANNEL_1: + { + /* Set the DMA capture callbacks */ + htim->hdma[TIM_DMA_ID_CC1]->XferCpltCallback = TIM_DMACaptureCplt; + htim->hdma[TIM_DMA_ID_CC1]->XferHalfCpltCallback = TIM_DMACaptureHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC1]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA channel */ + if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC1], (uint32_t)&htim->Instance->CCR1, (uint32_t)pData, Length) != HAL_OK) + { + return HAL_ERROR; + } + /* Enable the TIM Capture/Compare 1 DMA request */ + __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC1); + break; + } + + case TIM_CHANNEL_2: + { + /* Set the DMA capture callbacks */ + htim->hdma[TIM_DMA_ID_CC2]->XferCpltCallback = TIM_DMACaptureCplt; + htim->hdma[TIM_DMA_ID_CC2]->XferHalfCpltCallback = TIM_DMACaptureHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC2]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA channel */ + if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC2], (uint32_t)&htim->Instance->CCR2, (uint32_t)pData, Length) != HAL_OK) + { + return HAL_ERROR; + } + /* Enable the TIM Capture/Compare 2 DMA request */ + __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC2); + break; + } + + case TIM_CHANNEL_3: + { + /* Set the DMA capture callbacks */ + htim->hdma[TIM_DMA_ID_CC3]->XferCpltCallback = TIM_DMACaptureCplt; + htim->hdma[TIM_DMA_ID_CC3]->XferHalfCpltCallback = TIM_DMACaptureHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC3]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA channel */ + if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC3], (uint32_t)&htim->Instance->CCR3, (uint32_t)pData, Length) != HAL_OK) + { + return HAL_ERROR; + } + /* Enable the TIM Capture/Compare 3 DMA request */ + __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC3); + break; + } + + case TIM_CHANNEL_4: + { + /* Set the DMA capture callbacks */ + htim->hdma[TIM_DMA_ID_CC4]->XferCpltCallback = TIM_DMACaptureCplt; + htim->hdma[TIM_DMA_ID_CC4]->XferHalfCpltCallback = TIM_DMACaptureHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC4]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA channel */ + if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC4], (uint32_t)&htim->Instance->CCR4, (uint32_t)pData, Length) != HAL_OK) + { + return HAL_ERROR; + } + /* Enable the TIM Capture/Compare 4 DMA request */ + __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC4); + break; + } + + default: + break; + } + + /* Enable the Input Capture channel */ + TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_ENABLE); + + /* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */ + tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS; + if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr)) + { + __HAL_TIM_ENABLE(htim); + } + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stops the TIM Input Capture measurement in DMA mode. + * @param htim TIM Input Capture handle + * @param Channel TIM Channels to be disabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_IC_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + /* Check the parameters */ + assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel)); + assert_param(IS_TIM_DMA_CC_INSTANCE(htim->Instance)); + + switch (Channel) + { + case TIM_CHANNEL_1: + { + /* Disable the TIM Capture/Compare 1 DMA request */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC1); + (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC1]); + break; + } + + case TIM_CHANNEL_2: + { + /* Disable the TIM Capture/Compare 2 DMA request */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC2); + (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC2]); + break; + } + + case TIM_CHANNEL_3: + { + /* Disable the TIM Capture/Compare 3 DMA request */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC3); + (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC3]); + break; + } + + case TIM_CHANNEL_4: + { + /* Disable the TIM Capture/Compare 4 DMA request */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC4); + (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC4]); + break; + } + + default: + break; + } + + /* Disable the Input Capture channel */ + TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_DISABLE); + + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Change the htim state */ + htim->State = HAL_TIM_STATE_READY; + + /* Return function status */ + return HAL_OK; +} +/** + * @} + */ + +/** @defgroup TIM_Exported_Functions_Group5 TIM One Pulse functions + * @brief TIM One Pulse functions + * +@verbatim + ============================================================================== + ##### TIM One Pulse functions ##### + ============================================================================== + [..] + This section provides functions allowing to: + (+) Initialize and configure the TIM One Pulse. + (+) De-initialize the TIM One Pulse. + (+) Start the TIM One Pulse. + (+) Stop the TIM One Pulse. + (+) Start the TIM One Pulse and enable interrupt. + (+) Stop the TIM One Pulse and disable interrupt. + (+) Start the TIM One Pulse and enable DMA transfer. + (+) Stop the TIM One Pulse and disable DMA transfer. + +@endverbatim + * @{ + */ +/** + * @brief Initializes the TIM One Pulse Time Base according to the specified + * parameters in the TIM_HandleTypeDef and initializes the associated handle. + * @note Switching from Center Aligned counter mode to Edge counter mode (or reverse) + * requires a timer reset to avoid unexpected direction + * due to DIR bit readonly in center aligned mode. + * Ex: call @ref HAL_TIM_OnePulse_DeInit() before HAL_TIM_OnePulse_Init() + * @param htim TIM One Pulse handle + * @param OnePulseMode Select the One pulse mode. + * This parameter can be one of the following values: + * @arg TIM_OPMODE_SINGLE: Only one pulse will be generated. + * @arg TIM_OPMODE_REPETITIVE: Repetitive pulses will be generated. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_OnePulse_Init(TIM_HandleTypeDef *htim, uint32_t OnePulseMode) +{ + /* Check the TIM handle allocation */ + if (htim == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_TIM_INSTANCE(htim->Instance)); + assert_param(IS_TIM_COUNTER_MODE(htim->Init.CounterMode)); + assert_param(IS_TIM_CLOCKDIVISION_DIV(htim->Init.ClockDivision)); + assert_param(IS_TIM_OPM_MODE(OnePulseMode)); + assert_param(IS_TIM_AUTORELOAD_PRELOAD(htim->Init.AutoReloadPreload)); + + if (htim->State == HAL_TIM_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + htim->Lock = HAL_UNLOCKED; + +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + /* Reset interrupt callbacks to legacy weak callbacks */ + TIM_ResetCallback(htim); + + if (htim->OnePulse_MspInitCallback == NULL) + { + htim->OnePulse_MspInitCallback = HAL_TIM_OnePulse_MspInit; + } + /* Init the low level hardware : GPIO, CLOCK, NVIC */ + htim->OnePulse_MspInitCallback(htim); +#else + /* Init the low level hardware : GPIO, CLOCK, NVIC and DMA */ + HAL_TIM_OnePulse_MspInit(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + } + + /* Set the TIM state */ + htim->State = HAL_TIM_STATE_BUSY; + + /* Configure the Time base in the One Pulse Mode */ + TIM_Base_SetConfig(htim->Instance, &htim->Init); + + /* Reset the OPM Bit */ + htim->Instance->CR1 &= ~TIM_CR1_OPM; + + /* Configure the OPM Mode */ + htim->Instance->CR1 |= OnePulseMode; + + /* Initialize the TIM state*/ + htim->State = HAL_TIM_STATE_READY; + + return HAL_OK; +} + +/** + * @brief DeInitializes the TIM One Pulse + * @param htim TIM One Pulse handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_OnePulse_DeInit(TIM_HandleTypeDef *htim) +{ + /* Check the parameters */ + assert_param(IS_TIM_INSTANCE(htim->Instance)); + + htim->State = HAL_TIM_STATE_BUSY; + + /* Disable the TIM Peripheral Clock */ + __HAL_TIM_DISABLE(htim); + +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + if (htim->OnePulse_MspDeInitCallback == NULL) + { + htim->OnePulse_MspDeInitCallback = HAL_TIM_OnePulse_MspDeInit; + } + /* DeInit the low level hardware */ + htim->OnePulse_MspDeInitCallback(htim); +#else + /* DeInit the low level hardware: GPIO, CLOCK, NVIC */ + HAL_TIM_OnePulse_MspDeInit(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + + /* Change TIM state */ + htim->State = HAL_TIM_STATE_RESET; + + /* Release Lock */ + __HAL_UNLOCK(htim); + + return HAL_OK; +} + +/** + * @brief Initializes the TIM One Pulse MSP. + * @param htim TIM One Pulse handle + * @retval None + */ +__weak void HAL_TIM_OnePulse_MspInit(TIM_HandleTypeDef *htim) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(htim); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_TIM_OnePulse_MspInit could be implemented in the user file + */ +} + +/** + * @brief DeInitializes TIM One Pulse MSP. + * @param htim TIM One Pulse handle + * @retval None + */ +__weak void HAL_TIM_OnePulse_MspDeInit(TIM_HandleTypeDef *htim) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(htim); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_TIM_OnePulse_MspDeInit could be implemented in the user file + */ +} + +/** + * @brief Starts the TIM One Pulse signal generation. + * @param htim TIM One Pulse handle + * @param OutputChannel TIM Channels to be enabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_OnePulse_Start(TIM_HandleTypeDef *htim, uint32_t OutputChannel) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(OutputChannel); + + /* Enable the Capture compare and the Input Capture channels + (in the OPM Mode the two possible channels that can be used are TIM_CHANNEL_1 and TIM_CHANNEL_2) + if TIM_CHANNEL_1 is used as output, the TIM_CHANNEL_2 will be used as input and + if TIM_CHANNEL_1 is used as input, the TIM_CHANNEL_2 will be used as output + in all combinations, the TIM_CHANNEL_1 and TIM_CHANNEL_2 should be enabled together + + No need to enable the counter, it's enabled automatically by hardware + (the counter starts in response to a stimulus and generate a pulse */ + + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_ENABLE); + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_ENABLE); + + if (IS_TIM_BREAK_INSTANCE(htim->Instance) != RESET) + { + /* Enable the main output */ + __HAL_TIM_MOE_ENABLE(htim); + } + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stops the TIM One Pulse signal generation. + * @param htim TIM One Pulse handle + * @param OutputChannel TIM Channels to be disable + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_OnePulse_Stop(TIM_HandleTypeDef *htim, uint32_t OutputChannel) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(OutputChannel); + + /* Disable the Capture compare and the Input Capture channels + (in the OPM Mode the two possible channels that can be used are TIM_CHANNEL_1 and TIM_CHANNEL_2) + if TIM_CHANNEL_1 is used as output, the TIM_CHANNEL_2 will be used as input and + if TIM_CHANNEL_1 is used as input, the TIM_CHANNEL_2 will be used as output + in all combinations, the TIM_CHANNEL_1 and TIM_CHANNEL_2 should be disabled together */ + + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_DISABLE); + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_DISABLE); + + if (IS_TIM_BREAK_INSTANCE(htim->Instance) != RESET) + { + /* Disable the Main Output */ + __HAL_TIM_MOE_DISABLE(htim); + } + + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Starts the TIM One Pulse signal generation in interrupt mode. + * @param htim TIM One Pulse handle + * @param OutputChannel TIM Channels to be enabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_OnePulse_Start_IT(TIM_HandleTypeDef *htim, uint32_t OutputChannel) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(OutputChannel); + + /* Enable the Capture compare and the Input Capture channels + (in the OPM Mode the two possible channels that can be used are TIM_CHANNEL_1 and TIM_CHANNEL_2) + if TIM_CHANNEL_1 is used as output, the TIM_CHANNEL_2 will be used as input and + if TIM_CHANNEL_1 is used as input, the TIM_CHANNEL_2 will be used as output + in all combinations, the TIM_CHANNEL_1 and TIM_CHANNEL_2 should be enabled together + + No need to enable the counter, it's enabled automatically by hardware + (the counter starts in response to a stimulus and generate a pulse */ + + /* Enable the TIM Capture/Compare 1 interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC1); + + /* Enable the TIM Capture/Compare 2 interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC2); + + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_ENABLE); + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_ENABLE); + + if (IS_TIM_BREAK_INSTANCE(htim->Instance) != RESET) + { + /* Enable the main output */ + __HAL_TIM_MOE_ENABLE(htim); + } + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stops the TIM One Pulse signal generation in interrupt mode. + * @param htim TIM One Pulse handle + * @param OutputChannel TIM Channels to be enabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_OnePulse_Stop_IT(TIM_HandleTypeDef *htim, uint32_t OutputChannel) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(OutputChannel); + + /* Disable the TIM Capture/Compare 1 interrupt */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC1); + + /* Disable the TIM Capture/Compare 2 interrupt */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC2); + + /* Disable the Capture compare and the Input Capture channels + (in the OPM Mode the two possible channels that can be used are TIM_CHANNEL_1 and TIM_CHANNEL_2) + if TIM_CHANNEL_1 is used as output, the TIM_CHANNEL_2 will be used as input and + if TIM_CHANNEL_1 is used as input, the TIM_CHANNEL_2 will be used as output + in all combinations, the TIM_CHANNEL_1 and TIM_CHANNEL_2 should be disabled together */ + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_DISABLE); + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_DISABLE); + + if (IS_TIM_BREAK_INSTANCE(htim->Instance) != RESET) + { + /* Disable the Main Output */ + __HAL_TIM_MOE_DISABLE(htim); + } + + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Return function status */ + return HAL_OK; +} + +/** + * @} + */ + +/** @defgroup TIM_Exported_Functions_Group6 TIM Encoder functions + * @brief TIM Encoder functions + * +@verbatim + ============================================================================== + ##### TIM Encoder functions ##### + ============================================================================== + [..] + This section provides functions allowing to: + (+) Initialize and configure the TIM Encoder. + (+) De-initialize the TIM Encoder. + (+) Start the TIM Encoder. + (+) Stop the TIM Encoder. + (+) Start the TIM Encoder and enable interrupt. + (+) Stop the TIM Encoder and disable interrupt. + (+) Start the TIM Encoder and enable DMA transfer. + (+) Stop the TIM Encoder and disable DMA transfer. + +@endverbatim + * @{ + */ +/** + * @brief Initializes the TIM Encoder Interface and initialize the associated handle. + * @note Switching from Center Aligned counter mode to Edge counter mode (or reverse) + * requires a timer reset to avoid unexpected direction + * due to DIR bit readonly in center aligned mode. + * Ex: call @ref HAL_TIM_Encoder_DeInit() before HAL_TIM_Encoder_Init() + * @note Encoder mode and External clock mode 2 are not compatible and must not be selected together + * Ex: A call for @ref HAL_TIM_Encoder_Init will erase the settings of @ref HAL_TIM_ConfigClockSource + * using TIM_CLOCKSOURCE_ETRMODE2 and vice versa + * @param htim TIM Encoder Interface handle + * @param sConfig TIM Encoder Interface configuration structure + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_Encoder_Init(TIM_HandleTypeDef *htim, TIM_Encoder_InitTypeDef *sConfig) +{ + uint32_t tmpsmcr; + uint32_t tmpccmr1; + uint32_t tmpccer; + + /* Check the TIM handle allocation */ + if (htim == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_TIM_COUNTER_MODE(htim->Init.CounterMode)); + assert_param(IS_TIM_CLOCKDIVISION_DIV(htim->Init.ClockDivision)); + assert_param(IS_TIM_AUTORELOAD_PRELOAD(htim->Init.AutoReloadPreload)); + assert_param(IS_TIM_CC2_INSTANCE(htim->Instance)); + assert_param(IS_TIM_ENCODER_MODE(sConfig->EncoderMode)); + assert_param(IS_TIM_IC_SELECTION(sConfig->IC1Selection)); + assert_param(IS_TIM_IC_SELECTION(sConfig->IC2Selection)); + assert_param(IS_TIM_ENCODERINPUT_POLARITY(sConfig->IC1Polarity)); + assert_param(IS_TIM_ENCODERINPUT_POLARITY(sConfig->IC2Polarity)); + assert_param(IS_TIM_IC_PRESCALER(sConfig->IC1Prescaler)); + assert_param(IS_TIM_IC_PRESCALER(sConfig->IC2Prescaler)); + assert_param(IS_TIM_IC_FILTER(sConfig->IC1Filter)); + assert_param(IS_TIM_IC_FILTER(sConfig->IC2Filter)); + + if (htim->State == HAL_TIM_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + htim->Lock = HAL_UNLOCKED; + +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + /* Reset interrupt callbacks to legacy weak callbacks */ + TIM_ResetCallback(htim); + + if (htim->Encoder_MspInitCallback == NULL) + { + htim->Encoder_MspInitCallback = HAL_TIM_Encoder_MspInit; + } + /* Init the low level hardware : GPIO, CLOCK, NVIC */ + htim->Encoder_MspInitCallback(htim); +#else + /* Init the low level hardware : GPIO, CLOCK, NVIC and DMA */ + HAL_TIM_Encoder_MspInit(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + } + + /* Set the TIM state */ + htim->State = HAL_TIM_STATE_BUSY; + + /* Reset the SMS and ECE bits */ + htim->Instance->SMCR &= ~(TIM_SMCR_SMS | TIM_SMCR_ECE); + + /* Configure the Time base in the Encoder Mode */ + TIM_Base_SetConfig(htim->Instance, &htim->Init); + + /* Get the TIMx SMCR register value */ + tmpsmcr = htim->Instance->SMCR; + + /* Get the TIMx CCMR1 register value */ + tmpccmr1 = htim->Instance->CCMR1; + + /* Get the TIMx CCER register value */ + tmpccer = htim->Instance->CCER; + + /* Set the encoder Mode */ + tmpsmcr |= sConfig->EncoderMode; + + /* Select the Capture Compare 1 and the Capture Compare 2 as input */ + tmpccmr1 &= ~(TIM_CCMR1_CC1S | TIM_CCMR1_CC2S); + tmpccmr1 |= (sConfig->IC1Selection | (sConfig->IC2Selection << 8U)); + + /* Set the Capture Compare 1 and the Capture Compare 2 prescalers and filters */ + tmpccmr1 &= ~(TIM_CCMR1_IC1PSC | TIM_CCMR1_IC2PSC); + tmpccmr1 &= ~(TIM_CCMR1_IC1F | TIM_CCMR1_IC2F); + tmpccmr1 |= sConfig->IC1Prescaler | (sConfig->IC2Prescaler << 8U); + tmpccmr1 |= (sConfig->IC1Filter << 4U) | (sConfig->IC2Filter << 12U); + + /* Set the TI1 and the TI2 Polarities */ + tmpccer &= ~(TIM_CCER_CC1P | TIM_CCER_CC2P); + tmpccer &= ~(TIM_CCER_CC1NP | TIM_CCER_CC2NP); + tmpccer |= sConfig->IC1Polarity | (sConfig->IC2Polarity << 4U); + + /* Write to TIMx SMCR */ + htim->Instance->SMCR = tmpsmcr; + + /* Write to TIMx CCMR1 */ + htim->Instance->CCMR1 = tmpccmr1; + + /* Write to TIMx CCER */ + htim->Instance->CCER = tmpccer; + + /* Initialize the TIM state*/ + htim->State = HAL_TIM_STATE_READY; + + return HAL_OK; +} + + +/** + * @brief DeInitializes the TIM Encoder interface + * @param htim TIM Encoder Interface handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_Encoder_DeInit(TIM_HandleTypeDef *htim) +{ + /* Check the parameters */ + assert_param(IS_TIM_INSTANCE(htim->Instance)); + + htim->State = HAL_TIM_STATE_BUSY; + + /* Disable the TIM Peripheral Clock */ + __HAL_TIM_DISABLE(htim); + +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + if (htim->Encoder_MspDeInitCallback == NULL) + { + htim->Encoder_MspDeInitCallback = HAL_TIM_Encoder_MspDeInit; + } + /* DeInit the low level hardware */ + htim->Encoder_MspDeInitCallback(htim); +#else + /* DeInit the low level hardware: GPIO, CLOCK, NVIC */ + HAL_TIM_Encoder_MspDeInit(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + + /* Change TIM state */ + htim->State = HAL_TIM_STATE_RESET; + + /* Release Lock */ + __HAL_UNLOCK(htim); + + return HAL_OK; +} + +/** + * @brief Initializes the TIM Encoder Interface MSP. + * @param htim TIM Encoder Interface handle + * @retval None + */ +__weak void HAL_TIM_Encoder_MspInit(TIM_HandleTypeDef *htim) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(htim); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_TIM_Encoder_MspInit could be implemented in the user file + */ +} + +/** + * @brief DeInitializes TIM Encoder Interface MSP. + * @param htim TIM Encoder Interface handle + * @retval None + */ +__weak void HAL_TIM_Encoder_MspDeInit(TIM_HandleTypeDef *htim) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(htim); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_TIM_Encoder_MspDeInit could be implemented in the user file + */ +} + +/** + * @brief Starts the TIM Encoder Interface. + * @param htim TIM Encoder Interface handle + * @param Channel TIM Channels to be enabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_ALL: TIM Channel 1 and TIM Channel 2 are selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_Encoder_Start(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + /* Check the parameters */ + assert_param(IS_TIM_CC2_INSTANCE(htim->Instance)); + + /* Enable the encoder interface channels */ + switch (Channel) + { + case TIM_CHANNEL_1: + { + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_ENABLE); + break; + } + + case TIM_CHANNEL_2: + { + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_ENABLE); + break; + } + + default : + { + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_ENABLE); + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_ENABLE); + break; + } + } + /* Enable the Peripheral */ + __HAL_TIM_ENABLE(htim); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stops the TIM Encoder Interface. + * @param htim TIM Encoder Interface handle + * @param Channel TIM Channels to be disabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_ALL: TIM Channel 1 and TIM Channel 2 are selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_Encoder_Stop(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + /* Check the parameters */ + assert_param(IS_TIM_CC2_INSTANCE(htim->Instance)); + + /* Disable the Input Capture channels 1 and 2 + (in the EncoderInterface the two possible channels that can be used are TIM_CHANNEL_1 and TIM_CHANNEL_2) */ + switch (Channel) + { + case TIM_CHANNEL_1: + { + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_DISABLE); + break; + } + + case TIM_CHANNEL_2: + { + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_DISABLE); + break; + } + + default : + { + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_DISABLE); + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_DISABLE); + break; + } + } + + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Starts the TIM Encoder Interface in interrupt mode. + * @param htim TIM Encoder Interface handle + * @param Channel TIM Channels to be enabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_ALL: TIM Channel 1 and TIM Channel 2 are selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_Encoder_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + /* Check the parameters */ + assert_param(IS_TIM_CC2_INSTANCE(htim->Instance)); + + /* Enable the encoder interface channels */ + /* Enable the capture compare Interrupts 1 and/or 2 */ + switch (Channel) + { + case TIM_CHANNEL_1: + { + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_ENABLE); + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC1); + break; + } + + case TIM_CHANNEL_2: + { + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_ENABLE); + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC2); + break; + } + + default : + { + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_ENABLE); + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_ENABLE); + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC1); + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC2); + break; + } + } + + /* Enable the Peripheral */ + __HAL_TIM_ENABLE(htim); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stops the TIM Encoder Interface in interrupt mode. + * @param htim TIM Encoder Interface handle + * @param Channel TIM Channels to be disabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_ALL: TIM Channel 1 and TIM Channel 2 are selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_Encoder_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + /* Check the parameters */ + assert_param(IS_TIM_CC2_INSTANCE(htim->Instance)); + + /* Disable the Input Capture channels 1 and 2 + (in the EncoderInterface the two possible channels that can be used are TIM_CHANNEL_1 and TIM_CHANNEL_2) */ + if (Channel == TIM_CHANNEL_1) + { + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_DISABLE); + + /* Disable the capture compare Interrupts 1 */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC1); + } + else if (Channel == TIM_CHANNEL_2) + { + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_DISABLE); + + /* Disable the capture compare Interrupts 2 */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC2); + } + else + { + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_DISABLE); + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_DISABLE); + + /* Disable the capture compare Interrupts 1 and 2 */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC1); + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC2); + } + + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Change the htim state */ + htim->State = HAL_TIM_STATE_READY; + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Starts the TIM Encoder Interface in DMA mode. + * @param htim TIM Encoder Interface handle + * @param Channel TIM Channels to be enabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_ALL: TIM Channel 1 and TIM Channel 2 are selected + * @param pData1 The destination Buffer address for IC1. + * @param pData2 The destination Buffer address for IC2. + * @param Length The length of data to be transferred from TIM peripheral to memory. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_Encoder_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Channel, uint32_t *pData1, + uint32_t *pData2, uint16_t Length) +{ + /* Check the parameters */ + assert_param(IS_TIM_DMA_CC_INSTANCE(htim->Instance)); + + if (htim->State == HAL_TIM_STATE_BUSY) + { + return HAL_BUSY; + } + else if (htim->State == HAL_TIM_STATE_READY) + { + if ((((pData1 == NULL) || (pData2 == NULL))) && (Length > 0U)) + { + return HAL_ERROR; + } + else + { + htim->State = HAL_TIM_STATE_BUSY; + } + } + else + { + /* nothing to do */ + } + + switch (Channel) + { + case TIM_CHANNEL_1: + { + /* Set the DMA capture callbacks */ + htim->hdma[TIM_DMA_ID_CC1]->XferCpltCallback = TIM_DMACaptureCplt; + htim->hdma[TIM_DMA_ID_CC1]->XferHalfCpltCallback = TIM_DMACaptureHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC1]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA channel */ + if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC1], (uint32_t)&htim->Instance->CCR1, (uint32_t)pData1, Length) != HAL_OK) + { + return HAL_ERROR; + } + /* Enable the TIM Input Capture DMA request */ + __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC1); + + /* Enable the Peripheral */ + __HAL_TIM_ENABLE(htim); + + /* Enable the Capture compare channel */ + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_ENABLE); + break; + } + + case TIM_CHANNEL_2: + { + /* Set the DMA capture callbacks */ + htim->hdma[TIM_DMA_ID_CC2]->XferCpltCallback = TIM_DMACaptureCplt; + htim->hdma[TIM_DMA_ID_CC2]->XferHalfCpltCallback = TIM_DMACaptureHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC2]->XferErrorCallback = TIM_DMAError; + /* Enable the DMA channel */ + if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC2], (uint32_t)&htim->Instance->CCR2, (uint32_t)pData2, Length) != HAL_OK) + { + return HAL_ERROR; + } + /* Enable the TIM Input Capture DMA request */ + __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC2); + + /* Enable the Peripheral */ + __HAL_TIM_ENABLE(htim); + + /* Enable the Capture compare channel */ + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_ENABLE); + break; + } + + case TIM_CHANNEL_ALL: + { + /* Set the DMA capture callbacks */ + htim->hdma[TIM_DMA_ID_CC1]->XferCpltCallback = TIM_DMACaptureCplt; + htim->hdma[TIM_DMA_ID_CC1]->XferHalfCpltCallback = TIM_DMACaptureHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC1]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA channel */ + if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC1], (uint32_t)&htim->Instance->CCR1, (uint32_t)pData1, Length) != HAL_OK) + { + return HAL_ERROR; + } + + /* Set the DMA capture callbacks */ + htim->hdma[TIM_DMA_ID_CC2]->XferCpltCallback = TIM_DMACaptureCplt; + htim->hdma[TIM_DMA_ID_CC2]->XferHalfCpltCallback = TIM_DMACaptureHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC2]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA channel */ + if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC2], (uint32_t)&htim->Instance->CCR2, (uint32_t)pData2, Length) != HAL_OK) + { + return HAL_ERROR; + } + /* Enable the Peripheral */ + __HAL_TIM_ENABLE(htim); + + /* Enable the Capture compare channel */ + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_ENABLE); + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_ENABLE); + + /* Enable the TIM Input Capture DMA request */ + __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC1); + /* Enable the TIM Input Capture DMA request */ + __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC2); + break; + } + + default: + break; + } + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stops the TIM Encoder Interface in DMA mode. + * @param htim TIM Encoder Interface handle + * @param Channel TIM Channels to be enabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_ALL: TIM Channel 1 and TIM Channel 2 are selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_Encoder_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + /* Check the parameters */ + assert_param(IS_TIM_DMA_CC_INSTANCE(htim->Instance)); + + /* Disable the Input Capture channels 1 and 2 + (in the EncoderInterface the two possible channels that can be used are TIM_CHANNEL_1 and TIM_CHANNEL_2) */ + if (Channel == TIM_CHANNEL_1) + { + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_DISABLE); + + /* Disable the capture compare DMA Request 1 */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC1); + (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC1]); + } + else if (Channel == TIM_CHANNEL_2) + { + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_DISABLE); + + /* Disable the capture compare DMA Request 2 */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC2); + (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC2]); + } + else + { + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_DISABLE); + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_DISABLE); + + /* Disable the capture compare DMA Request 1 and 2 */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC1); + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC2); + (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC1]); + (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC2]); + } + + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Change the htim state */ + htim->State = HAL_TIM_STATE_READY; + + /* Return function status */ + return HAL_OK; +} + +/** + * @} + */ +/** @defgroup TIM_Exported_Functions_Group7 TIM IRQ handler management + * @brief TIM IRQ handler management + * +@verbatim + ============================================================================== + ##### IRQ handler management ##### + ============================================================================== + [..] + This section provides Timer IRQ handler function. + +@endverbatim + * @{ + */ +/** + * @brief This function handles TIM interrupts requests. + * @param htim TIM handle + * @retval None + */ +void HAL_TIM_IRQHandler(TIM_HandleTypeDef *htim) +{ + /* Capture compare 1 event */ + if (__HAL_TIM_GET_FLAG(htim, TIM_FLAG_CC1) != RESET) + { + if (__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_CC1) != RESET) + { + { + __HAL_TIM_CLEAR_IT(htim, TIM_IT_CC1); + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_1; + + /* Input capture event */ + if ((htim->Instance->CCMR1 & TIM_CCMR1_CC1S) != 0x00U) + { +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + htim->IC_CaptureCallback(htim); +#else + HAL_TIM_IC_CaptureCallback(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + } + /* Output compare event */ + else + { +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + htim->OC_DelayElapsedCallback(htim); + htim->PWM_PulseFinishedCallback(htim); +#else + HAL_TIM_OC_DelayElapsedCallback(htim); + HAL_TIM_PWM_PulseFinishedCallback(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + } + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED; + } + } + } + /* Capture compare 2 event */ + if (__HAL_TIM_GET_FLAG(htim, TIM_FLAG_CC2) != RESET) + { + if (__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_CC2) != RESET) + { + __HAL_TIM_CLEAR_IT(htim, TIM_IT_CC2); + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_2; + /* Input capture event */ + if ((htim->Instance->CCMR1 & TIM_CCMR1_CC2S) != 0x00U) + { +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + htim->IC_CaptureCallback(htim); +#else + HAL_TIM_IC_CaptureCallback(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + } + /* Output compare event */ + else + { +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + htim->OC_DelayElapsedCallback(htim); + htim->PWM_PulseFinishedCallback(htim); +#else + HAL_TIM_OC_DelayElapsedCallback(htim); + HAL_TIM_PWM_PulseFinishedCallback(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + } + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED; + } + } + /* Capture compare 3 event */ + if (__HAL_TIM_GET_FLAG(htim, TIM_FLAG_CC3) != RESET) + { + if (__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_CC3) != RESET) + { + __HAL_TIM_CLEAR_IT(htim, TIM_IT_CC3); + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_3; + /* Input capture event */ + if ((htim->Instance->CCMR2 & TIM_CCMR2_CC3S) != 0x00U) + { +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + htim->IC_CaptureCallback(htim); +#else + HAL_TIM_IC_CaptureCallback(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + } + /* Output compare event */ + else + { +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + htim->OC_DelayElapsedCallback(htim); + htim->PWM_PulseFinishedCallback(htim); +#else + HAL_TIM_OC_DelayElapsedCallback(htim); + HAL_TIM_PWM_PulseFinishedCallback(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + } + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED; + } + } + /* Capture compare 4 event */ + if (__HAL_TIM_GET_FLAG(htim, TIM_FLAG_CC4) != RESET) + { + if (__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_CC4) != RESET) + { + __HAL_TIM_CLEAR_IT(htim, TIM_IT_CC4); + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_4; + /* Input capture event */ + if ((htim->Instance->CCMR2 & TIM_CCMR2_CC4S) != 0x00U) + { +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + htim->IC_CaptureCallback(htim); +#else + HAL_TIM_IC_CaptureCallback(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + } + /* Output compare event */ + else + { +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + htim->OC_DelayElapsedCallback(htim); + htim->PWM_PulseFinishedCallback(htim); +#else + HAL_TIM_OC_DelayElapsedCallback(htim); + HAL_TIM_PWM_PulseFinishedCallback(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + } + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED; + } + } + /* TIM Update event */ + if (__HAL_TIM_GET_FLAG(htim, TIM_FLAG_UPDATE) != RESET) + { + if (__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_UPDATE) != RESET) + { + __HAL_TIM_CLEAR_IT(htim, TIM_IT_UPDATE); +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + htim->PeriodElapsedCallback(htim); +#else + HAL_TIM_PeriodElapsedCallback(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + } + } + /* TIM Break input event */ + if (__HAL_TIM_GET_FLAG(htim, TIM_FLAG_BREAK) != RESET) + { + if (__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_BREAK) != RESET) + { + __HAL_TIM_CLEAR_IT(htim, TIM_IT_BREAK); +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + htim->BreakCallback(htim); +#else + HAL_TIMEx_BreakCallback(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + } + } + /* TIM Trigger detection event */ + if (__HAL_TIM_GET_FLAG(htim, TIM_FLAG_TRIGGER) != RESET) + { + if (__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_TRIGGER) != RESET) + { + __HAL_TIM_CLEAR_IT(htim, TIM_IT_TRIGGER); +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + htim->TriggerCallback(htim); +#else + HAL_TIM_TriggerCallback(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + } + } + /* TIM commutation event */ + if (__HAL_TIM_GET_FLAG(htim, TIM_FLAG_COM) != RESET) + { + if (__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_COM) != RESET) + { + __HAL_TIM_CLEAR_IT(htim, TIM_FLAG_COM); +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + htim->CommutationCallback(htim); +#else + HAL_TIMEx_CommutCallback(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + } + } +} + +/** + * @} + */ + +/** @defgroup TIM_Exported_Functions_Group8 TIM Peripheral Control functions + * @brief TIM Peripheral Control functions + * +@verbatim + ============================================================================== + ##### Peripheral Control functions ##### + ============================================================================== + [..] + This section provides functions allowing to: + (+) Configure The Input Output channels for OC, PWM, IC or One Pulse mode. + (+) Configure External Clock source. + (+) Configure Complementary channels, break features and dead time. + (+) Configure Master and the Slave synchronization. + (+) Configure the DMA Burst Mode. + +@endverbatim + * @{ + */ + +/** + * @brief Initializes the TIM Output Compare Channels according to the specified + * parameters in the TIM_OC_InitTypeDef. + * @param htim TIM Output Compare handle + * @param sConfig TIM Output Compare configuration structure + * @param Channel TIM Channels to configure + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_OC_ConfigChannel(TIM_HandleTypeDef *htim, + TIM_OC_InitTypeDef *sConfig, + uint32_t Channel) +{ + /* Check the parameters */ + assert_param(IS_TIM_CHANNELS(Channel)); + assert_param(IS_TIM_OC_MODE(sConfig->OCMode)); + assert_param(IS_TIM_OC_POLARITY(sConfig->OCPolarity)); + + /* Process Locked */ + __HAL_LOCK(htim); + + htim->State = HAL_TIM_STATE_BUSY; + + switch (Channel) + { + case TIM_CHANNEL_1: + { + /* Check the parameters */ + assert_param(IS_TIM_CC1_INSTANCE(htim->Instance)); + + /* Configure the TIM Channel 1 in Output Compare */ + TIM_OC1_SetConfig(htim->Instance, sConfig); + break; + } + + case TIM_CHANNEL_2: + { + /* Check the parameters */ + assert_param(IS_TIM_CC2_INSTANCE(htim->Instance)); + + /* Configure the TIM Channel 2 in Output Compare */ + TIM_OC2_SetConfig(htim->Instance, sConfig); + break; + } + + case TIM_CHANNEL_3: + { + /* Check the parameters */ + assert_param(IS_TIM_CC3_INSTANCE(htim->Instance)); + + /* Configure the TIM Channel 3 in Output Compare */ + TIM_OC3_SetConfig(htim->Instance, sConfig); + break; + } + + case TIM_CHANNEL_4: + { + /* Check the parameters */ + assert_param(IS_TIM_CC4_INSTANCE(htim->Instance)); + + /* Configure the TIM Channel 4 in Output Compare */ + TIM_OC4_SetConfig(htim->Instance, sConfig); + break; + } + + default: + break; + } + + htim->State = HAL_TIM_STATE_READY; + + __HAL_UNLOCK(htim); + + return HAL_OK; +} + +/** + * @brief Initializes the TIM Input Capture Channels according to the specified + * parameters in the TIM_IC_InitTypeDef. + * @param htim TIM IC handle + * @param sConfig TIM Input Capture configuration structure + * @param Channel TIM Channel to configure + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_IC_ConfigChannel(TIM_HandleTypeDef *htim, TIM_IC_InitTypeDef *sConfig, uint32_t Channel) +{ + /* Check the parameters */ + assert_param(IS_TIM_CC1_INSTANCE(htim->Instance)); + assert_param(IS_TIM_IC_POLARITY(sConfig->ICPolarity)); + assert_param(IS_TIM_IC_SELECTION(sConfig->ICSelection)); + assert_param(IS_TIM_IC_PRESCALER(sConfig->ICPrescaler)); + assert_param(IS_TIM_IC_FILTER(sConfig->ICFilter)); + + /* Process Locked */ + __HAL_LOCK(htim); + + htim->State = HAL_TIM_STATE_BUSY; + + if (Channel == TIM_CHANNEL_1) + { + /* TI1 Configuration */ + TIM_TI1_SetConfig(htim->Instance, + sConfig->ICPolarity, + sConfig->ICSelection, + sConfig->ICFilter); + + /* Reset the IC1PSC Bits */ + htim->Instance->CCMR1 &= ~TIM_CCMR1_IC1PSC; + + /* Set the IC1PSC value */ + htim->Instance->CCMR1 |= sConfig->ICPrescaler; + } + else if (Channel == TIM_CHANNEL_2) + { + /* TI2 Configuration */ + assert_param(IS_TIM_CC2_INSTANCE(htim->Instance)); + + TIM_TI2_SetConfig(htim->Instance, + sConfig->ICPolarity, + sConfig->ICSelection, + sConfig->ICFilter); + + /* Reset the IC2PSC Bits */ + htim->Instance->CCMR1 &= ~TIM_CCMR1_IC2PSC; + + /* Set the IC2PSC value */ + htim->Instance->CCMR1 |= (sConfig->ICPrescaler << 8U); + } + else if (Channel == TIM_CHANNEL_3) + { + /* TI3 Configuration */ + assert_param(IS_TIM_CC3_INSTANCE(htim->Instance)); + + TIM_TI3_SetConfig(htim->Instance, + sConfig->ICPolarity, + sConfig->ICSelection, + sConfig->ICFilter); + + /* Reset the IC3PSC Bits */ + htim->Instance->CCMR2 &= ~TIM_CCMR2_IC3PSC; + + /* Set the IC3PSC value */ + htim->Instance->CCMR2 |= sConfig->ICPrescaler; + } + else + { + /* TI4 Configuration */ + assert_param(IS_TIM_CC4_INSTANCE(htim->Instance)); + + TIM_TI4_SetConfig(htim->Instance, + sConfig->ICPolarity, + sConfig->ICSelection, + sConfig->ICFilter); + + /* Reset the IC4PSC Bits */ + htim->Instance->CCMR2 &= ~TIM_CCMR2_IC4PSC; + + /* Set the IC4PSC value */ + htim->Instance->CCMR2 |= (sConfig->ICPrescaler << 8U); + } + + htim->State = HAL_TIM_STATE_READY; + + __HAL_UNLOCK(htim); + + return HAL_OK; +} + +/** + * @brief Initializes the TIM PWM channels according to the specified + * parameters in the TIM_OC_InitTypeDef. + * @param htim TIM PWM handle + * @param sConfig TIM PWM configuration structure + * @param Channel TIM Channels to be configured + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_PWM_ConfigChannel(TIM_HandleTypeDef *htim, + TIM_OC_InitTypeDef *sConfig, + uint32_t Channel) +{ + /* Check the parameters */ + assert_param(IS_TIM_CHANNELS(Channel)); + assert_param(IS_TIM_PWM_MODE(sConfig->OCMode)); + assert_param(IS_TIM_OC_POLARITY(sConfig->OCPolarity)); + assert_param(IS_TIM_FAST_STATE(sConfig->OCFastMode)); + + /* Process Locked */ + __HAL_LOCK(htim); + + htim->State = HAL_TIM_STATE_BUSY; + + switch (Channel) + { + case TIM_CHANNEL_1: + { + /* Check the parameters */ + assert_param(IS_TIM_CC1_INSTANCE(htim->Instance)); + + /* Configure the Channel 1 in PWM mode */ + TIM_OC1_SetConfig(htim->Instance, sConfig); + + /* Set the Preload enable bit for channel1 */ + htim->Instance->CCMR1 |= TIM_CCMR1_OC1PE; + + /* Configure the Output Fast mode */ + htim->Instance->CCMR1 &= ~TIM_CCMR1_OC1FE; + htim->Instance->CCMR1 |= sConfig->OCFastMode; + break; + } + + case TIM_CHANNEL_2: + { + /* Check the parameters */ + assert_param(IS_TIM_CC2_INSTANCE(htim->Instance)); + + /* Configure the Channel 2 in PWM mode */ + TIM_OC2_SetConfig(htim->Instance, sConfig); + + /* Set the Preload enable bit for channel2 */ + htim->Instance->CCMR1 |= TIM_CCMR1_OC2PE; + + /* Configure the Output Fast mode */ + htim->Instance->CCMR1 &= ~TIM_CCMR1_OC2FE; + htim->Instance->CCMR1 |= sConfig->OCFastMode << 8U; + break; + } + + case TIM_CHANNEL_3: + { + /* Check the parameters */ + assert_param(IS_TIM_CC3_INSTANCE(htim->Instance)); + + /* Configure the Channel 3 in PWM mode */ + TIM_OC3_SetConfig(htim->Instance, sConfig); + + /* Set the Preload enable bit for channel3 */ + htim->Instance->CCMR2 |= TIM_CCMR2_OC3PE; + + /* Configure the Output Fast mode */ + htim->Instance->CCMR2 &= ~TIM_CCMR2_OC3FE; + htim->Instance->CCMR2 |= sConfig->OCFastMode; + break; + } + + case TIM_CHANNEL_4: + { + /* Check the parameters */ + assert_param(IS_TIM_CC4_INSTANCE(htim->Instance)); + + /* Configure the Channel 4 in PWM mode */ + TIM_OC4_SetConfig(htim->Instance, sConfig); + + /* Set the Preload enable bit for channel4 */ + htim->Instance->CCMR2 |= TIM_CCMR2_OC4PE; + + /* Configure the Output Fast mode */ + htim->Instance->CCMR2 &= ~TIM_CCMR2_OC4FE; + htim->Instance->CCMR2 |= sConfig->OCFastMode << 8U; + break; + } + + default: + break; + } + + htim->State = HAL_TIM_STATE_READY; + + __HAL_UNLOCK(htim); + + return HAL_OK; +} + +/** + * @brief Initializes the TIM One Pulse Channels according to the specified + * parameters in the TIM_OnePulse_InitTypeDef. + * @param htim TIM One Pulse handle + * @param sConfig TIM One Pulse configuration structure + * @param OutputChannel TIM output channel to configure + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @param InputChannel TIM input Channel to configure + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @note To output a waveform with a minimum delay user can enable the fast + * mode by calling the @ref __HAL_TIM_ENABLE_OCxFAST macro. Then CCx + * output is forced in response to the edge detection on TIx input, + * without taking in account the comparison. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_OnePulse_ConfigChannel(TIM_HandleTypeDef *htim, TIM_OnePulse_InitTypeDef *sConfig, + uint32_t OutputChannel, uint32_t InputChannel) +{ + TIM_OC_InitTypeDef temp1; + + /* Check the parameters */ + assert_param(IS_TIM_OPM_CHANNELS(OutputChannel)); + assert_param(IS_TIM_OPM_CHANNELS(InputChannel)); + + if (OutputChannel != InputChannel) + { + /* Process Locked */ + __HAL_LOCK(htim); + + htim->State = HAL_TIM_STATE_BUSY; + + /* Extract the Output compare configuration from sConfig structure */ + temp1.OCMode = sConfig->OCMode; + temp1.Pulse = sConfig->Pulse; + temp1.OCPolarity = sConfig->OCPolarity; + temp1.OCNPolarity = sConfig->OCNPolarity; + temp1.OCIdleState = sConfig->OCIdleState; + temp1.OCNIdleState = sConfig->OCNIdleState; + + switch (OutputChannel) + { + case TIM_CHANNEL_1: + { + assert_param(IS_TIM_CC1_INSTANCE(htim->Instance)); + + TIM_OC1_SetConfig(htim->Instance, &temp1); + break; + } + case TIM_CHANNEL_2: + { + assert_param(IS_TIM_CC2_INSTANCE(htim->Instance)); + + TIM_OC2_SetConfig(htim->Instance, &temp1); + break; + } + default: + break; + } + + switch (InputChannel) + { + case TIM_CHANNEL_1: + { + assert_param(IS_TIM_CC1_INSTANCE(htim->Instance)); + + TIM_TI1_SetConfig(htim->Instance, sConfig->ICPolarity, + sConfig->ICSelection, sConfig->ICFilter); + + /* Reset the IC1PSC Bits */ + htim->Instance->CCMR1 &= ~TIM_CCMR1_IC1PSC; + + /* Select the Trigger source */ + htim->Instance->SMCR &= ~TIM_SMCR_TS; + htim->Instance->SMCR |= TIM_TS_TI1FP1; + + /* Select the Slave Mode */ + htim->Instance->SMCR &= ~TIM_SMCR_SMS; + htim->Instance->SMCR |= TIM_SLAVEMODE_TRIGGER; + break; + } + case TIM_CHANNEL_2: + { + assert_param(IS_TIM_CC2_INSTANCE(htim->Instance)); + + TIM_TI2_SetConfig(htim->Instance, sConfig->ICPolarity, + sConfig->ICSelection, sConfig->ICFilter); + + /* Reset the IC2PSC Bits */ + htim->Instance->CCMR1 &= ~TIM_CCMR1_IC2PSC; + + /* Select the Trigger source */ + htim->Instance->SMCR &= ~TIM_SMCR_TS; + htim->Instance->SMCR |= TIM_TS_TI2FP2; + + /* Select the Slave Mode */ + htim->Instance->SMCR &= ~TIM_SMCR_SMS; + htim->Instance->SMCR |= TIM_SLAVEMODE_TRIGGER; + break; + } + + default: + break; + } + + htim->State = HAL_TIM_STATE_READY; + + __HAL_UNLOCK(htim); + + return HAL_OK; + } + else + { + return HAL_ERROR; + } +} + +/** + * @brief Configure the DMA Burst to transfer Data from the memory to the TIM peripheral + * @param htim TIM handle + * @param BurstBaseAddress TIM Base address from where the DMA will start the Data write + * This parameter can be one of the following values: + * @arg TIM_DMABASE_CR1 + * @arg TIM_DMABASE_CR2 + * @arg TIM_DMABASE_SMCR + * @arg TIM_DMABASE_DIER + * @arg TIM_DMABASE_SR + * @arg TIM_DMABASE_EGR + * @arg TIM_DMABASE_CCMR1 + * @arg TIM_DMABASE_CCMR2 + * @arg TIM_DMABASE_CCER + * @arg TIM_DMABASE_CNT + * @arg TIM_DMABASE_PSC + * @arg TIM_DMABASE_ARR + * @arg TIM_DMABASE_RCR + * @arg TIM_DMABASE_CCR1 + * @arg TIM_DMABASE_CCR2 + * @arg TIM_DMABASE_CCR3 + * @arg TIM_DMABASE_CCR4 + * @arg TIM_DMABASE_BDTR + * @param BurstRequestSrc TIM DMA Request sources + * This parameter can be one of the following values: + * @arg TIM_DMA_UPDATE: TIM update Interrupt source + * @arg TIM_DMA_CC1: TIM Capture Compare 1 DMA source + * @arg TIM_DMA_CC2: TIM Capture Compare 2 DMA source + * @arg TIM_DMA_CC3: TIM Capture Compare 3 DMA source + * @arg TIM_DMA_CC4: TIM Capture Compare 4 DMA source + * @arg TIM_DMA_COM: TIM Commutation DMA source + * @arg TIM_DMA_TRIGGER: TIM Trigger DMA source + * @param BurstBuffer The Buffer address. + * @param BurstLength DMA Burst length. This parameter can be one value + * between: TIM_DMABURSTLENGTH_1TRANSFER and TIM_DMABURSTLENGTH_18TRANSFERS. + * @note This function should be used only when BurstLength is equal to DMA data transfer length. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_DMABurst_WriteStart(TIM_HandleTypeDef *htim, uint32_t BurstBaseAddress, + uint32_t BurstRequestSrc, uint32_t *BurstBuffer, uint32_t BurstLength) +{ + return HAL_TIM_DMABurst_MultiWriteStart(htim, BurstBaseAddress, BurstRequestSrc, BurstBuffer, BurstLength, + ((BurstLength) >> 8U) + 1U); +} + +/** + * @brief Configure the DMA Burst to transfer multiple Data from the memory to the TIM peripheral + * @param htim TIM handle + * @param BurstBaseAddress TIM Base address from where the DMA will start the Data write + * This parameter can be one of the following values: + * @arg TIM_DMABASE_CR1 + * @arg TIM_DMABASE_CR2 + * @arg TIM_DMABASE_SMCR + * @arg TIM_DMABASE_DIER + * @arg TIM_DMABASE_SR + * @arg TIM_DMABASE_EGR + * @arg TIM_DMABASE_CCMR1 + * @arg TIM_DMABASE_CCMR2 + * @arg TIM_DMABASE_CCER + * @arg TIM_DMABASE_CNT + * @arg TIM_DMABASE_PSC + * @arg TIM_DMABASE_ARR + * @arg TIM_DMABASE_RCR + * @arg TIM_DMABASE_CCR1 + * @arg TIM_DMABASE_CCR2 + * @arg TIM_DMABASE_CCR3 + * @arg TIM_DMABASE_CCR4 + * @arg TIM_DMABASE_BDTR + * @param BurstRequestSrc TIM DMA Request sources + * This parameter can be one of the following values: + * @arg TIM_DMA_UPDATE: TIM update Interrupt source + * @arg TIM_DMA_CC1: TIM Capture Compare 1 DMA source + * @arg TIM_DMA_CC2: TIM Capture Compare 2 DMA source + * @arg TIM_DMA_CC3: TIM Capture Compare 3 DMA source + * @arg TIM_DMA_CC4: TIM Capture Compare 4 DMA source + * @arg TIM_DMA_COM: TIM Commutation DMA source + * @arg TIM_DMA_TRIGGER: TIM Trigger DMA source + * @param BurstBuffer The Buffer address. + * @param BurstLength DMA Burst length. This parameter can be one value + * between: TIM_DMABURSTLENGTH_1TRANSFER and TIM_DMABURSTLENGTH_18TRANSFERS. + * @param DataLength Data length. This parameter can be one value + * between 1 and 0xFFFF. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_DMABurst_MultiWriteStart(TIM_HandleTypeDef *htim, uint32_t BurstBaseAddress, + uint32_t BurstRequestSrc, uint32_t *BurstBuffer, + uint32_t BurstLength, uint32_t DataLength) +{ + /* Check the parameters */ + assert_param(IS_TIM_DMABURST_INSTANCE(htim->Instance)); + assert_param(IS_TIM_DMA_BASE(BurstBaseAddress)); + assert_param(IS_TIM_DMA_SOURCE(BurstRequestSrc)); + assert_param(IS_TIM_DMA_LENGTH(BurstLength)); + assert_param(IS_TIM_DMA_DATA_LENGTH(DataLength)); + + if (htim->State == HAL_TIM_STATE_BUSY) + { + return HAL_BUSY; + } + else if (htim->State == HAL_TIM_STATE_READY) + { + if ((BurstBuffer == NULL) && (BurstLength > 0U)) + { + return HAL_ERROR; + } + else + { + htim->State = HAL_TIM_STATE_BUSY; + } + } + else + { + /* nothing to do */ + } + switch (BurstRequestSrc) + { + case TIM_DMA_UPDATE: + { + /* Set the DMA Period elapsed callbacks */ + htim->hdma[TIM_DMA_ID_UPDATE]->XferCpltCallback = TIM_DMAPeriodElapsedCplt; + htim->hdma[TIM_DMA_ID_UPDATE]->XferHalfCpltCallback = TIM_DMAPeriodElapsedHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_UPDATE]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA channel */ + if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_UPDATE], (uint32_t)BurstBuffer, + (uint32_t)&htim->Instance->DMAR, DataLength) != HAL_OK) + { + return HAL_ERROR; + } + break; + } + case TIM_DMA_CC1: + { + /* Set the DMA compare callbacks */ + htim->hdma[TIM_DMA_ID_CC1]->XferCpltCallback = TIM_DMADelayPulseCplt; + htim->hdma[TIM_DMA_ID_CC1]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC1]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA channel */ + if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC1], (uint32_t)BurstBuffer, + (uint32_t)&htim->Instance->DMAR, DataLength) != HAL_OK) + { + return HAL_ERROR; + } + break; + } + case TIM_DMA_CC2: + { + /* Set the DMA compare callbacks */ + htim->hdma[TIM_DMA_ID_CC2]->XferCpltCallback = TIM_DMADelayPulseCplt; + htim->hdma[TIM_DMA_ID_CC2]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC2]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA channel */ + if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC2], (uint32_t)BurstBuffer, + (uint32_t)&htim->Instance->DMAR, DataLength) != HAL_OK) + { + return HAL_ERROR; + } + break; + } + case TIM_DMA_CC3: + { + /* Set the DMA compare callbacks */ + htim->hdma[TIM_DMA_ID_CC3]->XferCpltCallback = TIM_DMADelayPulseCplt; + htim->hdma[TIM_DMA_ID_CC3]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC3]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA channel */ + if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC3], (uint32_t)BurstBuffer, + (uint32_t)&htim->Instance->DMAR, DataLength) != HAL_OK) + { + return HAL_ERROR; + } + break; + } + case TIM_DMA_CC4: + { + /* Set the DMA compare callbacks */ + htim->hdma[TIM_DMA_ID_CC4]->XferCpltCallback = TIM_DMADelayPulseCplt; + htim->hdma[TIM_DMA_ID_CC4]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC4]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA channel */ + if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC4], (uint32_t)BurstBuffer, + (uint32_t)&htim->Instance->DMAR, DataLength) != HAL_OK) + { + return HAL_ERROR; + } + break; + } + case TIM_DMA_COM: + { + /* Set the DMA commutation callbacks */ + htim->hdma[TIM_DMA_ID_COMMUTATION]->XferCpltCallback = TIMEx_DMACommutationCplt; + htim->hdma[TIM_DMA_ID_COMMUTATION]->XferHalfCpltCallback = TIMEx_DMACommutationHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_COMMUTATION]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA channel */ + if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_COMMUTATION], (uint32_t)BurstBuffer, + (uint32_t)&htim->Instance->DMAR, DataLength) != HAL_OK) + { + return HAL_ERROR; + } + break; + } + case TIM_DMA_TRIGGER: + { + /* Set the DMA trigger callbacks */ + htim->hdma[TIM_DMA_ID_TRIGGER]->XferCpltCallback = TIM_DMATriggerCplt; + htim->hdma[TIM_DMA_ID_TRIGGER]->XferHalfCpltCallback = TIM_DMATriggerHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_TRIGGER]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA channel */ + if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_TRIGGER], (uint32_t)BurstBuffer, + (uint32_t)&htim->Instance->DMAR, DataLength) != HAL_OK) + { + return HAL_ERROR; + } + break; + } + default: + break; + } + + /* Configure the DMA Burst Mode */ + htim->Instance->DCR = (BurstBaseAddress | BurstLength); + /* Enable the TIM DMA Request */ + __HAL_TIM_ENABLE_DMA(htim, BurstRequestSrc); + + htim->State = HAL_TIM_STATE_READY; + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stops the TIM DMA Burst mode + * @param htim TIM handle + * @param BurstRequestSrc TIM DMA Request sources to disable + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_DMABurst_WriteStop(TIM_HandleTypeDef *htim, uint32_t BurstRequestSrc) +{ + HAL_StatusTypeDef status = HAL_OK; + /* Check the parameters */ + assert_param(IS_TIM_DMA_SOURCE(BurstRequestSrc)); + + /* Abort the DMA transfer (at least disable the DMA channel) */ + switch (BurstRequestSrc) + { + case TIM_DMA_UPDATE: + { + status = HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_UPDATE]); + break; + } + case TIM_DMA_CC1: + { + status = HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC1]); + break; + } + case TIM_DMA_CC2: + { + status = HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC2]); + break; + } + case TIM_DMA_CC3: + { + status = HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC3]); + break; + } + case TIM_DMA_CC4: + { + status = HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC4]); + break; + } + case TIM_DMA_COM: + { + status = HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_COMMUTATION]); + break; + } + case TIM_DMA_TRIGGER: + { + status = HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_TRIGGER]); + break; + } + default: + break; + } + + if (HAL_OK == status) + { + /* Disable the TIM Update DMA request */ + __HAL_TIM_DISABLE_DMA(htim, BurstRequestSrc); + } + + /* Return function status */ + return status; +} + +/** + * @brief Configure the DMA Burst to transfer Data from the TIM peripheral to the memory + * @param htim TIM handle + * @param BurstBaseAddress TIM Base address from where the DMA will start the Data read + * This parameter can be one of the following values: + * @arg TIM_DMABASE_CR1 + * @arg TIM_DMABASE_CR2 + * @arg TIM_DMABASE_SMCR + * @arg TIM_DMABASE_DIER + * @arg TIM_DMABASE_SR + * @arg TIM_DMABASE_EGR + * @arg TIM_DMABASE_CCMR1 + * @arg TIM_DMABASE_CCMR2 + * @arg TIM_DMABASE_CCER + * @arg TIM_DMABASE_CNT + * @arg TIM_DMABASE_PSC + * @arg TIM_DMABASE_ARR + * @arg TIM_DMABASE_RCR + * @arg TIM_DMABASE_CCR1 + * @arg TIM_DMABASE_CCR2 + * @arg TIM_DMABASE_CCR3 + * @arg TIM_DMABASE_CCR4 + * @arg TIM_DMABASE_BDTR + * @param BurstRequestSrc TIM DMA Request sources + * This parameter can be one of the following values: + * @arg TIM_DMA_UPDATE: TIM update Interrupt source + * @arg TIM_DMA_CC1: TIM Capture Compare 1 DMA source + * @arg TIM_DMA_CC2: TIM Capture Compare 2 DMA source + * @arg TIM_DMA_CC3: TIM Capture Compare 3 DMA source + * @arg TIM_DMA_CC4: TIM Capture Compare 4 DMA source + * @arg TIM_DMA_COM: TIM Commutation DMA source + * @arg TIM_DMA_TRIGGER: TIM Trigger DMA source + * @param BurstBuffer The Buffer address. + * @param BurstLength DMA Burst length. This parameter can be one value + * between: TIM_DMABURSTLENGTH_1TRANSFER and TIM_DMABURSTLENGTH_18TRANSFERS. + * @note This function should be used only when BurstLength is equal to DMA data transfer length. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_DMABurst_ReadStart(TIM_HandleTypeDef *htim, uint32_t BurstBaseAddress, + uint32_t BurstRequestSrc, uint32_t *BurstBuffer, uint32_t BurstLength) +{ + return HAL_TIM_DMABurst_MultiReadStart(htim, BurstBaseAddress, BurstRequestSrc, BurstBuffer, BurstLength, + ((BurstLength) >> 8U) + 1U); +} + +/** + * @brief Configure the DMA Burst to transfer Data from the TIM peripheral to the memory + * @param htim TIM handle + * @param BurstBaseAddress TIM Base address from where the DMA will start the Data read + * This parameter can be one of the following values: + * @arg TIM_DMABASE_CR1 + * @arg TIM_DMABASE_CR2 + * @arg TIM_DMABASE_SMCR + * @arg TIM_DMABASE_DIER + * @arg TIM_DMABASE_SR + * @arg TIM_DMABASE_EGR + * @arg TIM_DMABASE_CCMR1 + * @arg TIM_DMABASE_CCMR2 + * @arg TIM_DMABASE_CCER + * @arg TIM_DMABASE_CNT + * @arg TIM_DMABASE_PSC + * @arg TIM_DMABASE_ARR + * @arg TIM_DMABASE_RCR + * @arg TIM_DMABASE_CCR1 + * @arg TIM_DMABASE_CCR2 + * @arg TIM_DMABASE_CCR3 + * @arg TIM_DMABASE_CCR4 + * @arg TIM_DMABASE_BDTR + * @param BurstRequestSrc TIM DMA Request sources + * This parameter can be one of the following values: + * @arg TIM_DMA_UPDATE: TIM update Interrupt source + * @arg TIM_DMA_CC1: TIM Capture Compare 1 DMA source + * @arg TIM_DMA_CC2: TIM Capture Compare 2 DMA source + * @arg TIM_DMA_CC3: TIM Capture Compare 3 DMA source + * @arg TIM_DMA_CC4: TIM Capture Compare 4 DMA source + * @arg TIM_DMA_COM: TIM Commutation DMA source + * @arg TIM_DMA_TRIGGER: TIM Trigger DMA source + * @param BurstBuffer The Buffer address. + * @param BurstLength DMA Burst length. This parameter can be one value + * between: TIM_DMABURSTLENGTH_1TRANSFER and TIM_DMABURSTLENGTH_18TRANSFERS. + * @param DataLength Data length. This parameter can be one value + * between 1 and 0xFFFF. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_DMABurst_MultiReadStart(TIM_HandleTypeDef *htim, uint32_t BurstBaseAddress, + uint32_t BurstRequestSrc, uint32_t *BurstBuffer, + uint32_t BurstLength, uint32_t DataLength) +{ + /* Check the parameters */ + assert_param(IS_TIM_DMABURST_INSTANCE(htim->Instance)); + assert_param(IS_TIM_DMA_BASE(BurstBaseAddress)); + assert_param(IS_TIM_DMA_SOURCE(BurstRequestSrc)); + assert_param(IS_TIM_DMA_LENGTH(BurstLength)); + assert_param(IS_TIM_DMA_DATA_LENGTH(DataLength)); + + if (htim->State == HAL_TIM_STATE_BUSY) + { + return HAL_BUSY; + } + else if (htim->State == HAL_TIM_STATE_READY) + { + if ((BurstBuffer == NULL) && (BurstLength > 0U)) + { + return HAL_ERROR; + } + else + { + htim->State = HAL_TIM_STATE_BUSY; + } + } + else + { + /* nothing to do */ + } + switch (BurstRequestSrc) + { + case TIM_DMA_UPDATE: + { + /* Set the DMA Period elapsed callbacks */ + htim->hdma[TIM_DMA_ID_UPDATE]->XferCpltCallback = TIM_DMAPeriodElapsedCplt; + htim->hdma[TIM_DMA_ID_UPDATE]->XferHalfCpltCallback = TIM_DMAPeriodElapsedHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_UPDATE]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA channel */ + if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_UPDATE], (uint32_t)&htim->Instance->DMAR, (uint32_t)BurstBuffer, + DataLength) != HAL_OK) + { + return HAL_ERROR; + } + break; + } + case TIM_DMA_CC1: + { + /* Set the DMA capture callbacks */ + htim->hdma[TIM_DMA_ID_CC1]->XferCpltCallback = TIM_DMACaptureCplt; + htim->hdma[TIM_DMA_ID_CC1]->XferHalfCpltCallback = TIM_DMACaptureHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC1]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA channel */ + if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC1], (uint32_t)&htim->Instance->DMAR, (uint32_t)BurstBuffer, + DataLength) != HAL_OK) + { + return HAL_ERROR; + } + break; + } + case TIM_DMA_CC2: + { + /* Set the DMA capture callbacks */ + htim->hdma[TIM_DMA_ID_CC2]->XferCpltCallback = TIM_DMACaptureCplt; + htim->hdma[TIM_DMA_ID_CC2]->XferHalfCpltCallback = TIM_DMACaptureHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC2]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA channel */ + if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC2], (uint32_t)&htim->Instance->DMAR, (uint32_t)BurstBuffer, + DataLength) != HAL_OK) + { + return HAL_ERROR; + } + break; + } + case TIM_DMA_CC3: + { + /* Set the DMA capture callbacks */ + htim->hdma[TIM_DMA_ID_CC3]->XferCpltCallback = TIM_DMACaptureCplt; + htim->hdma[TIM_DMA_ID_CC3]->XferHalfCpltCallback = TIM_DMACaptureHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC3]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA channel */ + if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC3], (uint32_t)&htim->Instance->DMAR, (uint32_t)BurstBuffer, + DataLength) != HAL_OK) + { + return HAL_ERROR; + } + break; + } + case TIM_DMA_CC4: + { + /* Set the DMA capture callbacks */ + htim->hdma[TIM_DMA_ID_CC4]->XferCpltCallback = TIM_DMACaptureCplt; + htim->hdma[TIM_DMA_ID_CC4]->XferHalfCpltCallback = TIM_DMACaptureHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC4]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA channel */ + if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC4], (uint32_t)&htim->Instance->DMAR, (uint32_t)BurstBuffer, + DataLength) != HAL_OK) + { + return HAL_ERROR; + } + break; + } + case TIM_DMA_COM: + { + /* Set the DMA commutation callbacks */ + htim->hdma[TIM_DMA_ID_COMMUTATION]->XferCpltCallback = TIMEx_DMACommutationCplt; + htim->hdma[TIM_DMA_ID_COMMUTATION]->XferHalfCpltCallback = TIMEx_DMACommutationHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_COMMUTATION]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA channel */ + if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_COMMUTATION], (uint32_t)&htim->Instance->DMAR, (uint32_t)BurstBuffer, + DataLength) != HAL_OK) + { + return HAL_ERROR; + } + break; + } + case TIM_DMA_TRIGGER: + { + /* Set the DMA trigger callbacks */ + htim->hdma[TIM_DMA_ID_TRIGGER]->XferCpltCallback = TIM_DMATriggerCplt; + htim->hdma[TIM_DMA_ID_TRIGGER]->XferHalfCpltCallback = TIM_DMATriggerHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_TRIGGER]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA channel */ + if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_TRIGGER], (uint32_t)&htim->Instance->DMAR, (uint32_t)BurstBuffer, + DataLength) != HAL_OK) + { + return HAL_ERROR; + } + break; + } + default: + break; + } + + /* Configure the DMA Burst Mode */ + htim->Instance->DCR = (BurstBaseAddress | BurstLength); + + /* Enable the TIM DMA Request */ + __HAL_TIM_ENABLE_DMA(htim, BurstRequestSrc); + + htim->State = HAL_TIM_STATE_READY; + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stop the DMA burst reading + * @param htim TIM handle + * @param BurstRequestSrc TIM DMA Request sources to disable. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_DMABurst_ReadStop(TIM_HandleTypeDef *htim, uint32_t BurstRequestSrc) +{ + HAL_StatusTypeDef status = HAL_OK; + /* Check the parameters */ + assert_param(IS_TIM_DMA_SOURCE(BurstRequestSrc)); + + /* Abort the DMA transfer (at least disable the DMA channel) */ + switch (BurstRequestSrc) + { + case TIM_DMA_UPDATE: + { + status = HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_UPDATE]); + break; + } + case TIM_DMA_CC1: + { + status = HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC1]); + break; + } + case TIM_DMA_CC2: + { + status = HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC2]); + break; + } + case TIM_DMA_CC3: + { + status = HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC3]); + break; + } + case TIM_DMA_CC4: + { + status = HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC4]); + break; + } + case TIM_DMA_COM: + { + status = HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_COMMUTATION]); + break; + } + case TIM_DMA_TRIGGER: + { + status = HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_TRIGGER]); + break; + } + default: + break; + } + + if (HAL_OK == status) + { + /* Disable the TIM Update DMA request */ + __HAL_TIM_DISABLE_DMA(htim, BurstRequestSrc); + } + + /* Return function status */ + return status; +} + +/** + * @brief Generate a software event + * @param htim TIM handle + * @param EventSource specifies the event source. + * This parameter can be one of the following values: + * @arg TIM_EVENTSOURCE_UPDATE: Timer update Event source + * @arg TIM_EVENTSOURCE_CC1: Timer Capture Compare 1 Event source + * @arg TIM_EVENTSOURCE_CC2: Timer Capture Compare 2 Event source + * @arg TIM_EVENTSOURCE_CC3: Timer Capture Compare 3 Event source + * @arg TIM_EVENTSOURCE_CC4: Timer Capture Compare 4 Event source + * @arg TIM_EVENTSOURCE_COM: Timer COM event source + * @arg TIM_EVENTSOURCE_TRIGGER: Timer Trigger Event source + * @arg TIM_EVENTSOURCE_BREAK: Timer Break event source + * @note Basic timers can only generate an update event. + * @note TIM_EVENTSOURCE_COM is relevant only with advanced timer instances. + * @note TIM_EVENTSOURCE_BREAK are relevant only for timer instances + * supporting a break input. + * @retval HAL status + */ + +HAL_StatusTypeDef HAL_TIM_GenerateEvent(TIM_HandleTypeDef *htim, uint32_t EventSource) +{ + /* Check the parameters */ + assert_param(IS_TIM_INSTANCE(htim->Instance)); + assert_param(IS_TIM_EVENT_SOURCE(EventSource)); + + /* Process Locked */ + __HAL_LOCK(htim); + + /* Change the TIM state */ + htim->State = HAL_TIM_STATE_BUSY; + + /* Set the event sources */ + htim->Instance->EGR = EventSource; + + /* Change the TIM state */ + htim->State = HAL_TIM_STATE_READY; + + __HAL_UNLOCK(htim); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Configures the OCRef clear feature + * @param htim TIM handle + * @param sClearInputConfig pointer to a TIM_ClearInputConfigTypeDef structure that + * contains the OCREF clear feature and parameters for the TIM peripheral. + * @param Channel specifies the TIM Channel + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 + * @arg TIM_CHANNEL_2: TIM Channel 2 + * @arg TIM_CHANNEL_3: TIM Channel 3 + * @arg TIM_CHANNEL_4: TIM Channel 4 + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_ConfigOCrefClear(TIM_HandleTypeDef *htim, + TIM_ClearInputConfigTypeDef *sClearInputConfig, + uint32_t Channel) +{ + /* Check the parameters */ + assert_param(IS_TIM_OCXREF_CLEAR_INSTANCE(htim->Instance)); + assert_param(IS_TIM_CLEARINPUT_SOURCE(sClearInputConfig->ClearInputSource)); + + /* Process Locked */ + __HAL_LOCK(htim); + + htim->State = HAL_TIM_STATE_BUSY; + + switch (sClearInputConfig->ClearInputSource) + { + case TIM_CLEARINPUTSOURCE_NONE: + { + /* Clear the OCREF clear selection bit and the the ETR Bits */ + CLEAR_BIT(htim->Instance->SMCR, (TIM_SMCR_OCCS | TIM_SMCR_ETF | TIM_SMCR_ETPS | TIM_SMCR_ECE | TIM_SMCR_ETP)); + break; + } + case TIM_CLEARINPUTSOURCE_OCREFCLR: + { + /* Clear the OCREF clear selection bit */ + CLEAR_BIT(htim->Instance->SMCR, TIM_SMCR_OCCS); + } + break; + + case TIM_CLEARINPUTSOURCE_ETR: + { + /* Check the parameters */ + assert_param(IS_TIM_CLEARINPUT_POLARITY(sClearInputConfig->ClearInputPolarity)); + assert_param(IS_TIM_CLEARINPUT_PRESCALER(sClearInputConfig->ClearInputPrescaler)); + assert_param(IS_TIM_CLEARINPUT_FILTER(sClearInputConfig->ClearInputFilter)); + + /* When OCRef clear feature is used with ETR source, ETR prescaler must be off */ + if (sClearInputConfig->ClearInputPrescaler != TIM_CLEARINPUTPRESCALER_DIV1) + { + htim->State = HAL_TIM_STATE_READY; + __HAL_UNLOCK(htim); + return HAL_ERROR; + } + + TIM_ETR_SetConfig(htim->Instance, + sClearInputConfig->ClearInputPrescaler, + sClearInputConfig->ClearInputPolarity, + sClearInputConfig->ClearInputFilter); + + /* Set the OCREF clear selection bit */ + SET_BIT(htim->Instance->SMCR, TIM_SMCR_OCCS); + break; + } + + default: + break; + } + + switch (Channel) + { + case TIM_CHANNEL_1: + { + if (sClearInputConfig->ClearInputState != (uint32_t)DISABLE) + { + /* Enable the OCREF clear feature for Channel 1 */ + SET_BIT(htim->Instance->CCMR1, TIM_CCMR1_OC1CE); + } + else + { + /* Disable the OCREF clear feature for Channel 1 */ + CLEAR_BIT(htim->Instance->CCMR1, TIM_CCMR1_OC1CE); + } + break; + } + case TIM_CHANNEL_2: + { + if (sClearInputConfig->ClearInputState != (uint32_t)DISABLE) + { + /* Enable the OCREF clear feature for Channel 2 */ + SET_BIT(htim->Instance->CCMR1, TIM_CCMR1_OC2CE); + } + else + { + /* Disable the OCREF clear feature for Channel 2 */ + CLEAR_BIT(htim->Instance->CCMR1, TIM_CCMR1_OC2CE); + } + break; + } + case TIM_CHANNEL_3: + { + if (sClearInputConfig->ClearInputState != (uint32_t)DISABLE) + { + /* Enable the OCREF clear feature for Channel 3 */ + SET_BIT(htim->Instance->CCMR2, TIM_CCMR2_OC3CE); + } + else + { + /* Disable the OCREF clear feature for Channel 3 */ + CLEAR_BIT(htim->Instance->CCMR2, TIM_CCMR2_OC3CE); + } + break; + } + case TIM_CHANNEL_4: + { + if (sClearInputConfig->ClearInputState != (uint32_t)DISABLE) + { + /* Enable the OCREF clear feature for Channel 4 */ + SET_BIT(htim->Instance->CCMR2, TIM_CCMR2_OC4CE); + } + else + { + /* Disable the OCREF clear feature for Channel 4 */ + CLEAR_BIT(htim->Instance->CCMR2, TIM_CCMR2_OC4CE); + } + break; + } + default: + break; + } + + htim->State = HAL_TIM_STATE_READY; + + __HAL_UNLOCK(htim); + + return HAL_OK; +} + +/** + * @brief Configures the clock source to be used + * @param htim TIM handle + * @param sClockSourceConfig pointer to a TIM_ClockConfigTypeDef structure that + * contains the clock source information for the TIM peripheral. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_ConfigClockSource(TIM_HandleTypeDef *htim, TIM_ClockConfigTypeDef *sClockSourceConfig) +{ + uint32_t tmpsmcr; + + /* Process Locked */ + __HAL_LOCK(htim); + + htim->State = HAL_TIM_STATE_BUSY; + + /* Check the parameters */ + assert_param(IS_TIM_CLOCKSOURCE(sClockSourceConfig->ClockSource)); + + /* Reset the SMS, TS, ECE, ETPS and ETRF bits */ + tmpsmcr = htim->Instance->SMCR; + tmpsmcr &= ~(TIM_SMCR_SMS | TIM_SMCR_TS); + tmpsmcr &= ~(TIM_SMCR_ETF | TIM_SMCR_ETPS | TIM_SMCR_ECE | TIM_SMCR_ETP); + htim->Instance->SMCR = tmpsmcr; + + switch (sClockSourceConfig->ClockSource) + { + case TIM_CLOCKSOURCE_INTERNAL: + { + assert_param(IS_TIM_INSTANCE(htim->Instance)); + break; + } + + case TIM_CLOCKSOURCE_ETRMODE1: + { + /* Check whether or not the timer instance supports external trigger input mode 1 (ETRF)*/ + assert_param(IS_TIM_CLOCKSOURCE_ETRMODE1_INSTANCE(htim->Instance)); + + /* Check ETR input conditioning related parameters */ + assert_param(IS_TIM_CLOCKPRESCALER(sClockSourceConfig->ClockPrescaler)); + assert_param(IS_TIM_CLOCKPOLARITY(sClockSourceConfig->ClockPolarity)); + assert_param(IS_TIM_CLOCKFILTER(sClockSourceConfig->ClockFilter)); + + /* Configure the ETR Clock source */ + TIM_ETR_SetConfig(htim->Instance, + sClockSourceConfig->ClockPrescaler, + sClockSourceConfig->ClockPolarity, + sClockSourceConfig->ClockFilter); + + /* Select the External clock mode1 and the ETRF trigger */ + tmpsmcr = htim->Instance->SMCR; + tmpsmcr |= (TIM_SLAVEMODE_EXTERNAL1 | TIM_CLOCKSOURCE_ETRMODE1); + /* Write to TIMx SMCR */ + htim->Instance->SMCR = tmpsmcr; + break; + } + + case TIM_CLOCKSOURCE_ETRMODE2: + { + /* Check whether or not the timer instance supports external trigger input mode 2 (ETRF)*/ + assert_param(IS_TIM_CLOCKSOURCE_ETRMODE2_INSTANCE(htim->Instance)); + + /* Check ETR input conditioning related parameters */ + assert_param(IS_TIM_CLOCKPRESCALER(sClockSourceConfig->ClockPrescaler)); + assert_param(IS_TIM_CLOCKPOLARITY(sClockSourceConfig->ClockPolarity)); + assert_param(IS_TIM_CLOCKFILTER(sClockSourceConfig->ClockFilter)); + + /* Configure the ETR Clock source */ + TIM_ETR_SetConfig(htim->Instance, + sClockSourceConfig->ClockPrescaler, + sClockSourceConfig->ClockPolarity, + sClockSourceConfig->ClockFilter); + /* Enable the External clock mode2 */ + htim->Instance->SMCR |= TIM_SMCR_ECE; + break; + } + + case TIM_CLOCKSOURCE_TI1: + { + /* Check whether or not the timer instance supports external clock mode 1 */ + assert_param(IS_TIM_CLOCKSOURCE_TIX_INSTANCE(htim->Instance)); + + /* Check TI1 input conditioning related parameters */ + assert_param(IS_TIM_CLOCKPOLARITY(sClockSourceConfig->ClockPolarity)); + assert_param(IS_TIM_CLOCKFILTER(sClockSourceConfig->ClockFilter)); + + TIM_TI1_ConfigInputStage(htim->Instance, + sClockSourceConfig->ClockPolarity, + sClockSourceConfig->ClockFilter); + TIM_ITRx_SetConfig(htim->Instance, TIM_CLOCKSOURCE_TI1); + break; + } + + case TIM_CLOCKSOURCE_TI2: + { + /* Check whether or not the timer instance supports external clock mode 1 (ETRF)*/ + assert_param(IS_TIM_CLOCKSOURCE_TIX_INSTANCE(htim->Instance)); + + /* Check TI2 input conditioning related parameters */ + assert_param(IS_TIM_CLOCKPOLARITY(sClockSourceConfig->ClockPolarity)); + assert_param(IS_TIM_CLOCKFILTER(sClockSourceConfig->ClockFilter)); + + TIM_TI2_ConfigInputStage(htim->Instance, + sClockSourceConfig->ClockPolarity, + sClockSourceConfig->ClockFilter); + TIM_ITRx_SetConfig(htim->Instance, TIM_CLOCKSOURCE_TI2); + break; + } + + case TIM_CLOCKSOURCE_TI1ED: + { + /* Check whether or not the timer instance supports external clock mode 1 */ + assert_param(IS_TIM_CLOCKSOURCE_TIX_INSTANCE(htim->Instance)); + + /* Check TI1 input conditioning related parameters */ + assert_param(IS_TIM_CLOCKPOLARITY(sClockSourceConfig->ClockPolarity)); + assert_param(IS_TIM_CLOCKFILTER(sClockSourceConfig->ClockFilter)); + + TIM_TI1_ConfigInputStage(htim->Instance, + sClockSourceConfig->ClockPolarity, + sClockSourceConfig->ClockFilter); + TIM_ITRx_SetConfig(htim->Instance, TIM_CLOCKSOURCE_TI1ED); + break; + } + + case TIM_CLOCKSOURCE_ITR0: + case TIM_CLOCKSOURCE_ITR1: + case TIM_CLOCKSOURCE_ITR2: + case TIM_CLOCKSOURCE_ITR3: + { + /* Check whether or not the timer instance supports internal trigger input */ + assert_param(IS_TIM_CLOCKSOURCE_ITRX_INSTANCE(htim->Instance)); + + TIM_ITRx_SetConfig(htim->Instance, sClockSourceConfig->ClockSource); + break; + } + + default: + break; + } + htim->State = HAL_TIM_STATE_READY; + + __HAL_UNLOCK(htim); + + return HAL_OK; +} + +/** + * @brief Selects the signal connected to the TI1 input: direct from CH1_input + * or a XOR combination between CH1_input, CH2_input & CH3_input + * @param htim TIM handle. + * @param TI1_Selection Indicate whether or not channel 1 is connected to the + * output of a XOR gate. + * This parameter can be one of the following values: + * @arg TIM_TI1SELECTION_CH1: The TIMx_CH1 pin is connected to TI1 input + * @arg TIM_TI1SELECTION_XORCOMBINATION: The TIMx_CH1, CH2 and CH3 + * pins are connected to the TI1 input (XOR combination) + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_ConfigTI1Input(TIM_HandleTypeDef *htim, uint32_t TI1_Selection) +{ + uint32_t tmpcr2; + + /* Check the parameters */ + assert_param(IS_TIM_XOR_INSTANCE(htim->Instance)); + assert_param(IS_TIM_TI1SELECTION(TI1_Selection)); + + /* Get the TIMx CR2 register value */ + tmpcr2 = htim->Instance->CR2; + + /* Reset the TI1 selection */ + tmpcr2 &= ~TIM_CR2_TI1S; + + /* Set the TI1 selection */ + tmpcr2 |= TI1_Selection; + + /* Write to TIMxCR2 */ + htim->Instance->CR2 = tmpcr2; + + return HAL_OK; +} + +/** + * @brief Configures the TIM in Slave mode + * @param htim TIM handle. + * @param sSlaveConfig pointer to a TIM_SlaveConfigTypeDef structure that + * contains the selected trigger (internal trigger input, filtered + * timer input or external trigger input) and the Slave mode + * (Disable, Reset, Gated, Trigger, External clock mode 1). + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_SlaveConfigSynchro(TIM_HandleTypeDef *htim, TIM_SlaveConfigTypeDef *sSlaveConfig) +{ + /* Check the parameters */ + assert_param(IS_TIM_SLAVE_INSTANCE(htim->Instance)); + assert_param(IS_TIM_SLAVE_MODE(sSlaveConfig->SlaveMode)); + assert_param(IS_TIM_TRIGGER_SELECTION(sSlaveConfig->InputTrigger)); + + __HAL_LOCK(htim); + + htim->State = HAL_TIM_STATE_BUSY; + + if (TIM_SlaveTimer_SetConfig(htim, sSlaveConfig) != HAL_OK) + { + htim->State = HAL_TIM_STATE_READY; + __HAL_UNLOCK(htim); + return HAL_ERROR; + } + + /* Disable Trigger Interrupt */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_TRIGGER); + + /* Disable Trigger DMA request */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_TRIGGER); + + htim->State = HAL_TIM_STATE_READY; + + __HAL_UNLOCK(htim); + + return HAL_OK; +} + +/** + * @brief Configures the TIM in Slave mode in interrupt mode + * @param htim TIM handle. + * @param sSlaveConfig pointer to a TIM_SlaveConfigTypeDef structure that + * contains the selected trigger (internal trigger input, filtered + * timer input or external trigger input) and the Slave mode + * (Disable, Reset, Gated, Trigger, External clock mode 1). + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_SlaveConfigSynchro_IT(TIM_HandleTypeDef *htim, + TIM_SlaveConfigTypeDef *sSlaveConfig) +{ + /* Check the parameters */ + assert_param(IS_TIM_SLAVE_INSTANCE(htim->Instance)); + assert_param(IS_TIM_SLAVE_MODE(sSlaveConfig->SlaveMode)); + assert_param(IS_TIM_TRIGGER_SELECTION(sSlaveConfig->InputTrigger)); + + __HAL_LOCK(htim); + + htim->State = HAL_TIM_STATE_BUSY; + + if (TIM_SlaveTimer_SetConfig(htim, sSlaveConfig) != HAL_OK) + { + htim->State = HAL_TIM_STATE_READY; + __HAL_UNLOCK(htim); + return HAL_ERROR; + } + + /* Enable Trigger Interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_TRIGGER); + + /* Disable Trigger DMA request */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_TRIGGER); + + htim->State = HAL_TIM_STATE_READY; + + __HAL_UNLOCK(htim); + + return HAL_OK; +} + +/** + * @brief Read the captured value from Capture Compare unit + * @param htim TIM handle. + * @param Channel TIM Channels to be enabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @retval Captured value + */ +uint32_t HAL_TIM_ReadCapturedValue(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + uint32_t tmpreg = 0U; + + switch (Channel) + { + case TIM_CHANNEL_1: + { + /* Check the parameters */ + assert_param(IS_TIM_CC1_INSTANCE(htim->Instance)); + + /* Return the capture 1 value */ + tmpreg = htim->Instance->CCR1; + + break; + } + case TIM_CHANNEL_2: + { + /* Check the parameters */ + assert_param(IS_TIM_CC2_INSTANCE(htim->Instance)); + + /* Return the capture 2 value */ + tmpreg = htim->Instance->CCR2; + + break; + } + + case TIM_CHANNEL_3: + { + /* Check the parameters */ + assert_param(IS_TIM_CC3_INSTANCE(htim->Instance)); + + /* Return the capture 3 value */ + tmpreg = htim->Instance->CCR3; + + break; + } + + case TIM_CHANNEL_4: + { + /* Check the parameters */ + assert_param(IS_TIM_CC4_INSTANCE(htim->Instance)); + + /* Return the capture 4 value */ + tmpreg = htim->Instance->CCR4; + + break; + } + + default: + break; + } + + return tmpreg; +} + +/** + * @} + */ + +/** @defgroup TIM_Exported_Functions_Group9 TIM Callbacks functions + * @brief TIM Callbacks functions + * +@verbatim + ============================================================================== + ##### TIM Callbacks functions ##### + ============================================================================== + [..] + This section provides TIM callback functions: + (+) TIM Period elapsed callback + (+) TIM Output Compare callback + (+) TIM Input capture callback + (+) TIM Trigger callback + (+) TIM Error callback + +@endverbatim + * @{ + */ + +/** + * @brief Period elapsed callback in non-blocking mode + * @param htim TIM handle + * @retval None + */ +__weak void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(htim); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_TIM_PeriodElapsedCallback could be implemented in the user file + */ +} + +/** + * @brief Period elapsed half complete callback in non-blocking mode + * @param htim TIM handle + * @retval None + */ +__weak void HAL_TIM_PeriodElapsedHalfCpltCallback(TIM_HandleTypeDef *htim) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(htim); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_TIM_PeriodElapsedHalfCpltCallback could be implemented in the user file + */ +} + +/** + * @brief Output Compare callback in non-blocking mode + * @param htim TIM OC handle + * @retval None + */ +__weak void HAL_TIM_OC_DelayElapsedCallback(TIM_HandleTypeDef *htim) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(htim); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_TIM_OC_DelayElapsedCallback could be implemented in the user file + */ +} + +/** + * @brief Input Capture callback in non-blocking mode + * @param htim TIM IC handle + * @retval None + */ +__weak void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(htim); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_TIM_IC_CaptureCallback could be implemented in the user file + */ +} + +/** + * @brief Input Capture half complete callback in non-blocking mode + * @param htim TIM IC handle + * @retval None + */ +__weak void HAL_TIM_IC_CaptureHalfCpltCallback(TIM_HandleTypeDef *htim) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(htim); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_TIM_IC_CaptureHalfCpltCallback could be implemented in the user file + */ +} + +/** + * @brief PWM Pulse finished callback in non-blocking mode + * @param htim TIM handle + * @retval None + */ +__weak void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(htim); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_TIM_PWM_PulseFinishedCallback could be implemented in the user file + */ +} + +/** + * @brief PWM Pulse finished half complete callback in non-blocking mode + * @param htim TIM handle + * @retval None + */ +__weak void HAL_TIM_PWM_PulseFinishedHalfCpltCallback(TIM_HandleTypeDef *htim) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(htim); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_TIM_PWM_PulseFinishedHalfCpltCallback could be implemented in the user file + */ +} + +/** + * @brief Hall Trigger detection callback in non-blocking mode + * @param htim TIM handle + * @retval None + */ +__weak void HAL_TIM_TriggerCallback(TIM_HandleTypeDef *htim) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(htim); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_TIM_TriggerCallback could be implemented in the user file + */ +} + +/** + * @brief Hall Trigger detection half complete callback in non-blocking mode + * @param htim TIM handle + * @retval None + */ +__weak void HAL_TIM_TriggerHalfCpltCallback(TIM_HandleTypeDef *htim) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(htim); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_TIM_TriggerHalfCpltCallback could be implemented in the user file + */ +} + +/** + * @brief Timer error callback in non-blocking mode + * @param htim TIM handle + * @retval None + */ +__weak void HAL_TIM_ErrorCallback(TIM_HandleTypeDef *htim) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(htim); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_TIM_ErrorCallback could be implemented in the user file + */ +} + +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) +/** + * @brief Register a User TIM callback to be used instead of the weak predefined callback + * @param htim tim handle + * @param CallbackID ID of the callback to be registered + * This parameter can be one of the following values: + * @arg @ref HAL_TIM_BASE_MSPINIT_CB_ID Base MspInit Callback ID + * @arg @ref HAL_TIM_BASE_MSPDEINIT_CB_ID Base MspDeInit Callback ID + * @arg @ref HAL_TIM_IC_MSPINIT_CB_ID IC MspInit Callback ID + * @arg @ref HAL_TIM_IC_MSPDEINIT_CB_ID IC MspDeInit Callback ID + * @arg @ref HAL_TIM_OC_MSPINIT_CB_ID OC MspInit Callback ID + * @arg @ref HAL_TIM_OC_MSPDEINIT_CB_ID OC MspDeInit Callback ID + * @arg @ref HAL_TIM_PWM_MSPINIT_CB_ID PWM MspInit Callback ID + * @arg @ref HAL_TIM_PWM_MSPDEINIT_CB_ID PWM MspDeInit Callback ID + * @arg @ref HAL_TIM_ONE_PULSE_MSPINIT_CB_ID One Pulse MspInit Callback ID + * @arg @ref HAL_TIM_ONE_PULSE_MSPDEINIT_CB_ID One Pulse MspDeInit Callback ID + * @arg @ref HAL_TIM_ENCODER_MSPINIT_CB_ID Encoder MspInit Callback ID + * @arg @ref HAL_TIM_ENCODER_MSPDEINIT_CB_ID Encoder MspDeInit Callback ID + * @arg @ref HAL_TIM_HALL_SENSOR_MSPINIT_CB_ID Hall Sensor MspInit Callback ID + * @arg @ref HAL_TIM_HALL_SENSOR_MSPDEINIT_CB_ID Hall Sensor MspDeInit Callback ID + * @arg @ref HAL_TIM_PERIOD_ELAPSED_CB_ID Period Elapsed Callback ID + * @arg @ref HAL_TIM_PERIOD_ELAPSED_HALF_CB_ID Period Elapsed half complete Callback ID + * @arg @ref HAL_TIM_TRIGGER_CB_ID Trigger Callback ID + * @arg @ref HAL_TIM_TRIGGER_HALF_CB_ID Trigger half complete Callback ID + * @arg @ref HAL_TIM_IC_CAPTURE_CB_ID Input Capture Callback ID + * @arg @ref HAL_TIM_IC_CAPTURE_HALF_CB_ID Input Capture half complete Callback ID + * @arg @ref HAL_TIM_OC_DELAY_ELAPSED_CB_ID Output Compare Delay Elapsed Callback ID + * @arg @ref HAL_TIM_PWM_PULSE_FINISHED_CB_ID PWM Pulse Finished Callback ID + * @arg @ref HAL_TIM_PWM_PULSE_FINISHED_HALF_CB_ID PWM Pulse Finished half complete Callback ID + * @arg @ref HAL_TIM_ERROR_CB_ID Error Callback ID + * @arg @ref HAL_TIM_COMMUTATION_CB_ID Commutation Callback ID + * @arg @ref HAL_TIM_COMMUTATION_HALF_CB_ID Commutation half complete Callback ID + * @arg @ref HAL_TIM_BREAK_CB_ID Break Callback ID + * @param pCallback pointer to the callback function + * @retval status + */ +HAL_StatusTypeDef HAL_TIM_RegisterCallback(TIM_HandleTypeDef *htim, HAL_TIM_CallbackIDTypeDef CallbackID, + pTIM_CallbackTypeDef pCallback) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (pCallback == NULL) + { + return HAL_ERROR; + } + /* Process locked */ + __HAL_LOCK(htim); + + if (htim->State == HAL_TIM_STATE_READY) + { + switch (CallbackID) + { + case HAL_TIM_BASE_MSPINIT_CB_ID : + htim->Base_MspInitCallback = pCallback; + break; + + case HAL_TIM_BASE_MSPDEINIT_CB_ID : + htim->Base_MspDeInitCallback = pCallback; + break; + + case HAL_TIM_IC_MSPINIT_CB_ID : + htim->IC_MspInitCallback = pCallback; + break; + + case HAL_TIM_IC_MSPDEINIT_CB_ID : + htim->IC_MspDeInitCallback = pCallback; + break; + + case HAL_TIM_OC_MSPINIT_CB_ID : + htim->OC_MspInitCallback = pCallback; + break; + + case HAL_TIM_OC_MSPDEINIT_CB_ID : + htim->OC_MspDeInitCallback = pCallback; + break; + + case HAL_TIM_PWM_MSPINIT_CB_ID : + htim->PWM_MspInitCallback = pCallback; + break; + + case HAL_TIM_PWM_MSPDEINIT_CB_ID : + htim->PWM_MspDeInitCallback = pCallback; + break; + + case HAL_TIM_ONE_PULSE_MSPINIT_CB_ID : + htim->OnePulse_MspInitCallback = pCallback; + break; + + case HAL_TIM_ONE_PULSE_MSPDEINIT_CB_ID : + htim->OnePulse_MspDeInitCallback = pCallback; + break; + + case HAL_TIM_ENCODER_MSPINIT_CB_ID : + htim->Encoder_MspInitCallback = pCallback; + break; + + case HAL_TIM_ENCODER_MSPDEINIT_CB_ID : + htim->Encoder_MspDeInitCallback = pCallback; + break; + + case HAL_TIM_HALL_SENSOR_MSPINIT_CB_ID : + htim->HallSensor_MspInitCallback = pCallback; + break; + + case HAL_TIM_HALL_SENSOR_MSPDEINIT_CB_ID : + htim->HallSensor_MspDeInitCallback = pCallback; + break; + + case HAL_TIM_PERIOD_ELAPSED_CB_ID : + htim->PeriodElapsedCallback = pCallback; + break; + + case HAL_TIM_PERIOD_ELAPSED_HALF_CB_ID : + htim->PeriodElapsedHalfCpltCallback = pCallback; + break; + + case HAL_TIM_TRIGGER_CB_ID : + htim->TriggerCallback = pCallback; + break; + + case HAL_TIM_TRIGGER_HALF_CB_ID : + htim->TriggerHalfCpltCallback = pCallback; + break; + + case HAL_TIM_IC_CAPTURE_CB_ID : + htim->IC_CaptureCallback = pCallback; + break; + + case HAL_TIM_IC_CAPTURE_HALF_CB_ID : + htim->IC_CaptureHalfCpltCallback = pCallback; + break; + + case HAL_TIM_OC_DELAY_ELAPSED_CB_ID : + htim->OC_DelayElapsedCallback = pCallback; + break; + + case HAL_TIM_PWM_PULSE_FINISHED_CB_ID : + htim->PWM_PulseFinishedCallback = pCallback; + break; + + case HAL_TIM_PWM_PULSE_FINISHED_HALF_CB_ID : + htim->PWM_PulseFinishedHalfCpltCallback = pCallback; + break; + + case HAL_TIM_ERROR_CB_ID : + htim->ErrorCallback = pCallback; + break; + + case HAL_TIM_COMMUTATION_CB_ID : + htim->CommutationCallback = pCallback; + break; + + case HAL_TIM_COMMUTATION_HALF_CB_ID : + htim->CommutationHalfCpltCallback = pCallback; + break; + + case HAL_TIM_BREAK_CB_ID : + htim->BreakCallback = pCallback; + break; + + default : + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else if (htim->State == HAL_TIM_STATE_RESET) + { + switch (CallbackID) + { + case HAL_TIM_BASE_MSPINIT_CB_ID : + htim->Base_MspInitCallback = pCallback; + break; + + case HAL_TIM_BASE_MSPDEINIT_CB_ID : + htim->Base_MspDeInitCallback = pCallback; + break; + + case HAL_TIM_IC_MSPINIT_CB_ID : + htim->IC_MspInitCallback = pCallback; + break; + + case HAL_TIM_IC_MSPDEINIT_CB_ID : + htim->IC_MspDeInitCallback = pCallback; + break; + + case HAL_TIM_OC_MSPINIT_CB_ID : + htim->OC_MspInitCallback = pCallback; + break; + + case HAL_TIM_OC_MSPDEINIT_CB_ID : + htim->OC_MspDeInitCallback = pCallback; + break; + + case HAL_TIM_PWM_MSPINIT_CB_ID : + htim->PWM_MspInitCallback = pCallback; + break; + + case HAL_TIM_PWM_MSPDEINIT_CB_ID : + htim->PWM_MspDeInitCallback = pCallback; + break; + + case HAL_TIM_ONE_PULSE_MSPINIT_CB_ID : + htim->OnePulse_MspInitCallback = pCallback; + break; + + case HAL_TIM_ONE_PULSE_MSPDEINIT_CB_ID : + htim->OnePulse_MspDeInitCallback = pCallback; + break; + + case HAL_TIM_ENCODER_MSPINIT_CB_ID : + htim->Encoder_MspInitCallback = pCallback; + break; + + case HAL_TIM_ENCODER_MSPDEINIT_CB_ID : + htim->Encoder_MspDeInitCallback = pCallback; + break; + + case HAL_TIM_HALL_SENSOR_MSPINIT_CB_ID : + htim->HallSensor_MspInitCallback = pCallback; + break; + + case HAL_TIM_HALL_SENSOR_MSPDEINIT_CB_ID : + htim->HallSensor_MspDeInitCallback = pCallback; + break; + + default : + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else + { + /* Return error status */ + status = HAL_ERROR; + } + + /* Release Lock */ + __HAL_UNLOCK(htim); + + return status; +} + +/** + * @brief Unregister a TIM callback + * TIM callback is redirected to the weak predefined callback + * @param htim tim handle + * @param CallbackID ID of the callback to be unregistered + * This parameter can be one of the following values: + * @arg @ref HAL_TIM_BASE_MSPINIT_CB_ID Base MspInit Callback ID + * @arg @ref HAL_TIM_BASE_MSPDEINIT_CB_ID Base MspDeInit Callback ID + * @arg @ref HAL_TIM_IC_MSPINIT_CB_ID IC MspInit Callback ID + * @arg @ref HAL_TIM_IC_MSPDEINIT_CB_ID IC MspDeInit Callback ID + * @arg @ref HAL_TIM_OC_MSPINIT_CB_ID OC MspInit Callback ID + * @arg @ref HAL_TIM_OC_MSPDEINIT_CB_ID OC MspDeInit Callback ID + * @arg @ref HAL_TIM_PWM_MSPINIT_CB_ID PWM MspInit Callback ID + * @arg @ref HAL_TIM_PWM_MSPDEINIT_CB_ID PWM MspDeInit Callback ID + * @arg @ref HAL_TIM_ONE_PULSE_MSPINIT_CB_ID One Pulse MspInit Callback ID + * @arg @ref HAL_TIM_ONE_PULSE_MSPDEINIT_CB_ID One Pulse MspDeInit Callback ID + * @arg @ref HAL_TIM_ENCODER_MSPINIT_CB_ID Encoder MspInit Callback ID + * @arg @ref HAL_TIM_ENCODER_MSPDEINIT_CB_ID Encoder MspDeInit Callback ID + * @arg @ref HAL_TIM_HALL_SENSOR_MSPINIT_CB_ID Hall Sensor MspInit Callback ID + * @arg @ref HAL_TIM_HALL_SENSOR_MSPDEINIT_CB_ID Hall Sensor MspDeInit Callback ID + * @arg @ref HAL_TIM_PERIOD_ELAPSED_CB_ID Period Elapsed Callback ID + * @arg @ref HAL_TIM_PERIOD_ELAPSED_HALF_CB_ID Period Elapsed half complete Callback ID + * @arg @ref HAL_TIM_TRIGGER_CB_ID Trigger Callback ID + * @arg @ref HAL_TIM_TRIGGER_HALF_CB_ID Trigger half complete Callback ID + * @arg @ref HAL_TIM_IC_CAPTURE_CB_ID Input Capture Callback ID + * @arg @ref HAL_TIM_IC_CAPTURE_HALF_CB_ID Input Capture half complete Callback ID + * @arg @ref HAL_TIM_OC_DELAY_ELAPSED_CB_ID Output Compare Delay Elapsed Callback ID + * @arg @ref HAL_TIM_PWM_PULSE_FINISHED_CB_ID PWM Pulse Finished Callback ID + * @arg @ref HAL_TIM_PWM_PULSE_FINISHED_HALF_CB_ID PWM Pulse Finished half complete Callback ID + * @arg @ref HAL_TIM_ERROR_CB_ID Error Callback ID + * @arg @ref HAL_TIM_COMMUTATION_CB_ID Commutation Callback ID + * @arg @ref HAL_TIM_COMMUTATION_HALF_CB_ID Commutation half complete Callback ID + * @arg @ref HAL_TIM_BREAK_CB_ID Break Callback ID + * @retval status + */ +HAL_StatusTypeDef HAL_TIM_UnRegisterCallback(TIM_HandleTypeDef *htim, HAL_TIM_CallbackIDTypeDef CallbackID) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Process locked */ + __HAL_LOCK(htim); + + if (htim->State == HAL_TIM_STATE_READY) + { + switch (CallbackID) + { + case HAL_TIM_BASE_MSPINIT_CB_ID : + htim->Base_MspInitCallback = HAL_TIM_Base_MspInit; /* Legacy weak Base MspInit Callback */ + break; + + case HAL_TIM_BASE_MSPDEINIT_CB_ID : + htim->Base_MspDeInitCallback = HAL_TIM_Base_MspDeInit; /* Legacy weak Base Msp DeInit Callback */ + break; + + case HAL_TIM_IC_MSPINIT_CB_ID : + htim->IC_MspInitCallback = HAL_TIM_IC_MspInit; /* Legacy weak IC Msp Init Callback */ + break; + + case HAL_TIM_IC_MSPDEINIT_CB_ID : + htim->IC_MspDeInitCallback = HAL_TIM_IC_MspDeInit; /* Legacy weak IC Msp DeInit Callback */ + break; + + case HAL_TIM_OC_MSPINIT_CB_ID : + htim->OC_MspInitCallback = HAL_TIM_OC_MspInit; /* Legacy weak OC Msp Init Callback */ + break; + + case HAL_TIM_OC_MSPDEINIT_CB_ID : + htim->OC_MspDeInitCallback = HAL_TIM_OC_MspDeInit; /* Legacy weak OC Msp DeInit Callback */ + break; + + case HAL_TIM_PWM_MSPINIT_CB_ID : + htim->PWM_MspInitCallback = HAL_TIM_PWM_MspInit; /* Legacy weak PWM Msp Init Callback */ + break; + + case HAL_TIM_PWM_MSPDEINIT_CB_ID : + htim->PWM_MspDeInitCallback = HAL_TIM_PWM_MspDeInit; /* Legacy weak PWM Msp DeInit Callback */ + break; + + case HAL_TIM_ONE_PULSE_MSPINIT_CB_ID : + htim->OnePulse_MspInitCallback = HAL_TIM_OnePulse_MspInit; /* Legacy weak One Pulse Msp Init Callback */ + break; + + case HAL_TIM_ONE_PULSE_MSPDEINIT_CB_ID : + htim->OnePulse_MspDeInitCallback = HAL_TIM_OnePulse_MspDeInit; /* Legacy weak One Pulse Msp DeInit Callback */ + break; + + case HAL_TIM_ENCODER_MSPINIT_CB_ID : + htim->Encoder_MspInitCallback = HAL_TIM_Encoder_MspInit; /* Legacy weak Encoder Msp Init Callback */ + break; + + case HAL_TIM_ENCODER_MSPDEINIT_CB_ID : + htim->Encoder_MspDeInitCallback = HAL_TIM_Encoder_MspDeInit; /* Legacy weak Encoder Msp DeInit Callback */ + break; + + case HAL_TIM_HALL_SENSOR_MSPINIT_CB_ID : + htim->HallSensor_MspInitCallback = HAL_TIMEx_HallSensor_MspInit; /* Legacy weak Hall Sensor Msp Init Callback */ + break; + + case HAL_TIM_HALL_SENSOR_MSPDEINIT_CB_ID : + htim->HallSensor_MspDeInitCallback = HAL_TIMEx_HallSensor_MspDeInit; /* Legacy weak Hall Sensor Msp DeInit Callback */ + break; + + case HAL_TIM_PERIOD_ELAPSED_CB_ID : + htim->PeriodElapsedCallback = HAL_TIM_PeriodElapsedCallback; /* Legacy weak Period Elapsed Callback */ + break; + + case HAL_TIM_PERIOD_ELAPSED_HALF_CB_ID : + htim->PeriodElapsedHalfCpltCallback = HAL_TIM_PeriodElapsedHalfCpltCallback; /* Legacy weak Period Elapsed half complete Callback */ + break; + + case HAL_TIM_TRIGGER_CB_ID : + htim->TriggerCallback = HAL_TIM_TriggerCallback; /* Legacy weak Trigger Callback */ + break; + + case HAL_TIM_TRIGGER_HALF_CB_ID : + htim->TriggerHalfCpltCallback = HAL_TIM_TriggerHalfCpltCallback; /* Legacy weak Trigger half complete Callback */ + break; + + case HAL_TIM_IC_CAPTURE_CB_ID : + htim->IC_CaptureCallback = HAL_TIM_IC_CaptureCallback; /* Legacy weak IC Capture Callback */ + break; + + case HAL_TIM_IC_CAPTURE_HALF_CB_ID : + htim->IC_CaptureHalfCpltCallback = HAL_TIM_IC_CaptureHalfCpltCallback; /* Legacy weak IC Capture half complete Callback */ + break; + + case HAL_TIM_OC_DELAY_ELAPSED_CB_ID : + htim->OC_DelayElapsedCallback = HAL_TIM_OC_DelayElapsedCallback; /* Legacy weak OC Delay Elapsed Callback */ + break; + + case HAL_TIM_PWM_PULSE_FINISHED_CB_ID : + htim->PWM_PulseFinishedCallback = HAL_TIM_PWM_PulseFinishedCallback; /* Legacy weak PWM Pulse Finished Callback */ + break; + + case HAL_TIM_PWM_PULSE_FINISHED_HALF_CB_ID : + htim->PWM_PulseFinishedHalfCpltCallback = HAL_TIM_PWM_PulseFinishedHalfCpltCallback; /* Legacy weak PWM Pulse Finished half complete Callback */ + break; + + case HAL_TIM_ERROR_CB_ID : + htim->ErrorCallback = HAL_TIM_ErrorCallback; /* Legacy weak Error Callback */ + break; + + case HAL_TIM_COMMUTATION_CB_ID : + htim->CommutationCallback = HAL_TIMEx_CommutCallback; /* Legacy weak Commutation Callback */ + break; + + case HAL_TIM_COMMUTATION_HALF_CB_ID : + htim->CommutationHalfCpltCallback = HAL_TIMEx_CommutHalfCpltCallback; /* Legacy weak Commutation half complete Callback */ + break; + + case HAL_TIM_BREAK_CB_ID : + htim->BreakCallback = HAL_TIMEx_BreakCallback; /* Legacy weak Break Callback */ + break; + + default : + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else if (htim->State == HAL_TIM_STATE_RESET) + { + switch (CallbackID) + { + case HAL_TIM_BASE_MSPINIT_CB_ID : + htim->Base_MspInitCallback = HAL_TIM_Base_MspInit; /* Legacy weak Base MspInit Callback */ + break; + + case HAL_TIM_BASE_MSPDEINIT_CB_ID : + htim->Base_MspDeInitCallback = HAL_TIM_Base_MspDeInit; /* Legacy weak Base Msp DeInit Callback */ + break; + + case HAL_TIM_IC_MSPINIT_CB_ID : + htim->IC_MspInitCallback = HAL_TIM_IC_MspInit; /* Legacy weak IC Msp Init Callback */ + break; + + case HAL_TIM_IC_MSPDEINIT_CB_ID : + htim->IC_MspDeInitCallback = HAL_TIM_IC_MspDeInit; /* Legacy weak IC Msp DeInit Callback */ + break; + + case HAL_TIM_OC_MSPINIT_CB_ID : + htim->OC_MspInitCallback = HAL_TIM_OC_MspInit; /* Legacy weak OC Msp Init Callback */ + break; + + case HAL_TIM_OC_MSPDEINIT_CB_ID : + htim->OC_MspDeInitCallback = HAL_TIM_OC_MspDeInit; /* Legacy weak OC Msp DeInit Callback */ + break; + + case HAL_TIM_PWM_MSPINIT_CB_ID : + htim->PWM_MspInitCallback = HAL_TIM_PWM_MspInit; /* Legacy weak PWM Msp Init Callback */ + break; + + case HAL_TIM_PWM_MSPDEINIT_CB_ID : + htim->PWM_MspDeInitCallback = HAL_TIM_PWM_MspDeInit; /* Legacy weak PWM Msp DeInit Callback */ + break; + + case HAL_TIM_ONE_PULSE_MSPINIT_CB_ID : + htim->OnePulse_MspInitCallback = HAL_TIM_OnePulse_MspInit; /* Legacy weak One Pulse Msp Init Callback */ + break; + + case HAL_TIM_ONE_PULSE_MSPDEINIT_CB_ID : + htim->OnePulse_MspDeInitCallback = HAL_TIM_OnePulse_MspDeInit; /* Legacy weak One Pulse Msp DeInit Callback */ + break; + + case HAL_TIM_ENCODER_MSPINIT_CB_ID : + htim->Encoder_MspInitCallback = HAL_TIM_Encoder_MspInit; /* Legacy weak Encoder Msp Init Callback */ + break; + + case HAL_TIM_ENCODER_MSPDEINIT_CB_ID : + htim->Encoder_MspDeInitCallback = HAL_TIM_Encoder_MspDeInit; /* Legacy weak Encoder Msp DeInit Callback */ + break; + + case HAL_TIM_HALL_SENSOR_MSPINIT_CB_ID : + htim->HallSensor_MspInitCallback = HAL_TIMEx_HallSensor_MspInit; /* Legacy weak Hall Sensor Msp Init Callback */ + break; + + case HAL_TIM_HALL_SENSOR_MSPDEINIT_CB_ID : + htim->HallSensor_MspDeInitCallback = HAL_TIMEx_HallSensor_MspDeInit; /* Legacy weak Hall Sensor Msp DeInit Callback */ + break; + + default : + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else + { + /* Return error status */ + status = HAL_ERROR; + } + + /* Release Lock */ + __HAL_UNLOCK(htim); + + return status; +} +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + +/** + * @} + */ + +/** @defgroup TIM_Exported_Functions_Group10 TIM Peripheral State functions + * @brief TIM Peripheral State functions + * +@verbatim + ============================================================================== + ##### Peripheral State functions ##### + ============================================================================== + [..] + This subsection permits to get in run-time the status of the peripheral + and the data flow. + +@endverbatim + * @{ + */ + +/** + * @brief Return the TIM Base handle state. + * @param htim TIM Base handle + * @retval HAL state + */ +HAL_TIM_StateTypeDef HAL_TIM_Base_GetState(TIM_HandleTypeDef *htim) +{ + return htim->State; +} + +/** + * @brief Return the TIM OC handle state. + * @param htim TIM Output Compare handle + * @retval HAL state + */ +HAL_TIM_StateTypeDef HAL_TIM_OC_GetState(TIM_HandleTypeDef *htim) +{ + return htim->State; +} + +/** + * @brief Return the TIM PWM handle state. + * @param htim TIM handle + * @retval HAL state + */ +HAL_TIM_StateTypeDef HAL_TIM_PWM_GetState(TIM_HandleTypeDef *htim) +{ + return htim->State; +} + +/** + * @brief Return the TIM Input Capture handle state. + * @param htim TIM IC handle + * @retval HAL state + */ +HAL_TIM_StateTypeDef HAL_TIM_IC_GetState(TIM_HandleTypeDef *htim) +{ + return htim->State; +} + +/** + * @brief Return the TIM One Pulse Mode handle state. + * @param htim TIM OPM handle + * @retval HAL state + */ +HAL_TIM_StateTypeDef HAL_TIM_OnePulse_GetState(TIM_HandleTypeDef *htim) +{ + return htim->State; +} + +/** + * @brief Return the TIM Encoder Mode handle state. + * @param htim TIM Encoder Interface handle + * @retval HAL state + */ +HAL_TIM_StateTypeDef HAL_TIM_Encoder_GetState(TIM_HandleTypeDef *htim) +{ + return htim->State; +} + +/** + * @} + */ + +/** + * @} + */ + +/** @defgroup TIM_Private_Functions TIM Private Functions + * @{ + */ + +/** + * @brief TIM DMA error callback + * @param hdma pointer to DMA handle. + * @retval None + */ +void TIM_DMAError(DMA_HandleTypeDef *hdma) +{ + TIM_HandleTypeDef *htim = (TIM_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; + + htim->State = HAL_TIM_STATE_READY; + +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + htim->ErrorCallback(htim); +#else + HAL_TIM_ErrorCallback(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ +} + +/** + * @brief TIM DMA Delay Pulse complete callback. + * @param hdma pointer to DMA handle. + * @retval None + */ +void TIM_DMADelayPulseCplt(DMA_HandleTypeDef *hdma) +{ + TIM_HandleTypeDef *htim = (TIM_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; + + htim->State = HAL_TIM_STATE_READY; + + if (hdma == htim->hdma[TIM_DMA_ID_CC1]) + { + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_1; + } + else if (hdma == htim->hdma[TIM_DMA_ID_CC2]) + { + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_2; + } + else if (hdma == htim->hdma[TIM_DMA_ID_CC3]) + { + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_3; + } + else if (hdma == htim->hdma[TIM_DMA_ID_CC4]) + { + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_4; + } + else + { + /* nothing to do */ + } + +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + htim->PWM_PulseFinishedCallback(htim); +#else + HAL_TIM_PWM_PulseFinishedCallback(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED; +} + +/** + * @brief TIM DMA Delay Pulse half complete callback. + * @param hdma pointer to DMA handle. + * @retval None + */ +void TIM_DMADelayPulseHalfCplt(DMA_HandleTypeDef *hdma) +{ + TIM_HandleTypeDef *htim = (TIM_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; + + htim->State = HAL_TIM_STATE_READY; + + if (hdma == htim->hdma[TIM_DMA_ID_CC1]) + { + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_1; + } + else if (hdma == htim->hdma[TIM_DMA_ID_CC2]) + { + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_2; + } + else if (hdma == htim->hdma[TIM_DMA_ID_CC3]) + { + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_3; + } + else if (hdma == htim->hdma[TIM_DMA_ID_CC4]) + { + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_4; + } + else + { + /* nothing to do */ + } + +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + htim->PWM_PulseFinishedHalfCpltCallback(htim); +#else + HAL_TIM_PWM_PulseFinishedHalfCpltCallback(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED; +} + +/** + * @brief TIM DMA Capture complete callback. + * @param hdma pointer to DMA handle. + * @retval None + */ +void TIM_DMACaptureCplt(DMA_HandleTypeDef *hdma) +{ + TIM_HandleTypeDef *htim = (TIM_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; + + htim->State = HAL_TIM_STATE_READY; + + if (hdma == htim->hdma[TIM_DMA_ID_CC1]) + { + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_1; + } + else if (hdma == htim->hdma[TIM_DMA_ID_CC2]) + { + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_2; + } + else if (hdma == htim->hdma[TIM_DMA_ID_CC3]) + { + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_3; + } + else if (hdma == htim->hdma[TIM_DMA_ID_CC4]) + { + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_4; + } + else + { + /* nothing to do */ + } + +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + htim->IC_CaptureCallback(htim); +#else + HAL_TIM_IC_CaptureCallback(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED; +} + +/** + * @brief TIM DMA Capture half complete callback. + * @param hdma pointer to DMA handle. + * @retval None + */ +void TIM_DMACaptureHalfCplt(DMA_HandleTypeDef *hdma) +{ + TIM_HandleTypeDef *htim = (TIM_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; + + htim->State = HAL_TIM_STATE_READY; + + if (hdma == htim->hdma[TIM_DMA_ID_CC1]) + { + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_1; + } + else if (hdma == htim->hdma[TIM_DMA_ID_CC2]) + { + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_2; + } + else if (hdma == htim->hdma[TIM_DMA_ID_CC3]) + { + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_3; + } + else if (hdma == htim->hdma[TIM_DMA_ID_CC4]) + { + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_4; + } + else + { + /* nothing to do */ + } + +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + htim->IC_CaptureHalfCpltCallback(htim); +#else + HAL_TIM_IC_CaptureHalfCpltCallback(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED; +} + +/** + * @brief TIM DMA Period Elapse complete callback. + * @param hdma pointer to DMA handle. + * @retval None + */ +static void TIM_DMAPeriodElapsedCplt(DMA_HandleTypeDef *hdma) +{ + TIM_HandleTypeDef *htim = (TIM_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; + + htim->State = HAL_TIM_STATE_READY; + +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + htim->PeriodElapsedCallback(htim); +#else + HAL_TIM_PeriodElapsedCallback(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ +} + +/** + * @brief TIM DMA Period Elapse half complete callback. + * @param hdma pointer to DMA handle. + * @retval None + */ +static void TIM_DMAPeriodElapsedHalfCplt(DMA_HandleTypeDef *hdma) +{ + TIM_HandleTypeDef *htim = (TIM_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; + + htim->State = HAL_TIM_STATE_READY; + +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + htim->PeriodElapsedHalfCpltCallback(htim); +#else + HAL_TIM_PeriodElapsedHalfCpltCallback(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ +} + +/** + * @brief TIM DMA Trigger callback. + * @param hdma pointer to DMA handle. + * @retval None + */ +static void TIM_DMATriggerCplt(DMA_HandleTypeDef *hdma) +{ + TIM_HandleTypeDef *htim = (TIM_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; + + htim->State = HAL_TIM_STATE_READY; + +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + htim->TriggerCallback(htim); +#else + HAL_TIM_TriggerCallback(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ +} + +/** + * @brief TIM DMA Trigger half complete callback. + * @param hdma pointer to DMA handle. + * @retval None + */ +static void TIM_DMATriggerHalfCplt(DMA_HandleTypeDef *hdma) +{ + TIM_HandleTypeDef *htim = (TIM_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; + + htim->State = HAL_TIM_STATE_READY; + +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + htim->TriggerHalfCpltCallback(htim); +#else + HAL_TIM_TriggerHalfCpltCallback(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ +} + +/** + * @brief Time Base configuration + * @param TIMx TIM peripheral + * @param Structure TIM Base configuration structure + * @retval None + */ +void TIM_Base_SetConfig(TIM_TypeDef *TIMx, TIM_Base_InitTypeDef *Structure) +{ + uint32_t tmpcr1; + tmpcr1 = TIMx->CR1; + + /* Set TIM Time Base Unit parameters ---------------------------------------*/ + if (IS_TIM_COUNTER_MODE_SELECT_INSTANCE(TIMx)) + { + /* Select the Counter Mode */ + tmpcr1 &= ~(TIM_CR1_DIR | TIM_CR1_CMS); + tmpcr1 |= Structure->CounterMode; + } + + if (IS_TIM_CLOCK_DIVISION_INSTANCE(TIMx)) + { + /* Set the clock division */ + tmpcr1 &= ~TIM_CR1_CKD; + tmpcr1 |= (uint32_t)Structure->ClockDivision; + } + + /* Set the auto-reload preload */ + MODIFY_REG(tmpcr1, TIM_CR1_ARPE, Structure->AutoReloadPreload); + + TIMx->CR1 = tmpcr1; + + /* Set the Autoreload value */ + TIMx->ARR = (uint32_t)Structure->Period ; + + /* Set the Prescaler value */ + TIMx->PSC = Structure->Prescaler; + + if (IS_TIM_REPETITION_COUNTER_INSTANCE(TIMx)) + { + /* Set the Repetition Counter value */ + TIMx->RCR = Structure->RepetitionCounter; + } + + /* Generate an update event to reload the Prescaler + and the repetition counter (only for advanced timer) value immediately */ + TIMx->EGR = TIM_EGR_UG; +} + +/** + * @brief Timer Output Compare 1 configuration + * @param TIMx to select the TIM peripheral + * @param OC_Config The ouput configuration structure + * @retval None + */ +static void TIM_OC1_SetConfig(TIM_TypeDef *TIMx, TIM_OC_InitTypeDef *OC_Config) +{ + uint32_t tmpccmrx; + uint32_t tmpccer; + uint32_t tmpcr2; + + /* Disable the Channel 1: Reset the CC1E Bit */ + TIMx->CCER &= ~TIM_CCER_CC1E; + + /* Get the TIMx CCER register value */ + tmpccer = TIMx->CCER; + /* Get the TIMx CR2 register value */ + tmpcr2 = TIMx->CR2; + + /* Get the TIMx CCMR1 register value */ + tmpccmrx = TIMx->CCMR1; + + /* Reset the Output Compare Mode Bits */ + tmpccmrx &= ~TIM_CCMR1_OC1M; + tmpccmrx &= ~TIM_CCMR1_CC1S; + /* Select the Output Compare Mode */ + tmpccmrx |= OC_Config->OCMode; + + /* Reset the Output Polarity level */ + tmpccer &= ~TIM_CCER_CC1P; + /* Set the Output Compare Polarity */ + tmpccer |= OC_Config->OCPolarity; + + if (IS_TIM_CCXN_INSTANCE(TIMx, TIM_CHANNEL_1)) + { + /* Check parameters */ + assert_param(IS_TIM_OCN_POLARITY(OC_Config->OCNPolarity)); + + /* Reset the Output N Polarity level */ + tmpccer &= ~TIM_CCER_CC1NP; + /* Set the Output N Polarity */ + tmpccer |= OC_Config->OCNPolarity; + /* Reset the Output N State */ + tmpccer &= ~TIM_CCER_CC1NE; + } + + if (IS_TIM_BREAK_INSTANCE(TIMx)) + { + /* Check parameters */ + assert_param(IS_TIM_OCNIDLE_STATE(OC_Config->OCNIdleState)); + assert_param(IS_TIM_OCIDLE_STATE(OC_Config->OCIdleState)); + + /* Reset the Output Compare and Output Compare N IDLE State */ + tmpcr2 &= ~TIM_CR2_OIS1; + tmpcr2 &= ~TIM_CR2_OIS1N; + /* Set the Output Idle state */ + tmpcr2 |= OC_Config->OCIdleState; + /* Set the Output N Idle state */ + tmpcr2 |= OC_Config->OCNIdleState; + } + + /* Write to TIMx CR2 */ + TIMx->CR2 = tmpcr2; + + /* Write to TIMx CCMR1 */ + TIMx->CCMR1 = tmpccmrx; + + /* Set the Capture Compare Register value */ + TIMx->CCR1 = OC_Config->Pulse; + + /* Write to TIMx CCER */ + TIMx->CCER = tmpccer; +} + +/** + * @brief Timer Output Compare 2 configuration + * @param TIMx to select the TIM peripheral + * @param OC_Config The ouput configuration structure + * @retval None + */ +void TIM_OC2_SetConfig(TIM_TypeDef *TIMx, TIM_OC_InitTypeDef *OC_Config) +{ + uint32_t tmpccmrx; + uint32_t tmpccer; + uint32_t tmpcr2; + + /* Disable the Channel 2: Reset the CC2E Bit */ + TIMx->CCER &= ~TIM_CCER_CC2E; + + /* Get the TIMx CCER register value */ + tmpccer = TIMx->CCER; + /* Get the TIMx CR2 register value */ + tmpcr2 = TIMx->CR2; + + /* Get the TIMx CCMR1 register value */ + tmpccmrx = TIMx->CCMR1; + + /* Reset the Output Compare mode and Capture/Compare selection Bits */ + tmpccmrx &= ~TIM_CCMR1_OC2M; + tmpccmrx &= ~TIM_CCMR1_CC2S; + + /* Select the Output Compare Mode */ + tmpccmrx |= (OC_Config->OCMode << 8U); + + /* Reset the Output Polarity level */ + tmpccer &= ~TIM_CCER_CC2P; + /* Set the Output Compare Polarity */ + tmpccer |= (OC_Config->OCPolarity << 4U); + + if (IS_TIM_CCXN_INSTANCE(TIMx, TIM_CHANNEL_2)) + { + assert_param(IS_TIM_OCN_POLARITY(OC_Config->OCNPolarity)); + + /* Reset the Output N Polarity level */ + tmpccer &= ~TIM_CCER_CC2NP; + /* Set the Output N Polarity */ + tmpccer |= (OC_Config->OCNPolarity << 4U); + /* Reset the Output N State */ + tmpccer &= ~TIM_CCER_CC2NE; + + } + + if (IS_TIM_BREAK_INSTANCE(TIMx)) + { + /* Check parameters */ + assert_param(IS_TIM_OCNIDLE_STATE(OC_Config->OCNIdleState)); + assert_param(IS_TIM_OCIDLE_STATE(OC_Config->OCIdleState)); + + /* Reset the Output Compare and Output Compare N IDLE State */ + tmpcr2 &= ~TIM_CR2_OIS2; + tmpcr2 &= ~TIM_CR2_OIS2N; + /* Set the Output Idle state */ + tmpcr2 |= (OC_Config->OCIdleState << 2U); + /* Set the Output N Idle state */ + tmpcr2 |= (OC_Config->OCNIdleState << 2U); + } + + /* Write to TIMx CR2 */ + TIMx->CR2 = tmpcr2; + + /* Write to TIMx CCMR1 */ + TIMx->CCMR1 = tmpccmrx; + + /* Set the Capture Compare Register value */ + TIMx->CCR2 = OC_Config->Pulse; + + /* Write to TIMx CCER */ + TIMx->CCER = tmpccer; +} + +/** + * @brief Timer Output Compare 3 configuration + * @param TIMx to select the TIM peripheral + * @param OC_Config The ouput configuration structure + * @retval None + */ +static void TIM_OC3_SetConfig(TIM_TypeDef *TIMx, TIM_OC_InitTypeDef *OC_Config) +{ + uint32_t tmpccmrx; + uint32_t tmpccer; + uint32_t tmpcr2; + + /* Disable the Channel 3: Reset the CC2E Bit */ + TIMx->CCER &= ~TIM_CCER_CC3E; + + /* Get the TIMx CCER register value */ + tmpccer = TIMx->CCER; + /* Get the TIMx CR2 register value */ + tmpcr2 = TIMx->CR2; + + /* Get the TIMx CCMR2 register value */ + tmpccmrx = TIMx->CCMR2; + + /* Reset the Output Compare mode and Capture/Compare selection Bits */ + tmpccmrx &= ~TIM_CCMR2_OC3M; + tmpccmrx &= ~TIM_CCMR2_CC3S; + /* Select the Output Compare Mode */ + tmpccmrx |= OC_Config->OCMode; + + /* Reset the Output Polarity level */ + tmpccer &= ~TIM_CCER_CC3P; + /* Set the Output Compare Polarity */ + tmpccer |= (OC_Config->OCPolarity << 8U); + + if (IS_TIM_CCXN_INSTANCE(TIMx, TIM_CHANNEL_3)) + { + assert_param(IS_TIM_OCN_POLARITY(OC_Config->OCNPolarity)); + + /* Reset the Output N Polarity level */ + tmpccer &= ~TIM_CCER_CC3NP; + /* Set the Output N Polarity */ + tmpccer |= (OC_Config->OCNPolarity << 8U); + /* Reset the Output N State */ + tmpccer &= ~TIM_CCER_CC3NE; + } + + if (IS_TIM_BREAK_INSTANCE(TIMx)) + { + /* Check parameters */ + assert_param(IS_TIM_OCNIDLE_STATE(OC_Config->OCNIdleState)); + assert_param(IS_TIM_OCIDLE_STATE(OC_Config->OCIdleState)); + + /* Reset the Output Compare and Output Compare N IDLE State */ + tmpcr2 &= ~TIM_CR2_OIS3; + tmpcr2 &= ~TIM_CR2_OIS3N; + /* Set the Output Idle state */ + tmpcr2 |= (OC_Config->OCIdleState << 4U); + /* Set the Output N Idle state */ + tmpcr2 |= (OC_Config->OCNIdleState << 4U); + } + + /* Write to TIMx CR2 */ + TIMx->CR2 = tmpcr2; + + /* Write to TIMx CCMR2 */ + TIMx->CCMR2 = tmpccmrx; + + /* Set the Capture Compare Register value */ + TIMx->CCR3 = OC_Config->Pulse; + + /* Write to TIMx CCER */ + TIMx->CCER = tmpccer; +} + +/** + * @brief Timer Output Compare 4 configuration + * @param TIMx to select the TIM peripheral + * @param OC_Config The ouput configuration structure + * @retval None + */ +static void TIM_OC4_SetConfig(TIM_TypeDef *TIMx, TIM_OC_InitTypeDef *OC_Config) +{ + uint32_t tmpccmrx; + uint32_t tmpccer; + uint32_t tmpcr2; + + /* Disable the Channel 4: Reset the CC4E Bit */ + TIMx->CCER &= ~TIM_CCER_CC4E; + + /* Get the TIMx CCER register value */ + tmpccer = TIMx->CCER; + /* Get the TIMx CR2 register value */ + tmpcr2 = TIMx->CR2; + + /* Get the TIMx CCMR2 register value */ + tmpccmrx = TIMx->CCMR2; + + /* Reset the Output Compare mode and Capture/Compare selection Bits */ + tmpccmrx &= ~TIM_CCMR2_OC4M; + tmpccmrx &= ~TIM_CCMR2_CC4S; + + /* Select the Output Compare Mode */ + tmpccmrx |= (OC_Config->OCMode << 8U); + + /* Reset the Output Polarity level */ + tmpccer &= ~TIM_CCER_CC4P; + /* Set the Output Compare Polarity */ + tmpccer |= (OC_Config->OCPolarity << 12U); + + if (IS_TIM_BREAK_INSTANCE(TIMx)) + { + /* Check parameters */ + assert_param(IS_TIM_OCIDLE_STATE(OC_Config->OCIdleState)); + + /* Reset the Output Compare IDLE State */ + tmpcr2 &= ~TIM_CR2_OIS4; + + /* Set the Output Idle state */ + tmpcr2 |= (OC_Config->OCIdleState << 6U); + } + + /* Write to TIMx CR2 */ + TIMx->CR2 = tmpcr2; + + /* Write to TIMx CCMR2 */ + TIMx->CCMR2 = tmpccmrx; + + /* Set the Capture Compare Register value */ + TIMx->CCR4 = OC_Config->Pulse; + + /* Write to TIMx CCER */ + TIMx->CCER = tmpccer; +} + +/** + * @brief Slave Timer configuration function + * @param htim TIM handle + * @param sSlaveConfig Slave timer configuration + * @retval None + */ +static HAL_StatusTypeDef TIM_SlaveTimer_SetConfig(TIM_HandleTypeDef *htim, + TIM_SlaveConfigTypeDef *sSlaveConfig) +{ + uint32_t tmpsmcr; + uint32_t tmpccmr1; + uint32_t tmpccer; + + /* Get the TIMx SMCR register value */ + tmpsmcr = htim->Instance->SMCR; + + /* Reset the Trigger Selection Bits */ + tmpsmcr &= ~TIM_SMCR_TS; + /* Set the Input Trigger source */ + tmpsmcr |= sSlaveConfig->InputTrigger; + + /* Reset the slave mode Bits */ + tmpsmcr &= ~TIM_SMCR_SMS; + /* Set the slave mode */ + tmpsmcr |= sSlaveConfig->SlaveMode; + + /* Write to TIMx SMCR */ + htim->Instance->SMCR = tmpsmcr; + + /* Configure the trigger prescaler, filter, and polarity */ + switch (sSlaveConfig->InputTrigger) + { + case TIM_TS_ETRF: + { + /* Check the parameters */ + assert_param(IS_TIM_CLOCKSOURCE_ETRMODE1_INSTANCE(htim->Instance)); + assert_param(IS_TIM_TRIGGERPRESCALER(sSlaveConfig->TriggerPrescaler)); + assert_param(IS_TIM_TRIGGERPOLARITY(sSlaveConfig->TriggerPolarity)); + assert_param(IS_TIM_TRIGGERFILTER(sSlaveConfig->TriggerFilter)); + /* Configure the ETR Trigger source */ + TIM_ETR_SetConfig(htim->Instance, + sSlaveConfig->TriggerPrescaler, + sSlaveConfig->TriggerPolarity, + sSlaveConfig->TriggerFilter); + break; + } + + case TIM_TS_TI1F_ED: + { + /* Check the parameters */ + assert_param(IS_TIM_CC1_INSTANCE(htim->Instance)); + assert_param(IS_TIM_TRIGGERFILTER(sSlaveConfig->TriggerFilter)); + + if(sSlaveConfig->SlaveMode == TIM_SLAVEMODE_GATED) + { + return HAL_ERROR; + } + + /* Disable the Channel 1: Reset the CC1E Bit */ + tmpccer = htim->Instance->CCER; + htim->Instance->CCER &= ~TIM_CCER_CC1E; + tmpccmr1 = htim->Instance->CCMR1; + + /* Set the filter */ + tmpccmr1 &= ~TIM_CCMR1_IC1F; + tmpccmr1 |= ((sSlaveConfig->TriggerFilter) << 4U); + + /* Write to TIMx CCMR1 and CCER registers */ + htim->Instance->CCMR1 = tmpccmr1; + htim->Instance->CCER = tmpccer; + break; + } + + case TIM_TS_TI1FP1: + { + /* Check the parameters */ + assert_param(IS_TIM_CC1_INSTANCE(htim->Instance)); + assert_param(IS_TIM_TRIGGERPOLARITY(sSlaveConfig->TriggerPolarity)); + assert_param(IS_TIM_TRIGGERFILTER(sSlaveConfig->TriggerFilter)); + + /* Configure TI1 Filter and Polarity */ + TIM_TI1_ConfigInputStage(htim->Instance, + sSlaveConfig->TriggerPolarity, + sSlaveConfig->TriggerFilter); + break; + } + + case TIM_TS_TI2FP2: + { + /* Check the parameters */ + assert_param(IS_TIM_CC2_INSTANCE(htim->Instance)); + assert_param(IS_TIM_TRIGGERPOLARITY(sSlaveConfig->TriggerPolarity)); + assert_param(IS_TIM_TRIGGERFILTER(sSlaveConfig->TriggerFilter)); + + /* Configure TI2 Filter and Polarity */ + TIM_TI2_ConfigInputStage(htim->Instance, + sSlaveConfig->TriggerPolarity, + sSlaveConfig->TriggerFilter); + break; + } + + case TIM_TS_ITR0: + case TIM_TS_ITR1: + case TIM_TS_ITR2: + case TIM_TS_ITR3: + { + /* Check the parameter */ + assert_param(IS_TIM_CC2_INSTANCE(htim->Instance)); + break; + } + + default: + break; + } + return HAL_OK; +} + +/** + * @brief Configure the TI1 as Input. + * @param TIMx to select the TIM peripheral. + * @param TIM_ICPolarity The Input Polarity. + * This parameter can be one of the following values: + * @arg TIM_ICPOLARITY_RISING + * @arg TIM_ICPOLARITY_FALLING + * @arg TIM_ICPOLARITY_BOTHEDGE + * @param TIM_ICSelection specifies the input to be used. + * This parameter can be one of the following values: + * @arg TIM_ICSELECTION_DIRECTTI: TIM Input 1 is selected to be connected to IC1. + * @arg TIM_ICSELECTION_INDIRECTTI: TIM Input 1 is selected to be connected to IC2. + * @arg TIM_ICSELECTION_TRC: TIM Input 1 is selected to be connected to TRC. + * @param TIM_ICFilter Specifies the Input Capture Filter. + * This parameter must be a value between 0x00 and 0x0F. + * @retval None + * @note TIM_ICFilter and TIM_ICPolarity are not used in INDIRECT mode as TI2FP1 + * (on channel2 path) is used as the input signal. Therefore CCMR1 must be + * protected against un-initialized filter and polarity values. + */ +void TIM_TI1_SetConfig(TIM_TypeDef *TIMx, uint32_t TIM_ICPolarity, uint32_t TIM_ICSelection, + uint32_t TIM_ICFilter) +{ + uint32_t tmpccmr1; + uint32_t tmpccer; + + /* Disable the Channel 1: Reset the CC1E Bit */ + TIMx->CCER &= ~TIM_CCER_CC1E; + tmpccmr1 = TIMx->CCMR1; + tmpccer = TIMx->CCER; + + /* Select the Input */ + if (IS_TIM_CC2_INSTANCE(TIMx) != RESET) + { + tmpccmr1 &= ~TIM_CCMR1_CC1S; + tmpccmr1 |= TIM_ICSelection; + } + else + { + tmpccmr1 |= TIM_CCMR1_CC1S_0; + } + + /* Set the filter */ + tmpccmr1 &= ~TIM_CCMR1_IC1F; + tmpccmr1 |= ((TIM_ICFilter << 4U) & TIM_CCMR1_IC1F); + + /* Select the Polarity and set the CC1E Bit */ + tmpccer &= ~(TIM_CCER_CC1P | TIM_CCER_CC1NP); + tmpccer |= (TIM_ICPolarity & (TIM_CCER_CC1P | TIM_CCER_CC1NP)); + + /* Write to TIMx CCMR1 and CCER registers */ + TIMx->CCMR1 = tmpccmr1; + TIMx->CCER = tmpccer; +} + +/** + * @brief Configure the Polarity and Filter for TI1. + * @param TIMx to select the TIM peripheral. + * @param TIM_ICPolarity The Input Polarity. + * This parameter can be one of the following values: + * @arg TIM_ICPOLARITY_RISING + * @arg TIM_ICPOLARITY_FALLING + * @arg TIM_ICPOLARITY_BOTHEDGE + * @param TIM_ICFilter Specifies the Input Capture Filter. + * This parameter must be a value between 0x00 and 0x0F. + * @retval None + */ +static void TIM_TI1_ConfigInputStage(TIM_TypeDef *TIMx, uint32_t TIM_ICPolarity, uint32_t TIM_ICFilter) +{ + uint32_t tmpccmr1; + uint32_t tmpccer; + + /* Disable the Channel 1: Reset the CC1E Bit */ + tmpccer = TIMx->CCER; + TIMx->CCER &= ~TIM_CCER_CC1E; + tmpccmr1 = TIMx->CCMR1; + + /* Set the filter */ + tmpccmr1 &= ~TIM_CCMR1_IC1F; + tmpccmr1 |= (TIM_ICFilter << 4U); + + /* Select the Polarity and set the CC1E Bit */ + tmpccer &= ~(TIM_CCER_CC1P | TIM_CCER_CC1NP); + tmpccer |= TIM_ICPolarity; + + /* Write to TIMx CCMR1 and CCER registers */ + TIMx->CCMR1 = tmpccmr1; + TIMx->CCER = tmpccer; +} + +/** + * @brief Configure the TI2 as Input. + * @param TIMx to select the TIM peripheral + * @param TIM_ICPolarity The Input Polarity. + * This parameter can be one of the following values: + * @arg TIM_ICPOLARITY_RISING + * @arg TIM_ICPOLARITY_FALLING + * @arg TIM_ICPOLARITY_BOTHEDGE + * @param TIM_ICSelection specifies the input to be used. + * This parameter can be one of the following values: + * @arg TIM_ICSELECTION_DIRECTTI: TIM Input 2 is selected to be connected to IC2. + * @arg TIM_ICSELECTION_INDIRECTTI: TIM Input 2 is selected to be connected to IC1. + * @arg TIM_ICSELECTION_TRC: TIM Input 2 is selected to be connected to TRC. + * @param TIM_ICFilter Specifies the Input Capture Filter. + * This parameter must be a value between 0x00 and 0x0F. + * @retval None + * @note TIM_ICFilter and TIM_ICPolarity are not used in INDIRECT mode as TI1FP2 + * (on channel1 path) is used as the input signal. Therefore CCMR1 must be + * protected against un-initialized filter and polarity values. + */ +static void TIM_TI2_SetConfig(TIM_TypeDef *TIMx, uint32_t TIM_ICPolarity, uint32_t TIM_ICSelection, + uint32_t TIM_ICFilter) +{ + uint32_t tmpccmr1; + uint32_t tmpccer; + + /* Disable the Channel 2: Reset the CC2E Bit */ + TIMx->CCER &= ~TIM_CCER_CC2E; + tmpccmr1 = TIMx->CCMR1; + tmpccer = TIMx->CCER; + + /* Select the Input */ + tmpccmr1 &= ~TIM_CCMR1_CC2S; + tmpccmr1 |= (TIM_ICSelection << 8U); + + /* Set the filter */ + tmpccmr1 &= ~TIM_CCMR1_IC2F; + tmpccmr1 |= ((TIM_ICFilter << 12U) & TIM_CCMR1_IC2F); + + /* Select the Polarity and set the CC2E Bit */ + tmpccer &= ~(TIM_CCER_CC2P | TIM_CCER_CC2NP); + tmpccer |= ((TIM_ICPolarity << 4U) & (TIM_CCER_CC2P | TIM_CCER_CC2NP)); + + /* Write to TIMx CCMR1 and CCER registers */ + TIMx->CCMR1 = tmpccmr1 ; + TIMx->CCER = tmpccer; +} + +/** + * @brief Configure the Polarity and Filter for TI2. + * @param TIMx to select the TIM peripheral. + * @param TIM_ICPolarity The Input Polarity. + * This parameter can be one of the following values: + * @arg TIM_ICPOLARITY_RISING + * @arg TIM_ICPOLARITY_FALLING + * @arg TIM_ICPOLARITY_BOTHEDGE + * @param TIM_ICFilter Specifies the Input Capture Filter. + * This parameter must be a value between 0x00 and 0x0F. + * @retval None + */ +static void TIM_TI2_ConfigInputStage(TIM_TypeDef *TIMx, uint32_t TIM_ICPolarity, uint32_t TIM_ICFilter) +{ + uint32_t tmpccmr1; + uint32_t tmpccer; + + /* Disable the Channel 2: Reset the CC2E Bit */ + TIMx->CCER &= ~TIM_CCER_CC2E; + tmpccmr1 = TIMx->CCMR1; + tmpccer = TIMx->CCER; + + /* Set the filter */ + tmpccmr1 &= ~TIM_CCMR1_IC2F; + tmpccmr1 |= (TIM_ICFilter << 12U); + + /* Select the Polarity and set the CC2E Bit */ + tmpccer &= ~(TIM_CCER_CC2P | TIM_CCER_CC2NP); + tmpccer |= (TIM_ICPolarity << 4U); + + /* Write to TIMx CCMR1 and CCER registers */ + TIMx->CCMR1 = tmpccmr1 ; + TIMx->CCER = tmpccer; +} + +/** + * @brief Configure the TI3 as Input. + * @param TIMx to select the TIM peripheral + * @param TIM_ICPolarity The Input Polarity. + * This parameter can be one of the following values: + * @arg TIM_ICPOLARITY_RISING + * @arg TIM_ICPOLARITY_FALLING + * @arg TIM_ICPOLARITY_BOTHEDGE + * @param TIM_ICSelection specifies the input to be used. + * This parameter can be one of the following values: + * @arg TIM_ICSELECTION_DIRECTTI: TIM Input 3 is selected to be connected to IC3. + * @arg TIM_ICSELECTION_INDIRECTTI: TIM Input 3 is selected to be connected to IC4. + * @arg TIM_ICSELECTION_TRC: TIM Input 3 is selected to be connected to TRC. + * @param TIM_ICFilter Specifies the Input Capture Filter. + * This parameter must be a value between 0x00 and 0x0F. + * @retval None + * @note TIM_ICFilter and TIM_ICPolarity are not used in INDIRECT mode as TI3FP4 + * (on channel1 path) is used as the input signal. Therefore CCMR2 must be + * protected against un-initialized filter and polarity values. + */ +static void TIM_TI3_SetConfig(TIM_TypeDef *TIMx, uint32_t TIM_ICPolarity, uint32_t TIM_ICSelection, + uint32_t TIM_ICFilter) +{ + uint32_t tmpccmr2; + uint32_t tmpccer; + + /* Disable the Channel 3: Reset the CC3E Bit */ + TIMx->CCER &= ~TIM_CCER_CC3E; + tmpccmr2 = TIMx->CCMR2; + tmpccer = TIMx->CCER; + + /* Select the Input */ + tmpccmr2 &= ~TIM_CCMR2_CC3S; + tmpccmr2 |= TIM_ICSelection; + + /* Set the filter */ + tmpccmr2 &= ~TIM_CCMR2_IC3F; + tmpccmr2 |= ((TIM_ICFilter << 4U) & TIM_CCMR2_IC3F); + + /* Select the Polarity and set the CC3E Bit */ + tmpccer &= ~(TIM_CCER_CC3P | TIM_CCER_CC3NP); + tmpccer |= ((TIM_ICPolarity << 8U) & (TIM_CCER_CC3P | TIM_CCER_CC3NP)); + + /* Write to TIMx CCMR2 and CCER registers */ + TIMx->CCMR2 = tmpccmr2; + TIMx->CCER = tmpccer; +} + +/** + * @brief Configure the TI4 as Input. + * @param TIMx to select the TIM peripheral + * @param TIM_ICPolarity The Input Polarity. + * This parameter can be one of the following values: + * @arg TIM_ICPOLARITY_RISING + * @arg TIM_ICPOLARITY_FALLING + * @arg TIM_ICPOLARITY_BOTHEDGE + * @param TIM_ICSelection specifies the input to be used. + * This parameter can be one of the following values: + * @arg TIM_ICSELECTION_DIRECTTI: TIM Input 4 is selected to be connected to IC4. + * @arg TIM_ICSELECTION_INDIRECTTI: TIM Input 4 is selected to be connected to IC3. + * @arg TIM_ICSELECTION_TRC: TIM Input 4 is selected to be connected to TRC. + * @param TIM_ICFilter Specifies the Input Capture Filter. + * This parameter must be a value between 0x00 and 0x0F. + * @note TIM_ICFilter and TIM_ICPolarity are not used in INDIRECT mode as TI4FP3 + * (on channel1 path) is used as the input signal. Therefore CCMR2 must be + * protected against un-initialized filter and polarity values. + * @retval None + */ +static void TIM_TI4_SetConfig(TIM_TypeDef *TIMx, uint32_t TIM_ICPolarity, uint32_t TIM_ICSelection, + uint32_t TIM_ICFilter) +{ + uint32_t tmpccmr2; + uint32_t tmpccer; + + /* Disable the Channel 4: Reset the CC4E Bit */ + TIMx->CCER &= ~TIM_CCER_CC4E; + tmpccmr2 = TIMx->CCMR2; + tmpccer = TIMx->CCER; + + /* Select the Input */ + tmpccmr2 &= ~TIM_CCMR2_CC4S; + tmpccmr2 |= (TIM_ICSelection << 8U); + + /* Set the filter */ + tmpccmr2 &= ~TIM_CCMR2_IC4F; + tmpccmr2 |= ((TIM_ICFilter << 12U) & TIM_CCMR2_IC4F); + + /* Select the Polarity and set the CC4E Bit */ + tmpccer &= ~(TIM_CCER_CC4P | TIM_CCER_CC4NP); + tmpccer |= ((TIM_ICPolarity << 12U) & (TIM_CCER_CC4P | TIM_CCER_CC4NP)); + + /* Write to TIMx CCMR2 and CCER registers */ + TIMx->CCMR2 = tmpccmr2; + TIMx->CCER = tmpccer ; +} + +/** + * @brief Selects the Input Trigger source + * @param TIMx to select the TIM peripheral + * @param InputTriggerSource The Input Trigger source. + * This parameter can be one of the following values: + * @arg TIM_TS_ITR0: Internal Trigger 0 + * @arg TIM_TS_ITR1: Internal Trigger 1 + * @arg TIM_TS_ITR2: Internal Trigger 2 + * @arg TIM_TS_ITR3: Internal Trigger 3 + * @arg TIM_TS_TI1F_ED: TI1 Edge Detector + * @arg TIM_TS_TI1FP1: Filtered Timer Input 1 + * @arg TIM_TS_TI2FP2: Filtered Timer Input 2 + * @arg TIM_TS_ETRF: External Trigger input + * @retval None + */ +static void TIM_ITRx_SetConfig(TIM_TypeDef *TIMx, uint32_t InputTriggerSource) +{ + uint32_t tmpsmcr; + + /* Get the TIMx SMCR register value */ + tmpsmcr = TIMx->SMCR; + /* Reset the TS Bits */ + tmpsmcr &= ~TIM_SMCR_TS; + /* Set the Input Trigger source and the slave mode*/ + tmpsmcr |= (InputTriggerSource | TIM_SLAVEMODE_EXTERNAL1); + /* Write to TIMx SMCR */ + TIMx->SMCR = tmpsmcr; +} +/** + * @brief Configures the TIMx External Trigger (ETR). + * @param TIMx to select the TIM peripheral + * @param TIM_ExtTRGPrescaler The external Trigger Prescaler. + * This parameter can be one of the following values: + * @arg TIM_ETRPRESCALER_DIV1: ETRP Prescaler OFF. + * @arg TIM_ETRPRESCALER_DIV2: ETRP frequency divided by 2. + * @arg TIM_ETRPRESCALER_DIV4: ETRP frequency divided by 4. + * @arg TIM_ETRPRESCALER_DIV8: ETRP frequency divided by 8. + * @param TIM_ExtTRGPolarity The external Trigger Polarity. + * This parameter can be one of the following values: + * @arg TIM_ETRPOLARITY_INVERTED: active low or falling edge active. + * @arg TIM_ETRPOLARITY_NONINVERTED: active high or rising edge active. + * @param ExtTRGFilter External Trigger Filter. + * This parameter must be a value between 0x00 and 0x0F + * @retval None + */ +void TIM_ETR_SetConfig(TIM_TypeDef *TIMx, uint32_t TIM_ExtTRGPrescaler, + uint32_t TIM_ExtTRGPolarity, uint32_t ExtTRGFilter) +{ + uint32_t tmpsmcr; + + tmpsmcr = TIMx->SMCR; + + /* Reset the ETR Bits */ + tmpsmcr &= ~(TIM_SMCR_ETF | TIM_SMCR_ETPS | TIM_SMCR_ECE | TIM_SMCR_ETP); + + /* Set the Prescaler, the Filter value and the Polarity */ + tmpsmcr |= (uint32_t)(TIM_ExtTRGPrescaler | (TIM_ExtTRGPolarity | (ExtTRGFilter << 8U))); + + /* Write to TIMx SMCR */ + TIMx->SMCR = tmpsmcr; +} + +/** + * @brief Enables or disables the TIM Capture Compare Channel x. + * @param TIMx to select the TIM peripheral + * @param Channel specifies the TIM Channel + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 + * @arg TIM_CHANNEL_2: TIM Channel 2 + * @arg TIM_CHANNEL_3: TIM Channel 3 + * @arg TIM_CHANNEL_4: TIM Channel 4 + * @param ChannelState specifies the TIM Channel CCxE bit new state. + * This parameter can be: TIM_CCx_ENABLE or TIM_CCx_DISABLE. + * @retval None + */ +void TIM_CCxChannelCmd(TIM_TypeDef *TIMx, uint32_t Channel, uint32_t ChannelState) +{ + uint32_t tmp; + + /* Check the parameters */ + assert_param(IS_TIM_CC1_INSTANCE(TIMx)); + assert_param(IS_TIM_CHANNELS(Channel)); + + tmp = TIM_CCER_CC1E << (Channel & 0x1FU); /* 0x1FU = 31 bits max shift */ + + /* Reset the CCxE Bit */ + TIMx->CCER &= ~tmp; + + /* Set or reset the CCxE Bit */ + TIMx->CCER |= (uint32_t)(ChannelState << (Channel & 0x1FU)); /* 0x1FU = 31 bits max shift */ +} + +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) +/** + * @brief Reset interrupt callbacks to the legacy weak callbacks. + * @param htim pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @retval None + */ +void TIM_ResetCallback(TIM_HandleTypeDef *htim) +{ + /* Reset the TIM callback to the legacy weak callbacks */ + htim->PeriodElapsedCallback = HAL_TIM_PeriodElapsedCallback; /* Legacy weak PeriodElapsedCallback */ + htim->PeriodElapsedHalfCpltCallback = HAL_TIM_PeriodElapsedHalfCpltCallback; /* Legacy weak PeriodElapsedHalfCpltCallback */ + htim->TriggerCallback = HAL_TIM_TriggerCallback; /* Legacy weak TriggerCallback */ + htim->TriggerHalfCpltCallback = HAL_TIM_TriggerHalfCpltCallback; /* Legacy weak TriggerHalfCpltCallback */ + htim->IC_CaptureCallback = HAL_TIM_IC_CaptureCallback; /* Legacy weak IC_CaptureCallback */ + htim->IC_CaptureHalfCpltCallback = HAL_TIM_IC_CaptureHalfCpltCallback; /* Legacy weak IC_CaptureHalfCpltCallback */ + htim->OC_DelayElapsedCallback = HAL_TIM_OC_DelayElapsedCallback; /* Legacy weak OC_DelayElapsedCallback */ + htim->PWM_PulseFinishedCallback = HAL_TIM_PWM_PulseFinishedCallback; /* Legacy weak PWM_PulseFinishedCallback */ + htim->PWM_PulseFinishedHalfCpltCallback = HAL_TIM_PWM_PulseFinishedHalfCpltCallback; /* Legacy weak PWM_PulseFinishedHalfCpltCallback */ + htim->ErrorCallback = HAL_TIM_ErrorCallback; /* Legacy weak ErrorCallback */ + htim->CommutationCallback = HAL_TIMEx_CommutCallback; /* Legacy weak CommutationCallback */ + htim->CommutationHalfCpltCallback = HAL_TIMEx_CommutHalfCpltCallback; /* Legacy weak CommutationHalfCpltCallback */ + htim->BreakCallback = HAL_TIMEx_BreakCallback; /* Legacy weak BreakCallback */ +} +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + +/** + * @} + */ + +#endif /* HAL_TIM_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.c b/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.c new file mode 100644 index 0000000..ba50c15 --- /dev/null +++ b/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.c @@ -0,0 +1,1939 @@ +/** + ****************************************************************************** + * @file stm32f0xx_hal_tim_ex.c + * @author MCD Application Team + * @brief TIM HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the Timer Extended peripheral: + * + Time Hall Sensor Interface Initialization + * + Time Hall Sensor Interface Start + * + Time Complementary signal break and dead time configuration + * + Time Master and Slave synchronization configuration + * + Time OCRef clear configuration + * + Timer remapping capabilities configuration + @verbatim + ============================================================================== + ##### TIMER Extended features ##### + ============================================================================== + [..] + The Timer Extended features include: + (#) Complementary outputs with programmable dead-time for : + (++) Output Compare + (++) PWM generation (Edge and Center-aligned Mode) + (++) One-pulse mode output + (#) Synchronization circuit to control the timer with external signals and to + interconnect several timers together. + (#) Break input to put the timer output signals in reset state or in a known state. + (#) Supports incremental (quadrature) encoder and hall-sensor circuitry for + positioning purposes + + ##### How to use this driver ##### + ============================================================================== + [..] + (#) Initialize the TIM low level resources by implementing the following functions + depending on the selected feature: + (++) Hall Sensor output : HAL_TIMEx_HallSensor_MspInit() + + (#) Initialize the TIM low level resources : + (##) Enable the TIM interface clock using __HAL_RCC_TIMx_CLK_ENABLE(); + (##) TIM pins configuration + (+++) Enable the clock for the TIM GPIOs using the following function: + __HAL_RCC_GPIOx_CLK_ENABLE(); + (+++) Configure these TIM pins in Alternate function mode using HAL_GPIO_Init(); + + (#) The external Clock can be configured, if needed (the default clock is the + internal clock from the APBx), using the following function: + HAL_TIM_ConfigClockSource, the clock configuration should be done before + any start function. + + (#) Configure the TIM in the desired functioning mode using one of the + initialization function of this driver: + (++) HAL_TIMEx_HallSensor_Init() and HAL_TIMEx_ConfigCommutEvent(): to use the + Timer Hall Sensor Interface and the commutation event with the corresponding + Interrupt and DMA request if needed (Note that One Timer is used to interface + with the Hall sensor Interface and another Timer should be used to use + the commutation event). + + (#) Activate the TIM peripheral using one of the start functions: + (++) Complementary Output Compare : HAL_TIMEx_OCN_Start(), HAL_TIMEx_OCN_Start_DMA(), HAL_TIMEx_OC_Start_IT() + (++) Complementary PWM generation : HAL_TIMEx_PWMN_Start(), HAL_TIMEx_PWMN_Start_DMA(), HAL_TIMEx_PWMN_Start_IT() + (++) Complementary One-pulse mode output : HAL_TIMEx_OnePulseN_Start(), HAL_TIMEx_OnePulseN_Start_IT() + (++) Hall Sensor output : HAL_TIMEx_HallSensor_Start(), HAL_TIMEx_HallSensor_Start_DMA(), HAL_TIMEx_HallSensor_Start_IT(). + + @endverbatim + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2016 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f0xx_hal.h" + +/** @addtogroup STM32F0xx_HAL_Driver + * @{ + */ + +/** @defgroup TIMEx TIMEx + * @brief TIM Extended HAL module driver + * @{ + */ + +#ifdef HAL_TIM_MODULE_ENABLED + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +static void TIM_CCxNChannelCmd(TIM_TypeDef *TIMx, uint32_t Channel, uint32_t ChannelNState); + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup TIMEx_Exported_Functions TIM Extended Exported Functions + * @{ + */ + +/** @defgroup TIMEx_Exported_Functions_Group1 Extended Timer Hall Sensor functions + * @brief Timer Hall Sensor functions + * +@verbatim + ============================================================================== + ##### Timer Hall Sensor functions ##### + ============================================================================== + [..] + This section provides functions allowing to: + (+) Initialize and configure TIM HAL Sensor. + (+) De-initialize TIM HAL Sensor. + (+) Start the Hall Sensor Interface. + (+) Stop the Hall Sensor Interface. + (+) Start the Hall Sensor Interface and enable interrupts. + (+) Stop the Hall Sensor Interface and disable interrupts. + (+) Start the Hall Sensor Interface and enable DMA transfers. + (+) Stop the Hall Sensor Interface and disable DMA transfers. + +@endverbatim + * @{ + */ +/** + * @brief Initializes the TIM Hall Sensor Interface and initialize the associated handle. + * @param htim TIM Hall Sensor Interface handle + * @param sConfig TIM Hall Sensor configuration structure + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_HallSensor_Init(TIM_HandleTypeDef *htim, TIM_HallSensor_InitTypeDef *sConfig) +{ + TIM_OC_InitTypeDef OC_Config; + + /* Check the TIM handle allocation */ + if (htim == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_TIM_HALL_SENSOR_INTERFACE_INSTANCE(htim->Instance)); + assert_param(IS_TIM_COUNTER_MODE(htim->Init.CounterMode)); + assert_param(IS_TIM_CLOCKDIVISION_DIV(htim->Init.ClockDivision)); + assert_param(IS_TIM_AUTORELOAD_PRELOAD(htim->Init.AutoReloadPreload)); + assert_param(IS_TIM_IC_POLARITY(sConfig->IC1Polarity)); + assert_param(IS_TIM_IC_PRESCALER(sConfig->IC1Prescaler)); + assert_param(IS_TIM_IC_FILTER(sConfig->IC1Filter)); + + if (htim->State == HAL_TIM_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + htim->Lock = HAL_UNLOCKED; + +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + /* Reset interrupt callbacks to legacy week callbacks */ + TIM_ResetCallback(htim); + + if (htim->HallSensor_MspInitCallback == NULL) + { + htim->HallSensor_MspInitCallback = HAL_TIMEx_HallSensor_MspInit; + } + /* Init the low level hardware : GPIO, CLOCK, NVIC */ + htim->HallSensor_MspInitCallback(htim); +#else + /* Init the low level hardware : GPIO, CLOCK, NVIC and DMA */ + HAL_TIMEx_HallSensor_MspInit(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + } + + /* Set the TIM state */ + htim->State = HAL_TIM_STATE_BUSY; + + /* Configure the Time base in the Encoder Mode */ + TIM_Base_SetConfig(htim->Instance, &htim->Init); + + /* Configure the Channel 1 as Input Channel to interface with the three Outputs of the Hall sensor */ + TIM_TI1_SetConfig(htim->Instance, sConfig->IC1Polarity, TIM_ICSELECTION_TRC, sConfig->IC1Filter); + + /* Reset the IC1PSC Bits */ + htim->Instance->CCMR1 &= ~TIM_CCMR1_IC1PSC; + /* Set the IC1PSC value */ + htim->Instance->CCMR1 |= sConfig->IC1Prescaler; + + /* Enable the Hall sensor interface (XOR function of the three inputs) */ + htim->Instance->CR2 |= TIM_CR2_TI1S; + + /* Select the TIM_TS_TI1F_ED signal as Input trigger for the TIM */ + htim->Instance->SMCR &= ~TIM_SMCR_TS; + htim->Instance->SMCR |= TIM_TS_TI1F_ED; + + /* Use the TIM_TS_TI1F_ED signal to reset the TIM counter each edge detection */ + htim->Instance->SMCR &= ~TIM_SMCR_SMS; + htim->Instance->SMCR |= TIM_SLAVEMODE_RESET; + + /* Program channel 2 in PWM 2 mode with the desired Commutation_Delay*/ + OC_Config.OCFastMode = TIM_OCFAST_DISABLE; + OC_Config.OCIdleState = TIM_OCIDLESTATE_RESET; + OC_Config.OCMode = TIM_OCMODE_PWM2; + OC_Config.OCNIdleState = TIM_OCNIDLESTATE_RESET; + OC_Config.OCNPolarity = TIM_OCNPOLARITY_HIGH; + OC_Config.OCPolarity = TIM_OCPOLARITY_HIGH; + OC_Config.Pulse = sConfig->Commutation_Delay; + + TIM_OC2_SetConfig(htim->Instance, &OC_Config); + + /* Select OC2REF as trigger output on TRGO: write the MMS bits in the TIMx_CR2 + register to 101 */ + htim->Instance->CR2 &= ~TIM_CR2_MMS; + htim->Instance->CR2 |= TIM_TRGO_OC2REF; + + /* Initialize the TIM state*/ + htim->State = HAL_TIM_STATE_READY; + + return HAL_OK; +} + +/** + * @brief DeInitializes the TIM Hall Sensor interface + * @param htim TIM Hall Sensor Interface handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_HallSensor_DeInit(TIM_HandleTypeDef *htim) +{ + /* Check the parameters */ + assert_param(IS_TIM_INSTANCE(htim->Instance)); + + htim->State = HAL_TIM_STATE_BUSY; + + /* Disable the TIM Peripheral Clock */ + __HAL_TIM_DISABLE(htim); + +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + if (htim->HallSensor_MspDeInitCallback == NULL) + { + htim->HallSensor_MspDeInitCallback = HAL_TIMEx_HallSensor_MspDeInit; + } + /* DeInit the low level hardware */ + htim->HallSensor_MspDeInitCallback(htim); +#else + /* DeInit the low level hardware: GPIO, CLOCK, NVIC */ + HAL_TIMEx_HallSensor_MspDeInit(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + + /* Change TIM state */ + htim->State = HAL_TIM_STATE_RESET; + + /* Release Lock */ + __HAL_UNLOCK(htim); + + return HAL_OK; +} + +/** + * @brief Initializes the TIM Hall Sensor MSP. + * @param htim TIM Hall Sensor Interface handle + * @retval None + */ +__weak void HAL_TIMEx_HallSensor_MspInit(TIM_HandleTypeDef *htim) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(htim); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_TIMEx_HallSensor_MspInit could be implemented in the user file + */ +} + +/** + * @brief DeInitializes TIM Hall Sensor MSP. + * @param htim TIM Hall Sensor Interface handle + * @retval None + */ +__weak void HAL_TIMEx_HallSensor_MspDeInit(TIM_HandleTypeDef *htim) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(htim); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_TIMEx_HallSensor_MspDeInit could be implemented in the user file + */ +} + +/** + * @brief Starts the TIM Hall Sensor Interface. + * @param htim TIM Hall Sensor Interface handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_HallSensor_Start(TIM_HandleTypeDef *htim) +{ + uint32_t tmpsmcr; + + /* Check the parameters */ + assert_param(IS_TIM_HALL_SENSOR_INTERFACE_INSTANCE(htim->Instance)); + + /* Enable the Input Capture channel 1 + (in the Hall Sensor Interface the three possible channels that can be used are TIM_CHANNEL_1, TIM_CHANNEL_2 and TIM_CHANNEL_3) */ + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_ENABLE); + + /* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */ + tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS; + if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr)) + { + __HAL_TIM_ENABLE(htim); + } + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stops the TIM Hall sensor Interface. + * @param htim TIM Hall Sensor Interface handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_HallSensor_Stop(TIM_HandleTypeDef *htim) +{ + /* Check the parameters */ + assert_param(IS_TIM_HALL_SENSOR_INTERFACE_INSTANCE(htim->Instance)); + + /* Disable the Input Capture channels 1, 2 and 3 + (in the Hall Sensor Interface the three possible channels that can be used are TIM_CHANNEL_1, TIM_CHANNEL_2 and TIM_CHANNEL_3) */ + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_DISABLE); + + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Starts the TIM Hall Sensor Interface in interrupt mode. + * @param htim TIM Hall Sensor Interface handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_HallSensor_Start_IT(TIM_HandleTypeDef *htim) +{ + uint32_t tmpsmcr; + + /* Check the parameters */ + assert_param(IS_TIM_HALL_SENSOR_INTERFACE_INSTANCE(htim->Instance)); + + /* Enable the capture compare Interrupts 1 event */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC1); + + /* Enable the Input Capture channel 1 + (in the Hall Sensor Interface the three possible channels that can be used are TIM_CHANNEL_1, TIM_CHANNEL_2 and TIM_CHANNEL_3) */ + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_ENABLE); + + /* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */ + tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS; + if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr)) + { + __HAL_TIM_ENABLE(htim); + } + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stops the TIM Hall Sensor Interface in interrupt mode. + * @param htim TIM Hall Sensor Interface handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_HallSensor_Stop_IT(TIM_HandleTypeDef *htim) +{ + /* Check the parameters */ + assert_param(IS_TIM_HALL_SENSOR_INTERFACE_INSTANCE(htim->Instance)); + + /* Disable the Input Capture channel 1 + (in the Hall Sensor Interface the three possible channels that can be used are TIM_CHANNEL_1, TIM_CHANNEL_2 and TIM_CHANNEL_3) */ + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_DISABLE); + + /* Disable the capture compare Interrupts event */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC1); + + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Starts the TIM Hall Sensor Interface in DMA mode. + * @param htim TIM Hall Sensor Interface handle + * @param pData The destination Buffer address. + * @param Length The length of data to be transferred from TIM peripheral to memory. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_HallSensor_Start_DMA(TIM_HandleTypeDef *htim, uint32_t *pData, uint16_t Length) +{ + uint32_t tmpsmcr; + + /* Check the parameters */ + assert_param(IS_TIM_HALL_SENSOR_INTERFACE_INSTANCE(htim->Instance)); + + if (htim->State == HAL_TIM_STATE_BUSY) + { + return HAL_BUSY; + } + else if (htim->State == HAL_TIM_STATE_READY) + { + if (((uint32_t)pData == 0U) && (Length > 0U)) + { + return HAL_ERROR; + } + else + { + htim->State = HAL_TIM_STATE_BUSY; + } + } + else + { + /* nothing to do */ + } + /* Enable the Input Capture channel 1 + (in the Hall Sensor Interface the three possible channels that can be used are TIM_CHANNEL_1, TIM_CHANNEL_2 and TIM_CHANNEL_3) */ + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_ENABLE); + + /* Set the DMA Input Capture 1 Callbacks */ + htim->hdma[TIM_DMA_ID_CC1]->XferCpltCallback = TIM_DMACaptureCplt; + htim->hdma[TIM_DMA_ID_CC1]->XferHalfCpltCallback = TIM_DMACaptureHalfCplt; + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC1]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA channel for Capture 1*/ + if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC1], (uint32_t)&htim->Instance->CCR1, (uint32_t)pData, Length) != HAL_OK) + { + return HAL_ERROR; + } + /* Enable the capture compare 1 Interrupt */ + __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC1); + + /* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */ + tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS; + if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr)) + { + __HAL_TIM_ENABLE(htim); + } + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stops the TIM Hall Sensor Interface in DMA mode. + * @param htim TIM Hall Sensor Interface handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_HallSensor_Stop_DMA(TIM_HandleTypeDef *htim) +{ + /* Check the parameters */ + assert_param(IS_TIM_HALL_SENSOR_INTERFACE_INSTANCE(htim->Instance)); + + /* Disable the Input Capture channel 1 + (in the Hall Sensor Interface the three possible channels that can be used are TIM_CHANNEL_1, TIM_CHANNEL_2 and TIM_CHANNEL_3) */ + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_DISABLE); + + + /* Disable the capture compare Interrupts 1 event */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC1); + + (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC1]); + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Return function status */ + return HAL_OK; +} + +/** + * @} + */ + +/** @defgroup TIMEx_Exported_Functions_Group2 Extended Timer Complementary Output Compare functions + * @brief Timer Complementary Output Compare functions + * +@verbatim + ============================================================================== + ##### Timer Complementary Output Compare functions ##### + ============================================================================== + [..] + This section provides functions allowing to: + (+) Start the Complementary Output Compare/PWM. + (+) Stop the Complementary Output Compare/PWM. + (+) Start the Complementary Output Compare/PWM and enable interrupts. + (+) Stop the Complementary Output Compare/PWM and disable interrupts. + (+) Start the Complementary Output Compare/PWM and enable DMA transfers. + (+) Stop the Complementary Output Compare/PWM and disable DMA transfers. + +@endverbatim + * @{ + */ + +/** + * @brief Starts the TIM Output Compare signal generation on the complementary + * output. + * @param htim TIM Output Compare handle + * @param Channel TIM Channel to be enabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_OCN_Start(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + uint32_t tmpsmcr; + + /* Check the parameters */ + assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel)); + + /* Enable the Capture compare channel N */ + TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_ENABLE); + + /* Enable the Main Output */ + __HAL_TIM_MOE_ENABLE(htim); + + /* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */ + tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS; + if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr)) + { + __HAL_TIM_ENABLE(htim); + } + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stops the TIM Output Compare signal generation on the complementary + * output. + * @param htim TIM handle + * @param Channel TIM Channel to be disabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_OCN_Stop(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + /* Check the parameters */ + assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel)); + + /* Disable the Capture compare channel N */ + TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_DISABLE); + + /* Disable the Main Output */ + __HAL_TIM_MOE_DISABLE(htim); + + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Starts the TIM Output Compare signal generation in interrupt mode + * on the complementary output. + * @param htim TIM OC handle + * @param Channel TIM Channel to be enabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_OCN_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + uint32_t tmpsmcr; + + /* Check the parameters */ + assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel)); + + switch (Channel) + { + case TIM_CHANNEL_1: + { + /* Enable the TIM Output Compare interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC1); + break; + } + + case TIM_CHANNEL_2: + { + /* Enable the TIM Output Compare interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC2); + break; + } + + case TIM_CHANNEL_3: + { + /* Enable the TIM Output Compare interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC3); + break; + } + + + default: + break; + } + + /* Enable the TIM Break interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_BREAK); + + /* Enable the Capture compare channel N */ + TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_ENABLE); + + /* Enable the Main Output */ + __HAL_TIM_MOE_ENABLE(htim); + + /* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */ + tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS; + if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr)) + { + __HAL_TIM_ENABLE(htim); + } + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stops the TIM Output Compare signal generation in interrupt mode + * on the complementary output. + * @param htim TIM Output Compare handle + * @param Channel TIM Channel to be disabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_OCN_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + uint32_t tmpccer; + /* Check the parameters */ + assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel)); + + switch (Channel) + { + case TIM_CHANNEL_1: + { + /* Disable the TIM Output Compare interrupt */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC1); + break; + } + + case TIM_CHANNEL_2: + { + /* Disable the TIM Output Compare interrupt */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC2); + break; + } + + case TIM_CHANNEL_3: + { + /* Disable the TIM Output Compare interrupt */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC3); + break; + } + + default: + break; + } + + /* Disable the Capture compare channel N */ + TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_DISABLE); + + /* Disable the TIM Break interrupt (only if no more channel is active) */ + tmpccer = htim->Instance->CCER; + if ((tmpccer & (TIM_CCER_CC1NE | TIM_CCER_CC2NE | TIM_CCER_CC3NE)) == (uint32_t)RESET) + { + __HAL_TIM_DISABLE_IT(htim, TIM_IT_BREAK); + } + + /* Disable the Main Output */ + __HAL_TIM_MOE_DISABLE(htim); + + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Starts the TIM Output Compare signal generation in DMA mode + * on the complementary output. + * @param htim TIM Output Compare handle + * @param Channel TIM Channel to be enabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @param pData The source Buffer address. + * @param Length The length of data to be transferred from memory to TIM peripheral + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_OCN_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Channel, uint32_t *pData, uint16_t Length) +{ + uint32_t tmpsmcr; + + /* Check the parameters */ + assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel)); + + if (htim->State == HAL_TIM_STATE_BUSY) + { + return HAL_BUSY; + } + else if (htim->State == HAL_TIM_STATE_READY) + { + if (((uint32_t)pData == 0U) && (Length > 0U)) + { + return HAL_ERROR; + } + else + { + htim->State = HAL_TIM_STATE_BUSY; + } + } + else + { + /* nothing to do */ + } + + switch (Channel) + { + case TIM_CHANNEL_1: + { + /* Set the DMA compare callbacks */ + htim->hdma[TIM_DMA_ID_CC1]->XferCpltCallback = TIM_DMADelayPulseCplt; + htim->hdma[TIM_DMA_ID_CC1]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC1]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA channel */ + if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC1], (uint32_t)pData, (uint32_t)&htim->Instance->CCR1, Length) != HAL_OK) + { + return HAL_ERROR; + } + /* Enable the TIM Output Compare DMA request */ + __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC1); + break; + } + + case TIM_CHANNEL_2: + { + /* Set the DMA compare callbacks */ + htim->hdma[TIM_DMA_ID_CC2]->XferCpltCallback = TIM_DMADelayPulseCplt; + htim->hdma[TIM_DMA_ID_CC2]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC2]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA channel */ + if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC2], (uint32_t)pData, (uint32_t)&htim->Instance->CCR2, Length) != HAL_OK) + { + return HAL_ERROR; + } + /* Enable the TIM Output Compare DMA request */ + __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC2); + break; + } + + case TIM_CHANNEL_3: + { + /* Set the DMA compare callbacks */ + htim->hdma[TIM_DMA_ID_CC3]->XferCpltCallback = TIM_DMADelayPulseCplt; + htim->hdma[TIM_DMA_ID_CC3]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC3]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA channel */ + if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC3], (uint32_t)pData, (uint32_t)&htim->Instance->CCR3, Length) != HAL_OK) + { + return HAL_ERROR; + } + /* Enable the TIM Output Compare DMA request */ + __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC3); + break; + } + + default: + break; + } + + /* Enable the Capture compare channel N */ + TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_ENABLE); + + /* Enable the Main Output */ + __HAL_TIM_MOE_ENABLE(htim); + + /* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */ + tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS; + if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr)) + { + __HAL_TIM_ENABLE(htim); + } + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stops the TIM Output Compare signal generation in DMA mode + * on the complementary output. + * @param htim TIM Output Compare handle + * @param Channel TIM Channel to be disabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_OCN_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + /* Check the parameters */ + assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel)); + + switch (Channel) + { + case TIM_CHANNEL_1: + { + /* Disable the TIM Output Compare DMA request */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC1); + (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC1]); + break; + } + + case TIM_CHANNEL_2: + { + /* Disable the TIM Output Compare DMA request */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC2); + (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC2]); + break; + } + + case TIM_CHANNEL_3: + { + /* Disable the TIM Output Compare DMA request */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC3); + (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC3]); + break; + } + + default: + break; + } + + /* Disable the Capture compare channel N */ + TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_DISABLE); + + /* Disable the Main Output */ + __HAL_TIM_MOE_DISABLE(htim); + + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Change the htim state */ + htim->State = HAL_TIM_STATE_READY; + + /* Return function status */ + return HAL_OK; +} + +/** + * @} + */ + +/** @defgroup TIMEx_Exported_Functions_Group3 Extended Timer Complementary PWM functions + * @brief Timer Complementary PWM functions + * +@verbatim + ============================================================================== + ##### Timer Complementary PWM functions ##### + ============================================================================== + [..] + This section provides functions allowing to: + (+) Start the Complementary PWM. + (+) Stop the Complementary PWM. + (+) Start the Complementary PWM and enable interrupts. + (+) Stop the Complementary PWM and disable interrupts. + (+) Start the Complementary PWM and enable DMA transfers. + (+) Stop the Complementary PWM and disable DMA transfers. + (+) Start the Complementary Input Capture measurement. + (+) Stop the Complementary Input Capture. + (+) Start the Complementary Input Capture and enable interrupts. + (+) Stop the Complementary Input Capture and disable interrupts. + (+) Start the Complementary Input Capture and enable DMA transfers. + (+) Stop the Complementary Input Capture and disable DMA transfers. + (+) Start the Complementary One Pulse generation. + (+) Stop the Complementary One Pulse. + (+) Start the Complementary One Pulse and enable interrupts. + (+) Stop the Complementary One Pulse and disable interrupts. + +@endverbatim + * @{ + */ + +/** + * @brief Starts the PWM signal generation on the complementary output. + * @param htim TIM handle + * @param Channel TIM Channel to be enabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_PWMN_Start(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + uint32_t tmpsmcr; + + /* Check the parameters */ + assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel)); + + /* Enable the complementary PWM output */ + TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_ENABLE); + + /* Enable the Main Output */ + __HAL_TIM_MOE_ENABLE(htim); + + /* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */ + tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS; + if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr)) + { + __HAL_TIM_ENABLE(htim); + } + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stops the PWM signal generation on the complementary output. + * @param htim TIM handle + * @param Channel TIM Channel to be disabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_PWMN_Stop(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + /* Check the parameters */ + assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel)); + + /* Disable the complementary PWM output */ + TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_DISABLE); + + /* Disable the Main Output */ + __HAL_TIM_MOE_DISABLE(htim); + + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Starts the PWM signal generation in interrupt mode on the + * complementary output. + * @param htim TIM handle + * @param Channel TIM Channel to be disabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_PWMN_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + uint32_t tmpsmcr; + + /* Check the parameters */ + assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel)); + + switch (Channel) + { + case TIM_CHANNEL_1: + { + /* Enable the TIM Capture/Compare 1 interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC1); + break; + } + + case TIM_CHANNEL_2: + { + /* Enable the TIM Capture/Compare 2 interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC2); + break; + } + + case TIM_CHANNEL_3: + { + /* Enable the TIM Capture/Compare 3 interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC3); + break; + } + + default: + break; + } + + /* Enable the TIM Break interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_BREAK); + + /* Enable the complementary PWM output */ + TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_ENABLE); + + /* Enable the Main Output */ + __HAL_TIM_MOE_ENABLE(htim); + + /* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */ + tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS; + if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr)) + { + __HAL_TIM_ENABLE(htim); + } + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stops the PWM signal generation in interrupt mode on the + * complementary output. + * @param htim TIM handle + * @param Channel TIM Channel to be disabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_PWMN_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + uint32_t tmpccer; + + /* Check the parameters */ + assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel)); + + switch (Channel) + { + case TIM_CHANNEL_1: + { + /* Disable the TIM Capture/Compare 1 interrupt */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC1); + break; + } + + case TIM_CHANNEL_2: + { + /* Disable the TIM Capture/Compare 2 interrupt */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC2); + break; + } + + case TIM_CHANNEL_3: + { + /* Disable the TIM Capture/Compare 3 interrupt */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC3); + break; + } + + default: + break; + } + + /* Disable the complementary PWM output */ + TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_DISABLE); + + /* Disable the TIM Break interrupt (only if no more channel is active) */ + tmpccer = htim->Instance->CCER; + if ((tmpccer & (TIM_CCER_CC1NE | TIM_CCER_CC2NE | TIM_CCER_CC3NE)) == (uint32_t)RESET) + { + __HAL_TIM_DISABLE_IT(htim, TIM_IT_BREAK); + } + + /* Disable the Main Output */ + __HAL_TIM_MOE_DISABLE(htim); + + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Starts the TIM PWM signal generation in DMA mode on the + * complementary output + * @param htim TIM handle + * @param Channel TIM Channel to be enabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @param pData The source Buffer address. + * @param Length The length of data to be transferred from memory to TIM peripheral + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_PWMN_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Channel, uint32_t *pData, uint16_t Length) +{ + uint32_t tmpsmcr; + + /* Check the parameters */ + assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel)); + + if (htim->State == HAL_TIM_STATE_BUSY) + { + return HAL_BUSY; + } + else if (htim->State == HAL_TIM_STATE_READY) + { + if (((uint32_t)pData == 0U) && (Length > 0U)) + { + return HAL_ERROR; + } + else + { + htim->State = HAL_TIM_STATE_BUSY; + } + } + else + { + /* nothing to do */ + } + switch (Channel) + { + case TIM_CHANNEL_1: + { + /* Set the DMA compare callbacks */ + htim->hdma[TIM_DMA_ID_CC1]->XferCpltCallback = TIM_DMADelayPulseCplt; + htim->hdma[TIM_DMA_ID_CC1]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC1]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA channel */ + if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC1], (uint32_t)pData, (uint32_t)&htim->Instance->CCR1, Length) != HAL_OK) + { + return HAL_ERROR; + } + /* Enable the TIM Capture/Compare 1 DMA request */ + __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC1); + break; + } + + case TIM_CHANNEL_2: + { + /* Set the DMA compare callbacks */ + htim->hdma[TIM_DMA_ID_CC2]->XferCpltCallback = TIM_DMADelayPulseCplt; + htim->hdma[TIM_DMA_ID_CC2]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC2]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA channel */ + if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC2], (uint32_t)pData, (uint32_t)&htim->Instance->CCR2, Length) != HAL_OK) + { + return HAL_ERROR; + } + /* Enable the TIM Capture/Compare 2 DMA request */ + __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC2); + break; + } + + case TIM_CHANNEL_3: + { + /* Set the DMA compare callbacks */ + htim->hdma[TIM_DMA_ID_CC3]->XferCpltCallback = TIM_DMADelayPulseCplt; + htim->hdma[TIM_DMA_ID_CC3]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC3]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA channel */ + if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC3], (uint32_t)pData, (uint32_t)&htim->Instance->CCR3, Length) != HAL_OK) + { + return HAL_ERROR; + } + /* Enable the TIM Capture/Compare 3 DMA request */ + __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC3); + break; + } + + default: + break; + } + + /* Enable the complementary PWM output */ + TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_ENABLE); + + /* Enable the Main Output */ + __HAL_TIM_MOE_ENABLE(htim); + + /* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */ + tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS; + if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr)) + { + __HAL_TIM_ENABLE(htim); + } + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stops the TIM PWM signal generation in DMA mode on the complementary + * output + * @param htim TIM handle + * @param Channel TIM Channel to be disabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_PWMN_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + /* Check the parameters */ + assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel)); + + switch (Channel) + { + case TIM_CHANNEL_1: + { + /* Disable the TIM Capture/Compare 1 DMA request */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC1); + (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC1]); + break; + } + + case TIM_CHANNEL_2: + { + /* Disable the TIM Capture/Compare 2 DMA request */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC2); + (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC2]); + break; + } + + case TIM_CHANNEL_3: + { + /* Disable the TIM Capture/Compare 3 DMA request */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC3); + (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC3]); + break; + } + + default: + break; + } + + /* Disable the complementary PWM output */ + TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_DISABLE); + + /* Disable the Main Output */ + __HAL_TIM_MOE_DISABLE(htim); + + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Change the htim state */ + htim->State = HAL_TIM_STATE_READY; + + /* Return function status */ + return HAL_OK; +} + +/** + * @} + */ + +/** @defgroup TIMEx_Exported_Functions_Group4 Extended Timer Complementary One Pulse functions + * @brief Timer Complementary One Pulse functions + * +@verbatim + ============================================================================== + ##### Timer Complementary One Pulse functions ##### + ============================================================================== + [..] + This section provides functions allowing to: + (+) Start the Complementary One Pulse generation. + (+) Stop the Complementary One Pulse. + (+) Start the Complementary One Pulse and enable interrupts. + (+) Stop the Complementary One Pulse and disable interrupts. + +@endverbatim + * @{ + */ + +/** + * @brief Starts the TIM One Pulse signal generation on the complementary + * output. + * @param htim TIM One Pulse handle + * @param OutputChannel TIM Channel to be enabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_OnePulseN_Start(TIM_HandleTypeDef *htim, uint32_t OutputChannel) +{ + /* Check the parameters */ + assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, OutputChannel)); + + /* Enable the complementary One Pulse output */ + TIM_CCxNChannelCmd(htim->Instance, OutputChannel, TIM_CCxN_ENABLE); + + /* Enable the Main Output */ + __HAL_TIM_MOE_ENABLE(htim); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stops the TIM One Pulse signal generation on the complementary + * output. + * @param htim TIM One Pulse handle + * @param OutputChannel TIM Channel to be disabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_OnePulseN_Stop(TIM_HandleTypeDef *htim, uint32_t OutputChannel) +{ + + /* Check the parameters */ + assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, OutputChannel)); + + /* Disable the complementary One Pulse output */ + TIM_CCxNChannelCmd(htim->Instance, OutputChannel, TIM_CCxN_DISABLE); + + /* Disable the Main Output */ + __HAL_TIM_MOE_DISABLE(htim); + + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Starts the TIM One Pulse signal generation in interrupt mode on the + * complementary channel. + * @param htim TIM One Pulse handle + * @param OutputChannel TIM Channel to be enabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_OnePulseN_Start_IT(TIM_HandleTypeDef *htim, uint32_t OutputChannel) +{ + /* Check the parameters */ + assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, OutputChannel)); + + /* Enable the TIM Capture/Compare 1 interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC1); + + /* Enable the TIM Capture/Compare 2 interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC2); + + /* Enable the complementary One Pulse output */ + TIM_CCxNChannelCmd(htim->Instance, OutputChannel, TIM_CCxN_ENABLE); + + /* Enable the Main Output */ + __HAL_TIM_MOE_ENABLE(htim); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stops the TIM One Pulse signal generation in interrupt mode on the + * complementary channel. + * @param htim TIM One Pulse handle + * @param OutputChannel TIM Channel to be disabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_OnePulseN_Stop_IT(TIM_HandleTypeDef *htim, uint32_t OutputChannel) +{ + /* Check the parameters */ + assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, OutputChannel)); + + /* Disable the TIM Capture/Compare 1 interrupt */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC1); + + /* Disable the TIM Capture/Compare 2 interrupt */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC2); + + /* Disable the complementary One Pulse output */ + TIM_CCxNChannelCmd(htim->Instance, OutputChannel, TIM_CCxN_DISABLE); + + /* Disable the Main Output */ + __HAL_TIM_MOE_DISABLE(htim); + + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Return function status */ + return HAL_OK; +} + +/** + * @} + */ + +/** @defgroup TIMEx_Exported_Functions_Group5 Extended Peripheral Control functions + * @brief Peripheral Control functions + * +@verbatim + ============================================================================== + ##### Peripheral Control functions ##### + ============================================================================== + [..] + This section provides functions allowing to: + (+) Configure the commutation event in case of use of the Hall sensor interface. + (+) Configure Output channels for OC and PWM mode. + + (+) Configure Complementary channels, break features and dead time. + (+) Configure Master synchronization. + (+) Configure timer remapping capabilities. + +@endverbatim + * @{ + */ + +/** + * @brief Configure the TIM commutation event sequence. + * @note This function is mandatory to use the commutation event in order to + * update the configuration at each commutation detection on the TRGI input of the Timer, + * the typical use of this feature is with the use of another Timer(interface Timer) + * configured in Hall sensor interface, this interface Timer will generate the + * commutation at its TRGO output (connected to Timer used in this function) each time + * the TI1 of the Interface Timer detect a commutation at its input TI1. + * @param htim TIM handle + * @param InputTrigger the Internal trigger corresponding to the Timer Interfacing with the Hall sensor + * This parameter can be one of the following values: + * @arg TIM_TS_ITR0: Internal trigger 0 selected + * @arg TIM_TS_ITR1: Internal trigger 1 selected + * @arg TIM_TS_ITR2: Internal trigger 2 selected + * @arg TIM_TS_ITR3: Internal trigger 3 selected + * @arg TIM_TS_NONE: No trigger is needed + * @param CommutationSource the Commutation Event source + * This parameter can be one of the following values: + * @arg TIM_COMMUTATION_TRGI: Commutation source is the TRGI of the Interface Timer + * @arg TIM_COMMUTATION_SOFTWARE: Commutation source is set by software using the COMG bit + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_ConfigCommutEvent(TIM_HandleTypeDef *htim, uint32_t InputTrigger, + uint32_t CommutationSource) +{ + /* Check the parameters */ + assert_param(IS_TIM_COMMUTATION_EVENT_INSTANCE(htim->Instance)); + assert_param(IS_TIM_INTERNAL_TRIGGEREVENT_SELECTION(InputTrigger)); + + __HAL_LOCK(htim); + + if ((InputTrigger == TIM_TS_ITR0) || (InputTrigger == TIM_TS_ITR1) || + (InputTrigger == TIM_TS_ITR2) || (InputTrigger == TIM_TS_ITR3)) + { + /* Select the Input trigger */ + htim->Instance->SMCR &= ~TIM_SMCR_TS; + htim->Instance->SMCR |= InputTrigger; + } + + /* Select the Capture Compare preload feature */ + htim->Instance->CR2 |= TIM_CR2_CCPC; + /* Select the Commutation event source */ + htim->Instance->CR2 &= ~TIM_CR2_CCUS; + htim->Instance->CR2 |= CommutationSource; + + /* Disable Commutation Interrupt */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_COM); + + /* Disable Commutation DMA request */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_COM); + + __HAL_UNLOCK(htim); + + return HAL_OK; +} + +/** + * @brief Configure the TIM commutation event sequence with interrupt. + * @note This function is mandatory to use the commutation event in order to + * update the configuration at each commutation detection on the TRGI input of the Timer, + * the typical use of this feature is with the use of another Timer(interface Timer) + * configured in Hall sensor interface, this interface Timer will generate the + * commutation at its TRGO output (connected to Timer used in this function) each time + * the TI1 of the Interface Timer detect a commutation at its input TI1. + * @param htim TIM handle + * @param InputTrigger the Internal trigger corresponding to the Timer Interfacing with the Hall sensor + * This parameter can be one of the following values: + * @arg TIM_TS_ITR0: Internal trigger 0 selected + * @arg TIM_TS_ITR1: Internal trigger 1 selected + * @arg TIM_TS_ITR2: Internal trigger 2 selected + * @arg TIM_TS_ITR3: Internal trigger 3 selected + * @arg TIM_TS_NONE: No trigger is needed + * @param CommutationSource the Commutation Event source + * This parameter can be one of the following values: + * @arg TIM_COMMUTATION_TRGI: Commutation source is the TRGI of the Interface Timer + * @arg TIM_COMMUTATION_SOFTWARE: Commutation source is set by software using the COMG bit + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_ConfigCommutEvent_IT(TIM_HandleTypeDef *htim, uint32_t InputTrigger, + uint32_t CommutationSource) +{ + /* Check the parameters */ + assert_param(IS_TIM_COMMUTATION_EVENT_INSTANCE(htim->Instance)); + assert_param(IS_TIM_INTERNAL_TRIGGEREVENT_SELECTION(InputTrigger)); + + __HAL_LOCK(htim); + + if ((InputTrigger == TIM_TS_ITR0) || (InputTrigger == TIM_TS_ITR1) || + (InputTrigger == TIM_TS_ITR2) || (InputTrigger == TIM_TS_ITR3)) + { + /* Select the Input trigger */ + htim->Instance->SMCR &= ~TIM_SMCR_TS; + htim->Instance->SMCR |= InputTrigger; + } + + /* Select the Capture Compare preload feature */ + htim->Instance->CR2 |= TIM_CR2_CCPC; + /* Select the Commutation event source */ + htim->Instance->CR2 &= ~TIM_CR2_CCUS; + htim->Instance->CR2 |= CommutationSource; + + /* Disable Commutation DMA request */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_COM); + + /* Enable the Commutation Interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_COM); + + __HAL_UNLOCK(htim); + + return HAL_OK; +} + +/** + * @brief Configure the TIM commutation event sequence with DMA. + * @note This function is mandatory to use the commutation event in order to + * update the configuration at each commutation detection on the TRGI input of the Timer, + * the typical use of this feature is with the use of another Timer(interface Timer) + * configured in Hall sensor interface, this interface Timer will generate the + * commutation at its TRGO output (connected to Timer used in this function) each time + * the TI1 of the Interface Timer detect a commutation at its input TI1. + * @note The user should configure the DMA in his own software, in This function only the COMDE bit is set + * @param htim TIM handle + * @param InputTrigger the Internal trigger corresponding to the Timer Interfacing with the Hall sensor + * This parameter can be one of the following values: + * @arg TIM_TS_ITR0: Internal trigger 0 selected + * @arg TIM_TS_ITR1: Internal trigger 1 selected + * @arg TIM_TS_ITR2: Internal trigger 2 selected + * @arg TIM_TS_ITR3: Internal trigger 3 selected + * @arg TIM_TS_NONE: No trigger is needed + * @param CommutationSource the Commutation Event source + * This parameter can be one of the following values: + * @arg TIM_COMMUTATION_TRGI: Commutation source is the TRGI of the Interface Timer + * @arg TIM_COMMUTATION_SOFTWARE: Commutation source is set by software using the COMG bit + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_ConfigCommutEvent_DMA(TIM_HandleTypeDef *htim, uint32_t InputTrigger, + uint32_t CommutationSource) +{ + /* Check the parameters */ + assert_param(IS_TIM_COMMUTATION_EVENT_INSTANCE(htim->Instance)); + assert_param(IS_TIM_INTERNAL_TRIGGEREVENT_SELECTION(InputTrigger)); + + __HAL_LOCK(htim); + + if ((InputTrigger == TIM_TS_ITR0) || (InputTrigger == TIM_TS_ITR1) || + (InputTrigger == TIM_TS_ITR2) || (InputTrigger == TIM_TS_ITR3)) + { + /* Select the Input trigger */ + htim->Instance->SMCR &= ~TIM_SMCR_TS; + htim->Instance->SMCR |= InputTrigger; + } + + /* Select the Capture Compare preload feature */ + htim->Instance->CR2 |= TIM_CR2_CCPC; + /* Select the Commutation event source */ + htim->Instance->CR2 &= ~TIM_CR2_CCUS; + htim->Instance->CR2 |= CommutationSource; + + /* Enable the Commutation DMA Request */ + /* Set the DMA Commutation Callback */ + htim->hdma[TIM_DMA_ID_COMMUTATION]->XferCpltCallback = TIMEx_DMACommutationCplt; + htim->hdma[TIM_DMA_ID_COMMUTATION]->XferHalfCpltCallback = TIMEx_DMACommutationHalfCplt; + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_COMMUTATION]->XferErrorCallback = TIM_DMAError; + + /* Disable Commutation Interrupt */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_COM); + + /* Enable the Commutation DMA Request */ + __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_COM); + + __HAL_UNLOCK(htim); + + return HAL_OK; +} + +/** + * @brief Configures the TIM in master mode. + * @param htim TIM handle. + * @param sMasterConfig pointer to a TIM_MasterConfigTypeDef structure that + * contains the selected trigger output (TRGO) and the Master/Slave + * mode. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_MasterConfigSynchronization(TIM_HandleTypeDef *htim, + TIM_MasterConfigTypeDef *sMasterConfig) +{ + uint32_t tmpcr2; + uint32_t tmpsmcr; + + /* Check the parameters */ + assert_param(IS_TIM_MASTER_INSTANCE(htim->Instance)); + assert_param(IS_TIM_TRGO_SOURCE(sMasterConfig->MasterOutputTrigger)); + assert_param(IS_TIM_MSM_STATE(sMasterConfig->MasterSlaveMode)); + + /* Check input state */ + __HAL_LOCK(htim); + + /* Change the handler state */ + htim->State = HAL_TIM_STATE_BUSY; + + /* Get the TIMx CR2 register value */ + tmpcr2 = htim->Instance->CR2; + + /* Get the TIMx SMCR register value */ + tmpsmcr = htim->Instance->SMCR; + + /* Reset the MMS Bits */ + tmpcr2 &= ~TIM_CR2_MMS; + /* Select the TRGO source */ + tmpcr2 |= sMasterConfig->MasterOutputTrigger; + + /* Update TIMx CR2 */ + htim->Instance->CR2 = tmpcr2; + + if (IS_TIM_SLAVE_INSTANCE(htim->Instance)) + { + /* Reset the MSM Bit */ + tmpsmcr &= ~TIM_SMCR_MSM; + /* Set master mode */ + tmpsmcr |= sMasterConfig->MasterSlaveMode; + + /* Update TIMx SMCR */ + htim->Instance->SMCR = tmpsmcr; + } + + /* Change the htim state */ + htim->State = HAL_TIM_STATE_READY; + + __HAL_UNLOCK(htim); + + return HAL_OK; +} + +/** + * @brief Configures the Break feature, dead time, Lock level, OSSI/OSSR State + * and the AOE(automatic output enable). + * @param htim TIM handle + * @param sBreakDeadTimeConfig pointer to a TIM_ConfigBreakDeadConfigTypeDef structure that + * contains the BDTR Register configuration information for the TIM peripheral. + * @note Interrupts can be generated when an active level is detected on the + * break input, the break 2 input or the system break input. Break + * interrupt can be enabled by calling the @ref __HAL_TIM_ENABLE_IT macro. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_ConfigBreakDeadTime(TIM_HandleTypeDef *htim, + TIM_BreakDeadTimeConfigTypeDef *sBreakDeadTimeConfig) +{ + /* Keep this variable initialized to 0 as it is used to configure BDTR register */ + uint32_t tmpbdtr = 0U; + + /* Check the parameters */ + assert_param(IS_TIM_BREAK_INSTANCE(htim->Instance)); + assert_param(IS_TIM_OSSR_STATE(sBreakDeadTimeConfig->OffStateRunMode)); + assert_param(IS_TIM_OSSI_STATE(sBreakDeadTimeConfig->OffStateIDLEMode)); + assert_param(IS_TIM_LOCK_LEVEL(sBreakDeadTimeConfig->LockLevel)); + assert_param(IS_TIM_DEADTIME(sBreakDeadTimeConfig->DeadTime)); + assert_param(IS_TIM_BREAK_STATE(sBreakDeadTimeConfig->BreakState)); + assert_param(IS_TIM_BREAK_POLARITY(sBreakDeadTimeConfig->BreakPolarity)); + assert_param(IS_TIM_AUTOMATIC_OUTPUT_STATE(sBreakDeadTimeConfig->AutomaticOutput)); + + /* Check input state */ + __HAL_LOCK(htim); + + /* Set the Lock level, the Break enable Bit and the Polarity, the OSSR State, + the OSSI State, the dead time value and the Automatic Output Enable Bit */ + + /* Set the BDTR bits */ + MODIFY_REG(tmpbdtr, TIM_BDTR_DTG, sBreakDeadTimeConfig->DeadTime); + MODIFY_REG(tmpbdtr, TIM_BDTR_LOCK, sBreakDeadTimeConfig->LockLevel); + MODIFY_REG(tmpbdtr, TIM_BDTR_OSSI, sBreakDeadTimeConfig->OffStateIDLEMode); + MODIFY_REG(tmpbdtr, TIM_BDTR_OSSR, sBreakDeadTimeConfig->OffStateRunMode); + MODIFY_REG(tmpbdtr, TIM_BDTR_BKE, sBreakDeadTimeConfig->BreakState); + MODIFY_REG(tmpbdtr, TIM_BDTR_BKP, sBreakDeadTimeConfig->BreakPolarity); + MODIFY_REG(tmpbdtr, TIM_BDTR_AOE, sBreakDeadTimeConfig->AutomaticOutput); + + + /* Set TIMx_BDTR */ + htim->Instance->BDTR = tmpbdtr; + + __HAL_UNLOCK(htim); + + return HAL_OK; +} + +/** + * @brief Configures the TIMx Remapping input capabilities. + * @param htim TIM handle. + * @param Remap specifies the TIM remapping source. + * For TIM14, the parameter can have the following values: + * @arg TIM_TIM14_GPIO: TIM14 TI1 is connected to GPIO + * @arg TIM_TIM14_RTC: TIM14 TI1 is connected to RTC_clock + * @arg TIM_TIM14_HSE: TIM14 TI1 is connected to HSE/32 + * @arg TIM_TIM14_MCO: TIM14 TI1 is connected to MCO + * + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_RemapConfig(TIM_HandleTypeDef *htim, uint32_t Remap) +{ + __HAL_LOCK(htim); + + /* Check parameters */ + assert_param(IS_TIM_REMAP(htim->Instance, Remap)); + + /* Set the Timer remapping configuration */ + WRITE_REG(htim->Instance->OR, Remap); + + __HAL_UNLOCK(htim); + + return HAL_OK; +} + +/** + * @} + */ + +/** @defgroup TIMEx_Exported_Functions_Group6 Extended Callbacks functions + * @brief Extended Callbacks functions + * +@verbatim + ============================================================================== + ##### Extended Callbacks functions ##### + ============================================================================== + [..] + This section provides Extended TIM callback functions: + (+) Timer Commutation callback + (+) Timer Break callback + +@endverbatim + * @{ + */ + +/** + * @brief Hall commutation changed callback in non-blocking mode + * @param htim TIM handle + * @retval None + */ +__weak void HAL_TIMEx_CommutCallback(TIM_HandleTypeDef *htim) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(htim); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_TIMEx_CommutCallback could be implemented in the user file + */ +} +/** + * @brief Hall commutation changed half complete callback in non-blocking mode + * @param htim TIM handle + * @retval None + */ +__weak void HAL_TIMEx_CommutHalfCpltCallback(TIM_HandleTypeDef *htim) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(htim); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_TIMEx_CommutHalfCpltCallback could be implemented in the user file + */ +} + +/** + * @brief Hall Break detection callback in non-blocking mode + * @param htim TIM handle + * @retval None + */ +__weak void HAL_TIMEx_BreakCallback(TIM_HandleTypeDef *htim) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(htim); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_TIMEx_BreakCallback could be implemented in the user file + */ +} +/** + * @} + */ + +/** @defgroup TIMEx_Exported_Functions_Group7 Extended Peripheral State functions + * @brief Extended Peripheral State functions + * +@verbatim + ============================================================================== + ##### Extended Peripheral State functions ##### + ============================================================================== + [..] + This subsection permits to get in run-time the status of the peripheral + and the data flow. + +@endverbatim + * @{ + */ + +/** + * @brief Return the TIM Hall Sensor interface handle state. + * @param htim TIM Hall Sensor handle + * @retval HAL state + */ +HAL_TIM_StateTypeDef HAL_TIMEx_HallSensor_GetState(TIM_HandleTypeDef *htim) +{ + return htim->State; +} + +/** + * @} + */ + +/** + * @} + */ + +/* Private functions ---------------------------------------------------------*/ +/** @defgroup TIMEx_Private_Functions TIMEx Private Functions + * @{ + */ + +/** + * @brief TIM DMA Commutation callback. + * @param hdma pointer to DMA handle. + * @retval None + */ +void TIMEx_DMACommutationCplt(DMA_HandleTypeDef *hdma) +{ + TIM_HandleTypeDef *htim = (TIM_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; + + /* Change the htim state */ + htim->State = HAL_TIM_STATE_READY; + +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + htim->CommutationCallback(htim); +#else + HAL_TIMEx_CommutCallback(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ +} + +/** + * @brief TIM DMA Commutation half complete callback. + * @param hdma pointer to DMA handle. + * @retval None + */ +void TIMEx_DMACommutationHalfCplt(DMA_HandleTypeDef *hdma) +{ + TIM_HandleTypeDef *htim = (TIM_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; + + /* Change the htim state */ + htim->State = HAL_TIM_STATE_READY; + +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + htim->CommutationHalfCpltCallback(htim); +#else + HAL_TIMEx_CommutHalfCpltCallback(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ +} + + +/** + * @brief Enables or disables the TIM Capture Compare Channel xN. + * @param TIMx to select the TIM peripheral + * @param Channel specifies the TIM Channel + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 + * @arg TIM_CHANNEL_2: TIM Channel 2 + * @arg TIM_CHANNEL_3: TIM Channel 3 + * @param ChannelNState specifies the TIM Channel CCxNE bit new state. + * This parameter can be: TIM_CCxN_ENABLE or TIM_CCxN_Disable. + * @retval None + */ +static void TIM_CCxNChannelCmd(TIM_TypeDef *TIMx, uint32_t Channel, uint32_t ChannelNState) +{ + uint32_t tmp; + + tmp = TIM_CCER_CC1NE << (Channel & 0x1FU); /* 0x1FU = 31 bits max shift */ + + /* Reset the CCxNE Bit */ + TIMx->CCER &= ~tmp; + + /* Set or reset the CCxNE Bit */ + TIMx->CCER |= (uint32_t)(ChannelNState << (Channel & 0x1FU)); /* 0x1FU = 31 bits max shift */ +} +/** + * @} + */ + +#endif /* HAL_TIM_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.c b/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.c new file mode 100644 index 0000000..071ebdc --- /dev/null +++ b/test/STM32F072C8T6/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.c @@ -0,0 +1,878 @@ +/** + ****************************************************************************** + * @file stm32f0xx_ll_usb.c + * @author MCD Application Team + * @brief USB Low Layer HAL module driver. + * + * This file provides firmware functions to manage the following + * functionalities of the USB Peripheral Controller: + * + Initialization/de-initialization functions + * + I/O operation functions + * + Peripheral Control functions + * + Peripheral State functions + * + @verbatim + ============================================================================== + ##### How to use this driver ##### + ============================================================================== + [..] + (#) Fill parameters of Init structure in USB_OTG_CfgTypeDef structure. + + (#) Call USB_CoreInit() API to initialize the USB Core peripheral. + + (#) The upper HAL HCD/PCD driver will call the right routines for its internal processes. + + @endverbatim + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2016 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f0xx_hal.h" + +/** @addtogroup STM32F0xx_LL_USB_DRIVER + * @{ + */ + +#if defined (HAL_PCD_MODULE_ENABLED) || defined (HAL_HCD_MODULE_ENABLED) +#if defined (USB) +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + + +/** + * @brief Initializes the USB Core + * @param USBx: USB Instance + * @param cfg : pointer to a USB_CfgTypeDef structure that contains + * the configuration information for the specified USBx peripheral. + * @retval HAL status + */ +HAL_StatusTypeDef USB_CoreInit(USB_TypeDef *USBx, USB_CfgTypeDef cfg) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(USBx); + UNUSED(cfg); + + /* NOTE : - This function is not required by USB Device FS peripheral, it is used + only by USB OTG FS peripheral. + - This function is added to ensure compatibility across platforms. + */ + + return HAL_OK; +} + +/** + * @brief USB_EnableGlobalInt + * Enables the controller's Global Int in the AHB Config reg + * @param USBx : Selected device + * @retval HAL status + */ +HAL_StatusTypeDef USB_EnableGlobalInt(USB_TypeDef *USBx) +{ + uint16_t winterruptmask; + + /* Set winterruptmask variable */ + winterruptmask = USB_CNTR_CTRM | USB_CNTR_WKUPM | + USB_CNTR_SUSPM | USB_CNTR_ERRM | + USB_CNTR_SOFM | USB_CNTR_ESOFM | + USB_CNTR_RESETM | USB_CNTR_L1REQM; + + /* Set interrupt mask */ + USBx->CNTR |= winterruptmask; + + return HAL_OK; +} + +/** + * @brief USB_DisableGlobalInt + * Disable the controller's Global Int in the AHB Config reg + * @param USBx : Selected device + * @retval HAL status +*/ +HAL_StatusTypeDef USB_DisableGlobalInt(USB_TypeDef *USBx) +{ + uint16_t winterruptmask; + + /* Set winterruptmask variable */ + winterruptmask = USB_CNTR_CTRM | USB_CNTR_WKUPM | + USB_CNTR_SUSPM | USB_CNTR_ERRM | + USB_CNTR_SOFM | USB_CNTR_ESOFM | + USB_CNTR_RESETM | USB_CNTR_L1REQM; + + /* Clear interrupt mask */ + USBx->CNTR &= ~winterruptmask; + + return HAL_OK; +} + +/** + * @brief USB_SetCurrentMode : Set functional mode + * @param USBx : Selected device + * @param mode : current core mode + * This parameter can be one of the these values: + * @arg USB_DEVICE_MODE: Peripheral mode mode + * @retval HAL status + */ +HAL_StatusTypeDef USB_SetCurrentMode(USB_TypeDef *USBx, USB_ModeTypeDef mode) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(USBx); + UNUSED(mode); + + /* NOTE : - This function is not required by USB Device FS peripheral, it is used + only by USB OTG FS peripheral. + - This function is added to ensure compatibility across platforms. + */ + return HAL_OK; +} + +/** + * @brief USB_DevInit : Initializes the USB controller registers + * for device mode + * @param USBx : Selected device + * @param cfg : pointer to a USB_CfgTypeDef structure that contains + * the configuration information for the specified USBx peripheral. + * @retval HAL status + */ +HAL_StatusTypeDef USB_DevInit(USB_TypeDef *USBx, USB_CfgTypeDef cfg) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(cfg); + + /* Init Device */ + /*CNTR_FRES = 1*/ + USBx->CNTR = USB_CNTR_FRES; + + /*CNTR_FRES = 0*/ + USBx->CNTR = 0; + + /*Clear pending interrupts*/ + USBx->ISTR = 0; + + /*Set Btable Address*/ + USBx->BTABLE = BTABLE_ADDRESS; + + /* Enable USB Device Interrupt mask */ + (void)USB_EnableGlobalInt(USBx); + + return HAL_OK; +} + +/** + * @brief USB_SetDevSpeed :Initializes the device speed + * depending on the PHY type and the enumeration speed of the device. + * @param USBx Selected device + * @param speed device speed + * @retval Hal status + */ +HAL_StatusTypeDef USB_SetDevSpeed(USB_TypeDef *USBx, uint8_t speed) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(USBx); + UNUSED(speed); + + /* NOTE : - This function is not required by USB Device FS peripheral, it is used + only by USB OTG FS peripheral. + - This function is added to ensure compatibility across platforms. + */ + + return HAL_OK; +} + +/** + * @brief USB_FlushTxFifo : Flush a Tx FIFO + * @param USBx : Selected device + * @param num : FIFO number + * This parameter can be a value from 1 to 15 + 15 means Flush all Tx FIFOs + * @retval HAL status + */ +HAL_StatusTypeDef USB_FlushTxFifo(USB_TypeDef *USBx, uint32_t num) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(USBx); + UNUSED(num); + + /* NOTE : - This function is not required by USB Device FS peripheral, it is used + only by USB OTG FS peripheral. + - This function is added to ensure compatibility across platforms. + */ + + return HAL_OK; +} + +/** + * @brief USB_FlushRxFifo : Flush Rx FIFO + * @param USBx : Selected device + * @retval HAL status + */ +HAL_StatusTypeDef USB_FlushRxFifo(USB_TypeDef *USBx) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(USBx); + + /* NOTE : - This function is not required by USB Device FS peripheral, it is used + only by USB OTG FS peripheral. + - This function is added to ensure compatibility across platforms. + */ + + return HAL_OK; +} + +/** + * @brief Activate and configure an endpoint + * @param USBx : Selected device + * @param ep: pointer to endpoint structure + * @retval HAL status + */ +HAL_StatusTypeDef USB_ActivateEndpoint(USB_TypeDef *USBx, USB_EPTypeDef *ep) +{ + HAL_StatusTypeDef ret = HAL_OK; + uint16_t wEpRegVal; + + wEpRegVal = PCD_GET_ENDPOINT(USBx, ep->num) & USB_EP_T_MASK; + + /* initialize Endpoint */ + switch (ep->type) + { + case EP_TYPE_CTRL: + wEpRegVal |= USB_EP_CONTROL; + break; + + case EP_TYPE_BULK: + wEpRegVal |= USB_EP_BULK; + break; + + case EP_TYPE_INTR: + wEpRegVal |= USB_EP_INTERRUPT; + break; + + case EP_TYPE_ISOC: + wEpRegVal |= USB_EP_ISOCHRONOUS; + break; + + default: + ret = HAL_ERROR; + break; + } + + PCD_SET_ENDPOINT(USBx, ep->num, wEpRegVal | USB_EP_CTR_RX | USB_EP_CTR_TX); + + PCD_SET_EP_ADDRESS(USBx, ep->num, ep->num); + + if (ep->doublebuffer == 0U) + { + if (ep->is_in != 0U) + { + /*Set the endpoint Transmit buffer address */ + PCD_SET_EP_TX_ADDRESS(USBx, ep->num, ep->pmaadress); + PCD_CLEAR_TX_DTOG(USBx, ep->num); + + if (ep->type != EP_TYPE_ISOC) + { + /* Configure NAK status for the Endpoint */ + PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_NAK); + } + else + { + /* Configure TX Endpoint to disabled state */ + PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS); + } + } + else + { + /*Set the endpoint Receive buffer address */ + PCD_SET_EP_RX_ADDRESS(USBx, ep->num, ep->pmaadress); + /*Set the endpoint Receive buffer counter*/ + PCD_SET_EP_RX_CNT(USBx, ep->num, ep->maxpacket); + PCD_CLEAR_RX_DTOG(USBx, ep->num); + /* Configure VALID status for the Endpoint*/ + PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_VALID); + } + } + /*Double Buffer*/ + else + { + /* Set the endpoint as double buffered */ + PCD_SET_EP_DBUF(USBx, ep->num); + /* Set buffer address for double buffered mode */ + PCD_SET_EP_DBUF_ADDR(USBx, ep->num, ep->pmaaddr0, ep->pmaaddr1); + + if (ep->is_in == 0U) + { + /* Clear the data toggle bits for the endpoint IN/OUT */ + PCD_CLEAR_RX_DTOG(USBx, ep->num); + PCD_CLEAR_TX_DTOG(USBx, ep->num); + + /* Reset value of the data toggle bits for the endpoint out */ + PCD_TX_DTOG(USBx, ep->num); + + PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_VALID); + PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS); + } + else + { + /* Clear the data toggle bits for the endpoint IN/OUT */ + PCD_CLEAR_RX_DTOG(USBx, ep->num); + PCD_CLEAR_TX_DTOG(USBx, ep->num); + PCD_RX_DTOG(USBx, ep->num); + + if (ep->type != EP_TYPE_ISOC) + { + /* Configure NAK status for the Endpoint */ + PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_NAK); + } + else + { + /* Configure TX Endpoint to disabled state */ + PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS); + } + + PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_DIS); + } + } + + return ret; +} + +/** + * @brief De-activate and de-initialize an endpoint + * @param USBx : Selected device + * @param ep: pointer to endpoint structure + * @retval HAL status + */ +HAL_StatusTypeDef USB_DeactivateEndpoint(USB_TypeDef *USBx, USB_EPTypeDef *ep) +{ + if (ep->doublebuffer == 0U) + { + if (ep->is_in != 0U) + { + PCD_CLEAR_TX_DTOG(USBx, ep->num); + /* Configure DISABLE status for the Endpoint*/ + PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS); + } + else + { + PCD_CLEAR_RX_DTOG(USBx, ep->num); + /* Configure DISABLE status for the Endpoint*/ + PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_DIS); + } + } + /*Double Buffer*/ + else + { + if (ep->is_in == 0U) + { + /* Clear the data toggle bits for the endpoint IN/OUT*/ + PCD_CLEAR_RX_DTOG(USBx, ep->num); + PCD_CLEAR_TX_DTOG(USBx, ep->num); + + /* Reset value of the data toggle bits for the endpoint out*/ + PCD_TX_DTOG(USBx, ep->num); + + PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_DIS); + PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS); + } + else + { + /* Clear the data toggle bits for the endpoint IN/OUT*/ + PCD_CLEAR_RX_DTOG(USBx, ep->num); + PCD_CLEAR_TX_DTOG(USBx, ep->num); + PCD_RX_DTOG(USBx, ep->num); + /* Configure DISABLE status for the Endpoint*/ + PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS); + PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_DIS); + } + } + + return HAL_OK; +} + +/** + * @brief USB_EPStartXfer : setup and starts a transfer over an EP + * @param USBx : Selected device + * @param ep: pointer to endpoint structure + * @retval HAL status + */ +HAL_StatusTypeDef USB_EPStartXfer(USB_TypeDef *USBx, USB_EPTypeDef *ep) +{ + uint16_t pmabuffer; + uint32_t len; + + /* IN endpoint */ + if (ep->is_in == 1U) + { + /*Multi packet transfer*/ + if (ep->xfer_len > ep->maxpacket) + { + len = ep->maxpacket; + ep->xfer_len -= len; + } + else + { + len = ep->xfer_len; + ep->xfer_len = 0U; + } + + /* configure and validate Tx endpoint */ + if (ep->doublebuffer == 0U) + { + USB_WritePMA(USBx, ep->xfer_buff, ep->pmaadress, (uint16_t)len); + PCD_SET_EP_TX_CNT(USBx, ep->num, len); + } + else + { + /* Write the data to the USB endpoint */ + if ((PCD_GET_ENDPOINT(USBx, ep->num) & USB_EP_DTOG_TX) != 0U) + { + /* Set the Double buffer counter for pmabuffer1 */ + PCD_SET_EP_DBUF1_CNT(USBx, ep->num, ep->is_in, len); + pmabuffer = ep->pmaaddr1; + } + else + { + /* Set the Double buffer counter for pmabuffer0 */ + PCD_SET_EP_DBUF0_CNT(USBx, ep->num, ep->is_in, len); + pmabuffer = ep->pmaaddr0; + } + USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len); + PCD_FreeUserBuffer(USBx, ep->num, ep->is_in); + } + + PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_VALID); + } + else /* OUT endpoint */ + { + /* Multi packet transfer*/ + if (ep->xfer_len > ep->maxpacket) + { + len = ep->maxpacket; + ep->xfer_len -= len; + } + else + { + len = ep->xfer_len; + ep->xfer_len = 0U; + } + + /* configure and validate Rx endpoint */ + if (ep->doublebuffer == 0U) + { + /*Set RX buffer count*/ + PCD_SET_EP_RX_CNT(USBx, ep->num, len); + } + else + { + /*Set the Double buffer counter*/ + PCD_SET_EP_DBUF_CNT(USBx, ep->num, ep->is_in, len); + } + + PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_VALID); + } + + return HAL_OK; +} + +/** + * @brief USB_WritePacket : Writes a packet into the Tx FIFO associated + * with the EP/channel + * @param USBx : Selected device + * @param src : pointer to source buffer + * @param ch_ep_num : endpoint or host channel number + * @param len : Number of bytes to write + * @retval HAL status + */ +HAL_StatusTypeDef USB_WritePacket(USB_TypeDef *USBx, uint8_t *src, uint8_t ch_ep_num, uint16_t len) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(USBx); + UNUSED(src); + UNUSED(ch_ep_num); + UNUSED(len); + /* NOTE : - This function is not required by USB Device FS peripheral, it is used + only by USB OTG FS peripheral. + - This function is added to ensure compatibility across platforms. + */ + return HAL_OK; +} + +/** + * @brief USB_ReadPacket : read a packet from the Tx FIFO associated + * with the EP/channel + * @param USBx : Selected device + * @param dest : destination pointer + * @param len : Number of bytes to read + * @retval pointer to destination buffer + */ +void *USB_ReadPacket(USB_TypeDef *USBx, uint8_t *dest, uint16_t len) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(USBx); + UNUSED(dest); + UNUSED(len); + /* NOTE : - This function is not required by USB Device FS peripheral, it is used + only by USB OTG FS peripheral. + - This function is added to ensure compatibility across platforms. + */ + return ((void *)NULL); +} + +/** + * @brief USB_EPSetStall : set a stall condition over an EP + * @param USBx : Selected device + * @param ep: pointer to endpoint structure + * @retval HAL status + */ +HAL_StatusTypeDef USB_EPSetStall(USB_TypeDef *USBx, USB_EPTypeDef *ep) +{ + if (ep->is_in != 0U) + { + PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_STALL); + } + else + { + PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_STALL); + } + + return HAL_OK; +} + +/** + * @brief USB_EPClearStall : Clear a stall condition over an EP + * @param USBx : Selected device + * @param ep: pointer to endpoint structure + * @retval HAL status + */ +HAL_StatusTypeDef USB_EPClearStall(USB_TypeDef *USBx, USB_EPTypeDef *ep) +{ + if (ep->doublebuffer == 0U) + { + if (ep->is_in != 0U) + { + PCD_CLEAR_TX_DTOG(USBx, ep->num); + + if (ep->type != EP_TYPE_ISOC) + { + /* Configure NAK status for the Endpoint */ + PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_NAK); + } + } + else + { + PCD_CLEAR_RX_DTOG(USBx, ep->num); + + /* Configure VALID status for the Endpoint*/ + PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_VALID); + } + } + + return HAL_OK; +} + +/** + * @brief USB_StopDevice : Stop the usb device mode + * @param USBx : Selected device + * @retval HAL status + */ +HAL_StatusTypeDef USB_StopDevice(USB_TypeDef *USBx) +{ + /* disable all interrupts and force USB reset */ + USBx->CNTR = USB_CNTR_FRES; + + /* clear interrupt status register */ + USBx->ISTR = 0; + + /* switch-off device */ + USBx->CNTR = (USB_CNTR_FRES | USB_CNTR_PDWN); + + return HAL_OK; +} + +/** + * @brief USB_SetDevAddress : Stop the usb device mode + * @param USBx : Selected device + * @param address : new device address to be assigned + * This parameter can be a value from 0 to 255 + * @retval HAL status + */ +HAL_StatusTypeDef USB_SetDevAddress(USB_TypeDef *USBx, uint8_t address) +{ + if (address == 0U) + { + /* set device address and enable function */ + USBx->DADDR = USB_DADDR_EF; + } + + return HAL_OK; +} + +/** + * @brief USB_DevConnect : Connect the USB device by enabling the pull-up/pull-down + * @param USBx : Selected device + * @retval HAL status + */ +HAL_StatusTypeDef USB_DevConnect(USB_TypeDef *USBx) +{ + /* Enabling DP Pull-UP bit to Connect internal PU resistor on USB DP line */ + USBx->BCDR |= USB_BCDR_DPPU; + + return HAL_OK; +} + +/** + * @brief USB_DevDisconnect : Disconnect the USB device by disabling the pull-up/pull-down + * @param USBx : Selected device + * @retval HAL status + */ +HAL_StatusTypeDef USB_DevDisconnect(USB_TypeDef *USBx) +{ + /* Disable DP Pull-Up bit to disconnect the Internal PU resistor on USB DP line */ + USBx->BCDR &= (uint16_t)(~(USB_BCDR_DPPU)); + + return HAL_OK; +} + +/** + * @brief USB_ReadInterrupts: return the global USB interrupt status + * @param USBx : Selected device + * @retval HAL status + */ +uint32_t USB_ReadInterrupts(USB_TypeDef *USBx) +{ + uint32_t tmpreg; + + tmpreg = USBx->ISTR; + return tmpreg; +} + +/** + * @brief USB_ReadDevAllOutEpInterrupt: return the USB device OUT endpoints interrupt status + * @param USBx : Selected device + * @retval HAL status + */ +uint32_t USB_ReadDevAllOutEpInterrupt(USB_TypeDef *USBx) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(USBx); + /* NOTE : - This function is not required by USB Device FS peripheral, it is used + only by USB OTG FS peripheral. + - This function is added to ensure compatibility across platforms. + */ + return (0); +} + +/** + * @brief USB_ReadDevAllInEpInterrupt: return the USB device IN endpoints interrupt status + * @param USBx : Selected device + * @retval HAL status + */ +uint32_t USB_ReadDevAllInEpInterrupt(USB_TypeDef *USBx) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(USBx); + /* NOTE : - This function is not required by USB Device FS peripheral, it is used + only by USB OTG FS peripheral. + - This function is added to ensure compatibility across platforms. + */ + return (0); +} + +/** + * @brief Returns Device OUT EP Interrupt register + * @param USBx : Selected device + * @param epnum : endpoint number + * This parameter can be a value from 0 to 15 + * @retval Device OUT EP Interrupt register + */ +uint32_t USB_ReadDevOutEPInterrupt(USB_TypeDef *USBx, uint8_t epnum) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(USBx); + UNUSED(epnum); + /* NOTE : - This function is not required by USB Device FS peripheral, it is used + only by USB OTG FS peripheral. + - This function is added to ensure compatibility across platforms. + */ + return (0); +} + +/** + * @brief Returns Device IN EP Interrupt register + * @param USBx : Selected device + * @param epnum : endpoint number + * This parameter can be a value from 0 to 15 + * @retval Device IN EP Interrupt register + */ +uint32_t USB_ReadDevInEPInterrupt(USB_TypeDef *USBx, uint8_t epnum) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(USBx); + UNUSED(epnum); + /* NOTE : - This function is not required by USB Device FS peripheral, it is used + only by USB OTG FS peripheral. + - This function is added to ensure compatibility across platforms. + */ + return (0); +} + +/** + * @brief USB_ClearInterrupts: clear a USB interrupt + * @param USBx Selected device + * @param interrupt interrupt flag + * @retval None + */ +void USB_ClearInterrupts(USB_TypeDef *USBx, uint32_t interrupt) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(USBx); + UNUSED(interrupt); + /* NOTE : - This function is not required by USB Device FS peripheral, it is used + only by USB OTG FS peripheral. + - This function is added to ensure compatibility across platforms. + */ +} + +/** + * @brief Prepare the EP0 to start the first control setup + * @param USBx Selected device + * @param psetup pointer to setup packet + * @retval HAL status + */ +HAL_StatusTypeDef USB_EP0_OutStart(USB_TypeDef *USBx, uint8_t *psetup) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(USBx); + UNUSED(psetup); + /* NOTE : - This function is not required by USB Device FS peripheral, it is used + only by USB OTG FS peripheral. + - This function is added to ensure compatibility across platforms. + */ + return HAL_OK; +} + +/** + * @brief USB_ActivateRemoteWakeup : active remote wakeup signalling + * @param USBx Selected device + * @retval HAL status + */ +HAL_StatusTypeDef USB_ActivateRemoteWakeup(USB_TypeDef *USBx) +{ + USBx->CNTR |= USB_CNTR_RESUME; + + return HAL_OK; +} + +/** + * @brief USB_DeActivateRemoteWakeup : de-active remote wakeup signalling + * @param USBx Selected device + * @retval HAL status + */ +HAL_StatusTypeDef USB_DeActivateRemoteWakeup(USB_TypeDef *USBx) +{ + USBx->CNTR &= ~(USB_CNTR_RESUME); + return HAL_OK; +} + +/** + * @brief Copy a buffer from user memory area to packet memory area (PMA) + * @param USBx USB peripheral instance register address. + * @param pbUsrBuf pointer to user memory area. + * @param wPMABufAddr address into PMA. + * @param wNBytes: no. of bytes to be copied. + * @retval None + */ +void USB_WritePMA(USB_TypeDef *USBx, uint8_t *pbUsrBuf, uint16_t wPMABufAddr, uint16_t wNBytes) +{ + uint32_t n = ((uint32_t)wNBytes + 1U) >> 1; + uint32_t BaseAddr = (uint32_t)USBx; + uint32_t i, temp1, temp2; + __IO uint16_t *pdwVal; + uint8_t *pBuf = pbUsrBuf; + + pdwVal = (__IO uint16_t *)(BaseAddr + 0x400U + ((uint32_t)wPMABufAddr * PMA_ACCESS)); + + for (i = n; i != 0U; i--) + { + temp1 = *pBuf; + pBuf++; + temp2 = temp1 | ((uint16_t)((uint16_t) *pBuf << 8)); + *pdwVal = (uint16_t)temp2; + pdwVal++; + +#if PMA_ACCESS > 1U + pdwVal++; +#endif + + pBuf++; + } +} + +/** + * @brief Copy a buffer from user memory area to packet memory area (PMA) + * @param USBx: USB peripheral instance register address. + * @param pbUsrBuf pointer to user memory area. + * @param wPMABufAddr address into PMA. + * @param wNBytes: no. of bytes to be copied. + * @retval None + */ +void USB_ReadPMA(USB_TypeDef *USBx, uint8_t *pbUsrBuf, uint16_t wPMABufAddr, uint16_t wNBytes) +{ + uint32_t n = (uint32_t)wNBytes >> 1; + uint32_t BaseAddr = (uint32_t)USBx; + uint32_t i, temp; + __IO uint16_t *pdwVal; + uint8_t *pBuf = pbUsrBuf; + + pdwVal = (__IO uint16_t *)(BaseAddr + 0x400U + ((uint32_t)wPMABufAddr * PMA_ACCESS)); + + for (i = n; i != 0U; i--) + { + temp = *(__IO uint16_t *)pdwVal; + pdwVal++; + *pBuf = (uint8_t)((temp >> 0) & 0xFFU); + pBuf++; + *pBuf = (uint8_t)((temp >> 8) & 0xFFU); + pBuf++; + +#if PMA_ACCESS > 1U + pdwVal++; +#endif + } + + if ((wNBytes % 2U) != 0U) + { + temp = *pdwVal; + *pBuf = (uint8_t)((temp >> 0) & 0xFFU); + } +} + + +/** + * @} + */ + +/** + * @} + */ +#endif /* defined (USB) */ +#endif /* defined (HAL_PCD_MODULE_ENABLED) || defined (HAL_HCD_MODULE_ENABLED) */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/test/STM32F072C8T6/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc/usbd_cdc.h b/test/STM32F072C8T6/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc/usbd_cdc.h new file mode 100644 index 0000000..6702b54 --- /dev/null +++ b/test/STM32F072C8T6/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc/usbd_cdc.h @@ -0,0 +1,179 @@ +/** + ****************************************************************************** + * @file usbd_cdc.h + * @author MCD Application Team + * @brief header file for the usbd_cdc.c file. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2015 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __USB_CDC_H +#define __USB_CDC_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_ioreq.h" + +/** @addtogroup STM32_USB_DEVICE_LIBRARY + * @{ + */ + +/** @defgroup usbd_cdc + * @brief This file is the Header file for usbd_cdc.c + * @{ + */ + + +/** @defgroup usbd_cdc_Exported_Defines + * @{ + */ +#define CDC_IN_EP 0x81U /* EP1 for data IN */ +#define CDC_OUT_EP 0x01U /* EP1 for data OUT */ +#define CDC_CMD_EP 0x82U /* EP2 for CDC commands */ + +#ifndef CDC_HS_BINTERVAL +#define CDC_HS_BINTERVAL 0x10U +#endif /* CDC_HS_BINTERVAL */ + +#ifndef CDC_FS_BINTERVAL +#define CDC_FS_BINTERVAL 0x10U +#endif /* CDC_FS_BINTERVAL */ + +/* CDC Endpoints parameters: you can fine tune these values depending on the needed baudrates and performance. */ +#define CDC_DATA_HS_MAX_PACKET_SIZE 512U /* Endpoint IN & OUT Packet size */ +#define CDC_DATA_FS_MAX_PACKET_SIZE 64U /* Endpoint IN & OUT Packet size */ +#define CDC_CMD_PACKET_SIZE 8U /* Control Endpoint Packet size */ + +#define USB_CDC_CONFIG_DESC_SIZ 67U +#define CDC_DATA_HS_IN_PACKET_SIZE CDC_DATA_HS_MAX_PACKET_SIZE +#define CDC_DATA_HS_OUT_PACKET_SIZE CDC_DATA_HS_MAX_PACKET_SIZE + +#define CDC_DATA_FS_IN_PACKET_SIZE CDC_DATA_FS_MAX_PACKET_SIZE +#define CDC_DATA_FS_OUT_PACKET_SIZE CDC_DATA_FS_MAX_PACKET_SIZE + +/*---------------------------------------------------------------------*/ +/* CDC definitions */ +/*---------------------------------------------------------------------*/ +#define CDC_SEND_ENCAPSULATED_COMMAND 0x00U +#define CDC_GET_ENCAPSULATED_RESPONSE 0x01U +#define CDC_SET_COMM_FEATURE 0x02U +#define CDC_GET_COMM_FEATURE 0x03U +#define CDC_CLEAR_COMM_FEATURE 0x04U +#define CDC_SET_LINE_CODING 0x20U +#define CDC_GET_LINE_CODING 0x21U +#define CDC_SET_CONTROL_LINE_STATE 0x22U +#define CDC_SEND_BREAK 0x23U + +/** + * @} + */ + + +/** @defgroup USBD_CORE_Exported_TypesDefinitions + * @{ + */ + +/** + * @} + */ +typedef struct +{ + uint32_t bitrate; + uint8_t format; + uint8_t paritytype; + uint8_t datatype; +} USBD_CDC_LineCodingTypeDef; + +typedef struct _USBD_CDC_Itf +{ + int8_t (* Init)(void); + int8_t (* DeInit)(void); + int8_t (* Control)(uint8_t cmd, uint8_t *pbuf, uint16_t length); + int8_t (* Receive)(uint8_t *Buf, uint32_t *Len); + +} USBD_CDC_ItfTypeDef; + + +typedef struct +{ + uint32_t data[CDC_DATA_HS_MAX_PACKET_SIZE / 4U]; /* Force 32bits alignment */ + uint8_t CmdOpCode; + uint8_t CmdLength; + uint8_t *RxBuffer; + uint8_t *TxBuffer; + uint32_t RxLength; + uint32_t TxLength; + + __IO uint32_t TxState; + __IO uint32_t RxState; +} +USBD_CDC_HandleTypeDef; + + + +/** @defgroup USBD_CORE_Exported_Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup USBD_CORE_Exported_Variables + * @{ + */ + +extern USBD_ClassTypeDef USBD_CDC; +#define USBD_CDC_CLASS &USBD_CDC +/** + * @} + */ + +/** @defgroup USB_CORE_Exported_Functions + * @{ + */ +uint8_t USBD_CDC_RegisterInterface(USBD_HandleTypeDef *pdev, + USBD_CDC_ItfTypeDef *fops); + +uint8_t USBD_CDC_SetTxBuffer(USBD_HandleTypeDef *pdev, + uint8_t *pbuff, + uint16_t length); + +uint8_t USBD_CDC_SetRxBuffer(USBD_HandleTypeDef *pdev, + uint8_t *pbuff); + +uint8_t USBD_CDC_ReceivePacket(USBD_HandleTypeDef *pdev); + +uint8_t USBD_CDC_TransmitPacket(USBD_HandleTypeDef *pdev); +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __USB_CDC_H */ +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/test/STM32F072C8T6/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.c b/test/STM32F072C8T6/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.c new file mode 100644 index 0000000..b27fb55 --- /dev/null +++ b/test/STM32F072C8T6/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.c @@ -0,0 +1,945 @@ +/** + ****************************************************************************** + * @file usbd_cdc.c + * @author MCD Application Team + * @brief This file provides the high layer firmware functions to manage the + * following functionalities of the USB CDC Class: + * - Initialization and Configuration of high and low layer + * - Enumeration as CDC Device (and enumeration for each implemented memory interface) + * - OUT/IN data transfer + * - Command IN transfer (class requests management) + * - Error management + * + * @verbatim + * + * =================================================================== + * CDC Class Driver Description + * =================================================================== + * This driver manages the "Universal Serial Bus Class Definitions for Communications Devices + * Revision 1.2 November 16, 2007" and the sub-protocol specification of "Universal Serial Bus + * Communications Class Subclass Specification for PSTN Devices Revision 1.2 February 9, 2007" + * This driver implements the following aspects of the specification: + * - Device descriptor management + * - Configuration descriptor management + * - Enumeration as CDC device with 2 data endpoints (IN and OUT) and 1 command endpoint (IN) + * - Requests management (as described in section 6.2 in specification) + * - Abstract Control Model compliant + * - Union Functional collection (using 1 IN endpoint for control) + * - Data interface class + * + * These aspects may be enriched or modified for a specific user application. + * + * This driver doesn't implement the following aspects of the specification + * (but it is possible to manage these features with some modifications on this driver): + * - Any class-specific aspect relative to communication classes should be managed by user application. + * - All communication classes other than PSTN are not managed + * + * @endverbatim + * + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2015 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* BSPDependencies +- "stm32xxxxx_{eval}{discovery}{nucleo_144}.c" +- "stm32xxxxx_{eval}{discovery}_io.c" +EndBSPDependencies */ + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_cdc.h" +#include "usbd_ctlreq.h" + + +/** @addtogroup STM32_USB_DEVICE_LIBRARY + * @{ + */ + + +/** @defgroup USBD_CDC + * @brief usbd core module + * @{ + */ + +/** @defgroup USBD_CDC_Private_TypesDefinitions + * @{ + */ +/** + * @} + */ + + +/** @defgroup USBD_CDC_Private_Defines + * @{ + */ +/** + * @} + */ + + +/** @defgroup USBD_CDC_Private_Macros + * @{ + */ + +/** + * @} + */ + + +/** @defgroup USBD_CDC_Private_FunctionPrototypes + * @{ + */ + + +static uint8_t USBD_CDC_Init(USBD_HandleTypeDef *pdev, + uint8_t cfgidx); + +static uint8_t USBD_CDC_DeInit(USBD_HandleTypeDef *pdev, + uint8_t cfgidx); + +static uint8_t USBD_CDC_Setup(USBD_HandleTypeDef *pdev, + USBD_SetupReqTypedef *req); + +static uint8_t USBD_CDC_DataIn(USBD_HandleTypeDef *pdev, + uint8_t epnum); + +static uint8_t USBD_CDC_DataOut(USBD_HandleTypeDef *pdev, + uint8_t epnum); + +static uint8_t USBD_CDC_EP0_RxReady(USBD_HandleTypeDef *pdev); + +static uint8_t *USBD_CDC_GetFSCfgDesc(uint16_t *length); + +static uint8_t *USBD_CDC_GetHSCfgDesc(uint16_t *length); + +static uint8_t *USBD_CDC_GetOtherSpeedCfgDesc(uint16_t *length); + +static uint8_t *USBD_CDC_GetOtherSpeedCfgDesc(uint16_t *length); + +uint8_t *USBD_CDC_GetDeviceQualifierDescriptor(uint16_t *length); + +/* USB Standard Device Descriptor */ +__ALIGN_BEGIN static uint8_t USBD_CDC_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] __ALIGN_END = +{ + USB_LEN_DEV_QUALIFIER_DESC, + USB_DESC_TYPE_DEVICE_QUALIFIER, + 0x00, + 0x02, + 0x00, + 0x00, + 0x00, + 0x40, + 0x01, + 0x00, +}; + +/** + * @} + */ + +/** @defgroup USBD_CDC_Private_Variables + * @{ + */ + + +/* CDC interface class callbacks structure */ +USBD_ClassTypeDef USBD_CDC = +{ + USBD_CDC_Init, + USBD_CDC_DeInit, + USBD_CDC_Setup, + NULL, /* EP0_TxSent, */ + USBD_CDC_EP0_RxReady, + USBD_CDC_DataIn, + USBD_CDC_DataOut, + NULL, + NULL, + NULL, + USBD_CDC_GetHSCfgDesc, + USBD_CDC_GetFSCfgDesc, + USBD_CDC_GetOtherSpeedCfgDesc, + USBD_CDC_GetDeviceQualifierDescriptor, +}; + +/* USB CDC device Configuration Descriptor */ +__ALIGN_BEGIN uint8_t USBD_CDC_CfgHSDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END = +{ + /*Configuration Descriptor*/ + 0x09, /* bLength: Configuration Descriptor size */ + USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */ + USB_CDC_CONFIG_DESC_SIZ, /* wTotalLength:no of returned bytes */ + 0x00, + 0x02, /* bNumInterfaces: 2 interface */ + 0x01, /* bConfigurationValue: Configuration value */ + 0x00, /* iConfiguration: Index of string descriptor describing the configuration */ + 0xC0, /* bmAttributes: self powered */ + 0x32, /* MaxPower 0 mA */ + + /*---------------------------------------------------------------------------*/ + + /*Interface Descriptor */ + 0x09, /* bLength: Interface Descriptor size */ + USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface */ + /* Interface descriptor type */ + 0x00, /* bInterfaceNumber: Number of Interface */ + 0x00, /* bAlternateSetting: Alternate setting */ + 0x01, /* bNumEndpoints: One endpoints used */ + 0x02, /* bInterfaceClass: Communication Interface Class */ + 0x02, /* bInterfaceSubClass: Abstract Control Model */ + 0x01, /* bInterfaceProtocol: Common AT commands */ + 0x00, /* iInterface: */ + + /*Header Functional Descriptor*/ + 0x05, /* bLength: Endpoint Descriptor size */ + 0x24, /* bDescriptorType: CS_INTERFACE */ + 0x00, /* bDescriptorSubtype: Header Func Desc */ + 0x10, /* bcdCDC: spec release number */ + 0x01, + + /*Call Management Functional Descriptor*/ + 0x05, /* bFunctionLength */ + 0x24, /* bDescriptorType: CS_INTERFACE */ + 0x01, /* bDescriptorSubtype: Call Management Func Desc */ + 0x00, /* bmCapabilities: D0+D1 */ + 0x01, /* bDataInterface: 1 */ + + /*ACM Functional Descriptor*/ + 0x04, /* bFunctionLength */ + 0x24, /* bDescriptorType: CS_INTERFACE */ + 0x02, /* bDescriptorSubtype: Abstract Control Management desc */ + 0x02, /* bmCapabilities */ + + /*Union Functional Descriptor*/ + 0x05, /* bFunctionLength */ + 0x24, /* bDescriptorType: CS_INTERFACE */ + 0x06, /* bDescriptorSubtype: Union func desc */ + 0x00, /* bMasterInterface: Communication class interface */ + 0x01, /* bSlaveInterface0: Data Class Interface */ + + /*Endpoint 2 Descriptor*/ + 0x07, /* bLength: Endpoint Descriptor size */ + USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ + CDC_CMD_EP, /* bEndpointAddress */ + 0x03, /* bmAttributes: Interrupt */ + LOBYTE(CDC_CMD_PACKET_SIZE), /* wMaxPacketSize: */ + HIBYTE(CDC_CMD_PACKET_SIZE), + CDC_HS_BINTERVAL, /* bInterval: */ + /*---------------------------------------------------------------------------*/ + + /*Data class interface descriptor*/ + 0x09, /* bLength: Endpoint Descriptor size */ + USB_DESC_TYPE_INTERFACE, /* bDescriptorType: */ + 0x01, /* bInterfaceNumber: Number of Interface */ + 0x00, /* bAlternateSetting: Alternate setting */ + 0x02, /* bNumEndpoints: Two endpoints used */ + 0x0A, /* bInterfaceClass: CDC */ + 0x00, /* bInterfaceSubClass: */ + 0x00, /* bInterfaceProtocol: */ + 0x00, /* iInterface: */ + + /*Endpoint OUT Descriptor*/ + 0x07, /* bLength: Endpoint Descriptor size */ + USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ + CDC_OUT_EP, /* bEndpointAddress */ + 0x02, /* bmAttributes: Bulk */ + LOBYTE(CDC_DATA_HS_MAX_PACKET_SIZE), /* wMaxPacketSize: */ + HIBYTE(CDC_DATA_HS_MAX_PACKET_SIZE), + 0x00, /* bInterval: ignore for Bulk transfer */ + + /*Endpoint IN Descriptor*/ + 0x07, /* bLength: Endpoint Descriptor size */ + USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ + CDC_IN_EP, /* bEndpointAddress */ + 0x02, /* bmAttributes: Bulk */ + LOBYTE(CDC_DATA_HS_MAX_PACKET_SIZE), /* wMaxPacketSize: */ + HIBYTE(CDC_DATA_HS_MAX_PACKET_SIZE), + 0x00 /* bInterval: ignore for Bulk transfer */ +} ; + + +/* USB CDC device Configuration Descriptor */ +__ALIGN_BEGIN uint8_t USBD_CDC_CfgFSDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END = +{ + /*Configuration Descriptor*/ + 0x09, /* bLength: Configuration Descriptor size */ + USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */ + USB_CDC_CONFIG_DESC_SIZ, /* wTotalLength:no of returned bytes */ + 0x00, + 0x02, /* bNumInterfaces: 2 interface */ + 0x01, /* bConfigurationValue: Configuration value */ + 0x00, /* iConfiguration: Index of string descriptor describing the configuration */ + 0xC0, /* bmAttributes: self powered */ + 0x32, /* MaxPower 0 mA */ + + /*---------------------------------------------------------------------------*/ + + /*Interface Descriptor */ + 0x09, /* bLength: Interface Descriptor size */ + USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface */ + /* Interface descriptor type */ + 0x00, /* bInterfaceNumber: Number of Interface */ + 0x00, /* bAlternateSetting: Alternate setting */ + 0x01, /* bNumEndpoints: One endpoints used */ + 0x02, /* bInterfaceClass: Communication Interface Class */ + 0x02, /* bInterfaceSubClass: Abstract Control Model */ + 0x01, /* bInterfaceProtocol: Common AT commands */ + 0x00, /* iInterface: */ + + /*Header Functional Descriptor*/ + 0x05, /* bLength: Endpoint Descriptor size */ + 0x24, /* bDescriptorType: CS_INTERFACE */ + 0x00, /* bDescriptorSubtype: Header Func Desc */ + 0x10, /* bcdCDC: spec release number */ + 0x01, + + /*Call Management Functional Descriptor*/ + 0x05, /* bFunctionLength */ + 0x24, /* bDescriptorType: CS_INTERFACE */ + 0x01, /* bDescriptorSubtype: Call Management Func Desc */ + 0x00, /* bmCapabilities: D0+D1 */ + 0x01, /* bDataInterface: 1 */ + + /*ACM Functional Descriptor*/ + 0x04, /* bFunctionLength */ + 0x24, /* bDescriptorType: CS_INTERFACE */ + 0x02, /* bDescriptorSubtype: Abstract Control Management desc */ + 0x02, /* bmCapabilities */ + + /*Union Functional Descriptor*/ + 0x05, /* bFunctionLength */ + 0x24, /* bDescriptorType: CS_INTERFACE */ + 0x06, /* bDescriptorSubtype: Union func desc */ + 0x00, /* bMasterInterface: Communication class interface */ + 0x01, /* bSlaveInterface0: Data Class Interface */ + + /*Endpoint 2 Descriptor*/ + 0x07, /* bLength: Endpoint Descriptor size */ + USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ + CDC_CMD_EP, /* bEndpointAddress */ + 0x03, /* bmAttributes: Interrupt */ + LOBYTE(CDC_CMD_PACKET_SIZE), /* wMaxPacketSize: */ + HIBYTE(CDC_CMD_PACKET_SIZE), + CDC_FS_BINTERVAL, /* bInterval: */ + /*---------------------------------------------------------------------------*/ + + /*Data class interface descriptor*/ + 0x09, /* bLength: Endpoint Descriptor size */ + USB_DESC_TYPE_INTERFACE, /* bDescriptorType: */ + 0x01, /* bInterfaceNumber: Number of Interface */ + 0x00, /* bAlternateSetting: Alternate setting */ + 0x02, /* bNumEndpoints: Two endpoints used */ + 0x0A, /* bInterfaceClass: CDC */ + 0x00, /* bInterfaceSubClass: */ + 0x00, /* bInterfaceProtocol: */ + 0x00, /* iInterface: */ + + /*Endpoint OUT Descriptor*/ + 0x07, /* bLength: Endpoint Descriptor size */ + USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ + CDC_OUT_EP, /* bEndpointAddress */ + 0x02, /* bmAttributes: Bulk */ + LOBYTE(CDC_DATA_FS_MAX_PACKET_SIZE), /* wMaxPacketSize: */ + HIBYTE(CDC_DATA_FS_MAX_PACKET_SIZE), + 0x00, /* bInterval: ignore for Bulk transfer */ + + /*Endpoint IN Descriptor*/ + 0x07, /* bLength: Endpoint Descriptor size */ + USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ + CDC_IN_EP, /* bEndpointAddress */ + 0x02, /* bmAttributes: Bulk */ + LOBYTE(CDC_DATA_FS_MAX_PACKET_SIZE), /* wMaxPacketSize: */ + HIBYTE(CDC_DATA_FS_MAX_PACKET_SIZE), + 0x00 /* bInterval: ignore for Bulk transfer */ +} ; + +__ALIGN_BEGIN uint8_t USBD_CDC_OtherSpeedCfgDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END = +{ + 0x09, /* bLength: Configuation Descriptor size */ + USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION, + USB_CDC_CONFIG_DESC_SIZ, + 0x00, + 0x02, /* bNumInterfaces: 2 interfaces */ + 0x01, /* bConfigurationValue: */ + 0x04, /* iConfiguration: */ + 0xC0, /* bmAttributes: */ + 0x32, /* MaxPower 100 mA */ + + /*Interface Descriptor */ + 0x09, /* bLength: Interface Descriptor size */ + USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface */ + /* Interface descriptor type */ + 0x00, /* bInterfaceNumber: Number of Interface */ + 0x00, /* bAlternateSetting: Alternate setting */ + 0x01, /* bNumEndpoints: One endpoints used */ + 0x02, /* bInterfaceClass: Communication Interface Class */ + 0x02, /* bInterfaceSubClass: Abstract Control Model */ + 0x01, /* bInterfaceProtocol: Common AT commands */ + 0x00, /* iInterface: */ + + /*Header Functional Descriptor*/ + 0x05, /* bLength: Endpoint Descriptor size */ + 0x24, /* bDescriptorType: CS_INTERFACE */ + 0x00, /* bDescriptorSubtype: Header Func Desc */ + 0x10, /* bcdCDC: spec release number */ + 0x01, + + /*Call Management Functional Descriptor*/ + 0x05, /* bFunctionLength */ + 0x24, /* bDescriptorType: CS_INTERFACE */ + 0x01, /* bDescriptorSubtype: Call Management Func Desc */ + 0x00, /* bmCapabilities: D0+D1 */ + 0x01, /* bDataInterface: 1 */ + + /*ACM Functional Descriptor*/ + 0x04, /* bFunctionLength */ + 0x24, /* bDescriptorType: CS_INTERFACE */ + 0x02, /* bDescriptorSubtype: Abstract Control Management desc */ + 0x02, /* bmCapabilities */ + + /*Union Functional Descriptor*/ + 0x05, /* bFunctionLength */ + 0x24, /* bDescriptorType: CS_INTERFACE */ + 0x06, /* bDescriptorSubtype: Union func desc */ + 0x00, /* bMasterInterface: Communication class interface */ + 0x01, /* bSlaveInterface0: Data Class Interface */ + + /*Endpoint 2 Descriptor*/ + 0x07, /* bLength: Endpoint Descriptor size */ + USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ + CDC_CMD_EP, /* bEndpointAddress */ + 0x03, /* bmAttributes: Interrupt */ + LOBYTE(CDC_CMD_PACKET_SIZE), /* wMaxPacketSize: */ + HIBYTE(CDC_CMD_PACKET_SIZE), + CDC_FS_BINTERVAL, /* bInterval: */ + + /*---------------------------------------------------------------------------*/ + + /*Data class interface descriptor*/ + 0x09, /* bLength: Endpoint Descriptor size */ + USB_DESC_TYPE_INTERFACE, /* bDescriptorType: */ + 0x01, /* bInterfaceNumber: Number of Interface */ + 0x00, /* bAlternateSetting: Alternate setting */ + 0x02, /* bNumEndpoints: Two endpoints used */ + 0x0A, /* bInterfaceClass: CDC */ + 0x00, /* bInterfaceSubClass: */ + 0x00, /* bInterfaceProtocol: */ + 0x00, /* iInterface: */ + + /*Endpoint OUT Descriptor*/ + 0x07, /* bLength: Endpoint Descriptor size */ + USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ + CDC_OUT_EP, /* bEndpointAddress */ + 0x02, /* bmAttributes: Bulk */ + 0x40, /* wMaxPacketSize: */ + 0x00, + 0x00, /* bInterval: ignore for Bulk transfer */ + + /*Endpoint IN Descriptor*/ + 0x07, /* bLength: Endpoint Descriptor size */ + USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ + CDC_IN_EP, /* bEndpointAddress */ + 0x02, /* bmAttributes: Bulk */ + 0x40, /* wMaxPacketSize: */ + 0x00, + 0x00 /* bInterval */ +}; + +/** + * @} + */ + +/** @defgroup USBD_CDC_Private_Functions + * @{ + */ + +/** + * @brief USBD_CDC_Init + * Initialize the CDC interface + * @param pdev: device instance + * @param cfgidx: Configuration index + * @retval status + */ +static uint8_t USBD_CDC_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx) +{ + uint8_t ret = 0U; + USBD_CDC_HandleTypeDef *hcdc; + + if (pdev->dev_speed == USBD_SPEED_HIGH) + { + /* Open EP IN */ + USBD_LL_OpenEP(pdev, CDC_IN_EP, USBD_EP_TYPE_BULK, + CDC_DATA_HS_IN_PACKET_SIZE); + + pdev->ep_in[CDC_IN_EP & 0xFU].is_used = 1U; + + /* Open EP OUT */ + USBD_LL_OpenEP(pdev, CDC_OUT_EP, USBD_EP_TYPE_BULK, + CDC_DATA_HS_OUT_PACKET_SIZE); + + pdev->ep_out[CDC_OUT_EP & 0xFU].is_used = 1U; + + } + else + { + /* Open EP IN */ + USBD_LL_OpenEP(pdev, CDC_IN_EP, USBD_EP_TYPE_BULK, + CDC_DATA_FS_IN_PACKET_SIZE); + + pdev->ep_in[CDC_IN_EP & 0xFU].is_used = 1U; + + /* Open EP OUT */ + USBD_LL_OpenEP(pdev, CDC_OUT_EP, USBD_EP_TYPE_BULK, + CDC_DATA_FS_OUT_PACKET_SIZE); + + pdev->ep_out[CDC_OUT_EP & 0xFU].is_used = 1U; + } + /* Open Command IN EP */ + USBD_LL_OpenEP(pdev, CDC_CMD_EP, USBD_EP_TYPE_INTR, CDC_CMD_PACKET_SIZE); + pdev->ep_in[CDC_CMD_EP & 0xFU].is_used = 1U; + + pdev->pClassData = USBD_malloc(sizeof(USBD_CDC_HandleTypeDef)); + + if (pdev->pClassData == NULL) + { + ret = 1U; + } + else + { + hcdc = (USBD_CDC_HandleTypeDef *) pdev->pClassData; + + /* Init physical Interface components */ + ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Init(); + + /* Init Xfer states */ + hcdc->TxState = 0U; + hcdc->RxState = 0U; + + if (pdev->dev_speed == USBD_SPEED_HIGH) + { + /* Prepare Out endpoint to receive next packet */ + USBD_LL_PrepareReceive(pdev, CDC_OUT_EP, hcdc->RxBuffer, + CDC_DATA_HS_OUT_PACKET_SIZE); + } + else + { + /* Prepare Out endpoint to receive next packet */ + USBD_LL_PrepareReceive(pdev, CDC_OUT_EP, hcdc->RxBuffer, + CDC_DATA_FS_OUT_PACKET_SIZE); + } + } + return ret; +} + +/** + * @brief USBD_CDC_Init + * DeInitialize the CDC layer + * @param pdev: device instance + * @param cfgidx: Configuration index + * @retval status + */ +static uint8_t USBD_CDC_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx) +{ + uint8_t ret = 0U; + + /* Close EP IN */ + USBD_LL_CloseEP(pdev, CDC_IN_EP); + pdev->ep_in[CDC_IN_EP & 0xFU].is_used = 0U; + + /* Close EP OUT */ + USBD_LL_CloseEP(pdev, CDC_OUT_EP); + pdev->ep_out[CDC_OUT_EP & 0xFU].is_used = 0U; + + /* Close Command IN EP */ + USBD_LL_CloseEP(pdev, CDC_CMD_EP); + pdev->ep_in[CDC_CMD_EP & 0xFU].is_used = 0U; + + /* DeInit physical Interface components */ + if (pdev->pClassData != NULL) + { + ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->DeInit(); + USBD_free(pdev->pClassData); + pdev->pClassData = NULL; + } + + return ret; +} + +/** + * @brief USBD_CDC_Setup + * Handle the CDC specific requests + * @param pdev: instance + * @param req: usb requests + * @retval status + */ +static uint8_t USBD_CDC_Setup(USBD_HandleTypeDef *pdev, + USBD_SetupReqTypedef *req) +{ + USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *) pdev->pClassData; + uint8_t ifalt = 0U; + uint16_t status_info = 0U; + uint8_t ret = USBD_OK; + + switch (req->bmRequest & USB_REQ_TYPE_MASK) + { + case USB_REQ_TYPE_CLASS : + if (req->wLength) + { + if (req->bmRequest & 0x80U) + { + ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Control(req->bRequest, + (uint8_t *)(void *)hcdc->data, + req->wLength); + + USBD_CtlSendData(pdev, (uint8_t *)(void *)hcdc->data, req->wLength); + } + else + { + hcdc->CmdOpCode = req->bRequest; + hcdc->CmdLength = (uint8_t)req->wLength; + + USBD_CtlPrepareRx(pdev, (uint8_t *)(void *)hcdc->data, req->wLength); + } + } + else + { + ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Control(req->bRequest, + (uint8_t *)(void *)req, 0U); + } + break; + + case USB_REQ_TYPE_STANDARD: + switch (req->bRequest) + { + case USB_REQ_GET_STATUS: + if (pdev->dev_state == USBD_STATE_CONFIGURED) + { + USBD_CtlSendData(pdev, (uint8_t *)(void *)&status_info, 2U); + } + else + { + USBD_CtlError(pdev, req); + ret = USBD_FAIL; + } + break; + + case USB_REQ_GET_INTERFACE: + if (pdev->dev_state == USBD_STATE_CONFIGURED) + { + USBD_CtlSendData(pdev, &ifalt, 1U); + } + else + { + USBD_CtlError(pdev, req); + ret = USBD_FAIL; + } + break; + + case USB_REQ_SET_INTERFACE: + if (pdev->dev_state != USBD_STATE_CONFIGURED) + { + USBD_CtlError(pdev, req); + ret = USBD_FAIL; + } + break; + + default: + USBD_CtlError(pdev, req); + ret = USBD_FAIL; + break; + } + break; + + default: + USBD_CtlError(pdev, req); + ret = USBD_FAIL; + break; + } + + return ret; +} + +/** + * @brief USBD_CDC_DataIn + * Data sent on non-control IN endpoint + * @param pdev: device instance + * @param epnum: endpoint number + * @retval status + */ +static uint8_t USBD_CDC_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum) +{ + USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassData; + PCD_HandleTypeDef *hpcd = pdev->pData; + + if (pdev->pClassData != NULL) + { + if ((pdev->ep_in[epnum].total_length > 0U) && ((pdev->ep_in[epnum].total_length % hpcd->IN_ep[epnum].maxpacket) == 0U)) + { + /* Update the packet total length */ + pdev->ep_in[epnum].total_length = 0U; + + /* Send ZLP */ + USBD_LL_Transmit(pdev, epnum, NULL, 0U); + } + else + { + hcdc->TxState = 0U; + } + return USBD_OK; + } + else + { + return USBD_FAIL; + } +} + +/** + * @brief USBD_CDC_DataOut + * Data received on non-control Out endpoint + * @param pdev: device instance + * @param epnum: endpoint number + * @retval status + */ +static uint8_t USBD_CDC_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum) +{ + USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *) pdev->pClassData; + + /* Get the received data length */ + hcdc->RxLength = USBD_LL_GetRxDataSize(pdev, epnum); + + /* USB data will be immediately processed, this allow next USB traffic being + NAKed till the end of the application Xfer */ + if (pdev->pClassData != NULL) + { + ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Receive(hcdc->RxBuffer, &hcdc->RxLength); + + return USBD_OK; + } + else + { + return USBD_FAIL; + } +} + +/** + * @brief USBD_CDC_EP0_RxReady + * Handle EP0 Rx Ready event + * @param pdev: device instance + * @retval status + */ +static uint8_t USBD_CDC_EP0_RxReady(USBD_HandleTypeDef *pdev) +{ + USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *) pdev->pClassData; + + if ((pdev->pUserData != NULL) && (hcdc->CmdOpCode != 0xFFU)) + { + ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Control(hcdc->CmdOpCode, + (uint8_t *)(void *)hcdc->data, + (uint16_t)hcdc->CmdLength); + hcdc->CmdOpCode = 0xFFU; + + } + return USBD_OK; +} + +/** + * @brief USBD_CDC_GetFSCfgDesc + * Return configuration descriptor + * @param speed : current device speed + * @param length : pointer data length + * @retval pointer to descriptor buffer + */ +static uint8_t *USBD_CDC_GetFSCfgDesc(uint16_t *length) +{ + *length = sizeof(USBD_CDC_CfgFSDesc); + return USBD_CDC_CfgFSDesc; +} + +/** + * @brief USBD_CDC_GetHSCfgDesc + * Return configuration descriptor + * @param speed : current device speed + * @param length : pointer data length + * @retval pointer to descriptor buffer + */ +static uint8_t *USBD_CDC_GetHSCfgDesc(uint16_t *length) +{ + *length = sizeof(USBD_CDC_CfgHSDesc); + return USBD_CDC_CfgHSDesc; +} + +/** + * @brief USBD_CDC_GetCfgDesc + * Return configuration descriptor + * @param speed : current device speed + * @param length : pointer data length + * @retval pointer to descriptor buffer + */ +static uint8_t *USBD_CDC_GetOtherSpeedCfgDesc(uint16_t *length) +{ + *length = sizeof(USBD_CDC_OtherSpeedCfgDesc); + return USBD_CDC_OtherSpeedCfgDesc; +} + +/** +* @brief DeviceQualifierDescriptor +* return Device Qualifier descriptor +* @param length : pointer data length +* @retval pointer to descriptor buffer +*/ +uint8_t *USBD_CDC_GetDeviceQualifierDescriptor(uint16_t *length) +{ + *length = sizeof(USBD_CDC_DeviceQualifierDesc); + return USBD_CDC_DeviceQualifierDesc; +} + +/** +* @brief USBD_CDC_RegisterInterface + * @param pdev: device instance + * @param fops: CD Interface callback + * @retval status + */ +uint8_t USBD_CDC_RegisterInterface(USBD_HandleTypeDef *pdev, + USBD_CDC_ItfTypeDef *fops) +{ + uint8_t ret = USBD_FAIL; + + if (fops != NULL) + { + pdev->pUserData = fops; + ret = USBD_OK; + } + + return ret; +} + +/** + * @brief USBD_CDC_SetTxBuffer + * @param pdev: device instance + * @param pbuff: Tx Buffer + * @retval status + */ +uint8_t USBD_CDC_SetTxBuffer(USBD_HandleTypeDef *pdev, + uint8_t *pbuff, + uint16_t length) +{ + USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *) pdev->pClassData; + + hcdc->TxBuffer = pbuff; + hcdc->TxLength = length; + + return USBD_OK; +} + + +/** + * @brief USBD_CDC_SetRxBuffer + * @param pdev: device instance + * @param pbuff: Rx Buffer + * @retval status + */ +uint8_t USBD_CDC_SetRxBuffer(USBD_HandleTypeDef *pdev, + uint8_t *pbuff) +{ + USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *) pdev->pClassData; + + hcdc->RxBuffer = pbuff; + + return USBD_OK; +} + +/** + * @brief USBD_CDC_TransmitPacket + * Transmit packet on IN endpoint + * @param pdev: device instance + * @retval status + */ +uint8_t USBD_CDC_TransmitPacket(USBD_HandleTypeDef *pdev) +{ + USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *) pdev->pClassData; + + if (pdev->pClassData != NULL) + { + if (hcdc->TxState == 0U) + { + /* Tx Transfer in progress */ + hcdc->TxState = 1U; + + /* Update the packet total length */ + pdev->ep_in[CDC_IN_EP & 0xFU].total_length = hcdc->TxLength; + + /* Transmit next packet */ + USBD_LL_Transmit(pdev, CDC_IN_EP, hcdc->TxBuffer, + (uint16_t)hcdc->TxLength); + + return USBD_OK; + } + else + { + return USBD_BUSY; + } + } + else + { + return USBD_FAIL; + } +} + + +/** + * @brief USBD_CDC_ReceivePacket + * prepare OUT Endpoint for reception + * @param pdev: device instance + * @retval status + */ +uint8_t USBD_CDC_ReceivePacket(USBD_HandleTypeDef *pdev) +{ + USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *) pdev->pClassData; + + /* Suspend or Resume USB Out process */ + if (pdev->pClassData != NULL) + { + if (pdev->dev_speed == USBD_SPEED_HIGH) + { + /* Prepare Out endpoint to receive next packet */ + USBD_LL_PrepareReceive(pdev, + CDC_OUT_EP, + hcdc->RxBuffer, + CDC_DATA_HS_OUT_PACKET_SIZE); + } + else + { + /* Prepare Out endpoint to receive next packet */ + USBD_LL_PrepareReceive(pdev, + CDC_OUT_EP, + hcdc->RxBuffer, + CDC_DATA_FS_OUT_PACKET_SIZE); + } + return USBD_OK; + } + else + { + return USBD_FAIL; + } +} +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/test/STM32F072C8T6/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_core.h b/test/STM32F072C8T6/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_core.h new file mode 100644 index 0000000..030927b --- /dev/null +++ b/test/STM32F072C8T6/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_core.h @@ -0,0 +1,161 @@ +/** + ****************************************************************************** + * @file usbd_core.h + * @author MCD Application Team + * @brief Header file for usbd_core.c file + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2015 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __USBD_CORE_H +#define __USBD_CORE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_conf.h" +#include "usbd_def.h" +#include "usbd_ioreq.h" +#include "usbd_ctlreq.h" + +/** @addtogroup STM32_USB_DEVICE_LIBRARY + * @{ + */ + +/** @defgroup USBD_CORE + * @brief This file is the Header file for usbd_core.c file + * @{ + */ + + +/** @defgroup USBD_CORE_Exported_Defines + * @{ + */ +#ifndef USBD_DEBUG_LEVEL +#define USBD_DEBUG_LEVEL 0U +#endif /* USBD_DEBUG_LEVEL */ +/** + * @} + */ + + +/** @defgroup USBD_CORE_Exported_TypesDefinitions + * @{ + */ + + +/** + * @} + */ + + + +/** @defgroup USBD_CORE_Exported_Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup USBD_CORE_Exported_Variables + * @{ + */ +#define USBD_SOF USBD_LL_SOF +/** + * @} + */ + +/** @defgroup USBD_CORE_Exported_FunctionsPrototype + * @{ + */ +USBD_StatusTypeDef USBD_Init(USBD_HandleTypeDef *pdev, USBD_DescriptorsTypeDef *pdesc, uint8_t id); +USBD_StatusTypeDef USBD_DeInit(USBD_HandleTypeDef *pdev); +USBD_StatusTypeDef USBD_Start(USBD_HandleTypeDef *pdev); +USBD_StatusTypeDef USBD_Stop(USBD_HandleTypeDef *pdev); +USBD_StatusTypeDef USBD_RegisterClass(USBD_HandleTypeDef *pdev, USBD_ClassTypeDef *pclass); + +USBD_StatusTypeDef USBD_RunTestMode(USBD_HandleTypeDef *pdev); +USBD_StatusTypeDef USBD_SetClassConfig(USBD_HandleTypeDef *pdev, uint8_t cfgidx); +USBD_StatusTypeDef USBD_ClrClassConfig(USBD_HandleTypeDef *pdev, uint8_t cfgidx); + +USBD_StatusTypeDef USBD_LL_SetupStage(USBD_HandleTypeDef *pdev, uint8_t *psetup); +USBD_StatusTypeDef USBD_LL_DataOutStage(USBD_HandleTypeDef *pdev, uint8_t epnum, uint8_t *pdata); +USBD_StatusTypeDef USBD_LL_DataInStage(USBD_HandleTypeDef *pdev, uint8_t epnum, uint8_t *pdata); + +USBD_StatusTypeDef USBD_LL_Reset(USBD_HandleTypeDef *pdev); +USBD_StatusTypeDef USBD_LL_SetSpeed(USBD_HandleTypeDef *pdev, USBD_SpeedTypeDef speed); +USBD_StatusTypeDef USBD_LL_Suspend(USBD_HandleTypeDef *pdev); +USBD_StatusTypeDef USBD_LL_Resume(USBD_HandleTypeDef *pdev); + +USBD_StatusTypeDef USBD_LL_SOF(USBD_HandleTypeDef *pdev); +USBD_StatusTypeDef USBD_LL_IsoINIncomplete(USBD_HandleTypeDef *pdev, uint8_t epnum); +USBD_StatusTypeDef USBD_LL_IsoOUTIncomplete(USBD_HandleTypeDef *pdev, uint8_t epnum); + +USBD_StatusTypeDef USBD_LL_DevConnected(USBD_HandleTypeDef *pdev); +USBD_StatusTypeDef USBD_LL_DevDisconnected(USBD_HandleTypeDef *pdev); + +/* USBD Low Level Driver */ +USBD_StatusTypeDef USBD_LL_Init(USBD_HandleTypeDef *pdev); +USBD_StatusTypeDef USBD_LL_DeInit(USBD_HandleTypeDef *pdev); +USBD_StatusTypeDef USBD_LL_Start(USBD_HandleTypeDef *pdev); +USBD_StatusTypeDef USBD_LL_Stop(USBD_HandleTypeDef *pdev); +USBD_StatusTypeDef USBD_LL_OpenEP(USBD_HandleTypeDef *pdev, + uint8_t ep_addr, + uint8_t ep_type, + uint16_t ep_mps); + +USBD_StatusTypeDef USBD_LL_CloseEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr); +USBD_StatusTypeDef USBD_LL_FlushEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr); +USBD_StatusTypeDef USBD_LL_StallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr); +USBD_StatusTypeDef USBD_LL_ClearStallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr); +uint8_t USBD_LL_IsStallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr); +USBD_StatusTypeDef USBD_LL_SetUSBAddress(USBD_HandleTypeDef *pdev, uint8_t dev_addr); +USBD_StatusTypeDef USBD_LL_Transmit(USBD_HandleTypeDef *pdev, + uint8_t ep_addr, + uint8_t *pbuf, + uint16_t size); + +USBD_StatusTypeDef USBD_LL_PrepareReceive(USBD_HandleTypeDef *pdev, + uint8_t ep_addr, + uint8_t *pbuf, + uint16_t size); + +uint32_t USBD_LL_GetRxDataSize(USBD_HandleTypeDef *pdev, uint8_t ep_addr); +void USBD_LL_Delay(uint32_t Delay); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __USBD_CORE_H */ + +/** + * @} + */ + +/** +* @} +*/ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ + + + diff --git a/test/STM32F072C8T6/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_ctlreq.h b/test/STM32F072C8T6/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_ctlreq.h new file mode 100644 index 0000000..25a4758 --- /dev/null +++ b/test/STM32F072C8T6/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_ctlreq.h @@ -0,0 +1,105 @@ +/** + ****************************************************************************** + * @file usbd_req.h + * @author MCD Application Team + * @brief Header file for the usbd_req.c file + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2015 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __USB_REQUEST_H +#define __USB_REQUEST_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_def.h" + + +/** @addtogroup STM32_USB_DEVICE_LIBRARY + * @{ + */ + +/** @defgroup USBD_REQ + * @brief header file for the usbd_req.c file + * @{ + */ + +/** @defgroup USBD_REQ_Exported_Defines + * @{ + */ +/** + * @} + */ + + +/** @defgroup USBD_REQ_Exported_Types + * @{ + */ +/** + * @} + */ + + + +/** @defgroup USBD_REQ_Exported_Macros + * @{ + */ +/** + * @} + */ + +/** @defgroup USBD_REQ_Exported_Variables + * @{ + */ +/** + * @} + */ + +/** @defgroup USBD_REQ_Exported_FunctionsPrototype + * @{ + */ + +USBD_StatusTypeDef USBD_StdDevReq(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); +USBD_StatusTypeDef USBD_StdItfReq(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); +USBD_StatusTypeDef USBD_StdEPReq(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); + + +void USBD_CtlError(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); + +void USBD_ParseSetupRequest(USBD_SetupReqTypedef *req, uint8_t *pdata); + +void USBD_GetString(uint8_t *desc, uint8_t *unicode, uint16_t *len); +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __USB_REQUEST_H */ + +/** + * @} + */ + +/** +* @} +*/ + + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/test/STM32F072C8T6/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_def.h b/test/STM32F072C8T6/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_def.h new file mode 100644 index 0000000..8d7502f --- /dev/null +++ b/test/STM32F072C8T6/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_def.h @@ -0,0 +1,348 @@ +/** + ****************************************************************************** + * @file usbd_def.h + * @author MCD Application Team + * @brief General defines for the usb device library + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2015 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __USBD_DEF_H +#define __USBD_DEF_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_conf.h" + +/** @addtogroup STM32_USBD_DEVICE_LIBRARY + * @{ + */ + +/** @defgroup USB_DEF + * @brief general defines for the usb device library file + * @{ + */ + +/** @defgroup USB_DEF_Exported_Defines + * @{ + */ + +#ifndef NULL +#define NULL 0U +#endif /* NULL */ + +#ifndef USBD_MAX_NUM_INTERFACES +#define USBD_MAX_NUM_INTERFACES 1U +#endif /* USBD_MAX_NUM_CONFIGURATION */ + +#ifndef USBD_MAX_NUM_CONFIGURATION +#define USBD_MAX_NUM_CONFIGURATION 1U +#endif /* USBD_MAX_NUM_CONFIGURATION */ + +#ifndef USBD_LPM_ENABLED +#define USBD_LPM_ENABLED 0U +#endif /* USBD_LPM_ENABLED */ + +#ifndef USBD_SELF_POWERED +#define USBD_SELF_POWERED 1U +#endif /*USBD_SELF_POWERED */ + +#ifndef USBD_SUPPORT_USER_STRING_DESC +#define USBD_SUPPORT_USER_STRING_DESC 0U +#endif /* USBD_SUPPORT_USER_STRING_DESC */ + +#define USB_LEN_DEV_QUALIFIER_DESC 0x0AU +#define USB_LEN_DEV_DESC 0x12U +#define USB_LEN_CFG_DESC 0x09U +#define USB_LEN_IF_DESC 0x09U +#define USB_LEN_EP_DESC 0x07U +#define USB_LEN_OTG_DESC 0x03U +#define USB_LEN_LANGID_STR_DESC 0x04U +#define USB_LEN_OTHER_SPEED_DESC_SIZ 0x09U + +#define USBD_IDX_LANGID_STR 0x00U +#define USBD_IDX_MFC_STR 0x01U +#define USBD_IDX_PRODUCT_STR 0x02U +#define USBD_IDX_SERIAL_STR 0x03U +#define USBD_IDX_CONFIG_STR 0x04U +#define USBD_IDX_INTERFACE_STR 0x05U + +#define USB_REQ_TYPE_STANDARD 0x00U +#define USB_REQ_TYPE_CLASS 0x20U +#define USB_REQ_TYPE_VENDOR 0x40U +#define USB_REQ_TYPE_MASK 0x60U + +#define USB_REQ_RECIPIENT_DEVICE 0x00U +#define USB_REQ_RECIPIENT_INTERFACE 0x01U +#define USB_REQ_RECIPIENT_ENDPOINT 0x02U +#define USB_REQ_RECIPIENT_MASK 0x03U + +#define USB_REQ_GET_STATUS 0x00U +#define USB_REQ_CLEAR_FEATURE 0x01U +#define USB_REQ_SET_FEATURE 0x03U +#define USB_REQ_SET_ADDRESS 0x05U +#define USB_REQ_GET_DESCRIPTOR 0x06U +#define USB_REQ_SET_DESCRIPTOR 0x07U +#define USB_REQ_GET_CONFIGURATION 0x08U +#define USB_REQ_SET_CONFIGURATION 0x09U +#define USB_REQ_GET_INTERFACE 0x0AU +#define USB_REQ_SET_INTERFACE 0x0BU +#define USB_REQ_SYNCH_FRAME 0x0CU + +#define USB_DESC_TYPE_DEVICE 0x01U +#define USB_DESC_TYPE_CONFIGURATION 0x02U +#define USB_DESC_TYPE_STRING 0x03U +#define USB_DESC_TYPE_INTERFACE 0x04U +#define USB_DESC_TYPE_ENDPOINT 0x05U +#define USB_DESC_TYPE_DEVICE_QUALIFIER 0x06U +#define USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION 0x07U +#define USB_DESC_TYPE_BOS 0x0FU + +#define USB_CONFIG_REMOTE_WAKEUP 0x02U +#define USB_CONFIG_SELF_POWERED 0x01U + +#define USB_FEATURE_EP_HALT 0x00U +#define USB_FEATURE_REMOTE_WAKEUP 0x01U +#define USB_FEATURE_TEST_MODE 0x02U + +#define USB_DEVICE_CAPABITY_TYPE 0x10U + +#define USB_HS_MAX_PACKET_SIZE 512U +#define USB_FS_MAX_PACKET_SIZE 64U +#define USB_MAX_EP0_SIZE 64U + +/* Device Status */ +#define USBD_STATE_DEFAULT 0x01U +#define USBD_STATE_ADDRESSED 0x02U +#define USBD_STATE_CONFIGURED 0x03U +#define USBD_STATE_SUSPENDED 0x04U + + +/* EP0 State */ +#define USBD_EP0_IDLE 0x00U +#define USBD_EP0_SETUP 0x01U +#define USBD_EP0_DATA_IN 0x02U +#define USBD_EP0_DATA_OUT 0x03U +#define USBD_EP0_STATUS_IN 0x04U +#define USBD_EP0_STATUS_OUT 0x05U +#define USBD_EP0_STALL 0x06U + +#define USBD_EP_TYPE_CTRL 0x00U +#define USBD_EP_TYPE_ISOC 0x01U +#define USBD_EP_TYPE_BULK 0x02U +#define USBD_EP_TYPE_INTR 0x03U + + +/** + * @} + */ + + +/** @defgroup USBD_DEF_Exported_TypesDefinitions + * @{ + */ + +typedef struct usb_setup_req +{ + uint8_t bmRequest; + uint8_t bRequest; + uint16_t wValue; + uint16_t wIndex; + uint16_t wLength; +} USBD_SetupReqTypedef; + +struct _USBD_HandleTypeDef; + +typedef struct _Device_cb +{ + uint8_t (*Init)(struct _USBD_HandleTypeDef *pdev, uint8_t cfgidx); + uint8_t (*DeInit)(struct _USBD_HandleTypeDef *pdev, uint8_t cfgidx); + /* Control Endpoints*/ + uint8_t (*Setup)(struct _USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); + uint8_t (*EP0_TxSent)(struct _USBD_HandleTypeDef *pdev); + uint8_t (*EP0_RxReady)(struct _USBD_HandleTypeDef *pdev); + /* Class Specific Endpoints*/ + uint8_t (*DataIn)(struct _USBD_HandleTypeDef *pdev, uint8_t epnum); + uint8_t (*DataOut)(struct _USBD_HandleTypeDef *pdev, uint8_t epnum); + uint8_t (*SOF)(struct _USBD_HandleTypeDef *pdev); + uint8_t (*IsoINIncomplete)(struct _USBD_HandleTypeDef *pdev, uint8_t epnum); + uint8_t (*IsoOUTIncomplete)(struct _USBD_HandleTypeDef *pdev, uint8_t epnum); + + uint8_t *(*GetHSConfigDescriptor)(uint16_t *length); + uint8_t *(*GetFSConfigDescriptor)(uint16_t *length); + uint8_t *(*GetOtherSpeedConfigDescriptor)(uint16_t *length); + uint8_t *(*GetDeviceQualifierDescriptor)(uint16_t *length); +#if (USBD_SUPPORT_USER_STRING_DESC == 1U) + uint8_t *(*GetUsrStrDescriptor)(struct _USBD_HandleTypeDef *pdev, uint8_t index, uint16_t *length); +#endif + +} USBD_ClassTypeDef; + +/* Following USB Device Speed */ +typedef enum +{ + USBD_SPEED_HIGH = 0U, + USBD_SPEED_FULL = 1U, + USBD_SPEED_LOW = 2U, +} USBD_SpeedTypeDef; + +/* Following USB Device status */ +typedef enum +{ + USBD_OK = 0U, + USBD_BUSY, + USBD_FAIL, +} USBD_StatusTypeDef; + +/* USB Device descriptors structure */ +typedef struct +{ + uint8_t *(*GetDeviceDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length); + uint8_t *(*GetLangIDStrDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length); + uint8_t *(*GetManufacturerStrDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length); + uint8_t *(*GetProductStrDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length); + uint8_t *(*GetSerialStrDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length); + uint8_t *(*GetConfigurationStrDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length); + uint8_t *(*GetInterfaceStrDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length); +#if (USBD_LPM_ENABLED == 1U) + uint8_t *(*GetBOSDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length); +#endif +} USBD_DescriptorsTypeDef; + +/* USB Device handle structure */ +typedef struct +{ + uint32_t status; + uint32_t is_used; + uint32_t total_length; + uint32_t rem_length; + uint32_t maxpacket; +} USBD_EndpointTypeDef; + +/* USB Device handle structure */ +typedef struct _USBD_HandleTypeDef +{ + uint8_t id; + uint32_t dev_config; + uint32_t dev_default_config; + uint32_t dev_config_status; + USBD_SpeedTypeDef dev_speed; + USBD_EndpointTypeDef ep_in[16]; + USBD_EndpointTypeDef ep_out[16]; + uint32_t ep0_state; + uint32_t ep0_data_len; + uint8_t dev_state; + uint8_t dev_old_state; + uint8_t dev_address; + uint8_t dev_connection_status; + uint8_t dev_test_mode; + uint32_t dev_remote_wakeup; + + USBD_SetupReqTypedef request; + USBD_DescriptorsTypeDef *pDesc; + USBD_ClassTypeDef *pClass; + void *pClassData; + void *pUserData; + void *pData; +} USBD_HandleTypeDef; + +/** + * @} + */ + + + +/** @defgroup USBD_DEF_Exported_Macros + * @{ + */ +#define SWAPBYTE(addr) (((uint16_t)(*((uint8_t *)(addr)))) + \ + (((uint16_t)(*(((uint8_t *)(addr)) + 1U))) << 8U)) + +#define LOBYTE(x) ((uint8_t)((x) & 0x00FFU)) +#define HIBYTE(x) ((uint8_t)(((x) & 0xFF00U) >> 8U)) +#define MIN(a, b) (((a) < (b)) ? (a) : (b)) +#define MAX(a, b) (((a) > (b)) ? (a) : (b)) + + +#if defined ( __GNUC__ ) +#ifndef __weak +#define __weak __attribute__((weak)) +#endif /* __weak */ +#ifndef __packed +#define __packed __attribute__((__packed__)) +#endif /* __packed */ +#endif /* __GNUC__ */ + + +/* In HS mode and when the DMA is used, all variables and data structures dealing + with the DMA during the transaction process should be 4-bytes aligned */ + +#if defined ( __GNUC__ ) && !defined (__CC_ARM) /* GNU Compiler */ +#ifndef __ALIGN_END +#define __ALIGN_END __attribute__ ((aligned (4U))) +#endif /* __ALIGN_END */ +#ifndef __ALIGN_BEGIN +#define __ALIGN_BEGIN +#endif /* __ALIGN_BEGIN */ +#else +#ifndef __ALIGN_END +#define __ALIGN_END +#endif /* __ALIGN_END */ +#ifndef __ALIGN_BEGIN +#if defined (__CC_ARM) /* ARM Compiler */ +#define __ALIGN_BEGIN __align(4U) +#elif defined (__ICCARM__) /* IAR Compiler */ +#define __ALIGN_BEGIN +#endif /* __CC_ARM */ +#endif /* __ALIGN_BEGIN */ +#endif /* __GNUC__ */ + + +/** + * @} + */ + +/** @defgroup USBD_DEF_Exported_Variables + * @{ + */ + +/** + * @} + */ + +/** @defgroup USBD_DEF_Exported_FunctionsPrototype + * @{ + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __USBD_DEF_H */ + +/** + * @} + */ + +/** +* @} +*/ +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/test/STM32F072C8T6/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_ioreq.h b/test/STM32F072C8T6/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_ioreq.h new file mode 100644 index 0000000..8a6dd5f --- /dev/null +++ b/test/STM32F072C8T6/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_ioreq.h @@ -0,0 +1,119 @@ +/** + ****************************************************************************** + * @file usbd_ioreq.h + * @author MCD Application Team + * @brief Header file for the usbd_ioreq.c file + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2015 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __USBD_IOREQ_H +#define __USBD_IOREQ_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_def.h" +#include "usbd_core.h" + +/** @addtogroup STM32_USB_DEVICE_LIBRARY + * @{ + */ + +/** @defgroup USBD_IOREQ + * @brief header file for the usbd_ioreq.c file + * @{ + */ + +/** @defgroup USBD_IOREQ_Exported_Defines + * @{ + */ +/** + * @} + */ + + +/** @defgroup USBD_IOREQ_Exported_Types + * @{ + */ + + +/** + * @} + */ + + + +/** @defgroup USBD_IOREQ_Exported_Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup USBD_IOREQ_Exported_Variables + * @{ + */ + +/** + * @} + */ + +/** @defgroup USBD_IOREQ_Exported_FunctionsPrototype + * @{ + */ + +USBD_StatusTypeDef USBD_CtlSendData(USBD_HandleTypeDef *pdev, + uint8_t *pbuf, + uint16_t len); + +USBD_StatusTypeDef USBD_CtlContinueSendData(USBD_HandleTypeDef *pdev, + uint8_t *pbuf, + uint16_t len); + +USBD_StatusTypeDef USBD_CtlPrepareRx(USBD_HandleTypeDef *pdev, + uint8_t *pbuf, + uint16_t len); + +USBD_StatusTypeDef USBD_CtlContinueRx(USBD_HandleTypeDef *pdev, + uint8_t *pbuf, + uint16_t len); + +USBD_StatusTypeDef USBD_CtlSendStatus(USBD_HandleTypeDef *pdev); + +USBD_StatusTypeDef USBD_CtlReceiveStatus(USBD_HandleTypeDef *pdev); + +uint32_t USBD_GetRxCount(USBD_HandleTypeDef *pdev, uint8_t ep_addr); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __USBD_IOREQ_H */ + +/** + * @} + */ + +/** +* @} +*/ +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/test/STM32F072C8T6/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_core.c b/test/STM32F072C8T6/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_core.c new file mode 100644 index 0000000..b1a60ae --- /dev/null +++ b/test/STM32F072C8T6/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_core.c @@ -0,0 +1,611 @@ +/** + ****************************************************************************** + * @file usbd_core.c + * @author MCD Application Team + * @brief This file provides all the USBD core functions. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2015 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_core.h" + +/** @addtogroup STM32_USBD_DEVICE_LIBRARY +* @{ +*/ + + +/** @defgroup USBD_CORE +* @brief usbd core module +* @{ +*/ + +/** @defgroup USBD_CORE_Private_TypesDefinitions +* @{ +*/ + +/** +* @} +*/ + + +/** @defgroup USBD_CORE_Private_Defines +* @{ +*/ + +/** +* @} +*/ + + +/** @defgroup USBD_CORE_Private_Macros +* @{ +*/ + +/** +* @} +*/ + + +/** @defgroup USBD_CORE_Private_FunctionPrototypes +* @{ +*/ + +/** +* @} +*/ + +/** @defgroup USBD_CORE_Private_Variables +* @{ +*/ + +/** +* @} +*/ + + +/** @defgroup USBD_CORE_Private_Functions +* @{ +*/ + +/** +* @brief USBD_Init +* Initializes the device stack and load the class driver +* @param pdev: device instance +* @param pdesc: Descriptor structure address +* @param id: Low level core index +* @retval None +*/ +USBD_StatusTypeDef USBD_Init(USBD_HandleTypeDef *pdev, + USBD_DescriptorsTypeDef *pdesc, uint8_t id) +{ + /* Check whether the USB Host handle is valid */ + if (pdev == NULL) + { +#if (USBD_DEBUG_LEVEL > 1U) + USBD_ErrLog("Invalid Device handle"); +#endif + return USBD_FAIL; + } + + /* Unlink previous class*/ + if (pdev->pClass != NULL) + { + pdev->pClass = NULL; + } + + /* Assign USBD Descriptors */ + if (pdesc != NULL) + { + pdev->pDesc = pdesc; + } + + /* Set Device initial State */ + pdev->dev_state = USBD_STATE_DEFAULT; + pdev->id = id; + /* Initialize low level driver */ + USBD_LL_Init(pdev); + + return USBD_OK; +} + +/** +* @brief USBD_DeInit +* Re-Initialize th device library +* @param pdev: device instance +* @retval status: status +*/ +USBD_StatusTypeDef USBD_DeInit(USBD_HandleTypeDef *pdev) +{ + /* Set Default State */ + pdev->dev_state = USBD_STATE_DEFAULT; + + /* Free Class Resources */ + pdev->pClass->DeInit(pdev, (uint8_t)pdev->dev_config); + + /* Stop the low level driver */ + USBD_LL_Stop(pdev); + + /* Initialize low level driver */ + USBD_LL_DeInit(pdev); + + return USBD_OK; +} + +/** + * @brief USBD_RegisterClass + * Link class driver to Device Core. + * @param pDevice : Device Handle + * @param pclass: Class handle + * @retval USBD Status + */ +USBD_StatusTypeDef USBD_RegisterClass(USBD_HandleTypeDef *pdev, USBD_ClassTypeDef *pclass) +{ + USBD_StatusTypeDef status = USBD_OK; + if (pclass != NULL) + { + /* link the class to the USB Device handle */ + pdev->pClass = pclass; + status = USBD_OK; + } + else + { +#if (USBD_DEBUG_LEVEL > 1U) + USBD_ErrLog("Invalid Class handle"); +#endif + status = USBD_FAIL; + } + + return status; +} + +/** + * @brief USBD_Start + * Start the USB Device Core. + * @param pdev: Device Handle + * @retval USBD Status + */ +USBD_StatusTypeDef USBD_Start(USBD_HandleTypeDef *pdev) +{ + /* Start the low level driver */ + USBD_LL_Start(pdev); + + return USBD_OK; +} + +/** + * @brief USBD_Stop + * Stop the USB Device Core. + * @param pdev: Device Handle + * @retval USBD Status + */ +USBD_StatusTypeDef USBD_Stop(USBD_HandleTypeDef *pdev) +{ + /* Free Class Resources */ + pdev->pClass->DeInit(pdev, (uint8_t)pdev->dev_config); + + /* Stop the low level driver */ + USBD_LL_Stop(pdev); + + return USBD_OK; +} + +/** +* @brief USBD_RunTestMode +* Launch test mode process +* @param pdev: device instance +* @retval status +*/ +USBD_StatusTypeDef USBD_RunTestMode(USBD_HandleTypeDef *pdev) +{ + /* Prevent unused argument compilation warning */ + UNUSED(pdev); + + return USBD_OK; +} + +/** +* @brief USBD_SetClassConfig +* Configure device and start the interface +* @param pdev: device instance +* @param cfgidx: configuration index +* @retval status +*/ + +USBD_StatusTypeDef USBD_SetClassConfig(USBD_HandleTypeDef *pdev, uint8_t cfgidx) +{ + USBD_StatusTypeDef ret = USBD_FAIL; + + if (pdev->pClass != NULL) + { + /* Set configuration and Start the Class*/ + if (pdev->pClass->Init(pdev, cfgidx) == 0U) + { + ret = USBD_OK; + } + } + + return ret; +} + +/** +* @brief USBD_ClrClassConfig +* Clear current configuration +* @param pdev: device instance +* @param cfgidx: configuration index +* @retval status: USBD_StatusTypeDef +*/ +USBD_StatusTypeDef USBD_ClrClassConfig(USBD_HandleTypeDef *pdev, uint8_t cfgidx) +{ + /* Clear configuration and De-initialize the Class process*/ + pdev->pClass->DeInit(pdev, cfgidx); + + return USBD_OK; +} + + +/** +* @brief USBD_SetupStage +* Handle the setup stage +* @param pdev: device instance +* @retval status +*/ +USBD_StatusTypeDef USBD_LL_SetupStage(USBD_HandleTypeDef *pdev, uint8_t *psetup) +{ + USBD_ParseSetupRequest(&pdev->request, psetup); + + pdev->ep0_state = USBD_EP0_SETUP; + + pdev->ep0_data_len = pdev->request.wLength; + + switch (pdev->request.bmRequest & 0x1FU) + { + case USB_REQ_RECIPIENT_DEVICE: + USBD_StdDevReq(pdev, &pdev->request); + break; + + case USB_REQ_RECIPIENT_INTERFACE: + USBD_StdItfReq(pdev, &pdev->request); + break; + + case USB_REQ_RECIPIENT_ENDPOINT: + USBD_StdEPReq(pdev, &pdev->request); + break; + + default: + USBD_LL_StallEP(pdev, (pdev->request.bmRequest & 0x80U)); + break; + } + + return USBD_OK; +} + +/** +* @brief USBD_DataOutStage +* Handle data OUT stage +* @param pdev: device instance +* @param epnum: endpoint index +* @retval status +*/ +USBD_StatusTypeDef USBD_LL_DataOutStage(USBD_HandleTypeDef *pdev, + uint8_t epnum, uint8_t *pdata) +{ + USBD_EndpointTypeDef *pep; + + if (epnum == 0U) + { + pep = &pdev->ep_out[0]; + + if (pdev->ep0_state == USBD_EP0_DATA_OUT) + { + if (pep->rem_length > pep->maxpacket) + { + pep->rem_length -= pep->maxpacket; + + USBD_CtlContinueRx(pdev, pdata, + (uint16_t)MIN(pep->rem_length, pep->maxpacket)); + } + else + { + if ((pdev->pClass->EP0_RxReady != NULL) && + (pdev->dev_state == USBD_STATE_CONFIGURED)) + { + pdev->pClass->EP0_RxReady(pdev); + } + USBD_CtlSendStatus(pdev); + } + } + else + { + if (pdev->ep0_state == USBD_EP0_STATUS_OUT) + { + /* + * STATUS PHASE completed, update ep0_state to idle + */ + pdev->ep0_state = USBD_EP0_IDLE; + USBD_LL_StallEP(pdev, 0U); + } + } + } + else if ((pdev->pClass->DataOut != NULL) && + (pdev->dev_state == USBD_STATE_CONFIGURED)) + { + pdev->pClass->DataOut(pdev, epnum); + } + else + { + /* should never be in this condition */ + return USBD_FAIL; + } + + return USBD_OK; +} + +/** +* @brief USBD_DataInStage +* Handle data in stage +* @param pdev: device instance +* @param epnum: endpoint index +* @retval status +*/ +USBD_StatusTypeDef USBD_LL_DataInStage(USBD_HandleTypeDef *pdev, + uint8_t epnum, uint8_t *pdata) +{ + USBD_EndpointTypeDef *pep; + + if (epnum == 0U) + { + pep = &pdev->ep_in[0]; + + if (pdev->ep0_state == USBD_EP0_DATA_IN) + { + if (pep->rem_length > pep->maxpacket) + { + pep->rem_length -= pep->maxpacket; + + USBD_CtlContinueSendData(pdev, pdata, (uint16_t)pep->rem_length); + + /* Prepare endpoint for premature end of transfer */ + USBD_LL_PrepareReceive(pdev, 0U, NULL, 0U); + } + else + { + /* last packet is MPS multiple, so send ZLP packet */ + if ((pep->total_length % pep->maxpacket == 0U) && + (pep->total_length >= pep->maxpacket) && + (pep->total_length < pdev->ep0_data_len)) + { + USBD_CtlContinueSendData(pdev, NULL, 0U); + pdev->ep0_data_len = 0U; + + /* Prepare endpoint for premature end of transfer */ + USBD_LL_PrepareReceive(pdev, 0U, NULL, 0U); + } + else + { + if ((pdev->pClass->EP0_TxSent != NULL) && + (pdev->dev_state == USBD_STATE_CONFIGURED)) + { + pdev->pClass->EP0_TxSent(pdev); + } + USBD_LL_StallEP(pdev, 0x80U); + USBD_CtlReceiveStatus(pdev); + } + } + } + else + { + if ((pdev->ep0_state == USBD_EP0_STATUS_IN) || + (pdev->ep0_state == USBD_EP0_IDLE)) + { + USBD_LL_StallEP(pdev, 0x80U); + } + } + + if (pdev->dev_test_mode == 1U) + { + USBD_RunTestMode(pdev); + pdev->dev_test_mode = 0U; + } + } + else if ((pdev->pClass->DataIn != NULL) && + (pdev->dev_state == USBD_STATE_CONFIGURED)) + { + pdev->pClass->DataIn(pdev, epnum); + } + else + { + /* should never be in this condition */ + return USBD_FAIL; + } + + return USBD_OK; +} + +/** +* @brief USBD_LL_Reset +* Handle Reset event +* @param pdev: device instance +* @retval status +*/ + +USBD_StatusTypeDef USBD_LL_Reset(USBD_HandleTypeDef *pdev) +{ + /* Open EP0 OUT */ + USBD_LL_OpenEP(pdev, 0x00U, USBD_EP_TYPE_CTRL, USB_MAX_EP0_SIZE); + pdev->ep_out[0x00U & 0xFU].is_used = 1U; + + pdev->ep_out[0].maxpacket = USB_MAX_EP0_SIZE; + + /* Open EP0 IN */ + USBD_LL_OpenEP(pdev, 0x80U, USBD_EP_TYPE_CTRL, USB_MAX_EP0_SIZE); + pdev->ep_in[0x80U & 0xFU].is_used = 1U; + + pdev->ep_in[0].maxpacket = USB_MAX_EP0_SIZE; + + /* Upon Reset call user call back */ + pdev->dev_state = USBD_STATE_DEFAULT; + pdev->ep0_state = USBD_EP0_IDLE; + pdev->dev_config = 0U; + pdev->dev_remote_wakeup = 0U; + + if (pdev->pClassData) + { + pdev->pClass->DeInit(pdev, (uint8_t)pdev->dev_config); + } + + return USBD_OK; +} + +/** +* @brief USBD_LL_Reset +* Handle Reset event +* @param pdev: device instance +* @retval status +*/ +USBD_StatusTypeDef USBD_LL_SetSpeed(USBD_HandleTypeDef *pdev, + USBD_SpeedTypeDef speed) +{ + pdev->dev_speed = speed; + + return USBD_OK; +} + +/** +* @brief USBD_Suspend +* Handle Suspend event +* @param pdev: device instance +* @retval status +*/ + +USBD_StatusTypeDef USBD_LL_Suspend(USBD_HandleTypeDef *pdev) +{ + pdev->dev_old_state = pdev->dev_state; + pdev->dev_state = USBD_STATE_SUSPENDED; + + return USBD_OK; +} + +/** +* @brief USBD_Resume +* Handle Resume event +* @param pdev: device instance +* @retval status +*/ + +USBD_StatusTypeDef USBD_LL_Resume(USBD_HandleTypeDef *pdev) +{ + if (pdev->dev_state == USBD_STATE_SUSPENDED) + { + pdev->dev_state = pdev->dev_old_state; + } + + return USBD_OK; +} + +/** +* @brief USBD_SOF +* Handle SOF event +* @param pdev: device instance +* @retval status +*/ + +USBD_StatusTypeDef USBD_LL_SOF(USBD_HandleTypeDef *pdev) +{ + if (pdev->dev_state == USBD_STATE_CONFIGURED) + { + if (pdev->pClass->SOF != NULL) + { + pdev->pClass->SOF(pdev); + } + } + + return USBD_OK; +} + +/** +* @brief USBD_IsoINIncomplete +* Handle iso in incomplete event +* @param pdev: device instance +* @retval status +*/ +USBD_StatusTypeDef USBD_LL_IsoINIncomplete(USBD_HandleTypeDef *pdev, + uint8_t epnum) +{ + /* Prevent unused arguments compilation warning */ + UNUSED(pdev); + UNUSED(epnum); + + return USBD_OK; +} + +/** +* @brief USBD_IsoOUTIncomplete +* Handle iso out incomplete event +* @param pdev: device instance +* @retval status +*/ +USBD_StatusTypeDef USBD_LL_IsoOUTIncomplete(USBD_HandleTypeDef *pdev, + uint8_t epnum) +{ + /* Prevent unused arguments compilation warning */ + UNUSED(pdev); + UNUSED(epnum); + + return USBD_OK; +} + +/** +* @brief USBD_DevConnected +* Handle device connection event +* @param pdev: device instance +* @retval status +*/ +USBD_StatusTypeDef USBD_LL_DevConnected(USBD_HandleTypeDef *pdev) +{ + /* Prevent unused argument compilation warning */ + UNUSED(pdev); + + return USBD_OK; +} + +/** +* @brief USBD_DevDisconnected +* Handle device disconnection event +* @param pdev: device instance +* @retval status +*/ +USBD_StatusTypeDef USBD_LL_DevDisconnected(USBD_HandleTypeDef *pdev) +{ + /* Free Class Resources */ + pdev->dev_state = USBD_STATE_DEFAULT; + pdev->pClass->DeInit(pdev, (uint8_t)pdev->dev_config); + + return USBD_OK; +} +/** +* @} +*/ + + +/** +* @} +*/ + + +/** +* @} +*/ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ + diff --git a/test/STM32F072C8T6/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ctlreq.c b/test/STM32F072C8T6/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ctlreq.c new file mode 100644 index 0000000..e57c1bc --- /dev/null +++ b/test/STM32F072C8T6/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ctlreq.c @@ -0,0 +1,918 @@ +/** + ****************************************************************************** + * @file usbd_req.c + * @author MCD Application Team + * @brief This file provides the standard USB requests following chapter 9. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2015 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_ctlreq.h" +#include "usbd_ioreq.h" + + +/** @addtogroup STM32_USBD_STATE_DEVICE_LIBRARY + * @{ + */ + + +/** @defgroup USBD_REQ + * @brief USB standard requests module + * @{ + */ + +/** @defgroup USBD_REQ_Private_TypesDefinitions + * @{ + */ + +/** + * @} + */ + + +/** @defgroup USBD_REQ_Private_Defines + * @{ + */ + +/** + * @} + */ + + +/** @defgroup USBD_REQ_Private_Macros + * @{ + */ + +/** + * @} + */ + + +/** @defgroup USBD_REQ_Private_Variables + * @{ + */ + +/** + * @} + */ + + +/** @defgroup USBD_REQ_Private_FunctionPrototypes + * @{ + */ +static void USBD_GetDescriptor(USBD_HandleTypeDef *pdev, + USBD_SetupReqTypedef *req); + +static void USBD_SetAddress(USBD_HandleTypeDef *pdev, + USBD_SetupReqTypedef *req); + +static void USBD_SetConfig(USBD_HandleTypeDef *pdev, + USBD_SetupReqTypedef *req); + +static void USBD_GetConfig(USBD_HandleTypeDef *pdev, + USBD_SetupReqTypedef *req); + +static void USBD_GetStatus(USBD_HandleTypeDef *pdev, + USBD_SetupReqTypedef *req); + +static void USBD_SetFeature(USBD_HandleTypeDef *pdev, + USBD_SetupReqTypedef *req); + +static void USBD_ClrFeature(USBD_HandleTypeDef *pdev, + USBD_SetupReqTypedef *req); + +static uint8_t USBD_GetLen(uint8_t *buf); + +/** + * @} + */ + + +/** @defgroup USBD_REQ_Private_Functions + * @{ + */ + + +/** +* @brief USBD_StdDevReq +* Handle standard usb device requests +* @param pdev: device instance +* @param req: usb request +* @retval status +*/ +USBD_StatusTypeDef USBD_StdDevReq(USBD_HandleTypeDef *pdev, + USBD_SetupReqTypedef *req) +{ + USBD_StatusTypeDef ret = USBD_OK; + + switch (req->bmRequest & USB_REQ_TYPE_MASK) + { + case USB_REQ_TYPE_CLASS: + case USB_REQ_TYPE_VENDOR: + pdev->pClass->Setup(pdev, req); + break; + + case USB_REQ_TYPE_STANDARD: + switch (req->bRequest) + { + case USB_REQ_GET_DESCRIPTOR: + USBD_GetDescriptor(pdev, req); + break; + + case USB_REQ_SET_ADDRESS: + USBD_SetAddress(pdev, req); + break; + + case USB_REQ_SET_CONFIGURATION: + USBD_SetConfig(pdev, req); + break; + + case USB_REQ_GET_CONFIGURATION: + USBD_GetConfig(pdev, req); + break; + + case USB_REQ_GET_STATUS: + USBD_GetStatus(pdev, req); + break; + + case USB_REQ_SET_FEATURE: + USBD_SetFeature(pdev, req); + break; + + case USB_REQ_CLEAR_FEATURE: + USBD_ClrFeature(pdev, req); + break; + + default: + USBD_CtlError(pdev, req); + break; + } + break; + + default: + USBD_CtlError(pdev, req); + break; + } + + return ret; +} + +/** +* @brief USBD_StdItfReq +* Handle standard usb interface requests +* @param pdev: device instance +* @param req: usb request +* @retval status +*/ +USBD_StatusTypeDef USBD_StdItfReq(USBD_HandleTypeDef *pdev, + USBD_SetupReqTypedef *req) +{ + USBD_StatusTypeDef ret = USBD_OK; + + switch (req->bmRequest & USB_REQ_TYPE_MASK) + { + case USB_REQ_TYPE_CLASS: + case USB_REQ_TYPE_VENDOR: + case USB_REQ_TYPE_STANDARD: + switch (pdev->dev_state) + { + case USBD_STATE_DEFAULT: + case USBD_STATE_ADDRESSED: + case USBD_STATE_CONFIGURED: + + if (LOBYTE(req->wIndex) <= USBD_MAX_NUM_INTERFACES) + { + ret = (USBD_StatusTypeDef)pdev->pClass->Setup(pdev, req); + + if ((req->wLength == 0U) && (ret == USBD_OK)) + { + USBD_CtlSendStatus(pdev); + } + } + else + { + USBD_CtlError(pdev, req); + } + break; + + default: + USBD_CtlError(pdev, req); + break; + } + break; + + default: + USBD_CtlError(pdev, req); + break; + } + + return USBD_OK; +} + +/** +* @brief USBD_StdEPReq +* Handle standard usb endpoint requests +* @param pdev: device instance +* @param req: usb request +* @retval status +*/ +USBD_StatusTypeDef USBD_StdEPReq(USBD_HandleTypeDef *pdev, + USBD_SetupReqTypedef *req) +{ + USBD_EndpointTypeDef *pep; + uint8_t ep_addr; + USBD_StatusTypeDef ret = USBD_OK; + ep_addr = LOBYTE(req->wIndex); + + switch (req->bmRequest & USB_REQ_TYPE_MASK) + { + case USB_REQ_TYPE_CLASS: + case USB_REQ_TYPE_VENDOR: + pdev->pClass->Setup(pdev, req); + break; + + case USB_REQ_TYPE_STANDARD: + /* Check if it is a class request */ + if ((req->bmRequest & 0x60U) == 0x20U) + { + ret = (USBD_StatusTypeDef)pdev->pClass->Setup(pdev, req); + + return ret; + } + + switch (req->bRequest) + { + case USB_REQ_SET_FEATURE: + switch (pdev->dev_state) + { + case USBD_STATE_ADDRESSED: + if ((ep_addr != 0x00U) && (ep_addr != 0x80U)) + { + USBD_LL_StallEP(pdev, ep_addr); + USBD_LL_StallEP(pdev, 0x80U); + } + else + { + USBD_CtlError(pdev, req); + } + break; + + case USBD_STATE_CONFIGURED: + if (req->wValue == USB_FEATURE_EP_HALT) + { + if ((ep_addr != 0x00U) && + (ep_addr != 0x80U) && (req->wLength == 0x00U)) + { + USBD_LL_StallEP(pdev, ep_addr); + } + } + USBD_CtlSendStatus(pdev); + + break; + + default: + USBD_CtlError(pdev, req); + break; + } + break; + + case USB_REQ_CLEAR_FEATURE: + + switch (pdev->dev_state) + { + case USBD_STATE_ADDRESSED: + if ((ep_addr != 0x00U) && (ep_addr != 0x80U)) + { + USBD_LL_StallEP(pdev, ep_addr); + USBD_LL_StallEP(pdev, 0x80U); + } + else + { + USBD_CtlError(pdev, req); + } + break; + + case USBD_STATE_CONFIGURED: + if (req->wValue == USB_FEATURE_EP_HALT) + { + if ((ep_addr & 0x7FU) != 0x00U) + { + USBD_LL_ClearStallEP(pdev, ep_addr); + } + USBD_CtlSendStatus(pdev); + } + break; + + default: + USBD_CtlError(pdev, req); + break; + } + break; + + case USB_REQ_GET_STATUS: + switch (pdev->dev_state) + { + case USBD_STATE_ADDRESSED: + if ((ep_addr != 0x00U) && (ep_addr != 0x80U)) + { + USBD_CtlError(pdev, req); + break; + } + pep = ((ep_addr & 0x80U) == 0x80U) ? &pdev->ep_in[ep_addr & 0x7FU] : \ + &pdev->ep_out[ep_addr & 0x7FU]; + + pep->status = 0x0000U; + + USBD_CtlSendData(pdev, (uint8_t *)(void *)&pep->status, 2U); + break; + + case USBD_STATE_CONFIGURED: + if ((ep_addr & 0x80U) == 0x80U) + { + if (pdev->ep_in[ep_addr & 0xFU].is_used == 0U) + { + USBD_CtlError(pdev, req); + break; + } + } + else + { + if (pdev->ep_out[ep_addr & 0xFU].is_used == 0U) + { + USBD_CtlError(pdev, req); + break; + } + } + + pep = ((ep_addr & 0x80U) == 0x80U) ? &pdev->ep_in[ep_addr & 0x7FU] : \ + &pdev->ep_out[ep_addr & 0x7FU]; + + if ((ep_addr == 0x00U) || (ep_addr == 0x80U)) + { + pep->status = 0x0000U; + } + else if (USBD_LL_IsStallEP(pdev, ep_addr)) + { + pep->status = 0x0001U; + } + else + { + pep->status = 0x0000U; + } + + USBD_CtlSendData(pdev, (uint8_t *)(void *)&pep->status, 2U); + break; + + default: + USBD_CtlError(pdev, req); + break; + } + break; + + default: + USBD_CtlError(pdev, req); + break; + } + break; + + default: + USBD_CtlError(pdev, req); + break; + } + + return ret; +} + + +/** +* @brief USBD_GetDescriptor +* Handle Get Descriptor requests +* @param pdev: device instance +* @param req: usb request +* @retval status +*/ +static void USBD_GetDescriptor(USBD_HandleTypeDef *pdev, + USBD_SetupReqTypedef *req) +{ + uint16_t len = 0U; + uint8_t *pbuf = NULL; + uint8_t err = 0U; + + switch (req->wValue >> 8) + { +#if (USBD_LPM_ENABLED == 1U) + case USB_DESC_TYPE_BOS: + if (pdev->pDesc->GetBOSDescriptor != NULL) + { + pbuf = pdev->pDesc->GetBOSDescriptor(pdev->dev_speed, &len); + } + else + { + USBD_CtlError(pdev, req); + err++; + } + break; +#endif + case USB_DESC_TYPE_DEVICE: + pbuf = pdev->pDesc->GetDeviceDescriptor(pdev->dev_speed, &len); + break; + + case USB_DESC_TYPE_CONFIGURATION: + if (pdev->dev_speed == USBD_SPEED_HIGH) + { + pbuf = pdev->pClass->GetHSConfigDescriptor(&len); + pbuf[1] = USB_DESC_TYPE_CONFIGURATION; + } + else + { + pbuf = pdev->pClass->GetFSConfigDescriptor(&len); + pbuf[1] = USB_DESC_TYPE_CONFIGURATION; + } + break; + + case USB_DESC_TYPE_STRING: + switch ((uint8_t)(req->wValue)) + { + case USBD_IDX_LANGID_STR: + if (pdev->pDesc->GetLangIDStrDescriptor != NULL) + { + pbuf = pdev->pDesc->GetLangIDStrDescriptor(pdev->dev_speed, &len); + } + else + { + USBD_CtlError(pdev, req); + err++; + } + break; + + case USBD_IDX_MFC_STR: + if (pdev->pDesc->GetManufacturerStrDescriptor != NULL) + { + pbuf = pdev->pDesc->GetManufacturerStrDescriptor(pdev->dev_speed, &len); + } + else + { + USBD_CtlError(pdev, req); + err++; + } + break; + + case USBD_IDX_PRODUCT_STR: + if (pdev->pDesc->GetProductStrDescriptor != NULL) + { + pbuf = pdev->pDesc->GetProductStrDescriptor(pdev->dev_speed, &len); + } + else + { + USBD_CtlError(pdev, req); + err++; + } + break; + + case USBD_IDX_SERIAL_STR: + if (pdev->pDesc->GetSerialStrDescriptor != NULL) + { + pbuf = pdev->pDesc->GetSerialStrDescriptor(pdev->dev_speed, &len); + } + else + { + USBD_CtlError(pdev, req); + err++; + } + break; + + case USBD_IDX_CONFIG_STR: + if (pdev->pDesc->GetConfigurationStrDescriptor != NULL) + { + pbuf = pdev->pDesc->GetConfigurationStrDescriptor(pdev->dev_speed, &len); + } + else + { + USBD_CtlError(pdev, req); + err++; + } + break; + + case USBD_IDX_INTERFACE_STR: + if (pdev->pDesc->GetInterfaceStrDescriptor != NULL) + { + pbuf = pdev->pDesc->GetInterfaceStrDescriptor(pdev->dev_speed, &len); + } + else + { + USBD_CtlError(pdev, req); + err++; + } + break; + + default: +#if (USBD_SUPPORT_USER_STRING_DESC == 1U) + if (pdev->pClass->GetUsrStrDescriptor != NULL) + { + pbuf = pdev->pClass->GetUsrStrDescriptor(pdev, (req->wValue), &len); + } + else + { + USBD_CtlError(pdev, req); + err++; + } + break; +#else + USBD_CtlError(pdev, req); + err++; +#endif + } + break; + + case USB_DESC_TYPE_DEVICE_QUALIFIER: + if (pdev->dev_speed == USBD_SPEED_HIGH) + { + pbuf = pdev->pClass->GetDeviceQualifierDescriptor(&len); + } + else + { + USBD_CtlError(pdev, req); + err++; + } + break; + + case USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION: + if (pdev->dev_speed == USBD_SPEED_HIGH) + { + pbuf = pdev->pClass->GetOtherSpeedConfigDescriptor(&len); + pbuf[1] = USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION; + } + else + { + USBD_CtlError(pdev, req); + err++; + } + break; + + default: + USBD_CtlError(pdev, req); + err++; + break; + } + + if (err != 0U) + { + return; + } + else + { + if ((len != 0U) && (req->wLength != 0U)) + { + len = MIN(len, req->wLength); + (void)USBD_CtlSendData(pdev, pbuf, len); + } + + if (req->wLength == 0U) + { + (void)USBD_CtlSendStatus(pdev); + } + } +} + +/** +* @brief USBD_SetAddress +* Set device address +* @param pdev: device instance +* @param req: usb request +* @retval status +*/ +static void USBD_SetAddress(USBD_HandleTypeDef *pdev, + USBD_SetupReqTypedef *req) +{ + uint8_t dev_addr; + + if ((req->wIndex == 0U) && (req->wLength == 0U) && (req->wValue < 128U)) + { + dev_addr = (uint8_t)(req->wValue) & 0x7FU; + + if (pdev->dev_state == USBD_STATE_CONFIGURED) + { + USBD_CtlError(pdev, req); + } + else + { + pdev->dev_address = dev_addr; + USBD_LL_SetUSBAddress(pdev, dev_addr); + USBD_CtlSendStatus(pdev); + + if (dev_addr != 0U) + { + pdev->dev_state = USBD_STATE_ADDRESSED; + } + else + { + pdev->dev_state = USBD_STATE_DEFAULT; + } + } + } + else + { + USBD_CtlError(pdev, req); + } +} + +/** +* @brief USBD_SetConfig +* Handle Set device configuration request +* @param pdev: device instance +* @param req: usb request +* @retval status +*/ +static void USBD_SetConfig(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) +{ + static uint8_t cfgidx; + + cfgidx = (uint8_t)(req->wValue); + + if (cfgidx > USBD_MAX_NUM_CONFIGURATION) + { + USBD_CtlError(pdev, req); + } + else + { + switch (pdev->dev_state) + { + case USBD_STATE_ADDRESSED: + if (cfgidx) + { + pdev->dev_config = cfgidx; + pdev->dev_state = USBD_STATE_CONFIGURED; + if (USBD_SetClassConfig(pdev, cfgidx) == USBD_FAIL) + { + USBD_CtlError(pdev, req); + return; + } + USBD_CtlSendStatus(pdev); + } + else + { + USBD_CtlSendStatus(pdev); + } + break; + + case USBD_STATE_CONFIGURED: + if (cfgidx == 0U) + { + pdev->dev_state = USBD_STATE_ADDRESSED; + pdev->dev_config = cfgidx; + USBD_ClrClassConfig(pdev, cfgidx); + USBD_CtlSendStatus(pdev); + } + else if (cfgidx != pdev->dev_config) + { + /* Clear old configuration */ + USBD_ClrClassConfig(pdev, (uint8_t)pdev->dev_config); + + /* set new configuration */ + pdev->dev_config = cfgidx; + if (USBD_SetClassConfig(pdev, cfgidx) == USBD_FAIL) + { + USBD_CtlError(pdev, req); + return; + } + USBD_CtlSendStatus(pdev); + } + else + { + USBD_CtlSendStatus(pdev); + } + break; + + default: + USBD_CtlError(pdev, req); + USBD_ClrClassConfig(pdev, cfgidx); + break; + } + } +} + +/** +* @brief USBD_GetConfig +* Handle Get device configuration request +* @param pdev: device instance +* @param req: usb request +* @retval status +*/ +static void USBD_GetConfig(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) +{ + if (req->wLength != 1U) + { + USBD_CtlError(pdev, req); + } + else + { + switch (pdev->dev_state) + { + case USBD_STATE_DEFAULT: + case USBD_STATE_ADDRESSED: + pdev->dev_default_config = 0U; + USBD_CtlSendData(pdev, (uint8_t *)(void *)&pdev->dev_default_config, 1U); + break; + + case USBD_STATE_CONFIGURED: + USBD_CtlSendData(pdev, (uint8_t *)(void *)&pdev->dev_config, 1U); + break; + + default: + USBD_CtlError(pdev, req); + break; + } + } +} + +/** +* @brief USBD_GetStatus +* Handle Get Status request +* @param pdev: device instance +* @param req: usb request +* @retval status +*/ +static void USBD_GetStatus(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) +{ + switch (pdev->dev_state) + { + case USBD_STATE_DEFAULT: + case USBD_STATE_ADDRESSED: + case USBD_STATE_CONFIGURED: + if (req->wLength != 0x2U) + { + USBD_CtlError(pdev, req); + break; + } + +#if (USBD_SELF_POWERED == 1U) + pdev->dev_config_status = USB_CONFIG_SELF_POWERED; +#else + pdev->dev_config_status = 0U; +#endif + + if (pdev->dev_remote_wakeup) + { + pdev->dev_config_status |= USB_CONFIG_REMOTE_WAKEUP; + } + + USBD_CtlSendData(pdev, (uint8_t *)(void *)&pdev->dev_config_status, 2U); + break; + + default: + USBD_CtlError(pdev, req); + break; + } +} + + +/** +* @brief USBD_SetFeature +* Handle Set device feature request +* @param pdev: device instance +* @param req: usb request +* @retval status +*/ +static void USBD_SetFeature(USBD_HandleTypeDef *pdev, + USBD_SetupReqTypedef *req) +{ + if (req->wValue == USB_FEATURE_REMOTE_WAKEUP) + { + pdev->dev_remote_wakeup = 1U; + USBD_CtlSendStatus(pdev); + } +} + + +/** +* @brief USBD_ClrFeature +* Handle clear device feature request +* @param pdev: device instance +* @param req: usb request +* @retval status +*/ +static void USBD_ClrFeature(USBD_HandleTypeDef *pdev, + USBD_SetupReqTypedef *req) +{ + switch (pdev->dev_state) + { + case USBD_STATE_DEFAULT: + case USBD_STATE_ADDRESSED: + case USBD_STATE_CONFIGURED: + if (req->wValue == USB_FEATURE_REMOTE_WAKEUP) + { + pdev->dev_remote_wakeup = 0U; + USBD_CtlSendStatus(pdev); + } + break; + + default: + USBD_CtlError(pdev, req); + break; + } +} + +/** +* @brief USBD_ParseSetupRequest +* Copy buffer into setup structure +* @param pdev: device instance +* @param req: usb request +* @retval None +*/ + +void USBD_ParseSetupRequest(USBD_SetupReqTypedef *req, uint8_t *pdata) +{ + req->bmRequest = *(uint8_t *)(pdata); + req->bRequest = *(uint8_t *)(pdata + 1U); + req->wValue = SWAPBYTE(pdata + 2U); + req->wIndex = SWAPBYTE(pdata + 4U); + req->wLength = SWAPBYTE(pdata + 6U); + +} + +/** +* @brief USBD_CtlError +* Handle USB low level Error +* @param pdev: device instance +* @param req: usb request +* @retval None +*/ + +void USBD_CtlError(USBD_HandleTypeDef *pdev, + USBD_SetupReqTypedef *req) +{ + USBD_LL_StallEP(pdev, 0x80U); + USBD_LL_StallEP(pdev, 0U); +} + + +/** + * @brief USBD_GetString + * Convert Ascii string into unicode one + * @param desc : descriptor buffer + * @param unicode : Formatted string buffer (unicode) + * @param len : descriptor length + * @retval None + */ +void USBD_GetString(uint8_t *desc, uint8_t *unicode, uint16_t *len) +{ + uint8_t idx = 0U; + + if (desc != NULL) + { + *len = (uint16_t)USBD_GetLen(desc) * 2U + 2U; + unicode[idx++] = *(uint8_t *)(void *)len; + unicode[idx++] = USB_DESC_TYPE_STRING; + + while (*desc != '\0') + { + unicode[idx++] = *desc++; + unicode[idx++] = 0U; + } + } +} + +/** + * @brief USBD_GetLen + * return the string length + * @param buf : pointer to the ascii string buffer + * @retval string length + */ +static uint8_t USBD_GetLen(uint8_t *buf) +{ + uint8_t len = 0U; + + while (*buf != '\0') + { + len++; + buf++; + } + + return len; +} +/** + * @} + */ + + +/** + * @} + */ + + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/test/STM32F072C8T6/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ioreq.c b/test/STM32F072C8T6/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ioreq.c new file mode 100644 index 0000000..3351972 --- /dev/null +++ b/test/STM32F072C8T6/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ioreq.c @@ -0,0 +1,216 @@ +/** + ****************************************************************************** + * @file usbd_ioreq.c + * @author MCD Application Team + * @brief This file provides the IO requests APIs for control endpoints. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2015 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_ioreq.h" + +/** @addtogroup STM32_USB_DEVICE_LIBRARY + * @{ + */ + + +/** @defgroup USBD_IOREQ + * @brief control I/O requests module + * @{ + */ + +/** @defgroup USBD_IOREQ_Private_TypesDefinitions + * @{ + */ +/** + * @} + */ + + +/** @defgroup USBD_IOREQ_Private_Defines + * @{ + */ + +/** + * @} + */ + + +/** @defgroup USBD_IOREQ_Private_Macros + * @{ + */ +/** + * @} + */ + + +/** @defgroup USBD_IOREQ_Private_Variables + * @{ + */ + +/** + * @} + */ + + +/** @defgroup USBD_IOREQ_Private_FunctionPrototypes + * @{ + */ +/** + * @} + */ + + +/** @defgroup USBD_IOREQ_Private_Functions + * @{ + */ + +/** +* @brief USBD_CtlSendData +* send data on the ctl pipe +* @param pdev: device instance +* @param buff: pointer to data buffer +* @param len: length of data to be sent +* @retval status +*/ +USBD_StatusTypeDef USBD_CtlSendData(USBD_HandleTypeDef *pdev, + uint8_t *pbuf, uint16_t len) +{ + /* Set EP0 State */ + pdev->ep0_state = USBD_EP0_DATA_IN; + pdev->ep_in[0].total_length = len; + pdev->ep_in[0].rem_length = len; + + /* Start the transfer */ + USBD_LL_Transmit(pdev, 0x00U, pbuf, len); + + return USBD_OK; +} + +/** +* @brief USBD_CtlContinueSendData +* continue sending data on the ctl pipe +* @param pdev: device instance +* @param buff: pointer to data buffer +* @param len: length of data to be sent +* @retval status +*/ +USBD_StatusTypeDef USBD_CtlContinueSendData(USBD_HandleTypeDef *pdev, + uint8_t *pbuf, uint16_t len) +{ + /* Start the next transfer */ + USBD_LL_Transmit(pdev, 0x00U, pbuf, len); + + return USBD_OK; +} + +/** +* @brief USBD_CtlPrepareRx +* receive data on the ctl pipe +* @param pdev: device instance +* @param buff: pointer to data buffer +* @param len: length of data to be received +* @retval status +*/ +USBD_StatusTypeDef USBD_CtlPrepareRx(USBD_HandleTypeDef *pdev, + uint8_t *pbuf, uint16_t len) +{ + /* Set EP0 State */ + pdev->ep0_state = USBD_EP0_DATA_OUT; + pdev->ep_out[0].total_length = len; + pdev->ep_out[0].rem_length = len; + + /* Start the transfer */ + USBD_LL_PrepareReceive(pdev, 0U, pbuf, len); + + return USBD_OK; +} + +/** +* @brief USBD_CtlContinueRx +* continue receive data on the ctl pipe +* @param pdev: device instance +* @param buff: pointer to data buffer +* @param len: length of data to be received +* @retval status +*/ +USBD_StatusTypeDef USBD_CtlContinueRx(USBD_HandleTypeDef *pdev, + uint8_t *pbuf, uint16_t len) +{ + USBD_LL_PrepareReceive(pdev, 0U, pbuf, len); + + return USBD_OK; +} + +/** +* @brief USBD_CtlSendStatus +* send zero lzngth packet on the ctl pipe +* @param pdev: device instance +* @retval status +*/ +USBD_StatusTypeDef USBD_CtlSendStatus(USBD_HandleTypeDef *pdev) +{ + /* Set EP0 State */ + pdev->ep0_state = USBD_EP0_STATUS_IN; + + /* Start the transfer */ + USBD_LL_Transmit(pdev, 0x00U, NULL, 0U); + + return USBD_OK; +} + +/** +* @brief USBD_CtlReceiveStatus +* receive zero lzngth packet on the ctl pipe +* @param pdev: device instance +* @retval status +*/ +USBD_StatusTypeDef USBD_CtlReceiveStatus(USBD_HandleTypeDef *pdev) +{ + /* Set EP0 State */ + pdev->ep0_state = USBD_EP0_STATUS_OUT; + + /* Start the transfer */ + USBD_LL_PrepareReceive(pdev, 0U, NULL, 0U); + + return USBD_OK; +} + +/** +* @brief USBD_GetRxCount +* returns the received data length +* @param pdev: device instance +* @param ep_addr: endpoint address +* @retval Rx Data blength +*/ +uint32_t USBD_GetRxCount(USBD_HandleTypeDef *pdev, uint8_t ep_addr) +{ + return USBD_LL_GetRxDataSize(pdev, ep_addr); +} + +/** + * @} + */ + + +/** + * @} + */ + + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/test/STM32F072C8T6/STM32F072C8TX_FLASH.ld b/test/STM32F072C8T6/STM32F072C8TX_FLASH.ld new file mode 100644 index 0000000..1269c3d --- /dev/null +++ b/test/STM32F072C8T6/STM32F072C8TX_FLASH.ld @@ -0,0 +1,175 @@ +/** + ****************************************************************************** + * @file LinkerScript.ld + * @author Auto-generated by STM32CubeIDE + * @brief Linker script for STM32F072C8Tx Device from STM32F0 series + * 64Kbytes FLASH + * 16Kbytes RAM + * + * Set heap size, stack size and stack location according + * to application requirements. + * + * Set memory bank area and size if external memory is used + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2020 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/* Entry Point */ +ENTRY(Reset_Handler) + +/* Highest address of the user mode stack */ +_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */ + +_Min_Heap_Size = 0x200 ; /* required amount of heap */ +_Min_Stack_Size = 0x400 ; /* required amount of stack */ + +/* Memories definition */ +MEMORY +{ + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 16K + FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 64K +} + +/* Sections */ +SECTIONS +{ + /* The startup code into "FLASH" Rom type memory */ + .isr_vector : + { + . = ALIGN(4); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + } >FLASH + + /* The program code and other data into "FLASH" Rom type memory */ + .text : + { + . = ALIGN(4); + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + + KEEP (*(.init)) + KEEP (*(.fini)) + + . = ALIGN(4); + _etext = .; /* define a global symbols at end of code */ + } >FLASH + + /* Constant data into "FLASH" Rom type memory */ + .rodata : + { + . = ALIGN(4); + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + . = ALIGN(4); + } >FLASH + + .ARM.extab : { + . = ALIGN(4); + *(.ARM.extab* .gnu.linkonce.armextab.*) + . = ALIGN(4); + } >FLASH + + .ARM : { + . = ALIGN(4); + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + . = ALIGN(4); + } >FLASH + + .preinit_array : + { + . = ALIGN(4); + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + . = ALIGN(4); + } >FLASH + + .init_array : + { + . = ALIGN(4); + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + . = ALIGN(4); + } >FLASH + + .fini_array : + { + . = ALIGN(4); + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + . = ALIGN(4); + } >FLASH + + /* Used by the startup to initialize data */ + _sidata = LOADADDR(.data); + + /* Initialized data sections into "RAM" Ram type memory */ + .data : + { + . = ALIGN(4); + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + + . = ALIGN(4); + _edata = .; /* define a global symbol at data end */ + + } >RAM AT> FLASH + + /* Uninitialized data section into "RAM" Ram type memory */ + . = ALIGN(4); + .bss : + { + /* This is used by the startup in order to initialize the .bss section */ + _sbss = .; /* define a global symbol at bss start */ + __bss_start__ = _sbss; + *(.bss) + *(.bss*) + *(COMMON) + + . = ALIGN(4); + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + } >RAM + + /* User_heap_stack section, used to check that there is enough "RAM" Ram type memory left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >RAM + + /* Remove information from the compiler libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } +} diff --git a/test/STM32F072C8T6/bin/stm32f072_ecm.bin b/test/STM32F072C8T6/bin/stm32f072_ecm.bin new file mode 100644 index 0000000..1b331f7 Binary files /dev/null and b/test/STM32F072C8T6/bin/stm32f072_ecm.bin differ diff --git a/test/STM32F072C8T6/bin/stm32f072_ecm.elf b/test/STM32F072C8T6/bin/stm32f072_ecm.elf new file mode 100644 index 0000000..8455fb6 Binary files /dev/null and b/test/STM32F072C8T6/bin/stm32f072_ecm.elf differ diff --git a/test/STM32F072C8T6/bin/stm32f072_ecm.list b/test/STM32F072C8T6/bin/stm32f072_ecm.list new file mode 100644 index 0000000..750d244 --- /dev/null +++ b/test/STM32F072C8T6/bin/stm32f072_ecm.list @@ -0,0 +1,43014 @@ + +stm32f072_ecm.elf: file format elf32-littlearm + +Sections: +Idx Name Size VMA LMA File off Algn + 0 .isr_vector 000000c0 08000000 08000000 00010000 2**0 + CONTENTS, ALLOC, LOAD, READONLY, DATA + 1 .text 0000fc1c 080000c0 080000c0 000100c0 2**2 + CONTENTS, ALLOC, LOAD, READONLY, CODE + 2 .rodata 000001cc 0800fcdc 0800fcdc 0001fcdc 2**2 + CONTENTS, ALLOC, LOAD, READONLY, DATA + 3 .ARM.extab 00000000 0800fea8 0800fea8 0002009c 2**0 + CONTENTS + 4 .ARM 00000000 0800fea8 0800fea8 0002009c 2**0 + CONTENTS + 5 .preinit_array 00000000 0800fea8 0800fea8 0002009c 2**0 + CONTENTS, ALLOC, LOAD, DATA + 6 .init_array 00000004 0800fea8 0800fea8 0001fea8 2**2 + CONTENTS, ALLOC, LOAD, DATA + 7 .fini_array 00000004 0800feac 0800feac 0001feac 2**2 + CONTENTS, ALLOC, LOAD, DATA + 8 .data 0000009c 20000000 0800feb0 00020000 2**2 + CONTENTS, ALLOC, LOAD, DATA + 9 .bss 0000369c 2000009c 0800ff4c 0002009c 2**2 + ALLOC + 10 ._user_heap_stack 00000600 20003738 0800ff4c 00023738 2**0 + ALLOC + 11 .ARM.attributes 00000028 00000000 00000000 0002009c 2**0 + CONTENTS, READONLY + 12 .debug_info 00029068 00000000 00000000 000200c4 2**0 + CONTENTS, READONLY, DEBUGGING + 13 .debug_abbrev 00005bb1 00000000 00000000 0004912c 2**0 + CONTENTS, READONLY, DEBUGGING + 14 .debug_aranges 000012c8 00000000 00000000 0004ece0 2**3 + CONTENTS, READONLY, DEBUGGING + 15 .debug_ranges 000010e0 00000000 00000000 0004ffa8 2**3 + CONTENTS, READONLY, DEBUGGING + 16 .debug_macro 0001cd20 00000000 00000000 00051088 2**0 + CONTENTS, READONLY, DEBUGGING + 17 .debug_line 000169ee 00000000 00000000 0006dda8 2**0 + CONTENTS, READONLY, DEBUGGING + 18 .debug_str 00082af5 00000000 00000000 00084796 2**0 + CONTENTS, READONLY, DEBUGGING + 19 .comment 0000007b 00000000 00000000 0010728b 2**0 + CONTENTS, READONLY + 20 .debug_frame 00003e20 00000000 00000000 00107308 2**2 + CONTENTS, READONLY, DEBUGGING + +Disassembly of section .text: + +080000c0 <__do_global_dtors_aux>: + 80000c0: b510 push {r4, lr} + 80000c2: 4c06 ldr r4, [pc, #24] ; (80000dc <__do_global_dtors_aux+0x1c>) + 80000c4: 7823 ldrb r3, [r4, #0] + 80000c6: 2b00 cmp r3, #0 + 80000c8: d107 bne.n 80000da <__do_global_dtors_aux+0x1a> + 80000ca: 4b05 ldr r3, [pc, #20] ; (80000e0 <__do_global_dtors_aux+0x20>) + 80000cc: 2b00 cmp r3, #0 + 80000ce: d002 beq.n 80000d6 <__do_global_dtors_aux+0x16> + 80000d0: 4804 ldr r0, [pc, #16] ; (80000e4 <__do_global_dtors_aux+0x24>) + 80000d2: e000 b.n 80000d6 <__do_global_dtors_aux+0x16> + 80000d4: bf00 nop + 80000d6: 2301 movs r3, #1 + 80000d8: 7023 strb r3, [r4, #0] + 80000da: bd10 pop {r4, pc} + 80000dc: 2000009c .word 0x2000009c + 80000e0: 00000000 .word 0x00000000 + 80000e4: 0800fcc4 .word 0x0800fcc4 + +080000e8 : + 80000e8: 4b04 ldr r3, [pc, #16] ; (80000fc ) + 80000ea: b510 push {r4, lr} + 80000ec: 2b00 cmp r3, #0 + 80000ee: d003 beq.n 80000f8 + 80000f0: 4903 ldr r1, [pc, #12] ; (8000100 ) + 80000f2: 4804 ldr r0, [pc, #16] ; (8000104 ) + 80000f4: e000 b.n 80000f8 + 80000f6: bf00 nop + 80000f8: bd10 pop {r4, pc} + 80000fa: 46c0 nop ; (mov r8, r8) + 80000fc: 00000000 .word 0x00000000 + 8000100: 200000a0 .word 0x200000a0 + 8000104: 0800fcc4 .word 0x0800fcc4 + +08000108 : + 8000108: 7802 ldrb r2, [r0, #0] + 800010a: 780b ldrb r3, [r1, #0] + 800010c: 2a00 cmp r2, #0 + 800010e: d003 beq.n 8000118 + 8000110: 3001 adds r0, #1 + 8000112: 3101 adds r1, #1 + 8000114: 429a cmp r2, r3 + 8000116: d0f7 beq.n 8000108 + 8000118: 1ad0 subs r0, r2, r3 + 800011a: 4770 bx lr + +0800011c : + 800011c: 2300 movs r3, #0 + 800011e: 5cc2 ldrb r2, [r0, r3] + 8000120: 3301 adds r3, #1 + 8000122: 2a00 cmp r2, #0 + 8000124: d1fb bne.n 800011e + 8000126: 1e58 subs r0, r3, #1 + 8000128: 4770 bx lr + ... + +0800012c <__udivsi3>: + 800012c: 2200 movs r2, #0 + 800012e: 0843 lsrs r3, r0, #1 + 8000130: 428b cmp r3, r1 + 8000132: d374 bcc.n 800021e <__udivsi3+0xf2> + 8000134: 0903 lsrs r3, r0, #4 + 8000136: 428b cmp r3, r1 + 8000138: d35f bcc.n 80001fa <__udivsi3+0xce> + 800013a: 0a03 lsrs r3, r0, #8 + 800013c: 428b cmp r3, r1 + 800013e: d344 bcc.n 80001ca <__udivsi3+0x9e> + 8000140: 0b03 lsrs r3, r0, #12 + 8000142: 428b cmp r3, r1 + 8000144: d328 bcc.n 8000198 <__udivsi3+0x6c> + 8000146: 0c03 lsrs r3, r0, #16 + 8000148: 428b cmp r3, r1 + 800014a: d30d bcc.n 8000168 <__udivsi3+0x3c> + 800014c: 22ff movs r2, #255 ; 0xff + 800014e: 0209 lsls r1, r1, #8 + 8000150: ba12 rev r2, r2 + 8000152: 0c03 lsrs r3, r0, #16 + 8000154: 428b cmp r3, r1 + 8000156: d302 bcc.n 800015e <__udivsi3+0x32> + 8000158: 1212 asrs r2, r2, #8 + 800015a: 0209 lsls r1, r1, #8 + 800015c: d065 beq.n 800022a <__udivsi3+0xfe> + 800015e: 0b03 lsrs r3, r0, #12 + 8000160: 428b cmp r3, r1 + 8000162: d319 bcc.n 8000198 <__udivsi3+0x6c> + 8000164: e000 b.n 8000168 <__udivsi3+0x3c> + 8000166: 0a09 lsrs r1, r1, #8 + 8000168: 0bc3 lsrs r3, r0, #15 + 800016a: 428b cmp r3, r1 + 800016c: d301 bcc.n 8000172 <__udivsi3+0x46> + 800016e: 03cb lsls r3, r1, #15 + 8000170: 1ac0 subs r0, r0, r3 + 8000172: 4152 adcs r2, r2 + 8000174: 0b83 lsrs r3, r0, #14 + 8000176: 428b cmp r3, r1 + 8000178: d301 bcc.n 800017e <__udivsi3+0x52> + 800017a: 038b lsls r3, r1, #14 + 800017c: 1ac0 subs r0, r0, r3 + 800017e: 4152 adcs r2, r2 + 8000180: 0b43 lsrs r3, r0, #13 + 8000182: 428b cmp r3, r1 + 8000184: d301 bcc.n 800018a <__udivsi3+0x5e> + 8000186: 034b lsls r3, r1, #13 + 8000188: 1ac0 subs r0, r0, r3 + 800018a: 4152 adcs r2, r2 + 800018c: 0b03 lsrs r3, r0, #12 + 800018e: 428b cmp r3, r1 + 8000190: d301 bcc.n 8000196 <__udivsi3+0x6a> + 8000192: 030b lsls r3, r1, #12 + 8000194: 1ac0 subs r0, r0, r3 + 8000196: 4152 adcs r2, r2 + 8000198: 0ac3 lsrs r3, r0, #11 + 800019a: 428b cmp r3, r1 + 800019c: d301 bcc.n 80001a2 <__udivsi3+0x76> + 800019e: 02cb lsls r3, r1, #11 + 80001a0: 1ac0 subs r0, r0, r3 + 80001a2: 4152 adcs r2, r2 + 80001a4: 0a83 lsrs r3, r0, #10 + 80001a6: 428b cmp r3, r1 + 80001a8: d301 bcc.n 80001ae <__udivsi3+0x82> + 80001aa: 028b lsls r3, r1, #10 + 80001ac: 1ac0 subs r0, r0, r3 + 80001ae: 4152 adcs r2, r2 + 80001b0: 0a43 lsrs r3, r0, #9 + 80001b2: 428b cmp r3, r1 + 80001b4: d301 bcc.n 80001ba <__udivsi3+0x8e> + 80001b6: 024b lsls r3, r1, #9 + 80001b8: 1ac0 subs r0, r0, r3 + 80001ba: 4152 adcs r2, r2 + 80001bc: 0a03 lsrs r3, r0, #8 + 80001be: 428b cmp r3, r1 + 80001c0: d301 bcc.n 80001c6 <__udivsi3+0x9a> + 80001c2: 020b lsls r3, r1, #8 + 80001c4: 1ac0 subs r0, r0, r3 + 80001c6: 4152 adcs r2, r2 + 80001c8: d2cd bcs.n 8000166 <__udivsi3+0x3a> + 80001ca: 09c3 lsrs r3, r0, #7 + 80001cc: 428b cmp r3, r1 + 80001ce: d301 bcc.n 80001d4 <__udivsi3+0xa8> + 80001d0: 01cb lsls r3, r1, #7 + 80001d2: 1ac0 subs r0, r0, r3 + 80001d4: 4152 adcs r2, r2 + 80001d6: 0983 lsrs r3, r0, #6 + 80001d8: 428b cmp r3, r1 + 80001da: d301 bcc.n 80001e0 <__udivsi3+0xb4> + 80001dc: 018b lsls r3, r1, #6 + 80001de: 1ac0 subs r0, r0, r3 + 80001e0: 4152 adcs r2, r2 + 80001e2: 0943 lsrs r3, r0, #5 + 80001e4: 428b cmp r3, r1 + 80001e6: d301 bcc.n 80001ec <__udivsi3+0xc0> + 80001e8: 014b lsls r3, r1, #5 + 80001ea: 1ac0 subs r0, r0, r3 + 80001ec: 4152 adcs r2, r2 + 80001ee: 0903 lsrs r3, r0, #4 + 80001f0: 428b cmp r3, r1 + 80001f2: d301 bcc.n 80001f8 <__udivsi3+0xcc> + 80001f4: 010b lsls r3, r1, #4 + 80001f6: 1ac0 subs r0, r0, r3 + 80001f8: 4152 adcs r2, r2 + 80001fa: 08c3 lsrs r3, r0, #3 + 80001fc: 428b cmp r3, r1 + 80001fe: d301 bcc.n 8000204 <__udivsi3+0xd8> + 8000200: 00cb lsls r3, r1, #3 + 8000202: 1ac0 subs r0, r0, r3 + 8000204: 4152 adcs r2, r2 + 8000206: 0883 lsrs r3, r0, #2 + 8000208: 428b cmp r3, r1 + 800020a: d301 bcc.n 8000210 <__udivsi3+0xe4> + 800020c: 008b lsls r3, r1, #2 + 800020e: 1ac0 subs r0, r0, r3 + 8000210: 4152 adcs r2, r2 + 8000212: 0843 lsrs r3, r0, #1 + 8000214: 428b cmp r3, r1 + 8000216: d301 bcc.n 800021c <__udivsi3+0xf0> + 8000218: 004b lsls r3, r1, #1 + 800021a: 1ac0 subs r0, r0, r3 + 800021c: 4152 adcs r2, r2 + 800021e: 1a41 subs r1, r0, r1 + 8000220: d200 bcs.n 8000224 <__udivsi3+0xf8> + 8000222: 4601 mov r1, r0 + 8000224: 4152 adcs r2, r2 + 8000226: 4610 mov r0, r2 + 8000228: 4770 bx lr + 800022a: e7ff b.n 800022c <__udivsi3+0x100> + 800022c: b501 push {r0, lr} + 800022e: 2000 movs r0, #0 + 8000230: f000 f8f0 bl 8000414 <__aeabi_idiv0> + 8000234: bd02 pop {r1, pc} + 8000236: 46c0 nop ; (mov r8, r8) + +08000238 <__aeabi_uidivmod>: + 8000238: 2900 cmp r1, #0 + 800023a: d0f7 beq.n 800022c <__udivsi3+0x100> + 800023c: e776 b.n 800012c <__udivsi3> + 800023e: 4770 bx lr + +08000240 <__divsi3>: + 8000240: 4603 mov r3, r0 + 8000242: 430b orrs r3, r1 + 8000244: d47f bmi.n 8000346 <__divsi3+0x106> + 8000246: 2200 movs r2, #0 + 8000248: 0843 lsrs r3, r0, #1 + 800024a: 428b cmp r3, r1 + 800024c: d374 bcc.n 8000338 <__divsi3+0xf8> + 800024e: 0903 lsrs r3, r0, #4 + 8000250: 428b cmp r3, r1 + 8000252: d35f bcc.n 8000314 <__divsi3+0xd4> + 8000254: 0a03 lsrs r3, r0, #8 + 8000256: 428b cmp r3, r1 + 8000258: d344 bcc.n 80002e4 <__divsi3+0xa4> + 800025a: 0b03 lsrs r3, r0, #12 + 800025c: 428b cmp r3, r1 + 800025e: d328 bcc.n 80002b2 <__divsi3+0x72> + 8000260: 0c03 lsrs r3, r0, #16 + 8000262: 428b cmp r3, r1 + 8000264: d30d bcc.n 8000282 <__divsi3+0x42> + 8000266: 22ff movs r2, #255 ; 0xff + 8000268: 0209 lsls r1, r1, #8 + 800026a: ba12 rev r2, r2 + 800026c: 0c03 lsrs r3, r0, #16 + 800026e: 428b cmp r3, r1 + 8000270: d302 bcc.n 8000278 <__divsi3+0x38> + 8000272: 1212 asrs r2, r2, #8 + 8000274: 0209 lsls r1, r1, #8 + 8000276: d065 beq.n 8000344 <__divsi3+0x104> + 8000278: 0b03 lsrs r3, r0, #12 + 800027a: 428b cmp r3, r1 + 800027c: d319 bcc.n 80002b2 <__divsi3+0x72> + 800027e: e000 b.n 8000282 <__divsi3+0x42> + 8000280: 0a09 lsrs r1, r1, #8 + 8000282: 0bc3 lsrs r3, r0, #15 + 8000284: 428b cmp r3, r1 + 8000286: d301 bcc.n 800028c <__divsi3+0x4c> + 8000288: 03cb lsls r3, r1, #15 + 800028a: 1ac0 subs r0, r0, r3 + 800028c: 4152 adcs r2, r2 + 800028e: 0b83 lsrs r3, r0, #14 + 8000290: 428b cmp r3, r1 + 8000292: d301 bcc.n 8000298 <__divsi3+0x58> + 8000294: 038b lsls r3, r1, #14 + 8000296: 1ac0 subs r0, r0, r3 + 8000298: 4152 adcs r2, r2 + 800029a: 0b43 lsrs r3, r0, #13 + 800029c: 428b cmp r3, r1 + 800029e: d301 bcc.n 80002a4 <__divsi3+0x64> + 80002a0: 034b lsls r3, r1, #13 + 80002a2: 1ac0 subs r0, r0, r3 + 80002a4: 4152 adcs r2, r2 + 80002a6: 0b03 lsrs r3, r0, #12 + 80002a8: 428b cmp r3, r1 + 80002aa: d301 bcc.n 80002b0 <__divsi3+0x70> + 80002ac: 030b lsls r3, r1, #12 + 80002ae: 1ac0 subs r0, r0, r3 + 80002b0: 4152 adcs r2, r2 + 80002b2: 0ac3 lsrs r3, r0, #11 + 80002b4: 428b cmp r3, r1 + 80002b6: d301 bcc.n 80002bc <__divsi3+0x7c> + 80002b8: 02cb lsls r3, r1, #11 + 80002ba: 1ac0 subs r0, r0, r3 + 80002bc: 4152 adcs r2, r2 + 80002be: 0a83 lsrs r3, r0, #10 + 80002c0: 428b cmp r3, r1 + 80002c2: d301 bcc.n 80002c8 <__divsi3+0x88> + 80002c4: 028b lsls r3, r1, #10 + 80002c6: 1ac0 subs r0, r0, r3 + 80002c8: 4152 adcs r2, r2 + 80002ca: 0a43 lsrs r3, r0, #9 + 80002cc: 428b cmp r3, r1 + 80002ce: d301 bcc.n 80002d4 <__divsi3+0x94> + 80002d0: 024b lsls r3, r1, #9 + 80002d2: 1ac0 subs r0, r0, r3 + 80002d4: 4152 adcs r2, r2 + 80002d6: 0a03 lsrs r3, r0, #8 + 80002d8: 428b cmp r3, r1 + 80002da: d301 bcc.n 80002e0 <__divsi3+0xa0> + 80002dc: 020b lsls r3, r1, #8 + 80002de: 1ac0 subs r0, r0, r3 + 80002e0: 4152 adcs r2, r2 + 80002e2: d2cd bcs.n 8000280 <__divsi3+0x40> + 80002e4: 09c3 lsrs r3, r0, #7 + 80002e6: 428b cmp r3, r1 + 80002e8: d301 bcc.n 80002ee <__divsi3+0xae> + 80002ea: 01cb lsls r3, r1, #7 + 80002ec: 1ac0 subs r0, r0, r3 + 80002ee: 4152 adcs r2, r2 + 80002f0: 0983 lsrs r3, r0, #6 + 80002f2: 428b cmp r3, r1 + 80002f4: d301 bcc.n 80002fa <__divsi3+0xba> + 80002f6: 018b lsls r3, r1, #6 + 80002f8: 1ac0 subs r0, r0, r3 + 80002fa: 4152 adcs r2, r2 + 80002fc: 0943 lsrs r3, r0, #5 + 80002fe: 428b cmp r3, r1 + 8000300: d301 bcc.n 8000306 <__divsi3+0xc6> + 8000302: 014b lsls r3, r1, #5 + 8000304: 1ac0 subs r0, r0, r3 + 8000306: 4152 adcs r2, r2 + 8000308: 0903 lsrs r3, r0, #4 + 800030a: 428b cmp r3, r1 + 800030c: d301 bcc.n 8000312 <__divsi3+0xd2> + 800030e: 010b lsls r3, r1, #4 + 8000310: 1ac0 subs r0, r0, r3 + 8000312: 4152 adcs r2, r2 + 8000314: 08c3 lsrs r3, r0, #3 + 8000316: 428b cmp r3, r1 + 8000318: d301 bcc.n 800031e <__divsi3+0xde> + 800031a: 00cb lsls r3, r1, #3 + 800031c: 1ac0 subs r0, r0, r3 + 800031e: 4152 adcs r2, r2 + 8000320: 0883 lsrs r3, r0, #2 + 8000322: 428b cmp r3, r1 + 8000324: d301 bcc.n 800032a <__divsi3+0xea> + 8000326: 008b lsls r3, r1, #2 + 8000328: 1ac0 subs r0, r0, r3 + 800032a: 4152 adcs r2, r2 + 800032c: 0843 lsrs r3, r0, #1 + 800032e: 428b cmp r3, r1 + 8000330: d301 bcc.n 8000336 <__divsi3+0xf6> + 8000332: 004b lsls r3, r1, #1 + 8000334: 1ac0 subs r0, r0, r3 + 8000336: 4152 adcs r2, r2 + 8000338: 1a41 subs r1, r0, r1 + 800033a: d200 bcs.n 800033e <__divsi3+0xfe> + 800033c: 4601 mov r1, r0 + 800033e: 4152 adcs r2, r2 + 8000340: 4610 mov r0, r2 + 8000342: 4770 bx lr + 8000344: e05d b.n 8000402 <__divsi3+0x1c2> + 8000346: 0fca lsrs r2, r1, #31 + 8000348: d000 beq.n 800034c <__divsi3+0x10c> + 800034a: 4249 negs r1, r1 + 800034c: 1003 asrs r3, r0, #32 + 800034e: d300 bcc.n 8000352 <__divsi3+0x112> + 8000350: 4240 negs r0, r0 + 8000352: 4053 eors r3, r2 + 8000354: 2200 movs r2, #0 + 8000356: 469c mov ip, r3 + 8000358: 0903 lsrs r3, r0, #4 + 800035a: 428b cmp r3, r1 + 800035c: d32d bcc.n 80003ba <__divsi3+0x17a> + 800035e: 0a03 lsrs r3, r0, #8 + 8000360: 428b cmp r3, r1 + 8000362: d312 bcc.n 800038a <__divsi3+0x14a> + 8000364: 22fc movs r2, #252 ; 0xfc + 8000366: 0189 lsls r1, r1, #6 + 8000368: ba12 rev r2, r2 + 800036a: 0a03 lsrs r3, r0, #8 + 800036c: 428b cmp r3, r1 + 800036e: d30c bcc.n 800038a <__divsi3+0x14a> + 8000370: 0189 lsls r1, r1, #6 + 8000372: 1192 asrs r2, r2, #6 + 8000374: 428b cmp r3, r1 + 8000376: d308 bcc.n 800038a <__divsi3+0x14a> + 8000378: 0189 lsls r1, r1, #6 + 800037a: 1192 asrs r2, r2, #6 + 800037c: 428b cmp r3, r1 + 800037e: d304 bcc.n 800038a <__divsi3+0x14a> + 8000380: 0189 lsls r1, r1, #6 + 8000382: d03a beq.n 80003fa <__divsi3+0x1ba> + 8000384: 1192 asrs r2, r2, #6 + 8000386: e000 b.n 800038a <__divsi3+0x14a> + 8000388: 0989 lsrs r1, r1, #6 + 800038a: 09c3 lsrs r3, r0, #7 + 800038c: 428b cmp r3, r1 + 800038e: d301 bcc.n 8000394 <__divsi3+0x154> + 8000390: 01cb lsls r3, r1, #7 + 8000392: 1ac0 subs r0, r0, r3 + 8000394: 4152 adcs r2, r2 + 8000396: 0983 lsrs r3, r0, #6 + 8000398: 428b cmp r3, r1 + 800039a: d301 bcc.n 80003a0 <__divsi3+0x160> + 800039c: 018b lsls r3, r1, #6 + 800039e: 1ac0 subs r0, r0, r3 + 80003a0: 4152 adcs r2, r2 + 80003a2: 0943 lsrs r3, r0, #5 + 80003a4: 428b cmp r3, r1 + 80003a6: d301 bcc.n 80003ac <__divsi3+0x16c> + 80003a8: 014b lsls r3, r1, #5 + 80003aa: 1ac0 subs r0, r0, r3 + 80003ac: 4152 adcs r2, r2 + 80003ae: 0903 lsrs r3, r0, #4 + 80003b0: 428b cmp r3, r1 + 80003b2: d301 bcc.n 80003b8 <__divsi3+0x178> + 80003b4: 010b lsls r3, r1, #4 + 80003b6: 1ac0 subs r0, r0, r3 + 80003b8: 4152 adcs r2, r2 + 80003ba: 08c3 lsrs r3, r0, #3 + 80003bc: 428b cmp r3, r1 + 80003be: d301 bcc.n 80003c4 <__divsi3+0x184> + 80003c0: 00cb lsls r3, r1, #3 + 80003c2: 1ac0 subs r0, r0, r3 + 80003c4: 4152 adcs r2, r2 + 80003c6: 0883 lsrs r3, r0, #2 + 80003c8: 428b cmp r3, r1 + 80003ca: d301 bcc.n 80003d0 <__divsi3+0x190> + 80003cc: 008b lsls r3, r1, #2 + 80003ce: 1ac0 subs r0, r0, r3 + 80003d0: 4152 adcs r2, r2 + 80003d2: d2d9 bcs.n 8000388 <__divsi3+0x148> + 80003d4: 0843 lsrs r3, r0, #1 + 80003d6: 428b cmp r3, r1 + 80003d8: d301 bcc.n 80003de <__divsi3+0x19e> + 80003da: 004b lsls r3, r1, #1 + 80003dc: 1ac0 subs r0, r0, r3 + 80003de: 4152 adcs r2, r2 + 80003e0: 1a41 subs r1, r0, r1 + 80003e2: d200 bcs.n 80003e6 <__divsi3+0x1a6> + 80003e4: 4601 mov r1, r0 + 80003e6: 4663 mov r3, ip + 80003e8: 4152 adcs r2, r2 + 80003ea: 105b asrs r3, r3, #1 + 80003ec: 4610 mov r0, r2 + 80003ee: d301 bcc.n 80003f4 <__divsi3+0x1b4> + 80003f0: 4240 negs r0, r0 + 80003f2: 2b00 cmp r3, #0 + 80003f4: d500 bpl.n 80003f8 <__divsi3+0x1b8> + 80003f6: 4249 negs r1, r1 + 80003f8: 4770 bx lr + 80003fa: 4663 mov r3, ip + 80003fc: 105b asrs r3, r3, #1 + 80003fe: d300 bcc.n 8000402 <__divsi3+0x1c2> + 8000400: 4240 negs r0, r0 + 8000402: b501 push {r0, lr} + 8000404: 2000 movs r0, #0 + 8000406: f000 f805 bl 8000414 <__aeabi_idiv0> + 800040a: bd02 pop {r1, pc} + +0800040c <__aeabi_idivmod>: + 800040c: 2900 cmp r1, #0 + 800040e: d0f8 beq.n 8000402 <__divsi3+0x1c2> + 8000410: e716 b.n 8000240 <__divsi3> + 8000412: 4770 bx lr + +08000414 <__aeabi_idiv0>: + 8000414: 4770 bx lr + 8000416: 46c0 nop ; (mov r8, r8) + +08000418
: +/** + * @brief The application entry point. + * @retval int + */ +int main(void) +{ + 8000418: b580 push {r7, lr} + 800041a: af00 add r7, sp, #0 + /* USER CODE END 1 */ + + /* MCU Configuration--------------------------------------------------------*/ + + /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ + HAL_Init(); + 800041c: f000 f8f8 bl 8000610 + /* USER CODE BEGIN Init */ + + /* USER CODE END Init */ + + /* Configure the system clock */ + SystemClock_Config(); + 8000420: f000 f809 bl 8000436 + /* USER CODE BEGIN SysInit */ + + /* USER CODE END SysInit */ + + /* Initialize all configured peripherals */ + MX_GPIO_Init(); + 8000424: f000 f85c bl 80004e0 + MX_USB_DEVICE_Init(); + 8000428: f00d ff76 bl 800e318 + /* USER CODE BEGIN 2 */ + ecm_main_init(); + 800042c: f00d fece bl 800e1cc + while (1) + { + /* USER CODE END WHILE */ + + /* USER CODE BEGIN 3 */ + ecm_main_loop(); + 8000430: f00d fef6 bl 800e220 + 8000434: e7fc b.n 8000430 + +08000436 : +/** + * @brief System Clock Configuration + * @retval None + */ +void SystemClock_Config(void) +{ + 8000436: b590 push {r4, r7, lr} + 8000438: b099 sub sp, #100 ; 0x64 + 800043a: af00 add r7, sp, #0 + RCC_OscInitTypeDef RCC_OscInitStruct = {0}; + 800043c: 242c movs r4, #44 ; 0x2c + 800043e: 193b adds r3, r7, r4 + 8000440: 0018 movs r0, r3 + 8000442: 2334 movs r3, #52 ; 0x34 + 8000444: 001a movs r2, r3 + 8000446: 2100 movs r1, #0 + 8000448: f00f fc34 bl 800fcb4 + RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; + 800044c: 231c movs r3, #28 + 800044e: 18fb adds r3, r7, r3 + 8000450: 0018 movs r0, r3 + 8000452: 2310 movs r3, #16 + 8000454: 001a movs r2, r3 + 8000456: 2100 movs r1, #0 + 8000458: f00f fc2c bl 800fcb4 + RCC_PeriphCLKInitTypeDef PeriphClkInit = {0}; + 800045c: 003b movs r3, r7 + 800045e: 0018 movs r0, r3 + 8000460: 231c movs r3, #28 + 8000462: 001a movs r2, r3 + 8000464: 2100 movs r1, #0 + 8000466: f00f fc25 bl 800fcb4 + + /** Initializes the CPU, AHB and APB busses clocks + */ + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI48; + 800046a: 193b adds r3, r7, r4 + 800046c: 2220 movs r2, #32 + 800046e: 601a str r2, [r3, #0] + RCC_OscInitStruct.HSI48State = RCC_HSI48_ON; + 8000470: 193b adds r3, r7, r4 + 8000472: 2201 movs r2, #1 + 8000474: 621a str r2, [r3, #32] + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; + 8000476: 193b adds r3, r7, r4 + 8000478: 2200 movs r2, #0 + 800047a: 625a str r2, [r3, #36] ; 0x24 + if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) + 800047c: 193b adds r3, r7, r4 + 800047e: 0018 movs r0, r3 + 8000480: f001 fba0 bl 8001bc4 + 8000484: 1e03 subs r3, r0, #0 + 8000486: d001 beq.n 800048c + { + Error_Handler(); + 8000488: f000 f842 bl 8000510 + } + /** Initializes the CPU, AHB and APB busses clocks + */ + RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK + 800048c: 211c movs r1, #28 + 800048e: 187b adds r3, r7, r1 + 8000490: 2207 movs r2, #7 + 8000492: 601a str r2, [r3, #0] + |RCC_CLOCKTYPE_PCLK1; + RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI48; + 8000494: 187b adds r3, r7, r1 + 8000496: 2203 movs r2, #3 + 8000498: 605a str r2, [r3, #4] + RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; + 800049a: 187b adds r3, r7, r1 + 800049c: 2200 movs r2, #0 + 800049e: 609a str r2, [r3, #8] + RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; + 80004a0: 187b adds r3, r7, r1 + 80004a2: 2200 movs r2, #0 + 80004a4: 60da str r2, [r3, #12] + + if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK) + 80004a6: 187b adds r3, r7, r1 + 80004a8: 2101 movs r1, #1 + 80004aa: 0018 movs r0, r3 + 80004ac: f001 ff10 bl 80022d0 + 80004b0: 1e03 subs r3, r0, #0 + 80004b2: d001 beq.n 80004b8 + { + Error_Handler(); + 80004b4: f000 f82c bl 8000510 + } + PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USB; + 80004b8: 003b movs r3, r7 + 80004ba: 2280 movs r2, #128 ; 0x80 + 80004bc: 0292 lsls r2, r2, #10 + 80004be: 601a str r2, [r3, #0] + PeriphClkInit.UsbClockSelection = RCC_USBCLKSOURCE_HSI48; + 80004c0: 003b movs r3, r7 + 80004c2: 2200 movs r2, #0 + 80004c4: 619a str r2, [r3, #24] + + if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) + 80004c6: 003b movs r3, r7 + 80004c8: 0018 movs r0, r3 + 80004ca: f002 f859 bl 8002580 + 80004ce: 1e03 subs r3, r0, #0 + 80004d0: d001 beq.n 80004d6 + { + Error_Handler(); + 80004d2: f000 f81d bl 8000510 + } +} + 80004d6: 46c0 nop ; (mov r8, r8) + 80004d8: 46bd mov sp, r7 + 80004da: b019 add sp, #100 ; 0x64 + 80004dc: bd90 pop {r4, r7, pc} + ... + +080004e0 : + * @brief GPIO Initialization Function + * @param None + * @retval None + */ +static void MX_GPIO_Init(void) +{ + 80004e0: b580 push {r7, lr} + 80004e2: b082 sub sp, #8 + 80004e4: af00 add r7, sp, #0 + + /* GPIO Ports Clock Enable */ + __HAL_RCC_GPIOA_CLK_ENABLE(); + 80004e6: 4b09 ldr r3, [pc, #36] ; (800050c ) + 80004e8: 695a ldr r2, [r3, #20] + 80004ea: 4b08 ldr r3, [pc, #32] ; (800050c ) + 80004ec: 2180 movs r1, #128 ; 0x80 + 80004ee: 0289 lsls r1, r1, #10 + 80004f0: 430a orrs r2, r1 + 80004f2: 615a str r2, [r3, #20] + 80004f4: 4b05 ldr r3, [pc, #20] ; (800050c ) + 80004f6: 695a ldr r2, [r3, #20] + 80004f8: 2380 movs r3, #128 ; 0x80 + 80004fa: 029b lsls r3, r3, #10 + 80004fc: 4013 ands r3, r2 + 80004fe: 607b str r3, [r7, #4] + 8000500: 687b ldr r3, [r7, #4] + +} + 8000502: 46c0 nop ; (mov r8, r8) + 8000504: 46bd mov sp, r7 + 8000506: b002 add sp, #8 + 8000508: bd80 pop {r7, pc} + 800050a: 46c0 nop ; (mov r8, r8) + 800050c: 40021000 .word 0x40021000 + +08000510 : +/** + * @brief This function is executed in case of error occurrence. + * @retval None + */ +void Error_Handler(void) +{ + 8000510: b580 push {r7, lr} + 8000512: af00 add r7, sp, #0 + /* USER CODE BEGIN Error_Handler_Debug */ + /* User can add his own implementation to report the HAL error return state */ + + /* USER CODE END Error_Handler_Debug */ +} + 8000514: 46c0 nop ; (mov r8, r8) + 8000516: 46bd mov sp, r7 + 8000518: bd80 pop {r7, pc} + ... + +0800051c : +/* USER CODE END 0 */ +/** + * Initializes the Global MSP. + */ +void HAL_MspInit(void) +{ + 800051c: b580 push {r7, lr} + 800051e: b082 sub sp, #8 + 8000520: af00 add r7, sp, #0 + /* USER CODE BEGIN MspInit 0 */ + + /* USER CODE END MspInit 0 */ + + __HAL_RCC_SYSCFG_CLK_ENABLE(); + 8000522: 4b0f ldr r3, [pc, #60] ; (8000560 ) + 8000524: 699a ldr r2, [r3, #24] + 8000526: 4b0e ldr r3, [pc, #56] ; (8000560 ) + 8000528: 2101 movs r1, #1 + 800052a: 430a orrs r2, r1 + 800052c: 619a str r2, [r3, #24] + 800052e: 4b0c ldr r3, [pc, #48] ; (8000560 ) + 8000530: 699b ldr r3, [r3, #24] + 8000532: 2201 movs r2, #1 + 8000534: 4013 ands r3, r2 + 8000536: 607b str r3, [r7, #4] + 8000538: 687b ldr r3, [r7, #4] + __HAL_RCC_PWR_CLK_ENABLE(); + 800053a: 4b09 ldr r3, [pc, #36] ; (8000560 ) + 800053c: 69da ldr r2, [r3, #28] + 800053e: 4b08 ldr r3, [pc, #32] ; (8000560 ) + 8000540: 2180 movs r1, #128 ; 0x80 + 8000542: 0549 lsls r1, r1, #21 + 8000544: 430a orrs r2, r1 + 8000546: 61da str r2, [r3, #28] + 8000548: 4b05 ldr r3, [pc, #20] ; (8000560 ) + 800054a: 69da ldr r2, [r3, #28] + 800054c: 2380 movs r3, #128 ; 0x80 + 800054e: 055b lsls r3, r3, #21 + 8000550: 4013 ands r3, r2 + 8000552: 603b str r3, [r7, #0] + 8000554: 683b ldr r3, [r7, #0] + /* System interrupt init*/ + + /* USER CODE BEGIN MspInit 1 */ + + /* USER CODE END MspInit 1 */ +} + 8000556: 46c0 nop ; (mov r8, r8) + 8000558: 46bd mov sp, r7 + 800055a: b002 add sp, #8 + 800055c: bd80 pop {r7, pc} + 800055e: 46c0 nop ; (mov r8, r8) + 8000560: 40021000 .word 0x40021000 + +08000564 : +/******************************************************************************/ +/** + * @brief This function handles Non maskable interrupt. + */ +void NMI_Handler(void) +{ + 8000564: b580 push {r7, lr} + 8000566: af00 add r7, sp, #0 + + /* USER CODE END NonMaskableInt_IRQn 0 */ + /* USER CODE BEGIN NonMaskableInt_IRQn 1 */ + + /* USER CODE END NonMaskableInt_IRQn 1 */ +} + 8000568: 46c0 nop ; (mov r8, r8) + 800056a: 46bd mov sp, r7 + 800056c: bd80 pop {r7, pc} + +0800056e : + +/** + * @brief This function handles Hard fault interrupt. + */ +void HardFault_Handler(void) +{ + 800056e: b580 push {r7, lr} + 8000570: af00 add r7, sp, #0 + /* USER CODE BEGIN HardFault_IRQn 0 */ + + /* USER CODE END HardFault_IRQn 0 */ + while (1) + 8000572: e7fe b.n 8000572 + +08000574 : + +/** + * @brief This function handles System service call via SWI instruction. + */ +void SVC_Handler(void) +{ + 8000574: b580 push {r7, lr} + 8000576: af00 add r7, sp, #0 + + /* USER CODE END SVC_IRQn 0 */ + /* USER CODE BEGIN SVC_IRQn 1 */ + + /* USER CODE END SVC_IRQn 1 */ +} + 8000578: 46c0 nop ; (mov r8, r8) + 800057a: 46bd mov sp, r7 + 800057c: bd80 pop {r7, pc} + +0800057e : + +/** + * @brief This function handles Pendable request for system service. + */ +void PendSV_Handler(void) +{ + 800057e: b580 push {r7, lr} + 8000580: af00 add r7, sp, #0 + + /* USER CODE END PendSV_IRQn 0 */ + /* USER CODE BEGIN PendSV_IRQn 1 */ + + /* USER CODE END PendSV_IRQn 1 */ +} + 8000582: 46c0 nop ; (mov r8, r8) + 8000584: 46bd mov sp, r7 + 8000586: bd80 pop {r7, pc} + +08000588 : + +/** + * @brief This function handles System tick timer. + */ +void SysTick_Handler(void) +{ + 8000588: b580 push {r7, lr} + 800058a: af00 add r7, sp, #0 + /* USER CODE BEGIN SysTick_IRQn 0 */ + + /* USER CODE END SysTick_IRQn 0 */ + HAL_IncTick(); + 800058c: f000 f888 bl 80006a0 + /* USER CODE BEGIN SysTick_IRQn 1 */ + + /* USER CODE END SysTick_IRQn 1 */ +} + 8000590: 46c0 nop ; (mov r8, r8) + 8000592: 46bd mov sp, r7 + 8000594: bd80 pop {r7, pc} + ... + +08000598 : + +/** + * @brief This function handles USB global interrupt / USB wake-up interrupt through EXTI line 18. + */ +void USB_IRQHandler(void) +{ + 8000598: b580 push {r7, lr} + 800059a: af00 add r7, sp, #0 + /* USER CODE BEGIN USB_IRQn 0 */ + + /* USER CODE END USB_IRQn 0 */ + HAL_PCD_IRQHandler(&hpcd_USB_FS); + 800059c: 4b03 ldr r3, [pc, #12] ; (80005ac ) + 800059e: 0018 movs r0, r3 + 80005a0: f000 fbfa bl 8000d98 + /* USER CODE BEGIN USB_IRQn 1 */ + + /* USER CODE END USB_IRQn 1 */ +} + 80005a4: 46c0 nop ; (mov r8, r8) + 80005a6: 46bd mov sp, r7 + 80005a8: bd80 pop {r7, pc} + 80005aa: 46c0 nop ; (mov r8, r8) + 80005ac: 200034c4 .word 0x200034c4 + +080005b0 : + * @brief Setup the microcontroller system. + * @param None + * @retval None + */ +void SystemInit(void) +{ + 80005b0: b580 push {r7, lr} + 80005b2: af00 add r7, sp, #0 + before branch to main program. This call is made inside + the "startup_stm32f0xx.s" file. + User can setups the default system clock (System clock source, PLL Multiplier + and Divider factors, AHB/APBx prescalers and Flash settings). + */ +} + 80005b4: 46c0 nop ; (mov r8, r8) + 80005b6: 46bd mov sp, r7 + 80005b8: bd80 pop {r7, pc} + ... + +080005bc : + + .section .text.Reset_Handler + .weak Reset_Handler + .type Reset_Handler, %function +Reset_Handler: + ldr r0, =_estack + 80005bc: 480d ldr r0, [pc, #52] ; (80005f4 ) + mov sp, r0 /* set stack pointer */ + 80005be: 4685 mov sp, r0 + +/* Copy the data segment initializers from flash to SRAM */ + ldr r0, =_sdata + 80005c0: 480d ldr r0, [pc, #52] ; (80005f8 ) + ldr r1, =_edata + 80005c2: 490e ldr r1, [pc, #56] ; (80005fc ) + ldr r2, =_sidata + 80005c4: 4a0e ldr r2, [pc, #56] ; (8000600 ) + movs r3, #0 + 80005c6: 2300 movs r3, #0 + b LoopCopyDataInit + 80005c8: e002 b.n 80005d0 + +080005ca : + +CopyDataInit: + ldr r4, [r2, r3] + 80005ca: 58d4 ldr r4, [r2, r3] + str r4, [r0, r3] + 80005cc: 50c4 str r4, [r0, r3] + adds r3, r3, #4 + 80005ce: 3304 adds r3, #4 + +080005d0 : + +LoopCopyDataInit: + adds r4, r0, r3 + 80005d0: 18c4 adds r4, r0, r3 + cmp r4, r1 + 80005d2: 428c cmp r4, r1 + bcc CopyDataInit + 80005d4: d3f9 bcc.n 80005ca + +/* Zero fill the bss segment. */ + ldr r2, =_sbss + 80005d6: 4a0b ldr r2, [pc, #44] ; (8000604 ) + ldr r4, =_ebss + 80005d8: 4c0b ldr r4, [pc, #44] ; (8000608 ) + movs r3, #0 + 80005da: 2300 movs r3, #0 + b LoopFillZerobss + 80005dc: e001 b.n 80005e2 + +080005de : + +FillZerobss: + str r3, [r2] + 80005de: 6013 str r3, [r2, #0] + adds r2, r2, #4 + 80005e0: 3204 adds r2, #4 + +080005e2 : + +LoopFillZerobss: + cmp r2, r4 + 80005e2: 42a2 cmp r2, r4 + bcc FillZerobss + 80005e4: d3fb bcc.n 80005de + +/* Call the clock system intitialization function.*/ + bl SystemInit + 80005e6: f7ff ffe3 bl 80005b0 +/* Call static constructors */ + bl __libc_init_array + 80005ea: f00f fb27 bl 800fc3c <__libc_init_array> +/* Call the application's entry point.*/ + bl main + 80005ee: f7ff ff13 bl 8000418
+ +080005f2 : + +LoopForever: + b LoopForever + 80005f2: e7fe b.n 80005f2 + ldr r0, =_estack + 80005f4: 20004000 .word 0x20004000 + ldr r0, =_sdata + 80005f8: 20000000 .word 0x20000000 + ldr r1, =_edata + 80005fc: 2000009c .word 0x2000009c + ldr r2, =_sidata + 8000600: 0800feb0 .word 0x0800feb0 + ldr r2, =_sbss + 8000604: 2000009c .word 0x2000009c + ldr r4, =_ebss + 8000608: 20003738 .word 0x20003738 + +0800060c : + * @retval : None +*/ + .section .text.Default_Handler,"ax",%progbits +Default_Handler: +Infinite_Loop: + b Infinite_Loop + 800060c: e7fe b.n 800060c + ... + +08000610 : + * In the default implementation,Systick is used as source of time base. + * The tick variable is incremented each 1ms in its ISR. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_Init(void) +{ + 8000610: b580 push {r7, lr} + 8000612: af00 add r7, sp, #0 + /* Configure Flash prefetch */ +#if (PREFETCH_ENABLE != 0) + __HAL_FLASH_PREFETCH_BUFFER_ENABLE(); + 8000614: 4b07 ldr r3, [pc, #28] ; (8000634 ) + 8000616: 681a ldr r2, [r3, #0] + 8000618: 4b06 ldr r3, [pc, #24] ; (8000634 ) + 800061a: 2110 movs r1, #16 + 800061c: 430a orrs r2, r1 + 800061e: 601a str r2, [r3, #0] +#endif /* PREFETCH_ENABLE */ + + /* Use systick as time base source and configure 1ms tick (default clock after Reset is HSI) */ + + HAL_InitTick(TICK_INT_PRIORITY); + 8000620: 2000 movs r0, #0 + 8000622: f000 f809 bl 8000638 + + /* Init the low level hardware */ + HAL_MspInit(); + 8000626: f7ff ff79 bl 800051c + + /* Return function status */ + return HAL_OK; + 800062a: 2300 movs r3, #0 +} + 800062c: 0018 movs r0, r3 + 800062e: 46bd mov sp, r7 + 8000630: bd80 pop {r7, pc} + 8000632: 46c0 nop ; (mov r8, r8) + 8000634: 40022000 .word 0x40022000 + +08000638 : + * implementation in user file. + * @param TickPriority Tick interrupt priority. + * @retval HAL status + */ +__weak HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority) +{ + 8000638: b590 push {r4, r7, lr} + 800063a: b083 sub sp, #12 + 800063c: af00 add r7, sp, #0 + 800063e: 6078 str r0, [r7, #4] + /*Configure the SysTick to have interrupt in 1ms time basis*/ + if (HAL_SYSTICK_Config(SystemCoreClock / (1000U / uwTickFreq)) > 0U) + 8000640: 4b14 ldr r3, [pc, #80] ; (8000694 ) + 8000642: 681c ldr r4, [r3, #0] + 8000644: 4b14 ldr r3, [pc, #80] ; (8000698 ) + 8000646: 781b ldrb r3, [r3, #0] + 8000648: 0019 movs r1, r3 + 800064a: 23fa movs r3, #250 ; 0xfa + 800064c: 0098 lsls r0, r3, #2 + 800064e: f7ff fd6d bl 800012c <__udivsi3> + 8000652: 0003 movs r3, r0 + 8000654: 0019 movs r1, r3 + 8000656: 0020 movs r0, r4 + 8000658: f7ff fd68 bl 800012c <__udivsi3> + 800065c: 0003 movs r3, r0 + 800065e: 0018 movs r0, r3 + 8000660: f000 f90b bl 800087a + 8000664: 1e03 subs r3, r0, #0 + 8000666: d001 beq.n 800066c + { + return HAL_ERROR; + 8000668: 2301 movs r3, #1 + 800066a: e00f b.n 800068c + } + + /* Configure the SysTick IRQ priority */ + if (TickPriority < (1UL << __NVIC_PRIO_BITS)) + 800066c: 687b ldr r3, [r7, #4] + 800066e: 2b03 cmp r3, #3 + 8000670: d80b bhi.n 800068a + { + HAL_NVIC_SetPriority(SysTick_IRQn, TickPriority, 0U); + 8000672: 6879 ldr r1, [r7, #4] + 8000674: 2301 movs r3, #1 + 8000676: 425b negs r3, r3 + 8000678: 2200 movs r2, #0 + 800067a: 0018 movs r0, r3 + 800067c: f000 f8d8 bl 8000830 + uwTickPrio = TickPriority; + 8000680: 4b06 ldr r3, [pc, #24] ; (800069c ) + 8000682: 687a ldr r2, [r7, #4] + 8000684: 601a str r2, [r3, #0] + { + return HAL_ERROR; + } + + /* Return function status */ + return HAL_OK; + 8000686: 2300 movs r3, #0 + 8000688: e000 b.n 800068c + return HAL_ERROR; + 800068a: 2301 movs r3, #1 +} + 800068c: 0018 movs r0, r3 + 800068e: 46bd mov sp, r7 + 8000690: b003 add sp, #12 + 8000692: bd90 pop {r4, r7, pc} + 8000694: 20000000 .word 0x20000000 + 8000698: 20000008 .word 0x20000008 + 800069c: 20000004 .word 0x20000004 + +080006a0 : + * @note This function is declared as __weak to be overwritten in case of other + * implementations in user file. + * @retval None + */ +__weak void HAL_IncTick(void) +{ + 80006a0: b580 push {r7, lr} + 80006a2: af00 add r7, sp, #0 + uwTick += uwTickFreq; + 80006a4: 4b05 ldr r3, [pc, #20] ; (80006bc ) + 80006a6: 781b ldrb r3, [r3, #0] + 80006a8: 001a movs r2, r3 + 80006aa: 4b05 ldr r3, [pc, #20] ; (80006c0 ) + 80006ac: 681b ldr r3, [r3, #0] + 80006ae: 18d2 adds r2, r2, r3 + 80006b0: 4b03 ldr r3, [pc, #12] ; (80006c0 ) + 80006b2: 601a str r2, [r3, #0] +} + 80006b4: 46c0 nop ; (mov r8, r8) + 80006b6: 46bd mov sp, r7 + 80006b8: bd80 pop {r7, pc} + 80006ba: 46c0 nop ; (mov r8, r8) + 80006bc: 20000008 .word 0x20000008 + 80006c0: 200028f0 .word 0x200028f0 + +080006c4 : + * @note This function is declared as __weak to be overwritten in case of other + * implementations in user file. + * @retval tick value + */ +__weak uint32_t HAL_GetTick(void) +{ + 80006c4: b580 push {r7, lr} + 80006c6: af00 add r7, sp, #0 + return uwTick; + 80006c8: 4b02 ldr r3, [pc, #8] ; (80006d4 ) + 80006ca: 681b ldr r3, [r3, #0] +} + 80006cc: 0018 movs r0, r3 + 80006ce: 46bd mov sp, r7 + 80006d0: bd80 pop {r7, pc} + 80006d2: 46c0 nop ; (mov r8, r8) + 80006d4: 200028f0 .word 0x200028f0 + +080006d8 <__NVIC_EnableIRQ>: + \details Enables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) +{ + 80006d8: b580 push {r7, lr} + 80006da: b082 sub sp, #8 + 80006dc: af00 add r7, sp, #0 + 80006de: 0002 movs r2, r0 + 80006e0: 1dfb adds r3, r7, #7 + 80006e2: 701a strb r2, [r3, #0] + if ((int32_t)(IRQn) >= 0) + 80006e4: 1dfb adds r3, r7, #7 + 80006e6: 781b ldrb r3, [r3, #0] + 80006e8: 2b7f cmp r3, #127 ; 0x7f + 80006ea: d809 bhi.n 8000700 <__NVIC_EnableIRQ+0x28> + { + NVIC->ISER[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + 80006ec: 1dfb adds r3, r7, #7 + 80006ee: 781b ldrb r3, [r3, #0] + 80006f0: 001a movs r2, r3 + 80006f2: 231f movs r3, #31 + 80006f4: 401a ands r2, r3 + 80006f6: 4b04 ldr r3, [pc, #16] ; (8000708 <__NVIC_EnableIRQ+0x30>) + 80006f8: 2101 movs r1, #1 + 80006fa: 4091 lsls r1, r2 + 80006fc: 000a movs r2, r1 + 80006fe: 601a str r2, [r3, #0] + } +} + 8000700: 46c0 nop ; (mov r8, r8) + 8000702: 46bd mov sp, r7 + 8000704: b002 add sp, #8 + 8000706: bd80 pop {r7, pc} + 8000708: e000e100 .word 0xe000e100 + +0800070c <__NVIC_SetPriority>: + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every processor exception. + */ +__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + 800070c: b590 push {r4, r7, lr} + 800070e: b083 sub sp, #12 + 8000710: af00 add r7, sp, #0 + 8000712: 0002 movs r2, r0 + 8000714: 6039 str r1, [r7, #0] + 8000716: 1dfb adds r3, r7, #7 + 8000718: 701a strb r2, [r3, #0] + if ((int32_t)(IRQn) >= 0) + 800071a: 1dfb adds r3, r7, #7 + 800071c: 781b ldrb r3, [r3, #0] + 800071e: 2b7f cmp r3, #127 ; 0x7f + 8000720: d828 bhi.n 8000774 <__NVIC_SetPriority+0x68> + { + NVIC->IP[_IP_IDX(IRQn)] = ((uint32_t)(NVIC->IP[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + 8000722: 4a2f ldr r2, [pc, #188] ; (80007e0 <__NVIC_SetPriority+0xd4>) + 8000724: 1dfb adds r3, r7, #7 + 8000726: 781b ldrb r3, [r3, #0] + 8000728: b25b sxtb r3, r3 + 800072a: 089b lsrs r3, r3, #2 + 800072c: 33c0 adds r3, #192 ; 0xc0 + 800072e: 009b lsls r3, r3, #2 + 8000730: 589b ldr r3, [r3, r2] + 8000732: 1dfa adds r2, r7, #7 + 8000734: 7812 ldrb r2, [r2, #0] + 8000736: 0011 movs r1, r2 + 8000738: 2203 movs r2, #3 + 800073a: 400a ands r2, r1 + 800073c: 00d2 lsls r2, r2, #3 + 800073e: 21ff movs r1, #255 ; 0xff + 8000740: 4091 lsls r1, r2 + 8000742: 000a movs r2, r1 + 8000744: 43d2 mvns r2, r2 + 8000746: 401a ands r2, r3 + 8000748: 0011 movs r1, r2 + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + 800074a: 683b ldr r3, [r7, #0] + 800074c: 019b lsls r3, r3, #6 + 800074e: 22ff movs r2, #255 ; 0xff + 8000750: 401a ands r2, r3 + 8000752: 1dfb adds r3, r7, #7 + 8000754: 781b ldrb r3, [r3, #0] + 8000756: 0018 movs r0, r3 + 8000758: 2303 movs r3, #3 + 800075a: 4003 ands r3, r0 + 800075c: 00db lsls r3, r3, #3 + 800075e: 409a lsls r2, r3 + NVIC->IP[_IP_IDX(IRQn)] = ((uint32_t)(NVIC->IP[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + 8000760: 481f ldr r0, [pc, #124] ; (80007e0 <__NVIC_SetPriority+0xd4>) + 8000762: 1dfb adds r3, r7, #7 + 8000764: 781b ldrb r3, [r3, #0] + 8000766: b25b sxtb r3, r3 + 8000768: 089b lsrs r3, r3, #2 + 800076a: 430a orrs r2, r1 + 800076c: 33c0 adds r3, #192 ; 0xc0 + 800076e: 009b lsls r3, r3, #2 + 8000770: 501a str r2, [r3, r0] + else + { + SCB->SHP[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } +} + 8000772: e031 b.n 80007d8 <__NVIC_SetPriority+0xcc> + SCB->SHP[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + 8000774: 4a1b ldr r2, [pc, #108] ; (80007e4 <__NVIC_SetPriority+0xd8>) + 8000776: 1dfb adds r3, r7, #7 + 8000778: 781b ldrb r3, [r3, #0] + 800077a: 0019 movs r1, r3 + 800077c: 230f movs r3, #15 + 800077e: 400b ands r3, r1 + 8000780: 3b08 subs r3, #8 + 8000782: 089b lsrs r3, r3, #2 + 8000784: 3306 adds r3, #6 + 8000786: 009b lsls r3, r3, #2 + 8000788: 18d3 adds r3, r2, r3 + 800078a: 3304 adds r3, #4 + 800078c: 681b ldr r3, [r3, #0] + 800078e: 1dfa adds r2, r7, #7 + 8000790: 7812 ldrb r2, [r2, #0] + 8000792: 0011 movs r1, r2 + 8000794: 2203 movs r2, #3 + 8000796: 400a ands r2, r1 + 8000798: 00d2 lsls r2, r2, #3 + 800079a: 21ff movs r1, #255 ; 0xff + 800079c: 4091 lsls r1, r2 + 800079e: 000a movs r2, r1 + 80007a0: 43d2 mvns r2, r2 + 80007a2: 401a ands r2, r3 + 80007a4: 0011 movs r1, r2 + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + 80007a6: 683b ldr r3, [r7, #0] + 80007a8: 019b lsls r3, r3, #6 + 80007aa: 22ff movs r2, #255 ; 0xff + 80007ac: 401a ands r2, r3 + 80007ae: 1dfb adds r3, r7, #7 + 80007b0: 781b ldrb r3, [r3, #0] + 80007b2: 0018 movs r0, r3 + 80007b4: 2303 movs r3, #3 + 80007b6: 4003 ands r3, r0 + 80007b8: 00db lsls r3, r3, #3 + 80007ba: 409a lsls r2, r3 + SCB->SHP[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + 80007bc: 4809 ldr r0, [pc, #36] ; (80007e4 <__NVIC_SetPriority+0xd8>) + 80007be: 1dfb adds r3, r7, #7 + 80007c0: 781b ldrb r3, [r3, #0] + 80007c2: 001c movs r4, r3 + 80007c4: 230f movs r3, #15 + 80007c6: 4023 ands r3, r4 + 80007c8: 3b08 subs r3, #8 + 80007ca: 089b lsrs r3, r3, #2 + 80007cc: 430a orrs r2, r1 + 80007ce: 3306 adds r3, #6 + 80007d0: 009b lsls r3, r3, #2 + 80007d2: 18c3 adds r3, r0, r3 + 80007d4: 3304 adds r3, #4 + 80007d6: 601a str r2, [r3, #0] +} + 80007d8: 46c0 nop ; (mov r8, r8) + 80007da: 46bd mov sp, r7 + 80007dc: b003 add sp, #12 + 80007de: bd90 pop {r4, r7, pc} + 80007e0: e000e100 .word 0xe000e100 + 80007e4: e000ed00 .word 0xe000ed00 + +080007e8 : + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + 80007e8: b580 push {r7, lr} + 80007ea: b082 sub sp, #8 + 80007ec: af00 add r7, sp, #0 + 80007ee: 6078 str r0, [r7, #4] + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + 80007f0: 687b ldr r3, [r7, #4] + 80007f2: 3b01 subs r3, #1 + 80007f4: 4a0c ldr r2, [pc, #48] ; (8000828 ) + 80007f6: 4293 cmp r3, r2 + 80007f8: d901 bls.n 80007fe + { + return (1UL); /* Reload value impossible */ + 80007fa: 2301 movs r3, #1 + 80007fc: e010 b.n 8000820 + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + 80007fe: 4b0b ldr r3, [pc, #44] ; (800082c ) + 8000800: 687a ldr r2, [r7, #4] + 8000802: 3a01 subs r2, #1 + 8000804: 605a str r2, [r3, #4] + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + 8000806: 2301 movs r3, #1 + 8000808: 425b negs r3, r3 + 800080a: 2103 movs r1, #3 + 800080c: 0018 movs r0, r3 + 800080e: f7ff ff7d bl 800070c <__NVIC_SetPriority> + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + 8000812: 4b06 ldr r3, [pc, #24] ; (800082c ) + 8000814: 2200 movs r2, #0 + 8000816: 609a str r2, [r3, #8] + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + 8000818: 4b04 ldr r3, [pc, #16] ; (800082c ) + 800081a: 2207 movs r2, #7 + 800081c: 601a str r2, [r3, #0] + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ + 800081e: 2300 movs r3, #0 +} + 8000820: 0018 movs r0, r3 + 8000822: 46bd mov sp, r7 + 8000824: b002 add sp, #8 + 8000826: bd80 pop {r7, pc} + 8000828: 00ffffff .word 0x00ffffff + 800082c: e000e010 .word 0xe000e010 + +08000830 : + * with stm32f0xx devices, this parameter is a dummy value and it is ignored, because + * no subpriority supported in Cortex M0 based products. + * @retval None + */ +void HAL_NVIC_SetPriority(IRQn_Type IRQn, uint32_t PreemptPriority, uint32_t SubPriority) +{ + 8000830: b580 push {r7, lr} + 8000832: b084 sub sp, #16 + 8000834: af00 add r7, sp, #0 + 8000836: 60b9 str r1, [r7, #8] + 8000838: 607a str r2, [r7, #4] + 800083a: 210f movs r1, #15 + 800083c: 187b adds r3, r7, r1 + 800083e: 1c02 adds r2, r0, #0 + 8000840: 701a strb r2, [r3, #0] + /* Check the parameters */ + assert_param(IS_NVIC_PREEMPTION_PRIORITY(PreemptPriority)); + NVIC_SetPriority(IRQn,PreemptPriority); + 8000842: 68ba ldr r2, [r7, #8] + 8000844: 187b adds r3, r7, r1 + 8000846: 781b ldrb r3, [r3, #0] + 8000848: b25b sxtb r3, r3 + 800084a: 0011 movs r1, r2 + 800084c: 0018 movs r0, r3 + 800084e: f7ff ff5d bl 800070c <__NVIC_SetPriority> +} + 8000852: 46c0 nop ; (mov r8, r8) + 8000854: 46bd mov sp, r7 + 8000856: b004 add sp, #16 + 8000858: bd80 pop {r7, pc} + +0800085a : + * This parameter can be an enumerator of IRQn_Type enumeration + * (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32f0xxxx.h)) + * @retval None + */ +void HAL_NVIC_EnableIRQ(IRQn_Type IRQn) +{ + 800085a: b580 push {r7, lr} + 800085c: b082 sub sp, #8 + 800085e: af00 add r7, sp, #0 + 8000860: 0002 movs r2, r0 + 8000862: 1dfb adds r3, r7, #7 + 8000864: 701a strb r2, [r3, #0] + /* Check the parameters */ + assert_param(IS_NVIC_DEVICE_IRQ(IRQn)); + + /* Enable interrupt */ + NVIC_EnableIRQ(IRQn); + 8000866: 1dfb adds r3, r7, #7 + 8000868: 781b ldrb r3, [r3, #0] + 800086a: b25b sxtb r3, r3 + 800086c: 0018 movs r0, r3 + 800086e: f7ff ff33 bl 80006d8 <__NVIC_EnableIRQ> +} + 8000872: 46c0 nop ; (mov r8, r8) + 8000874: 46bd mov sp, r7 + 8000876: b002 add sp, #8 + 8000878: bd80 pop {r7, pc} + +0800087a : + * @param TicksNumb Specifies the ticks Number of ticks between two interrupts. + * @retval status: - 0 Function succeeded. + * - 1 Function failed. + */ +uint32_t HAL_SYSTICK_Config(uint32_t TicksNumb) +{ + 800087a: b580 push {r7, lr} + 800087c: b082 sub sp, #8 + 800087e: af00 add r7, sp, #0 + 8000880: 6078 str r0, [r7, #4] + return SysTick_Config(TicksNumb); + 8000882: 687b ldr r3, [r7, #4] + 8000884: 0018 movs r0, r3 + 8000886: f7ff ffaf bl 80007e8 + 800088a: 0003 movs r3, r0 +} + 800088c: 0018 movs r0, r3 + 800088e: 46bd mov sp, r7 + 8000890: b002 add sp, #8 + 8000892: bd80 pop {r7, pc} + +08000894 : + * @param GPIO_Init pointer to a GPIO_InitTypeDef structure that contains + * the configuration information for the specified GPIO peripheral. + * @retval None + */ +void HAL_GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *GPIO_Init) +{ + 8000894: b580 push {r7, lr} + 8000896: b086 sub sp, #24 + 8000898: af00 add r7, sp, #0 + 800089a: 6078 str r0, [r7, #4] + 800089c: 6039 str r1, [r7, #0] + uint32_t position = 0x00u; + 800089e: 2300 movs r3, #0 + 80008a0: 617b str r3, [r7, #20] + assert_param(IS_GPIO_PIN(GPIO_Init->Pin)); + assert_param(IS_GPIO_MODE(GPIO_Init->Mode)); + assert_param(IS_GPIO_PULL(GPIO_Init->Pull)); + + /* Configure the port pins */ + while (((GPIO_Init->Pin) >> position) != 0x00u) + 80008a2: e155 b.n 8000b50 + { + /* Get current io position */ + iocurrent = (GPIO_Init->Pin) & (1uL << position); + 80008a4: 683b ldr r3, [r7, #0] + 80008a6: 681b ldr r3, [r3, #0] + 80008a8: 2101 movs r1, #1 + 80008aa: 697a ldr r2, [r7, #20] + 80008ac: 4091 lsls r1, r2 + 80008ae: 000a movs r2, r1 + 80008b0: 4013 ands r3, r2 + 80008b2: 60fb str r3, [r7, #12] + + if (iocurrent != 0x00u) + 80008b4: 68fb ldr r3, [r7, #12] + 80008b6: 2b00 cmp r3, #0 + 80008b8: d100 bne.n 80008bc + 80008ba: e146 b.n 8000b4a + { + /*--------------------- GPIO Mode Configuration ------------------------*/ + /* In case of Alternate function mode selection */ + if((GPIO_Init->Mode == GPIO_MODE_AF_PP) || (GPIO_Init->Mode == GPIO_MODE_AF_OD)) + 80008bc: 683b ldr r3, [r7, #0] + 80008be: 685b ldr r3, [r3, #4] + 80008c0: 2b02 cmp r3, #2 + 80008c2: d003 beq.n 80008cc + 80008c4: 683b ldr r3, [r7, #0] + 80008c6: 685b ldr r3, [r3, #4] + 80008c8: 2b12 cmp r3, #18 + 80008ca: d123 bne.n 8000914 + /* Check the Alternate function parameters */ + assert_param(IS_GPIO_AF_INSTANCE(GPIOx)); + assert_param(IS_GPIO_AF(GPIO_Init->Alternate)); + + /* Configure Alternate function mapped with the current IO */ + temp = GPIOx->AFR[position >> 3u]; + 80008cc: 697b ldr r3, [r7, #20] + 80008ce: 08da lsrs r2, r3, #3 + 80008d0: 687b ldr r3, [r7, #4] + 80008d2: 3208 adds r2, #8 + 80008d4: 0092 lsls r2, r2, #2 + 80008d6: 58d3 ldr r3, [r2, r3] + 80008d8: 613b str r3, [r7, #16] + temp &= ~(0xFu << ((position & 0x07u) * 4u)); + 80008da: 697b ldr r3, [r7, #20] + 80008dc: 2207 movs r2, #7 + 80008de: 4013 ands r3, r2 + 80008e0: 009b lsls r3, r3, #2 + 80008e2: 220f movs r2, #15 + 80008e4: 409a lsls r2, r3 + 80008e6: 0013 movs r3, r2 + 80008e8: 43da mvns r2, r3 + 80008ea: 693b ldr r3, [r7, #16] + 80008ec: 4013 ands r3, r2 + 80008ee: 613b str r3, [r7, #16] + temp |= ((GPIO_Init->Alternate) << ((position & 0x07u) * 4u)); + 80008f0: 683b ldr r3, [r7, #0] + 80008f2: 691a ldr r2, [r3, #16] + 80008f4: 697b ldr r3, [r7, #20] + 80008f6: 2107 movs r1, #7 + 80008f8: 400b ands r3, r1 + 80008fa: 009b lsls r3, r3, #2 + 80008fc: 409a lsls r2, r3 + 80008fe: 0013 movs r3, r2 + 8000900: 693a ldr r2, [r7, #16] + 8000902: 4313 orrs r3, r2 + 8000904: 613b str r3, [r7, #16] + GPIOx->AFR[position >> 3u] = temp; + 8000906: 697b ldr r3, [r7, #20] + 8000908: 08da lsrs r2, r3, #3 + 800090a: 687b ldr r3, [r7, #4] + 800090c: 3208 adds r2, #8 + 800090e: 0092 lsls r2, r2, #2 + 8000910: 6939 ldr r1, [r7, #16] + 8000912: 50d1 str r1, [r2, r3] + } + + /* Configure IO Direction mode (Input, Output, Alternate or Analog) */ + temp = GPIOx->MODER; + 8000914: 687b ldr r3, [r7, #4] + 8000916: 681b ldr r3, [r3, #0] + 8000918: 613b str r3, [r7, #16] + temp &= ~(GPIO_MODER_MODER0 << (position * 2u)); + 800091a: 697b ldr r3, [r7, #20] + 800091c: 005b lsls r3, r3, #1 + 800091e: 2203 movs r2, #3 + 8000920: 409a lsls r2, r3 + 8000922: 0013 movs r3, r2 + 8000924: 43da mvns r2, r3 + 8000926: 693b ldr r3, [r7, #16] + 8000928: 4013 ands r3, r2 + 800092a: 613b str r3, [r7, #16] + temp |= ((GPIO_Init->Mode & GPIO_MODE) << (position * 2u)); + 800092c: 683b ldr r3, [r7, #0] + 800092e: 685b ldr r3, [r3, #4] + 8000930: 2203 movs r2, #3 + 8000932: 401a ands r2, r3 + 8000934: 697b ldr r3, [r7, #20] + 8000936: 005b lsls r3, r3, #1 + 8000938: 409a lsls r2, r3 + 800093a: 0013 movs r3, r2 + 800093c: 693a ldr r2, [r7, #16] + 800093e: 4313 orrs r3, r2 + 8000940: 613b str r3, [r7, #16] + GPIOx->MODER = temp; + 8000942: 687b ldr r3, [r7, #4] + 8000944: 693a ldr r2, [r7, #16] + 8000946: 601a str r2, [r3, #0] + + /* In case of Output or Alternate function mode selection */ + if((GPIO_Init->Mode == GPIO_MODE_OUTPUT_PP) || (GPIO_Init->Mode == GPIO_MODE_AF_PP) || + 8000948: 683b ldr r3, [r7, #0] + 800094a: 685b ldr r3, [r3, #4] + 800094c: 2b01 cmp r3, #1 + 800094e: d00b beq.n 8000968 + 8000950: 683b ldr r3, [r7, #0] + 8000952: 685b ldr r3, [r3, #4] + 8000954: 2b02 cmp r3, #2 + 8000956: d007 beq.n 8000968 + (GPIO_Init->Mode == GPIO_MODE_OUTPUT_OD) || (GPIO_Init->Mode == GPIO_MODE_AF_OD)) + 8000958: 683b ldr r3, [r7, #0] + 800095a: 685b ldr r3, [r3, #4] + if((GPIO_Init->Mode == GPIO_MODE_OUTPUT_PP) || (GPIO_Init->Mode == GPIO_MODE_AF_PP) || + 800095c: 2b11 cmp r3, #17 + 800095e: d003 beq.n 8000968 + (GPIO_Init->Mode == GPIO_MODE_OUTPUT_OD) || (GPIO_Init->Mode == GPIO_MODE_AF_OD)) + 8000960: 683b ldr r3, [r7, #0] + 8000962: 685b ldr r3, [r3, #4] + 8000964: 2b12 cmp r3, #18 + 8000966: d130 bne.n 80009ca + { + /* Check the Speed parameter */ + assert_param(IS_GPIO_SPEED(GPIO_Init->Speed)); + /* Configure the IO Speed */ + temp = GPIOx->OSPEEDR; + 8000968: 687b ldr r3, [r7, #4] + 800096a: 689b ldr r3, [r3, #8] + 800096c: 613b str r3, [r7, #16] + temp &= ~(GPIO_OSPEEDER_OSPEEDR0 << (position * 2u)); + 800096e: 697b ldr r3, [r7, #20] + 8000970: 005b lsls r3, r3, #1 + 8000972: 2203 movs r2, #3 + 8000974: 409a lsls r2, r3 + 8000976: 0013 movs r3, r2 + 8000978: 43da mvns r2, r3 + 800097a: 693b ldr r3, [r7, #16] + 800097c: 4013 ands r3, r2 + 800097e: 613b str r3, [r7, #16] + temp |= (GPIO_Init->Speed << (position * 2u)); + 8000980: 683b ldr r3, [r7, #0] + 8000982: 68da ldr r2, [r3, #12] + 8000984: 697b ldr r3, [r7, #20] + 8000986: 005b lsls r3, r3, #1 + 8000988: 409a lsls r2, r3 + 800098a: 0013 movs r3, r2 + 800098c: 693a ldr r2, [r7, #16] + 800098e: 4313 orrs r3, r2 + 8000990: 613b str r3, [r7, #16] + GPIOx->OSPEEDR = temp; + 8000992: 687b ldr r3, [r7, #4] + 8000994: 693a ldr r2, [r7, #16] + 8000996: 609a str r2, [r3, #8] + + /* Configure the IO Output Type */ + temp = GPIOx->OTYPER; + 8000998: 687b ldr r3, [r7, #4] + 800099a: 685b ldr r3, [r3, #4] + 800099c: 613b str r3, [r7, #16] + temp &= ~(GPIO_OTYPER_OT_0 << position) ; + 800099e: 2201 movs r2, #1 + 80009a0: 697b ldr r3, [r7, #20] + 80009a2: 409a lsls r2, r3 + 80009a4: 0013 movs r3, r2 + 80009a6: 43da mvns r2, r3 + 80009a8: 693b ldr r3, [r7, #16] + 80009aa: 4013 ands r3, r2 + 80009ac: 613b str r3, [r7, #16] + temp |= (((GPIO_Init->Mode & GPIO_OUTPUT_TYPE) >> 4u) << position); + 80009ae: 683b ldr r3, [r7, #0] + 80009b0: 685b ldr r3, [r3, #4] + 80009b2: 091b lsrs r3, r3, #4 + 80009b4: 2201 movs r2, #1 + 80009b6: 401a ands r2, r3 + 80009b8: 697b ldr r3, [r7, #20] + 80009ba: 409a lsls r2, r3 + 80009bc: 0013 movs r3, r2 + 80009be: 693a ldr r2, [r7, #16] + 80009c0: 4313 orrs r3, r2 + 80009c2: 613b str r3, [r7, #16] + GPIOx->OTYPER = temp; + 80009c4: 687b ldr r3, [r7, #4] + 80009c6: 693a ldr r2, [r7, #16] + 80009c8: 605a str r2, [r3, #4] + } + + /* Activate the Pull-up or Pull down resistor for the current IO */ + temp = GPIOx->PUPDR; + 80009ca: 687b ldr r3, [r7, #4] + 80009cc: 68db ldr r3, [r3, #12] + 80009ce: 613b str r3, [r7, #16] + temp &= ~(GPIO_PUPDR_PUPDR0 << (position * 2u)); + 80009d0: 697b ldr r3, [r7, #20] + 80009d2: 005b lsls r3, r3, #1 + 80009d4: 2203 movs r2, #3 + 80009d6: 409a lsls r2, r3 + 80009d8: 0013 movs r3, r2 + 80009da: 43da mvns r2, r3 + 80009dc: 693b ldr r3, [r7, #16] + 80009de: 4013 ands r3, r2 + 80009e0: 613b str r3, [r7, #16] + temp |= ((GPIO_Init->Pull) << (position * 2u)); + 80009e2: 683b ldr r3, [r7, #0] + 80009e4: 689a ldr r2, [r3, #8] + 80009e6: 697b ldr r3, [r7, #20] + 80009e8: 005b lsls r3, r3, #1 + 80009ea: 409a lsls r2, r3 + 80009ec: 0013 movs r3, r2 + 80009ee: 693a ldr r2, [r7, #16] + 80009f0: 4313 orrs r3, r2 + 80009f2: 613b str r3, [r7, #16] + GPIOx->PUPDR = temp; + 80009f4: 687b ldr r3, [r7, #4] + 80009f6: 693a ldr r2, [r7, #16] + 80009f8: 60da str r2, [r3, #12] + + /*--------------------- EXTI Mode Configuration ------------------------*/ + /* Configure the External Interrupt or event for the current IO */ + if((GPIO_Init->Mode & EXTI_MODE) == EXTI_MODE) + 80009fa: 683b ldr r3, [r7, #0] + 80009fc: 685a ldr r2, [r3, #4] + 80009fe: 2380 movs r3, #128 ; 0x80 + 8000a00: 055b lsls r3, r3, #21 + 8000a02: 4013 ands r3, r2 + 8000a04: d100 bne.n 8000a08 + 8000a06: e0a0 b.n 8000b4a + { + /* Enable SYSCFG Clock */ + __HAL_RCC_SYSCFG_CLK_ENABLE(); + 8000a08: 4b57 ldr r3, [pc, #348] ; (8000b68 ) + 8000a0a: 699a ldr r2, [r3, #24] + 8000a0c: 4b56 ldr r3, [pc, #344] ; (8000b68 ) + 8000a0e: 2101 movs r1, #1 + 8000a10: 430a orrs r2, r1 + 8000a12: 619a str r2, [r3, #24] + 8000a14: 4b54 ldr r3, [pc, #336] ; (8000b68 ) + 8000a16: 699b ldr r3, [r3, #24] + 8000a18: 2201 movs r2, #1 + 8000a1a: 4013 ands r3, r2 + 8000a1c: 60bb str r3, [r7, #8] + 8000a1e: 68bb ldr r3, [r7, #8] + + temp = SYSCFG->EXTICR[position >> 2u]; + 8000a20: 4a52 ldr r2, [pc, #328] ; (8000b6c ) + 8000a22: 697b ldr r3, [r7, #20] + 8000a24: 089b lsrs r3, r3, #2 + 8000a26: 3302 adds r3, #2 + 8000a28: 009b lsls r3, r3, #2 + 8000a2a: 589b ldr r3, [r3, r2] + 8000a2c: 613b str r3, [r7, #16] + temp &= ~(0x0FuL << (4u * (position & 0x03u))); + 8000a2e: 697b ldr r3, [r7, #20] + 8000a30: 2203 movs r2, #3 + 8000a32: 4013 ands r3, r2 + 8000a34: 009b lsls r3, r3, #2 + 8000a36: 220f movs r2, #15 + 8000a38: 409a lsls r2, r3 + 8000a3a: 0013 movs r3, r2 + 8000a3c: 43da mvns r2, r3 + 8000a3e: 693b ldr r3, [r7, #16] + 8000a40: 4013 ands r3, r2 + 8000a42: 613b str r3, [r7, #16] + temp |= (GPIO_GET_INDEX(GPIOx) << (4u * (position & 0x03u))); + 8000a44: 687a ldr r2, [r7, #4] + 8000a46: 2390 movs r3, #144 ; 0x90 + 8000a48: 05db lsls r3, r3, #23 + 8000a4a: 429a cmp r2, r3 + 8000a4c: d019 beq.n 8000a82 + 8000a4e: 687b ldr r3, [r7, #4] + 8000a50: 4a47 ldr r2, [pc, #284] ; (8000b70 ) + 8000a52: 4293 cmp r3, r2 + 8000a54: d013 beq.n 8000a7e + 8000a56: 687b ldr r3, [r7, #4] + 8000a58: 4a46 ldr r2, [pc, #280] ; (8000b74 ) + 8000a5a: 4293 cmp r3, r2 + 8000a5c: d00d beq.n 8000a7a + 8000a5e: 687b ldr r3, [r7, #4] + 8000a60: 4a45 ldr r2, [pc, #276] ; (8000b78 ) + 8000a62: 4293 cmp r3, r2 + 8000a64: d007 beq.n 8000a76 + 8000a66: 687b ldr r3, [r7, #4] + 8000a68: 4a44 ldr r2, [pc, #272] ; (8000b7c ) + 8000a6a: 4293 cmp r3, r2 + 8000a6c: d101 bne.n 8000a72 + 8000a6e: 2304 movs r3, #4 + 8000a70: e008 b.n 8000a84 + 8000a72: 2305 movs r3, #5 + 8000a74: e006 b.n 8000a84 + 8000a76: 2303 movs r3, #3 + 8000a78: e004 b.n 8000a84 + 8000a7a: 2302 movs r3, #2 + 8000a7c: e002 b.n 8000a84 + 8000a7e: 2301 movs r3, #1 + 8000a80: e000 b.n 8000a84 + 8000a82: 2300 movs r3, #0 + 8000a84: 697a ldr r2, [r7, #20] + 8000a86: 2103 movs r1, #3 + 8000a88: 400a ands r2, r1 + 8000a8a: 0092 lsls r2, r2, #2 + 8000a8c: 4093 lsls r3, r2 + 8000a8e: 693a ldr r2, [r7, #16] + 8000a90: 4313 orrs r3, r2 + 8000a92: 613b str r3, [r7, #16] + SYSCFG->EXTICR[position >> 2u] = temp; + 8000a94: 4935 ldr r1, [pc, #212] ; (8000b6c ) + 8000a96: 697b ldr r3, [r7, #20] + 8000a98: 089b lsrs r3, r3, #2 + 8000a9a: 3302 adds r3, #2 + 8000a9c: 009b lsls r3, r3, #2 + 8000a9e: 693a ldr r2, [r7, #16] + 8000aa0: 505a str r2, [r3, r1] + + /* Clear EXTI line configuration */ + temp = EXTI->IMR; + 8000aa2: 4b37 ldr r3, [pc, #220] ; (8000b80 ) + 8000aa4: 681b ldr r3, [r3, #0] + 8000aa6: 613b str r3, [r7, #16] + temp &= ~(iocurrent); + 8000aa8: 68fb ldr r3, [r7, #12] + 8000aaa: 43da mvns r2, r3 + 8000aac: 693b ldr r3, [r7, #16] + 8000aae: 4013 ands r3, r2 + 8000ab0: 613b str r3, [r7, #16] + if((GPIO_Init->Mode & GPIO_MODE_IT) == GPIO_MODE_IT) + 8000ab2: 683b ldr r3, [r7, #0] + 8000ab4: 685a ldr r2, [r3, #4] + 8000ab6: 2380 movs r3, #128 ; 0x80 + 8000ab8: 025b lsls r3, r3, #9 + 8000aba: 4013 ands r3, r2 + 8000abc: d003 beq.n 8000ac6 + { + temp |= iocurrent; + 8000abe: 693a ldr r2, [r7, #16] + 8000ac0: 68fb ldr r3, [r7, #12] + 8000ac2: 4313 orrs r3, r2 + 8000ac4: 613b str r3, [r7, #16] + } + EXTI->IMR = temp; + 8000ac6: 4b2e ldr r3, [pc, #184] ; (8000b80 ) + 8000ac8: 693a ldr r2, [r7, #16] + 8000aca: 601a str r2, [r3, #0] + + temp = EXTI->EMR; + 8000acc: 4b2c ldr r3, [pc, #176] ; (8000b80 ) + 8000ace: 685b ldr r3, [r3, #4] + 8000ad0: 613b str r3, [r7, #16] + temp &= ~(iocurrent); + 8000ad2: 68fb ldr r3, [r7, #12] + 8000ad4: 43da mvns r2, r3 + 8000ad6: 693b ldr r3, [r7, #16] + 8000ad8: 4013 ands r3, r2 + 8000ada: 613b str r3, [r7, #16] + if((GPIO_Init->Mode & GPIO_MODE_EVT) == GPIO_MODE_EVT) + 8000adc: 683b ldr r3, [r7, #0] + 8000ade: 685a ldr r2, [r3, #4] + 8000ae0: 2380 movs r3, #128 ; 0x80 + 8000ae2: 029b lsls r3, r3, #10 + 8000ae4: 4013 ands r3, r2 + 8000ae6: d003 beq.n 8000af0 + { + temp |= iocurrent; + 8000ae8: 693a ldr r2, [r7, #16] + 8000aea: 68fb ldr r3, [r7, #12] + 8000aec: 4313 orrs r3, r2 + 8000aee: 613b str r3, [r7, #16] + } + EXTI->EMR = temp; + 8000af0: 4b23 ldr r3, [pc, #140] ; (8000b80 ) + 8000af2: 693a ldr r2, [r7, #16] + 8000af4: 605a str r2, [r3, #4] + + /* Clear Rising Falling edge configuration */ + temp = EXTI->RTSR; + 8000af6: 4b22 ldr r3, [pc, #136] ; (8000b80 ) + 8000af8: 689b ldr r3, [r3, #8] + 8000afa: 613b str r3, [r7, #16] + temp &= ~(iocurrent); + 8000afc: 68fb ldr r3, [r7, #12] + 8000afe: 43da mvns r2, r3 + 8000b00: 693b ldr r3, [r7, #16] + 8000b02: 4013 ands r3, r2 + 8000b04: 613b str r3, [r7, #16] + if((GPIO_Init->Mode & RISING_EDGE) == RISING_EDGE) + 8000b06: 683b ldr r3, [r7, #0] + 8000b08: 685a ldr r2, [r3, #4] + 8000b0a: 2380 movs r3, #128 ; 0x80 + 8000b0c: 035b lsls r3, r3, #13 + 8000b0e: 4013 ands r3, r2 + 8000b10: d003 beq.n 8000b1a + { + temp |= iocurrent; + 8000b12: 693a ldr r2, [r7, #16] + 8000b14: 68fb ldr r3, [r7, #12] + 8000b16: 4313 orrs r3, r2 + 8000b18: 613b str r3, [r7, #16] + } + EXTI->RTSR = temp; + 8000b1a: 4b19 ldr r3, [pc, #100] ; (8000b80 ) + 8000b1c: 693a ldr r2, [r7, #16] + 8000b1e: 609a str r2, [r3, #8] + + temp = EXTI->FTSR; + 8000b20: 4b17 ldr r3, [pc, #92] ; (8000b80 ) + 8000b22: 68db ldr r3, [r3, #12] + 8000b24: 613b str r3, [r7, #16] + temp &= ~(iocurrent); + 8000b26: 68fb ldr r3, [r7, #12] + 8000b28: 43da mvns r2, r3 + 8000b2a: 693b ldr r3, [r7, #16] + 8000b2c: 4013 ands r3, r2 + 8000b2e: 613b str r3, [r7, #16] + if((GPIO_Init->Mode & FALLING_EDGE) == FALLING_EDGE) + 8000b30: 683b ldr r3, [r7, #0] + 8000b32: 685a ldr r2, [r3, #4] + 8000b34: 2380 movs r3, #128 ; 0x80 + 8000b36: 039b lsls r3, r3, #14 + 8000b38: 4013 ands r3, r2 + 8000b3a: d003 beq.n 8000b44 + { + temp |= iocurrent; + 8000b3c: 693a ldr r2, [r7, #16] + 8000b3e: 68fb ldr r3, [r7, #12] + 8000b40: 4313 orrs r3, r2 + 8000b42: 613b str r3, [r7, #16] + } + EXTI->FTSR = temp; + 8000b44: 4b0e ldr r3, [pc, #56] ; (8000b80 ) + 8000b46: 693a ldr r2, [r7, #16] + 8000b48: 60da str r2, [r3, #12] + } + } + + position++; + 8000b4a: 697b ldr r3, [r7, #20] + 8000b4c: 3301 adds r3, #1 + 8000b4e: 617b str r3, [r7, #20] + while (((GPIO_Init->Pin) >> position) != 0x00u) + 8000b50: 683b ldr r3, [r7, #0] + 8000b52: 681a ldr r2, [r3, #0] + 8000b54: 697b ldr r3, [r7, #20] + 8000b56: 40da lsrs r2, r3 + 8000b58: 1e13 subs r3, r2, #0 + 8000b5a: d000 beq.n 8000b5e + 8000b5c: e6a2 b.n 80008a4 + } +} + 8000b5e: 46c0 nop ; (mov r8, r8) + 8000b60: 46bd mov sp, r7 + 8000b62: b006 add sp, #24 + 8000b64: bd80 pop {r7, pc} + 8000b66: 46c0 nop ; (mov r8, r8) + 8000b68: 40021000 .word 0x40021000 + 8000b6c: 40010000 .word 0x40010000 + 8000b70: 48000400 .word 0x48000400 + 8000b74: 48000800 .word 0x48000800 + 8000b78: 48000c00 .word 0x48000c00 + 8000b7c: 48001000 .word 0x48001000 + 8000b80: 40010400 .word 0x40010400 + +08000b84 : + * parameters in the PCD_InitTypeDef and initialize the associated handle. + * @param hpcd PCD handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_Init(PCD_HandleTypeDef *hpcd) +{ + 8000b84: b5f0 push {r4, r5, r6, r7, lr} + 8000b86: b08b sub sp, #44 ; 0x2c + 8000b88: af06 add r7, sp, #24 + 8000b8a: 6078 str r0, [r7, #4] + uint8_t i; + + /* Check the PCD handle allocation */ + if (hpcd == NULL) + 8000b8c: 687b ldr r3, [r7, #4] + 8000b8e: 2b00 cmp r3, #0 + 8000b90: d101 bne.n 8000b96 + { + return HAL_ERROR; + 8000b92: 2301 movs r3, #1 + 8000b94: e0d4 b.n 8000d40 + } + + /* Check the parameters */ + assert_param(IS_PCD_ALL_INSTANCE(hpcd->Instance)); + + if (hpcd->State == HAL_PCD_STATE_RESET) + 8000b96: 687b ldr r3, [r7, #4] + 8000b98: 4a6b ldr r2, [pc, #428] ; (8000d48 ) + 8000b9a: 5c9b ldrb r3, [r3, r2] + 8000b9c: b2db uxtb r3, r3 + 8000b9e: 2b00 cmp r3, #0 + 8000ba0: d108 bne.n 8000bb4 + { + /* Allocate lock resource and initialize it */ + hpcd->Lock = HAL_UNLOCKED; + 8000ba2: 687a ldr r2, [r7, #4] + 8000ba4: 238a movs r3, #138 ; 0x8a + 8000ba6: 009b lsls r3, r3, #2 + 8000ba8: 2100 movs r1, #0 + 8000baa: 54d1 strb r1, [r2, r3] + + /* Init the low level hardware */ + hpcd->MspInitCallback(hpcd); +#else + /* Init the low level hardware : GPIO, CLOCK, NVIC... */ + HAL_PCD_MspInit(hpcd); + 8000bac: 687b ldr r3, [r7, #4] + 8000bae: 0018 movs r0, r3 + 8000bb0: f00d fbe2 bl 800e378 +#endif /* (USE_HAL_PCD_REGISTER_CALLBACKS) */ + } + + hpcd->State = HAL_PCD_STATE_BUSY; + 8000bb4: 687b ldr r3, [r7, #4] + 8000bb6: 4a64 ldr r2, [pc, #400] ; (8000d48 ) + 8000bb8: 2103 movs r1, #3 + 8000bba: 5499 strb r1, [r3, r2] + + /* Disable the Interrupts */ + __HAL_PCD_DISABLE(hpcd); + 8000bbc: 687b ldr r3, [r7, #4] + 8000bbe: 681b ldr r3, [r3, #0] + 8000bc0: 0018 movs r0, r3 + 8000bc2: f001 fdf7 bl 80027b4 + + /* Init endpoints structures */ + for (i = 0U; i < hpcd->Init.dev_endpoints; i++) + 8000bc6: 230f movs r3, #15 + 8000bc8: 18fb adds r3, r7, r3 + 8000bca: 2200 movs r2, #0 + 8000bcc: 701a strb r2, [r3, #0] + 8000bce: e043 b.n 8000c58 + { + /* Init ep structure */ + hpcd->IN_ep[i].is_in = 1U; + 8000bd0: 200f movs r0, #15 + 8000bd2: 183b adds r3, r7, r0 + 8000bd4: 781b ldrb r3, [r3, #0] + 8000bd6: 687a ldr r2, [r7, #4] + 8000bd8: 2129 movs r1, #41 ; 0x29 + 8000bda: 015b lsls r3, r3, #5 + 8000bdc: 18d3 adds r3, r2, r3 + 8000bde: 185b adds r3, r3, r1 + 8000be0: 2201 movs r2, #1 + 8000be2: 701a strb r2, [r3, #0] + hpcd->IN_ep[i].num = i; + 8000be4: 183b adds r3, r7, r0 + 8000be6: 781b ldrb r3, [r3, #0] + 8000be8: 687a ldr r2, [r7, #4] + 8000bea: 2128 movs r1, #40 ; 0x28 + 8000bec: 015b lsls r3, r3, #5 + 8000bee: 18d3 adds r3, r2, r3 + 8000bf0: 185b adds r3, r3, r1 + 8000bf2: 183a adds r2, r7, r0 + 8000bf4: 7812 ldrb r2, [r2, #0] + 8000bf6: 701a strb r2, [r3, #0] + hpcd->IN_ep[i].tx_fifo_num = i; + 8000bf8: 183b adds r3, r7, r0 + 8000bfa: 781b ldrb r3, [r3, #0] + 8000bfc: 183a adds r2, r7, r0 + 8000bfe: 7812 ldrb r2, [r2, #0] + 8000c00: b291 uxth r1, r2 + 8000c02: 687a ldr r2, [r7, #4] + 8000c04: 015b lsls r3, r3, #5 + 8000c06: 18d3 adds r3, r2, r3 + 8000c08: 3336 adds r3, #54 ; 0x36 + 8000c0a: 1c0a adds r2, r1, #0 + 8000c0c: 801a strh r2, [r3, #0] + /* Control until ep is activated */ + hpcd->IN_ep[i].type = EP_TYPE_CTRL; + 8000c0e: 183b adds r3, r7, r0 + 8000c10: 781b ldrb r3, [r3, #0] + 8000c12: 687a ldr r2, [r7, #4] + 8000c14: 212b movs r1, #43 ; 0x2b + 8000c16: 015b lsls r3, r3, #5 + 8000c18: 18d3 adds r3, r2, r3 + 8000c1a: 185b adds r3, r3, r1 + 8000c1c: 2200 movs r2, #0 + 8000c1e: 701a strb r2, [r3, #0] + hpcd->IN_ep[i].maxpacket = 0U; + 8000c20: 183b adds r3, r7, r0 + 8000c22: 781b ldrb r3, [r3, #0] + 8000c24: 687a ldr r2, [r7, #4] + 8000c26: 015b lsls r3, r3, #5 + 8000c28: 18d3 adds r3, r2, r3 + 8000c2a: 3338 adds r3, #56 ; 0x38 + 8000c2c: 2200 movs r2, #0 + 8000c2e: 601a str r2, [r3, #0] + hpcd->IN_ep[i].xfer_buff = 0U; + 8000c30: 183b adds r3, r7, r0 + 8000c32: 781b ldrb r3, [r3, #0] + 8000c34: 687a ldr r2, [r7, #4] + 8000c36: 015b lsls r3, r3, #5 + 8000c38: 18d3 adds r3, r2, r3 + 8000c3a: 333c adds r3, #60 ; 0x3c + 8000c3c: 2200 movs r2, #0 + 8000c3e: 601a str r2, [r3, #0] + hpcd->IN_ep[i].xfer_len = 0U; + 8000c40: 183b adds r3, r7, r0 + 8000c42: 781a ldrb r2, [r3, #0] + 8000c44: 687b ldr r3, [r7, #4] + 8000c46: 3202 adds r2, #2 + 8000c48: 0152 lsls r2, r2, #5 + 8000c4a: 2100 movs r1, #0 + 8000c4c: 50d1 str r1, [r2, r3] + for (i = 0U; i < hpcd->Init.dev_endpoints; i++) + 8000c4e: 183b adds r3, r7, r0 + 8000c50: 781a ldrb r2, [r3, #0] + 8000c52: 183b adds r3, r7, r0 + 8000c54: 3201 adds r2, #1 + 8000c56: 701a strb r2, [r3, #0] + 8000c58: 230f movs r3, #15 + 8000c5a: 18fb adds r3, r7, r3 + 8000c5c: 781a ldrb r2, [r3, #0] + 8000c5e: 687b ldr r3, [r7, #4] + 8000c60: 685b ldr r3, [r3, #4] + 8000c62: 429a cmp r2, r3 + 8000c64: d3b4 bcc.n 8000bd0 + } + + for (i = 0U; i < hpcd->Init.dev_endpoints; i++) + 8000c66: 230f movs r3, #15 + 8000c68: 18fb adds r3, r7, r3 + 8000c6a: 2200 movs r2, #0 + 8000c6c: 701a strb r2, [r3, #0] + 8000c6e: e03f b.n 8000cf0 + { + hpcd->OUT_ep[i].is_in = 0U; + 8000c70: 200f movs r0, #15 + 8000c72: 183b adds r3, r7, r0 + 8000c74: 781a ldrb r2, [r3, #0] + 8000c76: 6879 ldr r1, [r7, #4] + 8000c78: 232a movs r3, #42 ; 0x2a + 8000c7a: 33ff adds r3, #255 ; 0xff + 8000c7c: 0152 lsls r2, r2, #5 + 8000c7e: 188a adds r2, r1, r2 + 8000c80: 18d3 adds r3, r2, r3 + 8000c82: 2200 movs r2, #0 + 8000c84: 701a strb r2, [r3, #0] + hpcd->OUT_ep[i].num = i; + 8000c86: 183b adds r3, r7, r0 + 8000c88: 781a ldrb r2, [r3, #0] + 8000c8a: 6879 ldr r1, [r7, #4] + 8000c8c: 2394 movs r3, #148 ; 0x94 + 8000c8e: 005b lsls r3, r3, #1 + 8000c90: 0152 lsls r2, r2, #5 + 8000c92: 188a adds r2, r1, r2 + 8000c94: 18d3 adds r3, r2, r3 + 8000c96: 183a adds r2, r7, r0 + 8000c98: 7812 ldrb r2, [r2, #0] + 8000c9a: 701a strb r2, [r3, #0] + /* Control until ep is activated */ + hpcd->OUT_ep[i].type = EP_TYPE_CTRL; + 8000c9c: 183b adds r3, r7, r0 + 8000c9e: 781a ldrb r2, [r3, #0] + 8000ca0: 6879 ldr r1, [r7, #4] + 8000ca2: 232c movs r3, #44 ; 0x2c + 8000ca4: 33ff adds r3, #255 ; 0xff + 8000ca6: 0152 lsls r2, r2, #5 + 8000ca8: 188a adds r2, r1, r2 + 8000caa: 18d3 adds r3, r2, r3 + 8000cac: 2200 movs r2, #0 + 8000cae: 701a strb r2, [r3, #0] + hpcd->OUT_ep[i].maxpacket = 0U; + 8000cb0: 183b adds r3, r7, r0 + 8000cb2: 781a ldrb r2, [r3, #0] + 8000cb4: 6879 ldr r1, [r7, #4] + 8000cb6: 239c movs r3, #156 ; 0x9c + 8000cb8: 005b lsls r3, r3, #1 + 8000cba: 0152 lsls r2, r2, #5 + 8000cbc: 188a adds r2, r1, r2 + 8000cbe: 18d3 adds r3, r2, r3 + 8000cc0: 2200 movs r2, #0 + 8000cc2: 601a str r2, [r3, #0] + hpcd->OUT_ep[i].xfer_buff = 0U; + 8000cc4: 183b adds r3, r7, r0 + 8000cc6: 781a ldrb r2, [r3, #0] + 8000cc8: 6879 ldr r1, [r7, #4] + 8000cca: 239e movs r3, #158 ; 0x9e + 8000ccc: 005b lsls r3, r3, #1 + 8000cce: 0152 lsls r2, r2, #5 + 8000cd0: 188a adds r2, r1, r2 + 8000cd2: 18d3 adds r3, r2, r3 + 8000cd4: 2200 movs r2, #0 + 8000cd6: 601a str r2, [r3, #0] + hpcd->OUT_ep[i].xfer_len = 0U; + 8000cd8: 183b adds r3, r7, r0 + 8000cda: 781a ldrb r2, [r3, #0] + 8000cdc: 687b ldr r3, [r7, #4] + 8000cde: 320a adds r2, #10 + 8000ce0: 0152 lsls r2, r2, #5 + 8000ce2: 2100 movs r1, #0 + 8000ce4: 50d1 str r1, [r2, r3] + for (i = 0U; i < hpcd->Init.dev_endpoints; i++) + 8000ce6: 183b adds r3, r7, r0 + 8000ce8: 781a ldrb r2, [r3, #0] + 8000cea: 183b adds r3, r7, r0 + 8000cec: 3201 adds r2, #1 + 8000cee: 701a strb r2, [r3, #0] + 8000cf0: 230f movs r3, #15 + 8000cf2: 18fb adds r3, r7, r3 + 8000cf4: 781a ldrb r2, [r3, #0] + 8000cf6: 687b ldr r3, [r7, #4] + 8000cf8: 685b ldr r3, [r3, #4] + 8000cfa: 429a cmp r2, r3 + 8000cfc: d3b8 bcc.n 8000c70 + } + + /* Init Device */ + (void)USB_DevInit(hpcd->Instance, hpcd->Init); + 8000cfe: 687b ldr r3, [r7, #4] + 8000d00: 6818 ldr r0, [r3, #0] + 8000d02: 687b ldr r3, [r7, #4] + 8000d04: 466a mov r2, sp + 8000d06: 0011 movs r1, r2 + 8000d08: 001a movs r2, r3 + 8000d0a: 3210 adds r2, #16 + 8000d0c: ca70 ldmia r2!, {r4, r5, r6} + 8000d0e: c170 stmia r1!, {r4, r5, r6} + 8000d10: ca30 ldmia r2!, {r4, r5} + 8000d12: c130 stmia r1!, {r4, r5} + 8000d14: 6859 ldr r1, [r3, #4] + 8000d16: 689a ldr r2, [r3, #8] + 8000d18: 68db ldr r3, [r3, #12] + 8000d1a: f001 fd6b bl 80027f4 + + hpcd->USB_Address = 0U; + 8000d1e: 687b ldr r3, [r7, #4] + 8000d20: 2224 movs r2, #36 ; 0x24 + 8000d22: 2100 movs r1, #0 + 8000d24: 5499 strb r1, [r3, r2] + hpcd->State = HAL_PCD_STATE_READY; + 8000d26: 687b ldr r3, [r7, #4] + 8000d28: 4a07 ldr r2, [pc, #28] ; (8000d48 ) + 8000d2a: 2101 movs r1, #1 + 8000d2c: 5499 strb r1, [r3, r2] + + /* Activate LPM */ + if (hpcd->Init.lpm_enable == 1U) + 8000d2e: 687b ldr r3, [r7, #4] + 8000d30: 69db ldr r3, [r3, #28] + 8000d32: 2b01 cmp r3, #1 + 8000d34: d103 bne.n 8000d3e + { + (void)HAL_PCDEx_ActivateLPM(hpcd); + 8000d36: 687b ldr r3, [r7, #4] + 8000d38: 0018 movs r0, r3 + 8000d3a: f000 ff0d bl 8001b58 + } + + return HAL_OK; + 8000d3e: 2300 movs r3, #0 +} + 8000d40: 0018 movs r0, r3 + 8000d42: 46bd mov sp, r7 + 8000d44: b005 add sp, #20 + 8000d46: bdf0 pop {r4, r5, r6, r7, pc} + 8000d48: 00000229 .word 0x00000229 + +08000d4c : + * @brief Start the USB device + * @param hpcd PCD handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_Start(PCD_HandleTypeDef *hpcd) +{ + 8000d4c: b580 push {r7, lr} + 8000d4e: b082 sub sp, #8 + 8000d50: af00 add r7, sp, #0 + 8000d52: 6078 str r0, [r7, #4] + __HAL_LOCK(hpcd); + 8000d54: 687a ldr r2, [r7, #4] + 8000d56: 238a movs r3, #138 ; 0x8a + 8000d58: 009b lsls r3, r3, #2 + 8000d5a: 5cd3 ldrb r3, [r2, r3] + 8000d5c: 2b01 cmp r3, #1 + 8000d5e: d101 bne.n 8000d64 + 8000d60: 2302 movs r3, #2 + 8000d62: e014 b.n 8000d8e + 8000d64: 687a ldr r2, [r7, #4] + 8000d66: 238a movs r3, #138 ; 0x8a + 8000d68: 009b lsls r3, r3, #2 + 8000d6a: 2101 movs r1, #1 + 8000d6c: 54d1 strb r1, [r2, r3] + (void)USB_DevConnect(hpcd->Instance); + 8000d6e: 687b ldr r3, [r7, #4] + 8000d70: 681b ldr r3, [r3, #0] + 8000d72: 0018 movs r0, r3 + 8000d74: f002 fd96 bl 80038a4 + __HAL_PCD_ENABLE(hpcd); + 8000d78: 687b ldr r3, [r7, #4] + 8000d7a: 681b ldr r3, [r3, #0] + 8000d7c: 0018 movs r0, r3 + 8000d7e: f001 fcff bl 8002780 + __HAL_UNLOCK(hpcd); + 8000d82: 687a ldr r2, [r7, #4] + 8000d84: 238a movs r3, #138 ; 0x8a + 8000d86: 009b lsls r3, r3, #2 + 8000d88: 2100 movs r1, #0 + 8000d8a: 54d1 strb r1, [r2, r3] + return HAL_OK; + 8000d8c: 2300 movs r3, #0 +} + 8000d8e: 0018 movs r0, r3 + 8000d90: 46bd mov sp, r7 + 8000d92: b002 add sp, #8 + 8000d94: bd80 pop {r7, pc} + ... + +08000d98 : + * @brief This function handles PCD interrupt request. + * @param hpcd PCD handle + * @retval HAL status + */ +void HAL_PCD_IRQHandler(PCD_HandleTypeDef *hpcd) +{ + 8000d98: b580 push {r7, lr} + 8000d9a: b082 sub sp, #8 + 8000d9c: af00 add r7, sp, #0 + 8000d9e: 6078 str r0, [r7, #4] + if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_CTR)) + 8000da0: 687b ldr r3, [r7, #4] + 8000da2: 681b ldr r3, [r3, #0] + 8000da4: 0018 movs r0, r3 + 8000da6: f002 fd93 bl 80038d0 + 8000daa: 0002 movs r2, r0 + 8000dac: 2380 movs r3, #128 ; 0x80 + 8000dae: 021b lsls r3, r3, #8 + 8000db0: 401a ands r2, r3 + 8000db2: 2380 movs r3, #128 ; 0x80 + 8000db4: 021b lsls r3, r3, #8 + 8000db6: 429a cmp r2, r3 + 8000db8: d103 bne.n 8000dc2 + { + /* servicing of the endpoint correct transfer interrupt */ + /* clear of the CTR flag into the sub */ + (void)PCD_EP_ISR_Handler(hpcd); + 8000dba: 687b ldr r3, [r7, #4] + 8000dbc: 0018 movs r0, r3 + 8000dbe: f000 fbaf bl 8001520 + } + + if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_RESET)) + 8000dc2: 687b ldr r3, [r7, #4] + 8000dc4: 681b ldr r3, [r3, #0] + 8000dc6: 0018 movs r0, r3 + 8000dc8: f002 fd82 bl 80038d0 + 8000dcc: 0002 movs r2, r0 + 8000dce: 2380 movs r3, #128 ; 0x80 + 8000dd0: 00db lsls r3, r3, #3 + 8000dd2: 401a ands r2, r3 + 8000dd4: 2380 movs r3, #128 ; 0x80 + 8000dd6: 00db lsls r3, r3, #3 + 8000dd8: 429a cmp r2, r3 + 8000dda: d114 bne.n 8000e06 + { + __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_RESET); + 8000ddc: 687b ldr r3, [r7, #4] + 8000dde: 681b ldr r3, [r3, #0] + 8000de0: 2244 movs r2, #68 ; 0x44 + 8000de2: 5a9b ldrh r3, [r3, r2] + 8000de4: b29a uxth r2, r3 + 8000de6: 687b ldr r3, [r7, #4] + 8000de8: 681b ldr r3, [r3, #0] + 8000dea: 49a8 ldr r1, [pc, #672] ; (800108c ) + 8000dec: 400a ands r2, r1 + 8000dee: b291 uxth r1, r2 + 8000df0: 2244 movs r2, #68 ; 0x44 + 8000df2: 5299 strh r1, [r3, r2] + +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) + hpcd->ResetCallback(hpcd); +#else + HAL_PCD_ResetCallback(hpcd); + 8000df4: 687b ldr r3, [r7, #4] + 8000df6: 0018 movs r0, r3 + 8000df8: f00d fb60 bl 800e4bc +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ + + (void)HAL_PCD_SetAddress(hpcd, 0U); + 8000dfc: 687b ldr r3, [r7, #4] + 8000dfe: 2100 movs r1, #0 + 8000e00: 0018 movs r0, r3 + 8000e02: f000 f951 bl 80010a8 + } + + if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_PMAOVR)) + 8000e06: 687b ldr r3, [r7, #4] + 8000e08: 681b ldr r3, [r3, #0] + 8000e0a: 0018 movs r0, r3 + 8000e0c: f002 fd60 bl 80038d0 + 8000e10: 0002 movs r2, r0 + 8000e12: 2380 movs r3, #128 ; 0x80 + 8000e14: 01db lsls r3, r3, #7 + 8000e16: 401a ands r2, r3 + 8000e18: 2380 movs r3, #128 ; 0x80 + 8000e1a: 01db lsls r3, r3, #7 + 8000e1c: 429a cmp r2, r3 + 8000e1e: d10b bne.n 8000e38 + { + __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_PMAOVR); + 8000e20: 687b ldr r3, [r7, #4] + 8000e22: 681b ldr r3, [r3, #0] + 8000e24: 2244 movs r2, #68 ; 0x44 + 8000e26: 5a9b ldrh r3, [r3, r2] + 8000e28: b29a uxth r2, r3 + 8000e2a: 687b ldr r3, [r7, #4] + 8000e2c: 681b ldr r3, [r3, #0] + 8000e2e: 4998 ldr r1, [pc, #608] ; (8001090 ) + 8000e30: 400a ands r2, r1 + 8000e32: b291 uxth r1, r2 + 8000e34: 2244 movs r2, #68 ; 0x44 + 8000e36: 5299 strh r1, [r3, r2] + } + + if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_ERR)) + 8000e38: 687b ldr r3, [r7, #4] + 8000e3a: 681b ldr r3, [r3, #0] + 8000e3c: 0018 movs r0, r3 + 8000e3e: f002 fd47 bl 80038d0 + 8000e42: 0002 movs r2, r0 + 8000e44: 2380 movs r3, #128 ; 0x80 + 8000e46: 019b lsls r3, r3, #6 + 8000e48: 401a ands r2, r3 + 8000e4a: 2380 movs r3, #128 ; 0x80 + 8000e4c: 019b lsls r3, r3, #6 + 8000e4e: 429a cmp r2, r3 + 8000e50: d10b bne.n 8000e6a + { + __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_ERR); + 8000e52: 687b ldr r3, [r7, #4] + 8000e54: 681b ldr r3, [r3, #0] + 8000e56: 2244 movs r2, #68 ; 0x44 + 8000e58: 5a9b ldrh r3, [r3, r2] + 8000e5a: b29a uxth r2, r3 + 8000e5c: 687b ldr r3, [r7, #4] + 8000e5e: 681b ldr r3, [r3, #0] + 8000e60: 498c ldr r1, [pc, #560] ; (8001094 ) + 8000e62: 400a ands r2, r1 + 8000e64: b291 uxth r1, r2 + 8000e66: 2244 movs r2, #68 ; 0x44 + 8000e68: 5299 strh r1, [r3, r2] + } + + if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_WKUP)) + 8000e6a: 687b ldr r3, [r7, #4] + 8000e6c: 681b ldr r3, [r3, #0] + 8000e6e: 0018 movs r0, r3 + 8000e70: f002 fd2e bl 80038d0 + 8000e74: 0002 movs r2, r0 + 8000e76: 2380 movs r3, #128 ; 0x80 + 8000e78: 015b lsls r3, r3, #5 + 8000e7a: 401a ands r2, r3 + 8000e7c: 2380 movs r3, #128 ; 0x80 + 8000e7e: 015b lsls r3, r3, #5 + 8000e80: 429a cmp r2, r3 + 8000e82: d137 bne.n 8000ef4 + { + hpcd->Instance->CNTR &= (uint16_t) ~(USB_CNTR_LPMODE); + 8000e84: 687b ldr r3, [r7, #4] + 8000e86: 681b ldr r3, [r3, #0] + 8000e88: 2240 movs r2, #64 ; 0x40 + 8000e8a: 5a9b ldrh r3, [r3, r2] + 8000e8c: b29a uxth r2, r3 + 8000e8e: 687b ldr r3, [r7, #4] + 8000e90: 681b ldr r3, [r3, #0] + 8000e92: 2104 movs r1, #4 + 8000e94: 438a bics r2, r1 + 8000e96: b291 uxth r1, r2 + 8000e98: 2240 movs r2, #64 ; 0x40 + 8000e9a: 5299 strh r1, [r3, r2] + hpcd->Instance->CNTR &= (uint16_t) ~(USB_CNTR_FSUSP); + 8000e9c: 687b ldr r3, [r7, #4] + 8000e9e: 681b ldr r3, [r3, #0] + 8000ea0: 2240 movs r2, #64 ; 0x40 + 8000ea2: 5a9b ldrh r3, [r3, r2] + 8000ea4: b29a uxth r2, r3 + 8000ea6: 687b ldr r3, [r7, #4] + 8000ea8: 681b ldr r3, [r3, #0] + 8000eaa: 2108 movs r1, #8 + 8000eac: 438a bics r2, r1 + 8000eae: b291 uxth r1, r2 + 8000eb0: 2240 movs r2, #64 ; 0x40 + 8000eb2: 5299 strh r1, [r3, r2] + + if (hpcd->LPM_State == LPM_L1) + 8000eb4: 687a ldr r2, [r7, #4] + 8000eb6: 2398 movs r3, #152 ; 0x98 + 8000eb8: 009b lsls r3, r3, #2 + 8000eba: 5cd3 ldrb r3, [r2, r3] + 8000ebc: 2b01 cmp r3, #1 + 8000ebe: d109 bne.n 8000ed4 + { + hpcd->LPM_State = LPM_L0; + 8000ec0: 687a ldr r2, [r7, #4] + 8000ec2: 2398 movs r3, #152 ; 0x98 + 8000ec4: 009b lsls r3, r3, #2 + 8000ec6: 2100 movs r1, #0 + 8000ec8: 54d1 strb r1, [r2, r3] +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) + hpcd->LPMCallback(hpcd, PCD_LPM_L0_ACTIVE); +#else + HAL_PCDEx_LPM_Callback(hpcd, PCD_LPM_L0_ACTIVE); + 8000eca: 687b ldr r3, [r7, #4] + 8000ecc: 2100 movs r1, #0 + 8000ece: 0018 movs r0, r3 + 8000ed0: f000 fe6c bl 8001bac + } + +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) + hpcd->ResumeCallback(hpcd); +#else + HAL_PCD_ResumeCallback(hpcd); + 8000ed4: 687b ldr r3, [r7, #4] + 8000ed6: 0018 movs r0, r3 + 8000ed8: f00d fb0f bl 800e4fa +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ + + __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_WKUP); + 8000edc: 687b ldr r3, [r7, #4] + 8000ede: 681b ldr r3, [r3, #0] + 8000ee0: 2244 movs r2, #68 ; 0x44 + 8000ee2: 5a9b ldrh r3, [r3, r2] + 8000ee4: b29a uxth r2, r3 + 8000ee6: 687b ldr r3, [r7, #4] + 8000ee8: 681b ldr r3, [r3, #0] + 8000eea: 496b ldr r1, [pc, #428] ; (8001098 ) + 8000eec: 400a ands r2, r1 + 8000eee: b291 uxth r1, r2 + 8000ef0: 2244 movs r2, #68 ; 0x44 + 8000ef2: 5299 strh r1, [r3, r2] + } + + if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_SUSP)) + 8000ef4: 687b ldr r3, [r7, #4] + 8000ef6: 681b ldr r3, [r3, #0] + 8000ef8: 0018 movs r0, r3 + 8000efa: f002 fce9 bl 80038d0 + 8000efe: 0002 movs r2, r0 + 8000f00: 2380 movs r3, #128 ; 0x80 + 8000f02: 011b lsls r3, r3, #4 + 8000f04: 401a ands r2, r3 + 8000f06: 2380 movs r3, #128 ; 0x80 + 8000f08: 011b lsls r3, r3, #4 + 8000f0a: 429a cmp r2, r3 + 8000f0c: d134 bne.n 8000f78 + { + /* Force low-power mode in the macrocell */ + hpcd->Instance->CNTR |= USB_CNTR_FSUSP; + 8000f0e: 687b ldr r3, [r7, #4] + 8000f10: 681b ldr r3, [r3, #0] + 8000f12: 2240 movs r2, #64 ; 0x40 + 8000f14: 5a9b ldrh r3, [r3, r2] + 8000f16: b29a uxth r2, r3 + 8000f18: 687b ldr r3, [r7, #4] + 8000f1a: 681b ldr r3, [r3, #0] + 8000f1c: 2108 movs r1, #8 + 8000f1e: 430a orrs r2, r1 + 8000f20: b291 uxth r1, r2 + 8000f22: 2240 movs r2, #64 ; 0x40 + 8000f24: 5299 strh r1, [r3, r2] + + /* clear of the ISTR bit must be done after setting of CNTR_FSUSP */ + __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_SUSP); + 8000f26: 687b ldr r3, [r7, #4] + 8000f28: 681b ldr r3, [r3, #0] + 8000f2a: 2244 movs r2, #68 ; 0x44 + 8000f2c: 5a9b ldrh r3, [r3, r2] + 8000f2e: b29a uxth r2, r3 + 8000f30: 687b ldr r3, [r7, #4] + 8000f32: 681b ldr r3, [r3, #0] + 8000f34: 4959 ldr r1, [pc, #356] ; (800109c ) + 8000f36: 400a ands r2, r1 + 8000f38: b291 uxth r1, r2 + 8000f3a: 2244 movs r2, #68 ; 0x44 + 8000f3c: 5299 strh r1, [r3, r2] + + hpcd->Instance->CNTR |= USB_CNTR_LPMODE; + 8000f3e: 687b ldr r3, [r7, #4] + 8000f40: 681b ldr r3, [r3, #0] + 8000f42: 2240 movs r2, #64 ; 0x40 + 8000f44: 5a9b ldrh r3, [r3, r2] + 8000f46: b29a uxth r2, r3 + 8000f48: 687b ldr r3, [r7, #4] + 8000f4a: 681b ldr r3, [r3, #0] + 8000f4c: 2104 movs r1, #4 + 8000f4e: 430a orrs r2, r1 + 8000f50: b291 uxth r1, r2 + 8000f52: 2240 movs r2, #64 ; 0x40 + 8000f54: 5299 strh r1, [r3, r2] + + if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_WKUP) == 0U) + 8000f56: 687b ldr r3, [r7, #4] + 8000f58: 681b ldr r3, [r3, #0] + 8000f5a: 0018 movs r0, r3 + 8000f5c: f002 fcb8 bl 80038d0 + 8000f60: 0002 movs r2, r0 + 8000f62: 2380 movs r3, #128 ; 0x80 + 8000f64: 015b lsls r3, r3, #5 + 8000f66: 401a ands r2, r3 + 8000f68: 2380 movs r3, #128 ; 0x80 + 8000f6a: 015b lsls r3, r3, #5 + 8000f6c: 429a cmp r2, r3 + 8000f6e: d003 beq.n 8000f78 + { +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) + hpcd->SuspendCallback(hpcd); +#else + HAL_PCD_SuspendCallback(hpcd); + 8000f70: 687b ldr r3, [r7, #4] + 8000f72: 0018 movs r0, r3 + 8000f74: f00d fab9 bl 800e4ea +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ + } + } + + /* Handle LPM Interrupt */ + if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_L1REQ)) + 8000f78: 687b ldr r3, [r7, #4] + 8000f7a: 681b ldr r3, [r3, #0] + 8000f7c: 0018 movs r0, r3 + 8000f7e: f002 fca7 bl 80038d0 + 8000f82: 0002 movs r2, r0 + 8000f84: 2380 movs r3, #128 ; 0x80 + 8000f86: 4013 ands r3, r2 + 8000f88: 2b80 cmp r3, #128 ; 0x80 + 8000f8a: d145 bne.n 8001018 + { + __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_L1REQ); + 8000f8c: 687b ldr r3, [r7, #4] + 8000f8e: 681b ldr r3, [r3, #0] + 8000f90: 2244 movs r2, #68 ; 0x44 + 8000f92: 5a9b ldrh r3, [r3, r2] + 8000f94: b29a uxth r2, r3 + 8000f96: 687b ldr r3, [r7, #4] + 8000f98: 681b ldr r3, [r3, #0] + 8000f9a: 2180 movs r1, #128 ; 0x80 + 8000f9c: 438a bics r2, r1 + 8000f9e: b291 uxth r1, r2 + 8000fa0: 2244 movs r2, #68 ; 0x44 + 8000fa2: 5299 strh r1, [r3, r2] + if (hpcd->LPM_State == LPM_L0) + 8000fa4: 687a ldr r2, [r7, #4] + 8000fa6: 2398 movs r3, #152 ; 0x98 + 8000fa8: 009b lsls r3, r3, #2 + 8000faa: 5cd3 ldrb r3, [r2, r3] + 8000fac: 2b00 cmp r3, #0 + 8000fae: d12f bne.n 8001010 + { + /* Force suspend and low-power mode before going to L1 state*/ + hpcd->Instance->CNTR |= USB_CNTR_LPMODE; + 8000fb0: 687b ldr r3, [r7, #4] + 8000fb2: 681b ldr r3, [r3, #0] + 8000fb4: 2240 movs r2, #64 ; 0x40 + 8000fb6: 5a9b ldrh r3, [r3, r2] + 8000fb8: b29a uxth r2, r3 + 8000fba: 687b ldr r3, [r7, #4] + 8000fbc: 681b ldr r3, [r3, #0] + 8000fbe: 2104 movs r1, #4 + 8000fc0: 430a orrs r2, r1 + 8000fc2: b291 uxth r1, r2 + 8000fc4: 2240 movs r2, #64 ; 0x40 + 8000fc6: 5299 strh r1, [r3, r2] + hpcd->Instance->CNTR |= USB_CNTR_FSUSP; + 8000fc8: 687b ldr r3, [r7, #4] + 8000fca: 681b ldr r3, [r3, #0] + 8000fcc: 2240 movs r2, #64 ; 0x40 + 8000fce: 5a9b ldrh r3, [r3, r2] + 8000fd0: b29a uxth r2, r3 + 8000fd2: 687b ldr r3, [r7, #4] + 8000fd4: 681b ldr r3, [r3, #0] + 8000fd6: 2108 movs r1, #8 + 8000fd8: 430a orrs r2, r1 + 8000fda: b291 uxth r1, r2 + 8000fdc: 2240 movs r2, #64 ; 0x40 + 8000fde: 5299 strh r1, [r3, r2] + + hpcd->LPM_State = LPM_L1; + 8000fe0: 687a ldr r2, [r7, #4] + 8000fe2: 2398 movs r3, #152 ; 0x98 + 8000fe4: 009b lsls r3, r3, #2 + 8000fe6: 2101 movs r1, #1 + 8000fe8: 54d1 strb r1, [r2, r3] + hpcd->BESL = ((uint32_t)hpcd->Instance->LPMCSR & USB_LPMCSR_BESL) >> 2; + 8000fea: 687b ldr r3, [r7, #4] + 8000fec: 681b ldr r3, [r3, #0] + 8000fee: 2254 movs r2, #84 ; 0x54 + 8000ff0: 5a9b ldrh r3, [r3, r2] + 8000ff2: b29b uxth r3, r3 + 8000ff4: 089b lsrs r3, r3, #2 + 8000ff6: 223c movs r2, #60 ; 0x3c + 8000ff8: 4013 ands r3, r2 + 8000ffa: 0019 movs r1, r3 + 8000ffc: 687a ldr r2, [r7, #4] + 8000ffe: 2399 movs r3, #153 ; 0x99 + 8001000: 009b lsls r3, r3, #2 + 8001002: 50d1 str r1, [r2, r3] +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) + hpcd->LPMCallback(hpcd, PCD_LPM_L1_ACTIVE); +#else + HAL_PCDEx_LPM_Callback(hpcd, PCD_LPM_L1_ACTIVE); + 8001004: 687b ldr r3, [r7, #4] + 8001006: 2101 movs r1, #1 + 8001008: 0018 movs r0, r3 + 800100a: f000 fdcf bl 8001bac + 800100e: e003 b.n 8001018 + else + { +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) + hpcd->SuspendCallback(hpcd); +#else + HAL_PCD_SuspendCallback(hpcd); + 8001010: 687b ldr r3, [r7, #4] + 8001012: 0018 movs r0, r3 + 8001014: f00d fa69 bl 800e4ea +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ + } + } + + if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_SOF)) + 8001018: 687b ldr r3, [r7, #4] + 800101a: 681b ldr r3, [r3, #0] + 800101c: 0018 movs r0, r3 + 800101e: f002 fc57 bl 80038d0 + 8001022: 0002 movs r2, r0 + 8001024: 2380 movs r3, #128 ; 0x80 + 8001026: 009b lsls r3, r3, #2 + 8001028: 401a ands r2, r3 + 800102a: 2380 movs r3, #128 ; 0x80 + 800102c: 009b lsls r3, r3, #2 + 800102e: 429a cmp r2, r3 + 8001030: d10f bne.n 8001052 + { + __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_SOF); + 8001032: 687b ldr r3, [r7, #4] + 8001034: 681b ldr r3, [r3, #0] + 8001036: 2244 movs r2, #68 ; 0x44 + 8001038: 5a9b ldrh r3, [r3, r2] + 800103a: b29a uxth r2, r3 + 800103c: 687b ldr r3, [r7, #4] + 800103e: 681b ldr r3, [r3, #0] + 8001040: 4917 ldr r1, [pc, #92] ; (80010a0 ) + 8001042: 400a ands r2, r1 + 8001044: b291 uxth r1, r2 + 8001046: 2244 movs r2, #68 ; 0x44 + 8001048: 5299 strh r1, [r3, r2] + +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) + hpcd->SOFCallback(hpcd); +#else + HAL_PCD_SOFCallback(hpcd); + 800104a: 687b ldr r3, [r7, #4] + 800104c: 0018 movs r0, r3 + 800104e: f00d fa26 bl 800e49e +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ + } + + if (__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_ESOF)) + 8001052: 687b ldr r3, [r7, #4] + 8001054: 681b ldr r3, [r3, #0] + 8001056: 0018 movs r0, r3 + 8001058: f002 fc3a bl 80038d0 + 800105c: 0002 movs r2, r0 + 800105e: 2380 movs r3, #128 ; 0x80 + 8001060: 005b lsls r3, r3, #1 + 8001062: 401a ands r2, r3 + 8001064: 2380 movs r3, #128 ; 0x80 + 8001066: 005b lsls r3, r3, #1 + 8001068: 429a cmp r2, r3 + 800106a: d10b bne.n 8001084 + { + /* clear ESOF flag in ISTR */ + __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_ESOF); + 800106c: 687b ldr r3, [r7, #4] + 800106e: 681b ldr r3, [r3, #0] + 8001070: 2244 movs r2, #68 ; 0x44 + 8001072: 5a9b ldrh r3, [r3, r2] + 8001074: b29a uxth r2, r3 + 8001076: 687b ldr r3, [r7, #4] + 8001078: 681b ldr r3, [r3, #0] + 800107a: 490a ldr r1, [pc, #40] ; (80010a4 ) + 800107c: 400a ands r2, r1 + 800107e: b291 uxth r1, r2 + 8001080: 2244 movs r2, #68 ; 0x44 + 8001082: 5299 strh r1, [r3, r2] + } +} + 8001084: 46c0 nop ; (mov r8, r8) + 8001086: 46bd mov sp, r7 + 8001088: b002 add sp, #8 + 800108a: bd80 pop {r7, pc} + 800108c: fffffbff .word 0xfffffbff + 8001090: ffffbfff .word 0xffffbfff + 8001094: ffffdfff .word 0xffffdfff + 8001098: ffffefff .word 0xffffefff + 800109c: fffff7ff .word 0xfffff7ff + 80010a0: fffffdff .word 0xfffffdff + 80010a4: fffffeff .word 0xfffffeff + +080010a8 : + * @param hpcd PCD handle + * @param address new device address + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_SetAddress(PCD_HandleTypeDef *hpcd, uint8_t address) +{ + 80010a8: b580 push {r7, lr} + 80010aa: b082 sub sp, #8 + 80010ac: af00 add r7, sp, #0 + 80010ae: 6078 str r0, [r7, #4] + 80010b0: 000a movs r2, r1 + 80010b2: 1cfb adds r3, r7, #3 + 80010b4: 701a strb r2, [r3, #0] + __HAL_LOCK(hpcd); + 80010b6: 687a ldr r2, [r7, #4] + 80010b8: 238a movs r3, #138 ; 0x8a + 80010ba: 009b lsls r3, r3, #2 + 80010bc: 5cd3 ldrb r3, [r2, r3] + 80010be: 2b01 cmp r3, #1 + 80010c0: d101 bne.n 80010c6 + 80010c2: 2302 movs r3, #2 + 80010c4: e017 b.n 80010f6 + 80010c6: 687a ldr r2, [r7, #4] + 80010c8: 238a movs r3, #138 ; 0x8a + 80010ca: 009b lsls r3, r3, #2 + 80010cc: 2101 movs r1, #1 + 80010ce: 54d1 strb r1, [r2, r3] + hpcd->USB_Address = address; + 80010d0: 687b ldr r3, [r7, #4] + 80010d2: 1cfa adds r2, r7, #3 + 80010d4: 2124 movs r1, #36 ; 0x24 + 80010d6: 7812 ldrb r2, [r2, #0] + 80010d8: 545a strb r2, [r3, r1] + (void)USB_SetDevAddress(hpcd->Instance, address); + 80010da: 687b ldr r3, [r7, #4] + 80010dc: 681a ldr r2, [r3, #0] + 80010de: 1cfb adds r3, r7, #3 + 80010e0: 781b ldrb r3, [r3, #0] + 80010e2: 0019 movs r1, r3 + 80010e4: 0010 movs r0, r2 + 80010e6: f002 fbc9 bl 800387c + __HAL_UNLOCK(hpcd); + 80010ea: 687a ldr r2, [r7, #4] + 80010ec: 238a movs r3, #138 ; 0x8a + 80010ee: 009b lsls r3, r3, #2 + 80010f0: 2100 movs r1, #0 + 80010f2: 54d1 strb r1, [r2, r3] + return HAL_OK; + 80010f4: 2300 movs r3, #0 +} + 80010f6: 0018 movs r0, r3 + 80010f8: 46bd mov sp, r7 + 80010fa: b002 add sp, #8 + 80010fc: bd80 pop {r7, pc} + +080010fe : + * @param ep_mps endpoint max packet size + * @param ep_type endpoint type + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_EP_Open(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint16_t ep_mps, uint8_t ep_type) +{ + 80010fe: b590 push {r4, r7, lr} + 8001100: b085 sub sp, #20 + 8001102: af00 add r7, sp, #0 + 8001104: 6078 str r0, [r7, #4] + 8001106: 000c movs r4, r1 + 8001108: 0010 movs r0, r2 + 800110a: 0019 movs r1, r3 + 800110c: 1cfb adds r3, r7, #3 + 800110e: 1c22 adds r2, r4, #0 + 8001110: 701a strb r2, [r3, #0] + 8001112: 003b movs r3, r7 + 8001114: 1c02 adds r2, r0, #0 + 8001116: 801a strh r2, [r3, #0] + 8001118: 1cbb adds r3, r7, #2 + 800111a: 1c0a adds r2, r1, #0 + 800111c: 701a strb r2, [r3, #0] + HAL_StatusTypeDef ret = HAL_OK; + 800111e: 230b movs r3, #11 + 8001120: 18fb adds r3, r7, r3 + 8001122: 2200 movs r2, #0 + 8001124: 701a strb r2, [r3, #0] + PCD_EPTypeDef *ep; + + if ((ep_addr & 0x80U) == 0x80U) + 8001126: 1cfb adds r3, r7, #3 + 8001128: 781b ldrb r3, [r3, #0] + 800112a: b25b sxtb r3, r3 + 800112c: 2b00 cmp r3, #0 + 800112e: da0c bge.n 800114a + { + ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK]; + 8001130: 1cfb adds r3, r7, #3 + 8001132: 781b ldrb r3, [r3, #0] + 8001134: 2207 movs r2, #7 + 8001136: 4013 ands r3, r2 + 8001138: 015b lsls r3, r3, #5 + 800113a: 3328 adds r3, #40 ; 0x28 + 800113c: 687a ldr r2, [r7, #4] + 800113e: 18d3 adds r3, r2, r3 + 8001140: 60fb str r3, [r7, #12] + ep->is_in = 1U; + 8001142: 68fb ldr r3, [r7, #12] + 8001144: 2201 movs r2, #1 + 8001146: 705a strb r2, [r3, #1] + 8001148: e00c b.n 8001164 + } + else + { + ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK]; + 800114a: 1cfb adds r3, r7, #3 + 800114c: 781b ldrb r3, [r3, #0] + 800114e: 2207 movs r2, #7 + 8001150: 4013 ands r3, r2 + 8001152: 015b lsls r3, r3, #5 + 8001154: 3329 adds r3, #41 ; 0x29 + 8001156: 33ff adds r3, #255 ; 0xff + 8001158: 687a ldr r2, [r7, #4] + 800115a: 18d3 adds r3, r2, r3 + 800115c: 60fb str r3, [r7, #12] + ep->is_in = 0U; + 800115e: 68fb ldr r3, [r7, #12] + 8001160: 2200 movs r2, #0 + 8001162: 705a strb r2, [r3, #1] + } + + ep->num = ep_addr & EP_ADDR_MSK; + 8001164: 1cfb adds r3, r7, #3 + 8001166: 781b ldrb r3, [r3, #0] + 8001168: 2207 movs r2, #7 + 800116a: 4013 ands r3, r2 + 800116c: b2da uxtb r2, r3 + 800116e: 68fb ldr r3, [r7, #12] + 8001170: 701a strb r2, [r3, #0] + ep->maxpacket = ep_mps; + 8001172: 003b movs r3, r7 + 8001174: 881a ldrh r2, [r3, #0] + 8001176: 68fb ldr r3, [r7, #12] + 8001178: 611a str r2, [r3, #16] + ep->type = ep_type; + 800117a: 68fb ldr r3, [r7, #12] + 800117c: 1cba adds r2, r7, #2 + 800117e: 7812 ldrb r2, [r2, #0] + 8001180: 70da strb r2, [r3, #3] + + if (ep->is_in != 0U) + 8001182: 68fb ldr r3, [r7, #12] + 8001184: 785b ldrb r3, [r3, #1] + 8001186: 2b00 cmp r3, #0 + 8001188: d004 beq.n 8001194 + { + /* Assign a Tx FIFO */ + ep->tx_fifo_num = ep->num; + 800118a: 68fb ldr r3, [r7, #12] + 800118c: 781b ldrb r3, [r3, #0] + 800118e: b29a uxth r2, r3 + 8001190: 68fb ldr r3, [r7, #12] + 8001192: 81da strh r2, [r3, #14] + } + /* Set initial data PID. */ + if (ep_type == EP_TYPE_BULK) + 8001194: 1cbb adds r3, r7, #2 + 8001196: 781b ldrb r3, [r3, #0] + 8001198: 2b02 cmp r3, #2 + 800119a: d102 bne.n 80011a2 + { + ep->data_pid_start = 0U; + 800119c: 68fb ldr r3, [r7, #12] + 800119e: 2200 movs r2, #0 + 80011a0: 711a strb r2, [r3, #4] + } + + __HAL_LOCK(hpcd); + 80011a2: 687a ldr r2, [r7, #4] + 80011a4: 238a movs r3, #138 ; 0x8a + 80011a6: 009b lsls r3, r3, #2 + 80011a8: 5cd3 ldrb r3, [r2, r3] + 80011aa: 2b01 cmp r3, #1 + 80011ac: d101 bne.n 80011b2 + 80011ae: 2302 movs r3, #2 + 80011b0: e013 b.n 80011da + 80011b2: 687a ldr r2, [r7, #4] + 80011b4: 238a movs r3, #138 ; 0x8a + 80011b6: 009b lsls r3, r3, #2 + 80011b8: 2101 movs r1, #1 + 80011ba: 54d1 strb r1, [r2, r3] + (void)USB_ActivateEndpoint(hpcd->Instance, ep); + 80011bc: 687b ldr r3, [r7, #4] + 80011be: 681b ldr r3, [r3, #0] + 80011c0: 68fa ldr r2, [r7, #12] + 80011c2: 0011 movs r1, r2 + 80011c4: 0018 movs r0, r3 + 80011c6: f001 fb45 bl 8002854 + __HAL_UNLOCK(hpcd); + 80011ca: 687a ldr r2, [r7, #4] + 80011cc: 238a movs r3, #138 ; 0x8a + 80011ce: 009b lsls r3, r3, #2 + 80011d0: 2100 movs r1, #0 + 80011d2: 54d1 strb r1, [r2, r3] + + return ret; + 80011d4: 230b movs r3, #11 + 80011d6: 18fb adds r3, r7, r3 + 80011d8: 781b ldrb r3, [r3, #0] +} + 80011da: 0018 movs r0, r3 + 80011dc: 46bd mov sp, r7 + 80011de: b005 add sp, #20 + 80011e0: bd90 pop {r4, r7, pc} + +080011e2 : + * @param hpcd PCD handle + * @param ep_addr endpoint address + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_EP_Close(PCD_HandleTypeDef *hpcd, uint8_t ep_addr) +{ + 80011e2: b580 push {r7, lr} + 80011e4: b084 sub sp, #16 + 80011e6: af00 add r7, sp, #0 + 80011e8: 6078 str r0, [r7, #4] + 80011ea: 000a movs r2, r1 + 80011ec: 1cfb adds r3, r7, #3 + 80011ee: 701a strb r2, [r3, #0] + PCD_EPTypeDef *ep; + + if ((ep_addr & 0x80U) == 0x80U) + 80011f0: 1cfb adds r3, r7, #3 + 80011f2: 781b ldrb r3, [r3, #0] + 80011f4: b25b sxtb r3, r3 + 80011f6: 2b00 cmp r3, #0 + 80011f8: da0c bge.n 8001214 + { + ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK]; + 80011fa: 1cfb adds r3, r7, #3 + 80011fc: 781b ldrb r3, [r3, #0] + 80011fe: 2207 movs r2, #7 + 8001200: 4013 ands r3, r2 + 8001202: 015b lsls r3, r3, #5 + 8001204: 3328 adds r3, #40 ; 0x28 + 8001206: 687a ldr r2, [r7, #4] + 8001208: 18d3 adds r3, r2, r3 + 800120a: 60fb str r3, [r7, #12] + ep->is_in = 1U; + 800120c: 68fb ldr r3, [r7, #12] + 800120e: 2201 movs r2, #1 + 8001210: 705a strb r2, [r3, #1] + 8001212: e00c b.n 800122e + } + else + { + ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK]; + 8001214: 1cfb adds r3, r7, #3 + 8001216: 781b ldrb r3, [r3, #0] + 8001218: 2207 movs r2, #7 + 800121a: 4013 ands r3, r2 + 800121c: 015b lsls r3, r3, #5 + 800121e: 3329 adds r3, #41 ; 0x29 + 8001220: 33ff adds r3, #255 ; 0xff + 8001222: 687a ldr r2, [r7, #4] + 8001224: 18d3 adds r3, r2, r3 + 8001226: 60fb str r3, [r7, #12] + ep->is_in = 0U; + 8001228: 68fb ldr r3, [r7, #12] + 800122a: 2200 movs r2, #0 + 800122c: 705a strb r2, [r3, #1] + } + ep->num = ep_addr & EP_ADDR_MSK; + 800122e: 1cfb adds r3, r7, #3 + 8001230: 781b ldrb r3, [r3, #0] + 8001232: 2207 movs r2, #7 + 8001234: 4013 ands r3, r2 + 8001236: b2da uxtb r2, r3 + 8001238: 68fb ldr r3, [r7, #12] + 800123a: 701a strb r2, [r3, #0] + + __HAL_LOCK(hpcd); + 800123c: 687a ldr r2, [r7, #4] + 800123e: 238a movs r3, #138 ; 0x8a + 8001240: 009b lsls r3, r3, #2 + 8001242: 5cd3 ldrb r3, [r2, r3] + 8001244: 2b01 cmp r3, #1 + 8001246: d101 bne.n 800124c + 8001248: 2302 movs r3, #2 + 800124a: e011 b.n 8001270 + 800124c: 687a ldr r2, [r7, #4] + 800124e: 238a movs r3, #138 ; 0x8a + 8001250: 009b lsls r3, r3, #2 + 8001252: 2101 movs r1, #1 + 8001254: 54d1 strb r1, [r2, r3] + (void)USB_DeactivateEndpoint(hpcd->Instance, ep); + 8001256: 687b ldr r3, [r7, #4] + 8001258: 681b ldr r3, [r3, #0] + 800125a: 68fa ldr r2, [r7, #12] + 800125c: 0011 movs r1, r2 + 800125e: 0018 movs r0, r3 + 8001260: f001 fdf0 bl 8002e44 + __HAL_UNLOCK(hpcd); + 8001264: 687a ldr r2, [r7, #4] + 8001266: 238a movs r3, #138 ; 0x8a + 8001268: 009b lsls r3, r3, #2 + 800126a: 2100 movs r1, #0 + 800126c: 54d1 strb r1, [r2, r3] + return HAL_OK; + 800126e: 2300 movs r3, #0 +} + 8001270: 0018 movs r0, r3 + 8001272: 46bd mov sp, r7 + 8001274: b004 add sp, #16 + 8001276: bd80 pop {r7, pc} + +08001278 : + * @param pBuf pointer to the reception buffer + * @param len amount of data to be received + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_EP_Receive(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len) +{ + 8001278: b580 push {r7, lr} + 800127a: b086 sub sp, #24 + 800127c: af00 add r7, sp, #0 + 800127e: 60f8 str r0, [r7, #12] + 8001280: 607a str r2, [r7, #4] + 8001282: 603b str r3, [r7, #0] + 8001284: 200b movs r0, #11 + 8001286: 183b adds r3, r7, r0 + 8001288: 1c0a adds r2, r1, #0 + 800128a: 701a strb r2, [r3, #0] + PCD_EPTypeDef *ep; + + ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK]; + 800128c: 0001 movs r1, r0 + 800128e: 187b adds r3, r7, r1 + 8001290: 781b ldrb r3, [r3, #0] + 8001292: 2207 movs r2, #7 + 8001294: 4013 ands r3, r2 + 8001296: 015b lsls r3, r3, #5 + 8001298: 3329 adds r3, #41 ; 0x29 + 800129a: 33ff adds r3, #255 ; 0xff + 800129c: 68fa ldr r2, [r7, #12] + 800129e: 18d3 adds r3, r2, r3 + 80012a0: 617b str r3, [r7, #20] + + /*setup and start the Xfer */ + ep->xfer_buff = pBuf; + 80012a2: 697b ldr r3, [r7, #20] + 80012a4: 687a ldr r2, [r7, #4] + 80012a6: 615a str r2, [r3, #20] + ep->xfer_len = len; + 80012a8: 697b ldr r3, [r7, #20] + 80012aa: 683a ldr r2, [r7, #0] + 80012ac: 619a str r2, [r3, #24] + ep->xfer_count = 0U; + 80012ae: 697b ldr r3, [r7, #20] + 80012b0: 2200 movs r2, #0 + 80012b2: 61da str r2, [r3, #28] + ep->is_in = 0U; + 80012b4: 697b ldr r3, [r7, #20] + 80012b6: 2200 movs r2, #0 + 80012b8: 705a strb r2, [r3, #1] + ep->num = ep_addr & EP_ADDR_MSK; + 80012ba: 187b adds r3, r7, r1 + 80012bc: 781b ldrb r3, [r3, #0] + 80012be: 2207 movs r2, #7 + 80012c0: 4013 ands r3, r2 + 80012c2: b2da uxtb r2, r3 + 80012c4: 697b ldr r3, [r7, #20] + 80012c6: 701a strb r2, [r3, #0] + + if ((ep_addr & EP_ADDR_MSK) == 0U) + 80012c8: 187b adds r3, r7, r1 + 80012ca: 781b ldrb r3, [r3, #0] + 80012cc: 2207 movs r2, #7 + 80012ce: 4013 ands r3, r2 + 80012d0: d107 bne.n 80012e2 + { + (void)USB_EP0StartXfer(hpcd->Instance, ep); + 80012d2: 68fb ldr r3, [r7, #12] + 80012d4: 681b ldr r3, [r3, #0] + 80012d6: 697a ldr r2, [r7, #20] + 80012d8: 0011 movs r1, r2 + 80012da: 0018 movs r0, r3 + 80012dc: f001 ff28 bl 8003130 + 80012e0: e006 b.n 80012f0 + } + else + { + (void)USB_EPStartXfer(hpcd->Instance, ep); + 80012e2: 68fb ldr r3, [r7, #12] + 80012e4: 681b ldr r3, [r3, #0] + 80012e6: 697a ldr r2, [r7, #20] + 80012e8: 0011 movs r1, r2 + 80012ea: 0018 movs r0, r3 + 80012ec: f001 ff20 bl 8003130 + } + + return HAL_OK; + 80012f0: 2300 movs r3, #0 +} + 80012f2: 0018 movs r0, r3 + 80012f4: 46bd mov sp, r7 + 80012f6: b006 add sp, #24 + 80012f8: bd80 pop {r7, pc} + +080012fa : + * @param hpcd PCD handle + * @param ep_addr endpoint address + * @retval Data Size + */ +uint32_t HAL_PCD_EP_GetRxCount(PCD_HandleTypeDef *hpcd, uint8_t ep_addr) +{ + 80012fa: b580 push {r7, lr} + 80012fc: b082 sub sp, #8 + 80012fe: af00 add r7, sp, #0 + 8001300: 6078 str r0, [r7, #4] + 8001302: 000a movs r2, r1 + 8001304: 1cfb adds r3, r7, #3 + 8001306: 701a strb r2, [r3, #0] + return hpcd->OUT_ep[ep_addr & EP_ADDR_MSK].xfer_count; + 8001308: 1cfb adds r3, r7, #3 + 800130a: 781b ldrb r3, [r3, #0] + 800130c: 2207 movs r2, #7 + 800130e: 4013 ands r3, r2 + 8001310: 687a ldr r2, [r7, #4] + 8001312: 330a adds r3, #10 + 8001314: 015b lsls r3, r3, #5 + 8001316: 18d3 adds r3, r2, r3 + 8001318: 3304 adds r3, #4 + 800131a: 681b ldr r3, [r3, #0] +} + 800131c: 0018 movs r0, r3 + 800131e: 46bd mov sp, r7 + 8001320: b002 add sp, #8 + 8001322: bd80 pop {r7, pc} + +08001324 : + * @param pBuf pointer to the transmission buffer + * @param len amount of data to be sent + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_EP_Transmit(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len) +{ + 8001324: b580 push {r7, lr} + 8001326: b086 sub sp, #24 + 8001328: af00 add r7, sp, #0 + 800132a: 60f8 str r0, [r7, #12] + 800132c: 607a str r2, [r7, #4] + 800132e: 603b str r3, [r7, #0] + 8001330: 200b movs r0, #11 + 8001332: 183b adds r3, r7, r0 + 8001334: 1c0a adds r2, r1, #0 + 8001336: 701a strb r2, [r3, #0] + PCD_EPTypeDef *ep; + + ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK]; + 8001338: 0001 movs r1, r0 + 800133a: 187b adds r3, r7, r1 + 800133c: 781b ldrb r3, [r3, #0] + 800133e: 2207 movs r2, #7 + 8001340: 4013 ands r3, r2 + 8001342: 015b lsls r3, r3, #5 + 8001344: 3328 adds r3, #40 ; 0x28 + 8001346: 68fa ldr r2, [r7, #12] + 8001348: 18d3 adds r3, r2, r3 + 800134a: 617b str r3, [r7, #20] + + /*setup and start the Xfer */ + ep->xfer_buff = pBuf; + 800134c: 697b ldr r3, [r7, #20] + 800134e: 687a ldr r2, [r7, #4] + 8001350: 615a str r2, [r3, #20] + ep->xfer_len = len; + 8001352: 697b ldr r3, [r7, #20] + 8001354: 683a ldr r2, [r7, #0] + 8001356: 619a str r2, [r3, #24] + ep->xfer_count = 0U; + 8001358: 697b ldr r3, [r7, #20] + 800135a: 2200 movs r2, #0 + 800135c: 61da str r2, [r3, #28] + ep->is_in = 1U; + 800135e: 697b ldr r3, [r7, #20] + 8001360: 2201 movs r2, #1 + 8001362: 705a strb r2, [r3, #1] + ep->num = ep_addr & EP_ADDR_MSK; + 8001364: 187b adds r3, r7, r1 + 8001366: 781b ldrb r3, [r3, #0] + 8001368: 2207 movs r2, #7 + 800136a: 4013 ands r3, r2 + 800136c: b2da uxtb r2, r3 + 800136e: 697b ldr r3, [r7, #20] + 8001370: 701a strb r2, [r3, #0] + + if ((ep_addr & EP_ADDR_MSK) == 0U) + 8001372: 187b adds r3, r7, r1 + 8001374: 781b ldrb r3, [r3, #0] + 8001376: 2207 movs r2, #7 + 8001378: 4013 ands r3, r2 + 800137a: d107 bne.n 800138c + { + (void)USB_EP0StartXfer(hpcd->Instance, ep); + 800137c: 68fb ldr r3, [r7, #12] + 800137e: 681b ldr r3, [r3, #0] + 8001380: 697a ldr r2, [r7, #20] + 8001382: 0011 movs r1, r2 + 8001384: 0018 movs r0, r3 + 8001386: f001 fed3 bl 8003130 + 800138a: e006 b.n 800139a + } + else + { + (void)USB_EPStartXfer(hpcd->Instance, ep); + 800138c: 68fb ldr r3, [r7, #12] + 800138e: 681b ldr r3, [r3, #0] + 8001390: 697a ldr r2, [r7, #20] + 8001392: 0011 movs r1, r2 + 8001394: 0018 movs r0, r3 + 8001396: f001 fecb bl 8003130 + } + + return HAL_OK; + 800139a: 2300 movs r3, #0 +} + 800139c: 0018 movs r0, r3 + 800139e: 46bd mov sp, r7 + 80013a0: b006 add sp, #24 + 80013a2: bd80 pop {r7, pc} + +080013a4 : + * @param hpcd PCD handle + * @param ep_addr endpoint address + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_EP_SetStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr) +{ + 80013a4: b580 push {r7, lr} + 80013a6: b084 sub sp, #16 + 80013a8: af00 add r7, sp, #0 + 80013aa: 6078 str r0, [r7, #4] + 80013ac: 000a movs r2, r1 + 80013ae: 1cfb adds r3, r7, #3 + 80013b0: 701a strb r2, [r3, #0] + PCD_EPTypeDef *ep; + + if (((uint32_t)ep_addr & EP_ADDR_MSK) > hpcd->Init.dev_endpoints) + 80013b2: 1cfb adds r3, r7, #3 + 80013b4: 781b ldrb r3, [r3, #0] + 80013b6: 2207 movs r2, #7 + 80013b8: 401a ands r2, r3 + 80013ba: 687b ldr r3, [r7, #4] + 80013bc: 685b ldr r3, [r3, #4] + 80013be: 429a cmp r2, r3 + 80013c0: d901 bls.n 80013c6 + { + return HAL_ERROR; + 80013c2: 2301 movs r3, #1 + 80013c4: e050 b.n 8001468 + } + + if ((0x80U & ep_addr) == 0x80U) + 80013c6: 1cfb adds r3, r7, #3 + 80013c8: 781b ldrb r3, [r3, #0] + 80013ca: b25b sxtb r3, r3 + 80013cc: 2b00 cmp r3, #0 + 80013ce: da0c bge.n 80013ea + { + ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK]; + 80013d0: 1cfb adds r3, r7, #3 + 80013d2: 781b ldrb r3, [r3, #0] + 80013d4: 2207 movs r2, #7 + 80013d6: 4013 ands r3, r2 + 80013d8: 015b lsls r3, r3, #5 + 80013da: 3328 adds r3, #40 ; 0x28 + 80013dc: 687a ldr r2, [r7, #4] + 80013de: 18d3 adds r3, r2, r3 + 80013e0: 60fb str r3, [r7, #12] + ep->is_in = 1U; + 80013e2: 68fb ldr r3, [r7, #12] + 80013e4: 2201 movs r2, #1 + 80013e6: 705a strb r2, [r3, #1] + 80013e8: e00a b.n 8001400 + } + else + { + ep = &hpcd->OUT_ep[ep_addr]; + 80013ea: 1cfb adds r3, r7, #3 + 80013ec: 781b ldrb r3, [r3, #0] + 80013ee: 015b lsls r3, r3, #5 + 80013f0: 3329 adds r3, #41 ; 0x29 + 80013f2: 33ff adds r3, #255 ; 0xff + 80013f4: 687a ldr r2, [r7, #4] + 80013f6: 18d3 adds r3, r2, r3 + 80013f8: 60fb str r3, [r7, #12] + ep->is_in = 0U; + 80013fa: 68fb ldr r3, [r7, #12] + 80013fc: 2200 movs r2, #0 + 80013fe: 705a strb r2, [r3, #1] + } + + ep->is_stall = 1U; + 8001400: 68fb ldr r3, [r7, #12] + 8001402: 2201 movs r2, #1 + 8001404: 709a strb r2, [r3, #2] + ep->num = ep_addr & EP_ADDR_MSK; + 8001406: 1cfb adds r3, r7, #3 + 8001408: 781b ldrb r3, [r3, #0] + 800140a: 2207 movs r2, #7 + 800140c: 4013 ands r3, r2 + 800140e: b2da uxtb r2, r3 + 8001410: 68fb ldr r3, [r7, #12] + 8001412: 701a strb r2, [r3, #0] + + __HAL_LOCK(hpcd); + 8001414: 687a ldr r2, [r7, #4] + 8001416: 238a movs r3, #138 ; 0x8a + 8001418: 009b lsls r3, r3, #2 + 800141a: 5cd3 ldrb r3, [r2, r3] + 800141c: 2b01 cmp r3, #1 + 800141e: d101 bne.n 8001424 + 8001420: 2302 movs r3, #2 + 8001422: e021 b.n 8001468 + 8001424: 687a ldr r2, [r7, #4] + 8001426: 238a movs r3, #138 ; 0x8a + 8001428: 009b lsls r3, r3, #2 + 800142a: 2101 movs r1, #1 + 800142c: 54d1 strb r1, [r2, r3] + + (void)USB_EPSetStall(hpcd->Instance, ep); + 800142e: 687b ldr r3, [r7, #4] + 8001430: 681b ldr r3, [r3, #0] + 8001432: 68fa ldr r2, [r7, #12] + 8001434: 0011 movs r1, r2 + 8001436: 0018 movs r0, r3 + 8001438: f002 f94c bl 80036d4 + if ((ep_addr & EP_ADDR_MSK) == 0U) + 800143c: 1cfb adds r3, r7, #3 + 800143e: 781b ldrb r3, [r3, #0] + 8001440: 2207 movs r2, #7 + 8001442: 4013 ands r3, r2 + 8001444: d10a bne.n 800145c + { + (void)USB_EP0_OutStart(hpcd->Instance, (uint8_t *)hpcd->Setup); + 8001446: 687b ldr r3, [r7, #4] + 8001448: 681a ldr r2, [r3, #0] + 800144a: 687b ldr r3, [r7, #4] + 800144c: 218c movs r1, #140 ; 0x8c + 800144e: 0089 lsls r1, r1, #2 + 8001450: 468c mov ip, r1 + 8001452: 4463 add r3, ip + 8001454: 0019 movs r1, r3 + 8001456: 0010 movs r0, r2 + 8001458: f002 fa48 bl 80038ec + } + __HAL_UNLOCK(hpcd); + 800145c: 687a ldr r2, [r7, #4] + 800145e: 238a movs r3, #138 ; 0x8a + 8001460: 009b lsls r3, r3, #2 + 8001462: 2100 movs r1, #0 + 8001464: 54d1 strb r1, [r2, r3] + + return HAL_OK; + 8001466: 2300 movs r3, #0 +} + 8001468: 0018 movs r0, r3 + 800146a: 46bd mov sp, r7 + 800146c: b004 add sp, #16 + 800146e: bd80 pop {r7, pc} + +08001470 : + * @param hpcd PCD handle + * @param ep_addr endpoint address + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_EP_ClrStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr) +{ + 8001470: b580 push {r7, lr} + 8001472: b084 sub sp, #16 + 8001474: af00 add r7, sp, #0 + 8001476: 6078 str r0, [r7, #4] + 8001478: 000a movs r2, r1 + 800147a: 1cfb adds r3, r7, #3 + 800147c: 701a strb r2, [r3, #0] + PCD_EPTypeDef *ep; + + if (((uint32_t)ep_addr & 0x0FU) > hpcd->Init.dev_endpoints) + 800147e: 1cfb adds r3, r7, #3 + 8001480: 781b ldrb r3, [r3, #0] + 8001482: 220f movs r2, #15 + 8001484: 401a ands r2, r3 + 8001486: 687b ldr r3, [r7, #4] + 8001488: 685b ldr r3, [r3, #4] + 800148a: 429a cmp r2, r3 + 800148c: d901 bls.n 8001492 + { + return HAL_ERROR; + 800148e: 2301 movs r3, #1 + 8001490: e042 b.n 8001518 + } + + if ((0x80U & ep_addr) == 0x80U) + 8001492: 1cfb adds r3, r7, #3 + 8001494: 781b ldrb r3, [r3, #0] + 8001496: b25b sxtb r3, r3 + 8001498: 2b00 cmp r3, #0 + 800149a: da0c bge.n 80014b6 + { + ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK]; + 800149c: 1cfb adds r3, r7, #3 + 800149e: 781b ldrb r3, [r3, #0] + 80014a0: 2207 movs r2, #7 + 80014a2: 4013 ands r3, r2 + 80014a4: 015b lsls r3, r3, #5 + 80014a6: 3328 adds r3, #40 ; 0x28 + 80014a8: 687a ldr r2, [r7, #4] + 80014aa: 18d3 adds r3, r2, r3 + 80014ac: 60fb str r3, [r7, #12] + ep->is_in = 1U; + 80014ae: 68fb ldr r3, [r7, #12] + 80014b0: 2201 movs r2, #1 + 80014b2: 705a strb r2, [r3, #1] + 80014b4: e00c b.n 80014d0 + } + else + { + ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK]; + 80014b6: 1cfb adds r3, r7, #3 + 80014b8: 781b ldrb r3, [r3, #0] + 80014ba: 2207 movs r2, #7 + 80014bc: 4013 ands r3, r2 + 80014be: 015b lsls r3, r3, #5 + 80014c0: 3329 adds r3, #41 ; 0x29 + 80014c2: 33ff adds r3, #255 ; 0xff + 80014c4: 687a ldr r2, [r7, #4] + 80014c6: 18d3 adds r3, r2, r3 + 80014c8: 60fb str r3, [r7, #12] + ep->is_in = 0U; + 80014ca: 68fb ldr r3, [r7, #12] + 80014cc: 2200 movs r2, #0 + 80014ce: 705a strb r2, [r3, #1] + } + + ep->is_stall = 0U; + 80014d0: 68fb ldr r3, [r7, #12] + 80014d2: 2200 movs r2, #0 + 80014d4: 709a strb r2, [r3, #2] + ep->num = ep_addr & EP_ADDR_MSK; + 80014d6: 1cfb adds r3, r7, #3 + 80014d8: 781b ldrb r3, [r3, #0] + 80014da: 2207 movs r2, #7 + 80014dc: 4013 ands r3, r2 + 80014de: b2da uxtb r2, r3 + 80014e0: 68fb ldr r3, [r7, #12] + 80014e2: 701a strb r2, [r3, #0] + + __HAL_LOCK(hpcd); + 80014e4: 687a ldr r2, [r7, #4] + 80014e6: 238a movs r3, #138 ; 0x8a + 80014e8: 009b lsls r3, r3, #2 + 80014ea: 5cd3 ldrb r3, [r2, r3] + 80014ec: 2b01 cmp r3, #1 + 80014ee: d101 bne.n 80014f4 + 80014f0: 2302 movs r3, #2 + 80014f2: e011 b.n 8001518 + 80014f4: 687a ldr r2, [r7, #4] + 80014f6: 238a movs r3, #138 ; 0x8a + 80014f8: 009b lsls r3, r3, #2 + 80014fa: 2101 movs r1, #1 + 80014fc: 54d1 strb r1, [r2, r3] + (void)USB_EPClearStall(hpcd->Instance, ep); + 80014fe: 687b ldr r3, [r7, #4] + 8001500: 681b ldr r3, [r3, #0] + 8001502: 68fa ldr r2, [r7, #12] + 8001504: 0011 movs r1, r2 + 8001506: 0018 movs r0, r3 + 8001508: f002 f926 bl 8003758 + __HAL_UNLOCK(hpcd); + 800150c: 687a ldr r2, [r7, #4] + 800150e: 238a movs r3, #138 ; 0x8a + 8001510: 009b lsls r3, r3, #2 + 8001512: 2100 movs r1, #0 + 8001514: 54d1 strb r1, [r2, r3] + + return HAL_OK; + 8001516: 2300 movs r3, #0 +} + 8001518: 0018 movs r0, r3 + 800151a: 46bd mov sp, r7 + 800151c: b004 add sp, #16 + 800151e: bd80 pop {r7, pc} + +08001520 : + * @brief This function handles PCD Endpoint interrupt request. + * @param hpcd PCD handle + * @retval HAL status + */ +static HAL_StatusTypeDef PCD_EP_ISR_Handler(PCD_HandleTypeDef *hpcd) +{ + 8001520: b590 push {r4, r7, lr} + 8001522: b089 sub sp, #36 ; 0x24 + 8001524: af00 add r7, sp, #0 + 8001526: 6078 str r0, [r7, #4] + uint16_t wIstr; + uint16_t wEPVal; + uint8_t epindex; + + /* stay in loop while pending interrupts */ + while ((hpcd->Instance->ISTR & USB_ISTR_CTR) != 0U) + 8001528: e2b3 b.n 8001a92 + { + wIstr = hpcd->Instance->ISTR; + 800152a: 687b ldr r3, [r7, #4] + 800152c: 681a ldr r2, [r3, #0] + 800152e: 2016 movs r0, #22 + 8001530: 183b adds r3, r7, r0 + 8001532: 2144 movs r1, #68 ; 0x44 + 8001534: 5a52 ldrh r2, [r2, r1] + 8001536: 801a strh r2, [r3, #0] + /* extract highest priority endpoint number */ + epindex = (uint8_t)(wIstr & USB_ISTR_EP_ID); + 8001538: 183b adds r3, r7, r0 + 800153a: 881b ldrh r3, [r3, #0] + 800153c: b2da uxtb r2, r3 + 800153e: 2015 movs r0, #21 + 8001540: 183b adds r3, r7, r0 + 8001542: 210f movs r1, #15 + 8001544: 400a ands r2, r1 + 8001546: 701a strb r2, [r3, #0] + + if (epindex == 0U) + 8001548: 183b adds r3, r7, r0 + 800154a: 781b ldrb r3, [r3, #0] + 800154c: 2b00 cmp r3, #0 + 800154e: d000 beq.n 8001552 + 8001550: e141 b.n 80017d6 + { + /* Decode and service control endpoint interrupt */ + + /* DIR bit = origin of the interrupt */ + if ((wIstr & USB_ISTR_DIR) == 0U) + 8001552: 2316 movs r3, #22 + 8001554: 18fb adds r3, r7, r3 + 8001556: 881b ldrh r3, [r3, #0] + 8001558: 2210 movs r2, #16 + 800155a: 4013 ands r3, r2 + 800155c: d14e bne.n 80015fc + { + /* DIR = 0 */ + + /* DIR = 0 => IN int */ + /* DIR = 0 implies that (EP_CTR_TX = 1) always */ + PCD_CLEAR_TX_EP_CTR(hpcd->Instance, PCD_ENDP0); + 800155e: 687b ldr r3, [r7, #4] + 8001560: 681b ldr r3, [r3, #0] + 8001562: 881b ldrh r3, [r3, #0] + 8001564: b29b uxth r3, r3 + 8001566: 4aca ldr r2, [pc, #808] ; (8001890 ) + 8001568: 4013 ands r3, r2 + 800156a: b29c uxth r4, r3 + 800156c: 687b ldr r3, [r7, #4] + 800156e: 681b ldr r3, [r3, #0] + 8001570: 4ac8 ldr r2, [pc, #800] ; (8001894 ) + 8001572: 4322 orrs r2, r4 + 8001574: b292 uxth r2, r2 + 8001576: 801a strh r2, [r3, #0] + ep = &hpcd->IN_ep[0]; + 8001578: 687b ldr r3, [r7, #4] + 800157a: 3328 adds r3, #40 ; 0x28 + 800157c: 60fb str r3, [r7, #12] + + ep->xfer_count = PCD_GET_EP_TX_CNT(hpcd->Instance, ep->num); + 800157e: 687b ldr r3, [r7, #4] + 8001580: 681b ldr r3, [r3, #0] + 8001582: 2250 movs r2, #80 ; 0x50 + 8001584: 5a9b ldrh r3, [r3, r2] + 8001586: b29b uxth r3, r3 + 8001588: 001a movs r2, r3 + 800158a: 68fb ldr r3, [r7, #12] + 800158c: 781b ldrb r3, [r3, #0] + 800158e: 00db lsls r3, r3, #3 + 8001590: 18d2 adds r2, r2, r3 + 8001592: 687b ldr r3, [r7, #4] + 8001594: 681b ldr r3, [r3, #0] + 8001596: 18d3 adds r3, r2, r3 + 8001598: 4abf ldr r2, [pc, #764] ; (8001898 ) + 800159a: 4694 mov ip, r2 + 800159c: 4463 add r3, ip + 800159e: 881b ldrh r3, [r3, #0] + 80015a0: 059b lsls r3, r3, #22 + 80015a2: 0d9a lsrs r2, r3, #22 + 80015a4: 68fb ldr r3, [r7, #12] + 80015a6: 61da str r2, [r3, #28] + ep->xfer_buff += ep->xfer_count; + 80015a8: 68fb ldr r3, [r7, #12] + 80015aa: 695a ldr r2, [r3, #20] + 80015ac: 68fb ldr r3, [r7, #12] + 80015ae: 69db ldr r3, [r3, #28] + 80015b0: 18d2 adds r2, r2, r3 + 80015b2: 68fb ldr r3, [r7, #12] + 80015b4: 615a str r2, [r3, #20] + + /* TX COMPLETE */ +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) + hpcd->DataInStageCallback(hpcd, 0U); +#else + HAL_PCD_DataInStageCallback(hpcd, 0U); + 80015b6: 687b ldr r3, [r7, #4] + 80015b8: 2100 movs r1, #0 + 80015ba: 0018 movs r0, r3 + 80015bc: f00c ff54 bl 800e468 +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ + + if ((hpcd->USB_Address > 0U) && (ep->xfer_len == 0U)) + 80015c0: 687b ldr r3, [r7, #4] + 80015c2: 2224 movs r2, #36 ; 0x24 + 80015c4: 5c9b ldrb r3, [r3, r2] + 80015c6: b2db uxtb r3, r3 + 80015c8: 2b00 cmp r3, #0 + 80015ca: d100 bne.n 80015ce + 80015cc: e261 b.n 8001a92 + 80015ce: 68fb ldr r3, [r7, #12] + 80015d0: 699b ldr r3, [r3, #24] + 80015d2: 2b00 cmp r3, #0 + 80015d4: d000 beq.n 80015d8 + 80015d6: e25c b.n 8001a92 + { + hpcd->Instance->DADDR = ((uint16_t)hpcd->USB_Address | USB_DADDR_EF); + 80015d8: 687b ldr r3, [r7, #4] + 80015da: 2224 movs r2, #36 ; 0x24 + 80015dc: 5c9b ldrb r3, [r3, r2] + 80015de: b2db uxtb r3, r3 + 80015e0: 2280 movs r2, #128 ; 0x80 + 80015e2: 4252 negs r2, r2 + 80015e4: 4313 orrs r3, r2 + 80015e6: b2da uxtb r2, r3 + 80015e8: 687b ldr r3, [r7, #4] + 80015ea: 681b ldr r3, [r3, #0] + 80015ec: b291 uxth r1, r2 + 80015ee: 224c movs r2, #76 ; 0x4c + 80015f0: 5299 strh r1, [r3, r2] + hpcd->USB_Address = 0U; + 80015f2: 687b ldr r3, [r7, #4] + 80015f4: 2224 movs r2, #36 ; 0x24 + 80015f6: 2100 movs r1, #0 + 80015f8: 5499 strb r1, [r3, r2] + 80015fa: e24a b.n 8001a92 + { + /* DIR = 1 */ + + /* DIR = 1 & CTR_RX => SETUP or OUT int */ + /* DIR = 1 & (CTR_TX | CTR_RX) => 2 int pending */ + ep = &hpcd->OUT_ep[0]; + 80015fc: 687b ldr r3, [r7, #4] + 80015fe: 3329 adds r3, #41 ; 0x29 + 8001600: 33ff adds r3, #255 ; 0xff + 8001602: 60fb str r3, [r7, #12] + wEPVal = PCD_GET_ENDPOINT(hpcd->Instance, PCD_ENDP0); + 8001604: 687b ldr r3, [r7, #4] + 8001606: 681a ldr r2, [r3, #0] + 8001608: 2112 movs r1, #18 + 800160a: 187b adds r3, r7, r1 + 800160c: 8812 ldrh r2, [r2, #0] + 800160e: 801a strh r2, [r3, #0] + + if ((wEPVal & USB_EP_SETUP) != 0U) + 8001610: 187b adds r3, r7, r1 + 8001612: 881a ldrh r2, [r3, #0] + 8001614: 2380 movs r3, #128 ; 0x80 + 8001616: 011b lsls r3, r3, #4 + 8001618: 4013 ands r3, r2 + 800161a: d033 beq.n 8001684 + { + /* Get SETUP Packet*/ + ep->xfer_count = PCD_GET_EP_RX_CNT(hpcd->Instance, ep->num); + 800161c: 687b ldr r3, [r7, #4] + 800161e: 681b ldr r3, [r3, #0] + 8001620: 2250 movs r2, #80 ; 0x50 + 8001622: 5a9b ldrh r3, [r3, r2] + 8001624: b29b uxth r3, r3 + 8001626: 001a movs r2, r3 + 8001628: 68fb ldr r3, [r7, #12] + 800162a: 781b ldrb r3, [r3, #0] + 800162c: 00db lsls r3, r3, #3 + 800162e: 18d2 adds r2, r2, r3 + 8001630: 687b ldr r3, [r7, #4] + 8001632: 681b ldr r3, [r3, #0] + 8001634: 18d3 adds r3, r2, r3 + 8001636: 4a99 ldr r2, [pc, #612] ; (800189c ) + 8001638: 4694 mov ip, r2 + 800163a: 4463 add r3, ip + 800163c: 881b ldrh r3, [r3, #0] + 800163e: 059b lsls r3, r3, #22 + 8001640: 0d9a lsrs r2, r3, #22 + 8001642: 68fb ldr r3, [r7, #12] + 8001644: 61da str r2, [r3, #28] + + USB_ReadPMA(hpcd->Instance, (uint8_t *)hpcd->Setup, + 8001646: 687b ldr r3, [r7, #4] + 8001648: 6818 ldr r0, [r3, #0] + 800164a: 687b ldr r3, [r7, #4] + 800164c: 228c movs r2, #140 ; 0x8c + 800164e: 0092 lsls r2, r2, #2 + 8001650: 1899 adds r1, r3, r2 + 8001652: 68fb ldr r3, [r7, #12] + 8001654: 88da ldrh r2, [r3, #6] + ep->pmaadress, (uint16_t)ep->xfer_count); + 8001656: 68fb ldr r3, [r7, #12] + 8001658: 69db ldr r3, [r3, #28] + USB_ReadPMA(hpcd->Instance, (uint8_t *)hpcd->Setup, + 800165a: b29b uxth r3, r3 + 800165c: f002 f993 bl 8003986 + + /* SETUP bit kept frozen while CTR_RX = 1*/ + PCD_CLEAR_RX_EP_CTR(hpcd->Instance, PCD_ENDP0); + 8001660: 687b ldr r3, [r7, #4] + 8001662: 681b ldr r3, [r3, #0] + 8001664: 881b ldrh r3, [r3, #0] + 8001666: b29b uxth r3, r3 + 8001668: 4a8d ldr r2, [pc, #564] ; (80018a0 ) + 800166a: 4013 ands r3, r2 + 800166c: b29c uxth r4, r3 + 800166e: 687b ldr r3, [r7, #4] + 8001670: 681b ldr r3, [r3, #0] + 8001672: 2280 movs r2, #128 ; 0x80 + 8001674: 4322 orrs r2, r4 + 8001676: b292 uxth r2, r2 + 8001678: 801a strh r2, [r3, #0] + + /* Process SETUP Packet*/ +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) + hpcd->SetupStageCallback(hpcd); +#else + HAL_PCD_SetupStageCallback(hpcd); + 800167a: 687b ldr r3, [r7, #4] + 800167c: 0018 movs r0, r3 + 800167e: f00c fec1 bl 800e404 + 8001682: e206 b.n 8001a92 +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ + } + + else if ((wEPVal & USB_EP_CTR_RX) != 0U) + 8001684: 2312 movs r3, #18 + 8001686: 18fb adds r3, r7, r3 + 8001688: 2200 movs r2, #0 + 800168a: 5e9b ldrsh r3, [r3, r2] + 800168c: 2b00 cmp r3, #0 + 800168e: db00 blt.n 8001692 + 8001690: e1ff b.n 8001a92 + { + PCD_CLEAR_RX_EP_CTR(hpcd->Instance, PCD_ENDP0); + 8001692: 687b ldr r3, [r7, #4] + 8001694: 681b ldr r3, [r3, #0] + 8001696: 881b ldrh r3, [r3, #0] + 8001698: b29b uxth r3, r3 + 800169a: 4a81 ldr r2, [pc, #516] ; (80018a0 ) + 800169c: 4013 ands r3, r2 + 800169e: b29c uxth r4, r3 + 80016a0: 687b ldr r3, [r7, #4] + 80016a2: 681b ldr r3, [r3, #0] + 80016a4: 2280 movs r2, #128 ; 0x80 + 80016a6: 4322 orrs r2, r4 + 80016a8: b292 uxth r2, r2 + 80016aa: 801a strh r2, [r3, #0] + + /* Get Control Data OUT Packet*/ + ep->xfer_count = PCD_GET_EP_RX_CNT(hpcd->Instance, ep->num); + 80016ac: 687b ldr r3, [r7, #4] + 80016ae: 681b ldr r3, [r3, #0] + 80016b0: 2250 movs r2, #80 ; 0x50 + 80016b2: 5a9b ldrh r3, [r3, r2] + 80016b4: b29b uxth r3, r3 + 80016b6: 001a movs r2, r3 + 80016b8: 68fb ldr r3, [r7, #12] + 80016ba: 781b ldrb r3, [r3, #0] + 80016bc: 00db lsls r3, r3, #3 + 80016be: 18d2 adds r2, r2, r3 + 80016c0: 687b ldr r3, [r7, #4] + 80016c2: 681b ldr r3, [r3, #0] + 80016c4: 18d3 adds r3, r2, r3 + 80016c6: 4a75 ldr r2, [pc, #468] ; (800189c ) + 80016c8: 4694 mov ip, r2 + 80016ca: 4463 add r3, ip + 80016cc: 881b ldrh r3, [r3, #0] + 80016ce: 059b lsls r3, r3, #22 + 80016d0: 0d9a lsrs r2, r3, #22 + 80016d2: 68fb ldr r3, [r7, #12] + 80016d4: 61da str r2, [r3, #28] + + if ((ep->xfer_count != 0U) && (ep->xfer_buff != 0U)) + 80016d6: 68fb ldr r3, [r7, #12] + 80016d8: 69db ldr r3, [r3, #28] + 80016da: 2b00 cmp r3, #0 + 80016dc: d01a beq.n 8001714 + 80016de: 68fb ldr r3, [r7, #12] + 80016e0: 695b ldr r3, [r3, #20] + 80016e2: 2b00 cmp r3, #0 + 80016e4: d016 beq.n 8001714 + { + USB_ReadPMA(hpcd->Instance, ep->xfer_buff, + 80016e6: 687b ldr r3, [r7, #4] + 80016e8: 6818 ldr r0, [r3, #0] + 80016ea: 68fb ldr r3, [r7, #12] + 80016ec: 6959 ldr r1, [r3, #20] + 80016ee: 68fb ldr r3, [r7, #12] + 80016f0: 88da ldrh r2, [r3, #6] + ep->pmaadress, (uint16_t)ep->xfer_count); + 80016f2: 68fb ldr r3, [r7, #12] + 80016f4: 69db ldr r3, [r3, #28] + USB_ReadPMA(hpcd->Instance, ep->xfer_buff, + 80016f6: b29b uxth r3, r3 + 80016f8: f002 f945 bl 8003986 + + ep->xfer_buff += ep->xfer_count; + 80016fc: 68fb ldr r3, [r7, #12] + 80016fe: 695a ldr r2, [r3, #20] + 8001700: 68fb ldr r3, [r7, #12] + 8001702: 69db ldr r3, [r3, #28] + 8001704: 18d2 adds r2, r2, r3 + 8001706: 68fb ldr r3, [r7, #12] + 8001708: 615a str r2, [r3, #20] + + /* Process Control Data OUT Packet*/ +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) + hpcd->DataOutStageCallback(hpcd, 0U); +#else + HAL_PCD_DataOutStageCallback(hpcd, 0U); + 800170a: 687b ldr r3, [r7, #4] + 800170c: 2100 movs r1, #0 + 800170e: 0018 movs r0, r3 + 8001710: f00c fe8d bl 800e42e +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ + } + + PCD_SET_EP_RX_CNT(hpcd->Instance, PCD_ENDP0, ep->maxpacket); + 8001714: 687b ldr r3, [r7, #4] + 8001716: 681b ldr r3, [r3, #0] + 8001718: 001c movs r4, r3 + 800171a: 687b ldr r3, [r7, #4] + 800171c: 681b ldr r3, [r3, #0] + 800171e: 2250 movs r2, #80 ; 0x50 + 8001720: 5a9b ldrh r3, [r3, r2] + 8001722: b29b uxth r3, r3 + 8001724: 18e4 adds r4, r4, r3 + 8001726: 4b5d ldr r3, [pc, #372] ; (800189c ) + 8001728: 18e3 adds r3, r4, r3 + 800172a: 60bb str r3, [r7, #8] + 800172c: 68fb ldr r3, [r7, #12] + 800172e: 691b ldr r3, [r3, #16] + 8001730: 2b00 cmp r3, #0 + 8001732: d10e bne.n 8001752 + 8001734: 68bb ldr r3, [r7, #8] + 8001736: 881b ldrh r3, [r3, #0] + 8001738: 4a5a ldr r2, [pc, #360] ; (80018a4 ) + 800173a: 4013 ands r3, r2 + 800173c: b29a uxth r2, r3 + 800173e: 68bb ldr r3, [r7, #8] + 8001740: 801a strh r2, [r3, #0] + 8001742: 68bb ldr r3, [r7, #8] + 8001744: 881b ldrh r3, [r3, #0] + 8001746: 4a53 ldr r2, [pc, #332] ; (8001894 ) + 8001748: 4313 orrs r3, r2 + 800174a: b29a uxth r2, r3 + 800174c: 68bb ldr r3, [r7, #8] + 800174e: 801a strh r2, [r3, #0] + 8001750: e02b b.n 80017aa + 8001752: 68fb ldr r3, [r7, #12] + 8001754: 691b ldr r3, [r3, #16] + 8001756: 2b3e cmp r3, #62 ; 0x3e + 8001758: d812 bhi.n 8001780 + 800175a: 68fb ldr r3, [r7, #12] + 800175c: 691b ldr r3, [r3, #16] + 800175e: 085b lsrs r3, r3, #1 + 8001760: 61bb str r3, [r7, #24] + 8001762: 68fb ldr r3, [r7, #12] + 8001764: 691b ldr r3, [r3, #16] + 8001766: 2201 movs r2, #1 + 8001768: 4013 ands r3, r2 + 800176a: d002 beq.n 8001772 + 800176c: 69bb ldr r3, [r7, #24] + 800176e: 3301 adds r3, #1 + 8001770: 61bb str r3, [r7, #24] + 8001772: 69bb ldr r3, [r7, #24] + 8001774: b29b uxth r3, r3 + 8001776: 029b lsls r3, r3, #10 + 8001778: b29a uxth r2, r3 + 800177a: 68bb ldr r3, [r7, #8] + 800177c: 801a strh r2, [r3, #0] + 800177e: e014 b.n 80017aa + 8001780: 68fb ldr r3, [r7, #12] + 8001782: 691b ldr r3, [r3, #16] + 8001784: 095b lsrs r3, r3, #5 + 8001786: 61bb str r3, [r7, #24] + 8001788: 68fb ldr r3, [r7, #12] + 800178a: 691b ldr r3, [r3, #16] + 800178c: 221f movs r2, #31 + 800178e: 4013 ands r3, r2 + 8001790: d102 bne.n 8001798 + 8001792: 69bb ldr r3, [r7, #24] + 8001794: 3b01 subs r3, #1 + 8001796: 61bb str r3, [r7, #24] + 8001798: 69bb ldr r3, [r7, #24] + 800179a: b29b uxth r3, r3 + 800179c: 029b lsls r3, r3, #10 + 800179e: b29b uxth r3, r3 + 80017a0: 4a3c ldr r2, [pc, #240] ; (8001894 ) + 80017a2: 4313 orrs r3, r2 + 80017a4: b29a uxth r2, r3 + 80017a6: 68bb ldr r3, [r7, #8] + 80017a8: 801a strh r2, [r3, #0] + PCD_SET_EP_RX_STATUS(hpcd->Instance, PCD_ENDP0, USB_EP_RX_VALID); + 80017aa: 687b ldr r3, [r7, #4] + 80017ac: 681b ldr r3, [r3, #0] + 80017ae: 881b ldrh r3, [r3, #0] + 80017b0: b29b uxth r3, r3 + 80017b2: 4a3d ldr r2, [pc, #244] ; (80018a8 ) + 80017b4: 4013 ands r3, r2 + 80017b6: b29c uxth r4, r3 + 80017b8: 2380 movs r3, #128 ; 0x80 + 80017ba: 015b lsls r3, r3, #5 + 80017bc: 4063 eors r3, r4 + 80017be: b29c uxth r4, r3 + 80017c0: 2380 movs r3, #128 ; 0x80 + 80017c2: 019b lsls r3, r3, #6 + 80017c4: 4063 eors r3, r4 + 80017c6: b29c uxth r4, r3 + 80017c8: 687b ldr r3, [r7, #4] + 80017ca: 681b ldr r3, [r3, #0] + 80017cc: 4a37 ldr r2, [pc, #220] ; (80018ac ) + 80017ce: 4322 orrs r2, r4 + 80017d0: b292 uxth r2, r2 + 80017d2: 801a strh r2, [r3, #0] + 80017d4: e15d b.n 8001a92 + else + { + /* Decode and service non control endpoints interrupt */ + + /* process related endpoint register */ + wEPVal = PCD_GET_ENDPOINT(hpcd->Instance, epindex); + 80017d6: 687b ldr r3, [r7, #4] + 80017d8: 681b ldr r3, [r3, #0] + 80017da: 001a movs r2, r3 + 80017dc: 2315 movs r3, #21 + 80017de: 18fb adds r3, r7, r3 + 80017e0: 781b ldrb r3, [r3, #0] + 80017e2: 009b lsls r3, r3, #2 + 80017e4: 18d2 adds r2, r2, r3 + 80017e6: 2112 movs r1, #18 + 80017e8: 187b adds r3, r7, r1 + 80017ea: 8812 ldrh r2, [r2, #0] + 80017ec: 801a strh r2, [r3, #0] + if ((wEPVal & USB_EP_CTR_RX) != 0U) + 80017ee: 187b adds r3, r7, r1 + 80017f0: 2200 movs r2, #0 + 80017f2: 5e9b ldrsh r3, [r3, r2] + 80017f4: 2b00 cmp r3, #0 + 80017f6: db00 blt.n 80017fa + 80017f8: e0f5 b.n 80019e6 + { + /* clear int flag */ + PCD_CLEAR_RX_EP_CTR(hpcd->Instance, epindex); + 80017fa: 687b ldr r3, [r7, #4] + 80017fc: 681b ldr r3, [r3, #0] + 80017fe: 001a movs r2, r3 + 8001800: 2115 movs r1, #21 + 8001802: 187b adds r3, r7, r1 + 8001804: 781b ldrb r3, [r3, #0] + 8001806: 009b lsls r3, r3, #2 + 8001808: 18d3 adds r3, r2, r3 + 800180a: 881b ldrh r3, [r3, #0] + 800180c: b29b uxth r3, r3 + 800180e: 4a24 ldr r2, [pc, #144] ; (80018a0 ) + 8001810: 4013 ands r3, r2 + 8001812: b29c uxth r4, r3 + 8001814: 687b ldr r3, [r7, #4] + 8001816: 681b ldr r3, [r3, #0] + 8001818: 001a movs r2, r3 + 800181a: 187b adds r3, r7, r1 + 800181c: 781b ldrb r3, [r3, #0] + 800181e: 009b lsls r3, r3, #2 + 8001820: 18d3 adds r3, r2, r3 + 8001822: 2280 movs r2, #128 ; 0x80 + 8001824: 4322 orrs r2, r4 + 8001826: b292 uxth r2, r2 + 8001828: 801a strh r2, [r3, #0] + ep = &hpcd->OUT_ep[epindex]; + 800182a: 187b adds r3, r7, r1 + 800182c: 781b ldrb r3, [r3, #0] + 800182e: 015b lsls r3, r3, #5 + 8001830: 3329 adds r3, #41 ; 0x29 + 8001832: 33ff adds r3, #255 ; 0xff + 8001834: 687a ldr r2, [r7, #4] + 8001836: 18d3 adds r3, r2, r3 + 8001838: 60fb str r3, [r7, #12] + + /* OUT double Buffering*/ + if (ep->doublebuffer == 0U) + 800183a: 68fb ldr r3, [r7, #12] + 800183c: 7b1b ldrb r3, [r3, #12] + 800183e: 2b00 cmp r3, #0 + 8001840: d136 bne.n 80018b0 + { + count = (uint16_t)PCD_GET_EP_RX_CNT(hpcd->Instance, ep->num); + 8001842: 687b ldr r3, [r7, #4] + 8001844: 681b ldr r3, [r3, #0] + 8001846: 2250 movs r2, #80 ; 0x50 + 8001848: 5a9b ldrh r3, [r3, r2] + 800184a: b29b uxth r3, r3 + 800184c: 001a movs r2, r3 + 800184e: 68fb ldr r3, [r7, #12] + 8001850: 781b ldrb r3, [r3, #0] + 8001852: 00db lsls r3, r3, #3 + 8001854: 18d2 adds r2, r2, r3 + 8001856: 687b ldr r3, [r7, #4] + 8001858: 681b ldr r3, [r3, #0] + 800185a: 18d3 adds r3, r2, r3 + 800185c: 4a0f ldr r2, [pc, #60] ; (800189c ) + 800185e: 4694 mov ip, r2 + 8001860: 4463 add r3, ip + 8001862: 881a ldrh r2, [r3, #0] + 8001864: 211e movs r1, #30 + 8001866: 187b adds r3, r7, r1 + 8001868: 0592 lsls r2, r2, #22 + 800186a: 0d92 lsrs r2, r2, #22 + 800186c: 801a strh r2, [r3, #0] + if (count != 0U) + 800186e: 187b adds r3, r7, r1 + 8001870: 881b ldrh r3, [r3, #0] + 8001872: 2b00 cmp r3, #0 + 8001874: d100 bne.n 8001878 + 8001876: e08b b.n 8001990 + { + USB_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaadress, count); + 8001878: 687b ldr r3, [r7, #4] + 800187a: 6818 ldr r0, [r3, #0] + 800187c: 68fb ldr r3, [r7, #12] + 800187e: 6959 ldr r1, [r3, #20] + 8001880: 68fb ldr r3, [r7, #12] + 8001882: 88da ldrh r2, [r3, #6] + 8001884: 231e movs r3, #30 + 8001886: 18fb adds r3, r7, r3 + 8001888: 881b ldrh r3, [r3, #0] + 800188a: f002 f87c bl 8003986 + 800188e: e07f b.n 8001990 + 8001890: ffff8f0f .word 0xffff8f0f + 8001894: ffff8000 .word 0xffff8000 + 8001898: 00000402 .word 0x00000402 + 800189c: 00000406 .word 0x00000406 + 80018a0: 00000f8f .word 0x00000f8f + 80018a4: ffff83ff .word 0xffff83ff + 80018a8: ffffbf8f .word 0xffffbf8f + 80018ac: ffff8080 .word 0xffff8080 + } + } + else + { + if ((PCD_GET_ENDPOINT(hpcd->Instance, ep->num) & USB_EP_DTOG_RX) != 0U) + 80018b0: 687b ldr r3, [r7, #4] + 80018b2: 681b ldr r3, [r3, #0] + 80018b4: 001a movs r2, r3 + 80018b6: 68fb ldr r3, [r7, #12] + 80018b8: 781b ldrb r3, [r3, #0] + 80018ba: 009b lsls r3, r3, #2 + 80018bc: 18d3 adds r3, r2, r3 + 80018be: 881b ldrh r3, [r3, #0] + 80018c0: b29b uxth r3, r3 + 80018c2: 001a movs r2, r3 + 80018c4: 2380 movs r3, #128 ; 0x80 + 80018c6: 01db lsls r3, r3, #7 + 80018c8: 4013 ands r3, r2 + 80018ca: d025 beq.n 8001918 + { + /*read from endpoint BUF0Addr buffer*/ + count = (uint16_t)PCD_GET_EP_DBUF0_CNT(hpcd->Instance, ep->num); + 80018cc: 687b ldr r3, [r7, #4] + 80018ce: 681b ldr r3, [r3, #0] + 80018d0: 2250 movs r2, #80 ; 0x50 + 80018d2: 5a9b ldrh r3, [r3, r2] + 80018d4: b29b uxth r3, r3 + 80018d6: 001a movs r2, r3 + 80018d8: 68fb ldr r3, [r7, #12] + 80018da: 781b ldrb r3, [r3, #0] + 80018dc: 00db lsls r3, r3, #3 + 80018de: 18d2 adds r2, r2, r3 + 80018e0: 687b ldr r3, [r7, #4] + 80018e2: 681b ldr r3, [r3, #0] + 80018e4: 18d3 adds r3, r2, r3 + 80018e6: 4a72 ldr r2, [pc, #456] ; (8001ab0 ) + 80018e8: 4694 mov ip, r2 + 80018ea: 4463 add r3, ip + 80018ec: 881a ldrh r2, [r3, #0] + 80018ee: 211e movs r1, #30 + 80018f0: 187b adds r3, r7, r1 + 80018f2: 0592 lsls r2, r2, #22 + 80018f4: 0d92 lsrs r2, r2, #22 + 80018f6: 801a strh r2, [r3, #0] + if (count != 0U) + 80018f8: 187b adds r3, r7, r1 + 80018fa: 881b ldrh r3, [r3, #0] + 80018fc: 2b00 cmp r3, #0 + 80018fe: d030 beq.n 8001962 + { + USB_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaaddr0, count); + 8001900: 687b ldr r3, [r7, #4] + 8001902: 6818 ldr r0, [r3, #0] + 8001904: 68fb ldr r3, [r7, #12] + 8001906: 6959 ldr r1, [r3, #20] + 8001908: 68fb ldr r3, [r7, #12] + 800190a: 891a ldrh r2, [r3, #8] + 800190c: 231e movs r3, #30 + 800190e: 18fb adds r3, r7, r3 + 8001910: 881b ldrh r3, [r3, #0] + 8001912: f002 f838 bl 8003986 + 8001916: e024 b.n 8001962 + } + } + else + { + /*read from endpoint BUF1Addr buffer*/ + count = (uint16_t)PCD_GET_EP_DBUF1_CNT(hpcd->Instance, ep->num); + 8001918: 687b ldr r3, [r7, #4] + 800191a: 681b ldr r3, [r3, #0] + 800191c: 2250 movs r2, #80 ; 0x50 + 800191e: 5a9b ldrh r3, [r3, r2] + 8001920: b29b uxth r3, r3 + 8001922: 001a movs r2, r3 + 8001924: 68fb ldr r3, [r7, #12] + 8001926: 781b ldrb r3, [r3, #0] + 8001928: 00db lsls r3, r3, #3 + 800192a: 18d2 adds r2, r2, r3 + 800192c: 687b ldr r3, [r7, #4] + 800192e: 681b ldr r3, [r3, #0] + 8001930: 18d3 adds r3, r2, r3 + 8001932: 4a60 ldr r2, [pc, #384] ; (8001ab4 ) + 8001934: 4694 mov ip, r2 + 8001936: 4463 add r3, ip + 8001938: 881a ldrh r2, [r3, #0] + 800193a: 211e movs r1, #30 + 800193c: 187b adds r3, r7, r1 + 800193e: 0592 lsls r2, r2, #22 + 8001940: 0d92 lsrs r2, r2, #22 + 8001942: 801a strh r2, [r3, #0] + if (count != 0U) + 8001944: 187b adds r3, r7, r1 + 8001946: 881b ldrh r3, [r3, #0] + 8001948: 2b00 cmp r3, #0 + 800194a: d00a beq.n 8001962 + { + USB_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaaddr1, count); + 800194c: 687b ldr r3, [r7, #4] + 800194e: 6818 ldr r0, [r3, #0] + 8001950: 68fb ldr r3, [r7, #12] + 8001952: 6959 ldr r1, [r3, #20] + 8001954: 68fb ldr r3, [r7, #12] + 8001956: 895a ldrh r2, [r3, #10] + 8001958: 231e movs r3, #30 + 800195a: 18fb adds r3, r7, r3 + 800195c: 881b ldrh r3, [r3, #0] + 800195e: f002 f812 bl 8003986 + } + } + /* free EP OUT Buffer */ + PCD_FreeUserBuffer(hpcd->Instance, ep->num, 0U); + 8001962: 687b ldr r3, [r7, #4] + 8001964: 681b ldr r3, [r3, #0] + 8001966: 001a movs r2, r3 + 8001968: 68fb ldr r3, [r7, #12] + 800196a: 781b ldrb r3, [r3, #0] + 800196c: 009b lsls r3, r3, #2 + 800196e: 18d3 adds r3, r2, r3 + 8001970: 881b ldrh r3, [r3, #0] + 8001972: b29b uxth r3, r3 + 8001974: 4a50 ldr r2, [pc, #320] ; (8001ab8 ) + 8001976: 4013 ands r3, r2 + 8001978: b29c uxth r4, r3 + 800197a: 687b ldr r3, [r7, #4] + 800197c: 681b ldr r3, [r3, #0] + 800197e: 001a movs r2, r3 + 8001980: 68fb ldr r3, [r7, #12] + 8001982: 781b ldrb r3, [r3, #0] + 8001984: 009b lsls r3, r3, #2 + 8001986: 18d3 adds r3, r2, r3 + 8001988: 4a4c ldr r2, [pc, #304] ; (8001abc ) + 800198a: 4322 orrs r2, r4 + 800198c: b292 uxth r2, r2 + 800198e: 801a strh r2, [r3, #0] + } + /*multi-packet on the NON control OUT endpoint*/ + ep->xfer_count += count; + 8001990: 68fb ldr r3, [r7, #12] + 8001992: 69da ldr r2, [r3, #28] + 8001994: 211e movs r1, #30 + 8001996: 187b adds r3, r7, r1 + 8001998: 881b ldrh r3, [r3, #0] + 800199a: 18d2 adds r2, r2, r3 + 800199c: 68fb ldr r3, [r7, #12] + 800199e: 61da str r2, [r3, #28] + ep->xfer_buff += count; + 80019a0: 68fb ldr r3, [r7, #12] + 80019a2: 695a ldr r2, [r3, #20] + 80019a4: 187b adds r3, r7, r1 + 80019a6: 881b ldrh r3, [r3, #0] + 80019a8: 18d2 adds r2, r2, r3 + 80019aa: 68fb ldr r3, [r7, #12] + 80019ac: 615a str r2, [r3, #20] + + if ((ep->xfer_len == 0U) || (count < ep->maxpacket)) + 80019ae: 68fb ldr r3, [r7, #12] + 80019b0: 699b ldr r3, [r3, #24] + 80019b2: 2b00 cmp r3, #0 + 80019b4: d006 beq.n 80019c4 + 80019b6: 231e movs r3, #30 + 80019b8: 18fb adds r3, r7, r3 + 80019ba: 881a ldrh r2, [r3, #0] + 80019bc: 68fb ldr r3, [r7, #12] + 80019be: 691b ldr r3, [r3, #16] + 80019c0: 429a cmp r2, r3 + 80019c2: d207 bcs.n 80019d4 + { + /* RX COMPLETE */ +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) + hpcd->DataOutStageCallback(hpcd, ep->num); +#else + HAL_PCD_DataOutStageCallback(hpcd, ep->num); + 80019c4: 68fb ldr r3, [r7, #12] + 80019c6: 781a ldrb r2, [r3, #0] + 80019c8: 687b ldr r3, [r7, #4] + 80019ca: 0011 movs r1, r2 + 80019cc: 0018 movs r0, r3 + 80019ce: f00c fd2e bl 800e42e + 80019d2: e008 b.n 80019e6 +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ + } + else + { + (void)HAL_PCD_EP_Receive(hpcd, ep->num, ep->xfer_buff, ep->xfer_len); + 80019d4: 68fb ldr r3, [r7, #12] + 80019d6: 7819 ldrb r1, [r3, #0] + 80019d8: 68fb ldr r3, [r7, #12] + 80019da: 695a ldr r2, [r3, #20] + 80019dc: 68fb ldr r3, [r7, #12] + 80019de: 699b ldr r3, [r3, #24] + 80019e0: 6878 ldr r0, [r7, #4] + 80019e2: f7ff fc49 bl 8001278 + } + + } /* if((wEPVal & EP_CTR_RX) */ + + if ((wEPVal & USB_EP_CTR_TX) != 0U) + 80019e6: 2312 movs r3, #18 + 80019e8: 18fb adds r3, r7, r3 + 80019ea: 881b ldrh r3, [r3, #0] + 80019ec: 2280 movs r2, #128 ; 0x80 + 80019ee: 4013 ands r3, r2 + 80019f0: d04f beq.n 8001a92 + { + ep = &hpcd->IN_ep[epindex]; + 80019f2: 2115 movs r1, #21 + 80019f4: 187b adds r3, r7, r1 + 80019f6: 781b ldrb r3, [r3, #0] + 80019f8: 015b lsls r3, r3, #5 + 80019fa: 3328 adds r3, #40 ; 0x28 + 80019fc: 687a ldr r2, [r7, #4] + 80019fe: 18d3 adds r3, r2, r3 + 8001a00: 60fb str r3, [r7, #12] + + /* clear int flag */ + PCD_CLEAR_TX_EP_CTR(hpcd->Instance, epindex); + 8001a02: 687b ldr r3, [r7, #4] + 8001a04: 681b ldr r3, [r3, #0] + 8001a06: 001a movs r2, r3 + 8001a08: 187b adds r3, r7, r1 + 8001a0a: 781b ldrb r3, [r3, #0] + 8001a0c: 009b lsls r3, r3, #2 + 8001a0e: 18d3 adds r3, r2, r3 + 8001a10: 881b ldrh r3, [r3, #0] + 8001a12: b29b uxth r3, r3 + 8001a14: 4a2a ldr r2, [pc, #168] ; (8001ac0 ) + 8001a16: 4013 ands r3, r2 + 8001a18: b29c uxth r4, r3 + 8001a1a: 687b ldr r3, [r7, #4] + 8001a1c: 681b ldr r3, [r3, #0] + 8001a1e: 001a movs r2, r3 + 8001a20: 187b adds r3, r7, r1 + 8001a22: 781b ldrb r3, [r3, #0] + 8001a24: 009b lsls r3, r3, #2 + 8001a26: 18d3 adds r3, r2, r3 + 8001a28: 4a26 ldr r2, [pc, #152] ; (8001ac4 ) + 8001a2a: 4322 orrs r2, r4 + 8001a2c: b292 uxth r2, r2 + 8001a2e: 801a strh r2, [r3, #0] + + /*multi-packet on the NON control IN endpoint*/ + ep->xfer_count = PCD_GET_EP_TX_CNT(hpcd->Instance, ep->num); + 8001a30: 687b ldr r3, [r7, #4] + 8001a32: 681b ldr r3, [r3, #0] + 8001a34: 2250 movs r2, #80 ; 0x50 + 8001a36: 5a9b ldrh r3, [r3, r2] + 8001a38: b29b uxth r3, r3 + 8001a3a: 001a movs r2, r3 + 8001a3c: 68fb ldr r3, [r7, #12] + 8001a3e: 781b ldrb r3, [r3, #0] + 8001a40: 00db lsls r3, r3, #3 + 8001a42: 18d2 adds r2, r2, r3 + 8001a44: 687b ldr r3, [r7, #4] + 8001a46: 681b ldr r3, [r3, #0] + 8001a48: 18d3 adds r3, r2, r3 + 8001a4a: 4a19 ldr r2, [pc, #100] ; (8001ab0 ) + 8001a4c: 4694 mov ip, r2 + 8001a4e: 4463 add r3, ip + 8001a50: 881b ldrh r3, [r3, #0] + 8001a52: 059b lsls r3, r3, #22 + 8001a54: 0d9a lsrs r2, r3, #22 + 8001a56: 68fb ldr r3, [r7, #12] + 8001a58: 61da str r2, [r3, #28] + ep->xfer_buff += ep->xfer_count; + 8001a5a: 68fb ldr r3, [r7, #12] + 8001a5c: 695a ldr r2, [r3, #20] + 8001a5e: 68fb ldr r3, [r7, #12] + 8001a60: 69db ldr r3, [r3, #28] + 8001a62: 18d2 adds r2, r2, r3 + 8001a64: 68fb ldr r3, [r7, #12] + 8001a66: 615a str r2, [r3, #20] + + /* Zero Length Packet? */ + if (ep->xfer_len == 0U) + 8001a68: 68fb ldr r3, [r7, #12] + 8001a6a: 699b ldr r3, [r3, #24] + 8001a6c: 2b00 cmp r3, #0 + 8001a6e: d107 bne.n 8001a80 + { + /* TX COMPLETE */ +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) + hpcd->DataInStageCallback(hpcd, ep->num); +#else + HAL_PCD_DataInStageCallback(hpcd, ep->num); + 8001a70: 68fb ldr r3, [r7, #12] + 8001a72: 781a ldrb r2, [r3, #0] + 8001a74: 687b ldr r3, [r7, #4] + 8001a76: 0011 movs r1, r2 + 8001a78: 0018 movs r0, r3 + 8001a7a: f00c fcf5 bl 800e468 + 8001a7e: e008 b.n 8001a92 +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ + } + else + { + (void)HAL_PCD_EP_Transmit(hpcd, ep->num, ep->xfer_buff, ep->xfer_len); + 8001a80: 68fb ldr r3, [r7, #12] + 8001a82: 7819 ldrb r1, [r3, #0] + 8001a84: 68fb ldr r3, [r7, #12] + 8001a86: 695a ldr r2, [r3, #20] + 8001a88: 68fb ldr r3, [r7, #12] + 8001a8a: 699b ldr r3, [r3, #24] + 8001a8c: 6878 ldr r0, [r7, #4] + 8001a8e: f7ff fc49 bl 8001324 + while ((hpcd->Instance->ISTR & USB_ISTR_CTR) != 0U) + 8001a92: 687b ldr r3, [r7, #4] + 8001a94: 681b ldr r3, [r3, #0] + 8001a96: 2244 movs r2, #68 ; 0x44 + 8001a98: 5a9b ldrh r3, [r3, r2] + 8001a9a: b29b uxth r3, r3 + 8001a9c: b21b sxth r3, r3 + 8001a9e: 2b00 cmp r3, #0 + 8001aa0: da00 bge.n 8001aa4 + 8001aa2: e542 b.n 800152a + } + } + } + } + return HAL_OK; + 8001aa4: 2300 movs r3, #0 +} + 8001aa6: 0018 movs r0, r3 + 8001aa8: 46bd mov sp, r7 + 8001aaa: b009 add sp, #36 ; 0x24 + 8001aac: bd90 pop {r4, r7, pc} + 8001aae: 46c0 nop ; (mov r8, r8) + 8001ab0: 00000402 .word 0x00000402 + 8001ab4: 00000406 .word 0x00000406 + 8001ab8: ffff8f8f .word 0xffff8f8f + 8001abc: ffff80c0 .word 0xffff80c0 + 8001ac0: ffff8f0f .word 0xffff8f0f + 8001ac4: ffff8000 .word 0xffff8000 + +08001ac8 : + +HAL_StatusTypeDef HAL_PCDEx_PMAConfig(PCD_HandleTypeDef *hpcd, + uint16_t ep_addr, + uint16_t ep_kind, + uint32_t pmaadress) +{ + 8001ac8: b590 push {r4, r7, lr} + 8001aca: b087 sub sp, #28 + 8001acc: af00 add r7, sp, #0 + 8001ace: 60f8 str r0, [r7, #12] + 8001ad0: 0008 movs r0, r1 + 8001ad2: 0011 movs r1, r2 + 8001ad4: 607b str r3, [r7, #4] + 8001ad6: 240a movs r4, #10 + 8001ad8: 193b adds r3, r7, r4 + 8001ada: 1c02 adds r2, r0, #0 + 8001adc: 801a strh r2, [r3, #0] + 8001ade: 2308 movs r3, #8 + 8001ae0: 18fb adds r3, r7, r3 + 8001ae2: 1c0a adds r2, r1, #0 + 8001ae4: 801a strh r2, [r3, #0] + PCD_EPTypeDef *ep; + + /* initialize ep structure*/ + if ((0x80U & ep_addr) == 0x80U) + 8001ae6: 193b adds r3, r7, r4 + 8001ae8: 881b ldrh r3, [r3, #0] + 8001aea: 2280 movs r2, #128 ; 0x80 + 8001aec: 4013 ands r3, r2 + 8001aee: b29b uxth r3, r3 + 8001af0: 2b00 cmp r3, #0 + 8001af2: d00a beq.n 8001b0a + { + ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK]; + 8001af4: 230a movs r3, #10 + 8001af6: 18fb adds r3, r7, r3 + 8001af8: 881b ldrh r3, [r3, #0] + 8001afa: 2207 movs r2, #7 + 8001afc: 4013 ands r3, r2 + 8001afe: 015b lsls r3, r3, #5 + 8001b00: 3328 adds r3, #40 ; 0x28 + 8001b02: 68fa ldr r2, [r7, #12] + 8001b04: 18d3 adds r3, r2, r3 + 8001b06: 617b str r3, [r7, #20] + 8001b08: e008 b.n 8001b1c + } + else + { + ep = &hpcd->OUT_ep[ep_addr]; + 8001b0a: 230a movs r3, #10 + 8001b0c: 18fb adds r3, r7, r3 + 8001b0e: 881b ldrh r3, [r3, #0] + 8001b10: 015b lsls r3, r3, #5 + 8001b12: 3329 adds r3, #41 ; 0x29 + 8001b14: 33ff adds r3, #255 ; 0xff + 8001b16: 68fa ldr r2, [r7, #12] + 8001b18: 18d3 adds r3, r2, r3 + 8001b1a: 617b str r3, [r7, #20] + } + + /* Here we check if the endpoint is single or double Buffer*/ + if (ep_kind == PCD_SNG_BUF) + 8001b1c: 2308 movs r3, #8 + 8001b1e: 18fb adds r3, r7, r3 + 8001b20: 881b ldrh r3, [r3, #0] + 8001b22: 2b00 cmp r3, #0 + 8001b24: d107 bne.n 8001b36 + { + /* Single Buffer */ + ep->doublebuffer = 0U; + 8001b26: 697b ldr r3, [r7, #20] + 8001b28: 2200 movs r2, #0 + 8001b2a: 731a strb r2, [r3, #12] + /* Configure the PMA */ + ep->pmaadress = (uint16_t)pmaadress; + 8001b2c: 687b ldr r3, [r7, #4] + 8001b2e: b29a uxth r2, r3 + 8001b30: 697b ldr r3, [r7, #20] + 8001b32: 80da strh r2, [r3, #6] + 8001b34: e00b b.n 8001b4e + } + else /* USB_DBL_BUF */ + { + /* Double Buffer Endpoint */ + ep->doublebuffer = 1U; + 8001b36: 697b ldr r3, [r7, #20] + 8001b38: 2201 movs r2, #1 + 8001b3a: 731a strb r2, [r3, #12] + /* Configure the PMA */ + ep->pmaaddr0 = (uint16_t)(pmaadress & 0xFFFFU); + 8001b3c: 687b ldr r3, [r7, #4] + 8001b3e: b29a uxth r2, r3 + 8001b40: 697b ldr r3, [r7, #20] + 8001b42: 811a strh r2, [r3, #8] + ep->pmaaddr1 = (uint16_t)((pmaadress & 0xFFFF0000U) >> 16); + 8001b44: 687b ldr r3, [r7, #4] + 8001b46: 0c1b lsrs r3, r3, #16 + 8001b48: b29a uxth r2, r3 + 8001b4a: 697b ldr r3, [r7, #20] + 8001b4c: 815a strh r2, [r3, #10] + } + + return HAL_OK; + 8001b4e: 2300 movs r3, #0 +} + 8001b50: 0018 movs r0, r3 + 8001b52: 46bd mov sp, r7 + 8001b54: b007 add sp, #28 + 8001b56: bd90 pop {r4, r7, pc} + +08001b58 : + * @brief Activate LPM feature. + * @param hpcd PCD handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCDEx_ActivateLPM(PCD_HandleTypeDef *hpcd) +{ + 8001b58: b580 push {r7, lr} + 8001b5a: b084 sub sp, #16 + 8001b5c: af00 add r7, sp, #0 + 8001b5e: 6078 str r0, [r7, #4] + + USB_TypeDef *USBx = hpcd->Instance; + 8001b60: 687b ldr r3, [r7, #4] + 8001b62: 681b ldr r3, [r3, #0] + 8001b64: 60fb str r3, [r7, #12] + hpcd->lpm_active = 1U; + 8001b66: 687a ldr r2, [r7, #4] + 8001b68: 239a movs r3, #154 ; 0x9a + 8001b6a: 009b lsls r3, r3, #2 + 8001b6c: 2101 movs r1, #1 + 8001b6e: 50d1 str r1, [r2, r3] + hpcd->LPM_State = LPM_L0; + 8001b70: 687a ldr r2, [r7, #4] + 8001b72: 2398 movs r3, #152 ; 0x98 + 8001b74: 009b lsls r3, r3, #2 + 8001b76: 2100 movs r1, #0 + 8001b78: 54d1 strb r1, [r2, r3] + + USBx->LPMCSR |= USB_LPMCSR_LMPEN; + 8001b7a: 68fb ldr r3, [r7, #12] + 8001b7c: 2254 movs r2, #84 ; 0x54 + 8001b7e: 5a9b ldrh r3, [r3, r2] + 8001b80: b29b uxth r3, r3 + 8001b82: 2201 movs r2, #1 + 8001b84: 4313 orrs r3, r2 + 8001b86: b299 uxth r1, r3 + 8001b88: 68fb ldr r3, [r7, #12] + 8001b8a: 2254 movs r2, #84 ; 0x54 + 8001b8c: 5299 strh r1, [r3, r2] + USBx->LPMCSR |= USB_LPMCSR_LPMACK; + 8001b8e: 68fb ldr r3, [r7, #12] + 8001b90: 2254 movs r2, #84 ; 0x54 + 8001b92: 5a9b ldrh r3, [r3, r2] + 8001b94: b29b uxth r3, r3 + 8001b96: 2202 movs r2, #2 + 8001b98: 4313 orrs r3, r2 + 8001b9a: b299 uxth r1, r3 + 8001b9c: 68fb ldr r3, [r7, #12] + 8001b9e: 2254 movs r2, #84 ; 0x54 + 8001ba0: 5299 strh r1, [r3, r2] + + return HAL_OK; + 8001ba2: 2300 movs r3, #0 +} + 8001ba4: 0018 movs r0, r3 + 8001ba6: 46bd mov sp, r7 + 8001ba8: b004 add sp, #16 + 8001baa: bd80 pop {r7, pc} + +08001bac : + * @param hpcd PCD handle + * @param msg LPM message + * @retval HAL status + */ +__weak void HAL_PCDEx_LPM_Callback(PCD_HandleTypeDef *hpcd, PCD_LPM_MsgTypeDef msg) +{ + 8001bac: b580 push {r7, lr} + 8001bae: b082 sub sp, #8 + 8001bb0: af00 add r7, sp, #0 + 8001bb2: 6078 str r0, [r7, #4] + 8001bb4: 000a movs r2, r1 + 8001bb6: 1cfb adds r3, r7, #3 + 8001bb8: 701a strb r2, [r3, #0] + UNUSED(msg); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_PCDEx_LPM_Callback could be implemented in the user file + */ +} + 8001bba: 46c0 nop ; (mov r8, r8) + 8001bbc: 46bd mov sp, r7 + 8001bbe: b002 add sp, #8 + 8001bc0: bd80 pop {r7, pc} + ... + +08001bc4 : + * supported by this macro. User should request a transition to HSE Off + * first and then HSE On or HSE Bypass. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RCC_OscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct) +{ + 8001bc4: b580 push {r7, lr} + 8001bc6: b088 sub sp, #32 + 8001bc8: af00 add r7, sp, #0 + 8001bca: 6078 str r0, [r7, #4] + uint32_t tickstart; + uint32_t pll_config; + uint32_t pll_config2; + + /* Check Null pointer */ + if(RCC_OscInitStruct == NULL) + 8001bcc: 687b ldr r3, [r7, #4] + 8001bce: 2b00 cmp r3, #0 + 8001bd0: d102 bne.n 8001bd8 + { + return HAL_ERROR; + 8001bd2: 2301 movs r3, #1 + 8001bd4: f000 fb76 bl 80022c4 + + /* Check the parameters */ + assert_param(IS_RCC_OSCILLATORTYPE(RCC_OscInitStruct->OscillatorType)); + + /*------------------------------- HSE Configuration ------------------------*/ + if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSE) == RCC_OSCILLATORTYPE_HSE) + 8001bd8: 687b ldr r3, [r7, #4] + 8001bda: 681b ldr r3, [r3, #0] + 8001bdc: 2201 movs r2, #1 + 8001bde: 4013 ands r3, r2 + 8001be0: d100 bne.n 8001be4 + 8001be2: e08e b.n 8001d02 + { + /* Check the parameters */ + assert_param(IS_RCC_HSE(RCC_OscInitStruct->HSEState)); + + /* When the HSE is used as system clock or clock source for PLL in these cases it is not allowed to be disabled */ + if((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_HSE) + 8001be4: 4bc5 ldr r3, [pc, #788] ; (8001efc ) + 8001be6: 685b ldr r3, [r3, #4] + 8001be8: 220c movs r2, #12 + 8001bea: 4013 ands r3, r2 + 8001bec: 2b04 cmp r3, #4 + 8001bee: d00e beq.n 8001c0e + || ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && (__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_HSE))) + 8001bf0: 4bc2 ldr r3, [pc, #776] ; (8001efc ) + 8001bf2: 685b ldr r3, [r3, #4] + 8001bf4: 220c movs r2, #12 + 8001bf6: 4013 ands r3, r2 + 8001bf8: 2b08 cmp r3, #8 + 8001bfa: d117 bne.n 8001c2c + 8001bfc: 4bbf ldr r3, [pc, #764] ; (8001efc ) + 8001bfe: 685a ldr r2, [r3, #4] + 8001c00: 23c0 movs r3, #192 ; 0xc0 + 8001c02: 025b lsls r3, r3, #9 + 8001c04: 401a ands r2, r3 + 8001c06: 2380 movs r3, #128 ; 0x80 + 8001c08: 025b lsls r3, r3, #9 + 8001c0a: 429a cmp r2, r3 + 8001c0c: d10e bne.n 8001c2c + { + if((__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) != RESET) && (RCC_OscInitStruct->HSEState == RCC_HSE_OFF)) + 8001c0e: 4bbb ldr r3, [pc, #748] ; (8001efc ) + 8001c10: 681a ldr r2, [r3, #0] + 8001c12: 2380 movs r3, #128 ; 0x80 + 8001c14: 029b lsls r3, r3, #10 + 8001c16: 4013 ands r3, r2 + 8001c18: d100 bne.n 8001c1c + 8001c1a: e071 b.n 8001d00 + 8001c1c: 687b ldr r3, [r7, #4] + 8001c1e: 685b ldr r3, [r3, #4] + 8001c20: 2b00 cmp r3, #0 + 8001c22: d000 beq.n 8001c26 + 8001c24: e06c b.n 8001d00 + { + return HAL_ERROR; + 8001c26: 2301 movs r3, #1 + 8001c28: f000 fb4c bl 80022c4 + } + } + else + { + /* Set the new HSE configuration ---------------------------------------*/ + __HAL_RCC_HSE_CONFIG(RCC_OscInitStruct->HSEState); + 8001c2c: 687b ldr r3, [r7, #4] + 8001c2e: 685b ldr r3, [r3, #4] + 8001c30: 2b01 cmp r3, #1 + 8001c32: d107 bne.n 8001c44 + 8001c34: 4bb1 ldr r3, [pc, #708] ; (8001efc ) + 8001c36: 681a ldr r2, [r3, #0] + 8001c38: 4bb0 ldr r3, [pc, #704] ; (8001efc ) + 8001c3a: 2180 movs r1, #128 ; 0x80 + 8001c3c: 0249 lsls r1, r1, #9 + 8001c3e: 430a orrs r2, r1 + 8001c40: 601a str r2, [r3, #0] + 8001c42: e02f b.n 8001ca4 + 8001c44: 687b ldr r3, [r7, #4] + 8001c46: 685b ldr r3, [r3, #4] + 8001c48: 2b00 cmp r3, #0 + 8001c4a: d10c bne.n 8001c66 + 8001c4c: 4bab ldr r3, [pc, #684] ; (8001efc ) + 8001c4e: 681a ldr r2, [r3, #0] + 8001c50: 4baa ldr r3, [pc, #680] ; (8001efc ) + 8001c52: 49ab ldr r1, [pc, #684] ; (8001f00 ) + 8001c54: 400a ands r2, r1 + 8001c56: 601a str r2, [r3, #0] + 8001c58: 4ba8 ldr r3, [pc, #672] ; (8001efc ) + 8001c5a: 681a ldr r2, [r3, #0] + 8001c5c: 4ba7 ldr r3, [pc, #668] ; (8001efc ) + 8001c5e: 49a9 ldr r1, [pc, #676] ; (8001f04 ) + 8001c60: 400a ands r2, r1 + 8001c62: 601a str r2, [r3, #0] + 8001c64: e01e b.n 8001ca4 + 8001c66: 687b ldr r3, [r7, #4] + 8001c68: 685b ldr r3, [r3, #4] + 8001c6a: 2b05 cmp r3, #5 + 8001c6c: d10e bne.n 8001c8c + 8001c6e: 4ba3 ldr r3, [pc, #652] ; (8001efc ) + 8001c70: 681a ldr r2, [r3, #0] + 8001c72: 4ba2 ldr r3, [pc, #648] ; (8001efc ) + 8001c74: 2180 movs r1, #128 ; 0x80 + 8001c76: 02c9 lsls r1, r1, #11 + 8001c78: 430a orrs r2, r1 + 8001c7a: 601a str r2, [r3, #0] + 8001c7c: 4b9f ldr r3, [pc, #636] ; (8001efc ) + 8001c7e: 681a ldr r2, [r3, #0] + 8001c80: 4b9e ldr r3, [pc, #632] ; (8001efc ) + 8001c82: 2180 movs r1, #128 ; 0x80 + 8001c84: 0249 lsls r1, r1, #9 + 8001c86: 430a orrs r2, r1 + 8001c88: 601a str r2, [r3, #0] + 8001c8a: e00b b.n 8001ca4 + 8001c8c: 4b9b ldr r3, [pc, #620] ; (8001efc ) + 8001c8e: 681a ldr r2, [r3, #0] + 8001c90: 4b9a ldr r3, [pc, #616] ; (8001efc ) + 8001c92: 499b ldr r1, [pc, #620] ; (8001f00 ) + 8001c94: 400a ands r2, r1 + 8001c96: 601a str r2, [r3, #0] + 8001c98: 4b98 ldr r3, [pc, #608] ; (8001efc ) + 8001c9a: 681a ldr r2, [r3, #0] + 8001c9c: 4b97 ldr r3, [pc, #604] ; (8001efc ) + 8001c9e: 4999 ldr r1, [pc, #612] ; (8001f04 ) + 8001ca0: 400a ands r2, r1 + 8001ca2: 601a str r2, [r3, #0] + + + /* Check the HSE State */ + if(RCC_OscInitStruct->HSEState != RCC_HSE_OFF) + 8001ca4: 687b ldr r3, [r7, #4] + 8001ca6: 685b ldr r3, [r3, #4] + 8001ca8: 2b00 cmp r3, #0 + 8001caa: d014 beq.n 8001cd6 + { + /* Get Start Tick */ + tickstart = HAL_GetTick(); + 8001cac: f7fe fd0a bl 80006c4 + 8001cb0: 0003 movs r3, r0 + 8001cb2: 61bb str r3, [r7, #24] + + /* Wait till HSE is ready */ + while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) == RESET) + 8001cb4: e008 b.n 8001cc8 + { + if((HAL_GetTick() - tickstart ) > HSE_TIMEOUT_VALUE) + 8001cb6: f7fe fd05 bl 80006c4 + 8001cba: 0002 movs r2, r0 + 8001cbc: 69bb ldr r3, [r7, #24] + 8001cbe: 1ad3 subs r3, r2, r3 + 8001cc0: 2b64 cmp r3, #100 ; 0x64 + 8001cc2: d901 bls.n 8001cc8 + { + return HAL_TIMEOUT; + 8001cc4: 2303 movs r3, #3 + 8001cc6: e2fd b.n 80022c4 + while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) == RESET) + 8001cc8: 4b8c ldr r3, [pc, #560] ; (8001efc ) + 8001cca: 681a ldr r2, [r3, #0] + 8001ccc: 2380 movs r3, #128 ; 0x80 + 8001cce: 029b lsls r3, r3, #10 + 8001cd0: 4013 ands r3, r2 + 8001cd2: d0f0 beq.n 8001cb6 + 8001cd4: e015 b.n 8001d02 + } + } + else + { + /* Get Start Tick */ + tickstart = HAL_GetTick(); + 8001cd6: f7fe fcf5 bl 80006c4 + 8001cda: 0003 movs r3, r0 + 8001cdc: 61bb str r3, [r7, #24] + + /* Wait till HSE is disabled */ + while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) != RESET) + 8001cde: e008 b.n 8001cf2 + { + if((HAL_GetTick() - tickstart ) > HSE_TIMEOUT_VALUE) + 8001ce0: f7fe fcf0 bl 80006c4 + 8001ce4: 0002 movs r2, r0 + 8001ce6: 69bb ldr r3, [r7, #24] + 8001ce8: 1ad3 subs r3, r2, r3 + 8001cea: 2b64 cmp r3, #100 ; 0x64 + 8001cec: d901 bls.n 8001cf2 + { + return HAL_TIMEOUT; + 8001cee: 2303 movs r3, #3 + 8001cf0: e2e8 b.n 80022c4 + while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) != RESET) + 8001cf2: 4b82 ldr r3, [pc, #520] ; (8001efc ) + 8001cf4: 681a ldr r2, [r3, #0] + 8001cf6: 2380 movs r3, #128 ; 0x80 + 8001cf8: 029b lsls r3, r3, #10 + 8001cfa: 4013 ands r3, r2 + 8001cfc: d1f0 bne.n 8001ce0 + 8001cfe: e000 b.n 8001d02 + if((__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) != RESET) && (RCC_OscInitStruct->HSEState == RCC_HSE_OFF)) + 8001d00: 46c0 nop ; (mov r8, r8) + } + } + } + } + /*----------------------------- HSI Configuration --------------------------*/ + if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSI) == RCC_OSCILLATORTYPE_HSI) + 8001d02: 687b ldr r3, [r7, #4] + 8001d04: 681b ldr r3, [r3, #0] + 8001d06: 2202 movs r2, #2 + 8001d08: 4013 ands r3, r2 + 8001d0a: d100 bne.n 8001d0e + 8001d0c: e06c b.n 8001de8 + /* Check the parameters */ + assert_param(IS_RCC_HSI(RCC_OscInitStruct->HSIState)); + assert_param(IS_RCC_CALIBRATION_VALUE(RCC_OscInitStruct->HSICalibrationValue)); + + /* Check if HSI is used as system clock or as PLL source when PLL is selected as system clock */ + if((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_HSI) + 8001d0e: 4b7b ldr r3, [pc, #492] ; (8001efc ) + 8001d10: 685b ldr r3, [r3, #4] + 8001d12: 220c movs r2, #12 + 8001d14: 4013 ands r3, r2 + 8001d16: d00e beq.n 8001d36 + || ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && (__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_HSI))) + 8001d18: 4b78 ldr r3, [pc, #480] ; (8001efc ) + 8001d1a: 685b ldr r3, [r3, #4] + 8001d1c: 220c movs r2, #12 + 8001d1e: 4013 ands r3, r2 + 8001d20: 2b08 cmp r3, #8 + 8001d22: d11f bne.n 8001d64 + 8001d24: 4b75 ldr r3, [pc, #468] ; (8001efc ) + 8001d26: 685a ldr r2, [r3, #4] + 8001d28: 23c0 movs r3, #192 ; 0xc0 + 8001d2a: 025b lsls r3, r3, #9 + 8001d2c: 401a ands r2, r3 + 8001d2e: 2380 movs r3, #128 ; 0x80 + 8001d30: 021b lsls r3, r3, #8 + 8001d32: 429a cmp r2, r3 + 8001d34: d116 bne.n 8001d64 + { + /* When HSI is used as system clock it will not disabled */ + if((__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) != RESET) && (RCC_OscInitStruct->HSIState != RCC_HSI_ON)) + 8001d36: 4b71 ldr r3, [pc, #452] ; (8001efc ) + 8001d38: 681b ldr r3, [r3, #0] + 8001d3a: 2202 movs r2, #2 + 8001d3c: 4013 ands r3, r2 + 8001d3e: d005 beq.n 8001d4c + 8001d40: 687b ldr r3, [r7, #4] + 8001d42: 68db ldr r3, [r3, #12] + 8001d44: 2b01 cmp r3, #1 + 8001d46: d001 beq.n 8001d4c + { + return HAL_ERROR; + 8001d48: 2301 movs r3, #1 + 8001d4a: e2bb b.n 80022c4 + } + /* Otherwise, just the calibration is allowed */ + else + { + /* Adjusts the Internal High Speed oscillator (HSI) calibration value.*/ + __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->HSICalibrationValue); + 8001d4c: 4b6b ldr r3, [pc, #428] ; (8001efc ) + 8001d4e: 681b ldr r3, [r3, #0] + 8001d50: 22f8 movs r2, #248 ; 0xf8 + 8001d52: 4393 bics r3, r2 + 8001d54: 0019 movs r1, r3 + 8001d56: 687b ldr r3, [r7, #4] + 8001d58: 691b ldr r3, [r3, #16] + 8001d5a: 00da lsls r2, r3, #3 + 8001d5c: 4b67 ldr r3, [pc, #412] ; (8001efc ) + 8001d5e: 430a orrs r2, r1 + 8001d60: 601a str r2, [r3, #0] + if((__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) != RESET) && (RCC_OscInitStruct->HSIState != RCC_HSI_ON)) + 8001d62: e041 b.n 8001de8 + } + } + else + { + /* Check the HSI State */ + if(RCC_OscInitStruct->HSIState != RCC_HSI_OFF) + 8001d64: 687b ldr r3, [r7, #4] + 8001d66: 68db ldr r3, [r3, #12] + 8001d68: 2b00 cmp r3, #0 + 8001d6a: d024 beq.n 8001db6 + { + /* Enable the Internal High Speed oscillator (HSI). */ + __HAL_RCC_HSI_ENABLE(); + 8001d6c: 4b63 ldr r3, [pc, #396] ; (8001efc ) + 8001d6e: 681a ldr r2, [r3, #0] + 8001d70: 4b62 ldr r3, [pc, #392] ; (8001efc ) + 8001d72: 2101 movs r1, #1 + 8001d74: 430a orrs r2, r1 + 8001d76: 601a str r2, [r3, #0] + + /* Get Start Tick */ + tickstart = HAL_GetTick(); + 8001d78: f7fe fca4 bl 80006c4 + 8001d7c: 0003 movs r3, r0 + 8001d7e: 61bb str r3, [r7, #24] + + /* Wait till HSI is ready */ + while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) == RESET) + 8001d80: e008 b.n 8001d94 + { + if((HAL_GetTick() - tickstart ) > HSI_TIMEOUT_VALUE) + 8001d82: f7fe fc9f bl 80006c4 + 8001d86: 0002 movs r2, r0 + 8001d88: 69bb ldr r3, [r7, #24] + 8001d8a: 1ad3 subs r3, r2, r3 + 8001d8c: 2b02 cmp r3, #2 + 8001d8e: d901 bls.n 8001d94 + { + return HAL_TIMEOUT; + 8001d90: 2303 movs r3, #3 + 8001d92: e297 b.n 80022c4 + while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) == RESET) + 8001d94: 4b59 ldr r3, [pc, #356] ; (8001efc ) + 8001d96: 681b ldr r3, [r3, #0] + 8001d98: 2202 movs r2, #2 + 8001d9a: 4013 ands r3, r2 + 8001d9c: d0f1 beq.n 8001d82 + } + } + + /* Adjusts the Internal High Speed oscillator (HSI) calibration value.*/ + __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->HSICalibrationValue); + 8001d9e: 4b57 ldr r3, [pc, #348] ; (8001efc ) + 8001da0: 681b ldr r3, [r3, #0] + 8001da2: 22f8 movs r2, #248 ; 0xf8 + 8001da4: 4393 bics r3, r2 + 8001da6: 0019 movs r1, r3 + 8001da8: 687b ldr r3, [r7, #4] + 8001daa: 691b ldr r3, [r3, #16] + 8001dac: 00da lsls r2, r3, #3 + 8001dae: 4b53 ldr r3, [pc, #332] ; (8001efc ) + 8001db0: 430a orrs r2, r1 + 8001db2: 601a str r2, [r3, #0] + 8001db4: e018 b.n 8001de8 + } + else + { + /* Disable the Internal High Speed oscillator (HSI). */ + __HAL_RCC_HSI_DISABLE(); + 8001db6: 4b51 ldr r3, [pc, #324] ; (8001efc ) + 8001db8: 681a ldr r2, [r3, #0] + 8001dba: 4b50 ldr r3, [pc, #320] ; (8001efc ) + 8001dbc: 2101 movs r1, #1 + 8001dbe: 438a bics r2, r1 + 8001dc0: 601a str r2, [r3, #0] + + /* Get Start Tick */ + tickstart = HAL_GetTick(); + 8001dc2: f7fe fc7f bl 80006c4 + 8001dc6: 0003 movs r3, r0 + 8001dc8: 61bb str r3, [r7, #24] + + /* Wait till HSI is disabled */ + while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) != RESET) + 8001dca: e008 b.n 8001dde + { + if((HAL_GetTick() - tickstart ) > HSI_TIMEOUT_VALUE) + 8001dcc: f7fe fc7a bl 80006c4 + 8001dd0: 0002 movs r2, r0 + 8001dd2: 69bb ldr r3, [r7, #24] + 8001dd4: 1ad3 subs r3, r2, r3 + 8001dd6: 2b02 cmp r3, #2 + 8001dd8: d901 bls.n 8001dde + { + return HAL_TIMEOUT; + 8001dda: 2303 movs r3, #3 + 8001ddc: e272 b.n 80022c4 + while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) != RESET) + 8001dde: 4b47 ldr r3, [pc, #284] ; (8001efc ) + 8001de0: 681b ldr r3, [r3, #0] + 8001de2: 2202 movs r2, #2 + 8001de4: 4013 ands r3, r2 + 8001de6: d1f1 bne.n 8001dcc + } + } + } + } + /*------------------------------ LSI Configuration -------------------------*/ + if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSI) == RCC_OSCILLATORTYPE_LSI) + 8001de8: 687b ldr r3, [r7, #4] + 8001dea: 681b ldr r3, [r3, #0] + 8001dec: 2208 movs r2, #8 + 8001dee: 4013 ands r3, r2 + 8001df0: d036 beq.n 8001e60 + { + /* Check the parameters */ + assert_param(IS_RCC_LSI(RCC_OscInitStruct->LSIState)); + + /* Check the LSI State */ + if(RCC_OscInitStruct->LSIState != RCC_LSI_OFF) + 8001df2: 687b ldr r3, [r7, #4] + 8001df4: 69db ldr r3, [r3, #28] + 8001df6: 2b00 cmp r3, #0 + 8001df8: d019 beq.n 8001e2e + { + /* Enable the Internal Low Speed oscillator (LSI). */ + __HAL_RCC_LSI_ENABLE(); + 8001dfa: 4b40 ldr r3, [pc, #256] ; (8001efc ) + 8001dfc: 6a5a ldr r2, [r3, #36] ; 0x24 + 8001dfe: 4b3f ldr r3, [pc, #252] ; (8001efc ) + 8001e00: 2101 movs r1, #1 + 8001e02: 430a orrs r2, r1 + 8001e04: 625a str r2, [r3, #36] ; 0x24 + + /* Get Start Tick */ + tickstart = HAL_GetTick(); + 8001e06: f7fe fc5d bl 80006c4 + 8001e0a: 0003 movs r3, r0 + 8001e0c: 61bb str r3, [r7, #24] + + /* Wait till LSI is ready */ + while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSIRDY) == RESET) + 8001e0e: e008 b.n 8001e22 + { + if((HAL_GetTick() - tickstart ) > LSI_TIMEOUT_VALUE) + 8001e10: f7fe fc58 bl 80006c4 + 8001e14: 0002 movs r2, r0 + 8001e16: 69bb ldr r3, [r7, #24] + 8001e18: 1ad3 subs r3, r2, r3 + 8001e1a: 2b02 cmp r3, #2 + 8001e1c: d901 bls.n 8001e22 + { + return HAL_TIMEOUT; + 8001e1e: 2303 movs r3, #3 + 8001e20: e250 b.n 80022c4 + while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSIRDY) == RESET) + 8001e22: 4b36 ldr r3, [pc, #216] ; (8001efc ) + 8001e24: 6a5b ldr r3, [r3, #36] ; 0x24 + 8001e26: 2202 movs r2, #2 + 8001e28: 4013 ands r3, r2 + 8001e2a: d0f1 beq.n 8001e10 + 8001e2c: e018 b.n 8001e60 + } + } + else + { + /* Disable the Internal Low Speed oscillator (LSI). */ + __HAL_RCC_LSI_DISABLE(); + 8001e2e: 4b33 ldr r3, [pc, #204] ; (8001efc ) + 8001e30: 6a5a ldr r2, [r3, #36] ; 0x24 + 8001e32: 4b32 ldr r3, [pc, #200] ; (8001efc ) + 8001e34: 2101 movs r1, #1 + 8001e36: 438a bics r2, r1 + 8001e38: 625a str r2, [r3, #36] ; 0x24 + + /* Get Start Tick */ + tickstart = HAL_GetTick(); + 8001e3a: f7fe fc43 bl 80006c4 + 8001e3e: 0003 movs r3, r0 + 8001e40: 61bb str r3, [r7, #24] + + /* Wait till LSI is disabled */ + while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSIRDY) != RESET) + 8001e42: e008 b.n 8001e56 + { + if((HAL_GetTick() - tickstart ) > LSI_TIMEOUT_VALUE) + 8001e44: f7fe fc3e bl 80006c4 + 8001e48: 0002 movs r2, r0 + 8001e4a: 69bb ldr r3, [r7, #24] + 8001e4c: 1ad3 subs r3, r2, r3 + 8001e4e: 2b02 cmp r3, #2 + 8001e50: d901 bls.n 8001e56 + { + return HAL_TIMEOUT; + 8001e52: 2303 movs r3, #3 + 8001e54: e236 b.n 80022c4 + while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSIRDY) != RESET) + 8001e56: 4b29 ldr r3, [pc, #164] ; (8001efc ) + 8001e58: 6a5b ldr r3, [r3, #36] ; 0x24 + 8001e5a: 2202 movs r2, #2 + 8001e5c: 4013 ands r3, r2 + 8001e5e: d1f1 bne.n 8001e44 + } + } + } + } + /*------------------------------ LSE Configuration -------------------------*/ + if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSE) == RCC_OSCILLATORTYPE_LSE) + 8001e60: 687b ldr r3, [r7, #4] + 8001e62: 681b ldr r3, [r3, #0] + 8001e64: 2204 movs r2, #4 + 8001e66: 4013 ands r3, r2 + 8001e68: d100 bne.n 8001e6c + 8001e6a: e0b5 b.n 8001fd8 + { + FlagStatus pwrclkchanged = RESET; + 8001e6c: 231f movs r3, #31 + 8001e6e: 18fb adds r3, r7, r3 + 8001e70: 2200 movs r2, #0 + 8001e72: 701a strb r2, [r3, #0] + /* Check the parameters */ + assert_param(IS_RCC_LSE(RCC_OscInitStruct->LSEState)); + + /* Update LSE configuration in Backup Domain control register */ + /* Requires to enable write access to Backup Domain of necessary */ + if(__HAL_RCC_PWR_IS_CLK_DISABLED()) + 8001e74: 4b21 ldr r3, [pc, #132] ; (8001efc ) + 8001e76: 69da ldr r2, [r3, #28] + 8001e78: 2380 movs r3, #128 ; 0x80 + 8001e7a: 055b lsls r3, r3, #21 + 8001e7c: 4013 ands r3, r2 + 8001e7e: d111 bne.n 8001ea4 + { + __HAL_RCC_PWR_CLK_ENABLE(); + 8001e80: 4b1e ldr r3, [pc, #120] ; (8001efc ) + 8001e82: 69da ldr r2, [r3, #28] + 8001e84: 4b1d ldr r3, [pc, #116] ; (8001efc ) + 8001e86: 2180 movs r1, #128 ; 0x80 + 8001e88: 0549 lsls r1, r1, #21 + 8001e8a: 430a orrs r2, r1 + 8001e8c: 61da str r2, [r3, #28] + 8001e8e: 4b1b ldr r3, [pc, #108] ; (8001efc ) + 8001e90: 69da ldr r2, [r3, #28] + 8001e92: 2380 movs r3, #128 ; 0x80 + 8001e94: 055b lsls r3, r3, #21 + 8001e96: 4013 ands r3, r2 + 8001e98: 60fb str r3, [r7, #12] + 8001e9a: 68fb ldr r3, [r7, #12] + pwrclkchanged = SET; + 8001e9c: 231f movs r3, #31 + 8001e9e: 18fb adds r3, r7, r3 + 8001ea0: 2201 movs r2, #1 + 8001ea2: 701a strb r2, [r3, #0] + } + + if(HAL_IS_BIT_CLR(PWR->CR, PWR_CR_DBP)) + 8001ea4: 4b18 ldr r3, [pc, #96] ; (8001f08 ) + 8001ea6: 681a ldr r2, [r3, #0] + 8001ea8: 2380 movs r3, #128 ; 0x80 + 8001eaa: 005b lsls r3, r3, #1 + 8001eac: 4013 ands r3, r2 + 8001eae: d11a bne.n 8001ee6 + { + /* Enable write access to Backup domain */ + SET_BIT(PWR->CR, PWR_CR_DBP); + 8001eb0: 4b15 ldr r3, [pc, #84] ; (8001f08 ) + 8001eb2: 681a ldr r2, [r3, #0] + 8001eb4: 4b14 ldr r3, [pc, #80] ; (8001f08 ) + 8001eb6: 2180 movs r1, #128 ; 0x80 + 8001eb8: 0049 lsls r1, r1, #1 + 8001eba: 430a orrs r2, r1 + 8001ebc: 601a str r2, [r3, #0] + + /* Wait for Backup domain Write protection disable */ + tickstart = HAL_GetTick(); + 8001ebe: f7fe fc01 bl 80006c4 + 8001ec2: 0003 movs r3, r0 + 8001ec4: 61bb str r3, [r7, #24] + + while(HAL_IS_BIT_CLR(PWR->CR, PWR_CR_DBP)) + 8001ec6: e008 b.n 8001eda + { + if((HAL_GetTick() - tickstart) > RCC_DBP_TIMEOUT_VALUE) + 8001ec8: f7fe fbfc bl 80006c4 + 8001ecc: 0002 movs r2, r0 + 8001ece: 69bb ldr r3, [r7, #24] + 8001ed0: 1ad3 subs r3, r2, r3 + 8001ed2: 2b64 cmp r3, #100 ; 0x64 + 8001ed4: d901 bls.n 8001eda + { + return HAL_TIMEOUT; + 8001ed6: 2303 movs r3, #3 + 8001ed8: e1f4 b.n 80022c4 + while(HAL_IS_BIT_CLR(PWR->CR, PWR_CR_DBP)) + 8001eda: 4b0b ldr r3, [pc, #44] ; (8001f08 ) + 8001edc: 681a ldr r2, [r3, #0] + 8001ede: 2380 movs r3, #128 ; 0x80 + 8001ee0: 005b lsls r3, r3, #1 + 8001ee2: 4013 ands r3, r2 + 8001ee4: d0f0 beq.n 8001ec8 + } + } + } + + /* Set the new LSE configuration -----------------------------------------*/ + __HAL_RCC_LSE_CONFIG(RCC_OscInitStruct->LSEState); + 8001ee6: 687b ldr r3, [r7, #4] + 8001ee8: 689b ldr r3, [r3, #8] + 8001eea: 2b01 cmp r3, #1 + 8001eec: d10e bne.n 8001f0c + 8001eee: 4b03 ldr r3, [pc, #12] ; (8001efc ) + 8001ef0: 6a1a ldr r2, [r3, #32] + 8001ef2: 4b02 ldr r3, [pc, #8] ; (8001efc ) + 8001ef4: 2101 movs r1, #1 + 8001ef6: 430a orrs r2, r1 + 8001ef8: 621a str r2, [r3, #32] + 8001efa: e035 b.n 8001f68 + 8001efc: 40021000 .word 0x40021000 + 8001f00: fffeffff .word 0xfffeffff + 8001f04: fffbffff .word 0xfffbffff + 8001f08: 40007000 .word 0x40007000 + 8001f0c: 687b ldr r3, [r7, #4] + 8001f0e: 689b ldr r3, [r3, #8] + 8001f10: 2b00 cmp r3, #0 + 8001f12: d10c bne.n 8001f2e + 8001f14: 4bca ldr r3, [pc, #808] ; (8002240 ) + 8001f16: 6a1a ldr r2, [r3, #32] + 8001f18: 4bc9 ldr r3, [pc, #804] ; (8002240 ) + 8001f1a: 2101 movs r1, #1 + 8001f1c: 438a bics r2, r1 + 8001f1e: 621a str r2, [r3, #32] + 8001f20: 4bc7 ldr r3, [pc, #796] ; (8002240 ) + 8001f22: 6a1a ldr r2, [r3, #32] + 8001f24: 4bc6 ldr r3, [pc, #792] ; (8002240 ) + 8001f26: 2104 movs r1, #4 + 8001f28: 438a bics r2, r1 + 8001f2a: 621a str r2, [r3, #32] + 8001f2c: e01c b.n 8001f68 + 8001f2e: 687b ldr r3, [r7, #4] + 8001f30: 689b ldr r3, [r3, #8] + 8001f32: 2b05 cmp r3, #5 + 8001f34: d10c bne.n 8001f50 + 8001f36: 4bc2 ldr r3, [pc, #776] ; (8002240 ) + 8001f38: 6a1a ldr r2, [r3, #32] + 8001f3a: 4bc1 ldr r3, [pc, #772] ; (8002240 ) + 8001f3c: 2104 movs r1, #4 + 8001f3e: 430a orrs r2, r1 + 8001f40: 621a str r2, [r3, #32] + 8001f42: 4bbf ldr r3, [pc, #764] ; (8002240 ) + 8001f44: 6a1a ldr r2, [r3, #32] + 8001f46: 4bbe ldr r3, [pc, #760] ; (8002240 ) + 8001f48: 2101 movs r1, #1 + 8001f4a: 430a orrs r2, r1 + 8001f4c: 621a str r2, [r3, #32] + 8001f4e: e00b b.n 8001f68 + 8001f50: 4bbb ldr r3, [pc, #748] ; (8002240 ) + 8001f52: 6a1a ldr r2, [r3, #32] + 8001f54: 4bba ldr r3, [pc, #744] ; (8002240 ) + 8001f56: 2101 movs r1, #1 + 8001f58: 438a bics r2, r1 + 8001f5a: 621a str r2, [r3, #32] + 8001f5c: 4bb8 ldr r3, [pc, #736] ; (8002240 ) + 8001f5e: 6a1a ldr r2, [r3, #32] + 8001f60: 4bb7 ldr r3, [pc, #732] ; (8002240 ) + 8001f62: 2104 movs r1, #4 + 8001f64: 438a bics r2, r1 + 8001f66: 621a str r2, [r3, #32] + /* Check the LSE State */ + if(RCC_OscInitStruct->LSEState != RCC_LSE_OFF) + 8001f68: 687b ldr r3, [r7, #4] + 8001f6a: 689b ldr r3, [r3, #8] + 8001f6c: 2b00 cmp r3, #0 + 8001f6e: d014 beq.n 8001f9a + { + /* Get Start Tick */ + tickstart = HAL_GetTick(); + 8001f70: f7fe fba8 bl 80006c4 + 8001f74: 0003 movs r3, r0 + 8001f76: 61bb str r3, [r7, #24] + + /* Wait till LSE is ready */ + while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET) + 8001f78: e009 b.n 8001f8e + { + if((HAL_GetTick() - tickstart ) > RCC_LSE_TIMEOUT_VALUE) + 8001f7a: f7fe fba3 bl 80006c4 + 8001f7e: 0002 movs r2, r0 + 8001f80: 69bb ldr r3, [r7, #24] + 8001f82: 1ad3 subs r3, r2, r3 + 8001f84: 4aaf ldr r2, [pc, #700] ; (8002244 ) + 8001f86: 4293 cmp r3, r2 + 8001f88: d901 bls.n 8001f8e + { + return HAL_TIMEOUT; + 8001f8a: 2303 movs r3, #3 + 8001f8c: e19a b.n 80022c4 + while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET) + 8001f8e: 4bac ldr r3, [pc, #688] ; (8002240 ) + 8001f90: 6a1b ldr r3, [r3, #32] + 8001f92: 2202 movs r2, #2 + 8001f94: 4013 ands r3, r2 + 8001f96: d0f0 beq.n 8001f7a + 8001f98: e013 b.n 8001fc2 + } + } + else + { + /* Get Start Tick */ + tickstart = HAL_GetTick(); + 8001f9a: f7fe fb93 bl 80006c4 + 8001f9e: 0003 movs r3, r0 + 8001fa0: 61bb str r3, [r7, #24] + + /* Wait till LSE is disabled */ + while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) != RESET) + 8001fa2: e009 b.n 8001fb8 + { + if((HAL_GetTick() - tickstart ) > RCC_LSE_TIMEOUT_VALUE) + 8001fa4: f7fe fb8e bl 80006c4 + 8001fa8: 0002 movs r2, r0 + 8001faa: 69bb ldr r3, [r7, #24] + 8001fac: 1ad3 subs r3, r2, r3 + 8001fae: 4aa5 ldr r2, [pc, #660] ; (8002244 ) + 8001fb0: 4293 cmp r3, r2 + 8001fb2: d901 bls.n 8001fb8 + { + return HAL_TIMEOUT; + 8001fb4: 2303 movs r3, #3 + 8001fb6: e185 b.n 80022c4 + while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) != RESET) + 8001fb8: 4ba1 ldr r3, [pc, #644] ; (8002240 ) + 8001fba: 6a1b ldr r3, [r3, #32] + 8001fbc: 2202 movs r2, #2 + 8001fbe: 4013 ands r3, r2 + 8001fc0: d1f0 bne.n 8001fa4 + } + } + } + + /* Require to disable power clock if necessary */ + if(pwrclkchanged == SET) + 8001fc2: 231f movs r3, #31 + 8001fc4: 18fb adds r3, r7, r3 + 8001fc6: 781b ldrb r3, [r3, #0] + 8001fc8: 2b01 cmp r3, #1 + 8001fca: d105 bne.n 8001fd8 + { + __HAL_RCC_PWR_CLK_DISABLE(); + 8001fcc: 4b9c ldr r3, [pc, #624] ; (8002240 ) + 8001fce: 69da ldr r2, [r3, #28] + 8001fd0: 4b9b ldr r3, [pc, #620] ; (8002240 ) + 8001fd2: 499d ldr r1, [pc, #628] ; (8002248 ) + 8001fd4: 400a ands r2, r1 + 8001fd6: 61da str r2, [r3, #28] + } + } + + /*----------------------------- HSI14 Configuration --------------------------*/ + if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSI14) == RCC_OSCILLATORTYPE_HSI14) + 8001fd8: 687b ldr r3, [r7, #4] + 8001fda: 681b ldr r3, [r3, #0] + 8001fdc: 2210 movs r2, #16 + 8001fde: 4013 ands r3, r2 + 8001fe0: d063 beq.n 80020aa + /* Check the parameters */ + assert_param(IS_RCC_HSI14(RCC_OscInitStruct->HSI14State)); + assert_param(IS_RCC_CALIBRATION_VALUE(RCC_OscInitStruct->HSI14CalibrationValue)); + + /* Check the HSI14 State */ + if(RCC_OscInitStruct->HSI14State == RCC_HSI14_ON) + 8001fe2: 687b ldr r3, [r7, #4] + 8001fe4: 695b ldr r3, [r3, #20] + 8001fe6: 2b01 cmp r3, #1 + 8001fe8: d12a bne.n 8002040 + { + /* Disable ADC control of the Internal High Speed oscillator HSI14 */ + __HAL_RCC_HSI14ADC_DISABLE(); + 8001fea: 4b95 ldr r3, [pc, #596] ; (8002240 ) + 8001fec: 6b5a ldr r2, [r3, #52] ; 0x34 + 8001fee: 4b94 ldr r3, [pc, #592] ; (8002240 ) + 8001ff0: 2104 movs r1, #4 + 8001ff2: 430a orrs r2, r1 + 8001ff4: 635a str r2, [r3, #52] ; 0x34 + + /* Enable the Internal High Speed oscillator (HSI). */ + __HAL_RCC_HSI14_ENABLE(); + 8001ff6: 4b92 ldr r3, [pc, #584] ; (8002240 ) + 8001ff8: 6b5a ldr r2, [r3, #52] ; 0x34 + 8001ffa: 4b91 ldr r3, [pc, #580] ; (8002240 ) + 8001ffc: 2101 movs r1, #1 + 8001ffe: 430a orrs r2, r1 + 8002000: 635a str r2, [r3, #52] ; 0x34 + + /* Get Start Tick */ + tickstart = HAL_GetTick(); + 8002002: f7fe fb5f bl 80006c4 + 8002006: 0003 movs r3, r0 + 8002008: 61bb str r3, [r7, #24] + + /* Wait till HSI is ready */ + while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSI14RDY) == RESET) + 800200a: e008 b.n 800201e + { + if((HAL_GetTick() - tickstart) > HSI14_TIMEOUT_VALUE) + 800200c: f7fe fb5a bl 80006c4 + 8002010: 0002 movs r2, r0 + 8002012: 69bb ldr r3, [r7, #24] + 8002014: 1ad3 subs r3, r2, r3 + 8002016: 2b02 cmp r3, #2 + 8002018: d901 bls.n 800201e + { + return HAL_TIMEOUT; + 800201a: 2303 movs r3, #3 + 800201c: e152 b.n 80022c4 + while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSI14RDY) == RESET) + 800201e: 4b88 ldr r3, [pc, #544] ; (8002240 ) + 8002020: 6b5b ldr r3, [r3, #52] ; 0x34 + 8002022: 2202 movs r2, #2 + 8002024: 4013 ands r3, r2 + 8002026: d0f1 beq.n 800200c + } + } + + /* Adjusts the Internal High Speed oscillator 14Mhz (HSI14) calibration value. */ + __HAL_RCC_HSI14_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->HSI14CalibrationValue); + 8002028: 4b85 ldr r3, [pc, #532] ; (8002240 ) + 800202a: 6b5b ldr r3, [r3, #52] ; 0x34 + 800202c: 22f8 movs r2, #248 ; 0xf8 + 800202e: 4393 bics r3, r2 + 8002030: 0019 movs r1, r3 + 8002032: 687b ldr r3, [r7, #4] + 8002034: 699b ldr r3, [r3, #24] + 8002036: 00da lsls r2, r3, #3 + 8002038: 4b81 ldr r3, [pc, #516] ; (8002240 ) + 800203a: 430a orrs r2, r1 + 800203c: 635a str r2, [r3, #52] ; 0x34 + 800203e: e034 b.n 80020aa + } + else if(RCC_OscInitStruct->HSI14State == RCC_HSI14_ADC_CONTROL) + 8002040: 687b ldr r3, [r7, #4] + 8002042: 695b ldr r3, [r3, #20] + 8002044: 3305 adds r3, #5 + 8002046: d111 bne.n 800206c + { + /* Enable ADC control of the Internal High Speed oscillator HSI14 */ + __HAL_RCC_HSI14ADC_ENABLE(); + 8002048: 4b7d ldr r3, [pc, #500] ; (8002240 ) + 800204a: 6b5a ldr r2, [r3, #52] ; 0x34 + 800204c: 4b7c ldr r3, [pc, #496] ; (8002240 ) + 800204e: 2104 movs r1, #4 + 8002050: 438a bics r2, r1 + 8002052: 635a str r2, [r3, #52] ; 0x34 + + /* Adjusts the Internal High Speed oscillator 14Mhz (HSI14) calibration value. */ + __HAL_RCC_HSI14_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->HSI14CalibrationValue); + 8002054: 4b7a ldr r3, [pc, #488] ; (8002240 ) + 8002056: 6b5b ldr r3, [r3, #52] ; 0x34 + 8002058: 22f8 movs r2, #248 ; 0xf8 + 800205a: 4393 bics r3, r2 + 800205c: 0019 movs r1, r3 + 800205e: 687b ldr r3, [r7, #4] + 8002060: 699b ldr r3, [r3, #24] + 8002062: 00da lsls r2, r3, #3 + 8002064: 4b76 ldr r3, [pc, #472] ; (8002240 ) + 8002066: 430a orrs r2, r1 + 8002068: 635a str r2, [r3, #52] ; 0x34 + 800206a: e01e b.n 80020aa + } + else + { + /* Disable ADC control of the Internal High Speed oscillator HSI14 */ + __HAL_RCC_HSI14ADC_DISABLE(); + 800206c: 4b74 ldr r3, [pc, #464] ; (8002240 ) + 800206e: 6b5a ldr r2, [r3, #52] ; 0x34 + 8002070: 4b73 ldr r3, [pc, #460] ; (8002240 ) + 8002072: 2104 movs r1, #4 + 8002074: 430a orrs r2, r1 + 8002076: 635a str r2, [r3, #52] ; 0x34 + + /* Disable the Internal High Speed oscillator (HSI). */ + __HAL_RCC_HSI14_DISABLE(); + 8002078: 4b71 ldr r3, [pc, #452] ; (8002240 ) + 800207a: 6b5a ldr r2, [r3, #52] ; 0x34 + 800207c: 4b70 ldr r3, [pc, #448] ; (8002240 ) + 800207e: 2101 movs r1, #1 + 8002080: 438a bics r2, r1 + 8002082: 635a str r2, [r3, #52] ; 0x34 + + /* Get Start Tick */ + tickstart = HAL_GetTick(); + 8002084: f7fe fb1e bl 80006c4 + 8002088: 0003 movs r3, r0 + 800208a: 61bb str r3, [r7, #24] + + /* Wait till HSI is ready */ + while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSI14RDY) != RESET) + 800208c: e008 b.n 80020a0 + { + if((HAL_GetTick() - tickstart) > HSI14_TIMEOUT_VALUE) + 800208e: f7fe fb19 bl 80006c4 + 8002092: 0002 movs r2, r0 + 8002094: 69bb ldr r3, [r7, #24] + 8002096: 1ad3 subs r3, r2, r3 + 8002098: 2b02 cmp r3, #2 + 800209a: d901 bls.n 80020a0 + { + return HAL_TIMEOUT; + 800209c: 2303 movs r3, #3 + 800209e: e111 b.n 80022c4 + while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSI14RDY) != RESET) + 80020a0: 4b67 ldr r3, [pc, #412] ; (8002240 ) + 80020a2: 6b5b ldr r3, [r3, #52] ; 0x34 + 80020a4: 2202 movs r2, #2 + 80020a6: 4013 ands r3, r2 + 80020a8: d1f1 bne.n 800208e + } + } + +#if defined(RCC_HSI48_SUPPORT) + /*----------------------------- HSI48 Configuration --------------------------*/ + if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSI48) == RCC_OSCILLATORTYPE_HSI48) + 80020aa: 687b ldr r3, [r7, #4] + 80020ac: 681b ldr r3, [r3, #0] + 80020ae: 2220 movs r2, #32 + 80020b0: 4013 ands r3, r2 + 80020b2: d05c beq.n 800216e + { + /* Check the parameters */ + assert_param(IS_RCC_HSI48(RCC_OscInitStruct->HSI48State)); + + /* When the HSI48 is used as system clock it is not allowed to be disabled */ + if((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_HSI48) || + 80020b4: 4b62 ldr r3, [pc, #392] ; (8002240 ) + 80020b6: 685b ldr r3, [r3, #4] + 80020b8: 220c movs r2, #12 + 80020ba: 4013 ands r3, r2 + 80020bc: 2b0c cmp r3, #12 + 80020be: d00e beq.n 80020de + ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && (__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_HSI48))) + 80020c0: 4b5f ldr r3, [pc, #380] ; (8002240 ) + 80020c2: 685b ldr r3, [r3, #4] + 80020c4: 220c movs r2, #12 + 80020c6: 4013 ands r3, r2 + if((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_HSI48) || + 80020c8: 2b08 cmp r3, #8 + 80020ca: d114 bne.n 80020f6 + ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && (__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_HSI48))) + 80020cc: 4b5c ldr r3, [pc, #368] ; (8002240 ) + 80020ce: 685a ldr r2, [r3, #4] + 80020d0: 23c0 movs r3, #192 ; 0xc0 + 80020d2: 025b lsls r3, r3, #9 + 80020d4: 401a ands r2, r3 + 80020d6: 23c0 movs r3, #192 ; 0xc0 + 80020d8: 025b lsls r3, r3, #9 + 80020da: 429a cmp r2, r3 + 80020dc: d10b bne.n 80020f6 + { + if((__HAL_RCC_GET_FLAG(RCC_FLAG_HSI48RDY) != RESET) && (RCC_OscInitStruct->HSI48State != RCC_HSI48_ON)) + 80020de: 4b58 ldr r3, [pc, #352] ; (8002240 ) + 80020e0: 6b5a ldr r2, [r3, #52] ; 0x34 + 80020e2: 2380 movs r3, #128 ; 0x80 + 80020e4: 025b lsls r3, r3, #9 + 80020e6: 4013 ands r3, r2 + 80020e8: d040 beq.n 800216c + 80020ea: 687b ldr r3, [r7, #4] + 80020ec: 6a1b ldr r3, [r3, #32] + 80020ee: 2b01 cmp r3, #1 + 80020f0: d03c beq.n 800216c + { + return HAL_ERROR; + 80020f2: 2301 movs r3, #1 + 80020f4: e0e6 b.n 80022c4 + } + } + else + { + /* Check the HSI48 State */ + if(RCC_OscInitStruct->HSI48State != RCC_HSI48_OFF) + 80020f6: 687b ldr r3, [r7, #4] + 80020f8: 6a1b ldr r3, [r3, #32] + 80020fa: 2b00 cmp r3, #0 + 80020fc: d01b beq.n 8002136 + { + /* Enable the Internal High Speed oscillator (HSI48). */ + __HAL_RCC_HSI48_ENABLE(); + 80020fe: 4b50 ldr r3, [pc, #320] ; (8002240 ) + 8002100: 6b5a ldr r2, [r3, #52] ; 0x34 + 8002102: 4b4f ldr r3, [pc, #316] ; (8002240 ) + 8002104: 2180 movs r1, #128 ; 0x80 + 8002106: 0249 lsls r1, r1, #9 + 8002108: 430a orrs r2, r1 + 800210a: 635a str r2, [r3, #52] ; 0x34 + + /* Get Start Tick */ + tickstart = HAL_GetTick(); + 800210c: f7fe fada bl 80006c4 + 8002110: 0003 movs r3, r0 + 8002112: 61bb str r3, [r7, #24] + + /* Wait till HSI48 is ready */ + while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSI48RDY) == RESET) + 8002114: e008 b.n 8002128 + { + if((HAL_GetTick() - tickstart) > HSI48_TIMEOUT_VALUE) + 8002116: f7fe fad5 bl 80006c4 + 800211a: 0002 movs r2, r0 + 800211c: 69bb ldr r3, [r7, #24] + 800211e: 1ad3 subs r3, r2, r3 + 8002120: 2b02 cmp r3, #2 + 8002122: d901 bls.n 8002128 + { + return HAL_TIMEOUT; + 8002124: 2303 movs r3, #3 + 8002126: e0cd b.n 80022c4 + while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSI48RDY) == RESET) + 8002128: 4b45 ldr r3, [pc, #276] ; (8002240 ) + 800212a: 6b5a ldr r2, [r3, #52] ; 0x34 + 800212c: 2380 movs r3, #128 ; 0x80 + 800212e: 025b lsls r3, r3, #9 + 8002130: 4013 ands r3, r2 + 8002132: d0f0 beq.n 8002116 + 8002134: e01b b.n 800216e + } + } + else + { + /* Disable the Internal High Speed oscillator (HSI48). */ + __HAL_RCC_HSI48_DISABLE(); + 8002136: 4b42 ldr r3, [pc, #264] ; (8002240 ) + 8002138: 6b5a ldr r2, [r3, #52] ; 0x34 + 800213a: 4b41 ldr r3, [pc, #260] ; (8002240 ) + 800213c: 4943 ldr r1, [pc, #268] ; (800224c ) + 800213e: 400a ands r2, r1 + 8002140: 635a str r2, [r3, #52] ; 0x34 + + /* Get Start Tick */ + tickstart = HAL_GetTick(); + 8002142: f7fe fabf bl 80006c4 + 8002146: 0003 movs r3, r0 + 8002148: 61bb str r3, [r7, #24] + + /* Wait till HSI48 is ready */ + while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSI48RDY) != RESET) + 800214a: e008 b.n 800215e + { + if((HAL_GetTick() - tickstart) > HSI48_TIMEOUT_VALUE) + 800214c: f7fe faba bl 80006c4 + 8002150: 0002 movs r2, r0 + 8002152: 69bb ldr r3, [r7, #24] + 8002154: 1ad3 subs r3, r2, r3 + 8002156: 2b02 cmp r3, #2 + 8002158: d901 bls.n 800215e + { + return HAL_TIMEOUT; + 800215a: 2303 movs r3, #3 + 800215c: e0b2 b.n 80022c4 + while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSI48RDY) != RESET) + 800215e: 4b38 ldr r3, [pc, #224] ; (8002240 ) + 8002160: 6b5a ldr r2, [r3, #52] ; 0x34 + 8002162: 2380 movs r3, #128 ; 0x80 + 8002164: 025b lsls r3, r3, #9 + 8002166: 4013 ands r3, r2 + 8002168: d1f0 bne.n 800214c + 800216a: e000 b.n 800216e + if((__HAL_RCC_GET_FLAG(RCC_FLAG_HSI48RDY) != RESET) && (RCC_OscInitStruct->HSI48State != RCC_HSI48_ON)) + 800216c: 46c0 nop ; (mov r8, r8) +#endif /* RCC_HSI48_SUPPORT */ + + /*-------------------------------- PLL Configuration -----------------------*/ + /* Check the parameters */ + assert_param(IS_RCC_PLL(RCC_OscInitStruct->PLL.PLLState)); + if ((RCC_OscInitStruct->PLL.PLLState) != RCC_PLL_NONE) + 800216e: 687b ldr r3, [r7, #4] + 8002170: 6a5b ldr r3, [r3, #36] ; 0x24 + 8002172: 2b00 cmp r3, #0 + 8002174: d100 bne.n 8002178 + 8002176: e0a4 b.n 80022c2 + { + /* Check if the PLL is used as system clock or not */ + if(__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_SYSCLKSOURCE_STATUS_PLLCLK) + 8002178: 4b31 ldr r3, [pc, #196] ; (8002240 ) + 800217a: 685b ldr r3, [r3, #4] + 800217c: 220c movs r2, #12 + 800217e: 4013 ands r3, r2 + 8002180: 2b08 cmp r3, #8 + 8002182: d100 bne.n 8002186 + 8002184: e078 b.n 8002278 + { + if((RCC_OscInitStruct->PLL.PLLState) == RCC_PLL_ON) + 8002186: 687b ldr r3, [r7, #4] + 8002188: 6a5b ldr r3, [r3, #36] ; 0x24 + 800218a: 2b02 cmp r3, #2 + 800218c: d14c bne.n 8002228 + assert_param(IS_RCC_PLLSOURCE(RCC_OscInitStruct->PLL.PLLSource)); + assert_param(IS_RCC_PLL_MUL(RCC_OscInitStruct->PLL.PLLMUL)); + assert_param(IS_RCC_PREDIV(RCC_OscInitStruct->PLL.PREDIV)); + + /* Disable the main PLL. */ + __HAL_RCC_PLL_DISABLE(); + 800218e: 4b2c ldr r3, [pc, #176] ; (8002240 ) + 8002190: 681a ldr r2, [r3, #0] + 8002192: 4b2b ldr r3, [pc, #172] ; (8002240 ) + 8002194: 492e ldr r1, [pc, #184] ; (8002250 ) + 8002196: 400a ands r2, r1 + 8002198: 601a str r2, [r3, #0] + + /* Get Start Tick */ + tickstart = HAL_GetTick(); + 800219a: f7fe fa93 bl 80006c4 + 800219e: 0003 movs r3, r0 + 80021a0: 61bb str r3, [r7, #24] + + /* Wait till PLL is disabled */ + while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) != RESET) + 80021a2: e008 b.n 80021b6 + { + if((HAL_GetTick() - tickstart ) > PLL_TIMEOUT_VALUE) + 80021a4: f7fe fa8e bl 80006c4 + 80021a8: 0002 movs r2, r0 + 80021aa: 69bb ldr r3, [r7, #24] + 80021ac: 1ad3 subs r3, r2, r3 + 80021ae: 2b02 cmp r3, #2 + 80021b0: d901 bls.n 80021b6 + { + return HAL_TIMEOUT; + 80021b2: 2303 movs r3, #3 + 80021b4: e086 b.n 80022c4 + while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) != RESET) + 80021b6: 4b22 ldr r3, [pc, #136] ; (8002240 ) + 80021b8: 681a ldr r2, [r3, #0] + 80021ba: 2380 movs r3, #128 ; 0x80 + 80021bc: 049b lsls r3, r3, #18 + 80021be: 4013 ands r3, r2 + 80021c0: d1f0 bne.n 80021a4 + } + } + + /* Configure the main PLL clock source, predivider and multiplication factor. */ + __HAL_RCC_PLL_CONFIG(RCC_OscInitStruct->PLL.PLLSource, + 80021c2: 4b1f ldr r3, [pc, #124] ; (8002240 ) + 80021c4: 6adb ldr r3, [r3, #44] ; 0x2c + 80021c6: 220f movs r2, #15 + 80021c8: 4393 bics r3, r2 + 80021ca: 0019 movs r1, r3 + 80021cc: 687b ldr r3, [r7, #4] + 80021ce: 6b1a ldr r2, [r3, #48] ; 0x30 + 80021d0: 4b1b ldr r3, [pc, #108] ; (8002240 ) + 80021d2: 430a orrs r2, r1 + 80021d4: 62da str r2, [r3, #44] ; 0x2c + 80021d6: 4b1a ldr r3, [pc, #104] ; (8002240 ) + 80021d8: 685b ldr r3, [r3, #4] + 80021da: 4a1e ldr r2, [pc, #120] ; (8002254 ) + 80021dc: 4013 ands r3, r2 + 80021de: 0019 movs r1, r3 + 80021e0: 687b ldr r3, [r7, #4] + 80021e2: 6ada ldr r2, [r3, #44] ; 0x2c + 80021e4: 687b ldr r3, [r7, #4] + 80021e6: 6a9b ldr r3, [r3, #40] ; 0x28 + 80021e8: 431a orrs r2, r3 + 80021ea: 4b15 ldr r3, [pc, #84] ; (8002240 ) + 80021ec: 430a orrs r2, r1 + 80021ee: 605a str r2, [r3, #4] + RCC_OscInitStruct->PLL.PREDIV, + RCC_OscInitStruct->PLL.PLLMUL); + /* Enable the main PLL. */ + __HAL_RCC_PLL_ENABLE(); + 80021f0: 4b13 ldr r3, [pc, #76] ; (8002240 ) + 80021f2: 681a ldr r2, [r3, #0] + 80021f4: 4b12 ldr r3, [pc, #72] ; (8002240 ) + 80021f6: 2180 movs r1, #128 ; 0x80 + 80021f8: 0449 lsls r1, r1, #17 + 80021fa: 430a orrs r2, r1 + 80021fc: 601a str r2, [r3, #0] + + /* Get Start Tick */ + tickstart = HAL_GetTick(); + 80021fe: f7fe fa61 bl 80006c4 + 8002202: 0003 movs r3, r0 + 8002204: 61bb str r3, [r7, #24] + + /* Wait till PLL is ready */ + while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) == RESET) + 8002206: e008 b.n 800221a + { + if((HAL_GetTick() - tickstart ) > PLL_TIMEOUT_VALUE) + 8002208: f7fe fa5c bl 80006c4 + 800220c: 0002 movs r2, r0 + 800220e: 69bb ldr r3, [r7, #24] + 8002210: 1ad3 subs r3, r2, r3 + 8002212: 2b02 cmp r3, #2 + 8002214: d901 bls.n 800221a + { + return HAL_TIMEOUT; + 8002216: 2303 movs r3, #3 + 8002218: e054 b.n 80022c4 + while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) == RESET) + 800221a: 4b09 ldr r3, [pc, #36] ; (8002240 ) + 800221c: 681a ldr r2, [r3, #0] + 800221e: 2380 movs r3, #128 ; 0x80 + 8002220: 049b lsls r3, r3, #18 + 8002222: 4013 ands r3, r2 + 8002224: d0f0 beq.n 8002208 + 8002226: e04c b.n 80022c2 + } + } + else + { + /* Disable the main PLL. */ + __HAL_RCC_PLL_DISABLE(); + 8002228: 4b05 ldr r3, [pc, #20] ; (8002240 ) + 800222a: 681a ldr r2, [r3, #0] + 800222c: 4b04 ldr r3, [pc, #16] ; (8002240 ) + 800222e: 4908 ldr r1, [pc, #32] ; (8002250 ) + 8002230: 400a ands r2, r1 + 8002232: 601a str r2, [r3, #0] + + /* Get Start Tick */ + tickstart = HAL_GetTick(); + 8002234: f7fe fa46 bl 80006c4 + 8002238: 0003 movs r3, r0 + 800223a: 61bb str r3, [r7, #24] + + /* Wait till PLL is disabled */ + while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) != RESET) + 800223c: e015 b.n 800226a + 800223e: 46c0 nop ; (mov r8, r8) + 8002240: 40021000 .word 0x40021000 + 8002244: 00001388 .word 0x00001388 + 8002248: efffffff .word 0xefffffff + 800224c: fffeffff .word 0xfffeffff + 8002250: feffffff .word 0xfeffffff + 8002254: ffc27fff .word 0xffc27fff + { + if((HAL_GetTick() - tickstart ) > PLL_TIMEOUT_VALUE) + 8002258: f7fe fa34 bl 80006c4 + 800225c: 0002 movs r2, r0 + 800225e: 69bb ldr r3, [r7, #24] + 8002260: 1ad3 subs r3, r2, r3 + 8002262: 2b02 cmp r3, #2 + 8002264: d901 bls.n 800226a + { + return HAL_TIMEOUT; + 8002266: 2303 movs r3, #3 + 8002268: e02c b.n 80022c4 + while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) != RESET) + 800226a: 4b18 ldr r3, [pc, #96] ; (80022cc ) + 800226c: 681a ldr r2, [r3, #0] + 800226e: 2380 movs r3, #128 ; 0x80 + 8002270: 049b lsls r3, r3, #18 + 8002272: 4013 ands r3, r2 + 8002274: d1f0 bne.n 8002258 + 8002276: e024 b.n 80022c2 + } + } + else + { + /* Check if there is a request to disable the PLL used as System clock source */ + if((RCC_OscInitStruct->PLL.PLLState) == RCC_PLL_OFF) + 8002278: 687b ldr r3, [r7, #4] + 800227a: 6a5b ldr r3, [r3, #36] ; 0x24 + 800227c: 2b01 cmp r3, #1 + 800227e: d101 bne.n 8002284 + { + return HAL_ERROR; + 8002280: 2301 movs r3, #1 + 8002282: e01f b.n 80022c4 + } + else + { + /* Do not return HAL_ERROR if request repeats the current configuration */ + pll_config = RCC->CFGR; + 8002284: 4b11 ldr r3, [pc, #68] ; (80022cc ) + 8002286: 685b ldr r3, [r3, #4] + 8002288: 617b str r3, [r7, #20] + pll_config2 = RCC->CFGR2; + 800228a: 4b10 ldr r3, [pc, #64] ; (80022cc ) + 800228c: 6adb ldr r3, [r3, #44] ; 0x2c + 800228e: 613b str r3, [r7, #16] + if((READ_BIT(pll_config, RCC_CFGR_PLLSRC) != RCC_OscInitStruct->PLL.PLLSource) || + 8002290: 697a ldr r2, [r7, #20] + 8002292: 23c0 movs r3, #192 ; 0xc0 + 8002294: 025b lsls r3, r3, #9 + 8002296: 401a ands r2, r3 + 8002298: 687b ldr r3, [r7, #4] + 800229a: 6a9b ldr r3, [r3, #40] ; 0x28 + 800229c: 429a cmp r2, r3 + 800229e: d10e bne.n 80022be + (READ_BIT(pll_config2, RCC_CFGR2_PREDIV) != RCC_OscInitStruct->PLL.PREDIV) || + 80022a0: 693b ldr r3, [r7, #16] + 80022a2: 220f movs r2, #15 + 80022a4: 401a ands r2, r3 + 80022a6: 687b ldr r3, [r7, #4] + 80022a8: 6b1b ldr r3, [r3, #48] ; 0x30 + if((READ_BIT(pll_config, RCC_CFGR_PLLSRC) != RCC_OscInitStruct->PLL.PLLSource) || + 80022aa: 429a cmp r2, r3 + 80022ac: d107 bne.n 80022be + (READ_BIT(pll_config, RCC_CFGR_PLLMUL) != RCC_OscInitStruct->PLL.PLLMUL)) + 80022ae: 697a ldr r2, [r7, #20] + 80022b0: 23f0 movs r3, #240 ; 0xf0 + 80022b2: 039b lsls r3, r3, #14 + 80022b4: 401a ands r2, r3 + 80022b6: 687b ldr r3, [r7, #4] + 80022b8: 6adb ldr r3, [r3, #44] ; 0x2c + (READ_BIT(pll_config2, RCC_CFGR2_PREDIV) != RCC_OscInitStruct->PLL.PREDIV) || + 80022ba: 429a cmp r2, r3 + 80022bc: d001 beq.n 80022c2 + { + return HAL_ERROR; + 80022be: 2301 movs r3, #1 + 80022c0: e000 b.n 80022c4 + } + } + } + } + + return HAL_OK; + 80022c2: 2300 movs r3, #0 +} + 80022c4: 0018 movs r0, r3 + 80022c6: 46bd mov sp, r7 + 80022c8: b008 add sp, #32 + 80022ca: bd80 pop {r7, pc} + 80022cc: 40021000 .word 0x40021000 + +080022d0 : + * You can use @ref HAL_RCC_GetClockConfig() function to know which clock is + * currently used as system clock source. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RCC_ClockConfig(RCC_ClkInitTypeDef *RCC_ClkInitStruct, uint32_t FLatency) +{ + 80022d0: b580 push {r7, lr} + 80022d2: b084 sub sp, #16 + 80022d4: af00 add r7, sp, #0 + 80022d6: 6078 str r0, [r7, #4] + 80022d8: 6039 str r1, [r7, #0] + uint32_t tickstart; + + /* Check Null pointer */ + if(RCC_ClkInitStruct == NULL) + 80022da: 687b ldr r3, [r7, #4] + 80022dc: 2b00 cmp r3, #0 + 80022de: d101 bne.n 80022e4 + { + return HAL_ERROR; + 80022e0: 2301 movs r3, #1 + 80022e2: e0bf b.n 8002464 + /* To correctly read data from FLASH memory, the number of wait states (LATENCY) + must be correctly programmed according to the frequency of the CPU clock + (HCLK) of the device. */ + + /* Increasing the number of wait states because of higher CPU frequency */ + if(FLatency > __HAL_FLASH_GET_LATENCY()) + 80022e4: 4b61 ldr r3, [pc, #388] ; (800246c ) + 80022e6: 681b ldr r3, [r3, #0] + 80022e8: 2201 movs r2, #1 + 80022ea: 4013 ands r3, r2 + 80022ec: 683a ldr r2, [r7, #0] + 80022ee: 429a cmp r2, r3 + 80022f0: d911 bls.n 8002316 + { + /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */ + __HAL_FLASH_SET_LATENCY(FLatency); + 80022f2: 4b5e ldr r3, [pc, #376] ; (800246c ) + 80022f4: 681b ldr r3, [r3, #0] + 80022f6: 2201 movs r2, #1 + 80022f8: 4393 bics r3, r2 + 80022fa: 0019 movs r1, r3 + 80022fc: 4b5b ldr r3, [pc, #364] ; (800246c ) + 80022fe: 683a ldr r2, [r7, #0] + 8002300: 430a orrs r2, r1 + 8002302: 601a str r2, [r3, #0] + + /* Check that the new number of wait states is taken into account to access the Flash + memory by reading the FLASH_ACR register */ + if(__HAL_FLASH_GET_LATENCY() != FLatency) + 8002304: 4b59 ldr r3, [pc, #356] ; (800246c ) + 8002306: 681b ldr r3, [r3, #0] + 8002308: 2201 movs r2, #1 + 800230a: 4013 ands r3, r2 + 800230c: 683a ldr r2, [r7, #0] + 800230e: 429a cmp r2, r3 + 8002310: d001 beq.n 8002316 + { + return HAL_ERROR; + 8002312: 2301 movs r3, #1 + 8002314: e0a6 b.n 8002464 + } + } + + /*-------------------------- HCLK Configuration --------------------------*/ + if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_HCLK) == RCC_CLOCKTYPE_HCLK) + 8002316: 687b ldr r3, [r7, #4] + 8002318: 681b ldr r3, [r3, #0] + 800231a: 2202 movs r2, #2 + 800231c: 4013 ands r3, r2 + 800231e: d015 beq.n 800234c + { + /* Set the highest APB divider in order to ensure that we do not go through + a non-spec phase whatever we decrease or increase HCLK. */ + if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK1) == RCC_CLOCKTYPE_PCLK1) + 8002320: 687b ldr r3, [r7, #4] + 8002322: 681b ldr r3, [r3, #0] + 8002324: 2204 movs r2, #4 + 8002326: 4013 ands r3, r2 + 8002328: d006 beq.n 8002338 + { + MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE, RCC_HCLK_DIV16); + 800232a: 4b51 ldr r3, [pc, #324] ; (8002470 ) + 800232c: 685a ldr r2, [r3, #4] + 800232e: 4b50 ldr r3, [pc, #320] ; (8002470 ) + 8002330: 21e0 movs r1, #224 ; 0xe0 + 8002332: 00c9 lsls r1, r1, #3 + 8002334: 430a orrs r2, r1 + 8002336: 605a str r2, [r3, #4] + } + + /* Set the new HCLK clock divider */ + assert_param(IS_RCC_HCLK(RCC_ClkInitStruct->AHBCLKDivider)); + MODIFY_REG(RCC->CFGR, RCC_CFGR_HPRE, RCC_ClkInitStruct->AHBCLKDivider); + 8002338: 4b4d ldr r3, [pc, #308] ; (8002470 ) + 800233a: 685b ldr r3, [r3, #4] + 800233c: 22f0 movs r2, #240 ; 0xf0 + 800233e: 4393 bics r3, r2 + 8002340: 0019 movs r1, r3 + 8002342: 687b ldr r3, [r7, #4] + 8002344: 689a ldr r2, [r3, #8] + 8002346: 4b4a ldr r3, [pc, #296] ; (8002470 ) + 8002348: 430a orrs r2, r1 + 800234a: 605a str r2, [r3, #4] + } + + /*------------------------- SYSCLK Configuration ---------------------------*/ + if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_SYSCLK) == RCC_CLOCKTYPE_SYSCLK) + 800234c: 687b ldr r3, [r7, #4] + 800234e: 681b ldr r3, [r3, #0] + 8002350: 2201 movs r2, #1 + 8002352: 4013 ands r3, r2 + 8002354: d04c beq.n 80023f0 + { + assert_param(IS_RCC_SYSCLKSOURCE(RCC_ClkInitStruct->SYSCLKSource)); + + /* HSE is selected as System Clock Source */ + if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_HSE) + 8002356: 687b ldr r3, [r7, #4] + 8002358: 685b ldr r3, [r3, #4] + 800235a: 2b01 cmp r3, #1 + 800235c: d107 bne.n 800236e + { + /* Check the HSE ready flag */ + if(__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) == RESET) + 800235e: 4b44 ldr r3, [pc, #272] ; (8002470 ) + 8002360: 681a ldr r2, [r3, #0] + 8002362: 2380 movs r3, #128 ; 0x80 + 8002364: 029b lsls r3, r3, #10 + 8002366: 4013 ands r3, r2 + 8002368: d120 bne.n 80023ac + { + return HAL_ERROR; + 800236a: 2301 movs r3, #1 + 800236c: e07a b.n 8002464 + } + } + /* PLL is selected as System Clock Source */ + else if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_PLLCLK) + 800236e: 687b ldr r3, [r7, #4] + 8002370: 685b ldr r3, [r3, #4] + 8002372: 2b02 cmp r3, #2 + 8002374: d107 bne.n 8002386 + { + /* Check the PLL ready flag */ + if(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) == RESET) + 8002376: 4b3e ldr r3, [pc, #248] ; (8002470 ) + 8002378: 681a ldr r2, [r3, #0] + 800237a: 2380 movs r3, #128 ; 0x80 + 800237c: 049b lsls r3, r3, #18 + 800237e: 4013 ands r3, r2 + 8002380: d114 bne.n 80023ac + { + return HAL_ERROR; + 8002382: 2301 movs r3, #1 + 8002384: e06e b.n 8002464 + } + } +#if defined(RCC_CFGR_SWS_HSI48) + /* HSI48 is selected as System Clock Source */ + else if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_HSI48) + 8002386: 687b ldr r3, [r7, #4] + 8002388: 685b ldr r3, [r3, #4] + 800238a: 2b03 cmp r3, #3 + 800238c: d107 bne.n 800239e + { + /* Check the HSI48 ready flag */ + if(__HAL_RCC_GET_FLAG(RCC_FLAG_HSI48RDY) == RESET) + 800238e: 4b38 ldr r3, [pc, #224] ; (8002470 ) + 8002390: 6b5a ldr r2, [r3, #52] ; 0x34 + 8002392: 2380 movs r3, #128 ; 0x80 + 8002394: 025b lsls r3, r3, #9 + 8002396: 4013 ands r3, r2 + 8002398: d108 bne.n 80023ac + { + return HAL_ERROR; + 800239a: 2301 movs r3, #1 + 800239c: e062 b.n 8002464 +#endif /* RCC_CFGR_SWS_HSI48 */ + /* HSI is selected as System Clock Source */ + else + { + /* Check the HSI ready flag */ + if(__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) == RESET) + 800239e: 4b34 ldr r3, [pc, #208] ; (8002470 ) + 80023a0: 681b ldr r3, [r3, #0] + 80023a2: 2202 movs r2, #2 + 80023a4: 4013 ands r3, r2 + 80023a6: d101 bne.n 80023ac + { + return HAL_ERROR; + 80023a8: 2301 movs r3, #1 + 80023aa: e05b b.n 8002464 + } + } + __HAL_RCC_SYSCLK_CONFIG(RCC_ClkInitStruct->SYSCLKSource); + 80023ac: 4b30 ldr r3, [pc, #192] ; (8002470 ) + 80023ae: 685b ldr r3, [r3, #4] + 80023b0: 2203 movs r2, #3 + 80023b2: 4393 bics r3, r2 + 80023b4: 0019 movs r1, r3 + 80023b6: 687b ldr r3, [r7, #4] + 80023b8: 685a ldr r2, [r3, #4] + 80023ba: 4b2d ldr r3, [pc, #180] ; (8002470 ) + 80023bc: 430a orrs r2, r1 + 80023be: 605a str r2, [r3, #4] + + /* Get Start Tick */ + tickstart = HAL_GetTick(); + 80023c0: f7fe f980 bl 80006c4 + 80023c4: 0003 movs r3, r0 + 80023c6: 60fb str r3, [r7, #12] + + while (__HAL_RCC_GET_SYSCLK_SOURCE() != (RCC_ClkInitStruct->SYSCLKSource << RCC_CFGR_SWS_Pos)) + 80023c8: e009 b.n 80023de + { + if((HAL_GetTick() - tickstart ) > CLOCKSWITCH_TIMEOUT_VALUE) + 80023ca: f7fe f97b bl 80006c4 + 80023ce: 0002 movs r2, r0 + 80023d0: 68fb ldr r3, [r7, #12] + 80023d2: 1ad3 subs r3, r2, r3 + 80023d4: 4a27 ldr r2, [pc, #156] ; (8002474 ) + 80023d6: 4293 cmp r3, r2 + 80023d8: d901 bls.n 80023de + { + return HAL_TIMEOUT; + 80023da: 2303 movs r3, #3 + 80023dc: e042 b.n 8002464 + while (__HAL_RCC_GET_SYSCLK_SOURCE() != (RCC_ClkInitStruct->SYSCLKSource << RCC_CFGR_SWS_Pos)) + 80023de: 4b24 ldr r3, [pc, #144] ; (8002470 ) + 80023e0: 685b ldr r3, [r3, #4] + 80023e2: 220c movs r2, #12 + 80023e4: 401a ands r2, r3 + 80023e6: 687b ldr r3, [r7, #4] + 80023e8: 685b ldr r3, [r3, #4] + 80023ea: 009b lsls r3, r3, #2 + 80023ec: 429a cmp r2, r3 + 80023ee: d1ec bne.n 80023ca + } + } + } + + /* Decreasing the number of wait states because of lower CPU frequency */ + if(FLatency < __HAL_FLASH_GET_LATENCY()) + 80023f0: 4b1e ldr r3, [pc, #120] ; (800246c ) + 80023f2: 681b ldr r3, [r3, #0] + 80023f4: 2201 movs r2, #1 + 80023f6: 4013 ands r3, r2 + 80023f8: 683a ldr r2, [r7, #0] + 80023fa: 429a cmp r2, r3 + 80023fc: d211 bcs.n 8002422 + { + /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */ + __HAL_FLASH_SET_LATENCY(FLatency); + 80023fe: 4b1b ldr r3, [pc, #108] ; (800246c ) + 8002400: 681b ldr r3, [r3, #0] + 8002402: 2201 movs r2, #1 + 8002404: 4393 bics r3, r2 + 8002406: 0019 movs r1, r3 + 8002408: 4b18 ldr r3, [pc, #96] ; (800246c ) + 800240a: 683a ldr r2, [r7, #0] + 800240c: 430a orrs r2, r1 + 800240e: 601a str r2, [r3, #0] + + /* Check that the new number of wait states is taken into account to access the Flash + memory by reading the FLASH_ACR register */ + if(__HAL_FLASH_GET_LATENCY() != FLatency) + 8002410: 4b16 ldr r3, [pc, #88] ; (800246c ) + 8002412: 681b ldr r3, [r3, #0] + 8002414: 2201 movs r2, #1 + 8002416: 4013 ands r3, r2 + 8002418: 683a ldr r2, [r7, #0] + 800241a: 429a cmp r2, r3 + 800241c: d001 beq.n 8002422 + { + return HAL_ERROR; + 800241e: 2301 movs r3, #1 + 8002420: e020 b.n 8002464 + } + } + + /*-------------------------- PCLK1 Configuration ---------------------------*/ + if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK1) == RCC_CLOCKTYPE_PCLK1) + 8002422: 687b ldr r3, [r7, #4] + 8002424: 681b ldr r3, [r3, #0] + 8002426: 2204 movs r2, #4 + 8002428: 4013 ands r3, r2 + 800242a: d009 beq.n 8002440 + { + assert_param(IS_RCC_PCLK(RCC_ClkInitStruct->APB1CLKDivider)); + MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE, RCC_ClkInitStruct->APB1CLKDivider); + 800242c: 4b10 ldr r3, [pc, #64] ; (8002470 ) + 800242e: 685b ldr r3, [r3, #4] + 8002430: 4a11 ldr r2, [pc, #68] ; (8002478 ) + 8002432: 4013 ands r3, r2 + 8002434: 0019 movs r1, r3 + 8002436: 687b ldr r3, [r7, #4] + 8002438: 68da ldr r2, [r3, #12] + 800243a: 4b0d ldr r3, [pc, #52] ; (8002470 ) + 800243c: 430a orrs r2, r1 + 800243e: 605a str r2, [r3, #4] + } + + /* Update the SystemCoreClock global variable */ + SystemCoreClock = HAL_RCC_GetSysClockFreq() >> AHBPrescTable[(RCC->CFGR & RCC_CFGR_HPRE)>> RCC_CFGR_HPRE_BITNUMBER]; + 8002440: f000 f820 bl 8002484 + 8002444: 0001 movs r1, r0 + 8002446: 4b0a ldr r3, [pc, #40] ; (8002470 ) + 8002448: 685b ldr r3, [r3, #4] + 800244a: 091b lsrs r3, r3, #4 + 800244c: 220f movs r2, #15 + 800244e: 4013 ands r3, r2 + 8002450: 4a0a ldr r2, [pc, #40] ; (800247c ) + 8002452: 5cd3 ldrb r3, [r2, r3] + 8002454: 000a movs r2, r1 + 8002456: 40da lsrs r2, r3 + 8002458: 4b09 ldr r3, [pc, #36] ; (8002480 ) + 800245a: 601a str r2, [r3, #0] + + /* Configure the source of time base considering new system clocks settings*/ + HAL_InitTick (TICK_INT_PRIORITY); + 800245c: 2000 movs r0, #0 + 800245e: f7fe f8eb bl 8000638 + + return HAL_OK; + 8002462: 2300 movs r3, #0 +} + 8002464: 0018 movs r0, r3 + 8002466: 46bd mov sp, r7 + 8002468: b004 add sp, #16 + 800246a: bd80 pop {r7, pc} + 800246c: 40022000 .word 0x40022000 + 8002470: 40021000 .word 0x40021000 + 8002474: 00001388 .word 0x00001388 + 8002478: fffff8ff .word 0xfffff8ff + 800247c: 0800fd28 .word 0x0800fd28 + 8002480: 20000000 .word 0x20000000 + +08002484 : + * right SYSCLK value. Otherwise, any configuration based on this function will be incorrect. + * + * @retval SYSCLK frequency + */ +uint32_t HAL_RCC_GetSysClockFreq(void) +{ + 8002484: b590 push {r4, r7, lr} + 8002486: b08f sub sp, #60 ; 0x3c + 8002488: af00 add r7, sp, #0 + const uint8_t aPLLMULFactorTable[16] = { 2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, + 800248a: 2314 movs r3, #20 + 800248c: 18fb adds r3, r7, r3 + 800248e: 4a37 ldr r2, [pc, #220] ; (800256c ) + 8002490: ca13 ldmia r2!, {r0, r1, r4} + 8002492: c313 stmia r3!, {r0, r1, r4} + 8002494: 6812 ldr r2, [r2, #0] + 8002496: 601a str r2, [r3, #0] + 10U, 11U, 12U, 13U, 14U, 15U, 16U, 16U}; + const uint8_t aPredivFactorTable[16] = { 1U, 2U, 3U, 4U, 5U, 6U, 7U, 8U, + 8002498: 1d3b adds r3, r7, #4 + 800249a: 4a35 ldr r2, [pc, #212] ; (8002570 ) + 800249c: ca13 ldmia r2!, {r0, r1, r4} + 800249e: c313 stmia r3!, {r0, r1, r4} + 80024a0: 6812 ldr r2, [r2, #0] + 80024a2: 601a str r2, [r3, #0] + 9U,10U, 11U, 12U, 13U, 14U, 15U, 16U}; + + uint32_t tmpreg = 0U, prediv = 0U, pllclk = 0U, pllmul = 0U; + 80024a4: 2300 movs r3, #0 + 80024a6: 62fb str r3, [r7, #44] ; 0x2c + 80024a8: 2300 movs r3, #0 + 80024aa: 62bb str r3, [r7, #40] ; 0x28 + 80024ac: 2300 movs r3, #0 + 80024ae: 637b str r3, [r7, #52] ; 0x34 + 80024b0: 2300 movs r3, #0 + 80024b2: 627b str r3, [r7, #36] ; 0x24 + uint32_t sysclockfreq = 0U; + 80024b4: 2300 movs r3, #0 + 80024b6: 633b str r3, [r7, #48] ; 0x30 + + tmpreg = RCC->CFGR; + 80024b8: 4b2e ldr r3, [pc, #184] ; (8002574 ) + 80024ba: 685b ldr r3, [r3, #4] + 80024bc: 62fb str r3, [r7, #44] ; 0x2c + + /* Get SYSCLK source -------------------------------------------------------*/ + switch (tmpreg & RCC_CFGR_SWS) + 80024be: 6afb ldr r3, [r7, #44] ; 0x2c + 80024c0: 220c movs r2, #12 + 80024c2: 4013 ands r3, r2 + 80024c4: 2b08 cmp r3, #8 + 80024c6: d006 beq.n 80024d6 + 80024c8: 2b0c cmp r3, #12 + 80024ca: d043 beq.n 8002554 + 80024cc: 2b04 cmp r3, #4 + 80024ce: d144 bne.n 800255a + { + case RCC_SYSCLKSOURCE_STATUS_HSE: /* HSE used as system clock */ + { + sysclockfreq = HSE_VALUE; + 80024d0: 4b29 ldr r3, [pc, #164] ; (8002578 ) + 80024d2: 633b str r3, [r7, #48] ; 0x30 + break; + 80024d4: e044 b.n 8002560 + } + case RCC_SYSCLKSOURCE_STATUS_PLLCLK: /* PLL used as system clock */ + { + pllmul = aPLLMULFactorTable[(uint32_t)(tmpreg & RCC_CFGR_PLLMUL) >> RCC_CFGR_PLLMUL_BITNUMBER]; + 80024d6: 6afb ldr r3, [r7, #44] ; 0x2c + 80024d8: 0c9b lsrs r3, r3, #18 + 80024da: 220f movs r2, #15 + 80024dc: 4013 ands r3, r2 + 80024de: 2214 movs r2, #20 + 80024e0: 18ba adds r2, r7, r2 + 80024e2: 5cd3 ldrb r3, [r2, r3] + 80024e4: 627b str r3, [r7, #36] ; 0x24 + prediv = aPredivFactorTable[(uint32_t)(RCC->CFGR2 & RCC_CFGR2_PREDIV) >> RCC_CFGR2_PREDIV_BITNUMBER]; + 80024e6: 4b23 ldr r3, [pc, #140] ; (8002574 ) + 80024e8: 6adb ldr r3, [r3, #44] ; 0x2c + 80024ea: 220f movs r2, #15 + 80024ec: 4013 ands r3, r2 + 80024ee: 1d3a adds r2, r7, #4 + 80024f0: 5cd3 ldrb r3, [r2, r3] + 80024f2: 62bb str r3, [r7, #40] ; 0x28 + if ((tmpreg & RCC_CFGR_PLLSRC) == RCC_PLLSOURCE_HSE) + 80024f4: 6afa ldr r2, [r7, #44] ; 0x2c + 80024f6: 23c0 movs r3, #192 ; 0xc0 + 80024f8: 025b lsls r3, r3, #9 + 80024fa: 401a ands r2, r3 + 80024fc: 2380 movs r3, #128 ; 0x80 + 80024fe: 025b lsls r3, r3, #9 + 8002500: 429a cmp r2, r3 + 8002502: d109 bne.n 8002518 + { + /* HSE used as PLL clock source : PLLCLK = HSE/PREDIV * PLLMUL */ + pllclk = (uint32_t)((uint64_t) HSE_VALUE / (uint64_t) (prediv)) * ((uint64_t) pllmul); + 8002504: 6ab9 ldr r1, [r7, #40] ; 0x28 + 8002506: 481c ldr r0, [pc, #112] ; (8002578 ) + 8002508: f7fd fe10 bl 800012c <__udivsi3> + 800250c: 0003 movs r3, r0 + 800250e: 001a movs r2, r3 + 8002510: 6a7b ldr r3, [r7, #36] ; 0x24 + 8002512: 4353 muls r3, r2 + 8002514: 637b str r3, [r7, #52] ; 0x34 + 8002516: e01a b.n 800254e + } +#if defined(RCC_CFGR_PLLSRC_HSI48_PREDIV) + else if ((tmpreg & RCC_CFGR_PLLSRC) == RCC_PLLSOURCE_HSI48) + 8002518: 6afa ldr r2, [r7, #44] ; 0x2c + 800251a: 23c0 movs r3, #192 ; 0xc0 + 800251c: 025b lsls r3, r3, #9 + 800251e: 401a ands r2, r3 + 8002520: 23c0 movs r3, #192 ; 0xc0 + 8002522: 025b lsls r3, r3, #9 + 8002524: 429a cmp r2, r3 + 8002526: d109 bne.n 800253c + { + /* HSI48 used as PLL clock source : PLLCLK = HSI48/PREDIV * PLLMUL */ + pllclk = (uint32_t)((uint64_t) HSI48_VALUE / (uint64_t) (prediv)) * ((uint64_t) pllmul); + 8002528: 6ab9 ldr r1, [r7, #40] ; 0x28 + 800252a: 4814 ldr r0, [pc, #80] ; (800257c ) + 800252c: f7fd fdfe bl 800012c <__udivsi3> + 8002530: 0003 movs r3, r0 + 8002532: 001a movs r2, r3 + 8002534: 6a7b ldr r3, [r7, #36] ; 0x24 + 8002536: 4353 muls r3, r2 + 8002538: 637b str r3, [r7, #52] ; 0x34 + 800253a: e008 b.n 800254e +#endif /* RCC_CFGR_PLLSRC_HSI48_PREDIV */ + else + { +#if (defined(STM32F042x6) || defined(STM32F048xx) || defined(STM32F070x6) || defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F078xx) || defined(STM32F070xB) || defined(STM32F091xC) || defined(STM32F098xx) || defined(STM32F030xC)) + /* HSI used as PLL clock source : PLLCLK = HSI/PREDIV * PLLMUL */ + pllclk = (uint32_t)((uint64_t) HSI_VALUE / (uint64_t) (prediv)) * ((uint64_t) pllmul); + 800253c: 6ab9 ldr r1, [r7, #40] ; 0x28 + 800253e: 480e ldr r0, [pc, #56] ; (8002578 ) + 8002540: f7fd fdf4 bl 800012c <__udivsi3> + 8002544: 0003 movs r3, r0 + 8002546: 001a movs r2, r3 + 8002548: 6a7b ldr r3, [r7, #36] ; 0x24 + 800254a: 4353 muls r3, r2 + 800254c: 637b str r3, [r7, #52] ; 0x34 +#else + /* HSI used as PLL clock source : PLLCLK = HSI/2 * PLLMUL */ + pllclk = (uint32_t)((uint64_t) (HSI_VALUE >> 1U) * ((uint64_t) pllmul)); +#endif + } + sysclockfreq = pllclk; + 800254e: 6b7b ldr r3, [r7, #52] ; 0x34 + 8002550: 633b str r3, [r7, #48] ; 0x30 + break; + 8002552: e005 b.n 8002560 + } +#if defined(RCC_CFGR_SWS_HSI48) + case RCC_SYSCLKSOURCE_STATUS_HSI48: /* HSI48 used as system clock source */ + { + sysclockfreq = HSI48_VALUE; + 8002554: 4b09 ldr r3, [pc, #36] ; (800257c ) + 8002556: 633b str r3, [r7, #48] ; 0x30 + break; + 8002558: e002 b.n 8002560 + } +#endif /* RCC_CFGR_SWS_HSI48 */ + case RCC_SYSCLKSOURCE_STATUS_HSI: /* HSI used as system clock source */ + default: /* HSI used as system clock */ + { + sysclockfreq = HSI_VALUE; + 800255a: 4b07 ldr r3, [pc, #28] ; (8002578 ) + 800255c: 633b str r3, [r7, #48] ; 0x30 + break; + 800255e: 46c0 nop ; (mov r8, r8) + } + } + return sysclockfreq; + 8002560: 6b3b ldr r3, [r7, #48] ; 0x30 +} + 8002562: 0018 movs r0, r3 + 8002564: 46bd mov sp, r7 + 8002566: b00f add sp, #60 ; 0x3c + 8002568: bd90 pop {r4, r7, pc} + 800256a: 46c0 nop ; (mov r8, r8) + 800256c: 0800fcdc .word 0x0800fcdc + 8002570: 0800fcec .word 0x0800fcec + 8002574: 40021000 .word 0x40021000 + 8002578: 007a1200 .word 0x007a1200 + 800257c: 02dc6c00 .word 0x02dc6c00 + +08002580 : + * the backup registers) and RCC_BDCR register are set to their reset values. + * + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit) +{ + 8002580: b580 push {r7, lr} + 8002582: b086 sub sp, #24 + 8002584: af00 add r7, sp, #0 + 8002586: 6078 str r0, [r7, #4] + uint32_t tickstart = 0U; + 8002588: 2300 movs r3, #0 + 800258a: 613b str r3, [r7, #16] + uint32_t temp_reg = 0U; + 800258c: 2300 movs r3, #0 + 800258e: 60fb str r3, [r7, #12] + + /* Check the parameters */ + assert_param(IS_RCC_PERIPHCLOCK(PeriphClkInit->PeriphClockSelection)); + + /*---------------------------- RTC configuration -------------------------------*/ + if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_RTC) == (RCC_PERIPHCLK_RTC)) + 8002590: 687b ldr r3, [r7, #4] + 8002592: 681a ldr r2, [r3, #0] + 8002594: 2380 movs r3, #128 ; 0x80 + 8002596: 025b lsls r3, r3, #9 + 8002598: 4013 ands r3, r2 + 800259a: d100 bne.n 800259e + 800259c: e08f b.n 80026be + { + /* check for RTC Parameters used to output RTCCLK */ + assert_param(IS_RCC_RTCCLKSOURCE(PeriphClkInit->RTCClockSelection)); + + FlagStatus pwrclkchanged = RESET; + 800259e: 2317 movs r3, #23 + 80025a0: 18fb adds r3, r7, r3 + 80025a2: 2200 movs r2, #0 + 80025a4: 701a strb r2, [r3, #0] + + /* As soon as function is called to change RTC clock source, activation of the + power domain is done. */ + /* Requires to enable write access to Backup Domain of necessary */ + if(__HAL_RCC_PWR_IS_CLK_DISABLED()) + 80025a6: 4b6f ldr r3, [pc, #444] ; (8002764 ) + 80025a8: 69da ldr r2, [r3, #28] + 80025aa: 2380 movs r3, #128 ; 0x80 + 80025ac: 055b lsls r3, r3, #21 + 80025ae: 4013 ands r3, r2 + 80025b0: d111 bne.n 80025d6 + { + __HAL_RCC_PWR_CLK_ENABLE(); + 80025b2: 4b6c ldr r3, [pc, #432] ; (8002764 ) + 80025b4: 69da ldr r2, [r3, #28] + 80025b6: 4b6b ldr r3, [pc, #428] ; (8002764 ) + 80025b8: 2180 movs r1, #128 ; 0x80 + 80025ba: 0549 lsls r1, r1, #21 + 80025bc: 430a orrs r2, r1 + 80025be: 61da str r2, [r3, #28] + 80025c0: 4b68 ldr r3, [pc, #416] ; (8002764 ) + 80025c2: 69da ldr r2, [r3, #28] + 80025c4: 2380 movs r3, #128 ; 0x80 + 80025c6: 055b lsls r3, r3, #21 + 80025c8: 4013 ands r3, r2 + 80025ca: 60bb str r3, [r7, #8] + 80025cc: 68bb ldr r3, [r7, #8] + pwrclkchanged = SET; + 80025ce: 2317 movs r3, #23 + 80025d0: 18fb adds r3, r7, r3 + 80025d2: 2201 movs r2, #1 + 80025d4: 701a strb r2, [r3, #0] + } + + if(HAL_IS_BIT_CLR(PWR->CR, PWR_CR_DBP)) + 80025d6: 4b64 ldr r3, [pc, #400] ; (8002768 ) + 80025d8: 681a ldr r2, [r3, #0] + 80025da: 2380 movs r3, #128 ; 0x80 + 80025dc: 005b lsls r3, r3, #1 + 80025de: 4013 ands r3, r2 + 80025e0: d11a bne.n 8002618 + { + /* Enable write access to Backup domain */ + SET_BIT(PWR->CR, PWR_CR_DBP); + 80025e2: 4b61 ldr r3, [pc, #388] ; (8002768 ) + 80025e4: 681a ldr r2, [r3, #0] + 80025e6: 4b60 ldr r3, [pc, #384] ; (8002768 ) + 80025e8: 2180 movs r1, #128 ; 0x80 + 80025ea: 0049 lsls r1, r1, #1 + 80025ec: 430a orrs r2, r1 + 80025ee: 601a str r2, [r3, #0] + + /* Wait for Backup domain Write protection disable */ + tickstart = HAL_GetTick(); + 80025f0: f7fe f868 bl 80006c4 + 80025f4: 0003 movs r3, r0 + 80025f6: 613b str r3, [r7, #16] + + while(HAL_IS_BIT_CLR(PWR->CR, PWR_CR_DBP)) + 80025f8: e008 b.n 800260c + { + if((HAL_GetTick() - tickstart) > RCC_DBP_TIMEOUT_VALUE) + 80025fa: f7fe f863 bl 80006c4 + 80025fe: 0002 movs r2, r0 + 8002600: 693b ldr r3, [r7, #16] + 8002602: 1ad3 subs r3, r2, r3 + 8002604: 2b64 cmp r3, #100 ; 0x64 + 8002606: d901 bls.n 800260c + { + return HAL_TIMEOUT; + 8002608: 2303 movs r3, #3 + 800260a: e0a6 b.n 800275a + while(HAL_IS_BIT_CLR(PWR->CR, PWR_CR_DBP)) + 800260c: 4b56 ldr r3, [pc, #344] ; (8002768 ) + 800260e: 681a ldr r2, [r3, #0] + 8002610: 2380 movs r3, #128 ; 0x80 + 8002612: 005b lsls r3, r3, #1 + 8002614: 4013 ands r3, r2 + 8002616: d0f0 beq.n 80025fa + } + } + } + + /* Reset the Backup domain only if the RTC Clock source selection is modified from reset value */ + temp_reg = (RCC->BDCR & RCC_BDCR_RTCSEL); + 8002618: 4b52 ldr r3, [pc, #328] ; (8002764 ) + 800261a: 6a1a ldr r2, [r3, #32] + 800261c: 23c0 movs r3, #192 ; 0xc0 + 800261e: 009b lsls r3, r3, #2 + 8002620: 4013 ands r3, r2 + 8002622: 60fb str r3, [r7, #12] + if((temp_reg != 0x00000000U) && (temp_reg != (PeriphClkInit->RTCClockSelection & RCC_BDCR_RTCSEL))) + 8002624: 68fb ldr r3, [r7, #12] + 8002626: 2b00 cmp r3, #0 + 8002628: d034 beq.n 8002694 + 800262a: 687b ldr r3, [r7, #4] + 800262c: 685a ldr r2, [r3, #4] + 800262e: 23c0 movs r3, #192 ; 0xc0 + 8002630: 009b lsls r3, r3, #2 + 8002632: 4013 ands r3, r2 + 8002634: 68fa ldr r2, [r7, #12] + 8002636: 429a cmp r2, r3 + 8002638: d02c beq.n 8002694 + { + /* Store the content of BDCR register before the reset of Backup Domain */ + temp_reg = (RCC->BDCR & ~(RCC_BDCR_RTCSEL)); + 800263a: 4b4a ldr r3, [pc, #296] ; (8002764 ) + 800263c: 6a1b ldr r3, [r3, #32] + 800263e: 4a4b ldr r2, [pc, #300] ; (800276c ) + 8002640: 4013 ands r3, r2 + 8002642: 60fb str r3, [r7, #12] + /* RTC Clock selection can be changed only if the Backup Domain is reset */ + __HAL_RCC_BACKUPRESET_FORCE(); + 8002644: 4b47 ldr r3, [pc, #284] ; (8002764 ) + 8002646: 6a1a ldr r2, [r3, #32] + 8002648: 4b46 ldr r3, [pc, #280] ; (8002764 ) + 800264a: 2180 movs r1, #128 ; 0x80 + 800264c: 0249 lsls r1, r1, #9 + 800264e: 430a orrs r2, r1 + 8002650: 621a str r2, [r3, #32] + __HAL_RCC_BACKUPRESET_RELEASE(); + 8002652: 4b44 ldr r3, [pc, #272] ; (8002764 ) + 8002654: 6a1a ldr r2, [r3, #32] + 8002656: 4b43 ldr r3, [pc, #268] ; (8002764 ) + 8002658: 4945 ldr r1, [pc, #276] ; (8002770 ) + 800265a: 400a ands r2, r1 + 800265c: 621a str r2, [r3, #32] + /* Restore the Content of BDCR register */ + RCC->BDCR = temp_reg; + 800265e: 4b41 ldr r3, [pc, #260] ; (8002764 ) + 8002660: 68fa ldr r2, [r7, #12] + 8002662: 621a str r2, [r3, #32] + + /* Wait for LSERDY if LSE was enabled */ + if (HAL_IS_BIT_SET(temp_reg, RCC_BDCR_LSEON)) + 8002664: 68fb ldr r3, [r7, #12] + 8002666: 2201 movs r2, #1 + 8002668: 4013 ands r3, r2 + 800266a: d013 beq.n 8002694 + { + /* Get Start Tick */ + tickstart = HAL_GetTick(); + 800266c: f7fe f82a bl 80006c4 + 8002670: 0003 movs r3, r0 + 8002672: 613b str r3, [r7, #16] + + /* Wait till LSE is ready */ + while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET) + 8002674: e009 b.n 800268a + { + if((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE) + 8002676: f7fe f825 bl 80006c4 + 800267a: 0002 movs r2, r0 + 800267c: 693b ldr r3, [r7, #16] + 800267e: 1ad3 subs r3, r2, r3 + 8002680: 4a3c ldr r2, [pc, #240] ; (8002774 ) + 8002682: 4293 cmp r3, r2 + 8002684: d901 bls.n 800268a + { + return HAL_TIMEOUT; + 8002686: 2303 movs r3, #3 + 8002688: e067 b.n 800275a + while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET) + 800268a: 4b36 ldr r3, [pc, #216] ; (8002764 ) + 800268c: 6a1b ldr r3, [r3, #32] + 800268e: 2202 movs r2, #2 + 8002690: 4013 ands r3, r2 + 8002692: d0f0 beq.n 8002676 + } + } + } + } + __HAL_RCC_RTC_CONFIG(PeriphClkInit->RTCClockSelection); + 8002694: 4b33 ldr r3, [pc, #204] ; (8002764 ) + 8002696: 6a1b ldr r3, [r3, #32] + 8002698: 4a34 ldr r2, [pc, #208] ; (800276c ) + 800269a: 4013 ands r3, r2 + 800269c: 0019 movs r1, r3 + 800269e: 687b ldr r3, [r7, #4] + 80026a0: 685a ldr r2, [r3, #4] + 80026a2: 4b30 ldr r3, [pc, #192] ; (8002764 ) + 80026a4: 430a orrs r2, r1 + 80026a6: 621a str r2, [r3, #32] + + /* Require to disable power clock if necessary */ + if(pwrclkchanged == SET) + 80026a8: 2317 movs r3, #23 + 80026aa: 18fb adds r3, r7, r3 + 80026ac: 781b ldrb r3, [r3, #0] + 80026ae: 2b01 cmp r3, #1 + 80026b0: d105 bne.n 80026be + { + __HAL_RCC_PWR_CLK_DISABLE(); + 80026b2: 4b2c ldr r3, [pc, #176] ; (8002764 ) + 80026b4: 69da ldr r2, [r3, #28] + 80026b6: 4b2b ldr r3, [pc, #172] ; (8002764 ) + 80026b8: 492f ldr r1, [pc, #188] ; (8002778 ) + 80026ba: 400a ands r2, r1 + 80026bc: 61da str r2, [r3, #28] + } + } + + /*------------------------------- USART1 Configuration ------------------------*/ + if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USART1) == RCC_PERIPHCLK_USART1) + 80026be: 687b ldr r3, [r7, #4] + 80026c0: 681b ldr r3, [r3, #0] + 80026c2: 2201 movs r2, #1 + 80026c4: 4013 ands r3, r2 + 80026c6: d009 beq.n 80026dc + { + /* Check the parameters */ + assert_param(IS_RCC_USART1CLKSOURCE(PeriphClkInit->Usart1ClockSelection)); + + /* Configure the USART1 clock source */ + __HAL_RCC_USART1_CONFIG(PeriphClkInit->Usart1ClockSelection); + 80026c8: 4b26 ldr r3, [pc, #152] ; (8002764 ) + 80026ca: 6b1b ldr r3, [r3, #48] ; 0x30 + 80026cc: 2203 movs r2, #3 + 80026ce: 4393 bics r3, r2 + 80026d0: 0019 movs r1, r3 + 80026d2: 687b ldr r3, [r7, #4] + 80026d4: 689a ldr r2, [r3, #8] + 80026d6: 4b23 ldr r3, [pc, #140] ; (8002764 ) + 80026d8: 430a orrs r2, r1 + 80026da: 631a str r2, [r3, #48] ; 0x30 + } + +#if defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F078xx)\ + || defined(STM32F091xC) || defined(STM32F098xx) + /*----------------------------- USART2 Configuration --------------------------*/ + if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USART2) == RCC_PERIPHCLK_USART2) + 80026dc: 687b ldr r3, [r7, #4] + 80026de: 681b ldr r3, [r3, #0] + 80026e0: 2202 movs r2, #2 + 80026e2: 4013 ands r3, r2 + 80026e4: d009 beq.n 80026fa + { + /* Check the parameters */ + assert_param(IS_RCC_USART2CLKSOURCE(PeriphClkInit->Usart2ClockSelection)); + + /* Configure the USART2 clock source */ + __HAL_RCC_USART2_CONFIG(PeriphClkInit->Usart2ClockSelection); + 80026e6: 4b1f ldr r3, [pc, #124] ; (8002764 ) + 80026e8: 6b1b ldr r3, [r3, #48] ; 0x30 + 80026ea: 4a24 ldr r2, [pc, #144] ; (800277c ) + 80026ec: 4013 ands r3, r2 + 80026ee: 0019 movs r1, r3 + 80026f0: 687b ldr r3, [r7, #4] + 80026f2: 68da ldr r2, [r3, #12] + 80026f4: 4b1b ldr r3, [pc, #108] ; (8002764 ) + 80026f6: 430a orrs r2, r1 + 80026f8: 631a str r2, [r3, #48] ; 0x30 + __HAL_RCC_USART3_CONFIG(PeriphClkInit->Usart3ClockSelection); + } +#endif /* STM32F091xC || STM32F098xx */ + + /*------------------------------ I2C1 Configuration ------------------------*/ + if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2C1) == RCC_PERIPHCLK_I2C1) + 80026fa: 687b ldr r3, [r7, #4] + 80026fc: 681b ldr r3, [r3, #0] + 80026fe: 2220 movs r2, #32 + 8002700: 4013 ands r3, r2 + 8002702: d009 beq.n 8002718 + { + /* Check the parameters */ + assert_param(IS_RCC_I2C1CLKSOURCE(PeriphClkInit->I2c1ClockSelection)); + + /* Configure the I2C1 clock source */ + __HAL_RCC_I2C1_CONFIG(PeriphClkInit->I2c1ClockSelection); + 8002704: 4b17 ldr r3, [pc, #92] ; (8002764 ) + 8002706: 6b1b ldr r3, [r3, #48] ; 0x30 + 8002708: 2210 movs r2, #16 + 800270a: 4393 bics r3, r2 + 800270c: 0019 movs r1, r3 + 800270e: 687b ldr r3, [r7, #4] + 8002710: 691a ldr r2, [r3, #16] + 8002712: 4b14 ldr r3, [pc, #80] ; (8002764 ) + 8002714: 430a orrs r2, r1 + 8002716: 631a str r2, [r3, #48] ; 0x30 + } + +#if defined(STM32F042x6) || defined(STM32F048xx) || defined(STM32F072xB) || defined(STM32F078xx) || defined(STM32F070xB) || defined(STM32F070x6) + /*------------------------------ USB Configuration ------------------------*/ + if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USB) == RCC_PERIPHCLK_USB) + 8002718: 687b ldr r3, [r7, #4] + 800271a: 681a ldr r2, [r3, #0] + 800271c: 2380 movs r3, #128 ; 0x80 + 800271e: 029b lsls r3, r3, #10 + 8002720: 4013 ands r3, r2 + 8002722: d009 beq.n 8002738 + { + /* Check the parameters */ + assert_param(IS_RCC_USBCLKSOURCE(PeriphClkInit->UsbClockSelection)); + + /* Configure the USB clock source */ + __HAL_RCC_USB_CONFIG(PeriphClkInit->UsbClockSelection); + 8002724: 4b0f ldr r3, [pc, #60] ; (8002764 ) + 8002726: 6b1b ldr r3, [r3, #48] ; 0x30 + 8002728: 2280 movs r2, #128 ; 0x80 + 800272a: 4393 bics r3, r2 + 800272c: 0019 movs r1, r3 + 800272e: 687b ldr r3, [r7, #4] + 8002730: 699a ldr r2, [r3, #24] + 8002732: 4b0c ldr r3, [pc, #48] ; (8002764 ) + 8002734: 430a orrs r2, r1 + 8002736: 631a str r2, [r3, #48] ; 0x30 +#if defined(STM32F042x6) || defined(STM32F048xx)\ + || defined(STM32F051x8) || defined(STM32F058xx)\ + || defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F078xx)\ + || defined(STM32F091xC) || defined(STM32F098xx) + /*------------------------------ CEC clock Configuration -------------------*/ + if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_CEC) == RCC_PERIPHCLK_CEC) + 8002738: 687b ldr r3, [r7, #4] + 800273a: 681a ldr r2, [r3, #0] + 800273c: 2380 movs r3, #128 ; 0x80 + 800273e: 00db lsls r3, r3, #3 + 8002740: 4013 ands r3, r2 + 8002742: d009 beq.n 8002758 + { + /* Check the parameters */ + assert_param(IS_RCC_CECCLKSOURCE(PeriphClkInit->CecClockSelection)); + + /* Configure the CEC clock source */ + __HAL_RCC_CEC_CONFIG(PeriphClkInit->CecClockSelection); + 8002744: 4b07 ldr r3, [pc, #28] ; (8002764 ) + 8002746: 6b1b ldr r3, [r3, #48] ; 0x30 + 8002748: 2240 movs r2, #64 ; 0x40 + 800274a: 4393 bics r3, r2 + 800274c: 0019 movs r1, r3 + 800274e: 687b ldr r3, [r7, #4] + 8002750: 695a ldr r2, [r3, #20] + 8002752: 4b04 ldr r3, [pc, #16] ; (8002764 ) + 8002754: 430a orrs r2, r1 + 8002756: 631a str r2, [r3, #48] ; 0x30 +#endif /* STM32F042x6 || STM32F048xx || */ + /* STM32F051x8 || STM32F058xx || */ + /* STM32F071xB || STM32F072xB || STM32F078xx || */ + /* STM32F091xC || STM32F098xx */ + + return HAL_OK; + 8002758: 2300 movs r3, #0 +} + 800275a: 0018 movs r0, r3 + 800275c: 46bd mov sp, r7 + 800275e: b006 add sp, #24 + 8002760: bd80 pop {r7, pc} + 8002762: 46c0 nop ; (mov r8, r8) + 8002764: 40021000 .word 0x40021000 + 8002768: 40007000 .word 0x40007000 + 800276c: fffffcff .word 0xfffffcff + 8002770: fffeffff .word 0xfffeffff + 8002774: 00001388 .word 0x00001388 + 8002778: efffffff .word 0xefffffff + 800277c: fffcffff .word 0xfffcffff + +08002780 : + * Enables the controller's Global Int in the AHB Config reg + * @param USBx : Selected device + * @retval HAL status + */ +HAL_StatusTypeDef USB_EnableGlobalInt(USB_TypeDef *USBx) +{ + 8002780: b580 push {r7, lr} + 8002782: b084 sub sp, #16 + 8002784: af00 add r7, sp, #0 + 8002786: 6078 str r0, [r7, #4] + uint16_t winterruptmask; + + /* Set winterruptmask variable */ + winterruptmask = USB_CNTR_CTRM | USB_CNTR_WKUPM | + 8002788: 210e movs r1, #14 + 800278a: 187b adds r3, r7, r1 + 800278c: 4a08 ldr r2, [pc, #32] ; (80027b0 ) + 800278e: 801a strh r2, [r3, #0] + USB_CNTR_SUSPM | USB_CNTR_ERRM | + USB_CNTR_SOFM | USB_CNTR_ESOFM | + USB_CNTR_RESETM | USB_CNTR_L1REQM; + + /* Set interrupt mask */ + USBx->CNTR |= winterruptmask; + 8002790: 687b ldr r3, [r7, #4] + 8002792: 2240 movs r2, #64 ; 0x40 + 8002794: 5a9b ldrh r3, [r3, r2] + 8002796: b29a uxth r2, r3 + 8002798: 187b adds r3, r7, r1 + 800279a: 881b ldrh r3, [r3, #0] + 800279c: 4313 orrs r3, r2 + 800279e: b299 uxth r1, r3 + 80027a0: 687b ldr r3, [r7, #4] + 80027a2: 2240 movs r2, #64 ; 0x40 + 80027a4: 5299 strh r1, [r3, r2] + + return HAL_OK; + 80027a6: 2300 movs r3, #0 +} + 80027a8: 0018 movs r0, r3 + 80027aa: 46bd mov sp, r7 + 80027ac: b004 add sp, #16 + 80027ae: bd80 pop {r7, pc} + 80027b0: ffffbf80 .word 0xffffbf80 + +080027b4 : + * Disable the controller's Global Int in the AHB Config reg + * @param USBx : Selected device + * @retval HAL status +*/ +HAL_StatusTypeDef USB_DisableGlobalInt(USB_TypeDef *USBx) +{ + 80027b4: b580 push {r7, lr} + 80027b6: b084 sub sp, #16 + 80027b8: af00 add r7, sp, #0 + 80027ba: 6078 str r0, [r7, #4] + uint16_t winterruptmask; + + /* Set winterruptmask variable */ + winterruptmask = USB_CNTR_CTRM | USB_CNTR_WKUPM | + 80027bc: 210e movs r1, #14 + 80027be: 187b adds r3, r7, r1 + 80027c0: 4a0b ldr r2, [pc, #44] ; (80027f0 ) + 80027c2: 801a strh r2, [r3, #0] + USB_CNTR_SUSPM | USB_CNTR_ERRM | + USB_CNTR_SOFM | USB_CNTR_ESOFM | + USB_CNTR_RESETM | USB_CNTR_L1REQM; + + /* Clear interrupt mask */ + USBx->CNTR &= ~winterruptmask; + 80027c4: 687b ldr r3, [r7, #4] + 80027c6: 2240 movs r2, #64 ; 0x40 + 80027c8: 5a9b ldrh r3, [r3, r2] + 80027ca: b29b uxth r3, r3 + 80027cc: b21b sxth r3, r3 + 80027ce: 187a adds r2, r7, r1 + 80027d0: 2100 movs r1, #0 + 80027d2: 5e52 ldrsh r2, [r2, r1] + 80027d4: 43d2 mvns r2, r2 + 80027d6: b212 sxth r2, r2 + 80027d8: 4013 ands r3, r2 + 80027da: b21b sxth r3, r3 + 80027dc: b299 uxth r1, r3 + 80027de: 687b ldr r3, [r7, #4] + 80027e0: 2240 movs r2, #64 ; 0x40 + 80027e2: 5299 strh r1, [r3, r2] + + return HAL_OK; + 80027e4: 2300 movs r3, #0 +} + 80027e6: 0018 movs r0, r3 + 80027e8: 46bd mov sp, r7 + 80027ea: b004 add sp, #16 + 80027ec: bd80 pop {r7, pc} + 80027ee: 46c0 nop ; (mov r8, r8) + 80027f0: ffffbf80 .word 0xffffbf80 + +080027f4 : + * @param cfg : pointer to a USB_CfgTypeDef structure that contains + * the configuration information for the specified USBx peripheral. + * @retval HAL status + */ +HAL_StatusTypeDef USB_DevInit(USB_TypeDef *USBx, USB_CfgTypeDef cfg) +{ + 80027f4: b084 sub sp, #16 + 80027f6: b590 push {r4, r7, lr} + 80027f8: 46c6 mov lr, r8 + 80027fa: b500 push {lr} + 80027fc: b082 sub sp, #8 + 80027fe: af00 add r7, sp, #0 + 8002800: 6078 str r0, [r7, #4] + 8002802: 2004 movs r0, #4 + 8002804: 2410 movs r4, #16 + 8002806: 46a4 mov ip, r4 + 8002808: 2408 movs r4, #8 + 800280a: 46a0 mov r8, r4 + 800280c: 44b8 add r8, r7 + 800280e: 44c4 add ip, r8 + 8002810: 4460 add r0, ip + 8002812: 6001 str r1, [r0, #0] + 8002814: 6042 str r2, [r0, #4] + 8002816: 6083 str r3, [r0, #8] + /* Prevent unused argument(s) compilation warning */ + UNUSED(cfg); + + /* Init Device */ + /*CNTR_FRES = 1*/ + USBx->CNTR = USB_CNTR_FRES; + 8002818: 687b ldr r3, [r7, #4] + 800281a: 2240 movs r2, #64 ; 0x40 + 800281c: 2101 movs r1, #1 + 800281e: 5299 strh r1, [r3, r2] + + /*CNTR_FRES = 0*/ + USBx->CNTR = 0; + 8002820: 687b ldr r3, [r7, #4] + 8002822: 2240 movs r2, #64 ; 0x40 + 8002824: 2100 movs r1, #0 + 8002826: 5299 strh r1, [r3, r2] + + /*Clear pending interrupts*/ + USBx->ISTR = 0; + 8002828: 687b ldr r3, [r7, #4] + 800282a: 2244 movs r2, #68 ; 0x44 + 800282c: 2100 movs r1, #0 + 800282e: 5299 strh r1, [r3, r2] + + /*Set Btable Address*/ + USBx->BTABLE = BTABLE_ADDRESS; + 8002830: 687b ldr r3, [r7, #4] + 8002832: 2250 movs r2, #80 ; 0x50 + 8002834: 2100 movs r1, #0 + 8002836: 5299 strh r1, [r3, r2] + + /* Enable USB Device Interrupt mask */ + (void)USB_EnableGlobalInt(USBx); + 8002838: 687b ldr r3, [r7, #4] + 800283a: 0018 movs r0, r3 + 800283c: f7ff ffa0 bl 8002780 + + return HAL_OK; + 8002840: 2300 movs r3, #0 +} + 8002842: 0018 movs r0, r3 + 8002844: 46bd mov sp, r7 + 8002846: b002 add sp, #8 + 8002848: bc04 pop {r2} + 800284a: 4690 mov r8, r2 + 800284c: bc90 pop {r4, r7} + 800284e: bc08 pop {r3} + 8002850: b004 add sp, #16 + 8002852: 4718 bx r3 + +08002854 : + * @param USBx : Selected device + * @param ep: pointer to endpoint structure + * @retval HAL status + */ +HAL_StatusTypeDef USB_ActivateEndpoint(USB_TypeDef *USBx, USB_EPTypeDef *ep) +{ + 8002854: b590 push {r4, r7, lr} + 8002856: b087 sub sp, #28 + 8002858: af00 add r7, sp, #0 + 800285a: 6078 str r0, [r7, #4] + 800285c: 6039 str r1, [r7, #0] + HAL_StatusTypeDef ret = HAL_OK; + 800285e: 2317 movs r3, #23 + 8002860: 18fb adds r3, r7, r3 + 8002862: 2200 movs r2, #0 + 8002864: 701a strb r2, [r3, #0] + uint16_t wEpRegVal; + + wEpRegVal = PCD_GET_ENDPOINT(USBx, ep->num) & USB_EP_T_MASK; + 8002866: 687a ldr r2, [r7, #4] + 8002868: 683b ldr r3, [r7, #0] + 800286a: 781b ldrb r3, [r3, #0] + 800286c: 009b lsls r3, r3, #2 + 800286e: 18d3 adds r3, r2, r3 + 8002870: 881b ldrh r3, [r3, #0] + 8002872: b29a uxth r2, r3 + 8002874: 2314 movs r3, #20 + 8002876: 18fb adds r3, r7, r3 + 8002878: 49b2 ldr r1, [pc, #712] ; (8002b44 ) + 800287a: 400a ands r2, r1 + 800287c: 801a strh r2, [r3, #0] + + /* initialize Endpoint */ + switch (ep->type) + 800287e: 683b ldr r3, [r7, #0] + 8002880: 78db ldrb r3, [r3, #3] + 8002882: 2b01 cmp r3, #1 + 8002884: d020 beq.n 80028c8 + 8002886: dc02 bgt.n 800288e + 8002888: 2b00 cmp r3, #0 + 800288a: d005 beq.n 8002898 + 800288c: e025 b.n 80028da + 800288e: 2b02 cmp r3, #2 + 8002890: d00b beq.n 80028aa + 8002892: 2b03 cmp r3, #3 + 8002894: d00f beq.n 80028b6 + 8002896: e020 b.n 80028da + { + case EP_TYPE_CTRL: + wEpRegVal |= USB_EP_CONTROL; + 8002898: 2214 movs r2, #20 + 800289a: 18bb adds r3, r7, r2 + 800289c: 18ba adds r2, r7, r2 + 800289e: 8812 ldrh r2, [r2, #0] + 80028a0: 2180 movs r1, #128 ; 0x80 + 80028a2: 0089 lsls r1, r1, #2 + 80028a4: 430a orrs r2, r1 + 80028a6: 801a strh r2, [r3, #0] + break; + 80028a8: e01c b.n 80028e4 + + case EP_TYPE_BULK: + wEpRegVal |= USB_EP_BULK; + 80028aa: 2214 movs r2, #20 + 80028ac: 18bb adds r3, r7, r2 + 80028ae: 18ba adds r2, r7, r2 + 80028b0: 8812 ldrh r2, [r2, #0] + 80028b2: 801a strh r2, [r3, #0] + break; + 80028b4: e016 b.n 80028e4 + + case EP_TYPE_INTR: + wEpRegVal |= USB_EP_INTERRUPT; + 80028b6: 2214 movs r2, #20 + 80028b8: 18bb adds r3, r7, r2 + 80028ba: 18ba adds r2, r7, r2 + 80028bc: 8812 ldrh r2, [r2, #0] + 80028be: 21c0 movs r1, #192 ; 0xc0 + 80028c0: 00c9 lsls r1, r1, #3 + 80028c2: 430a orrs r2, r1 + 80028c4: 801a strh r2, [r3, #0] + break; + 80028c6: e00d b.n 80028e4 + + case EP_TYPE_ISOC: + wEpRegVal |= USB_EP_ISOCHRONOUS; + 80028c8: 2214 movs r2, #20 + 80028ca: 18bb adds r3, r7, r2 + 80028cc: 18ba adds r2, r7, r2 + 80028ce: 8812 ldrh r2, [r2, #0] + 80028d0: 2180 movs r1, #128 ; 0x80 + 80028d2: 00c9 lsls r1, r1, #3 + 80028d4: 430a orrs r2, r1 + 80028d6: 801a strh r2, [r3, #0] + break; + 80028d8: e004 b.n 80028e4 + + default: + ret = HAL_ERROR; + 80028da: 2317 movs r3, #23 + 80028dc: 18fb adds r3, r7, r3 + 80028de: 2201 movs r2, #1 + 80028e0: 701a strb r2, [r3, #0] + break; + 80028e2: 46c0 nop ; (mov r8, r8) + } + + PCD_SET_ENDPOINT(USBx, ep->num, wEpRegVal | USB_EP_CTR_RX | USB_EP_CTR_TX); + 80028e4: 687a ldr r2, [r7, #4] + 80028e6: 683b ldr r3, [r7, #0] + 80028e8: 781b ldrb r3, [r3, #0] + 80028ea: 009b lsls r3, r3, #2 + 80028ec: 18d3 adds r3, r2, r3 + 80028ee: 2214 movs r2, #20 + 80028f0: 18ba adds r2, r7, r2 + 80028f2: 8812 ldrh r2, [r2, #0] + 80028f4: 4994 ldr r1, [pc, #592] ; (8002b48 ) + 80028f6: 430a orrs r2, r1 + 80028f8: b292 uxth r2, r2 + 80028fa: 801a strh r2, [r3, #0] + + PCD_SET_EP_ADDRESS(USBx, ep->num, ep->num); + 80028fc: 687a ldr r2, [r7, #4] + 80028fe: 683b ldr r3, [r7, #0] + 8002900: 781b ldrb r3, [r3, #0] + 8002902: 009b lsls r3, r3, #2 + 8002904: 18d3 adds r3, r2, r3 + 8002906: 881b ldrh r3, [r3, #0] + 8002908: b29b uxth r3, r3 + 800290a: b21b sxth r3, r3 + 800290c: 4a8f ldr r2, [pc, #572] ; (8002b4c ) + 800290e: 4013 ands r3, r2 + 8002910: b21a sxth r2, r3 + 8002912: 683b ldr r3, [r7, #0] + 8002914: 781b ldrb r3, [r3, #0] + 8002916: b21b sxth r3, r3 + 8002918: 4313 orrs r3, r2 + 800291a: b21b sxth r3, r3 + 800291c: b29c uxth r4, r3 + 800291e: 687a ldr r2, [r7, #4] + 8002920: 683b ldr r3, [r7, #0] + 8002922: 781b ldrb r3, [r3, #0] + 8002924: 009b lsls r3, r3, #2 + 8002926: 18d3 adds r3, r2, r3 + 8002928: 4a87 ldr r2, [pc, #540] ; (8002b48 ) + 800292a: 4322 orrs r2, r4 + 800292c: b292 uxth r2, r2 + 800292e: 801a strh r2, [r3, #0] + + if (ep->doublebuffer == 0U) + 8002930: 683b ldr r3, [r7, #0] + 8002932: 7b1b ldrb r3, [r3, #12] + 8002934: 2b00 cmp r3, #0 + 8002936: d000 beq.n 800293a + 8002938: e11a b.n 8002b70 + { + if (ep->is_in != 0U) + 800293a: 683b ldr r3, [r7, #0] + 800293c: 785b ldrb r3, [r3, #1] + 800293e: 2b00 cmp r3, #0 + 8002940: d062 beq.n 8002a08 + { + /*Set the endpoint Transmit buffer address */ + PCD_SET_EP_TX_ADDRESS(USBx, ep->num, ep->pmaadress); + 8002942: 687c ldr r4, [r7, #4] + 8002944: 687b ldr r3, [r7, #4] + 8002946: 2250 movs r2, #80 ; 0x50 + 8002948: 5a9b ldrh r3, [r3, r2] + 800294a: b29b uxth r3, r3 + 800294c: 18e4 adds r4, r4, r3 + 800294e: 683b ldr r3, [r7, #0] + 8002950: 781b ldrb r3, [r3, #0] + 8002952: 00db lsls r3, r3, #3 + 8002954: 18e3 adds r3, r4, r3 + 8002956: 2280 movs r2, #128 ; 0x80 + 8002958: 00d2 lsls r2, r2, #3 + 800295a: 4694 mov ip, r2 + 800295c: 4463 add r3, ip + 800295e: 001c movs r4, r3 + 8002960: 683b ldr r3, [r7, #0] + 8002962: 88db ldrh r3, [r3, #6] + 8002964: 085b lsrs r3, r3, #1 + 8002966: b29b uxth r3, r3 + 8002968: 18db adds r3, r3, r3 + 800296a: b29b uxth r3, r3 + 800296c: 8023 strh r3, [r4, #0] + PCD_CLEAR_TX_DTOG(USBx, ep->num); + 800296e: 687a ldr r2, [r7, #4] + 8002970: 683b ldr r3, [r7, #0] + 8002972: 781b ldrb r3, [r3, #0] + 8002974: 009b lsls r3, r3, #2 + 8002976: 18d3 adds r3, r2, r3 + 8002978: 881b ldrh r3, [r3, #0] + 800297a: b29c uxth r4, r3 + 800297c: 0022 movs r2, r4 + 800297e: 2340 movs r3, #64 ; 0x40 + 8002980: 4013 ands r3, r2 + 8002982: d012 beq.n 80029aa + 8002984: 687a ldr r2, [r7, #4] + 8002986: 683b ldr r3, [r7, #0] + 8002988: 781b ldrb r3, [r3, #0] + 800298a: 009b lsls r3, r3, #2 + 800298c: 18d3 adds r3, r2, r3 + 800298e: 881b ldrh r3, [r3, #0] + 8002990: b29b uxth r3, r3 + 8002992: 4a6e ldr r2, [pc, #440] ; (8002b4c ) + 8002994: 4013 ands r3, r2 + 8002996: b29c uxth r4, r3 + 8002998: 687a ldr r2, [r7, #4] + 800299a: 683b ldr r3, [r7, #0] + 800299c: 781b ldrb r3, [r3, #0] + 800299e: 009b lsls r3, r3, #2 + 80029a0: 18d3 adds r3, r2, r3 + 80029a2: 4a6b ldr r2, [pc, #428] ; (8002b50 ) + 80029a4: 4322 orrs r2, r4 + 80029a6: b292 uxth r2, r2 + 80029a8: 801a strh r2, [r3, #0] + + if (ep->type != EP_TYPE_ISOC) + 80029aa: 683b ldr r3, [r7, #0] + 80029ac: 78db ldrb r3, [r3, #3] + 80029ae: 2b01 cmp r3, #1 + 80029b0: d016 beq.n 80029e0 + { + /* Configure NAK status for the Endpoint */ + PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_NAK); + 80029b2: 687a ldr r2, [r7, #4] + 80029b4: 683b ldr r3, [r7, #0] + 80029b6: 781b ldrb r3, [r3, #0] + 80029b8: 009b lsls r3, r3, #2 + 80029ba: 18d3 adds r3, r2, r3 + 80029bc: 881b ldrh r3, [r3, #0] + 80029be: b29b uxth r3, r3 + 80029c0: 4a64 ldr r2, [pc, #400] ; (8002b54 ) + 80029c2: 4013 ands r3, r2 + 80029c4: b29c uxth r4, r3 + 80029c6: 2320 movs r3, #32 + 80029c8: 4063 eors r3, r4 + 80029ca: b29c uxth r4, r3 + 80029cc: 687a ldr r2, [r7, #4] + 80029ce: 683b ldr r3, [r7, #0] + 80029d0: 781b ldrb r3, [r3, #0] + 80029d2: 009b lsls r3, r3, #2 + 80029d4: 18d3 adds r3, r2, r3 + 80029d6: 4a5c ldr r2, [pc, #368] ; (8002b48 ) + 80029d8: 4322 orrs r2, r4 + 80029da: b292 uxth r2, r2 + 80029dc: 801a strh r2, [r3, #0] + 80029de: e21a b.n 8002e16 + } + else + { + /* Configure TX Endpoint to disabled state */ + PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS); + 80029e0: 687a ldr r2, [r7, #4] + 80029e2: 683b ldr r3, [r7, #0] + 80029e4: 781b ldrb r3, [r3, #0] + 80029e6: 009b lsls r3, r3, #2 + 80029e8: 18d3 adds r3, r2, r3 + 80029ea: 881b ldrh r3, [r3, #0] + 80029ec: b29b uxth r3, r3 + 80029ee: 4a59 ldr r2, [pc, #356] ; (8002b54 ) + 80029f0: 4013 ands r3, r2 + 80029f2: b29c uxth r4, r3 + 80029f4: 687a ldr r2, [r7, #4] + 80029f6: 683b ldr r3, [r7, #0] + 80029f8: 781b ldrb r3, [r3, #0] + 80029fa: 009b lsls r3, r3, #2 + 80029fc: 18d3 adds r3, r2, r3 + 80029fe: 4a52 ldr r2, [pc, #328] ; (8002b48 ) + 8002a00: 4322 orrs r2, r4 + 8002a02: b292 uxth r2, r2 + 8002a04: 801a strh r2, [r3, #0] + 8002a06: e206 b.n 8002e16 + } + } + else + { + /*Set the endpoint Receive buffer address */ + PCD_SET_EP_RX_ADDRESS(USBx, ep->num, ep->pmaadress); + 8002a08: 687c ldr r4, [r7, #4] + 8002a0a: 687b ldr r3, [r7, #4] + 8002a0c: 2250 movs r2, #80 ; 0x50 + 8002a0e: 5a9b ldrh r3, [r3, r2] + 8002a10: b29b uxth r3, r3 + 8002a12: 18e4 adds r4, r4, r3 + 8002a14: 683b ldr r3, [r7, #0] + 8002a16: 781b ldrb r3, [r3, #0] + 8002a18: 00db lsls r3, r3, #3 + 8002a1a: 18e3 adds r3, r4, r3 + 8002a1c: 4a4e ldr r2, [pc, #312] ; (8002b58 ) + 8002a1e: 4694 mov ip, r2 + 8002a20: 4463 add r3, ip + 8002a22: 001c movs r4, r3 + 8002a24: 683b ldr r3, [r7, #0] + 8002a26: 88db ldrh r3, [r3, #6] + 8002a28: 085b lsrs r3, r3, #1 + 8002a2a: b29b uxth r3, r3 + 8002a2c: 18db adds r3, r3, r3 + 8002a2e: b29b uxth r3, r3 + 8002a30: 8023 strh r3, [r4, #0] + /*Set the endpoint Receive buffer counter*/ + PCD_SET_EP_RX_CNT(USBx, ep->num, ep->maxpacket); + 8002a32: 687c ldr r4, [r7, #4] + 8002a34: 687b ldr r3, [r7, #4] + 8002a36: 2250 movs r2, #80 ; 0x50 + 8002a38: 5a9b ldrh r3, [r3, r2] + 8002a3a: b29b uxth r3, r3 + 8002a3c: 18e4 adds r4, r4, r3 + 8002a3e: 683b ldr r3, [r7, #0] + 8002a40: 781b ldrb r3, [r3, #0] + 8002a42: 00db lsls r3, r3, #3 + 8002a44: 18e3 adds r3, r4, r3 + 8002a46: 4a45 ldr r2, [pc, #276] ; (8002b5c ) + 8002a48: 4694 mov ip, r2 + 8002a4a: 4463 add r3, ip + 8002a4c: 60fb str r3, [r7, #12] + 8002a4e: 683b ldr r3, [r7, #0] + 8002a50: 691b ldr r3, [r3, #16] + 8002a52: 2b00 cmp r3, #0 + 8002a54: d10e bne.n 8002a74 + 8002a56: 68fb ldr r3, [r7, #12] + 8002a58: 881b ldrh r3, [r3, #0] + 8002a5a: 4a41 ldr r2, [pc, #260] ; (8002b60 ) + 8002a5c: 4013 ands r3, r2 + 8002a5e: b29a uxth r2, r3 + 8002a60: 68fb ldr r3, [r7, #12] + 8002a62: 801a strh r2, [r3, #0] + 8002a64: 68fb ldr r3, [r7, #12] + 8002a66: 881b ldrh r3, [r3, #0] + 8002a68: 4a3e ldr r2, [pc, #248] ; (8002b64 ) + 8002a6a: 4313 orrs r3, r2 + 8002a6c: b29a uxth r2, r3 + 8002a6e: 68fb ldr r3, [r7, #12] + 8002a70: 801a strh r2, [r3, #0] + 8002a72: e02b b.n 8002acc + 8002a74: 683b ldr r3, [r7, #0] + 8002a76: 691b ldr r3, [r3, #16] + 8002a78: 2b3e cmp r3, #62 ; 0x3e + 8002a7a: d812 bhi.n 8002aa2 + 8002a7c: 683b ldr r3, [r7, #0] + 8002a7e: 691b ldr r3, [r3, #16] + 8002a80: 085b lsrs r3, r3, #1 + 8002a82: 613b str r3, [r7, #16] + 8002a84: 683b ldr r3, [r7, #0] + 8002a86: 691b ldr r3, [r3, #16] + 8002a88: 2201 movs r2, #1 + 8002a8a: 4013 ands r3, r2 + 8002a8c: d002 beq.n 8002a94 + 8002a8e: 693b ldr r3, [r7, #16] + 8002a90: 3301 adds r3, #1 + 8002a92: 613b str r3, [r7, #16] + 8002a94: 693b ldr r3, [r7, #16] + 8002a96: b29b uxth r3, r3 + 8002a98: 029b lsls r3, r3, #10 + 8002a9a: b29a uxth r2, r3 + 8002a9c: 68fb ldr r3, [r7, #12] + 8002a9e: 801a strh r2, [r3, #0] + 8002aa0: e014 b.n 8002acc + 8002aa2: 683b ldr r3, [r7, #0] + 8002aa4: 691b ldr r3, [r3, #16] + 8002aa6: 095b lsrs r3, r3, #5 + 8002aa8: 613b str r3, [r7, #16] + 8002aaa: 683b ldr r3, [r7, #0] + 8002aac: 691b ldr r3, [r3, #16] + 8002aae: 221f movs r2, #31 + 8002ab0: 4013 ands r3, r2 + 8002ab2: d102 bne.n 8002aba + 8002ab4: 693b ldr r3, [r7, #16] + 8002ab6: 3b01 subs r3, #1 + 8002ab8: 613b str r3, [r7, #16] + 8002aba: 693b ldr r3, [r7, #16] + 8002abc: b29b uxth r3, r3 + 8002abe: 029b lsls r3, r3, #10 + 8002ac0: b29b uxth r3, r3 + 8002ac2: 4a28 ldr r2, [pc, #160] ; (8002b64 ) + 8002ac4: 4313 orrs r3, r2 + 8002ac6: b29a uxth r2, r3 + 8002ac8: 68fb ldr r3, [r7, #12] + 8002aca: 801a strh r2, [r3, #0] + PCD_CLEAR_RX_DTOG(USBx, ep->num); + 8002acc: 687a ldr r2, [r7, #4] + 8002ace: 683b ldr r3, [r7, #0] + 8002ad0: 781b ldrb r3, [r3, #0] + 8002ad2: 009b lsls r3, r3, #2 + 8002ad4: 18d3 adds r3, r2, r3 + 8002ad6: 881b ldrh r3, [r3, #0] + 8002ad8: b29c uxth r4, r3 + 8002ada: 0022 movs r2, r4 + 8002adc: 2380 movs r3, #128 ; 0x80 + 8002ade: 01db lsls r3, r3, #7 + 8002ae0: 4013 ands r3, r2 + 8002ae2: d012 beq.n 8002b0a + 8002ae4: 687a ldr r2, [r7, #4] + 8002ae6: 683b ldr r3, [r7, #0] + 8002ae8: 781b ldrb r3, [r3, #0] + 8002aea: 009b lsls r3, r3, #2 + 8002aec: 18d3 adds r3, r2, r3 + 8002aee: 881b ldrh r3, [r3, #0] + 8002af0: b29b uxth r3, r3 + 8002af2: 4a16 ldr r2, [pc, #88] ; (8002b4c ) + 8002af4: 4013 ands r3, r2 + 8002af6: b29c uxth r4, r3 + 8002af8: 687a ldr r2, [r7, #4] + 8002afa: 683b ldr r3, [r7, #0] + 8002afc: 781b ldrb r3, [r3, #0] + 8002afe: 009b lsls r3, r3, #2 + 8002b00: 18d3 adds r3, r2, r3 + 8002b02: 4a19 ldr r2, [pc, #100] ; (8002b68 ) + 8002b04: 4322 orrs r2, r4 + 8002b06: b292 uxth r2, r2 + 8002b08: 801a strh r2, [r3, #0] + /* Configure VALID status for the Endpoint*/ + PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_VALID); + 8002b0a: 687a ldr r2, [r7, #4] + 8002b0c: 683b ldr r3, [r7, #0] + 8002b0e: 781b ldrb r3, [r3, #0] + 8002b10: 009b lsls r3, r3, #2 + 8002b12: 18d3 adds r3, r2, r3 + 8002b14: 881b ldrh r3, [r3, #0] + 8002b16: b29b uxth r3, r3 + 8002b18: 4a14 ldr r2, [pc, #80] ; (8002b6c ) + 8002b1a: 4013 ands r3, r2 + 8002b1c: b29c uxth r4, r3 + 8002b1e: 2380 movs r3, #128 ; 0x80 + 8002b20: 015b lsls r3, r3, #5 + 8002b22: 4063 eors r3, r4 + 8002b24: b29c uxth r4, r3 + 8002b26: 2380 movs r3, #128 ; 0x80 + 8002b28: 019b lsls r3, r3, #6 + 8002b2a: 4063 eors r3, r4 + 8002b2c: b29c uxth r4, r3 + 8002b2e: 687a ldr r2, [r7, #4] + 8002b30: 683b ldr r3, [r7, #0] + 8002b32: 781b ldrb r3, [r3, #0] + 8002b34: 009b lsls r3, r3, #2 + 8002b36: 18d3 adds r3, r2, r3 + 8002b38: 4a03 ldr r2, [pc, #12] ; (8002b48 ) + 8002b3a: 4322 orrs r2, r4 + 8002b3c: b292 uxth r2, r2 + 8002b3e: 801a strh r2, [r3, #0] + 8002b40: e169 b.n 8002e16 + 8002b42: 46c0 nop ; (mov r8, r8) + 8002b44: ffff898f .word 0xffff898f + 8002b48: ffff8080 .word 0xffff8080 + 8002b4c: ffff8f8f .word 0xffff8f8f + 8002b50: ffff80c0 .word 0xffff80c0 + 8002b54: ffff8fbf .word 0xffff8fbf + 8002b58: 00000404 .word 0x00000404 + 8002b5c: 00000406 .word 0x00000406 + 8002b60: ffff83ff .word 0xffff83ff + 8002b64: ffff8000 .word 0xffff8000 + 8002b68: ffffc080 .word 0xffffc080 + 8002b6c: ffffbf8f .word 0xffffbf8f + } + /*Double Buffer*/ + else + { + /* Set the endpoint as double buffered */ + PCD_SET_EP_DBUF(USBx, ep->num); + 8002b70: 687a ldr r2, [r7, #4] + 8002b72: 683b ldr r3, [r7, #0] + 8002b74: 781b ldrb r3, [r3, #0] + 8002b76: 009b lsls r3, r3, #2 + 8002b78: 18d3 adds r3, r2, r3 + 8002b7a: 881b ldrh r3, [r3, #0] + 8002b7c: b29b uxth r3, r3 + 8002b7e: 4aa9 ldr r2, [pc, #676] ; (8002e24 ) + 8002b80: 4013 ands r3, r2 + 8002b82: b29c uxth r4, r3 + 8002b84: 687a ldr r2, [r7, #4] + 8002b86: 683b ldr r3, [r7, #0] + 8002b88: 781b ldrb r3, [r3, #0] + 8002b8a: 009b lsls r3, r3, #2 + 8002b8c: 18d3 adds r3, r2, r3 + 8002b8e: 4aa6 ldr r2, [pc, #664] ; (8002e28 ) + 8002b90: 4322 orrs r2, r4 + 8002b92: b292 uxth r2, r2 + 8002b94: 801a strh r2, [r3, #0] + /* Set buffer address for double buffered mode */ + PCD_SET_EP_DBUF_ADDR(USBx, ep->num, ep->pmaaddr0, ep->pmaaddr1); + 8002b96: 687c ldr r4, [r7, #4] + 8002b98: 687b ldr r3, [r7, #4] + 8002b9a: 2250 movs r2, #80 ; 0x50 + 8002b9c: 5a9b ldrh r3, [r3, r2] + 8002b9e: b29b uxth r3, r3 + 8002ba0: 18e4 adds r4, r4, r3 + 8002ba2: 683b ldr r3, [r7, #0] + 8002ba4: 781b ldrb r3, [r3, #0] + 8002ba6: 00db lsls r3, r3, #3 + 8002ba8: 18e3 adds r3, r4, r3 + 8002baa: 2280 movs r2, #128 ; 0x80 + 8002bac: 00d2 lsls r2, r2, #3 + 8002bae: 4694 mov ip, r2 + 8002bb0: 4463 add r3, ip + 8002bb2: 001c movs r4, r3 + 8002bb4: 683b ldr r3, [r7, #0] + 8002bb6: 891b ldrh r3, [r3, #8] + 8002bb8: 085b lsrs r3, r3, #1 + 8002bba: b29b uxth r3, r3 + 8002bbc: 18db adds r3, r3, r3 + 8002bbe: b29b uxth r3, r3 + 8002bc0: 8023 strh r3, [r4, #0] + 8002bc2: 687c ldr r4, [r7, #4] + 8002bc4: 687b ldr r3, [r7, #4] + 8002bc6: 2250 movs r2, #80 ; 0x50 + 8002bc8: 5a9b ldrh r3, [r3, r2] + 8002bca: b29b uxth r3, r3 + 8002bcc: 18e4 adds r4, r4, r3 + 8002bce: 683b ldr r3, [r7, #0] + 8002bd0: 781b ldrb r3, [r3, #0] + 8002bd2: 00db lsls r3, r3, #3 + 8002bd4: 18e3 adds r3, r4, r3 + 8002bd6: 4a95 ldr r2, [pc, #596] ; (8002e2c ) + 8002bd8: 4694 mov ip, r2 + 8002bda: 4463 add r3, ip + 8002bdc: 001c movs r4, r3 + 8002bde: 683b ldr r3, [r7, #0] + 8002be0: 895b ldrh r3, [r3, #10] + 8002be2: 085b lsrs r3, r3, #1 + 8002be4: b29b uxth r3, r3 + 8002be6: 18db adds r3, r3, r3 + 8002be8: b29b uxth r3, r3 + 8002bea: 8023 strh r3, [r4, #0] + + if (ep->is_in == 0U) + 8002bec: 683b ldr r3, [r7, #0] + 8002bee: 785b ldrb r3, [r3, #1] + 8002bf0: 2b00 cmp r3, #0 + 8002bf2: d000 beq.n 8002bf6 + 8002bf4: e07e b.n 8002cf4 + { + /* Clear the data toggle bits for the endpoint IN/OUT */ + PCD_CLEAR_RX_DTOG(USBx, ep->num); + 8002bf6: 687a ldr r2, [r7, #4] + 8002bf8: 683b ldr r3, [r7, #0] + 8002bfa: 781b ldrb r3, [r3, #0] + 8002bfc: 009b lsls r3, r3, #2 + 8002bfe: 18d3 adds r3, r2, r3 + 8002c00: 881b ldrh r3, [r3, #0] + 8002c02: b29c uxth r4, r3 + 8002c04: 0022 movs r2, r4 + 8002c06: 2380 movs r3, #128 ; 0x80 + 8002c08: 01db lsls r3, r3, #7 + 8002c0a: 4013 ands r3, r2 + 8002c0c: d012 beq.n 8002c34 + 8002c0e: 687a ldr r2, [r7, #4] + 8002c10: 683b ldr r3, [r7, #0] + 8002c12: 781b ldrb r3, [r3, #0] + 8002c14: 009b lsls r3, r3, #2 + 8002c16: 18d3 adds r3, r2, r3 + 8002c18: 881b ldrh r3, [r3, #0] + 8002c1a: b29b uxth r3, r3 + 8002c1c: 4a81 ldr r2, [pc, #516] ; (8002e24 ) + 8002c1e: 4013 ands r3, r2 + 8002c20: b29c uxth r4, r3 + 8002c22: 687a ldr r2, [r7, #4] + 8002c24: 683b ldr r3, [r7, #0] + 8002c26: 781b ldrb r3, [r3, #0] + 8002c28: 009b lsls r3, r3, #2 + 8002c2a: 18d3 adds r3, r2, r3 + 8002c2c: 4a80 ldr r2, [pc, #512] ; (8002e30 ) + 8002c2e: 4322 orrs r2, r4 + 8002c30: b292 uxth r2, r2 + 8002c32: 801a strh r2, [r3, #0] + PCD_CLEAR_TX_DTOG(USBx, ep->num); + 8002c34: 687a ldr r2, [r7, #4] + 8002c36: 683b ldr r3, [r7, #0] + 8002c38: 781b ldrb r3, [r3, #0] + 8002c3a: 009b lsls r3, r3, #2 + 8002c3c: 18d3 adds r3, r2, r3 + 8002c3e: 881b ldrh r3, [r3, #0] + 8002c40: b29c uxth r4, r3 + 8002c42: 0022 movs r2, r4 + 8002c44: 2340 movs r3, #64 ; 0x40 + 8002c46: 4013 ands r3, r2 + 8002c48: d012 beq.n 8002c70 + 8002c4a: 687a ldr r2, [r7, #4] + 8002c4c: 683b ldr r3, [r7, #0] + 8002c4e: 781b ldrb r3, [r3, #0] + 8002c50: 009b lsls r3, r3, #2 + 8002c52: 18d3 adds r3, r2, r3 + 8002c54: 881b ldrh r3, [r3, #0] + 8002c56: b29b uxth r3, r3 + 8002c58: 4a72 ldr r2, [pc, #456] ; (8002e24 ) + 8002c5a: 4013 ands r3, r2 + 8002c5c: b29c uxth r4, r3 + 8002c5e: 687a ldr r2, [r7, #4] + 8002c60: 683b ldr r3, [r7, #0] + 8002c62: 781b ldrb r3, [r3, #0] + 8002c64: 009b lsls r3, r3, #2 + 8002c66: 18d3 adds r3, r2, r3 + 8002c68: 4a72 ldr r2, [pc, #456] ; (8002e34 ) + 8002c6a: 4322 orrs r2, r4 + 8002c6c: b292 uxth r2, r2 + 8002c6e: 801a strh r2, [r3, #0] + + /* Reset value of the data toggle bits for the endpoint out */ + PCD_TX_DTOG(USBx, ep->num); + 8002c70: 687a ldr r2, [r7, #4] + 8002c72: 683b ldr r3, [r7, #0] + 8002c74: 781b ldrb r3, [r3, #0] + 8002c76: 009b lsls r3, r3, #2 + 8002c78: 18d3 adds r3, r2, r3 + 8002c7a: 881b ldrh r3, [r3, #0] + 8002c7c: b29b uxth r3, r3 + 8002c7e: 4a69 ldr r2, [pc, #420] ; (8002e24 ) + 8002c80: 4013 ands r3, r2 + 8002c82: b29c uxth r4, r3 + 8002c84: 687a ldr r2, [r7, #4] + 8002c86: 683b ldr r3, [r7, #0] + 8002c88: 781b ldrb r3, [r3, #0] + 8002c8a: 009b lsls r3, r3, #2 + 8002c8c: 18d3 adds r3, r2, r3 + 8002c8e: 4a69 ldr r2, [pc, #420] ; (8002e34 ) + 8002c90: 4322 orrs r2, r4 + 8002c92: b292 uxth r2, r2 + 8002c94: 801a strh r2, [r3, #0] + + PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_VALID); + 8002c96: 687a ldr r2, [r7, #4] + 8002c98: 683b ldr r3, [r7, #0] + 8002c9a: 781b ldrb r3, [r3, #0] + 8002c9c: 009b lsls r3, r3, #2 + 8002c9e: 18d3 adds r3, r2, r3 + 8002ca0: 881b ldrh r3, [r3, #0] + 8002ca2: b29b uxth r3, r3 + 8002ca4: 4a64 ldr r2, [pc, #400] ; (8002e38 ) + 8002ca6: 4013 ands r3, r2 + 8002ca8: b29c uxth r4, r3 + 8002caa: 2380 movs r3, #128 ; 0x80 + 8002cac: 015b lsls r3, r3, #5 + 8002cae: 4063 eors r3, r4 + 8002cb0: b29c uxth r4, r3 + 8002cb2: 2380 movs r3, #128 ; 0x80 + 8002cb4: 019b lsls r3, r3, #6 + 8002cb6: 4063 eors r3, r4 + 8002cb8: b29c uxth r4, r3 + 8002cba: 687a ldr r2, [r7, #4] + 8002cbc: 683b ldr r3, [r7, #0] + 8002cbe: 781b ldrb r3, [r3, #0] + 8002cc0: 009b lsls r3, r3, #2 + 8002cc2: 18d3 adds r3, r2, r3 + 8002cc4: 4a5d ldr r2, [pc, #372] ; (8002e3c ) + 8002cc6: 4322 orrs r2, r4 + 8002cc8: b292 uxth r2, r2 + 8002cca: 801a strh r2, [r3, #0] + PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS); + 8002ccc: 687a ldr r2, [r7, #4] + 8002cce: 683b ldr r3, [r7, #0] + 8002cd0: 781b ldrb r3, [r3, #0] + 8002cd2: 009b lsls r3, r3, #2 + 8002cd4: 18d3 adds r3, r2, r3 + 8002cd6: 881b ldrh r3, [r3, #0] + 8002cd8: b29b uxth r3, r3 + 8002cda: 4a59 ldr r2, [pc, #356] ; (8002e40 ) + 8002cdc: 4013 ands r3, r2 + 8002cde: b29c uxth r4, r3 + 8002ce0: 687a ldr r2, [r7, #4] + 8002ce2: 683b ldr r3, [r7, #0] + 8002ce4: 781b ldrb r3, [r3, #0] + 8002ce6: 009b lsls r3, r3, #2 + 8002ce8: 18d3 adds r3, r2, r3 + 8002cea: 4a54 ldr r2, [pc, #336] ; (8002e3c ) + 8002cec: 4322 orrs r2, r4 + 8002cee: b292 uxth r2, r2 + 8002cf0: 801a strh r2, [r3, #0] + 8002cf2: e090 b.n 8002e16 + } + else + { + /* Clear the data toggle bits for the endpoint IN/OUT */ + PCD_CLEAR_RX_DTOG(USBx, ep->num); + 8002cf4: 687a ldr r2, [r7, #4] + 8002cf6: 683b ldr r3, [r7, #0] + 8002cf8: 781b ldrb r3, [r3, #0] + 8002cfa: 009b lsls r3, r3, #2 + 8002cfc: 18d3 adds r3, r2, r3 + 8002cfe: 881b ldrh r3, [r3, #0] + 8002d00: b29c uxth r4, r3 + 8002d02: 0022 movs r2, r4 + 8002d04: 2380 movs r3, #128 ; 0x80 + 8002d06: 01db lsls r3, r3, #7 + 8002d08: 4013 ands r3, r2 + 8002d0a: d012 beq.n 8002d32 + 8002d0c: 687a ldr r2, [r7, #4] + 8002d0e: 683b ldr r3, [r7, #0] + 8002d10: 781b ldrb r3, [r3, #0] + 8002d12: 009b lsls r3, r3, #2 + 8002d14: 18d3 adds r3, r2, r3 + 8002d16: 881b ldrh r3, [r3, #0] + 8002d18: b29b uxth r3, r3 + 8002d1a: 4a42 ldr r2, [pc, #264] ; (8002e24 ) + 8002d1c: 4013 ands r3, r2 + 8002d1e: b29c uxth r4, r3 + 8002d20: 687a ldr r2, [r7, #4] + 8002d22: 683b ldr r3, [r7, #0] + 8002d24: 781b ldrb r3, [r3, #0] + 8002d26: 009b lsls r3, r3, #2 + 8002d28: 18d3 adds r3, r2, r3 + 8002d2a: 4a41 ldr r2, [pc, #260] ; (8002e30 ) + 8002d2c: 4322 orrs r2, r4 + 8002d2e: b292 uxth r2, r2 + 8002d30: 801a strh r2, [r3, #0] + PCD_CLEAR_TX_DTOG(USBx, ep->num); + 8002d32: 687a ldr r2, [r7, #4] + 8002d34: 683b ldr r3, [r7, #0] + 8002d36: 781b ldrb r3, [r3, #0] + 8002d38: 009b lsls r3, r3, #2 + 8002d3a: 18d3 adds r3, r2, r3 + 8002d3c: 881b ldrh r3, [r3, #0] + 8002d3e: b29c uxth r4, r3 + 8002d40: 0022 movs r2, r4 + 8002d42: 2340 movs r3, #64 ; 0x40 + 8002d44: 4013 ands r3, r2 + 8002d46: d012 beq.n 8002d6e + 8002d48: 687a ldr r2, [r7, #4] + 8002d4a: 683b ldr r3, [r7, #0] + 8002d4c: 781b ldrb r3, [r3, #0] + 8002d4e: 009b lsls r3, r3, #2 + 8002d50: 18d3 adds r3, r2, r3 + 8002d52: 881b ldrh r3, [r3, #0] + 8002d54: b29b uxth r3, r3 + 8002d56: 4a33 ldr r2, [pc, #204] ; (8002e24 ) + 8002d58: 4013 ands r3, r2 + 8002d5a: b29c uxth r4, r3 + 8002d5c: 687a ldr r2, [r7, #4] + 8002d5e: 683b ldr r3, [r7, #0] + 8002d60: 781b ldrb r3, [r3, #0] + 8002d62: 009b lsls r3, r3, #2 + 8002d64: 18d3 adds r3, r2, r3 + 8002d66: 4a33 ldr r2, [pc, #204] ; (8002e34 ) + 8002d68: 4322 orrs r2, r4 + 8002d6a: b292 uxth r2, r2 + 8002d6c: 801a strh r2, [r3, #0] + PCD_RX_DTOG(USBx, ep->num); + 8002d6e: 687a ldr r2, [r7, #4] + 8002d70: 683b ldr r3, [r7, #0] + 8002d72: 781b ldrb r3, [r3, #0] + 8002d74: 009b lsls r3, r3, #2 + 8002d76: 18d3 adds r3, r2, r3 + 8002d78: 881b ldrh r3, [r3, #0] + 8002d7a: b29b uxth r3, r3 + 8002d7c: 4a29 ldr r2, [pc, #164] ; (8002e24 ) + 8002d7e: 4013 ands r3, r2 + 8002d80: b29c uxth r4, r3 + 8002d82: 687a ldr r2, [r7, #4] + 8002d84: 683b ldr r3, [r7, #0] + 8002d86: 781b ldrb r3, [r3, #0] + 8002d88: 009b lsls r3, r3, #2 + 8002d8a: 18d3 adds r3, r2, r3 + 8002d8c: 4a28 ldr r2, [pc, #160] ; (8002e30 ) + 8002d8e: 4322 orrs r2, r4 + 8002d90: b292 uxth r2, r2 + 8002d92: 801a strh r2, [r3, #0] + + if (ep->type != EP_TYPE_ISOC) + 8002d94: 683b ldr r3, [r7, #0] + 8002d96: 78db ldrb r3, [r3, #3] + 8002d98: 2b01 cmp r3, #1 + 8002d9a: d016 beq.n 8002dca + { + /* Configure NAK status for the Endpoint */ + PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_NAK); + 8002d9c: 687a ldr r2, [r7, #4] + 8002d9e: 683b ldr r3, [r7, #0] + 8002da0: 781b ldrb r3, [r3, #0] + 8002da2: 009b lsls r3, r3, #2 + 8002da4: 18d3 adds r3, r2, r3 + 8002da6: 881b ldrh r3, [r3, #0] + 8002da8: b29b uxth r3, r3 + 8002daa: 4a25 ldr r2, [pc, #148] ; (8002e40 ) + 8002dac: 4013 ands r3, r2 + 8002dae: b29c uxth r4, r3 + 8002db0: 2320 movs r3, #32 + 8002db2: 4063 eors r3, r4 + 8002db4: b29c uxth r4, r3 + 8002db6: 687a ldr r2, [r7, #4] + 8002db8: 683b ldr r3, [r7, #0] + 8002dba: 781b ldrb r3, [r3, #0] + 8002dbc: 009b lsls r3, r3, #2 + 8002dbe: 18d3 adds r3, r2, r3 + 8002dc0: 4a1e ldr r2, [pc, #120] ; (8002e3c ) + 8002dc2: 4322 orrs r2, r4 + 8002dc4: b292 uxth r2, r2 + 8002dc6: 801a strh r2, [r3, #0] + 8002dc8: e012 b.n 8002df0 + } + else + { + /* Configure TX Endpoint to disabled state */ + PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS); + 8002dca: 687a ldr r2, [r7, #4] + 8002dcc: 683b ldr r3, [r7, #0] + 8002dce: 781b ldrb r3, [r3, #0] + 8002dd0: 009b lsls r3, r3, #2 + 8002dd2: 18d3 adds r3, r2, r3 + 8002dd4: 881b ldrh r3, [r3, #0] + 8002dd6: b29b uxth r3, r3 + 8002dd8: 4a19 ldr r2, [pc, #100] ; (8002e40 ) + 8002dda: 4013 ands r3, r2 + 8002ddc: b29c uxth r4, r3 + 8002dde: 687a ldr r2, [r7, #4] + 8002de0: 683b ldr r3, [r7, #0] + 8002de2: 781b ldrb r3, [r3, #0] + 8002de4: 009b lsls r3, r3, #2 + 8002de6: 18d3 adds r3, r2, r3 + 8002de8: 4a14 ldr r2, [pc, #80] ; (8002e3c ) + 8002dea: 4322 orrs r2, r4 + 8002dec: b292 uxth r2, r2 + 8002dee: 801a strh r2, [r3, #0] + } + + PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_DIS); + 8002df0: 687a ldr r2, [r7, #4] + 8002df2: 683b ldr r3, [r7, #0] + 8002df4: 781b ldrb r3, [r3, #0] + 8002df6: 009b lsls r3, r3, #2 + 8002df8: 18d3 adds r3, r2, r3 + 8002dfa: 881b ldrh r3, [r3, #0] + 8002dfc: b29b uxth r3, r3 + 8002dfe: 4a0e ldr r2, [pc, #56] ; (8002e38 ) + 8002e00: 4013 ands r3, r2 + 8002e02: b29c uxth r4, r3 + 8002e04: 687a ldr r2, [r7, #4] + 8002e06: 683b ldr r3, [r7, #0] + 8002e08: 781b ldrb r3, [r3, #0] + 8002e0a: 009b lsls r3, r3, #2 + 8002e0c: 18d3 adds r3, r2, r3 + 8002e0e: 4a0b ldr r2, [pc, #44] ; (8002e3c ) + 8002e10: 4322 orrs r2, r4 + 8002e12: b292 uxth r2, r2 + 8002e14: 801a strh r2, [r3, #0] + } + } + + return ret; + 8002e16: 2317 movs r3, #23 + 8002e18: 18fb adds r3, r7, r3 + 8002e1a: 781b ldrb r3, [r3, #0] +} + 8002e1c: 0018 movs r0, r3 + 8002e1e: 46bd mov sp, r7 + 8002e20: b007 add sp, #28 + 8002e22: bd90 pop {r4, r7, pc} + 8002e24: ffff8f8f .word 0xffff8f8f + 8002e28: ffff8180 .word 0xffff8180 + 8002e2c: 00000404 .word 0x00000404 + 8002e30: ffffc080 .word 0xffffc080 + 8002e34: ffff80c0 .word 0xffff80c0 + 8002e38: ffffbf8f .word 0xffffbf8f + 8002e3c: ffff8080 .word 0xffff8080 + 8002e40: ffff8fbf .word 0xffff8fbf + +08002e44 : + * @param USBx : Selected device + * @param ep: pointer to endpoint structure + * @retval HAL status + */ +HAL_StatusTypeDef USB_DeactivateEndpoint(USB_TypeDef *USBx, USB_EPTypeDef *ep) +{ + 8002e44: b590 push {r4, r7, lr} + 8002e46: b083 sub sp, #12 + 8002e48: af00 add r7, sp, #0 + 8002e4a: 6078 str r0, [r7, #4] + 8002e4c: 6039 str r1, [r7, #0] + if (ep->doublebuffer == 0U) + 8002e4e: 683b ldr r3, [r7, #0] + 8002e50: 7b1b ldrb r3, [r3, #12] + 8002e52: 2b00 cmp r3, #0 + 8002e54: d168 bne.n 8002f28 + { + if (ep->is_in != 0U) + 8002e56: 683b ldr r3, [r7, #0] + 8002e58: 785b ldrb r3, [r3, #1] + 8002e5a: 2b00 cmp r3, #0 + 8002e5c: d031 beq.n 8002ec2 + { + PCD_CLEAR_TX_DTOG(USBx, ep->num); + 8002e5e: 687a ldr r2, [r7, #4] + 8002e60: 683b ldr r3, [r7, #0] + 8002e62: 781b ldrb r3, [r3, #0] + 8002e64: 009b lsls r3, r3, #2 + 8002e66: 18d3 adds r3, r2, r3 + 8002e68: 881b ldrh r3, [r3, #0] + 8002e6a: b29c uxth r4, r3 + 8002e6c: 0022 movs r2, r4 + 8002e6e: 2340 movs r3, #64 ; 0x40 + 8002e70: 4013 ands r3, r2 + 8002e72: d012 beq.n 8002e9a + 8002e74: 687a ldr r2, [r7, #4] + 8002e76: 683b ldr r3, [r7, #0] + 8002e78: 781b ldrb r3, [r3, #0] + 8002e7a: 009b lsls r3, r3, #2 + 8002e7c: 18d3 adds r3, r2, r3 + 8002e7e: 881b ldrh r3, [r3, #0] + 8002e80: b29b uxth r3, r3 + 8002e82: 4aa5 ldr r2, [pc, #660] ; (8003118 ) + 8002e84: 4013 ands r3, r2 + 8002e86: b29c uxth r4, r3 + 8002e88: 687a ldr r2, [r7, #4] + 8002e8a: 683b ldr r3, [r7, #0] + 8002e8c: 781b ldrb r3, [r3, #0] + 8002e8e: 009b lsls r3, r3, #2 + 8002e90: 18d3 adds r3, r2, r3 + 8002e92: 4aa2 ldr r2, [pc, #648] ; (800311c ) + 8002e94: 4322 orrs r2, r4 + 8002e96: b292 uxth r2, r2 + 8002e98: 801a strh r2, [r3, #0] + /* Configure DISABLE status for the Endpoint*/ + PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS); + 8002e9a: 687a ldr r2, [r7, #4] + 8002e9c: 683b ldr r3, [r7, #0] + 8002e9e: 781b ldrb r3, [r3, #0] + 8002ea0: 009b lsls r3, r3, #2 + 8002ea2: 18d3 adds r3, r2, r3 + 8002ea4: 881b ldrh r3, [r3, #0] + 8002ea6: b29b uxth r3, r3 + 8002ea8: 4a9d ldr r2, [pc, #628] ; (8003120 ) + 8002eaa: 4013 ands r3, r2 + 8002eac: b29c uxth r4, r3 + 8002eae: 687a ldr r2, [r7, #4] + 8002eb0: 683b ldr r3, [r7, #0] + 8002eb2: 781b ldrb r3, [r3, #0] + 8002eb4: 009b lsls r3, r3, #2 + 8002eb6: 18d3 adds r3, r2, r3 + 8002eb8: 4a9a ldr r2, [pc, #616] ; (8003124 ) + 8002eba: 4322 orrs r2, r4 + 8002ebc: b292 uxth r2, r2 + 8002ebe: 801a strh r2, [r3, #0] + 8002ec0: e124 b.n 800310c + } + else + { + PCD_CLEAR_RX_DTOG(USBx, ep->num); + 8002ec2: 687a ldr r2, [r7, #4] + 8002ec4: 683b ldr r3, [r7, #0] + 8002ec6: 781b ldrb r3, [r3, #0] + 8002ec8: 009b lsls r3, r3, #2 + 8002eca: 18d3 adds r3, r2, r3 + 8002ecc: 881b ldrh r3, [r3, #0] + 8002ece: b29c uxth r4, r3 + 8002ed0: 0022 movs r2, r4 + 8002ed2: 2380 movs r3, #128 ; 0x80 + 8002ed4: 01db lsls r3, r3, #7 + 8002ed6: 4013 ands r3, r2 + 8002ed8: d012 beq.n 8002f00 + 8002eda: 687a ldr r2, [r7, #4] + 8002edc: 683b ldr r3, [r7, #0] + 8002ede: 781b ldrb r3, [r3, #0] + 8002ee0: 009b lsls r3, r3, #2 + 8002ee2: 18d3 adds r3, r2, r3 + 8002ee4: 881b ldrh r3, [r3, #0] + 8002ee6: b29b uxth r3, r3 + 8002ee8: 4a8b ldr r2, [pc, #556] ; (8003118 ) + 8002eea: 4013 ands r3, r2 + 8002eec: b29c uxth r4, r3 + 8002eee: 687a ldr r2, [r7, #4] + 8002ef0: 683b ldr r3, [r7, #0] + 8002ef2: 781b ldrb r3, [r3, #0] + 8002ef4: 009b lsls r3, r3, #2 + 8002ef6: 18d3 adds r3, r2, r3 + 8002ef8: 4a8b ldr r2, [pc, #556] ; (8003128 ) + 8002efa: 4322 orrs r2, r4 + 8002efc: b292 uxth r2, r2 + 8002efe: 801a strh r2, [r3, #0] + /* Configure DISABLE status for the Endpoint*/ + PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_DIS); + 8002f00: 687a ldr r2, [r7, #4] + 8002f02: 683b ldr r3, [r7, #0] + 8002f04: 781b ldrb r3, [r3, #0] + 8002f06: 009b lsls r3, r3, #2 + 8002f08: 18d3 adds r3, r2, r3 + 8002f0a: 881b ldrh r3, [r3, #0] + 8002f0c: b29b uxth r3, r3 + 8002f0e: 4a87 ldr r2, [pc, #540] ; (800312c ) + 8002f10: 4013 ands r3, r2 + 8002f12: b29c uxth r4, r3 + 8002f14: 687a ldr r2, [r7, #4] + 8002f16: 683b ldr r3, [r7, #0] + 8002f18: 781b ldrb r3, [r3, #0] + 8002f1a: 009b lsls r3, r3, #2 + 8002f1c: 18d3 adds r3, r2, r3 + 8002f1e: 4a81 ldr r2, [pc, #516] ; (8003124 ) + 8002f20: 4322 orrs r2, r4 + 8002f22: b292 uxth r2, r2 + 8002f24: 801a strh r2, [r3, #0] + 8002f26: e0f1 b.n 800310c + } + } + /*Double Buffer*/ + else + { + if (ep->is_in == 0U) + 8002f28: 683b ldr r3, [r7, #0] + 8002f2a: 785b ldrb r3, [r3, #1] + 8002f2c: 2b00 cmp r3, #0 + 8002f2e: d000 beq.n 8002f32 + 8002f30: e076 b.n 8003020 + { + /* Clear the data toggle bits for the endpoint IN/OUT*/ + PCD_CLEAR_RX_DTOG(USBx, ep->num); + 8002f32: 687a ldr r2, [r7, #4] + 8002f34: 683b ldr r3, [r7, #0] + 8002f36: 781b ldrb r3, [r3, #0] + 8002f38: 009b lsls r3, r3, #2 + 8002f3a: 18d3 adds r3, r2, r3 + 8002f3c: 881b ldrh r3, [r3, #0] + 8002f3e: b29c uxth r4, r3 + 8002f40: 0022 movs r2, r4 + 8002f42: 2380 movs r3, #128 ; 0x80 + 8002f44: 01db lsls r3, r3, #7 + 8002f46: 4013 ands r3, r2 + 8002f48: d012 beq.n 8002f70 + 8002f4a: 687a ldr r2, [r7, #4] + 8002f4c: 683b ldr r3, [r7, #0] + 8002f4e: 781b ldrb r3, [r3, #0] + 8002f50: 009b lsls r3, r3, #2 + 8002f52: 18d3 adds r3, r2, r3 + 8002f54: 881b ldrh r3, [r3, #0] + 8002f56: b29b uxth r3, r3 + 8002f58: 4a6f ldr r2, [pc, #444] ; (8003118 ) + 8002f5a: 4013 ands r3, r2 + 8002f5c: b29c uxth r4, r3 + 8002f5e: 687a ldr r2, [r7, #4] + 8002f60: 683b ldr r3, [r7, #0] + 8002f62: 781b ldrb r3, [r3, #0] + 8002f64: 009b lsls r3, r3, #2 + 8002f66: 18d3 adds r3, r2, r3 + 8002f68: 4a6f ldr r2, [pc, #444] ; (8003128 ) + 8002f6a: 4322 orrs r2, r4 + 8002f6c: b292 uxth r2, r2 + 8002f6e: 801a strh r2, [r3, #0] + PCD_CLEAR_TX_DTOG(USBx, ep->num); + 8002f70: 687a ldr r2, [r7, #4] + 8002f72: 683b ldr r3, [r7, #0] + 8002f74: 781b ldrb r3, [r3, #0] + 8002f76: 009b lsls r3, r3, #2 + 8002f78: 18d3 adds r3, r2, r3 + 8002f7a: 881b ldrh r3, [r3, #0] + 8002f7c: b29c uxth r4, r3 + 8002f7e: 0022 movs r2, r4 + 8002f80: 2340 movs r3, #64 ; 0x40 + 8002f82: 4013 ands r3, r2 + 8002f84: d012 beq.n 8002fac + 8002f86: 687a ldr r2, [r7, #4] + 8002f88: 683b ldr r3, [r7, #0] + 8002f8a: 781b ldrb r3, [r3, #0] + 8002f8c: 009b lsls r3, r3, #2 + 8002f8e: 18d3 adds r3, r2, r3 + 8002f90: 881b ldrh r3, [r3, #0] + 8002f92: b29b uxth r3, r3 + 8002f94: 4a60 ldr r2, [pc, #384] ; (8003118 ) + 8002f96: 4013 ands r3, r2 + 8002f98: b29c uxth r4, r3 + 8002f9a: 687a ldr r2, [r7, #4] + 8002f9c: 683b ldr r3, [r7, #0] + 8002f9e: 781b ldrb r3, [r3, #0] + 8002fa0: 009b lsls r3, r3, #2 + 8002fa2: 18d3 adds r3, r2, r3 + 8002fa4: 4a5d ldr r2, [pc, #372] ; (800311c ) + 8002fa6: 4322 orrs r2, r4 + 8002fa8: b292 uxth r2, r2 + 8002faa: 801a strh r2, [r3, #0] + + /* Reset value of the data toggle bits for the endpoint out*/ + PCD_TX_DTOG(USBx, ep->num); + 8002fac: 687a ldr r2, [r7, #4] + 8002fae: 683b ldr r3, [r7, #0] + 8002fb0: 781b ldrb r3, [r3, #0] + 8002fb2: 009b lsls r3, r3, #2 + 8002fb4: 18d3 adds r3, r2, r3 + 8002fb6: 881b ldrh r3, [r3, #0] + 8002fb8: b29b uxth r3, r3 + 8002fba: 4a57 ldr r2, [pc, #348] ; (8003118 ) + 8002fbc: 4013 ands r3, r2 + 8002fbe: b29c uxth r4, r3 + 8002fc0: 687a ldr r2, [r7, #4] + 8002fc2: 683b ldr r3, [r7, #0] + 8002fc4: 781b ldrb r3, [r3, #0] + 8002fc6: 009b lsls r3, r3, #2 + 8002fc8: 18d3 adds r3, r2, r3 + 8002fca: 4a54 ldr r2, [pc, #336] ; (800311c ) + 8002fcc: 4322 orrs r2, r4 + 8002fce: b292 uxth r2, r2 + 8002fd0: 801a strh r2, [r3, #0] + + PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_DIS); + 8002fd2: 687a ldr r2, [r7, #4] + 8002fd4: 683b ldr r3, [r7, #0] + 8002fd6: 781b ldrb r3, [r3, #0] + 8002fd8: 009b lsls r3, r3, #2 + 8002fda: 18d3 adds r3, r2, r3 + 8002fdc: 881b ldrh r3, [r3, #0] + 8002fde: b29b uxth r3, r3 + 8002fe0: 4a52 ldr r2, [pc, #328] ; (800312c ) + 8002fe2: 4013 ands r3, r2 + 8002fe4: b29c uxth r4, r3 + 8002fe6: 687a ldr r2, [r7, #4] + 8002fe8: 683b ldr r3, [r7, #0] + 8002fea: 781b ldrb r3, [r3, #0] + 8002fec: 009b lsls r3, r3, #2 + 8002fee: 18d3 adds r3, r2, r3 + 8002ff0: 4a4c ldr r2, [pc, #304] ; (8003124 ) + 8002ff2: 4322 orrs r2, r4 + 8002ff4: b292 uxth r2, r2 + 8002ff6: 801a strh r2, [r3, #0] + PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS); + 8002ff8: 687a ldr r2, [r7, #4] + 8002ffa: 683b ldr r3, [r7, #0] + 8002ffc: 781b ldrb r3, [r3, #0] + 8002ffe: 009b lsls r3, r3, #2 + 8003000: 18d3 adds r3, r2, r3 + 8003002: 881b ldrh r3, [r3, #0] + 8003004: b29b uxth r3, r3 + 8003006: 4a46 ldr r2, [pc, #280] ; (8003120 ) + 8003008: 4013 ands r3, r2 + 800300a: b29c uxth r4, r3 + 800300c: 687a ldr r2, [r7, #4] + 800300e: 683b ldr r3, [r7, #0] + 8003010: 781b ldrb r3, [r3, #0] + 8003012: 009b lsls r3, r3, #2 + 8003014: 18d3 adds r3, r2, r3 + 8003016: 4a43 ldr r2, [pc, #268] ; (8003124 ) + 8003018: 4322 orrs r2, r4 + 800301a: b292 uxth r2, r2 + 800301c: 801a strh r2, [r3, #0] + 800301e: e075 b.n 800310c + } + else + { + /* Clear the data toggle bits for the endpoint IN/OUT*/ + PCD_CLEAR_RX_DTOG(USBx, ep->num); + 8003020: 687a ldr r2, [r7, #4] + 8003022: 683b ldr r3, [r7, #0] + 8003024: 781b ldrb r3, [r3, #0] + 8003026: 009b lsls r3, r3, #2 + 8003028: 18d3 adds r3, r2, r3 + 800302a: 881b ldrh r3, [r3, #0] + 800302c: b29c uxth r4, r3 + 800302e: 0022 movs r2, r4 + 8003030: 2380 movs r3, #128 ; 0x80 + 8003032: 01db lsls r3, r3, #7 + 8003034: 4013 ands r3, r2 + 8003036: d012 beq.n 800305e + 8003038: 687a ldr r2, [r7, #4] + 800303a: 683b ldr r3, [r7, #0] + 800303c: 781b ldrb r3, [r3, #0] + 800303e: 009b lsls r3, r3, #2 + 8003040: 18d3 adds r3, r2, r3 + 8003042: 881b ldrh r3, [r3, #0] + 8003044: b29b uxth r3, r3 + 8003046: 4a34 ldr r2, [pc, #208] ; (8003118 ) + 8003048: 4013 ands r3, r2 + 800304a: b29c uxth r4, r3 + 800304c: 687a ldr r2, [r7, #4] + 800304e: 683b ldr r3, [r7, #0] + 8003050: 781b ldrb r3, [r3, #0] + 8003052: 009b lsls r3, r3, #2 + 8003054: 18d3 adds r3, r2, r3 + 8003056: 4a34 ldr r2, [pc, #208] ; (8003128 ) + 8003058: 4322 orrs r2, r4 + 800305a: b292 uxth r2, r2 + 800305c: 801a strh r2, [r3, #0] + PCD_CLEAR_TX_DTOG(USBx, ep->num); + 800305e: 687a ldr r2, [r7, #4] + 8003060: 683b ldr r3, [r7, #0] + 8003062: 781b ldrb r3, [r3, #0] + 8003064: 009b lsls r3, r3, #2 + 8003066: 18d3 adds r3, r2, r3 + 8003068: 881b ldrh r3, [r3, #0] + 800306a: b29c uxth r4, r3 + 800306c: 0022 movs r2, r4 + 800306e: 2340 movs r3, #64 ; 0x40 + 8003070: 4013 ands r3, r2 + 8003072: d012 beq.n 800309a + 8003074: 687a ldr r2, [r7, #4] + 8003076: 683b ldr r3, [r7, #0] + 8003078: 781b ldrb r3, [r3, #0] + 800307a: 009b lsls r3, r3, #2 + 800307c: 18d3 adds r3, r2, r3 + 800307e: 881b ldrh r3, [r3, #0] + 8003080: b29b uxth r3, r3 + 8003082: 4a25 ldr r2, [pc, #148] ; (8003118 ) + 8003084: 4013 ands r3, r2 + 8003086: b29c uxth r4, r3 + 8003088: 687a ldr r2, [r7, #4] + 800308a: 683b ldr r3, [r7, #0] + 800308c: 781b ldrb r3, [r3, #0] + 800308e: 009b lsls r3, r3, #2 + 8003090: 18d3 adds r3, r2, r3 + 8003092: 4a22 ldr r2, [pc, #136] ; (800311c ) + 8003094: 4322 orrs r2, r4 + 8003096: b292 uxth r2, r2 + 8003098: 801a strh r2, [r3, #0] + PCD_RX_DTOG(USBx, ep->num); + 800309a: 687a ldr r2, [r7, #4] + 800309c: 683b ldr r3, [r7, #0] + 800309e: 781b ldrb r3, [r3, #0] + 80030a0: 009b lsls r3, r3, #2 + 80030a2: 18d3 adds r3, r2, r3 + 80030a4: 881b ldrh r3, [r3, #0] + 80030a6: b29b uxth r3, r3 + 80030a8: 4a1b ldr r2, [pc, #108] ; (8003118 ) + 80030aa: 4013 ands r3, r2 + 80030ac: b29c uxth r4, r3 + 80030ae: 687a ldr r2, [r7, #4] + 80030b0: 683b ldr r3, [r7, #0] + 80030b2: 781b ldrb r3, [r3, #0] + 80030b4: 009b lsls r3, r3, #2 + 80030b6: 18d3 adds r3, r2, r3 + 80030b8: 4a1b ldr r2, [pc, #108] ; (8003128 ) + 80030ba: 4322 orrs r2, r4 + 80030bc: b292 uxth r2, r2 + 80030be: 801a strh r2, [r3, #0] + /* Configure DISABLE status for the Endpoint*/ + PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS); + 80030c0: 687a ldr r2, [r7, #4] + 80030c2: 683b ldr r3, [r7, #0] + 80030c4: 781b ldrb r3, [r3, #0] + 80030c6: 009b lsls r3, r3, #2 + 80030c8: 18d3 adds r3, r2, r3 + 80030ca: 881b ldrh r3, [r3, #0] + 80030cc: b29b uxth r3, r3 + 80030ce: 4a14 ldr r2, [pc, #80] ; (8003120 ) + 80030d0: 4013 ands r3, r2 + 80030d2: b29c uxth r4, r3 + 80030d4: 687a ldr r2, [r7, #4] + 80030d6: 683b ldr r3, [r7, #0] + 80030d8: 781b ldrb r3, [r3, #0] + 80030da: 009b lsls r3, r3, #2 + 80030dc: 18d3 adds r3, r2, r3 + 80030de: 4a11 ldr r2, [pc, #68] ; (8003124 ) + 80030e0: 4322 orrs r2, r4 + 80030e2: b292 uxth r2, r2 + 80030e4: 801a strh r2, [r3, #0] + PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_DIS); + 80030e6: 687a ldr r2, [r7, #4] + 80030e8: 683b ldr r3, [r7, #0] + 80030ea: 781b ldrb r3, [r3, #0] + 80030ec: 009b lsls r3, r3, #2 + 80030ee: 18d3 adds r3, r2, r3 + 80030f0: 881b ldrh r3, [r3, #0] + 80030f2: b29b uxth r3, r3 + 80030f4: 4a0d ldr r2, [pc, #52] ; (800312c ) + 80030f6: 4013 ands r3, r2 + 80030f8: b29c uxth r4, r3 + 80030fa: 687a ldr r2, [r7, #4] + 80030fc: 683b ldr r3, [r7, #0] + 80030fe: 781b ldrb r3, [r3, #0] + 8003100: 009b lsls r3, r3, #2 + 8003102: 18d3 adds r3, r2, r3 + 8003104: 4a07 ldr r2, [pc, #28] ; (8003124 ) + 8003106: 4322 orrs r2, r4 + 8003108: b292 uxth r2, r2 + 800310a: 801a strh r2, [r3, #0] + } + } + + return HAL_OK; + 800310c: 2300 movs r3, #0 +} + 800310e: 0018 movs r0, r3 + 8003110: 46bd mov sp, r7 + 8003112: b003 add sp, #12 + 8003114: bd90 pop {r4, r7, pc} + 8003116: 46c0 nop ; (mov r8, r8) + 8003118: ffff8f8f .word 0xffff8f8f + 800311c: ffff80c0 .word 0xffff80c0 + 8003120: ffff8fbf .word 0xffff8fbf + 8003124: ffff8080 .word 0xffff8080 + 8003128: ffffc080 .word 0xffffc080 + 800312c: ffffbf8f .word 0xffffbf8f + +08003130 : + * @param USBx : Selected device + * @param ep: pointer to endpoint structure + * @retval HAL status + */ +HAL_StatusTypeDef USB_EPStartXfer(USB_TypeDef *USBx, USB_EPTypeDef *ep) +{ + 8003130: b590 push {r4, r7, lr} + 8003132: b095 sub sp, #84 ; 0x54 + 8003134: af00 add r7, sp, #0 + 8003136: 6078 str r0, [r7, #4] + 8003138: 6039 str r1, [r7, #0] + uint16_t pmabuffer; + uint32_t len; + + /* IN endpoint */ + if (ep->is_in == 1U) + 800313a: 683b ldr r3, [r7, #0] + 800313c: 785b ldrb r3, [r3, #1] + 800313e: 2b01 cmp r3, #1 + 8003140: d000 beq.n 8003144 + 8003142: e163 b.n 800340c + { + /*Multi packet transfer*/ + if (ep->xfer_len > ep->maxpacket) + 8003144: 683b ldr r3, [r7, #0] + 8003146: 699a ldr r2, [r3, #24] + 8003148: 683b ldr r3, [r7, #0] + 800314a: 691b ldr r3, [r3, #16] + 800314c: 429a cmp r2, r3 + 800314e: d909 bls.n 8003164 + { + len = ep->maxpacket; + 8003150: 683b ldr r3, [r7, #0] + 8003152: 691b ldr r3, [r3, #16] + 8003154: 64bb str r3, [r7, #72] ; 0x48 + ep->xfer_len -= len; + 8003156: 683b ldr r3, [r7, #0] + 8003158: 699a ldr r2, [r3, #24] + 800315a: 6cbb ldr r3, [r7, #72] ; 0x48 + 800315c: 1ad2 subs r2, r2, r3 + 800315e: 683b ldr r3, [r7, #0] + 8003160: 619a str r2, [r3, #24] + 8003162: e005 b.n 8003170 + } + else + { + len = ep->xfer_len; + 8003164: 683b ldr r3, [r7, #0] + 8003166: 699b ldr r3, [r3, #24] + 8003168: 64bb str r3, [r7, #72] ; 0x48 + ep->xfer_len = 0U; + 800316a: 683b ldr r3, [r7, #0] + 800316c: 2200 movs r2, #0 + 800316e: 619a str r2, [r3, #24] + } + + /* configure and validate Tx endpoint */ + if (ep->doublebuffer == 0U) + 8003170: 683b ldr r3, [r7, #0] + 8003172: 7b1b ldrb r3, [r3, #12] + 8003174: 2b00 cmp r3, #0 + 8003176: d11b bne.n 80031b0 + { + USB_WritePMA(USBx, ep->xfer_buff, ep->pmaadress, (uint16_t)len); + 8003178: 683b ldr r3, [r7, #0] + 800317a: 6959 ldr r1, [r3, #20] + 800317c: 683b ldr r3, [r7, #0] + 800317e: 88da ldrh r2, [r3, #6] + 8003180: 6cbb ldr r3, [r7, #72] ; 0x48 + 8003182: b29b uxth r3, r3 + 8003184: 6878 ldr r0, [r7, #4] + 8003186: f000 fbbb bl 8003900 + PCD_SET_EP_TX_CNT(USBx, ep->num, len); + 800318a: 687c ldr r4, [r7, #4] + 800318c: 687b ldr r3, [r7, #4] + 800318e: 2250 movs r2, #80 ; 0x50 + 8003190: 5a9b ldrh r3, [r3, r2] + 8003192: b29b uxth r3, r3 + 8003194: 18e4 adds r4, r4, r3 + 8003196: 683b ldr r3, [r7, #0] + 8003198: 781b ldrb r3, [r3, #0] + 800319a: 00db lsls r3, r3, #3 + 800319c: 18e3 adds r3, r4, r3 + 800319e: 4acc ldr r2, [pc, #816] ; (80034d0 ) + 80031a0: 4694 mov ip, r2 + 80031a2: 4463 add r3, ip + 80031a4: 60fb str r3, [r7, #12] + 80031a6: 6cbb ldr r3, [r7, #72] ; 0x48 + 80031a8: b29a uxth r2, r3 + 80031aa: 68fb ldr r3, [r7, #12] + 80031ac: 801a strh r2, [r3, #0] + 80031ae: e113 b.n 80033d8 + } + else + { + /* Write the data to the USB endpoint */ + if ((PCD_GET_ENDPOINT(USBx, ep->num) & USB_EP_DTOG_TX) != 0U) + 80031b0: 687a ldr r2, [r7, #4] + 80031b2: 683b ldr r3, [r7, #0] + 80031b4: 781b ldrb r3, [r3, #0] + 80031b6: 009b lsls r3, r3, #2 + 80031b8: 18d3 adds r3, r2, r3 + 80031ba: 881b ldrh r3, [r3, #0] + 80031bc: b29b uxth r3, r3 + 80031be: 001a movs r2, r3 + 80031c0: 2340 movs r3, #64 ; 0x40 + 80031c2: 4013 ands r3, r2 + 80031c4: d067 beq.n 8003296 + { + /* Set the Double buffer counter for pmabuffer1 */ + PCD_SET_EP_DBUF1_CNT(USBx, ep->num, ep->is_in, len); + 80031c6: 687c ldr r4, [r7, #4] + 80031c8: 683b ldr r3, [r7, #0] + 80031ca: 785b ldrb r3, [r3, #1] + 80031cc: 2b00 cmp r3, #0 + 80031ce: d147 bne.n 8003260 + 80031d0: 687c ldr r4, [r7, #4] + 80031d2: 687b ldr r3, [r7, #4] + 80031d4: 2250 movs r2, #80 ; 0x50 + 80031d6: 5a9b ldrh r3, [r3, r2] + 80031d8: b29b uxth r3, r3 + 80031da: 18e4 adds r4, r4, r3 + 80031dc: 683b ldr r3, [r7, #0] + 80031de: 781b ldrb r3, [r3, #0] + 80031e0: 00db lsls r3, r3, #3 + 80031e2: 18e3 adds r3, r4, r3 + 80031e4: 4abb ldr r2, [pc, #748] ; (80034d4 ) + 80031e6: 4694 mov ip, r2 + 80031e8: 4463 add r3, ip + 80031ea: 613b str r3, [r7, #16] + 80031ec: 6cbb ldr r3, [r7, #72] ; 0x48 + 80031ee: 2b00 cmp r3, #0 + 80031f0: d10e bne.n 8003210 + 80031f2: 693b ldr r3, [r7, #16] + 80031f4: 881b ldrh r3, [r3, #0] + 80031f6: 4ab8 ldr r2, [pc, #736] ; (80034d8 ) + 80031f8: 4013 ands r3, r2 + 80031fa: b29a uxth r2, r3 + 80031fc: 693b ldr r3, [r7, #16] + 80031fe: 801a strh r2, [r3, #0] + 8003200: 693b ldr r3, [r7, #16] + 8003202: 881b ldrh r3, [r3, #0] + 8003204: 4ab5 ldr r2, [pc, #724] ; (80034dc ) + 8003206: 4313 orrs r3, r2 + 8003208: b29a uxth r2, r3 + 800320a: 693b ldr r3, [r7, #16] + 800320c: 801a strh r2, [r3, #0] + 800320e: e03c b.n 800328a + 8003210: 6cbb ldr r3, [r7, #72] ; 0x48 + 8003212: 2b3e cmp r3, #62 ; 0x3e + 8003214: d810 bhi.n 8003238 + 8003216: 6cbb ldr r3, [r7, #72] ; 0x48 + 8003218: 085b lsrs r3, r3, #1 + 800321a: 647b str r3, [r7, #68] ; 0x44 + 800321c: 6cbb ldr r3, [r7, #72] ; 0x48 + 800321e: 2201 movs r2, #1 + 8003220: 4013 ands r3, r2 + 8003222: d002 beq.n 800322a + 8003224: 6c7b ldr r3, [r7, #68] ; 0x44 + 8003226: 3301 adds r3, #1 + 8003228: 647b str r3, [r7, #68] ; 0x44 + 800322a: 6c7b ldr r3, [r7, #68] ; 0x44 + 800322c: b29b uxth r3, r3 + 800322e: 029b lsls r3, r3, #10 + 8003230: b29a uxth r2, r3 + 8003232: 693b ldr r3, [r7, #16] + 8003234: 801a strh r2, [r3, #0] + 8003236: e028 b.n 800328a + 8003238: 6cbb ldr r3, [r7, #72] ; 0x48 + 800323a: 095b lsrs r3, r3, #5 + 800323c: 647b str r3, [r7, #68] ; 0x44 + 800323e: 6cbb ldr r3, [r7, #72] ; 0x48 + 8003240: 221f movs r2, #31 + 8003242: 4013 ands r3, r2 + 8003244: d102 bne.n 800324c + 8003246: 6c7b ldr r3, [r7, #68] ; 0x44 + 8003248: 3b01 subs r3, #1 + 800324a: 647b str r3, [r7, #68] ; 0x44 + 800324c: 6c7b ldr r3, [r7, #68] ; 0x44 + 800324e: b29b uxth r3, r3 + 8003250: 029b lsls r3, r3, #10 + 8003252: b29b uxth r3, r3 + 8003254: 4aa1 ldr r2, [pc, #644] ; (80034dc ) + 8003256: 4313 orrs r3, r2 + 8003258: b29a uxth r2, r3 + 800325a: 693b ldr r3, [r7, #16] + 800325c: 801a strh r2, [r3, #0] + 800325e: e014 b.n 800328a + 8003260: 683b ldr r3, [r7, #0] + 8003262: 785b ldrb r3, [r3, #1] + 8003264: 2b01 cmp r3, #1 + 8003266: d110 bne.n 800328a + 8003268: 687b ldr r3, [r7, #4] + 800326a: 2250 movs r2, #80 ; 0x50 + 800326c: 5a9b ldrh r3, [r3, r2] + 800326e: b29b uxth r3, r3 + 8003270: 18e4 adds r4, r4, r3 + 8003272: 683b ldr r3, [r7, #0] + 8003274: 781b ldrb r3, [r3, #0] + 8003276: 00db lsls r3, r3, #3 + 8003278: 18e3 adds r3, r4, r3 + 800327a: 4a96 ldr r2, [pc, #600] ; (80034d4 ) + 800327c: 4694 mov ip, r2 + 800327e: 4463 add r3, ip + 8003280: 617b str r3, [r7, #20] + 8003282: 6cbb ldr r3, [r7, #72] ; 0x48 + 8003284: b29a uxth r2, r3 + 8003286: 697b ldr r3, [r7, #20] + 8003288: 801a strh r2, [r3, #0] + pmabuffer = ep->pmaaddr1; + 800328a: 234e movs r3, #78 ; 0x4e + 800328c: 18fb adds r3, r7, r3 + 800328e: 683a ldr r2, [r7, #0] + 8003290: 8952 ldrh r2, [r2, #10] + 8003292: 801a strh r2, [r3, #0] + 8003294: e066 b.n 8003364 + } + else + { + /* Set the Double buffer counter for pmabuffer0 */ + PCD_SET_EP_DBUF0_CNT(USBx, ep->num, ep->is_in, len); + 8003296: 683b ldr r3, [r7, #0] + 8003298: 785b ldrb r3, [r3, #1] + 800329a: 2b00 cmp r3, #0 + 800329c: d147 bne.n 800332e + 800329e: 687c ldr r4, [r7, #4] + 80032a0: 687b ldr r3, [r7, #4] + 80032a2: 2250 movs r2, #80 ; 0x50 + 80032a4: 5a9b ldrh r3, [r3, r2] + 80032a6: b29b uxth r3, r3 + 80032a8: 18e4 adds r4, r4, r3 + 80032aa: 683b ldr r3, [r7, #0] + 80032ac: 781b ldrb r3, [r3, #0] + 80032ae: 00db lsls r3, r3, #3 + 80032b0: 18e3 adds r3, r4, r3 + 80032b2: 4a87 ldr r2, [pc, #540] ; (80034d0 ) + 80032b4: 4694 mov ip, r2 + 80032b6: 4463 add r3, ip + 80032b8: 61bb str r3, [r7, #24] + 80032ba: 6cbb ldr r3, [r7, #72] ; 0x48 + 80032bc: 2b00 cmp r3, #0 + 80032be: d10e bne.n 80032de + 80032c0: 69bb ldr r3, [r7, #24] + 80032c2: 881b ldrh r3, [r3, #0] + 80032c4: 4a84 ldr r2, [pc, #528] ; (80034d8 ) + 80032c6: 4013 ands r3, r2 + 80032c8: b29a uxth r2, r3 + 80032ca: 69bb ldr r3, [r7, #24] + 80032cc: 801a strh r2, [r3, #0] + 80032ce: 69bb ldr r3, [r7, #24] + 80032d0: 881b ldrh r3, [r3, #0] + 80032d2: 4a82 ldr r2, [pc, #520] ; (80034dc ) + 80032d4: 4313 orrs r3, r2 + 80032d6: b29a uxth r2, r3 + 80032d8: 69bb ldr r3, [r7, #24] + 80032da: 801a strh r2, [r3, #0] + 80032dc: e03d b.n 800335a + 80032de: 6cbb ldr r3, [r7, #72] ; 0x48 + 80032e0: 2b3e cmp r3, #62 ; 0x3e + 80032e2: d810 bhi.n 8003306 + 80032e4: 6cbb ldr r3, [r7, #72] ; 0x48 + 80032e6: 085b lsrs r3, r3, #1 + 80032e8: 643b str r3, [r7, #64] ; 0x40 + 80032ea: 6cbb ldr r3, [r7, #72] ; 0x48 + 80032ec: 2201 movs r2, #1 + 80032ee: 4013 ands r3, r2 + 80032f0: d002 beq.n 80032f8 + 80032f2: 6c3b ldr r3, [r7, #64] ; 0x40 + 80032f4: 3301 adds r3, #1 + 80032f6: 643b str r3, [r7, #64] ; 0x40 + 80032f8: 6c3b ldr r3, [r7, #64] ; 0x40 + 80032fa: b29b uxth r3, r3 + 80032fc: 029b lsls r3, r3, #10 + 80032fe: b29a uxth r2, r3 + 8003300: 69bb ldr r3, [r7, #24] + 8003302: 801a strh r2, [r3, #0] + 8003304: e029 b.n 800335a + 8003306: 6cbb ldr r3, [r7, #72] ; 0x48 + 8003308: 095b lsrs r3, r3, #5 + 800330a: 643b str r3, [r7, #64] ; 0x40 + 800330c: 6cbb ldr r3, [r7, #72] ; 0x48 + 800330e: 221f movs r2, #31 + 8003310: 4013 ands r3, r2 + 8003312: d102 bne.n 800331a + 8003314: 6c3b ldr r3, [r7, #64] ; 0x40 + 8003316: 3b01 subs r3, #1 + 8003318: 643b str r3, [r7, #64] ; 0x40 + 800331a: 6c3b ldr r3, [r7, #64] ; 0x40 + 800331c: b29b uxth r3, r3 + 800331e: 029b lsls r3, r3, #10 + 8003320: b29b uxth r3, r3 + 8003322: 4a6e ldr r2, [pc, #440] ; (80034dc ) + 8003324: 4313 orrs r3, r2 + 8003326: b29a uxth r2, r3 + 8003328: 69bb ldr r3, [r7, #24] + 800332a: 801a strh r2, [r3, #0] + 800332c: e015 b.n 800335a + 800332e: 683b ldr r3, [r7, #0] + 8003330: 785b ldrb r3, [r3, #1] + 8003332: 2b01 cmp r3, #1 + 8003334: d111 bne.n 800335a + 8003336: 687c ldr r4, [r7, #4] + 8003338: 687b ldr r3, [r7, #4] + 800333a: 2250 movs r2, #80 ; 0x50 + 800333c: 5a9b ldrh r3, [r3, r2] + 800333e: b29b uxth r3, r3 + 8003340: 18e4 adds r4, r4, r3 + 8003342: 683b ldr r3, [r7, #0] + 8003344: 781b ldrb r3, [r3, #0] + 8003346: 00db lsls r3, r3, #3 + 8003348: 18e3 adds r3, r4, r3 + 800334a: 4a61 ldr r2, [pc, #388] ; (80034d0 ) + 800334c: 4694 mov ip, r2 + 800334e: 4463 add r3, ip + 8003350: 61fb str r3, [r7, #28] + 8003352: 6cbb ldr r3, [r7, #72] ; 0x48 + 8003354: b29a uxth r2, r3 + 8003356: 69fb ldr r3, [r7, #28] + 8003358: 801a strh r2, [r3, #0] + pmabuffer = ep->pmaaddr0; + 800335a: 234e movs r3, #78 ; 0x4e + 800335c: 18fb adds r3, r7, r3 + 800335e: 683a ldr r2, [r7, #0] + 8003360: 8912 ldrh r2, [r2, #8] + 8003362: 801a strh r2, [r3, #0] + } + USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len); + 8003364: 683b ldr r3, [r7, #0] + 8003366: 6959 ldr r1, [r3, #20] + 8003368: 6cbb ldr r3, [r7, #72] ; 0x48 + 800336a: b29c uxth r4, r3 + 800336c: 234e movs r3, #78 ; 0x4e + 800336e: 18fb adds r3, r7, r3 + 8003370: 881a ldrh r2, [r3, #0] + 8003372: 6878 ldr r0, [r7, #4] + 8003374: 0023 movs r3, r4 + 8003376: f000 fac3 bl 8003900 + PCD_FreeUserBuffer(USBx, ep->num, ep->is_in); + 800337a: 683b ldr r3, [r7, #0] + 800337c: 785b ldrb r3, [r3, #1] + 800337e: 2b00 cmp r3, #0 + 8003380: d113 bne.n 80033aa + 8003382: 687a ldr r2, [r7, #4] + 8003384: 683b ldr r3, [r7, #0] + 8003386: 781b ldrb r3, [r3, #0] + 8003388: 009b lsls r3, r3, #2 + 800338a: 18d3 adds r3, r2, r3 + 800338c: 881b ldrh r3, [r3, #0] + 800338e: b29b uxth r3, r3 + 8003390: 4a53 ldr r2, [pc, #332] ; (80034e0 ) + 8003392: 4013 ands r3, r2 + 8003394: b29c uxth r4, r3 + 8003396: 687a ldr r2, [r7, #4] + 8003398: 683b ldr r3, [r7, #0] + 800339a: 781b ldrb r3, [r3, #0] + 800339c: 009b lsls r3, r3, #2 + 800339e: 18d3 adds r3, r2, r3 + 80033a0: 4a50 ldr r2, [pc, #320] ; (80034e4 ) + 80033a2: 4322 orrs r2, r4 + 80033a4: b292 uxth r2, r2 + 80033a6: 801a strh r2, [r3, #0] + 80033a8: e016 b.n 80033d8 + 80033aa: 683b ldr r3, [r7, #0] + 80033ac: 785b ldrb r3, [r3, #1] + 80033ae: 2b01 cmp r3, #1 + 80033b0: d112 bne.n 80033d8 + 80033b2: 687a ldr r2, [r7, #4] + 80033b4: 683b ldr r3, [r7, #0] + 80033b6: 781b ldrb r3, [r3, #0] + 80033b8: 009b lsls r3, r3, #2 + 80033ba: 18d3 adds r3, r2, r3 + 80033bc: 881b ldrh r3, [r3, #0] + 80033be: b29b uxth r3, r3 + 80033c0: 4a47 ldr r2, [pc, #284] ; (80034e0 ) + 80033c2: 4013 ands r3, r2 + 80033c4: b29c uxth r4, r3 + 80033c6: 687a ldr r2, [r7, #4] + 80033c8: 683b ldr r3, [r7, #0] + 80033ca: 781b ldrb r3, [r3, #0] + 80033cc: 009b lsls r3, r3, #2 + 80033ce: 18d3 adds r3, r2, r3 + 80033d0: 4a45 ldr r2, [pc, #276] ; (80034e8 ) + 80033d2: 4322 orrs r2, r4 + 80033d4: b292 uxth r2, r2 + 80033d6: 801a strh r2, [r3, #0] + } + + PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_VALID); + 80033d8: 687a ldr r2, [r7, #4] + 80033da: 683b ldr r3, [r7, #0] + 80033dc: 781b ldrb r3, [r3, #0] + 80033de: 009b lsls r3, r3, #2 + 80033e0: 18d3 adds r3, r2, r3 + 80033e2: 881b ldrh r3, [r3, #0] + 80033e4: b29b uxth r3, r3 + 80033e6: 4a41 ldr r2, [pc, #260] ; (80034ec ) + 80033e8: 4013 ands r3, r2 + 80033ea: b29c uxth r4, r3 + 80033ec: 2310 movs r3, #16 + 80033ee: 4063 eors r3, r4 + 80033f0: b29c uxth r4, r3 + 80033f2: 2320 movs r3, #32 + 80033f4: 4063 eors r3, r4 + 80033f6: b29c uxth r4, r3 + 80033f8: 687a ldr r2, [r7, #4] + 80033fa: 683b ldr r3, [r7, #0] + 80033fc: 781b ldrb r3, [r3, #0] + 80033fe: 009b lsls r3, r3, #2 + 8003400: 18d3 adds r3, r2, r3 + 8003402: 4a3b ldr r2, [pc, #236] ; (80034f0 ) + 8003404: 4322 orrs r2, r4 + 8003406: b292 uxth r2, r2 + 8003408: 801a strh r2, [r3, #0] + 800340a: e152 b.n 80036b2 + } + else /* OUT endpoint */ + { + /* Multi packet transfer*/ + if (ep->xfer_len > ep->maxpacket) + 800340c: 683b ldr r3, [r7, #0] + 800340e: 699a ldr r2, [r3, #24] + 8003410: 683b ldr r3, [r7, #0] + 8003412: 691b ldr r3, [r3, #16] + 8003414: 429a cmp r2, r3 + 8003416: d909 bls.n 800342c + { + len = ep->maxpacket; + 8003418: 683b ldr r3, [r7, #0] + 800341a: 691b ldr r3, [r3, #16] + 800341c: 64bb str r3, [r7, #72] ; 0x48 + ep->xfer_len -= len; + 800341e: 683b ldr r3, [r7, #0] + 8003420: 699a ldr r2, [r3, #24] + 8003422: 6cbb ldr r3, [r7, #72] ; 0x48 + 8003424: 1ad2 subs r2, r2, r3 + 8003426: 683b ldr r3, [r7, #0] + 8003428: 619a str r2, [r3, #24] + 800342a: e005 b.n 8003438 + } + else + { + len = ep->xfer_len; + 800342c: 683b ldr r3, [r7, #0] + 800342e: 699b ldr r3, [r3, #24] + 8003430: 64bb str r3, [r7, #72] ; 0x48 + ep->xfer_len = 0U; + 8003432: 683b ldr r3, [r7, #0] + 8003434: 2200 movs r2, #0 + 8003436: 619a str r2, [r3, #24] + } + + /* configure and validate Rx endpoint */ + if (ep->doublebuffer == 0U) + 8003438: 683b ldr r3, [r7, #0] + 800343a: 7b1b ldrb r3, [r3, #12] + 800343c: 2b00 cmp r3, #0 + 800343e: d159 bne.n 80034f4 + { + /*Set RX buffer count*/ + PCD_SET_EP_RX_CNT(USBx, ep->num, len); + 8003440: 687c ldr r4, [r7, #4] + 8003442: 687b ldr r3, [r7, #4] + 8003444: 2250 movs r2, #80 ; 0x50 + 8003446: 5a9b ldrh r3, [r3, r2] + 8003448: b29b uxth r3, r3 + 800344a: 18e4 adds r4, r4, r3 + 800344c: 683b ldr r3, [r7, #0] + 800344e: 781b ldrb r3, [r3, #0] + 8003450: 00db lsls r3, r3, #3 + 8003452: 18e3 adds r3, r4, r3 + 8003454: 4a1f ldr r2, [pc, #124] ; (80034d4 ) + 8003456: 4694 mov ip, r2 + 8003458: 4463 add r3, ip + 800345a: 623b str r3, [r7, #32] + 800345c: 6cbb ldr r3, [r7, #72] ; 0x48 + 800345e: 2b00 cmp r3, #0 + 8003460: d10e bne.n 8003480 + 8003462: 6a3b ldr r3, [r7, #32] + 8003464: 881b ldrh r3, [r3, #0] + 8003466: 4a1c ldr r2, [pc, #112] ; (80034d8 ) + 8003468: 4013 ands r3, r2 + 800346a: b29a uxth r2, r3 + 800346c: 6a3b ldr r3, [r7, #32] + 800346e: 801a strh r2, [r3, #0] + 8003470: 6a3b ldr r3, [r7, #32] + 8003472: 881b ldrh r3, [r3, #0] + 8003474: 4a19 ldr r2, [pc, #100] ; (80034dc ) + 8003476: 4313 orrs r3, r2 + 8003478: b29a uxth r2, r3 + 800347a: 6a3b ldr r3, [r7, #32] + 800347c: 801a strh r2, [r3, #0] + 800347e: e0fd b.n 800367c + 8003480: 6cbb ldr r3, [r7, #72] ; 0x48 + 8003482: 2b3e cmp r3, #62 ; 0x3e + 8003484: d810 bhi.n 80034a8 + 8003486: 6cbb ldr r3, [r7, #72] ; 0x48 + 8003488: 085b lsrs r3, r3, #1 + 800348a: 63fb str r3, [r7, #60] ; 0x3c + 800348c: 6cbb ldr r3, [r7, #72] ; 0x48 + 800348e: 2201 movs r2, #1 + 8003490: 4013 ands r3, r2 + 8003492: d002 beq.n 800349a + 8003494: 6bfb ldr r3, [r7, #60] ; 0x3c + 8003496: 3301 adds r3, #1 + 8003498: 63fb str r3, [r7, #60] ; 0x3c + 800349a: 6bfb ldr r3, [r7, #60] ; 0x3c + 800349c: b29b uxth r3, r3 + 800349e: 029b lsls r3, r3, #10 + 80034a0: b29a uxth r2, r3 + 80034a2: 6a3b ldr r3, [r7, #32] + 80034a4: 801a strh r2, [r3, #0] + 80034a6: e0e9 b.n 800367c + 80034a8: 6cbb ldr r3, [r7, #72] ; 0x48 + 80034aa: 095b lsrs r3, r3, #5 + 80034ac: 63fb str r3, [r7, #60] ; 0x3c + 80034ae: 6cbb ldr r3, [r7, #72] ; 0x48 + 80034b0: 221f movs r2, #31 + 80034b2: 4013 ands r3, r2 + 80034b4: d102 bne.n 80034bc + 80034b6: 6bfb ldr r3, [r7, #60] ; 0x3c + 80034b8: 3b01 subs r3, #1 + 80034ba: 63fb str r3, [r7, #60] ; 0x3c + 80034bc: 6bfb ldr r3, [r7, #60] ; 0x3c + 80034be: b29b uxth r3, r3 + 80034c0: 029b lsls r3, r3, #10 + 80034c2: b29b uxth r3, r3 + 80034c4: 4a05 ldr r2, [pc, #20] ; (80034dc ) + 80034c6: 4313 orrs r3, r2 + 80034c8: b29a uxth r2, r3 + 80034ca: 6a3b ldr r3, [r7, #32] + 80034cc: 801a strh r2, [r3, #0] + 80034ce: e0d5 b.n 800367c + 80034d0: 00000402 .word 0x00000402 + 80034d4: 00000406 .word 0x00000406 + 80034d8: ffff83ff .word 0xffff83ff + 80034dc: ffff8000 .word 0xffff8000 + 80034e0: ffff8f8f .word 0xffff8f8f + 80034e4: ffff80c0 .word 0xffff80c0 + 80034e8: ffffc080 .word 0xffffc080 + 80034ec: ffff8fbf .word 0xffff8fbf + 80034f0: ffff8080 .word 0xffff8080 + } + else + { + /*Set the Double buffer counter*/ + PCD_SET_EP_DBUF_CNT(USBx, ep->num, ep->is_in, len); + 80034f4: 683b ldr r3, [r7, #0] + 80034f6: 785b ldrb r3, [r3, #1] + 80034f8: 2b00 cmp r3, #0 + 80034fa: d147 bne.n 800358c + 80034fc: 687c ldr r4, [r7, #4] + 80034fe: 687b ldr r3, [r7, #4] + 8003500: 2250 movs r2, #80 ; 0x50 + 8003502: 5a9b ldrh r3, [r3, r2] + 8003504: b29b uxth r3, r3 + 8003506: 18e4 adds r4, r4, r3 + 8003508: 683b ldr r3, [r7, #0] + 800350a: 781b ldrb r3, [r3, #0] + 800350c: 00db lsls r3, r3, #3 + 800350e: 18e3 adds r3, r4, r3 + 8003510: 4a6a ldr r2, [pc, #424] ; (80036bc ) + 8003512: 4694 mov ip, r2 + 8003514: 4463 add r3, ip + 8003516: 62fb str r3, [r7, #44] ; 0x2c + 8003518: 6cbb ldr r3, [r7, #72] ; 0x48 + 800351a: 2b00 cmp r3, #0 + 800351c: d10e bne.n 800353c + 800351e: 6afb ldr r3, [r7, #44] ; 0x2c + 8003520: 881b ldrh r3, [r3, #0] + 8003522: 4a67 ldr r2, [pc, #412] ; (80036c0 ) + 8003524: 4013 ands r3, r2 + 8003526: b29a uxth r2, r3 + 8003528: 6afb ldr r3, [r7, #44] ; 0x2c + 800352a: 801a strh r2, [r3, #0] + 800352c: 6afb ldr r3, [r7, #44] ; 0x2c + 800352e: 881b ldrh r3, [r3, #0] + 8003530: 4a64 ldr r2, [pc, #400] ; (80036c4 ) + 8003532: 4313 orrs r3, r2 + 8003534: b29a uxth r2, r3 + 8003536: 6afb ldr r3, [r7, #44] ; 0x2c + 8003538: 801a strh r2, [r3, #0] + 800353a: e03d b.n 80035b8 + 800353c: 6cbb ldr r3, [r7, #72] ; 0x48 + 800353e: 2b3e cmp r3, #62 ; 0x3e + 8003540: d810 bhi.n 8003564 + 8003542: 6cbb ldr r3, [r7, #72] ; 0x48 + 8003544: 085b lsrs r3, r3, #1 + 8003546: 63bb str r3, [r7, #56] ; 0x38 + 8003548: 6cbb ldr r3, [r7, #72] ; 0x48 + 800354a: 2201 movs r2, #1 + 800354c: 4013 ands r3, r2 + 800354e: d002 beq.n 8003556 + 8003550: 6bbb ldr r3, [r7, #56] ; 0x38 + 8003552: 3301 adds r3, #1 + 8003554: 63bb str r3, [r7, #56] ; 0x38 + 8003556: 6bbb ldr r3, [r7, #56] ; 0x38 + 8003558: b29b uxth r3, r3 + 800355a: 029b lsls r3, r3, #10 + 800355c: b29a uxth r2, r3 + 800355e: 6afb ldr r3, [r7, #44] ; 0x2c + 8003560: 801a strh r2, [r3, #0] + 8003562: e029 b.n 80035b8 + 8003564: 6cbb ldr r3, [r7, #72] ; 0x48 + 8003566: 095b lsrs r3, r3, #5 + 8003568: 63bb str r3, [r7, #56] ; 0x38 + 800356a: 6cbb ldr r3, [r7, #72] ; 0x48 + 800356c: 221f movs r2, #31 + 800356e: 4013 ands r3, r2 + 8003570: d102 bne.n 8003578 + 8003572: 6bbb ldr r3, [r7, #56] ; 0x38 + 8003574: 3b01 subs r3, #1 + 8003576: 63bb str r3, [r7, #56] ; 0x38 + 8003578: 6bbb ldr r3, [r7, #56] ; 0x38 + 800357a: b29b uxth r3, r3 + 800357c: 029b lsls r3, r3, #10 + 800357e: b29b uxth r3, r3 + 8003580: 4a50 ldr r2, [pc, #320] ; (80036c4 ) + 8003582: 4313 orrs r3, r2 + 8003584: b29a uxth r2, r3 + 8003586: 6afb ldr r3, [r7, #44] ; 0x2c + 8003588: 801a strh r2, [r3, #0] + 800358a: e015 b.n 80035b8 + 800358c: 683b ldr r3, [r7, #0] + 800358e: 785b ldrb r3, [r3, #1] + 8003590: 2b01 cmp r3, #1 + 8003592: d111 bne.n 80035b8 + 8003594: 687c ldr r4, [r7, #4] + 8003596: 687b ldr r3, [r7, #4] + 8003598: 2250 movs r2, #80 ; 0x50 + 800359a: 5a9b ldrh r3, [r3, r2] + 800359c: b29b uxth r3, r3 + 800359e: 18e4 adds r4, r4, r3 + 80035a0: 683b ldr r3, [r7, #0] + 80035a2: 781b ldrb r3, [r3, #0] + 80035a4: 00db lsls r3, r3, #3 + 80035a6: 18e3 adds r3, r4, r3 + 80035a8: 4a44 ldr r2, [pc, #272] ; (80036bc ) + 80035aa: 4694 mov ip, r2 + 80035ac: 4463 add r3, ip + 80035ae: 633b str r3, [r7, #48] ; 0x30 + 80035b0: 6cbb ldr r3, [r7, #72] ; 0x48 + 80035b2: b29a uxth r2, r3 + 80035b4: 6b3b ldr r3, [r7, #48] ; 0x30 + 80035b6: 801a strh r2, [r3, #0] + 80035b8: 687c ldr r4, [r7, #4] + 80035ba: 683b ldr r3, [r7, #0] + 80035bc: 785b ldrb r3, [r3, #1] + 80035be: 2b00 cmp r3, #0 + 80035c0: d147 bne.n 8003652 + 80035c2: 687c ldr r4, [r7, #4] + 80035c4: 687b ldr r3, [r7, #4] + 80035c6: 2250 movs r2, #80 ; 0x50 + 80035c8: 5a9b ldrh r3, [r3, r2] + 80035ca: b29b uxth r3, r3 + 80035cc: 18e4 adds r4, r4, r3 + 80035ce: 683b ldr r3, [r7, #0] + 80035d0: 781b ldrb r3, [r3, #0] + 80035d2: 00db lsls r3, r3, #3 + 80035d4: 18e3 adds r3, r4, r3 + 80035d6: 4a3c ldr r2, [pc, #240] ; (80036c8 ) + 80035d8: 4694 mov ip, r2 + 80035da: 4463 add r3, ip + 80035dc: 627b str r3, [r7, #36] ; 0x24 + 80035de: 6cbb ldr r3, [r7, #72] ; 0x48 + 80035e0: 2b00 cmp r3, #0 + 80035e2: d10e bne.n 8003602 + 80035e4: 6a7b ldr r3, [r7, #36] ; 0x24 + 80035e6: 881b ldrh r3, [r3, #0] + 80035e8: 4a35 ldr r2, [pc, #212] ; (80036c0 ) + 80035ea: 4013 ands r3, r2 + 80035ec: b29a uxth r2, r3 + 80035ee: 6a7b ldr r3, [r7, #36] ; 0x24 + 80035f0: 801a strh r2, [r3, #0] + 80035f2: 6a7b ldr r3, [r7, #36] ; 0x24 + 80035f4: 881b ldrh r3, [r3, #0] + 80035f6: 4a33 ldr r2, [pc, #204] ; (80036c4 ) + 80035f8: 4313 orrs r3, r2 + 80035fa: b29a uxth r2, r3 + 80035fc: 6a7b ldr r3, [r7, #36] ; 0x24 + 80035fe: 801a strh r2, [r3, #0] + 8003600: e03c b.n 800367c + 8003602: 6cbb ldr r3, [r7, #72] ; 0x48 + 8003604: 2b3e cmp r3, #62 ; 0x3e + 8003606: d810 bhi.n 800362a + 8003608: 6cbb ldr r3, [r7, #72] ; 0x48 + 800360a: 085b lsrs r3, r3, #1 + 800360c: 637b str r3, [r7, #52] ; 0x34 + 800360e: 6cbb ldr r3, [r7, #72] ; 0x48 + 8003610: 2201 movs r2, #1 + 8003612: 4013 ands r3, r2 + 8003614: d002 beq.n 800361c + 8003616: 6b7b ldr r3, [r7, #52] ; 0x34 + 8003618: 3301 adds r3, #1 + 800361a: 637b str r3, [r7, #52] ; 0x34 + 800361c: 6b7b ldr r3, [r7, #52] ; 0x34 + 800361e: b29b uxth r3, r3 + 8003620: 029b lsls r3, r3, #10 + 8003622: b29a uxth r2, r3 + 8003624: 6a7b ldr r3, [r7, #36] ; 0x24 + 8003626: 801a strh r2, [r3, #0] + 8003628: e028 b.n 800367c + 800362a: 6cbb ldr r3, [r7, #72] ; 0x48 + 800362c: 095b lsrs r3, r3, #5 + 800362e: 637b str r3, [r7, #52] ; 0x34 + 8003630: 6cbb ldr r3, [r7, #72] ; 0x48 + 8003632: 221f movs r2, #31 + 8003634: 4013 ands r3, r2 + 8003636: d102 bne.n 800363e + 8003638: 6b7b ldr r3, [r7, #52] ; 0x34 + 800363a: 3b01 subs r3, #1 + 800363c: 637b str r3, [r7, #52] ; 0x34 + 800363e: 6b7b ldr r3, [r7, #52] ; 0x34 + 8003640: b29b uxth r3, r3 + 8003642: 029b lsls r3, r3, #10 + 8003644: b29b uxth r3, r3 + 8003646: 4a1f ldr r2, [pc, #124] ; (80036c4 ) + 8003648: 4313 orrs r3, r2 + 800364a: b29a uxth r2, r3 + 800364c: 6a7b ldr r3, [r7, #36] ; 0x24 + 800364e: 801a strh r2, [r3, #0] + 8003650: e014 b.n 800367c + 8003652: 683b ldr r3, [r7, #0] + 8003654: 785b ldrb r3, [r3, #1] + 8003656: 2b01 cmp r3, #1 + 8003658: d110 bne.n 800367c + 800365a: 687b ldr r3, [r7, #4] + 800365c: 2250 movs r2, #80 ; 0x50 + 800365e: 5a9b ldrh r3, [r3, r2] + 8003660: b29b uxth r3, r3 + 8003662: 18e4 adds r4, r4, r3 + 8003664: 683b ldr r3, [r7, #0] + 8003666: 781b ldrb r3, [r3, #0] + 8003668: 00db lsls r3, r3, #3 + 800366a: 18e3 adds r3, r4, r3 + 800366c: 4a16 ldr r2, [pc, #88] ; (80036c8 ) + 800366e: 4694 mov ip, r2 + 8003670: 4463 add r3, ip + 8003672: 62bb str r3, [r7, #40] ; 0x28 + 8003674: 6cbb ldr r3, [r7, #72] ; 0x48 + 8003676: b29a uxth r2, r3 + 8003678: 6abb ldr r3, [r7, #40] ; 0x28 + 800367a: 801a strh r2, [r3, #0] + } + + PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_VALID); + 800367c: 687a ldr r2, [r7, #4] + 800367e: 683b ldr r3, [r7, #0] + 8003680: 781b ldrb r3, [r3, #0] + 8003682: 009b lsls r3, r3, #2 + 8003684: 18d3 adds r3, r2, r3 + 8003686: 881b ldrh r3, [r3, #0] + 8003688: b29b uxth r3, r3 + 800368a: 4a10 ldr r2, [pc, #64] ; (80036cc ) + 800368c: 4013 ands r3, r2 + 800368e: b29c uxth r4, r3 + 8003690: 2380 movs r3, #128 ; 0x80 + 8003692: 015b lsls r3, r3, #5 + 8003694: 4063 eors r3, r4 + 8003696: b29c uxth r4, r3 + 8003698: 2380 movs r3, #128 ; 0x80 + 800369a: 019b lsls r3, r3, #6 + 800369c: 4063 eors r3, r4 + 800369e: b29c uxth r4, r3 + 80036a0: 687a ldr r2, [r7, #4] + 80036a2: 683b ldr r3, [r7, #0] + 80036a4: 781b ldrb r3, [r3, #0] + 80036a6: 009b lsls r3, r3, #2 + 80036a8: 18d3 adds r3, r2, r3 + 80036aa: 4a09 ldr r2, [pc, #36] ; (80036d0 ) + 80036ac: 4322 orrs r2, r4 + 80036ae: b292 uxth r2, r2 + 80036b0: 801a strh r2, [r3, #0] + } + + return HAL_OK; + 80036b2: 2300 movs r3, #0 +} + 80036b4: 0018 movs r0, r3 + 80036b6: 46bd mov sp, r7 + 80036b8: b015 add sp, #84 ; 0x54 + 80036ba: bd90 pop {r4, r7, pc} + 80036bc: 00000402 .word 0x00000402 + 80036c0: ffff83ff .word 0xffff83ff + 80036c4: ffff8000 .word 0xffff8000 + 80036c8: 00000406 .word 0x00000406 + 80036cc: ffffbf8f .word 0xffffbf8f + 80036d0: ffff8080 .word 0xffff8080 + +080036d4 : + * @param USBx : Selected device + * @param ep: pointer to endpoint structure + * @retval HAL status + */ +HAL_StatusTypeDef USB_EPSetStall(USB_TypeDef *USBx, USB_EPTypeDef *ep) +{ + 80036d4: b590 push {r4, r7, lr} + 80036d6: b083 sub sp, #12 + 80036d8: af00 add r7, sp, #0 + 80036da: 6078 str r0, [r7, #4] + 80036dc: 6039 str r1, [r7, #0] + if (ep->is_in != 0U) + 80036de: 683b ldr r3, [r7, #0] + 80036e0: 785b ldrb r3, [r3, #1] + 80036e2: 2b00 cmp r3, #0 + 80036e4: d016 beq.n 8003714 + { + PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_STALL); + 80036e6: 687a ldr r2, [r7, #4] + 80036e8: 683b ldr r3, [r7, #0] + 80036ea: 781b ldrb r3, [r3, #0] + 80036ec: 009b lsls r3, r3, #2 + 80036ee: 18d3 adds r3, r2, r3 + 80036f0: 881b ldrh r3, [r3, #0] + 80036f2: b29b uxth r3, r3 + 80036f4: 4a15 ldr r2, [pc, #84] ; (800374c ) + 80036f6: 4013 ands r3, r2 + 80036f8: b29c uxth r4, r3 + 80036fa: 2310 movs r3, #16 + 80036fc: 4063 eors r3, r4 + 80036fe: b29c uxth r4, r3 + 8003700: 687a ldr r2, [r7, #4] + 8003702: 683b ldr r3, [r7, #0] + 8003704: 781b ldrb r3, [r3, #0] + 8003706: 009b lsls r3, r3, #2 + 8003708: 18d3 adds r3, r2, r3 + 800370a: 4a11 ldr r2, [pc, #68] ; (8003750 ) + 800370c: 4322 orrs r2, r4 + 800370e: b292 uxth r2, r2 + 8003710: 801a strh r2, [r3, #0] + 8003712: e016 b.n 8003742 + } + else + { + PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_STALL); + 8003714: 687a ldr r2, [r7, #4] + 8003716: 683b ldr r3, [r7, #0] + 8003718: 781b ldrb r3, [r3, #0] + 800371a: 009b lsls r3, r3, #2 + 800371c: 18d3 adds r3, r2, r3 + 800371e: 881b ldrh r3, [r3, #0] + 8003720: b29b uxth r3, r3 + 8003722: 4a0c ldr r2, [pc, #48] ; (8003754 ) + 8003724: 4013 ands r3, r2 + 8003726: b29c uxth r4, r3 + 8003728: 2380 movs r3, #128 ; 0x80 + 800372a: 015b lsls r3, r3, #5 + 800372c: 4063 eors r3, r4 + 800372e: b29c uxth r4, r3 + 8003730: 687a ldr r2, [r7, #4] + 8003732: 683b ldr r3, [r7, #0] + 8003734: 781b ldrb r3, [r3, #0] + 8003736: 009b lsls r3, r3, #2 + 8003738: 18d3 adds r3, r2, r3 + 800373a: 4a05 ldr r2, [pc, #20] ; (8003750 ) + 800373c: 4322 orrs r2, r4 + 800373e: b292 uxth r2, r2 + 8003740: 801a strh r2, [r3, #0] + } + + return HAL_OK; + 8003742: 2300 movs r3, #0 +} + 8003744: 0018 movs r0, r3 + 8003746: 46bd mov sp, r7 + 8003748: b003 add sp, #12 + 800374a: bd90 pop {r4, r7, pc} + 800374c: ffff8fbf .word 0xffff8fbf + 8003750: ffff8080 .word 0xffff8080 + 8003754: ffffbf8f .word 0xffffbf8f + +08003758 : + * @param USBx : Selected device + * @param ep: pointer to endpoint structure + * @retval HAL status + */ +HAL_StatusTypeDef USB_EPClearStall(USB_TypeDef *USBx, USB_EPTypeDef *ep) +{ + 8003758: b590 push {r4, r7, lr} + 800375a: b083 sub sp, #12 + 800375c: af00 add r7, sp, #0 + 800375e: 6078 str r0, [r7, #4] + 8003760: 6039 str r1, [r7, #0] + if (ep->doublebuffer == 0U) + 8003762: 683b ldr r3, [r7, #0] + 8003764: 7b1b ldrb r3, [r3, #12] + 8003766: 2b00 cmp r3, #0 + 8003768: d000 beq.n 800376c + 800376a: e076 b.n 800385a + { + if (ep->is_in != 0U) + 800376c: 683b ldr r3, [r7, #0] + 800376e: 785b ldrb r3, [r3, #1] + 8003770: 2b00 cmp r3, #0 + 8003772: d038 beq.n 80037e6 + { + PCD_CLEAR_TX_DTOG(USBx, ep->num); + 8003774: 687a ldr r2, [r7, #4] + 8003776: 683b ldr r3, [r7, #0] + 8003778: 781b ldrb r3, [r3, #0] + 800377a: 009b lsls r3, r3, #2 + 800377c: 18d3 adds r3, r2, r3 + 800377e: 881b ldrh r3, [r3, #0] + 8003780: b29c uxth r4, r3 + 8003782: 0022 movs r2, r4 + 8003784: 2340 movs r3, #64 ; 0x40 + 8003786: 4013 ands r3, r2 + 8003788: d012 beq.n 80037b0 + 800378a: 687a ldr r2, [r7, #4] + 800378c: 683b ldr r3, [r7, #0] + 800378e: 781b ldrb r3, [r3, #0] + 8003790: 009b lsls r3, r3, #2 + 8003792: 18d3 adds r3, r2, r3 + 8003794: 881b ldrh r3, [r3, #0] + 8003796: b29b uxth r3, r3 + 8003798: 4a32 ldr r2, [pc, #200] ; (8003864 ) + 800379a: 4013 ands r3, r2 + 800379c: b29c uxth r4, r3 + 800379e: 687a ldr r2, [r7, #4] + 80037a0: 683b ldr r3, [r7, #0] + 80037a2: 781b ldrb r3, [r3, #0] + 80037a4: 009b lsls r3, r3, #2 + 80037a6: 18d3 adds r3, r2, r3 + 80037a8: 4a2f ldr r2, [pc, #188] ; (8003868 ) + 80037aa: 4322 orrs r2, r4 + 80037ac: b292 uxth r2, r2 + 80037ae: 801a strh r2, [r3, #0] + + if (ep->type != EP_TYPE_ISOC) + 80037b0: 683b ldr r3, [r7, #0] + 80037b2: 78db ldrb r3, [r3, #3] + 80037b4: 2b01 cmp r3, #1 + 80037b6: d050 beq.n 800385a + { + /* Configure NAK status for the Endpoint */ + PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_NAK); + 80037b8: 687a ldr r2, [r7, #4] + 80037ba: 683b ldr r3, [r7, #0] + 80037bc: 781b ldrb r3, [r3, #0] + 80037be: 009b lsls r3, r3, #2 + 80037c0: 18d3 adds r3, r2, r3 + 80037c2: 881b ldrh r3, [r3, #0] + 80037c4: b29b uxth r3, r3 + 80037c6: 4a29 ldr r2, [pc, #164] ; (800386c ) + 80037c8: 4013 ands r3, r2 + 80037ca: b29c uxth r4, r3 + 80037cc: 2320 movs r3, #32 + 80037ce: 4063 eors r3, r4 + 80037d0: b29c uxth r4, r3 + 80037d2: 687a ldr r2, [r7, #4] + 80037d4: 683b ldr r3, [r7, #0] + 80037d6: 781b ldrb r3, [r3, #0] + 80037d8: 009b lsls r3, r3, #2 + 80037da: 18d3 adds r3, r2, r3 + 80037dc: 4a24 ldr r2, [pc, #144] ; (8003870 ) + 80037de: 4322 orrs r2, r4 + 80037e0: b292 uxth r2, r2 + 80037e2: 801a strh r2, [r3, #0] + 80037e4: e039 b.n 800385a + } + } + else + { + PCD_CLEAR_RX_DTOG(USBx, ep->num); + 80037e6: 687a ldr r2, [r7, #4] + 80037e8: 683b ldr r3, [r7, #0] + 80037ea: 781b ldrb r3, [r3, #0] + 80037ec: 009b lsls r3, r3, #2 + 80037ee: 18d3 adds r3, r2, r3 + 80037f0: 881b ldrh r3, [r3, #0] + 80037f2: b29c uxth r4, r3 + 80037f4: 0022 movs r2, r4 + 80037f6: 2380 movs r3, #128 ; 0x80 + 80037f8: 01db lsls r3, r3, #7 + 80037fa: 4013 ands r3, r2 + 80037fc: d012 beq.n 8003824 + 80037fe: 687a ldr r2, [r7, #4] + 8003800: 683b ldr r3, [r7, #0] + 8003802: 781b ldrb r3, [r3, #0] + 8003804: 009b lsls r3, r3, #2 + 8003806: 18d3 adds r3, r2, r3 + 8003808: 881b ldrh r3, [r3, #0] + 800380a: b29b uxth r3, r3 + 800380c: 4a15 ldr r2, [pc, #84] ; (8003864 ) + 800380e: 4013 ands r3, r2 + 8003810: b29c uxth r4, r3 + 8003812: 687a ldr r2, [r7, #4] + 8003814: 683b ldr r3, [r7, #0] + 8003816: 781b ldrb r3, [r3, #0] + 8003818: 009b lsls r3, r3, #2 + 800381a: 18d3 adds r3, r2, r3 + 800381c: 4a15 ldr r2, [pc, #84] ; (8003874 ) + 800381e: 4322 orrs r2, r4 + 8003820: b292 uxth r2, r2 + 8003822: 801a strh r2, [r3, #0] + + /* Configure VALID status for the Endpoint*/ + PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_VALID); + 8003824: 687a ldr r2, [r7, #4] + 8003826: 683b ldr r3, [r7, #0] + 8003828: 781b ldrb r3, [r3, #0] + 800382a: 009b lsls r3, r3, #2 + 800382c: 18d3 adds r3, r2, r3 + 800382e: 881b ldrh r3, [r3, #0] + 8003830: b29b uxth r3, r3 + 8003832: 4a11 ldr r2, [pc, #68] ; (8003878 ) + 8003834: 4013 ands r3, r2 + 8003836: b29c uxth r4, r3 + 8003838: 2380 movs r3, #128 ; 0x80 + 800383a: 015b lsls r3, r3, #5 + 800383c: 4063 eors r3, r4 + 800383e: b29c uxth r4, r3 + 8003840: 2380 movs r3, #128 ; 0x80 + 8003842: 019b lsls r3, r3, #6 + 8003844: 4063 eors r3, r4 + 8003846: b29c uxth r4, r3 + 8003848: 687a ldr r2, [r7, #4] + 800384a: 683b ldr r3, [r7, #0] + 800384c: 781b ldrb r3, [r3, #0] + 800384e: 009b lsls r3, r3, #2 + 8003850: 18d3 adds r3, r2, r3 + 8003852: 4a07 ldr r2, [pc, #28] ; (8003870 ) + 8003854: 4322 orrs r2, r4 + 8003856: b292 uxth r2, r2 + 8003858: 801a strh r2, [r3, #0] + } + } + + return HAL_OK; + 800385a: 2300 movs r3, #0 +} + 800385c: 0018 movs r0, r3 + 800385e: 46bd mov sp, r7 + 8003860: b003 add sp, #12 + 8003862: bd90 pop {r4, r7, pc} + 8003864: ffff8f8f .word 0xffff8f8f + 8003868: ffff80c0 .word 0xffff80c0 + 800386c: ffff8fbf .word 0xffff8fbf + 8003870: ffff8080 .word 0xffff8080 + 8003874: ffffc080 .word 0xffffc080 + 8003878: ffffbf8f .word 0xffffbf8f + +0800387c : + * @param address : new device address to be assigned + * This parameter can be a value from 0 to 255 + * @retval HAL status + */ +HAL_StatusTypeDef USB_SetDevAddress(USB_TypeDef *USBx, uint8_t address) +{ + 800387c: b580 push {r7, lr} + 800387e: b082 sub sp, #8 + 8003880: af00 add r7, sp, #0 + 8003882: 6078 str r0, [r7, #4] + 8003884: 000a movs r2, r1 + 8003886: 1cfb adds r3, r7, #3 + 8003888: 701a strb r2, [r3, #0] + if (address == 0U) + 800388a: 1cfb adds r3, r7, #3 + 800388c: 781b ldrb r3, [r3, #0] + 800388e: 2b00 cmp r3, #0 + 8003890: d103 bne.n 800389a + { + /* set device address and enable function */ + USBx->DADDR = USB_DADDR_EF; + 8003892: 687b ldr r3, [r7, #4] + 8003894: 224c movs r2, #76 ; 0x4c + 8003896: 2180 movs r1, #128 ; 0x80 + 8003898: 5299 strh r1, [r3, r2] + } + + return HAL_OK; + 800389a: 2300 movs r3, #0 +} + 800389c: 0018 movs r0, r3 + 800389e: 46bd mov sp, r7 + 80038a0: b002 add sp, #8 + 80038a2: bd80 pop {r7, pc} + +080038a4 : + * @brief USB_DevConnect : Connect the USB device by enabling the pull-up/pull-down + * @param USBx : Selected device + * @retval HAL status + */ +HAL_StatusTypeDef USB_DevConnect(USB_TypeDef *USBx) +{ + 80038a4: b580 push {r7, lr} + 80038a6: b082 sub sp, #8 + 80038a8: af00 add r7, sp, #0 + 80038aa: 6078 str r0, [r7, #4] + /* Enabling DP Pull-UP bit to Connect internal PU resistor on USB DP line */ + USBx->BCDR |= USB_BCDR_DPPU; + 80038ac: 687b ldr r3, [r7, #4] + 80038ae: 2258 movs r2, #88 ; 0x58 + 80038b0: 5a9b ldrh r3, [r3, r2] + 80038b2: b29b uxth r3, r3 + 80038b4: 4a05 ldr r2, [pc, #20] ; (80038cc ) + 80038b6: 4313 orrs r3, r2 + 80038b8: b299 uxth r1, r3 + 80038ba: 687b ldr r3, [r7, #4] + 80038bc: 2258 movs r2, #88 ; 0x58 + 80038be: 5299 strh r1, [r3, r2] + + return HAL_OK; + 80038c0: 2300 movs r3, #0 +} + 80038c2: 0018 movs r0, r3 + 80038c4: 46bd mov sp, r7 + 80038c6: b002 add sp, #8 + 80038c8: bd80 pop {r7, pc} + 80038ca: 46c0 nop ; (mov r8, r8) + 80038cc: ffff8000 .word 0xffff8000 + +080038d0 : + * @brief USB_ReadInterrupts: return the global USB interrupt status + * @param USBx : Selected device + * @retval HAL status + */ +uint32_t USB_ReadInterrupts(USB_TypeDef *USBx) +{ + 80038d0: b580 push {r7, lr} + 80038d2: b084 sub sp, #16 + 80038d4: af00 add r7, sp, #0 + 80038d6: 6078 str r0, [r7, #4] + uint32_t tmpreg; + + tmpreg = USBx->ISTR; + 80038d8: 687b ldr r3, [r7, #4] + 80038da: 2244 movs r2, #68 ; 0x44 + 80038dc: 5a9b ldrh r3, [r3, r2] + 80038de: b29b uxth r3, r3 + 80038e0: 60fb str r3, [r7, #12] + return tmpreg; + 80038e2: 68fb ldr r3, [r7, #12] +} + 80038e4: 0018 movs r0, r3 + 80038e6: 46bd mov sp, r7 + 80038e8: b004 add sp, #16 + 80038ea: bd80 pop {r7, pc} + +080038ec : + * @param USBx Selected device + * @param psetup pointer to setup packet + * @retval HAL status + */ +HAL_StatusTypeDef USB_EP0_OutStart(USB_TypeDef *USBx, uint8_t *psetup) +{ + 80038ec: b580 push {r7, lr} + 80038ee: b082 sub sp, #8 + 80038f0: af00 add r7, sp, #0 + 80038f2: 6078 str r0, [r7, #4] + 80038f4: 6039 str r1, [r7, #0] + UNUSED(psetup); + /* NOTE : - This function is not required by USB Device FS peripheral, it is used + only by USB OTG FS peripheral. + - This function is added to ensure compatibility across platforms. + */ + return HAL_OK; + 80038f6: 2300 movs r3, #0 +} + 80038f8: 0018 movs r0, r3 + 80038fa: 46bd mov sp, r7 + 80038fc: b002 add sp, #8 + 80038fe: bd80 pop {r7, pc} + +08003900 : + * @param wPMABufAddr address into PMA. + * @param wNBytes: no. of bytes to be copied. + * @retval None + */ +void USB_WritePMA(USB_TypeDef *USBx, uint8_t *pbUsrBuf, uint16_t wPMABufAddr, uint16_t wNBytes) +{ + 8003900: b580 push {r7, lr} + 8003902: b08c sub sp, #48 ; 0x30 + 8003904: af00 add r7, sp, #0 + 8003906: 60f8 str r0, [r7, #12] + 8003908: 60b9 str r1, [r7, #8] + 800390a: 0019 movs r1, r3 + 800390c: 1dbb adds r3, r7, #6 + 800390e: 801a strh r2, [r3, #0] + 8003910: 1d3b adds r3, r7, #4 + 8003912: 1c0a adds r2, r1, #0 + 8003914: 801a strh r2, [r3, #0] + uint32_t n = ((uint32_t)wNBytes + 1U) >> 1; + 8003916: 1d3b adds r3, r7, #4 + 8003918: 881b ldrh r3, [r3, #0] + 800391a: 3301 adds r3, #1 + 800391c: 085b lsrs r3, r3, #1 + 800391e: 623b str r3, [r7, #32] + uint32_t BaseAddr = (uint32_t)USBx; + 8003920: 68fb ldr r3, [r7, #12] + 8003922: 61fb str r3, [r7, #28] + uint32_t i, temp1, temp2; + __IO uint16_t *pdwVal; + uint8_t *pBuf = pbUsrBuf; + 8003924: 68bb ldr r3, [r7, #8] + 8003926: 627b str r3, [r7, #36] ; 0x24 + + pdwVal = (__IO uint16_t *)(BaseAddr + 0x400U + ((uint32_t)wPMABufAddr * PMA_ACCESS)); + 8003928: 1dbb adds r3, r7, #6 + 800392a: 881a ldrh r2, [r3, #0] + 800392c: 69fb ldr r3, [r7, #28] + 800392e: 18d3 adds r3, r2, r3 + 8003930: 2280 movs r2, #128 ; 0x80 + 8003932: 00d2 lsls r2, r2, #3 + 8003934: 4694 mov ip, r2 + 8003936: 4463 add r3, ip + 8003938: 62bb str r3, [r7, #40] ; 0x28 + + for (i = n; i != 0U; i--) + 800393a: 6a3b ldr r3, [r7, #32] + 800393c: 62fb str r3, [r7, #44] ; 0x2c + 800393e: e01b b.n 8003978 + { + temp1 = *pBuf; + 8003940: 6a7b ldr r3, [r7, #36] ; 0x24 + 8003942: 781b ldrb r3, [r3, #0] + 8003944: 61bb str r3, [r7, #24] + pBuf++; + 8003946: 6a7b ldr r3, [r7, #36] ; 0x24 + 8003948: 3301 adds r3, #1 + 800394a: 627b str r3, [r7, #36] ; 0x24 + temp2 = temp1 | ((uint16_t)((uint16_t) *pBuf << 8)); + 800394c: 6a7b ldr r3, [r7, #36] ; 0x24 + 800394e: 781b ldrb r3, [r3, #0] + 8003950: b29b uxth r3, r3 + 8003952: 021b lsls r3, r3, #8 + 8003954: b29b uxth r3, r3 + 8003956: 001a movs r2, r3 + 8003958: 69bb ldr r3, [r7, #24] + 800395a: 4313 orrs r3, r2 + 800395c: 617b str r3, [r7, #20] + *pdwVal = (uint16_t)temp2; + 800395e: 697b ldr r3, [r7, #20] + 8003960: b29a uxth r2, r3 + 8003962: 6abb ldr r3, [r7, #40] ; 0x28 + 8003964: 801a strh r2, [r3, #0] + pdwVal++; + 8003966: 6abb ldr r3, [r7, #40] ; 0x28 + 8003968: 3302 adds r3, #2 + 800396a: 62bb str r3, [r7, #40] ; 0x28 + +#if PMA_ACCESS > 1U + pdwVal++; +#endif + + pBuf++; + 800396c: 6a7b ldr r3, [r7, #36] ; 0x24 + 800396e: 3301 adds r3, #1 + 8003970: 627b str r3, [r7, #36] ; 0x24 + for (i = n; i != 0U; i--) + 8003972: 6afb ldr r3, [r7, #44] ; 0x2c + 8003974: 3b01 subs r3, #1 + 8003976: 62fb str r3, [r7, #44] ; 0x2c + 8003978: 6afb ldr r3, [r7, #44] ; 0x2c + 800397a: 2b00 cmp r3, #0 + 800397c: d1e0 bne.n 8003940 + } +} + 800397e: 46c0 nop ; (mov r8, r8) + 8003980: 46bd mov sp, r7 + 8003982: b00c add sp, #48 ; 0x30 + 8003984: bd80 pop {r7, pc} + +08003986 : + * @param wPMABufAddr address into PMA. + * @param wNBytes: no. of bytes to be copied. + * @retval None + */ +void USB_ReadPMA(USB_TypeDef *USBx, uint8_t *pbUsrBuf, uint16_t wPMABufAddr, uint16_t wNBytes) +{ + 8003986: b580 push {r7, lr} + 8003988: b08a sub sp, #40 ; 0x28 + 800398a: af00 add r7, sp, #0 + 800398c: 60f8 str r0, [r7, #12] + 800398e: 60b9 str r1, [r7, #8] + 8003990: 0019 movs r1, r3 + 8003992: 1dbb adds r3, r7, #6 + 8003994: 801a strh r2, [r3, #0] + 8003996: 1d3b adds r3, r7, #4 + 8003998: 1c0a adds r2, r1, #0 + 800399a: 801a strh r2, [r3, #0] + uint32_t n = (uint32_t)wNBytes >> 1; + 800399c: 1d3b adds r3, r7, #4 + 800399e: 881b ldrh r3, [r3, #0] + 80039a0: 085b lsrs r3, r3, #1 + 80039a2: b29b uxth r3, r3 + 80039a4: 61bb str r3, [r7, #24] + uint32_t BaseAddr = (uint32_t)USBx; + 80039a6: 68fb ldr r3, [r7, #12] + 80039a8: 617b str r3, [r7, #20] + uint32_t i, temp; + __IO uint16_t *pdwVal; + uint8_t *pBuf = pbUsrBuf; + 80039aa: 68bb ldr r3, [r7, #8] + 80039ac: 61fb str r3, [r7, #28] + + pdwVal = (__IO uint16_t *)(BaseAddr + 0x400U + ((uint32_t)wPMABufAddr * PMA_ACCESS)); + 80039ae: 1dbb adds r3, r7, #6 + 80039b0: 881a ldrh r2, [r3, #0] + 80039b2: 697b ldr r3, [r7, #20] + 80039b4: 18d3 adds r3, r2, r3 + 80039b6: 2280 movs r2, #128 ; 0x80 + 80039b8: 00d2 lsls r2, r2, #3 + 80039ba: 4694 mov ip, r2 + 80039bc: 4463 add r3, ip + 80039be: 623b str r3, [r7, #32] + + for (i = n; i != 0U; i--) + 80039c0: 69bb ldr r3, [r7, #24] + 80039c2: 627b str r3, [r7, #36] ; 0x24 + 80039c4: e018 b.n 80039f8 + { + temp = *(__IO uint16_t *)pdwVal; + 80039c6: 6a3b ldr r3, [r7, #32] + 80039c8: 881b ldrh r3, [r3, #0] + 80039ca: b29b uxth r3, r3 + 80039cc: 613b str r3, [r7, #16] + pdwVal++; + 80039ce: 6a3b ldr r3, [r7, #32] + 80039d0: 3302 adds r3, #2 + 80039d2: 623b str r3, [r7, #32] + *pBuf = (uint8_t)((temp >> 0) & 0xFFU); + 80039d4: 693b ldr r3, [r7, #16] + 80039d6: b2da uxtb r2, r3 + 80039d8: 69fb ldr r3, [r7, #28] + 80039da: 701a strb r2, [r3, #0] + pBuf++; + 80039dc: 69fb ldr r3, [r7, #28] + 80039de: 3301 adds r3, #1 + 80039e0: 61fb str r3, [r7, #28] + *pBuf = (uint8_t)((temp >> 8) & 0xFFU); + 80039e2: 693b ldr r3, [r7, #16] + 80039e4: 0a1b lsrs r3, r3, #8 + 80039e6: b2da uxtb r2, r3 + 80039e8: 69fb ldr r3, [r7, #28] + 80039ea: 701a strb r2, [r3, #0] + pBuf++; + 80039ec: 69fb ldr r3, [r7, #28] + 80039ee: 3301 adds r3, #1 + 80039f0: 61fb str r3, [r7, #28] + for (i = n; i != 0U; i--) + 80039f2: 6a7b ldr r3, [r7, #36] ; 0x24 + 80039f4: 3b01 subs r3, #1 + 80039f6: 627b str r3, [r7, #36] ; 0x24 + 80039f8: 6a7b ldr r3, [r7, #36] ; 0x24 + 80039fa: 2b00 cmp r3, #0 + 80039fc: d1e3 bne.n 80039c6 +#if PMA_ACCESS > 1U + pdwVal++; +#endif + } + + if ((wNBytes % 2U) != 0U) + 80039fe: 1d3b adds r3, r7, #4 + 8003a00: 881b ldrh r3, [r3, #0] + 8003a02: 2201 movs r2, #1 + 8003a04: 4013 ands r3, r2 + 8003a06: b29b uxth r3, r3 + 8003a08: 2b00 cmp r3, #0 + 8003a0a: d007 beq.n 8003a1c + { + temp = *pdwVal; + 8003a0c: 6a3b ldr r3, [r7, #32] + 8003a0e: 881b ldrh r3, [r3, #0] + 8003a10: b29b uxth r3, r3 + 8003a12: 613b str r3, [r7, #16] + *pBuf = (uint8_t)((temp >> 0) & 0xFFU); + 8003a14: 693b ldr r3, [r7, #16] + 8003a16: b2da uxtb r2, r3 + 8003a18: 69fb ldr r3, [r7, #28] + 8003a1a: 701a strb r2, [r3, #0] + } +} + 8003a1c: 46c0 nop ; (mov r8, r8) + 8003a1e: 46bd mov sp, r7 + 8003a20: b00a add sp, #40 ; 0x28 + 8003a22: bd80 pop {r7, pc} + +08003a24 : +static dhcp_config_t *config = NULL; + +char magic_cookie[] = {0x63,0x82,0x53,0x63}; + +static uint32_t get_ip(const uint8_t *pnt) +{ + 8003a24: b580 push {r7, lr} + 8003a26: b084 sub sp, #16 + 8003a28: af00 add r7, sp, #0 + 8003a2a: 6078 str r0, [r7, #4] + uint32_t result; + memcpy(&result, pnt, sizeof(result)); + 8003a2c: 6879 ldr r1, [r7, #4] + 8003a2e: 230c movs r3, #12 + 8003a30: 18fb adds r3, r7, r3 + 8003a32: 2204 movs r2, #4 + 8003a34: 0018 movs r0, r3 + 8003a36: f00c f934 bl 800fca2 + return result; + 8003a3a: 68fb ldr r3, [r7, #12] +} + 8003a3c: 0018 movs r0, r3 + 8003a3e: 46bd mov sp, r7 + 8003a40: b004 add sp, #16 + 8003a42: bd80 pop {r7, pc} + +08003a44 : + +static void set_ip(uint8_t *pnt, uint32_t value) +{ + 8003a44: b580 push {r7, lr} + 8003a46: b082 sub sp, #8 + 8003a48: af00 add r7, sp, #0 + 8003a4a: 6078 str r0, [r7, #4] + 8003a4c: 6039 str r1, [r7, #0] + memcpy(pnt, &value, sizeof(value)); + 8003a4e: 0039 movs r1, r7 + 8003a50: 687b ldr r3, [r7, #4] + 8003a52: 2204 movs r2, #4 + 8003a54: 0018 movs r0, r3 + 8003a56: f00c f924 bl 800fca2 +} + 8003a5a: 46c0 nop ; (mov r8, r8) + 8003a5c: 46bd mov sp, r7 + 8003a5e: b002 add sp, #8 + 8003a60: bd80 pop {r7, pc} + ... + +08003a64 : + +static dhcp_entry_t *entry_by_ip(uint32_t ip) +{ + 8003a64: b580 push {r7, lr} + 8003a66: b084 sub sp, #16 + 8003a68: af00 add r7, sp, #0 + 8003a6a: 6078 str r0, [r7, #4] + int i; + for (i = 0; i < config->num_entry; i++) + 8003a6c: 2300 movs r3, #0 + 8003a6e: 60fb str r3, [r7, #12] + 8003a70: e01d b.n 8003aae + if (get_ip(config->entries[i].addr) == ip) + 8003a72: 4b14 ldr r3, [pc, #80] ; (8003ac4 ) + 8003a74: 681b ldr r3, [r3, #0] + 8003a76: 6959 ldr r1, [r3, #20] + 8003a78: 68fa ldr r2, [r7, #12] + 8003a7a: 0013 movs r3, r2 + 8003a7c: 009b lsls r3, r3, #2 + 8003a7e: 189b adds r3, r3, r2 + 8003a80: 009b lsls r3, r3, #2 + 8003a82: 18cb adds r3, r1, r3 + 8003a84: 3306 adds r3, #6 + 8003a86: 0018 movs r0, r3 + 8003a88: f7ff ffcc bl 8003a24 + 8003a8c: 0002 movs r2, r0 + 8003a8e: 687b ldr r3, [r7, #4] + 8003a90: 4293 cmp r3, r2 + 8003a92: d109 bne.n 8003aa8 + return &config->entries[i]; + 8003a94: 4b0b ldr r3, [pc, #44] ; (8003ac4 ) + 8003a96: 681b ldr r3, [r3, #0] + 8003a98: 6959 ldr r1, [r3, #20] + 8003a9a: 68fa ldr r2, [r7, #12] + 8003a9c: 0013 movs r3, r2 + 8003a9e: 009b lsls r3, r3, #2 + 8003aa0: 189b adds r3, r3, r2 + 8003aa2: 009b lsls r3, r3, #2 + 8003aa4: 18cb adds r3, r1, r3 + 8003aa6: e009 b.n 8003abc + for (i = 0; i < config->num_entry; i++) + 8003aa8: 68fb ldr r3, [r7, #12] + 8003aaa: 3301 adds r3, #1 + 8003aac: 60fb str r3, [r7, #12] + 8003aae: 4b05 ldr r3, [pc, #20] ; (8003ac4 ) + 8003ab0: 681b ldr r3, [r3, #0] + 8003ab2: 691b ldr r3, [r3, #16] + 8003ab4: 68fa ldr r2, [r7, #12] + 8003ab6: 429a cmp r2, r3 + 8003ab8: dbdb blt.n 8003a72 + return NULL; + 8003aba: 2300 movs r3, #0 +} + 8003abc: 0018 movs r0, r3 + 8003abe: 46bd mov sp, r7 + 8003ac0: b004 add sp, #16 + 8003ac2: bd80 pop {r7, pc} + 8003ac4: 200000bc .word 0x200000bc + +08003ac8 : + +static dhcp_entry_t *entry_by_mac(uint8_t *mac) +{ + 8003ac8: b580 push {r7, lr} + 8003aca: b084 sub sp, #16 + 8003acc: af00 add r7, sp, #0 + 8003ace: 6078 str r0, [r7, #4] + int i; + for (i = 0; i < config->num_entry; i++) + 8003ad0: 2300 movs r3, #0 + 8003ad2: 60fb str r3, [r7, #12] + 8003ad4: e01d b.n 8003b12 + if (memcmp(config->entries[i].mac, mac, 6) == 0) + 8003ad6: 4b14 ldr r3, [pc, #80] ; (8003b28 ) + 8003ad8: 681b ldr r3, [r3, #0] + 8003ada: 6959 ldr r1, [r3, #20] + 8003adc: 68fa ldr r2, [r7, #12] + 8003ade: 0013 movs r3, r2 + 8003ae0: 009b lsls r3, r3, #2 + 8003ae2: 189b adds r3, r3, r2 + 8003ae4: 009b lsls r3, r3, #2 + 8003ae6: 18cb adds r3, r1, r3 + 8003ae8: 0018 movs r0, r3 + 8003aea: 687b ldr r3, [r7, #4] + 8003aec: 2206 movs r2, #6 + 8003aee: 0019 movs r1, r3 + 8003af0: f00c f8c8 bl 800fc84 + 8003af4: 1e03 subs r3, r0, #0 + 8003af6: d109 bne.n 8003b0c + return &config->entries[i]; + 8003af8: 4b0b ldr r3, [pc, #44] ; (8003b28 ) + 8003afa: 681b ldr r3, [r3, #0] + 8003afc: 6959 ldr r1, [r3, #20] + 8003afe: 68fa ldr r2, [r7, #12] + 8003b00: 0013 movs r3, r2 + 8003b02: 009b lsls r3, r3, #2 + 8003b04: 189b adds r3, r3, r2 + 8003b06: 009b lsls r3, r3, #2 + 8003b08: 18cb adds r3, r1, r3 + 8003b0a: e009 b.n 8003b20 + for (i = 0; i < config->num_entry; i++) + 8003b0c: 68fb ldr r3, [r7, #12] + 8003b0e: 3301 adds r3, #1 + 8003b10: 60fb str r3, [r7, #12] + 8003b12: 4b05 ldr r3, [pc, #20] ; (8003b28 ) + 8003b14: 681b ldr r3, [r3, #0] + 8003b16: 691b ldr r3, [r3, #16] + 8003b18: 68fa ldr r2, [r7, #12] + 8003b1a: 429a cmp r2, r3 + 8003b1c: dbdb blt.n 8003ad6 + return NULL; + 8003b1e: 2300 movs r3, #0 +} + 8003b20: 0018 movs r0, r3 + 8003b22: 46bd mov sp, r7 + 8003b24: b004 add sp, #16 + 8003b26: bd80 pop {r7, pc} + 8003b28: 200000bc .word 0x200000bc + +08003b2c : + +static __inline bool is_vacant(dhcp_entry_t *entry) +{ + 8003b2c: b580 push {r7, lr} + 8003b2e: b082 sub sp, #8 + 8003b30: af00 add r7, sp, #0 + 8003b32: 6078 str r0, [r7, #4] + return memcmp("\0\0\0\0\0", entry->mac, 6) == 0; + 8003b34: 6879 ldr r1, [r7, #4] + 8003b36: 4b06 ldr r3, [pc, #24] ; (8003b50 ) + 8003b38: 2206 movs r2, #6 + 8003b3a: 0018 movs r0, r3 + 8003b3c: f00c f8a2 bl 800fc84 + 8003b40: 0003 movs r3, r0 + 8003b42: 425a negs r2, r3 + 8003b44: 4153 adcs r3, r2 + 8003b46: b2db uxtb r3, r3 +} + 8003b48: 0018 movs r0, r3 + 8003b4a: 46bd mov sp, r7 + 8003b4c: b002 add sp, #8 + 8003b4e: bd80 pop {r7, pc} + 8003b50: 0800fcfc .word 0x0800fcfc + +08003b54 : + +static dhcp_entry_t *vacant_address() +{ + 8003b54: b580 push {r7, lr} + 8003b56: b082 sub sp, #8 + 8003b58: af00 add r7, sp, #0 + int i; + for (i = 0; i < config->num_entry; i++) + 8003b5a: 2300 movs r3, #0 + 8003b5c: 607b str r3, [r7, #4] + 8003b5e: e01a b.n 8003b96 + if (is_vacant(config->entries + i)) + 8003b60: 4b12 ldr r3, [pc, #72] ; (8003bac ) + 8003b62: 681b ldr r3, [r3, #0] + 8003b64: 6959 ldr r1, [r3, #20] + 8003b66: 687a ldr r2, [r7, #4] + 8003b68: 0013 movs r3, r2 + 8003b6a: 009b lsls r3, r3, #2 + 8003b6c: 189b adds r3, r3, r2 + 8003b6e: 009b lsls r3, r3, #2 + 8003b70: 18cb adds r3, r1, r3 + 8003b72: 0018 movs r0, r3 + 8003b74: f7ff ffda bl 8003b2c + 8003b78: 1e03 subs r3, r0, #0 + 8003b7a: d009 beq.n 8003b90 + return config->entries + i; + 8003b7c: 4b0b ldr r3, [pc, #44] ; (8003bac ) + 8003b7e: 681b ldr r3, [r3, #0] + 8003b80: 6959 ldr r1, [r3, #20] + 8003b82: 687a ldr r2, [r7, #4] + 8003b84: 0013 movs r3, r2 + 8003b86: 009b lsls r3, r3, #2 + 8003b88: 189b adds r3, r3, r2 + 8003b8a: 009b lsls r3, r3, #2 + 8003b8c: 18cb adds r3, r1, r3 + 8003b8e: e009 b.n 8003ba4 + for (i = 0; i < config->num_entry; i++) + 8003b90: 687b ldr r3, [r7, #4] + 8003b92: 3301 adds r3, #1 + 8003b94: 607b str r3, [r7, #4] + 8003b96: 4b05 ldr r3, [pc, #20] ; (8003bac ) + 8003b98: 681b ldr r3, [r3, #0] + 8003b9a: 691b ldr r3, [r3, #16] + 8003b9c: 687a ldr r2, [r7, #4] + 8003b9e: 429a cmp r2, r3 + 8003ba0: dbde blt.n 8003b60 + return NULL; + 8003ba2: 2300 movs r3, #0 +} + 8003ba4: 0018 movs r0, r3 + 8003ba6: 46bd mov sp, r7 + 8003ba8: b002 add sp, #8 + 8003baa: bd80 pop {r7, pc} + 8003bac: 200000bc .word 0x200000bc + +08003bb0 : + +static __inline void free_entry(dhcp_entry_t *entry) +{ + 8003bb0: b580 push {r7, lr} + 8003bb2: b082 sub sp, #8 + 8003bb4: af00 add r7, sp, #0 + 8003bb6: 6078 str r0, [r7, #4] + memset(entry->mac, 0, 6); + 8003bb8: 687b ldr r3, [r7, #4] + 8003bba: 2206 movs r2, #6 + 8003bbc: 2100 movs r1, #0 + 8003bbe: 0018 movs r0, r3 + 8003bc0: f00c f878 bl 800fcb4 +} + 8003bc4: 46c0 nop ; (mov r8, r8) + 8003bc6: 46bd mov sp, r7 + 8003bc8: b002 add sp, #8 + 8003bca: bd80 pop {r7, pc} + +08003bcc : + +uint8_t *find_dhcp_option(uint8_t *attrs, int size, uint8_t attr) +{ + 8003bcc: b580 push {r7, lr} + 8003bce: b086 sub sp, #24 + 8003bd0: af00 add r7, sp, #0 + 8003bd2: 60f8 str r0, [r7, #12] + 8003bd4: 60b9 str r1, [r7, #8] + 8003bd6: 1dfb adds r3, r7, #7 + 8003bd8: 701a strb r2, [r3, #0] + int i = 0; + 8003bda: 2300 movs r3, #0 + 8003bdc: 617b str r3, [r7, #20] + while ((i + 1) < size) + 8003bde: e01d b.n 8003c1c + { + int next = i + attrs[i + 1] + 2; + 8003be0: 697b ldr r3, [r7, #20] + 8003be2: 3301 adds r3, #1 + 8003be4: 68fa ldr r2, [r7, #12] + 8003be6: 18d3 adds r3, r2, r3 + 8003be8: 781b ldrb r3, [r3, #0] + 8003bea: 001a movs r2, r3 + 8003bec: 697b ldr r3, [r7, #20] + 8003bee: 18d3 adds r3, r2, r3 + 8003bf0: 3302 adds r3, #2 + 8003bf2: 613b str r3, [r7, #16] + if (next > size) return NULL; + 8003bf4: 693a ldr r2, [r7, #16] + 8003bf6: 68bb ldr r3, [r7, #8] + 8003bf8: 429a cmp r2, r3 + 8003bfa: dd01 ble.n 8003c00 + 8003bfc: 2300 movs r3, #0 + 8003bfe: e013 b.n 8003c28 + if (attrs[i] == attr) + 8003c00: 697b ldr r3, [r7, #20] + 8003c02: 68fa ldr r2, [r7, #12] + 8003c04: 18d3 adds r3, r2, r3 + 8003c06: 781b ldrb r3, [r3, #0] + 8003c08: 1dfa adds r2, r7, #7 + 8003c0a: 7812 ldrb r2, [r2, #0] + 8003c0c: 429a cmp r2, r3 + 8003c0e: d103 bne.n 8003c18 + return attrs + i; + 8003c10: 697b ldr r3, [r7, #20] + 8003c12: 68fa ldr r2, [r7, #12] + 8003c14: 18d3 adds r3, r2, r3 + 8003c16: e007 b.n 8003c28 + i = next; + 8003c18: 693b ldr r3, [r7, #16] + 8003c1a: 617b str r3, [r7, #20] + while ((i + 1) < size) + 8003c1c: 697b ldr r3, [r7, #20] + 8003c1e: 3301 adds r3, #1 + 8003c20: 68ba ldr r2, [r7, #8] + 8003c22: 429a cmp r2, r3 + 8003c24: dcdc bgt.n 8003be0 + } + return NULL; + 8003c26: 2300 movs r3, #0 +} + 8003c28: 0018 movs r0, r3 + 8003c2a: 46bd mov sp, r7 + 8003c2c: b006 add sp, #24 + 8003c2e: bd80 pop {r7, pc} + +08003c30 : + uint32_t dns, + int lease_time, + uint32_t serverid, + uint32_t router, + uint32_t subnet) +{ + 8003c30: b580 push {r7, lr} + 8003c32: b086 sub sp, #24 + 8003c34: af00 add r7, sp, #0 + 8003c36: 60f8 str r0, [r7, #12] + 8003c38: 607a str r2, [r7, #4] + 8003c3a: 603b str r3, [r7, #0] + 8003c3c: 200b movs r0, #11 + 8003c3e: 183b adds r3, r7, r0 + 8003c40: 1c0a adds r2, r1, #0 + 8003c42: 701a strb r2, [r3, #0] + uint8_t *ptr = (uint8_t *)dest; + 8003c44: 68fb ldr r3, [r7, #12] + 8003c46: 617b str r3, [r7, #20] + /* ACK message type */ + *ptr++ = 53; + 8003c48: 697b ldr r3, [r7, #20] + 8003c4a: 1c5a adds r2, r3, #1 + 8003c4c: 617a str r2, [r7, #20] + 8003c4e: 2235 movs r2, #53 ; 0x35 + 8003c50: 701a strb r2, [r3, #0] + *ptr++ = 1; + 8003c52: 697b ldr r3, [r7, #20] + 8003c54: 1c5a adds r2, r3, #1 + 8003c56: 617a str r2, [r7, #20] + 8003c58: 2201 movs r2, #1 + 8003c5a: 701a strb r2, [r3, #0] + *ptr++ = msg_type; + 8003c5c: 697b ldr r3, [r7, #20] + 8003c5e: 1c5a adds r2, r3, #1 + 8003c60: 617a str r2, [r7, #20] + 8003c62: 183a adds r2, r7, r0 + 8003c64: 7812 ldrb r2, [r2, #0] + 8003c66: 701a strb r2, [r3, #0] + + /* dhcp server identifier */ + *ptr++ = DHCP_SERVERID; + 8003c68: 697b ldr r3, [r7, #20] + 8003c6a: 1c5a adds r2, r3, #1 + 8003c6c: 617a str r2, [r7, #20] + 8003c6e: 2236 movs r2, #54 ; 0x36 + 8003c70: 701a strb r2, [r3, #0] + *ptr++ = 4; + 8003c72: 697b ldr r3, [r7, #20] + 8003c74: 1c5a adds r2, r3, #1 + 8003c76: 617a str r2, [r7, #20] + 8003c78: 2204 movs r2, #4 + 8003c7a: 701a strb r2, [r3, #0] + set_ip(ptr, serverid); + 8003c7c: 6a7a ldr r2, [r7, #36] ; 0x24 + 8003c7e: 697b ldr r3, [r7, #20] + 8003c80: 0011 movs r1, r2 + 8003c82: 0018 movs r0, r3 + 8003c84: f7ff fede bl 8003a44 + ptr += 4; + 8003c88: 697b ldr r3, [r7, #20] + 8003c8a: 3304 adds r3, #4 + 8003c8c: 617b str r3, [r7, #20] + + /* lease time */ + *ptr++ = DHCP_LEASETIME; + 8003c8e: 697b ldr r3, [r7, #20] + 8003c90: 1c5a adds r2, r3, #1 + 8003c92: 617a str r2, [r7, #20] + 8003c94: 2233 movs r2, #51 ; 0x33 + 8003c96: 701a strb r2, [r3, #0] + *ptr++ = 4; + 8003c98: 697b ldr r3, [r7, #20] + 8003c9a: 1c5a adds r2, r3, #1 + 8003c9c: 617a str r2, [r7, #20] + 8003c9e: 2204 movs r2, #4 + 8003ca0: 701a strb r2, [r3, #0] + *ptr++ = (lease_time >> 24) & 0xFF; + 8003ca2: 6a3b ldr r3, [r7, #32] + 8003ca4: 0e19 lsrs r1, r3, #24 + 8003ca6: 697b ldr r3, [r7, #20] + 8003ca8: 1c5a adds r2, r3, #1 + 8003caa: 617a str r2, [r7, #20] + 8003cac: b2ca uxtb r2, r1 + 8003cae: 701a strb r2, [r3, #0] + *ptr++ = (lease_time >> 16) & 0xFF; + 8003cb0: 6a3b ldr r3, [r7, #32] + 8003cb2: 1419 asrs r1, r3, #16 + 8003cb4: 697b ldr r3, [r7, #20] + 8003cb6: 1c5a adds r2, r3, #1 + 8003cb8: 617a str r2, [r7, #20] + 8003cba: b2ca uxtb r2, r1 + 8003cbc: 701a strb r2, [r3, #0] + *ptr++ = (lease_time >> 8) & 0xFF; + 8003cbe: 6a3b ldr r3, [r7, #32] + 8003cc0: 1219 asrs r1, r3, #8 + 8003cc2: 697b ldr r3, [r7, #20] + 8003cc4: 1c5a adds r2, r3, #1 + 8003cc6: 617a str r2, [r7, #20] + 8003cc8: b2ca uxtb r2, r1 + 8003cca: 701a strb r2, [r3, #0] + *ptr++ = (lease_time >> 0) & 0xFF; + 8003ccc: 697b ldr r3, [r7, #20] + 8003cce: 1c5a adds r2, r3, #1 + 8003cd0: 617a str r2, [r7, #20] + 8003cd2: 6a3a ldr r2, [r7, #32] + 8003cd4: b2d2 uxtb r2, r2 + 8003cd6: 701a strb r2, [r3, #0] + + /* subnet mask */ + *ptr++ = DHCP_SUBNETMASK; + 8003cd8: 697b ldr r3, [r7, #20] + 8003cda: 1c5a adds r2, r3, #1 + 8003cdc: 617a str r2, [r7, #20] + 8003cde: 2201 movs r2, #1 + 8003ce0: 701a strb r2, [r3, #0] + *ptr++ = 4; + 8003ce2: 697b ldr r3, [r7, #20] + 8003ce4: 1c5a adds r2, r3, #1 + 8003ce6: 617a str r2, [r7, #20] + 8003ce8: 2204 movs r2, #4 + 8003cea: 701a strb r2, [r3, #0] + set_ip(ptr, subnet); + 8003cec: 6afa ldr r2, [r7, #44] ; 0x2c + 8003cee: 697b ldr r3, [r7, #20] + 8003cf0: 0011 movs r1, r2 + 8003cf2: 0018 movs r0, r3 + 8003cf4: f7ff fea6 bl 8003a44 + ptr += 4; + 8003cf8: 697b ldr r3, [r7, #20] + 8003cfa: 3304 adds r3, #4 + 8003cfc: 617b str r3, [r7, #20] + + /* router */ + if (router != 0) + 8003cfe: 6abb ldr r3, [r7, #40] ; 0x28 + 8003d00: 2b00 cmp r3, #0 + 8003d02: d012 beq.n 8003d2a + { + *ptr++ = DHCP_ROUTER; + 8003d04: 697b ldr r3, [r7, #20] + 8003d06: 1c5a adds r2, r3, #1 + 8003d08: 617a str r2, [r7, #20] + 8003d0a: 2203 movs r2, #3 + 8003d0c: 701a strb r2, [r3, #0] + *ptr++ = 4; + 8003d0e: 697b ldr r3, [r7, #20] + 8003d10: 1c5a adds r2, r3, #1 + 8003d12: 617a str r2, [r7, #20] + 8003d14: 2204 movs r2, #4 + 8003d16: 701a strb r2, [r3, #0] + set_ip(ptr, router); + 8003d18: 6aba ldr r2, [r7, #40] ; 0x28 + 8003d1a: 697b ldr r3, [r7, #20] + 8003d1c: 0011 movs r1, r2 + 8003d1e: 0018 movs r0, r3 + 8003d20: f7ff fe90 bl 8003a44 + ptr += 4; + 8003d24: 697b ldr r3, [r7, #20] + 8003d26: 3304 adds r3, #4 + 8003d28: 617b str r3, [r7, #20] + } + + /* domain name */ + if (domain != NULL) + 8003d2a: 687b ldr r3, [r7, #4] + 8003d2c: 2b00 cmp r3, #0 + 8003d2e: d01a beq.n 8003d66 + { + int len = strlen(domain); + 8003d30: 687b ldr r3, [r7, #4] + 8003d32: 0018 movs r0, r3 + 8003d34: f7fc f9f2 bl 800011c + 8003d38: 0003 movs r3, r0 + 8003d3a: 613b str r3, [r7, #16] + *ptr++ = DHCP_DNSDOMAIN; + 8003d3c: 697b ldr r3, [r7, #20] + 8003d3e: 1c5a adds r2, r3, #1 + 8003d40: 617a str r2, [r7, #20] + 8003d42: 220f movs r2, #15 + 8003d44: 701a strb r2, [r3, #0] + *ptr++ = len; + 8003d46: 697b ldr r3, [r7, #20] + 8003d48: 1c5a adds r2, r3, #1 + 8003d4a: 617a str r2, [r7, #20] + 8003d4c: 693a ldr r2, [r7, #16] + 8003d4e: b2d2 uxtb r2, r2 + 8003d50: 701a strb r2, [r3, #0] + memcpy(ptr, domain, len); + 8003d52: 693a ldr r2, [r7, #16] + 8003d54: 6879 ldr r1, [r7, #4] + 8003d56: 697b ldr r3, [r7, #20] + 8003d58: 0018 movs r0, r3 + 8003d5a: f00b ffa2 bl 800fca2 + ptr += len; + 8003d5e: 693b ldr r3, [r7, #16] + 8003d60: 697a ldr r2, [r7, #20] + 8003d62: 18d3 adds r3, r2, r3 + 8003d64: 617b str r3, [r7, #20] + } + + /* domain name server (DNS) */ + if (dns != 0) + 8003d66: 683b ldr r3, [r7, #0] + 8003d68: 2b00 cmp r3, #0 + 8003d6a: d012 beq.n 8003d92 + { + *ptr++ = DHCP_DNSSERVER; + 8003d6c: 697b ldr r3, [r7, #20] + 8003d6e: 1c5a adds r2, r3, #1 + 8003d70: 617a str r2, [r7, #20] + 8003d72: 2206 movs r2, #6 + 8003d74: 701a strb r2, [r3, #0] + *ptr++ = 4; + 8003d76: 697b ldr r3, [r7, #20] + 8003d78: 1c5a adds r2, r3, #1 + 8003d7a: 617a str r2, [r7, #20] + 8003d7c: 2204 movs r2, #4 + 8003d7e: 701a strb r2, [r3, #0] + set_ip(ptr, dns); + 8003d80: 683a ldr r2, [r7, #0] + 8003d82: 697b ldr r3, [r7, #20] + 8003d84: 0011 movs r1, r2 + 8003d86: 0018 movs r0, r3 + 8003d88: f7ff fe5c bl 8003a44 + ptr += 4; + 8003d8c: 697b ldr r3, [r7, #20] + 8003d8e: 3304 adds r3, #4 + 8003d90: 617b str r3, [r7, #20] + } + + /* end */ + *ptr++ = DHCP_END; + 8003d92: 697b ldr r3, [r7, #20] + 8003d94: 1c5a adds r2, r3, #1 + 8003d96: 617a str r2, [r7, #20] + 8003d98: 22ff movs r2, #255 ; 0xff + 8003d9a: 701a strb r2, [r3, #0] + return ptr - (uint8_t *)dest; + 8003d9c: 697a ldr r2, [r7, #20] + 8003d9e: 68fb ldr r3, [r7, #12] + 8003da0: 1ad3 subs r3, r2, r3 +} + 8003da2: 0018 movs r0, r3 + 8003da4: 46bd mov sp, r7 + 8003da6: b006 add sp, #24 + 8003da8: bd80 pop {r7, pc} + ... + +08003dac : + +static void udp_recv_proc(void *arg, struct udp_pcb *upcb, struct pbuf *p, struct ip_addr *addr, u16_t port) +{ + 8003dac: b5f0 push {r4, r5, r6, r7, lr} + 8003dae: 46c6 mov lr, r8 + 8003db0: b500 push {lr} + 8003db2: b08e sub sp, #56 ; 0x38 + 8003db4: af04 add r7, sp, #16 + 8003db6: 6178 str r0, [r7, #20] + 8003db8: 6139 str r1, [r7, #16] + 8003dba: 60fa str r2, [r7, #12] + 8003dbc: 60bb str r3, [r7, #8] + uint8_t *ptr; + dhcp_entry_t *entry; + struct pbuf *pp; + + int n = p->len; + 8003dbe: 68fb ldr r3, [r7, #12] + 8003dc0: 895b ldrh r3, [r3, #10] + 8003dc2: 623b str r3, [r7, #32] + if (n > sizeof(dhcp_data)) n = sizeof(dhcp_data); + 8003dc4: 6a3a ldr r2, [r7, #32] + 8003dc6: 2381 movs r3, #129 ; 0x81 + 8003dc8: 009b lsls r3, r3, #2 + 8003dca: 429a cmp r2, r3 + 8003dcc: d902 bls.n 8003dd4 + 8003dce: 2381 movs r3, #129 ; 0x81 + 8003dd0: 009b lsls r3, r3, #2 + 8003dd2: 623b str r3, [r7, #32] + memcpy(&dhcp_data, p->payload, n); + 8003dd4: 68fb ldr r3, [r7, #12] + 8003dd6: 6859 ldr r1, [r3, #4] + 8003dd8: 6a3a ldr r2, [r7, #32] + 8003dda: 4baa ldr r3, [pc, #680] ; (8004084 ) + 8003ddc: 0018 movs r0, r3 + 8003dde: f00b ff60 bl 800fca2 + switch (dhcp_data.dp_options[2]) + 8003de2: 4ba8 ldr r3, [pc, #672] ; (8004084 ) + 8003de4: 22f2 movs r2, #242 ; 0xf2 + 8003de6: 5c9b ldrb r3, [r3, r2] + 8003de8: 2b01 cmp r3, #1 + 8003dea: d003 beq.n 8003df4 + 8003dec: 2b03 cmp r3, #3 + 8003dee: d100 bne.n 8003df2 + 8003df0: e081 b.n 8003ef6 + udp_sendto(upcb, pp, IP_ADDR_BROADCAST, port); + pbuf_free(pp); + break; + + default: + break; + 8003df2: e13d b.n 8004070 + entry = entry_by_mac(dhcp_data.dp_chaddr); + 8003df4: 4ba4 ldr r3, [pc, #656] ; (8004088 ) + 8003df6: 0018 movs r0, r3 + 8003df8: f7ff fe66 bl 8003ac8 + 8003dfc: 0003 movs r3, r0 + 8003dfe: 627b str r3, [r7, #36] ; 0x24 + if (entry == NULL) entry = vacant_address(); + 8003e00: 6a7b ldr r3, [r7, #36] ; 0x24 + 8003e02: 2b00 cmp r3, #0 + 8003e04: d103 bne.n 8003e0e + 8003e06: f7ff fea5 bl 8003b54 + 8003e0a: 0003 movs r3, r0 + 8003e0c: 627b str r3, [r7, #36] ; 0x24 + if (entry == NULL) break; + 8003e0e: 6a7b ldr r3, [r7, #36] ; 0x24 + 8003e10: 2b00 cmp r3, #0 + 8003e12: d100 bne.n 8003e16 + 8003e14: e11f b.n 8004056 + dhcp_data.dp_op = 2; /* reply */ + 8003e16: 4b9b ldr r3, [pc, #620] ; (8004084 ) + 8003e18: 2202 movs r2, #2 + 8003e1a: 701a strb r2, [r3, #0] + dhcp_data.dp_secs = 0; + 8003e1c: 4b99 ldr r3, [pc, #612] ; (8004084 ) + 8003e1e: 2200 movs r2, #0 + 8003e20: 811a strh r2, [r3, #8] + dhcp_data.dp_flags = 0; + 8003e22: 4b98 ldr r3, [pc, #608] ; (8004084 ) + 8003e24: 2200 movs r2, #0 + 8003e26: 815a strh r2, [r3, #10] + set_ip(dhcp_data.dp_yiaddr, get_ip(entry->addr)); + 8003e28: 6a7b ldr r3, [r7, #36] ; 0x24 + 8003e2a: 3306 adds r3, #6 + 8003e2c: 0018 movs r0, r3 + 8003e2e: f7ff fdf9 bl 8003a24 + 8003e32: 0002 movs r2, r0 + 8003e34: 4b95 ldr r3, [pc, #596] ; (800408c ) + 8003e36: 0011 movs r1, r2 + 8003e38: 0018 movs r0, r3 + 8003e3a: f7ff fe03 bl 8003a44 + memcpy(dhcp_data.dp_magic, magic_cookie, 4); + 8003e3e: 4b94 ldr r3, [pc, #592] ; (8004090 ) + 8003e40: 681a ldr r2, [r3, #0] + 8003e42: 4b90 ldr r3, [pc, #576] ; (8004084 ) + 8003e44: 21ec movs r1, #236 ; 0xec + 8003e46: 505a str r2, [r3, r1] + memset(dhcp_data.dp_options, 0, sizeof(dhcp_data.dp_options)); + 8003e48: 2314 movs r3, #20 + 8003e4a: 33ff adds r3, #255 ; 0xff + 8003e4c: 001a movs r2, r3 + 8003e4e: 4b91 ldr r3, [pc, #580] ; (8004094 ) + 8003e50: 2100 movs r1, #0 + 8003e52: 0018 movs r0, r3 + 8003e54: f00b ff2e bl 800fcb4 + config->domain, + 8003e58: 4b8f ldr r3, [pc, #572] ; (8004098 ) + 8003e5a: 681b ldr r3, [r3, #0] + fill_options(dhcp_data.dp_options, + 8003e5c: 68dc ldr r4, [r3, #12] + get_ip(config->dns), + 8003e5e: 4b8e ldr r3, [pc, #568] ; (8004098 ) + 8003e60: 681b ldr r3, [r3, #0] + 8003e62: 3306 adds r3, #6 + fill_options(dhcp_data.dp_options, + 8003e64: 0018 movs r0, r3 + 8003e66: f7ff fddd bl 8003a24 + 8003e6a: 6078 str r0, [r7, #4] + entry->lease, + 8003e6c: 6a7b ldr r3, [r7, #36] ; 0x24 + 8003e6e: 691b ldr r3, [r3, #16] + fill_options(dhcp_data.dp_options, + 8003e70: 001d movs r5, r3 + get_ip(config->addr), + 8003e72: 4b89 ldr r3, [pc, #548] ; (8004098 ) + 8003e74: 681b ldr r3, [r3, #0] + fill_options(dhcp_data.dp_options, + 8003e76: 0018 movs r0, r3 + 8003e78: f7ff fdd4 bl 8003a24 + 8003e7c: 0006 movs r6, r0 + get_ip(config->addr), + 8003e7e: 4b86 ldr r3, [pc, #536] ; (8004098 ) + 8003e80: 681b ldr r3, [r3, #0] + fill_options(dhcp_data.dp_options, + 8003e82: 0018 movs r0, r3 + 8003e84: f7ff fdce bl 8003a24 + 8003e88: 4680 mov r8, r0 + get_ip(entry->subnet)); + 8003e8a: 6a7b ldr r3, [r7, #36] ; 0x24 + 8003e8c: 330a adds r3, #10 + fill_options(dhcp_data.dp_options, + 8003e8e: 0018 movs r0, r3 + 8003e90: f7ff fdc8 bl 8003a24 + 8003e94: 0003 movs r3, r0 + 8003e96: 487f ldr r0, [pc, #508] ; (8004094 ) + 8003e98: 9303 str r3, [sp, #12] + 8003e9a: 4642 mov r2, r8 + 8003e9c: 9202 str r2, [sp, #8] + 8003e9e: 9601 str r6, [sp, #4] + 8003ea0: 9500 str r5, [sp, #0] + 8003ea2: 687b ldr r3, [r7, #4] + 8003ea4: 0022 movs r2, r4 + 8003ea6: 2102 movs r1, #2 + 8003ea8: f7ff fec2 bl 8003c30 + pp = pbuf_alloc(PBUF_TRANSPORT, sizeof(dhcp_data), PBUF_POOL); + 8003eac: 2381 movs r3, #129 ; 0x81 + 8003eae: 009b lsls r3, r3, #2 + 8003eb0: 2203 movs r2, #3 + 8003eb2: 0019 movs r1, r3 + 8003eb4: 2000 movs r0, #0 + 8003eb6: f001 f969 bl 800518c + 8003eba: 0003 movs r3, r0 + 8003ebc: 61bb str r3, [r7, #24] + if (pp == NULL) break; + 8003ebe: 69bb ldr r3, [r7, #24] + 8003ec0: 2b00 cmp r3, #0 + 8003ec2: d100 bne.n 8003ec6 + 8003ec4: e0c9 b.n 800405a + memcpy(pp->payload, &dhcp_data, sizeof(dhcp_data)); + 8003ec6: 69bb ldr r3, [r7, #24] + 8003ec8: 6858 ldr r0, [r3, #4] + 8003eca: 2381 movs r3, #129 ; 0x81 + 8003ecc: 009a lsls r2, r3, #2 + 8003ece: 4b6d ldr r3, [pc, #436] ; (8004084 ) + 8003ed0: 0019 movs r1, r3 + 8003ed2: f00b fee6 bl 800fca2 + udp_sendto(upcb, pp, IP_ADDR_BROADCAST, port); + 8003ed6: 2338 movs r3, #56 ; 0x38 + 8003ed8: 2208 movs r2, #8 + 8003eda: 4694 mov ip, r2 + 8003edc: 44bc add ip, r7 + 8003ede: 4463 add r3, ip + 8003ee0: 881b ldrh r3, [r3, #0] + 8003ee2: 4a6e ldr r2, [pc, #440] ; (800409c ) + 8003ee4: 69b9 ldr r1, [r7, #24] + 8003ee6: 6938 ldr r0, [r7, #16] + 8003ee8: f006 fe80 bl 800abec + pbuf_free(pp); + 8003eec: 69bb ldr r3, [r7, #24] + 8003eee: 0018 movs r0, r3 + 8003ef0: f001 fbd8 bl 80056a4 + break; + 8003ef4: e0bc b.n 8004070 + ptr = find_dhcp_option(dhcp_data.dp_options, sizeof(dhcp_data.dp_options), DHCP_IPADDRESS); + 8003ef6: 2314 movs r3, #20 + 8003ef8: 33ff adds r3, #255 ; 0xff + 8003efa: 0019 movs r1, r3 + 8003efc: 4b65 ldr r3, [pc, #404] ; (8004094 ) + 8003efe: 2232 movs r2, #50 ; 0x32 + 8003f00: 0018 movs r0, r3 + 8003f02: f7ff fe63 bl 8003bcc + 8003f06: 0003 movs r3, r0 + 8003f08: 61fb str r3, [r7, #28] + if (ptr == NULL) break; + 8003f0a: 69fb ldr r3, [r7, #28] + 8003f0c: 2b00 cmp r3, #0 + 8003f0e: d100 bne.n 8003f12 + 8003f10: e0a5 b.n 800405e + if (ptr[1] != 4) break; + 8003f12: 69fb ldr r3, [r7, #28] + 8003f14: 3301 adds r3, #1 + 8003f16: 781b ldrb r3, [r3, #0] + 8003f18: 2b04 cmp r3, #4 + 8003f1a: d000 beq.n 8003f1e + 8003f1c: e0a1 b.n 8004062 + ptr += 2; + 8003f1e: 69fb ldr r3, [r7, #28] + 8003f20: 3302 adds r3, #2 + 8003f22: 61fb str r3, [r7, #28] + entry = entry_by_mac(dhcp_data.dp_chaddr); + 8003f24: 4b58 ldr r3, [pc, #352] ; (8004088 ) + 8003f26: 0018 movs r0, r3 + 8003f28: f7ff fdce bl 8003ac8 + 8003f2c: 0003 movs r3, r0 + 8003f2e: 627b str r3, [r7, #36] ; 0x24 + if (entry != NULL) free_entry(entry); + 8003f30: 6a7b ldr r3, [r7, #36] ; 0x24 + 8003f32: 2b00 cmp r3, #0 + 8003f34: d003 beq.n 8003f3e + 8003f36: 6a7b ldr r3, [r7, #36] ; 0x24 + 8003f38: 0018 movs r0, r3 + 8003f3a: f7ff fe39 bl 8003bb0 + entry = entry_by_ip(get_ip(ptr)); + 8003f3e: 69fb ldr r3, [r7, #28] + 8003f40: 0018 movs r0, r3 + 8003f42: f7ff fd6f bl 8003a24 + 8003f46: 0003 movs r3, r0 + 8003f48: 0018 movs r0, r3 + 8003f4a: f7ff fd8b bl 8003a64 + 8003f4e: 0003 movs r3, r0 + 8003f50: 627b str r3, [r7, #36] ; 0x24 + if (entry == NULL) break; + 8003f52: 6a7b ldr r3, [r7, #36] ; 0x24 + 8003f54: 2b00 cmp r3, #0 + 8003f56: d100 bne.n 8003f5a + 8003f58: e085 b.n 8004066 + if (!is_vacant(entry)) break; + 8003f5a: 6a7b ldr r3, [r7, #36] ; 0x24 + 8003f5c: 0018 movs r0, r3 + 8003f5e: f7ff fde5 bl 8003b2c + 8003f62: 0003 movs r3, r0 + 8003f64: 001a movs r2, r3 + 8003f66: 2301 movs r3, #1 + 8003f68: 4053 eors r3, r2 + 8003f6a: b2db uxtb r3, r3 + 8003f6c: 2b00 cmp r3, #0 + 8003f6e: d000 beq.n 8003f72 + 8003f70: e07b b.n 800406a + memcpy(dhcp_data.dp_yiaddr, ptr, 4); + 8003f72: 4b44 ldr r3, [pc, #272] ; (8004084 ) + 8003f74: 69fa ldr r2, [r7, #28] + 8003f76: 3310 adds r3, #16 + 8003f78: 0011 movs r1, r2 + 8003f7a: 2204 movs r2, #4 + 8003f7c: 0018 movs r0, r3 + 8003f7e: f00b fe90 bl 800fca2 + dhcp_data.dp_op = 2; /* reply */ + 8003f82: 4b40 ldr r3, [pc, #256] ; (8004084 ) + 8003f84: 2202 movs r2, #2 + 8003f86: 701a strb r2, [r3, #0] + dhcp_data.dp_secs = 0; + 8003f88: 4b3e ldr r3, [pc, #248] ; (8004084 ) + 8003f8a: 2200 movs r2, #0 + 8003f8c: 811a strh r2, [r3, #8] + dhcp_data.dp_flags = 0; + 8003f8e: 4b3d ldr r3, [pc, #244] ; (8004084 ) + 8003f90: 2200 movs r2, #0 + 8003f92: 815a strh r2, [r3, #10] + memcpy(dhcp_data.dp_magic, magic_cookie, 4); + 8003f94: 4b3e ldr r3, [pc, #248] ; (8004090 ) + 8003f96: 681a ldr r2, [r3, #0] + 8003f98: 4b3a ldr r3, [pc, #232] ; (8004084 ) + 8003f9a: 21ec movs r1, #236 ; 0xec + 8003f9c: 505a str r2, [r3, r1] + memset(dhcp_data.dp_options, 0, sizeof(dhcp_data.dp_options)); + 8003f9e: 2314 movs r3, #20 + 8003fa0: 33ff adds r3, #255 ; 0xff + 8003fa2: 001a movs r2, r3 + 8003fa4: 4b3b ldr r3, [pc, #236] ; (8004094 ) + 8003fa6: 2100 movs r1, #0 + 8003fa8: 0018 movs r0, r3 + 8003faa: f00b fe83 bl 800fcb4 + config->domain, + 8003fae: 4b3a ldr r3, [pc, #232] ; (8004098 ) + 8003fb0: 681b ldr r3, [r3, #0] + fill_options(dhcp_data.dp_options, + 8003fb2: 68dc ldr r4, [r3, #12] + get_ip(config->dns), + 8003fb4: 4b38 ldr r3, [pc, #224] ; (8004098 ) + 8003fb6: 681b ldr r3, [r3, #0] + 8003fb8: 3306 adds r3, #6 + fill_options(dhcp_data.dp_options, + 8003fba: 0018 movs r0, r3 + 8003fbc: f7ff fd32 bl 8003a24 + 8003fc0: 6078 str r0, [r7, #4] + entry->lease, + 8003fc2: 6a7b ldr r3, [r7, #36] ; 0x24 + 8003fc4: 691b ldr r3, [r3, #16] + fill_options(dhcp_data.dp_options, + 8003fc6: 001d movs r5, r3 + get_ip(config->addr), + 8003fc8: 4b33 ldr r3, [pc, #204] ; (8004098 ) + 8003fca: 681b ldr r3, [r3, #0] + fill_options(dhcp_data.dp_options, + 8003fcc: 0018 movs r0, r3 + 8003fce: f7ff fd29 bl 8003a24 + 8003fd2: 0006 movs r6, r0 + get_ip(config->addr), + 8003fd4: 4b30 ldr r3, [pc, #192] ; (8004098 ) + 8003fd6: 681b ldr r3, [r3, #0] + fill_options(dhcp_data.dp_options, + 8003fd8: 0018 movs r0, r3 + 8003fda: f7ff fd23 bl 8003a24 + 8003fde: 4680 mov r8, r0 + get_ip(entry->subnet)); + 8003fe0: 6a7b ldr r3, [r7, #36] ; 0x24 + 8003fe2: 330a adds r3, #10 + fill_options(dhcp_data.dp_options, + 8003fe4: 0018 movs r0, r3 + 8003fe6: f7ff fd1d bl 8003a24 + 8003fea: 0003 movs r3, r0 + 8003fec: 4829 ldr r0, [pc, #164] ; (8004094 ) + 8003fee: 9303 str r3, [sp, #12] + 8003ff0: 4642 mov r2, r8 + 8003ff2: 9202 str r2, [sp, #8] + 8003ff4: 9601 str r6, [sp, #4] + 8003ff6: 9500 str r5, [sp, #0] + 8003ff8: 687b ldr r3, [r7, #4] + 8003ffa: 0022 movs r2, r4 + 8003ffc: 2105 movs r1, #5 + 8003ffe: f7ff fe17 bl 8003c30 + pp = pbuf_alloc(PBUF_TRANSPORT, sizeof(dhcp_data), PBUF_POOL); + 8004002: 2381 movs r3, #129 ; 0x81 + 8004004: 009b lsls r3, r3, #2 + 8004006: 2203 movs r2, #3 + 8004008: 0019 movs r1, r3 + 800400a: 2000 movs r0, #0 + 800400c: f001 f8be bl 800518c + 8004010: 0003 movs r3, r0 + 8004012: 61bb str r3, [r7, #24] + if (pp == NULL) break; + 8004014: 69bb ldr r3, [r7, #24] + 8004016: 2b00 cmp r3, #0 + 8004018: d029 beq.n 800406e + memcpy(entry->mac, dhcp_data.dp_chaddr, 6); + 800401a: 6a7b ldr r3, [r7, #36] ; 0x24 + 800401c: 491a ldr r1, [pc, #104] ; (8004088 ) + 800401e: 2206 movs r2, #6 + 8004020: 0018 movs r0, r3 + 8004022: f00b fe3e bl 800fca2 + memcpy(pp->payload, &dhcp_data, sizeof(dhcp_data)); + 8004026: 69bb ldr r3, [r7, #24] + 8004028: 6858 ldr r0, [r3, #4] + 800402a: 2381 movs r3, #129 ; 0x81 + 800402c: 009a lsls r2, r3, #2 + 800402e: 4b15 ldr r3, [pc, #84] ; (8004084 ) + 8004030: 0019 movs r1, r3 + 8004032: f00b fe36 bl 800fca2 + udp_sendto(upcb, pp, IP_ADDR_BROADCAST, port); + 8004036: 2338 movs r3, #56 ; 0x38 + 8004038: 2208 movs r2, #8 + 800403a: 4694 mov ip, r2 + 800403c: 44bc add ip, r7 + 800403e: 4463 add r3, ip + 8004040: 881b ldrh r3, [r3, #0] + 8004042: 4a16 ldr r2, [pc, #88] ; (800409c ) + 8004044: 69b9 ldr r1, [r7, #24] + 8004046: 6938 ldr r0, [r7, #16] + 8004048: f006 fdd0 bl 800abec + pbuf_free(pp); + 800404c: 69bb ldr r3, [r7, #24] + 800404e: 0018 movs r0, r3 + 8004050: f001 fb28 bl 80056a4 + break; + 8004054: e00c b.n 8004070 + if (entry == NULL) break; + 8004056: 46c0 nop ; (mov r8, r8) + 8004058: e00a b.n 8004070 + if (pp == NULL) break; + 800405a: 46c0 nop ; (mov r8, r8) + 800405c: e008 b.n 8004070 + if (ptr == NULL) break; + 800405e: 46c0 nop ; (mov r8, r8) + 8004060: e006 b.n 8004070 + if (ptr[1] != 4) break; + 8004062: 46c0 nop ; (mov r8, r8) + 8004064: e004 b.n 8004070 + if (entry == NULL) break; + 8004066: 46c0 nop ; (mov r8, r8) + 8004068: e002 b.n 8004070 + if (!is_vacant(entry)) break; + 800406a: 46c0 nop ; (mov r8, r8) + 800406c: e000 b.n 8004070 + if (pp == NULL) break; + 800406e: 46c0 nop ; (mov r8, r8) + } + pbuf_free(p); + 8004070: 68fb ldr r3, [r7, #12] + 8004072: 0018 movs r0, r3 + 8004074: f001 fb16 bl 80056a4 +} + 8004078: 46c0 nop ; (mov r8, r8) + 800407a: 46bd mov sp, r7 + 800407c: b00a add sp, #40 ; 0x28 + 800407e: bc04 pop {r2} + 8004080: 4690 mov r8, r2 + 8004082: bdf0 pop {r4, r5, r6, r7, pc} + 8004084: 200028f4 .word 0x200028f4 + 8004088: 20002910 .word 0x20002910 + 800408c: 20002904 .word 0x20002904 + 8004090: 2000000c .word 0x2000000c + 8004094: 200029e4 .word 0x200029e4 + 8004098: 200000bc .word 0x200000bc + 800409c: 0800fdc4 .word 0x0800fdc4 + +080040a0 : + +err_t dhserv_init(dhcp_config_t *c) +{ + 80040a0: b5b0 push {r4, r5, r7, lr} + 80040a2: b084 sub sp, #16 + 80040a4: af00 add r7, sp, #0 + 80040a6: 6078 str r0, [r7, #4] + err_t err; + udp_init(); + 80040a8: f006 fbbe bl 800a828 + dhserv_free(); + 80040ac: f000 f83c bl 8004128 + pcb = udp_new(); + 80040b0: f006 ff98 bl 800afe4 + 80040b4: 0002 movs r2, r0 + 80040b6: 4b18 ldr r3, [pc, #96] ; (8004118 ) + 80040b8: 601a str r2, [r3, #0] + if (pcb == NULL) + 80040ba: 4b17 ldr r3, [pc, #92] ; (8004118 ) + 80040bc: 681b ldr r3, [r3, #0] + 80040be: 2b00 cmp r3, #0 + 80040c0: d102 bne.n 80040c8 + return ERR_MEM; + 80040c2: 2301 movs r3, #1 + 80040c4: 425b negs r3, r3 + 80040c6: e022 b.n 800410e + err = udp_bind(pcb, IP_ADDR_ANY, c->port); + 80040c8: 4b13 ldr r3, [pc, #76] ; (8004118 ) + 80040ca: 6818 ldr r0, [r3, #0] + 80040cc: 687b ldr r3, [r7, #4] + 80040ce: 889a ldrh r2, [r3, #4] + 80040d0: 250f movs r5, #15 + 80040d2: 197c adds r4, r7, r5 + 80040d4: 4b11 ldr r3, [pc, #68] ; (800411c ) + 80040d6: 0019 movs r1, r3 + 80040d8: f006 fed6 bl 800ae88 + 80040dc: 0003 movs r3, r0 + 80040de: 7023 strb r3, [r4, #0] + if (err != ERR_OK) + 80040e0: 197b adds r3, r7, r5 + 80040e2: 781b ldrb r3, [r3, #0] + 80040e4: b25b sxtb r3, r3 + 80040e6: 2b00 cmp r3, #0 + 80040e8: d006 beq.n 80040f8 + { + dhserv_free(); + 80040ea: f000 f81d bl 8004128 + return err; + 80040ee: 230f movs r3, #15 + 80040f0: 18fb adds r3, r7, r3 + 80040f2: 781b ldrb r3, [r3, #0] + 80040f4: b25b sxtb r3, r3 + 80040f6: e00a b.n 800410e + } + udp_recv(pcb, udp_recv_proc, NULL); + 80040f8: 4b07 ldr r3, [pc, #28] ; (8004118 ) + 80040fa: 681b ldr r3, [r3, #0] + 80040fc: 4908 ldr r1, [pc, #32] ; (8004120 ) + 80040fe: 2200 movs r2, #0 + 8004100: 0018 movs r0, r3 + 8004102: f006 ff2d bl 800af60 + config = c; + 8004106: 4b07 ldr r3, [pc, #28] ; (8004124 ) + 8004108: 687a ldr r2, [r7, #4] + 800410a: 601a str r2, [r3, #0] + return ERR_OK; + 800410c: 2300 movs r3, #0 +} + 800410e: 0018 movs r0, r3 + 8004110: 46bd mov sp, r7 + 8004112: b004 add sp, #16 + 8004114: bdb0 pop {r4, r5, r7, pc} + 8004116: 46c0 nop ; (mov r8, r8) + 8004118: 200000b8 .word 0x200000b8 + 800411c: 0800fdc0 .word 0x0800fdc0 + 8004120: 08003dad .word 0x08003dad + 8004124: 200000bc .word 0x200000bc + +08004128 : + +void dhserv_free(void) +{ + 8004128: b580 push {r7, lr} + 800412a: af00 add r7, sp, #0 + if (pcb == NULL) return; + 800412c: 4b07 ldr r3, [pc, #28] ; (800414c ) + 800412e: 681b ldr r3, [r3, #0] + 8004130: 2b00 cmp r3, #0 + 8004132: d008 beq.n 8004146 + udp_remove(pcb); + 8004134: 4b05 ldr r3, [pc, #20] ; (800414c ) + 8004136: 681b ldr r3, [r3, #0] + 8004138: 0018 movs r0, r3 + 800413a: f006 ff21 bl 800af80 + pcb = NULL; + 800413e: 4b03 ldr r3, [pc, #12] ; (800414c ) + 8004140: 2200 movs r2, #0 + 8004142: 601a str r2, [r3, #0] + 8004144: e000 b.n 8004148 + if (pcb == NULL) return; + 8004146: 46c0 nop ; (mov r8, r8) +} + 8004148: 46bd mov sp, r7 + 800414a: bd80 pop {r7, pc} + 800414c: 200000b8 .word 0x200000b8 + +08004150 : + uint16_t type; + uint16_t Class; +} dns_query_t; + +static uint16_t get_uint16(const uint8_t *pnt) +{ + 8004150: b590 push {r4, r7, lr} + 8004152: b085 sub sp, #20 + 8004154: af00 add r7, sp, #0 + 8004156: 6078 str r0, [r7, #4] + uint16_t result; + memcpy(&result, pnt, sizeof(result)); + 8004158: 6879 ldr r1, [r7, #4] + 800415a: 240e movs r4, #14 + 800415c: 193b adds r3, r7, r4 + 800415e: 2202 movs r2, #2 + 8004160: 0018 movs r0, r3 + 8004162: f00b fd9e bl 800fca2 + return result; + 8004166: 193b adds r3, r7, r4 + 8004168: 881b ldrh r3, [r3, #0] +} + 800416a: 0018 movs r0, r3 + 800416c: 46bd mov sp, r7 + 800416e: b005 add sp, #20 + 8004170: bd90 pop {r4, r7, pc} + +08004172 : + +static int parse_next_query(void *data, int size, dns_query_t *query) +{ + 8004172: b590 push {r4, r7, lr} + 8004174: b089 sub sp, #36 ; 0x24 + 8004176: af00 add r7, sp, #0 + 8004178: 60f8 str r0, [r7, #12] + 800417a: 60b9 str r1, [r7, #8] + 800417c: 607a str r2, [r7, #4] + int len; + int lables; + uint8_t *ptr; + + len = 0; + 800417e: 2300 movs r3, #0 + 8004180: 61fb str r3, [r7, #28] + lables = 0; + 8004182: 2300 movs r3, #0 + 8004184: 61bb str r3, [r7, #24] + ptr = (uint8_t *)data; + 8004186: 68fb ldr r3, [r7, #12] + 8004188: 617b str r3, [r7, #20] + + while (true) + { + uint8_t lable_len; + if (size <= 0) return -1; + 800418a: 68bb ldr r3, [r7, #8] + 800418c: 2b00 cmp r3, #0 + 800418e: dc02 bgt.n 8004196 + 8004190: 2301 movs r3, #1 + 8004192: 425b negs r3, r3 + 8004194: e075 b.n 8004282 + lable_len = *ptr++; + 8004196: 697b ldr r3, [r7, #20] + 8004198: 1c5a adds r2, r3, #1 + 800419a: 617a str r2, [r7, #20] + 800419c: 2113 movs r1, #19 + 800419e: 187a adds r2, r7, r1 + 80041a0: 781b ldrb r3, [r3, #0] + 80041a2: 7013 strb r3, [r2, #0] + size--; + 80041a4: 68bb ldr r3, [r7, #8] + 80041a6: 3b01 subs r3, #1 + 80041a8: 60bb str r3, [r7, #8] + if (lable_len == 0) break; + 80041aa: 187b adds r3, r7, r1 + 80041ac: 781b ldrb r3, [r3, #0] + 80041ae: 2b00 cmp r3, #0 + 80041b0: d040 beq.n 8004234 + if (lables > 0) + 80041b2: 69bb ldr r3, [r7, #24] + 80041b4: 2b00 cmp r3, #0 + 80041b6: dd0b ble.n 80041d0 + { + if (len == DNS_MAX_HOST_NAME_LEN) return -2; + 80041b8: 69fb ldr r3, [r7, #28] + 80041ba: 2b80 cmp r3, #128 ; 0x80 + 80041bc: d102 bne.n 80041c4 + 80041be: 2302 movs r3, #2 + 80041c0: 425b negs r3, r3 + 80041c2: e05e b.n 8004282 + query->name[len++] = '.'; + 80041c4: 69fb ldr r3, [r7, #28] + 80041c6: 1c5a adds r2, r3, #1 + 80041c8: 61fa str r2, [r7, #28] + 80041ca: 687a ldr r2, [r7, #4] + 80041cc: 212e movs r1, #46 ; 0x2e + 80041ce: 54d1 strb r1, [r2, r3] + } + if (lable_len > size) return -1; + 80041d0: 2313 movs r3, #19 + 80041d2: 18fb adds r3, r7, r3 + 80041d4: 781b ldrb r3, [r3, #0] + 80041d6: 68ba ldr r2, [r7, #8] + 80041d8: 429a cmp r2, r3 + 80041da: da02 bge.n 80041e2 + 80041dc: 2301 movs r3, #1 + 80041de: 425b negs r3, r3 + 80041e0: e04f b.n 8004282 + if (len + lable_len >= DNS_MAX_HOST_NAME_LEN) return -2; + 80041e2: 2313 movs r3, #19 + 80041e4: 18fb adds r3, r7, r3 + 80041e6: 781a ldrb r2, [r3, #0] + 80041e8: 69fb ldr r3, [r7, #28] + 80041ea: 18d3 adds r3, r2, r3 + 80041ec: 2b7f cmp r3, #127 ; 0x7f + 80041ee: dd02 ble.n 80041f6 + 80041f0: 2302 movs r3, #2 + 80041f2: 425b negs r3, r3 + 80041f4: e045 b.n 8004282 + memcpy(&query->name[len], ptr, lable_len); + 80041f6: 687a ldr r2, [r7, #4] + 80041f8: 69fb ldr r3, [r7, #28] + 80041fa: 18d0 adds r0, r2, r3 + 80041fc: 2113 movs r1, #19 + 80041fe: 000c movs r4, r1 + 8004200: 187b adds r3, r7, r1 + 8004202: 781a ldrb r2, [r3, #0] + 8004204: 697b ldr r3, [r7, #20] + 8004206: 0019 movs r1, r3 + 8004208: f00b fd4b bl 800fca2 + len += lable_len; + 800420c: 0021 movs r1, r4 + 800420e: 187b adds r3, r7, r1 + 8004210: 781b ldrb r3, [r3, #0] + 8004212: 69fa ldr r2, [r7, #28] + 8004214: 18d3 adds r3, r2, r3 + 8004216: 61fb str r3, [r7, #28] + ptr += lable_len; + 8004218: 187b adds r3, r7, r1 + 800421a: 781b ldrb r3, [r3, #0] + 800421c: 697a ldr r2, [r7, #20] + 800421e: 18d3 adds r3, r2, r3 + 8004220: 617b str r3, [r7, #20] + size -= lable_len; + 8004222: 187b adds r3, r7, r1 + 8004224: 781b ldrb r3, [r3, #0] + 8004226: 68ba ldr r2, [r7, #8] + 8004228: 1ad3 subs r3, r2, r3 + 800422a: 60bb str r3, [r7, #8] + lables++; + 800422c: 69bb ldr r3, [r7, #24] + 800422e: 3301 adds r3, #1 + 8004230: 61bb str r3, [r7, #24] + { + 8004232: e7aa b.n 800418a + if (lable_len == 0) break; + 8004234: 46c0 nop ; (mov r8, r8) + } + + if (size < 4) return -1; + 8004236: 68bb ldr r3, [r7, #8] + 8004238: 2b03 cmp r3, #3 + 800423a: dc02 bgt.n 8004242 + 800423c: 2301 movs r3, #1 + 800423e: 425b negs r3, r3 + 8004240: e01f b.n 8004282 + query->name[len] = 0; + 8004242: 687a ldr r2, [r7, #4] + 8004244: 69fb ldr r3, [r7, #28] + 8004246: 18d3 adds r3, r2, r3 + 8004248: 2200 movs r2, #0 + 800424a: 701a strb r2, [r3, #0] + query->type = get_uint16(ptr); + 800424c: 697b ldr r3, [r7, #20] + 800424e: 0018 movs r0, r3 + 8004250: f7ff ff7e bl 8004150 + 8004254: 0003 movs r3, r0 + 8004256: 0019 movs r1, r3 + 8004258: 687b ldr r3, [r7, #4] + 800425a: 2280 movs r2, #128 ; 0x80 + 800425c: 5299 strh r1, [r3, r2] + ptr += 2; + 800425e: 697b ldr r3, [r7, #20] + 8004260: 3302 adds r3, #2 + 8004262: 617b str r3, [r7, #20] + query->Class = get_uint16(ptr); + 8004264: 697b ldr r3, [r7, #20] + 8004266: 0018 movs r0, r3 + 8004268: f7ff ff72 bl 8004150 + 800426c: 0003 movs r3, r0 + 800426e: 0019 movs r1, r3 + 8004270: 687b ldr r3, [r7, #4] + 8004272: 2282 movs r2, #130 ; 0x82 + 8004274: 5299 strh r1, [r3, r2] + ptr += 2; + 8004276: 697b ldr r3, [r7, #20] + 8004278: 3302 adds r3, #2 + 800427a: 617b str r3, [r7, #20] + return ptr - (uint8_t *)data; + 800427c: 697a ldr r2, [r7, #20] + 800427e: 68fb ldr r3, [r7, #12] + 8004280: 1ad3 subs r3, r2, r3 +} + 8004282: 0018 movs r0, r3 + 8004284: 46bd mov sp, r7 + 8004286: b009 add sp, #36 ; 0x24 + 8004288: bd90 pop {r4, r7, pc} + ... + +0800428c : + +static void udp_recv_proc(void *arg, struct udp_pcb *upcb, struct pbuf *p, struct ip_addr *addr, u16_t port) +{ + 800428c: b590 push {r4, r7, lr} + 800428e: b08b sub sp, #44 ; 0x2c + 8004290: af00 add r7, sp, #0 + 8004292: 60f8 str r0, [r7, #12] + 8004294: 60b9 str r1, [r7, #8] + 8004296: 607a str r2, [r7, #4] + 8004298: 603b str r3, [r7, #0] + static dns_query_t query; + struct pbuf *out; + ip_addr_t host_addr; + dns_answer_t *answer; + + if (p->len <= sizeof(dns_header_t)) goto error; + 800429a: 687b ldr r3, [r7, #4] + 800429c: 895b ldrh r3, [r3, #10] + 800429e: 2b0c cmp r3, #12 + 80042a0: d800 bhi.n 80042a4 + 80042a2: e142 b.n 800452a + header = (dns_header_t *)p->payload; + 80042a4: 687b ldr r3, [r7, #4] + 80042a6: 685b ldr r3, [r3, #4] + 80042a8: 627b str r3, [r7, #36] ; 0x24 + if (header->flags.qr != 0) goto error; + 80042aa: 6a7b ldr r3, [r7, #36] ; 0x24 + 80042ac: 789b ldrb r3, [r3, #2] + 80042ae: 227f movs r2, #127 ; 0x7f + 80042b0: 4393 bics r3, r2 + 80042b2: b2db uxtb r3, r3 + 80042b4: 2b00 cmp r3, #0 + 80042b6: d000 beq.n 80042ba + 80042b8: e139 b.n 800452e + if (ntohs(header->n_record[0]) != 1) goto error; + 80042ba: 6a7b ldr r3, [r7, #36] ; 0x24 + 80042bc: 791a ldrb r2, [r3, #4] + 80042be: 795b ldrb r3, [r3, #5] + 80042c0: 021b lsls r3, r3, #8 + 80042c2: 4313 orrs r3, r2 + 80042c4: b29b uxth r3, r3 + 80042c6: 0018 movs r0, r3 + 80042c8: f000 f9ba bl 8004640 + 80042cc: 0003 movs r3, r0 + 80042ce: 2b01 cmp r3, #1 + 80042d0: d000 beq.n 80042d4 + 80042d2: e12e b.n 8004532 + + len = parse_next_query(header + 1, p->len - sizeof(dns_header_t), &query); + 80042d4: 6a7b ldr r3, [r7, #36] ; 0x24 + 80042d6: 330c adds r3, #12 + 80042d8: 0018 movs r0, r3 + 80042da: 687b ldr r3, [r7, #4] + 80042dc: 895b ldrh r3, [r3, #10] + 80042de: 3b0c subs r3, #12 + 80042e0: 0019 movs r1, r3 + 80042e2: 4b9b ldr r3, [pc, #620] ; (8004550 ) + 80042e4: 001a movs r2, r3 + 80042e6: f7ff ff44 bl 8004172 + 80042ea: 0003 movs r3, r0 + 80042ec: 623b str r3, [r7, #32] + if (len < 0) goto error; + 80042ee: 6a3b ldr r3, [r7, #32] + 80042f0: 2b00 cmp r3, #0 + 80042f2: da00 bge.n 80042f6 + 80042f4: e11f b.n 8004536 + if (!query_proc(query.name, &host_addr)) goto error; + 80042f6: 4b97 ldr r3, [pc, #604] ; (8004554 ) + 80042f8: 681b ldr r3, [r3, #0] + 80042fa: 2214 movs r2, #20 + 80042fc: 18b9 adds r1, r7, r2 + 80042fe: 4a94 ldr r2, [pc, #592] ; (8004550 ) + 8004300: 0010 movs r0, r2 + 8004302: 4798 blx r3 + 8004304: 0003 movs r3, r0 + 8004306: 001a movs r2, r3 + 8004308: 2301 movs r3, #1 + 800430a: 4053 eors r3, r2 + 800430c: b2db uxtb r3, r3 + 800430e: 2b00 cmp r3, #0 + 8004310: d000 beq.n 8004314 + 8004312: e112 b.n 800453a + + len += sizeof(dns_header_t); + 8004314: 6a3b ldr r3, [r7, #32] + 8004316: 330c adds r3, #12 + 8004318: 623b str r3, [r7, #32] + out = pbuf_alloc(PBUF_TRANSPORT, len + 16, PBUF_POOL); + 800431a: 6a3b ldr r3, [r7, #32] + 800431c: b29b uxth r3, r3 + 800431e: 3310 adds r3, #16 + 8004320: b29b uxth r3, r3 + 8004322: 2203 movs r2, #3 + 8004324: 0019 movs r1, r3 + 8004326: 2000 movs r0, #0 + 8004328: f000 ff30 bl 800518c + 800432c: 0003 movs r3, r0 + 800432e: 61fb str r3, [r7, #28] + if (out == NULL) goto error; + 8004330: 69fb ldr r3, [r7, #28] + 8004332: 2b00 cmp r3, #0 + 8004334: d100 bne.n 8004338 + 8004336: e102 b.n 800453e + + memcpy(out->payload, p->payload, len); + 8004338: 69fb ldr r3, [r7, #28] + 800433a: 6858 ldr r0, [r3, #4] + 800433c: 687b ldr r3, [r7, #4] + 800433e: 685b ldr r3, [r3, #4] + 8004340: 6a3a ldr r2, [r7, #32] + 8004342: 0019 movs r1, r3 + 8004344: f00b fcad bl 800fca2 + header = (dns_header_t *)out->payload; + 8004348: 69fb ldr r3, [r7, #28] + 800434a: 685b ldr r3, [r3, #4] + 800434c: 627b str r3, [r7, #36] ; 0x24 + header->flags.qr = 1; + 800434e: 6a7b ldr r3, [r7, #36] ; 0x24 + 8004350: 789a ldrb r2, [r3, #2] + 8004352: 2180 movs r1, #128 ; 0x80 + 8004354: 4249 negs r1, r1 + 8004356: 430a orrs r2, r1 + 8004358: 709a strb r2, [r3, #2] + header->n_record[1] = htons(1); + 800435a: 2001 movs r0, #1 + 800435c: f000 f95a bl 8004614 + 8004360: 0003 movs r3, r0 + 8004362: 001a movs r2, r3 + 8004364: 6a7b ldr r3, [r7, #36] ; 0x24 + 8004366: 21ff movs r1, #255 ; 0xff + 8004368: 4011 ands r1, r2 + 800436a: 000c movs r4, r1 + 800436c: 7999 ldrb r1, [r3, #6] + 800436e: 2000 movs r0, #0 + 8004370: 4001 ands r1, r0 + 8004372: 1c08 adds r0, r1, #0 + 8004374: 1c21 adds r1, r4, #0 + 8004376: 4301 orrs r1, r0 + 8004378: 7199 strb r1, [r3, #6] + 800437a: 0a12 lsrs r2, r2, #8 + 800437c: b290 uxth r0, r2 + 800437e: 79da ldrb r2, [r3, #7] + 8004380: 2100 movs r1, #0 + 8004382: 400a ands r2, r1 + 8004384: 1c11 adds r1, r2, #0 + 8004386: 1c02 adds r2, r0, #0 + 8004388: 430a orrs r2, r1 + 800438a: 71da strb r2, [r3, #7] + answer = (struct dns_answer *)((uint8_t *)out->payload + len); + 800438c: 69fb ldr r3, [r7, #28] + 800438e: 685a ldr r2, [r3, #4] + 8004390: 6a3b ldr r3, [r7, #32] + 8004392: 18d3 adds r3, r2, r3 + 8004394: 61bb str r3, [r7, #24] + answer->name = htons(0xC00C); + 8004396: 4b70 ldr r3, [pc, #448] ; (8004558 ) + 8004398: 0018 movs r0, r3 + 800439a: f000 f93b bl 8004614 + 800439e: 0003 movs r3, r0 + 80043a0: 001a movs r2, r3 + 80043a2: 69bb ldr r3, [r7, #24] + 80043a4: 21ff movs r1, #255 ; 0xff + 80043a6: 4011 ands r1, r2 + 80043a8: 000c movs r4, r1 + 80043aa: 7819 ldrb r1, [r3, #0] + 80043ac: 2000 movs r0, #0 + 80043ae: 4001 ands r1, r0 + 80043b0: 1c08 adds r0, r1, #0 + 80043b2: 1c21 adds r1, r4, #0 + 80043b4: 4301 orrs r1, r0 + 80043b6: 7019 strb r1, [r3, #0] + 80043b8: 0a12 lsrs r2, r2, #8 + 80043ba: b290 uxth r0, r2 + 80043bc: 785a ldrb r2, [r3, #1] + 80043be: 2100 movs r1, #0 + 80043c0: 400a ands r2, r1 + 80043c2: 1c11 adds r1, r2, #0 + 80043c4: 1c02 adds r2, r0, #0 + 80043c6: 430a orrs r2, r1 + 80043c8: 705a strb r2, [r3, #1] + answer->type = htons(1); + 80043ca: 2001 movs r0, #1 + 80043cc: f000 f922 bl 8004614 + 80043d0: 0003 movs r3, r0 + 80043d2: 001a movs r2, r3 + 80043d4: 69bb ldr r3, [r7, #24] + 80043d6: 21ff movs r1, #255 ; 0xff + 80043d8: 4011 ands r1, r2 + 80043da: 000c movs r4, r1 + 80043dc: 7899 ldrb r1, [r3, #2] + 80043de: 2000 movs r0, #0 + 80043e0: 4001 ands r1, r0 + 80043e2: 1c08 adds r0, r1, #0 + 80043e4: 1c21 adds r1, r4, #0 + 80043e6: 4301 orrs r1, r0 + 80043e8: 7099 strb r1, [r3, #2] + 80043ea: 0a12 lsrs r2, r2, #8 + 80043ec: b290 uxth r0, r2 + 80043ee: 78da ldrb r2, [r3, #3] + 80043f0: 2100 movs r1, #0 + 80043f2: 400a ands r2, r1 + 80043f4: 1c11 adds r1, r2, #0 + 80043f6: 1c02 adds r2, r0, #0 + 80043f8: 430a orrs r2, r1 + 80043fa: 70da strb r2, [r3, #3] + answer->Class = htons(1); + 80043fc: 2001 movs r0, #1 + 80043fe: f000 f909 bl 8004614 + 8004402: 0003 movs r3, r0 + 8004404: 001a movs r2, r3 + 8004406: 69bb ldr r3, [r7, #24] + 8004408: 21ff movs r1, #255 ; 0xff + 800440a: 4011 ands r1, r2 + 800440c: 000c movs r4, r1 + 800440e: 7919 ldrb r1, [r3, #4] + 8004410: 2000 movs r0, #0 + 8004412: 4001 ands r1, r0 + 8004414: 1c08 adds r0, r1, #0 + 8004416: 1c21 adds r1, r4, #0 + 8004418: 4301 orrs r1, r0 + 800441a: 7119 strb r1, [r3, #4] + 800441c: 0a12 lsrs r2, r2, #8 + 800441e: b290 uxth r0, r2 + 8004420: 795a ldrb r2, [r3, #5] + 8004422: 2100 movs r1, #0 + 8004424: 400a ands r2, r1 + 8004426: 1c11 adds r1, r2, #0 + 8004428: 1c02 adds r2, r0, #0 + 800442a: 430a orrs r2, r1 + 800442c: 715a strb r2, [r3, #5] + answer->ttl = htonl(32); + 800442e: 2020 movs r0, #32 + 8004430: f000 f916 bl 8004660 + 8004434: 0002 movs r2, r0 + 8004436: 69bb ldr r3, [r7, #24] + 8004438: 3306 adds r3, #6 + 800443a: 21ff movs r1, #255 ; 0xff + 800443c: 4011 ands r1, r2 + 800443e: 000c movs r4, r1 + 8004440: 7819 ldrb r1, [r3, #0] + 8004442: 2000 movs r0, #0 + 8004444: 4001 ands r1, r0 + 8004446: 1c08 adds r0, r1, #0 + 8004448: 1c21 adds r1, r4, #0 + 800444a: 4301 orrs r1, r0 + 800444c: 7019 strb r1, [r3, #0] + 800444e: 0a11 lsrs r1, r2, #8 + 8004450: 20ff movs r0, #255 ; 0xff + 8004452: 4001 ands r1, r0 + 8004454: 000c movs r4, r1 + 8004456: 7859 ldrb r1, [r3, #1] + 8004458: 2000 movs r0, #0 + 800445a: 4001 ands r1, r0 + 800445c: 1c08 adds r0, r1, #0 + 800445e: 1c21 adds r1, r4, #0 + 8004460: 4301 orrs r1, r0 + 8004462: 7059 strb r1, [r3, #1] + 8004464: 0c11 lsrs r1, r2, #16 + 8004466: 20ff movs r0, #255 ; 0xff + 8004468: 4001 ands r1, r0 + 800446a: 000c movs r4, r1 + 800446c: 7899 ldrb r1, [r3, #2] + 800446e: 2000 movs r0, #0 + 8004470: 4001 ands r1, r0 + 8004472: 1c08 adds r0, r1, #0 + 8004474: 1c21 adds r1, r4, #0 + 8004476: 4301 orrs r1, r0 + 8004478: 7099 strb r1, [r3, #2] + 800447a: 0e10 lsrs r0, r2, #24 + 800447c: 78da ldrb r2, [r3, #3] + 800447e: 2100 movs r1, #0 + 8004480: 400a ands r2, r1 + 8004482: 1c11 adds r1, r2, #0 + 8004484: 1c02 adds r2, r0, #0 + 8004486: 430a orrs r2, r1 + 8004488: 70da strb r2, [r3, #3] + answer->len = htons(4); + 800448a: 2004 movs r0, #4 + 800448c: f000 f8c2 bl 8004614 + 8004490: 0003 movs r3, r0 + 8004492: 001a movs r2, r3 + 8004494: 69bb ldr r3, [r7, #24] + 8004496: 21ff movs r1, #255 ; 0xff + 8004498: 4011 ands r1, r2 + 800449a: 000c movs r4, r1 + 800449c: 7a99 ldrb r1, [r3, #10] + 800449e: 2000 movs r0, #0 + 80044a0: 4001 ands r1, r0 + 80044a2: 1c08 adds r0, r1, #0 + 80044a4: 1c21 adds r1, r4, #0 + 80044a6: 4301 orrs r1, r0 + 80044a8: 7299 strb r1, [r3, #10] + 80044aa: 0a12 lsrs r2, r2, #8 + 80044ac: b290 uxth r0, r2 + 80044ae: 7ada ldrb r2, [r3, #11] + 80044b0: 2100 movs r1, #0 + 80044b2: 400a ands r2, r1 + 80044b4: 1c11 adds r1, r2, #0 + 80044b6: 1c02 adds r2, r0, #0 + 80044b8: 430a orrs r2, r1 + 80044ba: 72da strb r2, [r3, #11] + answer->addr = host_addr.addr; + 80044bc: 697a ldr r2, [r7, #20] + 80044be: 69bb ldr r3, [r7, #24] + 80044c0: 21ff movs r1, #255 ; 0xff + 80044c2: 4011 ands r1, r2 + 80044c4: 000c movs r4, r1 + 80044c6: 7b19 ldrb r1, [r3, #12] + 80044c8: 2000 movs r0, #0 + 80044ca: 4001 ands r1, r0 + 80044cc: 1c08 adds r0, r1, #0 + 80044ce: 1c21 adds r1, r4, #0 + 80044d0: 4301 orrs r1, r0 + 80044d2: 7319 strb r1, [r3, #12] + 80044d4: 0a11 lsrs r1, r2, #8 + 80044d6: 20ff movs r0, #255 ; 0xff + 80044d8: 4001 ands r1, r0 + 80044da: 000c movs r4, r1 + 80044dc: 7b59 ldrb r1, [r3, #13] + 80044de: 2000 movs r0, #0 + 80044e0: 4001 ands r1, r0 + 80044e2: 1c08 adds r0, r1, #0 + 80044e4: 1c21 adds r1, r4, #0 + 80044e6: 4301 orrs r1, r0 + 80044e8: 7359 strb r1, [r3, #13] + 80044ea: 0c11 lsrs r1, r2, #16 + 80044ec: 20ff movs r0, #255 ; 0xff + 80044ee: 4001 ands r1, r0 + 80044f0: 000c movs r4, r1 + 80044f2: 7b99 ldrb r1, [r3, #14] + 80044f4: 2000 movs r0, #0 + 80044f6: 4001 ands r1, r0 + 80044f8: 1c08 adds r0, r1, #0 + 80044fa: 1c21 adds r1, r4, #0 + 80044fc: 4301 orrs r1, r0 + 80044fe: 7399 strb r1, [r3, #14] + 8004500: 0e10 lsrs r0, r2, #24 + 8004502: 7bda ldrb r2, [r3, #15] + 8004504: 2100 movs r1, #0 + 8004506: 400a ands r2, r1 + 8004508: 1c11 adds r1, r2, #0 + 800450a: 1c02 adds r2, r0, #0 + 800450c: 430a orrs r2, r1 + 800450e: 73da strb r2, [r3, #15] + + udp_sendto(upcb, out, addr, port); + 8004510: 2338 movs r3, #56 ; 0x38 + 8004512: 18fb adds r3, r7, r3 + 8004514: 881b ldrh r3, [r3, #0] + 8004516: 683a ldr r2, [r7, #0] + 8004518: 69f9 ldr r1, [r7, #28] + 800451a: 68b8 ldr r0, [r7, #8] + 800451c: f006 fb66 bl 800abec + pbuf_free(out); + 8004520: 69fb ldr r3, [r7, #28] + 8004522: 0018 movs r0, r3 + 8004524: f001 f8be bl 80056a4 + 8004528: e00a b.n 8004540 + if (p->len <= sizeof(dns_header_t)) goto error; + 800452a: 46c0 nop ; (mov r8, r8) + 800452c: e008 b.n 8004540 + if (header->flags.qr != 0) goto error; + 800452e: 46c0 nop ; (mov r8, r8) + 8004530: e006 b.n 8004540 + if (ntohs(header->n_record[0]) != 1) goto error; + 8004532: 46c0 nop ; (mov r8, r8) + 8004534: e004 b.n 8004540 + if (len < 0) goto error; + 8004536: 46c0 nop ; (mov r8, r8) + 8004538: e002 b.n 8004540 + if (!query_proc(query.name, &host_addr)) goto error; + 800453a: 46c0 nop ; (mov r8, r8) + 800453c: e000 b.n 8004540 + if (out == NULL) goto error; + 800453e: 46c0 nop ; (mov r8, r8) + +error: + pbuf_free(p); + 8004540: 687b ldr r3, [r7, #4] + 8004542: 0018 movs r0, r3 + 8004544: f001 f8ae bl 80056a4 +} + 8004548: 46c0 nop ; (mov r8, r8) + 800454a: 46bd mov sp, r7 + 800454c: b00b add sp, #44 ; 0x2c + 800454e: bd90 pop {r4, r7, pc} + 8004550: 200000c8 .word 0x200000c8 + 8004554: 200000c4 .word 0x200000c4 + 8004558: 0000c00c .word 0x0000c00c + +0800455c : + +err_t dnserv_init(ip_addr_t *bind, uint16_t port, dns_query_proc_t qp) +{ + 800455c: b5b0 push {r4, r5, r7, lr} + 800455e: b086 sub sp, #24 + 8004560: af00 add r7, sp, #0 + 8004562: 60f8 str r0, [r7, #12] + 8004564: 607a str r2, [r7, #4] + 8004566: 230a movs r3, #10 + 8004568: 18fb adds r3, r7, r3 + 800456a: 1c0a adds r2, r1, #0 + 800456c: 801a strh r2, [r3, #0] + err_t err; + udp_init(); + 800456e: f006 f95b bl 800a828 + dnserv_free(); + 8004572: f000 f83b bl 80045ec + pcb = udp_new(); + 8004576: f006 fd35 bl 800afe4 + 800457a: 0002 movs r2, r0 + 800457c: 4b18 ldr r3, [pc, #96] ; (80045e0 ) + 800457e: 601a str r2, [r3, #0] + if (pcb == NULL) + 8004580: 4b17 ldr r3, [pc, #92] ; (80045e0 ) + 8004582: 681b ldr r3, [r3, #0] + 8004584: 2b00 cmp r3, #0 + 8004586: d102 bne.n 800458e + return ERR_MEM; + 8004588: 2301 movs r3, #1 + 800458a: 425b negs r3, r3 + 800458c: e023 b.n 80045d6 + err = udp_bind(pcb, bind, port); + 800458e: 4b14 ldr r3, [pc, #80] ; (80045e0 ) + 8004590: 6818 ldr r0, [r3, #0] + 8004592: 2517 movs r5, #23 + 8004594: 197c adds r4, r7, r5 + 8004596: 230a movs r3, #10 + 8004598: 18fb adds r3, r7, r3 + 800459a: 881a ldrh r2, [r3, #0] + 800459c: 68fb ldr r3, [r7, #12] + 800459e: 0019 movs r1, r3 + 80045a0: f006 fc72 bl 800ae88 + 80045a4: 0003 movs r3, r0 + 80045a6: 7023 strb r3, [r4, #0] + if (err != ERR_OK) + 80045a8: 197b adds r3, r7, r5 + 80045aa: 781b ldrb r3, [r3, #0] + 80045ac: b25b sxtb r3, r3 + 80045ae: 2b00 cmp r3, #0 + 80045b0: d006 beq.n 80045c0 + { + dnserv_free(); + 80045b2: f000 f81b bl 80045ec + return err; + 80045b6: 2317 movs r3, #23 + 80045b8: 18fb adds r3, r7, r3 + 80045ba: 781b ldrb r3, [r3, #0] + 80045bc: b25b sxtb r3, r3 + 80045be: e00a b.n 80045d6 + } + udp_recv(pcb, udp_recv_proc, NULL); + 80045c0: 4b07 ldr r3, [pc, #28] ; (80045e0 ) + 80045c2: 681b ldr r3, [r3, #0] + 80045c4: 4907 ldr r1, [pc, #28] ; (80045e4 ) + 80045c6: 2200 movs r2, #0 + 80045c8: 0018 movs r0, r3 + 80045ca: f006 fcc9 bl 800af60 + query_proc = qp; + 80045ce: 4b06 ldr r3, [pc, #24] ; (80045e8 ) + 80045d0: 687a ldr r2, [r7, #4] + 80045d2: 601a str r2, [r3, #0] + return ERR_OK; + 80045d4: 2300 movs r3, #0 +} + 80045d6: 0018 movs r0, r3 + 80045d8: 46bd mov sp, r7 + 80045da: b006 add sp, #24 + 80045dc: bdb0 pop {r4, r5, r7, pc} + 80045de: 46c0 nop ; (mov r8, r8) + 80045e0: 200000c0 .word 0x200000c0 + 80045e4: 0800428d .word 0x0800428d + 80045e8: 200000c4 .word 0x200000c4 + +080045ec : + +void dnserv_free() +{ + 80045ec: b580 push {r7, lr} + 80045ee: af00 add r7, sp, #0 + if (pcb == NULL) return; + 80045f0: 4b07 ldr r3, [pc, #28] ; (8004610 ) + 80045f2: 681b ldr r3, [r3, #0] + 80045f4: 2b00 cmp r3, #0 + 80045f6: d008 beq.n 800460a + udp_remove(pcb); + 80045f8: 4b05 ldr r3, [pc, #20] ; (8004610 ) + 80045fa: 681b ldr r3, [r3, #0] + 80045fc: 0018 movs r0, r3 + 80045fe: f006 fcbf bl 800af80 + pcb = NULL; + 8004602: 4b03 ldr r3, [pc, #12] ; (8004610 ) + 8004604: 2200 movs r2, #0 + 8004606: 601a str r2, [r3, #0] + 8004608: e000 b.n 800460c + if (pcb == NULL) return; + 800460a: 46c0 nop ; (mov r8, r8) +} + 800460c: 46bd mov sp, r7 + 800460e: bd80 pop {r7, pc} + 8004610: 200000c0 .word 0x200000c0 + +08004614 : + * @param n u16_t in host byte order + * @return n in network byte order + */ +u16_t +lwip_htons(u16_t n) +{ + 8004614: b580 push {r7, lr} + 8004616: b082 sub sp, #8 + 8004618: af00 add r7, sp, #0 + 800461a: 0002 movs r2, r0 + 800461c: 1dbb adds r3, r7, #6 + 800461e: 801a strh r2, [r3, #0] + return ((n & 0xff) << 8) | ((n & 0xff00) >> 8); + 8004620: 1dbb adds r3, r7, #6 + 8004622: 881b ldrh r3, [r3, #0] + 8004624: 021b lsls r3, r3, #8 + 8004626: b21a sxth r2, r3 + 8004628: 1dbb adds r3, r7, #6 + 800462a: 881b ldrh r3, [r3, #0] + 800462c: 0a1b lsrs r3, r3, #8 + 800462e: b29b uxth r3, r3 + 8004630: b21b sxth r3, r3 + 8004632: 4313 orrs r3, r2 + 8004634: b21b sxth r3, r3 + 8004636: b29b uxth r3, r3 +} + 8004638: 0018 movs r0, r3 + 800463a: 46bd mov sp, r7 + 800463c: b002 add sp, #8 + 800463e: bd80 pop {r7, pc} + +08004640 : + * @param n u16_t in network byte order + * @return n in host byte order + */ +u16_t +lwip_ntohs(u16_t n) +{ + 8004640: b580 push {r7, lr} + 8004642: b082 sub sp, #8 + 8004644: af00 add r7, sp, #0 + 8004646: 0002 movs r2, r0 + 8004648: 1dbb adds r3, r7, #6 + 800464a: 801a strh r2, [r3, #0] + return lwip_htons(n); + 800464c: 1dbb adds r3, r7, #6 + 800464e: 881b ldrh r3, [r3, #0] + 8004650: 0018 movs r0, r3 + 8004652: f7ff ffdf bl 8004614 + 8004656: 0003 movs r3, r0 +} + 8004658: 0018 movs r0, r3 + 800465a: 46bd mov sp, r7 + 800465c: b002 add sp, #8 + 800465e: bd80 pop {r7, pc} + +08004660 : + * @param n u32_t in host byte order + * @return n in network byte order + */ +u32_t +lwip_htonl(u32_t n) +{ + 8004660: b580 push {r7, lr} + 8004662: b082 sub sp, #8 + 8004664: af00 add r7, sp, #0 + 8004666: 6078 str r0, [r7, #4] + return ((n & 0xff) << 24) | + 8004668: 687b ldr r3, [r7, #4] + 800466a: 061a lsls r2, r3, #24 + ((n & 0xff00) << 8) | + 800466c: 687b ldr r3, [r7, #4] + 800466e: 0219 lsls r1, r3, #8 + 8004670: 23ff movs r3, #255 ; 0xff + 8004672: 041b lsls r3, r3, #16 + 8004674: 400b ands r3, r1 + return ((n & 0xff) << 24) | + 8004676: 431a orrs r2, r3 + ((n & 0xff0000UL) >> 8) | + 8004678: 687b ldr r3, [r7, #4] + 800467a: 0a19 lsrs r1, r3, #8 + 800467c: 23ff movs r3, #255 ; 0xff + 800467e: 021b lsls r3, r3, #8 + 8004680: 400b ands r3, r1 + ((n & 0xff00) << 8) | + 8004682: 431a orrs r2, r3 + ((n & 0xff000000UL) >> 24); + 8004684: 687b ldr r3, [r7, #4] + 8004686: 0e1b lsrs r3, r3, #24 + ((n & 0xff0000UL) >> 8) | + 8004688: 4313 orrs r3, r2 +} + 800468a: 0018 movs r0, r3 + 800468c: 46bd mov sp, r7 + 800468e: b002 add sp, #8 + 8004690: bd80 pop {r7, pc} + +08004692 : + * @param n u32_t in network byte order + * @return n in host byte order + */ +u32_t +lwip_ntohl(u32_t n) +{ + 8004692: b580 push {r7, lr} + 8004694: b082 sub sp, #8 + 8004696: af00 add r7, sp, #0 + 8004698: 6078 str r0, [r7, #4] + return lwip_htonl(n); + 800469a: 687b ldr r3, [r7, #4] + 800469c: 0018 movs r0, r3 + 800469e: f7ff ffdf bl 8004660 + 80046a2: 0003 movs r3, r0 +} + 80046a4: 0018 movs r0, r3 + 80046a6: 46bd mov sp, r7 + 80046a8: b002 add sp, #8 + 80046aa: bd80 pop {r7, pc} + +080046ac : +/** + * Perform Sanity check of user-configurable values, and initialize all modules. + */ +void +lwip_init(void) +{ + 80046ac: b580 push {r7, lr} + 80046ae: af00 add r7, sp, #0 + /* Modules initialization */ + stats_init(); + 80046b0: f001 fa76 bl 8005ba0 +#if !NO_SYS + sys_init(); +#endif /* !NO_SYS */ + mem_init(); + 80046b4: f000 f86c bl 8004790 + memp_init(); + 80046b8: f000 fb18 bl 8004cec + pbuf_init(); + netif_init(); + 80046bc: f000 fc6a bl 8004f94 +#endif /* LWIP_ARP */ +#if LWIP_RAW + raw_init(); +#endif /* LWIP_RAW */ +#if LWIP_UDP + udp_init(); + 80046c0: f006 f8b2 bl 800a828 +#endif /* LWIP_UDP */ +#if LWIP_TCP + tcp_init(); + 80046c4: f001 fa71 bl 8005baa +#if LWIP_DNS + dns_init(); +#endif /* LWIP_DNS */ + +#if LWIP_TIMERS + sys_timeouts_init(); + 80046c8: f006 f81e bl 800a708 +#endif /* LWIP_TIMERS */ +} + 80046cc: 46c0 nop ; (mov r8, r8) + 80046ce: 46bd mov sp, r7 + 80046d0: bd80 pop {r7, pc} + ... + +080046d4 : + * This assumes access to the heap is protected by the calling function + * already. + */ +static void +plug_holes(struct mem *mem) +{ + 80046d4: b580 push {r7, lr} + 80046d6: b084 sub sp, #16 + 80046d8: af00 add r7, sp, #0 + 80046da: 6078 str r0, [r7, #4] + LWIP_ASSERT("plug_holes: mem->used == 0", mem->used == 0); + + /* plug hole forward */ + LWIP_ASSERT("plug_holes: mem->next <= MEM_SIZE_ALIGNED", mem->next <= MEM_SIZE_ALIGNED); + + nmem = (struct mem *)(void *)&ram[mem->next]; + 80046dc: 4b29 ldr r3, [pc, #164] ; (8004784 ) + 80046de: 681b ldr r3, [r3, #0] + 80046e0: 687a ldr r2, [r7, #4] + 80046e2: 8812 ldrh r2, [r2, #0] + 80046e4: 189b adds r3, r3, r2 + 80046e6: 60fb str r3, [r7, #12] + if (mem != nmem && nmem->used == 0 && (u8_t *)nmem != (u8_t *)ram_end) { + 80046e8: 687a ldr r2, [r7, #4] + 80046ea: 68fb ldr r3, [r7, #12] + 80046ec: 429a cmp r2, r3 + 80046ee: d01f beq.n 8004730 + 80046f0: 68fb ldr r3, [r7, #12] + 80046f2: 791b ldrb r3, [r3, #4] + 80046f4: 2b00 cmp r3, #0 + 80046f6: d11b bne.n 8004730 + 80046f8: 4b23 ldr r3, [pc, #140] ; (8004788 ) + 80046fa: 681b ldr r3, [r3, #0] + 80046fc: 68fa ldr r2, [r7, #12] + 80046fe: 429a cmp r2, r3 + 8004700: d016 beq.n 8004730 + /* if mem->next is unused and not end of ram, combine mem and mem->next */ + if (lfree == nmem) { + 8004702: 4b22 ldr r3, [pc, #136] ; (800478c ) + 8004704: 681b ldr r3, [r3, #0] + 8004706: 68fa ldr r2, [r7, #12] + 8004708: 429a cmp r2, r3 + 800470a: d102 bne.n 8004712 + lfree = mem; + 800470c: 4b1f ldr r3, [pc, #124] ; (800478c ) + 800470e: 687a ldr r2, [r7, #4] + 8004710: 601a str r2, [r3, #0] + } + mem->next = nmem->next; + 8004712: 68fb ldr r3, [r7, #12] + 8004714: 881a ldrh r2, [r3, #0] + 8004716: 687b ldr r3, [r7, #4] + 8004718: 801a strh r2, [r3, #0] + ((struct mem *)(void *)&ram[nmem->next])->prev = (mem_size_t)((u8_t *)mem - ram); + 800471a: 687a ldr r2, [r7, #4] + 800471c: 4b19 ldr r3, [pc, #100] ; (8004784 ) + 800471e: 681b ldr r3, [r3, #0] + 8004720: 1ad1 subs r1, r2, r3 + 8004722: 4b18 ldr r3, [pc, #96] ; (8004784 ) + 8004724: 681b ldr r3, [r3, #0] + 8004726: 68fa ldr r2, [r7, #12] + 8004728: 8812 ldrh r2, [r2, #0] + 800472a: 189b adds r3, r3, r2 + 800472c: b28a uxth r2, r1 + 800472e: 805a strh r2, [r3, #2] + } + + /* plug hole backward */ + pmem = (struct mem *)(void *)&ram[mem->prev]; + 8004730: 4b14 ldr r3, [pc, #80] ; (8004784 ) + 8004732: 681b ldr r3, [r3, #0] + 8004734: 687a ldr r2, [r7, #4] + 8004736: 8852 ldrh r2, [r2, #2] + 8004738: 189b adds r3, r3, r2 + 800473a: 60bb str r3, [r7, #8] + if (pmem != mem && pmem->used == 0) { + 800473c: 68ba ldr r2, [r7, #8] + 800473e: 687b ldr r3, [r7, #4] + 8004740: 429a cmp r2, r3 + 8004742: d01a beq.n 800477a + 8004744: 68bb ldr r3, [r7, #8] + 8004746: 791b ldrb r3, [r3, #4] + 8004748: 2b00 cmp r3, #0 + 800474a: d116 bne.n 800477a + /* if mem->prev is unused, combine mem and mem->prev */ + if (lfree == mem) { + 800474c: 4b0f ldr r3, [pc, #60] ; (800478c ) + 800474e: 681b ldr r3, [r3, #0] + 8004750: 687a ldr r2, [r7, #4] + 8004752: 429a cmp r2, r3 + 8004754: d102 bne.n 800475c + lfree = pmem; + 8004756: 4b0d ldr r3, [pc, #52] ; (800478c ) + 8004758: 68ba ldr r2, [r7, #8] + 800475a: 601a str r2, [r3, #0] + } + pmem->next = mem->next; + 800475c: 687b ldr r3, [r7, #4] + 800475e: 881a ldrh r2, [r3, #0] + 8004760: 68bb ldr r3, [r7, #8] + 8004762: 801a strh r2, [r3, #0] + ((struct mem *)(void *)&ram[mem->next])->prev = (mem_size_t)((u8_t *)pmem - ram); + 8004764: 68ba ldr r2, [r7, #8] + 8004766: 4b07 ldr r3, [pc, #28] ; (8004784 ) + 8004768: 681b ldr r3, [r3, #0] + 800476a: 1ad1 subs r1, r2, r3 + 800476c: 4b05 ldr r3, [pc, #20] ; (8004784 ) + 800476e: 681b ldr r3, [r3, #0] + 8004770: 687a ldr r2, [r7, #4] + 8004772: 8812 ldrh r2, [r2, #0] + 8004774: 189b adds r3, r3, r2 + 8004776: b28a uxth r2, r1 + 8004778: 805a strh r2, [r3, #2] + } +} + 800477a: 46c0 nop ; (mov r8, r8) + 800477c: 46bd mov sp, r7 + 800477e: b004 add sp, #16 + 8004780: bd80 pop {r7, pc} + 8004782: 46c0 nop ; (mov r8, r8) + 8004784: 2000014c .word 0x2000014c + 8004788: 20000150 .word 0x20000150 + 800478c: 20000154 .word 0x20000154 + +08004790 : +/** + * Zero the heap and initialize start, end and lowest-free + */ +void +mem_init(void) +{ + 8004790: b580 push {r7, lr} + 8004792: b082 sub sp, #8 + 8004794: af00 add r7, sp, #0 + + LWIP_ASSERT("Sanity check alignment", + (SIZEOF_STRUCT_MEM & (MEM_ALIGNMENT-1)) == 0); + + /* align the heap */ + ram = (u8_t *)LWIP_MEM_ALIGN(LWIP_RAM_HEAP_POINTER); + 8004796: 4b1b ldr r3, [pc, #108] ; (8004804 ) + 8004798: 3303 adds r3, #3 + 800479a: 2203 movs r2, #3 + 800479c: 4393 bics r3, r2 + 800479e: 001a movs r2, r3 + 80047a0: 4b19 ldr r3, [pc, #100] ; (8004808 ) + 80047a2: 601a str r2, [r3, #0] + /* initialize the start of the heap */ + mem = (struct mem *)(void *)ram; + 80047a4: 4b18 ldr r3, [pc, #96] ; (8004808 ) + 80047a6: 681b ldr r3, [r3, #0] + 80047a8: 607b str r3, [r7, #4] + mem->next = MEM_SIZE_ALIGNED; + 80047aa: 687b ldr r3, [r7, #4] + 80047ac: 22c8 movs r2, #200 ; 0xc8 + 80047ae: 00d2 lsls r2, r2, #3 + 80047b0: 801a strh r2, [r3, #0] + mem->prev = 0; + 80047b2: 687b ldr r3, [r7, #4] + 80047b4: 2200 movs r2, #0 + 80047b6: 805a strh r2, [r3, #2] + mem->used = 0; + 80047b8: 687b ldr r3, [r7, #4] + 80047ba: 2200 movs r2, #0 + 80047bc: 711a strb r2, [r3, #4] + /* initialize the end of the heap */ + ram_end = (struct mem *)(void *)&ram[MEM_SIZE_ALIGNED]; + 80047be: 4b12 ldr r3, [pc, #72] ; (8004808 ) + 80047c0: 681b ldr r3, [r3, #0] + 80047c2: 22c8 movs r2, #200 ; 0xc8 + 80047c4: 00d2 lsls r2, r2, #3 + 80047c6: 189a adds r2, r3, r2 + 80047c8: 4b10 ldr r3, [pc, #64] ; (800480c ) + 80047ca: 601a str r2, [r3, #0] + ram_end->used = 1; + 80047cc: 4b0f ldr r3, [pc, #60] ; (800480c ) + 80047ce: 681b ldr r3, [r3, #0] + 80047d0: 2201 movs r2, #1 + 80047d2: 711a strb r2, [r3, #4] + ram_end->next = MEM_SIZE_ALIGNED; + 80047d4: 4b0d ldr r3, [pc, #52] ; (800480c ) + 80047d6: 681b ldr r3, [r3, #0] + 80047d8: 22c8 movs r2, #200 ; 0xc8 + 80047da: 00d2 lsls r2, r2, #3 + 80047dc: 801a strh r2, [r3, #0] + ram_end->prev = MEM_SIZE_ALIGNED; + 80047de: 4b0b ldr r3, [pc, #44] ; (800480c ) + 80047e0: 681b ldr r3, [r3, #0] + 80047e2: 22c8 movs r2, #200 ; 0xc8 + 80047e4: 00d2 lsls r2, r2, #3 + 80047e6: 805a strh r2, [r3, #2] + + /* initialize the lowest-free pointer to the start of the heap */ + lfree = (struct mem *)(void *)ram; + 80047e8: 4b07 ldr r3, [pc, #28] ; (8004808 ) + 80047ea: 681a ldr r2, [r3, #0] + 80047ec: 4b08 ldr r3, [pc, #32] ; (8004810 ) + 80047ee: 601a str r2, [r3, #0] + + MEM_STATS_AVAIL(avail, MEM_SIZE_ALIGNED); + 80047f0: 4b08 ldr r3, [pc, #32] ; (8004814 ) + 80047f2: 22a8 movs r2, #168 ; 0xa8 + 80047f4: 21c8 movs r1, #200 ; 0xc8 + 80047f6: 00c9 lsls r1, r1, #3 + 80047f8: 5299 strh r1, [r3, r2] + + if(sys_mutex_new(&mem_mutex) != ERR_OK) { + LWIP_ASSERT("failed to create mem_mutex", 0); + } +} + 80047fa: 46c0 nop ; (mov r8, r8) + 80047fc: 46bd mov sp, r7 + 80047fe: b002 add sp, #8 + 8004800: bd80 pop {r7, pc} + 8004802: 46c0 nop ; (mov r8, r8) + 8004804: 20002af8 .word 0x20002af8 + 8004808: 2000014c .word 0x2000014c + 800480c: 20000150 .word 0x20000150 + 8004810: 20000154 .word 0x20000154 + 8004814: 20003158 .word 0x20003158 + +08004818 : + * @param rmem is the data portion of a struct mem as returned by a previous + * call to mem_malloc() + */ +void +mem_free(void *rmem) +{ + 8004818: b580 push {r7, lr} + 800481a: b084 sub sp, #16 + 800481c: af00 add r7, sp, #0 + 800481e: 6078 str r0, [r7, #4] + struct mem *mem; + LWIP_MEM_FREE_DECL_PROTECT(); + + if (rmem == NULL) { + 8004820: 687b ldr r3, [r7, #4] + 8004822: 2b00 cmp r3, #0 + 8004824: d036 beq.n 8004894 + LWIP_ASSERT("mem_free: sanity check alignment", (((mem_ptr_t)rmem) & (MEM_ALIGNMENT-1)) == 0); + + LWIP_ASSERT("mem_free: legal memory", (u8_t *)rmem >= (u8_t *)ram && + (u8_t *)rmem < (u8_t *)ram_end); + + if ((u8_t *)rmem < (u8_t *)ram || (u8_t *)rmem >= (u8_t *)ram_end) { + 8004826: 4b1d ldr r3, [pc, #116] ; (800489c ) + 8004828: 681b ldr r3, [r3, #0] + 800482a: 687a ldr r2, [r7, #4] + 800482c: 429a cmp r2, r3 + 800482e: d304 bcc.n 800483a + 8004830: 4b1b ldr r3, [pc, #108] ; (80048a0 ) + 8004832: 681b ldr r3, [r3, #0] + 8004834: 687a ldr r2, [r7, #4] + 8004836: 429a cmp r2, r3 + 8004838: d308 bcc.n 800484c + SYS_ARCH_DECL_PROTECT(lev); + LWIP_DEBUGF(MEM_DEBUG | LWIP_DBG_LEVEL_SEVERE, ("mem_free: illegal memory\n")); + /* protect mem stats from concurrent access */ + SYS_ARCH_PROTECT(lev); + MEM_STATS_INC(illegal); + 800483a: 4b1a ldr r3, [pc, #104] ; (80048a4 ) + 800483c: 22b0 movs r2, #176 ; 0xb0 + 800483e: 5a9b ldrh r3, [r3, r2] + 8004840: 3301 adds r3, #1 + 8004842: b299 uxth r1, r3 + 8004844: 4b17 ldr r3, [pc, #92] ; (80048a4 ) + 8004846: 22b0 movs r2, #176 ; 0xb0 + 8004848: 5299 strh r1, [r3, r2] + SYS_ARCH_UNPROTECT(lev); + return; + 800484a: e024 b.n 8004896 + } + /* protect the heap from concurrent access */ + LWIP_MEM_FREE_PROTECT(); + /* Get the corresponding struct mem ... */ + mem = (struct mem *)(void *)((u8_t *)rmem - SIZEOF_STRUCT_MEM); + 800484c: 687b ldr r3, [r7, #4] + 800484e: 3b08 subs r3, #8 + 8004850: 60fb str r3, [r7, #12] + /* ... which has to be in a used state ... */ + LWIP_ASSERT("mem_free: mem->used", mem->used); + /* ... and is now unused. */ + mem->used = 0; + 8004852: 68fb ldr r3, [r7, #12] + 8004854: 2200 movs r2, #0 + 8004856: 711a strb r2, [r3, #4] + + if (mem < lfree) { + 8004858: 4b13 ldr r3, [pc, #76] ; (80048a8 ) + 800485a: 681b ldr r3, [r3, #0] + 800485c: 68fa ldr r2, [r7, #12] + 800485e: 429a cmp r2, r3 + 8004860: d202 bcs.n 8004868 + /* the newly freed struct is now the lowest */ + lfree = mem; + 8004862: 4b11 ldr r3, [pc, #68] ; (80048a8 ) + 8004864: 68fa ldr r2, [r7, #12] + 8004866: 601a str r2, [r3, #0] + } + + MEM_STATS_DEC_USED(used, mem->next - (mem_size_t)(((u8_t *)mem - ram))); + 8004868: 4b0e ldr r3, [pc, #56] ; (80048a4 ) + 800486a: 22aa movs r2, #170 ; 0xaa + 800486c: 5a9a ldrh r2, [r3, r2] + 800486e: 68f9 ldr r1, [r7, #12] + 8004870: 4b0a ldr r3, [pc, #40] ; (800489c ) + 8004872: 681b ldr r3, [r3, #0] + 8004874: 1acb subs r3, r1, r3 + 8004876: b299 uxth r1, r3 + 8004878: 68fb ldr r3, [r7, #12] + 800487a: 881b ldrh r3, [r3, #0] + 800487c: 1acb subs r3, r1, r3 + 800487e: b29b uxth r3, r3 + 8004880: 18d3 adds r3, r2, r3 + 8004882: b299 uxth r1, r3 + 8004884: 4b07 ldr r3, [pc, #28] ; (80048a4 ) + 8004886: 22aa movs r2, #170 ; 0xaa + 8004888: 5299 strh r1, [r3, r2] + + /* finally, see if prev or next are free also */ + plug_holes(mem); + 800488a: 68fb ldr r3, [r7, #12] + 800488c: 0018 movs r0, r3 + 800488e: f7ff ff21 bl 80046d4 + 8004892: e000 b.n 8004896 + return; + 8004894: 46c0 nop ; (mov r8, r8) +#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT + mem_free_count = 1; +#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */ + LWIP_MEM_FREE_UNPROTECT(); +} + 8004896: 46bd mov sp, r7 + 8004898: b004 add sp, #16 + 800489a: bd80 pop {r7, pc} + 800489c: 2000014c .word 0x2000014c + 80048a0: 20000150 .word 0x20000150 + 80048a4: 20003158 .word 0x20003158 + 80048a8: 20000154 .word 0x20000154 + +080048ac : + * or NULL if newsize is > old size, in which case rmem is NOT touched + * or freed! + */ +void * +mem_trim(void *rmem, mem_size_t newsize) +{ + 80048ac: b580 push {r7, lr} + 80048ae: b086 sub sp, #24 + 80048b0: af00 add r7, sp, #0 + 80048b2: 6078 str r0, [r7, #4] + 80048b4: 000a movs r2, r1 + 80048b6: 1cbb adds r3, r7, #2 + 80048b8: 801a strh r2, [r3, #0] + /* use the FREE_PROTECT here: it protects with sem OR SYS_ARCH_PROTECT */ + LWIP_MEM_FREE_DECL_PROTECT(); + + /* Expand the size of the allocated memory region so that we can + adjust for alignment. */ + newsize = LWIP_MEM_ALIGN_SIZE(newsize); + 80048ba: 1cbb adds r3, r7, #2 + 80048bc: 881b ldrh r3, [r3, #0] + 80048be: 3303 adds r3, #3 + 80048c0: b29a uxth r2, r3 + 80048c2: 1cbb adds r3, r7, #2 + 80048c4: 2103 movs r1, #3 + 80048c6: 438a bics r2, r1 + 80048c8: 801a strh r2, [r3, #0] + + if(newsize < MIN_SIZE_ALIGNED) { + 80048ca: 1cbb adds r3, r7, #2 + 80048cc: 881b ldrh r3, [r3, #0] + 80048ce: 2b0b cmp r3, #11 + 80048d0: d802 bhi.n 80048d8 + /* every data block must be at least MIN_SIZE_ALIGNED long */ + newsize = MIN_SIZE_ALIGNED; + 80048d2: 1cbb adds r3, r7, #2 + 80048d4: 220c movs r2, #12 + 80048d6: 801a strh r2, [r3, #0] + } + + if (newsize > MEM_SIZE_ALIGNED) { + 80048d8: 1cbb adds r3, r7, #2 + 80048da: 881a ldrh r2, [r3, #0] + 80048dc: 23c8 movs r3, #200 ; 0xc8 + 80048de: 00db lsls r3, r3, #3 + 80048e0: 429a cmp r2, r3 + 80048e2: d901 bls.n 80048e8 + return NULL; + 80048e4: 2300 movs r3, #0 + 80048e6: e0e8 b.n 8004aba + } + + LWIP_ASSERT("mem_trim: legal memory", (u8_t *)rmem >= (u8_t *)ram && + (u8_t *)rmem < (u8_t *)ram_end); + + if ((u8_t *)rmem < (u8_t *)ram || (u8_t *)rmem >= (u8_t *)ram_end) { + 80048e8: 4b76 ldr r3, [pc, #472] ; (8004ac4 ) + 80048ea: 681b ldr r3, [r3, #0] + 80048ec: 687a ldr r2, [r7, #4] + 80048ee: 429a cmp r2, r3 + 80048f0: d304 bcc.n 80048fc + 80048f2: 4b75 ldr r3, [pc, #468] ; (8004ac8 ) + 80048f4: 681b ldr r3, [r3, #0] + 80048f6: 687a ldr r2, [r7, #4] + 80048f8: 429a cmp r2, r3 + 80048fa: d309 bcc.n 8004910 + SYS_ARCH_DECL_PROTECT(lev); + LWIP_DEBUGF(MEM_DEBUG | LWIP_DBG_LEVEL_SEVERE, ("mem_trim: illegal memory\n")); + /* protect mem stats from concurrent access */ + SYS_ARCH_PROTECT(lev); + MEM_STATS_INC(illegal); + 80048fc: 4b73 ldr r3, [pc, #460] ; (8004acc ) + 80048fe: 22b0 movs r2, #176 ; 0xb0 + 8004900: 5a9b ldrh r3, [r3, r2] + 8004902: 3301 adds r3, #1 + 8004904: b299 uxth r1, r3 + 8004906: 4b71 ldr r3, [pc, #452] ; (8004acc ) + 8004908: 22b0 movs r2, #176 ; 0xb0 + 800490a: 5299 strh r1, [r3, r2] + SYS_ARCH_UNPROTECT(lev); + return rmem; + 800490c: 687b ldr r3, [r7, #4] + 800490e: e0d4 b.n 8004aba + } + /* Get the corresponding struct mem ... */ + mem = (struct mem *)(void *)((u8_t *)rmem - SIZEOF_STRUCT_MEM); + 8004910: 687b ldr r3, [r7, #4] + 8004912: 3b08 subs r3, #8 + 8004914: 617b str r3, [r7, #20] + /* ... and its offset pointer */ + ptr = (mem_size_t)((u8_t *)mem - ram); + 8004916: 697a ldr r2, [r7, #20] + 8004918: 4b6a ldr r3, [pc, #424] ; (8004ac4 ) + 800491a: 681b ldr r3, [r3, #0] + 800491c: 1ad2 subs r2, r2, r3 + 800491e: 2112 movs r1, #18 + 8004920: 187b adds r3, r7, r1 + 8004922: 801a strh r2, [r3, #0] + + size = mem->next - ptr - SIZEOF_STRUCT_MEM; + 8004924: 697b ldr r3, [r7, #20] + 8004926: 881a ldrh r2, [r3, #0] + 8004928: 187b adds r3, r7, r1 + 800492a: 881b ldrh r3, [r3, #0] + 800492c: 1ad3 subs r3, r2, r3 + 800492e: b29a uxth r2, r3 + 8004930: 2110 movs r1, #16 + 8004932: 187b adds r3, r7, r1 + 8004934: 3a08 subs r2, #8 + 8004936: 801a strh r2, [r3, #0] + LWIP_ASSERT("mem_trim can only shrink memory", newsize <= size); + if (newsize > size) { + 8004938: 1cba adds r2, r7, #2 + 800493a: 187b adds r3, r7, r1 + 800493c: 8812 ldrh r2, [r2, #0] + 800493e: 881b ldrh r3, [r3, #0] + 8004940: 429a cmp r2, r3 + 8004942: d901 bls.n 8004948 + /* not supported */ + return NULL; + 8004944: 2300 movs r3, #0 + 8004946: e0b8 b.n 8004aba + } + if (newsize == size) { + 8004948: 1cba adds r2, r7, #2 + 800494a: 2310 movs r3, #16 + 800494c: 18fb adds r3, r7, r3 + 800494e: 8812 ldrh r2, [r2, #0] + 8004950: 881b ldrh r3, [r3, #0] + 8004952: 429a cmp r2, r3 + 8004954: d101 bne.n 800495a + /* No change in size, simply return */ + return rmem; + 8004956: 687b ldr r3, [r7, #4] + 8004958: e0af b.n 8004aba + } + + /* protect the heap from concurrent access */ + LWIP_MEM_FREE_PROTECT(); + + mem2 = (struct mem *)(void *)&ram[mem->next]; + 800495a: 4b5a ldr r3, [pc, #360] ; (8004ac4 ) + 800495c: 681b ldr r3, [r3, #0] + 800495e: 697a ldr r2, [r7, #20] + 8004960: 8812 ldrh r2, [r2, #0] + 8004962: 189b adds r3, r3, r2 + 8004964: 60fb str r3, [r7, #12] + if(mem2->used == 0) { + 8004966: 68fb ldr r3, [r7, #12] + 8004968: 791b ldrb r3, [r3, #4] + 800496a: 2b00 cmp r3, #0 + 800496c: d153 bne.n 8004a16 + /* The next struct is unused, we can simply move it at little */ + mem_size_t next; + /* remember the old next pointer */ + next = mem2->next; + 800496e: 2308 movs r3, #8 + 8004970: 18fb adds r3, r7, r3 + 8004972: 68fa ldr r2, [r7, #12] + 8004974: 8812 ldrh r2, [r2, #0] + 8004976: 801a strh r2, [r3, #0] + /* create new struct mem which is moved directly after the shrinked mem */ + ptr2 = ptr + SIZEOF_STRUCT_MEM + newsize; + 8004978: 2312 movs r3, #18 + 800497a: 18fa adds r2, r7, r3 + 800497c: 1cbb adds r3, r7, #2 + 800497e: 8812 ldrh r2, [r2, #0] + 8004980: 881b ldrh r3, [r3, #0] + 8004982: 18d3 adds r3, r2, r3 + 8004984: b29a uxth r2, r3 + 8004986: 230a movs r3, #10 + 8004988: 18fb adds r3, r7, r3 + 800498a: 3208 adds r2, #8 + 800498c: 801a strh r2, [r3, #0] + if (lfree == mem2) { + 800498e: 4b50 ldr r3, [pc, #320] ; (8004ad0 ) + 8004990: 681b ldr r3, [r3, #0] + 8004992: 68fa ldr r2, [r7, #12] + 8004994: 429a cmp r2, r3 + 8004996: d107 bne.n 80049a8 + lfree = (struct mem *)(void *)&ram[ptr2]; + 8004998: 4b4a ldr r3, [pc, #296] ; (8004ac4 ) + 800499a: 681a ldr r2, [r3, #0] + 800499c: 230a movs r3, #10 + 800499e: 18fb adds r3, r7, r3 + 80049a0: 881b ldrh r3, [r3, #0] + 80049a2: 18d2 adds r2, r2, r3 + 80049a4: 4b4a ldr r3, [pc, #296] ; (8004ad0 ) + 80049a6: 601a str r2, [r3, #0] + } + mem2 = (struct mem *)(void *)&ram[ptr2]; + 80049a8: 4b46 ldr r3, [pc, #280] ; (8004ac4 ) + 80049aa: 681a ldr r2, [r3, #0] + 80049ac: 210a movs r1, #10 + 80049ae: 187b adds r3, r7, r1 + 80049b0: 881b ldrh r3, [r3, #0] + 80049b2: 18d3 adds r3, r2, r3 + 80049b4: 60fb str r3, [r7, #12] + mem2->used = 0; + 80049b6: 68fb ldr r3, [r7, #12] + 80049b8: 2200 movs r2, #0 + 80049ba: 711a strb r2, [r3, #4] + /* restore the next pointer */ + mem2->next = next; + 80049bc: 68fb ldr r3, [r7, #12] + 80049be: 2208 movs r2, #8 + 80049c0: 18ba adds r2, r7, r2 + 80049c2: 8812 ldrh r2, [r2, #0] + 80049c4: 801a strh r2, [r3, #0] + /* link it back to mem */ + mem2->prev = ptr; + 80049c6: 68fb ldr r3, [r7, #12] + 80049c8: 2212 movs r2, #18 + 80049ca: 18ba adds r2, r7, r2 + 80049cc: 8812 ldrh r2, [r2, #0] + 80049ce: 805a strh r2, [r3, #2] + /* link mem to it */ + mem->next = ptr2; + 80049d0: 697b ldr r3, [r7, #20] + 80049d2: 187a adds r2, r7, r1 + 80049d4: 8812 ldrh r2, [r2, #0] + 80049d6: 801a strh r2, [r3, #0] + /* last thing to restore linked list: as we have moved mem2, + * let 'mem2->next->prev' point to mem2 again. but only if mem2->next is not + * the end of the heap */ + if (mem2->next != MEM_SIZE_ALIGNED) { + 80049d8: 68fb ldr r3, [r7, #12] + 80049da: 881a ldrh r2, [r3, #0] + 80049dc: 23c8 movs r3, #200 ; 0xc8 + 80049de: 00db lsls r3, r3, #3 + 80049e0: 429a cmp r2, r3 + 80049e2: d008 beq.n 80049f6 + ((struct mem *)(void *)&ram[mem2->next])->prev = ptr2; + 80049e4: 4b37 ldr r3, [pc, #220] ; (8004ac4 ) + 80049e6: 681b ldr r3, [r3, #0] + 80049e8: 68fa ldr r2, [r7, #12] + 80049ea: 8812 ldrh r2, [r2, #0] + 80049ec: 189b adds r3, r3, r2 + 80049ee: 220a movs r2, #10 + 80049f0: 18ba adds r2, r7, r2 + 80049f2: 8812 ldrh r2, [r2, #0] + 80049f4: 805a strh r2, [r3, #2] + } + MEM_STATS_DEC_USED(used, (size - newsize)); + 80049f6: 4b35 ldr r3, [pc, #212] ; (8004acc ) + 80049f8: 22aa movs r2, #170 ; 0xaa + 80049fa: 5a9a ldrh r2, [r3, r2] + 80049fc: 1cb9 adds r1, r7, #2 + 80049fe: 2310 movs r3, #16 + 8004a00: 18fb adds r3, r7, r3 + 8004a02: 8809 ldrh r1, [r1, #0] + 8004a04: 881b ldrh r3, [r3, #0] + 8004a06: 1acb subs r3, r1, r3 + 8004a08: b29b uxth r3, r3 + 8004a0a: 18d3 adds r3, r2, r3 + 8004a0c: b299 uxth r1, r3 + 8004a0e: 4b2f ldr r3, [pc, #188] ; (8004acc ) + 8004a10: 22aa movs r2, #170 ; 0xaa + 8004a12: 5299 strh r1, [r3, r2] + 8004a14: e050 b.n 8004ab8 + /* no need to plug holes, we've already done that */ + } else if (newsize + SIZEOF_STRUCT_MEM + MIN_SIZE_ALIGNED <= size) { + 8004a16: 1cbb adds r3, r7, #2 + 8004a18: 881b ldrh r3, [r3, #0] + 8004a1a: 3314 adds r3, #20 + 8004a1c: 001a movs r2, r3 + 8004a1e: 2310 movs r3, #16 + 8004a20: 18fb adds r3, r7, r3 + 8004a22: 881b ldrh r3, [r3, #0] + 8004a24: 429a cmp r2, r3 + 8004a26: d847 bhi.n 8004ab8 + * Old size ('size') must be big enough to contain at least 'newsize' plus a struct mem + * ('SIZEOF_STRUCT_MEM') with some data ('MIN_SIZE_ALIGNED'). + * @todo we could leave out MIN_SIZE_ALIGNED. We would create an empty + * region that couldn't hold data, but when mem->next gets freed, + * the 2 regions would be combined, resulting in more free memory */ + ptr2 = ptr + SIZEOF_STRUCT_MEM + newsize; + 8004a28: 2312 movs r3, #18 + 8004a2a: 18fa adds r2, r7, r3 + 8004a2c: 1cbb adds r3, r7, #2 + 8004a2e: 8812 ldrh r2, [r2, #0] + 8004a30: 881b ldrh r3, [r3, #0] + 8004a32: 18d3 adds r3, r2, r3 + 8004a34: b29a uxth r2, r3 + 8004a36: 210a movs r1, #10 + 8004a38: 187b adds r3, r7, r1 + 8004a3a: 3208 adds r2, #8 + 8004a3c: 801a strh r2, [r3, #0] + mem2 = (struct mem *)(void *)&ram[ptr2]; + 8004a3e: 4b21 ldr r3, [pc, #132] ; (8004ac4 ) + 8004a40: 681a ldr r2, [r3, #0] + 8004a42: 187b adds r3, r7, r1 + 8004a44: 881b ldrh r3, [r3, #0] + 8004a46: 18d3 adds r3, r2, r3 + 8004a48: 60fb str r3, [r7, #12] + if (mem2 < lfree) { + 8004a4a: 4b21 ldr r3, [pc, #132] ; (8004ad0 ) + 8004a4c: 681b ldr r3, [r3, #0] + 8004a4e: 68fa ldr r2, [r7, #12] + 8004a50: 429a cmp r2, r3 + 8004a52: d202 bcs.n 8004a5a + lfree = mem2; + 8004a54: 4b1e ldr r3, [pc, #120] ; (8004ad0 ) + 8004a56: 68fa ldr r2, [r7, #12] + 8004a58: 601a str r2, [r3, #0] + } + mem2->used = 0; + 8004a5a: 68fb ldr r3, [r7, #12] + 8004a5c: 2200 movs r2, #0 + 8004a5e: 711a strb r2, [r3, #4] + mem2->next = mem->next; + 8004a60: 697b ldr r3, [r7, #20] + 8004a62: 881a ldrh r2, [r3, #0] + 8004a64: 68fb ldr r3, [r7, #12] + 8004a66: 801a strh r2, [r3, #0] + mem2->prev = ptr; + 8004a68: 68fb ldr r3, [r7, #12] + 8004a6a: 2212 movs r2, #18 + 8004a6c: 18ba adds r2, r7, r2 + 8004a6e: 8812 ldrh r2, [r2, #0] + 8004a70: 805a strh r2, [r3, #2] + mem->next = ptr2; + 8004a72: 697b ldr r3, [r7, #20] + 8004a74: 220a movs r2, #10 + 8004a76: 18ba adds r2, r7, r2 + 8004a78: 8812 ldrh r2, [r2, #0] + 8004a7a: 801a strh r2, [r3, #0] + if (mem2->next != MEM_SIZE_ALIGNED) { + 8004a7c: 68fb ldr r3, [r7, #12] + 8004a7e: 881a ldrh r2, [r3, #0] + 8004a80: 23c8 movs r3, #200 ; 0xc8 + 8004a82: 00db lsls r3, r3, #3 + 8004a84: 429a cmp r2, r3 + 8004a86: d008 beq.n 8004a9a + ((struct mem *)(void *)&ram[mem2->next])->prev = ptr2; + 8004a88: 4b0e ldr r3, [pc, #56] ; (8004ac4 ) + 8004a8a: 681b ldr r3, [r3, #0] + 8004a8c: 68fa ldr r2, [r7, #12] + 8004a8e: 8812 ldrh r2, [r2, #0] + 8004a90: 189b adds r3, r3, r2 + 8004a92: 220a movs r2, #10 + 8004a94: 18ba adds r2, r7, r2 + 8004a96: 8812 ldrh r2, [r2, #0] + 8004a98: 805a strh r2, [r3, #2] + } + MEM_STATS_DEC_USED(used, (size - newsize)); + 8004a9a: 4b0c ldr r3, [pc, #48] ; (8004acc ) + 8004a9c: 22aa movs r2, #170 ; 0xaa + 8004a9e: 5a9a ldrh r2, [r3, r2] + 8004aa0: 1cb9 adds r1, r7, #2 + 8004aa2: 2310 movs r3, #16 + 8004aa4: 18fb adds r3, r7, r3 + 8004aa6: 8809 ldrh r1, [r1, #0] + 8004aa8: 881b ldrh r3, [r3, #0] + 8004aaa: 1acb subs r3, r1, r3 + 8004aac: b29b uxth r3, r3 + 8004aae: 18d3 adds r3, r2, r3 + 8004ab0: b299 uxth r1, r3 + 8004ab2: 4b06 ldr r3, [pc, #24] ; (8004acc ) + 8004ab4: 22aa movs r2, #170 ; 0xaa + 8004ab6: 5299 strh r1, [r3, r2] + } */ +#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT + mem_free_count = 1; +#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */ + LWIP_MEM_FREE_UNPROTECT(); + return rmem; + 8004ab8: 687b ldr r3, [r7, #4] +} + 8004aba: 0018 movs r0, r3 + 8004abc: 46bd mov sp, r7 + 8004abe: b006 add sp, #24 + 8004ac0: bd80 pop {r7, pc} + 8004ac2: 46c0 nop ; (mov r8, r8) + 8004ac4: 2000014c .word 0x2000014c + 8004ac8: 20000150 .word 0x20000150 + 8004acc: 20003158 .word 0x20003158 + 8004ad0: 20000154 .word 0x20000154 + +08004ad4 : + * + * Note that the returned value will always be aligned (as defined by MEM_ALIGNMENT). + */ +void * +mem_malloc(mem_size_t size) +{ + 8004ad4: b580 push {r7, lr} + 8004ad6: b088 sub sp, #32 + 8004ad8: af00 add r7, sp, #0 + 8004ada: 0002 movs r2, r0 + 8004adc: 1dbb adds r3, r7, #6 + 8004ade: 801a strh r2, [r3, #0] +#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT + u8_t local_mem_free_count = 0; +#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */ + LWIP_MEM_ALLOC_DECL_PROTECT(); + + if (size == 0) { + 8004ae0: 1dbb adds r3, r7, #6 + 8004ae2: 881b ldrh r3, [r3, #0] + 8004ae4: 2b00 cmp r3, #0 + 8004ae6: d101 bne.n 8004aec + return NULL; + 8004ae8: 2300 movs r3, #0 + 8004aea: e0f2 b.n 8004cd2 + } + + /* Expand the size of the allocated memory region so that we can + adjust for alignment. */ + size = LWIP_MEM_ALIGN_SIZE(size); + 8004aec: 1dbb adds r3, r7, #6 + 8004aee: 881b ldrh r3, [r3, #0] + 8004af0: 3303 adds r3, #3 + 8004af2: b29a uxth r2, r3 + 8004af4: 1dbb adds r3, r7, #6 + 8004af6: 2103 movs r1, #3 + 8004af8: 438a bics r2, r1 + 8004afa: 801a strh r2, [r3, #0] + + if(size < MIN_SIZE_ALIGNED) { + 8004afc: 1dbb adds r3, r7, #6 + 8004afe: 881b ldrh r3, [r3, #0] + 8004b00: 2b0b cmp r3, #11 + 8004b02: d802 bhi.n 8004b0a + /* every data block must be at least MIN_SIZE_ALIGNED long */ + size = MIN_SIZE_ALIGNED; + 8004b04: 1dbb adds r3, r7, #6 + 8004b06: 220c movs r2, #12 + 8004b08: 801a strh r2, [r3, #0] + } + + if (size > MEM_SIZE_ALIGNED) { + 8004b0a: 1dbb adds r3, r7, #6 + 8004b0c: 881a ldrh r2, [r3, #0] + 8004b0e: 23c8 movs r3, #200 ; 0xc8 + 8004b10: 00db lsls r3, r3, #3 + 8004b12: 429a cmp r2, r3 + 8004b14: d901 bls.n 8004b1a + return NULL; + 8004b16: 2300 movs r3, #0 + 8004b18: e0db b.n 8004cd2 +#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */ + + /* Scan through the heap searching for a free block that is big enough, + * beginning with the lowest free block. + */ + for (ptr = (mem_size_t)((u8_t *)lfree - ram); ptr < MEM_SIZE_ALIGNED - size; + 8004b1a: 4b70 ldr r3, [pc, #448] ; (8004cdc ) + 8004b1c: 681b ldr r3, [r3, #0] + 8004b1e: 001a movs r2, r3 + 8004b20: 4b6f ldr r3, [pc, #444] ; (8004ce0 ) + 8004b22: 681b ldr r3, [r3, #0] + 8004b24: 1ad2 subs r2, r2, r3 + 8004b26: 231e movs r3, #30 + 8004b28: 18fb adds r3, r7, r3 + 8004b2a: 801a strh r2, [r3, #0] + 8004b2c: e0bd b.n 8004caa + ptr = ((struct mem *)(void *)&ram[ptr])->next) { + mem = (struct mem *)(void *)&ram[ptr]; + 8004b2e: 4b6c ldr r3, [pc, #432] ; (8004ce0 ) + 8004b30: 681a ldr r2, [r3, #0] + 8004b32: 231e movs r3, #30 + 8004b34: 18fb adds r3, r7, r3 + 8004b36: 881b ldrh r3, [r3, #0] + 8004b38: 18d3 adds r3, r2, r3 + 8004b3a: 617b str r3, [r7, #20] + local_mem_free_count = 1; + break; + } +#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */ + + if ((!mem->used) && + 8004b3c: 697b ldr r3, [r7, #20] + 8004b3e: 791b ldrb r3, [r3, #4] + 8004b40: 2b00 cmp r3, #0 + 8004b42: d000 beq.n 8004b46 + 8004b44: e0a8 b.n 8004c98 + (mem->next - (ptr + SIZEOF_STRUCT_MEM)) >= size) { + 8004b46: 697b ldr r3, [r7, #20] + 8004b48: 881b ldrh r3, [r3, #0] + 8004b4a: 001a movs r2, r3 + 8004b4c: 231e movs r3, #30 + 8004b4e: 18fb adds r3, r7, r3 + 8004b50: 881b ldrh r3, [r3, #0] + 8004b52: 1ad3 subs r3, r2, r3 + 8004b54: 3b08 subs r3, #8 + 8004b56: 001a movs r2, r3 + 8004b58: 1dbb adds r3, r7, #6 + 8004b5a: 881b ldrh r3, [r3, #0] + if ((!mem->used) && + 8004b5c: 429a cmp r2, r3 + 8004b5e: d200 bcs.n 8004b62 + 8004b60: e09a b.n 8004c98 + /* mem is not used and at least perfect fit is possible: + * mem->next - (ptr + SIZEOF_STRUCT_MEM) gives us the 'user data size' of mem */ + + if (mem->next - (ptr + SIZEOF_STRUCT_MEM) >= (size + SIZEOF_STRUCT_MEM + MIN_SIZE_ALIGNED)) { + 8004b62: 697b ldr r3, [r7, #20] + 8004b64: 881b ldrh r3, [r3, #0] + 8004b66: 001a movs r2, r3 + 8004b68: 231e movs r3, #30 + 8004b6a: 18fb adds r3, r7, r3 + 8004b6c: 881b ldrh r3, [r3, #0] + 8004b6e: 1ad3 subs r3, r2, r3 + 8004b70: 3b08 subs r3, #8 + 8004b72: 001a movs r2, r3 + 8004b74: 1dbb adds r3, r7, #6 + 8004b76: 881b ldrh r3, [r3, #0] + 8004b78: 3314 adds r3, #20 + 8004b7a: 429a cmp r2, r3 + 8004b7c: d34c bcc.n 8004c18 + * struct mem would fit in but no data between mem2 and mem2->next + * @todo we could leave out MIN_SIZE_ALIGNED. We would create an empty + * region that couldn't hold data, but when mem->next gets freed, + * the 2 regions would be combined, resulting in more free memory + */ + ptr2 = ptr + SIZEOF_STRUCT_MEM + size; + 8004b7e: 201e movs r0, #30 + 8004b80: 183a adds r2, r7, r0 + 8004b82: 1dbb adds r3, r7, #6 + 8004b84: 8812 ldrh r2, [r2, #0] + 8004b86: 881b ldrh r3, [r3, #0] + 8004b88: 18d3 adds r3, r2, r3 + 8004b8a: b29a uxth r2, r3 + 8004b8c: 2112 movs r1, #18 + 8004b8e: 187b adds r3, r7, r1 + 8004b90: 3208 adds r2, #8 + 8004b92: 801a strh r2, [r3, #0] + /* create mem2 struct */ + mem2 = (struct mem *)(void *)&ram[ptr2]; + 8004b94: 4b52 ldr r3, [pc, #328] ; (8004ce0 ) + 8004b96: 681a ldr r2, [r3, #0] + 8004b98: 187b adds r3, r7, r1 + 8004b9a: 881b ldrh r3, [r3, #0] + 8004b9c: 18d3 adds r3, r2, r3 + 8004b9e: 60fb str r3, [r7, #12] + mem2->used = 0; + 8004ba0: 68fb ldr r3, [r7, #12] + 8004ba2: 2200 movs r2, #0 + 8004ba4: 711a strb r2, [r3, #4] + mem2->next = mem->next; + 8004ba6: 697b ldr r3, [r7, #20] + 8004ba8: 881a ldrh r2, [r3, #0] + 8004baa: 68fb ldr r3, [r7, #12] + 8004bac: 801a strh r2, [r3, #0] + mem2->prev = ptr; + 8004bae: 68fb ldr r3, [r7, #12] + 8004bb0: 183a adds r2, r7, r0 + 8004bb2: 8812 ldrh r2, [r2, #0] + 8004bb4: 805a strh r2, [r3, #2] + /* and insert it between mem and mem->next */ + mem->next = ptr2; + 8004bb6: 697b ldr r3, [r7, #20] + 8004bb8: 187a adds r2, r7, r1 + 8004bba: 8812 ldrh r2, [r2, #0] + 8004bbc: 801a strh r2, [r3, #0] + mem->used = 1; + 8004bbe: 697b ldr r3, [r7, #20] + 8004bc0: 2201 movs r2, #1 + 8004bc2: 711a strb r2, [r3, #4] + + if (mem2->next != MEM_SIZE_ALIGNED) { + 8004bc4: 68fb ldr r3, [r7, #12] + 8004bc6: 881a ldrh r2, [r3, #0] + 8004bc8: 23c8 movs r3, #200 ; 0xc8 + 8004bca: 00db lsls r3, r3, #3 + 8004bcc: 429a cmp r2, r3 + 8004bce: d008 beq.n 8004be2 + ((struct mem *)(void *)&ram[mem2->next])->prev = ptr2; + 8004bd0: 4b43 ldr r3, [pc, #268] ; (8004ce0 ) + 8004bd2: 681b ldr r3, [r3, #0] + 8004bd4: 68fa ldr r2, [r7, #12] + 8004bd6: 8812 ldrh r2, [r2, #0] + 8004bd8: 189b adds r3, r3, r2 + 8004bda: 2212 movs r2, #18 + 8004bdc: 18ba adds r2, r7, r2 + 8004bde: 8812 ldrh r2, [r2, #0] + 8004be0: 805a strh r2, [r3, #2] + } + MEM_STATS_INC_USED(used, (size + SIZEOF_STRUCT_MEM)); + 8004be2: 4b40 ldr r3, [pc, #256] ; (8004ce4 ) + 8004be4: 22aa movs r2, #170 ; 0xaa + 8004be6: 5a9a ldrh r2, [r3, r2] + 8004be8: 1dbb adds r3, r7, #6 + 8004bea: 881b ldrh r3, [r3, #0] + 8004bec: 18d3 adds r3, r2, r3 + 8004bee: b29b uxth r3, r3 + 8004bf0: 3308 adds r3, #8 + 8004bf2: b299 uxth r1, r3 + 8004bf4: 4b3b ldr r3, [pc, #236] ; (8004ce4 ) + 8004bf6: 22aa movs r2, #170 ; 0xaa + 8004bf8: 5299 strh r1, [r3, r2] + 8004bfa: 4b3a ldr r3, [pc, #232] ; (8004ce4 ) + 8004bfc: 22ac movs r2, #172 ; 0xac + 8004bfe: 5a9a ldrh r2, [r3, r2] + 8004c00: 4b38 ldr r3, [pc, #224] ; (8004ce4 ) + 8004c02: 21aa movs r1, #170 ; 0xaa + 8004c04: 5a5b ldrh r3, [r3, r1] + 8004c06: 429a cmp r2, r3 + 8004c08: d228 bcs.n 8004c5c + 8004c0a: 4b36 ldr r3, [pc, #216] ; (8004ce4 ) + 8004c0c: 22aa movs r2, #170 ; 0xaa + 8004c0e: 5a99 ldrh r1, [r3, r2] + 8004c10: 4b34 ldr r3, [pc, #208] ; (8004ce4 ) + 8004c12: 22ac movs r2, #172 ; 0xac + 8004c14: 5299 strh r1, [r3, r2] + 8004c16: e021 b.n 8004c5c + * take care of this). + * -> near fit or excact fit: do not split, no mem2 creation + * also can't move mem->next directly behind mem, since mem->next + * will always be used at this point! + */ + mem->used = 1; + 8004c18: 697b ldr r3, [r7, #20] + 8004c1a: 2201 movs r2, #1 + 8004c1c: 711a strb r2, [r3, #4] + MEM_STATS_INC_USED(used, mem->next - (mem_size_t)((u8_t *)mem - ram)); + 8004c1e: 4b31 ldr r3, [pc, #196] ; (8004ce4 ) + 8004c20: 22aa movs r2, #170 ; 0xaa + 8004c22: 5a9a ldrh r2, [r3, r2] + 8004c24: 697b ldr r3, [r7, #20] + 8004c26: 8819 ldrh r1, [r3, #0] + 8004c28: 6978 ldr r0, [r7, #20] + 8004c2a: 4b2d ldr r3, [pc, #180] ; (8004ce0 ) + 8004c2c: 681b ldr r3, [r3, #0] + 8004c2e: 1ac3 subs r3, r0, r3 + 8004c30: b29b uxth r3, r3 + 8004c32: 1acb subs r3, r1, r3 + 8004c34: b29b uxth r3, r3 + 8004c36: 18d3 adds r3, r2, r3 + 8004c38: b299 uxth r1, r3 + 8004c3a: 4b2a ldr r3, [pc, #168] ; (8004ce4 ) + 8004c3c: 22aa movs r2, #170 ; 0xaa + 8004c3e: 5299 strh r1, [r3, r2] + 8004c40: 4b28 ldr r3, [pc, #160] ; (8004ce4 ) + 8004c42: 22ac movs r2, #172 ; 0xac + 8004c44: 5a9a ldrh r2, [r3, r2] + 8004c46: 4b27 ldr r3, [pc, #156] ; (8004ce4 ) + 8004c48: 21aa movs r1, #170 ; 0xaa + 8004c4a: 5a5b ldrh r3, [r3, r1] + 8004c4c: 429a cmp r2, r3 + 8004c4e: d205 bcs.n 8004c5c + 8004c50: 4b24 ldr r3, [pc, #144] ; (8004ce4 ) + 8004c52: 22aa movs r2, #170 ; 0xaa + 8004c54: 5a99 ldrh r1, [r3, r2] + 8004c56: 4b23 ldr r3, [pc, #140] ; (8004ce4 ) + 8004c58: 22ac movs r2, #172 ; 0xac + 8004c5a: 5299 strh r1, [r3, r2] + } +#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT +mem_malloc_adjust_lfree: +#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */ + if (mem == lfree) { + 8004c5c: 4b1f ldr r3, [pc, #124] ; (8004cdc ) + 8004c5e: 681b ldr r3, [r3, #0] + 8004c60: 697a ldr r2, [r7, #20] + 8004c62: 429a cmp r2, r3 + 8004c64: d115 bne.n 8004c92 + struct mem *cur = lfree; + 8004c66: 4b1d ldr r3, [pc, #116] ; (8004cdc ) + 8004c68: 681b ldr r3, [r3, #0] + 8004c6a: 61bb str r3, [r7, #24] + /* Find next free block after mem and update lowest free pointer */ + while (cur->used && cur != ram_end) { + 8004c6c: e005 b.n 8004c7a + /* If mem_free or mem_trim have run, we have to restart since they + could have altered our current struct mem or lfree. */ + goto mem_malloc_adjust_lfree; + } +#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */ + cur = (struct mem *)(void *)&ram[cur->next]; + 8004c6e: 4b1c ldr r3, [pc, #112] ; (8004ce0 ) + 8004c70: 681b ldr r3, [r3, #0] + 8004c72: 69ba ldr r2, [r7, #24] + 8004c74: 8812 ldrh r2, [r2, #0] + 8004c76: 189b adds r3, r3, r2 + 8004c78: 61bb str r3, [r7, #24] + while (cur->used && cur != ram_end) { + 8004c7a: 69bb ldr r3, [r7, #24] + 8004c7c: 791b ldrb r3, [r3, #4] + 8004c7e: 2b00 cmp r3, #0 + 8004c80: d004 beq.n 8004c8c + 8004c82: 4b19 ldr r3, [pc, #100] ; (8004ce8 ) + 8004c84: 681b ldr r3, [r3, #0] + 8004c86: 69ba ldr r2, [r7, #24] + 8004c88: 429a cmp r2, r3 + 8004c8a: d1f0 bne.n 8004c6e + } + lfree = cur; + 8004c8c: 4b13 ldr r3, [pc, #76] ; (8004cdc ) + 8004c8e: 69ba ldr r2, [r7, #24] + 8004c90: 601a str r2, [r3, #0] + LWIP_ASSERT("mem_malloc: allocated memory properly aligned.", + ((mem_ptr_t)mem + SIZEOF_STRUCT_MEM) % MEM_ALIGNMENT == 0); + LWIP_ASSERT("mem_malloc: sanity check alignment", + (((mem_ptr_t)mem) & (MEM_ALIGNMENT-1)) == 0); + + return (u8_t *)mem + SIZEOF_STRUCT_MEM; + 8004c92: 697b ldr r3, [r7, #20] + 8004c94: 3308 adds r3, #8 + 8004c96: e01c b.n 8004cd2 + ptr = ((struct mem *)(void *)&ram[ptr])->next) { + 8004c98: 4b11 ldr r3, [pc, #68] ; (8004ce0 ) + 8004c9a: 681a ldr r2, [r3, #0] + 8004c9c: 211e movs r1, #30 + 8004c9e: 187b adds r3, r7, r1 + 8004ca0: 881b ldrh r3, [r3, #0] + 8004ca2: 18d2 adds r2, r2, r3 + 8004ca4: 187b adds r3, r7, r1 + 8004ca6: 8812 ldrh r2, [r2, #0] + 8004ca8: 801a strh r2, [r3, #0] + for (ptr = (mem_size_t)((u8_t *)lfree - ram); ptr < MEM_SIZE_ALIGNED - size; + 8004caa: 231e movs r3, #30 + 8004cac: 18fb adds r3, r7, r3 + 8004cae: 881a ldrh r2, [r3, #0] + 8004cb0: 1dbb adds r3, r7, #6 + 8004cb2: 881b ldrh r3, [r3, #0] + 8004cb4: 21c8 movs r1, #200 ; 0xc8 + 8004cb6: 00c9 lsls r1, r1, #3 + 8004cb8: 1acb subs r3, r1, r3 + 8004cba: 429a cmp r2, r3 + 8004cbc: da00 bge.n 8004cc0 + 8004cbe: e736 b.n 8004b2e +#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT + /* if we got interrupted by a mem_free, try again */ + } while(local_mem_free_count != 0); +#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */ + LWIP_DEBUGF(MEM_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("mem_malloc: could not allocate %"S16_F" bytes\n", (s16_t)size)); + MEM_STATS_INC(err); + 8004cc0: 4b08 ldr r3, [pc, #32] ; (8004ce4 ) + 8004cc2: 22ae movs r2, #174 ; 0xae + 8004cc4: 5a9b ldrh r3, [r3, r2] + 8004cc6: 3301 adds r3, #1 + 8004cc8: b299 uxth r1, r3 + 8004cca: 4b06 ldr r3, [pc, #24] ; (8004ce4 ) + 8004ccc: 22ae movs r2, #174 ; 0xae + 8004cce: 5299 strh r1, [r3, r2] + LWIP_MEM_ALLOC_UNPROTECT(); + sys_mutex_unlock(&mem_mutex); + return NULL; + 8004cd0: 2300 movs r3, #0 +} + 8004cd2: 0018 movs r0, r3 + 8004cd4: 46bd mov sp, r7 + 8004cd6: b008 add sp, #32 + 8004cd8: bd80 pop {r7, pc} + 8004cda: 46c0 nop ; (mov r8, r8) + 8004cdc: 20000154 .word 0x20000154 + 8004ce0: 2000014c .word 0x2000014c + 8004ce4: 20003158 .word 0x20003158 + 8004ce8: 20000150 .word 0x20000150 + +08004cec : + * + * Carves out memp_memory into linked lists for each pool-type. + */ +void +memp_init(void) +{ + 8004cec: b590 push {r4, r7, lr} + 8004cee: b083 sub sp, #12 + 8004cf0: af00 add r7, sp, #0 + struct memp *memp; + u16_t i, j; + + for (i = 0; i < MEMP_MAX; ++i) { + 8004cf2: 1cbb adds r3, r7, #2 + 8004cf4: 2200 movs r2, #0 + 8004cf6: 801a strh r2, [r3, #0] + 8004cf8: e039 b.n 8004d6e + MEMP_STATS_AVAIL(used, i, 0); + 8004cfa: 1cbb adds r3, r7, #2 + 8004cfc: 881a ldrh r2, [r3, #0] + 8004cfe: 4940 ldr r1, [pc, #256] ; (8004e00 ) + 8004d00: 20b4 movs r0, #180 ; 0xb4 + 8004d02: 0013 movs r3, r2 + 8004d04: 009b lsls r3, r3, #2 + 8004d06: 189b adds r3, r3, r2 + 8004d08: 005b lsls r3, r3, #1 + 8004d0a: 18cb adds r3, r1, r3 + 8004d0c: 181b adds r3, r3, r0 + 8004d0e: 2200 movs r2, #0 + 8004d10: 801a strh r2, [r3, #0] + MEMP_STATS_AVAIL(max, i, 0); + 8004d12: 1cbb adds r3, r7, #2 + 8004d14: 881a ldrh r2, [r3, #0] + 8004d16: 493a ldr r1, [pc, #232] ; (8004e00 ) + 8004d18: 20b6 movs r0, #182 ; 0xb6 + 8004d1a: 0013 movs r3, r2 + 8004d1c: 009b lsls r3, r3, #2 + 8004d1e: 189b adds r3, r3, r2 + 8004d20: 005b lsls r3, r3, #1 + 8004d22: 18cb adds r3, r1, r3 + 8004d24: 181b adds r3, r3, r0 + 8004d26: 2200 movs r2, #0 + 8004d28: 801a strh r2, [r3, #0] + MEMP_STATS_AVAIL(err, i, 0); + 8004d2a: 1cbb adds r3, r7, #2 + 8004d2c: 881a ldrh r2, [r3, #0] + 8004d2e: 4934 ldr r1, [pc, #208] ; (8004e00 ) + 8004d30: 20b8 movs r0, #184 ; 0xb8 + 8004d32: 0013 movs r3, r2 + 8004d34: 009b lsls r3, r3, #2 + 8004d36: 189b adds r3, r3, r2 + 8004d38: 005b lsls r3, r3, #1 + 8004d3a: 18cb adds r3, r1, r3 + 8004d3c: 181b adds r3, r3, r0 + 8004d3e: 2200 movs r2, #0 + 8004d40: 801a strh r2, [r3, #0] + MEMP_STATS_AVAIL(avail, i, memp_num[i]); + 8004d42: 1cbb adds r3, r7, #2 + 8004d44: 8819 ldrh r1, [r3, #0] + 8004d46: 1cbb adds r3, r7, #2 + 8004d48: 881a ldrh r2, [r3, #0] + 8004d4a: 4b2e ldr r3, [pc, #184] ; (8004e04 ) + 8004d4c: 0049 lsls r1, r1, #1 + 8004d4e: 5acc ldrh r4, [r1, r3] + 8004d50: 492b ldr r1, [pc, #172] ; (8004e00 ) + 8004d52: 20b2 movs r0, #178 ; 0xb2 + 8004d54: 0013 movs r3, r2 + 8004d56: 009b lsls r3, r3, #2 + 8004d58: 189b adds r3, r3, r2 + 8004d5a: 005b lsls r3, r3, #1 + 8004d5c: 18cb adds r3, r1, r3 + 8004d5e: 181b adds r3, r3, r0 + 8004d60: 1c22 adds r2, r4, #0 + 8004d62: 801a strh r2, [r3, #0] + for (i = 0; i < MEMP_MAX; ++i) { + 8004d64: 1cbb adds r3, r7, #2 + 8004d66: 1cba adds r2, r7, #2 + 8004d68: 8812 ldrh r2, [r2, #0] + 8004d6a: 3201 adds r2, #1 + 8004d6c: 801a strh r2, [r3, #0] + 8004d6e: 1cbb adds r3, r7, #2 + 8004d70: 881b ldrh r3, [r3, #0] + 8004d72: 2b09 cmp r3, #9 + 8004d74: d9c1 bls.n 8004cfa + } + +#if !MEMP_SEPARATE_POOLS + memp = (struct memp *)LWIP_MEM_ALIGN(memp_memory); + 8004d76: 4b24 ldr r3, [pc, #144] ; (8004e08 ) + 8004d78: 3303 adds r3, #3 + 8004d7a: 2203 movs r2, #3 + 8004d7c: 4393 bics r3, r2 + 8004d7e: 607b str r3, [r7, #4] +#endif /* !MEMP_SEPARATE_POOLS */ + /* for every pool: */ + for (i = 0; i < MEMP_MAX; ++i) { + 8004d80: 1cbb adds r3, r7, #2 + 8004d82: 2200 movs r2, #0 + 8004d84: 801a strh r2, [r3, #0] + 8004d86: e032 b.n 8004dee + memp_tab[i] = NULL; + 8004d88: 1cbb adds r3, r7, #2 + 8004d8a: 881a ldrh r2, [r3, #0] + 8004d8c: 4b1f ldr r3, [pc, #124] ; (8004e0c ) + 8004d8e: 0092 lsls r2, r2, #2 + 8004d90: 2100 movs r1, #0 + 8004d92: 50d1 str r1, [r2, r3] +#if MEMP_SEPARATE_POOLS + memp = (struct memp*)memp_bases[i]; +#endif /* MEMP_SEPARATE_POOLS */ + /* create a linked list of memp elements */ + for (j = 0; j < memp_num[i]; ++j) { + 8004d94: 003b movs r3, r7 + 8004d96: 2200 movs r2, #0 + 8004d98: 801a strh r2, [r3, #0] + 8004d9a: e01a b.n 8004dd2 + memp->next = memp_tab[i]; + 8004d9c: 1cbb adds r3, r7, #2 + 8004d9e: 881a ldrh r2, [r3, #0] + 8004da0: 4b1a ldr r3, [pc, #104] ; (8004e0c ) + 8004da2: 0092 lsls r2, r2, #2 + 8004da4: 58d2 ldr r2, [r2, r3] + 8004da6: 687b ldr r3, [r7, #4] + 8004da8: 601a str r2, [r3, #0] + memp_tab[i] = memp; + 8004daa: 1cbb adds r3, r7, #2 + 8004dac: 881a ldrh r2, [r3, #0] + 8004dae: 4b17 ldr r3, [pc, #92] ; (8004e0c ) + 8004db0: 0092 lsls r2, r2, #2 + 8004db2: 6879 ldr r1, [r7, #4] + 8004db4: 50d1 str r1, [r2, r3] + memp = (struct memp *)(void *)((u8_t *)memp + MEMP_SIZE + memp_sizes[i] + 8004db6: 1cbb adds r3, r7, #2 + 8004db8: 881a ldrh r2, [r3, #0] + 8004dba: 4b15 ldr r3, [pc, #84] ; (8004e10 ) + 8004dbc: 0052 lsls r2, r2, #1 + 8004dbe: 5ad3 ldrh r3, [r2, r3] + 8004dc0: 001a movs r2, r3 + 8004dc2: 687b ldr r3, [r7, #4] + 8004dc4: 189b adds r3, r3, r2 + 8004dc6: 607b str r3, [r7, #4] + for (j = 0; j < memp_num[i]; ++j) { + 8004dc8: 003b movs r3, r7 + 8004dca: 003a movs r2, r7 + 8004dcc: 8812 ldrh r2, [r2, #0] + 8004dce: 3201 adds r2, #1 + 8004dd0: 801a strh r2, [r3, #0] + 8004dd2: 1cbb adds r3, r7, #2 + 8004dd4: 881a ldrh r2, [r3, #0] + 8004dd6: 4b0b ldr r3, [pc, #44] ; (8004e04 ) + 8004dd8: 0052 lsls r2, r2, #1 + 8004dda: 5ad3 ldrh r3, [r2, r3] + 8004ddc: 003a movs r2, r7 + 8004dde: 8812 ldrh r2, [r2, #0] + 8004de0: 429a cmp r2, r3 + 8004de2: d3db bcc.n 8004d9c + for (i = 0; i < MEMP_MAX; ++i) { + 8004de4: 1cbb adds r3, r7, #2 + 8004de6: 1cba adds r2, r7, #2 + 8004de8: 8812 ldrh r2, [r2, #0] + 8004dea: 3201 adds r2, #1 + 8004dec: 801a strh r2, [r3, #0] + 8004dee: 1cbb adds r3, r7, #2 + 8004df0: 881b ldrh r3, [r3, #0] + 8004df2: 2b09 cmp r3, #9 + 8004df4: d9c8 bls.n 8004d88 +#if MEMP_OVERFLOW_CHECK + memp_overflow_init(); + /* check everything a first time to see if it worked */ + memp_overflow_check_all(); +#endif /* MEMP_OVERFLOW_CHECK */ +} + 8004df6: 46c0 nop ; (mov r8, r8) + 8004df8: 46bd mov sp, r7 + 8004dfa: b003 add sp, #12 + 8004dfc: bd90 pop {r4, r7, pc} + 8004dfe: 46c0 nop ; (mov r8, r8) + 8004e00: 20003158 .word 0x20003158 + 8004e04: 0800fd4c .word 0x0800fd4c + 8004e08: 20000180 .word 0x20000180 + 8004e0c: 20000158 .word 0x20000158 + 8004e10: 0800fd38 .word 0x0800fd38 + +08004e14 : +#if !MEMP_OVERFLOW_CHECK +memp_malloc(memp_t type) +#else +memp_malloc_fn(memp_t type, const char* file, const int line) +#endif +{ + 8004e14: b590 push {r4, r7, lr} + 8004e16: b085 sub sp, #20 + 8004e18: af00 add r7, sp, #0 + 8004e1a: 0002 movs r2, r0 + 8004e1c: 1dfb adds r3, r7, #7 + 8004e1e: 701a strb r2, [r3, #0] + struct memp *memp; + SYS_ARCH_DECL_PROTECT(old_level); + + LWIP_ERROR("memp_malloc: type < MEMP_MAX", (type < MEMP_MAX), return NULL;); + 8004e20: 1dfb adds r3, r7, #7 + 8004e22: 781b ldrb r3, [r3, #0] + 8004e24: 2b09 cmp r3, #9 + 8004e26: d901 bls.n 8004e2c + 8004e28: 2300 movs r3, #0 + 8004e2a: e070 b.n 8004f0e + SYS_ARCH_PROTECT(old_level); +#if MEMP_OVERFLOW_CHECK >= 2 + memp_overflow_check_all(); +#endif /* MEMP_OVERFLOW_CHECK >= 2 */ + + memp = memp_tab[type]; + 8004e2c: 1dfb adds r3, r7, #7 + 8004e2e: 781a ldrb r2, [r3, #0] + 8004e30: 4b39 ldr r3, [pc, #228] ; (8004f18 ) + 8004e32: 0092 lsls r2, r2, #2 + 8004e34: 58d3 ldr r3, [r2, r3] + 8004e36: 60fb str r3, [r7, #12] + + if (memp != NULL) { + 8004e38: 68fb ldr r3, [r7, #12] + 8004e3a: 2b00 cmp r3, #0 + 8004e3c: d04f beq.n 8004ede + memp_tab[type] = memp->next; + 8004e3e: 1dfb adds r3, r7, #7 + 8004e40: 781a ldrb r2, [r3, #0] + 8004e42: 68fb ldr r3, [r7, #12] + 8004e44: 6819 ldr r1, [r3, #0] + 8004e46: 4b34 ldr r3, [pc, #208] ; (8004f18 ) + 8004e48: 0092 lsls r2, r2, #2 + 8004e4a: 50d1 str r1, [r2, r3] +#if MEMP_OVERFLOW_CHECK + memp->next = NULL; + memp->file = file; + memp->line = line; +#endif /* MEMP_OVERFLOW_CHECK */ + MEMP_STATS_INC_USED(used, type); + 8004e4c: 1dfb adds r3, r7, #7 + 8004e4e: 781a ldrb r2, [r3, #0] + 8004e50: 4932 ldr r1, [pc, #200] ; (8004f1c ) + 8004e52: 20b4 movs r0, #180 ; 0xb4 + 8004e54: 0013 movs r3, r2 + 8004e56: 009b lsls r3, r3, #2 + 8004e58: 189b adds r3, r3, r2 + 8004e5a: 005b lsls r3, r3, #1 + 8004e5c: 18cb adds r3, r1, r3 + 8004e5e: 181b adds r3, r3, r0 + 8004e60: 881b ldrh r3, [r3, #0] + 8004e62: 1dfa adds r2, r7, #7 + 8004e64: 7812 ldrb r2, [r2, #0] + 8004e66: 3301 adds r3, #1 + 8004e68: b29c uxth r4, r3 + 8004e6a: 492c ldr r1, [pc, #176] ; (8004f1c ) + 8004e6c: 20b4 movs r0, #180 ; 0xb4 + 8004e6e: 0013 movs r3, r2 + 8004e70: 009b lsls r3, r3, #2 + 8004e72: 189b adds r3, r3, r2 + 8004e74: 005b lsls r3, r3, #1 + 8004e76: 18cb adds r3, r1, r3 + 8004e78: 181b adds r3, r3, r0 + 8004e7a: 1c22 adds r2, r4, #0 + 8004e7c: 801a strh r2, [r3, #0] + 8004e7e: 1dfb adds r3, r7, #7 + 8004e80: 781a ldrb r2, [r3, #0] + 8004e82: 4926 ldr r1, [pc, #152] ; (8004f1c ) + 8004e84: 20b6 movs r0, #182 ; 0xb6 + 8004e86: 0013 movs r3, r2 + 8004e88: 009b lsls r3, r3, #2 + 8004e8a: 189b adds r3, r3, r2 + 8004e8c: 005b lsls r3, r3, #1 + 8004e8e: 18cb adds r3, r1, r3 + 8004e90: 181b adds r3, r3, r0 + 8004e92: 8819 ldrh r1, [r3, #0] + 8004e94: 1dfb adds r3, r7, #7 + 8004e96: 781a ldrb r2, [r3, #0] + 8004e98: 4820 ldr r0, [pc, #128] ; (8004f1c ) + 8004e9a: 24b4 movs r4, #180 ; 0xb4 + 8004e9c: 0013 movs r3, r2 + 8004e9e: 009b lsls r3, r3, #2 + 8004ea0: 189b adds r3, r3, r2 + 8004ea2: 005b lsls r3, r3, #1 + 8004ea4: 18c3 adds r3, r0, r3 + 8004ea6: 191b adds r3, r3, r4 + 8004ea8: 881b ldrh r3, [r3, #0] + 8004eaa: 4299 cmp r1, r3 + 8004eac: d22e bcs.n 8004f0c + 8004eae: 1dfb adds r3, r7, #7 + 8004eb0: 7819 ldrb r1, [r3, #0] + 8004eb2: 1dfb adds r3, r7, #7 + 8004eb4: 781a ldrb r2, [r3, #0] + 8004eb6: 4819 ldr r0, [pc, #100] ; (8004f1c ) + 8004eb8: 24b4 movs r4, #180 ; 0xb4 + 8004eba: 000b movs r3, r1 + 8004ebc: 009b lsls r3, r3, #2 + 8004ebe: 185b adds r3, r3, r1 + 8004ec0: 005b lsls r3, r3, #1 + 8004ec2: 18c3 adds r3, r0, r3 + 8004ec4: 191b adds r3, r3, r4 + 8004ec6: 881c ldrh r4, [r3, #0] + 8004ec8: 4914 ldr r1, [pc, #80] ; (8004f1c ) + 8004eca: 20b6 movs r0, #182 ; 0xb6 + 8004ecc: 0013 movs r3, r2 + 8004ece: 009b lsls r3, r3, #2 + 8004ed0: 189b adds r3, r3, r2 + 8004ed2: 005b lsls r3, r3, #1 + 8004ed4: 18cb adds r3, r1, r3 + 8004ed6: 181b adds r3, r3, r0 + 8004ed8: 1c22 adds r2, r4, #0 + 8004eda: 801a strh r2, [r3, #0] + 8004edc: e016 b.n 8004f0c + LWIP_ASSERT("memp_malloc: memp properly aligned", + ((mem_ptr_t)memp % MEM_ALIGNMENT) == 0); + memp = (struct memp*)(void *)((u8_t*)memp + MEMP_SIZE); + } else { + LWIP_DEBUGF(MEMP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("memp_malloc: out of memory in pool %s\n", memp_desc[type])); + MEMP_STATS_INC(err, type); + 8004ede: 1dfb adds r3, r7, #7 + 8004ee0: 781a ldrb r2, [r3, #0] + 8004ee2: 490e ldr r1, [pc, #56] ; (8004f1c ) + 8004ee4: 20b8 movs r0, #184 ; 0xb8 + 8004ee6: 0013 movs r3, r2 + 8004ee8: 009b lsls r3, r3, #2 + 8004eea: 189b adds r3, r3, r2 + 8004eec: 005b lsls r3, r3, #1 + 8004eee: 18cb adds r3, r1, r3 + 8004ef0: 181b adds r3, r3, r0 + 8004ef2: 881b ldrh r3, [r3, #0] + 8004ef4: 3301 adds r3, #1 + 8004ef6: b29c uxth r4, r3 + 8004ef8: 4908 ldr r1, [pc, #32] ; (8004f1c ) + 8004efa: 20b8 movs r0, #184 ; 0xb8 + 8004efc: 0013 movs r3, r2 + 8004efe: 009b lsls r3, r3, #2 + 8004f00: 189b adds r3, r3, r2 + 8004f02: 005b lsls r3, r3, #1 + 8004f04: 18cb adds r3, r1, r3 + 8004f06: 181b adds r3, r3, r0 + 8004f08: 1c22 adds r2, r4, #0 + 8004f0a: 801a strh r2, [r3, #0] + } + + SYS_ARCH_UNPROTECT(old_level); + + return memp; + 8004f0c: 68fb ldr r3, [r7, #12] +} + 8004f0e: 0018 movs r0, r3 + 8004f10: 46bd mov sp, r7 + 8004f12: b005 add sp, #20 + 8004f14: bd90 pop {r4, r7, pc} + 8004f16: 46c0 nop ; (mov r8, r8) + 8004f18: 20000158 .word 0x20000158 + 8004f1c: 20003158 .word 0x20003158 + +08004f20 : + * @param type the pool where to put mem + * @param mem the memp element to free + */ +void +memp_free(memp_t type, void *mem) +{ + 8004f20: b590 push {r4, r7, lr} + 8004f22: b085 sub sp, #20 + 8004f24: af00 add r7, sp, #0 + 8004f26: 0002 movs r2, r0 + 8004f28: 6039 str r1, [r7, #0] + 8004f2a: 1dfb adds r3, r7, #7 + 8004f2c: 701a strb r2, [r3, #0] + struct memp *memp; + SYS_ARCH_DECL_PROTECT(old_level); + + if (mem == NULL) { + 8004f2e: 683b ldr r3, [r7, #0] + 8004f30: 2b00 cmp r3, #0 + 8004f32: d026 beq.n 8004f82 + return; + } + LWIP_ASSERT("memp_free: mem properly aligned", + ((mem_ptr_t)mem % MEM_ALIGNMENT) == 0); + + memp = (struct memp *)(void *)((u8_t*)mem - MEMP_SIZE); + 8004f34: 683b ldr r3, [r7, #0] + 8004f36: 60fb str r3, [r7, #12] + memp_overflow_check_element_overflow(memp, type); + memp_overflow_check_element_underflow(memp, type); +#endif /* MEMP_OVERFLOW_CHECK >= 2 */ +#endif /* MEMP_OVERFLOW_CHECK */ + + MEMP_STATS_DEC(used, type); + 8004f38: 1dfb adds r3, r7, #7 + 8004f3a: 781a ldrb r2, [r3, #0] + 8004f3c: 4913 ldr r1, [pc, #76] ; (8004f8c ) + 8004f3e: 20b4 movs r0, #180 ; 0xb4 + 8004f40: 0013 movs r3, r2 + 8004f42: 009b lsls r3, r3, #2 + 8004f44: 189b adds r3, r3, r2 + 8004f46: 005b lsls r3, r3, #1 + 8004f48: 18cb adds r3, r1, r3 + 8004f4a: 181b adds r3, r3, r0 + 8004f4c: 881b ldrh r3, [r3, #0] + 8004f4e: 3b01 subs r3, #1 + 8004f50: b29c uxth r4, r3 + 8004f52: 490e ldr r1, [pc, #56] ; (8004f8c ) + 8004f54: 20b4 movs r0, #180 ; 0xb4 + 8004f56: 0013 movs r3, r2 + 8004f58: 009b lsls r3, r3, #2 + 8004f5a: 189b adds r3, r3, r2 + 8004f5c: 005b lsls r3, r3, #1 + 8004f5e: 18cb adds r3, r1, r3 + 8004f60: 181b adds r3, r3, r0 + 8004f62: 1c22 adds r2, r4, #0 + 8004f64: 801a strh r2, [r3, #0] + + memp->next = memp_tab[type]; + 8004f66: 1dfb adds r3, r7, #7 + 8004f68: 781a ldrb r2, [r3, #0] + 8004f6a: 4b09 ldr r3, [pc, #36] ; (8004f90 ) + 8004f6c: 0092 lsls r2, r2, #2 + 8004f6e: 58d2 ldr r2, [r2, r3] + 8004f70: 68fb ldr r3, [r7, #12] + 8004f72: 601a str r2, [r3, #0] + memp_tab[type] = memp; + 8004f74: 1dfb adds r3, r7, #7 + 8004f76: 781a ldrb r2, [r3, #0] + 8004f78: 4b05 ldr r3, [pc, #20] ; (8004f90 ) + 8004f7a: 0092 lsls r2, r2, #2 + 8004f7c: 68f9 ldr r1, [r7, #12] + 8004f7e: 50d1 str r1, [r2, r3] + 8004f80: e000 b.n 8004f84 + return; + 8004f82: 46c0 nop ; (mov r8, r8) +#if MEMP_SANITY_CHECK + LWIP_ASSERT("memp sanity", memp_sanity()); +#endif /* MEMP_SANITY_CHECK */ + + SYS_ARCH_UNPROTECT(old_level); +} + 8004f84: 46bd mov sp, r7 + 8004f86: b005 add sp, #20 + 8004f88: bd90 pop {r4, r7, pc} + 8004f8a: 46c0 nop ; (mov r8, r8) + 8004f8c: 20003158 .word 0x20003158 + 8004f90: 20000158 .word 0x20000158 + +08004f94 : +} +#endif /* LWIP_HAVE_LOOPIF */ + +void +netif_init(void) +{ + 8004f94: b580 push {r7, lr} + 8004f96: af00 add r7, sp, #0 + netif_add(&loop_netif, &loop_ipaddr, &loop_netmask, &loop_gw, NULL, netif_loopif_init, tcpip_input); +#endif /* NO_SYS */ + netif_set_up(&loop_netif); + +#endif /* LWIP_HAVE_LOOPIF */ +} + 8004f98: 46c0 nop ; (mov r8, r8) + 8004f9a: 46bd mov sp, r7 + 8004f9c: bd80 pop {r7, pc} + ... + +08004fa0 : + * @return netif, or NULL if failed. + */ +struct netif * +netif_add(struct netif *netif, ip_addr_t *ipaddr, ip_addr_t *netmask, + ip_addr_t *gw, void *state, netif_init_fn init, netif_input_fn input) +{ + 8004fa0: b580 push {r7, lr} + 8004fa2: b084 sub sp, #16 + 8004fa4: af00 add r7, sp, #0 + 8004fa6: 60f8 str r0, [r7, #12] + 8004fa8: 60b9 str r1, [r7, #8] + 8004faa: 607a str r2, [r7, #4] + 8004fac: 603b str r3, [r7, #0] + + LWIP_ASSERT("No init function given", init != NULL); + + /* reset new interface configuration state */ + ip_addr_set_zero(&netif->ip_addr); + 8004fae: 68fb ldr r3, [r7, #12] + 8004fb0: 2200 movs r2, #0 + 8004fb2: 605a str r2, [r3, #4] + ip_addr_set_zero(&netif->netmask); + 8004fb4: 68fb ldr r3, [r7, #12] + 8004fb6: 2200 movs r2, #0 + 8004fb8: 609a str r2, [r3, #8] + ip_addr_set_zero(&netif->gw); + 8004fba: 68fb ldr r3, [r7, #12] + 8004fbc: 2200 movs r2, #0 + 8004fbe: 60da str r2, [r3, #12] + netif->flags = 0; + 8004fc0: 68fb ldr r3, [r7, #12] + 8004fc2: 2229 movs r2, #41 ; 0x29 + 8004fc4: 2100 movs r1, #0 + 8004fc6: 5499 strb r1, [r3, r2] + netif->loop_first = NULL; + netif->loop_last = NULL; +#endif /* ENABLE_LOOPBACK */ + + /* remember netif specific state information data */ + netif->state = state; + 8004fc8: 68fb ldr r3, [r7, #12] + 8004fca: 69ba ldr r2, [r7, #24] + 8004fcc: 61da str r2, [r3, #28] + netif->num = netif_num++; + 8004fce: 4b13 ldr r3, [pc, #76] ; (800501c ) + 8004fd0: 781b ldrb r3, [r3, #0] + 8004fd2: 1c5a adds r2, r3, #1 + 8004fd4: b2d1 uxtb r1, r2 + 8004fd6: 4a11 ldr r2, [pc, #68] ; (800501c ) + 8004fd8: 7011 strb r1, [r2, #0] + 8004fda: 68fa ldr r2, [r7, #12] + 8004fdc: 212c movs r1, #44 ; 0x2c + 8004fde: 5453 strb r3, [r2, r1] + netif->input = input; + 8004fe0: 68fb ldr r3, [r7, #12] + 8004fe2: 6a3a ldr r2, [r7, #32] + 8004fe4: 611a str r2, [r3, #16] + NETIF_SET_HWADDRHINT(netif, NULL); +#if ENABLE_LOOPBACK && LWIP_LOOPBACK_MAX_PBUFS + netif->loop_cnt_current = 0; +#endif /* ENABLE_LOOPBACK && LWIP_LOOPBACK_MAX_PBUFS */ + + netif_set_addr(netif, ipaddr, netmask, gw); + 8004fe6: 683b ldr r3, [r7, #0] + 8004fe8: 687a ldr r2, [r7, #4] + 8004fea: 68b9 ldr r1, [r7, #8] + 8004fec: 68f8 ldr r0, [r7, #12] + 8004fee: f000 f819 bl 8005024 + + /* call user specified initialization function for netif */ + if (init(netif) != ERR_OK) { + 8004ff2: 68fa ldr r2, [r7, #12] + 8004ff4: 69fb ldr r3, [r7, #28] + 8004ff6: 0010 movs r0, r2 + 8004ff8: 4798 blx r3 + 8004ffa: 1e03 subs r3, r0, #0 + 8004ffc: d001 beq.n 8005002 + return NULL; + 8004ffe: 2300 movs r3, #0 + 8005000: e007 b.n 8005012 + } + + /* add this netif to the list */ + netif->next = netif_list; + 8005002: 4b07 ldr r3, [pc, #28] ; (8005020 ) + 8005004: 681a ldr r2, [r3, #0] + 8005006: 68fb ldr r3, [r7, #12] + 8005008: 601a str r2, [r3, #0] + netif_list = netif; + 800500a: 4b05 ldr r3, [pc, #20] ; (8005020 ) + 800500c: 68fa ldr r2, [r7, #12] + 800500e: 601a str r2, [r3, #0] + LWIP_DEBUGF(NETIF_DEBUG, (" netmask ")); + ip_addr_debug_print(NETIF_DEBUG, netmask); + LWIP_DEBUGF(NETIF_DEBUG, (" gw ")); + ip_addr_debug_print(NETIF_DEBUG, gw); + LWIP_DEBUGF(NETIF_DEBUG, ("\n")); + return netif; + 8005010: 68fb ldr r3, [r7, #12] +} + 8005012: 0018 movs r0, r3 + 8005014: 46bd mov sp, r7 + 8005016: b004 add sp, #16 + 8005018: bd80 pop {r7, pc} + 800501a: 46c0 nop ; (mov r8, r8) + 800501c: 20002273 .word 0x20002273 + 8005020: 2000314c .word 0x2000314c + +08005024 : + * @param gw the new default gateway + */ +void +netif_set_addr(struct netif *netif, ip_addr_t *ipaddr, ip_addr_t *netmask, + ip_addr_t *gw) +{ + 8005024: b580 push {r7, lr} + 8005026: b084 sub sp, #16 + 8005028: af00 add r7, sp, #0 + 800502a: 60f8 str r0, [r7, #12] + 800502c: 60b9 str r1, [r7, #8] + 800502e: 607a str r2, [r7, #4] + 8005030: 603b str r3, [r7, #0] + netif_set_ipaddr(netif, ipaddr); + 8005032: 68ba ldr r2, [r7, #8] + 8005034: 68fb ldr r3, [r7, #12] + 8005036: 0011 movs r1, r2 + 8005038: 0018 movs r0, r3 + 800503a: f000 f811 bl 8005060 + netif_set_netmask(netif, netmask); + 800503e: 687a ldr r2, [r7, #4] + 8005040: 68fb ldr r3, [r7, #12] + 8005042: 0011 movs r1, r2 + 8005044: 0018 movs r0, r3 + 8005046: f000 f877 bl 8005138 + netif_set_gw(netif, gw); + 800504a: 683a ldr r2, [r7, #0] + 800504c: 68fb ldr r3, [r7, #12] + 800504e: 0011 movs r1, r2 + 8005050: 0018 movs r0, r3 + 8005052: f000 f85f bl 8005114 +} + 8005056: 46c0 nop ; (mov r8, r8) + 8005058: 46bd mov sp, r7 + 800505a: b004 add sp, #16 + 800505c: bd80 pop {r7, pc} + ... + +08005060 : + * @note call netif_set_addr() if you also want to change netmask and + * default gateway + */ +void +netif_set_ipaddr(struct netif *netif, ip_addr_t *ipaddr) +{ + 8005060: b580 push {r7, lr} + 8005062: b086 sub sp, #24 + 8005064: af00 add r7, sp, #0 + 8005066: 6078 str r0, [r7, #4] + 8005068: 6039 str r1, [r7, #0] +#if LWIP_TCP + struct tcp_pcb *pcb; + struct tcp_pcb_listen *lpcb; + + /* address is actually being changed? */ + if (ipaddr && (ip_addr_cmp(ipaddr, &(netif->ip_addr))) == 0) { + 800506a: 683b ldr r3, [r7, #0] + 800506c: 2b00 cmp r3, #0 + 800506e: d03f beq.n 80050f0 + 8005070: 683b ldr r3, [r7, #0] + 8005072: 681a ldr r2, [r3, #0] + 8005074: 687b ldr r3, [r7, #4] + 8005076: 685b ldr r3, [r3, #4] + 8005078: 429a cmp r2, r3 + 800507a: d039 beq.n 80050f0 + /* extern struct tcp_pcb *tcp_active_pcbs; defined by tcp.h */ + LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_STATE, ("netif_set_ipaddr: netif address being changed\n")); + pcb = tcp_active_pcbs; + 800507c: 4b23 ldr r3, [pc, #140] ; (800510c ) + 800507e: 681b ldr r3, [r3, #0] + 8005080: 617b str r3, [r7, #20] + while (pcb != NULL) { + 8005082: e012 b.n 80050aa + /* PCB bound to current local interface address? */ + if (ip_addr_cmp(&(pcb->local_ip), &(netif->ip_addr)) + 8005084: 697b ldr r3, [r7, #20] + 8005086: 681a ldr r2, [r3, #0] + 8005088: 687b ldr r3, [r7, #4] + 800508a: 685b ldr r3, [r3, #4] + 800508c: 429a cmp r2, r3 + 800508e: d109 bne.n 80050a4 + /* connections to link-local addresses must persist (RFC3927 ch. 1.9) */ + && !ip_addr_islinklocal(&(pcb->local_ip)) +#endif /* LWIP_AUTOIP */ + ) { + /* this connection must be aborted */ + struct tcp_pcb *next = pcb->next; + 8005090: 697b ldr r3, [r7, #20] + 8005092: 68db ldr r3, [r3, #12] + 8005094: 60fb str r3, [r7, #12] + LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_STATE, ("netif_set_ipaddr: aborting TCP pcb %p\n", (void *)pcb)); + tcp_abort(pcb); + 8005096: 697b ldr r3, [r7, #20] + 8005098: 0018 movs r0, r3 + 800509a: f000 ff6f bl 8005f7c + pcb = next; + 800509e: 68fb ldr r3, [r7, #12] + 80050a0: 617b str r3, [r7, #20] + 80050a2: e002 b.n 80050aa + } else { + pcb = pcb->next; + 80050a4: 697b ldr r3, [r7, #20] + 80050a6: 68db ldr r3, [r3, #12] + 80050a8: 617b str r3, [r7, #20] + while (pcb != NULL) { + 80050aa: 697b ldr r3, [r7, #20] + 80050ac: 2b00 cmp r3, #0 + 80050ae: d1e9 bne.n 8005084 + } + } + for (lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next) { + 80050b0: 4b17 ldr r3, [pc, #92] ; (8005110 ) + 80050b2: 681b ldr r3, [r3, #0] + 80050b4: 613b str r3, [r7, #16] + 80050b6: e018 b.n 80050ea + /* PCB bound to current local interface address? */ + if ((!(ip_addr_isany(&(lpcb->local_ip)))) && + 80050b8: 693b ldr r3, [r7, #16] + 80050ba: 2b00 cmp r3, #0 + 80050bc: d012 beq.n 80050e4 + 80050be: 693b ldr r3, [r7, #16] + 80050c0: 681b ldr r3, [r3, #0] + 80050c2: 2b00 cmp r3, #0 + 80050c4: d00e beq.n 80050e4 + (ip_addr_cmp(&(lpcb->local_ip), &(netif->ip_addr)))) { + 80050c6: 693b ldr r3, [r7, #16] + 80050c8: 681a ldr r2, [r3, #0] + 80050ca: 687b ldr r3, [r7, #4] + 80050cc: 685b ldr r3, [r3, #4] + if ((!(ip_addr_isany(&(lpcb->local_ip)))) && + 80050ce: 429a cmp r2, r3 + 80050d0: d108 bne.n 80050e4 + /* The PCB is listening to the old ipaddr and + * is set to listen to the new one instead */ + ip_addr_set(&(lpcb->local_ip), ipaddr); + 80050d2: 683b ldr r3, [r7, #0] + 80050d4: 2b00 cmp r3, #0 + 80050d6: d002 beq.n 80050de + 80050d8: 683b ldr r3, [r7, #0] + 80050da: 681a ldr r2, [r3, #0] + 80050dc: e000 b.n 80050e0 + 80050de: 2200 movs r2, #0 + 80050e0: 693b ldr r3, [r7, #16] + 80050e2: 601a str r2, [r3, #0] + for (lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next) { + 80050e4: 693b ldr r3, [r7, #16] + 80050e6: 68db ldr r3, [r3, #12] + 80050e8: 613b str r3, [r7, #16] + 80050ea: 693b ldr r3, [r7, #16] + 80050ec: 2b00 cmp r3, #0 + 80050ee: d1e3 bne.n 80050b8 + } +#endif + snmp_delete_ipaddridx_tree(netif); + snmp_delete_iprteidx_tree(0,netif); + /* set new IP address to netif */ + ip_addr_set(&(netif->ip_addr), ipaddr); + 80050f0: 683b ldr r3, [r7, #0] + 80050f2: 2b00 cmp r3, #0 + 80050f4: d002 beq.n 80050fc + 80050f6: 683b ldr r3, [r7, #0] + 80050f8: 681a ldr r2, [r3, #0] + 80050fa: e000 b.n 80050fe + 80050fc: 2200 movs r2, #0 + 80050fe: 687b ldr r3, [r7, #4] + 8005100: 605a str r2, [r3, #4] + netif->name[0], netif->name[1], + ip4_addr1_16(&netif->ip_addr), + ip4_addr2_16(&netif->ip_addr), + ip4_addr3_16(&netif->ip_addr), + ip4_addr4_16(&netif->ip_addr))); +} + 8005102: 46c0 nop ; (mov r8, r8) + 8005104: 46bd mov sp, r7 + 8005106: b006 add sp, #24 + 8005108: bd80 pop {r7, pc} + 800510a: 46c0 nop ; (mov r8, r8) + 800510c: 20003274 .word 0x20003274 + 8005110: 2000327c .word 0x2000327c + +08005114 : + * + * @note call netif_set_addr() if you also want to change ip address and netmask + */ +void +netif_set_gw(struct netif *netif, ip_addr_t *gw) +{ + 8005114: b580 push {r7, lr} + 8005116: b082 sub sp, #8 + 8005118: af00 add r7, sp, #0 + 800511a: 6078 str r0, [r7, #4] + 800511c: 6039 str r1, [r7, #0] + ip_addr_set(&(netif->gw), gw); + 800511e: 683b ldr r3, [r7, #0] + 8005120: 2b00 cmp r3, #0 + 8005122: d002 beq.n 800512a + 8005124: 683b ldr r3, [r7, #0] + 8005126: 681a ldr r2, [r3, #0] + 8005128: e000 b.n 800512c + 800512a: 2200 movs r2, #0 + 800512c: 687b ldr r3, [r7, #4] + 800512e: 60da str r2, [r3, #12] + netif->name[0], netif->name[1], + ip4_addr1_16(&netif->gw), + ip4_addr2_16(&netif->gw), + ip4_addr3_16(&netif->gw), + ip4_addr4_16(&netif->gw))); +} + 8005130: 46c0 nop ; (mov r8, r8) + 8005132: 46bd mov sp, r7 + 8005134: b002 add sp, #8 + 8005136: bd80 pop {r7, pc} + +08005138 : + * @note call netif_set_addr() if you also want to change ip address and + * default gateway + */ +void +netif_set_netmask(struct netif *netif, ip_addr_t *netmask) +{ + 8005138: b580 push {r7, lr} + 800513a: b082 sub sp, #8 + 800513c: af00 add r7, sp, #0 + 800513e: 6078 str r0, [r7, #4] + 8005140: 6039 str r1, [r7, #0] + snmp_delete_iprteidx_tree(0, netif); + /* set new netmask to netif */ + ip_addr_set(&(netif->netmask), netmask); + 8005142: 683b ldr r3, [r7, #0] + 8005144: 2b00 cmp r3, #0 + 8005146: d002 beq.n 800514e + 8005148: 683b ldr r3, [r7, #0] + 800514a: 681a ldr r2, [r3, #0] + 800514c: e000 b.n 8005150 + 800514e: 2200 movs r2, #0 + 8005150: 687b ldr r3, [r7, #4] + 8005152: 609a str r2, [r3, #8] + netif->name[0], netif->name[1], + ip4_addr1_16(&netif->netmask), + ip4_addr2_16(&netif->netmask), + ip4_addr3_16(&netif->netmask), + ip4_addr4_16(&netif->netmask))); +} + 8005154: 46c0 nop ; (mov r8, r8) + 8005156: 46bd mov sp, r7 + 8005158: b002 add sp, #8 + 800515a: bd80 pop {r7, pc} + +0800515c : + * + * @param netif the default network interface + */ +void +netif_set_default(struct netif *netif) +{ + 800515c: b580 push {r7, lr} + 800515e: b082 sub sp, #8 + 8005160: af00 add r7, sp, #0 + 8005162: 6078 str r0, [r7, #4] + snmp_delete_iprteidx_tree(1, netif); + } else { + /* install default route */ + snmp_insert_iprteidx_tree(1, netif); + } + netif_default = netif; + 8005164: 4b03 ldr r3, [pc, #12] ; (8005174 ) + 8005166: 687a ldr r2, [r7, #4] + 8005168: 601a str r2, [r3, #0] + LWIP_DEBUGF(NETIF_DEBUG, ("netif: setting default interface %c%c\n", + netif ? netif->name[0] : '\'', netif ? netif->name[1] : '\'')); +} + 800516a: 46c0 nop ; (mov r8, r8) + 800516c: 46bd mov sp, r7 + 800516e: b002 add sp, #8 + 8005170: bd80 pop {r7, pc} + 8005172: 46c0 nop ; (mov r8, r8) + 8005174: 20003150 .word 0x20003150 + +08005178 : +#endif /* !NO_SYS */ + +/** Queue a call to pbuf_free_ooseq if not already queued. */ +static void +pbuf_pool_is_empty(void) +{ + 8005178: b580 push {r7, lr} + 800517a: af00 add r7, sp, #0 +#ifndef PBUF_POOL_FREE_OOSEQ_QUEUE_CALL + SYS_ARCH_DECL_PROTECT(old_level); + SYS_ARCH_PROTECT(old_level); + pbuf_free_ooseq_pending = 1; + 800517c: 4b02 ldr r3, [pc, #8] ; (8005188 ) + 800517e: 2201 movs r2, #1 + 8005180: 701a strb r2, [r3, #0] + if(!queued) { + /* queue a call to pbuf_free_ooseq if not already queued */ + PBUF_POOL_FREE_OOSEQ_QUEUE_CALL(); + } +#endif /* PBUF_POOL_FREE_OOSEQ_QUEUE_CALL */ +} + 8005182: 46c0 nop ; (mov r8, r8) + 8005184: 46bd mov sp, r7 + 8005186: bd80 pop {r7, pc} + 8005188: 20003154 .word 0x20003154 + +0800518c : + * @return the allocated pbuf. If multiple pbufs where allocated, this + * is the first pbuf of a pbuf chain. + */ +struct pbuf * +pbuf_alloc(pbuf_layer layer, u16_t length, pbuf_type type) +{ + 800518c: b590 push {r4, r7, lr} + 800518e: b089 sub sp, #36 ; 0x24 + 8005190: af00 add r7, sp, #0 + 8005192: 0004 movs r4, r0 + 8005194: 0008 movs r0, r1 + 8005196: 0011 movs r1, r2 + 8005198: 1dfb adds r3, r7, #7 + 800519a: 1c22 adds r2, r4, #0 + 800519c: 701a strb r2, [r3, #0] + 800519e: 1d3b adds r3, r7, #4 + 80051a0: 1c02 adds r2, r0, #0 + 80051a2: 801a strh r2, [r3, #0] + 80051a4: 1dbb adds r3, r7, #6 + 80051a6: 1c0a adds r2, r1, #0 + 80051a8: 701a strb r2, [r3, #0] + u16_t offset; + s32_t rem_len; /* remaining length */ + LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_alloc(length=%"U16_F")\n", length)); + + /* determine header offset */ + switch (layer) { + 80051aa: 1dfb adds r3, r7, #7 + 80051ac: 781b ldrb r3, [r3, #0] + 80051ae: 2b01 cmp r3, #1 + 80051b0: d00d beq.n 80051ce + 80051b2: dc02 bgt.n 80051ba + 80051b4: 2b00 cmp r3, #0 + 80051b6: d005 beq.n 80051c4 + 80051b8: e018 b.n 80051ec + 80051ba: 2b02 cmp r3, #2 + 80051bc: d00c beq.n 80051d8 + 80051be: 2b03 cmp r3, #3 + 80051c0: d00f beq.n 80051e2 + 80051c2: e013 b.n 80051ec + case PBUF_TRANSPORT: + /* add room for transport (often TCP) layer header */ + offset = PBUF_LINK_HLEN + PBUF_IP_HLEN + PBUF_TRANSPORT_HLEN; + 80051c4: 2316 movs r3, #22 + 80051c6: 18fb adds r3, r7, r3 + 80051c8: 2236 movs r2, #54 ; 0x36 + 80051ca: 801a strh r2, [r3, #0] + break; + 80051cc: e010 b.n 80051f0 + case PBUF_IP: + /* add room for IP layer header */ + offset = PBUF_LINK_HLEN + PBUF_IP_HLEN; + 80051ce: 2316 movs r3, #22 + 80051d0: 18fb adds r3, r7, r3 + 80051d2: 2222 movs r2, #34 ; 0x22 + 80051d4: 801a strh r2, [r3, #0] + break; + 80051d6: e00b b.n 80051f0 + case PBUF_LINK: + /* add room for link layer header */ + offset = PBUF_LINK_HLEN; + 80051d8: 2316 movs r3, #22 + 80051da: 18fb adds r3, r7, r3 + 80051dc: 220e movs r2, #14 + 80051de: 801a strh r2, [r3, #0] + break; + 80051e0: e006 b.n 80051f0 + case PBUF_RAW: + offset = 0; + 80051e2: 2316 movs r3, #22 + 80051e4: 18fb adds r3, r7, r3 + 80051e6: 2200 movs r2, #0 + 80051e8: 801a strh r2, [r3, #0] + break; + 80051ea: e001 b.n 80051f0 + default: + LWIP_ASSERT("pbuf_alloc: bad pbuf layer", 0); + return NULL; + 80051ec: 2300 movs r3, #0 + 80051ee: e0e9 b.n 80053c4 + } + + switch (type) { + 80051f0: 1dbb adds r3, r7, #6 + 80051f2: 781b ldrb r3, [r3, #0] + 80051f4: 2b02 cmp r3, #2 + 80051f6: dc06 bgt.n 8005206 + 80051f8: 2b01 cmp r3, #1 + 80051fa: db00 blt.n 80051fe + 80051fc: e0bc b.n 8005378 + 80051fe: 2b00 cmp r3, #0 + 8005200: d100 bne.n 8005204 + 8005202: e082 b.n 800530a + 8005204: e0d5 b.n 80053b2 + 8005206: 2b03 cmp r3, #3 + 8005208: d000 beq.n 800520c + 800520a: e0d2 b.n 80053b2 + case PBUF_POOL: + /* allocate head of pbuf chain into p */ + p = (struct pbuf *)memp_malloc(MEMP_PBUF_POOL); + 800520c: 2009 movs r0, #9 + 800520e: f7ff fe01 bl 8004e14 + 8005212: 0003 movs r3, r0 + 8005214: 61fb str r3, [r7, #28] + LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_alloc: allocated pbuf %p\n", (void *)p)); + if (p == NULL) { + 8005216: 69fb ldr r3, [r7, #28] + 8005218: 2b00 cmp r3, #0 + 800521a: d103 bne.n 8005224 + PBUF_POOL_IS_EMPTY(); + 800521c: f7ff ffac bl 8005178 + return NULL; + 8005220: 2300 movs r3, #0 + 8005222: e0cf b.n 80053c4 + } + p->type = type; + 8005224: 69fb ldr r3, [r7, #28] + 8005226: 1dba adds r2, r7, #6 + 8005228: 7812 ldrb r2, [r2, #0] + 800522a: 731a strb r2, [r3, #12] + p->next = NULL; + 800522c: 69fb ldr r3, [r7, #28] + 800522e: 2200 movs r2, #0 + 8005230: 601a str r2, [r3, #0] + + /* make the payload pointer point 'offset' bytes into pbuf data memory */ + p->payload = LWIP_MEM_ALIGN((void *)((u8_t *)p + (SIZEOF_STRUCT_PBUF + offset))); + 8005232: 2116 movs r1, #22 + 8005234: 187b adds r3, r7, r1 + 8005236: 881b ldrh r3, [r3, #0] + 8005238: 3310 adds r3, #16 + 800523a: 69fa ldr r2, [r7, #28] + 800523c: 18d3 adds r3, r2, r3 + 800523e: 3303 adds r3, #3 + 8005240: 2203 movs r2, #3 + 8005242: 4393 bics r3, r2 + 8005244: 001a movs r2, r3 + 8005246: 69fb ldr r3, [r7, #28] + 8005248: 605a str r2, [r3, #4] + LWIP_ASSERT("pbuf_alloc: pbuf p->payload properly aligned", + ((mem_ptr_t)p->payload % MEM_ALIGNMENT) == 0); + /* the total length of the pbuf chain is the requested size */ + p->tot_len = length; + 800524a: 69fb ldr r3, [r7, #28] + 800524c: 1d3a adds r2, r7, #4 + 800524e: 8812 ldrh r2, [r2, #0] + 8005250: 811a strh r2, [r3, #8] + /* set the length of the first pbuf in the chain */ + p->len = LWIP_MIN(length, PBUF_POOL_BUFSIZE_ALIGNED - LWIP_MEM_ALIGN_SIZE(offset)); + 8005252: 187b adds r3, r7, r1 + 8005254: 881b ldrh r3, [r3, #0] + 8005256: 3303 adds r3, #3 + 8005258: 2203 movs r2, #3 + 800525a: 4393 bics r3, r2 + 800525c: 4a5b ldr r2, [pc, #364] ; (80053cc ) + 800525e: 1ad2 subs r2, r2, r3 + 8005260: 1d3b adds r3, r7, #4 + 8005262: 881b ldrh r3, [r3, #0] + 8005264: 429a cmp r2, r3 + 8005266: dd00 ble.n 800526a + 8005268: 001a movs r2, r3 + 800526a: b292 uxth r2, r2 + 800526c: 69fb ldr r3, [r7, #28] + 800526e: 815a strh r2, [r3, #10] + ((u8_t*)p->payload + p->len <= + (u8_t*)p + SIZEOF_STRUCT_PBUF + PBUF_POOL_BUFSIZE_ALIGNED)); + LWIP_ASSERT("PBUF_POOL_BUFSIZE must be bigger than MEM_ALIGNMENT", + (PBUF_POOL_BUFSIZE_ALIGNED - LWIP_MEM_ALIGN_SIZE(offset)) > 0 ); + /* set reference count (needed here in case we fail) */ + p->ref = 1; + 8005270: 69fb ldr r3, [r7, #28] + 8005272: 2201 movs r2, #1 + 8005274: 81da strh r2, [r3, #14] + + /* now allocate the tail of the pbuf chain */ + + /* remember first pbuf for linkage in next iteration */ + r = p; + 8005276: 69fb ldr r3, [r7, #28] + 8005278: 61bb str r3, [r7, #24] + /* remaining length to be allocated */ + rem_len = length - p->len; + 800527a: 1d3b adds r3, r7, #4 + 800527c: 881b ldrh r3, [r3, #0] + 800527e: 69fa ldr r2, [r7, #28] + 8005280: 8952 ldrh r2, [r2, #10] + 8005282: 1a9b subs r3, r3, r2 + 8005284: 613b str r3, [r7, #16] + /* any remaining pbufs to be allocated? */ + while (rem_len > 0) { + 8005286: e03c b.n 8005302 + q = (struct pbuf *)memp_malloc(MEMP_PBUF_POOL); + 8005288: 2009 movs r0, #9 + 800528a: f7ff fdc3 bl 8004e14 + 800528e: 0003 movs r3, r0 + 8005290: 60fb str r3, [r7, #12] + if (q == NULL) { + 8005292: 68fb ldr r3, [r7, #12] + 8005294: 2b00 cmp r3, #0 + 8005296: d107 bne.n 80052a8 + PBUF_POOL_IS_EMPTY(); + 8005298: f7ff ff6e bl 8005178 + /* free chain so far allocated */ + pbuf_free(p); + 800529c: 69fb ldr r3, [r7, #28] + 800529e: 0018 movs r0, r3 + 80052a0: f000 fa00 bl 80056a4 + /* bail out unsuccesfully */ + return NULL; + 80052a4: 2300 movs r3, #0 + 80052a6: e08d b.n 80053c4 + } + q->type = type; + 80052a8: 68fb ldr r3, [r7, #12] + 80052aa: 1dba adds r2, r7, #6 + 80052ac: 7812 ldrb r2, [r2, #0] + 80052ae: 731a strb r2, [r3, #12] + q->flags = 0; + 80052b0: 68fb ldr r3, [r7, #12] + 80052b2: 2200 movs r2, #0 + 80052b4: 735a strb r2, [r3, #13] + q->next = NULL; + 80052b6: 68fb ldr r3, [r7, #12] + 80052b8: 2200 movs r2, #0 + 80052ba: 601a str r2, [r3, #0] + /* make previous pbuf point to this pbuf */ + r->next = q; + 80052bc: 69bb ldr r3, [r7, #24] + 80052be: 68fa ldr r2, [r7, #12] + 80052c0: 601a str r2, [r3, #0] + /* set total length of this pbuf and next in chain */ + LWIP_ASSERT("rem_len < max_u16_t", rem_len < 0xffff); + q->tot_len = (u16_t)rem_len; + 80052c2: 693b ldr r3, [r7, #16] + 80052c4: b29a uxth r2, r3 + 80052c6: 68fb ldr r3, [r7, #12] + 80052c8: 811a strh r2, [r3, #8] + /* this pbuf length is pool size, unless smaller sized tail */ + q->len = LWIP_MIN((u16_t)rem_len, PBUF_POOL_BUFSIZE_ALIGNED); + 80052ca: 693b ldr r3, [r7, #16] + 80052cc: b29b uxth r3, r3 + 80052ce: 1c19 adds r1, r3, #0 + 80052d0: b28b uxth r3, r1 + 80052d2: 4a3e ldr r2, [pc, #248] ; (80053cc ) + 80052d4: 4293 cmp r3, r2 + 80052d6: d901 bls.n 80052dc + 80052d8: 4b3c ldr r3, [pc, #240] ; (80053cc ) + 80052da: 1c19 adds r1, r3, #0 + 80052dc: b28a uxth r2, r1 + 80052de: 68fb ldr r3, [r7, #12] + 80052e0: 815a strh r2, [r3, #10] + q->payload = (void *)((u8_t *)q + SIZEOF_STRUCT_PBUF); + 80052e2: 68fb ldr r3, [r7, #12] + 80052e4: 3310 adds r3, #16 + 80052e6: 001a movs r2, r3 + 80052e8: 68fb ldr r3, [r7, #12] + 80052ea: 605a str r2, [r3, #4] + LWIP_ASSERT("pbuf_alloc: pbuf q->payload properly aligned", + ((mem_ptr_t)q->payload % MEM_ALIGNMENT) == 0); + LWIP_ASSERT("check p->payload + p->len does not overflow pbuf", + ((u8_t*)p->payload + p->len <= + (u8_t*)p + SIZEOF_STRUCT_PBUF + PBUF_POOL_BUFSIZE_ALIGNED)); + q->ref = 1; + 80052ec: 68fb ldr r3, [r7, #12] + 80052ee: 2201 movs r2, #1 + 80052f0: 81da strh r2, [r3, #14] + /* calculate remaining length to be allocated */ + rem_len -= q->len; + 80052f2: 68fb ldr r3, [r7, #12] + 80052f4: 895b ldrh r3, [r3, #10] + 80052f6: 001a movs r2, r3 + 80052f8: 693b ldr r3, [r7, #16] + 80052fa: 1a9b subs r3, r3, r2 + 80052fc: 613b str r3, [r7, #16] + /* remember this pbuf for linkage in next iteration */ + r = q; + 80052fe: 68fb ldr r3, [r7, #12] + 8005300: 61bb str r3, [r7, #24] + while (rem_len > 0) { + 8005302: 693b ldr r3, [r7, #16] + 8005304: 2b00 cmp r3, #0 + 8005306: dcbf bgt.n 8005288 + } + /* end of chain */ + /*r->next = NULL;*/ + + break; + 8005308: e055 b.n 80053b6 + case PBUF_RAM: + /* If pbuf is to be allocated in RAM, allocate memory for it. */ + p = (struct pbuf*)mem_malloc(LWIP_MEM_ALIGN_SIZE(SIZEOF_STRUCT_PBUF + offset) + LWIP_MEM_ALIGN_SIZE(length)); + 800530a: 2316 movs r3, #22 + 800530c: 18fb adds r3, r7, r3 + 800530e: 881b ldrh r3, [r3, #0] + 8005310: 3313 adds r3, #19 + 8005312: b29b uxth r3, r3 + 8005314: 2203 movs r2, #3 + 8005316: 4393 bics r3, r2 + 8005318: b29a uxth r2, r3 + 800531a: 1d3b adds r3, r7, #4 + 800531c: 881b ldrh r3, [r3, #0] + 800531e: 3303 adds r3, #3 + 8005320: b29b uxth r3, r3 + 8005322: 2103 movs r1, #3 + 8005324: 438b bics r3, r1 + 8005326: b29b uxth r3, r3 + 8005328: 18d3 adds r3, r2, r3 + 800532a: b29b uxth r3, r3 + 800532c: 0018 movs r0, r3 + 800532e: f7ff fbd1 bl 8004ad4 + 8005332: 0003 movs r3, r0 + 8005334: 61fb str r3, [r7, #28] + if (p == NULL) { + 8005336: 69fb ldr r3, [r7, #28] + 8005338: 2b00 cmp r3, #0 + 800533a: d101 bne.n 8005340 + return NULL; + 800533c: 2300 movs r3, #0 + 800533e: e041 b.n 80053c4 + } + /* Set up internal structure of the pbuf. */ + p->payload = LWIP_MEM_ALIGN((void *)((u8_t *)p + SIZEOF_STRUCT_PBUF + offset)); + 8005340: 2316 movs r3, #22 + 8005342: 18fb adds r3, r7, r3 + 8005344: 881b ldrh r3, [r3, #0] + 8005346: 3310 adds r3, #16 + 8005348: 69fa ldr r2, [r7, #28] + 800534a: 18d3 adds r3, r2, r3 + 800534c: 3303 adds r3, #3 + 800534e: 2203 movs r2, #3 + 8005350: 4393 bics r3, r2 + 8005352: 001a movs r2, r3 + 8005354: 69fb ldr r3, [r7, #28] + 8005356: 605a str r2, [r3, #4] + p->len = p->tot_len = length; + 8005358: 69fb ldr r3, [r7, #28] + 800535a: 1d3a adds r2, r7, #4 + 800535c: 8812 ldrh r2, [r2, #0] + 800535e: 811a strh r2, [r3, #8] + 8005360: 69fb ldr r3, [r7, #28] + 8005362: 891a ldrh r2, [r3, #8] + 8005364: 69fb ldr r3, [r7, #28] + 8005366: 815a strh r2, [r3, #10] + p->next = NULL; + 8005368: 69fb ldr r3, [r7, #28] + 800536a: 2200 movs r2, #0 + 800536c: 601a str r2, [r3, #0] + p->type = type; + 800536e: 69fb ldr r3, [r7, #28] + 8005370: 1dba adds r2, r7, #6 + 8005372: 7812 ldrb r2, [r2, #0] + 8005374: 731a strb r2, [r3, #12] + + LWIP_ASSERT("pbuf_alloc: pbuf->payload properly aligned", + ((mem_ptr_t)p->payload % MEM_ALIGNMENT) == 0); + break; + 8005376: e01e b.n 80053b6 + /* pbuf references existing (non-volatile static constant) ROM payload? */ + case PBUF_ROM: + /* pbuf references existing (externally allocated) RAM payload? */ + case PBUF_REF: + /* only allocate memory for the pbuf structure */ + p = (struct pbuf *)memp_malloc(MEMP_PBUF); + 8005378: 2008 movs r0, #8 + 800537a: f7ff fd4b bl 8004e14 + 800537e: 0003 movs r3, r0 + 8005380: 61fb str r3, [r7, #28] + if (p == NULL) { + 8005382: 69fb ldr r3, [r7, #28] + 8005384: 2b00 cmp r3, #0 + 8005386: d101 bne.n 800538c + LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_LEVEL_SERIOUS, + ("pbuf_alloc: Could not allocate MEMP_PBUF for PBUF_%s.\n", + (type == PBUF_ROM) ? "ROM" : "REF")); + return NULL; + 8005388: 2300 movs r3, #0 + 800538a: e01b b.n 80053c4 + } + /* caller must set this field properly, afterwards */ + p->payload = NULL; + 800538c: 69fb ldr r3, [r7, #28] + 800538e: 2200 movs r2, #0 + 8005390: 605a str r2, [r3, #4] + p->len = p->tot_len = length; + 8005392: 69fb ldr r3, [r7, #28] + 8005394: 1d3a adds r2, r7, #4 + 8005396: 8812 ldrh r2, [r2, #0] + 8005398: 811a strh r2, [r3, #8] + 800539a: 69fb ldr r3, [r7, #28] + 800539c: 891a ldrh r2, [r3, #8] + 800539e: 69fb ldr r3, [r7, #28] + 80053a0: 815a strh r2, [r3, #10] + p->next = NULL; + 80053a2: 69fb ldr r3, [r7, #28] + 80053a4: 2200 movs r2, #0 + 80053a6: 601a str r2, [r3, #0] + p->type = type; + 80053a8: 69fb ldr r3, [r7, #28] + 80053aa: 1dba adds r2, r7, #6 + 80053ac: 7812 ldrb r2, [r2, #0] + 80053ae: 731a strb r2, [r3, #12] + break; + 80053b0: e001 b.n 80053b6 + default: + LWIP_ASSERT("pbuf_alloc: erroneous type", 0); + return NULL; + 80053b2: 2300 movs r3, #0 + 80053b4: e006 b.n 80053c4 + } + /* set reference count */ + p->ref = 1; + 80053b6: 69fb ldr r3, [r7, #28] + 80053b8: 2201 movs r2, #1 + 80053ba: 81da strh r2, [r3, #14] + /* set flags */ + p->flags = 0; + 80053bc: 69fb ldr r3, [r7, #28] + 80053be: 2200 movs r2, #0 + 80053c0: 735a strb r2, [r3, #13] + LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_alloc(length=%"U16_F") == %p\n", length, (void *)p)); + return p; + 80053c2: 69fb ldr r3, [r7, #28] +} + 80053c4: 0018 movs r0, r3 + 80053c6: 46bd mov sp, r7 + 80053c8: b009 add sp, #36 ; 0x24 + 80053ca: bd90 pop {r4, r7, pc} + 80053cc: 000005ec .word 0x000005ec + +080053d0 : + * big enough to hold 'length' plus the header size + */ +struct pbuf* +pbuf_alloced_custom(pbuf_layer l, u16_t length, pbuf_type type, struct pbuf_custom *p, + void *payload_mem, u16_t payload_mem_len) +{ + 80053d0: b590 push {r4, r7, lr} + 80053d2: b085 sub sp, #20 + 80053d4: af00 add r7, sp, #0 + 80053d6: 0004 movs r4, r0 + 80053d8: 0008 movs r0, r1 + 80053da: 0011 movs r1, r2 + 80053dc: 603b str r3, [r7, #0] + 80053de: 1dfb adds r3, r7, #7 + 80053e0: 1c22 adds r2, r4, #0 + 80053e2: 701a strb r2, [r3, #0] + 80053e4: 1d3b adds r3, r7, #4 + 80053e6: 1c02 adds r2, r0, #0 + 80053e8: 801a strh r2, [r3, #0] + 80053ea: 1dbb adds r3, r7, #6 + 80053ec: 1c0a adds r2, r1, #0 + 80053ee: 701a strb r2, [r3, #0] + u16_t offset; + LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_alloced_custom(length=%"U16_F")\n", length)); + + /* determine header offset */ + switch (l) { + 80053f0: 1dfb adds r3, r7, #7 + 80053f2: 781b ldrb r3, [r3, #0] + 80053f4: 2b01 cmp r3, #1 + 80053f6: d00d beq.n 8005414 + 80053f8: dc02 bgt.n 8005400 + 80053fa: 2b00 cmp r3, #0 + 80053fc: d005 beq.n 800540a + 80053fe: e018 b.n 8005432 + 8005400: 2b02 cmp r3, #2 + 8005402: d00c beq.n 800541e + 8005404: 2b03 cmp r3, #3 + 8005406: d00f beq.n 8005428 + 8005408: e013 b.n 8005432 + case PBUF_TRANSPORT: + /* add room for transport (often TCP) layer header */ + offset = PBUF_LINK_HLEN + PBUF_IP_HLEN + PBUF_TRANSPORT_HLEN; + 800540a: 230e movs r3, #14 + 800540c: 18fb adds r3, r7, r3 + 800540e: 2236 movs r2, #54 ; 0x36 + 8005410: 801a strh r2, [r3, #0] + break; + 8005412: e010 b.n 8005436 + case PBUF_IP: + /* add room for IP layer header */ + offset = PBUF_LINK_HLEN + PBUF_IP_HLEN; + 8005414: 230e movs r3, #14 + 8005416: 18fb adds r3, r7, r3 + 8005418: 2222 movs r2, #34 ; 0x22 + 800541a: 801a strh r2, [r3, #0] + break; + 800541c: e00b b.n 8005436 + case PBUF_LINK: + /* add room for link layer header */ + offset = PBUF_LINK_HLEN; + 800541e: 230e movs r3, #14 + 8005420: 18fb adds r3, r7, r3 + 8005422: 220e movs r2, #14 + 8005424: 801a strh r2, [r3, #0] + break; + 8005426: e006 b.n 8005436 + case PBUF_RAW: + offset = 0; + 8005428: 230e movs r3, #14 + 800542a: 18fb adds r3, r7, r3 + 800542c: 2200 movs r2, #0 + 800542e: 801a strh r2, [r3, #0] + break; + 8005430: e001 b.n 8005436 + default: + LWIP_ASSERT("pbuf_alloced_custom: bad pbuf layer", 0); + return NULL; + 8005432: 2300 movs r3, #0 + 8005434: e039 b.n 80054aa + } + + if (LWIP_MEM_ALIGN_SIZE(offset) + length > payload_mem_len) { + 8005436: 230e movs r3, #14 + 8005438: 18fb adds r3, r7, r3 + 800543a: 881b ldrh r3, [r3, #0] + 800543c: 3303 adds r3, #3 + 800543e: 2203 movs r2, #3 + 8005440: 4393 bics r3, r2 + 8005442: 001a movs r2, r3 + 8005444: 1d3b adds r3, r7, #4 + 8005446: 881b ldrh r3, [r3, #0] + 8005448: 18d2 adds r2, r2, r3 + 800544a: 2324 movs r3, #36 ; 0x24 + 800544c: 18fb adds r3, r7, r3 + 800544e: 881b ldrh r3, [r3, #0] + 8005450: 429a cmp r2, r3 + 8005452: dd01 ble.n 8005458 + LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_LEVEL_WARNING, ("pbuf_alloced_custom(length=%"U16_F") buffer too short\n", length)); + return NULL; + 8005454: 2300 movs r3, #0 + 8005456: e028 b.n 80054aa + } + + p->pbuf.next = NULL; + 8005458: 683b ldr r3, [r7, #0] + 800545a: 2200 movs r2, #0 + 800545c: 601a str r2, [r3, #0] + if (payload_mem != NULL) { + 800545e: 6a3b ldr r3, [r7, #32] + 8005460: 2b00 cmp r3, #0 + 8005462: d00c beq.n 800547e + p->pbuf.payload = (u8_t *)payload_mem + LWIP_MEM_ALIGN_SIZE(offset); + 8005464: 230e movs r3, #14 + 8005466: 18fb adds r3, r7, r3 + 8005468: 881b ldrh r3, [r3, #0] + 800546a: 3303 adds r3, #3 + 800546c: 001a movs r2, r3 + 800546e: 2303 movs r3, #3 + 8005470: 439a bics r2, r3 + 8005472: 0013 movs r3, r2 + 8005474: 6a3a ldr r2, [r7, #32] + 8005476: 18d2 adds r2, r2, r3 + 8005478: 683b ldr r3, [r7, #0] + 800547a: 605a str r2, [r3, #4] + 800547c: e002 b.n 8005484 + } else { + p->pbuf.payload = NULL; + 800547e: 683b ldr r3, [r7, #0] + 8005480: 2200 movs r2, #0 + 8005482: 605a str r2, [r3, #4] + } + p->pbuf.flags = PBUF_FLAG_IS_CUSTOM; + 8005484: 683b ldr r3, [r7, #0] + 8005486: 2202 movs r2, #2 + 8005488: 735a strb r2, [r3, #13] + p->pbuf.len = p->pbuf.tot_len = length; + 800548a: 683b ldr r3, [r7, #0] + 800548c: 1d3a adds r2, r7, #4 + 800548e: 8812 ldrh r2, [r2, #0] + 8005490: 811a strh r2, [r3, #8] + 8005492: 683b ldr r3, [r7, #0] + 8005494: 891a ldrh r2, [r3, #8] + 8005496: 683b ldr r3, [r7, #0] + 8005498: 815a strh r2, [r3, #10] + p->pbuf.type = type; + 800549a: 683b ldr r3, [r7, #0] + 800549c: 1dba adds r2, r7, #6 + 800549e: 7812 ldrb r2, [r2, #0] + 80054a0: 731a strb r2, [r3, #12] + p->pbuf.ref = 1; + 80054a2: 683b ldr r3, [r7, #0] + 80054a4: 2201 movs r2, #1 + 80054a6: 81da strh r2, [r3, #14] + return &p->pbuf; + 80054a8: 683b ldr r3, [r7, #0] +} + 80054aa: 0018 movs r0, r3 + 80054ac: 46bd mov sp, r7 + 80054ae: b005 add sp, #20 + 80054b0: bd90 pop {r4, r7, pc} + +080054b2 : + * + * @note Despite its name, pbuf_realloc cannot grow the size of a pbuf (chain). + */ +void +pbuf_realloc(struct pbuf *p, u16_t new_len) +{ + 80054b2: b580 push {r7, lr} + 80054b4: b086 sub sp, #24 + 80054b6: af00 add r7, sp, #0 + 80054b8: 6078 str r0, [r7, #4] + 80054ba: 000a movs r2, r1 + 80054bc: 1cbb adds r3, r7, #2 + 80054be: 801a strh r2, [r3, #0] + struct pbuf *q; + u16_t rem_len; /* remaining length */ + s32_t grow; + + LWIP_ASSERT("pbuf_realloc: p != NULL", p != NULL); + LWIP_ASSERT("pbuf_realloc: sane p->type", p->type == PBUF_POOL || + 80054c0: 687b ldr r3, [r7, #4] + 80054c2: 7b1b ldrb r3, [r3, #12] + 80054c4: 2b03 cmp r3, #3 + 80054c6: d001 beq.n 80054cc + 80054c8: 687b ldr r3, [r7, #4] + 80054ca: 7b1b ldrb r3, [r3, #12] + p->type == PBUF_ROM || + p->type == PBUF_RAM || + p->type == PBUF_REF); + + /* desired length larger than current length? */ + if (new_len >= p->tot_len) { + 80054cc: 687b ldr r3, [r7, #4] + 80054ce: 891b ldrh r3, [r3, #8] + 80054d0: 1cba adds r2, r7, #2 + 80054d2: 8812 ldrh r2, [r2, #0] + 80054d4: 429a cmp r2, r3 + 80054d6: d25a bcs.n 800558e + return; + } + + /* the pbuf chain grows by (new_len - p->tot_len) bytes + * (which may be negative in case of shrinking) */ + grow = new_len - p->tot_len; + 80054d8: 1cbb adds r3, r7, #2 + 80054da: 881b ldrh r3, [r3, #0] + 80054dc: 687a ldr r2, [r7, #4] + 80054de: 8912 ldrh r2, [r2, #8] + 80054e0: 1a9b subs r3, r3, r2 + 80054e2: 60fb str r3, [r7, #12] + + /* first, step over any pbufs that should remain in the chain */ + rem_len = new_len; + 80054e4: 2312 movs r3, #18 + 80054e6: 18fb adds r3, r7, r3 + 80054e8: 1cba adds r2, r7, #2 + 80054ea: 8812 ldrh r2, [r2, #0] + 80054ec: 801a strh r2, [r3, #0] + q = p; + 80054ee: 687b ldr r3, [r7, #4] + 80054f0: 617b str r3, [r7, #20] + /* should this pbuf be kept? */ + while (rem_len > q->len) { + 80054f2: e012 b.n 800551a + /* decrease remaining length by pbuf length */ + rem_len -= q->len; + 80054f4: 697b ldr r3, [r7, #20] + 80054f6: 895a ldrh r2, [r3, #10] + 80054f8: 2112 movs r1, #18 + 80054fa: 187b adds r3, r7, r1 + 80054fc: 1879 adds r1, r7, r1 + 80054fe: 8809 ldrh r1, [r1, #0] + 8005500: 1a8a subs r2, r1, r2 + 8005502: 801a strh r2, [r3, #0] + /* decrease total length indicator */ + LWIP_ASSERT("grow < max_u16_t", grow < 0xffff); + q->tot_len += (u16_t)grow; + 8005504: 697b ldr r3, [r7, #20] + 8005506: 891a ldrh r2, [r3, #8] + 8005508: 68fb ldr r3, [r7, #12] + 800550a: b29b uxth r3, r3 + 800550c: 18d3 adds r3, r2, r3 + 800550e: b29a uxth r2, r3 + 8005510: 697b ldr r3, [r7, #20] + 8005512: 811a strh r2, [r3, #8] + /* proceed to next pbuf in chain */ + q = q->next; + 8005514: 697b ldr r3, [r7, #20] + 8005516: 681b ldr r3, [r3, #0] + 8005518: 617b str r3, [r7, #20] + while (rem_len > q->len) { + 800551a: 697b ldr r3, [r7, #20] + 800551c: 895b ldrh r3, [r3, #10] + 800551e: 2212 movs r2, #18 + 8005520: 18ba adds r2, r7, r2 + 8005522: 8812 ldrh r2, [r2, #0] + 8005524: 429a cmp r2, r3 + 8005526: d8e5 bhi.n 80054f4 + /* we have now reached the new last pbuf (in q) */ + /* rem_len == desired length for pbuf q */ + + /* shrink allocated memory for PBUF_RAM */ + /* (other types merely adjust their length fields */ + if ((q->type == PBUF_RAM) && (rem_len != q->len)) { + 8005528: 697b ldr r3, [r7, #20] + 800552a: 7b1b ldrb r3, [r3, #12] + 800552c: 2b00 cmp r3, #0 + 800552e: d118 bne.n 8005562 + 8005530: 697b ldr r3, [r7, #20] + 8005532: 895b ldrh r3, [r3, #10] + 8005534: 2212 movs r2, #18 + 8005536: 18ba adds r2, r7, r2 + 8005538: 8812 ldrh r2, [r2, #0] + 800553a: 429a cmp r2, r3 + 800553c: d011 beq.n 8005562 + /* reallocate and adjust the length of the pbuf that will be split */ + q = (struct pbuf *)mem_trim(q, (u16_t)((u8_t *)q->payload - (u8_t *)q) + rem_len); + 800553e: 697b ldr r3, [r7, #20] + 8005540: 685b ldr r3, [r3, #4] + 8005542: 001a movs r2, r3 + 8005544: 697b ldr r3, [r7, #20] + 8005546: 1ad3 subs r3, r2, r3 + 8005548: b29a uxth r2, r3 + 800554a: 2312 movs r3, #18 + 800554c: 18fb adds r3, r7, r3 + 800554e: 881b ldrh r3, [r3, #0] + 8005550: 18d3 adds r3, r2, r3 + 8005552: b29a uxth r2, r3 + 8005554: 697b ldr r3, [r7, #20] + 8005556: 0011 movs r1, r2 + 8005558: 0018 movs r0, r3 + 800555a: f7ff f9a7 bl 80048ac + 800555e: 0003 movs r3, r0 + 8005560: 617b str r3, [r7, #20] + LWIP_ASSERT("mem_trim returned q == NULL", q != NULL); + } + /* adjust length fields for new last pbuf */ + q->len = rem_len; + 8005562: 697b ldr r3, [r7, #20] + 8005564: 2212 movs r2, #18 + 8005566: 18ba adds r2, r7, r2 + 8005568: 8812 ldrh r2, [r2, #0] + 800556a: 815a strh r2, [r3, #10] + q->tot_len = q->len; + 800556c: 697b ldr r3, [r7, #20] + 800556e: 895a ldrh r2, [r3, #10] + 8005570: 697b ldr r3, [r7, #20] + 8005572: 811a strh r2, [r3, #8] + + /* any remaining pbufs in chain? */ + if (q->next != NULL) { + 8005574: 697b ldr r3, [r7, #20] + 8005576: 681b ldr r3, [r3, #0] + 8005578: 2b00 cmp r3, #0 + 800557a: d004 beq.n 8005586 + /* free remaining pbufs in chain */ + pbuf_free(q->next); + 800557c: 697b ldr r3, [r7, #20] + 800557e: 681b ldr r3, [r3, #0] + 8005580: 0018 movs r0, r3 + 8005582: f000 f88f bl 80056a4 + } + /* q is last packet in chain */ + q->next = NULL; + 8005586: 697b ldr r3, [r7, #20] + 8005588: 2200 movs r2, #0 + 800558a: 601a str r2, [r3, #0] + 800558c: e000 b.n 8005590 + return; + 800558e: 46c0 nop ; (mov r8, r8) + +} + 8005590: 46bd mov sp, r7 + 8005592: b006 add sp, #24 + 8005594: bd80 pop {r7, pc} + +08005596 : + * @return non-zero on failure, zero on success. + * + */ +u8_t +pbuf_header(struct pbuf *p, s16_t header_size_increment) +{ + 8005596: b580 push {r7, lr} + 8005598: b084 sub sp, #16 + 800559a: af00 add r7, sp, #0 + 800559c: 6078 str r0, [r7, #4] + 800559e: 000a movs r2, r1 + 80055a0: 1cbb adds r3, r7, #2 + 80055a2: 801a strh r2, [r3, #0] + u16_t type; + void *payload; + u16_t increment_magnitude; + + LWIP_ASSERT("p != NULL", p != NULL); + if ((header_size_increment == 0) || (p == NULL)) { + 80055a4: 1cbb adds r3, r7, #2 + 80055a6: 2200 movs r2, #0 + 80055a8: 5e9b ldrsh r3, [r3, r2] + 80055aa: 2b00 cmp r3, #0 + 80055ac: d002 beq.n 80055b4 + 80055ae: 687b ldr r3, [r7, #4] + 80055b0: 2b00 cmp r3, #0 + 80055b2: d101 bne.n 80055b8 + return 0; + 80055b4: 2300 movs r3, #0 + 80055b6: e071 b.n 800569c + } + + if (header_size_increment < 0){ + 80055b8: 1cbb adds r3, r7, #2 + 80055ba: 2200 movs r2, #0 + 80055bc: 5e9b ldrsh r3, [r3, r2] + 80055be: 2b00 cmp r3, #0 + 80055c0: da0d bge.n 80055de + increment_magnitude = -header_size_increment; + 80055c2: 1cbb adds r3, r7, #2 + 80055c4: 881a ldrh r2, [r3, #0] + 80055c6: 210e movs r1, #14 + 80055c8: 187b adds r3, r7, r1 + 80055ca: 4252 negs r2, r2 + 80055cc: 801a strh r2, [r3, #0] + /* Check that we aren't going to move off the end of the pbuf */ + LWIP_ERROR("increment_magnitude <= p->len", (increment_magnitude <= p->len), return 1;); + 80055ce: 687b ldr r3, [r7, #4] + 80055d0: 895b ldrh r3, [r3, #10] + 80055d2: 187a adds r2, r7, r1 + 80055d4: 8812 ldrh r2, [r2, #0] + 80055d6: 429a cmp r2, r3 + 80055d8: d906 bls.n 80055e8 + 80055da: 2301 movs r3, #1 + 80055dc: e05e b.n 800569c + } else { + increment_magnitude = header_size_increment; + 80055de: 230e movs r3, #14 + 80055e0: 18fb adds r3, r7, r3 + 80055e2: 1cba adds r2, r7, #2 + 80055e4: 8812 ldrh r2, [r2, #0] + 80055e6: 801a strh r2, [r3, #0] + LWIP_ASSERT("p->payload - increment_magnitude >= p + SIZEOF_STRUCT_PBUF", + (u8_t *)p->payload - increment_magnitude >= (u8_t *)p + SIZEOF_STRUCT_PBUF); +#endif + } + + type = p->type; + 80055e8: 687b ldr r3, [r7, #4] + 80055ea: 7b1a ldrb r2, [r3, #12] + 80055ec: 210c movs r1, #12 + 80055ee: 187b adds r3, r7, r1 + 80055f0: 801a strh r2, [r3, #0] + /* remember current payload pointer */ + payload = p->payload; + 80055f2: 687b ldr r3, [r7, #4] + 80055f4: 685b ldr r3, [r3, #4] + 80055f6: 60bb str r3, [r7, #8] + + /* pbuf types containing payloads? */ + if (type == PBUF_RAM || type == PBUF_POOL) { + 80055f8: 187b adds r3, r7, r1 + 80055fa: 881b ldrh r3, [r3, #0] + 80055fc: 2b00 cmp r3, #0 + 80055fe: d004 beq.n 800560a + 8005600: 230c movs r3, #12 + 8005602: 18fb adds r3, r7, r3 + 8005604: 881b ldrh r3, [r3, #0] + 8005606: 2b03 cmp r3, #3 + 8005608: d113 bne.n 8005632 + /* set new payload pointer */ + p->payload = (u8_t *)p->payload - header_size_increment; + 800560a: 687b ldr r3, [r7, #4] + 800560c: 685a ldr r2, [r3, #4] + 800560e: 1cbb adds r3, r7, #2 + 8005610: 2100 movs r1, #0 + 8005612: 5e5b ldrsh r3, [r3, r1] + 8005614: 425b negs r3, r3 + 8005616: 18d2 adds r2, r2, r3 + 8005618: 687b ldr r3, [r7, #4] + 800561a: 605a str r2, [r3, #4] + /* boundary check fails? */ + if ((u8_t *)p->payload < (u8_t *)p + SIZEOF_STRUCT_PBUF) { + 800561c: 687b ldr r3, [r7, #4] + 800561e: 685a ldr r2, [r3, #4] + 8005620: 687b ldr r3, [r7, #4] + 8005622: 3310 adds r3, #16 + 8005624: 429a cmp r2, r3 + 8005626: d228 bcs.n 800567a + LWIP_DEBUGF( PBUF_DEBUG | LWIP_DBG_LEVEL_SERIOUS, + ("pbuf_header: failed as %p < %p (not enough space for new header size)\n", + (void *)p->payload, (void *)(p + 1))); + /* restore old payload pointer */ + p->payload = payload; + 8005628: 687b ldr r3, [r7, #4] + 800562a: 68ba ldr r2, [r7, #8] + 800562c: 605a str r2, [r3, #4] + /* bail out unsuccesfully */ + return 1; + 800562e: 2301 movs r3, #1 + 8005630: e034 b.n 800569c + } + /* pbuf types refering to external payloads? */ + } else if (type == PBUF_REF || type == PBUF_ROM) { + 8005632: 230c movs r3, #12 + 8005634: 18fb adds r3, r7, r3 + 8005636: 881b ldrh r3, [r3, #0] + 8005638: 2b02 cmp r3, #2 + 800563a: d004 beq.n 8005646 + 800563c: 230c movs r3, #12 + 800563e: 18fb adds r3, r7, r3 + 8005640: 881b ldrh r3, [r3, #0] + 8005642: 2b01 cmp r3, #1 + 8005644: d117 bne.n 8005676 + /* hide a header in the payload? */ + if ((header_size_increment < 0) && (increment_magnitude <= p->len)) { + 8005646: 1cbb adds r3, r7, #2 + 8005648: 2200 movs r2, #0 + 800564a: 5e9b ldrsh r3, [r3, r2] + 800564c: 2b00 cmp r3, #0 + 800564e: da10 bge.n 8005672 + 8005650: 687b ldr r3, [r7, #4] + 8005652: 895b ldrh r3, [r3, #10] + 8005654: 220e movs r2, #14 + 8005656: 18ba adds r2, r7, r2 + 8005658: 8812 ldrh r2, [r2, #0] + 800565a: 429a cmp r2, r3 + 800565c: d809 bhi.n 8005672 + /* increase payload pointer */ + p->payload = (u8_t *)p->payload - header_size_increment; + 800565e: 687b ldr r3, [r7, #4] + 8005660: 685a ldr r2, [r3, #4] + 8005662: 1cbb adds r3, r7, #2 + 8005664: 2100 movs r1, #0 + 8005666: 5e5b ldrsh r3, [r3, r1] + 8005668: 425b negs r3, r3 + 800566a: 18d2 adds r2, r2, r3 + 800566c: 687b ldr r3, [r7, #4] + 800566e: 605a str r2, [r3, #4] + if ((header_size_increment < 0) && (increment_magnitude <= p->len)) { + 8005670: e003 b.n 800567a + } else { + /* cannot expand payload to front (yet!) + * bail out unsuccesfully */ + return 1; + 8005672: 2301 movs r3, #1 + 8005674: e012 b.n 800569c + } + } else { + /* Unknown type */ + LWIP_ASSERT("bad pbuf type", 0); + return 1; + 8005676: 2301 movs r3, #1 + 8005678: e010 b.n 800569c + } + /* modify pbuf length fields */ + p->len += header_size_increment; + 800567a: 687b ldr r3, [r7, #4] + 800567c: 895a ldrh r2, [r3, #10] + 800567e: 1cbb adds r3, r7, #2 + 8005680: 881b ldrh r3, [r3, #0] + 8005682: 18d3 adds r3, r2, r3 + 8005684: b29a uxth r2, r3 + 8005686: 687b ldr r3, [r7, #4] + 8005688: 815a strh r2, [r3, #10] + p->tot_len += header_size_increment; + 800568a: 687b ldr r3, [r7, #4] + 800568c: 891a ldrh r2, [r3, #8] + 800568e: 1cbb adds r3, r7, #2 + 8005690: 881b ldrh r3, [r3, #0] + 8005692: 18d3 adds r3, r2, r3 + 8005694: b29a uxth r2, r3 + 8005696: 687b ldr r3, [r7, #4] + 8005698: 811a strh r2, [r3, #8] + + LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_header: old %p new %p (%"S16_F")\n", + (void *)payload, (void *)p->payload, header_size_increment)); + + return 0; + 800569a: 2300 movs r3, #0 +} + 800569c: 0018 movs r0, r3 + 800569e: 46bd mov sp, r7 + 80056a0: b004 add sp, #16 + 80056a2: bd80 pop {r7, pc} + +080056a4 : + * 1->1->1 becomes ....... + * + */ +u8_t +pbuf_free(struct pbuf *p) +{ + 80056a4: b580 push {r7, lr} + 80056a6: b086 sub sp, #24 + 80056a8: af00 add r7, sp, #0 + 80056aa: 6078 str r0, [r7, #4] + u16_t type; + struct pbuf *q; + u8_t count; + + if (p == NULL) { + 80056ac: 687b ldr r3, [r7, #4] + 80056ae: 2b00 cmp r3, #0 + 80056b0: d101 bne.n 80056b6 + LWIP_ASSERT("p != NULL", p != NULL); + /* if assertions are disabled, proceed with debug output */ + LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_LEVEL_SERIOUS, + ("pbuf_free(p == NULL) was called.\n")); + return 0; + 80056b2: 2300 movs r3, #0 + 80056b4: e064 b.n 8005780 + } + LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_free(%p)\n", (void *)p)); + + PERF_START; + + LWIP_ASSERT("pbuf_free: sane type", + 80056b6: 687b ldr r3, [r7, #4] + 80056b8: 7b1b ldrb r3, [r3, #12] + 80056ba: 2b00 cmp r3, #0 + 80056bc: d001 beq.n 80056c2 + 80056be: 687b ldr r3, [r7, #4] + 80056c0: 7b1b ldrb r3, [r3, #12] + p->type == PBUF_RAM || p->type == PBUF_ROM || + p->type == PBUF_REF || p->type == PBUF_POOL); + + count = 0; + 80056c2: 2317 movs r3, #23 + 80056c4: 18fb adds r3, r7, r3 + 80056c6: 2200 movs r2, #0 + 80056c8: 701a strb r2, [r3, #0] + /* de-allocate all consecutive pbufs from the head of the chain that + * obtain a zero reference count after decrementing*/ + while (p != NULL) { + 80056ca: e053 b.n 8005774 + * further protection. */ + SYS_ARCH_PROTECT(old_level); + /* all pbufs in a chain are referenced at least once */ + LWIP_ASSERT("pbuf_free: p->ref > 0", p->ref > 0); + /* decrease reference count (number of pointers to pbuf) */ + ref = --(p->ref); + 80056cc: 687b ldr r3, [r7, #4] + 80056ce: 89db ldrh r3, [r3, #14] + 80056d0: 3b01 subs r3, #1 + 80056d2: b29a uxth r2, r3 + 80056d4: 687b ldr r3, [r7, #4] + 80056d6: 81da strh r2, [r3, #14] + 80056d8: 2114 movs r1, #20 + 80056da: 187b adds r3, r7, r1 + 80056dc: 687a ldr r2, [r7, #4] + 80056de: 89d2 ldrh r2, [r2, #14] + 80056e0: 801a strh r2, [r3, #0] + SYS_ARCH_UNPROTECT(old_level); + /* this pbuf is no longer referenced to? */ + if (ref == 0) { + 80056e2: 187b adds r3, r7, r1 + 80056e4: 881b ldrh r3, [r3, #0] + 80056e6: 2b00 cmp r3, #0 + 80056e8: d13d bne.n 8005766 + /* remember next pbuf in chain for next iteration */ + q = p->next; + 80056ea: 687b ldr r3, [r7, #4] + 80056ec: 681b ldr r3, [r3, #0] + 80056ee: 613b str r3, [r7, #16] + LWIP_DEBUGF( PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_free: deallocating %p\n", (void *)p)); + type = p->type; + 80056f0: 687b ldr r3, [r7, #4] + 80056f2: 7b1a ldrb r2, [r3, #12] + 80056f4: 230e movs r3, #14 + 80056f6: 18fb adds r3, r7, r3 + 80056f8: 801a strh r2, [r3, #0] +#if LWIP_SUPPORT_CUSTOM_PBUF + /* is this a custom pbuf? */ + if ((p->flags & PBUF_FLAG_IS_CUSTOM) != 0) { + 80056fa: 687b ldr r3, [r7, #4] + 80056fc: 7b5b ldrb r3, [r3, #13] + 80056fe: 001a movs r2, r3 + 8005700: 2302 movs r3, #2 + 8005702: 4013 ands r3, r2 + 8005704: d007 beq.n 8005716 + struct pbuf_custom *pc = (struct pbuf_custom*)p; + 8005706: 687b ldr r3, [r7, #4] + 8005708: 60bb str r3, [r7, #8] + LWIP_ASSERT("pc->custom_free_function != NULL", pc->custom_free_function != NULL); + pc->custom_free_function(p); + 800570a: 68bb ldr r3, [r7, #8] + 800570c: 691b ldr r3, [r3, #16] + 800570e: 687a ldr r2, [r7, #4] + 8005710: 0010 movs r0, r2 + 8005712: 4798 blx r3 + 8005714: e01e b.n 8005754 + } else +#endif /* LWIP_SUPPORT_CUSTOM_PBUF */ + { + /* is this a pbuf from the pool? */ + if (type == PBUF_POOL) { + 8005716: 230e movs r3, #14 + 8005718: 18fb adds r3, r7, r3 + 800571a: 881b ldrh r3, [r3, #0] + 800571c: 2b03 cmp r3, #3 + 800571e: d105 bne.n 800572c + memp_free(MEMP_PBUF_POOL, p); + 8005720: 687b ldr r3, [r7, #4] + 8005722: 0019 movs r1, r3 + 8005724: 2009 movs r0, #9 + 8005726: f7ff fbfb bl 8004f20 + 800572a: e013 b.n 8005754 + /* is this a ROM or RAM referencing pbuf? */ + } else if (type == PBUF_ROM || type == PBUF_REF) { + 800572c: 230e movs r3, #14 + 800572e: 18fb adds r3, r7, r3 + 8005730: 881b ldrh r3, [r3, #0] + 8005732: 2b01 cmp r3, #1 + 8005734: d004 beq.n 8005740 + 8005736: 230e movs r3, #14 + 8005738: 18fb adds r3, r7, r3 + 800573a: 881b ldrh r3, [r3, #0] + 800573c: 2b02 cmp r3, #2 + 800573e: d105 bne.n 800574c + memp_free(MEMP_PBUF, p); + 8005740: 687b ldr r3, [r7, #4] + 8005742: 0019 movs r1, r3 + 8005744: 2008 movs r0, #8 + 8005746: f7ff fbeb bl 8004f20 + 800574a: e003 b.n 8005754 + /* type == PBUF_RAM */ + } else { + mem_free(p); + 800574c: 687b ldr r3, [r7, #4] + 800574e: 0018 movs r0, r3 + 8005750: f7ff f862 bl 8004818 + } + } + count++; + 8005754: 2117 movs r1, #23 + 8005756: 187b adds r3, r7, r1 + 8005758: 781a ldrb r2, [r3, #0] + 800575a: 187b adds r3, r7, r1 + 800575c: 3201 adds r2, #1 + 800575e: 701a strb r2, [r3, #0] + /* proceed to next pbuf */ + p = q; + 8005760: 693b ldr r3, [r7, #16] + 8005762: 607b str r3, [r7, #4] + 8005764: e006 b.n 8005774 + /* p->ref > 0, this pbuf is still referenced to */ + /* (and so the remaining pbufs in chain as well) */ + } else { + LWIP_DEBUGF( PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_free: %p has ref %"U16_F", ending here.\n", (void *)p, ref)); + /* stop walking through the chain */ + p = NULL; + 8005766: 2300 movs r3, #0 + 8005768: 607b str r3, [r7, #4] + 800576a: 2217 movs r2, #23 + 800576c: 18bb adds r3, r7, r2 + 800576e: 18ba adds r2, r7, r2 + 8005770: 7812 ldrb r2, [r2, #0] + 8005772: 701a strb r2, [r3, #0] + while (p != NULL) { + 8005774: 687b ldr r3, [r7, #4] + 8005776: 2b00 cmp r3, #0 + 8005778: d1a8 bne.n 80056cc + } + } + PERF_STOP("pbuf_free"); + /* return number of de-allocated pbufs */ + return count; + 800577a: 2317 movs r3, #23 + 800577c: 18fb adds r3, r7, r3 + 800577e: 781b ldrb r3, [r3, #0] +} + 8005780: 0018 movs r0, r3 + 8005782: 46bd mov sp, r7 + 8005784: b006 add sp, #24 + 8005786: bd80 pop {r7, pc} + +08005788 : + * @return the number of pbufs in a chain + */ + +u8_t +pbuf_clen(struct pbuf *p) +{ + 8005788: b580 push {r7, lr} + 800578a: b084 sub sp, #16 + 800578c: af00 add r7, sp, #0 + 800578e: 6078 str r0, [r7, #4] + u8_t len; + + len = 0; + 8005790: 230f movs r3, #15 + 8005792: 18fb adds r3, r7, r3 + 8005794: 2200 movs r2, #0 + 8005796: 701a strb r2, [r3, #0] + while (p != NULL) { + 8005798: e008 b.n 80057ac + ++len; + 800579a: 220f movs r2, #15 + 800579c: 18bb adds r3, r7, r2 + 800579e: 18ba adds r2, r7, r2 + 80057a0: 7812 ldrb r2, [r2, #0] + 80057a2: 3201 adds r2, #1 + 80057a4: 701a strb r2, [r3, #0] + p = p->next; + 80057a6: 687b ldr r3, [r7, #4] + 80057a8: 681b ldr r3, [r3, #0] + 80057aa: 607b str r3, [r7, #4] + while (p != NULL) { + 80057ac: 687b ldr r3, [r7, #4] + 80057ae: 2b00 cmp r3, #0 + 80057b0: d1f3 bne.n 800579a + } + return len; + 80057b2: 230f movs r3, #15 + 80057b4: 18fb adds r3, r7, r3 + 80057b6: 781b ldrb r3, [r3, #0] +} + 80057b8: 0018 movs r0, r3 + 80057ba: 46bd mov sp, r7 + 80057bc: b004 add sp, #16 + 80057be: bd80 pop {r7, pc} + +080057c0 : + * @param p pbuf to increase reference counter of + * + */ +void +pbuf_ref(struct pbuf *p) +{ + 80057c0: b580 push {r7, lr} + 80057c2: b082 sub sp, #8 + 80057c4: af00 add r7, sp, #0 + 80057c6: 6078 str r0, [r7, #4] + SYS_ARCH_DECL_PROTECT(old_level); + /* pbuf given? */ + if (p != NULL) { + 80057c8: 687b ldr r3, [r7, #4] + 80057ca: 2b00 cmp r3, #0 + 80057cc: d005 beq.n 80057da + SYS_ARCH_PROTECT(old_level); + ++(p->ref); + 80057ce: 687b ldr r3, [r7, #4] + 80057d0: 89db ldrh r3, [r3, #14] + 80057d2: 3301 adds r3, #1 + 80057d4: b29a uxth r2, r3 + 80057d6: 687b ldr r3, [r7, #4] + 80057d8: 81da strh r2, [r3, #14] + SYS_ARCH_UNPROTECT(old_level); + } +} + 80057da: 46c0 nop ; (mov r8, r8) + 80057dc: 46bd mov sp, r7 + 80057de: b002 add sp, #8 + 80057e0: bd80 pop {r7, pc} + +080057e2 : + * @see pbuf_chain() + */ + +void +pbuf_cat(struct pbuf *h, struct pbuf *t) +{ + 80057e2: b580 push {r7, lr} + 80057e4: b084 sub sp, #16 + 80057e6: af00 add r7, sp, #0 + 80057e8: 6078 str r0, [r7, #4] + 80057ea: 6039 str r1, [r7, #0] + struct pbuf *p; + + LWIP_ERROR("(h != NULL) && (t != NULL) (programmer violates API)", + 80057ec: 687b ldr r3, [r7, #4] + 80057ee: 2b00 cmp r3, #0 + 80057f0: d020 beq.n 8005834 + 80057f2: 683b ldr r3, [r7, #0] + 80057f4: 2b00 cmp r3, #0 + 80057f6: d01d beq.n 8005834 + ((h != NULL) && (t != NULL)), return;); + + /* proceed to last pbuf of chain */ + for (p = h; p->next != NULL; p = p->next) { + 80057f8: 687b ldr r3, [r7, #4] + 80057fa: 60fb str r3, [r7, #12] + 80057fc: e00a b.n 8005814 + /* add total length of second chain to all totals of first chain */ + p->tot_len += t->tot_len; + 80057fe: 68fb ldr r3, [r7, #12] + 8005800: 891a ldrh r2, [r3, #8] + 8005802: 683b ldr r3, [r7, #0] + 8005804: 891b ldrh r3, [r3, #8] + 8005806: 18d3 adds r3, r2, r3 + 8005808: b29a uxth r2, r3 + 800580a: 68fb ldr r3, [r7, #12] + 800580c: 811a strh r2, [r3, #8] + for (p = h; p->next != NULL; p = p->next) { + 800580e: 68fb ldr r3, [r7, #12] + 8005810: 681b ldr r3, [r3, #0] + 8005812: 60fb str r3, [r7, #12] + 8005814: 68fb ldr r3, [r7, #12] + 8005816: 681b ldr r3, [r3, #0] + 8005818: 2b00 cmp r3, #0 + 800581a: d1f0 bne.n 80057fe + } + /* { p is last pbuf of first h chain, p->next == NULL } */ + LWIP_ASSERT("p->tot_len == p->len (of last pbuf in chain)", p->tot_len == p->len); + LWIP_ASSERT("p->next == NULL", p->next == NULL); + /* add total length of second chain to last pbuf total of first chain */ + p->tot_len += t->tot_len; + 800581c: 68fb ldr r3, [r7, #12] + 800581e: 891a ldrh r2, [r3, #8] + 8005820: 683b ldr r3, [r7, #0] + 8005822: 891b ldrh r3, [r3, #8] + 8005824: 18d3 adds r3, r2, r3 + 8005826: b29a uxth r2, r3 + 8005828: 68fb ldr r3, [r7, #12] + 800582a: 811a strh r2, [r3, #8] + /* chain last pbuf of head (p) with first of tail (t) */ + p->next = t; + 800582c: 68fb ldr r3, [r7, #12] + 800582e: 683a ldr r2, [r7, #0] + 8005830: 601a str r2, [r3, #0] + 8005832: e000 b.n 8005836 + LWIP_ERROR("(h != NULL) && (t != NULL) (programmer violates API)", + 8005834: 46c0 nop ; (mov r8, r8) + /* p->next now references t, but the caller will drop its reference to t, + * so netto there is no change to the reference count of t. + */ +} + 8005836: 46bd mov sp, r7 + 8005838: b004 add sp, #16 + 800583a: bd80 pop {r7, pc} + +0800583c : + * The ->ref field of the first pbuf of the tail chain is adjusted. + * + */ +void +pbuf_chain(struct pbuf *h, struct pbuf *t) +{ + 800583c: b580 push {r7, lr} + 800583e: b082 sub sp, #8 + 8005840: af00 add r7, sp, #0 + 8005842: 6078 str r0, [r7, #4] + 8005844: 6039 str r1, [r7, #0] + pbuf_cat(h, t); + 8005846: 683a ldr r2, [r7, #0] + 8005848: 687b ldr r3, [r7, #4] + 800584a: 0011 movs r1, r2 + 800584c: 0018 movs r0, r3 + 800584e: f7ff ffc8 bl 80057e2 + /* t is now referenced by h */ + pbuf_ref(t); + 8005852: 683b ldr r3, [r7, #0] + 8005854: 0018 movs r0, r3 + 8005856: f7ff ffb3 bl 80057c0 + LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_chain: %p references %p\n", (void *)h, (void *)t)); +} + 800585a: 46c0 nop ; (mov r8, r8) + 800585c: 46bd mov sp, r7 + 800585e: b002 add sp, #8 + 8005860: bd80 pop {r7, pc} + +08005862 : + * ERR_ARG if one of the pbufs is NULL or p_to is not big + * enough to hold p_from + */ +err_t +pbuf_copy(struct pbuf *p_to, struct pbuf *p_from) +{ + 8005862: b5f0 push {r4, r5, r6, r7, lr} + 8005864: b085 sub sp, #20 + 8005866: af00 add r7, sp, #0 + 8005868: 6078 str r0, [r7, #4] + 800586a: 6039 str r1, [r7, #0] + u16_t offset_to=0, offset_from=0, len; + 800586c: 230e movs r3, #14 + 800586e: 18fb adds r3, r7, r3 + 8005870: 2200 movs r2, #0 + 8005872: 801a strh r2, [r3, #0] + 8005874: 230c movs r3, #12 + 8005876: 18fb adds r3, r7, r3 + 8005878: 2200 movs r2, #0 + 800587a: 801a strh r2, [r3, #0] + + LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_copy(%p, %p)\n", + (void*)p_to, (void*)p_from)); + + /* is the target big enough to hold the source? */ + LWIP_ERROR("pbuf_copy: target not big enough to hold source", ((p_to != NULL) && + 800587c: 687b ldr r3, [r7, #4] + 800587e: 2b00 cmp r3, #0 + 8005880: d008 beq.n 8005894 + 8005882: 683b ldr r3, [r7, #0] + 8005884: 2b00 cmp r3, #0 + 8005886: d005 beq.n 8005894 + 8005888: 687b ldr r3, [r7, #4] + 800588a: 891a ldrh r2, [r3, #8] + 800588c: 683b ldr r3, [r7, #0] + 800588e: 891b ldrh r3, [r3, #8] + 8005890: 429a cmp r2, r3 + 8005892: d202 bcs.n 800589a + 8005894: 230e movs r3, #14 + 8005896: 425b negs r3, r3 + 8005898: e08c b.n 80059b4 + + /* iterate through pbuf chain */ + do + { + /* copy one part of the original chain */ + if ((p_to->len - offset_to) >= (p_from->len - offset_from)) { + 800589a: 687b ldr r3, [r7, #4] + 800589c: 895b ldrh r3, [r3, #10] + 800589e: 001a movs r2, r3 + 80058a0: 230e movs r3, #14 + 80058a2: 18fb adds r3, r7, r3 + 80058a4: 881b ldrh r3, [r3, #0] + 80058a6: 1ad2 subs r2, r2, r3 + 80058a8: 683b ldr r3, [r7, #0] + 80058aa: 895b ldrh r3, [r3, #10] + 80058ac: 0019 movs r1, r3 + 80058ae: 230c movs r3, #12 + 80058b0: 18fb adds r3, r7, r3 + 80058b2: 881b ldrh r3, [r3, #0] + 80058b4: 1acb subs r3, r1, r3 + 80058b6: 429a cmp r2, r3 + 80058b8: db09 blt.n 80058ce + /* complete current p_from fits into current p_to */ + len = p_from->len - offset_from; + 80058ba: 683b ldr r3, [r7, #0] + 80058bc: 8959 ldrh r1, [r3, #10] + 80058be: 230a movs r3, #10 + 80058c0: 18fb adds r3, r7, r3 + 80058c2: 220c movs r2, #12 + 80058c4: 18ba adds r2, r7, r2 + 80058c6: 8812 ldrh r2, [r2, #0] + 80058c8: 1a8a subs r2, r1, r2 + 80058ca: 801a strh r2, [r3, #0] + 80058cc: e008 b.n 80058e0 + } else { + /* current p_from does not fit into current p_to */ + len = p_to->len - offset_to; + 80058ce: 687b ldr r3, [r7, #4] + 80058d0: 8959 ldrh r1, [r3, #10] + 80058d2: 230a movs r3, #10 + 80058d4: 18fb adds r3, r7, r3 + 80058d6: 220e movs r2, #14 + 80058d8: 18ba adds r2, r7, r2 + 80058da: 8812 ldrh r2, [r2, #0] + 80058dc: 1a8a subs r2, r1, r2 + 80058de: 801a strh r2, [r3, #0] + } + MEMCPY((u8_t*)p_to->payload + offset_to, (u8_t*)p_from->payload + offset_from, len); + 80058e0: 687b ldr r3, [r7, #4] + 80058e2: 685a ldr r2, [r3, #4] + 80058e4: 250e movs r5, #14 + 80058e6: 197b adds r3, r7, r5 + 80058e8: 881b ldrh r3, [r3, #0] + 80058ea: 18d0 adds r0, r2, r3 + 80058ec: 683b ldr r3, [r7, #0] + 80058ee: 685a ldr r2, [r3, #4] + 80058f0: 240c movs r4, #12 + 80058f2: 193b adds r3, r7, r4 + 80058f4: 881b ldrh r3, [r3, #0] + 80058f6: 18d1 adds r1, r2, r3 + 80058f8: 260a movs r6, #10 + 80058fa: 19bb adds r3, r7, r6 + 80058fc: 881b ldrh r3, [r3, #0] + 80058fe: 001a movs r2, r3 + 8005900: f00a f9cf bl 800fca2 + offset_to += len; + 8005904: 197b adds r3, r7, r5 + 8005906: 1979 adds r1, r7, r5 + 8005908: 0030 movs r0, r6 + 800590a: 183a adds r2, r7, r0 + 800590c: 8809 ldrh r1, [r1, #0] + 800590e: 8812 ldrh r2, [r2, #0] + 8005910: 188a adds r2, r1, r2 + 8005912: 801a strh r2, [r3, #0] + offset_from += len; + 8005914: 193b adds r3, r7, r4 + 8005916: 1939 adds r1, r7, r4 + 8005918: 183a adds r2, r7, r0 + 800591a: 8809 ldrh r1, [r1, #0] + 800591c: 8812 ldrh r2, [r2, #0] + 800591e: 188a adds r2, r1, r2 + 8005920: 801a strh r2, [r3, #0] + LWIP_ASSERT("offset_to <= p_to->len", offset_to <= p_to->len); + LWIP_ASSERT("offset_from <= p_from->len", offset_from <= p_from->len); + if (offset_from >= p_from->len) { + 8005922: 683b ldr r3, [r7, #0] + 8005924: 895b ldrh r3, [r3, #10] + 8005926: 193a adds r2, r7, r4 + 8005928: 8812 ldrh r2, [r2, #0] + 800592a: 429a cmp r2, r3 + 800592c: d306 bcc.n 800593c + /* on to next p_from (if any) */ + offset_from = 0; + 800592e: 230c movs r3, #12 + 8005930: 18fb adds r3, r7, r3 + 8005932: 2200 movs r2, #0 + 8005934: 801a strh r2, [r3, #0] + p_from = p_from->next; + 8005936: 683b ldr r3, [r7, #0] + 8005938: 681b ldr r3, [r3, #0] + 800593a: 603b str r3, [r7, #0] + } + if (offset_to == p_to->len) { + 800593c: 687b ldr r3, [r7, #4] + 800593e: 895b ldrh r3, [r3, #10] + 8005940: 220e movs r2, #14 + 8005942: 18ba adds r2, r7, r2 + 8005944: 8812 ldrh r2, [r2, #0] + 8005946: 429a cmp r2, r3 + 8005948: d10f bne.n 800596a + /* on to next p_to (if any) */ + offset_to = 0; + 800594a: 230e movs r3, #14 + 800594c: 18fb adds r3, r7, r3 + 800594e: 2200 movs r2, #0 + 8005950: 801a strh r2, [r3, #0] + p_to = p_to->next; + 8005952: 687b ldr r3, [r7, #4] + 8005954: 681b ldr r3, [r3, #0] + 8005956: 607b str r3, [r7, #4] + LWIP_ERROR("p_to != NULL", (p_to != NULL) || (p_from == NULL) , return ERR_ARG;); + 8005958: 687b ldr r3, [r7, #4] + 800595a: 2b00 cmp r3, #0 + 800595c: d105 bne.n 800596a + 800595e: 683b ldr r3, [r7, #0] + 8005960: 2b00 cmp r3, #0 + 8005962: d002 beq.n 800596a + 8005964: 230e movs r3, #14 + 8005966: 425b negs r3, r3 + 8005968: e024 b.n 80059b4 + } + + if((p_from != NULL) && (p_from->len == p_from->tot_len)) { + 800596a: 683b ldr r3, [r7, #0] + 800596c: 2b00 cmp r3, #0 + 800596e: d00c beq.n 800598a + 8005970: 683b ldr r3, [r7, #0] + 8005972: 895a ldrh r2, [r3, #10] + 8005974: 683b ldr r3, [r7, #0] + 8005976: 891b ldrh r3, [r3, #8] + 8005978: 429a cmp r2, r3 + 800597a: d106 bne.n 800598a + /* don't copy more than one packet! */ + LWIP_ERROR("pbuf_copy() does not allow packet queues!\n", + 800597c: 683b ldr r3, [r7, #0] + 800597e: 681b ldr r3, [r3, #0] + 8005980: 2b00 cmp r3, #0 + 8005982: d002 beq.n 800598a + 8005984: 2306 movs r3, #6 + 8005986: 425b negs r3, r3 + 8005988: e014 b.n 80059b4 + (p_from->next == NULL), return ERR_VAL;); + } + if((p_to != NULL) && (p_to->len == p_to->tot_len)) { + 800598a: 687b ldr r3, [r7, #4] + 800598c: 2b00 cmp r3, #0 + 800598e: d00c beq.n 80059aa + 8005990: 687b ldr r3, [r7, #4] + 8005992: 895a ldrh r2, [r3, #10] + 8005994: 687b ldr r3, [r7, #4] + 8005996: 891b ldrh r3, [r3, #8] + 8005998: 429a cmp r2, r3 + 800599a: d106 bne.n 80059aa + /* don't copy more than one packet! */ + LWIP_ERROR("pbuf_copy() does not allow packet queues!\n", + 800599c: 687b ldr r3, [r7, #4] + 800599e: 681b ldr r3, [r3, #0] + 80059a0: 2b00 cmp r3, #0 + 80059a2: d002 beq.n 80059aa + 80059a4: 2306 movs r3, #6 + 80059a6: 425b negs r3, r3 + 80059a8: e004 b.n 80059b4 + (p_to->next == NULL), return ERR_VAL;); + } + } while (p_from); + 80059aa: 683b ldr r3, [r7, #0] + 80059ac: 2b00 cmp r3, #0 + 80059ae: d000 beq.n 80059b2 + 80059b0: e773 b.n 800589a + LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_copy: end of chain reached.\n")); + return ERR_OK; + 80059b2: 2300 movs r3, #0 +} + 80059b4: 0018 movs r0, r3 + 80059b6: 46bd mov sp, r7 + 80059b8: b005 add sp, #20 + 80059ba: bdf0 pop {r4, r5, r6, r7, pc} + +080059bc : + * @param offset offset into the packet buffer from where to begin copying len bytes + * @return the number of bytes copied, or 0 on failure + */ +u16_t +pbuf_copy_partial(struct pbuf *buf, void *dataptr, u16_t len, u16_t offset) +{ + 80059bc: b5b0 push {r4, r5, r7, lr} + 80059be: b088 sub sp, #32 + 80059c0: af00 add r7, sp, #0 + 80059c2: 60f8 str r0, [r7, #12] + 80059c4: 60b9 str r1, [r7, #8] + 80059c6: 0019 movs r1, r3 + 80059c8: 1dbb adds r3, r7, #6 + 80059ca: 801a strh r2, [r3, #0] + 80059cc: 1d3b adds r3, r7, #4 + 80059ce: 1c0a adds r2, r1, #0 + 80059d0: 801a strh r2, [r3, #0] + struct pbuf *p; + u16_t left; + u16_t buf_copy_len; + u16_t copied_total = 0; + 80059d2: 2316 movs r3, #22 + 80059d4: 18fb adds r3, r7, r3 + 80059d6: 2200 movs r2, #0 + 80059d8: 801a strh r2, [r3, #0] + + LWIP_ERROR("pbuf_copy_partial: invalid buf", (buf != NULL), return 0;); + 80059da: 68fb ldr r3, [r7, #12] + 80059dc: 2b00 cmp r3, #0 + 80059de: d101 bne.n 80059e4 + 80059e0: 2300 movs r3, #0 + 80059e2: e06f b.n 8005ac4 + LWIP_ERROR("pbuf_copy_partial: invalid dataptr", (dataptr != NULL), return 0;); + 80059e4: 68bb ldr r3, [r7, #8] + 80059e6: 2b00 cmp r3, #0 + 80059e8: d101 bne.n 80059ee + 80059ea: 2300 movs r3, #0 + 80059ec: e06a b.n 8005ac4 + + left = 0; + 80059ee: 231a movs r3, #26 + 80059f0: 18fb adds r3, r7, r3 + 80059f2: 2200 movs r2, #0 + 80059f4: 801a strh r2, [r3, #0] + + if((buf == NULL) || (dataptr == NULL)) { + 80059f6: 68fb ldr r3, [r7, #12] + 80059f8: 2b00 cmp r3, #0 + 80059fa: d002 beq.n 8005a02 + 80059fc: 68bb ldr r3, [r7, #8] + 80059fe: 2b00 cmp r3, #0 + 8005a00: d101 bne.n 8005a06 + return 0; + 8005a02: 2300 movs r3, #0 + 8005a04: e05e b.n 8005ac4 + } + + /* Note some systems use byte copy if dataptr or one of the pbuf payload pointers are unaligned. */ + for(p = buf; len != 0 && p != NULL; p = p->next) { + 8005a06: 68fb ldr r3, [r7, #12] + 8005a08: 61fb str r3, [r7, #28] + 8005a0a: e051 b.n 8005ab0 + if ((offset != 0) && (offset >= p->len)) { + 8005a0c: 1d3b adds r3, r7, #4 + 8005a0e: 881b ldrh r3, [r3, #0] + 8005a10: 2b00 cmp r3, #0 + 8005a12: d00d beq.n 8005a30 + 8005a14: 69fb ldr r3, [r7, #28] + 8005a16: 895b ldrh r3, [r3, #10] + 8005a18: 1d3a adds r2, r7, #4 + 8005a1a: 8812 ldrh r2, [r2, #0] + 8005a1c: 429a cmp r2, r3 + 8005a1e: d307 bcc.n 8005a30 + /* don't copy from this buffer -> on to the next */ + offset -= p->len; + 8005a20: 69fb ldr r3, [r7, #28] + 8005a22: 895a ldrh r2, [r3, #10] + 8005a24: 1d3b adds r3, r7, #4 + 8005a26: 1d39 adds r1, r7, #4 + 8005a28: 8809 ldrh r1, [r1, #0] + 8005a2a: 1a8a subs r2, r1, r2 + 8005a2c: 801a strh r2, [r3, #0] + 8005a2e: e03c b.n 8005aaa + } else { + /* copy from this buffer. maybe only partially. */ + buf_copy_len = p->len - offset; + 8005a30: 69fb ldr r3, [r7, #28] + 8005a32: 8959 ldrh r1, [r3, #10] + 8005a34: 2018 movs r0, #24 + 8005a36: 183b adds r3, r7, r0 + 8005a38: 1d3a adds r2, r7, #4 + 8005a3a: 8812 ldrh r2, [r2, #0] + 8005a3c: 1a8a subs r2, r1, r2 + 8005a3e: 801a strh r2, [r3, #0] + if (buf_copy_len > len) + 8005a40: 183a adds r2, r7, r0 + 8005a42: 1dbb adds r3, r7, #6 + 8005a44: 8812 ldrh r2, [r2, #0] + 8005a46: 881b ldrh r3, [r3, #0] + 8005a48: 429a cmp r2, r3 + 8005a4a: d904 bls.n 8005a56 + buf_copy_len = len; + 8005a4c: 2318 movs r3, #24 + 8005a4e: 18fb adds r3, r7, r3 + 8005a50: 1dba adds r2, r7, #6 + 8005a52: 8812 ldrh r2, [r2, #0] + 8005a54: 801a strh r2, [r3, #0] + /* copy the necessary parts of the buffer */ + MEMCPY(&((char*)dataptr)[left], &((char*)p->payload)[offset], buf_copy_len); + 8005a56: 251a movs r5, #26 + 8005a58: 197b adds r3, r7, r5 + 8005a5a: 881b ldrh r3, [r3, #0] + 8005a5c: 68ba ldr r2, [r7, #8] + 8005a5e: 18d0 adds r0, r2, r3 + 8005a60: 69fb ldr r3, [r7, #28] + 8005a62: 685a ldr r2, [r3, #4] + 8005a64: 1d3b adds r3, r7, #4 + 8005a66: 881b ldrh r3, [r3, #0] + 8005a68: 18d1 adds r1, r2, r3 + 8005a6a: 2418 movs r4, #24 + 8005a6c: 193b adds r3, r7, r4 + 8005a6e: 881b ldrh r3, [r3, #0] + 8005a70: 001a movs r2, r3 + 8005a72: f00a f916 bl 800fca2 + copied_total += buf_copy_len; + 8005a76: 2216 movs r2, #22 + 8005a78: 18bb adds r3, r7, r2 + 8005a7a: 18b9 adds r1, r7, r2 + 8005a7c: 0020 movs r0, r4 + 8005a7e: 183a adds r2, r7, r0 + 8005a80: 8809 ldrh r1, [r1, #0] + 8005a82: 8812 ldrh r2, [r2, #0] + 8005a84: 188a adds r2, r1, r2 + 8005a86: 801a strh r2, [r3, #0] + left += buf_copy_len; + 8005a88: 197b adds r3, r7, r5 + 8005a8a: 1979 adds r1, r7, r5 + 8005a8c: 183a adds r2, r7, r0 + 8005a8e: 8809 ldrh r1, [r1, #0] + 8005a90: 8812 ldrh r2, [r2, #0] + 8005a92: 188a adds r2, r1, r2 + 8005a94: 801a strh r2, [r3, #0] + len -= buf_copy_len; + 8005a96: 1dbb adds r3, r7, #6 + 8005a98: 1db9 adds r1, r7, #6 + 8005a9a: 183a adds r2, r7, r0 + 8005a9c: 8809 ldrh r1, [r1, #0] + 8005a9e: 8812 ldrh r2, [r2, #0] + 8005aa0: 1a8a subs r2, r1, r2 + 8005aa2: 801a strh r2, [r3, #0] + offset = 0; + 8005aa4: 1d3b adds r3, r7, #4 + 8005aa6: 2200 movs r2, #0 + 8005aa8: 801a strh r2, [r3, #0] + for(p = buf; len != 0 && p != NULL; p = p->next) { + 8005aaa: 69fb ldr r3, [r7, #28] + 8005aac: 681b ldr r3, [r3, #0] + 8005aae: 61fb str r3, [r7, #28] + 8005ab0: 1dbb adds r3, r7, #6 + 8005ab2: 881b ldrh r3, [r3, #0] + 8005ab4: 2b00 cmp r3, #0 + 8005ab6: d002 beq.n 8005abe + 8005ab8: 69fb ldr r3, [r7, #28] + 8005aba: 2b00 cmp r3, #0 + 8005abc: d1a6 bne.n 8005a0c + } + } + return copied_total; + 8005abe: 2316 movs r3, #22 + 8005ac0: 18fb adds r3, r7, r3 + 8005ac2: 881b ldrh r3, [r3, #0] +} + 8005ac4: 0018 movs r0, r3 + 8005ac6: 46bd mov sp, r7 + 8005ac8: b008 add sp, #32 + 8005aca: bdb0 pop {r4, r5, r7, pc} + +08005acc : + * caller). + * + */ +u8_t +raw_input(struct pbuf *p, struct netif *inp) +{ + 8005acc: b590 push {r4, r7, lr} + 8005ace: b089 sub sp, #36 ; 0x24 + 8005ad0: af00 add r7, sp, #0 + 8005ad2: 6078 str r0, [r7, #4] + 8005ad4: 6039 str r1, [r7, #0] + struct raw_pcb *pcb, *prev; + struct ip_hdr *iphdr; + s16_t proto; + u8_t eaten = 0; + 8005ad6: 2317 movs r3, #23 + 8005ad8: 18fb adds r3, r7, r3 + 8005ada: 2200 movs r2, #0 + 8005adc: 701a strb r2, [r3, #0] + + LWIP_UNUSED_ARG(inp); + + iphdr = (struct ip_hdr *)p->payload; + 8005ade: 687b ldr r3, [r7, #4] + 8005ae0: 685b ldr r3, [r3, #4] + 8005ae2: 613b str r3, [r7, #16] + proto = IPH_PROTO(iphdr); + 8005ae4: 693b ldr r3, [r7, #16] + 8005ae6: 7a5a ldrb r2, [r3, #9] + 8005ae8: 230e movs r3, #14 + 8005aea: 18fb adds r3, r7, r3 + 8005aec: 801a strh r2, [r3, #0] + + prev = NULL; + 8005aee: 2300 movs r3, #0 + 8005af0: 61bb str r3, [r7, #24] + pcb = raw_pcbs; + 8005af2: 4b28 ldr r3, [pc, #160] ; (8005b94 ) + 8005af4: 681b ldr r3, [r3, #0] + 8005af6: 61fb str r3, [r7, #28] + /* loop through all raw pcbs until the packet is eaten by one */ + /* this allows multiple pcbs to match against the packet by design */ + while ((eaten == 0) && (pcb != NULL)) { + 8005af8: e03c b.n 8005b74 + if ((pcb->protocol == proto) && + 8005afa: 69fb ldr r3, [r7, #28] + 8005afc: 7c1b ldrb r3, [r3, #16] + 8005afe: 001a movs r2, r3 + 8005b00: 230e movs r3, #14 + 8005b02: 18fb adds r3, r7, r3 + 8005b04: 2100 movs r1, #0 + 8005b06: 5e5b ldrsh r3, [r3, r1] + 8005b08: 429a cmp r2, r3 + 8005b0a: d12e bne.n 8005b6a + (ip_addr_isany(&pcb->local_ip) || + 8005b0c: 69fb ldr r3, [r7, #28] + if ((pcb->protocol == proto) && + 8005b0e: 2b00 cmp r3, #0 + 8005b10: d009 beq.n 8005b26 + (ip_addr_isany(&pcb->local_ip) || + 8005b12: 69fb ldr r3, [r7, #28] + 8005b14: 681b ldr r3, [r3, #0] + 8005b16: 2b00 cmp r3, #0 + 8005b18: d005 beq.n 8005b26 + ip_addr_cmp(&(pcb->local_ip), ¤t_iphdr_dest))) { + 8005b1a: 69fb ldr r3, [r7, #28] + 8005b1c: 681a ldr r2, [r3, #0] + 8005b1e: 4b1e ldr r3, [pc, #120] ; (8005b98 ) + 8005b20: 681b ldr r3, [r3, #0] + (ip_addr_isany(&pcb->local_ip) || + 8005b22: 429a cmp r2, r3 + 8005b24: d121 bne.n 8005b6a + /* broadcast filter? */ + if (ip_get_option(pcb, SOF_BROADCAST) || !ip_addr_isbroadcast(¤t_iphdr_dest, inp)) +#endif /* IP_SOF_BROADCAST_RECV */ + { + /* receive callback function available? */ + if (pcb->recv != NULL) { + 8005b26: 69fb ldr r3, [r7, #28] + 8005b28: 695b ldr r3, [r3, #20] + 8005b2a: 2b00 cmp r3, #0 + 8005b2c: d01d beq.n 8005b6a + /* the receive callback function did not eat the packet? */ + if (pcb->recv(pcb->recv_arg, pcb, p, ip_current_src_addr()) != 0) { + 8005b2e: 69fb ldr r3, [r7, #28] + 8005b30: 695c ldr r4, [r3, #20] + 8005b32: 69fb ldr r3, [r7, #28] + 8005b34: 6998 ldr r0, [r3, #24] + 8005b36: 4b19 ldr r3, [pc, #100] ; (8005b9c ) + 8005b38: 687a ldr r2, [r7, #4] + 8005b3a: 69f9 ldr r1, [r7, #28] + 8005b3c: 47a0 blx r4 + 8005b3e: 1e03 subs r3, r0, #0 + 8005b40: d013 beq.n 8005b6a + /* receive function ate the packet */ + p = NULL; + 8005b42: 2300 movs r3, #0 + 8005b44: 607b str r3, [r7, #4] + eaten = 1; + 8005b46: 2317 movs r3, #23 + 8005b48: 18fb adds r3, r7, r3 + 8005b4a: 2201 movs r2, #1 + 8005b4c: 701a strb r2, [r3, #0] + if (prev != NULL) { + 8005b4e: 69bb ldr r3, [r7, #24] + 8005b50: 2b00 cmp r3, #0 + 8005b52: d00a beq.n 8005b6a + /* move the pcb to the front of raw_pcbs so that is + found faster next time */ + prev->next = pcb->next; + 8005b54: 69fb ldr r3, [r7, #28] + 8005b56: 68da ldr r2, [r3, #12] + 8005b58: 69bb ldr r3, [r7, #24] + 8005b5a: 60da str r2, [r3, #12] + pcb->next = raw_pcbs; + 8005b5c: 4b0d ldr r3, [pc, #52] ; (8005b94 ) + 8005b5e: 681a ldr r2, [r3, #0] + 8005b60: 69fb ldr r3, [r7, #28] + 8005b62: 60da str r2, [r3, #12] + raw_pcbs = pcb; + 8005b64: 4b0b ldr r3, [pc, #44] ; (8005b94 ) + 8005b66: 69fa ldr r2, [r7, #28] + 8005b68: 601a str r2, [r3, #0] + } + /* no receive callback function was set for this raw PCB */ + } + /* drop the packet */ + } + prev = pcb; + 8005b6a: 69fb ldr r3, [r7, #28] + 8005b6c: 61bb str r3, [r7, #24] + pcb = pcb->next; + 8005b6e: 69fb ldr r3, [r7, #28] + 8005b70: 68db ldr r3, [r3, #12] + 8005b72: 61fb str r3, [r7, #28] + while ((eaten == 0) && (pcb != NULL)) { + 8005b74: 2317 movs r3, #23 + 8005b76: 18fb adds r3, r7, r3 + 8005b78: 781b ldrb r3, [r3, #0] + 8005b7a: 2b00 cmp r3, #0 + 8005b7c: d102 bne.n 8005b84 + 8005b7e: 69fb ldr r3, [r7, #28] + 8005b80: 2b00 cmp r3, #0 + 8005b82: d1ba bne.n 8005afa + } + return eaten; + 8005b84: 2317 movs r3, #23 + 8005b86: 18fb adds r3, r7, r3 + 8005b88: 781b ldrb r3, [r3, #0] +} + 8005b8a: 0018 movs r0, r3 + 8005b8c: 46bd mov sp, r7 + 8005b8e: b009 add sp, #36 ; 0x24 + 8005b90: bd90 pop {r4, r7, pc} + 8005b92: 46c0 nop ; (mov r8, r8) + 8005b94: 20002274 .word 0x20002274 + 8005b98: 2000329c .word 0x2000329c + 8005b9c: 20003294 .word 0x20003294 + +08005ba0 : +#include + +struct stats_ lwip_stats; + +void stats_init(void) +{ + 8005ba0: b580 push {r7, lr} + 8005ba2: af00 add r7, sp, #0 +#endif /* MEMP_STATS */ +#if MEM_STATS + lwip_stats.mem.name = "MEM"; +#endif /* MEM_STATS */ +#endif /* LWIP_DEBUG */ +} + 8005ba4: 46c0 nop ; (mov r8, r8) + 8005ba6: 46bd mov sp, r7 + 8005ba8: bd80 pop {r7, pc} + +08005baa : +/** + * Initialize this module. + */ +void +tcp_init(void) +{ + 8005baa: b580 push {r7, lr} + 8005bac: af00 add r7, sp, #0 +#if LWIP_RANDOMIZE_INITIAL_LOCAL_PORTS && defined(LWIP_RAND) + tcp_port = TCP_ENSURE_LOCAL_PORT_RANGE(LWIP_RAND()); +#endif /* LWIP_RANDOMIZE_INITIAL_LOCAL_PORTS && defined(LWIP_RAND) */ +} + 8005bae: 46c0 nop ; (mov r8, r8) + 8005bb0: 46bd mov sp, r7 + 8005bb2: bd80 pop {r7, pc} + +08005bb4 : +/** + * Called periodically to dispatch TCP timers. + */ +void +tcp_tmr(void) +{ + 8005bb4: b580 push {r7, lr} + 8005bb6: af00 add r7, sp, #0 + /* Call tcp_fasttmr() every 250 ms */ + tcp_fasttmr(); + 8005bb8: f000 fcd0 bl 800655c + + if (++tcp_timer & 1) { + 8005bbc: 4b08 ldr r3, [pc, #32] ; (8005be0 ) + 8005bbe: 781b ldrb r3, [r3, #0] + 8005bc0: 3301 adds r3, #1 + 8005bc2: b2da uxtb r2, r3 + 8005bc4: 4b06 ldr r3, [pc, #24] ; (8005be0 ) + 8005bc6: 701a strb r2, [r3, #0] + 8005bc8: 4b05 ldr r3, [pc, #20] ; (8005be0 ) + 8005bca: 781b ldrb r3, [r3, #0] + 8005bcc: 001a movs r2, r3 + 8005bce: 2301 movs r3, #1 + 8005bd0: 4013 ands r3, r2 + 8005bd2: d001 beq.n 8005bd8 + /* Call tcp_tmr() every 500 ms, i.e., every other timer + tcp_tmr() is called. */ + tcp_slowtmr(); + 8005bd4: f000 fa54 bl 8006080 + } +} + 8005bd8: 46c0 nop ; (mov r8, r8) + 8005bda: 46bd mov sp, r7 + 8005bdc: bd80 pop {r7, pc} + 8005bde: 46c0 nop ; (mov r8, r8) + 8005be0: 20002278 .word 0x20002278 + +08005be4 : + * @return ERR_OK if connection has been closed + * another err_t if closing failed and pcb is not freed + */ +static err_t +tcp_close_shutdown(struct tcp_pcb *pcb, u8_t rst_on_unacked_data) +{ + 8005be4: b5b0 push {r4, r5, r7, lr} + 8005be6: b086 sub sp, #24 + 8005be8: af02 add r7, sp, #8 + 8005bea: 6078 str r0, [r7, #4] + 8005bec: 000a movs r2, r1 + 8005bee: 1cfb adds r3, r7, #3 + 8005bf0: 701a strb r2, [r3, #0] + err_t err; + + if (rst_on_unacked_data && ((pcb->state == ESTABLISHED) || (pcb->state == CLOSE_WAIT))) { + 8005bf2: 1cfb adds r3, r7, #3 + 8005bf4: 781b ldrb r3, [r3, #0] + 8005bf6: 2b00 cmp r3, #0 + 8005bf8: d100 bne.n 8005bfc + 8005bfa: e068 b.n 8005cce + 8005bfc: 687b ldr r3, [r7, #4] + 8005bfe: 7e1b ldrb r3, [r3, #24] + 8005c00: 2b04 cmp r3, #4 + 8005c02: d003 beq.n 8005c0c + 8005c04: 687b ldr r3, [r7, #4] + 8005c06: 7e1b ldrb r3, [r3, #24] + 8005c08: 2b07 cmp r3, #7 + 8005c0a: d160 bne.n 8005cce + if ((pcb->refused_data != NULL) || (pcb->rcv_wnd != TCP_WND)) { + 8005c0c: 687b ldr r3, [r7, #4] + 8005c0e: 6f9b ldr r3, [r3, #120] ; 0x78 + 8005c10: 2b00 cmp r3, #0 + 8005c12: d104 bne.n 8005c1e + 8005c14: 687b ldr r3, [r7, #4] + 8005c16: 8d9b ldrh r3, [r3, #44] ; 0x2c + 8005c18: 4a8b ldr r2, [pc, #556] ; (8005e48 ) + 8005c1a: 4293 cmp r3, r2 + 8005c1c: d057 beq.n 8005cce + side about this. */ + LWIP_ASSERT("pcb->flags & TF_RXCLOSED", pcb->flags & TF_RXCLOSED); + + /* don't call tcp_abort here: we must not deallocate the pcb since + that might not be expected when calling tcp_close */ + tcp_rst(pcb->snd_nxt, pcb->rcv_nxt, &pcb->local_ip, &pcb->remote_ip, + 8005c1e: 687b ldr r3, [r7, #4] + 8005c20: 6d18 ldr r0, [r3, #80] ; 0x50 + 8005c22: 687b ldr r3, [r7, #4] + 8005c24: 6a99 ldr r1, [r3, #40] ; 0x28 + 8005c26: 687c ldr r4, [r7, #4] + 8005c28: 687b ldr r3, [r7, #4] + 8005c2a: 1d1d adds r5, r3, #4 + 8005c2c: 687b ldr r3, [r7, #4] + 8005c2e: 8b5b ldrh r3, [r3, #26] + 8005c30: 687a ldr r2, [r7, #4] + 8005c32: 8b92 ldrh r2, [r2, #28] + 8005c34: 9201 str r2, [sp, #4] + 8005c36: 9300 str r3, [sp, #0] + 8005c38: 002b movs r3, r5 + 8005c3a: 0022 movs r2, r4 + 8005c3c: f004 f9c6 bl 8009fcc + pcb->local_port, pcb->remote_port); + + tcp_pcb_purge(pcb); + 8005c40: 687b ldr r3, [r7, #4] + 8005c42: 0018 movs r0, r3 + 8005c44: f000 fef0 bl 8006a28 + TCP_RMV_ACTIVE(pcb); + 8005c48: 4b80 ldr r3, [pc, #512] ; (8005e4c ) + 8005c4a: 681b ldr r3, [r3, #0] + 8005c4c: 687a ldr r2, [r7, #4] + 8005c4e: 429a cmp r2, r3 + 8005c50: d105 bne.n 8005c5e + 8005c52: 4b7e ldr r3, [pc, #504] ; (8005e4c ) + 8005c54: 681b ldr r3, [r3, #0] + 8005c56: 68da ldr r2, [r3, #12] + 8005c58: 4b7c ldr r3, [pc, #496] ; (8005e4c ) + 8005c5a: 601a str r2, [r3, #0] + 8005c5c: e019 b.n 8005c92 + 8005c5e: 4b7b ldr r3, [pc, #492] ; (8005e4c ) + 8005c60: 681a ldr r2, [r3, #0] + 8005c62: 4b7b ldr r3, [pc, #492] ; (8005e50 ) + 8005c64: 601a str r2, [r3, #0] + 8005c66: e010 b.n 8005c8a + 8005c68: 4b79 ldr r3, [pc, #484] ; (8005e50 ) + 8005c6a: 681b ldr r3, [r3, #0] + 8005c6c: 68db ldr r3, [r3, #12] + 8005c6e: 687a ldr r2, [r7, #4] + 8005c70: 429a cmp r2, r3 + 8005c72: d105 bne.n 8005c80 + 8005c74: 4b76 ldr r3, [pc, #472] ; (8005e50 ) + 8005c76: 681b ldr r3, [r3, #0] + 8005c78: 687a ldr r2, [r7, #4] + 8005c7a: 68d2 ldr r2, [r2, #12] + 8005c7c: 60da str r2, [r3, #12] + 8005c7e: e008 b.n 8005c92 + 8005c80: 4b73 ldr r3, [pc, #460] ; (8005e50 ) + 8005c82: 681b ldr r3, [r3, #0] + 8005c84: 68da ldr r2, [r3, #12] + 8005c86: 4b72 ldr r3, [pc, #456] ; (8005e50 ) + 8005c88: 601a str r2, [r3, #0] + 8005c8a: 4b71 ldr r3, [pc, #452] ; (8005e50 ) + 8005c8c: 681b ldr r3, [r3, #0] + 8005c8e: 2b00 cmp r3, #0 + 8005c90: d1ea bne.n 8005c68 + 8005c92: 687b ldr r3, [r7, #4] + 8005c94: 2200 movs r2, #0 + 8005c96: 60da str r2, [r3, #12] + 8005c98: 4b6e ldr r3, [pc, #440] ; (8005e54 ) + 8005c9a: 2201 movs r2, #1 + 8005c9c: 701a strb r2, [r3, #0] + if (pcb->state == ESTABLISHED) { + 8005c9e: 687b ldr r3, [r7, #4] + 8005ca0: 7e1b ldrb r3, [r3, #24] + 8005ca2: 2b04 cmp r3, #4 + 8005ca4: d10c bne.n 8005cc0 + /* move to TIME_WAIT since we close actively */ + pcb->state = TIME_WAIT; + 8005ca6: 687b ldr r3, [r7, #4] + 8005ca8: 220a movs r2, #10 + 8005caa: 761a strb r2, [r3, #24] + TCP_REG(&tcp_tw_pcbs, pcb); + 8005cac: 4b6a ldr r3, [pc, #424] ; (8005e58 ) + 8005cae: 681a ldr r2, [r3, #0] + 8005cb0: 687b ldr r3, [r7, #4] + 8005cb2: 60da str r2, [r3, #12] + 8005cb4: 4b68 ldr r3, [pc, #416] ; (8005e58 ) + 8005cb6: 687a ldr r2, [r7, #4] + 8005cb8: 601a str r2, [r3, #0] + 8005cba: f004 fcdb bl 800a674 + 8005cbe: e004 b.n 8005cca + } else { + /* CLOSE_WAIT: deallocate the pcb since we already sent a RST for it */ + memp_free(MEMP_TCP_PCB, pcb); + 8005cc0: 687b ldr r3, [r7, #4] + 8005cc2: 0019 movs r1, r3 + 8005cc4: 2002 movs r0, #2 + 8005cc6: f7ff f92b bl 8004f20 + } + return ERR_OK; + 8005cca: 2300 movs r3, #0 + 8005ccc: e0b8 b.n 8005e40 + } + } + + switch (pcb->state) { + 8005cce: 687b ldr r3, [r7, #4] + 8005cd0: 7e1b ldrb r3, [r3, #24] + 8005cd2: 2b07 cmp r3, #7 + 8005cd4: d900 bls.n 8005cd8 + 8005cd6: e096 b.n 8005e06 + 8005cd8: 009a lsls r2, r3, #2 + 8005cda: 4b60 ldr r3, [pc, #384] ; (8005e5c ) + 8005cdc: 18d3 adds r3, r2, r3 + 8005cde: 681b ldr r3, [r3, #0] + 8005ce0: 469f mov pc, r3 + * and the user needs some way to free it should the need arise. + * Calling tcp_close() with a pcb that has already been closed, (i.e. twice) + * or for a pcb that has been used and then entered the CLOSED state + * is erroneous, but this should never happen as the pcb has in those cases + * been freed, and so any remaining handles are bogus. */ + err = ERR_OK; + 8005ce2: 230f movs r3, #15 + 8005ce4: 18fb adds r3, r7, r3 + 8005ce6: 2200 movs r2, #0 + 8005ce8: 701a strb r2, [r3, #0] + if (pcb->local_port != 0) { + 8005cea: 687b ldr r3, [r7, #4] + 8005cec: 8b5b ldrh r3, [r3, #26] + 8005cee: 2b00 cmp r3, #0 + 8005cf0: d027 beq.n 8005d42 + TCP_RMV(&tcp_bound_pcbs, pcb); + 8005cf2: 4b5b ldr r3, [pc, #364] ; (8005e60 ) + 8005cf4: 681b ldr r3, [r3, #0] + 8005cf6: 687a ldr r2, [r7, #4] + 8005cf8: 429a cmp r2, r3 + 8005cfa: d105 bne.n 8005d08 + 8005cfc: 4b58 ldr r3, [pc, #352] ; (8005e60 ) + 8005cfe: 681b ldr r3, [r3, #0] + 8005d00: 68da ldr r2, [r3, #12] + 8005d02: 4b57 ldr r3, [pc, #348] ; (8005e60 ) + 8005d04: 601a str r2, [r3, #0] + 8005d06: e019 b.n 8005d3c + 8005d08: 4b55 ldr r3, [pc, #340] ; (8005e60 ) + 8005d0a: 681a ldr r2, [r3, #0] + 8005d0c: 4b50 ldr r3, [pc, #320] ; (8005e50 ) + 8005d0e: 601a str r2, [r3, #0] + 8005d10: e010 b.n 8005d34 + 8005d12: 4b4f ldr r3, [pc, #316] ; (8005e50 ) + 8005d14: 681b ldr r3, [r3, #0] + 8005d16: 68db ldr r3, [r3, #12] + 8005d18: 687a ldr r2, [r7, #4] + 8005d1a: 429a cmp r2, r3 + 8005d1c: d105 bne.n 8005d2a + 8005d1e: 4b4c ldr r3, [pc, #304] ; (8005e50 ) + 8005d20: 681b ldr r3, [r3, #0] + 8005d22: 687a ldr r2, [r7, #4] + 8005d24: 68d2 ldr r2, [r2, #12] + 8005d26: 60da str r2, [r3, #12] + 8005d28: e008 b.n 8005d3c + 8005d2a: 4b49 ldr r3, [pc, #292] ; (8005e50 ) + 8005d2c: 681b ldr r3, [r3, #0] + 8005d2e: 68da ldr r2, [r3, #12] + 8005d30: 4b47 ldr r3, [pc, #284] ; (8005e50 ) + 8005d32: 601a str r2, [r3, #0] + 8005d34: 4b46 ldr r3, [pc, #280] ; (8005e50 ) + 8005d36: 681b ldr r3, [r3, #0] + 8005d38: 2b00 cmp r3, #0 + 8005d3a: d1ea bne.n 8005d12 + 8005d3c: 687b ldr r3, [r7, #4] + 8005d3e: 2200 movs r2, #0 + 8005d40: 60da str r2, [r3, #12] + } + memp_free(MEMP_TCP_PCB, pcb); + 8005d42: 687b ldr r3, [r7, #4] + 8005d44: 0019 movs r1, r3 + 8005d46: 2002 movs r0, #2 + 8005d48: f7ff f8ea bl 8004f20 + pcb = NULL; + 8005d4c: 2300 movs r3, #0 + 8005d4e: 607b str r3, [r7, #4] + break; + 8005d50: e065 b.n 8005e1e + case LISTEN: + err = ERR_OK; + 8005d52: 230f movs r3, #15 + 8005d54: 18fb adds r3, r7, r3 + 8005d56: 2200 movs r2, #0 + 8005d58: 701a strb r2, [r3, #0] + tcp_pcb_remove(&tcp_listen_pcbs.pcbs, pcb); + 8005d5a: 687a ldr r2, [r7, #4] + 8005d5c: 4b41 ldr r3, [pc, #260] ; (8005e64 ) + 8005d5e: 0011 movs r1, r2 + 8005d60: 0018 movs r0, r3 + 8005d62: f000 fea3 bl 8006aac + memp_free(MEMP_TCP_PCB_LISTEN, pcb); + 8005d66: 687b ldr r3, [r7, #4] + 8005d68: 0019 movs r1, r3 + 8005d6a: 2003 movs r0, #3 + 8005d6c: f7ff f8d8 bl 8004f20 + pcb = NULL; + 8005d70: 2300 movs r3, #0 + 8005d72: 607b str r3, [r7, #4] + break; + 8005d74: e053 b.n 8005e1e + case SYN_SENT: + err = ERR_OK; + 8005d76: 230f movs r3, #15 + 8005d78: 18fb adds r3, r7, r3 + 8005d7a: 2200 movs r2, #0 + 8005d7c: 701a strb r2, [r3, #0] + TCP_PCB_REMOVE_ACTIVE(pcb); + 8005d7e: 687a ldr r2, [r7, #4] + 8005d80: 4b32 ldr r3, [pc, #200] ; (8005e4c ) + 8005d82: 0011 movs r1, r2 + 8005d84: 0018 movs r0, r3 + 8005d86: f000 fe91 bl 8006aac + 8005d8a: 4b32 ldr r3, [pc, #200] ; (8005e54 ) + 8005d8c: 2201 movs r2, #1 + 8005d8e: 701a strb r2, [r3, #0] + memp_free(MEMP_TCP_PCB, pcb); + 8005d90: 687b ldr r3, [r7, #4] + 8005d92: 0019 movs r1, r3 + 8005d94: 2002 movs r0, #2 + 8005d96: f7ff f8c3 bl 8004f20 + pcb = NULL; + 8005d9a: 2300 movs r3, #0 + 8005d9c: 607b str r3, [r7, #4] + snmp_inc_tcpattemptfails(); + break; + 8005d9e: e03e b.n 8005e1e + case SYN_RCVD: + err = tcp_send_fin(pcb); + 8005da0: 250f movs r5, #15 + 8005da2: 197c adds r4, r7, r5 + 8005da4: 687b ldr r3, [r7, #4] + 8005da6: 0018 movs r0, r3 + 8005da8: f003 fb89 bl 80094be + 8005dac: 0003 movs r3, r0 + 8005dae: 7023 strb r3, [r4, #0] + if (err == ERR_OK) { + 8005db0: 197b adds r3, r7, r5 + 8005db2: 781b ldrb r3, [r3, #0] + 8005db4: b25b sxtb r3, r3 + 8005db6: 2b00 cmp r3, #0 + 8005db8: d12c bne.n 8005e14 + snmp_inc_tcpattemptfails(); + pcb->state = FIN_WAIT_1; + 8005dba: 687b ldr r3, [r7, #4] + 8005dbc: 2205 movs r2, #5 + 8005dbe: 761a strb r2, [r3, #24] + } + break; + 8005dc0: e028 b.n 8005e14 + case ESTABLISHED: + err = tcp_send_fin(pcb); + 8005dc2: 250f movs r5, #15 + 8005dc4: 197c adds r4, r7, r5 + 8005dc6: 687b ldr r3, [r7, #4] + 8005dc8: 0018 movs r0, r3 + 8005dca: f003 fb78 bl 80094be + 8005dce: 0003 movs r3, r0 + 8005dd0: 7023 strb r3, [r4, #0] + if (err == ERR_OK) { + 8005dd2: 197b adds r3, r7, r5 + 8005dd4: 781b ldrb r3, [r3, #0] + 8005dd6: b25b sxtb r3, r3 + 8005dd8: 2b00 cmp r3, #0 + 8005dda: d11d bne.n 8005e18 + snmp_inc_tcpestabresets(); + pcb->state = FIN_WAIT_1; + 8005ddc: 687b ldr r3, [r7, #4] + 8005dde: 2205 movs r2, #5 + 8005de0: 761a strb r2, [r3, #24] + } + break; + 8005de2: e019 b.n 8005e18 + case CLOSE_WAIT: + err = tcp_send_fin(pcb); + 8005de4: 250f movs r5, #15 + 8005de6: 197c adds r4, r7, r5 + 8005de8: 687b ldr r3, [r7, #4] + 8005dea: 0018 movs r0, r3 + 8005dec: f003 fb67 bl 80094be + 8005df0: 0003 movs r3, r0 + 8005df2: 7023 strb r3, [r4, #0] + if (err == ERR_OK) { + 8005df4: 197b adds r3, r7, r5 + 8005df6: 781b ldrb r3, [r3, #0] + 8005df8: b25b sxtb r3, r3 + 8005dfa: 2b00 cmp r3, #0 + 8005dfc: d10e bne.n 8005e1c + snmp_inc_tcpestabresets(); + pcb->state = LAST_ACK; + 8005dfe: 687b ldr r3, [r7, #4] + 8005e00: 2209 movs r2, #9 + 8005e02: 761a strb r2, [r3, #24] + } + break; + 8005e04: e00a b.n 8005e1c + default: + /* Has already been closed, do nothing. */ + err = ERR_OK; + 8005e06: 230f movs r3, #15 + 8005e08: 18fb adds r3, r7, r3 + 8005e0a: 2200 movs r2, #0 + 8005e0c: 701a strb r2, [r3, #0] + pcb = NULL; + 8005e0e: 2300 movs r3, #0 + 8005e10: 607b str r3, [r7, #4] + break; + 8005e12: e004 b.n 8005e1e + break; + 8005e14: 46c0 nop ; (mov r8, r8) + 8005e16: e002 b.n 8005e1e + break; + 8005e18: 46c0 nop ; (mov r8, r8) + 8005e1a: e000 b.n 8005e1e + break; + 8005e1c: 46c0 nop ; (mov r8, r8) + } + + if (pcb != NULL && err == ERR_OK) { + 8005e1e: 687b ldr r3, [r7, #4] + 8005e20: 2b00 cmp r3, #0 + 8005e22: d009 beq.n 8005e38 + 8005e24: 230f movs r3, #15 + 8005e26: 18fb adds r3, r7, r3 + 8005e28: 781b ldrb r3, [r3, #0] + 8005e2a: b25b sxtb r3, r3 + 8005e2c: 2b00 cmp r3, #0 + 8005e2e: d103 bne.n 8005e38 + returns (unsent data is sent from tcp timer functions, also), we don't care + for the return value of tcp_output for now. */ + /* @todo: When implementing SO_LINGER, this must be changed somehow: + If SOF_LINGER is set, the data should be sent and acked before close returns. + This can only be valid for sequential APIs, not for the raw API. */ + tcp_output(pcb); + 8005e30: 687b ldr r3, [r7, #4] + 8005e32: 0018 movs r0, r3 + 8005e34: f003 fdec bl 8009a10 + } + return err; + 8005e38: 230f movs r3, #15 + 8005e3a: 18fb adds r3, r7, r3 + 8005e3c: 781b ldrb r3, [r3, #0] + 8005e3e: b25b sxtb r3, r3 +} + 8005e40: 0018 movs r0, r3 + 8005e42: 46bd mov sp, r7 + 8005e44: b004 add sp, #16 + 8005e46: bdb0 pop {r4, r5, r7, pc} + 8005e48: 000016d0 .word 0x000016d0 + 8005e4c: 20003274 .word 0x20003274 + 8005e50: 20003280 .word 0x20003280 + 8005e54: 20003270 .word 0x20003270 + 8005e58: 20003288 .word 0x20003288 + 8005e5c: 0800fd78 .word 0x0800fd78 + 8005e60: 20003284 .word 0x20003284 + 8005e64: 2000327c .word 0x2000327c + +08005e68 : + * @return ERR_OK if connection has been closed + * another err_t if closing failed and pcb is not freed + */ +err_t +tcp_close(struct tcp_pcb *pcb) +{ + 8005e68: b580 push {r7, lr} + 8005e6a: b082 sub sp, #8 + 8005e6c: af00 add r7, sp, #0 + 8005e6e: 6078 str r0, [r7, #4] +#if TCP_DEBUG + LWIP_DEBUGF(TCP_DEBUG, ("tcp_close: closing in ")); + tcp_debug_print_state(pcb->state); +#endif /* TCP_DEBUG */ + + if (pcb->state != LISTEN) { + 8005e70: 687b ldr r3, [r7, #4] + 8005e72: 7e1b ldrb r3, [r3, #24] + 8005e74: 2b01 cmp r3, #1 + 8005e76: d006 beq.n 8005e86 + /* Set a flag not to receive any more data... */ + pcb->flags |= TF_RXCLOSED; + 8005e78: 687b ldr r3, [r7, #4] + 8005e7a: 7f9b ldrb r3, [r3, #30] + 8005e7c: 2210 movs r2, #16 + 8005e7e: 4313 orrs r3, r2 + 8005e80: b2da uxtb r2, r3 + 8005e82: 687b ldr r3, [r7, #4] + 8005e84: 779a strb r2, [r3, #30] + } + /* ... and close */ + return tcp_close_shutdown(pcb, 1); + 8005e86: 687b ldr r3, [r7, #4] + 8005e88: 2101 movs r1, #1 + 8005e8a: 0018 movs r0, r3 + 8005e8c: f7ff feaa bl 8005be4 + 8005e90: 0003 movs r3, r0 +} + 8005e92: 0018 movs r0, r3 + 8005e94: 46bd mov sp, r7 + 8005e96: b002 add sp, #8 + 8005e98: bd80 pop {r7, pc} + ... + +08005e9c : + * @param pcb the tcp_pcb to abort + * @param reset boolean to indicate whether a reset should be sent + */ +void +tcp_abandon(struct tcp_pcb *pcb, int reset) +{ + 8005e9c: b5b0 push {r4, r5, r7, lr} + 8005e9e: b088 sub sp, #32 + 8005ea0: af02 add r7, sp, #8 + 8005ea2: 6078 str r0, [r7, #4] + 8005ea4: 6039 str r1, [r7, #0] + LWIP_ASSERT("don't call tcp_abort/tcp_abandon for listen-pcbs", + pcb->state != LISTEN); + /* Figure out on which TCP PCB list we are, and remove us. If we + are in an active state, call the receive function associated with + the PCB with a NULL argument, and send an RST to the remote end. */ + if (pcb->state == TIME_WAIT) { + 8005ea6: 687b ldr r3, [r7, #4] + 8005ea8: 7e1b ldrb r3, [r3, #24] + 8005eaa: 2b0a cmp r3, #10 + 8005eac: d10b bne.n 8005ec6 + tcp_pcb_remove(&tcp_tw_pcbs, pcb); + 8005eae: 687a ldr r2, [r7, #4] + 8005eb0: 4b2f ldr r3, [pc, #188] ; (8005f70 ) + 8005eb2: 0011 movs r1, r2 + 8005eb4: 0018 movs r0, r3 + 8005eb6: f000 fdf9 bl 8006aac + memp_free(MEMP_TCP_PCB, pcb); + 8005eba: 687b ldr r3, [r7, #4] + 8005ebc: 0019 movs r1, r3 + 8005ebe: 2002 movs r0, #2 + 8005ec0: f7ff f82e bl 8004f20 + tcp_rst(seqno, ackno, &pcb->local_ip, &pcb->remote_ip, pcb->local_port, pcb->remote_port); + } + memp_free(MEMP_TCP_PCB, pcb); + TCP_EVENT_ERR(errf, errf_arg, ERR_ABRT); + } +} + 8005ec4: e050 b.n 8005f68 + seqno = pcb->snd_nxt; + 8005ec6: 687b ldr r3, [r7, #4] + 8005ec8: 6d1b ldr r3, [r3, #80] ; 0x50 + 8005eca: 617b str r3, [r7, #20] + ackno = pcb->rcv_nxt; + 8005ecc: 687b ldr r3, [r7, #4] + 8005ece: 6a9b ldr r3, [r3, #40] ; 0x28 + 8005ed0: 613b str r3, [r7, #16] + errf = pcb->errf; + 8005ed2: 687b ldr r3, [r7, #4] + 8005ed4: 228c movs r2, #140 ; 0x8c + 8005ed6: 589b ldr r3, [r3, r2] + 8005ed8: 60fb str r3, [r7, #12] + errf_arg = pcb->callback_arg; + 8005eda: 687b ldr r3, [r7, #4] + 8005edc: 691b ldr r3, [r3, #16] + 8005ede: 60bb str r3, [r7, #8] + TCP_PCB_REMOVE_ACTIVE(pcb); + 8005ee0: 687a ldr r2, [r7, #4] + 8005ee2: 4b24 ldr r3, [pc, #144] ; (8005f74 ) + 8005ee4: 0011 movs r1, r2 + 8005ee6: 0018 movs r0, r3 + 8005ee8: f000 fde0 bl 8006aac + 8005eec: 4b22 ldr r3, [pc, #136] ; (8005f78 ) + 8005eee: 2201 movs r2, #1 + 8005ef0: 701a strb r2, [r3, #0] + if (pcb->unacked != NULL) { + 8005ef2: 687b ldr r3, [r7, #4] + 8005ef4: 6f1b ldr r3, [r3, #112] ; 0x70 + 8005ef6: 2b00 cmp r3, #0 + 8005ef8: d004 beq.n 8005f04 + tcp_segs_free(pcb->unacked); + 8005efa: 687b ldr r3, [r7, #4] + 8005efc: 6f1b ldr r3, [r3, #112] ; 0x70 + 8005efe: 0018 movs r0, r3 + 8005f00: f000 fbf8 bl 80066f4 + if (pcb->unsent != NULL) { + 8005f04: 687b ldr r3, [r7, #4] + 8005f06: 6edb ldr r3, [r3, #108] ; 0x6c + 8005f08: 2b00 cmp r3, #0 + 8005f0a: d004 beq.n 8005f16 + tcp_segs_free(pcb->unsent); + 8005f0c: 687b ldr r3, [r7, #4] + 8005f0e: 6edb ldr r3, [r3, #108] ; 0x6c + 8005f10: 0018 movs r0, r3 + 8005f12: f000 fbef bl 80066f4 + if (pcb->ooseq != NULL) { + 8005f16: 687b ldr r3, [r7, #4] + 8005f18: 6f5b ldr r3, [r3, #116] ; 0x74 + 8005f1a: 2b00 cmp r3, #0 + 8005f1c: d004 beq.n 8005f28 + tcp_segs_free(pcb->ooseq); + 8005f1e: 687b ldr r3, [r7, #4] + 8005f20: 6f5b ldr r3, [r3, #116] ; 0x74 + 8005f22: 0018 movs r0, r3 + 8005f24: f000 fbe6 bl 80066f4 + if (reset) { + 8005f28: 683b ldr r3, [r7, #0] + 8005f2a: 2b00 cmp r3, #0 + 8005f2c: d00e beq.n 8005f4c + tcp_rst(seqno, ackno, &pcb->local_ip, &pcb->remote_ip, pcb->local_port, pcb->remote_port); + 8005f2e: 687c ldr r4, [r7, #4] + 8005f30: 687b ldr r3, [r7, #4] + 8005f32: 1d1d adds r5, r3, #4 + 8005f34: 687b ldr r3, [r7, #4] + 8005f36: 8b5b ldrh r3, [r3, #26] + 8005f38: 687a ldr r2, [r7, #4] + 8005f3a: 8b92 ldrh r2, [r2, #28] + 8005f3c: 6939 ldr r1, [r7, #16] + 8005f3e: 6978 ldr r0, [r7, #20] + 8005f40: 9201 str r2, [sp, #4] + 8005f42: 9300 str r3, [sp, #0] + 8005f44: 002b movs r3, r5 + 8005f46: 0022 movs r2, r4 + 8005f48: f004 f840 bl 8009fcc + memp_free(MEMP_TCP_PCB, pcb); + 8005f4c: 687b ldr r3, [r7, #4] + 8005f4e: 0019 movs r1, r3 + 8005f50: 2002 movs r0, #2 + 8005f52: f7fe ffe5 bl 8004f20 + TCP_EVENT_ERR(errf, errf_arg, ERR_ABRT); + 8005f56: 68fb ldr r3, [r7, #12] + 8005f58: 2b00 cmp r3, #0 + 8005f5a: d005 beq.n 8005f68 + 8005f5c: 230a movs r3, #10 + 8005f5e: 4259 negs r1, r3 + 8005f60: 68ba ldr r2, [r7, #8] + 8005f62: 68fb ldr r3, [r7, #12] + 8005f64: 0010 movs r0, r2 + 8005f66: 4798 blx r3 +} + 8005f68: 46c0 nop ; (mov r8, r8) + 8005f6a: 46bd mov sp, r7 + 8005f6c: b006 add sp, #24 + 8005f6e: bdb0 pop {r4, r5, r7, pc} + 8005f70: 20003288 .word 0x20003288 + 8005f74: 20003274 .word 0x20003274 + 8005f78: 20003270 .word 0x20003270 + +08005f7c : + * + * @param pcb the tcp pcb to abort + */ +void +tcp_abort(struct tcp_pcb *pcb) +{ + 8005f7c: b580 push {r7, lr} + 8005f7e: b082 sub sp, #8 + 8005f80: af00 add r7, sp, #0 + 8005f82: 6078 str r0, [r7, #4] + tcp_abandon(pcb, 1); + 8005f84: 687b ldr r3, [r7, #4] + 8005f86: 2101 movs r1, #1 + 8005f88: 0018 movs r0, r3 + 8005f8a: f7ff ff87 bl 8005e9c +} + 8005f8e: 46c0 nop ; (mov r8, r8) + 8005f90: 46bd mov sp, r7 + 8005f92: b002 add sp, #8 + 8005f94: bd80 pop {r7, pc} + ... + +08005f98 : + * + * Returns how much extra window would be advertised if we sent an + * update now. + */ +u32_t tcp_update_rcv_ann_wnd(struct tcp_pcb *pcb) +{ + 8005f98: b580 push {r7, lr} + 8005f9a: b084 sub sp, #16 + 8005f9c: af00 add r7, sp, #0 + 8005f9e: 6078 str r0, [r7, #4] + u32_t new_right_edge = pcb->rcv_nxt + pcb->rcv_wnd; + 8005fa0: 687b ldr r3, [r7, #4] + 8005fa2: 6a9b ldr r3, [r3, #40] ; 0x28 + 8005fa4: 687a ldr r2, [r7, #4] + 8005fa6: 8d92 ldrh r2, [r2, #44] ; 0x2c + 8005fa8: 189b adds r3, r3, r2 + 8005faa: 60fb str r3, [r7, #12] + + if (TCP_SEQ_GEQ(new_right_edge, pcb->rcv_ann_right_edge + LWIP_MIN((TCP_WND / 2), pcb->mss))) { + 8005fac: 687b ldr r3, [r7, #4] + 8005fae: 6b1b ldr r3, [r3, #48] ; 0x30 + 8005fb0: 687a ldr r2, [r7, #4] + 8005fb2: 8ed2 ldrh r2, [r2, #54] ; 0x36 + 8005fb4: 1c10 adds r0, r2, #0 + 8005fb6: b282 uxth r2, r0 + 8005fb8: 4916 ldr r1, [pc, #88] ; (8006014 ) + 8005fba: 428a cmp r2, r1 + 8005fbc: d901 bls.n 8005fc2 + 8005fbe: 4a15 ldr r2, [pc, #84] ; (8006014 ) + 8005fc0: 1c10 adds r0, r2, #0 + 8005fc2: b282 uxth r2, r0 + 8005fc4: 189b adds r3, r3, r2 + 8005fc6: 68fa ldr r2, [r7, #12] + 8005fc8: 1ad3 subs r3, r2, r3 + 8005fca: d408 bmi.n 8005fde + /* we can advertise more window */ + pcb->rcv_ann_wnd = pcb->rcv_wnd; + 8005fcc: 687b ldr r3, [r7, #4] + 8005fce: 8d9a ldrh r2, [r3, #44] ; 0x2c + 8005fd0: 687b ldr r3, [r7, #4] + 8005fd2: 85da strh r2, [r3, #46] ; 0x2e + return new_right_edge - pcb->rcv_ann_right_edge; + 8005fd4: 687b ldr r3, [r7, #4] + 8005fd6: 6b1b ldr r3, [r3, #48] ; 0x30 + 8005fd8: 68fa ldr r2, [r7, #12] + 8005fda: 1ad3 subs r3, r2, r3 + 8005fdc: e015 b.n 800600a + } else { + if (TCP_SEQ_GT(pcb->rcv_nxt, pcb->rcv_ann_right_edge)) { + 8005fde: 687b ldr r3, [r7, #4] + 8005fe0: 6a9a ldr r2, [r3, #40] ; 0x28 + 8005fe2: 687b ldr r3, [r7, #4] + 8005fe4: 6b1b ldr r3, [r3, #48] ; 0x30 + 8005fe6: 1ad3 subs r3, r2, r3 + 8005fe8: 2b00 cmp r3, #0 + 8005fea: dd03 ble.n 8005ff4 + /* Can happen due to other end sending out of advertised window, + * but within actual available (but not yet advertised) window */ + pcb->rcv_ann_wnd = 0; + 8005fec: 687b ldr r3, [r7, #4] + 8005fee: 2200 movs r2, #0 + 8005ff0: 85da strh r2, [r3, #46] ; 0x2e + 8005ff2: e009 b.n 8006008 + } else { + /* keep the right edge of window constant */ + u32_t new_rcv_ann_wnd = pcb->rcv_ann_right_edge - pcb->rcv_nxt; + 8005ff4: 687b ldr r3, [r7, #4] + 8005ff6: 6b1a ldr r2, [r3, #48] ; 0x30 + 8005ff8: 687b ldr r3, [r7, #4] + 8005ffa: 6a9b ldr r3, [r3, #40] ; 0x28 + 8005ffc: 1ad3 subs r3, r2, r3 + 8005ffe: 60bb str r3, [r7, #8] + LWIP_ASSERT("new_rcv_ann_wnd <= 0xffff", new_rcv_ann_wnd <= 0xffff); + pcb->rcv_ann_wnd = (u16_t)new_rcv_ann_wnd; + 8006000: 68bb ldr r3, [r7, #8] + 8006002: b29a uxth r2, r3 + 8006004: 687b ldr r3, [r7, #4] + 8006006: 85da strh r2, [r3, #46] ; 0x2e + } + return 0; + 8006008: 2300 movs r3, #0 + } +} + 800600a: 0018 movs r0, r3 + 800600c: 46bd mov sp, r7 + 800600e: b004 add sp, #16 + 8006010: bd80 pop {r7, pc} + 8006012: 46c0 nop ; (mov r8, r8) + 8006014: 00000b68 .word 0x00000b68 + +08006018 : + * @param pcb the tcp_pcb for which data is read + * @param len the amount of bytes that have been read by the application + */ +void +tcp_recved(struct tcp_pcb *pcb, u16_t len) +{ + 8006018: b580 push {r7, lr} + 800601a: b084 sub sp, #16 + 800601c: af00 add r7, sp, #0 + 800601e: 6078 str r0, [r7, #4] + 8006020: 000a movs r2, r1 + 8006022: 1cbb adds r3, r7, #2 + 8006024: 801a strh r2, [r3, #0] + LWIP_ASSERT("don't call tcp_recved for listen-pcbs", + pcb->state != LISTEN); + LWIP_ASSERT("tcp_recved: len would wrap rcv_wnd\n", + len <= 0xffff - pcb->rcv_wnd ); + + pcb->rcv_wnd += len; + 8006026: 687b ldr r3, [r7, #4] + 8006028: 8d9a ldrh r2, [r3, #44] ; 0x2c + 800602a: 1cbb adds r3, r7, #2 + 800602c: 881b ldrh r3, [r3, #0] + 800602e: 18d3 adds r3, r2, r3 + 8006030: b29a uxth r2, r3 + 8006032: 687b ldr r3, [r7, #4] + 8006034: 859a strh r2, [r3, #44] ; 0x2c + if (pcb->rcv_wnd > TCP_WND) { + 8006036: 687b ldr r3, [r7, #4] + 8006038: 8d9b ldrh r3, [r3, #44] ; 0x2c + 800603a: 4a0f ldr r2, [pc, #60] ; (8006078 ) + 800603c: 4293 cmp r3, r2 + 800603e: d902 bls.n 8006046 + pcb->rcv_wnd = TCP_WND; + 8006040: 687b ldr r3, [r7, #4] + 8006042: 4a0d ldr r2, [pc, #52] ; (8006078 ) + 8006044: 859a strh r2, [r3, #44] ; 0x2c + } + + wnd_inflation = tcp_update_rcv_ann_wnd(pcb); + 8006046: 687b ldr r3, [r7, #4] + 8006048: 0018 movs r0, r3 + 800604a: f7ff ffa5 bl 8005f98 + 800604e: 0003 movs r3, r0 + 8006050: 60fb str r3, [r7, #12] + + /* If the change in the right edge of window is significant (default + * watermark is TCP_WND/4), then send an explicit update now. + * Otherwise wait for a packet to be sent in the normal course of + * events (or more window to be available later) */ + if (wnd_inflation >= TCP_WND_UPDATE_THRESHOLD) { + 8006052: 68fb ldr r3, [r7, #12] + 8006054: 4a09 ldr r2, [pc, #36] ; (800607c ) + 8006056: 4293 cmp r3, r2 + 8006058: dd0a ble.n 8006070 + tcp_ack_now(pcb); + 800605a: 687b ldr r3, [r7, #4] + 800605c: 7f9b ldrb r3, [r3, #30] + 800605e: 2202 movs r2, #2 + 8006060: 4313 orrs r3, r2 + 8006062: b2da uxtb r2, r3 + 8006064: 687b ldr r3, [r7, #4] + 8006066: 779a strb r2, [r3, #30] + tcp_output(pcb); + 8006068: 687b ldr r3, [r7, #4] + 800606a: 0018 movs r0, r3 + 800606c: f003 fcd0 bl 8009a10 + } + + LWIP_DEBUGF(TCP_DEBUG, ("tcp_recved: recveived %"U16_F" bytes, wnd %"U16_F" (%"U16_F").\n", + len, pcb->rcv_wnd, TCP_WND - pcb->rcv_wnd)); +} + 8006070: 46c0 nop ; (mov r8, r8) + 8006072: 46bd mov sp, r7 + 8006074: b004 add sp, #16 + 8006076: bd80 pop {r7, pc} + 8006078: 000016d0 .word 0x000016d0 + 800607c: 000005b3 .word 0x000005b3 + +08006080 : + * + * Automatically called from tcp_tmr(). + */ +void +tcp_slowtmr(void) +{ + 8006080: b5b0 push {r4, r5, r7, lr} + 8006082: b08a sub sp, #40 ; 0x28 + 8006084: af02 add r7, sp, #8 + u16_t eff_wnd; + u8_t pcb_remove; /* flag if a PCB should be removed */ + u8_t pcb_reset; /* flag if a RST should be sent when removing */ + err_t err; + + err = ERR_OK; + 8006086: 2315 movs r3, #21 + 8006088: 18fb adds r3, r7, r3 + 800608a: 2200 movs r2, #0 + 800608c: 701a strb r2, [r3, #0] + + ++tcp_ticks; + 800608e: 4bc8 ldr r3, [pc, #800] ; (80063b0 ) + 8006090: 681b ldr r3, [r3, #0] + 8006092: 1c5a adds r2, r3, #1 + 8006094: 4bc6 ldr r3, [pc, #792] ; (80063b0 ) + 8006096: 601a str r2, [r3, #0] + ++tcp_timer_ctr; + 8006098: 4bc6 ldr r3, [pc, #792] ; (80063b4 ) + 800609a: 781b ldrb r3, [r3, #0] + 800609c: 3301 adds r3, #1 + 800609e: b2da uxtb r2, r3 + 80060a0: 4bc4 ldr r3, [pc, #784] ; (80063b4 ) + 80060a2: 701a strb r2, [r3, #0] + +tcp_slowtmr_start: + /* Steps through all of the active PCBs. */ + prev = NULL; + 80060a4: 2300 movs r3, #0 + 80060a6: 61bb str r3, [r7, #24] + pcb = tcp_active_pcbs; + 80060a8: 4bc3 ldr r3, [pc, #780] ; (80063b8 ) + 80060aa: 681b ldr r3, [r3, #0] + 80060ac: 61fb str r3, [r7, #28] + if (pcb == NULL) { + LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: no active pcbs\n")); + } + while (pcb != NULL) { + 80060ae: e206 b.n 80064be + LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: processing active pcb\n")); + LWIP_ASSERT("tcp_slowtmr: active pcb->state != CLOSED\n", pcb->state != CLOSED); + LWIP_ASSERT("tcp_slowtmr: active pcb->state != LISTEN\n", pcb->state != LISTEN); + LWIP_ASSERT("tcp_slowtmr: active pcb->state != TIME-WAIT\n", pcb->state != TIME_WAIT); + if (pcb->last_timer == tcp_timer_ctr) { + 80060b0: 69fb ldr r3, [r7, #28] + 80060b2: 2221 movs r2, #33 ; 0x21 + 80060b4: 5c9a ldrb r2, [r3, r2] + 80060b6: 4bbf ldr r3, [pc, #764] ; (80063b4 ) + 80060b8: 781b ldrb r3, [r3, #0] + 80060ba: 429a cmp r2, r3 + 80060bc: d103 bne.n 80060c6 + /* skip this pcb, we have already processed it */ + pcb = pcb->next; + 80060be: 69fb ldr r3, [r7, #28] + 80060c0: 68db ldr r3, [r3, #12] + 80060c2: 61fb str r3, [r7, #28] + continue; + 80060c4: e1fb b.n 80064be + } + pcb->last_timer = tcp_timer_ctr; + 80060c6: 4bbb ldr r3, [pc, #748] ; (80063b4 ) + 80060c8: 7819 ldrb r1, [r3, #0] + 80060ca: 69fb ldr r3, [r7, #28] + 80060cc: 2221 movs r2, #33 ; 0x21 + 80060ce: 5499 strb r1, [r3, r2] + + pcb_remove = 0; + 80060d0: 2317 movs r3, #23 + 80060d2: 18fb adds r3, r7, r3 + 80060d4: 2200 movs r2, #0 + 80060d6: 701a strb r2, [r3, #0] + pcb_reset = 0; + 80060d8: 2316 movs r3, #22 + 80060da: 18fb adds r3, r7, r3 + 80060dc: 2200 movs r2, #0 + 80060de: 701a strb r2, [r3, #0] + + if (pcb->state == SYN_SENT && pcb->nrtx == TCP_SYNMAXRTX) { + 80060e0: 69fb ldr r3, [r7, #28] + 80060e2: 7e1b ldrb r3, [r3, #24] + 80060e4: 2b02 cmp r3, #2 + 80060e6: d10b bne.n 8006100 + 80060e8: 69fb ldr r3, [r7, #28] + 80060ea: 2246 movs r2, #70 ; 0x46 + 80060ec: 5c9b ldrb r3, [r3, r2] + 80060ee: 2b06 cmp r3, #6 + 80060f0: d106 bne.n 8006100 + ++pcb_remove; + 80060f2: 2217 movs r2, #23 + 80060f4: 18bb adds r3, r7, r2 + 80060f6: 18ba adds r2, r7, r2 + 80060f8: 7812 ldrb r2, [r2, #0] + 80060fa: 3201 adds r2, #1 + 80060fc: 701a strb r2, [r3, #0] + 80060fe: e0a1 b.n 8006244 + LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: max SYN retries reached\n")); + } + else if (pcb->nrtx == TCP_MAXRTX) { + 8006100: 69fb ldr r3, [r7, #28] + 8006102: 2246 movs r2, #70 ; 0x46 + 8006104: 5c9b ldrb r3, [r3, r2] + 8006106: 2b0c cmp r3, #12 + 8006108: d106 bne.n 8006118 + ++pcb_remove; + 800610a: 2217 movs r2, #23 + 800610c: 18bb adds r3, r7, r2 + 800610e: 18ba adds r2, r7, r2 + 8006110: 7812 ldrb r2, [r2, #0] + 8006112: 3201 adds r2, #1 + 8006114: 701a strb r2, [r3, #0] + 8006116: e095 b.n 8006244 + LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: max DATA retries reached\n")); + } else { + if (pcb->persist_backoff > 0) { + 8006118: 69fb ldr r3, [r7, #28] + 800611a: 2295 movs r2, #149 ; 0x95 + 800611c: 5c9b ldrb r3, [r3, r2] + 800611e: 2b00 cmp r3, #0 + 8006120: d029 beq.n 8006176 + /* If snd_wnd is zero, use persist timer to send 1 byte probes + * instead of using the standard retransmission mechanism. */ + pcb->persist_cnt++; + 8006122: 69fb ldr r3, [r7, #28] + 8006124: 2294 movs r2, #148 ; 0x94 + 8006126: 5c9b ldrb r3, [r3, r2] + 8006128: 3301 adds r3, #1 + 800612a: b2d9 uxtb r1, r3 + 800612c: 69fb ldr r3, [r7, #28] + 800612e: 2294 movs r2, #148 ; 0x94 + 8006130: 5499 strb r1, [r3, r2] + if (pcb->persist_cnt >= tcp_persist_backoff[pcb->persist_backoff-1]) { + 8006132: 69fb ldr r3, [r7, #28] + 8006134: 2294 movs r2, #148 ; 0x94 + 8006136: 5c9a ldrb r2, [r3, r2] + 8006138: 69fb ldr r3, [r7, #28] + 800613a: 2195 movs r1, #149 ; 0x95 + 800613c: 5c5b ldrb r3, [r3, r1] + 800613e: 3b01 subs r3, #1 + 8006140: 499e ldr r1, [pc, #632] ; (80063bc ) + 8006142: 5ccb ldrb r3, [r1, r3] + 8006144: 429a cmp r2, r3 + 8006146: d200 bcs.n 800614a + 8006148: e07c b.n 8006244 + pcb->persist_cnt = 0; + 800614a: 69fb ldr r3, [r7, #28] + 800614c: 2294 movs r2, #148 ; 0x94 + 800614e: 2100 movs r1, #0 + 8006150: 5499 strb r1, [r3, r2] + if (pcb->persist_backoff < sizeof(tcp_persist_backoff)) { + 8006152: 69fb ldr r3, [r7, #28] + 8006154: 2295 movs r2, #149 ; 0x95 + 8006156: 5c9b ldrb r3, [r3, r2] + 8006158: 2b06 cmp r3, #6 + 800615a: d807 bhi.n 800616c + pcb->persist_backoff++; + 800615c: 69fb ldr r3, [r7, #28] + 800615e: 2295 movs r2, #149 ; 0x95 + 8006160: 5c9b ldrb r3, [r3, r2] + 8006162: 3301 adds r3, #1 + 8006164: b2d9 uxtb r1, r3 + 8006166: 69fb ldr r3, [r7, #28] + 8006168: 2295 movs r2, #149 ; 0x95 + 800616a: 5499 strb r1, [r3, r2] + } + tcp_zero_window_probe(pcb); + 800616c: 69fb ldr r3, [r7, #28] + 800616e: 0018 movs r0, r3 + 8006170: f004 f98c bl 800a48c + 8006174: e066 b.n 8006244 + } + } else { + /* Increase the retransmission timer if it is running */ + if(pcb->rtime >= 0) { + 8006176: 69fb ldr r3, [r7, #28] + 8006178: 2234 movs r2, #52 ; 0x34 + 800617a: 5e9b ldrsh r3, [r3, r2] + 800617c: 2b00 cmp r3, #0 + 800617e: db08 blt.n 8006192 + ++pcb->rtime; + 8006180: 69fb ldr r3, [r7, #28] + 8006182: 2234 movs r2, #52 ; 0x34 + 8006184: 5e9b ldrsh r3, [r3, r2] + 8006186: b29b uxth r3, r3 + 8006188: 3301 adds r3, #1 + 800618a: b29b uxth r3, r3 + 800618c: b21a sxth r2, r3 + 800618e: 69fb ldr r3, [r7, #28] + 8006190: 869a strh r2, [r3, #52] ; 0x34 + } + + if (pcb->unacked != NULL && pcb->rtime >= pcb->rto) { + 8006192: 69fb ldr r3, [r7, #28] + 8006194: 6f1b ldr r3, [r3, #112] ; 0x70 + 8006196: 2b00 cmp r3, #0 + 8006198: d054 beq.n 8006244 + 800619a: 69fb ldr r3, [r7, #28] + 800619c: 2234 movs r2, #52 ; 0x34 + 800619e: 5e9a ldrsh r2, [r3, r2] + 80061a0: 69fb ldr r3, [r7, #28] + 80061a2: 2144 movs r1, #68 ; 0x44 + 80061a4: 5e5b ldrsh r3, [r3, r1] + 80061a6: 429a cmp r2, r3 + 80061a8: db4c blt.n 8006244 + " pcb->rto %"S16_F"\n", + pcb->rtime, pcb->rto)); + + /* Double retransmission time-out unless we are trying to + * connect to somebody (i.e., we are in SYN_SENT). */ + if (pcb->state != SYN_SENT) { + 80061aa: 69fb ldr r3, [r7, #28] + 80061ac: 7e1b ldrb r3, [r3, #24] + 80061ae: 2b02 cmp r3, #2 + 80061b0: d014 beq.n 80061dc + pcb->rto = ((pcb->sa >> 3) + pcb->sv) << tcp_backoff[pcb->nrtx]; + 80061b2: 69fb ldr r3, [r7, #28] + 80061b4: 2240 movs r2, #64 ; 0x40 + 80061b6: 5e9b ldrsh r3, [r3, r2] + 80061b8: 10db asrs r3, r3, #3 + 80061ba: b21b sxth r3, r3 + 80061bc: 0019 movs r1, r3 + 80061be: 69fb ldr r3, [r7, #28] + 80061c0: 2242 movs r2, #66 ; 0x42 + 80061c2: 5e9b ldrsh r3, [r3, r2] + 80061c4: 18cb adds r3, r1, r3 + 80061c6: 69fa ldr r2, [r7, #28] + 80061c8: 2146 movs r1, #70 ; 0x46 + 80061ca: 5c52 ldrb r2, [r2, r1] + 80061cc: 0011 movs r1, r2 + 80061ce: 4a7c ldr r2, [pc, #496] ; (80063c0 ) + 80061d0: 5c52 ldrb r2, [r2, r1] + 80061d2: 4093 lsls r3, r2 + 80061d4: b219 sxth r1, r3 + 80061d6: 69fb ldr r3, [r7, #28] + 80061d8: 2244 movs r2, #68 ; 0x44 + 80061da: 5299 strh r1, [r3, r2] + } + + /* Reset the retransmission timer. */ + pcb->rtime = 0; + 80061dc: 69fb ldr r3, [r7, #28] + 80061de: 2200 movs r2, #0 + 80061e0: 869a strh r2, [r3, #52] ; 0x34 + + /* Reduce congestion window and ssthresh. */ + eff_wnd = LWIP_MIN(pcb->cwnd, pcb->snd_wnd); + 80061e2: 69fb ldr r3, [r7, #28] + 80061e4: 2260 movs r2, #96 ; 0x60 + 80061e6: 5a99 ldrh r1, [r3, r2] + 80061e8: 69fb ldr r3, [r7, #28] + 80061ea: 224c movs r2, #76 ; 0x4c + 80061ec: 5a9b ldrh r3, [r3, r2] + 80061ee: 220e movs r2, #14 + 80061f0: 18ba adds r2, r7, r2 + 80061f2: 1c1c adds r4, r3, #0 + 80061f4: 1c0b adds r3, r1, #0 + 80061f6: b298 uxth r0, r3 + 80061f8: b2a1 uxth r1, r4 + 80061fa: 4288 cmp r0, r1 + 80061fc: d900 bls.n 8006200 + 80061fe: 1c23 adds r3, r4, #0 + 8006200: 8013 strh r3, [r2, #0] + pcb->ssthresh = eff_wnd >> 1; + 8006202: 230e movs r3, #14 + 8006204: 18fb adds r3, r7, r3 + 8006206: 881b ldrh r3, [r3, #0] + 8006208: 085b lsrs r3, r3, #1 + 800620a: b299 uxth r1, r3 + 800620c: 69fb ldr r3, [r7, #28] + 800620e: 224e movs r2, #78 ; 0x4e + 8006210: 5299 strh r1, [r3, r2] + if (pcb->ssthresh < (pcb->mss << 1)) { + 8006212: 69fb ldr r3, [r7, #28] + 8006214: 224e movs r2, #78 ; 0x4e + 8006216: 5a9b ldrh r3, [r3, r2] + 8006218: 001a movs r2, r3 + 800621a: 69fb ldr r3, [r7, #28] + 800621c: 8edb ldrh r3, [r3, #54] ; 0x36 + 800621e: 005b lsls r3, r3, #1 + 8006220: 429a cmp r2, r3 + 8006222: da06 bge.n 8006232 + pcb->ssthresh = (pcb->mss << 1); + 8006224: 69fb ldr r3, [r7, #28] + 8006226: 8edb ldrh r3, [r3, #54] ; 0x36 + 8006228: 18db adds r3, r3, r3 + 800622a: b299 uxth r1, r3 + 800622c: 69fb ldr r3, [r7, #28] + 800622e: 224e movs r2, #78 ; 0x4e + 8006230: 5299 strh r1, [r3, r2] + } + pcb->cwnd = pcb->mss; + 8006232: 69fb ldr r3, [r7, #28] + 8006234: 8ed9 ldrh r1, [r3, #54] ; 0x36 + 8006236: 69fb ldr r3, [r7, #28] + 8006238: 224c movs r2, #76 ; 0x4c + 800623a: 5299 strh r1, [r3, r2] + " ssthresh %"U16_F"\n", + pcb->cwnd, pcb->ssthresh)); + + /* The following needs to be called AFTER cwnd is set to one + mss - STJ */ + tcp_rexmit_rto(pcb); + 800623c: 69fb ldr r3, [r7, #28] + 800623e: 0018 movs r0, r3 + 8006240: f003 ffe8 bl 800a214 + } + } + } + /* Check if this PCB has stayed too long in FIN-WAIT-2 */ + if (pcb->state == FIN_WAIT_2) { + 8006244: 69fb ldr r3, [r7, #28] + 8006246: 7e1b ldrb r3, [r3, #24] + 8006248: 2b06 cmp r3, #6 + 800624a: d112 bne.n 8006272 + /* If this PCB is in FIN_WAIT_2 because of SHUT_WR don't let it time out. */ + if (pcb->flags & TF_RXCLOSED) { + 800624c: 69fb ldr r3, [r7, #28] + 800624e: 7f9b ldrb r3, [r3, #30] + 8006250: 001a movs r2, r3 + 8006252: 2310 movs r3, #16 + 8006254: 4013 ands r3, r2 + 8006256: d00c beq.n 8006272 + /* PCB was fully closed (either through close() or SHUT_RDWR): + normal FIN-WAIT timeout handling. */ + if ((u32_t)(tcp_ticks - pcb->tmr) > + 8006258: 4b55 ldr r3, [pc, #340] ; (80063b0 ) + 800625a: 681a ldr r2, [r3, #0] + 800625c: 69fb ldr r3, [r7, #28] + 800625e: 6a5b ldr r3, [r3, #36] ; 0x24 + 8006260: 1ad3 subs r3, r2, r3 + 8006262: 2b28 cmp r3, #40 ; 0x28 + 8006264: d905 bls.n 8006272 + TCP_FIN_WAIT_TIMEOUT / TCP_SLOW_INTERVAL) { + ++pcb_remove; + 8006266: 2217 movs r2, #23 + 8006268: 18bb adds r3, r7, r2 + 800626a: 18ba adds r2, r7, r2 + 800626c: 7812 ldrb r2, [r2, #0] + 800626e: 3201 adds r2, #1 + 8006270: 701a strb r2, [r3, #0] + } + } + } + + /* Check if KEEPALIVE should be sent */ + if(ip_get_option(pcb, SOF_KEEPALIVE) && + 8006272: 69fb ldr r3, [r7, #28] + 8006274: 7a1b ldrb r3, [r3, #8] + 8006276: 001a movs r2, r3 + 8006278: 2308 movs r3, #8 + 800627a: 4013 ands r3, r2 + 800627c: d049 beq.n 8006312 + ((pcb->state == ESTABLISHED) || + 800627e: 69fb ldr r3, [r7, #28] + 8006280: 7e1b ldrb r3, [r3, #24] + if(ip_get_option(pcb, SOF_KEEPALIVE) && + 8006282: 2b04 cmp r3, #4 + 8006284: d003 beq.n 800628e + (pcb->state == CLOSE_WAIT))) { + 8006286: 69fb ldr r3, [r7, #28] + 8006288: 7e1b ldrb r3, [r3, #24] + ((pcb->state == ESTABLISHED) || + 800628a: 2b07 cmp r3, #7 + 800628c: d141 bne.n 8006312 + if((u32_t)(tcp_ticks - pcb->tmr) > + 800628e: 4b48 ldr r3, [pc, #288] ; (80063b0 ) + 8006290: 681a ldr r2, [r3, #0] + 8006292: 69fb ldr r3, [r7, #28] + 8006294: 6a5b ldr r3, [r3, #36] ; 0x24 + 8006296: 1ad4 subs r4, r2, r3 + (pcb->keep_idle + TCP_KEEP_DUR(pcb)) / TCP_SLOW_INTERVAL) + 8006298: 69fb ldr r3, [r7, #28] + 800629a: 2290 movs r2, #144 ; 0x90 + 800629c: 589b ldr r3, [r3, r2] + 800629e: 4a49 ldr r2, [pc, #292] ; (80063c4 ) + 80062a0: 189a adds r2, r3, r2 + 80062a2: 23fa movs r3, #250 ; 0xfa + 80062a4: 0059 lsls r1, r3, #1 + 80062a6: 0010 movs r0, r2 + 80062a8: f7f9 ff40 bl 800012c <__udivsi3> + 80062ac: 0003 movs r3, r0 + if((u32_t)(tcp_ticks - pcb->tmr) > + 80062ae: 429c cmp r4, r3 + 80062b0: d90c bls.n 80062cc + { + LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: KEEPALIVE timeout. Aborting connection to %"U16_F".%"U16_F".%"U16_F".%"U16_F".\n", + ip4_addr1_16(&pcb->remote_ip), ip4_addr2_16(&pcb->remote_ip), + ip4_addr3_16(&pcb->remote_ip), ip4_addr4_16(&pcb->remote_ip))); + + ++pcb_remove; + 80062b2: 2217 movs r2, #23 + 80062b4: 18bb adds r3, r7, r2 + 80062b6: 18ba adds r2, r7, r2 + 80062b8: 7812 ldrb r2, [r2, #0] + 80062ba: 3201 adds r2, #1 + 80062bc: 701a strb r2, [r3, #0] + ++pcb_reset; + 80062be: 2216 movs r2, #22 + 80062c0: 18bb adds r3, r7, r2 + 80062c2: 18ba adds r2, r7, r2 + 80062c4: 7812 ldrb r2, [r2, #0] + 80062c6: 3201 adds r2, #1 + 80062c8: 701a strb r2, [r3, #0] + 80062ca: e022 b.n 8006312 + } + else if((u32_t)(tcp_ticks - pcb->tmr) > + 80062cc: 4b38 ldr r3, [pc, #224] ; (80063b0 ) + 80062ce: 681a ldr r2, [r3, #0] + 80062d0: 69fb ldr r3, [r7, #28] + 80062d2: 6a5b ldr r3, [r3, #36] ; 0x24 + 80062d4: 1ad4 subs r4, r2, r3 + (pcb->keep_idle + pcb->keep_cnt_sent * TCP_KEEP_INTVL(pcb)) + 80062d6: 69fb ldr r3, [r7, #28] + 80062d8: 2290 movs r2, #144 ; 0x90 + 80062da: 589a ldr r2, [r3, r2] + 80062dc: 69fb ldr r3, [r7, #28] + 80062de: 2196 movs r1, #150 ; 0x96 + 80062e0: 5c5b ldrb r3, [r3, r1] + 80062e2: 0019 movs r1, r3 + 80062e4: 4b38 ldr r3, [pc, #224] ; (80063c8 ) + 80062e6: 434b muls r3, r1 + 80062e8: 18d2 adds r2, r2, r3 + / TCP_SLOW_INTERVAL) + 80062ea: 23fa movs r3, #250 ; 0xfa + 80062ec: 0059 lsls r1, r3, #1 + 80062ee: 0010 movs r0, r2 + 80062f0: f7f9 ff1c bl 800012c <__udivsi3> + 80062f4: 0003 movs r3, r0 + else if((u32_t)(tcp_ticks - pcb->tmr) > + 80062f6: 429c cmp r4, r3 + 80062f8: d90b bls.n 8006312 + { + tcp_keepalive(pcb); + 80062fa: 69fb ldr r3, [r7, #28] + 80062fc: 0018 movs r0, r3 + 80062fe: f004 f86d bl 800a3dc + pcb->keep_cnt_sent++; + 8006302: 69fb ldr r3, [r7, #28] + 8006304: 2296 movs r2, #150 ; 0x96 + 8006306: 5c9b ldrb r3, [r3, r2] + 8006308: 3301 adds r3, #1 + 800630a: b2d9 uxtb r1, r3 + 800630c: 69fb ldr r3, [r7, #28] + 800630e: 2296 movs r2, #150 ; 0x96 + 8006310: 5499 strb r1, [r3, r2] + + /* If this PCB has queued out of sequence data, but has been + inactive for too long, will drop the data (it will eventually + be retransmitted). */ +#if TCP_QUEUE_OOSEQ + if (pcb->ooseq != NULL && + 8006312: 69fb ldr r3, [r7, #28] + 8006314: 6f5b ldr r3, [r3, #116] ; 0x74 + 8006316: 2b00 cmp r3, #0 + 8006318: d016 beq.n 8006348 + (u32_t)tcp_ticks - pcb->tmr >= pcb->rto * TCP_OOSEQ_TIMEOUT) { + 800631a: 4b25 ldr r3, [pc, #148] ; (80063b0 ) + 800631c: 681a ldr r2, [r3, #0] + 800631e: 69fb ldr r3, [r7, #28] + 8006320: 6a5b ldr r3, [r3, #36] ; 0x24 + 8006322: 1ad2 subs r2, r2, r3 + 8006324: 69fb ldr r3, [r7, #28] + 8006326: 2144 movs r1, #68 ; 0x44 + 8006328: 5e5b ldrsh r3, [r3, r1] + 800632a: 0019 movs r1, r3 + 800632c: 000b movs r3, r1 + 800632e: 005b lsls r3, r3, #1 + 8006330: 185b adds r3, r3, r1 + 8006332: 005b lsls r3, r3, #1 + if (pcb->ooseq != NULL && + 8006334: 429a cmp r2, r3 + 8006336: d307 bcc.n 8006348 + tcp_segs_free(pcb->ooseq); + 8006338: 69fb ldr r3, [r7, #28] + 800633a: 6f5b ldr r3, [r3, #116] ; 0x74 + 800633c: 0018 movs r0, r3 + 800633e: f000 f9d9 bl 80066f4 + pcb->ooseq = NULL; + 8006342: 69fb ldr r3, [r7, #28] + 8006344: 2200 movs r2, #0 + 8006346: 675a str r2, [r3, #116] ; 0x74 + LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_slowtmr: dropping OOSEQ queued data\n")); + } +#endif /* TCP_QUEUE_OOSEQ */ + + /* Check if this PCB has stayed too long in SYN-RCVD */ + if (pcb->state == SYN_RCVD) { + 8006348: 69fb ldr r3, [r7, #28] + 800634a: 7e1b ldrb r3, [r3, #24] + 800634c: 2b03 cmp r3, #3 + 800634e: d10c bne.n 800636a + if ((u32_t)(tcp_ticks - pcb->tmr) > + 8006350: 4b17 ldr r3, [pc, #92] ; (80063b0 ) + 8006352: 681a ldr r2, [r3, #0] + 8006354: 69fb ldr r3, [r7, #28] + 8006356: 6a5b ldr r3, [r3, #36] ; 0x24 + 8006358: 1ad3 subs r3, r2, r3 + 800635a: 2b28 cmp r3, #40 ; 0x28 + 800635c: d905 bls.n 800636a + TCP_SYN_RCVD_TIMEOUT / TCP_SLOW_INTERVAL) { + ++pcb_remove; + 800635e: 2217 movs r2, #23 + 8006360: 18bb adds r3, r7, r2 + 8006362: 18ba adds r2, r7, r2 + 8006364: 7812 ldrb r2, [r2, #0] + 8006366: 3201 adds r2, #1 + 8006368: 701a strb r2, [r3, #0] + LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: removing pcb stuck in SYN-RCVD\n")); + } + } + + /* Check if this PCB has stayed too long in LAST-ACK */ + if (pcb->state == LAST_ACK) { + 800636a: 69fb ldr r3, [r7, #28] + 800636c: 7e1b ldrb r3, [r3, #24] + 800636e: 2b09 cmp r3, #9 + 8006370: d10c bne.n 800638c + if ((u32_t)(tcp_ticks - pcb->tmr) > 2 * TCP_MSL / TCP_SLOW_INTERVAL) { + 8006372: 4b0f ldr r3, [pc, #60] ; (80063b0 ) + 8006374: 681a ldr r2, [r3, #0] + 8006376: 69fb ldr r3, [r7, #28] + 8006378: 6a5b ldr r3, [r3, #36] ; 0x24 + 800637a: 1ad3 subs r3, r2, r3 + 800637c: 2bf0 cmp r3, #240 ; 0xf0 + 800637e: d905 bls.n 800638c + ++pcb_remove; + 8006380: 2217 movs r2, #23 + 8006382: 18bb adds r3, r7, r2 + 8006384: 18ba adds r2, r7, r2 + 8006386: 7812 ldrb r2, [r2, #0] + 8006388: 3201 adds r2, #1 + 800638a: 701a strb r2, [r3, #0] + LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: removing pcb stuck in LAST-ACK\n")); + } + } + + /* If the PCB should be removed, do it. */ + if (pcb_remove) { + 800638c: 2317 movs r3, #23 + 800638e: 18fb adds r3, r7, r3 + 8006390: 781b ldrb r3, [r3, #0] + 8006392: 2b00 cmp r3, #0 + 8006394: d056 beq.n 8006444 + struct tcp_pcb *pcb2; + tcp_err_fn err_fn; + void *err_arg; + tcp_pcb_purge(pcb); + 8006396: 69fb ldr r3, [r7, #28] + 8006398: 0018 movs r0, r3 + 800639a: f000 fb45 bl 8006a28 + /* Remove PCB from tcp_active_pcbs list. */ + if (prev != NULL) { + 800639e: 69bb ldr r3, [r7, #24] + 80063a0: 2b00 cmp r3, #0 + 80063a2: d013 beq.n 80063cc + LWIP_ASSERT("tcp_slowtmr: middle tcp != tcp_active_pcbs", pcb != tcp_active_pcbs); + prev->next = pcb->next; + 80063a4: 69fb ldr r3, [r7, #28] + 80063a6: 68da ldr r2, [r3, #12] + 80063a8: 69bb ldr r3, [r7, #24] + 80063aa: 60da str r2, [r3, #12] + 80063ac: e012 b.n 80063d4 + 80063ae: 46c0 nop ; (mov r8, r8) + 80063b0: 20003278 .word 0x20003278 + 80063b4: 20002279 .word 0x20002279 + 80063b8: 20003274 .word 0x20003274 + 80063bc: 0800fd70 .word 0x0800fd70 + 80063c0: 0800fd60 .word 0x0800fd60 + 80063c4: 000a4cb8 .word 0x000a4cb8 + 80063c8: 000124f8 .word 0x000124f8 + } else { + /* This PCB was the first. */ + LWIP_ASSERT("tcp_slowtmr: first pcb == tcp_active_pcbs", tcp_active_pcbs == pcb); + tcp_active_pcbs = pcb->next; + 80063cc: 69fb ldr r3, [r7, #28] + 80063ce: 68da ldr r2, [r3, #12] + 80063d0: 4b5e ldr r3, [pc, #376] ; (800654c ) + 80063d2: 601a str r2, [r3, #0] + } + + if (pcb_reset) { + 80063d4: 2316 movs r3, #22 + 80063d6: 18fb adds r3, r7, r3 + 80063d8: 781b ldrb r3, [r3, #0] + 80063da: 2b00 cmp r3, #0 + 80063dc: d010 beq.n 8006400 + tcp_rst(pcb->snd_nxt, pcb->rcv_nxt, &pcb->local_ip, &pcb->remote_ip, + 80063de: 69fb ldr r3, [r7, #28] + 80063e0: 6d18 ldr r0, [r3, #80] ; 0x50 + 80063e2: 69fb ldr r3, [r7, #28] + 80063e4: 6a99 ldr r1, [r3, #40] ; 0x28 + 80063e6: 69fc ldr r4, [r7, #28] + 80063e8: 69fb ldr r3, [r7, #28] + 80063ea: 1d1d adds r5, r3, #4 + 80063ec: 69fb ldr r3, [r7, #28] + 80063ee: 8b5b ldrh r3, [r3, #26] + 80063f0: 69fa ldr r2, [r7, #28] + 80063f2: 8b92 ldrh r2, [r2, #28] + 80063f4: 9201 str r2, [sp, #4] + 80063f6: 9300 str r3, [sp, #0] + 80063f8: 002b movs r3, r5 + 80063fa: 0022 movs r2, r4 + 80063fc: f003 fde6 bl 8009fcc + pcb->local_port, pcb->remote_port); + } + + err_fn = pcb->errf; + 8006400: 69fb ldr r3, [r7, #28] + 8006402: 228c movs r2, #140 ; 0x8c + 8006404: 589b ldr r3, [r3, r2] + 8006406: 60bb str r3, [r7, #8] + err_arg = pcb->callback_arg; + 8006408: 69fb ldr r3, [r7, #28] + 800640a: 691b ldr r3, [r3, #16] + 800640c: 607b str r3, [r7, #4] + pcb2 = pcb; + 800640e: 69fb ldr r3, [r7, #28] + 8006410: 603b str r3, [r7, #0] + pcb = pcb->next; + 8006412: 69fb ldr r3, [r7, #28] + 8006414: 68db ldr r3, [r3, #12] + 8006416: 61fb str r3, [r7, #28] + memp_free(MEMP_TCP_PCB, pcb2); + 8006418: 683b ldr r3, [r7, #0] + 800641a: 0019 movs r1, r3 + 800641c: 2002 movs r0, #2 + 800641e: f7fe fd7f bl 8004f20 + + tcp_active_pcbs_changed = 0; + 8006422: 4b4b ldr r3, [pc, #300] ; (8006550 ) + 8006424: 2200 movs r2, #0 + 8006426: 701a strb r2, [r3, #0] + TCP_EVENT_ERR(err_fn, err_arg, ERR_ABRT); + 8006428: 68bb ldr r3, [r7, #8] + 800642a: 2b00 cmp r3, #0 + 800642c: d005 beq.n 800643a + 800642e: 230a movs r3, #10 + 8006430: 4259 negs r1, r3 + 8006432: 687a ldr r2, [r7, #4] + 8006434: 68bb ldr r3, [r7, #8] + 8006436: 0010 movs r0, r2 + 8006438: 4798 blx r3 + if (tcp_active_pcbs_changed) { + 800643a: 4b45 ldr r3, [pc, #276] ; (8006550 ) + 800643c: 781b ldrb r3, [r3, #0] + 800643e: 2b00 cmp r3, #0 + 8006440: d03d beq.n 80064be + goto tcp_slowtmr_start; + 8006442: e62f b.n 80060a4 + } + } else { + /* get the 'next' element now and work with 'prev' below (in case of abort) */ + prev = pcb; + 8006444: 69fb ldr r3, [r7, #28] + 8006446: 61bb str r3, [r7, #24] + pcb = pcb->next; + 8006448: 69fb ldr r3, [r7, #28] + 800644a: 68db ldr r3, [r3, #12] + 800644c: 61fb str r3, [r7, #28] + + /* We check if we should poll the connection. */ + ++prev->polltmr; + 800644e: 69bb ldr r3, [r7, #24] + 8006450: 7fdb ldrb r3, [r3, #31] + 8006452: 3301 adds r3, #1 + 8006454: b2da uxtb r2, r3 + 8006456: 69bb ldr r3, [r7, #24] + 8006458: 77da strb r2, [r3, #31] + if (prev->polltmr >= prev->pollinterval) { + 800645a: 69bb ldr r3, [r7, #24] + 800645c: 7fda ldrb r2, [r3, #31] + 800645e: 69bb ldr r3, [r7, #24] + 8006460: 2120 movs r1, #32 + 8006462: 5c5b ldrb r3, [r3, r1] + 8006464: 429a cmp r2, r3 + 8006466: d32a bcc.n 80064be + prev->polltmr = 0; + 8006468: 69bb ldr r3, [r7, #24] + 800646a: 2200 movs r2, #0 + 800646c: 77da strb r2, [r3, #31] + LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: polling application\n")); + tcp_active_pcbs_changed = 0; + 800646e: 4b38 ldr r3, [pc, #224] ; (8006550 ) + 8006470: 2200 movs r2, #0 + 8006472: 701a strb r2, [r3, #0] + TCP_EVENT_POLL(prev, err); + 8006474: 69bb ldr r3, [r7, #24] + 8006476: 2288 movs r2, #136 ; 0x88 + 8006478: 589b ldr r3, [r3, r2] + 800647a: 2b00 cmp r3, #0 + 800647c: d00c beq.n 8006498 + 800647e: 69bb ldr r3, [r7, #24] + 8006480: 2288 movs r2, #136 ; 0x88 + 8006482: 589a ldr r2, [r3, r2] + 8006484: 69bb ldr r3, [r7, #24] + 8006486: 691b ldr r3, [r3, #16] + 8006488: 2115 movs r1, #21 + 800648a: 187c adds r4, r7, r1 + 800648c: 69b9 ldr r1, [r7, #24] + 800648e: 0018 movs r0, r3 + 8006490: 4790 blx r2 + 8006492: 0003 movs r3, r0 + 8006494: 7023 strb r3, [r4, #0] + 8006496: e003 b.n 80064a0 + 8006498: 2315 movs r3, #21 + 800649a: 18fb adds r3, r7, r3 + 800649c: 2200 movs r2, #0 + 800649e: 701a strb r2, [r3, #0] + if (tcp_active_pcbs_changed) { + 80064a0: 4b2b ldr r3, [pc, #172] ; (8006550 ) + 80064a2: 781b ldrb r3, [r3, #0] + 80064a4: 2b00 cmp r3, #0 + 80064a6: d000 beq.n 80064aa + goto tcp_slowtmr_start; + 80064a8: e5fc b.n 80060a4 + } + /* if err == ERR_ABRT, 'prev' is already deallocated */ + if (err == ERR_OK) { + 80064aa: 2315 movs r3, #21 + 80064ac: 18fb adds r3, r7, r3 + 80064ae: 781b ldrb r3, [r3, #0] + 80064b0: b25b sxtb r3, r3 + 80064b2: 2b00 cmp r3, #0 + 80064b4: d103 bne.n 80064be + tcp_output(prev); + 80064b6: 69bb ldr r3, [r7, #24] + 80064b8: 0018 movs r0, r3 + 80064ba: f003 faa9 bl 8009a10 + while (pcb != NULL) { + 80064be: 69fb ldr r3, [r7, #28] + 80064c0: 2b00 cmp r3, #0 + 80064c2: d000 beq.n 80064c6 + 80064c4: e5f4 b.n 80060b0 + } + } + + + /* Steps through all of the TIME-WAIT PCBs. */ + prev = NULL; + 80064c6: 2300 movs r3, #0 + 80064c8: 61bb str r3, [r7, #24] + pcb = tcp_tw_pcbs; + 80064ca: 4b22 ldr r3, [pc, #136] ; (8006554 ) + 80064cc: 681b ldr r3, [r3, #0] + 80064ce: 61fb str r3, [r7, #28] + while (pcb != NULL) { + 80064d0: e035 b.n 800653e + LWIP_ASSERT("tcp_slowtmr: TIME-WAIT pcb->state == TIME-WAIT", pcb->state == TIME_WAIT); + pcb_remove = 0; + 80064d2: 2317 movs r3, #23 + 80064d4: 18fb adds r3, r7, r3 + 80064d6: 2200 movs r2, #0 + 80064d8: 701a strb r2, [r3, #0] + + /* Check if this PCB has stayed long enough in TIME-WAIT */ + if ((u32_t)(tcp_ticks - pcb->tmr) > 2 * TCP_MSL / TCP_SLOW_INTERVAL) { + 80064da: 4b1f ldr r3, [pc, #124] ; (8006558 ) + 80064dc: 681a ldr r2, [r3, #0] + 80064de: 69fb ldr r3, [r7, #28] + 80064e0: 6a5b ldr r3, [r3, #36] ; 0x24 + 80064e2: 1ad3 subs r3, r2, r3 + 80064e4: 2bf0 cmp r3, #240 ; 0xf0 + 80064e6: d905 bls.n 80064f4 + ++pcb_remove; + 80064e8: 2217 movs r2, #23 + 80064ea: 18bb adds r3, r7, r2 + 80064ec: 18ba adds r2, r7, r2 + 80064ee: 7812 ldrb r2, [r2, #0] + 80064f0: 3201 adds r2, #1 + 80064f2: 701a strb r2, [r3, #0] + } + + + + /* If the PCB should be removed, do it. */ + if (pcb_remove) { + 80064f4: 2317 movs r3, #23 + 80064f6: 18fb adds r3, r7, r3 + 80064f8: 781b ldrb r3, [r3, #0] + 80064fa: 2b00 cmp r3, #0 + 80064fc: d01a beq.n 8006534 + struct tcp_pcb *pcb2; + tcp_pcb_purge(pcb); + 80064fe: 69fb ldr r3, [r7, #28] + 8006500: 0018 movs r0, r3 + 8006502: f000 fa91 bl 8006a28 + /* Remove PCB from tcp_tw_pcbs list. */ + if (prev != NULL) { + 8006506: 69bb ldr r3, [r7, #24] + 8006508: 2b00 cmp r3, #0 + 800650a: d004 beq.n 8006516 + LWIP_ASSERT("tcp_slowtmr: middle tcp != tcp_tw_pcbs", pcb != tcp_tw_pcbs); + prev->next = pcb->next; + 800650c: 69fb ldr r3, [r7, #28] + 800650e: 68da ldr r2, [r3, #12] + 8006510: 69bb ldr r3, [r7, #24] + 8006512: 60da str r2, [r3, #12] + 8006514: e003 b.n 800651e + } else { + /* This PCB was the first. */ + LWIP_ASSERT("tcp_slowtmr: first pcb == tcp_tw_pcbs", tcp_tw_pcbs == pcb); + tcp_tw_pcbs = pcb->next; + 8006516: 69fb ldr r3, [r7, #28] + 8006518: 68da ldr r2, [r3, #12] + 800651a: 4b0e ldr r3, [pc, #56] ; (8006554 ) + 800651c: 601a str r2, [r3, #0] + } + pcb2 = pcb; + 800651e: 69fb ldr r3, [r7, #28] + 8006520: 613b str r3, [r7, #16] + pcb = pcb->next; + 8006522: 69fb ldr r3, [r7, #28] + 8006524: 68db ldr r3, [r3, #12] + 8006526: 61fb str r3, [r7, #28] + memp_free(MEMP_TCP_PCB, pcb2); + 8006528: 693b ldr r3, [r7, #16] + 800652a: 0019 movs r1, r3 + 800652c: 2002 movs r0, #2 + 800652e: f7fe fcf7 bl 8004f20 + 8006532: e004 b.n 800653e + } else { + prev = pcb; + 8006534: 69fb ldr r3, [r7, #28] + 8006536: 61bb str r3, [r7, #24] + pcb = pcb->next; + 8006538: 69fb ldr r3, [r7, #28] + 800653a: 68db ldr r3, [r3, #12] + 800653c: 61fb str r3, [r7, #28] + while (pcb != NULL) { + 800653e: 69fb ldr r3, [r7, #28] + 8006540: 2b00 cmp r3, #0 + 8006542: d1c6 bne.n 80064d2 + } + } +} + 8006544: 46c0 nop ; (mov r8, r8) + 8006546: 46bd mov sp, r7 + 8006548: b008 add sp, #32 + 800654a: bdb0 pop {r4, r5, r7, pc} + 800654c: 20003274 .word 0x20003274 + 8006550: 20003270 .word 0x20003270 + 8006554: 20003288 .word 0x20003288 + 8006558: 20003278 .word 0x20003278 + +0800655c : + * + * Automatically called from tcp_tmr(). + */ +void +tcp_fasttmr(void) +{ + 800655c: b580 push {r7, lr} + 800655e: b082 sub sp, #8 + 8006560: af00 add r7, sp, #0 + struct tcp_pcb *pcb; + + ++tcp_timer_ctr; + 8006562: 4b25 ldr r3, [pc, #148] ; (80065f8 ) + 8006564: 781b ldrb r3, [r3, #0] + 8006566: 3301 adds r3, #1 + 8006568: b2da uxtb r2, r3 + 800656a: 4b23 ldr r3, [pc, #140] ; (80065f8 ) + 800656c: 701a strb r2, [r3, #0] + +tcp_fasttmr_start: + pcb = tcp_active_pcbs; + 800656e: 4b23 ldr r3, [pc, #140] ; (80065fc ) + 8006570: 681b ldr r3, [r3, #0] + 8006572: 607b str r3, [r7, #4] + + while(pcb != NULL) { + 8006574: e038 b.n 80065e8 + if (pcb->last_timer != tcp_timer_ctr) { + 8006576: 687b ldr r3, [r7, #4] + 8006578: 2221 movs r2, #33 ; 0x21 + 800657a: 5c9a ldrb r2, [r3, r2] + 800657c: 4b1e ldr r3, [pc, #120] ; (80065f8 ) + 800657e: 781b ldrb r3, [r3, #0] + 8006580: 429a cmp r2, r3 + 8006582: d031 beq.n 80065e8 + struct tcp_pcb *next; + pcb->last_timer = tcp_timer_ctr; + 8006584: 4b1c ldr r3, [pc, #112] ; (80065f8 ) + 8006586: 7819 ldrb r1, [r3, #0] + 8006588: 687b ldr r3, [r7, #4] + 800658a: 2221 movs r2, #33 ; 0x21 + 800658c: 5499 strb r1, [r3, r2] + /* send delayed ACKs */ + if (pcb->flags & TF_ACK_DELAY) { + 800658e: 687b ldr r3, [r7, #4] + 8006590: 7f9b ldrb r3, [r3, #30] + 8006592: 001a movs r2, r3 + 8006594: 2301 movs r3, #1 + 8006596: 4013 ands r3, r2 + 8006598: d011 beq.n 80065be + LWIP_DEBUGF(TCP_DEBUG, ("tcp_fasttmr: delayed ACK\n")); + tcp_ack_now(pcb); + 800659a: 687b ldr r3, [r7, #4] + 800659c: 7f9b ldrb r3, [r3, #30] + 800659e: 2202 movs r2, #2 + 80065a0: 4313 orrs r3, r2 + 80065a2: b2da uxtb r2, r3 + 80065a4: 687b ldr r3, [r7, #4] + 80065a6: 779a strb r2, [r3, #30] + tcp_output(pcb); + 80065a8: 687b ldr r3, [r7, #4] + 80065aa: 0018 movs r0, r3 + 80065ac: f003 fa30 bl 8009a10 + pcb->flags &= ~(TF_ACK_DELAY | TF_ACK_NOW); + 80065b0: 687b ldr r3, [r7, #4] + 80065b2: 7f9b ldrb r3, [r3, #30] + 80065b4: 2203 movs r2, #3 + 80065b6: 4393 bics r3, r2 + 80065b8: b2da uxtb r2, r3 + 80065ba: 687b ldr r3, [r7, #4] + 80065bc: 779a strb r2, [r3, #30] + } + + next = pcb->next; + 80065be: 687b ldr r3, [r7, #4] + 80065c0: 68db ldr r3, [r3, #12] + 80065c2: 603b str r3, [r7, #0] + + /* If there is data which was previously "refused" by upper layer */ + if (pcb->refused_data != NULL) { + 80065c4: 687b ldr r3, [r7, #4] + 80065c6: 6f9b ldr r3, [r3, #120] ; 0x78 + 80065c8: 2b00 cmp r3, #0 + 80065ca: d00b beq.n 80065e4 + tcp_active_pcbs_changed = 0; + 80065cc: 4b0c ldr r3, [pc, #48] ; (8006600 ) + 80065ce: 2200 movs r2, #0 + 80065d0: 701a strb r2, [r3, #0] + tcp_process_refused_data(pcb); + 80065d2: 687b ldr r3, [r7, #4] + 80065d4: 0018 movs r0, r3 + 80065d6: f000 f815 bl 8006604 + if (tcp_active_pcbs_changed) { + 80065da: 4b09 ldr r3, [pc, #36] ; (8006600 ) + 80065dc: 781b ldrb r3, [r3, #0] + 80065de: 2b00 cmp r3, #0 + 80065e0: d000 beq.n 80065e4 + /* application callback has changed the pcb list: restart the loop */ + goto tcp_fasttmr_start; + 80065e2: e7c4 b.n 800656e + } + } + pcb = next; + 80065e4: 683b ldr r3, [r7, #0] + 80065e6: 607b str r3, [r7, #4] + while(pcb != NULL) { + 80065e8: 687b ldr r3, [r7, #4] + 80065ea: 2b00 cmp r3, #0 + 80065ec: d1c3 bne.n 8006576 + } + } +} + 80065ee: 46c0 nop ; (mov r8, r8) + 80065f0: 46bd mov sp, r7 + 80065f2: b002 add sp, #8 + 80065f4: bd80 pop {r7, pc} + 80065f6: 46c0 nop ; (mov r8, r8) + 80065f8: 20002279 .word 0x20002279 + 80065fc: 20003274 .word 0x20003274 + 8006600: 20003270 .word 0x20003270 + +08006604 : + +/** Pass pcb->refused_data to the recv callback */ +err_t +tcp_process_refused_data(struct tcp_pcb *pcb) +{ + 8006604: b5b0 push {r4, r5, r7, lr} + 8006606: b084 sub sp, #16 + 8006608: af00 add r7, sp, #0 + 800660a: 6078 str r0, [r7, #4] + err_t err; + u8_t refused_flags = pcb->refused_data->flags; + 800660c: 687b ldr r3, [r7, #4] + 800660e: 6f9a ldr r2, [r3, #120] ; 0x78 + 8006610: 230e movs r3, #14 + 8006612: 18fb adds r3, r7, r3 + 8006614: 7b52 ldrb r2, [r2, #13] + 8006616: 701a strb r2, [r3, #0] + /* set pcb->refused_data to NULL in case the callback frees it and then + closes the pcb */ + struct pbuf *refused_data = pcb->refused_data; + 8006618: 687b ldr r3, [r7, #4] + 800661a: 6f9b ldr r3, [r3, #120] ; 0x78 + 800661c: 60bb str r3, [r7, #8] + pcb->refused_data = NULL; + 800661e: 687b ldr r3, [r7, #4] + 8006620: 2200 movs r2, #0 + 8006622: 679a str r2, [r3, #120] ; 0x78 + /* Notify again application with data previously received. */ + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: notify kept packet\n")); + TCP_EVENT_RECV(pcb, refused_data, ERR_OK, err); + 8006624: 687b ldr r3, [r7, #4] + 8006626: 2280 movs r2, #128 ; 0x80 + 8006628: 589b ldr r3, [r3, r2] + 800662a: 2b00 cmp r3, #0 + 800662c: d00d beq.n 800664a + 800662e: 687b ldr r3, [r7, #4] + 8006630: 2280 movs r2, #128 ; 0x80 + 8006632: 589d ldr r5, [r3, r2] + 8006634: 687b ldr r3, [r7, #4] + 8006636: 6918 ldr r0, [r3, #16] + 8006638: 230f movs r3, #15 + 800663a: 18fc adds r4, r7, r3 + 800663c: 68ba ldr r2, [r7, #8] + 800663e: 6879 ldr r1, [r7, #4] + 8006640: 2300 movs r3, #0 + 8006642: 47a8 blx r5 + 8006644: 0003 movs r3, r0 + 8006646: 7023 strb r3, [r4, #0] + 8006648: e009 b.n 800665e + 800664a: 230f movs r3, #15 + 800664c: 18fc adds r4, r7, r3 + 800664e: 68ba ldr r2, [r7, #8] + 8006650: 6879 ldr r1, [r7, #4] + 8006652: 2300 movs r3, #0 + 8006654: 2000 movs r0, #0 + 8006656: f000 f899 bl 800678c + 800665a: 0003 movs r3, r0 + 800665c: 7023 strb r3, [r4, #0] + if (err == ERR_OK) { + 800665e: 230f movs r3, #15 + 8006660: 18fb adds r3, r7, r3 + 8006662: 781b ldrb r3, [r3, #0] + 8006664: b25b sxtb r3, r3 + 8006666: 2b00 cmp r3, #0 + 8006668: d130 bne.n 80066cc + /* did refused_data include a FIN? */ + if (refused_flags & PBUF_FLAG_TCP_FIN) { + 800666a: 230e movs r3, #14 + 800666c: 18fb adds r3, r7, r3 + 800666e: 781b ldrb r3, [r3, #0] + 8006670: 2220 movs r2, #32 + 8006672: 4013 ands r3, r2 + 8006674: d036 beq.n 80066e4 + /* correct rcv_wnd as the application won't call tcp_recved() + for the FIN's seqno */ + if (pcb->rcv_wnd != TCP_WND) { + 8006676: 687b ldr r3, [r7, #4] + 8006678: 8d9b ldrh r3, [r3, #44] ; 0x2c + 800667a: 4a1d ldr r2, [pc, #116] ; (80066f0 ) + 800667c: 4293 cmp r3, r2 + 800667e: d005 beq.n 800668c + pcb->rcv_wnd++; + 8006680: 687b ldr r3, [r7, #4] + 8006682: 8d9b ldrh r3, [r3, #44] ; 0x2c + 8006684: 3301 adds r3, #1 + 8006686: b29a uxth r2, r3 + 8006688: 687b ldr r3, [r7, #4] + 800668a: 859a strh r2, [r3, #44] ; 0x2c + } + TCP_EVENT_CLOSED(pcb, err); + 800668c: 687b ldr r3, [r7, #4] + 800668e: 2280 movs r2, #128 ; 0x80 + 8006690: 589b ldr r3, [r3, r2] + 8006692: 2b00 cmp r3, #0 + 8006694: d00d beq.n 80066b2 + 8006696: 687b ldr r3, [r7, #4] + 8006698: 2280 movs r2, #128 ; 0x80 + 800669a: 589d ldr r5, [r3, r2] + 800669c: 687b ldr r3, [r7, #4] + 800669e: 6918 ldr r0, [r3, #16] + 80066a0: 230f movs r3, #15 + 80066a2: 18fc adds r4, r7, r3 + 80066a4: 6879 ldr r1, [r7, #4] + 80066a6: 2300 movs r3, #0 + 80066a8: 2200 movs r2, #0 + 80066aa: 47a8 blx r5 + 80066ac: 0003 movs r3, r0 + 80066ae: 7023 strb r3, [r4, #0] + 80066b0: e003 b.n 80066ba + 80066b2: 230f movs r3, #15 + 80066b4: 18fb adds r3, r7, r3 + 80066b6: 2200 movs r2, #0 + 80066b8: 701a strb r2, [r3, #0] + if (err == ERR_ABRT) { + 80066ba: 230f movs r3, #15 + 80066bc: 18fb adds r3, r7, r3 + 80066be: 781b ldrb r3, [r3, #0] + 80066c0: b25b sxtb r3, r3 + 80066c2: 330a adds r3, #10 + 80066c4: d10e bne.n 80066e4 + return ERR_ABRT; + 80066c6: 230a movs r3, #10 + 80066c8: 425b negs r3, r3 + 80066ca: e00c b.n 80066e6 + } + } + } else if (err == ERR_ABRT) { + 80066cc: 230f movs r3, #15 + 80066ce: 18fb adds r3, r7, r3 + 80066d0: 781b ldrb r3, [r3, #0] + 80066d2: b25b sxtb r3, r3 + 80066d4: 330a adds r3, #10 + 80066d6: d102 bne.n 80066de + /* if err == ERR_ABRT, 'pcb' is already deallocated */ + /* Drop incoming packets because pcb is "full" (only if the incoming + segment contains data). */ + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: drop incoming packets, because pcb is \"full\"\n")); + return ERR_ABRT; + 80066d8: 230a movs r3, #10 + 80066da: 425b negs r3, r3 + 80066dc: e003 b.n 80066e6 + } else { + /* data is still refused, pbuf is still valid (go on for ACK-only packets) */ + pcb->refused_data = refused_data; + 80066de: 687b ldr r3, [r7, #4] + 80066e0: 68ba ldr r2, [r7, #8] + 80066e2: 679a str r2, [r3, #120] ; 0x78 + } + return ERR_OK; + 80066e4: 2300 movs r3, #0 +} + 80066e6: 0018 movs r0, r3 + 80066e8: 46bd mov sp, r7 + 80066ea: b004 add sp, #16 + 80066ec: bdb0 pop {r4, r5, r7, pc} + 80066ee: 46c0 nop ; (mov r8, r8) + 80066f0: 000016d0 .word 0x000016d0 + +080066f4 : + * + * @param seg tcp_seg list of TCP segments to free + */ +void +tcp_segs_free(struct tcp_seg *seg) +{ + 80066f4: b580 push {r7, lr} + 80066f6: b084 sub sp, #16 + 80066f8: af00 add r7, sp, #0 + 80066fa: 6078 str r0, [r7, #4] + while (seg != NULL) { + 80066fc: e008 b.n 8006710 + struct tcp_seg *next = seg->next; + 80066fe: 687b ldr r3, [r7, #4] + 8006700: 681b ldr r3, [r3, #0] + 8006702: 60fb str r3, [r7, #12] + tcp_seg_free(seg); + 8006704: 687b ldr r3, [r7, #4] + 8006706: 0018 movs r0, r3 + 8006708: f000 f809 bl 800671e + seg = next; + 800670c: 68fb ldr r3, [r7, #12] + 800670e: 607b str r3, [r7, #4] + while (seg != NULL) { + 8006710: 687b ldr r3, [r7, #4] + 8006712: 2b00 cmp r3, #0 + 8006714: d1f3 bne.n 80066fe + } +} + 8006716: 46c0 nop ; (mov r8, r8) + 8006718: 46bd mov sp, r7 + 800671a: b004 add sp, #16 + 800671c: bd80 pop {r7, pc} + +0800671e : + * + * @param seg single tcp_seg to free + */ +void +tcp_seg_free(struct tcp_seg *seg) +{ + 800671e: b580 push {r7, lr} + 8006720: b082 sub sp, #8 + 8006722: af00 add r7, sp, #0 + 8006724: 6078 str r0, [r7, #4] + if (seg != NULL) { + 8006726: 687b ldr r3, [r7, #4] + 8006728: 2b00 cmp r3, #0 + 800672a: d00d beq.n 8006748 + if (seg->p != NULL) { + 800672c: 687b ldr r3, [r7, #4] + 800672e: 685b ldr r3, [r3, #4] + 8006730: 2b00 cmp r3, #0 + 8006732: d004 beq.n 800673e + pbuf_free(seg->p); + 8006734: 687b ldr r3, [r7, #4] + 8006736: 685b ldr r3, [r3, #4] + 8006738: 0018 movs r0, r3 + 800673a: f7fe ffb3 bl 80056a4 +#if TCP_DEBUG + seg->p = NULL; +#endif /* TCP_DEBUG */ + } + memp_free(MEMP_TCP_SEG, seg); + 800673e: 687b ldr r3, [r7, #4] + 8006740: 0019 movs r1, r3 + 8006742: 2004 movs r0, #4 + 8006744: f7fe fbec bl 8004f20 + } +} + 8006748: 46c0 nop ; (mov r8, r8) + 800674a: 46bd mov sp, r7 + 800674c: b002 add sp, #8 + 800674e: bd80 pop {r7, pc} + +08006750 : + * @param seg the old tcp_seg + * @return a copy of seg + */ +struct tcp_seg * +tcp_seg_copy(struct tcp_seg *seg) +{ + 8006750: b580 push {r7, lr} + 8006752: b084 sub sp, #16 + 8006754: af00 add r7, sp, #0 + 8006756: 6078 str r0, [r7, #4] + struct tcp_seg *cseg; + + cseg = (struct tcp_seg *)memp_malloc(MEMP_TCP_SEG); + 8006758: 2004 movs r0, #4 + 800675a: f7fe fb5b bl 8004e14 + 800675e: 0003 movs r3, r0 + 8006760: 60fb str r3, [r7, #12] + if (cseg == NULL) { + 8006762: 68fb ldr r3, [r7, #12] + 8006764: 2b00 cmp r3, #0 + 8006766: d101 bne.n 800676c + return NULL; + 8006768: 2300 movs r3, #0 + 800676a: e00b b.n 8006784 + } + SMEMCPY((u8_t *)cseg, (const u8_t *)seg, sizeof(struct tcp_seg)); + 800676c: 6879 ldr r1, [r7, #4] + 800676e: 68fb ldr r3, [r7, #12] + 8006770: 2210 movs r2, #16 + 8006772: 0018 movs r0, r3 + 8006774: f009 fa95 bl 800fca2 + pbuf_ref(cseg->p); + 8006778: 68fb ldr r3, [r7, #12] + 800677a: 685b ldr r3, [r3, #4] + 800677c: 0018 movs r0, r3 + 800677e: f7ff f81f bl 80057c0 + return cseg; + 8006782: 68fb ldr r3, [r7, #12] +} + 8006784: 0018 movs r0, r3 + 8006786: 46bd mov sp, r7 + 8006788: b004 add sp, #16 + 800678a: bd80 pop {r7, pc} + +0800678c : + * Default receive callback that is called if the user didn't register + * a recv callback for the pcb. + */ +err_t +tcp_recv_null(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err) +{ + 800678c: b580 push {r7, lr} + 800678e: b084 sub sp, #16 + 8006790: af00 add r7, sp, #0 + 8006792: 60f8 str r0, [r7, #12] + 8006794: 60b9 str r1, [r7, #8] + 8006796: 607a str r2, [r7, #4] + 8006798: 001a movs r2, r3 + 800679a: 1cfb adds r3, r7, #3 + 800679c: 701a strb r2, [r3, #0] + LWIP_UNUSED_ARG(arg); + if (p != NULL) { + 800679e: 687b ldr r3, [r7, #4] + 80067a0: 2b00 cmp r3, #0 + 80067a2: d00b beq.n 80067bc + tcp_recved(pcb, p->tot_len); + 80067a4: 687b ldr r3, [r7, #4] + 80067a6: 891a ldrh r2, [r3, #8] + 80067a8: 68bb ldr r3, [r7, #8] + 80067aa: 0011 movs r1, r2 + 80067ac: 0018 movs r0, r3 + 80067ae: f7ff fc33 bl 8006018 + pbuf_free(p); + 80067b2: 687b ldr r3, [r7, #4] + 80067b4: 0018 movs r0, r3 + 80067b6: f7fe ff75 bl 80056a4 + 80067ba: e00a b.n 80067d2 + } else if (err == ERR_OK) { + 80067bc: 1cfb adds r3, r7, #3 + 80067be: 781b ldrb r3, [r3, #0] + 80067c0: b25b sxtb r3, r3 + 80067c2: 2b00 cmp r3, #0 + 80067c4: d105 bne.n 80067d2 + return tcp_close(pcb); + 80067c6: 68bb ldr r3, [r7, #8] + 80067c8: 0018 movs r0, r3 + 80067ca: f7ff fb4d bl 8005e68 + 80067ce: 0003 movs r3, r0 + 80067d0: e000 b.n 80067d4 + } + return ERR_OK; + 80067d2: 2300 movs r3, #0 +} + 80067d4: 0018 movs r0, r3 + 80067d6: 46bd mov sp, r7 + 80067d8: b004 add sp, #16 + 80067da: bd80 pop {r7, pc} + +080067dc : + * + * @param prio minimum priority + */ +static void +tcp_kill_prio(u8_t prio) +{ + 80067dc: b580 push {r7, lr} + 80067de: b086 sub sp, #24 + 80067e0: af00 add r7, sp, #0 + 80067e2: 0002 movs r2, r0 + 80067e4: 1dfb adds r3, r7, #7 + 80067e6: 701a strb r2, [r3, #0] + struct tcp_pcb *pcb, *inactive; + u32_t inactivity; + u8_t mprio; + + + mprio = TCP_PRIO_MAX; + 80067e8: 230b movs r3, #11 + 80067ea: 18fb adds r3, r7, r3 + 80067ec: 227f movs r2, #127 ; 0x7f + 80067ee: 701a strb r2, [r3, #0] + + /* We kill the oldest active connection that has lower priority than prio. */ + inactivity = 0; + 80067f0: 2300 movs r3, #0 + 80067f2: 60fb str r3, [r7, #12] + inactive = NULL; + 80067f4: 2300 movs r3, #0 + 80067f6: 613b str r3, [r7, #16] + for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) { + 80067f8: 4b1b ldr r3, [pc, #108] ; (8006868 ) + 80067fa: 681b ldr r3, [r3, #0] + 80067fc: 617b str r3, [r7, #20] + 80067fe: e024 b.n 800684a + if (pcb->prio <= prio && + 8006800: 697b ldr r3, [r7, #20] + 8006802: 7e5b ldrb r3, [r3, #25] + 8006804: 1dfa adds r2, r7, #7 + 8006806: 7812 ldrb r2, [r2, #0] + 8006808: 429a cmp r2, r3 + 800680a: d31b bcc.n 8006844 + pcb->prio <= mprio && + 800680c: 697b ldr r3, [r7, #20] + 800680e: 7e5b ldrb r3, [r3, #25] + if (pcb->prio <= prio && + 8006810: 220b movs r2, #11 + 8006812: 18ba adds r2, r7, r2 + 8006814: 7812 ldrb r2, [r2, #0] + 8006816: 429a cmp r2, r3 + 8006818: d314 bcc.n 8006844 + (u32_t)(tcp_ticks - pcb->tmr) >= inactivity) { + 800681a: 4b14 ldr r3, [pc, #80] ; (800686c ) + 800681c: 681a ldr r2, [r3, #0] + 800681e: 697b ldr r3, [r7, #20] + 8006820: 6a5b ldr r3, [r3, #36] ; 0x24 + 8006822: 1ad3 subs r3, r2, r3 + pcb->prio <= mprio && + 8006824: 68fa ldr r2, [r7, #12] + 8006826: 429a cmp r2, r3 + 8006828: d80c bhi.n 8006844 + inactivity = tcp_ticks - pcb->tmr; + 800682a: 4b10 ldr r3, [pc, #64] ; (800686c ) + 800682c: 681a ldr r2, [r3, #0] + 800682e: 697b ldr r3, [r7, #20] + 8006830: 6a5b ldr r3, [r3, #36] ; 0x24 + 8006832: 1ad3 subs r3, r2, r3 + 8006834: 60fb str r3, [r7, #12] + inactive = pcb; + 8006836: 697b ldr r3, [r7, #20] + 8006838: 613b str r3, [r7, #16] + mprio = pcb->prio; + 800683a: 230b movs r3, #11 + 800683c: 18fb adds r3, r7, r3 + 800683e: 697a ldr r2, [r7, #20] + 8006840: 7e52 ldrb r2, [r2, #25] + 8006842: 701a strb r2, [r3, #0] + for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) { + 8006844: 697b ldr r3, [r7, #20] + 8006846: 68db ldr r3, [r3, #12] + 8006848: 617b str r3, [r7, #20] + 800684a: 697b ldr r3, [r7, #20] + 800684c: 2b00 cmp r3, #0 + 800684e: d1d7 bne.n 8006800 + } + } + if (inactive != NULL) { + 8006850: 693b ldr r3, [r7, #16] + 8006852: 2b00 cmp r3, #0 + 8006854: d003 beq.n 800685e + LWIP_DEBUGF(TCP_DEBUG, ("tcp_kill_prio: killing oldest PCB %p (%"S32_F")\n", + (void *)inactive, inactivity)); + tcp_abort(inactive); + 8006856: 693b ldr r3, [r7, #16] + 8006858: 0018 movs r0, r3 + 800685a: f7ff fb8f bl 8005f7c + } +} + 800685e: 46c0 nop ; (mov r8, r8) + 8006860: 46bd mov sp, r7 + 8006862: b006 add sp, #24 + 8006864: bd80 pop {r7, pc} + 8006866: 46c0 nop ; (mov r8, r8) + 8006868: 20003274 .word 0x20003274 + 800686c: 20003278 .word 0x20003278 + +08006870 : + * Kills the oldest connection that is in TIME_WAIT state. + * Called from tcp_alloc() if no more connections are available. + */ +static void +tcp_kill_timewait(void) +{ + 8006870: b580 push {r7, lr} + 8006872: b084 sub sp, #16 + 8006874: af00 add r7, sp, #0 + struct tcp_pcb *pcb, *inactive; + u32_t inactivity; + + inactivity = 0; + 8006876: 2300 movs r3, #0 + 8006878: 607b str r3, [r7, #4] + inactive = NULL; + 800687a: 2300 movs r3, #0 + 800687c: 60bb str r3, [r7, #8] + /* Go through the list of TIME_WAIT pcbs and get the oldest pcb. */ + for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) { + 800687e: 4b12 ldr r3, [pc, #72] ; (80068c8 ) + 8006880: 681b ldr r3, [r3, #0] + 8006882: 60fb str r3, [r7, #12] + 8006884: e012 b.n 80068ac + if ((u32_t)(tcp_ticks - pcb->tmr) >= inactivity) { + 8006886: 4b11 ldr r3, [pc, #68] ; (80068cc ) + 8006888: 681a ldr r2, [r3, #0] + 800688a: 68fb ldr r3, [r7, #12] + 800688c: 6a5b ldr r3, [r3, #36] ; 0x24 + 800688e: 1ad3 subs r3, r2, r3 + 8006890: 687a ldr r2, [r7, #4] + 8006892: 429a cmp r2, r3 + 8006894: d807 bhi.n 80068a6 + inactivity = tcp_ticks - pcb->tmr; + 8006896: 4b0d ldr r3, [pc, #52] ; (80068cc ) + 8006898: 681a ldr r2, [r3, #0] + 800689a: 68fb ldr r3, [r7, #12] + 800689c: 6a5b ldr r3, [r3, #36] ; 0x24 + 800689e: 1ad3 subs r3, r2, r3 + 80068a0: 607b str r3, [r7, #4] + inactive = pcb; + 80068a2: 68fb ldr r3, [r7, #12] + 80068a4: 60bb str r3, [r7, #8] + for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) { + 80068a6: 68fb ldr r3, [r7, #12] + 80068a8: 68db ldr r3, [r3, #12] + 80068aa: 60fb str r3, [r7, #12] + 80068ac: 68fb ldr r3, [r7, #12] + 80068ae: 2b00 cmp r3, #0 + 80068b0: d1e9 bne.n 8006886 + } + } + if (inactive != NULL) { + 80068b2: 68bb ldr r3, [r7, #8] + 80068b4: 2b00 cmp r3, #0 + 80068b6: d003 beq.n 80068c0 + LWIP_DEBUGF(TCP_DEBUG, ("tcp_kill_timewait: killing oldest TIME-WAIT PCB %p (%"S32_F")\n", + (void *)inactive, inactivity)); + tcp_abort(inactive); + 80068b8: 68bb ldr r3, [r7, #8] + 80068ba: 0018 movs r0, r3 + 80068bc: f7ff fb5e bl 8005f7c + } +} + 80068c0: 46c0 nop ; (mov r8, r8) + 80068c2: 46bd mov sp, r7 + 80068c4: b004 add sp, #16 + 80068c6: bd80 pop {r7, pc} + 80068c8: 20003288 .word 0x20003288 + 80068cc: 20003278 .word 0x20003278 + +080068d0 : + * @param prio priority for the new pcb + * @return a new tcp_pcb that initially is in state CLOSED + */ +struct tcp_pcb * +tcp_alloc(u8_t prio) +{ + 80068d0: b580 push {r7, lr} + 80068d2: b084 sub sp, #16 + 80068d4: af00 add r7, sp, #0 + 80068d6: 0002 movs r2, r0 + 80068d8: 1dfb adds r3, r7, #7 + 80068da: 701a strb r2, [r3, #0] + struct tcp_pcb *pcb; + u32_t iss; + + pcb = (struct tcp_pcb *)memp_malloc(MEMP_TCP_PCB); + 80068dc: 2002 movs r0, #2 + 80068de: f7fe fa99 bl 8004e14 + 80068e2: 0003 movs r3, r0 + 80068e4: 60fb str r3, [r7, #12] + if (pcb == NULL) { + 80068e6: 68fb ldr r3, [r7, #12] + 80068e8: 2b00 cmp r3, #0 + 80068ea: d129 bne.n 8006940 + /* Try killing oldest connection in TIME-WAIT. */ + LWIP_DEBUGF(TCP_DEBUG, ("tcp_alloc: killing off oldest TIME-WAIT connection\n")); + tcp_kill_timewait(); + 80068ec: f7ff ffc0 bl 8006870 + /* Try to allocate a tcp_pcb again. */ + pcb = (struct tcp_pcb *)memp_malloc(MEMP_TCP_PCB); + 80068f0: 2002 movs r0, #2 + 80068f2: f7fe fa8f bl 8004e14 + 80068f6: 0003 movs r3, r0 + 80068f8: 60fb str r3, [r7, #12] + if (pcb == NULL) { + 80068fa: 68fb ldr r3, [r7, #12] + 80068fc: 2b00 cmp r3, #0 + 80068fe: d114 bne.n 800692a + /* Try killing active connections with lower priority than the new one. */ + LWIP_DEBUGF(TCP_DEBUG, ("tcp_alloc: killing connection with prio lower than %d\n", prio)); + tcp_kill_prio(prio); + 8006900: 1dfb adds r3, r7, #7 + 8006902: 781b ldrb r3, [r3, #0] + 8006904: 0018 movs r0, r3 + 8006906: f7ff ff69 bl 80067dc + /* Try to allocate a tcp_pcb again. */ + pcb = (struct tcp_pcb *)memp_malloc(MEMP_TCP_PCB); + 800690a: 2002 movs r0, #2 + 800690c: f7fe fa82 bl 8004e14 + 8006910: 0003 movs r3, r0 + 8006912: 60fb str r3, [r7, #12] + if (pcb != NULL) { + 8006914: 68fb ldr r3, [r7, #12] + 8006916: 2b00 cmp r3, #0 + 8006918: d007 beq.n 800692a + /* adjust err stats: memp_malloc failed twice before */ + MEMP_STATS_DEC(err, MEMP_TCP_PCB); + 800691a: 4b3c ldr r3, [pc, #240] ; (8006a0c ) + 800691c: 22cc movs r2, #204 ; 0xcc + 800691e: 5a9b ldrh r3, [r3, r2] + 8006920: 3b01 subs r3, #1 + 8006922: b299 uxth r1, r3 + 8006924: 4b39 ldr r3, [pc, #228] ; (8006a0c ) + 8006926: 22cc movs r2, #204 ; 0xcc + 8006928: 5299 strh r1, [r3, r2] + } + } + if (pcb != NULL) { + 800692a: 68fb ldr r3, [r7, #12] + 800692c: 2b00 cmp r3, #0 + 800692e: d007 beq.n 8006940 + /* adjust err stats: timewait PCB was freed above */ + MEMP_STATS_DEC(err, MEMP_TCP_PCB); + 8006930: 4b36 ldr r3, [pc, #216] ; (8006a0c ) + 8006932: 22cc movs r2, #204 ; 0xcc + 8006934: 5a9b ldrh r3, [r3, r2] + 8006936: 3b01 subs r3, #1 + 8006938: b299 uxth r1, r3 + 800693a: 4b34 ldr r3, [pc, #208] ; (8006a0c ) + 800693c: 22cc movs r2, #204 ; 0xcc + 800693e: 5299 strh r1, [r3, r2] + } + } + if (pcb != NULL) { + 8006940: 68fb ldr r3, [r7, #12] + 8006942: 2b00 cmp r3, #0 + 8006944: d05d beq.n 8006a02 + memset(pcb, 0, sizeof(struct tcp_pcb)); + 8006946: 68fb ldr r3, [r7, #12] + 8006948: 2298 movs r2, #152 ; 0x98 + 800694a: 2100 movs r1, #0 + 800694c: 0018 movs r0, r3 + 800694e: f009 f9b1 bl 800fcb4 + pcb->prio = prio; + 8006952: 68fb ldr r3, [r7, #12] + 8006954: 1dfa adds r2, r7, #7 + 8006956: 7812 ldrb r2, [r2, #0] + 8006958: 765a strb r2, [r3, #25] + pcb->snd_buf = TCP_SND_BUF; + 800695a: 68fb ldr r3, [r7, #12] + 800695c: 2266 movs r2, #102 ; 0x66 + 800695e: 492c ldr r1, [pc, #176] ; (8006a10 ) + 8006960: 5299 strh r1, [r3, r2] + pcb->snd_queuelen = 0; + 8006962: 68fb ldr r3, [r7, #12] + 8006964: 2268 movs r2, #104 ; 0x68 + 8006966: 2100 movs r1, #0 + 8006968: 5299 strh r1, [r3, r2] + pcb->rcv_wnd = TCP_WND; + 800696a: 68fb ldr r3, [r7, #12] + 800696c: 4a29 ldr r2, [pc, #164] ; (8006a14 ) + 800696e: 859a strh r2, [r3, #44] ; 0x2c + pcb->rcv_ann_wnd = TCP_WND; + 8006970: 68fb ldr r3, [r7, #12] + 8006972: 4a28 ldr r2, [pc, #160] ; (8006a14 ) + 8006974: 85da strh r2, [r3, #46] ; 0x2e + pcb->tos = 0; + 8006976: 68fb ldr r3, [r7, #12] + 8006978: 2200 movs r2, #0 + 800697a: 725a strb r2, [r3, #9] + pcb->ttl = TCP_TTL; + 800697c: 68fb ldr r3, [r7, #12] + 800697e: 22ff movs r2, #255 ; 0xff + 8006980: 729a strb r2, [r3, #10] + /* As initial send MSS, we use TCP_MSS but limit it to 536. + The send MSS is updated when an MSS option is received. */ + pcb->mss = (TCP_MSS > 536) ? 536 : TCP_MSS; + 8006982: 68fb ldr r3, [r7, #12] + 8006984: 2286 movs r2, #134 ; 0x86 + 8006986: 0092 lsls r2, r2, #2 + 8006988: 86da strh r2, [r3, #54] ; 0x36 + pcb->rto = 3000 / TCP_SLOW_INTERVAL; + 800698a: 68fb ldr r3, [r7, #12] + 800698c: 2244 movs r2, #68 ; 0x44 + 800698e: 2106 movs r1, #6 + 8006990: 5299 strh r1, [r3, r2] + pcb->sa = 0; + 8006992: 68fb ldr r3, [r7, #12] + 8006994: 2240 movs r2, #64 ; 0x40 + 8006996: 2100 movs r1, #0 + 8006998: 5299 strh r1, [r3, r2] + pcb->sv = 3000 / TCP_SLOW_INTERVAL; + 800699a: 68fb ldr r3, [r7, #12] + 800699c: 2242 movs r2, #66 ; 0x42 + 800699e: 2106 movs r1, #6 + 80069a0: 5299 strh r1, [r3, r2] + pcb->rtime = -1; + 80069a2: 68fb ldr r3, [r7, #12] + 80069a4: 2201 movs r2, #1 + 80069a6: 4252 negs r2, r2 + 80069a8: 869a strh r2, [r3, #52] ; 0x34 + pcb->cwnd = 1; + 80069aa: 68fb ldr r3, [r7, #12] + 80069ac: 224c movs r2, #76 ; 0x4c + 80069ae: 2101 movs r1, #1 + 80069b0: 5299 strh r1, [r3, r2] + iss = tcp_next_iss(); + 80069b2: f000 f8cf bl 8006b54 + 80069b6: 0003 movs r3, r0 + 80069b8: 60bb str r3, [r7, #8] + pcb->snd_wl2 = iss; + 80069ba: 68fb ldr r3, [r7, #12] + 80069bc: 68ba ldr r2, [r7, #8] + 80069be: 659a str r2, [r3, #88] ; 0x58 + pcb->snd_nxt = iss; + 80069c0: 68fb ldr r3, [r7, #12] + 80069c2: 68ba ldr r2, [r7, #8] + 80069c4: 651a str r2, [r3, #80] ; 0x50 + pcb->lastack = iss; + 80069c6: 68fb ldr r3, [r7, #12] + 80069c8: 68ba ldr r2, [r7, #8] + 80069ca: 649a str r2, [r3, #72] ; 0x48 + pcb->snd_lbb = iss; + 80069cc: 68fb ldr r3, [r7, #12] + 80069ce: 68ba ldr r2, [r7, #8] + 80069d0: 65da str r2, [r3, #92] ; 0x5c + pcb->tmr = tcp_ticks; + 80069d2: 4b11 ldr r3, [pc, #68] ; (8006a18 ) + 80069d4: 681a ldr r2, [r3, #0] + 80069d6: 68fb ldr r3, [r7, #12] + 80069d8: 625a str r2, [r3, #36] ; 0x24 + pcb->last_timer = tcp_timer_ctr; + 80069da: 4b10 ldr r3, [pc, #64] ; (8006a1c ) + 80069dc: 7819 ldrb r1, [r3, #0] + 80069de: 68fb ldr r3, [r7, #12] + 80069e0: 2221 movs r2, #33 ; 0x21 + 80069e2: 5499 strb r1, [r3, r2] + + pcb->polltmr = 0; + 80069e4: 68fb ldr r3, [r7, #12] + 80069e6: 2200 movs r2, #0 + 80069e8: 77da strb r2, [r3, #31] + +#if LWIP_CALLBACK_API + pcb->recv = tcp_recv_null; + 80069ea: 68fb ldr r3, [r7, #12] + 80069ec: 2180 movs r1, #128 ; 0x80 + 80069ee: 4a0c ldr r2, [pc, #48] ; (8006a20 ) + 80069f0: 505a str r2, [r3, r1] +#endif /* LWIP_CALLBACK_API */ + + /* Init KEEPALIVE timer */ + pcb->keep_idle = TCP_KEEPIDLE_DEFAULT; + 80069f2: 68fb ldr r3, [r7, #12] + 80069f4: 2290 movs r2, #144 ; 0x90 + 80069f6: 490b ldr r1, [pc, #44] ; (8006a24 ) + 80069f8: 5099 str r1, [r3, r2] +#if LWIP_TCP_KEEPALIVE + pcb->keep_intvl = TCP_KEEPINTVL_DEFAULT; + pcb->keep_cnt = TCP_KEEPCNT_DEFAULT; +#endif /* LWIP_TCP_KEEPALIVE */ + + pcb->keep_cnt_sent = 0; + 80069fa: 68fb ldr r3, [r7, #12] + 80069fc: 2296 movs r2, #150 ; 0x96 + 80069fe: 2100 movs r1, #0 + 8006a00: 5499 strb r1, [r3, r2] + } + return pcb; + 8006a02: 68fb ldr r3, [r7, #12] +} + 8006a04: 0018 movs r0, r3 + 8006a06: 46bd mov sp, r7 + 8006a08: b004 add sp, #16 + 8006a0a: bd80 pop {r7, pc} + 8006a0c: 20003158 .word 0x20003158 + 8006a10: 00000b68 .word 0x00000b68 + 8006a14: 000016d0 .word 0x000016d0 + 8006a18: 20003278 .word 0x20003278 + 8006a1c: 20002279 .word 0x20002279 + 8006a20: 0800678d .word 0x0800678d + 8006a24: 006ddd00 .word 0x006ddd00 + +08006a28 : + * + * @param pcb tcp_pcb to purge. The pcb itself is not deallocated! + */ +void +tcp_pcb_purge(struct tcp_pcb *pcb) +{ + 8006a28: b580 push {r7, lr} + 8006a2a: b082 sub sp, #8 + 8006a2c: af00 add r7, sp, #0 + 8006a2e: 6078 str r0, [r7, #4] + if (pcb->state != CLOSED && + 8006a30: 687b ldr r3, [r7, #4] + 8006a32: 7e1b ldrb r3, [r3, #24] + 8006a34: 2b00 cmp r3, #0 + 8006a36: d034 beq.n 8006aa2 + pcb->state != TIME_WAIT && + 8006a38: 687b ldr r3, [r7, #4] + 8006a3a: 7e1b ldrb r3, [r3, #24] + if (pcb->state != CLOSED && + 8006a3c: 2b0a cmp r3, #10 + 8006a3e: d030 beq.n 8006aa2 + pcb->state != LISTEN) { + 8006a40: 687b ldr r3, [r7, #4] + 8006a42: 7e1b ldrb r3, [r3, #24] + pcb->state != TIME_WAIT && + 8006a44: 2b01 cmp r3, #1 + 8006a46: d02c beq.n 8006aa2 + } + } +#endif /* TCP_LISTEN_BACKLOG */ + + + if (pcb->refused_data != NULL) { + 8006a48: 687b ldr r3, [r7, #4] + 8006a4a: 6f9b ldr r3, [r3, #120] ; 0x78 + 8006a4c: 2b00 cmp r3, #0 + 8006a4e: d007 beq.n 8006a60 + LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge: data left on ->refused_data\n")); + pbuf_free(pcb->refused_data); + 8006a50: 687b ldr r3, [r7, #4] + 8006a52: 6f9b ldr r3, [r3, #120] ; 0x78 + 8006a54: 0018 movs r0, r3 + 8006a56: f7fe fe25 bl 80056a4 + pcb->refused_data = NULL; + 8006a5a: 687b ldr r3, [r7, #4] + 8006a5c: 2200 movs r2, #0 + 8006a5e: 679a str r2, [r3, #120] ; 0x78 + } +#if TCP_QUEUE_OOSEQ + if (pcb->ooseq != NULL) { + LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge: data left on ->ooseq\n")); + } + tcp_segs_free(pcb->ooseq); + 8006a60: 687b ldr r3, [r7, #4] + 8006a62: 6f5b ldr r3, [r3, #116] ; 0x74 + 8006a64: 0018 movs r0, r3 + 8006a66: f7ff fe45 bl 80066f4 + pcb->ooseq = NULL; + 8006a6a: 687b ldr r3, [r7, #4] + 8006a6c: 2200 movs r2, #0 + 8006a6e: 675a str r2, [r3, #116] ; 0x74 +#endif /* TCP_QUEUE_OOSEQ */ + + /* Stop the retransmission timer as it will expect data on unacked + queue if it fires */ + pcb->rtime = -1; + 8006a70: 687b ldr r3, [r7, #4] + 8006a72: 2201 movs r2, #1 + 8006a74: 4252 negs r2, r2 + 8006a76: 869a strh r2, [r3, #52] ; 0x34 + + tcp_segs_free(pcb->unsent); + 8006a78: 687b ldr r3, [r7, #4] + 8006a7a: 6edb ldr r3, [r3, #108] ; 0x6c + 8006a7c: 0018 movs r0, r3 + 8006a7e: f7ff fe39 bl 80066f4 + tcp_segs_free(pcb->unacked); + 8006a82: 687b ldr r3, [r7, #4] + 8006a84: 6f1b ldr r3, [r3, #112] ; 0x70 + 8006a86: 0018 movs r0, r3 + 8006a88: f7ff fe34 bl 80066f4 + pcb->unacked = pcb->unsent = NULL; + 8006a8c: 687b ldr r3, [r7, #4] + 8006a8e: 2200 movs r2, #0 + 8006a90: 66da str r2, [r3, #108] ; 0x6c + 8006a92: 687b ldr r3, [r7, #4] + 8006a94: 6eda ldr r2, [r3, #108] ; 0x6c + 8006a96: 687b ldr r3, [r7, #4] + 8006a98: 671a str r2, [r3, #112] ; 0x70 +#if TCP_OVERSIZE + pcb->unsent_oversize = 0; + 8006a9a: 687b ldr r3, [r7, #4] + 8006a9c: 226a movs r2, #106 ; 0x6a + 8006a9e: 2100 movs r1, #0 + 8006aa0: 5299 strh r1, [r3, r2] +#endif /* TCP_OVERSIZE */ + } +} + 8006aa2: 46c0 nop ; (mov r8, r8) + 8006aa4: 46bd mov sp, r7 + 8006aa6: b002 add sp, #8 + 8006aa8: bd80 pop {r7, pc} + ... + +08006aac : + * @param pcblist PCB list to purge. + * @param pcb tcp_pcb to purge. The pcb itself is NOT deallocated! + */ +void +tcp_pcb_remove(struct tcp_pcb **pcblist, struct tcp_pcb *pcb) +{ + 8006aac: b580 push {r7, lr} + 8006aae: b082 sub sp, #8 + 8006ab0: af00 add r7, sp, #0 + 8006ab2: 6078 str r0, [r7, #4] + 8006ab4: 6039 str r1, [r7, #0] + TCP_RMV(pcblist, pcb); + 8006ab6: 687b ldr r3, [r7, #4] + 8006ab8: 681b ldr r3, [r3, #0] + 8006aba: 683a ldr r2, [r7, #0] + 8006abc: 429a cmp r2, r3 + 8006abe: d105 bne.n 8006acc + 8006ac0: 687b ldr r3, [r7, #4] + 8006ac2: 681b ldr r3, [r3, #0] + 8006ac4: 68da ldr r2, [r3, #12] + 8006ac6: 687b ldr r3, [r7, #4] + 8006ac8: 601a str r2, [r3, #0] + 8006aca: e019 b.n 8006b00 + 8006acc: 687b ldr r3, [r7, #4] + 8006ace: 681a ldr r2, [r3, #0] + 8006ad0: 4b1f ldr r3, [pc, #124] ; (8006b50 ) + 8006ad2: 601a str r2, [r3, #0] + 8006ad4: e010 b.n 8006af8 + 8006ad6: 4b1e ldr r3, [pc, #120] ; (8006b50 ) + 8006ad8: 681b ldr r3, [r3, #0] + 8006ada: 68db ldr r3, [r3, #12] + 8006adc: 683a ldr r2, [r7, #0] + 8006ade: 429a cmp r2, r3 + 8006ae0: d105 bne.n 8006aee + 8006ae2: 4b1b ldr r3, [pc, #108] ; (8006b50 ) + 8006ae4: 681b ldr r3, [r3, #0] + 8006ae6: 683a ldr r2, [r7, #0] + 8006ae8: 68d2 ldr r2, [r2, #12] + 8006aea: 60da str r2, [r3, #12] + 8006aec: e008 b.n 8006b00 + 8006aee: 4b18 ldr r3, [pc, #96] ; (8006b50 ) + 8006af0: 681b ldr r3, [r3, #0] + 8006af2: 68da ldr r2, [r3, #12] + 8006af4: 4b16 ldr r3, [pc, #88] ; (8006b50 ) + 8006af6: 601a str r2, [r3, #0] + 8006af8: 4b15 ldr r3, [pc, #84] ; (8006b50 ) + 8006afa: 681b ldr r3, [r3, #0] + 8006afc: 2b00 cmp r3, #0 + 8006afe: d1ea bne.n 8006ad6 + 8006b00: 683b ldr r3, [r7, #0] + 8006b02: 2200 movs r2, #0 + 8006b04: 60da str r2, [r3, #12] + + tcp_pcb_purge(pcb); + 8006b06: 683b ldr r3, [r7, #0] + 8006b08: 0018 movs r0, r3 + 8006b0a: f7ff ff8d bl 8006a28 + + /* if there is an outstanding delayed ACKs, send it */ + if (pcb->state != TIME_WAIT && + 8006b0e: 683b ldr r3, [r7, #0] + 8006b10: 7e1b ldrb r3, [r3, #24] + 8006b12: 2b0a cmp r3, #10 + 8006b14: d014 beq.n 8006b40 + pcb->state != LISTEN && + 8006b16: 683b ldr r3, [r7, #0] + 8006b18: 7e1b ldrb r3, [r3, #24] + if (pcb->state != TIME_WAIT && + 8006b1a: 2b01 cmp r3, #1 + 8006b1c: d010 beq.n 8006b40 + pcb->flags & TF_ACK_DELAY) { + 8006b1e: 683b ldr r3, [r7, #0] + 8006b20: 7f9b ldrb r3, [r3, #30] + 8006b22: 001a movs r2, r3 + 8006b24: 2301 movs r3, #1 + 8006b26: 4013 ands r3, r2 + pcb->state != LISTEN && + 8006b28: d00a beq.n 8006b40 + pcb->flags |= TF_ACK_NOW; + 8006b2a: 683b ldr r3, [r7, #0] + 8006b2c: 7f9b ldrb r3, [r3, #30] + 8006b2e: 2202 movs r2, #2 + 8006b30: 4313 orrs r3, r2 + 8006b32: b2da uxtb r2, r3 + 8006b34: 683b ldr r3, [r7, #0] + 8006b36: 779a strb r2, [r3, #30] + tcp_output(pcb); + 8006b38: 683b ldr r3, [r7, #0] + 8006b3a: 0018 movs r0, r3 + 8006b3c: f002 ff68 bl 8009a10 +#if TCP_QUEUE_OOSEQ + LWIP_ASSERT("ooseq segments leaking", pcb->ooseq == NULL); +#endif /* TCP_QUEUE_OOSEQ */ + } + + pcb->state = CLOSED; + 8006b40: 683b ldr r3, [r7, #0] + 8006b42: 2200 movs r2, #0 + 8006b44: 761a strb r2, [r3, #24] + + LWIP_ASSERT("tcp_pcb_remove: tcp_pcbs_sane()", tcp_pcbs_sane()); +} + 8006b46: 46c0 nop ; (mov r8, r8) + 8006b48: 46bd mov sp, r7 + 8006b4a: b002 add sp, #8 + 8006b4c: bd80 pop {r7, pc} + 8006b4e: 46c0 nop ; (mov r8, r8) + 8006b50: 20003280 .word 0x20003280 + +08006b54 : + * + * @return u32_t pseudo random sequence number + */ +u32_t +tcp_next_iss(void) +{ + 8006b54: b580 push {r7, lr} + 8006b56: af00 add r7, sp, #0 + static u32_t iss = 6510; + + iss += tcp_ticks; /* XXX */ + 8006b58: 4b05 ldr r3, [pc, #20] ; (8006b70 ) + 8006b5a: 681a ldr r2, [r3, #0] + 8006b5c: 4b05 ldr r3, [pc, #20] ; (8006b74 ) + 8006b5e: 681b ldr r3, [r3, #0] + 8006b60: 18d2 adds r2, r2, r3 + 8006b62: 4b03 ldr r3, [pc, #12] ; (8006b70 ) + 8006b64: 601a str r2, [r3, #0] + return iss; + 8006b66: 4b02 ldr r3, [pc, #8] ; (8006b70 ) + 8006b68: 681b ldr r3, [r3, #0] +} + 8006b6a: 0018 movs r0, r3 + 8006b6c: 46bd mov sp, r7 + 8006b6e: bd80 pop {r7, pc} + 8006b70: 20000010 .word 0x20000010 + 8006b74: 20003278 .word 0x20003278 + +08006b78 : + * by using ip_route to determin the netif used to send to the address and + * calculating the minimum of TCP_MSS and that netif's mtu (if set). + */ +u16_t +tcp_eff_send_mss(u16_t sendmss, ip_addr_t *addr) +{ + 8006b78: b590 push {r4, r7, lr} + 8006b7a: b085 sub sp, #20 + 8006b7c: af00 add r7, sp, #0 + 8006b7e: 0002 movs r2, r0 + 8006b80: 6039 str r1, [r7, #0] + 8006b82: 1dbb adds r3, r7, #6 + 8006b84: 801a strh r2, [r3, #0] + u16_t mss_s; + struct netif *outif; + + outif = ip_route(addr); + 8006b86: 683b ldr r3, [r7, #0] + 8006b88: 0018 movs r0, r3 + 8006b8a: f004 fe5d bl 800b848 + 8006b8e: 0003 movs r3, r0 + 8006b90: 60fb str r3, [r7, #12] + if ((outif != NULL) && (outif->mtu != 0)) { + 8006b92: 68fb ldr r3, [r7, #12] + 8006b94: 2b00 cmp r3, #0 + 8006b96: d014 beq.n 8006bc2 + 8006b98: 68fb ldr r3, [r7, #12] + 8006b9a: 8c1b ldrh r3, [r3, #32] + 8006b9c: 2b00 cmp r3, #0 + 8006b9e: d010 beq.n 8006bc2 + mss_s = outif->mtu - IP_HLEN - TCP_HLEN; + 8006ba0: 68fb ldr r3, [r7, #12] + 8006ba2: 8c1a ldrh r2, [r3, #32] + 8006ba4: 210a movs r1, #10 + 8006ba6: 187b adds r3, r7, r1 + 8006ba8: 3a28 subs r2, #40 ; 0x28 + 8006baa: 801a strh r2, [r3, #0] + /* RFC 1122, chap 4.2.2.6: + * Eff.snd.MSS = min(SendMSS+20, MMS_S) - TCPhdrsize - IPoptionsize + * We correct for TCP options in tcp_write(), and don't support IP options. + */ + sendmss = LWIP_MIN(sendmss, mss_s); + 8006bac: 1dba adds r2, r7, #6 + 8006bae: 187b adds r3, r7, r1 + 8006bb0: 1db9 adds r1, r7, #6 + 8006bb2: 880c ldrh r4, [r1, #0] + 8006bb4: 881b ldrh r3, [r3, #0] + 8006bb6: b298 uxth r0, r3 + 8006bb8: b2a1 uxth r1, r4 + 8006bba: 4288 cmp r0, r1 + 8006bbc: d900 bls.n 8006bc0 + 8006bbe: 1c23 adds r3, r4, #0 + 8006bc0: 8013 strh r3, [r2, #0] + } + return sendmss; + 8006bc2: 1dbb adds r3, r7, #6 + 8006bc4: 881b ldrh r3, [r3, #0] +} + 8006bc6: 0018 movs r0, r3 + 8006bc8: 46bd mov sp, r7 + 8006bca: b005 add sp, #20 + 8006bcc: bd90 pop {r4, r7, pc} + ... + +08006bd0 : + * @param p received TCP segment to process (p->payload pointing to the IP header) + * @param inp network interface on which this segment was received + */ +void +tcp_input(struct pbuf *p, struct netif *inp) +{ + 8006bd0: b5b0 push {r4, r5, r7, lr} + 8006bd2: b088 sub sp, #32 + 8006bd4: af02 add r7, sp, #8 + 8006bd6: 6078 str r0, [r7, #4] + 8006bd8: 6039 str r1, [r7, #0] + u8_t hdrlen; + err_t err; + + PERF_START; + + TCP_STATS_INC(tcp.recv); + 8006bda: 4bd3 ldr r3, [pc, #844] ; (8006f28 ) + 8006bdc: 2292 movs r2, #146 ; 0x92 + 8006bde: 5a9b ldrh r3, [r3, r2] + 8006be0: 3301 adds r3, #1 + 8006be2: b299 uxth r1, r3 + 8006be4: 4bd0 ldr r3, [pc, #832] ; (8006f28 ) + 8006be6: 2292 movs r2, #146 ; 0x92 + 8006be8: 5299 strh r1, [r3, r2] + snmp_inc_tcpinsegs(); + + iphdr = (struct ip_hdr *)p->payload; + 8006bea: 687b ldr r3, [r7, #4] + 8006bec: 685a ldr r2, [r3, #4] + 8006bee: 4bcf ldr r3, [pc, #828] ; (8006f2c ) + 8006bf0: 601a str r2, [r3, #0] + tcphdr = (struct tcp_hdr *)((u8_t *)p->payload + IPH_HL(iphdr) * 4); + 8006bf2: 687b ldr r3, [r7, #4] + 8006bf4: 685a ldr r2, [r3, #4] + 8006bf6: 4bcd ldr r3, [pc, #820] ; (8006f2c ) + 8006bf8: 681b ldr r3, [r3, #0] + 8006bfa: 781b ldrb r3, [r3, #0] + 8006bfc: 0019 movs r1, r3 + 8006bfe: 230f movs r3, #15 + 8006c00: 400b ands r3, r1 + 8006c02: 009b lsls r3, r3, #2 + 8006c04: 18d2 adds r2, r2, r3 + 8006c06: 4bca ldr r3, [pc, #808] ; (8006f30 ) + 8006c08: 601a str r2, [r3, #0] +#if TCP_INPUT_DEBUG + tcp_debug_print(tcphdr); +#endif + + /* remove header from payload */ + if (pbuf_header(p, -((s16_t)(IPH_HL(iphdr) * 4))) || (p->tot_len < sizeof(struct tcp_hdr))) { + 8006c0a: 4bc8 ldr r3, [pc, #800] ; (8006f2c ) + 8006c0c: 681b ldr r3, [r3, #0] + 8006c0e: 781b ldrb r3, [r3, #0] + 8006c10: b29b uxth r3, r3 + 8006c12: 220f movs r2, #15 + 8006c14: 4013 ands r3, r2 + 8006c16: b29b uxth r3, r3 + 8006c18: 009b lsls r3, r3, #2 + 8006c1a: b29b uxth r3, r3 + 8006c1c: 425b negs r3, r3 + 8006c1e: b29b uxth r3, r3 + 8006c20: b21a sxth r2, r3 + 8006c22: 687b ldr r3, [r7, #4] + 8006c24: 0011 movs r1, r2 + 8006c26: 0018 movs r0, r3 + 8006c28: f7fe fcb5 bl 8005596 + 8006c2c: 1e03 subs r3, r0, #0 + 8006c2e: d103 bne.n 8006c38 + 8006c30: 687b ldr r3, [r7, #4] + 8006c32: 891b ldrh r3, [r3, #8] + 8006c34: 2b13 cmp r3, #19 + 8006c36: d809 bhi.n 8006c4c + /* drop short packets */ + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: short packet (%"U16_F" bytes) discarded\n", p->tot_len)); + TCP_STATS_INC(tcp.lenerr); + 8006c38: 4bbb ldr r3, [pc, #748] ; (8006f28 ) + 8006c3a: 229a movs r2, #154 ; 0x9a + 8006c3c: 5a9b ldrh r3, [r3, r2] + 8006c3e: 3301 adds r3, #1 + 8006c40: b299 uxth r1, r3 + 8006c42: 4bb9 ldr r3, [pc, #740] ; (8006f28 ) + 8006c44: 229a movs r2, #154 ; 0x9a + 8006c46: 5299 strh r1, [r3, r2] + goto dropped; + 8006c48: f000 fbf4 bl 8007434 + } + + /* Don't even process incoming broadcasts/multicasts. */ + if (ip_addr_isbroadcast(¤t_iphdr_dest, inp) || + 8006c4c: 4bb9 ldr r3, [pc, #740] ; (8006f34 ) + 8006c4e: 681b ldr r3, [r3, #0] + 8006c50: 683a ldr r2, [r7, #0] + 8006c52: 0011 movs r1, r2 + 8006c54: 0018 movs r0, r3 + 8006c56: f005 fa11 bl 800c07c + 8006c5a: 1e03 subs r3, r0, #0 + 8006c5c: d105 bne.n 8006c6a + ip_addr_ismulticast(¤t_iphdr_dest)) { + 8006c5e: 4bb5 ldr r3, [pc, #724] ; (8006f34 ) + 8006c60: 681b ldr r3, [r3, #0] + 8006c62: 22f0 movs r2, #240 ; 0xf0 + 8006c64: 4013 ands r3, r2 + if (ip_addr_isbroadcast(¤t_iphdr_dest, inp) || + 8006c66: 2be0 cmp r3, #224 ; 0xe0 + 8006c68: d109 bne.n 8006c7e + TCP_STATS_INC(tcp.proterr); + 8006c6a: 4baf ldr r3, [pc, #700] ; (8006f28 ) + 8006c6c: 22a0 movs r2, #160 ; 0xa0 + 8006c6e: 5a9b ldrh r3, [r3, r2] + 8006c70: 3301 adds r3, #1 + 8006c72: b299 uxth r1, r3 + 8006c74: 4bac ldr r3, [pc, #688] ; (8006f28 ) + 8006c76: 22a0 movs r2, #160 ; 0xa0 + 8006c78: 5299 strh r1, [r3, r2] + goto dropped; + 8006c7a: f000 fbdb bl 8007434 + } + +#if CHECKSUM_CHECK_TCP + /* Verify TCP checksum. */ + if (inet_chksum_pseudo(p, ip_current_src_addr(), ip_current_dest_addr(), + 8006c7e: 687b ldr r3, [r7, #4] + 8006c80: 891b ldrh r3, [r3, #8] + 8006c82: 4aac ldr r2, [pc, #688] ; (8006f34 ) + 8006c84: 49ac ldr r1, [pc, #688] ; (8006f38 ) + 8006c86: 6878 ldr r0, [r7, #4] + 8006c88: 9300 str r3, [sp, #0] + 8006c8a: 2306 movs r3, #6 + 8006c8c: f004 fcd5 bl 800b63a + 8006c90: 1e03 subs r3, r0, #0 + 8006c92: d009 beq.n 8006ca8 + inet_chksum_pseudo(p, ip_current_src_addr(), ip_current_dest_addr(), + IP_PROTO_TCP, p->tot_len))); +#if TCP_DEBUG + tcp_debug_print(tcphdr); +#endif /* TCP_DEBUG */ + TCP_STATS_INC(tcp.chkerr); + 8006c94: 4ba4 ldr r3, [pc, #656] ; (8006f28 ) + 8006c96: 2298 movs r2, #152 ; 0x98 + 8006c98: 5a9b ldrh r3, [r3, r2] + 8006c9a: 3301 adds r3, #1 + 8006c9c: b299 uxth r1, r3 + 8006c9e: 4ba2 ldr r3, [pc, #648] ; (8006f28 ) + 8006ca0: 2298 movs r2, #152 ; 0x98 + 8006ca2: 5299 strh r1, [r3, r2] + goto dropped; + 8006ca4: f000 fbc6 bl 8007434 + } +#endif + + /* Move the payload pointer in the pbuf so that it points to the + TCP data instead of the TCP header. */ + hdrlen = TCPH_HDRLEN(tcphdr); + 8006ca8: 4ba1 ldr r3, [pc, #644] ; (8006f30 ) + 8006caa: 681b ldr r3, [r3, #0] + 8006cac: 7b1a ldrb r2, [r3, #12] + 8006cae: 7b5b ldrb r3, [r3, #13] + 8006cb0: 021b lsls r3, r3, #8 + 8006cb2: 4313 orrs r3, r2 + 8006cb4: b29b uxth r3, r3 + 8006cb6: 0018 movs r0, r3 + 8006cb8: f7fd fcc2 bl 8004640 + 8006cbc: 0003 movs r3, r0 + 8006cbe: 0b1b lsrs r3, r3, #12 + 8006cc0: b29a uxth r2, r3 + 8006cc2: 210a movs r1, #10 + 8006cc4: 187b adds r3, r7, r1 + 8006cc6: 701a strb r2, [r3, #0] + if(pbuf_header(p, -(hdrlen * 4))){ + 8006cc8: 187b adds r3, r7, r1 + 8006cca: 781b ldrb r3, [r3, #0] + 8006ccc: b29b uxth r3, r3 + 8006cce: 1c1a adds r2, r3, #0 + 8006cd0: 0392 lsls r2, r2, #14 + 8006cd2: 1ad3 subs r3, r2, r3 + 8006cd4: 009b lsls r3, r3, #2 + 8006cd6: b29b uxth r3, r3 + 8006cd8: b21a sxth r2, r3 + 8006cda: 687b ldr r3, [r7, #4] + 8006cdc: 0011 movs r1, r2 + 8006cde: 0018 movs r0, r3 + 8006ce0: f7fe fc59 bl 8005596 + 8006ce4: 1e03 subs r3, r0, #0 + 8006ce6: d009 beq.n 8006cfc + /* drop short packets */ + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: short packet\n")); + TCP_STATS_INC(tcp.lenerr); + 8006ce8: 4b8f ldr r3, [pc, #572] ; (8006f28 ) + 8006cea: 229a movs r2, #154 ; 0x9a + 8006cec: 5a9b ldrh r3, [r3, r2] + 8006cee: 3301 adds r3, #1 + 8006cf0: b299 uxth r1, r3 + 8006cf2: 4b8d ldr r3, [pc, #564] ; (8006f28 ) + 8006cf4: 229a movs r2, #154 ; 0x9a + 8006cf6: 5299 strh r1, [r3, r2] + goto dropped; + 8006cf8: f000 fb9c bl 8007434 + } + + /* Convert fields in TCP header to host byte order. */ + tcphdr->src = ntohs(tcphdr->src); + 8006cfc: 4b8c ldr r3, [pc, #560] ; (8006f30 ) + 8006cfe: 681b ldr r3, [r3, #0] + 8006d00: 781a ldrb r2, [r3, #0] + 8006d02: 785b ldrb r3, [r3, #1] + 8006d04: 021b lsls r3, r3, #8 + 8006d06: 4313 orrs r3, r2 + 8006d08: b29a uxth r2, r3 + 8006d0a: 4b89 ldr r3, [pc, #548] ; (8006f30 ) + 8006d0c: 681c ldr r4, [r3, #0] + 8006d0e: 0010 movs r0, r2 + 8006d10: f7fd fc96 bl 8004640 + 8006d14: 0003 movs r3, r0 + 8006d16: 22ff movs r2, #255 ; 0xff + 8006d18: 401a ands r2, r3 + 8006d1a: 0010 movs r0, r2 + 8006d1c: 7822 ldrb r2, [r4, #0] + 8006d1e: 2100 movs r1, #0 + 8006d20: 400a ands r2, r1 + 8006d22: 1c11 adds r1, r2, #0 + 8006d24: 1c02 adds r2, r0, #0 + 8006d26: 430a orrs r2, r1 + 8006d28: 7022 strb r2, [r4, #0] + 8006d2a: 0a1b lsrs r3, r3, #8 + 8006d2c: b299 uxth r1, r3 + 8006d2e: 7863 ldrb r3, [r4, #1] + 8006d30: 2200 movs r2, #0 + 8006d32: 4013 ands r3, r2 + 8006d34: 1c1a adds r2, r3, #0 + 8006d36: 1c0b adds r3, r1, #0 + 8006d38: 4313 orrs r3, r2 + 8006d3a: 7063 strb r3, [r4, #1] + tcphdr->dest = ntohs(tcphdr->dest); + 8006d3c: 4b7c ldr r3, [pc, #496] ; (8006f30 ) + 8006d3e: 681b ldr r3, [r3, #0] + 8006d40: 789a ldrb r2, [r3, #2] + 8006d42: 78db ldrb r3, [r3, #3] + 8006d44: 021b lsls r3, r3, #8 + 8006d46: 4313 orrs r3, r2 + 8006d48: b29a uxth r2, r3 + 8006d4a: 4b79 ldr r3, [pc, #484] ; (8006f30 ) + 8006d4c: 681c ldr r4, [r3, #0] + 8006d4e: 0010 movs r0, r2 + 8006d50: f7fd fc76 bl 8004640 + 8006d54: 0003 movs r3, r0 + 8006d56: 22ff movs r2, #255 ; 0xff + 8006d58: 401a ands r2, r3 + 8006d5a: 0010 movs r0, r2 + 8006d5c: 78a2 ldrb r2, [r4, #2] + 8006d5e: 2100 movs r1, #0 + 8006d60: 400a ands r2, r1 + 8006d62: 1c11 adds r1, r2, #0 + 8006d64: 1c02 adds r2, r0, #0 + 8006d66: 430a orrs r2, r1 + 8006d68: 70a2 strb r2, [r4, #2] + 8006d6a: 0a1b lsrs r3, r3, #8 + 8006d6c: b299 uxth r1, r3 + 8006d6e: 78e3 ldrb r3, [r4, #3] + 8006d70: 2200 movs r2, #0 + 8006d72: 4013 ands r3, r2 + 8006d74: 1c1a adds r2, r3, #0 + 8006d76: 1c0b adds r3, r1, #0 + 8006d78: 4313 orrs r3, r2 + 8006d7a: 70e3 strb r3, [r4, #3] + seqno = tcphdr->seqno = ntohl(tcphdr->seqno); + 8006d7c: 4b6c ldr r3, [pc, #432] ; (8006f30 ) + 8006d7e: 681b ldr r3, [r3, #0] + 8006d80: 791a ldrb r2, [r3, #4] + 8006d82: 7959 ldrb r1, [r3, #5] + 8006d84: 0209 lsls r1, r1, #8 + 8006d86: 430a orrs r2, r1 + 8006d88: 7999 ldrb r1, [r3, #6] + 8006d8a: 0409 lsls r1, r1, #16 + 8006d8c: 430a orrs r2, r1 + 8006d8e: 79db ldrb r3, [r3, #7] + 8006d90: 061b lsls r3, r3, #24 + 8006d92: 4313 orrs r3, r2 + 8006d94: 001a movs r2, r3 + 8006d96: 4b66 ldr r3, [pc, #408] ; (8006f30 ) + 8006d98: 681c ldr r4, [r3, #0] + 8006d9a: 0010 movs r0, r2 + 8006d9c: f7fd fc79 bl 8004692 + 8006da0: 0003 movs r3, r0 + 8006da2: 22ff movs r2, #255 ; 0xff + 8006da4: 401a ands r2, r3 + 8006da6: 0010 movs r0, r2 + 8006da8: 7922 ldrb r2, [r4, #4] + 8006daa: 2100 movs r1, #0 + 8006dac: 400a ands r2, r1 + 8006dae: 1c11 adds r1, r2, #0 + 8006db0: 1c02 adds r2, r0, #0 + 8006db2: 430a orrs r2, r1 + 8006db4: 7122 strb r2, [r4, #4] + 8006db6: 0a1a lsrs r2, r3, #8 + 8006db8: 21ff movs r1, #255 ; 0xff + 8006dba: 400a ands r2, r1 + 8006dbc: 0010 movs r0, r2 + 8006dbe: 7962 ldrb r2, [r4, #5] + 8006dc0: 2100 movs r1, #0 + 8006dc2: 400a ands r2, r1 + 8006dc4: 1c11 adds r1, r2, #0 + 8006dc6: 1c02 adds r2, r0, #0 + 8006dc8: 430a orrs r2, r1 + 8006dca: 7162 strb r2, [r4, #5] + 8006dcc: 0c1a lsrs r2, r3, #16 + 8006dce: 21ff movs r1, #255 ; 0xff + 8006dd0: 400a ands r2, r1 + 8006dd2: 0010 movs r0, r2 + 8006dd4: 79a2 ldrb r2, [r4, #6] + 8006dd6: 2100 movs r1, #0 + 8006dd8: 400a ands r2, r1 + 8006dda: 1c11 adds r1, r2, #0 + 8006ddc: 1c02 adds r2, r0, #0 + 8006dde: 430a orrs r2, r1 + 8006de0: 71a2 strb r2, [r4, #6] + 8006de2: 0e19 lsrs r1, r3, #24 + 8006de4: 79e3 ldrb r3, [r4, #7] + 8006de6: 2200 movs r2, #0 + 8006de8: 4013 ands r3, r2 + 8006dea: 1c1a adds r2, r3, #0 + 8006dec: 1c0b adds r3, r1, #0 + 8006dee: 4313 orrs r3, r2 + 8006df0: 71e3 strb r3, [r4, #7] + 8006df2: 7923 ldrb r3, [r4, #4] + 8006df4: 7962 ldrb r2, [r4, #5] + 8006df6: 0212 lsls r2, r2, #8 + 8006df8: 4313 orrs r3, r2 + 8006dfa: 79a2 ldrb r2, [r4, #6] + 8006dfc: 0412 lsls r2, r2, #16 + 8006dfe: 4313 orrs r3, r2 + 8006e00: 79e2 ldrb r2, [r4, #7] + 8006e02: 0612 lsls r2, r2, #24 + 8006e04: 4313 orrs r3, r2 + 8006e06: 001a movs r2, r3 + 8006e08: 4b4c ldr r3, [pc, #304] ; (8006f3c ) + 8006e0a: 601a str r2, [r3, #0] + ackno = tcphdr->ackno = ntohl(tcphdr->ackno); + 8006e0c: 4b48 ldr r3, [pc, #288] ; (8006f30 ) + 8006e0e: 681b ldr r3, [r3, #0] + 8006e10: 7a1a ldrb r2, [r3, #8] + 8006e12: 7a59 ldrb r1, [r3, #9] + 8006e14: 0209 lsls r1, r1, #8 + 8006e16: 430a orrs r2, r1 + 8006e18: 7a99 ldrb r1, [r3, #10] + 8006e1a: 0409 lsls r1, r1, #16 + 8006e1c: 430a orrs r2, r1 + 8006e1e: 7adb ldrb r3, [r3, #11] + 8006e20: 061b lsls r3, r3, #24 + 8006e22: 4313 orrs r3, r2 + 8006e24: 001a movs r2, r3 + 8006e26: 4b42 ldr r3, [pc, #264] ; (8006f30 ) + 8006e28: 681c ldr r4, [r3, #0] + 8006e2a: 0010 movs r0, r2 + 8006e2c: f7fd fc31 bl 8004692 + 8006e30: 0003 movs r3, r0 + 8006e32: 22ff movs r2, #255 ; 0xff + 8006e34: 401a ands r2, r3 + 8006e36: 0010 movs r0, r2 + 8006e38: 7a22 ldrb r2, [r4, #8] + 8006e3a: 2100 movs r1, #0 + 8006e3c: 400a ands r2, r1 + 8006e3e: 1c11 adds r1, r2, #0 + 8006e40: 1c02 adds r2, r0, #0 + 8006e42: 430a orrs r2, r1 + 8006e44: 7222 strb r2, [r4, #8] + 8006e46: 0a1a lsrs r2, r3, #8 + 8006e48: 21ff movs r1, #255 ; 0xff + 8006e4a: 400a ands r2, r1 + 8006e4c: 0010 movs r0, r2 + 8006e4e: 7a62 ldrb r2, [r4, #9] + 8006e50: 2100 movs r1, #0 + 8006e52: 400a ands r2, r1 + 8006e54: 1c11 adds r1, r2, #0 + 8006e56: 1c02 adds r2, r0, #0 + 8006e58: 430a orrs r2, r1 + 8006e5a: 7262 strb r2, [r4, #9] + 8006e5c: 0c1a lsrs r2, r3, #16 + 8006e5e: 21ff movs r1, #255 ; 0xff + 8006e60: 400a ands r2, r1 + 8006e62: 0010 movs r0, r2 + 8006e64: 7aa2 ldrb r2, [r4, #10] + 8006e66: 2100 movs r1, #0 + 8006e68: 400a ands r2, r1 + 8006e6a: 1c11 adds r1, r2, #0 + 8006e6c: 1c02 adds r2, r0, #0 + 8006e6e: 430a orrs r2, r1 + 8006e70: 72a2 strb r2, [r4, #10] + 8006e72: 0e19 lsrs r1, r3, #24 + 8006e74: 7ae3 ldrb r3, [r4, #11] + 8006e76: 2200 movs r2, #0 + 8006e78: 4013 ands r3, r2 + 8006e7a: 1c1a adds r2, r3, #0 + 8006e7c: 1c0b adds r3, r1, #0 + 8006e7e: 4313 orrs r3, r2 + 8006e80: 72e3 strb r3, [r4, #11] + 8006e82: 7a23 ldrb r3, [r4, #8] + 8006e84: 7a62 ldrb r2, [r4, #9] + 8006e86: 0212 lsls r2, r2, #8 + 8006e88: 4313 orrs r3, r2 + 8006e8a: 7aa2 ldrb r2, [r4, #10] + 8006e8c: 0412 lsls r2, r2, #16 + 8006e8e: 4313 orrs r3, r2 + 8006e90: 7ae2 ldrb r2, [r4, #11] + 8006e92: 0612 lsls r2, r2, #24 + 8006e94: 4313 orrs r3, r2 + 8006e96: 001a movs r2, r3 + 8006e98: 4b29 ldr r3, [pc, #164] ; (8006f40 ) + 8006e9a: 601a str r2, [r3, #0] + tcphdr->wnd = ntohs(tcphdr->wnd); + 8006e9c: 4b24 ldr r3, [pc, #144] ; (8006f30 ) + 8006e9e: 681b ldr r3, [r3, #0] + 8006ea0: 7b9a ldrb r2, [r3, #14] + 8006ea2: 7bdb ldrb r3, [r3, #15] + 8006ea4: 021b lsls r3, r3, #8 + 8006ea6: 4313 orrs r3, r2 + 8006ea8: b29a uxth r2, r3 + 8006eaa: 4b21 ldr r3, [pc, #132] ; (8006f30 ) + 8006eac: 681c ldr r4, [r3, #0] + 8006eae: 0010 movs r0, r2 + 8006eb0: f7fd fbc6 bl 8004640 + 8006eb4: 0003 movs r3, r0 + 8006eb6: 22ff movs r2, #255 ; 0xff + 8006eb8: 401a ands r2, r3 + 8006eba: 0010 movs r0, r2 + 8006ebc: 7ba2 ldrb r2, [r4, #14] + 8006ebe: 2100 movs r1, #0 + 8006ec0: 400a ands r2, r1 + 8006ec2: 1c11 adds r1, r2, #0 + 8006ec4: 1c02 adds r2, r0, #0 + 8006ec6: 430a orrs r2, r1 + 8006ec8: 73a2 strb r2, [r4, #14] + 8006eca: 0a1b lsrs r3, r3, #8 + 8006ecc: b299 uxth r1, r3 + 8006ece: 7be3 ldrb r3, [r4, #15] + 8006ed0: 2200 movs r2, #0 + 8006ed2: 4013 ands r3, r2 + 8006ed4: 1c1a adds r2, r3, #0 + 8006ed6: 1c0b adds r3, r1, #0 + 8006ed8: 4313 orrs r3, r2 + 8006eda: 73e3 strb r3, [r4, #15] + + flags = TCPH_FLAGS(tcphdr); + 8006edc: 4b14 ldr r3, [pc, #80] ; (8006f30 ) + 8006ede: 681b ldr r3, [r3, #0] + 8006ee0: 7b1a ldrb r2, [r3, #12] + 8006ee2: 7b5b ldrb r3, [r3, #13] + 8006ee4: 021b lsls r3, r3, #8 + 8006ee6: 4313 orrs r3, r2 + 8006ee8: b29b uxth r3, r3 + 8006eea: 0018 movs r0, r3 + 8006eec: f7fd fba8 bl 8004640 + 8006ef0: 0003 movs r3, r0 + 8006ef2: b2db uxtb r3, r3 + 8006ef4: 223f movs r2, #63 ; 0x3f + 8006ef6: 4013 ands r3, r2 + 8006ef8: b2da uxtb r2, r3 + 8006efa: 4b12 ldr r3, [pc, #72] ; (8006f44 ) + 8006efc: 701a strb r2, [r3, #0] + tcplen = p->tot_len + ((flags & (TCP_FIN | TCP_SYN)) ? 1 : 0); + 8006efe: 687b ldr r3, [r7, #4] + 8006f00: 891a ldrh r2, [r3, #8] + 8006f02: 4b10 ldr r3, [pc, #64] ; (8006f44 ) + 8006f04: 781b ldrb r3, [r3, #0] + 8006f06: 0019 movs r1, r3 + 8006f08: 2303 movs r3, #3 + 8006f0a: 400b ands r3, r1 + 8006f0c: 1e59 subs r1, r3, #1 + 8006f0e: 418b sbcs r3, r1 + 8006f10: b2db uxtb r3, r3 + 8006f12: b29b uxth r3, r3 + 8006f14: 18d3 adds r3, r2, r3 + 8006f16: b29a uxth r2, r3 + 8006f18: 4b0b ldr r3, [pc, #44] ; (8006f48 ) + 8006f1a: 801a strh r2, [r3, #0] + + /* Demultiplex an incoming segment. First, we check if it is destined + for an active connection. */ + prev = NULL; + 8006f1c: 2300 movs r3, #0 + 8006f1e: 613b str r3, [r7, #16] + + + for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) { + 8006f20: 4b0a ldr r3, [pc, #40] ; (8006f4c ) + 8006f22: 681b ldr r3, [r3, #0] + 8006f24: 617b str r3, [r7, #20] + 8006f26: e049 b.n 8006fbc + 8006f28: 20003158 .word 0x20003158 + 8006f2c: 20002290 .word 0x20002290 + 8006f30: 2000228c .word 0x2000228c + 8006f34: 2000329c .word 0x2000329c + 8006f38: 20003294 .word 0x20003294 + 8006f3c: 20002294 .word 0x20002294 + 8006f40: 20002298 .word 0x20002298 + 8006f44: 2000229c .word 0x2000229c + 8006f48: 2000229e .word 0x2000229e + 8006f4c: 20003274 .word 0x20003274 + LWIP_ASSERT("tcp_input: active pcb->state != CLOSED", pcb->state != CLOSED); + LWIP_ASSERT("tcp_input: active pcb->state != TIME-WAIT", pcb->state != TIME_WAIT); + LWIP_ASSERT("tcp_input: active pcb->state != LISTEN", pcb->state != LISTEN); + if (pcb->remote_port == tcphdr->src && + 8006f50: 697b ldr r3, [r7, #20] + 8006f52: 8b9a ldrh r2, [r3, #28] + 8006f54: 4bcc ldr r3, [pc, #816] ; (8007288 ) + 8006f56: 681b ldr r3, [r3, #0] + 8006f58: 7819 ldrb r1, [r3, #0] + 8006f5a: 785b ldrb r3, [r3, #1] + 8006f5c: 021b lsls r3, r3, #8 + 8006f5e: 430b orrs r3, r1 + 8006f60: b29b uxth r3, r3 + 8006f62: 429a cmp r2, r3 + 8006f64: d125 bne.n 8006fb2 + pcb->local_port == tcphdr->dest && + 8006f66: 697b ldr r3, [r7, #20] + 8006f68: 8b5a ldrh r2, [r3, #26] + 8006f6a: 4bc7 ldr r3, [pc, #796] ; (8007288 ) + 8006f6c: 681b ldr r3, [r3, #0] + 8006f6e: 7899 ldrb r1, [r3, #2] + 8006f70: 78db ldrb r3, [r3, #3] + 8006f72: 021b lsls r3, r3, #8 + 8006f74: 430b orrs r3, r1 + 8006f76: b29b uxth r3, r3 + if (pcb->remote_port == tcphdr->src && + 8006f78: 429a cmp r2, r3 + 8006f7a: d11a bne.n 8006fb2 + ip_addr_cmp(&(pcb->remote_ip), ¤t_iphdr_src) && + 8006f7c: 697b ldr r3, [r7, #20] + 8006f7e: 685a ldr r2, [r3, #4] + 8006f80: 4bc2 ldr r3, [pc, #776] ; (800728c ) + 8006f82: 681b ldr r3, [r3, #0] + pcb->local_port == tcphdr->dest && + 8006f84: 429a cmp r2, r3 + 8006f86: d114 bne.n 8006fb2 + ip_addr_cmp(&(pcb->local_ip), ¤t_iphdr_dest)) { + 8006f88: 697b ldr r3, [r7, #20] + 8006f8a: 681a ldr r2, [r3, #0] + 8006f8c: 4bc0 ldr r3, [pc, #768] ; (8007290 ) + 8006f8e: 681b ldr r3, [r3, #0] + ip_addr_cmp(&(pcb->remote_ip), ¤t_iphdr_src) && + 8006f90: 429a cmp r2, r3 + 8006f92: d10e bne.n 8006fb2 + + /* Move this PCB to the front of the list so that subsequent + lookups will be faster (we exploit locality in TCP segment + arrivals). */ + LWIP_ASSERT("tcp_input: pcb->next != pcb (before cache)", pcb->next != pcb); + if (prev != NULL) { + 8006f94: 693b ldr r3, [r7, #16] + 8006f96: 2b00 cmp r3, #0 + 8006f98: d014 beq.n 8006fc4 + prev->next = pcb->next; + 8006f9a: 697b ldr r3, [r7, #20] + 8006f9c: 68da ldr r2, [r3, #12] + 8006f9e: 693b ldr r3, [r7, #16] + 8006fa0: 60da str r2, [r3, #12] + pcb->next = tcp_active_pcbs; + 8006fa2: 4bbc ldr r3, [pc, #752] ; (8007294 ) + 8006fa4: 681a ldr r2, [r3, #0] + 8006fa6: 697b ldr r3, [r7, #20] + 8006fa8: 60da str r2, [r3, #12] + tcp_active_pcbs = pcb; + 8006faa: 4bba ldr r3, [pc, #744] ; (8007294 ) + 8006fac: 697a ldr r2, [r7, #20] + 8006fae: 601a str r2, [r3, #0] + } + LWIP_ASSERT("tcp_input: pcb->next != pcb (after cache)", pcb->next != pcb); + break; + 8006fb0: e008 b.n 8006fc4 + } + prev = pcb; + 8006fb2: 697b ldr r3, [r7, #20] + 8006fb4: 613b str r3, [r7, #16] + for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) { + 8006fb6: 697b ldr r3, [r7, #20] + 8006fb8: 68db ldr r3, [r3, #12] + 8006fba: 617b str r3, [r7, #20] + 8006fbc: 697b ldr r3, [r7, #20] + 8006fbe: 2b00 cmp r3, #0 + 8006fc0: d1c6 bne.n 8006f50 + 8006fc2: e000 b.n 8006fc6 + break; + 8006fc4: 46c0 nop ; (mov r8, r8) + } + + if (pcb == NULL) { + 8006fc6: 697b ldr r3, [r7, #20] + 8006fc8: 2b00 cmp r3, #0 + 8006fca: d000 beq.n 8006fce + 8006fcc: e074 b.n 80070b8 + /* If it did not go to an active connection, we check the connections + in the TIME-WAIT state. */ + for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) { + 8006fce: 4bb2 ldr r3, [pc, #712] ; (8007298 ) + 8006fd0: 681b ldr r3, [r3, #0] + 8006fd2: 617b str r3, [r7, #20] + 8006fd4: e02d b.n 8007032 + LWIP_ASSERT("tcp_input: TIME-WAIT pcb->state == TIME-WAIT", pcb->state == TIME_WAIT); + if (pcb->remote_port == tcphdr->src && + 8006fd6: 697b ldr r3, [r7, #20] + 8006fd8: 8b9a ldrh r2, [r3, #28] + 8006fda: 4bab ldr r3, [pc, #684] ; (8007288 ) + 8006fdc: 681b ldr r3, [r3, #0] + 8006fde: 7819 ldrb r1, [r3, #0] + 8006fe0: 785b ldrb r3, [r3, #1] + 8006fe2: 021b lsls r3, r3, #8 + 8006fe4: 430b orrs r3, r1 + 8006fe6: b29b uxth r3, r3 + 8006fe8: 429a cmp r2, r3 + 8006fea: d11f bne.n 800702c + pcb->local_port == tcphdr->dest && + 8006fec: 697b ldr r3, [r7, #20] + 8006fee: 8b5a ldrh r2, [r3, #26] + 8006ff0: 4ba5 ldr r3, [pc, #660] ; (8007288 ) + 8006ff2: 681b ldr r3, [r3, #0] + 8006ff4: 7899 ldrb r1, [r3, #2] + 8006ff6: 78db ldrb r3, [r3, #3] + 8006ff8: 021b lsls r3, r3, #8 + 8006ffa: 430b orrs r3, r1 + 8006ffc: b29b uxth r3, r3 + if (pcb->remote_port == tcphdr->src && + 8006ffe: 429a cmp r2, r3 + 8007000: d114 bne.n 800702c + ip_addr_cmp(&(pcb->remote_ip), ¤t_iphdr_src) && + 8007002: 697b ldr r3, [r7, #20] + 8007004: 685a ldr r2, [r3, #4] + 8007006: 4ba1 ldr r3, [pc, #644] ; (800728c ) + 8007008: 681b ldr r3, [r3, #0] + pcb->local_port == tcphdr->dest && + 800700a: 429a cmp r2, r3 + 800700c: d10e bne.n 800702c + ip_addr_cmp(&(pcb->local_ip), ¤t_iphdr_dest)) { + 800700e: 697b ldr r3, [r7, #20] + 8007010: 681a ldr r2, [r3, #0] + 8007012: 4b9f ldr r3, [pc, #636] ; (8007290 ) + 8007014: 681b ldr r3, [r3, #0] + ip_addr_cmp(&(pcb->remote_ip), ¤t_iphdr_src) && + 8007016: 429a cmp r2, r3 + 8007018: d108 bne.n 800702c + /* We don't really care enough to move this PCB to the front + of the list since we are not very likely to receive that + many segments for connections in TIME-WAIT. */ + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: packed for TIME_WAITing connection.\n")); + tcp_timewait_input(pcb); + 800701a: 697b ldr r3, [r7, #20] + 800701c: 0018 movs r0, r3 + 800701e: f000 fb23 bl 8007668 + pbuf_free(p); + 8007022: 687b ldr r3, [r7, #4] + 8007024: 0018 movs r0, r3 + 8007026: f7fe fb3d bl 80056a4 + return; + 800702a: e211 b.n 8007450 + for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) { + 800702c: 697b ldr r3, [r7, #20] + 800702e: 68db ldr r3, [r3, #12] + 8007030: 617b str r3, [r7, #20] + 8007032: 697b ldr r3, [r7, #20] + 8007034: 2b00 cmp r3, #0 + 8007036: d1ce bne.n 8006fd6 + } + } + + /* Finally, if we still did not get a match, we check all PCBs that + are LISTENing for incoming connections. */ + prev = NULL; + 8007038: 2300 movs r3, #0 + 800703a: 613b str r3, [r7, #16] + for(lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next) { + 800703c: 4b97 ldr r3, [pc, #604] ; (800729c ) + 800703e: 681b ldr r3, [r3, #0] + 8007040: 60fb str r3, [r7, #12] + 8007042: e01c b.n 800707e + if (lpcb->local_port == tcphdr->dest) { + 8007044: 68fb ldr r3, [r7, #12] + 8007046: 8b5a ldrh r2, [r3, #26] + 8007048: 4b8f ldr r3, [pc, #572] ; (8007288 ) + 800704a: 681b ldr r3, [r3, #0] + 800704c: 7899 ldrb r1, [r3, #2] + 800704e: 78db ldrb r3, [r3, #3] + 8007050: 021b lsls r3, r3, #8 + 8007052: 430b orrs r3, r1 + 8007054: b29b uxth r3, r3 + 8007056: 429a cmp r2, r3 + 8007058: d10c bne.n 8007074 + /* found an ANY-match */ + lpcb_any = lpcb; + lpcb_prev = prev; + } +#else /* SO_REUSE */ + if (ip_addr_cmp(&(lpcb->local_ip), ¤t_iphdr_dest) || + 800705a: 68fb ldr r3, [r7, #12] + 800705c: 681a ldr r2, [r3, #0] + 800705e: 4b8c ldr r3, [pc, #560] ; (8007290 ) + 8007060: 681b ldr r3, [r3, #0] + 8007062: 429a cmp r2, r3 + 8007064: d00e beq.n 8007084 + ip_addr_isany(&(lpcb->local_ip))) { + 8007066: 68fb ldr r3, [r7, #12] + if (ip_addr_cmp(&(lpcb->local_ip), ¤t_iphdr_dest) || + 8007068: 2b00 cmp r3, #0 + 800706a: d00b beq.n 8007084 + ip_addr_isany(&(lpcb->local_ip))) { + 800706c: 68fb ldr r3, [r7, #12] + 800706e: 681b ldr r3, [r3, #0] + 8007070: 2b00 cmp r3, #0 + 8007072: d007 beq.n 8007084 + /* found a match */ + break; + } +#endif /* SO_REUSE */ + } + prev = (struct tcp_pcb *)lpcb; + 8007074: 68fb ldr r3, [r7, #12] + 8007076: 613b str r3, [r7, #16] + for(lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next) { + 8007078: 68fb ldr r3, [r7, #12] + 800707a: 68db ldr r3, [r3, #12] + 800707c: 60fb str r3, [r7, #12] + 800707e: 68fb ldr r3, [r7, #12] + 8007080: 2b00 cmp r3, #0 + 8007082: d1df bne.n 8007044 + /* only pass to ANY if no specific local IP has been found */ + lpcb = lpcb_any; + prev = lpcb_prev; + } +#endif /* SO_REUSE */ + if (lpcb != NULL) { + 8007084: 68fb ldr r3, [r7, #12] + 8007086: 2b00 cmp r3, #0 + 8007088: d016 beq.n 80070b8 + /* Move this PCB to the front of the list so that subsequent + lookups will be faster (we exploit locality in TCP segment + arrivals). */ + if (prev != NULL) { + 800708a: 693b ldr r3, [r7, #16] + 800708c: 2b00 cmp r3, #0 + 800708e: d00a beq.n 80070a6 + ((struct tcp_pcb_listen *)prev)->next = lpcb->next; + 8007090: 68fb ldr r3, [r7, #12] + 8007092: 68da ldr r2, [r3, #12] + 8007094: 693b ldr r3, [r7, #16] + 8007096: 60da str r2, [r3, #12] + /* our successor is the remainder of the listening list */ + lpcb->next = tcp_listen_pcbs.listen_pcbs; + 8007098: 4b80 ldr r3, [pc, #512] ; (800729c ) + 800709a: 681a ldr r2, [r3, #0] + 800709c: 68fb ldr r3, [r7, #12] + 800709e: 60da str r2, [r3, #12] + /* put this listening pcb at the head of the listening list */ + tcp_listen_pcbs.listen_pcbs = lpcb; + 80070a0: 4b7e ldr r3, [pc, #504] ; (800729c ) + 80070a2: 68fa ldr r2, [r7, #12] + 80070a4: 601a str r2, [r3, #0] + } + + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: packed for LISTENing connection.\n")); + tcp_listen_input(lpcb); + 80070a6: 68fb ldr r3, [r7, #12] + 80070a8: 0018 movs r0, r3 + 80070aa: f000 f9ed bl 8007488 + pbuf_free(p); + 80070ae: 687b ldr r3, [r7, #4] + 80070b0: 0018 movs r0, r3 + 80070b2: f7fe faf7 bl 80056a4 + return; + 80070b6: e1cb b.n 8007450 + tcp_debug_print_flags(TCPH_FLAGS(tcphdr)); + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n")); +#endif /* TCP_INPUT_DEBUG */ + + + if (pcb != NULL) { + 80070b8: 697b ldr r3, [r7, #20] + 80070ba: 2b00 cmp r3, #0 + 80070bc: d100 bne.n 80070c0 + 80070be: e176 b.n 80073ae + tcp_debug_print_state(pcb->state); +#endif /* TCP_DEBUG */ +#endif /* TCP_INPUT_DEBUG */ + + /* Set up a tcp_seg structure. */ + inseg.next = NULL; + 80070c0: 4b77 ldr r3, [pc, #476] ; (80072a0 ) + 80070c2: 2200 movs r2, #0 + 80070c4: 601a str r2, [r3, #0] + inseg.len = p->tot_len; + 80070c6: 687b ldr r3, [r7, #4] + 80070c8: 891a ldrh r2, [r3, #8] + 80070ca: 4b75 ldr r3, [pc, #468] ; (80072a0 ) + 80070cc: 811a strh r2, [r3, #8] + inseg.p = p; + 80070ce: 4b74 ldr r3, [pc, #464] ; (80072a0 ) + 80070d0: 687a ldr r2, [r7, #4] + 80070d2: 605a str r2, [r3, #4] + inseg.tcphdr = tcphdr; + 80070d4: 4b6c ldr r3, [pc, #432] ; (8007288 ) + 80070d6: 681a ldr r2, [r3, #0] + 80070d8: 4b71 ldr r3, [pc, #452] ; (80072a0 ) + 80070da: 60da str r2, [r3, #12] + + recv_data = NULL; + 80070dc: 4b71 ldr r3, [pc, #452] ; (80072a4 ) + 80070de: 2200 movs r2, #0 + 80070e0: 601a str r2, [r3, #0] + recv_flags = 0; + 80070e2: 4b71 ldr r3, [pc, #452] ; (80072a8 ) + 80070e4: 2200 movs r2, #0 + 80070e6: 701a strb r2, [r3, #0] + + if (flags & TCP_PSH) { + 80070e8: 4b70 ldr r3, [pc, #448] ; (80072ac ) + 80070ea: 781b ldrb r3, [r3, #0] + 80070ec: 001a movs r2, r3 + 80070ee: 2308 movs r3, #8 + 80070f0: 4013 ands r3, r2 + 80070f2: d006 beq.n 8007102 + p->flags |= PBUF_FLAG_PUSH; + 80070f4: 687b ldr r3, [r7, #4] + 80070f6: 7b5b ldrb r3, [r3, #13] + 80070f8: 2201 movs r2, #1 + 80070fa: 4313 orrs r3, r2 + 80070fc: b2da uxtb r2, r3 + 80070fe: 687b ldr r3, [r7, #4] + 8007100: 735a strb r2, [r3, #13] + } + + /* If there is data which was previously "refused" by upper layer */ + if (pcb->refused_data != NULL) { + 8007102: 697b ldr r3, [r7, #20] + 8007104: 6f9b ldr r3, [r3, #120] ; 0x78 + 8007106: 2b00 cmp r3, #0 + 8007108: d017 beq.n 800713a + if ((tcp_process_refused_data(pcb) == ERR_ABRT) || + 800710a: 697b ldr r3, [r7, #20] + 800710c: 0018 movs r0, r3 + 800710e: f7ff fa79 bl 8006604 + 8007112: 0003 movs r3, r0 + 8007114: 330a adds r3, #10 + 8007116: d007 beq.n 8007128 + ((pcb->refused_data != NULL) && (tcplen > 0))) { + 8007118: 697b ldr r3, [r7, #20] + 800711a: 6f9b ldr r3, [r3, #120] ; 0x78 + if ((tcp_process_refused_data(pcb) == ERR_ABRT) || + 800711c: 2b00 cmp r3, #0 + 800711e: d00c beq.n 800713a + ((pcb->refused_data != NULL) && (tcplen > 0))) { + 8007120: 4b63 ldr r3, [pc, #396] ; (80072b0 ) + 8007122: 881b ldrh r3, [r3, #0] + 8007124: 2b00 cmp r3, #0 + 8007126: d008 beq.n 800713a + /* pcb has been aborted or refused data is still refused and the new + segment contains data */ + TCP_STATS_INC(tcp.drop); + 8007128: 4b62 ldr r3, [pc, #392] ; (80072b4 ) + 800712a: 2296 movs r2, #150 ; 0x96 + 800712c: 5a9b ldrh r3, [r3, r2] + 800712e: 3301 adds r3, #1 + 8007130: b299 uxth r1, r3 + 8007132: 4b60 ldr r3, [pc, #384] ; (80072b4 ) + 8007134: 2296 movs r2, #150 ; 0x96 + 8007136: 5299 strh r1, [r3, r2] + snmp_inc_tcpinerrs(); + goto aborted; + 8007138: e126 b.n 8007388 + } + } + tcp_input_pcb = pcb; + 800713a: 4b5f ldr r3, [pc, #380] ; (80072b8 ) + 800713c: 697a ldr r2, [r7, #20] + 800713e: 601a str r2, [r3, #0] + err = tcp_process(pcb); + 8007140: 250b movs r5, #11 + 8007142: 197c adds r4, r7, r5 + 8007144: 697b ldr r3, [r7, #20] + 8007146: 0018 movs r0, r3 + 8007148: f000 fb02 bl 8007750 + 800714c: 0003 movs r3, r0 + 800714e: 7023 strb r3, [r4, #0] + /* A return value of ERR_ABRT means that tcp_abort() was called + and that the pcb has been freed. If so, we don't do anything. */ + if (err != ERR_ABRT) { + 8007150: 197b adds r3, r7, r5 + 8007152: 781b ldrb r3, [r3, #0] + 8007154: b25b sxtb r3, r3 + 8007156: 330a adds r3, #10 + 8007158: d100 bne.n 800715c + 800715a: e10e b.n 800737a + if (recv_flags & TF_RESET) { + 800715c: 4b52 ldr r3, [pc, #328] ; (80072a8 ) + 800715e: 781b ldrb r3, [r3, #0] + 8007160: 001a movs r2, r3 + 8007162: 2308 movs r3, #8 + 8007164: 4013 ands r3, r2 + 8007166: d019 beq.n 800719c + /* TF_RESET means that the connection was reset by the other + end. We then call the error callback to inform the + application that the connection is dead before we + deallocate the PCB. */ + TCP_EVENT_ERR(pcb->errf, pcb->callback_arg, ERR_RST); + 8007168: 697b ldr r3, [r7, #20] + 800716a: 228c movs r2, #140 ; 0x8c + 800716c: 589b ldr r3, [r3, r2] + 800716e: 2b00 cmp r3, #0 + 8007170: d008 beq.n 8007184 + 8007172: 697b ldr r3, [r7, #20] + 8007174: 228c movs r2, #140 ; 0x8c + 8007176: 589a ldr r2, [r3, r2] + 8007178: 697b ldr r3, [r7, #20] + 800717a: 6918 ldr r0, [r3, #16] + 800717c: 230b movs r3, #11 + 800717e: 425b negs r3, r3 + 8007180: 0019 movs r1, r3 + 8007182: 4790 blx r2 + tcp_pcb_remove(&tcp_active_pcbs, pcb); + 8007184: 697a ldr r2, [r7, #20] + 8007186: 4b43 ldr r3, [pc, #268] ; (8007294 ) + 8007188: 0011 movs r1, r2 + 800718a: 0018 movs r0, r3 + 800718c: f7ff fc8e bl 8006aac + memp_free(MEMP_TCP_PCB, pcb); + 8007190: 697b ldr r3, [r7, #20] + 8007192: 0019 movs r1, r3 + 8007194: 2002 movs r0, #2 + 8007196: f7fd fec3 bl 8004f20 + 800719a: e0f5 b.n 8007388 + } else if (recv_flags & TF_CLOSED) { + 800719c: 4b42 ldr r3, [pc, #264] ; (80072a8 ) + 800719e: 781b ldrb r3, [r3, #0] + 80071a0: 001a movs r2, r3 + 80071a2: 2310 movs r3, #16 + 80071a4: 4013 ands r3, r2 + 80071a6: d01f beq.n 80071e8 + /* The connection has been closed and we will deallocate the + PCB. */ + if (!(pcb->flags & TF_RXCLOSED)) { + 80071a8: 697b ldr r3, [r7, #20] + 80071aa: 7f9b ldrb r3, [r3, #30] + 80071ac: 001a movs r2, r3 + 80071ae: 2310 movs r3, #16 + 80071b0: 4013 ands r3, r2 + 80071b2: d10d bne.n 80071d0 + /* Connection closed although the application has only shut down the + tx side: call the PCB's err callback and indicate the closure to + ensure the application doesn't continue using the PCB. */ + TCP_EVENT_ERR(pcb->errf, pcb->callback_arg, ERR_CLSD); + 80071b4: 697b ldr r3, [r7, #20] + 80071b6: 228c movs r2, #140 ; 0x8c + 80071b8: 589b ldr r3, [r3, r2] + 80071ba: 2b00 cmp r3, #0 + 80071bc: d008 beq.n 80071d0 + 80071be: 697b ldr r3, [r7, #20] + 80071c0: 228c movs r2, #140 ; 0x8c + 80071c2: 589a ldr r2, [r3, r2] + 80071c4: 697b ldr r3, [r7, #20] + 80071c6: 6918 ldr r0, [r3, #16] + 80071c8: 230c movs r3, #12 + 80071ca: 425b negs r3, r3 + 80071cc: 0019 movs r1, r3 + 80071ce: 4790 blx r2 + } + tcp_pcb_remove(&tcp_active_pcbs, pcb); + 80071d0: 697a ldr r2, [r7, #20] + 80071d2: 4b30 ldr r3, [pc, #192] ; (8007294 ) + 80071d4: 0011 movs r1, r2 + 80071d6: 0018 movs r0, r3 + 80071d8: f7ff fc68 bl 8006aac + memp_free(MEMP_TCP_PCB, pcb); + 80071dc: 697b ldr r3, [r7, #20] + 80071de: 0019 movs r1, r3 + 80071e0: 2002 movs r0, #2 + 80071e2: f7fd fe9d bl 8004f20 + 80071e6: e0cf b.n 8007388 + } else { + err = ERR_OK; + 80071e8: 230b movs r3, #11 + 80071ea: 18fb adds r3, r7, r3 + 80071ec: 2200 movs r2, #0 + 80071ee: 701a strb r2, [r3, #0] + /* If the application has registered a "sent" function to be + called when new send buffer space is available, we call it + now. */ + if (pcb->acked > 0) { + 80071f0: 697b ldr r3, [r7, #20] + 80071f2: 2264 movs r2, #100 ; 0x64 + 80071f4: 5a9b ldrh r3, [r3, r2] + 80071f6: 2b00 cmp r3, #0 + 80071f8: d01d beq.n 8007236 + TCP_EVENT_SENT(pcb, pcb->acked, err); + 80071fa: 697b ldr r3, [r7, #20] + 80071fc: 6fdb ldr r3, [r3, #124] ; 0x7c + 80071fe: 2b00 cmp r3, #0 + 8007200: d00e beq.n 8007220 + 8007202: 697b ldr r3, [r7, #20] + 8007204: 6fdd ldr r5, [r3, #124] ; 0x7c + 8007206: 697b ldr r3, [r7, #20] + 8007208: 6918 ldr r0, [r3, #16] + 800720a: 697b ldr r3, [r7, #20] + 800720c: 2264 movs r2, #100 ; 0x64 + 800720e: 5a9a ldrh r2, [r3, r2] + 8007210: 230b movs r3, #11 + 8007212: 18fc adds r4, r7, r3 + 8007214: 697b ldr r3, [r7, #20] + 8007216: 0019 movs r1, r3 + 8007218: 47a8 blx r5 + 800721a: 0003 movs r3, r0 + 800721c: 7023 strb r3, [r4, #0] + 800721e: e003 b.n 8007228 + 8007220: 230b movs r3, #11 + 8007222: 18fb adds r3, r7, r3 + 8007224: 2200 movs r2, #0 + 8007226: 701a strb r2, [r3, #0] + if (err == ERR_ABRT) { + 8007228: 230b movs r3, #11 + 800722a: 18fb adds r3, r7, r3 + 800722c: 781b ldrb r3, [r3, #0] + 800722e: b25b sxtb r3, r3 + 8007230: 330a adds r3, #10 + 8007232: d100 bne.n 8007236 + 8007234: e0a3 b.n 800737e + goto aborted; + } + } + + if (recv_data != NULL) { + 8007236: 4b1b ldr r3, [pc, #108] ; (80072a4 ) + 8007238: 681b ldr r3, [r3, #0] + 800723a: 2b00 cmp r3, #0 + 800723c: d059 beq.n 80072f2 + LWIP_ASSERT("pcb->refused_data == NULL", pcb->refused_data == NULL); + if (pcb->flags & TF_RXCLOSED) { + 800723e: 697b ldr r3, [r7, #20] + 8007240: 7f9b ldrb r3, [r3, #30] + 8007242: 001a movs r2, r3 + 8007244: 2310 movs r3, #16 + 8007246: 4013 ands r3, r2 + 8007248: d009 beq.n 800725e + /* received data although already closed -> abort (send RST) to + notify the remote host that not all data has been processed */ + pbuf_free(recv_data); + 800724a: 4b16 ldr r3, [pc, #88] ; (80072a4 ) + 800724c: 681b ldr r3, [r3, #0] + 800724e: 0018 movs r0, r3 + 8007250: f7fe fa28 bl 80056a4 + tcp_abort(pcb); + 8007254: 697b ldr r3, [r7, #20] + 8007256: 0018 movs r0, r3 + 8007258: f7fe fe90 bl 8005f7c + goto aborted; + 800725c: e094 b.n 8007388 + } + + /* Notify application that data has been received. */ + TCP_EVENT_RECV(pcb, recv_data, ERR_OK, err); + 800725e: 697b ldr r3, [r7, #20] + 8007260: 2280 movs r2, #128 ; 0x80 + 8007262: 589b ldr r3, [r3, r2] + 8007264: 2b00 cmp r3, #0 + 8007266: d029 beq.n 80072bc + 8007268: 697b ldr r3, [r7, #20] + 800726a: 2280 movs r2, #128 ; 0x80 + 800726c: 589d ldr r5, [r3, r2] + 800726e: 697b ldr r3, [r7, #20] + 8007270: 6918 ldr r0, [r3, #16] + 8007272: 4b0c ldr r3, [pc, #48] ; (80072a4 ) + 8007274: 681a ldr r2, [r3, #0] + 8007276: 230b movs r3, #11 + 8007278: 18fc adds r4, r7, r3 + 800727a: 6979 ldr r1, [r7, #20] + 800727c: 2300 movs r3, #0 + 800727e: 47a8 blx r5 + 8007280: 0003 movs r3, r0 + 8007282: 7023 strb r3, [r4, #0] + 8007284: e025 b.n 80072d2 + 8007286: 46c0 nop ; (mov r8, r8) + 8007288: 2000228c .word 0x2000228c + 800728c: 20003294 .word 0x20003294 + 8007290: 2000329c .word 0x2000329c + 8007294: 20003274 .word 0x20003274 + 8007298: 20003288 .word 0x20003288 + 800729c: 2000327c .word 0x2000327c + 80072a0: 2000227c .word 0x2000227c + 80072a4: 200022a4 .word 0x200022a4 + 80072a8: 200022a0 .word 0x200022a0 + 80072ac: 2000229c .word 0x2000229c + 80072b0: 2000229e .word 0x2000229e + 80072b4: 20003158 .word 0x20003158 + 80072b8: 2000328c .word 0x2000328c + 80072bc: 4b66 ldr r3, [pc, #408] ; (8007458 ) + 80072be: 681a ldr r2, [r3, #0] + 80072c0: 230b movs r3, #11 + 80072c2: 18fc adds r4, r7, r3 + 80072c4: 6979 ldr r1, [r7, #20] + 80072c6: 2300 movs r3, #0 + 80072c8: 2000 movs r0, #0 + 80072ca: f7ff fa5f bl 800678c + 80072ce: 0003 movs r3, r0 + 80072d0: 7023 strb r3, [r4, #0] + if (err == ERR_ABRT) { + 80072d2: 230b movs r3, #11 + 80072d4: 18fb adds r3, r7, r3 + 80072d6: 781b ldrb r3, [r3, #0] + 80072d8: b25b sxtb r3, r3 + 80072da: 330a adds r3, #10 + 80072dc: d051 beq.n 8007382 + goto aborted; + } + + /* If the upper layer can't receive this data, store it */ + if (err != ERR_OK) { + 80072de: 230b movs r3, #11 + 80072e0: 18fb adds r3, r7, r3 + 80072e2: 781b ldrb r3, [r3, #0] + 80072e4: b25b sxtb r3, r3 + 80072e6: 2b00 cmp r3, #0 + 80072e8: d003 beq.n 80072f2 + pcb->refused_data = recv_data; + 80072ea: 4b5b ldr r3, [pc, #364] ; (8007458 ) + 80072ec: 681a ldr r2, [r3, #0] + 80072ee: 697b ldr r3, [r7, #20] + 80072f0: 679a str r2, [r3, #120] ; 0x78 + } + } + + /* If a FIN segment was received, we call the callback + function with a NULL buffer to indicate EOF. */ + if (recv_flags & TF_GOT_FIN) { + 80072f2: 4b5a ldr r3, [pc, #360] ; (800745c ) + 80072f4: 781b ldrb r3, [r3, #0] + 80072f6: 001a movs r2, r3 + 80072f8: 2320 movs r3, #32 + 80072fa: 4013 ands r3, r2 + 80072fc: d035 beq.n 800736a + if (pcb->refused_data != NULL) { + 80072fe: 697b ldr r3, [r7, #20] + 8007300: 6f9b ldr r3, [r3, #120] ; 0x78 + 8007302: 2b00 cmp r3, #0 + 8007304: d009 beq.n 800731a + /* Delay this if we have refused data. */ + pcb->refused_data->flags |= PBUF_FLAG_TCP_FIN; + 8007306: 697b ldr r3, [r7, #20] + 8007308: 6f9b ldr r3, [r3, #120] ; 0x78 + 800730a: 7b5a ldrb r2, [r3, #13] + 800730c: 697b ldr r3, [r7, #20] + 800730e: 6f9b ldr r3, [r3, #120] ; 0x78 + 8007310: 2120 movs r1, #32 + 8007312: 430a orrs r2, r1 + 8007314: b2d2 uxtb r2, r2 + 8007316: 735a strb r2, [r3, #13] + 8007318: e027 b.n 800736a + } else { + /* correct rcv_wnd as the application won't call tcp_recved() + for the FIN's seqno */ + if (pcb->rcv_wnd != TCP_WND) { + 800731a: 697b ldr r3, [r7, #20] + 800731c: 8d9b ldrh r3, [r3, #44] ; 0x2c + 800731e: 4a50 ldr r2, [pc, #320] ; (8007460 ) + 8007320: 4293 cmp r3, r2 + 8007322: d005 beq.n 8007330 + pcb->rcv_wnd++; + 8007324: 697b ldr r3, [r7, #20] + 8007326: 8d9b ldrh r3, [r3, #44] ; 0x2c + 8007328: 3301 adds r3, #1 + 800732a: b29a uxth r2, r3 + 800732c: 697b ldr r3, [r7, #20] + 800732e: 859a strh r2, [r3, #44] ; 0x2c + } + TCP_EVENT_CLOSED(pcb, err); + 8007330: 697b ldr r3, [r7, #20] + 8007332: 2280 movs r2, #128 ; 0x80 + 8007334: 589b ldr r3, [r3, r2] + 8007336: 2b00 cmp r3, #0 + 8007338: d00d beq.n 8007356 + 800733a: 697b ldr r3, [r7, #20] + 800733c: 2280 movs r2, #128 ; 0x80 + 800733e: 589d ldr r5, [r3, r2] + 8007340: 697b ldr r3, [r7, #20] + 8007342: 6918 ldr r0, [r3, #16] + 8007344: 230b movs r3, #11 + 8007346: 18fc adds r4, r7, r3 + 8007348: 6979 ldr r1, [r7, #20] + 800734a: 2300 movs r3, #0 + 800734c: 2200 movs r2, #0 + 800734e: 47a8 blx r5 + 8007350: 0003 movs r3, r0 + 8007352: 7023 strb r3, [r4, #0] + 8007354: e003 b.n 800735e + 8007356: 230b movs r3, #11 + 8007358: 18fb adds r3, r7, r3 + 800735a: 2200 movs r2, #0 + 800735c: 701a strb r2, [r3, #0] + if (err == ERR_ABRT) { + 800735e: 230b movs r3, #11 + 8007360: 18fb adds r3, r7, r3 + 8007362: 781b ldrb r3, [r3, #0] + 8007364: b25b sxtb r3, r3 + 8007366: 330a adds r3, #10 + 8007368: d00d beq.n 8007386 + goto aborted; + } + } + } + + tcp_input_pcb = NULL; + 800736a: 4b3e ldr r3, [pc, #248] ; (8007464 ) + 800736c: 2200 movs r2, #0 + 800736e: 601a str r2, [r3, #0] + /* Try to send something out. */ + tcp_output(pcb); + 8007370: 697b ldr r3, [r7, #20] + 8007372: 0018 movs r0, r3 + 8007374: f002 fb4c bl 8009a10 + 8007378: e006 b.n 8007388 +#endif /* TCP_INPUT_DEBUG */ + } + } + /* Jump target if pcb has been aborted in a callback (by calling tcp_abort()). + Below this line, 'pcb' may not be dereferenced! */ +aborted: + 800737a: 46c0 nop ; (mov r8, r8) + 800737c: e004 b.n 8007388 + goto aborted; + 800737e: 46c0 nop ; (mov r8, r8) + 8007380: e002 b.n 8007388 + goto aborted; + 8007382: 46c0 nop ; (mov r8, r8) + 8007384: e000 b.n 8007388 + goto aborted; + 8007386: 46c0 nop ; (mov r8, r8) + tcp_input_pcb = NULL; + 8007388: 4b36 ldr r3, [pc, #216] ; (8007464 ) + 800738a: 2200 movs r2, #0 + 800738c: 601a str r2, [r3, #0] + recv_data = NULL; + 800738e: 4b32 ldr r3, [pc, #200] ; (8007458 ) + 8007390: 2200 movs r2, #0 + 8007392: 601a str r2, [r3, #0] + + /* give up our reference to inseg.p */ + if (inseg.p != NULL) + 8007394: 4b34 ldr r3, [pc, #208] ; (8007468 ) + 8007396: 685b ldr r3, [r3, #4] + 8007398: 2b00 cmp r3, #0 + 800739a: d058 beq.n 800744e + { + pbuf_free(inseg.p); + 800739c: 4b32 ldr r3, [pc, #200] ; (8007468 ) + 800739e: 685b ldr r3, [r3, #4] + 80073a0: 0018 movs r0, r3 + 80073a2: f7fe f97f bl 80056a4 + inseg.p = NULL; + 80073a6: 4b30 ldr r3, [pc, #192] ; (8007468 ) + 80073a8: 2200 movs r2, #0 + 80073aa: 605a str r2, [r3, #4] + pbuf_free(p); + } + + LWIP_ASSERT("tcp_input: tcp_pcbs_sane()", tcp_pcbs_sane()); + PERF_STOP("tcp_input"); + return; + 80073ac: e04f b.n 800744e + if (!(TCPH_FLAGS(tcphdr) & TCP_RST)) { + 80073ae: 4b2f ldr r3, [pc, #188] ; (800746c ) + 80073b0: 681b ldr r3, [r3, #0] + 80073b2: 7b1a ldrb r2, [r3, #12] + 80073b4: 7b5b ldrb r3, [r3, #13] + 80073b6: 021b lsls r3, r3, #8 + 80073b8: 4313 orrs r3, r2 + 80073ba: b29b uxth r3, r3 + 80073bc: 0018 movs r0, r3 + 80073be: f7fd f93f bl 8004640 + 80073c2: 0003 movs r3, r0 + 80073c4: 001a movs r2, r3 + 80073c6: 2304 movs r3, #4 + 80073c8: 4013 ands r3, r2 + 80073ca: d12e bne.n 800742a + TCP_STATS_INC(tcp.proterr); + 80073cc: 4b28 ldr r3, [pc, #160] ; (8007470 ) + 80073ce: 22a0 movs r2, #160 ; 0xa0 + 80073d0: 5a9b ldrh r3, [r3, r2] + 80073d2: 3301 adds r3, #1 + 80073d4: b299 uxth r1, r3 + 80073d6: 4b26 ldr r3, [pc, #152] ; (8007470 ) + 80073d8: 22a0 movs r2, #160 ; 0xa0 + 80073da: 5299 strh r1, [r3, r2] + TCP_STATS_INC(tcp.drop); + 80073dc: 4b24 ldr r3, [pc, #144] ; (8007470 ) + 80073de: 2296 movs r2, #150 ; 0x96 + 80073e0: 5a9b ldrh r3, [r3, r2] + 80073e2: 3301 adds r3, #1 + 80073e4: b299 uxth r1, r3 + 80073e6: 4b22 ldr r3, [pc, #136] ; (8007470 ) + 80073e8: 2296 movs r2, #150 ; 0x96 + 80073ea: 5299 strh r1, [r3, r2] + tcp_rst(ackno, seqno + tcplen, + 80073ec: 4b21 ldr r3, [pc, #132] ; (8007474 ) + 80073ee: 6818 ldr r0, [r3, #0] + 80073f0: 4b21 ldr r3, [pc, #132] ; (8007478 ) + 80073f2: 881b ldrh r3, [r3, #0] + 80073f4: 001a movs r2, r3 + 80073f6: 4b21 ldr r3, [pc, #132] ; (800747c ) + 80073f8: 681b ldr r3, [r3, #0] + 80073fa: 18d4 adds r4, r2, r3 + tcphdr->dest, tcphdr->src); + 80073fc: 4b1b ldr r3, [pc, #108] ; (800746c ) + 80073fe: 681b ldr r3, [r3, #0] + tcp_rst(ackno, seqno + tcplen, + 8007400: 789a ldrb r2, [r3, #2] + 8007402: 78db ldrb r3, [r3, #3] + 8007404: 021b lsls r3, r3, #8 + 8007406: 4313 orrs r3, r2 + 8007408: b29a uxth r2, r3 + tcphdr->dest, tcphdr->src); + 800740a: 4b18 ldr r3, [pc, #96] ; (800746c ) + 800740c: 681b ldr r3, [r3, #0] + tcp_rst(ackno, seqno + tcplen, + 800740e: 7819 ldrb r1, [r3, #0] + 8007410: 785b ldrb r3, [r3, #1] + 8007412: 021b lsls r3, r3, #8 + 8007414: 430b orrs r3, r1 + 8007416: b29b uxth r3, r3 + 8007418: 4d19 ldr r5, [pc, #100] ; (8007480 ) + 800741a: 491a ldr r1, [pc, #104] ; (8007484 ) + 800741c: 9301 str r3, [sp, #4] + 800741e: 9200 str r2, [sp, #0] + 8007420: 002b movs r3, r5 + 8007422: 000a movs r2, r1 + 8007424: 0021 movs r1, r4 + 8007426: f002 fdd1 bl 8009fcc + pbuf_free(p); + 800742a: 687b ldr r3, [r7, #4] + 800742c: 0018 movs r0, r3 + 800742e: f7fe f939 bl 80056a4 + return; + 8007432: e00c b.n 800744e +dropped: + TCP_STATS_INC(tcp.drop); + 8007434: 4b0e ldr r3, [pc, #56] ; (8007470 ) + 8007436: 2296 movs r2, #150 ; 0x96 + 8007438: 5a9b ldrh r3, [r3, r2] + 800743a: 3301 adds r3, #1 + 800743c: b299 uxth r1, r3 + 800743e: 4b0c ldr r3, [pc, #48] ; (8007470 ) + 8007440: 2296 movs r2, #150 ; 0x96 + 8007442: 5299 strh r1, [r3, r2] + snmp_inc_tcpinerrs(); + pbuf_free(p); + 8007444: 687b ldr r3, [r7, #4] + 8007446: 0018 movs r0, r3 + 8007448: f7fe f92c bl 80056a4 + 800744c: e000 b.n 8007450 + return; + 800744e: 46c0 nop ; (mov r8, r8) +} + 8007450: 46bd mov sp, r7 + 8007452: b006 add sp, #24 + 8007454: bdb0 pop {r4, r5, r7, pc} + 8007456: 46c0 nop ; (mov r8, r8) + 8007458: 200022a4 .word 0x200022a4 + 800745c: 200022a0 .word 0x200022a0 + 8007460: 000016d0 .word 0x000016d0 + 8007464: 2000328c .word 0x2000328c + 8007468: 2000227c .word 0x2000227c + 800746c: 2000228c .word 0x2000228c + 8007470: 20003158 .word 0x20003158 + 8007474: 20002298 .word 0x20002298 + 8007478: 2000229e .word 0x2000229e + 800747c: 20002294 .word 0x20002294 + 8007480: 20003294 .word 0x20003294 + 8007484: 2000329c .word 0x2000329c + +08007488 : + * @note the segment which arrived is saved in global variables, therefore only the pcb + * involved is passed as a parameter to this function + */ +static err_t +tcp_listen_input(struct tcp_pcb_listen *pcb) +{ + 8007488: b5b0 push {r4, r5, r7, lr} + 800748a: b086 sub sp, #24 + 800748c: af02 add r7, sp, #8 + 800748e: 6078 str r0, [r7, #4] + struct tcp_pcb *npcb; + err_t rc; + + if (flags & TCP_RST) { + 8007490: 4b6b ldr r3, [pc, #428] ; (8007640 ) + 8007492: 781b ldrb r3, [r3, #0] + 8007494: 001a movs r2, r3 + 8007496: 2304 movs r3, #4 + 8007498: 4013 ands r3, r2 + 800749a: d001 beq.n 80074a0 + /* An incoming RST should be ignored. Return. */ + return ERR_OK; + 800749c: 2300 movs r3, #0 + 800749e: e0cb b.n 8007638 + } + + /* In the LISTEN state, we check for incoming SYN segments, + creates a new PCB, and responds with a SYN|ACK. */ + if (flags & TCP_ACK) { + 80074a0: 4b67 ldr r3, [pc, #412] ; (8007640 ) + 80074a2: 781b ldrb r3, [r3, #0] + 80074a4: 001a movs r2, r3 + 80074a6: 2310 movs r3, #16 + 80074a8: 4013 ands r3, r2 + 80074aa: d01f beq.n 80074ec + /* For incoming segments with the ACK flag set, respond with a + RST. */ + LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_listen_input: ACK in LISTEN, sending reset\n")); + tcp_rst(ackno, seqno + tcplen, ip_current_dest_addr(), + 80074ac: 4b65 ldr r3, [pc, #404] ; (8007644 ) + 80074ae: 6818 ldr r0, [r3, #0] + 80074b0: 4b65 ldr r3, [pc, #404] ; (8007648 ) + 80074b2: 881b ldrh r3, [r3, #0] + 80074b4: 001a movs r2, r3 + 80074b6: 4b65 ldr r3, [pc, #404] ; (800764c ) + 80074b8: 681b ldr r3, [r3, #0] + 80074ba: 18d4 adds r4, r2, r3 + ip_current_src_addr(), tcphdr->dest, tcphdr->src); + 80074bc: 4b64 ldr r3, [pc, #400] ; (8007650 ) + 80074be: 681b ldr r3, [r3, #0] + tcp_rst(ackno, seqno + tcplen, ip_current_dest_addr(), + 80074c0: 789a ldrb r2, [r3, #2] + 80074c2: 78db ldrb r3, [r3, #3] + 80074c4: 021b lsls r3, r3, #8 + 80074c6: 4313 orrs r3, r2 + 80074c8: b29a uxth r2, r3 + ip_current_src_addr(), tcphdr->dest, tcphdr->src); + 80074ca: 4b61 ldr r3, [pc, #388] ; (8007650 ) + 80074cc: 681b ldr r3, [r3, #0] + tcp_rst(ackno, seqno + tcplen, ip_current_dest_addr(), + 80074ce: 7819 ldrb r1, [r3, #0] + 80074d0: 785b ldrb r3, [r3, #1] + 80074d2: 021b lsls r3, r3, #8 + 80074d4: 430b orrs r3, r1 + 80074d6: b29b uxth r3, r3 + 80074d8: 4d5e ldr r5, [pc, #376] ; (8007654 ) + 80074da: 495f ldr r1, [pc, #380] ; (8007658 ) + 80074dc: 9301 str r3, [sp, #4] + 80074de: 9200 str r2, [sp, #0] + 80074e0: 002b movs r3, r5 + 80074e2: 000a movs r2, r1 + 80074e4: 0021 movs r1, r4 + 80074e6: f002 fd71 bl 8009fcc + 80074ea: e0a4 b.n 8007636 + } else if (flags & TCP_SYN) { + 80074ec: 4b54 ldr r3, [pc, #336] ; (8007640 ) + 80074ee: 781b ldrb r3, [r3, #0] + 80074f0: 001a movs r2, r3 + 80074f2: 2302 movs r3, #2 + 80074f4: 4013 ands r3, r2 + 80074f6: d100 bne.n 80074fa + 80074f8: e09d b.n 8007636 + if (pcb->accepts_pending >= pcb->backlog) { + LWIP_DEBUGF(TCP_DEBUG, ("tcp_listen_input: listen backlog exceeded for port %"U16_F"\n", tcphdr->dest)); + return ERR_ABRT; + } +#endif /* TCP_LISTEN_BACKLOG */ + npcb = tcp_alloc(pcb->prio); + 80074fa: 687b ldr r3, [r7, #4] + 80074fc: 7e5b ldrb r3, [r3, #25] + 80074fe: 0018 movs r0, r3 + 8007500: f7ff f9e6 bl 80068d0 + 8007504: 0003 movs r3, r0 + 8007506: 60fb str r3, [r7, #12] + /* If a new PCB could not be created (probably due to lack of memory), + we don't do anything, but rely on the sender will retransmit the + SYN at a time when we have more memory available. */ + if (npcb == NULL) { + 8007508: 68fb ldr r3, [r7, #12] + 800750a: 2b00 cmp r3, #0 + 800750c: d10a bne.n 8007524 + LWIP_DEBUGF(TCP_DEBUG, ("tcp_listen_input: could not allocate PCB\n")); + TCP_STATS_INC(tcp.memerr); + 800750e: 4b53 ldr r3, [pc, #332] ; (800765c ) + 8007510: 229c movs r2, #156 ; 0x9c + 8007512: 5a9b ldrh r3, [r3, r2] + 8007514: 3301 adds r3, #1 + 8007516: b299 uxth r1, r3 + 8007518: 4b50 ldr r3, [pc, #320] ; (800765c ) + 800751a: 229c movs r2, #156 ; 0x9c + 800751c: 5299 strh r1, [r3, r2] + return ERR_MEM; + 800751e: 2301 movs r3, #1 + 8007520: 425b negs r3, r3 + 8007522: e089 b.n 8007638 + } +#if TCP_LISTEN_BACKLOG + pcb->accepts_pending++; +#endif /* TCP_LISTEN_BACKLOG */ + /* Set up the new PCB. */ + ip_addr_copy(npcb->local_ip, current_iphdr_dest); + 8007524: 4b4c ldr r3, [pc, #304] ; (8007658 ) + 8007526: 681a ldr r2, [r3, #0] + 8007528: 68fb ldr r3, [r7, #12] + 800752a: 601a str r2, [r3, #0] + npcb->local_port = pcb->local_port; + 800752c: 687b ldr r3, [r7, #4] + 800752e: 8b5a ldrh r2, [r3, #26] + 8007530: 68fb ldr r3, [r7, #12] + 8007532: 835a strh r2, [r3, #26] + ip_addr_copy(npcb->remote_ip, current_iphdr_src); + 8007534: 4b47 ldr r3, [pc, #284] ; (8007654 ) + 8007536: 681a ldr r2, [r3, #0] + 8007538: 68fb ldr r3, [r7, #12] + 800753a: 605a str r2, [r3, #4] + npcb->remote_port = tcphdr->src; + 800753c: 4b44 ldr r3, [pc, #272] ; (8007650 ) + 800753e: 681b ldr r3, [r3, #0] + 8007540: 781a ldrb r2, [r3, #0] + 8007542: 785b ldrb r3, [r3, #1] + 8007544: 021b lsls r3, r3, #8 + 8007546: 4313 orrs r3, r2 + 8007548: b29a uxth r2, r3 + 800754a: 68fb ldr r3, [r7, #12] + 800754c: 839a strh r2, [r3, #28] + npcb->state = SYN_RCVD; + 800754e: 68fb ldr r3, [r7, #12] + 8007550: 2203 movs r2, #3 + 8007552: 761a strb r2, [r3, #24] + npcb->rcv_nxt = seqno + 1; + 8007554: 4b3d ldr r3, [pc, #244] ; (800764c ) + 8007556: 681b ldr r3, [r3, #0] + 8007558: 1c5a adds r2, r3, #1 + 800755a: 68fb ldr r3, [r7, #12] + 800755c: 629a str r2, [r3, #40] ; 0x28 + npcb->rcv_ann_right_edge = npcb->rcv_nxt; + 800755e: 68fb ldr r3, [r7, #12] + 8007560: 6a9a ldr r2, [r3, #40] ; 0x28 + 8007562: 68fb ldr r3, [r7, #12] + 8007564: 631a str r2, [r3, #48] ; 0x30 + npcb->snd_wnd = tcphdr->wnd; + 8007566: 4b3a ldr r3, [pc, #232] ; (8007650 ) + 8007568: 681b ldr r3, [r3, #0] + 800756a: 7b9a ldrb r2, [r3, #14] + 800756c: 7bdb ldrb r3, [r3, #15] + 800756e: 021b lsls r3, r3, #8 + 8007570: 4313 orrs r3, r2 + 8007572: b299 uxth r1, r3 + 8007574: 68fb ldr r3, [r7, #12] + 8007576: 2260 movs r2, #96 ; 0x60 + 8007578: 5299 strh r1, [r3, r2] + npcb->snd_wnd_max = tcphdr->wnd; + 800757a: 4b35 ldr r3, [pc, #212] ; (8007650 ) + 800757c: 681b ldr r3, [r3, #0] + 800757e: 7b9a ldrb r2, [r3, #14] + 8007580: 7bdb ldrb r3, [r3, #15] + 8007582: 021b lsls r3, r3, #8 + 8007584: 4313 orrs r3, r2 + 8007586: b299 uxth r1, r3 + 8007588: 68fb ldr r3, [r7, #12] + 800758a: 2262 movs r2, #98 ; 0x62 + 800758c: 5299 strh r1, [r3, r2] + npcb->ssthresh = npcb->snd_wnd; + 800758e: 68fb ldr r3, [r7, #12] + 8007590: 2260 movs r2, #96 ; 0x60 + 8007592: 5a99 ldrh r1, [r3, r2] + 8007594: 68fb ldr r3, [r7, #12] + 8007596: 224e movs r2, #78 ; 0x4e + 8007598: 5299 strh r1, [r3, r2] + npcb->snd_wl1 = seqno - 1;/* initialise to seqno-1 to force window update */ + 800759a: 4b2c ldr r3, [pc, #176] ; (800764c ) + 800759c: 681b ldr r3, [r3, #0] + 800759e: 1e5a subs r2, r3, #1 + 80075a0: 68fb ldr r3, [r7, #12] + 80075a2: 655a str r2, [r3, #84] ; 0x54 + npcb->callback_arg = pcb->callback_arg; + 80075a4: 687b ldr r3, [r7, #4] + 80075a6: 691a ldr r2, [r3, #16] + 80075a8: 68fb ldr r3, [r7, #12] + 80075aa: 611a str r2, [r3, #16] +#if LWIP_CALLBACK_API + npcb->accept = pcb->accept; + 80075ac: 687b ldr r3, [r7, #4] + 80075ae: 695a ldr r2, [r3, #20] + 80075b0: 68fb ldr r3, [r7, #12] + 80075b2: 615a str r2, [r3, #20] +#endif /* LWIP_CALLBACK_API */ + /* inherit socket options */ + npcb->so_options = pcb->so_options & SOF_INHERITED; + 80075b4: 687b ldr r3, [r7, #4] + 80075b6: 7a1b ldrb r3, [r3, #8] + 80075b8: 2273 movs r2, #115 ; 0x73 + 80075ba: 4393 bics r3, r2 + 80075bc: b2da uxtb r2, r3 + 80075be: 68fb ldr r3, [r7, #12] + 80075c0: 721a strb r2, [r3, #8] + /* Register the new PCB so that we can begin receiving segments + for it. */ + TCP_REG_ACTIVE(npcb); + 80075c2: 4b27 ldr r3, [pc, #156] ; (8007660 ) + 80075c4: 681a ldr r2, [r3, #0] + 80075c6: 68fb ldr r3, [r7, #12] + 80075c8: 60da str r2, [r3, #12] + 80075ca: 4b25 ldr r3, [pc, #148] ; (8007660 ) + 80075cc: 68fa ldr r2, [r7, #12] + 80075ce: 601a str r2, [r3, #0] + 80075d0: f003 f850 bl 800a674 + 80075d4: 4b23 ldr r3, [pc, #140] ; (8007664 ) + 80075d6: 2201 movs r2, #1 + 80075d8: 701a strb r2, [r3, #0] + + /* Parse any options in the SYN. */ + tcp_parseopt(npcb); + 80075da: 68fb ldr r3, [r7, #12] + 80075dc: 0018 movs r0, r3 + 80075de: f001 fdab bl 8009138 +#if TCP_CALCULATE_EFF_SEND_MSS + npcb->mss = tcp_eff_send_mss(npcb->mss, &(npcb->remote_ip)); + 80075e2: 68fb ldr r3, [r7, #12] + 80075e4: 8eda ldrh r2, [r3, #54] ; 0x36 + 80075e6: 68fb ldr r3, [r7, #12] + 80075e8: 3304 adds r3, #4 + 80075ea: 0019 movs r1, r3 + 80075ec: 0010 movs r0, r2 + 80075ee: f7ff fac3 bl 8006b78 + 80075f2: 0003 movs r3, r0 + 80075f4: 001a movs r2, r3 + 80075f6: 68fb ldr r3, [r7, #12] + 80075f8: 86da strh r2, [r3, #54] ; 0x36 +#endif /* TCP_CALCULATE_EFF_SEND_MSS */ + + snmp_inc_tcppassiveopens(); + + /* Send a SYN|ACK together with the MSS option. */ + rc = tcp_enqueue_flags(npcb, TCP_SYN | TCP_ACK); + 80075fa: 250b movs r5, #11 + 80075fc: 197c adds r4, r7, r5 + 80075fe: 68fb ldr r3, [r7, #12] + 8007600: 2112 movs r1, #18 + 8007602: 0018 movs r0, r3 + 8007604: f002 f8aa bl 800975c + 8007608: 0003 movs r3, r0 + 800760a: 7023 strb r3, [r4, #0] + if (rc != ERR_OK) { + 800760c: 197b adds r3, r7, r5 + 800760e: 781b ldrb r3, [r3, #0] + 8007610: b25b sxtb r3, r3 + 8007612: 2b00 cmp r3, #0 + 8007614: d009 beq.n 800762a + tcp_abandon(npcb, 0); + 8007616: 68fb ldr r3, [r7, #12] + 8007618: 2100 movs r1, #0 + 800761a: 0018 movs r0, r3 + 800761c: f7fe fc3e bl 8005e9c + return rc; + 8007620: 230b movs r3, #11 + 8007622: 18fb adds r3, r7, r3 + 8007624: 781b ldrb r3, [r3, #0] + 8007626: b25b sxtb r3, r3 + 8007628: e006 b.n 8007638 + } + return tcp_output(npcb); + 800762a: 68fb ldr r3, [r7, #12] + 800762c: 0018 movs r0, r3 + 800762e: f002 f9ef bl 8009a10 + 8007632: 0003 movs r3, r0 + 8007634: e000 b.n 8007638 + } + return ERR_OK; + 8007636: 2300 movs r3, #0 +} + 8007638: 0018 movs r0, r3 + 800763a: 46bd mov sp, r7 + 800763c: b004 add sp, #16 + 800763e: bdb0 pop {r4, r5, r7, pc} + 8007640: 2000229c .word 0x2000229c + 8007644: 20002298 .word 0x20002298 + 8007648: 2000229e .word 0x2000229e + 800764c: 20002294 .word 0x20002294 + 8007650: 2000228c .word 0x2000228c + 8007654: 20003294 .word 0x20003294 + 8007658: 2000329c .word 0x2000329c + 800765c: 20003158 .word 0x20003158 + 8007660: 20003274 .word 0x20003274 + 8007664: 20003270 .word 0x20003270 + +08007668 : + * @note the segment which arrived is saved in global variables, therefore only the pcb + * involved is passed as a parameter to this function + */ +static err_t +tcp_timewait_input(struct tcp_pcb *pcb) +{ + 8007668: b5b0 push {r4, r5, r7, lr} + 800766a: b084 sub sp, #16 + 800766c: af02 add r7, sp, #8 + 800766e: 6078 str r0, [r7, #4] + /* RFC 1337: in TIME_WAIT, ignore RST and ACK FINs + any 'acceptable' segments */ + /* RFC 793 3.9 Event Processing - Segment Arrives: + * - first check sequence number - we skip that one in TIME_WAIT (always + * acceptable since we only send ACKs) + * - second check the RST bit (... return) */ + if (flags & TCP_RST) { + 8007670: 4b2f ldr r3, [pc, #188] ; (8007730 ) + 8007672: 781b ldrb r3, [r3, #0] + 8007674: 001a movs r2, r3 + 8007676: 2304 movs r3, #4 + 8007678: 4013 ands r3, r2 + 800767a: d001 beq.n 8007680 + return ERR_OK; + 800767c: 2300 movs r3, #0 + 800767e: e052 b.n 8007726 + } + /* - fourth, check the SYN bit, */ + if (flags & TCP_SYN) { + 8007680: 4b2b ldr r3, [pc, #172] ; (8007730 ) + 8007682: 781b ldrb r3, [r3, #0] + 8007684: 001a movs r2, r3 + 8007686: 2302 movs r3, #2 + 8007688: 4013 ands r3, r2 + 800768a: d030 beq.n 80076ee + /* If an incoming segment is not acceptable, an acknowledgment + should be sent in reply */ + if (TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt, pcb->rcv_nxt+pcb->rcv_wnd)) { + 800768c: 4b29 ldr r3, [pc, #164] ; (8007734 ) + 800768e: 681a ldr r2, [r3, #0] + 8007690: 687b ldr r3, [r7, #4] + 8007692: 6a9b ldr r3, [r3, #40] ; 0x28 + 8007694: 1ad3 subs r3, r2, r3 + 8007696: d434 bmi.n 8007702 + 8007698: 4b26 ldr r3, [pc, #152] ; (8007734 ) + 800769a: 681a ldr r2, [r3, #0] + 800769c: 687b ldr r3, [r7, #4] + 800769e: 6a9b ldr r3, [r3, #40] ; 0x28 + 80076a0: 6879 ldr r1, [r7, #4] + 80076a2: 8d89 ldrh r1, [r1, #44] ; 0x2c + 80076a4: 185b adds r3, r3, r1 + 80076a6: 1ad3 subs r3, r2, r3 + 80076a8: 2b00 cmp r3, #0 + 80076aa: dc2a bgt.n 8007702 + /* If the SYN is in the window it is an error, send a reset */ + tcp_rst(ackno, seqno + tcplen, ip_current_dest_addr(), ip_current_src_addr(), + 80076ac: 4b22 ldr r3, [pc, #136] ; (8007738 ) + 80076ae: 6818 ldr r0, [r3, #0] + 80076b0: 4b22 ldr r3, [pc, #136] ; (800773c ) + 80076b2: 881b ldrh r3, [r3, #0] + 80076b4: 001a movs r2, r3 + 80076b6: 4b1f ldr r3, [pc, #124] ; (8007734 ) + 80076b8: 681b ldr r3, [r3, #0] + 80076ba: 18d4 adds r4, r2, r3 + tcphdr->dest, tcphdr->src); + 80076bc: 4b20 ldr r3, [pc, #128] ; (8007740 ) + 80076be: 681b ldr r3, [r3, #0] + tcp_rst(ackno, seqno + tcplen, ip_current_dest_addr(), ip_current_src_addr(), + 80076c0: 789a ldrb r2, [r3, #2] + 80076c2: 78db ldrb r3, [r3, #3] + 80076c4: 021b lsls r3, r3, #8 + 80076c6: 4313 orrs r3, r2 + 80076c8: b29a uxth r2, r3 + tcphdr->dest, tcphdr->src); + 80076ca: 4b1d ldr r3, [pc, #116] ; (8007740 ) + 80076cc: 681b ldr r3, [r3, #0] + tcp_rst(ackno, seqno + tcplen, ip_current_dest_addr(), ip_current_src_addr(), + 80076ce: 7819 ldrb r1, [r3, #0] + 80076d0: 785b ldrb r3, [r3, #1] + 80076d2: 021b lsls r3, r3, #8 + 80076d4: 430b orrs r3, r1 + 80076d6: b29b uxth r3, r3 + 80076d8: 4d1a ldr r5, [pc, #104] ; (8007744 ) + 80076da: 491b ldr r1, [pc, #108] ; (8007748 ) + 80076dc: 9301 str r3, [sp, #4] + 80076de: 9200 str r2, [sp, #0] + 80076e0: 002b movs r3, r5 + 80076e2: 000a movs r2, r1 + 80076e4: 0021 movs r1, r4 + 80076e6: f002 fc71 bl 8009fcc + return ERR_OK; + 80076ea: 2300 movs r3, #0 + 80076ec: e01b b.n 8007726 + } + } else if (flags & TCP_FIN) { + 80076ee: 4b10 ldr r3, [pc, #64] ; (8007730 ) + 80076f0: 781b ldrb r3, [r3, #0] + 80076f2: 001a movs r2, r3 + 80076f4: 2301 movs r3, #1 + 80076f6: 4013 ands r3, r2 + 80076f8: d003 beq.n 8007702 + /* - eighth, check the FIN bit: Remain in the TIME-WAIT state. + Restart the 2 MSL time-wait timeout.*/ + pcb->tmr = tcp_ticks; + 80076fa: 4b14 ldr r3, [pc, #80] ; (800774c ) + 80076fc: 681a ldr r2, [r3, #0] + 80076fe: 687b ldr r3, [r7, #4] + 8007700: 625a str r2, [r3, #36] ; 0x24 + } + + if ((tcplen > 0)) { + 8007702: 4b0e ldr r3, [pc, #56] ; (800773c ) + 8007704: 881b ldrh r3, [r3, #0] + 8007706: 2b00 cmp r3, #0 + 8007708: d00c beq.n 8007724 + /* Acknowledge data, FIN or out-of-window SYN */ + pcb->flags |= TF_ACK_NOW; + 800770a: 687b ldr r3, [r7, #4] + 800770c: 7f9b ldrb r3, [r3, #30] + 800770e: 2202 movs r2, #2 + 8007710: 4313 orrs r3, r2 + 8007712: b2da uxtb r2, r3 + 8007714: 687b ldr r3, [r7, #4] + 8007716: 779a strb r2, [r3, #30] + return tcp_output(pcb); + 8007718: 687b ldr r3, [r7, #4] + 800771a: 0018 movs r0, r3 + 800771c: f002 f978 bl 8009a10 + 8007720: 0003 movs r3, r0 + 8007722: e000 b.n 8007726 + } + return ERR_OK; + 8007724: 2300 movs r3, #0 +} + 8007726: 0018 movs r0, r3 + 8007728: 46bd mov sp, r7 + 800772a: b002 add sp, #8 + 800772c: bdb0 pop {r4, r5, r7, pc} + 800772e: 46c0 nop ; (mov r8, r8) + 8007730: 2000229c .word 0x2000229c + 8007734: 20002294 .word 0x20002294 + 8007738: 20002298 .word 0x20002298 + 800773c: 2000229e .word 0x2000229e + 8007740: 2000228c .word 0x2000228c + 8007744: 20003294 .word 0x20003294 + 8007748: 2000329c .word 0x2000329c + 800774c: 20003278 .word 0x20003278 + +08007750 : + * @note the segment which arrived is saved in global variables, therefore only the pcb + * involved is passed as a parameter to this function + */ +static err_t +tcp_process(struct tcp_pcb *pcb) +{ + 8007750: b5b0 push {r4, r5, r7, lr} + 8007752: b086 sub sp, #24 + 8007754: af02 add r7, sp, #8 + 8007756: 6078 str r0, [r7, #4] + struct tcp_seg *rseg; + u8_t acceptable = 0; + 8007758: 230f movs r3, #15 + 800775a: 18fb adds r3, r7, r3 + 800775c: 2200 movs r2, #0 + 800775e: 701a strb r2, [r3, #0] + err_t err; + + err = ERR_OK; + 8007760: 230e movs r3, #14 + 8007762: 18fb adds r3, r7, r3 + 8007764: 2200 movs r2, #0 + 8007766: 701a strb r2, [r3, #0] + + /* Process incoming RST segments. */ + if (flags & TCP_RST) { + 8007768: 4bd1 ldr r3, [pc, #836] ; (8007ab0 ) + 800776a: 781b ldrb r3, [r3, #0] + 800776c: 001a movs r2, r3 + 800776e: 2304 movs r3, #4 + 8007770: 4013 ands r3, r2 + 8007772: d03a beq.n 80077ea + /* First, determine if the reset is acceptable. */ + if (pcb->state == SYN_SENT) { + 8007774: 687b ldr r3, [r7, #4] + 8007776: 7e1b ldrb r3, [r3, #24] + 8007778: 2b02 cmp r3, #2 + 800777a: d10a bne.n 8007792 + if (ackno == pcb->snd_nxt) { + 800777c: 687b ldr r3, [r7, #4] + 800777e: 6d1a ldr r2, [r3, #80] ; 0x50 + 8007780: 4bcc ldr r3, [pc, #816] ; (8007ab4 ) + 8007782: 681b ldr r3, [r3, #0] + 8007784: 429a cmp r2, r3 + 8007786: d118 bne.n 80077ba + acceptable = 1; + 8007788: 230f movs r3, #15 + 800778a: 18fb adds r3, r7, r3 + 800778c: 2201 movs r2, #1 + 800778e: 701a strb r2, [r3, #0] + 8007790: e013 b.n 80077ba + } + } else { + if (TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt, + 8007792: 4bc9 ldr r3, [pc, #804] ; (8007ab8 ) + 8007794: 681a ldr r2, [r3, #0] + 8007796: 687b ldr r3, [r7, #4] + 8007798: 6a9b ldr r3, [r3, #40] ; 0x28 + 800779a: 1ad3 subs r3, r2, r3 + 800779c: d40d bmi.n 80077ba + 800779e: 4bc6 ldr r3, [pc, #792] ; (8007ab8 ) + 80077a0: 681a ldr r2, [r3, #0] + 80077a2: 687b ldr r3, [r7, #4] + 80077a4: 6a9b ldr r3, [r3, #40] ; 0x28 + 80077a6: 6879 ldr r1, [r7, #4] + 80077a8: 8d89 ldrh r1, [r1, #44] ; 0x2c + 80077aa: 185b adds r3, r3, r1 + 80077ac: 1ad3 subs r3, r2, r3 + 80077ae: 2b00 cmp r3, #0 + 80077b0: dc03 bgt.n 80077ba + pcb->rcv_nxt+pcb->rcv_wnd)) { + acceptable = 1; + 80077b2: 230f movs r3, #15 + 80077b4: 18fb adds r3, r7, r3 + 80077b6: 2201 movs r2, #1 + 80077b8: 701a strb r2, [r3, #0] + } + } + + if (acceptable) { + 80077ba: 230f movs r3, #15 + 80077bc: 18fb adds r3, r7, r3 + 80077be: 781b ldrb r3, [r3, #0] + 80077c0: 2b00 cmp r3, #0 + 80077c2: d010 beq.n 80077e6 + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_process: Connection RESET\n")); + LWIP_ASSERT("tcp_input: pcb->state != CLOSED", pcb->state != CLOSED); + recv_flags |= TF_RESET; + 80077c4: 4bbd ldr r3, [pc, #756] ; (8007abc ) + 80077c6: 781b ldrb r3, [r3, #0] + 80077c8: 2208 movs r2, #8 + 80077ca: 4313 orrs r3, r2 + 80077cc: b2da uxtb r2, r3 + 80077ce: 4bbb ldr r3, [pc, #748] ; (8007abc ) + 80077d0: 701a strb r2, [r3, #0] + pcb->flags &= ~TF_ACK_DELAY; + 80077d2: 687b ldr r3, [r7, #4] + 80077d4: 7f9b ldrb r3, [r3, #30] + 80077d6: 2201 movs r2, #1 + 80077d8: 4393 bics r3, r2 + 80077da: b2da uxtb r2, r3 + 80077dc: 687b ldr r3, [r7, #4] + 80077de: 779a strb r2, [r3, #30] + return ERR_RST; + 80077e0: 230b movs r3, #11 + 80077e2: 425b negs r3, r3 + 80077e4: e333 b.n 8007e4e + } else { + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_process: unacceptable reset seqno %"U32_F" rcv_nxt %"U32_F"\n", + seqno, pcb->rcv_nxt)); + LWIP_DEBUGF(TCP_DEBUG, ("tcp_process: unacceptable reset seqno %"U32_F" rcv_nxt %"U32_F"\n", + seqno, pcb->rcv_nxt)); + return ERR_OK; + 80077e6: 2300 movs r3, #0 + 80077e8: e331 b.n 8007e4e + } + } + + if ((flags & TCP_SYN) && (pcb->state != SYN_SENT && pcb->state != SYN_RCVD)) { + 80077ea: 4bb1 ldr r3, [pc, #708] ; (8007ab0 ) + 80077ec: 781b ldrb r3, [r3, #0] + 80077ee: 001a movs r2, r3 + 80077f0: 2302 movs r3, #2 + 80077f2: 4013 ands r3, r2 + 80077f4: d010 beq.n 8007818 + 80077f6: 687b ldr r3, [r7, #4] + 80077f8: 7e1b ldrb r3, [r3, #24] + 80077fa: 2b02 cmp r3, #2 + 80077fc: d00c beq.n 8007818 + 80077fe: 687b ldr r3, [r7, #4] + 8007800: 7e1b ldrb r3, [r3, #24] + 8007802: 2b03 cmp r3, #3 + 8007804: d008 beq.n 8007818 + /* Cope with new connection attempt after remote end crashed */ + tcp_ack_now(pcb); + 8007806: 687b ldr r3, [r7, #4] + 8007808: 7f9b ldrb r3, [r3, #30] + 800780a: 2202 movs r2, #2 + 800780c: 4313 orrs r3, r2 + 800780e: b2da uxtb r2, r3 + 8007810: 687b ldr r3, [r7, #4] + 8007812: 779a strb r2, [r3, #30] + return ERR_OK; + 8007814: 2300 movs r3, #0 + 8007816: e31a b.n 8007e4e + } + + if ((pcb->flags & TF_RXCLOSED) == 0) { + 8007818: 687b ldr r3, [r7, #4] + 800781a: 7f9b ldrb r3, [r3, #30] + 800781c: 001a movs r2, r3 + 800781e: 2310 movs r3, #16 + 8007820: 4013 ands r3, r2 + 8007822: d103 bne.n 800782c + /* Update the PCB (in)activity timer unless rx is closed (see tcp_shutdown) */ + pcb->tmr = tcp_ticks; + 8007824: 4ba6 ldr r3, [pc, #664] ; (8007ac0 ) + 8007826: 681a ldr r2, [r3, #0] + 8007828: 687b ldr r3, [r7, #4] + 800782a: 625a str r2, [r3, #36] ; 0x24 + } + pcb->keep_cnt_sent = 0; + 800782c: 687b ldr r3, [r7, #4] + 800782e: 2296 movs r2, #150 ; 0x96 + 8007830: 2100 movs r1, #0 + 8007832: 5499 strb r1, [r3, r2] + + tcp_parseopt(pcb); + 8007834: 687b ldr r3, [r7, #4] + 8007836: 0018 movs r0, r3 + 8007838: f001 fc7e bl 8009138 + + /* Do different things depending on the TCP state. */ + switch (pcb->state) { + 800783c: 687b ldr r3, [r7, #4] + 800783e: 7e1b ldrb r3, [r3, #24] + 8007840: 2b09 cmp r3, #9 + 8007842: d900 bls.n 8007846 + 8007844: e2f3 b.n 8007e2e + 8007846: 009a lsls r2, r3, #2 + 8007848: 4b9e ldr r3, [pc, #632] ; (8007ac4 ) + 800784a: 18d3 adds r3, r2, r3 + 800784c: 681b ldr r3, [r3, #0] + 800784e: 469f mov pc, r3 + case SYN_SENT: + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("SYN-SENT: ackno %"U32_F" pcb->snd_nxt %"U32_F" unacked %"U32_F"\n", ackno, + pcb->snd_nxt, ntohl(pcb->unacked->tcphdr->seqno))); + /* received SYN ACK with expected sequence number? */ + if ((flags & TCP_ACK) && (flags & TCP_SYN) + 8007850: 4b97 ldr r3, [pc, #604] ; (8007ab0 ) + 8007852: 781b ldrb r3, [r3, #0] + 8007854: 001a movs r2, r3 + 8007856: 2310 movs r3, #16 + 8007858: 4013 ands r3, r2 + 800785a: d100 bne.n 800785e + 800785c: e0be b.n 80079dc + 800785e: 4b94 ldr r3, [pc, #592] ; (8007ab0 ) + 8007860: 781b ldrb r3, [r3, #0] + 8007862: 001a movs r2, r3 + 8007864: 2302 movs r3, #2 + 8007866: 4013 ands r3, r2 + 8007868: d100 bne.n 800786c + 800786a: e0b7 b.n 80079dc + && ackno == ntohl(pcb->unacked->tcphdr->seqno) + 1) { + 800786c: 687b ldr r3, [r7, #4] + 800786e: 6f1b ldr r3, [r3, #112] ; 0x70 + 8007870: 68db ldr r3, [r3, #12] + 8007872: 791a ldrb r2, [r3, #4] + 8007874: 7959 ldrb r1, [r3, #5] + 8007876: 0209 lsls r1, r1, #8 + 8007878: 430a orrs r2, r1 + 800787a: 7999 ldrb r1, [r3, #6] + 800787c: 0409 lsls r1, r1, #16 + 800787e: 430a orrs r2, r1 + 8007880: 79db ldrb r3, [r3, #7] + 8007882: 061b lsls r3, r3, #24 + 8007884: 4313 orrs r3, r2 + 8007886: 0018 movs r0, r3 + 8007888: f7fc ff03 bl 8004692 + 800788c: 0003 movs r3, r0 + 800788e: 1c5a adds r2, r3, #1 + 8007890: 4b88 ldr r3, [pc, #544] ; (8007ab4 ) + 8007892: 681b ldr r3, [r3, #0] + 8007894: 429a cmp r2, r3 + 8007896: d000 beq.n 800789a + 8007898: e0a0 b.n 80079dc + pcb->snd_buf++; + 800789a: 687b ldr r3, [r7, #4] + 800789c: 2266 movs r2, #102 ; 0x66 + 800789e: 5a9b ldrh r3, [r3, r2] + 80078a0: 3301 adds r3, #1 + 80078a2: b299 uxth r1, r3 + 80078a4: 687b ldr r3, [r7, #4] + 80078a6: 2266 movs r2, #102 ; 0x66 + 80078a8: 5299 strh r1, [r3, r2] + pcb->rcv_nxt = seqno + 1; + 80078aa: 4b83 ldr r3, [pc, #524] ; (8007ab8 ) + 80078ac: 681b ldr r3, [r3, #0] + 80078ae: 1c5a adds r2, r3, #1 + 80078b0: 687b ldr r3, [r7, #4] + 80078b2: 629a str r2, [r3, #40] ; 0x28 + pcb->rcv_ann_right_edge = pcb->rcv_nxt; + 80078b4: 687b ldr r3, [r7, #4] + 80078b6: 6a9a ldr r2, [r3, #40] ; 0x28 + 80078b8: 687b ldr r3, [r7, #4] + 80078ba: 631a str r2, [r3, #48] ; 0x30 + pcb->lastack = ackno; + 80078bc: 4b7d ldr r3, [pc, #500] ; (8007ab4 ) + 80078be: 681a ldr r2, [r3, #0] + 80078c0: 687b ldr r3, [r7, #4] + 80078c2: 649a str r2, [r3, #72] ; 0x48 + pcb->snd_wnd = tcphdr->wnd; + 80078c4: 4b80 ldr r3, [pc, #512] ; (8007ac8 ) + 80078c6: 681b ldr r3, [r3, #0] + 80078c8: 7b9a ldrb r2, [r3, #14] + 80078ca: 7bdb ldrb r3, [r3, #15] + 80078cc: 021b lsls r3, r3, #8 + 80078ce: 4313 orrs r3, r2 + 80078d0: b299 uxth r1, r3 + 80078d2: 687b ldr r3, [r7, #4] + 80078d4: 2260 movs r2, #96 ; 0x60 + 80078d6: 5299 strh r1, [r3, r2] + pcb->snd_wnd_max = tcphdr->wnd; + 80078d8: 4b7b ldr r3, [pc, #492] ; (8007ac8 ) + 80078da: 681b ldr r3, [r3, #0] + 80078dc: 7b9a ldrb r2, [r3, #14] + 80078de: 7bdb ldrb r3, [r3, #15] + 80078e0: 021b lsls r3, r3, #8 + 80078e2: 4313 orrs r3, r2 + 80078e4: b299 uxth r1, r3 + 80078e6: 687b ldr r3, [r7, #4] + 80078e8: 2262 movs r2, #98 ; 0x62 + 80078ea: 5299 strh r1, [r3, r2] + pcb->snd_wl1 = seqno - 1; /* initialise to seqno - 1 to force window update */ + 80078ec: 4b72 ldr r3, [pc, #456] ; (8007ab8 ) + 80078ee: 681b ldr r3, [r3, #0] + 80078f0: 1e5a subs r2, r3, #1 + 80078f2: 687b ldr r3, [r7, #4] + 80078f4: 655a str r2, [r3, #84] ; 0x54 + pcb->state = ESTABLISHED; + 80078f6: 687b ldr r3, [r7, #4] + 80078f8: 2204 movs r2, #4 + 80078fa: 761a strb r2, [r3, #24] + +#if TCP_CALCULATE_EFF_SEND_MSS + pcb->mss = tcp_eff_send_mss(pcb->mss, &(pcb->remote_ip)); + 80078fc: 687b ldr r3, [r7, #4] + 80078fe: 8eda ldrh r2, [r3, #54] ; 0x36 + 8007900: 687b ldr r3, [r7, #4] + 8007902: 3304 adds r3, #4 + 8007904: 0019 movs r1, r3 + 8007906: 0010 movs r0, r2 + 8007908: f7ff f936 bl 8006b78 + 800790c: 0003 movs r3, r0 + 800790e: 001a movs r2, r3 + 8007910: 687b ldr r3, [r7, #4] + 8007912: 86da strh r2, [r3, #54] ; 0x36 +#endif /* TCP_CALCULATE_EFF_SEND_MSS */ + + /* Set ssthresh again after changing pcb->mss (already set in tcp_connect + * but for the default value of pcb->mss) */ + pcb->ssthresh = pcb->mss * 10; + 8007914: 687b ldr r3, [r7, #4] + 8007916: 8edb ldrh r3, [r3, #54] ; 0x36 + 8007918: 1c1a adds r2, r3, #0 + 800791a: 0092 lsls r2, r2, #2 + 800791c: 18d3 adds r3, r2, r3 + 800791e: 18db adds r3, r3, r3 + 8007920: b299 uxth r1, r3 + 8007922: 687b ldr r3, [r7, #4] + 8007924: 224e movs r2, #78 ; 0x4e + 8007926: 5299 strh r1, [r3, r2] + + pcb->cwnd = ((pcb->cwnd == 1) ? (pcb->mss * 2) : pcb->mss); + 8007928: 687b ldr r3, [r7, #4] + 800792a: 224c movs r2, #76 ; 0x4c + 800792c: 5a9b ldrh r3, [r3, r2] + 800792e: 2b01 cmp r3, #1 + 8007930: d104 bne.n 800793c + 8007932: 687b ldr r3, [r7, #4] + 8007934: 8edb ldrh r3, [r3, #54] ; 0x36 + 8007936: 18db adds r3, r3, r3 + 8007938: b29b uxth r3, r3 + 800793a: e001 b.n 8007940 + 800793c: 687b ldr r3, [r7, #4] + 800793e: 8edb ldrh r3, [r3, #54] ; 0x36 + 8007940: 687a ldr r2, [r7, #4] + 8007942: 214c movs r1, #76 ; 0x4c + 8007944: 5253 strh r3, [r2, r1] + LWIP_ASSERT("pcb->snd_queuelen > 0", (pcb->snd_queuelen > 0)); + --pcb->snd_queuelen; + 8007946: 687b ldr r3, [r7, #4] + 8007948: 2268 movs r2, #104 ; 0x68 + 800794a: 5a9b ldrh r3, [r3, r2] + 800794c: 3b01 subs r3, #1 + 800794e: b299 uxth r1, r3 + 8007950: 687b ldr r3, [r7, #4] + 8007952: 2268 movs r2, #104 ; 0x68 + 8007954: 5299 strh r1, [r3, r2] + LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_process: SYN-SENT --queuelen %"U16_F"\n", (u16_t)pcb->snd_queuelen)); + rseg = pcb->unacked; + 8007956: 687b ldr r3, [r7, #4] + 8007958: 6f1b ldr r3, [r3, #112] ; 0x70 + 800795a: 60bb str r3, [r7, #8] + pcb->unacked = rseg->next; + 800795c: 68bb ldr r3, [r7, #8] + 800795e: 681a ldr r2, [r3, #0] + 8007960: 687b ldr r3, [r7, #4] + 8007962: 671a str r2, [r3, #112] ; 0x70 + tcp_seg_free(rseg); + 8007964: 68bb ldr r3, [r7, #8] + 8007966: 0018 movs r0, r3 + 8007968: f7fe fed9 bl 800671e + + /* If there's nothing left to acknowledge, stop the retransmit + timer, otherwise reset it to start again */ + if(pcb->unacked == NULL) + 800796c: 687b ldr r3, [r7, #4] + 800796e: 6f1b ldr r3, [r3, #112] ; 0x70 + 8007970: 2b00 cmp r3, #0 + 8007972: d104 bne.n 800797e + pcb->rtime = -1; + 8007974: 687b ldr r3, [r7, #4] + 8007976: 2201 movs r2, #1 + 8007978: 4252 negs r2, r2 + 800797a: 869a strh r2, [r3, #52] ; 0x34 + 800797c: e006 b.n 800798c + else { + pcb->rtime = 0; + 800797e: 687b ldr r3, [r7, #4] + 8007980: 2200 movs r2, #0 + 8007982: 869a strh r2, [r3, #52] ; 0x34 + pcb->nrtx = 0; + 8007984: 687b ldr r3, [r7, #4] + 8007986: 2246 movs r2, #70 ; 0x46 + 8007988: 2100 movs r1, #0 + 800798a: 5499 strb r1, [r3, r2] + } + + /* Call the user specified function to call when sucessfully + * connected. */ + TCP_EVENT_CONNECTED(pcb, ERR_OK, err); + 800798c: 687b ldr r3, [r7, #4] + 800798e: 2284 movs r2, #132 ; 0x84 + 8007990: 589b ldr r3, [r3, r2] + 8007992: 2b00 cmp r3, #0 + 8007994: d00d beq.n 80079b2 + 8007996: 687b ldr r3, [r7, #4] + 8007998: 2284 movs r2, #132 ; 0x84 + 800799a: 589d ldr r5, [r3, r2] + 800799c: 687b ldr r3, [r7, #4] + 800799e: 691b ldr r3, [r3, #16] + 80079a0: 220e movs r2, #14 + 80079a2: 18bc adds r4, r7, r2 + 80079a4: 6879 ldr r1, [r7, #4] + 80079a6: 2200 movs r2, #0 + 80079a8: 0018 movs r0, r3 + 80079aa: 47a8 blx r5 + 80079ac: 0003 movs r3, r0 + 80079ae: 7023 strb r3, [r4, #0] + 80079b0: e003 b.n 80079ba + 80079b2: 230e movs r3, #14 + 80079b4: 18fb adds r3, r7, r3 + 80079b6: 2200 movs r2, #0 + 80079b8: 701a strb r2, [r3, #0] + if (err == ERR_ABRT) { + 80079ba: 230e movs r3, #14 + 80079bc: 18fb adds r3, r7, r3 + 80079be: 781b ldrb r3, [r3, #0] + 80079c0: b25b sxtb r3, r3 + 80079c2: 330a adds r3, #10 + 80079c4: d102 bne.n 80079cc + return ERR_ABRT; + 80079c6: 230a movs r3, #10 + 80079c8: 425b negs r3, r3 + 80079ca: e240 b.n 8007e4e + } + tcp_ack_now(pcb); + 80079cc: 687b ldr r3, [r7, #4] + 80079ce: 7f9b ldrb r3, [r3, #30] + 80079d0: 2202 movs r2, #2 + 80079d2: 4313 orrs r3, r2 + 80079d4: b2da uxtb r2, r3 + 80079d6: 687b ldr r3, [r7, #4] + 80079d8: 779a strb r2, [r3, #30] + else if (flags & TCP_ACK) { + /* send a RST to bring the other side in a non-synchronized state. */ + tcp_rst(ackno, seqno + tcplen, ip_current_dest_addr(), ip_current_src_addr(), + tcphdr->dest, tcphdr->src); + } + break; + 80079da: e22a b.n 8007e32 + else if (flags & TCP_ACK) { + 80079dc: 4b34 ldr r3, [pc, #208] ; (8007ab0 ) + 80079de: 781b ldrb r3, [r3, #0] + 80079e0: 001a movs r2, r3 + 80079e2: 2310 movs r3, #16 + 80079e4: 4013 ands r3, r2 + 80079e6: d100 bne.n 80079ea + 80079e8: e223 b.n 8007e32 + tcp_rst(ackno, seqno + tcplen, ip_current_dest_addr(), ip_current_src_addr(), + 80079ea: 4b32 ldr r3, [pc, #200] ; (8007ab4 ) + 80079ec: 6818 ldr r0, [r3, #0] + 80079ee: 4b37 ldr r3, [pc, #220] ; (8007acc ) + 80079f0: 881b ldrh r3, [r3, #0] + 80079f2: 001a movs r2, r3 + 80079f4: 4b30 ldr r3, [pc, #192] ; (8007ab8 ) + 80079f6: 681b ldr r3, [r3, #0] + 80079f8: 18d4 adds r4, r2, r3 + tcphdr->dest, tcphdr->src); + 80079fa: 4b33 ldr r3, [pc, #204] ; (8007ac8 ) + 80079fc: 681b ldr r3, [r3, #0] + tcp_rst(ackno, seqno + tcplen, ip_current_dest_addr(), ip_current_src_addr(), + 80079fe: 789a ldrb r2, [r3, #2] + 8007a00: 78db ldrb r3, [r3, #3] + 8007a02: 021b lsls r3, r3, #8 + 8007a04: 4313 orrs r3, r2 + 8007a06: b29a uxth r2, r3 + tcphdr->dest, tcphdr->src); + 8007a08: 4b2f ldr r3, [pc, #188] ; (8007ac8 ) + 8007a0a: 681b ldr r3, [r3, #0] + tcp_rst(ackno, seqno + tcplen, ip_current_dest_addr(), ip_current_src_addr(), + 8007a0c: 7819 ldrb r1, [r3, #0] + 8007a0e: 785b ldrb r3, [r3, #1] + 8007a10: 021b lsls r3, r3, #8 + 8007a12: 430b orrs r3, r1 + 8007a14: b29b uxth r3, r3 + 8007a16: 4d2e ldr r5, [pc, #184] ; (8007ad0 ) + 8007a18: 492e ldr r1, [pc, #184] ; (8007ad4 ) + 8007a1a: 9301 str r3, [sp, #4] + 8007a1c: 9200 str r2, [sp, #0] + 8007a1e: 002b movs r3, r5 + 8007a20: 000a movs r2, r1 + 8007a22: 0021 movs r1, r4 + 8007a24: f002 fad2 bl 8009fcc + break; + 8007a28: e203 b.n 8007e32 + case SYN_RCVD: + if (flags & TCP_ACK) { + 8007a2a: 4b21 ldr r3, [pc, #132] ; (8007ab0 ) + 8007a2c: 781b ldrb r3, [r3, #0] + 8007a2e: 001a movs r2, r3 + 8007a30: 2310 movs r3, #16 + 8007a32: 4013 ands r3, r2 + 8007a34: d100 bne.n 8007a38 + 8007a36: e0a6 b.n 8007b86 + /* expected ACK number? */ + if (TCP_SEQ_BETWEEN(ackno, pcb->lastack+1, pcb->snd_nxt)) { + 8007a38: 4b1e ldr r3, [pc, #120] ; (8007ab4 ) + 8007a3a: 681a ldr r2, [r3, #0] + 8007a3c: 687b ldr r3, [r7, #4] + 8007a3e: 6c9b ldr r3, [r3, #72] ; 0x48 + 8007a40: 1ad3 subs r3, r2, r3 + 8007a42: 3b01 subs r3, #1 + 8007a44: 2b00 cmp r3, #0 + 8007a46: da00 bge.n 8007a4a + 8007a48: e07d b.n 8007b46 + 8007a4a: 4b1a ldr r3, [pc, #104] ; (8007ab4 ) + 8007a4c: 681a ldr r2, [r3, #0] + 8007a4e: 687b ldr r3, [r7, #4] + 8007a50: 6d1b ldr r3, [r3, #80] ; 0x50 + 8007a52: 1ad3 subs r3, r2, r3 + 8007a54: 2b00 cmp r3, #0 + 8007a56: dd00 ble.n 8007a5a + 8007a58: e075 b.n 8007b46 + u16_t old_cwnd; + pcb->state = ESTABLISHED; + 8007a5a: 687b ldr r3, [r7, #4] + 8007a5c: 2204 movs r2, #4 + 8007a5e: 761a strb r2, [r3, #24] + LWIP_DEBUGF(TCP_DEBUG, ("TCP connection established %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest)); +#if LWIP_CALLBACK_API + LWIP_ASSERT("pcb->accept != NULL", pcb->accept != NULL); +#endif + /* Call the accept function. */ + TCP_EVENT_ACCEPT(pcb, ERR_OK, err); + 8007a60: 687b ldr r3, [r7, #4] + 8007a62: 695b ldr r3, [r3, #20] + 8007a64: 2b00 cmp r3, #0 + 8007a66: d00c beq.n 8007a82 + 8007a68: 687b ldr r3, [r7, #4] + 8007a6a: 695d ldr r5, [r3, #20] + 8007a6c: 687b ldr r3, [r7, #4] + 8007a6e: 691b ldr r3, [r3, #16] + 8007a70: 220e movs r2, #14 + 8007a72: 18bc adds r4, r7, r2 + 8007a74: 6879 ldr r1, [r7, #4] + 8007a76: 2200 movs r2, #0 + 8007a78: 0018 movs r0, r3 + 8007a7a: 47a8 blx r5 + 8007a7c: 0003 movs r3, r0 + 8007a7e: 7023 strb r3, [r4, #0] + 8007a80: e003 b.n 8007a8a + 8007a82: 230e movs r3, #14 + 8007a84: 18fb adds r3, r7, r3 + 8007a86: 22f2 movs r2, #242 ; 0xf2 + 8007a88: 701a strb r2, [r3, #0] + if (err != ERR_OK) { + 8007a8a: 230e movs r3, #14 + 8007a8c: 18fb adds r3, r7, r3 + 8007a8e: 781b ldrb r3, [r3, #0] + 8007a90: b25b sxtb r3, r3 + 8007a92: 2b00 cmp r3, #0 + 8007a94: d020 beq.n 8007ad8 + /* If the accept function returns with an error, we abort + * the connection. */ + /* Already aborted? */ + if (err != ERR_ABRT) { + 8007a96: 230e movs r3, #14 + 8007a98: 18fb adds r3, r7, r3 + 8007a9a: 781b ldrb r3, [r3, #0] + 8007a9c: b25b sxtb r3, r3 + 8007a9e: 330a adds r3, #10 + 8007aa0: d003 beq.n 8007aaa + tcp_abort(pcb); + 8007aa2: 687b ldr r3, [r7, #4] + 8007aa4: 0018 movs r0, r3 + 8007aa6: f7fe fa69 bl 8005f7c + } + return ERR_ABRT; + 8007aaa: 230a movs r3, #10 + 8007aac: 425b negs r3, r3 + 8007aae: e1ce b.n 8007e4e + 8007ab0: 2000229c .word 0x2000229c + 8007ab4: 20002298 .word 0x20002298 + 8007ab8: 20002294 .word 0x20002294 + 8007abc: 200022a0 .word 0x200022a0 + 8007ac0: 20003278 .word 0x20003278 + 8007ac4: 0800fd98 .word 0x0800fd98 + 8007ac8: 2000228c .word 0x2000228c + 8007acc: 2000229e .word 0x2000229e + 8007ad0: 20003294 .word 0x20003294 + 8007ad4: 2000329c .word 0x2000329c + } + old_cwnd = pcb->cwnd; + 8007ad8: 230c movs r3, #12 + 8007ada: 18fb adds r3, r7, r3 + 8007adc: 687a ldr r2, [r7, #4] + 8007ade: 214c movs r1, #76 ; 0x4c + 8007ae0: 5a52 ldrh r2, [r2, r1] + 8007ae2: 801a strh r2, [r3, #0] + /* If there was any data contained within this ACK, + * we'd better pass it on to the application as well. */ + tcp_receive(pcb); + 8007ae4: 687b ldr r3, [r7, #4] + 8007ae6: 0018 movs r0, r3 + 8007ae8: f000 fa7c bl 8007fe4 + + /* Prevent ACK for SYN to generate a sent event */ + if (pcb->acked != 0) { + 8007aec: 687b ldr r3, [r7, #4] + 8007aee: 2264 movs r2, #100 ; 0x64 + 8007af0: 5a9b ldrh r3, [r3, r2] + 8007af2: 2b00 cmp r3, #0 + 8007af4: d007 beq.n 8007b06 + pcb->acked--; + 8007af6: 687b ldr r3, [r7, #4] + 8007af8: 2264 movs r2, #100 ; 0x64 + 8007afa: 5a9b ldrh r3, [r3, r2] + 8007afc: 3b01 subs r3, #1 + 8007afe: b299 uxth r1, r3 + 8007b00: 687b ldr r3, [r7, #4] + 8007b02: 2264 movs r2, #100 ; 0x64 + 8007b04: 5299 strh r1, [r3, r2] + } + + pcb->cwnd = ((old_cwnd == 1) ? (pcb->mss * 2) : pcb->mss); + 8007b06: 230c movs r3, #12 + 8007b08: 18fb adds r3, r7, r3 + 8007b0a: 881b ldrh r3, [r3, #0] + 8007b0c: 2b01 cmp r3, #1 + 8007b0e: d104 bne.n 8007b1a + 8007b10: 687b ldr r3, [r7, #4] + 8007b12: 8edb ldrh r3, [r3, #54] ; 0x36 + 8007b14: 18db adds r3, r3, r3 + 8007b16: b29b uxth r3, r3 + 8007b18: e001 b.n 8007b1e + 8007b1a: 687b ldr r3, [r7, #4] + 8007b1c: 8edb ldrh r3, [r3, #54] ; 0x36 + 8007b1e: 687a ldr r2, [r7, #4] + 8007b20: 214c movs r1, #76 ; 0x4c + 8007b22: 5253 strh r3, [r2, r1] + + if (recv_flags & TF_GOT_FIN) { + 8007b24: 4bcc ldr r3, [pc, #816] ; (8007e58 ) + 8007b26: 781b ldrb r3, [r3, #0] + 8007b28: 001a movs r2, r3 + 8007b2a: 2320 movs r3, #32 + 8007b2c: 4013 ands r3, r2 + 8007b2e: d03e beq.n 8007bae + tcp_ack_now(pcb); + 8007b30: 687b ldr r3, [r7, #4] + 8007b32: 7f9b ldrb r3, [r3, #30] + 8007b34: 2202 movs r2, #2 + 8007b36: 4313 orrs r3, r2 + 8007b38: b2da uxtb r2, r3 + 8007b3a: 687b ldr r3, [r7, #4] + 8007b3c: 779a strb r2, [r3, #30] + pcb->state = CLOSE_WAIT; + 8007b3e: 687b ldr r3, [r7, #4] + 8007b40: 2207 movs r2, #7 + 8007b42: 761a strb r2, [r3, #24] + if (TCP_SEQ_BETWEEN(ackno, pcb->lastack+1, pcb->snd_nxt)) { + 8007b44: e033 b.n 8007bae + } + } else { + /* incorrect ACK number, send RST */ + tcp_rst(ackno, seqno + tcplen, ip_current_dest_addr(), ip_current_src_addr(), + 8007b46: 4bc5 ldr r3, [pc, #788] ; (8007e5c ) + 8007b48: 6818 ldr r0, [r3, #0] + 8007b4a: 4bc5 ldr r3, [pc, #788] ; (8007e60 ) + 8007b4c: 881b ldrh r3, [r3, #0] + 8007b4e: 001a movs r2, r3 + 8007b50: 4bc4 ldr r3, [pc, #784] ; (8007e64 ) + 8007b52: 681b ldr r3, [r3, #0] + 8007b54: 18d4 adds r4, r2, r3 + tcphdr->dest, tcphdr->src); + 8007b56: 4bc4 ldr r3, [pc, #784] ; (8007e68 ) + 8007b58: 681b ldr r3, [r3, #0] + tcp_rst(ackno, seqno + tcplen, ip_current_dest_addr(), ip_current_src_addr(), + 8007b5a: 789a ldrb r2, [r3, #2] + 8007b5c: 78db ldrb r3, [r3, #3] + 8007b5e: 021b lsls r3, r3, #8 + 8007b60: 4313 orrs r3, r2 + 8007b62: b29a uxth r2, r3 + tcphdr->dest, tcphdr->src); + 8007b64: 4bc0 ldr r3, [pc, #768] ; (8007e68 ) + 8007b66: 681b ldr r3, [r3, #0] + tcp_rst(ackno, seqno + tcplen, ip_current_dest_addr(), ip_current_src_addr(), + 8007b68: 7819 ldrb r1, [r3, #0] + 8007b6a: 785b ldrb r3, [r3, #1] + 8007b6c: 021b lsls r3, r3, #8 + 8007b6e: 430b orrs r3, r1 + 8007b70: b29b uxth r3, r3 + 8007b72: 4dbe ldr r5, [pc, #760] ; (8007e6c ) + 8007b74: 49be ldr r1, [pc, #760] ; (8007e70 ) + 8007b76: 9301 str r3, [sp, #4] + 8007b78: 9200 str r2, [sp, #0] + 8007b7a: 002b movs r3, r5 + 8007b7c: 000a movs r2, r1 + 8007b7e: 0021 movs r1, r4 + 8007b80: f002 fa24 bl 8009fcc + } + } else if ((flags & TCP_SYN) && (seqno == pcb->rcv_nxt - 1)) { + /* Looks like another copy of the SYN - retransmit our SYN-ACK */ + tcp_rexmit(pcb); + } + break; + 8007b84: e157 b.n 8007e36 + } else if ((flags & TCP_SYN) && (seqno == pcb->rcv_nxt - 1)) { + 8007b86: 4bbb ldr r3, [pc, #748] ; (8007e74 ) + 8007b88: 781b ldrb r3, [r3, #0] + 8007b8a: 001a movs r2, r3 + 8007b8c: 2302 movs r3, #2 + 8007b8e: 4013 ands r3, r2 + 8007b90: d100 bne.n 8007b94 + 8007b92: e150 b.n 8007e36 + 8007b94: 687b ldr r3, [r7, #4] + 8007b96: 6a9b ldr r3, [r3, #40] ; 0x28 + 8007b98: 1e5a subs r2, r3, #1 + 8007b9a: 4bb2 ldr r3, [pc, #712] ; (8007e64 ) + 8007b9c: 681b ldr r3, [r3, #0] + 8007b9e: 429a cmp r2, r3 + 8007ba0: d000 beq.n 8007ba4 + 8007ba2: e148 b.n 8007e36 + tcp_rexmit(pcb); + 8007ba4: 687b ldr r3, [r7, #4] + 8007ba6: 0018 movs r0, r3 + 8007ba8: f002 fb66 bl 800a278 + break; + 8007bac: e143 b.n 8007e36 + if (TCP_SEQ_BETWEEN(ackno, pcb->lastack+1, pcb->snd_nxt)) { + 8007bae: 46c0 nop ; (mov r8, r8) + break; + 8007bb0: e141 b.n 8007e36 + case CLOSE_WAIT: + /* FALLTHROUGH */ + case ESTABLISHED: + tcp_receive(pcb); + 8007bb2: 687b ldr r3, [r7, #4] + 8007bb4: 0018 movs r0, r3 + 8007bb6: f000 fa15 bl 8007fe4 + if (recv_flags & TF_GOT_FIN) { /* passive close */ + 8007bba: 4ba7 ldr r3, [pc, #668] ; (8007e58 ) + 8007bbc: 781b ldrb r3, [r3, #0] + 8007bbe: 001a movs r2, r3 + 8007bc0: 2320 movs r3, #32 + 8007bc2: 4013 ands r3, r2 + 8007bc4: d100 bne.n 8007bc8 + 8007bc6: e138 b.n 8007e3a + tcp_ack_now(pcb); + 8007bc8: 687b ldr r3, [r7, #4] + 8007bca: 7f9b ldrb r3, [r3, #30] + 8007bcc: 2202 movs r2, #2 + 8007bce: 4313 orrs r3, r2 + 8007bd0: b2da uxtb r2, r3 + 8007bd2: 687b ldr r3, [r7, #4] + 8007bd4: 779a strb r2, [r3, #30] + pcb->state = CLOSE_WAIT; + 8007bd6: 687b ldr r3, [r7, #4] + 8007bd8: 2207 movs r2, #7 + 8007bda: 761a strb r2, [r3, #24] + } + break; + 8007bdc: e12d b.n 8007e3a + case FIN_WAIT_1: + tcp_receive(pcb); + 8007bde: 687b ldr r3, [r7, #4] + 8007be0: 0018 movs r0, r3 + 8007be2: f000 f9ff bl 8007fe4 + if (recv_flags & TF_GOT_FIN) { + 8007be6: 4b9c ldr r3, [pc, #624] ; (8007e58 ) + 8007be8: 781b ldrb r3, [r3, #0] + 8007bea: 001a movs r2, r3 + 8007bec: 2320 movs r3, #32 + 8007bee: 4013 ands r3, r2 + 8007bf0: d059 beq.n 8007ca6 + if ((flags & TCP_ACK) && (ackno == pcb->snd_nxt)) { + 8007bf2: 4ba0 ldr r3, [pc, #640] ; (8007e74 ) + 8007bf4: 781b ldrb r3, [r3, #0] + 8007bf6: 001a movs r2, r3 + 8007bf8: 2310 movs r3, #16 + 8007bfa: 4013 ands r3, r2 + 8007bfc: d048 beq.n 8007c90 + 8007bfe: 687b ldr r3, [r7, #4] + 8007c00: 6d1a ldr r2, [r3, #80] ; 0x50 + 8007c02: 4b96 ldr r3, [pc, #600] ; (8007e5c ) + 8007c04: 681b ldr r3, [r3, #0] + 8007c06: 429a cmp r2, r3 + 8007c08: d142 bne.n 8007c90 + LWIP_DEBUGF(TCP_DEBUG, + ("TCP connection closed: FIN_WAIT_1 %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest)); + tcp_ack_now(pcb); + 8007c0a: 687b ldr r3, [r7, #4] + 8007c0c: 7f9b ldrb r3, [r3, #30] + 8007c0e: 2202 movs r2, #2 + 8007c10: 4313 orrs r3, r2 + 8007c12: b2da uxtb r2, r3 + 8007c14: 687b ldr r3, [r7, #4] + 8007c16: 779a strb r2, [r3, #30] + tcp_pcb_purge(pcb); + 8007c18: 687b ldr r3, [r7, #4] + 8007c1a: 0018 movs r0, r3 + 8007c1c: f7fe ff04 bl 8006a28 + TCP_RMV_ACTIVE(pcb); + 8007c20: 4b95 ldr r3, [pc, #596] ; (8007e78 ) + 8007c22: 681b ldr r3, [r3, #0] + 8007c24: 687a ldr r2, [r7, #4] + 8007c26: 429a cmp r2, r3 + 8007c28: d105 bne.n 8007c36 + 8007c2a: 4b93 ldr r3, [pc, #588] ; (8007e78 ) + 8007c2c: 681b ldr r3, [r3, #0] + 8007c2e: 68da ldr r2, [r3, #12] + 8007c30: 4b91 ldr r3, [pc, #580] ; (8007e78 ) + 8007c32: 601a str r2, [r3, #0] + 8007c34: e019 b.n 8007c6a + 8007c36: 4b90 ldr r3, [pc, #576] ; (8007e78 ) + 8007c38: 681a ldr r2, [r3, #0] + 8007c3a: 4b90 ldr r3, [pc, #576] ; (8007e7c ) + 8007c3c: 601a str r2, [r3, #0] + 8007c3e: e010 b.n 8007c62 + 8007c40: 4b8e ldr r3, [pc, #568] ; (8007e7c ) + 8007c42: 681b ldr r3, [r3, #0] + 8007c44: 68db ldr r3, [r3, #12] + 8007c46: 687a ldr r2, [r7, #4] + 8007c48: 429a cmp r2, r3 + 8007c4a: d105 bne.n 8007c58 + 8007c4c: 4b8b ldr r3, [pc, #556] ; (8007e7c ) + 8007c4e: 681b ldr r3, [r3, #0] + 8007c50: 687a ldr r2, [r7, #4] + 8007c52: 68d2 ldr r2, [r2, #12] + 8007c54: 60da str r2, [r3, #12] + 8007c56: e008 b.n 8007c6a + 8007c58: 4b88 ldr r3, [pc, #544] ; (8007e7c ) + 8007c5a: 681b ldr r3, [r3, #0] + 8007c5c: 68da ldr r2, [r3, #12] + 8007c5e: 4b87 ldr r3, [pc, #540] ; (8007e7c ) + 8007c60: 601a str r2, [r3, #0] + 8007c62: 4b86 ldr r3, [pc, #536] ; (8007e7c ) + 8007c64: 681b ldr r3, [r3, #0] + 8007c66: 2b00 cmp r3, #0 + 8007c68: d1ea bne.n 8007c40 + 8007c6a: 687b ldr r3, [r7, #4] + 8007c6c: 2200 movs r2, #0 + 8007c6e: 60da str r2, [r3, #12] + 8007c70: 4b83 ldr r3, [pc, #524] ; (8007e80 ) + 8007c72: 2201 movs r2, #1 + 8007c74: 701a strb r2, [r3, #0] + pcb->state = TIME_WAIT; + 8007c76: 687b ldr r3, [r7, #4] + 8007c78: 220a movs r2, #10 + 8007c7a: 761a strb r2, [r3, #24] + TCP_REG(&tcp_tw_pcbs, pcb); + 8007c7c: 4b81 ldr r3, [pc, #516] ; (8007e84 ) + 8007c7e: 681a ldr r2, [r3, #0] + 8007c80: 687b ldr r3, [r7, #4] + 8007c82: 60da str r2, [r3, #12] + 8007c84: 4b7f ldr r3, [pc, #508] ; (8007e84 ) + 8007c86: 687a ldr r2, [r7, #4] + 8007c88: 601a str r2, [r3, #0] + 8007c8a: f002 fcf3 bl 800a674 + pcb->state = CLOSING; + } + } else if ((flags & TCP_ACK) && (ackno == pcb->snd_nxt)) { + pcb->state = FIN_WAIT_2; + } + break; + 8007c8e: e0d6 b.n 8007e3e + tcp_ack_now(pcb); + 8007c90: 687b ldr r3, [r7, #4] + 8007c92: 7f9b ldrb r3, [r3, #30] + 8007c94: 2202 movs r2, #2 + 8007c96: 4313 orrs r3, r2 + 8007c98: b2da uxtb r2, r3 + 8007c9a: 687b ldr r3, [r7, #4] + 8007c9c: 779a strb r2, [r3, #30] + pcb->state = CLOSING; + 8007c9e: 687b ldr r3, [r7, #4] + 8007ca0: 2208 movs r2, #8 + 8007ca2: 761a strb r2, [r3, #24] + break; + 8007ca4: e0cb b.n 8007e3e + } else if ((flags & TCP_ACK) && (ackno == pcb->snd_nxt)) { + 8007ca6: 4b73 ldr r3, [pc, #460] ; (8007e74 ) + 8007ca8: 781b ldrb r3, [r3, #0] + 8007caa: 001a movs r2, r3 + 8007cac: 2310 movs r3, #16 + 8007cae: 4013 ands r3, r2 + 8007cb0: d100 bne.n 8007cb4 + 8007cb2: e0c4 b.n 8007e3e + 8007cb4: 687b ldr r3, [r7, #4] + 8007cb6: 6d1a ldr r2, [r3, #80] ; 0x50 + 8007cb8: 4b68 ldr r3, [pc, #416] ; (8007e5c ) + 8007cba: 681b ldr r3, [r3, #0] + 8007cbc: 429a cmp r2, r3 + 8007cbe: d000 beq.n 8007cc2 + 8007cc0: e0bd b.n 8007e3e + pcb->state = FIN_WAIT_2; + 8007cc2: 687b ldr r3, [r7, #4] + 8007cc4: 2206 movs r2, #6 + 8007cc6: 761a strb r2, [r3, #24] + break; + 8007cc8: e0b9 b.n 8007e3e + case FIN_WAIT_2: + tcp_receive(pcb); + 8007cca: 687b ldr r3, [r7, #4] + 8007ccc: 0018 movs r0, r3 + 8007cce: f000 f989 bl 8007fe4 + if (recv_flags & TF_GOT_FIN) { + 8007cd2: 4b61 ldr r3, [pc, #388] ; (8007e58 ) + 8007cd4: 781b ldrb r3, [r3, #0] + 8007cd6: 001a movs r2, r3 + 8007cd8: 2320 movs r3, #32 + 8007cda: 4013 ands r3, r2 + 8007cdc: d100 bne.n 8007ce0 + 8007cde: e0b0 b.n 8007e42 + LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed: FIN_WAIT_2 %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest)); + tcp_ack_now(pcb); + 8007ce0: 687b ldr r3, [r7, #4] + 8007ce2: 7f9b ldrb r3, [r3, #30] + 8007ce4: 2202 movs r2, #2 + 8007ce6: 4313 orrs r3, r2 + 8007ce8: b2da uxtb r2, r3 + 8007cea: 687b ldr r3, [r7, #4] + 8007cec: 779a strb r2, [r3, #30] + tcp_pcb_purge(pcb); + 8007cee: 687b ldr r3, [r7, #4] + 8007cf0: 0018 movs r0, r3 + 8007cf2: f7fe fe99 bl 8006a28 + TCP_RMV_ACTIVE(pcb); + 8007cf6: 4b60 ldr r3, [pc, #384] ; (8007e78 ) + 8007cf8: 681b ldr r3, [r3, #0] + 8007cfa: 687a ldr r2, [r7, #4] + 8007cfc: 429a cmp r2, r3 + 8007cfe: d105 bne.n 8007d0c + 8007d00: 4b5d ldr r3, [pc, #372] ; (8007e78 ) + 8007d02: 681b ldr r3, [r3, #0] + 8007d04: 68da ldr r2, [r3, #12] + 8007d06: 4b5c ldr r3, [pc, #368] ; (8007e78 ) + 8007d08: 601a str r2, [r3, #0] + 8007d0a: e019 b.n 8007d40 + 8007d0c: 4b5a ldr r3, [pc, #360] ; (8007e78 ) + 8007d0e: 681a ldr r2, [r3, #0] + 8007d10: 4b5a ldr r3, [pc, #360] ; (8007e7c ) + 8007d12: 601a str r2, [r3, #0] + 8007d14: e010 b.n 8007d38 + 8007d16: 4b59 ldr r3, [pc, #356] ; (8007e7c ) + 8007d18: 681b ldr r3, [r3, #0] + 8007d1a: 68db ldr r3, [r3, #12] + 8007d1c: 687a ldr r2, [r7, #4] + 8007d1e: 429a cmp r2, r3 + 8007d20: d105 bne.n 8007d2e + 8007d22: 4b56 ldr r3, [pc, #344] ; (8007e7c ) + 8007d24: 681b ldr r3, [r3, #0] + 8007d26: 687a ldr r2, [r7, #4] + 8007d28: 68d2 ldr r2, [r2, #12] + 8007d2a: 60da str r2, [r3, #12] + 8007d2c: e008 b.n 8007d40 + 8007d2e: 4b53 ldr r3, [pc, #332] ; (8007e7c ) + 8007d30: 681b ldr r3, [r3, #0] + 8007d32: 68da ldr r2, [r3, #12] + 8007d34: 4b51 ldr r3, [pc, #324] ; (8007e7c ) + 8007d36: 601a str r2, [r3, #0] + 8007d38: 4b50 ldr r3, [pc, #320] ; (8007e7c ) + 8007d3a: 681b ldr r3, [r3, #0] + 8007d3c: 2b00 cmp r3, #0 + 8007d3e: d1ea bne.n 8007d16 + 8007d40: 687b ldr r3, [r7, #4] + 8007d42: 2200 movs r2, #0 + 8007d44: 60da str r2, [r3, #12] + 8007d46: 4b4e ldr r3, [pc, #312] ; (8007e80 ) + 8007d48: 2201 movs r2, #1 + 8007d4a: 701a strb r2, [r3, #0] + pcb->state = TIME_WAIT; + 8007d4c: 687b ldr r3, [r7, #4] + 8007d4e: 220a movs r2, #10 + 8007d50: 761a strb r2, [r3, #24] + TCP_REG(&tcp_tw_pcbs, pcb); + 8007d52: 4b4c ldr r3, [pc, #304] ; (8007e84 ) + 8007d54: 681a ldr r2, [r3, #0] + 8007d56: 687b ldr r3, [r7, #4] + 8007d58: 60da str r2, [r3, #12] + 8007d5a: 4b4a ldr r3, [pc, #296] ; (8007e84 ) + 8007d5c: 687a ldr r2, [r7, #4] + 8007d5e: 601a str r2, [r3, #0] + 8007d60: f002 fc88 bl 800a674 + } + break; + 8007d64: e06d b.n 8007e42 + case CLOSING: + tcp_receive(pcb); + 8007d66: 687b ldr r3, [r7, #4] + 8007d68: 0018 movs r0, r3 + 8007d6a: f000 f93b bl 8007fe4 + if (flags & TCP_ACK && ackno == pcb->snd_nxt) { + 8007d6e: 4b41 ldr r3, [pc, #260] ; (8007e74 ) + 8007d70: 781b ldrb r3, [r3, #0] + 8007d72: 001a movs r2, r3 + 8007d74: 2310 movs r3, #16 + 8007d76: 4013 ands r3, r2 + 8007d78: d065 beq.n 8007e46 + 8007d7a: 687b ldr r3, [r7, #4] + 8007d7c: 6d1a ldr r2, [r3, #80] ; 0x50 + 8007d7e: 4b37 ldr r3, [pc, #220] ; (8007e5c ) + 8007d80: 681b ldr r3, [r3, #0] + 8007d82: 429a cmp r2, r3 + 8007d84: d15f bne.n 8007e46 + LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed: CLOSING %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest)); + tcp_pcb_purge(pcb); + 8007d86: 687b ldr r3, [r7, #4] + 8007d88: 0018 movs r0, r3 + 8007d8a: f7fe fe4d bl 8006a28 + TCP_RMV_ACTIVE(pcb); + 8007d8e: 4b3a ldr r3, [pc, #232] ; (8007e78 ) + 8007d90: 681b ldr r3, [r3, #0] + 8007d92: 687a ldr r2, [r7, #4] + 8007d94: 429a cmp r2, r3 + 8007d96: d105 bne.n 8007da4 + 8007d98: 4b37 ldr r3, [pc, #220] ; (8007e78 ) + 8007d9a: 681b ldr r3, [r3, #0] + 8007d9c: 68da ldr r2, [r3, #12] + 8007d9e: 4b36 ldr r3, [pc, #216] ; (8007e78 ) + 8007da0: 601a str r2, [r3, #0] + 8007da2: e019 b.n 8007dd8 + 8007da4: 4b34 ldr r3, [pc, #208] ; (8007e78 ) + 8007da6: 681a ldr r2, [r3, #0] + 8007da8: 4b34 ldr r3, [pc, #208] ; (8007e7c ) + 8007daa: 601a str r2, [r3, #0] + 8007dac: e010 b.n 8007dd0 + 8007dae: 4b33 ldr r3, [pc, #204] ; (8007e7c ) + 8007db0: 681b ldr r3, [r3, #0] + 8007db2: 68db ldr r3, [r3, #12] + 8007db4: 687a ldr r2, [r7, #4] + 8007db6: 429a cmp r2, r3 + 8007db8: d105 bne.n 8007dc6 + 8007dba: 4b30 ldr r3, [pc, #192] ; (8007e7c ) + 8007dbc: 681b ldr r3, [r3, #0] + 8007dbe: 687a ldr r2, [r7, #4] + 8007dc0: 68d2 ldr r2, [r2, #12] + 8007dc2: 60da str r2, [r3, #12] + 8007dc4: e008 b.n 8007dd8 + 8007dc6: 4b2d ldr r3, [pc, #180] ; (8007e7c ) + 8007dc8: 681b ldr r3, [r3, #0] + 8007dca: 68da ldr r2, [r3, #12] + 8007dcc: 4b2b ldr r3, [pc, #172] ; (8007e7c ) + 8007dce: 601a str r2, [r3, #0] + 8007dd0: 4b2a ldr r3, [pc, #168] ; (8007e7c ) + 8007dd2: 681b ldr r3, [r3, #0] + 8007dd4: 2b00 cmp r3, #0 + 8007dd6: d1ea bne.n 8007dae + 8007dd8: 687b ldr r3, [r7, #4] + 8007dda: 2200 movs r2, #0 + 8007ddc: 60da str r2, [r3, #12] + 8007dde: 4b28 ldr r3, [pc, #160] ; (8007e80 ) + 8007de0: 2201 movs r2, #1 + 8007de2: 701a strb r2, [r3, #0] + pcb->state = TIME_WAIT; + 8007de4: 687b ldr r3, [r7, #4] + 8007de6: 220a movs r2, #10 + 8007de8: 761a strb r2, [r3, #24] + TCP_REG(&tcp_tw_pcbs, pcb); + 8007dea: 4b26 ldr r3, [pc, #152] ; (8007e84 ) + 8007dec: 681a ldr r2, [r3, #0] + 8007dee: 687b ldr r3, [r7, #4] + 8007df0: 60da str r2, [r3, #12] + 8007df2: 4b24 ldr r3, [pc, #144] ; (8007e84 ) + 8007df4: 687a ldr r2, [r7, #4] + 8007df6: 601a str r2, [r3, #0] + 8007df8: f002 fc3c bl 800a674 + } + break; + 8007dfc: e023 b.n 8007e46 + case LAST_ACK: + tcp_receive(pcb); + 8007dfe: 687b ldr r3, [r7, #4] + 8007e00: 0018 movs r0, r3 + 8007e02: f000 f8ef bl 8007fe4 + if (flags & TCP_ACK && ackno == pcb->snd_nxt) { + 8007e06: 4b1b ldr r3, [pc, #108] ; (8007e74 ) + 8007e08: 781b ldrb r3, [r3, #0] + 8007e0a: 001a movs r2, r3 + 8007e0c: 2310 movs r3, #16 + 8007e0e: 4013 ands r3, r2 + 8007e10: d01b beq.n 8007e4a + 8007e12: 687b ldr r3, [r7, #4] + 8007e14: 6d1a ldr r2, [r3, #80] ; 0x50 + 8007e16: 4b11 ldr r3, [pc, #68] ; (8007e5c ) + 8007e18: 681b ldr r3, [r3, #0] + 8007e1a: 429a cmp r2, r3 + 8007e1c: d115 bne.n 8007e4a + LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed: LAST_ACK %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest)); + /* bugfix #21699: don't set pcb->state to CLOSED here or we risk leaking segments */ + recv_flags |= TF_CLOSED; + 8007e1e: 4b0e ldr r3, [pc, #56] ; (8007e58 ) + 8007e20: 781b ldrb r3, [r3, #0] + 8007e22: 2210 movs r2, #16 + 8007e24: 4313 orrs r3, r2 + 8007e26: b2da uxtb r2, r3 + 8007e28: 4b0b ldr r3, [pc, #44] ; (8007e58 ) + 8007e2a: 701a strb r2, [r3, #0] + } + break; + 8007e2c: e00d b.n 8007e4a + default: + break; + 8007e2e: 46c0 nop ; (mov r8, r8) + 8007e30: e00c b.n 8007e4c + break; + 8007e32: 46c0 nop ; (mov r8, r8) + 8007e34: e00a b.n 8007e4c + break; + 8007e36: 46c0 nop ; (mov r8, r8) + 8007e38: e008 b.n 8007e4c + break; + 8007e3a: 46c0 nop ; (mov r8, r8) + 8007e3c: e006 b.n 8007e4c + break; + 8007e3e: 46c0 nop ; (mov r8, r8) + 8007e40: e004 b.n 8007e4c + break; + 8007e42: 46c0 nop ; (mov r8, r8) + 8007e44: e002 b.n 8007e4c + break; + 8007e46: 46c0 nop ; (mov r8, r8) + 8007e48: e000 b.n 8007e4c + break; + 8007e4a: 46c0 nop ; (mov r8, r8) + } + return ERR_OK; + 8007e4c: 2300 movs r3, #0 +} + 8007e4e: 0018 movs r0, r3 + 8007e50: 46bd mov sp, r7 + 8007e52: b004 add sp, #16 + 8007e54: bdb0 pop {r4, r5, r7, pc} + 8007e56: 46c0 nop ; (mov r8, r8) + 8007e58: 200022a0 .word 0x200022a0 + 8007e5c: 20002298 .word 0x20002298 + 8007e60: 2000229e .word 0x2000229e + 8007e64: 20002294 .word 0x20002294 + 8007e68: 2000228c .word 0x2000228c + 8007e6c: 20003294 .word 0x20003294 + 8007e70: 2000329c .word 0x2000329c + 8007e74: 2000229c .word 0x2000229c + 8007e78: 20003274 .word 0x20003274 + 8007e7c: 20003280 .word 0x20003280 + 8007e80: 20003270 .word 0x20003270 + 8007e84: 20003288 .word 0x20003288 + +08007e88 : + * + * Called from tcp_receive() + */ +static void +tcp_oos_insert_segment(struct tcp_seg *cseg, struct tcp_seg *next) +{ + 8007e88: b590 push {r4, r7, lr} + 8007e8a: b085 sub sp, #20 + 8007e8c: af00 add r7, sp, #0 + 8007e8e: 6078 str r0, [r7, #4] + 8007e90: 6039 str r1, [r7, #0] + struct tcp_seg *old_seg; + + if (TCPH_FLAGS(cseg->tcphdr) & TCP_FIN) { + 8007e92: 687b ldr r3, [r7, #4] + 8007e94: 68db ldr r3, [r3, #12] + 8007e96: 7b1a ldrb r2, [r3, #12] + 8007e98: 7b5b ldrb r3, [r3, #13] + 8007e9a: 021b lsls r3, r3, #8 + 8007e9c: 4313 orrs r3, r2 + 8007e9e: b29b uxth r3, r3 + 8007ea0: 0018 movs r0, r3 + 8007ea2: f7fc fbcd bl 8004640 + 8007ea6: 0003 movs r3, r0 + 8007ea8: 001a movs r2, r3 + 8007eaa: 2301 movs r3, #1 + 8007eac: 4013 ands r3, r2 + 8007eae: d041 beq.n 8007f34 + /* received segment overlaps all following segments */ + tcp_segs_free(next); + 8007eb0: 683b ldr r3, [r7, #0] + 8007eb2: 0018 movs r0, r3 + 8007eb4: f7fe fc1e bl 80066f4 + next = NULL; + 8007eb8: 2300 movs r3, #0 + 8007eba: 603b str r3, [r7, #0] + 8007ebc: e089 b.n 8007fd2 + oos queue may have segments with FIN flag */ + while (next && + TCP_SEQ_GEQ((seqno + cseg->len), + (next->tcphdr->seqno + next->len))) { + /* cseg with FIN already processed */ + if (TCPH_FLAGS(next->tcphdr) & TCP_FIN) { + 8007ebe: 683b ldr r3, [r7, #0] + 8007ec0: 68db ldr r3, [r3, #12] + 8007ec2: 7b1a ldrb r2, [r3, #12] + 8007ec4: 7b5b ldrb r3, [r3, #13] + 8007ec6: 021b lsls r3, r3, #8 + 8007ec8: 4313 orrs r3, r2 + 8007eca: b29b uxth r3, r3 + 8007ecc: 0018 movs r0, r3 + 8007ece: f7fc fbb7 bl 8004640 + 8007ed2: 0003 movs r3, r0 + 8007ed4: 001a movs r2, r3 + 8007ed6: 2301 movs r3, #1 + 8007ed8: 4013 ands r3, r2 + 8007eda: d022 beq.n 8007f22 + TCPH_SET_FLAG(cseg->tcphdr, TCP_FIN); + 8007edc: 687b ldr r3, [r7, #4] + 8007ede: 68db ldr r3, [r3, #12] + 8007ee0: 7b1a ldrb r2, [r3, #12] + 8007ee2: 7b5b ldrb r3, [r3, #13] + 8007ee4: 021b lsls r3, r3, #8 + 8007ee6: 4313 orrs r3, r2 + 8007ee8: b29c uxth r4, r3 + 8007eea: 2001 movs r0, #1 + 8007eec: f7fc fb92 bl 8004614 + 8007ef0: 0003 movs r3, r0 + 8007ef2: 001a movs r2, r3 + 8007ef4: 687b ldr r3, [r7, #4] + 8007ef6: 68db ldr r3, [r3, #12] + 8007ef8: 4322 orrs r2, r4 + 8007efa: b292 uxth r2, r2 + 8007efc: 21ff movs r1, #255 ; 0xff + 8007efe: 4011 ands r1, r2 + 8007f00: 000c movs r4, r1 + 8007f02: 7b19 ldrb r1, [r3, #12] + 8007f04: 2000 movs r0, #0 + 8007f06: 4001 ands r1, r0 + 8007f08: 1c08 adds r0, r1, #0 + 8007f0a: 1c21 adds r1, r4, #0 + 8007f0c: 4301 orrs r1, r0 + 8007f0e: 7319 strb r1, [r3, #12] + 8007f10: 0a12 lsrs r2, r2, #8 + 8007f12: b290 uxth r0, r2 + 8007f14: 7b5a ldrb r2, [r3, #13] + 8007f16: 2100 movs r1, #0 + 8007f18: 400a ands r2, r1 + 8007f1a: 1c11 adds r1, r2, #0 + 8007f1c: 1c02 adds r2, r0, #0 + 8007f1e: 430a orrs r2, r1 + 8007f20: 735a strb r2, [r3, #13] + } + old_seg = next; + 8007f22: 683b ldr r3, [r7, #0] + 8007f24: 60fb str r3, [r7, #12] + next = next->next; + 8007f26: 683b ldr r3, [r7, #0] + 8007f28: 681b ldr r3, [r3, #0] + 8007f2a: 603b str r3, [r7, #0] + tcp_seg_free(old_seg); + 8007f2c: 68fb ldr r3, [r7, #12] + 8007f2e: 0018 movs r0, r3 + 8007f30: f7fe fbf5 bl 800671e + while (next && + 8007f34: 683b ldr r3, [r7, #0] + 8007f36: 2b00 cmp r3, #0 + 8007f38: d017 beq.n 8007f6a + TCP_SEQ_GEQ((seqno + cseg->len), + 8007f3a: 687b ldr r3, [r7, #4] + 8007f3c: 891b ldrh r3, [r3, #8] + 8007f3e: 001a movs r2, r3 + 8007f40: 4b27 ldr r3, [pc, #156] ; (8007fe0 ) + 8007f42: 681b ldr r3, [r3, #0] + 8007f44: 18d2 adds r2, r2, r3 + 8007f46: 683b ldr r3, [r7, #0] + 8007f48: 68db ldr r3, [r3, #12] + 8007f4a: 7919 ldrb r1, [r3, #4] + 8007f4c: 7958 ldrb r0, [r3, #5] + 8007f4e: 0200 lsls r0, r0, #8 + 8007f50: 4301 orrs r1, r0 + 8007f52: 7998 ldrb r0, [r3, #6] + 8007f54: 0400 lsls r0, r0, #16 + 8007f56: 4301 orrs r1, r0 + 8007f58: 79db ldrb r3, [r3, #7] + 8007f5a: 061b lsls r3, r3, #24 + 8007f5c: 430b orrs r3, r1 + 8007f5e: 0019 movs r1, r3 + 8007f60: 683b ldr r3, [r7, #0] + 8007f62: 891b ldrh r3, [r3, #8] + 8007f64: 18cb adds r3, r1, r3 + 8007f66: 1ad3 subs r3, r2, r3 + while (next && + 8007f68: d5a9 bpl.n 8007ebe + } + if (next && + 8007f6a: 683b ldr r3, [r7, #0] + 8007f6c: 2b00 cmp r3, #0 + 8007f6e: d030 beq.n 8007fd2 + TCP_SEQ_GT(seqno + cseg->len, next->tcphdr->seqno)) { + 8007f70: 687b ldr r3, [r7, #4] + 8007f72: 891b ldrh r3, [r3, #8] + 8007f74: 001a movs r2, r3 + 8007f76: 4b1a ldr r3, [pc, #104] ; (8007fe0 ) + 8007f78: 681b ldr r3, [r3, #0] + 8007f7a: 18d2 adds r2, r2, r3 + 8007f7c: 683b ldr r3, [r7, #0] + 8007f7e: 68db ldr r3, [r3, #12] + 8007f80: 7919 ldrb r1, [r3, #4] + 8007f82: 7958 ldrb r0, [r3, #5] + 8007f84: 0200 lsls r0, r0, #8 + 8007f86: 4301 orrs r1, r0 + 8007f88: 7998 ldrb r0, [r3, #6] + 8007f8a: 0400 lsls r0, r0, #16 + 8007f8c: 4301 orrs r1, r0 + 8007f8e: 79db ldrb r3, [r3, #7] + 8007f90: 061b lsls r3, r3, #24 + 8007f92: 430b orrs r3, r1 + 8007f94: 1ad3 subs r3, r2, r3 + if (next && + 8007f96: 2b00 cmp r3, #0 + 8007f98: dd1b ble.n 8007fd2 + /* We need to trim the incoming segment. */ + cseg->len = (u16_t)(next->tcphdr->seqno - seqno); + 8007f9a: 683b ldr r3, [r7, #0] + 8007f9c: 68db ldr r3, [r3, #12] + 8007f9e: 791a ldrb r2, [r3, #4] + 8007fa0: 7959 ldrb r1, [r3, #5] + 8007fa2: 0209 lsls r1, r1, #8 + 8007fa4: 430a orrs r2, r1 + 8007fa6: 7999 ldrb r1, [r3, #6] + 8007fa8: 0409 lsls r1, r1, #16 + 8007faa: 430a orrs r2, r1 + 8007fac: 79db ldrb r3, [r3, #7] + 8007fae: 061b lsls r3, r3, #24 + 8007fb0: 4313 orrs r3, r2 + 8007fb2: b29a uxth r2, r3 + 8007fb4: 4b0a ldr r3, [pc, #40] ; (8007fe0 ) + 8007fb6: 681b ldr r3, [r3, #0] + 8007fb8: b29b uxth r3, r3 + 8007fba: 1ad3 subs r3, r2, r3 + 8007fbc: b29a uxth r2, r3 + 8007fbe: 687b ldr r3, [r7, #4] + 8007fc0: 811a strh r2, [r3, #8] + pbuf_realloc(cseg->p, cseg->len); + 8007fc2: 687b ldr r3, [r7, #4] + 8007fc4: 685a ldr r2, [r3, #4] + 8007fc6: 687b ldr r3, [r7, #4] + 8007fc8: 891b ldrh r3, [r3, #8] + 8007fca: 0019 movs r1, r3 + 8007fcc: 0010 movs r0, r2 + 8007fce: f7fd fa70 bl 80054b2 + } + } + cseg->next = next; + 8007fd2: 687b ldr r3, [r7, #4] + 8007fd4: 683a ldr r2, [r7, #0] + 8007fd6: 601a str r2, [r3, #0] +} + 8007fd8: 46c0 nop ; (mov r8, r8) + 8007fda: 46bd mov sp, r7 + 8007fdc: b005 add sp, #20 + 8007fde: bd90 pop {r4, r7, pc} + 8007fe0: 20002294 .word 0x20002294 + +08007fe4 : + * + * Called from tcp_process(). + */ +static void +tcp_receive(struct tcp_pcb *pcb) +{ + 8007fe4: b5f0 push {r4, r5, r6, r7, lr} + 8007fe6: b08d sub sp, #52 ; 0x34 + 8007fe8: af00 add r7, sp, #0 + 8007fea: 6078 str r0, [r7, #4] + struct pbuf *p; + s32_t off; + s16_t m; + u32_t right_wnd_edge; + u16_t new_tot_len; + int found_dupack = 0; + 8007fec: 2300 movs r3, #0 + 8007fee: 61bb str r3, [r7, #24] + u16_t ooseq_qlen; +#endif /* TCP_OOSEQ_MAX_BYTES || TCP_OOSEQ_MAX_PBUFS */ + + LWIP_ASSERT("tcp_receive: wrong state", pcb->state >= ESTABLISHED); + + if (flags & TCP_ACK) { + 8007ff0: 4bba ldr r3, [pc, #744] ; (80082dc ) + 8007ff2: 781b ldrb r3, [r3, #0] + 8007ff4: 001a movs r2, r3 + 8007ff6: 2310 movs r3, #16 + 8007ff8: 4013 ands r3, r2 + 8007ffa: d100 bne.n 8007ffe + 8007ffc: e2ed b.n 80085da + right_wnd_edge = pcb->snd_wnd + pcb->snd_wl2; + 8007ffe: 687b ldr r3, [r7, #4] + 8008000: 2260 movs r2, #96 ; 0x60 + 8008002: 5a9b ldrh r3, [r3, r2] + 8008004: 001a movs r2, r3 + 8008006: 687b ldr r3, [r7, #4] + 8008008: 6d9b ldr r3, [r3, #88] ; 0x58 + 800800a: 18d3 adds r3, r2, r3 + 800800c: 617b str r3, [r7, #20] + + /* Update window. */ + if (TCP_SEQ_LT(pcb->snd_wl1, seqno) || + 800800e: 687b ldr r3, [r7, #4] + 8008010: 6d5a ldr r2, [r3, #84] ; 0x54 + 8008012: 4bb3 ldr r3, [pc, #716] ; (80082e0 ) + 8008014: 681b ldr r3, [r3, #0] + 8008016: 1ad3 subs r3, r2, r3 + 8008018: d41d bmi.n 8008056 + (pcb->snd_wl1 == seqno && TCP_SEQ_LT(pcb->snd_wl2, ackno)) || + 800801a: 687b ldr r3, [r7, #4] + 800801c: 6d5a ldr r2, [r3, #84] ; 0x54 + 800801e: 4bb0 ldr r3, [pc, #704] ; (80082e0 ) + 8008020: 681b ldr r3, [r3, #0] + if (TCP_SEQ_LT(pcb->snd_wl1, seqno) || + 8008022: 429a cmp r2, r3 + 8008024: d105 bne.n 8008032 + (pcb->snd_wl1 == seqno && TCP_SEQ_LT(pcb->snd_wl2, ackno)) || + 8008026: 687b ldr r3, [r7, #4] + 8008028: 6d9a ldr r2, [r3, #88] ; 0x58 + 800802a: 4bae ldr r3, [pc, #696] ; (80082e4 ) + 800802c: 681b ldr r3, [r3, #0] + 800802e: 1ad3 subs r3, r2, r3 + 8008030: d411 bmi.n 8008056 + (pcb->snd_wl2 == ackno && tcphdr->wnd > pcb->snd_wnd)) { + 8008032: 687b ldr r3, [r7, #4] + 8008034: 6d9a ldr r2, [r3, #88] ; 0x58 + 8008036: 4bab ldr r3, [pc, #684] ; (80082e4 ) + 8008038: 681b ldr r3, [r3, #0] + (pcb->snd_wl1 == seqno && TCP_SEQ_LT(pcb->snd_wl2, ackno)) || + 800803a: 429a cmp r2, r3 + 800803c: d14f bne.n 80080de + (pcb->snd_wl2 == ackno && tcphdr->wnd > pcb->snd_wnd)) { + 800803e: 4baa ldr r3, [pc, #680] ; (80082e8 ) + 8008040: 681b ldr r3, [r3, #0] + 8008042: 7b9a ldrb r2, [r3, #14] + 8008044: 7bdb ldrb r3, [r3, #15] + 8008046: 021b lsls r3, r3, #8 + 8008048: 4313 orrs r3, r2 + 800804a: b29a uxth r2, r3 + 800804c: 687b ldr r3, [r7, #4] + 800804e: 2160 movs r1, #96 ; 0x60 + 8008050: 5a5b ldrh r3, [r3, r1] + 8008052: 429a cmp r2, r3 + 8008054: d943 bls.n 80080de + pcb->snd_wnd = tcphdr->wnd; + 8008056: 4ba4 ldr r3, [pc, #656] ; (80082e8 ) + 8008058: 681b ldr r3, [r3, #0] + 800805a: 7b9a ldrb r2, [r3, #14] + 800805c: 7bdb ldrb r3, [r3, #15] + 800805e: 021b lsls r3, r3, #8 + 8008060: 4313 orrs r3, r2 + 8008062: b299 uxth r1, r3 + 8008064: 687b ldr r3, [r7, #4] + 8008066: 2260 movs r2, #96 ; 0x60 + 8008068: 5299 strh r1, [r3, r2] + /* keep track of the biggest window announced by the remote host to calculate + the maximum segment size */ + if (pcb->snd_wnd_max < tcphdr->wnd) { + 800806a: 687b ldr r3, [r7, #4] + 800806c: 2262 movs r2, #98 ; 0x62 + 800806e: 5a9a ldrh r2, [r3, r2] + 8008070: 4b9d ldr r3, [pc, #628] ; (80082e8 ) + 8008072: 681b ldr r3, [r3, #0] + 8008074: 7b99 ldrb r1, [r3, #14] + 8008076: 7bdb ldrb r3, [r3, #15] + 8008078: 021b lsls r3, r3, #8 + 800807a: 430b orrs r3, r1 + 800807c: b29b uxth r3, r3 + 800807e: 429a cmp r2, r3 + 8008080: d209 bcs.n 8008096 + pcb->snd_wnd_max = tcphdr->wnd; + 8008082: 4b99 ldr r3, [pc, #612] ; (80082e8 ) + 8008084: 681b ldr r3, [r3, #0] + 8008086: 7b9a ldrb r2, [r3, #14] + 8008088: 7bdb ldrb r3, [r3, #15] + 800808a: 021b lsls r3, r3, #8 + 800808c: 4313 orrs r3, r2 + 800808e: b299 uxth r1, r3 + 8008090: 687b ldr r3, [r7, #4] + 8008092: 2262 movs r2, #98 ; 0x62 + 8008094: 5299 strh r1, [r3, r2] + } + pcb->snd_wl1 = seqno; + 8008096: 4b92 ldr r3, [pc, #584] ; (80082e0 ) + 8008098: 681a ldr r2, [r3, #0] + 800809a: 687b ldr r3, [r7, #4] + 800809c: 655a str r2, [r3, #84] ; 0x54 + pcb->snd_wl2 = ackno; + 800809e: 4b91 ldr r3, [pc, #580] ; (80082e4 ) + 80080a0: 681a ldr r2, [r3, #0] + 80080a2: 687b ldr r3, [r7, #4] + 80080a4: 659a str r2, [r3, #88] ; 0x58 + if (pcb->snd_wnd == 0) { + 80080a6: 687b ldr r3, [r7, #4] + 80080a8: 2260 movs r2, #96 ; 0x60 + 80080aa: 5a9b ldrh r3, [r3, r2] + 80080ac: 2b00 cmp r3, #0 + 80080ae: d10d bne.n 80080cc + if (pcb->persist_backoff == 0) { + 80080b0: 687b ldr r3, [r7, #4] + 80080b2: 2295 movs r2, #149 ; 0x95 + 80080b4: 5c9b ldrb r3, [r3, r2] + 80080b6: 2b00 cmp r3, #0 + 80080b8: d111 bne.n 80080de + /* start persist timer */ + pcb->persist_cnt = 0; + 80080ba: 687b ldr r3, [r7, #4] + 80080bc: 2294 movs r2, #148 ; 0x94 + 80080be: 2100 movs r1, #0 + 80080c0: 5499 strb r1, [r3, r2] + pcb->persist_backoff = 1; + 80080c2: 687b ldr r3, [r7, #4] + 80080c4: 2295 movs r2, #149 ; 0x95 + 80080c6: 2101 movs r1, #1 + 80080c8: 5499 strb r1, [r3, r2] + 80080ca: e008 b.n 80080de + } + } else if (pcb->persist_backoff > 0) { + 80080cc: 687b ldr r3, [r7, #4] + 80080ce: 2295 movs r2, #149 ; 0x95 + 80080d0: 5c9b ldrb r3, [r3, r2] + 80080d2: 2b00 cmp r3, #0 + 80080d4: d003 beq.n 80080de + /* stop persist timer */ + pcb->persist_backoff = 0; + 80080d6: 687b ldr r3, [r7, #4] + 80080d8: 2295 movs r2, #149 ; 0x95 + 80080da: 2100 movs r1, #0 + 80080dc: 5499 strb r1, [r3, r2] + * If it only passes 1, should reset dupack counter + * + */ + + /* Clause 1 */ + if (TCP_SEQ_LEQ(ackno, pcb->lastack)) { + 80080de: 4b81 ldr r3, [pc, #516] ; (80082e4 ) + 80080e0: 681a ldr r2, [r3, #0] + 80080e2: 687b ldr r3, [r7, #4] + 80080e4: 6c9b ldr r3, [r3, #72] ; 0x48 + 80080e6: 1ad3 subs r3, r2, r3 + 80080e8: 2b00 cmp r3, #0 + 80080ea: dc58 bgt.n 800819e + pcb->acked = 0; + 80080ec: 687b ldr r3, [r7, #4] + 80080ee: 2264 movs r2, #100 ; 0x64 + 80080f0: 2100 movs r1, #0 + 80080f2: 5299 strh r1, [r3, r2] + /* Clause 2 */ + if (tcplen == 0) { + 80080f4: 4b7d ldr r3, [pc, #500] ; (80082ec ) + 80080f6: 881b ldrh r3, [r3, #0] + 80080f8: 2b00 cmp r3, #0 + 80080fa: d147 bne.n 800818c + /* Clause 3 */ + if (pcb->snd_wl2 + pcb->snd_wnd == right_wnd_edge){ + 80080fc: 687b ldr r3, [r7, #4] + 80080fe: 6d9b ldr r3, [r3, #88] ; 0x58 + 8008100: 687a ldr r2, [r7, #4] + 8008102: 2160 movs r1, #96 ; 0x60 + 8008104: 5a52 ldrh r2, [r2, r1] + 8008106: 189b adds r3, r3, r2 + 8008108: 697a ldr r2, [r7, #20] + 800810a: 429a cmp r2, r3 + 800810c: d13e bne.n 800818c + /* Clause 4 */ + if (pcb->rtime >= 0) { + 800810e: 687b ldr r3, [r7, #4] + 8008110: 2234 movs r2, #52 ; 0x34 + 8008112: 5e9b ldrsh r3, [r3, r2] + 8008114: 2b00 cmp r3, #0 + 8008116: db39 blt.n 800818c + /* Clause 5 */ + if (pcb->lastack == ackno) { + 8008118: 687b ldr r3, [r7, #4] + 800811a: 6c9a ldr r2, [r3, #72] ; 0x48 + 800811c: 4b71 ldr r3, [pc, #452] ; (80082e4 ) + 800811e: 681b ldr r3, [r3, #0] + 8008120: 429a cmp r2, r3 + 8008122: d133 bne.n 800818c + found_dupack = 1; + 8008124: 2301 movs r3, #1 + 8008126: 61bb str r3, [r7, #24] + if ((u8_t)(pcb->dupacks + 1) > pcb->dupacks) { + 8008128: 687b ldr r3, [r7, #4] + 800812a: 2247 movs r2, #71 ; 0x47 + 800812c: 5c9b ldrb r3, [r3, r2] + 800812e: 2bff cmp r3, #255 ; 0xff + 8008130: d007 beq.n 8008142 + ++pcb->dupacks; + 8008132: 687b ldr r3, [r7, #4] + 8008134: 2247 movs r2, #71 ; 0x47 + 8008136: 5c9b ldrb r3, [r3, r2] + 8008138: 3301 adds r3, #1 + 800813a: b2d9 uxtb r1, r3 + 800813c: 687b ldr r3, [r7, #4] + 800813e: 2247 movs r2, #71 ; 0x47 + 8008140: 5499 strb r1, [r3, r2] + } + if (pcb->dupacks > 3) { + 8008142: 687b ldr r3, [r7, #4] + 8008144: 2247 movs r2, #71 ; 0x47 + 8008146: 5c9b ldrb r3, [r3, r2] + 8008148: 2b03 cmp r3, #3 + 800814a: d916 bls.n 800817a + /* Inflate the congestion window, but not if it means that + the value overflows. */ + if ((u16_t)(pcb->cwnd + pcb->mss) > pcb->cwnd) { + 800814c: 687b ldr r3, [r7, #4] + 800814e: 224c movs r2, #76 ; 0x4c + 8008150: 5a9a ldrh r2, [r3, r2] + 8008152: 687b ldr r3, [r7, #4] + 8008154: 8edb ldrh r3, [r3, #54] ; 0x36 + 8008156: 18d3 adds r3, r2, r3 + 8008158: b29a uxth r2, r3 + 800815a: 687b ldr r3, [r7, #4] + 800815c: 214c movs r1, #76 ; 0x4c + 800815e: 5a5b ldrh r3, [r3, r1] + 8008160: 429a cmp r2, r3 + 8008162: d913 bls.n 800818c + pcb->cwnd += pcb->mss; + 8008164: 687b ldr r3, [r7, #4] + 8008166: 224c movs r2, #76 ; 0x4c + 8008168: 5a9a ldrh r2, [r3, r2] + 800816a: 687b ldr r3, [r7, #4] + 800816c: 8edb ldrh r3, [r3, #54] ; 0x36 + 800816e: 18d3 adds r3, r2, r3 + 8008170: b299 uxth r1, r3 + 8008172: 687b ldr r3, [r7, #4] + 8008174: 224c movs r2, #76 ; 0x4c + 8008176: 5299 strh r1, [r3, r2] + 8008178: e008 b.n 800818c + } + } else if (pcb->dupacks == 3) { + 800817a: 687b ldr r3, [r7, #4] + 800817c: 2247 movs r2, #71 ; 0x47 + 800817e: 5c9b ldrb r3, [r3, r2] + 8008180: 2b03 cmp r3, #3 + 8008182: d103 bne.n 800818c + /* Do fast retransmit */ + tcp_rexmit_fast(pcb); + 8008184: 687b ldr r3, [r7, #4] + 8008186: 0018 movs r0, r3 + 8008188: f002 f8d2 bl 800a330 + } + } + } + /* If Clause (1) or more is true, but not a duplicate ack, reset + * count of consecutive duplicate acks */ + if (!found_dupack) { + 800818c: 69bb ldr r3, [r7, #24] + 800818e: 2b00 cmp r3, #0 + 8008190: d000 beq.n 8008194 + 8008192: e184 b.n 800849e + pcb->dupacks = 0; + 8008194: 687b ldr r3, [r7, #4] + 8008196: 2247 movs r2, #71 ; 0x47 + 8008198: 2100 movs r1, #0 + 800819a: 5499 strb r1, [r3, r2] + 800819c: e17f b.n 800849e + } + } else if (TCP_SEQ_BETWEEN(ackno, pcb->lastack+1, pcb->snd_nxt)){ + 800819e: 4b51 ldr r3, [pc, #324] ; (80082e4 ) + 80081a0: 681a ldr r2, [r3, #0] + 80081a2: 687b ldr r3, [r7, #4] + 80081a4: 6c9b ldr r3, [r3, #72] ; 0x48 + 80081a6: 1ad3 subs r3, r2, r3 + 80081a8: 3b01 subs r3, #1 + 80081aa: 2b00 cmp r3, #0 + 80081ac: da00 bge.n 80081b0 + 80081ae: e125 b.n 80083fc + 80081b0: 4b4c ldr r3, [pc, #304] ; (80082e4 ) + 80081b2: 681a ldr r2, [r3, #0] + 80081b4: 687b ldr r3, [r7, #4] + 80081b6: 6d1b ldr r3, [r3, #80] ; 0x50 + 80081b8: 1ad3 subs r3, r2, r3 + 80081ba: 2b00 cmp r3, #0 + 80081bc: dd00 ble.n 80081c0 + 80081be: e11d b.n 80083fc + /* We come here when the ACK acknowledges new data. */ + + /* Reset the "IN Fast Retransmit" flag, since we are no longer + in fast retransmit. Also reset the congestion window to the + slow start threshold. */ + if (pcb->flags & TF_INFR) { + 80081c0: 687b ldr r3, [r7, #4] + 80081c2: 7f9b ldrb r3, [r3, #30] + 80081c4: 001a movs r2, r3 + 80081c6: 2304 movs r3, #4 + 80081c8: 4013 ands r3, r2 + 80081ca: d00c beq.n 80081e6 + pcb->flags &= ~TF_INFR; + 80081cc: 687b ldr r3, [r7, #4] + 80081ce: 7f9b ldrb r3, [r3, #30] + 80081d0: 2204 movs r2, #4 + 80081d2: 4393 bics r3, r2 + 80081d4: b2da uxtb r2, r3 + 80081d6: 687b ldr r3, [r7, #4] + 80081d8: 779a strb r2, [r3, #30] + pcb->cwnd = pcb->ssthresh; + 80081da: 687b ldr r3, [r7, #4] + 80081dc: 224e movs r2, #78 ; 0x4e + 80081de: 5a99 ldrh r1, [r3, r2] + 80081e0: 687b ldr r3, [r7, #4] + 80081e2: 224c movs r2, #76 ; 0x4c + 80081e4: 5299 strh r1, [r3, r2] + } + + /* Reset the number of retransmissions. */ + pcb->nrtx = 0; + 80081e6: 687b ldr r3, [r7, #4] + 80081e8: 2246 movs r2, #70 ; 0x46 + 80081ea: 2100 movs r1, #0 + 80081ec: 5499 strb r1, [r3, r2] + + /* Reset the retransmission time-out. */ + pcb->rto = (pcb->sa >> 3) + pcb->sv; + 80081ee: 687b ldr r3, [r7, #4] + 80081f0: 2240 movs r2, #64 ; 0x40 + 80081f2: 5e9b ldrsh r3, [r3, r2] + 80081f4: 10db asrs r3, r3, #3 + 80081f6: b21b sxth r3, r3 + 80081f8: b29a uxth r2, r3 + 80081fa: 687b ldr r3, [r7, #4] + 80081fc: 2142 movs r1, #66 ; 0x42 + 80081fe: 5e5b ldrsh r3, [r3, r1] + 8008200: b29b uxth r3, r3 + 8008202: 18d3 adds r3, r2, r3 + 8008204: b29b uxth r3, r3 + 8008206: b219 sxth r1, r3 + 8008208: 687b ldr r3, [r7, #4] + 800820a: 2244 movs r2, #68 ; 0x44 + 800820c: 5299 strh r1, [r3, r2] + + /* Update the send buffer space. Diff between the two can never exceed 64K? */ + pcb->acked = (u16_t)(ackno - pcb->lastack); + 800820e: 4b35 ldr r3, [pc, #212] ; (80082e4 ) + 8008210: 681b ldr r3, [r3, #0] + 8008212: b29a uxth r2, r3 + 8008214: 687b ldr r3, [r7, #4] + 8008216: 6c9b ldr r3, [r3, #72] ; 0x48 + 8008218: b29b uxth r3, r3 + 800821a: 1ad3 subs r3, r2, r3 + 800821c: b299 uxth r1, r3 + 800821e: 687b ldr r3, [r7, #4] + 8008220: 2264 movs r2, #100 ; 0x64 + 8008222: 5299 strh r1, [r3, r2] + + pcb->snd_buf += pcb->acked; + 8008224: 687b ldr r3, [r7, #4] + 8008226: 2266 movs r2, #102 ; 0x66 + 8008228: 5a9a ldrh r2, [r3, r2] + 800822a: 687b ldr r3, [r7, #4] + 800822c: 2164 movs r1, #100 ; 0x64 + 800822e: 5a5b ldrh r3, [r3, r1] + 8008230: 18d3 adds r3, r2, r3 + 8008232: b299 uxth r1, r3 + 8008234: 687b ldr r3, [r7, #4] + 8008236: 2266 movs r2, #102 ; 0x66 + 8008238: 5299 strh r1, [r3, r2] + + /* Reset the fast retransmit variables. */ + pcb->dupacks = 0; + 800823a: 687b ldr r3, [r7, #4] + 800823c: 2247 movs r2, #71 ; 0x47 + 800823e: 2100 movs r1, #0 + 8008240: 5499 strb r1, [r3, r2] + pcb->lastack = ackno; + 8008242: 4b28 ldr r3, [pc, #160] ; (80082e4 ) + 8008244: 681a ldr r2, [r3, #0] + 8008246: 687b ldr r3, [r7, #4] + 8008248: 649a str r2, [r3, #72] ; 0x48 + + /* Update the congestion control variables (cwnd and + ssthresh). */ + if (pcb->state >= ESTABLISHED) { + 800824a: 687b ldr r3, [r7, #4] + 800824c: 7e1b ldrb r3, [r3, #24] + 800824e: 2b03 cmp r3, #3 + 8008250: d800 bhi.n 8008254 + 8008252: e091 b.n 8008378 + if (pcb->cwnd < pcb->ssthresh) { + 8008254: 687b ldr r3, [r7, #4] + 8008256: 224c movs r2, #76 ; 0x4c + 8008258: 5a9a ldrh r2, [r3, r2] + 800825a: 687b ldr r3, [r7, #4] + 800825c: 214e movs r1, #78 ; 0x4e + 800825e: 5a5b ldrh r3, [r3, r1] + 8008260: 429a cmp r2, r3 + 8008262: d217 bcs.n 8008294 + if ((u16_t)(pcb->cwnd + pcb->mss) > pcb->cwnd) { + 8008264: 687b ldr r3, [r7, #4] + 8008266: 224c movs r2, #76 ; 0x4c + 8008268: 5a9a ldrh r2, [r3, r2] + 800826a: 687b ldr r3, [r7, #4] + 800826c: 8edb ldrh r3, [r3, #54] ; 0x36 + 800826e: 18d3 adds r3, r2, r3 + 8008270: b29a uxth r2, r3 + 8008272: 687b ldr r3, [r7, #4] + 8008274: 214c movs r1, #76 ; 0x4c + 8008276: 5a5b ldrh r3, [r3, r1] + 8008278: 429a cmp r2, r3 + 800827a: d800 bhi.n 800827e + 800827c: e07c b.n 8008378 + pcb->cwnd += pcb->mss; + 800827e: 687b ldr r3, [r7, #4] + 8008280: 224c movs r2, #76 ; 0x4c + 8008282: 5a9a ldrh r2, [r3, r2] + 8008284: 687b ldr r3, [r7, #4] + 8008286: 8edb ldrh r3, [r3, #54] ; 0x36 + 8008288: 18d3 adds r3, r2, r3 + 800828a: b299 uxth r1, r3 + 800828c: 687b ldr r3, [r7, #4] + 800828e: 224c movs r2, #76 ; 0x4c + 8008290: 5299 strh r1, [r3, r2] + 8008292: e071 b.n 8008378 + } + LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_receive: slow start cwnd %"U16_F"\n", pcb->cwnd)); + } else { + u16_t new_cwnd = (pcb->cwnd + pcb->mss * pcb->mss / pcb->cwnd); + 8008294: 687b ldr r3, [r7, #4] + 8008296: 224c movs r2, #76 ; 0x4c + 8008298: 5a9c ldrh r4, [r3, r2] + 800829a: 687b ldr r3, [r7, #4] + 800829c: 8edb ldrh r3, [r3, #54] ; 0x36 + 800829e: 001a movs r2, r3 + 80082a0: 687b ldr r3, [r7, #4] + 80082a2: 8edb ldrh r3, [r3, #54] ; 0x36 + 80082a4: 4353 muls r3, r2 + 80082a6: 0018 movs r0, r3 + 80082a8: 687b ldr r3, [r7, #4] + 80082aa: 224c movs r2, #76 ; 0x4c + 80082ac: 5a9b ldrh r3, [r3, r2] + 80082ae: 0019 movs r1, r3 + 80082b0: f7f7 ffc6 bl 8000240 <__divsi3> + 80082b4: 0003 movs r3, r0 + 80082b6: b29a uxth r2, r3 + 80082b8: 2112 movs r1, #18 + 80082ba: 187b adds r3, r7, r1 + 80082bc: 18a2 adds r2, r4, r2 + 80082be: 801a strh r2, [r3, #0] + if (new_cwnd > pcb->cwnd) { + 80082c0: 687b ldr r3, [r7, #4] + 80082c2: 224c movs r2, #76 ; 0x4c + 80082c4: 5a9b ldrh r3, [r3, r2] + 80082c6: 187a adds r2, r7, r1 + 80082c8: 8812 ldrh r2, [r2, #0] + 80082ca: 429a cmp r2, r3 + 80082cc: d954 bls.n 8008378 + pcb->cwnd = new_cwnd; + 80082ce: 687b ldr r3, [r7, #4] + 80082d0: 2212 movs r2, #18 + 80082d2: 18ba adds r2, r7, r2 + 80082d4: 214c movs r1, #76 ; 0x4c + 80082d6: 8812 ldrh r2, [r2, #0] + 80082d8: 525a strh r2, [r3, r1] + pcb->unacked != NULL? + ntohl(pcb->unacked->tcphdr->seqno) + TCP_TCPLEN(pcb->unacked): 0)); + + /* Remove segment from the unacknowledged list if the incoming + ACK acknowlegdes them. */ + while (pcb->unacked != NULL && + 80082da: e04d b.n 8008378 + 80082dc: 2000229c .word 0x2000229c + 80082e0: 20002294 .word 0x20002294 + 80082e4: 20002298 .word 0x20002298 + 80082e8: 2000228c .word 0x2000228c + 80082ec: 2000229e .word 0x2000229e + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: removing %"U32_F":%"U32_F" from pcb->unacked\n", + ntohl(pcb->unacked->tcphdr->seqno), + ntohl(pcb->unacked->tcphdr->seqno) + + TCP_TCPLEN(pcb->unacked))); + + next = pcb->unacked; + 80082f0: 687b ldr r3, [r7, #4] + 80082f2: 6f1b ldr r3, [r3, #112] ; 0x70 + 80082f4: 62fb str r3, [r7, #44] ; 0x2c + pcb->unacked = pcb->unacked->next; + 80082f6: 687b ldr r3, [r7, #4] + 80082f8: 6f1b ldr r3, [r3, #112] ; 0x70 + 80082fa: 681a ldr r2, [r3, #0] + 80082fc: 687b ldr r3, [r7, #4] + 80082fe: 671a str r2, [r3, #112] ; 0x70 + + LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_receive: queuelen %"U16_F" ... ", (u16_t)pcb->snd_queuelen)); + LWIP_ASSERT("pcb->snd_queuelen >= pbuf_clen(next->p)", (pcb->snd_queuelen >= pbuf_clen(next->p))); + 8008300: 6afb ldr r3, [r7, #44] ; 0x2c + 8008302: 685b ldr r3, [r3, #4] + 8008304: 0018 movs r0, r3 + 8008306: f7fd fa3f bl 8005788 + /* Prevent ACK for FIN to generate a sent event */ + if ((pcb->acked != 0) && ((TCPH_FLAGS(next->tcphdr) & TCP_FIN) != 0)) { + 800830a: 687b ldr r3, [r7, #4] + 800830c: 2264 movs r2, #100 ; 0x64 + 800830e: 5a9b ldrh r3, [r3, r2] + 8008310: 2b00 cmp r3, #0 + 8008312: d016 beq.n 8008342 + 8008314: 6afb ldr r3, [r7, #44] ; 0x2c + 8008316: 68db ldr r3, [r3, #12] + 8008318: 7b1a ldrb r2, [r3, #12] + 800831a: 7b5b ldrb r3, [r3, #13] + 800831c: 021b lsls r3, r3, #8 + 800831e: 4313 orrs r3, r2 + 8008320: b29b uxth r3, r3 + 8008322: 0018 movs r0, r3 + 8008324: f7fc f98c bl 8004640 + 8008328: 0003 movs r3, r0 + 800832a: 001a movs r2, r3 + 800832c: 2301 movs r3, #1 + 800832e: 4013 ands r3, r2 + 8008330: d007 beq.n 8008342 + pcb->acked--; + 8008332: 687b ldr r3, [r7, #4] + 8008334: 2264 movs r2, #100 ; 0x64 + 8008336: 5a9b ldrh r3, [r3, r2] + 8008338: 3b01 subs r3, #1 + 800833a: b299 uxth r1, r3 + 800833c: 687b ldr r3, [r7, #4] + 800833e: 2264 movs r2, #100 ; 0x64 + 8008340: 5299 strh r1, [r3, r2] + } + + pcb->snd_queuelen -= pbuf_clen(next->p); + 8008342: 6afb ldr r3, [r7, #44] ; 0x2c + 8008344: 685b ldr r3, [r3, #4] + 8008346: 0018 movs r0, r3 + 8008348: f7fd fa1e bl 8005788 + 800834c: 0003 movs r3, r0 + 800834e: 0019 movs r1, r3 + 8008350: 687b ldr r3, [r7, #4] + 8008352: 2268 movs r2, #104 ; 0x68 + 8008354: 5a9a ldrh r2, [r3, r2] + 8008356: b28b uxth r3, r1 + 8008358: 1ad3 subs r3, r2, r3 + 800835a: b299 uxth r1, r3 + 800835c: 687b ldr r3, [r7, #4] + 800835e: 2268 movs r2, #104 ; 0x68 + 8008360: 5299 strh r1, [r3, r2] + tcp_seg_free(next); + 8008362: 6afb ldr r3, [r7, #44] ; 0x2c + 8008364: 0018 movs r0, r3 + 8008366: f7fe f9da bl 800671e + + LWIP_DEBUGF(TCP_QLEN_DEBUG, ("%"U16_F" (after freeing unacked)\n", (u16_t)pcb->snd_queuelen)); + if (pcb->snd_queuelen != 0) { + 800836a: 687b ldr r3, [r7, #4] + 800836c: 2268 movs r2, #104 ; 0x68 + 800836e: 5a9b ldrh r3, [r3, r2] + 8008370: 2b00 cmp r3, #0 + 8008372: d001 beq.n 8008378 + LWIP_ASSERT("tcp_receive: valid queue length", pcb->unacked != NULL || + 8008374: 687b ldr r3, [r7, #4] + 8008376: 6f1b ldr r3, [r3, #112] ; 0x70 + while (pcb->unacked != NULL && + 8008378: 687b ldr r3, [r7, #4] + 800837a: 6f1b ldr r3, [r3, #112] ; 0x70 + 800837c: 2b00 cmp r3, #0 + 800837e: d02d beq.n 80083dc + TCP_SEQ_LEQ(ntohl(pcb->unacked->tcphdr->seqno) + + 8008380: 687b ldr r3, [r7, #4] + 8008382: 6f1b ldr r3, [r3, #112] ; 0x70 + 8008384: 68db ldr r3, [r3, #12] + 8008386: 791a ldrb r2, [r3, #4] + 8008388: 7959 ldrb r1, [r3, #5] + 800838a: 0209 lsls r1, r1, #8 + 800838c: 430a orrs r2, r1 + 800838e: 7999 ldrb r1, [r3, #6] + 8008390: 0409 lsls r1, r1, #16 + 8008392: 430a orrs r2, r1 + 8008394: 79db ldrb r3, [r3, #7] + 8008396: 061b lsls r3, r3, #24 + 8008398: 4313 orrs r3, r2 + 800839a: 0018 movs r0, r3 + 800839c: f7fc f979 bl 8004692 + 80083a0: 0004 movs r4, r0 + 80083a2: 687b ldr r3, [r7, #4] + 80083a4: 6f1b ldr r3, [r3, #112] ; 0x70 + 80083a6: 891b ldrh r3, [r3, #8] + 80083a8: 001d movs r5, r3 + 80083aa: 687b ldr r3, [r7, #4] + 80083ac: 6f1b ldr r3, [r3, #112] ; 0x70 + 80083ae: 68db ldr r3, [r3, #12] + 80083b0: 7b1a ldrb r2, [r3, #12] + 80083b2: 7b5b ldrb r3, [r3, #13] + 80083b4: 021b lsls r3, r3, #8 + 80083b6: 4313 orrs r3, r2 + 80083b8: b29b uxth r3, r3 + 80083ba: 0018 movs r0, r3 + 80083bc: f7fc f940 bl 8004640 + 80083c0: 0003 movs r3, r0 + 80083c2: 001a movs r2, r3 + 80083c4: 2303 movs r3, #3 + 80083c6: 4013 ands r3, r2 + 80083c8: 1e5a subs r2, r3, #1 + 80083ca: 4193 sbcs r3, r2 + 80083cc: b2db uxtb r3, r3 + 80083ce: 18eb adds r3, r5, r3 + 80083d0: 18e2 adds r2, r4, r3 + 80083d2: 4bd6 ldr r3, [pc, #856] ; (800872c ) + 80083d4: 681b ldr r3, [r3, #0] + 80083d6: 1ad3 subs r3, r2, r3 + while (pcb->unacked != NULL && + 80083d8: 2b00 cmp r3, #0 + 80083da: dd89 ble.n 80082f0 + } + } + + /* If there's nothing left to acknowledge, stop the retransmit + timer, otherwise reset it to start again */ + if(pcb->unacked == NULL) + 80083dc: 687b ldr r3, [r7, #4] + 80083de: 6f1b ldr r3, [r3, #112] ; 0x70 + 80083e0: 2b00 cmp r3, #0 + 80083e2: d104 bne.n 80083ee + pcb->rtime = -1; + 80083e4: 687b ldr r3, [r7, #4] + 80083e6: 2201 movs r2, #1 + 80083e8: 4252 negs r2, r2 + 80083ea: 869a strh r2, [r3, #52] ; 0x34 + 80083ec: e002 b.n 80083f4 + else + pcb->rtime = 0; + 80083ee: 687b ldr r3, [r7, #4] + 80083f0: 2200 movs r2, #0 + 80083f2: 869a strh r2, [r3, #52] ; 0x34 + + pcb->polltmr = 0; + 80083f4: 687b ldr r3, [r7, #4] + 80083f6: 2200 movs r2, #0 + 80083f8: 77da strb r2, [r3, #31] + 80083fa: e003 b.n 8008404 + } else { + /* Fix bug bug #21582: out of sequence ACK, didn't really ack anything */ + pcb->acked = 0; + 80083fc: 687b ldr r3, [r7, #4] + 80083fe: 2264 movs r2, #100 ; 0x64 + 8008400: 2100 movs r1, #0 + 8008402: 5299 strh r1, [r3, r2] + on the list are acknowledged by the ACK. This may seem + strange since an "unsent" segment shouldn't be acked. The + rationale is that lwIP puts all outstanding segments on the + ->unsent list after a retransmission, so these segments may + in fact have been sent once. */ + while (pcb->unsent != NULL && + 8008404: e04b b.n 800849e + TCP_TCPLEN(pcb->unsent), pcb->snd_nxt)) { + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: removing %"U32_F":%"U32_F" from pcb->unsent\n", + ntohl(pcb->unsent->tcphdr->seqno), ntohl(pcb->unsent->tcphdr->seqno) + + TCP_TCPLEN(pcb->unsent))); + + next = pcb->unsent; + 8008406: 687b ldr r3, [r7, #4] + 8008408: 6edb ldr r3, [r3, #108] ; 0x6c + 800840a: 62fb str r3, [r7, #44] ; 0x2c + pcb->unsent = pcb->unsent->next; + 800840c: 687b ldr r3, [r7, #4] + 800840e: 6edb ldr r3, [r3, #108] ; 0x6c + 8008410: 681a ldr r2, [r3, #0] + 8008412: 687b ldr r3, [r7, #4] + 8008414: 66da str r2, [r3, #108] ; 0x6c +#if TCP_OVERSIZE + if (pcb->unsent == NULL) { + 8008416: 687b ldr r3, [r7, #4] + 8008418: 6edb ldr r3, [r3, #108] ; 0x6c + 800841a: 2b00 cmp r3, #0 + 800841c: d103 bne.n 8008426 + pcb->unsent_oversize = 0; + 800841e: 687b ldr r3, [r7, #4] + 8008420: 226a movs r2, #106 ; 0x6a + 8008422: 2100 movs r1, #0 + 8008424: 5299 strh r1, [r3, r2] + } +#endif /* TCP_OVERSIZE */ + LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_receive: queuelen %"U16_F" ... ", (u16_t)pcb->snd_queuelen)); + LWIP_ASSERT("pcb->snd_queuelen >= pbuf_clen(next->p)", (pcb->snd_queuelen >= pbuf_clen(next->p))); + 8008426: 6afb ldr r3, [r7, #44] ; 0x2c + 8008428: 685b ldr r3, [r3, #4] + 800842a: 0018 movs r0, r3 + 800842c: f7fd f9ac bl 8005788 + /* Prevent ACK for FIN to generate a sent event */ + if ((pcb->acked != 0) && ((TCPH_FLAGS(next->tcphdr) & TCP_FIN) != 0)) { + 8008430: 687b ldr r3, [r7, #4] + 8008432: 2264 movs r2, #100 ; 0x64 + 8008434: 5a9b ldrh r3, [r3, r2] + 8008436: 2b00 cmp r3, #0 + 8008438: d016 beq.n 8008468 + 800843a: 6afb ldr r3, [r7, #44] ; 0x2c + 800843c: 68db ldr r3, [r3, #12] + 800843e: 7b1a ldrb r2, [r3, #12] + 8008440: 7b5b ldrb r3, [r3, #13] + 8008442: 021b lsls r3, r3, #8 + 8008444: 4313 orrs r3, r2 + 8008446: b29b uxth r3, r3 + 8008448: 0018 movs r0, r3 + 800844a: f7fc f8f9 bl 8004640 + 800844e: 0003 movs r3, r0 + 8008450: 001a movs r2, r3 + 8008452: 2301 movs r3, #1 + 8008454: 4013 ands r3, r2 + 8008456: d007 beq.n 8008468 + pcb->acked--; + 8008458: 687b ldr r3, [r7, #4] + 800845a: 2264 movs r2, #100 ; 0x64 + 800845c: 5a9b ldrh r3, [r3, r2] + 800845e: 3b01 subs r3, #1 + 8008460: b299 uxth r1, r3 + 8008462: 687b ldr r3, [r7, #4] + 8008464: 2264 movs r2, #100 ; 0x64 + 8008466: 5299 strh r1, [r3, r2] + } + pcb->snd_queuelen -= pbuf_clen(next->p); + 8008468: 6afb ldr r3, [r7, #44] ; 0x2c + 800846a: 685b ldr r3, [r3, #4] + 800846c: 0018 movs r0, r3 + 800846e: f7fd f98b bl 8005788 + 8008472: 0003 movs r3, r0 + 8008474: 0019 movs r1, r3 + 8008476: 687b ldr r3, [r7, #4] + 8008478: 2268 movs r2, #104 ; 0x68 + 800847a: 5a9a ldrh r2, [r3, r2] + 800847c: b28b uxth r3, r1 + 800847e: 1ad3 subs r3, r2, r3 + 8008480: b299 uxth r1, r3 + 8008482: 687b ldr r3, [r7, #4] + 8008484: 2268 movs r2, #104 ; 0x68 + 8008486: 5299 strh r1, [r3, r2] + tcp_seg_free(next); + 8008488: 6afb ldr r3, [r7, #44] ; 0x2c + 800848a: 0018 movs r0, r3 + 800848c: f7fe f947 bl 800671e + LWIP_DEBUGF(TCP_QLEN_DEBUG, ("%"U16_F" (after freeing unsent)\n", (u16_t)pcb->snd_queuelen)); + if (pcb->snd_queuelen != 0) { + 8008490: 687b ldr r3, [r7, #4] + 8008492: 2268 movs r2, #104 ; 0x68 + 8008494: 5a9b ldrh r3, [r3, r2] + 8008496: 2b00 cmp r3, #0 + 8008498: d001 beq.n 800849e + LWIP_ASSERT("tcp_receive: valid queue length", + 800849a: 687b ldr r3, [r7, #4] + 800849c: 6f1b ldr r3, [r3, #112] ; 0x70 + while (pcb->unsent != NULL && + 800849e: 687b ldr r3, [r7, #4] + 80084a0: 6edb ldr r3, [r3, #108] ; 0x6c + 80084a2: 2b00 cmp r3, #0 + 80084a4: d034 beq.n 8008510 + TCP_SEQ_BETWEEN(ackno, ntohl(pcb->unsent->tcphdr->seqno) + + 80084a6: 4ba1 ldr r3, [pc, #644] ; (800872c ) + 80084a8: 681c ldr r4, [r3, #0] + 80084aa: 687b ldr r3, [r7, #4] + 80084ac: 6edb ldr r3, [r3, #108] ; 0x6c + 80084ae: 68db ldr r3, [r3, #12] + 80084b0: 791a ldrb r2, [r3, #4] + 80084b2: 7959 ldrb r1, [r3, #5] + 80084b4: 0209 lsls r1, r1, #8 + 80084b6: 430a orrs r2, r1 + 80084b8: 7999 ldrb r1, [r3, #6] + 80084ba: 0409 lsls r1, r1, #16 + 80084bc: 430a orrs r2, r1 + 80084be: 79db ldrb r3, [r3, #7] + 80084c0: 061b lsls r3, r3, #24 + 80084c2: 4313 orrs r3, r2 + 80084c4: 0018 movs r0, r3 + 80084c6: f7fc f8e4 bl 8004692 + 80084ca: 0005 movs r5, r0 + 80084cc: 687b ldr r3, [r7, #4] + 80084ce: 6edb ldr r3, [r3, #108] ; 0x6c + 80084d0: 891b ldrh r3, [r3, #8] + 80084d2: 001e movs r6, r3 + 80084d4: 687b ldr r3, [r7, #4] + 80084d6: 6edb ldr r3, [r3, #108] ; 0x6c + 80084d8: 68db ldr r3, [r3, #12] + 80084da: 7b1a ldrb r2, [r3, #12] + 80084dc: 7b5b ldrb r3, [r3, #13] + 80084de: 021b lsls r3, r3, #8 + 80084e0: 4313 orrs r3, r2 + 80084e2: b29b uxth r3, r3 + 80084e4: 0018 movs r0, r3 + 80084e6: f7fc f8ab bl 8004640 + 80084ea: 0003 movs r3, r0 + 80084ec: 001a movs r2, r3 + 80084ee: 2303 movs r3, #3 + 80084f0: 4013 ands r3, r2 + 80084f2: 1e5a subs r2, r3, #1 + 80084f4: 4193 sbcs r3, r2 + 80084f6: b2db uxtb r3, r3 + 80084f8: 18f3 adds r3, r6, r3 + 80084fa: 18eb adds r3, r5, r3 + 80084fc: 1ae3 subs r3, r4, r3 + while (pcb->unsent != NULL && + 80084fe: d407 bmi.n 8008510 + TCP_SEQ_BETWEEN(ackno, ntohl(pcb->unsent->tcphdr->seqno) + + 8008500: 4b8a ldr r3, [pc, #552] ; (800872c ) + 8008502: 681a ldr r2, [r3, #0] + 8008504: 687b ldr r3, [r7, #4] + 8008506: 6d1b ldr r3, [r3, #80] ; 0x50 + 8008508: 1ad3 subs r3, r2, r3 + 800850a: 2b00 cmp r3, #0 + 800850c: dc00 bgt.n 8008510 + 800850e: e77a b.n 8008406 + pcb->rttest, pcb->rtseq, ackno)); + + /* RTT estimation calculations. This is done by checking if the + incoming segment acknowledges the segment we use to take a + round-trip time measurement. */ + if (pcb->rttest && TCP_SEQ_LT(pcb->rtseq, ackno)) { + 8008510: 687b ldr r3, [r7, #4] + 8008512: 6b9b ldr r3, [r3, #56] ; 0x38 + 8008514: 2b00 cmp r3, #0 + 8008516: d060 beq.n 80085da + 8008518: 687b ldr r3, [r7, #4] + 800851a: 6bda ldr r2, [r3, #60] ; 0x3c + 800851c: 4b83 ldr r3, [pc, #524] ; (800872c ) + 800851e: 681b ldr r3, [r3, #0] + 8008520: 1ad3 subs r3, r2, r3 + 8008522: d55a bpl.n 80085da + /* diff between this shouldn't exceed 32K since this are tcp timer ticks + and a round-trip shouldn't be that long... */ + m = (s16_t)(tcp_ticks - pcb->rttest); + 8008524: 4b82 ldr r3, [pc, #520] ; (8008730 ) + 8008526: 681b ldr r3, [r3, #0] + 8008528: b29a uxth r2, r3 + 800852a: 687b ldr r3, [r7, #4] + 800852c: 6b9b ldr r3, [r3, #56] ; 0x38 + 800852e: b29b uxth r3, r3 + 8008530: 1ad3 subs r3, r2, r3 + 8008532: b29a uxth r2, r3 + 8008534: 201e movs r0, #30 + 8008536: 183b adds r3, r7, r0 + 8008538: 801a strh r2, [r3, #0] + + LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: experienced rtt %"U16_F" ticks (%"U16_F" msec).\n", + m, m * TCP_SLOW_INTERVAL)); + + /* This is taken directly from VJs original code in his paper */ + m = m - (pcb->sa >> 3); + 800853a: 183b adds r3, r7, r0 + 800853c: 881a ldrh r2, [r3, #0] + 800853e: 687b ldr r3, [r7, #4] + 8008540: 2140 movs r1, #64 ; 0x40 + 8008542: 5e5b ldrsh r3, [r3, r1] + 8008544: 10db asrs r3, r3, #3 + 8008546: b21b sxth r3, r3 + 8008548: b29b uxth r3, r3 + 800854a: 1ad3 subs r3, r2, r3 + 800854c: b29a uxth r2, r3 + 800854e: 183b adds r3, r7, r0 + 8008550: 801a strh r2, [r3, #0] + pcb->sa += m; + 8008552: 687b ldr r3, [r7, #4] + 8008554: 2240 movs r2, #64 ; 0x40 + 8008556: 5e9b ldrsh r3, [r3, r2] + 8008558: b29a uxth r2, r3 + 800855a: 183b adds r3, r7, r0 + 800855c: 881b ldrh r3, [r3, #0] + 800855e: 18d3 adds r3, r2, r3 + 8008560: b29b uxth r3, r3 + 8008562: b219 sxth r1, r3 + 8008564: 687b ldr r3, [r7, #4] + 8008566: 2240 movs r2, #64 ; 0x40 + 8008568: 5299 strh r1, [r3, r2] + if (m < 0) { + 800856a: 183b adds r3, r7, r0 + 800856c: 2200 movs r2, #0 + 800856e: 5e9b ldrsh r3, [r3, r2] + 8008570: 2b00 cmp r3, #0 + 8008572: da06 bge.n 8008582 + m = -m; + 8008574: 211e movs r1, #30 + 8008576: 187b adds r3, r7, r1 + 8008578: 881b ldrh r3, [r3, #0] + 800857a: 425b negs r3, r3 + 800857c: b29a uxth r2, r3 + 800857e: 187b adds r3, r7, r1 + 8008580: 801a strh r2, [r3, #0] + } + m = m - (pcb->sv >> 2); + 8008582: 201e movs r0, #30 + 8008584: 183b adds r3, r7, r0 + 8008586: 881a ldrh r2, [r3, #0] + 8008588: 687b ldr r3, [r7, #4] + 800858a: 2142 movs r1, #66 ; 0x42 + 800858c: 5e5b ldrsh r3, [r3, r1] + 800858e: 109b asrs r3, r3, #2 + 8008590: b21b sxth r3, r3 + 8008592: b29b uxth r3, r3 + 8008594: 1ad3 subs r3, r2, r3 + 8008596: b29a uxth r2, r3 + 8008598: 183b adds r3, r7, r0 + 800859a: 801a strh r2, [r3, #0] + pcb->sv += m; + 800859c: 687b ldr r3, [r7, #4] + 800859e: 2242 movs r2, #66 ; 0x42 + 80085a0: 5e9b ldrsh r3, [r3, r2] + 80085a2: b29a uxth r2, r3 + 80085a4: 183b adds r3, r7, r0 + 80085a6: 881b ldrh r3, [r3, #0] + 80085a8: 18d3 adds r3, r2, r3 + 80085aa: b29b uxth r3, r3 + 80085ac: b219 sxth r1, r3 + 80085ae: 687b ldr r3, [r7, #4] + 80085b0: 2242 movs r2, #66 ; 0x42 + 80085b2: 5299 strh r1, [r3, r2] + pcb->rto = (pcb->sa >> 3) + pcb->sv; + 80085b4: 687b ldr r3, [r7, #4] + 80085b6: 2240 movs r2, #64 ; 0x40 + 80085b8: 5e9b ldrsh r3, [r3, r2] + 80085ba: 10db asrs r3, r3, #3 + 80085bc: b21b sxth r3, r3 + 80085be: b29a uxth r2, r3 + 80085c0: 687b ldr r3, [r7, #4] + 80085c2: 2142 movs r1, #66 ; 0x42 + 80085c4: 5e5b ldrsh r3, [r3, r1] + 80085c6: b29b uxth r3, r3 + 80085c8: 18d3 adds r3, r2, r3 + 80085ca: b29b uxth r3, r3 + 80085cc: b219 sxth r1, r3 + 80085ce: 687b ldr r3, [r7, #4] + 80085d0: 2244 movs r2, #68 ; 0x44 + 80085d2: 5299 strh r1, [r3, r2] + + LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: RTO %"U16_F" (%"U16_F" milliseconds)\n", + pcb->rto, pcb->rto * TCP_SLOW_INTERVAL)); + + pcb->rttest = 0; + 80085d4: 687b ldr r3, [r7, #4] + 80085d6: 2200 movs r2, #0 + 80085d8: 639a str r2, [r3, #56] ; 0x38 + + /* If the incoming segment contains data, we must process it + further unless the pcb already received a FIN. + (RFC 793, chapeter 3.9, "SEGMENT ARRIVES" in states CLOSE-WAIT, CLOSING, + LAST-ACK and TIME-WAIT: "Ignore the segment text.") */ + if ((tcplen > 0) && (pcb->state < CLOSE_WAIT)) { + 80085da: 4b56 ldr r3, [pc, #344] ; (8008734 ) + 80085dc: 881b ldrh r3, [r3, #0] + 80085de: 2b00 cmp r3, #0 + 80085e0: d101 bne.n 80085e6 + 80085e2: f000 fd83 bl 80090ec + 80085e6: 687b ldr r3, [r7, #4] + 80085e8: 7e1b ldrb r3, [r3, #24] + 80085ea: 2b06 cmp r3, #6 + 80085ec: d901 bls.n 80085f2 + 80085ee: f000 fd7d bl 80090ec + this if the sequence number of the incoming segment is less + than rcv_nxt, and the sequence number plus the length of the + segment is larger than rcv_nxt. */ + /* if (TCP_SEQ_LT(seqno, pcb->rcv_nxt)){ + if (TCP_SEQ_LT(pcb->rcv_nxt, seqno + tcplen)) {*/ + if (TCP_SEQ_BETWEEN(pcb->rcv_nxt, seqno + 1, seqno + tcplen - 1)){ + 80085f2: 687b ldr r3, [r7, #4] + 80085f4: 6a9a ldr r2, [r3, #40] ; 0x28 + 80085f6: 4b50 ldr r3, [pc, #320] ; (8008738 ) + 80085f8: 681b ldr r3, [r3, #0] + 80085fa: 1ad3 subs r3, r2, r3 + 80085fc: 3b01 subs r3, #1 + 80085fe: 2b00 cmp r3, #0 + 8008600: da00 bge.n 8008604 + 8008602: e09d b.n 8008740 + 8008604: 687b ldr r3, [r7, #4] + 8008606: 6a9a ldr r2, [r3, #40] ; 0x28 + 8008608: 4b4a ldr r3, [pc, #296] ; (8008734 ) + 800860a: 881b ldrh r3, [r3, #0] + 800860c: 0019 movs r1, r3 + 800860e: 4b4a ldr r3, [pc, #296] ; (8008738 ) + 8008610: 681b ldr r3, [r3, #0] + 8008612: 18cb adds r3, r1, r3 + 8008614: 1ad3 subs r3, r2, r3 + 8008616: 3301 adds r3, #1 + 8008618: 2b00 cmp r3, #0 + 800861a: dd00 ble.n 800861e + 800861c: e090 b.n 8008740 + + After we are done with adjusting the pbuf pointers we must + adjust the ->data pointer in the seg and the segment + length.*/ + + off = pcb->rcv_nxt - seqno; + 800861e: 687b ldr r3, [r7, #4] + 8008620: 6a9a ldr r2, [r3, #40] ; 0x28 + 8008622: 4b45 ldr r3, [pc, #276] ; (8008738 ) + 8008624: 681b ldr r3, [r3, #0] + 8008626: 1ad3 subs r3, r2, r3 + 8008628: 623b str r3, [r7, #32] + p = inseg.p; + 800862a: 4b44 ldr r3, [pc, #272] ; (800873c ) + 800862c: 685b ldr r3, [r3, #4] + 800862e: 627b str r3, [r7, #36] ; 0x24 + LWIP_ASSERT("inseg.p != NULL", inseg.p); + LWIP_ASSERT("insane offset!", (off < 0x7fff)); + if (inseg.p->len < off) { + 8008630: 4b42 ldr r3, [pc, #264] ; (800873c ) + 8008632: 685b ldr r3, [r3, #4] + 8008634: 895b ldrh r3, [r3, #10] + 8008636: 001a movs r2, r3 + 8008638: 6a3b ldr r3, [r7, #32] + 800863a: 4293 cmp r3, r2 + 800863c: dd2b ble.n 8008696 + LWIP_ASSERT("pbuf too short!", (((s32_t)inseg.p->tot_len) >= off)); + new_tot_len = (u16_t)(inseg.p->tot_len - off); + 800863e: 4b3f ldr r3, [pc, #252] ; (800873c ) + 8008640: 685b ldr r3, [r3, #4] + 8008642: 8919 ldrh r1, [r3, #8] + 8008644: 6a3b ldr r3, [r7, #32] + 8008646: b29a uxth r2, r3 + 8008648: 2310 movs r3, #16 + 800864a: 18fb adds r3, r7, r3 + 800864c: 1a8a subs r2, r1, r2 + 800864e: 801a strh r2, [r3, #0] + while (p->len < off) { + 8008650: e010 b.n 8008674 + off -= p->len; + 8008652: 6a7b ldr r3, [r7, #36] ; 0x24 + 8008654: 895b ldrh r3, [r3, #10] + 8008656: 001a movs r2, r3 + 8008658: 6a3b ldr r3, [r7, #32] + 800865a: 1a9b subs r3, r3, r2 + 800865c: 623b str r3, [r7, #32] + /* KJM following line changed (with addition of new_tot_len var) + to fix bug #9076 + inseg.p->tot_len -= p->len; */ + p->tot_len = new_tot_len; + 800865e: 6a7b ldr r3, [r7, #36] ; 0x24 + 8008660: 2210 movs r2, #16 + 8008662: 18ba adds r2, r7, r2 + 8008664: 8812 ldrh r2, [r2, #0] + 8008666: 811a strh r2, [r3, #8] + p->len = 0; + 8008668: 6a7b ldr r3, [r7, #36] ; 0x24 + 800866a: 2200 movs r2, #0 + 800866c: 815a strh r2, [r3, #10] + p = p->next; + 800866e: 6a7b ldr r3, [r7, #36] ; 0x24 + 8008670: 681b ldr r3, [r3, #0] + 8008672: 627b str r3, [r7, #36] ; 0x24 + while (p->len < off) { + 8008674: 6a7b ldr r3, [r7, #36] ; 0x24 + 8008676: 895b ldrh r3, [r3, #10] + 8008678: 001a movs r2, r3 + 800867a: 6a3b ldr r3, [r7, #32] + 800867c: 4293 cmp r3, r2 + 800867e: dce8 bgt.n 8008652 + } + if(pbuf_header(p, (s16_t)-off)) { + 8008680: 6a3b ldr r3, [r7, #32] + 8008682: b29b uxth r3, r3 + 8008684: 425b negs r3, r3 + 8008686: b29b uxth r3, r3 + 8008688: b21a sxth r2, r3 + 800868a: 6a7b ldr r3, [r7, #36] ; 0x24 + 800868c: 0011 movs r1, r2 + 800868e: 0018 movs r0, r3 + 8008690: f7fc ff81 bl 8005596 + 8008694: e00a b.n 80086ac + /* Do we need to cope with this failing? Assert for now */ + LWIP_ASSERT("pbuf_header failed", 0); + } + } else { + if(pbuf_header(inseg.p, (s16_t)-off)) { + 8008696: 4b29 ldr r3, [pc, #164] ; (800873c ) + 8008698: 685b ldr r3, [r3, #4] + 800869a: 6a3a ldr r2, [r7, #32] + 800869c: b292 uxth r2, r2 + 800869e: 4252 negs r2, r2 + 80086a0: b292 uxth r2, r2 + 80086a2: b212 sxth r2, r2 + 80086a4: 0011 movs r1, r2 + 80086a6: 0018 movs r0, r3 + 80086a8: f7fc ff75 bl 8005596 + /* Do we need to cope with this failing? Assert for now */ + LWIP_ASSERT("pbuf_header failed", 0); + } + } + inseg.len -= (u16_t)(pcb->rcv_nxt - seqno); + 80086ac: 4b23 ldr r3, [pc, #140] ; (800873c ) + 80086ae: 891a ldrh r2, [r3, #8] + 80086b0: 4b21 ldr r3, [pc, #132] ; (8008738 ) + 80086b2: 681b ldr r3, [r3, #0] + 80086b4: b299 uxth r1, r3 + 80086b6: 687b ldr r3, [r7, #4] + 80086b8: 6a9b ldr r3, [r3, #40] ; 0x28 + 80086ba: b29b uxth r3, r3 + 80086bc: 1acb subs r3, r1, r3 + 80086be: b29b uxth r3, r3 + 80086c0: 18d3 adds r3, r2, r3 + 80086c2: b29a uxth r2, r3 + 80086c4: 4b1d ldr r3, [pc, #116] ; (800873c ) + 80086c6: 811a strh r2, [r3, #8] + inseg.tcphdr->seqno = seqno = pcb->rcv_nxt; + 80086c8: 687b ldr r3, [r7, #4] + 80086ca: 6a9a ldr r2, [r3, #40] ; 0x28 + 80086cc: 4b1a ldr r3, [pc, #104] ; (8008738 ) + 80086ce: 601a str r2, [r3, #0] + 80086d0: 4b1a ldr r3, [pc, #104] ; (800873c ) + 80086d2: 68db ldr r3, [r3, #12] + 80086d4: 4a18 ldr r2, [pc, #96] ; (8008738 ) + 80086d6: 6812 ldr r2, [r2, #0] + 80086d8: 21ff movs r1, #255 ; 0xff + 80086da: 4011 ands r1, r2 + 80086dc: 000c movs r4, r1 + 80086de: 7919 ldrb r1, [r3, #4] + 80086e0: 2000 movs r0, #0 + 80086e2: 4001 ands r1, r0 + 80086e4: 1c08 adds r0, r1, #0 + 80086e6: 1c21 adds r1, r4, #0 + 80086e8: 4301 orrs r1, r0 + 80086ea: 7119 strb r1, [r3, #4] + 80086ec: 0a11 lsrs r1, r2, #8 + 80086ee: 20ff movs r0, #255 ; 0xff + 80086f0: 4001 ands r1, r0 + 80086f2: 000c movs r4, r1 + 80086f4: 7959 ldrb r1, [r3, #5] + 80086f6: 2000 movs r0, #0 + 80086f8: 4001 ands r1, r0 + 80086fa: 1c08 adds r0, r1, #0 + 80086fc: 1c21 adds r1, r4, #0 + 80086fe: 4301 orrs r1, r0 + 8008700: 7159 strb r1, [r3, #5] + 8008702: 0c11 lsrs r1, r2, #16 + 8008704: 20ff movs r0, #255 ; 0xff + 8008706: 4001 ands r1, r0 + 8008708: 000c movs r4, r1 + 800870a: 7999 ldrb r1, [r3, #6] + 800870c: 2000 movs r0, #0 + 800870e: 4001 ands r1, r0 + 8008710: 1c08 adds r0, r1, #0 + 8008712: 1c21 adds r1, r4, #0 + 8008714: 4301 orrs r1, r0 + 8008716: 7199 strb r1, [r3, #6] + 8008718: 0e10 lsrs r0, r2, #24 + 800871a: 79da ldrb r2, [r3, #7] + 800871c: 2100 movs r1, #0 + 800871e: 400a ands r2, r1 + 8008720: 1c11 adds r1, r2, #0 + 8008722: 1c02 adds r2, r0, #0 + 8008724: 430a orrs r2, r1 + 8008726: 71da strb r2, [r3, #7] + 8008728: e017 b.n 800875a + 800872a: 46c0 nop ; (mov r8, r8) + 800872c: 20002298 .word 0x20002298 + 8008730: 20003278 .word 0x20003278 + 8008734: 2000229e .word 0x2000229e + 8008738: 20002294 .word 0x20002294 + 800873c: 2000227c .word 0x2000227c + } + else { + if (TCP_SEQ_LT(seqno, pcb->rcv_nxt)){ + 8008740: 4b78 ldr r3, [pc, #480] ; (8008924 ) + 8008742: 681a ldr r2, [r3, #0] + 8008744: 687b ldr r3, [r7, #4] + 8008746: 6a9b ldr r3, [r3, #40] ; 0x28 + 8008748: 1ad3 subs r3, r2, r3 + 800874a: d506 bpl.n 800875a + /* the whole segment is < rcv_nxt */ + /* must be a duplicate of a packet that has already been correctly handled */ + + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: duplicate seqno %"U32_F"\n", seqno)); + tcp_ack_now(pcb); + 800874c: 687b ldr r3, [r7, #4] + 800874e: 7f9b ldrb r3, [r3, #30] + 8008750: 2202 movs r2, #2 + 8008752: 4313 orrs r3, r2 + 8008754: b2da uxtb r2, r3 + 8008756: 687b ldr r3, [r7, #4] + 8008758: 779a strb r2, [r3, #30] + } + + /* The sequence number must be within the window (above rcv_nxt + and below rcv_nxt + rcv_wnd) in order to be further + processed. */ + if (TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt, + 800875a: 4b72 ldr r3, [pc, #456] ; (8008924 ) + 800875c: 681a ldr r2, [r3, #0] + 800875e: 687b ldr r3, [r7, #4] + 8008760: 6a9b ldr r3, [r3, #40] ; 0x28 + 8008762: 1ad3 subs r3, r2, r3 + 8008764: d501 bpl.n 800876a + 8008766: f000 fcbb bl 80090e0 + 800876a: 4b6e ldr r3, [pc, #440] ; (8008924 ) + 800876c: 681a ldr r2, [r3, #0] + 800876e: 687b ldr r3, [r7, #4] + 8008770: 6a9b ldr r3, [r3, #40] ; 0x28 + 8008772: 6879 ldr r1, [r7, #4] + 8008774: 8d89 ldrh r1, [r1, #44] ; 0x2c + 8008776: 185b adds r3, r3, r1 + 8008778: 1ad3 subs r3, r2, r3 + 800877a: 3301 adds r3, #1 + 800877c: 2b00 cmp r3, #0 + 800877e: dd01 ble.n 8008784 + 8008780: f000 fcae bl 80090e0 + pcb->rcv_nxt + pcb->rcv_wnd - 1)){ + if (pcb->rcv_nxt == seqno) { + 8008784: 687b ldr r3, [r7, #4] + 8008786: 6a9a ldr r2, [r3, #40] ; 0x28 + 8008788: 4b66 ldr r3, [pc, #408] ; (8008924 ) + 800878a: 681b ldr r3, [r3, #0] + 800878c: 429a cmp r2, r3 + 800878e: d000 beq.n 8008792 + 8008790: e2be b.n 8008d10 + /* The incoming segment is the next in sequence. We check if + we have to trim the end of the segment and update rcv_nxt + and pass the data to the application. */ + tcplen = TCP_TCPLEN(&inseg); + 8008792: 4b65 ldr r3, [pc, #404] ; (8008928 ) + 8008794: 891c ldrh r4, [r3, #8] + 8008796: 4b64 ldr r3, [pc, #400] ; (8008928 ) + 8008798: 68db ldr r3, [r3, #12] + 800879a: 7b1a ldrb r2, [r3, #12] + 800879c: 7b5b ldrb r3, [r3, #13] + 800879e: 021b lsls r3, r3, #8 + 80087a0: 4313 orrs r3, r2 + 80087a2: b29b uxth r3, r3 + 80087a4: 0018 movs r0, r3 + 80087a6: f7fb ff4b bl 8004640 + 80087aa: 0003 movs r3, r0 + 80087ac: 001a movs r2, r3 + 80087ae: 2303 movs r3, #3 + 80087b0: 4013 ands r3, r2 + 80087b2: 1e5a subs r2, r3, #1 + 80087b4: 4193 sbcs r3, r2 + 80087b6: b2db uxtb r3, r3 + 80087b8: b29b uxth r3, r3 + 80087ba: 18e3 adds r3, r4, r3 + 80087bc: b29a uxth r2, r3 + 80087be: 4b5b ldr r3, [pc, #364] ; (800892c ) + 80087c0: 801a strh r2, [r3, #0] + + if (tcplen > pcb->rcv_wnd) { + 80087c2: 687b ldr r3, [r7, #4] + 80087c4: 8d9a ldrh r2, [r3, #44] ; 0x2c + 80087c6: 4b59 ldr r3, [pc, #356] ; (800892c ) + 80087c8: 881b ldrh r3, [r3, #0] + 80087ca: 429a cmp r2, r3 + 80087cc: d300 bcc.n 80087d0 + 80087ce: e07e b.n 80088ce + LWIP_DEBUGF(TCP_INPUT_DEBUG, + ("tcp_receive: other end overran receive window" + "seqno %"U32_F" len %"U16_F" right edge %"U32_F"\n", + seqno, tcplen, pcb->rcv_nxt + pcb->rcv_wnd)); + if (TCPH_FLAGS(inseg.tcphdr) & TCP_FIN) { + 80087d0: 4b55 ldr r3, [pc, #340] ; (8008928 ) + 80087d2: 68db ldr r3, [r3, #12] + 80087d4: 7b1a ldrb r2, [r3, #12] + 80087d6: 7b5b ldrb r3, [r3, #13] + 80087d8: 021b lsls r3, r3, #8 + 80087da: 4313 orrs r3, r2 + 80087dc: b29b uxth r3, r3 + 80087de: 0018 movs r0, r3 + 80087e0: f7fb ff2e bl 8004640 + 80087e4: 0003 movs r3, r0 + 80087e6: 001a movs r2, r3 + 80087e8: 2301 movs r3, #1 + 80087ea: 4013 ands r3, r2 + 80087ec: d036 beq.n 800885c + /* Must remove the FIN from the header as we're trimming + * that byte of sequence-space from the packet */ + TCPH_FLAGS_SET(inseg.tcphdr, TCPH_FLAGS(inseg.tcphdr) &~ TCP_FIN); + 80087ee: 4b4e ldr r3, [pc, #312] ; (8008928 ) + 80087f0: 68db ldr r3, [r3, #12] + 80087f2: 7b1a ldrb r2, [r3, #12] + 80087f4: 7b5b ldrb r3, [r3, #13] + 80087f6: 021b lsls r3, r3, #8 + 80087f8: 4313 orrs r3, r2 + 80087fa: b29b uxth r3, r3 + 80087fc: b21b sxth r3, r3 + 80087fe: 4a4c ldr r2, [pc, #304] ; (8008930 ) + 8008800: 4013 ands r3, r2 + 8008802: b21c sxth r4, r3 + 8008804: 4b48 ldr r3, [pc, #288] ; (8008928 ) + 8008806: 68db ldr r3, [r3, #12] + 8008808: 7b1a ldrb r2, [r3, #12] + 800880a: 7b5b ldrb r3, [r3, #13] + 800880c: 021b lsls r3, r3, #8 + 800880e: 4313 orrs r3, r2 + 8008810: b29b uxth r3, r3 + 8008812: 0018 movs r0, r3 + 8008814: f7fb ff14 bl 8004640 + 8008818: 0003 movs r3, r0 + 800881a: 001a movs r2, r3 + 800881c: 233e movs r3, #62 ; 0x3e + 800881e: 4013 ands r3, r2 + 8008820: b29b uxth r3, r3 + 8008822: 0018 movs r0, r3 + 8008824: f7fb fef6 bl 8004614 + 8008828: 0003 movs r3, r0 + 800882a: b21b sxth r3, r3 + 800882c: 4323 orrs r3, r4 + 800882e: b21a sxth r2, r3 + 8008830: 4b3d ldr r3, [pc, #244] ; (8008928 ) + 8008832: 68db ldr r3, [r3, #12] + 8008834: b292 uxth r2, r2 + 8008836: 21ff movs r1, #255 ; 0xff + 8008838: 4011 ands r1, r2 + 800883a: 000c movs r4, r1 + 800883c: 7b19 ldrb r1, [r3, #12] + 800883e: 2000 movs r0, #0 + 8008840: 4001 ands r1, r0 + 8008842: 1c08 adds r0, r1, #0 + 8008844: 1c21 adds r1, r4, #0 + 8008846: 4301 orrs r1, r0 + 8008848: 7319 strb r1, [r3, #12] + 800884a: 0a12 lsrs r2, r2, #8 + 800884c: b290 uxth r0, r2 + 800884e: 7b5a ldrb r2, [r3, #13] + 8008850: 2100 movs r1, #0 + 8008852: 400a ands r2, r1 + 8008854: 1c11 adds r1, r2, #0 + 8008856: 1c02 adds r2, r0, #0 + 8008858: 430a orrs r2, r1 + 800885a: 735a strb r2, [r3, #13] + } + /* Adjust length of segment to fit in the window. */ + inseg.len = pcb->rcv_wnd; + 800885c: 687b ldr r3, [r7, #4] + 800885e: 8d9a ldrh r2, [r3, #44] ; 0x2c + 8008860: 4b31 ldr r3, [pc, #196] ; (8008928 ) + 8008862: 811a strh r2, [r3, #8] + if (TCPH_FLAGS(inseg.tcphdr) & TCP_SYN) { + 8008864: 4b30 ldr r3, [pc, #192] ; (8008928 ) + 8008866: 68db ldr r3, [r3, #12] + 8008868: 7b1a ldrb r2, [r3, #12] + 800886a: 7b5b ldrb r3, [r3, #13] + 800886c: 021b lsls r3, r3, #8 + 800886e: 4313 orrs r3, r2 + 8008870: b29b uxth r3, r3 + 8008872: 0018 movs r0, r3 + 8008874: f7fb fee4 bl 8004640 + 8008878: 0003 movs r3, r0 + 800887a: 001a movs r2, r3 + 800887c: 2302 movs r3, #2 + 800887e: 4013 ands r3, r2 + 8008880: d005 beq.n 800888e + inseg.len -= 1; + 8008882: 4b29 ldr r3, [pc, #164] ; (8008928 ) + 8008884: 891b ldrh r3, [r3, #8] + 8008886: 3b01 subs r3, #1 + 8008888: b29a uxth r2, r3 + 800888a: 4b27 ldr r3, [pc, #156] ; (8008928 ) + 800888c: 811a strh r2, [r3, #8] + } + pbuf_realloc(inseg.p, inseg.len); + 800888e: 4b26 ldr r3, [pc, #152] ; (8008928 ) + 8008890: 685a ldr r2, [r3, #4] + 8008892: 4b25 ldr r3, [pc, #148] ; (8008928 ) + 8008894: 891b ldrh r3, [r3, #8] + 8008896: 0019 movs r1, r3 + 8008898: 0010 movs r0, r2 + 800889a: f7fc fe0a bl 80054b2 + tcplen = TCP_TCPLEN(&inseg); + 800889e: 4b22 ldr r3, [pc, #136] ; (8008928 ) + 80088a0: 891c ldrh r4, [r3, #8] + 80088a2: 4b21 ldr r3, [pc, #132] ; (8008928 ) + 80088a4: 68db ldr r3, [r3, #12] + 80088a6: 7b1a ldrb r2, [r3, #12] + 80088a8: 7b5b ldrb r3, [r3, #13] + 80088aa: 021b lsls r3, r3, #8 + 80088ac: 4313 orrs r3, r2 + 80088ae: b29b uxth r3, r3 + 80088b0: 0018 movs r0, r3 + 80088b2: f7fb fec5 bl 8004640 + 80088b6: 0003 movs r3, r0 + 80088b8: 001a movs r2, r3 + 80088ba: 2303 movs r3, #3 + 80088bc: 4013 ands r3, r2 + 80088be: 1e5a subs r2, r3, #1 + 80088c0: 4193 sbcs r3, r2 + 80088c2: b2db uxtb r3, r3 + 80088c4: b29b uxth r3, r3 + 80088c6: 18e3 adds r3, r4, r3 + 80088c8: b29a uxth r2, r3 + 80088ca: 4b18 ldr r3, [pc, #96] ; (800892c ) + 80088cc: 801a strh r2, [r3, #0] + } +#if TCP_QUEUE_OOSEQ + /* Received in-sequence data, adjust ooseq data if: + - FIN has been received or + - inseq overlaps with ooseq */ + if (pcb->ooseq != NULL) { + 80088ce: 687b ldr r3, [r7, #4] + 80088d0: 6f5b ldr r3, [r3, #116] ; 0x74 + 80088d2: 2b00 cmp r3, #0 + 80088d4: d100 bne.n 80088d8 + 80088d6: e10f b.n 8008af8 + if (TCPH_FLAGS(inseg.tcphdr) & TCP_FIN) { + 80088d8: 4b13 ldr r3, [pc, #76] ; (8008928 ) + 80088da: 68db ldr r3, [r3, #12] + 80088dc: 7b1a ldrb r2, [r3, #12] + 80088de: 7b5b ldrb r3, [r3, #13] + 80088e0: 021b lsls r3, r3, #8 + 80088e2: 4313 orrs r3, r2 + 80088e4: b29b uxth r3, r3 + 80088e6: 0018 movs r0, r3 + 80088e8: f7fb feaa bl 8004640 + 80088ec: 0003 movs r3, r0 + 80088ee: 001a movs r2, r3 + 80088f0: 2301 movs r3, #1 + 80088f2: 4013 ands r3, r2 + 80088f4: d011 beq.n 800891a + LWIP_DEBUGF(TCP_INPUT_DEBUG, + ("tcp_receive: received in-order FIN, binning ooseq queue\n")); + /* Received in-order FIN means anything that was received + * out of order must now have been received in-order, so + * bin the ooseq queue */ + while (pcb->ooseq != NULL) { + 80088f6: e00b b.n 8008910 + struct tcp_seg *old_ooseq = pcb->ooseq; + 80088f8: 687b ldr r3, [r7, #4] + 80088fa: 6f5b ldr r3, [r3, #116] ; 0x74 + 80088fc: 60bb str r3, [r7, #8] + pcb->ooseq = pcb->ooseq->next; + 80088fe: 687b ldr r3, [r7, #4] + 8008900: 6f5b ldr r3, [r3, #116] ; 0x74 + 8008902: 681a ldr r2, [r3, #0] + 8008904: 687b ldr r3, [r7, #4] + 8008906: 675a str r2, [r3, #116] ; 0x74 + tcp_seg_free(old_ooseq); + 8008908: 68bb ldr r3, [r7, #8] + 800890a: 0018 movs r0, r3 + 800890c: f7fd ff07 bl 800671e + while (pcb->ooseq != NULL) { + 8008910: 687b ldr r3, [r7, #4] + 8008912: 6f5b ldr r3, [r3, #116] ; 0x74 + 8008914: 2b00 cmp r3, #0 + 8008916: d1ef bne.n 80088f8 + 8008918: e0ee b.n 8008af8 + } + } else { + next = pcb->ooseq; + 800891a: 687b ldr r3, [r7, #4] + 800891c: 6f5b ldr r3, [r3, #116] ; 0x74 + 800891e: 62fb str r3, [r7, #44] ; 0x2c + /* Remove all segments on ooseq that are covered by inseg already. + * FIN is copied from ooseq to inseg if present. */ + while (next && + 8008920: e06a b.n 80089f8 + 8008922: 46c0 nop ; (mov r8, r8) + 8008924: 20002294 .word 0x20002294 + 8008928: 2000227c .word 0x2000227c + 800892c: 2000229e .word 0x2000229e + 8008930: ffffc0ff .word 0xffffc0ff + TCP_SEQ_GEQ(seqno + tcplen, + next->tcphdr->seqno + next->len)) { + /* inseg cannot have FIN here (already processed above) */ + if (TCPH_FLAGS(next->tcphdr) & TCP_FIN && + 8008934: 6afb ldr r3, [r7, #44] ; 0x2c + 8008936: 68db ldr r3, [r3, #12] + 8008938: 7b1a ldrb r2, [r3, #12] + 800893a: 7b5b ldrb r3, [r3, #13] + 800893c: 021b lsls r3, r3, #8 + 800893e: 4313 orrs r3, r2 + 8008940: b29b uxth r3, r3 + 8008942: 0018 movs r0, r3 + 8008944: f7fb fe7c bl 8004640 + 8008948: 0003 movs r3, r0 + 800894a: 001a movs r2, r3 + 800894c: 2301 movs r3, #1 + 800894e: 4013 ands r3, r2 + 8008950: d049 beq.n 80089e6 + (TCPH_FLAGS(inseg.tcphdr) & TCP_SYN) == 0) { + 8008952: 4bba ldr r3, [pc, #744] ; (8008c3c ) + 8008954: 68db ldr r3, [r3, #12] + 8008956: 7b1a ldrb r2, [r3, #12] + 8008958: 7b5b ldrb r3, [r3, #13] + 800895a: 021b lsls r3, r3, #8 + 800895c: 4313 orrs r3, r2 + 800895e: b29b uxth r3, r3 + 8008960: 0018 movs r0, r3 + 8008962: f7fb fe6d bl 8004640 + 8008966: 0003 movs r3, r0 + 8008968: 001a movs r2, r3 + 800896a: 2302 movs r3, #2 + 800896c: 4013 ands r3, r2 + if (TCPH_FLAGS(next->tcphdr) & TCP_FIN && + 800896e: d13a bne.n 80089e6 + TCPH_SET_FLAG(inseg.tcphdr, TCP_FIN); + 8008970: 4bb2 ldr r3, [pc, #712] ; (8008c3c ) + 8008972: 68db ldr r3, [r3, #12] + 8008974: 7b1a ldrb r2, [r3, #12] + 8008976: 7b5b ldrb r3, [r3, #13] + 8008978: 021b lsls r3, r3, #8 + 800897a: 4313 orrs r3, r2 + 800897c: b29c uxth r4, r3 + 800897e: 2001 movs r0, #1 + 8008980: f7fb fe48 bl 8004614 + 8008984: 0003 movs r3, r0 + 8008986: 001a movs r2, r3 + 8008988: 4bac ldr r3, [pc, #688] ; (8008c3c ) + 800898a: 68db ldr r3, [r3, #12] + 800898c: 4322 orrs r2, r4 + 800898e: b292 uxth r2, r2 + 8008990: 21ff movs r1, #255 ; 0xff + 8008992: 4011 ands r1, r2 + 8008994: 000c movs r4, r1 + 8008996: 7b19 ldrb r1, [r3, #12] + 8008998: 2000 movs r0, #0 + 800899a: 4001 ands r1, r0 + 800899c: 1c08 adds r0, r1, #0 + 800899e: 1c21 adds r1, r4, #0 + 80089a0: 4301 orrs r1, r0 + 80089a2: 7319 strb r1, [r3, #12] + 80089a4: 0a12 lsrs r2, r2, #8 + 80089a6: b290 uxth r0, r2 + 80089a8: 7b5a ldrb r2, [r3, #13] + 80089aa: 2100 movs r1, #0 + 80089ac: 400a ands r2, r1 + 80089ae: 1c11 adds r1, r2, #0 + 80089b0: 1c02 adds r2, r0, #0 + 80089b2: 430a orrs r2, r1 + 80089b4: 735a strb r2, [r3, #13] + tcplen = TCP_TCPLEN(&inseg); + 80089b6: 4ba1 ldr r3, [pc, #644] ; (8008c3c ) + 80089b8: 891c ldrh r4, [r3, #8] + 80089ba: 4ba0 ldr r3, [pc, #640] ; (8008c3c ) + 80089bc: 68db ldr r3, [r3, #12] + 80089be: 7b1a ldrb r2, [r3, #12] + 80089c0: 7b5b ldrb r3, [r3, #13] + 80089c2: 021b lsls r3, r3, #8 + 80089c4: 4313 orrs r3, r2 + 80089c6: b29b uxth r3, r3 + 80089c8: 0018 movs r0, r3 + 80089ca: f7fb fe39 bl 8004640 + 80089ce: 0003 movs r3, r0 + 80089d0: 001a movs r2, r3 + 80089d2: 2303 movs r3, #3 + 80089d4: 4013 ands r3, r2 + 80089d6: 1e5a subs r2, r3, #1 + 80089d8: 4193 sbcs r3, r2 + 80089da: b2db uxtb r3, r3 + 80089dc: b29b uxth r3, r3 + 80089de: 18e3 adds r3, r4, r3 + 80089e0: b29a uxth r2, r3 + 80089e2: 4b97 ldr r3, [pc, #604] ; (8008c40 ) + 80089e4: 801a strh r2, [r3, #0] + } + prev = next; + 80089e6: 6afb ldr r3, [r7, #44] ; 0x2c + 80089e8: 62bb str r3, [r7, #40] ; 0x28 + next = next->next; + 80089ea: 6afb ldr r3, [r7, #44] ; 0x2c + 80089ec: 681b ldr r3, [r3, #0] + 80089ee: 62fb str r3, [r7, #44] ; 0x2c + tcp_seg_free(prev); + 80089f0: 6abb ldr r3, [r7, #40] ; 0x28 + 80089f2: 0018 movs r0, r3 + 80089f4: f7fd fe93 bl 800671e + while (next && + 80089f8: 6afb ldr r3, [r7, #44] ; 0x2c + 80089fa: 2b00 cmp r3, #0 + 80089fc: d018 beq.n 8008a30 + TCP_SEQ_GEQ(seqno + tcplen, + 80089fe: 4b90 ldr r3, [pc, #576] ; (8008c40 ) + 8008a00: 881b ldrh r3, [r3, #0] + 8008a02: 001a movs r2, r3 + 8008a04: 4b8f ldr r3, [pc, #572] ; (8008c44 ) + 8008a06: 681b ldr r3, [r3, #0] + 8008a08: 18d2 adds r2, r2, r3 + 8008a0a: 6afb ldr r3, [r7, #44] ; 0x2c + 8008a0c: 68db ldr r3, [r3, #12] + 8008a0e: 7919 ldrb r1, [r3, #4] + 8008a10: 7958 ldrb r0, [r3, #5] + 8008a12: 0200 lsls r0, r0, #8 + 8008a14: 4301 orrs r1, r0 + 8008a16: 7998 ldrb r0, [r3, #6] + 8008a18: 0400 lsls r0, r0, #16 + 8008a1a: 4301 orrs r1, r0 + 8008a1c: 79db ldrb r3, [r3, #7] + 8008a1e: 061b lsls r3, r3, #24 + 8008a20: 430b orrs r3, r1 + 8008a22: 0019 movs r1, r3 + 8008a24: 6afb ldr r3, [r7, #44] ; 0x2c + 8008a26: 891b ldrh r3, [r3, #8] + 8008a28: 18cb adds r3, r1, r3 + 8008a2a: 1ad3 subs r3, r2, r3 + while (next && + 8008a2c: d400 bmi.n 8008a30 + 8008a2e: e781 b.n 8008934 + } + /* Now trim right side of inseg if it overlaps with the first + * segment on ooseq */ + if (next && + 8008a30: 6afb ldr r3, [r7, #44] ; 0x2c + 8008a32: 2b00 cmp r3, #0 + 8008a34: d05d beq.n 8008af2 + TCP_SEQ_GT(seqno + tcplen, + 8008a36: 4b82 ldr r3, [pc, #520] ; (8008c40 ) + 8008a38: 881b ldrh r3, [r3, #0] + 8008a3a: 001a movs r2, r3 + 8008a3c: 4b81 ldr r3, [pc, #516] ; (8008c44 ) + 8008a3e: 681b ldr r3, [r3, #0] + 8008a40: 18d2 adds r2, r2, r3 + 8008a42: 6afb ldr r3, [r7, #44] ; 0x2c + 8008a44: 68db ldr r3, [r3, #12] + 8008a46: 7919 ldrb r1, [r3, #4] + 8008a48: 7958 ldrb r0, [r3, #5] + 8008a4a: 0200 lsls r0, r0, #8 + 8008a4c: 4301 orrs r1, r0 + 8008a4e: 7998 ldrb r0, [r3, #6] + 8008a50: 0400 lsls r0, r0, #16 + 8008a52: 4301 orrs r1, r0 + 8008a54: 79db ldrb r3, [r3, #7] + 8008a56: 061b lsls r3, r3, #24 + 8008a58: 430b orrs r3, r1 + 8008a5a: 1ad3 subs r3, r2, r3 + if (next && + 8008a5c: 2b00 cmp r3, #0 + 8008a5e: dd48 ble.n 8008af2 + next->tcphdr->seqno)) { + /* inseg cannot have FIN here (already processed above) */ + inseg.len = (u16_t)(next->tcphdr->seqno - seqno); + 8008a60: 6afb ldr r3, [r7, #44] ; 0x2c + 8008a62: 68db ldr r3, [r3, #12] + 8008a64: 791a ldrb r2, [r3, #4] + 8008a66: 7959 ldrb r1, [r3, #5] + 8008a68: 0209 lsls r1, r1, #8 + 8008a6a: 430a orrs r2, r1 + 8008a6c: 7999 ldrb r1, [r3, #6] + 8008a6e: 0409 lsls r1, r1, #16 + 8008a70: 430a orrs r2, r1 + 8008a72: 79db ldrb r3, [r3, #7] + 8008a74: 061b lsls r3, r3, #24 + 8008a76: 4313 orrs r3, r2 + 8008a78: b29a uxth r2, r3 + 8008a7a: 4b72 ldr r3, [pc, #456] ; (8008c44 ) + 8008a7c: 681b ldr r3, [r3, #0] + 8008a7e: b29b uxth r3, r3 + 8008a80: 1ad3 subs r3, r2, r3 + 8008a82: b29a uxth r2, r3 + 8008a84: 4b6d ldr r3, [pc, #436] ; (8008c3c ) + 8008a86: 811a strh r2, [r3, #8] + if (TCPH_FLAGS(inseg.tcphdr) & TCP_SYN) { + 8008a88: 4b6c ldr r3, [pc, #432] ; (8008c3c ) + 8008a8a: 68db ldr r3, [r3, #12] + 8008a8c: 7b1a ldrb r2, [r3, #12] + 8008a8e: 7b5b ldrb r3, [r3, #13] + 8008a90: 021b lsls r3, r3, #8 + 8008a92: 4313 orrs r3, r2 + 8008a94: b29b uxth r3, r3 + 8008a96: 0018 movs r0, r3 + 8008a98: f7fb fdd2 bl 8004640 + 8008a9c: 0003 movs r3, r0 + 8008a9e: 001a movs r2, r3 + 8008aa0: 2302 movs r3, #2 + 8008aa2: 4013 ands r3, r2 + 8008aa4: d005 beq.n 8008ab2 + inseg.len -= 1; + 8008aa6: 4b65 ldr r3, [pc, #404] ; (8008c3c ) + 8008aa8: 891b ldrh r3, [r3, #8] + 8008aaa: 3b01 subs r3, #1 + 8008aac: b29a uxth r2, r3 + 8008aae: 4b63 ldr r3, [pc, #396] ; (8008c3c ) + 8008ab0: 811a strh r2, [r3, #8] + } + pbuf_realloc(inseg.p, inseg.len); + 8008ab2: 4b62 ldr r3, [pc, #392] ; (8008c3c ) + 8008ab4: 685a ldr r2, [r3, #4] + 8008ab6: 4b61 ldr r3, [pc, #388] ; (8008c3c ) + 8008ab8: 891b ldrh r3, [r3, #8] + 8008aba: 0019 movs r1, r3 + 8008abc: 0010 movs r0, r2 + 8008abe: f7fc fcf8 bl 80054b2 + tcplen = TCP_TCPLEN(&inseg); + 8008ac2: 4b5e ldr r3, [pc, #376] ; (8008c3c ) + 8008ac4: 891c ldrh r4, [r3, #8] + 8008ac6: 4b5d ldr r3, [pc, #372] ; (8008c3c ) + 8008ac8: 68db ldr r3, [r3, #12] + 8008aca: 7b1a ldrb r2, [r3, #12] + 8008acc: 7b5b ldrb r3, [r3, #13] + 8008ace: 021b lsls r3, r3, #8 + 8008ad0: 4313 orrs r3, r2 + 8008ad2: b29b uxth r3, r3 + 8008ad4: 0018 movs r0, r3 + 8008ad6: f7fb fdb3 bl 8004640 + 8008ada: 0003 movs r3, r0 + 8008adc: 001a movs r2, r3 + 8008ade: 2303 movs r3, #3 + 8008ae0: 4013 ands r3, r2 + 8008ae2: 1e5a subs r2, r3, #1 + 8008ae4: 4193 sbcs r3, r2 + 8008ae6: b2db uxtb r3, r3 + 8008ae8: b29b uxth r3, r3 + 8008aea: 18e3 adds r3, r4, r3 + 8008aec: b29a uxth r2, r3 + 8008aee: 4b54 ldr r3, [pc, #336] ; (8008c40 ) + 8008af0: 801a strh r2, [r3, #0] + LWIP_ASSERT("tcp_receive: segment not trimmed correctly to ooseq queue\n", + (seqno + tcplen) == next->tcphdr->seqno); + } + pcb->ooseq = next; + 8008af2: 687b ldr r3, [r7, #4] + 8008af4: 6afa ldr r2, [r7, #44] ; 0x2c + 8008af6: 675a str r2, [r3, #116] ; 0x74 + } + } +#endif /* TCP_QUEUE_OOSEQ */ + + pcb->rcv_nxt = seqno + tcplen; + 8008af8: 4b51 ldr r3, [pc, #324] ; (8008c40 ) + 8008afa: 881b ldrh r3, [r3, #0] + 8008afc: 001a movs r2, r3 + 8008afe: 4b51 ldr r3, [pc, #324] ; (8008c44 ) + 8008b00: 681b ldr r3, [r3, #0] + 8008b02: 18d2 adds r2, r2, r3 + 8008b04: 687b ldr r3, [r7, #4] + 8008b06: 629a str r2, [r3, #40] ; 0x28 + + /* Update the receiver's (our) window. */ + LWIP_ASSERT("tcp_receive: tcplen > rcv_wnd\n", pcb->rcv_wnd >= tcplen); + pcb->rcv_wnd -= tcplen; + 8008b08: 687b ldr r3, [r7, #4] + 8008b0a: 8d9a ldrh r2, [r3, #44] ; 0x2c + 8008b0c: 4b4c ldr r3, [pc, #304] ; (8008c40 ) + 8008b0e: 881b ldrh r3, [r3, #0] + 8008b10: 1ad3 subs r3, r2, r3 + 8008b12: b29a uxth r2, r3 + 8008b14: 687b ldr r3, [r7, #4] + 8008b16: 859a strh r2, [r3, #44] ; 0x2c + + tcp_update_rcv_ann_wnd(pcb); + 8008b18: 687b ldr r3, [r7, #4] + 8008b1a: 0018 movs r0, r3 + 8008b1c: f7fd fa3c bl 8005f98 + chains its data on this pbuf as well. + + If the segment was a FIN, we set the TF_GOT_FIN flag that will + be used to indicate to the application that the remote side has + closed its end of the connection. */ + if (inseg.p->tot_len > 0) { + 8008b20: 4b46 ldr r3, [pc, #280] ; (8008c3c ) + 8008b22: 685b ldr r3, [r3, #4] + 8008b24: 891b ldrh r3, [r3, #8] + 8008b26: 2b00 cmp r3, #0 + 8008b28: d006 beq.n 8008b38 + recv_data = inseg.p; + 8008b2a: 4b44 ldr r3, [pc, #272] ; (8008c3c ) + 8008b2c: 685a ldr r2, [r3, #4] + 8008b2e: 4b46 ldr r3, [pc, #280] ; (8008c48 ) + 8008b30: 601a str r2, [r3, #0] + /* Since this pbuf now is the responsibility of the + application, we delete our reference to it so that we won't + (mistakingly) deallocate it. */ + inseg.p = NULL; + 8008b32: 4b42 ldr r3, [pc, #264] ; (8008c3c ) + 8008b34: 2200 movs r2, #0 + 8008b36: 605a str r2, [r3, #4] + } + if (TCPH_FLAGS(inseg.tcphdr) & TCP_FIN) { + 8008b38: 4b40 ldr r3, [pc, #256] ; (8008c3c ) + 8008b3a: 68db ldr r3, [r3, #12] + 8008b3c: 7b1a ldrb r2, [r3, #12] + 8008b3e: 7b5b ldrb r3, [r3, #13] + 8008b40: 021b lsls r3, r3, #8 + 8008b42: 4313 orrs r3, r2 + 8008b44: b29b uxth r3, r3 + 8008b46: 0018 movs r0, r3 + 8008b48: f7fb fd7a bl 8004640 + 8008b4c: 0003 movs r3, r0 + 8008b4e: 001a movs r2, r3 + 8008b50: 2301 movs r3, #1 + 8008b52: 4013 ands r3, r2 + 8008b54: d100 bne.n 8008b58 + 8008b56: e0a7 b.n 8008ca8 + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: received FIN.\n")); + recv_flags |= TF_GOT_FIN; + 8008b58: 4b3c ldr r3, [pc, #240] ; (8008c4c ) + 8008b5a: 781b ldrb r3, [r3, #0] + 8008b5c: 2220 movs r2, #32 + 8008b5e: 4313 orrs r3, r2 + 8008b60: b2da uxtb r2, r3 + 8008b62: 4b3a ldr r3, [pc, #232] ; (8008c4c ) + 8008b64: 701a strb r2, [r3, #0] + } + +#if TCP_QUEUE_OOSEQ + /* We now check if we have segments on the ->ooseq queue that + are now in sequence. */ + while (pcb->ooseq != NULL && + 8008b66: e09f b.n 8008ca8 + pcb->ooseq->tcphdr->seqno == pcb->rcv_nxt) { + + cseg = pcb->ooseq; + 8008b68: 687b ldr r3, [r7, #4] + 8008b6a: 6f5b ldr r3, [r3, #116] ; 0x74 + 8008b6c: 60fb str r3, [r7, #12] + seqno = pcb->ooseq->tcphdr->seqno; + 8008b6e: 687b ldr r3, [r7, #4] + 8008b70: 6f5b ldr r3, [r3, #116] ; 0x74 + 8008b72: 68db ldr r3, [r3, #12] + 8008b74: 791a ldrb r2, [r3, #4] + 8008b76: 7959 ldrb r1, [r3, #5] + 8008b78: 0209 lsls r1, r1, #8 + 8008b7a: 430a orrs r2, r1 + 8008b7c: 7999 ldrb r1, [r3, #6] + 8008b7e: 0409 lsls r1, r1, #16 + 8008b80: 430a orrs r2, r1 + 8008b82: 79db ldrb r3, [r3, #7] + 8008b84: 061b lsls r3, r3, #24 + 8008b86: 4313 orrs r3, r2 + 8008b88: 001a movs r2, r3 + 8008b8a: 4b2e ldr r3, [pc, #184] ; (8008c44 ) + 8008b8c: 601a str r2, [r3, #0] + + pcb->rcv_nxt += TCP_TCPLEN(cseg); + 8008b8e: 68fb ldr r3, [r7, #12] + 8008b90: 891b ldrh r3, [r3, #8] + 8008b92: 001c movs r4, r3 + 8008b94: 68fb ldr r3, [r7, #12] + 8008b96: 68db ldr r3, [r3, #12] + 8008b98: 7b1a ldrb r2, [r3, #12] + 8008b9a: 7b5b ldrb r3, [r3, #13] + 8008b9c: 021b lsls r3, r3, #8 + 8008b9e: 4313 orrs r3, r2 + 8008ba0: b29b uxth r3, r3 + 8008ba2: 0018 movs r0, r3 + 8008ba4: f7fb fd4c bl 8004640 + 8008ba8: 0003 movs r3, r0 + 8008baa: 001a movs r2, r3 + 8008bac: 2303 movs r3, #3 + 8008bae: 4013 ands r3, r2 + 8008bb0: 1e5a subs r2, r3, #1 + 8008bb2: 4193 sbcs r3, r2 + 8008bb4: b2db uxtb r3, r3 + 8008bb6: 18e2 adds r2, r4, r3 + 8008bb8: 687b ldr r3, [r7, #4] + 8008bba: 6a9b ldr r3, [r3, #40] ; 0x28 + 8008bbc: 189a adds r2, r3, r2 + 8008bbe: 687b ldr r3, [r7, #4] + 8008bc0: 629a str r2, [r3, #40] ; 0x28 + LWIP_ASSERT("tcp_receive: ooseq tcplen > rcv_wnd\n", + 8008bc2: 68fb ldr r3, [r7, #12] + 8008bc4: 68db ldr r3, [r3, #12] + 8008bc6: 7b1a ldrb r2, [r3, #12] + 8008bc8: 7b5b ldrb r3, [r3, #13] + 8008bca: 021b lsls r3, r3, #8 + 8008bcc: 4313 orrs r3, r2 + 8008bce: b29b uxth r3, r3 + 8008bd0: 0018 movs r0, r3 + 8008bd2: f7fb fd35 bl 8004640 + pcb->rcv_wnd >= TCP_TCPLEN(cseg)); + pcb->rcv_wnd -= TCP_TCPLEN(cseg); + 8008bd6: 68fb ldr r3, [r7, #12] + 8008bd8: 891b ldrh r3, [r3, #8] + 8008bda: 001c movs r4, r3 + 8008bdc: 68fb ldr r3, [r7, #12] + 8008bde: 68db ldr r3, [r3, #12] + 8008be0: 7b1a ldrb r2, [r3, #12] + 8008be2: 7b5b ldrb r3, [r3, #13] + 8008be4: 021b lsls r3, r3, #8 + 8008be6: 4313 orrs r3, r2 + 8008be8: b29b uxth r3, r3 + 8008bea: 0018 movs r0, r3 + 8008bec: f7fb fd28 bl 8004640 + 8008bf0: 0003 movs r3, r0 + 8008bf2: 001a movs r2, r3 + 8008bf4: 2303 movs r3, #3 + 8008bf6: 4013 ands r3, r2 + 8008bf8: 1e5a subs r2, r3, #1 + 8008bfa: 4193 sbcs r3, r2 + 8008bfc: b2db uxtb r3, r3 + 8008bfe: 18e1 adds r1, r4, r3 + 8008c00: 687b ldr r3, [r7, #4] + 8008c02: 8d9a ldrh r2, [r3, #44] ; 0x2c + 8008c04: b28b uxth r3, r1 + 8008c06: 1ad3 subs r3, r2, r3 + 8008c08: b29a uxth r2, r3 + 8008c0a: 687b ldr r3, [r7, #4] + 8008c0c: 859a strh r2, [r3, #44] ; 0x2c + + tcp_update_rcv_ann_wnd(pcb); + 8008c0e: 687b ldr r3, [r7, #4] + 8008c10: 0018 movs r0, r3 + 8008c12: f7fd f9c1 bl 8005f98 + + if (cseg->p->tot_len > 0) { + 8008c16: 68fb ldr r3, [r7, #12] + 8008c18: 685b ldr r3, [r3, #4] + 8008c1a: 891b ldrh r3, [r3, #8] + 8008c1c: 2b00 cmp r3, #0 + 8008c1e: d01e beq.n 8008c5e + /* Chain this pbuf onto the pbuf that we will pass to + the application. */ + if (recv_data) { + 8008c20: 4b09 ldr r3, [pc, #36] ; (8008c48 ) + 8008c22: 681b ldr r3, [r3, #0] + 8008c24: 2b00 cmp r3, #0 + 8008c26: d013 beq.n 8008c50 + pbuf_cat(recv_data, cseg->p); + 8008c28: 4b07 ldr r3, [pc, #28] ; (8008c48 ) + 8008c2a: 681a ldr r2, [r3, #0] + 8008c2c: 68fb ldr r3, [r7, #12] + 8008c2e: 685b ldr r3, [r3, #4] + 8008c30: 0019 movs r1, r3 + 8008c32: 0010 movs r0, r2 + 8008c34: f7fc fdd5 bl 80057e2 + 8008c38: e00e b.n 8008c58 + 8008c3a: 46c0 nop ; (mov r8, r8) + 8008c3c: 2000227c .word 0x2000227c + 8008c40: 2000229e .word 0x2000229e + 8008c44: 20002294 .word 0x20002294 + 8008c48: 200022a4 .word 0x200022a4 + 8008c4c: 200022a0 .word 0x200022a0 + } else { + recv_data = cseg->p; + 8008c50: 68fb ldr r3, [r7, #12] + 8008c52: 685a ldr r2, [r3, #4] + 8008c54: 4b9b ldr r3, [pc, #620] ; (8008ec4 ) + 8008c56: 601a str r2, [r3, #0] + } + cseg->p = NULL; + 8008c58: 68fb ldr r3, [r7, #12] + 8008c5a: 2200 movs r2, #0 + 8008c5c: 605a str r2, [r3, #4] + } + if (TCPH_FLAGS(cseg->tcphdr) & TCP_FIN) { + 8008c5e: 68fb ldr r3, [r7, #12] + 8008c60: 68db ldr r3, [r3, #12] + 8008c62: 7b1a ldrb r2, [r3, #12] + 8008c64: 7b5b ldrb r3, [r3, #13] + 8008c66: 021b lsls r3, r3, #8 + 8008c68: 4313 orrs r3, r2 + 8008c6a: b29b uxth r3, r3 + 8008c6c: 0018 movs r0, r3 + 8008c6e: f7fb fce7 bl 8004640 + 8008c72: 0003 movs r3, r0 + 8008c74: 001a movs r2, r3 + 8008c76: 2301 movs r3, #1 + 8008c78: 4013 ands r3, r2 + 8008c7a: d00d beq.n 8008c98 + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: dequeued FIN.\n")); + recv_flags |= TF_GOT_FIN; + 8008c7c: 4b92 ldr r3, [pc, #584] ; (8008ec8 ) + 8008c7e: 781b ldrb r3, [r3, #0] + 8008c80: 2220 movs r2, #32 + 8008c82: 4313 orrs r3, r2 + 8008c84: b2da uxtb r2, r3 + 8008c86: 4b90 ldr r3, [pc, #576] ; (8008ec8 ) + 8008c88: 701a strb r2, [r3, #0] + if (pcb->state == ESTABLISHED) { /* force passive close or we can move to active close */ + 8008c8a: 687b ldr r3, [r7, #4] + 8008c8c: 7e1b ldrb r3, [r3, #24] + 8008c8e: 2b04 cmp r3, #4 + 8008c90: d102 bne.n 8008c98 + pcb->state = CLOSE_WAIT; + 8008c92: 687b ldr r3, [r7, #4] + 8008c94: 2207 movs r2, #7 + 8008c96: 761a strb r2, [r3, #24] + } + } + + pcb->ooseq = cseg->next; + 8008c98: 68fb ldr r3, [r7, #12] + 8008c9a: 681a ldr r2, [r3, #0] + 8008c9c: 687b ldr r3, [r7, #4] + 8008c9e: 675a str r2, [r3, #116] ; 0x74 + tcp_seg_free(cseg); + 8008ca0: 68fb ldr r3, [r7, #12] + 8008ca2: 0018 movs r0, r3 + 8008ca4: f7fd fd3b bl 800671e + while (pcb->ooseq != NULL && + 8008ca8: 687b ldr r3, [r7, #4] + 8008caa: 6f5b ldr r3, [r3, #116] ; 0x74 + 8008cac: 2b00 cmp r3, #0 + 8008cae: d012 beq.n 8008cd6 + pcb->ooseq->tcphdr->seqno == pcb->rcv_nxt) { + 8008cb0: 687b ldr r3, [r7, #4] + 8008cb2: 6f5b ldr r3, [r3, #116] ; 0x74 + 8008cb4: 68db ldr r3, [r3, #12] + 8008cb6: 791a ldrb r2, [r3, #4] + 8008cb8: 7959 ldrb r1, [r3, #5] + 8008cba: 0209 lsls r1, r1, #8 + 8008cbc: 430a orrs r2, r1 + 8008cbe: 7999 ldrb r1, [r3, #6] + 8008cc0: 0409 lsls r1, r1, #16 + 8008cc2: 430a orrs r2, r1 + 8008cc4: 79db ldrb r3, [r3, #7] + 8008cc6: 061b lsls r3, r3, #24 + 8008cc8: 4313 orrs r3, r2 + 8008cca: 001a movs r2, r3 + 8008ccc: 687b ldr r3, [r7, #4] + 8008cce: 6a9b ldr r3, [r3, #40] ; 0x28 + while (pcb->ooseq != NULL && + 8008cd0: 429a cmp r2, r3 + 8008cd2: d100 bne.n 8008cd6 + 8008cd4: e748 b.n 8008b68 + } +#endif /* TCP_QUEUE_OOSEQ */ + + + /* Acknowledge the segment(s). */ + tcp_ack(pcb); + 8008cd6: 687b ldr r3, [r7, #4] + 8008cd8: 7f9b ldrb r3, [r3, #30] + 8008cda: 001a movs r2, r3 + 8008cdc: 2301 movs r3, #1 + 8008cde: 4013 ands r3, r2 + 8008ce0: d00e beq.n 8008d00 + 8008ce2: 687b ldr r3, [r7, #4] + 8008ce4: 7f9b ldrb r3, [r3, #30] + 8008ce6: 2201 movs r2, #1 + 8008ce8: 4393 bics r3, r2 + 8008cea: b2da uxtb r2, r3 + 8008cec: 687b ldr r3, [r7, #4] + 8008cee: 779a strb r2, [r3, #30] + 8008cf0: 687b ldr r3, [r7, #4] + 8008cf2: 7f9b ldrb r3, [r3, #30] + 8008cf4: 2202 movs r2, #2 + 8008cf6: 4313 orrs r3, r2 + 8008cf8: b2da uxtb r2, r3 + 8008cfa: 687b ldr r3, [r7, #4] + 8008cfc: 779a strb r2, [r3, #30] + if (pcb->rcv_nxt == seqno) { + 8008cfe: e1f4 b.n 80090ea + tcp_ack(pcb); + 8008d00: 687b ldr r3, [r7, #4] + 8008d02: 7f9b ldrb r3, [r3, #30] + 8008d04: 2201 movs r2, #1 + 8008d06: 4313 orrs r3, r2 + 8008d08: b2da uxtb r2, r3 + 8008d0a: 687b ldr r3, [r7, #4] + 8008d0c: 779a strb r2, [r3, #30] + if (pcb->rcv_nxt == seqno) { + 8008d0e: e1ec b.n 80090ea + + } else { + /* We get here if the incoming segment is out-of-sequence. */ + tcp_send_empty_ack(pcb); + 8008d10: 687b ldr r3, [r7, #4] + 8008d12: 0018 movs r0, r3 + 8008d14: f000 fe1c bl 8009950 +#if TCP_QUEUE_OOSEQ + /* We queue the segment on the ->ooseq queue. */ + if (pcb->ooseq == NULL) { + 8008d18: 687b ldr r3, [r7, #4] + 8008d1a: 6f5b ldr r3, [r3, #116] ; 0x74 + 8008d1c: 2b00 cmp r3, #0 + 8008d1e: d107 bne.n 8008d30 + pcb->ooseq = tcp_seg_copy(&inseg); + 8008d20: 4b6a ldr r3, [pc, #424] ; (8008ecc ) + 8008d22: 0018 movs r0, r3 + 8008d24: f7fd fd14 bl 8006750 + 8008d28: 0002 movs r2, r0 + 8008d2a: 687b ldr r3, [r7, #4] + 8008d2c: 675a str r2, [r3, #116] ; 0x74 + if (pcb->rcv_nxt == seqno) { + 8008d2e: e1dc b.n 80090ea + + If the incoming segment has the same sequence number as a + segment on the ->ooseq queue, we discard the segment that + contains less data. */ + + prev = NULL; + 8008d30: 2300 movs r3, #0 + 8008d32: 62bb str r3, [r7, #40] ; 0x28 + for(next = pcb->ooseq; next != NULL; next = next->next) { + 8008d34: 687b ldr r3, [r7, #4] + 8008d36: 6f5b ldr r3, [r3, #116] ; 0x74 + 8008d38: 62fb str r3, [r7, #44] ; 0x2c + 8008d3a: e1c0 b.n 80090be + if (seqno == next->tcphdr->seqno) { + 8008d3c: 6afb ldr r3, [r7, #44] ; 0x2c + 8008d3e: 68db ldr r3, [r3, #12] + 8008d40: 791a ldrb r2, [r3, #4] + 8008d42: 7959 ldrb r1, [r3, #5] + 8008d44: 0209 lsls r1, r1, #8 + 8008d46: 430a orrs r2, r1 + 8008d48: 7999 ldrb r1, [r3, #6] + 8008d4a: 0409 lsls r1, r1, #16 + 8008d4c: 430a orrs r2, r1 + 8008d4e: 79db ldrb r3, [r3, #7] + 8008d50: 061b lsls r3, r3, #24 + 8008d52: 4313 orrs r3, r2 + 8008d54: 001a movs r2, r3 + 8008d56: 4b5e ldr r3, [pc, #376] ; (8008ed0 ) + 8008d58: 681b ldr r3, [r3, #0] + 8008d5a: 429a cmp r2, r3 + 8008d5c: d121 bne.n 8008da2 + /* The sequence number of the incoming segment is the + same as the sequence number of the segment on + ->ooseq. We check the lengths to see which one to + discard. */ + if (inseg.len > next->len) { + 8008d5e: 4b5b ldr r3, [pc, #364] ; (8008ecc ) + 8008d60: 891a ldrh r2, [r3, #8] + 8008d62: 6afb ldr r3, [r7, #44] ; 0x2c + 8008d64: 891b ldrh r3, [r3, #8] + 8008d66: 429a cmp r2, r3 + 8008d68: d800 bhi.n 8008d6c + 8008d6a: e1ad b.n 80090c8 + /* The incoming segment is larger than the old + segment. We replace some segments with the new + one. */ + cseg = tcp_seg_copy(&inseg); + 8008d6c: 4b57 ldr r3, [pc, #348] ; (8008ecc ) + 8008d6e: 0018 movs r0, r3 + 8008d70: f7fd fcee bl 8006750 + 8008d74: 0003 movs r3, r0 + 8008d76: 60fb str r3, [r7, #12] + if (cseg != NULL) { + 8008d78: 68fb ldr r3, [r7, #12] + 8008d7a: 2b00 cmp r3, #0 + 8008d7c: d100 bne.n 8008d80 + 8008d7e: e1a5 b.n 80090cc + if (prev != NULL) { + 8008d80: 6abb ldr r3, [r7, #40] ; 0x28 + 8008d82: 2b00 cmp r3, #0 + 8008d84: d003 beq.n 8008d8e + prev->next = cseg; + 8008d86: 6abb ldr r3, [r7, #40] ; 0x28 + 8008d88: 68fa ldr r2, [r7, #12] + 8008d8a: 601a str r2, [r3, #0] + 8008d8c: e002 b.n 8008d94 + } else { + pcb->ooseq = cseg; + 8008d8e: 687b ldr r3, [r7, #4] + 8008d90: 68fa ldr r2, [r7, #12] + 8008d92: 675a str r2, [r3, #116] ; 0x74 + } + tcp_oos_insert_segment(cseg, next); + 8008d94: 6afa ldr r2, [r7, #44] ; 0x2c + 8008d96: 68fb ldr r3, [r7, #12] + 8008d98: 0011 movs r1, r2 + 8008d9a: 0018 movs r0, r3 + 8008d9c: f7ff f874 bl 8007e88 + } + break; + 8008da0: e194 b.n 80090cc + segment was smaller than the old one; in either + case, we ditch the incoming segment. */ + break; + } + } else { + if (prev == NULL) { + 8008da2: 6abb ldr r3, [r7, #40] ; 0x28 + 8008da4: 2b00 cmp r3, #0 + 8008da6: d124 bne.n 8008df2 + if (TCP_SEQ_LT(seqno, next->tcphdr->seqno)) { + 8008da8: 4b49 ldr r3, [pc, #292] ; (8008ed0 ) + 8008daa: 681a ldr r2, [r3, #0] + 8008dac: 6afb ldr r3, [r7, #44] ; 0x2c + 8008dae: 68db ldr r3, [r3, #12] + 8008db0: 7919 ldrb r1, [r3, #4] + 8008db2: 7958 ldrb r0, [r3, #5] + 8008db4: 0200 lsls r0, r0, #8 + 8008db6: 4301 orrs r1, r0 + 8008db8: 7998 ldrb r0, [r3, #6] + 8008dba: 0400 lsls r0, r0, #16 + 8008dbc: 4301 orrs r1, r0 + 8008dbe: 79db ldrb r3, [r3, #7] + 8008dc0: 061b lsls r3, r3, #24 + 8008dc2: 430b orrs r3, r1 + 8008dc4: 1ad3 subs r3, r2, r3 + 8008dc6: d400 bmi.n 8008dca + 8008dc8: e084 b.n 8008ed4 + /* The sequence number of the incoming segment is lower + than the sequence number of the first segment on the + queue. We put the incoming segment first on the + queue. */ + cseg = tcp_seg_copy(&inseg); + 8008dca: 4b40 ldr r3, [pc, #256] ; (8008ecc ) + 8008dcc: 0018 movs r0, r3 + 8008dce: f7fd fcbf bl 8006750 + 8008dd2: 0003 movs r3, r0 + 8008dd4: 60fb str r3, [r7, #12] + if (cseg != NULL) { + 8008dd6: 68fb ldr r3, [r7, #12] + 8008dd8: 2b00 cmp r3, #0 + 8008dda: d100 bne.n 8008dde + 8008ddc: e178 b.n 80090d0 + pcb->ooseq = cseg; + 8008dde: 687b ldr r3, [r7, #4] + 8008de0: 68fa ldr r2, [r7, #12] + 8008de2: 675a str r2, [r3, #116] ; 0x74 + tcp_oos_insert_segment(cseg, next); + 8008de4: 6afa ldr r2, [r7, #44] ; 0x2c + 8008de6: 68fb ldr r3, [r7, #12] + 8008de8: 0011 movs r1, r2 + 8008dea: 0018 movs r0, r3 + 8008dec: f7ff f84c bl 8007e88 + } + break; + 8008df0: e16e b.n 80090d0 + } + } else { + /*if (TCP_SEQ_LT(prev->tcphdr->seqno, seqno) && + TCP_SEQ_LT(seqno, next->tcphdr->seqno)) {*/ + if (TCP_SEQ_BETWEEN(seqno, prev->tcphdr->seqno+1, next->tcphdr->seqno-1)) { + 8008df2: 4b37 ldr r3, [pc, #220] ; (8008ed0 ) + 8008df4: 681a ldr r2, [r3, #0] + 8008df6: 6abb ldr r3, [r7, #40] ; 0x28 + 8008df8: 68db ldr r3, [r3, #12] + 8008dfa: 7919 ldrb r1, [r3, #4] + 8008dfc: 7958 ldrb r0, [r3, #5] + 8008dfe: 0200 lsls r0, r0, #8 + 8008e00: 4301 orrs r1, r0 + 8008e02: 7998 ldrb r0, [r3, #6] + 8008e04: 0400 lsls r0, r0, #16 + 8008e06: 4301 orrs r1, r0 + 8008e08: 79db ldrb r3, [r3, #7] + 8008e0a: 061b lsls r3, r3, #24 + 8008e0c: 430b orrs r3, r1 + 8008e0e: 1ad3 subs r3, r2, r3 + 8008e10: 3b01 subs r3, #1 + 8008e12: 2b00 cmp r3, #0 + 8008e14: db5e blt.n 8008ed4 + 8008e16: 4b2e ldr r3, [pc, #184] ; (8008ed0 ) + 8008e18: 681a ldr r2, [r3, #0] + 8008e1a: 6afb ldr r3, [r7, #44] ; 0x2c + 8008e1c: 68db ldr r3, [r3, #12] + 8008e1e: 7919 ldrb r1, [r3, #4] + 8008e20: 7958 ldrb r0, [r3, #5] + 8008e22: 0200 lsls r0, r0, #8 + 8008e24: 4301 orrs r1, r0 + 8008e26: 7998 ldrb r0, [r3, #6] + 8008e28: 0400 lsls r0, r0, #16 + 8008e2a: 4301 orrs r1, r0 + 8008e2c: 79db ldrb r3, [r3, #7] + 8008e2e: 061b lsls r3, r3, #24 + 8008e30: 430b orrs r3, r1 + 8008e32: 1ad3 subs r3, r2, r3 + 8008e34: 3301 adds r3, #1 + 8008e36: 2b00 cmp r3, #0 + 8008e38: dc4c bgt.n 8008ed4 + /* The sequence number of the incoming segment is in + between the sequence numbers of the previous and + the next segment on ->ooseq. We trim trim the previous + segment, delete next segments that included in received segment + and trim received, if needed. */ + cseg = tcp_seg_copy(&inseg); + 8008e3a: 4b24 ldr r3, [pc, #144] ; (8008ecc ) + 8008e3c: 0018 movs r0, r3 + 8008e3e: f7fd fc87 bl 8006750 + 8008e42: 0003 movs r3, r0 + 8008e44: 60fb str r3, [r7, #12] + if (cseg != NULL) { + 8008e46: 68fb ldr r3, [r7, #12] + 8008e48: 2b00 cmp r3, #0 + 8008e4a: d100 bne.n 8008e4e + 8008e4c: e142 b.n 80090d4 + if (TCP_SEQ_GT(prev->tcphdr->seqno + prev->len, seqno)) { + 8008e4e: 6abb ldr r3, [r7, #40] ; 0x28 + 8008e50: 68db ldr r3, [r3, #12] + 8008e52: 791a ldrb r2, [r3, #4] + 8008e54: 7959 ldrb r1, [r3, #5] + 8008e56: 0209 lsls r1, r1, #8 + 8008e58: 430a orrs r2, r1 + 8008e5a: 7999 ldrb r1, [r3, #6] + 8008e5c: 0409 lsls r1, r1, #16 + 8008e5e: 430a orrs r2, r1 + 8008e60: 79db ldrb r3, [r3, #7] + 8008e62: 061b lsls r3, r3, #24 + 8008e64: 4313 orrs r3, r2 + 8008e66: 001a movs r2, r3 + 8008e68: 6abb ldr r3, [r7, #40] ; 0x28 + 8008e6a: 891b ldrh r3, [r3, #8] + 8008e6c: 18d2 adds r2, r2, r3 + 8008e6e: 4b18 ldr r3, [pc, #96] ; (8008ed0 ) + 8008e70: 681b ldr r3, [r3, #0] + 8008e72: 1ad3 subs r3, r2, r3 + 8008e74: 2b00 cmp r3, #0 + 8008e76: dd1b ble.n 8008eb0 + /* We need to trim the prev segment. */ + prev->len = (u16_t)(seqno - prev->tcphdr->seqno); + 8008e78: 4b15 ldr r3, [pc, #84] ; (8008ed0 ) + 8008e7a: 681b ldr r3, [r3, #0] + 8008e7c: b29a uxth r2, r3 + 8008e7e: 6abb ldr r3, [r7, #40] ; 0x28 + 8008e80: 68db ldr r3, [r3, #12] + 8008e82: 7919 ldrb r1, [r3, #4] + 8008e84: 7958 ldrb r0, [r3, #5] + 8008e86: 0200 lsls r0, r0, #8 + 8008e88: 4301 orrs r1, r0 + 8008e8a: 7998 ldrb r0, [r3, #6] + 8008e8c: 0400 lsls r0, r0, #16 + 8008e8e: 4301 orrs r1, r0 + 8008e90: 79db ldrb r3, [r3, #7] + 8008e92: 061b lsls r3, r3, #24 + 8008e94: 430b orrs r3, r1 + 8008e96: b29b uxth r3, r3 + 8008e98: 1ad3 subs r3, r2, r3 + 8008e9a: b29a uxth r2, r3 + 8008e9c: 6abb ldr r3, [r7, #40] ; 0x28 + 8008e9e: 811a strh r2, [r3, #8] + pbuf_realloc(prev->p, prev->len); + 8008ea0: 6abb ldr r3, [r7, #40] ; 0x28 + 8008ea2: 685a ldr r2, [r3, #4] + 8008ea4: 6abb ldr r3, [r7, #40] ; 0x28 + 8008ea6: 891b ldrh r3, [r3, #8] + 8008ea8: 0019 movs r1, r3 + 8008eaa: 0010 movs r0, r2 + 8008eac: f7fc fb01 bl 80054b2 + } + prev->next = cseg; + 8008eb0: 6abb ldr r3, [r7, #40] ; 0x28 + 8008eb2: 68fa ldr r2, [r7, #12] + 8008eb4: 601a str r2, [r3, #0] + tcp_oos_insert_segment(cseg, next); + 8008eb6: 6afa ldr r2, [r7, #44] ; 0x2c + 8008eb8: 68fb ldr r3, [r7, #12] + 8008eba: 0011 movs r1, r2 + 8008ebc: 0018 movs r0, r3 + 8008ebe: f7fe ffe3 bl 8007e88 + } + break; + 8008ec2: e107 b.n 80090d4 + 8008ec4: 200022a4 .word 0x200022a4 + 8008ec8: 200022a0 .word 0x200022a0 + 8008ecc: 2000227c .word 0x2000227c + 8008ed0: 20002294 .word 0x20002294 + } + } + /* If the "next" segment is the last segment on the + ooseq queue, we add the incoming segment to the end + of the list. */ + if (next->next == NULL && + 8008ed4: 6afb ldr r3, [r7, #44] ; 0x2c + 8008ed6: 681b ldr r3, [r3, #0] + 8008ed8: 2b00 cmp r3, #0 + 8008eda: d000 beq.n 8008ede + 8008edc: e0ea b.n 80090b4 + TCP_SEQ_GT(seqno, next->tcphdr->seqno)) { + 8008ede: 4b92 ldr r3, [pc, #584] ; (8009128 ) + 8008ee0: 681a ldr r2, [r3, #0] + 8008ee2: 6afb ldr r3, [r7, #44] ; 0x2c + 8008ee4: 68db ldr r3, [r3, #12] + 8008ee6: 7919 ldrb r1, [r3, #4] + 8008ee8: 7958 ldrb r0, [r3, #5] + 8008eea: 0200 lsls r0, r0, #8 + 8008eec: 4301 orrs r1, r0 + 8008eee: 7998 ldrb r0, [r3, #6] + 8008ef0: 0400 lsls r0, r0, #16 + 8008ef2: 4301 orrs r1, r0 + 8008ef4: 79db ldrb r3, [r3, #7] + 8008ef6: 061b lsls r3, r3, #24 + 8008ef8: 430b orrs r3, r1 + 8008efa: 1ad3 subs r3, r2, r3 + if (next->next == NULL && + 8008efc: 2b00 cmp r3, #0 + 8008efe: dc00 bgt.n 8008f02 + 8008f00: e0d8 b.n 80090b4 + if (TCPH_FLAGS(next->tcphdr) & TCP_FIN) { + 8008f02: 6afb ldr r3, [r7, #44] ; 0x2c + 8008f04: 68db ldr r3, [r3, #12] + 8008f06: 7b1a ldrb r2, [r3, #12] + 8008f08: 7b5b ldrb r3, [r3, #13] + 8008f0a: 021b lsls r3, r3, #8 + 8008f0c: 4313 orrs r3, r2 + 8008f0e: b29b uxth r3, r3 + 8008f10: 0018 movs r0, r3 + 8008f12: f7fb fb95 bl 8004640 + 8008f16: 0003 movs r3, r0 + 8008f18: 001a movs r2, r3 + 8008f1a: 2301 movs r3, #1 + 8008f1c: 4013 ands r3, r2 + 8008f1e: d000 beq.n 8008f22 + 8008f20: e0da b.n 80090d8 + /* segment "next" already contains all data */ + break; + } + next->next = tcp_seg_copy(&inseg); + 8008f22: 4b82 ldr r3, [pc, #520] ; (800912c ) + 8008f24: 0018 movs r0, r3 + 8008f26: f7fd fc13 bl 8006750 + 8008f2a: 0002 movs r2, r0 + 8008f2c: 6afb ldr r3, [r7, #44] ; 0x2c + 8008f2e: 601a str r2, [r3, #0] + if (next->next != NULL) { + 8008f30: 6afb ldr r3, [r7, #44] ; 0x2c + 8008f32: 681b ldr r3, [r3, #0] + 8008f34: 2b00 cmp r3, #0 + 8008f36: d100 bne.n 8008f3a + 8008f38: e0d0 b.n 80090dc + if (TCP_SEQ_GT(next->tcphdr->seqno + next->len, seqno)) { + 8008f3a: 6afb ldr r3, [r7, #44] ; 0x2c + 8008f3c: 68db ldr r3, [r3, #12] + 8008f3e: 791a ldrb r2, [r3, #4] + 8008f40: 7959 ldrb r1, [r3, #5] + 8008f42: 0209 lsls r1, r1, #8 + 8008f44: 430a orrs r2, r1 + 8008f46: 7999 ldrb r1, [r3, #6] + 8008f48: 0409 lsls r1, r1, #16 + 8008f4a: 430a orrs r2, r1 + 8008f4c: 79db ldrb r3, [r3, #7] + 8008f4e: 061b lsls r3, r3, #24 + 8008f50: 4313 orrs r3, r2 + 8008f52: 001a movs r2, r3 + 8008f54: 6afb ldr r3, [r7, #44] ; 0x2c + 8008f56: 891b ldrh r3, [r3, #8] + 8008f58: 18d2 adds r2, r2, r3 + 8008f5a: 4b73 ldr r3, [pc, #460] ; (8009128 ) + 8008f5c: 681b ldr r3, [r3, #0] + 8008f5e: 1ad3 subs r3, r2, r3 + 8008f60: 2b00 cmp r3, #0 + 8008f62: dd1b ble.n 8008f9c + /* We need to trim the last segment. */ + next->len = (u16_t)(seqno - next->tcphdr->seqno); + 8008f64: 4b70 ldr r3, [pc, #448] ; (8009128 ) + 8008f66: 681b ldr r3, [r3, #0] + 8008f68: b29a uxth r2, r3 + 8008f6a: 6afb ldr r3, [r7, #44] ; 0x2c + 8008f6c: 68db ldr r3, [r3, #12] + 8008f6e: 7919 ldrb r1, [r3, #4] + 8008f70: 7958 ldrb r0, [r3, #5] + 8008f72: 0200 lsls r0, r0, #8 + 8008f74: 4301 orrs r1, r0 + 8008f76: 7998 ldrb r0, [r3, #6] + 8008f78: 0400 lsls r0, r0, #16 + 8008f7a: 4301 orrs r1, r0 + 8008f7c: 79db ldrb r3, [r3, #7] + 8008f7e: 061b lsls r3, r3, #24 + 8008f80: 430b orrs r3, r1 + 8008f82: b29b uxth r3, r3 + 8008f84: 1ad3 subs r3, r2, r3 + 8008f86: b29a uxth r2, r3 + 8008f88: 6afb ldr r3, [r7, #44] ; 0x2c + 8008f8a: 811a strh r2, [r3, #8] + pbuf_realloc(next->p, next->len); + 8008f8c: 6afb ldr r3, [r7, #44] ; 0x2c + 8008f8e: 685a ldr r2, [r3, #4] + 8008f90: 6afb ldr r3, [r7, #44] ; 0x2c + 8008f92: 891b ldrh r3, [r3, #8] + 8008f94: 0019 movs r1, r3 + 8008f96: 0010 movs r0, r2 + 8008f98: f7fc fa8b bl 80054b2 + } + /* check if the remote side overruns our receive window */ + if ((u32_t)tcplen + seqno > pcb->rcv_nxt + (u32_t)pcb->rcv_wnd) { + 8008f9c: 4b64 ldr r3, [pc, #400] ; (8009130 ) + 8008f9e: 881b ldrh r3, [r3, #0] + 8008fa0: 001a movs r2, r3 + 8008fa2: 4b61 ldr r3, [pc, #388] ; (8009128 ) + 8008fa4: 681b ldr r3, [r3, #0] + 8008fa6: 18d2 adds r2, r2, r3 + 8008fa8: 687b ldr r3, [r7, #4] + 8008faa: 6a9b ldr r3, [r3, #40] ; 0x28 + 8008fac: 6879 ldr r1, [r7, #4] + 8008fae: 8d89 ldrh r1, [r1, #44] ; 0x2c + 8008fb0: 185b adds r3, r3, r1 + 8008fb2: 429a cmp r2, r3 + 8008fb4: d800 bhi.n 8008fb8 + 8008fb6: e091 b.n 80090dc + LWIP_DEBUGF(TCP_INPUT_DEBUG, + ("tcp_receive: other end overran receive window" + "seqno %"U32_F" len %"U16_F" right edge %"U32_F"\n", + seqno, tcplen, pcb->rcv_nxt + pcb->rcv_wnd)); + if (TCPH_FLAGS(next->next->tcphdr) & TCP_FIN) { + 8008fb8: 6afb ldr r3, [r7, #44] ; 0x2c + 8008fba: 681b ldr r3, [r3, #0] + 8008fbc: 68db ldr r3, [r3, #12] + 8008fbe: 7b1a ldrb r2, [r3, #12] + 8008fc0: 7b5b ldrb r3, [r3, #13] + 8008fc2: 021b lsls r3, r3, #8 + 8008fc4: 4313 orrs r3, r2 + 8008fc6: b29b uxth r3, r3 + 8008fc8: 0018 movs r0, r3 + 8008fca: f7fb fb39 bl 8004640 + 8008fce: 0003 movs r3, r0 + 8008fd0: 001a movs r2, r3 + 8008fd2: 2301 movs r3, #1 + 8008fd4: 4013 ands r3, r2 + 8008fd6: d039 beq.n 800904c + /* Must remove the FIN from the header as we're trimming + * that byte of sequence-space from the packet */ + TCPH_FLAGS_SET(next->next->tcphdr, TCPH_FLAGS(next->next->tcphdr) &~ TCP_FIN); + 8008fd8: 6afb ldr r3, [r7, #44] ; 0x2c + 8008fda: 681b ldr r3, [r3, #0] + 8008fdc: 68db ldr r3, [r3, #12] + 8008fde: 7b1a ldrb r2, [r3, #12] + 8008fe0: 7b5b ldrb r3, [r3, #13] + 8008fe2: 021b lsls r3, r3, #8 + 8008fe4: 4313 orrs r3, r2 + 8008fe6: b29b uxth r3, r3 + 8008fe8: b21b sxth r3, r3 + 8008fea: 4a52 ldr r2, [pc, #328] ; (8009134 ) + 8008fec: 4013 ands r3, r2 + 8008fee: b21c sxth r4, r3 + 8008ff0: 6afb ldr r3, [r7, #44] ; 0x2c + 8008ff2: 681b ldr r3, [r3, #0] + 8008ff4: 68db ldr r3, [r3, #12] + 8008ff6: 7b1a ldrb r2, [r3, #12] + 8008ff8: 7b5b ldrb r3, [r3, #13] + 8008ffa: 021b lsls r3, r3, #8 + 8008ffc: 4313 orrs r3, r2 + 8008ffe: b29b uxth r3, r3 + 8009000: 0018 movs r0, r3 + 8009002: f7fb fb1d bl 8004640 + 8009006: 0003 movs r3, r0 + 8009008: 001a movs r2, r3 + 800900a: 233e movs r3, #62 ; 0x3e + 800900c: 4013 ands r3, r2 + 800900e: b29b uxth r3, r3 + 8009010: 0018 movs r0, r3 + 8009012: f7fb faff bl 8004614 + 8009016: 0003 movs r3, r0 + 8009018: b21b sxth r3, r3 + 800901a: 4323 orrs r3, r4 + 800901c: b21a sxth r2, r3 + 800901e: 6afb ldr r3, [r7, #44] ; 0x2c + 8009020: 681b ldr r3, [r3, #0] + 8009022: 68db ldr r3, [r3, #12] + 8009024: b292 uxth r2, r2 + 8009026: 21ff movs r1, #255 ; 0xff + 8009028: 4011 ands r1, r2 + 800902a: 000c movs r4, r1 + 800902c: 7b19 ldrb r1, [r3, #12] + 800902e: 2000 movs r0, #0 + 8009030: 4001 ands r1, r0 + 8009032: 1c08 adds r0, r1, #0 + 8009034: 1c21 adds r1, r4, #0 + 8009036: 4301 orrs r1, r0 + 8009038: 7319 strb r1, [r3, #12] + 800903a: 0a12 lsrs r2, r2, #8 + 800903c: b290 uxth r0, r2 + 800903e: 7b5a ldrb r2, [r3, #13] + 8009040: 2100 movs r1, #0 + 8009042: 400a ands r2, r1 + 8009044: 1c11 adds r1, r2, #0 + 8009046: 1c02 adds r2, r0, #0 + 8009048: 430a orrs r2, r1 + 800904a: 735a strb r2, [r3, #13] + } + /* Adjust length of segment to fit in the window. */ + next->next->len = pcb->rcv_nxt + pcb->rcv_wnd - seqno; + 800904c: 687b ldr r3, [r7, #4] + 800904e: 6a9b ldr r3, [r3, #40] ; 0x28 + 8009050: b29a uxth r2, r3 + 8009052: 687b ldr r3, [r7, #4] + 8009054: 8d9b ldrh r3, [r3, #44] ; 0x2c + 8009056: 18d3 adds r3, r2, r3 + 8009058: b299 uxth r1, r3 + 800905a: 4b33 ldr r3, [pc, #204] ; (8009128 ) + 800905c: 681b ldr r3, [r3, #0] + 800905e: b29a uxth r2, r3 + 8009060: 6afb ldr r3, [r7, #44] ; 0x2c + 8009062: 681b ldr r3, [r3, #0] + 8009064: 1a8a subs r2, r1, r2 + 8009066: b292 uxth r2, r2 + 8009068: 811a strh r2, [r3, #8] + pbuf_realloc(next->next->p, next->next->len); + 800906a: 6afb ldr r3, [r7, #44] ; 0x2c + 800906c: 681b ldr r3, [r3, #0] + 800906e: 685a ldr r2, [r3, #4] + 8009070: 6afb ldr r3, [r7, #44] ; 0x2c + 8009072: 681b ldr r3, [r3, #0] + 8009074: 891b ldrh r3, [r3, #8] + 8009076: 0019 movs r1, r3 + 8009078: 0010 movs r0, r2 + 800907a: f7fc fa1a bl 80054b2 + tcplen = TCP_TCPLEN(next->next); + 800907e: 6afb ldr r3, [r7, #44] ; 0x2c + 8009080: 681b ldr r3, [r3, #0] + 8009082: 891c ldrh r4, [r3, #8] + 8009084: 6afb ldr r3, [r7, #44] ; 0x2c + 8009086: 681b ldr r3, [r3, #0] + 8009088: 68db ldr r3, [r3, #12] + 800908a: 7b1a ldrb r2, [r3, #12] + 800908c: 7b5b ldrb r3, [r3, #13] + 800908e: 021b lsls r3, r3, #8 + 8009090: 4313 orrs r3, r2 + 8009092: b29b uxth r3, r3 + 8009094: 0018 movs r0, r3 + 8009096: f7fb fad3 bl 8004640 + 800909a: 0003 movs r3, r0 + 800909c: 001a movs r2, r3 + 800909e: 2303 movs r3, #3 + 80090a0: 4013 ands r3, r2 + 80090a2: 1e5a subs r2, r3, #1 + 80090a4: 4193 sbcs r3, r2 + 80090a6: b2db uxtb r3, r3 + 80090a8: b29b uxth r3, r3 + 80090aa: 18e3 adds r3, r4, r3 + 80090ac: b29a uxth r2, r3 + 80090ae: 4b20 ldr r3, [pc, #128] ; (8009130 ) + 80090b0: 801a strh r2, [r3, #0] + LWIP_ASSERT("tcp_receive: segment not trimmed correctly to rcv_wnd\n", + (seqno + tcplen) == (pcb->rcv_nxt + pcb->rcv_wnd)); + } + } + break; + 80090b2: e013 b.n 80090dc + } + } + prev = next; + 80090b4: 6afb ldr r3, [r7, #44] ; 0x2c + 80090b6: 62bb str r3, [r7, #40] ; 0x28 + for(next = pcb->ooseq; next != NULL; next = next->next) { + 80090b8: 6afb ldr r3, [r7, #44] ; 0x2c + 80090ba: 681b ldr r3, [r3, #0] + 80090bc: 62fb str r3, [r7, #44] ; 0x2c + 80090be: 6afb ldr r3, [r7, #44] ; 0x2c + 80090c0: 2b00 cmp r3, #0 + 80090c2: d000 beq.n 80090c6 + 80090c4: e63a b.n 8008d3c + if (pcb->rcv_nxt == seqno) { + 80090c6: e010 b.n 80090ea + break; + 80090c8: 46c0 nop ; (mov r8, r8) + 80090ca: e00e b.n 80090ea + break; + 80090cc: 46c0 nop ; (mov r8, r8) + 80090ce: e00c b.n 80090ea + break; + 80090d0: 46c0 nop ; (mov r8, r8) + 80090d2: e00a b.n 80090ea + break; + 80090d4: 46c0 nop ; (mov r8, r8) + 80090d6: e008 b.n 80090ea + break; + 80090d8: 46c0 nop ; (mov r8, r8) + 80090da: e006 b.n 80090ea + break; + 80090dc: 46c0 nop ; (mov r8, r8) + if (pcb->rcv_nxt == seqno) { + 80090de: e004 b.n 80090ea +#endif /* TCP_OOSEQ_MAX_BYTES || TCP_OOSEQ_MAX_PBUFS */ +#endif /* TCP_QUEUE_OOSEQ */ + } + } else { + /* The incoming segment is not withing the window. */ + tcp_send_empty_ack(pcb); + 80090e0: 687b ldr r3, [r7, #4] + 80090e2: 0018 movs r0, r3 + 80090e4: f000 fc34 bl 8009950 + if (TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt, + 80090e8: e019 b.n 800911e + 80090ea: e018 b.n 800911e + } else { + /* Segments with length 0 is taken care of here. Segments that + fall out of the window are ACKed. */ + /*if (TCP_SEQ_GT(pcb->rcv_nxt, seqno) || + TCP_SEQ_GEQ(seqno, pcb->rcv_nxt + pcb->rcv_wnd)) {*/ + if(!TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt, pcb->rcv_nxt + pcb->rcv_wnd-1)){ + 80090ec: 4b0e ldr r3, [pc, #56] ; (8009128 ) + 80090ee: 681a ldr r2, [r3, #0] + 80090f0: 687b ldr r3, [r7, #4] + 80090f2: 6a9b ldr r3, [r3, #40] ; 0x28 + 80090f4: 1ad3 subs r3, r2, r3 + 80090f6: d40a bmi.n 800910e + 80090f8: 4b0b ldr r3, [pc, #44] ; (8009128 ) + 80090fa: 681a ldr r2, [r3, #0] + 80090fc: 687b ldr r3, [r7, #4] + 80090fe: 6a9b ldr r3, [r3, #40] ; 0x28 + 8009100: 6879 ldr r1, [r7, #4] + 8009102: 8d89 ldrh r1, [r1, #44] ; 0x2c + 8009104: 185b adds r3, r3, r1 + 8009106: 1ad3 subs r3, r2, r3 + 8009108: 3301 adds r3, #1 + 800910a: 2b00 cmp r3, #0 + 800910c: dd07 ble.n 800911e + tcp_ack_now(pcb); + 800910e: 687b ldr r3, [r7, #4] + 8009110: 7f9b ldrb r3, [r3, #30] + 8009112: 2202 movs r2, #2 + 8009114: 4313 orrs r3, r2 + 8009116: b2da uxtb r2, r3 + 8009118: 687b ldr r3, [r7, #4] + 800911a: 779a strb r2, [r3, #30] + } + } +} + 800911c: e7ff b.n 800911e + 800911e: 46c0 nop ; (mov r8, r8) + 8009120: 46bd mov sp, r7 + 8009122: b00d add sp, #52 ; 0x34 + 8009124: bdf0 pop {r4, r5, r6, r7, pc} + 8009126: 46c0 nop ; (mov r8, r8) + 8009128: 20002294 .word 0x20002294 + 800912c: 2000227c .word 0x2000227c + 8009130: 2000229e .word 0x2000229e + 8009134: ffffc0ff .word 0xffffc0ff + +08009138 : + * + * @param pcb the tcp_pcb for which a segment arrived + */ +static void +tcp_parseopt(struct tcp_pcb *pcb) +{ + 8009138: b580 push {r7, lr} + 800913a: b086 sub sp, #24 + 800913c: af00 add r7, sp, #0 + 800913e: 6078 str r0, [r7, #4] + u8_t *opts, opt; +#if LWIP_TCP_TIMESTAMPS + u32_t tsval; +#endif + + opts = (u8_t *)tcphdr + TCP_HLEN; + 8009140: 4b56 ldr r3, [pc, #344] ; (800929c ) + 8009142: 681b ldr r3, [r3, #0] + 8009144: 3314 adds r3, #20 + 8009146: 613b str r3, [r7, #16] + + /* Parse the TCP MSS option, if present. */ + if(TCPH_HDRLEN(tcphdr) > 0x5) { + 8009148: 4b54 ldr r3, [pc, #336] ; (800929c ) + 800914a: 681b ldr r3, [r3, #0] + 800914c: 7b1a ldrb r2, [r3, #12] + 800914e: 7b5b ldrb r3, [r3, #13] + 8009150: 021b lsls r3, r3, #8 + 8009152: 4313 orrs r3, r2 + 8009154: b29b uxth r3, r3 + 8009156: 0018 movs r0, r3 + 8009158: f7fb fa72 bl 8004640 + 800915c: 0003 movs r3, r0 + 800915e: 0b1b lsrs r3, r3, #12 + 8009160: b29b uxth r3, r3 + 8009162: 2b05 cmp r3, #5 + 8009164: d800 bhi.n 8009168 + 8009166: e095 b.n 8009294 + max_c = (TCPH_HDRLEN(tcphdr) - 5) << 2; + 8009168: 4b4c ldr r3, [pc, #304] ; (800929c ) + 800916a: 681b ldr r3, [r3, #0] + 800916c: 7b1a ldrb r2, [r3, #12] + 800916e: 7b5b ldrb r3, [r3, #13] + 8009170: 021b lsls r3, r3, #8 + 8009172: 4313 orrs r3, r2 + 8009174: b29b uxth r3, r3 + 8009176: 0018 movs r0, r3 + 8009178: f7fb fa62 bl 8004640 + 800917c: 0003 movs r3, r0 + 800917e: 0b1b lsrs r3, r3, #12 + 8009180: b29b uxth r3, r3 + 8009182: 3b05 subs r3, #5 + 8009184: b29a uxth r2, r3 + 8009186: 230e movs r3, #14 + 8009188: 18fb adds r3, r7, r3 + 800918a: 0092 lsls r2, r2, #2 + 800918c: 801a strh r2, [r3, #0] + for (c = 0; c < max_c; ) { + 800918e: 2316 movs r3, #22 + 8009190: 18fb adds r3, r7, r3 + 8009192: 2200 movs r2, #0 + 8009194: 801a strh r2, [r3, #0] + 8009196: e06e b.n 8009276 + opt = opts[c]; + 8009198: 2316 movs r3, #22 + 800919a: 18fb adds r3, r7, r3 + 800919c: 881b ldrh r3, [r3, #0] + 800919e: 693a ldr r2, [r7, #16] + 80091a0: 18d2 adds r2, r2, r3 + 80091a2: 210d movs r1, #13 + 80091a4: 187b adds r3, r7, r1 + 80091a6: 7812 ldrb r2, [r2, #0] + 80091a8: 701a strb r2, [r3, #0] + switch (opt) { + 80091aa: 187b adds r3, r7, r1 + 80091ac: 781b ldrb r3, [r3, #0] + 80091ae: 2b01 cmp r3, #1 + 80091b0: d005 beq.n 80091be + 80091b2: 2b02 cmp r3, #2 + 80091b4: d00a beq.n 80091cc + 80091b6: 2b00 cmp r3, #0 + 80091b8: d100 bne.n 80091bc + 80091ba: e066 b.n 800928a + 80091bc: e045 b.n 800924a + /* End of options. */ + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: EOL\n")); + return; + case 0x01: + /* NOP option. */ + ++c; + 80091be: 2216 movs r2, #22 + 80091c0: 18bb adds r3, r7, r2 + 80091c2: 18ba adds r2, r7, r2 + 80091c4: 8812 ldrh r2, [r2, #0] + 80091c6: 3201 adds r2, #1 + 80091c8: 801a strh r2, [r3, #0] + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: NOP\n")); + break; + 80091ca: e054 b.n 8009276 + case 0x02: + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: MSS\n")); + if (opts[c + 1] != 0x04 || c + 0x04 > max_c) { + 80091cc: 2316 movs r3, #22 + 80091ce: 18fb adds r3, r7, r3 + 80091d0: 881b ldrh r3, [r3, #0] + 80091d2: 3301 adds r3, #1 + 80091d4: 693a ldr r2, [r7, #16] + 80091d6: 18d3 adds r3, r2, r3 + 80091d8: 781b ldrb r3, [r3, #0] + 80091da: 2b04 cmp r3, #4 + 80091dc: d157 bne.n 800928e + 80091de: 2316 movs r3, #22 + 80091e0: 18fb adds r3, r7, r3 + 80091e2: 881b ldrh r3, [r3, #0] + 80091e4: 1d1a adds r2, r3, #4 + 80091e6: 230e movs r3, #14 + 80091e8: 18fb adds r3, r7, r3 + 80091ea: 881b ldrh r3, [r3, #0] + 80091ec: 429a cmp r2, r3 + 80091ee: dc4e bgt.n 800928e + /* Bad length */ + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: bad length\n")); + return; + } + /* An MSS option with the right option length. */ + mss = (opts[c + 2] << 8) | opts[c + 3]; + 80091f0: 2116 movs r1, #22 + 80091f2: 187b adds r3, r7, r1 + 80091f4: 881b ldrh r3, [r3, #0] + 80091f6: 3302 adds r3, #2 + 80091f8: 693a ldr r2, [r7, #16] + 80091fa: 18d3 adds r3, r2, r3 + 80091fc: 781b ldrb r3, [r3, #0] + 80091fe: 021b lsls r3, r3, #8 + 8009200: b21a sxth r2, r3 + 8009202: 187b adds r3, r7, r1 + 8009204: 881b ldrh r3, [r3, #0] + 8009206: 3303 adds r3, #3 + 8009208: 6939 ldr r1, [r7, #16] + 800920a: 18cb adds r3, r1, r3 + 800920c: 781b ldrb r3, [r3, #0] + 800920e: b21b sxth r3, r3 + 8009210: 4313 orrs r3, r2 + 8009212: b21a sxth r2, r3 + 8009214: 210a movs r1, #10 + 8009216: 187b adds r3, r7, r1 + 8009218: 801a strh r2, [r3, #0] + /* Limit the mss to the configured TCP_MSS and prevent division by zero */ + pcb->mss = ((mss > TCP_MSS) || (mss == 0)) ? TCP_MSS : mss; + 800921a: 187b adds r3, r7, r1 + 800921c: 881b ldrh r3, [r3, #0] + 800921e: 4a20 ldr r2, [pc, #128] ; (80092a0 ) + 8009220: 4293 cmp r3, r2 + 8009222: d808 bhi.n 8009236 + 8009224: 230a movs r3, #10 + 8009226: 18fb adds r3, r7, r3 + 8009228: 881b ldrh r3, [r3, #0] + 800922a: 2b00 cmp r3, #0 + 800922c: d003 beq.n 8009236 + 800922e: 230a movs r3, #10 + 8009230: 18fb adds r3, r7, r3 + 8009232: 881a ldrh r2, [r3, #0] + 8009234: e000 b.n 8009238 + 8009236: 4a1a ldr r2, [pc, #104] ; (80092a0 ) + 8009238: 687b ldr r3, [r7, #4] + 800923a: 86da strh r2, [r3, #54] ; 0x36 + /* Advance to next option */ + c += 0x04; + 800923c: 2216 movs r2, #22 + 800923e: 18bb adds r3, r7, r2 + 8009240: 18ba adds r2, r7, r2 + 8009242: 8812 ldrh r2, [r2, #0] + 8009244: 3204 adds r2, #4 + 8009246: 801a strh r2, [r3, #0] + break; + 8009248: e015 b.n 8009276 + c += 0x0A; + break; +#endif + default: + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: other\n")); + if (opts[c + 1] == 0) { + 800924a: 2316 movs r3, #22 + 800924c: 18fb adds r3, r7, r3 + 800924e: 881b ldrh r3, [r3, #0] + 8009250: 3301 adds r3, #1 + 8009252: 693a ldr r2, [r7, #16] + 8009254: 18d3 adds r3, r2, r3 + 8009256: 781b ldrb r3, [r3, #0] + 8009258: 2b00 cmp r3, #0 + 800925a: d01a beq.n 8009292 + and we don't process them further. */ + return; + } + /* All other options have a length field, so that we easily + can skip past them. */ + c += opts[c + 1]; + 800925c: 2016 movs r0, #22 + 800925e: 183b adds r3, r7, r0 + 8009260: 881b ldrh r3, [r3, #0] + 8009262: 3301 adds r3, #1 + 8009264: 693a ldr r2, [r7, #16] + 8009266: 18d3 adds r3, r2, r3 + 8009268: 781b ldrb r3, [r3, #0] + 800926a: b299 uxth r1, r3 + 800926c: 183b adds r3, r7, r0 + 800926e: 183a adds r2, r7, r0 + 8009270: 8812 ldrh r2, [r2, #0] + 8009272: 188a adds r2, r1, r2 + 8009274: 801a strh r2, [r3, #0] + for (c = 0; c < max_c; ) { + 8009276: 2316 movs r3, #22 + 8009278: 18fa adds r2, r7, r3 + 800927a: 230e movs r3, #14 + 800927c: 18fb adds r3, r7, r3 + 800927e: 8812 ldrh r2, [r2, #0] + 8009280: 881b ldrh r3, [r3, #0] + 8009282: 429a cmp r2, r3 + 8009284: d200 bcs.n 8009288 + 8009286: e787 b.n 8009198 + 8009288: e004 b.n 8009294 + return; + 800928a: 46c0 nop ; (mov r8, r8) + 800928c: e002 b.n 8009294 + return; + 800928e: 46c0 nop ; (mov r8, r8) + 8009290: e000 b.n 8009294 + return; + 8009292: 46c0 nop ; (mov r8, r8) + } + } + } +} + 8009294: 46bd mov sp, r7 + 8009296: b006 add sp, #24 + 8009298: bd80 pop {r7, pc} + 800929a: 46c0 nop ; (mov r8, r8) + 800929c: 2000228c .word 0x2000228c + 80092a0: 000005b4 .word 0x000005b4 + +080092a4 : + * @return pbuf with p->payload being the tcp_hdr + */ +static struct pbuf * +tcp_output_alloc_header(struct tcp_pcb *pcb, u16_t optlen, u16_t datalen, + u32_t seqno_be /* already in network byte order */) +{ + 80092a4: b590 push {r4, r7, lr} + 80092a6: b087 sub sp, #28 + 80092a8: af00 add r7, sp, #0 + 80092aa: 60f8 str r0, [r7, #12] + 80092ac: 0008 movs r0, r1 + 80092ae: 0011 movs r1, r2 + 80092b0: 607b str r3, [r7, #4] + 80092b2: 240a movs r4, #10 + 80092b4: 193b adds r3, r7, r4 + 80092b6: 1c02 adds r2, r0, #0 + 80092b8: 801a strh r2, [r3, #0] + 80092ba: 2008 movs r0, #8 + 80092bc: 183b adds r3, r7, r0 + 80092be: 1c0a adds r2, r1, #0 + 80092c0: 801a strh r2, [r3, #0] + struct tcp_hdr *tcphdr; + struct pbuf *p = pbuf_alloc(PBUF_IP, TCP_HLEN + optlen + datalen, PBUF_RAM); + 80092c2: 193a adds r2, r7, r4 + 80092c4: 183b adds r3, r7, r0 + 80092c6: 8812 ldrh r2, [r2, #0] + 80092c8: 881b ldrh r3, [r3, #0] + 80092ca: 18d3 adds r3, r2, r3 + 80092cc: b29b uxth r3, r3 + 80092ce: 3314 adds r3, #20 + 80092d0: b29b uxth r3, r3 + 80092d2: 2200 movs r2, #0 + 80092d4: 0019 movs r1, r3 + 80092d6: 2001 movs r0, #1 + 80092d8: f7fb ff58 bl 800518c + 80092dc: 0003 movs r3, r0 + 80092de: 617b str r3, [r7, #20] + if (p != NULL) { + 80092e0: 697b ldr r3, [r7, #20] + 80092e2: 2b00 cmp r3, #0 + 80092e4: d100 bne.n 80092e8 + 80092e6: e0e5 b.n 80094b4 + LWIP_ASSERT("check that first pbuf can hold struct tcp_hdr", + (p->len >= TCP_HLEN + optlen)); + tcphdr = (struct tcp_hdr *)p->payload; + 80092e8: 697b ldr r3, [r7, #20] + 80092ea: 685b ldr r3, [r3, #4] + 80092ec: 613b str r3, [r7, #16] + tcphdr->src = htons(pcb->local_port); + 80092ee: 68fb ldr r3, [r7, #12] + 80092f0: 8b5b ldrh r3, [r3, #26] + 80092f2: 0018 movs r0, r3 + 80092f4: f7fb f98e bl 8004614 + 80092f8: 0003 movs r3, r0 + 80092fa: 001a movs r2, r3 + 80092fc: 693b ldr r3, [r7, #16] + 80092fe: 21ff movs r1, #255 ; 0xff + 8009300: 4011 ands r1, r2 + 8009302: 000c movs r4, r1 + 8009304: 7819 ldrb r1, [r3, #0] + 8009306: 2000 movs r0, #0 + 8009308: 4001 ands r1, r0 + 800930a: 1c08 adds r0, r1, #0 + 800930c: 1c21 adds r1, r4, #0 + 800930e: 4301 orrs r1, r0 + 8009310: 7019 strb r1, [r3, #0] + 8009312: 0a12 lsrs r2, r2, #8 + 8009314: b290 uxth r0, r2 + 8009316: 785a ldrb r2, [r3, #1] + 8009318: 2100 movs r1, #0 + 800931a: 400a ands r2, r1 + 800931c: 1c11 adds r1, r2, #0 + 800931e: 1c02 adds r2, r0, #0 + 8009320: 430a orrs r2, r1 + 8009322: 705a strb r2, [r3, #1] + tcphdr->dest = htons(pcb->remote_port); + 8009324: 68fb ldr r3, [r7, #12] + 8009326: 8b9b ldrh r3, [r3, #28] + 8009328: 0018 movs r0, r3 + 800932a: f7fb f973 bl 8004614 + 800932e: 0003 movs r3, r0 + 8009330: 001a movs r2, r3 + 8009332: 693b ldr r3, [r7, #16] + 8009334: 21ff movs r1, #255 ; 0xff + 8009336: 4011 ands r1, r2 + 8009338: 000c movs r4, r1 + 800933a: 7899 ldrb r1, [r3, #2] + 800933c: 2000 movs r0, #0 + 800933e: 4001 ands r1, r0 + 8009340: 1c08 adds r0, r1, #0 + 8009342: 1c21 adds r1, r4, #0 + 8009344: 4301 orrs r1, r0 + 8009346: 7099 strb r1, [r3, #2] + 8009348: 0a12 lsrs r2, r2, #8 + 800934a: b290 uxth r0, r2 + 800934c: 78da ldrb r2, [r3, #3] + 800934e: 2100 movs r1, #0 + 8009350: 400a ands r2, r1 + 8009352: 1c11 adds r1, r2, #0 + 8009354: 1c02 adds r2, r0, #0 + 8009356: 430a orrs r2, r1 + 8009358: 70da strb r2, [r3, #3] + tcphdr->seqno = seqno_be; + 800935a: 693b ldr r3, [r7, #16] + 800935c: 1d3a adds r2, r7, #4 + 800935e: 7810 ldrb r0, [r2, #0] + 8009360: 791a ldrb r2, [r3, #4] + 8009362: 2100 movs r1, #0 + 8009364: 400a ands r2, r1 + 8009366: 1c11 adds r1, r2, #0 + 8009368: 1c02 adds r2, r0, #0 + 800936a: 430a orrs r2, r1 + 800936c: 711a strb r2, [r3, #4] + 800936e: 1d7a adds r2, r7, #5 + 8009370: 7810 ldrb r0, [r2, #0] + 8009372: 795a ldrb r2, [r3, #5] + 8009374: 2100 movs r1, #0 + 8009376: 400a ands r2, r1 + 8009378: 1c11 adds r1, r2, #0 + 800937a: 1c02 adds r2, r0, #0 + 800937c: 430a orrs r2, r1 + 800937e: 715a strb r2, [r3, #5] + 8009380: 1dba adds r2, r7, #6 + 8009382: 7810 ldrb r0, [r2, #0] + 8009384: 799a ldrb r2, [r3, #6] + 8009386: 2100 movs r1, #0 + 8009388: 400a ands r2, r1 + 800938a: 1c11 adds r1, r2, #0 + 800938c: 1c02 adds r2, r0, #0 + 800938e: 430a orrs r2, r1 + 8009390: 719a strb r2, [r3, #6] + 8009392: 1dfa adds r2, r7, #7 + 8009394: 7810 ldrb r0, [r2, #0] + 8009396: 79da ldrb r2, [r3, #7] + 8009398: 2100 movs r1, #0 + 800939a: 400a ands r2, r1 + 800939c: 1c11 adds r1, r2, #0 + 800939e: 1c02 adds r2, r0, #0 + 80093a0: 430a orrs r2, r1 + 80093a2: 71da strb r2, [r3, #7] + tcphdr->ackno = htonl(pcb->rcv_nxt); + 80093a4: 68fb ldr r3, [r7, #12] + 80093a6: 6a9b ldr r3, [r3, #40] ; 0x28 + 80093a8: 0018 movs r0, r3 + 80093aa: f7fb f959 bl 8004660 + 80093ae: 0002 movs r2, r0 + 80093b0: 693b ldr r3, [r7, #16] + 80093b2: 21ff movs r1, #255 ; 0xff + 80093b4: 4011 ands r1, r2 + 80093b6: 000c movs r4, r1 + 80093b8: 7a19 ldrb r1, [r3, #8] + 80093ba: 2000 movs r0, #0 + 80093bc: 4001 ands r1, r0 + 80093be: 1c08 adds r0, r1, #0 + 80093c0: 1c21 adds r1, r4, #0 + 80093c2: 4301 orrs r1, r0 + 80093c4: 7219 strb r1, [r3, #8] + 80093c6: 0a11 lsrs r1, r2, #8 + 80093c8: 20ff movs r0, #255 ; 0xff + 80093ca: 4001 ands r1, r0 + 80093cc: 000c movs r4, r1 + 80093ce: 7a59 ldrb r1, [r3, #9] + 80093d0: 2000 movs r0, #0 + 80093d2: 4001 ands r1, r0 + 80093d4: 1c08 adds r0, r1, #0 + 80093d6: 1c21 adds r1, r4, #0 + 80093d8: 4301 orrs r1, r0 + 80093da: 7259 strb r1, [r3, #9] + 80093dc: 0c11 lsrs r1, r2, #16 + 80093de: 20ff movs r0, #255 ; 0xff + 80093e0: 4001 ands r1, r0 + 80093e2: 000c movs r4, r1 + 80093e4: 7a99 ldrb r1, [r3, #10] + 80093e6: 2000 movs r0, #0 + 80093e8: 4001 ands r1, r0 + 80093ea: 1c08 adds r0, r1, #0 + 80093ec: 1c21 adds r1, r4, #0 + 80093ee: 4301 orrs r1, r0 + 80093f0: 7299 strb r1, [r3, #10] + 80093f2: 0e10 lsrs r0, r2, #24 + 80093f4: 7ada ldrb r2, [r3, #11] + 80093f6: 2100 movs r1, #0 + 80093f8: 400a ands r2, r1 + 80093fa: 1c11 adds r1, r2, #0 + 80093fc: 1c02 adds r2, r0, #0 + 80093fe: 430a orrs r2, r1 + 8009400: 72da strb r2, [r3, #11] + TCPH_HDRLEN_FLAGS_SET(tcphdr, (5 + optlen / 4), TCP_ACK); + 8009402: 230a movs r3, #10 + 8009404: 18fb adds r3, r7, r3 + 8009406: 881b ldrh r3, [r3, #0] + 8009408: 089b lsrs r3, r3, #2 + 800940a: b29b uxth r3, r3 + 800940c: 3305 adds r3, #5 + 800940e: b29b uxth r3, r3 + 8009410: 031b lsls r3, r3, #12 + 8009412: b29b uxth r3, r3 + 8009414: 2210 movs r2, #16 + 8009416: 4313 orrs r3, r2 + 8009418: b29b uxth r3, r3 + 800941a: 0018 movs r0, r3 + 800941c: f7fb f8fa bl 8004614 + 8009420: 0003 movs r3, r0 + 8009422: 001a movs r2, r3 + 8009424: 693b ldr r3, [r7, #16] + 8009426: 21ff movs r1, #255 ; 0xff + 8009428: 4011 ands r1, r2 + 800942a: 000c movs r4, r1 + 800942c: 7b19 ldrb r1, [r3, #12] + 800942e: 2000 movs r0, #0 + 8009430: 4001 ands r1, r0 + 8009432: 1c08 adds r0, r1, #0 + 8009434: 1c21 adds r1, r4, #0 + 8009436: 4301 orrs r1, r0 + 8009438: 7319 strb r1, [r3, #12] + 800943a: 0a12 lsrs r2, r2, #8 + 800943c: b290 uxth r0, r2 + 800943e: 7b5a ldrb r2, [r3, #13] + 8009440: 2100 movs r1, #0 + 8009442: 400a ands r2, r1 + 8009444: 1c11 adds r1, r2, #0 + 8009446: 1c02 adds r2, r0, #0 + 8009448: 430a orrs r2, r1 + 800944a: 735a strb r2, [r3, #13] + tcphdr->wnd = htons(pcb->rcv_ann_wnd); + 800944c: 68fb ldr r3, [r7, #12] + 800944e: 8ddb ldrh r3, [r3, #46] ; 0x2e + 8009450: 0018 movs r0, r3 + 8009452: f7fb f8df bl 8004614 + 8009456: 0003 movs r3, r0 + 8009458: 001a movs r2, r3 + 800945a: 693b ldr r3, [r7, #16] + 800945c: 21ff movs r1, #255 ; 0xff + 800945e: 4011 ands r1, r2 + 8009460: 000c movs r4, r1 + 8009462: 7b99 ldrb r1, [r3, #14] + 8009464: 2000 movs r0, #0 + 8009466: 4001 ands r1, r0 + 8009468: 1c08 adds r0, r1, #0 + 800946a: 1c21 adds r1, r4, #0 + 800946c: 4301 orrs r1, r0 + 800946e: 7399 strb r1, [r3, #14] + 8009470: 0a12 lsrs r2, r2, #8 + 8009472: b290 uxth r0, r2 + 8009474: 7bda ldrb r2, [r3, #15] + 8009476: 2100 movs r1, #0 + 8009478: 400a ands r2, r1 + 800947a: 1c11 adds r1, r2, #0 + 800947c: 1c02 adds r2, r0, #0 + 800947e: 430a orrs r2, r1 + 8009480: 73da strb r2, [r3, #15] + tcphdr->chksum = 0; + 8009482: 693b ldr r3, [r7, #16] + 8009484: 7c1a ldrb r2, [r3, #16] + 8009486: 2100 movs r1, #0 + 8009488: 400a ands r2, r1 + 800948a: 741a strb r2, [r3, #16] + 800948c: 7c5a ldrb r2, [r3, #17] + 800948e: 2100 movs r1, #0 + 8009490: 400a ands r2, r1 + 8009492: 745a strb r2, [r3, #17] + tcphdr->urgp = 0; + 8009494: 693b ldr r3, [r7, #16] + 8009496: 7c9a ldrb r2, [r3, #18] + 8009498: 2100 movs r1, #0 + 800949a: 400a ands r2, r1 + 800949c: 749a strb r2, [r3, #18] + 800949e: 7cda ldrb r2, [r3, #19] + 80094a0: 2100 movs r1, #0 + 80094a2: 400a ands r2, r1 + 80094a4: 74da strb r2, [r3, #19] + + /* If we're sending a packet, update the announced right window edge */ + pcb->rcv_ann_right_edge = pcb->rcv_nxt + pcb->rcv_ann_wnd; + 80094a6: 68fb ldr r3, [r7, #12] + 80094a8: 6a9b ldr r3, [r3, #40] ; 0x28 + 80094aa: 68fa ldr r2, [r7, #12] + 80094ac: 8dd2 ldrh r2, [r2, #46] ; 0x2e + 80094ae: 189a adds r2, r3, r2 + 80094b0: 68fb ldr r3, [r7, #12] + 80094b2: 631a str r2, [r3, #48] ; 0x30 + } + return p; + 80094b4: 697b ldr r3, [r7, #20] +} + 80094b6: 0018 movs r0, r3 + 80094b8: 46bd mov sp, r7 + 80094ba: b007 add sp, #28 + 80094bc: bd90 pop {r4, r7, pc} + +080094be : + * @param pcb the tcp_pcb over which to send a segment + * @return ERR_OK if sent, another err_t otherwise + */ +err_t +tcp_send_fin(struct tcp_pcb *pcb) +{ + 80094be: b590 push {r4, r7, lr} + 80094c0: b085 sub sp, #20 + 80094c2: af00 add r7, sp, #0 + 80094c4: 6078 str r0, [r7, #4] + /* first, try to add the fin to the last unsent segment */ + if (pcb->unsent != NULL) { + 80094c6: 687b ldr r3, [r7, #4] + 80094c8: 6edb ldr r3, [r3, #108] ; 0x6c + 80094ca: 2b00 cmp r3, #0 + 80094cc: d045 beq.n 800955a + struct tcp_seg *last_unsent; + for (last_unsent = pcb->unsent; last_unsent->next != NULL; + 80094ce: 687b ldr r3, [r7, #4] + 80094d0: 6edb ldr r3, [r3, #108] ; 0x6c + 80094d2: 60fb str r3, [r7, #12] + 80094d4: e002 b.n 80094dc + last_unsent = last_unsent->next); + 80094d6: 68fb ldr r3, [r7, #12] + 80094d8: 681b ldr r3, [r3, #0] + 80094da: 60fb str r3, [r7, #12] + for (last_unsent = pcb->unsent; last_unsent->next != NULL; + 80094dc: 68fb ldr r3, [r7, #12] + 80094de: 681b ldr r3, [r3, #0] + 80094e0: 2b00 cmp r3, #0 + 80094e2: d1f8 bne.n 80094d6 + + if ((TCPH_FLAGS(last_unsent->tcphdr) & (TCP_SYN | TCP_FIN | TCP_RST)) == 0) { + 80094e4: 68fb ldr r3, [r7, #12] + 80094e6: 68db ldr r3, [r3, #12] + 80094e8: 7b1a ldrb r2, [r3, #12] + 80094ea: 7b5b ldrb r3, [r3, #13] + 80094ec: 021b lsls r3, r3, #8 + 80094ee: 4313 orrs r3, r2 + 80094f0: b29b uxth r3, r3 + 80094f2: 0018 movs r0, r3 + 80094f4: f7fb f8a4 bl 8004640 + 80094f8: 0003 movs r3, r0 + 80094fa: 001a movs r2, r3 + 80094fc: 2307 movs r3, #7 + 80094fe: 4013 ands r3, r2 + 8009500: d12b bne.n 800955a + /* no SYN/FIN/RST flag in the header, we can add the FIN flag */ + TCPH_SET_FLAG(last_unsent->tcphdr, TCP_FIN); + 8009502: 68fb ldr r3, [r7, #12] + 8009504: 68db ldr r3, [r3, #12] + 8009506: 7b1a ldrb r2, [r3, #12] + 8009508: 7b5b ldrb r3, [r3, #13] + 800950a: 021b lsls r3, r3, #8 + 800950c: 4313 orrs r3, r2 + 800950e: b29c uxth r4, r3 + 8009510: 2001 movs r0, #1 + 8009512: f7fb f87f bl 8004614 + 8009516: 0003 movs r3, r0 + 8009518: 001a movs r2, r3 + 800951a: 68fb ldr r3, [r7, #12] + 800951c: 68db ldr r3, [r3, #12] + 800951e: 4322 orrs r2, r4 + 8009520: b292 uxth r2, r2 + 8009522: 21ff movs r1, #255 ; 0xff + 8009524: 4011 ands r1, r2 + 8009526: 000c movs r4, r1 + 8009528: 7b19 ldrb r1, [r3, #12] + 800952a: 2000 movs r0, #0 + 800952c: 4001 ands r1, r0 + 800952e: 1c08 adds r0, r1, #0 + 8009530: 1c21 adds r1, r4, #0 + 8009532: 4301 orrs r1, r0 + 8009534: 7319 strb r1, [r3, #12] + 8009536: 0a12 lsrs r2, r2, #8 + 8009538: b290 uxth r0, r2 + 800953a: 7b5a ldrb r2, [r3, #13] + 800953c: 2100 movs r1, #0 + 800953e: 400a ands r2, r1 + 8009540: 1c11 adds r1, r2, #0 + 8009542: 1c02 adds r2, r0, #0 + 8009544: 430a orrs r2, r1 + 8009546: 735a strb r2, [r3, #13] + pcb->flags |= TF_FIN; + 8009548: 687b ldr r3, [r7, #4] + 800954a: 7f9b ldrb r3, [r3, #30] + 800954c: 2220 movs r2, #32 + 800954e: 4313 orrs r3, r2 + 8009550: b2da uxtb r2, r3 + 8009552: 687b ldr r3, [r7, #4] + 8009554: 779a strb r2, [r3, #30] + return ERR_OK; + 8009556: 2300 movs r3, #0 + 8009558: e005 b.n 8009566 + } + } + /* no data, no length, flags, copy=1, no optdata */ + return tcp_enqueue_flags(pcb, TCP_FIN); + 800955a: 687b ldr r3, [r7, #4] + 800955c: 2101 movs r1, #1 + 800955e: 0018 movs r0, r3 + 8009560: f000 f8fc bl 800975c + 8009564: 0003 movs r3, r0 +} + 8009566: 0018 movs r0, r3 + 8009568: 46bd mov sp, r7 + 800956a: b005 add sp, #20 + 800956c: bd90 pop {r4, r7, pc} + ... + +08009570 : + * The TCP header is filled in except ackno and wnd. + * p is freed on failure. + */ +static struct tcp_seg * +tcp_create_segment(struct tcp_pcb *pcb, struct pbuf *p, u8_t flags, u32_t seqno, u8_t optflags) +{ + 8009570: b590 push {r4, r7, lr} + 8009572: b087 sub sp, #28 + 8009574: af00 add r7, sp, #0 + 8009576: 60f8 str r0, [r7, #12] + 8009578: 60b9 str r1, [r7, #8] + 800957a: 603b str r3, [r7, #0] + 800957c: 1dfb adds r3, r7, #7 + 800957e: 701a strb r2, [r3, #0] + struct tcp_seg *seg; + u8_t optlen = LWIP_TCP_OPT_LENGTH(optflags); + 8009580: 2028 movs r0, #40 ; 0x28 + 8009582: 183b adds r3, r7, r0 + 8009584: 781b ldrb r3, [r3, #0] + 8009586: 009b lsls r3, r3, #2 + 8009588: b2db uxtb r3, r3 + 800958a: 2204 movs r2, #4 + 800958c: 4013 ands r3, r2 + 800958e: b2d9 uxtb r1, r3 + 8009590: 183b adds r3, r7, r0 + 8009592: 781b ldrb r3, [r3, #0] + 8009594: 2202 movs r2, #2 + 8009596: 4013 ands r3, r2 + 8009598: d001 beq.n 800959e + 800959a: 230c movs r3, #12 + 800959c: e000 b.n 80095a0 + 800959e: 2300 movs r3, #0 + 80095a0: 2217 movs r2, #23 + 80095a2: 18ba adds r2, r7, r2 + 80095a4: 185b adds r3, r3, r1 + 80095a6: 7013 strb r3, [r2, #0] + + if ((seg = (struct tcp_seg *)memp_malloc(MEMP_TCP_SEG)) == NULL) { + 80095a8: 2004 movs r0, #4 + 80095aa: f7fb fc33 bl 8004e14 + 80095ae: 0003 movs r3, r0 + 80095b0: 613b str r3, [r7, #16] + 80095b2: 693b ldr r3, [r7, #16] + 80095b4: 2b00 cmp r3, #0 + 80095b6: d105 bne.n 80095c4 + LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_create_segment: no memory.\n")); + pbuf_free(p); + 80095b8: 68bb ldr r3, [r7, #8] + 80095ba: 0018 movs r0, r3 + 80095bc: f7fc f872 bl 80056a4 + return NULL; + 80095c0: 2300 movs r3, #0 + 80095c2: e0c5 b.n 8009750 + } + seg->flags = optflags; + 80095c4: 693b ldr r3, [r7, #16] + 80095c6: 2228 movs r2, #40 ; 0x28 + 80095c8: 18ba adds r2, r7, r2 + 80095ca: 7812 ldrb r2, [r2, #0] + 80095cc: 729a strb r2, [r3, #10] + seg->next = NULL; + 80095ce: 693b ldr r3, [r7, #16] + 80095d0: 2200 movs r2, #0 + 80095d2: 601a str r2, [r3, #0] + seg->p = p; + 80095d4: 693b ldr r3, [r7, #16] + 80095d6: 68ba ldr r2, [r7, #8] + 80095d8: 605a str r2, [r3, #4] + seg->len = p->tot_len - optlen; + 80095da: 68bb ldr r3, [r7, #8] + 80095dc: 891a ldrh r2, [r3, #8] + 80095de: 2317 movs r3, #23 + 80095e0: 18fb adds r3, r7, r3 + 80095e2: 781b ldrb r3, [r3, #0] + 80095e4: b29b uxth r3, r3 + 80095e6: 1ad3 subs r3, r2, r3 + 80095e8: b29a uxth r2, r3 + 80095ea: 693b ldr r3, [r7, #16] + 80095ec: 811a strh r2, [r3, #8] + LWIP_ASSERT("invalid optflags passed: TF_SEG_DATA_CHECKSUMMED", + (optflags & TF_SEG_DATA_CHECKSUMMED) == 0); +#endif /* TCP_CHECKSUM_ON_COPY */ + + /* build TCP header */ + if (pbuf_header(p, TCP_HLEN)) { + 80095ee: 68bb ldr r3, [r7, #8] + 80095f0: 2114 movs r1, #20 + 80095f2: 0018 movs r0, r3 + 80095f4: f7fb ffcf bl 8005596 + 80095f8: 1e03 subs r3, r0, #0 + 80095fa: d00d beq.n 8009618 + LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_create_segment: no room for TCP header in pbuf.\n")); + TCP_STATS_INC(tcp.err); + 80095fc: 4b56 ldr r3, [pc, #344] ; (8009758 ) + 80095fe: 22a4 movs r2, #164 ; 0xa4 + 8009600: 5a9b ldrh r3, [r3, r2] + 8009602: 3301 adds r3, #1 + 8009604: b299 uxth r1, r3 + 8009606: 4b54 ldr r3, [pc, #336] ; (8009758 ) + 8009608: 22a4 movs r2, #164 ; 0xa4 + 800960a: 5299 strh r1, [r3, r2] + tcp_seg_free(seg); + 800960c: 693b ldr r3, [r7, #16] + 800960e: 0018 movs r0, r3 + 8009610: f7fd f885 bl 800671e + return NULL; + 8009614: 2300 movs r3, #0 + 8009616: e09b b.n 8009750 + } + seg->tcphdr = (struct tcp_hdr *)seg->p->payload; + 8009618: 693b ldr r3, [r7, #16] + 800961a: 685b ldr r3, [r3, #4] + 800961c: 685a ldr r2, [r3, #4] + 800961e: 693b ldr r3, [r7, #16] + 8009620: 60da str r2, [r3, #12] + seg->tcphdr->src = htons(pcb->local_port); + 8009622: 68fb ldr r3, [r7, #12] + 8009624: 8b5a ldrh r2, [r3, #26] + 8009626: 693b ldr r3, [r7, #16] + 8009628: 68dc ldr r4, [r3, #12] + 800962a: 0010 movs r0, r2 + 800962c: f7fa fff2 bl 8004614 + 8009630: 0003 movs r3, r0 + 8009632: 22ff movs r2, #255 ; 0xff + 8009634: 401a ands r2, r3 + 8009636: 0010 movs r0, r2 + 8009638: 7822 ldrb r2, [r4, #0] + 800963a: 2100 movs r1, #0 + 800963c: 400a ands r2, r1 + 800963e: 1c11 adds r1, r2, #0 + 8009640: 1c02 adds r2, r0, #0 + 8009642: 430a orrs r2, r1 + 8009644: 7022 strb r2, [r4, #0] + 8009646: 0a1b lsrs r3, r3, #8 + 8009648: b299 uxth r1, r3 + 800964a: 7863 ldrb r3, [r4, #1] + 800964c: 2200 movs r2, #0 + 800964e: 4013 ands r3, r2 + 8009650: 1c1a adds r2, r3, #0 + 8009652: 1c0b adds r3, r1, #0 + 8009654: 4313 orrs r3, r2 + 8009656: 7063 strb r3, [r4, #1] + seg->tcphdr->dest = htons(pcb->remote_port); + 8009658: 68fb ldr r3, [r7, #12] + 800965a: 8b9a ldrh r2, [r3, #28] + 800965c: 693b ldr r3, [r7, #16] + 800965e: 68dc ldr r4, [r3, #12] + 8009660: 0010 movs r0, r2 + 8009662: f7fa ffd7 bl 8004614 + 8009666: 0003 movs r3, r0 + 8009668: 22ff movs r2, #255 ; 0xff + 800966a: 401a ands r2, r3 + 800966c: 0010 movs r0, r2 + 800966e: 78a2 ldrb r2, [r4, #2] + 8009670: 2100 movs r1, #0 + 8009672: 400a ands r2, r1 + 8009674: 1c11 adds r1, r2, #0 + 8009676: 1c02 adds r2, r0, #0 + 8009678: 430a orrs r2, r1 + 800967a: 70a2 strb r2, [r4, #2] + 800967c: 0a1b lsrs r3, r3, #8 + 800967e: b299 uxth r1, r3 + 8009680: 78e3 ldrb r3, [r4, #3] + 8009682: 2200 movs r2, #0 + 8009684: 4013 ands r3, r2 + 8009686: 1c1a adds r2, r3, #0 + 8009688: 1c0b adds r3, r1, #0 + 800968a: 4313 orrs r3, r2 + 800968c: 70e3 strb r3, [r4, #3] + seg->tcphdr->seqno = htonl(seqno); + 800968e: 693b ldr r3, [r7, #16] + 8009690: 68dc ldr r4, [r3, #12] + 8009692: 683b ldr r3, [r7, #0] + 8009694: 0018 movs r0, r3 + 8009696: f7fa ffe3 bl 8004660 + 800969a: 0003 movs r3, r0 + 800969c: 22ff movs r2, #255 ; 0xff + 800969e: 401a ands r2, r3 + 80096a0: 0010 movs r0, r2 + 80096a2: 7922 ldrb r2, [r4, #4] + 80096a4: 2100 movs r1, #0 + 80096a6: 400a ands r2, r1 + 80096a8: 1c11 adds r1, r2, #0 + 80096aa: 1c02 adds r2, r0, #0 + 80096ac: 430a orrs r2, r1 + 80096ae: 7122 strb r2, [r4, #4] + 80096b0: 0a1a lsrs r2, r3, #8 + 80096b2: 21ff movs r1, #255 ; 0xff + 80096b4: 400a ands r2, r1 + 80096b6: 0010 movs r0, r2 + 80096b8: 7962 ldrb r2, [r4, #5] + 80096ba: 2100 movs r1, #0 + 80096bc: 400a ands r2, r1 + 80096be: 1c11 adds r1, r2, #0 + 80096c0: 1c02 adds r2, r0, #0 + 80096c2: 430a orrs r2, r1 + 80096c4: 7162 strb r2, [r4, #5] + 80096c6: 0c1a lsrs r2, r3, #16 + 80096c8: 21ff movs r1, #255 ; 0xff + 80096ca: 400a ands r2, r1 + 80096cc: 0010 movs r0, r2 + 80096ce: 79a2 ldrb r2, [r4, #6] + 80096d0: 2100 movs r1, #0 + 80096d2: 400a ands r2, r1 + 80096d4: 1c11 adds r1, r2, #0 + 80096d6: 1c02 adds r2, r0, #0 + 80096d8: 430a orrs r2, r1 + 80096da: 71a2 strb r2, [r4, #6] + 80096dc: 0e19 lsrs r1, r3, #24 + 80096de: 79e3 ldrb r3, [r4, #7] + 80096e0: 2200 movs r2, #0 + 80096e2: 4013 ands r3, r2 + 80096e4: 1c1a adds r2, r3, #0 + 80096e6: 1c0b adds r3, r1, #0 + 80096e8: 4313 orrs r3, r2 + 80096ea: 71e3 strb r3, [r4, #7] + /* ackno is set in tcp_output */ + TCPH_HDRLEN_FLAGS_SET(seg->tcphdr, (5 + optlen / 4), flags); + 80096ec: 2317 movs r3, #23 + 80096ee: 18fb adds r3, r7, r3 + 80096f0: 781b ldrb r3, [r3, #0] + 80096f2: 089b lsrs r3, r3, #2 + 80096f4: b2db uxtb r3, r3 + 80096f6: 3305 adds r3, #5 + 80096f8: 031b lsls r3, r3, #12 + 80096fa: b21a sxth r2, r3 + 80096fc: 1dfb adds r3, r7, #7 + 80096fe: 781b ldrb r3, [r3, #0] + 8009700: b21b sxth r3, r3 + 8009702: 4313 orrs r3, r2 + 8009704: b21b sxth r3, r3 + 8009706: b29a uxth r2, r3 + 8009708: 693b ldr r3, [r7, #16] + 800970a: 68dc ldr r4, [r3, #12] + 800970c: 0010 movs r0, r2 + 800970e: f7fa ff81 bl 8004614 + 8009712: 0003 movs r3, r0 + 8009714: 22ff movs r2, #255 ; 0xff + 8009716: 401a ands r2, r3 + 8009718: 0010 movs r0, r2 + 800971a: 7b22 ldrb r2, [r4, #12] + 800971c: 2100 movs r1, #0 + 800971e: 400a ands r2, r1 + 8009720: 1c11 adds r1, r2, #0 + 8009722: 1c02 adds r2, r0, #0 + 8009724: 430a orrs r2, r1 + 8009726: 7322 strb r2, [r4, #12] + 8009728: 0a1b lsrs r3, r3, #8 + 800972a: b299 uxth r1, r3 + 800972c: 7b63 ldrb r3, [r4, #13] + 800972e: 2200 movs r2, #0 + 8009730: 4013 ands r3, r2 + 8009732: 1c1a adds r2, r3, #0 + 8009734: 1c0b adds r3, r1, #0 + 8009736: 4313 orrs r3, r2 + 8009738: 7363 strb r3, [r4, #13] + /* wnd and chksum are set in tcp_output */ + seg->tcphdr->urgp = 0; + 800973a: 693b ldr r3, [r7, #16] + 800973c: 68db ldr r3, [r3, #12] + 800973e: 7c9a ldrb r2, [r3, #18] + 8009740: 2100 movs r1, #0 + 8009742: 400a ands r2, r1 + 8009744: 749a strb r2, [r3, #18] + 8009746: 7cda ldrb r2, [r3, #19] + 8009748: 2100 movs r1, #0 + 800974a: 400a ands r2, r1 + 800974c: 74da strb r2, [r3, #19] + return seg; + 800974e: 693b ldr r3, [r7, #16] +} + 8009750: 0018 movs r0, r3 + 8009752: 46bd mov sp, r7 + 8009754: b007 add sp, #28 + 8009756: bd90 pop {r4, r7, pc} + 8009758: 20003158 .word 0x20003158 + +0800975c : + * @param optdata pointer to TCP options, or NULL. + * @param optlen length of TCP options in bytes. + */ +err_t +tcp_enqueue_flags(struct tcp_pcb *pcb, u8_t flags) +{ + 800975c: b590 push {r4, r7, lr} + 800975e: b08b sub sp, #44 ; 0x2c + 8009760: af02 add r7, sp, #8 + 8009762: 6078 str r0, [r7, #4] + 8009764: 000a movs r2, r1 + 8009766: 1cfb adds r3, r7, #3 + 8009768: 701a strb r2, [r3, #0] + struct pbuf *p; + struct tcp_seg *seg; + u8_t optflags = 0; + 800976a: 231f movs r3, #31 + 800976c: 18fb adds r3, r7, r3 + 800976e: 2200 movs r2, #0 + 8009770: 701a strb r2, [r3, #0] + u8_t optlen = 0; + 8009772: 2317 movs r3, #23 + 8009774: 18fb adds r3, r7, r3 + 8009776: 2200 movs r2, #0 + 8009778: 701a strb r2, [r3, #0] + + LWIP_ASSERT("tcp_enqueue_flags: need either TCP_SYN or TCP_FIN in flags (programmer violates API)", + (flags & (TCP_SYN | TCP_FIN)) != 0); + + /* check for configured max queuelen and possible overflow */ + if ((pcb->snd_queuelen >= TCP_SND_QUEUELEN) || (pcb->snd_queuelen > TCP_SNDQUEUELEN_OVERFLOW)) { + 800977a: 687b ldr r3, [r7, #4] + 800977c: 2268 movs r2, #104 ; 0x68 + 800977e: 5a9b ldrh r3, [r3, r2] + 8009780: 2b07 cmp r3, #7 + 8009782: d805 bhi.n 8009790 + 8009784: 687b ldr r3, [r7, #4] + 8009786: 2268 movs r2, #104 ; 0x68 + 8009788: 5a9b ldrh r3, [r3, r2] + 800978a: 4a6f ldr r2, [pc, #444] ; (8009948 ) + 800978c: 4293 cmp r3, r2 + 800978e: d912 bls.n 80097b6 + LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 3, ("tcp_enqueue_flags: too long queue %"U16_F" (max %"U16_F")\n", + pcb->snd_queuelen, TCP_SND_QUEUELEN)); + TCP_STATS_INC(tcp.memerr); + 8009790: 4b6e ldr r3, [pc, #440] ; (800994c ) + 8009792: 229c movs r2, #156 ; 0x9c + 8009794: 5a9b ldrh r3, [r3, r2] + 8009796: 3301 adds r3, #1 + 8009798: b299 uxth r1, r3 + 800979a: 4b6c ldr r3, [pc, #432] ; (800994c ) + 800979c: 229c movs r2, #156 ; 0x9c + 800979e: 5299 strh r1, [r3, r2] + pcb->flags |= TF_NAGLEMEMERR; + 80097a0: 687b ldr r3, [r7, #4] + 80097a2: 7f9b ldrb r3, [r3, #30] + 80097a4: 2280 movs r2, #128 ; 0x80 + 80097a6: 4252 negs r2, r2 + 80097a8: 4313 orrs r3, r2 + 80097aa: b2da uxtb r2, r3 + 80097ac: 687b ldr r3, [r7, #4] + 80097ae: 779a strb r2, [r3, #30] + return ERR_MEM; + 80097b0: 2301 movs r3, #1 + 80097b2: 425b negs r3, r3 + 80097b4: e0c3 b.n 800993e + } + + if (flags & TCP_SYN) { + 80097b6: 1cfb adds r3, r7, #3 + 80097b8: 781b ldrb r3, [r3, #0] + 80097ba: 2202 movs r2, #2 + 80097bc: 4013 ands r3, r2 + 80097be: d003 beq.n 80097c8 + optflags = TF_SEG_OPTS_MSS; + 80097c0: 231f movs r3, #31 + 80097c2: 18fb adds r3, r7, r3 + 80097c4: 2201 movs r2, #1 + 80097c6: 701a strb r2, [r3, #0] +#if LWIP_TCP_TIMESTAMPS + if ((pcb->flags & TF_TIMESTAMP)) { + optflags |= TF_SEG_OPTS_TS; + } +#endif /* LWIP_TCP_TIMESTAMPS */ + optlen = LWIP_TCP_OPT_LENGTH(optflags); + 80097c8: 201f movs r0, #31 + 80097ca: 183b adds r3, r7, r0 + 80097cc: 781b ldrb r3, [r3, #0] + 80097ce: 009b lsls r3, r3, #2 + 80097d0: b2db uxtb r3, r3 + 80097d2: 2204 movs r2, #4 + 80097d4: 4013 ands r3, r2 + 80097d6: b2d9 uxtb r1, r3 + 80097d8: 183b adds r3, r7, r0 + 80097da: 781b ldrb r3, [r3, #0] + 80097dc: 2202 movs r2, #2 + 80097de: 4013 ands r3, r2 + 80097e0: d001 beq.n 80097e6 + 80097e2: 230c movs r3, #12 + 80097e4: e000 b.n 80097e8 + 80097e6: 2300 movs r3, #0 + 80097e8: 2217 movs r2, #23 + 80097ea: 18ba adds r2, r7, r2 + 80097ec: 185b adds r3, r3, r1 + 80097ee: 7013 strb r3, [r2, #0] + + /* tcp_enqueue_flags is always called with either SYN or FIN in flags. + * We need one available snd_buf byte to do that. + * This means we can't send FIN while snd_buf==0. A better fix would be to + * not include SYN and FIN sequence numbers in the snd_buf count. */ + if (pcb->snd_buf == 0) { + 80097f0: 687b ldr r3, [r7, #4] + 80097f2: 2266 movs r2, #102 ; 0x66 + 80097f4: 5a9b ldrh r3, [r3, r2] + 80097f6: 2b00 cmp r3, #0 + 80097f8: d10a bne.n 8009810 + LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 3, ("tcp_enqueue_flags: no send buffer available\n")); + TCP_STATS_INC(tcp.memerr); + 80097fa: 4b54 ldr r3, [pc, #336] ; (800994c ) + 80097fc: 229c movs r2, #156 ; 0x9c + 80097fe: 5a9b ldrh r3, [r3, r2] + 8009800: 3301 adds r3, #1 + 8009802: b299 uxth r1, r3 + 8009804: 4b51 ldr r3, [pc, #324] ; (800994c ) + 8009806: 229c movs r2, #156 ; 0x9c + 8009808: 5299 strh r1, [r3, r2] + return ERR_MEM; + 800980a: 2301 movs r3, #1 + 800980c: 425b negs r3, r3 + 800980e: e096 b.n 800993e + } + + /* Allocate pbuf with room for TCP header + options */ + if ((p = pbuf_alloc(PBUF_TRANSPORT, optlen, PBUF_RAM)) == NULL) { + 8009810: 2317 movs r3, #23 + 8009812: 18fb adds r3, r7, r3 + 8009814: 781b ldrb r3, [r3, #0] + 8009816: b29b uxth r3, r3 + 8009818: 2200 movs r2, #0 + 800981a: 0019 movs r1, r3 + 800981c: 2000 movs r0, #0 + 800981e: f7fb fcb5 bl 800518c + 8009822: 0003 movs r3, r0 + 8009824: 613b str r3, [r7, #16] + 8009826: 693b ldr r3, [r7, #16] + 8009828: 2b00 cmp r3, #0 + 800982a: d112 bne.n 8009852 + pcb->flags |= TF_NAGLEMEMERR; + 800982c: 687b ldr r3, [r7, #4] + 800982e: 7f9b ldrb r3, [r3, #30] + 8009830: 2280 movs r2, #128 ; 0x80 + 8009832: 4252 negs r2, r2 + 8009834: 4313 orrs r3, r2 + 8009836: b2da uxtb r2, r3 + 8009838: 687b ldr r3, [r7, #4] + 800983a: 779a strb r2, [r3, #30] + TCP_STATS_INC(tcp.memerr); + 800983c: 4b43 ldr r3, [pc, #268] ; (800994c ) + 800983e: 229c movs r2, #156 ; 0x9c + 8009840: 5a9b ldrh r3, [r3, r2] + 8009842: 3301 adds r3, #1 + 8009844: b299 uxth r1, r3 + 8009846: 4b41 ldr r3, [pc, #260] ; (800994c ) + 8009848: 229c movs r2, #156 ; 0x9c + 800984a: 5299 strh r1, [r3, r2] + return ERR_MEM; + 800984c: 2301 movs r3, #1 + 800984e: 425b negs r3, r3 + 8009850: e075 b.n 800993e + } + LWIP_ASSERT("tcp_enqueue_flags: check that first pbuf can hold optlen", + (p->len >= optlen)); + + /* Allocate memory for tcp_seg, and fill in fields. */ + if ((seg = tcp_create_segment(pcb, p, flags, pcb->snd_lbb, optflags)) == NULL) { + 8009852: 687b ldr r3, [r7, #4] + 8009854: 6ddc ldr r4, [r3, #92] ; 0x5c + 8009856: 1cfb adds r3, r7, #3 + 8009858: 781a ldrb r2, [r3, #0] + 800985a: 6939 ldr r1, [r7, #16] + 800985c: 6878 ldr r0, [r7, #4] + 800985e: 231f movs r3, #31 + 8009860: 18fb adds r3, r7, r3 + 8009862: 781b ldrb r3, [r3, #0] + 8009864: 9300 str r3, [sp, #0] + 8009866: 0023 movs r3, r4 + 8009868: f7ff fe82 bl 8009570 + 800986c: 0003 movs r3, r0 + 800986e: 60fb str r3, [r7, #12] + 8009870: 68fb ldr r3, [r7, #12] + 8009872: 2b00 cmp r3, #0 + 8009874: d112 bne.n 800989c + pcb->flags |= TF_NAGLEMEMERR; + 8009876: 687b ldr r3, [r7, #4] + 8009878: 7f9b ldrb r3, [r3, #30] + 800987a: 2280 movs r2, #128 ; 0x80 + 800987c: 4252 negs r2, r2 + 800987e: 4313 orrs r3, r2 + 8009880: b2da uxtb r2, r3 + 8009882: 687b ldr r3, [r7, #4] + 8009884: 779a strb r2, [r3, #30] + TCP_STATS_INC(tcp.memerr); + 8009886: 4b31 ldr r3, [pc, #196] ; (800994c ) + 8009888: 229c movs r2, #156 ; 0x9c + 800988a: 5a9b ldrh r3, [r3, r2] + 800988c: 3301 adds r3, #1 + 800988e: b299 uxth r1, r3 + 8009890: 4b2e ldr r3, [pc, #184] ; (800994c ) + 8009892: 229c movs r2, #156 ; 0x9c + 8009894: 5299 strh r1, [r3, r2] + return ERR_MEM; + 8009896: 2301 movs r3, #1 + 8009898: 425b negs r3, r3 + 800989a: e050 b.n 800993e + ntohl(seg->tcphdr->seqno), + ntohl(seg->tcphdr->seqno) + TCP_TCPLEN(seg), + (u16_t)flags)); + + /* Now append seg to pcb->unsent queue */ + if (pcb->unsent == NULL) { + 800989c: 687b ldr r3, [r7, #4] + 800989e: 6edb ldr r3, [r3, #108] ; 0x6c + 80098a0: 2b00 cmp r3, #0 + 80098a2: d103 bne.n 80098ac + pcb->unsent = seg; + 80098a4: 687b ldr r3, [r7, #4] + 80098a6: 68fa ldr r2, [r7, #12] + 80098a8: 66da str r2, [r3, #108] ; 0x6c + 80098aa: e00d b.n 80098c8 + } else { + struct tcp_seg *useg; + for (useg = pcb->unsent; useg->next != NULL; useg = useg->next); + 80098ac: 687b ldr r3, [r7, #4] + 80098ae: 6edb ldr r3, [r3, #108] ; 0x6c + 80098b0: 61bb str r3, [r7, #24] + 80098b2: e002 b.n 80098ba + 80098b4: 69bb ldr r3, [r7, #24] + 80098b6: 681b ldr r3, [r3, #0] + 80098b8: 61bb str r3, [r7, #24] + 80098ba: 69bb ldr r3, [r7, #24] + 80098bc: 681b ldr r3, [r3, #0] + 80098be: 2b00 cmp r3, #0 + 80098c0: d1f8 bne.n 80098b4 + useg->next = seg; + 80098c2: 69bb ldr r3, [r7, #24] + 80098c4: 68fa ldr r2, [r7, #12] + 80098c6: 601a str r2, [r3, #0] + } +#if TCP_OVERSIZE + /* The new unsent tail has no space */ + pcb->unsent_oversize = 0; + 80098c8: 687b ldr r3, [r7, #4] + 80098ca: 226a movs r2, #106 ; 0x6a + 80098cc: 2100 movs r1, #0 + 80098ce: 5299 strh r1, [r3, r2] +#endif /* TCP_OVERSIZE */ + + /* SYN and FIN bump the sequence number */ + if ((flags & TCP_SYN) || (flags & TCP_FIN)) { + 80098d0: 1cfb adds r3, r7, #3 + 80098d2: 781b ldrb r3, [r3, #0] + 80098d4: 2202 movs r2, #2 + 80098d6: 4013 ands r3, r2 + 80098d8: d104 bne.n 80098e4 + 80098da: 1cfb adds r3, r7, #3 + 80098dc: 781b ldrb r3, [r3, #0] + 80098de: 2201 movs r2, #1 + 80098e0: 4013 ands r3, r2 + 80098e2: d00c beq.n 80098fe + pcb->snd_lbb++; + 80098e4: 687b ldr r3, [r7, #4] + 80098e6: 6ddb ldr r3, [r3, #92] ; 0x5c + 80098e8: 1c5a adds r2, r3, #1 + 80098ea: 687b ldr r3, [r7, #4] + 80098ec: 65da str r2, [r3, #92] ; 0x5c + /* optlen does not influence snd_buf */ + pcb->snd_buf--; + 80098ee: 687b ldr r3, [r7, #4] + 80098f0: 2266 movs r2, #102 ; 0x66 + 80098f2: 5a9b ldrh r3, [r3, r2] + 80098f4: 3b01 subs r3, #1 + 80098f6: b299 uxth r1, r3 + 80098f8: 687b ldr r3, [r7, #4] + 80098fa: 2266 movs r2, #102 ; 0x66 + 80098fc: 5299 strh r1, [r3, r2] + } + if (flags & TCP_FIN) { + 80098fe: 1cfb adds r3, r7, #3 + 8009900: 781b ldrb r3, [r3, #0] + 8009902: 2201 movs r2, #1 + 8009904: 4013 ands r3, r2 + 8009906: d006 beq.n 8009916 + pcb->flags |= TF_FIN; + 8009908: 687b ldr r3, [r7, #4] + 800990a: 7f9b ldrb r3, [r3, #30] + 800990c: 2220 movs r2, #32 + 800990e: 4313 orrs r3, r2 + 8009910: b2da uxtb r2, r3 + 8009912: 687b ldr r3, [r7, #4] + 8009914: 779a strb r2, [r3, #30] + } + + /* update number of segments on the queues */ + pcb->snd_queuelen += pbuf_clen(seg->p); + 8009916: 68fb ldr r3, [r7, #12] + 8009918: 685b ldr r3, [r3, #4] + 800991a: 0018 movs r0, r3 + 800991c: f7fb ff34 bl 8005788 + 8009920: 0003 movs r3, r0 + 8009922: 0019 movs r1, r3 + 8009924: 687b ldr r3, [r7, #4] + 8009926: 2268 movs r2, #104 ; 0x68 + 8009928: 5a9a ldrh r2, [r3, r2] + 800992a: b28b uxth r3, r1 + 800992c: 18d3 adds r3, r2, r3 + 800992e: b299 uxth r1, r3 + 8009930: 687b ldr r3, [r7, #4] + 8009932: 2268 movs r2, #104 ; 0x68 + 8009934: 5299 strh r1, [r3, r2] + LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_enqueue_flags: %"S16_F" (after enqueued)\n", pcb->snd_queuelen)); + if (pcb->snd_queuelen != 0) { + 8009936: 687b ldr r3, [r7, #4] + 8009938: 2268 movs r2, #104 ; 0x68 + 800993a: 5a9b ldrh r3, [r3, r2] + LWIP_ASSERT("tcp_enqueue_flags: invalid queue length", + pcb->unacked != NULL || pcb->unsent != NULL); + } + + return ERR_OK; + 800993c: 2300 movs r3, #0 +} + 800993e: 0018 movs r0, r3 + 8009940: 46bd mov sp, r7 + 8009942: b009 add sp, #36 ; 0x24 + 8009944: bd90 pop {r4, r7, pc} + 8009946: 46c0 nop ; (mov r8, r8) + 8009948: 0000fffc .word 0x0000fffc + 800994c: 20003158 .word 0x20003158 + +08009950 : + * + * @param pcb Protocol control block for the TCP connection to send the ACK + */ +err_t +tcp_send_empty_ack(struct tcp_pcb *pcb) +{ + 8009950: b5b0 push {r4, r5, r7, lr} + 8009952: b088 sub sp, #32 + 8009954: af02 add r7, sp, #8 + 8009956: 6078 str r0, [r7, #4] + struct pbuf *p; + struct tcp_hdr *tcphdr; + u8_t optlen = 0; + 8009958: 2117 movs r1, #23 + 800995a: 187b adds r3, r7, r1 + 800995c: 2200 movs r2, #0 + 800995e: 701a strb r2, [r3, #0] + if (pcb->flags & TF_TIMESTAMP) { + optlen = LWIP_TCP_OPT_LENGTH(TF_SEG_OPTS_TS); + } +#endif + + p = tcp_output_alloc_header(pcb, optlen, 0, htonl(pcb->snd_nxt)); + 8009960: 187b adds r3, r7, r1 + 8009962: 781b ldrb r3, [r3, #0] + 8009964: b29c uxth r4, r3 + 8009966: 687b ldr r3, [r7, #4] + 8009968: 6d1b ldr r3, [r3, #80] ; 0x50 + 800996a: 0018 movs r0, r3 + 800996c: f7fa fe78 bl 8004660 + 8009970: 0003 movs r3, r0 + 8009972: 6878 ldr r0, [r7, #4] + 8009974: 2200 movs r2, #0 + 8009976: 0021 movs r1, r4 + 8009978: f7ff fc94 bl 80092a4 + 800997c: 0003 movs r3, r0 + 800997e: 613b str r3, [r7, #16] + if (p == NULL) { + 8009980: 693b ldr r3, [r7, #16] + 8009982: 2b00 cmp r3, #0 + 8009984: d102 bne.n 800998c + LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_output: (ACK) could not allocate pbuf\n")); + return ERR_BUF; + 8009986: 2302 movs r3, #2 + 8009988: 425b negs r3, r3 + 800998a: e03d b.n 8009a08 + } + tcphdr = (struct tcp_hdr *)p->payload; + 800998c: 693b ldr r3, [r7, #16] + 800998e: 685b ldr r3, [r3, #4] + 8009990: 60fb str r3, [r7, #12] + LWIP_DEBUGF(TCP_OUTPUT_DEBUG, + ("tcp_output: sending ACK for %"U32_F"\n", pcb->rcv_nxt)); + /* remove ACK flags from the PCB, as we send an empty ACK now */ + pcb->flags &= ~(TF_ACK_DELAY | TF_ACK_NOW); + 8009992: 687b ldr r3, [r7, #4] + 8009994: 7f9b ldrb r3, [r3, #30] + 8009996: 2203 movs r2, #3 + 8009998: 4393 bics r3, r2 + 800999a: b2da uxtb r2, r3 + 800999c: 687b ldr r3, [r7, #4] + 800999e: 779a strb r2, [r3, #30] + tcp_build_timestamp_option(pcb, (u32_t *)(tcphdr + 1)); + } +#endif + +#if CHECKSUM_GEN_TCP + tcphdr->chksum = inet_chksum_pseudo(p, &(pcb->local_ip), &(pcb->remote_ip), + 80099a0: 6879 ldr r1, [r7, #4] + 80099a2: 687b ldr r3, [r7, #4] + 80099a4: 1d1a adds r2, r3, #4 + 80099a6: 693b ldr r3, [r7, #16] + 80099a8: 891b ldrh r3, [r3, #8] + 80099aa: 6938 ldr r0, [r7, #16] + 80099ac: 9300 str r3, [sp, #0] + 80099ae: 2306 movs r3, #6 + 80099b0: f001 fe43 bl 800b63a + 80099b4: 0003 movs r3, r0 + 80099b6: 001a movs r2, r3 + 80099b8: 68fb ldr r3, [r7, #12] + 80099ba: 21ff movs r1, #255 ; 0xff + 80099bc: 4011 ands r1, r2 + 80099be: 000c movs r4, r1 + 80099c0: 7c19 ldrb r1, [r3, #16] + 80099c2: 2000 movs r0, #0 + 80099c4: 4001 ands r1, r0 + 80099c6: 1c08 adds r0, r1, #0 + 80099c8: 1c21 adds r1, r4, #0 + 80099ca: 4301 orrs r1, r0 + 80099cc: 7419 strb r1, [r3, #16] + 80099ce: 0a12 lsrs r2, r2, #8 + 80099d0: b290 uxth r0, r2 + 80099d2: 7c5a ldrb r2, [r3, #17] + 80099d4: 2100 movs r1, #0 + 80099d6: 400a ands r2, r1 + 80099d8: 1c11 adds r1, r2, #0 + 80099da: 1c02 adds r2, r0, #0 + 80099dc: 430a orrs r2, r1 + 80099de: 745a strb r2, [r3, #17] +#endif +#if LWIP_NETIF_HWADDRHINT + ip_output_hinted(p, &(pcb->local_ip), &(pcb->remote_ip), pcb->ttl, pcb->tos, + IP_PROTO_TCP, &(pcb->addr_hint)); +#else /* LWIP_NETIF_HWADDRHINT*/ + ip_output(p, &(pcb->local_ip), &(pcb->remote_ip), pcb->ttl, pcb->tos, + 80099e0: 6879 ldr r1, [r7, #4] + 80099e2: 687b ldr r3, [r7, #4] + 80099e4: 1d1c adds r4, r3, #4 + 80099e6: 687b ldr r3, [r7, #4] + 80099e8: 7a9d ldrb r5, [r3, #10] + 80099ea: 687b ldr r3, [r7, #4] + 80099ec: 7a5b ldrb r3, [r3, #9] + 80099ee: 6938 ldr r0, [r7, #16] + 80099f0: 2206 movs r2, #6 + 80099f2: 9201 str r2, [sp, #4] + 80099f4: 9300 str r3, [sp, #0] + 80099f6: 002b movs r3, r5 + 80099f8: 0022 movs r2, r4 + 80099fa: f002 fb09 bl 800c010 + IP_PROTO_TCP); +#endif /* LWIP_NETIF_HWADDRHINT*/ + pbuf_free(p); + 80099fe: 693b ldr r3, [r7, #16] + 8009a00: 0018 movs r0, r3 + 8009a02: f7fb fe4f bl 80056a4 + + return ERR_OK; + 8009a06: 2300 movs r3, #0 +} + 8009a08: 0018 movs r0, r3 + 8009a0a: 46bd mov sp, r7 + 8009a0c: b006 add sp, #24 + 8009a0e: bdb0 pop {r4, r5, r7, pc} + +08009a10 : + * @return ERR_OK if data has been sent or nothing to send + * another err_t on error + */ +err_t +tcp_output(struct tcp_pcb *pcb) +{ + 8009a10: b5b0 push {r4, r5, r7, lr} + 8009a12: b088 sub sp, #32 + 8009a14: af00 add r7, sp, #0 + 8009a16: 6078 str r0, [r7, #4] + + /* First, check if we are invoked by the TCP input processing + code. If so, we do not output anything. Instead, we rely on the + input processing code to call us when input processing is done + with. */ + if (tcp_input_pcb == pcb) { + 8009a18: 4bcd ldr r3, [pc, #820] ; (8009d50 ) + 8009a1a: 681b ldr r3, [r3, #0] + 8009a1c: 687a ldr r2, [r7, #4] + 8009a1e: 429a cmp r2, r3 + 8009a20: d101 bne.n 8009a26 + return ERR_OK; + 8009a22: 2300 movs r3, #0 + 8009a24: e1a7 b.n 8009d76 + } + + wnd = LWIP_MIN(pcb->snd_wnd, pcb->cwnd); + 8009a26: 687b ldr r3, [r7, #4] + 8009a28: 2260 movs r2, #96 ; 0x60 + 8009a2a: 5a9a ldrh r2, [r3, r2] + 8009a2c: 687b ldr r3, [r7, #4] + 8009a2e: 214c movs r1, #76 ; 0x4c + 8009a30: 5a5b ldrh r3, [r3, r1] + 8009a32: 429a cmp r2, r3 + 8009a34: d203 bcs.n 8009a3e + 8009a36: 687b ldr r3, [r7, #4] + 8009a38: 2260 movs r2, #96 ; 0x60 + 8009a3a: 5a9b ldrh r3, [r3, r2] + 8009a3c: e002 b.n 8009a44 + 8009a3e: 687b ldr r3, [r7, #4] + 8009a40: 224c movs r2, #76 ; 0x4c + 8009a42: 5a9b ldrh r3, [r3, r2] + 8009a44: 613b str r3, [r7, #16] + + seg = pcb->unsent; + 8009a46: 687b ldr r3, [r7, #4] + 8009a48: 6edb ldr r3, [r3, #108] ; 0x6c + 8009a4a: 61fb str r3, [r7, #28] + * because the ->unsent queue is empty or because the window does + * not allow it), construct an empty ACK segment and send it. + * + * If data is to be sent, we will just piggyback the ACK (see below). + */ + if (pcb->flags & TF_ACK_NOW && + 8009a4c: 687b ldr r3, [r7, #4] + 8009a4e: 7f9b ldrb r3, [r3, #30] + 8009a50: 001a movs r2, r3 + 8009a52: 2302 movs r3, #2 + 8009a54: 4013 ands r3, r2 + 8009a56: d021 beq.n 8009a9c + 8009a58: 69fb ldr r3, [r7, #28] + 8009a5a: 2b00 cmp r3, #0 + 8009a5c: d018 beq.n 8009a90 + (seg == NULL || + ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len > wnd)) { + 8009a5e: 69fb ldr r3, [r7, #28] + 8009a60: 68db ldr r3, [r3, #12] + 8009a62: 791a ldrb r2, [r3, #4] + 8009a64: 7959 ldrb r1, [r3, #5] + 8009a66: 0209 lsls r1, r1, #8 + 8009a68: 430a orrs r2, r1 + 8009a6a: 7999 ldrb r1, [r3, #6] + 8009a6c: 0409 lsls r1, r1, #16 + 8009a6e: 430a orrs r2, r1 + 8009a70: 79db ldrb r3, [r3, #7] + 8009a72: 061b lsls r3, r3, #24 + 8009a74: 4313 orrs r3, r2 + 8009a76: 0018 movs r0, r3 + 8009a78: f7fa fe0b bl 8004692 + 8009a7c: 0002 movs r2, r0 + 8009a7e: 687b ldr r3, [r7, #4] + 8009a80: 6c9b ldr r3, [r3, #72] ; 0x48 + 8009a82: 1ad3 subs r3, r2, r3 + 8009a84: 69fa ldr r2, [r7, #28] + 8009a86: 8912 ldrh r2, [r2, #8] + 8009a88: 189b adds r3, r3, r2 + (seg == NULL || + 8009a8a: 693a ldr r2, [r7, #16] + 8009a8c: 429a cmp r2, r3 + 8009a8e: d205 bcs.n 8009a9c + return tcp_send_empty_ack(pcb); + 8009a90: 687b ldr r3, [r7, #4] + 8009a92: 0018 movs r0, r3 + 8009a94: f7ff ff5c bl 8009950 + 8009a98: 0003 movs r3, r0 + 8009a9a: e16c b.n 8009d76 + } + + /* useg should point to last segment on unacked queue */ + useg = pcb->unacked; + 8009a9c: 687b ldr r3, [r7, #4] + 8009a9e: 6f1b ldr r3, [r3, #112] ; 0x70 + 8009aa0: 61bb str r3, [r7, #24] + if (useg != NULL) { + 8009aa2: 69bb ldr r3, [r7, #24] + 8009aa4: 2b00 cmp r3, #0 + 8009aa6: d100 bne.n 8009aaa + 8009aa8: e133 b.n 8009d12 + for (; useg->next != NULL; useg = useg->next); + 8009aaa: e002 b.n 8009ab2 + 8009aac: 69bb ldr r3, [r7, #24] + 8009aae: 681b ldr r3, [r3, #0] + 8009ab0: 61bb str r3, [r7, #24] + 8009ab2: 69bb ldr r3, [r7, #24] + 8009ab4: 681b ldr r3, [r3, #0] + 8009ab6: 2b00 cmp r3, #0 + 8009ab8: d1f8 bne.n 8009aac + ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len, + ntohl(seg->tcphdr->seqno), pcb->lastack)); + } +#endif /* TCP_CWND_DEBUG */ + /* data available and window allows it to be sent? */ + while (seg != NULL && + 8009aba: e12a b.n 8009d12 + ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len <= wnd) { + LWIP_ASSERT("RST not expected here!", + 8009abc: 69fb ldr r3, [r7, #28] + 8009abe: 68db ldr r3, [r3, #12] + 8009ac0: 7b1a ldrb r2, [r3, #12] + 8009ac2: 7b5b ldrb r3, [r3, #13] + 8009ac4: 021b lsls r3, r3, #8 + 8009ac6: 4313 orrs r3, r2 + 8009ac8: b29b uxth r3, r3 + 8009aca: 0018 movs r0, r3 + 8009acc: f7fa fdb8 bl 8004640 + * - if tcp_write had a memory error before (prevent delayed ACK timeout) or + * - if FIN was already enqueued for this PCB (SYN is always alone in a segment - + * either seg->next != NULL or pcb->unacked == NULL; + * RST is no sent using tcp_write/tcp_output. + */ + if((tcp_do_output_nagle(pcb) == 0) && + 8009ad0: 687b ldr r3, [r7, #4] + 8009ad2: 6f1b ldr r3, [r3, #112] ; 0x70 + 8009ad4: 2b00 cmp r3, #0 + 8009ad6: d01f beq.n 8009b18 + 8009ad8: 687b ldr r3, [r7, #4] + 8009ada: 7f9b ldrb r3, [r3, #30] + 8009adc: 001a movs r2, r3 + 8009ade: 2344 movs r3, #68 ; 0x44 + 8009ae0: 4013 ands r3, r2 + 8009ae2: d119 bne.n 8009b18 + 8009ae4: 687b ldr r3, [r7, #4] + 8009ae6: 6edb ldr r3, [r3, #108] ; 0x6c + 8009ae8: 2b00 cmp r3, #0 + 8009aea: d00b beq.n 8009b04 + 8009aec: 687b ldr r3, [r7, #4] + 8009aee: 6edb ldr r3, [r3, #108] ; 0x6c + 8009af0: 681b ldr r3, [r3, #0] + 8009af2: 2b00 cmp r3, #0 + 8009af4: d110 bne.n 8009b18 + 8009af6: 687b ldr r3, [r7, #4] + 8009af8: 6edb ldr r3, [r3, #108] ; 0x6c + 8009afa: 891a ldrh r2, [r3, #8] + 8009afc: 687b ldr r3, [r7, #4] + 8009afe: 8edb ldrh r3, [r3, #54] ; 0x36 + 8009b00: 429a cmp r2, r3 + 8009b02: d209 bcs.n 8009b18 + 8009b04: 687b ldr r3, [r7, #4] + 8009b06: 2266 movs r2, #102 ; 0x66 + 8009b08: 5a9b ldrh r3, [r3, r2] + 8009b0a: 2b00 cmp r3, #0 + 8009b0c: d004 beq.n 8009b18 + 8009b0e: 687b ldr r3, [r7, #4] + 8009b10: 2268 movs r2, #104 ; 0x68 + 8009b12: 5a9b ldrh r3, [r3, r2] + 8009b14: 2b07 cmp r3, #7 + 8009b16: d901 bls.n 8009b1c + 8009b18: 2301 movs r3, #1 + 8009b1a: e000 b.n 8009b1e + 8009b1c: 2300 movs r3, #0 + 8009b1e: 2b00 cmp r3, #0 + 8009b20: d106 bne.n 8009b30 + ((pcb->flags & (TF_NAGLEMEMERR | TF_FIN)) == 0)){ + 8009b22: 687b ldr r3, [r7, #4] + 8009b24: 7f9b ldrb r3, [r3, #30] + 8009b26: 001a movs r2, r3 + 8009b28: 23a0 movs r3, #160 ; 0xa0 + 8009b2a: 4013 ands r3, r2 + if((tcp_do_output_nagle(pcb) == 0) && + 8009b2c: d100 bne.n 8009b30 + 8009b2e: e111 b.n 8009d54 + pcb->lastack, + ntohl(seg->tcphdr->seqno), pcb->lastack, i)); + ++i; +#endif /* TCP_CWND_DEBUG */ + + pcb->unsent = seg->next; + 8009b30: 69fb ldr r3, [r7, #28] + 8009b32: 681a ldr r2, [r3, #0] + 8009b34: 687b ldr r3, [r7, #4] + 8009b36: 66da str r2, [r3, #108] ; 0x6c + + if (pcb->state != SYN_SENT) { + 8009b38: 687b ldr r3, [r7, #4] + 8009b3a: 7e1b ldrb r3, [r3, #24] + 8009b3c: 2b02 cmp r3, #2 + 8009b3e: d029 beq.n 8009b94 + TCPH_SET_FLAG(seg->tcphdr, TCP_ACK); + 8009b40: 69fb ldr r3, [r7, #28] + 8009b42: 68db ldr r3, [r3, #12] + 8009b44: 7b1a ldrb r2, [r3, #12] + 8009b46: 7b5b ldrb r3, [r3, #13] + 8009b48: 021b lsls r3, r3, #8 + 8009b4a: 4313 orrs r3, r2 + 8009b4c: b29c uxth r4, r3 + 8009b4e: 2010 movs r0, #16 + 8009b50: f7fa fd60 bl 8004614 + 8009b54: 0003 movs r3, r0 + 8009b56: 001a movs r2, r3 + 8009b58: 69fb ldr r3, [r7, #28] + 8009b5a: 68db ldr r3, [r3, #12] + 8009b5c: 4322 orrs r2, r4 + 8009b5e: b292 uxth r2, r2 + 8009b60: 21ff movs r1, #255 ; 0xff + 8009b62: 4011 ands r1, r2 + 8009b64: 000c movs r4, r1 + 8009b66: 7b19 ldrb r1, [r3, #12] + 8009b68: 2000 movs r0, #0 + 8009b6a: 4001 ands r1, r0 + 8009b6c: 1c08 adds r0, r1, #0 + 8009b6e: 1c21 adds r1, r4, #0 + 8009b70: 4301 orrs r1, r0 + 8009b72: 7319 strb r1, [r3, #12] + 8009b74: 0a12 lsrs r2, r2, #8 + 8009b76: b290 uxth r0, r2 + 8009b78: 7b5a ldrb r2, [r3, #13] + 8009b7a: 2100 movs r1, #0 + 8009b7c: 400a ands r2, r1 + 8009b7e: 1c11 adds r1, r2, #0 + 8009b80: 1c02 adds r2, r0, #0 + 8009b82: 430a orrs r2, r1 + 8009b84: 735a strb r2, [r3, #13] + pcb->flags &= ~(TF_ACK_DELAY | TF_ACK_NOW); + 8009b86: 687b ldr r3, [r7, #4] + 8009b88: 7f9b ldrb r3, [r3, #30] + 8009b8a: 2203 movs r2, #3 + 8009b8c: 4393 bics r3, r2 + 8009b8e: b2da uxtb r2, r3 + 8009b90: 687b ldr r3, [r7, #4] + 8009b92: 779a strb r2, [r3, #30] + } + + tcp_output_segment(seg, pcb); + 8009b94: 687a ldr r2, [r7, #4] + 8009b96: 69fb ldr r3, [r7, #28] + 8009b98: 0011 movs r1, r2 + 8009b9a: 0018 movs r0, r3 + 8009b9c: f000 f8f0 bl 8009d80 + snd_nxt = ntohl(seg->tcphdr->seqno) + TCP_TCPLEN(seg); + 8009ba0: 69fb ldr r3, [r7, #28] + 8009ba2: 68db ldr r3, [r3, #12] + 8009ba4: 791a ldrb r2, [r3, #4] + 8009ba6: 7959 ldrb r1, [r3, #5] + 8009ba8: 0209 lsls r1, r1, #8 + 8009baa: 430a orrs r2, r1 + 8009bac: 7999 ldrb r1, [r3, #6] + 8009bae: 0409 lsls r1, r1, #16 + 8009bb0: 430a orrs r2, r1 + 8009bb2: 79db ldrb r3, [r3, #7] + 8009bb4: 061b lsls r3, r3, #24 + 8009bb6: 4313 orrs r3, r2 + 8009bb8: 0018 movs r0, r3 + 8009bba: f7fa fd6a bl 8004692 + 8009bbe: 0004 movs r4, r0 + 8009bc0: 69fb ldr r3, [r7, #28] + 8009bc2: 891b ldrh r3, [r3, #8] + 8009bc4: 001d movs r5, r3 + 8009bc6: 69fb ldr r3, [r7, #28] + 8009bc8: 68db ldr r3, [r3, #12] + 8009bca: 7b1a ldrb r2, [r3, #12] + 8009bcc: 7b5b ldrb r3, [r3, #13] + 8009bce: 021b lsls r3, r3, #8 + 8009bd0: 4313 orrs r3, r2 + 8009bd2: b29b uxth r3, r3 + 8009bd4: 0018 movs r0, r3 + 8009bd6: f7fa fd33 bl 8004640 + 8009bda: 0003 movs r3, r0 + 8009bdc: 001a movs r2, r3 + 8009bde: 2303 movs r3, #3 + 8009be0: 4013 ands r3, r2 + 8009be2: 1e5a subs r2, r3, #1 + 8009be4: 4193 sbcs r3, r2 + 8009be6: b2db uxtb r3, r3 + 8009be8: 18eb adds r3, r5, r3 + 8009bea: 18e3 adds r3, r4, r3 + 8009bec: 60fb str r3, [r7, #12] + if (TCP_SEQ_LT(pcb->snd_nxt, snd_nxt)) { + 8009bee: 687b ldr r3, [r7, #4] + 8009bf0: 6d1a ldr r2, [r3, #80] ; 0x50 + 8009bf2: 68fb ldr r3, [r7, #12] + 8009bf4: 1ad3 subs r3, r2, r3 + 8009bf6: d502 bpl.n 8009bfe + pcb->snd_nxt = snd_nxt; + 8009bf8: 687b ldr r3, [r7, #4] + 8009bfa: 68fa ldr r2, [r7, #12] + 8009bfc: 651a str r2, [r3, #80] ; 0x50 + } + /* put segment on unacknowledged list if length > 0 */ + if (TCP_TCPLEN(seg) > 0) { + 8009bfe: 69fb ldr r3, [r7, #28] + 8009c00: 891b ldrh r3, [r3, #8] + 8009c02: 001c movs r4, r3 + 8009c04: 69fb ldr r3, [r7, #28] + 8009c06: 68db ldr r3, [r3, #12] + 8009c08: 7b1a ldrb r2, [r3, #12] + 8009c0a: 7b5b ldrb r3, [r3, #13] + 8009c0c: 021b lsls r3, r3, #8 + 8009c0e: 4313 orrs r3, r2 + 8009c10: b29b uxth r3, r3 + 8009c12: 0018 movs r0, r3 + 8009c14: f7fa fd14 bl 8004640 + 8009c18: 0003 movs r3, r0 + 8009c1a: 001a movs r2, r3 + 8009c1c: 2303 movs r3, #3 + 8009c1e: 4013 ands r3, r2 + 8009c20: 1e5a subs r2, r3, #1 + 8009c22: 4193 sbcs r3, r2 + 8009c24: b2db uxtb r3, r3 + 8009c26: 18e3 adds r3, r4, r3 + 8009c28: 2b00 cmp r3, #0 + 8009c2a: dd6b ble.n 8009d04 + seg->next = NULL; + 8009c2c: 69fb ldr r3, [r7, #28] + 8009c2e: 2200 movs r2, #0 + 8009c30: 601a str r2, [r3, #0] + /* unacked list is empty? */ + if (pcb->unacked == NULL) { + 8009c32: 687b ldr r3, [r7, #4] + 8009c34: 6f1b ldr r3, [r3, #112] ; 0x70 + 8009c36: 2b00 cmp r3, #0 + 8009c38: d105 bne.n 8009c46 + pcb->unacked = seg; + 8009c3a: 687b ldr r3, [r7, #4] + 8009c3c: 69fa ldr r2, [r7, #28] + 8009c3e: 671a str r2, [r3, #112] ; 0x70 + useg = seg; + 8009c40: 69fb ldr r3, [r7, #28] + 8009c42: 61bb str r3, [r7, #24] + 8009c44: e062 b.n 8009d0c + /* unacked list is not empty? */ + } else { + /* In the case of fast retransmit, the packet should not go to the tail + * of the unacked queue, but rather somewhere before it. We need to check for + * this case. -STJ Jul 27, 2004 */ + if (TCP_SEQ_LT(ntohl(seg->tcphdr->seqno), ntohl(useg->tcphdr->seqno))) { + 8009c46: 69fb ldr r3, [r7, #28] + 8009c48: 68db ldr r3, [r3, #12] + 8009c4a: 791a ldrb r2, [r3, #4] + 8009c4c: 7959 ldrb r1, [r3, #5] + 8009c4e: 0209 lsls r1, r1, #8 + 8009c50: 430a orrs r2, r1 + 8009c52: 7999 ldrb r1, [r3, #6] + 8009c54: 0409 lsls r1, r1, #16 + 8009c56: 430a orrs r2, r1 + 8009c58: 79db ldrb r3, [r3, #7] + 8009c5a: 061b lsls r3, r3, #24 + 8009c5c: 4313 orrs r3, r2 + 8009c5e: 0018 movs r0, r3 + 8009c60: f7fa fd17 bl 8004692 + 8009c64: 0004 movs r4, r0 + 8009c66: 69bb ldr r3, [r7, #24] + 8009c68: 68db ldr r3, [r3, #12] + 8009c6a: 791a ldrb r2, [r3, #4] + 8009c6c: 7959 ldrb r1, [r3, #5] + 8009c6e: 0209 lsls r1, r1, #8 + 8009c70: 430a orrs r2, r1 + 8009c72: 7999 ldrb r1, [r3, #6] + 8009c74: 0409 lsls r1, r1, #16 + 8009c76: 430a orrs r2, r1 + 8009c78: 79db ldrb r3, [r3, #7] + 8009c7a: 061b lsls r3, r3, #24 + 8009c7c: 4313 orrs r3, r2 + 8009c7e: 0018 movs r0, r3 + 8009c80: f7fa fd07 bl 8004692 + 8009c84: 0003 movs r3, r0 + 8009c86: 1ae3 subs r3, r4, r3 + 8009c88: d535 bpl.n 8009cf6 + /* add segment to before tail of unacked list, keeping the list sorted */ + struct tcp_seg **cur_seg = &(pcb->unacked); + 8009c8a: 687b ldr r3, [r7, #4] + 8009c8c: 3370 adds r3, #112 ; 0x70 + 8009c8e: 617b str r3, [r7, #20] + while (*cur_seg && + 8009c90: e002 b.n 8009c98 + TCP_SEQ_LT(ntohl((*cur_seg)->tcphdr->seqno), ntohl(seg->tcphdr->seqno))) { + cur_seg = &((*cur_seg)->next ); + 8009c92: 697b ldr r3, [r7, #20] + 8009c94: 681b ldr r3, [r3, #0] + 8009c96: 617b str r3, [r7, #20] + while (*cur_seg && + 8009c98: 697b ldr r3, [r7, #20] + 8009c9a: 681b ldr r3, [r3, #0] + 8009c9c: 2b00 cmp r3, #0 + 8009c9e: d022 beq.n 8009ce6 + TCP_SEQ_LT(ntohl((*cur_seg)->tcphdr->seqno), ntohl(seg->tcphdr->seqno))) { + 8009ca0: 697b ldr r3, [r7, #20] + 8009ca2: 681b ldr r3, [r3, #0] + 8009ca4: 68db ldr r3, [r3, #12] + 8009ca6: 791a ldrb r2, [r3, #4] + 8009ca8: 7959 ldrb r1, [r3, #5] + 8009caa: 0209 lsls r1, r1, #8 + 8009cac: 430a orrs r2, r1 + 8009cae: 7999 ldrb r1, [r3, #6] + 8009cb0: 0409 lsls r1, r1, #16 + 8009cb2: 430a orrs r2, r1 + 8009cb4: 79db ldrb r3, [r3, #7] + 8009cb6: 061b lsls r3, r3, #24 + 8009cb8: 4313 orrs r3, r2 + 8009cba: 0018 movs r0, r3 + 8009cbc: f7fa fce9 bl 8004692 + 8009cc0: 0004 movs r4, r0 + 8009cc2: 69fb ldr r3, [r7, #28] + 8009cc4: 68db ldr r3, [r3, #12] + 8009cc6: 791a ldrb r2, [r3, #4] + 8009cc8: 7959 ldrb r1, [r3, #5] + 8009cca: 0209 lsls r1, r1, #8 + 8009ccc: 430a orrs r2, r1 + 8009cce: 7999 ldrb r1, [r3, #6] + 8009cd0: 0409 lsls r1, r1, #16 + 8009cd2: 430a orrs r2, r1 + 8009cd4: 79db ldrb r3, [r3, #7] + 8009cd6: 061b lsls r3, r3, #24 + 8009cd8: 4313 orrs r3, r2 + 8009cda: 0018 movs r0, r3 + 8009cdc: f7fa fcd9 bl 8004692 + 8009ce0: 0003 movs r3, r0 + 8009ce2: 1ae3 subs r3, r4, r3 + while (*cur_seg && + 8009ce4: d4d5 bmi.n 8009c92 + } + seg->next = (*cur_seg); + 8009ce6: 697b ldr r3, [r7, #20] + 8009ce8: 681a ldr r2, [r3, #0] + 8009cea: 69fb ldr r3, [r7, #28] + 8009cec: 601a str r2, [r3, #0] + (*cur_seg) = seg; + 8009cee: 697b ldr r3, [r7, #20] + 8009cf0: 69fa ldr r2, [r7, #28] + 8009cf2: 601a str r2, [r3, #0] + 8009cf4: e00a b.n 8009d0c + } else { + /* add segment to tail of unacked list */ + useg->next = seg; + 8009cf6: 69bb ldr r3, [r7, #24] + 8009cf8: 69fa ldr r2, [r7, #28] + 8009cfa: 601a str r2, [r3, #0] + useg = useg->next; + 8009cfc: 69bb ldr r3, [r7, #24] + 8009cfe: 681b ldr r3, [r3, #0] + 8009d00: 61bb str r3, [r7, #24] + 8009d02: e003 b.n 8009d0c + } + } + /* do not queue empty segments on the unacked list */ + } else { + tcp_seg_free(seg); + 8009d04: 69fb ldr r3, [r7, #28] + 8009d06: 0018 movs r0, r3 + 8009d08: f7fc fd09 bl 800671e + } + seg = pcb->unsent; + 8009d0c: 687b ldr r3, [r7, #4] + 8009d0e: 6edb ldr r3, [r3, #108] ; 0x6c + 8009d10: 61fb str r3, [r7, #28] + while (seg != NULL && + 8009d12: 69fb ldr r3, [r7, #28] + 8009d14: 2b00 cmp r3, #0 + 8009d16: d01e beq.n 8009d56 + ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len <= wnd) { + 8009d18: 69fb ldr r3, [r7, #28] + 8009d1a: 68db ldr r3, [r3, #12] + 8009d1c: 791a ldrb r2, [r3, #4] + 8009d1e: 7959 ldrb r1, [r3, #5] + 8009d20: 0209 lsls r1, r1, #8 + 8009d22: 430a orrs r2, r1 + 8009d24: 7999 ldrb r1, [r3, #6] + 8009d26: 0409 lsls r1, r1, #16 + 8009d28: 430a orrs r2, r1 + 8009d2a: 79db ldrb r3, [r3, #7] + 8009d2c: 061b lsls r3, r3, #24 + 8009d2e: 4313 orrs r3, r2 + 8009d30: 0018 movs r0, r3 + 8009d32: f7fa fcae bl 8004692 + 8009d36: 0002 movs r2, r0 + 8009d38: 687b ldr r3, [r7, #4] + 8009d3a: 6c9b ldr r3, [r3, #72] ; 0x48 + 8009d3c: 1ad3 subs r3, r2, r3 + 8009d3e: 69fa ldr r2, [r7, #28] + 8009d40: 8912 ldrh r2, [r2, #8] + 8009d42: 189b adds r3, r3, r2 + while (seg != NULL && + 8009d44: 693a ldr r2, [r7, #16] + 8009d46: 429a cmp r2, r3 + 8009d48: d300 bcc.n 8009d4c + 8009d4a: e6b7 b.n 8009abc + 8009d4c: e003 b.n 8009d56 + 8009d4e: 46c0 nop ; (mov r8, r8) + 8009d50: 2000328c .word 0x2000328c + break; + 8009d54: 46c0 nop ; (mov r8, r8) + } +#if TCP_OVERSIZE + if (pcb->unsent == NULL) { + 8009d56: 687b ldr r3, [r7, #4] + 8009d58: 6edb ldr r3, [r3, #108] ; 0x6c + 8009d5a: 2b00 cmp r3, #0 + 8009d5c: d103 bne.n 8009d66 + /* last unsent has been removed, reset unsent_oversize */ + pcb->unsent_oversize = 0; + 8009d5e: 687b ldr r3, [r7, #4] + 8009d60: 226a movs r2, #106 ; 0x6a + 8009d62: 2100 movs r1, #0 + 8009d64: 5299 strh r1, [r3, r2] + } +#endif /* TCP_OVERSIZE */ + + pcb->flags &= ~TF_NAGLEMEMERR; + 8009d66: 687b ldr r3, [r7, #4] + 8009d68: 7f9b ldrb r3, [r3, #30] + 8009d6a: 227f movs r2, #127 ; 0x7f + 8009d6c: 4013 ands r3, r2 + 8009d6e: b2da uxtb r2, r3 + 8009d70: 687b ldr r3, [r7, #4] + 8009d72: 779a strb r2, [r3, #30] + return ERR_OK; + 8009d74: 2300 movs r3, #0 +} + 8009d76: 0018 movs r0, r3 + 8009d78: 46bd mov sp, r7 + 8009d7a: b008 add sp, #32 + 8009d7c: bdb0 pop {r4, r5, r7, pc} + 8009d7e: 46c0 nop ; (mov r8, r8) + +08009d80 : + * @param seg the tcp_seg to send + * @param pcb the tcp_pcb for the TCP connection used to send the segment + */ +static void +tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb) +{ + 8009d80: b5b0 push {r4, r5, r7, lr} + 8009d82: b088 sub sp, #32 + 8009d84: af02 add r7, sp, #8 + 8009d86: 6078 str r0, [r7, #4] + 8009d88: 6039 str r1, [r7, #0] + /** @bug Exclude retransmitted segments from this count. */ + snmp_inc_tcpoutsegs(); + + /* The TCP header has already been constructed, but the ackno and + wnd fields remain. */ + seg->tcphdr->ackno = htonl(pcb->rcv_nxt); + 8009d8a: 683b ldr r3, [r7, #0] + 8009d8c: 6a9a ldr r2, [r3, #40] ; 0x28 + 8009d8e: 687b ldr r3, [r7, #4] + 8009d90: 68dc ldr r4, [r3, #12] + 8009d92: 0010 movs r0, r2 + 8009d94: f7fa fc64 bl 8004660 + 8009d98: 0003 movs r3, r0 + 8009d9a: 22ff movs r2, #255 ; 0xff + 8009d9c: 401a ands r2, r3 + 8009d9e: 0010 movs r0, r2 + 8009da0: 7a22 ldrb r2, [r4, #8] + 8009da2: 2100 movs r1, #0 + 8009da4: 400a ands r2, r1 + 8009da6: 1c11 adds r1, r2, #0 + 8009da8: 1c02 adds r2, r0, #0 + 8009daa: 430a orrs r2, r1 + 8009dac: 7222 strb r2, [r4, #8] + 8009dae: 0a1a lsrs r2, r3, #8 + 8009db0: 21ff movs r1, #255 ; 0xff + 8009db2: 400a ands r2, r1 + 8009db4: 0010 movs r0, r2 + 8009db6: 7a62 ldrb r2, [r4, #9] + 8009db8: 2100 movs r1, #0 + 8009dba: 400a ands r2, r1 + 8009dbc: 1c11 adds r1, r2, #0 + 8009dbe: 1c02 adds r2, r0, #0 + 8009dc0: 430a orrs r2, r1 + 8009dc2: 7262 strb r2, [r4, #9] + 8009dc4: 0c1a lsrs r2, r3, #16 + 8009dc6: 21ff movs r1, #255 ; 0xff + 8009dc8: 400a ands r2, r1 + 8009dca: 0010 movs r0, r2 + 8009dcc: 7aa2 ldrb r2, [r4, #10] + 8009dce: 2100 movs r1, #0 + 8009dd0: 400a ands r2, r1 + 8009dd2: 1c11 adds r1, r2, #0 + 8009dd4: 1c02 adds r2, r0, #0 + 8009dd6: 430a orrs r2, r1 + 8009dd8: 72a2 strb r2, [r4, #10] + 8009dda: 0e19 lsrs r1, r3, #24 + 8009ddc: 7ae3 ldrb r3, [r4, #11] + 8009dde: 2200 movs r2, #0 + 8009de0: 4013 ands r3, r2 + 8009de2: 1c1a adds r2, r3, #0 + 8009de4: 1c0b adds r3, r1, #0 + 8009de6: 4313 orrs r3, r2 + 8009de8: 72e3 strb r3, [r4, #11] + + /* advertise our receive window size in this TCP segment */ + seg->tcphdr->wnd = htons(pcb->rcv_ann_wnd); + 8009dea: 683b ldr r3, [r7, #0] + 8009dec: 8dda ldrh r2, [r3, #46] ; 0x2e + 8009dee: 687b ldr r3, [r7, #4] + 8009df0: 68dc ldr r4, [r3, #12] + 8009df2: 0010 movs r0, r2 + 8009df4: f7fa fc0e bl 8004614 + 8009df8: 0003 movs r3, r0 + 8009dfa: 22ff movs r2, #255 ; 0xff + 8009dfc: 401a ands r2, r3 + 8009dfe: 0010 movs r0, r2 + 8009e00: 7ba2 ldrb r2, [r4, #14] + 8009e02: 2100 movs r1, #0 + 8009e04: 400a ands r2, r1 + 8009e06: 1c11 adds r1, r2, #0 + 8009e08: 1c02 adds r2, r0, #0 + 8009e0a: 430a orrs r2, r1 + 8009e0c: 73a2 strb r2, [r4, #14] + 8009e0e: 0a1b lsrs r3, r3, #8 + 8009e10: b299 uxth r1, r3 + 8009e12: 7be3 ldrb r3, [r4, #15] + 8009e14: 2200 movs r2, #0 + 8009e16: 4013 ands r3, r2 + 8009e18: 1c1a adds r2, r3, #0 + 8009e1a: 1c0b adds r3, r1, #0 + 8009e1c: 4313 orrs r3, r2 + 8009e1e: 73e3 strb r3, [r4, #15] + + pcb->rcv_ann_right_edge = pcb->rcv_nxt + pcb->rcv_ann_wnd; + 8009e20: 683b ldr r3, [r7, #0] + 8009e22: 6a9b ldr r3, [r3, #40] ; 0x28 + 8009e24: 683a ldr r2, [r7, #0] + 8009e26: 8dd2 ldrh r2, [r2, #46] ; 0x2e + 8009e28: 189a adds r2, r3, r2 + 8009e2a: 683b ldr r3, [r7, #0] + 8009e2c: 631a str r2, [r3, #48] ; 0x30 + + /* Add any requested options. NB MSS option is only set on SYN + packets, so ignore it here */ + opts = (u32_t *)(void *)(seg->tcphdr + 1); + 8009e2e: 687b ldr r3, [r7, #4] + 8009e30: 68db ldr r3, [r3, #12] + 8009e32: 3314 adds r3, #20 + 8009e34: 617b str r3, [r7, #20] + if (seg->flags & TF_SEG_OPTS_MSS) { + 8009e36: 687b ldr r3, [r7, #4] + 8009e38: 7a9b ldrb r3, [r3, #10] + 8009e3a: 001a movs r2, r3 + 8009e3c: 2301 movs r3, #1 + 8009e3e: 4013 ands r3, r2 + 8009e40: d018 beq.n 8009e74 + u16_t mss; +#if TCP_CALCULATE_EFF_SEND_MSS + mss = tcp_eff_send_mss(TCP_MSS, &pcb->remote_ip); + 8009e42: 683b ldr r3, [r7, #0] + 8009e44: 3304 adds r3, #4 + 8009e46: 2512 movs r5, #18 + 8009e48: 197c adds r4, r7, r5 + 8009e4a: 4a5d ldr r2, [pc, #372] ; (8009fc0 ) + 8009e4c: 0019 movs r1, r3 + 8009e4e: 0010 movs r0, r2 + 8009e50: f7fc fe92 bl 8006b78 + 8009e54: 0003 movs r3, r0 + 8009e56: 8023 strh r3, [r4, #0] +#else /* TCP_CALCULATE_EFF_SEND_MSS */ + mss = TCP_MSS; +#endif /* TCP_CALCULATE_EFF_SEND_MSS */ + *opts = TCP_BUILD_MSS_OPTION(mss); + 8009e58: 197b adds r3, r7, r5 + 8009e5a: 881b ldrh r3, [r3, #0] + 8009e5c: 2281 movs r2, #129 ; 0x81 + 8009e5e: 0492 lsls r2, r2, #18 + 8009e60: 4313 orrs r3, r2 + 8009e62: 0018 movs r0, r3 + 8009e64: f7fa fbfc bl 8004660 + 8009e68: 0002 movs r2, r0 + 8009e6a: 697b ldr r3, [r7, #20] + 8009e6c: 601a str r2, [r3, #0] + opts += 1; + 8009e6e: 697b ldr r3, [r7, #20] + 8009e70: 3304 adds r3, #4 + 8009e72: 617b str r3, [r7, #20] + } +#endif + + /* Set retransmission timer running if it is not currently enabled + This must be set before checking the route. */ + if (pcb->rtime == -1) { + 8009e74: 683b ldr r3, [r7, #0] + 8009e76: 2234 movs r2, #52 ; 0x34 + 8009e78: 5e9b ldrsh r3, [r3, r2] + 8009e7a: 3301 adds r3, #1 + 8009e7c: d102 bne.n 8009e84 + pcb->rtime = 0; + 8009e7e: 683b ldr r3, [r7, #0] + 8009e80: 2200 movs r2, #0 + 8009e82: 869a strh r2, [r3, #52] ; 0x34 + } + + /* If we don't have a local IP address, we get one by + calling ip_route(). */ + if (ip_addr_isany(&(pcb->local_ip))) { + 8009e84: 683b ldr r3, [r7, #0] + 8009e86: 2b00 cmp r3, #0 + 8009e88: d003 beq.n 8009e92 + 8009e8a: 683b ldr r3, [r7, #0] + 8009e8c: 681b ldr r3, [r3, #0] + 8009e8e: 2b00 cmp r3, #0 + 8009e90: d10e bne.n 8009eb0 + netif = ip_route(&(pcb->remote_ip)); + 8009e92: 683b ldr r3, [r7, #0] + 8009e94: 3304 adds r3, #4 + 8009e96: 0018 movs r0, r3 + 8009e98: f001 fcd6 bl 800b848 + 8009e9c: 0003 movs r3, r0 + 8009e9e: 60fb str r3, [r7, #12] + if (netif == NULL) { + 8009ea0: 68fb ldr r3, [r7, #12] + 8009ea2: 2b00 cmp r3, #0 + 8009ea4: d100 bne.n 8009ea8 + 8009ea6: e086 b.n 8009fb6 + return; + } + ip_addr_copy(pcb->local_ip, netif->ip_addr); + 8009ea8: 68fb ldr r3, [r7, #12] + 8009eaa: 685a ldr r2, [r3, #4] + 8009eac: 683b ldr r3, [r7, #0] + 8009eae: 601a str r2, [r3, #0] + } + + if (pcb->rttest == 0) { + 8009eb0: 683b ldr r3, [r7, #0] + 8009eb2: 6b9b ldr r3, [r3, #56] ; 0x38 + 8009eb4: 2b00 cmp r3, #0 + 8009eb6: d115 bne.n 8009ee4 + pcb->rttest = tcp_ticks; + 8009eb8: 4b42 ldr r3, [pc, #264] ; (8009fc4 ) + 8009eba: 681a ldr r2, [r3, #0] + 8009ebc: 683b ldr r3, [r7, #0] + 8009ebe: 639a str r2, [r3, #56] ; 0x38 + pcb->rtseq = ntohl(seg->tcphdr->seqno); + 8009ec0: 687b ldr r3, [r7, #4] + 8009ec2: 68db ldr r3, [r3, #12] + 8009ec4: 791a ldrb r2, [r3, #4] + 8009ec6: 7959 ldrb r1, [r3, #5] + 8009ec8: 0209 lsls r1, r1, #8 + 8009eca: 430a orrs r2, r1 + 8009ecc: 7999 ldrb r1, [r3, #6] + 8009ece: 0409 lsls r1, r1, #16 + 8009ed0: 430a orrs r2, r1 + 8009ed2: 79db ldrb r3, [r3, #7] + 8009ed4: 061b lsls r3, r3, #24 + 8009ed6: 4313 orrs r3, r2 + 8009ed8: 0018 movs r0, r3 + 8009eda: f7fa fbda bl 8004692 + 8009ede: 0002 movs r2, r0 + 8009ee0: 683b ldr r3, [r7, #0] + 8009ee2: 63da str r2, [r3, #60] ; 0x3c + } + LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_output_segment: %"U32_F":%"U32_F"\n", + htonl(seg->tcphdr->seqno), htonl(seg->tcphdr->seqno) + + seg->len)); + + len = (u16_t)((u8_t *)seg->tcphdr - (u8_t *)seg->p->payload); + 8009ee4: 687b ldr r3, [r7, #4] + 8009ee6: 68db ldr r3, [r3, #12] + 8009ee8: 001a movs r2, r3 + 8009eea: 687b ldr r3, [r7, #4] + 8009eec: 685b ldr r3, [r3, #4] + 8009eee: 685b ldr r3, [r3, #4] + 8009ef0: 1ad2 subs r2, r2, r3 + 8009ef2: 200a movs r0, #10 + 8009ef4: 183b adds r3, r7, r0 + 8009ef6: 801a strh r2, [r3, #0] + + seg->p->len -= len; + 8009ef8: 687b ldr r3, [r7, #4] + 8009efa: 685b ldr r3, [r3, #4] + 8009efc: 8959 ldrh r1, [r3, #10] + 8009efe: 687b ldr r3, [r7, #4] + 8009f00: 685b ldr r3, [r3, #4] + 8009f02: 183a adds r2, r7, r0 + 8009f04: 8812 ldrh r2, [r2, #0] + 8009f06: 1a8a subs r2, r1, r2 + 8009f08: b292 uxth r2, r2 + 8009f0a: 815a strh r2, [r3, #10] + seg->p->tot_len -= len; + 8009f0c: 687b ldr r3, [r7, #4] + 8009f0e: 685b ldr r3, [r3, #4] + 8009f10: 8919 ldrh r1, [r3, #8] + 8009f12: 687b ldr r3, [r7, #4] + 8009f14: 685b ldr r3, [r3, #4] + 8009f16: 183a adds r2, r7, r0 + 8009f18: 8812 ldrh r2, [r2, #0] + 8009f1a: 1a8a subs r2, r1, r2 + 8009f1c: b292 uxth r2, r2 + 8009f1e: 811a strh r2, [r3, #8] + + seg->p->payload = seg->tcphdr; + 8009f20: 687b ldr r3, [r7, #4] + 8009f22: 685b ldr r3, [r3, #4] + 8009f24: 687a ldr r2, [r7, #4] + 8009f26: 68d2 ldr r2, [r2, #12] + 8009f28: 605a str r2, [r3, #4] + + seg->tcphdr->chksum = 0; + 8009f2a: 687b ldr r3, [r7, #4] + 8009f2c: 68db ldr r3, [r3, #12] + 8009f2e: 7c1a ldrb r2, [r3, #16] + 8009f30: 2100 movs r1, #0 + 8009f32: 400a ands r2, r1 + 8009f34: 741a strb r2, [r3, #16] + 8009f36: 7c5a ldrb r2, [r3, #17] + 8009f38: 2100 movs r1, #0 + 8009f3a: 400a ands r2, r1 + 8009f3c: 745a strb r2, [r3, #17] + seg->tcphdr->chksum = chksum_slow; + } +#endif /* TCP_CHECKSUM_ON_COPY_SANITY_CHECK */ + } +#else /* TCP_CHECKSUM_ON_COPY */ + seg->tcphdr->chksum = inet_chksum_pseudo(seg->p, &(pcb->local_ip), + 8009f3e: 687b ldr r3, [r7, #4] + 8009f40: 6858 ldr r0, [r3, #4] + 8009f42: 6839 ldr r1, [r7, #0] + 8009f44: 683b ldr r3, [r7, #0] + 8009f46: 1d1d adds r5, r3, #4 + &(pcb->remote_ip), + IP_PROTO_TCP, seg->p->tot_len); + 8009f48: 687b ldr r3, [r7, #4] + 8009f4a: 685b ldr r3, [r3, #4] + seg->tcphdr->chksum = inet_chksum_pseudo(seg->p, &(pcb->local_ip), + 8009f4c: 891a ldrh r2, [r3, #8] + 8009f4e: 687b ldr r3, [r7, #4] + 8009f50: 68dc ldr r4, [r3, #12] + 8009f52: 9200 str r2, [sp, #0] + 8009f54: 2306 movs r3, #6 + 8009f56: 002a movs r2, r5 + 8009f58: f001 fb6f bl 800b63a + 8009f5c: 0003 movs r3, r0 + 8009f5e: 22ff movs r2, #255 ; 0xff + 8009f60: 401a ands r2, r3 + 8009f62: 0010 movs r0, r2 + 8009f64: 7c22 ldrb r2, [r4, #16] + 8009f66: 2100 movs r1, #0 + 8009f68: 400a ands r2, r1 + 8009f6a: 1c11 adds r1, r2, #0 + 8009f6c: 1c02 adds r2, r0, #0 + 8009f6e: 430a orrs r2, r1 + 8009f70: 7422 strb r2, [r4, #16] + 8009f72: 0a1b lsrs r3, r3, #8 + 8009f74: b299 uxth r1, r3 + 8009f76: 7c63 ldrb r3, [r4, #17] + 8009f78: 2200 movs r2, #0 + 8009f7a: 4013 ands r3, r2 + 8009f7c: 1c1a adds r2, r3, #0 + 8009f7e: 1c0b adds r3, r1, #0 + 8009f80: 4313 orrs r3, r2 + 8009f82: 7463 strb r3, [r4, #17] +#endif /* TCP_CHECKSUM_ON_COPY */ +#endif /* CHECKSUM_GEN_TCP */ + TCP_STATS_INC(tcp.xmit); + 8009f84: 4b10 ldr r3, [pc, #64] ; (8009fc8 ) + 8009f86: 2290 movs r2, #144 ; 0x90 + 8009f88: 5a9b ldrh r3, [r3, r2] + 8009f8a: 3301 adds r3, #1 + 8009f8c: b299 uxth r1, r3 + 8009f8e: 4b0e ldr r3, [pc, #56] ; (8009fc8 ) + 8009f90: 2290 movs r2, #144 ; 0x90 + 8009f92: 5299 strh r1, [r3, r2] + +#if LWIP_NETIF_HWADDRHINT + ip_output_hinted(seg->p, &(pcb->local_ip), &(pcb->remote_ip), pcb->ttl, pcb->tos, + IP_PROTO_TCP, &(pcb->addr_hint)); +#else /* LWIP_NETIF_HWADDRHINT*/ + ip_output(seg->p, &(pcb->local_ip), &(pcb->remote_ip), pcb->ttl, pcb->tos, + 8009f94: 687b ldr r3, [r7, #4] + 8009f96: 6858 ldr r0, [r3, #4] + 8009f98: 6839 ldr r1, [r7, #0] + 8009f9a: 683b ldr r3, [r7, #0] + 8009f9c: 1d1c adds r4, r3, #4 + 8009f9e: 683b ldr r3, [r7, #0] + 8009fa0: 7a9d ldrb r5, [r3, #10] + 8009fa2: 683b ldr r3, [r7, #0] + 8009fa4: 7a5b ldrb r3, [r3, #9] + 8009fa6: 2206 movs r2, #6 + 8009fa8: 9201 str r2, [sp, #4] + 8009faa: 9300 str r3, [sp, #0] + 8009fac: 002b movs r3, r5 + 8009fae: 0022 movs r2, r4 + 8009fb0: f002 f82e bl 800c010 + 8009fb4: e000 b.n 8009fb8 + return; + 8009fb6: 46c0 nop ; (mov r8, r8) + IP_PROTO_TCP); +#endif /* LWIP_NETIF_HWADDRHINT*/ +} + 8009fb8: 46bd mov sp, r7 + 8009fba: b006 add sp, #24 + 8009fbc: bdb0 pop {r4, r5, r7, pc} + 8009fbe: 46c0 nop ; (mov r8, r8) + 8009fc0: 000005b4 .word 0x000005b4 + 8009fc4: 20003278 .word 0x20003278 + 8009fc8: 20003158 .word 0x20003158 + +08009fcc : + */ +void +tcp_rst(u32_t seqno, u32_t ackno, + ip_addr_t *local_ip, ip_addr_t *remote_ip, + u16_t local_port, u16_t remote_port) +{ + 8009fcc: b590 push {r4, r7, lr} + 8009fce: b089 sub sp, #36 ; 0x24 + 8009fd0: af02 add r7, sp, #8 + 8009fd2: 60f8 str r0, [r7, #12] + 8009fd4: 60b9 str r1, [r7, #8] + 8009fd6: 607a str r2, [r7, #4] + 8009fd8: 603b str r3, [r7, #0] + struct pbuf *p; + struct tcp_hdr *tcphdr; + p = pbuf_alloc(PBUF_IP, TCP_HLEN, PBUF_RAM); + 8009fda: 2200 movs r2, #0 + 8009fdc: 2114 movs r1, #20 + 8009fde: 2001 movs r0, #1 + 8009fe0: f7fb f8d4 bl 800518c + 8009fe4: 0003 movs r3, r0 + 8009fe6: 617b str r3, [r7, #20] + if (p == NULL) { + 8009fe8: 697b ldr r3, [r7, #20] + 8009fea: 2b00 cmp r3, #0 + 8009fec: d100 bne.n 8009ff0 + 8009fee: e108 b.n 800a202 + return; + } + LWIP_ASSERT("check that first pbuf can hold struct tcp_hdr", + (p->len >= sizeof(struct tcp_hdr))); + + tcphdr = (struct tcp_hdr *)p->payload; + 8009ff0: 697b ldr r3, [r7, #20] + 8009ff2: 685b ldr r3, [r3, #4] + 8009ff4: 613b str r3, [r7, #16] + tcphdr->src = htons(local_port); + 8009ff6: 2328 movs r3, #40 ; 0x28 + 8009ff8: 18fb adds r3, r7, r3 + 8009ffa: 881b ldrh r3, [r3, #0] + 8009ffc: 0018 movs r0, r3 + 8009ffe: f7fa fb09 bl 8004614 + 800a002: 0003 movs r3, r0 + 800a004: 001a movs r2, r3 + 800a006: 693b ldr r3, [r7, #16] + 800a008: 21ff movs r1, #255 ; 0xff + 800a00a: 4011 ands r1, r2 + 800a00c: 000c movs r4, r1 + 800a00e: 7819 ldrb r1, [r3, #0] + 800a010: 2000 movs r0, #0 + 800a012: 4001 ands r1, r0 + 800a014: 1c08 adds r0, r1, #0 + 800a016: 1c21 adds r1, r4, #0 + 800a018: 4301 orrs r1, r0 + 800a01a: 7019 strb r1, [r3, #0] + 800a01c: 0a12 lsrs r2, r2, #8 + 800a01e: b290 uxth r0, r2 + 800a020: 785a ldrb r2, [r3, #1] + 800a022: 2100 movs r1, #0 + 800a024: 400a ands r2, r1 + 800a026: 1c11 adds r1, r2, #0 + 800a028: 1c02 adds r2, r0, #0 + 800a02a: 430a orrs r2, r1 + 800a02c: 705a strb r2, [r3, #1] + tcphdr->dest = htons(remote_port); + 800a02e: 232c movs r3, #44 ; 0x2c + 800a030: 18fb adds r3, r7, r3 + 800a032: 881b ldrh r3, [r3, #0] + 800a034: 0018 movs r0, r3 + 800a036: f7fa faed bl 8004614 + 800a03a: 0003 movs r3, r0 + 800a03c: 001a movs r2, r3 + 800a03e: 693b ldr r3, [r7, #16] + 800a040: 21ff movs r1, #255 ; 0xff + 800a042: 4011 ands r1, r2 + 800a044: 000c movs r4, r1 + 800a046: 7899 ldrb r1, [r3, #2] + 800a048: 2000 movs r0, #0 + 800a04a: 4001 ands r1, r0 + 800a04c: 1c08 adds r0, r1, #0 + 800a04e: 1c21 adds r1, r4, #0 + 800a050: 4301 orrs r1, r0 + 800a052: 7099 strb r1, [r3, #2] + 800a054: 0a12 lsrs r2, r2, #8 + 800a056: b290 uxth r0, r2 + 800a058: 78da ldrb r2, [r3, #3] + 800a05a: 2100 movs r1, #0 + 800a05c: 400a ands r2, r1 + 800a05e: 1c11 adds r1, r2, #0 + 800a060: 1c02 adds r2, r0, #0 + 800a062: 430a orrs r2, r1 + 800a064: 70da strb r2, [r3, #3] + tcphdr->seqno = htonl(seqno); + 800a066: 68fb ldr r3, [r7, #12] + 800a068: 0018 movs r0, r3 + 800a06a: f7fa faf9 bl 8004660 + 800a06e: 0002 movs r2, r0 + 800a070: 693b ldr r3, [r7, #16] + 800a072: 21ff movs r1, #255 ; 0xff + 800a074: 4011 ands r1, r2 + 800a076: 000c movs r4, r1 + 800a078: 7919 ldrb r1, [r3, #4] + 800a07a: 2000 movs r0, #0 + 800a07c: 4001 ands r1, r0 + 800a07e: 1c08 adds r0, r1, #0 + 800a080: 1c21 adds r1, r4, #0 + 800a082: 4301 orrs r1, r0 + 800a084: 7119 strb r1, [r3, #4] + 800a086: 0a11 lsrs r1, r2, #8 + 800a088: 20ff movs r0, #255 ; 0xff + 800a08a: 4001 ands r1, r0 + 800a08c: 000c movs r4, r1 + 800a08e: 7959 ldrb r1, [r3, #5] + 800a090: 2000 movs r0, #0 + 800a092: 4001 ands r1, r0 + 800a094: 1c08 adds r0, r1, #0 + 800a096: 1c21 adds r1, r4, #0 + 800a098: 4301 orrs r1, r0 + 800a09a: 7159 strb r1, [r3, #5] + 800a09c: 0c11 lsrs r1, r2, #16 + 800a09e: 20ff movs r0, #255 ; 0xff + 800a0a0: 4001 ands r1, r0 + 800a0a2: 000c movs r4, r1 + 800a0a4: 7999 ldrb r1, [r3, #6] + 800a0a6: 2000 movs r0, #0 + 800a0a8: 4001 ands r1, r0 + 800a0aa: 1c08 adds r0, r1, #0 + 800a0ac: 1c21 adds r1, r4, #0 + 800a0ae: 4301 orrs r1, r0 + 800a0b0: 7199 strb r1, [r3, #6] + 800a0b2: 0e10 lsrs r0, r2, #24 + 800a0b4: 79da ldrb r2, [r3, #7] + 800a0b6: 2100 movs r1, #0 + 800a0b8: 400a ands r2, r1 + 800a0ba: 1c11 adds r1, r2, #0 + 800a0bc: 1c02 adds r2, r0, #0 + 800a0be: 430a orrs r2, r1 + 800a0c0: 71da strb r2, [r3, #7] + tcphdr->ackno = htonl(ackno); + 800a0c2: 68bb ldr r3, [r7, #8] + 800a0c4: 0018 movs r0, r3 + 800a0c6: f7fa facb bl 8004660 + 800a0ca: 0002 movs r2, r0 + 800a0cc: 693b ldr r3, [r7, #16] + 800a0ce: 21ff movs r1, #255 ; 0xff + 800a0d0: 4011 ands r1, r2 + 800a0d2: 000c movs r4, r1 + 800a0d4: 7a19 ldrb r1, [r3, #8] + 800a0d6: 2000 movs r0, #0 + 800a0d8: 4001 ands r1, r0 + 800a0da: 1c08 adds r0, r1, #0 + 800a0dc: 1c21 adds r1, r4, #0 + 800a0de: 4301 orrs r1, r0 + 800a0e0: 7219 strb r1, [r3, #8] + 800a0e2: 0a11 lsrs r1, r2, #8 + 800a0e4: 20ff movs r0, #255 ; 0xff + 800a0e6: 4001 ands r1, r0 + 800a0e8: 000c movs r4, r1 + 800a0ea: 7a59 ldrb r1, [r3, #9] + 800a0ec: 2000 movs r0, #0 + 800a0ee: 4001 ands r1, r0 + 800a0f0: 1c08 adds r0, r1, #0 + 800a0f2: 1c21 adds r1, r4, #0 + 800a0f4: 4301 orrs r1, r0 + 800a0f6: 7259 strb r1, [r3, #9] + 800a0f8: 0c11 lsrs r1, r2, #16 + 800a0fa: 20ff movs r0, #255 ; 0xff + 800a0fc: 4001 ands r1, r0 + 800a0fe: 000c movs r4, r1 + 800a100: 7a99 ldrb r1, [r3, #10] + 800a102: 2000 movs r0, #0 + 800a104: 4001 ands r1, r0 + 800a106: 1c08 adds r0, r1, #0 + 800a108: 1c21 adds r1, r4, #0 + 800a10a: 4301 orrs r1, r0 + 800a10c: 7299 strb r1, [r3, #10] + 800a10e: 0e10 lsrs r0, r2, #24 + 800a110: 7ada ldrb r2, [r3, #11] + 800a112: 2100 movs r1, #0 + 800a114: 400a ands r2, r1 + 800a116: 1c11 adds r1, r2, #0 + 800a118: 1c02 adds r2, r0, #0 + 800a11a: 430a orrs r2, r1 + 800a11c: 72da strb r2, [r3, #11] + TCPH_HDRLEN_FLAGS_SET(tcphdr, TCP_HLEN/4, TCP_RST | TCP_ACK); + 800a11e: 4b3b ldr r3, [pc, #236] ; (800a20c ) + 800a120: 0018 movs r0, r3 + 800a122: f7fa fa77 bl 8004614 + 800a126: 0003 movs r3, r0 + 800a128: 001a movs r2, r3 + 800a12a: 693b ldr r3, [r7, #16] + 800a12c: 21ff movs r1, #255 ; 0xff + 800a12e: 4011 ands r1, r2 + 800a130: 000c movs r4, r1 + 800a132: 7b19 ldrb r1, [r3, #12] + 800a134: 2000 movs r0, #0 + 800a136: 4001 ands r1, r0 + 800a138: 1c08 adds r0, r1, #0 + 800a13a: 1c21 adds r1, r4, #0 + 800a13c: 4301 orrs r1, r0 + 800a13e: 7319 strb r1, [r3, #12] + 800a140: 0a12 lsrs r2, r2, #8 + 800a142: b290 uxth r0, r2 + 800a144: 7b5a ldrb r2, [r3, #13] + 800a146: 2100 movs r1, #0 + 800a148: 400a ands r2, r1 + 800a14a: 1c11 adds r1, r2, #0 + 800a14c: 1c02 adds r2, r0, #0 + 800a14e: 430a orrs r2, r1 + 800a150: 735a strb r2, [r3, #13] + tcphdr->wnd = PP_HTONS(TCP_WND); + 800a152: 693b ldr r3, [r7, #16] + 800a154: 7b9a ldrb r2, [r3, #14] + 800a156: 2100 movs r1, #0 + 800a158: 400a ands r2, r1 + 800a15a: 1c11 adds r1, r2, #0 + 800a15c: 2216 movs r2, #22 + 800a15e: 430a orrs r2, r1 + 800a160: 739a strb r2, [r3, #14] + 800a162: 7bda ldrb r2, [r3, #15] + 800a164: 2100 movs r1, #0 + 800a166: 400a ands r2, r1 + 800a168: 1c11 adds r1, r2, #0 + 800a16a: 2230 movs r2, #48 ; 0x30 + 800a16c: 4252 negs r2, r2 + 800a16e: 430a orrs r2, r1 + 800a170: 73da strb r2, [r3, #15] + tcphdr->chksum = 0; + 800a172: 693b ldr r3, [r7, #16] + 800a174: 7c1a ldrb r2, [r3, #16] + 800a176: 2100 movs r1, #0 + 800a178: 400a ands r2, r1 + 800a17a: 741a strb r2, [r3, #16] + 800a17c: 7c5a ldrb r2, [r3, #17] + 800a17e: 2100 movs r1, #0 + 800a180: 400a ands r2, r1 + 800a182: 745a strb r2, [r3, #17] + tcphdr->urgp = 0; + 800a184: 693b ldr r3, [r7, #16] + 800a186: 7c9a ldrb r2, [r3, #18] + 800a188: 2100 movs r1, #0 + 800a18a: 400a ands r2, r1 + 800a18c: 749a strb r2, [r3, #18] + 800a18e: 7cda ldrb r2, [r3, #19] + 800a190: 2100 movs r1, #0 + 800a192: 400a ands r2, r1 + 800a194: 74da strb r2, [r3, #19] + +#if CHECKSUM_GEN_TCP + tcphdr->chksum = inet_chksum_pseudo(p, local_ip, remote_ip, + 800a196: 697b ldr r3, [r7, #20] + 800a198: 891b ldrh r3, [r3, #8] + 800a19a: 683a ldr r2, [r7, #0] + 800a19c: 6879 ldr r1, [r7, #4] + 800a19e: 6978 ldr r0, [r7, #20] + 800a1a0: 9300 str r3, [sp, #0] + 800a1a2: 2306 movs r3, #6 + 800a1a4: f001 fa49 bl 800b63a + 800a1a8: 0003 movs r3, r0 + 800a1aa: 001a movs r2, r3 + 800a1ac: 693b ldr r3, [r7, #16] + 800a1ae: 21ff movs r1, #255 ; 0xff + 800a1b0: 4011 ands r1, r2 + 800a1b2: 000c movs r4, r1 + 800a1b4: 7c19 ldrb r1, [r3, #16] + 800a1b6: 2000 movs r0, #0 + 800a1b8: 4001 ands r1, r0 + 800a1ba: 1c08 adds r0, r1, #0 + 800a1bc: 1c21 adds r1, r4, #0 + 800a1be: 4301 orrs r1, r0 + 800a1c0: 7419 strb r1, [r3, #16] + 800a1c2: 0a12 lsrs r2, r2, #8 + 800a1c4: b290 uxth r0, r2 + 800a1c6: 7c5a ldrb r2, [r3, #17] + 800a1c8: 2100 movs r1, #0 + 800a1ca: 400a ands r2, r1 + 800a1cc: 1c11 adds r1, r2, #0 + 800a1ce: 1c02 adds r2, r0, #0 + 800a1d0: 430a orrs r2, r1 + 800a1d2: 745a strb r2, [r3, #17] + IP_PROTO_TCP, p->tot_len); +#endif + TCP_STATS_INC(tcp.xmit); + 800a1d4: 4b0e ldr r3, [pc, #56] ; (800a210 ) + 800a1d6: 2290 movs r2, #144 ; 0x90 + 800a1d8: 5a9b ldrh r3, [r3, r2] + 800a1da: 3301 adds r3, #1 + 800a1dc: b299 uxth r1, r3 + 800a1de: 4b0c ldr r3, [pc, #48] ; (800a210 ) + 800a1e0: 2290 movs r2, #144 ; 0x90 + 800a1e2: 5299 strh r1, [r3, r2] + snmp_inc_tcpoutrsts(); + /* Send output with hardcoded TTL since we have no access to the pcb */ + ip_output(p, local_ip, remote_ip, TCP_TTL, 0, IP_PROTO_TCP); + 800a1e4: 683a ldr r2, [r7, #0] + 800a1e6: 6879 ldr r1, [r7, #4] + 800a1e8: 6978 ldr r0, [r7, #20] + 800a1ea: 2306 movs r3, #6 + 800a1ec: 9301 str r3, [sp, #4] + 800a1ee: 2300 movs r3, #0 + 800a1f0: 9300 str r3, [sp, #0] + 800a1f2: 23ff movs r3, #255 ; 0xff + 800a1f4: f001 ff0c bl 800c010 + pbuf_free(p); + 800a1f8: 697b ldr r3, [r7, #20] + 800a1fa: 0018 movs r0, r3 + 800a1fc: f7fb fa52 bl 80056a4 + 800a200: e000 b.n 800a204 + return; + 800a202: 46c0 nop ; (mov r8, r8) + LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_rst: seqno %"U32_F" ackno %"U32_F".\n", seqno, ackno)); +} + 800a204: 46bd mov sp, r7 + 800a206: b007 add sp, #28 + 800a208: bd90 pop {r4, r7, pc} + 800a20a: 46c0 nop ; (mov r8, r8) + 800a20c: 00005014 .word 0x00005014 + 800a210: 20003158 .word 0x20003158 + +0800a214 : + * + * @param pcb the tcp_pcb for which to re-enqueue all unacked segments + */ +void +tcp_rexmit_rto(struct tcp_pcb *pcb) +{ + 800a214: b580 push {r7, lr} + 800a216: b084 sub sp, #16 + 800a218: af00 add r7, sp, #0 + 800a21a: 6078 str r0, [r7, #4] + struct tcp_seg *seg; + + if (pcb->unacked == NULL) { + 800a21c: 687b ldr r3, [r7, #4] + 800a21e: 6f1b ldr r3, [r3, #112] ; 0x70 + 800a220: 2b00 cmp r3, #0 + 800a222: d025 beq.n 800a270 + return; + } + + /* Move all unacked segments to the head of the unsent queue */ + for (seg = pcb->unacked; seg->next != NULL; seg = seg->next); + 800a224: 687b ldr r3, [r7, #4] + 800a226: 6f1b ldr r3, [r3, #112] ; 0x70 + 800a228: 60fb str r3, [r7, #12] + 800a22a: e002 b.n 800a232 + 800a22c: 68fb ldr r3, [r7, #12] + 800a22e: 681b ldr r3, [r3, #0] + 800a230: 60fb str r3, [r7, #12] + 800a232: 68fb ldr r3, [r7, #12] + 800a234: 681b ldr r3, [r3, #0] + 800a236: 2b00 cmp r3, #0 + 800a238: d1f8 bne.n 800a22c + /* concatenate unsent queue after unacked queue */ + seg->next = pcb->unsent; + 800a23a: 687b ldr r3, [r7, #4] + 800a23c: 6eda ldr r2, [r3, #108] ; 0x6c + 800a23e: 68fb ldr r3, [r7, #12] + 800a240: 601a str r2, [r3, #0] + /* unsent queue is the concatenated queue (of unacked, unsent) */ + pcb->unsent = pcb->unacked; + 800a242: 687b ldr r3, [r7, #4] + 800a244: 6f1a ldr r2, [r3, #112] ; 0x70 + 800a246: 687b ldr r3, [r7, #4] + 800a248: 66da str r2, [r3, #108] ; 0x6c + /* unacked queue is now empty */ + pcb->unacked = NULL; + 800a24a: 687b ldr r3, [r7, #4] + 800a24c: 2200 movs r2, #0 + 800a24e: 671a str r2, [r3, #112] ; 0x70 + /* last unsent hasn't changed, no need to reset unsent_oversize */ + + /* increment number of retransmissions */ + ++pcb->nrtx; + 800a250: 687b ldr r3, [r7, #4] + 800a252: 2246 movs r2, #70 ; 0x46 + 800a254: 5c9b ldrb r3, [r3, r2] + 800a256: 3301 adds r3, #1 + 800a258: b2d9 uxtb r1, r3 + 800a25a: 687b ldr r3, [r7, #4] + 800a25c: 2246 movs r2, #70 ; 0x46 + 800a25e: 5499 strb r1, [r3, r2] + + /* Don't take any RTT measurements after retransmitting. */ + pcb->rttest = 0; + 800a260: 687b ldr r3, [r7, #4] + 800a262: 2200 movs r2, #0 + 800a264: 639a str r2, [r3, #56] ; 0x38 + + /* Do the actual retransmission */ + tcp_output(pcb); + 800a266: 687b ldr r3, [r7, #4] + 800a268: 0018 movs r0, r3 + 800a26a: f7ff fbd1 bl 8009a10 + 800a26e: e000 b.n 800a272 + return; + 800a270: 46c0 nop ; (mov r8, r8) +} + 800a272: 46bd mov sp, r7 + 800a274: b004 add sp, #16 + 800a276: bd80 pop {r7, pc} + +0800a278 : + * + * @param pcb the tcp_pcb for which to retransmit the first unacked segment + */ +void +tcp_rexmit(struct tcp_pcb *pcb) +{ + 800a278: b590 push {r4, r7, lr} + 800a27a: b085 sub sp, #20 + 800a27c: af00 add r7, sp, #0 + 800a27e: 6078 str r0, [r7, #4] + struct tcp_seg *seg; + struct tcp_seg **cur_seg; + + if (pcb->unacked == NULL) { + 800a280: 687b ldr r3, [r7, #4] + 800a282: 6f1b ldr r3, [r3, #112] ; 0x70 + 800a284: 2b00 cmp r3, #0 + 800a286: d04f beq.n 800a328 + return; + } + + /* Move the first unacked segment to the unsent queue */ + /* Keep the unsent queue sorted. */ + seg = pcb->unacked; + 800a288: 687b ldr r3, [r7, #4] + 800a28a: 6f1b ldr r3, [r3, #112] ; 0x70 + 800a28c: 60bb str r3, [r7, #8] + pcb->unacked = seg->next; + 800a28e: 68bb ldr r3, [r7, #8] + 800a290: 681a ldr r2, [r3, #0] + 800a292: 687b ldr r3, [r7, #4] + 800a294: 671a str r2, [r3, #112] ; 0x70 + + cur_seg = &(pcb->unsent); + 800a296: 687b ldr r3, [r7, #4] + 800a298: 336c adds r3, #108 ; 0x6c + 800a29a: 60fb str r3, [r7, #12] + while (*cur_seg && + 800a29c: e002 b.n 800a2a4 + TCP_SEQ_LT(ntohl((*cur_seg)->tcphdr->seqno), ntohl(seg->tcphdr->seqno))) { + cur_seg = &((*cur_seg)->next ); + 800a29e: 68fb ldr r3, [r7, #12] + 800a2a0: 681b ldr r3, [r3, #0] + 800a2a2: 60fb str r3, [r7, #12] + while (*cur_seg && + 800a2a4: 68fb ldr r3, [r7, #12] + 800a2a6: 681b ldr r3, [r3, #0] + 800a2a8: 2b00 cmp r3, #0 + 800a2aa: d022 beq.n 800a2f2 + TCP_SEQ_LT(ntohl((*cur_seg)->tcphdr->seqno), ntohl(seg->tcphdr->seqno))) { + 800a2ac: 68fb ldr r3, [r7, #12] + 800a2ae: 681b ldr r3, [r3, #0] + 800a2b0: 68db ldr r3, [r3, #12] + 800a2b2: 791a ldrb r2, [r3, #4] + 800a2b4: 7959 ldrb r1, [r3, #5] + 800a2b6: 0209 lsls r1, r1, #8 + 800a2b8: 430a orrs r2, r1 + 800a2ba: 7999 ldrb r1, [r3, #6] + 800a2bc: 0409 lsls r1, r1, #16 + 800a2be: 430a orrs r2, r1 + 800a2c0: 79db ldrb r3, [r3, #7] + 800a2c2: 061b lsls r3, r3, #24 + 800a2c4: 4313 orrs r3, r2 + 800a2c6: 0018 movs r0, r3 + 800a2c8: f7fa f9e3 bl 8004692 + 800a2cc: 0004 movs r4, r0 + 800a2ce: 68bb ldr r3, [r7, #8] + 800a2d0: 68db ldr r3, [r3, #12] + 800a2d2: 791a ldrb r2, [r3, #4] + 800a2d4: 7959 ldrb r1, [r3, #5] + 800a2d6: 0209 lsls r1, r1, #8 + 800a2d8: 430a orrs r2, r1 + 800a2da: 7999 ldrb r1, [r3, #6] + 800a2dc: 0409 lsls r1, r1, #16 + 800a2de: 430a orrs r2, r1 + 800a2e0: 79db ldrb r3, [r3, #7] + 800a2e2: 061b lsls r3, r3, #24 + 800a2e4: 4313 orrs r3, r2 + 800a2e6: 0018 movs r0, r3 + 800a2e8: f7fa f9d3 bl 8004692 + 800a2ec: 0003 movs r3, r0 + 800a2ee: 1ae3 subs r3, r4, r3 + while (*cur_seg && + 800a2f0: d4d5 bmi.n 800a29e + } + seg->next = *cur_seg; + 800a2f2: 68fb ldr r3, [r7, #12] + 800a2f4: 681a ldr r2, [r3, #0] + 800a2f6: 68bb ldr r3, [r7, #8] + 800a2f8: 601a str r2, [r3, #0] + *cur_seg = seg; + 800a2fa: 68fb ldr r3, [r7, #12] + 800a2fc: 68ba ldr r2, [r7, #8] + 800a2fe: 601a str r2, [r3, #0] +#if TCP_OVERSIZE + if (seg->next == NULL) { + 800a300: 68bb ldr r3, [r7, #8] + 800a302: 681b ldr r3, [r3, #0] + 800a304: 2b00 cmp r3, #0 + 800a306: d103 bne.n 800a310 + /* the retransmitted segment is last in unsent, so reset unsent_oversize */ + pcb->unsent_oversize = 0; + 800a308: 687b ldr r3, [r7, #4] + 800a30a: 226a movs r2, #106 ; 0x6a + 800a30c: 2100 movs r1, #0 + 800a30e: 5299 strh r1, [r3, r2] + } +#endif /* TCP_OVERSIZE */ + + ++pcb->nrtx; + 800a310: 687b ldr r3, [r7, #4] + 800a312: 2246 movs r2, #70 ; 0x46 + 800a314: 5c9b ldrb r3, [r3, r2] + 800a316: 3301 adds r3, #1 + 800a318: b2d9 uxtb r1, r3 + 800a31a: 687b ldr r3, [r7, #4] + 800a31c: 2246 movs r2, #70 ; 0x46 + 800a31e: 5499 strb r1, [r3, r2] + + /* Don't take any rtt measurements after retransmitting. */ + pcb->rttest = 0; + 800a320: 687b ldr r3, [r7, #4] + 800a322: 2200 movs r2, #0 + 800a324: 639a str r2, [r3, #56] ; 0x38 + 800a326: e000 b.n 800a32a + return; + 800a328: 46c0 nop ; (mov r8, r8) + + /* Do the actual retransmission. */ + snmp_inc_tcpretranssegs(); + /* No need to call tcp_output: we are always called from tcp_input() + and thus tcp_output directly returns. */ +} + 800a32a: 46bd mov sp, r7 + 800a32c: b005 add sp, #20 + 800a32e: bd90 pop {r4, r7, pc} + +0800a330 : + * + * @param pcb the tcp_pcb for which to retransmit the first unacked segment + */ +void +tcp_rexmit_fast(struct tcp_pcb *pcb) +{ + 800a330: b580 push {r7, lr} + 800a332: b082 sub sp, #8 + 800a334: af00 add r7, sp, #0 + 800a336: 6078 str r0, [r7, #4] + if (pcb->unacked != NULL && !(pcb->flags & TF_INFR)) { + 800a338: 687b ldr r3, [r7, #4] + 800a33a: 6f1b ldr r3, [r3, #112] ; 0x70 + 800a33c: 2b00 cmp r3, #0 + 800a33e: d048 beq.n 800a3d2 + 800a340: 687b ldr r3, [r7, #4] + 800a342: 7f9b ldrb r3, [r3, #30] + 800a344: 001a movs r2, r3 + 800a346: 2304 movs r3, #4 + 800a348: 4013 ands r3, r2 + 800a34a: d142 bne.n 800a3d2 + LWIP_DEBUGF(TCP_FR_DEBUG, + ("tcp_receive: dupacks %"U16_F" (%"U32_F + "), fast retransmit %"U32_F"\n", + (u16_t)pcb->dupacks, pcb->lastack, + ntohl(pcb->unacked->tcphdr->seqno))); + tcp_rexmit(pcb); + 800a34c: 687b ldr r3, [r7, #4] + 800a34e: 0018 movs r0, r3 + 800a350: f7ff ff92 bl 800a278 + + /* Set ssthresh to half of the minimum of the current + * cwnd and the advertised window */ + if (pcb->cwnd > pcb->snd_wnd) { + 800a354: 687b ldr r3, [r7, #4] + 800a356: 224c movs r2, #76 ; 0x4c + 800a358: 5a9a ldrh r2, [r3, r2] + 800a35a: 687b ldr r3, [r7, #4] + 800a35c: 2160 movs r1, #96 ; 0x60 + 800a35e: 5a5b ldrh r3, [r3, r1] + 800a360: 429a cmp r2, r3 + 800a362: d908 bls.n 800a376 + pcb->ssthresh = pcb->snd_wnd / 2; + 800a364: 687b ldr r3, [r7, #4] + 800a366: 2260 movs r2, #96 ; 0x60 + 800a368: 5a9b ldrh r3, [r3, r2] + 800a36a: 085b lsrs r3, r3, #1 + 800a36c: b299 uxth r1, r3 + 800a36e: 687b ldr r3, [r7, #4] + 800a370: 224e movs r2, #78 ; 0x4e + 800a372: 5299 strh r1, [r3, r2] + 800a374: e007 b.n 800a386 + } else { + pcb->ssthresh = pcb->cwnd / 2; + 800a376: 687b ldr r3, [r7, #4] + 800a378: 224c movs r2, #76 ; 0x4c + 800a37a: 5a9b ldrh r3, [r3, r2] + 800a37c: 085b lsrs r3, r3, #1 + 800a37e: b299 uxth r1, r3 + 800a380: 687b ldr r3, [r7, #4] + 800a382: 224e movs r2, #78 ; 0x4e + 800a384: 5299 strh r1, [r3, r2] + } + + /* The minimum value for ssthresh should be 2 MSS */ + if (pcb->ssthresh < 2*pcb->mss) { + 800a386: 687b ldr r3, [r7, #4] + 800a388: 224e movs r2, #78 ; 0x4e + 800a38a: 5a9b ldrh r3, [r3, r2] + 800a38c: 001a movs r2, r3 + 800a38e: 687b ldr r3, [r7, #4] + 800a390: 8edb ldrh r3, [r3, #54] ; 0x36 + 800a392: 005b lsls r3, r3, #1 + 800a394: 429a cmp r2, r3 + 800a396: da06 bge.n 800a3a6 + LWIP_DEBUGF(TCP_FR_DEBUG, + ("tcp_receive: The minimum value for ssthresh %"U16_F + " should be min 2 mss %"U16_F"...\n", + pcb->ssthresh, 2*pcb->mss)); + pcb->ssthresh = 2*pcb->mss; + 800a398: 687b ldr r3, [r7, #4] + 800a39a: 8edb ldrh r3, [r3, #54] ; 0x36 + 800a39c: 18db adds r3, r3, r3 + 800a39e: b299 uxth r1, r3 + 800a3a0: 687b ldr r3, [r7, #4] + 800a3a2: 224e movs r2, #78 ; 0x4e + 800a3a4: 5299 strh r1, [r3, r2] + } + + pcb->cwnd = pcb->ssthresh + 3 * pcb->mss; + 800a3a6: 687b ldr r3, [r7, #4] + 800a3a8: 224e movs r2, #78 ; 0x4e + 800a3aa: 5a9a ldrh r2, [r3, r2] + 800a3ac: 687b ldr r3, [r7, #4] + 800a3ae: 8edb ldrh r3, [r3, #54] ; 0x36 + 800a3b0: 1c19 adds r1, r3, #0 + 800a3b2: 1c0b adds r3, r1, #0 + 800a3b4: 18db adds r3, r3, r3 + 800a3b6: 185b adds r3, r3, r1 + 800a3b8: b29b uxth r3, r3 + 800a3ba: 18d3 adds r3, r2, r3 + 800a3bc: b299 uxth r1, r3 + 800a3be: 687b ldr r3, [r7, #4] + 800a3c0: 224c movs r2, #76 ; 0x4c + 800a3c2: 5299 strh r1, [r3, r2] + pcb->flags |= TF_INFR; + 800a3c4: 687b ldr r3, [r7, #4] + 800a3c6: 7f9b ldrb r3, [r3, #30] + 800a3c8: 2204 movs r2, #4 + 800a3ca: 4313 orrs r3, r2 + 800a3cc: b2da uxtb r2, r3 + 800a3ce: 687b ldr r3, [r7, #4] + 800a3d0: 779a strb r2, [r3, #30] + } +} + 800a3d2: 46c0 nop ; (mov r8, r8) + 800a3d4: 46bd mov sp, r7 + 800a3d6: b002 add sp, #8 + 800a3d8: bd80 pop {r7, pc} + ... + +0800a3dc : + * + * @param pcb the tcp_pcb for which to send a keepalive packet + */ +void +tcp_keepalive(struct tcp_pcb *pcb) +{ + 800a3dc: b590 push {r4, r7, lr} + 800a3de: b087 sub sp, #28 + 800a3e0: af02 add r7, sp, #8 + 800a3e2: 6078 str r0, [r7, #4] + ip4_addr3_16(&pcb->remote_ip), ip4_addr4_16(&pcb->remote_ip))); + + LWIP_DEBUGF(TCP_DEBUG, ("tcp_keepalive: tcp_ticks %"U32_F" pcb->tmr %"U32_F" pcb->keep_cnt_sent %"U16_F"\n", + tcp_ticks, pcb->tmr, pcb->keep_cnt_sent)); + + p = tcp_output_alloc_header(pcb, 0, 0, htonl(pcb->snd_nxt - 1)); + 800a3e4: 687b ldr r3, [r7, #4] + 800a3e6: 6d1b ldr r3, [r3, #80] ; 0x50 + 800a3e8: 3b01 subs r3, #1 + 800a3ea: 0018 movs r0, r3 + 800a3ec: f7fa f938 bl 8004660 + 800a3f0: 0003 movs r3, r0 + 800a3f2: 6878 ldr r0, [r7, #4] + 800a3f4: 2200 movs r2, #0 + 800a3f6: 2100 movs r1, #0 + 800a3f8: f7fe ff54 bl 80092a4 + 800a3fc: 0003 movs r3, r0 + 800a3fe: 60fb str r3, [r7, #12] + if(p == NULL) { + 800a400: 68fb ldr r3, [r7, #12] + 800a402: 2b00 cmp r3, #0 + 800a404: d03c beq.n 800a480 + LWIP_DEBUGF(TCP_DEBUG, + ("tcp_keepalive: could not allocate memory for pbuf\n")); + return; + } + tcphdr = (struct tcp_hdr *)p->payload; + 800a406: 68fb ldr r3, [r7, #12] + 800a408: 685b ldr r3, [r3, #4] + 800a40a: 60bb str r3, [r7, #8] + +#if CHECKSUM_GEN_TCP + tcphdr->chksum = inet_chksum_pseudo(p, &pcb->local_ip, &pcb->remote_ip, + 800a40c: 6879 ldr r1, [r7, #4] + 800a40e: 687b ldr r3, [r7, #4] + 800a410: 1d1a adds r2, r3, #4 + 800a412: 68fb ldr r3, [r7, #12] + 800a414: 891b ldrh r3, [r3, #8] + 800a416: 68f8 ldr r0, [r7, #12] + 800a418: 9300 str r3, [sp, #0] + 800a41a: 2306 movs r3, #6 + 800a41c: f001 f90d bl 800b63a + 800a420: 0003 movs r3, r0 + 800a422: 001a movs r2, r3 + 800a424: 68bb ldr r3, [r7, #8] + 800a426: 21ff movs r1, #255 ; 0xff + 800a428: 4011 ands r1, r2 + 800a42a: 000c movs r4, r1 + 800a42c: 7c19 ldrb r1, [r3, #16] + 800a42e: 2000 movs r0, #0 + 800a430: 4001 ands r1, r0 + 800a432: 1c08 adds r0, r1, #0 + 800a434: 1c21 adds r1, r4, #0 + 800a436: 4301 orrs r1, r0 + 800a438: 7419 strb r1, [r3, #16] + 800a43a: 0a12 lsrs r2, r2, #8 + 800a43c: b290 uxth r0, r2 + 800a43e: 7c5a ldrb r2, [r3, #17] + 800a440: 2100 movs r1, #0 + 800a442: 400a ands r2, r1 + 800a444: 1c11 adds r1, r2, #0 + 800a446: 1c02 adds r2, r0, #0 + 800a448: 430a orrs r2, r1 + 800a44a: 745a strb r2, [r3, #17] + IP_PROTO_TCP, p->tot_len); +#endif + TCP_STATS_INC(tcp.xmit); + 800a44c: 4b0e ldr r3, [pc, #56] ; (800a488 ) + 800a44e: 2290 movs r2, #144 ; 0x90 + 800a450: 5a9b ldrh r3, [r3, r2] + 800a452: 3301 adds r3, #1 + 800a454: b299 uxth r1, r3 + 800a456: 4b0c ldr r3, [pc, #48] ; (800a488 ) + 800a458: 2290 movs r2, #144 ; 0x90 + 800a45a: 5299 strh r1, [r3, r2] + /* Send output to IP */ +#if LWIP_NETIF_HWADDRHINT + ip_output_hinted(p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl, 0, IP_PROTO_TCP, + &(pcb->addr_hint)); +#else /* LWIP_NETIF_HWADDRHINT*/ + ip_output(p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl, 0, IP_PROTO_TCP); + 800a45c: 6879 ldr r1, [r7, #4] + 800a45e: 687b ldr r3, [r7, #4] + 800a460: 1d1a adds r2, r3, #4 + 800a462: 687b ldr r3, [r7, #4] + 800a464: 7a9c ldrb r4, [r3, #10] + 800a466: 68f8 ldr r0, [r7, #12] + 800a468: 2306 movs r3, #6 + 800a46a: 9301 str r3, [sp, #4] + 800a46c: 2300 movs r3, #0 + 800a46e: 9300 str r3, [sp, #0] + 800a470: 0023 movs r3, r4 + 800a472: f001 fdcd bl 800c010 +#endif /* LWIP_NETIF_HWADDRHINT*/ + + pbuf_free(p); + 800a476: 68fb ldr r3, [r7, #12] + 800a478: 0018 movs r0, r3 + 800a47a: f7fb f913 bl 80056a4 + 800a47e: e000 b.n 800a482 + return; + 800a480: 46c0 nop ; (mov r8, r8) + + LWIP_DEBUGF(TCP_DEBUG, ("tcp_keepalive: seqno %"U32_F" ackno %"U32_F".\n", + pcb->snd_nxt - 1, pcb->rcv_nxt)); +} + 800a482: 46bd mov sp, r7 + 800a484: b005 add sp, #20 + 800a486: bd90 pop {r4, r7, pc} + 800a488: 20003158 .word 0x20003158 + +0800a48c : + * + * @param pcb the tcp_pcb for which to send a zero-window probe packet + */ +void +tcp_zero_window_probe(struct tcp_pcb *pcb) +{ + 800a48c: b590 push {r4, r7, lr} + 800a48e: b08b sub sp, #44 ; 0x2c + 800a490: af02 add r7, sp, #8 + 800a492: 6078 str r0, [r7, #4] + LWIP_DEBUGF(TCP_DEBUG, + ("tcp_zero_window_probe: tcp_ticks %"U32_F + " pcb->tmr %"U32_F" pcb->keep_cnt_sent %"U16_F"\n", + tcp_ticks, pcb->tmr, pcb->keep_cnt_sent)); + + seg = pcb->unacked; + 800a494: 687b ldr r3, [r7, #4] + 800a496: 6f1b ldr r3, [r3, #112] ; 0x70 + 800a498: 61fb str r3, [r7, #28] + + if(seg == NULL) { + 800a49a: 69fb ldr r3, [r7, #28] + 800a49c: 2b00 cmp r3, #0 + 800a49e: d102 bne.n 800a4a6 + seg = pcb->unsent; + 800a4a0: 687b ldr r3, [r7, #4] + 800a4a2: 6edb ldr r3, [r3, #108] ; 0x6c + 800a4a4: 61fb str r3, [r7, #28] + } + if(seg == NULL) { + 800a4a6: 69fb ldr r3, [r7, #28] + 800a4a8: 2b00 cmp r3, #0 + 800a4aa: d100 bne.n 800a4ae + 800a4ac: e0b4 b.n 800a618 + return; + } + + is_fin = ((TCPH_FLAGS(seg->tcphdr) & TCP_FIN) != 0) && (seg->len == 0); + 800a4ae: 69fb ldr r3, [r7, #28] + 800a4b0: 68db ldr r3, [r3, #12] + 800a4b2: 7b1a ldrb r2, [r3, #12] + 800a4b4: 7b5b ldrb r3, [r3, #13] + 800a4b6: 021b lsls r3, r3, #8 + 800a4b8: 4313 orrs r3, r2 + 800a4ba: b29b uxth r3, r3 + 800a4bc: 0018 movs r0, r3 + 800a4be: f7fa f8bf bl 8004640 + 800a4c2: 0003 movs r3, r0 + 800a4c4: 001a movs r2, r3 + 800a4c6: 2301 movs r3, #1 + 800a4c8: 4013 ands r3, r2 + 800a4ca: d005 beq.n 800a4d8 + 800a4cc: 69fb ldr r3, [r7, #28] + 800a4ce: 891b ldrh r3, [r3, #8] + 800a4d0: 2b00 cmp r3, #0 + 800a4d2: d101 bne.n 800a4d8 + 800a4d4: 2201 movs r2, #1 + 800a4d6: e000 b.n 800a4da + 800a4d8: 2200 movs r2, #0 + 800a4da: 211b movs r1, #27 + 800a4dc: 187b adds r3, r7, r1 + 800a4de: 701a strb r2, [r3, #0] + /* we want to send one seqno: either FIN or data (no options) */ + len = is_fin ? 0 : 1; + 800a4e0: 187b adds r3, r7, r1 + 800a4e2: 781b ldrb r3, [r3, #0] + 800a4e4: 425a negs r2, r3 + 800a4e6: 4153 adcs r3, r2 + 800a4e8: b2da uxtb r2, r3 + 800a4ea: 2018 movs r0, #24 + 800a4ec: 183b adds r3, r7, r0 + 800a4ee: 801a strh r2, [r3, #0] + + p = tcp_output_alloc_header(pcb, 0, len, seg->tcphdr->seqno); + 800a4f0: 69fb ldr r3, [r7, #28] + 800a4f2: 68db ldr r3, [r3, #12] + 800a4f4: 791a ldrb r2, [r3, #4] + 800a4f6: 7959 ldrb r1, [r3, #5] + 800a4f8: 0209 lsls r1, r1, #8 + 800a4fa: 430a orrs r2, r1 + 800a4fc: 7999 ldrb r1, [r3, #6] + 800a4fe: 0409 lsls r1, r1, #16 + 800a500: 430a orrs r2, r1 + 800a502: 79db ldrb r3, [r3, #7] + 800a504: 061b lsls r3, r3, #24 + 800a506: 4313 orrs r3, r2 + 800a508: 0019 movs r1, r3 + 800a50a: 183b adds r3, r7, r0 + 800a50c: 881a ldrh r2, [r3, #0] + 800a50e: 6878 ldr r0, [r7, #4] + 800a510: 000b movs r3, r1 + 800a512: 2100 movs r1, #0 + 800a514: f7fe fec6 bl 80092a4 + 800a518: 0003 movs r3, r0 + 800a51a: 617b str r3, [r7, #20] + if(p == NULL) { + 800a51c: 697b ldr r3, [r7, #20] + 800a51e: 2b00 cmp r3, #0 + 800a520: d100 bne.n 800a524 + 800a522: e07b b.n 800a61c + LWIP_DEBUGF(TCP_DEBUG, ("tcp_zero_window_probe: no memory for pbuf\n")); + return; + } + tcphdr = (struct tcp_hdr *)p->payload; + 800a524: 697b ldr r3, [r7, #20] + 800a526: 685b ldr r3, [r3, #4] + 800a528: 613b str r3, [r7, #16] + + if (is_fin) { + 800a52a: 231b movs r3, #27 + 800a52c: 18fb adds r3, r7, r3 + 800a52e: 781b ldrb r3, [r3, #0] + 800a530: 2b00 cmp r3, #0 + 800a532: d026 beq.n 800a582 + /* FIN segment, no data */ + TCPH_FLAGS_SET(tcphdr, TCP_ACK | TCP_FIN); + 800a534: 693b ldr r3, [r7, #16] + 800a536: 7b1a ldrb r2, [r3, #12] + 800a538: 7b5b ldrb r3, [r3, #13] + 800a53a: 021b lsls r3, r3, #8 + 800a53c: 4313 orrs r3, r2 + 800a53e: b29b uxth r3, r3 + 800a540: b21b sxth r3, r3 + 800a542: 4a38 ldr r2, [pc, #224] ; (800a624 ) + 800a544: 4013 ands r3, r2 + 800a546: b21c sxth r4, r3 + 800a548: 2011 movs r0, #17 + 800a54a: f7fa f863 bl 8004614 + 800a54e: 0003 movs r3, r0 + 800a550: b21b sxth r3, r3 + 800a552: 4323 orrs r3, r4 + 800a554: b21b sxth r3, r3 + 800a556: b29a uxth r2, r3 + 800a558: 693b ldr r3, [r7, #16] + 800a55a: 21ff movs r1, #255 ; 0xff + 800a55c: 4011 ands r1, r2 + 800a55e: 000c movs r4, r1 + 800a560: 7b19 ldrb r1, [r3, #12] + 800a562: 2000 movs r0, #0 + 800a564: 4001 ands r1, r0 + 800a566: 1c08 adds r0, r1, #0 + 800a568: 1c21 adds r1, r4, #0 + 800a56a: 4301 orrs r1, r0 + 800a56c: 7319 strb r1, [r3, #12] + 800a56e: 0a12 lsrs r2, r2, #8 + 800a570: b290 uxth r0, r2 + 800a572: 7b5a ldrb r2, [r3, #13] + 800a574: 2100 movs r1, #0 + 800a576: 400a ands r2, r1 + 800a578: 1c11 adds r1, r2, #0 + 800a57a: 1c02 adds r2, r0, #0 + 800a57c: 430a orrs r2, r1 + 800a57e: 735a strb r2, [r3, #13] + 800a580: e010 b.n 800a5a4 + } else { + /* Data segment, copy in one byte from the head of the unacked queue */ + char *d = ((char *)p->payload + TCP_HLEN); + 800a582: 697b ldr r3, [r7, #20] + 800a584: 685b ldr r3, [r3, #4] + 800a586: 3314 adds r3, #20 + 800a588: 60fb str r3, [r7, #12] + /* Depending on whether the segment has already been sent (unacked) or not + (unsent), seg->p->payload points to the IP header or TCP header. + Ensure we copy the first TCP data byte: */ + pbuf_copy_partial(seg->p, d, 1, seg->p->tot_len - seg->len); + 800a58a: 69fb ldr r3, [r7, #28] + 800a58c: 6858 ldr r0, [r3, #4] + 800a58e: 69fb ldr r3, [r7, #28] + 800a590: 685b ldr r3, [r3, #4] + 800a592: 891a ldrh r2, [r3, #8] + 800a594: 69fb ldr r3, [r7, #28] + 800a596: 891b ldrh r3, [r3, #8] + 800a598: 1ad3 subs r3, r2, r3 + 800a59a: b29b uxth r3, r3 + 800a59c: 68f9 ldr r1, [r7, #12] + 800a59e: 2201 movs r2, #1 + 800a5a0: f7fb fa0c bl 80059bc + } + +#if CHECKSUM_GEN_TCP + tcphdr->chksum = inet_chksum_pseudo(p, &pcb->local_ip, &pcb->remote_ip, + 800a5a4: 6879 ldr r1, [r7, #4] + 800a5a6: 687b ldr r3, [r7, #4] + 800a5a8: 1d1a adds r2, r3, #4 + 800a5aa: 697b ldr r3, [r7, #20] + 800a5ac: 891b ldrh r3, [r3, #8] + 800a5ae: 6978 ldr r0, [r7, #20] + 800a5b0: 9300 str r3, [sp, #0] + 800a5b2: 2306 movs r3, #6 + 800a5b4: f001 f841 bl 800b63a + 800a5b8: 0003 movs r3, r0 + 800a5ba: 001a movs r2, r3 + 800a5bc: 693b ldr r3, [r7, #16] + 800a5be: 21ff movs r1, #255 ; 0xff + 800a5c0: 4011 ands r1, r2 + 800a5c2: 000c movs r4, r1 + 800a5c4: 7c19 ldrb r1, [r3, #16] + 800a5c6: 2000 movs r0, #0 + 800a5c8: 4001 ands r1, r0 + 800a5ca: 1c08 adds r0, r1, #0 + 800a5cc: 1c21 adds r1, r4, #0 + 800a5ce: 4301 orrs r1, r0 + 800a5d0: 7419 strb r1, [r3, #16] + 800a5d2: 0a12 lsrs r2, r2, #8 + 800a5d4: b290 uxth r0, r2 + 800a5d6: 7c5a ldrb r2, [r3, #17] + 800a5d8: 2100 movs r1, #0 + 800a5da: 400a ands r2, r1 + 800a5dc: 1c11 adds r1, r2, #0 + 800a5de: 1c02 adds r2, r0, #0 + 800a5e0: 430a orrs r2, r1 + 800a5e2: 745a strb r2, [r3, #17] + IP_PROTO_TCP, p->tot_len); +#endif + TCP_STATS_INC(tcp.xmit); + 800a5e4: 4b10 ldr r3, [pc, #64] ; (800a628 ) + 800a5e6: 2290 movs r2, #144 ; 0x90 + 800a5e8: 5a9b ldrh r3, [r3, r2] + 800a5ea: 3301 adds r3, #1 + 800a5ec: b299 uxth r1, r3 + 800a5ee: 4b0e ldr r3, [pc, #56] ; (800a628 ) + 800a5f0: 2290 movs r2, #144 ; 0x90 + 800a5f2: 5299 strh r1, [r3, r2] + /* Send output to IP */ +#if LWIP_NETIF_HWADDRHINT + ip_output_hinted(p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl, 0, IP_PROTO_TCP, + &(pcb->addr_hint)); +#else /* LWIP_NETIF_HWADDRHINT*/ + ip_output(p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl, 0, IP_PROTO_TCP); + 800a5f4: 6879 ldr r1, [r7, #4] + 800a5f6: 687b ldr r3, [r7, #4] + 800a5f8: 1d1a adds r2, r3, #4 + 800a5fa: 687b ldr r3, [r7, #4] + 800a5fc: 7a9c ldrb r4, [r3, #10] + 800a5fe: 6978 ldr r0, [r7, #20] + 800a600: 2306 movs r3, #6 + 800a602: 9301 str r3, [sp, #4] + 800a604: 2300 movs r3, #0 + 800a606: 9300 str r3, [sp, #0] + 800a608: 0023 movs r3, r4 + 800a60a: f001 fd01 bl 800c010 +#endif /* LWIP_NETIF_HWADDRHINT*/ + + pbuf_free(p); + 800a60e: 697b ldr r3, [r7, #20] + 800a610: 0018 movs r0, r3 + 800a612: f7fb f847 bl 80056a4 + 800a616: e002 b.n 800a61e + return; + 800a618: 46c0 nop ; (mov r8, r8) + 800a61a: e000 b.n 800a61e + return; + 800a61c: 46c0 nop ; (mov r8, r8) + + LWIP_DEBUGF(TCP_DEBUG, ("tcp_zero_window_probe: seqno %"U32_F + " ackno %"U32_F".\n", + pcb->snd_nxt - 1, pcb->rcv_nxt)); +} + 800a61e: 46bd mov sp, r7 + 800a620: b009 add sp, #36 ; 0x24 + 800a622: bd90 pop {r4, r7, pc} + 800a624: ffffc0ff .word 0xffffc0ff + 800a628: 20003158 .word 0x20003158 + +0800a62c : + * + * @param arg unused argument + */ +static void +tcpip_tcp_timer(void *arg) +{ + 800a62c: b580 push {r7, lr} + 800a62e: b082 sub sp, #8 + 800a630: af00 add r7, sp, #0 + 800a632: 6078 str r0, [r7, #4] + LWIP_UNUSED_ARG(arg); + + /* call TCP timer handler */ + tcp_tmr(); + 800a634: f7fb fabe bl 8005bb4 + /* timer still needed? */ + if (tcp_active_pcbs || tcp_tw_pcbs) { + 800a638: 4b0a ldr r3, [pc, #40] ; (800a664 ) + 800a63a: 681b ldr r3, [r3, #0] + 800a63c: 2b00 cmp r3, #0 + 800a63e: d103 bne.n 800a648 + 800a640: 4b09 ldr r3, [pc, #36] ; (800a668 ) + 800a642: 681b ldr r3, [r3, #0] + 800a644: 2b00 cmp r3, #0 + 800a646: d006 beq.n 800a656 + /* restart timer */ + sys_timeout(TCP_TMR_INTERVAL, tcpip_tcp_timer, NULL); + 800a648: 4b08 ldr r3, [pc, #32] ; (800a66c ) + 800a64a: 2200 movs r2, #0 + 800a64c: 0019 movs r1, r3 + 800a64e: 20fa movs r0, #250 ; 0xfa + 800a650: f000 f87a bl 800a748 + 800a654: e002 b.n 800a65c + } else { + /* disable timer */ + tcpip_tcp_timer_active = 0; + 800a656: 4b06 ldr r3, [pc, #24] ; (800a670 ) + 800a658: 2200 movs r2, #0 + 800a65a: 601a str r2, [r3, #0] + } +} + 800a65c: 46c0 nop ; (mov r8, r8) + 800a65e: 46bd mov sp, r7 + 800a660: b002 add sp, #8 + 800a662: bd80 pop {r7, pc} + 800a664: 20003274 .word 0x20003274 + 800a668: 20003288 .word 0x20003288 + 800a66c: 0800a62d .word 0x0800a62d + 800a670: 200022b0 .word 0x200022b0 + +0800a674 : + * the reason is to have the TCP timer only running when + * there are active (or time-wait) PCBs. + */ +void +tcp_timer_needed(void) +{ + 800a674: b580 push {r7, lr} + 800a676: af00 add r7, sp, #0 + /* timer is off but needed again? */ + if (!tcpip_tcp_timer_active && (tcp_active_pcbs || tcp_tw_pcbs)) { + 800a678: 4b0b ldr r3, [pc, #44] ; (800a6a8 ) + 800a67a: 681b ldr r3, [r3, #0] + 800a67c: 2b00 cmp r3, #0 + 800a67e: d110 bne.n 800a6a2 + 800a680: 4b0a ldr r3, [pc, #40] ; (800a6ac ) + 800a682: 681b ldr r3, [r3, #0] + 800a684: 2b00 cmp r3, #0 + 800a686: d103 bne.n 800a690 + 800a688: 4b09 ldr r3, [pc, #36] ; (800a6b0 ) + 800a68a: 681b ldr r3, [r3, #0] + 800a68c: 2b00 cmp r3, #0 + 800a68e: d008 beq.n 800a6a2 + /* enable and start timer */ + tcpip_tcp_timer_active = 1; + 800a690: 4b05 ldr r3, [pc, #20] ; (800a6a8 ) + 800a692: 2201 movs r2, #1 + 800a694: 601a str r2, [r3, #0] + sys_timeout(TCP_TMR_INTERVAL, tcpip_tcp_timer, NULL); + 800a696: 4b07 ldr r3, [pc, #28] ; (800a6b4 ) + 800a698: 2200 movs r2, #0 + 800a69a: 0019 movs r1, r3 + 800a69c: 20fa movs r0, #250 ; 0xfa + 800a69e: f000 f853 bl 800a748 + } +} + 800a6a2: 46c0 nop ; (mov r8, r8) + 800a6a4: 46bd mov sp, r7 + 800a6a6: bd80 pop {r7, pc} + 800a6a8: 200022b0 .word 0x200022b0 + 800a6ac: 20003274 .word 0x20003274 + 800a6b0: 20003288 .word 0x20003288 + 800a6b4: 0800a62d .word 0x0800a62d + +0800a6b8 : + * + * @param arg unused argument + */ +static void +ip_reass_timer(void *arg) +{ + 800a6b8: b580 push {r7, lr} + 800a6ba: b082 sub sp, #8 + 800a6bc: af00 add r7, sp, #0 + 800a6be: 6078 str r0, [r7, #4] + LWIP_UNUSED_ARG(arg); + LWIP_DEBUGF(TIMERS_DEBUG, ("tcpip: ip_reass_tmr()\n")); + ip_reass_tmr(); + 800a6c0: f001 fd14 bl 800c0ec + sys_timeout(IP_TMR_INTERVAL, ip_reass_timer, NULL); + 800a6c4: 4905 ldr r1, [pc, #20] ; (800a6dc ) + 800a6c6: 23fa movs r3, #250 ; 0xfa + 800a6c8: 009b lsls r3, r3, #2 + 800a6ca: 2200 movs r2, #0 + 800a6cc: 0018 movs r0, r3 + 800a6ce: f000 f83b bl 800a748 +} + 800a6d2: 46c0 nop ; (mov r8, r8) + 800a6d4: 46bd mov sp, r7 + 800a6d6: b002 add sp, #8 + 800a6d8: bd80 pop {r7, pc} + 800a6da: 46c0 nop ; (mov r8, r8) + 800a6dc: 0800a6b9 .word 0x0800a6b9 + +0800a6e0 : + * + * @param arg unused argument + */ +static void +arp_timer(void *arg) +{ + 800a6e0: b580 push {r7, lr} + 800a6e2: b082 sub sp, #8 + 800a6e4: af00 add r7, sp, #0 + 800a6e6: 6078 str r0, [r7, #4] + LWIP_UNUSED_ARG(arg); + LWIP_DEBUGF(TIMERS_DEBUG, ("tcpip: etharp_tmr()\n")); + etharp_tmr(); + 800a6e8: f002 fc58 bl 800cf9c + sys_timeout(ARP_TMR_INTERVAL, arp_timer, NULL); + 800a6ec: 4b04 ldr r3, [pc, #16] ; (800a700 ) + 800a6ee: 4805 ldr r0, [pc, #20] ; (800a704 ) + 800a6f0: 2200 movs r2, #0 + 800a6f2: 0019 movs r1, r3 + 800a6f4: f000 f828 bl 800a748 +} + 800a6f8: 46c0 nop ; (mov r8, r8) + 800a6fa: 46bd mov sp, r7 + 800a6fc: b002 add sp, #8 + 800a6fe: bd80 pop {r7, pc} + 800a700: 0800a6e1 .word 0x0800a6e1 + 800a704: 00001388 .word 0x00001388 + +0800a708 : +} +#endif /* LWIP_DNS */ + +/** Initialize this module */ +void sys_timeouts_init(void) +{ + 800a708: b580 push {r7, lr} + 800a70a: af00 add r7, sp, #0 +#if IP_REASSEMBLY + sys_timeout(IP_TMR_INTERVAL, ip_reass_timer, NULL); + 800a70c: 490a ldr r1, [pc, #40] ; (800a738 ) + 800a70e: 23fa movs r3, #250 ; 0xfa + 800a710: 009b lsls r3, r3, #2 + 800a712: 2200 movs r2, #0 + 800a714: 0018 movs r0, r3 + 800a716: f000 f817 bl 800a748 +#endif /* IP_REASSEMBLY */ +#if LWIP_ARP + sys_timeout(ARP_TMR_INTERVAL, arp_timer, NULL); + 800a71a: 4b08 ldr r3, [pc, #32] ; (800a73c ) + 800a71c: 4808 ldr r0, [pc, #32] ; (800a740 ) + 800a71e: 2200 movs r2, #0 + 800a720: 0019 movs r1, r3 + 800a722: f000 f811 bl 800a748 + sys_timeout(DNS_TMR_INTERVAL, dns_timer, NULL); +#endif /* LWIP_DNS */ + +#if NO_SYS + /* Initialise timestamp for sys_check_timeouts */ + timeouts_last_time = sys_now(); + 800a726: f003 fc5b bl 800dfe0 + 800a72a: 0002 movs r2, r0 + 800a72c: 4b05 ldr r3, [pc, #20] ; (800a744 ) + 800a72e: 601a str r2, [r3, #0] +#endif +} + 800a730: 46c0 nop ; (mov r8, r8) + 800a732: 46bd mov sp, r7 + 800a734: bd80 pop {r7, pc} + 800a736: 46c0 nop ; (mov r8, r8) + 800a738: 0800a6b9 .word 0x0800a6b9 + 800a73c: 0800a6e1 .word 0x0800a6e1 + 800a740: 00001388 .word 0x00001388 + 800a744: 200022ac .word 0x200022ac + +0800a748 : +sys_timeout_debug(u32_t msecs, sys_timeout_handler handler, void *arg, const char* handler_name) +#else /* LWIP_DEBUG_TIMERNAMES */ +void +sys_timeout(u32_t msecs, sys_timeout_handler handler, void *arg) +#endif /* LWIP_DEBUG_TIMERNAMES */ +{ + 800a748: b580 push {r7, lr} + 800a74a: b086 sub sp, #24 + 800a74c: af00 add r7, sp, #0 + 800a74e: 60f8 str r0, [r7, #12] + 800a750: 60b9 str r1, [r7, #8] + 800a752: 607a str r2, [r7, #4] + struct sys_timeo *timeout, *t; + + timeout = (struct sys_timeo *)memp_malloc(MEMP_SYS_TIMEOUT); + 800a754: 2007 movs r0, #7 + 800a756: f7fa fb5d bl 8004e14 + 800a75a: 0003 movs r3, r0 + 800a75c: 613b str r3, [r7, #16] + if (timeout == NULL) { + 800a75e: 693b ldr r3, [r7, #16] + 800a760: 2b00 cmp r3, #0 + 800a762: d05b beq.n 800a81c + LWIP_ASSERT("sys_timeout: timeout != NULL, pool MEMP_SYS_TIMEOUT is empty", timeout != NULL); + return; + } + timeout->next = NULL; + 800a764: 693b ldr r3, [r7, #16] + 800a766: 2200 movs r2, #0 + 800a768: 601a str r2, [r3, #0] + timeout->h = handler; + 800a76a: 693b ldr r3, [r7, #16] + 800a76c: 68ba ldr r2, [r7, #8] + 800a76e: 609a str r2, [r3, #8] + timeout->arg = arg; + 800a770: 693b ldr r3, [r7, #16] + 800a772: 687a ldr r2, [r7, #4] + 800a774: 60da str r2, [r3, #12] + timeout->time = msecs; + 800a776: 693b ldr r3, [r7, #16] + 800a778: 68fa ldr r2, [r7, #12] + 800a77a: 605a str r2, [r3, #4] + timeout->handler_name = handler_name; + LWIP_DEBUGF(TIMERS_DEBUG, ("sys_timeout: %p msecs=%"U32_F" handler=%s arg=%p\n", + (void *)timeout, msecs, handler_name, (void *)arg)); +#endif /* LWIP_DEBUG_TIMERNAMES */ + + if (next_timeout == NULL) { + 800a77c: 4b29 ldr r3, [pc, #164] ; (800a824 ) + 800a77e: 681b ldr r3, [r3, #0] + 800a780: 2b00 cmp r3, #0 + 800a782: d103 bne.n 800a78c + next_timeout = timeout; + 800a784: 4b27 ldr r3, [pc, #156] ; (800a824 ) + 800a786: 693a ldr r2, [r7, #16] + 800a788: 601a str r2, [r3, #0] + return; + 800a78a: e048 b.n 800a81e + } + + if (next_timeout->time > msecs) { + 800a78c: 4b25 ldr r3, [pc, #148] ; (800a824 ) + 800a78e: 681b ldr r3, [r3, #0] + 800a790: 685b ldr r3, [r3, #4] + 800a792: 68fa ldr r2, [r7, #12] + 800a794: 429a cmp r2, r3 + 800a796: d20f bcs.n 800a7b8 + next_timeout->time -= msecs; + 800a798: 4b22 ldr r3, [pc, #136] ; (800a824 ) + 800a79a: 681b ldr r3, [r3, #0] + 800a79c: 6859 ldr r1, [r3, #4] + 800a79e: 4b21 ldr r3, [pc, #132] ; (800a824 ) + 800a7a0: 681b ldr r3, [r3, #0] + 800a7a2: 68fa ldr r2, [r7, #12] + 800a7a4: 1a8a subs r2, r1, r2 + 800a7a6: 605a str r2, [r3, #4] + timeout->next = next_timeout; + 800a7a8: 4b1e ldr r3, [pc, #120] ; (800a824 ) + 800a7aa: 681a ldr r2, [r3, #0] + 800a7ac: 693b ldr r3, [r7, #16] + 800a7ae: 601a str r2, [r3, #0] + next_timeout = timeout; + 800a7b0: 4b1c ldr r3, [pc, #112] ; (800a824 ) + 800a7b2: 693a ldr r2, [r7, #16] + 800a7b4: 601a str r2, [r3, #0] + 800a7b6: e032 b.n 800a81e + } else { + for(t = next_timeout; t != NULL; t = t->next) { + 800a7b8: 4b1a ldr r3, [pc, #104] ; (800a824 ) + 800a7ba: 681b ldr r3, [r3, #0] + 800a7bc: 617b str r3, [r7, #20] + 800a7be: e029 b.n 800a814 + timeout->time -= t->time; + 800a7c0: 693b ldr r3, [r7, #16] + 800a7c2: 685a ldr r2, [r3, #4] + 800a7c4: 697b ldr r3, [r7, #20] + 800a7c6: 685b ldr r3, [r3, #4] + 800a7c8: 1ad2 subs r2, r2, r3 + 800a7ca: 693b ldr r3, [r7, #16] + 800a7cc: 605a str r2, [r3, #4] + if (t->next == NULL || t->next->time > timeout->time) { + 800a7ce: 697b ldr r3, [r7, #20] + 800a7d0: 681b ldr r3, [r3, #0] + 800a7d2: 2b00 cmp r3, #0 + 800a7d4: d006 beq.n 800a7e4 + 800a7d6: 697b ldr r3, [r7, #20] + 800a7d8: 681b ldr r3, [r3, #0] + 800a7da: 685a ldr r2, [r3, #4] + 800a7dc: 693b ldr r3, [r7, #16] + 800a7de: 685b ldr r3, [r3, #4] + 800a7e0: 429a cmp r2, r3 + 800a7e2: d914 bls.n 800a80e + if (t->next != NULL) { + 800a7e4: 697b ldr r3, [r7, #20] + 800a7e6: 681b ldr r3, [r3, #0] + 800a7e8: 2b00 cmp r3, #0 + 800a7ea: d008 beq.n 800a7fe + t->next->time -= timeout->time; + 800a7ec: 697b ldr r3, [r7, #20] + 800a7ee: 681b ldr r3, [r3, #0] + 800a7f0: 6859 ldr r1, [r3, #4] + 800a7f2: 693b ldr r3, [r7, #16] + 800a7f4: 685a ldr r2, [r3, #4] + 800a7f6: 697b ldr r3, [r7, #20] + 800a7f8: 681b ldr r3, [r3, #0] + 800a7fa: 1a8a subs r2, r1, r2 + 800a7fc: 605a str r2, [r3, #4] + } + timeout->next = t->next; + 800a7fe: 697b ldr r3, [r7, #20] + 800a800: 681a ldr r2, [r3, #0] + 800a802: 693b ldr r3, [r7, #16] + 800a804: 601a str r2, [r3, #0] + t->next = timeout; + 800a806: 697b ldr r3, [r7, #20] + 800a808: 693a ldr r2, [r7, #16] + 800a80a: 601a str r2, [r3, #0] + break; + 800a80c: e007 b.n 800a81e + for(t = next_timeout; t != NULL; t = t->next) { + 800a80e: 697b ldr r3, [r7, #20] + 800a810: 681b ldr r3, [r3, #0] + 800a812: 617b str r3, [r7, #20] + 800a814: 697b ldr r3, [r7, #20] + 800a816: 2b00 cmp r3, #0 + 800a818: d1d2 bne.n 800a7c0 + 800a81a: e000 b.n 800a81e + return; + 800a81c: 46c0 nop ; (mov r8, r8) + } + } + } +} + 800a81e: 46bd mov sp, r7 + 800a820: b006 add sp, #24 + 800a822: bd80 pop {r7, pc} + 800a824: 200022a8 .word 0x200022a8 + +0800a828 : +/** + * Initialize this module. + */ +void +udp_init(void) +{ + 800a828: b580 push {r7, lr} + 800a82a: af00 add r7, sp, #0 +#if LWIP_RANDOMIZE_INITIAL_LOCAL_PORTS && defined(LWIP_RAND) + udp_port = UDP_ENSURE_LOCAL_PORT_RANGE(LWIP_RAND()); +#endif /* LWIP_RANDOMIZE_INITIAL_LOCAL_PORTS && defined(LWIP_RAND) */ +} + 800a82c: 46c0 nop ; (mov r8, r8) + 800a82e: 46bd mov sp, r7 + 800a830: bd80 pop {r7, pc} + ... + +0800a834 : + * + * @return a new (free) local UDP port number + */ +static u16_t +udp_new_port(void) +{ + 800a834: b580 push {r7, lr} + 800a836: b082 sub sp, #8 + 800a838: af00 add r7, sp, #0 + u16_t n = 0; + 800a83a: 1dbb adds r3, r7, #6 + 800a83c: 2200 movs r2, #0 + 800a83e: 801a strh r2, [r3, #0] + struct udp_pcb *pcb; + +again: + if (udp_port++ == UDP_LOCAL_PORT_RANGE_END) { + 800a840: 4b16 ldr r3, [pc, #88] ; (800a89c ) + 800a842: 881b ldrh r3, [r3, #0] + 800a844: 1c5a adds r2, r3, #1 + 800a846: b291 uxth r1, r2 + 800a848: 4a14 ldr r2, [pc, #80] ; (800a89c ) + 800a84a: 8011 strh r1, [r2, #0] + 800a84c: 4a14 ldr r2, [pc, #80] ; (800a8a0 ) + 800a84e: 4293 cmp r3, r2 + 800a850: d102 bne.n 800a858 + udp_port = UDP_LOCAL_PORT_RANGE_START; + 800a852: 4b12 ldr r3, [pc, #72] ; (800a89c ) + 800a854: 4a13 ldr r2, [pc, #76] ; (800a8a4 ) + 800a856: 801a strh r2, [r3, #0] + } + /* Check all PCBs. */ + for(pcb = udp_pcbs; pcb != NULL; pcb = pcb->next) { + 800a858: 4b13 ldr r3, [pc, #76] ; (800a8a8 ) + 800a85a: 681b ldr r3, [r3, #0] + 800a85c: 603b str r3, [r7, #0] + 800a85e: e014 b.n 800a88a + if (pcb->local_port == udp_port) { + 800a860: 683b ldr r3, [r7, #0] + 800a862: 8a5a ldrh r2, [r3, #18] + 800a864: 4b0d ldr r3, [pc, #52] ; (800a89c ) + 800a866: 881b ldrh r3, [r3, #0] + 800a868: 429a cmp r2, r3 + 800a86a: d10b bne.n 800a884 + if (++n > (UDP_LOCAL_PORT_RANGE_END - UDP_LOCAL_PORT_RANGE_START)) { + 800a86c: 1dbb adds r3, r7, #6 + 800a86e: 1dba adds r2, r7, #6 + 800a870: 8812 ldrh r2, [r2, #0] + 800a872: 3201 adds r2, #1 + 800a874: 801a strh r2, [r3, #0] + 800a876: 1dbb adds r3, r7, #6 + 800a878: 881b ldrh r3, [r3, #0] + 800a87a: 4a0c ldr r2, [pc, #48] ; (800a8ac ) + 800a87c: 4293 cmp r3, r2 + 800a87e: d9df bls.n 800a840 + return 0; + 800a880: 2300 movs r3, #0 + 800a882: e007 b.n 800a894 + for(pcb = udp_pcbs; pcb != NULL; pcb = pcb->next) { + 800a884: 683b ldr r3, [r7, #0] + 800a886: 68db ldr r3, [r3, #12] + 800a888: 603b str r3, [r7, #0] + 800a88a: 683b ldr r3, [r7, #0] + 800a88c: 2b00 cmp r3, #0 + 800a88e: d1e7 bne.n 800a860 + } + goto again; + } + } + return udp_port; + 800a890: 4b02 ldr r3, [pc, #8] ; (800a89c ) + 800a892: 881b ldrh r3, [r3, #0] + if (ipcb != NULL) { + return 0; + } + return udp_port; +#endif +} + 800a894: 0018 movs r0, r3 + 800a896: 46bd mov sp, r7 + 800a898: b002 add sp, #8 + 800a89a: bd80 pop {r7, pc} + 800a89c: 20000014 .word 0x20000014 + 800a8a0: 0000ffff .word 0x0000ffff + 800a8a4: ffffc000 .word 0xffffc000 + 800a8a8: 20003290 .word 0x20003290 + 800a8ac: 00003fff .word 0x00003fff + +0800a8b0 : + * @param inp network interface on which the datagram was received. + * + */ +void +udp_input(struct pbuf *p, struct netif *inp) +{ + 800a8b0: b5b0 push {r4, r5, r7, lr} + 800a8b2: b08c sub sp, #48 ; 0x30 + 800a8b4: af02 add r7, sp, #8 + 800a8b6: 6078 str r0, [r7, #4] + 800a8b8: 6039 str r1, [r7, #0] + u8_t local_match; + u8_t broadcast; + + PERF_START; + + UDP_STATS_INC(udp.recv); + 800a8ba: 4bc4 ldr r3, [pc, #784] ; (800abcc ) + 800a8bc: 227a movs r2, #122 ; 0x7a + 800a8be: 5a9b ldrh r3, [r3, r2] + 800a8c0: 3301 adds r3, #1 + 800a8c2: b299 uxth r1, r3 + 800a8c4: 4bc1 ldr r3, [pc, #772] ; (800abcc ) + 800a8c6: 227a movs r2, #122 ; 0x7a + 800a8c8: 5299 strh r1, [r3, r2] + + iphdr = (struct ip_hdr *)p->payload; + 800a8ca: 687b ldr r3, [r7, #4] + 800a8cc: 685b ldr r3, [r3, #4] + 800a8ce: 617b str r3, [r7, #20] + + /* Check minimum length (IP header + UDP header) + * and move payload pointer to UDP header */ + if (p->tot_len < (IPH_HL(iphdr) * 4 + UDP_HLEN) || pbuf_header(p, -(s16_t)(IPH_HL(iphdr) * 4))) { + 800a8d0: 687b ldr r3, [r7, #4] + 800a8d2: 891b ldrh r3, [r3, #8] + 800a8d4: 001a movs r2, r3 + 800a8d6: 697b ldr r3, [r7, #20] + 800a8d8: 781b ldrb r3, [r3, #0] + 800a8da: 0019 movs r1, r3 + 800a8dc: 230f movs r3, #15 + 800a8de: 400b ands r3, r1 + 800a8e0: 3302 adds r3, #2 + 800a8e2: 009b lsls r3, r3, #2 + 800a8e4: 429a cmp r2, r3 + 800a8e6: db11 blt.n 800a90c + 800a8e8: 697b ldr r3, [r7, #20] + 800a8ea: 781b ldrb r3, [r3, #0] + 800a8ec: b29b uxth r3, r3 + 800a8ee: 220f movs r2, #15 + 800a8f0: 4013 ands r3, r2 + 800a8f2: b29b uxth r3, r3 + 800a8f4: 009b lsls r3, r3, #2 + 800a8f6: b29b uxth r3, r3 + 800a8f8: 425b negs r3, r3 + 800a8fa: b29b uxth r3, r3 + 800a8fc: b21a sxth r2, r3 + 800a8fe: 687b ldr r3, [r7, #4] + 800a900: 0011 movs r1, r2 + 800a902: 0018 movs r0, r3 + 800a904: f7fa fe47 bl 8005596 + 800a908: 1e03 subs r3, r0, #0 + 800a90a: d014 beq.n 800a936 + /* drop short packets */ + LWIP_DEBUGF(UDP_DEBUG, + ("udp_input: short UDP datagram (%"U16_F" bytes) discarded\n", p->tot_len)); + UDP_STATS_INC(udp.lenerr); + 800a90c: 4baf ldr r3, [pc, #700] ; (800abcc ) + 800a90e: 2282 movs r2, #130 ; 0x82 + 800a910: 5a9b ldrh r3, [r3, r2] + 800a912: 3301 adds r3, #1 + 800a914: b299 uxth r1, r3 + 800a916: 4bad ldr r3, [pc, #692] ; (800abcc ) + 800a918: 2282 movs r2, #130 ; 0x82 + 800a91a: 5299 strh r1, [r3, r2] + UDP_STATS_INC(udp.drop); + 800a91c: 4bab ldr r3, [pc, #684] ; (800abcc ) + 800a91e: 227e movs r2, #126 ; 0x7e + 800a920: 5a9b ldrh r3, [r3, r2] + 800a922: 3301 adds r3, #1 + 800a924: b299 uxth r1, r3 + 800a926: 4ba9 ldr r3, [pc, #676] ; (800abcc ) + 800a928: 227e movs r2, #126 ; 0x7e + 800a92a: 5299 strh r1, [r3, r2] + snmp_inc_udpinerrors(); + pbuf_free(p); + 800a92c: 687b ldr r3, [r7, #4] + 800a92e: 0018 movs r0, r3 + 800a930: f7fa feb8 bl 80056a4 + goto end; + 800a934: e156 b.n 800abe4 + } + + udphdr = (struct udp_hdr *)p->payload; + 800a936: 687b ldr r3, [r7, #4] + 800a938: 685b ldr r3, [r3, #4] + 800a93a: 613b str r3, [r7, #16] + + /* is broadcast packet ? */ + broadcast = ip_addr_isbroadcast(¤t_iphdr_dest, inp); + 800a93c: 4ba4 ldr r3, [pc, #656] ; (800abd0 ) + 800a93e: 681b ldr r3, [r3, #0] + 800a940: 220f movs r2, #15 + 800a942: 18bc adds r4, r7, r2 + 800a944: 683a ldr r2, [r7, #0] + 800a946: 0011 movs r1, r2 + 800a948: 0018 movs r0, r3 + 800a94a: f001 fb97 bl 800c07c + 800a94e: 0003 movs r3, r0 + 800a950: 7023 strb r3, [r4, #0] + + LWIP_DEBUGF(UDP_DEBUG, ("udp_input: received datagram of length %"U16_F"\n", p->tot_len)); + + /* convert src and dest ports to host byte order */ + src = ntohs(udphdr->src); + 800a952: 693b ldr r3, [r7, #16] + 800a954: 781a ldrb r2, [r3, #0] + 800a956: 785b ldrb r3, [r3, #1] + 800a958: 021b lsls r3, r3, #8 + 800a95a: 4313 orrs r3, r2 + 800a95c: b29b uxth r3, r3 + 800a95e: 220c movs r2, #12 + 800a960: 18bc adds r4, r7, r2 + 800a962: 0018 movs r0, r3 + 800a964: f7f9 fe6c bl 8004640 + 800a968: 0003 movs r3, r0 + 800a96a: 8023 strh r3, [r4, #0] + dest = ntohs(udphdr->dest); + 800a96c: 693b ldr r3, [r7, #16] + 800a96e: 789a ldrb r2, [r3, #2] + 800a970: 78db ldrb r3, [r3, #3] + 800a972: 021b lsls r3, r3, #8 + 800a974: 4313 orrs r3, r2 + 800a976: b29b uxth r3, r3 + 800a978: 220a movs r2, #10 + 800a97a: 18bc adds r4, r7, r2 + 800a97c: 0018 movs r0, r3 + 800a97e: f7f9 fe5f bl 8004640 + 800a982: 0003 movs r3, r0 + 800a984: 8023 strh r3, [r4, #0] + } + } + } else +#endif /* LWIP_DHCP */ + { + prev = NULL; + 800a986: 2300 movs r3, #0 + 800a988: 623b str r3, [r7, #32] + local_match = 0; + 800a98a: 231b movs r3, #27 + 800a98c: 18fb adds r3, r7, r3 + 800a98e: 2200 movs r2, #0 + 800a990: 701a strb r2, [r3, #0] + uncon_pcb = NULL; + 800a992: 2300 movs r3, #0 + 800a994: 61fb str r3, [r7, #28] + /* Iterate through the UDP pcb list for a matching pcb. + * 'Perfect match' pcbs (connected to the remote port & ip address) are + * preferred. If no perfect match is found, the first unconnected pcb that + * matches the local port and ip address gets the datagram. */ + for (pcb = udp_pcbs; pcb != NULL; pcb = pcb->next) { + 800a996: 4b8f ldr r3, [pc, #572] ; (800abd4 ) + 800a998: 681b ldr r3, [r3, #0] + 800a99a: 627b str r3, [r7, #36] ; 0x24 + 800a99c: e077 b.n 800aa8e + local_match = 0; + 800a99e: 231b movs r3, #27 + 800a9a0: 18fb adds r3, r7, r3 + 800a9a2: 2200 movs r2, #0 + 800a9a4: 701a strb r2, [r3, #0] + ip4_addr3_16(&pcb->local_ip), ip4_addr4_16(&pcb->local_ip), pcb->local_port, + ip4_addr1_16(&pcb->remote_ip), ip4_addr2_16(&pcb->remote_ip), + ip4_addr3_16(&pcb->remote_ip), ip4_addr4_16(&pcb->remote_ip), pcb->remote_port)); + + /* compare PCB local addr+port to UDP destination addr+port */ + if (pcb->local_port == dest) { + 800a9a6: 6a7b ldr r3, [r7, #36] ; 0x24 + 800a9a8: 8a5b ldrh r3, [r3, #18] + 800a9aa: 220a movs r2, #10 + 800a9ac: 18ba adds r2, r7, r2 + 800a9ae: 8812 ldrh r2, [r2, #0] + 800a9b0: 429a cmp r2, r3 + 800a9b2: d135 bne.n 800aa20 + if ( + 800a9b4: 230f movs r3, #15 + 800a9b6: 18fb adds r3, r7, r3 + 800a9b8: 781b ldrb r3, [r3, #0] + 800a9ba: 2b00 cmp r3, #0 + 800a9bc: d106 bne.n 800a9cc + (!broadcast && ip_addr_isany(&pcb->local_ip)) || + 800a9be: 6a7b ldr r3, [r7, #36] ; 0x24 + 800a9c0: 2b00 cmp r3, #0 + 800a9c2: d01e beq.n 800aa02 + 800a9c4: 6a7b ldr r3, [r7, #36] ; 0x24 + 800a9c6: 681b ldr r3, [r3, #0] + 800a9c8: 2b00 cmp r3, #0 + 800a9ca: d01a beq.n 800aa02 + ip_addr_cmp(&(pcb->local_ip), ¤t_iphdr_dest) || + 800a9cc: 6a7b ldr r3, [r7, #36] ; 0x24 + 800a9ce: 681a ldr r2, [r3, #0] + 800a9d0: 4b7f ldr r3, [pc, #508] ; (800abd0 ) + 800a9d2: 681b ldr r3, [r3, #0] + (!broadcast && ip_addr_isany(&pcb->local_ip)) || + 800a9d4: 429a cmp r2, r3 + 800a9d6: d014 beq.n 800aa02 + ip_addr_cmp(&(pcb->local_ip), ¤t_iphdr_dest) || + 800a9d8: 230f movs r3, #15 + 800a9da: 18fb adds r3, r7, r3 + 800a9dc: 781b ldrb r3, [r3, #0] + 800a9de: 2b00 cmp r3, #0 + 800a9e0: d01e beq.n 800aa20 + (broadcast && ip_get_option(pcb, SOF_BROADCAST) && + (ip_addr_isany(&pcb->local_ip) || + ip_addr_netcmp(&pcb->local_ip, ip_current_dest_addr(), &inp->netmask)))) { +#else /* IP_SOF_BROADCAST_RECV */ + (broadcast && + (ip_addr_isany(&pcb->local_ip) || + 800a9e2: 6a7b ldr r3, [r7, #36] ; 0x24 + (broadcast && + 800a9e4: 2b00 cmp r3, #0 + 800a9e6: d00c beq.n 800aa02 + (ip_addr_isany(&pcb->local_ip) || + 800a9e8: 6a7b ldr r3, [r7, #36] ; 0x24 + 800a9ea: 681b ldr r3, [r3, #0] + 800a9ec: 2b00 cmp r3, #0 + 800a9ee: d008 beq.n 800aa02 + ip_addr_netcmp(&pcb->local_ip, ip_current_dest_addr(), &inp->netmask)))) { + 800a9f0: 6a7b ldr r3, [r7, #36] ; 0x24 + 800a9f2: 681a ldr r2, [r3, #0] + 800a9f4: 4b76 ldr r3, [pc, #472] ; (800abd0 ) + 800a9f6: 681b ldr r3, [r3, #0] + 800a9f8: 405a eors r2, r3 + 800a9fa: 683b ldr r3, [r7, #0] + 800a9fc: 689b ldr r3, [r3, #8] + 800a9fe: 4013 ands r3, r2 + (ip_addr_isany(&pcb->local_ip) || + 800aa00: d10e bne.n 800aa20 +#endif /* IP_SOF_BROADCAST_RECV */ + local_match = 1; + 800aa02: 231b movs r3, #27 + 800aa04: 18fb adds r3, r7, r3 + 800aa06: 2201 movs r2, #1 + 800aa08: 701a strb r2, [r3, #0] + if ((uncon_pcb == NULL) && + 800aa0a: 69fb ldr r3, [r7, #28] + 800aa0c: 2b00 cmp r3, #0 + 800aa0e: d107 bne.n 800aa20 + ((pcb->flags & UDP_FLAGS_CONNECTED) == 0)) { + 800aa10: 6a7b ldr r3, [r7, #36] ; 0x24 + 800aa12: 7c1b ldrb r3, [r3, #16] + 800aa14: 001a movs r2, r3 + 800aa16: 2304 movs r3, #4 + 800aa18: 4013 ands r3, r2 + if ((uncon_pcb == NULL) && + 800aa1a: d101 bne.n 800aa20 + /* the first unconnected matching PCB */ + uncon_pcb = pcb; + 800aa1c: 6a7b ldr r3, [r7, #36] ; 0x24 + 800aa1e: 61fb str r3, [r7, #28] + } + } + } + /* compare PCB remote addr+port to UDP source addr+port */ + if ((local_match != 0) && + 800aa20: 231b movs r3, #27 + 800aa22: 18fb adds r3, r7, r3 + 800aa24: 781b ldrb r3, [r3, #0] + 800aa26: 2b00 cmp r3, #0 + 800aa28: d02c beq.n 800aa84 + (pcb->remote_port == src) && + 800aa2a: 6a7b ldr r3, [r7, #36] ; 0x24 + 800aa2c: 8a9b ldrh r3, [r3, #20] + if ((local_match != 0) && + 800aa2e: 220c movs r2, #12 + 800aa30: 18ba adds r2, r7, r2 + 800aa32: 8812 ldrh r2, [r2, #0] + 800aa34: 429a cmp r2, r3 + 800aa36: d125 bne.n 800aa84 + (ip_addr_isany(&pcb->remote_ip) || + 800aa38: 6a7b ldr r3, [r7, #36] ; 0x24 + 800aa3a: 3304 adds r3, #4 + (pcb->remote_port == src) && + 800aa3c: 2b00 cmp r3, #0 + 800aa3e: d009 beq.n 800aa54 + (ip_addr_isany(&pcb->remote_ip) || + 800aa40: 6a7b ldr r3, [r7, #36] ; 0x24 + 800aa42: 685b ldr r3, [r3, #4] + 800aa44: 2b00 cmp r3, #0 + 800aa46: d005 beq.n 800aa54 + ip_addr_cmp(&(pcb->remote_ip), ¤t_iphdr_src))) { + 800aa48: 6a7b ldr r3, [r7, #36] ; 0x24 + 800aa4a: 685a ldr r2, [r3, #4] + 800aa4c: 4b62 ldr r3, [pc, #392] ; (800abd8 ) + 800aa4e: 681b ldr r3, [r3, #0] + (ip_addr_isany(&pcb->remote_ip) || + 800aa50: 429a cmp r2, r3 + 800aa52: d117 bne.n 800aa84 + /* the first fully matching PCB */ + if (prev != NULL) { + 800aa54: 6a3b ldr r3, [r7, #32] + 800aa56: 2b00 cmp r3, #0 + 800aa58: d00b beq.n 800aa72 + /* move the pcb to the front of udp_pcbs so that is + found faster next time */ + prev->next = pcb->next; + 800aa5a: 6a7b ldr r3, [r7, #36] ; 0x24 + 800aa5c: 68da ldr r2, [r3, #12] + 800aa5e: 6a3b ldr r3, [r7, #32] + 800aa60: 60da str r2, [r3, #12] + pcb->next = udp_pcbs; + 800aa62: 4b5c ldr r3, [pc, #368] ; (800abd4 ) + 800aa64: 681a ldr r2, [r3, #0] + 800aa66: 6a7b ldr r3, [r7, #36] ; 0x24 + 800aa68: 60da str r2, [r3, #12] + udp_pcbs = pcb; + 800aa6a: 4b5a ldr r3, [pc, #360] ; (800abd4 ) + 800aa6c: 6a7a ldr r2, [r7, #36] ; 0x24 + 800aa6e: 601a str r2, [r3, #0] + } else { + UDP_STATS_INC(udp.cachehit); + } + break; + 800aa70: e011 b.n 800aa96 + UDP_STATS_INC(udp.cachehit); + 800aa72: 4b56 ldr r3, [pc, #344] ; (800abcc ) + 800aa74: 228e movs r2, #142 ; 0x8e + 800aa76: 5a9b ldrh r3, [r3, r2] + 800aa78: 3301 adds r3, #1 + 800aa7a: b299 uxth r1, r3 + 800aa7c: 4b53 ldr r3, [pc, #332] ; (800abcc ) + 800aa7e: 228e movs r2, #142 ; 0x8e + 800aa80: 5299 strh r1, [r3, r2] + break; + 800aa82: e008 b.n 800aa96 + } + prev = pcb; + 800aa84: 6a7b ldr r3, [r7, #36] ; 0x24 + 800aa86: 623b str r3, [r7, #32] + for (pcb = udp_pcbs; pcb != NULL; pcb = pcb->next) { + 800aa88: 6a7b ldr r3, [r7, #36] ; 0x24 + 800aa8a: 68db ldr r3, [r3, #12] + 800aa8c: 627b str r3, [r7, #36] ; 0x24 + 800aa8e: 6a7b ldr r3, [r7, #36] ; 0x24 + 800aa90: 2b00 cmp r3, #0 + 800aa92: d000 beq.n 800aa96 + 800aa94: e783 b.n 800a99e + } + /* no fully matching pcb found? then look for an unconnected pcb */ + if (pcb == NULL) { + 800aa96: 6a7b ldr r3, [r7, #36] ; 0x24 + 800aa98: 2b00 cmp r3, #0 + 800aa9a: d101 bne.n 800aaa0 + pcb = uncon_pcb; + 800aa9c: 69fb ldr r3, [r7, #28] + 800aa9e: 627b str r3, [r7, #36] ; 0x24 + } + } + + /* Check checksum if this is a match or if it was directed at us. */ + if (pcb != NULL || ip_addr_cmp(&inp->ip_addr, ¤t_iphdr_dest)) { + 800aaa0: 6a7b ldr r3, [r7, #36] ; 0x24 + 800aaa2: 2b00 cmp r3, #0 + 800aaa4: d106 bne.n 800aab4 + 800aaa6: 683b ldr r3, [r7, #0] + 800aaa8: 685a ldr r2, [r3, #4] + 800aaaa: 4b49 ldr r3, [pc, #292] ; (800abd0 ) + 800aaac: 681b ldr r3, [r3, #0] + 800aaae: 429a cmp r2, r3 + 800aab0: d000 beq.n 800aab4 + 800aab2: e093 b.n 800abdc +#endif /* CHECKSUM_CHECK_UDP */ + } else +#endif /* LWIP_UDPLITE */ + { +#if CHECKSUM_CHECK_UDP + if (udphdr->chksum != 0) { + 800aab4: 693b ldr r3, [r7, #16] + 800aab6: 799a ldrb r2, [r3, #6] + 800aab8: 79db ldrb r3, [r3, #7] + 800aaba: 021b lsls r3, r3, #8 + 800aabc: 4313 orrs r3, r2 + 800aabe: b29b uxth r3, r3 + 800aac0: 2b00 cmp r3, #0 + 800aac2: d01f beq.n 800ab04 + if (inet_chksum_pseudo(p, ip_current_src_addr(), ip_current_dest_addr(), + 800aac4: 687b ldr r3, [r7, #4] + 800aac6: 891b ldrh r3, [r3, #8] + 800aac8: 4a41 ldr r2, [pc, #260] ; (800abd0 ) + 800aaca: 4943 ldr r1, [pc, #268] ; (800abd8 ) + 800aacc: 6878 ldr r0, [r7, #4] + 800aace: 9300 str r3, [sp, #0] + 800aad0: 2311 movs r3, #17 + 800aad2: f000 fdb2 bl 800b63a + 800aad6: 1e03 subs r3, r0, #0 + 800aad8: d014 beq.n 800ab04 + IP_PROTO_UDP, p->tot_len) != 0) { + LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, + ("udp_input: UDP datagram discarded due to failing checksum\n")); + UDP_STATS_INC(udp.chkerr); + 800aada: 4b3c ldr r3, [pc, #240] ; (800abcc ) + 800aadc: 2280 movs r2, #128 ; 0x80 + 800aade: 5a9b ldrh r3, [r3, r2] + 800aae0: 3301 adds r3, #1 + 800aae2: b299 uxth r1, r3 + 800aae4: 4b39 ldr r3, [pc, #228] ; (800abcc ) + 800aae6: 2280 movs r2, #128 ; 0x80 + 800aae8: 5299 strh r1, [r3, r2] + UDP_STATS_INC(udp.drop); + 800aaea: 4b38 ldr r3, [pc, #224] ; (800abcc ) + 800aaec: 227e movs r2, #126 ; 0x7e + 800aaee: 5a9b ldrh r3, [r3, r2] + 800aaf0: 3301 adds r3, #1 + 800aaf2: b299 uxth r1, r3 + 800aaf4: 4b35 ldr r3, [pc, #212] ; (800abcc ) + 800aaf6: 227e movs r2, #126 ; 0x7e + 800aaf8: 5299 strh r1, [r3, r2] + snmp_inc_udpinerrors(); + pbuf_free(p); + 800aafa: 687b ldr r3, [r7, #4] + 800aafc: 0018 movs r0, r3 + 800aafe: f7fa fdd1 bl 80056a4 + goto end; + 800ab02: e06f b.n 800abe4 + } + } +#endif /* CHECKSUM_CHECK_UDP */ + } + if(pbuf_header(p, -UDP_HLEN)) { + 800ab04: 2308 movs r3, #8 + 800ab06: 425a negs r2, r3 + 800ab08: 687b ldr r3, [r7, #4] + 800ab0a: 0011 movs r1, r2 + 800ab0c: 0018 movs r0, r3 + 800ab0e: f7fa fd42 bl 8005596 + 800ab12: 1e03 subs r3, r0, #0 + 800ab14: d00c beq.n 800ab30 + /* Can we cope with this failing? Just assert for now */ + LWIP_ASSERT("pbuf_header failed\n", 0); + UDP_STATS_INC(udp.drop); + 800ab16: 4b2d ldr r3, [pc, #180] ; (800abcc ) + 800ab18: 227e movs r2, #126 ; 0x7e + 800ab1a: 5a9b ldrh r3, [r3, r2] + 800ab1c: 3301 adds r3, #1 + 800ab1e: b299 uxth r1, r3 + 800ab20: 4b2a ldr r3, [pc, #168] ; (800abcc ) + 800ab22: 227e movs r2, #126 ; 0x7e + 800ab24: 5299 strh r1, [r3, r2] + snmp_inc_udpinerrors(); + pbuf_free(p); + 800ab26: 687b ldr r3, [r7, #4] + 800ab28: 0018 movs r0, r3 + 800ab2a: f7fa fdbb bl 80056a4 + goto end; + 800ab2e: e059 b.n 800abe4 + } + if (pcb != NULL) { + 800ab30: 6a7b ldr r3, [r7, #36] ; 0x24 + 800ab32: 2b00 cmp r3, #0 + 800ab34: d016 beq.n 800ab64 + pbuf_header(p, -(s16_t)((IPH_HL(iphdr) * 4) + UDP_HLEN)); + } + } +#endif /* SO_REUSE && SO_REUSE_RXTOALL */ + /* callback */ + if (pcb->recv != NULL) { + 800ab36: 6a7b ldr r3, [r7, #36] ; 0x24 + 800ab38: 699b ldr r3, [r3, #24] + 800ab3a: 2b00 cmp r3, #0 + 800ab3c: d00d beq.n 800ab5a + /* now the recv function is responsible for freeing p */ + pcb->recv(pcb->recv_arg, pcb, p, ip_current_src_addr(), src); + 800ab3e: 6a7b ldr r3, [r7, #36] ; 0x24 + 800ab40: 699c ldr r4, [r3, #24] + 800ab42: 6a7b ldr r3, [r7, #36] ; 0x24 + 800ab44: 69d8 ldr r0, [r3, #28] + 800ab46: 4d24 ldr r5, [pc, #144] ; (800abd8 ) + 800ab48: 687a ldr r2, [r7, #4] + 800ab4a: 6a79 ldr r1, [r7, #36] ; 0x24 + 800ab4c: 230c movs r3, #12 + 800ab4e: 18fb adds r3, r7, r3 + 800ab50: 881b ldrh r3, [r3, #0] + 800ab52: 9300 str r3, [sp, #0] + 800ab54: 002b movs r3, r5 + 800ab56: 47a0 blx r4 + if (pcb != NULL) { + 800ab58: e044 b.n 800abe4 + } else { + /* no recv function registered? then we have to free the pbuf! */ + pbuf_free(p); + 800ab5a: 687b ldr r3, [r7, #4] + 800ab5c: 0018 movs r0, r3 + 800ab5e: f7fa fda1 bl 80056a4 + goto end; + 800ab62: e03f b.n 800abe4 + LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, ("udp_input: not for us.\n")); + +#if LWIP_ICMP + /* No match was found, send ICMP destination port unreachable unless + destination address was broadcast/multicast. */ + if (!broadcast && + 800ab64: 230f movs r3, #15 + 800ab66: 18fb adds r3, r7, r3 + 800ab68: 781b ldrb r3, [r3, #0] + 800ab6a: 2b00 cmp r3, #0 + 800ab6c: d119 bne.n 800aba2 + !ip_addr_ismulticast(¤t_iphdr_dest)) { + 800ab6e: 4b18 ldr r3, [pc, #96] ; (800abd0 ) + 800ab70: 681b ldr r3, [r3, #0] + 800ab72: 22f0 movs r2, #240 ; 0xf0 + 800ab74: 4013 ands r3, r2 + if (!broadcast && + 800ab76: 2be0 cmp r3, #224 ; 0xe0 + 800ab78: d013 beq.n 800aba2 + /* move payload pointer back to ip header */ + pbuf_header(p, (IPH_HL(iphdr) * 4) + UDP_HLEN); + 800ab7a: 697b ldr r3, [r7, #20] + 800ab7c: 781b ldrb r3, [r3, #0] + 800ab7e: 001a movs r2, r3 + 800ab80: 230f movs r3, #15 + 800ab82: 4013 ands r3, r2 + 800ab84: 3302 adds r3, #2 + 800ab86: b29b uxth r3, r3 + 800ab88: 009b lsls r3, r3, #2 + 800ab8a: b29b uxth r3, r3 + 800ab8c: b21a sxth r2, r3 + 800ab8e: 687b ldr r3, [r7, #4] + 800ab90: 0011 movs r1, r2 + 800ab92: 0018 movs r0, r3 + 800ab94: f7fa fcff bl 8005596 + LWIP_ASSERT("p->payload == iphdr", (p->payload == iphdr)); + icmp_dest_unreach(p, ICMP_DUR_PORT); + 800ab98: 687b ldr r3, [r7, #4] + 800ab9a: 2103 movs r1, #3 + 800ab9c: 0018 movs r0, r3 + 800ab9e: f000 fc35 bl 800b40c + } +#endif /* LWIP_ICMP */ + UDP_STATS_INC(udp.proterr); + 800aba2: 4b0a ldr r3, [pc, #40] ; (800abcc ) + 800aba4: 2288 movs r2, #136 ; 0x88 + 800aba6: 5a9b ldrh r3, [r3, r2] + 800aba8: 3301 adds r3, #1 + 800abaa: b299 uxth r1, r3 + 800abac: 4b07 ldr r3, [pc, #28] ; (800abcc ) + 800abae: 2288 movs r2, #136 ; 0x88 + 800abb0: 5299 strh r1, [r3, r2] + UDP_STATS_INC(udp.drop); + 800abb2: 4b06 ldr r3, [pc, #24] ; (800abcc ) + 800abb4: 227e movs r2, #126 ; 0x7e + 800abb6: 5a9b ldrh r3, [r3, r2] + 800abb8: 3301 adds r3, #1 + 800abba: b299 uxth r1, r3 + 800abbc: 4b03 ldr r3, [pc, #12] ; (800abcc ) + 800abbe: 227e movs r2, #126 ; 0x7e + 800abc0: 5299 strh r1, [r3, r2] + snmp_inc_udpnoports(); + pbuf_free(p); + 800abc2: 687b ldr r3, [r7, #4] + 800abc4: 0018 movs r0, r3 + 800abc6: f7fa fd6d bl 80056a4 + if (pcb != NULL) { + 800abca: e00b b.n 800abe4 + 800abcc: 20003158 .word 0x20003158 + 800abd0: 2000329c .word 0x2000329c + 800abd4: 20003290 .word 0x20003290 + 800abd8: 20003294 .word 0x20003294 + } + } else { + pbuf_free(p); + 800abdc: 687b ldr r3, [r7, #4] + 800abde: 0018 movs r0, r3 + 800abe0: f7fa fd60 bl 80056a4 + } +end: + PERF_STOP("udp_input"); +} + 800abe4: 46c0 nop ; (mov r8, r8) + 800abe6: 46bd mov sp, r7 + 800abe8: b00a add sp, #40 ; 0x28 + 800abea: bdb0 pop {r4, r5, r7, pc} + +0800abec : + * @see udp_disconnect() udp_send() + */ +err_t +udp_sendto(struct udp_pcb *pcb, struct pbuf *p, + ip_addr_t *dst_ip, u16_t dst_port) +{ + 800abec: b590 push {r4, r7, lr} + 800abee: b089 sub sp, #36 ; 0x24 + 800abf0: af02 add r7, sp, #8 + 800abf2: 60f8 str r0, [r7, #12] + 800abf4: 60b9 str r1, [r7, #8] + 800abf6: 607a str r2, [r7, #4] + 800abf8: 001a movs r2, r3 + 800abfa: 1cbb adds r3, r7, #2 + 800abfc: 801a strh r2, [r3, #0] + + /* find the outgoing network interface for this packet */ +#if LWIP_IGMP + netif = ip_route((ip_addr_ismulticast(dst_ip))?(&(pcb->multicast_ip)):(dst_ip)); +#else + netif = ip_route(dst_ip); + 800abfe: 687b ldr r3, [r7, #4] + 800ac00: 0018 movs r0, r3 + 800ac02: f000 fe21 bl 800b848 + 800ac06: 0003 movs r3, r0 + 800ac08: 617b str r3, [r7, #20] +#endif /* LWIP_IGMP */ + + /* no outgoing network interface could be found? */ + if (netif == NULL) { + 800ac0a: 697b ldr r3, [r7, #20] + 800ac0c: 2b00 cmp r3, #0 + 800ac0e: d10a bne.n 800ac26 + LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("udp_send: No route to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", + ip4_addr1_16(dst_ip), ip4_addr2_16(dst_ip), ip4_addr3_16(dst_ip), ip4_addr4_16(dst_ip))); + UDP_STATS_INC(udp.rterr); + 800ac10: 4b0c ldr r3, [pc, #48] ; (800ac44 ) + 800ac12: 2286 movs r2, #134 ; 0x86 + 800ac14: 5a9b ldrh r3, [r3, r2] + 800ac16: 3301 adds r3, #1 + 800ac18: b299 uxth r1, r3 + 800ac1a: 4b0a ldr r3, [pc, #40] ; (800ac44 ) + 800ac1c: 2286 movs r2, #134 ; 0x86 + 800ac1e: 5299 strh r1, [r3, r2] + return ERR_RTE; + 800ac20: 2304 movs r3, #4 + 800ac22: 425b negs r3, r3 + 800ac24: e00a b.n 800ac3c + } +#if LWIP_CHECKSUM_ON_COPY + return udp_sendto_if_chksum(pcb, p, dst_ip, dst_port, netif, have_chksum, chksum); +#else /* LWIP_CHECKSUM_ON_COPY */ + return udp_sendto_if(pcb, p, dst_ip, dst_port, netif); + 800ac26: 1cbb adds r3, r7, #2 + 800ac28: 881c ldrh r4, [r3, #0] + 800ac2a: 687a ldr r2, [r7, #4] + 800ac2c: 68b9 ldr r1, [r7, #8] + 800ac2e: 68f8 ldr r0, [r7, #12] + 800ac30: 697b ldr r3, [r7, #20] + 800ac32: 9300 str r3, [sp, #0] + 800ac34: 0023 movs r3, r4 + 800ac36: f000 f807 bl 800ac48 + 800ac3a: 0003 movs r3, r0 +#endif /* LWIP_CHECKSUM_ON_COPY */ +} + 800ac3c: 0018 movs r0, r3 + 800ac3e: 46bd mov sp, r7 + 800ac40: b007 add sp, #28 + 800ac42: bd90 pop {r4, r7, pc} + 800ac44: 20003158 .word 0x20003158 + +0800ac48 : + * @see udp_disconnect() udp_send() + */ +err_t +udp_sendto_if(struct udp_pcb *pcb, struct pbuf *p, + ip_addr_t *dst_ip, u16_t dst_port, struct netif *netif) +{ + 800ac48: b5f0 push {r4, r5, r6, r7, lr} + 800ac4a: b08d sub sp, #52 ; 0x34 + 800ac4c: af04 add r7, sp, #16 + 800ac4e: 60f8 str r0, [r7, #12] + 800ac50: 60b9 str r1, [r7, #8] + 800ac52: 607a str r2, [r7, #4] + 800ac54: 001a movs r2, r3 + 800ac56: 1cbb adds r3, r7, #2 + 800ac58: 801a strh r2, [r3, #0] + return ERR_VAL; + } +#endif /* IP_SOF_BROADCAST */ + + /* if the PCB is not yet bound to a port, bind it here */ + if (pcb->local_port == 0) { + 800ac5a: 68fb ldr r3, [r7, #12] + 800ac5c: 8a5b ldrh r3, [r3, #18] + 800ac5e: 2b00 cmp r3, #0 + 800ac60: d114 bne.n 800ac8c + LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, ("udp_send: not yet bound to a port, binding now\n")); + err = udp_bind(pcb, &pcb->local_ip, pcb->local_port); + 800ac62: 68f9 ldr r1, [r7, #12] + 800ac64: 68fb ldr r3, [r7, #12] + 800ac66: 8a5a ldrh r2, [r3, #18] + 800ac68: 2515 movs r5, #21 + 800ac6a: 197c adds r4, r7, r5 + 800ac6c: 68fb ldr r3, [r7, #12] + 800ac6e: 0018 movs r0, r3 + 800ac70: f000 f90a bl 800ae88 + 800ac74: 0003 movs r3, r0 + 800ac76: 7023 strb r3, [r4, #0] + if (err != ERR_OK) { + 800ac78: 197b adds r3, r7, r5 + 800ac7a: 781b ldrb r3, [r3, #0] + 800ac7c: b25b sxtb r3, r3 + 800ac7e: 2b00 cmp r3, #0 + 800ac80: d004 beq.n 800ac8c + LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("udp_send: forced port bind failed\n")); + return err; + 800ac82: 2315 movs r3, #21 + 800ac84: 18fb adds r3, r7, r3 + 800ac86: 781b ldrb r3, [r3, #0] + 800ac88: b25b sxtb r3, r3 + 800ac8a: e0f6 b.n 800ae7a + } + } + + /* not enough space to add an UDP header to first pbuf in given p chain? */ + if (pbuf_header(p, UDP_HLEN)) { + 800ac8c: 68bb ldr r3, [r7, #8] + 800ac8e: 2108 movs r1, #8 + 800ac90: 0018 movs r0, r3 + 800ac92: f7fa fc80 bl 8005596 + 800ac96: 1e03 subs r3, r0, #0 + 800ac98: d017 beq.n 800acca + /* allocate header in a separate new pbuf */ + q = pbuf_alloc(PBUF_IP, UDP_HLEN, PBUF_RAM); + 800ac9a: 2200 movs r2, #0 + 800ac9c: 2108 movs r1, #8 + 800ac9e: 2001 movs r0, #1 + 800aca0: f7fa fa74 bl 800518c + 800aca4: 0003 movs r3, r0 + 800aca6: 61bb str r3, [r7, #24] + /* new header pbuf could not be allocated? */ + if (q == NULL) { + 800aca8: 69bb ldr r3, [r7, #24] + 800acaa: 2b00 cmp r3, #0 + 800acac: d102 bne.n 800acb4 + LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("udp_send: could not allocate header\n")); + return ERR_MEM; + 800acae: 2301 movs r3, #1 + 800acb0: 425b negs r3, r3 + 800acb2: e0e2 b.n 800ae7a + } + if (p->tot_len != 0) { + 800acb4: 68bb ldr r3, [r7, #8] + 800acb6: 891b ldrh r3, [r3, #8] + 800acb8: 2b00 cmp r3, #0 + 800acba: d008 beq.n 800acce + /* chain header q in front of given pbuf p (only if p contains data) */ + pbuf_chain(q, p); + 800acbc: 68ba ldr r2, [r7, #8] + 800acbe: 69bb ldr r3, [r7, #24] + 800acc0: 0011 movs r1, r2 + 800acc2: 0018 movs r0, r3 + 800acc4: f7fa fdba bl 800583c + 800acc8: e001 b.n 800acce + LWIP_DEBUGF(UDP_DEBUG, + ("udp_send: added header pbuf %p before given pbuf %p\n", (void *)q, (void *)p)); + } else { + /* adding space for header within p succeeded */ + /* first pbuf q equals given pbuf */ + q = p; + 800acca: 68bb ldr r3, [r7, #8] + 800accc: 61bb str r3, [r7, #24] + LWIP_DEBUGF(UDP_DEBUG, ("udp_send: added header in given pbuf %p\n", (void *)p)); + } + LWIP_ASSERT("check that first pbuf can hold struct udp_hdr", + (q->len >= sizeof(struct udp_hdr))); + /* q now represents the packet to be sent */ + udphdr = (struct udp_hdr *)q->payload; + 800acce: 69bb ldr r3, [r7, #24] + 800acd0: 685b ldr r3, [r3, #4] + 800acd2: 613b str r3, [r7, #16] + udphdr->src = htons(pcb->local_port); + 800acd4: 68fb ldr r3, [r7, #12] + 800acd6: 8a5b ldrh r3, [r3, #18] + 800acd8: 0018 movs r0, r3 + 800acda: f7f9 fc9b bl 8004614 + 800acde: 0003 movs r3, r0 + 800ace0: 001a movs r2, r3 + 800ace2: 693b ldr r3, [r7, #16] + 800ace4: 21ff movs r1, #255 ; 0xff + 800ace6: 4011 ands r1, r2 + 800ace8: 000c movs r4, r1 + 800acea: 7819 ldrb r1, [r3, #0] + 800acec: 2000 movs r0, #0 + 800acee: 4001 ands r1, r0 + 800acf0: 1c08 adds r0, r1, #0 + 800acf2: 1c21 adds r1, r4, #0 + 800acf4: 4301 orrs r1, r0 + 800acf6: 7019 strb r1, [r3, #0] + 800acf8: 0a12 lsrs r2, r2, #8 + 800acfa: b290 uxth r0, r2 + 800acfc: 785a ldrb r2, [r3, #1] + 800acfe: 2100 movs r1, #0 + 800ad00: 400a ands r2, r1 + 800ad02: 1c11 adds r1, r2, #0 + 800ad04: 1c02 adds r2, r0, #0 + 800ad06: 430a orrs r2, r1 + 800ad08: 705a strb r2, [r3, #1] + udphdr->dest = htons(dst_port); + 800ad0a: 1cbb adds r3, r7, #2 + 800ad0c: 881b ldrh r3, [r3, #0] + 800ad0e: 0018 movs r0, r3 + 800ad10: f7f9 fc80 bl 8004614 + 800ad14: 0003 movs r3, r0 + 800ad16: 001a movs r2, r3 + 800ad18: 693b ldr r3, [r7, #16] + 800ad1a: 21ff movs r1, #255 ; 0xff + 800ad1c: 4011 ands r1, r2 + 800ad1e: 000c movs r4, r1 + 800ad20: 7899 ldrb r1, [r3, #2] + 800ad22: 2000 movs r0, #0 + 800ad24: 4001 ands r1, r0 + 800ad26: 1c08 adds r0, r1, #0 + 800ad28: 1c21 adds r1, r4, #0 + 800ad2a: 4301 orrs r1, r0 + 800ad2c: 7099 strb r1, [r3, #2] + 800ad2e: 0a12 lsrs r2, r2, #8 + 800ad30: b290 uxth r0, r2 + 800ad32: 78da ldrb r2, [r3, #3] + 800ad34: 2100 movs r1, #0 + 800ad36: 400a ands r2, r1 + 800ad38: 1c11 adds r1, r2, #0 + 800ad3a: 1c02 adds r2, r0, #0 + 800ad3c: 430a orrs r2, r1 + 800ad3e: 70da strb r2, [r3, #3] + /* in UDP, 0 checksum means 'no checksum' */ + udphdr->chksum = 0x0000; + 800ad40: 693b ldr r3, [r7, #16] + 800ad42: 799a ldrb r2, [r3, #6] + 800ad44: 2100 movs r1, #0 + 800ad46: 400a ands r2, r1 + 800ad48: 719a strb r2, [r3, #6] + 800ad4a: 79da ldrb r2, [r3, #7] + 800ad4c: 2100 movs r1, #0 + 800ad4e: 400a ands r2, r1 + 800ad50: 71da strb r2, [r3, #7] + } +#endif /* LWIP_IGMP */ + + + /* PCB local address is IP_ANY_ADDR? */ + if (ip_addr_isany(&pcb->local_ip)) { + 800ad52: 68fb ldr r3, [r7, #12] + 800ad54: 2b00 cmp r3, #0 + 800ad56: d003 beq.n 800ad60 + 800ad58: 68fb ldr r3, [r7, #12] + 800ad5a: 681b ldr r3, [r3, #0] + 800ad5c: 2b00 cmp r3, #0 + 800ad5e: d103 bne.n 800ad68 + /* use outgoing network interface IP address as source address */ + src_ip = &(netif->ip_addr); + 800ad60: 6bbb ldr r3, [r7, #56] ; 0x38 + 800ad62: 3304 adds r3, #4 + 800ad64: 61fb str r3, [r7, #28] + 800ad66: e014 b.n 800ad92 + } else { + /* check if UDP PCB local IP address is correct + * this could be an old address if netif->ip_addr has changed */ + if (!ip_addr_cmp(&(pcb->local_ip), &(netif->ip_addr))) { + 800ad68: 68fb ldr r3, [r7, #12] + 800ad6a: 681a ldr r2, [r3, #0] + 800ad6c: 6bbb ldr r3, [r7, #56] ; 0x38 + 800ad6e: 685b ldr r3, [r3, #4] + 800ad70: 429a cmp r2, r3 + 800ad72: d00c beq.n 800ad8e + /* local_ip doesn't match, drop the packet */ + if (q != p) { + 800ad74: 69ba ldr r2, [r7, #24] + 800ad76: 68bb ldr r3, [r7, #8] + 800ad78: 429a cmp r2, r3 + 800ad7a: d005 beq.n 800ad88 + /* free the header pbuf */ + pbuf_free(q); + 800ad7c: 69bb ldr r3, [r7, #24] + 800ad7e: 0018 movs r0, r3 + 800ad80: f7fa fc90 bl 80056a4 + q = NULL; + 800ad84: 2300 movs r3, #0 + 800ad86: 61bb str r3, [r7, #24] + /* p is still referenced by the caller, and will live on */ + } + return ERR_VAL; + 800ad88: 2306 movs r3, #6 + 800ad8a: 425b negs r3, r3 + 800ad8c: e075 b.n 800ae7a + } + /* use UDP PCB local IP address as source address */ + src_ip = &(pcb->local_ip); + 800ad8e: 68fb ldr r3, [r7, #12] + 800ad90: 61fb str r3, [r7, #28] + NETIF_SET_HWADDRHINT(netif, NULL); + } else +#endif /* LWIP_UDPLITE */ + { /* UDP */ + LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP packet length %"U16_F"\n", q->tot_len)); + udphdr->len = htons(q->tot_len); + 800ad92: 69bb ldr r3, [r7, #24] + 800ad94: 891b ldrh r3, [r3, #8] + 800ad96: 0018 movs r0, r3 + 800ad98: f7f9 fc3c bl 8004614 + 800ad9c: 0003 movs r3, r0 + 800ad9e: 001a movs r2, r3 + 800ada0: 693b ldr r3, [r7, #16] + 800ada2: 21ff movs r1, #255 ; 0xff + 800ada4: 4011 ands r1, r2 + 800ada6: 000c movs r4, r1 + 800ada8: 7919 ldrb r1, [r3, #4] + 800adaa: 2000 movs r0, #0 + 800adac: 4001 ands r1, r0 + 800adae: 1c08 adds r0, r1, #0 + 800adb0: 1c21 adds r1, r4, #0 + 800adb2: 4301 orrs r1, r0 + 800adb4: 7119 strb r1, [r3, #4] + 800adb6: 0a12 lsrs r2, r2, #8 + 800adb8: b290 uxth r0, r2 + 800adba: 795a ldrb r2, [r3, #5] + 800adbc: 2100 movs r1, #0 + 800adbe: 400a ands r2, r1 + 800adc0: 1c11 adds r1, r2, #0 + 800adc2: 1c02 adds r2, r0, #0 + 800adc4: 430a orrs r2, r1 + 800adc6: 715a strb r2, [r3, #5] + /* calculate checksum */ +#if CHECKSUM_GEN_UDP + if ((pcb->flags & UDP_FLAGS_NOCHKSUM) == 0) { + 800adc8: 68fb ldr r3, [r7, #12] + 800adca: 7c1b ldrb r3, [r3, #16] + 800adcc: 001a movs r2, r3 + 800adce: 2301 movs r3, #1 + 800add0: 4013 ands r3, r2 + 800add2: d128 bne.n 800ae26 + acc = udpchksum + (u16_t)~(chksum); + udpchksum = FOLD_U32T(acc); + } else +#endif /* LWIP_CHECKSUM_ON_COPY */ + { + udpchksum = inet_chksum_pseudo(q, src_ip, dst_ip, IP_PROTO_UDP, q->tot_len); + 800add4: 69bb ldr r3, [r7, #24] + 800add6: 891b ldrh r3, [r3, #8] + 800add8: 2516 movs r5, #22 + 800adda: 197c adds r4, r7, r5 + 800addc: 687a ldr r2, [r7, #4] + 800adde: 69f9 ldr r1, [r7, #28] + 800ade0: 69b8 ldr r0, [r7, #24] + 800ade2: 9300 str r3, [sp, #0] + 800ade4: 2311 movs r3, #17 + 800ade6: f000 fc28 bl 800b63a + 800adea: 0003 movs r3, r0 + 800adec: 8023 strh r3, [r4, #0] + } + + /* chksum zero must become 0xffff, as zero means 'no checksum' */ + if (udpchksum == 0x0000) { + 800adee: 197b adds r3, r7, r5 + 800adf0: 881b ldrh r3, [r3, #0] + 800adf2: 2b00 cmp r3, #0 + 800adf4: d104 bne.n 800ae00 + udpchksum = 0xffff; + 800adf6: 2316 movs r3, #22 + 800adf8: 18fb adds r3, r7, r3 + 800adfa: 2201 movs r2, #1 + 800adfc: 4252 negs r2, r2 + 800adfe: 801a strh r2, [r3, #0] + } + udphdr->chksum = udpchksum; + 800ae00: 693b ldr r3, [r7, #16] + 800ae02: 2216 movs r2, #22 + 800ae04: 18ba adds r2, r7, r2 + 800ae06: 7814 ldrb r4, [r2, #0] + 800ae08: 7999 ldrb r1, [r3, #6] + 800ae0a: 2000 movs r0, #0 + 800ae0c: 4001 ands r1, r0 + 800ae0e: 1c08 adds r0, r1, #0 + 800ae10: 1c21 adds r1, r4, #0 + 800ae12: 4301 orrs r1, r0 + 800ae14: 7199 strb r1, [r3, #6] + 800ae16: 7850 ldrb r0, [r2, #1] + 800ae18: 79da ldrb r2, [r3, #7] + 800ae1a: 2100 movs r1, #0 + 800ae1c: 400a ands r2, r1 + 800ae1e: 1c11 adds r1, r2, #0 + 800ae20: 1c02 adds r2, r0, #0 + 800ae22: 430a orrs r2, r1 + 800ae24: 71da strb r2, [r3, #7] +#endif /* CHECKSUM_GEN_UDP */ + LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP checksum 0x%04"X16_F"\n", udphdr->chksum)); + LWIP_DEBUGF(UDP_DEBUG, ("udp_send: ip_output_if (,,,,IP_PROTO_UDP,)\n")); + /* output to IP */ + NETIF_SET_HWADDRHINT(netif, &pcb->addr_hint); + err = ip_output_if(q, src_ip, dst_ip, pcb->ttl, pcb->tos, IP_PROTO_UDP, netif); + 800ae26: 68fb ldr r3, [r7, #12] + 800ae28: 7a9e ldrb r6, [r3, #10] + 800ae2a: 68fb ldr r3, [r7, #12] + 800ae2c: 7a5b ldrb r3, [r3, #9] + 800ae2e: 2215 movs r2, #21 + 800ae30: 18bc adds r4, r7, r2 + 800ae32: 687d ldr r5, [r7, #4] + 800ae34: 69f9 ldr r1, [r7, #28] + 800ae36: 69b8 ldr r0, [r7, #24] + 800ae38: 6bba ldr r2, [r7, #56] ; 0x38 + 800ae3a: 9202 str r2, [sp, #8] + 800ae3c: 2211 movs r2, #17 + 800ae3e: 9201 str r2, [sp, #4] + 800ae40: 9300 str r3, [sp, #0] + 800ae42: 0033 movs r3, r6 + 800ae44: 002a movs r2, r5 + 800ae46: f000 ff0d bl 800bc64 + 800ae4a: 0003 movs r3, r0 + 800ae4c: 7023 strb r3, [r4, #0] + } + /* TODO: must this be increased even if error occured? */ + snmp_inc_udpoutdatagrams(); + + /* did we chain a separate header pbuf earlier? */ + if (q != p) { + 800ae4e: 69ba ldr r2, [r7, #24] + 800ae50: 68bb ldr r3, [r7, #8] + 800ae52: 429a cmp r2, r3 + 800ae54: d005 beq.n 800ae62 + /* free the header pbuf */ + pbuf_free(q); + 800ae56: 69bb ldr r3, [r7, #24] + 800ae58: 0018 movs r0, r3 + 800ae5a: f7fa fc23 bl 80056a4 + q = NULL; + 800ae5e: 2300 movs r3, #0 + 800ae60: 61bb str r3, [r7, #24] + /* p is still referenced by the caller, and will live on */ + } + + UDP_STATS_INC(udp.xmit); + 800ae62: 4b08 ldr r3, [pc, #32] ; (800ae84 ) + 800ae64: 2278 movs r2, #120 ; 0x78 + 800ae66: 5a9b ldrh r3, [r3, r2] + 800ae68: 3301 adds r3, #1 + 800ae6a: b299 uxth r1, r3 + 800ae6c: 4b05 ldr r3, [pc, #20] ; (800ae84 ) + 800ae6e: 2278 movs r2, #120 ; 0x78 + 800ae70: 5299 strh r1, [r3, r2] + return err; + 800ae72: 2315 movs r3, #21 + 800ae74: 18fb adds r3, r7, r3 + 800ae76: 781b ldrb r3, [r3, #0] + 800ae78: b25b sxtb r3, r3 +} + 800ae7a: 0018 movs r0, r3 + 800ae7c: 46bd mov sp, r7 + 800ae7e: b009 add sp, #36 ; 0x24 + 800ae80: bdf0 pop {r4, r5, r6, r7, pc} + 800ae82: 46c0 nop ; (mov r8, r8) + 800ae84: 20003158 .word 0x20003158 + +0800ae88 : + * + * @see udp_disconnect() + */ +err_t +udp_bind(struct udp_pcb *pcb, ip_addr_t *ipaddr, u16_t port) +{ + 800ae88: b590 push {r4, r7, lr} + 800ae8a: b087 sub sp, #28 + 800ae8c: af00 add r7, sp, #0 + 800ae8e: 60f8 str r0, [r7, #12] + 800ae90: 60b9 str r1, [r7, #8] + 800ae92: 1dbb adds r3, r7, #6 + 800ae94: 801a strh r2, [r3, #0] + + LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, ("udp_bind(ipaddr = ")); + ip_addr_debug_print(UDP_DEBUG, ipaddr); + LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, (", port = %"U16_F")\n", port)); + + rebind = 0; + 800ae96: 2313 movs r3, #19 + 800ae98: 18fb adds r3, r7, r3 + 800ae9a: 2200 movs r2, #0 + 800ae9c: 701a strb r2, [r3, #0] + /* Check for double bind and rebind of the same pcb */ + for (ipcb = udp_pcbs; ipcb != NULL; ipcb = ipcb->next) { + 800ae9e: 4b2f ldr r3, [pc, #188] ; (800af5c ) + 800aea0: 681b ldr r3, [r3, #0] + 800aea2: 617b str r3, [r7, #20] + 800aea4: e028 b.n 800aef8 + /* is this UDP PCB already on active list? */ + if (pcb == ipcb) { + 800aea6: 68fa ldr r2, [r7, #12] + 800aea8: 697b ldr r3, [r7, #20] + 800aeaa: 429a cmp r2, r3 + 800aeac: d104 bne.n 800aeb8 + /* pcb may occur at most once in active list */ + LWIP_ASSERT("rebind == 0", rebind == 0); + /* pcb already in list, just rebind */ + rebind = 1; + 800aeae: 2313 movs r3, #19 + 800aeb0: 18fb adds r3, r7, r3 + 800aeb2: 2201 movs r2, #1 + 800aeb4: 701a strb r2, [r3, #0] + 800aeb6: e01c b.n 800aef2 + !ip_get_option(ipcb, SOF_REUSEADDR)) { +#else /* SO_REUSE */ + /* port matches that of PCB in list and REUSEADDR not set -> reject */ + else { +#endif /* SO_REUSE */ + if ((ipcb->local_port == port) && + 800aeb8: 697b ldr r3, [r7, #20] + 800aeba: 8a5b ldrh r3, [r3, #18] + 800aebc: 1dba adds r2, r7, #6 + 800aebe: 8812 ldrh r2, [r2, #0] + 800aec0: 429a cmp r2, r3 + 800aec2: d116 bne.n 800aef2 + /* IP address matches, or one is IP_ADDR_ANY? */ + (ip_addr_isany(&(ipcb->local_ip)) || + 800aec4: 697b ldr r3, [r7, #20] + if ((ipcb->local_port == port) && + 800aec6: 2b00 cmp r3, #0 + 800aec8: d010 beq.n 800aeec + (ip_addr_isany(&(ipcb->local_ip)) || + 800aeca: 697b ldr r3, [r7, #20] + 800aecc: 681b ldr r3, [r3, #0] + 800aece: 2b00 cmp r3, #0 + 800aed0: d00c beq.n 800aeec + 800aed2: 68bb ldr r3, [r7, #8] + 800aed4: 2b00 cmp r3, #0 + 800aed6: d009 beq.n 800aeec + ip_addr_isany(ipaddr) || + 800aed8: 68bb ldr r3, [r7, #8] + 800aeda: 681b ldr r3, [r3, #0] + 800aedc: 2b00 cmp r3, #0 + 800aede: d005 beq.n 800aeec + ip_addr_cmp(&(ipcb->local_ip), ipaddr))) { + 800aee0: 697b ldr r3, [r7, #20] + 800aee2: 681a ldr r2, [r3, #0] + 800aee4: 68bb ldr r3, [r7, #8] + 800aee6: 681b ldr r3, [r3, #0] + ip_addr_isany(ipaddr) || + 800aee8: 429a cmp r2, r3 + 800aeea: d102 bne.n 800aef2 + /* other PCB already binds to this local IP and port */ + LWIP_DEBUGF(UDP_DEBUG, + ("udp_bind: local port %"U16_F" already bound by another pcb\n", port)); + return ERR_USE; + 800aeec: 2308 movs r3, #8 + 800aeee: 425b negs r3, r3 + 800aef0: e02f b.n 800af52 + for (ipcb = udp_pcbs; ipcb != NULL; ipcb = ipcb->next) { + 800aef2: 697b ldr r3, [r7, #20] + 800aef4: 68db ldr r3, [r3, #12] + 800aef6: 617b str r3, [r7, #20] + 800aef8: 697b ldr r3, [r7, #20] + 800aefa: 2b00 cmp r3, #0 + 800aefc: d1d3 bne.n 800aea6 + } + } + } + + ip_addr_set(&pcb->local_ip, ipaddr); + 800aefe: 68bb ldr r3, [r7, #8] + 800af00: 2b00 cmp r3, #0 + 800af02: d002 beq.n 800af0a + 800af04: 68bb ldr r3, [r7, #8] + 800af06: 681a ldr r2, [r3, #0] + 800af08: e000 b.n 800af0c + 800af0a: 2200 movs r2, #0 + 800af0c: 68fb ldr r3, [r7, #12] + 800af0e: 601a str r2, [r3, #0] + + /* no port specified? */ + if (port == 0) { + 800af10: 1dbb adds r3, r7, #6 + 800af12: 881b ldrh r3, [r3, #0] + 800af14: 2b00 cmp r3, #0 + 800af16: d10b bne.n 800af30 + port = udp_new_port(); + 800af18: 1dbc adds r4, r7, #6 + 800af1a: f7ff fc8b bl 800a834 + 800af1e: 0003 movs r3, r0 + 800af20: 8023 strh r3, [r4, #0] + if (port == 0) { + 800af22: 1dbb adds r3, r7, #6 + 800af24: 881b ldrh r3, [r3, #0] + 800af26: 2b00 cmp r3, #0 + 800af28: d102 bne.n 800af30 + /* no more ports available in local range */ + LWIP_DEBUGF(UDP_DEBUG, ("udp_bind: out of free UDP ports\n")); + return ERR_USE; + 800af2a: 2308 movs r3, #8 + 800af2c: 425b negs r3, r3 + 800af2e: e010 b.n 800af52 + } + } + pcb->local_port = port; + 800af30: 68fb ldr r3, [r7, #12] + 800af32: 1dba adds r2, r7, #6 + 800af34: 8812 ldrh r2, [r2, #0] + 800af36: 825a strh r2, [r3, #18] + snmp_insert_udpidx_tree(pcb); + /* pcb not active yet? */ + if (rebind == 0) { + 800af38: 2313 movs r3, #19 + 800af3a: 18fb adds r3, r7, r3 + 800af3c: 781b ldrb r3, [r3, #0] + 800af3e: 2b00 cmp r3, #0 + 800af40: d106 bne.n 800af50 + /* place the PCB on the active list if not already there */ + pcb->next = udp_pcbs; + 800af42: 4b06 ldr r3, [pc, #24] ; (800af5c ) + 800af44: 681a ldr r2, [r3, #0] + 800af46: 68fb ldr r3, [r7, #12] + 800af48: 60da str r2, [r3, #12] + udp_pcbs = pcb; + 800af4a: 4b04 ldr r3, [pc, #16] ; (800af5c ) + 800af4c: 68fa ldr r2, [r7, #12] + 800af4e: 601a str r2, [r3, #0] + LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, + ("udp_bind: bound to %"U16_F".%"U16_F".%"U16_F".%"U16_F", port %"U16_F"\n", + ip4_addr1_16(&pcb->local_ip), ip4_addr2_16(&pcb->local_ip), + ip4_addr3_16(&pcb->local_ip), ip4_addr4_16(&pcb->local_ip), + pcb->local_port)); + return ERR_OK; + 800af50: 2300 movs r3, #0 +} + 800af52: 0018 movs r0, r3 + 800af54: 46bd mov sp, r7 + 800af56: b007 add sp, #28 + 800af58: bd90 pop {r4, r7, pc} + 800af5a: 46c0 nop ; (mov r8, r8) + 800af5c: 20003290 .word 0x20003290 + +0800af60 : + * @param recv function pointer of the callback function + * @param recv_arg additional argument to pass to the callback function + */ +void +udp_recv(struct udp_pcb *pcb, udp_recv_fn recv, void *recv_arg) +{ + 800af60: b580 push {r7, lr} + 800af62: b084 sub sp, #16 + 800af64: af00 add r7, sp, #0 + 800af66: 60f8 str r0, [r7, #12] + 800af68: 60b9 str r1, [r7, #8] + 800af6a: 607a str r2, [r7, #4] + /* remember recv() callback and user data */ + pcb->recv = recv; + 800af6c: 68fb ldr r3, [r7, #12] + 800af6e: 68ba ldr r2, [r7, #8] + 800af70: 619a str r2, [r3, #24] + pcb->recv_arg = recv_arg; + 800af72: 68fb ldr r3, [r7, #12] + 800af74: 687a ldr r2, [r7, #4] + 800af76: 61da str r2, [r3, #28] +} + 800af78: 46c0 nop ; (mov r8, r8) + 800af7a: 46bd mov sp, r7 + 800af7c: b004 add sp, #16 + 800af7e: bd80 pop {r7, pc} + +0800af80 : + * + * @see udp_new() + */ +void +udp_remove(struct udp_pcb *pcb) +{ + 800af80: b580 push {r7, lr} + 800af82: b084 sub sp, #16 + 800af84: af00 add r7, sp, #0 + 800af86: 6078 str r0, [r7, #4] + struct udp_pcb *pcb2; + + snmp_delete_udpidx_tree(pcb); + /* pcb to be removed is first in list? */ + if (udp_pcbs == pcb) { + 800af88: 4b15 ldr r3, [pc, #84] ; (800afe0 ) + 800af8a: 681b ldr r3, [r3, #0] + 800af8c: 687a ldr r2, [r7, #4] + 800af8e: 429a cmp r2, r3 + 800af90: d105 bne.n 800af9e + /* make list start at 2nd pcb */ + udp_pcbs = udp_pcbs->next; + 800af92: 4b13 ldr r3, [pc, #76] ; (800afe0 ) + 800af94: 681b ldr r3, [r3, #0] + 800af96: 68da ldr r2, [r3, #12] + 800af98: 4b11 ldr r3, [pc, #68] ; (800afe0 ) + 800af9a: 601a str r2, [r3, #0] + 800af9c: e016 b.n 800afcc + /* pcb not 1st in list */ + } else { + for (pcb2 = udp_pcbs; pcb2 != NULL; pcb2 = pcb2->next) { + 800af9e: 4b10 ldr r3, [pc, #64] ; (800afe0 ) + 800afa0: 681b ldr r3, [r3, #0] + 800afa2: 60fb str r3, [r7, #12] + 800afa4: e00f b.n 800afc6 + /* find pcb in udp_pcbs list */ + if (pcb2->next != NULL && pcb2->next == pcb) { + 800afa6: 68fb ldr r3, [r7, #12] + 800afa8: 68db ldr r3, [r3, #12] + 800afaa: 2b00 cmp r3, #0 + 800afac: d008 beq.n 800afc0 + 800afae: 68fb ldr r3, [r7, #12] + 800afb0: 68db ldr r3, [r3, #12] + 800afb2: 687a ldr r2, [r7, #4] + 800afb4: 429a cmp r2, r3 + 800afb6: d103 bne.n 800afc0 + /* remove pcb from list */ + pcb2->next = pcb->next; + 800afb8: 687b ldr r3, [r7, #4] + 800afba: 68da ldr r2, [r3, #12] + 800afbc: 68fb ldr r3, [r7, #12] + 800afbe: 60da str r2, [r3, #12] + for (pcb2 = udp_pcbs; pcb2 != NULL; pcb2 = pcb2->next) { + 800afc0: 68fb ldr r3, [r7, #12] + 800afc2: 68db ldr r3, [r3, #12] + 800afc4: 60fb str r3, [r7, #12] + 800afc6: 68fb ldr r3, [r7, #12] + 800afc8: 2b00 cmp r3, #0 + 800afca: d1ec bne.n 800afa6 + } + } + } + memp_free(MEMP_UDP_PCB, pcb); + 800afcc: 687b ldr r3, [r7, #4] + 800afce: 0019 movs r1, r3 + 800afd0: 2001 movs r0, #1 + 800afd2: f7f9 ffa5 bl 8004f20 +} + 800afd6: 46c0 nop ; (mov r8, r8) + 800afd8: 46bd mov sp, r7 + 800afda: b004 add sp, #16 + 800afdc: bd80 pop {r7, pc} + 800afde: 46c0 nop ; (mov r8, r8) + 800afe0: 20003290 .word 0x20003290 + +0800afe4 : + * + * @see udp_remove() + */ +struct udp_pcb * +udp_new(void) +{ + 800afe4: b580 push {r7, lr} + 800afe6: b082 sub sp, #8 + 800afe8: af00 add r7, sp, #0 + struct udp_pcb *pcb; + pcb = (struct udp_pcb *)memp_malloc(MEMP_UDP_PCB); + 800afea: 2001 movs r0, #1 + 800afec: f7f9 ff12 bl 8004e14 + 800aff0: 0003 movs r3, r0 + 800aff2: 607b str r3, [r7, #4] + /* could allocate UDP PCB? */ + if (pcb != NULL) { + 800aff4: 687b ldr r3, [r7, #4] + 800aff6: 2b00 cmp r3, #0 + 800aff8: d008 beq.n 800b00c + /* UDP Lite: by initializing to all zeroes, chksum_len is set to 0 + * which means checksum is generated over the whole datagram per default + * (recommended as default by RFC 3828). */ + /* initialize PCB to all zeroes */ + memset(pcb, 0, sizeof(struct udp_pcb)); + 800affa: 687b ldr r3, [r7, #4] + 800affc: 2220 movs r2, #32 + 800affe: 2100 movs r1, #0 + 800b000: 0018 movs r0, r3 + 800b002: f004 fe57 bl 800fcb4 + pcb->ttl = UDP_TTL; + 800b006: 687b ldr r3, [r7, #4] + 800b008: 22ff movs r2, #255 ; 0xff + 800b00a: 729a strb r2, [r3, #10] + } + return pcb; + 800b00c: 687b ldr r3, [r7, #4] +} + 800b00e: 0018 movs r0, r3 + 800b010: 46bd mov sp, r7 + 800b012: b002 add sp, #8 + 800b014: bd80 pop {r7, pc} + ... + +0800b018 : + * @param p the icmp echo request packet, p->payload pointing to the ip header + * @param inp the netif on which this packet was received + */ +void +icmp_input(struct pbuf *p, struct netif *inp) +{ + 800b018: b590 push {r4, r7, lr} + 800b01a: b08d sub sp, #52 ; 0x34 + 800b01c: af04 add r7, sp, #16 + 800b01e: 6078 str r0, [r7, #4] + 800b020: 6039 str r1, [r7, #0] +#endif /* LWIP_DEBUG */ + struct icmp_echo_hdr *iecho; + struct ip_hdr *iphdr; + s16_t hlen; + + ICMP_STATS_INC(icmp.recv); + 800b022: 4be1 ldr r3, [pc, #900] ; (800b3a8 ) + 800b024: 2262 movs r2, #98 ; 0x62 + 800b026: 5a9b ldrh r3, [r3, r2] + 800b028: 3301 adds r3, #1 + 800b02a: b299 uxth r1, r3 + 800b02c: 4bde ldr r3, [pc, #888] ; (800b3a8 ) + 800b02e: 2262 movs r2, #98 ; 0x62 + 800b030: 5299 strh r1, [r3, r2] + snmp_inc_icmpinmsgs(); + + + iphdr = (struct ip_hdr *)p->payload; + 800b032: 687b ldr r3, [r7, #4] + 800b034: 685b ldr r3, [r3, #4] + 800b036: 61fb str r3, [r7, #28] + hlen = IPH_HL(iphdr) * 4; + 800b038: 69fb ldr r3, [r7, #28] + 800b03a: 781b ldrb r3, [r3, #0] + 800b03c: b29b uxth r3, r3 + 800b03e: 220f movs r2, #15 + 800b040: 4013 ands r3, r2 + 800b042: b29b uxth r3, r3 + 800b044: 009b lsls r3, r3, #2 + 800b046: b29a uxth r2, r3 + 800b048: 2116 movs r1, #22 + 800b04a: 187b adds r3, r7, r1 + 800b04c: 801a strh r2, [r3, #0] + if (pbuf_header(p, -hlen) || (p->tot_len < sizeof(u16_t)*2)) { + 800b04e: 187b adds r3, r7, r1 + 800b050: 881b ldrh r3, [r3, #0] + 800b052: 425b negs r3, r3 + 800b054: b29b uxth r3, r3 + 800b056: b21a sxth r2, r3 + 800b058: 687b ldr r3, [r7, #4] + 800b05a: 0011 movs r1, r2 + 800b05c: 0018 movs r0, r3 + 800b05e: f7fa fa9a bl 8005596 + 800b062: 1e03 subs r3, r0, #0 + 800b064: d000 beq.n 800b068 + 800b066: e19c b.n 800b3a2 + 800b068: 687b ldr r3, [r7, #4] + 800b06a: 891b ldrh r3, [r3, #8] + 800b06c: 2b03 cmp r3, #3 + 800b06e: d800 bhi.n 800b072 + 800b070: e197 b.n 800b3a2 + LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: short ICMP (%"U16_F" bytes) received\n", p->tot_len)); + goto lenerr; + } + + type = *((u8_t *)p->payload); + 800b072: 687b ldr r3, [r7, #4] + 800b074: 685a ldr r2, [r3, #4] + 800b076: 2115 movs r1, #21 + 800b078: 187b adds r3, r7, r1 + 800b07a: 7812 ldrb r2, [r2, #0] + 800b07c: 701a strb r2, [r3, #0] +#ifdef LWIP_DEBUG + code = *(((u8_t *)p->payload)+1); +#endif /* LWIP_DEBUG */ + switch (type) { + 800b07e: 187b adds r3, r7, r1 + 800b080: 781b ldrb r3, [r3, #0] + 800b082: 2b00 cmp r3, #0 + 800b084: d100 bne.n 800b088 + 800b086: e184 b.n 800b392 + 800b088: 2b08 cmp r3, #8 + 800b08a: d000 beq.n 800b08e + 800b08c: e170 b.n 800b370 + (as obviously, an echo request has been sent, too). */ + break; + case ICMP_ECHO: +#if !LWIP_MULTICAST_PING || !LWIP_BROADCAST_PING + { + int accepted = 1; + 800b08e: 2301 movs r3, #1 + 800b090: 61bb str r3, [r7, #24] +#if !LWIP_MULTICAST_PING + /* multicast destination address? */ + if (ip_addr_ismulticast(¤t_iphdr_dest)) { + 800b092: 4bc6 ldr r3, [pc, #792] ; (800b3ac ) + 800b094: 681b ldr r3, [r3, #0] + 800b096: 22f0 movs r2, #240 ; 0xf0 + 800b098: 4013 ands r3, r2 + 800b09a: 2be0 cmp r3, #224 ; 0xe0 + 800b09c: d101 bne.n 800b0a2 + accepted = 0; + 800b09e: 2300 movs r3, #0 + 800b0a0: 61bb str r3, [r7, #24] + } +#endif /* LWIP_MULTICAST_PING */ +#if !LWIP_BROADCAST_PING + /* broadcast destination address? */ + if (ip_addr_isbroadcast(¤t_iphdr_dest, inp)) { + 800b0a2: 4bc2 ldr r3, [pc, #776] ; (800b3ac ) + 800b0a4: 681b ldr r3, [r3, #0] + 800b0a6: 683a ldr r2, [r7, #0] + 800b0a8: 0011 movs r1, r2 + 800b0aa: 0018 movs r0, r3 + 800b0ac: f000 ffe6 bl 800c07c + 800b0b0: 1e03 subs r3, r0, #0 + 800b0b2: d001 beq.n 800b0b8 + accepted = 0; + 800b0b4: 2300 movs r3, #0 + 800b0b6: 61bb str r3, [r7, #24] + } +#endif /* LWIP_BROADCAST_PING */ + /* broadcast or multicast destination address not acceptd? */ + if (!accepted) { + 800b0b8: 69bb ldr r3, [r7, #24] + 800b0ba: 2b00 cmp r3, #0 + 800b0bc: d10c bne.n 800b0d8 + LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: Not echoing to multicast or broadcast pings\n")); + ICMP_STATS_INC(icmp.err); + 800b0be: 4bba ldr r3, [pc, #744] ; (800b3a8 ) + 800b0c0: 2274 movs r2, #116 ; 0x74 + 800b0c2: 5a9b ldrh r3, [r3, r2] + 800b0c4: 3301 adds r3, #1 + 800b0c6: b299 uxth r1, r3 + 800b0c8: 4bb7 ldr r3, [pc, #732] ; (800b3a8 ) + 800b0ca: 2274 movs r2, #116 ; 0x74 + 800b0cc: 5299 strh r1, [r3, r2] + pbuf_free(p); + 800b0ce: 687b ldr r3, [r7, #4] + 800b0d0: 0018 movs r0, r3 + 800b0d2: f7fa fae7 bl 80056a4 + return; + 800b0d6: e193 b.n 800b400 + } + } +#endif /* !LWIP_MULTICAST_PING || !LWIP_BROADCAST_PING */ + LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: ping\n")); + if (p->tot_len < sizeof(struct icmp_echo_hdr)) { + 800b0d8: 687b ldr r3, [r7, #4] + 800b0da: 891b ldrh r3, [r3, #8] + 800b0dc: 2b07 cmp r3, #7 + 800b0de: d800 bhi.n 800b0e2 + 800b0e0: e16a b.n 800b3b8 + LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: bad ICMP echo received\n")); + goto lenerr; + } + if (inet_chksum_pbuf(p) != 0) { + 800b0e2: 687b ldr r3, [r7, #4] + 800b0e4: 0018 movs r0, r3 + 800b0e6: f000 fb58 bl 800b79a + 800b0ea: 1e03 subs r3, r0, #0 + 800b0ec: d00c beq.n 800b108 + LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: checksum failed for received ICMP echo\n")); + pbuf_free(p); + 800b0ee: 687b ldr r3, [r7, #4] + 800b0f0: 0018 movs r0, r3 + 800b0f2: f7fa fad7 bl 80056a4 + ICMP_STATS_INC(icmp.chkerr); + 800b0f6: 4bac ldr r3, [pc, #688] ; (800b3a8 ) + 800b0f8: 2268 movs r2, #104 ; 0x68 + 800b0fa: 5a9b ldrh r3, [r3, r2] + 800b0fc: 3301 adds r3, #1 + 800b0fe: b299 uxth r1, r3 + 800b100: 4ba9 ldr r3, [pc, #676] ; (800b3a8 ) + 800b102: 2268 movs r2, #104 ; 0x68 + 800b104: 5299 strh r1, [r3, r2] + snmp_inc_icmpinerrors(); + return; + 800b106: e17b b.n 800b400 + } +#if LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN + if (pbuf_header(p, (PBUF_IP_HLEN + PBUF_LINK_HLEN))) { + 800b108: 687b ldr r3, [r7, #4] + 800b10a: 2122 movs r1, #34 ; 0x22 + 800b10c: 0018 movs r0, r3 + 800b10e: f7fa fa42 bl 8005596 + 800b112: 1e03 subs r3, r0, #0 + 800b114: d039 beq.n 800b18a + /* p is not big enough to contain link headers + * allocate a new one and copy p into it + */ + struct pbuf *r; + /* switch p->payload to ip header */ + if (pbuf_header(p, hlen)) { + 800b116: 2316 movs r3, #22 + 800b118: 18fb adds r3, r7, r3 + 800b11a: 2200 movs r2, #0 + 800b11c: 5e9a ldrsh r2, [r3, r2] + 800b11e: 687b ldr r3, [r7, #4] + 800b120: 0011 movs r1, r2 + 800b122: 0018 movs r0, r3 + 800b124: f7fa fa37 bl 8005596 + 800b128: 1e03 subs r3, r0, #0 + 800b12a: d000 beq.n 800b12e + 800b12c: e152 b.n 800b3d4 + LWIP_ASSERT("icmp_input: moving p->payload to ip header failed\n", 0); + goto memerr; + } + /* allocate new packet buffer with space for link headers */ + r = pbuf_alloc(PBUF_LINK, p->tot_len, PBUF_RAM); + 800b12e: 687b ldr r3, [r7, #4] + 800b130: 891b ldrh r3, [r3, #8] + 800b132: 2200 movs r2, #0 + 800b134: 0019 movs r1, r3 + 800b136: 2002 movs r0, #2 + 800b138: f7fa f828 bl 800518c + 800b13c: 0003 movs r3, r0 + 800b13e: 613b str r3, [r7, #16] + if (r == NULL) { + 800b140: 693b ldr r3, [r7, #16] + 800b142: 2b00 cmp r3, #0 + 800b144: d100 bne.n 800b148 + 800b146: e147 b.n 800b3d8 + goto memerr; + } + LWIP_ASSERT("check that first pbuf can hold struct the ICMP header", + (r->len >= hlen + sizeof(struct icmp_echo_hdr))); + /* copy the whole packet including ip header */ + if (pbuf_copy(r, p) != ERR_OK) { + 800b148: 687a ldr r2, [r7, #4] + 800b14a: 693b ldr r3, [r7, #16] + 800b14c: 0011 movs r1, r2 + 800b14e: 0018 movs r0, r3 + 800b150: f7fa fb87 bl 8005862 + 800b154: 1e03 subs r3, r0, #0 + 800b156: d000 beq.n 800b15a + 800b158: e140 b.n 800b3dc + LWIP_ASSERT("icmp_input: copying to new pbuf failed\n", 0); + goto memerr; + } + iphdr = (struct ip_hdr *)r->payload; + 800b15a: 693b ldr r3, [r7, #16] + 800b15c: 685b ldr r3, [r3, #4] + 800b15e: 61fb str r3, [r7, #28] + /* switch r->payload back to icmp header */ + if (pbuf_header(r, -hlen)) { + 800b160: 2316 movs r3, #22 + 800b162: 18fb adds r3, r7, r3 + 800b164: 881b ldrh r3, [r3, #0] + 800b166: 425b negs r3, r3 + 800b168: b29b uxth r3, r3 + 800b16a: b21a sxth r2, r3 + 800b16c: 693b ldr r3, [r7, #16] + 800b16e: 0011 movs r1, r2 + 800b170: 0018 movs r0, r3 + 800b172: f7fa fa10 bl 8005596 + 800b176: 1e03 subs r3, r0, #0 + 800b178: d000 beq.n 800b17c + 800b17a: e131 b.n 800b3e0 + LWIP_ASSERT("icmp_input: restoring original p->payload failed\n", 0); + goto memerr; + } + /* free the original p */ + pbuf_free(p); + 800b17c: 687b ldr r3, [r7, #4] + 800b17e: 0018 movs r0, r3 + 800b180: f7fa fa90 bl 80056a4 + /* we now have an identical copy of p that has room for link headers */ + p = r; + 800b184: 693b ldr r3, [r7, #16] + 800b186: 607b str r3, [r7, #4] + 800b188: e009 b.n 800b19e + } else { + /* restore p->payload to point to icmp header */ + if (pbuf_header(p, -(s16_t)(PBUF_IP_HLEN + PBUF_LINK_HLEN))) { + 800b18a: 2322 movs r3, #34 ; 0x22 + 800b18c: 425a negs r2, r3 + 800b18e: 687b ldr r3, [r7, #4] + 800b190: 0011 movs r1, r2 + 800b192: 0018 movs r0, r3 + 800b194: f7fa f9ff bl 8005596 + 800b198: 1e03 subs r3, r0, #0 + 800b19a: d000 beq.n 800b19e + 800b19c: e122 b.n 800b3e4 + } +#endif /* LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN */ + /* At this point, all checks are OK. */ + /* We generate an answer by switching the dest and src ip addresses, + * setting the icmp type to ECHO_RESPONSE and updating the checksum. */ + iecho = (struct icmp_echo_hdr *)p->payload; + 800b19e: 687b ldr r3, [r7, #4] + 800b1a0: 685b ldr r3, [r3, #4] + 800b1a2: 60fb str r3, [r7, #12] + ip_addr_copy(iphdr->src, *ip_current_dest_addr()); + 800b1a4: 4b81 ldr r3, [pc, #516] ; (800b3ac ) + 800b1a6: 681a ldr r2, [r3, #0] + 800b1a8: 69fb ldr r3, [r7, #28] + 800b1aa: 21ff movs r1, #255 ; 0xff + 800b1ac: 4011 ands r1, r2 + 800b1ae: 000c movs r4, r1 + 800b1b0: 7b19 ldrb r1, [r3, #12] + 800b1b2: 2000 movs r0, #0 + 800b1b4: 4001 ands r1, r0 + 800b1b6: 1c08 adds r0, r1, #0 + 800b1b8: 1c21 adds r1, r4, #0 + 800b1ba: 4301 orrs r1, r0 + 800b1bc: 7319 strb r1, [r3, #12] + 800b1be: 0a11 lsrs r1, r2, #8 + 800b1c0: 20ff movs r0, #255 ; 0xff + 800b1c2: 4001 ands r1, r0 + 800b1c4: 000c movs r4, r1 + 800b1c6: 7b59 ldrb r1, [r3, #13] + 800b1c8: 2000 movs r0, #0 + 800b1ca: 4001 ands r1, r0 + 800b1cc: 1c08 adds r0, r1, #0 + 800b1ce: 1c21 adds r1, r4, #0 + 800b1d0: 4301 orrs r1, r0 + 800b1d2: 7359 strb r1, [r3, #13] + 800b1d4: 0c11 lsrs r1, r2, #16 + 800b1d6: 20ff movs r0, #255 ; 0xff + 800b1d8: 4001 ands r1, r0 + 800b1da: 000c movs r4, r1 + 800b1dc: 7b99 ldrb r1, [r3, #14] + 800b1de: 2000 movs r0, #0 + 800b1e0: 4001 ands r1, r0 + 800b1e2: 1c08 adds r0, r1, #0 + 800b1e4: 1c21 adds r1, r4, #0 + 800b1e6: 4301 orrs r1, r0 + 800b1e8: 7399 strb r1, [r3, #14] + 800b1ea: 0e10 lsrs r0, r2, #24 + 800b1ec: 7bda ldrb r2, [r3, #15] + 800b1ee: 2100 movs r1, #0 + 800b1f0: 400a ands r2, r1 + 800b1f2: 1c11 adds r1, r2, #0 + 800b1f4: 1c02 adds r2, r0, #0 + 800b1f6: 430a orrs r2, r1 + 800b1f8: 73da strb r2, [r3, #15] + ip_addr_copy(iphdr->dest, *ip_current_src_addr()); + 800b1fa: 4b6d ldr r3, [pc, #436] ; (800b3b0 ) + 800b1fc: 681a ldr r2, [r3, #0] + 800b1fe: 69fb ldr r3, [r7, #28] + 800b200: 21ff movs r1, #255 ; 0xff + 800b202: 4011 ands r1, r2 + 800b204: 000c movs r4, r1 + 800b206: 7c19 ldrb r1, [r3, #16] + 800b208: 2000 movs r0, #0 + 800b20a: 4001 ands r1, r0 + 800b20c: 1c08 adds r0, r1, #0 + 800b20e: 1c21 adds r1, r4, #0 + 800b210: 4301 orrs r1, r0 + 800b212: 7419 strb r1, [r3, #16] + 800b214: 0a11 lsrs r1, r2, #8 + 800b216: 20ff movs r0, #255 ; 0xff + 800b218: 4001 ands r1, r0 + 800b21a: 000c movs r4, r1 + 800b21c: 7c59 ldrb r1, [r3, #17] + 800b21e: 2000 movs r0, #0 + 800b220: 4001 ands r1, r0 + 800b222: 1c08 adds r0, r1, #0 + 800b224: 1c21 adds r1, r4, #0 + 800b226: 4301 orrs r1, r0 + 800b228: 7459 strb r1, [r3, #17] + 800b22a: 0c11 lsrs r1, r2, #16 + 800b22c: 20ff movs r0, #255 ; 0xff + 800b22e: 4001 ands r1, r0 + 800b230: 000c movs r4, r1 + 800b232: 7c99 ldrb r1, [r3, #18] + 800b234: 2000 movs r0, #0 + 800b236: 4001 ands r1, r0 + 800b238: 1c08 adds r0, r1, #0 + 800b23a: 1c21 adds r1, r4, #0 + 800b23c: 4301 orrs r1, r0 + 800b23e: 7499 strb r1, [r3, #18] + 800b240: 0e10 lsrs r0, r2, #24 + 800b242: 7cda ldrb r2, [r3, #19] + 800b244: 2100 movs r1, #0 + 800b246: 400a ands r2, r1 + 800b248: 1c11 adds r1, r2, #0 + 800b24a: 1c02 adds r2, r0, #0 + 800b24c: 430a orrs r2, r1 + 800b24e: 74da strb r2, [r3, #19] + ICMPH_TYPE_SET(iecho, ICMP_ER); + 800b250: 68fb ldr r3, [r7, #12] + 800b252: 2200 movs r2, #0 + 800b254: 701a strb r2, [r3, #0] +#if CHECKSUM_GEN_ICMP + /* adjust the checksum */ + if (iecho->chksum >= PP_HTONS(0xffffU - (ICMP_ECHO << 8))) { + 800b256: 68fb ldr r3, [r7, #12] + 800b258: 789a ldrb r2, [r3, #2] + 800b25a: 78db ldrb r3, [r3, #3] + 800b25c: 021b lsls r3, r3, #8 + 800b25e: 4313 orrs r3, r2 + 800b260: b29b uxth r3, r3 + 800b262: 4a54 ldr r2, [pc, #336] ; (800b3b4 ) + 800b264: 4293 cmp r3, r2 + 800b266: d91c bls.n 800b2a2 + iecho->chksum += PP_HTONS(ICMP_ECHO << 8) + 1; + 800b268: 68fb ldr r3, [r7, #12] + 800b26a: 789a ldrb r2, [r3, #2] + 800b26c: 78db ldrb r3, [r3, #3] + 800b26e: 021b lsls r3, r3, #8 + 800b270: 4313 orrs r3, r2 + 800b272: b29b uxth r3, r3 + 800b274: 3309 adds r3, #9 + 800b276: b29a uxth r2, r3 + 800b278: 68fb ldr r3, [r7, #12] + 800b27a: 21ff movs r1, #255 ; 0xff + 800b27c: 4011 ands r1, r2 + 800b27e: 000c movs r4, r1 + 800b280: 7899 ldrb r1, [r3, #2] + 800b282: 2000 movs r0, #0 + 800b284: 4001 ands r1, r0 + 800b286: 1c08 adds r0, r1, #0 + 800b288: 1c21 adds r1, r4, #0 + 800b28a: 4301 orrs r1, r0 + 800b28c: 7099 strb r1, [r3, #2] + 800b28e: 0a12 lsrs r2, r2, #8 + 800b290: b290 uxth r0, r2 + 800b292: 78da ldrb r2, [r3, #3] + 800b294: 2100 movs r1, #0 + 800b296: 400a ands r2, r1 + 800b298: 1c11 adds r1, r2, #0 + 800b29a: 1c02 adds r2, r0, #0 + 800b29c: 430a orrs r2, r1 + 800b29e: 70da strb r2, [r3, #3] + 800b2a0: e01b b.n 800b2da + } else { + iecho->chksum += PP_HTONS(ICMP_ECHO << 8); + 800b2a2: 68fb ldr r3, [r7, #12] + 800b2a4: 789a ldrb r2, [r3, #2] + 800b2a6: 78db ldrb r3, [r3, #3] + 800b2a8: 021b lsls r3, r3, #8 + 800b2aa: 4313 orrs r3, r2 + 800b2ac: b29b uxth r3, r3 + 800b2ae: 3308 adds r3, #8 + 800b2b0: b29a uxth r2, r3 + 800b2b2: 68fb ldr r3, [r7, #12] + 800b2b4: 21ff movs r1, #255 ; 0xff + 800b2b6: 4011 ands r1, r2 + 800b2b8: 000c movs r4, r1 + 800b2ba: 7899 ldrb r1, [r3, #2] + 800b2bc: 2000 movs r0, #0 + 800b2be: 4001 ands r1, r0 + 800b2c0: 1c08 adds r0, r1, #0 + 800b2c2: 1c21 adds r1, r4, #0 + 800b2c4: 4301 orrs r1, r0 + 800b2c6: 7099 strb r1, [r3, #2] + 800b2c8: 0a12 lsrs r2, r2, #8 + 800b2ca: b290 uxth r0, r2 + 800b2cc: 78da ldrb r2, [r3, #3] + 800b2ce: 2100 movs r1, #0 + 800b2d0: 400a ands r2, r1 + 800b2d2: 1c11 adds r1, r2, #0 + 800b2d4: 1c02 adds r2, r0, #0 + 800b2d6: 430a orrs r2, r1 + 800b2d8: 70da strb r2, [r3, #3] +#else /* CHECKSUM_GEN_ICMP */ + iecho->chksum = 0; +#endif /* CHECKSUM_GEN_ICMP */ + + /* Set the correct TTL and recalculate the header checksum. */ + IPH_TTL_SET(iphdr, ICMP_TTL); + 800b2da: 69fb ldr r3, [r7, #28] + 800b2dc: 22ff movs r2, #255 ; 0xff + 800b2de: 721a strb r2, [r3, #8] + IPH_CHKSUM_SET(iphdr, 0); + 800b2e0: 69fb ldr r3, [r7, #28] + 800b2e2: 7a9a ldrb r2, [r3, #10] + 800b2e4: 2100 movs r1, #0 + 800b2e6: 400a ands r2, r1 + 800b2e8: 729a strb r2, [r3, #10] + 800b2ea: 7ada ldrb r2, [r3, #11] + 800b2ec: 2100 movs r1, #0 + 800b2ee: 400a ands r2, r1 + 800b2f0: 72da strb r2, [r3, #11] +#if CHECKSUM_GEN_IP + IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, IP_HLEN)); + 800b2f2: 69fb ldr r3, [r7, #28] + 800b2f4: 2114 movs r1, #20 + 800b2f6: 0018 movs r0, r3 + 800b2f8: f000 fa3a bl 800b770 + 800b2fc: 0003 movs r3, r0 + 800b2fe: 001a movs r2, r3 + 800b300: 69fb ldr r3, [r7, #28] + 800b302: 21ff movs r1, #255 ; 0xff + 800b304: 4011 ands r1, r2 + 800b306: 000c movs r4, r1 + 800b308: 7a99 ldrb r1, [r3, #10] + 800b30a: 2000 movs r0, #0 + 800b30c: 4001 ands r1, r0 + 800b30e: 1c08 adds r0, r1, #0 + 800b310: 1c21 adds r1, r4, #0 + 800b312: 4301 orrs r1, r0 + 800b314: 7299 strb r1, [r3, #10] + 800b316: 0a12 lsrs r2, r2, #8 + 800b318: b290 uxth r0, r2 + 800b31a: 7ada ldrb r2, [r3, #11] + 800b31c: 2100 movs r1, #0 + 800b31e: 400a ands r2, r1 + 800b320: 1c11 adds r1, r2, #0 + 800b322: 1c02 adds r2, r0, #0 + 800b324: 430a orrs r2, r1 + 800b326: 72da strb r2, [r3, #11] +#endif /* CHECKSUM_GEN_IP */ + + ICMP_STATS_INC(icmp.xmit); + 800b328: 4b1f ldr r3, [pc, #124] ; (800b3a8 ) + 800b32a: 2260 movs r2, #96 ; 0x60 + 800b32c: 5a9b ldrh r3, [r3, r2] + 800b32e: 3301 adds r3, #1 + 800b330: b299 uxth r1, r3 + 800b332: 4b1d ldr r3, [pc, #116] ; (800b3a8 ) + 800b334: 2260 movs r2, #96 ; 0x60 + 800b336: 5299 strh r1, [r3, r2] + /* increase number of messages attempted to send */ + snmp_inc_icmpoutmsgs(); + /* increase number of echo replies attempted to send */ + snmp_inc_icmpoutechoreps(); + + if(pbuf_header(p, hlen)) { + 800b338: 2316 movs r3, #22 + 800b33a: 18fb adds r3, r7, r3 + 800b33c: 2200 movs r2, #0 + 800b33e: 5e9a ldrsh r2, [r3, r2] + 800b340: 687b ldr r3, [r7, #4] + 800b342: 0011 movs r1, r2 + 800b344: 0018 movs r0, r3 + 800b346: f7fa f926 bl 8005596 + 800b34a: 1e03 subs r3, r0, #0 + 800b34c: d123 bne.n 800b396 + LWIP_ASSERT("Can't move over header in packet", 0); + } else { + err_t ret; + /* send an ICMP packet, src addr is the dest addr of the curren packet */ + ret = ip_output_if(p, ip_current_dest_addr(), IP_HDRINCL, + 800b34e: 230b movs r3, #11 + 800b350: 18fc adds r4, r7, r3 + 800b352: 4916 ldr r1, [pc, #88] ; (800b3ac ) + 800b354: 6878 ldr r0, [r7, #4] + 800b356: 683b ldr r3, [r7, #0] + 800b358: 9302 str r3, [sp, #8] + 800b35a: 2301 movs r3, #1 + 800b35c: 9301 str r3, [sp, #4] + 800b35e: 2300 movs r3, #0 + 800b360: 9300 str r3, [sp, #0] + 800b362: 23ff movs r3, #255 ; 0xff + 800b364: 2200 movs r2, #0 + 800b366: f000 fc7d bl 800bc64 + 800b36a: 0003 movs r3, r0 + 800b36c: 7023 strb r3, [r4, #0] + ICMP_TTL, 0, IP_PROTO_ICMP, inp); + if (ret != ERR_OK) { + LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: ip_output_if returned an error: %c.\n", ret)); + } + } + break; + 800b36e: e012 b.n 800b396 + default: + LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: ICMP type %"S16_F" code %"S16_F" not supported.\n", + (s16_t)type, (s16_t)code)); + ICMP_STATS_INC(icmp.proterr); + 800b370: 4b0d ldr r3, [pc, #52] ; (800b3a8 ) + 800b372: 2270 movs r2, #112 ; 0x70 + 800b374: 5a9b ldrh r3, [r3, r2] + 800b376: 3301 adds r3, #1 + 800b378: b299 uxth r1, r3 + 800b37a: 4b0b ldr r3, [pc, #44] ; (800b3a8 ) + 800b37c: 2270 movs r2, #112 ; 0x70 + 800b37e: 5299 strh r1, [r3, r2] + ICMP_STATS_INC(icmp.drop); + 800b380: 4b09 ldr r3, [pc, #36] ; (800b3a8 ) + 800b382: 2266 movs r2, #102 ; 0x66 + 800b384: 5a9b ldrh r3, [r3, r2] + 800b386: 3301 adds r3, #1 + 800b388: b299 uxth r1, r3 + 800b38a: 4b07 ldr r3, [pc, #28] ; (800b3a8 ) + 800b38c: 2266 movs r2, #102 ; 0x66 + 800b38e: 5299 strh r1, [r3, r2] + 800b390: e002 b.n 800b398 + break; + 800b392: 46c0 nop ; (mov r8, r8) + 800b394: e000 b.n 800b398 + break; + 800b396: 46c0 nop ; (mov r8, r8) + } + pbuf_free(p); + 800b398: 687b ldr r3, [r7, #4] + 800b39a: 0018 movs r0, r3 + 800b39c: f7fa f982 bl 80056a4 + return; + 800b3a0: e02e b.n 800b400 +lenerr: + 800b3a2: 46c0 nop ; (mov r8, r8) + 800b3a4: e009 b.n 800b3ba + 800b3a6: 46c0 nop ; (mov r8, r8) + 800b3a8: 20003158 .word 0x20003158 + 800b3ac: 2000329c .word 0x2000329c + 800b3b0: 20003294 .word 0x20003294 + 800b3b4: 0000fff6 .word 0x0000fff6 + goto lenerr; + 800b3b8: 46c0 nop ; (mov r8, r8) + pbuf_free(p); + 800b3ba: 687b ldr r3, [r7, #4] + 800b3bc: 0018 movs r0, r3 + 800b3be: f7fa f971 bl 80056a4 + ICMP_STATS_INC(icmp.lenerr); + 800b3c2: 4b11 ldr r3, [pc, #68] ; (800b408 ) + 800b3c4: 226a movs r2, #106 ; 0x6a + 800b3c6: 5a9b ldrh r3, [r3, r2] + 800b3c8: 3301 adds r3, #1 + 800b3ca: b299 uxth r1, r3 + 800b3cc: 4b0e ldr r3, [pc, #56] ; (800b408 ) + 800b3ce: 226a movs r2, #106 ; 0x6a + 800b3d0: 5299 strh r1, [r3, r2] + snmp_inc_icmpinerrors(); + return; + 800b3d2: e015 b.n 800b400 + goto memerr; + 800b3d4: 46c0 nop ; (mov r8, r8) + 800b3d6: e006 b.n 800b3e6 + goto memerr; + 800b3d8: 46c0 nop ; (mov r8, r8) + 800b3da: e004 b.n 800b3e6 + goto memerr; + 800b3dc: 46c0 nop ; (mov r8, r8) + 800b3de: e002 b.n 800b3e6 + goto memerr; + 800b3e0: 46c0 nop ; (mov r8, r8) + 800b3e2: e000 b.n 800b3e6 + goto memerr; + 800b3e4: 46c0 nop ; (mov r8, r8) +#if LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN +memerr: + pbuf_free(p); + 800b3e6: 687b ldr r3, [r7, #4] + 800b3e8: 0018 movs r0, r3 + 800b3ea: f7fa f95b bl 80056a4 + ICMP_STATS_INC(icmp.err); + 800b3ee: 4b06 ldr r3, [pc, #24] ; (800b408 ) + 800b3f0: 2274 movs r2, #116 ; 0x74 + 800b3f2: 5a9b ldrh r3, [r3, r2] + 800b3f4: 3301 adds r3, #1 + 800b3f6: b299 uxth r1, r3 + 800b3f8: 4b03 ldr r3, [pc, #12] ; (800b408 ) + 800b3fa: 2274 movs r2, #116 ; 0x74 + 800b3fc: 5299 strh r1, [r3, r2] + snmp_inc_icmpinerrors(); + return; + 800b3fe: 46c0 nop ; (mov r8, r8) +#endif /* LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN */ +} + 800b400: 46bd mov sp, r7 + 800b402: b009 add sp, #36 ; 0x24 + 800b404: bd90 pop {r4, r7, pc} + 800b406: 46c0 nop ; (mov r8, r8) + 800b408: 20003158 .word 0x20003158 + +0800b40c : + * p->payload pointing to the IP header + * @param t type of the 'unreachable' packet + */ +void +icmp_dest_unreach(struct pbuf *p, enum icmp_dur_type t) +{ + 800b40c: b580 push {r7, lr} + 800b40e: b082 sub sp, #8 + 800b410: af00 add r7, sp, #0 + 800b412: 6078 str r0, [r7, #4] + 800b414: 000a movs r2, r1 + 800b416: 1cfb adds r3, r7, #3 + 800b418: 701a strb r2, [r3, #0] + icmp_send_response(p, ICMP_DUR, t); + 800b41a: 1cfb adds r3, r7, #3 + 800b41c: 781a ldrb r2, [r3, #0] + 800b41e: 687b ldr r3, [r7, #4] + 800b420: 2103 movs r1, #3 + 800b422: 0018 movs r0, r3 + 800b424: f000 f816 bl 800b454 +} + 800b428: 46c0 nop ; (mov r8, r8) + 800b42a: 46bd mov sp, r7 + 800b42c: b002 add sp, #8 + 800b42e: bd80 pop {r7, pc} + +0800b430 : + * p->payload pointing to the IP header + * @param t type of the 'time exceeded' packet + */ +void +icmp_time_exceeded(struct pbuf *p, enum icmp_te_type t) +{ + 800b430: b580 push {r7, lr} + 800b432: b082 sub sp, #8 + 800b434: af00 add r7, sp, #0 + 800b436: 6078 str r0, [r7, #4] + 800b438: 000a movs r2, r1 + 800b43a: 1cfb adds r3, r7, #3 + 800b43c: 701a strb r2, [r3, #0] + icmp_send_response(p, ICMP_TE, t); + 800b43e: 1cfb adds r3, r7, #3 + 800b440: 781a ldrb r2, [r3, #0] + 800b442: 687b ldr r3, [r7, #4] + 800b444: 210b movs r1, #11 + 800b446: 0018 movs r0, r3 + 800b448: f000 f804 bl 800b454 +} + 800b44c: 46c0 nop ; (mov r8, r8) + 800b44e: 46bd mov sp, r7 + 800b450: b002 add sp, #8 + 800b452: bd80 pop {r7, pc} + +0800b454 : + * @param type Type of the ICMP header + * @param code Code of the ICMP header + */ +static void +icmp_send_response(struct pbuf *p, u8_t type, u8_t code) +{ + 800b454: b590 push {r4, r7, lr} + 800b456: b089 sub sp, #36 ; 0x24 + 800b458: af02 add r7, sp, #8 + 800b45a: 6078 str r0, [r7, #4] + 800b45c: 0008 movs r0, r1 + 800b45e: 0011 movs r1, r2 + 800b460: 1cfb adds r3, r7, #3 + 800b462: 1c02 adds r2, r0, #0 + 800b464: 701a strb r2, [r3, #0] + 800b466: 1cbb adds r3, r7, #2 + 800b468: 1c0a adds r2, r1, #0 + 800b46a: 701a strb r2, [r3, #0] + /* we can use the echo header here */ + struct icmp_echo_hdr *icmphdr; + ip_addr_t iphdr_src; + + /* ICMP header + IP header + 8 bytes of data */ + q = pbuf_alloc(PBUF_IP, sizeof(struct icmp_echo_hdr) + IP_HLEN + ICMP_DEST_UNREACH_DATASIZE, + 800b46c: 2200 movs r2, #0 + 800b46e: 2124 movs r1, #36 ; 0x24 + 800b470: 2001 movs r0, #1 + 800b472: f7f9 fe8b bl 800518c + 800b476: 0003 movs r3, r0 + 800b478: 617b str r3, [r7, #20] + PBUF_RAM); + if (q == NULL) { + 800b47a: 697b ldr r3, [r7, #20] + 800b47c: 2b00 cmp r3, #0 + 800b47e: d073 beq.n 800b568 + return; + } + LWIP_ASSERT("check that first pbuf can hold icmp message", + (q->len >= (sizeof(struct icmp_echo_hdr) + IP_HLEN + ICMP_DEST_UNREACH_DATASIZE))); + + iphdr = (struct ip_hdr *)p->payload; + 800b480: 687b ldr r3, [r7, #4] + 800b482: 685b ldr r3, [r3, #4] + 800b484: 613b str r3, [r7, #16] + ip_addr_debug_print(ICMP_DEBUG, &(iphdr->src)); + LWIP_DEBUGF(ICMP_DEBUG, (" to ")); + ip_addr_debug_print(ICMP_DEBUG, &(iphdr->dest)); + LWIP_DEBUGF(ICMP_DEBUG, ("\n")); + + icmphdr = (struct icmp_echo_hdr *)q->payload; + 800b486: 697b ldr r3, [r7, #20] + 800b488: 685b ldr r3, [r3, #4] + 800b48a: 60fb str r3, [r7, #12] + icmphdr->type = type; + 800b48c: 68fb ldr r3, [r7, #12] + 800b48e: 1cfa adds r2, r7, #3 + 800b490: 7812 ldrb r2, [r2, #0] + 800b492: 701a strb r2, [r3, #0] + icmphdr->code = code; + 800b494: 68fb ldr r3, [r7, #12] + 800b496: 1cba adds r2, r7, #2 + 800b498: 7812 ldrb r2, [r2, #0] + 800b49a: 705a strb r2, [r3, #1] + icmphdr->id = 0; + 800b49c: 68fb ldr r3, [r7, #12] + 800b49e: 791a ldrb r2, [r3, #4] + 800b4a0: 2100 movs r1, #0 + 800b4a2: 400a ands r2, r1 + 800b4a4: 711a strb r2, [r3, #4] + 800b4a6: 795a ldrb r2, [r3, #5] + 800b4a8: 2100 movs r1, #0 + 800b4aa: 400a ands r2, r1 + 800b4ac: 715a strb r2, [r3, #5] + icmphdr->seqno = 0; + 800b4ae: 68fb ldr r3, [r7, #12] + 800b4b0: 799a ldrb r2, [r3, #6] + 800b4b2: 2100 movs r1, #0 + 800b4b4: 400a ands r2, r1 + 800b4b6: 719a strb r2, [r3, #6] + 800b4b8: 79da ldrb r2, [r3, #7] + 800b4ba: 2100 movs r1, #0 + 800b4bc: 400a ands r2, r1 + 800b4be: 71da strb r2, [r3, #7] + + /* copy fields from original packet */ + SMEMCPY((u8_t *)q->payload + sizeof(struct icmp_echo_hdr), (u8_t *)p->payload, + 800b4c0: 697b ldr r3, [r7, #20] + 800b4c2: 685b ldr r3, [r3, #4] + 800b4c4: 3308 adds r3, #8 + 800b4c6: 0018 movs r0, r3 + 800b4c8: 687b ldr r3, [r7, #4] + 800b4ca: 685b ldr r3, [r3, #4] + 800b4cc: 221c movs r2, #28 + 800b4ce: 0019 movs r1, r3 + 800b4d0: f004 fbe7 bl 800fca2 + IP_HLEN + ICMP_DEST_UNREACH_DATASIZE); + + /* calculate checksum */ + icmphdr->chksum = 0; + 800b4d4: 68fb ldr r3, [r7, #12] + 800b4d6: 789a ldrb r2, [r3, #2] + 800b4d8: 2100 movs r1, #0 + 800b4da: 400a ands r2, r1 + 800b4dc: 709a strb r2, [r3, #2] + 800b4de: 78da ldrb r2, [r3, #3] + 800b4e0: 2100 movs r1, #0 + 800b4e2: 400a ands r2, r1 + 800b4e4: 70da strb r2, [r3, #3] + icmphdr->chksum = inet_chksum(icmphdr, q->len); + 800b4e6: 697b ldr r3, [r7, #20] + 800b4e8: 895a ldrh r2, [r3, #10] + 800b4ea: 68fb ldr r3, [r7, #12] + 800b4ec: 0011 movs r1, r2 + 800b4ee: 0018 movs r0, r3 + 800b4f0: f000 f93e bl 800b770 + 800b4f4: 0003 movs r3, r0 + 800b4f6: 001a movs r2, r3 + 800b4f8: 68fb ldr r3, [r7, #12] + 800b4fa: 21ff movs r1, #255 ; 0xff + 800b4fc: 4011 ands r1, r2 + 800b4fe: 000c movs r4, r1 + 800b500: 7899 ldrb r1, [r3, #2] + 800b502: 2000 movs r0, #0 + 800b504: 4001 ands r1, r0 + 800b506: 1c08 adds r0, r1, #0 + 800b508: 1c21 adds r1, r4, #0 + 800b50a: 4301 orrs r1, r0 + 800b50c: 7099 strb r1, [r3, #2] + 800b50e: 0a12 lsrs r2, r2, #8 + 800b510: b290 uxth r0, r2 + 800b512: 78da ldrb r2, [r3, #3] + 800b514: 2100 movs r1, #0 + 800b516: 400a ands r2, r1 + 800b518: 1c11 adds r1, r2, #0 + 800b51a: 1c02 adds r2, r0, #0 + 800b51c: 430a orrs r2, r1 + 800b51e: 70da strb r2, [r3, #3] + ICMP_STATS_INC(icmp.xmit); + 800b520: 4b13 ldr r3, [pc, #76] ; (800b570 ) + 800b522: 2260 movs r2, #96 ; 0x60 + 800b524: 5a9b ldrh r3, [r3, r2] + 800b526: 3301 adds r3, #1 + 800b528: b299 uxth r1, r3 + 800b52a: 4b11 ldr r3, [pc, #68] ; (800b570 ) + 800b52c: 2260 movs r2, #96 ; 0x60 + 800b52e: 5299 strh r1, [r3, r2] + /* increase number of messages attempted to send */ + snmp_inc_icmpoutmsgs(); + /* increase number of destination unreachable messages attempted to send */ + snmp_inc_icmpouttimeexcds(); + ip_addr_copy(iphdr_src, iphdr->src); + 800b530: 693b ldr r3, [r7, #16] + 800b532: 7b1a ldrb r2, [r3, #12] + 800b534: 7b59 ldrb r1, [r3, #13] + 800b536: 0209 lsls r1, r1, #8 + 800b538: 430a orrs r2, r1 + 800b53a: 7b99 ldrb r1, [r3, #14] + 800b53c: 0409 lsls r1, r1, #16 + 800b53e: 430a orrs r2, r1 + 800b540: 7bdb ldrb r3, [r3, #15] + 800b542: 061b lsls r3, r3, #24 + 800b544: 4313 orrs r3, r2 + 800b546: 60bb str r3, [r7, #8] + ip_output(q, NULL, &iphdr_src, ICMP_TTL, 0, IP_PROTO_ICMP); + 800b548: 2308 movs r3, #8 + 800b54a: 18fa adds r2, r7, r3 + 800b54c: 6978 ldr r0, [r7, #20] + 800b54e: 2301 movs r3, #1 + 800b550: 9301 str r3, [sp, #4] + 800b552: 2300 movs r3, #0 + 800b554: 9300 str r3, [sp, #0] + 800b556: 23ff movs r3, #255 ; 0xff + 800b558: 2100 movs r1, #0 + 800b55a: f000 fd59 bl 800c010 + pbuf_free(q); + 800b55e: 697b ldr r3, [r7, #20] + 800b560: 0018 movs r0, r3 + 800b562: f7fa f89f bl 80056a4 + 800b566: e000 b.n 800b56a + return; + 800b568: 46c0 nop ; (mov r8, r8) +} + 800b56a: 46bd mov sp, r7 + 800b56c: b007 add sp, #28 + 800b56e: bd90 pop {r4, r7, pc} + 800b570: 20003158 .word 0x20003158 + +0800b574 : + * @return host order (!) lwip checksum (non-inverted Internet sum) + */ + +static u16_t +lwip_standard_chksum(void *dataptr, int len) +{ + 800b574: b580 push {r7, lr} + 800b576: b088 sub sp, #32 + 800b578: af00 add r7, sp, #0 + 800b57a: 6078 str r0, [r7, #4] + 800b57c: 6039 str r1, [r7, #0] + u8_t *pb = (u8_t *)dataptr; + 800b57e: 687b ldr r3, [r7, #4] + 800b580: 61fb str r3, [r7, #28] + u16_t *ps, t = 0; + 800b582: 230e movs r3, #14 + 800b584: 18fb adds r3, r7, r3 + 800b586: 2200 movs r2, #0 + 800b588: 801a strh r2, [r3, #0] + u32_t sum = 0; + 800b58a: 2300 movs r3, #0 + 800b58c: 617b str r3, [r7, #20] + int odd = ((mem_ptr_t)pb & 1); + 800b58e: 69fb ldr r3, [r7, #28] + 800b590: 2201 movs r2, #1 + 800b592: 4013 ands r3, r2 + 800b594: 613b str r3, [r7, #16] + + /* Get aligned to u16_t */ + if (odd && len > 0) { + 800b596: 693b ldr r3, [r7, #16] + 800b598: 2b00 cmp r3, #0 + 800b59a: d00d beq.n 800b5b8 + 800b59c: 683b ldr r3, [r7, #0] + 800b59e: 2b00 cmp r3, #0 + 800b5a0: dd0a ble.n 800b5b8 + ((u8_t *)&t)[1] = *pb++; + 800b5a2: 69fa ldr r2, [r7, #28] + 800b5a4: 1c53 adds r3, r2, #1 + 800b5a6: 61fb str r3, [r7, #28] + 800b5a8: 230e movs r3, #14 + 800b5aa: 18fb adds r3, r7, r3 + 800b5ac: 3301 adds r3, #1 + 800b5ae: 7812 ldrb r2, [r2, #0] + 800b5b0: 701a strb r2, [r3, #0] + len--; + 800b5b2: 683b ldr r3, [r7, #0] + 800b5b4: 3b01 subs r3, #1 + 800b5b6: 603b str r3, [r7, #0] + } + + /* Add the bulk of the data */ + ps = (u16_t *)(void *)pb; + 800b5b8: 69fb ldr r3, [r7, #28] + 800b5ba: 61bb str r3, [r7, #24] + while (len > 1) { + 800b5bc: e00a b.n 800b5d4 + sum += *ps++; + 800b5be: 69bb ldr r3, [r7, #24] + 800b5c0: 1c9a adds r2, r3, #2 + 800b5c2: 61ba str r2, [r7, #24] + 800b5c4: 881b ldrh r3, [r3, #0] + 800b5c6: 001a movs r2, r3 + 800b5c8: 697b ldr r3, [r7, #20] + 800b5ca: 189b adds r3, r3, r2 + 800b5cc: 617b str r3, [r7, #20] + len -= 2; + 800b5ce: 683b ldr r3, [r7, #0] + 800b5d0: 3b02 subs r3, #2 + 800b5d2: 603b str r3, [r7, #0] + while (len > 1) { + 800b5d4: 683b ldr r3, [r7, #0] + 800b5d6: 2b01 cmp r3, #1 + 800b5d8: dcf1 bgt.n 800b5be + } + + /* Consume left-over byte, if any */ + if (len > 0) { + 800b5da: 683b ldr r3, [r7, #0] + 800b5dc: 2b00 cmp r3, #0 + 800b5de: dd04 ble.n 800b5ea + ((u8_t *)&t)[0] = *(u8_t *)ps; + 800b5e0: 230e movs r3, #14 + 800b5e2: 18fb adds r3, r7, r3 + 800b5e4: 69ba ldr r2, [r7, #24] + 800b5e6: 7812 ldrb r2, [r2, #0] + 800b5e8: 701a strb r2, [r3, #0] + } + + /* Add end bytes */ + sum += t; + 800b5ea: 230e movs r3, #14 + 800b5ec: 18fb adds r3, r7, r3 + 800b5ee: 881b ldrh r3, [r3, #0] + 800b5f0: 001a movs r2, r3 + 800b5f2: 697b ldr r3, [r7, #20] + 800b5f4: 189b adds r3, r3, r2 + 800b5f6: 617b str r3, [r7, #20] + + /* Fold 32-bit sum to 16 bits + calling this twice is propably faster than if statements... */ + sum = FOLD_U32T(sum); + 800b5f8: 697b ldr r3, [r7, #20] + 800b5fa: 0c1a lsrs r2, r3, #16 + 800b5fc: 697b ldr r3, [r7, #20] + 800b5fe: 041b lsls r3, r3, #16 + 800b600: 0c1b lsrs r3, r3, #16 + 800b602: 18d3 adds r3, r2, r3 + 800b604: 617b str r3, [r7, #20] + sum = FOLD_U32T(sum); + 800b606: 697b ldr r3, [r7, #20] + 800b608: 0c1a lsrs r2, r3, #16 + 800b60a: 697b ldr r3, [r7, #20] + 800b60c: 041b lsls r3, r3, #16 + 800b60e: 0c1b lsrs r3, r3, #16 + 800b610: 18d3 adds r3, r2, r3 + 800b612: 617b str r3, [r7, #20] + + /* Swap if alignment was odd */ + if (odd) { + 800b614: 693b ldr r3, [r7, #16] + 800b616: 2b00 cmp r3, #0 + 800b618: d009 beq.n 800b62e + sum = SWAP_BYTES_IN_WORD(sum); + 800b61a: 697b ldr r3, [r7, #20] + 800b61c: 021b lsls r3, r3, #8 + 800b61e: 041b lsls r3, r3, #16 + 800b620: 0c1a lsrs r2, r3, #16 + 800b622: 697b ldr r3, [r7, #20] + 800b624: 0a1b lsrs r3, r3, #8 + 800b626: 21ff movs r1, #255 ; 0xff + 800b628: 400b ands r3, r1 + 800b62a: 4313 orrs r3, r2 + 800b62c: 617b str r3, [r7, #20] + } + + return (u16_t)sum; + 800b62e: 697b ldr r3, [r7, #20] + 800b630: b29b uxth r3, r3 +} + 800b632: 0018 movs r0, r3 + 800b634: 46bd mov sp, r7 + 800b636: b008 add sp, #32 + 800b638: bd80 pop {r7, pc} + +0800b63a : + */ +u16_t +inet_chksum_pseudo(struct pbuf *p, + ip_addr_t *src, ip_addr_t *dest, + u8_t proto, u16_t proto_len) +{ + 800b63a: b580 push {r7, lr} + 800b63c: b088 sub sp, #32 + 800b63e: af00 add r7, sp, #0 + 800b640: 60f8 str r0, [r7, #12] + 800b642: 60b9 str r1, [r7, #8] + 800b644: 607a str r2, [r7, #4] + 800b646: 001a movs r2, r3 + 800b648: 1cfb adds r3, r7, #3 + 800b64a: 701a strb r2, [r3, #0] + u32_t acc; + u32_t addr; + struct pbuf *q; + u8_t swapped; + + acc = 0; + 800b64c: 2300 movs r3, #0 + 800b64e: 61fb str r3, [r7, #28] + swapped = 0; + 800b650: 2317 movs r3, #23 + 800b652: 18fb adds r3, r7, r3 + 800b654: 2200 movs r2, #0 + 800b656: 701a strb r2, [r3, #0] + /* iterate through all pbuf in chain */ + for(q = p; q != NULL; q = q->next) { + 800b658: 68fb ldr r3, [r7, #12] + 800b65a: 61bb str r3, [r7, #24] + 800b65c: e02e b.n 800b6bc + LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): checksumming pbuf %p (has next %p) \n", + (void *)q, (void *)q->next)); + acc += LWIP_CHKSUM(q->payload, q->len); + 800b65e: 69bb ldr r3, [r7, #24] + 800b660: 685a ldr r2, [r3, #4] + 800b662: 69bb ldr r3, [r7, #24] + 800b664: 895b ldrh r3, [r3, #10] + 800b666: 0019 movs r1, r3 + 800b668: 0010 movs r0, r2 + 800b66a: f7ff ff83 bl 800b574 + 800b66e: 0003 movs r3, r0 + 800b670: 001a movs r2, r3 + 800b672: 69fb ldr r3, [r7, #28] + 800b674: 189b adds r3, r3, r2 + 800b676: 61fb str r3, [r7, #28] + /*LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): unwrapped lwip_chksum()=%"X32_F" \n", acc));*/ + /* just executing this next line is probably faster that the if statement needed + to check whether we really need to execute it, and does no harm */ + acc = FOLD_U32T(acc); + 800b678: 69fb ldr r3, [r7, #28] + 800b67a: 0c1a lsrs r2, r3, #16 + 800b67c: 69fb ldr r3, [r7, #28] + 800b67e: 041b lsls r3, r3, #16 + 800b680: 0c1b lsrs r3, r3, #16 + 800b682: 18d3 adds r3, r2, r3 + 800b684: 61fb str r3, [r7, #28] + if (q->len % 2 != 0) { + 800b686: 69bb ldr r3, [r7, #24] + 800b688: 895b ldrh r3, [r3, #10] + 800b68a: 2201 movs r2, #1 + 800b68c: 4013 ands r3, r2 + 800b68e: b29b uxth r3, r3 + 800b690: 2b00 cmp r3, #0 + 800b692: d010 beq.n 800b6b6 + swapped = 1 - swapped; + 800b694: 2217 movs r2, #23 + 800b696: 18bb adds r3, r7, r2 + 800b698: 18ba adds r2, r7, r2 + 800b69a: 7812 ldrb r2, [r2, #0] + 800b69c: 2101 movs r1, #1 + 800b69e: 1a8a subs r2, r1, r2 + 800b6a0: 701a strb r2, [r3, #0] + acc = SWAP_BYTES_IN_WORD(acc); + 800b6a2: 69fb ldr r3, [r7, #28] + 800b6a4: 021b lsls r3, r3, #8 + 800b6a6: 041b lsls r3, r3, #16 + 800b6a8: 0c1a lsrs r2, r3, #16 + 800b6aa: 69fb ldr r3, [r7, #28] + 800b6ac: 0a1b lsrs r3, r3, #8 + 800b6ae: 21ff movs r1, #255 ; 0xff + 800b6b0: 400b ands r3, r1 + 800b6b2: 4313 orrs r3, r2 + 800b6b4: 61fb str r3, [r7, #28] + for(q = p; q != NULL; q = q->next) { + 800b6b6: 69bb ldr r3, [r7, #24] + 800b6b8: 681b ldr r3, [r3, #0] + 800b6ba: 61bb str r3, [r7, #24] + 800b6bc: 69bb ldr r3, [r7, #24] + 800b6be: 2b00 cmp r3, #0 + 800b6c0: d1cd bne.n 800b65e + } + /*LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): wrapped lwip_chksum()=%"X32_F" \n", acc));*/ + } + + if (swapped) { + 800b6c2: 2317 movs r3, #23 + 800b6c4: 18fb adds r3, r7, r3 + 800b6c6: 781b ldrb r3, [r3, #0] + 800b6c8: 2b00 cmp r3, #0 + 800b6ca: d009 beq.n 800b6e0 + acc = SWAP_BYTES_IN_WORD(acc); + 800b6cc: 69fb ldr r3, [r7, #28] + 800b6ce: 021b lsls r3, r3, #8 + 800b6d0: 041b lsls r3, r3, #16 + 800b6d2: 0c1a lsrs r2, r3, #16 + 800b6d4: 69fb ldr r3, [r7, #28] + 800b6d6: 0a1b lsrs r3, r3, #8 + 800b6d8: 21ff movs r1, #255 ; 0xff + 800b6da: 400b ands r3, r1 + 800b6dc: 4313 orrs r3, r2 + 800b6de: 61fb str r3, [r7, #28] + } + addr = ip4_addr_get_u32(src); + 800b6e0: 68bb ldr r3, [r7, #8] + 800b6e2: 681b ldr r3, [r3, #0] + 800b6e4: 613b str r3, [r7, #16] + acc += (addr & 0xffffUL); + 800b6e6: 693b ldr r3, [r7, #16] + 800b6e8: 041b lsls r3, r3, #16 + 800b6ea: 0c1b lsrs r3, r3, #16 + 800b6ec: 69fa ldr r2, [r7, #28] + 800b6ee: 18d3 adds r3, r2, r3 + 800b6f0: 61fb str r3, [r7, #28] + acc += ((addr >> 16) & 0xffffUL); + 800b6f2: 693b ldr r3, [r7, #16] + 800b6f4: 0c1b lsrs r3, r3, #16 + 800b6f6: 69fa ldr r2, [r7, #28] + 800b6f8: 18d3 adds r3, r2, r3 + 800b6fa: 61fb str r3, [r7, #28] + addr = ip4_addr_get_u32(dest); + 800b6fc: 687b ldr r3, [r7, #4] + 800b6fe: 681b ldr r3, [r3, #0] + 800b700: 613b str r3, [r7, #16] + acc += (addr & 0xffffUL); + 800b702: 693b ldr r3, [r7, #16] + 800b704: 041b lsls r3, r3, #16 + 800b706: 0c1b lsrs r3, r3, #16 + 800b708: 69fa ldr r2, [r7, #28] + 800b70a: 18d3 adds r3, r2, r3 + 800b70c: 61fb str r3, [r7, #28] + acc += ((addr >> 16) & 0xffffUL); + 800b70e: 693b ldr r3, [r7, #16] + 800b710: 0c1b lsrs r3, r3, #16 + 800b712: 69fa ldr r2, [r7, #28] + 800b714: 18d3 adds r3, r2, r3 + 800b716: 61fb str r3, [r7, #28] + acc += (u32_t)htons((u16_t)proto); + 800b718: 1cfb adds r3, r7, #3 + 800b71a: 781b ldrb r3, [r3, #0] + 800b71c: b29b uxth r3, r3 + 800b71e: 0018 movs r0, r3 + 800b720: f7f8 ff78 bl 8004614 + 800b724: 0003 movs r3, r0 + 800b726: 001a movs r2, r3 + 800b728: 69fb ldr r3, [r7, #28] + 800b72a: 189b adds r3, r3, r2 + 800b72c: 61fb str r3, [r7, #28] + acc += (u32_t)htons(proto_len); + 800b72e: 2328 movs r3, #40 ; 0x28 + 800b730: 18fb adds r3, r7, r3 + 800b732: 881b ldrh r3, [r3, #0] + 800b734: 0018 movs r0, r3 + 800b736: f7f8 ff6d bl 8004614 + 800b73a: 0003 movs r3, r0 + 800b73c: 001a movs r2, r3 + 800b73e: 69fb ldr r3, [r7, #28] + 800b740: 189b adds r3, r3, r2 + 800b742: 61fb str r3, [r7, #28] + + /* Fold 32-bit sum to 16 bits + calling this twice is propably faster than if statements... */ + acc = FOLD_U32T(acc); + 800b744: 69fb ldr r3, [r7, #28] + 800b746: 0c1a lsrs r2, r3, #16 + 800b748: 69fb ldr r3, [r7, #28] + 800b74a: 041b lsls r3, r3, #16 + 800b74c: 0c1b lsrs r3, r3, #16 + 800b74e: 18d3 adds r3, r2, r3 + 800b750: 61fb str r3, [r7, #28] + acc = FOLD_U32T(acc); + 800b752: 69fb ldr r3, [r7, #28] + 800b754: 0c1a lsrs r2, r3, #16 + 800b756: 69fb ldr r3, [r7, #28] + 800b758: 041b lsls r3, r3, #16 + 800b75a: 0c1b lsrs r3, r3, #16 + 800b75c: 18d3 adds r3, r2, r3 + 800b75e: 61fb str r3, [r7, #28] + LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): pbuf chain lwip_chksum()=%"X32_F"\n", acc)); + return (u16_t)~(acc & 0xffffUL); + 800b760: 69fb ldr r3, [r7, #28] + 800b762: b29b uxth r3, r3 + 800b764: 43db mvns r3, r3 + 800b766: b29b uxth r3, r3 +} + 800b768: 0018 movs r0, r3 + 800b76a: 46bd mov sp, r7 + 800b76c: b008 add sp, #32 + 800b76e: bd80 pop {r7, pc} + +0800b770 : + * @return checksum (as u16_t) to be saved directly in the protocol header + */ + +u16_t +inet_chksum(void *dataptr, u16_t len) +{ + 800b770: b580 push {r7, lr} + 800b772: b082 sub sp, #8 + 800b774: af00 add r7, sp, #0 + 800b776: 6078 str r0, [r7, #4] + 800b778: 000a movs r2, r1 + 800b77a: 1cbb adds r3, r7, #2 + 800b77c: 801a strh r2, [r3, #0] + return ~LWIP_CHKSUM(dataptr, len); + 800b77e: 1cbb adds r3, r7, #2 + 800b780: 881a ldrh r2, [r3, #0] + 800b782: 687b ldr r3, [r7, #4] + 800b784: 0011 movs r1, r2 + 800b786: 0018 movs r0, r3 + 800b788: f7ff fef4 bl 800b574 + 800b78c: 0003 movs r3, r0 + 800b78e: 43db mvns r3, r3 + 800b790: b29b uxth r3, r3 +} + 800b792: 0018 movs r0, r3 + 800b794: 46bd mov sp, r7 + 800b796: b002 add sp, #8 + 800b798: bd80 pop {r7, pc} + +0800b79a : + * @param p pbuf chain over that the checksum should be calculated + * @return checksum (as u16_t) to be saved directly in the protocol header + */ +u16_t +inet_chksum_pbuf(struct pbuf *p) +{ + 800b79a: b580 push {r7, lr} + 800b79c: b086 sub sp, #24 + 800b79e: af00 add r7, sp, #0 + 800b7a0: 6078 str r0, [r7, #4] + u32_t acc; + struct pbuf *q; + u8_t swapped; + + acc = 0; + 800b7a2: 2300 movs r3, #0 + 800b7a4: 617b str r3, [r7, #20] + swapped = 0; + 800b7a6: 230f movs r3, #15 + 800b7a8: 18fb adds r3, r7, r3 + 800b7aa: 2200 movs r2, #0 + 800b7ac: 701a strb r2, [r3, #0] + for(q = p; q != NULL; q = q->next) { + 800b7ae: 687b ldr r3, [r7, #4] + 800b7b0: 613b str r3, [r7, #16] + 800b7b2: e02e b.n 800b812 + acc += LWIP_CHKSUM(q->payload, q->len); + 800b7b4: 693b ldr r3, [r7, #16] + 800b7b6: 685a ldr r2, [r3, #4] + 800b7b8: 693b ldr r3, [r7, #16] + 800b7ba: 895b ldrh r3, [r3, #10] + 800b7bc: 0019 movs r1, r3 + 800b7be: 0010 movs r0, r2 + 800b7c0: f7ff fed8 bl 800b574 + 800b7c4: 0003 movs r3, r0 + 800b7c6: 001a movs r2, r3 + 800b7c8: 697b ldr r3, [r7, #20] + 800b7ca: 189b adds r3, r3, r2 + 800b7cc: 617b str r3, [r7, #20] + acc = FOLD_U32T(acc); + 800b7ce: 697b ldr r3, [r7, #20] + 800b7d0: 0c1a lsrs r2, r3, #16 + 800b7d2: 697b ldr r3, [r7, #20] + 800b7d4: 041b lsls r3, r3, #16 + 800b7d6: 0c1b lsrs r3, r3, #16 + 800b7d8: 18d3 adds r3, r2, r3 + 800b7da: 617b str r3, [r7, #20] + if (q->len % 2 != 0) { + 800b7dc: 693b ldr r3, [r7, #16] + 800b7de: 895b ldrh r3, [r3, #10] + 800b7e0: 2201 movs r2, #1 + 800b7e2: 4013 ands r3, r2 + 800b7e4: b29b uxth r3, r3 + 800b7e6: 2b00 cmp r3, #0 + 800b7e8: d010 beq.n 800b80c + swapped = 1 - swapped; + 800b7ea: 220f movs r2, #15 + 800b7ec: 18bb adds r3, r7, r2 + 800b7ee: 18ba adds r2, r7, r2 + 800b7f0: 7812 ldrb r2, [r2, #0] + 800b7f2: 2101 movs r1, #1 + 800b7f4: 1a8a subs r2, r1, r2 + 800b7f6: 701a strb r2, [r3, #0] + acc = SWAP_BYTES_IN_WORD(acc); + 800b7f8: 697b ldr r3, [r7, #20] + 800b7fa: 021b lsls r3, r3, #8 + 800b7fc: 041b lsls r3, r3, #16 + 800b7fe: 0c1a lsrs r2, r3, #16 + 800b800: 697b ldr r3, [r7, #20] + 800b802: 0a1b lsrs r3, r3, #8 + 800b804: 21ff movs r1, #255 ; 0xff + 800b806: 400b ands r3, r1 + 800b808: 4313 orrs r3, r2 + 800b80a: 617b str r3, [r7, #20] + for(q = p; q != NULL; q = q->next) { + 800b80c: 693b ldr r3, [r7, #16] + 800b80e: 681b ldr r3, [r3, #0] + 800b810: 613b str r3, [r7, #16] + 800b812: 693b ldr r3, [r7, #16] + 800b814: 2b00 cmp r3, #0 + 800b816: d1cd bne.n 800b7b4 + } + } + + if (swapped) { + 800b818: 230f movs r3, #15 + 800b81a: 18fb adds r3, r7, r3 + 800b81c: 781b ldrb r3, [r3, #0] + 800b81e: 2b00 cmp r3, #0 + 800b820: d009 beq.n 800b836 + acc = SWAP_BYTES_IN_WORD(acc); + 800b822: 697b ldr r3, [r7, #20] + 800b824: 021b lsls r3, r3, #8 + 800b826: 041b lsls r3, r3, #16 + 800b828: 0c1a lsrs r2, r3, #16 + 800b82a: 697b ldr r3, [r7, #20] + 800b82c: 0a1b lsrs r3, r3, #8 + 800b82e: 21ff movs r1, #255 ; 0xff + 800b830: 400b ands r3, r1 + 800b832: 4313 orrs r3, r2 + 800b834: 617b str r3, [r7, #20] + } + return (u16_t)~(acc & 0xffffUL); + 800b836: 697b ldr r3, [r7, #20] + 800b838: b29b uxth r3, r3 + 800b83a: 43db mvns r3, r3 + 800b83c: b29b uxth r3, r3 +} + 800b83e: 0018 movs r0, r3 + 800b840: 46bd mov sp, r7 + 800b842: b006 add sp, #24 + 800b844: bd80 pop {r7, pc} + ... + +0800b848 : + * @param dest the destination IP address for which to find the route + * @return the netif on which to send to reach dest + */ +struct netif * +ip_route(ip_addr_t *dest) +{ + 800b848: b580 push {r7, lr} + 800b84a: b084 sub sp, #16 + 800b84c: af00 add r7, sp, #0 + 800b84e: 6078 str r0, [r7, #4] + return netif; + } +#endif + + /* iterate through netifs */ + for (netif = netif_list; netif != NULL; netif = netif->next) { + 800b850: 4b1c ldr r3, [pc, #112] ; (800b8c4 ) + 800b852: 681b ldr r3, [r3, #0] + 800b854: 60fb str r3, [r7, #12] + 800b856: e016 b.n 800b886 + /* network mask matches? */ + if (netif_is_up(netif)) { + 800b858: 68fb ldr r3, [r7, #12] + 800b85a: 2229 movs r2, #41 ; 0x29 + 800b85c: 5c9b ldrb r3, [r3, r2] + 800b85e: 1c1a adds r2, r3, #0 + 800b860: 2301 movs r3, #1 + 800b862: 4013 ands r3, r2 + 800b864: b2db uxtb r3, r3 + 800b866: 2b00 cmp r3, #0 + 800b868: d00a beq.n 800b880 + if (ip_addr_netcmp(dest, &(netif->ip_addr), &(netif->netmask))) { + 800b86a: 687b ldr r3, [r7, #4] + 800b86c: 681a ldr r2, [r3, #0] + 800b86e: 68fb ldr r3, [r7, #12] + 800b870: 685b ldr r3, [r3, #4] + 800b872: 405a eors r2, r3 + 800b874: 68fb ldr r3, [r7, #12] + 800b876: 689b ldr r3, [r3, #8] + 800b878: 4013 ands r3, r2 + 800b87a: d101 bne.n 800b880 + /* return netif on which to forward IP packet */ + return netif; + 800b87c: 68fb ldr r3, [r7, #12] + 800b87e: e01d b.n 800b8bc + for (netif = netif_list; netif != NULL; netif = netif->next) { + 800b880: 68fb ldr r3, [r7, #12] + 800b882: 681b ldr r3, [r3, #0] + 800b884: 60fb str r3, [r7, #12] + 800b886: 68fb ldr r3, [r7, #12] + 800b888: 2b00 cmp r3, #0 + 800b88a: d1e5 bne.n 800b858 + } + } + } + if ((netif_default == NULL) || (!netif_is_up(netif_default))) { + 800b88c: 4b0e ldr r3, [pc, #56] ; (800b8c8 ) + 800b88e: 681b ldr r3, [r3, #0] + 800b890: 2b00 cmp r3, #0 + 800b892: d007 beq.n 800b8a4 + 800b894: 4b0c ldr r3, [pc, #48] ; (800b8c8 ) + 800b896: 681b ldr r3, [r3, #0] + 800b898: 2229 movs r2, #41 ; 0x29 + 800b89a: 5c9b ldrb r3, [r3, r2] + 800b89c: 001a movs r2, r3 + 800b89e: 2301 movs r3, #1 + 800b8a0: 4013 ands r3, r2 + 800b8a2: d109 bne.n 800b8b8 + LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip_route: No route to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", + ip4_addr1_16(dest), ip4_addr2_16(dest), ip4_addr3_16(dest), ip4_addr4_16(dest))); + IP_STATS_INC(ip.rterr); + 800b8a4: 4b09 ldr r3, [pc, #36] ; (800b8cc ) + 800b8a6: 2256 movs r2, #86 ; 0x56 + 800b8a8: 5a9b ldrh r3, [r3, r2] + 800b8aa: 3301 adds r3, #1 + 800b8ac: b299 uxth r1, r3 + 800b8ae: 4b07 ldr r3, [pc, #28] ; (800b8cc ) + 800b8b0: 2256 movs r2, #86 ; 0x56 + 800b8b2: 5299 strh r1, [r3, r2] + snmp_inc_ipoutnoroutes(); + return NULL; + 800b8b4: 2300 movs r3, #0 + 800b8b6: e001 b.n 800b8bc + } + /* no matching netif found, use default netif */ + return netif_default; + 800b8b8: 4b03 ldr r3, [pc, #12] ; (800b8c8 ) + 800b8ba: 681b ldr r3, [r3, #0] +} + 800b8bc: 0018 movs r0, r3 + 800b8be: 46bd mov sp, r7 + 800b8c0: b004 add sp, #16 + 800b8c2: bd80 pop {r7, pc} + 800b8c4: 2000314c .word 0x2000314c + 800b8c8: 20003150 .word 0x20003150 + 800b8cc: 20003158 .word 0x20003158 + +0800b8d0 : + * @return ERR_OK if the packet was processed (could return ERR_* if it wasn't + * processed, but currently always returns ERR_OK) + */ +err_t +ip_input(struct pbuf *p, struct netif *inp) +{ + 800b8d0: b5b0 push {r4, r5, r7, lr} + 800b8d2: b088 sub sp, #32 + 800b8d4: af00 add r7, sp, #0 + 800b8d6: 6078 str r0, [r7, #4] + 800b8d8: 6039 str r1, [r7, #0] + struct ip_hdr *iphdr; + struct netif *netif; + u16_t iphdr_hlen; + u16_t iphdr_len; +#if IP_ACCEPT_LINK_LAYER_ADDRESSING + int check_ip_src=1; + 800b8da: 2301 movs r3, #1 + 800b8dc: 617b str r3, [r7, #20] +#endif /* IP_ACCEPT_LINK_LAYER_ADDRESSING */ + + IP_STATS_INC(ip.recv); + 800b8de: 4bcd ldr r3, [pc, #820] ; (800bc14 ) + 800b8e0: 224a movs r2, #74 ; 0x4a + 800b8e2: 5a9b ldrh r3, [r3, r2] + 800b8e4: 3301 adds r3, #1 + 800b8e6: b299 uxth r1, r3 + 800b8e8: 4bca ldr r3, [pc, #808] ; (800bc14 ) + 800b8ea: 224a movs r2, #74 ; 0x4a + 800b8ec: 5299 strh r1, [r3, r2] + snmp_inc_ipinreceives(); + + /* identify the IP header */ + iphdr = (struct ip_hdr *)p->payload; + 800b8ee: 687b ldr r3, [r7, #4] + 800b8f0: 685b ldr r3, [r3, #4] + 800b8f2: 61fb str r3, [r7, #28] + if (IPH_V(iphdr) != 4) { + 800b8f4: 69fb ldr r3, [r7, #28] + 800b8f6: 781b ldrb r3, [r3, #0] + 800b8f8: 091b lsrs r3, r3, #4 + 800b8fa: b2db uxtb r3, r3 + 800b8fc: 2b04 cmp r3, #4 + 800b8fe: d015 beq.n 800b92c + LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_WARNING, ("IP packet dropped due to bad version number %"U16_F"\n", IPH_V(iphdr))); + ip_debug_print(p); + pbuf_free(p); + 800b900: 687b ldr r3, [r7, #4] + 800b902: 0018 movs r0, r3 + 800b904: f7f9 fece bl 80056a4 + IP_STATS_INC(ip.err); + 800b908: 4bc2 ldr r3, [pc, #776] ; (800bc14 ) + 800b90a: 225c movs r2, #92 ; 0x5c + 800b90c: 5a9b ldrh r3, [r3, r2] + 800b90e: 3301 adds r3, #1 + 800b910: b299 uxth r1, r3 + 800b912: 4bc0 ldr r3, [pc, #768] ; (800bc14 ) + 800b914: 225c movs r2, #92 ; 0x5c + 800b916: 5299 strh r1, [r3, r2] + IP_STATS_INC(ip.drop); + 800b918: 4bbe ldr r3, [pc, #760] ; (800bc14 ) + 800b91a: 224e movs r2, #78 ; 0x4e + 800b91c: 5a9b ldrh r3, [r3, r2] + 800b91e: 3301 adds r3, #1 + 800b920: b299 uxth r1, r3 + 800b922: 4bbc ldr r3, [pc, #752] ; (800bc14 ) + 800b924: 224e movs r2, #78 ; 0x4e + 800b926: 5299 strh r1, [r3, r2] + snmp_inc_ipinhdrerrors(); + return ERR_OK; + 800b928: 2300 movs r3, #0 + 800b92a: e18f b.n 800bc4c + return ERR_OK; + } +#endif + + /* obtain IP header length in number of 32-bit words */ + iphdr_hlen = IPH_HL(iphdr); + 800b92c: 69fb ldr r3, [r7, #28] + 800b92e: 781b ldrb r3, [r3, #0] + 800b930: b29a uxth r2, r3 + 800b932: 250e movs r5, #14 + 800b934: 197b adds r3, r7, r5 + 800b936: 210f movs r1, #15 + 800b938: 400a ands r2, r1 + 800b93a: 801a strh r2, [r3, #0] + /* calculate IP header length in bytes */ + iphdr_hlen *= 4; + 800b93c: 197b adds r3, r7, r5 + 800b93e: 197a adds r2, r7, r5 + 800b940: 8812 ldrh r2, [r2, #0] + 800b942: 0092 lsls r2, r2, #2 + 800b944: 801a strh r2, [r3, #0] + /* obtain ip length in bytes */ + iphdr_len = ntohs(IPH_LEN(iphdr)); + 800b946: 69fb ldr r3, [r7, #28] + 800b948: 789a ldrb r2, [r3, #2] + 800b94a: 78db ldrb r3, [r3, #3] + 800b94c: 021b lsls r3, r3, #8 + 800b94e: 4313 orrs r3, r2 + 800b950: b29b uxth r3, r3 + 800b952: 220c movs r2, #12 + 800b954: 18bc adds r4, r7, r2 + 800b956: 0018 movs r0, r3 + 800b958: f7f8 fe72 bl 8004640 + 800b95c: 0003 movs r3, r0 + 800b95e: 8023 strh r3, [r4, #0] + + /* header length exceeds first pbuf length, or ip length exceeds total pbuf length? */ + if ((iphdr_hlen > p->len) || (iphdr_len > p->tot_len)) { + 800b960: 687b ldr r3, [r7, #4] + 800b962: 895b ldrh r3, [r3, #10] + 800b964: 197a adds r2, r7, r5 + 800b966: 8812 ldrh r2, [r2, #0] + 800b968: 429a cmp r2, r3 + 800b96a: d806 bhi.n 800b97a + 800b96c: 687b ldr r3, [r7, #4] + 800b96e: 891b ldrh r3, [r3, #8] + 800b970: 220c movs r2, #12 + 800b972: 18ba adds r2, r7, r2 + 800b974: 8812 ldrh r2, [r2, #0] + 800b976: 429a cmp r2, r3 + 800b978: d915 bls.n 800b9a6 + LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, + ("IP (len %"U16_F") is longer than pbuf (len %"U16_F"), IP packet dropped.\n", + iphdr_len, p->tot_len)); + } + /* free (drop) packet pbufs */ + pbuf_free(p); + 800b97a: 687b ldr r3, [r7, #4] + 800b97c: 0018 movs r0, r3 + 800b97e: f7f9 fe91 bl 80056a4 + IP_STATS_INC(ip.lenerr); + 800b982: 4ba4 ldr r3, [pc, #656] ; (800bc14 ) + 800b984: 2252 movs r2, #82 ; 0x52 + 800b986: 5a9b ldrh r3, [r3, r2] + 800b988: 3301 adds r3, #1 + 800b98a: b299 uxth r1, r3 + 800b98c: 4ba1 ldr r3, [pc, #644] ; (800bc14 ) + 800b98e: 2252 movs r2, #82 ; 0x52 + 800b990: 5299 strh r1, [r3, r2] + IP_STATS_INC(ip.drop); + 800b992: 4ba0 ldr r3, [pc, #640] ; (800bc14 ) + 800b994: 224e movs r2, #78 ; 0x4e + 800b996: 5a9b ldrh r3, [r3, r2] + 800b998: 3301 adds r3, #1 + 800b99a: b299 uxth r1, r3 + 800b99c: 4b9d ldr r3, [pc, #628] ; (800bc14 ) + 800b99e: 224e movs r2, #78 ; 0x4e + 800b9a0: 5299 strh r1, [r3, r2] + snmp_inc_ipindiscards(); + return ERR_OK; + 800b9a2: 2300 movs r3, #0 + 800b9a4: e152 b.n 800bc4c + } + + /* verify checksum */ +#if CHECKSUM_CHECK_IP + if (inet_chksum(iphdr, iphdr_hlen) != 0) { + 800b9a6: 230e movs r3, #14 + 800b9a8: 18fb adds r3, r7, r3 + 800b9aa: 881a ldrh r2, [r3, #0] + 800b9ac: 69fb ldr r3, [r7, #28] + 800b9ae: 0011 movs r1, r2 + 800b9b0: 0018 movs r0, r3 + 800b9b2: f7ff fedd bl 800b770 + 800b9b6: 1e03 subs r3, r0, #0 + 800b9b8: d015 beq.n 800b9e6 + + LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, + ("Checksum (0x%"X16_F") failed, IP packet dropped.\n", inet_chksum(iphdr, iphdr_hlen))); + ip_debug_print(p); + pbuf_free(p); + 800b9ba: 687b ldr r3, [r7, #4] + 800b9bc: 0018 movs r0, r3 + 800b9be: f7f9 fe71 bl 80056a4 + IP_STATS_INC(ip.chkerr); + 800b9c2: 4b94 ldr r3, [pc, #592] ; (800bc14 ) + 800b9c4: 2250 movs r2, #80 ; 0x50 + 800b9c6: 5a9b ldrh r3, [r3, r2] + 800b9c8: 3301 adds r3, #1 + 800b9ca: b299 uxth r1, r3 + 800b9cc: 4b91 ldr r3, [pc, #580] ; (800bc14 ) + 800b9ce: 2250 movs r2, #80 ; 0x50 + 800b9d0: 5299 strh r1, [r3, r2] + IP_STATS_INC(ip.drop); + 800b9d2: 4b90 ldr r3, [pc, #576] ; (800bc14 ) + 800b9d4: 224e movs r2, #78 ; 0x4e + 800b9d6: 5a9b ldrh r3, [r3, r2] + 800b9d8: 3301 adds r3, #1 + 800b9da: b299 uxth r1, r3 + 800b9dc: 4b8d ldr r3, [pc, #564] ; (800bc14 ) + 800b9de: 224e movs r2, #78 ; 0x4e + 800b9e0: 5299 strh r1, [r3, r2] + snmp_inc_ipinhdrerrors(); + return ERR_OK; + 800b9e2: 2300 movs r3, #0 + 800b9e4: e132 b.n 800bc4c + } +#endif + + /* Trim pbuf. This should have been done at the netif layer, + * but we'll do it anyway just to be sure that its done. */ + pbuf_realloc(p, iphdr_len); + 800b9e6: 230c movs r3, #12 + 800b9e8: 18fb adds r3, r7, r3 + 800b9ea: 881a ldrh r2, [r3, #0] + 800b9ec: 687b ldr r3, [r7, #4] + 800b9ee: 0011 movs r1, r2 + 800b9f0: 0018 movs r0, r3 + 800b9f2: f7f9 fd5e bl 80054b2 + + /* copy IP addresses to aligned ip_addr_t */ + ip_addr_copy(current_iphdr_dest, iphdr->dest); + 800b9f6: 69fb ldr r3, [r7, #28] + 800b9f8: 7c1a ldrb r2, [r3, #16] + 800b9fa: 7c59 ldrb r1, [r3, #17] + 800b9fc: 0209 lsls r1, r1, #8 + 800b9fe: 430a orrs r2, r1 + 800ba00: 7c99 ldrb r1, [r3, #18] + 800ba02: 0409 lsls r1, r1, #16 + 800ba04: 430a orrs r2, r1 + 800ba06: 7cdb ldrb r3, [r3, #19] + 800ba08: 061b lsls r3, r3, #24 + 800ba0a: 4313 orrs r3, r2 + 800ba0c: 001a movs r2, r3 + 800ba0e: 4b82 ldr r3, [pc, #520] ; (800bc18 ) + 800ba10: 601a str r2, [r3, #0] + ip_addr_copy(current_iphdr_src, iphdr->src); + 800ba12: 69fb ldr r3, [r7, #28] + 800ba14: 7b1a ldrb r2, [r3, #12] + 800ba16: 7b59 ldrb r1, [r3, #13] + 800ba18: 0209 lsls r1, r1, #8 + 800ba1a: 430a orrs r2, r1 + 800ba1c: 7b99 ldrb r1, [r3, #14] + 800ba1e: 0409 lsls r1, r1, #16 + 800ba20: 430a orrs r2, r1 + 800ba22: 7bdb ldrb r3, [r3, #15] + 800ba24: 061b lsls r3, r3, #24 + 800ba26: 4313 orrs r3, r2 + 800ba28: 001a movs r2, r3 + 800ba2a: 4b7c ldr r3, [pc, #496] ; (800bc1c ) + 800ba2c: 601a str r2, [r3, #0] +#endif /* LWIP_IGMP */ + { + /* start trying with inp. if that's not acceptable, start walking the + list of configured netifs. + 'first' is used as a boolean to mark whether we started walking the list */ + int first = 1; + 800ba2e: 2301 movs r3, #1 + 800ba30: 613b str r3, [r7, #16] + netif = inp; + 800ba32: 683b ldr r3, [r7, #0] + 800ba34: 61bb str r3, [r7, #24] + ip4_addr_get_u32(&iphdr->dest) & ip4_addr_get_u32(&netif->netmask), + ip4_addr_get_u32(&netif->ip_addr) & ip4_addr_get_u32(&netif->netmask), + ip4_addr_get_u32(&iphdr->dest) & ~ip4_addr_get_u32(&netif->netmask))); + + /* interface is up and configured? */ + if ((netif_is_up(netif)) && (!ip_addr_isany(&(netif->ip_addr)))) { + 800ba36: 69bb ldr r3, [r7, #24] + 800ba38: 2229 movs r2, #41 ; 0x29 + 800ba3a: 5c9b ldrb r3, [r3, r2] + 800ba3c: 1c1a adds r2, r3, #0 + 800ba3e: 2301 movs r3, #1 + 800ba40: 4013 ands r3, r2 + 800ba42: b2db uxtb r3, r3 + 800ba44: 2b00 cmp r3, #0 + 800ba46: d016 beq.n 800ba76 + 800ba48: 69bb ldr r3, [r7, #24] + 800ba4a: 3304 adds r3, #4 + 800ba4c: 2b00 cmp r3, #0 + 800ba4e: d012 beq.n 800ba76 + 800ba50: 69bb ldr r3, [r7, #24] + 800ba52: 685b ldr r3, [r3, #4] + 800ba54: 2b00 cmp r3, #0 + 800ba56: d00e beq.n 800ba76 + /* unicast to this interface address? */ + if (ip_addr_cmp(¤t_iphdr_dest, &(netif->ip_addr)) || + 800ba58: 4b6f ldr r3, [pc, #444] ; (800bc18 ) + 800ba5a: 681a ldr r2, [r3, #0] + 800ba5c: 69bb ldr r3, [r7, #24] + 800ba5e: 685b ldr r3, [r3, #4] + 800ba60: 429a cmp r2, r3 + 800ba62: d01e beq.n 800baa2 + /* or broadcast on this interface network address? */ + ip_addr_isbroadcast(¤t_iphdr_dest, netif)) { + 800ba64: 4b6c ldr r3, [pc, #432] ; (800bc18 ) + 800ba66: 681b ldr r3, [r3, #0] + 800ba68: 69ba ldr r2, [r7, #24] + 800ba6a: 0011 movs r1, r2 + 800ba6c: 0018 movs r0, r3 + 800ba6e: f000 fb05 bl 800c07c + 800ba72: 1e03 subs r3, r0, #0 + if (ip_addr_cmp(¤t_iphdr_dest, &(netif->ip_addr)) || + 800ba74: d115 bne.n 800baa2 + /* break out of for loop */ + break; + } +#endif /* LWIP_AUTOIP */ + } + if (first) { + 800ba76: 693b ldr r3, [r7, #16] + 800ba78: 2b00 cmp r3, #0 + 800ba7a: d005 beq.n 800ba88 + first = 0; + 800ba7c: 2300 movs r3, #0 + 800ba7e: 613b str r3, [r7, #16] + netif = netif_list; + 800ba80: 4b67 ldr r3, [pc, #412] ; (800bc20 ) + 800ba82: 681b ldr r3, [r3, #0] + 800ba84: 61bb str r3, [r7, #24] + 800ba86: e002 b.n 800ba8e + } else { + netif = netif->next; + 800ba88: 69bb ldr r3, [r7, #24] + 800ba8a: 681b ldr r3, [r3, #0] + 800ba8c: 61bb str r3, [r7, #24] + } + if (netif == inp) { + 800ba8e: 69ba ldr r2, [r7, #24] + 800ba90: 683b ldr r3, [r7, #0] + 800ba92: 429a cmp r2, r3 + 800ba94: d102 bne.n 800ba9c + netif = netif->next; + 800ba96: 69bb ldr r3, [r7, #24] + 800ba98: 681b ldr r3, [r3, #0] + 800ba9a: 61bb str r3, [r7, #24] + } + } while(netif != NULL); + 800ba9c: 69bb ldr r3, [r7, #24] + 800ba9e: 2b00 cmp r3, #0 + 800baa0: d1c9 bne.n 800ba36 + * If you want to accept private broadcast communication while a netif is down, + * define LWIP_IP_ACCEPT_UDP_PORT(dst_port), e.g.: + * + * #define LWIP_IP_ACCEPT_UDP_PORT(dst_port) ((dst_port) == PP_NTOHS(12345)) + */ + if (netif == NULL) { + 800baa2: 69bb ldr r3, [r7, #24] + 800baa4: 2b00 cmp r3, #0 + 800baa6: d117 bne.n 800bad8 + /* remote port is DHCP server? */ + if (IPH_PROTO(iphdr) == IP_PROTO_UDP) { + 800baa8: 69fb ldr r3, [r7, #28] + 800baaa: 7a5b ldrb r3, [r3, #9] + 800baac: 2b11 cmp r3, #17 + 800baae: d113 bne.n 800bad8 + struct udp_hdr *udphdr = (struct udp_hdr *)((u8_t *)iphdr + iphdr_hlen); + 800bab0: 230e movs r3, #14 + 800bab2: 18fb adds r3, r7, r3 + 800bab4: 881b ldrh r3, [r3, #0] + 800bab6: 69fa ldr r2, [r7, #28] + 800bab8: 18d3 adds r3, r2, r3 + 800baba: 60bb str r3, [r7, #8] + LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE, ("ip_input: UDP packet to DHCP client port %"U16_F"\n", + ntohs(udphdr->dest))); + if (IP_ACCEPT_LINK_LAYER_ADDRESSED_PORT(udphdr->dest)) { + 800babc: 68bb ldr r3, [r7, #8] + 800babe: 789a ldrb r2, [r3, #2] + 800bac0: 78db ldrb r3, [r3, #3] + 800bac2: 021b lsls r3, r3, #8 + 800bac4: 4313 orrs r3, r2 + 800bac6: b29a uxth r2, r3 + 800bac8: 2386 movs r3, #134 ; 0x86 + 800baca: 01db lsls r3, r3, #7 + 800bacc: 429a cmp r2, r3 + 800bace: d103 bne.n 800bad8 + LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE, ("ip_input: DHCP packet accepted.\n")); + netif = inp; + 800bad0: 683b ldr r3, [r7, #0] + 800bad2: 61bb str r3, [r7, #24] + check_ip_src = 0; + 800bad4: 2300 movs r3, #0 + 800bad6: 617b str r3, [r7, #20] +#endif /* IP_ACCEPT_LINK_LAYER_ADDRESSING */ + + /* broadcast or multicast packet source address? Compliant with RFC 1122: 3.2.1.3 */ +#if IP_ACCEPT_LINK_LAYER_ADDRESSING + /* DHCP servers need 0.0.0.0 to be allowed as source address (RFC 1.1.2.2: 3.2.1.3/a) */ + if (check_ip_src && !ip_addr_isany(¤t_iphdr_src)) + 800bad8: 697b ldr r3, [r7, #20] + 800bada: 2b00 cmp r3, #0 + 800badc: d020 beq.n 800bb20 + 800bade: 4b4f ldr r3, [pc, #316] ; (800bc1c ) + 800bae0: 681b ldr r3, [r3, #0] + 800bae2: 2b00 cmp r3, #0 + 800bae4: d01c beq.n 800bb20 +#endif /* IP_ACCEPT_LINK_LAYER_ADDRESSING */ + { if ((ip_addr_isbroadcast(¤t_iphdr_src, inp)) || + 800bae6: 4b4d ldr r3, [pc, #308] ; (800bc1c ) + 800bae8: 681b ldr r3, [r3, #0] + 800baea: 683a ldr r2, [r7, #0] + 800baec: 0011 movs r1, r2 + 800baee: 0018 movs r0, r3 + 800baf0: f000 fac4 bl 800c07c + 800baf4: 1e03 subs r3, r0, #0 + 800baf6: d105 bne.n 800bb04 + (ip_addr_ismulticast(¤t_iphdr_src))) { + 800baf8: 4b48 ldr r3, [pc, #288] ; (800bc1c ) + 800bafa: 681b ldr r3, [r3, #0] + 800bafc: 22f0 movs r2, #240 ; 0xf0 + 800bafe: 4013 ands r3, r2 + { if ((ip_addr_isbroadcast(¤t_iphdr_src, inp)) || + 800bb00: 2be0 cmp r3, #224 ; 0xe0 + 800bb02: d10d bne.n 800bb20 + /* packet source is not valid */ + LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, ("ip_input: packet source is not valid.\n")); + /* free (drop) packet pbufs */ + pbuf_free(p); + 800bb04: 687b ldr r3, [r7, #4] + 800bb06: 0018 movs r0, r3 + 800bb08: f7f9 fdcc bl 80056a4 + IP_STATS_INC(ip.drop); + 800bb0c: 4b41 ldr r3, [pc, #260] ; (800bc14 ) + 800bb0e: 224e movs r2, #78 ; 0x4e + 800bb10: 5a9b ldrh r3, [r3, r2] + 800bb12: 3301 adds r3, #1 + 800bb14: b299 uxth r1, r3 + 800bb16: 4b3f ldr r3, [pc, #252] ; (800bc14 ) + 800bb18: 224e movs r2, #78 ; 0x4e + 800bb1a: 5299 strh r1, [r3, r2] + snmp_inc_ipinaddrerrors(); + snmp_inc_ipindiscards(); + return ERR_OK; + 800bb1c: 2300 movs r3, #0 + 800bb1e: e095 b.n 800bc4c + } + } + + /* packet not for us? */ + if (netif == NULL) { + 800bb20: 69bb ldr r3, [r7, #24] + 800bb22: 2b00 cmp r3, #0 + 800bb24: d105 bne.n 800bb32 +#endif /* IP_FORWARD */ + { + snmp_inc_ipinaddrerrors(); + snmp_inc_ipindiscards(); + } + pbuf_free(p); + 800bb26: 687b ldr r3, [r7, #4] + 800bb28: 0018 movs r0, r3 + 800bb2a: f7f9 fdbb bl 80056a4 + return ERR_OK; + 800bb2e: 2300 movs r3, #0 + 800bb30: e08c b.n 800bc4c + } + /* packet consists of multiple fragments? */ + if ((IPH_OFFSET(iphdr) & PP_HTONS(IP_OFFMASK | IP_MF)) != 0) { + 800bb32: 69fb ldr r3, [r7, #28] + 800bb34: 799a ldrb r2, [r3, #6] + 800bb36: 79db ldrb r3, [r3, #7] + 800bb38: 021b lsls r3, r3, #8 + 800bb3a: 4313 orrs r3, r2 + 800bb3c: b29b uxth r3, r3 + 800bb3e: 001a movs r2, r3 + 800bb40: 4b38 ldr r3, [pc, #224] ; (800bc24 ) + 800bb42: 4013 ands r3, r2 + 800bb44: d00d beq.n 800bb62 +#if IP_REASSEMBLY /* packet fragment reassembly code present? */ + LWIP_DEBUGF(IP_DEBUG, ("IP packet is a fragment (id=0x%04"X16_F" tot_len=%"U16_F" len=%"U16_F" MF=%"U16_F" offset=%"U16_F"), calling ip_reass()\n", + ntohs(IPH_ID(iphdr)), p->tot_len, ntohs(IPH_LEN(iphdr)), !!(IPH_OFFSET(iphdr) & PP_HTONS(IP_MF)), (ntohs(IPH_OFFSET(iphdr)) & IP_OFFMASK)*8)); + /* reassemble the packet*/ + p = ip_reass(p); + 800bb46: 687b ldr r3, [r7, #4] + 800bb48: 0018 movs r0, r3 + 800bb4a: f000 fe51 bl 800c7f0 + 800bb4e: 0003 movs r3, r0 + 800bb50: 607b str r3, [r7, #4] + /* packet not fully reassembled yet? */ + if (p == NULL) { + 800bb52: 687b ldr r3, [r7, #4] + 800bb54: 2b00 cmp r3, #0 + 800bb56: d101 bne.n 800bb5c + return ERR_OK; + 800bb58: 2300 movs r3, #0 + 800bb5a: e077 b.n 800bc4c + } + iphdr = (struct ip_hdr *)p->payload; + 800bb5c: 687b ldr r3, [r7, #4] + 800bb5e: 685b ldr r3, [r3, #4] + 800bb60: 61fb str r3, [r7, #28] + /* send to upper layers */ + LWIP_DEBUGF(IP_DEBUG, ("ip_input: \n")); + ip_debug_print(p); + LWIP_DEBUGF(IP_DEBUG, ("ip_input: p->len %"U16_F" p->tot_len %"U16_F"\n", p->len, p->tot_len)); + + current_netif = inp; + 800bb62: 4b31 ldr r3, [pc, #196] ; (800bc28 ) + 800bb64: 683a ldr r2, [r7, #0] + 800bb66: 601a str r2, [r3, #0] + current_header = iphdr; + 800bb68: 4b30 ldr r3, [pc, #192] ; (800bc2c ) + 800bb6a: 69fa ldr r2, [r7, #28] + 800bb6c: 601a str r2, [r3, #0] + +#if LWIP_RAW + /* raw input did not eat the packet? */ + if (raw_input(p, inp) == 0) + 800bb6e: 683a ldr r2, [r7, #0] + 800bb70: 687b ldr r3, [r7, #4] + 800bb72: 0011 movs r1, r2 + 800bb74: 0018 movs r0, r3 + 800bb76: f7f9 ffa9 bl 8005acc + 800bb7a: 1e03 subs r3, r0, #0 + 800bb7c: d158 bne.n 800bc30 +#endif /* LWIP_RAW */ + { + switch (IPH_PROTO(iphdr)) { + 800bb7e: 69fb ldr r3, [r7, #28] + 800bb80: 7a5b ldrb r3, [r3, #9] + 800bb82: 2b06 cmp r3, #6 + 800bb84: d00b beq.n 800bb9e + 800bb86: 2b11 cmp r3, #17 + 800bb88: d002 beq.n 800bb90 + 800bb8a: 2b01 cmp r3, #1 + 800bb8c: d00e beq.n 800bbac + 800bb8e: e014 b.n 800bbba + case IP_PROTO_UDP: +#if LWIP_UDPLITE + case IP_PROTO_UDPLITE: +#endif /* LWIP_UDPLITE */ + snmp_inc_ipindelivers(); + udp_input(p, inp); + 800bb90: 683a ldr r2, [r7, #0] + 800bb92: 687b ldr r3, [r7, #4] + 800bb94: 0011 movs r1, r2 + 800bb96: 0018 movs r0, r3 + 800bb98: f7fe fe8a bl 800a8b0 + break; + 800bb9c: e049 b.n 800bc32 +#endif /* LWIP_UDP */ +#if LWIP_TCP + case IP_PROTO_TCP: + snmp_inc_ipindelivers(); + tcp_input(p, inp); + 800bb9e: 683a ldr r2, [r7, #0] + 800bba0: 687b ldr r3, [r7, #4] + 800bba2: 0011 movs r1, r2 + 800bba4: 0018 movs r0, r3 + 800bba6: f7fb f813 bl 8006bd0 + break; + 800bbaa: e042 b.n 800bc32 +#endif /* LWIP_TCP */ +#if LWIP_ICMP + case IP_PROTO_ICMP: + snmp_inc_ipindelivers(); + icmp_input(p, inp); + 800bbac: 683a ldr r2, [r7, #0] + 800bbae: 687b ldr r3, [r7, #4] + 800bbb0: 0011 movs r1, r2 + 800bbb2: 0018 movs r0, r3 + 800bbb4: f7ff fa30 bl 800b018 + break; + 800bbb8: e03b b.n 800bc32 + break; +#endif /* LWIP_IGMP */ + default: +#if LWIP_ICMP + /* send ICMP destination protocol unreachable unless is was a broadcast */ + if (!ip_addr_isbroadcast(¤t_iphdr_dest, inp) && + 800bbba: 4b17 ldr r3, [pc, #92] ; (800bc18 ) + 800bbbc: 681b ldr r3, [r3, #0] + 800bbbe: 683a ldr r2, [r7, #0] + 800bbc0: 0011 movs r1, r2 + 800bbc2: 0018 movs r0, r3 + 800bbc4: f000 fa5a bl 800c07c + 800bbc8: 1e03 subs r3, r0, #0 + 800bbca: d10d bne.n 800bbe8 + !ip_addr_ismulticast(¤t_iphdr_dest)) { + 800bbcc: 4b12 ldr r3, [pc, #72] ; (800bc18 ) + 800bbce: 681b ldr r3, [r3, #0] + 800bbd0: 22f0 movs r2, #240 ; 0xf0 + 800bbd2: 4013 ands r3, r2 + if (!ip_addr_isbroadcast(¤t_iphdr_dest, inp) && + 800bbd4: 2be0 cmp r3, #224 ; 0xe0 + 800bbd6: d007 beq.n 800bbe8 + p->payload = iphdr; + 800bbd8: 687b ldr r3, [r7, #4] + 800bbda: 69fa ldr r2, [r7, #28] + 800bbdc: 605a str r2, [r3, #4] + icmp_dest_unreach(p, ICMP_DUR_PROTO); + 800bbde: 687b ldr r3, [r7, #4] + 800bbe0: 2102 movs r1, #2 + 800bbe2: 0018 movs r0, r3 + 800bbe4: f7ff fc12 bl 800b40c + } +#endif /* LWIP_ICMP */ + pbuf_free(p); + 800bbe8: 687b ldr r3, [r7, #4] + 800bbea: 0018 movs r0, r3 + 800bbec: f7f9 fd5a bl 80056a4 + + LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("Unsupported transport protocol %"U16_F"\n", IPH_PROTO(iphdr))); + + IP_STATS_INC(ip.proterr); + 800bbf0: 4b08 ldr r3, [pc, #32] ; (800bc14 ) + 800bbf2: 2258 movs r2, #88 ; 0x58 + 800bbf4: 5a9b ldrh r3, [r3, r2] + 800bbf6: 3301 adds r3, #1 + 800bbf8: b299 uxth r1, r3 + 800bbfa: 4b06 ldr r3, [pc, #24] ; (800bc14 ) + 800bbfc: 2258 movs r2, #88 ; 0x58 + 800bbfe: 5299 strh r1, [r3, r2] + IP_STATS_INC(ip.drop); + 800bc00: 4b04 ldr r3, [pc, #16] ; (800bc14 ) + 800bc02: 224e movs r2, #78 ; 0x4e + 800bc04: 5a9b ldrh r3, [r3, r2] + 800bc06: 3301 adds r3, #1 + 800bc08: b299 uxth r1, r3 + 800bc0a: 4b02 ldr r3, [pc, #8] ; (800bc14 ) + 800bc0c: 224e movs r2, #78 ; 0x4e + 800bc0e: 5299 strh r1, [r3, r2] + 800bc10: e00f b.n 800bc32 + 800bc12: 46c0 nop ; (mov r8, r8) + 800bc14: 20003158 .word 0x20003158 + 800bc18: 2000329c .word 0x2000329c + 800bc1c: 20003294 .word 0x20003294 + 800bc20: 2000314c .word 0x2000314c + 800bc24: 0000ff3f .word 0x0000ff3f + 800bc28: 20003298 .word 0x20003298 + 800bc2c: 200032a0 .word 0x200032a0 + snmp_inc_ipinunknownprotos(); + } + } + 800bc30: 46c0 nop ; (mov r8, r8) + + current_netif = NULL; + 800bc32: 4b08 ldr r3, [pc, #32] ; (800bc54 ) + 800bc34: 2200 movs r2, #0 + 800bc36: 601a str r2, [r3, #0] + current_header = NULL; + 800bc38: 4b07 ldr r3, [pc, #28] ; (800bc58 ) + 800bc3a: 2200 movs r2, #0 + 800bc3c: 601a str r2, [r3, #0] + ip_addr_set_any(¤t_iphdr_src); + 800bc3e: 4b07 ldr r3, [pc, #28] ; (800bc5c ) + 800bc40: 2200 movs r2, #0 + 800bc42: 601a str r2, [r3, #0] + ip_addr_set_any(¤t_iphdr_dest); + 800bc44: 4b06 ldr r3, [pc, #24] ; (800bc60 ) + 800bc46: 2200 movs r2, #0 + 800bc48: 601a str r2, [r3, #0] + + return ERR_OK; + 800bc4a: 2300 movs r3, #0 +} + 800bc4c: 0018 movs r0, r3 + 800bc4e: 46bd mov sp, r7 + 800bc50: b008 add sp, #32 + 800bc52: bdb0 pop {r4, r5, r7, pc} + 800bc54: 20003298 .word 0x20003298 + 800bc58: 200032a0 .word 0x200032a0 + 800bc5c: 20003294 .word 0x20003294 + 800bc60: 2000329c .word 0x2000329c + +0800bc64 : + */ +err_t +ip_output_if(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest, + u8_t ttl, u8_t tos, + u8_t proto, struct netif *netif) +{ + 800bc64: b590 push {r4, r7, lr} + 800bc66: b089 sub sp, #36 ; 0x24 + 800bc68: af00 add r7, sp, #0 + 800bc6a: 60f8 str r0, [r7, #12] + 800bc6c: 60b9 str r1, [r7, #8] + 800bc6e: 607a str r2, [r7, #4] + 800bc70: 001a movs r2, r3 + 800bc72: 1cfb adds r3, r7, #3 + 800bc74: 701a strb r2, [r3, #0] +{ +#endif /* IP_OPTIONS_SEND */ + struct ip_hdr *iphdr; + ip_addr_t dest_addr; +#if CHECKSUM_GEN_IP_INLINE + u32_t chk_sum = 0; + 800bc76: 2300 movs r3, #0 + 800bc78: 61fb str r3, [r7, #28] + LWIP_ASSERT("p->ref == 1", p->ref == 1); + + snmp_inc_ipoutrequests(); + + /* Should the IP header be generated or is it already included in p? */ + if (dest != IP_HDRINCL) { + 800bc7a: 687b ldr r3, [r7, #4] + 800bc7c: 2b00 cmp r3, #0 + 800bc7e: d100 bne.n 800bc82 + 800bc80: e18b b.n 800bf9a + u16_t ip_hlen = IP_HLEN; + 800bc82: 2316 movs r3, #22 + 800bc84: 18fb adds r3, r7, r3 + 800bc86: 2214 movs r2, #20 + 800bc88: 801a strh r2, [r3, #0] + } +#endif /* CHECKSUM_GEN_IP_INLINE */ + } +#endif /* IP_OPTIONS_SEND */ + /* generate IP header */ + if (pbuf_header(p, IP_HLEN)) { + 800bc8a: 68fb ldr r3, [r7, #12] + 800bc8c: 2114 movs r1, #20 + 800bc8e: 0018 movs r0, r3 + 800bc90: f7f9 fc81 bl 8005596 + 800bc94: 1e03 subs r3, r0, #0 + 800bc96: d00a beq.n 800bcae + LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip_output: not enough room for IP header in pbuf\n")); + + IP_STATS_INC(ip.err); + 800bc98: 4bdb ldr r3, [pc, #876] ; (800c008 ) + 800bc9a: 225c movs r2, #92 ; 0x5c + 800bc9c: 5a9b ldrh r3, [r3, r2] + 800bc9e: 3301 adds r3, #1 + 800bca0: b299 uxth r1, r3 + 800bca2: 4bd9 ldr r3, [pc, #868] ; (800c008 ) + 800bca4: 225c movs r2, #92 ; 0x5c + 800bca6: 5299 strh r1, [r3, r2] + snmp_inc_ipoutdiscards(); + return ERR_BUF; + 800bca8: 2302 movs r3, #2 + 800bcaa: 425b negs r3, r3 + 800bcac: e1a8 b.n 800c000 + } + + iphdr = (struct ip_hdr *)p->payload; + 800bcae: 68fb ldr r3, [r7, #12] + 800bcb0: 685b ldr r3, [r3, #4] + 800bcb2: 61bb str r3, [r7, #24] + LWIP_ASSERT("check that first pbuf can hold struct ip_hdr", + (p->len >= sizeof(struct ip_hdr))); + + IPH_TTL_SET(iphdr, ttl); + 800bcb4: 69bb ldr r3, [r7, #24] + 800bcb6: 1cfa adds r2, r7, #3 + 800bcb8: 7812 ldrb r2, [r2, #0] + 800bcba: 721a strb r2, [r3, #8] + IPH_PROTO_SET(iphdr, proto); + 800bcbc: 69bb ldr r3, [r7, #24] + 800bcbe: 2134 movs r1, #52 ; 0x34 + 800bcc0: 187a adds r2, r7, r1 + 800bcc2: 7812 ldrb r2, [r2, #0] + 800bcc4: 725a strb r2, [r3, #9] +#if CHECKSUM_GEN_IP_INLINE + chk_sum += LWIP_MAKE_U16(proto, ttl); + 800bcc6: 187b adds r3, r7, r1 + 800bcc8: 781b ldrb r3, [r3, #0] + 800bcca: 021a lsls r2, r3, #8 + 800bccc: 1cfb adds r3, r7, #3 + 800bcce: 781b ldrb r3, [r3, #0] + 800bcd0: 4313 orrs r3, r2 + 800bcd2: 001a movs r2, r3 + 800bcd4: 69fb ldr r3, [r7, #28] + 800bcd6: 189b adds r3, r3, r2 + 800bcd8: 61fb str r3, [r7, #28] +#endif /* CHECKSUM_GEN_IP_INLINE */ + + /* dest cannot be NULL here */ + ip_addr_copy(iphdr->dest, *dest); + 800bcda: 687b ldr r3, [r7, #4] + 800bcdc: 681a ldr r2, [r3, #0] + 800bcde: 69bb ldr r3, [r7, #24] + 800bce0: 21ff movs r1, #255 ; 0xff + 800bce2: 4011 ands r1, r2 + 800bce4: 000c movs r4, r1 + 800bce6: 7c19 ldrb r1, [r3, #16] + 800bce8: 2000 movs r0, #0 + 800bcea: 4001 ands r1, r0 + 800bcec: 1c08 adds r0, r1, #0 + 800bcee: 1c21 adds r1, r4, #0 + 800bcf0: 4301 orrs r1, r0 + 800bcf2: 7419 strb r1, [r3, #16] + 800bcf4: 0a11 lsrs r1, r2, #8 + 800bcf6: 20ff movs r0, #255 ; 0xff + 800bcf8: 4001 ands r1, r0 + 800bcfa: 000c movs r4, r1 + 800bcfc: 7c59 ldrb r1, [r3, #17] + 800bcfe: 2000 movs r0, #0 + 800bd00: 4001 ands r1, r0 + 800bd02: 1c08 adds r0, r1, #0 + 800bd04: 1c21 adds r1, r4, #0 + 800bd06: 4301 orrs r1, r0 + 800bd08: 7459 strb r1, [r3, #17] + 800bd0a: 0c11 lsrs r1, r2, #16 + 800bd0c: 20ff movs r0, #255 ; 0xff + 800bd0e: 4001 ands r1, r0 + 800bd10: 000c movs r4, r1 + 800bd12: 7c99 ldrb r1, [r3, #18] + 800bd14: 2000 movs r0, #0 + 800bd16: 4001 ands r1, r0 + 800bd18: 1c08 adds r0, r1, #0 + 800bd1a: 1c21 adds r1, r4, #0 + 800bd1c: 4301 orrs r1, r0 + 800bd1e: 7499 strb r1, [r3, #18] + 800bd20: 0e10 lsrs r0, r2, #24 + 800bd22: 7cda ldrb r2, [r3, #19] + 800bd24: 2100 movs r1, #0 + 800bd26: 400a ands r2, r1 + 800bd28: 1c11 adds r1, r2, #0 + 800bd2a: 1c02 adds r2, r0, #0 + 800bd2c: 430a orrs r2, r1 + 800bd2e: 74da strb r2, [r3, #19] +#if CHECKSUM_GEN_IP_INLINE + chk_sum += ip4_addr_get_u32(&iphdr->dest) & 0xFFFF; + 800bd30: 69bb ldr r3, [r7, #24] + 800bd32: 7c1a ldrb r2, [r3, #16] + 800bd34: 7c59 ldrb r1, [r3, #17] + 800bd36: 0209 lsls r1, r1, #8 + 800bd38: 430a orrs r2, r1 + 800bd3a: 7c99 ldrb r1, [r3, #18] + 800bd3c: 0409 lsls r1, r1, #16 + 800bd3e: 430a orrs r2, r1 + 800bd40: 7cdb ldrb r3, [r3, #19] + 800bd42: 061b lsls r3, r3, #24 + 800bd44: 4313 orrs r3, r2 + 800bd46: 041b lsls r3, r3, #16 + 800bd48: 0c1b lsrs r3, r3, #16 + 800bd4a: 69fa ldr r2, [r7, #28] + 800bd4c: 18d3 adds r3, r2, r3 + 800bd4e: 61fb str r3, [r7, #28] + chk_sum += ip4_addr_get_u32(&iphdr->dest) >> 16; + 800bd50: 69bb ldr r3, [r7, #24] + 800bd52: 7c1a ldrb r2, [r3, #16] + 800bd54: 7c59 ldrb r1, [r3, #17] + 800bd56: 0209 lsls r1, r1, #8 + 800bd58: 430a orrs r2, r1 + 800bd5a: 7c99 ldrb r1, [r3, #18] + 800bd5c: 0409 lsls r1, r1, #16 + 800bd5e: 430a orrs r2, r1 + 800bd60: 7cdb ldrb r3, [r3, #19] + 800bd62: 061b lsls r3, r3, #24 + 800bd64: 4313 orrs r3, r2 + 800bd66: 0c1b lsrs r3, r3, #16 + 800bd68: 69fa ldr r2, [r7, #28] + 800bd6a: 18d3 adds r3, r2, r3 + 800bd6c: 61fb str r3, [r7, #28] +#endif /* CHECKSUM_GEN_IP_INLINE */ + + IPH_VHL_SET(iphdr, 4, ip_hlen / 4); + 800bd6e: 2316 movs r3, #22 + 800bd70: 18fb adds r3, r7, r3 + 800bd72: 881b ldrh r3, [r3, #0] + 800bd74: 089b lsrs r3, r3, #2 + 800bd76: b29b uxth r3, r3 + 800bd78: b2db uxtb r3, r3 + 800bd7a: 2240 movs r2, #64 ; 0x40 + 800bd7c: 4313 orrs r3, r2 + 800bd7e: b2da uxtb r2, r3 + 800bd80: 69bb ldr r3, [r7, #24] + 800bd82: 701a strb r2, [r3, #0] + IPH_TOS_SET(iphdr, tos); + 800bd84: 69bb ldr r3, [r7, #24] + 800bd86: 2130 movs r1, #48 ; 0x30 + 800bd88: 187a adds r2, r7, r1 + 800bd8a: 7812 ldrb r2, [r2, #0] + 800bd8c: 705a strb r2, [r3, #1] +#if CHECKSUM_GEN_IP_INLINE + chk_sum += LWIP_MAKE_U16(tos, iphdr->_v_hl); + 800bd8e: 187b adds r3, r7, r1 + 800bd90: 781b ldrb r3, [r3, #0] + 800bd92: 021b lsls r3, r3, #8 + 800bd94: 69ba ldr r2, [r7, #24] + 800bd96: 7812 ldrb r2, [r2, #0] + 800bd98: 4313 orrs r3, r2 + 800bd9a: 001a movs r2, r3 + 800bd9c: 69fb ldr r3, [r7, #28] + 800bd9e: 189b adds r3, r3, r2 + 800bda0: 61fb str r3, [r7, #28] +#endif /* CHECKSUM_GEN_IP_INLINE */ + IPH_LEN_SET(iphdr, htons(p->tot_len)); + 800bda2: 68fb ldr r3, [r7, #12] + 800bda4: 891b ldrh r3, [r3, #8] + 800bda6: 0018 movs r0, r3 + 800bda8: f7f8 fc34 bl 8004614 + 800bdac: 0003 movs r3, r0 + 800bdae: 001a movs r2, r3 + 800bdb0: 69bb ldr r3, [r7, #24] + 800bdb2: 21ff movs r1, #255 ; 0xff + 800bdb4: 4011 ands r1, r2 + 800bdb6: 000c movs r4, r1 + 800bdb8: 7899 ldrb r1, [r3, #2] + 800bdba: 2000 movs r0, #0 + 800bdbc: 4001 ands r1, r0 + 800bdbe: 1c08 adds r0, r1, #0 + 800bdc0: 1c21 adds r1, r4, #0 + 800bdc2: 4301 orrs r1, r0 + 800bdc4: 7099 strb r1, [r3, #2] + 800bdc6: 0a12 lsrs r2, r2, #8 + 800bdc8: b290 uxth r0, r2 + 800bdca: 78da ldrb r2, [r3, #3] + 800bdcc: 2100 movs r1, #0 + 800bdce: 400a ands r2, r1 + 800bdd0: 1c11 adds r1, r2, #0 + 800bdd2: 1c02 adds r2, r0, #0 + 800bdd4: 430a orrs r2, r1 + 800bdd6: 70da strb r2, [r3, #3] +#if CHECKSUM_GEN_IP_INLINE + chk_sum += iphdr->_len; + 800bdd8: 69bb ldr r3, [r7, #24] + 800bdda: 789a ldrb r2, [r3, #2] + 800bddc: 78db ldrb r3, [r3, #3] + 800bdde: 021b lsls r3, r3, #8 + 800bde0: 4313 orrs r3, r2 + 800bde2: b29b uxth r3, r3 + 800bde4: 001a movs r2, r3 + 800bde6: 69fb ldr r3, [r7, #28] + 800bde8: 189b adds r3, r3, r2 + 800bdea: 61fb str r3, [r7, #28] +#endif /* CHECKSUM_GEN_IP_INLINE */ + IPH_OFFSET_SET(iphdr, 0); + 800bdec: 69bb ldr r3, [r7, #24] + 800bdee: 799a ldrb r2, [r3, #6] + 800bdf0: 2100 movs r1, #0 + 800bdf2: 400a ands r2, r1 + 800bdf4: 719a strb r2, [r3, #6] + 800bdf6: 79da ldrb r2, [r3, #7] + 800bdf8: 2100 movs r1, #0 + 800bdfa: 400a ands r2, r1 + 800bdfc: 71da strb r2, [r3, #7] + IPH_ID_SET(iphdr, htons(ip_id)); + 800bdfe: 4b83 ldr r3, [pc, #524] ; (800c00c ) + 800be00: 881b ldrh r3, [r3, #0] + 800be02: 0018 movs r0, r3 + 800be04: f7f8 fc06 bl 8004614 + 800be08: 0003 movs r3, r0 + 800be0a: 001a movs r2, r3 + 800be0c: 69bb ldr r3, [r7, #24] + 800be0e: 21ff movs r1, #255 ; 0xff + 800be10: 4011 ands r1, r2 + 800be12: 000c movs r4, r1 + 800be14: 7919 ldrb r1, [r3, #4] + 800be16: 2000 movs r0, #0 + 800be18: 4001 ands r1, r0 + 800be1a: 1c08 adds r0, r1, #0 + 800be1c: 1c21 adds r1, r4, #0 + 800be1e: 4301 orrs r1, r0 + 800be20: 7119 strb r1, [r3, #4] + 800be22: 0a12 lsrs r2, r2, #8 + 800be24: b290 uxth r0, r2 + 800be26: 795a ldrb r2, [r3, #5] + 800be28: 2100 movs r1, #0 + 800be2a: 400a ands r2, r1 + 800be2c: 1c11 adds r1, r2, #0 + 800be2e: 1c02 adds r2, r0, #0 + 800be30: 430a orrs r2, r1 + 800be32: 715a strb r2, [r3, #5] +#if CHECKSUM_GEN_IP_INLINE + chk_sum += iphdr->_id; + 800be34: 69bb ldr r3, [r7, #24] + 800be36: 791a ldrb r2, [r3, #4] + 800be38: 795b ldrb r3, [r3, #5] + 800be3a: 021b lsls r3, r3, #8 + 800be3c: 4313 orrs r3, r2 + 800be3e: b29b uxth r3, r3 + 800be40: 001a movs r2, r3 + 800be42: 69fb ldr r3, [r7, #28] + 800be44: 189b adds r3, r3, r2 + 800be46: 61fb str r3, [r7, #28] +#endif /* CHECKSUM_GEN_IP_INLINE */ + ++ip_id; + 800be48: 4b70 ldr r3, [pc, #448] ; (800c00c ) + 800be4a: 881b ldrh r3, [r3, #0] + 800be4c: 3301 adds r3, #1 + 800be4e: b29a uxth r2, r3 + 800be50: 4b6e ldr r3, [pc, #440] ; (800c00c ) + 800be52: 801a strh r2, [r3, #0] + + if (ip_addr_isany(src)) { + 800be54: 68bb ldr r3, [r7, #8] + 800be56: 2b00 cmp r3, #0 + 800be58: d003 beq.n 800be62 + 800be5a: 68bb ldr r3, [r7, #8] + 800be5c: 681b ldr r3, [r3, #0] + 800be5e: 2b00 cmp r3, #0 + 800be60: d12b bne.n 800beba + ip_addr_copy(iphdr->src, netif->ip_addr); + 800be62: 6bbb ldr r3, [r7, #56] ; 0x38 + 800be64: 685a ldr r2, [r3, #4] + 800be66: 69bb ldr r3, [r7, #24] + 800be68: 21ff movs r1, #255 ; 0xff + 800be6a: 4011 ands r1, r2 + 800be6c: 000c movs r4, r1 + 800be6e: 7b19 ldrb r1, [r3, #12] + 800be70: 2000 movs r0, #0 + 800be72: 4001 ands r1, r0 + 800be74: 1c08 adds r0, r1, #0 + 800be76: 1c21 adds r1, r4, #0 + 800be78: 4301 orrs r1, r0 + 800be7a: 7319 strb r1, [r3, #12] + 800be7c: 0a11 lsrs r1, r2, #8 + 800be7e: 20ff movs r0, #255 ; 0xff + 800be80: 4001 ands r1, r0 + 800be82: 000c movs r4, r1 + 800be84: 7b59 ldrb r1, [r3, #13] + 800be86: 2000 movs r0, #0 + 800be88: 4001 ands r1, r0 + 800be8a: 1c08 adds r0, r1, #0 + 800be8c: 1c21 adds r1, r4, #0 + 800be8e: 4301 orrs r1, r0 + 800be90: 7359 strb r1, [r3, #13] + 800be92: 0c11 lsrs r1, r2, #16 + 800be94: 20ff movs r0, #255 ; 0xff + 800be96: 4001 ands r1, r0 + 800be98: 000c movs r4, r1 + 800be9a: 7b99 ldrb r1, [r3, #14] + 800be9c: 2000 movs r0, #0 + 800be9e: 4001 ands r1, r0 + 800bea0: 1c08 adds r0, r1, #0 + 800bea2: 1c21 adds r1, r4, #0 + 800bea4: 4301 orrs r1, r0 + 800bea6: 7399 strb r1, [r3, #14] + 800bea8: 0e10 lsrs r0, r2, #24 + 800beaa: 7bda ldrb r2, [r3, #15] + 800beac: 2100 movs r1, #0 + 800beae: 400a ands r2, r1 + 800beb0: 1c11 adds r1, r2, #0 + 800beb2: 1c02 adds r2, r0, #0 + 800beb4: 430a orrs r2, r1 + 800beb6: 73da strb r2, [r3, #15] + 800beb8: e02a b.n 800bf10 + } else { + /* src cannot be NULL here */ + ip_addr_copy(iphdr->src, *src); + 800beba: 68bb ldr r3, [r7, #8] + 800bebc: 681a ldr r2, [r3, #0] + 800bebe: 69bb ldr r3, [r7, #24] + 800bec0: 21ff movs r1, #255 ; 0xff + 800bec2: 4011 ands r1, r2 + 800bec4: 000c movs r4, r1 + 800bec6: 7b19 ldrb r1, [r3, #12] + 800bec8: 2000 movs r0, #0 + 800beca: 4001 ands r1, r0 + 800becc: 1c08 adds r0, r1, #0 + 800bece: 1c21 adds r1, r4, #0 + 800bed0: 4301 orrs r1, r0 + 800bed2: 7319 strb r1, [r3, #12] + 800bed4: 0a11 lsrs r1, r2, #8 + 800bed6: 20ff movs r0, #255 ; 0xff + 800bed8: 4001 ands r1, r0 + 800beda: 000c movs r4, r1 + 800bedc: 7b59 ldrb r1, [r3, #13] + 800bede: 2000 movs r0, #0 + 800bee0: 4001 ands r1, r0 + 800bee2: 1c08 adds r0, r1, #0 + 800bee4: 1c21 adds r1, r4, #0 + 800bee6: 4301 orrs r1, r0 + 800bee8: 7359 strb r1, [r3, #13] + 800beea: 0c11 lsrs r1, r2, #16 + 800beec: 20ff movs r0, #255 ; 0xff + 800beee: 4001 ands r1, r0 + 800bef0: 000c movs r4, r1 + 800bef2: 7b99 ldrb r1, [r3, #14] + 800bef4: 2000 movs r0, #0 + 800bef6: 4001 ands r1, r0 + 800bef8: 1c08 adds r0, r1, #0 + 800befa: 1c21 adds r1, r4, #0 + 800befc: 4301 orrs r1, r0 + 800befe: 7399 strb r1, [r3, #14] + 800bf00: 0e10 lsrs r0, r2, #24 + 800bf02: 7bda ldrb r2, [r3, #15] + 800bf04: 2100 movs r1, #0 + 800bf06: 400a ands r2, r1 + 800bf08: 1c11 adds r1, r2, #0 + 800bf0a: 1c02 adds r2, r0, #0 + 800bf0c: 430a orrs r2, r1 + 800bf0e: 73da strb r2, [r3, #15] + } + +#if CHECKSUM_GEN_IP_INLINE + chk_sum += ip4_addr_get_u32(&iphdr->src) & 0xFFFF; + 800bf10: 69bb ldr r3, [r7, #24] + 800bf12: 7b1a ldrb r2, [r3, #12] + 800bf14: 7b59 ldrb r1, [r3, #13] + 800bf16: 0209 lsls r1, r1, #8 + 800bf18: 430a orrs r2, r1 + 800bf1a: 7b99 ldrb r1, [r3, #14] + 800bf1c: 0409 lsls r1, r1, #16 + 800bf1e: 430a orrs r2, r1 + 800bf20: 7bdb ldrb r3, [r3, #15] + 800bf22: 061b lsls r3, r3, #24 + 800bf24: 4313 orrs r3, r2 + 800bf26: 041b lsls r3, r3, #16 + 800bf28: 0c1b lsrs r3, r3, #16 + 800bf2a: 69fa ldr r2, [r7, #28] + 800bf2c: 18d3 adds r3, r2, r3 + 800bf2e: 61fb str r3, [r7, #28] + chk_sum += ip4_addr_get_u32(&iphdr->src) >> 16; + 800bf30: 69bb ldr r3, [r7, #24] + 800bf32: 7b1a ldrb r2, [r3, #12] + 800bf34: 7b59 ldrb r1, [r3, #13] + 800bf36: 0209 lsls r1, r1, #8 + 800bf38: 430a orrs r2, r1 + 800bf3a: 7b99 ldrb r1, [r3, #14] + 800bf3c: 0409 lsls r1, r1, #16 + 800bf3e: 430a orrs r2, r1 + 800bf40: 7bdb ldrb r3, [r3, #15] + 800bf42: 061b lsls r3, r3, #24 + 800bf44: 4313 orrs r3, r2 + 800bf46: 0c1b lsrs r3, r3, #16 + 800bf48: 69fa ldr r2, [r7, #28] + 800bf4a: 18d3 adds r3, r2, r3 + 800bf4c: 61fb str r3, [r7, #28] + chk_sum = (chk_sum >> 16) + (chk_sum & 0xFFFF); + 800bf4e: 69fb ldr r3, [r7, #28] + 800bf50: 0c1a lsrs r2, r3, #16 + 800bf52: 69fb ldr r3, [r7, #28] + 800bf54: 041b lsls r3, r3, #16 + 800bf56: 0c1b lsrs r3, r3, #16 + 800bf58: 18d3 adds r3, r2, r3 + 800bf5a: 61fb str r3, [r7, #28] + chk_sum = (chk_sum >> 16) + chk_sum; + 800bf5c: 69fb ldr r3, [r7, #28] + 800bf5e: 0c1b lsrs r3, r3, #16 + 800bf60: 69fa ldr r2, [r7, #28] + 800bf62: 18d3 adds r3, r2, r3 + 800bf64: 61fb str r3, [r7, #28] + chk_sum = ~chk_sum; + 800bf66: 69fb ldr r3, [r7, #28] + 800bf68: 43db mvns r3, r3 + 800bf6a: 61fb str r3, [r7, #28] + iphdr->_chksum = chk_sum; /* network order */ + 800bf6c: 69fb ldr r3, [r7, #28] + 800bf6e: b29a uxth r2, r3 + 800bf70: 69bb ldr r3, [r7, #24] + 800bf72: 21ff movs r1, #255 ; 0xff + 800bf74: 4011 ands r1, r2 + 800bf76: 000c movs r4, r1 + 800bf78: 7a99 ldrb r1, [r3, #10] + 800bf7a: 2000 movs r0, #0 + 800bf7c: 4001 ands r1, r0 + 800bf7e: 1c08 adds r0, r1, #0 + 800bf80: 1c21 adds r1, r4, #0 + 800bf82: 4301 orrs r1, r0 + 800bf84: 7299 strb r1, [r3, #10] + 800bf86: 0a12 lsrs r2, r2, #8 + 800bf88: b290 uxth r0, r2 + 800bf8a: 7ada ldrb r2, [r3, #11] + 800bf8c: 2100 movs r1, #0 + 800bf8e: 400a ands r2, r1 + 800bf90: 1c11 adds r1, r2, #0 + 800bf92: 1c02 adds r2, r0, #0 + 800bf94: 430a orrs r2, r1 + 800bf96: 72da strb r2, [r3, #11] + 800bf98: e011 b.n 800bfbe + IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, ip_hlen)); +#endif +#endif /* CHECKSUM_GEN_IP_INLINE */ + } else { + /* IP header already included in p */ + iphdr = (struct ip_hdr *)p->payload; + 800bf9a: 68fb ldr r3, [r7, #12] + 800bf9c: 685b ldr r3, [r3, #4] + 800bf9e: 61bb str r3, [r7, #24] + ip_addr_copy(dest_addr, iphdr->dest); + 800bfa0: 69bb ldr r3, [r7, #24] + 800bfa2: 7c1a ldrb r2, [r3, #16] + 800bfa4: 7c59 ldrb r1, [r3, #17] + 800bfa6: 0209 lsls r1, r1, #8 + 800bfa8: 430a orrs r2, r1 + 800bfaa: 7c99 ldrb r1, [r3, #18] + 800bfac: 0409 lsls r1, r1, #16 + 800bfae: 430a orrs r2, r1 + 800bfb0: 7cdb ldrb r3, [r3, #19] + 800bfb2: 061b lsls r3, r3, #24 + 800bfb4: 4313 orrs r3, r2 + 800bfb6: 613b str r3, [r7, #16] + dest = &dest_addr; + 800bfb8: 2310 movs r3, #16 + 800bfba: 18fb adds r3, r7, r3 + 800bfbc: 607b str r3, [r7, #4] + } + + IP_STATS_INC(ip.xmit); + 800bfbe: 4b12 ldr r3, [pc, #72] ; (800c008 ) + 800bfc0: 2248 movs r2, #72 ; 0x48 + 800bfc2: 5a9b ldrh r3, [r3, r2] + 800bfc4: 3301 adds r3, #1 + 800bfc6: b299 uxth r1, r3 + 800bfc8: 4b0f ldr r3, [pc, #60] ; (800c008 ) + 800bfca: 2248 movs r2, #72 ; 0x48 + 800bfcc: 5299 strh r1, [r3, r2] + } +#endif /* LWIP_IGMP */ +#endif /* ENABLE_LOOPBACK */ +#if IP_FRAG + /* don't fragment if interface has mtu set to 0 [loopif] */ + if (netif->mtu && (p->tot_len > netif->mtu)) { + 800bfce: 6bbb ldr r3, [r7, #56] ; 0x38 + 800bfd0: 8c1b ldrh r3, [r3, #32] + 800bfd2: 2b00 cmp r3, #0 + 800bfd4: d00d beq.n 800bff2 + 800bfd6: 68fb ldr r3, [r7, #12] + 800bfd8: 891a ldrh r2, [r3, #8] + 800bfda: 6bbb ldr r3, [r7, #56] ; 0x38 + 800bfdc: 8c1b ldrh r3, [r3, #32] + 800bfde: 429a cmp r2, r3 + 800bfe0: d907 bls.n 800bff2 + return ip_frag(p, netif, dest); + 800bfe2: 687a ldr r2, [r7, #4] + 800bfe4: 6bb9 ldr r1, [r7, #56] ; 0x38 + 800bfe6: 68fb ldr r3, [r7, #12] + 800bfe8: 0018 movs r0, r3 + 800bfea: f000 fdf5 bl 800cbd8 + 800bfee: 0003 movs r3, r0 + 800bff0: e006 b.n 800c000 + } +#endif /* IP_FRAG */ + + LWIP_DEBUGF(IP_DEBUG, ("netif->output()")); + return netif->output(netif, p, dest); + 800bff2: 6bbb ldr r3, [r7, #56] ; 0x38 + 800bff4: 695b ldr r3, [r3, #20] + 800bff6: 687a ldr r2, [r7, #4] + 800bff8: 68f9 ldr r1, [r7, #12] + 800bffa: 6bb8 ldr r0, [r7, #56] ; 0x38 + 800bffc: 4798 blx r3 + 800bffe: 0003 movs r3, r0 +} + 800c000: 0018 movs r0, r3 + 800c002: 46bd mov sp, r7 + 800c004: b009 add sp, #36 ; 0x24 + 800c006: bd90 pop {r4, r7, pc} + 800c008: 20003158 .word 0x20003158 + 800c00c: 200022b4 .word 0x200022b4 + +0800c010 : + * see ip_output_if() for more return values + */ +err_t +ip_output(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest, + u8_t ttl, u8_t tos, u8_t proto) +{ + 800c010: b590 push {r4, r7, lr} + 800c012: b08b sub sp, #44 ; 0x2c + 800c014: af04 add r7, sp, #16 + 800c016: 60f8 str r0, [r7, #12] + 800c018: 60b9 str r1, [r7, #8] + 800c01a: 607a str r2, [r7, #4] + 800c01c: 001a movs r2, r3 + 800c01e: 1cfb adds r3, r7, #3 + 800c020: 701a strb r2, [r3, #0] + + /* pbufs passed to IP must have a ref-count of 1 as their payload pointer + gets altered as the packet is passed down the stack */ + LWIP_ASSERT("p->ref == 1", p->ref == 1); + + if ((netif = ip_route(dest)) == NULL) { + 800c022: 687b ldr r3, [r7, #4] + 800c024: 0018 movs r0, r3 + 800c026: f7ff fc0f bl 800b848 + 800c02a: 0003 movs r3, r0 + 800c02c: 617b str r3, [r7, #20] + 800c02e: 697b ldr r3, [r7, #20] + 800c030: 2b00 cmp r3, #0 + 800c032: d10a bne.n 800c04a + LWIP_DEBUGF(IP_DEBUG, ("ip_output: No route to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", + ip4_addr1_16(dest), ip4_addr2_16(dest), ip4_addr3_16(dest), ip4_addr4_16(dest))); + IP_STATS_INC(ip.rterr); + 800c034: 4b10 ldr r3, [pc, #64] ; (800c078 ) + 800c036: 2256 movs r2, #86 ; 0x56 + 800c038: 5a9b ldrh r3, [r3, r2] + 800c03a: 3301 adds r3, #1 + 800c03c: b299 uxth r1, r3 + 800c03e: 4b0e ldr r3, [pc, #56] ; (800c078 ) + 800c040: 2256 movs r2, #86 ; 0x56 + 800c042: 5299 strh r1, [r3, r2] + return ERR_RTE; + 800c044: 2304 movs r3, #4 + 800c046: 425b negs r3, r3 + 800c048: e012 b.n 800c070 + } + + return ip_output_if(p, src, dest, ttl, tos, proto, netif); + 800c04a: 1cfb adds r3, r7, #3 + 800c04c: 781c ldrb r4, [r3, #0] + 800c04e: 687a ldr r2, [r7, #4] + 800c050: 68b9 ldr r1, [r7, #8] + 800c052: 68f8 ldr r0, [r7, #12] + 800c054: 697b ldr r3, [r7, #20] + 800c056: 9302 str r3, [sp, #8] + 800c058: 232c movs r3, #44 ; 0x2c + 800c05a: 18fb adds r3, r7, r3 + 800c05c: 781b ldrb r3, [r3, #0] + 800c05e: 9301 str r3, [sp, #4] + 800c060: 2328 movs r3, #40 ; 0x28 + 800c062: 18fb adds r3, r7, r3 + 800c064: 781b ldrb r3, [r3, #0] + 800c066: 9300 str r3, [sp, #0] + 800c068: 0023 movs r3, r4 + 800c06a: f7ff fdfb bl 800bc64 + 800c06e: 0003 movs r3, r0 +} + 800c070: 0018 movs r0, r3 + 800c072: 46bd mov sp, r7 + 800c074: b007 add sp, #28 + 800c076: bd90 pop {r4, r7, pc} + 800c078: 20003158 .word 0x20003158 + +0800c07c : + * @param netif the network interface against which the address is checked + * @return returns non-zero if the address is a broadcast address + */ +u8_t +ip4_addr_isbroadcast(u32_t addr, const struct netif *netif) +{ + 800c07c: b580 push {r7, lr} + 800c07e: b084 sub sp, #16 + 800c080: af00 add r7, sp, #0 + 800c082: 6078 str r0, [r7, #4] + 800c084: 6039 str r1, [r7, #0] + ip_addr_t ipaddr; + ip4_addr_set_u32(&ipaddr, addr); + 800c086: 687b ldr r3, [r7, #4] + 800c088: 60fb str r3, [r7, #12] + + /* all ones (broadcast) or all zeroes (old skool broadcast) */ + if ((~addr == IPADDR_ANY) || + 800c08a: 687b ldr r3, [r7, #4] + 800c08c: 3301 adds r3, #1 + 800c08e: d002 beq.n 800c096 + 800c090: 687b ldr r3, [r7, #4] + 800c092: 2b00 cmp r3, #0 + 800c094: d101 bne.n 800c09a + (addr == IPADDR_ANY)) { + return 1; + 800c096: 2301 movs r3, #1 + 800c098: e024 b.n 800c0e4 + /* no broadcast support on this network interface? */ + } else if ((netif->flags & NETIF_FLAG_BROADCAST) == 0) { + 800c09a: 683b ldr r3, [r7, #0] + 800c09c: 2229 movs r2, #41 ; 0x29 + 800c09e: 5c9b ldrb r3, [r3, r2] + 800c0a0: 001a movs r2, r3 + 800c0a2: 2302 movs r3, #2 + 800c0a4: 4013 ands r3, r2 + 800c0a6: d101 bne.n 800c0ac + /* the given address cannot be a broadcast address + * nor can we check against any broadcast addresses */ + return 0; + 800c0a8: 2300 movs r3, #0 + 800c0aa: e01b b.n 800c0e4 + /* address matches network interface address exactly? => no broadcast */ + } else if (addr == ip4_addr_get_u32(&netif->ip_addr)) { + 800c0ac: 683b ldr r3, [r7, #0] + 800c0ae: 685b ldr r3, [r3, #4] + 800c0b0: 687a ldr r2, [r7, #4] + 800c0b2: 429a cmp r2, r3 + 800c0b4: d101 bne.n 800c0ba + return 0; + 800c0b6: 2300 movs r3, #0 + 800c0b8: e014 b.n 800c0e4 + /* on the same (sub) network... */ + } else if (ip_addr_netcmp(&ipaddr, &(netif->ip_addr), &(netif->netmask)) + 800c0ba: 68fa ldr r2, [r7, #12] + 800c0bc: 683b ldr r3, [r7, #0] + 800c0be: 685b ldr r3, [r3, #4] + 800c0c0: 405a eors r2, r3 + 800c0c2: 683b ldr r3, [r7, #0] + 800c0c4: 689b ldr r3, [r3, #8] + 800c0c6: 4013 ands r3, r2 + 800c0c8: d10b bne.n 800c0e2 + /* ...and host identifier bits are all ones? =>... */ + && ((addr & ~ip4_addr_get_u32(&netif->netmask)) == + 800c0ca: 683b ldr r3, [r7, #0] + 800c0cc: 689b ldr r3, [r3, #8] + 800c0ce: 43db mvns r3, r3 + 800c0d0: 687a ldr r2, [r7, #4] + 800c0d2: 401a ands r2, r3 + (IPADDR_BROADCAST & ~ip4_addr_get_u32(&netif->netmask)))) { + 800c0d4: 683b ldr r3, [r7, #0] + 800c0d6: 689b ldr r3, [r3, #8] + 800c0d8: 43db mvns r3, r3 + && ((addr & ~ip4_addr_get_u32(&netif->netmask)) == + 800c0da: 429a cmp r2, r3 + 800c0dc: d101 bne.n 800c0e2 + /* => network broadcast address */ + return 1; + 800c0de: 2301 movs r3, #1 + 800c0e0: e000 b.n 800c0e4 + } else { + return 0; + 800c0e2: 2300 movs r3, #0 + } +} + 800c0e4: 0018 movs r0, r3 + 800c0e6: 46bd mov sp, r7 + 800c0e8: b004 add sp, #16 + 800c0ea: bd80 pop {r7, pc} + +0800c0ec : + * + * Should be called every 1000 msec (defined by IP_TMR_INTERVAL). + */ +void +ip_reass_tmr(void) +{ + 800c0ec: b580 push {r7, lr} + 800c0ee: b084 sub sp, #16 + 800c0f0: af00 add r7, sp, #0 + struct ip_reassdata *r, *prev = NULL; + 800c0f2: 2300 movs r3, #0 + 800c0f4: 60bb str r3, [r7, #8] + + r = reassdatagrams; + 800c0f6: 4b13 ldr r3, [pc, #76] ; (800c144 ) + 800c0f8: 681b ldr r3, [r3, #0] + 800c0fa: 60fb str r3, [r7, #12] + while (r != NULL) { + 800c0fc: e01a b.n 800c134 + /* Decrement the timer. Once it reaches 0, + * clean up the incomplete fragment assembly */ + if (r->timer > 0) { + 800c0fe: 68fb ldr r3, [r7, #12] + 800c100: 7fdb ldrb r3, [r3, #31] + 800c102: 2b00 cmp r3, #0 + 800c104: d00b beq.n 800c11e + r->timer--; + 800c106: 68fb ldr r3, [r7, #12] + 800c108: 7fdb ldrb r3, [r3, #31] + 800c10a: 3b01 subs r3, #1 + 800c10c: b2da uxtb r2, r3 + 800c10e: 68fb ldr r3, [r7, #12] + 800c110: 77da strb r2, [r3, #31] + LWIP_DEBUGF(IP_REASS_DEBUG, ("ip_reass_tmr: timer dec %"U16_F"\n",(u16_t)r->timer)); + prev = r; + 800c112: 68fb ldr r3, [r7, #12] + 800c114: 60bb str r3, [r7, #8] + r = r->next; + 800c116: 68fb ldr r3, [r7, #12] + 800c118: 681b ldr r3, [r3, #0] + 800c11a: 60fb str r3, [r7, #12] + 800c11c: e00a b.n 800c134 + } else { + /* reassembly timed out */ + struct ip_reassdata *tmp; + LWIP_DEBUGF(IP_REASS_DEBUG, ("ip_reass_tmr: timer timed out\n")); + tmp = r; + 800c11e: 68fb ldr r3, [r7, #12] + 800c120: 607b str r3, [r7, #4] + /* get the next pointer before freeing */ + r = r->next; + 800c122: 68fb ldr r3, [r7, #12] + 800c124: 681b ldr r3, [r3, #0] + 800c126: 60fb str r3, [r7, #12] + /* free the helper struct and all enqueued pbufs */ + ip_reass_free_complete_datagram(tmp, prev); + 800c128: 68ba ldr r2, [r7, #8] + 800c12a: 687b ldr r3, [r7, #4] + 800c12c: 0011 movs r1, r2 + 800c12e: 0018 movs r0, r3 + 800c130: f000 f80a bl 800c148 + while (r != NULL) { + 800c134: 68fb ldr r3, [r7, #12] + 800c136: 2b00 cmp r3, #0 + 800c138: d1e1 bne.n 800c0fe + } + } +} + 800c13a: 46c0 nop ; (mov r8, r8) + 800c13c: 46bd mov sp, r7 + 800c13e: b004 add sp, #16 + 800c140: bd80 pop {r7, pc} + 800c142: 46c0 nop ; (mov r8, r8) + 800c144: 200022b8 .word 0x200022b8 + +0800c148 : + * @param prev the previous datagram in the linked list + * @return the number of pbufs freed + */ +static int +ip_reass_free_complete_datagram(struct ip_reassdata *ipr, struct ip_reassdata *prev) +{ + 800c148: b5b0 push {r4, r5, r7, lr} + 800c14a: b088 sub sp, #32 + 800c14c: af00 add r7, sp, #0 + 800c14e: 6078 str r0, [r7, #4] + 800c150: 6039 str r1, [r7, #0] + u16_t pbufs_freed = 0; + 800c152: 231e movs r3, #30 + 800c154: 18fb adds r3, r7, r3 + 800c156: 2200 movs r2, #0 + 800c158: 801a strh r2, [r3, #0] + LWIP_ASSERT("prev->next == ipr", prev->next == ipr); + } + + snmp_inc_ipreasmfails(); +#if LWIP_ICMP + iprh = (struct ip_reass_helper *)ipr->p->payload; + 800c15a: 687b ldr r3, [r7, #4] + 800c15c: 685b ldr r3, [r3, #4] + 800c15e: 685b ldr r3, [r3, #4] + 800c160: 617b str r3, [r7, #20] + if (iprh->start == 0) { + 800c162: 697b ldr r3, [r7, #20] + 800c164: 791a ldrb r2, [r3, #4] + 800c166: 795b ldrb r3, [r3, #5] + 800c168: 021b lsls r3, r3, #8 + 800c16a: 4313 orrs r3, r2 + 800c16c: b29b uxth r3, r3 + 800c16e: 2b00 cmp r3, #0 + 800c170: d132 bne.n 800c1d8 + /* The first fragment was received, send ICMP time exceeded. */ + /* First, de-queue the first pbuf from r->p. */ + p = ipr->p; + 800c172: 687b ldr r3, [r7, #4] + 800c174: 685b ldr r3, [r3, #4] + 800c176: 61bb str r3, [r7, #24] + ipr->p = iprh->next_pbuf; + 800c178: 697b ldr r3, [r7, #20] + 800c17a: 781a ldrb r2, [r3, #0] + 800c17c: 7859 ldrb r1, [r3, #1] + 800c17e: 0209 lsls r1, r1, #8 + 800c180: 430a orrs r2, r1 + 800c182: 7899 ldrb r1, [r3, #2] + 800c184: 0409 lsls r1, r1, #16 + 800c186: 430a orrs r2, r1 + 800c188: 78db ldrb r3, [r3, #3] + 800c18a: 061b lsls r3, r3, #24 + 800c18c: 4313 orrs r3, r2 + 800c18e: 001a movs r2, r3 + 800c190: 687b ldr r3, [r7, #4] + 800c192: 605a str r2, [r3, #4] + /* Then, copy the original header into it. */ + SMEMCPY(p->payload, &ipr->iphdr, IP_HLEN); + 800c194: 69bb ldr r3, [r7, #24] + 800c196: 6858 ldr r0, [r3, #4] + 800c198: 687b ldr r3, [r7, #4] + 800c19a: 3308 adds r3, #8 + 800c19c: 2214 movs r2, #20 + 800c19e: 0019 movs r1, r3 + 800c1a0: f003 fd7f bl 800fca2 + icmp_time_exceeded(p, ICMP_TE_FRAG); + 800c1a4: 69bb ldr r3, [r7, #24] + 800c1a6: 2101 movs r1, #1 + 800c1a8: 0018 movs r0, r3 + 800c1aa: f7ff f941 bl 800b430 + clen = pbuf_clen(p); + 800c1ae: 2513 movs r5, #19 + 800c1b0: 197c adds r4, r7, r5 + 800c1b2: 69bb ldr r3, [r7, #24] + 800c1b4: 0018 movs r0, r3 + 800c1b6: f7f9 fae7 bl 8005788 + 800c1ba: 0003 movs r3, r0 + 800c1bc: 7023 strb r3, [r4, #0] + LWIP_ASSERT("pbufs_freed + clen <= 0xffff", pbufs_freed + clen <= 0xffff); + pbufs_freed += clen; + 800c1be: 197b adds r3, r7, r5 + 800c1c0: 781b ldrb r3, [r3, #0] + 800c1c2: b299 uxth r1, r3 + 800c1c4: 221e movs r2, #30 + 800c1c6: 18bb adds r3, r7, r2 + 800c1c8: 18ba adds r2, r7, r2 + 800c1ca: 8812 ldrh r2, [r2, #0] + 800c1cc: 188a adds r2, r1, r2 + 800c1ce: 801a strh r2, [r3, #0] + pbuf_free(p); + 800c1d0: 69bb ldr r3, [r7, #24] + 800c1d2: 0018 movs r0, r3 + 800c1d4: f7f9 fa66 bl 80056a4 + } +#endif /* LWIP_ICMP */ + + /* First, free all received pbufs. The individual pbufs need to be released + separately as they have not yet been chained */ + p = ipr->p; + 800c1d8: 687b ldr r3, [r7, #4] + 800c1da: 685b ldr r3, [r3, #4] + 800c1dc: 61bb str r3, [r7, #24] + while (p != NULL) { + 800c1de: e026 b.n 800c22e + struct pbuf *pcur; + iprh = (struct ip_reass_helper *)p->payload; + 800c1e0: 69bb ldr r3, [r7, #24] + 800c1e2: 685b ldr r3, [r3, #4] + 800c1e4: 617b str r3, [r7, #20] + pcur = p; + 800c1e6: 69bb ldr r3, [r7, #24] + 800c1e8: 60fb str r3, [r7, #12] + /* get the next pointer before freeing */ + p = iprh->next_pbuf; + 800c1ea: 697b ldr r3, [r7, #20] + 800c1ec: 781a ldrb r2, [r3, #0] + 800c1ee: 7859 ldrb r1, [r3, #1] + 800c1f0: 0209 lsls r1, r1, #8 + 800c1f2: 430a orrs r2, r1 + 800c1f4: 7899 ldrb r1, [r3, #2] + 800c1f6: 0409 lsls r1, r1, #16 + 800c1f8: 430a orrs r2, r1 + 800c1fa: 78db ldrb r3, [r3, #3] + 800c1fc: 061b lsls r3, r3, #24 + 800c1fe: 4313 orrs r3, r2 + 800c200: 61bb str r3, [r7, #24] + clen = pbuf_clen(pcur); + 800c202: 2313 movs r3, #19 + 800c204: 18fc adds r4, r7, r3 + 800c206: 68fb ldr r3, [r7, #12] + 800c208: 0018 movs r0, r3 + 800c20a: f7f9 fabd bl 8005788 + 800c20e: 0003 movs r3, r0 + 800c210: 7023 strb r3, [r4, #0] + LWIP_ASSERT("pbufs_freed + clen <= 0xffff", pbufs_freed + clen <= 0xffff); + pbufs_freed += clen; + 800c212: 2313 movs r3, #19 + 800c214: 18fb adds r3, r7, r3 + 800c216: 781b ldrb r3, [r3, #0] + 800c218: b299 uxth r1, r3 + 800c21a: 221e movs r2, #30 + 800c21c: 18bb adds r3, r7, r2 + 800c21e: 18ba adds r2, r7, r2 + 800c220: 8812 ldrh r2, [r2, #0] + 800c222: 188a adds r2, r1, r2 + 800c224: 801a strh r2, [r3, #0] + pbuf_free(pcur); + 800c226: 68fb ldr r3, [r7, #12] + 800c228: 0018 movs r0, r3 + 800c22a: f7f9 fa3b bl 80056a4 + while (p != NULL) { + 800c22e: 69bb ldr r3, [r7, #24] + 800c230: 2b00 cmp r3, #0 + 800c232: d1d5 bne.n 800c1e0 + } + /* Then, unchain the struct ip_reassdata from the list and free it. */ + ip_reass_dequeue_datagram(ipr, prev); + 800c234: 683a ldr r2, [r7, #0] + 800c236: 687b ldr r3, [r7, #4] + 800c238: 0011 movs r1, r2 + 800c23a: 0018 movs r0, r3 + 800c23c: f000 f8ce bl 800c3dc + LWIP_ASSERT("ip_reass_pbufcount >= clen", ip_reass_pbufcount >= pbufs_freed); + ip_reass_pbufcount -= pbufs_freed; + 800c240: 4b07 ldr r3, [pc, #28] ; (800c260 ) + 800c242: 881a ldrh r2, [r3, #0] + 800c244: 211e movs r1, #30 + 800c246: 187b adds r3, r7, r1 + 800c248: 881b ldrh r3, [r3, #0] + 800c24a: 1ad3 subs r3, r2, r3 + 800c24c: b29a uxth r2, r3 + 800c24e: 4b04 ldr r3, [pc, #16] ; (800c260 ) + 800c250: 801a strh r2, [r3, #0] + + return pbufs_freed; + 800c252: 187b adds r3, r7, r1 + 800c254: 881b ldrh r3, [r3, #0] +} + 800c256: 0018 movs r0, r3 + 800c258: 46bd mov sp, r7 + 800c25a: b008 add sp, #32 + 800c25c: bdb0 pop {r4, r5, r7, pc} + 800c25e: 46c0 nop ; (mov r8, r8) + 800c260: 200022bc .word 0x200022bc + +0800c264 : + * (used for freeing other datagrams if not enough space) + * @return the number of pbufs freed + */ +static int +ip_reass_remove_oldest_datagram(struct ip_hdr *fraghdr, int pbufs_needed) +{ + 800c264: b580 push {r7, lr} + 800c266: b088 sub sp, #32 + 800c268: af00 add r7, sp, #0 + 800c26a: 6078 str r0, [r7, #4] + 800c26c: 6039 str r1, [r7, #0] + /* @todo Can't we simply remove the last datagram in the + * linked list behind reassdatagrams? + */ + struct ip_reassdata *r, *oldest, *prev; + int pbufs_freed = 0, pbufs_freed_current; + 800c26e: 2300 movs r3, #0 + 800c270: 613b str r3, [r7, #16] + int other_datagrams; + + /* Free datagrams until being allowed to enqueue 'pbufs_needed' pbufs, + * but don't free the datagram that 'fraghdr' belongs to! */ + do { + oldest = NULL; + 800c272: 2300 movs r3, #0 + 800c274: 61bb str r3, [r7, #24] + prev = NULL; + 800c276: 2300 movs r3, #0 + 800c278: 617b str r3, [r7, #20] + other_datagrams = 0; + 800c27a: 2300 movs r3, #0 + 800c27c: 60fb str r3, [r7, #12] + r = reassdatagrams; + 800c27e: 4b32 ldr r3, [pc, #200] ; (800c348 ) + 800c280: 681b ldr r3, [r3, #0] + 800c282: 61fb str r3, [r7, #28] + while (r != NULL) { + 800c284: e041 b.n 800c30a + if (!IP_ADDRESSES_AND_ID_MATCH(&r->iphdr, fraghdr)) { + 800c286: 69fb ldr r3, [r7, #28] + 800c288: 695a ldr r2, [r3, #20] + 800c28a: 687b ldr r3, [r7, #4] + 800c28c: 7b19 ldrb r1, [r3, #12] + 800c28e: 7b58 ldrb r0, [r3, #13] + 800c290: 0200 lsls r0, r0, #8 + 800c292: 4301 orrs r1, r0 + 800c294: 7b98 ldrb r0, [r3, #14] + 800c296: 0400 lsls r0, r0, #16 + 800c298: 4301 orrs r1, r0 + 800c29a: 7bdb ldrb r3, [r3, #15] + 800c29c: 061b lsls r3, r3, #24 + 800c29e: 430b orrs r3, r1 + 800c2a0: 429a cmp r2, r3 + 800c2a2: d118 bne.n 800c2d6 + 800c2a4: 69fb ldr r3, [r7, #28] + 800c2a6: 699a ldr r2, [r3, #24] + 800c2a8: 687b ldr r3, [r7, #4] + 800c2aa: 7c19 ldrb r1, [r3, #16] + 800c2ac: 7c58 ldrb r0, [r3, #17] + 800c2ae: 0200 lsls r0, r0, #8 + 800c2b0: 4301 orrs r1, r0 + 800c2b2: 7c98 ldrb r0, [r3, #18] + 800c2b4: 0400 lsls r0, r0, #16 + 800c2b6: 4301 orrs r1, r0 + 800c2b8: 7cdb ldrb r3, [r3, #19] + 800c2ba: 061b lsls r3, r3, #24 + 800c2bc: 430b orrs r3, r1 + 800c2be: 429a cmp r2, r3 + 800c2c0: d109 bne.n 800c2d6 + 800c2c2: 69fb ldr r3, [r7, #28] + 800c2c4: 899a ldrh r2, [r3, #12] + 800c2c6: 687b ldr r3, [r7, #4] + 800c2c8: 7919 ldrb r1, [r3, #4] + 800c2ca: 795b ldrb r3, [r3, #5] + 800c2cc: 021b lsls r3, r3, #8 + 800c2ce: 430b orrs r3, r1 + 800c2d0: b29b uxth r3, r3 + 800c2d2: 429a cmp r2, r3 + 800c2d4: d010 beq.n 800c2f8 + /* Not the same datagram as fraghdr */ + other_datagrams++; + 800c2d6: 68fb ldr r3, [r7, #12] + 800c2d8: 3301 adds r3, #1 + 800c2da: 60fb str r3, [r7, #12] + if (oldest == NULL) { + 800c2dc: 69bb ldr r3, [r7, #24] + 800c2de: 2b00 cmp r3, #0 + 800c2e0: d102 bne.n 800c2e8 + oldest = r; + 800c2e2: 69fb ldr r3, [r7, #28] + 800c2e4: 61bb str r3, [r7, #24] + 800c2e6: e007 b.n 800c2f8 + } else if (r->timer <= oldest->timer) { + 800c2e8: 69fb ldr r3, [r7, #28] + 800c2ea: 7fda ldrb r2, [r3, #31] + 800c2ec: 69bb ldr r3, [r7, #24] + 800c2ee: 7fdb ldrb r3, [r3, #31] + 800c2f0: 429a cmp r2, r3 + 800c2f2: d801 bhi.n 800c2f8 + /* older than the previous oldest */ + oldest = r; + 800c2f4: 69fb ldr r3, [r7, #28] + 800c2f6: 61bb str r3, [r7, #24] + } + } + if (r->next != NULL) { + 800c2f8: 69fb ldr r3, [r7, #28] + 800c2fa: 681b ldr r3, [r3, #0] + 800c2fc: 2b00 cmp r3, #0 + 800c2fe: d001 beq.n 800c304 + prev = r; + 800c300: 69fb ldr r3, [r7, #28] + 800c302: 617b str r3, [r7, #20] + } + r = r->next; + 800c304: 69fb ldr r3, [r7, #28] + 800c306: 681b ldr r3, [r3, #0] + 800c308: 61fb str r3, [r7, #28] + while (r != NULL) { + 800c30a: 69fb ldr r3, [r7, #28] + 800c30c: 2b00 cmp r3, #0 + 800c30e: d1ba bne.n 800c286 + } + if (oldest != NULL) { + 800c310: 69bb ldr r3, [r7, #24] + 800c312: 2b00 cmp r3, #0 + 800c314: d00b beq.n 800c32e + pbufs_freed_current = ip_reass_free_complete_datagram(oldest, prev); + 800c316: 697a ldr r2, [r7, #20] + 800c318: 69bb ldr r3, [r7, #24] + 800c31a: 0011 movs r1, r2 + 800c31c: 0018 movs r0, r3 + 800c31e: f7ff ff13 bl 800c148 + 800c322: 0003 movs r3, r0 + 800c324: 60bb str r3, [r7, #8] + pbufs_freed += pbufs_freed_current; + 800c326: 693a ldr r2, [r7, #16] + 800c328: 68bb ldr r3, [r7, #8] + 800c32a: 18d3 adds r3, r2, r3 + 800c32c: 613b str r3, [r7, #16] + } + } while ((pbufs_freed < pbufs_needed) && (other_datagrams > 1)); + 800c32e: 693a ldr r2, [r7, #16] + 800c330: 683b ldr r3, [r7, #0] + 800c332: 429a cmp r2, r3 + 800c334: da02 bge.n 800c33c + 800c336: 68fb ldr r3, [r7, #12] + 800c338: 2b01 cmp r3, #1 + 800c33a: dc9a bgt.n 800c272 + return pbufs_freed; + 800c33c: 693b ldr r3, [r7, #16] +} + 800c33e: 0018 movs r0, r3 + 800c340: 46bd mov sp, r7 + 800c342: b008 add sp, #32 + 800c344: bd80 pop {r7, pc} + 800c346: 46c0 nop ; (mov r8, r8) + 800c348: 200022b8 .word 0x200022b8 + +0800c34c : + * @param clen number of pbufs needed to enqueue (used for freeing other datagrams if not enough space) + * @return A pointer to the queue location into which the fragment was enqueued + */ +static struct ip_reassdata* +ip_reass_enqueue_new_datagram(struct ip_hdr *fraghdr, int clen) +{ + 800c34c: b580 push {r7, lr} + 800c34e: b084 sub sp, #16 + 800c350: af00 add r7, sp, #0 + 800c352: 6078 str r0, [r7, #4] + 800c354: 6039 str r1, [r7, #0] + struct ip_reassdata* ipr; + /* No matching previous fragment found, allocate a new reassdata struct */ + ipr = (struct ip_reassdata *)memp_malloc(MEMP_REASSDATA); + 800c356: 2005 movs r0, #5 + 800c358: f7f8 fd5c bl 8004e14 + 800c35c: 0003 movs r3, r0 + 800c35e: 60fb str r3, [r7, #12] + if (ipr == NULL) { + 800c360: 68fb ldr r3, [r7, #12] + 800c362: 2b00 cmp r3, #0 + 800c364: d119 bne.n 800c39a +#if IP_REASS_FREE_OLDEST + if (ip_reass_remove_oldest_datagram(fraghdr, clen) >= clen) { + 800c366: 683a ldr r2, [r7, #0] + 800c368: 687b ldr r3, [r7, #4] + 800c36a: 0011 movs r1, r2 + 800c36c: 0018 movs r0, r3 + 800c36e: f7ff ff79 bl 800c264 + 800c372: 0002 movs r2, r0 + 800c374: 683b ldr r3, [r7, #0] + 800c376: 4293 cmp r3, r2 + 800c378: dc04 bgt.n 800c384 + ipr = (struct ip_reassdata *)memp_malloc(MEMP_REASSDATA); + 800c37a: 2005 movs r0, #5 + 800c37c: f7f8 fd4a bl 8004e14 + 800c380: 0003 movs r3, r0 + 800c382: 60fb str r3, [r7, #12] + } + if (ipr == NULL) + 800c384: 68fb ldr r3, [r7, #12] + 800c386: 2b00 cmp r3, #0 + 800c388: d107 bne.n 800c39a +#endif /* IP_REASS_FREE_OLDEST */ + { + IPFRAG_STATS_INC(ip_frag.memerr); + 800c38a: 4b12 ldr r3, [pc, #72] ; (800c3d4 ) + 800c38c: 8f9b ldrh r3, [r3, #60] ; 0x3c + 800c38e: 3301 adds r3, #1 + 800c390: b29a uxth r2, r3 + 800c392: 4b10 ldr r3, [pc, #64] ; (800c3d4 ) + 800c394: 879a strh r2, [r3, #60] ; 0x3c + LWIP_DEBUGF(IP_REASS_DEBUG,("Failed to alloc reassdata struct\n")); + return NULL; + 800c396: 2300 movs r3, #0 + 800c398: e017 b.n 800c3ca + } + } + memset(ipr, 0, sizeof(struct ip_reassdata)); + 800c39a: 68fb ldr r3, [r7, #12] + 800c39c: 2220 movs r2, #32 + 800c39e: 2100 movs r1, #0 + 800c3a0: 0018 movs r0, r3 + 800c3a2: f003 fc87 bl 800fcb4 + ipr->timer = IP_REASS_MAXAGE; + 800c3a6: 68fb ldr r3, [r7, #12] + 800c3a8: 2203 movs r2, #3 + 800c3aa: 77da strb r2, [r3, #31] + + /* enqueue the new structure to the front of the list */ + ipr->next = reassdatagrams; + 800c3ac: 4b0a ldr r3, [pc, #40] ; (800c3d8 ) + 800c3ae: 681a ldr r2, [r3, #0] + 800c3b0: 68fb ldr r3, [r7, #12] + 800c3b2: 601a str r2, [r3, #0] + reassdatagrams = ipr; + 800c3b4: 4b08 ldr r3, [pc, #32] ; (800c3d8 ) + 800c3b6: 68fa ldr r2, [r7, #12] + 800c3b8: 601a str r2, [r3, #0] + /* copy the ip header for later tests and input */ + /* @todo: no ip options supported? */ + SMEMCPY(&(ipr->iphdr), fraghdr, IP_HLEN); + 800c3ba: 68fb ldr r3, [r7, #12] + 800c3bc: 3308 adds r3, #8 + 800c3be: 6879 ldr r1, [r7, #4] + 800c3c0: 2214 movs r2, #20 + 800c3c2: 0018 movs r0, r3 + 800c3c4: f003 fc6d bl 800fca2 + return ipr; + 800c3c8: 68fb ldr r3, [r7, #12] +} + 800c3ca: 0018 movs r0, r3 + 800c3cc: 46bd mov sp, r7 + 800c3ce: b004 add sp, #16 + 800c3d0: bd80 pop {r7, pc} + 800c3d2: 46c0 nop ; (mov r8, r8) + 800c3d4: 20003158 .word 0x20003158 + 800c3d8: 200022b8 .word 0x200022b8 + +0800c3dc : + * Dequeues a datagram from the datagram queue. Doesn't deallocate the pbufs. + * @param ipr points to the queue entry to dequeue + */ +static void +ip_reass_dequeue_datagram(struct ip_reassdata *ipr, struct ip_reassdata *prev) +{ + 800c3dc: b580 push {r7, lr} + 800c3de: b082 sub sp, #8 + 800c3e0: af00 add r7, sp, #0 + 800c3e2: 6078 str r0, [r7, #4] + 800c3e4: 6039 str r1, [r7, #0] + + /* dequeue the reass struct */ + if (reassdatagrams == ipr) { + 800c3e6: 4b0b ldr r3, [pc, #44] ; (800c414 ) + 800c3e8: 681b ldr r3, [r3, #0] + 800c3ea: 687a ldr r2, [r7, #4] + 800c3ec: 429a cmp r2, r3 + 800c3ee: d104 bne.n 800c3fa + /* it was the first in the list */ + reassdatagrams = ipr->next; + 800c3f0: 687b ldr r3, [r7, #4] + 800c3f2: 681a ldr r2, [r3, #0] + 800c3f4: 4b07 ldr r3, [pc, #28] ; (800c414 ) + 800c3f6: 601a str r2, [r3, #0] + 800c3f8: e003 b.n 800c402 + } else { + /* it wasn't the first, so it must have a valid 'prev' */ + LWIP_ASSERT("sanity check linked list", prev != NULL); + prev->next = ipr->next; + 800c3fa: 687b ldr r3, [r7, #4] + 800c3fc: 681a ldr r2, [r3, #0] + 800c3fe: 683b ldr r3, [r7, #0] + 800c400: 601a str r2, [r3, #0] + } + + /* now we can free the ip_reass struct */ + memp_free(MEMP_REASSDATA, ipr); + 800c402: 687b ldr r3, [r7, #4] + 800c404: 0019 movs r1, r3 + 800c406: 2005 movs r0, #5 + 800c408: f7f8 fd8a bl 8004f20 +} + 800c40c: 46c0 nop ; (mov r8, r8) + 800c40e: 46bd mov sp, r7 + 800c410: b002 add sp, #8 + 800c412: bd80 pop {r7, pc} + 800c414: 200022b8 .word 0x200022b8 + +0800c418 : + * @param new_p points to the pbuf for the current fragment + * @return 0 if invalid, >0 otherwise + */ +static int +ip_reass_chain_frag_into_datagram_and_validate(struct ip_reassdata *ipr, struct pbuf *new_p) +{ + 800c418: b5f0 push {r4, r5, r6, r7, lr} + 800c41a: b08b sub sp, #44 ; 0x2c + 800c41c: af00 add r7, sp, #0 + 800c41e: 6078 str r0, [r7, #4] + 800c420: 6039 str r1, [r7, #0] + struct ip_reass_helper *iprh, *iprh_tmp, *iprh_prev=NULL; + 800c422: 2300 movs r3, #0 + 800c424: 623b str r3, [r7, #32] + struct pbuf *q; + u16_t offset,len; + struct ip_hdr *fraghdr; + int valid = 1; + 800c426: 2301 movs r3, #1 + 800c428: 61bb str r3, [r7, #24] + + /* Extract length and fragment offset from current fragment */ + fraghdr = (struct ip_hdr*)new_p->payload; + 800c42a: 683b ldr r3, [r7, #0] + 800c42c: 685b ldr r3, [r3, #4] + 800c42e: 617b str r3, [r7, #20] + len = ntohs(IPH_LEN(fraghdr)) - IPH_HL(fraghdr) * 4; + 800c430: 697b ldr r3, [r7, #20] + 800c432: 789a ldrb r2, [r3, #2] + 800c434: 78db ldrb r3, [r3, #3] + 800c436: 021b lsls r3, r3, #8 + 800c438: 4313 orrs r3, r2 + 800c43a: b29b uxth r3, r3 + 800c43c: 0018 movs r0, r3 + 800c43e: f7f8 f8ff bl 8004640 + 800c442: 0003 movs r3, r0 + 800c444: 0019 movs r1, r3 + 800c446: 697b ldr r3, [r7, #20] + 800c448: 781b ldrb r3, [r3, #0] + 800c44a: b29b uxth r3, r3 + 800c44c: 220f movs r2, #15 + 800c44e: 4013 ands r3, r2 + 800c450: b29b uxth r3, r3 + 800c452: 009b lsls r3, r3, #2 + 800c454: b29a uxth r2, r3 + 800c456: 2612 movs r6, #18 + 800c458: 19bb adds r3, r7, r6 + 800c45a: 1a8a subs r2, r1, r2 + 800c45c: 801a strh r2, [r3, #0] + offset = (ntohs(IPH_OFFSET(fraghdr)) & IP_OFFMASK) * 8; + 800c45e: 697b ldr r3, [r7, #20] + 800c460: 799a ldrb r2, [r3, #6] + 800c462: 79db ldrb r3, [r3, #7] + 800c464: 021b lsls r3, r3, #8 + 800c466: 4313 orrs r3, r2 + 800c468: b29b uxth r3, r3 + 800c46a: 0018 movs r0, r3 + 800c46c: f7f8 f8e8 bl 8004640 + 800c470: 0003 movs r3, r0 + 800c472: 04db lsls r3, r3, #19 + 800c474: 0cdb lsrs r3, r3, #19 + 800c476: b29a uxth r2, r3 + 800c478: 2010 movs r0, #16 + 800c47a: 183b adds r3, r7, r0 + 800c47c: 00d2 lsls r2, r2, #3 + 800c47e: 801a strh r2, [r3, #0] + /* overwrite the fragment's ip header from the pbuf with our helper struct, + * and setup the embedded helper structure. */ + /* make sure the struct ip_reass_helper fits into the IP header */ + LWIP_ASSERT("sizeof(struct ip_reass_helper) <= IP_HLEN", + sizeof(struct ip_reass_helper) <= IP_HLEN); + iprh = (struct ip_reass_helper*)new_p->payload; + 800c480: 683b ldr r3, [r7, #0] + 800c482: 685b ldr r3, [r3, #4] + 800c484: 627b str r3, [r7, #36] ; 0x24 + iprh->next_pbuf = NULL; + 800c486: 6a7b ldr r3, [r7, #36] ; 0x24 + 800c488: 781a ldrb r2, [r3, #0] + 800c48a: 2100 movs r1, #0 + 800c48c: 400a ands r2, r1 + 800c48e: 701a strb r2, [r3, #0] + 800c490: 785a ldrb r2, [r3, #1] + 800c492: 2100 movs r1, #0 + 800c494: 400a ands r2, r1 + 800c496: 705a strb r2, [r3, #1] + 800c498: 789a ldrb r2, [r3, #2] + 800c49a: 2100 movs r1, #0 + 800c49c: 400a ands r2, r1 + 800c49e: 709a strb r2, [r3, #2] + 800c4a0: 78da ldrb r2, [r3, #3] + 800c4a2: 2100 movs r1, #0 + 800c4a4: 400a ands r2, r1 + 800c4a6: 70da strb r2, [r3, #3] + iprh->start = offset; + 800c4a8: 6a7b ldr r3, [r7, #36] ; 0x24 + 800c4aa: 0005 movs r5, r0 + 800c4ac: 183a adds r2, r7, r0 + 800c4ae: 7814 ldrb r4, [r2, #0] + 800c4b0: 7919 ldrb r1, [r3, #4] + 800c4b2: 2000 movs r0, #0 + 800c4b4: 4001 ands r1, r0 + 800c4b6: 1c08 adds r0, r1, #0 + 800c4b8: 1c21 adds r1, r4, #0 + 800c4ba: 4301 orrs r1, r0 + 800c4bc: 7119 strb r1, [r3, #4] + 800c4be: 7850 ldrb r0, [r2, #1] + 800c4c0: 795a ldrb r2, [r3, #5] + 800c4c2: 2100 movs r1, #0 + 800c4c4: 400a ands r2, r1 + 800c4c6: 1c11 adds r1, r2, #0 + 800c4c8: 1c02 adds r2, r0, #0 + 800c4ca: 430a orrs r2, r1 + 800c4cc: 715a strb r2, [r3, #5] + iprh->end = offset + len; + 800c4ce: 0028 movs r0, r5 + 800c4d0: 183a adds r2, r7, r0 + 800c4d2: 19bb adds r3, r7, r6 + 800c4d4: 8812 ldrh r2, [r2, #0] + 800c4d6: 881b ldrh r3, [r3, #0] + 800c4d8: 18d3 adds r3, r2, r3 + 800c4da: b29a uxth r2, r3 + 800c4dc: 6a7b ldr r3, [r7, #36] ; 0x24 + 800c4de: 21ff movs r1, #255 ; 0xff + 800c4e0: 4011 ands r1, r2 + 800c4e2: 000c movs r4, r1 + 800c4e4: 7999 ldrb r1, [r3, #6] + 800c4e6: 2000 movs r0, #0 + 800c4e8: 4001 ands r1, r0 + 800c4ea: 1c08 adds r0, r1, #0 + 800c4ec: 1c21 adds r1, r4, #0 + 800c4ee: 4301 orrs r1, r0 + 800c4f0: 7199 strb r1, [r3, #6] + 800c4f2: 0a12 lsrs r2, r2, #8 + 800c4f4: b290 uxth r0, r2 + 800c4f6: 79da ldrb r2, [r3, #7] + 800c4f8: 2100 movs r1, #0 + 800c4fa: 400a ands r2, r1 + 800c4fc: 1c11 adds r1, r2, #0 + 800c4fe: 1c02 adds r2, r0, #0 + 800c500: 430a orrs r2, r1 + 800c502: 71da strb r2, [r3, #7] + + /* Iterate through until we either get to the end of the list (append), + * or we find on with a larger offset (insert). */ + for (q = ipr->p; q != NULL;) { + 800c504: 687b ldr r3, [r7, #4] + 800c506: 685b ldr r3, [r3, #4] + 800c508: 61fb str r3, [r7, #28] + 800c50a: e0c3 b.n 800c694 + iprh_tmp = (struct ip_reass_helper*)q->payload; + 800c50c: 69fb ldr r3, [r7, #28] + 800c50e: 685b ldr r3, [r3, #4] + 800c510: 60fb str r3, [r7, #12] + if (iprh->start < iprh_tmp->start) { + 800c512: 6a7b ldr r3, [r7, #36] ; 0x24 + 800c514: 791a ldrb r2, [r3, #4] + 800c516: 795b ldrb r3, [r3, #5] + 800c518: 021b lsls r3, r3, #8 + 800c51a: 4313 orrs r3, r2 + 800c51c: b29a uxth r2, r3 + 800c51e: 68fb ldr r3, [r7, #12] + 800c520: 7919 ldrb r1, [r3, #4] + 800c522: 795b ldrb r3, [r3, #5] + 800c524: 021b lsls r3, r3, #8 + 800c526: 430b orrs r3, r1 + 800c528: b29b uxth r3, r3 + 800c52a: 429a cmp r2, r3 + 800c52c: d273 bcs.n 800c616 + /* the new pbuf should be inserted before this */ + iprh->next_pbuf = q; + 800c52e: 6a7b ldr r3, [r7, #36] ; 0x24 + 800c530: 221c movs r2, #28 + 800c532: 18ba adds r2, r7, r2 + 800c534: 7810 ldrb r0, [r2, #0] + 800c536: 781a ldrb r2, [r3, #0] + 800c538: 2100 movs r1, #0 + 800c53a: 400a ands r2, r1 + 800c53c: 1c11 adds r1, r2, #0 + 800c53e: 1c02 adds r2, r0, #0 + 800c540: 430a orrs r2, r1 + 800c542: 701a strb r2, [r3, #0] + 800c544: 221d movs r2, #29 + 800c546: 18ba adds r2, r7, r2 + 800c548: 7810 ldrb r0, [r2, #0] + 800c54a: 785a ldrb r2, [r3, #1] + 800c54c: 2100 movs r1, #0 + 800c54e: 400a ands r2, r1 + 800c550: 1c11 adds r1, r2, #0 + 800c552: 1c02 adds r2, r0, #0 + 800c554: 430a orrs r2, r1 + 800c556: 705a strb r2, [r3, #1] + 800c558: 221e movs r2, #30 + 800c55a: 18ba adds r2, r7, r2 + 800c55c: 7810 ldrb r0, [r2, #0] + 800c55e: 789a ldrb r2, [r3, #2] + 800c560: 2100 movs r1, #0 + 800c562: 400a ands r2, r1 + 800c564: 1c11 adds r1, r2, #0 + 800c566: 1c02 adds r2, r0, #0 + 800c568: 430a orrs r2, r1 + 800c56a: 709a strb r2, [r3, #2] + 800c56c: 221f movs r2, #31 + 800c56e: 18ba adds r2, r7, r2 + 800c570: 7810 ldrb r0, [r2, #0] + 800c572: 78da ldrb r2, [r3, #3] + 800c574: 2100 movs r1, #0 + 800c576: 400a ands r2, r1 + 800c578: 1c11 adds r1, r2, #0 + 800c57a: 1c02 adds r2, r0, #0 + 800c57c: 430a orrs r2, r1 + 800c57e: 70da strb r2, [r3, #3] + if (iprh_prev != NULL) { + 800c580: 6a3b ldr r3, [r7, #32] + 800c582: 2b00 cmp r3, #0 + 800c584: d043 beq.n 800c60e + /* not the fragment with the lowest offset */ +#if IP_REASS_CHECK_OVERLAP + if ((iprh->start < iprh_prev->end) || (iprh->end > iprh_tmp->start)) { + 800c586: 6a7b ldr r3, [r7, #36] ; 0x24 + 800c588: 791a ldrb r2, [r3, #4] + 800c58a: 795b ldrb r3, [r3, #5] + 800c58c: 021b lsls r3, r3, #8 + 800c58e: 4313 orrs r3, r2 + 800c590: b29a uxth r2, r3 + 800c592: 6a3b ldr r3, [r7, #32] + 800c594: 7999 ldrb r1, [r3, #6] + 800c596: 79db ldrb r3, [r3, #7] + 800c598: 021b lsls r3, r3, #8 + 800c59a: 430b orrs r3, r1 + 800c59c: b29b uxth r3, r3 + 800c59e: 429a cmp r2, r3 + 800c5a0: d200 bcs.n 800c5a4 + 800c5a2: e108 b.n 800c7b6 + 800c5a4: 6a7b ldr r3, [r7, #36] ; 0x24 + 800c5a6: 799a ldrb r2, [r3, #6] + 800c5a8: 79db ldrb r3, [r3, #7] + 800c5aa: 021b lsls r3, r3, #8 + 800c5ac: 4313 orrs r3, r2 + 800c5ae: b29a uxth r2, r3 + 800c5b0: 68fb ldr r3, [r7, #12] + 800c5b2: 7919 ldrb r1, [r3, #4] + 800c5b4: 795b ldrb r3, [r3, #5] + 800c5b6: 021b lsls r3, r3, #8 + 800c5b8: 430b orrs r3, r1 + 800c5ba: b29b uxth r3, r3 + 800c5bc: 429a cmp r2, r3 + 800c5be: d900 bls.n 800c5c2 + 800c5c0: e0f9 b.n 800c7b6 + /* fragment overlaps with previous or following, throw away */ + goto freepbuf; + } +#endif /* IP_REASS_CHECK_OVERLAP */ + iprh_prev->next_pbuf = new_p; + 800c5c2: 6a3b ldr r3, [r7, #32] + 800c5c4: 003a movs r2, r7 + 800c5c6: 7810 ldrb r0, [r2, #0] + 800c5c8: 781a ldrb r2, [r3, #0] + 800c5ca: 2100 movs r1, #0 + 800c5cc: 400a ands r2, r1 + 800c5ce: 1c11 adds r1, r2, #0 + 800c5d0: 1c02 adds r2, r0, #0 + 800c5d2: 430a orrs r2, r1 + 800c5d4: 701a strb r2, [r3, #0] + 800c5d6: 1c7a adds r2, r7, #1 + 800c5d8: 7810 ldrb r0, [r2, #0] + 800c5da: 785a ldrb r2, [r3, #1] + 800c5dc: 2100 movs r1, #0 + 800c5de: 400a ands r2, r1 + 800c5e0: 1c11 adds r1, r2, #0 + 800c5e2: 1c02 adds r2, r0, #0 + 800c5e4: 430a orrs r2, r1 + 800c5e6: 705a strb r2, [r3, #1] + 800c5e8: 1cba adds r2, r7, #2 + 800c5ea: 7810 ldrb r0, [r2, #0] + 800c5ec: 789a ldrb r2, [r3, #2] + 800c5ee: 2100 movs r1, #0 + 800c5f0: 400a ands r2, r1 + 800c5f2: 1c11 adds r1, r2, #0 + 800c5f4: 1c02 adds r2, r0, #0 + 800c5f6: 430a orrs r2, r1 + 800c5f8: 709a strb r2, [r3, #2] + 800c5fa: 1cfa adds r2, r7, #3 + 800c5fc: 7810 ldrb r0, [r2, #0] + 800c5fe: 78da ldrb r2, [r3, #3] + 800c600: 2100 movs r1, #0 + 800c602: 400a ands r2, r1 + 800c604: 1c11 adds r1, r2, #0 + 800c606: 1c02 adds r2, r0, #0 + 800c608: 430a orrs r2, r1 + 800c60a: 70da strb r2, [r3, #3] + } else { + /* fragment with the lowest offset */ + ipr->p = new_p; + } + break; + 800c60c: e046 b.n 800c69c + ipr->p = new_p; + 800c60e: 687b ldr r3, [r7, #4] + 800c610: 683a ldr r2, [r7, #0] + 800c612: 605a str r2, [r3, #4] + break; + 800c614: e042 b.n 800c69c + } else if(iprh->start == iprh_tmp->start) { + 800c616: 6a7b ldr r3, [r7, #36] ; 0x24 + 800c618: 791a ldrb r2, [r3, #4] + 800c61a: 795b ldrb r3, [r3, #5] + 800c61c: 021b lsls r3, r3, #8 + 800c61e: 4313 orrs r3, r2 + 800c620: b29a uxth r2, r3 + 800c622: 68fb ldr r3, [r7, #12] + 800c624: 7919 ldrb r1, [r3, #4] + 800c626: 795b ldrb r3, [r3, #5] + 800c628: 021b lsls r3, r3, #8 + 800c62a: 430b orrs r3, r1 + 800c62c: b29b uxth r3, r3 + 800c62e: 429a cmp r2, r3 + 800c630: d100 bne.n 800c634 + 800c632: e0c2 b.n 800c7ba + /* received the same datagram twice: no need to keep the datagram */ + goto freepbuf; +#if IP_REASS_CHECK_OVERLAP + } else if(iprh->start < iprh_tmp->end) { + 800c634: 6a7b ldr r3, [r7, #36] ; 0x24 + 800c636: 791a ldrb r2, [r3, #4] + 800c638: 795b ldrb r3, [r3, #5] + 800c63a: 021b lsls r3, r3, #8 + 800c63c: 4313 orrs r3, r2 + 800c63e: b29a uxth r2, r3 + 800c640: 68fb ldr r3, [r7, #12] + 800c642: 7999 ldrb r1, [r3, #6] + 800c644: 79db ldrb r3, [r3, #7] + 800c646: 021b lsls r3, r3, #8 + 800c648: 430b orrs r3, r1 + 800c64a: b29b uxth r3, r3 + 800c64c: 429a cmp r2, r3 + 800c64e: d200 bcs.n 800c652 + 800c650: e0b5 b.n 800c7be + /* overlap: no need to keep the new datagram */ + goto freepbuf; +#endif /* IP_REASS_CHECK_OVERLAP */ + } else { + /* Check if the fragments received so far have no wholes. */ + if (iprh_prev != NULL) { + 800c652: 6a3b ldr r3, [r7, #32] + 800c654: 2b00 cmp r3, #0 + 800c656: d00f beq.n 800c678 + if (iprh_prev->end != iprh_tmp->start) { + 800c658: 6a3b ldr r3, [r7, #32] + 800c65a: 799a ldrb r2, [r3, #6] + 800c65c: 79db ldrb r3, [r3, #7] + 800c65e: 021b lsls r3, r3, #8 + 800c660: 4313 orrs r3, r2 + 800c662: b29a uxth r2, r3 + 800c664: 68fb ldr r3, [r7, #12] + 800c666: 7919 ldrb r1, [r3, #4] + 800c668: 795b ldrb r3, [r3, #5] + 800c66a: 021b lsls r3, r3, #8 + 800c66c: 430b orrs r3, r1 + 800c66e: b29b uxth r3, r3 + 800c670: 429a cmp r2, r3 + 800c672: d001 beq.n 800c678 + /* There is a fragment missing between the current + * and the previous fragment */ + valid = 0; + 800c674: 2300 movs r3, #0 + 800c676: 61bb str r3, [r7, #24] + } + } + } + q = iprh_tmp->next_pbuf; + 800c678: 68fb ldr r3, [r7, #12] + 800c67a: 781a ldrb r2, [r3, #0] + 800c67c: 7859 ldrb r1, [r3, #1] + 800c67e: 0209 lsls r1, r1, #8 + 800c680: 430a orrs r2, r1 + 800c682: 7899 ldrb r1, [r3, #2] + 800c684: 0409 lsls r1, r1, #16 + 800c686: 430a orrs r2, r1 + 800c688: 78db ldrb r3, [r3, #3] + 800c68a: 061b lsls r3, r3, #24 + 800c68c: 4313 orrs r3, r2 + 800c68e: 61fb str r3, [r7, #28] + iprh_prev = iprh_tmp; + 800c690: 68fb ldr r3, [r7, #12] + 800c692: 623b str r3, [r7, #32] + for (q = ipr->p; q != NULL;) { + 800c694: 69fb ldr r3, [r7, #28] + 800c696: 2b00 cmp r3, #0 + 800c698: d000 beq.n 800c69c + 800c69a: e737 b.n 800c50c + } + + /* If q is NULL, then we made it to the end of the list. Determine what to do now */ + if (q == NULL) { + 800c69c: 69fb ldr r3, [r7, #28] + 800c69e: 2b00 cmp r3, #0 + 800c6a0: d13b bne.n 800c71a + if (iprh_prev != NULL) { + 800c6a2: 6a3b ldr r3, [r7, #32] + 800c6a4: 2b00 cmp r3, #0 + 800c6a6: d035 beq.n 800c714 + /* this is (for now), the fragment with the highest offset: + * chain it to the last fragment */ +#if IP_REASS_CHECK_OVERLAP + LWIP_ASSERT("check fragments don't overlap", iprh_prev->end <= iprh->start); +#endif /* IP_REASS_CHECK_OVERLAP */ + iprh_prev->next_pbuf = new_p; + 800c6a8: 6a3b ldr r3, [r7, #32] + 800c6aa: 003a movs r2, r7 + 800c6ac: 7810 ldrb r0, [r2, #0] + 800c6ae: 781a ldrb r2, [r3, #0] + 800c6b0: 2100 movs r1, #0 + 800c6b2: 400a ands r2, r1 + 800c6b4: 1c11 adds r1, r2, #0 + 800c6b6: 1c02 adds r2, r0, #0 + 800c6b8: 430a orrs r2, r1 + 800c6ba: 701a strb r2, [r3, #0] + 800c6bc: 1c7a adds r2, r7, #1 + 800c6be: 7810 ldrb r0, [r2, #0] + 800c6c0: 785a ldrb r2, [r3, #1] + 800c6c2: 2100 movs r1, #0 + 800c6c4: 400a ands r2, r1 + 800c6c6: 1c11 adds r1, r2, #0 + 800c6c8: 1c02 adds r2, r0, #0 + 800c6ca: 430a orrs r2, r1 + 800c6cc: 705a strb r2, [r3, #1] + 800c6ce: 1cba adds r2, r7, #2 + 800c6d0: 7810 ldrb r0, [r2, #0] + 800c6d2: 789a ldrb r2, [r3, #2] + 800c6d4: 2100 movs r1, #0 + 800c6d6: 400a ands r2, r1 + 800c6d8: 1c11 adds r1, r2, #0 + 800c6da: 1c02 adds r2, r0, #0 + 800c6dc: 430a orrs r2, r1 + 800c6de: 709a strb r2, [r3, #2] + 800c6e0: 1cfa adds r2, r7, #3 + 800c6e2: 7810 ldrb r0, [r2, #0] + 800c6e4: 78da ldrb r2, [r3, #3] + 800c6e6: 2100 movs r1, #0 + 800c6e8: 400a ands r2, r1 + 800c6ea: 1c11 adds r1, r2, #0 + 800c6ec: 1c02 adds r2, r0, #0 + 800c6ee: 430a orrs r2, r1 + 800c6f0: 70da strb r2, [r3, #3] + if (iprh_prev->end != iprh->start) { + 800c6f2: 6a3b ldr r3, [r7, #32] + 800c6f4: 799a ldrb r2, [r3, #6] + 800c6f6: 79db ldrb r3, [r3, #7] + 800c6f8: 021b lsls r3, r3, #8 + 800c6fa: 4313 orrs r3, r2 + 800c6fc: b29a uxth r2, r3 + 800c6fe: 6a7b ldr r3, [r7, #36] ; 0x24 + 800c700: 7919 ldrb r1, [r3, #4] + 800c702: 795b ldrb r3, [r3, #5] + 800c704: 021b lsls r3, r3, #8 + 800c706: 430b orrs r3, r1 + 800c708: b29b uxth r3, r3 + 800c70a: 429a cmp r2, r3 + 800c70c: d005 beq.n 800c71a + valid = 0; + 800c70e: 2300 movs r3, #0 + 800c710: 61bb str r3, [r7, #24] + 800c712: e002 b.n 800c71a +#if IP_REASS_CHECK_OVERLAP + LWIP_ASSERT("no previous fragment, this must be the first fragment!", + ipr->p == NULL); +#endif /* IP_REASS_CHECK_OVERLAP */ + /* this is the first fragment we ever received for this ip datagram */ + ipr->p = new_p; + 800c714: 687b ldr r3, [r7, #4] + 800c716: 683a ldr r2, [r7, #0] + 800c718: 605a str r2, [r3, #4] + } + } + + /* At this point, the validation part begins: */ + /* If we already received the last fragment */ + if ((ipr->flags & IP_REASS_FLAG_LASTFRAG) != 0) { + 800c71a: 687b ldr r3, [r7, #4] + 800c71c: 7f9b ldrb r3, [r3, #30] + 800c71e: 001a movs r2, r3 + 800c720: 2301 movs r3, #1 + 800c722: 4013 ands r3, r2 + 800c724: d045 beq.n 800c7b2 + /* and had no wholes so far */ + if (valid) { + 800c726: 69bb ldr r3, [r7, #24] + 800c728: 2b00 cmp r3, #0 + 800c72a: d040 beq.n 800c7ae + /* then check if the rest of the fragments is here */ + /* Check if the queue starts with the first datagram */ + if (((struct ip_reass_helper*)ipr->p->payload)->start != 0) { + 800c72c: 687b ldr r3, [r7, #4] + 800c72e: 685b ldr r3, [r3, #4] + 800c730: 685b ldr r3, [r3, #4] + 800c732: 791a ldrb r2, [r3, #4] + 800c734: 795b ldrb r3, [r3, #5] + 800c736: 021b lsls r3, r3, #8 + 800c738: 4313 orrs r3, r2 + 800c73a: b29b uxth r3, r3 + 800c73c: 2b00 cmp r3, #0 + 800c73e: d002 beq.n 800c746 + valid = 0; + 800c740: 2300 movs r3, #0 + 800c742: 61bb str r3, [r7, #24] + 800c744: e033 b.n 800c7ae + } else { + /* and check that there are no wholes after this datagram */ + iprh_prev = iprh; + 800c746: 6a7b ldr r3, [r7, #36] ; 0x24 + 800c748: 623b str r3, [r7, #32] + q = iprh->next_pbuf; + 800c74a: 6a7b ldr r3, [r7, #36] ; 0x24 + 800c74c: 781a ldrb r2, [r3, #0] + 800c74e: 7859 ldrb r1, [r3, #1] + 800c750: 0209 lsls r1, r1, #8 + 800c752: 430a orrs r2, r1 + 800c754: 7899 ldrb r1, [r3, #2] + 800c756: 0409 lsls r1, r1, #16 + 800c758: 430a orrs r2, r1 + 800c75a: 78db ldrb r3, [r3, #3] + 800c75c: 061b lsls r3, r3, #24 + 800c75e: 4313 orrs r3, r2 + 800c760: 61fb str r3, [r7, #28] + while (q != NULL) { + 800c762: e021 b.n 800c7a8 + iprh = (struct ip_reass_helper*)q->payload; + 800c764: 69fb ldr r3, [r7, #28] + 800c766: 685b ldr r3, [r3, #4] + 800c768: 627b str r3, [r7, #36] ; 0x24 + if (iprh_prev->end != iprh->start) { + 800c76a: 6a3b ldr r3, [r7, #32] + 800c76c: 799a ldrb r2, [r3, #6] + 800c76e: 79db ldrb r3, [r3, #7] + 800c770: 021b lsls r3, r3, #8 + 800c772: 4313 orrs r3, r2 + 800c774: b29a uxth r2, r3 + 800c776: 6a7b ldr r3, [r7, #36] ; 0x24 + 800c778: 7919 ldrb r1, [r3, #4] + 800c77a: 795b ldrb r3, [r3, #5] + 800c77c: 021b lsls r3, r3, #8 + 800c77e: 430b orrs r3, r1 + 800c780: b29b uxth r3, r3 + 800c782: 429a cmp r2, r3 + 800c784: d002 beq.n 800c78c + valid = 0; + 800c786: 2300 movs r3, #0 + 800c788: 61bb str r3, [r7, #24] + break; + 800c78a: e010 b.n 800c7ae + } + iprh_prev = iprh; + 800c78c: 6a7b ldr r3, [r7, #36] ; 0x24 + 800c78e: 623b str r3, [r7, #32] + q = iprh->next_pbuf; + 800c790: 6a7b ldr r3, [r7, #36] ; 0x24 + 800c792: 781a ldrb r2, [r3, #0] + 800c794: 7859 ldrb r1, [r3, #1] + 800c796: 0209 lsls r1, r1, #8 + 800c798: 430a orrs r2, r1 + 800c79a: 7899 ldrb r1, [r3, #2] + 800c79c: 0409 lsls r1, r1, #16 + 800c79e: 430a orrs r2, r1 + 800c7a0: 78db ldrb r3, [r3, #3] + 800c7a2: 061b lsls r3, r3, #24 + 800c7a4: 4313 orrs r3, r2 + 800c7a6: 61fb str r3, [r7, #28] + while (q != NULL) { + 800c7a8: 69fb ldr r3, [r7, #28] + 800c7aa: 2b00 cmp r3, #0 + 800c7ac: d1da bne.n 800c764 + } + } + /* If valid is 0 here, there are some fragments missing in the middle + * (since MF == 0 has already arrived). Such datagrams simply time out if + * no more fragments are received... */ + return valid; + 800c7ae: 69bb ldr r3, [r7, #24] + 800c7b0: e018 b.n 800c7e4 + } + /* If we come here, not all fragments were received, yet! */ + return 0; /* not yet valid! */ + 800c7b2: 2300 movs r3, #0 + 800c7b4: e016 b.n 800c7e4 +#if IP_REASS_CHECK_OVERLAP +freepbuf: + 800c7b6: 46c0 nop ; (mov r8, r8) + 800c7b8: e002 b.n 800c7c0 + goto freepbuf; + 800c7ba: 46c0 nop ; (mov r8, r8) + 800c7bc: e000 b.n 800c7c0 + goto freepbuf; + 800c7be: 46c0 nop ; (mov r8, r8) + ip_reass_pbufcount -= pbuf_clen(new_p); + 800c7c0: 683b ldr r3, [r7, #0] + 800c7c2: 0018 movs r0, r3 + 800c7c4: f7f8 ffe0 bl 8005788 + 800c7c8: 0003 movs r3, r0 + 800c7ca: 0019 movs r1, r3 + 800c7cc: 4b07 ldr r3, [pc, #28] ; (800c7ec ) + 800c7ce: 881a ldrh r2, [r3, #0] + 800c7d0: b28b uxth r3, r1 + 800c7d2: 1ad3 subs r3, r2, r3 + 800c7d4: b29a uxth r2, r3 + 800c7d6: 4b05 ldr r3, [pc, #20] ; (800c7ec ) + 800c7d8: 801a strh r2, [r3, #0] + pbuf_free(new_p); + 800c7da: 683b ldr r3, [r7, #0] + 800c7dc: 0018 movs r0, r3 + 800c7de: f7f8 ff61 bl 80056a4 + return 0; + 800c7e2: 2300 movs r3, #0 +#endif /* IP_REASS_CHECK_OVERLAP */ +} + 800c7e4: 0018 movs r0, r3 + 800c7e6: 46bd mov sp, r7 + 800c7e8: b00b add sp, #44 ; 0x2c + 800c7ea: bdf0 pop {r4, r5, r6, r7, pc} + 800c7ec: 200022bc .word 0x200022bc + +0800c7f0 : + * @param p points to a pbuf chain of the fragment + * @return NULL if reassembly is incomplete, ? otherwise + */ +struct pbuf * +ip_reass(struct pbuf *p) +{ + 800c7f0: b5b0 push {r4, r5, r7, lr} + 800c7f2: b08a sub sp, #40 ; 0x28 + 800c7f4: af00 add r7, sp, #0 + 800c7f6: 6078 str r0, [r7, #4] + struct ip_hdr *fraghdr; + struct ip_reassdata *ipr; + struct ip_reass_helper *iprh; + u16_t offset, len; + u8_t clen; + struct ip_reassdata *ipr_prev = NULL; + 800c7f8: 2300 movs r3, #0 + 800c7fa: 61fb str r3, [r7, #28] + + IPFRAG_STATS_INC(ip_frag.recv); + 800c7fc: 4bd3 ldr r3, [pc, #844] ; (800cb4c ) + 800c7fe: 8e5b ldrh r3, [r3, #50] ; 0x32 + 800c800: 3301 adds r3, #1 + 800c802: b29a uxth r2, r3 + 800c804: 4bd1 ldr r3, [pc, #836] ; (800cb4c ) + 800c806: 865a strh r2, [r3, #50] ; 0x32 + snmp_inc_ipreasmreqds(); + + fraghdr = (struct ip_hdr*)p->payload; + 800c808: 687b ldr r3, [r7, #4] + 800c80a: 685b ldr r3, [r3, #4] + 800c80c: 61bb str r3, [r7, #24] + + if ((IPH_HL(fraghdr) * 4) != IP_HLEN) { + 800c80e: 69bb ldr r3, [r7, #24] + 800c810: 781b ldrb r3, [r3, #0] + 800c812: 001a movs r2, r3 + 800c814: 230f movs r3, #15 + 800c816: 4013 ands r3, r2 + 800c818: 009b lsls r3, r3, #2 + 800c81a: 2b14 cmp r3, #20 + 800c81c: d008 beq.n 800c830 + LWIP_DEBUGF(IP_REASS_DEBUG,("ip_reass: IP options currently not supported!\n")); + IPFRAG_STATS_INC(ip_frag.err); + 800c81e: 4bcb ldr r3, [pc, #812] ; (800cb4c ) + 800c820: 2244 movs r2, #68 ; 0x44 + 800c822: 5a9b ldrh r3, [r3, r2] + 800c824: 3301 adds r3, #1 + 800c826: b299 uxth r1, r3 + 800c828: 4bc8 ldr r3, [pc, #800] ; (800cb4c ) + 800c82a: 2244 movs r2, #68 ; 0x44 + 800c82c: 5299 strh r1, [r3, r2] + goto nullreturn; + 800c82e: e193 b.n 800cb58 + } + + offset = (ntohs(IPH_OFFSET(fraghdr)) & IP_OFFMASK) * 8; + 800c830: 69bb ldr r3, [r7, #24] + 800c832: 799a ldrb r2, [r3, #6] + 800c834: 79db ldrb r3, [r3, #7] + 800c836: 021b lsls r3, r3, #8 + 800c838: 4313 orrs r3, r2 + 800c83a: b29b uxth r3, r3 + 800c83c: 0018 movs r0, r3 + 800c83e: f7f7 feff bl 8004640 + 800c842: 0003 movs r3, r0 + 800c844: 04db lsls r3, r3, #19 + 800c846: 0cdb lsrs r3, r3, #19 + 800c848: b29a uxth r2, r3 + 800c84a: 2316 movs r3, #22 + 800c84c: 18fb adds r3, r7, r3 + 800c84e: 00d2 lsls r2, r2, #3 + 800c850: 801a strh r2, [r3, #0] + len = ntohs(IPH_LEN(fraghdr)) - IPH_HL(fraghdr) * 4; + 800c852: 69bb ldr r3, [r7, #24] + 800c854: 789a ldrb r2, [r3, #2] + 800c856: 78db ldrb r3, [r3, #3] + 800c858: 021b lsls r3, r3, #8 + 800c85a: 4313 orrs r3, r2 + 800c85c: b29b uxth r3, r3 + 800c85e: 0018 movs r0, r3 + 800c860: f7f7 feee bl 8004640 + 800c864: 0003 movs r3, r0 + 800c866: 0019 movs r1, r3 + 800c868: 69bb ldr r3, [r7, #24] + 800c86a: 781b ldrb r3, [r3, #0] + 800c86c: b29b uxth r3, r3 + 800c86e: 220f movs r2, #15 + 800c870: 4013 ands r3, r2 + 800c872: b29b uxth r3, r3 + 800c874: 009b lsls r3, r3, #2 + 800c876: b29a uxth r2, r3 + 800c878: 2314 movs r3, #20 + 800c87a: 18fb adds r3, r7, r3 + 800c87c: 1a8a subs r2, r1, r2 + 800c87e: 801a strh r2, [r3, #0] + + /* Check if we are allowed to enqueue more datagrams. */ + clen = pbuf_clen(p); + 800c880: 2513 movs r5, #19 + 800c882: 197c adds r4, r7, r5 + 800c884: 687b ldr r3, [r7, #4] + 800c886: 0018 movs r0, r3 + 800c888: f7f8 ff7e bl 8005788 + 800c88c: 0003 movs r3, r0 + 800c88e: 7023 strb r3, [r4, #0] + if ((ip_reass_pbufcount + clen) > IP_REASS_MAX_PBUFS) { + 800c890: 4baf ldr r3, [pc, #700] ; (800cb50 ) + 800c892: 881b ldrh r3, [r3, #0] + 800c894: 001a movs r2, r3 + 800c896: 197b adds r3, r7, r5 + 800c898: 781b ldrb r3, [r3, #0] + 800c89a: 18d3 adds r3, r2, r3 + 800c89c: 2b0a cmp r3, #10 + 800c89e: dd19 ble.n 800c8d4 +#if IP_REASS_FREE_OLDEST + if (!ip_reass_remove_oldest_datagram(fraghdr, clen) || + 800c8a0: 2313 movs r3, #19 + 800c8a2: 18fb adds r3, r7, r3 + 800c8a4: 781a ldrb r2, [r3, #0] + 800c8a6: 69bb ldr r3, [r7, #24] + 800c8a8: 0011 movs r1, r2 + 800c8aa: 0018 movs r0, r3 + 800c8ac: f7ff fcda bl 800c264 + 800c8b0: 1e03 subs r3, r0, #0 + 800c8b2: d008 beq.n 800c8c6 + ((ip_reass_pbufcount + clen) > IP_REASS_MAX_PBUFS)) + 800c8b4: 4ba6 ldr r3, [pc, #664] ; (800cb50 ) + 800c8b6: 881b ldrh r3, [r3, #0] + 800c8b8: 001a movs r2, r3 + 800c8ba: 2313 movs r3, #19 + 800c8bc: 18fb adds r3, r7, r3 + 800c8be: 781b ldrb r3, [r3, #0] + 800c8c0: 18d3 adds r3, r2, r3 + if (!ip_reass_remove_oldest_datagram(fraghdr, clen) || + 800c8c2: 2b0a cmp r3, #10 + 800c8c4: dd06 ble.n 800c8d4 +#endif /* IP_REASS_FREE_OLDEST */ + { + /* No datagram could be freed and still too many pbufs enqueued */ + LWIP_DEBUGF(IP_REASS_DEBUG,("ip_reass: Overflow condition: pbufct=%d, clen=%d, MAX=%d\n", + ip_reass_pbufcount, clen, IP_REASS_MAX_PBUFS)); + IPFRAG_STATS_INC(ip_frag.memerr); + 800c8c6: 4ba1 ldr r3, [pc, #644] ; (800cb4c ) + 800c8c8: 8f9b ldrh r3, [r3, #60] ; 0x3c + 800c8ca: 3301 adds r3, #1 + 800c8cc: b29a uxth r2, r3 + 800c8ce: 4b9f ldr r3, [pc, #636] ; (800cb4c ) + 800c8d0: 879a strh r2, [r3, #60] ; 0x3c + /* @todo: send ICMP time exceeded here? */ + /* drop this pbuf */ + goto nullreturn; + 800c8d2: e141 b.n 800cb58 + } + } + + /* Look for the datagram the fragment belongs to in the current datagram queue, + * remembering the previous in the queue for later dequeueing. */ + for (ipr = reassdatagrams; ipr != NULL; ipr = ipr->next) { + 800c8d4: 4b9f ldr r3, [pc, #636] ; (800cb54 ) + 800c8d6: 681b ldr r3, [r3, #0] + 800c8d8: 623b str r3, [r7, #32] + 800c8da: e035 b.n 800c948 + /* Check if the incoming fragment matches the one currently present + in the reassembly buffer. If so, we proceed with copying the + fragment into the buffer. */ + if (IP_ADDRESSES_AND_ID_MATCH(&ipr->iphdr, fraghdr)) { + 800c8dc: 6a3b ldr r3, [r7, #32] + 800c8de: 695a ldr r2, [r3, #20] + 800c8e0: 69bb ldr r3, [r7, #24] + 800c8e2: 7b19 ldrb r1, [r3, #12] + 800c8e4: 7b58 ldrb r0, [r3, #13] + 800c8e6: 0200 lsls r0, r0, #8 + 800c8e8: 4301 orrs r1, r0 + 800c8ea: 7b98 ldrb r0, [r3, #14] + 800c8ec: 0400 lsls r0, r0, #16 + 800c8ee: 4301 orrs r1, r0 + 800c8f0: 7bdb ldrb r3, [r3, #15] + 800c8f2: 061b lsls r3, r3, #24 + 800c8f4: 430b orrs r3, r1 + 800c8f6: 429a cmp r2, r3 + 800c8f8: d121 bne.n 800c93e + 800c8fa: 6a3b ldr r3, [r7, #32] + 800c8fc: 699a ldr r2, [r3, #24] + 800c8fe: 69bb ldr r3, [r7, #24] + 800c900: 7c19 ldrb r1, [r3, #16] + 800c902: 7c58 ldrb r0, [r3, #17] + 800c904: 0200 lsls r0, r0, #8 + 800c906: 4301 orrs r1, r0 + 800c908: 7c98 ldrb r0, [r3, #18] + 800c90a: 0400 lsls r0, r0, #16 + 800c90c: 4301 orrs r1, r0 + 800c90e: 7cdb ldrb r3, [r3, #19] + 800c910: 061b lsls r3, r3, #24 + 800c912: 430b orrs r3, r1 + 800c914: 429a cmp r2, r3 + 800c916: d112 bne.n 800c93e + 800c918: 6a3b ldr r3, [r7, #32] + 800c91a: 899a ldrh r2, [r3, #12] + 800c91c: 69bb ldr r3, [r7, #24] + 800c91e: 7919 ldrb r1, [r3, #4] + 800c920: 795b ldrb r3, [r3, #5] + 800c922: 021b lsls r3, r3, #8 + 800c924: 430b orrs r3, r1 + 800c926: b29b uxth r3, r3 + 800c928: 429a cmp r2, r3 + 800c92a: d108 bne.n 800c93e + LWIP_DEBUGF(IP_REASS_DEBUG, ("ip_reass: matching previous fragment ID=%"X16_F"\n", + ntohs(IPH_ID(fraghdr)))); + IPFRAG_STATS_INC(ip_frag.cachehit); + 800c92c: 4b87 ldr r3, [pc, #540] ; (800cb4c ) + 800c92e: 2246 movs r2, #70 ; 0x46 + 800c930: 5a9b ldrh r3, [r3, r2] + 800c932: 3301 adds r3, #1 + 800c934: b299 uxth r1, r3 + 800c936: 4b85 ldr r3, [pc, #532] ; (800cb4c ) + 800c938: 2246 movs r2, #70 ; 0x46 + 800c93a: 5299 strh r1, [r3, r2] + break; + 800c93c: e007 b.n 800c94e + } + ipr_prev = ipr; + 800c93e: 6a3b ldr r3, [r7, #32] + 800c940: 61fb str r3, [r7, #28] + for (ipr = reassdatagrams; ipr != NULL; ipr = ipr->next) { + 800c942: 6a3b ldr r3, [r7, #32] + 800c944: 681b ldr r3, [r3, #0] + 800c946: 623b str r3, [r7, #32] + 800c948: 6a3b ldr r3, [r7, #32] + 800c94a: 2b00 cmp r3, #0 + 800c94c: d1c6 bne.n 800c8dc + } + + if (ipr == NULL) { + 800c94e: 6a3b ldr r3, [r7, #32] + 800c950: 2b00 cmp r3, #0 + 800c952: d10d bne.n 800c970 + /* Enqueue a new datagram into the datagram queue */ + ipr = ip_reass_enqueue_new_datagram(fraghdr, clen); + 800c954: 2313 movs r3, #19 + 800c956: 18fb adds r3, r7, r3 + 800c958: 781a ldrb r2, [r3, #0] + 800c95a: 69bb ldr r3, [r7, #24] + 800c95c: 0011 movs r1, r2 + 800c95e: 0018 movs r0, r3 + 800c960: f7ff fcf4 bl 800c34c + 800c964: 0003 movs r3, r0 + 800c966: 623b str r3, [r7, #32] + /* Bail if unable to enqueue */ + if(ipr == NULL) { + 800c968: 6a3b ldr r3, [r7, #32] + 800c96a: 2b00 cmp r3, #0 + 800c96c: d11d bne.n 800c9aa + goto nullreturn; + 800c96e: e0f3 b.n 800cb58 + } + } else { + if (((ntohs(IPH_OFFSET(fraghdr)) & IP_OFFMASK) == 0) && + 800c970: 69bb ldr r3, [r7, #24] + 800c972: 799a ldrb r2, [r3, #6] + 800c974: 79db ldrb r3, [r3, #7] + 800c976: 021b lsls r3, r3, #8 + 800c978: 4313 orrs r3, r2 + 800c97a: b29b uxth r3, r3 + 800c97c: 0018 movs r0, r3 + 800c97e: f7f7 fe5f bl 8004640 + 800c982: 0003 movs r3, r0 + 800c984: 04db lsls r3, r3, #19 + 800c986: 0cdb lsrs r3, r3, #19 + 800c988: d10f bne.n 800c9aa + ((ntohs(IPH_OFFSET(&ipr->iphdr)) & IP_OFFMASK) != 0)) { + 800c98a: 6a3b ldr r3, [r7, #32] + 800c98c: 89db ldrh r3, [r3, #14] + 800c98e: 0018 movs r0, r3 + 800c990: f7f7 fe56 bl 8004640 + 800c994: 0003 movs r3, r0 + 800c996: 04db lsls r3, r3, #19 + 800c998: 0cdb lsrs r3, r3, #19 + if (((ntohs(IPH_OFFSET(fraghdr)) & IP_OFFMASK) == 0) && + 800c99a: d006 beq.n 800c9aa + /* ipr->iphdr is not the header from the first fragment, but fraghdr is + * -> copy fraghdr into ipr->iphdr since we want to have the header + * of the first fragment (for ICMP time exceeded and later, for copying + * all options, if supported)*/ + SMEMCPY(&ipr->iphdr, fraghdr, IP_HLEN); + 800c99c: 6a3b ldr r3, [r7, #32] + 800c99e: 3308 adds r3, #8 + 800c9a0: 69b9 ldr r1, [r7, #24] + 800c9a2: 2214 movs r2, #20 + 800c9a4: 0018 movs r0, r3 + 800c9a6: f003 f97c bl 800fca2 + } + } + /* Track the current number of pbufs current 'in-flight', in order to limit + the number of fragments that may be enqueued at any one time */ + ip_reass_pbufcount += clen; + 800c9aa: 2313 movs r3, #19 + 800c9ac: 18fb adds r3, r7, r3 + 800c9ae: 781b ldrb r3, [r3, #0] + 800c9b0: b29a uxth r2, r3 + 800c9b2: 4b67 ldr r3, [pc, #412] ; (800cb50 ) + 800c9b4: 881b ldrh r3, [r3, #0] + 800c9b6: 18d3 adds r3, r2, r3 + 800c9b8: b29a uxth r2, r3 + 800c9ba: 4b65 ldr r3, [pc, #404] ; (800cb50 ) + 800c9bc: 801a strh r2, [r3, #0] + + /* At this point, we have either created a new entry or pointing + * to an existing one */ + + /* check for 'no more fragments', and update queue entry*/ + if ((IPH_OFFSET(fraghdr) & PP_NTOHS(IP_MF)) == 0) { + 800c9be: 69bb ldr r3, [r7, #24] + 800c9c0: 799a ldrb r2, [r3, #6] + 800c9c2: 79db ldrb r3, [r3, #7] + 800c9c4: 021b lsls r3, r3, #8 + 800c9c6: 4313 orrs r3, r2 + 800c9c8: b29b uxth r3, r3 + 800c9ca: 001a movs r2, r3 + 800c9cc: 2320 movs r3, #32 + 800c9ce: 4013 ands r3, r2 + 800c9d0: d110 bne.n 800c9f4 + ipr->flags |= IP_REASS_FLAG_LASTFRAG; + 800c9d2: 6a3b ldr r3, [r7, #32] + 800c9d4: 7f9b ldrb r3, [r3, #30] + 800c9d6: 2201 movs r2, #1 + 800c9d8: 4313 orrs r3, r2 + 800c9da: b2da uxtb r2, r3 + 800c9dc: 6a3b ldr r3, [r7, #32] + 800c9de: 779a strb r2, [r3, #30] + ipr->datagram_len = offset + len; + 800c9e0: 2316 movs r3, #22 + 800c9e2: 18fa adds r2, r7, r3 + 800c9e4: 2314 movs r3, #20 + 800c9e6: 18fb adds r3, r7, r3 + 800c9e8: 8812 ldrh r2, [r2, #0] + 800c9ea: 881b ldrh r3, [r3, #0] + 800c9ec: 18d3 adds r3, r2, r3 + 800c9ee: b29a uxth r2, r3 + 800c9f0: 6a3b ldr r3, [r7, #32] + 800c9f2: 839a strh r2, [r3, #28] + ("ip_reass: last fragment seen, total len %"S16_F"\n", + ipr->datagram_len)); + } + /* find the right place to insert this pbuf */ + /* @todo: trim pbufs if fragments are overlapping */ + if (ip_reass_chain_frag_into_datagram_and_validate(ipr, p)) { + 800c9f4: 687a ldr r2, [r7, #4] + 800c9f6: 6a3b ldr r3, [r7, #32] + 800c9f8: 0011 movs r1, r2 + 800c9fa: 0018 movs r0, r3 + 800c9fc: f7ff fd0c bl 800c418 + 800ca00: 1e03 subs r3, r0, #0 + 800ca02: d100 bne.n 800ca06 + 800ca04: e09f b.n 800cb46 + /* the totally last fragment (flag more fragments = 0) was received at least + * once AND all fragments are received */ + ipr->datagram_len += IP_HLEN; + 800ca06: 6a3b ldr r3, [r7, #32] + 800ca08: 8b9b ldrh r3, [r3, #28] + 800ca0a: 3314 adds r3, #20 + 800ca0c: b29a uxth r2, r3 + 800ca0e: 6a3b ldr r3, [r7, #32] + 800ca10: 839a strh r2, [r3, #28] + + /* save the second pbuf before copying the header over the pointer */ + r = ((struct ip_reass_helper*)ipr->p->payload)->next_pbuf; + 800ca12: 6a3b ldr r3, [r7, #32] + 800ca14: 685b ldr r3, [r3, #4] + 800ca16: 685b ldr r3, [r3, #4] + 800ca18: 781a ldrb r2, [r3, #0] + 800ca1a: 7859 ldrb r1, [r3, #1] + 800ca1c: 0209 lsls r1, r1, #8 + 800ca1e: 430a orrs r2, r1 + 800ca20: 7899 ldrb r1, [r3, #2] + 800ca22: 0409 lsls r1, r1, #16 + 800ca24: 430a orrs r2, r1 + 800ca26: 78db ldrb r3, [r3, #3] + 800ca28: 061b lsls r3, r3, #24 + 800ca2a: 4313 orrs r3, r2 + 800ca2c: 627b str r3, [r7, #36] ; 0x24 + + /* copy the original ip header back to the first pbuf */ + fraghdr = (struct ip_hdr*)(ipr->p->payload); + 800ca2e: 6a3b ldr r3, [r7, #32] + 800ca30: 685b ldr r3, [r3, #4] + 800ca32: 685b ldr r3, [r3, #4] + 800ca34: 61bb str r3, [r7, #24] + SMEMCPY(fraghdr, &ipr->iphdr, IP_HLEN); + 800ca36: 6a3b ldr r3, [r7, #32] + 800ca38: 3308 adds r3, #8 + 800ca3a: 0019 movs r1, r3 + 800ca3c: 69bb ldr r3, [r7, #24] + 800ca3e: 2214 movs r2, #20 + 800ca40: 0018 movs r0, r3 + 800ca42: f003 f92e bl 800fca2 + IPH_LEN_SET(fraghdr, htons(ipr->datagram_len)); + 800ca46: 6a3b ldr r3, [r7, #32] + 800ca48: 8b9b ldrh r3, [r3, #28] + 800ca4a: 0018 movs r0, r3 + 800ca4c: f7f7 fde2 bl 8004614 + 800ca50: 0003 movs r3, r0 + 800ca52: 001a movs r2, r3 + 800ca54: 69bb ldr r3, [r7, #24] + 800ca56: 21ff movs r1, #255 ; 0xff + 800ca58: 4011 ands r1, r2 + 800ca5a: 000c movs r4, r1 + 800ca5c: 7899 ldrb r1, [r3, #2] + 800ca5e: 2000 movs r0, #0 + 800ca60: 4001 ands r1, r0 + 800ca62: 1c08 adds r0, r1, #0 + 800ca64: 1c21 adds r1, r4, #0 + 800ca66: 4301 orrs r1, r0 + 800ca68: 7099 strb r1, [r3, #2] + 800ca6a: 0a12 lsrs r2, r2, #8 + 800ca6c: b290 uxth r0, r2 + 800ca6e: 78da ldrb r2, [r3, #3] + 800ca70: 2100 movs r1, #0 + 800ca72: 400a ands r2, r1 + 800ca74: 1c11 adds r1, r2, #0 + 800ca76: 1c02 adds r2, r0, #0 + 800ca78: 430a orrs r2, r1 + 800ca7a: 70da strb r2, [r3, #3] + IPH_OFFSET_SET(fraghdr, 0); + 800ca7c: 69bb ldr r3, [r7, #24] + 800ca7e: 799a ldrb r2, [r3, #6] + 800ca80: 2100 movs r1, #0 + 800ca82: 400a ands r2, r1 + 800ca84: 719a strb r2, [r3, #6] + 800ca86: 79da ldrb r2, [r3, #7] + 800ca88: 2100 movs r1, #0 + 800ca8a: 400a ands r2, r1 + 800ca8c: 71da strb r2, [r3, #7] + IPH_CHKSUM_SET(fraghdr, 0); + 800ca8e: 69bb ldr r3, [r7, #24] + 800ca90: 7a9a ldrb r2, [r3, #10] + 800ca92: 2100 movs r1, #0 + 800ca94: 400a ands r2, r1 + 800ca96: 729a strb r2, [r3, #10] + 800ca98: 7ada ldrb r2, [r3, #11] + 800ca9a: 2100 movs r1, #0 + 800ca9c: 400a ands r2, r1 + 800ca9e: 72da strb r2, [r3, #11] + /* @todo: do we need to set calculate the correct checksum? */ + IPH_CHKSUM_SET(fraghdr, inet_chksum(fraghdr, IP_HLEN)); + 800caa0: 69bb ldr r3, [r7, #24] + 800caa2: 2114 movs r1, #20 + 800caa4: 0018 movs r0, r3 + 800caa6: f7fe fe63 bl 800b770 + 800caaa: 0003 movs r3, r0 + 800caac: 001a movs r2, r3 + 800caae: 69bb ldr r3, [r7, #24] + 800cab0: 21ff movs r1, #255 ; 0xff + 800cab2: 4011 ands r1, r2 + 800cab4: 000c movs r4, r1 + 800cab6: 7a99 ldrb r1, [r3, #10] + 800cab8: 2000 movs r0, #0 + 800caba: 4001 ands r1, r0 + 800cabc: 1c08 adds r0, r1, #0 + 800cabe: 1c21 adds r1, r4, #0 + 800cac0: 4301 orrs r1, r0 + 800cac2: 7299 strb r1, [r3, #10] + 800cac4: 0a12 lsrs r2, r2, #8 + 800cac6: b290 uxth r0, r2 + 800cac8: 7ada ldrb r2, [r3, #11] + 800caca: 2100 movs r1, #0 + 800cacc: 400a ands r2, r1 + 800cace: 1c11 adds r1, r2, #0 + 800cad0: 1c02 adds r2, r0, #0 + 800cad2: 430a orrs r2, r1 + 800cad4: 72da strb r2, [r3, #11] + + p = ipr->p; + 800cad6: 6a3b ldr r3, [r7, #32] + 800cad8: 685b ldr r3, [r3, #4] + 800cada: 607b str r3, [r7, #4] + + /* chain together the pbufs contained within the reass_data list. */ + while(r != NULL) { + 800cadc: e01b b.n 800cb16 + iprh = (struct ip_reass_helper*)r->payload; + 800cade: 6a7b ldr r3, [r7, #36] ; 0x24 + 800cae0: 685b ldr r3, [r3, #4] + 800cae2: 60fb str r3, [r7, #12] + + /* hide the ip header for every succeding fragment */ + pbuf_header(r, -IP_HLEN); + 800cae4: 2314 movs r3, #20 + 800cae6: 425a negs r2, r3 + 800cae8: 6a7b ldr r3, [r7, #36] ; 0x24 + 800caea: 0011 movs r1, r2 + 800caec: 0018 movs r0, r3 + 800caee: f7f8 fd52 bl 8005596 + pbuf_cat(p, r); + 800caf2: 6a7a ldr r2, [r7, #36] ; 0x24 + 800caf4: 687b ldr r3, [r7, #4] + 800caf6: 0011 movs r1, r2 + 800caf8: 0018 movs r0, r3 + 800cafa: f7f8 fe72 bl 80057e2 + r = iprh->next_pbuf; + 800cafe: 68fb ldr r3, [r7, #12] + 800cb00: 781a ldrb r2, [r3, #0] + 800cb02: 7859 ldrb r1, [r3, #1] + 800cb04: 0209 lsls r1, r1, #8 + 800cb06: 430a orrs r2, r1 + 800cb08: 7899 ldrb r1, [r3, #2] + 800cb0a: 0409 lsls r1, r1, #16 + 800cb0c: 430a orrs r2, r1 + 800cb0e: 78db ldrb r3, [r3, #3] + 800cb10: 061b lsls r3, r3, #24 + 800cb12: 4313 orrs r3, r2 + 800cb14: 627b str r3, [r7, #36] ; 0x24 + while(r != NULL) { + 800cb16: 6a7b ldr r3, [r7, #36] ; 0x24 + 800cb18: 2b00 cmp r3, #0 + 800cb1a: d1e0 bne.n 800cade + } + /* release the sources allocate for the fragment queue entry */ + ip_reass_dequeue_datagram(ipr, ipr_prev); + 800cb1c: 69fa ldr r2, [r7, #28] + 800cb1e: 6a3b ldr r3, [r7, #32] + 800cb20: 0011 movs r1, r2 + 800cb22: 0018 movs r0, r3 + 800cb24: f7ff fc5a bl 800c3dc + + /* and adjust the number of pbufs currently queued for reassembly. */ + ip_reass_pbufcount -= pbuf_clen(p); + 800cb28: 687b ldr r3, [r7, #4] + 800cb2a: 0018 movs r0, r3 + 800cb2c: f7f8 fe2c bl 8005788 + 800cb30: 0003 movs r3, r0 + 800cb32: 0019 movs r1, r3 + 800cb34: 4b06 ldr r3, [pc, #24] ; (800cb50 ) + 800cb36: 881a ldrh r2, [r3, #0] + 800cb38: b28b uxth r3, r1 + 800cb3a: 1ad3 subs r3, r2, r3 + 800cb3c: b29a uxth r2, r3 + 800cb3e: 4b04 ldr r3, [pc, #16] ; (800cb50 ) + 800cb40: 801a strh r2, [r3, #0] + + /* Return the pbuf chain */ + return p; + 800cb42: 687b ldr r3, [r7, #4] + 800cb44: e013 b.n 800cb6e + } + /* the datagram is not (yet?) reassembled completely */ + LWIP_DEBUGF(IP_REASS_DEBUG,("ip_reass_pbufcount: %d out\n", ip_reass_pbufcount)); + return NULL; + 800cb46: 2300 movs r3, #0 + 800cb48: e011 b.n 800cb6e + 800cb4a: 46c0 nop ; (mov r8, r8) + 800cb4c: 20003158 .word 0x20003158 + 800cb50: 200022bc .word 0x200022bc + 800cb54: 200022b8 .word 0x200022b8 + +nullreturn: + LWIP_DEBUGF(IP_REASS_DEBUG,("ip_reass: nullreturn\n")); + IPFRAG_STATS_INC(ip_frag.drop); + 800cb58: 4b07 ldr r3, [pc, #28] ; (800cb78 ) + 800cb5a: 8edb ldrh r3, [r3, #54] ; 0x36 + 800cb5c: 3301 adds r3, #1 + 800cb5e: b29a uxth r2, r3 + 800cb60: 4b05 ldr r3, [pc, #20] ; (800cb78 ) + 800cb62: 86da strh r2, [r3, #54] ; 0x36 + pbuf_free(p); + 800cb64: 687b ldr r3, [r7, #4] + 800cb66: 0018 movs r0, r3 + 800cb68: f7f8 fd9c bl 80056a4 + return NULL; + 800cb6c: 2300 movs r3, #0 +} + 800cb6e: 0018 movs r0, r3 + 800cb70: 46bd mov sp, r7 + 800cb72: b00a add sp, #40 ; 0x28 + 800cb74: bdb0 pop {r4, r5, r7, pc} + 800cb76: 46c0 nop ; (mov r8, r8) + 800cb78: 20003158 .word 0x20003158 + +0800cb7c : + +#if !LWIP_NETIF_TX_SINGLE_PBUF +/** Allocate a new struct pbuf_custom_ref */ +static struct pbuf_custom_ref* +ip_frag_alloc_pbuf_custom_ref(void) +{ + 800cb7c: b580 push {r7, lr} + 800cb7e: af00 add r7, sp, #0 + return (struct pbuf_custom_ref*)memp_malloc(MEMP_FRAG_PBUF); + 800cb80: 2006 movs r0, #6 + 800cb82: f7f8 f947 bl 8004e14 + 800cb86: 0003 movs r3, r0 +} + 800cb88: 0018 movs r0, r3 + 800cb8a: 46bd mov sp, r7 + 800cb8c: bd80 pop {r7, pc} + +0800cb8e : + +/** Free a struct pbuf_custom_ref */ +static void +ip_frag_free_pbuf_custom_ref(struct pbuf_custom_ref* p) +{ + 800cb8e: b580 push {r7, lr} + 800cb90: b082 sub sp, #8 + 800cb92: af00 add r7, sp, #0 + 800cb94: 6078 str r0, [r7, #4] + LWIP_ASSERT("p != NULL", p != NULL); + memp_free(MEMP_FRAG_PBUF, p); + 800cb96: 687b ldr r3, [r7, #4] + 800cb98: 0019 movs r1, r3 + 800cb9a: 2006 movs r0, #6 + 800cb9c: f7f8 f9c0 bl 8004f20 +} + 800cba0: 46c0 nop ; (mov r8, r8) + 800cba2: 46bd mov sp, r7 + 800cba4: b002 add sp, #8 + 800cba6: bd80 pop {r7, pc} + +0800cba8 : + +/** Free-callback function to free a 'struct pbuf_custom_ref', called by + * pbuf_free. */ +static void +ipfrag_free_pbuf_custom(struct pbuf *p) +{ + 800cba8: b580 push {r7, lr} + 800cbaa: b084 sub sp, #16 + 800cbac: af00 add r7, sp, #0 + 800cbae: 6078 str r0, [r7, #4] + struct pbuf_custom_ref *pcr = (struct pbuf_custom_ref*)p; + 800cbb0: 687b ldr r3, [r7, #4] + 800cbb2: 60fb str r3, [r7, #12] + LWIP_ASSERT("pcr != NULL", pcr != NULL); + LWIP_ASSERT("pcr == p", (void*)pcr == (void*)p); + if (pcr->original != NULL) { + 800cbb4: 68fb ldr r3, [r7, #12] + 800cbb6: 695b ldr r3, [r3, #20] + 800cbb8: 2b00 cmp r3, #0 + 800cbba: d004 beq.n 800cbc6 + pbuf_free(pcr->original); + 800cbbc: 68fb ldr r3, [r7, #12] + 800cbbe: 695b ldr r3, [r3, #20] + 800cbc0: 0018 movs r0, r3 + 800cbc2: f7f8 fd6f bl 80056a4 + } + ip_frag_free_pbuf_custom_ref(pcr); + 800cbc6: 68fb ldr r3, [r7, #12] + 800cbc8: 0018 movs r0, r3 + 800cbca: f7ff ffe0 bl 800cb8e +} + 800cbce: 46c0 nop ; (mov r8, r8) + 800cbd0: 46bd mov sp, r7 + 800cbd2: b004 add sp, #16 + 800cbd4: bd80 pop {r7, pc} + ... + +0800cbd8 : + * + * @return ERR_OK if sent successfully, err_t otherwise + */ +err_t +ip_frag(struct pbuf *p, struct netif *netif, ip_addr_t *dest) +{ + 800cbd8: b5f0 push {r4, r5, r6, r7, lr} + 800cbda: b093 sub sp, #76 ; 0x4c + 800cbdc: af02 add r7, sp, #8 + 800cbde: 60f8 str r0, [r7, #12] + 800cbe0: 60b9 str r1, [r7, #8] + 800cbe2: 607a str r2, [r7, #4] + struct ip_hdr *original_iphdr; +#endif + struct ip_hdr *iphdr; + u16_t nfb; + u16_t left, cop; + u16_t mtu = netif->mtu; + 800cbe4: 2632 movs r6, #50 ; 0x32 + 800cbe6: 19bb adds r3, r7, r6 + 800cbe8: 68ba ldr r2, [r7, #8] + 800cbea: 8c12 ldrh r2, [r2, #32] + 800cbec: 801a strh r2, [r3, #0] + u16_t ofo, omf; + u16_t last; + u16_t poff = IP_HLEN; + 800cbee: 233a movs r3, #58 ; 0x3a + 800cbf0: 18fb adds r3, r7, r3 + 800cbf2: 2214 movs r2, #20 + 800cbf4: 801a strh r2, [r3, #0] + u16_t tmp; +#if !IP_FRAG_USES_STATIC_BUF && !LWIP_NETIF_TX_SINGLE_PBUF + u16_t newpbuflen = 0; + 800cbf6: 2336 movs r3, #54 ; 0x36 + 800cbf8: 18fb adds r3, r7, r3 + 800cbfa: 2200 movs r2, #0 + 800cbfc: 801a strh r2, [r3, #0] + + /* Copy the IP header in it */ + iphdr = (struct ip_hdr *)rambuf->payload; + SMEMCPY(iphdr, p->payload, IP_HLEN); +#else /* IP_FRAG_USES_STATIC_BUF */ + original_iphdr = (struct ip_hdr *)p->payload; + 800cbfe: 68fb ldr r3, [r7, #12] + 800cc00: 685b ldr r3, [r3, #4] + 800cc02: 62fb str r3, [r7, #44] ; 0x2c + iphdr = original_iphdr; + 800cc04: 6afb ldr r3, [r7, #44] ; 0x2c + 800cc06: 62bb str r3, [r7, #40] ; 0x28 +#endif /* IP_FRAG_USES_STATIC_BUF */ + + /* Save original offset */ + tmp = ntohs(IPH_OFFSET(iphdr)); + 800cc08: 6abb ldr r3, [r7, #40] ; 0x28 + 800cc0a: 799a ldrb r2, [r3, #6] + 800cc0c: 79db ldrb r3, [r3, #7] + 800cc0e: 021b lsls r3, r3, #8 + 800cc10: 4313 orrs r3, r2 + 800cc12: b29b uxth r3, r3 + 800cc14: 2138 movs r1, #56 ; 0x38 + 800cc16: 000d movs r5, r1 + 800cc18: 187c adds r4, r7, r1 + 800cc1a: 0018 movs r0, r3 + 800cc1c: f7f7 fd10 bl 8004640 + 800cc20: 0003 movs r3, r0 + 800cc22: 8023 strh r3, [r4, #0] + ofo = tmp & IP_OFFMASK; + 800cc24: 233c movs r3, #60 ; 0x3c + 800cc26: 18fb adds r3, r7, r3 + 800cc28: 0029 movs r1, r5 + 800cc2a: 187a adds r2, r7, r1 + 800cc2c: 8812 ldrh r2, [r2, #0] + 800cc2e: 04d2 lsls r2, r2, #19 + 800cc30: 0cd2 lsrs r2, r2, #19 + 800cc32: 801a strh r2, [r3, #0] + omf = tmp & IP_MF; + 800cc34: 2326 movs r3, #38 ; 0x26 + 800cc36: 18fb adds r3, r7, r3 + 800cc38: 187a adds r2, r7, r1 + 800cc3a: 8811 ldrh r1, [r2, #0] + 800cc3c: 2280 movs r2, #128 ; 0x80 + 800cc3e: 0192 lsls r2, r2, #6 + 800cc40: 400a ands r2, r1 + 800cc42: 801a strh r2, [r3, #0] + + left = p->tot_len - IP_HLEN; + 800cc44: 68fb ldr r3, [r7, #12] + 800cc46: 891a ldrh r2, [r3, #8] + 800cc48: 233e movs r3, #62 ; 0x3e + 800cc4a: 18fb adds r3, r7, r3 + 800cc4c: 3a14 subs r2, #20 + 800cc4e: 801a strh r2, [r3, #0] + + nfb = (mtu - IP_HLEN) / 8; + 800cc50: 19bb adds r3, r7, r6 + 800cc52: 881b ldrh r3, [r3, #0] + 800cc54: 3b14 subs r3, #20 + 800cc56: 2b00 cmp r3, #0 + 800cc58: da00 bge.n 800cc5c + 800cc5a: 3307 adds r3, #7 + 800cc5c: 10db asrs r3, r3, #3 + 800cc5e: 001a movs r2, r3 + 800cc60: 2324 movs r3, #36 ; 0x24 + 800cc62: 18fb adds r3, r7, r3 + 800cc64: 801a strh r2, [r3, #0] + + while (left) { + 800cc66: e15a b.n 800cf1e + last = (left <= mtu - IP_HLEN); + 800cc68: 233e movs r3, #62 ; 0x3e + 800cc6a: 18fb adds r3, r7, r3 + 800cc6c: 881b ldrh r3, [r3, #0] + 800cc6e: 2232 movs r2, #50 ; 0x32 + 800cc70: 18ba adds r2, r7, r2 + 800cc72: 8812 ldrh r2, [r2, #0] + 800cc74: 3a14 subs r2, #20 + 800cc76: 0fd8 lsrs r0, r3, #31 + 800cc78: 17d1 asrs r1, r2, #31 + 800cc7a: 429a cmp r2, r3 + 800cc7c: 4148 adcs r0, r1 + 800cc7e: 0003 movs r3, r0 + 800cc80: b2da uxtb r2, r3 + 800cc82: 2022 movs r0, #34 ; 0x22 + 800cc84: 183b adds r3, r7, r0 + 800cc86: 801a strh r2, [r3, #0] + + /* Set new offset and MF flag */ + tmp = omf | (IP_OFFMASK & (ofo)); + 800cc88: 233c movs r3, #60 ; 0x3c + 800cc8a: 18fb adds r3, r7, r3 + 800cc8c: 881b ldrh r3, [r3, #0] + 800cc8e: 04db lsls r3, r3, #19 + 800cc90: 0cdb lsrs r3, r3, #19 + 800cc92: b299 uxth r1, r3 + 800cc94: 2338 movs r3, #56 ; 0x38 + 800cc96: 18fb adds r3, r7, r3 + 800cc98: 2226 movs r2, #38 ; 0x26 + 800cc9a: 18ba adds r2, r7, r2 + 800cc9c: 8812 ldrh r2, [r2, #0] + 800cc9e: 430a orrs r2, r1 + 800cca0: 801a strh r2, [r3, #0] + if (!last) { + 800cca2: 183b adds r3, r7, r0 + 800cca4: 881b ldrh r3, [r3, #0] + 800cca6: 2b00 cmp r3, #0 + 800cca8: d107 bne.n 800ccba + tmp = tmp | IP_MF; + 800ccaa: 2238 movs r2, #56 ; 0x38 + 800ccac: 18bb adds r3, r7, r2 + 800ccae: 18ba adds r2, r7, r2 + 800ccb0: 8812 ldrh r2, [r2, #0] + 800ccb2: 2180 movs r1, #128 ; 0x80 + 800ccb4: 0189 lsls r1, r1, #6 + 800ccb6: 430a orrs r2, r1 + 800ccb8: 801a strh r2, [r3, #0] + } + + /* Fill this fragment */ + cop = last ? left : nfb * 8; + 800ccba: 2322 movs r3, #34 ; 0x22 + 800ccbc: 18fb adds r3, r7, r3 + 800ccbe: 881b ldrh r3, [r3, #0] + 800ccc0: 2b00 cmp r3, #0 + 800ccc2: d105 bne.n 800ccd0 + 800ccc4: 2324 movs r3, #36 ; 0x24 + 800ccc6: 18fb adds r3, r7, r3 + 800ccc8: 881b ldrh r3, [r3, #0] + 800ccca: 00db lsls r3, r3, #3 + 800cccc: b29b uxth r3, r3 + 800ccce: e002 b.n 800ccd6 + 800ccd0: 233e movs r3, #62 ; 0x3e + 800ccd2: 18fb adds r3, r7, r3 + 800ccd4: 881b ldrh r3, [r3, #0] + 800ccd6: 2220 movs r2, #32 + 800ccd8: 18ba adds r2, r7, r2 + 800ccda: 8013 strh r3, [r2, #0] + /* When not using a static buffer, create a chain of pbufs. + * The first will be a PBUF_RAM holding the link and IP header. + * The rest will be PBUF_REFs mirroring the pbuf chain to be fragged, + * but limited to the size of an mtu. + */ + rambuf = pbuf_alloc(PBUF_LINK, IP_HLEN, PBUF_RAM); + 800ccdc: 2200 movs r2, #0 + 800ccde: 2114 movs r1, #20 + 800cce0: 2002 movs r0, #2 + 800cce2: f7f8 fa53 bl 800518c + 800cce6: 0003 movs r3, r0 + 800cce8: 61fb str r3, [r7, #28] + if (rambuf == NULL) { + 800ccea: 69fb ldr r3, [r7, #28] + 800ccec: 2b00 cmp r3, #0 + 800ccee: d102 bne.n 800ccf6 + return ERR_MEM; + 800ccf0: 2301 movs r3, #1 + 800ccf2: 425b negs r3, r3 + 800ccf4: e11a b.n 800cf2c + } + LWIP_ASSERT("this needs a pbuf in one piece!", + (p->len >= (IP_HLEN))); + SMEMCPY(rambuf->payload, original_iphdr, IP_HLEN); + 800ccf6: 69fb ldr r3, [r7, #28] + 800ccf8: 685b ldr r3, [r3, #4] + 800ccfa: 6af9 ldr r1, [r7, #44] ; 0x2c + 800ccfc: 2214 movs r2, #20 + 800ccfe: 0018 movs r0, r3 + 800cd00: f002 ffcf bl 800fca2 + iphdr = (struct ip_hdr *)rambuf->payload; + 800cd04: 69fb ldr r3, [r7, #28] + 800cd06: 685b ldr r3, [r3, #4] + 800cd08: 62bb str r3, [r7, #40] ; 0x28 + + /* Can just adjust p directly for needed offset. */ + p->payload = (u8_t *)p->payload + poff; + 800cd0a: 68fb ldr r3, [r7, #12] + 800cd0c: 685a ldr r2, [r3, #4] + 800cd0e: 213a movs r1, #58 ; 0x3a + 800cd10: 187b adds r3, r7, r1 + 800cd12: 881b ldrh r3, [r3, #0] + 800cd14: 18d2 adds r2, r2, r3 + 800cd16: 68fb ldr r3, [r7, #12] + 800cd18: 605a str r2, [r3, #4] + p->len -= poff; + 800cd1a: 68fb ldr r3, [r7, #12] + 800cd1c: 895a ldrh r2, [r3, #10] + 800cd1e: 187b adds r3, r7, r1 + 800cd20: 881b ldrh r3, [r3, #0] + 800cd22: 1ad3 subs r3, r2, r3 + 800cd24: b29a uxth r2, r3 + 800cd26: 68fb ldr r3, [r7, #12] + 800cd28: 815a strh r2, [r3, #10] + + left_to_copy = cop; + 800cd2a: 2334 movs r3, #52 ; 0x34 + 800cd2c: 18fb adds r3, r7, r3 + 800cd2e: 2220 movs r2, #32 + 800cd30: 18ba adds r2, r7, r2 + 800cd32: 8812 ldrh r2, [r2, #0] + 800cd34: 801a strh r2, [r3, #0] + while (left_to_copy) { + 800cd36: e068 b.n 800ce0a + struct pbuf_custom_ref *pcr; + newpbuflen = (left_to_copy < p->len) ? left_to_copy : p->len; + 800cd38: 68fb ldr r3, [r7, #12] + 800cd3a: 8959 ldrh r1, [r3, #10] + 800cd3c: 2336 movs r3, #54 ; 0x36 + 800cd3e: 18fa adds r2, r7, r3 + 800cd40: 2334 movs r3, #52 ; 0x34 + 800cd42: 18fb adds r3, r7, r3 + 800cd44: 1c0c adds r4, r1, #0 + 800cd46: 881b ldrh r3, [r3, #0] + 800cd48: b298 uxth r0, r3 + 800cd4a: b2a1 uxth r1, r4 + 800cd4c: 4288 cmp r0, r1 + 800cd4e: d900 bls.n 800cd52 + 800cd50: 1c23 adds r3, r4, #0 + 800cd52: 8013 strh r3, [r2, #0] + /* Is this pbuf already empty? */ + if (!newpbuflen) { + 800cd54: 2336 movs r3, #54 ; 0x36 + 800cd56: 18fb adds r3, r7, r3 + 800cd58: 881b ldrh r3, [r3, #0] + 800cd5a: 2b00 cmp r3, #0 + 800cd5c: d108 bne.n 800cd70 + p = p->next; + 800cd5e: 68fb ldr r3, [r7, #12] + 800cd60: 681b ldr r3, [r3, #0] + 800cd62: 60fb str r3, [r7, #12] + 800cd64: 2234 movs r2, #52 ; 0x34 + 800cd66: 18bb adds r3, r7, r2 + 800cd68: 18ba adds r2, r7, r2 + 800cd6a: 8812 ldrh r2, [r2, #0] + 800cd6c: 801a strh r2, [r3, #0] + continue; + 800cd6e: e04c b.n 800ce0a + } + pcr = ip_frag_alloc_pbuf_custom_ref(); + 800cd70: f7ff ff04 bl 800cb7c + 800cd74: 0003 movs r3, r0 + 800cd76: 61bb str r3, [r7, #24] + if (pcr == NULL) { + 800cd78: 69bb ldr r3, [r7, #24] + 800cd7a: 2b00 cmp r3, #0 + 800cd7c: d106 bne.n 800cd8c + pbuf_free(rambuf); + 800cd7e: 69fb ldr r3, [r7, #28] + 800cd80: 0018 movs r0, r3 + 800cd82: f7f8 fc8f bl 80056a4 + return ERR_MEM; + 800cd86: 2301 movs r3, #1 + 800cd88: 425b negs r3, r3 + 800cd8a: e0cf b.n 800cf2c + } + /* Mirror this pbuf, although we might not need all of it. */ + newpbuf = pbuf_alloced_custom(PBUF_RAW, newpbuflen, PBUF_REF, &pcr->pc, p->payload, newpbuflen); + 800cd8c: 69b8 ldr r0, [r7, #24] + 800cd8e: 68fb ldr r3, [r7, #12] + 800cd90: 685b ldr r3, [r3, #4] + 800cd92: 2436 movs r4, #54 ; 0x36 + 800cd94: 193a adds r2, r7, r4 + 800cd96: 8811 ldrh r1, [r2, #0] + 800cd98: 193a adds r2, r7, r4 + 800cd9a: 8812 ldrh r2, [r2, #0] + 800cd9c: 9201 str r2, [sp, #4] + 800cd9e: 9300 str r3, [sp, #0] + 800cda0: 0003 movs r3, r0 + 800cda2: 2202 movs r2, #2 + 800cda4: 2003 movs r0, #3 + 800cda6: f7f8 fb13 bl 80053d0 + 800cdaa: 0003 movs r3, r0 + 800cdac: 617b str r3, [r7, #20] + if (newpbuf == NULL) { + 800cdae: 697b ldr r3, [r7, #20] + 800cdb0: 2b00 cmp r3, #0 + 800cdb2: d10a bne.n 800cdca + ip_frag_free_pbuf_custom_ref(pcr); + 800cdb4: 69bb ldr r3, [r7, #24] + 800cdb6: 0018 movs r0, r3 + 800cdb8: f7ff fee9 bl 800cb8e + pbuf_free(rambuf); + 800cdbc: 69fb ldr r3, [r7, #28] + 800cdbe: 0018 movs r0, r3 + 800cdc0: f7f8 fc70 bl 80056a4 + return ERR_MEM; + 800cdc4: 2301 movs r3, #1 + 800cdc6: 425b negs r3, r3 + 800cdc8: e0b0 b.n 800cf2c + } + pbuf_ref(p); + 800cdca: 68fb ldr r3, [r7, #12] + 800cdcc: 0018 movs r0, r3 + 800cdce: f7f8 fcf7 bl 80057c0 + pcr->original = p; + 800cdd2: 69bb ldr r3, [r7, #24] + 800cdd4: 68fa ldr r2, [r7, #12] + 800cdd6: 615a str r2, [r3, #20] + pcr->pc.custom_free_function = ipfrag_free_pbuf_custom; + 800cdd8: 69bb ldr r3, [r7, #24] + 800cdda: 4a56 ldr r2, [pc, #344] ; (800cf34 ) + 800cddc: 611a str r2, [r3, #16] + + /* Add it to end of rambuf's chain, but using pbuf_cat, not pbuf_chain + * so that it is removed when pbuf_dechain is later called on rambuf. + */ + pbuf_cat(rambuf, newpbuf); + 800cdde: 697a ldr r2, [r7, #20] + 800cde0: 69fb ldr r3, [r7, #28] + 800cde2: 0011 movs r1, r2 + 800cde4: 0018 movs r0, r3 + 800cde6: f7f8 fcfc bl 80057e2 + left_to_copy -= newpbuflen; + 800cdea: 2034 movs r0, #52 ; 0x34 + 800cdec: 183b adds r3, r7, r0 + 800cdee: 1839 adds r1, r7, r0 + 800cdf0: 2236 movs r2, #54 ; 0x36 + 800cdf2: 18ba adds r2, r7, r2 + 800cdf4: 8809 ldrh r1, [r1, #0] + 800cdf6: 8812 ldrh r2, [r2, #0] + 800cdf8: 1a8a subs r2, r1, r2 + 800cdfa: 801a strh r2, [r3, #0] + if (left_to_copy) { + 800cdfc: 183b adds r3, r7, r0 + 800cdfe: 881b ldrh r3, [r3, #0] + 800ce00: 2b00 cmp r3, #0 + 800ce02: d002 beq.n 800ce0a + p = p->next; + 800ce04: 68fb ldr r3, [r7, #12] + 800ce06: 681b ldr r3, [r3, #0] + 800ce08: 60fb str r3, [r7, #12] + while (left_to_copy) { + 800ce0a: 2334 movs r3, #52 ; 0x34 + 800ce0c: 18fb adds r3, r7, r3 + 800ce0e: 881b ldrh r3, [r3, #0] + 800ce10: 2b00 cmp r3, #0 + 800ce12: d191 bne.n 800cd38 + } + } + poff = newpbuflen; + 800ce14: 233a movs r3, #58 ; 0x3a + 800ce16: 18fb adds r3, r7, r3 + 800ce18: 2236 movs r2, #54 ; 0x36 + 800ce1a: 18ba adds r2, r7, r2 + 800ce1c: 8812 ldrh r2, [r2, #0] + 800ce1e: 801a strh r2, [r3, #0] +#endif /* LWIP_NETIF_TX_SINGLE_PBUF */ +#endif /* IP_FRAG_USES_STATIC_BUF */ + + /* Correct header */ + IPH_OFFSET_SET(iphdr, htons(tmp)); + 800ce20: 2338 movs r3, #56 ; 0x38 + 800ce22: 18fb adds r3, r7, r3 + 800ce24: 881b ldrh r3, [r3, #0] + 800ce26: 0018 movs r0, r3 + 800ce28: f7f7 fbf4 bl 8004614 + 800ce2c: 0003 movs r3, r0 + 800ce2e: 001a movs r2, r3 + 800ce30: 6abb ldr r3, [r7, #40] ; 0x28 + 800ce32: 21ff movs r1, #255 ; 0xff + 800ce34: 4011 ands r1, r2 + 800ce36: 000c movs r4, r1 + 800ce38: 7999 ldrb r1, [r3, #6] + 800ce3a: 2000 movs r0, #0 + 800ce3c: 4001 ands r1, r0 + 800ce3e: 1c08 adds r0, r1, #0 + 800ce40: 1c21 adds r1, r4, #0 + 800ce42: 4301 orrs r1, r0 + 800ce44: 7199 strb r1, [r3, #6] + 800ce46: 0a12 lsrs r2, r2, #8 + 800ce48: b290 uxth r0, r2 + 800ce4a: 79da ldrb r2, [r3, #7] + 800ce4c: 2100 movs r1, #0 + 800ce4e: 400a ands r2, r1 + 800ce50: 1c11 adds r1, r2, #0 + 800ce52: 1c02 adds r2, r0, #0 + 800ce54: 430a orrs r2, r1 + 800ce56: 71da strb r2, [r3, #7] + IPH_LEN_SET(iphdr, htons(cop + IP_HLEN)); + 800ce58: 2520 movs r5, #32 + 800ce5a: 197b adds r3, r7, r5 + 800ce5c: 881b ldrh r3, [r3, #0] + 800ce5e: 3314 adds r3, #20 + 800ce60: b29b uxth r3, r3 + 800ce62: 0018 movs r0, r3 + 800ce64: f7f7 fbd6 bl 8004614 + 800ce68: 0003 movs r3, r0 + 800ce6a: 001a movs r2, r3 + 800ce6c: 6abb ldr r3, [r7, #40] ; 0x28 + 800ce6e: 21ff movs r1, #255 ; 0xff + 800ce70: 4011 ands r1, r2 + 800ce72: 000c movs r4, r1 + 800ce74: 7899 ldrb r1, [r3, #2] + 800ce76: 2000 movs r0, #0 + 800ce78: 4001 ands r1, r0 + 800ce7a: 1c08 adds r0, r1, #0 + 800ce7c: 1c21 adds r1, r4, #0 + 800ce7e: 4301 orrs r1, r0 + 800ce80: 7099 strb r1, [r3, #2] + 800ce82: 0a12 lsrs r2, r2, #8 + 800ce84: b290 uxth r0, r2 + 800ce86: 78da ldrb r2, [r3, #3] + 800ce88: 2100 movs r1, #0 + 800ce8a: 400a ands r2, r1 + 800ce8c: 1c11 adds r1, r2, #0 + 800ce8e: 1c02 adds r2, r0, #0 + 800ce90: 430a orrs r2, r1 + 800ce92: 70da strb r2, [r3, #3] + IPH_CHKSUM_SET(iphdr, 0); + 800ce94: 6abb ldr r3, [r7, #40] ; 0x28 + 800ce96: 7a9a ldrb r2, [r3, #10] + 800ce98: 2100 movs r1, #0 + 800ce9a: 400a ands r2, r1 + 800ce9c: 729a strb r2, [r3, #10] + 800ce9e: 7ada ldrb r2, [r3, #11] + 800cea0: 2100 movs r1, #0 + 800cea2: 400a ands r2, r1 + 800cea4: 72da strb r2, [r3, #11] + IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, IP_HLEN)); + 800cea6: 6abb ldr r3, [r7, #40] ; 0x28 + 800cea8: 2114 movs r1, #20 + 800ceaa: 0018 movs r0, r3 + 800ceac: f7fe fc60 bl 800b770 + 800ceb0: 0003 movs r3, r0 + 800ceb2: 001a movs r2, r3 + 800ceb4: 6abb ldr r3, [r7, #40] ; 0x28 + 800ceb6: 21ff movs r1, #255 ; 0xff + 800ceb8: 4011 ands r1, r2 + 800ceba: 000c movs r4, r1 + 800cebc: 7a99 ldrb r1, [r3, #10] + 800cebe: 2000 movs r0, #0 + 800cec0: 4001 ands r1, r0 + 800cec2: 1c08 adds r0, r1, #0 + 800cec4: 1c21 adds r1, r4, #0 + 800cec6: 4301 orrs r1, r0 + 800cec8: 7299 strb r1, [r3, #10] + 800ceca: 0a12 lsrs r2, r2, #8 + 800cecc: b290 uxth r0, r2 + 800cece: 7ada ldrb r2, [r3, #11] + 800ced0: 2100 movs r1, #0 + 800ced2: 400a ands r2, r1 + 800ced4: 1c11 adds r1, r2, #0 + 800ced6: 1c02 adds r2, r0, #0 + 800ced8: 430a orrs r2, r1 + 800ceda: 72da strb r2, [r3, #11] + } +#else /* IP_FRAG_USES_STATIC_BUF */ + /* No need for separate header pbuf - we allowed room for it in rambuf + * when allocated. + */ + netif->output(netif, rambuf, dest); + 800cedc: 68bb ldr r3, [r7, #8] + 800cede: 695b ldr r3, [r3, #20] + 800cee0: 687a ldr r2, [r7, #4] + 800cee2: 69f9 ldr r1, [r7, #28] + 800cee4: 68b8 ldr r0, [r7, #8] + 800cee6: 4798 blx r3 + IPFRAG_STATS_INC(ip_frag.xmit); + 800cee8: 4b13 ldr r3, [pc, #76] ; (800cf38 ) + 800ceea: 8e1b ldrh r3, [r3, #48] ; 0x30 + 800ceec: 3301 adds r3, #1 + 800ceee: b29a uxth r2, r3 + 800cef0: 4b11 ldr r3, [pc, #68] ; (800cf38 ) + 800cef2: 861a strh r2, [r3, #48] ; 0x30 + * recreate it next time round the loop. If we're lucky the hardware + * will have already sent the packet, the free will really free, and + * there will be zero memory penalty. + */ + + pbuf_free(rambuf); + 800cef4: 69fb ldr r3, [r7, #28] + 800cef6: 0018 movs r0, r3 + 800cef8: f7f8 fbd4 bl 80056a4 +#endif /* IP_FRAG_USES_STATIC_BUF */ + left -= cop; + 800cefc: 223e movs r2, #62 ; 0x3e + 800cefe: 18bb adds r3, r7, r2 + 800cf00: 18b9 adds r1, r7, r2 + 800cf02: 197a adds r2, r7, r5 + 800cf04: 8809 ldrh r1, [r1, #0] + 800cf06: 8812 ldrh r2, [r2, #0] + 800cf08: 1a8a subs r2, r1, r2 + 800cf0a: 801a strh r2, [r3, #0] + ofo += nfb; + 800cf0c: 223c movs r2, #60 ; 0x3c + 800cf0e: 18bb adds r3, r7, r2 + 800cf10: 18b9 adds r1, r7, r2 + 800cf12: 2224 movs r2, #36 ; 0x24 + 800cf14: 18ba adds r2, r7, r2 + 800cf16: 8809 ldrh r1, [r1, #0] + 800cf18: 8812 ldrh r2, [r2, #0] + 800cf1a: 188a adds r2, r1, r2 + 800cf1c: 801a strh r2, [r3, #0] + while (left) { + 800cf1e: 233e movs r3, #62 ; 0x3e + 800cf20: 18fb adds r3, r7, r3 + 800cf22: 881b ldrh r3, [r3, #0] + 800cf24: 2b00 cmp r3, #0 + 800cf26: d000 beq.n 800cf2a + 800cf28: e69e b.n 800cc68 + } +#if IP_FRAG_USES_STATIC_BUF + pbuf_free(rambuf); +#endif /* IP_FRAG_USES_STATIC_BUF */ + snmp_inc_ipfragoks(); + return ERR_OK; + 800cf2a: 2300 movs r3, #0 +} + 800cf2c: 0018 movs r0, r3 + 800cf2e: 46bd mov sp, r7 + 800cf30: b011 add sp, #68 ; 0x44 + 800cf32: bdf0 pop {r4, r5, r6, r7, pc} + 800cf34: 0800cba9 .word 0x0800cba9 + 800cf38: 20003158 .word 0x20003158 + +0800cf3c : +#endif /* ARP_QUEUEING */ + +/** Clean up ARP table entries */ +static void +etharp_free_entry(int i) +{ + 800cf3c: b580 push {r7, lr} + 800cf3e: b082 sub sp, #8 + 800cf40: af00 add r7, sp, #0 + 800cf42: 6078 str r0, [r7, #4] + /* remove from SNMP ARP index tree */ + snmp_delete_arpidx_tree(arp_table[i].netif, &arp_table[i].ipaddr); + /* and empty packet queue */ + if (arp_table[i].q != NULL) { + 800cf44: 4914 ldr r1, [pc, #80] ; (800cf98 ) + 800cf46: 687a ldr r2, [r7, #4] + 800cf48: 0013 movs r3, r2 + 800cf4a: 009b lsls r3, r3, #2 + 800cf4c: 189b adds r3, r3, r2 + 800cf4e: 009b lsls r3, r3, #2 + 800cf50: 585b ldr r3, [r3, r1] + 800cf52: 2b00 cmp r3, #0 + 800cf54: d011 beq.n 800cf7a + /* remove all queued packets */ + LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_free_entry: freeing entry %"U16_F", packet queue %p.\n", (u16_t)i, (void *)(arp_table[i].q))); + free_etharp_q(arp_table[i].q); + 800cf56: 4910 ldr r1, [pc, #64] ; (800cf98 ) + 800cf58: 687a ldr r2, [r7, #4] + 800cf5a: 0013 movs r3, r2 + 800cf5c: 009b lsls r3, r3, #2 + 800cf5e: 189b adds r3, r3, r2 + 800cf60: 009b lsls r3, r3, #2 + 800cf62: 585b ldr r3, [r3, r1] + 800cf64: 0018 movs r0, r3 + 800cf66: f7f8 fb9d bl 80056a4 + arp_table[i].q = NULL; + 800cf6a: 490b ldr r1, [pc, #44] ; (800cf98 ) + 800cf6c: 687a ldr r2, [r7, #4] + 800cf6e: 0013 movs r3, r2 + 800cf70: 009b lsls r3, r3, #2 + 800cf72: 189b adds r3, r3, r2 + 800cf74: 009b lsls r3, r3, #2 + 800cf76: 2200 movs r2, #0 + 800cf78: 505a str r2, [r3, r1] + } + /* recycle entry for re-use */ + arp_table[i].state = ETHARP_STATE_EMPTY; + 800cf7a: 4907 ldr r1, [pc, #28] ; (800cf98 ) + 800cf7c: 687a ldr r2, [r7, #4] + 800cf7e: 0013 movs r3, r2 + 800cf80: 009b lsls r3, r3, #2 + 800cf82: 189b adds r3, r3, r2 + 800cf84: 009b lsls r3, r3, #2 + 800cf86: 18cb adds r3, r1, r3 + 800cf88: 3312 adds r3, #18 + 800cf8a: 2200 movs r2, #0 + 800cf8c: 701a strb r2, [r3, #0] + arp_table[i].ctime = 0; + arp_table[i].netif = NULL; + ip_addr_set_zero(&arp_table[i].ipaddr); + arp_table[i].ethaddr = ethzero; +#endif /* LWIP_DEBUG */ +} + 800cf8e: 46c0 nop ; (mov r8, r8) + 800cf90: 46bd mov sp, r7 + 800cf92: b002 add sp, #8 + 800cf94: bd80 pop {r7, pc} + 800cf96: 46c0 nop ; (mov r8, r8) + 800cf98: 200022c0 .word 0x200022c0 + +0800cf9c : + * This function should be called every ETHARP_TMR_INTERVAL milliseconds (5 seconds), + * in order to expire entries in the ARP table. + */ +void +etharp_tmr(void) +{ + 800cf9c: b580 push {r7, lr} + 800cf9e: b082 sub sp, #8 + 800cfa0: af00 add r7, sp, #0 + u8_t i; + + LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_timer\n")); + /* remove expired entries from the ARP table */ + for (i = 0; i < ARP_TABLE_SIZE; ++i) { + 800cfa2: 1dfb adds r3, r7, #7 + 800cfa4: 2200 movs r2, #0 + 800cfa6: 701a strb r2, [r3, #0] + 800cfa8: e06e b.n 800d088 + u8_t state = arp_table[i].state; + 800cfaa: 1dfb adds r3, r7, #7 + 800cfac: 781a ldrb r2, [r3, #0] + 800cfae: 1db9 adds r1, r7, #6 + 800cfb0: 4839 ldr r0, [pc, #228] ; (800d098 ) + 800cfb2: 0013 movs r3, r2 + 800cfb4: 009b lsls r3, r3, #2 + 800cfb6: 189b adds r3, r3, r2 + 800cfb8: 009b lsls r3, r3, #2 + 800cfba: 18c3 adds r3, r0, r3 + 800cfbc: 3312 adds r3, #18 + 800cfbe: 781b ldrb r3, [r3, #0] + 800cfc0: 700b strb r3, [r1, #0] + if (state != ETHARP_STATE_EMPTY + 800cfc2: 1dbb adds r3, r7, #6 + 800cfc4: 781b ldrb r3, [r3, #0] + 800cfc6: 2b00 cmp r3, #0 + 800cfc8: d059 beq.n 800d07e +#if ETHARP_SUPPORT_STATIC_ENTRIES + && (state != ETHARP_STATE_STATIC) + 800cfca: 1dbb adds r3, r7, #6 + 800cfcc: 781b ldrb r3, [r3, #0] + 800cfce: 2b04 cmp r3, #4 + 800cfd0: d055 beq.n 800d07e +#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */ + ) { + arp_table[i].ctime++; + 800cfd2: 1dfb adds r3, r7, #7 + 800cfd4: 781a ldrb r2, [r3, #0] + 800cfd6: 4930 ldr r1, [pc, #192] ; (800d098 ) + 800cfd8: 0013 movs r3, r2 + 800cfda: 009b lsls r3, r3, #2 + 800cfdc: 189b adds r3, r3, r2 + 800cfde: 009b lsls r3, r3, #2 + 800cfe0: 18cb adds r3, r1, r3 + 800cfe2: 3313 adds r3, #19 + 800cfe4: 781b ldrb r3, [r3, #0] + 800cfe6: 3301 adds r3, #1 + 800cfe8: b2d8 uxtb r0, r3 + 800cfea: 492b ldr r1, [pc, #172] ; (800d098 ) + 800cfec: 0013 movs r3, r2 + 800cfee: 009b lsls r3, r3, #2 + 800cff0: 189b adds r3, r3, r2 + 800cff2: 009b lsls r3, r3, #2 + 800cff4: 18cb adds r3, r1, r3 + 800cff6: 3313 adds r3, #19 + 800cff8: 1c02 adds r2, r0, #0 + 800cffa: 701a strb r2, [r3, #0] + if ((arp_table[i].ctime >= ARP_MAXAGE) || + 800cffc: 1dfb adds r3, r7, #7 + 800cffe: 781a ldrb r2, [r3, #0] + 800d000: 4925 ldr r1, [pc, #148] ; (800d098 ) + 800d002: 0013 movs r3, r2 + 800d004: 009b lsls r3, r3, #2 + 800d006: 189b adds r3, r3, r2 + 800d008: 009b lsls r3, r3, #2 + 800d00a: 18cb adds r3, r1, r3 + 800d00c: 3313 adds r3, #19 + 800d00e: 781b ldrb r3, [r3, #0] + 800d010: 2bef cmp r3, #239 ; 0xef + 800d012: d817 bhi.n 800d044 + ((arp_table[i].state == ETHARP_STATE_PENDING) && + 800d014: 1dfb adds r3, r7, #7 + 800d016: 781a ldrb r2, [r3, #0] + 800d018: 491f ldr r1, [pc, #124] ; (800d098 ) + 800d01a: 0013 movs r3, r2 + 800d01c: 009b lsls r3, r3, #2 + 800d01e: 189b adds r3, r3, r2 + 800d020: 009b lsls r3, r3, #2 + 800d022: 18cb adds r3, r1, r3 + 800d024: 3312 adds r3, #18 + 800d026: 781b ldrb r3, [r3, #0] + if ((arp_table[i].ctime >= ARP_MAXAGE) || + 800d028: 2b01 cmp r3, #1 + 800d02a: d111 bne.n 800d050 + (arp_table[i].ctime >= ARP_MAXPENDING))) { + 800d02c: 1dfb adds r3, r7, #7 + 800d02e: 781a ldrb r2, [r3, #0] + 800d030: 4919 ldr r1, [pc, #100] ; (800d098 ) + 800d032: 0013 movs r3, r2 + 800d034: 009b lsls r3, r3, #2 + 800d036: 189b adds r3, r3, r2 + 800d038: 009b lsls r3, r3, #2 + 800d03a: 18cb adds r3, r1, r3 + 800d03c: 3313 adds r3, #19 + 800d03e: 781b ldrb r3, [r3, #0] + ((arp_table[i].state == ETHARP_STATE_PENDING) && + 800d040: 2b01 cmp r3, #1 + 800d042: d905 bls.n 800d050 + /* pending or stable entry has become old! */ + LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_timer: expired %s entry %"U16_F".\n", + arp_table[i].state >= ETHARP_STATE_STABLE ? "stable" : "pending", (u16_t)i)); + /* clean up entries that have just been expired */ + etharp_free_entry(i); + 800d044: 1dfb adds r3, r7, #7 + 800d046: 781b ldrb r3, [r3, #0] + 800d048: 0018 movs r0, r3 + 800d04a: f7ff ff77 bl 800cf3c + 800d04e: e016 b.n 800d07e + } + else if (arp_table[i].state == ETHARP_STATE_STABLE_REREQUESTING) { + 800d050: 1dfb adds r3, r7, #7 + 800d052: 781a ldrb r2, [r3, #0] + 800d054: 4910 ldr r1, [pc, #64] ; (800d098 ) + 800d056: 0013 movs r3, r2 + 800d058: 009b lsls r3, r3, #2 + 800d05a: 189b adds r3, r3, r2 + 800d05c: 009b lsls r3, r3, #2 + 800d05e: 18cb adds r3, r1, r3 + 800d060: 3312 adds r3, #18 + 800d062: 781b ldrb r3, [r3, #0] + 800d064: 2b03 cmp r3, #3 + 800d066: d10a bne.n 800d07e + /* Reset state to stable, so that the next transmitted packet will + re-send an ARP request. */ + arp_table[i].state = ETHARP_STATE_STABLE; + 800d068: 1dfb adds r3, r7, #7 + 800d06a: 781a ldrb r2, [r3, #0] + 800d06c: 490a ldr r1, [pc, #40] ; (800d098 ) + 800d06e: 0013 movs r3, r2 + 800d070: 009b lsls r3, r3, #2 + 800d072: 189b adds r3, r3, r2 + 800d074: 009b lsls r3, r3, #2 + 800d076: 18cb adds r3, r1, r3 + 800d078: 3312 adds r3, #18 + 800d07a: 2202 movs r2, #2 + 800d07c: 701a strb r2, [r3, #0] + for (i = 0; i < ARP_TABLE_SIZE; ++i) { + 800d07e: 1dfb adds r3, r7, #7 + 800d080: 1dfa adds r2, r7, #7 + 800d082: 7812 ldrb r2, [r2, #0] + 800d084: 3201 adds r2, #1 + 800d086: 701a strb r2, [r3, #0] + 800d088: 1dfb adds r3, r7, #7 + 800d08a: 781b ldrb r3, [r3, #0] + 800d08c: 2b09 cmp r3, #9 + 800d08e: d98c bls.n 800cfaa + /* resend an ARP query here? */ + } +#endif /* ARP_QUEUEING */ + } + } +} + 800d090: 46c0 nop ; (mov r8, r8) + 800d092: 46bd mov sp, r7 + 800d094: b002 add sp, #8 + 800d096: bd80 pop {r7, pc} + 800d098: 200022c0 .word 0x200022c0 + +0800d09c : + * @return The ARP entry index that matched or is created, ERR_MEM if no + * entry is found or could be recycled. + */ +static s8_t +etharp_find_entry(ip_addr_t *ipaddr, u8_t flags) +{ + 800d09c: b580 push {r7, lr} + 800d09e: b086 sub sp, #24 + 800d0a0: af00 add r7, sp, #0 + 800d0a2: 6078 str r0, [r7, #4] + 800d0a4: 000a movs r2, r1 + 800d0a6: 1cfb adds r3, r7, #3 + 800d0a8: 701a strb r2, [r3, #0] + s8_t old_pending = ARP_TABLE_SIZE, old_stable = ARP_TABLE_SIZE; + 800d0aa: 2317 movs r3, #23 + 800d0ac: 18fb adds r3, r7, r3 + 800d0ae: 220a movs r2, #10 + 800d0b0: 701a strb r2, [r3, #0] + 800d0b2: 2316 movs r3, #22 + 800d0b4: 18fb adds r3, r7, r3 + 800d0b6: 220a movs r2, #10 + 800d0b8: 701a strb r2, [r3, #0] + s8_t empty = ARP_TABLE_SIZE; + 800d0ba: 2315 movs r3, #21 + 800d0bc: 18fb adds r3, r7, r3 + 800d0be: 220a movs r2, #10 + 800d0c0: 701a strb r2, [r3, #0] + u8_t i = 0, age_pending = 0, age_stable = 0; + 800d0c2: 2114 movs r1, #20 + 800d0c4: 187b adds r3, r7, r1 + 800d0c6: 2200 movs r2, #0 + 800d0c8: 701a strb r2, [r3, #0] + 800d0ca: 2313 movs r3, #19 + 800d0cc: 18fb adds r3, r7, r3 + 800d0ce: 2200 movs r2, #0 + 800d0d0: 701a strb r2, [r3, #0] + 800d0d2: 2312 movs r3, #18 + 800d0d4: 18fb adds r3, r7, r3 + 800d0d6: 2200 movs r2, #0 + 800d0d8: 701a strb r2, [r3, #0] + /* oldest entry with packets on queue */ + s8_t old_queue = ARP_TABLE_SIZE; + 800d0da: 2311 movs r3, #17 + 800d0dc: 18fb adds r3, r7, r3 + 800d0de: 220a movs r2, #10 + 800d0e0: 701a strb r2, [r3, #0] + /* its age */ + u8_t age_queue = 0; + 800d0e2: 2310 movs r3, #16 + 800d0e4: 18fb adds r3, r7, r3 + 800d0e6: 2200 movs r2, #0 + 800d0e8: 701a strb r2, [r3, #0] + * 4) remember the oldest pending entry with queued packets (if any) + * 5) search for a matching IP entry, either pending or stable + * until 5 matches, or all entries are searched for. + */ + + for (i = 0; i < ARP_TABLE_SIZE; ++i) { + 800d0ea: 187b adds r3, r7, r1 + 800d0ec: 2200 movs r2, #0 + 800d0ee: 701a strb r2, [r3, #0] + 800d0f0: e0c7 b.n 800d282 + u8_t state = arp_table[i].state; + 800d0f2: 2314 movs r3, #20 + 800d0f4: 18fb adds r3, r7, r3 + 800d0f6: 781a ldrb r2, [r3, #0] + 800d0f8: 230f movs r3, #15 + 800d0fa: 18f9 adds r1, r7, r3 + 800d0fc: 48a4 ldr r0, [pc, #656] ; (800d390 ) + 800d0fe: 0013 movs r3, r2 + 800d100: 009b lsls r3, r3, #2 + 800d102: 189b adds r3, r3, r2 + 800d104: 009b lsls r3, r3, #2 + 800d106: 18c3 adds r3, r0, r3 + 800d108: 3312 adds r3, #18 + 800d10a: 781b ldrb r3, [r3, #0] + 800d10c: 700b strb r3, [r1, #0] + /* no empty entry found yet and now we do find one? */ + if ((empty == ARP_TABLE_SIZE) && (state == ETHARP_STATE_EMPTY)) { + 800d10e: 2315 movs r3, #21 + 800d110: 18fb adds r3, r7, r3 + 800d112: 781b ldrb r3, [r3, #0] + 800d114: b25b sxtb r3, r3 + 800d116: 2b0a cmp r3, #10 + 800d118: d10b bne.n 800d132 + 800d11a: 230f movs r3, #15 + 800d11c: 18fb adds r3, r7, r3 + 800d11e: 781b ldrb r3, [r3, #0] + 800d120: 2b00 cmp r3, #0 + 800d122: d106 bne.n 800d132 + LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_find_entry: found empty entry %"U16_F"\n", (u16_t)i)); + /* remember first empty entry */ + empty = i; + 800d124: 2315 movs r3, #21 + 800d126: 18fb adds r3, r7, r3 + 800d128: 2214 movs r2, #20 + 800d12a: 18ba adds r2, r7, r2 + 800d12c: 7812 ldrb r2, [r2, #0] + 800d12e: 701a strb r2, [r3, #0] + 800d130: e0a1 b.n 800d276 + } else if (state != ETHARP_STATE_EMPTY) { + 800d132: 230f movs r3, #15 + 800d134: 18fb adds r3, r7, r3 + 800d136: 781b ldrb r3, [r3, #0] + 800d138: 2b00 cmp r3, #0 + 800d13a: d100 bne.n 800d13e + 800d13c: e09b b.n 800d276 + LWIP_ASSERT("state == ETHARP_STATE_PENDING || state >= ETHARP_STATE_STABLE", + state == ETHARP_STATE_PENDING || state >= ETHARP_STATE_STABLE); + /* if given, does IP address match IP address in ARP entry? */ + if (ipaddr && ip_addr_cmp(ipaddr, &arp_table[i].ipaddr)) { + 800d13e: 687b ldr r3, [r7, #4] + 800d140: 2b00 cmp r3, #0 + 800d142: d013 beq.n 800d16c + 800d144: 687b ldr r3, [r7, #4] + 800d146: 6819 ldr r1, [r3, #0] + 800d148: 2314 movs r3, #20 + 800d14a: 18fb adds r3, r7, r3 + 800d14c: 781a ldrb r2, [r3, #0] + 800d14e: 4890 ldr r0, [pc, #576] ; (800d390 ) + 800d150: 0013 movs r3, r2 + 800d152: 009b lsls r3, r3, #2 + 800d154: 189b adds r3, r3, r2 + 800d156: 009b lsls r3, r3, #2 + 800d158: 18c3 adds r3, r0, r3 + 800d15a: 3304 adds r3, #4 + 800d15c: 681b ldr r3, [r3, #0] + 800d15e: 4299 cmp r1, r3 + 800d160: d104 bne.n 800d16c + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: found matching entry %"U16_F"\n", (u16_t)i)); + /* found exact IP address match, simply bail out */ + return i; + 800d162: 2314 movs r3, #20 + 800d164: 18fb adds r3, r7, r3 + 800d166: 781b ldrb r3, [r3, #0] + 800d168: b25b sxtb r3, r3 + 800d16a: e10c b.n 800d386 + } + /* pending entry? */ + if (state == ETHARP_STATE_PENDING) { + 800d16c: 230f movs r3, #15 + 800d16e: 18fb adds r3, r7, r3 + 800d170: 781b ldrb r3, [r3, #0] + 800d172: 2b01 cmp r3, #1 + 800d174: d152 bne.n 800d21c + /* pending with queued packets? */ + if (arp_table[i].q != NULL) { + 800d176: 2314 movs r3, #20 + 800d178: 18fb adds r3, r7, r3 + 800d17a: 781a ldrb r2, [r3, #0] + 800d17c: 4984 ldr r1, [pc, #528] ; (800d390 ) + 800d17e: 0013 movs r3, r2 + 800d180: 009b lsls r3, r3, #2 + 800d182: 189b adds r3, r3, r2 + 800d184: 009b lsls r3, r3, #2 + 800d186: 585b ldr r3, [r3, r1] + 800d188: 2b00 cmp r3, #0 + 800d18a: d023 beq.n 800d1d4 + if (arp_table[i].ctime >= age_queue) { + 800d18c: 2314 movs r3, #20 + 800d18e: 18fb adds r3, r7, r3 + 800d190: 781a ldrb r2, [r3, #0] + 800d192: 497f ldr r1, [pc, #508] ; (800d390 ) + 800d194: 0013 movs r3, r2 + 800d196: 009b lsls r3, r3, #2 + 800d198: 189b adds r3, r3, r2 + 800d19a: 009b lsls r3, r3, #2 + 800d19c: 18cb adds r3, r1, r3 + 800d19e: 3313 adds r3, #19 + 800d1a0: 781b ldrb r3, [r3, #0] + 800d1a2: 2210 movs r2, #16 + 800d1a4: 18ba adds r2, r7, r2 + 800d1a6: 7812 ldrb r2, [r2, #0] + 800d1a8: 429a cmp r2, r3 + 800d1aa: d864 bhi.n 800d276 + old_queue = i; + 800d1ac: 2311 movs r3, #17 + 800d1ae: 18fb adds r3, r7, r3 + 800d1b0: 2114 movs r1, #20 + 800d1b2: 187a adds r2, r7, r1 + 800d1b4: 7812 ldrb r2, [r2, #0] + 800d1b6: 701a strb r2, [r3, #0] + age_queue = arp_table[i].ctime; + 800d1b8: 187b adds r3, r7, r1 + 800d1ba: 781a ldrb r2, [r3, #0] + 800d1bc: 2310 movs r3, #16 + 800d1be: 18f9 adds r1, r7, r3 + 800d1c0: 4873 ldr r0, [pc, #460] ; (800d390 ) + 800d1c2: 0013 movs r3, r2 + 800d1c4: 009b lsls r3, r3, #2 + 800d1c6: 189b adds r3, r3, r2 + 800d1c8: 009b lsls r3, r3, #2 + 800d1ca: 18c3 adds r3, r0, r3 + 800d1cc: 3313 adds r3, #19 + 800d1ce: 781b ldrb r3, [r3, #0] + 800d1d0: 700b strb r3, [r1, #0] + 800d1d2: e050 b.n 800d276 + } + } else + /* pending without queued packets? */ + { + if (arp_table[i].ctime >= age_pending) { + 800d1d4: 2314 movs r3, #20 + 800d1d6: 18fb adds r3, r7, r3 + 800d1d8: 781a ldrb r2, [r3, #0] + 800d1da: 496d ldr r1, [pc, #436] ; (800d390 ) + 800d1dc: 0013 movs r3, r2 + 800d1de: 009b lsls r3, r3, #2 + 800d1e0: 189b adds r3, r3, r2 + 800d1e2: 009b lsls r3, r3, #2 + 800d1e4: 18cb adds r3, r1, r3 + 800d1e6: 3313 adds r3, #19 + 800d1e8: 781b ldrb r3, [r3, #0] + 800d1ea: 2213 movs r2, #19 + 800d1ec: 18ba adds r2, r7, r2 + 800d1ee: 7812 ldrb r2, [r2, #0] + 800d1f0: 429a cmp r2, r3 + 800d1f2: d840 bhi.n 800d276 + old_pending = i; + 800d1f4: 2317 movs r3, #23 + 800d1f6: 18fb adds r3, r7, r3 + 800d1f8: 2114 movs r1, #20 + 800d1fa: 187a adds r2, r7, r1 + 800d1fc: 7812 ldrb r2, [r2, #0] + 800d1fe: 701a strb r2, [r3, #0] + age_pending = arp_table[i].ctime; + 800d200: 187b adds r3, r7, r1 + 800d202: 781a ldrb r2, [r3, #0] + 800d204: 2313 movs r3, #19 + 800d206: 18f9 adds r1, r7, r3 + 800d208: 4861 ldr r0, [pc, #388] ; (800d390 ) + 800d20a: 0013 movs r3, r2 + 800d20c: 009b lsls r3, r3, #2 + 800d20e: 189b adds r3, r3, r2 + 800d210: 009b lsls r3, r3, #2 + 800d212: 18c3 adds r3, r0, r3 + 800d214: 3313 adds r3, #19 + 800d216: 781b ldrb r3, [r3, #0] + 800d218: 700b strb r3, [r1, #0] + 800d21a: e02c b.n 800d276 + } + } + /* stable entry? */ + } else if (state >= ETHARP_STATE_STABLE) { + 800d21c: 230f movs r3, #15 + 800d21e: 18fb adds r3, r7, r3 + 800d220: 781b ldrb r3, [r3, #0] + 800d222: 2b01 cmp r3, #1 + 800d224: d927 bls.n 800d276 +#if ETHARP_SUPPORT_STATIC_ENTRIES + /* don't record old_stable for static entries since they never expire */ + if (state < ETHARP_STATE_STATIC) + 800d226: 230f movs r3, #15 + 800d228: 18fb adds r3, r7, r3 + 800d22a: 781b ldrb r3, [r3, #0] + 800d22c: 2b03 cmp r3, #3 + 800d22e: d822 bhi.n 800d276 +#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */ + { + /* remember entry with oldest stable entry in oldest, its age in maxtime */ + if (arp_table[i].ctime >= age_stable) { + 800d230: 2314 movs r3, #20 + 800d232: 18fb adds r3, r7, r3 + 800d234: 781a ldrb r2, [r3, #0] + 800d236: 4956 ldr r1, [pc, #344] ; (800d390 ) + 800d238: 0013 movs r3, r2 + 800d23a: 009b lsls r3, r3, #2 + 800d23c: 189b adds r3, r3, r2 + 800d23e: 009b lsls r3, r3, #2 + 800d240: 18cb adds r3, r1, r3 + 800d242: 3313 adds r3, #19 + 800d244: 781b ldrb r3, [r3, #0] + 800d246: 2212 movs r2, #18 + 800d248: 18ba adds r2, r7, r2 + 800d24a: 7812 ldrb r2, [r2, #0] + 800d24c: 429a cmp r2, r3 + 800d24e: d812 bhi.n 800d276 + old_stable = i; + 800d250: 2316 movs r3, #22 + 800d252: 18fb adds r3, r7, r3 + 800d254: 2114 movs r1, #20 + 800d256: 187a adds r2, r7, r1 + 800d258: 7812 ldrb r2, [r2, #0] + 800d25a: 701a strb r2, [r3, #0] + age_stable = arp_table[i].ctime; + 800d25c: 187b adds r3, r7, r1 + 800d25e: 781a ldrb r2, [r3, #0] + 800d260: 2312 movs r3, #18 + 800d262: 18f9 adds r1, r7, r3 + 800d264: 484a ldr r0, [pc, #296] ; (800d390 ) + 800d266: 0013 movs r3, r2 + 800d268: 009b lsls r3, r3, #2 + 800d26a: 189b adds r3, r3, r2 + 800d26c: 009b lsls r3, r3, #2 + 800d26e: 18c3 adds r3, r0, r3 + 800d270: 3313 adds r3, #19 + 800d272: 781b ldrb r3, [r3, #0] + 800d274: 700b strb r3, [r1, #0] + for (i = 0; i < ARP_TABLE_SIZE; ++i) { + 800d276: 2214 movs r2, #20 + 800d278: 18bb adds r3, r7, r2 + 800d27a: 18ba adds r2, r7, r2 + 800d27c: 7812 ldrb r2, [r2, #0] + 800d27e: 3201 adds r2, #1 + 800d280: 701a strb r2, [r3, #0] + 800d282: 2314 movs r3, #20 + 800d284: 18fb adds r3, r7, r3 + 800d286: 781b ldrb r3, [r3, #0] + 800d288: 2b09 cmp r3, #9 + 800d28a: d800 bhi.n 800d28e + 800d28c: e731 b.n 800d0f2 + } + } + /* { we have no match } => try to create a new entry */ + + /* don't create new entry, only search? */ + if (((flags & ETHARP_FLAG_FIND_ONLY) != 0) || + 800d28e: 1cfb adds r3, r7, #3 + 800d290: 781b ldrb r3, [r3, #0] + 800d292: 2202 movs r2, #2 + 800d294: 4013 ands r3, r2 + 800d296: d10a bne.n 800d2ae + 800d298: 2315 movs r3, #21 + 800d29a: 18fb adds r3, r7, r3 + 800d29c: 781b ldrb r3, [r3, #0] + 800d29e: b25b sxtb r3, r3 + 800d2a0: 2b0a cmp r3, #10 + 800d2a2: d107 bne.n 800d2b4 + /* or no empty entry found and not allowed to recycle? */ + ((empty == ARP_TABLE_SIZE) && ((flags & ETHARP_FLAG_TRY_HARD) == 0))) { + 800d2a4: 1cfb adds r3, r7, #3 + 800d2a6: 781b ldrb r3, [r3, #0] + 800d2a8: 2201 movs r2, #1 + 800d2aa: 4013 ands r3, r2 + 800d2ac: d102 bne.n 800d2b4 + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: no empty entry found and not allowed to recycle\n")); + return (s8_t)ERR_MEM; + 800d2ae: 2301 movs r3, #1 + 800d2b0: 425b negs r3, r3 + 800d2b2: e068 b.n 800d386 + * + * { ETHARP_FLAG_TRY_HARD is set at this point } + */ + + /* 1) empty entry available? */ + if (empty < ARP_TABLE_SIZE) { + 800d2b4: 2315 movs r3, #21 + 800d2b6: 18fb adds r3, r7, r3 + 800d2b8: 781b ldrb r3, [r3, #0] + 800d2ba: b25b sxtb r3, r3 + 800d2bc: 2b09 cmp r3, #9 + 800d2be: dc06 bgt.n 800d2ce + i = empty; + 800d2c0: 2314 movs r3, #20 + 800d2c2: 18fb adds r3, r7, r3 + 800d2c4: 2215 movs r2, #21 + 800d2c6: 18ba adds r2, r7, r2 + 800d2c8: 7812 ldrb r2, [r2, #0] + 800d2ca: 701a strb r2, [r3, #0] + 800d2cc: e035 b.n 800d33a + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: selecting empty entry %"U16_F"\n", (u16_t)i)); + } else { + /* 2) found recyclable stable entry? */ + if (old_stable < ARP_TABLE_SIZE) { + 800d2ce: 2316 movs r3, #22 + 800d2d0: 18fb adds r3, r7, r3 + 800d2d2: 781b ldrb r3, [r3, #0] + 800d2d4: b25b sxtb r3, r3 + 800d2d6: 2b09 cmp r3, #9 + 800d2d8: dc0c bgt.n 800d2f4 + /* recycle oldest stable*/ + i = old_stable; + 800d2da: 2114 movs r1, #20 + 800d2dc: 187b adds r3, r7, r1 + 800d2de: 2216 movs r2, #22 + 800d2e0: 18ba adds r2, r7, r2 + 800d2e2: 7812 ldrb r2, [r2, #0] + 800d2e4: 701a strb r2, [r3, #0] + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: selecting oldest stable entry %"U16_F"\n", (u16_t)i)); + /* no queued packets should exist on stable entries */ + LWIP_ASSERT("arp_table[i].q == NULL", arp_table[i].q == NULL); + 800d2e6: 187b adds r3, r7, r1 + 800d2e8: 781a ldrb r2, [r3, #0] + 800d2ea: 0013 movs r3, r2 + 800d2ec: 009b lsls r3, r3, #2 + 800d2ee: 189b adds r3, r3, r2 + 800d2f0: 009b lsls r3, r3, #2 + 800d2f2: e01c b.n 800d32e + /* 3) found recyclable pending entry without queued packets? */ + } else if (old_pending < ARP_TABLE_SIZE) { + 800d2f4: 2317 movs r3, #23 + 800d2f6: 18fb adds r3, r7, r3 + 800d2f8: 781b ldrb r3, [r3, #0] + 800d2fa: b25b sxtb r3, r3 + 800d2fc: 2b09 cmp r3, #9 + 800d2fe: dc06 bgt.n 800d30e + /* recycle oldest pending */ + i = old_pending; + 800d300: 2314 movs r3, #20 + 800d302: 18fb adds r3, r7, r3 + 800d304: 2217 movs r2, #23 + 800d306: 18ba adds r2, r7, r2 + 800d308: 7812 ldrb r2, [r2, #0] + 800d30a: 701a strb r2, [r3, #0] + 800d30c: e00f b.n 800d32e + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: selecting oldest pending entry %"U16_F" (without queue)\n", (u16_t)i)); + /* 4) found recyclable pending entry with queued packets? */ + } else if (old_queue < ARP_TABLE_SIZE) { + 800d30e: 2311 movs r3, #17 + 800d310: 18fb adds r3, r7, r3 + 800d312: 781b ldrb r3, [r3, #0] + 800d314: b25b sxtb r3, r3 + 800d316: 2b09 cmp r3, #9 + 800d318: dc06 bgt.n 800d328 + /* recycle oldest pending (queued packets are free in etharp_free_entry) */ + i = old_queue; + 800d31a: 2314 movs r3, #20 + 800d31c: 18fb adds r3, r7, r3 + 800d31e: 2211 movs r2, #17 + 800d320: 18ba adds r2, r7, r2 + 800d322: 7812 ldrb r2, [r2, #0] + 800d324: 701a strb r2, [r3, #0] + 800d326: e002 b.n 800d32e + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: selecting oldest pending entry %"U16_F", freeing packet queue %p\n", (u16_t)i, (void *)(arp_table[i].q))); + /* no empty or recyclable entries found */ + } else { + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: no empty or recyclable entries found\n")); + return (s8_t)ERR_MEM; + 800d328: 2301 movs r3, #1 + 800d32a: 425b negs r3, r3 + 800d32c: e02b b.n 800d386 + } + + /* { empty or recyclable entry found } */ + LWIP_ASSERT("i < ARP_TABLE_SIZE", i < ARP_TABLE_SIZE); + etharp_free_entry(i); + 800d32e: 2314 movs r3, #20 + 800d330: 18fb adds r3, r7, r3 + 800d332: 781b ldrb r3, [r3, #0] + 800d334: 0018 movs r0, r3 + 800d336: f7ff fe01 bl 800cf3c + } + + LWIP_ASSERT("i < ARP_TABLE_SIZE", i < ARP_TABLE_SIZE); + LWIP_ASSERT("arp_table[i].state == ETHARP_STATE_EMPTY", + 800d33a: 2314 movs r3, #20 + 800d33c: 18fb adds r3, r7, r3 + 800d33e: 781a ldrb r2, [r3, #0] + 800d340: 0013 movs r3, r2 + 800d342: 009b lsls r3, r3, #2 + 800d344: 189b adds r3, r3, r2 + 800d346: 009b lsls r3, r3, #2 + arp_table[i].state == ETHARP_STATE_EMPTY); + + /* IP address given? */ + if (ipaddr != NULL) { + 800d348: 687b ldr r3, [r7, #4] + 800d34a: 2b00 cmp r3, #0 + 800d34c: d00c beq.n 800d368 + /* set IP address */ + ip_addr_copy(arp_table[i].ipaddr, *ipaddr); + 800d34e: 2314 movs r3, #20 + 800d350: 18fb adds r3, r7, r3 + 800d352: 781a ldrb r2, [r3, #0] + 800d354: 687b ldr r3, [r7, #4] + 800d356: 6819 ldr r1, [r3, #0] + 800d358: 480d ldr r0, [pc, #52] ; (800d390 ) + 800d35a: 0013 movs r3, r2 + 800d35c: 009b lsls r3, r3, #2 + 800d35e: 189b adds r3, r3, r2 + 800d360: 009b lsls r3, r3, #2 + 800d362: 18c3 adds r3, r0, r3 + 800d364: 3304 adds r3, #4 + 800d366: 6019 str r1, [r3, #0] + } + arp_table[i].ctime = 0; + 800d368: 2014 movs r0, #20 + 800d36a: 183b adds r3, r7, r0 + 800d36c: 781a ldrb r2, [r3, #0] + 800d36e: 4908 ldr r1, [pc, #32] ; (800d390 ) + 800d370: 0013 movs r3, r2 + 800d372: 009b lsls r3, r3, #2 + 800d374: 189b adds r3, r3, r2 + 800d376: 009b lsls r3, r3, #2 + 800d378: 18cb adds r3, r1, r3 + 800d37a: 3313 adds r3, #19 + 800d37c: 2200 movs r2, #0 + 800d37e: 701a strb r2, [r3, #0] + return (err_t)i; + 800d380: 183b adds r3, r7, r0 + 800d382: 781b ldrb r3, [r3, #0] + 800d384: b25b sxtb r3, r3 +} + 800d386: 0018 movs r0, r3 + 800d388: 46bd mov sp, r7 + 800d38a: b006 add sp, #24 + 800d38c: bd80 pop {r7, pc} + 800d38e: 46c0 nop ; (mov r8, r8) + 800d390: 200022c0 .word 0x200022c0 + +0800d394 : + * @params dst the destination MAC address to be copied into the ethernet header + * @return ERR_OK if the packet was sent, any other err_t on failure + */ +static err_t +etharp_send_ip(struct netif *netif, struct pbuf *p, struct eth_addr *src, struct eth_addr *dst) +{ + 800d394: b580 push {r7, lr} + 800d396: b086 sub sp, #24 + 800d398: af00 add r7, sp, #0 + 800d39a: 60f8 str r0, [r7, #12] + 800d39c: 60b9 str r1, [r7, #8] + 800d39e: 607a str r2, [r7, #4] + 800d3a0: 603b str r3, [r7, #0] + struct eth_hdr *ethhdr = (struct eth_hdr *)p->payload; + 800d3a2: 68bb ldr r3, [r7, #8] + 800d3a4: 685b ldr r3, [r3, #4] + 800d3a6: 617b str r3, [r7, #20] + + LWIP_ASSERT("netif->hwaddr_len must be the same as ETHARP_HWADDR_LEN for etharp!", + (netif->hwaddr_len == ETHARP_HWADDR_LEN)); + ETHADDR32_COPY(ðhdr->dest, dst); + 800d3a8: 697b ldr r3, [r7, #20] + 800d3aa: 6839 ldr r1, [r7, #0] + 800d3ac: 2206 movs r2, #6 + 800d3ae: 0018 movs r0, r3 + 800d3b0: f002 fc77 bl 800fca2 + ETHADDR16_COPY(ðhdr->src, src); + 800d3b4: 697b ldr r3, [r7, #20] + 800d3b6: 3306 adds r3, #6 + 800d3b8: 6879 ldr r1, [r7, #4] + 800d3ba: 2206 movs r2, #6 + 800d3bc: 0018 movs r0, r3 + 800d3be: f002 fc70 bl 800fca2 + ethhdr->type = PP_HTONS(ETHTYPE_IP); + 800d3c2: 697b ldr r3, [r7, #20] + 800d3c4: 7b1a ldrb r2, [r3, #12] + 800d3c6: 2100 movs r1, #0 + 800d3c8: 400a ands r2, r1 + 800d3ca: 1c11 adds r1, r2, #0 + 800d3cc: 2208 movs r2, #8 + 800d3ce: 430a orrs r2, r1 + 800d3d0: 731a strb r2, [r3, #12] + 800d3d2: 7b5a ldrb r2, [r3, #13] + 800d3d4: 2100 movs r1, #0 + 800d3d6: 400a ands r2, r1 + 800d3d8: 735a strb r2, [r3, #13] + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_send_ip: sending packet %p\n", (void *)p)); + /* send the packet */ + return netif->linkoutput(netif, p); + 800d3da: 68fb ldr r3, [r7, #12] + 800d3dc: 699b ldr r3, [r3, #24] + 800d3de: 68b9 ldr r1, [r7, #8] + 800d3e0: 68fa ldr r2, [r7, #12] + 800d3e2: 0010 movs r0, r2 + 800d3e4: 4798 blx r3 + 800d3e6: 0003 movs r3, r0 +} + 800d3e8: 0018 movs r0, r3 + 800d3ea: 46bd mov sp, r7 + 800d3ec: b006 add sp, #24 + 800d3ee: bd80 pop {r7, pc} + +0800d3f0 : + * + * @see pbuf_free() + */ +static err_t +etharp_update_arp_entry(struct netif *netif, ip_addr_t *ipaddr, struct eth_addr *ethaddr, u8_t flags) +{ + 800d3f0: b5b0 push {r4, r5, r7, lr} + 800d3f2: b086 sub sp, #24 + 800d3f4: af00 add r7, sp, #0 + 800d3f6: 60f8 str r0, [r7, #12] + 800d3f8: 60b9 str r1, [r7, #8] + 800d3fa: 607a str r2, [r7, #4] + 800d3fc: 001a movs r2, r3 + 800d3fe: 1cfb adds r3, r7, #3 + 800d400: 701a strb r2, [r3, #0] + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_update_arp_entry: %"U16_F".%"U16_F".%"U16_F".%"U16_F" - %02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F"\n", + ip4_addr1_16(ipaddr), ip4_addr2_16(ipaddr), ip4_addr3_16(ipaddr), ip4_addr4_16(ipaddr), + ethaddr->addr[0], ethaddr->addr[1], ethaddr->addr[2], + ethaddr->addr[3], ethaddr->addr[4], ethaddr->addr[5])); + /* non-unicast address? */ + if (ip_addr_isany(ipaddr) || + 800d402: 68bb ldr r3, [r7, #8] + 800d404: 2b00 cmp r3, #0 + 800d406: d012 beq.n 800d42e + 800d408: 68bb ldr r3, [r7, #8] + 800d40a: 681b ldr r3, [r3, #0] + 800d40c: 2b00 cmp r3, #0 + 800d40e: d00e beq.n 800d42e + ip_addr_isbroadcast(ipaddr, netif) || + 800d410: 68bb ldr r3, [r7, #8] + 800d412: 681b ldr r3, [r3, #0] + 800d414: 68fa ldr r2, [r7, #12] + 800d416: 0011 movs r1, r2 + 800d418: 0018 movs r0, r3 + 800d41a: f7fe fe2f bl 800c07c + 800d41e: 1e03 subs r3, r0, #0 + if (ip_addr_isany(ipaddr) || + 800d420: d105 bne.n 800d42e + ip_addr_ismulticast(ipaddr)) { + 800d422: 68bb ldr r3, [r7, #8] + 800d424: 681b ldr r3, [r3, #0] + 800d426: 22f0 movs r2, #240 ; 0xf0 + 800d428: 4013 ands r3, r2 + ip_addr_isbroadcast(ipaddr, netif) || + 800d42a: 2be0 cmp r3, #224 ; 0xe0 + 800d42c: d102 bne.n 800d434 + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_update_arp_entry: will not add non-unicast IP address to ARP cache\n")); + return ERR_ARG; + 800d42e: 230e movs r3, #14 + 800d430: 425b negs r3, r3 + 800d432: e08a b.n 800d54a + } + /* find or create ARP entry */ + i = etharp_find_entry(ipaddr, flags); + 800d434: 2517 movs r5, #23 + 800d436: 197c adds r4, r7, r5 + 800d438: 1cfb adds r3, r7, #3 + 800d43a: 781a ldrb r2, [r3, #0] + 800d43c: 68bb ldr r3, [r7, #8] + 800d43e: 0011 movs r1, r2 + 800d440: 0018 movs r0, r3 + 800d442: f7ff fe2b bl 800d09c + 800d446: 0003 movs r3, r0 + 800d448: 7023 strb r3, [r4, #0] + /* bail out if no entry could be found */ + if (i < 0) { + 800d44a: 197b adds r3, r7, r5 + 800d44c: 781b ldrb r3, [r3, #0] + 800d44e: 2b7f cmp r3, #127 ; 0x7f + 800d450: d904 bls.n 800d45c + return (err_t)i; + 800d452: 2317 movs r3, #23 + 800d454: 18fb adds r3, r7, r3 + 800d456: 781b ldrb r3, [r3, #0] + 800d458: b25b sxtb r3, r3 + 800d45a: e076 b.n 800d54a + } + +#if ETHARP_SUPPORT_STATIC_ENTRIES + if (flags & ETHARP_FLAG_STATIC_ENTRY) { + 800d45c: 1cfb adds r3, r7, #3 + 800d45e: 781b ldrb r3, [r3, #0] + 800d460: 2204 movs r2, #4 + 800d462: 4013 ands r3, r2 + 800d464: d00d beq.n 800d482 + /* record static type */ + arp_table[i].state = ETHARP_STATE_STATIC; + 800d466: 2317 movs r3, #23 + 800d468: 18fb adds r3, r7, r3 + 800d46a: 2200 movs r2, #0 + 800d46c: 569a ldrsb r2, [r3, r2] + 800d46e: 4939 ldr r1, [pc, #228] ; (800d554 ) + 800d470: 0013 movs r3, r2 + 800d472: 009b lsls r3, r3, #2 + 800d474: 189b adds r3, r3, r2 + 800d476: 009b lsls r3, r3, #2 + 800d478: 18cb adds r3, r1, r3 + 800d47a: 3312 adds r3, #18 + 800d47c: 2204 movs r2, #4 + 800d47e: 701a strb r2, [r3, #0] + 800d480: e00c b.n 800d49c + } else +#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */ + { + /* mark it stable */ + arp_table[i].state = ETHARP_STATE_STABLE; + 800d482: 2317 movs r3, #23 + 800d484: 18fb adds r3, r7, r3 + 800d486: 2200 movs r2, #0 + 800d488: 569a ldrsb r2, [r3, r2] + 800d48a: 4932 ldr r1, [pc, #200] ; (800d554 ) + 800d48c: 0013 movs r3, r2 + 800d48e: 009b lsls r3, r3, #2 + 800d490: 189b adds r3, r3, r2 + 800d492: 009b lsls r3, r3, #2 + 800d494: 18cb adds r3, r1, r3 + 800d496: 3312 adds r3, #18 + 800d498: 2202 movs r2, #2 + 800d49a: 701a strb r2, [r3, #0] + } + + /* record network interface */ + arp_table[i].netif = netif; + 800d49c: 2417 movs r4, #23 + 800d49e: 193b adds r3, r7, r4 + 800d4a0: 2200 movs r2, #0 + 800d4a2: 569a ldrsb r2, [r3, r2] + 800d4a4: 492b ldr r1, [pc, #172] ; (800d554 ) + 800d4a6: 0013 movs r3, r2 + 800d4a8: 009b lsls r3, r3, #2 + 800d4aa: 189b adds r3, r3, r2 + 800d4ac: 009b lsls r3, r3, #2 + 800d4ae: 18cb adds r3, r1, r3 + 800d4b0: 3308 adds r3, #8 + 800d4b2: 68fa ldr r2, [r7, #12] + 800d4b4: 601a str r2, [r3, #0] + /* insert in SNMP ARP index tree */ + snmp_insert_arpidx_tree(netif, &arp_table[i].ipaddr); + + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_update_arp_entry: updating stable entry %"S16_F"\n", (s16_t)i)); + /* update address */ + ETHADDR32_COPY(&arp_table[i].ethaddr, ethaddr); + 800d4b6: 193b adds r3, r7, r4 + 800d4b8: 2200 movs r2, #0 + 800d4ba: 569a ldrsb r2, [r3, r2] + 800d4bc: 0013 movs r3, r2 + 800d4be: 009b lsls r3, r3, #2 + 800d4c0: 189b adds r3, r3, r2 + 800d4c2: 009b lsls r3, r3, #2 + 800d4c4: 3308 adds r3, #8 + 800d4c6: 001a movs r2, r3 + 800d4c8: 4b22 ldr r3, [pc, #136] ; (800d554 ) + 800d4ca: 18d3 adds r3, r2, r3 + 800d4cc: 3304 adds r3, #4 + 800d4ce: 6879 ldr r1, [r7, #4] + 800d4d0: 2206 movs r2, #6 + 800d4d2: 0018 movs r0, r3 + 800d4d4: f002 fbe5 bl 800fca2 + /* reset time stamp */ + arp_table[i].ctime = 0; + 800d4d8: 193b adds r3, r7, r4 + 800d4da: 2200 movs r2, #0 + 800d4dc: 569a ldrsb r2, [r3, r2] + 800d4de: 491d ldr r1, [pc, #116] ; (800d554 ) + 800d4e0: 0013 movs r3, r2 + 800d4e2: 009b lsls r3, r3, #2 + 800d4e4: 189b adds r3, r3, r2 + 800d4e6: 009b lsls r3, r3, #2 + 800d4e8: 18cb adds r3, r1, r3 + 800d4ea: 3313 adds r3, #19 + 800d4ec: 2200 movs r2, #0 + 800d4ee: 701a strb r2, [r3, #0] + /* get the packet pointer */ + p = q->p; + /* now queue entry can be freed */ + memp_free(MEMP_ARP_QUEUE, q); +#else /* ARP_QUEUEING */ + if (arp_table[i].q != NULL) { + 800d4f0: 193b adds r3, r7, r4 + 800d4f2: 2200 movs r2, #0 + 800d4f4: 569a ldrsb r2, [r3, r2] + 800d4f6: 4917 ldr r1, [pc, #92] ; (800d554 ) + 800d4f8: 0013 movs r3, r2 + 800d4fa: 009b lsls r3, r3, #2 + 800d4fc: 189b adds r3, r3, r2 + 800d4fe: 009b lsls r3, r3, #2 + 800d500: 585b ldr r3, [r3, r1] + 800d502: 2b00 cmp r3, #0 + 800d504: d020 beq.n 800d548 + struct pbuf *p = arp_table[i].q; + 800d506: 2017 movs r0, #23 + 800d508: 183b adds r3, r7, r0 + 800d50a: 2200 movs r2, #0 + 800d50c: 569a ldrsb r2, [r3, r2] + 800d50e: 4911 ldr r1, [pc, #68] ; (800d554 ) + 800d510: 0013 movs r3, r2 + 800d512: 009b lsls r3, r3, #2 + 800d514: 189b adds r3, r3, r2 + 800d516: 009b lsls r3, r3, #2 + 800d518: 585b ldr r3, [r3, r1] + 800d51a: 613b str r3, [r7, #16] + arp_table[i].q = NULL; + 800d51c: 183b adds r3, r7, r0 + 800d51e: 2200 movs r2, #0 + 800d520: 569a ldrsb r2, [r3, r2] + 800d522: 490c ldr r1, [pc, #48] ; (800d554 ) + 800d524: 0013 movs r3, r2 + 800d526: 009b lsls r3, r3, #2 + 800d528: 189b adds r3, r3, r2 + 800d52a: 009b lsls r3, r3, #2 + 800d52c: 2200 movs r2, #0 + 800d52e: 505a str r2, [r3, r1] +#endif /* ARP_QUEUEING */ + /* send the queued IP packet */ + etharp_send_ip(netif, p, (struct eth_addr*)(netif->hwaddr), ethaddr); + 800d530: 68fb ldr r3, [r7, #12] + 800d532: 3323 adds r3, #35 ; 0x23 + 800d534: 001a movs r2, r3 + 800d536: 687b ldr r3, [r7, #4] + 800d538: 6939 ldr r1, [r7, #16] + 800d53a: 68f8 ldr r0, [r7, #12] + 800d53c: f7ff ff2a bl 800d394 + /* free the queued IP packet */ + pbuf_free(p); + 800d540: 693b ldr r3, [r7, #16] + 800d542: 0018 movs r0, r3 + 800d544: f7f8 f8ae bl 80056a4 + } + return ERR_OK; + 800d548: 2300 movs r3, #0 +} + 800d54a: 0018 movs r0, r3 + 800d54c: 46bd mov sp, r7 + 800d54e: b006 add sp, #24 + 800d550: bdb0 pop {r4, r5, r7, pc} + 800d552: 46c0 nop ; (mov r8, r8) + 800d554: 200022c0 .word 0x200022c0 + +0800d558 : + * + * @see pbuf_free() + */ +static void +etharp_arp_input(struct netif *netif, struct eth_addr *ethaddr, struct pbuf *p) +{ + 800d558: b590 push {r4, r7, lr} + 800d55a: b08b sub sp, #44 ; 0x2c + 800d55c: af00 add r7, sp, #0 + 800d55e: 60f8 str r0, [r7, #12] + 800d560: 60b9 str r1, [r7, #8] + 800d562: 607a str r2, [r7, #4] + u8_t for_us; +#if LWIP_AUTOIP + const u8_t * ethdst_hwaddr; +#endif /* LWIP_AUTOIP */ + + LWIP_ERROR("netif != NULL", (netif != NULL), return;); + 800d564: 68fb ldr r3, [r7, #12] + 800d566: 2b00 cmp r3, #0 + 800d568: d100 bne.n 800d56c + 800d56a: e0f5 b.n 800d758 + + /* drop short ARP packets: we have to check for p->len instead of p->tot_len here + since a struct etharp_hdr is pointed to p->payload, so it musn't be chained! */ + if (p->len < SIZEOF_ETHARP_PACKET) { + 800d56c: 687b ldr r3, [r7, #4] + 800d56e: 895b ldrh r3, [r3, #10] + 800d570: 2b29 cmp r3, #41 ; 0x29 + 800d572: d810 bhi.n 800d596 + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, + ("etharp_arp_input: packet dropped, too short (%"S16_F"/%"S16_F")\n", p->tot_len, + (s16_t)SIZEOF_ETHARP_PACKET)); + ETHARP_STATS_INC(etharp.lenerr); + 800d574: 4b7a ldr r3, [pc, #488] ; (800d760 ) + 800d576: 8c5b ldrh r3, [r3, #34] ; 0x22 + 800d578: 3301 adds r3, #1 + 800d57a: b29a uxth r2, r3 + 800d57c: 4b78 ldr r3, [pc, #480] ; (800d760 ) + 800d57e: 845a strh r2, [r3, #34] ; 0x22 + ETHARP_STATS_INC(etharp.drop); + 800d580: 4b77 ldr r3, [pc, #476] ; (800d760 ) + 800d582: 8bdb ldrh r3, [r3, #30] + 800d584: 3301 adds r3, #1 + 800d586: b29a uxth r2, r3 + 800d588: 4b75 ldr r3, [pc, #468] ; (800d760 ) + 800d58a: 83da strh r2, [r3, #30] + pbuf_free(p); + 800d58c: 687b ldr r3, [r7, #4] + 800d58e: 0018 movs r0, r3 + 800d590: f7f8 f888 bl 80056a4 + return; + 800d594: e0e1 b.n 800d75a + } + + ethhdr = (struct eth_hdr *)p->payload; + 800d596: 687b ldr r3, [r7, #4] + 800d598: 685b ldr r3, [r3, #4] + 800d59a: 623b str r3, [r7, #32] + hdr = (struct etharp_hdr *)((u8_t*)ethhdr + SIZEOF_ETH_HDR); + 800d59c: 6a3b ldr r3, [r7, #32] + 800d59e: 330e adds r3, #14 + 800d5a0: 61fb str r3, [r7, #28] + hdr = (struct etharp_hdr *)(((u8_t*)ethhdr) + SIZEOF_ETH_HDR + SIZEOF_VLAN_HDR); + } +#endif /* ETHARP_SUPPORT_VLAN */ + + /* RFC 826 "Packet Reception": */ + if ((hdr->hwtype != PP_HTONS(HWTYPE_ETHERNET)) || + 800d5a2: 69fb ldr r3, [r7, #28] + 800d5a4: 781a ldrb r2, [r3, #0] + 800d5a6: 785b ldrb r3, [r3, #1] + 800d5a8: 021b lsls r3, r3, #8 + 800d5aa: 4313 orrs r3, r2 + 800d5ac: b29a uxth r2, r3 + 800d5ae: 2380 movs r3, #128 ; 0x80 + 800d5b0: 005b lsls r3, r3, #1 + 800d5b2: 429a cmp r2, r3 + 800d5b4: d10f bne.n 800d5d6 + (hdr->hwlen != ETHARP_HWADDR_LEN) || + 800d5b6: 69fb ldr r3, [r7, #28] + 800d5b8: 791b ldrb r3, [r3, #4] + if ((hdr->hwtype != PP_HTONS(HWTYPE_ETHERNET)) || + 800d5ba: 2b06 cmp r3, #6 + 800d5bc: d10b bne.n 800d5d6 + (hdr->protolen != sizeof(ip_addr_t)) || + 800d5be: 69fb ldr r3, [r7, #28] + 800d5c0: 795b ldrb r3, [r3, #5] + (hdr->hwlen != ETHARP_HWADDR_LEN) || + 800d5c2: 2b04 cmp r3, #4 + 800d5c4: d107 bne.n 800d5d6 + (hdr->proto != PP_HTONS(ETHTYPE_IP))) { + 800d5c6: 69fb ldr r3, [r7, #28] + 800d5c8: 789a ldrb r2, [r3, #2] + 800d5ca: 78db ldrb r3, [r3, #3] + 800d5cc: 021b lsls r3, r3, #8 + 800d5ce: 4313 orrs r3, r2 + 800d5d0: b29b uxth r3, r3 + (hdr->protolen != sizeof(ip_addr_t)) || + 800d5d2: 2b08 cmp r3, #8 + 800d5d4: d010 beq.n 800d5f8 + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, + ("etharp_arp_input: packet dropped, wrong hw type, hwlen, proto, protolen or ethernet type (%"U16_F"/%"U16_F"/%"U16_F"/%"U16_F")\n", + hdr->hwtype, hdr->hwlen, hdr->proto, hdr->protolen)); + ETHARP_STATS_INC(etharp.proterr); + 800d5d6: 4b62 ldr r3, [pc, #392] ; (800d760 ) + 800d5d8: 8d1b ldrh r3, [r3, #40] ; 0x28 + 800d5da: 3301 adds r3, #1 + 800d5dc: b29a uxth r2, r3 + 800d5de: 4b60 ldr r3, [pc, #384] ; (800d760 ) + 800d5e0: 851a strh r2, [r3, #40] ; 0x28 + ETHARP_STATS_INC(etharp.drop); + 800d5e2: 4b5f ldr r3, [pc, #380] ; (800d760 ) + 800d5e4: 8bdb ldrh r3, [r3, #30] + 800d5e6: 3301 adds r3, #1 + 800d5e8: b29a uxth r2, r3 + 800d5ea: 4b5d ldr r3, [pc, #372] ; (800d760 ) + 800d5ec: 83da strh r2, [r3, #30] + pbuf_free(p); + 800d5ee: 687b ldr r3, [r7, #4] + 800d5f0: 0018 movs r0, r3 + 800d5f2: f7f8 f857 bl 80056a4 + return; + 800d5f6: e0b0 b.n 800d75a + } + ETHARP_STATS_INC(etharp.recv); + 800d5f8: 4b59 ldr r3, [pc, #356] ; (800d760 ) + 800d5fa: 8b5b ldrh r3, [r3, #26] + 800d5fc: 3301 adds r3, #1 + 800d5fe: b29a uxth r2, r3 + 800d600: 4b57 ldr r3, [pc, #348] ; (800d760 ) + 800d602: 835a strh r2, [r3, #26] + autoip_arp_reply(netif, hdr); +#endif /* LWIP_AUTOIP */ + + /* Copy struct ip_addr2 to aligned ip_addr, to support compilers without + * structure packing (not using structure copy which breaks strict-aliasing rules). */ + IPADDR2_COPY(&sipaddr, &hdr->sipaddr); + 800d604: 69fb ldr r3, [r7, #28] + 800d606: 330e adds r3, #14 + 800d608: 0019 movs r1, r3 + 800d60a: 2318 movs r3, #24 + 800d60c: 18fb adds r3, r7, r3 + 800d60e: 2204 movs r2, #4 + 800d610: 0018 movs r0, r3 + 800d612: f002 fb46 bl 800fca2 + IPADDR2_COPY(&dipaddr, &hdr->dipaddr); + 800d616: 69fb ldr r3, [r7, #28] + 800d618: 3318 adds r3, #24 + 800d61a: 0019 movs r1, r3 + 800d61c: 2314 movs r3, #20 + 800d61e: 18fb adds r3, r7, r3 + 800d620: 2204 movs r2, #4 + 800d622: 0018 movs r0, r3 + 800d624: f002 fb3d bl 800fca2 + + /* this interface is not configured? */ + if (ip_addr_isany(&netif->ip_addr)) { + 800d628: 68fb ldr r3, [r7, #12] + 800d62a: 3304 adds r3, #4 + 800d62c: 2b00 cmp r3, #0 + 800d62e: d003 beq.n 800d638 + 800d630: 68fb ldr r3, [r7, #12] + 800d632: 685b ldr r3, [r3, #4] + 800d634: 2b00 cmp r3, #0 + 800d636: d104 bne.n 800d642 + for_us = 0; + 800d638: 2327 movs r3, #39 ; 0x27 + 800d63a: 18fb adds r3, r7, r3 + 800d63c: 2200 movs r2, #0 + 800d63e: 701a strb r2, [r3, #0] + 800d640: e009 b.n 800d656 + } else { + /* ARP packet directed to us? */ + for_us = (u8_t)ip_addr_cmp(&dipaddr, &(netif->ip_addr)); + 800d642: 697a ldr r2, [r7, #20] + 800d644: 68fb ldr r3, [r7, #12] + 800d646: 685b ldr r3, [r3, #4] + 800d648: 1ad3 subs r3, r2, r3 + 800d64a: 425a negs r2, r3 + 800d64c: 4153 adcs r3, r2 + 800d64e: b2da uxtb r2, r3 + 800d650: 2327 movs r3, #39 ; 0x27 + 800d652: 18fb adds r3, r7, r3 + 800d654: 701a strb r2, [r3, #0] + /* ARP message directed to us? + -> add IP address in ARP cache; assume requester wants to talk to us, + can result in directly sending the queued packets for this host. + ARP message not directed to us? + -> update the source IP address in the cache, if present */ + etharp_update_arp_entry(netif, &sipaddr, &(hdr->shwaddr), + 800d656: 69fb ldr r3, [r7, #28] + 800d658: 3308 adds r3, #8 + 800d65a: 001a movs r2, r3 + 800d65c: 2327 movs r3, #39 ; 0x27 + 800d65e: 18fb adds r3, r7, r3 + 800d660: 781b ldrb r3, [r3, #0] + 800d662: 2b00 cmp r3, #0 + 800d664: d001 beq.n 800d66a + 800d666: 2301 movs r3, #1 + 800d668: e000 b.n 800d66c + 800d66a: 2302 movs r3, #2 + 800d66c: 2118 movs r1, #24 + 800d66e: 1879 adds r1, r7, r1 + 800d670: 68f8 ldr r0, [r7, #12] + 800d672: f7ff febd bl 800d3f0 + for_us ? ETHARP_FLAG_TRY_HARD : ETHARP_FLAG_FIND_ONLY); + + /* now act on the message itself */ + switch (hdr->opcode) { + 800d676: 69fb ldr r3, [r7, #28] + 800d678: 799a ldrb r2, [r3, #6] + 800d67a: 79db ldrb r3, [r3, #7] + 800d67c: 021b lsls r3, r3, #8 + 800d67e: 4313 orrs r3, r2 + 800d680: b29b uxth r3, r3 + 800d682: 2280 movs r2, #128 ; 0x80 + 800d684: 0052 lsls r2, r2, #1 + 800d686: 4293 cmp r3, r2 + 800d688: d004 beq.n 800d694 + 800d68a: 2280 movs r2, #128 ; 0x80 + 800d68c: 0092 lsls r2, r2, #2 + 800d68e: 4293 cmp r3, r2 + 800d690: d05c beq.n 800d74c + 800d692: e054 b.n 800d73e + * reply. In any case, we time-stamp any existing ARP entry, + * and possiby send out an IP packet that was queued on it. */ + + LWIP_DEBUGF (ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_arp_input: incoming ARP request\n")); + /* ARP request for our address? */ + if (for_us) { + 800d694: 2327 movs r3, #39 ; 0x27 + 800d696: 18fb adds r3, r7, r3 + 800d698: 781b ldrb r3, [r3, #0] + 800d69a: 2b00 cmp r3, #0 + 800d69c: d057 beq.n 800d74e + + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_arp_input: replying to ARP request for our IP address\n")); + /* Re-use pbuf to send ARP reply. + Since we are re-using an existing pbuf, we can't call etharp_raw since + that would allocate a new pbuf. */ + hdr->opcode = htons(ARP_REPLY); + 800d69e: 2002 movs r0, #2 + 800d6a0: f7f6 ffb8 bl 8004614 + 800d6a4: 0003 movs r3, r0 + 800d6a6: 001a movs r2, r3 + 800d6a8: 69fb ldr r3, [r7, #28] + 800d6aa: 21ff movs r1, #255 ; 0xff + 800d6ac: 4011 ands r1, r2 + 800d6ae: 000c movs r4, r1 + 800d6b0: 7999 ldrb r1, [r3, #6] + 800d6b2: 2000 movs r0, #0 + 800d6b4: 4001 ands r1, r0 + 800d6b6: 1c08 adds r0, r1, #0 + 800d6b8: 1c21 adds r1, r4, #0 + 800d6ba: 4301 orrs r1, r0 + 800d6bc: 7199 strb r1, [r3, #6] + 800d6be: 0a12 lsrs r2, r2, #8 + 800d6c0: b290 uxth r0, r2 + 800d6c2: 79da ldrb r2, [r3, #7] + 800d6c4: 2100 movs r1, #0 + 800d6c6: 400a ands r2, r1 + 800d6c8: 1c11 adds r1, r2, #0 + 800d6ca: 1c02 adds r2, r0, #0 + 800d6cc: 430a orrs r2, r1 + 800d6ce: 71da strb r2, [r3, #7] + + IPADDR2_COPY(&hdr->dipaddr, &hdr->sipaddr); + 800d6d0: 69fb ldr r3, [r7, #28] + 800d6d2: 3318 adds r3, #24 + 800d6d4: 0018 movs r0, r3 + 800d6d6: 69fb ldr r3, [r7, #28] + 800d6d8: 330e adds r3, #14 + 800d6da: 2204 movs r2, #4 + 800d6dc: 0019 movs r1, r3 + 800d6de: f002 fae0 bl 800fca2 + IPADDR2_COPY(&hdr->sipaddr, &netif->ip_addr); + 800d6e2: 69fb ldr r3, [r7, #28] + 800d6e4: 330e adds r3, #14 + 800d6e6: 0018 movs r0, r3 + 800d6e8: 68fb ldr r3, [r7, #12] + 800d6ea: 3304 adds r3, #4 + 800d6ec: 2204 movs r2, #4 + 800d6ee: 0019 movs r1, r3 + 800d6f0: f002 fad7 bl 800fca2 + * 'sender IP address' MUST be sent using link-layer broadcast instead of + * link-layer unicast. (See RFC3927 Section 2.5, last paragraph) */ + ethdst_hwaddr = ip_addr_islinklocal(&netif->ip_addr) ? (u8_t*)(ethbroadcast.addr) : hdr->shwaddr.addr; +#endif /* LWIP_AUTOIP */ + + ETHADDR16_COPY(&hdr->dhwaddr, &hdr->shwaddr); + 800d6f4: 69fb ldr r3, [r7, #28] + 800d6f6: 3312 adds r3, #18 + 800d6f8: 0018 movs r0, r3 + 800d6fa: 69fb ldr r3, [r7, #28] + 800d6fc: 3308 adds r3, #8 + 800d6fe: 2206 movs r2, #6 + 800d700: 0019 movs r1, r3 + 800d702: f002 face bl 800fca2 +#if LWIP_AUTOIP + ETHADDR16_COPY(ðhdr->dest, ethdst_hwaddr); +#else /* LWIP_AUTOIP */ + ETHADDR16_COPY(ðhdr->dest, &hdr->shwaddr); + 800d706: 6a38 ldr r0, [r7, #32] + 800d708: 69fb ldr r3, [r7, #28] + 800d70a: 3308 adds r3, #8 + 800d70c: 2206 movs r2, #6 + 800d70e: 0019 movs r1, r3 + 800d710: f002 fac7 bl 800fca2 +#endif /* LWIP_AUTOIP */ + ETHADDR16_COPY(&hdr->shwaddr, ethaddr); + 800d714: 69fb ldr r3, [r7, #28] + 800d716: 3308 adds r3, #8 + 800d718: 68b9 ldr r1, [r7, #8] + 800d71a: 2206 movs r2, #6 + 800d71c: 0018 movs r0, r3 + 800d71e: f002 fac0 bl 800fca2 + ETHADDR16_COPY(ðhdr->src, ethaddr); + 800d722: 6a3b ldr r3, [r7, #32] + 800d724: 3306 adds r3, #6 + 800d726: 68b9 ldr r1, [r7, #8] + 800d728: 2206 movs r2, #6 + 800d72a: 0018 movs r0, r3 + 800d72c: f002 fab9 bl 800fca2 + + /* hwtype, hwaddr_len, proto, protolen and the type in the ethernet header + are already correct, we tested that before */ + + /* return ARP reply */ + netif->linkoutput(netif, p); + 800d730: 68fb ldr r3, [r7, #12] + 800d732: 699b ldr r3, [r3, #24] + 800d734: 6879 ldr r1, [r7, #4] + 800d736: 68fa ldr r2, [r7, #12] + 800d738: 0010 movs r0, r2 + 800d73a: 4798 blx r3 + /* request was not directed to us */ + } else { + /* { for_us == 0 and netif->ip_addr.addr != 0 } */ + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_arp_input: ARP request was not for us.\n")); + } + break; + 800d73c: e007 b.n 800d74e + dhcp_arp_reply(netif, &sipaddr); +#endif /* (LWIP_DHCP && DHCP_DOES_ARP_CHECK) */ + break; + default: + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_arp_input: ARP unknown opcode type %"S16_F"\n", htons(hdr->opcode))); + ETHARP_STATS_INC(etharp.err); + 800d73e: 4b08 ldr r3, [pc, #32] ; (800d760 ) + 800d740: 8d9b ldrh r3, [r3, #44] ; 0x2c + 800d742: 3301 adds r3, #1 + 800d744: b29a uxth r2, r3 + 800d746: 4b06 ldr r3, [pc, #24] ; (800d760 ) + 800d748: 859a strh r2, [r3, #44] ; 0x2c + break; + 800d74a: e000 b.n 800d74e + break; + 800d74c: 46c0 nop ; (mov r8, r8) + } + /* free ARP packet */ + pbuf_free(p); + 800d74e: 687b ldr r3, [r7, #4] + 800d750: 0018 movs r0, r3 + 800d752: f7f7 ffa7 bl 80056a4 + 800d756: e000 b.n 800d75a + LWIP_ERROR("netif != NULL", (netif != NULL), return;); + 800d758: 46c0 nop ; (mov r8, r8) +} + 800d75a: 46bd mov sp, r7 + 800d75c: b00b add sp, #44 ; 0x2c + 800d75e: bd90 pop {r4, r7, pc} + 800d760: 20003158 .word 0x20003158 + +0800d764 : +/** Just a small helper function that sends a pbuf to an ethernet address + * in the arp_table specified by the index 'arp_idx'. + */ +static err_t +etharp_output_to_arp_index(struct netif *netif, struct pbuf *q, u8_t arp_idx) +{ + 800d764: b590 push {r4, r7, lr} + 800d766: b085 sub sp, #20 + 800d768: af00 add r7, sp, #0 + 800d76a: 60f8 str r0, [r7, #12] + 800d76c: 60b9 str r1, [r7, #8] + 800d76e: 1dfb adds r3, r7, #7 + 800d770: 701a strb r2, [r3, #0] + LWIP_ASSERT("arp_table[arp_idx].state >= ETHARP_STATE_STABLE", + 800d772: 1dfb adds r3, r7, #7 + 800d774: 781a ldrb r2, [r3, #0] + 800d776: 0013 movs r3, r2 + 800d778: 009b lsls r3, r3, #2 + 800d77a: 189b adds r3, r3, r2 + 800d77c: 009b lsls r3, r3, #2 + arp_table[arp_idx].state >= ETHARP_STATE_STABLE); + /* if arp table entry is about to expire: re-request it, + but only if its state is ETHARP_STATE_STABLE to prevent flooding the + network with ARP requests if this address is used frequently. */ + if ((arp_table[arp_idx].state == ETHARP_STATE_STABLE) && + 800d77e: 1dfb adds r3, r7, #7 + 800d780: 781a ldrb r2, [r3, #0] + 800d782: 4924 ldr r1, [pc, #144] ; (800d814 ) + 800d784: 0013 movs r3, r2 + 800d786: 009b lsls r3, r3, #2 + 800d788: 189b adds r3, r3, r2 + 800d78a: 009b lsls r3, r3, #2 + 800d78c: 18cb adds r3, r1, r3 + 800d78e: 3312 adds r3, #18 + 800d790: 781b ldrb r3, [r3, #0] + 800d792: 2b02 cmp r3, #2 + 800d794: d126 bne.n 800d7e4 + (arp_table[arp_idx].ctime >= ARP_AGE_REREQUEST_USED)) { + 800d796: 1dfb adds r3, r7, #7 + 800d798: 781a ldrb r2, [r3, #0] + 800d79a: 491e ldr r1, [pc, #120] ; (800d814 ) + 800d79c: 0013 movs r3, r2 + 800d79e: 009b lsls r3, r3, #2 + 800d7a0: 189b adds r3, r3, r2 + 800d7a2: 009b lsls r3, r3, #2 + 800d7a4: 18cb adds r3, r1, r3 + 800d7a6: 3313 adds r3, #19 + 800d7a8: 781b ldrb r3, [r3, #0] + if ((arp_table[arp_idx].state == ETHARP_STATE_STABLE) && + 800d7aa: 2be3 cmp r3, #227 ; 0xe3 + 800d7ac: d91a bls.n 800d7e4 + if (etharp_request(netif, &arp_table[arp_idx].ipaddr) == ERR_OK) { + 800d7ae: 1dfb adds r3, r7, #7 + 800d7b0: 781a ldrb r2, [r3, #0] + 800d7b2: 0013 movs r3, r2 + 800d7b4: 009b lsls r3, r3, #2 + 800d7b6: 189b adds r3, r3, r2 + 800d7b8: 009b lsls r3, r3, #2 + 800d7ba: 4a16 ldr r2, [pc, #88] ; (800d814 ) + 800d7bc: 189b adds r3, r3, r2 + 800d7be: 1d1a adds r2, r3, #4 + 800d7c0: 68fb ldr r3, [r7, #12] + 800d7c2: 0011 movs r1, r2 + 800d7c4: 0018 movs r0, r3 + 800d7c6: f000 fb15 bl 800ddf4 + 800d7ca: 1e03 subs r3, r0, #0 + 800d7cc: d10a bne.n 800d7e4 + arp_table[arp_idx].state = ETHARP_STATE_STABLE_REREQUESTING; + 800d7ce: 1dfb adds r3, r7, #7 + 800d7d0: 781a ldrb r2, [r3, #0] + 800d7d2: 4910 ldr r1, [pc, #64] ; (800d814 ) + 800d7d4: 0013 movs r3, r2 + 800d7d6: 009b lsls r3, r3, #2 + 800d7d8: 189b adds r3, r3, r2 + 800d7da: 009b lsls r3, r3, #2 + 800d7dc: 18cb adds r3, r1, r3 + 800d7de: 3312 adds r3, #18 + 800d7e0: 2203 movs r2, #3 + 800d7e2: 701a strb r2, [r3, #0] + } + } + + return etharp_send_ip(netif, q, (struct eth_addr*)(netif->hwaddr), + 800d7e4: 68fb ldr r3, [r7, #12] + 800d7e6: 3323 adds r3, #35 ; 0x23 + 800d7e8: 001c movs r4, r3 + &arp_table[arp_idx].ethaddr); + 800d7ea: 1dfb adds r3, r7, #7 + 800d7ec: 781a ldrb r2, [r3, #0] + return etharp_send_ip(netif, q, (struct eth_addr*)(netif->hwaddr), + 800d7ee: 0013 movs r3, r2 + 800d7f0: 009b lsls r3, r3, #2 + 800d7f2: 189b adds r3, r3, r2 + 800d7f4: 009b lsls r3, r3, #2 + 800d7f6: 3308 adds r3, #8 + 800d7f8: 001a movs r2, r3 + 800d7fa: 4b06 ldr r3, [pc, #24] ; (800d814 ) + 800d7fc: 18d3 adds r3, r2, r3 + 800d7fe: 3304 adds r3, #4 + 800d800: 68b9 ldr r1, [r7, #8] + 800d802: 68f8 ldr r0, [r7, #12] + 800d804: 0022 movs r2, r4 + 800d806: f7ff fdc5 bl 800d394 + 800d80a: 0003 movs r3, r0 +} + 800d80c: 0018 movs r0, r3 + 800d80e: 46bd mov sp, r7 + 800d810: b005 add sp, #20 + 800d812: bd90 pop {r4, r7, pc} + 800d814: 200022c0 .word 0x200022c0 + +0800d818 : + * - ERR_RTE No route to destination (no gateway to external networks), + * or the return type of either etharp_query() or etharp_send_ip(). + */ +err_t +etharp_output(struct netif *netif, struct pbuf *q, ip_addr_t *ipaddr) +{ + 800d818: b580 push {r7, lr} + 800d81a: b088 sub sp, #32 + 800d81c: af00 add r7, sp, #0 + 800d81e: 60f8 str r0, [r7, #12] + 800d820: 60b9 str r1, [r7, #8] + 800d822: 607a str r2, [r7, #4] + struct eth_addr *dest; + struct eth_addr mcastaddr; + ip_addr_t *dst_addr = ipaddr; + 800d824: 687b ldr r3, [r7, #4] + 800d826: 61bb str r3, [r7, #24] + LWIP_ASSERT("netif != NULL", netif != NULL); + LWIP_ASSERT("q != NULL", q != NULL); + LWIP_ASSERT("ipaddr != NULL", ipaddr != NULL); + + /* make room for Ethernet header - should not fail */ + if (pbuf_header(q, sizeof(struct eth_hdr)) != 0) { + 800d828: 68bb ldr r3, [r7, #8] + 800d82a: 210e movs r1, #14 + 800d82c: 0018 movs r0, r3 + 800d82e: f7f7 feb2 bl 8005596 + 800d832: 1e03 subs r3, r0, #0 + 800d834: d008 beq.n 800d848 + /* bail out */ + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, + ("etharp_output: could not allocate room for header.\n")); + LINK_STATS_INC(link.lenerr); + 800d836: 4b6b ldr r3, [pc, #428] ; (800d9e4 ) + 800d838: 895b ldrh r3, [r3, #10] + 800d83a: 3301 adds r3, #1 + 800d83c: b29a uxth r2, r3 + 800d83e: 4b69 ldr r3, [pc, #420] ; (800d9e4 ) + 800d840: 815a strh r2, [r3, #10] + return ERR_BUF; + 800d842: 2302 movs r3, #2 + 800d844: 425b negs r3, r3 + 800d846: e0c9 b.n 800d9dc + + /* Determine on destination hardware address. Broadcasts and multicasts + * are special, other IP addresses are looked up in the ARP table. */ + + /* broadcast destination IP address? */ + if (ip_addr_isbroadcast(ipaddr, netif)) { + 800d848: 687b ldr r3, [r7, #4] + 800d84a: 681b ldr r3, [r3, #0] + 800d84c: 68fa ldr r2, [r7, #12] + 800d84e: 0011 movs r1, r2 + 800d850: 0018 movs r0, r3 + 800d852: f7fe fc13 bl 800c07c + 800d856: 1e03 subs r3, r0, #0 + 800d858: d002 beq.n 800d860 + /* broadcast on Ethernet also */ + dest = (struct eth_addr *)ðbroadcast; + 800d85a: 4b63 ldr r3, [pc, #396] ; (800d9e8 ) + 800d85c: 61fb str r3, [r7, #28] + 800d85e: e0b4 b.n 800d9ca + /* multicast destination IP address? */ + } else if (ip_addr_ismulticast(ipaddr)) { + 800d860: 687b ldr r3, [r7, #4] + 800d862: 681b ldr r3, [r3, #0] + 800d864: 22f0 movs r2, #240 ; 0xf0 + 800d866: 4013 ands r3, r2 + 800d868: 2be0 cmp r3, #224 ; 0xe0 + 800d86a: d11c bne.n 800d8a6 + /* Hash IP multicast address to MAC address.*/ + mcastaddr.addr[0] = LL_MULTICAST_ADDR_0; + 800d86c: 2110 movs r1, #16 + 800d86e: 187b adds r3, r7, r1 + 800d870: 2201 movs r2, #1 + 800d872: 701a strb r2, [r3, #0] + mcastaddr.addr[1] = LL_MULTICAST_ADDR_1; + 800d874: 187b adds r3, r7, r1 + 800d876: 2200 movs r2, #0 + 800d878: 705a strb r2, [r3, #1] + mcastaddr.addr[2] = LL_MULTICAST_ADDR_2; + 800d87a: 187b adds r3, r7, r1 + 800d87c: 225e movs r2, #94 ; 0x5e + 800d87e: 709a strb r2, [r3, #2] + mcastaddr.addr[3] = ip4_addr2(ipaddr) & 0x7f; + 800d880: 687b ldr r3, [r7, #4] + 800d882: 3301 adds r3, #1 + 800d884: 781b ldrb r3, [r3, #0] + 800d886: 227f movs r2, #127 ; 0x7f + 800d888: 4013 ands r3, r2 + 800d88a: b2da uxtb r2, r3 + 800d88c: 187b adds r3, r7, r1 + 800d88e: 70da strb r2, [r3, #3] + mcastaddr.addr[4] = ip4_addr3(ipaddr); + 800d890: 687b ldr r3, [r7, #4] + 800d892: 789a ldrb r2, [r3, #2] + 800d894: 187b adds r3, r7, r1 + 800d896: 711a strb r2, [r3, #4] + mcastaddr.addr[5] = ip4_addr4(ipaddr); + 800d898: 687b ldr r3, [r7, #4] + 800d89a: 78da ldrb r2, [r3, #3] + 800d89c: 187b adds r3, r7, r1 + 800d89e: 715a strb r2, [r3, #5] + /* destination Ethernet address is multicast */ + dest = &mcastaddr; + 800d8a0: 187b adds r3, r7, r1 + 800d8a2: 61fb str r3, [r7, #28] + 800d8a4: e091 b.n 800d9ca + /* unicast destination IP address? */ + } else { + s8_t i; + /* outside local network? if so, this can neither be a global broadcast nor + a subnet broadcast. */ + if (!ip_addr_netcmp(ipaddr, &(netif->ip_addr), &(netif->netmask)) && + 800d8a6: 687b ldr r3, [r7, #4] + 800d8a8: 681a ldr r2, [r3, #0] + 800d8aa: 68fb ldr r3, [r7, #12] + 800d8ac: 685b ldr r3, [r3, #4] + 800d8ae: 405a eors r2, r3 + 800d8b0: 68fb ldr r3, [r7, #12] + 800d8b2: 689b ldr r3, [r3, #8] + 800d8b4: 4013 ands r3, r2 + 800d8b6: d015 beq.n 800d8e4 + !ip_addr_islinklocal(ipaddr)) { + 800d8b8: 687b ldr r3, [r7, #4] + 800d8ba: 681b ldr r3, [r3, #0] + 800d8bc: 041b lsls r3, r3, #16 + 800d8be: 0c1b lsrs r3, r3, #16 + if (!ip_addr_netcmp(ipaddr, &(netif->ip_addr), &(netif->netmask)) && + 800d8c0: 4a4a ldr r2, [pc, #296] ; (800d9ec ) + 800d8c2: 4293 cmp r3, r2 + 800d8c4: d00e beq.n 800d8e4 + router for forwarding". */ + if (!ip_addr_islinklocal(&iphdr->src)) +#endif /* LWIP_AUTOIP */ + { + /* interface has default gateway? */ + if (!ip_addr_isany(&netif->gw)) { + 800d8c6: 68fb ldr r3, [r7, #12] + 800d8c8: 330c adds r3, #12 + 800d8ca: 2b00 cmp r3, #0 + 800d8cc: d007 beq.n 800d8de + 800d8ce: 68fb ldr r3, [r7, #12] + 800d8d0: 68db ldr r3, [r3, #12] + 800d8d2: 2b00 cmp r3, #0 + 800d8d4: d003 beq.n 800d8de + /* send to hardware address of default gateway IP address */ + dst_addr = &(netif->gw); + 800d8d6: 68fb ldr r3, [r7, #12] + 800d8d8: 330c adds r3, #12 + 800d8da: 61bb str r3, [r7, #24] + 800d8dc: e002 b.n 800d8e4 + /* no default gateway available */ + } else { + /* no route to destination error (default gateway missing) */ + return ERR_RTE; + 800d8de: 2304 movs r3, #4 + 800d8e0: 425b negs r3, r3 + 800d8e2: e07b b.n 800d9dc + if (netif->addr_hint != NULL) { + /* per-pcb cached entry was given */ + u8_t etharp_cached_entry = *(netif->addr_hint); + if (etharp_cached_entry < ARP_TABLE_SIZE) { +#endif /* LWIP_NETIF_HWADDRHINT */ + if ((arp_table[etharp_cached_entry].state >= ETHARP_STATE_STABLE) && + 800d8e4: 4b42 ldr r3, [pc, #264] ; (800d9f0 ) + 800d8e6: 781b ldrb r3, [r3, #0] + 800d8e8: 0019 movs r1, r3 + 800d8ea: 4a42 ldr r2, [pc, #264] ; (800d9f4 ) + 800d8ec: 000b movs r3, r1 + 800d8ee: 009b lsls r3, r3, #2 + 800d8f0: 185b adds r3, r3, r1 + 800d8f2: 009b lsls r3, r3, #2 + 800d8f4: 18d3 adds r3, r2, r3 + 800d8f6: 3312 adds r3, #18 + 800d8f8: 781b ldrb r3, [r3, #0] + 800d8fa: 2b01 cmp r3, #1 + 800d8fc: d91d bls.n 800d93a + (ip_addr_cmp(dst_addr, &arp_table[etharp_cached_entry].ipaddr))) { + 800d8fe: 69bb ldr r3, [r7, #24] + 800d900: 681a ldr r2, [r3, #0] + 800d902: 4b3b ldr r3, [pc, #236] ; (800d9f0 ) + 800d904: 781b ldrb r3, [r3, #0] + 800d906: 0018 movs r0, r3 + 800d908: 493a ldr r1, [pc, #232] ; (800d9f4 ) + 800d90a: 0003 movs r3, r0 + 800d90c: 009b lsls r3, r3, #2 + 800d90e: 181b adds r3, r3, r0 + 800d910: 009b lsls r3, r3, #2 + 800d912: 18cb adds r3, r1, r3 + 800d914: 3304 adds r3, #4 + 800d916: 681b ldr r3, [r3, #0] + if ((arp_table[etharp_cached_entry].state >= ETHARP_STATE_STABLE) && + 800d918: 429a cmp r2, r3 + 800d91a: d10e bne.n 800d93a + /* the per-pcb-cached entry is stable and the right one! */ + ETHARP_STATS_INC(etharp.cachehit); + 800d91c: 4b31 ldr r3, [pc, #196] ; (800d9e4 ) + 800d91e: 8ddb ldrh r3, [r3, #46] ; 0x2e + 800d920: 3301 adds r3, #1 + 800d922: b29a uxth r2, r3 + 800d924: 4b2f ldr r3, [pc, #188] ; (800d9e4 ) + 800d926: 85da strh r2, [r3, #46] ; 0x2e + return etharp_output_to_arp_index(netif, q, etharp_cached_entry); + 800d928: 4b31 ldr r3, [pc, #196] ; (800d9f0 ) + 800d92a: 781a ldrb r2, [r3, #0] + 800d92c: 68b9 ldr r1, [r7, #8] + 800d92e: 68fb ldr r3, [r7, #12] + 800d930: 0018 movs r0, r3 + 800d932: f7ff ff17 bl 800d764 + 800d936: 0003 movs r3, r0 + 800d938: e050 b.n 800d9dc + } +#endif /* LWIP_NETIF_HWADDRHINT */ + + /* find stable entry: do this here since this is a critical path for + throughput and etharp_find_entry() is kind of slow */ + for (i = 0; i < ARP_TABLE_SIZE; i++) { + 800d93a: 2317 movs r3, #23 + 800d93c: 18fb adds r3, r7, r3 + 800d93e: 2200 movs r2, #0 + 800d940: 701a strb r2, [r3, #0] + 800d942: e034 b.n 800d9ae + if ((arp_table[i].state >= ETHARP_STATE_STABLE) && + 800d944: 2317 movs r3, #23 + 800d946: 18fb adds r3, r7, r3 + 800d948: 2200 movs r2, #0 + 800d94a: 569a ldrsb r2, [r3, r2] + 800d94c: 4929 ldr r1, [pc, #164] ; (800d9f4 ) + 800d94e: 0013 movs r3, r2 + 800d950: 009b lsls r3, r3, #2 + 800d952: 189b adds r3, r3, r2 + 800d954: 009b lsls r3, r3, #2 + 800d956: 18cb adds r3, r1, r3 + 800d958: 3312 adds r3, #18 + 800d95a: 781b ldrb r3, [r3, #0] + 800d95c: 2b01 cmp r3, #1 + 800d95e: d91d bls.n 800d99c + (ip_addr_cmp(dst_addr, &arp_table[i].ipaddr))) { + 800d960: 69bb ldr r3, [r7, #24] + 800d962: 6819 ldr r1, [r3, #0] + 800d964: 2317 movs r3, #23 + 800d966: 18fb adds r3, r7, r3 + 800d968: 2200 movs r2, #0 + 800d96a: 569a ldrsb r2, [r3, r2] + 800d96c: 4821 ldr r0, [pc, #132] ; (800d9f4 ) + 800d96e: 0013 movs r3, r2 + 800d970: 009b lsls r3, r3, #2 + 800d972: 189b adds r3, r3, r2 + 800d974: 009b lsls r3, r3, #2 + 800d976: 18c3 adds r3, r0, r3 + 800d978: 3304 adds r3, #4 + 800d97a: 681b ldr r3, [r3, #0] + if ((arp_table[i].state >= ETHARP_STATE_STABLE) && + 800d97c: 4299 cmp r1, r3 + 800d97e: d10d bne.n 800d99c + /* found an existing, stable entry */ + ETHARP_SET_HINT(netif, i); + 800d980: 2117 movs r1, #23 + 800d982: 187b adds r3, r7, r1 + 800d984: 781a ldrb r2, [r3, #0] + 800d986: 4b1a ldr r3, [pc, #104] ; (800d9f0 ) + 800d988: 701a strb r2, [r3, #0] + return etharp_output_to_arp_index(netif, q, i); + 800d98a: 187b adds r3, r7, r1 + 800d98c: 781a ldrb r2, [r3, #0] + 800d98e: 68b9 ldr r1, [r7, #8] + 800d990: 68fb ldr r3, [r7, #12] + 800d992: 0018 movs r0, r3 + 800d994: f7ff fee6 bl 800d764 + 800d998: 0003 movs r3, r0 + 800d99a: e01f b.n 800d9dc + for (i = 0; i < ARP_TABLE_SIZE; i++) { + 800d99c: 2117 movs r1, #23 + 800d99e: 187b adds r3, r7, r1 + 800d9a0: 781b ldrb r3, [r3, #0] + 800d9a2: b25b sxtb r3, r3 + 800d9a4: b2db uxtb r3, r3 + 800d9a6: 3301 adds r3, #1 + 800d9a8: b2da uxtb r2, r3 + 800d9aa: 187b adds r3, r7, r1 + 800d9ac: 701a strb r2, [r3, #0] + 800d9ae: 2317 movs r3, #23 + 800d9b0: 18fb adds r3, r7, r3 + 800d9b2: 781b ldrb r3, [r3, #0] + 800d9b4: b25b sxtb r3, r3 + 800d9b6: 2b09 cmp r3, #9 + 800d9b8: ddc4 ble.n 800d944 + } + } + /* no stable entry found, use the (slower) query function: + queue on destination Ethernet address belonging to ipaddr */ + return etharp_query(netif, dst_addr, q); + 800d9ba: 68ba ldr r2, [r7, #8] + 800d9bc: 69b9 ldr r1, [r7, #24] + 800d9be: 68fb ldr r3, [r7, #12] + 800d9c0: 0018 movs r0, r3 + 800d9c2: f000 f819 bl 800d9f8 + 800d9c6: 0003 movs r3, r0 + 800d9c8: e008 b.n 800d9dc + } + + /* continuation for multicast/broadcast destinations */ + /* obtain source Ethernet address of the given interface */ + /* send packet directly on the link */ + return etharp_send_ip(netif, q, (struct eth_addr*)(netif->hwaddr), dest); + 800d9ca: 68fb ldr r3, [r7, #12] + 800d9cc: 3323 adds r3, #35 ; 0x23 + 800d9ce: 001a movs r2, r3 + 800d9d0: 69fb ldr r3, [r7, #28] + 800d9d2: 68b9 ldr r1, [r7, #8] + 800d9d4: 68f8 ldr r0, [r7, #12] + 800d9d6: f7ff fcdd bl 800d394 + 800d9da: 0003 movs r3, r0 +} + 800d9dc: 0018 movs r0, r3 + 800d9de: 46bd mov sp, r7 + 800d9e0: b008 add sp, #32 + 800d9e2: bd80 pop {r7, pc} + 800d9e4: 20003158 .word 0x20003158 + 800d9e8: 0800fdc8 .word 0x0800fdc8 + 800d9ec: 0000fea9 .word 0x0000fea9 + 800d9f0: 20002388 .word 0x20002388 + 800d9f4: 200022c0 .word 0x200022c0 + +0800d9f8 : + * - ERR_ARG Non-unicast address given, those will not appear in ARP cache. + * + */ +err_t +etharp_query(struct netif *netif, ip_addr_t *ipaddr, struct pbuf *q) +{ + 800d9f8: b5b0 push {r4, r5, r7, lr} + 800d9fa: b08a sub sp, #40 ; 0x28 + 800d9fc: af00 add r7, sp, #0 + 800d9fe: 60f8 str r0, [r7, #12] + 800da00: 60b9 str r1, [r7, #8] + 800da02: 607a str r2, [r7, #4] + struct eth_addr * srcaddr = (struct eth_addr *)netif->hwaddr; + 800da04: 68fb ldr r3, [r7, #12] + 800da06: 3323 adds r3, #35 ; 0x23 + 800da08: 61bb str r3, [r7, #24] + err_t result = ERR_MEM; + 800da0a: 2327 movs r3, #39 ; 0x27 + 800da0c: 18fb adds r3, r7, r3 + 800da0e: 22ff movs r2, #255 ; 0xff + 800da10: 701a strb r2, [r3, #0] + s8_t i; /* ARP entry index */ + + /* non-unicast address? */ + if (ip_addr_isbroadcast(ipaddr, netif) || + 800da12: 68bb ldr r3, [r7, #8] + 800da14: 681b ldr r3, [r3, #0] + 800da16: 68fa ldr r2, [r7, #12] + 800da18: 0011 movs r1, r2 + 800da1a: 0018 movs r0, r3 + 800da1c: f7fe fb2e bl 800c07c + 800da20: 1e03 subs r3, r0, #0 + 800da22: d10c bne.n 800da3e + ip_addr_ismulticast(ipaddr) || + 800da24: 68bb ldr r3, [r7, #8] + 800da26: 681b ldr r3, [r3, #0] + 800da28: 22f0 movs r2, #240 ; 0xf0 + 800da2a: 4013 ands r3, r2 + if (ip_addr_isbroadcast(ipaddr, netif) || + 800da2c: 2be0 cmp r3, #224 ; 0xe0 + 800da2e: d006 beq.n 800da3e + ip_addr_ismulticast(ipaddr) || + 800da30: 68bb ldr r3, [r7, #8] + 800da32: 2b00 cmp r3, #0 + 800da34: d003 beq.n 800da3e + ip_addr_isany(ipaddr)) { + 800da36: 68bb ldr r3, [r7, #8] + 800da38: 681b ldr r3, [r3, #0] + 800da3a: 2b00 cmp r3, #0 + 800da3c: d102 bne.n 800da44 + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: will not add non-unicast IP address to ARP cache\n")); + return ERR_ARG; + 800da3e: 230e movs r3, #14 + 800da40: 425b negs r3, r3 + 800da42: e116 b.n 800dc72 + } + + /* find entry in ARP cache, ask to create entry if queueing packet */ + i = etharp_find_entry(ipaddr, ETHARP_FLAG_TRY_HARD); + 800da44: 2517 movs r5, #23 + 800da46: 197c adds r4, r7, r5 + 800da48: 68bb ldr r3, [r7, #8] + 800da4a: 2101 movs r1, #1 + 800da4c: 0018 movs r0, r3 + 800da4e: f7ff fb25 bl 800d09c + 800da52: 0003 movs r3, r0 + 800da54: 7023 strb r3, [r4, #0] + + /* could not find or create entry? */ + if (i < 0) { + 800da56: 197b adds r3, r7, r5 + 800da58: 781b ldrb r3, [r3, #0] + 800da5a: 2b7f cmp r3, #127 ; 0x7f + 800da5c: d90d bls.n 800da7a + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: could not create ARP entry\n")); + if (q) { + 800da5e: 687b ldr r3, [r7, #4] + 800da60: 2b00 cmp r3, #0 + 800da62: d005 beq.n 800da70 + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: packet dropped\n")); + ETHARP_STATS_INC(etharp.memerr); + 800da64: 4b85 ldr r3, [pc, #532] ; (800dc7c ) + 800da66: 8c9b ldrh r3, [r3, #36] ; 0x24 + 800da68: 3301 adds r3, #1 + 800da6a: b29a uxth r2, r3 + 800da6c: 4b83 ldr r3, [pc, #524] ; (800dc7c ) + 800da6e: 849a strh r2, [r3, #36] ; 0x24 + } + return (err_t)i; + 800da70: 2317 movs r3, #23 + 800da72: 18fb adds r3, r7, r3 + 800da74: 781b ldrb r3, [r3, #0] + 800da76: b25b sxtb r3, r3 + 800da78: e0fb b.n 800dc72 + } + + /* mark a fresh entry as pending (we just sent a request) */ + if (arp_table[i].state == ETHARP_STATE_EMPTY) { + 800da7a: 2317 movs r3, #23 + 800da7c: 18fb adds r3, r7, r3 + 800da7e: 2200 movs r2, #0 + 800da80: 569a ldrsb r2, [r3, r2] + 800da82: 497f ldr r1, [pc, #508] ; (800dc80 ) + 800da84: 0013 movs r3, r2 + 800da86: 009b lsls r3, r3, #2 + 800da88: 189b adds r3, r3, r2 + 800da8a: 009b lsls r3, r3, #2 + 800da8c: 18cb adds r3, r1, r3 + 800da8e: 3312 adds r3, #18 + 800da90: 781b ldrb r3, [r3, #0] + 800da92: 2b00 cmp r3, #0 + 800da94: d10c bne.n 800dab0 + arp_table[i].state = ETHARP_STATE_PENDING; + 800da96: 2317 movs r3, #23 + 800da98: 18fb adds r3, r7, r3 + 800da9a: 2200 movs r2, #0 + 800da9c: 569a ldrsb r2, [r3, r2] + 800da9e: 4978 ldr r1, [pc, #480] ; (800dc80 ) + 800daa0: 0013 movs r3, r2 + 800daa2: 009b lsls r3, r3, #2 + 800daa4: 189b adds r3, r3, r2 + 800daa6: 009b lsls r3, r3, #2 + 800daa8: 18cb adds r3, r1, r3 + 800daaa: 3312 adds r3, #18 + 800daac: 2201 movs r2, #1 + 800daae: 701a strb r2, [r3, #0] + } + + /* { i is either a STABLE or (new or existing) PENDING entry } */ + LWIP_ASSERT("arp_table[i].state == PENDING or STABLE", + 800dab0: 2317 movs r3, #23 + 800dab2: 18fb adds r3, r7, r3 + 800dab4: 2200 movs r2, #0 + 800dab6: 569a ldrsb r2, [r3, r2] + 800dab8: 4971 ldr r1, [pc, #452] ; (800dc80 ) + 800daba: 0013 movs r3, r2 + 800dabc: 009b lsls r3, r3, #2 + 800dabe: 189b adds r3, r3, r2 + 800dac0: 009b lsls r3, r3, #2 + 800dac2: 18cb adds r3, r1, r3 + 800dac4: 3312 adds r3, #18 + 800dac6: 781b ldrb r3, [r3, #0] + 800dac8: 2b01 cmp r3, #1 + 800daca: d007 beq.n 800dadc + 800dacc: 2317 movs r3, #23 + 800dace: 18fb adds r3, r7, r3 + 800dad0: 2200 movs r2, #0 + 800dad2: 569a ldrsb r2, [r3, r2] + 800dad4: 0013 movs r3, r2 + 800dad6: 009b lsls r3, r3, #2 + 800dad8: 189b adds r3, r3, r2 + 800dada: 009b lsls r3, r3, #2 + ((arp_table[i].state == ETHARP_STATE_PENDING) || + (arp_table[i].state >= ETHARP_STATE_STABLE))); + + /* do we have a pending entry? or an implicit query request? */ + if ((arp_table[i].state == ETHARP_STATE_PENDING) || (q == NULL)) { + 800dadc: 2317 movs r3, #23 + 800dade: 18fb adds r3, r7, r3 + 800dae0: 2200 movs r2, #0 + 800dae2: 569a ldrsb r2, [r3, r2] + 800dae4: 4966 ldr r1, [pc, #408] ; (800dc80 ) + 800dae6: 0013 movs r3, r2 + 800dae8: 009b lsls r3, r3, #2 + 800daea: 189b adds r3, r3, r2 + 800daec: 009b lsls r3, r3, #2 + 800daee: 18cb adds r3, r1, r3 + 800daf0: 3312 adds r3, #18 + 800daf2: 781b ldrb r3, [r3, #0] + 800daf4: 2b01 cmp r3, #1 + 800daf6: d002 beq.n 800dafe + 800daf8: 687b ldr r3, [r7, #4] + 800dafa: 2b00 cmp r3, #0 + 800dafc: d111 bne.n 800db22 + /* try to resolve it; send out ARP request */ + result = etharp_request(netif, ipaddr); + 800dafe: 2327 movs r3, #39 ; 0x27 + 800db00: 18fc adds r4, r7, r3 + 800db02: 68ba ldr r2, [r7, #8] + 800db04: 68fb ldr r3, [r7, #12] + 800db06: 0011 movs r1, r2 + 800db08: 0018 movs r0, r3 + 800db0a: f000 f973 bl 800ddf4 + 800db0e: 0003 movs r3, r0 + 800db10: 7023 strb r3, [r4, #0] + /* ARP request couldn't be sent */ + /* We don't re-send arp request in etharp_tmr, but we still queue packets, + since this failure could be temporary, and the next packet calling + etharp_query again could lead to sending the queued packets. */ + } + if (q == NULL) { + 800db12: 687b ldr r3, [r7, #4] + 800db14: 2b00 cmp r3, #0 + 800db16: d104 bne.n 800db22 + return result; + 800db18: 2327 movs r3, #39 ; 0x27 + 800db1a: 18fb adds r3, r7, r3 + 800db1c: 781b ldrb r3, [r3, #0] + 800db1e: b25b sxtb r3, r3 + 800db20: e0a7 b.n 800dc72 + } + + /* packet given? */ + LWIP_ASSERT("q != NULL", q != NULL); + /* stable entry? */ + if (arp_table[i].state >= ETHARP_STATE_STABLE) { + 800db22: 2317 movs r3, #23 + 800db24: 18fb adds r3, r7, r3 + 800db26: 2200 movs r2, #0 + 800db28: 569a ldrsb r2, [r3, r2] + 800db2a: 4955 ldr r1, [pc, #340] ; (800dc80 ) + 800db2c: 0013 movs r3, r2 + 800db2e: 009b lsls r3, r3, #2 + 800db30: 189b adds r3, r3, r2 + 800db32: 009b lsls r3, r3, #2 + 800db34: 18cb adds r3, r1, r3 + 800db36: 3312 adds r3, #18 + 800db38: 781b ldrb r3, [r3, #0] + 800db3a: 2b01 cmp r3, #1 + 800db3c: d91a bls.n 800db74 + /* we have a valid IP->Ethernet address mapping */ + ETHARP_SET_HINT(netif, i); + 800db3e: 2117 movs r1, #23 + 800db40: 187b adds r3, r7, r1 + 800db42: 781a ldrb r2, [r3, #0] + 800db44: 4b4f ldr r3, [pc, #316] ; (800dc84 ) + 800db46: 701a strb r2, [r3, #0] + /* send the packet */ + result = etharp_send_ip(netif, q, srcaddr, &(arp_table[i].ethaddr)); + 800db48: 187b adds r3, r7, r1 + 800db4a: 2200 movs r2, #0 + 800db4c: 569a ldrsb r2, [r3, r2] + 800db4e: 0013 movs r3, r2 + 800db50: 009b lsls r3, r3, #2 + 800db52: 189b adds r3, r3, r2 + 800db54: 009b lsls r3, r3, #2 + 800db56: 3308 adds r3, #8 + 800db58: 001a movs r2, r3 + 800db5a: 4b49 ldr r3, [pc, #292] ; (800dc80 ) + 800db5c: 18d3 adds r3, r2, r3 + 800db5e: 3304 adds r3, #4 + 800db60: 2227 movs r2, #39 ; 0x27 + 800db62: 18bc adds r4, r7, r2 + 800db64: 69ba ldr r2, [r7, #24] + 800db66: 6879 ldr r1, [r7, #4] + 800db68: 68f8 ldr r0, [r7, #12] + 800db6a: f7ff fc13 bl 800d394 + 800db6e: 0003 movs r3, r0 + 800db70: 7023 strb r3, [r4, #0] + 800db72: e07a b.n 800dc6a + /* pending entry? (either just created or already pending */ + } else if (arp_table[i].state == ETHARP_STATE_PENDING) { + 800db74: 2317 movs r3, #23 + 800db76: 18fb adds r3, r7, r3 + 800db78: 2200 movs r2, #0 + 800db7a: 569a ldrsb r2, [r3, r2] + 800db7c: 4940 ldr r1, [pc, #256] ; (800dc80 ) + 800db7e: 0013 movs r3, r2 + 800db80: 009b lsls r3, r3, #2 + 800db82: 189b adds r3, r3, r2 + 800db84: 009b lsls r3, r3, #2 + 800db86: 18cb adds r3, r1, r3 + 800db88: 3312 adds r3, #18 + 800db8a: 781b ldrb r3, [r3, #0] + 800db8c: 2b01 cmp r3, #1 + 800db8e: d000 beq.n 800db92 + 800db90: e06b b.n 800dc6a + /* entry is still pending, queue the given packet 'q' */ + struct pbuf *p; + int copy_needed = 0; + 800db92: 2300 movs r3, #0 + 800db94: 61fb str r3, [r7, #28] + /* IF q includes a PBUF_REF, PBUF_POOL or PBUF_RAM, we have no choice but + * to copy the whole queue into a new PBUF_RAM (see bug #11400) + * PBUF_ROMs can be left as they are, since ROM must not get changed. */ + p = q; + 800db96: 687b ldr r3, [r7, #4] + 800db98: 623b str r3, [r7, #32] + while (p) { + 800db9a: e009 b.n 800dbb0 + LWIP_ASSERT("no packet queues allowed!", (p->len != p->tot_len) || (p->next == 0)); + if(p->type != PBUF_ROM) { + 800db9c: 6a3b ldr r3, [r7, #32] + 800db9e: 7b1b ldrb r3, [r3, #12] + 800dba0: 2b01 cmp r3, #1 + 800dba2: d002 beq.n 800dbaa + copy_needed = 1; + 800dba4: 2301 movs r3, #1 + 800dba6: 61fb str r3, [r7, #28] + break; + 800dba8: e005 b.n 800dbb6 + } + p = p->next; + 800dbaa: 6a3b ldr r3, [r7, #32] + 800dbac: 681b ldr r3, [r3, #0] + 800dbae: 623b str r3, [r7, #32] + while (p) { + 800dbb0: 6a3b ldr r3, [r7, #32] + 800dbb2: 2b00 cmp r3, #0 + 800dbb4: d1f2 bne.n 800db9c + } + if(copy_needed) { + 800dbb6: 69fb ldr r3, [r7, #28] + 800dbb8: 2b00 cmp r3, #0 + 800dbba: d01a beq.n 800dbf2 + /* copy the whole packet into new pbufs */ + p = pbuf_alloc(PBUF_RAW, p->tot_len, PBUF_RAM); + 800dbbc: 6a3b ldr r3, [r7, #32] + 800dbbe: 891b ldrh r3, [r3, #8] + 800dbc0: 2200 movs r2, #0 + 800dbc2: 0019 movs r1, r3 + 800dbc4: 2003 movs r0, #3 + 800dbc6: f7f7 fae1 bl 800518c + 800dbca: 0003 movs r3, r0 + 800dbcc: 623b str r3, [r7, #32] + if(p != NULL) { + 800dbce: 6a3b ldr r3, [r7, #32] + 800dbd0: 2b00 cmp r3, #0 + 800dbd2: d014 beq.n 800dbfe + if (pbuf_copy(p, q) != ERR_OK) { + 800dbd4: 687a ldr r2, [r7, #4] + 800dbd6: 6a3b ldr r3, [r7, #32] + 800dbd8: 0011 movs r1, r2 + 800dbda: 0018 movs r0, r3 + 800dbdc: f7f7 fe41 bl 8005862 + 800dbe0: 1e03 subs r3, r0, #0 + 800dbe2: d00c beq.n 800dbfe + pbuf_free(p); + 800dbe4: 6a3b ldr r3, [r7, #32] + 800dbe6: 0018 movs r0, r3 + 800dbe8: f7f7 fd5c bl 80056a4 + p = NULL; + 800dbec: 2300 movs r3, #0 + 800dbee: 623b str r3, [r7, #32] + 800dbf0: e005 b.n 800dbfe + } + } + } else { + /* referencing the old pbuf is enough */ + p = q; + 800dbf2: 687b ldr r3, [r7, #4] + 800dbf4: 623b str r3, [r7, #32] + pbuf_ref(p); + 800dbf6: 6a3b ldr r3, [r7, #32] + 800dbf8: 0018 movs r0, r3 + 800dbfa: f7f7 fde1 bl 80057c0 + } + /* packet could be taken over? */ + if (p != NULL) { + 800dbfe: 6a3b ldr r3, [r7, #32] + 800dc00: 2b00 cmp r3, #0 + 800dc02: d028 beq.n 800dc56 + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: could not queue a copy of PBUF_REF packet %p (out of memory)\n", (void *)q)); + result = ERR_MEM; + } +#else /* ARP_QUEUEING */ + /* always queue one packet per ARP request only, freeing a previously queued packet */ + if (arp_table[i].q != NULL) { + 800dc04: 2317 movs r3, #23 + 800dc06: 18fb adds r3, r7, r3 + 800dc08: 2200 movs r2, #0 + 800dc0a: 569a ldrsb r2, [r3, r2] + 800dc0c: 491c ldr r1, [pc, #112] ; (800dc80 ) + 800dc0e: 0013 movs r3, r2 + 800dc10: 009b lsls r3, r3, #2 + 800dc12: 189b adds r3, r3, r2 + 800dc14: 009b lsls r3, r3, #2 + 800dc16: 585b ldr r3, [r3, r1] + 800dc18: 2b00 cmp r3, #0 + 800dc1a: d00c beq.n 800dc36 + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: dropped previously queued packet %p for ARP entry %"S16_F"\n", (void *)q, (s16_t)i)); + pbuf_free(arp_table[i].q); + 800dc1c: 2317 movs r3, #23 + 800dc1e: 18fb adds r3, r7, r3 + 800dc20: 2200 movs r2, #0 + 800dc22: 569a ldrsb r2, [r3, r2] + 800dc24: 4916 ldr r1, [pc, #88] ; (800dc80 ) + 800dc26: 0013 movs r3, r2 + 800dc28: 009b lsls r3, r3, #2 + 800dc2a: 189b adds r3, r3, r2 + 800dc2c: 009b lsls r3, r3, #2 + 800dc2e: 585b ldr r3, [r3, r1] + 800dc30: 0018 movs r0, r3 + 800dc32: f7f7 fd37 bl 80056a4 + } + arp_table[i].q = p; + 800dc36: 2317 movs r3, #23 + 800dc38: 18fb adds r3, r7, r3 + 800dc3a: 2200 movs r2, #0 + 800dc3c: 569a ldrsb r2, [r3, r2] + 800dc3e: 4910 ldr r1, [pc, #64] ; (800dc80 ) + 800dc40: 0013 movs r3, r2 + 800dc42: 009b lsls r3, r3, #2 + 800dc44: 189b adds r3, r3, r2 + 800dc46: 009b lsls r3, r3, #2 + 800dc48: 6a3a ldr r2, [r7, #32] + 800dc4a: 505a str r2, [r3, r1] + result = ERR_OK; + 800dc4c: 2327 movs r3, #39 ; 0x27 + 800dc4e: 18fb adds r3, r7, r3 + 800dc50: 2200 movs r2, #0 + 800dc52: 701a strb r2, [r3, #0] + 800dc54: e009 b.n 800dc6a + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: queued packet %p on ARP entry %"S16_F"\n", (void *)q, (s16_t)i)); +#endif /* ARP_QUEUEING */ + } else { + ETHARP_STATS_INC(etharp.memerr); + 800dc56: 4b09 ldr r3, [pc, #36] ; (800dc7c ) + 800dc58: 8c9b ldrh r3, [r3, #36] ; 0x24 + 800dc5a: 3301 adds r3, #1 + 800dc5c: b29a uxth r2, r3 + 800dc5e: 4b07 ldr r3, [pc, #28] ; (800dc7c ) + 800dc60: 849a strh r2, [r3, #36] ; 0x24 + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: could not queue a copy of PBUF_REF packet %p (out of memory)\n", (void *)q)); + result = ERR_MEM; + 800dc62: 2327 movs r3, #39 ; 0x27 + 800dc64: 18fb adds r3, r7, r3 + 800dc66: 22ff movs r2, #255 ; 0xff + 800dc68: 701a strb r2, [r3, #0] + } + } + return result; + 800dc6a: 2327 movs r3, #39 ; 0x27 + 800dc6c: 18fb adds r3, r7, r3 + 800dc6e: 781b ldrb r3, [r3, #0] + 800dc70: b25b sxtb r3, r3 +} + 800dc72: 0018 movs r0, r3 + 800dc74: 46bd mov sp, r7 + 800dc76: b00a add sp, #40 ; 0x28 + 800dc78: bdb0 pop {r4, r5, r7, pc} + 800dc7a: 46c0 nop ; (mov r8, r8) + 800dc7c: 20003158 .word 0x20003158 + 800dc80: 200022c0 .word 0x200022c0 + 800dc84: 20002388 .word 0x20002388 + +0800dc88 : +etharp_raw(struct netif *netif, const struct eth_addr *ethsrc_addr, + const struct eth_addr *ethdst_addr, + const struct eth_addr *hwsrc_addr, const ip_addr_t *ipsrc_addr, + const struct eth_addr *hwdst_addr, const ip_addr_t *ipdst_addr, + const u16_t opcode) +{ + 800dc88: b5b0 push {r4, r5, r7, lr} + 800dc8a: b088 sub sp, #32 + 800dc8c: af00 add r7, sp, #0 + 800dc8e: 60f8 str r0, [r7, #12] + 800dc90: 60b9 str r1, [r7, #8] + 800dc92: 607a str r2, [r7, #4] + 800dc94: 603b str r3, [r7, #0] + struct pbuf *p; + err_t result = ERR_OK; + 800dc96: 231f movs r3, #31 + 800dc98: 18fb adds r3, r7, r3 + 800dc9a: 2200 movs r2, #0 + 800dc9c: 701a strb r2, [r3, #0] +#endif /* LWIP_AUTOIP */ + + LWIP_ASSERT("netif != NULL", netif != NULL); + + /* allocate a pbuf for the outgoing ARP request packet */ + p = pbuf_alloc(PBUF_RAW, SIZEOF_ETHARP_PACKET, PBUF_RAM); + 800dc9e: 2200 movs r2, #0 + 800dca0: 212a movs r1, #42 ; 0x2a + 800dca2: 2003 movs r0, #3 + 800dca4: f7f7 fa72 bl 800518c + 800dca8: 0003 movs r3, r0 + 800dcaa: 61bb str r3, [r7, #24] + /* could allocate a pbuf for an ARP request? */ + if (p == NULL) { + 800dcac: 69bb ldr r3, [r7, #24] + 800dcae: 2b00 cmp r3, #0 + 800dcb0: d108 bne.n 800dcc4 + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, + ("etharp_raw: could not allocate pbuf for ARP request.\n")); + ETHARP_STATS_INC(etharp.memerr); + 800dcb2: 4b4f ldr r3, [pc, #316] ; (800ddf0 ) + 800dcb4: 8c9b ldrh r3, [r3, #36] ; 0x24 + 800dcb6: 3301 adds r3, #1 + 800dcb8: b29a uxth r2, r3 + 800dcba: 4b4d ldr r3, [pc, #308] ; (800ddf0 ) + 800dcbc: 849a strh r2, [r3, #36] ; 0x24 + return ERR_MEM; + 800dcbe: 2301 movs r3, #1 + 800dcc0: 425b negs r3, r3 + 800dcc2: e090 b.n 800dde6 + } + LWIP_ASSERT("check that first pbuf can hold struct etharp_hdr", + (p->len >= SIZEOF_ETHARP_PACKET)); + + ethhdr = (struct eth_hdr *)p->payload; + 800dcc4: 69bb ldr r3, [r7, #24] + 800dcc6: 685b ldr r3, [r3, #4] + 800dcc8: 617b str r3, [r7, #20] + hdr = (struct etharp_hdr *)((u8_t*)ethhdr + SIZEOF_ETH_HDR); + 800dcca: 697b ldr r3, [r7, #20] + 800dccc: 330e adds r3, #14 + 800dcce: 613b str r3, [r7, #16] + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_raw: sending raw ARP packet.\n")); + hdr->opcode = htons(opcode); + 800dcd0: 233c movs r3, #60 ; 0x3c + 800dcd2: 18fb adds r3, r7, r3 + 800dcd4: 881b ldrh r3, [r3, #0] + 800dcd6: 0018 movs r0, r3 + 800dcd8: f7f6 fc9c bl 8004614 + 800dcdc: 0003 movs r3, r0 + 800dcde: 001a movs r2, r3 + 800dce0: 693b ldr r3, [r7, #16] + 800dce2: 21ff movs r1, #255 ; 0xff + 800dce4: 4011 ands r1, r2 + 800dce6: 000c movs r4, r1 + 800dce8: 7999 ldrb r1, [r3, #6] + 800dcea: 2000 movs r0, #0 + 800dcec: 4001 ands r1, r0 + 800dcee: 1c08 adds r0, r1, #0 + 800dcf0: 1c21 adds r1, r4, #0 + 800dcf2: 4301 orrs r1, r0 + 800dcf4: 7199 strb r1, [r3, #6] + 800dcf6: 0a12 lsrs r2, r2, #8 + 800dcf8: b290 uxth r0, r2 + 800dcfa: 79da ldrb r2, [r3, #7] + 800dcfc: 2100 movs r1, #0 + 800dcfe: 400a ands r2, r1 + 800dd00: 1c11 adds r1, r2, #0 + 800dd02: 1c02 adds r2, r0, #0 + 800dd04: 430a orrs r2, r1 + 800dd06: 71da strb r2, [r3, #7] + * 'sender IP address' MUST be sent using link-layer broadcast instead of + * link-layer unicast. (See RFC3927 Section 2.5, last paragraph) */ + ethdst_hwaddr = ip_addr_islinklocal(ipsrc_addr) ? (u8_t*)(ethbroadcast.addr) : ethdst_addr->addr; +#endif /* LWIP_AUTOIP */ + /* Write the ARP MAC-Addresses */ + ETHADDR16_COPY(&hdr->shwaddr, hwsrc_addr); + 800dd08: 693b ldr r3, [r7, #16] + 800dd0a: 3308 adds r3, #8 + 800dd0c: 6839 ldr r1, [r7, #0] + 800dd0e: 2206 movs r2, #6 + 800dd10: 0018 movs r0, r3 + 800dd12: f001 ffc6 bl 800fca2 + ETHADDR16_COPY(&hdr->dhwaddr, hwdst_addr); + 800dd16: 693b ldr r3, [r7, #16] + 800dd18: 3312 adds r3, #18 + 800dd1a: 6b79 ldr r1, [r7, #52] ; 0x34 + 800dd1c: 2206 movs r2, #6 + 800dd1e: 0018 movs r0, r3 + 800dd20: f001 ffbf bl 800fca2 + /* Write the Ethernet MAC-Addresses */ +#if LWIP_AUTOIP + ETHADDR16_COPY(ðhdr->dest, ethdst_hwaddr); +#else /* LWIP_AUTOIP */ + ETHADDR16_COPY(ðhdr->dest, ethdst_addr); + 800dd24: 697b ldr r3, [r7, #20] + 800dd26: 6879 ldr r1, [r7, #4] + 800dd28: 2206 movs r2, #6 + 800dd2a: 0018 movs r0, r3 + 800dd2c: f001 ffb9 bl 800fca2 +#endif /* LWIP_AUTOIP */ + ETHADDR16_COPY(ðhdr->src, ethsrc_addr); + 800dd30: 697b ldr r3, [r7, #20] + 800dd32: 3306 adds r3, #6 + 800dd34: 68b9 ldr r1, [r7, #8] + 800dd36: 2206 movs r2, #6 + 800dd38: 0018 movs r0, r3 + 800dd3a: f001 ffb2 bl 800fca2 + /* Copy struct ip_addr2 to aligned ip_addr, to support compilers without + * structure packing. */ + IPADDR2_COPY(&hdr->sipaddr, ipsrc_addr); + 800dd3e: 693b ldr r3, [r7, #16] + 800dd40: 330e adds r3, #14 + 800dd42: 6b39 ldr r1, [r7, #48] ; 0x30 + 800dd44: 2204 movs r2, #4 + 800dd46: 0018 movs r0, r3 + 800dd48: f001 ffab bl 800fca2 + IPADDR2_COPY(&hdr->dipaddr, ipdst_addr); + 800dd4c: 693b ldr r3, [r7, #16] + 800dd4e: 3318 adds r3, #24 + 800dd50: 6bb9 ldr r1, [r7, #56] ; 0x38 + 800dd52: 2204 movs r2, #4 + 800dd54: 0018 movs r0, r3 + 800dd56: f001 ffa4 bl 800fca2 + + hdr->hwtype = PP_HTONS(HWTYPE_ETHERNET); + 800dd5a: 693b ldr r3, [r7, #16] + 800dd5c: 781a ldrb r2, [r3, #0] + 800dd5e: 2100 movs r1, #0 + 800dd60: 400a ands r2, r1 + 800dd62: 701a strb r2, [r3, #0] + 800dd64: 785a ldrb r2, [r3, #1] + 800dd66: 2100 movs r1, #0 + 800dd68: 400a ands r2, r1 + 800dd6a: 1c11 adds r1, r2, #0 + 800dd6c: 2201 movs r2, #1 + 800dd6e: 430a orrs r2, r1 + 800dd70: 705a strb r2, [r3, #1] + hdr->proto = PP_HTONS(ETHTYPE_IP); + 800dd72: 693b ldr r3, [r7, #16] + 800dd74: 789a ldrb r2, [r3, #2] + 800dd76: 2100 movs r1, #0 + 800dd78: 400a ands r2, r1 + 800dd7a: 1c11 adds r1, r2, #0 + 800dd7c: 2208 movs r2, #8 + 800dd7e: 430a orrs r2, r1 + 800dd80: 709a strb r2, [r3, #2] + 800dd82: 78da ldrb r2, [r3, #3] + 800dd84: 2100 movs r1, #0 + 800dd86: 400a ands r2, r1 + 800dd88: 70da strb r2, [r3, #3] + /* set hwlen and protolen */ + hdr->hwlen = ETHARP_HWADDR_LEN; + 800dd8a: 693b ldr r3, [r7, #16] + 800dd8c: 2206 movs r2, #6 + 800dd8e: 711a strb r2, [r3, #4] + hdr->protolen = sizeof(ip_addr_t); + 800dd90: 693b ldr r3, [r7, #16] + 800dd92: 2204 movs r2, #4 + 800dd94: 715a strb r2, [r3, #5] + + ethhdr->type = PP_HTONS(ETHTYPE_ARP); + 800dd96: 697b ldr r3, [r7, #20] + 800dd98: 7b1a ldrb r2, [r3, #12] + 800dd9a: 2100 movs r1, #0 + 800dd9c: 400a ands r2, r1 + 800dd9e: 1c11 adds r1, r2, #0 + 800dda0: 2208 movs r2, #8 + 800dda2: 430a orrs r2, r1 + 800dda4: 731a strb r2, [r3, #12] + 800dda6: 7b5a ldrb r2, [r3, #13] + 800dda8: 2100 movs r1, #0 + 800ddaa: 400a ands r2, r1 + 800ddac: 1c11 adds r1, r2, #0 + 800ddae: 2206 movs r2, #6 + 800ddb0: 430a orrs r2, r1 + 800ddb2: 735a strb r2, [r3, #13] + /* send ARP query */ + result = netif->linkoutput(netif, p); + 800ddb4: 68fb ldr r3, [r7, #12] + 800ddb6: 699b ldr r3, [r3, #24] + 800ddb8: 251f movs r5, #31 + 800ddba: 197c adds r4, r7, r5 + 800ddbc: 69b9 ldr r1, [r7, #24] + 800ddbe: 68fa ldr r2, [r7, #12] + 800ddc0: 0010 movs r0, r2 + 800ddc2: 4798 blx r3 + 800ddc4: 0003 movs r3, r0 + 800ddc6: 7023 strb r3, [r4, #0] + ETHARP_STATS_INC(etharp.xmit); + 800ddc8: 4b09 ldr r3, [pc, #36] ; (800ddf0 ) + 800ddca: 8b1b ldrh r3, [r3, #24] + 800ddcc: 3301 adds r3, #1 + 800ddce: b29a uxth r2, r3 + 800ddd0: 4b07 ldr r3, [pc, #28] ; (800ddf0 ) + 800ddd2: 831a strh r2, [r3, #24] + /* free ARP query packet */ + pbuf_free(p); + 800ddd4: 69bb ldr r3, [r7, #24] + 800ddd6: 0018 movs r0, r3 + 800ddd8: f7f7 fc64 bl 80056a4 + p = NULL; + 800dddc: 2300 movs r3, #0 + 800ddde: 61bb str r3, [r7, #24] + /* could not allocate pbuf for ARP request */ + + return result; + 800dde0: 197b adds r3, r7, r5 + 800dde2: 781b ldrb r3, [r3, #0] + 800dde4: b25b sxtb r3, r3 +} + 800dde6: 0018 movs r0, r3 + 800dde8: 46bd mov sp, r7 + 800ddea: b008 add sp, #32 + 800ddec: bdb0 pop {r4, r5, r7, pc} + 800ddee: 46c0 nop ; (mov r8, r8) + 800ddf0: 20003158 .word 0x20003158 + +0800ddf4 : + * ERR_MEM if the ARP packet couldn't be allocated + * any other err_t on failure + */ +err_t +etharp_request(struct netif *netif, ip_addr_t *ipaddr) +{ + 800ddf4: b5b0 push {r4, r5, r7, lr} + 800ddf6: b086 sub sp, #24 + 800ddf8: af04 add r7, sp, #16 + 800ddfa: 6078 str r0, [r7, #4] + 800ddfc: 6039 str r1, [r7, #0] + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_request: sending ARP request.\n")); + return etharp_raw(netif, (struct eth_addr *)netif->hwaddr, ðbroadcast, + 800ddfe: 687b ldr r3, [r7, #4] + 800de00: 3323 adds r3, #35 ; 0x23 + 800de02: 0019 movs r1, r3 + (struct eth_addr *)netif->hwaddr, &netif->ip_addr, ðzero, + 800de04: 687b ldr r3, [r7, #4] + 800de06: 3323 adds r3, #35 ; 0x23 + 800de08: 001d movs r5, r3 + 800de0a: 687b ldr r3, [r7, #4] + 800de0c: 3304 adds r3, #4 + return etharp_raw(netif, (struct eth_addr *)netif->hwaddr, ðbroadcast, + 800de0e: 4c09 ldr r4, [pc, #36] ; (800de34 ) + 800de10: 6878 ldr r0, [r7, #4] + 800de12: 2201 movs r2, #1 + 800de14: 9203 str r2, [sp, #12] + 800de16: 683a ldr r2, [r7, #0] + 800de18: 9202 str r2, [sp, #8] + 800de1a: 4a07 ldr r2, [pc, #28] ; (800de38 ) + 800de1c: 9201 str r2, [sp, #4] + 800de1e: 9300 str r3, [sp, #0] + 800de20: 002b movs r3, r5 + 800de22: 0022 movs r2, r4 + 800de24: f7ff ff30 bl 800dc88 + 800de28: 0003 movs r3, r0 + ipaddr, ARP_REQUEST); +} + 800de2a: 0018 movs r0, r3 + 800de2c: 46bd mov sp, r7 + 800de2e: b002 add sp, #8 + 800de30: bdb0 pop {r4, r5, r7, pc} + 800de32: 46c0 nop ; (mov r8, r8) + 800de34: 0800fdc8 .word 0x0800fdc8 + 800de38: 0800fdd0 .word 0x0800fdd0 + +0800de3c : + * @param p the recevied packet, p->payload pointing to the ethernet header + * @param netif the network interface on which the packet was received + */ +err_t +ethernet_input(struct pbuf *p, struct netif *netif) +{ + 800de3c: b580 push {r7, lr} + 800de3e: b086 sub sp, #24 + 800de40: af00 add r7, sp, #0 + 800de42: 6078 str r0, [r7, #4] + 800de44: 6039 str r1, [r7, #0] + struct eth_hdr* ethhdr; + u16_t type; +#if LWIP_ARP || ETHARP_SUPPORT_VLAN + s16_t ip_hdr_offset = SIZEOF_ETH_HDR; + 800de46: 2316 movs r3, #22 + 800de48: 18fb adds r3, r7, r3 + 800de4a: 220e movs r2, #14 + 800de4c: 801a strh r2, [r3, #0] +#endif /* LWIP_ARP || ETHARP_SUPPORT_VLAN */ + + if (p->len <= SIZEOF_ETH_HDR) { + 800de4e: 687b ldr r3, [r7, #4] + 800de50: 895b ldrh r3, [r3, #10] + 800de52: 2b0e cmp r3, #14 + 800de54: d80c bhi.n 800de70 + /* a packet with only an ethernet header (or less) is not valid for us */ + ETHARP_STATS_INC(etharp.proterr); + 800de56: 4b49 ldr r3, [pc, #292] ; (800df7c ) + 800de58: 8d1b ldrh r3, [r3, #40] ; 0x28 + 800de5a: 3301 adds r3, #1 + 800de5c: b29a uxth r2, r3 + 800de5e: 4b47 ldr r3, [pc, #284] ; (800df7c ) + 800de60: 851a strh r2, [r3, #40] ; 0x28 + ETHARP_STATS_INC(etharp.drop); + 800de62: 4b46 ldr r3, [pc, #280] ; (800df7c ) + 800de64: 8bdb ldrh r3, [r3, #30] + 800de66: 3301 adds r3, #1 + 800de68: b29a uxth r2, r3 + 800de6a: 4b44 ldr r3, [pc, #272] ; (800df7c ) + 800de6c: 83da strh r2, [r3, #30] + goto free_and_return; + 800de6e: e07c b.n 800df6a + } + + /* points to packet payload, which starts with an Ethernet header */ + ethhdr = (struct eth_hdr *)p->payload; + 800de70: 687b ldr r3, [r7, #4] + 800de72: 685b ldr r3, [r3, #4] + 800de74: 613b str r3, [r7, #16] + (unsigned)ethhdr->dest.addr[3], (unsigned)ethhdr->dest.addr[4], (unsigned)ethhdr->dest.addr[5], + (unsigned)ethhdr->src.addr[0], (unsigned)ethhdr->src.addr[1], (unsigned)ethhdr->src.addr[2], + (unsigned)ethhdr->src.addr[3], (unsigned)ethhdr->src.addr[4], (unsigned)ethhdr->src.addr[5], + (unsigned)htons(ethhdr->type))); + + type = ethhdr->type; + 800de76: 230e movs r3, #14 + 800de78: 18fa adds r2, r7, r3 + 800de7a: 693b ldr r3, [r7, #16] + 800de7c: 7b19 ldrb r1, [r3, #12] + 800de7e: 7b5b ldrb r3, [r3, #13] + 800de80: 021b lsls r3, r3, #8 + 800de82: 430b orrs r3, r1 + 800de84: 8013 strh r3, [r2, #0] + +#if LWIP_ARP_FILTER_NETIF + netif = LWIP_ARP_FILTER_NETIF_FN(p, netif, htons(type)); +#endif /* LWIP_ARP_FILTER_NETIF*/ + + if (ethhdr->dest.addr[0] & 1) { + 800de86: 693b ldr r3, [r7, #16] + 800de88: 781b ldrb r3, [r3, #0] + 800de8a: 001a movs r2, r3 + 800de8c: 2301 movs r3, #1 + 800de8e: 4013 ands r3, r2 + 800de90: d022 beq.n 800ded8 + /* this might be a multicast or broadcast packet */ + if (ethhdr->dest.addr[0] == LL_MULTICAST_ADDR_0) { + 800de92: 693b ldr r3, [r7, #16] + 800de94: 781b ldrb r3, [r3, #0] + 800de96: 2b01 cmp r3, #1 + 800de98: d10f bne.n 800deba + if ((ethhdr->dest.addr[1] == LL_MULTICAST_ADDR_1) && + 800de9a: 693b ldr r3, [r7, #16] + 800de9c: 785b ldrb r3, [r3, #1] + 800de9e: 2b00 cmp r3, #0 + 800dea0: d11a bne.n 800ded8 + (ethhdr->dest.addr[2] == LL_MULTICAST_ADDR_2)) { + 800dea2: 693b ldr r3, [r7, #16] + 800dea4: 789b ldrb r3, [r3, #2] + if ((ethhdr->dest.addr[1] == LL_MULTICAST_ADDR_1) && + 800dea6: 2b5e cmp r3, #94 ; 0x5e + 800dea8: d116 bne.n 800ded8 + /* mark the pbuf as link-layer multicast */ + p->flags |= PBUF_FLAG_LLMCAST; + 800deaa: 687b ldr r3, [r7, #4] + 800deac: 7b5b ldrb r3, [r3, #13] + 800deae: 2210 movs r2, #16 + 800deb0: 4313 orrs r3, r2 + 800deb2: b2da uxtb r2, r3 + 800deb4: 687b ldr r3, [r7, #4] + 800deb6: 735a strb r2, [r3, #13] + 800deb8: e00e b.n 800ded8 + } + } else if (eth_addr_cmp(ðhdr->dest, ðbroadcast)) { + 800deba: 693b ldr r3, [r7, #16] + 800debc: 4930 ldr r1, [pc, #192] ; (800df80 ) + 800debe: 2206 movs r2, #6 + 800dec0: 0018 movs r0, r3 + 800dec2: f001 fedf bl 800fc84 + 800dec6: 1e03 subs r3, r0, #0 + 800dec8: d106 bne.n 800ded8 + /* mark the pbuf as link-layer broadcast */ + p->flags |= PBUF_FLAG_LLBCAST; + 800deca: 687b ldr r3, [r7, #4] + 800decc: 7b5b ldrb r3, [r3, #13] + 800dece: 2208 movs r2, #8 + 800ded0: 4313 orrs r3, r2 + 800ded2: b2da uxtb r2, r3 + 800ded4: 687b ldr r3, [r7, #4] + 800ded6: 735a strb r2, [r3, #13] + } + } + + switch (type) { + 800ded8: 230e movs r3, #14 + 800deda: 18fb adds r3, r7, r3 + 800dedc: 881b ldrh r3, [r3, #0] + 800dede: 2b08 cmp r3, #8 + 800dee0: d004 beq.n 800deec + 800dee2: 22c1 movs r2, #193 ; 0xc1 + 800dee4: 00d2 lsls r2, r2, #3 + 800dee6: 4293 cmp r3, r2 + 800dee8: d01b beq.n 800df22 + 800deea: e02a b.n 800df42 +#if LWIP_ARP + /* IP packet? */ + case PP_HTONS(ETHTYPE_IP): + if (!(netif->flags & NETIF_FLAG_ETHARP)) { + 800deec: 683b ldr r3, [r7, #0] + 800deee: 2229 movs r2, #41 ; 0x29 + 800def0: 5c9b ldrb r3, [r3, r2] + 800def2: 001a movs r2, r3 + 800def4: 2320 movs r3, #32 + 800def6: 4013 ands r3, r2 + 800def8: d032 beq.n 800df60 +#if ETHARP_TRUST_IP_MAC + /* update ARP table */ + etharp_ip_input(netif, p); +#endif /* ETHARP_TRUST_IP_MAC */ + /* skip Ethernet header */ + if(pbuf_header(p, -ip_hdr_offset)) { + 800defa: 2316 movs r3, #22 + 800defc: 18fb adds r3, r7, r3 + 800defe: 881b ldrh r3, [r3, #0] + 800df00: 425b negs r3, r3 + 800df02: b29b uxth r3, r3 + 800df04: b21a sxth r2, r3 + 800df06: 687b ldr r3, [r7, #4] + 800df08: 0011 movs r1, r2 + 800df0a: 0018 movs r0, r3 + 800df0c: f7f7 fb43 bl 8005596 + 800df10: 1e03 subs r3, r0, #0 + 800df12: d127 bne.n 800df64 + LWIP_ASSERT("Can't move over header in packet", 0); + goto free_and_return; + } else { + /* pass to IP layer */ + ip_input(p, netif); + 800df14: 683a ldr r2, [r7, #0] + 800df16: 687b ldr r3, [r7, #4] + 800df18: 0011 movs r1, r2 + 800df1a: 0018 movs r0, r3 + 800df1c: f7fd fcd8 bl 800b8d0 + } + break; + 800df20: e01c b.n 800df5c + + case PP_HTONS(ETHTYPE_ARP): + if (!(netif->flags & NETIF_FLAG_ETHARP)) { + 800df22: 683b ldr r3, [r7, #0] + 800df24: 2229 movs r2, #41 ; 0x29 + 800df26: 5c9b ldrb r3, [r3, r2] + 800df28: 001a movs r2, r3 + 800df2a: 2320 movs r3, #32 + 800df2c: 4013 ands r3, r2 + 800df2e: d01b beq.n 800df68 + goto free_and_return; + } + /* pass p to ARP module */ + etharp_arp_input(netif, (struct eth_addr*)(netif->hwaddr), p); + 800df30: 683b ldr r3, [r7, #0] + 800df32: 3323 adds r3, #35 ; 0x23 + 800df34: 0019 movs r1, r3 + 800df36: 687a ldr r2, [r7, #4] + 800df38: 683b ldr r3, [r7, #0] + 800df3a: 0018 movs r0, r3 + 800df3c: f7ff fb0c bl 800d558 + break; + 800df40: e00c b.n 800df5c + pppoe_data_input(netif, p); + break; +#endif /* PPPOE_SUPPORT */ + + default: + ETHARP_STATS_INC(etharp.proterr); + 800df42: 4b0e ldr r3, [pc, #56] ; (800df7c ) + 800df44: 8d1b ldrh r3, [r3, #40] ; 0x28 + 800df46: 3301 adds r3, #1 + 800df48: b29a uxth r2, r3 + 800df4a: 4b0c ldr r3, [pc, #48] ; (800df7c ) + 800df4c: 851a strh r2, [r3, #40] ; 0x28 + ETHARP_STATS_INC(etharp.drop); + 800df4e: 4b0b ldr r3, [pc, #44] ; (800df7c ) + 800df50: 8bdb ldrh r3, [r3, #30] + 800df52: 3301 adds r3, #1 + 800df54: b29a uxth r2, r3 + 800df56: 4b09 ldr r3, [pc, #36] ; (800df7c ) + 800df58: 83da strh r2, [r3, #30] + goto free_and_return; + 800df5a: e006 b.n 800df6a + } + + /* This means the pbuf is freed or consumed, + so the caller doesn't have to free it again */ + return ERR_OK; + 800df5c: 2300 movs r3, #0 + 800df5e: e009 b.n 800df74 + goto free_and_return; + 800df60: 46c0 nop ; (mov r8, r8) + 800df62: e002 b.n 800df6a + goto free_and_return; + 800df64: 46c0 nop ; (mov r8, r8) + 800df66: e000 b.n 800df6a + goto free_and_return; + 800df68: 46c0 nop ; (mov r8, r8) + +free_and_return: + pbuf_free(p); + 800df6a: 687b ldr r3, [r7, #4] + 800df6c: 0018 movs r0, r3 + 800df6e: f7f7 fb99 bl 80056a4 + return ERR_OK; + 800df72: 2300 movs r3, #0 +} + 800df74: 0018 movs r0, r3 + 800df76: 46bd mov sp, r7 + 800df78: b006 add sp, #24 + 800df7a: bd80 pop {r7, pc} + 800df7c: 20003158 .word 0x20003158 + 800df80: 0800fdc8 .word 0x0800fdc8 + +0800df84 : + entries /* entries */ +}; + +/* this function is called by usbd_ecm.c during an ISR; it must not block */ +void usb_ecm_recv_callback(const uint8_t *data, int size) +{ + 800df84: b580 push {r7, lr} + 800df86: b082 sub sp, #8 + 800df88: af00 add r7, sp, #0 + 800df8a: 6078 str r0, [r7, #4] + 800df8c: 6039 str r1, [r7, #0] + if (received_frame) + 800df8e: 4b13 ldr r3, [pc, #76] ; (800dfdc ) + 800df90: 681b ldr r3, [r3, #0] + 800df92: 2b00 cmp r3, #0 + 800df94: d11e bne.n 800dfd4 + return; + + received_frame = pbuf_alloc(PBUF_RAW, size, PBUF_POOL); + 800df96: 683b ldr r3, [r7, #0] + 800df98: b29b uxth r3, r3 + 800df9a: 2203 movs r2, #3 + 800df9c: 0019 movs r1, r3 + 800df9e: 2003 movs r0, #3 + 800dfa0: f7f7 f8f4 bl 800518c + 800dfa4: 0002 movs r2, r0 + 800dfa6: 4b0d ldr r3, [pc, #52] ; (800dfdc ) + 800dfa8: 601a str r2, [r3, #0] + if (!received_frame) + 800dfaa: 4b0c ldr r3, [pc, #48] ; (800dfdc ) + 800dfac: 681b ldr r3, [r3, #0] + 800dfae: 2b00 cmp r3, #0 + 800dfb0: d102 bne.n 800dfb8 + { + usb_ecm_recv_renew(); + 800dfb2: f001 fbb9 bl 800f728 + return; + 800dfb6: e00e b.n 800dfd6 + } + + memcpy(received_frame->payload, data, size); + 800dfb8: 4b08 ldr r3, [pc, #32] ; (800dfdc ) + 800dfba: 681b ldr r3, [r3, #0] + 800dfbc: 685b ldr r3, [r3, #4] + 800dfbe: 683a ldr r2, [r7, #0] + 800dfc0: 6879 ldr r1, [r7, #4] + 800dfc2: 0018 movs r0, r3 + 800dfc4: f001 fe6d bl 800fca2 + received_frame->len = size; + 800dfc8: 4b04 ldr r3, [pc, #16] ; (800dfdc ) + 800dfca: 681b ldr r3, [r3, #0] + 800dfcc: 683a ldr r2, [r7, #0] + 800dfce: b292 uxth r2, r2 + 800dfd0: 815a strh r2, [r3, #10] + 800dfd2: e000 b.n 800dfd6 + return; + 800dfd4: 46c0 nop ; (mov r8, r8) +} + 800dfd6: 46bd mov sp, r7 + 800dfd8: b002 add sp, #8 + 800dfda: bd80 pop {r7, pc} + 800dfdc: 200023c0 .word 0x200023c0 + +0800dfe0 : + +uint32_t sys_now() +{ + 800dfe0: b580 push {r7, lr} + 800dfe2: af00 add r7, sp, #0 + return (uint32_t)mtime(); + 800dfe4: f000 f92a bl 800e23c + 800dfe8: 0003 movs r3, r0 +} + 800dfea: 0018 movs r0, r3 + 800dfec: 46bd mov sp, r7 + 800dfee: bd80 pop {r7, pc} + +0800dff0 : + +TIMER_PROC(tcp_timer, TCP_TMR_INTERVAL, 1, NULL) +{ + 800dff0: b580 push {r7, lr} + 800dff2: b082 sub sp, #8 + 800dff4: af00 add r7, sp, #0 + 800dff6: 6078 str r0, [r7, #4] + tcp_tmr(); + 800dff8: f7f7 fddc bl 8005bb4 +} + 800dffc: 46c0 nop ; (mov r8, r8) + 800dffe: 46bd mov sp, r7 + 800e000: b002 add sp, #8 + 800e002: bd80 pop {r7, pc} + +0800e004 : + +err_t output_fn(struct netif *netif, struct pbuf *p, ip_addr_t *ipaddr) +{ + 800e004: b580 push {r7, lr} + 800e006: b084 sub sp, #16 + 800e008: af00 add r7, sp, #0 + 800e00a: 60f8 str r0, [r7, #12] + 800e00c: 60b9 str r1, [r7, #8] + 800e00e: 607a str r2, [r7, #4] + return etharp_output(netif, p, ipaddr); + 800e010: 687a ldr r2, [r7, #4] + 800e012: 68b9 ldr r1, [r7, #8] + 800e014: 68fb ldr r3, [r7, #12] + 800e016: 0018 movs r0, r3 + 800e018: f7ff fbfe bl 800d818 + 800e01c: 0003 movs r3, r0 +} + 800e01e: 0018 movs r0, r3 + 800e020: 46bd mov sp, r7 + 800e022: b004 add sp, #16 + 800e024: bd80 pop {r7, pc} + +0800e026 : + +err_t linkoutput_fn(struct netif *netif, struct pbuf *p) +{ + 800e026: b580 push {r7, lr} + 800e028: b084 sub sp, #16 + 800e02a: af00 add r7, sp, #0 + 800e02c: 6078 str r0, [r7, #4] + 800e02e: 6039 str r1, [r7, #0] + int i; + for (i = 0; i < 200; i++) + 800e030: 2300 movs r3, #0 + 800e032: 60fb str r3, [r7, #12] + 800e034: e009 b.n 800e04a + { + if (usb_ecm_can_xmit()) goto ready; + 800e036: f001 fd31 bl 800fa9c + 800e03a: 1e03 subs r3, r0, #0 + 800e03c: d10b bne.n 800e056 + msleep(1); + 800e03e: 2001 movs r0, #1 + 800e040: f000 f904 bl 800e24c + for (i = 0; i < 200; i++) + 800e044: 68fb ldr r3, [r7, #12] + 800e046: 3301 adds r3, #1 + 800e048: 60fb str r3, [r7, #12] + 800e04a: 68fb ldr r3, [r7, #12] + 800e04c: 2bc7 cmp r3, #199 ; 0xc7 + 800e04e: ddf2 ble.n 800e036 + } + return ERR_USE; + 800e050: 2308 movs r3, #8 + 800e052: 425b negs r3, r3 + 800e054: e005 b.n 800e062 + if (usb_ecm_can_xmit()) goto ready; + 800e056: 46c0 nop ; (mov r8, r8) +ready: + usb_ecm_xmit_packet(p); + 800e058: 683b ldr r3, [r7, #0] + 800e05a: 0018 movs r0, r3 + 800e05c: f001 fd30 bl 800fac0 + return ERR_OK; + 800e060: 2300 movs r3, #0 +} + 800e062: 0018 movs r0, r3 + 800e064: 46bd mov sp, r7 + 800e066: b004 add sp, #16 + 800e068: bd80 pop {r7, pc} + ... + +0800e06c : + +err_t netif_init_cb(struct netif *netif) +{ + 800e06c: b580 push {r7, lr} + 800e06e: b082 sub sp, #8 + 800e070: af00 add r7, sp, #0 + 800e072: 6078 str r0, [r7, #4] + LWIP_ASSERT("netif != NULL", (netif != NULL)); + netif->mtu = ECM_MTU; + 800e074: 687b ldr r3, [r7, #4] + 800e076: 22fa movs r2, #250 ; 0xfa + 800e078: 0052 lsls r2, r2, #1 + 800e07a: 841a strh r2, [r3, #32] + netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP | NETIF_FLAG_UP; + 800e07c: 687b ldr r3, [r7, #4] + 800e07e: 2229 movs r2, #41 ; 0x29 + 800e080: 2133 movs r1, #51 ; 0x33 + 800e082: 5499 strb r1, [r3, r2] + netif->state = NULL; + 800e084: 687b ldr r3, [r7, #4] + 800e086: 2200 movs r2, #0 + 800e088: 61da str r2, [r3, #28] + netif->name[0] = 'E'; + 800e08a: 687b ldr r3, [r7, #4] + 800e08c: 222a movs r2, #42 ; 0x2a + 800e08e: 2145 movs r1, #69 ; 0x45 + 800e090: 5499 strb r1, [r3, r2] + netif->name[1] = 'X'; + 800e092: 687b ldr r3, [r7, #4] + 800e094: 222b movs r2, #43 ; 0x2b + 800e096: 2158 movs r1, #88 ; 0x58 + 800e098: 5499 strb r1, [r3, r2] + netif->linkoutput = linkoutput_fn; + 800e09a: 687b ldr r3, [r7, #4] + 800e09c: 4a04 ldr r2, [pc, #16] ; (800e0b0 ) + 800e09e: 619a str r2, [r3, #24] + netif->output = output_fn; + 800e0a0: 687b ldr r3, [r7, #4] + 800e0a2: 4a04 ldr r2, [pc, #16] ; (800e0b4 ) + 800e0a4: 615a str r2, [r3, #20] + return ERR_OK; + 800e0a6: 2300 movs r3, #0 +} + 800e0a8: 0018 movs r0, r3 + 800e0aa: 46bd mov sp, r7 + 800e0ac: b002 add sp, #8 + 800e0ae: bd80 pop {r7, pc} + 800e0b0: 0800e027 .word 0x0800e027 + 800e0b4: 0800e005 .word 0x0800e005 + +0800e0b8 : + +#define PADDR(ptr) ((ip_addr_t *)ptr) + +static void init_lwip() +{ + 800e0b8: b590 push {r4, r7, lr} + 800e0ba: b087 sub sp, #28 + 800e0bc: af04 add r7, sp, #16 + struct netif *netif = &netif_data; + 800e0be: 4b16 ldr r3, [pc, #88] ; (800e118 ) + 800e0c0: 607b str r3, [r7, #4] + + lwip_init(); + 800e0c2: f7f6 faf3 bl 80046ac + netif->hwaddr_len = 6; + 800e0c6: 687b ldr r3, [r7, #4] + 800e0c8: 2222 movs r2, #34 ; 0x22 + 800e0ca: 2106 movs r1, #6 + 800e0cc: 5499 strb r1, [r3, r2] + memcpy(netif->hwaddr, hwaddr, 6); + 800e0ce: 687b ldr r3, [r7, #4] + 800e0d0: 3323 adds r3, #35 ; 0x23 + 800e0d2: 001a movs r2, r3 + 800e0d4: 4b11 ldr r3, [pc, #68] ; (800e11c ) + 800e0d6: 0010 movs r0, r2 + 800e0d8: 0019 movs r1, r3 + 800e0da: 2306 movs r3, #6 + 800e0dc: 001a movs r2, r3 + 800e0de: f001 fde0 bl 800fca2 + + netif = netif_add(netif, PADDR(ipaddr), PADDR(netmask), PADDR(gateway), NULL, netif_init_cb, ip_input); + 800e0e2: 4c0f ldr r4, [pc, #60] ; (800e120 ) + 800e0e4: 4a0f ldr r2, [pc, #60] ; (800e124 ) + 800e0e6: 4910 ldr r1, [pc, #64] ; (800e128 ) + 800e0e8: 6878 ldr r0, [r7, #4] + 800e0ea: 4b10 ldr r3, [pc, #64] ; (800e12c ) + 800e0ec: 9302 str r3, [sp, #8] + 800e0ee: 4b10 ldr r3, [pc, #64] ; (800e130 ) + 800e0f0: 9301 str r3, [sp, #4] + 800e0f2: 2300 movs r3, #0 + 800e0f4: 9300 str r3, [sp, #0] + 800e0f6: 0023 movs r3, r4 + 800e0f8: f7f6 ff52 bl 8004fa0 + 800e0fc: 0003 movs r3, r0 + 800e0fe: 607b str r3, [r7, #4] + netif_set_default(netif); + 800e100: 687b ldr r3, [r7, #4] + 800e102: 0018 movs r0, r3 + 800e104: f7f7 f82a bl 800515c + + stmr_add(&tcp_timer); + 800e108: 4b0a ldr r3, [pc, #40] ; (800e134 ) + 800e10a: 0018 movs r0, r3 + 800e10c: f000 f8f2 bl 800e2f4 +} + 800e110: 46c0 nop ; (mov r8, r8) + 800e112: 46bd mov sp, r7 + 800e114: b003 add sp, #12 + 800e116: bd90 pop {r4, r7, pc} + 800e118: 2000238c .word 0x2000238c + 800e11c: 20000018 .word 0x20000018 + 800e120: 200023bc .word 0x200023bc + 800e124: 20000024 .word 0x20000024 + 800e128: 20000020 .word 0x20000020 + 800e12c: 0800b8d1 .word 0x0800b8d1 + 800e130: 0800e06d .word 0x0800e06d + 800e134: 2000007c .word 0x2000007c + +0800e138 : + + +bool dns_query_proc(const char *name, ip_addr_t *addr) +{ + 800e138: b580 push {r7, lr} + 800e13a: b082 sub sp, #8 + 800e13c: af00 add r7, sp, #0 + 800e13e: 6078 str r0, [r7, #4] + 800e140: 6039 str r1, [r7, #0] + if (strcmp(name, "run.stm") == 0 || strcmp(name, "www.run.stm") == 0) + 800e142: 4a0d ldr r2, [pc, #52] ; (800e178 ) + 800e144: 687b ldr r3, [r7, #4] + 800e146: 0011 movs r1, r2 + 800e148: 0018 movs r0, r3 + 800e14a: f7f1 ffdd bl 8000108 + 800e14e: 1e03 subs r3, r0, #0 + 800e150: d007 beq.n 800e162 + 800e152: 4a0a ldr r2, [pc, #40] ; (800e17c ) + 800e154: 687b ldr r3, [r7, #4] + 800e156: 0011 movs r1, r2 + 800e158: 0018 movs r0, r3 + 800e15a: f7f1 ffd5 bl 8000108 + 800e15e: 1e03 subs r3, r0, #0 + 800e160: d105 bne.n 800e16e + { + addr->addr = *(uint32_t *)ipaddr; + 800e162: 4b07 ldr r3, [pc, #28] ; (800e180 ) + 800e164: 681a ldr r2, [r3, #0] + 800e166: 683b ldr r3, [r7, #0] + 800e168: 601a str r2, [r3, #0] + return true; + 800e16a: 2301 movs r3, #1 + 800e16c: e000 b.n 800e170 + } + return false; + 800e16e: 2300 movs r3, #0 +} + 800e170: 0018 movs r0, r3 + 800e172: 46bd mov sp, r7 + 800e174: b002 add sp, #8 + 800e176: bd80 pop {r7, pc} + 800e178: 0800fd08 .word 0x0800fd08 + 800e17c: 0800fd10 .word 0x0800fd10 + 800e180: 20000020 .word 0x20000020 + +0800e184 : + +// return res; +//} + +static void service_traffic(void) +{ + 800e184: b580 push {r7, lr} + 800e186: b082 sub sp, #8 + 800e188: af00 add r7, sp, #0 + \details Disables IRQ interrupts by setting the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __disable_irq(void) +{ + __ASM volatile ("cpsid i" : : : "memory"); + 800e18a: b672 cpsid i + struct pbuf *frame; + + /* retrieve and clear var set by usb_ecm_recv_callback() in ISR */ + __disable_irq(); + frame = received_frame; + 800e18c: 4b0d ldr r3, [pc, #52] ; (800e1c4 ) + 800e18e: 681b ldr r3, [r3, #0] + 800e190: 607b str r3, [r7, #4] + received_frame = NULL; + 800e192: 4b0c ldr r3, [pc, #48] ; (800e1c4 ) + 800e194: 2200 movs r2, #0 + 800e196: 601a str r2, [r3, #0] + __ASM volatile ("cpsie i" : : : "memory"); + 800e198: b662 cpsie i + __enable_irq(); + + if (!frame) + 800e19a: 687b ldr r3, [r7, #4] + 800e19c: 2b00 cmp r3, #0 + 800e19e: d00c beq.n 800e1ba + return; /* no packet was received */ + + /* packet was received, so handle it */ + ethernet_input(frame, &netif_data); + 800e1a0: 4a09 ldr r2, [pc, #36] ; (800e1c8 ) + 800e1a2: 687b ldr r3, [r7, #4] + 800e1a4: 0011 movs r1, r2 + 800e1a6: 0018 movs r0, r3 + 800e1a8: f7ff fe48 bl 800de3c + pbuf_free(frame); + 800e1ac: 687b ldr r3, [r7, #4] + 800e1ae: 0018 movs r0, r3 + 800e1b0: f7f7 fa78 bl 80056a4 + + /* tell usbd_ecm.c it is OK to receive another packet */ + usb_ecm_recv_renew(); + 800e1b4: f001 fab8 bl 800f728 + 800e1b8: e000 b.n 800e1bc + return; /* no packet was received */ + 800e1ba: 46c0 nop ; (mov r8, r8) +} + 800e1bc: 46bd mov sp, r7 + 800e1be: b002 add sp, #8 + 800e1c0: bd80 pop {r7, pc} + 800e1c2: 46c0 nop ; (mov r8, r8) + 800e1c4: 200023c0 .word 0x200023c0 + 800e1c8: 2000238c .word 0x2000238c + +0800e1cc : + +void ecm_main_init() +{ + 800e1cc: b580 push {r7, lr} + 800e1ce: af00 add r7, sp, #0 + time_init(); + 800e1d0: f000 f82f bl 800e232 + init_lwip(); + 800e1d4: f7ff ff70 bl 800e0b8 + + while (!netif_is_up(&netif_data)); + 800e1d8: 46c0 nop ; (mov r8, r8) + 800e1da: 4b0d ldr r3, [pc, #52] ; (800e210 ) + 800e1dc: 2229 movs r2, #41 ; 0x29 + 800e1de: 5c9b ldrb r3, [r3, r2] + 800e1e0: 001a movs r2, r3 + 800e1e2: 2301 movs r3, #1 + 800e1e4: 4013 ands r3, r2 + 800e1e6: d0f8 beq.n 800e1da + + while (dhserv_init(&dhcp_config) != ERR_OK); + 800e1e8: 46c0 nop ; (mov r8, r8) + 800e1ea: 4b0a ldr r3, [pc, #40] ; (800e214 ) + 800e1ec: 0018 movs r0, r3 + 800e1ee: f7f5 ff57 bl 80040a0 + 800e1f2: 1e03 subs r3, r0, #0 + 800e1f4: d1f9 bne.n 800e1ea + + while (dnserv_init(PADDR(ipaddr), 53, dns_query_proc) != ERR_OK); + 800e1f6: 46c0 nop ; (mov r8, r8) + 800e1f8: 4a07 ldr r2, [pc, #28] ; (800e218 ) + 800e1fa: 4b08 ldr r3, [pc, #32] ; (800e21c ) + 800e1fc: 2135 movs r1, #53 ; 0x35 + 800e1fe: 0018 movs r0, r3 + 800e200: f7f6 f9ac bl 800455c + 800e204: 1e03 subs r3, r0, #0 + 800e206: d1f7 bne.n 800e1f8 + + //http_set_cgi_handlers(cgi_uri_table, sizeof(cgi_uri_table) / sizeof(*cgi_uri_table)); + //http_set_ssi_handler(ssi_handler, ssi_tags_table, sizeof(ssi_tags_table) / sizeof(*ssi_tags_table)); + // httpd_init(); +} + 800e208: 46c0 nop ; (mov r8, r8) + 800e20a: 46bd mov sp, r7 + 800e20c: bd80 pop {r7, pc} + 800e20e: 46c0 nop ; (mov r8, r8) + 800e210: 2000238c .word 0x2000238c + 800e214: 20000064 .word 0x20000064 + 800e218: 0800e139 .word 0x0800e139 + 800e21c: 20000020 .word 0x20000020 + +0800e220 : + +void ecm_main_loop() +{ + 800e220: b580 push {r7, lr} + 800e222: af00 add r7, sp, #0 + service_traffic(); + 800e224: f7ff ffae bl 800e184 + stmr(); + 800e228: f000 f82e bl 800e288 +} + 800e22c: 46c0 nop ; (mov r8, r8) + 800e22e: 46bd mov sp, r7 + 800e230: bd80 pop {r7, pc} + +0800e232 : + +volatile uint32_t sysTimeTicks; +volatile uint32_t sysTimeDelayCounter; + +void time_init(void) +{ + 800e232: b580 push {r7, lr} + 800e234: af00 add r7, sp, #0 +// if (SysTick_Config(SystemCoreClock / 1000)) +// while (1) {} /* Capture error */ +} + 800e236: 46c0 nop ; (mov r8, r8) + 800e238: 46bd mov sp, r7 + 800e23a: bd80 pop {r7, pc} + +0800e23c : + // msAddition++; /* +1 ms */ +//} + + +uint32_t mtime(void) +{ + 800e23c: b580 push {r7, lr} + 800e23e: af00 add r7, sp, #0 + res = msAddition; + ctrl = SysTick->CTRL; + if (ctrl & SysTick_CTRL_COUNTFLAG_Msk) + goto read; + */ + return HAL_GetTick(); + 800e240: f7f2 fa40 bl 80006c4 + 800e244: 0003 movs r3, r0 +} + 800e246: 0018 movs r0, r3 + 800e248: 46bd mov sp, r7 + 800e24a: bd80 pop {r7, pc} + +0800e24c : + +void msleep(int ms) +{ + 800e24c: b580 push {r7, lr} + 800e24e: b084 sub sp, #16 + 800e250: af00 add r7, sp, #0 + 800e252: 6078 str r0, [r7, #4] + uint32_t t = mtime(); + 800e254: f7ff fff2 bl 800e23c + 800e258: 0003 movs r3, r0 + 800e25a: 60fb str r3, [r7, #12] + while (true) + { + uint32_t t1 = mtime(); + 800e25c: f7ff ffee bl 800e23c + 800e260: 0003 movs r3, r0 + 800e262: 60bb str r3, [r7, #8] + if (t1 - t >= ms) break; + 800e264: 68ba ldr r2, [r7, #8] + 800e266: 68fb ldr r3, [r7, #12] + 800e268: 1ad2 subs r2, r2, r3 + 800e26a: 687b ldr r3, [r7, #4] + 800e26c: 429a cmp r2, r3 + 800e26e: d204 bcs.n 800e27a + if (t1 < t) break; /* overflow */ + 800e270: 68ba ldr r2, [r7, #8] + 800e272: 68fb ldr r3, [r7, #12] + 800e274: 429a cmp r2, r3 + 800e276: d302 bcc.n 800e27e + { + 800e278: e7f0 b.n 800e25c + if (t1 - t >= ms) break; + 800e27a: 46c0 nop ; (mov r8, r8) + 800e27c: e000 b.n 800e280 + if (t1 < t) break; /* overflow */ + 800e27e: 46c0 nop ; (mov r8, r8) + } +} + 800e280: 46c0 nop ; (mov r8, r8) + 800e282: 46bd mov sp, r7 + 800e284: b004 add sp, #16 + 800e286: bd80 pop {r7, pc} + +0800e288 : + +static stmr_t *stmrs = NULL; + +void stmr(void) +{ + 800e288: b580 push {r7, lr} + 800e28a: b084 sub sp, #16 + 800e28c: af00 add r7, sp, #0 + stmr_t *tmr; + uint32_t time; + time = mtime(); + 800e28e: f7ff ffd5 bl 800e23c + 800e292: 0003 movs r3, r0 + 800e294: 60bb str r3, [r7, #8] + tmr = stmrs; + 800e296: 4b16 ldr r3, [pc, #88] ; (800e2f0 ) + 800e298: 681b ldr r3, [r3, #0] + 800e29a: 60fb str r3, [r7, #12] + while (tmr != NULL) + 800e29c: e021 b.n 800e2e2 + { + stmr_t *t; + uint32_t elapsed; + t = tmr; + 800e29e: 68fb ldr r3, [r7, #12] + 800e2a0: 607b str r3, [r7, #4] + tmr = tmr->next; + 800e2a2: 68fb ldr r3, [r7, #12] + 800e2a4: 695b ldr r3, [r3, #20] + 800e2a6: 60fb str r3, [r7, #12] + if ((t->flags & STMR_ACTIVE) == 0) + 800e2a8: 687b ldr r3, [r7, #4] + 800e2aa: 689b ldr r3, [r3, #8] + 800e2ac: 2201 movs r2, #1 + 800e2ae: 4013 ands r3, r2 + 800e2b0: d100 bne.n 800e2b4 + continue; + 800e2b2: e016 b.n 800e2e2 + elapsed = time; + 800e2b4: 68bb ldr r3, [r7, #8] + 800e2b6: 603b str r3, [r7, #0] + elapsed -= t->event; + 800e2b8: 687b ldr r3, [r7, #4] + 800e2ba: 685b ldr r3, [r3, #4] + 800e2bc: 683a ldr r2, [r7, #0] + 800e2be: 1ad3 subs r3, r2, r3 + 800e2c0: 603b str r3, [r7, #0] + if (elapsed < t->period) + 800e2c2: 687b ldr r3, [r7, #4] + 800e2c4: 681b ldr r3, [r3, #0] + 800e2c6: 683a ldr r2, [r7, #0] + 800e2c8: 429a cmp r2, r3 + 800e2ca: d200 bcs.n 800e2ce + continue; + 800e2cc: e009 b.n 800e2e2 + t->proc(t); + 800e2ce: 687b ldr r3, [r7, #4] + 800e2d0: 691b ldr r3, [r3, #16] + 800e2d2: 687a ldr r2, [r7, #4] + 800e2d4: 0010 movs r0, r2 + 800e2d6: 4798 blx r3 + t->event = mtime(); + 800e2d8: f7ff ffb0 bl 800e23c + 800e2dc: 0002 movs r2, r0 + 800e2de: 687b ldr r3, [r7, #4] + 800e2e0: 605a str r2, [r3, #4] + while (tmr != NULL) + 800e2e2: 68fb ldr r3, [r7, #12] + 800e2e4: 2b00 cmp r3, #0 + 800e2e6: d1da bne.n 800e29e + } +} + 800e2e8: 46c0 nop ; (mov r8, r8) + 800e2ea: 46bd mov sp, r7 + 800e2ec: b004 add sp, #16 + 800e2ee: bd80 pop {r7, pc} + 800e2f0: 200023c4 .word 0x200023c4 + +0800e2f4 : + tmr->next = stmrs; + stmrs = tmr; +} + +void stmr_add(stmr_t *tmr) +{ + 800e2f4: b580 push {r7, lr} + 800e2f6: b082 sub sp, #8 + 800e2f8: af00 add r7, sp, #0 + 800e2fa: 6078 str r0, [r7, #4] + tmr->next = stmrs; + 800e2fc: 4b05 ldr r3, [pc, #20] ; (800e314 ) + 800e2fe: 681a ldr r2, [r3, #0] + 800e300: 687b ldr r3, [r7, #4] + 800e302: 615a str r2, [r3, #20] + stmrs = tmr; + 800e304: 4b03 ldr r3, [pc, #12] ; (800e314 ) + 800e306: 687a ldr r2, [r7, #4] + 800e308: 601a str r2, [r3, #0] +} + 800e30a: 46c0 nop ; (mov r8, r8) + 800e30c: 46bd mov sp, r7 + 800e30e: b002 add sp, #8 + 800e310: bd80 pop {r7, pc} + 800e312: 46c0 nop ; (mov r8, r8) + 800e314: 200023c4 .word 0x200023c4 + +0800e318 : +/** + * Init USB device Library, add supported class and start the library + * @retval None + */ +void MX_USB_DEVICE_Init(void) +{ + 800e318: b580 push {r7, lr} + 800e31a: af00 add r7, sp, #0 + /* USER CODE BEGIN USB_DEVICE_Init_PreTreatment */ + + /* USER CODE END USB_DEVICE_Init_PreTreatment */ + + /* Init Device Library, add supported class and start the library. */ + if (USBD_Init(&hUsbDeviceFS, &VCP_Desc, 0) != USBD_OK) + 800e31c: 4913 ldr r1, [pc, #76] ; (800e36c ) + 800e31e: 4b14 ldr r3, [pc, #80] ; (800e370 ) + 800e320: 2200 movs r2, #0 + 800e322: 0018 movs r0, r3 + 800e324: f000 fa5b bl 800e7de + 800e328: 1e03 subs r3, r0, #0 + 800e32a: d001 beq.n 800e330 + { + Error_Handler(); + 800e32c: f7f2 f8f0 bl 8000510 + } + if (USBD_RegisterClass(&hUsbDeviceFS, &USBD_ECM) != USBD_OK) + 800e330: 4a10 ldr r2, [pc, #64] ; (800e374 ) + 800e332: 4b0f ldr r3, [pc, #60] ; (800e370 ) + 800e334: 0011 movs r1, r2 + 800e336: 0018 movs r0, r3 + 800e338: f000 fa82 bl 800e840 + 800e33c: 1e03 subs r3, r0, #0 + 800e33e: d001 beq.n 800e344 + { + Error_Handler(); + 800e340: f7f2 f8e6 bl 8000510 + } + if (USBD_ECM_RegisterInterface(&hUsbDeviceFS) != USBD_OK) + 800e344: 4b0a ldr r3, [pc, #40] ; (800e370 ) + 800e346: 0018 movs r0, r3 + 800e348: f001 fb6e bl 800fa28 + 800e34c: 1e03 subs r3, r0, #0 + 800e34e: d001 beq.n 800e354 + { + Error_Handler(); + 800e350: f7f2 f8de bl 8000510 + } + if (USBD_Start(&hUsbDeviceFS) != USBD_OK) + 800e354: 4b06 ldr r3, [pc, #24] ; (800e370 ) + 800e356: 0018 movs r0, r3 + 800e358: f000 fa93 bl 800e882 + 800e35c: 1e03 subs r3, r0, #0 + 800e35e: d001 beq.n 800e364 + { + Error_Handler(); + 800e360: f7f2 f8d6 bl 8000510 + } + + /* USER CODE BEGIN USB_DEVICE_Init_PostTreatment */ + + /* USER CODE END USB_DEVICE_Init_PostTreatment */ +} + 800e364: 46c0 nop ; (mov r8, r8) + 800e366: 46bd mov sp, r7 + 800e368: bd80 pop {r7, pc} + 800e36a: 46c0 nop ; (mov r8, r8) + 800e36c: 0800fe00 .word 0x0800fe00 + 800e370: 200032a4 .word 0x200032a4 + 800e374: 0800fe7c .word 0x0800fe7c + +0800e378 : + */ +#ifndef GPIO_SPEED_HIGH +#define GPIO_SPEED_HIGH GPIO_SPEED_FREQ_HIGH +#endif +void HAL_PCD_MspInit(PCD_HandleTypeDef *hpcd) +{ + 800e378: b580 push {r7, lr} + 800e37a: b08a sub sp, #40 ; 0x28 + 800e37c: af00 add r7, sp, #0 + 800e37e: 6078 str r0, [r7, #4] + GPIO_InitTypeDef GPIO_InitStruct; + + /* Enable the GPIOA clock */ + __HAL_RCC_GPIOA_CLK_ENABLE(); + 800e380: 4b1f ldr r3, [pc, #124] ; (800e400 ) + 800e382: 695a ldr r2, [r3, #20] + 800e384: 4b1e ldr r3, [pc, #120] ; (800e400 ) + 800e386: 2180 movs r1, #128 ; 0x80 + 800e388: 0289 lsls r1, r1, #10 + 800e38a: 430a orrs r2, r1 + 800e38c: 615a str r2, [r3, #20] + 800e38e: 4b1c ldr r3, [pc, #112] ; (800e400 ) + 800e390: 695a ldr r2, [r3, #20] + 800e392: 2380 movs r3, #128 ; 0x80 + 800e394: 029b lsls r3, r3, #10 + 800e396: 4013 ands r3, r2 + 800e398: 613b str r3, [r7, #16] + 800e39a: 693b ldr r3, [r7, #16] + + /* Configure USB DM and DP pins. + This is optional, and maintained only for user guidance. */ + GPIO_InitStruct.Pin = (GPIO_PIN_11 | GPIO_PIN_12); + 800e39c: 2114 movs r1, #20 + 800e39e: 187b adds r3, r7, r1 + 800e3a0: 22c0 movs r2, #192 ; 0xc0 + 800e3a2: 0152 lsls r2, r2, #5 + 800e3a4: 601a str r2, [r3, #0] + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + 800e3a6: 187b adds r3, r7, r1 + 800e3a8: 2202 movs r2, #2 + 800e3aa: 605a str r2, [r3, #4] + GPIO_InitStruct.Pull = GPIO_NOPULL; + 800e3ac: 187b adds r3, r7, r1 + 800e3ae: 2200 movs r2, #0 + 800e3b0: 609a str r2, [r3, #8] + GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; + 800e3b2: 187b adds r3, r7, r1 + 800e3b4: 2203 movs r2, #3 + 800e3b6: 60da str r2, [r3, #12] + GPIO_InitStruct.Alternate = GPIO_AF2_USB; + 800e3b8: 187b adds r3, r7, r1 + 800e3ba: 2202 movs r2, #2 + 800e3bc: 611a str r2, [r3, #16] + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + 800e3be: 187a adds r2, r7, r1 + 800e3c0: 2390 movs r3, #144 ; 0x90 + 800e3c2: 05db lsls r3, r3, #23 + 800e3c4: 0011 movs r1, r2 + 800e3c6: 0018 movs r0, r3 + 800e3c8: f7f2 fa64 bl 8000894 + + /* Enable USB FS Clock */ + __HAL_RCC_USB_CLK_ENABLE(); + 800e3cc: 4b0c ldr r3, [pc, #48] ; (800e400 ) + 800e3ce: 69da ldr r2, [r3, #28] + 800e3d0: 4b0b ldr r3, [pc, #44] ; (800e400 ) + 800e3d2: 2180 movs r1, #128 ; 0x80 + 800e3d4: 0409 lsls r1, r1, #16 + 800e3d6: 430a orrs r2, r1 + 800e3d8: 61da str r2, [r3, #28] + 800e3da: 4b09 ldr r3, [pc, #36] ; (800e400 ) + 800e3dc: 69da ldr r2, [r3, #28] + 800e3de: 2380 movs r3, #128 ; 0x80 + 800e3e0: 041b lsls r3, r3, #16 + 800e3e2: 4013 ands r3, r2 + 800e3e4: 60fb str r3, [r7, #12] + 800e3e6: 68fb ldr r3, [r7, #12] + + /* Set USB FS Interrupt priority */ + HAL_NVIC_SetPriority(USB_IRQn, 3 /* hard-coded: customize if needed */, 0); + 800e3e8: 2200 movs r2, #0 + 800e3ea: 2103 movs r1, #3 + 800e3ec: 201f movs r0, #31 + 800e3ee: f7f2 fa1f bl 8000830 + + /* Enable USB FS Interrupt */ + HAL_NVIC_EnableIRQ(USB_IRQn); + 800e3f2: 201f movs r0, #31 + 800e3f4: f7f2 fa31 bl 800085a +} + 800e3f8: 46c0 nop ; (mov r8, r8) + 800e3fa: 46bd mov sp, r7 + 800e3fc: b00a add sp, #40 ; 0x28 + 800e3fe: bd80 pop {r7, pc} + 800e400: 40021000 .word 0x40021000 + +0800e404 : + * @brief SOF callback. + * @param hpcd: PCD handle + * @retval None + */ +void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd) +{ + 800e404: b580 push {r7, lr} + 800e406: b082 sub sp, #8 + 800e408: af00 add r7, sp, #0 + 800e40a: 6078 str r0, [r7, #4] + USBD_LL_SetupStage(hpcd->pData, (uint8_t *)hpcd->Setup); + 800e40c: 687a ldr r2, [r7, #4] + 800e40e: 239c movs r3, #156 ; 0x9c + 800e410: 009b lsls r3, r3, #2 + 800e412: 58d2 ldr r2, [r2, r3] + 800e414: 687b ldr r3, [r7, #4] + 800e416: 218c movs r1, #140 ; 0x8c + 800e418: 0089 lsls r1, r1, #2 + 800e41a: 468c mov ip, r1 + 800e41c: 4463 add r3, ip + 800e41e: 0019 movs r1, r3 + 800e420: 0010 movs r0, r2 + 800e422: f000 fa79 bl 800e918 +} + 800e426: 46c0 nop ; (mov r8, r8) + 800e428: 46bd mov sp, r7 + 800e42a: b002 add sp, #8 + 800e42c: bd80 pop {r7, pc} + +0800e42e : + * @param hpcd: PCD handle + * @param epnum: Endpoint Number + * @retval None + */ +void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) +{ + 800e42e: b580 push {r7, lr} + 800e430: b082 sub sp, #8 + 800e432: af00 add r7, sp, #0 + 800e434: 6078 str r0, [r7, #4] + 800e436: 000a movs r2, r1 + 800e438: 1cfb adds r3, r7, #3 + 800e43a: 701a strb r2, [r3, #0] + USBD_LL_DataOutStage(hpcd->pData, epnum, hpcd->OUT_ep[epnum].xfer_buff); + 800e43c: 687a ldr r2, [r7, #4] + 800e43e: 239c movs r3, #156 ; 0x9c + 800e440: 009b lsls r3, r3, #2 + 800e442: 58d0 ldr r0, [r2, r3] + 800e444: 1cfb adds r3, r7, #3 + 800e446: 781a ldrb r2, [r3, #0] + 800e448: 6879 ldr r1, [r7, #4] + 800e44a: 239e movs r3, #158 ; 0x9e + 800e44c: 005b lsls r3, r3, #1 + 800e44e: 0152 lsls r2, r2, #5 + 800e450: 188a adds r2, r1, r2 + 800e452: 18d3 adds r3, r2, r3 + 800e454: 681a ldr r2, [r3, #0] + 800e456: 1cfb adds r3, r7, #3 + 800e458: 781b ldrb r3, [r3, #0] + 800e45a: 0019 movs r1, r3 + 800e45c: f000 fab8 bl 800e9d0 +} + 800e460: 46c0 nop ; (mov r8, r8) + 800e462: 46bd mov sp, r7 + 800e464: b002 add sp, #8 + 800e466: bd80 pop {r7, pc} + +0800e468 : + * @param hpcd: PCD handle + * @param epnum: Endpoint Number + * @retval None + */ +void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) +{ + 800e468: b580 push {r7, lr} + 800e46a: b082 sub sp, #8 + 800e46c: af00 add r7, sp, #0 + 800e46e: 6078 str r0, [r7, #4] + 800e470: 000a movs r2, r1 + 800e472: 1cfb adds r3, r7, #3 + 800e474: 701a strb r2, [r3, #0] + USBD_LL_DataInStage(hpcd->pData, epnum, hpcd->IN_ep[epnum].xfer_buff); + 800e476: 687a ldr r2, [r7, #4] + 800e478: 239c movs r3, #156 ; 0x9c + 800e47a: 009b lsls r3, r3, #2 + 800e47c: 58d0 ldr r0, [r2, r3] + 800e47e: 1cfb adds r3, r7, #3 + 800e480: 781b ldrb r3, [r3, #0] + 800e482: 687a ldr r2, [r7, #4] + 800e484: 015b lsls r3, r3, #5 + 800e486: 18d3 adds r3, r2, r3 + 800e488: 333c adds r3, #60 ; 0x3c + 800e48a: 681a ldr r2, [r3, #0] + 800e48c: 1cfb adds r3, r7, #3 + 800e48e: 781b ldrb r3, [r3, #0] + 800e490: 0019 movs r1, r3 + 800e492: f000 fb06 bl 800eaa2 +} + 800e496: 46c0 nop ; (mov r8, r8) + 800e498: 46bd mov sp, r7 + 800e49a: b002 add sp, #8 + 800e49c: bd80 pop {r7, pc} + +0800e49e : + * @brief SOF callback. + * @param hpcd: PCD handle + * @retval None + */ +void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd) +{ + 800e49e: b580 push {r7, lr} + 800e4a0: b082 sub sp, #8 + 800e4a2: af00 add r7, sp, #0 + 800e4a4: 6078 str r0, [r7, #4] + USBD_LL_SOF(hpcd->pData); + 800e4a6: 687a ldr r2, [r7, #4] + 800e4a8: 239c movs r3, #156 ; 0x9c + 800e4aa: 009b lsls r3, r3, #2 + 800e4ac: 58d3 ldr r3, [r2, r3] + 800e4ae: 0018 movs r0, r3 + 800e4b0: f000 fbc1 bl 800ec36 +} + 800e4b4: 46c0 nop ; (mov r8, r8) + 800e4b6: 46bd mov sp, r7 + 800e4b8: b002 add sp, #8 + 800e4ba: bd80 pop {r7, pc} + +0800e4bc : + * @brief SOF callback. + * @param hpcd: PCD handle + * @retval None + */ +void HAL_PCD_ResetCallback(PCD_HandleTypeDef *hpcd) +{ + 800e4bc: b580 push {r7, lr} + 800e4be: b082 sub sp, #8 + 800e4c0: af00 add r7, sp, #0 + 800e4c2: 6078 str r0, [r7, #4] + USBD_LL_SetSpeed(hpcd->pData, USBD_SPEED_FULL); + 800e4c4: 687a ldr r2, [r7, #4] + 800e4c6: 239c movs r3, #156 ; 0x9c + 800e4c8: 009b lsls r3, r3, #2 + 800e4ca: 58d3 ldr r3, [r2, r3] + 800e4cc: 2101 movs r1, #1 + 800e4ce: 0018 movs r0, r3 + 800e4d0: f000 fba1 bl 800ec16 + /* Reset Device */ + USBD_LL_Reset(hpcd->pData); + 800e4d4: 687a ldr r2, [r7, #4] + 800e4d6: 239c movs r3, #156 ; 0x9c + 800e4d8: 009b lsls r3, r3, #2 + 800e4da: 58d3 ldr r3, [r2, r3] + 800e4dc: 0018 movs r0, r3 + 800e4de: f000 fb67 bl 800ebb0 +} + 800e4e2: 46c0 nop ; (mov r8, r8) + 800e4e4: 46bd mov sp, r7 + 800e4e6: b002 add sp, #8 + 800e4e8: bd80 pop {r7, pc} + +0800e4ea : + * @brief SOF callback. + * @param hpcd: PCD handle + * @retval None + */ +void HAL_PCD_SuspendCallback(PCD_HandleTypeDef *hpcd) +{ + 800e4ea: b580 push {r7, lr} + 800e4ec: b082 sub sp, #8 + 800e4ee: af00 add r7, sp, #0 + 800e4f0: 6078 str r0, [r7, #4] +} + 800e4f2: 46c0 nop ; (mov r8, r8) + 800e4f4: 46bd mov sp, r7 + 800e4f6: b002 add sp, #8 + 800e4f8: bd80 pop {r7, pc} + +0800e4fa : + * @brief SOF callback. + * @param hpcd: PCD handle + * @retval None + */ +void HAL_PCD_ResumeCallback(PCD_HandleTypeDef *hpcd) +{ + 800e4fa: b580 push {r7, lr} + 800e4fc: b082 sub sp, #8 + 800e4fe: af00 add r7, sp, #0 + 800e500: 6078 str r0, [r7, #4] +} + 800e502: 46c0 nop ; (mov r8, r8) + 800e504: 46bd mov sp, r7 + 800e506: b002 add sp, #8 + 800e508: bd80 pop {r7, pc} + ... + +0800e50c : + * @brief Initializes the Low Level portion of the Device driver. + * @param pdev: Device handle + * @retval USBD Status + */ +USBD_StatusTypeDef USBD_LL_Init(USBD_HandleTypeDef *pdev) +{ + 800e50c: b580 push {r7, lr} + 800e50e: b084 sub sp, #16 + 800e510: af00 add r7, sp, #0 + 800e512: 6078 str r0, [r7, #4] + uint32_t pma_address; + + /* Set LL Driver parameters */ + hpcd.Instance = USB; + 800e514: 4b21 ldr r3, [pc, #132] ; (800e59c ) + 800e516: 4a22 ldr r2, [pc, #136] ; (800e5a0 ) + 800e518: 601a str r2, [r3, #0] + hpcd.Init.ep0_mps = 0x40; + 800e51a: 4b20 ldr r3, [pc, #128] ; (800e59c ) + 800e51c: 2240 movs r2, #64 ; 0x40 + 800e51e: 60da str r2, [r3, #12] + hpcd.Init.phy_itface = PCD_PHY_EMBEDDED; + 800e520: 4b1e ldr r3, [pc, #120] ; (800e59c ) + 800e522: 2202 movs r2, #2 + 800e524: 611a str r2, [r3, #16] + hpcd.Init.speed = PCD_SPEED_FULL; + 800e526: 4b1d ldr r3, [pc, #116] ; (800e59c ) + 800e528: 2202 movs r2, #2 + 800e52a: 609a str r2, [r3, #8] + /* Link The driver to the stack */ + hpcd.pData = pdev; + 800e52c: 4a1b ldr r2, [pc, #108] ; (800e59c ) + 800e52e: 239c movs r3, #156 ; 0x9c + 800e530: 009b lsls r3, r3, #2 + 800e532: 6879 ldr r1, [r7, #4] + 800e534: 50d1 str r1, [r2, r3] + pdev->pData = &hpcd; + 800e536: 687a ldr r2, [r7, #4] + 800e538: 2387 movs r3, #135 ; 0x87 + 800e53a: 009b lsls r3, r3, #2 + 800e53c: 4917 ldr r1, [pc, #92] ; (800e59c ) + 800e53e: 50d1 str r1, [r2, r3] + /* Initialize LL Driver */ + HAL_PCD_Init(pdev->pData); + 800e540: 687a ldr r2, [r7, #4] + 800e542: 2387 movs r3, #135 ; 0x87 + 800e544: 009b lsls r3, r3, #2 + 800e546: 58d3 ldr r3, [r2, r3] + 800e548: 0018 movs r0, r3 + 800e54a: f7f2 fb1b bl 8000b84 + /* + start address for PMA allocation: + ST's USB stack forces a BTABLE_ADDRESS at the start of PMA memory. The BTABLE occupied 8 bytes per endpoint. + we position the EP buffers starting immediately after this + */ + pma_address = 8 * MAX((sizeof(hpcd.IN_ep) / sizeof(*hpcd.IN_ep)), (sizeof(hpcd.OUT_ep) / sizeof(*hpcd.OUT_ep))); + 800e54e: 2340 movs r3, #64 ; 0x40 + 800e550: 60fb str r3, [r7, #12] + + /* PMA allocation for EP0 */ + HAL_PCDEx_PMAConfig(pdev->pData, 0x00, PCD_SNG_BUF, pma_address =+ USB_MAX_EP0_SIZE); + 800e552: 687a ldr r2, [r7, #4] + 800e554: 2387 movs r3, #135 ; 0x87 + 800e556: 009b lsls r3, r3, #2 + 800e558: 58d0 ldr r0, [r2, r3] + 800e55a: 2340 movs r3, #64 ; 0x40 + 800e55c: 60fb str r3, [r7, #12] + 800e55e: 68fb ldr r3, [r7, #12] + 800e560: 2200 movs r2, #0 + 800e562: 2100 movs r1, #0 + 800e564: f7f3 fab0 bl 8001ac8 + HAL_PCDEx_PMAConfig(pdev->pData, 0x80, PCD_SNG_BUF, pma_address =+ USB_MAX_EP0_SIZE); + 800e568: 687a ldr r2, [r7, #4] + 800e56a: 2387 movs r3, #135 ; 0x87 + 800e56c: 009b lsls r3, r3, #2 + 800e56e: 58d0 ldr r0, [r2, r3] + 800e570: 2340 movs r3, #64 ; 0x40 + 800e572: 60fb str r3, [r7, #12] + 800e574: 68fb ldr r3, [r7, #12] + 800e576: 2200 movs r2, #0 + 800e578: 2180 movs r1, #128 ; 0x80 + 800e57a: f7f3 faa5 bl 8001ac8 + + /* PMA allocation for other endpoints */ + USBD_ECM_PMAConfig(pdev->pData, &pma_address); + 800e57e: 687a ldr r2, [r7, #4] + 800e580: 2387 movs r3, #135 ; 0x87 + 800e582: 009b lsls r3, r3, #2 + 800e584: 58d3 ldr r3, [r2, r3] + 800e586: 220c movs r2, #12 + 800e588: 18ba adds r2, r7, r2 + 800e58a: 0011 movs r1, r2 + 800e58c: 0018 movs r0, r3 + 800e58e: f001 fa54 bl 800fa3a + + return USBD_OK; + 800e592: 2300 movs r3, #0 +} + 800e594: 0018 movs r0, r3 + 800e596: 46bd mov sp, r7 + 800e598: b004 add sp, #16 + 800e59a: bd80 pop {r7, pc} + 800e59c: 200034c4 .word 0x200034c4 + 800e5a0: 40005c00 .word 0x40005c00 + +0800e5a4 : + * @brief Starts the Low Level portion of the Device driver. + * @param pdev: Device handle + * @retval USBD Status + */ +USBD_StatusTypeDef USBD_LL_Start(USBD_HandleTypeDef *pdev) +{ + 800e5a4: b580 push {r7, lr} + 800e5a6: b082 sub sp, #8 + 800e5a8: af00 add r7, sp, #0 + 800e5aa: 6078 str r0, [r7, #4] + HAL_PCD_Start(pdev->pData); + 800e5ac: 687a ldr r2, [r7, #4] + 800e5ae: 2387 movs r3, #135 ; 0x87 + 800e5b0: 009b lsls r3, r3, #2 + 800e5b2: 58d3 ldr r3, [r2, r3] + 800e5b4: 0018 movs r0, r3 + 800e5b6: f7f2 fbc9 bl 8000d4c + return USBD_OK; + 800e5ba: 2300 movs r3, #0 +} + 800e5bc: 0018 movs r0, r3 + 800e5be: 46bd mov sp, r7 + 800e5c0: b002 add sp, #8 + 800e5c2: bd80 pop {r7, pc} + +0800e5c4 : + */ +USBD_StatusTypeDef USBD_LL_OpenEP(USBD_HandleTypeDef *pdev, + uint8_t ep_addr, + uint8_t ep_type, + uint16_t ep_mps) +{ + 800e5c4: b590 push {r4, r7, lr} + 800e5c6: b083 sub sp, #12 + 800e5c8: af00 add r7, sp, #0 + 800e5ca: 6078 str r0, [r7, #4] + 800e5cc: 000c movs r4, r1 + 800e5ce: 0010 movs r0, r2 + 800e5d0: 0019 movs r1, r3 + 800e5d2: 1cfb adds r3, r7, #3 + 800e5d4: 1c22 adds r2, r4, #0 + 800e5d6: 701a strb r2, [r3, #0] + 800e5d8: 1cbb adds r3, r7, #2 + 800e5da: 1c02 adds r2, r0, #0 + 800e5dc: 701a strb r2, [r3, #0] + 800e5de: 003b movs r3, r7 + 800e5e0: 1c0a adds r2, r1, #0 + 800e5e2: 801a strh r2, [r3, #0] + HAL_PCD_EP_Open(pdev->pData, + 800e5e4: 687a ldr r2, [r7, #4] + 800e5e6: 2387 movs r3, #135 ; 0x87 + 800e5e8: 009b lsls r3, r3, #2 + 800e5ea: 58d0 ldr r0, [r2, r3] + 800e5ec: 1cbb adds r3, r7, #2 + 800e5ee: 781c ldrb r4, [r3, #0] + 800e5f0: 003b movs r3, r7 + 800e5f2: 881a ldrh r2, [r3, #0] + 800e5f4: 1cfb adds r3, r7, #3 + 800e5f6: 7819 ldrb r1, [r3, #0] + 800e5f8: 0023 movs r3, r4 + 800e5fa: f7f2 fd80 bl 80010fe + ep_addr, + ep_mps, + ep_type); + + return USBD_OK; + 800e5fe: 2300 movs r3, #0 +} + 800e600: 0018 movs r0, r3 + 800e602: 46bd mov sp, r7 + 800e604: b003 add sp, #12 + 800e606: bd90 pop {r4, r7, pc} + +0800e608 : + * @param pdev: Device handle + * @param ep_addr: Endpoint Number + * @retval USBD Status + */ +USBD_StatusTypeDef USBD_LL_CloseEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr) +{ + 800e608: b580 push {r7, lr} + 800e60a: b082 sub sp, #8 + 800e60c: af00 add r7, sp, #0 + 800e60e: 6078 str r0, [r7, #4] + 800e610: 000a movs r2, r1 + 800e612: 1cfb adds r3, r7, #3 + 800e614: 701a strb r2, [r3, #0] + HAL_PCD_EP_Close(pdev->pData, ep_addr); + 800e616: 687a ldr r2, [r7, #4] + 800e618: 2387 movs r3, #135 ; 0x87 + 800e61a: 009b lsls r3, r3, #2 + 800e61c: 58d2 ldr r2, [r2, r3] + 800e61e: 1cfb adds r3, r7, #3 + 800e620: 781b ldrb r3, [r3, #0] + 800e622: 0019 movs r1, r3 + 800e624: 0010 movs r0, r2 + 800e626: f7f2 fddc bl 80011e2 + return USBD_OK; + 800e62a: 2300 movs r3, #0 +} + 800e62c: 0018 movs r0, r3 + 800e62e: 46bd mov sp, r7 + 800e630: b002 add sp, #8 + 800e632: bd80 pop {r7, pc} + +0800e634 : + * @param pdev: Device handle + * @param ep_addr: Endpoint Number + * @retval USBD Status + */ +USBD_StatusTypeDef USBD_LL_StallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr) +{ + 800e634: b580 push {r7, lr} + 800e636: b082 sub sp, #8 + 800e638: af00 add r7, sp, #0 + 800e63a: 6078 str r0, [r7, #4] + 800e63c: 000a movs r2, r1 + 800e63e: 1cfb adds r3, r7, #3 + 800e640: 701a strb r2, [r3, #0] + HAL_PCD_EP_SetStall(pdev->pData, ep_addr); + 800e642: 687a ldr r2, [r7, #4] + 800e644: 2387 movs r3, #135 ; 0x87 + 800e646: 009b lsls r3, r3, #2 + 800e648: 58d2 ldr r2, [r2, r3] + 800e64a: 1cfb adds r3, r7, #3 + 800e64c: 781b ldrb r3, [r3, #0] + 800e64e: 0019 movs r1, r3 + 800e650: 0010 movs r0, r2 + 800e652: f7f2 fea7 bl 80013a4 + return USBD_OK; + 800e656: 2300 movs r3, #0 +} + 800e658: 0018 movs r0, r3 + 800e65a: 46bd mov sp, r7 + 800e65c: b002 add sp, #8 + 800e65e: bd80 pop {r7, pc} + +0800e660 : + * @param pdev: Device handle + * @param ep_addr: Endpoint Number + * @retval USBD Status + */ +USBD_StatusTypeDef USBD_LL_ClearStallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr) +{ + 800e660: b580 push {r7, lr} + 800e662: b082 sub sp, #8 + 800e664: af00 add r7, sp, #0 + 800e666: 6078 str r0, [r7, #4] + 800e668: 000a movs r2, r1 + 800e66a: 1cfb adds r3, r7, #3 + 800e66c: 701a strb r2, [r3, #0] + HAL_PCD_EP_ClrStall(pdev->pData, ep_addr); + 800e66e: 687a ldr r2, [r7, #4] + 800e670: 2387 movs r3, #135 ; 0x87 + 800e672: 009b lsls r3, r3, #2 + 800e674: 58d2 ldr r2, [r2, r3] + 800e676: 1cfb adds r3, r7, #3 + 800e678: 781b ldrb r3, [r3, #0] + 800e67a: 0019 movs r1, r3 + 800e67c: 0010 movs r0, r2 + 800e67e: f7f2 fef7 bl 8001470 + return USBD_OK; + 800e682: 2300 movs r3, #0 +} + 800e684: 0018 movs r0, r3 + 800e686: 46bd mov sp, r7 + 800e688: b002 add sp, #8 + 800e68a: bd80 pop {r7, pc} + +0800e68c : + * @param pdev: Device handle + * @param ep_addr: Endpoint Number + * @retval Stall (1: Yes, 0: No) + */ +uint8_t USBD_LL_IsStallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr) +{ + 800e68c: b580 push {r7, lr} + 800e68e: b084 sub sp, #16 + 800e690: af00 add r7, sp, #0 + 800e692: 6078 str r0, [r7, #4] + 800e694: 000a movs r2, r1 + 800e696: 1cfb adds r3, r7, #3 + 800e698: 701a strb r2, [r3, #0] + PCD_HandleTypeDef *hpcd = pdev->pData; + 800e69a: 687a ldr r2, [r7, #4] + 800e69c: 2387 movs r3, #135 ; 0x87 + 800e69e: 009b lsls r3, r3, #2 + 800e6a0: 58d3 ldr r3, [r2, r3] + 800e6a2: 60fb str r3, [r7, #12] + + if((ep_addr & 0x80) == 0x80) + 800e6a4: 1cfb adds r3, r7, #3 + 800e6a6: 781b ldrb r3, [r3, #0] + 800e6a8: b25b sxtb r3, r3 + 800e6aa: 2b00 cmp r3, #0 + 800e6ac: da0a bge.n 800e6c4 + { + return hpcd->IN_ep[ep_addr & 0x7F].is_stall; + 800e6ae: 1cfb adds r3, r7, #3 + 800e6b0: 781b ldrb r3, [r3, #0] + 800e6b2: 227f movs r2, #127 ; 0x7f + 800e6b4: 4013 ands r3, r2 + 800e6b6: 68fa ldr r2, [r7, #12] + 800e6b8: 212a movs r1, #42 ; 0x2a + 800e6ba: 015b lsls r3, r3, #5 + 800e6bc: 18d3 adds r3, r2, r3 + 800e6be: 185b adds r3, r3, r1 + 800e6c0: 781b ldrb r3, [r3, #0] + 800e6c2: e00a b.n 800e6da + } + else + { + return hpcd->OUT_ep[ep_addr & 0x7F].is_stall; + 800e6c4: 1cfb adds r3, r7, #3 + 800e6c6: 781b ldrb r3, [r3, #0] + 800e6c8: 227f movs r2, #127 ; 0x7f + 800e6ca: 401a ands r2, r3 + 800e6cc: 68f9 ldr r1, [r7, #12] + 800e6ce: 2395 movs r3, #149 ; 0x95 + 800e6d0: 005b lsls r3, r3, #1 + 800e6d2: 0152 lsls r2, r2, #5 + 800e6d4: 188a adds r2, r1, r2 + 800e6d6: 18d3 adds r3, r2, r3 + 800e6d8: 781b ldrb r3, [r3, #0] + } +} + 800e6da: 0018 movs r0, r3 + 800e6dc: 46bd mov sp, r7 + 800e6de: b004 add sp, #16 + 800e6e0: bd80 pop {r7, pc} + +0800e6e2 : + * @param pdev: Device handle + * @param ep_addr: Endpoint Number + * @retval USBD Status + */ +USBD_StatusTypeDef USBD_LL_SetUSBAddress(USBD_HandleTypeDef *pdev, uint8_t dev_addr) +{ + 800e6e2: b580 push {r7, lr} + 800e6e4: b082 sub sp, #8 + 800e6e6: af00 add r7, sp, #0 + 800e6e8: 6078 str r0, [r7, #4] + 800e6ea: 000a movs r2, r1 + 800e6ec: 1cfb adds r3, r7, #3 + 800e6ee: 701a strb r2, [r3, #0] + HAL_PCD_SetAddress(pdev->pData, dev_addr); + 800e6f0: 687a ldr r2, [r7, #4] + 800e6f2: 2387 movs r3, #135 ; 0x87 + 800e6f4: 009b lsls r3, r3, #2 + 800e6f6: 58d2 ldr r2, [r2, r3] + 800e6f8: 1cfb adds r3, r7, #3 + 800e6fa: 781b ldrb r3, [r3, #0] + 800e6fc: 0019 movs r1, r3 + 800e6fe: 0010 movs r0, r2 + 800e700: f7f2 fcd2 bl 80010a8 + return USBD_OK; + 800e704: 2300 movs r3, #0 +} + 800e706: 0018 movs r0, r3 + 800e708: 46bd mov sp, r7 + 800e70a: b002 add sp, #8 + 800e70c: bd80 pop {r7, pc} + +0800e70e : + */ +USBD_StatusTypeDef USBD_LL_Transmit(USBD_HandleTypeDef *pdev, + uint8_t ep_addr, + uint8_t *pbuf, + uint16_t size) +{ + 800e70e: b5f0 push {r4, r5, r6, r7, lr} + 800e710: b087 sub sp, #28 + 800e712: af00 add r7, sp, #0 + 800e714: 60f8 str r0, [r7, #12] + 800e716: 0008 movs r0, r1 + 800e718: 607a str r2, [r7, #4] + 800e71a: 0019 movs r1, r3 + 800e71c: 260b movs r6, #11 + 800e71e: 19bb adds r3, r7, r6 + 800e720: 1c02 adds r2, r0, #0 + 800e722: 701a strb r2, [r3, #0] + 800e724: 2408 movs r4, #8 + 800e726: 193b adds r3, r7, r4 + 800e728: 1c0a adds r2, r1, #0 + 800e72a: 801a strh r2, [r3, #0] + HAL_StatusTypeDef outcome; + outcome = HAL_PCD_EP_Transmit(pdev->pData, ep_addr, pbuf, size); + 800e72c: 68fa ldr r2, [r7, #12] + 800e72e: 2387 movs r3, #135 ; 0x87 + 800e730: 009b lsls r3, r3, #2 + 800e732: 58d0 ldr r0, [r2, r3] + 800e734: 193b adds r3, r7, r4 + 800e736: 881d ldrh r5, [r3, #0] + 800e738: 2317 movs r3, #23 + 800e73a: 18fc adds r4, r7, r3 + 800e73c: 687a ldr r2, [r7, #4] + 800e73e: 19bb adds r3, r7, r6 + 800e740: 7819 ldrb r1, [r3, #0] + 800e742: 002b movs r3, r5 + 800e744: f7f2 fdee bl 8001324 + 800e748: 0003 movs r3, r0 + 800e74a: 7023 strb r3, [r4, #0] + return (HAL_OK == outcome) ? USBD_OK : USBD_BUSY; + 800e74c: 2317 movs r3, #23 + 800e74e: 18fb adds r3, r7, r3 + 800e750: 781b ldrb r3, [r3, #0] + 800e752: 1e5a subs r2, r3, #1 + 800e754: 4193 sbcs r3, r2 + 800e756: b2db uxtb r3, r3 +} + 800e758: 0018 movs r0, r3 + 800e75a: 46bd mov sp, r7 + 800e75c: b007 add sp, #28 + 800e75e: bdf0 pop {r4, r5, r6, r7, pc} + +0800e760 : + */ +USBD_StatusTypeDef USBD_LL_PrepareReceive(USBD_HandleTypeDef *pdev, + uint8_t ep_addr, + uint8_t *pbuf, + uint16_t size) +{ + 800e760: b5f0 push {r4, r5, r6, r7, lr} + 800e762: b087 sub sp, #28 + 800e764: af00 add r7, sp, #0 + 800e766: 60f8 str r0, [r7, #12] + 800e768: 0008 movs r0, r1 + 800e76a: 607a str r2, [r7, #4] + 800e76c: 0019 movs r1, r3 + 800e76e: 260b movs r6, #11 + 800e770: 19bb adds r3, r7, r6 + 800e772: 1c02 adds r2, r0, #0 + 800e774: 701a strb r2, [r3, #0] + 800e776: 2408 movs r4, #8 + 800e778: 193b adds r3, r7, r4 + 800e77a: 1c0a adds r2, r1, #0 + 800e77c: 801a strh r2, [r3, #0] + HAL_StatusTypeDef outcome; + outcome = HAL_PCD_EP_Receive(pdev->pData, ep_addr, pbuf, size); + 800e77e: 68fa ldr r2, [r7, #12] + 800e780: 2387 movs r3, #135 ; 0x87 + 800e782: 009b lsls r3, r3, #2 + 800e784: 58d0 ldr r0, [r2, r3] + 800e786: 193b adds r3, r7, r4 + 800e788: 881d ldrh r5, [r3, #0] + 800e78a: 2317 movs r3, #23 + 800e78c: 18fc adds r4, r7, r3 + 800e78e: 687a ldr r2, [r7, #4] + 800e790: 19bb adds r3, r7, r6 + 800e792: 7819 ldrb r1, [r3, #0] + 800e794: 002b movs r3, r5 + 800e796: f7f2 fd6f bl 8001278 + 800e79a: 0003 movs r3, r0 + 800e79c: 7023 strb r3, [r4, #0] + return (HAL_OK == outcome) ? USBD_OK : USBD_BUSY; + 800e79e: 2317 movs r3, #23 + 800e7a0: 18fb adds r3, r7, r3 + 800e7a2: 781b ldrb r3, [r3, #0] + 800e7a4: 1e5a subs r2, r3, #1 + 800e7a6: 4193 sbcs r3, r2 + 800e7a8: b2db uxtb r3, r3 +} + 800e7aa: 0018 movs r0, r3 + 800e7ac: 46bd mov sp, r7 + 800e7ae: b007 add sp, #28 + 800e7b0: bdf0 pop {r4, r5, r6, r7, pc} + +0800e7b2 : + * @param pdev: Device handle + * @param ep_addr: Endpoint Number + * @retval Recived Data Size + */ +uint32_t USBD_LL_GetRxDataSize(USBD_HandleTypeDef *pdev, uint8_t ep_addr) +{ + 800e7b2: b580 push {r7, lr} + 800e7b4: b082 sub sp, #8 + 800e7b6: af00 add r7, sp, #0 + 800e7b8: 6078 str r0, [r7, #4] + 800e7ba: 000a movs r2, r1 + 800e7bc: 1cfb adds r3, r7, #3 + 800e7be: 701a strb r2, [r3, #0] + return HAL_PCD_EP_GetRxCount(pdev->pData, ep_addr); + 800e7c0: 687a ldr r2, [r7, #4] + 800e7c2: 2387 movs r3, #135 ; 0x87 + 800e7c4: 009b lsls r3, r3, #2 + 800e7c6: 58d2 ldr r2, [r2, r3] + 800e7c8: 1cfb adds r3, r7, #3 + 800e7ca: 781b ldrb r3, [r3, #0] + 800e7cc: 0019 movs r1, r3 + 800e7ce: 0010 movs r0, r2 + 800e7d0: f7f2 fd93 bl 80012fa + 800e7d4: 0003 movs r3, r0 +} + 800e7d6: 0018 movs r0, r3 + 800e7d8: 46bd mov sp, r7 + 800e7da: b002 add sp, #8 + 800e7dc: bd80 pop {r7, pc} + +0800e7de : +* @param pdesc: Descriptor structure address +* @param id: Low level core index +* @retval None +*/ +USBD_StatusTypeDef USBD_Init(USBD_HandleTypeDef *pdev, const USBD_DescriptorsTypeDef *pdesc, uint8_t id) +{ + 800e7de: b580 push {r7, lr} + 800e7e0: b084 sub sp, #16 + 800e7e2: af00 add r7, sp, #0 + 800e7e4: 60f8 str r0, [r7, #12] + 800e7e6: 60b9 str r1, [r7, #8] + 800e7e8: 1dfb adds r3, r7, #7 + 800e7ea: 701a strb r2, [r3, #0] + /* Check whether the USB Host handle is valid */ + if(pdev == NULL) + 800e7ec: 68fb ldr r3, [r7, #12] + 800e7ee: 2b00 cmp r3, #0 + 800e7f0: d101 bne.n 800e7f6 + { + USBD_ErrLog("Invalid Device handle"); + return USBD_FAIL; + 800e7f2: 2302 movs r3, #2 + 800e7f4: e020 b.n 800e838 + } + + /* Unlink previous class*/ + if(pdev->pClass != NULL) + 800e7f6: 68fa ldr r2, [r7, #12] + 800e7f8: 2384 movs r3, #132 ; 0x84 + 800e7fa: 009b lsls r3, r3, #2 + 800e7fc: 58d3 ldr r3, [r2, r3] + 800e7fe: 2b00 cmp r3, #0 + 800e800: d004 beq.n 800e80c + { + pdev->pClass = NULL; + 800e802: 68fa ldr r2, [r7, #12] + 800e804: 2384 movs r3, #132 ; 0x84 + 800e806: 009b lsls r3, r3, #2 + 800e808: 2100 movs r1, #0 + 800e80a: 50d1 str r1, [r2, r3] + } + + /* Assign USBD Descriptors */ + if(pdesc != NULL) + 800e80c: 68bb ldr r3, [r7, #8] + 800e80e: 2b00 cmp r3, #0 + 800e810: d004 beq.n 800e81c + { + pdev->pDesc = pdesc; + 800e812: 68fa ldr r2, [r7, #12] + 800e814: 2383 movs r3, #131 ; 0x83 + 800e816: 009b lsls r3, r3, #2 + 800e818: 68b9 ldr r1, [r7, #8] + 800e81a: 50d1 str r1, [r2, r3] + } + + /* Set Device initial State */ + pdev->dev_state = USBD_STATE_DEFAULT; + 800e81c: 68fa ldr r2, [r7, #12] + 800e81e: 23fe movs r3, #254 ; 0xfe + 800e820: 005b lsls r3, r3, #1 + 800e822: 2101 movs r1, #1 + 800e824: 54d1 strb r1, [r2, r3] + pdev->id = id; + 800e826: 68fb ldr r3, [r7, #12] + 800e828: 1dfa adds r2, r7, #7 + 800e82a: 7812 ldrb r2, [r2, #0] + 800e82c: 701a strb r2, [r3, #0] + /* Initialize low level driver */ + USBD_LL_Init(pdev); + 800e82e: 68fb ldr r3, [r7, #12] + 800e830: 0018 movs r0, r3 + 800e832: f7ff fe6b bl 800e50c + + return USBD_OK; + 800e836: 2300 movs r3, #0 +} + 800e838: 0018 movs r0, r3 + 800e83a: 46bd mov sp, r7 + 800e83c: b004 add sp, #16 + 800e83e: bd80 pop {r7, pc} + +0800e840 : + * @param pDevice : Device Handle + * @param pclass: Class handle + * @retval USBD Status + */ +USBD_StatusTypeDef USBD_RegisterClass(USBD_HandleTypeDef *pdev, const USBD_ClassTypeDef *pclass) +{ + 800e840: b580 push {r7, lr} + 800e842: b084 sub sp, #16 + 800e844: af00 add r7, sp, #0 + 800e846: 6078 str r0, [r7, #4] + 800e848: 6039 str r1, [r7, #0] + USBD_StatusTypeDef status = USBD_OK; + 800e84a: 230f movs r3, #15 + 800e84c: 18fb adds r3, r7, r3 + 800e84e: 2200 movs r2, #0 + 800e850: 701a strb r2, [r3, #0] + if(pclass != 0) + 800e852: 683b ldr r3, [r7, #0] + 800e854: 2b00 cmp r3, #0 + 800e856: d009 beq.n 800e86c + { + /* link the class to the USB Device handle */ + pdev->pClass = pclass; + 800e858: 687a ldr r2, [r7, #4] + 800e85a: 2384 movs r3, #132 ; 0x84 + 800e85c: 009b lsls r3, r3, #2 + 800e85e: 6839 ldr r1, [r7, #0] + 800e860: 50d1 str r1, [r2, r3] + status = USBD_OK; + 800e862: 230f movs r3, #15 + 800e864: 18fb adds r3, r7, r3 + 800e866: 2200 movs r2, #0 + 800e868: 701a strb r2, [r3, #0] + 800e86a: e003 b.n 800e874 + } + else + { + USBD_ErrLog("Invalid Class handle"); + status = USBD_FAIL; + 800e86c: 230f movs r3, #15 + 800e86e: 18fb adds r3, r7, r3 + 800e870: 2202 movs r2, #2 + 800e872: 701a strb r2, [r3, #0] + } + + return status; + 800e874: 230f movs r3, #15 + 800e876: 18fb adds r3, r7, r3 + 800e878: 781b ldrb r3, [r3, #0] +} + 800e87a: 0018 movs r0, r3 + 800e87c: 46bd mov sp, r7 + 800e87e: b004 add sp, #16 + 800e880: bd80 pop {r7, pc} + +0800e882 : + * Start the USB Device Core. + * @param pdev: Device Handle + * @retval USBD Status + */ +USBD_StatusTypeDef USBD_Start (USBD_HandleTypeDef *pdev) +{ + 800e882: b580 push {r7, lr} + 800e884: b082 sub sp, #8 + 800e886: af00 add r7, sp, #0 + 800e888: 6078 str r0, [r7, #4] + + /* Start the low level driver */ + USBD_LL_Start(pdev); + 800e88a: 687b ldr r3, [r7, #4] + 800e88c: 0018 movs r0, r3 + 800e88e: f7ff fe89 bl 800e5a4 + + return USBD_OK; + 800e892: 2300 movs r3, #0 +} + 800e894: 0018 movs r0, r3 + 800e896: 46bd mov sp, r7 + 800e898: b002 add sp, #8 + 800e89a: bd80 pop {r7, pc} + +0800e89c : +* @param cfgidx: configuration index +* @retval status +*/ + +USBD_StatusTypeDef USBD_SetClassConfig(USBD_HandleTypeDef *pdev, uint8_t cfgidx) +{ + 800e89c: b580 push {r7, lr} + 800e89e: b084 sub sp, #16 + 800e8a0: af00 add r7, sp, #0 + 800e8a2: 6078 str r0, [r7, #4] + 800e8a4: 000a movs r2, r1 + 800e8a6: 1cfb adds r3, r7, #3 + 800e8a8: 701a strb r2, [r3, #0] + USBD_StatusTypeDef ret = USBD_FAIL; + 800e8aa: 230f movs r3, #15 + 800e8ac: 18fb adds r3, r7, r3 + 800e8ae: 2202 movs r2, #2 + 800e8b0: 701a strb r2, [r3, #0] + + if(pdev->pClass != NULL) + 800e8b2: 687a ldr r2, [r7, #4] + 800e8b4: 2384 movs r3, #132 ; 0x84 + 800e8b6: 009b lsls r3, r3, #2 + 800e8b8: 58d3 ldr r3, [r2, r3] + 800e8ba: 2b00 cmp r3, #0 + 800e8bc: d00f beq.n 800e8de + { + /* Set configuration and Start the Class*/ + if(pdev->pClass->Init(pdev, cfgidx) == 0) + 800e8be: 687a ldr r2, [r7, #4] + 800e8c0: 2384 movs r3, #132 ; 0x84 + 800e8c2: 009b lsls r3, r3, #2 + 800e8c4: 58d3 ldr r3, [r2, r3] + 800e8c6: 681b ldr r3, [r3, #0] + 800e8c8: 1cfa adds r2, r7, #3 + 800e8ca: 7811 ldrb r1, [r2, #0] + 800e8cc: 687a ldr r2, [r7, #4] + 800e8ce: 0010 movs r0, r2 + 800e8d0: 4798 blx r3 + 800e8d2: 1e03 subs r3, r0, #0 + 800e8d4: d103 bne.n 800e8de + { + ret = USBD_OK; + 800e8d6: 230f movs r3, #15 + 800e8d8: 18fb adds r3, r7, r3 + 800e8da: 2200 movs r2, #0 + 800e8dc: 701a strb r2, [r3, #0] + } + } + return ret; + 800e8de: 230f movs r3, #15 + 800e8e0: 18fb adds r3, r7, r3 + 800e8e2: 781b ldrb r3, [r3, #0] +} + 800e8e4: 0018 movs r0, r3 + 800e8e6: 46bd mov sp, r7 + 800e8e8: b004 add sp, #16 + 800e8ea: bd80 pop {r7, pc} + +0800e8ec : +* @param pdev: device instance +* @param cfgidx: configuration index +* @retval status: USBD_StatusTypeDef +*/ +USBD_StatusTypeDef USBD_ClrClassConfig(USBD_HandleTypeDef *pdev, uint8_t cfgidx) +{ + 800e8ec: b580 push {r7, lr} + 800e8ee: b082 sub sp, #8 + 800e8f0: af00 add r7, sp, #0 + 800e8f2: 6078 str r0, [r7, #4] + 800e8f4: 000a movs r2, r1 + 800e8f6: 1cfb adds r3, r7, #3 + 800e8f8: 701a strb r2, [r3, #0] + /* Clear configuration and De-initialize the Class process*/ + pdev->pClass->DeInit(pdev, cfgidx); + 800e8fa: 687a ldr r2, [r7, #4] + 800e8fc: 2384 movs r3, #132 ; 0x84 + 800e8fe: 009b lsls r3, r3, #2 + 800e900: 58d3 ldr r3, [r2, r3] + 800e902: 685b ldr r3, [r3, #4] + 800e904: 1cfa adds r2, r7, #3 + 800e906: 7811 ldrb r1, [r2, #0] + 800e908: 687a ldr r2, [r7, #4] + 800e90a: 0010 movs r0, r2 + 800e90c: 4798 blx r3 + return USBD_OK; + 800e90e: 2300 movs r3, #0 +} + 800e910: 0018 movs r0, r3 + 800e912: 46bd mov sp, r7 + 800e914: b002 add sp, #8 + 800e916: bd80 pop {r7, pc} + +0800e918 : +* Handle the setup stage +* @param pdev: device instance +* @retval status +*/ +USBD_StatusTypeDef USBD_LL_SetupStage(USBD_HandleTypeDef *pdev, uint8_t *psetup) +{ + 800e918: b580 push {r7, lr} + 800e91a: b082 sub sp, #8 + 800e91c: af00 add r7, sp, #0 + 800e91e: 6078 str r0, [r7, #4] + 800e920: 6039 str r1, [r7, #0] + + USBD_ParseSetupRequest(&pdev->request, psetup); + 800e922: 687b ldr r3, [r7, #4] + 800e924: 2281 movs r2, #129 ; 0x81 + 800e926: 0092 lsls r2, r2, #2 + 800e928: 4694 mov ip, r2 + 800e92a: 4463 add r3, ip + 800e92c: 683a ldr r2, [r7, #0] + 800e92e: 0011 movs r1, r2 + 800e930: 0018 movs r0, r3 + 800e932: f000 fd76 bl 800f422 + + pdev->ep0_state = USBD_EP0_SETUP; + 800e936: 687a ldr r2, [r7, #4] + 800e938: 23fa movs r3, #250 ; 0xfa + 800e93a: 005b lsls r3, r3, #1 + 800e93c: 2101 movs r1, #1 + 800e93e: 50d1 str r1, [r2, r3] + pdev->ep0_data_len = pdev->request.wLength; + 800e940: 687b ldr r3, [r7, #4] + 800e942: 4a22 ldr r2, [pc, #136] ; (800e9cc ) + 800e944: 5a9b ldrh r3, [r3, r2] + 800e946: 0019 movs r1, r3 + 800e948: 687a ldr r2, [r7, #4] + 800e94a: 23fc movs r3, #252 ; 0xfc + 800e94c: 005b lsls r3, r3, #1 + 800e94e: 50d1 str r1, [r2, r3] + + switch (pdev->request.bmRequest & 0x1F) + 800e950: 687a ldr r2, [r7, #4] + 800e952: 2381 movs r3, #129 ; 0x81 + 800e954: 009b lsls r3, r3, #2 + 800e956: 5cd3 ldrb r3, [r2, r3] + 800e958: 001a movs r2, r3 + 800e95a: 231f movs r3, #31 + 800e95c: 4013 ands r3, r2 + 800e95e: 2b01 cmp r3, #1 + 800e960: d00d beq.n 800e97e + 800e962: 2b02 cmp r3, #2 + 800e964: d015 beq.n 800e992 + 800e966: 2b00 cmp r3, #0 + 800e968: d11d bne.n 800e9a6 + { + case USB_REQ_RECIPIENT_DEVICE: + USBD_StdDevReq (pdev, &pdev->request); + 800e96a: 687b ldr r3, [r7, #4] + 800e96c: 2281 movs r2, #129 ; 0x81 + 800e96e: 0092 lsls r2, r2, #2 + 800e970: 189a adds r2, r3, r2 + 800e972: 687b ldr r3, [r7, #4] + 800e974: 0011 movs r1, r2 + 800e976: 0018 movs r0, r3 + 800e978: f000 f97c bl 800ec74 + break; + 800e97c: e020 b.n 800e9c0 + + case USB_REQ_RECIPIENT_INTERFACE: + USBD_StdItfReq(pdev, &pdev->request); + 800e97e: 687b ldr r3, [r7, #4] + 800e980: 2281 movs r2, #129 ; 0x81 + 800e982: 0092 lsls r2, r2, #2 + 800e984: 189a adds r2, r3, r2 + 800e986: 687b ldr r3, [r7, #4] + 800e988: 0011 movs r1, r2 + 800e98a: 0018 movs r0, r3 + 800e98c: f000 f9c6 bl 800ed1c + break; + 800e990: e016 b.n 800e9c0 + + case USB_REQ_RECIPIENT_ENDPOINT: + USBD_StdEPReq(pdev, &pdev->request); + 800e992: 687b ldr r3, [r7, #4] + 800e994: 2281 movs r2, #129 ; 0x81 + 800e996: 0092 lsls r2, r2, #2 + 800e998: 189a adds r2, r3, r2 + 800e99a: 687b ldr r3, [r7, #4] + 800e99c: 0011 movs r1, r2 + 800e99e: 0018 movs r0, r3 + 800e9a0: f000 f9fb bl 800ed9a + break; + 800e9a4: e00c b.n 800e9c0 + + default: + USBD_LL_StallEP(pdev , pdev->request.bmRequest & 0x80); + 800e9a6: 687a ldr r2, [r7, #4] + 800e9a8: 2381 movs r3, #129 ; 0x81 + 800e9aa: 009b lsls r3, r3, #2 + 800e9ac: 5cd3 ldrb r3, [r2, r3] + 800e9ae: 227f movs r2, #127 ; 0x7f + 800e9b0: 4393 bics r3, r2 + 800e9b2: b2da uxtb r2, r3 + 800e9b4: 687b ldr r3, [r7, #4] + 800e9b6: 0011 movs r1, r2 + 800e9b8: 0018 movs r0, r3 + 800e9ba: f7ff fe3b bl 800e634 + break; + 800e9be: 46c0 nop ; (mov r8, r8) + } + return USBD_OK; + 800e9c0: 2300 movs r3, #0 +} + 800e9c2: 0018 movs r0, r3 + 800e9c4: 46bd mov sp, r7 + 800e9c6: b002 add sp, #8 + 800e9c8: bd80 pop {r7, pc} + 800e9ca: 46c0 nop ; (mov r8, r8) + 800e9cc: 0000020a .word 0x0000020a + +0800e9d0 : +* @param pdev: device instance +* @param epnum: endpoint index +* @retval status +*/ +USBD_StatusTypeDef USBD_LL_DataOutStage(USBD_HandleTypeDef *pdev , uint8_t epnum, uint8_t *pdata) +{ + 800e9d0: b580 push {r7, lr} + 800e9d2: b086 sub sp, #24 + 800e9d4: af00 add r7, sp, #0 + 800e9d6: 60f8 str r0, [r7, #12] + 800e9d8: 607a str r2, [r7, #4] + 800e9da: 200b movs r0, #11 + 800e9dc: 183b adds r3, r7, r0 + 800e9de: 1c0a adds r2, r1, #0 + 800e9e0: 701a strb r2, [r3, #0] + USBD_EndpointTypeDef *pep; + + if(epnum == 0) + 800e9e2: 183b adds r3, r7, r0 + 800e9e4: 781b ldrb r3, [r3, #0] + 800e9e6: 2b00 cmp r3, #0 + 800e9e8: d13e bne.n 800ea68 + { + pep = &pdev->ep_out[0]; + 800e9ea: 68fb ldr r3, [r7, #12] + 800e9ec: 3305 adds r3, #5 + 800e9ee: 33ff adds r3, #255 ; 0xff + 800e9f0: 617b str r3, [r7, #20] + + if ( pdev->ep0_state == USBD_EP0_DATA_OUT) + 800e9f2: 68fa ldr r2, [r7, #12] + 800e9f4: 23fa movs r3, #250 ; 0xfa + 800e9f6: 005b lsls r3, r3, #1 + 800e9f8: 58d3 ldr r3, [r2, r3] + 800e9fa: 2b03 cmp r3, #3 + 800e9fc: d14c bne.n 800ea98 + { + if(pep->rem_length > pep->maxpacket) + 800e9fe: 697b ldr r3, [r7, #20] + 800ea00: 689a ldr r2, [r3, #8] + 800ea02: 697b ldr r3, [r7, #20] + 800ea04: 68db ldr r3, [r3, #12] + 800ea06: 429a cmp r2, r3 + 800ea08: d914 bls.n 800ea34 + { + pep->rem_length -= pep->maxpacket; + 800ea0a: 697b ldr r3, [r7, #20] + 800ea0c: 689a ldr r2, [r3, #8] + 800ea0e: 697b ldr r3, [r7, #20] + 800ea10: 68db ldr r3, [r3, #12] + 800ea12: 1ad2 subs r2, r2, r3 + 800ea14: 697b ldr r3, [r7, #20] + 800ea16: 609a str r2, [r3, #8] + + USBD_CtlContinueRx (pdev, + pdata, + MIN(pep->rem_length ,pep->maxpacket)); + 800ea18: 697b ldr r3, [r7, #20] + 800ea1a: 68da ldr r2, [r3, #12] + 800ea1c: 697b ldr r3, [r7, #20] + 800ea1e: 689b ldr r3, [r3, #8] + 800ea20: 429a cmp r2, r3 + 800ea22: d900 bls.n 800ea26 + 800ea24: 001a movs r2, r3 + USBD_CtlContinueRx (pdev, + 800ea26: b292 uxth r2, r2 + 800ea28: 6879 ldr r1, [r7, #4] + 800ea2a: 68fb ldr r3, [r7, #12] + 800ea2c: 0018 movs r0, r3 + 800ea2e: f001 f8ca bl 800fbc6 + 800ea32: e031 b.n 800ea98 + } + else + { + if((pdev->pClass->EP0_RxReady != NULL)&& + 800ea34: 68fa ldr r2, [r7, #12] + 800ea36: 2384 movs r3, #132 ; 0x84 + 800ea38: 009b lsls r3, r3, #2 + 800ea3a: 58d3 ldr r3, [r2, r3] + 800ea3c: 691b ldr r3, [r3, #16] + 800ea3e: 2b00 cmp r3, #0 + 800ea40: d00d beq.n 800ea5e + (pdev->dev_state == USBD_STATE_CONFIGURED)) + 800ea42: 68fa ldr r2, [r7, #12] + 800ea44: 23fe movs r3, #254 ; 0xfe + 800ea46: 005b lsls r3, r3, #1 + 800ea48: 5cd3 ldrb r3, [r2, r3] + if((pdev->pClass->EP0_RxReady != NULL)&& + 800ea4a: 2b03 cmp r3, #3 + 800ea4c: d107 bne.n 800ea5e + { + pdev->pClass->EP0_RxReady(pdev); + 800ea4e: 68fa ldr r2, [r7, #12] + 800ea50: 2384 movs r3, #132 ; 0x84 + 800ea52: 009b lsls r3, r3, #2 + 800ea54: 58d3 ldr r3, [r2, r3] + 800ea56: 691b ldr r3, [r3, #16] + 800ea58: 68fa ldr r2, [r7, #12] + 800ea5a: 0010 movs r0, r2 + 800ea5c: 4798 blx r3 + } + USBD_CtlSendStatus(pdev); + 800ea5e: 68fb ldr r3, [r7, #12] + 800ea60: 0018 movs r0, r3 + 800ea62: f001 f8c3 bl 800fbec + 800ea66: e017 b.n 800ea98 + } + } + } + else if((pdev->pClass->DataOut != NULL)&& + 800ea68: 68fa ldr r2, [r7, #12] + 800ea6a: 2384 movs r3, #132 ; 0x84 + 800ea6c: 009b lsls r3, r3, #2 + 800ea6e: 58d3 ldr r3, [r2, r3] + 800ea70: 699b ldr r3, [r3, #24] + 800ea72: 2b00 cmp r3, #0 + 800ea74: d010 beq.n 800ea98 + (pdev->dev_state == USBD_STATE_CONFIGURED)) + 800ea76: 68fa ldr r2, [r7, #12] + 800ea78: 23fe movs r3, #254 ; 0xfe + 800ea7a: 005b lsls r3, r3, #1 + 800ea7c: 5cd3 ldrb r3, [r2, r3] + else if((pdev->pClass->DataOut != NULL)&& + 800ea7e: 2b03 cmp r3, #3 + 800ea80: d10a bne.n 800ea98 + { + pdev->pClass->DataOut(pdev, epnum); + 800ea82: 68fa ldr r2, [r7, #12] + 800ea84: 2384 movs r3, #132 ; 0x84 + 800ea86: 009b lsls r3, r3, #2 + 800ea88: 58d3 ldr r3, [r2, r3] + 800ea8a: 699b ldr r3, [r3, #24] + 800ea8c: 220b movs r2, #11 + 800ea8e: 18ba adds r2, r7, r2 + 800ea90: 7811 ldrb r1, [r2, #0] + 800ea92: 68fa ldr r2, [r7, #12] + 800ea94: 0010 movs r0, r2 + 800ea96: 4798 blx r3 + } + return USBD_OK; + 800ea98: 2300 movs r3, #0 +} + 800ea9a: 0018 movs r0, r3 + 800ea9c: 46bd mov sp, r7 + 800ea9e: b006 add sp, #24 + 800eaa0: bd80 pop {r7, pc} + +0800eaa2 : +* @param pdev: device instance +* @param epnum: endpoint index +* @retval status +*/ +USBD_StatusTypeDef USBD_LL_DataInStage(USBD_HandleTypeDef *pdev ,uint8_t epnum, uint8_t *pdata) +{ + 800eaa2: b580 push {r7, lr} + 800eaa4: b086 sub sp, #24 + 800eaa6: af00 add r7, sp, #0 + 800eaa8: 60f8 str r0, [r7, #12] + 800eaaa: 607a str r2, [r7, #4] + 800eaac: 200b movs r0, #11 + 800eaae: 183b adds r3, r7, r0 + 800eab0: 1c0a adds r2, r1, #0 + 800eab2: 701a strb r2, [r3, #0] + USBD_EndpointTypeDef *pep; + + if(epnum == 0) + 800eab4: 183b adds r3, r7, r0 + 800eab6: 781b ldrb r3, [r3, #0] + 800eab8: 2b00 cmp r3, #0 + 800eaba: d15c bne.n 800eb76 + { + pep = &pdev->ep_in[0]; + 800eabc: 68fb ldr r3, [r7, #12] + 800eabe: 3314 adds r3, #20 + 800eac0: 617b str r3, [r7, #20] + + if ( pdev->ep0_state == USBD_EP0_DATA_IN) + 800eac2: 68fa ldr r2, [r7, #12] + 800eac4: 23fa movs r3, #250 ; 0xfa + 800eac6: 005b lsls r3, r3, #1 + 800eac8: 58d3 ldr r3, [r2, r3] + 800eaca: 2b02 cmp r3, #2 + 800eacc: d16b bne.n 800eba6 + { + if(pep->rem_length > pep->maxpacket) + 800eace: 697b ldr r3, [r7, #20] + 800ead0: 689a ldr r2, [r3, #8] + 800ead2: 697b ldr r3, [r7, #20] + 800ead4: 68db ldr r3, [r3, #12] + 800ead6: 429a cmp r2, r3 + 800ead8: d90f bls.n 800eafa + { + pep->rem_length -= pep->maxpacket; + 800eada: 697b ldr r3, [r7, #20] + 800eadc: 689a ldr r2, [r3, #8] + 800eade: 697b ldr r3, [r7, #20] + 800eae0: 68db ldr r3, [r3, #12] + 800eae2: 1ad2 subs r2, r2, r3 + 800eae4: 697b ldr r3, [r7, #20] + 800eae6: 609a str r2, [r3, #8] + + USBD_CtlContinueSendData (pdev, + pdata, + pep->rem_length); + 800eae8: 697b ldr r3, [r7, #20] + 800eaea: 689b ldr r3, [r3, #8] + USBD_CtlContinueSendData (pdev, + 800eaec: b29a uxth r2, r3 + 800eaee: 6879 ldr r1, [r7, #4] + 800eaf0: 68fb ldr r3, [r7, #12] + 800eaf2: 0018 movs r0, r3 + 800eaf4: f001 f854 bl 800fba0 + 800eaf8: e055 b.n 800eba6 + } + else + { /* last packet is MPS multiple, so send ZLP packet */ + if((pep->total_length % pep->maxpacket == 0) && + 800eafa: 697b ldr r3, [r7, #20] + 800eafc: 685a ldr r2, [r3, #4] + 800eafe: 697b ldr r3, [r7, #20] + 800eb00: 68db ldr r3, [r3, #12] + 800eb02: 0019 movs r1, r3 + 800eb04: 0010 movs r0, r2 + 800eb06: f7f1 fb97 bl 8000238 <__aeabi_uidivmod> + 800eb0a: 1e0b subs r3, r1, #0 + 800eb0c: d119 bne.n 800eb42 + (pep->total_length >= pep->maxpacket) && + 800eb0e: 697b ldr r3, [r7, #20] + 800eb10: 685a ldr r2, [r3, #4] + 800eb12: 697b ldr r3, [r7, #20] + 800eb14: 68db ldr r3, [r3, #12] + if((pep->total_length % pep->maxpacket == 0) && + 800eb16: 429a cmp r2, r3 + 800eb18: d313 bcc.n 800eb42 + (pep->total_length < pdev->ep0_data_len )) + 800eb1a: 697b ldr r3, [r7, #20] + 800eb1c: 685a ldr r2, [r3, #4] + 800eb1e: 68f9 ldr r1, [r7, #12] + 800eb20: 23fc movs r3, #252 ; 0xfc + 800eb22: 005b lsls r3, r3, #1 + 800eb24: 58cb ldr r3, [r1, r3] + (pep->total_length >= pep->maxpacket) && + 800eb26: 429a cmp r2, r3 + 800eb28: d20b bcs.n 800eb42 + { + + USBD_CtlContinueSendData(pdev , NULL, 0); + 800eb2a: 68fb ldr r3, [r7, #12] + 800eb2c: 2200 movs r2, #0 + 800eb2e: 2100 movs r1, #0 + 800eb30: 0018 movs r0, r3 + 800eb32: f001 f835 bl 800fba0 + pdev->ep0_data_len = 0; + 800eb36: 68fa ldr r2, [r7, #12] + 800eb38: 23fc movs r3, #252 ; 0xfc + 800eb3a: 005b lsls r3, r3, #1 + 800eb3c: 2100 movs r1, #0 + 800eb3e: 50d1 str r1, [r2, r3] + 800eb40: e031 b.n 800eba6 + } + else + { + if((pdev->pClass->EP0_TxSent != NULL)&& + 800eb42: 68fa ldr r2, [r7, #12] + 800eb44: 2384 movs r3, #132 ; 0x84 + 800eb46: 009b lsls r3, r3, #2 + 800eb48: 58d3 ldr r3, [r2, r3] + 800eb4a: 68db ldr r3, [r3, #12] + 800eb4c: 2b00 cmp r3, #0 + 800eb4e: d00d beq.n 800eb6c + (pdev->dev_state == USBD_STATE_CONFIGURED)) + 800eb50: 68fa ldr r2, [r7, #12] + 800eb52: 23fe movs r3, #254 ; 0xfe + 800eb54: 005b lsls r3, r3, #1 + 800eb56: 5cd3 ldrb r3, [r2, r3] + if((pdev->pClass->EP0_TxSent != NULL)&& + 800eb58: 2b03 cmp r3, #3 + 800eb5a: d107 bne.n 800eb6c + { + pdev->pClass->EP0_TxSent(pdev); + 800eb5c: 68fa ldr r2, [r7, #12] + 800eb5e: 2384 movs r3, #132 ; 0x84 + 800eb60: 009b lsls r3, r3, #2 + 800eb62: 58d3 ldr r3, [r2, r3] + 800eb64: 68db ldr r3, [r3, #12] + 800eb66: 68fa ldr r2, [r7, #12] + 800eb68: 0010 movs r0, r2 + 800eb6a: 4798 blx r3 + } + USBD_CtlReceiveStatus(pdev); + 800eb6c: 68fb ldr r3, [r7, #12] + 800eb6e: 0018 movs r0, r3 + 800eb70: f001 f850 bl 800fc14 + 800eb74: e017 b.n 800eba6 + } + } + } + } + else if((pdev->pClass->DataIn != NULL)&& + 800eb76: 68fa ldr r2, [r7, #12] + 800eb78: 2384 movs r3, #132 ; 0x84 + 800eb7a: 009b lsls r3, r3, #2 + 800eb7c: 58d3 ldr r3, [r2, r3] + 800eb7e: 695b ldr r3, [r3, #20] + 800eb80: 2b00 cmp r3, #0 + 800eb82: d010 beq.n 800eba6 + (pdev->dev_state == USBD_STATE_CONFIGURED)) + 800eb84: 68fa ldr r2, [r7, #12] + 800eb86: 23fe movs r3, #254 ; 0xfe + 800eb88: 005b lsls r3, r3, #1 + 800eb8a: 5cd3 ldrb r3, [r2, r3] + else if((pdev->pClass->DataIn != NULL)&& + 800eb8c: 2b03 cmp r3, #3 + 800eb8e: d10a bne.n 800eba6 + { + pdev->pClass->DataIn(pdev, epnum); + 800eb90: 68fa ldr r2, [r7, #12] + 800eb92: 2384 movs r3, #132 ; 0x84 + 800eb94: 009b lsls r3, r3, #2 + 800eb96: 58d3 ldr r3, [r2, r3] + 800eb98: 695b ldr r3, [r3, #20] + 800eb9a: 220b movs r2, #11 + 800eb9c: 18ba adds r2, r7, r2 + 800eb9e: 7811 ldrb r1, [r2, #0] + 800eba0: 68fa ldr r2, [r7, #12] + 800eba2: 0010 movs r0, r2 + 800eba4: 4798 blx r3 + } + return USBD_OK; + 800eba6: 2300 movs r3, #0 +} + 800eba8: 0018 movs r0, r3 + 800ebaa: 46bd mov sp, r7 + 800ebac: b006 add sp, #24 + 800ebae: bd80 pop {r7, pc} + +0800ebb0 : +* @param pdev: device instance +* @retval status +*/ + +USBD_StatusTypeDef USBD_LL_Reset(USBD_HandleTypeDef *pdev) +{ + 800ebb0: b580 push {r7, lr} + 800ebb2: b082 sub sp, #8 + 800ebb4: af00 add r7, sp, #0 + 800ebb6: 6078 str r0, [r7, #4] + /* Open EP0 OUT */ + USBD_LL_OpenEP(pdev, + 800ebb8: 6878 ldr r0, [r7, #4] + 800ebba: 2340 movs r3, #64 ; 0x40 + 800ebbc: 2200 movs r2, #0 + 800ebbe: 2100 movs r1, #0 + 800ebc0: f7ff fd00 bl 800e5c4 + 0x00, + USBD_EP_TYPE_CTRL, + USB_MAX_EP0_SIZE); + + pdev->ep_out[0].maxpacket = USB_MAX_EP0_SIZE; + 800ebc4: 687a ldr r2, [r7, #4] + 800ebc6: 2388 movs r3, #136 ; 0x88 + 800ebc8: 005b lsls r3, r3, #1 + 800ebca: 2140 movs r1, #64 ; 0x40 + 800ebcc: 50d1 str r1, [r2, r3] + + /* Open EP0 IN */ + USBD_LL_OpenEP(pdev, + 800ebce: 6878 ldr r0, [r7, #4] + 800ebd0: 2340 movs r3, #64 ; 0x40 + 800ebd2: 2200 movs r2, #0 + 800ebd4: 2180 movs r1, #128 ; 0x80 + 800ebd6: f7ff fcf5 bl 800e5c4 + 0x80, + USBD_EP_TYPE_CTRL, + USB_MAX_EP0_SIZE); + + pdev->ep_in[0].maxpacket = USB_MAX_EP0_SIZE; + 800ebda: 687b ldr r3, [r7, #4] + 800ebdc: 2240 movs r2, #64 ; 0x40 + 800ebde: 621a str r2, [r3, #32] + /* Upon Reset call user call back */ + pdev->dev_state = USBD_STATE_DEFAULT; + 800ebe0: 687a ldr r2, [r7, #4] + 800ebe2: 23fe movs r3, #254 ; 0xfe + 800ebe4: 005b lsls r3, r3, #1 + 800ebe6: 2101 movs r1, #1 + 800ebe8: 54d1 strb r1, [r2, r3] + + if (pdev->pClassData) + 800ebea: 687a ldr r2, [r7, #4] + 800ebec: 2385 movs r3, #133 ; 0x85 + 800ebee: 009b lsls r3, r3, #2 + 800ebf0: 58d3 ldr r3, [r2, r3] + 800ebf2: 2b00 cmp r3, #0 + 800ebf4: d00a beq.n 800ec0c + pdev->pClass->DeInit(pdev, pdev->dev_config); + 800ebf6: 687a ldr r2, [r7, #4] + 800ebf8: 2384 movs r3, #132 ; 0x84 + 800ebfa: 009b lsls r3, r3, #2 + 800ebfc: 58d3 ldr r3, [r2, r3] + 800ebfe: 685a ldr r2, [r3, #4] + 800ec00: 687b ldr r3, [r7, #4] + 800ec02: 685b ldr r3, [r3, #4] + 800ec04: b2d9 uxtb r1, r3 + 800ec06: 687b ldr r3, [r7, #4] + 800ec08: 0018 movs r0, r3 + 800ec0a: 4790 blx r2 + + + return USBD_OK; + 800ec0c: 2300 movs r3, #0 +} + 800ec0e: 0018 movs r0, r3 + 800ec10: 46bd mov sp, r7 + 800ec12: b002 add sp, #8 + 800ec14: bd80 pop {r7, pc} + +0800ec16 : +* Handle Reset event +* @param pdev: device instance +* @retval status +*/ +USBD_StatusTypeDef USBD_LL_SetSpeed(USBD_HandleTypeDef *pdev, USBD_SpeedTypeDef speed) +{ + 800ec16: b580 push {r7, lr} + 800ec18: b082 sub sp, #8 + 800ec1a: af00 add r7, sp, #0 + 800ec1c: 6078 str r0, [r7, #4] + 800ec1e: 000a movs r2, r1 + 800ec20: 1cfb adds r3, r7, #3 + 800ec22: 701a strb r2, [r3, #0] + pdev->dev_speed = speed; + 800ec24: 687b ldr r3, [r7, #4] + 800ec26: 1cfa adds r2, r7, #3 + 800ec28: 7812 ldrb r2, [r2, #0] + 800ec2a: 741a strb r2, [r3, #16] + return USBD_OK; + 800ec2c: 2300 movs r3, #0 +} + 800ec2e: 0018 movs r0, r3 + 800ec30: 46bd mov sp, r7 + 800ec32: b002 add sp, #8 + 800ec34: bd80 pop {r7, pc} + +0800ec36 : +* @param pdev: device instance +* @retval status +*/ + +USBD_StatusTypeDef USBD_LL_SOF(USBD_HandleTypeDef *pdev) +{ + 800ec36: b580 push {r7, lr} + 800ec38: b082 sub sp, #8 + 800ec3a: af00 add r7, sp, #0 + 800ec3c: 6078 str r0, [r7, #4] + if(pdev->dev_state == USBD_STATE_CONFIGURED) + 800ec3e: 687a ldr r2, [r7, #4] + 800ec40: 23fe movs r3, #254 ; 0xfe + 800ec42: 005b lsls r3, r3, #1 + 800ec44: 5cd3 ldrb r3, [r2, r3] + 800ec46: 2b03 cmp r3, #3 + 800ec48: d10e bne.n 800ec68 + { + if(pdev->pClass->SOF != NULL) + 800ec4a: 687a ldr r2, [r7, #4] + 800ec4c: 2384 movs r3, #132 ; 0x84 + 800ec4e: 009b lsls r3, r3, #2 + 800ec50: 58d3 ldr r3, [r2, r3] + 800ec52: 69db ldr r3, [r3, #28] + 800ec54: 2b00 cmp r3, #0 + 800ec56: d007 beq.n 800ec68 + { + pdev->pClass->SOF(pdev); + 800ec58: 687a ldr r2, [r7, #4] + 800ec5a: 2384 movs r3, #132 ; 0x84 + 800ec5c: 009b lsls r3, r3, #2 + 800ec5e: 58d3 ldr r3, [r2, r3] + 800ec60: 69db ldr r3, [r3, #28] + 800ec62: 687a ldr r2, [r7, #4] + 800ec64: 0010 movs r0, r2 + 800ec66: 4798 blx r3 + } + } + return USBD_OK; + 800ec68: 2300 movs r3, #0 +} + 800ec6a: 0018 movs r0, r3 + 800ec6c: 46bd mov sp, r7 + 800ec6e: b002 add sp, #8 + 800ec70: bd80 pop {r7, pc} + ... + +0800ec74 : +* @param pdev: device instance +* @param req: usb request +* @retval status +*/ +USBD_StatusTypeDef USBD_StdDevReq (USBD_HandleTypeDef *pdev , USBD_SetupReqTypedef *req) +{ + 800ec74: b580 push {r7, lr} + 800ec76: b084 sub sp, #16 + 800ec78: af00 add r7, sp, #0 + 800ec7a: 6078 str r0, [r7, #4] + 800ec7c: 6039 str r1, [r7, #0] + USBD_StatusTypeDef ret = USBD_OK; + 800ec7e: 230f movs r3, #15 + 800ec80: 18fb adds r3, r7, r3 + 800ec82: 2200 movs r2, #0 + 800ec84: 701a strb r2, [r3, #0] + + switch (req->bRequest) + 800ec86: 683b ldr r3, [r7, #0] + 800ec88: 785b ldrb r3, [r3, #1] + 800ec8a: 2b09 cmp r3, #9 + 800ec8c: d835 bhi.n 800ecfa + 800ec8e: 009a lsls r2, r3, #2 + 800ec90: 4b21 ldr r3, [pc, #132] ; (800ed18 ) + 800ec92: 18d3 adds r3, r2, r3 + 800ec94: 681b ldr r3, [r3, #0] + 800ec96: 469f mov pc, r3 + { + case USB_REQ_GET_DESCRIPTOR: + + USBD_GetDescriptor (pdev, req) ; + 800ec98: 683a ldr r2, [r7, #0] + 800ec9a: 687b ldr r3, [r7, #4] + 800ec9c: 0011 movs r1, r2 + 800ec9e: 0018 movs r0, r3 + 800eca0: f000 f97f bl 800efa2 + break; + 800eca4: e030 b.n 800ed08 + + case USB_REQ_SET_ADDRESS: + USBD_SetAddress(pdev, req); + 800eca6: 683a ldr r2, [r7, #0] + 800eca8: 687b ldr r3, [r7, #4] + 800ecaa: 0011 movs r1, r2 + 800ecac: 0018 movs r0, r3 + 800ecae: f000 fa19 bl 800f0e4 + break; + 800ecb2: e029 b.n 800ed08 + + case USB_REQ_SET_CONFIGURATION: + USBD_SetConfig (pdev , req); + 800ecb4: 683a ldr r2, [r7, #0] + 800ecb6: 687b ldr r3, [r7, #4] + 800ecb8: 0011 movs r1, r2 + 800ecba: 0018 movs r0, r3 + 800ecbc: f000 fa60 bl 800f180 + break; + 800ecc0: e022 b.n 800ed08 + + case USB_REQ_GET_CONFIGURATION: + USBD_GetConfig (pdev , req); + 800ecc2: 683a ldr r2, [r7, #0] + 800ecc4: 687b ldr r3, [r7, #4] + 800ecc6: 0011 movs r1, r2 + 800ecc8: 0018 movs r0, r3 + 800ecca: f000 faf5 bl 800f2b8 + break; + 800ecce: e01b b.n 800ed08 + + case USB_REQ_GET_STATUS: + USBD_GetStatus (pdev , req); + 800ecd0: 683a ldr r2, [r7, #0] + 800ecd2: 687b ldr r3, [r7, #4] + 800ecd4: 0011 movs r1, r2 + 800ecd6: 0018 movs r0, r3 + 800ecd8: f000 fb26 bl 800f328 + break; + 800ecdc: e014 b.n 800ed08 + + + case USB_REQ_SET_FEATURE: + USBD_SetFeature (pdev , req); + 800ecde: 683a ldr r2, [r7, #0] + 800ece0: 687b ldr r3, [r7, #4] + 800ece2: 0011 movs r1, r2 + 800ece4: 0018 movs r0, r3 + 800ece6: f000 fb4e bl 800f386 + break; + 800ecea: e00d b.n 800ed08 + + case USB_REQ_CLEAR_FEATURE: + USBD_ClrFeature (pdev , req); + 800ecec: 683a ldr r2, [r7, #0] + 800ecee: 687b ldr r3, [r7, #4] + 800ecf0: 0011 movs r1, r2 + 800ecf2: 0018 movs r0, r3 + 800ecf4: f000 fb66 bl 800f3c4 + break; + 800ecf8: e006 b.n 800ed08 + + default: + USBD_CtlError(pdev , req); + 800ecfa: 683a ldr r2, [r7, #0] + 800ecfc: 687b ldr r3, [r7, #4] + 800ecfe: 0011 movs r1, r2 + 800ed00: 0018 movs r0, r3 + 800ed02: f000 fbc9 bl 800f498 + break; + 800ed06: 46c0 nop ; (mov r8, r8) + } + + return ret; + 800ed08: 230f movs r3, #15 + 800ed0a: 18fb adds r3, r7, r3 + 800ed0c: 781b ldrb r3, [r3, #0] +} + 800ed0e: 0018 movs r0, r3 + 800ed10: 46bd mov sp, r7 + 800ed12: b004 add sp, #16 + 800ed14: bd80 pop {r7, pc} + 800ed16: 46c0 nop ; (mov r8, r8) + 800ed18: 0800fdd8 .word 0x0800fdd8 + +0800ed1c : +* @param pdev: device instance +* @param req: usb request +* @retval status +*/ +USBD_StatusTypeDef USBD_StdItfReq (USBD_HandleTypeDef *pdev , USBD_SetupReqTypedef *req) +{ + 800ed1c: b580 push {r7, lr} + 800ed1e: b084 sub sp, #16 + 800ed20: af00 add r7, sp, #0 + 800ed22: 6078 str r0, [r7, #4] + 800ed24: 6039 str r1, [r7, #0] + USBD_StatusTypeDef ret = USBD_OK; + 800ed26: 230f movs r3, #15 + 800ed28: 18fb adds r3, r7, r3 + 800ed2a: 2200 movs r2, #0 + 800ed2c: 701a strb r2, [r3, #0] + + switch (pdev->dev_state) + 800ed2e: 687a ldr r2, [r7, #4] + 800ed30: 23fe movs r3, #254 ; 0xfe + 800ed32: 005b lsls r3, r3, #1 + 800ed34: 5cd3 ldrb r3, [r2, r3] + 800ed36: 2b03 cmp r3, #3 + 800ed38: d122 bne.n 800ed80 + { + case USBD_STATE_CONFIGURED: + + if (LOBYTE(req->wIndex) <= USBD_MAX_NUM_INTERFACES) + 800ed3a: 683b ldr r3, [r7, #0] + 800ed3c: 889b ldrh r3, [r3, #4] + 800ed3e: b2db uxtb r3, r3 + 800ed40: 2b02 cmp r3, #2 + 800ed42: d816 bhi.n 800ed72 + { + pdev->pClass->Setup (pdev, req); + 800ed44: 687a ldr r2, [r7, #4] + 800ed46: 2384 movs r3, #132 ; 0x84 + 800ed48: 009b lsls r3, r3, #2 + 800ed4a: 58d3 ldr r3, [r2, r3] + 800ed4c: 689b ldr r3, [r3, #8] + 800ed4e: 6839 ldr r1, [r7, #0] + 800ed50: 687a ldr r2, [r7, #4] + 800ed52: 0010 movs r0, r2 + 800ed54: 4798 blx r3 + + if((req->wLength == 0)&& (ret == USBD_OK)) + 800ed56: 683b ldr r3, [r7, #0] + 800ed58: 88db ldrh r3, [r3, #6] + 800ed5a: 2b00 cmp r3, #0 + 800ed5c: d117 bne.n 800ed8e + 800ed5e: 230f movs r3, #15 + 800ed60: 18fb adds r3, r7, r3 + 800ed62: 781b ldrb r3, [r3, #0] + 800ed64: 2b00 cmp r3, #0 + 800ed66: d112 bne.n 800ed8e + { + USBD_CtlSendStatus(pdev); + 800ed68: 687b ldr r3, [r7, #4] + 800ed6a: 0018 movs r0, r3 + 800ed6c: f000 ff3e bl 800fbec + } + else + { + USBD_CtlError(pdev , req); + } + break; + 800ed70: e00d b.n 800ed8e + USBD_CtlError(pdev , req); + 800ed72: 683a ldr r2, [r7, #0] + 800ed74: 687b ldr r3, [r7, #4] + 800ed76: 0011 movs r1, r2 + 800ed78: 0018 movs r0, r3 + 800ed7a: f000 fb8d bl 800f498 + break; + 800ed7e: e006 b.n 800ed8e + + default: + USBD_CtlError(pdev , req); + 800ed80: 683a ldr r2, [r7, #0] + 800ed82: 687b ldr r3, [r7, #4] + 800ed84: 0011 movs r1, r2 + 800ed86: 0018 movs r0, r3 + 800ed88: f000 fb86 bl 800f498 + break; + 800ed8c: e000 b.n 800ed90 + break; + 800ed8e: 46c0 nop ; (mov r8, r8) + } + return USBD_OK; + 800ed90: 2300 movs r3, #0 +} + 800ed92: 0018 movs r0, r3 + 800ed94: 46bd mov sp, r7 + 800ed96: b004 add sp, #16 + 800ed98: bd80 pop {r7, pc} + +0800ed9a : +* @param pdev: device instance +* @param req: usb request +* @retval status +*/ +USBD_StatusTypeDef USBD_StdEPReq (USBD_HandleTypeDef *pdev , USBD_SetupReqTypedef *req) +{ + 800ed9a: b580 push {r7, lr} + 800ed9c: b084 sub sp, #16 + 800ed9e: af00 add r7, sp, #0 + 800eda0: 6078 str r0, [r7, #4] + 800eda2: 6039 str r1, [r7, #0] + + uint8_t ep_addr; + USBD_StatusTypeDef ret = USBD_OK; + 800eda4: 230f movs r3, #15 + 800eda6: 18fb adds r3, r7, r3 + 800eda8: 2200 movs r2, #0 + 800edaa: 701a strb r2, [r3, #0] + USBD_EndpointTypeDef *pep; + ep_addr = LOBYTE(req->wIndex); + 800edac: 683b ldr r3, [r7, #0] + 800edae: 889a ldrh r2, [r3, #4] + 800edb0: 230e movs r3, #14 + 800edb2: 18fb adds r3, r7, r3 + 800edb4: 701a strb r2, [r3, #0] + + switch (req->bRequest) + 800edb6: 683b ldr r3, [r7, #0] + 800edb8: 785b ldrb r3, [r3, #1] + 800edba: 2b01 cmp r3, #1 + 800edbc: d04e beq.n 800ee5c + 800edbe: 2b03 cmp r3, #3 + 800edc0: d003 beq.n 800edca + 800edc2: 2b00 cmp r3, #0 + 800edc4: d100 bne.n 800edc8 + 800edc6: e090 b.n 800eeea + break; + } + break; + + default: + break; + 800edc8: e0e4 b.n 800ef94 + switch (pdev->dev_state) + 800edca: 687a ldr r2, [r7, #4] + 800edcc: 23fe movs r3, #254 ; 0xfe + 800edce: 005b lsls r3, r3, #1 + 800edd0: 5cd3 ldrb r3, [r2, r3] + 800edd2: 2b02 cmp r3, #2 + 800edd4: d002 beq.n 800eddc + 800edd6: 2b03 cmp r3, #3 + 800edd8: d013 beq.n 800ee02 + 800edda: e036 b.n 800ee4a + if ((ep_addr != 0x00) && (ep_addr != 0x80)) + 800eddc: 230e movs r3, #14 + 800edde: 18fb adds r3, r7, r3 + 800ede0: 781b ldrb r3, [r3, #0] + 800ede2: 2b00 cmp r3, #0 + 800ede4: d038 beq.n 800ee58 + 800ede6: 230e movs r3, #14 + 800ede8: 18fb adds r3, r7, r3 + 800edea: 781b ldrb r3, [r3, #0] + 800edec: 2b80 cmp r3, #128 ; 0x80 + 800edee: d033 beq.n 800ee58 + USBD_LL_StallEP(pdev , ep_addr); + 800edf0: 230e movs r3, #14 + 800edf2: 18fb adds r3, r7, r3 + 800edf4: 781a ldrb r2, [r3, #0] + 800edf6: 687b ldr r3, [r7, #4] + 800edf8: 0011 movs r1, r2 + 800edfa: 0018 movs r0, r3 + 800edfc: f7ff fc1a bl 800e634 + break; + 800ee00: e02a b.n 800ee58 + if (req->wValue == USB_FEATURE_EP_HALT) + 800ee02: 683b ldr r3, [r7, #0] + 800ee04: 885b ldrh r3, [r3, #2] + 800ee06: 2b00 cmp r3, #0 + 800ee08: d111 bne.n 800ee2e + if ((ep_addr != 0x00) && (ep_addr != 0x80)) + 800ee0a: 230e movs r3, #14 + 800ee0c: 18fb adds r3, r7, r3 + 800ee0e: 781b ldrb r3, [r3, #0] + 800ee10: 2b00 cmp r3, #0 + 800ee12: d00c beq.n 800ee2e + 800ee14: 230e movs r3, #14 + 800ee16: 18fb adds r3, r7, r3 + 800ee18: 781b ldrb r3, [r3, #0] + 800ee1a: 2b80 cmp r3, #128 ; 0x80 + 800ee1c: d007 beq.n 800ee2e + USBD_LL_StallEP(pdev , ep_addr); + 800ee1e: 230e movs r3, #14 + 800ee20: 18fb adds r3, r7, r3 + 800ee22: 781a ldrb r2, [r3, #0] + 800ee24: 687b ldr r3, [r7, #4] + 800ee26: 0011 movs r1, r2 + 800ee28: 0018 movs r0, r3 + 800ee2a: f7ff fc03 bl 800e634 + pdev->pClass->Setup (pdev, req); + 800ee2e: 687a ldr r2, [r7, #4] + 800ee30: 2384 movs r3, #132 ; 0x84 + 800ee32: 009b lsls r3, r3, #2 + 800ee34: 58d3 ldr r3, [r2, r3] + 800ee36: 689b ldr r3, [r3, #8] + 800ee38: 6839 ldr r1, [r7, #0] + 800ee3a: 687a ldr r2, [r7, #4] + 800ee3c: 0010 movs r0, r2 + 800ee3e: 4798 blx r3 + USBD_CtlSendStatus(pdev); + 800ee40: 687b ldr r3, [r7, #4] + 800ee42: 0018 movs r0, r3 + 800ee44: f000 fed2 bl 800fbec + break; + 800ee48: e007 b.n 800ee5a + USBD_CtlError(pdev , req); + 800ee4a: 683a ldr r2, [r7, #0] + 800ee4c: 687b ldr r3, [r7, #4] + 800ee4e: 0011 movs r1, r2 + 800ee50: 0018 movs r0, r3 + 800ee52: f000 fb21 bl 800f498 + break; + 800ee56: e000 b.n 800ee5a + break; + 800ee58: 46c0 nop ; (mov r8, r8) + break; + 800ee5a: e09b b.n 800ef94 + switch (pdev->dev_state) + 800ee5c: 687a ldr r2, [r7, #4] + 800ee5e: 23fe movs r3, #254 ; 0xfe + 800ee60: 005b lsls r3, r3, #1 + 800ee62: 5cd3 ldrb r3, [r2, r3] + 800ee64: 2b02 cmp r3, #2 + 800ee66: d002 beq.n 800ee6e + 800ee68: 2b03 cmp r3, #3 + 800ee6a: d013 beq.n 800ee94 + 800ee6c: e032 b.n 800eed4 + if ((ep_addr != 0x00) && (ep_addr != 0x80)) + 800ee6e: 230e movs r3, #14 + 800ee70: 18fb adds r3, r7, r3 + 800ee72: 781b ldrb r3, [r3, #0] + 800ee74: 2b00 cmp r3, #0 + 800ee76: d034 beq.n 800eee2 + 800ee78: 230e movs r3, #14 + 800ee7a: 18fb adds r3, r7, r3 + 800ee7c: 781b ldrb r3, [r3, #0] + 800ee7e: 2b80 cmp r3, #128 ; 0x80 + 800ee80: d02f beq.n 800eee2 + USBD_LL_StallEP(pdev , ep_addr); + 800ee82: 230e movs r3, #14 + 800ee84: 18fb adds r3, r7, r3 + 800ee86: 781a ldrb r2, [r3, #0] + 800ee88: 687b ldr r3, [r7, #4] + 800ee8a: 0011 movs r1, r2 + 800ee8c: 0018 movs r0, r3 + 800ee8e: f7ff fbd1 bl 800e634 + break; + 800ee92: e026 b.n 800eee2 + if (req->wValue == USB_FEATURE_EP_HALT) + 800ee94: 683b ldr r3, [r7, #0] + 800ee96: 885b ldrh r3, [r3, #2] + 800ee98: 2b00 cmp r3, #0 + 800ee9a: d124 bne.n 800eee6 + if ((ep_addr & 0x7F) != 0x00) + 800ee9c: 230e movs r3, #14 + 800ee9e: 18fb adds r3, r7, r3 + 800eea0: 781b ldrb r3, [r3, #0] + 800eea2: 227f movs r2, #127 ; 0x7f + 800eea4: 4013 ands r3, r2 + 800eea6: d010 beq.n 800eeca + USBD_LL_ClearStallEP(pdev , ep_addr); + 800eea8: 230e movs r3, #14 + 800eeaa: 18fb adds r3, r7, r3 + 800eeac: 781a ldrb r2, [r3, #0] + 800eeae: 687b ldr r3, [r7, #4] + 800eeb0: 0011 movs r1, r2 + 800eeb2: 0018 movs r0, r3 + 800eeb4: f7ff fbd4 bl 800e660 + pdev->pClass->Setup (pdev, req); + 800eeb8: 687a ldr r2, [r7, #4] + 800eeba: 2384 movs r3, #132 ; 0x84 + 800eebc: 009b lsls r3, r3, #2 + 800eebe: 58d3 ldr r3, [r2, r3] + 800eec0: 689b ldr r3, [r3, #8] + 800eec2: 6839 ldr r1, [r7, #0] + 800eec4: 687a ldr r2, [r7, #4] + 800eec6: 0010 movs r0, r2 + 800eec8: 4798 blx r3 + USBD_CtlSendStatus(pdev); + 800eeca: 687b ldr r3, [r7, #4] + 800eecc: 0018 movs r0, r3 + 800eece: f000 fe8d bl 800fbec + break; + 800eed2: e008 b.n 800eee6 + USBD_CtlError(pdev , req); + 800eed4: 683a ldr r2, [r7, #0] + 800eed6: 687b ldr r3, [r7, #4] + 800eed8: 0011 movs r1, r2 + 800eeda: 0018 movs r0, r3 + 800eedc: f000 fadc bl 800f498 + break; + 800eee0: e002 b.n 800eee8 + break; + 800eee2: 46c0 nop ; (mov r8, r8) + 800eee4: e056 b.n 800ef94 + break; + 800eee6: 46c0 nop ; (mov r8, r8) + break; + 800eee8: e054 b.n 800ef94 + switch (pdev->dev_state) + 800eeea: 687a ldr r2, [r7, #4] + 800eeec: 23fe movs r3, #254 ; 0xfe + 800eeee: 005b lsls r3, r3, #1 + 800eef0: 5cd3 ldrb r3, [r2, r3] + 800eef2: 2b02 cmp r3, #2 + 800eef4: d002 beq.n 800eefc + 800eef6: 2b03 cmp r3, #3 + 800eef8: d00f beq.n 800ef1a + 800eefa: e042 b.n 800ef82 + if ((ep_addr & 0x7F) != 0x00) + 800eefc: 230e movs r3, #14 + 800eefe: 18fb adds r3, r7, r3 + 800ef00: 781b ldrb r3, [r3, #0] + 800ef02: 227f movs r2, #127 ; 0x7f + 800ef04: 4013 ands r3, r2 + 800ef06: d043 beq.n 800ef90 + USBD_LL_StallEP(pdev , ep_addr); + 800ef08: 230e movs r3, #14 + 800ef0a: 18fb adds r3, r7, r3 + 800ef0c: 781a ldrb r2, [r3, #0] + 800ef0e: 687b ldr r3, [r7, #4] + 800ef10: 0011 movs r1, r2 + 800ef12: 0018 movs r0, r3 + 800ef14: f7ff fb8e bl 800e634 + break; + 800ef18: e03a b.n 800ef90 + pep = ((ep_addr & 0x80) == 0x80) ? &pdev->ep_in[ep_addr & 0x7F]:\ + 800ef1a: 230e movs r3, #14 + 800ef1c: 18fb adds r3, r7, r3 + 800ef1e: 781b ldrb r3, [r3, #0] + 800ef20: b25b sxtb r3, r3 + 800ef22: 2b00 cmp r3, #0 + 800ef24: da0a bge.n 800ef3c + 800ef26: 230e movs r3, #14 + 800ef28: 18fb adds r3, r7, r3 + 800ef2a: 781b ldrb r3, [r3, #0] + 800ef2c: 227f movs r2, #127 ; 0x7f + 800ef2e: 4013 ands r3, r2 + 800ef30: 3301 adds r3, #1 + 800ef32: 011b lsls r3, r3, #4 + 800ef34: 687a ldr r2, [r7, #4] + 800ef36: 18d3 adds r3, r2, r3 + 800ef38: 3304 adds r3, #4 + 800ef3a: e009 b.n 800ef50 + &pdev->ep_out[ep_addr & 0x7F]; + 800ef3c: 230e movs r3, #14 + 800ef3e: 18fb adds r3, r7, r3 + 800ef40: 781b ldrb r3, [r3, #0] + 800ef42: 227f movs r2, #127 ; 0x7f + 800ef44: 4013 ands r3, r2 + pep = ((ep_addr & 0x80) == 0x80) ? &pdev->ep_in[ep_addr & 0x7F]:\ + 800ef46: 3310 adds r3, #16 + 800ef48: 011b lsls r3, r3, #4 + 800ef4a: 687a ldr r2, [r7, #4] + 800ef4c: 18d3 adds r3, r2, r3 + 800ef4e: 3304 adds r3, #4 + 800ef50: 60bb str r3, [r7, #8] + if(USBD_LL_IsStallEP(pdev, ep_addr)) + 800ef52: 230e movs r3, #14 + 800ef54: 18fb adds r3, r7, r3 + 800ef56: 781a ldrb r2, [r3, #0] + 800ef58: 687b ldr r3, [r7, #4] + 800ef5a: 0011 movs r1, r2 + 800ef5c: 0018 movs r0, r3 + 800ef5e: f7ff fb95 bl 800e68c + 800ef62: 1e03 subs r3, r0, #0 + 800ef64: d003 beq.n 800ef6e + pep->status = 0x0001; + 800ef66: 68bb ldr r3, [r7, #8] + 800ef68: 2201 movs r2, #1 + 800ef6a: 601a str r2, [r3, #0] + 800ef6c: e002 b.n 800ef74 + pep->status = 0x0000; + 800ef6e: 68bb ldr r3, [r7, #8] + 800ef70: 2200 movs r2, #0 + 800ef72: 601a str r2, [r3, #0] + (uint8_t *)&pep->status, + 800ef74: 68b9 ldr r1, [r7, #8] + USBD_CtlSendData (pdev, + 800ef76: 687b ldr r3, [r7, #4] + 800ef78: 2202 movs r2, #2 + 800ef7a: 0018 movs r0, r3 + 800ef7c: f000 fdf0 bl 800fb60 + break; + 800ef80: e007 b.n 800ef92 + USBD_CtlError(pdev , req); + 800ef82: 683a ldr r2, [r7, #0] + 800ef84: 687b ldr r3, [r7, #4] + 800ef86: 0011 movs r1, r2 + 800ef88: 0018 movs r0, r3 + 800ef8a: f000 fa85 bl 800f498 + break; + 800ef8e: e000 b.n 800ef92 + break; + 800ef90: 46c0 nop ; (mov r8, r8) + break; + 800ef92: 46c0 nop ; (mov r8, r8) + } + return ret; + 800ef94: 230f movs r3, #15 + 800ef96: 18fb adds r3, r7, r3 + 800ef98: 781b ldrb r3, [r3, #0] +} + 800ef9a: 0018 movs r0, r3 + 800ef9c: 46bd mov sp, r7 + 800ef9e: b004 add sp, #16 + 800efa0: bd80 pop {r7, pc} + +0800efa2 : +* @param req: usb request +* @retval status +*/ +static void USBD_GetDescriptor(USBD_HandleTypeDef *pdev , + USBD_SetupReqTypedef *req) +{ + 800efa2: b580 push {r7, lr} + 800efa4: b084 sub sp, #16 + 800efa6: af00 add r7, sp, #0 + 800efa8: 6078 str r0, [r7, #4] + 800efaa: 6039 str r1, [r7, #0] + uint16_t len; + uint8_t *pbuf; + + + switch (req->wValue >> 8) + 800efac: 683b ldr r3, [r7, #0] + 800efae: 885b ldrh r3, [r3, #2] + 800efb0: 0a1b lsrs r3, r3, #8 + 800efb2: b29b uxth r3, r3 + 800efb4: 2b02 cmp r3, #2 + 800efb6: d011 beq.n 800efdc + 800efb8: 2b03 cmp r3, #3 + 800efba: d01b beq.n 800eff4 + 800efbc: 2b01 cmp r3, #1 + 800efbe: d167 bne.n 800f090 + { + case USB_DESC_TYPE_DEVICE: + pbuf = pdev->pDesc->GetDeviceDescriptor(pdev->dev_speed, &len); + 800efc0: 687a ldr r2, [r7, #4] + 800efc2: 2383 movs r3, #131 ; 0x83 + 800efc4: 009b lsls r3, r3, #2 + 800efc6: 58d3 ldr r3, [r2, r3] + 800efc8: 681b ldr r3, [r3, #0] + 800efca: 687a ldr r2, [r7, #4] + 800efcc: 7c12 ldrb r2, [r2, #16] + 800efce: 210a movs r1, #10 + 800efd0: 1879 adds r1, r7, r1 + 800efd2: 0010 movs r0, r2 + 800efd4: 4798 blx r3 + 800efd6: 0003 movs r3, r0 + 800efd8: 60fb str r3, [r7, #12] + break; + 800efda: e060 b.n 800f09e + + case USB_DESC_TYPE_CONFIGURATION: + pbuf = (uint8_t *)pdev->pClass->GetFSConfigDescriptor(&len); + 800efdc: 687a ldr r2, [r7, #4] + 800efde: 2384 movs r3, #132 ; 0x84 + 800efe0: 009b lsls r3, r3, #2 + 800efe2: 58d3 ldr r3, [r2, r3] + 800efe4: 6a9b ldr r3, [r3, #40] ; 0x28 + 800efe6: 220a movs r2, #10 + 800efe8: 18ba adds r2, r7, r2 + 800efea: 0010 movs r0, r2 + 800efec: 4798 blx r3 + 800efee: 0003 movs r3, r0 + 800eff0: 60fb str r3, [r7, #12] + break; + 800eff2: e054 b.n 800f09e + + case USB_DESC_TYPE_STRING: + switch ((uint8_t)(req->wValue)) + 800eff4: 683b ldr r3, [r7, #0] + 800eff6: 885b ldrh r3, [r3, #2] + 800eff8: b2db uxtb r3, r3 + 800effa: 2b01 cmp r3, #1 + 800effc: d016 beq.n 800f02c + 800effe: dc02 bgt.n 800f006 + 800f000: 2b00 cmp r3, #0 + 800f002: d005 beq.n 800f010 + 800f004: e03c b.n 800f080 + 800f006: 2b02 cmp r3, #2 + 800f008: d01e beq.n 800f048 + 800f00a: 2b03 cmp r3, #3 + 800f00c: d02a beq.n 800f064 + 800f00e: e037 b.n 800f080 + { + case USBD_IDX_LANGID_STR: + pbuf = pdev->pDesc->GetLangIDStrDescriptor(pdev->dev_speed, &len); + 800f010: 687a ldr r2, [r7, #4] + 800f012: 2383 movs r3, #131 ; 0x83 + 800f014: 009b lsls r3, r3, #2 + 800f016: 58d3 ldr r3, [r2, r3] + 800f018: 685b ldr r3, [r3, #4] + 800f01a: 687a ldr r2, [r7, #4] + 800f01c: 7c12 ldrb r2, [r2, #16] + 800f01e: 210a movs r1, #10 + 800f020: 1879 adds r1, r7, r1 + 800f022: 0010 movs r0, r2 + 800f024: 4798 blx r3 + 800f026: 0003 movs r3, r0 + 800f028: 60fb str r3, [r7, #12] + break; + 800f02a: e030 b.n 800f08e + + case USBD_IDX_MFC_STR: + pbuf = pdev->pDesc->GetManufacturerStrDescriptor(pdev->dev_speed, &len); + 800f02c: 687a ldr r2, [r7, #4] + 800f02e: 2383 movs r3, #131 ; 0x83 + 800f030: 009b lsls r3, r3, #2 + 800f032: 58d3 ldr r3, [r2, r3] + 800f034: 689b ldr r3, [r3, #8] + 800f036: 687a ldr r2, [r7, #4] + 800f038: 7c12 ldrb r2, [r2, #16] + 800f03a: 210a movs r1, #10 + 800f03c: 1879 adds r1, r7, r1 + 800f03e: 0010 movs r0, r2 + 800f040: 4798 blx r3 + 800f042: 0003 movs r3, r0 + 800f044: 60fb str r3, [r7, #12] + break; + 800f046: e022 b.n 800f08e + + case USBD_IDX_PRODUCT_STR: + pbuf = pdev->pDesc->GetProductStrDescriptor(pdev->dev_speed, &len); + 800f048: 687a ldr r2, [r7, #4] + 800f04a: 2383 movs r3, #131 ; 0x83 + 800f04c: 009b lsls r3, r3, #2 + 800f04e: 58d3 ldr r3, [r2, r3] + 800f050: 68db ldr r3, [r3, #12] + 800f052: 687a ldr r2, [r7, #4] + 800f054: 7c12 ldrb r2, [r2, #16] + 800f056: 210a movs r1, #10 + 800f058: 1879 adds r1, r7, r1 + 800f05a: 0010 movs r0, r2 + 800f05c: 4798 blx r3 + 800f05e: 0003 movs r3, r0 + 800f060: 60fb str r3, [r7, #12] + break; + 800f062: e014 b.n 800f08e + + case USBD_IDX_SERIAL_STR: + pbuf = pdev->pDesc->GetSerialStrDescriptor(pdev->dev_speed, &len); + 800f064: 687a ldr r2, [r7, #4] + 800f066: 2383 movs r3, #131 ; 0x83 + 800f068: 009b lsls r3, r3, #2 + 800f06a: 58d3 ldr r3, [r2, r3] + 800f06c: 691b ldr r3, [r3, #16] + 800f06e: 687a ldr r2, [r7, #4] + 800f070: 7c12 ldrb r2, [r2, #16] + 800f072: 210a movs r1, #10 + 800f074: 1879 adds r1, r7, r1 + 800f076: 0010 movs r0, r2 + 800f078: 4798 blx r3 + 800f07a: 0003 movs r3, r0 + 800f07c: 60fb str r3, [r7, #12] + break; + 800f07e: e006 b.n 800f08e + + default: + USBD_CtlError(pdev , req); + 800f080: 683a ldr r2, [r7, #0] + 800f082: 687b ldr r3, [r7, #4] + 800f084: 0011 movs r1, r2 + 800f086: 0018 movs r0, r3 + 800f088: f000 fa06 bl 800f498 + return; + 800f08c: e027 b.n 800f0de + } + break; + 800f08e: e006 b.n 800f09e + + default: + USBD_CtlError(pdev , req); + 800f090: 683a ldr r2, [r7, #0] + 800f092: 687b ldr r3, [r7, #4] + 800f094: 0011 movs r1, r2 + 800f096: 0018 movs r0, r3 + 800f098: f000 f9fe bl 800f498 + return; + 800f09c: e01f b.n 800f0de + } + + if((len != 0)&& (req->wLength != 0)) + 800f09e: 230a movs r3, #10 + 800f0a0: 18fb adds r3, r7, r3 + 800f0a2: 881b ldrh r3, [r3, #0] + 800f0a4: 2b00 cmp r3, #0 + 800f0a6: d01a beq.n 800f0de + 800f0a8: 683b ldr r3, [r7, #0] + 800f0aa: 88db ldrh r3, [r3, #6] + 800f0ac: 2b00 cmp r3, #0 + 800f0ae: d016 beq.n 800f0de + { + + len = MIN(len , req->wLength); + 800f0b0: 683b ldr r3, [r7, #0] + 800f0b2: 88da ldrh r2, [r3, #6] + 800f0b4: 230a movs r3, #10 + 800f0b6: 18fb adds r3, r7, r3 + 800f0b8: 881b ldrh r3, [r3, #0] + 800f0ba: 1c18 adds r0, r3, #0 + 800f0bc: 1c11 adds r1, r2, #0 + 800f0be: b28a uxth r2, r1 + 800f0c0: b283 uxth r3, r0 + 800f0c2: 429a cmp r2, r3 + 800f0c4: d900 bls.n 800f0c8 + 800f0c6: 1c01 adds r1, r0, #0 + 800f0c8: b28a uxth r2, r1 + 800f0ca: 210a movs r1, #10 + 800f0cc: 187b adds r3, r7, r1 + 800f0ce: 801a strh r2, [r3, #0] + + USBD_CtlSendData (pdev, + 800f0d0: 187b adds r3, r7, r1 + 800f0d2: 881a ldrh r2, [r3, #0] + 800f0d4: 68f9 ldr r1, [r7, #12] + 800f0d6: 687b ldr r3, [r7, #4] + 800f0d8: 0018 movs r0, r3 + 800f0da: f000 fd41 bl 800fb60 + pbuf, + len); + } + +} + 800f0de: 46bd mov sp, r7 + 800f0e0: b004 add sp, #16 + 800f0e2: bd80 pop {r7, pc} + +0800f0e4 : +* @param req: usb request +* @retval status +*/ +static void USBD_SetAddress(USBD_HandleTypeDef *pdev , + USBD_SetupReqTypedef *req) +{ + 800f0e4: b590 push {r4, r7, lr} + 800f0e6: b085 sub sp, #20 + 800f0e8: af00 add r7, sp, #0 + 800f0ea: 6078 str r0, [r7, #4] + 800f0ec: 6039 str r1, [r7, #0] + uint8_t dev_addr; + + if ((req->wIndex == 0) && (req->wLength == 0)) + 800f0ee: 683b ldr r3, [r7, #0] + 800f0f0: 889b ldrh r3, [r3, #4] + 800f0f2: 2b00 cmp r3, #0 + 800f0f4: d13a bne.n 800f16c + 800f0f6: 683b ldr r3, [r7, #0] + 800f0f8: 88db ldrh r3, [r3, #6] + 800f0fa: 2b00 cmp r3, #0 + 800f0fc: d136 bne.n 800f16c + { + dev_addr = (uint8_t)(req->wValue) & 0x7F; + 800f0fe: 683b ldr r3, [r7, #0] + 800f100: 885b ldrh r3, [r3, #2] + 800f102: b2da uxtb r2, r3 + 800f104: 230f movs r3, #15 + 800f106: 18fb adds r3, r7, r3 + 800f108: 217f movs r1, #127 ; 0x7f + 800f10a: 400a ands r2, r1 + 800f10c: 701a strb r2, [r3, #0] + + if (pdev->dev_state == USBD_STATE_CONFIGURED) + 800f10e: 687a ldr r2, [r7, #4] + 800f110: 23fe movs r3, #254 ; 0xfe + 800f112: 005b lsls r3, r3, #1 + 800f114: 5cd3 ldrb r3, [r2, r3] + 800f116: 2b03 cmp r3, #3 + 800f118: d106 bne.n 800f128 + { + USBD_CtlError(pdev , req); + 800f11a: 683a ldr r2, [r7, #0] + 800f11c: 687b ldr r3, [r7, #4] + 800f11e: 0011 movs r1, r2 + 800f120: 0018 movs r0, r3 + 800f122: f000 f9b9 bl 800f498 + if (pdev->dev_state == USBD_STATE_CONFIGURED) + 800f126: e027 b.n 800f178 + } + else + { + pdev->dev_address = dev_addr; + 800f128: 687a ldr r2, [r7, #4] + 800f12a: 240f movs r4, #15 + 800f12c: 1939 adds r1, r7, r4 + 800f12e: 23ff movs r3, #255 ; 0xff + 800f130: 005b lsls r3, r3, #1 + 800f132: 7809 ldrb r1, [r1, #0] + 800f134: 54d1 strb r1, [r2, r3] + USBD_LL_SetUSBAddress(pdev, dev_addr); + 800f136: 193b adds r3, r7, r4 + 800f138: 781a ldrb r2, [r3, #0] + 800f13a: 687b ldr r3, [r7, #4] + 800f13c: 0011 movs r1, r2 + 800f13e: 0018 movs r0, r3 + 800f140: f7ff facf bl 800e6e2 + USBD_CtlSendStatus(pdev); + 800f144: 687b ldr r3, [r7, #4] + 800f146: 0018 movs r0, r3 + 800f148: f000 fd50 bl 800fbec + + if (dev_addr != 0) + 800f14c: 193b adds r3, r7, r4 + 800f14e: 781b ldrb r3, [r3, #0] + 800f150: 2b00 cmp r3, #0 + 800f152: d005 beq.n 800f160 + { + pdev->dev_state = USBD_STATE_ADDRESSED; + 800f154: 687a ldr r2, [r7, #4] + 800f156: 23fe movs r3, #254 ; 0xfe + 800f158: 005b lsls r3, r3, #1 + 800f15a: 2102 movs r1, #2 + 800f15c: 54d1 strb r1, [r2, r3] + if (pdev->dev_state == USBD_STATE_CONFIGURED) + 800f15e: e00b b.n 800f178 + } + else + { + pdev->dev_state = USBD_STATE_DEFAULT; + 800f160: 687a ldr r2, [r7, #4] + 800f162: 23fe movs r3, #254 ; 0xfe + 800f164: 005b lsls r3, r3, #1 + 800f166: 2101 movs r1, #1 + 800f168: 54d1 strb r1, [r2, r3] + if (pdev->dev_state == USBD_STATE_CONFIGURED) + 800f16a: e005 b.n 800f178 + } + } + } + else + { + USBD_CtlError(pdev , req); + 800f16c: 683a ldr r2, [r7, #0] + 800f16e: 687b ldr r3, [r7, #4] + 800f170: 0011 movs r1, r2 + 800f172: 0018 movs r0, r3 + 800f174: f000 f990 bl 800f498 + } +} + 800f178: 46c0 nop ; (mov r8, r8) + 800f17a: 46bd mov sp, r7 + 800f17c: b005 add sp, #20 + 800f17e: bd90 pop {r4, r7, pc} + +0800f180 : +* @param req: usb request +* @retval status +*/ +static void USBD_SetConfig(USBD_HandleTypeDef *pdev , + USBD_SetupReqTypedef *req) +{ + 800f180: b580 push {r7, lr} + 800f182: b082 sub sp, #8 + 800f184: af00 add r7, sp, #0 + 800f186: 6078 str r0, [r7, #4] + 800f188: 6039 str r1, [r7, #0] + + static uint8_t cfgidx; + + cfgidx = (uint8_t)(req->wValue); + 800f18a: 683b ldr r3, [r7, #0] + 800f18c: 885b ldrh r3, [r3, #2] + 800f18e: b2da uxtb r2, r3 + 800f190: 4b48 ldr r3, [pc, #288] ; (800f2b4 ) + 800f192: 701a strb r2, [r3, #0] + + if (cfgidx > USBD_MAX_NUM_CONFIGURATION ) + 800f194: 4b47 ldr r3, [pc, #284] ; (800f2b4 ) + 800f196: 781b ldrb r3, [r3, #0] + 800f198: 2b01 cmp r3, #1 + 800f19a: d906 bls.n 800f1aa + { + USBD_CtlError(pdev , req); + 800f19c: 683a ldr r2, [r7, #0] + 800f19e: 687b ldr r3, [r7, #4] + 800f1a0: 0011 movs r1, r2 + 800f1a2: 0018 movs r0, r3 + 800f1a4: f000 f978 bl 800f498 + 800f1a8: e081 b.n 800f2ae + } + else + { + switch (pdev->dev_state) + 800f1aa: 687a ldr r2, [r7, #4] + 800f1ac: 23fe movs r3, #254 ; 0xfe + 800f1ae: 005b lsls r3, r3, #1 + 800f1b0: 5cd3 ldrb r3, [r2, r3] + 800f1b2: 2b02 cmp r3, #2 + 800f1b4: d002 beq.n 800f1bc + 800f1b6: 2b03 cmp r3, #3 + 800f1b8: d029 beq.n 800f20e + 800f1ba: e071 b.n 800f2a0 + { + case USBD_STATE_ADDRESSED: + if (cfgidx) + 800f1bc: 4b3d ldr r3, [pc, #244] ; (800f2b4 ) + 800f1be: 781b ldrb r3, [r3, #0] + 800f1c0: 2b00 cmp r3, #0 + 800f1c2: d01f beq.n 800f204 + { + pdev->dev_config = cfgidx; + 800f1c4: 4b3b ldr r3, [pc, #236] ; (800f2b4 ) + 800f1c6: 781b ldrb r3, [r3, #0] + 800f1c8: 001a movs r2, r3 + 800f1ca: 687b ldr r3, [r7, #4] + 800f1cc: 605a str r2, [r3, #4] + pdev->dev_state = USBD_STATE_CONFIGURED; + 800f1ce: 687a ldr r2, [r7, #4] + 800f1d0: 23fe movs r3, #254 ; 0xfe + 800f1d2: 005b lsls r3, r3, #1 + 800f1d4: 2103 movs r1, #3 + 800f1d6: 54d1 strb r1, [r2, r3] + if(USBD_SetClassConfig(pdev , cfgidx) == USBD_FAIL) + 800f1d8: 4b36 ldr r3, [pc, #216] ; (800f2b4 ) + 800f1da: 781a ldrb r2, [r3, #0] + 800f1dc: 687b ldr r3, [r7, #4] + 800f1de: 0011 movs r1, r2 + 800f1e0: 0018 movs r0, r3 + 800f1e2: f7ff fb5b bl 800e89c + 800f1e6: 0003 movs r3, r0 + 800f1e8: 2b02 cmp r3, #2 + 800f1ea: d106 bne.n 800f1fa + { + USBD_CtlError(pdev , req); + 800f1ec: 683a ldr r2, [r7, #0] + 800f1ee: 687b ldr r3, [r7, #4] + 800f1f0: 0011 movs r1, r2 + 800f1f2: 0018 movs r0, r3 + 800f1f4: f000 f950 bl 800f498 + return; + 800f1f8: e059 b.n 800f2ae + } + USBD_CtlSendStatus(pdev); + 800f1fa: 687b ldr r3, [r7, #4] + 800f1fc: 0018 movs r0, r3 + 800f1fe: f000 fcf5 bl 800fbec + } + else + { + USBD_CtlSendStatus(pdev); + } + break; + 800f202: e054 b.n 800f2ae + USBD_CtlSendStatus(pdev); + 800f204: 687b ldr r3, [r7, #4] + 800f206: 0018 movs r0, r3 + 800f208: f000 fcf0 bl 800fbec + break; + 800f20c: e04f b.n 800f2ae + + case USBD_STATE_CONFIGURED: + if (cfgidx == 0) + 800f20e: 4b29 ldr r3, [pc, #164] ; (800f2b4 ) + 800f210: 781b ldrb r3, [r3, #0] + 800f212: 2b00 cmp r3, #0 + 800f214: d115 bne.n 800f242 + { + pdev->dev_state = USBD_STATE_ADDRESSED; + 800f216: 687a ldr r2, [r7, #4] + 800f218: 23fe movs r3, #254 ; 0xfe + 800f21a: 005b lsls r3, r3, #1 + 800f21c: 2102 movs r1, #2 + 800f21e: 54d1 strb r1, [r2, r3] + pdev->dev_config = cfgidx; + 800f220: 4b24 ldr r3, [pc, #144] ; (800f2b4 ) + 800f222: 781b ldrb r3, [r3, #0] + 800f224: 001a movs r2, r3 + 800f226: 687b ldr r3, [r7, #4] + 800f228: 605a str r2, [r3, #4] + USBD_ClrClassConfig(pdev , cfgidx); + 800f22a: 4b22 ldr r3, [pc, #136] ; (800f2b4 ) + 800f22c: 781a ldrb r2, [r3, #0] + 800f22e: 687b ldr r3, [r7, #4] + 800f230: 0011 movs r1, r2 + 800f232: 0018 movs r0, r3 + 800f234: f7ff fb5a bl 800e8ec + USBD_CtlSendStatus(pdev); + 800f238: 687b ldr r3, [r7, #4] + 800f23a: 0018 movs r0, r3 + 800f23c: f000 fcd6 bl 800fbec + } + else + { + USBD_CtlSendStatus(pdev); + } + break; + 800f240: e035 b.n 800f2ae + else if (cfgidx != pdev->dev_config) + 800f242: 4b1c ldr r3, [pc, #112] ; (800f2b4 ) + 800f244: 781b ldrb r3, [r3, #0] + 800f246: 001a movs r2, r3 + 800f248: 687b ldr r3, [r7, #4] + 800f24a: 685b ldr r3, [r3, #4] + 800f24c: 429a cmp r2, r3 + 800f24e: d022 beq.n 800f296 + USBD_ClrClassConfig(pdev , pdev->dev_config); + 800f250: 687b ldr r3, [r7, #4] + 800f252: 685b ldr r3, [r3, #4] + 800f254: b2da uxtb r2, r3 + 800f256: 687b ldr r3, [r7, #4] + 800f258: 0011 movs r1, r2 + 800f25a: 0018 movs r0, r3 + 800f25c: f7ff fb46 bl 800e8ec + pdev->dev_config = cfgidx; + 800f260: 4b14 ldr r3, [pc, #80] ; (800f2b4 ) + 800f262: 781b ldrb r3, [r3, #0] + 800f264: 001a movs r2, r3 + 800f266: 687b ldr r3, [r7, #4] + 800f268: 605a str r2, [r3, #4] + if(USBD_SetClassConfig(pdev , cfgidx) == USBD_FAIL) + 800f26a: 4b12 ldr r3, [pc, #72] ; (800f2b4 ) + 800f26c: 781a ldrb r2, [r3, #0] + 800f26e: 687b ldr r3, [r7, #4] + 800f270: 0011 movs r1, r2 + 800f272: 0018 movs r0, r3 + 800f274: f7ff fb12 bl 800e89c + 800f278: 0003 movs r3, r0 + 800f27a: 2b02 cmp r3, #2 + 800f27c: d106 bne.n 800f28c + USBD_CtlError(pdev , req); + 800f27e: 683a ldr r2, [r7, #0] + 800f280: 687b ldr r3, [r7, #4] + 800f282: 0011 movs r1, r2 + 800f284: 0018 movs r0, r3 + 800f286: f000 f907 bl 800f498 + return; + 800f28a: e010 b.n 800f2ae + USBD_CtlSendStatus(pdev); + 800f28c: 687b ldr r3, [r7, #4] + 800f28e: 0018 movs r0, r3 + 800f290: f000 fcac bl 800fbec + break; + 800f294: e00b b.n 800f2ae + USBD_CtlSendStatus(pdev); + 800f296: 687b ldr r3, [r7, #4] + 800f298: 0018 movs r0, r3 + 800f29a: f000 fca7 bl 800fbec + break; + 800f29e: e006 b.n 800f2ae + + default: + USBD_CtlError(pdev , req); + 800f2a0: 683a ldr r2, [r7, #0] + 800f2a2: 687b ldr r3, [r7, #4] + 800f2a4: 0011 movs r1, r2 + 800f2a6: 0018 movs r0, r3 + 800f2a8: f000 f8f6 bl 800f498 + break; + 800f2ac: 46c0 nop ; (mov r8, r8) + } + } +} + 800f2ae: 46bd mov sp, r7 + 800f2b0: b002 add sp, #8 + 800f2b2: bd80 pop {r7, pc} + 800f2b4: 200023c8 .word 0x200023c8 + +0800f2b8 : +* @param req: usb request +* @retval status +*/ +static void USBD_GetConfig(USBD_HandleTypeDef *pdev , + USBD_SetupReqTypedef *req) +{ + 800f2b8: b580 push {r7, lr} + 800f2ba: b082 sub sp, #8 + 800f2bc: af00 add r7, sp, #0 + 800f2be: 6078 str r0, [r7, #4] + 800f2c0: 6039 str r1, [r7, #0] + + if (req->wLength != 1) + 800f2c2: 683b ldr r3, [r7, #0] + 800f2c4: 88db ldrh r3, [r3, #6] + 800f2c6: 2b01 cmp r3, #1 + 800f2c8: d006 beq.n 800f2d8 + { + USBD_CtlError(pdev , req); + 800f2ca: 683a ldr r2, [r7, #0] + 800f2cc: 687b ldr r3, [r7, #4] + 800f2ce: 0011 movs r1, r2 + 800f2d0: 0018 movs r0, r3 + 800f2d2: f000 f8e1 bl 800f498 + default: + USBD_CtlError(pdev , req); + break; + } + } +} + 800f2d6: e023 b.n 800f320 + switch (pdev->dev_state ) + 800f2d8: 687a ldr r2, [r7, #4] + 800f2da: 23fe movs r3, #254 ; 0xfe + 800f2dc: 005b lsls r3, r3, #1 + 800f2de: 5cd3 ldrb r3, [r2, r3] + 800f2e0: 2b02 cmp r3, #2 + 800f2e2: d002 beq.n 800f2ea + 800f2e4: 2b03 cmp r3, #3 + 800f2e6: d00c beq.n 800f302 + 800f2e8: e013 b.n 800f312 + pdev->dev_default_config = 0; + 800f2ea: 687b ldr r3, [r7, #4] + 800f2ec: 2200 movs r2, #0 + 800f2ee: 609a str r2, [r3, #8] + (uint8_t *)&pdev->dev_default_config, + 800f2f0: 687b ldr r3, [r7, #4] + 800f2f2: 3308 adds r3, #8 + 800f2f4: 0019 movs r1, r3 + USBD_CtlSendData (pdev, + 800f2f6: 687b ldr r3, [r7, #4] + 800f2f8: 2201 movs r2, #1 + 800f2fa: 0018 movs r0, r3 + 800f2fc: f000 fc30 bl 800fb60 + break; + 800f300: e00e b.n 800f320 + (uint8_t *)&pdev->dev_config, + 800f302: 687b ldr r3, [r7, #4] + 800f304: 1d19 adds r1, r3, #4 + USBD_CtlSendData (pdev, + 800f306: 687b ldr r3, [r7, #4] + 800f308: 2201 movs r2, #1 + 800f30a: 0018 movs r0, r3 + 800f30c: f000 fc28 bl 800fb60 + break; + 800f310: e006 b.n 800f320 + USBD_CtlError(pdev , req); + 800f312: 683a ldr r2, [r7, #0] + 800f314: 687b ldr r3, [r7, #4] + 800f316: 0011 movs r1, r2 + 800f318: 0018 movs r0, r3 + 800f31a: f000 f8bd bl 800f498 + break; + 800f31e: 46c0 nop ; (mov r8, r8) +} + 800f320: 46c0 nop ; (mov r8, r8) + 800f322: 46bd mov sp, r7 + 800f324: b002 add sp, #8 + 800f326: bd80 pop {r7, pc} + +0800f328 : +* @param req: usb request +* @retval status +*/ +static void USBD_GetStatus(USBD_HandleTypeDef *pdev , + USBD_SetupReqTypedef *req) +{ + 800f328: b580 push {r7, lr} + 800f32a: b082 sub sp, #8 + 800f32c: af00 add r7, sp, #0 + 800f32e: 6078 str r0, [r7, #4] + 800f330: 6039 str r1, [r7, #0] + + + switch (pdev->dev_state) + 800f332: 687a ldr r2, [r7, #4] + 800f334: 23fe movs r3, #254 ; 0xfe + 800f336: 005b lsls r3, r3, #1 + 800f338: 5cd3 ldrb r3, [r2, r3] + 800f33a: 3b02 subs r3, #2 + 800f33c: 2b01 cmp r3, #1 + 800f33e: d817 bhi.n 800f370 + case USBD_STATE_CONFIGURED: + +#if ( USBD_SELF_POWERED == 1) + pdev->dev_config_status = USB_CONFIG_SELF_POWERED; +#else + pdev->dev_config_status = 0; + 800f340: 687b ldr r3, [r7, #4] + 800f342: 2200 movs r2, #0 + 800f344: 60da str r2, [r3, #12] +#endif + + if (pdev->dev_remote_wakeup) + 800f346: 687a ldr r2, [r7, #4] + 800f348: 2380 movs r3, #128 ; 0x80 + 800f34a: 009b lsls r3, r3, #2 + 800f34c: 58d3 ldr r3, [r2, r3] + 800f34e: 2b00 cmp r3, #0 + 800f350: d005 beq.n 800f35e + { + pdev->dev_config_status |= USB_CONFIG_REMOTE_WAKEUP; + 800f352: 687b ldr r3, [r7, #4] + 800f354: 68db ldr r3, [r3, #12] + 800f356: 2202 movs r2, #2 + 800f358: 431a orrs r2, r3 + 800f35a: 687b ldr r3, [r7, #4] + 800f35c: 60da str r2, [r3, #12] + } + + USBD_CtlSendData (pdev, + (uint8_t *)& pdev->dev_config_status, + 800f35e: 687b ldr r3, [r7, #4] + 800f360: 330c adds r3, #12 + 800f362: 0019 movs r1, r3 + USBD_CtlSendData (pdev, + 800f364: 687b ldr r3, [r7, #4] + 800f366: 2202 movs r2, #2 + 800f368: 0018 movs r0, r3 + 800f36a: f000 fbf9 bl 800fb60 + 2); + break; + 800f36e: e006 b.n 800f37e + + default : + USBD_CtlError(pdev , req); + 800f370: 683a ldr r2, [r7, #0] + 800f372: 687b ldr r3, [r7, #4] + 800f374: 0011 movs r1, r2 + 800f376: 0018 movs r0, r3 + 800f378: f000 f88e bl 800f498 + break; + 800f37c: 46c0 nop ; (mov r8, r8) + } +} + 800f37e: 46c0 nop ; (mov r8, r8) + 800f380: 46bd mov sp, r7 + 800f382: b002 add sp, #8 + 800f384: bd80 pop {r7, pc} + +0800f386 : +* @param req: usb request +* @retval status +*/ +static void USBD_SetFeature(USBD_HandleTypeDef *pdev , + USBD_SetupReqTypedef *req) +{ + 800f386: b580 push {r7, lr} + 800f388: b082 sub sp, #8 + 800f38a: af00 add r7, sp, #0 + 800f38c: 6078 str r0, [r7, #4] + 800f38e: 6039 str r1, [r7, #0] + + if (req->wValue == USB_FEATURE_REMOTE_WAKEUP) + 800f390: 683b ldr r3, [r7, #0] + 800f392: 885b ldrh r3, [r3, #2] + 800f394: 2b01 cmp r3, #1 + 800f396: d111 bne.n 800f3bc + { + pdev->dev_remote_wakeup = 1; + 800f398: 687a ldr r2, [r7, #4] + 800f39a: 2380 movs r3, #128 ; 0x80 + 800f39c: 009b lsls r3, r3, #2 + 800f39e: 2101 movs r1, #1 + 800f3a0: 50d1 str r1, [r2, r3] + pdev->pClass->Setup (pdev, req); + 800f3a2: 687a ldr r2, [r7, #4] + 800f3a4: 2384 movs r3, #132 ; 0x84 + 800f3a6: 009b lsls r3, r3, #2 + 800f3a8: 58d3 ldr r3, [r2, r3] + 800f3aa: 689b ldr r3, [r3, #8] + 800f3ac: 6839 ldr r1, [r7, #0] + 800f3ae: 687a ldr r2, [r7, #4] + 800f3b0: 0010 movs r0, r2 + 800f3b2: 4798 blx r3 + USBD_CtlSendStatus(pdev); + 800f3b4: 687b ldr r3, [r7, #4] + 800f3b6: 0018 movs r0, r3 + 800f3b8: f000 fc18 bl 800fbec + } + +} + 800f3bc: 46c0 nop ; (mov r8, r8) + 800f3be: 46bd mov sp, r7 + 800f3c0: b002 add sp, #8 + 800f3c2: bd80 pop {r7, pc} + +0800f3c4 : +* @param req: usb request +* @retval status +*/ +static void USBD_ClrFeature(USBD_HandleTypeDef *pdev , + USBD_SetupReqTypedef *req) +{ + 800f3c4: b580 push {r7, lr} + 800f3c6: b082 sub sp, #8 + 800f3c8: af00 add r7, sp, #0 + 800f3ca: 6078 str r0, [r7, #4] + 800f3cc: 6039 str r1, [r7, #0] + switch (pdev->dev_state) + 800f3ce: 687a ldr r2, [r7, #4] + 800f3d0: 23fe movs r3, #254 ; 0xfe + 800f3d2: 005b lsls r3, r3, #1 + 800f3d4: 5cd3 ldrb r3, [r2, r3] + 800f3d6: 3b02 subs r3, #2 + 800f3d8: 2b01 cmp r3, #1 + 800f3da: d816 bhi.n 800f40a + { + case USBD_STATE_ADDRESSED: + case USBD_STATE_CONFIGURED: + if (req->wValue == USB_FEATURE_REMOTE_WAKEUP) + 800f3dc: 683b ldr r3, [r7, #0] + 800f3de: 885b ldrh r3, [r3, #2] + 800f3e0: 2b01 cmp r3, #1 + 800f3e2: d119 bne.n 800f418 + { + pdev->dev_remote_wakeup = 0; + 800f3e4: 687a ldr r2, [r7, #4] + 800f3e6: 2380 movs r3, #128 ; 0x80 + 800f3e8: 009b lsls r3, r3, #2 + 800f3ea: 2100 movs r1, #0 + 800f3ec: 50d1 str r1, [r2, r3] + pdev->pClass->Setup (pdev, req); + 800f3ee: 687a ldr r2, [r7, #4] + 800f3f0: 2384 movs r3, #132 ; 0x84 + 800f3f2: 009b lsls r3, r3, #2 + 800f3f4: 58d3 ldr r3, [r2, r3] + 800f3f6: 689b ldr r3, [r3, #8] + 800f3f8: 6839 ldr r1, [r7, #0] + 800f3fa: 687a ldr r2, [r7, #4] + 800f3fc: 0010 movs r0, r2 + 800f3fe: 4798 blx r3 + USBD_CtlSendStatus(pdev); + 800f400: 687b ldr r3, [r7, #4] + 800f402: 0018 movs r0, r3 + 800f404: f000 fbf2 bl 800fbec + } + break; + 800f408: e006 b.n 800f418 + + default : + USBD_CtlError(pdev , req); + 800f40a: 683a ldr r2, [r7, #0] + 800f40c: 687b ldr r3, [r7, #4] + 800f40e: 0011 movs r1, r2 + 800f410: 0018 movs r0, r3 + 800f412: f000 f841 bl 800f498 + break; + 800f416: e000 b.n 800f41a + break; + 800f418: 46c0 nop ; (mov r8, r8) + } +} + 800f41a: 46c0 nop ; (mov r8, r8) + 800f41c: 46bd mov sp, r7 + 800f41e: b002 add sp, #8 + 800f420: bd80 pop {r7, pc} + +0800f422 : +* @param req: usb request +* @retval None +*/ + +void USBD_ParseSetupRequest(USBD_SetupReqTypedef *req, uint8_t *pdata) +{ + 800f422: b580 push {r7, lr} + 800f424: b082 sub sp, #8 + 800f426: af00 add r7, sp, #0 + 800f428: 6078 str r0, [r7, #4] + 800f42a: 6039 str r1, [r7, #0] + req->bmRequest = *(uint8_t *) (pdata); + 800f42c: 683b ldr r3, [r7, #0] + 800f42e: 781a ldrb r2, [r3, #0] + 800f430: 687b ldr r3, [r7, #4] + 800f432: 701a strb r2, [r3, #0] + req->bRequest = *(uint8_t *) (pdata + 1); + 800f434: 683b ldr r3, [r7, #0] + 800f436: 785a ldrb r2, [r3, #1] + 800f438: 687b ldr r3, [r7, #4] + 800f43a: 705a strb r2, [r3, #1] + req->wValue = SWAPBYTE (pdata + 2); + 800f43c: 683b ldr r3, [r7, #0] + 800f43e: 3302 adds r3, #2 + 800f440: 781b ldrb r3, [r3, #0] + 800f442: b29a uxth r2, r3 + 800f444: 683b ldr r3, [r7, #0] + 800f446: 3303 adds r3, #3 + 800f448: 781b ldrb r3, [r3, #0] + 800f44a: b29b uxth r3, r3 + 800f44c: 021b lsls r3, r3, #8 + 800f44e: b29b uxth r3, r3 + 800f450: 18d3 adds r3, r2, r3 + 800f452: b29a uxth r2, r3 + 800f454: 687b ldr r3, [r7, #4] + 800f456: 805a strh r2, [r3, #2] + req->wIndex = SWAPBYTE (pdata + 4); + 800f458: 683b ldr r3, [r7, #0] + 800f45a: 3304 adds r3, #4 + 800f45c: 781b ldrb r3, [r3, #0] + 800f45e: b29a uxth r2, r3 + 800f460: 683b ldr r3, [r7, #0] + 800f462: 3305 adds r3, #5 + 800f464: 781b ldrb r3, [r3, #0] + 800f466: b29b uxth r3, r3 + 800f468: 021b lsls r3, r3, #8 + 800f46a: b29b uxth r3, r3 + 800f46c: 18d3 adds r3, r2, r3 + 800f46e: b29a uxth r2, r3 + 800f470: 687b ldr r3, [r7, #4] + 800f472: 809a strh r2, [r3, #4] + req->wLength = SWAPBYTE (pdata + 6); + 800f474: 683b ldr r3, [r7, #0] + 800f476: 3306 adds r3, #6 + 800f478: 781b ldrb r3, [r3, #0] + 800f47a: b29a uxth r2, r3 + 800f47c: 683b ldr r3, [r7, #0] + 800f47e: 3307 adds r3, #7 + 800f480: 781b ldrb r3, [r3, #0] + 800f482: b29b uxth r3, r3 + 800f484: 021b lsls r3, r3, #8 + 800f486: b29b uxth r3, r3 + 800f488: 18d3 adds r3, r2, r3 + 800f48a: b29a uxth r2, r3 + 800f48c: 687b ldr r3, [r7, #4] + 800f48e: 80da strh r2, [r3, #6] + +} + 800f490: 46c0 nop ; (mov r8, r8) + 800f492: 46bd mov sp, r7 + 800f494: b002 add sp, #8 + 800f496: bd80 pop {r7, pc} + +0800f498 : +* @retval None +*/ + +void USBD_CtlError( USBD_HandleTypeDef *pdev , + USBD_SetupReqTypedef *req) +{ + 800f498: b580 push {r7, lr} + 800f49a: b082 sub sp, #8 + 800f49c: af00 add r7, sp, #0 + 800f49e: 6078 str r0, [r7, #4] + 800f4a0: 6039 str r1, [r7, #0] + USBD_LL_StallEP(pdev , 0x80); + 800f4a2: 687b ldr r3, [r7, #4] + 800f4a4: 2180 movs r1, #128 ; 0x80 + 800f4a6: 0018 movs r0, r3 + 800f4a8: f7ff f8c4 bl 800e634 + USBD_LL_StallEP(pdev , 0); + 800f4ac: 687b ldr r3, [r7, #4] + 800f4ae: 2100 movs r1, #0 + 800f4b0: 0018 movs r0, r3 + 800f4b2: f7ff f8bf bl 800e634 +} + 800f4b6: 46c0 nop ; (mov r8, r8) + 800f4b8: 46bd mov sp, r7 + 800f4ba: b002 add sp, #8 + 800f4bc: bd80 pop {r7, pc} + +0800f4be : + * @param unicode : Formatted string buffer (unicode) + * @param len : descriptor length + * @retval None + */ +void USBD_GetString(uint8_t *desc, uint8_t *unicode, uint16_t *len) +{ + 800f4be: b590 push {r4, r7, lr} + 800f4c0: b087 sub sp, #28 + 800f4c2: af00 add r7, sp, #0 + 800f4c4: 60f8 str r0, [r7, #12] + 800f4c6: 60b9 str r1, [r7, #8] + 800f4c8: 607a str r2, [r7, #4] + uint8_t idx = 0; + 800f4ca: 2317 movs r3, #23 + 800f4cc: 18fb adds r3, r7, r3 + 800f4ce: 2200 movs r2, #0 + 800f4d0: 701a strb r2, [r3, #0] + + if (desc != NULL) + 800f4d2: 68fb ldr r3, [r7, #12] + 800f4d4: 2b00 cmp r3, #0 + 800f4d6: d03e beq.n 800f556 + { + *len = USBD_GetLen(desc) * 2 + 2; + 800f4d8: 68fb ldr r3, [r7, #12] + 800f4da: 0018 movs r0, r3 + 800f4dc: f000 f83f bl 800f55e + 800f4e0: 0003 movs r3, r0 + 800f4e2: 3301 adds r3, #1 + 800f4e4: b29b uxth r3, r3 + 800f4e6: 18db adds r3, r3, r3 + 800f4e8: b29a uxth r2, r3 + 800f4ea: 687b ldr r3, [r7, #4] + 800f4ec: 801a strh r2, [r3, #0] + unicode[idx++] = *len; + 800f4ee: 687b ldr r3, [r7, #4] + 800f4f0: 8819 ldrh r1, [r3, #0] + 800f4f2: 2417 movs r4, #23 + 800f4f4: 193b adds r3, r7, r4 + 800f4f6: 781b ldrb r3, [r3, #0] + 800f4f8: 193a adds r2, r7, r4 + 800f4fa: 1c58 adds r0, r3, #1 + 800f4fc: 7010 strb r0, [r2, #0] + 800f4fe: 001a movs r2, r3 + 800f500: 68bb ldr r3, [r7, #8] + 800f502: 189b adds r3, r3, r2 + 800f504: b2ca uxtb r2, r1 + 800f506: 701a strb r2, [r3, #0] + unicode[idx++] = USB_DESC_TYPE_STRING; + 800f508: 193b adds r3, r7, r4 + 800f50a: 781b ldrb r3, [r3, #0] + 800f50c: 193a adds r2, r7, r4 + 800f50e: 1c59 adds r1, r3, #1 + 800f510: 7011 strb r1, [r2, #0] + 800f512: 001a movs r2, r3 + 800f514: 68bb ldr r3, [r7, #8] + 800f516: 189b adds r3, r3, r2 + 800f518: 2203 movs r2, #3 + 800f51a: 701a strb r2, [r3, #0] + + while (*desc != '\0') + 800f51c: e017 b.n 800f54e + { + unicode[idx++] = *desc++; + 800f51e: 68fb ldr r3, [r7, #12] + 800f520: 1c5a adds r2, r3, #1 + 800f522: 60fa str r2, [r7, #12] + 800f524: 2417 movs r4, #23 + 800f526: 193a adds r2, r7, r4 + 800f528: 7812 ldrb r2, [r2, #0] + 800f52a: 1939 adds r1, r7, r4 + 800f52c: 1c50 adds r0, r2, #1 + 800f52e: 7008 strb r0, [r1, #0] + 800f530: 0011 movs r1, r2 + 800f532: 68ba ldr r2, [r7, #8] + 800f534: 1852 adds r2, r2, r1 + 800f536: 781b ldrb r3, [r3, #0] + 800f538: 7013 strb r3, [r2, #0] + unicode[idx++] = 0x00; + 800f53a: 193b adds r3, r7, r4 + 800f53c: 781b ldrb r3, [r3, #0] + 800f53e: 193a adds r2, r7, r4 + 800f540: 1c59 adds r1, r3, #1 + 800f542: 7011 strb r1, [r2, #0] + 800f544: 001a movs r2, r3 + 800f546: 68bb ldr r3, [r7, #8] + 800f548: 189b adds r3, r3, r2 + 800f54a: 2200 movs r2, #0 + 800f54c: 701a strb r2, [r3, #0] + while (*desc != '\0') + 800f54e: 68fb ldr r3, [r7, #12] + 800f550: 781b ldrb r3, [r3, #0] + 800f552: 2b00 cmp r3, #0 + 800f554: d1e3 bne.n 800f51e + } + } +} + 800f556: 46c0 nop ; (mov r8, r8) + 800f558: 46bd mov sp, r7 + 800f55a: b007 add sp, #28 + 800f55c: bd90 pop {r4, r7, pc} + +0800f55e : + * return the string length + * @param buf : pointer to the ascii string buffer + * @retval string length + */ +static uint8_t USBD_GetLen(uint8_t *buf) +{ + 800f55e: b580 push {r7, lr} + 800f560: b084 sub sp, #16 + 800f562: af00 add r7, sp, #0 + 800f564: 6078 str r0, [r7, #4] + uint8_t len = 0; + 800f566: 230f movs r3, #15 + 800f568: 18fb adds r3, r7, r3 + 800f56a: 2200 movs r2, #0 + 800f56c: 701a strb r2, [r3, #0] + + while (*buf != '\0') + 800f56e: e008 b.n 800f582 + { + len++; + 800f570: 210f movs r1, #15 + 800f572: 187b adds r3, r7, r1 + 800f574: 781a ldrb r2, [r3, #0] + 800f576: 187b adds r3, r7, r1 + 800f578: 3201 adds r2, #1 + 800f57a: 701a strb r2, [r3, #0] + buf++; + 800f57c: 687b ldr r3, [r7, #4] + 800f57e: 3301 adds r3, #1 + 800f580: 607b str r3, [r7, #4] + while (*buf != '\0') + 800f582: 687b ldr r3, [r7, #4] + 800f584: 781b ldrb r3, [r3, #0] + 800f586: 2b00 cmp r3, #0 + 800f588: d1f2 bne.n 800f570 + } + + return len; + 800f58a: 230f movs r3, #15 + 800f58c: 18fb adds r3, r7, r3 + 800f58e: 781b ldrb r3, [r3, #0] +} + 800f590: 0018 movs r0, r3 + 800f592: 46bd mov sp, r7 + 800f594: b004 add sp, #16 + 800f596: bd80 pop {r7, pc} + +0800f598 : + * @param speed: Current device speed + * @param length: Pointer to data length variable + * @retval Pointer to descriptor buffer + */ +static uint8_t *USBD_VCP_DeviceDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) +{ + 800f598: b580 push {r7, lr} + 800f59a: b082 sub sp, #8 + 800f59c: af00 add r7, sp, #0 + 800f59e: 0002 movs r2, r0 + 800f5a0: 6039 str r1, [r7, #0] + 800f5a2: 1dfb adds r3, r7, #7 + 800f5a4: 701a strb r2, [r3, #0] + *length = sizeof(hUSBDDeviceDesc); + 800f5a6: 683b ldr r3, [r7, #0] + 800f5a8: 2212 movs r2, #18 + 800f5aa: 801a strh r2, [r3, #0] + return (uint8_t*)&hUSBDDeviceDesc; + 800f5ac: 4b02 ldr r3, [pc, #8] ; (800f5b8 ) +} + 800f5ae: 0018 movs r0, r3 + 800f5b0: 46bd mov sp, r7 + 800f5b2: b002 add sp, #8 + 800f5b4: bd80 pop {r7, pc} + 800f5b6: 46c0 nop ; (mov r8, r8) + 800f5b8: 0800fe14 .word 0x0800fe14 + +0800f5bc : + * @param speed: Current device speed + * @param length: Pointer to data length variable + * @retval Pointer to descriptor buffer + */ +static uint8_t *USBD_VCP_LangIDStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) +{ + 800f5bc: b580 push {r7, lr} + 800f5be: b082 sub sp, #8 + 800f5c0: af00 add r7, sp, #0 + 800f5c2: 0002 movs r2, r0 + 800f5c4: 6039 str r1, [r7, #0] + 800f5c6: 1dfb adds r3, r7, #7 + 800f5c8: 701a strb r2, [r3, #0] + *length = sizeof(USBD_LangIDDesc); + 800f5ca: 683b ldr r3, [r7, #0] + 800f5cc: 2204 movs r2, #4 + 800f5ce: 801a strh r2, [r3, #0] + return (uint8_t*)USBD_LangIDDesc; + 800f5d0: 4b02 ldr r3, [pc, #8] ; (800f5dc ) +} + 800f5d2: 0018 movs r0, r3 + 800f5d4: 46bd mov sp, r7 + 800f5d6: b002 add sp, #8 + 800f5d8: bd80 pop {r7, pc} + 800f5da: 46c0 nop ; (mov r8, r8) + 800f5dc: 0800fe78 .word 0x0800fe78 + +0800f5e0 : + * @param speed: Current device speed + * @param length: Pointer to data length variable + * @retval Pointer to descriptor buffer + */ +static uint8_t *USBD_VCP_ProductStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) +{ + 800f5e0: b580 push {r7, lr} + 800f5e2: b082 sub sp, #8 + 800f5e4: af00 add r7, sp, #0 + 800f5e6: 0002 movs r2, r0 + 800f5e8: 6039 str r1, [r7, #0] + 800f5ea: 1dfb adds r3, r7, #7 + 800f5ec: 701a strb r2, [r3, #0] + USBD_GetString((uint8_t *)USBD_PRODUCT_FS_STRING, USBD_StrDesc, length); + 800f5ee: 683a ldr r2, [r7, #0] + 800f5f0: 4904 ldr r1, [pc, #16] ; (800f604 ) + 800f5f2: 4b05 ldr r3, [pc, #20] ; (800f608 ) + 800f5f4: 0018 movs r0, r3 + 800f5f6: f7ff ff62 bl 800f4be + return USBD_StrDesc; + 800f5fa: 4b02 ldr r3, [pc, #8] ; (800f604 ) +} + 800f5fc: 0018 movs r0, r3 + 800f5fe: 46bd mov sp, r7 + 800f600: b002 add sp, #8 + 800f602: bd80 pop {r7, pc} + 800f604: 200023cc .word 0x200023cc + 800f608: 0800fd1c .word 0x0800fd1c + +0800f60c : + * @param speed: Current device speed + * @param length: Pointer to data length variable + * @retval Pointer to descriptor buffer + */ +static uint8_t *USBD_VCP_ManufacturerStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) +{ + 800f60c: b580 push {r7, lr} + 800f60e: b082 sub sp, #8 + 800f610: af00 add r7, sp, #0 + 800f612: 0002 movs r2, r0 + 800f614: 6039 str r1, [r7, #0] + 800f616: 1dfb adds r3, r7, #7 + 800f618: 701a strb r2, [r3, #0] + USBD_GetString((uint8_t *)USBD_MANUFACTURER_STRING, USBD_StrDesc, length); + 800f61a: 683a ldr r2, [r7, #0] + 800f61c: 4904 ldr r1, [pc, #16] ; (800f630 ) + 800f61e: 4b05 ldr r3, [pc, #20] ; (800f634 ) + 800f620: 0018 movs r0, r3 + 800f622: f7ff ff4c bl 800f4be + return USBD_StrDesc; + 800f626: 4b02 ldr r3, [pc, #8] ; (800f630 ) +} + 800f628: 0018 movs r0, r3 + 800f62a: 46bd mov sp, r7 + 800f62c: b002 add sp, #8 + 800f62e: bd80 pop {r7, pc} + 800f630: 200023cc .word 0x200023cc + 800f634: 0800fd20 .word 0x0800fd20 + +0800f638 : + * @param speed: Current device speed + * @param length: Pointer to data length variable + * @retval Pointer to descriptor buffer + */ +static uint8_t *USBD_VCP_SerialStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) +{ + 800f638: b580 push {r7, lr} + 800f63a: b084 sub sp, #16 + 800f63c: af00 add r7, sp, #0 + 800f63e: 0002 movs r2, r0 + 800f640: 6039 str r1, [r7, #0] + 800f642: 1dfb adds r3, r7, #7 + 800f644: 701a strb r2, [r3, #0] + + /* + for some peculiar reason, ST doesn't define the unique ID registers in the HAL include files + the DEVICE_ID registers are documented in Chapter 33 of the RM0091 Reference Manual + */ + deviceserial = *(uint32_t*)(0x1FFFF7B0); /*DEVICE_ID2*/ + 800f646: 4b0e ldr r3, [pc, #56] ; (800f680 ) + 800f648: 681b ldr r3, [r3, #0] + 800f64a: 60fb str r3, [r7, #12] + + USBD_StrDesc[0] = *length = 2 + 8*2 + 4*2; + 800f64c: 683b ldr r3, [r7, #0] + 800f64e: 221a movs r2, #26 + 800f650: 801a strh r2, [r3, #0] + 800f652: 4b0c ldr r3, [pc, #48] ; (800f684 ) + 800f654: 221a movs r2, #26 + 800f656: 701a strb r2, [r3, #0] + USBD_StrDesc[1] = USB_DESC_TYPE_STRING; + 800f658: 4b0a ldr r3, [pc, #40] ; (800f684 ) + 800f65a: 2203 movs r2, #3 + 800f65c: 705a strb r2, [r3, #1] + /* set upper bits to ensure classification as locally administered */ + IntToUnicode (0x02020000, &USBD_StrDesc[2], 4); + 800f65e: 4b0a ldr r3, [pc, #40] ; (800f688 ) + 800f660: 480a ldr r0, [pc, #40] ; (800f68c ) + 800f662: 2204 movs r2, #4 + 800f664: 0019 movs r1, r3 + 800f666: f000 f815 bl 800f694 + /* set lower 32-bits using silicon serial number */ + IntToUnicode (deviceserial, &USBD_StrDesc[10], 8); + 800f66a: 4909 ldr r1, [pc, #36] ; (800f690 ) + 800f66c: 68fb ldr r3, [r7, #12] + 800f66e: 2208 movs r2, #8 + 800f670: 0018 movs r0, r3 + 800f672: f000 f80f bl 800f694 + return USBD_StrDesc; + 800f676: 4b03 ldr r3, [pc, #12] ; (800f684 ) +} + 800f678: 0018 movs r0, r3 + 800f67a: 46bd mov sp, r7 + 800f67c: b004 add sp, #16 + 800f67e: bd80 pop {r7, pc} + 800f680: 1ffff7b0 .word 0x1ffff7b0 + 800f684: 200023cc .word 0x200023cc + 800f688: 200023ce .word 0x200023ce + 800f68c: 02020000 .word 0x02020000 + 800f690: 200023d6 .word 0x200023d6 + +0800f694 : + * @param pbuf: pointer to the buffer + * @param len: buffer length + * @retval None + */ +static void IntToUnicode (uint32_t value, uint8_t *pbuf, uint8_t len) +{ + 800f694: b580 push {r7, lr} + 800f696: b086 sub sp, #24 + 800f698: af00 add r7, sp, #0 + 800f69a: 60f8 str r0, [r7, #12] + 800f69c: 60b9 str r1, [r7, #8] + 800f69e: 1dfb adds r3, r7, #7 + 800f6a0: 701a strb r2, [r3, #0] + uint8_t idx = 0; + 800f6a2: 2117 movs r1, #23 + 800f6a4: 187b adds r3, r7, r1 + 800f6a6: 2200 movs r2, #0 + 800f6a8: 701a strb r2, [r3, #0] + + for( idx = 0 ; idx < len ; idx ++) + 800f6aa: 187b adds r3, r7, r1 + 800f6ac: 2200 movs r2, #0 + 800f6ae: 701a strb r2, [r3, #0] + 800f6b0: e02f b.n 800f712 + { + if( ((value >> 28)) < 0xA ) + 800f6b2: 68fb ldr r3, [r7, #12] + 800f6b4: 0f1b lsrs r3, r3, #28 + 800f6b6: 2b09 cmp r3, #9 + 800f6b8: d80d bhi.n 800f6d6 + { + pbuf[ 2* idx] = (value >> 28) + '0'; + 800f6ba: 68fb ldr r3, [r7, #12] + 800f6bc: 0f1b lsrs r3, r3, #28 + 800f6be: b2da uxtb r2, r3 + 800f6c0: 2317 movs r3, #23 + 800f6c2: 18fb adds r3, r7, r3 + 800f6c4: 781b ldrb r3, [r3, #0] + 800f6c6: 005b lsls r3, r3, #1 + 800f6c8: 0019 movs r1, r3 + 800f6ca: 68bb ldr r3, [r7, #8] + 800f6cc: 185b adds r3, r3, r1 + 800f6ce: 3230 adds r2, #48 ; 0x30 + 800f6d0: b2d2 uxtb r2, r2 + 800f6d2: 701a strb r2, [r3, #0] + 800f6d4: e00c b.n 800f6f0 + } + else + { + pbuf[2* idx] = (value >> 28) + 'A' - 10; + 800f6d6: 68fb ldr r3, [r7, #12] + 800f6d8: 0f1b lsrs r3, r3, #28 + 800f6da: b2da uxtb r2, r3 + 800f6dc: 2317 movs r3, #23 + 800f6de: 18fb adds r3, r7, r3 + 800f6e0: 781b ldrb r3, [r3, #0] + 800f6e2: 005b lsls r3, r3, #1 + 800f6e4: 0019 movs r1, r3 + 800f6e6: 68bb ldr r3, [r7, #8] + 800f6e8: 185b adds r3, r3, r1 + 800f6ea: 3237 adds r2, #55 ; 0x37 + 800f6ec: b2d2 uxtb r2, r2 + 800f6ee: 701a strb r2, [r3, #0] + } + + value = value << 4; + 800f6f0: 68fb ldr r3, [r7, #12] + 800f6f2: 011b lsls r3, r3, #4 + 800f6f4: 60fb str r3, [r7, #12] + + pbuf[ 2* idx + 1] = 0; + 800f6f6: 2117 movs r1, #23 + 800f6f8: 187b adds r3, r7, r1 + 800f6fa: 781b ldrb r3, [r3, #0] + 800f6fc: 005b lsls r3, r3, #1 + 800f6fe: 3301 adds r3, #1 + 800f700: 68ba ldr r2, [r7, #8] + 800f702: 18d3 adds r3, r2, r3 + 800f704: 2200 movs r2, #0 + 800f706: 701a strb r2, [r3, #0] + for( idx = 0 ; idx < len ; idx ++) + 800f708: 187b adds r3, r7, r1 + 800f70a: 781a ldrb r2, [r3, #0] + 800f70c: 187b adds r3, r7, r1 + 800f70e: 3201 adds r2, #1 + 800f710: 701a strb r2, [r3, #0] + 800f712: 2317 movs r3, #23 + 800f714: 18fa adds r2, r7, r3 + 800f716: 1dfb adds r3, r7, #7 + 800f718: 7812 ldrb r2, [r2, #0] + 800f71a: 781b ldrb r3, [r3, #0] + 800f71c: 429a cmp r2, r3 + 800f71e: d3c8 bcc.n 800f6b2 + } +} + 800f720: 46c0 nop ; (mov r8, r8) + 800f722: 46bd mov sp, r7 + 800f724: b006 add sp, #24 + 800f726: bd80 pop {r7, pc} + +0800f728 : +static int ecm_tx_remaining; +static int ecm_tx_busy; +static int copy_length; + +void usb_ecm_recv_renew(void) +{ + 800f728: b590 push {r4, r7, lr} + 800f72a: b083 sub sp, #12 + 800f72c: af00 add r7, sp, #0 + USBD_StatusTypeDef outcome; + + outcome = USBD_LL_PrepareReceive(registered_pdev, ECM_DATA_OUT_EP, ecm_rx_buffer + ecm_rx_index, ECM_DATA_OUT_SZ); + 800f72e: 4b0c ldr r3, [pc, #48] ; (800f760 ) + 800f730: 6818 ldr r0, [r3, #0] + 800f732: 4b0c ldr r3, [pc, #48] ; (800f764 ) + 800f734: 681b ldr r3, [r3, #0] + 800f736: 001a movs r2, r3 + 800f738: 4b0b ldr r3, [pc, #44] ; (800f768 ) + 800f73a: 18d2 adds r2, r2, r3 + 800f73c: 1dfc adds r4, r7, #7 + 800f73e: 2340 movs r3, #64 ; 0x40 + 800f740: 2103 movs r1, #3 + 800f742: f7ff f80d bl 800e760 + 800f746: 0003 movs r3, r0 + 800f748: 7023 strb r3, [r4, #0] + + OutboundTransferNeedsRenewal = (USBD_OK != outcome); /* set if the HAL was busy so that we know to retry it */ + 800f74a: 1dfb adds r3, r7, #7 + 800f74c: 781b ldrb r3, [r3, #0] + 800f74e: 1e5a subs r2, r3, #1 + 800f750: 4193 sbcs r3, r2 + 800f752: b2da uxtb r2, r3 + 800f754: 4b05 ldr r3, [pc, #20] ; (800f76c ) + 800f756: 701a strb r2, [r3, #0] +} + 800f758: 46c0 nop ; (mov r8, r8) + 800f75a: 46bd mov sp, r7 + 800f75c: b003 add sp, #12 + 800f75e: bd90 pop {r4, r7, pc} + 800f760: 200024cc .word 0x200024cc + 800f764: 200028d8 .word 0x200028d8 + 800f768: 200024d0 .word 0x200024d0 + 800f76c: 200028dd .word 0x200028dd + +0800f770 : + +static uint8_t USBD_ECM_Init (USBD_HandleTypeDef *pdev, uint8_t cfgidx) +{ + 800f770: b580 push {r7, lr} + 800f772: b082 sub sp, #8 + 800f774: af00 add r7, sp, #0 + 800f776: 6078 str r0, [r7, #4] + 800f778: 000a movs r2, r1 + 800f77a: 1cfb adds r3, r7, #3 + 800f77c: 701a strb r2, [r3, #0] + registered_pdev = pdev; + 800f77e: 4b14 ldr r3, [pc, #80] ; (800f7d0 ) + 800f780: 687a ldr r2, [r7, #4] + 800f782: 601a str r2, [r3, #0] + + /* Open EP IN */ + USBD_LL_OpenEP(pdev, ECM_DATA_IN_EP, USBD_EP_TYPE_BULK, ECM_DATA_IN_SZ); + 800f784: 6878 ldr r0, [r7, #4] + 800f786: 2340 movs r3, #64 ; 0x40 + 800f788: 2202 movs r2, #2 + 800f78a: 2182 movs r1, #130 ; 0x82 + 800f78c: f7fe ff1a bl 800e5c4 + + /* Open EP OUT */ + USBD_LL_OpenEP(pdev, ECM_DATA_OUT_EP, USBD_EP_TYPE_BULK, ECM_DATA_OUT_SZ); + 800f790: 6878 ldr r0, [r7, #4] + 800f792: 2340 movs r3, #64 ; 0x40 + 800f794: 2202 movs r2, #2 + 800f796: 2103 movs r1, #3 + 800f798: f7fe ff14 bl 800e5c4 + + /* Open Command IN EP */ + USBD_LL_OpenEP(pdev, ECM_NOTIFICATION_IN_EP, USBD_EP_TYPE_INTR, ECM_NOTIFICATION_IN_SZ); + 800f79c: 6878 ldr r0, [r7, #4] + 800f79e: 2340 movs r3, #64 ; 0x40 + 800f7a0: 2203 movs r2, #3 + 800f7a2: 2181 movs r1, #129 ; 0x81 + 800f7a4: f7fe ff0e bl 800e5c4 + + usb_ecm_recv_renew(); + 800f7a8: f7ff ffbe bl 800f728 + can_xmit = true; + 800f7ac: 4b09 ldr r3, [pc, #36] ; (800f7d4 ) + 800f7ae: 2201 movs r2, #1 + 800f7b0: 701a strb r2, [r3, #0] + OutboundTransferNeedsRenewal = false; + 800f7b2: 4b09 ldr r3, [pc, #36] ; (800f7d8 ) + 800f7b4: 2200 movs r2, #0 + 800f7b6: 701a strb r2, [r3, #0] + ecm_tx_busy = 0; + 800f7b8: 4b08 ldr r3, [pc, #32] ; (800f7dc ) + 800f7ba: 2200 movs r2, #0 + 800f7bc: 601a str r2, [r3, #0] + ecm_tx_remaining = 0; + 800f7be: 4b08 ldr r3, [pc, #32] ; (800f7e0 ) + 800f7c0: 2200 movs r2, #0 + 800f7c2: 601a str r2, [r3, #0] + + return USBD_OK; + 800f7c4: 2300 movs r3, #0 +} + 800f7c6: 0018 movs r0, r3 + 800f7c8: 46bd mov sp, r7 + 800f7ca: b002 add sp, #8 + 800f7cc: bd80 pop {r7, pc} + 800f7ce: 46c0 nop ; (mov r8, r8) + 800f7d0: 200024cc .word 0x200024cc + 800f7d4: 200028dc .word 0x200028dc + 800f7d8: 200028dd .word 0x200028dd + 800f7dc: 200028e8 .word 0x200028e8 + 800f7e0: 200028e4 .word 0x200028e4 + +0800f7e4 : + +static uint8_t USBD_ECM_DeInit (USBD_HandleTypeDef *pdev, uint8_t cfgidx) +{ + 800f7e4: b580 push {r7, lr} + 800f7e6: b082 sub sp, #8 + 800f7e8: af00 add r7, sp, #0 + 800f7ea: 6078 str r0, [r7, #4] + 800f7ec: 000a movs r2, r1 + 800f7ee: 1cfb adds r3, r7, #3 + 800f7f0: 701a strb r2, [r3, #0] + registered_pdev = NULL; + 800f7f2: 4b0d ldr r3, [pc, #52] ; (800f828 ) + 800f7f4: 2200 movs r2, #0 + 800f7f6: 601a str r2, [r3, #0] + + /* Close EP IN */ + USBD_LL_CloseEP(pdev, ECM_DATA_IN_EP); + 800f7f8: 687b ldr r3, [r7, #4] + 800f7fa: 2182 movs r1, #130 ; 0x82 + 800f7fc: 0018 movs r0, r3 + 800f7fe: f7fe ff03 bl 800e608 + + /* Close EP OUT */ + USBD_LL_CloseEP(pdev, ECM_DATA_OUT_EP); + 800f802: 687b ldr r3, [r7, #4] + 800f804: 2103 movs r1, #3 + 800f806: 0018 movs r0, r3 + 800f808: f7fe fefe bl 800e608 + + /* Close Command IN EP */ + USBD_LL_CloseEP(pdev, ECM_NOTIFICATION_IN_EP); + 800f80c: 687b ldr r3, [r7, #4] + 800f80e: 2181 movs r1, #129 ; 0x81 + 800f810: 0018 movs r0, r3 + 800f812: f7fe fef9 bl 800e608 + + can_xmit = false; + 800f816: 4b05 ldr r3, [pc, #20] ; (800f82c ) + 800f818: 2200 movs r2, #0 + 800f81a: 701a strb r2, [r3, #0] + + return USBD_OK; + 800f81c: 2300 movs r3, #0 +} + 800f81e: 0018 movs r0, r3 + 800f820: 46bd mov sp, r7 + 800f822: b002 add sp, #8 + 800f824: bd80 pop {r7, pc} + 800f826: 46c0 nop ; (mov r8, r8) + 800f828: 200024cc .word 0x200024cc + 800f82c: 200028dc .word 0x200028dc + +0800f830 : + +static uint8_t USBD_ECM_Setup (USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) +{ + 800f830: b580 push {r7, lr} + 800f832: b082 sub sp, #8 + 800f834: af00 add r7, sp, #0 + 800f836: 6078 str r0, [r7, #4] + 800f838: 6039 str r1, [r7, #0] + if (0x43 /* SET_ETHERNET_PACKET_FILTER */ == req->bRequest) + 800f83a: 683b ldr r3, [r7, #0] + 800f83c: 785b ldrb r3, [r3, #1] + 800f83e: 2b43 cmp r3, #67 ; 0x43 + 800f840: d109 bne.n 800f856 + { + notify.wIndex = req->wIndex; + 800f842: 683b ldr r3, [r7, #0] + 800f844: 889a ldrh r2, [r3, #4] + 800f846: 4b06 ldr r3, [pc, #24] ; (800f860 ) + 800f848: 809a strh r2, [r3, #4] + USBD_LL_Transmit(pdev, ECM_NOTIFICATION_IN_EP, (uint8_t *)¬ify, sizeof(notify)); + 800f84a: 4a05 ldr r2, [pc, #20] ; (800f860 ) + 800f84c: 6878 ldr r0, [r7, #4] + 800f84e: 2308 movs r3, #8 + 800f850: 2181 movs r1, #129 ; 0x81 + 800f852: f7fe ff5c bl 800e70e + } + + return USBD_OK; + 800f856: 2300 movs r3, #0 +} + 800f858: 0018 movs r0, r3 + 800f85a: 46bd mov sp, r7 + 800f85c: b002 add sp, #8 + 800f85e: bd80 pop {r7, pc} + 800f860: 20000094 .word 0x20000094 + +0800f864 : + +static void ecm_incoming_attempt(void) +{ + 800f864: b580 push {r7, lr} + 800f866: b082 sub sp, #8 + 800f868: af00 add r7, sp, #0 + int chunk_size; + + if (!ecm_tx_remaining || ecm_tx_busy) + 800f86a: 4b16 ldr r3, [pc, #88] ; (800f8c4 ) + 800f86c: 681b ldr r3, [r3, #0] + 800f86e: 2b00 cmp r3, #0 + 800f870: d024 beq.n 800f8bc + 800f872: 4b15 ldr r3, [pc, #84] ; (800f8c8 ) + 800f874: 681b ldr r3, [r3, #0] + 800f876: 2b00 cmp r3, #0 + 800f878: d120 bne.n 800f8bc + return; + + chunk_size = ecm_tx_remaining; + 800f87a: 4b12 ldr r3, [pc, #72] ; (800f8c4 ) + 800f87c: 681b ldr r3, [r3, #0] + 800f87e: 607b str r3, [r7, #4] + if (chunk_size > ECM_DATA_IN_SZ) + 800f880: 687b ldr r3, [r7, #4] + 800f882: 2b40 cmp r3, #64 ; 0x40 + 800f884: dd01 ble.n 800f88a + chunk_size = ECM_DATA_IN_SZ; + 800f886: 2340 movs r3, #64 ; 0x40 + 800f888: 607b str r3, [r7, #4] + + /* ST stack always returns a success code, so reading the return value is pointless */ + USBD_LL_Transmit(registered_pdev, ECM_DATA_IN_EP, ecm_tx_ptr, chunk_size); + 800f88a: 4b10 ldr r3, [pc, #64] ; (800f8cc ) + 800f88c: 6818 ldr r0, [r3, #0] + 800f88e: 4b10 ldr r3, [pc, #64] ; (800f8d0 ) + 800f890: 681a ldr r2, [r3, #0] + 800f892: 687b ldr r3, [r7, #4] + 800f894: b29b uxth r3, r3 + 800f896: 2182 movs r1, #130 ; 0x82 + 800f898: f7fe ff39 bl 800e70e + + ecm_tx_ptr += chunk_size; + 800f89c: 4b0c ldr r3, [pc, #48] ; (800f8d0 ) + 800f89e: 681a ldr r2, [r3, #0] + 800f8a0: 687b ldr r3, [r7, #4] + 800f8a2: 18d2 adds r2, r2, r3 + 800f8a4: 4b0a ldr r3, [pc, #40] ; (800f8d0 ) + 800f8a6: 601a str r2, [r3, #0] + ecm_tx_remaining -= chunk_size; + 800f8a8: 4b06 ldr r3, [pc, #24] ; (800f8c4 ) + 800f8aa: 681a ldr r2, [r3, #0] + 800f8ac: 687b ldr r3, [r7, #4] + 800f8ae: 1ad2 subs r2, r2, r3 + 800f8b0: 4b04 ldr r3, [pc, #16] ; (800f8c4 ) + 800f8b2: 601a str r2, [r3, #0] + ecm_tx_busy = 1; + 800f8b4: 4b04 ldr r3, [pc, #16] ; (800f8c8 ) + 800f8b6: 2201 movs r2, #1 + 800f8b8: 601a str r2, [r3, #0] + 800f8ba: e000 b.n 800f8be + return; + 800f8bc: 46c0 nop ; (mov r8, r8) +} + 800f8be: 46bd mov sp, r7 + 800f8c0: b002 add sp, #8 + 800f8c2: bd80 pop {r7, pc} + 800f8c4: 200028e4 .word 0x200028e4 + 800f8c8: 200028e8 .word 0x200028e8 + 800f8cc: 200024cc .word 0x200024cc + 800f8d0: 200028e0 .word 0x200028e0 + +0800f8d4 : + +static uint8_t USBD_ECM_DataIn (USBD_HandleTypeDef *pdev, uint8_t epnum) +{ + 800f8d4: b580 push {r7, lr} + 800f8d6: b082 sub sp, #8 + 800f8d8: af00 add r7, sp, #0 + 800f8da: 6078 str r0, [r7, #4] + 800f8dc: 000a movs r2, r1 + 800f8de: 1cfb adds r3, r7, #3 + 800f8e0: 701a strb r2, [r3, #0] + if (ECM_DATA_IN_EP == (epnum | 0x80)) + 800f8e2: 1cfb adds r3, r7, #3 + 800f8e4: 781b ldrb r3, [r3, #0] + 800f8e6: 2280 movs r2, #128 ; 0x80 + 800f8e8: 4252 negs r2, r2 + 800f8ea: 4313 orrs r3, r2 + 800f8ec: b2db uxtb r3, r3 + 800f8ee: 2b82 cmp r3, #130 ; 0x82 + 800f8f0: d10b bne.n 800f90a + { + ecm_tx_busy = 0; + 800f8f2: 4b08 ldr r3, [pc, #32] ; (800f914 ) + 800f8f4: 2200 movs r2, #0 + 800f8f6: 601a str r2, [r3, #0] + if (0 == ecm_tx_remaining) + 800f8f8: 4b07 ldr r3, [pc, #28] ; (800f918 ) + 800f8fa: 681b ldr r3, [r3, #0] + 800f8fc: 2b00 cmp r3, #0 + 800f8fe: d102 bne.n 800f906 + can_xmit = true; + 800f900: 4b06 ldr r3, [pc, #24] ; (800f91c ) + 800f902: 2201 movs r2, #1 + 800f904: 701a strb r2, [r3, #0] + ecm_incoming_attempt(); + 800f906: f7ff ffad bl 800f864 + } + + return USBD_OK; + 800f90a: 2300 movs r3, #0 +} + 800f90c: 0018 movs r0, r3 + 800f90e: 46bd mov sp, r7 + 800f910: b002 add sp, #8 + 800f912: bd80 pop {r7, pc} + 800f914: 200028e8 .word 0x200028e8 + 800f918: 200028e4 .word 0x200028e4 + 800f91c: 200028dc .word 0x200028dc + +0800f920 : + +static uint8_t USBD_ECM_DataOut (USBD_HandleTypeDef *pdev, uint8_t epnum) +{ + 800f920: b580 push {r7, lr} + 800f922: b084 sub sp, #16 + 800f924: af00 add r7, sp, #0 + 800f926: 6078 str r0, [r7, #4] + 800f928: 000a movs r2, r1 + 800f92a: 1cfb adds r3, r7, #3 + 800f92c: 701a strb r2, [r3, #0] + uint32_t RxLength; + + if (ECM_DATA_OUT_EP != epnum) + 800f92e: 1cfb adds r3, r7, #3 + 800f930: 781b ldrb r3, [r3, #0] + 800f932: 2b03 cmp r3, #3 + 800f934: d001 beq.n 800f93a + return USBD_OK; + 800f936: 2300 movs r3, #0 + 800f938: e021 b.n 800f97e + + /* Get the received data length */ + RxLength = USBD_LL_GetRxDataSize (pdev, epnum); + 800f93a: 1cfb adds r3, r7, #3 + 800f93c: 781a ldrb r2, [r3, #0] + 800f93e: 687b ldr r3, [r7, #4] + 800f940: 0011 movs r1, r2 + 800f942: 0018 movs r0, r3 + 800f944: f7fe ff35 bl 800e7b2 + 800f948: 0003 movs r3, r0 + 800f94a: 60fb str r3, [r7, #12] + + ecm_rx_index += RxLength; + 800f94c: 4b0e ldr r3, [pc, #56] ; (800f988 ) + 800f94e: 681b ldr r3, [r3, #0] + 800f950: 001a movs r2, r3 + 800f952: 68fb ldr r3, [r7, #12] + 800f954: 18d3 adds r3, r2, r3 + 800f956: 001a movs r2, r3 + 800f958: 4b0b ldr r3, [pc, #44] ; (800f988 ) + 800f95a: 601a str r2, [r3, #0] + + if (RxLength < ECM_DATA_OUT_SZ) + 800f95c: 68fb ldr r3, [r7, #12] + 800f95e: 2b3f cmp r3, #63 ; 0x3f + 800f960: d80a bhi.n 800f978 + { + usb_ecm_recv_callback(ecm_rx_buffer, ecm_rx_index); + 800f962: 4b09 ldr r3, [pc, #36] ; (800f988 ) + 800f964: 681a ldr r2, [r3, #0] + 800f966: 4b09 ldr r3, [pc, #36] ; (800f98c ) + 800f968: 0011 movs r1, r2 + 800f96a: 0018 movs r0, r3 + 800f96c: f7fe fb0a bl 800df84 + ecm_rx_index = 0; + 800f970: 4b05 ldr r3, [pc, #20] ; (800f988 ) + 800f972: 2200 movs r2, #0 + 800f974: 601a str r2, [r3, #0] + 800f976: e001 b.n 800f97c + } + else + { + /* Initiate next USB packet transfer */ + usb_ecm_recv_renew(); + 800f978: f7ff fed6 bl 800f728 + } + + return USBD_OK; + 800f97c: 2300 movs r3, #0 +} + 800f97e: 0018 movs r0, r3 + 800f980: 46bd mov sp, r7 + 800f982: b004 add sp, #16 + 800f984: bd80 pop {r7, pc} + 800f986: 46c0 nop ; (mov r8, r8) + 800f988: 200028d8 .word 0x200028d8 + 800f98c: 200024d0 .word 0x200024d0 + +0800f990 : + +static uint8_t USBD_ECM_SOF (USBD_HandleTypeDef *pdev) +{ + 800f990: b580 push {r7, lr} + 800f992: b082 sub sp, #8 + 800f994: af00 add r7, sp, #0 + 800f996: 6078 str r0, [r7, #4] + /* mop up for any failed USBD_LL_PrepareReceive() call */ + if (OutboundTransferNeedsRenewal) + 800f998: 4b11 ldr r3, [pc, #68] ; (800f9e0 ) + 800f99a: 781b ldrb r3, [r3, #0] + 800f99c: 2b00 cmp r3, #0 + 800f99e: d001 beq.n 800f9a4 + usb_ecm_recv_renew(); + 800f9a0: f7ff fec2 bl 800f728 + + if (ecm_tx_busy) + 800f9a4: 4b0f ldr r3, [pc, #60] ; (800f9e4 ) + 800f9a6: 681b ldr r3, [r3, #0] + 800f9a8: 2b00 cmp r3, #0 + 800f9aa: d012 beq.n 800f9d2 + { + /* ugly hack for ST stack sometimes not providing the DataOut callback */ + if (++ecm_tx_busy > 32) + 800f9ac: 4b0d ldr r3, [pc, #52] ; (800f9e4 ) + 800f9ae: 681b ldr r3, [r3, #0] + 800f9b0: 1c5a adds r2, r3, #1 + 800f9b2: 4b0c ldr r3, [pc, #48] ; (800f9e4 ) + 800f9b4: 601a str r2, [r3, #0] + 800f9b6: 4b0b ldr r3, [pc, #44] ; (800f9e4 ) + 800f9b8: 681b ldr r3, [r3, #0] + 800f9ba: 2b20 cmp r3, #32 + 800f9bc: dd09 ble.n 800f9d2 + { + ecm_tx_busy = 0; + 800f9be: 4b09 ldr r3, [pc, #36] ; (800f9e4 ) + 800f9c0: 2200 movs r2, #0 + 800f9c2: 601a str r2, [r3, #0] + if (0 == ecm_tx_remaining) + 800f9c4: 4b08 ldr r3, [pc, #32] ; (800f9e8 ) + 800f9c6: 681b ldr r3, [r3, #0] + 800f9c8: 2b00 cmp r3, #0 + 800f9ca: d102 bne.n 800f9d2 + can_xmit = true; + 800f9cc: 4b07 ldr r3, [pc, #28] ; (800f9ec ) + 800f9ce: 2201 movs r2, #1 + 800f9d0: 701a strb r2, [r3, #0] + } + } + + ecm_incoming_attempt(); + 800f9d2: f7ff ff47 bl 800f864 + + return USBD_OK; + 800f9d6: 2300 movs r3, #0 +} + 800f9d8: 0018 movs r0, r3 + 800f9da: 46bd mov sp, r7 + 800f9dc: b002 add sp, #8 + 800f9de: bd80 pop {r7, pc} + 800f9e0: 200028dd .word 0x200028dd + 800f9e4: 200028e8 .word 0x200028e8 + 800f9e8: 200028e4 .word 0x200028e4 + 800f9ec: 200028dc .word 0x200028dc + +0800f9f0 : + +static uint8_t USBD_ECM_EP0_RxReady (USBD_HandleTypeDef *pdev) +{ + 800f9f0: b580 push {r7, lr} + 800f9f2: b082 sub sp, #8 + 800f9f4: af00 add r7, sp, #0 + 800f9f6: 6078 str r0, [r7, #4] + return USBD_OK; + 800f9f8: 2300 movs r3, #0 +} + 800f9fa: 0018 movs r0, r3 + 800f9fc: 46bd mov sp, r7 + 800f9fe: b002 add sp, #8 + 800fa00: bd80 pop {r7, pc} + ... + +0800fa04 : + +static const uint8_t *USBD_ECM_GetFSCfgDesc (uint16_t *length) +{ + 800fa04: b580 push {r7, lr} + 800fa06: b082 sub sp, #8 + 800fa08: af00 add r7, sp, #0 + 800fa0a: 6078 str r0, [r7, #4] + *length = USBD_CfgFSDesc_len; + 800fa0c: 4b04 ldr r3, [pc, #16] ; (800fa20 ) + 800fa0e: 881a ldrh r2, [r3, #0] + 800fa10: 687b ldr r3, [r7, #4] + 800fa12: 801a strh r2, [r3, #0] + return USBD_CfgFSDesc_pnt; + 800fa14: 4b03 ldr r3, [pc, #12] ; (800fa24 ) + 800fa16: 681b ldr r3, [r3, #0] +} + 800fa18: 0018 movs r0, r3 + 800fa1a: 46bd mov sp, r7 + 800fa1c: b002 add sp, #8 + 800fa1e: bd80 pop {r7, pc} + 800fa20: 0800fe74 .word 0x0800fe74 + 800fa24: 0800fe70 .word 0x0800fe70 + +0800fa28 : + +uint8_t USBD_ECM_RegisterInterface(USBD_HandleTypeDef *pdev) +{ + 800fa28: b580 push {r7, lr} + 800fa2a: b082 sub sp, #8 + 800fa2c: af00 add r7, sp, #0 + 800fa2e: 6078 str r0, [r7, #4] + unsigned index; + + return USBD_OK; + 800fa30: 2300 movs r3, #0 +} + 800fa32: 0018 movs r0, r3 + 800fa34: 46bd mov sp, r7 + 800fa36: b002 add sp, #8 + 800fa38: bd80 pop {r7, pc} + +0800fa3a : + +void USBD_ECM_PMAConfig(PCD_HandleTypeDef *hpcd, uint32_t *pma_address) +{ + 800fa3a: b580 push {r7, lr} + 800fa3c: b082 sub sp, #8 + 800fa3e: af00 add r7, sp, #0 + 800fa40: 6078 str r0, [r7, #4] + 800fa42: 6039 str r1, [r7, #0] + /* allocate PMA memory for all endpoints associated with ECM */ + HAL_PCDEx_PMAConfig(hpcd, ECM_DATA_IN_EP, PCD_SNG_BUF, *pma_address); + 800fa44: 683b ldr r3, [r7, #0] + 800fa46: 681b ldr r3, [r3, #0] + 800fa48: 6878 ldr r0, [r7, #4] + 800fa4a: 2200 movs r2, #0 + 800fa4c: 2182 movs r1, #130 ; 0x82 + 800fa4e: f7f2 f83b bl 8001ac8 + *pma_address += ECM_DATA_IN_SZ; + 800fa52: 683b ldr r3, [r7, #0] + 800fa54: 681b ldr r3, [r3, #0] + 800fa56: 3340 adds r3, #64 ; 0x40 + 800fa58: 001a movs r2, r3 + 800fa5a: 683b ldr r3, [r7, #0] + 800fa5c: 601a str r2, [r3, #0] + HAL_PCDEx_PMAConfig(hpcd, ECM_DATA_OUT_EP, PCD_SNG_BUF, *pma_address); + 800fa5e: 683b ldr r3, [r7, #0] + 800fa60: 681b ldr r3, [r3, #0] + 800fa62: 6878 ldr r0, [r7, #4] + 800fa64: 2200 movs r2, #0 + 800fa66: 2103 movs r1, #3 + 800fa68: f7f2 f82e bl 8001ac8 + *pma_address += ECM_DATA_OUT_SZ; + 800fa6c: 683b ldr r3, [r7, #0] + 800fa6e: 681b ldr r3, [r3, #0] + 800fa70: 3340 adds r3, #64 ; 0x40 + 800fa72: 001a movs r2, r3 + 800fa74: 683b ldr r3, [r7, #0] + 800fa76: 601a str r2, [r3, #0] + HAL_PCDEx_PMAConfig(hpcd, ECM_NOTIFICATION_IN_EP, PCD_SNG_BUF, *pma_address); + 800fa78: 683b ldr r3, [r7, #0] + 800fa7a: 681b ldr r3, [r3, #0] + 800fa7c: 6878 ldr r0, [r7, #4] + 800fa7e: 2200 movs r2, #0 + 800fa80: 2181 movs r1, #129 ; 0x81 + 800fa82: f7f2 f821 bl 8001ac8 + *pma_address += ECM_NOTIFICATION_IN_SZ; + 800fa86: 683b ldr r3, [r7, #0] + 800fa88: 681b ldr r3, [r3, #0] + 800fa8a: 3340 adds r3, #64 ; 0x40 + 800fa8c: 001a movs r2, r3 + 800fa8e: 683b ldr r3, [r7, #0] + 800fa90: 601a str r2, [r3, #0] +} + 800fa92: 46c0 nop ; (mov r8, r8) + 800fa94: 46bd mov sp, r7 + 800fa96: b002 add sp, #8 + 800fa98: bd80 pop {r7, pc} + ... + +0800fa9c : + +bool usb_ecm_can_xmit(void) +{ + 800fa9c: b580 push {r7, lr} + 800fa9e: b082 sub sp, #8 + 800faa0: af00 add r7, sp, #0 + __ASM volatile ("cpsid i" : : : "memory"); + 800faa2: b672 cpsid i + bool outcome; + + __disable_irq(); + outcome = can_xmit; + 800faa4: 1dfb adds r3, r7, #7 + 800faa6: 4a05 ldr r2, [pc, #20] ; (800fabc ) + 800faa8: 7812 ldrb r2, [r2, #0] + 800faaa: 701a strb r2, [r3, #0] + __ASM volatile ("cpsie i" : : : "memory"); + 800faac: b662 cpsie i + __enable_irq(); + + return outcome; + 800faae: 1dfb adds r3, r7, #7 + 800fab0: 781b ldrb r3, [r3, #0] +} + 800fab2: 0018 movs r0, r3 + 800fab4: 46bd mov sp, r7 + 800fab6: b002 add sp, #8 + 800fab8: bd80 pop {r7, pc} + 800faba: 46c0 nop ; (mov r8, r8) + 800fabc: 200028dc .word 0x200028dc + +0800fac0 : + +void usb_ecm_xmit_packet(struct pbuf *p) +{ + 800fac0: b580 push {r7, lr} + 800fac2: b086 sub sp, #24 + 800fac4: af00 add r7, sp, #0 + 800fac6: 6078 str r0, [r7, #4] + struct pbuf *q; + int packet_size; + uint8_t *data; + + if (!registered_pdev || !can_xmit) + 800fac8: 4b1f ldr r3, [pc, #124] ; (800fb48 ) + 800faca: 681b ldr r3, [r3, #0] + 800facc: 2b00 cmp r3, #0 + 800face: d037 beq.n 800fb40 + 800fad0: 4b1e ldr r3, [pc, #120] ; (800fb4c ) + 800fad2: 781b ldrb r3, [r3, #0] + 800fad4: 2201 movs r2, #1 + 800fad6: 4053 eors r3, r2 + 800fad8: b2db uxtb r3, r3 + 800fada: 2b00 cmp r3, #0 + 800fadc: d130 bne.n 800fb40 + return; + + data = ecm_tx_buffer; + 800fade: 4b1c ldr r3, [pc, #112] ; (800fb50 ) + 800fae0: 60fb str r3, [r7, #12] + packet_size = 0; + 800fae2: 2300 movs r3, #0 + 800fae4: 613b str r3, [r7, #16] + for(q = p; q != NULL; q = q->next) + 800fae6: 687b ldr r3, [r7, #4] + 800fae8: 617b str r3, [r7, #20] + 800faea: e017 b.n 800fb1c + { + memcpy(data, q->payload, q->len); + 800faec: 697b ldr r3, [r7, #20] + 800faee: 6859 ldr r1, [r3, #4] + 800faf0: 697b ldr r3, [r7, #20] + 800faf2: 895b ldrh r3, [r3, #10] + 800faf4: 001a movs r2, r3 + 800faf6: 68fb ldr r3, [r7, #12] + 800faf8: 0018 movs r0, r3 + 800fafa: f000 f8d2 bl 800fca2 + data += q->len; + 800fafe: 697b ldr r3, [r7, #20] + 800fb00: 895b ldrh r3, [r3, #10] + 800fb02: 001a movs r2, r3 + 800fb04: 68fb ldr r3, [r7, #12] + 800fb06: 189b adds r3, r3, r2 + 800fb08: 60fb str r3, [r7, #12] + packet_size += q->len; + 800fb0a: 697b ldr r3, [r7, #20] + 800fb0c: 895b ldrh r3, [r3, #10] + 800fb0e: 001a movs r2, r3 + 800fb10: 693b ldr r3, [r7, #16] + 800fb12: 189b adds r3, r3, r2 + 800fb14: 613b str r3, [r7, #16] + for(q = p; q != NULL; q = q->next) + 800fb16: 697b ldr r3, [r7, #20] + 800fb18: 681b ldr r3, [r3, #0] + 800fb1a: 617b str r3, [r7, #20] + 800fb1c: 697b ldr r3, [r7, #20] + 800fb1e: 2b00 cmp r3, #0 + 800fb20: d1e4 bne.n 800faec + __ASM volatile ("cpsid i" : : : "memory"); + 800fb22: b672 cpsid i + } + + __disable_irq(); + can_xmit = false; + 800fb24: 4b09 ldr r3, [pc, #36] ; (800fb4c ) + 800fb26: 2200 movs r2, #0 + 800fb28: 701a strb r2, [r3, #0] + ecm_tx_ptr = ecm_tx_buffer; + 800fb2a: 4b0a ldr r3, [pc, #40] ; (800fb54 ) + 800fb2c: 4a08 ldr r2, [pc, #32] ; (800fb50 ) + 800fb2e: 601a str r2, [r3, #0] + ecm_tx_remaining = packet_size; + 800fb30: 4b09 ldr r3, [pc, #36] ; (800fb58 ) + 800fb32: 693a ldr r2, [r7, #16] + 800fb34: 601a str r2, [r3, #0] + copy_length = packet_size; + 800fb36: 4b09 ldr r3, [pc, #36] ; (800fb5c ) + 800fb38: 693a ldr r2, [r7, #16] + 800fb3a: 601a str r2, [r3, #0] + __ASM volatile ("cpsie i" : : : "memory"); + 800fb3c: b662 cpsie i + 800fb3e: e000 b.n 800fb42 + return; + 800fb40: 46c0 nop ; (mov r8, r8) + __enable_irq(); +} + 800fb42: 46bd mov sp, r7 + 800fb44: b006 add sp, #24 + 800fb46: bd80 pop {r7, pc} + 800fb48: 200024cc .word 0x200024cc + 800fb4c: 200028dc .word 0x200028dc + 800fb50: 200026d4 .word 0x200026d4 + 800fb54: 200028e0 .word 0x200028e0 + 800fb58: 200028e4 .word 0x200028e4 + 800fb5c: 200028ec .word 0x200028ec + +0800fb60 : +* @retval status +*/ +USBD_StatusTypeDef USBD_CtlSendData (USBD_HandleTypeDef *pdev, + uint8_t *pbuf, + uint16_t len) +{ + 800fb60: b580 push {r7, lr} + 800fb62: b084 sub sp, #16 + 800fb64: af00 add r7, sp, #0 + 800fb66: 60f8 str r0, [r7, #12] + 800fb68: 60b9 str r1, [r7, #8] + 800fb6a: 1dbb adds r3, r7, #6 + 800fb6c: 801a strh r2, [r3, #0] + /* Set EP0 State */ + pdev->ep0_state = USBD_EP0_DATA_IN; + 800fb6e: 68fa ldr r2, [r7, #12] + 800fb70: 23fa movs r3, #250 ; 0xfa + 800fb72: 005b lsls r3, r3, #1 + 800fb74: 2102 movs r1, #2 + 800fb76: 50d1 str r1, [r2, r3] + pdev->ep_in[0].total_length = len; + 800fb78: 1dbb adds r3, r7, #6 + 800fb7a: 881a ldrh r2, [r3, #0] + 800fb7c: 68fb ldr r3, [r7, #12] + 800fb7e: 619a str r2, [r3, #24] + pdev->ep_in[0].rem_length = len; + 800fb80: 1dbb adds r3, r7, #6 + 800fb82: 881a ldrh r2, [r3, #0] + 800fb84: 68fb ldr r3, [r7, #12] + 800fb86: 61da str r2, [r3, #28] + /* Start the transfer */ + USBD_LL_Transmit (pdev, 0x00, pbuf, len); + 800fb88: 1dbb adds r3, r7, #6 + 800fb8a: 881b ldrh r3, [r3, #0] + 800fb8c: 68ba ldr r2, [r7, #8] + 800fb8e: 68f8 ldr r0, [r7, #12] + 800fb90: 2100 movs r1, #0 + 800fb92: f7fe fdbc bl 800e70e + + return USBD_OK; + 800fb96: 2300 movs r3, #0 +} + 800fb98: 0018 movs r0, r3 + 800fb9a: 46bd mov sp, r7 + 800fb9c: b004 add sp, #16 + 800fb9e: bd80 pop {r7, pc} + +0800fba0 : +* @retval status +*/ +USBD_StatusTypeDef USBD_CtlContinueSendData (USBD_HandleTypeDef *pdev, + uint8_t *pbuf, + uint16_t len) +{ + 800fba0: b580 push {r7, lr} + 800fba2: b084 sub sp, #16 + 800fba4: af00 add r7, sp, #0 + 800fba6: 60f8 str r0, [r7, #12] + 800fba8: 60b9 str r1, [r7, #8] + 800fbaa: 1dbb adds r3, r7, #6 + 800fbac: 801a strh r2, [r3, #0] + /* Start the next transfer */ + USBD_LL_Transmit (pdev, 0x00, pbuf, len); + 800fbae: 1dbb adds r3, r7, #6 + 800fbb0: 881b ldrh r3, [r3, #0] + 800fbb2: 68ba ldr r2, [r7, #8] + 800fbb4: 68f8 ldr r0, [r7, #12] + 800fbb6: 2100 movs r1, #0 + 800fbb8: f7fe fda9 bl 800e70e + + return USBD_OK; + 800fbbc: 2300 movs r3, #0 +} + 800fbbe: 0018 movs r0, r3 + 800fbc0: 46bd mov sp, r7 + 800fbc2: b004 add sp, #16 + 800fbc4: bd80 pop {r7, pc} + +0800fbc6 : +* @retval status +*/ +USBD_StatusTypeDef USBD_CtlContinueRx (USBD_HandleTypeDef *pdev, + uint8_t *pbuf, + uint16_t len) +{ + 800fbc6: b580 push {r7, lr} + 800fbc8: b084 sub sp, #16 + 800fbca: af00 add r7, sp, #0 + 800fbcc: 60f8 str r0, [r7, #12] + 800fbce: 60b9 str r1, [r7, #8] + 800fbd0: 1dbb adds r3, r7, #6 + 800fbd2: 801a strh r2, [r3, #0] + + USBD_LL_PrepareReceive (pdev, + 800fbd4: 1dbb adds r3, r7, #6 + 800fbd6: 881b ldrh r3, [r3, #0] + 800fbd8: 68ba ldr r2, [r7, #8] + 800fbda: 68f8 ldr r0, [r7, #12] + 800fbdc: 2100 movs r1, #0 + 800fbde: f7fe fdbf bl 800e760 + 0, + pbuf, + len); + return USBD_OK; + 800fbe2: 2300 movs r3, #0 +} + 800fbe4: 0018 movs r0, r3 + 800fbe6: 46bd mov sp, r7 + 800fbe8: b004 add sp, #16 + 800fbea: bd80 pop {r7, pc} + +0800fbec : +* send zero lzngth packet on the ctl pipe +* @param pdev: device instance +* @retval status +*/ +USBD_StatusTypeDef USBD_CtlSendStatus (USBD_HandleTypeDef *pdev) +{ + 800fbec: b580 push {r7, lr} + 800fbee: b082 sub sp, #8 + 800fbf0: af00 add r7, sp, #0 + 800fbf2: 6078 str r0, [r7, #4] + + /* Set EP0 State */ + pdev->ep0_state = USBD_EP0_STATUS_IN; + 800fbf4: 687a ldr r2, [r7, #4] + 800fbf6: 23fa movs r3, #250 ; 0xfa + 800fbf8: 005b lsls r3, r3, #1 + 800fbfa: 2104 movs r1, #4 + 800fbfc: 50d1 str r1, [r2, r3] + + /* Start the transfer */ + USBD_LL_Transmit (pdev, 0x00, NULL, 0); + 800fbfe: 6878 ldr r0, [r7, #4] + 800fc00: 2300 movs r3, #0 + 800fc02: 2200 movs r2, #0 + 800fc04: 2100 movs r1, #0 + 800fc06: f7fe fd82 bl 800e70e + + return USBD_OK; + 800fc0a: 2300 movs r3, #0 +} + 800fc0c: 0018 movs r0, r3 + 800fc0e: 46bd mov sp, r7 + 800fc10: b002 add sp, #8 + 800fc12: bd80 pop {r7, pc} + +0800fc14 : +* receive zero lzngth packet on the ctl pipe +* @param pdev: device instance +* @retval status +*/ +USBD_StatusTypeDef USBD_CtlReceiveStatus (USBD_HandleTypeDef *pdev) +{ + 800fc14: b580 push {r7, lr} + 800fc16: b082 sub sp, #8 + 800fc18: af00 add r7, sp, #0 + 800fc1a: 6078 str r0, [r7, #4] + /* Set EP0 State */ + pdev->ep0_state = USBD_EP0_STATUS_OUT; + 800fc1c: 687a ldr r2, [r7, #4] + 800fc1e: 23fa movs r3, #250 ; 0xfa + 800fc20: 005b lsls r3, r3, #1 + 800fc22: 2105 movs r1, #5 + 800fc24: 50d1 str r1, [r2, r3] + + /* Start the transfer */ + USBD_LL_PrepareReceive ( pdev, + 800fc26: 6878 ldr r0, [r7, #4] + 800fc28: 2300 movs r3, #0 + 800fc2a: 2200 movs r2, #0 + 800fc2c: 2100 movs r1, #0 + 800fc2e: f7fe fd97 bl 800e760 + 0, + NULL, + 0); + + return USBD_OK; + 800fc32: 2300 movs r3, #0 +} + 800fc34: 0018 movs r0, r3 + 800fc36: 46bd mov sp, r7 + 800fc38: b002 add sp, #8 + 800fc3a: bd80 pop {r7, pc} + +0800fc3c <__libc_init_array>: + 800fc3c: b570 push {r4, r5, r6, lr} + 800fc3e: 2600 movs r6, #0 + 800fc40: 4d0c ldr r5, [pc, #48] ; (800fc74 <__libc_init_array+0x38>) + 800fc42: 4c0d ldr r4, [pc, #52] ; (800fc78 <__libc_init_array+0x3c>) + 800fc44: 1b64 subs r4, r4, r5 + 800fc46: 10a4 asrs r4, r4, #2 + 800fc48: 42a6 cmp r6, r4 + 800fc4a: d109 bne.n 800fc60 <__libc_init_array+0x24> + 800fc4c: 2600 movs r6, #0 + 800fc4e: f000 f839 bl 800fcc4 <_init> + 800fc52: 4d0a ldr r5, [pc, #40] ; (800fc7c <__libc_init_array+0x40>) + 800fc54: 4c0a ldr r4, [pc, #40] ; (800fc80 <__libc_init_array+0x44>) + 800fc56: 1b64 subs r4, r4, r5 + 800fc58: 10a4 asrs r4, r4, #2 + 800fc5a: 42a6 cmp r6, r4 + 800fc5c: d105 bne.n 800fc6a <__libc_init_array+0x2e> + 800fc5e: bd70 pop {r4, r5, r6, pc} + 800fc60: 00b3 lsls r3, r6, #2 + 800fc62: 58eb ldr r3, [r5, r3] + 800fc64: 4798 blx r3 + 800fc66: 3601 adds r6, #1 + 800fc68: e7ee b.n 800fc48 <__libc_init_array+0xc> + 800fc6a: 00b3 lsls r3, r6, #2 + 800fc6c: 58eb ldr r3, [r5, r3] + 800fc6e: 4798 blx r3 + 800fc70: 3601 adds r6, #1 + 800fc72: e7f2 b.n 800fc5a <__libc_init_array+0x1e> + 800fc74: 0800fea8 .word 0x0800fea8 + 800fc78: 0800fea8 .word 0x0800fea8 + 800fc7c: 0800fea8 .word 0x0800fea8 + 800fc80: 0800feac .word 0x0800feac + +0800fc84 : + 800fc84: b530 push {r4, r5, lr} + 800fc86: 2400 movs r4, #0 + 800fc88: 42a2 cmp r2, r4 + 800fc8a: d101 bne.n 800fc90 + 800fc8c: 2000 movs r0, #0 + 800fc8e: e005 b.n 800fc9c + 800fc90: 5d03 ldrb r3, [r0, r4] + 800fc92: 1c65 adds r5, r4, #1 + 800fc94: 5d0c ldrb r4, [r1, r4] + 800fc96: 42a3 cmp r3, r4 + 800fc98: d001 beq.n 800fc9e + 800fc9a: 1b18 subs r0, r3, r4 + 800fc9c: bd30 pop {r4, r5, pc} + 800fc9e: 002c movs r4, r5 + 800fca0: e7f2 b.n 800fc88 + +0800fca2 : + 800fca2: 2300 movs r3, #0 + 800fca4: b510 push {r4, lr} + 800fca6: 429a cmp r2, r3 + 800fca8: d100 bne.n 800fcac + 800fcaa: bd10 pop {r4, pc} + 800fcac: 5ccc ldrb r4, [r1, r3] + 800fcae: 54c4 strb r4, [r0, r3] + 800fcb0: 3301 adds r3, #1 + 800fcb2: e7f8 b.n 800fca6 + +0800fcb4 : + 800fcb4: 0003 movs r3, r0 + 800fcb6: 1812 adds r2, r2, r0 + 800fcb8: 4293 cmp r3, r2 + 800fcba: d100 bne.n 800fcbe + 800fcbc: 4770 bx lr + 800fcbe: 7019 strb r1, [r3, #0] + 800fcc0: 3301 adds r3, #1 + 800fcc2: e7f9 b.n 800fcb8 + +0800fcc4 <_init>: + 800fcc4: b5f8 push {r3, r4, r5, r6, r7, lr} + 800fcc6: 46c0 nop ; (mov r8, r8) + 800fcc8: bcf8 pop {r3, r4, r5, r6, r7} + 800fcca: bc08 pop {r3} + 800fccc: 469e mov lr, r3 + 800fcce: 4770 bx lr + +0800fcd0 <_fini>: + 800fcd0: b5f8 push {r3, r4, r5, r6, r7, lr} + 800fcd2: 46c0 nop ; (mov r8, r8) + 800fcd4: bcf8 pop {r3, r4, r5, r6, r7} + 800fcd6: bc08 pop {r3} + 800fcd8: 469e mov lr, r3 + 800fcda: 4770 bx lr diff --git a/test/STM32F072C8T6/bin/stm32f072_ecm.map b/test/STM32F072C8T6/bin/stm32f072_ecm.map new file mode 100644 index 0000000..61960a5 --- /dev/null +++ b/test/STM32F072C8T6/bin/stm32f072_ecm.map @@ -0,0 +1,8032 @@ +Archive member included to satisfy reference by file (symbol) + +c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-errno.o) + Core/Src/syscalls.o (__errno) +c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-exit.o) + c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m/crt0.o (exit) +c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-impure.o) + c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-exit.o) (_global_impure_ptr) +c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-init.o) + c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m/crt0.o (__libc_init_array) +c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-memcmp.o) + ecm_src/dhcp-server/dhserver.o (memcmp) +c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-memcpy-stub.o) + ecm_src/dhcp-server/dhserver.o (memcpy) +c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-memset.o) + c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m/crt0.o (memset) +c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-strcmp.o) + ecm_src/src/ecm_main.o (strcmp) +c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-strlen.o) + ecm_src/dhcp-server/dhserver.o (strlen) +c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v6-m\libgcc.a(_udivsi3.o) + Core/Src/system_stm32f0xx.o (__aeabi_uidiv) +c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v6-m\libgcc.a(_divsi3.o) + ecm_src/lwip-1.4.1/src/core/tcp_in.o (__aeabi_idiv) +c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v6-m\libgcc.a(_dvmd_tls.o) + c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v6-m\libgcc.a(_udivsi3.o) (__aeabi_idiv0) + +Allocating common symbols +Common symbol size file + +current_iphdr_src 0x4 ecm_src/lwip-1.4.1/src/core/ipv4/ip.o +netif_list 0x4 ecm_src/lwip-1.4.1/src/core/netif.o +hUsbDeviceFS 0x220 ecm_src/src/usb_device.o +tcp_active_pcbs_changed + 0x1 ecm_src/lwip-1.4.1/src/core/tcp.o +tcp_active_pcbs 0x4 ecm_src/lwip-1.4.1/src/core/tcp.o +udp_pcbs 0x4 ecm_src/lwip-1.4.1/src/core/udp.o +current_netif 0x4 ecm_src/lwip-1.4.1/src/core/ipv4/ip.o +tcp_ticks 0x4 ecm_src/lwip-1.4.1/src/core/tcp.o +tcp_listen_pcbs 0x4 ecm_src/lwip-1.4.1/src/core/tcp.o +sysTimeTicks 0x4 ecm_src/src/time.o +sysTimeDelayCounter + 0x4 ecm_src/src/time.o +dhcp_data 0x204 ecm_src/dhcp-server/dhserver.o +current_iphdr_dest 0x4 ecm_src/lwip-1.4.1/src/core/ipv4/ip.o +uwTick 0x4 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o +pFlash 0x20 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o +tcp_tmp_pcb 0x4 ecm_src/lwip-1.4.1/src/core/tcp.o +tcp_input_pcb 0x4 ecm_src/lwip-1.4.1/src/core/tcp_in.o +current_header 0x4 ecm_src/lwip-1.4.1/src/core/ipv4/ip.o +tcp_bound_pcbs 0x4 ecm_src/lwip-1.4.1/src/core/tcp.o +pbuf_free_ooseq_pending + 0x1 ecm_src/lwip-1.4.1/src/core/pbuf.o +tcp_tw_pcbs 0x4 ecm_src/lwip-1.4.1/src/core/tcp.o +lwip_stats 0x116 ecm_src/lwip-1.4.1/src/core/stats.o +netif_default 0x4 ecm_src/lwip-1.4.1/src/core/netif.o +hpcd_USB_FS 0x274 ecm_src/src/usbd_conf.o +ram_heap 0x654 ecm_src/lwip-1.4.1/src/core/mem.o + +Discarded input sections + + .text 0x0000000000000000 0x0 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v6-m/crti.o + .data 0x0000000000000000 0x0 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v6-m/crti.o + .bss 0x0000000000000000 0x0 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v6-m/crti.o + .data 0x0000000000000000 0x4 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v6-m/crtbegin.o + .text 0x0000000000000000 0x78 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m/crt0.o + .data 0x0000000000000000 0x0 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m/crt0.o + .bss 0x0000000000000000 0x0 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m/crt0.o + .ARM.extab 0x0000000000000000 0x0 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m/crt0.o + .ARM.exidx 0x0000000000000000 0x8 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m/crt0.o + .ARM.attributes + 0x0000000000000000 0x1b c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m/crt0.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/main.o + .text 0x0000000000000000 0x0 Core/Src/main.o + .data 0x0000000000000000 0x0 Core/Src/main.o + .bss 0x0000000000000000 0x0 Core/Src/main.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_hal_msp.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_hal_msp.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_hal_msp.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_hal_msp.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_hal_msp.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_hal_msp.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_hal_msp.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_hal_msp.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_hal_msp.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_hal_msp.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_hal_msp.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_hal_msp.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_hal_msp.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_hal_msp.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_hal_msp.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_hal_msp.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_hal_msp.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_hal_msp.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_hal_msp.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_hal_msp.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_hal_msp.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_hal_msp.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_hal_msp.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_hal_msp.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_hal_msp.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_hal_msp.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_hal_msp.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_hal_msp.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_hal_msp.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_hal_msp.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_hal_msp.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_hal_msp.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_hal_msp.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_hal_msp.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_hal_msp.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_hal_msp.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_hal_msp.o + .text 0x0000000000000000 0x0 Core/Src/stm32f0xx_hal_msp.o + .data 0x0000000000000000 0x0 Core/Src/stm32f0xx_hal_msp.o + .bss 0x0000000000000000 0x0 Core/Src/stm32f0xx_hal_msp.o + .debug_macro 0x0000000000000000 0xa48 Core/Src/stm32f0xx_hal_msp.o + .debug_macro 0x0000000000000000 0x12d Core/Src/stm32f0xx_hal_msp.o + .debug_macro 0x0000000000000000 0x2e Core/Src/stm32f0xx_hal_msp.o + .debug_macro 0x0000000000000000 0x22 Core/Src/stm32f0xx_hal_msp.o + .debug_macro 0x0000000000000000 0x22 Core/Src/stm32f0xx_hal_msp.o + .debug_macro 0x0000000000000000 0x8e Core/Src/stm32f0xx_hal_msp.o + .debug_macro 0x0000000000000000 0x51 Core/Src/stm32f0xx_hal_msp.o + .debug_macro 0x0000000000000000 0xef Core/Src/stm32f0xx_hal_msp.o + .debug_macro 0x0000000000000000 0x6a Core/Src/stm32f0xx_hal_msp.o + .debug_macro 0x0000000000000000 0x1df Core/Src/stm32f0xx_hal_msp.o + .debug_macro 0x0000000000000000 0x1c Core/Src/stm32f0xx_hal_msp.o + .debug_macro 0x0000000000000000 0x22 Core/Src/stm32f0xx_hal_msp.o + .debug_macro 0x0000000000000000 0xb5 Core/Src/stm32f0xx_hal_msp.o + .debug_macro 0x0000000000000000 0x391 Core/Src/stm32f0xx_hal_msp.o + .debug_macro 0x0000000000000000 0xfe50 Core/Src/stm32f0xx_hal_msp.o + .debug_macro 0x0000000000000000 0x3c Core/Src/stm32f0xx_hal_msp.o + .debug_macro 0x0000000000000000 0x174 Core/Src/stm32f0xx_hal_msp.o + .debug_macro 0x0000000000000000 0x53 Core/Src/stm32f0xx_hal_msp.o + .debug_macro 0x0000000000000000 0x946 Core/Src/stm32f0xx_hal_msp.o + .debug_macro 0x0000000000000000 0x5f3 Core/Src/stm32f0xx_hal_msp.o + .debug_macro 0x0000000000000000 0x12f Core/Src/stm32f0xx_hal_msp.o + .debug_macro 0x0000000000000000 0x1a7 Core/Src/stm32f0xx_hal_msp.o + .debug_macro 0x0000000000000000 0x1a7 Core/Src/stm32f0xx_hal_msp.o + .debug_macro 0x0000000000000000 0x22c Core/Src/stm32f0xx_hal_msp.o + .debug_macro 0x0000000000000000 0x34 Core/Src/stm32f0xx_hal_msp.o + .debug_macro 0x0000000000000000 0x43 Core/Src/stm32f0xx_hal_msp.o + .debug_macro 0x0000000000000000 0x28 Core/Src/stm32f0xx_hal_msp.o + .debug_macro 0x0000000000000000 0xb0 Core/Src/stm32f0xx_hal_msp.o + .debug_macro 0x0000000000000000 0x217 Core/Src/stm32f0xx_hal_msp.o + .debug_macro 0x0000000000000000 0x22c Core/Src/stm32f0xx_hal_msp.o + .debug_macro 0x0000000000000000 0x5f Core/Src/stm32f0xx_hal_msp.o + .debug_macro 0x0000000000000000 0xa5 Core/Src/stm32f0xx_hal_msp.o + .debug_macro 0x0000000000000000 0x65 Core/Src/stm32f0xx_hal_msp.o + .debug_macro 0x0000000000000000 0x234 Core/Src/stm32f0xx_hal_msp.o + .debug_macro 0x0000000000000000 0x4c Core/Src/stm32f0xx_hal_msp.o + .debug_macro 0x0000000000000000 0x16d Core/Src/stm32f0xx_hal_msp.o + .debug_macro 0x0000000000000000 0x130 Core/Src/stm32f0xx_hal_msp.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_it.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_it.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_it.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_it.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_it.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_it.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_it.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_it.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_it.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_it.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_it.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_it.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_it.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_it.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_it.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_it.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_it.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_it.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_it.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_it.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_it.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_it.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_it.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_it.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_it.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_it.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_it.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_it.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_it.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_it.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_it.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_it.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_it.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_it.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_it.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_it.o + .group 0x0000000000000000 0xc Core/Src/stm32f0xx_it.o + .text 0x0000000000000000 0x0 Core/Src/stm32f0xx_it.o + .data 0x0000000000000000 0x0 Core/Src/stm32f0xx_it.o + .bss 0x0000000000000000 0x0 Core/Src/stm32f0xx_it.o + .debug_macro 0x0000000000000000 0xa48 Core/Src/stm32f0xx_it.o + .debug_macro 0x0000000000000000 0x12d Core/Src/stm32f0xx_it.o + .debug_macro 0x0000000000000000 0x2e Core/Src/stm32f0xx_it.o + .debug_macro 0x0000000000000000 0x22 Core/Src/stm32f0xx_it.o + .debug_macro 0x0000000000000000 0x22 Core/Src/stm32f0xx_it.o + .debug_macro 0x0000000000000000 0x8e Core/Src/stm32f0xx_it.o + .debug_macro 0x0000000000000000 0x51 Core/Src/stm32f0xx_it.o + .debug_macro 0x0000000000000000 0xef Core/Src/stm32f0xx_it.o + .debug_macro 0x0000000000000000 0x6a Core/Src/stm32f0xx_it.o + .debug_macro 0x0000000000000000 0x1df Core/Src/stm32f0xx_it.o + .debug_macro 0x0000000000000000 0x1c Core/Src/stm32f0xx_it.o + .debug_macro 0x0000000000000000 0x22 Core/Src/stm32f0xx_it.o + .debug_macro 0x0000000000000000 0xb5 Core/Src/stm32f0xx_it.o + .debug_macro 0x0000000000000000 0x391 Core/Src/stm32f0xx_it.o + .debug_macro 0x0000000000000000 0xfe50 Core/Src/stm32f0xx_it.o + .debug_macro 0x0000000000000000 0x3c Core/Src/stm32f0xx_it.o + .debug_macro 0x0000000000000000 0x174 Core/Src/stm32f0xx_it.o + .debug_macro 0x0000000000000000 0x53 Core/Src/stm32f0xx_it.o + .debug_macro 0x0000000000000000 0x946 Core/Src/stm32f0xx_it.o + .debug_macro 0x0000000000000000 0x5f3 Core/Src/stm32f0xx_it.o + .debug_macro 0x0000000000000000 0x12f Core/Src/stm32f0xx_it.o + .debug_macro 0x0000000000000000 0x1a7 Core/Src/stm32f0xx_it.o + .debug_macro 0x0000000000000000 0x1a7 Core/Src/stm32f0xx_it.o + .debug_macro 0x0000000000000000 0x22c Core/Src/stm32f0xx_it.o + .debug_macro 0x0000000000000000 0x34 Core/Src/stm32f0xx_it.o + .debug_macro 0x0000000000000000 0x43 Core/Src/stm32f0xx_it.o + .debug_macro 0x0000000000000000 0x28 Core/Src/stm32f0xx_it.o + .debug_macro 0x0000000000000000 0xb0 Core/Src/stm32f0xx_it.o + .debug_macro 0x0000000000000000 0x217 Core/Src/stm32f0xx_it.o + .debug_macro 0x0000000000000000 0x22c Core/Src/stm32f0xx_it.o + .debug_macro 0x0000000000000000 0x5f Core/Src/stm32f0xx_it.o + .debug_macro 0x0000000000000000 0xa5 Core/Src/stm32f0xx_it.o + .debug_macro 0x0000000000000000 0x65 Core/Src/stm32f0xx_it.o + .debug_macro 0x0000000000000000 0x234 Core/Src/stm32f0xx_it.o + .debug_macro 0x0000000000000000 0x4c Core/Src/stm32f0xx_it.o + .debug_macro 0x0000000000000000 0x16d Core/Src/stm32f0xx_it.o + .debug_macro 0x0000000000000000 0x130 Core/Src/stm32f0xx_it.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/syscalls.o + .text 0x0000000000000000 0x0 Core/Src/syscalls.o + .data 0x0000000000000000 0x0 Core/Src/syscalls.o + .bss 0x0000000000000000 0x0 Core/Src/syscalls.o + .bss.__env 0x0000000000000000 0x4 Core/Src/syscalls.o + .data.environ 0x0000000000000000 0x4 Core/Src/syscalls.o + .text.initialise_monitor_handles + 0x0000000000000000 0xa Core/Src/syscalls.o + .text._getpid 0x0000000000000000 0xc Core/Src/syscalls.o + .text._kill 0x0000000000000000 0x20 Core/Src/syscalls.o + .text._exit 0x0000000000000000 0x18 Core/Src/syscalls.o + .text._read 0x0000000000000000 0x3a Core/Src/syscalls.o + .text._write 0x0000000000000000 0x38 Core/Src/syscalls.o + .text._close 0x0000000000000000 0x14 Core/Src/syscalls.o + .text._fstat 0x0000000000000000 0x1c Core/Src/syscalls.o + .text._isatty 0x0000000000000000 0x12 Core/Src/syscalls.o + .text._lseek 0x0000000000000000 0x16 Core/Src/syscalls.o + .text._open 0x0000000000000000 0x1c Core/Src/syscalls.o + .text._wait 0x0000000000000000 0x1e Core/Src/syscalls.o + .text._unlink 0x0000000000000000 0x1e Core/Src/syscalls.o + .text._times 0x0000000000000000 0x14 Core/Src/syscalls.o + .text._stat 0x0000000000000000 0x1c Core/Src/syscalls.o + .text._link 0x0000000000000000 0x20 Core/Src/syscalls.o + .text._fork 0x0000000000000000 0x18 Core/Src/syscalls.o + .text._execve 0x0000000000000000 0x22 Core/Src/syscalls.o + .debug_info 0x0000000000000000 0xf57 Core/Src/syscalls.o + .debug_abbrev 0x0000000000000000 0x282 Core/Src/syscalls.o + .debug_aranges + 0x0000000000000000 0xa8 Core/Src/syscalls.o + .debug_ranges 0x0000000000000000 0x98 Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x399 Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0xa48 Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x22 Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x40 Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x18 Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x94 Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x3c Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x34 Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x22 Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x57 Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0xef Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x6a Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x1df Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x174 Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x2e Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x22 Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x1c Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x22 Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0xb5 Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x391 Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0xfe50 Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x3c Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x12d Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x53 Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x946 Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x5f3 Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x12f Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x1a7 Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x1a7 Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x22c Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x34 Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x43 Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x28 Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0xb0 Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x217 Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x22c Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x5f Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0xa5 Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x65 Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x234 Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x4c Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x16d Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x130 Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x10 Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x32a Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x10 Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x52 Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x1f Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x43 Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x20 Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x1c Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x52 Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x40 Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x10 Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x40 Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0xd7 Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x1c Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x3d Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x122 Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x16 Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x35 Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x1a3 Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x16 Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x29 Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x10 Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x241 Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x1c Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x10 Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x10 Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x16 Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x145 Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x189 Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x16 Core/Src/syscalls.o + .debug_macro 0x0000000000000000 0x88 Core/Src/syscalls.o + .debug_line 0x0000000000000000 0xa52 Core/Src/syscalls.o + .debug_str 0x0000000000000000 0x75f61 Core/Src/syscalls.o + .comment 0x0000000000000000 0x7c Core/Src/syscalls.o + .debug_frame 0x0000000000000000 0x244 Core/Src/syscalls.o + .ARM.attributes + 0x0000000000000000 0x31 Core/Src/syscalls.o + .group 0x0000000000000000 0xc Core/Src/sysmem.o + .group 0x0000000000000000 0xc Core/Src/sysmem.o + .group 0x0000000000000000 0xc Core/Src/sysmem.o + .group 0x0000000000000000 0xc Core/Src/sysmem.o + .group 0x0000000000000000 0xc Core/Src/sysmem.o + .group 0x0000000000000000 0xc Core/Src/sysmem.o + .group 0x0000000000000000 0xc Core/Src/sysmem.o + .group 0x0000000000000000 0xc Core/Src/sysmem.o + .group 0x0000000000000000 0xc Core/Src/sysmem.o + .group 0x0000000000000000 0xc Core/Src/sysmem.o + .group 0x0000000000000000 0xc Core/Src/sysmem.o + .group 0x0000000000000000 0xc Core/Src/sysmem.o + .group 0x0000000000000000 0xc Core/Src/sysmem.o + .group 0x0000000000000000 0xc Core/Src/sysmem.o + .group 0x0000000000000000 0xc Core/Src/sysmem.o + .group 0x0000000000000000 0xc Core/Src/sysmem.o + .group 0x0000000000000000 0xc Core/Src/sysmem.o + .group 0x0000000000000000 0xc Core/Src/sysmem.o + .group 0x0000000000000000 0xc Core/Src/sysmem.o + .group 0x0000000000000000 0xc Core/Src/sysmem.o + .group 0x0000000000000000 0xc Core/Src/sysmem.o + .group 0x0000000000000000 0xc Core/Src/sysmem.o + .group 0x0000000000000000 0xc Core/Src/sysmem.o + .group 0x0000000000000000 0xc Core/Src/sysmem.o + .group 0x0000000000000000 0xc Core/Src/sysmem.o + .group 0x0000000000000000 0xc Core/Src/sysmem.o + .group 0x0000000000000000 0xc Core/Src/sysmem.o + .group 0x0000000000000000 0xc Core/Src/sysmem.o + .group 0x0000000000000000 0xc Core/Src/sysmem.o + .group 0x0000000000000000 0xc Core/Src/sysmem.o + .group 0x0000000000000000 0xc Core/Src/sysmem.o + .group 0x0000000000000000 0xc Core/Src/sysmem.o + .text 0x0000000000000000 0x0 Core/Src/sysmem.o + .data 0x0000000000000000 0x0 Core/Src/sysmem.o + .bss 0x0000000000000000 0x0 Core/Src/sysmem.o + .bss.heap_end.5149 + 0x0000000000000000 0x4 Core/Src/sysmem.o + .text._sbrk 0x0000000000000000 0x58 Core/Src/sysmem.o + .debug_info 0x0000000000000000 0x91c Core/Src/sysmem.o + .debug_abbrev 0x0000000000000000 0x1bb Core/Src/sysmem.o + .debug_aranges + 0x0000000000000000 0x20 Core/Src/sysmem.o + .debug_ranges 0x0000000000000000 0x10 Core/Src/sysmem.o + .debug_macro 0x0000000000000000 0x1ae Core/Src/sysmem.o + .debug_macro 0x0000000000000000 0xa48 Core/Src/sysmem.o + .debug_macro 0x0000000000000000 0x10 Core/Src/sysmem.o + .debug_macro 0x0000000000000000 0x22 Core/Src/sysmem.o + .debug_macro 0x0000000000000000 0x40 Core/Src/sysmem.o + .debug_macro 0x0000000000000000 0x18 Core/Src/sysmem.o + .debug_macro 0x0000000000000000 0x94 Core/Src/sysmem.o + .debug_macro 0x0000000000000000 0x3c Core/Src/sysmem.o + .debug_macro 0x0000000000000000 0x34 Core/Src/sysmem.o + .debug_macro 0x0000000000000000 0x174 Core/Src/sysmem.o + .debug_macro 0x0000000000000000 0x57 Core/Src/sysmem.o + .debug_macro 0x0000000000000000 0x52 Core/Src/sysmem.o + .debug_macro 0x0000000000000000 0x1f Core/Src/sysmem.o + .debug_macro 0x0000000000000000 0x43 Core/Src/sysmem.o + .debug_macro 0x0000000000000000 0x20 Core/Src/sysmem.o + .debug_macro 0x0000000000000000 0x1a3 Core/Src/sysmem.o + .debug_macro 0x0000000000000000 0x23b Core/Src/sysmem.o + .debug_macro 0x0000000000000000 0x16 Core/Src/sysmem.o + .debug_macro 0x0000000000000000 0x35 Core/Src/sysmem.o + .debug_macro 0x0000000000000000 0x330 Core/Src/sysmem.o + .debug_macro 0x0000000000000000 0x10 Core/Src/sysmem.o + .debug_macro 0x0000000000000000 0x10 Core/Src/sysmem.o + .debug_macro 0x0000000000000000 0x6a Core/Src/sysmem.o + .debug_macro 0x0000000000000000 0x1c Core/Src/sysmem.o + .debug_macro 0x0000000000000000 0x52 Core/Src/sysmem.o + .debug_macro 0x0000000000000000 0x40 Core/Src/sysmem.o + .debug_macro 0x0000000000000000 0x10 Core/Src/sysmem.o + .debug_macro 0x0000000000000000 0x40 Core/Src/sysmem.o + .debug_macro 0x0000000000000000 0xd7 Core/Src/sysmem.o + .debug_macro 0x0000000000000000 0x1c Core/Src/sysmem.o + .debug_macro 0x0000000000000000 0x3d Core/Src/sysmem.o + .debug_macro 0x0000000000000000 0x16 Core/Src/sysmem.o + .debug_macro 0x0000000000000000 0x145 Core/Src/sysmem.o + .debug_line 0x0000000000000000 0x55e Core/Src/sysmem.o + .debug_str 0x0000000000000000 0x7a3e Core/Src/sysmem.o + .comment 0x0000000000000000 0x7c Core/Src/sysmem.o + .debug_frame 0x0000000000000000 0x30 Core/Src/sysmem.o + .ARM.attributes + 0x0000000000000000 0x31 Core/Src/sysmem.o + .group 0x0000000000000000 0xc Core/Src/system_stm32f0xx.o + .group 0x0000000000000000 0xc Core/Src/system_stm32f0xx.o + .group 0x0000000000000000 0xc Core/Src/system_stm32f0xx.o + .group 0x0000000000000000 0xc Core/Src/system_stm32f0xx.o + .group 0x0000000000000000 0xc Core/Src/system_stm32f0xx.o + .group 0x0000000000000000 0xc Core/Src/system_stm32f0xx.o + .group 0x0000000000000000 0xc Core/Src/system_stm32f0xx.o + .group 0x0000000000000000 0xc Core/Src/system_stm32f0xx.o + .group 0x0000000000000000 0xc Core/Src/system_stm32f0xx.o + .group 0x0000000000000000 0xc Core/Src/system_stm32f0xx.o + .group 0x0000000000000000 0xc Core/Src/system_stm32f0xx.o + .group 0x0000000000000000 0xc Core/Src/system_stm32f0xx.o + .group 0x0000000000000000 0xc Core/Src/system_stm32f0xx.o + .group 0x0000000000000000 0xc Core/Src/system_stm32f0xx.o + .group 0x0000000000000000 0xc Core/Src/system_stm32f0xx.o + .group 0x0000000000000000 0xc Core/Src/system_stm32f0xx.o + .group 0x0000000000000000 0xc Core/Src/system_stm32f0xx.o + .group 0x0000000000000000 0xc Core/Src/system_stm32f0xx.o + .group 0x0000000000000000 0xc Core/Src/system_stm32f0xx.o + .group 0x0000000000000000 0xc Core/Src/system_stm32f0xx.o + .group 0x0000000000000000 0xc Core/Src/system_stm32f0xx.o + .group 0x0000000000000000 0xc Core/Src/system_stm32f0xx.o + .group 0x0000000000000000 0xc Core/Src/system_stm32f0xx.o + .group 0x0000000000000000 0xc Core/Src/system_stm32f0xx.o + .group 0x0000000000000000 0xc Core/Src/system_stm32f0xx.o + .group 0x0000000000000000 0xc Core/Src/system_stm32f0xx.o + .group 0x0000000000000000 0xc Core/Src/system_stm32f0xx.o + .group 0x0000000000000000 0xc Core/Src/system_stm32f0xx.o + .group 0x0000000000000000 0xc Core/Src/system_stm32f0xx.o + .group 0x0000000000000000 0xc Core/Src/system_stm32f0xx.o + .group 0x0000000000000000 0xc Core/Src/system_stm32f0xx.o + .group 0x0000000000000000 0xc Core/Src/system_stm32f0xx.o + .group 0x0000000000000000 0xc Core/Src/system_stm32f0xx.o + .group 0x0000000000000000 0xc Core/Src/system_stm32f0xx.o + .group 0x0000000000000000 0xc Core/Src/system_stm32f0xx.o + .group 0x0000000000000000 0xc Core/Src/system_stm32f0xx.o + .group 0x0000000000000000 0xc Core/Src/system_stm32f0xx.o + .text 0x0000000000000000 0x0 Core/Src/system_stm32f0xx.o + .data 0x0000000000000000 0x0 Core/Src/system_stm32f0xx.o + .bss 0x0000000000000000 0x0 Core/Src/system_stm32f0xx.o + .rodata.APBPrescTable + 0x0000000000000000 0x8 Core/Src/system_stm32f0xx.o + .text.SystemCoreClockUpdate + 0x0000000000000000 0x100 Core/Src/system_stm32f0xx.o + .debug_macro 0x0000000000000000 0xa48 Core/Src/system_stm32f0xx.o + .debug_macro 0x0000000000000000 0x2e Core/Src/system_stm32f0xx.o + .debug_macro 0x0000000000000000 0x22 Core/Src/system_stm32f0xx.o + .debug_macro 0x0000000000000000 0x22 Core/Src/system_stm32f0xx.o + .debug_macro 0x0000000000000000 0x8e Core/Src/system_stm32f0xx.o + .debug_macro 0x0000000000000000 0x51 Core/Src/system_stm32f0xx.o + .debug_macro 0x0000000000000000 0xef Core/Src/system_stm32f0xx.o + .debug_macro 0x0000000000000000 0x6a Core/Src/system_stm32f0xx.o + .debug_macro 0x0000000000000000 0x1df Core/Src/system_stm32f0xx.o + .debug_macro 0x0000000000000000 0x1c Core/Src/system_stm32f0xx.o + .debug_macro 0x0000000000000000 0x22 Core/Src/system_stm32f0xx.o + .debug_macro 0x0000000000000000 0xb5 Core/Src/system_stm32f0xx.o + .debug_macro 0x0000000000000000 0x391 Core/Src/system_stm32f0xx.o + .debug_macro 0x0000000000000000 0xfe50 Core/Src/system_stm32f0xx.o + .debug_macro 0x0000000000000000 0x3c Core/Src/system_stm32f0xx.o + .debug_macro 0x0000000000000000 0x12d Core/Src/system_stm32f0xx.o + .debug_macro 0x0000000000000000 0x174 Core/Src/system_stm32f0xx.o + .debug_macro 0x0000000000000000 0x53 Core/Src/system_stm32f0xx.o + .debug_macro 0x0000000000000000 0x946 Core/Src/system_stm32f0xx.o + .debug_macro 0x0000000000000000 0x5f3 Core/Src/system_stm32f0xx.o + .debug_macro 0x0000000000000000 0x12f Core/Src/system_stm32f0xx.o + .debug_macro 0x0000000000000000 0x1a7 Core/Src/system_stm32f0xx.o + .debug_macro 0x0000000000000000 0x1a7 Core/Src/system_stm32f0xx.o + .debug_macro 0x0000000000000000 0x22c Core/Src/system_stm32f0xx.o + .debug_macro 0x0000000000000000 0x34 Core/Src/system_stm32f0xx.o + .debug_macro 0x0000000000000000 0x43 Core/Src/system_stm32f0xx.o + .debug_macro 0x0000000000000000 0x28 Core/Src/system_stm32f0xx.o + .debug_macro 0x0000000000000000 0xb0 Core/Src/system_stm32f0xx.o + .debug_macro 0x0000000000000000 0x217 Core/Src/system_stm32f0xx.o + .debug_macro 0x0000000000000000 0x22c Core/Src/system_stm32f0xx.o + .debug_macro 0x0000000000000000 0x5f Core/Src/system_stm32f0xx.o + .debug_macro 0x0000000000000000 0xa5 Core/Src/system_stm32f0xx.o + .debug_macro 0x0000000000000000 0x65 Core/Src/system_stm32f0xx.o + .debug_macro 0x0000000000000000 0x234 Core/Src/system_stm32f0xx.o + .debug_macro 0x0000000000000000 0x4c Core/Src/system_stm32f0xx.o + .debug_macro 0x0000000000000000 0x16d Core/Src/system_stm32f0xx.o + .debug_macro 0x0000000000000000 0x130 Core/Src/system_stm32f0xx.o + .text 0x0000000000000000 0x14 Core/Startup/startup_stm32f072c8tx.o + .data 0x0000000000000000 0x0 Core/Startup/startup_stm32f072c8tx.o + .bss 0x0000000000000000 0x0 Core/Startup/startup_stm32f072c8tx.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .text 0x0000000000000000 0x0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .data 0x0000000000000000 0x0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .bss 0x0000000000000000 0x0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .text.HAL_DeInit + 0x0000000000000000 0x40 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .text.HAL_MspInit + 0x0000000000000000 0xa Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .text.HAL_MspDeInit + 0x0000000000000000 0xa Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .text.HAL_GetTickPrio + 0x0000000000000000 0x14 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .text.HAL_SetTickFreq + 0x0000000000000000 0x6c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .text.HAL_GetTickFreq + 0x0000000000000000 0x14 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .text.HAL_Delay + 0x0000000000000000 0x44 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .text.HAL_SuspendTick + 0x0000000000000000 0x1c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .text.HAL_ResumeTick + 0x0000000000000000 0x1c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .text.HAL_GetHalVersion + 0x0000000000000000 0x10 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .text.HAL_GetREVID + 0x0000000000000000 0x14 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .text.HAL_GetDEVID + 0x0000000000000000 0x18 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .text.HAL_GetUIDw0 + 0x0000000000000000 0x14 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .text.HAL_GetUIDw1 + 0x0000000000000000 0x14 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .text.HAL_GetUIDw2 + 0x0000000000000000 0x14 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .text.HAL_DBGMCU_EnableDBGStopMode + 0x0000000000000000 0x1c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .text.HAL_DBGMCU_DisableDBGStopMode + 0x0000000000000000 0x1c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .text.HAL_DBGMCU_EnableDBGStandbyMode + 0x0000000000000000 0x1c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .text.HAL_DBGMCU_DisableDBGStandbyMode + 0x0000000000000000 0x1c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .debug_macro 0x0000000000000000 0xa48 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .debug_macro 0x0000000000000000 0x12d Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .debug_macro 0x0000000000000000 0x2e Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .debug_macro 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .debug_macro 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .debug_macro 0x0000000000000000 0x8e Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .debug_macro 0x0000000000000000 0x51 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .debug_macro 0x0000000000000000 0xef Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .debug_macro 0x0000000000000000 0x6a Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .debug_macro 0x0000000000000000 0x1df Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .debug_macro 0x0000000000000000 0x1c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .debug_macro 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .debug_macro 0x0000000000000000 0xb5 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .debug_macro 0x0000000000000000 0x391 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .debug_macro 0x0000000000000000 0xfe50 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .debug_macro 0x0000000000000000 0x3c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .debug_macro 0x0000000000000000 0x174 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .debug_macro 0x0000000000000000 0x53 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .debug_macro 0x0000000000000000 0x946 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .debug_macro 0x0000000000000000 0x5f3 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .debug_macro 0x0000000000000000 0x12f Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .debug_macro 0x0000000000000000 0x1a7 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .debug_macro 0x0000000000000000 0x1a7 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .debug_macro 0x0000000000000000 0x22c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .debug_macro 0x0000000000000000 0x34 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .debug_macro 0x0000000000000000 0x43 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .debug_macro 0x0000000000000000 0x28 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .debug_macro 0x0000000000000000 0xb0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .debug_macro 0x0000000000000000 0x217 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .debug_macro 0x0000000000000000 0x22c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .debug_macro 0x0000000000000000 0x5f Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .debug_macro 0x0000000000000000 0xa5 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .debug_macro 0x0000000000000000 0x65 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .debug_macro 0x0000000000000000 0x234 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .debug_macro 0x0000000000000000 0x4c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .debug_macro 0x0000000000000000 0x16d Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .debug_macro 0x0000000000000000 0x130 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .text 0x0000000000000000 0x0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .data 0x0000000000000000 0x0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .bss 0x0000000000000000 0x0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .text.__NVIC_DisableIRQ + 0x0000000000000000 0x40 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .text.__NVIC_GetPendingIRQ + 0x0000000000000000 0x40 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .text.__NVIC_SetPendingIRQ + 0x0000000000000000 0x38 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .text.__NVIC_ClearPendingIRQ + 0x0000000000000000 0x38 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .text.__NVIC_GetPriority + 0x0000000000000000 0x7c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .text.__NVIC_SystemReset + 0x0000000000000000 0x20 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .text.HAL_NVIC_DisableIRQ + 0x0000000000000000 0x20 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .text.HAL_NVIC_SystemReset + 0x0000000000000000 0x8 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .text.HAL_NVIC_GetPriority + 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .text.HAL_NVIC_SetPendingIRQ + 0x0000000000000000 0x20 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .text.HAL_NVIC_GetPendingIRQ + 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .text.HAL_NVIC_ClearPendingIRQ + 0x0000000000000000 0x20 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .text.HAL_SYSTICK_CLKSourceConfig + 0x0000000000000000 0x34 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .text.HAL_SYSTICK_IRQHandler + 0x0000000000000000 0xe Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .text.HAL_SYSTICK_Callback + 0x0000000000000000 0xa Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .debug_macro 0x0000000000000000 0xa48 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .debug_macro 0x0000000000000000 0x12d Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .debug_macro 0x0000000000000000 0x2e Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .debug_macro 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .debug_macro 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .debug_macro 0x0000000000000000 0x8e Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .debug_macro 0x0000000000000000 0x51 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .debug_macro 0x0000000000000000 0xef Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .debug_macro 0x0000000000000000 0x6a Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .debug_macro 0x0000000000000000 0x1df Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .debug_macro 0x0000000000000000 0x1c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .debug_macro 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .debug_macro 0x0000000000000000 0xb5 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .debug_macro 0x0000000000000000 0x391 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .debug_macro 0x0000000000000000 0xfe50 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .debug_macro 0x0000000000000000 0x3c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .debug_macro 0x0000000000000000 0x174 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .debug_macro 0x0000000000000000 0x53 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .debug_macro 0x0000000000000000 0x946 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .debug_macro 0x0000000000000000 0x5f3 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .debug_macro 0x0000000000000000 0x12f Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .debug_macro 0x0000000000000000 0x1a7 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .debug_macro 0x0000000000000000 0x1a7 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .debug_macro 0x0000000000000000 0x22c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .debug_macro 0x0000000000000000 0x34 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .debug_macro 0x0000000000000000 0x43 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .debug_macro 0x0000000000000000 0x28 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .debug_macro 0x0000000000000000 0xb0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .debug_macro 0x0000000000000000 0x217 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .debug_macro 0x0000000000000000 0x22c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .debug_macro 0x0000000000000000 0x5f Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .debug_macro 0x0000000000000000 0xa5 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .debug_macro 0x0000000000000000 0x65 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .debug_macro 0x0000000000000000 0x234 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .debug_macro 0x0000000000000000 0x4c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .debug_macro 0x0000000000000000 0x16d Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .debug_macro 0x0000000000000000 0x130 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .text 0x0000000000000000 0x0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .data 0x0000000000000000 0x0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .bss 0x0000000000000000 0x0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .text.HAL_DMA_Init + 0x0000000000000000 0x90 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .text.HAL_DMA_DeInit + 0x0000000000000000 0x92 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .text.HAL_DMA_Start + 0x0000000000000000 0x92 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .text.HAL_DMA_Start_IT + 0x0000000000000000 0xcc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .text.HAL_DMA_Abort + 0x0000000000000000 0x70 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .text.HAL_DMA_Abort_IT + 0x0000000000000000 0x8c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .text.HAL_DMA_PollForTransfer + 0x0000000000000000 0x132 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .text.HAL_DMA_IRQHandler + 0x0000000000000000 0x144 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .text.HAL_DMA_RegisterCallback + 0x0000000000000000 0xa2 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .text.HAL_DMA_UnRegisterCallback + 0x0000000000000000 0xb4 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .rodata.HAL_DMA_UnRegisterCallback + 0x0000000000000000 0x14 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .text.HAL_DMA_GetState + 0x0000000000000000 0x18 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .text.HAL_DMA_GetError + 0x0000000000000000 0x14 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .text.DMA_SetConfig + 0x0000000000000000 0x58 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .text.DMA_CalcBaseAndBitshift + 0x0000000000000000 0x38 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .debug_info 0x0000000000000000 0x7a9 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .debug_abbrev 0x0000000000000000 0x216 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .debug_aranges + 0x0000000000000000 0x88 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .debug_ranges 0x0000000000000000 0x78 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .debug_macro 0x0000000000000000 0x1b5 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .debug_macro 0x0000000000000000 0xa48 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .debug_macro 0x0000000000000000 0x12d Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .debug_macro 0x0000000000000000 0x2e Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .debug_macro 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .debug_macro 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .debug_macro 0x0000000000000000 0x8e Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .debug_macro 0x0000000000000000 0x51 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .debug_macro 0x0000000000000000 0xef Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .debug_macro 0x0000000000000000 0x6a Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .debug_macro 0x0000000000000000 0x1df Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .debug_macro 0x0000000000000000 0x1c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .debug_macro 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .debug_macro 0x0000000000000000 0xb5 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .debug_macro 0x0000000000000000 0x391 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .debug_macro 0x0000000000000000 0xfe50 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .debug_macro 0x0000000000000000 0x3c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .debug_macro 0x0000000000000000 0x174 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .debug_macro 0x0000000000000000 0x53 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .debug_macro 0x0000000000000000 0x946 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .debug_macro 0x0000000000000000 0x5f3 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .debug_macro 0x0000000000000000 0x12f Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .debug_macro 0x0000000000000000 0x1a7 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .debug_macro 0x0000000000000000 0x1a7 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .debug_macro 0x0000000000000000 0x22c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .debug_macro 0x0000000000000000 0x34 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .debug_macro 0x0000000000000000 0x43 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .debug_macro 0x0000000000000000 0x28 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .debug_macro 0x0000000000000000 0xb0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .debug_macro 0x0000000000000000 0x217 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .debug_macro 0x0000000000000000 0x22c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .debug_macro 0x0000000000000000 0x5f Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .debug_macro 0x0000000000000000 0xa5 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .debug_macro 0x0000000000000000 0x65 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .debug_macro 0x0000000000000000 0x234 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .debug_macro 0x0000000000000000 0x4c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .debug_macro 0x0000000000000000 0x16d Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .debug_macro 0x0000000000000000 0x130 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .debug_line 0x0000000000000000 0x893 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .debug_str 0x0000000000000000 0x710c0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .comment 0x0000000000000000 0x7c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .debug_frame 0x0000000000000000 0x1d0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .ARM.attributes + 0x0000000000000000 0x31 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .text 0x0000000000000000 0x0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .data 0x0000000000000000 0x0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .bss 0x0000000000000000 0x0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .text.HAL_EXTI_SetConfigLine + 0x0000000000000000 0x148 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .text.HAL_EXTI_GetConfigLine + 0x0000000000000000 0xfc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .text.HAL_EXTI_ClearConfigLine + 0x0000000000000000 0xc0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .text.HAL_EXTI_RegisterCallback + 0x0000000000000000 0x42 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .text.HAL_EXTI_GetHandle + 0x0000000000000000 0x24 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .text.HAL_EXTI_IRQHandler + 0x0000000000000000 0x48 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .text.HAL_EXTI_GetPending + 0x0000000000000000 0x3c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .text.HAL_EXTI_ClearPending + 0x0000000000000000 0x2c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .text.HAL_EXTI_GenerateSWI + 0x0000000000000000 0x2c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .debug_info 0x0000000000000000 0x5a8 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .debug_abbrev 0x0000000000000000 0x1bc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .debug_aranges + 0x0000000000000000 0x60 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .debug_ranges 0x0000000000000000 0x50 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .debug_macro 0x0000000000000000 0x1b5 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .debug_macro 0x0000000000000000 0xa48 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .debug_macro 0x0000000000000000 0x12d Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .debug_macro 0x0000000000000000 0x2e Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .debug_macro 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .debug_macro 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .debug_macro 0x0000000000000000 0x8e Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .debug_macro 0x0000000000000000 0x51 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .debug_macro 0x0000000000000000 0xef Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .debug_macro 0x0000000000000000 0x6a Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .debug_macro 0x0000000000000000 0x1df Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .debug_macro 0x0000000000000000 0x1c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .debug_macro 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .debug_macro 0x0000000000000000 0xb5 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .debug_macro 0x0000000000000000 0x391 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .debug_macro 0x0000000000000000 0xfe50 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .debug_macro 0x0000000000000000 0x3c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .debug_macro 0x0000000000000000 0x174 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .debug_macro 0x0000000000000000 0x53 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .debug_macro 0x0000000000000000 0x946 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .debug_macro 0x0000000000000000 0x5f3 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .debug_macro 0x0000000000000000 0x12f Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .debug_macro 0x0000000000000000 0x1a7 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .debug_macro 0x0000000000000000 0x1a7 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .debug_macro 0x0000000000000000 0x22c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .debug_macro 0x0000000000000000 0x34 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .debug_macro 0x0000000000000000 0x43 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .debug_macro 0x0000000000000000 0x28 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .debug_macro 0x0000000000000000 0xb0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .debug_macro 0x0000000000000000 0x217 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .debug_macro 0x0000000000000000 0x22c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .debug_macro 0x0000000000000000 0x5f Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .debug_macro 0x0000000000000000 0xa5 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .debug_macro 0x0000000000000000 0x65 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .debug_macro 0x0000000000000000 0x234 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .debug_macro 0x0000000000000000 0x4c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .debug_macro 0x0000000000000000 0x16d Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .debug_macro 0x0000000000000000 0x130 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .debug_line 0x0000000000000000 0x77c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .debug_str 0x0000000000000000 0x70e8a Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .comment 0x0000000000000000 0x7c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .debug_frame 0x0000000000000000 0x130 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .ARM.attributes + 0x0000000000000000 0x31 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .text 0x0000000000000000 0x0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .data 0x0000000000000000 0x0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .bss 0x0000000000000000 0x0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .text.HAL_FLASH_Program + 0x0000000000000000 0x12c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .text.HAL_FLASH_Program_IT + 0x0000000000000000 0xa0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .text.HAL_FLASH_IRQHandler + 0x0000000000000000 0x1d0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .text.HAL_FLASH_EndOfOperationCallback + 0x0000000000000000 0x10 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .text.HAL_FLASH_OperationErrorCallback + 0x0000000000000000 0x10 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .text.HAL_FLASH_Unlock + 0x0000000000000000 0x4c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .text.HAL_FLASH_Lock + 0x0000000000000000 0x1c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .text.HAL_FLASH_OB_Unlock + 0x0000000000000000 0x34 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .text.HAL_FLASH_OB_Lock + 0x0000000000000000 0x20 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .text.HAL_FLASH_OB_Launch + 0x0000000000000000 0x2c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .text.HAL_FLASH_GetError + 0x0000000000000000 0x14 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .text.FLASH_Program_HalfWord + 0x0000000000000000 0x38 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .text.FLASH_WaitForLastOperation + 0x0000000000000000 0x80 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .text.FLASH_SetErrorCode + 0x0000000000000000 0x60 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .debug_info 0x0000000000000000 0x57f Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .debug_abbrev 0x0000000000000000 0x22e Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .debug_aranges + 0x0000000000000000 0x88 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .debug_ranges 0x0000000000000000 0x78 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .debug_macro 0x0000000000000000 0x1b5 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .debug_macro 0x0000000000000000 0xa48 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .debug_macro 0x0000000000000000 0x12d Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .debug_macro 0x0000000000000000 0x2e Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .debug_macro 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .debug_macro 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .debug_macro 0x0000000000000000 0x8e Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .debug_macro 0x0000000000000000 0x51 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .debug_macro 0x0000000000000000 0xef Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .debug_macro 0x0000000000000000 0x6a Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .debug_macro 0x0000000000000000 0x1df Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .debug_macro 0x0000000000000000 0x1c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .debug_macro 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .debug_macro 0x0000000000000000 0xb5 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .debug_macro 0x0000000000000000 0x391 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .debug_macro 0x0000000000000000 0xfe50 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .debug_macro 0x0000000000000000 0x3c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .debug_macro 0x0000000000000000 0x174 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .debug_macro 0x0000000000000000 0x53 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .debug_macro 0x0000000000000000 0x946 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .debug_macro 0x0000000000000000 0x5f3 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .debug_macro 0x0000000000000000 0x12f Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .debug_macro 0x0000000000000000 0x1a7 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .debug_macro 0x0000000000000000 0x1a7 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .debug_macro 0x0000000000000000 0x22c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .debug_macro 0x0000000000000000 0x34 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .debug_macro 0x0000000000000000 0x43 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .debug_macro 0x0000000000000000 0x28 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .debug_macro 0x0000000000000000 0xb0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .debug_macro 0x0000000000000000 0x217 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .debug_macro 0x0000000000000000 0x22c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .debug_macro 0x0000000000000000 0x5f Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .debug_macro 0x0000000000000000 0xa5 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .debug_macro 0x0000000000000000 0x65 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .debug_macro 0x0000000000000000 0x234 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .debug_macro 0x0000000000000000 0x4c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .debug_macro 0x0000000000000000 0x16d Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .debug_macro 0x0000000000000000 0x130 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .debug_line 0x0000000000000000 0x83f Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .debug_str 0x0000000000000000 0x70fa3 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .comment 0x0000000000000000 0x7c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .debug_frame 0x0000000000000000 0x1c4 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .ARM.attributes + 0x0000000000000000 0x31 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + COMMON 0x0000000000000000 0x20 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .text 0x0000000000000000 0x0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .data 0x0000000000000000 0x0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .bss 0x0000000000000000 0x0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .text.HAL_FLASHEx_Erase + 0x0000000000000000 0xec Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .text.HAL_FLASHEx_Erase_IT + 0x0000000000000000 0x88 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .text.HAL_FLASHEx_OBErase + 0x0000000000000000 0x9c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .text.HAL_FLASHEx_OBProgram + 0x0000000000000000 0x128 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .text.HAL_FLASHEx_OBGetConfig + 0x0000000000000000 0x38 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .text.HAL_FLASHEx_OBGetUserData + 0x0000000000000000 0x40 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .text.FLASH_MassErase + 0x0000000000000000 0x30 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .text.FLASH_OB_EnableWRP + 0x0000000000000000 0x1c0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .text.FLASH_OB_DisableWRP + 0x0000000000000000 0x1bc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .text.FLASH_OB_RDP_LevelConfig + 0x0000000000000000 0xbc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .text.FLASH_OB_UserConfig + 0x0000000000000000 0x88 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .text.FLASH_OB_ProgramData + 0x0000000000000000 0x80 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .text.FLASH_OB_GetWRP + 0x0000000000000000 0x14 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .text.FLASH_OB_GetRDP + 0x0000000000000000 0x34 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .text.FLASH_OB_GetUser + 0x0000000000000000 0x1c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .text.FLASH_PageErase + 0x0000000000000000 0x3c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .debug_info 0x0000000000000000 0x7c5 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .debug_abbrev 0x0000000000000000 0x219 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .debug_aranges + 0x0000000000000000 0x98 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .debug_ranges 0x0000000000000000 0x88 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .debug_macro 0x0000000000000000 0x1c7 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .debug_macro 0x0000000000000000 0xa48 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .debug_macro 0x0000000000000000 0x12d Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .debug_macro 0x0000000000000000 0x2e Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .debug_macro 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .debug_macro 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .debug_macro 0x0000000000000000 0x8e Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .debug_macro 0x0000000000000000 0x51 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .debug_macro 0x0000000000000000 0xef Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .debug_macro 0x0000000000000000 0x6a Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .debug_macro 0x0000000000000000 0x1df Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .debug_macro 0x0000000000000000 0x1c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .debug_macro 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .debug_macro 0x0000000000000000 0xb5 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .debug_macro 0x0000000000000000 0x391 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .debug_macro 0x0000000000000000 0xfe50 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .debug_macro 0x0000000000000000 0x3c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .debug_macro 0x0000000000000000 0x174 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .debug_macro 0x0000000000000000 0x53 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .debug_macro 0x0000000000000000 0x946 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .debug_macro 0x0000000000000000 0x5f3 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .debug_macro 0x0000000000000000 0x12f Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .debug_macro 0x0000000000000000 0x1a7 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .debug_macro 0x0000000000000000 0x1a7 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .debug_macro 0x0000000000000000 0x22c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .debug_macro 0x0000000000000000 0x34 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .debug_macro 0x0000000000000000 0x43 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .debug_macro 0x0000000000000000 0x28 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .debug_macro 0x0000000000000000 0xb0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .debug_macro 0x0000000000000000 0x217 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .debug_macro 0x0000000000000000 0x22c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .debug_macro 0x0000000000000000 0x5f Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .debug_macro 0x0000000000000000 0xa5 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .debug_macro 0x0000000000000000 0x65 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .debug_macro 0x0000000000000000 0x234 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .debug_macro 0x0000000000000000 0x4c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .debug_macro 0x0000000000000000 0x16d Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .debug_macro 0x0000000000000000 0x130 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .debug_line 0x0000000000000000 0x8b9 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .debug_str 0x0000000000000000 0x71123 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .comment 0x0000000000000000 0x7c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .debug_frame 0x0000000000000000 0x220 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .ARM.attributes + 0x0000000000000000 0x31 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .text 0x0000000000000000 0x0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .data 0x0000000000000000 0x0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .bss 0x0000000000000000 0x0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .text.HAL_GPIO_DeInit + 0x0000000000000000 0x1ac Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .text.HAL_GPIO_ReadPin + 0x0000000000000000 0x3a Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .text.HAL_GPIO_WritePin + 0x0000000000000000 0x3a Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .text.HAL_GPIO_TogglePin + 0x0000000000000000 0x36 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .text.HAL_GPIO_LockPin + 0x0000000000000000 0x52 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .text.HAL_GPIO_EXTI_IRQHandler + 0x0000000000000000 0x38 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .text.HAL_GPIO_EXTI_Callback + 0x0000000000000000 0x14 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .debug_macro 0x0000000000000000 0xa48 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .debug_macro 0x0000000000000000 0x12d Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .debug_macro 0x0000000000000000 0x2e Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .debug_macro 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .debug_macro 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .debug_macro 0x0000000000000000 0x8e Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .debug_macro 0x0000000000000000 0x51 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .debug_macro 0x0000000000000000 0xef Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .debug_macro 0x0000000000000000 0x6a Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .debug_macro 0x0000000000000000 0x1df Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .debug_macro 0x0000000000000000 0x1c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .debug_macro 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .debug_macro 0x0000000000000000 0xb5 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .debug_macro 0x0000000000000000 0x391 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .debug_macro 0x0000000000000000 0xfe50 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .debug_macro 0x0000000000000000 0x3c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .debug_macro 0x0000000000000000 0x174 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .debug_macro 0x0000000000000000 0x53 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .debug_macro 0x0000000000000000 0x946 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .debug_macro 0x0000000000000000 0x5f3 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .debug_macro 0x0000000000000000 0x12f Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .debug_macro 0x0000000000000000 0x1a7 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .debug_macro 0x0000000000000000 0x1a7 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .debug_macro 0x0000000000000000 0x22c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .debug_macro 0x0000000000000000 0x34 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .debug_macro 0x0000000000000000 0x43 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .debug_macro 0x0000000000000000 0x28 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .debug_macro 0x0000000000000000 0xb0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .debug_macro 0x0000000000000000 0x217 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .debug_macro 0x0000000000000000 0x22c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .debug_macro 0x0000000000000000 0x5f Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .debug_macro 0x0000000000000000 0xa5 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .debug_macro 0x0000000000000000 0x65 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .debug_macro 0x0000000000000000 0x234 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .debug_macro 0x0000000000000000 0x4c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .debug_macro 0x0000000000000000 0x16d Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .debug_macro 0x0000000000000000 0x130 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text 0x0000000000000000 0x0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .data 0x0000000000000000 0x0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .bss 0x0000000000000000 0x0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.HAL_I2C_Init + 0x0000000000000000 0x12c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.HAL_I2C_DeInit + 0x0000000000000000 0x60 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.HAL_I2C_MspInit + 0x0000000000000000 0x10 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.HAL_I2C_MspDeInit + 0x0000000000000000 0x10 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.HAL_I2C_Master_Transmit + 0x0000000000000000 0x210 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.HAL_I2C_Master_Receive + 0x0000000000000000 0x210 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.HAL_I2C_Slave_Transmit + 0x0000000000000000 0x22c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.HAL_I2C_Slave_Receive + 0x0000000000000000 0x214 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.HAL_I2C_Master_Transmit_IT + 0x0000000000000000 0xf8 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.HAL_I2C_Master_Receive_IT + 0x0000000000000000 0xf8 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.HAL_I2C_Slave_Transmit_IT + 0x0000000000000000 0xa8 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.HAL_I2C_Slave_Receive_IT + 0x0000000000000000 0xa8 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.HAL_I2C_Master_Transmit_DMA + 0x0000000000000000 0x20c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.HAL_I2C_Master_Receive_DMA + 0x0000000000000000 0x20c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.HAL_I2C_Slave_Transmit_DMA + 0x0000000000000000 0x17c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.HAL_I2C_Slave_Receive_DMA + 0x0000000000000000 0x17c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.HAL_I2C_Mem_Write + 0x0000000000000000 0x25c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.HAL_I2C_Mem_Read + 0x0000000000000000 0x268 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.HAL_I2C_Mem_Write_IT + 0x0000000000000000 0x150 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.HAL_I2C_Mem_Read_IT + 0x0000000000000000 0x154 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.HAL_I2C_Mem_Write_DMA + 0x0000000000000000 0x21c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.HAL_I2C_Mem_Read_DMA + 0x0000000000000000 0x220 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.HAL_I2C_IsDeviceReady + 0x0000000000000000 0x234 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.HAL_I2C_Master_Seq_Transmit_IT + 0x0000000000000000 0x124 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.HAL_I2C_Master_Seq_Transmit_DMA + 0x0000000000000000 0x234 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.HAL_I2C_Master_Seq_Receive_IT + 0x0000000000000000 0x124 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.HAL_I2C_Master_Seq_Receive_DMA + 0x0000000000000000 0x234 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.HAL_I2C_Slave_Seq_Transmit_IT + 0x0000000000000000 0x158 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.HAL_I2C_Slave_Seq_Transmit_DMA + 0x0000000000000000 0x28c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.HAL_I2C_Slave_Seq_Receive_IT + 0x0000000000000000 0x15c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.HAL_I2C_Slave_Seq_Receive_DMA + 0x0000000000000000 0x28c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.HAL_I2C_EnableListen_IT + 0x0000000000000000 0x40 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.HAL_I2C_DisableListen_IT + 0x0000000000000000 0x64 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.HAL_I2C_Master_Abort_IT + 0x0000000000000000 0x88 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.HAL_I2C_EV_IRQHandler + 0x0000000000000000 0x34 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.HAL_I2C_ER_IRQHandler + 0x0000000000000000 0xc4 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.HAL_I2C_MasterTxCpltCallback + 0x0000000000000000 0x10 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.HAL_I2C_MasterRxCpltCallback + 0x0000000000000000 0x10 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.HAL_I2C_SlaveTxCpltCallback + 0x0000000000000000 0x10 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.HAL_I2C_SlaveRxCpltCallback + 0x0000000000000000 0x10 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.HAL_I2C_AddrCallback + 0x0000000000000000 0x20 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.HAL_I2C_ListenCpltCallback + 0x0000000000000000 0x10 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.HAL_I2C_MemTxCpltCallback + 0x0000000000000000 0x10 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.HAL_I2C_MemRxCpltCallback + 0x0000000000000000 0x10 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.HAL_I2C_ErrorCallback + 0x0000000000000000 0x10 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.HAL_I2C_AbortCpltCallback + 0x0000000000000000 0x10 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.HAL_I2C_GetState + 0x0000000000000000 0x18 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.HAL_I2C_GetMode + 0x0000000000000000 0x18 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.HAL_I2C_GetError + 0x0000000000000000 0x14 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.I2C_Master_ISR_IT + 0x0000000000000000 0x288 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.I2C_Slave_ISR_IT + 0x0000000000000000 0x228 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.I2C_Master_ISR_DMA + 0x0000000000000000 0x218 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.I2C_Slave_ISR_DMA + 0x0000000000000000 0x1b0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.I2C_RequestMemoryWrite + 0x0000000000000000 0xc8 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.I2C_RequestMemoryRead + 0x0000000000000000 0xc4 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.I2C_ITAddrCplt + 0x0000000000000000 0x14a Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.I2C_ITMasterSeqCplt + 0x0000000000000000 0x82 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.I2C_ITSlaveSeqCplt + 0x0000000000000000 0x82 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.I2C_ITMasterCplt + 0x0000000000000000 0x144 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.I2C_ITSlaveCplt + 0x0000000000000000 0x1c0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.I2C_ITListenCplt + 0x0000000000000000 0xac Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.I2C_ITError + 0x0000000000000000 0x1a4 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.I2C_Flush_TXDR + 0x0000000000000000 0x44 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.I2C_DMAMasterTransmitCplt + 0x0000000000000000 0xa0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.I2C_DMASlaveTransmitCplt + 0x0000000000000000 0x48 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.I2C_DMAMasterReceiveCplt + 0x0000000000000000 0xa0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.I2C_DMASlaveReceiveCplt + 0x0000000000000000 0x50 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.I2C_DMAError + 0x0000000000000000 0x32 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.I2C_DMAAbort + 0x0000000000000000 0x4c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.I2C_WaitOnFlagUntilTimeout + 0x0000000000000000 0x7e Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.I2C_WaitOnTXISFlagUntilTimeout + 0x0000000000000000 0x7e Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.I2C_WaitOnSTOPFlagUntilTimeout + 0x0000000000000000 0x78 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.I2C_WaitOnRXNEFlagUntilTimeout + 0x0000000000000000 0xd8 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.I2C_IsAcknowledgeFailed + 0x0000000000000000 0xcc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.I2C_TransferConfig + 0x0000000000000000 0x6c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.I2C_Enable_IRQ + 0x0000000000000000 0xe4 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.I2C_Disable_IRQ + 0x0000000000000000 0xd2 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .text.I2C_ConvertOtherXferOptions + 0x0000000000000000 0x34 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .debug_info 0x0000000000000000 0x1f43 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .debug_abbrev 0x0000000000000000 0x22a Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .debug_aranges + 0x0000000000000000 0x288 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .debug_ranges 0x0000000000000000 0x278 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .debug_macro 0x0000000000000000 0x27a Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .debug_macro 0x0000000000000000 0xa48 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .debug_macro 0x0000000000000000 0x12d Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .debug_macro 0x0000000000000000 0x2e Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .debug_macro 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .debug_macro 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .debug_macro 0x0000000000000000 0x8e Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .debug_macro 0x0000000000000000 0x51 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .debug_macro 0x0000000000000000 0xef Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .debug_macro 0x0000000000000000 0x6a Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .debug_macro 0x0000000000000000 0x1df Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .debug_macro 0x0000000000000000 0x1c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .debug_macro 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .debug_macro 0x0000000000000000 0xb5 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .debug_macro 0x0000000000000000 0x391 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .debug_macro 0x0000000000000000 0xfe50 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .debug_macro 0x0000000000000000 0x3c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .debug_macro 0x0000000000000000 0x174 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .debug_macro 0x0000000000000000 0x53 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .debug_macro 0x0000000000000000 0x946 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .debug_macro 0x0000000000000000 0x5f3 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .debug_macro 0x0000000000000000 0x12f Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .debug_macro 0x0000000000000000 0x1a7 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .debug_macro 0x0000000000000000 0x1a7 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .debug_macro 0x0000000000000000 0x22c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .debug_macro 0x0000000000000000 0x34 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .debug_macro 0x0000000000000000 0x43 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .debug_macro 0x0000000000000000 0x28 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .debug_macro 0x0000000000000000 0xb0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .debug_macro 0x0000000000000000 0x217 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .debug_macro 0x0000000000000000 0x22c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .debug_macro 0x0000000000000000 0x5f Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .debug_macro 0x0000000000000000 0xa5 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .debug_macro 0x0000000000000000 0x65 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .debug_macro 0x0000000000000000 0x234 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .debug_macro 0x0000000000000000 0x4c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .debug_macro 0x0000000000000000 0x16d Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .debug_macro 0x0000000000000000 0x130 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .debug_line 0x0000000000000000 0x1a02 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .debug_str 0x0000000000000000 0x71f47 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .comment 0x0000000000000000 0x7c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .debug_frame 0x0000000000000000 0xa00 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .ARM.attributes + 0x0000000000000000 0x31 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .text 0x0000000000000000 0x0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .data 0x0000000000000000 0x0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .bss 0x0000000000000000 0x0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .text.HAL_I2CEx_ConfigAnalogFilter + 0x0000000000000000 0x98 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .text.HAL_I2CEx_ConfigDigitalFilter + 0x0000000000000000 0x98 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .text.HAL_I2CEx_EnableWakeUp + 0x0000000000000000 0x82 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .text.HAL_I2CEx_DisableWakeUp + 0x0000000000000000 0x84 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .text.HAL_I2CEx_EnableFastModePlus + 0x0000000000000000 0x3c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .text.HAL_I2CEx_DisableFastModePlus + 0x0000000000000000 0x40 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .debug_info 0x0000000000000000 0x8c9 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .debug_abbrev 0x0000000000000000 0x1b9 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .debug_aranges + 0x0000000000000000 0x48 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .debug_ranges 0x0000000000000000 0x38 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .debug_macro 0x0000000000000000 0x1b5 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .debug_macro 0x0000000000000000 0xa48 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .debug_macro 0x0000000000000000 0x12d Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .debug_macro 0x0000000000000000 0x2e Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .debug_macro 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .debug_macro 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .debug_macro 0x0000000000000000 0x8e Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .debug_macro 0x0000000000000000 0x51 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .debug_macro 0x0000000000000000 0xef Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .debug_macro 0x0000000000000000 0x6a Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .debug_macro 0x0000000000000000 0x1df Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .debug_macro 0x0000000000000000 0x1c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .debug_macro 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .debug_macro 0x0000000000000000 0xb5 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .debug_macro 0x0000000000000000 0x391 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .debug_macro 0x0000000000000000 0xfe50 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .debug_macro 0x0000000000000000 0x3c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .debug_macro 0x0000000000000000 0x174 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .debug_macro 0x0000000000000000 0x53 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .debug_macro 0x0000000000000000 0x946 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .debug_macro 0x0000000000000000 0x5f3 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .debug_macro 0x0000000000000000 0x12f Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .debug_macro 0x0000000000000000 0x1a7 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .debug_macro 0x0000000000000000 0x1a7 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .debug_macro 0x0000000000000000 0x22c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .debug_macro 0x0000000000000000 0x34 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .debug_macro 0x0000000000000000 0x43 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .debug_macro 0x0000000000000000 0x28 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .debug_macro 0x0000000000000000 0xb0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .debug_macro 0x0000000000000000 0x217 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .debug_macro 0x0000000000000000 0x22c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .debug_macro 0x0000000000000000 0x5f Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .debug_macro 0x0000000000000000 0xa5 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .debug_macro 0x0000000000000000 0x65 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .debug_macro 0x0000000000000000 0x234 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .debug_macro 0x0000000000000000 0x4c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .debug_macro 0x0000000000000000 0x16d Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .debug_macro 0x0000000000000000 0x130 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .debug_line 0x0000000000000000 0x7c3 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .debug_str 0x0000000000000000 0x71286 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .comment 0x0000000000000000 0x7c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .debug_frame 0x0000000000000000 0xd0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .ARM.attributes + 0x0000000000000000 0x31 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .text 0x0000000000000000 0x0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .data 0x0000000000000000 0x0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .bss 0x0000000000000000 0x0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .text.HAL_PCD_DeInit + 0x0000000000000000 0x40 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .text.HAL_PCD_MspInit + 0x0000000000000000 0x10 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .text.HAL_PCD_MspDeInit + 0x0000000000000000 0x10 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .text.HAL_PCD_Stop + 0x0000000000000000 0x4a Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .text.HAL_PCD_DataOutStageCallback + 0x0000000000000000 0x16 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .text.HAL_PCD_DataInStageCallback + 0x0000000000000000 0x16 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .text.HAL_PCD_SetupStageCallback + 0x0000000000000000 0x10 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .text.HAL_PCD_SOFCallback + 0x0000000000000000 0x10 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .text.HAL_PCD_ResetCallback + 0x0000000000000000 0x10 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .text.HAL_PCD_SuspendCallback + 0x0000000000000000 0x10 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .text.HAL_PCD_ResumeCallback + 0x0000000000000000 0x10 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .text.HAL_PCD_ISOOUTIncompleteCallback + 0x0000000000000000 0x16 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .text.HAL_PCD_ISOINIncompleteCallback + 0x0000000000000000 0x16 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .text.HAL_PCD_ConnectCallback + 0x0000000000000000 0x10 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .text.HAL_PCD_DisconnectCallback + 0x0000000000000000 0x10 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .text.HAL_PCD_DevConnect + 0x0000000000000000 0x40 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .text.HAL_PCD_DevDisconnect + 0x0000000000000000 0x40 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .text.HAL_PCD_EP_Flush + 0x0000000000000000 0x18 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .text.HAL_PCD_ActivateRemoteWakeup + 0x0000000000000000 0x1c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .text.HAL_PCD_DeActivateRemoteWakeup + 0x0000000000000000 0x1c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .text.HAL_PCD_GetState + 0x0000000000000000 0x1c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .debug_macro 0x0000000000000000 0xa48 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .debug_macro 0x0000000000000000 0x12d Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .debug_macro 0x0000000000000000 0x2e Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .debug_macro 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .debug_macro 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .debug_macro 0x0000000000000000 0x8e Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .debug_macro 0x0000000000000000 0x51 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .debug_macro 0x0000000000000000 0xef Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .debug_macro 0x0000000000000000 0x6a Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .debug_macro 0x0000000000000000 0x1df Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .debug_macro 0x0000000000000000 0x1c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .debug_macro 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .debug_macro 0x0000000000000000 0xb5 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .debug_macro 0x0000000000000000 0x391 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .debug_macro 0x0000000000000000 0xfe50 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .debug_macro 0x0000000000000000 0x3c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .debug_macro 0x0000000000000000 0x174 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .debug_macro 0x0000000000000000 0x53 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .debug_macro 0x0000000000000000 0x946 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .debug_macro 0x0000000000000000 0x5f3 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .debug_macro 0x0000000000000000 0x12f Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .debug_macro 0x0000000000000000 0x1a7 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .debug_macro 0x0000000000000000 0x1a7 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .debug_macro 0x0000000000000000 0x22c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .debug_macro 0x0000000000000000 0x34 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .debug_macro 0x0000000000000000 0x43 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .debug_macro 0x0000000000000000 0x28 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .debug_macro 0x0000000000000000 0xb0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .debug_macro 0x0000000000000000 0x217 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .debug_macro 0x0000000000000000 0x22c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .debug_macro 0x0000000000000000 0x5f Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .debug_macro 0x0000000000000000 0xa5 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .debug_macro 0x0000000000000000 0x65 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .debug_macro 0x0000000000000000 0x234 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .debug_macro 0x0000000000000000 0x4c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .debug_macro 0x0000000000000000 0x16d Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .debug_macro 0x0000000000000000 0x130 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .text 0x0000000000000000 0x0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .data 0x0000000000000000 0x0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .bss 0x0000000000000000 0x0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .text.HAL_PCDEx_ActivateBCD + 0x0000000000000000 0x72 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .text.HAL_PCDEx_DeActivateBCD + 0x0000000000000000 0x36 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .text.HAL_PCDEx_BCD_VBUSDetect + 0x0000000000000000 0x12e Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .text.HAL_PCDEx_DeActivateLPM + 0x0000000000000000 0x4a Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .text.HAL_PCDEx_BCD_Callback + 0x0000000000000000 0x16 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .debug_macro 0x0000000000000000 0xa48 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .debug_macro 0x0000000000000000 0x12d Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .debug_macro 0x0000000000000000 0x2e Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .debug_macro 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .debug_macro 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .debug_macro 0x0000000000000000 0x8e Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .debug_macro 0x0000000000000000 0x51 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .debug_macro 0x0000000000000000 0xef Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .debug_macro 0x0000000000000000 0x6a Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .debug_macro 0x0000000000000000 0x1df Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .debug_macro 0x0000000000000000 0x1c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .debug_macro 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .debug_macro 0x0000000000000000 0xb5 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .debug_macro 0x0000000000000000 0x391 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .debug_macro 0x0000000000000000 0xfe50 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .debug_macro 0x0000000000000000 0x3c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .debug_macro 0x0000000000000000 0x174 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .debug_macro 0x0000000000000000 0x53 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .debug_macro 0x0000000000000000 0x946 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .debug_macro 0x0000000000000000 0x5f3 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .debug_macro 0x0000000000000000 0x12f Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .debug_macro 0x0000000000000000 0x1a7 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .debug_macro 0x0000000000000000 0x1a7 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .debug_macro 0x0000000000000000 0x22c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .debug_macro 0x0000000000000000 0x34 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .debug_macro 0x0000000000000000 0x43 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .debug_macro 0x0000000000000000 0x28 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .debug_macro 0x0000000000000000 0xb0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .debug_macro 0x0000000000000000 0x217 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .debug_macro 0x0000000000000000 0x22c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .debug_macro 0x0000000000000000 0x5f Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .debug_macro 0x0000000000000000 0xa5 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .debug_macro 0x0000000000000000 0x65 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .debug_macro 0x0000000000000000 0x234 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .debug_macro 0x0000000000000000 0x4c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .debug_macro 0x0000000000000000 0x16d Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .debug_macro 0x0000000000000000 0x130 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .text 0x0000000000000000 0x0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .data 0x0000000000000000 0x0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .bss 0x0000000000000000 0x0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .text.HAL_PWR_DeInit + 0x0000000000000000 0x2c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .text.HAL_PWR_EnableBkUpAccess + 0x0000000000000000 0x1c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .text.HAL_PWR_DisableBkUpAccess + 0x0000000000000000 0x20 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .text.HAL_PWR_EnableWakeUpPin + 0x0000000000000000 0x20 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .text.HAL_PWR_DisableWakeUpPin + 0x0000000000000000 0x24 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .text.HAL_PWR_EnterSLEEPMode + 0x0000000000000000 0x38 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .text.HAL_PWR_EnterSTOPMode + 0x0000000000000000 0x68 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .text.HAL_PWR_EnterSTANDBYMode + 0x0000000000000000 0x2c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .text.HAL_PWR_EnableSleepOnExit + 0x0000000000000000 0x1c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .text.HAL_PWR_DisableSleepOnExit + 0x0000000000000000 0x1c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .text.HAL_PWR_EnableSEVOnPend + 0x0000000000000000 0x1c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .text.HAL_PWR_DisableSEVOnPend + 0x0000000000000000 0x1c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .debug_info 0x0000000000000000 0x43a Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .debug_abbrev 0x0000000000000000 0x15f Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .debug_aranges + 0x0000000000000000 0x78 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .debug_ranges 0x0000000000000000 0x68 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .debug_macro 0x0000000000000000 0x1b5 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .debug_macro 0x0000000000000000 0xa48 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .debug_macro 0x0000000000000000 0x12d Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .debug_macro 0x0000000000000000 0x2e Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .debug_macro 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .debug_macro 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .debug_macro 0x0000000000000000 0x8e Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .debug_macro 0x0000000000000000 0x51 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .debug_macro 0x0000000000000000 0xef Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .debug_macro 0x0000000000000000 0x6a Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .debug_macro 0x0000000000000000 0x1df Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .debug_macro 0x0000000000000000 0x1c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .debug_macro 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .debug_macro 0x0000000000000000 0xb5 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .debug_macro 0x0000000000000000 0x391 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .debug_macro 0x0000000000000000 0xfe50 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .debug_macro 0x0000000000000000 0x3c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .debug_macro 0x0000000000000000 0x174 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .debug_macro 0x0000000000000000 0x53 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .debug_macro 0x0000000000000000 0x946 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .debug_macro 0x0000000000000000 0x5f3 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .debug_macro 0x0000000000000000 0x12f Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .debug_macro 0x0000000000000000 0x1a7 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .debug_macro 0x0000000000000000 0x1a7 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .debug_macro 0x0000000000000000 0x22c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .debug_macro 0x0000000000000000 0x34 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .debug_macro 0x0000000000000000 0x43 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .debug_macro 0x0000000000000000 0x28 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .debug_macro 0x0000000000000000 0xb0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .debug_macro 0x0000000000000000 0x217 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .debug_macro 0x0000000000000000 0x22c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .debug_macro 0x0000000000000000 0x5f Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .debug_macro 0x0000000000000000 0xa5 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .debug_macro 0x0000000000000000 0x65 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .debug_macro 0x0000000000000000 0x234 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .debug_macro 0x0000000000000000 0x4c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .debug_macro 0x0000000000000000 0x16d Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .debug_macro 0x0000000000000000 0x130 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .debug_line 0x0000000000000000 0x768 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .debug_str 0x0000000000000000 0x70e51 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .comment 0x0000000000000000 0x7c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .debug_frame 0x0000000000000000 0x170 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .ARM.attributes + 0x0000000000000000 0x31 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .text 0x0000000000000000 0x0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .data 0x0000000000000000 0x0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .bss 0x0000000000000000 0x0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .text.HAL_PWR_ConfigPVD + 0x0000000000000000 0xc4 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .text.HAL_PWR_EnablePVD + 0x0000000000000000 0x1c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .text.HAL_PWR_DisablePVD + 0x0000000000000000 0x1c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .text.HAL_PWR_PVD_IRQHandler + 0x0000000000000000 0x28 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .text.HAL_PWR_PVDCallback + 0x0000000000000000 0xa Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .text.HAL_PWREx_EnableVddio2Monitor + 0x0000000000000000 0x2c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .text.HAL_PWREx_DisableVddio2Monitor + 0x0000000000000000 0x34 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .text.HAL_PWREx_Vddio2Monitor_IRQHandler + 0x0000000000000000 0x24 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .text.HAL_PWREx_Vddio2MonitorCallback + 0x0000000000000000 0xa Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .debug_info 0x0000000000000000 0x2d7 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .debug_abbrev 0x0000000000000000 0x155 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .debug_aranges + 0x0000000000000000 0x60 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .debug_ranges 0x0000000000000000 0x50 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .debug_macro 0x0000000000000000 0x1cd Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .debug_macro 0x0000000000000000 0xa48 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .debug_macro 0x0000000000000000 0x12d Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .debug_macro 0x0000000000000000 0x2e Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .debug_macro 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .debug_macro 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .debug_macro 0x0000000000000000 0x8e Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .debug_macro 0x0000000000000000 0x51 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .debug_macro 0x0000000000000000 0xef Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .debug_macro 0x0000000000000000 0x6a Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .debug_macro 0x0000000000000000 0x1df Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .debug_macro 0x0000000000000000 0x1c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .debug_macro 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .debug_macro 0x0000000000000000 0xb5 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .debug_macro 0x0000000000000000 0x391 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .debug_macro 0x0000000000000000 0xfe50 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .debug_macro 0x0000000000000000 0x3c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .debug_macro 0x0000000000000000 0x174 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .debug_macro 0x0000000000000000 0x53 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .debug_macro 0x0000000000000000 0x946 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .debug_macro 0x0000000000000000 0x5f3 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .debug_macro 0x0000000000000000 0x12f Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .debug_macro 0x0000000000000000 0x1a7 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .debug_macro 0x0000000000000000 0x1a7 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .debug_macro 0x0000000000000000 0x22c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .debug_macro 0x0000000000000000 0x34 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .debug_macro 0x0000000000000000 0x43 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .debug_macro 0x0000000000000000 0x28 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .debug_macro 0x0000000000000000 0xb0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .debug_macro 0x0000000000000000 0x217 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .debug_macro 0x0000000000000000 0x22c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .debug_macro 0x0000000000000000 0x5f Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .debug_macro 0x0000000000000000 0xa5 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .debug_macro 0x0000000000000000 0x65 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .debug_macro 0x0000000000000000 0x234 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .debug_macro 0x0000000000000000 0x4c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .debug_macro 0x0000000000000000 0x16d Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .debug_macro 0x0000000000000000 0x130 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .debug_line 0x0000000000000000 0x72e Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .debug_str 0x0000000000000000 0x70e1c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .comment 0x0000000000000000 0x7c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .debug_frame 0x0000000000000000 0x110 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .ARM.attributes + 0x0000000000000000 0x31 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .text 0x0000000000000000 0x0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .data 0x0000000000000000 0x0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .bss 0x0000000000000000 0x0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .text.HAL_RCC_DeInit + 0x0000000000000000 0x10c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .text.HAL_RCC_MCOConfig + 0x0000000000000000 0x80 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .text.HAL_RCC_EnableCSS + 0x0000000000000000 0x1c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .text.HAL_RCC_DisableCSS + 0x0000000000000000 0x20 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .text.HAL_RCC_GetHCLKFreq + 0x0000000000000000 0x14 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .text.HAL_RCC_GetPCLK1Freq + 0x0000000000000000 0x2c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .text.HAL_RCC_GetOscConfig + 0x0000000000000000 0x158 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .text.HAL_RCC_GetClockConfig + 0x0000000000000000 0x54 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .text.HAL_RCC_NMI_IRQHandler + 0x0000000000000000 0x28 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .text.HAL_RCC_CSSCallback + 0x0000000000000000 0xa Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .debug_macro 0x0000000000000000 0xa48 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .debug_macro 0x0000000000000000 0x12d Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .debug_macro 0x0000000000000000 0x2e Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .debug_macro 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .debug_macro 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .debug_macro 0x0000000000000000 0x8e Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .debug_macro 0x0000000000000000 0x51 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .debug_macro 0x0000000000000000 0xef Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .debug_macro 0x0000000000000000 0x6a Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .debug_macro 0x0000000000000000 0x1df Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .debug_macro 0x0000000000000000 0x1c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .debug_macro 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .debug_macro 0x0000000000000000 0xb5 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .debug_macro 0x0000000000000000 0x391 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .debug_macro 0x0000000000000000 0xfe50 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .debug_macro 0x0000000000000000 0x3c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .debug_macro 0x0000000000000000 0x174 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .debug_macro 0x0000000000000000 0x53 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .debug_macro 0x0000000000000000 0x946 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .debug_macro 0x0000000000000000 0x5f3 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .debug_macro 0x0000000000000000 0x12f Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .debug_macro 0x0000000000000000 0x1a7 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .debug_macro 0x0000000000000000 0x1a7 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .debug_macro 0x0000000000000000 0x22c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .debug_macro 0x0000000000000000 0x34 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .debug_macro 0x0000000000000000 0x43 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .debug_macro 0x0000000000000000 0x28 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .debug_macro 0x0000000000000000 0xb0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .debug_macro 0x0000000000000000 0x217 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .debug_macro 0x0000000000000000 0x22c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .debug_macro 0x0000000000000000 0x5f Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .debug_macro 0x0000000000000000 0xa5 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .debug_macro 0x0000000000000000 0x65 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .debug_macro 0x0000000000000000 0x234 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .debug_macro 0x0000000000000000 0x4c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .debug_macro 0x0000000000000000 0x16d Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .debug_macro 0x0000000000000000 0x130 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .text 0x0000000000000000 0x0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .data 0x0000000000000000 0x0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .bss 0x0000000000000000 0x0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .text.HAL_RCCEx_GetPeriphCLKConfig + 0x0000000000000000 0x94 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .text.HAL_RCCEx_GetPeriphCLKFreq + 0x0000000000000000 0x2f0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .text.HAL_RCCEx_CRSConfig + 0x0000000000000000 0x90 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .text.HAL_RCCEx_CRSSoftwareSynchronizationGenerate + 0x0000000000000000 0x1c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .text.HAL_RCCEx_CRSGetSynchronizationInfo + 0x0000000000000000 0x4c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .text.HAL_RCCEx_CRSWaitSynchronization + 0x0000000000000000 0xf4 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .text.HAL_RCCEx_CRS_IRQHandler + 0x0000000000000000 0xcc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .text.HAL_RCCEx_CRS_SyncOkCallback + 0x0000000000000000 0xa Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .text.HAL_RCCEx_CRS_SyncWarnCallback + 0x0000000000000000 0xa Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .text.HAL_RCCEx_CRS_ExpectedSyncCallback + 0x0000000000000000 0xa Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .text.HAL_RCCEx_CRS_ErrorCallback + 0x0000000000000000 0x10 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .debug_macro 0x0000000000000000 0xa48 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .debug_macro 0x0000000000000000 0x12d Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .debug_macro 0x0000000000000000 0x2e Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .debug_macro 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .debug_macro 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .debug_macro 0x0000000000000000 0x8e Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .debug_macro 0x0000000000000000 0x51 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .debug_macro 0x0000000000000000 0xef Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .debug_macro 0x0000000000000000 0x6a Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .debug_macro 0x0000000000000000 0x1df Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .debug_macro 0x0000000000000000 0x1c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .debug_macro 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .debug_macro 0x0000000000000000 0xb5 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .debug_macro 0x0000000000000000 0x391 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .debug_macro 0x0000000000000000 0xfe50 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .debug_macro 0x0000000000000000 0x3c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .debug_macro 0x0000000000000000 0x174 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .debug_macro 0x0000000000000000 0x53 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .debug_macro 0x0000000000000000 0x946 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .debug_macro 0x0000000000000000 0x5f3 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .debug_macro 0x0000000000000000 0x12f Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .debug_macro 0x0000000000000000 0x1a7 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .debug_macro 0x0000000000000000 0x1a7 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .debug_macro 0x0000000000000000 0x22c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .debug_macro 0x0000000000000000 0x34 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .debug_macro 0x0000000000000000 0x43 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .debug_macro 0x0000000000000000 0x28 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .debug_macro 0x0000000000000000 0xb0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .debug_macro 0x0000000000000000 0x217 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .debug_macro 0x0000000000000000 0x22c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .debug_macro 0x0000000000000000 0x5f Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .debug_macro 0x0000000000000000 0xa5 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .debug_macro 0x0000000000000000 0x65 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .debug_macro 0x0000000000000000 0x234 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .debug_macro 0x0000000000000000 0x4c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .debug_macro 0x0000000000000000 0x16d Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .debug_macro 0x0000000000000000 0x130 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .text 0x0000000000000000 0x0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .data 0x0000000000000000 0x0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .bss 0x0000000000000000 0x0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .debug_info 0x0000000000000000 0x145 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .debug_abbrev 0x0000000000000000 0x92 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .debug_aranges + 0x0000000000000000 0x18 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .debug_macro 0x0000000000000000 0x1b6 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .debug_macro 0x0000000000000000 0xa48 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .debug_macro 0x0000000000000000 0x12d Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .debug_macro 0x0000000000000000 0x2e Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .debug_macro 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .debug_macro 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .debug_macro 0x0000000000000000 0x8e Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .debug_macro 0x0000000000000000 0x51 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .debug_macro 0x0000000000000000 0xef Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .debug_macro 0x0000000000000000 0x6a Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .debug_macro 0x0000000000000000 0x1df Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .debug_macro 0x0000000000000000 0x1c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .debug_macro 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .debug_macro 0x0000000000000000 0xb5 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .debug_macro 0x0000000000000000 0x391 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .debug_macro 0x0000000000000000 0xfe50 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .debug_macro 0x0000000000000000 0x3c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .debug_macro 0x0000000000000000 0x174 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .debug_macro 0x0000000000000000 0x53 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .debug_macro 0x0000000000000000 0x946 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .debug_macro 0x0000000000000000 0x5f3 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .debug_macro 0x0000000000000000 0x12f Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .debug_macro 0x0000000000000000 0x1a7 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .debug_macro 0x0000000000000000 0x1a7 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .debug_macro 0x0000000000000000 0x22c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .debug_macro 0x0000000000000000 0x34 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .debug_macro 0x0000000000000000 0x43 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .debug_macro 0x0000000000000000 0x28 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .debug_macro 0x0000000000000000 0xb0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .debug_macro 0x0000000000000000 0x217 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .debug_macro 0x0000000000000000 0x22c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .debug_macro 0x0000000000000000 0x5f Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .debug_macro 0x0000000000000000 0xa5 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .debug_macro 0x0000000000000000 0x65 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .debug_macro 0x0000000000000000 0x234 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .debug_macro 0x0000000000000000 0x4c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .debug_macro 0x0000000000000000 0x16d Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .debug_macro 0x0000000000000000 0x130 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .debug_line 0x0000000000000000 0x67a Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .debug_str 0x0000000000000000 0x70c6e Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .comment 0x0000000000000000 0x7c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .ARM.attributes + 0x0000000000000000 0x31 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .text 0x0000000000000000 0x0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .data 0x0000000000000000 0x0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .bss 0x0000000000000000 0x0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .debug_info 0x0000000000000000 0x145 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .debug_abbrev 0x0000000000000000 0x92 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .debug_aranges + 0x0000000000000000 0x18 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .debug_macro 0x0000000000000000 0x1b5 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .debug_macro 0x0000000000000000 0xa48 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .debug_macro 0x0000000000000000 0x12d Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .debug_macro 0x0000000000000000 0x2e Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .debug_macro 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .debug_macro 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .debug_macro 0x0000000000000000 0x8e Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .debug_macro 0x0000000000000000 0x51 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .debug_macro 0x0000000000000000 0xef Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .debug_macro 0x0000000000000000 0x6a Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .debug_macro 0x0000000000000000 0x1df Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .debug_macro 0x0000000000000000 0x1c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .debug_macro 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .debug_macro 0x0000000000000000 0xb5 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .debug_macro 0x0000000000000000 0x391 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .debug_macro 0x0000000000000000 0xfe50 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .debug_macro 0x0000000000000000 0x3c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .debug_macro 0x0000000000000000 0x174 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .debug_macro 0x0000000000000000 0x53 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .debug_macro 0x0000000000000000 0x946 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .debug_macro 0x0000000000000000 0x5f3 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .debug_macro 0x0000000000000000 0x12f Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .debug_macro 0x0000000000000000 0x1a7 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .debug_macro 0x0000000000000000 0x1a7 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .debug_macro 0x0000000000000000 0x22c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .debug_macro 0x0000000000000000 0x34 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .debug_macro 0x0000000000000000 0x43 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .debug_macro 0x0000000000000000 0x28 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .debug_macro 0x0000000000000000 0xb0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .debug_macro 0x0000000000000000 0x217 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .debug_macro 0x0000000000000000 0x22c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .debug_macro 0x0000000000000000 0x5f Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .debug_macro 0x0000000000000000 0xa5 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .debug_macro 0x0000000000000000 0x65 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .debug_macro 0x0000000000000000 0x234 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .debug_macro 0x0000000000000000 0x4c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .debug_macro 0x0000000000000000 0x16d Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .debug_macro 0x0000000000000000 0x130 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .debug_line 0x0000000000000000 0x67d Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .debug_str 0x0000000000000000 0x70c71 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .comment 0x0000000000000000 0x7c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .ARM.attributes + 0x0000000000000000 0x31 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .group 0x0000000000000000 0xc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .text 0x0000000000000000 0x0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .data 0x0000000000000000 0x0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .bss 0x0000000000000000 0x0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .text.USB_CoreInit + 0x0000000000000000 0x38 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .text.USB_SetCurrentMode + 0x0000000000000000 0x18 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .text.USB_SetDevSpeed + 0x0000000000000000 0x18 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .text.USB_FlushTxFifo + 0x0000000000000000 0x14 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .text.USB_FlushRxFifo + 0x0000000000000000 0x12 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .text.USB_WritePacket + 0x0000000000000000 0x20 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .text.USB_ReadPacket + 0x0000000000000000 0x18 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .text.USB_StopDevice + 0x0000000000000000 0x2a Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .text.USB_DevDisconnect + 0x0000000000000000 0x26 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .text.USB_ReadDevAllOutEpInterrupt + 0x0000000000000000 0x12 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .text.USB_ReadDevAllInEpInterrupt + 0x0000000000000000 0x12 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .text.USB_ReadDevOutEPInterrupt + 0x0000000000000000 0x18 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .text.USB_ReadDevInEPInterrupt + 0x0000000000000000 0x18 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .text.USB_ClearInterrupts + 0x0000000000000000 0x12 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .text.USB_ActivateRemoteWakeup + 0x0000000000000000 0x26 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .text.USB_DeActivateRemoteWakeup + 0x0000000000000000 0x26 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .debug_macro 0x0000000000000000 0xa48 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .debug_macro 0x0000000000000000 0x12d Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .debug_macro 0x0000000000000000 0x2e Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .debug_macro 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .debug_macro 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .debug_macro 0x0000000000000000 0x8e Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .debug_macro 0x0000000000000000 0x51 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .debug_macro 0x0000000000000000 0xef Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .debug_macro 0x0000000000000000 0x6a Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .debug_macro 0x0000000000000000 0x1df Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .debug_macro 0x0000000000000000 0x1c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .debug_macro 0x0000000000000000 0x22 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .debug_macro 0x0000000000000000 0xb5 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .debug_macro 0x0000000000000000 0x391 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .debug_macro 0x0000000000000000 0xfe50 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .debug_macro 0x0000000000000000 0x3c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .debug_macro 0x0000000000000000 0x174 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .debug_macro 0x0000000000000000 0x53 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .debug_macro 0x0000000000000000 0x946 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .debug_macro 0x0000000000000000 0x5f3 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .debug_macro 0x0000000000000000 0x12f Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .debug_macro 0x0000000000000000 0x1a7 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .debug_macro 0x0000000000000000 0x1a7 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .debug_macro 0x0000000000000000 0x22c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .debug_macro 0x0000000000000000 0x34 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .debug_macro 0x0000000000000000 0x43 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .debug_macro 0x0000000000000000 0x28 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .debug_macro 0x0000000000000000 0xb0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .debug_macro 0x0000000000000000 0x217 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .debug_macro 0x0000000000000000 0x22c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .debug_macro 0x0000000000000000 0x5f Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .debug_macro 0x0000000000000000 0xa5 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .debug_macro 0x0000000000000000 0x65 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .debug_macro 0x0000000000000000 0x234 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .debug_macro 0x0000000000000000 0x4c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .debug_macro 0x0000000000000000 0x16d Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .debug_macro 0x0000000000000000 0x130 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .group 0x0000000000000000 0xc ecm_src/dhcp-server/dhserver.o + .group 0x0000000000000000 0xc ecm_src/dhcp-server/dhserver.o + .group 0x0000000000000000 0xc ecm_src/dhcp-server/dhserver.o + .group 0x0000000000000000 0xc ecm_src/dhcp-server/dhserver.o + .group 0x0000000000000000 0xc ecm_src/dhcp-server/dhserver.o + .group 0x0000000000000000 0xc ecm_src/dhcp-server/dhserver.o + .group 0x0000000000000000 0xc ecm_src/dhcp-server/dhserver.o + .group 0x0000000000000000 0xc ecm_src/dhcp-server/dhserver.o + .group 0x0000000000000000 0xc ecm_src/dhcp-server/dhserver.o + .group 0x0000000000000000 0xc ecm_src/dhcp-server/dhserver.o + .group 0x0000000000000000 0xc ecm_src/dhcp-server/dhserver.o + .group 0x0000000000000000 0xc ecm_src/dhcp-server/dhserver.o + .group 0x0000000000000000 0xc ecm_src/dhcp-server/dhserver.o + .group 0x0000000000000000 0xc ecm_src/dhcp-server/dhserver.o + .group 0x0000000000000000 0xc ecm_src/dhcp-server/dhserver.o + .group 0x0000000000000000 0xc ecm_src/dhcp-server/dhserver.o + .group 0x0000000000000000 0xc ecm_src/dhcp-server/dhserver.o + .group 0x0000000000000000 0xc ecm_src/dhcp-server/dhserver.o + .group 0x0000000000000000 0xc ecm_src/dhcp-server/dhserver.o + .group 0x0000000000000000 0xc ecm_src/dhcp-server/dhserver.o + .group 0x0000000000000000 0xc ecm_src/dhcp-server/dhserver.o + .group 0x0000000000000000 0xc ecm_src/dhcp-server/dhserver.o + .group 0x0000000000000000 0xc ecm_src/dhcp-server/dhserver.o + .group 0x0000000000000000 0xc ecm_src/dhcp-server/dhserver.o + .group 0x0000000000000000 0xc ecm_src/dhcp-server/dhserver.o + .group 0x0000000000000000 0xc ecm_src/dhcp-server/dhserver.o + .group 0x0000000000000000 0xc ecm_src/dhcp-server/dhserver.o + .group 0x0000000000000000 0xc ecm_src/dhcp-server/dhserver.o + .group 0x0000000000000000 0xc ecm_src/dhcp-server/dhserver.o + .group 0x0000000000000000 0xc ecm_src/dhcp-server/dhserver.o + .group 0x0000000000000000 0xc ecm_src/dhcp-server/dhserver.o + .group 0x0000000000000000 0xc ecm_src/dhcp-server/dhserver.o + .group 0x0000000000000000 0xc ecm_src/dhcp-server/dhserver.o + .group 0x0000000000000000 0xc ecm_src/dhcp-server/dhserver.o + .group 0x0000000000000000 0xc ecm_src/dhcp-server/dhserver.o + .group 0x0000000000000000 0xc ecm_src/dhcp-server/dhserver.o + .group 0x0000000000000000 0xc ecm_src/dhcp-server/dhserver.o + .group 0x0000000000000000 0xc ecm_src/dhcp-server/dhserver.o + .group 0x0000000000000000 0xc ecm_src/dhcp-server/dhserver.o + .group 0x0000000000000000 0xc ecm_src/dhcp-server/dhserver.o + .group 0x0000000000000000 0xc ecm_src/dhcp-server/dhserver.o + .group 0x0000000000000000 0xc ecm_src/dhcp-server/dhserver.o + .group 0x0000000000000000 0xc ecm_src/dhcp-server/dhserver.o + .group 0x0000000000000000 0xc ecm_src/dhcp-server/dhserver.o + .group 0x0000000000000000 0xc ecm_src/dhcp-server/dhserver.o + .group 0x0000000000000000 0xc ecm_src/dhcp-server/dhserver.o + .group 0x0000000000000000 0xc ecm_src/dhcp-server/dhserver.o + .group 0x0000000000000000 0xc ecm_src/dhcp-server/dhserver.o + .group 0x0000000000000000 0xc ecm_src/dhcp-server/dhserver.o + .group 0x0000000000000000 0xc ecm_src/dhcp-server/dhserver.o + .group 0x0000000000000000 0xc ecm_src/dhcp-server/dhserver.o + .text 0x0000000000000000 0x0 ecm_src/dhcp-server/dhserver.o + .data 0x0000000000000000 0x0 ecm_src/dhcp-server/dhserver.o + .bss 0x0000000000000000 0x0 ecm_src/dhcp-server/dhserver.o + .debug_macro 0x0000000000000000 0xa48 ecm_src/dhcp-server/dhserver.o + .debug_macro 0x0000000000000000 0x22 ecm_src/dhcp-server/dhserver.o + .debug_macro 0x0000000000000000 0x8e ecm_src/dhcp-server/dhserver.o + .debug_macro 0x0000000000000000 0x51 ecm_src/dhcp-server/dhserver.o + .debug_macro 0x0000000000000000 0xef ecm_src/dhcp-server/dhserver.o + .debug_macro 0x0000000000000000 0x6a ecm_src/dhcp-server/dhserver.o + .debug_macro 0x0000000000000000 0x1df ecm_src/dhcp-server/dhserver.o + .debug_macro 0x0000000000000000 0x22 ecm_src/dhcp-server/dhserver.o + .debug_macro 0x0000000000000000 0x46 ecm_src/dhcp-server/dhserver.o + .debug_macro 0x0000000000000000 0x18 ecm_src/dhcp-server/dhserver.o + .debug_macro 0x0000000000000000 0x3c ecm_src/dhcp-server/dhserver.o + .debug_macro 0x0000000000000000 0x34 ecm_src/dhcp-server/dhserver.o + .debug_macro 0x0000000000000000 0x16 ecm_src/dhcp-server/dhserver.o + .debug_macro 0x0000000000000000 0x330 ecm_src/dhcp-server/dhserver.o + .debug_macro 0x0000000000000000 0x10 ecm_src/dhcp-server/dhserver.o + .debug_macro 0x0000000000000000 0x52 ecm_src/dhcp-server/dhserver.o + .debug_macro 0x0000000000000000 0x1f ecm_src/dhcp-server/dhserver.o + .debug_macro 0x0000000000000000 0x43 ecm_src/dhcp-server/dhserver.o + .debug_macro 0x0000000000000000 0x20 ecm_src/dhcp-server/dhserver.o + .debug_macro 0x0000000000000000 0x1a3 ecm_src/dhcp-server/dhserver.o + .debug_macro 0x0000000000000000 0x10 ecm_src/dhcp-server/dhserver.o + .debug_macro 0x0000000000000000 0x1c ecm_src/dhcp-server/dhserver.o + .debug_macro 0x0000000000000000 0x52 ecm_src/dhcp-server/dhserver.o + .debug_macro 0x0000000000000000 0x40 ecm_src/dhcp-server/dhserver.o + .debug_macro 0x0000000000000000 0x10 ecm_src/dhcp-server/dhserver.o + .debug_macro 0x0000000000000000 0x40 ecm_src/dhcp-server/dhserver.o + .debug_macro 0x0000000000000000 0xd7 ecm_src/dhcp-server/dhserver.o + .debug_macro 0x0000000000000000 0x1c ecm_src/dhcp-server/dhserver.o + .debug_macro 0x0000000000000000 0x3d ecm_src/dhcp-server/dhserver.o + .debug_macro 0x0000000000000000 0x16 ecm_src/dhcp-server/dhserver.o + .debug_macro 0x0000000000000000 0x145 ecm_src/dhcp-server/dhserver.o + .debug_macro 0x0000000000000000 0x16 ecm_src/dhcp-server/dhserver.o + .debug_macro 0x0000000000000000 0x35 ecm_src/dhcp-server/dhserver.o + .debug_macro 0x0000000000000000 0x20 ecm_src/dhcp-server/dhserver.o + .debug_macro 0x0000000000000000 0x70 ecm_src/dhcp-server/dhserver.o + .debug_macro 0x0000000000000000 0x16 ecm_src/dhcp-server/dhserver.o + .debug_macro 0x0000000000000000 0x22 ecm_src/dhcp-server/dhserver.o + .debug_macro 0x0000000000000000 0x16 ecm_src/dhcp-server/dhserver.o + .debug_macro 0x0000000000000000 0x5e ecm_src/dhcp-server/dhserver.o + .debug_macro 0x0000000000000000 0x592 ecm_src/dhcp-server/dhserver.o + .debug_macro 0x0000000000000000 0x52 ecm_src/dhcp-server/dhserver.o + .debug_macro 0x0000000000000000 0x175 ecm_src/dhcp-server/dhserver.o + .debug_macro 0x0000000000000000 0x13b ecm_src/dhcp-server/dhserver.o + .group 0x0000000000000000 0xc ecm_src/dns-server/dnserver.o + .group 0x0000000000000000 0xc ecm_src/dns-server/dnserver.o + .group 0x0000000000000000 0xc ecm_src/dns-server/dnserver.o + .group 0x0000000000000000 0xc ecm_src/dns-server/dnserver.o + .group 0x0000000000000000 0xc ecm_src/dns-server/dnserver.o + .group 0x0000000000000000 0xc ecm_src/dns-server/dnserver.o + .group 0x0000000000000000 0xc ecm_src/dns-server/dnserver.o + .group 0x0000000000000000 0xc ecm_src/dns-server/dnserver.o + .group 0x0000000000000000 0xc ecm_src/dns-server/dnserver.o + .group 0x0000000000000000 0xc ecm_src/dns-server/dnserver.o + .group 0x0000000000000000 0xc ecm_src/dns-server/dnserver.o + .group 0x0000000000000000 0xc ecm_src/dns-server/dnserver.o + .group 0x0000000000000000 0xc ecm_src/dns-server/dnserver.o + .group 0x0000000000000000 0xc ecm_src/dns-server/dnserver.o + .group 0x0000000000000000 0xc ecm_src/dns-server/dnserver.o + .group 0x0000000000000000 0xc ecm_src/dns-server/dnserver.o + .group 0x0000000000000000 0xc ecm_src/dns-server/dnserver.o + .group 0x0000000000000000 0xc ecm_src/dns-server/dnserver.o + .group 0x0000000000000000 0xc ecm_src/dns-server/dnserver.o + .group 0x0000000000000000 0xc ecm_src/dns-server/dnserver.o + .group 0x0000000000000000 0xc ecm_src/dns-server/dnserver.o + .group 0x0000000000000000 0xc ecm_src/dns-server/dnserver.o + .group 0x0000000000000000 0xc ecm_src/dns-server/dnserver.o + .group 0x0000000000000000 0xc ecm_src/dns-server/dnserver.o + .group 0x0000000000000000 0xc ecm_src/dns-server/dnserver.o + .group 0x0000000000000000 0xc ecm_src/dns-server/dnserver.o + .group 0x0000000000000000 0xc ecm_src/dns-server/dnserver.o + .group 0x0000000000000000 0xc ecm_src/dns-server/dnserver.o + .group 0x0000000000000000 0xc ecm_src/dns-server/dnserver.o + .group 0x0000000000000000 0xc ecm_src/dns-server/dnserver.o + .group 0x0000000000000000 0xc ecm_src/dns-server/dnserver.o + .group 0x0000000000000000 0xc ecm_src/dns-server/dnserver.o + .group 0x0000000000000000 0xc ecm_src/dns-server/dnserver.o + .group 0x0000000000000000 0xc ecm_src/dns-server/dnserver.o + .group 0x0000000000000000 0xc ecm_src/dns-server/dnserver.o + .group 0x0000000000000000 0xc ecm_src/dns-server/dnserver.o + .group 0x0000000000000000 0xc ecm_src/dns-server/dnserver.o + .group 0x0000000000000000 0xc ecm_src/dns-server/dnserver.o + .group 0x0000000000000000 0xc ecm_src/dns-server/dnserver.o + .group 0x0000000000000000 0xc ecm_src/dns-server/dnserver.o + .group 0x0000000000000000 0xc ecm_src/dns-server/dnserver.o + .group 0x0000000000000000 0xc ecm_src/dns-server/dnserver.o + .group 0x0000000000000000 0xc ecm_src/dns-server/dnserver.o + .group 0x0000000000000000 0xc ecm_src/dns-server/dnserver.o + .group 0x0000000000000000 0xc ecm_src/dns-server/dnserver.o + .group 0x0000000000000000 0xc ecm_src/dns-server/dnserver.o + .group 0x0000000000000000 0xc ecm_src/dns-server/dnserver.o + .group 0x0000000000000000 0xc ecm_src/dns-server/dnserver.o + .group 0x0000000000000000 0xc ecm_src/dns-server/dnserver.o + .group 0x0000000000000000 0xc ecm_src/dns-server/dnserver.o + .group 0x0000000000000000 0xc ecm_src/dns-server/dnserver.o + .text 0x0000000000000000 0x0 ecm_src/dns-server/dnserver.o + .data 0x0000000000000000 0x0 ecm_src/dns-server/dnserver.o + .bss 0x0000000000000000 0x0 ecm_src/dns-server/dnserver.o + .debug_macro 0x0000000000000000 0xa48 ecm_src/dns-server/dnserver.o + .debug_macro 0x0000000000000000 0x22 ecm_src/dns-server/dnserver.o + .debug_macro 0x0000000000000000 0x8e ecm_src/dns-server/dnserver.o + .debug_macro 0x0000000000000000 0x51 ecm_src/dns-server/dnserver.o + .debug_macro 0x0000000000000000 0xef ecm_src/dns-server/dnserver.o + .debug_macro 0x0000000000000000 0x6a ecm_src/dns-server/dnserver.o + .debug_macro 0x0000000000000000 0x1df ecm_src/dns-server/dnserver.o + .debug_macro 0x0000000000000000 0x22 ecm_src/dns-server/dnserver.o + .debug_macro 0x0000000000000000 0x46 ecm_src/dns-server/dnserver.o + .debug_macro 0x0000000000000000 0x18 ecm_src/dns-server/dnserver.o + .debug_macro 0x0000000000000000 0x3c ecm_src/dns-server/dnserver.o + .debug_macro 0x0000000000000000 0x34 ecm_src/dns-server/dnserver.o + .debug_macro 0x0000000000000000 0x16 ecm_src/dns-server/dnserver.o + .debug_macro 0x0000000000000000 0x97 ecm_src/dns-server/dnserver.o + .debug_macro 0x0000000000000000 0x330 ecm_src/dns-server/dnserver.o + .debug_macro 0x0000000000000000 0xfd ecm_src/dns-server/dnserver.o + .debug_macro 0x0000000000000000 0x10 ecm_src/dns-server/dnserver.o + .debug_macro 0x0000000000000000 0x52 ecm_src/dns-server/dnserver.o + .debug_macro 0x0000000000000000 0x1f ecm_src/dns-server/dnserver.o + .debug_macro 0x0000000000000000 0x43 ecm_src/dns-server/dnserver.o + .debug_macro 0x0000000000000000 0x20 ecm_src/dns-server/dnserver.o + .debug_macro 0x0000000000000000 0x1a3 ecm_src/dns-server/dnserver.o + .debug_macro 0x0000000000000000 0x10 ecm_src/dns-server/dnserver.o + .debug_macro 0x0000000000000000 0x1c ecm_src/dns-server/dnserver.o + .debug_macro 0x0000000000000000 0x52 ecm_src/dns-server/dnserver.o + .debug_macro 0x0000000000000000 0x40 ecm_src/dns-server/dnserver.o + .debug_macro 0x0000000000000000 0x10 ecm_src/dns-server/dnserver.o + .debug_macro 0x0000000000000000 0x40 ecm_src/dns-server/dnserver.o + .debug_macro 0x0000000000000000 0xd7 ecm_src/dns-server/dnserver.o + .debug_macro 0x0000000000000000 0x1c ecm_src/dns-server/dnserver.o + .debug_macro 0x0000000000000000 0x3d ecm_src/dns-server/dnserver.o + .debug_macro 0x0000000000000000 0x16 ecm_src/dns-server/dnserver.o + .debug_macro 0x0000000000000000 0x145 ecm_src/dns-server/dnserver.o + .debug_macro 0x0000000000000000 0x16 ecm_src/dns-server/dnserver.o + .debug_macro 0x0000000000000000 0x35 ecm_src/dns-server/dnserver.o + .debug_macro 0x0000000000000000 0x20 ecm_src/dns-server/dnserver.o + .debug_macro 0x0000000000000000 0x16 ecm_src/dns-server/dnserver.o + .debug_macro 0x0000000000000000 0x22 ecm_src/dns-server/dnserver.o + .debug_macro 0x0000000000000000 0x16 ecm_src/dns-server/dnserver.o + .debug_macro 0x0000000000000000 0x70 ecm_src/dns-server/dnserver.o + .debug_macro 0x0000000000000000 0x5e ecm_src/dns-server/dnserver.o + .debug_macro 0x0000000000000000 0x592 ecm_src/dns-server/dnserver.o + .debug_macro 0x0000000000000000 0x76 ecm_src/dns-server/dnserver.o + .debug_macro 0x0000000000000000 0x55 ecm_src/dns-server/dnserver.o + .debug_macro 0x0000000000000000 0x10 ecm_src/dns-server/dnserver.o + .debug_macro 0x0000000000000000 0x56 ecm_src/dns-server/dnserver.o + .debug_macro 0x0000000000000000 0x13b ecm_src/dns-server/dnserver.o + .debug_macro 0x0000000000000000 0x37 ecm_src/dns-server/dnserver.o + .debug_macro 0x0000000000000000 0x86 ecm_src/dns-server/dnserver.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/def.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/def.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/def.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/def.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/def.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/def.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/def.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/def.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/def.o + .text 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/def.o + .data 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/def.o + .bss 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/def.o + .debug_macro 0x0000000000000000 0xa48 ecm_src/lwip-1.4.1/src/core/def.o + .debug_macro 0x0000000000000000 0x70 ecm_src/lwip-1.4.1/src/core/def.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/core/def.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/core/def.o + .debug_macro 0x0000000000000000 0x5e ecm_src/lwip-1.4.1/src/core/def.o + .debug_macro 0x0000000000000000 0x592 ecm_src/lwip-1.4.1/src/core/def.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/dhcp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/dhcp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/dhcp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/dhcp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/dhcp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/dhcp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/dhcp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/dhcp.o + .text 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/dhcp.o + .data 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/dhcp.o + .bss 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/dhcp.o + .debug_info 0x0000000000000000 0x4c ecm_src/lwip-1.4.1/src/core/dhcp.o + .debug_abbrev 0x0000000000000000 0x1e ecm_src/lwip-1.4.1/src/core/dhcp.o + .debug_aranges + 0x0000000000000000 0x18 ecm_src/lwip-1.4.1/src/core/dhcp.o + .debug_macro 0x0000000000000000 0x62 ecm_src/lwip-1.4.1/src/core/dhcp.o + .debug_macro 0x0000000000000000 0xa48 ecm_src/lwip-1.4.1/src/core/dhcp.o + .debug_macro 0x0000000000000000 0x70 ecm_src/lwip-1.4.1/src/core/dhcp.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/core/dhcp.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/dhcp.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/core/dhcp.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/core/dhcp.o + .debug_macro 0x0000000000000000 0x5e ecm_src/lwip-1.4.1/src/core/dhcp.o + .debug_macro 0x0000000000000000 0x592 ecm_src/lwip-1.4.1/src/core/dhcp.o + .debug_line 0x0000000000000000 0x13f ecm_src/lwip-1.4.1/src/core/dhcp.o + .debug_str 0x0000000000000000 0x45b0 ecm_src/lwip-1.4.1/src/core/dhcp.o + .comment 0x0000000000000000 0x7c ecm_src/lwip-1.4.1/src/core/dhcp.o + .ARM.attributes + 0x0000000000000000 0x31 ecm_src/lwip-1.4.1/src/core/dhcp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/dns.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/dns.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/dns.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/dns.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/dns.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/dns.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/dns.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/dns.o + .text 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/dns.o + .data 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/dns.o + .bss 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/dns.o + .debug_info 0x0000000000000000 0x4c ecm_src/lwip-1.4.1/src/core/dns.o + .debug_abbrev 0x0000000000000000 0x1e ecm_src/lwip-1.4.1/src/core/dns.o + .debug_aranges + 0x0000000000000000 0x18 ecm_src/lwip-1.4.1/src/core/dns.o + .debug_macro 0x0000000000000000 0x62 ecm_src/lwip-1.4.1/src/core/dns.o + .debug_macro 0x0000000000000000 0xa48 ecm_src/lwip-1.4.1/src/core/dns.o + .debug_macro 0x0000000000000000 0x70 ecm_src/lwip-1.4.1/src/core/dns.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/core/dns.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/dns.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/core/dns.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/core/dns.o + .debug_macro 0x0000000000000000 0x5e ecm_src/lwip-1.4.1/src/core/dns.o + .debug_macro 0x0000000000000000 0x592 ecm_src/lwip-1.4.1/src/core/dns.o + .debug_line 0x0000000000000000 0x13e ecm_src/lwip-1.4.1/src/core/dns.o + .debug_str 0x0000000000000000 0x45af ecm_src/lwip-1.4.1/src/core/dns.o + .comment 0x0000000000000000 0x7c ecm_src/lwip-1.4.1/src/core/dns.o + .ARM.attributes + 0x0000000000000000 0x31 ecm_src/lwip-1.4.1/src/core/dns.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/init.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/init.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/init.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/init.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/init.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/init.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/init.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/init.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/init.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/init.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/init.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/init.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/init.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/init.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/init.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/init.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/init.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/init.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/init.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/init.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/init.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/init.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/init.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/init.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/init.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/init.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/init.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/init.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/init.o + .text 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/init.o + .data 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/init.o + .bss 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/init.o + .debug_macro 0x0000000000000000 0xa48 ecm_src/lwip-1.4.1/src/core/init.o + .debug_macro 0x0000000000000000 0x70 ecm_src/lwip-1.4.1/src/core/init.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/core/init.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/init.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/core/init.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/core/init.o + .debug_macro 0x0000000000000000 0x5e ecm_src/lwip-1.4.1/src/core/init.o + .debug_macro 0x0000000000000000 0x592 ecm_src/lwip-1.4.1/src/core/init.o + .debug_macro 0x0000000000000000 0x46 ecm_src/lwip-1.4.1/src/core/init.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/core/init.o + .debug_macro 0x0000000000000000 0x76 ecm_src/lwip-1.4.1/src/core/init.o + .debug_macro 0x0000000000000000 0x4f ecm_src/lwip-1.4.1/src/core/init.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/init.o + .debug_macro 0x0000000000000000 0x58 ecm_src/lwip-1.4.1/src/core/init.o + .debug_macro 0x0000000000000000 0x175 ecm_src/lwip-1.4.1/src/core/init.o + .debug_macro 0x0000000000000000 0x56 ecm_src/lwip-1.4.1/src/core/init.o + .debug_macro 0x0000000000000000 0x13b ecm_src/lwip-1.4.1/src/core/init.o + .debug_macro 0x0000000000000000 0x3d ecm_src/lwip-1.4.1/src/core/init.o + .debug_macro 0x0000000000000000 0x64 ecm_src/lwip-1.4.1/src/core/init.o + .debug_macro 0x0000000000000000 0xac ecm_src/lwip-1.4.1/src/core/init.o + .debug_macro 0x0000000000000000 0x1be ecm_src/lwip-1.4.1/src/core/init.o + .debug_macro 0x0000000000000000 0x86 ecm_src/lwip-1.4.1/src/core/init.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/mem.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/mem.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/mem.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/mem.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/mem.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/mem.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/mem.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/mem.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/mem.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/mem.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/mem.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/mem.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/mem.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/mem.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/mem.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/mem.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/mem.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/mem.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/mem.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/mem.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/mem.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/mem.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/mem.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/mem.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/mem.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/mem.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/mem.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/mem.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/mem.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/mem.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/mem.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/mem.o + .text 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/mem.o + .data 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/mem.o + .bss 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/mem.o + .text.mem_calloc + 0x0000000000000000 0x4e ecm_src/lwip-1.4.1/src/core/mem.o + .debug_macro 0x0000000000000000 0xa48 ecm_src/lwip-1.4.1/src/core/mem.o + .debug_macro 0x0000000000000000 0x70 ecm_src/lwip-1.4.1/src/core/mem.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/core/mem.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/mem.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/core/mem.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/core/mem.o + .debug_macro 0x0000000000000000 0x5e ecm_src/lwip-1.4.1/src/core/mem.o + .debug_macro 0x0000000000000000 0x592 ecm_src/lwip-1.4.1/src/core/mem.o + .debug_macro 0x0000000000000000 0x58 ecm_src/lwip-1.4.1/src/core/mem.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/core/mem.o + .debug_macro 0x0000000000000000 0xc5 ecm_src/lwip-1.4.1/src/core/mem.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/mem.o + .debug_macro 0x0000000000000000 0x3a ecm_src/lwip-1.4.1/src/core/mem.o + .debug_macro 0x0000000000000000 0x127 ecm_src/lwip-1.4.1/src/core/mem.o + .debug_macro 0x0000000000000000 0x76 ecm_src/lwip-1.4.1/src/core/mem.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/core/mem.o + .debug_macro 0x0000000000000000 0x40 ecm_src/lwip-1.4.1/src/core/mem.o + .debug_macro 0x0000000000000000 0x18 ecm_src/lwip-1.4.1/src/core/mem.o + .debug_macro 0x0000000000000000 0x94 ecm_src/lwip-1.4.1/src/core/mem.o + .debug_macro 0x0000000000000000 0x3c ecm_src/lwip-1.4.1/src/core/mem.o + .debug_macro 0x0000000000000000 0x34 ecm_src/lwip-1.4.1/src/core/mem.o + .debug_macro 0x0000000000000000 0x174 ecm_src/lwip-1.4.1/src/core/mem.o + .debug_macro 0x0000000000000000 0x57 ecm_src/lwip-1.4.1/src/core/mem.o + .debug_macro 0x0000000000000000 0x52 ecm_src/lwip-1.4.1/src/core/mem.o + .debug_macro 0x0000000000000000 0x1f ecm_src/lwip-1.4.1/src/core/mem.o + .debug_macro 0x0000000000000000 0x43 ecm_src/lwip-1.4.1/src/core/mem.o + .debug_macro 0x0000000000000000 0x20 ecm_src/lwip-1.4.1/src/core/mem.o + .debug_macro 0x0000000000000000 0x1a3 ecm_src/lwip-1.4.1/src/core/mem.o + .debug_macro 0x0000000000000000 0x330 ecm_src/lwip-1.4.1/src/core/mem.o + .debug_macro 0x0000000000000000 0x35 ecm_src/lwip-1.4.1/src/core/mem.o + .debug_macro 0x0000000000000000 0x20 ecm_src/lwip-1.4.1/src/core/mem.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/memp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/memp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/memp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/memp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/memp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/memp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/memp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/memp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/memp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/memp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/memp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/memp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/memp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/memp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/memp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/memp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/memp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/memp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/memp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/memp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/memp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/memp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/memp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/memp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/memp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/memp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/memp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/memp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/memp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/memp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/memp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/memp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/memp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/memp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/memp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/memp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/memp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/memp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/memp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/memp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/memp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/memp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/memp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/memp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/memp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/memp.o + .text 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/memp.o + .data 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/memp.o + .bss 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/memp.o + .debug_macro 0x0000000000000000 0xa48 ecm_src/lwip-1.4.1/src/core/memp.o + .debug_macro 0x0000000000000000 0x70 ecm_src/lwip-1.4.1/src/core/memp.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/core/memp.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/memp.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/core/memp.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/core/memp.o + .debug_macro 0x0000000000000000 0x5e ecm_src/lwip-1.4.1/src/core/memp.o + .debug_macro 0x0000000000000000 0x592 ecm_src/lwip-1.4.1/src/core/memp.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/memp.o + .debug_macro 0x0000000000000000 0x3a ecm_src/lwip-1.4.1/src/core/memp.o + .debug_macro 0x0000000000000000 0x76 ecm_src/lwip-1.4.1/src/core/memp.o + .debug_macro 0x0000000000000000 0x4f ecm_src/lwip-1.4.1/src/core/memp.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/memp.o + .debug_macro 0x0000000000000000 0x58 ecm_src/lwip-1.4.1/src/core/memp.o + .debug_macro 0x0000000000000000 0x175 ecm_src/lwip-1.4.1/src/core/memp.o + .debug_macro 0x0000000000000000 0x56 ecm_src/lwip-1.4.1/src/core/memp.o + .debug_macro 0x0000000000000000 0x13b ecm_src/lwip-1.4.1/src/core/memp.o + .debug_macro 0x0000000000000000 0x37 ecm_src/lwip-1.4.1/src/core/memp.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/memp.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/core/memp.o + .debug_macro 0x0000000000000000 0x64 ecm_src/lwip-1.4.1/src/core/memp.o + .debug_macro 0x0000000000000000 0xac ecm_src/lwip-1.4.1/src/core/memp.o + .debug_macro 0x0000000000000000 0x1be ecm_src/lwip-1.4.1/src/core/memp.o + .debug_macro 0x0000000000000000 0xc5 ecm_src/lwip-1.4.1/src/core/memp.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/core/memp.o + .debug_macro 0x0000000000000000 0x86 ecm_src/lwip-1.4.1/src/core/memp.o + .debug_macro 0x0000000000000000 0x321 ecm_src/lwip-1.4.1/src/core/memp.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/core/memp.o + .debug_macro 0x0000000000000000 0x40 ecm_src/lwip-1.4.1/src/core/memp.o + .debug_macro 0x0000000000000000 0x18 ecm_src/lwip-1.4.1/src/core/memp.o + .debug_macro 0x0000000000000000 0x94 ecm_src/lwip-1.4.1/src/core/memp.o + .debug_macro 0x0000000000000000 0x3c ecm_src/lwip-1.4.1/src/core/memp.o + .debug_macro 0x0000000000000000 0x34 ecm_src/lwip-1.4.1/src/core/memp.o + .debug_macro 0x0000000000000000 0x174 ecm_src/lwip-1.4.1/src/core/memp.o + .debug_macro 0x0000000000000000 0x57 ecm_src/lwip-1.4.1/src/core/memp.o + .debug_macro 0x0000000000000000 0x52 ecm_src/lwip-1.4.1/src/core/memp.o + .debug_macro 0x0000000000000000 0x1f ecm_src/lwip-1.4.1/src/core/memp.o + .debug_macro 0x0000000000000000 0x43 ecm_src/lwip-1.4.1/src/core/memp.o + .debug_macro 0x0000000000000000 0x20 ecm_src/lwip-1.4.1/src/core/memp.o + .debug_macro 0x0000000000000000 0x1a3 ecm_src/lwip-1.4.1/src/core/memp.o + .debug_macro 0x0000000000000000 0x330 ecm_src/lwip-1.4.1/src/core/memp.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/memp.o + .debug_macro 0x0000000000000000 0x35 ecm_src/lwip-1.4.1/src/core/memp.o + .debug_macro 0x0000000000000000 0x20 ecm_src/lwip-1.4.1/src/core/memp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/netif.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/netif.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/netif.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/netif.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/netif.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/netif.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/netif.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/netif.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/netif.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/netif.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/netif.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/netif.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/netif.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/netif.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/netif.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/netif.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/netif.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/netif.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/netif.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/netif.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/netif.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/netif.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/netif.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/netif.o + .text 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/netif.o + .data 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/netif.o + .bss 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/netif.o + .text.netif_remove + 0x0000000000000000 0x90 ecm_src/lwip-1.4.1/src/core/netif.o + .text.netif_find + 0x0000000000000000 0x74 ecm_src/lwip-1.4.1/src/core/netif.o + .text.netif_set_up + 0x0000000000000000 0x5a ecm_src/lwip-1.4.1/src/core/netif.o + .text.netif_set_down + 0x0000000000000000 0x46 ecm_src/lwip-1.4.1/src/core/netif.o + .text.netif_set_link_up + 0x0000000000000000 0x5a ecm_src/lwip-1.4.1/src/core/netif.o + .text.netif_set_link_down + 0x0000000000000000 0x30 ecm_src/lwip-1.4.1/src/core/netif.o + .debug_macro 0x0000000000000000 0xa48 ecm_src/lwip-1.4.1/src/core/netif.o + .debug_macro 0x0000000000000000 0x70 ecm_src/lwip-1.4.1/src/core/netif.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/core/netif.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/netif.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/core/netif.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/core/netif.o + .debug_macro 0x0000000000000000 0x5e ecm_src/lwip-1.4.1/src/core/netif.o + .debug_macro 0x0000000000000000 0x592 ecm_src/lwip-1.4.1/src/core/netif.o + .debug_macro 0x0000000000000000 0x58 ecm_src/lwip-1.4.1/src/core/netif.o + .debug_macro 0x0000000000000000 0x17b ecm_src/lwip-1.4.1/src/core/netif.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/netif.o + .debug_macro 0x0000000000000000 0x76 ecm_src/lwip-1.4.1/src/core/netif.o + .debug_macro 0x0000000000000000 0x55 ecm_src/lwip-1.4.1/src/core/netif.o + .debug_macro 0x0000000000000000 0x56 ecm_src/lwip-1.4.1/src/core/netif.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/core/netif.o + .debug_macro 0x0000000000000000 0x13b ecm_src/lwip-1.4.1/src/core/netif.o + .debug_macro 0x0000000000000000 0x64 ecm_src/lwip-1.4.1/src/core/netif.o + .debug_macro 0x0000000000000000 0xac ecm_src/lwip-1.4.1/src/core/netif.o + .debug_macro 0x0000000000000000 0x1be ecm_src/lwip-1.4.1/src/core/netif.o + .debug_macro 0x0000000000000000 0x321 ecm_src/lwip-1.4.1/src/core/netif.o + .debug_macro 0x0000000000000000 0x86 ecm_src/lwip-1.4.1/src/core/netif.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/netif.o + .debug_macro 0x0000000000000000 0x3a ecm_src/lwip-1.4.1/src/core/netif.o + .debug_macro 0x0000000000000000 0x127 ecm_src/lwip-1.4.1/src/core/netif.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/pbuf.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/pbuf.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/pbuf.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/pbuf.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/pbuf.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/pbuf.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/pbuf.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/pbuf.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/pbuf.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/pbuf.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/pbuf.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/pbuf.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/pbuf.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/pbuf.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/pbuf.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/pbuf.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/pbuf.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/pbuf.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/pbuf.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/pbuf.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/pbuf.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/pbuf.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/pbuf.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/pbuf.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/pbuf.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/pbuf.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/pbuf.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/pbuf.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/pbuf.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/pbuf.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/pbuf.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/pbuf.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/pbuf.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/pbuf.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/pbuf.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/pbuf.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/pbuf.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/pbuf.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/pbuf.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/pbuf.o + .text 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/pbuf.o + .data 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/pbuf.o + .bss 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/pbuf.o + .text.pbuf_free_ooseq + 0x0000000000000000 0x48 ecm_src/lwip-1.4.1/src/core/pbuf.o + .text.pbuf_dechain + 0x0000000000000000 0x62 ecm_src/lwip-1.4.1/src/core/pbuf.o + .text.pbuf_take + 0x0000000000000000 0xce ecm_src/lwip-1.4.1/src/core/pbuf.o + .text.pbuf_coalesce + 0x0000000000000000 0x5e ecm_src/lwip-1.4.1/src/core/pbuf.o + .text.pbuf_get_at + 0x0000000000000000 0x76 ecm_src/lwip-1.4.1/src/core/pbuf.o + .text.pbuf_memcmp + 0x0000000000000000 0xf0 ecm_src/lwip-1.4.1/src/core/pbuf.o + .text.pbuf_memfind + 0x0000000000000000 0xa4 ecm_src/lwip-1.4.1/src/core/pbuf.o + .text.pbuf_strstr + 0x0000000000000000 0x60 ecm_src/lwip-1.4.1/src/core/pbuf.o + .debug_macro 0x0000000000000000 0xa48 ecm_src/lwip-1.4.1/src/core/pbuf.o + .debug_macro 0x0000000000000000 0x70 ecm_src/lwip-1.4.1/src/core/pbuf.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/core/pbuf.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/pbuf.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/core/pbuf.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/core/pbuf.o + .debug_macro 0x0000000000000000 0x5e ecm_src/lwip-1.4.1/src/core/pbuf.o + .debug_macro 0x0000000000000000 0x592 ecm_src/lwip-1.4.1/src/core/pbuf.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/core/pbuf.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/pbuf.o + .debug_macro 0x0000000000000000 0x3a ecm_src/lwip-1.4.1/src/core/pbuf.o + .debug_macro 0x0000000000000000 0x127 ecm_src/lwip-1.4.1/src/core/pbuf.o + .debug_macro 0x0000000000000000 0x58 ecm_src/lwip-1.4.1/src/core/pbuf.o + .debug_macro 0x0000000000000000 0x76 ecm_src/lwip-1.4.1/src/core/pbuf.o + .debug_macro 0x0000000000000000 0x4f ecm_src/lwip-1.4.1/src/core/pbuf.o + .debug_macro 0x0000000000000000 0xc5 ecm_src/lwip-1.4.1/src/core/pbuf.o + .debug_macro 0x0000000000000000 0x17b ecm_src/lwip-1.4.1/src/core/pbuf.o + .debug_macro 0x0000000000000000 0x62 ecm_src/lwip-1.4.1/src/core/pbuf.o + .debug_macro 0x0000000000000000 0x64 ecm_src/lwip-1.4.1/src/core/pbuf.o + .debug_macro 0x0000000000000000 0xac ecm_src/lwip-1.4.1/src/core/pbuf.o + .debug_macro 0x0000000000000000 0x1be ecm_src/lwip-1.4.1/src/core/pbuf.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/core/pbuf.o + .debug_macro 0x0000000000000000 0x40 ecm_src/lwip-1.4.1/src/core/pbuf.o + .debug_macro 0x0000000000000000 0x18 ecm_src/lwip-1.4.1/src/core/pbuf.o + .debug_macro 0x0000000000000000 0x94 ecm_src/lwip-1.4.1/src/core/pbuf.o + .debug_macro 0x0000000000000000 0x3c ecm_src/lwip-1.4.1/src/core/pbuf.o + .debug_macro 0x0000000000000000 0x34 ecm_src/lwip-1.4.1/src/core/pbuf.o + .debug_macro 0x0000000000000000 0x174 ecm_src/lwip-1.4.1/src/core/pbuf.o + .debug_macro 0x0000000000000000 0x57 ecm_src/lwip-1.4.1/src/core/pbuf.o + .debug_macro 0x0000000000000000 0x52 ecm_src/lwip-1.4.1/src/core/pbuf.o + .debug_macro 0x0000000000000000 0x1f ecm_src/lwip-1.4.1/src/core/pbuf.o + .debug_macro 0x0000000000000000 0x43 ecm_src/lwip-1.4.1/src/core/pbuf.o + .debug_macro 0x0000000000000000 0x20 ecm_src/lwip-1.4.1/src/core/pbuf.o + .debug_macro 0x0000000000000000 0x1a3 ecm_src/lwip-1.4.1/src/core/pbuf.o + .debug_macro 0x0000000000000000 0x330 ecm_src/lwip-1.4.1/src/core/pbuf.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/pbuf.o + .debug_macro 0x0000000000000000 0x35 ecm_src/lwip-1.4.1/src/core/pbuf.o + .debug_macro 0x0000000000000000 0x20 ecm_src/lwip-1.4.1/src/core/pbuf.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/raw.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/raw.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/raw.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/raw.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/raw.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/raw.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/raw.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/raw.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/raw.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/raw.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/raw.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/raw.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/raw.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/raw.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/raw.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/raw.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/raw.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/raw.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/raw.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/raw.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/raw.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/raw.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/raw.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/raw.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/raw.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/raw.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/raw.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/raw.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/raw.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/raw.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/raw.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/raw.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/raw.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/raw.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/raw.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/raw.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/raw.o + .text 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/raw.o + .data 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/raw.o + .bss 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/raw.o + .text.raw_bind + 0x0000000000000000 0x26 ecm_src/lwip-1.4.1/src/core/raw.o + .text.raw_connect + 0x0000000000000000 0x26 ecm_src/lwip-1.4.1/src/core/raw.o + .text.raw_recv + 0x0000000000000000 0x20 ecm_src/lwip-1.4.1/src/core/raw.o + .text.raw_sendto + 0x0000000000000000 0xf6 ecm_src/lwip-1.4.1/src/core/raw.o + .text.raw_send + 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/core/raw.o + .text.raw_remove + 0x0000000000000000 0x64 ecm_src/lwip-1.4.1/src/core/raw.o + .text.raw_new 0x0000000000000000 0x54 ecm_src/lwip-1.4.1/src/core/raw.o + .debug_macro 0x0000000000000000 0xa48 ecm_src/lwip-1.4.1/src/core/raw.o + .debug_macro 0x0000000000000000 0x70 ecm_src/lwip-1.4.1/src/core/raw.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/core/raw.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/raw.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/core/raw.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/core/raw.o + .debug_macro 0x0000000000000000 0x5e ecm_src/lwip-1.4.1/src/core/raw.o + .debug_macro 0x0000000000000000 0x592 ecm_src/lwip-1.4.1/src/core/raw.o + .debug_macro 0x0000000000000000 0x58 ecm_src/lwip-1.4.1/src/core/raw.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/raw.o + .debug_macro 0x0000000000000000 0x3a ecm_src/lwip-1.4.1/src/core/raw.o + .debug_macro 0x0000000000000000 0x17b ecm_src/lwip-1.4.1/src/core/raw.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/raw.o + .debug_macro 0x0000000000000000 0x76 ecm_src/lwip-1.4.1/src/core/raw.o + .debug_macro 0x0000000000000000 0x55 ecm_src/lwip-1.4.1/src/core/raw.o + .debug_macro 0x0000000000000000 0x56 ecm_src/lwip-1.4.1/src/core/raw.o + .debug_macro 0x0000000000000000 0x13b ecm_src/lwip-1.4.1/src/core/raw.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/core/raw.o + .debug_macro 0x0000000000000000 0x127 ecm_src/lwip-1.4.1/src/core/raw.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/core/raw.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/core/raw.o + .debug_macro 0x0000000000000000 0x40 ecm_src/lwip-1.4.1/src/core/raw.o + .debug_macro 0x0000000000000000 0x18 ecm_src/lwip-1.4.1/src/core/raw.o + .debug_macro 0x0000000000000000 0x94 ecm_src/lwip-1.4.1/src/core/raw.o + .debug_macro 0x0000000000000000 0x3c ecm_src/lwip-1.4.1/src/core/raw.o + .debug_macro 0x0000000000000000 0x34 ecm_src/lwip-1.4.1/src/core/raw.o + .debug_macro 0x0000000000000000 0x174 ecm_src/lwip-1.4.1/src/core/raw.o + .debug_macro 0x0000000000000000 0x57 ecm_src/lwip-1.4.1/src/core/raw.o + .debug_macro 0x0000000000000000 0x52 ecm_src/lwip-1.4.1/src/core/raw.o + .debug_macro 0x0000000000000000 0x1f ecm_src/lwip-1.4.1/src/core/raw.o + .debug_macro 0x0000000000000000 0x43 ecm_src/lwip-1.4.1/src/core/raw.o + .debug_macro 0x0000000000000000 0x20 ecm_src/lwip-1.4.1/src/core/raw.o + .debug_macro 0x0000000000000000 0x1a3 ecm_src/lwip-1.4.1/src/core/raw.o + .debug_macro 0x0000000000000000 0x330 ecm_src/lwip-1.4.1/src/core/raw.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/raw.o + .debug_macro 0x0000000000000000 0x35 ecm_src/lwip-1.4.1/src/core/raw.o + .debug_macro 0x0000000000000000 0x20 ecm_src/lwip-1.4.1/src/core/raw.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/stats.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/stats.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/stats.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/stats.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/stats.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/stats.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/stats.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/stats.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/stats.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/stats.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/stats.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/stats.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/stats.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/stats.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/stats.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/stats.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/stats.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/stats.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/stats.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/stats.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/stats.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/stats.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/stats.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/stats.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/stats.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/stats.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/stats.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/stats.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/stats.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/stats.o + .text 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/stats.o + .data 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/stats.o + .bss 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/stats.o + .debug_macro 0x0000000000000000 0xa48 ecm_src/lwip-1.4.1/src/core/stats.o + .debug_macro 0x0000000000000000 0x70 ecm_src/lwip-1.4.1/src/core/stats.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/core/stats.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/stats.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/core/stats.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/core/stats.o + .debug_macro 0x0000000000000000 0x5e ecm_src/lwip-1.4.1/src/core/stats.o + .debug_macro 0x0000000000000000 0x592 ecm_src/lwip-1.4.1/src/core/stats.o + .debug_macro 0x0000000000000000 0x58 ecm_src/lwip-1.4.1/src/core/stats.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/core/stats.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/stats.o + .debug_macro 0x0000000000000000 0x3a ecm_src/lwip-1.4.1/src/core/stats.o + .debug_macro 0x0000000000000000 0x127 ecm_src/lwip-1.4.1/src/core/stats.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/core/stats.o + .debug_macro 0x0000000000000000 0x40 ecm_src/lwip-1.4.1/src/core/stats.o + .debug_macro 0x0000000000000000 0x18 ecm_src/lwip-1.4.1/src/core/stats.o + .debug_macro 0x0000000000000000 0x94 ecm_src/lwip-1.4.1/src/core/stats.o + .debug_macro 0x0000000000000000 0x3c ecm_src/lwip-1.4.1/src/core/stats.o + .debug_macro 0x0000000000000000 0x34 ecm_src/lwip-1.4.1/src/core/stats.o + .debug_macro 0x0000000000000000 0x174 ecm_src/lwip-1.4.1/src/core/stats.o + .debug_macro 0x0000000000000000 0x57 ecm_src/lwip-1.4.1/src/core/stats.o + .debug_macro 0x0000000000000000 0x52 ecm_src/lwip-1.4.1/src/core/stats.o + .debug_macro 0x0000000000000000 0x1f ecm_src/lwip-1.4.1/src/core/stats.o + .debug_macro 0x0000000000000000 0x43 ecm_src/lwip-1.4.1/src/core/stats.o + .debug_macro 0x0000000000000000 0x20 ecm_src/lwip-1.4.1/src/core/stats.o + .debug_macro 0x0000000000000000 0x1a3 ecm_src/lwip-1.4.1/src/core/stats.o + .debug_macro 0x0000000000000000 0x330 ecm_src/lwip-1.4.1/src/core/stats.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/stats.o + .debug_macro 0x0000000000000000 0x35 ecm_src/lwip-1.4.1/src/core/stats.o + .debug_macro 0x0000000000000000 0x20 ecm_src/lwip-1.4.1/src/core/stats.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/sys.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/sys.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/sys.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/sys.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/sys.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/sys.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/sys.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/sys.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/sys.o + .text 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/sys.o + .data 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/sys.o + .bss 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/sys.o + .debug_info 0x0000000000000000 0x4c ecm_src/lwip-1.4.1/src/core/sys.o + .debug_abbrev 0x0000000000000000 0x1e ecm_src/lwip-1.4.1/src/core/sys.o + .debug_aranges + 0x0000000000000000 0x18 ecm_src/lwip-1.4.1/src/core/sys.o + .debug_macro 0x0000000000000000 0x6b ecm_src/lwip-1.4.1/src/core/sys.o + .debug_macro 0x0000000000000000 0xa48 ecm_src/lwip-1.4.1/src/core/sys.o + .debug_macro 0x0000000000000000 0x70 ecm_src/lwip-1.4.1/src/core/sys.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/core/sys.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/sys.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/core/sys.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/core/sys.o + .debug_macro 0x0000000000000000 0x5e ecm_src/lwip-1.4.1/src/core/sys.o + .debug_macro 0x0000000000000000 0x592 ecm_src/lwip-1.4.1/src/core/sys.o + .debug_macro 0x0000000000000000 0xc5 ecm_src/lwip-1.4.1/src/core/sys.o + .debug_line 0x0000000000000000 0x147 ecm_src/lwip-1.4.1/src/core/sys.o + .debug_str 0x0000000000000000 0x4a3a ecm_src/lwip-1.4.1/src/core/sys.o + .comment 0x0000000000000000 0x7c ecm_src/lwip-1.4.1/src/core/sys.o + .ARM.attributes + 0x0000000000000000 0x31 ecm_src/lwip-1.4.1/src/core/sys.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp.o + .text 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/tcp.o + .data 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/tcp.o + .bss 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/tcp.o + .rodata 0x0000000000000000 0x76 ecm_src/lwip-1.4.1/src/core/tcp.o + .rodata.tcp_state_str + 0x0000000000000000 0x2c ecm_src/lwip-1.4.1/src/core/tcp.o + .data.tcp_port + 0x0000000000000000 0x2 ecm_src/lwip-1.4.1/src/core/tcp.o + .rodata.tcp_pcb_lists + 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/tcp.o + .text.tcp_shutdown + 0x0000000000000000 0x92 ecm_src/lwip-1.4.1/src/core/tcp.o + .text.tcp_bind + 0x0000000000000000 0xec ecm_src/lwip-1.4.1/src/core/tcp.o + .text.tcp_accept_null + 0x0000000000000000 0x1a ecm_src/lwip-1.4.1/src/core/tcp.o + .text.tcp_listen_with_backlog + 0x0000000000000000 0x11c ecm_src/lwip-1.4.1/src/core/tcp.o + .text.tcp_new_port + 0x0000000000000000 0xa0 ecm_src/lwip-1.4.1/src/core/tcp.o + .text.tcp_connect + 0x0000000000000000 0x1dc ecm_src/lwip-1.4.1/src/core/tcp.o + .text.tcp_setprio + 0x0000000000000000 0x1e ecm_src/lwip-1.4.1/src/core/tcp.o + .text.tcp_new 0x0000000000000000 0x12 ecm_src/lwip-1.4.1/src/core/tcp.o + .text.tcp_arg 0x0000000000000000 0x18 ecm_src/lwip-1.4.1/src/core/tcp.o + .text.tcp_recv + 0x0000000000000000 0x1a ecm_src/lwip-1.4.1/src/core/tcp.o + .text.tcp_sent + 0x0000000000000000 0x18 ecm_src/lwip-1.4.1/src/core/tcp.o + .text.tcp_err 0x0000000000000000 0x1a ecm_src/lwip-1.4.1/src/core/tcp.o + .text.tcp_accept + 0x0000000000000000 0x18 ecm_src/lwip-1.4.1/src/core/tcp.o + .text.tcp_poll + 0x0000000000000000 0x28 ecm_src/lwip-1.4.1/src/core/tcp.o + .text.tcp_debug_state_str + 0x0000000000000000 0x24 ecm_src/lwip-1.4.1/src/core/tcp.o + .debug_macro 0x0000000000000000 0xa48 ecm_src/lwip-1.4.1/src/core/tcp.o + .debug_macro 0x0000000000000000 0x70 ecm_src/lwip-1.4.1/src/core/tcp.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/core/tcp.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/tcp.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/core/tcp.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/core/tcp.o + .debug_macro 0x0000000000000000 0x5e ecm_src/lwip-1.4.1/src/core/tcp.o + .debug_macro 0x0000000000000000 0x592 ecm_src/lwip-1.4.1/src/core/tcp.o + .debug_macro 0x0000000000000000 0x58 ecm_src/lwip-1.4.1/src/core/tcp.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/core/tcp.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/tcp.o + .debug_macro 0x0000000000000000 0x3a ecm_src/lwip-1.4.1/src/core/tcp.o + .debug_macro 0x0000000000000000 0x17b ecm_src/lwip-1.4.1/src/core/tcp.o + .debug_macro 0x0000000000000000 0x76 ecm_src/lwip-1.4.1/src/core/tcp.o + .debug_macro 0x0000000000000000 0x4f ecm_src/lwip-1.4.1/src/core/tcp.o + .debug_macro 0x0000000000000000 0x62 ecm_src/lwip-1.4.1/src/core/tcp.o + .debug_macro 0x0000000000000000 0x135 ecm_src/lwip-1.4.1/src/core/tcp.o + .debug_macro 0x0000000000000000 0x64 ecm_src/lwip-1.4.1/src/core/tcp.o + .debug_macro 0x0000000000000000 0xac ecm_src/lwip-1.4.1/src/core/tcp.o + .debug_macro 0x0000000000000000 0x12d ecm_src/lwip-1.4.1/src/core/tcp.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/core/tcp.o + .debug_macro 0x0000000000000000 0x40 ecm_src/lwip-1.4.1/src/core/tcp.o + .debug_macro 0x0000000000000000 0x18 ecm_src/lwip-1.4.1/src/core/tcp.o + .debug_macro 0x0000000000000000 0x94 ecm_src/lwip-1.4.1/src/core/tcp.o + .debug_macro 0x0000000000000000 0x3c ecm_src/lwip-1.4.1/src/core/tcp.o + .debug_macro 0x0000000000000000 0x34 ecm_src/lwip-1.4.1/src/core/tcp.o + .debug_macro 0x0000000000000000 0x174 ecm_src/lwip-1.4.1/src/core/tcp.o + .debug_macro 0x0000000000000000 0x57 ecm_src/lwip-1.4.1/src/core/tcp.o + .debug_macro 0x0000000000000000 0x52 ecm_src/lwip-1.4.1/src/core/tcp.o + .debug_macro 0x0000000000000000 0x1f ecm_src/lwip-1.4.1/src/core/tcp.o + .debug_macro 0x0000000000000000 0x43 ecm_src/lwip-1.4.1/src/core/tcp.o + .debug_macro 0x0000000000000000 0x20 ecm_src/lwip-1.4.1/src/core/tcp.o + .debug_macro 0x0000000000000000 0x1a3 ecm_src/lwip-1.4.1/src/core/tcp.o + .debug_macro 0x0000000000000000 0x330 ecm_src/lwip-1.4.1/src/core/tcp.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/tcp.o + .debug_macro 0x0000000000000000 0x35 ecm_src/lwip-1.4.1/src/core/tcp.o + .debug_macro 0x0000000000000000 0x20 ecm_src/lwip-1.4.1/src/core/tcp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_in.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_in.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_in.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_in.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_in.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_in.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_in.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_in.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_in.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_in.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_in.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_in.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_in.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_in.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_in.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_in.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_in.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_in.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_in.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_in.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_in.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_in.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_in.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_in.o + .text 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/tcp_in.o + .data 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/tcp_in.o + .bss 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/tcp_in.o + .debug_macro 0x0000000000000000 0xa48 ecm_src/lwip-1.4.1/src/core/tcp_in.o + .debug_macro 0x0000000000000000 0x70 ecm_src/lwip-1.4.1/src/core/tcp_in.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/core/tcp_in.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/tcp_in.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/core/tcp_in.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/core/tcp_in.o + .debug_macro 0x0000000000000000 0x5e ecm_src/lwip-1.4.1/src/core/tcp_in.o + .debug_macro 0x0000000000000000 0x592 ecm_src/lwip-1.4.1/src/core/tcp_in.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/core/tcp_in.o + .debug_macro 0x0000000000000000 0x76 ecm_src/lwip-1.4.1/src/core/tcp_in.o + .debug_macro 0x0000000000000000 0x4f ecm_src/lwip-1.4.1/src/core/tcp_in.o + .debug_macro 0x0000000000000000 0x58 ecm_src/lwip-1.4.1/src/core/tcp_in.o + .debug_macro 0x0000000000000000 0x17b ecm_src/lwip-1.4.1/src/core/tcp_in.o + .debug_macro 0x0000000000000000 0x62 ecm_src/lwip-1.4.1/src/core/tcp_in.o + .debug_macro 0x0000000000000000 0x135 ecm_src/lwip-1.4.1/src/core/tcp_in.o + .debug_macro 0x0000000000000000 0x64 ecm_src/lwip-1.4.1/src/core/tcp_in.o + .debug_macro 0x0000000000000000 0xac ecm_src/lwip-1.4.1/src/core/tcp_in.o + .debug_macro 0x0000000000000000 0x1be ecm_src/lwip-1.4.1/src/core/tcp_in.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/tcp_in.o + .debug_macro 0x0000000000000000 0x3a ecm_src/lwip-1.4.1/src/core/tcp_in.o + .debug_macro 0x0000000000000000 0x12d ecm_src/lwip-1.4.1/src/core/tcp_in.o + .debug_macro 0x0000000000000000 0x321 ecm_src/lwip-1.4.1/src/core/tcp_in.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/core/tcp_in.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_out.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_out.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_out.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_out.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_out.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_out.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_out.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_out.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_out.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_out.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_out.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_out.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_out.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_out.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_out.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_out.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_out.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_out.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_out.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_out.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_out.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_out.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_out.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_out.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_out.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_out.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_out.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_out.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_out.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_out.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_out.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_out.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_out.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_out.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_out.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_out.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_out.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_out.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_out.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/tcp_out.o + .text 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/tcp_out.o + .data 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/tcp_out.o + .bss 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/tcp_out.o + .text.tcp_pbuf_prealloc + 0x0000000000000000 0xe4 ecm_src/lwip-1.4.1/src/core/tcp_out.o + .text.tcp_write_checks + 0x0000000000000000 0xb8 ecm_src/lwip-1.4.1/src/core/tcp_out.o + .text.tcp_write + 0x0000000000000000 0x5d4 ecm_src/lwip-1.4.1/src/core/tcp_out.o + .debug_macro 0x0000000000000000 0xa48 ecm_src/lwip-1.4.1/src/core/tcp_out.o + .debug_macro 0x0000000000000000 0x70 ecm_src/lwip-1.4.1/src/core/tcp_out.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/core/tcp_out.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/tcp_out.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/core/tcp_out.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/core/tcp_out.o + .debug_macro 0x0000000000000000 0x5e ecm_src/lwip-1.4.1/src/core/tcp_out.o + .debug_macro 0x0000000000000000 0x592 ecm_src/lwip-1.4.1/src/core/tcp_out.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/core/tcp_out.o + .debug_macro 0x0000000000000000 0x76 ecm_src/lwip-1.4.1/src/core/tcp_out.o + .debug_macro 0x0000000000000000 0x4f ecm_src/lwip-1.4.1/src/core/tcp_out.o + .debug_macro 0x0000000000000000 0x58 ecm_src/lwip-1.4.1/src/core/tcp_out.o + .debug_macro 0x0000000000000000 0x17b ecm_src/lwip-1.4.1/src/core/tcp_out.o + .debug_macro 0x0000000000000000 0x62 ecm_src/lwip-1.4.1/src/core/tcp_out.o + .debug_macro 0x0000000000000000 0x135 ecm_src/lwip-1.4.1/src/core/tcp_out.o + .debug_macro 0x0000000000000000 0x64 ecm_src/lwip-1.4.1/src/core/tcp_out.o + .debug_macro 0x0000000000000000 0xac ecm_src/lwip-1.4.1/src/core/tcp_out.o + .debug_macro 0x0000000000000000 0x1be ecm_src/lwip-1.4.1/src/core/tcp_out.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/tcp_out.o + .debug_macro 0x0000000000000000 0x3a ecm_src/lwip-1.4.1/src/core/tcp_out.o + .debug_macro 0x0000000000000000 0x1c ecm_src/lwip-1.4.1/src/core/tcp_out.o + .debug_macro 0x0000000000000000 0x12d ecm_src/lwip-1.4.1/src/core/tcp_out.o + .debug_macro 0x0000000000000000 0x321 ecm_src/lwip-1.4.1/src/core/tcp_out.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/core/tcp_out.o + .debug_macro 0x0000000000000000 0x40 ecm_src/lwip-1.4.1/src/core/tcp_out.o + .debug_macro 0x0000000000000000 0x18 ecm_src/lwip-1.4.1/src/core/tcp_out.o + .debug_macro 0x0000000000000000 0x94 ecm_src/lwip-1.4.1/src/core/tcp_out.o + .debug_macro 0x0000000000000000 0x3c ecm_src/lwip-1.4.1/src/core/tcp_out.o + .debug_macro 0x0000000000000000 0x34 ecm_src/lwip-1.4.1/src/core/tcp_out.o + .debug_macro 0x0000000000000000 0x174 ecm_src/lwip-1.4.1/src/core/tcp_out.o + .debug_macro 0x0000000000000000 0x57 ecm_src/lwip-1.4.1/src/core/tcp_out.o + .debug_macro 0x0000000000000000 0x52 ecm_src/lwip-1.4.1/src/core/tcp_out.o + .debug_macro 0x0000000000000000 0x1f ecm_src/lwip-1.4.1/src/core/tcp_out.o + .debug_macro 0x0000000000000000 0x43 ecm_src/lwip-1.4.1/src/core/tcp_out.o + .debug_macro 0x0000000000000000 0x20 ecm_src/lwip-1.4.1/src/core/tcp_out.o + .debug_macro 0x0000000000000000 0x1a3 ecm_src/lwip-1.4.1/src/core/tcp_out.o + .debug_macro 0x0000000000000000 0x330 ecm_src/lwip-1.4.1/src/core/tcp_out.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/tcp_out.o + .debug_macro 0x0000000000000000 0x35 ecm_src/lwip-1.4.1/src/core/tcp_out.o + .debug_macro 0x0000000000000000 0x20 ecm_src/lwip-1.4.1/src/core/tcp_out.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/timers.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/timers.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/timers.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/timers.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/timers.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/timers.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/timers.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/timers.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/timers.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/timers.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/timers.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/timers.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/timers.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/timers.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/timers.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/timers.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/timers.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/timers.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/timers.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/timers.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/timers.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/timers.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/timers.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/timers.o + .text 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/timers.o + .data 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/timers.o + .bss 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/timers.o + .text.sys_untimeout + 0x0000000000000000 0x90 ecm_src/lwip-1.4.1/src/core/timers.o + .text.sys_check_timeouts + 0x0000000000000000 0xb0 ecm_src/lwip-1.4.1/src/core/timers.o + .text.sys_restart_timeouts + 0x0000000000000000 0x18 ecm_src/lwip-1.4.1/src/core/timers.o + .debug_macro 0x0000000000000000 0xa48 ecm_src/lwip-1.4.1/src/core/timers.o + .debug_macro 0x0000000000000000 0x70 ecm_src/lwip-1.4.1/src/core/timers.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/core/timers.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/timers.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/core/timers.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/core/timers.o + .debug_macro 0x0000000000000000 0x5e ecm_src/lwip-1.4.1/src/core/timers.o + .debug_macro 0x0000000000000000 0x592 ecm_src/lwip-1.4.1/src/core/timers.o + .debug_macro 0x0000000000000000 0x76 ecm_src/lwip-1.4.1/src/core/timers.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/core/timers.o + .debug_macro 0x0000000000000000 0x55 ecm_src/lwip-1.4.1/src/core/timers.o + .debug_macro 0x0000000000000000 0x58 ecm_src/lwip-1.4.1/src/core/timers.o + .debug_macro 0x0000000000000000 0x17b ecm_src/lwip-1.4.1/src/core/timers.o + .debug_macro 0x0000000000000000 0x62 ecm_src/lwip-1.4.1/src/core/timers.o + .debug_macro 0x0000000000000000 0x135 ecm_src/lwip-1.4.1/src/core/timers.o + .debug_macro 0x0000000000000000 0x64 ecm_src/lwip-1.4.1/src/core/timers.o + .debug_macro 0x0000000000000000 0xac ecm_src/lwip-1.4.1/src/core/timers.o + .debug_macro 0x0000000000000000 0x1be ecm_src/lwip-1.4.1/src/core/timers.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/timers.o + .debug_macro 0x0000000000000000 0x3a ecm_src/lwip-1.4.1/src/core/timers.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/timers.o + .debug_macro 0x0000000000000000 0x86 ecm_src/lwip-1.4.1/src/core/timers.o + .debug_macro 0x0000000000000000 0xc5 ecm_src/lwip-1.4.1/src/core/timers.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/udp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/udp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/udp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/udp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/udp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/udp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/udp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/udp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/udp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/udp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/udp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/udp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/udp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/udp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/udp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/udp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/udp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/udp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/udp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/udp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/udp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/udp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/udp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/udp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/udp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/udp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/udp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/udp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/udp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/udp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/udp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/udp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/udp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/udp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/udp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/udp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/udp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/udp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/udp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/udp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/udp.o + .text 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/udp.o + .data 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/udp.o + .bss 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/udp.o + .text.udp_send + 0x0000000000000000 0x24 ecm_src/lwip-1.4.1/src/core/udp.o + .text.udp_connect + 0x0000000000000000 0xa4 ecm_src/lwip-1.4.1/src/core/udp.o + .text.udp_disconnect + 0x0000000000000000 0x2a ecm_src/lwip-1.4.1/src/core/udp.o + .debug_macro 0x0000000000000000 0xa48 ecm_src/lwip-1.4.1/src/core/udp.o + .debug_macro 0x0000000000000000 0x70 ecm_src/lwip-1.4.1/src/core/udp.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/core/udp.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/udp.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/core/udp.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/core/udp.o + .debug_macro 0x0000000000000000 0x5e ecm_src/lwip-1.4.1/src/core/udp.o + .debug_macro 0x0000000000000000 0x592 ecm_src/lwip-1.4.1/src/core/udp.o + .debug_macro 0x0000000000000000 0x76 ecm_src/lwip-1.4.1/src/core/udp.o + .debug_macro 0x0000000000000000 0x4f ecm_src/lwip-1.4.1/src/core/udp.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/udp.o + .debug_macro 0x0000000000000000 0x58 ecm_src/lwip-1.4.1/src/core/udp.o + .debug_macro 0x0000000000000000 0x175 ecm_src/lwip-1.4.1/src/core/udp.o + .debug_macro 0x0000000000000000 0x56 ecm_src/lwip-1.4.1/src/core/udp.o + .debug_macro 0x0000000000000000 0x13b ecm_src/lwip-1.4.1/src/core/udp.o + .debug_macro 0x0000000000000000 0x37 ecm_src/lwip-1.4.1/src/core/udp.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/udp.o + .debug_macro 0x0000000000000000 0x3a ecm_src/lwip-1.4.1/src/core/udp.o + .debug_macro 0x0000000000000000 0x1c ecm_src/lwip-1.4.1/src/core/udp.o + .debug_macro 0x0000000000000000 0x64 ecm_src/lwip-1.4.1/src/core/udp.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/core/udp.o + .debug_macro 0x0000000000000000 0x127 ecm_src/lwip-1.4.1/src/core/udp.o + .debug_macro 0x0000000000000000 0x321 ecm_src/lwip-1.4.1/src/core/udp.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/core/udp.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/core/udp.o + .debug_macro 0x0000000000000000 0x40 ecm_src/lwip-1.4.1/src/core/udp.o + .debug_macro 0x0000000000000000 0x18 ecm_src/lwip-1.4.1/src/core/udp.o + .debug_macro 0x0000000000000000 0x94 ecm_src/lwip-1.4.1/src/core/udp.o + .debug_macro 0x0000000000000000 0x3c ecm_src/lwip-1.4.1/src/core/udp.o + .debug_macro 0x0000000000000000 0x34 ecm_src/lwip-1.4.1/src/core/udp.o + .debug_macro 0x0000000000000000 0x174 ecm_src/lwip-1.4.1/src/core/udp.o + .debug_macro 0x0000000000000000 0x57 ecm_src/lwip-1.4.1/src/core/udp.o + .debug_macro 0x0000000000000000 0x52 ecm_src/lwip-1.4.1/src/core/udp.o + .debug_macro 0x0000000000000000 0x1f ecm_src/lwip-1.4.1/src/core/udp.o + .debug_macro 0x0000000000000000 0x43 ecm_src/lwip-1.4.1/src/core/udp.o + .debug_macro 0x0000000000000000 0x20 ecm_src/lwip-1.4.1/src/core/udp.o + .debug_macro 0x0000000000000000 0x1a3 ecm_src/lwip-1.4.1/src/core/udp.o + .debug_macro 0x0000000000000000 0x330 ecm_src/lwip-1.4.1/src/core/udp.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/udp.o + .debug_macro 0x0000000000000000 0x35 ecm_src/lwip-1.4.1/src/core/udp.o + .debug_macro 0x0000000000000000 0x20 ecm_src/lwip-1.4.1/src/core/udp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/autoip.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/autoip.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/autoip.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/autoip.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/autoip.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/autoip.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/autoip.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/autoip.o + .text 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/ipv4/autoip.o + .data 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/ipv4/autoip.o + .bss 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/ipv4/autoip.o + .debug_info 0x0000000000000000 0x4c ecm_src/lwip-1.4.1/src/core/ipv4/autoip.o + .debug_abbrev 0x0000000000000000 0x1e ecm_src/lwip-1.4.1/src/core/ipv4/autoip.o + .debug_aranges + 0x0000000000000000 0x18 ecm_src/lwip-1.4.1/src/core/ipv4/autoip.o + .debug_macro 0x0000000000000000 0x62 ecm_src/lwip-1.4.1/src/core/ipv4/autoip.o + .debug_macro 0x0000000000000000 0xa48 ecm_src/lwip-1.4.1/src/core/ipv4/autoip.o + .debug_macro 0x0000000000000000 0x70 ecm_src/lwip-1.4.1/src/core/ipv4/autoip.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/core/ipv4/autoip.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/ipv4/autoip.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/core/ipv4/autoip.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/core/ipv4/autoip.o + .debug_macro 0x0000000000000000 0x5e ecm_src/lwip-1.4.1/src/core/ipv4/autoip.o + .debug_macro 0x0000000000000000 0x592 ecm_src/lwip-1.4.1/src/core/ipv4/autoip.o + .debug_line 0x0000000000000000 0x146 ecm_src/lwip-1.4.1/src/core/ipv4/autoip.o + .debug_str 0x0000000000000000 0x45b7 ecm_src/lwip-1.4.1/src/core/ipv4/autoip.o + .comment 0x0000000000000000 0x7c ecm_src/lwip-1.4.1/src/core/ipv4/autoip.o + .ARM.attributes + 0x0000000000000000 0x31 ecm_src/lwip-1.4.1/src/core/ipv4/autoip.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .text 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .data 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .bss 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .debug_macro 0x0000000000000000 0xa48 ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .debug_macro 0x0000000000000000 0x70 ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .debug_macro 0x0000000000000000 0x5e ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .debug_macro 0x0000000000000000 0x592 ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .debug_macro 0x0000000000000000 0x76 ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .debug_macro 0x0000000000000000 0x4f ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .debug_macro 0x0000000000000000 0x58 ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .debug_macro 0x0000000000000000 0x175 ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .debug_macro 0x0000000000000000 0x62 ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .debug_macro 0x0000000000000000 0x1c ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .debug_macro 0x0000000000000000 0x13b ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .debug_macro 0x0000000000000000 0x3a ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .debug_macro 0x0000000000000000 0x127 ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .debug_macro 0x0000000000000000 0x321 ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .debug_macro 0x0000000000000000 0x40 ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .debug_macro 0x0000000000000000 0x18 ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .debug_macro 0x0000000000000000 0x94 ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .debug_macro 0x0000000000000000 0x3c ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .debug_macro 0x0000000000000000 0x34 ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .debug_macro 0x0000000000000000 0x174 ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .debug_macro 0x0000000000000000 0x57 ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .debug_macro 0x0000000000000000 0x52 ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .debug_macro 0x0000000000000000 0x1f ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .debug_macro 0x0000000000000000 0x43 ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .debug_macro 0x0000000000000000 0x20 ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .debug_macro 0x0000000000000000 0x1a3 ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .debug_macro 0x0000000000000000 0x330 ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .debug_macro 0x0000000000000000 0x35 ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .debug_macro 0x0000000000000000 0x20 ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/igmp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/igmp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/igmp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/igmp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/igmp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/igmp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/igmp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/igmp.o + .text 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/ipv4/igmp.o + .data 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/ipv4/igmp.o + .bss 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/ipv4/igmp.o + .debug_info 0x0000000000000000 0x4c ecm_src/lwip-1.4.1/src/core/ipv4/igmp.o + .debug_abbrev 0x0000000000000000 0x1e ecm_src/lwip-1.4.1/src/core/ipv4/igmp.o + .debug_aranges + 0x0000000000000000 0x18 ecm_src/lwip-1.4.1/src/core/ipv4/igmp.o + .debug_macro 0x0000000000000000 0x62 ecm_src/lwip-1.4.1/src/core/ipv4/igmp.o + .debug_macro 0x0000000000000000 0xa48 ecm_src/lwip-1.4.1/src/core/ipv4/igmp.o + .debug_macro 0x0000000000000000 0x70 ecm_src/lwip-1.4.1/src/core/ipv4/igmp.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/core/ipv4/igmp.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/ipv4/igmp.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/core/ipv4/igmp.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/core/ipv4/igmp.o + .debug_macro 0x0000000000000000 0x5e ecm_src/lwip-1.4.1/src/core/ipv4/igmp.o + .debug_macro 0x0000000000000000 0x592 ecm_src/lwip-1.4.1/src/core/ipv4/igmp.o + .debug_line 0x0000000000000000 0x144 ecm_src/lwip-1.4.1/src/core/ipv4/igmp.o + .debug_str 0x0000000000000000 0x45b5 ecm_src/lwip-1.4.1/src/core/ipv4/igmp.o + .comment 0x0000000000000000 0x7c ecm_src/lwip-1.4.1/src/core/ipv4/igmp.o + .ARM.attributes + 0x0000000000000000 0x31 ecm_src/lwip-1.4.1/src/core/ipv4/igmp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/inet.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/inet.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/inet.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/inet.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/inet.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/inet.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/inet.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/inet.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/inet.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/inet.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/inet.o + .text 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/ipv4/inet.o + .data 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/ipv4/inet.o + .bss 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/ipv4/inet.o + .debug_info 0x0000000000000000 0x9d ecm_src/lwip-1.4.1/src/core/ipv4/inet.o + .debug_abbrev 0x0000000000000000 0x61 ecm_src/lwip-1.4.1/src/core/ipv4/inet.o + .debug_aranges + 0x0000000000000000 0x18 ecm_src/lwip-1.4.1/src/core/ipv4/inet.o + .debug_macro 0x0000000000000000 0x83 ecm_src/lwip-1.4.1/src/core/ipv4/inet.o + .debug_macro 0x0000000000000000 0xa48 ecm_src/lwip-1.4.1/src/core/ipv4/inet.o + .debug_macro 0x0000000000000000 0x70 ecm_src/lwip-1.4.1/src/core/ipv4/inet.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/core/ipv4/inet.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/ipv4/inet.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/core/ipv4/inet.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/core/ipv4/inet.o + .debug_macro 0x0000000000000000 0x5e ecm_src/lwip-1.4.1/src/core/ipv4/inet.o + .debug_macro 0x0000000000000000 0x592 ecm_src/lwip-1.4.1/src/core/ipv4/inet.o + .debug_macro 0x0000000000000000 0x58 ecm_src/lwip-1.4.1/src/core/ipv4/inet.o + .debug_macro 0x0000000000000000 0x17b ecm_src/lwip-1.4.1/src/core/ipv4/inet.o + .debug_macro 0x0000000000000000 0xd6 ecm_src/lwip-1.4.1/src/core/ipv4/inet.o + .debug_line 0x0000000000000000 0x1a3 ecm_src/lwip-1.4.1/src/core/ipv4/inet.o + .debug_str 0x0000000000000000 0x5952 ecm_src/lwip-1.4.1/src/core/ipv4/inet.o + .comment 0x0000000000000000 0x7c ecm_src/lwip-1.4.1/src/core/ipv4/inet.o + .ARM.attributes + 0x0000000000000000 0x31 ecm_src/lwip-1.4.1/src/core/ipv4/inet.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .text 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .data 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .bss 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .text.inet_chksum_pseudo_partial + 0x0000000000000000 0x194 ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .debug_macro 0x0000000000000000 0xa48 ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .debug_macro 0x0000000000000000 0x70 ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .debug_macro 0x0000000000000000 0x5e ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .debug_macro 0x0000000000000000 0x592 ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .debug_macro 0x0000000000000000 0x76 ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .debug_macro 0x0000000000000000 0x4f ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .debug_macro 0x0000000000000000 0x58 ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .debug_macro 0x0000000000000000 0x175 ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .debug_macro 0x0000000000000000 0x174 ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .debug_macro 0x0000000000000000 0x40 ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .debug_macro 0x0000000000000000 0x18 ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .debug_macro 0x0000000000000000 0x94 ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .debug_macro 0x0000000000000000 0x3c ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .debug_macro 0x0000000000000000 0x34 ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .debug_macro 0x0000000000000000 0x57 ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .debug_macro 0x0000000000000000 0x52 ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .debug_macro 0x0000000000000000 0x1f ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .debug_macro 0x0000000000000000 0x43 ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .debug_macro 0x0000000000000000 0x20 ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .debug_macro 0x0000000000000000 0x1a3 ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .debug_macro 0x0000000000000000 0x330 ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .debug_macro 0x0000000000000000 0x35 ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .debug_macro 0x0000000000000000 0x20 ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .text 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .data 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .bss 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .debug_macro 0x0000000000000000 0xa48 ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .debug_macro 0x0000000000000000 0x70 ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .debug_macro 0x0000000000000000 0x5e ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .debug_macro 0x0000000000000000 0x592 ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .debug_macro 0x0000000000000000 0x58 ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .debug_macro 0x0000000000000000 0x76 ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .debug_macro 0x0000000000000000 0x4f ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .debug_macro 0x0000000000000000 0x17b ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .debug_macro 0x0000000000000000 0x62 ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .debug_macro 0x0000000000000000 0x135 ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .debug_macro 0x0000000000000000 0x1c ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .debug_macro 0x0000000000000000 0x64 ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .debug_macro 0x0000000000000000 0x3d ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .debug_macro 0x0000000000000000 0x1be ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .debug_macro 0x0000000000000000 0x321 ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .debug_macro 0x0000000000000000 0x3a ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .debug_macro 0x0000000000000000 0x127 ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .debug_macro 0x0000000000000000 0x40 ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .debug_macro 0x0000000000000000 0x18 ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .debug_macro 0x0000000000000000 0x94 ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .debug_macro 0x0000000000000000 0x3c ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .debug_macro 0x0000000000000000 0x34 ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .debug_macro 0x0000000000000000 0x174 ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .debug_macro 0x0000000000000000 0x57 ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .debug_macro 0x0000000000000000 0x52 ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .debug_macro 0x0000000000000000 0x1f ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .debug_macro 0x0000000000000000 0x43 ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .debug_macro 0x0000000000000000 0x20 ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .debug_macro 0x0000000000000000 0x1a3 ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .debug_macro 0x0000000000000000 0x330 ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .debug_macro 0x0000000000000000 0x35 ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .debug_macro 0x0000000000000000 0x20 ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o + .text 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o + .data 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o + .bss 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o + .text.ip4_addr_netmask_valid + 0x0000000000000000 0x58 ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o + .text.ipaddr_addr + 0x0000000000000000 0x2a ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o + .text.ipaddr_aton + 0x0000000000000000 0x290 ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o + .rodata.ipaddr_aton + 0x0000000000000000 0x14 ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o + .text.ipaddr_ntoa + 0x0000000000000000 0x24 ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o + .text.ipaddr_ntoa_r + 0x0000000000000000 0x100 ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o + .bss.str.4349 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o + .debug_macro 0x0000000000000000 0xa48 ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o + .debug_macro 0x0000000000000000 0x70 ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o + .debug_macro 0x0000000000000000 0x5e ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o + .debug_macro 0x0000000000000000 0x592 ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o + .debug_macro 0x0000000000000000 0x58 ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o + .debug_macro 0x0000000000000000 0x175 ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o + .debug_macro 0x0000000000000000 0x76 ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o + .debug_macro 0x0000000000000000 0x55 ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o + .debug_macro 0x0000000000000000 0x56 ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .text 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .data 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .bss 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .debug_macro 0x0000000000000000 0xa48 ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .debug_macro 0x0000000000000000 0x70 ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .debug_macro 0x0000000000000000 0x5e ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .debug_macro 0x0000000000000000 0x592 ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .debug_macro 0x0000000000000000 0x76 ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .debug_macro 0x0000000000000000 0x55 ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .debug_macro 0x0000000000000000 0x58 ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .debug_macro 0x0000000000000000 0x175 ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .debug_macro 0x0000000000000000 0x56 ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .debug_macro 0x0000000000000000 0x13b ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .debug_macro 0x0000000000000000 0x1c ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .debug_macro 0x0000000000000000 0x321 ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .debug_macro 0x0000000000000000 0x3a ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .debug_macro 0x0000000000000000 0x127 ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .debug_macro 0x0000000000000000 0x64 ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .debug_macro 0x0000000000000000 0x40 ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .debug_macro 0x0000000000000000 0x18 ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .debug_macro 0x0000000000000000 0x94 ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .debug_macro 0x0000000000000000 0x3c ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .debug_macro 0x0000000000000000 0x34 ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .debug_macro 0x0000000000000000 0x174 ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .debug_macro 0x0000000000000000 0x57 ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .debug_macro 0x0000000000000000 0x52 ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .debug_macro 0x0000000000000000 0x1f ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .debug_macro 0x0000000000000000 0x43 ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .debug_macro 0x0000000000000000 0x20 ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .debug_macro 0x0000000000000000 0x1a3 ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .debug_macro 0x0000000000000000 0x330 ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .debug_macro 0x0000000000000000 0x35 ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .debug_macro 0x0000000000000000 0x20 ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/netif/etharp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/netif/etharp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/netif/etharp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/netif/etharp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/netif/etharp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/netif/etharp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/netif/etharp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/netif/etharp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/netif/etharp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/netif/etharp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/netif/etharp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/netif/etharp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/netif/etharp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/netif/etharp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/netif/etharp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/netif/etharp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/netif/etharp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/netif/etharp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/netif/etharp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/netif/etharp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/netif/etharp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/netif/etharp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/netif/etharp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/netif/etharp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/netif/etharp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/netif/etharp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/netif/etharp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/netif/etharp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/netif/etharp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/netif/etharp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/netif/etharp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/netif/etharp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/netif/etharp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/netif/etharp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/netif/etharp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/netif/etharp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/netif/etharp.o + .text 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/netif/etharp.o + .data 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/netif/etharp.o + .bss 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/netif/etharp.o + .text.etharp_add_static_entry + 0x0000000000000000 0x38 ecm_src/lwip-1.4.1/src/netif/etharp.o + .text.etharp_remove_static_entry + 0x0000000000000000 0x6c ecm_src/lwip-1.4.1/src/netif/etharp.o + .text.etharp_cleanup_netif + 0x0000000000000000 0x80 ecm_src/lwip-1.4.1/src/netif/etharp.o + .text.etharp_find_addr + 0x0000000000000000 0x94 ecm_src/lwip-1.4.1/src/netif/etharp.o + .debug_macro 0x0000000000000000 0xa48 ecm_src/lwip-1.4.1/src/netif/etharp.o + .debug_macro 0x0000000000000000 0x70 ecm_src/lwip-1.4.1/src/netif/etharp.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/netif/etharp.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/netif/etharp.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/netif/etharp.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/netif/etharp.o + .debug_macro 0x0000000000000000 0x5e ecm_src/lwip-1.4.1/src/netif/etharp.o + .debug_macro 0x0000000000000000 0x592 ecm_src/lwip-1.4.1/src/netif/etharp.o + .debug_macro 0x0000000000000000 0x58 ecm_src/lwip-1.4.1/src/netif/etharp.o + .debug_macro 0x0000000000000000 0x175 ecm_src/lwip-1.4.1/src/netif/etharp.o + .debug_macro 0x0000000000000000 0x76 ecm_src/lwip-1.4.1/src/netif/etharp.o + .debug_macro 0x0000000000000000 0x4f ecm_src/lwip-1.4.1/src/netif/etharp.o + .debug_macro 0x0000000000000000 0x62 ecm_src/lwip-1.4.1/src/netif/etharp.o + .debug_macro 0x0000000000000000 0x135 ecm_src/lwip-1.4.1/src/netif/etharp.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/netif/etharp.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/netif/etharp.o + .debug_macro 0x0000000000000000 0x3a ecm_src/lwip-1.4.1/src/netif/etharp.o + .debug_macro 0x0000000000000000 0x127 ecm_src/lwip-1.4.1/src/netif/etharp.o + .debug_macro 0x0000000000000000 0x321 ecm_src/lwip-1.4.1/src/netif/etharp.o + .debug_macro 0x0000000000000000 0x86 ecm_src/lwip-1.4.1/src/netif/etharp.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/netif/etharp.o + .debug_macro 0x0000000000000000 0x40 ecm_src/lwip-1.4.1/src/netif/etharp.o + .debug_macro 0x0000000000000000 0x18 ecm_src/lwip-1.4.1/src/netif/etharp.o + .debug_macro 0x0000000000000000 0x94 ecm_src/lwip-1.4.1/src/netif/etharp.o + .debug_macro 0x0000000000000000 0x3c ecm_src/lwip-1.4.1/src/netif/etharp.o + .debug_macro 0x0000000000000000 0x34 ecm_src/lwip-1.4.1/src/netif/etharp.o + .debug_macro 0x0000000000000000 0x174 ecm_src/lwip-1.4.1/src/netif/etharp.o + .debug_macro 0x0000000000000000 0x57 ecm_src/lwip-1.4.1/src/netif/etharp.o + .debug_macro 0x0000000000000000 0x52 ecm_src/lwip-1.4.1/src/netif/etharp.o + .debug_macro 0x0000000000000000 0x1f ecm_src/lwip-1.4.1/src/netif/etharp.o + .debug_macro 0x0000000000000000 0x43 ecm_src/lwip-1.4.1/src/netif/etharp.o + .debug_macro 0x0000000000000000 0x20 ecm_src/lwip-1.4.1/src/netif/etharp.o + .debug_macro 0x0000000000000000 0x1a3 ecm_src/lwip-1.4.1/src/netif/etharp.o + .debug_macro 0x0000000000000000 0x330 ecm_src/lwip-1.4.1/src/netif/etharp.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/netif/etharp.o + .debug_macro 0x0000000000000000 0x35 ecm_src/lwip-1.4.1/src/netif/etharp.o + .debug_macro 0x0000000000000000 0x20 ecm_src/lwip-1.4.1/src/netif/etharp.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/netif/ethernetif.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/netif/ethernetif.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/netif/ethernetif.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/netif/ethernetif.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/netif/ethernetif.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/netif/ethernetif.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/netif/ethernetif.o + .group 0x0000000000000000 0xc ecm_src/lwip-1.4.1/src/netif/ethernetif.o + .text 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/netif/ethernetif.o + .data 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/netif/ethernetif.o + .bss 0x0000000000000000 0x0 ecm_src/lwip-1.4.1/src/netif/ethernetif.o + .debug_info 0x0000000000000000 0x4c ecm_src/lwip-1.4.1/src/netif/ethernetif.o + .debug_abbrev 0x0000000000000000 0x1e ecm_src/lwip-1.4.1/src/netif/ethernetif.o + .debug_aranges + 0x0000000000000000 0x18 ecm_src/lwip-1.4.1/src/netif/ethernetif.o + .debug_macro 0x0000000000000000 0x62 ecm_src/lwip-1.4.1/src/netif/ethernetif.o + .debug_macro 0x0000000000000000 0xa48 ecm_src/lwip-1.4.1/src/netif/ethernetif.o + .debug_macro 0x0000000000000000 0x70 ecm_src/lwip-1.4.1/src/netif/ethernetif.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/netif/ethernetif.o + .debug_macro 0x0000000000000000 0x10 ecm_src/lwip-1.4.1/src/netif/ethernetif.o + .debug_macro 0x0000000000000000 0x22 ecm_src/lwip-1.4.1/src/netif/ethernetif.o + .debug_macro 0x0000000000000000 0x16 ecm_src/lwip-1.4.1/src/netif/ethernetif.o + .debug_macro 0x0000000000000000 0x5e ecm_src/lwip-1.4.1/src/netif/ethernetif.o + .debug_macro 0x0000000000000000 0x592 ecm_src/lwip-1.4.1/src/netif/ethernetif.o + .debug_line 0x0000000000000000 0x146 ecm_src/lwip-1.4.1/src/netif/ethernetif.o + .debug_str 0x0000000000000000 0x45b7 ecm_src/lwip-1.4.1/src/netif/ethernetif.o + .comment 0x0000000000000000 0x7c ecm_src/lwip-1.4.1/src/netif/ethernetif.o + .ARM.attributes + 0x0000000000000000 0x31 ecm_src/lwip-1.4.1/src/netif/ethernetif.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/ecm_main.o + .text 0x0000000000000000 0x0 ecm_src/src/ecm_main.o + .data 0x0000000000000000 0x0 ecm_src/src/ecm_main.o + .bss 0x0000000000000000 0x0 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0xa48 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x2e ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x22 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x22 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x8e ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x51 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0xef ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x6a ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x1df ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x1c ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x22 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0xb5 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x391 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0xfe50 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x3c ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x12d ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x174 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x53 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x946 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x5f3 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x12f ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x1a7 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x1a7 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x22c ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x34 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x43 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x28 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0xb0 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x217 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x22c ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x5f ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0xa5 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x65 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x234 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x4c ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x16d ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x130 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x46 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x18 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x3c ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x34 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x16 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x35 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x32a ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x10 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x52 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x1f ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x43 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x20 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x1a3 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x10 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x1c ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x52 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x40 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x10 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x40 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0xd7 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x1c ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x3d ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x16 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x145 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x16 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x16 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x29 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x16 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x20 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x64 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x1a6 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x22 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x70 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x16 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x22 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x16 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x5e ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x592 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x76 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x4f ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x52 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x175 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x62 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x13b ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x80 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x10 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x10 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x10 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x46 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x64 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x3d ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0xdc ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x22 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0xac ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x1be ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x10 ecm_src/src/ecm_main.o + .debug_macro 0x0000000000000000 0x10 ecm_src/src/ecm_main.o + .group 0x0000000000000000 0xc ecm_src/src/time.o + .group 0x0000000000000000 0xc ecm_src/src/time.o + .group 0x0000000000000000 0xc ecm_src/src/time.o + .group 0x0000000000000000 0xc ecm_src/src/time.o + .group 0x0000000000000000 0xc ecm_src/src/time.o + .group 0x0000000000000000 0xc ecm_src/src/time.o + .group 0x0000000000000000 0xc ecm_src/src/time.o + .group 0x0000000000000000 0xc ecm_src/src/time.o + .group 0x0000000000000000 0xc ecm_src/src/time.o + .group 0x0000000000000000 0xc ecm_src/src/time.o + .group 0x0000000000000000 0xc ecm_src/src/time.o + .group 0x0000000000000000 0xc ecm_src/src/time.o + .group 0x0000000000000000 0xc ecm_src/src/time.o + .group 0x0000000000000000 0xc ecm_src/src/time.o + .group 0x0000000000000000 0xc ecm_src/src/time.o + .group 0x0000000000000000 0xc ecm_src/src/time.o + .group 0x0000000000000000 0xc ecm_src/src/time.o + .group 0x0000000000000000 0xc ecm_src/src/time.o + .group 0x0000000000000000 0xc ecm_src/src/time.o + .group 0x0000000000000000 0xc ecm_src/src/time.o + .group 0x0000000000000000 0xc ecm_src/src/time.o + .group 0x0000000000000000 0xc ecm_src/src/time.o + .group 0x0000000000000000 0xc ecm_src/src/time.o + .group 0x0000000000000000 0xc ecm_src/src/time.o + .group 0x0000000000000000 0xc ecm_src/src/time.o + .group 0x0000000000000000 0xc ecm_src/src/time.o + .group 0x0000000000000000 0xc ecm_src/src/time.o + .group 0x0000000000000000 0xc ecm_src/src/time.o + .group 0x0000000000000000 0xc ecm_src/src/time.o + .group 0x0000000000000000 0xc ecm_src/src/time.o + .group 0x0000000000000000 0xc ecm_src/src/time.o + .group 0x0000000000000000 0xc ecm_src/src/time.o + .group 0x0000000000000000 0xc ecm_src/src/time.o + .group 0x0000000000000000 0xc ecm_src/src/time.o + .group 0x0000000000000000 0xc ecm_src/src/time.o + .group 0x0000000000000000 0xc ecm_src/src/time.o + .group 0x0000000000000000 0xc ecm_src/src/time.o + .group 0x0000000000000000 0xc ecm_src/src/time.o + .group 0x0000000000000000 0xc ecm_src/src/time.o + .text 0x0000000000000000 0x0 ecm_src/src/time.o + .data 0x0000000000000000 0x0 ecm_src/src/time.o + .bss 0x0000000000000000 0x0 ecm_src/src/time.o + .text.stmr_init + 0x0000000000000000 0x40 ecm_src/src/time.o + .text.stmr_free + 0x0000000000000000 0x68 ecm_src/src/time.o + .text.stmr_stop + 0x0000000000000000 0x1e ecm_src/src/time.o + .text.stmr_run + 0x0000000000000000 0x26 ecm_src/src/time.o + .debug_macro 0x0000000000000000 0xa48 ecm_src/src/time.o + .debug_macro 0x0000000000000000 0x22 ecm_src/src/time.o + .debug_macro 0x0000000000000000 0x22 ecm_src/src/time.o + .debug_macro 0x0000000000000000 0x8e ecm_src/src/time.o + .debug_macro 0x0000000000000000 0x51 ecm_src/src/time.o + .debug_macro 0x0000000000000000 0xef ecm_src/src/time.o + .debug_macro 0x0000000000000000 0x6a ecm_src/src/time.o + .debug_macro 0x0000000000000000 0x1df ecm_src/src/time.o + .debug_macro 0x0000000000000000 0x174 ecm_src/src/time.o + .debug_macro 0x0000000000000000 0x2e ecm_src/src/time.o + .debug_macro 0x0000000000000000 0x22 ecm_src/src/time.o + .debug_macro 0x0000000000000000 0x1c ecm_src/src/time.o + .debug_macro 0x0000000000000000 0x22 ecm_src/src/time.o + .debug_macro 0x0000000000000000 0xb5 ecm_src/src/time.o + .debug_macro 0x0000000000000000 0x391 ecm_src/src/time.o + .debug_macro 0x0000000000000000 0xfe50 ecm_src/src/time.o + .debug_macro 0x0000000000000000 0x3c ecm_src/src/time.o + .debug_macro 0x0000000000000000 0x12d ecm_src/src/time.o + .debug_macro 0x0000000000000000 0x53 ecm_src/src/time.o + .debug_macro 0x0000000000000000 0x946 ecm_src/src/time.o + .debug_macro 0x0000000000000000 0x5f3 ecm_src/src/time.o + .debug_macro 0x0000000000000000 0x12f ecm_src/src/time.o + .debug_macro 0x0000000000000000 0x1a7 ecm_src/src/time.o + .debug_macro 0x0000000000000000 0x1a7 ecm_src/src/time.o + .debug_macro 0x0000000000000000 0x22c ecm_src/src/time.o + .debug_macro 0x0000000000000000 0x34 ecm_src/src/time.o + .debug_macro 0x0000000000000000 0x43 ecm_src/src/time.o + .debug_macro 0x0000000000000000 0x28 ecm_src/src/time.o + .debug_macro 0x0000000000000000 0xb0 ecm_src/src/time.o + .debug_macro 0x0000000000000000 0x217 ecm_src/src/time.o + .debug_macro 0x0000000000000000 0x22c ecm_src/src/time.o + .debug_macro 0x0000000000000000 0x5f ecm_src/src/time.o + .debug_macro 0x0000000000000000 0xa5 ecm_src/src/time.o + .debug_macro 0x0000000000000000 0x65 ecm_src/src/time.o + .debug_macro 0x0000000000000000 0x234 ecm_src/src/time.o + .debug_macro 0x0000000000000000 0x4c ecm_src/src/time.o + .debug_macro 0x0000000000000000 0x16d ecm_src/src/time.o + .debug_macro 0x0000000000000000 0x130 ecm_src/src/time.o + .debug_macro 0x0000000000000000 0x10 ecm_src/src/time.o + COMMON 0x0000000000000000 0x8 ecm_src/src/time.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usb_device.o + .text 0x0000000000000000 0x0 ecm_src/src/usb_device.o + .data 0x0000000000000000 0x0 ecm_src/src/usb_device.o + .bss 0x0000000000000000 0x0 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0xa48 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x2e ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x22 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x22 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x8e ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x51 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0xef ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x6a ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x1df ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x1c ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x22 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0xb5 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x391 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0xfe50 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x3c ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x12d ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x174 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x53 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x946 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x5f3 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x12f ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x1a7 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x1a7 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x22c ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x34 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x43 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x28 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0xb0 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x217 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x22c ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x5f ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0xa5 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x65 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x234 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x4c ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x16d ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x130 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x46 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x18 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x3c ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x34 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x16 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x35 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x32a ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x10 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x52 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x1f ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x43 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x20 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x1a3 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x10 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x1c ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x52 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x40 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x10 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x40 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0xd7 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x1c ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x3d ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x16 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x145 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x16 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x16 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x29 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x16 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x20 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x64 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x1a6 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x22 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x70 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x16 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x22 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x16 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x5e ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x592 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x76 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x4f ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x52 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x175 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x62 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x13b ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x80 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x10 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x10 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x10 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x46 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x64 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x3d ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0xdc ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x22 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0xac ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x1be ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x10 ecm_src/src/usb_device.o + .debug_macro 0x0000000000000000 0x10 ecm_src/src/usb_device.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_conf.o + .text 0x0000000000000000 0x0 ecm_src/src/usbd_conf.o + .data 0x0000000000000000 0x0 ecm_src/src/usbd_conf.o + .bss 0x0000000000000000 0x0 ecm_src/src/usbd_conf.o + .text.HAL_PCD_MspDeInit + 0x0000000000000000 0x24 ecm_src/src/usbd_conf.o + .text.HAL_PCD_ISOOUTIncompleteCallback + 0x0000000000000000 0x2a ecm_src/src/usbd_conf.o + .text.HAL_PCD_ISOINIncompleteCallback + 0x0000000000000000 0x2a ecm_src/src/usbd_conf.o + .text.HAL_PCD_ConnectCallback + 0x0000000000000000 0x1e ecm_src/src/usbd_conf.o + .text.HAL_PCD_DisconnectCallback + 0x0000000000000000 0x1e ecm_src/src/usbd_conf.o + .text.USBD_LL_DeInit + 0x0000000000000000 0x20 ecm_src/src/usbd_conf.o + .text.USBD_LL_Stop + 0x0000000000000000 0x20 ecm_src/src/usbd_conf.o + .text.USBD_LL_FlushEP + 0x0000000000000000 0x2c ecm_src/src/usbd_conf.o + .text.USBD_LL_Delay + 0x0000000000000000 0x18 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0xa48 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x12d ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x2e ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x22 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x22 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x8e ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x51 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0xef ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x6a ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x1df ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x1c ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x22 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0xb5 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x391 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0xfe50 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x3c ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x174 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x53 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x946 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x5f3 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x12f ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x1a7 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x1a7 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x22c ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x34 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x43 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x28 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0xb0 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x217 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x22c ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x5f ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0xa5 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x65 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x234 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x4c ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x16d ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x130 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x46 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x18 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x3c ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x34 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x16 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x35 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x32a ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x10 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x52 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x1f ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x43 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x20 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x1a3 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x10 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x1c ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x52 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x40 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x10 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x40 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0xd7 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x1c ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x3d ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x16 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x145 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x16 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x16 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x29 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x16 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x20 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x64 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x22 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x70 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x16 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x22 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x16 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x5e ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x592 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x76 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x4f ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x52 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x175 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x62 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x13b ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x80 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x10 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x10 ecm_src/src/usbd_conf.o + .debug_macro 0x0000000000000000 0x10 ecm_src/src/usbd_conf.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_core.o + .text 0x0000000000000000 0x0 ecm_src/src/usbd_core.o + .data 0x0000000000000000 0x0 ecm_src/src/usbd_core.o + .bss 0x0000000000000000 0x0 ecm_src/src/usbd_core.o + .text.USBD_DeInit + 0x0000000000000000 0x42 ecm_src/src/usbd_core.o + .text.USBD_Stop + 0x0000000000000000 0x30 ecm_src/src/usbd_core.o + .text.USBD_LL_Suspend + 0x0000000000000000 0x2c ecm_src/src/usbd_core.o + .text.USBD_LL_Resume + 0x0000000000000000 0x22 ecm_src/src/usbd_core.o + .text.USBD_LL_IsoINIncomplete + 0x0000000000000000 0x18 ecm_src/src/usbd_core.o + .text.USBD_LL_IsoOUTIncomplete + 0x0000000000000000 0x18 ecm_src/src/usbd_core.o + .text.USBD_LL_DevConnected + 0x0000000000000000 0x12 ecm_src/src/usbd_core.o + .text.USBD_LL_DevDisconnected + 0x0000000000000000 0x32 ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0xa48 ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x12d ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x2e ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x22 ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x22 ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x8e ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x51 ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0xef ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x6a ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x1df ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x1c ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x22 ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0xb5 ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x391 ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0xfe50 ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x3c ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x174 ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x53 ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x946 ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x5f3 ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x12f ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x1a7 ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x1a7 ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x22c ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x34 ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x43 ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x28 ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0xb0 ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x217 ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x22c ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x5f ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0xa5 ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x65 ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x234 ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x4c ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x16d ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x130 ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x46 ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x18 ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x3c ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x34 ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x16 ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x35 ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x32a ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x10 ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x52 ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x1f ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x43 ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x20 ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x1a3 ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x10 ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x1c ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x52 ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x40 ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x10 ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x40 ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0xd7 ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x1c ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x3d ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x16 ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x145 ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x16 ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x16 ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x29 ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x16 ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x20 ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x64 ecm_src/src/usbd_core.o + .debug_macro 0x0000000000000000 0x1ac ecm_src/src/usbd_core.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ctlreq.o + .text 0x0000000000000000 0x0 ecm_src/src/usbd_ctlreq.o + .data 0x0000000000000000 0x0 ecm_src/src/usbd_ctlreq.o + .bss 0x0000000000000000 0x0 ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0xa48 ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x12d ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x2e ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x22 ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x22 ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x8e ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x51 ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0xef ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x6a ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x1df ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x1c ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x22 ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0xb5 ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x391 ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0xfe50 ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x3c ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x174 ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x53 ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x946 ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x5f3 ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x12f ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x1a7 ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x1a7 ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x22c ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x34 ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x43 ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x28 ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0xb0 ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x217 ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x22c ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x5f ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0xa5 ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x65 ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x234 ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x4c ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x16d ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x130 ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x46 ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x18 ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x3c ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x34 ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x16 ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x35 ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x32a ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x10 ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x52 ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x1f ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x43 ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x20 ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x1a3 ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x10 ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x1c ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x52 ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x40 ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x10 ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x40 ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0xd7 ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x1c ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x3d ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x16 ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x145 ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x16 ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x16 ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x29 ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x16 ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x20 ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x64 ecm_src/src/usbd_ctlreq.o + .debug_macro 0x0000000000000000 0x1a6 ecm_src/src/usbd_ctlreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_desc.o + .text 0x0000000000000000 0x0 ecm_src/src/usbd_desc.o + .data 0x0000000000000000 0x0 ecm_src/src/usbd_desc.o + .bss 0x0000000000000000 0x0 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0xa48 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x12d ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x2e ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x22 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x22 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x8e ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x51 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0xef ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x6a ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x1df ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x1c ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x22 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0xb5 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x391 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0xfe50 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x3c ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x174 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x53 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x946 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x5f3 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x12f ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x1a7 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x1a7 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x22c ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x34 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x43 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x28 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0xb0 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x217 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x22c ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x5f ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0xa5 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x65 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x234 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x4c ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x16d ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x130 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x46 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x18 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x3c ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x34 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x16 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x35 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x32a ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x10 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x52 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x1f ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x43 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x20 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x1a3 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x10 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x1c ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x52 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x40 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x10 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x40 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0xd7 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x1c ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x3d ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x16 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x145 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x16 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x16 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x29 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x16 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x20 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x64 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x1ac ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x10 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x22 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x70 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x16 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x22 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x16 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x5e ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x592 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x76 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x4f ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x52 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x175 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x62 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x13b ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x80 ecm_src/src/usbd_desc.o + .debug_macro 0x0000000000000000 0x10 ecm_src/src/usbd_desc.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ecm.o + .text 0x0000000000000000 0x0 ecm_src/src/usbd_ecm.o + .data 0x0000000000000000 0x0 ecm_src/src/usbd_ecm.o + .bss 0x0000000000000000 0x0 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0xa48 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x22 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x8e ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x51 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0xef ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x6a ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x1df ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x22 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x12d ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x2e ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x22 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x1c ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x22 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0xb5 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x391 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0xfe50 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x3c ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x174 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x53 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x946 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x5f3 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x12f ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x1a7 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x1a7 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x22c ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x34 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x43 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x28 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0xb0 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x217 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x22c ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x5f ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0xa5 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x65 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x234 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x4c ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x16d ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x130 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x46 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x18 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x3c ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x34 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x16 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x35 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x32a ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x10 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x52 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x1f ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x43 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x20 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x1a3 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x10 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x1c ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x52 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x40 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x10 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x40 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0xd7 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x1c ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x3d ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x16 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x145 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x16 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x16 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x29 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x16 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x20 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x64 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x1a6 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x70 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x16 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x22 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x16 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x5e ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x592 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x76 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x4f ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x52 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x175 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x62 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x13b ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x80 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x10 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x10 ecm_src/src/usbd_ecm.o + .debug_macro 0x0000000000000000 0x10 ecm_src/src/usbd_ecm.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .group 0x0000000000000000 0xc ecm_src/src/usbd_ioreq.o + .text 0x0000000000000000 0x0 ecm_src/src/usbd_ioreq.o + .data 0x0000000000000000 0x0 ecm_src/src/usbd_ioreq.o + .bss 0x0000000000000000 0x0 ecm_src/src/usbd_ioreq.o + .text.USBD_CtlPrepareRx + 0x0000000000000000 0x48 ecm_src/src/usbd_ioreq.o + .text.USBD_GetRxCount + 0x0000000000000000 0x28 ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0xa48 ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x12d ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x2e ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x22 ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x22 ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x8e ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x51 ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0xef ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x6a ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x1df ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x1c ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x22 ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0xb5 ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x391 ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0xfe50 ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x3c ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x174 ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x53 ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x946 ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x5f3 ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x12f ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x1a7 ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x1a7 ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x22c ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x34 ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x43 ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x28 ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0xb0 ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x217 ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x22c ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x5f ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0xa5 ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x65 ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x234 ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x4c ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x16d ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x130 ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x46 ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x18 ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x3c ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x34 ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x16 ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x35 ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x32a ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x10 ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x52 ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x1f ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x43 ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x20 ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x1a3 ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x10 ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x1c ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x52 ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x40 ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x10 ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x40 ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0xd7 ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x1c ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x3d ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x16 ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x145 ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x16 ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x16 ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x29 ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x16 ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x20 ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x64 ecm_src/src/usbd_ioreq.o + .debug_macro 0x0000000000000000 0x1a6 ecm_src/src/usbd_ioreq.o + .text 0x0000000000000000 0x0 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-errno.o) + .data 0x0000000000000000 0x0 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-errno.o) + .bss 0x0000000000000000 0x0 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-errno.o) + .text.__errno 0x0000000000000000 0xc c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-errno.o) + .debug_frame 0x0000000000000000 0x20 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-errno.o) + .ARM.attributes + 0x0000000000000000 0x2c c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-errno.o) + .text 0x0000000000000000 0x0 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-exit.o) + .data 0x0000000000000000 0x0 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-exit.o) + .bss 0x0000000000000000 0x0 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-exit.o) + .text.exit 0x0000000000000000 0x2c c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-exit.o) + .debug_frame 0x0000000000000000 0x28 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-exit.o) + .ARM.attributes + 0x0000000000000000 0x2c c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-exit.o) + .text 0x0000000000000000 0x0 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-impure.o) + .data 0x0000000000000000 0x0 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-impure.o) + .bss 0x0000000000000000 0x0 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-impure.o) + .data._impure_ptr + 0x0000000000000000 0x4 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-impure.o) + .data.impure_data + 0x0000000000000000 0x60 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-impure.o) + .rodata._global_impure_ptr + 0x0000000000000000 0x4 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-impure.o) + .ARM.attributes + 0x0000000000000000 0x2c c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-impure.o) + .text 0x0000000000000000 0x0 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-init.o) + .data 0x0000000000000000 0x0 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-init.o) + .bss 0x0000000000000000 0x0 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-init.o) + .text 0x0000000000000000 0x0 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-memcmp.o) + .data 0x0000000000000000 0x0 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-memcmp.o) + .bss 0x0000000000000000 0x0 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-memcmp.o) + .text 0x0000000000000000 0x0 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-memcpy-stub.o) + .data 0x0000000000000000 0x0 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-memcpy-stub.o) + .bss 0x0000000000000000 0x0 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-memcpy-stub.o) + .text 0x0000000000000000 0x0 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-memset.o) + .data 0x0000000000000000 0x0 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-memset.o) + .bss 0x0000000000000000 0x0 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-memset.o) + .data 0x0000000000000000 0x0 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-strcmp.o) + .bss 0x0000000000000000 0x0 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-strcmp.o) + .data 0x0000000000000000 0x0 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-strlen.o) + .bss 0x0000000000000000 0x0 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-strlen.o) + .data 0x0000000000000000 0x0 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v6-m\libgcc.a(_udivsi3.o) + .bss 0x0000000000000000 0x0 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v6-m\libgcc.a(_udivsi3.o) + .data 0x0000000000000000 0x0 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v6-m\libgcc.a(_divsi3.o) + .bss 0x0000000000000000 0x0 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v6-m\libgcc.a(_divsi3.o) + .data 0x0000000000000000 0x0 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v6-m\libgcc.a(_dvmd_tls.o) + .bss 0x0000000000000000 0x0 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v6-m\libgcc.a(_dvmd_tls.o) + .text 0x0000000000000000 0x0 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v6-m/crtend.o + .data 0x0000000000000000 0x0 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v6-m/crtend.o + .bss 0x0000000000000000 0x0 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v6-m/crtend.o + .eh_frame 0x0000000000000000 0x4 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v6-m/crtend.o + .ARM.attributes + 0x0000000000000000 0x2c c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v6-m/crtend.o + .text 0x0000000000000000 0x0 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v6-m/crtn.o + .data 0x0000000000000000 0x0 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v6-m/crtn.o + .bss 0x0000000000000000 0x0 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v6-m/crtn.o + +Memory Configuration + +Name Origin Length Attributes +RAM 0x0000000020000000 0x0000000000004000 xrw +FLASH 0x0000000008000000 0x0000000000010000 xr +*default* 0x0000000000000000 0xffffffffffffffff + +Linker script and memory map + +LOAD c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v6-m/crti.o +LOAD c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v6-m/crtbegin.o +LOAD c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m/crt0.o +LOAD Core/Src/main.o +LOAD Core/Src/stm32f0xx_hal_msp.o +LOAD Core/Src/stm32f0xx_it.o +LOAD Core/Src/syscalls.o +LOAD Core/Src/sysmem.o +LOAD Core/Src/system_stm32f0xx.o +LOAD Core/Startup/startup_stm32f072c8tx.o +LOAD Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o +LOAD Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o +LOAD Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.o +LOAD Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.o +LOAD Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.o +LOAD Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.o +LOAD Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o +LOAD Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.o +LOAD Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.o +LOAD Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o +LOAD Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o +LOAD Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.o +LOAD Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.o +LOAD Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o +LOAD Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o +LOAD Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.o +LOAD Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.o +LOAD Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o +LOAD ecm_src/dhcp-server/dhserver.o +LOAD ecm_src/dns-server/dnserver.o +LOAD ecm_src/lwip-1.4.1/src/core/def.o +LOAD ecm_src/lwip-1.4.1/src/core/dhcp.o +LOAD ecm_src/lwip-1.4.1/src/core/dns.o +LOAD ecm_src/lwip-1.4.1/src/core/init.o +LOAD ecm_src/lwip-1.4.1/src/core/mem.o +LOAD ecm_src/lwip-1.4.1/src/core/memp.o +LOAD ecm_src/lwip-1.4.1/src/core/netif.o +LOAD ecm_src/lwip-1.4.1/src/core/pbuf.o +LOAD ecm_src/lwip-1.4.1/src/core/raw.o +LOAD ecm_src/lwip-1.4.1/src/core/stats.o +LOAD ecm_src/lwip-1.4.1/src/core/sys.o +LOAD ecm_src/lwip-1.4.1/src/core/tcp.o +LOAD ecm_src/lwip-1.4.1/src/core/tcp_in.o +LOAD ecm_src/lwip-1.4.1/src/core/tcp_out.o +LOAD ecm_src/lwip-1.4.1/src/core/timers.o +LOAD ecm_src/lwip-1.4.1/src/core/udp.o +LOAD ecm_src/lwip-1.4.1/src/core/ipv4/autoip.o +LOAD ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o +LOAD ecm_src/lwip-1.4.1/src/core/ipv4/igmp.o +LOAD ecm_src/lwip-1.4.1/src/core/ipv4/inet.o +LOAD ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o +LOAD ecm_src/lwip-1.4.1/src/core/ipv4/ip.o +LOAD ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o +LOAD ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o +LOAD ecm_src/lwip-1.4.1/src/netif/etharp.o +LOAD ecm_src/lwip-1.4.1/src/netif/ethernetif.o +LOAD ecm_src/src/ecm_main.o +LOAD ecm_src/src/time.o +LOAD ecm_src/src/usb_device.o +LOAD ecm_src/src/usbd_conf.o +LOAD ecm_src/src/usbd_core.o +LOAD ecm_src/src/usbd_ctlreq.o +LOAD ecm_src/src/usbd_desc.o +LOAD ecm_src/src/usbd_ecm.o +LOAD ecm_src/src/usbd_ioreq.o +START GROUP +LOAD c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a +LOAD c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libm.a +END GROUP +START GROUP +LOAD c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v6-m\libgcc.a +LOAD c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a +END GROUP +START GROUP +LOAD c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v6-m\libgcc.a +LOAD c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a +LOAD c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libnosys.a +END GROUP +START GROUP +LOAD c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v6-m\libgcc.a +LOAD c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a +LOAD c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libnosys.a +END GROUP +LOAD c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v6-m/crtend.o +LOAD c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v6-m/crtn.o + 0x0000000020004000 _estack = (ORIGIN (RAM) + LENGTH (RAM)) + 0x0000000000000200 _Min_Heap_Size = 0x200 + 0x0000000000000400 _Min_Stack_Size = 0x400 + +.isr_vector 0x0000000008000000 0xc0 + 0x0000000008000000 . = ALIGN (0x4) + *(.isr_vector) + .isr_vector 0x0000000008000000 0xc0 Core/Startup/startup_stm32f072c8tx.o + 0x0000000008000000 g_pfnVectors + 0x00000000080000c0 . = ALIGN (0x4) + +.text 0x00000000080000c0 0xfc1c + 0x00000000080000c0 . = ALIGN (0x4) + *(.text) + .text 0x00000000080000c0 0x48 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v6-m/crtbegin.o + .text 0x0000000008000108 0x14 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-strcmp.o) + 0x0000000008000108 strcmp + .text 0x000000000800011c 0xe c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-strlen.o) + 0x000000000800011c strlen + *fill* 0x000000000800012a 0x2 + .text 0x000000000800012c 0x114 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v6-m\libgcc.a(_udivsi3.o) + 0x000000000800012c __aeabi_uidiv + 0x000000000800012c __udivsi3 + 0x0000000008000238 __aeabi_uidivmod + .text 0x0000000008000240 0x1d4 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v6-m\libgcc.a(_divsi3.o) + 0x0000000008000240 __divsi3 + 0x0000000008000240 __aeabi_idiv + 0x000000000800040c __aeabi_idivmod + .text 0x0000000008000414 0x4 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v6-m\libgcc.a(_dvmd_tls.o) + 0x0000000008000414 __aeabi_idiv0 + 0x0000000008000414 __aeabi_ldiv0 + *(.text*) + .text.main 0x0000000008000418 0x1e Core/Src/main.o + 0x0000000008000418 main + .text.SystemClock_Config + 0x0000000008000436 0xa8 Core/Src/main.o + 0x0000000008000436 SystemClock_Config + *fill* 0x00000000080004de 0x2 + .text.MX_GPIO_Init + 0x00000000080004e0 0x30 Core/Src/main.o + .text.Error_Handler + 0x0000000008000510 0xa Core/Src/main.o + 0x0000000008000510 Error_Handler + *fill* 0x000000000800051a 0x2 + .text.HAL_MspInit + 0x000000000800051c 0x48 Core/Src/stm32f0xx_hal_msp.o + 0x000000000800051c HAL_MspInit + .text.NMI_Handler + 0x0000000008000564 0xa Core/Src/stm32f0xx_it.o + 0x0000000008000564 NMI_Handler + .text.HardFault_Handler + 0x000000000800056e 0x6 Core/Src/stm32f0xx_it.o + 0x000000000800056e HardFault_Handler + .text.SVC_Handler + 0x0000000008000574 0xa Core/Src/stm32f0xx_it.o + 0x0000000008000574 SVC_Handler + .text.PendSV_Handler + 0x000000000800057e 0xa Core/Src/stm32f0xx_it.o + 0x000000000800057e PendSV_Handler + .text.SysTick_Handler + 0x0000000008000588 0xe Core/Src/stm32f0xx_it.o + 0x0000000008000588 SysTick_Handler + *fill* 0x0000000008000596 0x2 + .text.USB_IRQHandler + 0x0000000008000598 0x18 Core/Src/stm32f0xx_it.o + 0x0000000008000598 USB_IRQHandler + .text.SystemInit + 0x00000000080005b0 0xa Core/Src/system_stm32f0xx.o + 0x00000000080005b0 SystemInit + *fill* 0x00000000080005ba 0x2 + .text.Reset_Handler + 0x00000000080005bc 0x50 Core/Startup/startup_stm32f072c8tx.o + 0x00000000080005bc Reset_Handler + .text.Default_Handler + 0x000000000800060c 0x2 Core/Startup/startup_stm32f072c8tx.o + 0x000000000800060c TIM1_CC_IRQHandler + 0x000000000800060c TSC_IRQHandler + 0x000000000800060c ADC1_COMP_IRQHandler + 0x000000000800060c I2C1_IRQHandler + 0x000000000800060c RCC_CRS_IRQHandler + 0x000000000800060c SPI1_IRQHandler + 0x000000000800060c TIM6_DAC_IRQHandler + 0x000000000800060c USART3_4_IRQHandler + 0x000000000800060c EXTI2_3_IRQHandler + 0x000000000800060c I2C2_IRQHandler + 0x000000000800060c TIM17_IRQHandler + 0x000000000800060c CEC_CAN_IRQHandler + 0x000000000800060c RTC_IRQHandler + 0x000000000800060c PVD_VDDIO2_IRQHandler + 0x000000000800060c DMA1_Channel4_5_6_7_IRQHandler + 0x000000000800060c TIM16_IRQHandler + 0x000000000800060c TIM3_IRQHandler + 0x000000000800060c EXTI4_15_IRQHandler + 0x000000000800060c DMA1_Channel1_IRQHandler + 0x000000000800060c Default_Handler + 0x000000000800060c TIM14_IRQHandler + 0x000000000800060c TIM7_IRQHandler + 0x000000000800060c TIM15_IRQHandler + 0x000000000800060c EXTI0_1_IRQHandler + 0x000000000800060c SPI2_IRQHandler + 0x000000000800060c WWDG_IRQHandler + 0x000000000800060c TIM2_IRQHandler + 0x000000000800060c DMA1_Channel2_3_IRQHandler + 0x000000000800060c USART2_IRQHandler + 0x000000000800060c FLASH_IRQHandler + 0x000000000800060c USART1_IRQHandler + 0x000000000800060c TIM1_BRK_UP_TRG_COM_IRQHandler + *fill* 0x000000000800060e 0x2 + .text.HAL_Init + 0x0000000008000610 0x28 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + 0x0000000008000610 HAL_Init + .text.HAL_InitTick + 0x0000000008000638 0x68 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + 0x0000000008000638 HAL_InitTick + .text.HAL_IncTick + 0x00000000080006a0 0x24 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + 0x00000000080006a0 HAL_IncTick + .text.HAL_GetTick + 0x00000000080006c4 0x14 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + 0x00000000080006c4 HAL_GetTick + .text.__NVIC_EnableIRQ + 0x00000000080006d8 0x34 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .text.__NVIC_SetPriority + 0x000000000800070c 0xdc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .text.SysTick_Config + 0x00000000080007e8 0x48 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .text.HAL_NVIC_SetPriority + 0x0000000008000830 0x2a Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + 0x0000000008000830 HAL_NVIC_SetPriority + .text.HAL_NVIC_EnableIRQ + 0x000000000800085a 0x20 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + 0x000000000800085a HAL_NVIC_EnableIRQ + .text.HAL_SYSTICK_Config + 0x000000000800087a 0x1a Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + 0x000000000800087a HAL_SYSTICK_Config + .text.HAL_GPIO_Init + 0x0000000008000894 0x2f0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + 0x0000000008000894 HAL_GPIO_Init + .text.HAL_PCD_Init + 0x0000000008000b84 0x1c8 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + 0x0000000008000b84 HAL_PCD_Init + .text.HAL_PCD_Start + 0x0000000008000d4c 0x4a Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + 0x0000000008000d4c HAL_PCD_Start + *fill* 0x0000000008000d96 0x2 + .text.HAL_PCD_IRQHandler + 0x0000000008000d98 0x310 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + 0x0000000008000d98 HAL_PCD_IRQHandler + .text.HAL_PCD_SetAddress + 0x00000000080010a8 0x56 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + 0x00000000080010a8 HAL_PCD_SetAddress + .text.HAL_PCD_EP_Open + 0x00000000080010fe 0xe4 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + 0x00000000080010fe HAL_PCD_EP_Open + .text.HAL_PCD_EP_Close + 0x00000000080011e2 0x96 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + 0x00000000080011e2 HAL_PCD_EP_Close + .text.HAL_PCD_EP_Receive + 0x0000000008001278 0x82 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + 0x0000000008001278 HAL_PCD_EP_Receive + .text.HAL_PCD_EP_GetRxCount + 0x00000000080012fa 0x2a Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + 0x00000000080012fa HAL_PCD_EP_GetRxCount + .text.HAL_PCD_EP_Transmit + 0x0000000008001324 0x80 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + 0x0000000008001324 HAL_PCD_EP_Transmit + .text.HAL_PCD_EP_SetStall + 0x00000000080013a4 0xcc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + 0x00000000080013a4 HAL_PCD_EP_SetStall + .text.HAL_PCD_EP_ClrStall + 0x0000000008001470 0xb0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + 0x0000000008001470 HAL_PCD_EP_ClrStall + .text.PCD_EP_ISR_Handler + 0x0000000008001520 0x5a8 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .text.HAL_PCDEx_PMAConfig + 0x0000000008001ac8 0x90 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + 0x0000000008001ac8 HAL_PCDEx_PMAConfig + .text.HAL_PCDEx_ActivateLPM + 0x0000000008001b58 0x54 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + 0x0000000008001b58 HAL_PCDEx_ActivateLPM + .text.HAL_PCDEx_LPM_Callback + 0x0000000008001bac 0x16 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + 0x0000000008001bac HAL_PCDEx_LPM_Callback + *fill* 0x0000000008001bc2 0x2 + .text.HAL_RCC_OscConfig + 0x0000000008001bc4 0x70c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + 0x0000000008001bc4 HAL_RCC_OscConfig + .text.HAL_RCC_ClockConfig + 0x00000000080022d0 0x1b4 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + 0x00000000080022d0 HAL_RCC_ClockConfig + .text.HAL_RCC_GetSysClockFreq + 0x0000000008002484 0xfc Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + 0x0000000008002484 HAL_RCC_GetSysClockFreq + .text.HAL_RCCEx_PeriphCLKConfig + 0x0000000008002580 0x200 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + 0x0000000008002580 HAL_RCCEx_PeriphCLKConfig + .text.USB_EnableGlobalInt + 0x0000000008002780 0x34 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + 0x0000000008002780 USB_EnableGlobalInt + .text.USB_DisableGlobalInt + 0x00000000080027b4 0x40 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + 0x00000000080027b4 USB_DisableGlobalInt + .text.USB_DevInit + 0x00000000080027f4 0x60 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + 0x00000000080027f4 USB_DevInit + .text.USB_ActivateEndpoint + 0x0000000008002854 0x5f0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + 0x0000000008002854 USB_ActivateEndpoint + .text.USB_DeactivateEndpoint + 0x0000000008002e44 0x2ec Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + 0x0000000008002e44 USB_DeactivateEndpoint + .text.USB_EPStartXfer + 0x0000000008003130 0x5a4 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + 0x0000000008003130 USB_EPStartXfer + .text.USB_EPSetStall + 0x00000000080036d4 0x84 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + 0x00000000080036d4 USB_EPSetStall + .text.USB_EPClearStall + 0x0000000008003758 0x124 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + 0x0000000008003758 USB_EPClearStall + .text.USB_SetDevAddress + 0x000000000800387c 0x28 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + 0x000000000800387c USB_SetDevAddress + .text.USB_DevConnect + 0x00000000080038a4 0x2c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + 0x00000000080038a4 USB_DevConnect + .text.USB_ReadInterrupts + 0x00000000080038d0 0x1c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + 0x00000000080038d0 USB_ReadInterrupts + .text.USB_EP0_OutStart + 0x00000000080038ec 0x14 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + 0x00000000080038ec USB_EP0_OutStart + .text.USB_WritePMA + 0x0000000008003900 0x86 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + 0x0000000008003900 USB_WritePMA + .text.USB_ReadPMA + 0x0000000008003986 0x9e Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + 0x0000000008003986 USB_ReadPMA + .text.get_ip 0x0000000008003a24 0x20 ecm_src/dhcp-server/dhserver.o + .text.set_ip 0x0000000008003a44 0x1e ecm_src/dhcp-server/dhserver.o + *fill* 0x0000000008003a62 0x2 + .text.entry_by_ip + 0x0000000008003a64 0x64 ecm_src/dhcp-server/dhserver.o + .text.entry_by_mac + 0x0000000008003ac8 0x64 ecm_src/dhcp-server/dhserver.o + .text.is_vacant + 0x0000000008003b2c 0x28 ecm_src/dhcp-server/dhserver.o + .text.vacant_address + 0x0000000008003b54 0x5c ecm_src/dhcp-server/dhserver.o + .text.free_entry + 0x0000000008003bb0 0x1c ecm_src/dhcp-server/dhserver.o + .text.find_dhcp_option + 0x0000000008003bcc 0x64 ecm_src/dhcp-server/dhserver.o + 0x0000000008003bcc find_dhcp_option + .text.fill_options + 0x0000000008003c30 0x17a ecm_src/dhcp-server/dhserver.o + 0x0000000008003c30 fill_options + *fill* 0x0000000008003daa 0x2 + .text.udp_recv_proc + 0x0000000008003dac 0x2f4 ecm_src/dhcp-server/dhserver.o + .text.dhserv_init + 0x00000000080040a0 0x88 ecm_src/dhcp-server/dhserver.o + 0x00000000080040a0 dhserv_init + .text.dhserv_free + 0x0000000008004128 0x28 ecm_src/dhcp-server/dhserver.o + 0x0000000008004128 dhserv_free + .text.get_uint16 + 0x0000000008004150 0x22 ecm_src/dns-server/dnserver.o + .text.parse_next_query + 0x0000000008004172 0x118 ecm_src/dns-server/dnserver.o + *fill* 0x000000000800428a 0x2 + .text.udp_recv_proc + 0x000000000800428c 0x2d0 ecm_src/dns-server/dnserver.o + .text.dnserv_init + 0x000000000800455c 0x90 ecm_src/dns-server/dnserver.o + 0x000000000800455c dnserv_init + .text.dnserv_free + 0x00000000080045ec 0x28 ecm_src/dns-server/dnserver.o + 0x00000000080045ec dnserv_free + .text.lwip_htons + 0x0000000008004614 0x2c ecm_src/lwip-1.4.1/src/core/def.o + 0x0000000008004614 lwip_htons + .text.lwip_ntohs + 0x0000000008004640 0x20 ecm_src/lwip-1.4.1/src/core/def.o + 0x0000000008004640 lwip_ntohs + .text.lwip_htonl + 0x0000000008004660 0x32 ecm_src/lwip-1.4.1/src/core/def.o + 0x0000000008004660 lwip_htonl + .text.lwip_ntohl + 0x0000000008004692 0x1a ecm_src/lwip-1.4.1/src/core/def.o + 0x0000000008004692 lwip_ntohl + .text.lwip_init + 0x00000000080046ac 0x26 ecm_src/lwip-1.4.1/src/core/init.o + 0x00000000080046ac lwip_init + *fill* 0x00000000080046d2 0x2 + .text.plug_holes + 0x00000000080046d4 0xbc ecm_src/lwip-1.4.1/src/core/mem.o + .text.mem_init + 0x0000000008004790 0x88 ecm_src/lwip-1.4.1/src/core/mem.o + 0x0000000008004790 mem_init + .text.mem_free + 0x0000000008004818 0x94 ecm_src/lwip-1.4.1/src/core/mem.o + 0x0000000008004818 mem_free + .text.mem_trim + 0x00000000080048ac 0x228 ecm_src/lwip-1.4.1/src/core/mem.o + 0x00000000080048ac mem_trim + .text.mem_malloc + 0x0000000008004ad4 0x218 ecm_src/lwip-1.4.1/src/core/mem.o + 0x0000000008004ad4 mem_malloc + .text.memp_init + 0x0000000008004cec 0x128 ecm_src/lwip-1.4.1/src/core/memp.o + 0x0000000008004cec memp_init + .text.memp_malloc + 0x0000000008004e14 0x10c ecm_src/lwip-1.4.1/src/core/memp.o + 0x0000000008004e14 memp_malloc + .text.memp_free + 0x0000000008004f20 0x74 ecm_src/lwip-1.4.1/src/core/memp.o + 0x0000000008004f20 memp_free + .text.netif_init + 0x0000000008004f94 0xa ecm_src/lwip-1.4.1/src/core/netif.o + 0x0000000008004f94 netif_init + *fill* 0x0000000008004f9e 0x2 + .text.netif_add + 0x0000000008004fa0 0x84 ecm_src/lwip-1.4.1/src/core/netif.o + 0x0000000008004fa0 netif_add + .text.netif_set_addr + 0x0000000008005024 0x3a ecm_src/lwip-1.4.1/src/core/netif.o + 0x0000000008005024 netif_set_addr + *fill* 0x000000000800505e 0x2 + .text.netif_set_ipaddr + 0x0000000008005060 0xb4 ecm_src/lwip-1.4.1/src/core/netif.o + 0x0000000008005060 netif_set_ipaddr + .text.netif_set_gw + 0x0000000008005114 0x24 ecm_src/lwip-1.4.1/src/core/netif.o + 0x0000000008005114 netif_set_gw + .text.netif_set_netmask + 0x0000000008005138 0x24 ecm_src/lwip-1.4.1/src/core/netif.o + 0x0000000008005138 netif_set_netmask + .text.netif_set_default + 0x000000000800515c 0x1c ecm_src/lwip-1.4.1/src/core/netif.o + 0x000000000800515c netif_set_default + .text.pbuf_pool_is_empty + 0x0000000008005178 0x14 ecm_src/lwip-1.4.1/src/core/pbuf.o + .text.pbuf_alloc + 0x000000000800518c 0x244 ecm_src/lwip-1.4.1/src/core/pbuf.o + 0x000000000800518c pbuf_alloc + .text.pbuf_alloced_custom + 0x00000000080053d0 0xe2 ecm_src/lwip-1.4.1/src/core/pbuf.o + 0x00000000080053d0 pbuf_alloced_custom + .text.pbuf_realloc + 0x00000000080054b2 0xe4 ecm_src/lwip-1.4.1/src/core/pbuf.o + 0x00000000080054b2 pbuf_realloc + .text.pbuf_header + 0x0000000008005596 0x10e ecm_src/lwip-1.4.1/src/core/pbuf.o + 0x0000000008005596 pbuf_header + .text.pbuf_free + 0x00000000080056a4 0xe4 ecm_src/lwip-1.4.1/src/core/pbuf.o + 0x00000000080056a4 pbuf_free + .text.pbuf_clen + 0x0000000008005788 0x38 ecm_src/lwip-1.4.1/src/core/pbuf.o + 0x0000000008005788 pbuf_clen + .text.pbuf_ref + 0x00000000080057c0 0x22 ecm_src/lwip-1.4.1/src/core/pbuf.o + 0x00000000080057c0 pbuf_ref + .text.pbuf_cat + 0x00000000080057e2 0x5a ecm_src/lwip-1.4.1/src/core/pbuf.o + 0x00000000080057e2 pbuf_cat + .text.pbuf_chain + 0x000000000800583c 0x26 ecm_src/lwip-1.4.1/src/core/pbuf.o + 0x000000000800583c pbuf_chain + .text.pbuf_copy + 0x0000000008005862 0x15a ecm_src/lwip-1.4.1/src/core/pbuf.o + 0x0000000008005862 pbuf_copy + .text.pbuf_copy_partial + 0x00000000080059bc 0x110 ecm_src/lwip-1.4.1/src/core/pbuf.o + 0x00000000080059bc pbuf_copy_partial + .text.raw_input + 0x0000000008005acc 0xd4 ecm_src/lwip-1.4.1/src/core/raw.o + 0x0000000008005acc raw_input + .text.stats_init + 0x0000000008005ba0 0xa ecm_src/lwip-1.4.1/src/core/stats.o + 0x0000000008005ba0 stats_init + .text.tcp_init + 0x0000000008005baa 0xa ecm_src/lwip-1.4.1/src/core/tcp.o + 0x0000000008005baa tcp_init + .text.tcp_tmr 0x0000000008005bb4 0x30 ecm_src/lwip-1.4.1/src/core/tcp.o + 0x0000000008005bb4 tcp_tmr + .text.tcp_close_shutdown + 0x0000000008005be4 0x284 ecm_src/lwip-1.4.1/src/core/tcp.o + .text.tcp_close + 0x0000000008005e68 0x32 ecm_src/lwip-1.4.1/src/core/tcp.o + 0x0000000008005e68 tcp_close + *fill* 0x0000000008005e9a 0x2 + .text.tcp_abandon + 0x0000000008005e9c 0xe0 ecm_src/lwip-1.4.1/src/core/tcp.o + 0x0000000008005e9c tcp_abandon + .text.tcp_abort + 0x0000000008005f7c 0x1a ecm_src/lwip-1.4.1/src/core/tcp.o + 0x0000000008005f7c tcp_abort + *fill* 0x0000000008005f96 0x2 + .text.tcp_update_rcv_ann_wnd + 0x0000000008005f98 0x80 ecm_src/lwip-1.4.1/src/core/tcp.o + 0x0000000008005f98 tcp_update_rcv_ann_wnd + .text.tcp_recved + 0x0000000008006018 0x68 ecm_src/lwip-1.4.1/src/core/tcp.o + 0x0000000008006018 tcp_recved + .text.tcp_slowtmr + 0x0000000008006080 0x4dc ecm_src/lwip-1.4.1/src/core/tcp.o + 0x0000000008006080 tcp_slowtmr + .text.tcp_fasttmr + 0x000000000800655c 0xa8 ecm_src/lwip-1.4.1/src/core/tcp.o + 0x000000000800655c tcp_fasttmr + .text.tcp_process_refused_data + 0x0000000008006604 0xf0 ecm_src/lwip-1.4.1/src/core/tcp.o + 0x0000000008006604 tcp_process_refused_data + .text.tcp_segs_free + 0x00000000080066f4 0x2a ecm_src/lwip-1.4.1/src/core/tcp.o + 0x00000000080066f4 tcp_segs_free + .text.tcp_seg_free + 0x000000000800671e 0x32 ecm_src/lwip-1.4.1/src/core/tcp.o + 0x000000000800671e tcp_seg_free + .text.tcp_seg_copy + 0x0000000008006750 0x3c ecm_src/lwip-1.4.1/src/core/tcp.o + 0x0000000008006750 tcp_seg_copy + .text.tcp_recv_null + 0x000000000800678c 0x50 ecm_src/lwip-1.4.1/src/core/tcp.o + 0x000000000800678c tcp_recv_null + .text.tcp_kill_prio + 0x00000000080067dc 0x94 ecm_src/lwip-1.4.1/src/core/tcp.o + .text.tcp_kill_timewait + 0x0000000008006870 0x60 ecm_src/lwip-1.4.1/src/core/tcp.o + .text.tcp_alloc + 0x00000000080068d0 0x158 ecm_src/lwip-1.4.1/src/core/tcp.o + 0x00000000080068d0 tcp_alloc + .text.tcp_pcb_purge + 0x0000000008006a28 0x82 ecm_src/lwip-1.4.1/src/core/tcp.o + 0x0000000008006a28 tcp_pcb_purge + *fill* 0x0000000008006aaa 0x2 + .text.tcp_pcb_remove + 0x0000000008006aac 0xa8 ecm_src/lwip-1.4.1/src/core/tcp.o + 0x0000000008006aac tcp_pcb_remove + .text.tcp_next_iss + 0x0000000008006b54 0x24 ecm_src/lwip-1.4.1/src/core/tcp.o + 0x0000000008006b54 tcp_next_iss + .text.tcp_eff_send_mss + 0x0000000008006b78 0x56 ecm_src/lwip-1.4.1/src/core/tcp.o + 0x0000000008006b78 tcp_eff_send_mss + *fill* 0x0000000008006bce 0x2 + .text.tcp_input + 0x0000000008006bd0 0x8b8 ecm_src/lwip-1.4.1/src/core/tcp_in.o + 0x0000000008006bd0 tcp_input + .text.tcp_listen_input + 0x0000000008007488 0x1e0 ecm_src/lwip-1.4.1/src/core/tcp_in.o + .text.tcp_timewait_input + 0x0000000008007668 0xe8 ecm_src/lwip-1.4.1/src/core/tcp_in.o + .text.tcp_process + 0x0000000008007750 0x738 ecm_src/lwip-1.4.1/src/core/tcp_in.o + .text.tcp_oos_insert_segment + 0x0000000008007e88 0x15c ecm_src/lwip-1.4.1/src/core/tcp_in.o + .text.tcp_receive + 0x0000000008007fe4 0x1154 ecm_src/lwip-1.4.1/src/core/tcp_in.o + .text.tcp_parseopt + 0x0000000008009138 0x16c ecm_src/lwip-1.4.1/src/core/tcp_in.o + .text.tcp_output_alloc_header + 0x00000000080092a4 0x21a ecm_src/lwip-1.4.1/src/core/tcp_out.o + .text.tcp_send_fin + 0x00000000080094be 0xb0 ecm_src/lwip-1.4.1/src/core/tcp_out.o + 0x00000000080094be tcp_send_fin + *fill* 0x000000000800956e 0x2 + .text.tcp_create_segment + 0x0000000008009570 0x1ec ecm_src/lwip-1.4.1/src/core/tcp_out.o + .text.tcp_enqueue_flags + 0x000000000800975c 0x1f4 ecm_src/lwip-1.4.1/src/core/tcp_out.o + 0x000000000800975c tcp_enqueue_flags + .text.tcp_send_empty_ack + 0x0000000008009950 0xc0 ecm_src/lwip-1.4.1/src/core/tcp_out.o + 0x0000000008009950 tcp_send_empty_ack + .text.tcp_output + 0x0000000008009a10 0x370 ecm_src/lwip-1.4.1/src/core/tcp_out.o + 0x0000000008009a10 tcp_output + .text.tcp_output_segment + 0x0000000008009d80 0x24c ecm_src/lwip-1.4.1/src/core/tcp_out.o + .text.tcp_rst 0x0000000008009fcc 0x248 ecm_src/lwip-1.4.1/src/core/tcp_out.o + 0x0000000008009fcc tcp_rst + .text.tcp_rexmit_rto + 0x000000000800a214 0x64 ecm_src/lwip-1.4.1/src/core/tcp_out.o + 0x000000000800a214 tcp_rexmit_rto + .text.tcp_rexmit + 0x000000000800a278 0xb8 ecm_src/lwip-1.4.1/src/core/tcp_out.o + 0x000000000800a278 tcp_rexmit + .text.tcp_rexmit_fast + 0x000000000800a330 0xaa ecm_src/lwip-1.4.1/src/core/tcp_out.o + 0x000000000800a330 tcp_rexmit_fast + *fill* 0x000000000800a3da 0x2 + .text.tcp_keepalive + 0x000000000800a3dc 0xb0 ecm_src/lwip-1.4.1/src/core/tcp_out.o + 0x000000000800a3dc tcp_keepalive + .text.tcp_zero_window_probe + 0x000000000800a48c 0x1a0 ecm_src/lwip-1.4.1/src/core/tcp_out.o + 0x000000000800a48c tcp_zero_window_probe + .text.tcpip_tcp_timer + 0x000000000800a62c 0x48 ecm_src/lwip-1.4.1/src/core/timers.o + .text.tcp_timer_needed + 0x000000000800a674 0x44 ecm_src/lwip-1.4.1/src/core/timers.o + 0x000000000800a674 tcp_timer_needed + .text.ip_reass_timer + 0x000000000800a6b8 0x28 ecm_src/lwip-1.4.1/src/core/timers.o + .text.arp_timer + 0x000000000800a6e0 0x28 ecm_src/lwip-1.4.1/src/core/timers.o + .text.sys_timeouts_init + 0x000000000800a708 0x40 ecm_src/lwip-1.4.1/src/core/timers.o + 0x000000000800a708 sys_timeouts_init + .text.sys_timeout + 0x000000000800a748 0xe0 ecm_src/lwip-1.4.1/src/core/timers.o + 0x000000000800a748 sys_timeout + .text.udp_init + 0x000000000800a828 0xa ecm_src/lwip-1.4.1/src/core/udp.o + 0x000000000800a828 udp_init + *fill* 0x000000000800a832 0x2 + .text.udp_new_port + 0x000000000800a834 0x7c ecm_src/lwip-1.4.1/src/core/udp.o + .text.udp_input + 0x000000000800a8b0 0x33c ecm_src/lwip-1.4.1/src/core/udp.o + 0x000000000800a8b0 udp_input + .text.udp_sendto + 0x000000000800abec 0x5c ecm_src/lwip-1.4.1/src/core/udp.o + 0x000000000800abec udp_sendto + .text.udp_sendto_if + 0x000000000800ac48 0x240 ecm_src/lwip-1.4.1/src/core/udp.o + 0x000000000800ac48 udp_sendto_if + .text.udp_bind + 0x000000000800ae88 0xd8 ecm_src/lwip-1.4.1/src/core/udp.o + 0x000000000800ae88 udp_bind + .text.udp_recv + 0x000000000800af60 0x20 ecm_src/lwip-1.4.1/src/core/udp.o + 0x000000000800af60 udp_recv + .text.udp_remove + 0x000000000800af80 0x64 ecm_src/lwip-1.4.1/src/core/udp.o + 0x000000000800af80 udp_remove + .text.udp_new 0x000000000800afe4 0x32 ecm_src/lwip-1.4.1/src/core/udp.o + 0x000000000800afe4 udp_new + *fill* 0x000000000800b016 0x2 + .text.icmp_input + 0x000000000800b018 0x3f4 ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + 0x000000000800b018 icmp_input + .text.icmp_dest_unreach + 0x000000000800b40c 0x24 ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + 0x000000000800b40c icmp_dest_unreach + .text.icmp_time_exceeded + 0x000000000800b430 0x24 ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + 0x000000000800b430 icmp_time_exceeded + .text.icmp_send_response + 0x000000000800b454 0x120 ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .text.lwip_standard_chksum + 0x000000000800b574 0xc6 ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .text.inet_chksum_pseudo + 0x000000000800b63a 0x136 ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + 0x000000000800b63a inet_chksum_pseudo + .text.inet_chksum + 0x000000000800b770 0x2a ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + 0x000000000800b770 inet_chksum + .text.inet_chksum_pbuf + 0x000000000800b79a 0xac ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + 0x000000000800b79a inet_chksum_pbuf + *fill* 0x000000000800b846 0x2 + .text.ip_route + 0x000000000800b848 0x88 ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + 0x000000000800b848 ip_route + .text.ip_input + 0x000000000800b8d0 0x394 ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + 0x000000000800b8d0 ip_input + .text.ip_output_if + 0x000000000800bc64 0x3ac ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + 0x000000000800bc64 ip_output_if + .text.ip_output + 0x000000000800c010 0x6c ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + 0x000000000800c010 ip_output + .text.ip4_addr_isbroadcast + 0x000000000800c07c 0x70 ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o + 0x000000000800c07c ip4_addr_isbroadcast + .text.ip_reass_tmr + 0x000000000800c0ec 0x5c ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + 0x000000000800c0ec ip_reass_tmr + .text.ip_reass_free_complete_datagram + 0x000000000800c148 0x11c ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .text.ip_reass_remove_oldest_datagram + 0x000000000800c264 0xe8 ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .text.ip_reass_enqueue_new_datagram + 0x000000000800c34c 0x90 ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .text.ip_reass_dequeue_datagram + 0x000000000800c3dc 0x3c ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .text.ip_reass_chain_frag_into_datagram_and_validate + 0x000000000800c418 0x3d8 ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .text.ip_reass + 0x000000000800c7f0 0x38c ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + 0x000000000800c7f0 ip_reass + .text.ip_frag_alloc_pbuf_custom_ref + 0x000000000800cb7c 0x12 ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .text.ip_frag_free_pbuf_custom_ref + 0x000000000800cb8e 0x1a ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .text.ipfrag_free_pbuf_custom + 0x000000000800cba8 0x2e ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + *fill* 0x000000000800cbd6 0x2 + .text.ip_frag 0x000000000800cbd8 0x364 ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + 0x000000000800cbd8 ip_frag + .text.etharp_free_entry + 0x000000000800cf3c 0x60 ecm_src/lwip-1.4.1/src/netif/etharp.o + .text.etharp_tmr + 0x000000000800cf9c 0x100 ecm_src/lwip-1.4.1/src/netif/etharp.o + 0x000000000800cf9c etharp_tmr + .text.etharp_find_entry + 0x000000000800d09c 0x2f8 ecm_src/lwip-1.4.1/src/netif/etharp.o + .text.etharp_send_ip + 0x000000000800d394 0x5c ecm_src/lwip-1.4.1/src/netif/etharp.o + .text.etharp_update_arp_entry + 0x000000000800d3f0 0x168 ecm_src/lwip-1.4.1/src/netif/etharp.o + .text.etharp_arp_input + 0x000000000800d558 0x20c ecm_src/lwip-1.4.1/src/netif/etharp.o + .text.etharp_output_to_arp_index + 0x000000000800d764 0xb4 ecm_src/lwip-1.4.1/src/netif/etharp.o + .text.etharp_output + 0x000000000800d818 0x1e0 ecm_src/lwip-1.4.1/src/netif/etharp.o + 0x000000000800d818 etharp_output + .text.etharp_query + 0x000000000800d9f8 0x290 ecm_src/lwip-1.4.1/src/netif/etharp.o + 0x000000000800d9f8 etharp_query + .text.etharp_raw + 0x000000000800dc88 0x16c ecm_src/lwip-1.4.1/src/netif/etharp.o + .text.etharp_request + 0x000000000800ddf4 0x48 ecm_src/lwip-1.4.1/src/netif/etharp.o + 0x000000000800ddf4 etharp_request + .text.ethernet_input + 0x000000000800de3c 0x148 ecm_src/lwip-1.4.1/src/netif/etharp.o + 0x000000000800de3c ethernet_input + .text.usb_ecm_recv_callback + 0x000000000800df84 0x5c ecm_src/src/ecm_main.o + 0x000000000800df84 usb_ecm_recv_callback + .text.sys_now 0x000000000800dfe0 0x10 ecm_src/src/ecm_main.o + 0x000000000800dfe0 sys_now + .text.tcp_timer_proc + 0x000000000800dff0 0x14 ecm_src/src/ecm_main.o + 0x000000000800dff0 tcp_timer_proc + .text.output_fn + 0x000000000800e004 0x22 ecm_src/src/ecm_main.o + 0x000000000800e004 output_fn + .text.linkoutput_fn + 0x000000000800e026 0x44 ecm_src/src/ecm_main.o + 0x000000000800e026 linkoutput_fn + *fill* 0x000000000800e06a 0x2 + .text.netif_init_cb + 0x000000000800e06c 0x4c ecm_src/src/ecm_main.o + 0x000000000800e06c netif_init_cb + .text.init_lwip + 0x000000000800e0b8 0x80 ecm_src/src/ecm_main.o + .text.dns_query_proc + 0x000000000800e138 0x4c ecm_src/src/ecm_main.o + 0x000000000800e138 dns_query_proc + .text.service_traffic + 0x000000000800e184 0x48 ecm_src/src/ecm_main.o + .text.ecm_main_init + 0x000000000800e1cc 0x54 ecm_src/src/ecm_main.o + 0x000000000800e1cc ecm_main_init + .text.ecm_main_loop + 0x000000000800e220 0x12 ecm_src/src/ecm_main.o + 0x000000000800e220 ecm_main_loop + .text.time_init + 0x000000000800e232 0xa ecm_src/src/time.o + 0x000000000800e232 time_init + .text.mtime 0x000000000800e23c 0x10 ecm_src/src/time.o + 0x000000000800e23c mtime + .text.msleep 0x000000000800e24c 0x3c ecm_src/src/time.o + 0x000000000800e24c msleep + .text.stmr 0x000000000800e288 0x6c ecm_src/src/time.o + 0x000000000800e288 stmr + .text.stmr_add + 0x000000000800e2f4 0x24 ecm_src/src/time.o + 0x000000000800e2f4 stmr_add + .text.MX_USB_DEVICE_Init + 0x000000000800e318 0x60 ecm_src/src/usb_device.o + 0x000000000800e318 MX_USB_DEVICE_Init + .text.HAL_PCD_MspInit + 0x000000000800e378 0x8c ecm_src/src/usbd_conf.o + 0x000000000800e378 HAL_PCD_MspInit + .text.HAL_PCD_SetupStageCallback + 0x000000000800e404 0x2a ecm_src/src/usbd_conf.o + 0x000000000800e404 HAL_PCD_SetupStageCallback + .text.HAL_PCD_DataOutStageCallback + 0x000000000800e42e 0x3a ecm_src/src/usbd_conf.o + 0x000000000800e42e HAL_PCD_DataOutStageCallback + .text.HAL_PCD_DataInStageCallback + 0x000000000800e468 0x36 ecm_src/src/usbd_conf.o + 0x000000000800e468 HAL_PCD_DataInStageCallback + .text.HAL_PCD_SOFCallback + 0x000000000800e49e 0x1e ecm_src/src/usbd_conf.o + 0x000000000800e49e HAL_PCD_SOFCallback + .text.HAL_PCD_ResetCallback + 0x000000000800e4bc 0x2e ecm_src/src/usbd_conf.o + 0x000000000800e4bc HAL_PCD_ResetCallback + .text.HAL_PCD_SuspendCallback + 0x000000000800e4ea 0x10 ecm_src/src/usbd_conf.o + 0x000000000800e4ea HAL_PCD_SuspendCallback + .text.HAL_PCD_ResumeCallback + 0x000000000800e4fa 0x10 ecm_src/src/usbd_conf.o + 0x000000000800e4fa HAL_PCD_ResumeCallback + *fill* 0x000000000800e50a 0x2 + .text.USBD_LL_Init + 0x000000000800e50c 0x98 ecm_src/src/usbd_conf.o + 0x000000000800e50c USBD_LL_Init + .text.USBD_LL_Start + 0x000000000800e5a4 0x20 ecm_src/src/usbd_conf.o + 0x000000000800e5a4 USBD_LL_Start + .text.USBD_LL_OpenEP + 0x000000000800e5c4 0x44 ecm_src/src/usbd_conf.o + 0x000000000800e5c4 USBD_LL_OpenEP + .text.USBD_LL_CloseEP + 0x000000000800e608 0x2c ecm_src/src/usbd_conf.o + 0x000000000800e608 USBD_LL_CloseEP + .text.USBD_LL_StallEP + 0x000000000800e634 0x2c ecm_src/src/usbd_conf.o + 0x000000000800e634 USBD_LL_StallEP + .text.USBD_LL_ClearStallEP + 0x000000000800e660 0x2c ecm_src/src/usbd_conf.o + 0x000000000800e660 USBD_LL_ClearStallEP + .text.USBD_LL_IsStallEP + 0x000000000800e68c 0x56 ecm_src/src/usbd_conf.o + 0x000000000800e68c USBD_LL_IsStallEP + .text.USBD_LL_SetUSBAddress + 0x000000000800e6e2 0x2c ecm_src/src/usbd_conf.o + 0x000000000800e6e2 USBD_LL_SetUSBAddress + .text.USBD_LL_Transmit + 0x000000000800e70e 0x52 ecm_src/src/usbd_conf.o + 0x000000000800e70e USBD_LL_Transmit + .text.USBD_LL_PrepareReceive + 0x000000000800e760 0x52 ecm_src/src/usbd_conf.o + 0x000000000800e760 USBD_LL_PrepareReceive + .text.USBD_LL_GetRxDataSize + 0x000000000800e7b2 0x2c ecm_src/src/usbd_conf.o + 0x000000000800e7b2 USBD_LL_GetRxDataSize + .text.USBD_Init + 0x000000000800e7de 0x62 ecm_src/src/usbd_core.o + 0x000000000800e7de USBD_Init + .text.USBD_RegisterClass + 0x000000000800e840 0x42 ecm_src/src/usbd_core.o + 0x000000000800e840 USBD_RegisterClass + .text.USBD_Start + 0x000000000800e882 0x1a ecm_src/src/usbd_core.o + 0x000000000800e882 USBD_Start + .text.USBD_SetClassConfig + 0x000000000800e89c 0x50 ecm_src/src/usbd_core.o + 0x000000000800e89c USBD_SetClassConfig + .text.USBD_ClrClassConfig + 0x000000000800e8ec 0x2c ecm_src/src/usbd_core.o + 0x000000000800e8ec USBD_ClrClassConfig + .text.USBD_LL_SetupStage + 0x000000000800e918 0xb8 ecm_src/src/usbd_core.o + 0x000000000800e918 USBD_LL_SetupStage + .text.USBD_LL_DataOutStage + 0x000000000800e9d0 0xd2 ecm_src/src/usbd_core.o + 0x000000000800e9d0 USBD_LL_DataOutStage + .text.USBD_LL_DataInStage + 0x000000000800eaa2 0x10e ecm_src/src/usbd_core.o + 0x000000000800eaa2 USBD_LL_DataInStage + .text.USBD_LL_Reset + 0x000000000800ebb0 0x66 ecm_src/src/usbd_core.o + 0x000000000800ebb0 USBD_LL_Reset + .text.USBD_LL_SetSpeed + 0x000000000800ec16 0x20 ecm_src/src/usbd_core.o + 0x000000000800ec16 USBD_LL_SetSpeed + .text.USBD_LL_SOF + 0x000000000800ec36 0x3c ecm_src/src/usbd_core.o + 0x000000000800ec36 USBD_LL_SOF + *fill* 0x000000000800ec72 0x2 + .text.USBD_StdDevReq + 0x000000000800ec74 0xa8 ecm_src/src/usbd_ctlreq.o + 0x000000000800ec74 USBD_StdDevReq + .text.USBD_StdItfReq + 0x000000000800ed1c 0x7e ecm_src/src/usbd_ctlreq.o + 0x000000000800ed1c USBD_StdItfReq + .text.USBD_StdEPReq + 0x000000000800ed9a 0x208 ecm_src/src/usbd_ctlreq.o + 0x000000000800ed9a USBD_StdEPReq + .text.USBD_GetDescriptor + 0x000000000800efa2 0x142 ecm_src/src/usbd_ctlreq.o + .text.USBD_SetAddress + 0x000000000800f0e4 0x9c ecm_src/src/usbd_ctlreq.o + .text.USBD_SetConfig + 0x000000000800f180 0x138 ecm_src/src/usbd_ctlreq.o + .text.USBD_GetConfig + 0x000000000800f2b8 0x70 ecm_src/src/usbd_ctlreq.o + .text.USBD_GetStatus + 0x000000000800f328 0x5e ecm_src/src/usbd_ctlreq.o + .text.USBD_SetFeature + 0x000000000800f386 0x3e ecm_src/src/usbd_ctlreq.o + .text.USBD_ClrFeature + 0x000000000800f3c4 0x5e ecm_src/src/usbd_ctlreq.o + .text.USBD_ParseSetupRequest + 0x000000000800f422 0x76 ecm_src/src/usbd_ctlreq.o + 0x000000000800f422 USBD_ParseSetupRequest + .text.USBD_CtlError + 0x000000000800f498 0x26 ecm_src/src/usbd_ctlreq.o + 0x000000000800f498 USBD_CtlError + .text.USBD_GetString + 0x000000000800f4be 0xa0 ecm_src/src/usbd_ctlreq.o + 0x000000000800f4be USBD_GetString + .text.USBD_GetLen + 0x000000000800f55e 0x3a ecm_src/src/usbd_ctlreq.o + .text.USBD_VCP_DeviceDescriptor + 0x000000000800f598 0x24 ecm_src/src/usbd_desc.o + .text.USBD_VCP_LangIDStrDescriptor + 0x000000000800f5bc 0x24 ecm_src/src/usbd_desc.o + .text.USBD_VCP_ProductStrDescriptor + 0x000000000800f5e0 0x2c ecm_src/src/usbd_desc.o + .text.USBD_VCP_ManufacturerStrDescriptor + 0x000000000800f60c 0x2c ecm_src/src/usbd_desc.o + .text.USBD_VCP_SerialStrDescriptor + 0x000000000800f638 0x5c ecm_src/src/usbd_desc.o + .text.IntToUnicode + 0x000000000800f694 0x94 ecm_src/src/usbd_desc.o + .text.usb_ecm_recv_renew + 0x000000000800f728 0x48 ecm_src/src/usbd_ecm.o + 0x000000000800f728 usb_ecm_recv_renew + .text.USBD_ECM_Init + 0x000000000800f770 0x74 ecm_src/src/usbd_ecm.o + .text.USBD_ECM_DeInit + 0x000000000800f7e4 0x4c ecm_src/src/usbd_ecm.o + .text.USBD_ECM_Setup + 0x000000000800f830 0x34 ecm_src/src/usbd_ecm.o + .text.ecm_incoming_attempt + 0x000000000800f864 0x70 ecm_src/src/usbd_ecm.o + .text.USBD_ECM_DataIn + 0x000000000800f8d4 0x4c ecm_src/src/usbd_ecm.o + .text.USBD_ECM_DataOut + 0x000000000800f920 0x70 ecm_src/src/usbd_ecm.o + .text.USBD_ECM_SOF + 0x000000000800f990 0x60 ecm_src/src/usbd_ecm.o + .text.USBD_ECM_EP0_RxReady + 0x000000000800f9f0 0x12 ecm_src/src/usbd_ecm.o + *fill* 0x000000000800fa02 0x2 + .text.USBD_ECM_GetFSCfgDesc + 0x000000000800fa04 0x24 ecm_src/src/usbd_ecm.o + .text.USBD_ECM_RegisterInterface + 0x000000000800fa28 0x12 ecm_src/src/usbd_ecm.o + 0x000000000800fa28 USBD_ECM_RegisterInterface + .text.USBD_ECM_PMAConfig + 0x000000000800fa3a 0x60 ecm_src/src/usbd_ecm.o + 0x000000000800fa3a USBD_ECM_PMAConfig + *fill* 0x000000000800fa9a 0x2 + .text.usb_ecm_can_xmit + 0x000000000800fa9c 0x24 ecm_src/src/usbd_ecm.o + 0x000000000800fa9c usb_ecm_can_xmit + .text.usb_ecm_xmit_packet + 0x000000000800fac0 0xa0 ecm_src/src/usbd_ecm.o + 0x000000000800fac0 usb_ecm_xmit_packet + .text.USBD_CtlSendData + 0x000000000800fb60 0x40 ecm_src/src/usbd_ioreq.o + 0x000000000800fb60 USBD_CtlSendData + .text.USBD_CtlContinueSendData + 0x000000000800fba0 0x26 ecm_src/src/usbd_ioreq.o + 0x000000000800fba0 USBD_CtlContinueSendData + .text.USBD_CtlContinueRx + 0x000000000800fbc6 0x26 ecm_src/src/usbd_ioreq.o + 0x000000000800fbc6 USBD_CtlContinueRx + .text.USBD_CtlSendStatus + 0x000000000800fbec 0x28 ecm_src/src/usbd_ioreq.o + 0x000000000800fbec USBD_CtlSendStatus + .text.USBD_CtlReceiveStatus + 0x000000000800fc14 0x28 ecm_src/src/usbd_ioreq.o + 0x000000000800fc14 USBD_CtlReceiveStatus + .text.__libc_init_array + 0x000000000800fc3c 0x48 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-init.o) + 0x000000000800fc3c __libc_init_array + .text.memcmp 0x000000000800fc84 0x1e c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-memcmp.o) + 0x000000000800fc84 memcmp + .text.memcpy 0x000000000800fca2 0x12 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-memcpy-stub.o) + 0x000000000800fca2 memcpy + .text.memset 0x000000000800fcb4 0x10 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-memset.o) + 0x000000000800fcb4 memset + *(.glue_7) + .glue_7 0x000000000800fcc4 0x0 linker stubs + *(.glue_7t) + .glue_7t 0x000000000800fcc4 0x0 linker stubs + *(.eh_frame) + .eh_frame 0x000000000800fcc4 0x0 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v6-m/crtbegin.o + *(.init) + .init 0x000000000800fcc4 0x4 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v6-m/crti.o + 0x000000000800fcc4 _init + .init 0x000000000800fcc8 0x8 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v6-m/crtn.o + *(.fini) + .fini 0x000000000800fcd0 0x4 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v6-m/crti.o + 0x000000000800fcd0 _fini + .fini 0x000000000800fcd4 0x8 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v6-m/crtn.o + 0x000000000800fcdc . = ALIGN (0x4) + 0x000000000800fcdc _etext = . + +.vfp11_veneer 0x000000000800fcdc 0x0 + .vfp11_veneer 0x000000000800fcdc 0x0 linker stubs + +.v4_bx 0x000000000800fcdc 0x0 + .v4_bx 0x000000000800fcdc 0x0 linker stubs + +.iplt 0x000000000800fcdc 0x0 + .iplt 0x000000000800fcdc 0x0 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v6-m/crtbegin.o + +.rodata 0x000000000800fcdc 0x1cc + 0x000000000800fcdc . = ALIGN (0x4) + *(.rodata) + .rodata 0x000000000800fcdc 0x20 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .rodata 0x000000000800fcfc 0x6 ecm_src/dhcp-server/dhserver.o + *fill* 0x000000000800fd02 0x2 + .rodata 0x000000000800fd04 0x18 ecm_src/src/ecm_main.o + .rodata 0x000000000800fd1c 0x9 ecm_src/src/usbd_desc.o + *(.rodata*) + *fill* 0x000000000800fd25 0x3 + .rodata.AHBPrescTable + 0x000000000800fd28 0x10 Core/Src/system_stm32f0xx.o + 0x000000000800fd28 AHBPrescTable + .rodata.memp_sizes + 0x000000000800fd38 0x14 ecm_src/lwip-1.4.1/src/core/memp.o + .rodata.memp_num + 0x000000000800fd4c 0x14 ecm_src/lwip-1.4.1/src/core/memp.o + .rodata.tcp_backoff + 0x000000000800fd60 0xd ecm_src/lwip-1.4.1/src/core/tcp.o + 0x000000000800fd60 tcp_backoff + *fill* 0x000000000800fd6d 0x3 + .rodata.tcp_persist_backoff + 0x000000000800fd70 0x7 ecm_src/lwip-1.4.1/src/core/tcp.o + 0x000000000800fd70 tcp_persist_backoff + *fill* 0x000000000800fd77 0x1 + .rodata.tcp_close_shutdown + 0x000000000800fd78 0x20 ecm_src/lwip-1.4.1/src/core/tcp.o + .rodata.tcp_process + 0x000000000800fd98 0x28 ecm_src/lwip-1.4.1/src/core/tcp_in.o + .rodata.ip_addr_any + 0x000000000800fdc0 0x4 ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o + 0x000000000800fdc0 ip_addr_any + .rodata.ip_addr_broadcast + 0x000000000800fdc4 0x4 ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o + 0x000000000800fdc4 ip_addr_broadcast + .rodata.ethbroadcast + 0x000000000800fdc8 0x6 ecm_src/lwip-1.4.1/src/netif/etharp.o + 0x000000000800fdc8 ethbroadcast + *fill* 0x000000000800fdce 0x2 + .rodata.ethzero + 0x000000000800fdd0 0x6 ecm_src/lwip-1.4.1/src/netif/etharp.o + 0x000000000800fdd0 ethzero + *fill* 0x000000000800fdd6 0x2 + .rodata.USBD_StdDevReq + 0x000000000800fdd8 0x28 ecm_src/src/usbd_ctlreq.o + .rodata.VCP_Desc + 0x000000000800fe00 0x14 ecm_src/src/usbd_desc.o + 0x000000000800fe00 VCP_Desc + .rodata.hUSBDDeviceDesc + 0x000000000800fe14 0x12 ecm_src/src/usbd_desc.o + *fill* 0x000000000800fe26 0x2 + .rodata.USBD_ECM_CfgFSDesc + 0x000000000800fe28 0x47 ecm_src/src/usbd_desc.o + *fill* 0x000000000800fe6f 0x1 + .rodata.USBD_CfgFSDesc_pnt + 0x000000000800fe70 0x4 ecm_src/src/usbd_desc.o + 0x000000000800fe70 USBD_CfgFSDesc_pnt + .rodata.USBD_CfgFSDesc_len + 0x000000000800fe74 0x2 ecm_src/src/usbd_desc.o + 0x000000000800fe74 USBD_CfgFSDesc_len + *fill* 0x000000000800fe76 0x2 + .rodata.USBD_LangIDDesc + 0x000000000800fe78 0x4 ecm_src/src/usbd_desc.o + .rodata.USBD_ECM + 0x000000000800fe7c 0x2c ecm_src/src/usbd_ecm.o + 0x000000000800fe7c USBD_ECM + 0x000000000800fea8 . = ALIGN (0x4) + +.rel.dyn 0x000000000800fea8 0x0 + .rel.iplt 0x000000000800fea8 0x0 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v6-m/crtbegin.o + +.ARM.extab 0x000000000800fea8 0x0 + 0x000000000800fea8 . = ALIGN (0x4) + *(.ARM.extab* .gnu.linkonce.armextab.*) + 0x000000000800fea8 . = ALIGN (0x4) + +.ARM 0x000000000800fea8 0x0 + 0x000000000800fea8 . = ALIGN (0x4) + 0x000000000800fea8 __exidx_start = . + *(.ARM.exidx*) + 0x000000000800fea8 __exidx_end = . + 0x000000000800fea8 . = ALIGN (0x4) + +.preinit_array 0x000000000800fea8 0x0 + 0x000000000800fea8 . = ALIGN (0x4) + 0x000000000800fea8 PROVIDE (__preinit_array_start = .) + *(.preinit_array*) + 0x000000000800fea8 PROVIDE (__preinit_array_end = .) + 0x000000000800fea8 . = ALIGN (0x4) + +.init_array 0x000000000800fea8 0x4 + 0x000000000800fea8 . = ALIGN (0x4) + 0x000000000800fea8 PROVIDE (__init_array_start = .) + *(SORT_BY_NAME(.init_array.*)) + *(.init_array*) + .init_array 0x000000000800fea8 0x4 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v6-m/crtbegin.o + 0x000000000800feac PROVIDE (__init_array_end = .) + 0x000000000800feac . = ALIGN (0x4) + +.fini_array 0x000000000800feac 0x4 + 0x000000000800feac . = ALIGN (0x4) + [!provide] PROVIDE (__fini_array_start = .) + *(SORT_BY_NAME(.fini_array.*)) + *(.fini_array*) + .fini_array 0x000000000800feac 0x4 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v6-m/crtbegin.o + [!provide] PROVIDE (__fini_array_end = .) + 0x000000000800feb0 . = ALIGN (0x4) + 0x000000000800feb0 _sidata = LOADADDR (.data) + +.data 0x0000000020000000 0x9c load address 0x000000000800feb0 + 0x0000000020000000 . = ALIGN (0x4) + 0x0000000020000000 _sdata = . + *(.data) + *(.data*) + .data.SystemCoreClock + 0x0000000020000000 0x4 Core/Src/system_stm32f0xx.o + 0x0000000020000000 SystemCoreClock + .data.uwTickPrio + 0x0000000020000004 0x4 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + 0x0000000020000004 uwTickPrio + .data.uwTickFreq + 0x0000000020000008 0x1 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + 0x0000000020000008 uwTickFreq + *fill* 0x0000000020000009 0x3 + .data.magic_cookie + 0x000000002000000c 0x4 ecm_src/dhcp-server/dhserver.o + 0x000000002000000c magic_cookie + .data.iss.5439 + 0x0000000020000010 0x4 ecm_src/lwip-1.4.1/src/core/tcp.o + .data.udp_port + 0x0000000020000014 0x2 ecm_src/lwip-1.4.1/src/core/udp.o + *fill* 0x0000000020000016 0x2 + .data.hwaddr 0x0000000020000018 0x6 ecm_src/src/ecm_main.o + *fill* 0x000000002000001e 0x2 + .data.ipaddr 0x0000000020000020 0x4 ecm_src/src/ecm_main.o + .data.netmask 0x0000000020000024 0x4 ecm_src/src/ecm_main.o + .data.entries 0x0000000020000028 0x3c ecm_src/src/ecm_main.o + .data.dhcp_config + 0x0000000020000064 0x18 ecm_src/src/ecm_main.o + .data.tcp_timer + 0x000000002000007c 0x18 ecm_src/src/ecm_main.o + .data.notify 0x0000000020000094 0x8 ecm_src/src/usbd_ecm.o + 0x000000002000009c . = ALIGN (0x4) + 0x000000002000009c _edata = . + +.igot.plt 0x000000002000009c 0x0 load address 0x000000000800ff4c + .igot.plt 0x000000002000009c 0x0 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v6-m/crtbegin.o + 0x000000002000009c . = ALIGN (0x4) + +.bss 0x000000002000009c 0x369c load address 0x000000000800ff4c + 0x000000002000009c _sbss = . + 0x000000002000009c __bss_start__ = _sbss + *(.bss) + .bss 0x000000002000009c 0x1c c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v6-m/crtbegin.o + *(.bss*) + .bss.pcb 0x00000000200000b8 0x4 ecm_src/dhcp-server/dhserver.o + .bss.config 0x00000000200000bc 0x4 ecm_src/dhcp-server/dhserver.o + .bss.pcb 0x00000000200000c0 0x4 ecm_src/dns-server/dnserver.o + .bss.query_proc + 0x00000000200000c4 0x4 ecm_src/dns-server/dnserver.o + 0x00000000200000c4 query_proc + .bss.query.5774 + 0x00000000200000c8 0x84 ecm_src/dns-server/dnserver.o + .bss.ram 0x000000002000014c 0x4 ecm_src/lwip-1.4.1/src/core/mem.o + .bss.ram_end 0x0000000020000150 0x4 ecm_src/lwip-1.4.1/src/core/mem.o + .bss.lfree 0x0000000020000154 0x4 ecm_src/lwip-1.4.1/src/core/mem.o + .bss.memp_tab 0x0000000020000158 0x28 ecm_src/lwip-1.4.1/src/core/memp.o + .bss.memp_memory + 0x0000000020000180 0x20f3 ecm_src/lwip-1.4.1/src/core/memp.o + .bss.netif_num + 0x0000000020002273 0x1 ecm_src/lwip-1.4.1/src/core/netif.o + .bss.raw_pcbs 0x0000000020002274 0x4 ecm_src/lwip-1.4.1/src/core/raw.o + .bss.tcp_timer + 0x0000000020002278 0x1 ecm_src/lwip-1.4.1/src/core/tcp.o + .bss.tcp_timer_ctr + 0x0000000020002279 0x1 ecm_src/lwip-1.4.1/src/core/tcp.o + *fill* 0x000000002000227a 0x2 + .bss.inseg 0x000000002000227c 0x10 ecm_src/lwip-1.4.1/src/core/tcp_in.o + .bss.tcphdr 0x000000002000228c 0x4 ecm_src/lwip-1.4.1/src/core/tcp_in.o + .bss.iphdr 0x0000000020002290 0x4 ecm_src/lwip-1.4.1/src/core/tcp_in.o + .bss.seqno 0x0000000020002294 0x4 ecm_src/lwip-1.4.1/src/core/tcp_in.o + .bss.ackno 0x0000000020002298 0x4 ecm_src/lwip-1.4.1/src/core/tcp_in.o + .bss.flags 0x000000002000229c 0x1 ecm_src/lwip-1.4.1/src/core/tcp_in.o + *fill* 0x000000002000229d 0x1 + .bss.tcplen 0x000000002000229e 0x2 ecm_src/lwip-1.4.1/src/core/tcp_in.o + .bss.recv_flags + 0x00000000200022a0 0x1 ecm_src/lwip-1.4.1/src/core/tcp_in.o + *fill* 0x00000000200022a1 0x3 + .bss.recv_data + 0x00000000200022a4 0x4 ecm_src/lwip-1.4.1/src/core/tcp_in.o + .bss.next_timeout + 0x00000000200022a8 0x4 ecm_src/lwip-1.4.1/src/core/timers.o + .bss.timeouts_last_time + 0x00000000200022ac 0x4 ecm_src/lwip-1.4.1/src/core/timers.o + .bss.tcpip_tcp_timer_active + 0x00000000200022b0 0x4 ecm_src/lwip-1.4.1/src/core/timers.o + .bss.ip_id 0x00000000200022b4 0x2 ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + *fill* 0x00000000200022b6 0x2 + .bss.reassdatagrams + 0x00000000200022b8 0x4 ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .bss.ip_reass_pbufcount + 0x00000000200022bc 0x2 ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + *fill* 0x00000000200022be 0x2 + .bss.arp_table + 0x00000000200022c0 0xc8 ecm_src/lwip-1.4.1/src/netif/etharp.o + .bss.etharp_cached_entry + 0x0000000020002388 0x1 ecm_src/lwip-1.4.1/src/netif/etharp.o + *fill* 0x0000000020002389 0x3 + .bss.netif_data + 0x000000002000238c 0x30 ecm_src/src/ecm_main.o + .bss.gateway 0x00000000200023bc 0x4 ecm_src/src/ecm_main.o + .bss.received_frame + 0x00000000200023c0 0x4 ecm_src/src/ecm_main.o + .bss.stmrs 0x00000000200023c4 0x4 ecm_src/src/time.o + .bss.cfgidx.7723 + 0x00000000200023c8 0x1 ecm_src/src/usbd_ctlreq.o + *fill* 0x00000000200023c9 0x3 + .bss.USBD_StrDesc + 0x00000000200023cc 0x100 ecm_src/src/usbd_desc.o + .bss.registered_pdev + 0x00000000200024cc 0x4 ecm_src/src/usbd_ecm.o + .bss.ecm_rx_buffer + 0x00000000200024d0 0x202 ecm_src/src/usbd_ecm.o + *fill* 0x00000000200026d2 0x2 + .bss.ecm_tx_buffer + 0x00000000200026d4 0x202 ecm_src/src/usbd_ecm.o + *fill* 0x00000000200028d6 0x2 + .bss.ecm_rx_index + 0x00000000200028d8 0x4 ecm_src/src/usbd_ecm.o + .bss.can_xmit 0x00000000200028dc 0x1 ecm_src/src/usbd_ecm.o + .bss.OutboundTransferNeedsRenewal + 0x00000000200028dd 0x1 ecm_src/src/usbd_ecm.o + *fill* 0x00000000200028de 0x2 + .bss.ecm_tx_ptr + 0x00000000200028e0 0x4 ecm_src/src/usbd_ecm.o + .bss.ecm_tx_remaining + 0x00000000200028e4 0x4 ecm_src/src/usbd_ecm.o + .bss.ecm_tx_busy + 0x00000000200028e8 0x4 ecm_src/src/usbd_ecm.o + .bss.copy_length + 0x00000000200028ec 0x4 ecm_src/src/usbd_ecm.o + *(COMMON) + COMMON 0x00000000200028f0 0x4 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + 0x00000000200028f0 uwTick + COMMON 0x00000000200028f4 0x204 ecm_src/dhcp-server/dhserver.o + 0x00000000200028f4 dhcp_data + COMMON 0x0000000020002af8 0x654 ecm_src/lwip-1.4.1/src/core/mem.o + 0x0000000020002af8 ram_heap + COMMON 0x000000002000314c 0x8 ecm_src/lwip-1.4.1/src/core/netif.o + 0x000000002000314c netif_list + 0x0000000020003150 netif_default + COMMON 0x0000000020003154 0x1 ecm_src/lwip-1.4.1/src/core/pbuf.o + 0x0000000020003154 pbuf_free_ooseq_pending + *fill* 0x0000000020003155 0x3 + COMMON 0x0000000020003158 0x116 ecm_src/lwip-1.4.1/src/core/stats.o + 0x0000000020003158 lwip_stats + *fill* 0x000000002000326e 0x2 + COMMON 0x0000000020003270 0x1c ecm_src/lwip-1.4.1/src/core/tcp.o + 0x0000000020003270 tcp_active_pcbs_changed + 0x0000000020003274 tcp_active_pcbs + 0x0000000020003278 tcp_ticks + 0x000000002000327c tcp_listen_pcbs + 0x0000000020003280 tcp_tmp_pcb + 0x0000000020003284 tcp_bound_pcbs + 0x0000000020003288 tcp_tw_pcbs + COMMON 0x000000002000328c 0x4 ecm_src/lwip-1.4.1/src/core/tcp_in.o + 0x000000002000328c tcp_input_pcb + COMMON 0x0000000020003290 0x4 ecm_src/lwip-1.4.1/src/core/udp.o + 0x0000000020003290 udp_pcbs + COMMON 0x0000000020003294 0x10 ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + 0x0000000020003294 current_iphdr_src + 0x0000000020003298 current_netif + 0x000000002000329c current_iphdr_dest + 0x00000000200032a0 current_header + COMMON 0x00000000200032a4 0x220 ecm_src/src/usb_device.o + 0x00000000200032a4 hUsbDeviceFS + COMMON 0x00000000200034c4 0x274 ecm_src/src/usbd_conf.o + 0x00000000200034c4 hpcd_USB_FS + 0x0000000020003738 . = ALIGN (0x4) + 0x0000000020003738 _ebss = . + 0x0000000020003738 __bss_end__ = _ebss + +._user_heap_stack + 0x0000000020003738 0x600 load address 0x000000000800ff4c + 0x0000000020003738 . = ALIGN (0x8) + 0x0000000020003738 PROVIDE (end = .) + [!provide] PROVIDE (_end = .) + 0x0000000020003938 . = (. + _Min_Heap_Size) + *fill* 0x0000000020003738 0x200 + 0x0000000020003d38 . = (. + _Min_Stack_Size) + *fill* 0x0000000020003938 0x400 + 0x0000000020003d38 . = ALIGN (0x8) + +/DISCARD/ + libc.a(*) + libm.a(*) + libgcc.a(*) + +.ARM.attributes + 0x0000000000000000 0x28 + *(.ARM.attributes) + .ARM.attributes + 0x0000000000000000 0x1e c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v6-m/crti.o + .ARM.attributes + 0x000000000000001e 0x2c c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v6-m/crtbegin.o + .ARM.attributes + 0x000000000000004a 0x31 Core/Src/main.o + .ARM.attributes + 0x000000000000007b 0x31 Core/Src/stm32f0xx_hal_msp.o + .ARM.attributes + 0x00000000000000ac 0x31 Core/Src/stm32f0xx_it.o + .ARM.attributes + 0x00000000000000dd 0x31 Core/Src/system_stm32f0xx.o + .ARM.attributes + 0x000000000000010e 0x21 Core/Startup/startup_stm32f072c8tx.o + .ARM.attributes + 0x000000000000012f 0x31 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .ARM.attributes + 0x0000000000000160 0x31 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .ARM.attributes + 0x0000000000000191 0x31 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .ARM.attributes + 0x00000000000001c2 0x31 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .ARM.attributes + 0x00000000000001f3 0x31 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .ARM.attributes + 0x0000000000000224 0x31 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .ARM.attributes + 0x0000000000000255 0x31 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .ARM.attributes + 0x0000000000000286 0x31 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .ARM.attributes + 0x00000000000002b7 0x31 ecm_src/dhcp-server/dhserver.o + .ARM.attributes + 0x00000000000002e8 0x31 ecm_src/dns-server/dnserver.o + .ARM.attributes + 0x0000000000000319 0x31 ecm_src/lwip-1.4.1/src/core/def.o + .ARM.attributes + 0x000000000000034a 0x31 ecm_src/lwip-1.4.1/src/core/init.o + .ARM.attributes + 0x000000000000037b 0x31 ecm_src/lwip-1.4.1/src/core/mem.o + .ARM.attributes + 0x00000000000003ac 0x31 ecm_src/lwip-1.4.1/src/core/memp.o + .ARM.attributes + 0x00000000000003dd 0x31 ecm_src/lwip-1.4.1/src/core/netif.o + .ARM.attributes + 0x000000000000040e 0x31 ecm_src/lwip-1.4.1/src/core/pbuf.o + .ARM.attributes + 0x000000000000043f 0x31 ecm_src/lwip-1.4.1/src/core/raw.o + .ARM.attributes + 0x0000000000000470 0x31 ecm_src/lwip-1.4.1/src/core/stats.o + .ARM.attributes + 0x00000000000004a1 0x31 ecm_src/lwip-1.4.1/src/core/tcp.o + .ARM.attributes + 0x00000000000004d2 0x31 ecm_src/lwip-1.4.1/src/core/tcp_in.o + .ARM.attributes + 0x0000000000000503 0x31 ecm_src/lwip-1.4.1/src/core/tcp_out.o + .ARM.attributes + 0x0000000000000534 0x31 ecm_src/lwip-1.4.1/src/core/timers.o + .ARM.attributes + 0x0000000000000565 0x31 ecm_src/lwip-1.4.1/src/core/udp.o + .ARM.attributes + 0x0000000000000596 0x31 ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .ARM.attributes + 0x00000000000005c7 0x31 ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .ARM.attributes + 0x00000000000005f8 0x31 ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .ARM.attributes + 0x0000000000000629 0x31 ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o + .ARM.attributes + 0x000000000000065a 0x31 ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .ARM.attributes + 0x000000000000068b 0x31 ecm_src/lwip-1.4.1/src/netif/etharp.o + .ARM.attributes + 0x00000000000006bc 0x31 ecm_src/src/ecm_main.o + .ARM.attributes + 0x00000000000006ed 0x31 ecm_src/src/time.o + .ARM.attributes + 0x000000000000071e 0x31 ecm_src/src/usb_device.o + .ARM.attributes + 0x000000000000074f 0x31 ecm_src/src/usbd_conf.o + .ARM.attributes + 0x0000000000000780 0x31 ecm_src/src/usbd_core.o + .ARM.attributes + 0x00000000000007b1 0x31 ecm_src/src/usbd_ctlreq.o + .ARM.attributes + 0x00000000000007e2 0x31 ecm_src/src/usbd_desc.o + .ARM.attributes + 0x0000000000000813 0x31 ecm_src/src/usbd_ecm.o + .ARM.attributes + 0x0000000000000844 0x31 ecm_src/src/usbd_ioreq.o + .ARM.attributes + 0x0000000000000875 0x2c c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-init.o) + .ARM.attributes + 0x00000000000008a1 0x2c c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-memcmp.o) + .ARM.attributes + 0x00000000000008cd 0x2c c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-memcpy-stub.o) + .ARM.attributes + 0x00000000000008f9 0x2c c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-memset.o) + .ARM.attributes + 0x0000000000000925 0x1c c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-strcmp.o) + .ARM.attributes + 0x0000000000000941 0x1c c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-strlen.o) + .ARM.attributes + 0x000000000000095d 0x1e c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v6-m\libgcc.a(_udivsi3.o) + .ARM.attributes + 0x000000000000097b 0x1e c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v6-m\libgcc.a(_divsi3.o) + .ARM.attributes + 0x0000000000000999 0x1e c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v6-m\libgcc.a(_dvmd_tls.o) + .ARM.attributes + 0x00000000000009b7 0x1e c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v6-m/crtn.o +OUTPUT(stm32f072_ecm.elf elf32-littlearm) + +.debug_info 0x0000000000000000 0x29068 + .debug_info 0x0000000000000000 0x1a5b Core/Src/main.o + .debug_info 0x0000000000001a5b 0x25e Core/Src/stm32f0xx_hal_msp.o + .debug_info 0x0000000000001cb9 0x667 Core/Src/stm32f0xx_it.o + .debug_info 0x0000000000002320 0x29e Core/Src/system_stm32f0xx.o + .debug_info 0x00000000000025be 0x22 Core/Startup/startup_stm32f072c8tx.o + .debug_info 0x00000000000025e0 0x6c0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .debug_info 0x0000000000002ca0 0x78c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .debug_info 0x000000000000342c 0x67a Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .debug_info 0x0000000000003aa6 0xe67 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .debug_info 0x000000000000490d 0x880 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .debug_info 0x000000000000518d 0x82d Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .debug_info 0x00000000000059ba 0x677 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .debug_info 0x0000000000006031 0x1508 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .debug_info 0x0000000000007539 0x1397 ecm_src/dhcp-server/dhserver.o + .debug_info 0x00000000000088d0 0x1119 ecm_src/dns-server/dnserver.o + .debug_info 0x00000000000099e9 0xfe ecm_src/lwip-1.4.1/src/core/def.o + .debug_info 0x0000000000009ae7 0xc11 ecm_src/lwip-1.4.1/src/core/init.o + .debug_info 0x000000000000a6f8 0xd14 ecm_src/lwip-1.4.1/src/core/mem.o + .debug_info 0x000000000000b40c 0x15e1 ecm_src/lwip-1.4.1/src/core/memp.o + .debug_info 0x000000000000c9ed 0xebb ecm_src/lwip-1.4.1/src/core/netif.o + .debug_info 0x000000000000d8a8 0x1b6d ecm_src/lwip-1.4.1/src/core/pbuf.o + .debug_info 0x000000000000f415 0x10f3 ecm_src/lwip-1.4.1/src/core/raw.o + .debug_info 0x0000000000010508 0xa86 ecm_src/lwip-1.4.1/src/core/stats.o + .debug_info 0x0000000000010f8e 0x1e9c ecm_src/lwip-1.4.1/src/core/tcp.o + .debug_info 0x0000000000012e2a 0xf0b ecm_src/lwip-1.4.1/src/core/tcp_in.o + .debug_info 0x0000000000013d35 0x1b8e ecm_src/lwip-1.4.1/src/core/tcp_out.o + .debug_info 0x00000000000158c3 0xc58 ecm_src/lwip-1.4.1/src/core/timers.o + .debug_info 0x000000000001651b 0x1355 ecm_src/lwip-1.4.1/src/core/udp.o + .debug_info 0x0000000000017870 0xfe5 ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .debug_info 0x0000000000018855 0xbdb ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .debug_info 0x0000000000019430 0x1738 ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .debug_info 0x000000000001ab68 0x565 ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o + .debug_info 0x000000000001b0cd 0x1404 ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .debug_info 0x000000000001c4d1 0x1688 ecm_src/lwip-1.4.1/src/netif/etharp.o + .debug_info 0x000000000001db59 0x1b7d ecm_src/src/ecm_main.o + .debug_info 0x000000000001f6d6 0x382 ecm_src/src/time.o + .debug_info 0x000000000001fa58 0x1797 ecm_src/src/usb_device.o + .debug_info 0x00000000000211ef 0x1e14 ecm_src/src/usbd_conf.o + .debug_info 0x0000000000023003 0x1138 ecm_src/src/usbd_core.o + .debug_info 0x000000000002413b 0x10c4 ecm_src/src/usbd_ctlreq.o + .debug_info 0x00000000000251ff 0x1640 ecm_src/src/usbd_desc.o + .debug_info 0x000000000002683f 0x1965 ecm_src/src/usbd_ecm.o + .debug_info 0x00000000000281a4 0xec4 ecm_src/src/usbd_ioreq.o + +.debug_abbrev 0x0000000000000000 0x5bb1 + .debug_abbrev 0x0000000000000000 0x235 Core/Src/main.o + .debug_abbrev 0x0000000000000235 0x109 Core/Src/stm32f0xx_hal_msp.o + .debug_abbrev 0x000000000000033e 0x155 Core/Src/stm32f0xx_it.o + .debug_abbrev 0x0000000000000493 0x12b Core/Src/system_stm32f0xx.o + .debug_abbrev 0x00000000000005be 0x12 Core/Startup/startup_stm32f072c8tx.o + .debug_abbrev 0x00000000000005d0 0x1c7 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .debug_abbrev 0x0000000000000797 0x273 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .debug_abbrev 0x0000000000000a0a 0x1c0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .debug_abbrev 0x0000000000000bca 0x27d Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .debug_abbrev 0x0000000000000e47 0x1eb Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .debug_abbrev 0x0000000000001032 0x20f Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .debug_abbrev 0x0000000000001241 0x1a7 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .debug_abbrev 0x00000000000013e8 0x239 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .debug_abbrev 0x0000000000001621 0x2d0 ecm_src/dhcp-server/dhserver.o + .debug_abbrev 0x00000000000018f1 0x26e ecm_src/dns-server/dnserver.o + .debug_abbrev 0x0000000000001b5f 0x90 ecm_src/lwip-1.4.1/src/core/def.o + .debug_abbrev 0x0000000000001bef 0x155 ecm_src/lwip-1.4.1/src/core/init.o + .debug_abbrev 0x0000000000001d44 0x284 ecm_src/lwip-1.4.1/src/core/mem.o + .debug_abbrev 0x0000000000001fc8 0x24e ecm_src/lwip-1.4.1/src/core/memp.o + .debug_abbrev 0x0000000000002216 0x272 ecm_src/lwip-1.4.1/src/core/netif.o + .debug_abbrev 0x0000000000002488 0x2e6 ecm_src/lwip-1.4.1/src/core/pbuf.o + .debug_abbrev 0x000000000000276e 0x27d ecm_src/lwip-1.4.1/src/core/raw.o + .debug_abbrev 0x00000000000029eb 0x19b ecm_src/lwip-1.4.1/src/core/stats.o + .debug_abbrev 0x0000000000002b86 0x365 ecm_src/lwip-1.4.1/src/core/tcp.o + .debug_abbrev 0x0000000000002eeb 0x23a ecm_src/lwip-1.4.1/src/core/tcp_in.o + .debug_abbrev 0x0000000000003125 0x305 ecm_src/lwip-1.4.1/src/core/tcp_out.o + .debug_abbrev 0x000000000000342a 0x225 ecm_src/lwip-1.4.1/src/core/timers.o + .debug_abbrev 0x000000000000364f 0x2c5 ecm_src/lwip-1.4.1/src/core/udp.o + .debug_abbrev 0x0000000000003914 0x26d ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .debug_abbrev 0x0000000000003b81 0x202 ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .debug_abbrev 0x0000000000003d83 0x24e ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .debug_abbrev 0x0000000000003fd1 0x193 ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o + .debug_abbrev 0x0000000000004164 0x2b6 ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .debug_abbrev 0x000000000000441a 0x2b4 ecm_src/lwip-1.4.1/src/netif/etharp.o + .debug_abbrev 0x00000000000046ce 0x2c1 ecm_src/src/ecm_main.o + .debug_abbrev 0x000000000000498f 0x188 ecm_src/src/time.o + .debug_abbrev 0x0000000000004b17 0x1d5 ecm_src/src/usb_device.o + .debug_abbrev 0x0000000000004cec 0x2bb ecm_src/src/usbd_conf.o + .debug_abbrev 0x0000000000004fa7 0x261 ecm_src/src/usbd_core.o + .debug_abbrev 0x0000000000005208 0x291 ecm_src/src/usbd_ctlreq.o + .debug_abbrev 0x0000000000005499 0x23c ecm_src/src/usbd_desc.o + .debug_abbrev 0x00000000000056d5 0x30b ecm_src/src/usbd_ecm.o + .debug_abbrev 0x00000000000059e0 0x1d1 ecm_src/src/usbd_ioreq.o + +.debug_aranges 0x0000000000000000 0x12c8 + .debug_aranges + 0x0000000000000000 0x38 Core/Src/main.o + .debug_aranges + 0x0000000000000038 0x20 Core/Src/stm32f0xx_hal_msp.o + .debug_aranges + 0x0000000000000058 0x48 Core/Src/stm32f0xx_it.o + .debug_aranges + 0x00000000000000a0 0x28 Core/Src/system_stm32f0xx.o + .debug_aranges + 0x00000000000000c8 0x28 Core/Startup/startup_stm32f072c8tx.o + .debug_aranges + 0x00000000000000f0 0xd0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .debug_aranges + 0x00000000000001c0 0xc0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .debug_aranges + 0x0000000000000280 0x58 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .debug_aranges + 0x00000000000002d8 0x120 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .debug_aranges + 0x00000000000003f8 0x58 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .debug_aranges + 0x0000000000000450 0x80 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .debug_aranges + 0x00000000000004d0 0x78 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .debug_aranges + 0x0000000000000548 0x108 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .debug_aranges + 0x0000000000000650 0x78 ecm_src/dhcp-server/dhserver.o + .debug_aranges + 0x00000000000006c8 0x40 ecm_src/dns-server/dnserver.o + .debug_aranges + 0x0000000000000708 0x38 ecm_src/lwip-1.4.1/src/core/def.o + .debug_aranges + 0x0000000000000740 0x20 ecm_src/lwip-1.4.1/src/core/init.o + .debug_aranges + 0x0000000000000760 0x48 ecm_src/lwip-1.4.1/src/core/mem.o + .debug_aranges + 0x00000000000007a8 0x30 ecm_src/lwip-1.4.1/src/core/memp.o + .debug_aranges + 0x00000000000007d8 0x80 ecm_src/lwip-1.4.1/src/core/netif.o + .debug_aranges + 0x0000000000000858 0xb8 ecm_src/lwip-1.4.1/src/core/pbuf.o + .debug_aranges + 0x0000000000000910 0x58 ecm_src/lwip-1.4.1/src/core/raw.o + .debug_aranges + 0x0000000000000968 0x20 ecm_src/lwip-1.4.1/src/core/stats.o + .debug_aranges + 0x0000000000000988 0x140 ecm_src/lwip-1.4.1/src/core/tcp.o + .debug_aranges + 0x0000000000000ac8 0x50 ecm_src/lwip-1.4.1/src/core/tcp_in.o + .debug_aranges + 0x0000000000000b18 0x98 ecm_src/lwip-1.4.1/src/core/tcp_out.o + .debug_aranges + 0x0000000000000bb0 0x60 ecm_src/lwip-1.4.1/src/core/timers.o + .debug_aranges + 0x0000000000000c10 0x78 ecm_src/lwip-1.4.1/src/core/udp.o + .debug_aranges + 0x0000000000000c88 0x38 ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .debug_aranges + 0x0000000000000cc0 0x40 ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .debug_aranges + 0x0000000000000d00 0x38 ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .debug_aranges + 0x0000000000000d38 0x48 ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o + .debug_aranges + 0x0000000000000d80 0x70 ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .debug_aranges + 0x0000000000000df0 0x98 ecm_src/lwip-1.4.1/src/netif/etharp.o + .debug_aranges + 0x0000000000000e88 0x70 ecm_src/src/ecm_main.o + .debug_aranges + 0x0000000000000ef8 0x60 ecm_src/src/time.o + .debug_aranges + 0x0000000000000f58 0x20 ecm_src/src/usb_device.o + .debug_aranges + 0x0000000000000f78 0xf8 ecm_src/src/usbd_conf.o + .debug_aranges + 0x0000000000001070 0xb0 ecm_src/src/usbd_core.o + .debug_aranges + 0x0000000000001120 0x88 ecm_src/src/usbd_ctlreq.o + .debug_aranges + 0x00000000000011a8 0x48 ecm_src/src/usbd_desc.o + .debug_aranges + 0x00000000000011f0 0x88 ecm_src/src/usbd_ecm.o + .debug_aranges + 0x0000000000001278 0x50 ecm_src/src/usbd_ioreq.o + +.debug_ranges 0x0000000000000000 0x10e0 + .debug_ranges 0x0000000000000000 0x28 Core/Src/main.o + .debug_ranges 0x0000000000000028 0x10 Core/Src/stm32f0xx_hal_msp.o + .debug_ranges 0x0000000000000038 0x38 Core/Src/stm32f0xx_it.o + .debug_ranges 0x0000000000000070 0x18 Core/Src/system_stm32f0xx.o + .debug_ranges 0x0000000000000088 0x20 Core/Startup/startup_stm32f072c8tx.o + .debug_ranges 0x00000000000000a8 0xc0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .debug_ranges 0x0000000000000168 0xb0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .debug_ranges 0x0000000000000218 0x48 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .debug_ranges 0x0000000000000260 0x110 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .debug_ranges 0x0000000000000370 0x48 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .debug_ranges 0x00000000000003b8 0x70 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .debug_ranges 0x0000000000000428 0x68 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .debug_ranges 0x0000000000000490 0xf8 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .debug_ranges 0x0000000000000588 0x68 ecm_src/dhcp-server/dhserver.o + .debug_ranges 0x00000000000005f0 0x48 ecm_src/dns-server/dnserver.o + .debug_ranges 0x0000000000000638 0x28 ecm_src/lwip-1.4.1/src/core/def.o + .debug_ranges 0x0000000000000660 0x10 ecm_src/lwip-1.4.1/src/core/init.o + .debug_ranges 0x0000000000000670 0x38 ecm_src/lwip-1.4.1/src/core/mem.o + .debug_ranges 0x00000000000006a8 0x20 ecm_src/lwip-1.4.1/src/core/memp.o + .debug_ranges 0x00000000000006c8 0x88 ecm_src/lwip-1.4.1/src/core/netif.o + .debug_ranges 0x0000000000000750 0xa8 ecm_src/lwip-1.4.1/src/core/pbuf.o + .debug_ranges 0x00000000000007f8 0x48 ecm_src/lwip-1.4.1/src/core/raw.o + .debug_ranges 0x0000000000000840 0x10 ecm_src/lwip-1.4.1/src/core/stats.o + .debug_ranges 0x0000000000000850 0x130 ecm_src/lwip-1.4.1/src/core/tcp.o + .debug_ranges 0x0000000000000980 0x40 ecm_src/lwip-1.4.1/src/core/tcp_in.o + .debug_ranges 0x00000000000009c0 0xe8 ecm_src/lwip-1.4.1/src/core/tcp_out.o + .debug_ranges 0x0000000000000aa8 0x50 ecm_src/lwip-1.4.1/src/core/timers.o + .debug_ranges 0x0000000000000af8 0x68 ecm_src/lwip-1.4.1/src/core/udp.o + .debug_ranges 0x0000000000000b60 0x40 ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .debug_ranges 0x0000000000000ba0 0x30 ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .debug_ranges 0x0000000000000bd0 0x28 ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .debug_ranges 0x0000000000000bf8 0x38 ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o + .debug_ranges 0x0000000000000c30 0x60 ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .debug_ranges 0x0000000000000c90 0x88 ecm_src/lwip-1.4.1/src/netif/etharp.o + .debug_ranges 0x0000000000000d18 0x60 ecm_src/src/ecm_main.o + .debug_ranges 0x0000000000000d78 0x68 ecm_src/src/time.o + .debug_ranges 0x0000000000000de0 0x10 ecm_src/src/usb_device.o + .debug_ranges 0x0000000000000df0 0xe8 ecm_src/src/usbd_conf.o + .debug_ranges 0x0000000000000ed8 0xa0 ecm_src/src/usbd_core.o + .debug_ranges 0x0000000000000f78 0x78 ecm_src/src/usbd_ctlreq.o + .debug_ranges 0x0000000000000ff0 0x38 ecm_src/src/usbd_desc.o + .debug_ranges 0x0000000000001028 0x78 ecm_src/src/usbd_ecm.o + .debug_ranges 0x00000000000010a0 0x40 ecm_src/src/usbd_ioreq.o + +.debug_macro 0x0000000000000000 0x1cd20 + .debug_macro 0x0000000000000000 0x53f Core/Src/main.o + .debug_macro 0x000000000000053f 0xa48 Core/Src/main.o + .debug_macro 0x0000000000000f87 0x12d Core/Src/main.o + .debug_macro 0x00000000000010b4 0x2e Core/Src/main.o + .debug_macro 0x00000000000010e2 0x22 Core/Src/main.o + .debug_macro 0x0000000000001104 0x22 Core/Src/main.o + .debug_macro 0x0000000000001126 0x8e Core/Src/main.o + .debug_macro 0x00000000000011b4 0x51 Core/Src/main.o + .debug_macro 0x0000000000001205 0xef Core/Src/main.o + .debug_macro 0x00000000000012f4 0x6a Core/Src/main.o + .debug_macro 0x000000000000135e 0x1df Core/Src/main.o + .debug_macro 0x000000000000153d 0x1c Core/Src/main.o + .debug_macro 0x0000000000001559 0x22 Core/Src/main.o + .debug_macro 0x000000000000157b 0xb5 Core/Src/main.o + .debug_macro 0x0000000000001630 0x391 Core/Src/main.o + .debug_macro 0x00000000000019c1 0xfe50 Core/Src/main.o + .debug_macro 0x0000000000011811 0x3c Core/Src/main.o + .debug_macro 0x000000000001184d 0x174 Core/Src/main.o + .debug_macro 0x00000000000119c1 0x53 Core/Src/main.o + .debug_macro 0x0000000000011a14 0x946 Core/Src/main.o + .debug_macro 0x000000000001235a 0x5f3 Core/Src/main.o + .debug_macro 0x000000000001294d 0x12f Core/Src/main.o + .debug_macro 0x0000000000012a7c 0x1a7 Core/Src/main.o + .debug_macro 0x0000000000012c23 0x1a7 Core/Src/main.o + .debug_macro 0x0000000000012dca 0x22c Core/Src/main.o + .debug_macro 0x0000000000012ff6 0x34 Core/Src/main.o + .debug_macro 0x000000000001302a 0x43 Core/Src/main.o + .debug_macro 0x000000000001306d 0x28 Core/Src/main.o + .debug_macro 0x0000000000013095 0xb0 Core/Src/main.o + .debug_macro 0x0000000000013145 0x217 Core/Src/main.o + .debug_macro 0x000000000001335c 0x22c Core/Src/main.o + .debug_macro 0x0000000000013588 0x5f Core/Src/main.o + .debug_macro 0x00000000000135e7 0xa5 Core/Src/main.o + .debug_macro 0x000000000001368c 0x65 Core/Src/main.o + .debug_macro 0x00000000000136f1 0x234 Core/Src/main.o + .debug_macro 0x0000000000013925 0x4c Core/Src/main.o + .debug_macro 0x0000000000013971 0x16d Core/Src/main.o + .debug_macro 0x0000000000013ade 0x130 Core/Src/main.o + .debug_macro 0x0000000000013c0e 0x46 Core/Src/main.o + .debug_macro 0x0000000000013c54 0x18 Core/Src/main.o + .debug_macro 0x0000000000013c6c 0x3c Core/Src/main.o + .debug_macro 0x0000000000013ca8 0x34 Core/Src/main.o + .debug_macro 0x0000000000013cdc 0x16 Core/Src/main.o + .debug_macro 0x0000000000013cf2 0x35 Core/Src/main.o + .debug_macro 0x0000000000013d27 0x32a Core/Src/main.o + .debug_macro 0x0000000000014051 0x10 Core/Src/main.o + .debug_macro 0x0000000000014061 0x52 Core/Src/main.o + .debug_macro 0x00000000000140b3 0x1f Core/Src/main.o + .debug_macro 0x00000000000140d2 0x43 Core/Src/main.o + .debug_macro 0x0000000000014115 0x20 Core/Src/main.o + .debug_macro 0x0000000000014135 0x1a3 Core/Src/main.o + .debug_macro 0x00000000000142d8 0x10 Core/Src/main.o + .debug_macro 0x00000000000142e8 0x1c Core/Src/main.o + .debug_macro 0x0000000000014304 0x52 Core/Src/main.o + .debug_macro 0x0000000000014356 0x40 Core/Src/main.o + .debug_macro 0x0000000000014396 0x10 Core/Src/main.o + .debug_macro 0x00000000000143a6 0x40 Core/Src/main.o + .debug_macro 0x00000000000143e6 0xd7 Core/Src/main.o + .debug_macro 0x00000000000144bd 0x1c Core/Src/main.o + .debug_macro 0x00000000000144d9 0x3d Core/Src/main.o + .debug_macro 0x0000000000014516 0x16 Core/Src/main.o + .debug_macro 0x000000000001452c 0x145 Core/Src/main.o + .debug_macro 0x0000000000014671 0x16 Core/Src/main.o + .debug_macro 0x0000000000014687 0x16 Core/Src/main.o + .debug_macro 0x000000000001469d 0x29 Core/Src/main.o + .debug_macro 0x00000000000146c6 0x16 Core/Src/main.o + .debug_macro 0x00000000000146dc 0x20 Core/Src/main.o + .debug_macro 0x00000000000146fc 0x64 Core/Src/main.o + .debug_macro 0x0000000000014760 0x1a6 Core/Src/main.o + .debug_macro 0x0000000000014906 0x22 Core/Src/main.o + .debug_macro 0x0000000000014928 0x70 Core/Src/main.o + .debug_macro 0x0000000000014998 0x16 Core/Src/main.o + .debug_macro 0x00000000000149ae 0x22 Core/Src/main.o + .debug_macro 0x00000000000149d0 0x16 Core/Src/main.o + .debug_macro 0x00000000000149e6 0x5e Core/Src/main.o + .debug_macro 0x0000000000014a44 0x592 Core/Src/main.o + .debug_macro 0x0000000000014fd6 0x76 Core/Src/main.o + .debug_macro 0x000000000001504c 0x4f Core/Src/main.o + .debug_macro 0x000000000001509b 0x52 Core/Src/main.o + .debug_macro 0x00000000000150ed 0x175 Core/Src/main.o + .debug_macro 0x0000000000015262 0x62 Core/Src/main.o + .debug_macro 0x00000000000152c4 0x13b Core/Src/main.o + .debug_macro 0x00000000000153ff 0x80 Core/Src/main.o + .debug_macro 0x000000000001547f 0x10 Core/Src/main.o + .debug_macro 0x000000000001548f 0x10 Core/Src/main.o + .debug_macro 0x000000000001549f 0x10 Core/Src/main.o + .debug_macro 0x00000000000154af 0x46 Core/Src/main.o + .debug_macro 0x00000000000154f5 0x64 Core/Src/main.o + .debug_macro 0x0000000000015559 0x3d Core/Src/main.o + .debug_macro 0x0000000000015596 0xdc Core/Src/main.o + .debug_macro 0x0000000000015672 0x22 Core/Src/main.o + .debug_macro 0x0000000000015694 0xac Core/Src/main.o + .debug_macro 0x0000000000015740 0x1be Core/Src/main.o + .debug_macro 0x00000000000158fe 0x10 Core/Src/main.o + .debug_macro 0x000000000001590e 0x10 Core/Src/main.o + .debug_macro 0x000000000001591e 0x1bf Core/Src/stm32f0xx_hal_msp.o + .debug_macro 0x0000000000015add 0x1c9 Core/Src/stm32f0xx_it.o + .debug_macro 0x0000000000015ca6 0x1b5 Core/Src/system_stm32f0xx.o + .debug_macro 0x0000000000015e5b 0x1d9 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .debug_macro 0x0000000000016034 0x1b5 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .debug_macro 0x00000000000161e9 0x1ed Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .debug_macro 0x00000000000163d6 0x1c1 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .debug_macro 0x0000000000016597 0x1b5 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .debug_macro 0x000000000001674c 0x1c7 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .debug_macro 0x0000000000016913 0x1c7 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .debug_macro 0x0000000000016ada 0x1b5 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .debug_macro 0x0000000000016c8f 0x2e2 ecm_src/dhcp-server/dhserver.o + .debug_macro 0x0000000000016f71 0x97 ecm_src/dhcp-server/dhserver.o + .debug_macro 0x0000000000017008 0xfd ecm_src/dhcp-server/dhserver.o + .debug_macro 0x0000000000017105 0x70 ecm_src/dhcp-server/dhserver.o + .debug_macro 0x0000000000017175 0x55 ecm_src/dhcp-server/dhserver.o + .debug_macro 0x00000000000171ca 0x10 ecm_src/dhcp-server/dhserver.o + .debug_macro 0x00000000000171da 0x56 ecm_src/dhcp-server/dhserver.o + .debug_macro 0x0000000000017230 0x37 ecm_src/dhcp-server/dhserver.o + .debug_macro 0x0000000000017267 0x86 ecm_src/dhcp-server/dhserver.o + .debug_macro 0x00000000000172ed 0x2b2 ecm_src/dns-server/dnserver.o + .debug_macro 0x000000000001759f 0x4c ecm_src/dns-server/dnserver.o + .debug_macro 0x00000000000175eb 0x17b ecm_src/dns-server/dnserver.o + .debug_macro 0x0000000000017766 0x6b ecm_src/lwip-1.4.1/src/core/def.o + .debug_macro 0x00000000000177d1 0x16 ecm_src/lwip-1.4.1/src/core/def.o + .debug_macro 0x00000000000177e7 0x10 ecm_src/lwip-1.4.1/src/core/def.o + .debug_macro 0x00000000000177f7 0x58 ecm_src/lwip-1.4.1/src/core/def.o + .debug_macro 0x000000000001784f 0x18d ecm_src/lwip-1.4.1/src/core/init.o + .debug_macro 0x00000000000179dc 0x10 ecm_src/lwip-1.4.1/src/core/init.o + .debug_macro 0x00000000000179ec 0x3a ecm_src/lwip-1.4.1/src/core/init.o + .debug_macro 0x0000000000017a26 0x127 ecm_src/lwip-1.4.1/src/core/init.o + .debug_macro 0x0000000000017b4d 0xc5 ecm_src/lwip-1.4.1/src/core/init.o + .debug_macro 0x0000000000017c12 0x10 ecm_src/lwip-1.4.1/src/core/init.o + .debug_macro 0x0000000000017c22 0x321 ecm_src/lwip-1.4.1/src/core/init.o + .debug_macro 0x0000000000017f43 0x16 ecm_src/lwip-1.4.1/src/core/init.o + .debug_macro 0x0000000000017f59 0x1db ecm_src/lwip-1.4.1/src/core/mem.o + .debug_macro 0x0000000000018134 0x10 ecm_src/lwip-1.4.1/src/core/mem.o + .debug_macro 0x0000000000018144 0x2af ecm_src/lwip-1.4.1/src/core/memp.o + .debug_macro 0x00000000000183f3 0x12d ecm_src/lwip-1.4.1/src/core/memp.o + .debug_macro 0x0000000000018520 0x10 ecm_src/lwip-1.4.1/src/core/memp.o + .debug_macro 0x0000000000018530 0x116 ecm_src/lwip-1.4.1/src/core/netif.o + .debug_macro 0x0000000000018646 0x200 ecm_src/lwip-1.4.1/src/core/pbuf.o + .debug_macro 0x0000000000018846 0x16 ecm_src/lwip-1.4.1/src/core/pbuf.o + .debug_macro 0x000000000001885c 0x135 ecm_src/lwip-1.4.1/src/core/pbuf.o + .debug_macro 0x0000000000018991 0x1c7 ecm_src/lwip-1.4.1/src/core/raw.o + .debug_macro 0x0000000000018b58 0x17c ecm_src/lwip-1.4.1/src/core/stats.o + .debug_macro 0x0000000000018cd4 0x209 ecm_src/lwip-1.4.1/src/core/tcp.o + .debug_macro 0x0000000000018edd 0x31b ecm_src/lwip-1.4.1/src/core/tcp.o + .debug_macro 0x00000000000191f8 0x1c4 ecm_src/lwip-1.4.1/src/core/tcp.o + .debug_macro 0x00000000000193bc 0x10a ecm_src/lwip-1.4.1/src/core/tcp_in.o + .debug_macro 0x00000000000194c6 0x1c ecm_src/lwip-1.4.1/src/core/tcp_in.o + .debug_macro 0x00000000000194e2 0x1fa ecm_src/lwip-1.4.1/src/core/tcp_out.o + .debug_macro 0x00000000000196dc 0x13c ecm_src/lwip-1.4.1/src/core/timers.o + .debug_macro 0x0000000000019818 0x10 ecm_src/lwip-1.4.1/src/core/timers.o + .debug_macro 0x0000000000019828 0x209 ecm_src/lwip-1.4.1/src/core/udp.o + .debug_macro 0x0000000000019a31 0x1e2 ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .debug_macro 0x0000000000019c13 0x5e ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .debug_macro 0x0000000000019c71 0x198 ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .debug_macro 0x0000000000019e09 0x16 ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .debug_macro 0x0000000000019e1f 0x242 ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .debug_macro 0x000000000001a061 0xb2 ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .debug_macro 0x000000000001a113 0xbe ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o + .debug_macro 0x000000000001a1d1 0x1f7 ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .debug_macro 0x000000000001a3c8 0x22e ecm_src/lwip-1.4.1/src/netif/etharp.o + .debug_macro 0x000000000001a5f6 0x545 ecm_src/src/ecm_main.o + .debug_macro 0x000000000001ab3b 0x1d1 ecm_src/src/time.o + .debug_macro 0x000000000001ad0c 0x53f ecm_src/src/usb_device.o + .debug_macro 0x000000000001b24b 0x492 ecm_src/src/usbd_conf.o + .debug_macro 0x000000000001b6dd 0x1ac ecm_src/src/usbd_conf.o + .debug_macro 0x000000000001b889 0x3b9 ecm_src/src/usbd_core.o + .debug_macro 0x000000000001bc42 0x3bf ecm_src/src/usbd_ctlreq.o + .debug_macro 0x000000000001c001 0x4ae ecm_src/src/usbd_desc.o + .debug_macro 0x000000000001c4af 0x16 ecm_src/src/usbd_desc.o + .debug_macro 0x000000000001c4c5 0x49c ecm_src/src/usbd_ecm.o + .debug_macro 0x000000000001c961 0x3bf ecm_src/src/usbd_ioreq.o + +.debug_line 0x0000000000000000 0x169ee + .debug_line 0x0000000000000000 0xc83 Core/Src/main.o + .debug_line 0x0000000000000c83 0x67f Core/Src/stm32f0xx_hal_msp.o + .debug_line 0x0000000000001302 0x6e5 Core/Src/stm32f0xx_it.o + .debug_line 0x00000000000019e7 0x6a2 Core/Src/system_stm32f0xx.o + .debug_line 0x0000000000002089 0x89 Core/Startup/startup_stm32f072c8tx.o + .debug_line 0x0000000000002112 0x835 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .debug_line 0x0000000000002947 0x84d Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .debug_line 0x0000000000003194 0x80f Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .debug_line 0x00000000000039a3 0xb2b Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .debug_line 0x00000000000044ce 0x746 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .debug_line 0x0000000000004c14 0x922 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .debug_line 0x0000000000005536 0x8ce Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .debug_line 0x0000000000005e04 0xb64 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .debug_line 0x0000000000006968 0x93a ecm_src/dhcp-server/dhserver.o + .debug_line 0x00000000000072a2 0x845 ecm_src/dns-server/dnserver.o + .debug_line 0x0000000000007ae7 0x195 ecm_src/lwip-1.4.1/src/core/def.o + .debug_line 0x0000000000007c7c 0x2fa ecm_src/lwip-1.4.1/src/core/init.o + .debug_line 0x0000000000007f76 0x733 ecm_src/lwip-1.4.1/src/core/mem.o + .debug_line 0x00000000000086a9 0x802 ecm_src/lwip-1.4.1/src/core/memp.o + .debug_line 0x0000000000008eab 0x43d ecm_src/lwip-1.4.1/src/core/netif.o + .debug_line 0x00000000000092e8 0xa5d ecm_src/lwip-1.4.1/src/core/pbuf.o + .debug_line 0x0000000000009d45 0x79a ecm_src/lwip-1.4.1/src/core/raw.o + .debug_line 0x000000000000a4df 0x5f4 ecm_src/lwip-1.4.1/src/core/stats.o + .debug_line 0x000000000000aad3 0xcbe ecm_src/lwip-1.4.1/src/core/tcp.o + .debug_line 0x000000000000b791 0x87e ecm_src/lwip-1.4.1/src/core/tcp_in.o + .debug_line 0x000000000000c00f 0xb26 ecm_src/lwip-1.4.1/src/core/tcp_out.o + .debug_line 0x000000000000cb35 0x3d1 ecm_src/lwip-1.4.1/src/core/timers.o + .debug_line 0x000000000000cf06 0x921 ecm_src/lwip-1.4.1/src/core/udp.o + .debug_line 0x000000000000d827 0x73c ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .debug_line 0x000000000000df63 0x70e ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .debug_line 0x000000000000e671 0x827 ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .debug_line 0x000000000000ee98 0x348 ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o + .debug_line 0x000000000000f1e0 0x8eb ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .debug_line 0x000000000000facb 0xa19 ecm_src/lwip-1.4.1/src/netif/etharp.o + .debug_line 0x00000000000104e4 0xd46 ecm_src/src/ecm_main.o + .debug_line 0x000000000001122a 0x755 ecm_src/src/time.o + .debug_line 0x000000000001197f 0xc34 ecm_src/src/usb_device.o + .debug_line 0x00000000000125b3 0xcec ecm_src/src/usbd_conf.o + .debug_line 0x000000000001329f 0xacd ecm_src/src/usbd_core.o + .debug_line 0x0000000000013d6c 0xb18 ecm_src/src/usbd_ctlreq.o + .debug_line 0x0000000000014884 0xb75 ecm_src/src/usbd_desc.o + .debug_line 0x00000000000153f9 0xc76 ecm_src/src/usbd_ecm.o + .debug_line 0x000000000001606f 0x97f ecm_src/src/usbd_ioreq.o + +.debug_str 0x0000000000000000 0x82af5 + .debug_str 0x0000000000000000 0x7bb47 Core/Src/main.o + 0x7bff0 (size before relaxing) + .debug_str 0x000000000007bb47 0x2c Core/Src/stm32f0xx_hal_msp.o + 0x70cc6 (size before relaxing) + .debug_str 0x000000000007bb73 0x3ce Core/Src/stm32f0xx_it.o + 0x7105a (size before relaxing) + .debug_str 0x000000000007bf41 0x5f Core/Src/system_stm32f0xx.o + 0x70ce8 (size before relaxing) + .debug_str 0x000000000007bfa0 0x36 Core/Startup/startup_stm32f072c8tx.o + 0x69 (size before relaxing) + .debug_str 0x000000000007bfd6 0x4f1 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + 0x71256 (size before relaxing) + .debug_str 0x000000000007c4c7 0x1e8 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + 0x7110a (size before relaxing) + .debug_str 0x000000000007c6af 0x281 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + 0x70f84 (size before relaxing) + .debug_str 0x000000000007c930 0x3c3 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + 0x713cf (size before relaxing) + .debug_str 0x000000000007ccf3 0x1c6 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + 0x711f8 (size before relaxing) + .debug_str 0x000000000007ceb9 0x254 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + 0x710fd (size before relaxing) + .debug_str 0x000000000007d10d 0x2f6 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + 0x710da (size before relaxing) + .debug_str 0x000000000007d403 0x30f Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + 0x711de (size before relaxing) + .debug_str 0x000000000007d712 0x49a ecm_src/dhcp-server/dhserver.o + 0xbbcf (size before relaxing) + .debug_str 0x000000000007dbac 0x112 ecm_src/dns-server/dnserver.o + 0xb8c7 (size before relaxing) + .debug_str 0x000000000007dcbe 0x64 ecm_src/lwip-1.4.1/src/core/def.o + 0x47cf (size before relaxing) + .debug_str 0x000000000007dd22 0x1bbe ecm_src/lwip-1.4.1/src/core/init.o + 0x9bdc (size before relaxing) + .debug_str 0x000000000007f8e0 0x2e6 ecm_src/lwip-1.4.1/src/core/mem.o + 0x90b2 (size before relaxing) + .debug_str 0x000000000007fbc6 0x1d2 ecm_src/lwip-1.4.1/src/core/memp.o + 0xd1e8 (size before relaxing) + .debug_str 0x000000000007fd98 0x152 ecm_src/lwip-1.4.1/src/core/netif.o + 0x94d3 (size before relaxing) + .debug_str 0x000000000007feea 0x333 ecm_src/lwip-1.4.1/src/core/pbuf.o + 0xc2c2 (size before relaxing) + .debug_str 0x000000000008021d 0xbf ecm_src/lwip-1.4.1/src/core/raw.o + 0xa262 (size before relaxing) + .debug_str 0x00000000000802dc 0x45 ecm_src/lwip-1.4.1/src/core/stats.o + 0x88e6 (size before relaxing) + .debug_str 0x0000000000080321 0x4a1 ecm_src/lwip-1.4.1/src/core/tcp.o + 0xcbfc (size before relaxing) + .debug_str 0x00000000000807c2 0x1f3 ecm_src/lwip-1.4.1/src/core/tcp_in.o + 0x9306 (size before relaxing) + .debug_str 0x00000000000809b5 0x280 ecm_src/lwip-1.4.1/src/core/tcp_out.o + 0xcad6 (size before relaxing) + .debug_str 0x0000000000080c35 0x154 ecm_src/lwip-1.4.1/src/core/timers.o + 0x8633 (size before relaxing) + .debug_str 0x0000000000080d89 0x218 ecm_src/lwip-1.4.1/src/core/udp.o + 0xb345 (size before relaxing) + .debug_str 0x0000000000080fa1 0x10f ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + 0xb079 (size before relaxing) + .debug_str 0x00000000000810b0 0xed ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + 0x8eb0 (size before relaxing) + .debug_str 0x000000000008119d 0x14a ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + 0xcb20 (size before relaxing) + .debug_str 0x00000000000812e7 0x1f3 ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o + 0x5b5b (size before relaxing) + .debug_str 0x00000000000814da 0x377 ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + 0xb3b4 (size before relaxing) + .debug_str 0x0000000000081851 0x49a ecm_src/lwip-1.4.1/src/netif/etharp.o + 0xb533 (size before relaxing) + .debug_str 0x0000000000081ceb 0x131 ecm_src/src/ecm_main.o + 0x7bf71 (size before relaxing) + .debug_str 0x0000000000081e1c 0x9f ecm_src/src/time.o + 0x70e1b (size before relaxing) + .debug_str 0x0000000000081ebb 0x6b ecm_src/src/usb_device.o + 0x7bdd4 (size before relaxing) + .debug_str 0x0000000000081f26 0x192 ecm_src/src/usbd_conf.o + 0x7a216 (size before relaxing) + .debug_str 0x00000000000820b8 0x186 ecm_src/src/usbd_core.o + 0x75c15 (size before relaxing) + .debug_str 0x000000000008223e 0x114 ecm_src/src/usbd_ctlreq.o + 0x75bac (size before relaxing) + .debug_str 0x0000000000082352 0x501 ecm_src/src/usbd_desc.o + 0x79e0b (size before relaxing) + .debug_str 0x0000000000082853 0x1eb ecm_src/src/usbd_ecm.o + 0x79ee0 (size before relaxing) + .debug_str 0x0000000000082a3e 0xb7 ecm_src/src/usbd_ioreq.o + 0x75b34 (size before relaxing) + +.comment 0x0000000000000000 0x7b + .comment 0x0000000000000000 0x7b Core/Src/main.o + 0x7c (size before relaxing) + .comment 0x000000000000007b 0x7c Core/Src/stm32f0xx_hal_msp.o + .comment 0x000000000000007b 0x7c Core/Src/stm32f0xx_it.o + .comment 0x000000000000007b 0x7c Core/Src/system_stm32f0xx.o + .comment 0x000000000000007b 0x7c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .comment 0x000000000000007b 0x7c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .comment 0x000000000000007b 0x7c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .comment 0x000000000000007b 0x7c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .comment 0x000000000000007b 0x7c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .comment 0x000000000000007b 0x7c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .comment 0x000000000000007b 0x7c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .comment 0x000000000000007b 0x7c Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .comment 0x000000000000007b 0x7c ecm_src/dhcp-server/dhserver.o + .comment 0x000000000000007b 0x7c ecm_src/dns-server/dnserver.o + .comment 0x000000000000007b 0x7c ecm_src/lwip-1.4.1/src/core/def.o + .comment 0x000000000000007b 0x7c ecm_src/lwip-1.4.1/src/core/init.o + .comment 0x000000000000007b 0x7c ecm_src/lwip-1.4.1/src/core/mem.o + .comment 0x000000000000007b 0x7c ecm_src/lwip-1.4.1/src/core/memp.o + .comment 0x000000000000007b 0x7c ecm_src/lwip-1.4.1/src/core/netif.o + .comment 0x000000000000007b 0x7c ecm_src/lwip-1.4.1/src/core/pbuf.o + .comment 0x000000000000007b 0x7c ecm_src/lwip-1.4.1/src/core/raw.o + .comment 0x000000000000007b 0x7c ecm_src/lwip-1.4.1/src/core/stats.o + .comment 0x000000000000007b 0x7c ecm_src/lwip-1.4.1/src/core/tcp.o + .comment 0x000000000000007b 0x7c ecm_src/lwip-1.4.1/src/core/tcp_in.o + .comment 0x000000000000007b 0x7c ecm_src/lwip-1.4.1/src/core/tcp_out.o + .comment 0x000000000000007b 0x7c ecm_src/lwip-1.4.1/src/core/timers.o + .comment 0x000000000000007b 0x7c ecm_src/lwip-1.4.1/src/core/udp.o + .comment 0x000000000000007b 0x7c ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .comment 0x000000000000007b 0x7c ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .comment 0x000000000000007b 0x7c ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .comment 0x000000000000007b 0x7c ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o + .comment 0x000000000000007b 0x7c ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .comment 0x000000000000007b 0x7c ecm_src/lwip-1.4.1/src/netif/etharp.o + .comment 0x000000000000007b 0x7c ecm_src/src/ecm_main.o + .comment 0x000000000000007b 0x7c ecm_src/src/time.o + .comment 0x000000000000007b 0x7c ecm_src/src/usb_device.o + .comment 0x000000000000007b 0x7c ecm_src/src/usbd_conf.o + .comment 0x000000000000007b 0x7c ecm_src/src/usbd_core.o + .comment 0x000000000000007b 0x7c ecm_src/src/usbd_ctlreq.o + .comment 0x000000000000007b 0x7c ecm_src/src/usbd_desc.o + .comment 0x000000000000007b 0x7c ecm_src/src/usbd_ecm.o + .comment 0x000000000000007b 0x7c ecm_src/src/usbd_ioreq.o + +.debug_frame 0x0000000000000000 0x3e20 + .debug_frame 0x0000000000000000 0x88 Core/Src/main.o + .debug_frame 0x0000000000000088 0x30 Core/Src/stm32f0xx_hal_msp.o + .debug_frame 0x00000000000000b8 0xb8 Core/Src/stm32f0xx_it.o + .debug_frame 0x0000000000000170 0x4c Core/Src/system_stm32f0xx.o + .debug_frame 0x00000000000001bc 0x2a4 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.o + .debug_frame 0x0000000000000460 0x2a0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.o + .debug_frame 0x0000000000000700 0x110 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.o + .debug_frame 0x0000000000000810 0x434 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd.o + .debug_frame 0x0000000000000c44 0x110 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pcd_ex.o + .debug_frame 0x0000000000000d54 0x198 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.o + .debug_frame 0x0000000000000eec 0x180 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.o + .debug_frame 0x000000000000106c 0x3e0 Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_ll_usb.o + .debug_frame 0x000000000000144c 0x19c ecm_src/dhcp-server/dhserver.o + .debug_frame 0x00000000000015e8 0xb0 ecm_src/dns-server/dnserver.o + .debug_frame 0x0000000000001698 0x90 ecm_src/lwip-1.4.1/src/core/def.o + .debug_frame 0x0000000000001728 0x2c ecm_src/lwip-1.4.1/src/core/init.o + .debug_frame 0x0000000000001754 0xd0 ecm_src/lwip-1.4.1/src/core/mem.o + .debug_frame 0x0000000000001824 0x70 ecm_src/lwip-1.4.1/src/core/memp.o + .debug_frame 0x0000000000001894 0x1ac ecm_src/lwip-1.4.1/src/core/netif.o + .debug_frame 0x0000000000001a40 0x2a0 ecm_src/lwip-1.4.1/src/core/pbuf.o + .debug_frame 0x0000000000001ce0 0x114 ecm_src/lwip-1.4.1/src/core/raw.o + .debug_frame 0x0000000000001df4 0x2c ecm_src/lwip-1.4.1/src/core/stats.o + .debug_frame 0x0000000000001e20 0x4b4 ecm_src/lwip-1.4.1/src/core/tcp.o + .debug_frame 0x00000000000022d4 0x104 ecm_src/lwip-1.4.1/src/core/tcp_in.o + .debug_frame 0x00000000000023d8 0x220 ecm_src/lwip-1.4.1/src/core/tcp_out.o + .debug_frame 0x00000000000025f8 0x124 ecm_src/lwip-1.4.1/src/core/timers.o + .debug_frame 0x000000000000271c 0x198 ecm_src/lwip-1.4.1/src/core/udp.o + .debug_frame 0x00000000000028b4 0x90 ecm_src/lwip-1.4.1/src/core/ipv4/icmp.o + .debug_frame 0x0000000000002944 0xb0 ecm_src/lwip-1.4.1/src/core/ipv4/inet_chksum.o + .debug_frame 0x00000000000029f4 0x94 ecm_src/lwip-1.4.1/src/core/ipv4/ip.o + .debug_frame 0x0000000000002a88 0xd4 ecm_src/lwip-1.4.1/src/core/ipv4/ip_addr.o + .debug_frame 0x0000000000002b5c 0x17c ecm_src/lwip-1.4.1/src/core/ipv4/ip_frag.o + .debug_frame 0x0000000000002cd8 0x228 ecm_src/lwip-1.4.1/src/netif/etharp.o + .debug_frame 0x0000000000002f00 0x164 ecm_src/src/ecm_main.o + .debug_frame 0x0000000000003064 0x128 ecm_src/src/time.o + .debug_frame 0x000000000000318c 0x2c ecm_src/src/usb_device.o + .debug_frame 0x00000000000031b8 0x398 ecm_src/src/usbd_conf.o + .debug_frame 0x0000000000003550 0x270 ecm_src/src/usbd_core.o + .debug_frame 0x00000000000037c0 0x1d0 ecm_src/src/usbd_ctlreq.o + .debug_frame 0x0000000000003990 0xd0 ecm_src/src/usbd_desc.o + .debug_frame 0x0000000000003a60 0x1d0 ecm_src/src/usbd_ecm.o + .debug_frame 0x0000000000003c30 0xf0 ecm_src/src/usbd_ioreq.o + .debug_frame 0x0000000000003d20 0x2c c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-init.o) + .debug_frame 0x0000000000003d4c 0x2c c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-memcmp.o) + .debug_frame 0x0000000000003d78 0x28 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-memcpy-stub.o) + .debug_frame 0x0000000000003da0 0x20 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-memset.o) + .debug_frame 0x0000000000003dc0 0x20 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v6-m\libc_nano.a(lib_a-strcmp.o) + .debug_frame 0x0000000000003de0 0x20 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v6-m\libgcc.a(_udivsi3.o) + .debug_frame 0x0000000000003e00 0x20 c:/st/stm32cubeide_1.3.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.0.0.201904181610/tools/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v6-m\libgcc.a(_divsi3.o) diff --git a/test/STM32F072C8T6/stm32f072_ecm Debug.launch b/test/STM32F072C8T6/stm32f072_ecm Debug.launch new file mode 100644 index 0000000..d630c6f --- /dev/null +++ b/test/STM32F072C8T6/stm32f072_ecm Debug.launch @@ -0,0 +1,70 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/STM32F072C8T6/stm32f072_ecm.ioc b/test/STM32F072C8T6/stm32f072_ecm.ioc new file mode 100644 index 0000000..be7219d --- /dev/null +++ b/test/STM32F072C8T6/stm32f072_ecm.ioc @@ -0,0 +1,90 @@ +#MicroXplorer Configuration settings - do not modify +File.Version=6 +KeepUserPlacement=false +Mcu.Family=STM32F0 +Mcu.IP0=NVIC +Mcu.IP1=RCC +Mcu.IP2=SYS +Mcu.IP3=USB +Mcu.IP4=USB_DEVICE +Mcu.IPNb=5 +Mcu.Name=STM32F072C(8-B)Tx +Mcu.Package=LQFP48 +Mcu.Pin0=PA11 +Mcu.Pin1=PA12 +Mcu.Pin2=VP_SYS_VS_Systick +Mcu.Pin3=VP_USB_DEVICE_VS_USB_DEVICE_CDC_FS +Mcu.PinsNb=4 +Mcu.ThirdPartyNb=0 +Mcu.UserConstants= +Mcu.UserName=STM32F072C8Tx +MxCube.Version=5.6.0 +MxDb.Version=DB.5.0.60 +NVIC.ForceEnableDMAVector=true +NVIC.HardFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false +NVIC.NonMaskableInt_IRQn=true\:0\:0\:false\:false\:true\:false\:false +NVIC.PendSV_IRQn=true\:0\:0\:false\:false\:true\:false\:false +NVIC.SVC_IRQn=true\:0\:0\:false\:false\:true\:false\:false +NVIC.SysTick_IRQn=true\:0\:0\:false\:false\:true\:false\:true +NVIC.USB_IRQn=true\:0\:0\:false\:false\:true\:false\:true +PA11.Mode=Device +PA11.Signal=USB_DM +PA12.Mode=Device +PA12.Signal=USB_DP +PinOutPanel.RotationAngle=0 +ProjectManager.AskForMigrate=true +ProjectManager.BackupPrevious=false +ProjectManager.CompilerOptimize=6 +ProjectManager.ComputerToolchain=false +ProjectManager.CoupleFile=false +ProjectManager.CustomerFirmwarePackage= +ProjectManager.DefaultFWLocation=true +ProjectManager.DeletePrevious=true +ProjectManager.DeviceId=STM32F072C8Tx +ProjectManager.FirmwarePackage=STM32Cube FW_F0 V1.11.0 +ProjectManager.FreePins=false +ProjectManager.HalAssertFull=false +ProjectManager.HeapSize=0x200 +ProjectManager.KeepUserCode=true +ProjectManager.LastFirmware=true +ProjectManager.LibraryCopy=1 +ProjectManager.MainLocation=Core/Src +ProjectManager.NoMain=false +ProjectManager.PreviousToolchain= +ProjectManager.ProjectBuild=false +ProjectManager.ProjectFileName=stm32f072_ecm.ioc +ProjectManager.ProjectName=stm32f072_ecm +ProjectManager.StackSize=0x400 +ProjectManager.TargetToolchain=STM32CubeIDE +ProjectManager.ToolChainLocation= +ProjectManager.UnderRoot=true +ProjectManager.functionlistsort=1-MX_GPIO_Init-GPIO-false-HAL-true,2-SystemClock_Config-RCC-false-HAL-false,3-MX_USB_DEVICE_Init-USB_DEVICE-false-HAL-false +RCC.AHBFreq_Value=48000000 +RCC.APB1Freq_Value=48000000 +RCC.APB1TimFreq_Value=48000000 +RCC.CECFreq_Value=32786.88524590164 +RCC.FCLKCortexFreq_Value=48000000 +RCC.FamilyName=M +RCC.HCLKFreq_Value=48000000 +RCC.HSICECFreq_Value=32786.88524590164 +RCC.I2SFreq_Value=48000000 +RCC.IPParameters=AHBFreq_Value,APB1Freq_Value,APB1TimFreq_Value,CECFreq_Value,FCLKCortexFreq_Value,FamilyName,HCLKFreq_Value,HSICECFreq_Value,I2SFreq_Value,MCOFreq_Value,PLLCLKFreq_Value,PLLMCOFreq_Value,SYSCLKFreq_VALUE,SYSCLKSource,TimSysFreq_Value,USART1Freq_Value,USART2Freq_Value,VCOOutput2Freq_Value +RCC.MCOFreq_Value=48000000 +RCC.PLLCLKFreq_Value=16000000 +RCC.PLLMCOFreq_Value=16000000 +RCC.SYSCLKFreq_VALUE=48000000 +RCC.SYSCLKSource=RCC_SYSCLKSOURCE_HSI48 +RCC.TimSysFreq_Value=48000000 +RCC.USART1Freq_Value=48000000 +RCC.USART2Freq_Value=48000000 +RCC.VCOOutput2Freq_Value=8000000 +USB_DEVICE.CLASS_NAME_FS=CDC +USB_DEVICE.IPParameters=VirtualMode,VirtualModeFS,CLASS_NAME_FS +USB_DEVICE.VirtualMode=Cdc +USB_DEVICE.VirtualModeFS=Cdc_FS +VP_SYS_VS_Systick.Mode=SysTick +VP_SYS_VS_Systick.Signal=SYS_VS_Systick +VP_USB_DEVICE_VS_USB_DEVICE_CDC_FS.Mode=CDC_FS +VP_USB_DEVICE_VS_USB_DEVICE_CDC_FS.Signal=USB_DEVICE_VS_USB_DEVICE_CDC_FS +board=custom +isbadioc=false